您的位置:首页 > 其它

avcodec_decode_video2解码图像不成功分析

2016-08-09 18:15 288 查看
今天在测试解码一个AVI格式的视频文件时,调用解码函数:

avcodec_decode_video2(pCodecCtx, pFrame, &got_picture,packet);

在解码第一帧的时候,函数返回的是一个大于0的数,但是got_picture返回的确实0,这说明函数没有完整的解码出一帧。但是函数

也没执行失败,很大可能是被解码器缓存起来了。

1、

先看看一段问题,对于一个AVI格式视频,带有B帧。通过工具分析出如下结构:



图1

根据码率顺序,我们看到第一个GOP的大概结构是I P B P B B P B B。

一般的解码操作代码如下结构:

while(av_read_frame(pFormatCtx, packet)>=0)
{
if(packet->stream_index==videoindex)
{
ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
}
}

av_read_frame()是按照PTS顺序读取帧的,通过看图1,显然PTS的顺序不是顺序累加的,有B帧的存在,packet解码时间DTS和PTS是对应不上了。比方说当我读取到第0个P帧的时候,由于它参考了I帧,所以这个时候avcodec_decode_video2是没有能力解码此帧的。所以avcodec_decode_video2返回的是一个大于0的数,但是got_picture返回的是0。

另外,很有可能第一帧I帧是解码不出来的,因为后面的B,P帧都参考I帧,这样的话解码器就好缓存I帧,直到没有帧依赖此I帧。

2、

另外还有个现象,一个AVI格式,里面都是I帧:



图2

这种情况也会出现解码第一帧失败情况。这种情况下由于都是I帧,应该不存在参考帧问题,网上有些地方说是因为缓存处理,解码器解码时会缓存几帧提高程序的效率,防止程序在解码这一步等待太久。

对这一块感觉不是太理解,希望有明白的大神能够指点说明下。

针对这种因缓存造成的问题,解决办法还是有的。

第一种:

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) 
{  
  ;
}  
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) 
{
;
}  



这种就是记录缓存的帧个数,最后再解码出来。

第二种:

设置AVCodecContext中的flags,强制解码器快速输出。这样一开始就可以正常的解码第一帧。

参考文章:
http://blog.csdn.net/leixiaohua1020/article/details/19016109# http://blog.jianchihu.net/avcodec_decode_video2-no-pic.html http://blog.csdn.net/huyinguo/article/details/4725326 http://bbs.csdn.net/topics/390692774
上述的问题解答,如果有更好解释的欢迎大家指正。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  AVI ffmpeg