使用libav转码视频时发现一个问题:使用下面这段代码解码视频时,解码中会不时丢掉几帧。

while(av_read_frame(ifmt_ctx,&packet) >= ){
ret = avcodec_decode_video2(video_dec_ctx, vframe, &got_frame, &packet);
if (got_frame) {
packet.pts = av_rescale_q(packet.pts,video_dec_st->time_base,video_enc_st->time_base);
write_video_frame(ofmt_ctx,video_enc_st,vframe);
}
}

这是因为源视频中PTS与DTS的不同造成的。
av_read_frame()按照PTS顺序读帧的时候,如果此帧需要参考后面的帧,那么此时avcodec_decode_video2()是没有能力解码此帧的,表现为got_frame返回0。
比如说遇上如下EFGH四帧:

ID :E F G H
KIND:I B P P
PTS : 1 2 3 4
DTS : 1 4 2 3

那么顺序读到F时,由于F需要参考G帧,而此时我们还没读到G帧,我们是没有解码F的能力的,got_frame就返回0了。如果我们对此事不做处理,那么我们就会丢掉一个帧(但丢掉的未必是F,因为av_read_frame()和avcodec_decode_video2()是1:1调用的)。
所以我们需要在while(av_read_frame())读完整个视频后,继续调用avcodec_decode_video2()把之前那些没有成功解码的帧都解出来。调用的次数就是之前got_frame返回0的次数。
按照上述思路变更代码为以下,成功找回丢失的帧。

int skipped_frame = ;  

while(av_read_frame(ifmt_ctx,&packet) >= ){
ret = avcodec_decode_video2(video_dec_ctx, vframe, &got_frame, &packet);
if (got_frame) {
packet.pts = av_rescale_q(packet.pts,video_dec_st->time_base,video_enc_st->time_base);
write_video_frame(ofmt_ctx,video_enc_st,vframe);
}
else
{
skipped_frame++;
}
} for(int i=skipped_frame; i>; i--)
{
ret = avcodec_decode_video2(video_dec_ctx, vframe, &got_frame, &packet);
if (got_frame) {
packet.pts = av_rescale_q(packet.pts,video_dec_st->time_base,video_enc_st->time_base);
write_video_frame(ofmt_ctx,video_enc_st,vframe);
}
}

avcodec_decode_video2少帧问题的更多相关文章

  1. 最近调试HEVC中码率控制, 发现HM里面一个重大bug

    最近调试HEVC中码率控制, 发现里面一个重大bug! 码率控制中有这么一个函数: Int TEncRCGOP::xEstGOPTargetBits( TEncRCSeq* encRCSeq, Int ...

  2. SILK 预测模块分析

    SILK是一种新结构的基于噪声整形量化算法的编解码框架.不同于类CELP的AMR,EVRC,G729,Speex等标准. 类CELP的结构都是以码本激励为量化框架的编码器.但是这里并不讨论NSQ结构和 ...

  3. HEVC之路0:HM16.18的运行+码流分析

    1.HM下载 HM不能直接网页下载,因为它是采用svn来管理代码的,因此需要利用svn下载,这里采用TortoiseSVN(软件下载地址为https://tortoisesvn.net/)进行下载. ...

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

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

  5. 关于IPB帧与恒定比特率、动态比特率的详解

    之所以写这篇文章是因为有朋友对IPB帧的设置比较感兴趣,回复中说得比较简单,因此在这里详细的写一下,虽然说一般情况下我们很少去设置这个IPB帧,不过,如果真的学好了,并且清楚的了解了这个IPB帧的概念 ...

  6. H264编码原理以及I帧、B和P帧详解

    H264是新一代的编码标准,以高压缩高质量和支持多种网络的流媒体传输著称,在编码方面,我理解的他的理论依据是:参照一段时间内图像的统计结果表明,在相邻几幅图像画面中,一般有差别的像素只有10%以内的点 ...

  7. 【转】CSS3动画帧数科学计算法

    本文来源于:财付通TID 原作者:bboy90 总结都浓缩在这个工具里了,想知道工具的地址或想窥探工具诞生的趣事请往下看 . —————————————————————–     华丽丽的开篇     ...

  8. UDS帧传输

    说明 在UDS协议中,其中有一点我视作为基础,即帧传输.也即是数据传输这一块,在UDS的帧传输中,分为4种: SF单帧 FF第一帧 CF连续帧 FC流控制帧 首先,我们抛开以上的东西,假设一个销售商( ...

  9. 【Unity3D基础】让物体动起来②--UGUI鼠标点击逐帧移动

    背景 上一篇通过鼠标移动的代码很简单,所以看的人也不多,但是还是要感谢“武装三藏”在博客园给出的评论和支持,希望他也能看到第二篇,其实可以很简单,而且是精灵自控制,关键是代码少是我喜欢的方式,也再次印 ...

随机推荐

  1. Jenkins配置中安装插件时提示“No such plugin: cloudbees-folder”

    第一次配置Jenkins时,执行下图中出现“No such plugin: cloudbees-folder”,这时应该是服务还没起完全,稍等等就好

  2. Appium -作业5(2)

    # coding:utf-8 from appium import webdriverimport timedesired_caps = { 'platformName':'Android', 'de ...

  3. Event 对象的属性和方法

    事件触发时,会将一个 Event 对象传递给事件处理程序,比如: document.getElementById("testText").addEventListener(&quo ...

  4. 常用jqueryPlugin

    http://www.jq22.com editable-select :  jQuery可编辑可下拉插件jquery.editable-select.js

  5. list集合转换成datatable

    /// 将list集合转换成datatable /// </summary> /// <param name="list"></param> / ...

  6. ajax之发送post请求

    jquery发送post请求 function AjaxSubmit3() { //jquery发送post请求 $.ajax({ url: '/app04/ajax1/', type: 'POST' ...

  7. React Native多语言

    https://medium.com/@danielsternlicht/adding-localization-i18n-g11n-to-a-react-native-project-with-rt ...

  8. Jquery select chosen 插件注意点

    <select style="width:200px;" name="carId" data-placeholder="选择车辆牌照" ...

  9. 最邻近算法(KNN)识别数字验证码

    应用场景   对于简单的数字型验证码的自动识别.前期已经完成的工作是通过切割将验证码图片切割成一个一个的单个数字的图片,并按照对应的数字表征类别进行分类(即哪些图片表示数字7,哪些表示8),将各种数字 ...

  10. 5分钟K线图压力线买点怎么看?

    某开盘后底开一直呈现形成了一个长时间的箱体振荡的走势,K线在底位振荡时,其波动底点总是在不断抬高的话,这种走势说明有资金在场中积极运作,正是由于资金悄然建仓导致了底点慢慢抬高的走势,在底点不断抬高时, ...