【视频编解码·学习笔记】5. NAL Unit 结构分析
在上篇笔记中通过一个小程序,可以提取NAL Unit所包含的的字节数据。H.264码流中的每一个NAL Unit的作用并不是相同的,而是根据不同的类型起不同的作用。下面将对NAL Unit中的数据进行解析。
一、NAL Unit结构
一个NAL Unit都是由一个NAL Header和一个NAL Body组成。对于基本版本的H.264标准(不考虑SVC和MVC扩展),一个NAL Header的长度固定为1,即8bit。这8bit的含义分别为:
- forbidden_zero_bit:每一个NAL Header的第一个bit,规定必须为0;
- nal_ref_idc:第2和3位,主要表示NAL的优先级。当该值为正时,表示当前NAL Unit中包含了SPS、PPS和作为参考帧的Slice等重要数据。
- nal_unit_type:表示NAL Unit的类型,包括VCL层和非VCL层的多种数据类型。常见的nal_unit_type取值有:7表示SPS,8表示PPS,5表示IDR帧,1表示非IDR帧等。
查询H.264文档7.3节,可以看到NAL Unit语法结构:
7.4节介绍了每一个语法结构的内容和作用
二、NAL Unit的有效负载数据及其封装
在NAL Header之后,NAL Unit的其余部分,即NAL Body包含了有效负载数据的封装。从NAL Body到实际的语法元素的码流共3层封装:
第一层:EBSP——扩展字节序列载荷
EBSP全称为Extended Byte String Payload,等同于NAL Body的数据本身。在EBSP中包含了一个特殊的字节0x03,表示防止竞争校验字节:
emulation_prevention_three_byte:设置该值的目的是为了防止NAL Body内部出现于NAL Unit起始码0x 00 00 01或0x 00 00 00 01冲突。
当内部的连续4字节数据出现了下列情况时:
0x 00 00 00
0x 00 00 01
0x 00 00 02
0x 00 00 03
在两个0字节之后会插入值为3的一个字节,形成下列情况:
0x 00 00 03 00
0x 00 00 03 01
0x 00 00 03 02
0x 00 00 03 03
在进行解析时需要将附加的03字节去掉,得到RBSP数据。
第二层:RBSP——原始字节序列载荷
RBSP全称为Raw Byte Sequence Payload,相当于NAL Body去掉emulation_prevention_three_byte之后的数据,是对原始的语法元素码流进一步处理后产生的数据。
作用:字节对齐。
每一个NAL Unit都是紧密排列的,如果出现一个UAL unit字节没对齐,后面的就都对不齐,那就需要时刻进行数据位的对齐操作, 会对接收端和解码端造成极大的负担。
在语法元素编码后,并不一定占满了所有的比特,最后可能会空出几位来。为了补全一位数据,在RBSP在末尾添加了rbsp_trailing_bits()部分,其主要目的是字节对齐。
每个rbsp_trailing_bits()包括一个1bit和若干个0bit,0bit的个数不定,以实现字节的对齐。
例如:一个字节中前三位编码了语法元素1 0 1,后面还剩5位,需要补上1 0 0 0 0,凑成一个字节。
完整的一个字节为 1 0 1 1 0 0 0 0。
第三层:SODB——数据字节流
SODB全称为String Of Data Bits,表示H.264的语法元素编码完成后的实际的原始二进制码流。SODB通常不能保证字节对其。
【视频编解码·学习笔记】5. NAL Unit 结构分析的更多相关文章
- 【视频编解码·学习笔记】11. 提取SPS信息程序
一.准备工作: 回到之前SimpleH264Analyzer程序,找到SPS信息,并对其做解析 调整项目目录结构: 修改Global.h文件中代码,添加新数据类型UINT16,之前编写的工程中,UIN ...
- 【视频编解码·学习笔记】4. H.264的码流封装格式 & 提取NAL有效数据
一.码流封装格式简单介绍: H.264的语法元素进行编码后,生成的输出数据都封装为NAL Unit进行传递,多个NAL Unit的数据组合在一起形成总的输出码流.对于不同的应用场景,NAL规定了一种通 ...
- 【视频编解码·学习笔记】6. H.264码流分析工程创建
一.准备工作: 新建一个VS工程SimpleH264Analyzer, 修改工程属性参数-> 输出目录:$(SolutionDir)bin\$(Configuration)\,工作目录:$(So ...
- 【视频编解码·学习笔记】8. 熵编码算法:基本算法列举 & 指数哥伦布编码
一.H.264中的熵编码基本方法: 熵编码具有消除数据之间统计冗余的功能,在编码端作为最后一道工序,将语法元素写入输出码流 熵解码作为解码过程的第一步,将码流解析出语法元素供后续步骤重建图像使用 在H ...
- 【视频编解码·学习笔记】3. H.264视频编解码工程JM的下载与编解码
一.下载JM工程: JM是H.264标准制定团队所认可的官方参考软件.网址如下 http://iphome.hhi.de/suehring/tml/ 从页面中可找到相应的工程源码,本次选择JM 8.6 ...
- 【视频编解码·学习笔记】10. 序列参数集(SPS)介绍
一.SPS 相关概念: SPS即 "Sequence Paramater Set",又称作序列参数集. SPS中保存了一组编码视频序列(Coded video sequence)的 ...
- 【视频编解码·学习笔记】13. 提取PPS信息程序
PPS结构解析 与之前解析SPS方式类似 一.定义PPS类: 在3.NAL Unit目录下,新建PicParamSet.cpp和PicParamSet.h,在这两个文件中写入类的定义和函数实现. 类定 ...
- 【视频编解码·学习笔记】12. 图像参数集(PPS)介绍
一.PPS相关概念: 除了序列参数集SPS之外,H.264中另一重要的参数集合为图像参数集Picture Paramater Set(PPS). 通常情况下,PPS类似于SPS,在H.264的裸码流中 ...
- 【视频编解码·学习笔记】4. H.264的码流封装格式
一.码流封装格式简单介绍: H.264的语法元素进行编码后,生成的输出数据都封装为NAL Unit进行传递,多个NAL Unit的数据组合在一起形成总的输出码流.对于不同的应用场景,NAL规定了一种通 ...
随机推荐
- 我的第一个spring_boot项目
springBoot火了有一段时间了,现在才接触,着实没跟上节奏.. 一.创建项目并跑起来 目的很简单,只要配置好springBoot环境,并成功启动,且能访问到我项目下的任一资源即可 1 下载mav ...
- Angular17 Angular自定义指令
1 什么是HTML HTML文档就是一个纯文本文件,该文件包含了HTML元素.CSS样式以及JavaScript代码:HTML元素是由标签呈现,浏览器会为每个标签创建带有属性的DOM对象,浏览器通过渲 ...
- 移动端APP列表点透事件处理方法
关于点透事件这里不再赘述,如果不清楚的可以上网搜一搜,或者看小火柴的这篇文章. 这里是自己在做移动端时,在列表滑动的时候,遇到的点透问题.出现这个问题的来由是因为在转场的时候,各个手机的转场效果不一样 ...
- HDU 1166 敌兵布阵(线段树单点更新,板子题)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
- Ultra-QuickSort(树状数组求逆序对数)
Ultra-QuickSort 题目链接:http://poj.org/problem?id=2299 Time Limit: 7000MS Memory Limit: 65536K Total ...
- 关于JAVA实现二维码以及添加二维码LOGO
今天在公司,完成了之前的任务,没有什么事做,就想鼓捣一下二维码,因为之前没有接触过,我就去翻看了几本书,也基本完成了二维码的实现,以及添加二维码的LOGO. 现在绘制二维码一般都使用的是谷歌的zxin ...
- 调用webService的几种方式
转自:http://blog.csdn.net/u011165335/article/details/51345224 一.概览 方式1: HttpClient:可以用来调用webservie服务,也 ...
- Winform & Devexpress Chart使用入门
一.Chart(Winform) 使用图表控件(chart)首先要理解图表区域(ChartArea).XY轴(AxisX.AxisY).数据点(Series).标题(Title).图例(Legend) ...
- NullPointerException org.apache.commons.digester.Digester.getXMLReader(Digester.java:1058)
http://pwu-developer.blogspot.com/2010/01/nullpointerexception.html Maven is great build tool making ...
- 邓_ Php·魔术方法
================================================ 1.__tostring() 用于定义输出对象引用时调用 常用于打印一些对象的信息 必须有返回值 ...