一种FFmpeg提示“dts < pcr, TS is invalid“的解决方法

此问题出现在使用FFmpeg(动态库)输出UDP+TS流且开启muxrate输出CBR时,音频为aac编码,视频为264编码(libx264),视频部分使用vbv-bufsize及vbv-maxrate和nal-hrd=cbr编码CBR码流,可以看到程序刚跑起来FFmpeg的log回调就会疯狂报标题里提到的dts < pcr警告,这个警告的源码位置只有一个,就在libavformat\mpegtsenc.c的mpegts_write_pes这个函数里,但是读了下代码,也没看出来为什么会报这个警告,后来找到了这两篇参考:

FFMPEG转码音视频不同步情况总结 https://blog.csdn.net/liuchen1206/article/details/79461434

ffmpeg 奇葩问题2 https://blog.csdn.net/WaitForDone/article/details/78030095

其中第一篇参考文章里提到了编码速度问题,提到去掉B帧这个操作,而我的应用直接设置了zerolatency的tune相当于也是不带B帧的编码,第二篇文章提到了几个点,一开始直接放到了结果上,疯狂尝试各种qmin、qmax设置,结果都没有见效,而且实际发现我的视频码流并没有文章作者提到的编码出来的视频帧偏大的问题,其实用的就是默认的量化值,每帧大小也基本符合整体目标码率,最后百思不得其解时,试了下直接用ffmpeg命令行进行同样参数的编码操作,发现并没有报这个“dts < pcr”的警告,而且是跑了很长时间后也一次警告都没有,又结合了下第二篇参考文章中提到的delay设置,于是开始比较ffmpeg命令行程序的各种format、codec初始化操作参数,最后终于找到了问题:

原来,ffmpeg命令行程序有一个叫muxdelay的参数(浮点数,单位秒),对应的是AVFormatContext的max_delay这个属性,而ffmpeg命令行对这个参数有一个0.7s的默认值(fftools\ffmpeg_opt.c的init_options),实测去掉这个0.7s的默认值后,ffmpeg的输出也一样会报dts < pcr的警告,而我的程序在初始化format时并没有设置过这个值,直接用的默认0,于是也加上了默认0.7s的代码,再次测试就不会有这个警告了,不过,遗憾的是,这个参数不知为何并不支持使用dictionary的option方式传入format初始化,导致只能先在代码像ffmpeg命令行实现那样加上这个0.7的delay值。

博主友情提示:

如您在评论中需要提及如QQ号、电子邮件地址或其他隐私敏感信息,欢迎使用>>博主专用加密工具v3<<处理后发布,原文只有博主可以看到。