1. 程式人生 > 實用技巧 >ffmpeg拉流長時間堵塞解決方式

ffmpeg拉流長時間堵塞解決方式

由於網路堵塞或者推流端錯誤導致拉流端沒有流資料,ffmpeg主要會堵塞兩個函式,直到下次流資料的到來

  1. avformat_open_input()

    該函式是在開啟流資料時,如果沒有這個流的ip,http有自己的timeout,當連結失敗,ffmpeg會自動斷開.但是如果有這個ip,但是無法連結,就會堵塞,解決方式是新增超時控制.

    函式在ffmpeg原始碼的ffmpeg_opt.c檔案中,



    我設定了3秒超時時間,新增如下程式碼

    av_dict_set(&o->g->format_opts, "rw_timeout", "3000000", 0);

  2. av_read_frame()


    該函式是連結成功後,由於網路堵塞或者其它問題導致packet丟失,無法讀取,導致堵塞,

    函式在ffmpeg.c檔案中,解決方式也是新增超時

    `f->ctx->interrupt_callback.callback = CheckInterrupt;

    f->ctx->interrupt_callback.opaque = (void*)f->ctx;

    time_t start_time;

    start_time = time(NULL);

    int l = time(&start_time);

    f->ctx->st = l;

    return av_read_frame(f->ctx, pkt);

`

下面是回撥函式:

`

static int CheckInterrupt(void *ctx)

{

AVFormatContext p = (AVFormatContext)ctx;

time_t et;

et = time(NULL);

int l = time(&et);

av_log(NULL, AV_LOG_WARNING,"start time%d\n",p->st);

av_log(NULL, AV_LOG_WARNING,"end time%d\n",l);

return l - p->st >= 10 ? 1 : 0;//3秒超時


}

`

  需要注意的是,我在`f->ctx`結構體中添加了st變數,由時間戳作為評判超時的依據,需要把變數型別統一,所以需要新增變數如下:
在avformat.h檔案的AVFormatContext結構體中新增:
`int st;`