记录ffmpeg吞帧导致的整体解码延迟

问题描述

使用ffmpeg进行软解,发现与实时视频相比较,开始没有延迟,随着时间的推移,ffmpeg软解解码延迟越来越高。
下图为工作流程,拉流模块会从相机设备通过rtsp协议拉取原始码流,然后将原始码流传给解码器进行解码。
处理流程

解码延迟问题如下图记录所示,正常解码耗时如黄色框所示,13ms左右,因为不涉及B帧,因此解码的frame的dts(解码顺序)和pts(显示顺序)应该保持一致。但是经过中间的warnning后,pts和dts相差两帧(图中绿色线和橘黄线),解码耗时也如红色框所示,变为103ms,后面变得异常。
解码延迟
根据日志信息,勾画导致阻塞的情景,如下图所示:
在这里插入图片描述
随着吞帧(存帧)的数目越来越多,导致解码延迟越来越严重,表现出来就是视频播放延迟越来越严重。(正常解码不应该出现这种问题,这里推测ffmpeg本身bug)

解决方案

ffmepg会通过发送空流(eos流,data=NULL,size=0)来刷新解码管道,将全部的解码帧刷新数来,如下图所示,序号为127的对应码流的输入,会触发序号970的码流输出,序号127会被空流(eos流)刷新出来(实验是无论滞留解码器几针,都会随着eos流输入全部刷新出来,这说明不是数据不够引起的解码不出来,而是ffmpeg自己存在机制问题)。
在这里插入图片描述
因此由上述可以得出,当出现吞帧(存帧,滞留帧)导致解码延迟问题,可以向解码器发送空流来刷新滞留在解码器中的码流,解决该延迟问题。

直接发送空流导致的问题:
ffmpeg官方描述,发送空流后,解码器进入排空模式,从源码来看,数据进行排空模式后不在接受数据,因此向解码器发送空流后,还需要对解码器进行恢复操作。
在这里插入图片描述
在这里插入图片描述
由于不是很熟悉ffmpeg, 目前暂未找到恢复解码器的API,因此使用暴力手段,直接重新创建解码上下文。

缩减主要代码流程如下所示:

void DecodeVideoHandler::_Decode(BitStreamRef& pkt){
   
   
    m_ffmpeg_resource.packet->data = (pkt->data == NULL) ? NULL : (uint8_t*)pkt->data;
    m_ffmpeg_resource.packet->size = pkt->data_size;
    m_ffmpeg_resource.packet->pts = pkt->time_stamp;
    m_ffmpeg_resource.<
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值