怎么区分H.264视频流的I frame 和 P frame?

我是新手,前些天自己看那H.264规范文档及其他资料寻找答案时,
还有几个概念的关系还没能理解清楚,望达人指点一二:

NAL、Slice与frame意思及相互关系

NAL nal_unit_type中的1(非IDR图像的编码条带)、2(编码条带数据分割块A)、3(编码条带数据分割块B)、4(编码条带数据分割块C)、5(IDR图像的编码条带)种类型与Slice种的三种编码模式:I_slice、P_slice、B_slice 还有frame的3种类型:I frame、P frame、 B frame之间有什么映射关系么?

最后,NAL nal_unit_type中的6(SEI)、7(SPS)、8(PPS)属于什么帧呢?


1 frame的数据可以分为多个slice.
每个slice中的数据,在帧内预测只用到自己slice的数据, 与其他slice 数据没有依赖关系。
NAL 是用来将编码的数据进行大包的。 比如,每一个slice 数据可以放在NAL 包中。
I frame 是自己独立编码,不依赖于其他frame 数据。
P frame 依赖 I frame 数据。
B frame 依赖 I frame, P frame 或其他 B frame 数据。


那NAL nal_unit_type中的哪几种类型是I frame,现在只能确定nal_unit_type==5(IDR图像的编码条带)是I frame

sps、pps、SEI算不算I frame呢? 还有 属于编码条带分割的DPA、DPB、DPC呢?
能给个从视频流中提取I frame 和P frame的方法么?


一个frame是可以分割成多个Slice来编码的,而一个Slice编码之后被打包进一个NAL单元,不过NAL单元除了容纳Slice编码的码流外,还可以容纳其他数据,比如序列参数集SPS


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// H.264 NAL type
enum H264NALTYPE{
H264NT_NAL = 0,
H264NT_SLICE,
H264NT_SLICE_DPA,
H264NT_SLICE_DPB,
H264NT_SLICE_DPC,
H264NT_SLICE_IDR,
H264NT_SEI,
H264NT_SPS,
H264NT_PPS,
};
int H264GetNALType(LPVOID pBSBuf, const LONG nBSLen)
{
if ( nBSLen < 5 ) // 不完整的NAL单元
return H264NT_NAL;

UINT8* pBS = (UINT8 *)pBSBuf;
ULONG nType = pBS[4] & 0x1F; // NAL类型在固定的位置上 :)
if ( nType <= H264NT_PPS )
return nType;

return 0;
}

其中 H264NT_SLICE_IDR 是关键帧,H264NT_SLICE 是P帧


一个frame是可以分割成多个Slice来编码的,而一个Slice编码之后被打包进一个NAL单元,不过NAL单元除了容纳Slice编码的码流外,还可以容纳其他数据,比如序列参数集SPS。


  • 1、NAL、Slice与frame意思及相互关系

NAL指网络提取层,里面放一些与网络相关的信息
Slice是片的意思,264中把图像分成一帧(frame)或两场(field),而帧又可以分成一个或几个片(Slilce);片由宏块(MB)组成。宏块是编码处理的基本单元。

  • 2、NAL nal_unit_type中的1(非IDR图像的编码条带)、2(编码条带数据分割块A)、3(编码条带数据分割块B)、4(编码条带数据分割块C)、5(IDR图像的编码条带)种类型
    与 Slice种的三种编码模式:I_slice、P_slice、B_slice
    NAL nal_unit_type 里的五种类型

代表接下来数据是表示啥信息的和具体如何分块。
I_slice、P_slice、B_slice 表示I类型的片、P类型的片,B类型的片.其中I_slice为帧内预测模式编码;P_slice为单向预测编码或帧内模式;B_slice 中为双向预测或帧内模式。

  • 3、还有frame的3种类型:I frame、P frame、 B frame之间有什么映射关系么?

I frame、P frame、 B frame关系同 I_slice、P_slice、B_slice,slice和frame区别在问题1中已经讲明白。

  • 4、最后,NAL nal_unit_type中的6(SEI)、7(SPS)、8(PPS)属于什么帧呢?

NAL nal_unit_type 为序列参数集(SPS)、图像参数集(PPS)、增强信息(SEI)不属于啥帧的概念。表示后面的数据信息为序列参数集(SPS)、图像参数集(PPS)、增强信息(SEI)。

h.264解码中首先过滤码流获得参数集,参数集是H.264标准的一个新概念,是一种通过改进视频码流结构增强错误恢复能力的方法。

众所周知,一 些关键信息比特的丢失(如序列和图像的头信息)会造成解码的严重负面效应,而H.264把这些关键信息分离出来,凭借参数集的设计,确保在易出错的环境中 能正确地传输。这种码流结构的设计无疑增强了码流传输的错误恢复能力。

H.264的参数集又分为序列参数集(Sequence parameter set)和图像参数集(Picture parameter set)。其中,序列参数集包括一个图像序列的所有信息,即两个IDR图像间的所有图像信息。图像参数集包括一个图像的所有分片的所有相关信息,包括图像 类型、序列号等,解码时某些序列号的丢失可用来检验信息包的丢失与否。多个不同的序列和图像参数集存储在解码器中,编码器依据每个编码分片的头部的存储位置来选择适当的参数集,图像参数集本身也包括使用的序列参数集参考信息。

参数集具体实现的方法也是多样化的:
(1)通过带外传输,这种方式要求参数集通过可靠的协议,在首个片编码到达之前传输到解码器;
(2)通过带内传 输,这需要为参数集提供更高级别的保护,例如发送复制包来保证至少有一个到达目标;
(3)在编码器和解码器采用硬件处理参数集。

序列参数集以及图像参数集要在解码前传输,在解码的过程中被激活。一旦被激活,则上一个序列参数集或者图象参数集就失效了。图象参数集是被使用它的 slice data或者使用它的A分割的Nalu激活的。而序列参数集是被使用它的图象参数集或者包括缓冲期消息的SEI nalu所激活。

同一个IDR图象的序列参数集有相同的seq_parameter_set_id,直到一个图象的最后一个access unit或者包括缓冲期消息的SEI Nalu,这时需要出现下一个图象的序列参数集。
下一个图象的序列参数集被SEI nalu激活。如果序列参数集和图象参数集是通过其他传输管道发送的,则要保证以上的传输顺序。


H.264视频流是以NAL单元传送的。。。但在一个NAL单元里面,可能既存放I-Slice(P-Slice或B-Slice),同时也可能存放图像的其他信息
那么 是不是说 I frame, P frame,B frame是把收到的NAL单元中的VCL的信息先提取出,然后按内容进行I、P、B frame分类?

而我们只能通过NAL nal_unit_type来判别NAL单元中数据的类型哈~~~


呵呵 不好意思 还没有完全理解~~


NAL单元中首先会有一个H.264 NAL type,根据这个可以判断是啥信息。如果是
H264NT_SLICE_DPA,H264NT_SLICE_DPB,H264NT_SLICE_DPC, H264NT_SLICE_IDR视频数据相关的,里面还会有Slice head头信息,根据这个头信息,可以判断属于I-Slice(P-Slice或B-Slice),之后对于每个宏块,都会有MB head 信息,根据宏块头信息可以判断块模式。

H264就是这样以分层的方式组织信息的。不知道你理解没有。