FFmpeg推拉流的时候,如果调用API不当很容易出现调用部分函数一直没有返回的现象,因为这部分函数默认是阻塞的,如果不加控制,等待时间可能会达到30s以上,对于有些情况,等待30s的体验是无法接受的。
常见的阻塞函数:
- avformat_open_input
- av_read_frame
- avformat_write_header
- av_write_trailer
- av_write_frame
ffmpeg支持interrupt_callback机制,可以对输入(或输出)的AVFormatContext的interrupt_callback成员设置,然后再回调函数中做控制。
流媒体工具服务列表直播中设置超时回调如下:
mdc_listplay_task_t* task;
const char* input;
AVFormatContext* ic = NULL;
ic = avformat_alloc_context();
// 设置超时回调
ic->interrupt_callback.callback = &mdc_listplay_interrupt_cb;
ic->interrupt_callback.opaque = task;
int ret = avformat_open_input(&ic, input, NULL, NULL)
注意的是:
// false:继续阻塞;
// true:退出阻塞
static int mdc_listplay_interrupt_cb(void* param)
{
// ffmpeg 超时判断.
// false:继续阻塞;
// true:退出阻塞
mdc_listplay_task_t* task = param;
if (!task->running || apr_time_now() - task->last >= 10 * 1000 * 1000)
{
dzlog_warn("listplay: interrupt, id:%s", task->id);
return 1;
}
return 0;
}
参考文档: FFMPEG结构体分析之AVFormatContext-CSDN博客