h264 sps pps详解

2024-04-12 20:58
文章标签 详解 sps h264 pps

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

1、学习路线

step1、初步了解h264,了解h264数据帧分类和识别

step2、h264语法相关算法解析,这里对理解h264的视频帧很重要。通俗的说h264数据定义是由一组Bit组成,但是某个字段不是固定专有几个bit,它是根据其值通过算法转义保存。

step3、sps、pps帧语法定义

2、h264简介

     在H.264/AVC视频编码标准中,整个系统框架被分为了两个层面:视频编码层面(VCL)和网络抽象层面(NAL)。其中,前者负责有效表示视频数据的内容,而后者则负责格式化数据并提供头信息,以保证数据适合各种信道和存储介质上的传输。NAL占一个字节。

    NAL单元(NALU):NAL的基本语法结构,它包含一个字节的头信息和一系列来自VCL的称为原始字节序列载荷(RBSP)的字节流。 数据流是储存在介质上时: 每个NALU 前添加起始码:0x00000001(或者0x000001),用来指示一个 NALU的起始和终止位置。我们平时的每帧数据就是一个NAL单元(SPS与PPS除外)。

    编码器将每个NAL各自独立、完整地放入一个分组,因为分组都有头部,解码器可以方便地检测出NAL的分界,并依次取出NAL进行解码。每个NAL前有一个起始码 0x00 00 01(或者0x00 00 00 01),解码器检测每个起始码,作为一个NAL的起始标识,当检测到下一个起始码时,当前NAL结束。同时H.264规定,当检测到0x000000时,也可以表征当前NAL的结束。那么NAL中数据出现0x000001或0x000000时怎么办?H.264引入了防止竞争机制,如果编码器检测到NAL数据存在0x000001或0x000000时,编码器会在最后个字节前插入一个新的字节0x03,这样:

0x000000->0x00000300
0x000001->0x00000301
0x000002->0x00000302
0x000003->0x00000303
解码器检测到0x000003时,把03抛弃,恢复原始数据(脱壳操作)。解码器在解码时,首先逐个字节读取NAL的数据,统计NAL的长度,然后再开始解码。

NALU头由一个字节组成, 它的语法如下:
      +---------------+
      |0|1|2|3|4|5|6|7|
      +-+-+-+-+-+-+-+-+
      |F|NRI|  Type   |
      +---------------+
F: 1 个比特.
  forbidden_zero_bit. 在 H.264 规范中规定了这一位必须为 0.
NRI: 2 个比特.
  nal_ref_idc. 取 00 ~ 11, 似乎指示这个 NALU 的重要性, 如 00 的 NALU 解码器可以丢弃它而不影响图像的回放. 不过一般情况下不太关心
这个属性.
Type: 5 个比特.
 nal_unit_type. 这个 NALU 单元的类型. 简述如下:
0    没有定义
1     一个非IDR图像的编码条带 (bp帧)
slice_layer_without_partitioning_rbsp( )      
2     编码条带数据分割块A 
slice_data_partition_a_layer_rbsp( )      
3     编码条带数据分割块B 
slice_data_partition_b_layer_rbsp( )      
4     编码条带数据分割块C 
slice_data_partition_c_layer_rbsp( )      
5     IDR图像的编码条带 (i帧)
slice_layer_without_partitioning_rbsp( )      
6     辅助增强信息 (SEI) 
sei_rbsp( )      
7     序列参数集 (sps帧)
seq_parameter_set_rbsp( )      
8     图像参数集 
pic_parameter_set_rbsp( pps帧)      
9     访问单元分隔符 
access_unit_delimiter_rbsp( )      
10     序列结尾 
end_of_seq_rbsp( )      
11     流结尾 
end_of_stream_rbsp( )      
12     填充数据 
filler_data_rbsp( )      
13     序列参数集扩展 
seq_parameter_set_extension_rbsp( )      
14...18     保留      
19     未分割的辅助编码图像的编码条带 
slice_layer_without_partitioning_rbsp( )      
20...23     保留      
24    STAP-A   单一时间的组合包
25    STAP-B   单一时间的组合包
26    MTAP16   多个时间的组合包
27    MTAP24   多个时间的组合包
28    FU-A     分片的单元
29    FU-B     分片的单元
30-31 没有定义

当遇到 00 00 00 01 67表示sps帧

当遇到 00 00 00 01 68 表示pps帧

3、h264语法相关算法解析 

1、无符号指数哥伦布熵编码

1.1 编码过程

1、将待编码的数加1转换为最小的二进制序列(假设一共M位); 
2、此二进制序列前面补充M-1个0; 
3、enjoy!

1.1.1 示例

对 4 进行无符号指数哥伦布熵编码 
1、将4加1(为5)转换为最小的二进制序列即 101 (此是M=3) 
2、此二进制序列前面补充M-1即两个0 
3、得出的4的无符号指数哥伦布熵编码的序列为 00101

1.2 解码过程

1、获取二进制序列开头连续的N个0 
2、读取之后的N+1位的值,假设为X 
3、X-1获取解码后的值

1.2.1 示例

如对 00101进行无符号指数哥伦布熵解码 
1、获取开头连续的N个0, 此时N = 2 
2、再向后读取N+1位的值,即 101,为5 
3、 5 - 1 =4 获取其解码后码值,enjoy!

1.3 其他

注意0的无符号指数哥伦布熵编码的二进制序列为 1

2 有符号指数哥伦布熵编码

2.1 编码过程

1、将待编码的数的绝对值转换为最小的二进制序列(假设一共M位) 
2、在此二进制序列后补充一位符号位0表示正,1表示负 
3、在此二进制序列前补充M个0 
4、enjoy

2.1.1 示例1

如对4进行有符号指数哥伦布熵编码 
1、4的绝对值转为最小二进制序列,即 100 (此时M = 3) 
2、后面补充符号位,0 即 1000 
3、前面补充M个0, 即 0001000 
4、enjoy

2.1.2 示例2

如对-15进行有符号指数哥伦布熵编码 
1、-7的绝对值转为最小二进制序列,即 1111 (此时M = 4) 
2、后面补充符号位,1,即 11111 
3、前面补充M个0,即 000011111 
4、enjoy

2.2 解码过程

1、获取二进制序列开头连续的N个0 
2、读取之后的N位的值,假设为X 
3、获取最后1位符号位 
4、获取解码后码值

2.2.1 示例1

如对二进制序列 0001000 进行有符号指数哥伦布熵解码 
1、获取开头连续的N个0, 此时N = 3 
2、再获取N为数值,即 100 即为4 
3、获取最后的符号位,0,即为正值 
4、故此序列解码后的码值为4

2.2.2 示例2

如对二进制序列 000011111 进行有符号指数哥伦布熵解码 
1、获取开头连续的N个0, 此时N = 4 
2、再获取N为数值,即 1111 即为15 
3、获取最后的符号位,1,即为负值 
4、故此序列解码后的码值为-15

 

4、sps语法

 

5、pps语法

 

 



转载自:http://blog.csdn.net/yuanbinquan/article/details/60148345


这篇关于h264 sps pps详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/898219

相关文章

Android中Dialog的使用详解

《Android中Dialog的使用详解》Dialog(对话框)是Android中常用的UI组件,用于临时显示重要信息或获取用户输入,本文给大家介绍Android中Dialog的使用,感兴趣的朋友一起... 目录android中Dialog的使用详解1. 基本Dialog类型1.1 AlertDialog(

C#数据结构之字符串(string)详解

《C#数据结构之字符串(string)详解》:本文主要介绍C#数据结构之字符串(string),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录转义字符序列字符串的创建字符串的声明null字符串与空字符串重复单字符字符串的构造字符串的属性和常用方法属性常用方法总结摘

Java中StopWatch的使用示例详解

《Java中StopWatch的使用示例详解》stopWatch是org.springframework.util包下的一个工具类,使用它可直观的输出代码执行耗时,以及执行时间百分比,这篇文章主要介绍... 目录stopWatch 是org.springframework.util 包下的一个工具类,使用它

Java进行文件格式校验的方案详解

《Java进行文件格式校验的方案详解》这篇文章主要为大家详细介绍了Java中进行文件格式校验的相关方案,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、背景异常现象原因排查用户的无心之过二、解决方案Magandroidic Number判断主流检测库对比Tika的使用区分zip

Java实现时间与字符串互相转换详解

《Java实现时间与字符串互相转换详解》这篇文章主要为大家详细介绍了Java中实现时间与字符串互相转换的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、日期格式化为字符串(一)使用预定义格式(二)自定义格式二、字符串解析为日期(一)解析ISO格式字符串(二)解析自定义

springboot security快速使用示例详解

《springbootsecurity快速使用示例详解》:本文主要介绍springbootsecurity快速使用示例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝... 目录创www.chinasem.cn建spring boot项目生成脚手架配置依赖接口示例代码项目结构启用s

Python中随机休眠技术原理与应用详解

《Python中随机休眠技术原理与应用详解》在编程中,让程序暂停执行特定时间是常见需求,当需要引入不确定性时,随机休眠就成为关键技巧,下面我们就来看看Python中随机休眠技术的具体实现与应用吧... 目录引言一、实现原理与基础方法1.1 核心函数解析1.2 基础实现模板1.3 整数版实现二、典型应用场景2

一文详解SpringBoot响应压缩功能的配置与优化

《一文详解SpringBoot响应压缩功能的配置与优化》SpringBoot的响应压缩功能基于智能协商机制,需同时满足很多条件,本文主要为大家详细介绍了SpringBoot响应压缩功能的配置与优化,需... 目录一、核心工作机制1.1 自动协商触发条件1.2 压缩处理流程二、配置方案详解2.1 基础YAML

Python实现无痛修改第三方库源码的方法详解

《Python实现无痛修改第三方库源码的方法详解》很多时候,我们下载的第三方库是不会有需求不满足的情况,但也有极少的情况,第三方库没有兼顾到需求,本文将介绍几个修改源码的操作,大家可以根据需求进行选择... 目录需求不符合模拟示例 1. 修改源文件2. 继承修改3. 猴子补丁4. 追踪局部变量需求不符合很

java中反射(Reflection)机制举例详解

《java中反射(Reflection)机制举例详解》Java中的反射机制是指Java程序在运行期间可以获取到一个对象的全部信息,:本文主要介绍java中反射(Reflection)机制的相关资料... 目录一、什么是反射?二、反射的用途三、获取Class对象四、Class类型的对象使用场景1五、Class