前言
学习之前请容许我悼念下雷霄骅前辈,他的博客是我学习视频编解码资料的主要来源,雷霄骅前辈博客地址.我们主要是来学习FFmpeg和SDL,学习的第一阶段我们要使用它们来做一款跨平台的播放器,作者是从事iOS开发的,所以会将这个跨平台播放器集成于iOS平台,各位有什么好的建议可以在文章下方留言.FFmpeg主要是为了处理音视频的编码,而SDL则是为了展示画面,至于具体的知识还是需要阅读雷哥的博客去学习.
- 视频解码器(FFmpeg)
主要掌握几个常用的FFmpeg解码的函数,主要实现H.264->YUV的转换
- 视频显示(SDL)
掌握SDL显示视频的函数,实现YUV -> 设备屏幕
视频播放器原理
-
这是雷哥的一张图,简单介绍了视频播放器原理.我们日常生活中,视频,音频的结尾都会有类似.MP4之类的字符,这里就是他们的封装格式.我们拿到这个视频文件如果想播放的话,会将它解封装成音频压缩数据和视频压缩数据,在对这两个数据进行解码,获得音频采样数据和视频像素数据,他们分别会送到我们的声卡和显卡最终到达播放设备,这里需要注意的是我们需要解决声画同步的问题,这个我们以后再说.
封装格式(MP4,RMVB,TS,FLV,AVI)
- 上图讲的是比较形象的封装格式,同时也列举了一些封装格式的推出机构以及目前使用的主要领域.下图举例了两种比较代表性的封装格式,他们的具体区别图上可以看出,MPEG2 - TS这种封装格式在损坏了某个TS包时依旧可以继续播放,而FLV若损坏了文件头那么他将无法播放.
视频编码数据(H.264,MPEG2,VC-1)
- 上图主要讲的几种视频编码数据,通俗的讲视频编码其实就是将我们肉眼看到的每一幅图进行压缩,压缩成流,当然编码和压缩肯定是不能画等号的.这些流中也有集中压缩散发我们后面会讲到,压缩和不压缩前后体积大概相差百倍,这就对传输和存储带来了巨大的压力,所以我们才要对其进行视频编码,在我们的日常生活中H.264目前是最常见的,所以许多做视频的公司招聘上都会要求了解FFmpeg,H.264等.下面我们主要对H.264中最常见的IPB压缩算法来进行介绍.
IPB
视频流中的每一张静止的画面其实都是一帧,在压缩的算法中IPB算是一种比较常见的算法了.I帧是关键帧表示一副画面的完整数据,所以解码的时候只需要自身就可以完成,P帧是差别帧表示当前画面和上一幅画面的区别,上一幅画面的数据IPB三种帧都有可能,他的解码依赖于上一帧数据,最终实际上还是要依赖I帧才能实现解码.B帧是双向关键帧,表示该画面数据与上一帧和下一帧的区别,所以解码的时候我们需要对他的前后帧都进行解码,优点是压缩率高,但是处理起来计算机的处理负担会比较大.
从上面的解释看,我们知道I和P的解码算法比较简单,资源占用也比较少,I只要自己完成就行了,P呢,也只需要解码器把前一个画面缓存一下,遇到P时就使用之前缓存的画面就好了,如果视频流只有I和P,解码器可以不管后面的数据,边读边解码,线性前进,大家很舒服。但网络上的电影很多都采用了B帧,因为B帧记录的是前后帧的差别,比P帧能节约更多的空间,但这样一来,文件小了,解码器就麻烦了,因为在解码时,不仅要用之前缓存的画面,还要知道下一个I或者P的画面(也就是说要预读预解码),而且,B帧不能简单地丢掉,因为B帧其实也包含了画面信息,如果简单丢掉,并用之前的画面简单重复,就会造成画面卡(其实就是丢帧了),并且由于网络上的电影为了节约空间,往往使用相当多的B帧,B帧用的多,对不支持B帧的播放器就造成更大的困扰,画面也就越卡。 一般平均来说,I的压缩率是7(跟JPG差不多),P是20,B可以达到50,可见使用B帧能节省大量空间,节省出来的空间可以用来保存多一些I帧,这样在相同码率下,可以提供更好的画质。
上面这段话参考自CSDN Rachel-Zhang博主的一篇文章.
音频编码数据(AAC,MP3,AC-3)
- 一般音频编码的重要性远不如视频编码重要,因为音频数据就算不压缩,他的体积我们也是可以接受的.音频压缩中最常用的AAC原始码流他是由一个一个的ADTS frame组成的,每个ADTS的大小还不是固定的.其中每个ADTS frame之间通过syncword(同步字)进行分隔。同步字为0xFFF(二进制“111111111111”)。AAC码流解析的步骤就是首先从码流中搜索0x0FFF,分离出ADTS frame;然后再分析ADTS frame的首部各个字段。这就是AAC码流解码时的主要逻辑.
视频像素数据(YUV420P,RGB)
- 我们生活中比较常见的像素数据主要有两种,RGB个式和YUV格式,其中以后者的YUV420P居多.RGB格式的原理很简单,使用RGB我们可以把一幅图片的每个点上的颜色记录下来,同时生活中所有的颜色都是由三原色组成的,差别为非就是三者的比例不同罢了.YUV的原理主要就是人眼对亮度敏感而对色度并不敏感,所以对色度进行了比较深的压缩,可以看出对U和V分别压缩到了Y的四分之一,也就是宽压缩二分之一而长压缩二分之一,YUV先从左上角到右下角一行行存储了图片的Y信息,再然后是U信息,最后才是V信息,我们播放YUV视频时一般是无法直接播放的,因为他没有文件头所以我们要对视频的一些基本信息(例如画面宽高)进行设置才可以播放.
音频采样数据(PCM)
- 学习PCM前我们需要了解什么是采样,这个在大学教材数字信号处理有讲
声波其实是一个连续的模拟信号,我们如果想在计算机中对他进行处理,那么必须要将他转换为数字信号,我们对这个连续的模拟信号(类似正弦波)进行每隔一定的时间就进行取点,获取到该点的纵坐标值,然后将这些点用平滑的曲线连接起来,就能完成模拟信号转数字信号,当然我们还要对其中的噪声等因素进行处理,这些都是后话,这个采样的时间间隔越短我们所转化的数字信号的还原程度就越高.采样率我们一般根据人耳的识别频率以及奈奎斯特定理设为44.1kHZ,PCM格式也是不包含文件头的,所以我们直接播放时要将它的采样率和采样精度设置好,否则就会出问题.