今天在做音视频合成功能,由于Qt的定时器精度问题,导致视频合成有问题。
视频合成是采用FFmpeg实现的,将h264视频和aac视频合成到mp4容器中。音频写入到mp4容器验证过是正常的,但视频写入到mp4容器中,播放出来总是过快。查看了些资料,一般说是pts的问题,也按着官方文档去做,还是不行。
使用ffprobe工具统计总帧数却意外发现与预计帧数不一致。10秒的视频设置每秒15帧,共150帧。实际视频只有120帧,就纳闷了输入15帧/秒最后视频合成达不到15帧/秒。
最后定位到是QTimer的精度问题,视频的输入是通过定时器定时往队列里面拿的,比如设置20帧/秒,那么定时器就会每50ms触发一次。看了QTimer文档发现,该定时器的默认精度会有5%左右的误差。另外发现视频编解码与合成操作在主线程中负载较高,进一步放大定时器的误差。
定时器官方文档介绍:
有关更多QTimer的内容请看往期推文《Qt多种定时器》。
最后的解决方法是:
- 独立线程编解码合成;
- 设置QTimer定时器为高精度定时器(
setTimerType(Qt::PreciseTimer)
)。