音视频入门H264&AAC

音视频基础知识简述:
录像、录音,实质上是一个压缩采集到的图像或者音频数据的过程,这个过程又称为编码,混合。那为什么需要编码(压缩)呢?因为设备采集到的音视频数据太大了,如果不进行压缩,占用的空间太大,不利于传输等。
而播放视频或者音频文件,实质上是一个解压缩的过程,这个过程又称为解码。那为什么又要解码(解压缩)呢?因为播放器播放需要的是音频采样数据、视频像素数据,通俗一点来说就是需要的是编码之前的数据,所以需要解码来获取。

播放一个视频文件的流程如下:
在这里插入图片描述
编码的目的:
码率如果为10Mb/s,代表1秒钟有10M bit的视频数据,对于YUV422格式的1080P视频而言,一帧图像是1920x1080x2x8/1024/1024 = 31.64Mbit,1秒钟30帧图像的话,则有949.2Mb/s,可见其数据量之大,不压缩根本无法网上传播,通常720P的视频码率4Mb/s,1080P的码率6~8Mb/s,压缩率都在100倍以上。
同理原始音频采样数据体积很大,一般情况下一首4分钟的PCM格式的歌曲体积为:
4 * 60 * 44100 * 2 * 8 * 2 = 338.4Mbit = 1.41Mb/s
PS:这里假定采样率为44100,采样精度为16bit。
而平时一首4分钟的MP3歌曲体积一般在4MB左右。
如果是AAC编码格式的歌曲,体积就更小。

常见的一些音视频质量参数:码率
码率:影响体积,与体积成正比:码率越大,体积越大;码率越小,体积越小。码率就是数据传输时单位时间传送的数据位数,一般我们用的单位是kbps即千位每秒。也就是取样率(并不等同与采样率,采样率的单位是Hz,表示每秒采样的次数),单位时间内取样率越大,精度就越高,处理出来的文件就越接近原始文件,但是文件体积与取样率是成正比的,所以几乎所有的编码格式重视的都是如何用最低的码率达到最少的失真,围绕这个核心衍生出来cbr(固定码率)与vbr(可变码率), “码率”就是失真度,码率越高越清晰,反之则画面粗糙而多马赛克。

常见的一些音视频质量参数:帧率
帧率(FPS):影响画面流畅度,与画面流畅度成正比:帧率越大,画面越流畅;帧率越小,画面越有跳动感。如果码率为变量,则帧率也会影响体积,帧率越高,每秒钟经过的画面越多,需要的码率也越高,体积也越大。
帧率就是在1秒钟时间里传输的图片的帧数,也可以理解为图形处理器每秒钟能够刷新几次。每秒显示的图片数影响画面流畅度,与画面流畅度成正比:帧率越大,画面越流畅;帧率越小,画面越有跳动感。由于人类眼睛的特殊生理结构,如果所看画面之帧率高于16的时候,就会认为是连贯的,此现象称之为视觉暂留。并且当帧速达到一定数值后,再增长的话,人眼也不容易察觉到有明显的流畅度提升了。

常见的一些音视频质量参数:分辨率
分辨率:影响图像大小,与图像大小成正比:分辨率越高,图
像越大;分辨率越低,图像越小。

常见的一些音视频质量参数:GOP
关键帧的周期,也就是两个IDR帧之间的距离,一个帧组的最大帧数,一般而
言,每一秒视频至少需要使用 1 个关键帧。增加关键帧个数可改善质量,但是同时增加带宽和网络负载。需要说明的是,通过提高GOP值来提高图像质量是有限度的,在遇到场景切换的情况时,H.264编码器会自动强制插入一个I帧,此时实际的GOP值被缩短了。另一方面,在一个GOP中,P、B帧是由I帧预测得到的,当I帧的图像质量比较差时,会影响到一个GOP中后续P、B帧的图像质量,直到下一个GOP开始才有可能得以恢复,所以GOP值也不宜设置过大。
同时,由于P、B帧的复杂度大于I帧,所以过多的P、B帧会影响编码效率,使
编码效率降低。另外,过长的GOP还会影响Seek操作的响应速度,由于P、B
帧是由前面的I或P帧预测得到的,所以Seek操作需要直接定位,解码某一个P或B帧时,需要先解码得到本GOP内的I帧及之前的N个预测帧才可以,GOP值越长,需要解码的预测帧就越多,seek响应的时间也越长。

视频编码标准前世今生:
在这里插入图片描述

音频编码标准前世今生:
在这里插入图片描述

追本溯源:H264数据从哪里来:

在这里插入图片描述
RGB与YUV的相互转换:
在这里插入图片描述

RGB像素结构分析:
在这里插入图片描述
在这里插入图片描述
YUV像素结构分析:
黑点表示Y分量,空心圆圈表示像素点的UV分量
在这里插入图片描述

H264编码原理:
l 数据冗余。例如如空间冗余、时间冗余、结构冗余、信息熵冗余等,即图像的各像素之间存在着很强的相关性。消除这些冗余并不会导致信息损失,属于无损压缩。

l 视觉冗余。人眼的一些特性比如亮度辨别阈值,视觉阈值,对亮度和色度的敏感度不同,使得在编码的时候引入适量的误差,也不会被察觉出来。可以利用人眼的视觉特性,以一定的客观失真换取数据压缩。这种压缩属于有损压缩。
数字视频信号的压缩正是基于上述两种条件,使得视频数据量得以极大的压缩,有利于传输和存储。一般的数字视频压缩编码方法都是混合编码,即将变换编码,运动估计和运动补偿,以及熵编码三种方式相结合来进行压缩编码。通常使用变换编码来消去除图像的帧内冗余,用运动估计和运动补偿来去除图像的帧间冗余,用熵编码来进一步提高压缩的效率。

H264编码:I帧 P帧 B帧:
在这里插入图片描述
H264编码:变换编码:
变换编码
变换编码的作用是将空间域描述的图像信号变换到频率域,然后对变换后的系数进行编码处理。一般来说,图像在空间上具有较强的相关性,变换到频率域可以实现去相关和能量集中。常用的正交变换有离散傅里叶变换,离散余弦变换等等。数字视频压缩过程中应用广泛的是离散余弦变换。

离散余弦变换简称为DCT变换。它可以将LL的图像块从空间域变换为频率域。所以,在基于DCT的图像压缩编码过程中,首先需要将图像分成互不重叠的图像块。假设一帧图像的大小为1280720,首先将其以网格状的形式分成16090个尺寸为88的彼此没有重叠的图像块,接下来才能对每个图像块进行DCT变换。
经过分块以后,每个88点的图像块被送入DCT编码器,将88的图像块从空间域变换为频率域。下图给出一个实际8*8的图像块例子,图中的数字代表了每个像素的亮度值。从图上可以看出,在这个图像块中各个像素亮度值比较均匀,特别是相邻像素亮度值变化不是很大,说明图像信号具有很强的相关性。

H264编码:熵编码:
熵编码是因编码后的平均码长接近信源熵值而得名。熵编码多用可变字长编码(VLC,Variable Length Coding)实现。其基本原理是对信源中出现概率大的符号赋予短码,对于出现概率小的符号赋予长码,从而在统计上获得较短的平均码长。可变字长编码通常有霍夫曼编码、算术编码、游程编码等。其中游程编码是一种十分简单的压缩方法,它的压缩效率不高,但编码、解码速度快,仍被得到广泛的应用,特别在变换编码之后使用游程编码,有很好的效果。
首先要在量化器输出直流系数后对紧跟其后的交流系数进行Z型扫描(如图箭头线所示)。Z型扫描将二维的量化系数转换为一维的序列,并在此基础上进行游程编码。最后再对游程编码后的数据进行另一种变长编码,例如霍夫曼编码。通过这种变长编码,进一步提高编码的效率。

H264编码:运动估计和运动补偿编码:
运动估计和运动补偿
运动估计(Motion Estimation)和运动补偿(Motion Compensation)是消除图像序列时间方向相关性的有效手段。上文介绍的DCT变换、量化、熵编码的方法是在一帧图像的基础上进行,通过这些方法可以消除图像内部各像素间在空间上的相关性。实际上图像信号除了空间上的相关性之外,还有时间上的相关性。例如对于像新闻联播这种背景静止,画面主体运动较小的数字视频,每一幅画面之间的区别很小,画面之间的相关性很大。对于这种情况我们没有必要对每一帧图像单独进行编码,而是可以只对相邻视频帧中变化的部分进行编码,从而进一步减小数据量,这方面的工作是由运动估计和运动补偿来实现的。

H264码流传输:
H.264 基本流的结构
H.264的功能分为两层,视频编码层(VCL)和网络提取层(NAL)VCL数据即被压缩编码后的视频数据序列。在VCL数据要封装到NAL单元中之后,才可以用来传输或存储。
NAL单元格式[2] 表1所示:
表1 NAL单元格式
NAL头 RBSP NAL头 RBSP

H.264的码流结构图:

在这里插入图片描述

H264码流参数解析:
起始码: 每个NALU 前需添加起始码:0x000001,用来指示一个 NALU的起始和终止位置。在这样的机制下,*在码流中检测起始码,作为一个NALU得起始标识,(如果实际数据中连续出现二个0时编码器会在0后自动加上0x03,解码时相反处理丢掉0x03,所以不用担心NALU本身数据存在和起始码一样的数据)当检测到下一个起始码时,当前NALU结束。
NALU header: NALU 头的格式如图2 所示:

1.forbidden_bit: 禁止位,初始为0,当网络发现NAL单元有比特错误时可设置该比特为1,以便接收方纠错或丢掉该单元。
2.nal_reference_bitnal重要性指示,标志该NAL单元的重要性,值越大,越重要,解码器在解码处理不过来的时候,可以丢掉重要性为0的NALU。
3.TYPE:NAL类型

H264传输的协议有哪些:流媒体协议:

在这里插入图片描述
RTSP协议概述:

在这里插入图片描述
RTSP协议与HTTP协议的区别:
在这里插入图片描述

RTSP消息交互过程:
在这里插入图片描述
在这里插入图片描述
抓包工具wireshark使用:
通过live555作为服务端,vlc作为客户端抓取网络传输包进行分析
初步掌握wireshark的使用方法,此文不做分析,后续单独写一篇进行详细讲解。

H264传输协议:RTP:
RTP 协议是 IETF 在 1996 年提出的适合实时数据传输的新型协议。RTP 协议实际上是由实时传输协议RTP(Real-time Transport Protocol)和实时传输控制协议RTCP(Real-time Transport Control Protocol)两部分组成。RTP 协议基于多播或单播网络为用户提供连续媒体数据的实时传输服务;RTCP 协议是 RTP 协议的控制部分,用于实时监控数据传输质量,为系统提供拥塞控制和流控制。RTP 协议在RFC3550 中有详细介绍。每一个 RTP 数据包都由固定包头(Header )和载荷(Payload)两个部分组成,其中包头前12个字节的含义是固定的,而载荷则可以是音频或视频数据。RTP 固定包头的格式如图1所示:
在这里插入图片描述
RTP协议格式解析:
其中比较关键的参数设置解释如下:
(1)标示位(M ):1 位,该标示位的含义一般由具体的媒体应用框架(profile )定义, 目的在于标记处RTP 流中的重要事件。
(2)载荷类型(PT):7 位,用来指出RTP负载的具体格式。在RFC3551中,对常用的音视频格式的RTP 传输载荷类型做了默认的取值规定,例如,类型2 表明该RTP数据包中承载的是用ITU G.721 算法编码的语音数据,采用频率为 8000HZ,并且采用单声道。
(3)序号:16 位,每发送一个 RTP 数据包,序号加 1。接受者可以用它来检测分组丢失和恢复分组顺序。
(4)时间戳:32 位,时间戳表示了 RTP 数据分组中第一个字节的采样时间,反映出各RTP 包相对于时间戳初始值的偏差。对于RTP 发送端而言,采样时间必须来源于一个线性单调递增的时钟。

H.264 流媒体传输系统的实现:
前面分别讨论了RTP 协议及H.264基本流的结构,那么如何使用RTP协议来传输H.264视频了?一个有效的办法就是从H.264视频中剥离出每个NALU,在每个NALU前添加相应的RTP包头,然后将包含RTP 包头和NALU 的数据包发送出去。
一个完整的流媒体传输系统包含服务器端和客户端两个部分[5][6]。对于服务器端,其主要任务是读取H.264 视频,从码流中分离出每个NALU 单元,分析NALU 的类型,设置相应的 RTP 包头,封装 RTP 数据包并发送。而对于客户端来说,其主要任务则是接收 RTP数据包,从RTP 包中解析出NALU 单元,然后送至*进行解码播放。该流媒体传输系统的框架如下图所示。

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/u011509690/article/details/84953361