ffmpeg是当前最重要的开源多媒体工程,我之前和现在做的很多项目都用到了ffmpeg。我会在本文中不断更新一些使用和移植优化ffmpeg的心得,和大家一起交流提高。为了方便查看采用Q&A的形式。

Q0:视频文件里包含多路视频流时如何调用av_seek_frame?

A:根据流数量,按照流索引依次调用av_seek_frame,如下图代码所示:

Q1:我用一个解码循环解一遍视频文件后,调用av_seek_frame到开始位置用同一个循环再解一遍,可第二次的第一祯总是该视频的最后一祯,这是什么原因呢?我的调用方法
av_seek_frame(pFormatCtx, -1, pFormatCtx->start_time, 0)
后来发现
av_seek_frame(pFormatCtx, -1, 0, 0)效果一样,调用模式try了所有除了有一个没有进解码循环,其他都一样。

A: 重新解码前要flush codec
avcodec_flush_buffers(...streams[video_index]->codec)

Q2: 我调用av_seek_frame后解出的图像是花的,调用avcodec_flush_buffers后也是一样

A: 没有seek到I Frame

Q3:调用av_seek_frame后出现某一路或某几路流连续20几帧数据解码失败,如何解决?

A:这里有两种处理方法,一是在解码解码失败后,填充logo,如下图所示:

另一种方法是:每次av_seek_frame前保存每一个流 完整的一帧视频,当av_seek_frame后出现解码失败后填充上次保存的一帧视频;

第一种方法测试效果有点不尽人意,如果用脚本连续执行快进会出现快进一次出现一次logo,如果快进间隔为1s那就只能看logo了;

第二种方法测试效果会出现静帧现象,但是效果还算差强人意;

Q4. 如何正确使用av_seek_frame实现视频拖放

   time=5;//拖放到5秒的位置 

    ret = av_seek_frame(FormatCtx,videoStream,(int64_t)time*(AV_TIME_BASE),AVSEEK_FLAG_BACKWARD); 

 注:AVSEEK_FLAG_BACKWARD的作用是seej到请求的timestamp之前最近的关键帧
 

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐