【视频编解码·学习笔记】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规定了一种通 ...
随机推荐
- Machine Learning - week 1
Matrix 定义及基本运算 Transposing To "transpose" a matrix, swap the rows and columns. We put a &q ...
- CTF---密码学入门第一题 这里没有key
这里没有key分值:10 来源: 西普学院 难度:易 参与人数:5577人 Get Flag:1965人 答题人数:2074人 解题通过率:95% 你说没有就没有啊,俺为啥要听你的啊 解题链接: ht ...
- JSZX_HC_2016_R5
#1 ccz 200 #2 CTL 130 #3 KPM 130 本来以为准备挺充分的,开始后还是出现一些状况 >_< 好在还算顺利…… A AC人数:4 平均分:70 题目描述 给定 ...
- python面向对象进阶
前言 上节大话python面向对象对面向对象有了一些了解,这次就不用大话风格了 (ps:真心不好扯啊) isinstance与issubclass isinstance(obj,cls)检查是否obj ...
- JavaScript八张思维导图—字符串用法
JS基本概念 JS操作符 JS基本语句 JS数组用法 Date用法 JS字符串用法 JS编程风格 JS编程实践 不知不觉做前端已经五年多了,无论是从最初的jQuery还是现在火热的Angular,Vu ...
- HashSet,LinkedHashSet,TreeSet的区别
Set接口Set不允许包含相同的元素,如果试图把两个相同元素加入同一个集合中,add方法返回false.Set判断两个对象相同不是使用==运算符,而是根据equals方法.也就是说,只要两个对象用eq ...
- Redis能干啥?细看11种Web应用场景
下面列出11种Web应用场景,在这些场景下可以充分的利用Redis的特性,大大提高效率. 1.在主页中显示最新的项目列表. Redis使用的是常驻内存的缓存,速度非常快.LPUSH用来插入一个内容ID ...
- vue ajax获取数据的时候,如何保证传递参数的安全或者说如何保护api的安全
https://segmentfault.com/q/1010000005618139 vue ajax获取数据的时候,如何保证传递参数的安全或者说如何保护api的安全 点击提交,发送请求.但是api ...
- 用Dedecms5.7的arclist标签调用文章内容
arclist标签调用文章内容 首先大家都知道在Dedecms中,list标签是可以调用文章内容的,调用格式就不再此冗述了.从我个人来说,我非常不喜欢用list标签调用,有可能我会尽量使用arclis ...
- UITableViewCell滑动删除及移动
实现Cell的滑动删除, 需要实现UITableView的代理UITableViewDelegate中如下方法: //先要设Cell可编辑 - (BOOL)tableView:(UITableView ...