1.YUV知识点
1.1 为什么要有YUV
- YUV的亮度信号Y和色度信号U/V是分离的,如果只有Y信号分量而没有U/V分量,这样的图像就是黑白灰度图像,从黑白到彩色的兼容方案。
- 相对RGB,YUV的最大优点是只占用较小的频宽,RGB需要至少三个独立的视频信号,而YUV需要两个视频信号(Y表示明亮度,UV表示色彩和饱和度)。
- 编码时使用YUV可以去掉很多冗余信息,人眼对亮度更敏感,对色度敏感性不高,因此可以较多地压缩UV数据。
1.2 YUV的种类
YUV是按照人眼设计出来的一套颜色方案,目前有三种格式:
- YUV420,由 4 个 Y 分量共用一套 UV 分量
- YUV422,由 2 个 Y 分量共用一套 UV 分量
- YUV444,不共用,一个 Y 分量使用一套 UV 分量
按照YUV的排列顺序,也分为三种类型
- Planar YUV:三个分量分开存放
- Semi-Planar:Y分量单独存放,UV分量交错存放
- Packed YUV:三个分量全部交错存放
1.3 为什么受损的视频数据通常是绿色
视频的数据是YUV排列的,最终显示要转化为RGB,转换的公式如下:
R=clip(Y+1.13983*(V-128), 0, 255)
G=clip(Y-0.39465*(U-128)-0.58060*(V-128), 0, 255)
B=clip(Y+2.03211*(U-128), 0, 255)
如果视频数据损坏,即Y=0 U=0 V=0,最终得到的是R和B为0, G=125,所以整体的画面显示为绿色。
1.3 NV21转化为YUV420
NV21是相机采集出来的YUV数据排列,YUV420是正常视频编码器支持的排列方式。
- NV21:YUV 420 Semi-Planar,Y 分量单独存放,UV 分量交错存放,与 NV12 不同的是,UV 在排列的时候,从 V 开始。总长度为 w * h * 1.5
Y Y Y Y Y Y
Y Y Y Y Y Y
Y Y Y Y Y Y
Y Y Y Y Y Y
Y Y Y Y Y Y
Y Y Y Y Y Y
V U V U V U
V U V U V U
V U V U V U
- I420:YUV 420 Planar,YUV分量分别存放,先是 w * h 长度的Y,后面跟w * h * 0.25长度的U,最后是 w * h * 0.25长度的V,总长度是 w * h * 1.5
Y Y Y Y Y Y
Y Y Y Y Y Y
Y Y Y Y Y Y
Y Y Y Y Y Y
Y Y Y Y Y Y
Y Y Y Y Y Y
U U U
U U U
U U U
V V V
V V V
V V V
了解清楚NV21和I420的区别,转换就比较容易了。
1.4 YUV内存字节对齐
- YUV数据在内存中存储时,每行像素的数据后面可能还有填充字节。
- 这主要是因为有些系统/环境/操作对内存的字节对齐有要求,比如 64 字节对齐,那么宽度为 720 像素的图像,一行就不满足 64 对齐的要求,那就要填充到 768 像素。
- 存储一行像素所需的字节数,就叫 stride,也叫 pitch,也叫间距
- 如果图像的宽度是内存对齐长度的整数倍,那么间距就会等于宽度
2.H264/H265知识点
2.1 H264编码流程
- 帧类型分析
- 预测处理,I帧采用帧内预测和块的划分,P帧和B帧采用帧间预测和块的划分。帧内预测解决的是空间冗余问题,帧间预测解决是时间冗余问题。
- 变换+量化处理,把经过预测后的残差数据经过DCT转换,低频的数据集中在左上,高频数据集中在右下,人眼对高频信息不敏感,可以压缩地多一些。
-
熵编码,通过CAVLC方式把像素值进一步压缩为二进制流。
简而言之:
- 以宏块来细分图片,并最终以块来细分
- 使用帧内压缩技术来减少空间冗余
- 使用帧间压缩技术减少时间冗余(运动估计和补偿)
- 使用转换和量化来进行残留数据压缩
- 使用熵编码减少残留和运动矢量传输和信号发送中的最后冗余
同一帧相邻像素值相等、相似或者缓变的概率很大,编码器通过算法将图像划分为一块一块的,然后逐块进行后续的压缩处理。
帧内预测是同一帧内部处理。
帧间预测是不同帧之间处理,相邻帧之间也会出现相似或者缓变的情况。
H264中将16x16大小的块称为宏块,在做帧内和帧间预测的时候,也会划分为8x8/4x4的子块
2.2 H264和H265比较
技术对比:
- 可变化的尺寸转换(4x4到32x32),宏块不再固定
- 四叉树结构的预测区域(64x64到4x4)
- 基于候选清单的运动向量预测
- 多种帧内预测模式
- 更精准的运动补偿滤波器
- 优化的区块、采样点自适应偏移滤波器
结果对比:
- 码率低,编码效率高:以编码单位来说, 最小的8x8到最大的64x64。信息量不多的区域(颜色变化不明显,比如车体的红色部分和地面的灰色部分)划分的宏块较大,编码后的码字较少,而细节多的地方(轮胎)划分的宏块就相应的小和多一些,编码后的码字较多,这样就相当于对图像进行了有重点的编码,从而降低了整体的码率,编码效率就相应提高了。
- 占存储空间少:反复的质量比较测试已经表明,在相同的图像质量下,相比于H.264,通过H.265编码的视频码流大小比H.264减少大约39-44%。
- 编码算法效率高:同时,H.265的帧内预测模式支持33种方向(H.264只支持8种),并且提供了更好的运动补偿处理和矢量预测方法。
- 网络适应能力更强:在码率减少51-74%的情况下,H.265编码视频的质量还能与H.264编码视频近似甚至更好,其本质上说是比预期的信噪比(PSNR)要好。H.264可以在低于2Mbps的速度实现标清数字图像传送,而H.265/HEVC可以在低于1.5Mbps的传输带宽下,实现1080p全高清视频传输。
2.3 基本概念
-
SPS/PPS/VPS
- SPS:Sequence Parameters Set(序列参数集),主要包含profile、profile_level、视频的宽和高等等,没有SPS无法正确解码。
- PPS:Picture Parameters Set(图片参数集),包括熵编码的使用算法,slice group中的个数等编码相关的参数。
- VPS:Video Parameters Set(视频参数集),H265才有,VPS主要用于传输视频分级信息,有利于兼容标准在可分级视频编码或多视点视频的扩展。
-
NALU起始码
- H264格式有两种方式,Annex B格式和AVCC格式,其中Annex B格式比较常见,它是由起始码的。
- Annex B格式用开始码来解决这个问题,即给每个NALU加上前缀码:2个或者3个0x00,后面再加一个0x01, 如:0x000001或者0x00000001。这是由向每个这种类型的序列插入防竞争字节0x03实现的,那么插入防竞争字节后,0x000001变成了0x00000301。
-
一帧多Slice
- 正常情况下,H264的一帧只有一个Slice,但是某些编码器吐出的数据会存在一帧有多个Slice的情况。这种需要特别兼容下,将Slice中数据取出来memcpy到一起,这样处理之后不会存在兼容性问题。
-
SEI
- SEI 即补充增强信息(Supplemental Enhancement Information),属于码流范畴,它提供了向视频码流中加入额外信息的方法,是 H.264 标准的特性之一。
- 在直播场景,我们通常使用 SEI 来携带推流端的信息,一直随着直播流传输到播放端。由于 SEI 是绑定着视频帧,所以它可以支持诸如:
- 统计直播推流端到播放端延时。
- 支持和视频帧绑定的内容交互。比如,直播答题在播放端的弹窗等。
3.MP4和FLV知识点
3.1 FLV
FLV是一种流媒体格式,体积小、协议简单,主要用在直播领域,RTMP协议推流会封装成FLV格式的视频。
FLV = FLV header + FLV file body
FLV file body = PreviousTagSize0 + Tag1 + PreviousTagSize1 + Tag2 + ... + PreviousTagSizeN-1 + TagN
FLV tag分为三种类型:
- Video Tag:存放视频相关数据
- Audio Tag:存放音频相关数据
- Script Tag:存放音视频元数据
3.2 MP4
MP4是一种Box封装的格式,它和FLV有着根本的不同,所以FLV可以用作直播,但是MP4却不能。
- MP4文件由多个Box组成,每个Box存储不同的信息,而且Box之间是树状的结构。
- Box种类很多,主要有三种:
- ftyp:File Type Box,描述文件遵从的MP4规范与版本
- moov:Movie Box,媒体的metadata信息
- mdat:实际的媒体数据,可能有多个
- moov可以位于文件头部,也可以位于文件尾部,必须要先解析moov,才能播放这个视频,如果moov在文件尾部,那就无法顺序播放了。moov有两个重要的box:
- mvhd:Movie Header Box,mp4文件的整体信息,比如创建时间、文件时长等;
- trak:Track Box,一个mp4可以包含一个或多个轨道(比如视频轨道、音频轨道),轨道相关的信息就在trak里。trak是container box,至少包含两个box,tkhd、mdia;
- mvhd针对整个影片,tkhd针对单个track,mdhd针对媒体,vmhd针对视频,smhd针对音频,可以认为是从 宽泛 > 具体,前者一般是从后者推导出来的。
3.3 FLV可以seek吗?
FLV用作直播的时候,肯定是无法seek,但是用作点播时,它的keyframes中包含“filepositions”和“times”,分别指关键帧的文件位置和关键帧的PTS,通过keyframes可以建立自己的index,在seek过程中,可以快速地跳到你想要的关键帧的位置进行处理。
4.PCM和AAC知识点
PCM是Pulse Code Modulation 脉冲编码调制,是非压缩的音频编码,就是原始的音频数据。
但是PCM只是原始数据,我们播放原始数据的时候,不知道当前音频的声道、采样率等信息,不知道这些信息,是无法有效播放音频的。
AAC将PCM音频数据编码压缩,并在头部添加了采样率、采样大小、声道
- AAC一帧有1024个sample,采样率是44.1kHz,每秒有44100个 sample,AAC一帧的播放时间是22.32ms
- MP3每帧为1152个sample,采样率是44.1kHz,一帧时长是26.122ms