H.264 入门篇 - 00 (简介)

2023-11-11

目录

1、Profiles

2、应用领域

3、Level

4、层次结构

4.0、整个过程

4.1、数据切分

4.1.1、Macroblock (宏块)

4.2、帧内预测 (Intra-Frame Prediction)

4.3、帧间预测 (Inter-Frame Prediction)

4.4、变换 (Transform -> DCT)

4.5、量化 (Quantization)

4.6、熵编码 (entropy coding)

4.6.1、CAVLC

4.6.2、CABAC

4.7、去块滤波 (Deblocking filter)

4.8、其他

4.8.1、多参考帧的帧间预测

5、开源软件


参考资料:

https://iphome.hhi.de/wiegand/assets/pdfs/DIC_H264_07.pdf

SPEC:

H.264 : Advanced video coding for generic audiovisual services (最新版本)

H.264 : Advanced video coding for generic audiovisual services (2005 版本,带中文)

H.264 的多媒体视频 Codec 规范由 ITU-T 和 ISO/IEC联合开发;

ITU-T 给这个标准命名为 H.264(以前叫做H.26L),而ISO/IEC 称它为 MPEG-4 高级视频编码(Advanced Video Coding,AVC),并且它将成为MPEG-4标准的第10部分。

1、Profiles

H.264 有 4 种 Profile:

  • Baseline Profile(BP) :基本画质。
    • 支持I/P帧,只支持无交错(Progressive)和 CAVLC
  • Main Profile(MP):主流画质。
    • 提供I/P/B帧,支持无交错(Progressive)和交错(Interlaced),也支持CAVLC和CABAC的支持
  • Extended Profile(EP):进阶画质。
    • 支持I/P/B/SP/SI帧,只支持无交错(Progressive)和CAVLC;
  • High Profile(HP):高级画质。
    • 在Main Profile基础上增加了8×8内部预测、自定义量化、无损视频编码和更多的YUV格式

2、应用领域

Baseline Profile 主要是用于可视电话,会议电视,无线通讯等实时通信。要实时,就要减少视频decode和display的时延,所以没有 B frame;为了提高针对网络丢包的容错能力,特意添加了FMO,ASO和冗余 slice;

Main Profile 多应用于流媒体领域,数字视频存储,有了CABAC,MBAFF,Interlace,B frame等。

Extended Profile 用于改进误码性能和码流切换(SP和SI slice),侧重于码流切换(SI,SP slice)和error resilience(数据分割)

High Profile 主要用于高压缩效率和质量, 引入8x8 DCT,选择量化矩阵等。

一段码流的 profile 信息,会被编码到码流的 SPS (Sequence Paramater Set) 中的 profile_idc 字段 (详见 T-REC-H.264 的官方文档的 Annex A – Profiles and levels ):

Baseline -- profile_idc = 66 or constraint_set0_flag = 1

Constrain baseline -- profile_idc = 66 && constraint_set1_flag = 1

Main profile -- profile_idc = 77 or constraint_set1_flag = 1

Extend profile -- profile_idc = 88 or constraint_set2_flag = 1

High profile -- profile_idc = 100

High 10 -- profile_idc = 110

High 422 -- profile_idc = 122

High 444 -- profile_idc = 244

3、Level

H.264 的 Level 指示编码的分辨率、比特率、宏块数和帧率等。具体如下图:

一段码流的 level 信息,会被编码到码流的 SPS (Sequence Paramater Set) 中的 level_idc 字段 (详见 T-REC-H.264 的官方文档的 Annex A – Profiles and levels ):

码流所遵从的level由 level_idc 指定。

4、层次结构

H.264 编码过程分为了 Video Coding Layer (VCL) 和 Network Abstraction Layer (NAL);VCL 负责将输入的流进行编码,NAL 负责将编码完毕的内容打包成符合 H.264 格式数据流;

解码过程是编码的逆过程,按照 H.264 的协议来解析 NAL,得到相关的编码信息,按照编码信息进行对应的解码策略;

编码过程

4.0、整个过程

下图展示了编码的整个过程:

这个编码过程,包含了帧内预测 (Intra-frame) 和帧间预测 (Motion),这里有一个开关 (Intra/Inter MB select),用于确定当前是帧内还是帧间处理;

也包含了变换和量化的过程,最后将数据给到熵编码;

下面会拆解整个流程,分段进行描述;

4.1、数据切分

每帧数据可以分为 1 个或者多个 Slice;

每个 Slice 分为多个 Macroblock;

每个 Macroblock 还可以分为子 Block;

4.1.1、Macroblock (宏块)

H.264 使用基础的 16x16 Macroblock;除了 16x16,还可以细分为如下类型宏块;

每个分割的或者子宏块,都有独立的运动向量 (MV),并且需要被编码和传输;

使用 Elecard StreamEye Tools 工具抓取 H.264 的 P 帧,进行 Macroblock 分析如下所示:

4.2、帧内预测 (Intra-Frame Prediction)

一个 GOP 的第一帧一定是 I 帧,虽然 I 帧是 “完整” 的帧,其实我们也不能完全真的让他完整,要对其进行帧内预测编码,对关键帧进行压缩;

H.264的帧内压缩与JPEG很相似。一幅图像被划分好 Macroblock 后,对每个 Macroblock 可以进行多达 9 种模式的预测。找出与原图最接近的一种预测模式。

帧内预测编码就是用周围邻近的像素值来预测当前的像素值,然后对预测误差进行编码。帧内预测是基于图像块;

对于亮度分量(Luma),块的大小,可以在16×16和4×4之间选择,16×16块有4种预测模式(垂直Vertical,水平Horizontal,直流分量DC,平面Plane),4×4块有9种预测模式(直流分量DC,8个方向)。

对于色度分量(Chroma),预测是对整个8×8块进行的,有4种预测模式(垂直Vertical,水平Horizontal,直流分量DC,平面Plane)。除了DC预测外,其他每种预测模式对应不同方向上的预测

  • 16×16大小的亮度块:4种预测模式
  • 4×4大小的亮度块:9种预测模式
  • 8×8 色度块:4种预测模式,同16×16的亮度块

16×16亮度块和色度块的4种预测模式如下图:

4×4亮度块的9种预测模式如下图表示:

DC 模式用上方和左方相邻像素的均值表示整个预测块

帧内预测后,与真实图像比较如下:

此刻,我们得到了基于 Macroblock 的预测方式 (预测向量),我们再用预测的图像与真实的图像做残差:

再将我们之前得到的预测模式信息一起保存起来,这样我们就可以在解码时恢复原图了;

过程如下:

4.3、帧间预测 (Inter-Frame Prediction)

H.264 帧间预测是利用先前编码帧的重建图像作为参考,对当前图像进行预测编码的一种方式。它把参考图像的抽样点通过运动矢量的补偿,作为当前图像抽样值的参考值;

H.264/AVC帧间预测的区别在于块尺寸更丰富,采用了1/4精度运动矢量、多参考帧等方法。

通过宏块扫描与宏块搜索可以发现这两个帧的关联度是非常高的。进而发现这一组帧的关联度都是非常高的。因此,上面这几帧就可以划分为一组。其算法是:在相邻几幅图像画面中,一般有差别的像素只有10%以内的点,亮度差值变化不超过2%,而色度差值的变化只有1%以内,我们认为这样的图可以分到一组。

在这样一组帧中,经过编码后,我们只保留第一帖的完整数据,其它帧都通过参考上一帧计算出来。我们称第一帧为 I帧,其它帧我们称为P/B帧,这样编码后的数据帧组我们称为GOP。

运动估计 (Motion Estimation) 与运动补偿 (Motion Compensation)

在帧间编码中,活动的图像邻近帧之间存在一定的相关性,可以将活动的图像分为若干宏块,设法搜索出每个宏块在邻近帧之间的位置,并得出两者之间空间位置的相对偏移量,得到的偏移量叫做运动矢量 (Motion Vector),得到运动矢量的过程叫运动估计;

帧间预测使用的宏块类型如下:

每个分割或子宏块都有一个独立的运动补偿。每个运动矢量都须被编码、传输,分割的选择也要将编码压缩到比特流中。

对于较大的分割尺寸,运动矢量的选择和分割的选择只需少量的比特,但运动补偿残差较多。

小尺寸的分割可以减少运动补偿后的残差,但是需要传输较多的运动矢量和分割的选择。

因而,大尺寸分割适合于较平坦的区域,小尺寸分割适合较多细节区域。宏块的色度成分(Cr, Cb)为相应亮度的一半,采用和亮度相同的分割模式,只是尺寸减半

在H264编码器中将帧分组后,就要计算帧组内物体的运动矢量了。还以上面运动的台球视频帧为例,我们来看一下它是如何计算运动矢量的。

H264将两帧视频数据进行宏块扫描。当发现其中一幅图片中有物体时,就在另一幅图的邻近位置(搜索窗口中)进行搜索。如果此时在另一幅图中找到该物体,那么就可以计算出物体的运动矢量了。下面这幅图就是搜索后的台球移动的位置。

通过上图中台球位置相差,就可以计算出台图运行的方向和距离。H264依次把每一帧中球移动的距离和方向都记录下来就成了下面的样子

运动矢量计算出来后,将相同部分(也就是绿色部分)减去,就得到了补偿数据。我们最终只需要将补偿数据进行压缩保存,以后在解码时 (加上运动矢量) 就可以恢复原图了。压缩补偿后的数据只需要记录很少的一点数据。如下所示:

注意:帧间预测是利用先前编码帧的重建图像作为参考,对当前图像进行预测编码

4.4、变换 (Transform -> DCT)

帧内预测我们得到了:残差数据 + 预测方向;

帧间预测我们得到了:残差数据 (运动补偿数据) + 运动矢量;

接下来对残差数据做变换;

H.264/AVC中的宏块大小为16×16,对其中每个4×4大小的块进行4×4的整数DCT变换后,得到16个4×4的变换矩阵。为了进一步提高压缩效率,该协议还允许把每个4×4的变换矩阵中的直流分量DC,单独取出组成一个新的4×4矩阵,对此矩阵进行Hadamard变换。整数DCT避免了以往标准中的编解码不匹配问题,使得反变换不会出现失衡的问题。并且其运算只包含加减和移位,且将量化融合在其中,有效的降低了运算量。H.264/AVC编码中整数变换及量化过程如图6-9所示。宏块的数据传送顺序如图6-10所示,图中上方的-1、16、17为直流分量形成的4×4、2×2块。

4.5、量化 (Quantization)

量化过程在不降低视觉效果的前提下减少图像的编码长度,减少图像信息中视觉恢复中不必要的信息。

量化结果,实际上是由量化步长决定的 (QStep),量化步长越小,图像的细节信息保留的越多,码率越高,图像质量越高。反之,量化步长值越大,图像质量越差。

量化是有损压缩,这一步的图像质量有一定的损失。但是前提是不影响正常的视觉和图像质量。

q(x, y) = round(F(x, y) / Q + 0.5);

再经过锯齿扫描 zig-zag(之字扫描)

将二维数组转换成一维数组,例如上面量化后数据,可以以9、0、-1、0、-1、0、0、0、0、0、0、0、0、0、0、0形式保存在一维数组里面。下面就可以 将这些数据进行熵编码,继续压缩了。

FFmpeg 的标志,就来源于这个 zig-zag 扫描;

4.6、熵编码 (entropy coding)

H.264/AVC协议对于图像数据或残差提供了两种熵编码的方式,分别为基于上下文自适应变长码CAVLC(Context-based Adaptive Variable Length Coding)和基于上下文自适应二进制算术编码CABAC(Context-based Adaptive Binary Arithmetic Coding);如果不是预测残差,而是运动向量等其他数据,H.264/AVC则采用Exp-Golomb码或CABAC编码,视编码器的设置而定。

4.6.1、CAVLC

变长编码VLC的基本思想就是对出现频率大的符号使用较短的码字,而出现频率小的符号采用较长的码字,这样可以使得平均码长最小。CAVLC中,H.264/AVC采用若干VLC码表,不同的码表对应不同的概率模型。编码器能够根据上下文,在这些码表中自动地选择如周围块的非零系数或系数的绝对值大小。最大可能地与当前数据的概率模型匹配,从而实现了上下文自适应的功能。

4.6.2、CABAC

算术编码是一种高效的熵编码方案,其每个符号所对应的码长被认为是分数。由于对每一个符号的编码都与以前编码的结果有关,所以它考虑的是信源符号序列整体的概率特性,而不是单个符号的概率特性,因而它能够更大程度地逼近信源的极限香浓熵,降低码率。为了绕开算术编码中无限精度小数的表示问题,对信源符号概率进行估计,现代的算术编码多以有限状态机的方式实现,H.264/AVC的CABAC便是一个例子,其他的例子还有JPEG2000。在CABAC中,每编码一个二进制符号,编码器就会自动调整对信源概率模型(用一个“状态”来表示)的估计,随后的二进制符号就在这个更新了的概率模型基础上进行编码。这样的编码器不需要信源统计特性的先验知识,而是在编码过程中自适应地进行估计。显然,与CAVLC编码中预先设定好若干概率模型的方法比较起来,CABAC有更大的灵活性,可以获得更好的编码性能——大约降低10%的码率。

4.7、去块滤波 (Deblocking filter)

去块滤波,也叫环路滤波,它的作用是,消除经反量化和反变换后,重建图像中由于预测误差产生的块效应,即块边缘处的像素值跳变,从而一来改善图像的主观质量,二来减少预测误差。

H.264/AVC中的 Deblocking Filter还能够根据图像内容做出判断,只对由于块效应产生的像素值跳变进行平滑,而对图像中物体边缘处的像素值不连续给予保留,以免造成边缘模糊。与以往的Deblocking Filter不同的是,经过滤波后的图像将根据需要放在缓存中用于帧间预测,而不是仅仅在输出重建图像时用来改善主观质量,也就是说该滤波器位于解码环中,而非解码环的输出外,因而它又称作环路滤波 Loop Filter。需要注意的是,对于帧内预测,使用的是未经过滤波的重建图像。

4.8、其他

4.8.1、多参考帧的帧间预测

以往的P帧编码是以前面重建的帧作为参考,进行运动估计预测得到最佳匹配块。B帧编码同样是以前后重建帧为参考预测得到残差。H.264/AVC提供了多个参考帧的帧间预测模式,使估计到的宏块更贴近实际运动物体模型,运动向量表示更精确。但在选用多帧参考的同时,计算量巨增;

5、开源软件

H.264是一种视频压缩标准,其只规定了符合标准的码流的格式,以及码流中各个语法元素的解析方法。H.264标准并未规定编码器的实现或流程,这给了不同的厂商或组织在编码实现方面极大的自由度,并产生了一些比较著名的开源H.264编解码器工程。其中H.264编码器中最著名的两个当属JM和X264,这二者都属于H.264编码标准的一种实现形式。

JM:JM通常被认为是H.264标准制定团队所认可的官方参考软件,基本实现了H.264标准的全部特征。JM在运行时的运算过程较为复杂,而且没有采用汇编优化等加速方法,因此运行速度较慢,很难达到实时编解码。通常主要用于编解码技术的科学研究领域,目前(2016.7)最新版本为JM 19。

X264:X264是另一个著名的H.264开源视频编码器,由开源组织VideoLan开发制定。X264是目前企业界应用最为广泛的开源编码器,主要因为X264相对于JM进行了大量的优化与简化,使其运行效率大幅提高,主要有对编码代价计算方法的简化以及添加了MMX、SSE汇编优化等部分。虽然编码的质量在某些情况下相对于JM略有下降,但是已无法掩盖其在可应用性,尤其是实时编码方面无可比拟的优势。

JM的源代码的下载地址为:Karsten Suehring

除了上面描述的内容,FFmpeg 也是最流行的音视频开源软件,众多的播放器都曾使用 FFmpeg 作为他们的实现使用;

总览:

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

H.264 入门篇 - 00 (简介) 的相关文章

  • group by的基本用法

    在平常的工作中 我们经常需要对数据进行分组 那么group by该如何使用呢 都有哪些使用场景呢 语法 含有聚合函数的过滤条件需放在having后 1 select 字段 from 表名 where 条件 group by 字段 2 sel
  • ASP.NET-MVC4--Layout母版页面传入数据Model模型

    首先建立基础控制器 其它页面控制器都继承自这个基类控制器 定义好 layout母版页需要的 ViewModel 在基类ApplicationController控制器里 定义 ViewBag TopMenuModel 在Layout母版页里
  • 时间序列信号阈值降噪方法,有什么可以创新的地方吗?

    可以换个空间 从图域的角度进行分析 比如图傅里叶变换 图小波变换等图时频分析方法 图小波阈值降噪的基本思想是通过将时间序列信号转换成路图信号 再利用图小波变换分解成尺度函数系数和一系列对应不同尺度的谱图小波系数 然后设置阈值对图小波系数进行
  • 通常环境光照度参照表

    通常环境光照度参照表 场所 环境 光照度 晴天 30000 300000 lux 晴天室内 100 1000 lux 阴天 3000 10000 lux 阴天室外 50 500 lux 阴天室内 5 50 lux 黄昏室内 10 lux 日
  • 8大思路全面解决AJAX跨域问题

    未完待续 建议先看一下慕课网上的视频课程 Ajax全接触 课程时长合理 讲的很透彻
  • kubernetes13安装CoreDNS 部署时遇CrashLoopBackOff

    前言 https github com minminmsn k8s1 13 blob master coredns kubernetes1 13 1集群部署coredns md 按照上述大神写的说明去部署的CoreDNS 遭遇问题 在仪表盘
  • 散点图

    代码 画直线 我们通常引入的是分模块pyplot 大部分的功能都在这个包中 import matplotlib pyplot as plt import numpy as np x np linspace 1 1 50 指定的间隔内 返回均

随机推荐

  • MySQL高阶问题:server层和存储引擎层是如何交互的?

    点击上方石杉的架构笔记 右上选择 设为星标 每日早8点半 精品技术文章准时送上 往期文章 BAT 面试官是如何360 无死角考察候选人的 上篇 每秒上万并发下的Spring Cloud参数优化实战 分布式事务如何保障实际生产中99 99 高
  • 数据库修改删除的操作

    创建一个school数据库 创建学生表 学号int 登录密码 varchar 20 姓名 性别varchar 2 出生日期 datatime 家庭住址 email 注意事项 1 使用英文 表的名称和字段尽量使用 括起来 2 auto inc
  • 内点法求最优潮流和微电网调度(风、光、蓄电池、燃油机)(Matlab实现)

    目录 1 概述 2 案例 2 1算例描述 2 2 数据 3 一点小知识 4 Matlab代码实现 1 概述 由于电力系统本身的复杂性 电力潮流优化具有规模大 约束条件多和非线性的特点 通过对最优潮流的求解 最终达到优化已有资源 降低发电厂耗
  • 私有IP地址

    什么是私有IP地址呢 私有IP是主要用于在局域网中分配的 私有IP的主要范围有如下 私有 内网 IP地址范围 A类 10 0 0 0 10 255 255 255 B类 172 16 0 0 172 31 255 255 C类 192 16
  • 在SAE部署WordPress

    虽然几个月前我是以安装应用的形式将wordpress部署在sae 虽然当时sae应用商店还没有收费 但是作为一个开发者 不喜欢这种方式来搭建自己的博客 因为搭建自己的博客 自己什么事情都没有干 可能另外一个原因吧 应用达到一定的访问量 我们
  • 使用LDO进行电压转换,24V转5V电路为什么中间要加一个中间电压做转化

    问题 我的输入是24v 输出是5V 有两个方案 方案一 使用LM7805直接从24V转5V 假如后面的负载电流是100ma 那么LM7805上的发热功率就是W 19 0 1w 1 9w 方案二 先使用LM7815从24V转15V 然后从15
  • python — 项目命名规范

    python 项目命名规范 类型 公有 外部成员 私有 内部成员 项目 project My project 模块 module my naming convention my naming convention 包 package my
  • 逆序和 (最小反转数)【归并排序解决】

    算法竞赛 file author jUicE g2R qq 3406291309 彬 bin 必应 一个某双流一大学通信与信息专业大二在读 brief 一直在算法竞赛学习的路上 copyright 2023 9 COPYRIGHT 原创技术
  • 【Java入门杂记】【六】

    文章目录 返回值类型练习 返回数组 返回类型 参数列表 参数 多int 返回值 单int 形参 实参练习 参数 arr 返回值 int 参数 对象 返回值 多类型 对象数组 方法 重载方法 不构成重载方法 构造方法 面向对象 封装 继承 多
  • Host********* is not allowed to connect to this MySQL server 解决方法

    1 use mysql 2 update user set host where user root 3 FLUSH PRIVILEGES
  • 性能测试知识及古老测试工具LR

    目录 性能理论知识 LR基本知识点 1 LR工作原理 2 LR脚本支持的语言有 3 LR的四大组件 4 Vugen的选项 5 事务的响应时间查看 6 性能测试目的 7 常见单词 LR性能问题 1 请简述性能测试的过程 2 请写出基准测试的两
  • TCP/IP协议-应用层协议端口号及各层协议数据单元

    序言 重新复习一下常见应用层协议端口号 以及TCP IP各层数据单元 1 应用层协议端口号对应 基于TCP的应用层协议 应用层协议 服务 端口号 TCP UDP FTP 文件传输协议 20 数据 21 控制 TCP SSH 安全登录 文件传
  • kubernetes运行应用2之DaemonSet详解

    Python微信订餐小程序课程视频 https edu csdn net course detail 36074 Python实战量化交易理财系统 https edu csdn net course detail 35475目录 查看dae
  • java哈希表,java哈希表常用方法

    Java中的哈希表是一种用于存储键值对的数据结构 它通过使用一个哈希函数 能够实现快速查找 插入 删除的操作 本文将详细解读Java哈希表的运作机制 并介绍其常用方法及使用方式 一 Java哈希表的基本概念 Java哈希表 即HashTab
  • Three.js 实现透明背景

    例如中间放一个模型 背景透明通过相机可以看到现实环境 类似AR展示的效果 1 Renderer渲染器设置 renderer new THREE WebGLRenderer 抗锯齿属性 WebGLRenderer常用的一个属性 antiali
  • vue去除浏览器自带padding、margin

    浏览器自带padding margin
  • echarts地图中如何使用图片填充地图,类似于给地图添加纹理效果

    旧版本的echarts地图中的areaColor属性可以使用图片
  • js正则exec match测试验证

  • Linux三剑客awk、grep、sed详解

    一 前言 linux 有很多工具可以做文本处理 例如 sort cut split join paste comm uniq column rev tac tr nl pr head tail 学习 linux 文本处理的懒惰方式 不是最好
  • H.264 入门篇 - 00 (简介)

    目录 1 Profiles 2 应用领域 3 Level 4 层次结构 4 0 整个过程 4 1 数据切分 4 1 1 Macroblock 宏块 4 2 帧内预测 Intra Frame Prediction 4 3 帧间预测 Inter