其实最初不是为了解决这个问题而来的,是Peter兄给我的提示解决另一个问题却让我误打误撞解决了另外一个问题之后也把这个隐藏了很久的bug找到(之前总是有一些特别短的视频产生不知所措还以为是视频素材本身有问题呢),今天真是收获颇丰啊,对libav的理解更深。

一直以来我的程序架构是让读一帧av_read_frame,然后去尝试根据packet的type类型分别去decode video或者audio,然而这样总是在视频的结尾会有许多帧丢失的问题,我找过avplay代码中似乎没找到我想象中的那种读packet完毕后特殊处理的代码。

一下log是我设置将其avcodec_decode_video2函数调用前后输出的pts、dts值(注:Frame:为decode之后,测试视频为纯视频无音频的文件),从图中可以看出来,开头为了顺序正确,libav暂存了9个packet,读packet完毕后,我当然不能就直接不管了,还是要将libav暂存的那些帧取出来才行。


    综上几点我认为是在调用avcodec_decode_video2函数的时候,函数内会去发现这个packet尚不足以解码下一帧的时候就会暂存packet在内部队列中(我自己给他们取的名字,望能理解),这样问题就来了,等到整个视频文件都读取完了,剩下libav内部存的packet还有一大堆没处理,我的架构又是要求函数直接向视频索取一帧,因此就需要在读新packet完毕后还 单独调用decode video函数或者decode audio函数来取出剩余的AVFrame。

为了这些bug我破例无耻的使用了goto语句:

首先定义了类成员变量,初始化都为false:

bool            _no_packet;   //代表是否还有packet
bool _end_video_frame; //代表是否video中的队列取出完毕
bool _end_audio_frame; //代表是否audio中的队列取出完毕
AVPacket packet = {};
while(true)
{
auto auto_releaser = std::shared_ptr<AVPacket>(&packet, [](AVPacket* p) { av_free_packet(p); });
int ret = av_read_frame(_context.get(), &packet);
if ( ret != )
{
_no_packet = true;
if(!_end_video_frame)
goto loop_end_video;
if(!_end_audio_frame)
goto loop_end_audio;
if(_end_video_frame && _end_audio_frame)
return false;
}
if(packet.stream_index == vstream_index)
{
loop_end_video:
int frame_finished = true;
if(avcodec_decode_video2(_vcodec, _decoded_frame, &frame_finished, &packet) < )
{
// 。。。。do something。。。
}
if(frame_finished)
{
//。。。。do something。。。
}
else
{
if(_no_packet)
_end_video_frame = true;
}
}
else if (packet.stream_index == astream_index && (type & MEDIA_AUDIO) != )
{
loop_end_audio:
int frame_finished;
if (avcodec_decode_audio4(_acodec, _decoded_frame, &frame_finished, &packet) < )
{
// 。。。。do something。。。
}
if(frame_finished)
{
//。。。。do something。。。
}
else
{
if(_no_packet)
_end_audio_frame = true;
}
}
}

有了这些跳转,就能完美的在read_frame完之后还继续decode为我所用。希望能帮助到与我遇到了相同问题的人。

再次感谢Peter~

关于ffmpeg(libav)解码视频最后丢帧的问题的更多相关文章

  1. avcodec_decode_video2()解码视频后丢帧的问题解决

    使用libav转码视频时发现一个问题:使用下面这段代码解码视频时,视频尾巴上会丢掉几帧. while(av_read_frame(ifmt_ctx,&packet) >= 0){ ret ...

  2. 学习FFmpeg API – 解码视频

    本文转载 视频播放过程 首先简单介绍以下视频文件的相关知识.我们平时看到的视频文件有许多格式,比如 avi, mkv, rmvb, mov, mp4等等,这些被称为容器(Container), 不同的 ...

  3. ffmpeg编解码视频导致噪声增大的一种解决方法

    一.前言 ffmpeg在视音频编解码领域算是一个比较成熟的解决方案了.公司的一款视频编辑软件正是基于ffmpeg做了二次封装,并在此基础上进行音视频的编解码处理.然而,在观察编码后的视频质量时,发现图 ...

  4. 【转】学习FFmpeg API – 解码视频

    ffmpeg是编解码的利器,用了很久,以前看过dranger 的教程,非常精彩,受益颇多,是学习ffmpeg api很好的材料.可惜的是其针对的ffmpeg版本已经比较老了,而ffmpeg的更新又很快 ...

  5. 【学习ffmpeg】打开视频文件,帧分析,并bmp保存关键帧

    http://www.tuicool.com/articles/jiUzua   http://blog.csdn.net/code_future/article/details/8646717 主题 ...

  6. FFMPEG学习----解码视频

    基础概念 我们平时看到的视频文件有许多格式,比如 avi, mkv, rmvb, mov, mp4等等,这些被称为容器(Container), 不同的容器格式规定了其中音视频数据的组织方式(也包括其他 ...

  7. FFmpeg解码视频帧为jpg图片保存到本地

    FFmpeg解码视频帧为jpg图片保存到本地 - CSDN博客 https://blog.csdn.net/qq_28284547/article/details/78151635

  8. Android 音视频深入 九 FFmpeg解码视频生成yuv文件(附源码下载)

    项目地址,求star https://github.com/979451341/Audio-and-video-learning-materials/tree/master/FFmpeg(MP4%E8 ...

  9. 视频编解码---x264用于编码,ffmpeg用于解码

    项目要用到视频编解码,最近半个月都在搞,说实话真是走了很多弯路,浪费了很多时间.将自己的最终成果记录于此,期望会给其他人提供些许帮助. 参考教程: http://ffmpeg.org/trac/ffm ...

随机推荐

  1. select下拉框如何与接口配合动态生成option选项

    前几天在做任务时考虑到这个问题,具体任务用例如下: HTML: JS:

  2. Selenium2.0+TestNG+Ant+Jenkins自动化测试浅尝

    当前常用自动化测试工具 Web自动化测试工具:QTP .selenium等 性能自动化测试工具:loadrunner.jmeter等 接口自动化测试工具:SoapUI.postman等 手机自动化测试 ...

  3. ios json转model的简单现实

    在android开发中,可用第三方的转换库如gson等.当然在ios也有一些库如MJExtensiond等.在这里,我简单实现一下. 一.先建一个model并且继承NSObject,代码如下: cla ...

  4. 帝都Day7——解放篇

    昨天晚上的problems: songfen 坠大子段和,要把[l,r]其中一个数变成P,我们要把最小的数变成p. 当L,R没有取满整个区间,P可以在[L,R]外面!!!!!!!这种情况真是令人绝望. ...

  5. [SCOI2010]连续攻击游戏 BZOJ1854 二分图匹配

    题目描述 lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有2个属性,这些属性的值用[1,10000]之间的数表示.当他使用某种装备时,他只能使用该装备的某一个属性.并且每种装备 ...

  6. 洛谷P3003 苹果交货Apple Delivery

    题目描述 贝西有两个又香又脆的红苹果要送给她的两个朋友.当然她可以走的\(C(1 \leq C \leq 200000)\)条"牛路"都被包含在一种常用的图中,包含了\(P(1 \ ...

  7. EcmaScript源码

    /** @type {Number} @const */ NaN = 0; /** @type {Number} */ Infinity = 0; undefined = 0; /** @param ...

  8. input[checkbox],input[radiobox]的一些问题

    复选框和文字对不齐:checkbox复选框的一些深入研究与理解: 解决方案:复选框或单选框与文字对齐的问题的深入研究与一 实例:实例.

  9. POJ1034 The dog task

    题目来源:http://poj.org/problem?id=1034 题目大意: 一个猎人在遛狗.猎人的路径由一些给定的点指定.狗跟随着猎人,要与主人同时到达那些指定的点.在丛林里有一些有趣的地方, ...

  10. 文件系统满的话(filesystem full),该如何处理。(du and ls)

    #!/bin/bash function ergodic(){ ` do "/"$file ] then ergodic $"/"$file else loca ...