h264 NAL解析

article/2025/9/28 0:22:19

目录

1 AVCC与Annex-B标准

2 slice

2.1 slice header

3 elecard工具解析示例


H.264标准中,视频流是由NAL(Network Abstraction Layer)单元组成的(简称NALU),每个NALU中可能是IDR图像、SPS、PPS、non-IDR图像等。

1 AVCC与Annex-B标准

H.264码流分为AVCC与Annex-B两种组织格式。

  •  AVCC格式 也叫AVC1格式,MPEG-4格式,字节对齐,因此也叫Byte-Stream Format。用于mp4/flv/mkv等封装中。 
  • Annex-B格式 也叫MPEG-2 transport stream format格式(ts格式), ElementaryStream格式。用于TS流中(以及使用TS作为切片的hls格式中)。

这两种格式的区别有两点: 

(1)NALU的分割方式不同; 

(2)SPS/PPS的数据结构不同。

  • AVCC格式使用NALU长度(固定字节,字节数由extradata中的信息给定)进行分割,在封装文件或者直播流的头部包含extradata信息(非NALU),extradata中包含NALU长度的字节数以及SPS/PPS信息。
  • Annex-B格式使用start code进行分割,start code为0x000001或0x00000001,SPS/PPS作为一般NALU单元以start code作为分隔符的方式放在文件或者直播流的头部。

AVCC格式的extradata格式定义在“ISO_IEC_14496-15"文档中,Annex-B格式的SPS/PPS定义可以在"ISO_IEC_14496-10"文档中找到。

                                                            图 Annex-B格式h264码流

RBSP 的基本结构是:在原始编码数据VCL的后面填加填充 比特,以便字节对齐。一个 bit“1”若干比特“0”。

                                                                                   nal二进制示例图

1)0x00 00 00 01起始码,1998年以后的标准;1998年以前是0x00 00  01

2)NALU头为0x67,转换为二进制0110 0111
禁止位为0
NAL重要性为11,即3,表示最重要
NALU类型为[00111],即7,类型为7表示该NALU是SPS

//数据分割时视频传输在易错环境下抗误码的有效途径,使客户端在易错环境下能收到较为重要的视频信息,从而进行有效的错误掩盖,改善播放体验。通常A类信息slice-A + slice-B + slice-C=slice

2:slice A,包含slice header, MB header,量化参数、运动矢量等信息。A 类数据包含了正确解码图像所需的最重要信息。

3:slice B,包含所有Intra宏块的CBP (Coded Block Patter)和DCT。B 类数据包含了次重要的信息。

4:slice C,包含所有Inter宏块的CBP和DCT。C类数据包含的重要性最弱,有时slice的C类数据丢失对重建图像的质量几乎没有影响。但是C类数据却是A、B、C中数据量最大的。

5:IDR中的slice

6:补充增强信息单元SEI

7:sps

8:pps

                                                           

MediaCodec与VideoToolBox使用的数据格式

Android的硬解码接口MediaCodec只能接收Annex-B格式的H.264数据,而iOS平台的VideoToolBox则相反,只支持AVCC格式。这就导致:

  • 在Android平台硬解播放flv/mp4/mkv等封装的视频时,需要将AVCC格式的extradata以及NALU数据转为Annex-B格式;
  • 在iOS平台播放ts或ts切片的hls视频时,需要将Annex-B格式的SPS/PPS NALU转为AVCC格式的extradata,以及将其他以size方式分割的NALU转为start code方式。

2 slice

视频由frame组成(IDR,I,B,P帧),frame由slice构成,slice由宏块构成。每个NALU可能存放的是VCL音视频数据的slice或非VCL数据(SPS,pps等描述信息)。若slice数据量大于MTU(1500字节),一个NALU单元存放不下,分别封装在多个NALU中。

                                                             图  NAL构成

每一个Slice分为Slice header(用于保存Slice的总体信息)和Slice body组成(通常是一组连续的宏块结构或者宏块跳过信息),如下图所示:

 

SI和SP:即Switch I和Switch P,是一种特殊的编解码条带,可以保证在视频流之间进行有效的切换,并且解码器可以任意的访问。比如,同一个视频源被编码成各种码率的码流,在传输的过程中可以根据网络环境进行实时的切换;

2.1 slice header

  • first_mb_in_slice: 当前slice中包含的第一个宏块在整帧中的位置;
  • slice_type:当前slice的类型;

slice_type的值5到9表示除了当前条带的编码类型,所有当前编码图像的其他条带的slice_type的值应与当前条带的slice_type的值一样,或者等于当前条带的slice_type的值减5。对于IDR图像,slice_type的值应为2、4、7或者9。

  • pic_parameter_set_id:当前slice所依赖的pps的id;范围 0 到 255。
  • colour_plane_id:当标识位separate_colour_plane_flag为true时,colour_plane_id表示当前的颜色分量,0、1、2分别表示Y、U、V分量。
  • frame_num:表示当前帧序号的一种计量方式。
  • field_pic_flag:场编码标识位。当该标识位为1时表示当前slice按照场进行编码;该标识位为0时表示当前slice按照帧进行编码。
  • bottom_field_flag:底场标识位。该标志位为1表示当前slice是某一帧的底场;为0表示当前slice为某一帧的顶场。
  • idr_pic_id:表示IDR帧的序号。某一个IDR帧所属的所有slice,其idr_pic_id应保持一致。该值的取值范围为[0,65535]。
  • pic_order_cnt_lsb:表示当前帧序号的另一种计量方式。
  • delta_pic_order_cnt_bottom:表示顶场与底场POC差值的计算方法,不存在则默认为0;
  • slice_qp_delta:用于计算当前slice内所使用的初始qp值。

3 elecard工具解析示例

示例1

 

 profile_idc = 66 → baseline profile;

profile_idc = 77 → main profile;

profile_idc = 88 → extended profile;

(profile_idc = 99 → high profile;)

constraint_set0_flag ~ constraint_set5_flag是在编码的档次方面对码流增加的其他一些额外限制性条件。

level_idc,除以10,码流级别=5.2

seq_parameter_set_id表示当前的序列参数集的id。通过该id值,图像参数集pps可以引用其代表的sps中的参数。

max_num_ref_frames,用于表示参考帧的最大数目。

gaps_in_frame_num_value_allowed_flag,标识位,说明frame_num中是否允许不连续的值。

pic_width_in_mbs_minus1,用于计算图像的宽度,单位为宏块个数-1。

mb_adaptive_frame_field_flag,标识位,说明是否采用了宏块级的帧场自适应编码。当该标识位为0时,不存在帧编码和场编码之间的切换;当标识位为1时,宏块可能在帧编码和场编码模式之间进行选择。

direct_8x8_inference_flag,标识位,用于B_Skip、B_Direct模式运动矢量的推导计算。

frame_cropping_flag,标识位,说明是否需要对输出的图像帧进行裁剪。

vui_parameters_present_flag标识位,说明SPS中是否存在VUI信息。

 pic_parameter_set_id,表示当前PPS的id。某个PPS在码流中会被相应的slice引用,slice引用PPS的方式就是在Slice header中保存PPS的id值。该值的取值范围为[0,255]。

seq_parameter_set_id,表示当前PPS所引用的激活的SPS的id。通过这种方式,PPS中也可以取到对应SPS中的参数。该值的取值范围为[0,31]。

num_slice_groups_minus1,表示某一帧中slice group的个数。当该值为0时,一帧中所有的slice都属于一个slice group。slice group是一帧中宏块的组合方式,定义在协议文档的3.141部分。

weighted_pred_flag,标识位,表示在P/SP slice中是否开启加权预测。

weighted_bipred_idc,表示在B Slice中加权预测的方法,取值范围为[0,2]。0表示默认加权预测,1表示显式加权预测,2表示隐式加权预测。

pic_init_qp_minus26和pic_init_qs_minus26,表示初始的量化参数。实际的量化参数由该参数、slice header中的slice_qp_delta/slice_qs_delta计算得到。

chroma_qp_index_offset,用于计算色度分量的量化参数,取值范围为[-12,12]。

 

示例2

 

 

 

 

示例3

 

 


http://chatgpt.dhexx.cn/article/si0VSrb0.shtml

相关文章

H264(NAL简介与I帧判断)

http://blog.csdn.net/jefry_xdz/article/details/8461343 1、NAL全称Network Abstract Layer, 即网络抽象层。 在H.264/AVC视频编码标准中,整个系统框架被分为了两个层面:视频编码层面(VCL)和网络抽象层面(NA…

H.264(NAL简介与I帧判断)

H.264(NAL简介与I帧判断) 1、NAL全称Network Abstract Layer, 即网络抽象层。 在H.264/AVC视频编码标准中,整个系统框架被分为了两个层面:视频编码层面(VCL)和网络抽象层面(NAL)。其中,前者负责…

NAL(网络自适应层)

(1)整个系统框架被分为了两个层面:视频编码层面(VCL)和网络抽象层面(NAL)。其中,前者负责有效表示视频数据的内容,而后者则负责格式化数据并提供头信息,以保证…

H264的NAL解析

一、NAL全称Network Abstract Layer, 即网络抽象层。 在H.264/AVC视频编码标准中,整个系统框架被分为了两个层面:视频编码层面(VCL)和网络抽象层面(NAL)。其中,前者负责有效表示视频数据的内容&…

【Lua】xLua逻辑热更新

1 前言 Lua基础语法 中系统介绍了 Lua 的语法体系,ToLua逻辑热更新 中介绍了 ToLua 的应用,本文将进一步介绍 Unity3D 中基于 xLua 实现逻辑热更新。 逻辑热更新是指:在保持程序正常运行的情况下,在后台修改代码逻辑,修…

[Unity实战]一个好用的lua/xlua/tolua/slua调试工具vscode-luaide-lite插件 好用到飞起..[Unity-Debug+Xlua-Debug][开箱可用]

[Unity实战]一个好用的lua调试工具vscode-luaide-lite插件 好用到飞起..[Debug][开箱可用][xlua] 简介官方例子:xlua/tolua/slua/lua5.1等1.安装2.配置3.使用3.1启动unity3.2vscode-debug:Unity Editor3.3vscode-debug:3.4运行unity进入断点... 4.核心代码:5.github地址 简介 l…

XLua——热更新

什么是热更新? 游戏上线后,出现游戏Bug或者需要更新小版本内容,游戏如果没有做热更新支持的话,就需要重重新打包游戏,然后上传平台进行审核,审核通过后玩家才可以下载新版本。审核期间需要时间,…

通过Xlua插件运行lua程序

using System.Collections; using System.Collections.Generic; using UnityEngine; using XLua; //引入xlua命名空间 public class Creat : MonoBehaviour {private LuaEnv luaenv;void Start(){luaenv new LuaEnv(); //LuaEnv可以理解为lua的运行环境luaenv.DoString("…

xlua基础知识

1.1 xLua简介 xLua是由腾讯维护的一个开源项目,xLua为Unity、 .Net、 Mono等C#环境增加Lua脚本编程的能力,借助xLua,这些Lua代码可以方便的和C#相互调用。自2016年初推广以来,已经应用于十多款腾讯自研游戏,因其良好性…

[Unity XLua]热更新XLua入门(一)-基础篇

无意中发现了一个巨牛巨牛的人工智能教程,忍不住分享一下给大家。教程不仅是零基础,通俗易懂,小白也能学,而且非常风趣幽默,还时不时有内涵段子,像看小说一样,哈哈~我正在学习中&…

Xlua

有一个项目做完快上线了,不是lua写的,能热更新的东西就特别少,如果遇到bug也很难在第一时间热修复,所以我就接入了Xlua这个插件点击打开链接 原本只是想热修复一下的,后来领导要求把逻辑系统的C#代码全部换成了Lua,至于为什么,因为他们习惯了每天都更新和修改的开发模式...所以…

xLua热更新(二)实现热更新

一、环境配置 要实现热更新功能,我们首先需要开启热更新的宏。操作方法是在「File->Build Settings->Player Settings->Player->Other Settings->Scripting Define Symbols」选项中添加HOTFIX_ENABLE 开启后,在xLua的菜单中就出现了「…

Unity 热更新技术 |(六)xLua框架学习最新系列完整教程

🎬 博客主页:https://xiaoy.blog.csdn.net 🎥 本文由 呆呆敲代码的小Y 原创,首发于 CSDN🙉 🎄 学习专栏推荐:Unity系统学习专栏 🌲 游戏制作专栏推荐:游戏制作 🌲Unity实战100例专栏推荐:Unity 实战100例 教程 🏅 欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬…

xLua(九)——实战

一:使用xLua的步骤 ——导入xLua插件 其实xLua本质就是一个Unity工程,把Asset中的文件导入到Unity工程中就搞定了(导入之后编辑器菜单栏会扩展出一个XLua选项) ——添加宏File——Build Settings——Player Settings——Other Se…

【XLua】简单使用

文章目录 前言1 配置1.1 配置宏1.2 XLua配置 2 lua和C#相互调用2.1 XLua.CSharpCallLua2.2 XLua.LuaCallCSharp 3 加载器 前言 XLua本质上是为Unity提供了使用lua的能力,实际多用于热更新。 热更新,因为要给代码打标签才能生效,所以需要预测…

xLua介绍

xLua地址:传送门 Xlua是啥? 2016年 腾讯推出的 一种 unity下 lua 编成的解决方案 基本概念介绍: 1.模块 模块就是一个 程序库,可以通过 require 加载,得到了一个表示 table的全局变量 这个table 就像一个命名空间&am…

Lua快速入门篇(XLua教程)(Yanlz+热更新+xLua+配置+热补丁+第三方库+API+二次开发+常见问题+示例参考)

《Lua热更新》 ##《Lua热更新》发布说明: “Lua热更新”开始了,立钻哥哥终于开始此部分的探索了。 作为游戏发布迭代的重要技术:Lua热更新在网络游戏迭代更新中非常重要,特别是对于AppStore这样的平台,我们只需要定…

XLua加载

XLua加载lua文件的方式 LuaEnv.DoString(print("hello world")); //直接执行lua的语句,在函数体内的语句格式要符合lua的语法 LuaEnv.DoString("require byfile")//使用require lua文件名也可在unity中加载lua 但是在unity中需要把文件放置在…

XLua系列讲解_Helloworld

一、XLua简介 XLua是Unity3D下Lua编程解决方案,自2016年初推广以来,已经应用于十多款腾讯自研游戏,因其良好性能、易用性、扩展性而广受好评。现在,腾讯已经将xLua开源到GitHub。 二、Xlua的优点 简洁易用,容易上手可…

Unity XLua Hotfix热更新配置笔记

Unity XLUA Hotfix热更新配置笔记 目录 Unity XLUA Hotfix热更新配置笔记 配置热更新步骤: 下载XLUA下载压缩包解压 复制xlua 和plugins到assets开启热补丁特性 先添加宏 HOTFIX_ENABLE;INJECT_WITHOUT_TOOL报“This delegate/interface must add to CSharpCallLu…