ffmpeg解决帧丢失问题:还有几帧数据缓存在解码器中,需要取出来

文章目录

 


前言

       

最近在学习如何使用ffmpeg解析视频,在网上查找的办法大同小异,直接说解码函数avcodec_send_packet和avcodec_receive_frame,这两个是一起的,必须同时出现,我是通过子线程读取视频文件,不停地将读取出来的包放入videoQueue或audioQueue中,再利用SDL创建videoThread来不断从video队列里拿出packet送入解码器中,即利用avcodec_send_packet将包送入解码器中,利用avcodec_receive_frame将ffmpeg解析出来的Frame取出来,但通过进度条或直接打印解码出来的Frame->pts来看当前帧的时间,总会在最后少那么几帧,很郁闷

一、帧丢失原因

解码器内部有缓存队列,开始时会先存几帧数据,再开始输出有效Frame,所以到最后,解码器里还有几帧数据,根据视频大小不同,解码器里还剩余的packet数量也不太一样,所以到最后还有几帧没有输出,出现帧丢失现象。

二、解决方法

第一想法就是来网上搜如何解决帧丢失,但很少有,有也是没源代码,特别是ffmpeg的avcodec_send_packet和avcodec_receive_frame的帧丢失解决办法更少,于是就转向官方文档,终于找到一点头绪,如下图是在avcode.h中找到的,也是这两函数声明的头文件

上面说明出于需要或者提升性能,在最后编解码器还可能缓存了几帧数据,需要刷新编解码器,还提供了思路

 

1.送入空包进avcodec_send_packet

如上图官方文档提供的思路,需要送入空包进解码器,代码如下

packet->data = nullptr;
packet->size = 0;
avcodec_send_packet(pVideoCodecCtx, packet);

2.调用avcodec_receive_frame

送入空包后,再调用avcodec_receive_frame将解码出来的frame取出来,直到avcodec_receive_frame返回AVERROR_EOF才结束,代码如下

/**队列里取数据**/
        if (packet_queue_get(&pVideosState->videoQueue, packet, 0) <= 0)
        {

            if (pVideosState->readFinished)
            {
                /**队列里面没有数据了且读取完毕了**/
                while(1)
                {
                    packet->data = nullptr;
                    packet->size = 0;
                    avcodec_send_packet(pVideoCodecCtx, packet);
                    
                    ret = avcodec_receive_frame(pVideoCodecCtx, pFrame);
                    if(ret == AVERROR_EOF)
                        break;
                    
                    //进行你所需的一系列操作
                }
                //这个循环跳出后就全部取出解码器缓存的数据了
            }
        }

 

 

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值