iOS音视频开发学习(二)—— 基本术语了解
硬编码&软编码
为何编码:从存储角度、网络传输以及通用性3个角度来讲,压缩已经成了不可或缺的动作,压缩编码最基本的指标是压缩比。
何为编码:编码就是按照一定的格式记录采样和量化后的数据。
软编码和硬编码的区别:
软编码:使用CPU来计算数据结果。优点:实现直接,简单,参数调整方便。视频编码框架ffmpeg+x264算法把原数据YUV/RGB转换成H264,音频则使用fdk_aac将音频数据PCM转换成AAC
硬编码:使用非CPU(如显卡GPU、专用的DSP、FPGA、ASIC芯片等)来计算数据结果。优点:速度快,效率高。iOS上硬编码框架是VideoToolBox和AudioToolbox
大端(Big-Endian)&小端(Little-Endian)
大端:高位字节放在内存低地址处,低位字节则放在高地址处。(理解记忆:从左到右是低地址到高地址的话,比较符合我们平时的读写习惯)
小端:与大端相反,低位字节放在内存低地址处,高位字节则放在高地址处。
如何区分大小端:
例如,16位宽的数0x1234在大端模式CPU内存中的存放方式(假设从地址0x4000开始存放)为
内存地址 | 0x4000 | 0x4001 |
---|---|---|
存放内容 | 0x12 | 0x34 |
而在小端模式CPU内存中的存放方式则为:
内存地址 | 0x4000 | 0x4001 |
---|---|---|
存放内容 | 0x34 | 0x12 |
如何测试编译器是大端还是小端
int main(){
int x;
char x0, x1;
x = 0x1234;
x0 = ((char *)&x)[0]; //低地址
x1 = ((char *)&x)[1]; //高地址
printf("x0=0x%x,x1=0x%x", x0, x1);
return 0;
}
以上,如果低地址x0=0x12则为大端,反之则为小端。
大部分的操作系统都是小端,而通讯协议是大端。
H264/AVC视频编码(压缩)标准
H264编码.png编码优势:
- 低码率:在同等图像质量下,采用H.264技术压缩后的数据量只有MPEG2的1/8,MPEG4的1/3
- 高质量的图像:H.264能提供连续、流畅的高质量图像
- 容错能力强:H.264提供了解决在不稳定网络环境下容易发生的丢包等错误的必要工具
- 网络适应性强:H.264提供了网络抽象层(Network Abstraction Layer),使得H.264的文件能容易地在不同网络上传输(例如互联网,CDMA,GPRS,WCDMA,CDMA2000等)
- 高压缩率:H.264的压缩比达到惊人的102∶1
VCL
视频编码层:压缩后、去冗余的数据。技术核心包括以下几点。往往与网络抽象层互相配合。
- 帧内预测:解决的是空域数据冗余问题,一幅图里数据在宽高空间内包含了很多颜色,光亮.人的肉眼很难察觉的数据. 对于这些数据,我们可以认作冗余.直接压缩掉的。
- 帧间预测:解决的是时域数据冗余问题,摄像头在一段时间内所捕捉的数据没有较大的变化,我们针对这一时间内的相同的数据压缩掉.这叫时域数据压缩。
一般而言,帧间预测编码效率比帧内预测更高,其原因在于视频的帧间相关性很强,信息的冗余度很高。
- 变换编码:绝大多数图像都有一个共同的特征:平坦区域和内容缓慢变化区域占据一幅图像的大部分,而细节区域和内容突变区域则占小部分。也可以说,图像中直流和低频区占大部分,高频区占小部分。这样,空间域的图像变换到频域或所谓的变换域,会产生相关性很小的一些变换系数,并可对其进行压缩编码,即所谓的变换编码(Transform Coding)。
- 去块效应滤波:在视频编码中人厌察觉到的小块边界处的不连续。
块效应产生的原因:
1、对图像进行编码的时候,被分成的快进行DCT变换后相关性被忽略。
2、因为量化步长不同而高频分量不一样,从而导致图像相关性受到破坏。
3、H264的运动补偿加剧了块效应。
4、时域预测技术使得参考图像中存在的边界不连续可能会传递到后续图像编码。
- 熵编码:利用信源的统计特性进行码率压缩的编码称为熵编码。特点是无损编码,但是压缩率比较低,一般用在变换编码后面作进一步压缩。常用的有变长编码(huffman编码)和算术编码
变长编码
对出现概率大的符号分配短字长的二进制码,对出现概率小的符号分配长字长的二进制码,得到符号平均码长最短的码。也称为最佳编码。
算术编码
与huffman编码不同,不采用码字表示输入符号的方法,而是采用一个浮点数来代替一串输入符号,经算术编码后输出一个小于1,大于等于0的浮点数,在解码端在进行唯一的解码,恢复原符号序列。
这两种编码方法实际应用中都有受硬件精度的问题,即如何定点化表示小数的问题。
NALU
定义:NAL全称Network Abstract Layer,即网络抽象层,NALU是一个图像序列的组成,是H264编码的基本结构。分析一个H264文件,以00 00 00 01开始和结尾的部分代表一个NAL单元(NAL-Unit)。
作用:负责格式化数据并提供头信息,以保证数据适合各种信道和存储介质上的传播。NAL这一概念的提出提供了一个视频编码器和传输系统的友好接口,使得编码后的视频数据能够有效地在各种不同的网络环境中传输。
结构:开始码+NALU头+NALU数据
结论:为了实现编解码器良好的网络适应性,需要做两方面的工作:第一、在Codec中将NAL这一技术完整而有效的实现;第二、在遵循H.264/AVC NAL规范的前提下设计针对不同网络的最佳传输方案。如果实现了以上两个目标,所实现的就不仅仅是一种视频编解码技术,而是一套适用范围很广的多媒体传输方案,该方案适用于如视频会议,数据存储,电视广播,流媒体,无线通信,远程监控等多种领域。
序列/帧/片/宏块
帧序列.png如上图所示:
序列(Sequence):第一行表示一段时间内的图像变化不大的集合,称之为一个序列。序列可以理解为有着相同特点的一段数据。但是如果某个图像与之前的图像变换很大,很难参考之前的帧来生成新的帧,那就结束该序列,开始下一段序列。重复上一序列的做法,生成新的一段序列。
帧(Frame):H264结构中,一个视频图像编码后的数据叫做一帧。在H264协议内定义了三种帧,分别是I帧、B帧与P帧。I帧是一个完整的图像帧,P帧与B帧的差别就是P帧是参考之前的帧而生成的,而B帧是参考前后图像帧编码生成的。一帧由一个片或多个片组成。
片(Slice):一帧图片经过 H.264 编码器之后,就被编码为一个或多个片,而**装载着这些片的载体,就是 NALU **。
上图中可以看出,片都是由 NALU 装载并进行网络传输的,但是这并不代表 NALU 内就一定是片,这是充分不必要条件,因为 NALU 还有可能装载着其他用作描述视频的信息。
片的主要作用是用作宏块(Macroblock)的载体(ps:下面会介绍到宏块的概念)。片之所以被创造出来,主要目的是为限制误码的扩散和传输。
如何限制误码的扩散和传输?
每个片(slice)都应该是互相独立被传输的,某片的预测(片(slice)内预测和片(slice)间预测)不能以其它片中的宏块(Macroblock)为参考图像
宏块(Macroblock):一个片由一个或多个宏块(MB)组成,一个宏块由16x16的yuv数据组成。宏块是H264编码的基本单位,是视频信息的主要承载者。
片与宏块的关系.png上图结构中,我们不难看出,每个分片也包含着头和数据两部分:
- 分片头中包含着分片类型、分片中的宏块类型、分片帧的数量、分片属于那个图像以及对应的帧的设置和参数等信息。
-
分片数据中则是宏块,这里就是我们要找的存储像素数据的地方。
宏块的组成.png
从上图中,可以看到,宏块中包含了宏块类型、预测类型、Coded Block Pattern、Quantization Parameter、像素的亮度和色度数据集等等信息。
参考:https://www.jianshu.com/p/0c296b05ef2a
GOP画面组(Group of Pictures)
GOP说白了就是两个I帧之间的间隔。视频的编码(压缩)是按照“组”来进行的,每一个组叫作GOP(Group of Picture,图像组),表示一组连续的画面。通常意义上的GOP由I帧开始,到下一个I帧之前的帧结束(严格意义上讲,GOP由IDR帧开始,到下一个IDR帧之前的帧结束,这种情形下一个GOP中会有多个I帧。不过,一般而言,I帧基本上都是IDR帧。)
- I帧:表示关键帧,又称帧内编码帧,一帧画面的完整保留,解码时只需要本帧数据就可以进行独立解码。
- P帧:又称帧间预测(向前预测)编码帧,需要参考前面一帧才能进行编码。表示的是当前帧画面与前一帧(前一帧可能是I帧也可能是P帧)的差别。解码时需要用之前缓存的画面叠加上本帧定义的差别,生成最终画面。与I帧相比,P帧通常占用更少的数据位,但不足是,由于P帧对前面的P和I参考帧有着复杂的依耐性,因此对传输错误非常敏感。
- B帧:又称双向预测编码帧,也就是B帧记录的是本帧与前后帧的差别。也就是说要解码B帧,不仅要取得之前的缓存画面,还要解码之后的画面,通过前后画面的与本帧数据的叠加取得最终的画面。B帧压缩率高,但是对解码性能要求较高,对于不支持B帧解码的播放器容易卡顿。
DTS& PTS
- DTS(Decoding Time Stamp):即解码时间戳,这个时间戳的意义在于告诉播放器该在什么时候解码这一帧的数据。
- PTS(Presentation Time Stamp):即显示时间戳,这个时间戳用来告诉播放器该在什么时候显示这一帧的数据。
通常 DTS 和 PTS 的顺序是一致的。但如果有 B 帧时,解码顺序和播放顺序不一致了。这时就需要DTS 告诉我们该按什么顺序解码这几帧图像,PTS 告诉我们该按什么顺序显示这几帧图像。