我不知道用于av_dict_set设置超时的时间单位

时间:2015-12-02 02:59:05

标签: http ffmpeg timeout rtsp

我很困惑。我使用av_dict_set函数来设置超时,但是当我搜索有关av_dict_set的信息时,时间单位似乎有所不同。我现在不知道如何设置它。有人可以帮忙吗?

我发现了一些如下代码:

pFormatCtx = avformat_alloc_context();

av_dict_set(&opts, "rtsp_transport", "tcp", 0);
//av_dict_set(&opts, "timeout", "5000000", 0);
if(strncmp(stream_url, "rtmp:", sizeof("rtmp:")) == 0){
    av_dict_set(&opts, "timeout", "6", 0); // in secs
}
else if(strncmp(stream_url, "http:", sizeof("http:")) == 0){
    av_dict_set(&opts, "timeout", "6000", 0); // in ms
}

if(avformat_open_input(&pFormatCtx, stream_url, NULL, &opts)!=0)
{
  return 1;
}

也许它应该根据不同的协议(http或rtsp)设置时间单位。

上面的代码是对的吗?

1 个答案:

答案 0 :(得分:2)

TL; DR

  • RTMP和RTSP协议,时基:;
  • HTTP协议,时基:微秒(不是毫秒)。

因此,只需乘以当前值* 1000即可相应地修复HTTP部分。


我有一个C ++应用程序,该应用程序使用 libav 编码 H.264 / AAC RTSP流并将其推送到本地RTSP服务器然后为它服务。我还有另一个C ++应用程序,它使用libav 解码此RTSP流,从数据包中提取视频/音频数据,对其进行重新缩放并使用SFML显示来自缓冲区的像素数据。

解码应用程序中,我使用timeout选项来确定RTSP流是否可用。这是一个可选参数,但是如果解码过程早于可用的RTSP流开始,则如果未设置timeout,则解码过程会挂起。发生这种情况是因为RTSP和HTTP协议的默认值为-1,这意味着“无限等待”。如果您改为将其设置为其他值,并且发生这种情况,avformat_open_input将返回一个AVERROR代码,您可以对其进行进一步分析,例如,您可以通过简单地开始重新尝试重新连接到RTSP流结束,从而使您可以更好地控制执行流程。

问题是:“ 此值的正确时基是多少,以便我可以相应地使用它?

here所述,对于 RTSP协议,您可以设置timeout选项来确定等待打开流所需的最长时间。在 RTSP 部分中,指南明确指出该值以为单位估算:

超时

设置最大超时(以秒为单位)以等待传入连接。

值-1表示无穷大(默认)。此选项意味着rtsp_flags设置为“监听”。

虽然它没有为 RTMP协议指定它,但我已经通过将 RTSP URL 更改为 RTMP URL 而对它进行了测试,而无需更改时间基准,并且按预期方式工作,因此我的推论是两个协议共享相同的时间基准。

此外,在同一页面here中,对于 HTTP协议,您可以出于相同的目的设置timeout值,但时基必须在微秒

超时

设置底层底层操作使用的套接字I / O操作的超时(以微秒为单位)。默认情况下,它设置为-1,这表示未指定超时。

因此,在您的情况下,您需要替换,因为您期望的时基不正确(我假设您的意思是毫秒,而正确的时间是微秒,以使超时时间为6秒而不是0.006秒:

else if(strncmp(stream_url, "http:", sizeof("http:")) == 0){
    av_dict_set(&opts, "timeout", "6000", 0); // in ms
}

与此:

else if(strncmp(stream_url, "http:", sizeof("http:")) == 0){
    av_dict_set(&opts, "timeout", "6000000", 0); // In microseconds
}

如您的示例所示,您已经分配了格式上下文;然后,在打开流之前,先创建一个AVDictionary,然后将timeout的值设置为av_dict_set。您还可以设置其他选项。通过将刚刚创建和配置的字典作为参考传递,所有这些信息都传递给avformat_open_input

in line 405 in libavformat\utils.c所述,字典信息将被复制到解码器格式上下文priv_data中,并将其用于打开流。

如果触发了超时,则该函数将返回AVERROR代码。

avformat_network_init();
AVFormatContext* muxer_receiver = avformat_alloc_context();
AVDictionary* options = NULL;
av_dict_set(&options, "timeout", "3", 0);
if(avformat_open_input(&muxer_receiver, "rtsp://:32400/live/1", NULL, &options)!=0){
    return EXIT_FAILURE;
}
if(avformat_find_stream_info(muxer_receiver, NULL)<0){
    return EXIT_FAILURE;
}
// Do stuff like retrieving video and audio streams index
av_read_play(muxer_receiver);