flv文件格式解析!!!

flv头 FLV header

总体上看,FLV包括文件头(File Header)和文件体(File Body)两部分,其中文件体由一系列的Tag组成。

Signature: FLV 文件的前 3个字节 为固定的‘F’‘L’‘V’,用来标识这个文件是flv格式的.在做格式探测的时候,如果发现前3个字节为“FLV”,就认为它是flv文件.

Version: 第4个字节 表示flv版本号.

Flags: 第5个字节中的第0位和第2位,分别表示 video 与 audio 存在的情况.(1表示存在,0表示不存在)
如果都存在,值为5

DataOffset : 最后 4个字节 表示FLV header 长度.

综上,一共9个字节
unsigned char flvHeaderTag[9] = { 0x46, 0x4C, 0x56, 0x01, 0x05, 0x00, 0x00, 0x00, 0x09};

FLV头后面第一个prevTagSize始终为0

=========== File Body==========

FLV header之后,就是File Body.FLV File Body是由一连串的 PreviousTagSize + tags 构成. PreviousTagSize就是 4个字节 数据大小,表示前一个tag的size.



==========FLV Tag=====
FLV文件中的数据都是由一个个TAG组成,TAG里面的数据可能是video、audio、scripts.
TagType: TAG中第1个字节中的前5位表示这个TAG中包含数据的类型,  8 = audio,9 = video,18 = script data.

DataSize(3个字节) : StreamID之后 数据长度.(length of the tag – 11),其中UI24表示3个字节,11为整个Tag除去Data之外的大小。

Timestamp和TimestampExtended组成了这个TAG包数据的PTS信息,记得刚开始做FLV demux的时候,并没有考虑TimestampExtended的值,直接就把Timestamp默认为是PTS,后来发生的现象就是画面有跳帧的现象,后来才仔细看了一下文档发现真正数据的PTS是 PTS= Timestamp | TimestampExtended<<24.
StreamID之后就是数据 。每种格式都不一样,下面进行详细介绍.

即一直到StreamId一共有11个字节

===========Audio Tag==============
如果TAG包中的TagType==8时,就表示这个TAG是audio。
StreamID之后的数据是 AudioTagHeader ,AudioTagHeader结构如下:
AudioTagHeader的第 1个字节 ,也就是紧跟着StreamID的1个字节包含着音频类型、采样率等基本信息.上述表里列的十分清楚. AudioTagHeader之后跟着的就是AUDIODATA数据了 ,也就是audio payload 但是这里有个特例,如果音频格式(SoundFormat)是10 = AAC, AudioTagHeader中会多出1个字节的数据AACPacketType ,这个字段来表示AACAUDIODATA的类型:0 = AAC sequence header,1 = AAC raw。
图片双击可看大图:
  • AAC sequence header也就是包含了AudioSpecificConfig,AudioSpecificConfig包含着一些更加详细的音频信息,AudioSpecificConfig的定义在ISO14496-3中1.6.2.1 AudioSpecificConfig。
在ffmpeg中有对AudioSpecificConfig解析的函数,ff_mpeg4audio_get_config()(我的ffmpeg版本中是avpriv_mpeg4audio_get_config())。
  • AAC raw 这种包含的就是音频ES流了,也就是audio payload.

在FLV文件中,一般情况下 AAC sequence header 这种包只出现1次,而且是第一个audio tag,为什么要提到这种tag,因为当时在做FLV demux的时候,如果是AAC的音频,需要在每帧AAC ES流前边添加7个字节ADST头,ADST在音频的格式中会详细解读,这是解码器通用的格式,就是AAC的纯ES流要打包成ADST格式的AAC文件,解码器才能正常播放.就是在打包ADST的时候,需要samplingFrequencyIndex这个信息,samplingFrequencyIndex最准确的信息是在AudioSpecificConfig中,所以就对AudioSpecificConfig进行解析并得到了samplingFrequencyIndex。 到这步你就完全可以把FLV 文件中的音频信息及数据提取出来,送给音频解码器正常播放了。


==========Video Tag============
如果TAG包中的TagType==9时,就表示这个TAG是video. StreamID之后的数据就表示是 VideoTagHeader ,VideoTagHeader结构如下:
VideoTagHeader的头1个字节,也就是紧跟着StreamID的1个字节包含着视频 帧类型(比如关键帧,p帧) 及视频CodecID信息.
VideoTagHeader之后跟着的就是VIDEODATA数据了,也就是video payload.当然就像音频AAC一样,这里 也有特例 ,即如果视频的格式是AVC(H.264)的话,VideoTagHeader会多出 4个字节 的信息:AVCPacketType 和 CompositionTime。

AVCPacketType 表示接下来 VIDEODATA (AVCVIDEOPACKET)的内容:
IF AVCPacketType == 0 AVCDecoderConfigurationRecord (AVC sequence header)
IF AVCPacketType == 1 One or more NALUs (Full frames are required)
还有如果为2,表示是结束包,一般在flv文件结尾。

AVCDecoderConfigurationRecord 包含着H.264解码比较重要的 sps和pps 信息,在给AVC解码器送数据流之前一定要把sps和pps信息送出,否则解码器不能正常解码。而且在解码器stop之后再次start之前, 如seek、快进快退状态切换等,都需要重新送一遍sps和pps的信息 。AVCDecoderConfigurationRecord在FLV文件中一般情况也是出现1次,也就是第一个video tag. AVCDecoderConfigurationRecord的 定义 在ISO 14496-15, 5.2.4.1中。
CompositionTime:3个字节


===========AVCDecoderConfigurationRecord=========
FFmpeg中extradata_size 格式: 4B大小+SPS+4B大小+pps


AVCDecoderConfigurationRecord 结构的定义:
aligned(8) class AVCDecoderConfigurationRecord { 
unsigned int(8) configurationVersion = 1; 
unsigned int(8) AVCProfileIndication; 
unsigned int(8) profile_compatibility; 
unsigned int(8) AVCLevelIndication; 

bit(6) reserved = ‘111111’b; 
unsigned int(2) lengthSizeMinusOne

 
bit(3) reserved = ‘111’b; 
unsigned int(5) numOfSPS; 

for (i=0; i< numOfSPS; i++) { 
unsigned int(16) SPSLength ; 
bit( 8*sequenceParameterSetLength ) sequenceParameterSetNALUnit; 

unsigned int(8) numOfPPS; 
for (i=0; i< numOfPPSet; i++) { 
unsigned int(16) PPSetLength; 
bit(8*pictureParameterSetLength) pictureParameterSetNALUnit; 
}


下面 蓝色的部分就是 FLV 文件中的 AVCDecoderConfigurationRecord 部分。
17 00 表示是参数包,然后00 00 00 是 :3个字节CompositionTime
00000130h: 00 00 00 17 00 00 00 00   01 4D 40 15 FF E1 00 0A  ; .........M@.?. 
00000140h:  67 4D 40 15 96 53 01 00 4A 20 01 00 05 68 E9 23  ; gM@. ..J ...h? 
00000150h:  88 00  00 00 00 2A 08 00 00 52 00 00 00 00 00 00 ; ?...*...R......

根据定义:
·         configurationVersion =  01
·         AVCProfileIndication =  4D
·         profile_compatibility =  40
·         AVCLevelIndication =  15
 
·         lengthSizeMinusOne =  FF  <- 非常重要,是 H.264 视频中 NALU 的长度, 计算方法 1 + (lengthSizeMinusOne & 3) 计算结果为 4

·         numOfSequenceParameterSets =  E1  <- SPS 的个数,计算方法是 numOfSequenceParameterSets & 0x1F 计算结果为 1


·         sequenceParameterSetLength =  00 0A  <- SPS 的长度
·         sequenceParameterSetNALUnits =  67 4D 40 15 96 53 01 00 4A 20  <- SPS数据

·         numOfPictureParameterSets =  01  <- PPS 的个数
·         pictureParameterSetLength =  00 05  <- PPS 的长度
·         pictureParameterSetNALUnits =  68 E9 23 88 00  <- PPS数据



资料:

FLV文件格式规范.pdf
解析工具:
FlvParse

SpecialFFLV

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值