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)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM