当前位置: 首页 > news >正文

h264编码总结

文章目录

  • h264
    • h264码流
    • NALU
    • 片(Slice)
      • 视频压缩
    • 宏块(Macroblock)

h264

h264码流

  1. 完整视频文件(如MP4/MKV/AVI)采用"容器封装"技术,将视频流(如H.264)、音频流(如AAC)、元数据等多个独立数据流打包整合,并添加同步时序信息

  2. H.264码流只是其中的视频组成部分

  3. H.264编码标准从码流功能的角度主要分为两个层次:视频编码层(Video Coding Layer, VCL)和 网络抽象层(Network Abstraction Layer, NAL) 。下图为H.264的分层结构图

    在这里插入图片描述

    1. 视频编码层(Video Coding Layer, VCL)

      1. 视频编码层负责将原始视频数据进行编码,它定义了如何将原始视频数据压缩成更小的格式,VCL使用多种编码工具和技术来实现高效的压缩
    2. 网络抽象层(Network Abstraction Layer, NAL)

      1. 网络抽象层负责将视频编码层产生的比特流组织成适合传输和存储的格式。它的主要任务是将编码数据打包成网络抽象层单元(Network Abstraction Layer Unit,NALU),这些单元可以在不同的网络和存储介质上进行传输和存储
    3. 视频编码层将原始视频数据压缩编码,网络抽象层将压缩编码后的数据打包成NALU(网络抽象层单元)来进行传输或存储

      在这里插入图片描述

  4. 码流组织方式,目前H264主流的码流组织方式有两种:AnnexB和AVCC两种格式

    1. AnnexB
      1. 每个NALU之间通过分隔符0x00 00 00 01或者0x00 00 01区分不同的NALU,分隔符的字节,一般被称为 start code, 起始码
      2. 在原始码率中可能会出现0x00 00 00 01或者0x00 00 01,为了防止这种情况发生,AnnexB 引入了防竞争字节(Emulation Prevention Bytes)的概念
        1. 在这里插入图片描述

        2. 防竞争字节,就是在给 NALU 添加起始码之前,先对码流进行一次遍历,查找码流里面的存在的 0x00 00 00,0x00 00 01,0x00 00 02,0x00 00 03 的字节,在 00 00 之后,插入一个字节,内容是 03。经过这样处理的码流,就不会再和起始码(0x00 00 01, 0x00 00 00 01)重复而发生冲突

      3. AnnexB格式通常用于实时的流格式,比如说传输流、实时播放、通过无线传输的广播、DVD等。在这些格式中通常会周期性的重复SPS和PPS包,经常是在每一个关键帧之前。因此据此解码器可以建立一个随机访问的点,这样就可以加入一个正在进行的流,及播放一个已经在传输的流。
    2. AVCC
      1. AVCC格式在每个NALU之前包含了长度信息,可以直接根据长度信息来定位和提取NALU。
      2. AVCC格式也叫AVC1格式,MPEG-4格式,常用于mp4/flv等封装中。AVCC格式的一个优点是在开始配置解码器的时候可以跳到流的中间播放,这种格式通常用于可以被随机访问的多媒体数据,如存储在硬盘的文件。解码器配置参数在一开始就配置好了,系统可以很容易的识别NALU的边界,不需要额外的起始码,减少了资源的浪费,同时可以在播放时调到视频的中间位置。这种格式通常被用于可以被随机访问的多媒体数据,如存储在硬盘的文件。MP4、MKV通常用AVCC格式来存储

NALU

  1. NALU的组成

    1. 一个NALU = NALU Header + NALU 主体
  2. NALU的主体涉及到三个重要的名词,分别为EBSP、RBSP和SODB。EBSP完全等价于NALU主体,EBSP包含RBSP,RBSP包含SODB

    1. EBSP完全等价于NALU主体

    2. RBSP,EBSP去掉防竞争字节之后的数据

    3. SODB是一种以比特为单位的数据表示形式。RBSP 相较于 SOBP,多了tariling bits

      1. RBSP 去掉补齐的数据后,就是 SODB

      2. 视频在编码的时候,会将一比特一比特的数据写入到码流里面,而在写完之后,就有可能发生一种情况,就是写入的数据数量不满一个字节,补齐的规则是先写入 1 bit 数据,数据内容是 1,然后开始补齐 0,直到补齐到一整个字节

        1. 在这里插入图片描述
      3. 如果刚刚好写满一个字节,就在补一个字节,新增加的字节第一位是 1,后面都是 0

        1. 在这里插入图片描述
    4. 在这里插入图片描述

  3. NALU Header

    1. 占一个字节大小,NALU Header的结构如下

      在这里插入图片描述

    2. forbidden_zero_bit

    3. 在网络传输中发生错误时,会被置为1,告诉接收方丢掉该单元,否则为0

    4. nal_ref_idc

      1. 用于表示当前NALU的重要性,值越大,越重要。解码器在解码处理不过来的时候,可以丢掉重要性为0的NALU

      2. nal_ref_idc重要性
        3HIGHEST
        2HIGH
        1LOW
        0DISPOSABLE
    5. nal_unit_type

      1. 表示NALU数据的类型,有以下几种
        在这里插入图片描述

        1. 1-4:I/P/B帧,它们是依据VLC的slice区分的。

        2. 5:IDR帧,立即解码刷新单元,可以独立解码和显示。一种特殊的I帧(Instantaneous Decoding Refresh),强制刷新解码器状态,确保后续帧仅参考IDR之后的图像。IDR帧需依赖当前有效的SPS/PPS进行解码,通常这些参数集会在IDR帧之前传输。解码器在遇到IDR帧时,会丢弃之前的参考帧,并应用最新的SPS/PPS配置

        3. 6:SEI,英文全称Supplemental Enhancement Information,翻译为“补充增强信息”,用于向码流中添加非必要的辅助数据,不影响解码流程,解码器可选择性解析或忽略,常见用途:携带时间戳、HDR元数据、字幕、版权信息等。

        4. 7:SPS,全称Sequence Paramater Set,翻译为“序列参数集”。SPS中保存了一组编码视频序列(Coded Video Sequence)的全局参数。因此该类型保存的是和编码序列相关的参数,比如profile、level、分辨率、帧率、参考帧数量等。

          1. 计算帧率参考

            00 00 00 01 67 64 10 28 f0 6c 6a 82  80 41 a6 c8 00 00 03 00 08 00 00 03 01 e4 78 40  21 50
            去掉防竞争。类型。头
            64 10 28 f0 6c 6a 82 80 41 a6 c8 00 00 00 08 00 00 01 e4 78 40 21 50
            //去掉补齐。50:010//1 0000Offset | Data       | 含义
            -------+------------+-------------------------
            0x00   | 00 00 00 01 | Start code
            0x04   | 67         | NALU头 (SPS类型)
            0x05   | 64 10 28   | Profile/Level/约束标志
            0x08   | f0 6c 6a 82 80 41 a6 c8 | SPS主体参数
            0x10   | 00 00 00 08| 疑似num_units_in_tick
            0x14   | 00 00 01 e4| 疑似time_scalefps = time_scale / (2 * num_units_in_tick)= 484 / (2 * 8) ≈ 30
            
        5. 8:PPS,全称Picture Paramater Set,翻译为“图像参数集”。该类型保存了整体图像相关的参数,包含有关熵编码模式、分片组、运动预测和去块滤波器等信息。

        6. 9:AU分隔符,AU全称Access Unit,它是一个或者多个NALU的集合,代表了一个完整的帧。

片(Slice)

  1. 片(Slice) 是编码层(VCL)的核心逻辑单元,用于将一帧图像划分为多个可独立编码和传输的数据块
    1. 一帧视频图像可以编码为一个或若干个 slice
    2. 每个片经过编码后,会封装到一个 NALU(网络抽象层单元) 中,因此单个 NALU 通常仅包含一个片。
  2. VCL NALU:直接承载片的编码数据,是码流中实际存储视频内容的核心单元。
    非 VCL NALU:包含序列参数集(SPS)、图像参数集(PPS)等控制信息。
  3. 一帧图像可以编码为一个或多个片(Slice),而每一个片(Slice)最少包含一个宏块,最多包含整帧图像的宏块
  4. 片的主要目的是为限制误码的扩散和传输,一帧图像可编码为一个或多个片,每个片独立编码,支持容错和并行处理。片内宏块按光栅顺序连续排列,且不同片之间禁止相互参考
  5. 每个片也包含头和数据两部分
    1. 片头中包含着片类型、片中的宏块类型、片帧的数量、片属于哪个图像以及对应的帧的设置和参数等信息。
    2. 片数据中则是宏块,这里就是我们要找的存储像素数据的地方。
  6. 在这里插入图片描述

视频压缩

  1. 帧内压缩
    1. 指的是一帧图片的内部压缩。当H.264对图片进行 16 * 16 分块后,会对每个小块内的图像进行分析,如果2个小块图像比较相近,那么住需要存储一张即可,无需存储重复图块。这样可以有效压缩图片的存储大小
    2. 帧内压缩是生成I帧的算法
  2. 帧间压缩
    1. 指的是图片间的图像压缩。在每帧图片划分成16 * 16 小块的图像进行分析基础上,比图片间的数据,如果两张图片比较相近,对相同的图像模块只需存储一份,对不同的部分再做存储。避免了重复数据的存储,极大改善了图片压缩空间
    2. 帧间压缩是生成B帧和P帧的算法
  3. 图像(I帧、P帧、B帧)
    1. I帧:完整编码的帧叫I帧,是一个图像经过压缩后的产物,自身可以通过视频解压算法解压成一张单独的完整的图片
    2. P帧:参考之前的I帧生成的只包含差异部分编码的帧叫P帧, 需要参考其前面的一个I 帧或者P 帧来生成一张完整的图片 ;
    3. B帧:参考前后的帧编码的帧叫B帧 , 要参考其前一个I或者P帧及其后面的一个P帧来生成一张完整的图片
    4. 在这里插入图片描述

宏块(Macroblock)

  1. 宏块(Macroblock)是视频压缩的基本单元,其像素区域由亮度元素和色度元素组成。视频解码最主要的工作则是提供高效的方式从码流中获得宏块中的像素阵列

  2. 在这里插入图片描述

  3. 在这里插入图片描述

http://www.dtcms.com/a/284968.html

相关文章:

  • C语言(20250717)
  • select_shape_proto 用起来很省事
  • 4G模块 A7680通过MQTT协议连接到华为云
  • 广州VR 内容制作报价:各类 VR 内容的报价详情​
  • 闲庭信步使用图像验证平台加速FPGA的开发:第二十课——图像还原的FPGA实现
  • 深入理解进程等待:wait的简化与waitpid的灵活性
  • kimi故事提示词 + deepseekR1 文生图提示
  • milvus向量数据库连接测试 和 集合维度不同搜索不到内容
  • windows利用wsl安装qemu
  • 利用deepspeed在Trainer下面微调大模型Qwen2.5-3B
  • SpringBoot01-springBoot的特点
  • 登录功能实现深度解析:从会话管理到安全校验全流程指南
  • 【算法训练营Day13】二叉树part3
  • 【中等】题解力扣21:合并两个有序链表
  • 教你使用bge-m3生成稀疏向量和稠密向量
  • 大语言模型系列(1): 3分钟上手,在骁龙AI PC上部署DeepSeek!
  • 【Lua】题目小练2
  • LIN协议核心详解
  • c++之 KMP 讲解
  • Cocos游戏中UI跟随模型移动,例如人物头上的血条、昵称条等
  • C++中,不能声明为虚函数的函数类型
  • C++进阶-AVL树(平衡二叉查找树)(难度较高)
  • 2025 XYD Summer Camp 7.17 模考
  • Vue.js 响应式原理深度解析:从 Vue 2 的“缺陷”到 Vue 3 的“涅槃重生”
  • OpenVela之网络驱动适配指南
  • JxBrowser 7.43.5 版本发布啦!
  • ​​Sublime Text 2.0.2.2221 安装教程 - 详细步骤指南(附下载与配置)​
  • 深入解析:Chunked Prefill 与 FlashAttention/FlashInfer 如何协同工作
  • WSL2 离线安装流程
  • 如何让订货系统支持多角色?