avformat_open_input 阻塞 and 设置超时时间

在编写能够适配 h264 和 h265 编码的MP4播放器时遇到的问题.(PS如果iOS系统播放器能够满足这一点我也不至于会累成狗).于是有了以下的尝试.

  1. 完美解析播放 本地mp4 (h264编码)
  2. 完美解析播放 本地mp4 (h265编码)
  3. 解析网络mp4 (海鸟)
    视频地址 http://vjs.zencdn.net/v/oceans.mp4 卡顿超级严重
  4. 解析网络mp4 (驯龙高手)
    视频地址 http://vfx.mtime.cn/Video/2019/02/04/mp4/190204084208765161.mp4 播放顺畅
  5. 解析网络mp4 这边是找了一个h265编码的视频.不好找呀.我这里也是限时才有的 播放顺畅

ffmpeg 用avformat_open_input() 解析网络流时.默认是阻塞线程, 解析错误或其他原因的长时间不返回.
为 avformat_open_input() 函数设置stimeout 的参数 (单位微妙)
设置interrupt_callback和timeout . 能解决这些问题

设置超时时间timeout

 

//设置一些参数
    //    AVDictionary * options = NULL;
    /*
     //设置缓存大小,1080p可将值调大
     //以udp方式打开,如果以tcp方式打开将udp替换为tcp
     //设置超时3秒 设置超时断开连接时间,单位微秒
     //设置最大时延
     */
    // av_dict_set(&options, "buffer_size", "1024000", 0);
    // av_dict_set(&options, "rtsp_transport", "tcp", 0);
    // av_dict_set(&options, "stimeout", "3000000", 0);
    // av_dict_set(&options, "max_delay", "500000", 0);
    
    //    pFormatCtx->probesize = 100 *1024;
    //    pFormatCtx->max_analyze_duration = 5 * AV_TIME_BASE;

    AVDictionary * opts = NULL;
    av_dict_set(&opts, "rtsp_transport", "tcp", 0);
    av_dict_set(&opts, "stimeout", "2000000", 0);

avformat_open_input 阻塞处理 interrupt_callback

 

static int decode_interrupt_cb(void *ctx)
{
    return 1;  // return 1 时会立刻结束阻塞
}
//建议这么写
static int decode_interrupt_cb(void *ctx)
{
    exit_info * is = ctx;
    if (is->nExit == 1) {
        OOLog(@"终止rtsp >>>>>>>>>>>>>>>>>>> is->nExit = 1");
    }
    return is->nExit;
}
想结束时 is->nExit = 1; 就好了

formatCtx->interrupt_callback.callback = decode_interrupt_cb;
formatCtx->interrupt_callback.opaque = is;

当然也有说avformat_open_input 能设置成非阻塞的 (设置后貌似没效果,建议不用)

 

formatCtx->flags |= AVFMT_FLAG_NONBLOCK;



作者:Kingiiyy_iOS
链接:https://www.jianshu.com/p/f1d511ea98b4
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

av_read_frame函数是FFmpeg库中用于读取音视频帧的函数。默认情况下,该函数会在没有可用的音视频帧时阻塞,直到有新的音视频帧可用为止。如果你想让av_read_frame函数立即返回而不阻塞,可以通过设置回调函数来实现。 方法一:设置回调函数 你可以通过设置interrupt_callback回调函数来打断av_read_frame函数的阻塞。具体步骤如下: 1. 定义一个回调函数,用于打断av_read_frame函数的阻塞。回调函数的原型如下: ```c int interrupt_cb(void *opaque); ``` 2. 在设置interrupt_callback之前,先设置AVFormatContext的opaque字段,将回调函数所需的上下文信息传递给回调函数。例如: ```c m_avformatCtx->interrupt_callback.opaque = this; ``` 3. 设置interrupt_callback回调函数,将回调函数的指针赋值给interrupt_callback.callback字段。例如: ```c m_avformatCtx->interrupt_callback.callback = interrupt_cb; ``` 4. 在回调函数中实现打断逻辑。当回调函数返回非零值时,av_read_frame函数将立即返回。 方法二:设置超时 除了设置回调函数外,你还可以通过设置超时时间来让av_read_frame函数在超过指定时间后立即返回。具体步骤如下: 1. 使用av_dict_set函数设置超时时间。例如: ```c av_dict_set(&inputDic, "stimeout", "2000000", 0); // 设置超时时间为2秒 ``` 2. 在avformat_open_input函数调用之前,将设置好的字典传递给该函数。 这两种方法的区别在于,设置回调函数可以在任何情况下打断av_read_frame函数的阻塞,而设置超时只能在超过指定时间后打断阻塞
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值