C++基于ffmpeg和QT开发播放器~学习笔记

Posted 长安紫薯

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++基于ffmpeg和QT开发播放器~学习笔记相关的知识,希望对你有一定的参考价值。

C++基于ffmpeg和QT开发播放器

B站网址

https://www.bilibili.com/video/BV1h44y1t7D8?p=2&spm_id_from=pageDriver
http://www.ffmpeg.club/qt_download.html

封装格式和编码格式

格式头:使用什么压缩方式,帧率是多少,音频采用什么压缩方式,视频采用什么压缩方式,对应关键帧的索引,并不是所有视频都有,如没有关键帧索引的,在seek时就会很慢。
视频帧和音频帧交叉出现,但不太可能完全一对一。如视频帧1秒25帧,但音频很难做到的。音频是根据采样率定的,比如44100。对应1秒钟视频就不好算,一般是一秒22.5帧。

YUV转换成RGB数据量是非常大的,200万像素,一个像素RGB是3个字节,一幅画面有6M,一秒钟有10幅画面就60M,
一秒钟有20幅画面就120M,一分钟就几个G了。所以大家要注意,如果把这部分RGB的做缓冲,一定要考虑好,数据量非常大。不像我们做视频帧。视频帧是很小的,如一副画面有6M,经过压缩后可能只有10k。能压到1%,甚至0.5%。可以选择压缩率,甚至效果还不差。
YUV的复制和缓冲开销都不用考虑,但RGB的复制和缓冲一定要考虑。YUV可以采用软解压,也可以采用硬解压,目前主流CPU的解码应该是比硬解码比较强的,这个是做过测试的。现在如8核的CPU解码非常快,但是耗电量非常大,CPU会一直很热,好处是兼容性很强。目前更多的还是基于软解码,将来可能更多的还是基于硬解码,因为硬解码快,可能1秒可以解压100帧多。硬解码是很快的,一般是我们写好的程序,烧录在CPU上或者显卡上的。对应ARM来说,直接就是硬件电路,这部分解码时间可以忽略不计的。但也有问题,它是固话在硬件中的,无法做优化。它解码的性能是固定好的。

像素格式


显卡的解码并不比我们的CPU强

注意这里有个坑,col3后面有时会补齐格式,会增加几个,为提升计算效率,这样在像素复制时,必须跳过这些,否则就出错了。知道了一般拷贝你就要8的倍数。如1024。不要一个一个拷贝,一块进行拷贝这样效率高。

很多人有错误的认识,认为软解码慢,那是嵌入式,它确是慢。比如DSP芯片,它的软解码就慢,它单核主频才1G,但现在的主流CPU多核,8核2.0G的,很多情况下比硬解码快。它的软解码的性能和兼容性都是强于硬解码的,而硬解码是固定的,比如它就只能60帧/s,硬解码的好处是它无需解码指令的转换,那CPU的开销就小,它直接就是电路。如CPU做先要把指令转换为电路,然后在进行运算。硬解码直接把电路跑通就行了,所以它的热功耗会非常小,省电。

YUV


YUV可以多种存储方式,而RGB一般一种存储方式。
YUV4:4:4 YUV类似RGB,转换简单
YUV4:2:2,第一个还是YUV,但第二个UV共用前一个的Y
YUV4:2:0,我们日常都采用这个格式,它不是连续4个,而是上下,为什么呢,因为图像周边色度是相似的,所以它采用2*2,然后共用一个UY,这样可以看出它占用的存储空间是最小的,占12b。
YUVP,先连续存Y,再连续存UV,这我们需要关注什么?之前方式只需一个数组,而这个需要两个数组,一个存Y,一个存UV

PCM音频参数


采样率 44100什么意思?就是每秒钟采样44100次。那可以知道,采样率越大,听到的声音越真实,采样率越小,听到的声音越假。
那双声道,就是左右声道,更类似我们人类听,现在话筒都支持两个采样点,那信息量又翻一倍。


AV_SAMPLE_FMT_S16 交叉存储C1左声道,C2右声道
AV_SAMPLE_FMT_S16P,平面存储,则先存储左声道C1,后存储右声道C2,两个数组
必然说加快播放速度,视频很容易,如25帧/s,那每秒刷50帧,就是两倍速。那音频如何处理,就可以改变播放和原始采样率的关系,那就是快速播放。

MP4


它有个BOX结构,BOX还可以嵌套,首先有个总时长,还有视频和音频时间,因为它们不总是一致的,总会相差一点



GOP


这组数据是可以独立播放的,GOP,
如你随便抽出10帧,并不一定能独立播放的,如果你没有关键帧,或者关键帧少数据,那解码不出来,

  • I帧,关键帧(一帧视频的完整数据,这帧可以单独解码),比如监控,降低帧率,1秒刷新1次,就解关键帧,其它帧不解。在做运动分析时,就只解关键帧,其它帧都不要了,24路监控,摄像头正常就行了,其它帧解析开销很大,关键帧可以单独解码。一般设置成为25,50,那什么意思,就是指每50帧,就一帧关键帧。也可能有问题,那这关键帧丢掉了,这50帧就都不正确了。中间丢掉一帧,画面都乱了。如果只依赖前一帧,就没问题。因为每一帧都是针对它的参考帧的变化,前面乱了,后面自然也就乱了。
  • P帧,是针对前一帧的变化
  • B帧,是针对前后帧的变化,需要先把前面的帧和后面的帧都解完,才能把当前B解码,这样会出现解码顺序和帧顺序不一致,因为存放的顺序是按显示的顺序存放的。那就必须有缓冲。就会发现有人做mpeg最后会少一段,就在缓冲中,不缓冲就没法解码。画面的不正确,画面的花屏,都可能跟这个有关。

以上是关于C++基于ffmpeg和QT开发播放器~学习笔记的主要内容,如果未能解决你的问题,请参考以下文章

C++ QT结合FFmpeg实战开发视频播放器-17FFmpeg基本介绍

QT软件开发-基于FFMPEG设计视频播放器-GPU硬解图像

QT软件开发-基于FFMPEG设计视频播放器-支持流媒体地址播放

QT软件开发-基于FFMPEG设计视频播放器-支持软解与硬解-完整例子

QT软件开发-基于FFMPEG设计视频播放器-软解图像

QT软件开发-基于FFMPEG设计视频播放器-支持软解与硬解