flv 格式分析2
来源:互联网 发布:伺服电机编程实例 编辑:程序博客网 时间:2024/05/22 15:11
flv文件格式解析
date: 2014.12.10; modification:2014.12.10
目录:
- 1 概述
- 2 File header文件头
- 3 Body
- 4 Tag
- 4.1 Tag Header
- 4.2 Tag Data
- 4.3 脚本Tag Data
- 4.4 音频Tag data
- 4.5 视频Tag data
- 4.5.1 AVC视频封装
- 5 参考文献
1 概述
flv文件总体分为两部分: header和body.
其中body部分又是由一个个数据段组成, 这数据段称为Tag. 其中tag又分为Tag header和Tag data. 详见后文.
它们的关系如下图
2 File header文件头
File header部分记录了flv的类型, 版本等信息, 是flv的开头, 一般都差不多, 占9bytes. 具体格式如下:
3 Body
body部分由一个个Tag组成, 每个Tag的下面有一块4bytes的空间, 用来记录这个tag的长度, 这个后置用于逆向读取处理.
4 Tag
每个Tag由也是由两部分组成的: Tag Header和Tag Data. Tag Header里存放的是当前Tag的类型, 数据区(Tag Data)长度等信息, 具体如下:
4.1 Tag Header
Tag类型取值:
- 8: 音频
- 9: 视频
- 18: 脚本
- 其他: 保留
4.2 Tag Data
Tag header之后紧接着就是数据区(Tag data), 其长度由Tag header中的"数据区长度"字段表明. 数据区根据Tag类型的不同可分为三种, 音频数据, 视频数据和脚本数据.
4.3 脚本Tag Data
脚本Tag一般至少有一个, 用于存放flv的MetaData信息, 比如duration, audiodatarate, creator, width等. 一般这是FLV文件的第一个Tag, 因为知道了这些基本信息之后, 才好继续进行后面的解码的工作.
首先介绍下脚本的数据类型. 所有数据都是以 数据类型+(数据长度)+数据 的格式出现的, 也就是amf封装, 数据类型占1byte, 数据长度看数据类型是否存在, 后面才是数据.
其中数据类型的种类有:
- 0 = Number type
- 1 = Boolean type
- 2 = String type
- 3 = Object type
- 4 = MovieClip type
- 5 = Null type
- 6 = Undefined type
- 7 = Reference type
- 8 = ECMA array type
- 10 = Strict array type
- 11 = Date type
- 12 = Long string type
如果类型为String, 后面的2bytes为字符串的长度(Long String是4bytes), 再后面才是字符串数据; 如果是Number类型, 后面的8bytes为Double类型的数据; Boolean类型, 后面1byte为Bool类型.
知道了这些后再来看看flv中的脚本, 一般开头是0x02, 表示String类型, 后面的2bytes为字符串长度, 一般是0x000a("onMetaData"的长度), 再后面就是字符串"onMetaData". 好像flv格式的文件都有onMetaData标记, 在运行ActionScript的时候会用到它. 后面跟的是0x08, 表示ECMA Array类型, 这个和Map比较相似, 一个键跟着一个值. 键都是String类型的, 所以开头的0x02被省略了, 直接跟着的是字符串的长度, 然后是字符串, 再是值的类型, 也就是上面介绍的那些了.
4.4 音频Tag data
第一个byte是音频的信息, 格式如下.
- 音频格式 (4bits) 取值:
- 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
- 采样率 (2bits) 取值:
- 0 = 5.5-kHz
- 1 = 11-kHz
- 2 = 22-kHz
- 3 = 44-kHz; 对于AAC总是3
- 采样长度 (1bit) 取值:
- 0 = snd8Bit
- 1 = snd16Bit; 压缩过的音频都是16bit
- 音频类型 (1bit) 取值:
- 0 = sndMono
- 1 = sndStereo; 对于AAC总是1
4.5 视频Tag data
和音频数据一样, 第一个byte是视频信息, 格式如下:
- 帧类型 (4bits) 取值:
- 1: keyframe (for AVC, a seekable frame)
- 2: inter frame (for AVC, a non-seekable frame)
- 3: disposable inter frame (H.263 only)
- 4: generated keyframe (reserved for server use only)
- 5: video info/command frame
- 编码ID (4 bits) 取值:
- 1: JPEG (currently unused)
- 2: Sorenson H.263
- 3: Screen video
- 4: On2 VP6
- 5: On2 VP6 with alpha channel
- 6: Screen video version 2
- 7: AVC
接下来就是具体Video的流数据的封装了.
4.5.1 AVC视频封装
对于AVC格式的video, 除了第一个字节的'帧类型'和'编码ID'之外, 从第二个字节开始分别为:
- AVC包类型:AVCPacketType (8Bits) 取值:
- 0: AVC sequence header
- 1: AVC NALU
- 2: AVC end of sequence
- CompositionTime (24Bits) 取值:
- 如果上面的AVCPacketType=0x01, 为相对时间戳;
- 其它: 均为0;
- Data (n Bytes) 为负载数据 取值:
- 如果AVCPacketType=0x00, 为AVCDecorderConfigurationRecord;
- 如果AVCPacketType=0x01, 为NALUs;
- 如果AVCPacketType=0x02, 为空.
AVCDecoderConfigurationRecord详细说明:
一般第一个视频Tag会封装视频编码的总体描述信息(AVC sequence header), 就是AVCDecoderConfigurationRecord结构(ISO/IEC 14496-15 AVC file format中规定). 其结构如下:
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) numOfSequenceParameterSets; for (i=0; i< numOfSequenceParameterSets; i++) { unsigned int(16) sequenceParameterSetLength ; bit(8*sequenceParameterSetLength) sequenceParameterSetNALUnit; } unsigned int(8) numOfPictureParameterSets; for (i=0; i< numOfPictureParameterSets; i++) { unsigned int(16) pictureParameterSetLength; bit(8*pictureParameterSetLength) pictureParameterSetNALUnit; }}
例如:
下面高亮的部分就是 FLV 文件中的 AVCDecoderConfigurationRecord 部分.
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......
根据 AVCDecoderConfigurationRecord 结构的定义:
- configurationVersion = 01
- AVCProfileIndication = 4D
- profile_compatibility = 40
- AVCLevelIndication = 15
- lengthSizeMinusOne = FF : 非常重要, 是 H.264 视频中 NALU 的长度, 计算方法是
1 + (lengthSizeMinusOne & 3)
, NALU的长度怎么会一直都是4呢? 其实这不是NALU的长度, 而是NALU中, 表示长度的那个字段的长度是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 的个数, 结果为1
- pictureParameterSetLength = 00 05 : PPS 的长度
- pictureParameterSetNALUnits = 68 E9 23 88 00 : PPS内容
5 参考文献
http://wuyuans.com/2012/08/flv-format/
http://blog.csdn.net/k1988/article/details/5654631
- flv 格式分析2
- flv 格式分析
- flv 格式分析3
- FLV格式分析
- FLV封装格式分析
- FLV视频文件格式分析
- 通过RTMP play分析FLV格式详解
- 学习和分析FLV封装格式
- 流媒体-FLV格式详解及数据分析
- 通过RTMP play分析FLV格式详解
- FlV(H264+AAC)格式详细分析
- FLV容器分析2
- FLV容器分析2
- FLV容器分析2
- FLV封装格式解析2
- flv格式
- flv格式
- FLV格式
- 深入理解JavaScript系列(20):《你真懂JavaScript吗?》答案详解
- 简单的Hessian实例
- Codeforce 85E (二分答案+二分图染色)
- 通过linux的tc工具简单实现上传和下载的流量控制
- 深入理解JavaScript系列(21):S.O.L.I.D五大原则之接口隔离原则ISP
- flv 格式分析2
- windows下安装,配置gcc编译器
- MySQL:Table XXX is marked as crashed and should be repaired
- 深入理解JavaScript系列(22):S.O.L.I.D五大原则之依赖倒置原则DIP
- div+css实现九宫格效果
- Android Jni开发环境搭建
- 对一种基于CAS的Singleton实现方式的探讨
- 分享的力量
- 模拟 POJ-1581 A Contesting Decision