我很困惑。我使用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)设置时间单位。
上面的代码是对的吗?
答案 0 :(得分:2)
TL; DR
因此,只需乘以当前值* 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);