H264 帧结构分析、帧判断

http://blog.csdn.net/dxpqxb/article/details/7631304

H264以NALU(NAL unit)为单位来支持编码数据在基于分组交换技术网络中传输。

NALU定义了可用于基于分组和基于比特流系统的基本格式,同时给出头信息,从而提供了视频编码和外部世界的接口。

H264编码过程中的三种不同的数据形式:

SODB 数据比特串-->最原始的编码数据,即VCL数据;

RBSP 原始字节序列载荷-->在SODB的后面填加了结尾比特(RBSP trailing bits 一个bit“1”)若干比特“0”,以便字节对齐;

EBSP 扩展字节序列载荷-->在RBSP基础上填加了仿校验字节(0X03)它的原因是: 在NALU加到Annexb上时,需要添加每组NALU之前的开始码StartCodePrefix,如果该NALU对应的slice为一帧的开始则用4位字节表示,ox00000001,否则用3位字节表示ox000001(是一帧的一部分)。另外,为了使NALU主体中不包括与开始码相冲突的,在编码时,每遇到两个字节连续为0,就插入一个字节的0x03。解码时将0x03去掉。也称为脱壳操作。

编码处理过程:

1. 将VCL层输出的SODB封装成nal_unit,NALU是一个通用封装格式,可以适用于有序字节流方式和IP包交换方式。

2. 针对不同的传送网络(电路交换|包交换),将nal_unit封装成针对不同网络的封装格式(比如把nalu封装成rtp包)。

---------------------------------------------------

处理过程一,VCL数据封装成NALU

---------------------------------------------------

VCL层输出的比特流SODB(String Of Data Bits),到nal_unit之间,经过了以下三步处理:

1.SODB字节对齐处理后封装成RBSP(Raw Byte Sequence Payload)。

2.为防止RBSP的字节流与有序字节流传送方式下的SCP(start_code_prefix_one_3bytes,0x000001)出现字节竞争情形,循环检测RBSP前三个字节,在出现字节竞争时在第三字节前加入emulation_prevention_three_byte(0x03),具体方法: 

nal_unit( NumBytesInNALunit ) {

forbidden_zero_bit

nal_ref_idc

nal_unit_type

NumBytesInRBSP = 0

for( i = 1; i < NumBytesInNALunit; i++ ) {

if( i + 2 < NumBytesInNALunit && next_bits( 24 ) = = 0x000003 ) {

rbsp_byte[ NumBytesInRBSP++ ]

rbsp_byte[ NumBytesInRBSP++ ]

i += 2

emulation_prevention_three_byte

} else

rbsp_byte[ NumBytesInRBSP++ ]

}

}

3. 防字节竞争处理后的RBSP再加一个字节的header(forbidden_zero_bit+ nal_ref_idc+ nal_unit_type),封装成nal_unit.

------------------------------------------------

处理过程二,NALU的RTP打包

------------------------------------------------

一、NALU打包成RTP的方式有三种:

1. 单一 NAL 单元模式
即一个 RTP 包仅由一个完整的 NALU 组成. 这种情况下 RTP NAL 头类型字段和原始的 H.264的
NALU 头类型字段是一样的.

2. 组合封包模式
即可能是由多个 NAL 单元组成一个 RTP 包. 分别有4种组合方式: STAP-A, STAP-B, MTAP16, MTAP24.
那么这里的类型值分别是 24, 25, 26 以及 27.

3. 分片封包模式
用于把一个 NALU 单元封装成多个 RTP 包. 存在两种类型 FU-A 和 FU-B. 类型值分别是 28 和 29.

还记得前面nal_unit_type的定义吧,0~23是给H264用的,24~31未使用,在rtp打包时,如果一个NALU放在一个RTP包里,可以使用NALU的nal_unit_type,但是当需要把多个NALU打包成一个RTP包,或者需要把一个NALU打包成多个RTP包时,就定义新的type来标识。

Type Packet Type name
---------------------------------------------------------
0 undefined -
1-23 NAL unit Single NAL unit packet per H.264
24 STAP-A Single-time aggregation packet
25 STAP-B Single-time aggregation packet
26 MTAP16 Multi-time aggregation packet
27 MTAP24 Multi-time aggregation packet
28 FU-A Fragmentation unit
29 FU-B Fragmentation unit
30-31 undefined

 

二、三种打包方式的具体格式

1 .单一 NAL 单元模式

对于 NALU 的长度小于 MTU 大小的包, 一般采用单一 NAL 单元模式.
对于一个原始的 H.264 NALU 单元常由 [Start Code] [NALU Header] [NALU Payload] 三部分组成, 其中 Start Code 用于标示这是一个

NALU 单元的开始, 必须是 "00 00 00 01" 或 "00 00 01", NALU 头仅一个字节, 其后都是 NALU 单元内容.
打包时去除 "00 00 01" 或 "00 00 00 01" 的开始码, 把其他数据封包的 RTP 包即可.

0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|F|NRI| type | |
+-+-+-+-+-+-+-+-+ |
| |
| Bytes 2..n of a Single NAL unit |
| |
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| :...OPTIONAL RTP padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

如有一个 H.264 的 NALU 是这样的:

[00 00 00 01 67 42 A0 1E 23 56 0E 2F ... ]

这是一个序列参数集 NAL 单元. [00 00 00 01] 是四个字节的开始码, 67 是 NALU 头, 42 开始的数据是 NALU 内容.

封装成 RTP 包将如下:

[ RTP Header ] [ 67 42 A0 1E 23 56 0E 2F ]

即只要去掉 4 个字节的开始码就可以了.

2 组合封包模式

其次, 当 NALU 的长度特别小时, 可以把几个 NALU 单元封在一个 RTP 包中.

0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| RTP Header |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|STAP-A NAL HDR | NALU 1 Size | NALU 1 HDR |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| NALU 1 Data |
: :
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| | NALU 2 Size | NALU 2 HDR |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| NALU 2 Data |
: :
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| :...OPTIONAL RTP padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

3 Fragmentation Units (FUs).

而当 NALU 的长度超过 MTU 时, 就必须对 NALU 单元进行分片封包. 也称为 Fragmentation Units (FUs).

0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| FU indicator | FU header | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| |
| FU payload |
| |
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| :...OPTIONAL RTP padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figure 14. RTP payload format for FU-A

FU indicator有以下格式:
+---------------+
|0|1|2|3|4|5|6|7|
+-+-+-+-+-+-+-+-+
|F|NRI| Type |
+---------------+
FU指示字节的类型域 Type=28表示FU-A。。NRI域的值必须根据分片NAL单元的NRI域的值设置。

FU header的格式如下:
+---------------+
|0|1|2|3|4|5|6|7|
+-+-+-+-+-+-+-+-+
|S|E|R| Type |
+---------------+
S: 1 bit
当设置成1,开始位指示分片NAL单元的开始。当跟随的FU荷载不是分片NAL单元荷载的开始,开始位设为0。
E: 1 bit
当设置成1, 结束位指示分片NAL单元的结束,即, 荷载的最后字节也是分片NAL单元的最后一个字节。当跟随的FU荷载不是分片NAL单元的最后分片,结束位设置为0。
R: 1 bit
保留位必须设置为0,接收者必须忽略该位。
Type: 5 bits

三、拆包和解包

拆包:当编码器在编码时需要将原有一个NAL按照FU-A进行分片,原有的NAL的单元头与分片后的FU-A的单元头有如下关系:
原始的NAL头的前三位为FU indicator的前三位,原始的NAL头的后五位为FU header的后五位,FU indicator与FU header的剩余位数根据实际情况决定。

解包:当接收端收到FU-A的分片数据,需要将所有的分片包组合还原成原始的NAl包时,FU-A的单元头与还原后的NAL的关系如下:
还原后的NAL头的八位是由FU indicator的前三位加FU header的后五位组成,即:
nal_unit_type = (fu_indicator & 0xe0) | (fu_header & 0x1f)

时间: 2024-09-16 00:36:27

H264 帧结构分析、帧判断的相关文章

ffmpeg编码h264只包含I帧P帧的方法

ffmpeg使用avcodc_encode_video编码,默认产生的h264包含B帧,在安防行业很多地方是不需要用到B帧的.   1.基础知识充电 这就涉及到h264的各种profile格式了,参考 h264各种profile h264分4种等级(profile):Baseline.Main.Extended.High Baseline profile:支持I帧P帧 Main profile:支持I/P/B/SP/SI帧 Extended profile:支持I/P/B帧 High profi

h264 流、帧结构

H264元素的分层结构 H.264编码器输出的Bit流中,每个Bit都隶属于某个句法元素.句法元素被组织成有层次的结构,分别描述各个层次的信息.           在H.264 中,句法元素共被组织成  序列.图像.片.宏块.子宏块五个层次.在这样的结构中,每一层的头部和它的数据部分形成管理与被管理的强依赖关系,头部的句法元素是该层数据的核心,而一旦头部丢失,数据部分的信息几乎不可能再被正确解码出来,尤其在序列层及图像层.         在 H.264 中,分层结构最大的不同是取消了序列层和

视频流中的 I帧 P帧 B帧 .

转自:http://blog.csdn.net/abcjennifer/article/details/6577934 视频压缩中,每帧代表一幅静止的图像.而在实际压缩时,会采取各种算法减少数据的容量,其中IPB就是最常见的. Intra coded frames, Predicted pictures, and Bi-directional predictive pictures. I帧是关键帧,属于帧内压缩.就是和AVI的压缩是一样的. P是向前搜索的意思.B是双向搜索.他们都是基于I帧来压

h264检测是I帧还是P帧,解决录像第一帧有马赛克问题

最近使用h264码流数据进行录像,但是录出来的第一帧有马赛克,究其原因是录像的第一帧不是关键帧,所以需要录像是需要判断第一帧是否是关键帧,方法有两种,第一种是原码流的基础上查找,第二种是将原码流传递给ffmpeg让ffmpeg判断key_frame,第二种相对简单,但是由于这样一来录像和解码视频切合的太紧密,之后修改比较麻烦,所以选择第一种方案,查看注释1可以明白如何检测h264码流的关键帧,下面是我截取原码流的关键帧和p帧   0000000 :是sps 0000000  :  是pps 00

h 264编码 分辨率-帧编码 场编码,分辨率,H264帧头

问题描述 帧编码 场编码,分辨率,H264帧头 大神们,我想问三个问题:第一,视频编码有两种方式(我知道的):帧编码和场编码,帧编码是逐行扫描,场编码是隔行扫描:在图像运动比较剧烈时,最好使用场编码,图像运动相对静止的话,使用帧编码:在进行场编码时会有顶场和底场(上半场和下半场),那么我想问的是,我这样理解对不对?还有这上半场和下半场是作为两帧画面发送给接收端(但是这样我觉得实际的帧率会下降),还是作为一帧给接收端呢?如果是一帧的话,他是怎么处理的,接收端拿到以后,是怎么样进行解码播放的呢? 第

音视频基础 、IPB帧及其特点

基本概念讲解 媒体:是表示,传输,存储信息的载体,常人们见到的文字.声音.图像.图形等都是表示信息的媒体. 多媒体: 是声音.动画.文字.图像和录像等各种媒体的组合,以图文并茂,生动活泼的动态形式表现出来,给人以很强的视觉冲击力,留下深刻印象 多媒体技术:是将文字.声音.图形.静态图像.动态图像与计算集成在一起的技术.它要解决的问题是计算机进一步帮助人类按最自然的和最习惯的方式接受和处理信息. 流媒体 :流媒体是指采用流式传输的方式在Internet播放的连续时基媒体格式,实际指的是一种新的媒体

FLASH WEB制作实例讲解(帧标签的使用)

web 大家都知道,我们在做PS图片处理时,同样一种效果,并非只有一种方法能够实现,好比一道数学题有N种解法,同样,在制作FLASH WEB时,实现效果也不是千篇一律的.今天我们就来学学利用帧标签制作FLASH WEB 先看看这个简单的FLASH WEB: 很简单吧.. 看完演示,想必大家头脑会浮现好多种制作思路,的确..可以简单运用goto语句,可以调用外部swf,AS不错的话还可以全部由AS实现.. 我们今天用帧标签来实现..帧标签:帧标签即为帧添加的名称 因为我们这次教程主要讲的是关于帧标

Fireworks制作图片变换效果逐帧动画

细节性的动画在FW里还是使用逐帧动画调节起来比较细腻,虽然使用动画元件比较快,但是我还是比较喜欢一帧一帧的调,做了几个图片变换过渡的效果: ① 逐帧动画: PNG文件: ② 逐帧+蒙板: PNG文件: ③ 逐帧+不透明度做的图片过渡: PNG文件: ④ 逐帧+灰度蒙板做的图片过渡: PNG文件:

Fireworks逐帧动画效果及实例剖析

细节性的动画在FW里还是使用逐帧动画调节起来比较细腻,虽然使用动画元件比较快,但是我还是比较喜欢一帧一帧的调,做了几个图片变换过渡的效果: ① 逐帧动画: PNG文件: ② 逐帧+蒙板: PNG文件: ③ 逐帧+不透明度做的图片过渡: PNG文件: ④ 逐帧+灰度蒙板做的图片过渡: PNG文件: