【H.264/AVC视频编解码技术详解】六、H.264的NAL解析

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 《H.264/AVC视频编解码技术详解》视频教程已经在“CSDN学院”上线,视频中详述了H.264的背景、标准协议和实现,并通过一个实战工程的形式对H.

《H.264/AVC视频编解码技术详解》视频教程已经在“CSDN学院”上线,视频中详述了H.264的背景、标准协议和实现,并通过一个实战工程的形式对H.264的标准进行解析和实现,欢迎观看!

“纸上得来终觉浅,绝知此事要躬行”,只有自己按照标准文档以代码的形式操作一遍,才能对视频压缩编码标准的思想和方法有足够深刻的理解和体会!

链接地址:H.264/AVC视频编解码技术详解

本节视频免费

GitHub代码地址:点击这里

H.264的NAL解析

在有序字节流格式的H.264码流中,我们可以根据前缀起始码0x 00 00 01或0x 00 00 01获取到一个完整的NAL Unit所包含的的字节数据。H.264码流中的每一个NAL Unit的作用并不是相同的,而是根据不同的类型起不同的作用。因此将H.264的码流解析为NAL Unit之后,下一步将是对NAL Unit中的数据进行解析。

  1. NAL Unit结构

H.264标准中规定的一个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帧等。

    1. NAL Unit的有效负载数据及其封装

在NAL Header之后,NAL Unit的其余部分,即NAL Body包含了有效负载数据的封装。从NAL Body到实际的语法元素的码流共3层封装:

(1). 第一层: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数据。

(2). 第二层:RBSP——原始字节序列载荷

RBSP全称为Raw Byte Sequence Payload,相当于NAL Body去掉emulation_prevention_three_byte之后的数据,是对原始的语法元素码流进一步处理后产生的数据。相比于原始的语法元素码流,RBSP在末尾添加了rbsp_trailing_bits()部分,其主要目的是字节对齐。每个rbsp_trailing_bits()包括一个1bit和若干个0bit,0bit的个数不定,以实现字节的对齐。

(3). 第三层:SODB——数据字节流

SODB全称为String Of Data Bits,表示H.264的语法元素编码完成后的实际的原始二进制码流。SODB通常不能保证字节对其。

目录
相关文章
|
3天前
|
数据安全/隐私保护 流计算 开发者
python知识点100篇系列(18)-解析m3u8文件的下载视频
【10月更文挑战第6天】m3u8是苹果公司推出的一种视频播放标准,采用UTF-8编码,主要用于记录视频的网络地址。HLS(Http Live Streaming)是苹果公司提出的一种基于HTTP的流媒体传输协议,通过m3u8索引文件按序访问ts文件,实现音视频播放。本文介绍了如何通过浏览器找到m3u8文件,解析m3u8文件获取ts文件地址,下载ts文件并解密(如有必要),最后使用ffmpeg合并ts文件为mp4文件。
|
3天前
|
存储 应用服务中间件 云计算
深入解析:云计算中的容器化技术——Docker实战指南
【10月更文挑战第14天】深入解析:云计算中的容器化技术——Docker实战指南
14 1
|
4天前
|
开发框架 JavaScript 前端开发
Electron技术深度解析:构建跨平台桌面应用的利器
【10月更文挑战第13天】Electron技术深度解析:构建跨平台桌面应用的利器
19 0
|
4天前
|
缓存 前端开发 JavaScript
Webpack技术深度解析:模块打包与性能优化
【10月更文挑战第13天】Webpack技术深度解析:模块打包与性能优化
|
5天前
|
分布式计算 Java 应用服务中间件
NettyIO框架的深度技术解析与实战
【10月更文挑战第13天】Netty是一个异步事件驱动的网络应用程序框架,由JBOSS提供,现已成为Github上的独立项目。
16 0
|
10天前
|
缓存 Java 程序员
Map - LinkedHashSet&Map源码解析
Map - LinkedHashSet&Map源码解析
26 0
|
10天前
|
算法 Java 容器
Map - HashSet & HashMap 源码解析
Map - HashSet & HashMap 源码解析
24 0
|
10天前
|
存储 Java C++
Collection-PriorityQueue源码解析
Collection-PriorityQueue源码解析
20 0
|
10天前
|
安全 Java 程序员
Collection-Stack&Queue源码解析
Collection-Stack&Queue源码解析
24 0
|
8天前
|
存储
让星星⭐月亮告诉你,HashMap的put方法源码解析及其中两种会触发扩容的场景(足够详尽,有问题欢迎指正~)
`HashMap`的`put`方法通过调用`putVal`实现,主要涉及两个场景下的扩容操作:1. 初始化时,链表数组的初始容量设为16,阈值设为12;2. 当存储的元素个数超过阈值时,链表数组的容量和阈值均翻倍。`putVal`方法处理键值对的插入,包括链表和红黑树的转换,确保高效的数据存取。
29 5

推荐镜像

更多