多媒体封装格式学习:H264封装成FLV(二)

之前也看过很多人写的博客或者是技术贴,基本上都忽略了一些问题,也就是一个Tag中应该封装H264码流文件中多少码流呢,是一个Nalu单元还是几个?经过多次的研究和试验,我发现大部分的Tag中可以只存放一个Nalu单元,但是此Nalu单元必须是完整的一帧,那问题就来了:1、SPS, PPS, SEI在H264码流中都会占用一个Nalu单元,他们是否要单独的使用一个Tag来存放;2、当某些Nalu单元中的Nalu_type = slice的时候,该怎么处理?OK,这些问题先放着,留在后面纠结。

上面刚刚说过,ScriptTag结束了,然后接下来肯定是一个四字节的previous data size来表示ScriptTag的所占字节。那么接下来呢?是不是就应该直接将H264中的码流按照一定的格式进行封装呢?还不行,我们还需要有一个VideoTag来专门说明一下SPS , PPS, SEI等信息。直接看结构:

typedef struct VideoTagDate
{
  unsigned char FrameCodecType;//高4位,表示帧类型,低4位,表示编码类型
  unsigned char AVPacketType;//0 = AVC sequence header.....1 = AVC NALU.....2 = AVC end of sequence (lower level NALU 
  unsigned char CompositionTime[3];//默认为0
  unsigned char DataLenth[4];//data长度+前面的9字节,注意,ScriptTag后的第一个Tag没有此字段
  unsigned char *Data;
}VideoTagDate;

如上结构的第一个字节FrameCodecType表示此Tag的帧类型和编码类型,高四位代表着此Tag的帧类型,比如说当高四位为0001(二进制的)的时候,代表此Tag是关键帧,当高四位为0002的时候,代表此Tag为帧间的。此字段的第四位代表着此Tag采用的编码方式,比如说0007代表的就是此Tag采用的是H264编码标准。下一个字段AVPacketType则代表着此Tag内所包含的内容的类型,当AVPacketType = 0x00的时候,说明此Tag中包含的是头信息,为0x01的时候是关键帧,为0x02的时候是P帧或者B帧,在这里有两点值得注意一下:AVPacketType = 0x00,只有在ScriptData之后的第一个Tag内才会出现,其他时候不会出现,第二点就是,当AVPacketType为0x01的时候,此Tag会包含4个Nalu单元,分别是SPS , PPS, SEI,和IDR帧。后面几个字段就不多解释了。那么回到此Tag,这事ScriptTag下的第一个Tag,它大概可以这样表示:

首先是TagHeader,   TagType:0x09 DataSize 0x00 00 1D TS: 0x00 0000 TsEx 0x00 StreamID 0x00 00 00

接着就是VideoTagData,  FrameCodecType:0x17 AVPacketType:0x00CompositionTime:0x00 00 00 

大家有没有发现VideoTagData的Data和Datalenth字段没有写出来?因为此Tag是没有Datalenth字段的,这点大家注意,除了此Tag外,其他的Tag都有这个字段。因为此Tag的data字段是固定的,大家可以去查一下AVCDecoderConfigurationRecord的内容,这里跟那里是一样的。

下面就是真正的将H264的码流给封装到Tag中去了,注意了每个Tag必须要至少含有一个完整帧,否则会出问题的~~~,如果一个Nalu中包含一个完整的帧,这种的很好封装起来,就是讲H264码流中此Nalu的头0x00 00 00 01或者0x00 00 01去掉,然后放到Data字段中去就OK了。但是当一个Tag中需要包含多个Nalu头呢?那么此Tag应该这样写:

TagHeader我就不再多写了,都是一样的结构,这里主要注重VideoTagData的内容,就以H264码流开头部分为例吧,H264开头部分有SPS,PPS,SEI信息,他们都是单独的在一个Nalu单元中的,但是他们肯定不是一个完整帧,所以他们要和IDR帧写在一个Tag内,构成一个完整的帧:

FrameCodecType:0x17AVPacketType:0x01 CompositionTime:0x00 00 00

Lenth (sps的长度):0x00 0000 19 Data:码流中sps的内容

Lenth (pps的长度):0x00 0000 05 Data: 码流中pps的内容

Lenth (sei的长度):0x00 0002 A7 Data:码流中sei的内容

Lenth (idr的长度):0x00 00AC B1 Data:码流中Idr帧的内容

 

到这里,基本的FLV封装内容就已经差不多了,具体的一些细节还有待弄清楚,如果有什么错误的地方,还希望广大朋友批评指正。。。。thanks

 


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值