FLV---flv封装格式
程序员文章站
2022-03-21 07:50:12
...
FLV文件 = File Header + File Body(Tag + Tag + Tag …)
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出现,而且只有一个。
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 文件大小
其中有两个编解码器id,一个是audiocodecid 对应Audio Tag Data中的4bit音频编码类型(如10对应AAC)
还有一个是videocodecid 对Video Tag Data中的4bit视频编码类型(如7对应AVC)
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
}
}
1.2.1 AVCVIDEOPACKET及内部结构
对于H.264数据来说,CodecID = 7。
当nalu_type=H264_IDR则为1.(关键帧),反之则为2.intet frame(非I帧吧?)
当CodecID = 7时,视频数据就是AVCVIDEOPACKET格式。
下面讲解一下AVCVIDEOPACKET。
AVCPacketType = 0(存放nalu配置参数)????AVCDecoderConfigurationRecord:
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封装格式详解
关于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 = 8位
1 = 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