音视频基础知识
一、音频入门
1.1 音频量化与编码
采样大小:一个采样使用多少 bit 存放,常用的是 16 bit/位(音频模拟信号的y值高度,振幅)
-
采样率
- 采样频率8k,16k,32k,44.1k,48k,对于aac来说一般采用 44.1k 的采样率
- 1 s内在模拟信号的频率上采集 44.1k 次
- 假设20HZ的频率,44.1k 的采样率,每秒正弦波里采集 2k 次
-
声道数
- 单声道、双声道、多声道
- 多声道表示多个喇叭
-
码率计算
- 计算一个PCM音频流的码率:采样率 * 采样大小 * 声道数
- 例子
采样率 44.1k,采样大小 16 bit,双声道的 PCM 编码的 WAV 文件,它的码率是 44.1k * 16 * 2 = 1411.2 kb/s
1.2 音频压缩技术
-
消除冗余数据(有损压缩技术)
- 压缩的主要方法是去除采集到的音频冗余信息,包括人耳听觉范围外的音频信号以及被遮蔽掉的音频信号(根据心里声学原理,这些声音人听不到)
- 信号的掩蔽分为频域掩蔽和时域掩蔽
- 频域掩蔽(音量高的声音其频率附件的音量小的声音会被遮蔽听不到,可作为冗余信息)
- 时域掩蔽(同一时间内音量高的声音会遮蔽音量低的声音会被遮蔽)
音频编码过程
-> 时域音频转频域(方便分析量化)
音频信号输入 -> 量化编码 -> 比特流格式化
-> 心里声学模型(去除冗余信息) +辅助数据(可选)
1.3 音频编解码器
-
常见的音频编解码器
- 包括:OPUS,AAC,Vorbis,Speex,iLBC,AMR,G.711 等
- OPUS:现在流行的编解码器,内部两个核,基于口和基于耳的模型,实时互动要求实时性会使用口的模型,音乐类的要求高保真使用耳的模型。功能强大
- AAC:常用于泛娱乐化直播系统里,对实时性要求不是特别高,对声音音质要求高。直播系统使用的rtmp协议,支持AAC和Speex,不支持OPUS,其最近新推出的。
- Speex:除了音频编解码器外还包括外围的工作模块,回音消除,降噪等。
- G.711:固话使用这种音频编解码器
性能对比:OPUS > AAC > Vorbis
1.4 AAC 介绍(Advanced Audio Coding)
-
AAC介绍
- 为什么专门介绍AAC?应用范围广,传输协议rtmp支持AAC,AAC 音频编解码音频高保真
- AAC 目的是取代 mp3 格式,AAC对于原始数据的损耗比较小,压缩率很高,这是通过最新的MPEG-4编解码规范实现的,AAC加入了SBR和PS技术在压缩数据同时保持和原始音质接近
-
AAC 目前的规格
- AAC LC:Low Complexity 低复杂度,码流 128k,能不能码流降到更小,音质还提高呢?
- AAC HE V1:AAC + SBR (Special Band Replication) 分频复用,将音频的频带分成两部分,低频和高频,分别进行编码,高频增加采样,码流64k左右
- AAC HE V2:AAC + SBR + PS (Parametric Stereo),双声道分别保存,一个声道完整保存,另一个声道置存储差异的部分,进一步降低音频码率,码流32k左右
-
AAC格式
- DIF(Audio Data Interchange format), 在 AAC 文件的开头存一个很小的头, 包括其采样率, 采样大小, 声道数等基本信息, 那么就可以对整个AAC文件进行解读.这种格式只能从头开始解读,常用在磁盘文件中。每拿出一帧数据都根据头部参数去解析他就可以将整个AAC文件播放出来
- ADTS(Audio Data Transsport Stream):在每一个音频帧前面加一个同步字,加一个小的头,7-9字节。好处是如果是流传输,没收到一个音频帧都可以直接解出来。这种格式可以在音频流任何位置开始解码。缺点是一个完整的文件较大。
AAC 编解码库:Libfdk_AAC > ffmpef AAC > libfaac > libvo_aacenc
二、视频入门
2.1 视频基础知识
-
H264基本概念
- I 帧:关键帧,采用帧内压缩技术,理解,1s60帧,一组帧变化很小,将第一帧完整保存下来,称 I 帧
- P 帧:向前参考帧,压缩时只参考前一个帧,属于帧内压缩技术,前一个例子,第一帧是 I 帧,后面的帧只存储和前一帧间的差异,这样就可以将数据大大减少,是 P 帧
- B 帧:双向参考帧,压缩时既参考前一个帧,也参考后一帧,压缩率更高。实时互动一般不使用 B 帧
-
GOF (Group of frame) 一组帧
- 一个 I 帧和另一个 I 帧之间的一组帧称 GOF
-
SPS与PPS
- 存 GOF 的参数
- SPS:Sequence Parameter Set,序列参数集(一组帧参数集),存放帧数、参考帧数目、解码图像尺寸、帧场编码模式选择标示等
- PPS:Picture Parameter Set,图像参数集,存放熵编码模式选择标识、片组数目、初始量化参数和去方块滤波系数调整标识等
- 在一组帧之前首先会收到SPS和PPS,如果没有这两个参数是无法解码的
- SPS和PPS划归为 I 帧,这两种类型数据是不能丢的
-
视频花屏/卡顿原因
- 如果 GOF 分组中的 P 帧丢失 -> 解码端图像发生错误
- 为避免花屏问题发生,一般如果发现 P 帧或 I 帧丢失,就不显示本 GOF 内所有帧,知道下一个 I 帧来后重新刷新图像,这会造成卡顿
-
视频编解码器
- x264/x265:是目前使用最广泛的,性能优秀,软编基本上都是x264;x265压缩比更高,cpu占用高,直播系统一般不使用
- openH264:支持svc视频技术,svc指将视频分层传输,一帧数据分为小中大三部分,如果网络差,只发内核层,网络好多发几层使得视频更加清晰。缺点是移动端 openH264 非标准的,硬件不支持,无法硬件编码,消耗cpu,发热耗电。
- vp8/vp9:谷歌推出的,分别对应x264/x265
2.2 H264编码原理:H264宏块的划分与帧分组
-
H264压缩技术
- 帧内预测压缩:解决的是空域数据冗余问题。空域数据是指图里的数据,如颜色,光亮等人眼不敏感的数据,可直接删除
- 帧间预测压缩:解决的是时域数据冗余问题。一组视频帧之间数据相关性很高,很多重复数据,可删除
- 整数离散余弦变换(DCT):将空间上的相关性变成频域上无关的数据然后量化
- CABAC压缩:无损压缩
-
H264宏块的划分与分组
- 一张图划分成许多宏块(例如1920✖️1080图像按照8✖️8像素来进行宏块分组),有了这些宏块才能进行算法的处理
- 宏块还可以进一步子块划分
-
帧分组
- 一组帧内相关性很高,变化小,通过一些算法可大幅压缩数据
2.3 视频压缩技术详解
-
帧间压缩技术:针对时域数据冗余
- 一组帧内宏块查找,可进行运动估算
- 例如一组帧内,只有一个小球进行微小运动,背景不变。那么宏块扫描到球时,在这一组帧内进行查找此宏块周围有没有类似的宏块,找到后很多帧可进行运动估算。这样通过运动矢量数据和残差数据,可以大幅压缩视频数据。
-
帧内预测压缩技术:针对 I 帧,空域数据冗余
- 通过计算,对每一个宏块选择不同的帧内预测模式,共9种可选
- 选定预测模式后,宏块通过预测模式产生一个图,和原图会有差别。然后计算出原图与预测后图残差值。
- 压缩,只需存储残差数据和每个宏块预测模式信息数据。
- 解码时就可以通过预测模式信息恢复出预测图,加上残差值进行累加得到原图
-
DCT压缩
- 一个宏块经过DCT压缩会变成只有左上角有数据,右下角全为空。达到数据减少目的。
-
VLC压缩(类似哈夫曼编码):无损压缩
- 频率高的编为短码,频率低的编为长码
- VLC是MPEG2使用的技术,x264使用CABAC,即上下文适应的压缩技术:除了类似哈夫曼编码外,还有上下文适应,压缩比更强
- CABAC是上下文适应的无损压缩技术
2.4 H264结构与码流
-
H264 结构图
- 通过压缩技术,形成一帧帧 H264 视频帧序列,每一个视频帧都是结构化的,每一帧都是一个图像
- 每一帧都是有多个片组成,每一片都是有一个个宏块组成,宏块又可以进一步分成子块
-
H264 编码分层(分两层 NAL 层和 VCL 层)
- NAL层,网络抽象层:Network Abstraction Layer:H264 需要在网络中传输,由于网络包的最大传输单元是1500字节,而一个 H264 帧往往大于 1500 字节。所以需要将一个帧拆成多个包进行传输。所有这些拆包,组包等都是通过 NAL 层来处理。
- VCL 层,视频编码层:Video Coding Layer:对视频原始数据进行压缩
-
码流基本概念1
- SODB(String of Data Bits):原始数据比特流,压缩数据流,由VCL层产生,是流所以长度不一定是8的倍数。而计算机都是以字节即8的整数倍来处理,为方便处理,诞生RBSP
- RBSP(Raw Byte Sequence Payload):SODB数据加上末尾位,因为SODB是流,压缩数据流,为了方便知道流的结束,先在末尾补1,如果不是8位对齐则继续在末尾补0。
-
码流基本概念2
- EBSP(Encapsulate Byte Sequence Payload):生成压缩流之后还需要在每一帧的开头加上起始位,起始位一般是16进制的0000 0001或者是0000 01,但是在编码数据里也很有可能出现连续的0,就与起始位冲突了。如何解决?H264规范,如果压缩后的数据里遇到连续两个0x00,那就插入一个0x03,防止与起始位标记产生冲突
- NALU:NAL Header(1 byte) + EBSP,在EBSP基础上加上一个字节的网络头,就形成一个NALU即NAL Unit。
-
NAL 单元(NAL Unit)
- NAL单元由 NALU 头部 + H264 帧的一个切片
- 切片又可以细分成切片头 + 切片数据
- H264视频帧由多个切片构成(一个H264视频帧最少一个切片),在网络传输时要把H264帧切开来进行传输,按切片来切。每个切片都组成一个NALU单元。
-
切片与宏块
- 每个切片数据都包括许多宏块,每个宏块包括宏块类型,宏块的预测,编码残差数据。
-
H264 码流分层
- 一个 Annexb 格式的 H264 数据是由起始码(0000 0001)和NAL Unit组成;NAL Unit 是由NAL Header 和 一个切片(NAL 主体)组成;这个切片是由切片头和切片数据组成。在切片数据里又包括多个宏块;在宏块里,包括宏块类型,宏块的预测,编码残差数据。
- 从网络上来说,一个RTP包,这个RTP包括 NAL Header 和 一个切片(NAL 主体),再往下和上面一样分
2.5 NALU 详解
-
NAL Header
- NAL 是由 NAL Header 和 H264 帧的一个切片(NAL Body)组成的,其中 Header 占 1 个字节,8位
- F位:第一位是F位,禁止位,H264规定这个必须是 0
- NRI位:第二三为是NRI位,指示NAL的重要性,00是最不重要的,11是最重要的,不过目前没什么作用
- Type位:告知此NAL单元是什么类型。记住几个重要的即可
- nal_unit_type 为5时表示 I 帧,NAL类型是IDR图像的片;
- nal_unit_type 为7 -> NAL类型是序列参数集(SPS);SPS指的是GOF一系列图像的公共参数,如宽,高,多少帧
- nal_unit_type 为8 -> NAL类型是图像参数集(PPS);PPS存放帧内预测模式
- nal_unit_type 为28/29 -> 分片的单元,H264 帧通过网络传输, 而一个网络包最大1500字节, 放不下就切成多个片, 每个包一个片, 最后进行组装
-
NAL 类型介绍
- 单一类型:一个RTP包只包含一个NALU,完整的帧,一个H264帧里只包含一个片,如P帧,B帧很多都是单一类型
- 组合类型:一个RTP包包括多个NALU,类型24-27。像SPS,PPS这两个NALU一般放在同一个RTP包里,因为这两个单元数据量都特别小
- 分片类型:一个NALU分成多个RTP包,类型28、29.
2.6 YUV介绍
-
RGB
- 红绿蓝,每个元素占一个字节,3个元素共24位。通过对红、绿、蓝三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色,目前的显示器大都是采用了RGB颜色标准。
-
YUV
- 电视系统所采用的一种颜色编码方法
- Y:明亮度,灰阶值
- U和V:表示色度,描述影像的色彩及饱和度。
- 摄像机露出来的数据就是YUV的
-
YUV常见格式
- YUV4:4:4 (YCbCr 4:4:4)
- YUV4:2:2 (YCbCr 4:2:2)
- YUV4:2:0 (YCbCr 4:2:0)
- 减少存储空间
三、其他
3.1 音视频流程
音视频采集 -> 编码 -> 传输 -> 解码 -> 渲染
3.2 音视频硬件编解码
3.3 FFMPEG
3.4 视频渲染与OpenGL
3.5 x264优化
编码常用x264,解码常用ffmpeg