H264视频码流结构分析

目录

前言

H264码流结构

H264帧结构

H264档次介绍

RTSP实时音视频开发实战课程:<RTSP实时音视频开发实战>

《YUV编码为H264视频流代码实现》链接:

https://edu.csdn.net/learn/38258/606133?spm=1003.2001.3001.4157

《H264视频流解码为YUV代码实现》链接:

https://edu.csdn.net/learn/38258/606144?spm=1003.2001.3001.4157

前言

       在音视频开发入门基础知识(视频入门篇)中已经介绍了视频开发技术的基本的过程,其中就对H264编码做了简单的介绍;本文会对H264编码后的视频流做一个详细的介绍。

H264码流结构

      通常一个H264码流中包含了多个GOP(图像组),每一个GOP里面包含多个视频编码帧,如下图所示。GOP(Group of Pictures)图像组的意思。H264码流对GOP的划分是两个邻近关键帧(IDR帧)之间的图像为一个GOP,包含前面的IDR帧,不包含后面的IDR帧,包含第一个IDR帧后面的所有P帧和B帧;如下图GOP图像包含了5个图像编码帧,一个IDR帧和两个P帧,两个B帧。GOP又分为开放(open)GOP和闭合(close)GOP;open GOP是指当前GOP中的P帧和B帧能将前一个GOP的图像作为参考帧,并且open gop中不存在IDR帧,会有I帧(下面会介绍),假设下图是open GOP的情况,序号为6的P帧能参考序号为0的IDR帧(此时应该叫I帧)或者序号为6的P帧参考序号为1和4的P帧。close GOP是指当前GOP中的P帧和B帧不能将前一个GOP的图像作为参考帧,若下图是close GOP的情况序号为6的P帧不能参考序号为0的IDR帧,也不能参考序号为1和4的P帧,他只能参考序号为5的IDR帧。

084f679f700a4c6a9639014c7e7fab96.png

      一个GOP包含了一个IDR帧和多个P帧或B帧。这里在介绍下H264的编码帧类型;

IDR帧:Instantaneous Decoding Refresh,即时解码刷新帧;也叫关键帧 。同时IDR帧也是I帧(帧内编码帧);IDR帧编码上采用帧内编码技术,即IDR帧的编码和解码不需要参考其他视频帧,只对图像做空间上冗余的压缩编码;解码过程遇到IDR帧会重新解析计算解码参数,并清空之前的解码信息,可以防止前面GOP内的错误延续到当前GOP。

I帧:帧内(Intraframe)压缩编码帧;帧内压缩过程,主要是通过空间上邻近像素相似的特点来解决空间冗余(当前编码块/像素和周围块/像素存在相似或者相同就是空间冗余)的一个编码方法,比如常见的jpeg图像就是通过帧内编码压缩的图像。I帧不一定是IDR帧(关键帧),IDR帧一定是I帧/关键帧;I帧解码不会像P帧B帧那样需要依赖前面或者后面视频帧图像,所以I帧可以单独一帧来解码;I帧和IDR帧最大的区别在于解码过程是否会清空之前的解码信息(IDR帧会清空之前的解码信息,I帧则不会)。

P帧:前向参考编码帧,通常采用帧间和帧内混合的编码方式。通常当前视频图像和前一帧视频图像有着相似和差异的内容,去除相似的内容,保留差异的值进行编码,就可以消除图像时间上的冗余;解码需要依赖参考帧,等参考帧解码完成后才能解码P帧。

B帧:双向参考编码帧,就是需要参考前面一帧图像也需要参考后面的一帧的图像;和P帧类似,B帧通常也采用帧间和帧内混合的编码方式;不同的地方是P帧是和前一帧的差异做编码,B帧不仅仅和前一帧差异做编码,也和后面一帧的差异进行编码;B帧解码需要依赖前后的参考帧,等前后参考帧解码全部完成后才能解码B帧。

      P帧和B帧在编码的过程也可以采用帧内编码的模式,B帧和P帧主要靠帧间编码来提示压缩率的。下图2-1是一个I帧/IDR帧的信息,下面中画面中需要的橙色方块就是I帧/IDR帧采用帧内编码的数据块。下图2-2是P帧的信息,图2-2中方块的颜色大多是蓝色,这表示这些数据采用帧间编码;另外有小部分是橙色方块这些块采用帧内编码。

2b4a2d0605da400c93d54c4b2cf2e339.png

 图 2-1

2bf2307eade44cfd91807d278ba8151b.png

 图 2-2

H264帧结构

      我们知道H264视频码流是由若干个GOP组成,而GOP由一个I帧和多个P帧/B帧组成。那么I帧和P帧/B帧的构成是什么样子的呢?H264在功能上分为两层:NAL 层,和VLC层。

      NAL层:NetworkAbstraction Layer,网络提取层;再将VLC层数据进行存储或者传输前需要将这些VLC数据映射或者封装到NAL单元中。

      VLC层:VideoCoding Layer,视频编码层;视频图像编码后输出的数据,他表示被压缩后的视频序列。

       在一帧编码图像中存在一个或多个NAL Unit(Nal 单元);NAL单元包含NAL Unit Header(Nal 单元头)和NAL Unit Body(Nal 单元主体数据);NAL Unit Header由起始码和Nal Type组成。NAL Unit Body通常是RBSP(Raw Byte Sequence Payload 原始字节序列载荷)数据 ,即编码后的比特流数据。              

       Nal Unit 起始码通常是十六进制数0x000001或者0x00000001;在解析Nal Unit的时候首先要找到起始码,根据起始码的位置来判断一个NalUnit的开始或者结束。NalUnit根据类型可以分为 SPS、PPS、I Slice、P slice、B slice等;

      SPS:Sequence Paramater Set 序列参数集;主要记录了编码视频的的 Profilelevel、图像宽高等。

      PPS:Picture Paramater Set 图像参数集 ;主要记录编码数据所依赖的参数,如参考帧,图像序列计算方法等。

     Islice/Pslice/Bslice:编码帧片数据;在编码I帧、P帧或者B帧的时候会将待编码的图像分成一个或多个Slice(片),对每个Slice单独编码生成Slice编码数据;在多线程的时候多个Slice可以并行编码提高编码速度。

      SPS和PPS记录的数据是GOP里面图像的信息或者单个图像的信息,这些信息都是公共的部分,比如一个GOP的图像分辨率都是一样的;所以通常SPS和PPS Nal Unit数据放在GOP的IDR帧前面或者I帧前面,通常说PPS和SPS在IDR/I帧里面。

       如何区分Nal Unit里面数据类型呢?通过Nal Type来判断当前Nal Unit的类型;Nal Unit 定义如下;根据nal_unit_type字段来解析Nal Unit的类型。下图可以看出nal_unit_type在码流前8个bit中,具体在前8个比特的高5bit的位置,nal_unit_type的取值计算为(data[0] &0x1f)。 

d21202dc4c5e423e8f022aeb665e81d3.png

         nal_unit_type字段定义如下;如下图可以知道 nal_unit_type为7时候 Nal Unit是SPS;nal_unit_type为8时候 Nal Unit是PPS;nal_unit_type为5时候 Nal Unit是IDR Slice;nal_unit_type为1时候 Nal Unit是非IDR Slice;nal_unit_type为9时候 Nal Unit是SEI(视频增强信息)。

bf0352dc3c0c47b9a08a9ad7e7976cbd.png

        对于非IDR 的Slice我们可以进一步解析slice_header()中的slice_type;slice_header()定义如下图。

下图是slice_type的定义。

     下图是码流分析工具StreamAnalyzer展现出的SPS Nal Unit的bit构成,如下蓝色区域数字,起始码为00000001 ,起始码后面的67为十六进制数,取高5bit得到nal_unit_type值是7。7862078d421e450da42ad62cd470743d.png

     下图是码流分析工具StreamAnalyzer展现出的PPS Nal Unit的bit构成,如下蓝色区域数字,起始码为00000001 ,起始码后面的68为十六进制数,取高5bit得到nal_unit_type值是8。

48a2a342f9004f7f8cd039aad323a4c2.png

      下图是码流分析工具StreamAnalyzer展现出的I slice Nal Unit的bit构成,如下蓝色区域数字,起始码为00000001 ,起始码后面的65为十六进制数,取高5bit得到nal_unit_type值是5。

3407db5e2f1c42b4b3af91490d186160.png      下图是码流分析工具StreamAnalyzer展现出的P slice Nal Unit的bit构成,如下蓝色区域数字,起始码为00000001 ,起始码后面的61为十六进制数,取高5bit得到nal_unit_type值是1。

c34c3c1308784a43b8d97d69626ef61c.png

H264档次介绍

H264基本部分规定了三种档次,具体如下:

基本档次(Baseline Profile):只支持I帧和P帧;支持利用基于上下文自适应的变长编码进行的熵编码(CAVLC)。

主要档次(Main Profile):支持隔行视频;支持B帧编码以及加权预测帧间编码;支持利用基于上下文自适应的算术编码(CABAC)。

扩展层次 (Extend Profile):支持码流间的有效切换、改进误码性能,不支持隔行扫描和CABAC。 

      在新修订的H264规范中,增加了High、High10、High422、High444档次。H264的各个档次所支持的功能如下表所示。水平是H264新规范中支持的Profile,垂直是H264的编解码功能;Yes表示支持,No表示不支持。

245fd4748f914265b343973b376ca8bb.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值