欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

FLV---flv封装格式

程序员文章站 2022-03-21 07:50:12
...

FLV文件 = File Header + File Body(Tag + Tag + Tag …)
FLV---flv封装格式
FLV---flv封装格式
FLV---flv封装格式

1、FLVtag有三类:视频/音频/脚本tag

typedef struct {
    UB[2] Reserved;
    UB[1] Filter;
    UB[5] TagType;
    UI24 DataSize;
    UI24 Timestamp;	//DTS 音频的pts=dts 视频有b帧时PTS = DTS + CTS(CompositionTime )
    UI8 TimestampExtended;
    UI24 StreamID;
    
IF TagType == 8
    AudioTag_Header + AudioTag_DATA;
IF TagType == 9
    VideoTag_Header + VideoTag_DATA;
IF TagType == 18
    SCRIPTDATA Data;
}FLVTAG;

1.1 Script Tag Data结构(控制帧)

又称Metadata Tag,会放若干关于FLV视频和音频的元数据信息如:duration、width、height等。通常该类型Tag会跟在File Header后面作为第一个Tag出现,而且只有一个。
FLV---flv封装格式
FLV---flv封装格式

					AMF1("onMetaData")	AMF2("width,heighr...")

第一个AMF包:

第1个字节表示AMF包类型,一般总是0x02,表示字符串。
第2-3个字节为UI16类型值,标识字符串的长度,一般总是0x000A(“onMetaData”长度)。
后面字节为具体的字符串,一般总为“onMetaData” (6F,6E,4D,65,74,61,44,61,74,61)。

第二个AMF包:

第1个字节表示AMF包类型,总是0x08,表示数组。
第2-5个字节为UI32类型值,表示数组元素的个数。
后面跟着就是数组的元素,格式为:元素名长度(UI16) + 元素名(UI8[n]+ 元素值类型 + 元素的值(double),最后以“009”结尾。
常见的数组元素如表7所示。????

表7.常见MetaData
值				含义
duration		时长
width			视频宽度
height			视频高度
videodatarate	视频码率
framerate		视频帧率
videocodecid	视频编码方式
audiosamplerate	音频采样率
audiosamplesize	音频采样精度
stereo			是否为立体声
audiocodecid	音频编码方式
filesize		文件大小

FLV---flv封装格式
其中有两个编解码器id,一个是audiocodecid 对应Audio Tag Data中的4bit音频编码类型(如10对应AAC)
FLV---flv封装格式
还有一个是videocodecid 对Video Tag Data中的4bit视频编码类型(如7对应AVC)
FLV---flv封装格式

1.2 视频tag

VideoTag
{
	VideoTag_header
	{
		UB[2] Reserved;
	    UB[1] Filter;
	    UB[5] TagType;
	    UI24 DataSize;
	    UI24 Timestamp;			//DTS   注:音频的pts=dts 而视频有b帧时PTS = DTS + CTS(CompositionTime )
	    UI8 TimestampExtended;
	    UI24 StreamID;
	}
	VideoTag_Data
	{
		视频参数		1字节
		{
			FrameType	帧类型		4bit
			CodecId		编码类型		4bit
		}
		视频数据:如AVCVIDEOPACKET
	}
}

FLV---flv封装格式

1.2.1 AVCVIDEOPACKET及内部结构

对于H.264数据来说,CodecID = 7。
当nalu_type=H264_IDR则为1.(关键帧),反之则为2.intet frame(非I帧吧?)

当CodecID = 7时,视频数据就是AVCVIDEOPACKET格式。
下面讲解一下AVCVIDEOPACKET。
FLV---flv封装格式

AVCPacketType = 0(存放nalu配置参数)????AVCDecoderConfigurationRecord:

FLV---flv封装格式

AVCPacketType = 0(存放nalu数据)????Data:
Data:
{
	Nalu Len(UI32)
	Nalu Data(UI8[n])
	Nalu Len(UI32)
	Nalu Data(UI8[n])
	...
}

当视频编码类型是AVC时,视频数据内容可以参考AVCVIDEOPACKET ★★pts?dts?cts?★★FLV封装格式详解
FLV---flv封装格式
关于CTS

1.3 音频tag

1.3.1 audio_tag_header

typedef struct {
    UB [4] SoundFormat;
    UB [2] SoundRate;
    UB [1] SoundSize;
    UB [1] SoundType;
  IF SoundFormat == 10
    UI8 AACPacketType;
}


soundFormat	UB [4]	声音格式:	0 = Linear PCM, platform endian
								1 = ADPCM
								2 = MP3
								3 = Linear PCM, little endian
								4 = Nellymoser 16-kHz mono
								5 = Nellymoser 8-kHz mono
								6 = Nellymoser
								7 = G.711 A-law logarithmic PCM
								8 = G.711 mu-law logarithmic PCM 9 = reserved
								10 = AAC
								11 = Speex
								14 = MP3 8-Khz
								15 = Device-specific sound

SoundRate	UB [2]	采样率:	//在AAC中总为3
								0 = 5.5 kHz
								1 = 11 kHz
								2 = 22 kHz
								3 = 44 kHz
							//FLV封装格式并不支持48KHz的采样率。
SoundSize	UB [1]	采样位深(精度)。此参数仅适用未压缩格式,压缩格式总在内部被解码为16位。
								0 = 81 = 16位

SoundType	UB [1]				0 = 单声道sndMono
								1 = 立体声sndStereo
								
IF SoundFormat == 10(声音格式为AAC)
 AACPacketType	UI8	AAC帧类型。仅当声音格式为 10 时,存在此字段
									0 = AAC sequence header
									1 = AAC raw

实例:将SPS与PPS封装在一个VideoTag中:

例如:将SPS与PPS封装在一个Tag中:

Tag Header:
	TagType:09(Tag的类型,包括音频(0x08)、视频(0x09)、script data(0x12))
	Datasize:00 00 2e(Tag Data 部分的大小)
	Timestamp:00 00 00(时间戳,19ms)
	Timestamp_ex:00(时间戳的扩展部分)
	StreamID:00 00 00(总是0)

Tag data:// = 视频参数(此处为12)+视频数据(此处为AVCVideoPaket)
	FrameType | CodecID:17(keyframe | AVC)(视频tag的参数)

AVCVideoPaket:(因为CodecID==7,所以VideoData为AVCVideoPaket)
	AVCPaketType:00(ACVPacket的类型,0: AVC sequence header;1: AVC NALU;2: AVC end of sequence)
	CompositionTime:00 00 00
//因为ACVPaketType==0,所以Data=AVCDecoderConfigurationRecord

AVCDecoderConfigurationRecord:
	configurationVersion:01	//直接填1?
	AVCProfileIndication:64   	//源自sps.date[1]
	profile_compatibility:00	//源自sps.date[2]
	AVCLevelIndication:1e		//源自sps.date[3]
	lengthSi*usOne:ff (NALUSize的长度,计算方法为:1 + (lengthSi*usOne & 3)=4// 6 bits reserved (111111) + 2 bits nal size length - 1
	// (Reserved << 2) | Nal_Size_length = (0x3F << 2) | 0x03 = 0xFF
	numOfSequenceParameterSets:e1(低五位为SPS的个数,计算方法为:numOfSequenceParameterSets & 0x1F=1// 3 bits reserved (111) + 5 bits number of sps (00001)
	// (Reserved << 5) | Number_of_SPS = (0x07 << 5) | 0x01 = 0xe1
	sequenceParameterSetLength:00 18(SPS的长度,24)
	sequenceParameterSetNALUnits:67 64 00 1e ac d9 40 a0 33 b0 11 00 00 03 02 47 00 00 6d 34 0f 16 2d 96(SPS数据)
	numOfPictureParameterSets:01(PPS的个数)
	pictureParameterSetLength:00 06(PPS的长度)
	pictureParameterSetNALUnits:68 eb e3 cb 22 c0(PPS数据)
	previousTagSize:00 00 00 39


previousTagSize:00 00 00 39
相关标签: flv