一、引言
根据《video_file_format_spec_v10_1.pdf》第75页,如果某个Tag的Tag header中的TagType值为9,表示该Tag为Video Tag:
这时StreamID之后紧接着的就是VideoTagHeader,也就是说这时Tag header之后的就是VideoTagHeader:
然后这时如果Filter的值不为1,表示未加密,不需要预处理。则VideoTagHeader之后紧接着的就VIDEODATA:
所以,
1.当某个Tag的Tag header中的TagType属性的值为9时,该Tag为Video Tag;
2.未加密的情况下,一个Video Tag = Tag header + VideoTagHeader + VIDEODATA。
二、VideoTagHeader
根据《video_file_format_spec_v10_1.pdf》第78页,VideoTagHeader包含的属性如下:
其中:
Frame Type:占4位(8位等于1个字节),为该帧的类型。值为1表示是H.264的I帧;值为2表示是H.264的P帧、B帧;值为3表示是H.263的disposable inter frame;值为4表示是给服务器保留的生成的关键帧;值为5表示是视频信息/命令帧。
CodecID:占4位,编解码器的标识符,表示该Video Tag的视频数据使用的是哪种视频压缩编码方式。值为2表示是Sorenson H.263;值为3表示是屏幕视频;值为4表示是On2 VP6;值为5表示是带alpha通道的On2 VP6;值为6表示是屏幕视频的版本2;值为7表示是H.264。
AVCPacketType:占1字节,H.264数据包的类型。仅当FLV文件中的视频为H.264格式时,才有该属性。
值为0表示该Video Tag包含AVC sequence header,即此时该Video Tag的VIDEODATA为AVCDecoderConfigurationRecord,关于AVCDecoderConfigurationRecord的概念可以参考:《音视频入门基础:H.264专题(18)------AVCDecoderConfigurationRecord简介》;
值为1表示该Video Tag包含H.264的一个或多个NALU,即此时该Video Tag的VIDEODATA为一个或多个NALU,这些NALU之间用NALUnitLength分隔。FLV等文件格式使用的是avcC包装的H.264,avcC包装的H.264码流中,每个NALU前面没有起始码。avcC通过在每个NALU前加上NALUnitLength,在读取某个NALU之前,先把该NALU前面的NALUnitLength读取出来,拿到该NALU的总长度,然后根据该长度读取相应的字节数,读取出整个NALU。
值为2表示是该Video Tag包含AVC end of sequence,表示这段H.264码流结束。
CompositionTime:占3字节。AVCPacketType属性的值为1时,该值为Composition time offset(简称CTS),即PTS相对于DTS的偏移值;AVCPacketType属性的值为其它时,CompositionTime属性的值为0。
从《音视频入门基础:FLV专题(7)------Tag header简介》中可以知道,Tag header的第5到第8个字节为该音视频帧的解码时间戳(DTS)。所以该音视频帧的显示时间戳(PTS) = DTS + CTS。
三、VIDEODATA
根据《video_file_format_spec_v10_1.pdf》第79页,FLV文件未加密时,VIDEODATA为VideoTagBody:
四、VideoTagBody
根据《video_file_format_spec_v10_1.pdf》第79页,当FLV文件的视频压缩编码格式为H.264时,VideoTagBody为AVCVIDEOPACKET:
五、AVCVIDEOPACKET
根据《video_file_format_spec_v10_1.pdf》第79页,AVCPacketType的值为0时,AVCVIDEOPACKET为AVCDecoderConfigurationRecord;当AVCPacketType的值为1时,AVCVIDEOPACKET包含H.264的一个或多个NALU;文档中没有写AVCPacketType的值为2的情况,所以当AVCPacketType的值为2时,AVCVIDEOPACKET没有数据:
六、用flvAnalyser工具分析Video Tag
用flvAnalyser工具可以直接显示Video Tag的各个部分。
AVCPacketType的值为0时:
AVCPacketType的值为1时:
AVCPacketType的值为2时:
七、总结
1.当某个Tag的Tag header中的TagType属性的值为9时,该Tag为Video Tag;
2.未加密的情况下,一个Video Tag = Tag header + VideoTagHeader + VIDEODATA。
3.当FLV文件的视频压缩编码格式为H.264并且未加密时,如果VideoTagHeader中的AVCPacketType的值为0,VIDEODATA为AVCDecoderConfigurationRecord;如果AVCPacketType的值为1,VIDEODATA包含一个或多个NALU;如果AVCPacketType的值为2,表示这段H.264码流结束,VIDEODATA没有数据。