av_interleaved_write_frame 網絡不好的情況下返回較慢


用libvlc做直播推流引擎
在網絡較差的情況下,需要關閉直播,並且重新開播。
這個過程中,推流引擎重啟,需要的是快速響應。
實際上測試結果發現,經常會發生引擎關閉接口卡住。
后來跟蹤代碼,定位到s_rtmp_send_thread() 中
其中一句:
ret = av_interleaved_write_frame(formatContext, pkt);
這個方法在網絡較好的情況下,一般是幾個毫秒就返回發送成功。
然后在網絡較差的情況下,會一直卡在這里,沒有返回。。。

跟蹤ffmpeg代碼,這個方法的實現在mux.c
libavformat/mux.c
av_interleaved_write_frame()
write_packet() 真正寫數據
ret = s->oformat->write_packet(s, pkt);
write_packet 這里就是一個定義在avformat.h中的指針,指向flv_write_packet()

經一步跟蹤代碼,發現關於網絡讀寫的超時控制,定義在url.h中

typedef struct URLContext {
......
int64_t rw_timeout; /**< maximum time to wait for (network) read/write 
......
} URLContext;

於是在初始化的地方,設置這個參數:

libavformat/avio.c --->
url_alloc_for_protocol() return之前添加如下語句

// 網絡讀寫超時 控制在 800ms

if (0 == uc->rw_timeout || uc->rw_timeout > 800000)
        uc->rw_timeout = 800000;

回到項目中,在av_interleaved_write_frame兩端輸出時間,發現現在這個接口在網絡不好的情況下,基本控制在1s以內。然后並不是精確的時間控制。貌似ffmpeg本身都不能嚴格控制到毫秒級別。

為了確保這個返回一定得到響應,同時在libavformat/mux.c
av_interleaved_write_frame()中修改下面的代碼:

for(;;) 

這個沒有控制的for循環,改為

int mOutTimes = 128;
int nn;
for(nn=0;nn<mOutTimes;nn++)

這里的128是個經驗值。


免責聲明!

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



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