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

编程入门 行业动态 更新时间:2024-10-24 10:27:15

<a href=https://www.elefans.com/category/jswz/34/1768490.html style=多媒体封装格式学习:H264封装成FLV(一)"/>

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

         搞了好几天的FLV封装,话说封装真是个苦力活,有时候思路不是很清晰的时候,真心有点乱。

         网上关于H264封装成FLV的文档,都分析的很详细了,但是有几个点没有考虑到,一会在下面我会一一跟大家说明。图什么的我就不画了,网上一搜应该有很多,那先看下面一个结构体吧。

typedef struct FLVHeader
{unsigned char First;// "F"unsigned char Second;//"L"unsigned char Last;//"V"unsigned char Version; //0x01unsigned char Flags;//"前五位保留且为0,第六位表示是否存在音频Tag,第七位保留为0,第八位表示是否有视频Tag"unsigned char HeaderLenth[4];//header 长度,一共9bytes
}FLVHeader;

了解过FLV的朋友都应该知道FLV是由FLVHeader和FLVBody两大部分构成的,而FLVBody又可以划分成N个更小的单元:Tag。我们先从简单的看起,上述代码是一个FLVHeader的结构体,其前三个字节分别是F,L,V 第四个字节是Version也就是FLV的版本号,当前为1。第五个字节是一个标志位Flags,代表当前FLV是否包含音频或者视频Tag,此Flags的第六位代表是否含有音频Tag,第八位表示是否含有视频Tag,其他位为0;举个例子,当Flag = 0X01的时候,代表只包含视频Tag,等于0X04的时候代表只含有音频Tag,当Flag等于0X05时,就代表此FLV既包含音频Tag,也包含视频Tag。最后有一个四字节的HeaderLenth,代表着当前Header的长度。大家有没有注意到,我用char[4]来表示这个四字节的变量,而没有用unsigned int类型吗?是有一定道理的,大家可以自己去尝试一下。

下面具体介绍一下FLVBody部分。FLVBody由多个previousdata size + Tag构成,其中Tag的类型多种多样,由于我对音频部分不是很熟悉,我这里就不讨论音频Tag了。而previous data size 用四个字节代表上一个Tag所占字节数,但是FLVBody和第一个Tag之间的previous data size为0.

那么一个Tag是由哪几个部分组成的呢?如果简单分开来:Tag = TagHeader + TagData,如下结构体说明了TagHeader的结构:

typedef struct TagHeader
{unsigned char TagType;//tag类型,音频为(0X08),视频(0X09),script data(0x12),其他值保留unsigned char DataSize[3];//3字节表示Tagdata的大小unsigned char Ts[3]      ;     //3字节,为Tag的时间戳,  unsigned char TsEx     ;//时间戳的拓展位,当24位不够用时,此八位作为时间戳最高位,将时间戳变为32位unsigned char StreamID[3];//一直为0;
}TagHeader;

Tagheader的第一个字节为TagType,此字节意在说明此Tag的类型,如果是音频,TagType=0X08,视频的话,TagType = 0X09;如果是Script data的话,TagType = 0X12;其他值保留。第2-4字节为DataSize,表示TagHeader后面接着的TagData的数据大小。Ts和TsEx结构地内注释已经很清楚了,就不重复了。StreamID恒定为0.

         对于一个Tag来说,TagHeader的结构都是一样的,而TagData的结构就很复杂了,首先,针对不同的TagType,对应的TagData肯定不一样,分为AudioTagData,VideoTagData,ScriptTagData。AudioTagData在本文中不做分析,因为这并不会影响H264码流的封装。

         当我们向一个FLV文件中写入FLVHeader后,紧接着的肯定是4个字节的previousdata size,且为0。那下一步,我们应该来写我们的Tag了,但是第一个是什么Tag呢,是AudioTag,VideoTag,还是ScriptTag呢。我们第一个应该写入的Tag是ScriptTag,那我们看一下它的结构是如何的:


ypedef struct ScriptTagData
{unsigned char MetaDataType;//0x02unsigned char StringLenth[2];//一般位10,即0x000A;unsigned char MetaString[10];//值为onMetaDatunsigned char InfoDataType;//0x08表示数组,也就是第二个AMF包unsigned char EnumNum[4];//4bytes有多少个元素//18bytes//1unsigned char DurationLenth[2];//2bytes,duration的长度unsigned char DurationName[8];unsigned char DurationType;unsigned char DurationData[8];//2unsigned char WidthLenth[2];//unsigned char WidthName[5];unsigned char WidthType;unsigned char WidthData[8];//3unsigned char HeightLenth[2];unsigned char HeightName[6];unsigned char HeightType;unsigned char HeightData[8];//4unsigned char FrameRateLenth[2];unsigned char FrameRateName[9];unsigned char FrameRateType;unsigned char FrameRateData[8];//5unsigned char FileSizeLenth[2];unsigned char FileSizeName[8];unsigned char FileSizeType;unsigned char FileSizeData[8];unsigned char End[3];//0x000009
}ScriptTagData;

上面的结构是ScriptTag的TagData,ScriptTag的TagHeader按之前的结构来写。ScriptTagData中的MetaDataType,StringLenth,MetaString,InfoDataType都是恒定不变的固定值,注释里都有他们的值,在这里就不多做解释了。接下来就是EnumNum[4]了,它包含4个字节,它代表ScriptTagData中含有多少个字段,上述结构体中我只定义了五个字段:Duration,width,height,framrate和filesize,所以EnumNum[4] = 0x00 00 00 05,当然也可以定义更多的字段,具体得去查看FLV的封装文档。接下来就是定义的字段了,以durantion为例子,DurationLenth[2]代表duration这个字符串的长度8,不包含’\0’所以DurationLenth[2]=0x00 08;  DurationName[8]代表这个字符串”duration”也不包含’\0’。 DurationType代表着duration这个字段所对应的值DurationData的类型,这里DurationType为0,代表DurationData是Double型的,所以在结构体中我将其定义为了unsigned char DurationData[8],为8个字节的unsignedchar 型,与Double所占字节数一样。其他的几个字段也是一样的,就不累述了。最后当字段定义结束后,需要结束符End[3],为0X00 00 09。

既然SciptTag结束了,那么就轮到VideoTag了,这里确实有点恶心。搞过视频的朋友应该都知道不管是H264还是H265都是以Nalu来封装的吧,每条Nalu都是以0X 00 00 01或者0X 00 00 00 01开头的,在这个头之后的1Byte内,包含了此Nalu的Type,在这个字节的低五位中,具体关于Nalu的请去查看H264或者H265的说明。先写到这里了,明儿接着。


对了,有几个不错的链接,这里给大家发一下:

/




更多推荐

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

本文发布于:2024-02-25 02:51:39,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1697542.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:多媒体   格式   FLV

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!