ffmpeg avformat_open_input 返回 -1094995529 问题排查
使用场景:live555 mediaServer作为服务端, 客户端ffmpeg rtsp拉流
问题:开始拉流正常,但多次之后 avformat_open_input
总是返回 -1094995529
,导致触发超时回调
原因:只调用 avformat_free_context()
释放了 AVFormatContext
,rtsp 连接未关闭,多次之后无法再建立连接
解决方法:调用 avformat_close_input()
关闭 avformat_open_input()
打开的流,两者必须成对使用
排查:
首先设置ffmpeg日志级别为debug,可以打印 ffmpeg 底层 api调用细节
av_log_set_level(AV_LOG_DEBUG);
发现正常执行流程日志如下:
[tcp @ 0x7f61e41d6c80] No default whitelist set
[tcp @ 0x7f61e41d6c80] Original list of addresses:
[tcp @ 0x7f61e41d6c80] Address 172.20.35.17 port 554
[tcp @ 0x7f61e41d6c80] Interleaved list of addresses:
[tcp @ 0x7f61e41d6c80] Address 172.20.35.17 port 554
[tcp @ 0x7f61e41d6c80] Starting connection attempt to 172.20.35.17 port 554
[tcp @ 0x7f61e41d6c80] Successfully connected to 172.20.35.17 port 554
[rtsp @ 0x7f61f0199b80] SDP:
v=0
o=- 1649730133151151 1 IN IP4 192.168.242.1
s=Matroska video+audio+(optional)subtitles, streamed by the LIVE555 Media Server
i=9-1920x1080-264.mkv
t=0 0
a=tool:LIVE555 Streaming Media v2021.02.11
a=type:broadcast
a=control:*
a=range:npt=0-
a=x-qt-text-nam:Matroska video+audio+(optional)subtitles, streamed by the LIVE555 Media Server
a=x-qt-text-inf:9-1920x1080-264.mkv
m=video 0 RTP/AVP 96
c=IN IP4 0.0.0.0
b=AS:500
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1;profile-level-id=640028;sprop-parameter-sets=Z2QAKKy0A8ARPywgAAADACAAAAUR4wZU,aO8Lyw==
a=control:track1
当tcp连接成功之后开始交换rtsp/sdp信令,但是多次之后开始失败,日志如下:
[tcp @ 0x7f61e41d6c80] No default whitelist set
[tcp @ 0x7f61e41d6c80] Original list of addresses:
[tcp @ 0x7f61e41d6c80] Address 172.20.35.17 port 554
[tcp @ 0x7f61e41d6c80] Interleaved list of addresses:
[tcp @ 0x7f61e41d6c80] Address 172.20.35.17 port 554
[tcp @ 0x7f61e41d6c80] Starting connection attempt to 172.20.35.17 port 554
[tcp @ 0x7f61e41d6c80] Successfully connected to 172.20.35.17 port 554
只有tcp连接成功,不再发送sdp信令。
rtsp协议建立连接阶段的sdp传输总是用的tcp协议,后续媒体流可以选择tcp/udp,所以为rtsp连接失败导致。而多次拉流后才会发生,说明可能是 tcp 连接没有关闭释放导致。
根据ffmpeg代码注释,发现:
avformat_alloc_context()
分配的 fmt 可以 调用 avformat_free_context()
释放.
而 avformat_open_input()
打开的 fmt 必须 调用 avformat_close_input()
关闭,关闭的同时会释放 fmt.
ffmpeg拉流:
av_log_set_level(AV_LOG_ERROR); // AV_LOG_DEBUG
// avformat_free_context() can be used to free the context
in_fmt = avformat_alloc_context();
// 设置av_read_frame 超时回调
in_fmt->interrupt_callback.callback = read_interrupt_callback;
in_fmt->interrupt_callback.opaque = this;
read_start_time = time(NULL); // 每次读流之前记录一下起始时间
// must be closed with avformat_close_input(),会释放掉in_fmt,不用再次调用 avformat_free_context()
int ret = avformat_open_input(&in_fmt, srcPath.c_str(), NULL, NULL);
if (ret < 0) {
releaseSources();
return ErrorCode::E_STREAM_OPEN_TIMEOUT; // 拉流超时
}
// releaseSources();
// avformat_close_input(&in_fmt)
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!
2019-04-12 ES6学习笔记(十八)Class 的继承