原理
H.264原始码流(又称为“裸流”)是由一个一个的NALU组成的。他们的结构如下图所示。
H.264码流第一个 NALU
是 SPS(序列参数集Sequence Parameter Set)
H.264码流第二个 NALU 是 PPS(图像参数集Picture Parameter Set)
H.264码流第三个 NALU 是 IDR(即时解码器刷新)
I和IDR帧都是使用帧内预测的
。
它们都是同一个东西而已,在编码和解码中为了方便,要首个I帧和其他I帧区别开,所以才把第一个首个I帧叫IDR,这样就方便控制编码和解码流程
其中每个NALU之间通过startcode(起始码)进行分隔,起始码分成两种:0x000001(3Byte)或者0x00000001(4Byte)。如果NALU对应的Slice为一帧的开始就用0x00000001,否则就用0x000001。
int FindStart3(unsigned char *buf)
{
if((buf[0]==0)&&(buf[1]==0)&&(buf[2]==1)) // 0x 00 00 01
return 1;
else
return 0;
}
int FindStart4(unsigned char *buf)
{
if((buf[0]==0)&&(buf[1]==0)&&(buf[2]==0)&&(buf[3]==1)) // 0x 00 00 00 01
return 1;
else
return 0;
}
forbidden_zero_bit 是禁止位,应该是第一位即f(1)=0,1为语法有错误
n->nal_idc = (buf[head_size] & 0x60); // 2 bit
nal_ref_idc是参考级别,代表被其它帧参考情况,u(2)= 11 = 3最(0为无参考,详见规范)
nal_unit_type是该帧的类型,为剩下的5位,u(5)= 0 0111 = 7
n->nal_type = (buf[head_size] & 0x1f)
typedef enum {
NALU_TYPE_SLICE = 1,
NALU_TYPE_DPA = 2,
NALU_TYPE_DPB = 3,
NALU_TYPE_DPC = 4,
NALU_TYPE_IDR = 5,
NALU_TYPE_SEI = 6,
NALU_TYPE_SPS = 7,
NALU_TYPE_PPS = 8,
NALU_TYPE_AUD = 9,
NALU_TYPE_EOSEQ = 10,
NALU_TYPE_EOSTREAM = 11,
NALU_TYPE_FILL = 12,
}