H264之NALU结构详解

2023-12-10 12:12
文章标签 详解 结构 h264 nalu

本文主要是介绍H264之NALU结构详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  摘要:本文详细描述了AVC的NALU的码流结构,以及各个层面上NALU详细的构成。
  关键字:AVC,NALU

1 NALU简介

  NAL层即网络抽象层(Network Abstraction Layer),是为了方便在网络上传输的一种抽象层。一般网络上传输的数据包有大小限制,而AVC的帧大小远远大于网络传输的字节大小限制。因此要对AVC的数据流进行拆包,将一帧数据拆分为多个包传输。和NAL层相对是VAL层,即视频编码层(Video Coding Layer)

  NALU就是经过分组后的一个一个数据包。每个NALU由一个1字节的NALU头部和一个包含控制信息或编码视频数据的字节流组成。NALU头部包含了NALU的类型以及其重要性的信息。NALU的类型指示了NALU的用途或功能,可以用于识别不同类型的单元,例如参数集和用于参考的片段。用于参考的参数集和片段被认为是重要或高优先级的,因为它们的丢失可能会导致难以解码后续的编码片段。非参考片段被认为对解码器的影响较小,因为它们的丢失不会影响进一步的解码。这些信息可以选择性地用于在传输过程中对某些NALU进行优先级排序。
  每个NALU中的VCL数据即编码序列以一个或多个即时解码器刷新(IDR)访问单元开始,其中包含一个或多个IDR片段,每个IDR片段都是一个帧内编码的片段。接下来是默认的片段类型,即非IDR编码的片段,以及/或者数据分割片段。数据分割片段将编码视频数据的不同组件分别放在单独的NAL单元中,这在存在传输错误的情况下可能很有用。非VCL NAL单元包括参数集、补充增强信息参数,这些参数对解码和显示视频数据可能有用,但对于正确解码来说并非必需,以及定义编码部分之间边界的分隔符。

2 NALU码流结构

在这里插入图片描述

  一个完整的数据包包含多个NALU,不同的NALU该如何组织规范中并没有规定,因此实际实现比较广泛的有两种格式AnnexB和AVCC。

2.1 AnnexB

在这里插入图片描述

  AnnexB是一种比较常见的H264码流格式,FFmpeg解封装的H264码流就是这种格式。AnnexB的格式比较简单每个NALU单元之前通过分隔符0x00 00 00 01或者0x00 00 01区分不同的NALU单元。对于非VCL和VCL的单元是不区分的都是存储在NALU的Body中。
  由于NALU的Body中的数据是压缩数据可能出现start code,因此规定RBSP中的0x000000、0x000001、0x000002和0x000003是非法的。如果数据中包含类似的二进制序列需要插入一个“模拟预防”字节0x03来实现,使得0x000001变成0x00000301,解码时去除即可。

  VCL包含经过编码的数据,而非VCL包含一些元数据协助解码。

2.2 AVCC

在这里插入图片描述

  另一种常见的存储H.264流的方法是AVCC格式。在这种格式中,每个NALU之前都有它的长度(以大端格式表示)。这种方法更容易解析,但会失去附录B的字节对齐特性。长度可以使用1、2或4个不同的字节进行编码增加复杂性。该值存储在一个头部对象中,通常被称为“extradata”或“sequence header”。它的基本格式如下:

bits    
8   version ( always 0x01 )
8   avc profile ( sps[0][1] )
8   avc compatibility ( sps[0][2] )
8   avc level ( sps[0][3] )
6   reserved ( all bits on )
2   NALULengthSizeMinusOne
3   reserved ( all bits on )
5   number of SPS NALUs (usually 1)repeated once per SPS:16         SPS sizevariable   SPS NALU data8   number of PPS NALUs (usually 1)repeated once per PPS:16       PPS sizevariable PPS NALU data

2.3 AVCC和AnnexB优点对比

  两种不同格式的优点:
附录B(Annex B)格式:

  • 字节对齐特性:Annex B格式使用起始码(start code)作为NALU的分隔符,这使得解析和处理数据包相对容易,因为起始码可以用于准确定位NALU的边界。
  • 广泛支持:Annex B格式是H.264视频流的一种常见格式,得到了广泛的支持,并且在许多常见的容器格式(如MP4)中使用。
  • 适合网络流。
    AVCC格式:
  • 简化解析:AVCC格式在每个NALU之前包含了长度信息,这使得解析和处理数据包更加简单,因为可以直接根据长度信息来定位和提取NALU。
  • 灵活性:AVCC格式允许使用不同字节长度来编码NALU的长度,从而提供了更大的灵活性,可以适应不同大小的NALU。
  • 适合本地文件。

2.3 NALU

  一个完整的NALU由NALU Header和RBSP(Raw Byte Sequence Payloads)组成。
  NALU Header占位8Bit,其中三个字段分别为

  • Forbidden_bit(1bit,一定是0);
  • NAL_Reference_bit(2bit,优先级),如 00 的 NALU 解码器可以丢弃它而不影响图像的回放。0~3,取值越大,表示当前NALU越重要,需要优先受到保护。如果当前NALU是属于参考帧的片,或是序列参数集,或是图像参数集这些重要的单位时,本句法元素必需大于0;
  • NAL_UNIT_TYPE(5bit),标识了当前Unit的类型和优先级信息。
      下面是Unit的类型标识和具体对应的类型描述(一般码流的前两个NALU分别是SPS和PPS):
0      Unspecified                                                    non-VCL
1      Coded slice of a non-IDR picture                               VCL
2      Coded slice data partition A                                   VCL
3      Coded slice data partition B                                   VCL
4      Coded slice data partition C                                   VCL
5      Coded slice of an IDR picture                                  VCL
6      Supplemental enhancement information (SEI)                     non-VCL
7      Sequence parameter set                                         non-VCL
8      Picture parameter set                                          non-VCL
9      Access unit delimiter                                          non-VCL
10     End of sequence                                                non-VCL
11     End of stream                                                  non-VCL
12     Filler data                                                    non-VCL
13     Sequence parameter set extension                               non-VCL
14     Prefix NAL unit                                                non-VCL
15     Subset sequence parameter set                                  non-VCL
16     Depth parameter set                                            non-VCL
17..18 Reserved                                                       non-VCL
19     Coded slice of an auxiliary coded picture without partitioning non-VCL
20     Coded slice extension                                          non-VCL
21     Coded slice extension for depth view components                non-VCL
22..23 Reserved                                                       non-VCL
24..31 Unspecified                                                    non-VCL
  • SPS: 序列参数集,包含解码配置,比如profile level 分辨率和帧率等。
  • PPS:图像参数集,包含有关熵编码模式、分片组、运动预测和去块滤波器等信息。
  • IDR: 立即解码刷新单元,这种NALU包含一个完整的图像序列,不依赖其他NALU就可以独立解码和显示,即一种特殊的I帧。

2.3.1 Slice

  一个视频图像可编码成一个或更多个切片,每个切片包含整数个宏块(MB),即每个切片至少一个 MB,最多时每个切片包含整个图像的宏块。总之,一幅图像中每个切片的宏块数不一定固定。设切片的目的是为了限制误码的扩散和传输,应使编码切片相互间是独立的。某个切片的预测不能以其它切片中的宏块为参考图像,这样某一切片中的预测误差才不会传播到其它切片中去。
  切片由切片头和切片数据组成。切片头(slice header)传递了适用于切片中所有宏块(macroblock)的共同信息,例如切片类型(slice type),切片类型确定了允许使用哪些宏块类型,切片对应的帧编号,参考图像设置以及默认量化参数(QP)。切片头包含了以下信息:

  • 切片类型:切片类型确定了切片中可以使用的宏块类型,例如I帧、P帧或B帧。
  • 帧编号:切片头指示了切片所对应的帧的编号,用于正确解码和顺序播放视频帧。
  • 参考图像设置:切片头包含了参考图像的相关设置,用于解码过程中的运动估计和补偿。
  • 默认量化参数(QP):切片头中包含了默认的量化参数,用于控制视频质量和压缩率。
      切片头中的这些信息对于解码器正确解码视频数据非常重要。通过切片头,解码器可以了解切片中宏块的类型、参考图像的设置以及量化参数的默认值,从而进行正确的解码和重建视频帧。切片头在H.264(或AVC)视频编码中起着关键的作用,它提供了切片中宏块的共同信息,确保视频数据能够被正确解码和播放。
      切片数据部分由一系列组成切片的宏块(macroblock)组成。在许多编码序列中,包含没有数据的宏块,即跳过宏块(skip macroblock),是非常常见的情况。跳过宏块通过参数"mb skip run"来表示,它表示一系列跳过的宏块的数量,在CAVLC熵编码模式下使用;或者通过"mb skip flag"来表示,它表示单个跳过的宏块,在CABAC熵编码模式下使用。跳过宏块是指在编码过程中,某些宏块不包含有效的数据,可以被跳过以提高编码效率。在切片数据部分中,这些跳过宏块的存在是很常见的。在CAVLC熵编码模式下,通过"mb skip run"参数来表示一连串跳过的宏块的数量。而在CABAC熵编码模式下,通过"mb skip flag"参数来表示单个跳过的宏块。这些跳过宏块的存在可以减少编码数据量,提高压缩效率。在解码过程中,解码器会根据相应的参数来识别和处理跳过宏块,以正确恢复视频帧的内容。切片数据部分中的这些跳过宏块对于视频编码和解码过程至关重要,它们在提高编码效率和压缩率方面发挥着重要作用。

2.3.2 宏块

  宏块层包含了解码单个宏块所需的所有语法元素。在H.264(或AVC)中,宏块是视频编码的基本单元,表示视频帧内的一个矩形像素块。宏块层包含了解码和重建宏块所需的所有信息和语法元素。宏块层中的语法元素包括:

  • 宏块类型:指定宏块的类型,如帧内(I帧)、预测(P帧)或双向预测(B帧),表示用于编码宏块的预测模式。
  • 运动矢量:指定宏块相对于前一帧中参考位置的位移,描述宏块的运动信息。
  • 变换系数:表示经过离散余弦变换(DCT)和量化后的宏块变换系数。
  • 预测模式:指示用于编码宏块的预测模式,如帧内预测或帧间预测。
  • 残差数据:包含预测和量化后的残差信息,用于在解码过程中重建宏块。
      通过解码宏块层中的语法元素,解码器可以重建宏块,并为整个视频帧的重建做出贡献。宏块层在解码过程中起着关键作用,因为它包含了解码和重建单个宏块所需的所有必要信息。

3 参考文献

  • H.264媒体流AnnexB和AVCC格式分析 及 FFmpeg解析mp4的H.264码流方法
  • Possible Locations for Sequence/Picture Parameter Set(s) for H.264 Stream
  • what the advantage of h264 Annex-B VS AVCC
  • H264解析
  • H264: From NAL to RTP

这篇关于H264之NALU结构详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/477083

相关文章

Redis实现延迟任务的三种方法详解

《Redis实现延迟任务的三种方法详解》延迟任务(DelayedTask)是指在未来的某个时间点,执行相应的任务,本文为大家整理了三种常见的实现方法,感兴趣的小伙伴可以参考一下... 目录1.前言2.Redis如何实现延迟任务3.代码实现3.1. 过期键通知事件实现3.2. 使用ZSet实现延迟任务3.3

C语言函数递归实际应用举例详解

《C语言函数递归实际应用举例详解》程序调用自身的编程技巧称为递归,递归做为一种算法在程序设计语言中广泛应用,:本文主要介绍C语言函数递归实际应用举例的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录前言一、递归的概念与思想二、递归的限制条件 三、递归的实际应用举例(一)求 n 的阶乘(二)顺序打印

Python Faker库基本用法详解

《PythonFaker库基本用法详解》Faker是一个非常强大的库,适用于生成各种类型的伪随机数据,可以帮助开发者在测试、数据生成、或其他需要随机数据的场景中提高效率,本文给大家介绍PythonF... 目录安装基本用法主要功能示例代码语言和地区生成多条假数据自定义字段小结Faker 是一个 python

Java Predicate接口定义详解

《JavaPredicate接口定义详解》Predicate是Java中的一个函数式接口,它代表一个判断逻辑,接收一个输入参数,返回一个布尔值,:本文主要介绍JavaPredicate接口的定义... 目录Java Predicate接口Java lamda表达式 Predicate<T>、BiFuncti

详解如何通过Python批量转换图片为PDF

《详解如何通过Python批量转换图片为PDF》:本文主要介绍如何基于Python+Tkinter开发的图片批量转PDF工具,可以支持批量添加图片,拖拽等操作,感兴趣的小伙伴可以参考一下... 目录1. 概述2. 功能亮点2.1 主要功能2.2 界面设计3. 使用指南3.1 运行环境3.2 使用步骤4. 核

一文详解JavaScript中的fetch方法

《一文详解JavaScript中的fetch方法》fetch函数是一个用于在JavaScript中执行HTTP请求的现代API,它提供了一种更简洁、更强大的方式来处理网络请求,:本文主要介绍Jav... 目录前言什么是 fetch 方法基本语法简单的 GET 请求示例代码解释发送 POST 请求示例代码解释

详解nginx 中location和 proxy_pass的匹配规则

《详解nginx中location和proxy_pass的匹配规则》location是Nginx中用来匹配客户端请求URI的指令,决定如何处理特定路径的请求,它定义了请求的路由规则,后续的配置(如... 目录location 的作用语法示例:location /www.chinasem.cntestproxy

CSS will-change 属性示例详解

《CSSwill-change属性示例详解》will-change是一个CSS属性,用于告诉浏览器某个元素在未来可能会发生哪些变化,本文给大家介绍CSSwill-change属性详解,感... will-change 是一个 css 属性,用于告诉浏览器某个元素在未来可能会发生哪些变化。这可以帮助浏览器优化

Python基础文件操作方法超详细讲解(详解版)

《Python基础文件操作方法超详细讲解(详解版)》文件就是操作系统为用户或应用程序提供的一个读写硬盘的虚拟单位,文件的核心操作就是读和写,:本文主要介绍Python基础文件操作方法超详细讲解的相... 目录一、文件操作1. 文件打开与关闭1.1 打开文件1.2 关闭文件2. 访问模式及说明二、文件读写1.

详解C++中类的大小决定因数

《详解C++中类的大小决定因数》类的大小受多个因素影响,主要包括成员变量、对齐方式、继承关系、虚函数表等,下面就来介绍一下,具有一定的参考价值,感兴趣的可以了解一下... 目录1. 非静态数据成员示例:2. 数据对齐(Padding)示例:3. 虚函数(vtable 指针)示例:4. 继承普通继承虚继承5.