使用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. spark 实现TOP N

    数据量较少的情况下: scala> numrdd.sortBy(x=>x,false).take(3) res17: Array[Int] = Array(100, 99, 98) sca ...

  2. C#字符串加密解密

    /// <summary> /// 加密字符串 /// 注意:密钥必须为8位 /// </summary> /// <param name="strText&q ...

  3. day22-类的多态

    一.多态 多态的概念是应用于Java和C#这一类强类型语言中,而Python崇尚“鸭子类型”.所谓多态:调用的方法是同一个,但是执行的代码或者说现象不一样,此时就称为多态 #我们编写了名为Animal ...

  4. SQL 用到的操作符

    1.LIKE 操作符用于在 WHERE 子句中搜索列中的指定模式. SELECT column_name(s) FROM table_name WHERE column_name LIKE patte ...

  5. MySQL大数据量分页查询方法及其优化

    MySQL大数据量分页查询方法及其优化   ---方法1: 直接使用数据库提供的SQL语句---语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N---适 ...

  6. es查询时报 Data too large

    报错如下: 原因: https://www.cnblogs.com/jiu0821/p/6526930.html 参数 indices.fielddata.cache.size 控制有多少堆内存是分配 ...

  7. 21 week4 submit buidAndRun() node-rest-client

    . 我们想实现一个提交代码的功能 这个功能有nodeserver 传到后边的server 验证 在返回给nodeserver 我们稍微修改一下ui ATOM修改文件权限不够 用下面命令 我们 Cont ...

  8. Redis入门及主从配置

    1.Redis入门简介 Redis是一个开源的使用ANSI C语音编写.支持网络.可基于内存亦可持久化的日志型,Key-Value数据库.支持存储的value类型包括 string(字符串).list ...

  9. 学习JS的心路历程-参数传递方式(上)

    很多人认为JS的传递方式是值是Call by value, 物件及数组是Call by Reference.甚至还有人宣称其实JS是Call by sharing,那到底是哪一个呢? 这两天我们一一来 ...

  10. Python str list to list

    eg1: My csv data like this below,i wt count list nums 2018上,"['C', 'B', 'B', 'B', 'D', 'A', 'B' ...