# iOS音视频开发-了解编码及视频 ## 1. 视频H264编码 ### 1.1 为何编码? 从存储角度和网络传输以及通用性 3个角度,压缩已经成了不可或缺的动作.压缩编码最基本的指标,就是压缩比. 压缩比通常都是小于1(如果等于或者大于1,是不是就失去了编码的意义了.编码的目的就是为了压缩数据体量). ### 1.2 何为编码? 编码就是按照一定的格式记录采样和量化后的数据. #### 1.2.1编码中软编码和硬编码的区别? - 硬编码: 使用非CPU进行编码,例如使用GPU芯片处理 - 软编码: 使用CPU来进行编码计算. #### 1.2.2 软编码与硬编码的区分? - 软编码: 实现直接、简单,参数调整方便,升级易,但CPU负载重,性能较硬编码低,低码率下质量通常比硬编码要好一点。 - 硬编码:性能高,低码率下通常质量低于硬编码器,但部分产品在GPU硬件平台移植了优秀的软编码算法(如X264)的,质量基本等同于软编码。 - 硬编码,就是使用GPU计算,获取数据结果,优点速度快,效率高.\ - 软编码,就是通过CPU来计算,获取数据结果. #### 1.2.3 压缩算法 **压缩算法分为2种,有损压缩与无损压缩.** - 无损压缩:解压后的数据可以完全复原,在常用的压缩格式中,无损压缩使用频次较低 - 有损压缩:解压后数据不能完全复原,会丢失一部分信息.压缩比越小,丢失的信息就会越多.信号还原的失真就会越大. **需要根据不同的场景(考虑因素包括存储设备,传输网络环境,播放设备等)选用不同的压缩编码算法.** ### 1.3 VideoToolBox 硬编码 VideoToolbox 是一套纯C语言API。其中包含了很多C语言函数 VideoToolBox实际上属于低级框架,它是可以直接访问硬件编码器和解码器.它存在于视频压缩和解压缩以及存储在像素缓存区中的数据转换提供服务. **硬编码的优点:提高性能、增加效率、延长电量的使用** ## 2.了解视频 ![img](https://pic1.zhimg.com/80/v2-fd236dc3d800828e9d6fd5c48dba472c_720w.webp) ### 2.1视频的构成: - 图像 - 音频 - 元信息 **图像:** 视频内容本身就是一帧一帧的图片构成.人眼只要1秒钟连续播放16张以上的图片,就会认为这是一段连贯的视频.这种物理现象叫视觉暂留. **音频:** 视频一定是由音频+图像内容构成的.所以音频在视频中是单独的一个部分.针对这一块我们需要单独编码的. **元信息:** 元信息其实就是描述信息的信息.用于描述信息的结构\语义\用途\用法等.比如视频元信息就包含了视频的具体信息,比如编码格式,分辨率等等. ### 2.2视频中的编码格式 - **视频编码格式** - - H264编码的优势: - - 低码率 - 高质量的图像 - 容错能力强 - 网络适应性强 - **总结:** H264最大的优势,具有很高的数据压缩比率,在同等图像质量下,H264的压缩比是MPEG-2的2倍以上,MPEG-4的1.5~2倍. - **举例:** 原始文件的大小如果为88GB,采用MPEG-2压缩标准压缩后变成3.5GB,压缩比为25∶1,而采用H.264压缩标准压缩后变为879MB,从88GB到879MB,H.264的压缩比达到惊人的102∶1 - **音频编码格式:** - - AAC是目前比较热门的有损压缩编码技术,并且衍生了LC-AAC,HE-AAC,HE-AAC v2 三种主要编码格式. - - LC-AAC 是比较传统的AAC,主要应用于中高码率的场景编码(>= 80Kbit/s) - HE-AAC 主要应用于低码率场景的编码(<= 48Kbit/s) - **优势**:在小于128Kbit/s的码率下表现优异,并且多用于视频中的音频编码 - **适合场景**:于128Kbit/s以下的音频编码,多用于视频中的音频轨的编码 ### 2.3 容器(视频封装格式) **封装格式:** 就是将已经编码压缩好的视频数据 和音频数据按照一定的格式放到一个文件中.这个文件可以称为容器. 当然可以理解为这只是一个外壳. 通常我们不仅仅只存放音频数据和视频数据,还会存放 一下视频同步的元数据.例如字幕.这多种数据会不同的程序来处理,但是它们在传输和存储的时候,这多种数据都是被绑定在一起的. - **常见的视频容器格式**: - - AVI: 是当时为对抗quicktime格式(mov)而推出的,只能支持固定CBR恒定定比特率编码的声音文件 - MOV:是Quicktime封装 - WMV:微软推出的,作为市场竞争 - mkv:万能封装器,有良好的兼容和跨平台性、纠错性,可带外挂字幕 - flv: 这种封装方式可以很好的保护原始地址,不容易被下载到,目前一些视频分享网站都采用这种封装方式 - MP4:主要应用于mpeg4的封装,主要在手机上使用。 ## 3.视频压缩的可能性 视频压缩,该从那几个方向去进行数据的压缩了? 实际上压缩的本质都是从冗余信息开始出发压缩的. 而视频数据之间是有极强的相关性.也就是这样会产生大量的冗余信息.这样的冗余包括空间上的冗余信息和时间上的冗余信息. - **使用帧间编码技术可以去除时间上的冗余信息,具体包括如下** - - **运动补偿**: 运动补偿是通过先前的局部图形来预测,补偿当前的局部图像.它是减少帧序列冗余信息很有效的方法. - **运动表示**: 不同区域的图像需要使用不同的运动矢量来描述运动信息 - **运动估计**: 运动估计就是从视频序列中抽取运动信息的一整套技术. ### 3.1 编码概念 **IPB帧** 视频压缩中,每帧代表着一副静止的图像.而进行实际压缩时,会采用各种算法以减少数据的容量.其实IPB帧是最常用的一种方式: - **I帧**:**关键帧,采用帧内压缩技术**.帧内编码帧(intra picture),I帧通常是每个GOP(MPEG所使用的一种视频压缩技术)的第一帧.经过适度的压缩.作为随机访问的参考点,可以当做静态图像.I帧可以看做一个图像经过压缩后的产物.I帧压缩可以得到6:1的压缩比而不会产生任何可察觉的模糊现象.I帧压缩去除了视频空间的冗余信息. - **P帧**:**向前参考帧.压缩时只参考前一个帧.属于帧间压缩技术**. 前后预测编码帧(predictive-frame),通过将图像序列中前面已编码帧的时间冗余信息充分去除来压缩传输数据量的编码图像. - **B帧**:**双向参考帧,压缩时即参考前一帧也参考后一帧.帧间压缩技术.** 双向预测编码帧(bi-directional interpolated prediction frame),既要考虑源图像序列前面已编码帧,又要顾及源图像序列后面的已编码帧之间的时间冗余信息,来压缩传输数据量的编码图像. **读者角度解读** - **I帧**,自身可以通过视频解码算法解压成一张单独的完整的视频画面.所以I帧去掉的是视频帧在空间维度上的冗余信息. - **P帧**,需要参考前面的一个I帧或P帧解码成一个完整的视频画面 - **B帧**,需要参考前面的一个I帧或者P帧以及后面的一个P帧来生成一个完整的视频画面. - **所以,P和B帧去掉的视频帧在时间上维度上的冗余信息**. ### 3.2 解码中PTS 与 DTS **DTS(Decoding Time Stamp)** ,主要用于视频的解码; **PTS(Presentation Time Stamp)** ,主要用于解码节点进行视频的同步和输出. 在没有B帧的情况下,DTS和PST的输出顺序是一样的.因为B帧会打乱了解码和显示顺序.所以一旦存在B帧,PTS和DTS势必会不同.实际上在大多数编解码标准中,编码顺序和输入顺序并不一致.于是需要PTS和DST这2种不同的时间戳. ### 3.3 GOP概念 **两个I帧之间形成的一组图片,就是GOP(Group of Picture).** 通常在编码器设置参数时,必须会设置gop_size的值.其实就是代表2个I帧之间的帧数目. 在一个GOP组中容量最大的就是I帧.所以相对而言,gop_size设置的越大,整个视频画面质量就会越好.但是解码端必须从接收的第一个I帧开始才可以正确解码出原始图像.否则无法正确解码. 如果在一秒钟内,有30帧.这30帧可以画成一组.如果摄像机或者镜头它一分钟之内它都没有发生大的变化.那也可以把这一分钟内所有的帧画做一组. ![img](https://pic3.zhimg.com/80/v2-4afb22faa0edb9a88c373ba5bc064ac2_720w.webp) **一组帧**就是一个I帧到下一个I帧.这一组的数据.包括B帧/P帧. ### 3.3 SPS/PPS SPS/PPS实际上就是存储GOP的参数. **SPS: (Sequence Parameter Set,序列参数集)存放帧数,参考帧数目,解码图像尺寸,帧场编码模式选择标识等**. - 一组帧的参数集. **PPS:(Picture Parameter Set,图像参数集).存放熵编码模式选择标识,片组数目,初始量化参数和去方块滤波系数调整标识等.(与图像相关的信息)** 在一组帧之前我们首先收到的是SPS/PPS数据.如果没有这组参数的话,我们是无法解码. 如果我们在解码时发生错误,首先要检查是否有SPS/PPS.如果没有,是因为对端没有发送过来还是因为对端在发送过程中丢失了. SPS/PPS数据,我们也把其归类到I帧.这2组数据是绝对不能丢的. ## 4. 视频花屏/卡顿原因 我们在观看视频时,会遇到花屏或者卡顿现象.那这个与我们刚刚所讲的GOF就息息相关了. - 如果GOP分组中的P帧丢失就会造成解码端的图像发生错误. - 为了避免花屏问题的发生,一般如果发现P帧或者I帧丢失.就不显示本GOP内的所有帧.只到下一个I帧来后重新刷新图像. - 当这时因为没有刷新屏幕.丢包的这一组帧全部扔掉了.图像就会卡在哪里不动.这就是卡顿的原因. **所以总结起来,花屏是因为你丢了P帧或者I帧.导致解码错误. 而卡顿是因为为了怕花屏,将整组错误的GOP数据扔掉了.直达下一组正确的GOP再重新刷屏.而这中间的时间差,就是我们所感受的卡顿.** ## 5.颜色模型 我们开发场景中使用最多的应该是 RGB 模型 ![img](https://pic3.zhimg.com/80/v2-892a6dad41d32ac11611566523626bce_720w.webp) 在 RGB 模型中每种颜色需要 3 个数字,分别表示 R、G、B,比如 (255, 0, 0) 表示红色,通常一个数字占用 1 字节,那么表示一种颜色需要 24 bits。那么有没有更高效的颜色模型能够用更少的 bit 来表示颜色呢? 现在我们假设我们定义一个**「亮度(Luminance)」**的概念来表示颜色的亮度,那它就可以用含 R、G、B 的表达式表示为: ```text Y = kr*R + kg*G + kb*B ``` Y 即「亮度」,kr、kg、kb 即 R、G、B 的权重值。 这时,我们可以定义一个**「色度(Chrominance)」**的概念来表示颜色的差异: ```text Cr = R – Y Cg = G – Y Cb = B – Y ``` Cr、Cg、Cb 分别表示在 R、G、B 上的色度分量。上述模型就是 **YCbCr** 颜色模型基本原理。 **YCbCr** 是属于 **YUV** 家族的一员,是在计算机系统中应用最为广泛的颜色模型,就比如在本文所讲的视频领域。***在 YUV 中 Y 表示的是「亮度」,也就是灰阶值,U 和 V 则是表示「色度」。\*** **YUV 的关键是在于它的亮度信号 Y 和色度信号 U、V 是分离的。那就是说即使只有 Y 信号分量而没有 U、V 分量,我们仍然可以表示出图像,只不过图像是黑白灰度图像**。在YCbCr 中 Y 是指亮度分量,Cb 指蓝色色度分量,而 Cr 指红色色度分量。 现在我们从 ITU-R BT.601-7 标准中拿到推荐的相关系数,就可以得到 YCbCr 与 RGB 相互转换的公式 ```text Y = 0.299R + 0.587G + 0.114B Cb = 0.564(B - Y) Cr = 0.713(R - Y) R = Y + 1.402Cr G = Y - 0.344Cb - 0.714Cr B = Y + 1.772Cb ``` 这样对于 **YCbCr** 这个颜色模型我们就有个初步认识了,但是我们会发现,这里 **YCbCr** 也仍然用了 3 个数字来表示颜色啊,有节省 **bit** 吗?为了回答这个问题,我们来结合视频中的图像和图像中的像素表示来说明 - 假设图片有如下像素组成 ![img](https://pic2.zhimg.com/80/v2-e834a437ca3971e80af48ec35d303bb9_720w.webp) 一副图片就是一个像素阵列.每个像素的 3 个分量的信息是完整的,**YCbCr 4:4:4**。 ![img](https://pic3.zhimg.com/80/v2-bc186e8c85439db556230dd77df7947a_720w.webp) 下图中,对于每个像素点都保留「亮度」值,但是省略每行中偶素位像素点的「色度」值,从而节省了 bit。**YCbCr4:2:2** ![img](https://pic1.zhimg.com/80/v2-0f6c0c6f7fe0cdc3bf918c8b6bc9be4c_720w.webp) 上图,做了更多的省略,但是对图片质量的影响却不会太大.**YCbCr4:2:0** ![img](https://pic1.zhimg.com/80/v2-c956932981497aa3bc3e67ef56159ab0_720w.webp) ## 6. 音频编码 常用压缩编码格式 WAV编码 WAV编码的一种实现方式(其实它有非常多实现方式,但都是不会进行压缩操作).就是在源PCM数据格式的前面加上44个字节.分别用来描述PCM的采样率,声道数,数据格式等信息. - 特点:音质非常好,大量软件都支持其播放 - 适合场合:多媒体开发的中间文件,保存音乐和音效素材 MP3编码 MP3编码具有不错的压缩比,而且听感也接近于WAV文件,当然在不同的环境下,应该调整合适的参数来达到更好的效果. - 特点:音质在128Kbit/s以上表现不错,压缩比比较高.大量软件和硬件都支持.兼容性高. - 适合场合:高比特率下对兼容性有要求的音乐欣赏. AAC编码 AAC是目前比较热门的有损压缩编码技术,并且衍生了LC-AAC,HE-AAC,HE-AAC v2 三种主要编码格式. - LC-AAC 是比较传统的AAC,主要应用于中高码率的场景编码(>= 80Kbit/s) - HE-AAC 主要应用于低码率场景的编码(<= 48Kbit/s) - 特点:在小于128Kbit/s的码率下表现优异,并且多用于视频中的音频编码 - 适合场景:于128Kbit/s以下的音频编码,多用于视频中的音频轨的编码 Ogg编码 Ogg编码是一种非常有潜力的编码,在各种码率下都有比较优秀的表现.尤其在低码率场景下.Ogg除了音质好之外,Ogg的编码算法也是非常出色.可以用更小的码率达到更好的音质.128Kbit/s的Ogg比192Kbit/s甚至更高码率的MP3更优质.但目前由软件还是硬件支持问题,都没法达到与MP3的使用广度. - 特点:可以用比MP3更小的码率实现比MP3更好的音质,高中低码率下均有良好的表现,兼容不够好,流媒体特性不支持. - 适合场景:语言聊天的音频消息场景 原文地址:[iOS音视频开发-了解编码及视频 - 资料 - 我爱音视频网 - 构建全国最权威的音视频技术交流分享论坛](