使用libav转码视频时发现一个问题:使用下面这段代码解码视频时,视频尾巴上会丢掉几帧。
while(av_read_frame(ifmt_ctx,&packet) >= 0){ 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 = 0; while(av_read_frame(ifmt_ctx,&packet) >= 0){ 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>0; 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); } }
原文地址:http://blog.yikuyiku.com/?p=3486
avcodec_decode_video2()解码视频后丢帧的问题解决的更多相关文章
-
关于ffmpeg(libav)解码视频最后丢帧的问题
其实最初不是为了解决这个问题而来的,是Peter兄给我的提示解决另一个问题却让我误打误撞解决了另外一个问题之后也把这个隐藏了很久的bug找到(之前总是有一些特别短的视频产生不知所措还以为是视频素材本身 ...
-
FFmpeg解码视频帧为jpg图片保存到本地
FFmpeg解码视频帧为jpg图片保存到本地 - CSDN博客 https://blog.csdn.net/qq_28284547/article/details/78151635
-
用libvlc 抓取解码后的帧数据
vlc是一套优秀的开源媒体库,其特点是提供了完整的流媒体框架, 用它可以非常方便的实现抓取解码帧的功能. 与此功能有关的关键API为 libvlc_video_set_callbacks /*设置回调 ...
-
学习FFmpeg API – 解码视频
本文转载 视频播放过程 首先简单介绍以下视频文件的相关知识.我们平时看到的视频文件有许多格式,比如 avi, mkv, rmvb, mov, mp4等等,这些被称为容器(Container), 不同的 ...
-
【转】学习FFmpeg API – 解码视频
ffmpeg是编解码的利器,用了很久,以前看过dranger 的教程,非常精彩,受益颇多,是学习ffmpeg api很好的材料.可惜的是其针对的ffmpeg版本已经比较老了,而ffmpeg的更新又很快 ...
-
Android 音视频深入 九 FFmpeg解码视频生成yuv文件(附源码下载)
项目地址,求star https://github.com/979451341/Audio-and-video-learning-materials/tree/master/FFmpeg(MP4%E8 ...
-
FFMPEG学习----解码视频
基础概念 我们平时看到的视频文件有许多格式,比如 avi, mkv, rmvb, mov, mp4等等,这些被称为容器(Container), 不同的容器格式规定了其中音视频数据的组织方式(也包括其他 ...
-
【学习ffmpeg】打开视频文件,帧分析,并bmp保存关键帧
http://www.tuicool.com/articles/jiUzua http://blog.csdn.net/code_future/article/details/8646717 主题 ...
-
EasyPusher直播推送中用到的缓冲区设计和丢帧原理
问题描述 我们在开发直播过程中,会需要用到直播推送端,推送端将直播的音视频数据推送到流媒体服务器或者cdn,再由流媒体服务器/CDN进行视频的转发和分发,提供给客户端进行观看.由于直播推送端会存在于各 ...
随机推荐
-
【CoreAnimation】1 到 5
学习资源来自:图层树 . Quartz 2D Core Animation 复合引擎,职责为尽可能快地组合屏幕上不同的可视内容.这些内容被分解成多个独立的图层,存储在 图层树 的体系中.于是这个树形成 ...
-
SOL面向对象 五大原则
单一职责原则SRP(Single Responsibility Principle)是指一个类的功能要单一,不能包罗万象.如同一个人一样,分配的工作不能太多,否则一天到晚虽然忙忙碌碌的,但效率却高不起 ...
-
3.4.2内核下的I2C驱动
1. 框架1.1 硬件协议简介1.2 驱动框架1.3 bus-drv-dev模型及写程序a. 设备的4种构建方法a.1 定义一个i2c_board_info, 里面有:名字, 设备地址 然后i2c_r ...
-
Swift - 项目部署配置(支持的系统,设备和状态条样式等)
点击项目,在General选项卡中的“Deployment Info”栏目中可以进行一些项目的配置 Deployment Target:支持的iOS SDK的最低版本 Device:所支持的设备(iP ...
-
centos7配置ip
vi /etc/sysconfig/network-scripts/ifcfg-enp0s3 ONBOOT=yes 重启ip服务 systemctl restart network.service 开 ...
-
存个emacs配置
emacs配置 (global-set-key [f9] 'compile-file) (global-set-key [f10] 'gud-gdb) (global-set-key (kbd &qu ...
-
POJ 1985 Cow Marathon (模板题)(树的直径)
<题目链接> 题目大意: 给定一颗树,求出树的直径. 解题分析:树的直径模板题,以下程序分别用树形DP和两次BFS来求解. 树形DP: #include <cstdio> #i ...
-
(4)Microsoft office Word 2013版本操作入门_插入图片及图片的排版
1.word中插入图片和文绕图 1.1插入图片 :点击[插入]-->[图片] 或者 [联机图片]从网上选择. 1.2文字环绕: [格式] --->点击[位置] .[自动换行] 进行图 ...
-
输出1-100 , 奇数偶数分别添加标识(for循环语句嵌套if-else语句)
package com.summer.cn; /** * @author Summer * 输出1-100 , 奇数偶数分别添加标识 */ public class Test041518 { publ ...
-
PAT 甲级 1005 Spell It Right (20 分)
1005 Spell It Right (20 分) Given a non-negative integer N, your task is to compute the sum of all th ...