视频编码原理讲解一:VCL层和NAL层的讲解

一.视频为什么要编码?

在我们做音视频产品的时候,经常会把音视频数据进行网络传输 ,而此时音视频数据就需要进行编码(所谓编码就是指压缩 )。因为在网络传输的时候,网络带宽有限 ,若此时网络传输的时候还用原始数据进行传输的时候,则会对网络带宽造成极大的负担。比方说一个分辨率为1280 * 720 帧率为30帧的视频,按照YUV420格式的计算,它每秒传输的数据量就是1280* 720* 30 * 3/2 ~= 39.5M,这个数据量是极其惊人的。所以此时, 我们就要引入视频编码技术来压缩视频,让其体积大小能够大幅度缩小,这样在网络传输的时候就会大大降低网络负担 。在音视频开发中,一般分为H264、H265这两种最常见的编码格式 。H264的压缩比能够达到1:100,H265的压缩比能够达到1:200,但是目前业内由于HEVC技术还没完全成熟,所以绝大部分设备都是用H264进行压缩处理。

二. VCL 层和 NAL 层的讲解

H264编码格式是目前业内最流行的视频编码格式,它是MPEG-4 的第十个部分。H264具有高压缩率、高图像质量、网络适应性很强等特点 。在同等的图像质量下,H264的压缩比远超绝大部分编码格式(HEVC 除外 )。在H264(HEVC)编码框架中分为两大层,一层是VCL (Video Coding Layer)、另外一层是NAL层 (Network Abstraction Layer)。VCL层主要负责内容的表示(如下图),NAL层主要负责对H264数据进行打包和传输,下面我们来重点介绍这两层里面包含的知识点。

2.1. VCL 层的知识点:

VCL层包含了四个比较重要的知识点,分别是帧内预测压缩帧间预测压缩变换量化、 熵编码

帧内压缩:也称之为空间压缩 ,当压缩一张图片的时候,若仅仅考虑帧的数据也不考虑相邻帧和帧之间的冗余数据,这样的方式就叫帧内压缩。在H264中I帧生成的原理就是帧内压缩,帧内压缩可以独立解码出一帧完整的图像而不需要参考任何帧 ,帧内压缩表现出来的数据是最大16 x 16的宏块(它也包括:4x4,8x8)。帧内压缩本质上是在空间的XY轴上进行压缩,它的压缩率比较小。下面9张图是9种不同的预测方式

帧间压缩: 帧间压缩是通过对比相邻两帧之间的数据进行压缩,并且进一步提高压缩量。用这种方法可以先编码出一个完整的图像1帧,紧接着2帧的数据就不编码出一张完整的图像,而是只写入和1帧的不同的数据,这样2帧数据的大小则会大大降低。以此类推,3帧的数据参考2帧数据,并且也只写入2帧不同的数据,帧间压缩表现出来的数据同样也是最大16 x 16的宏块(它也包括:4x4,8x8)。按照这样的方法,不停地循环下去。这样的方式,就是P B 的实现方法。

变换量化:

为了 要让压缩的H264图像在网络传输中节省更多的码率 ,需要采用变换编码以及量化技术 来消除图像信号中的相关性以及减小图像编码中的动态变换范围。变换编码的原理就是把图像时域信号变换成频域信号 ,在频域范围内, 绝大部分信号集中在低频区域 ,相对时域信号 ,码率能够大幅度下降。而在H264中通常用下面方法进行处理:H264数据经过帧内压缩 (16 * 16亮度、4 * 4亮度、8 * 8亮度)、**帧间预测(**4 * 4 ~ 16 * 16亮度)得到了残差值。这些残差值需要经过冗余的统计,并进行数据的变换和量化操作。

对于H264的16 x 16的亮度块,通过4x4的前向DCT变换,然后对16个DC系数再进行4 x4 的Hadmard变换,最后把这16个DC系数进行量化。

而对于8x8的色度块,则进行4x4的DCT变换后,得到4个DC和60个AC系数并对DC系数进行2x2的Hadmard变换。变换后则对DC系数和AC系数进行量化操作。

要值得注意的是,由于变换块越大,编码的效率越高,图像的还原度越好。所以为了让其编码质量得到更好的效果,在H264的高清(HD)档次,它支持8x8的DCT变换,并且不需要对DC系数进行Hadmard变换,DCT变换后则对DC和AC系数进行统一处理。

熵编码:

熵编码压缩是一种无损压缩模式 ,其实现原理是使用的编码模式来表示输入的数据,并达到压缩效果。常用的 熵编码方式分别是变长编码(CAVLC)和算术编码(CABAC)。

**变长编码(CAVLC):**对出现概率大的符号,对出现概率小的符号提供长字节二进制码。

**算术编码(CABAC):**采用一个浮点数代替一串输入符号,范围是[0,1)

具体的参考CAVLC和CABAC简介_c avlc-CSDN博客

CABAC 的编码压缩率远远大于CAVLC,CABAC具有更高的编码效果。

2.2. NAL 层(Network Abstraction Layer):负责以网络所要求的方式进行打包和传送,下图是一个NAL层的组成部分(这里主要介绍H264码流的NAL,H265的后面会讲)

NAL 层一般由三部分组成,分别是

StartCode(起始码:必须是00 00 00 01)

NALU Header(NALU头部)

NALU Payload(具体传输的视频内容)。

比方说一串H264码流的NALU:00 00 00 01 68 43 A0 25 56 2E....

其中:[00 00 00 01]是StartCode也就是起始码

68\] 是NAL头部 \[43 A0 25 56 2E...\]就是NALU Payload的数据 #### 2.2.1. StartCode起始码: 起始码是所有H264码流开始时候的分隔符,一般分为0x000 001和0x000 000 01两种 #### **2.2.2. NAL** **头部:** **NALU头部长度为一个字节,它的语法是禁止位(1bit)、重要性位(2bit)、NALU类型(5bit)** ![](https://i-blog.csdnimg.cn/direct/b0a6a667a082477c8be2f087d655ec9c.png) **NALU** **类型的图表:** ![](https://i-blog.csdnimg.cn/direct/b36f0021b5bc4d8cab86bce83185f4ec.png) **比方说:NALU头部是0x68,转换为二进制数据就是0110 1000.** **这表示,禁止位为0,NAL重要性为11(最重要),01000换算成HEX格式就是8也就是PPS。**

相关推荐
Panesle14 小时前
HunyuanCustom:文生视频框架论文速读
人工智能·算法·音视频·文生视频
程序员JerrySUN20 小时前
驱动开发硬核特训 · Day 30(下篇): 深入解析 lm48100q I2C 音频编解码器驱动模型(基于 i.MX8MP)
linux·驱动开发·架构·音视频
读心悦1 天前
5000字总结 HTML5 中的音频和视频,关羽标签、属性、API 和最佳实践
前端·音视频·html5
东风西巷1 天前
BLURRR剪辑软件免费版:创意剪辑,轻松上手,打造个性视频
android·智能手机·音视频·生活·软件需求
weixin_446260851 天前
视觉革命来袭!ComfyUI-LTXVideo 让视频创作更高效
人工智能·音视频
拧螺丝专业户1 天前
外网访问内网海康威视监控视频的方案:WebRTC + Coturn 搭建
音视频·webrtc·监控视频
追随远方2 天前
Android平台FFmpeg音视频开发深度指南
android·ffmpeg·音视频
Oliverro2 天前
嵌入式音视频通话EasyRTC基于WebRTC技术驱动智能带屏音箱:开启智能交互新体验
人工智能·音视频
佩奇的技术笔记2 天前
AI编程: 使用Trae1小时做成的音视频工具,提取音频并识别文本
音视频·ai编程