——如果要学习一个新的知识点,官方手册可能是最快的途径。查看网上其他人的总结也许入门更快,但是要准确,深入,完整,还是要看官方手册。
 
以下内容来自对官方文档Video File Format Specification Version 10的分析总结。过程中借助ffmpeg实际转换了一个flv文件用例研究。
 
一个FLV文件,每种类型的tag都属于一个流,也就是一个flv文件最多只有一个音频流,一个视频流,不存在多个独立的音视频流在一个文件的情况。(mp4好像是可以的)
 
另外,FLV文件格式所用的是大端序。
 
注:下面的数据type中,UI表示无符号整形,后面跟的数字表示其长度是多少位。比如UI8,表示无法整形,长度一个字节。UI24是三个字节。UB表示位域,UB5表示一个字节的5位。可以参考c中的位域结构体。
 
FLV头

 
Field
type
Comment
签名
UI8
’F’(0X46)
签名
UI8
‘L’(0X4C)
签名
UI8
‘V’(0x56)
版本
UI8
FLV的版本。0x01表示FLV 版本是1
保留字段
UB5
前五位必须是0
是否有音频流
UB1
音频流是否存在标志
保留字段
UB1
必须是0
是否有视频流
UB1
视频流是否存在标志
文件头大小
UI32
FLV版本1时填写9,表明的是FLV头的大小,为后期的FLV版本扩展使用。包括这四个字节。
数据的起始位置就是从文件开头偏移这么多的大小。
 
 
FLV文件体

 
body部分由一个个Tag组成,每个Tag的下面有一块4bytes的空间,用来记录这个tag的长度,这个后置用于逆向读取处理,他们的关系如下图:
注意:头下面四个自己就是PreviousTagSize,因为前一个没有Tag,所以,值填写0。
 
FLV tags 结构

 
Field
type
Comment
TAG类型
UI8
 
8: audio
9: video
18: script data——这里是一些描述信息。
all others: reserved其他所有值未使用。
数据大小
UI24
数据区的大小,不包括包头。包头总大小是11个字节。
时戳
UI24
当前帧时戳,单位是毫秒。相对于FLV文件的第一个TAG时戳。第一个tag的时戳总是0。——不是时戳增量,rtmp中是时戳增量。
时戳扩展字段
UI8
如果时戳大于0xFFFFFF,将会使用这个字节。这个字节是时戳的高8位,上面的三个字节是低24位。
流ID
U24
总是0
数据区
UI8[n]
 
 
 
音频数据

 
Field
type
Comment
音频格式
UB4
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
 
7, 8, 14, and 15:内部保留使用。
flv是不支持g711a的,如果要用,可能要用线性音频。
采样率
UB2
For AAC: always 3
0 = 5.5-kHz
1 = 11-kHz
2 = 22-kHz
3 = 44-kHz
采样大小
UB1
0 = snd8Bit
1 = snd16Bit
声道
UB1
0=单声道
1=立体声,双声道。AAC永远是1
声音数据
UI8[N]
如果是PCM线性数据,存储的时候每个16bit小端存储,有符号。
如果音频格式是AAC,则存储的数据是AAC AUDIO DATA,否则为线性数组。
 
 
AAC AUDIO DATA

 
视频数据

 
 
Field
type
Comment
帧类型
UB4
 
1: keyframe (for AVC, a seekable frame)——h264的IDR,关键帧,可重入帧。
2: inter frame (for AVC, a non- seekable frame)——h264的普通帧
 
3: disposable inter frame (H.263 only)
4: generated keyframe (reserved for server use only)
5: video info/command frame
编码ID
UB4
使用哪种编码类型:
 
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
视频数据
UI[N]
如果是avc,则参考下面的介绍:
 
AVCVIDEOPACKET
 
AVCVIDEOPACKET

 
 
Field
type
Comment
AVC packet类型
UI8
0:AVC序列头
1:AVC NALU单元
2:AVC序列结束。低级别avc不需要。
CTS
SI24
如果AVC packet类型是1,则为cts偏移(见下面的解释),为0则为0
数据
UI8[n]
如果AVC packet类型是0,则是解码器配置,sps,pps。
如果是1,则是nalu单元,可以是多个,具体格式:将下面
 
关于CTS:这是一个比较难以理解的概念,需要和pts,dts配合一起理解。
首先,pts(presentation time stamps),dts(decoder timestamps),cts(CompositionTime)的概念:
pts:显示时间,也就是接收方在显示器显示这帧的时间。单位为1/90000 秒。
dts:解码时间,也就是rtp包中传输的时间戳,表明解码的顺序。单位单位为1/90000 秒。——根据后面的理解,pts就是标准中的CompositionTime
cts偏移:cts = (pts - dts) / 90 。cts的单位是毫秒。
 
pts和dts的时间不一样,应该只出现在含有B帧的情况下,也就是profile main以上。baseline是没有这个问题的,baseline的pts和dts一直想吐,所以cts一直为0。
 
在flv tag中的时戳就是DTS。
 
研究 一下文档,  ISO/IEC 14496-12:2005(E)      8.15   Time to Sample Boxes,发现CompositionTime就是presentation time stamps,只是叫法不同。——需要再进一步确认。
 
在上图中,cp就是pts,显示时间。DT是解码时间,rtp的时戳。
I1是第一个帧,B2是第二个,后面的序号就是摄像头输出的顺序。决定了显示的顺序。
DT,是编码的顺序,特别是在有B帧的情况,P4要在第二个解,因为B2和B3依赖于P4,但是P4的显示要在B3之后,因为他的顺序靠后。这样就存在显示时间CT(PTS)和解码时间DT的差,就有了CT偏移。
 
 
P4解码时间是10,但是显示时间是40,
 
AVCVIDEOPACKET中data格式:
 
 
Field
type
Comment
长度
UI32
nalu单元的长度,不包括长度字段。
nalu数据
UI8[N]
NALU数据,没有四个字节的nalu单元头,直接从h264头开始,比如:65 ** ** **,41 **  ** ** 
长度
UI32
nalu单元的长度,不包括长度字段。
nalu数据
UI8[N]
NALU数据,没有四个字节的nalu单元头,直接从h264头开始,比如:65 ** ** **,41 **  ** ** 
...
...
...
     
 
 
Data tags

主要是onMeta信息需要关注。
 
 
 
 
AVCDecoderConfigurationRecord

AVCVIDEOPACKET的数据格式,保存控制信息。
记录sps,pps信息。一般出现在第二个tag中,紧跟在onMeta之后。
 
一个典型的序列:
 
0000190: 0900 0033 0000 0000 0000 0017 0000 0000  ...3............
00001a0: 0164 002a ffe1 001e 6764 002a acd9 4078  .d.*....gd.*..@x
00001b0: 0227 e5ff c389 4388 0400 0003 0028 0000  .'....C......(..
00001c0: 0978 3c60 c658 0100 0568 ebec b22c 0000  .x<`.X...h...,..
 
17:表示h264IDR data
00:表示是AVC序列头
00 00 00 :cts为0
//从此往下就是AVCDecoderConfigurationRecord
01 :版本号
64 00 2a:profile level id,sps的三个字节,64表示是h264 high profile,2a表示level。
FF:NALU长度,为3?不知道这个长度用在哪里。
E1:表示下面紧跟SPS有一个。
//sps[N]:sps数组。
00 1e:    前面是两个字节的sps长度,表示后面的sps的长度是1e大小。
6764 002a acd9 4078 0227 e5ff c389 4388 0400 0003 0028 0000 0978 3c60 c658:sps的数据。
//因为只有一个sps,跳过这些长度,然后就是pps的个数信息:
01 :pps个数,1
//pps[n] pps 的个数
00 05:表示pps的大小是5个字节。
68 eb ec b2 2c:pps的数据
00 00 …….这是下一个tag 的内容了
 

我 的微信公众号

FLV文件格式官方规范详解的更多相关文章

  1. FLV视频封装格式详解

    FLV视频封装格式详解 分类: FFMpeg编解码 2012-04-04 21:13 1378人阅读 评论(2) 收藏 举报 flvheaderaudiovideocodecfile 目录(?)[-] ...

  2. 3dTiles 数据规范详解[1] 介绍

    版权:转载请带原地址.https://www.cnblogs.com/onsummer/p/12799366.html @秋意正寒 Web中的三维 html5和webgl技术使得浏览器三维变成了可能. ...

  3. 【转】FLV视频封装格式详解

    Overview Flash Video(简称FLV),是一种流行的网络格式.目前国内外大部分视频分享网站都是采用的这种格式. File Structure 从整个文件上开看,FLV是由The FLV ...

  4. 3dTiles 数据规范详解[3] 内嵌在瓦片文件中的两大数据表

    转载请声明出处:全网@秋意正寒 零.本篇前言 说实话,我很纠结是先介绍瓦片的二进制数据文件结构,还是先介绍这两个重要的表.思前想后,我决定还是先介绍这两个数据表. 因为这两个表不先给读者灌输,那么介绍 ...

  5. CommonJs规范详解---【XUEBIG】

     CommonJS是服务器模块的规范,Node.js采用了这个规范   1.CommonJs规范的出发点:JS没有模块系统.标准库较少.缺乏包管理工具:为了让JS可以在任何地方运行,以达到Java.C ...

  6. 3dTiles 数据规范详解[4.1] b3dm瓦片二进制数据文件结构

    B3dm,Batched 3D Model,成批量的三维模型的意思. 倾斜摄影数据(例如osgb).BIM数据(如rvt).传统三维模型(如obj.dae.3dMax制作的模型等),均可创建此类瓦片. ...

  7. 各大厂 C/C++ 编程规范详解

    来吧!各大厂知名规范体系~ 各有特点各有侧重~ Google C++ Style Guide Google C++ Style Guide,[中文版],简称 GSG,谷歌的 C++ 编程规范,在国内有 ...

  8. 百度MIP页规范详解 —— canonical标签

    百度MIP的规范要求必须添加强制性标签canonical,不然MIP校验工具会报错: 强制性标签<link rel="/^(canonical)$/"> 缺失或错误 这 ...

  9. wav文件格式分析与详解

    WAV文件是在PC机平台上很常见的.最经典的多媒体音频文件,最早于1991年8月出现在Windows 3.1操作系统上,文件扩展名为WAV,是WaveFom的简写,也称为波形文件,可直接存储声音波形, ...

随机推荐

  1. 基于AspectJ的XML方式进行AOP开发

    -------------------siwuxie095                                 基于 AspectJ 的 XML 方式进行 AOP 开发         1 ...

  2. python版本安装

    目的 本文目的在于,对于不熟悉Python的人,教你: 1. 从哪里找到 可以下载到 各种版本的 包括Python 2.x和Python 3.x的 最新版本的 Python. 高手请无视之. 2.以及 ...

  3. C# Socket网络编程精华篇

    我们在讲解Socket编程前,先看几个和Socket编程紧密相关的概念: TCP/IP层次模型 当然这里我们只讨论重要的四层 01,应用层(Application):应用层是个很广泛的概念,有一些基本 ...

  4. JFinal WEB MVC和Struts简要对比

    JFinal遵循COC原则,零配置,无xml,而struts需要配置来支持action.result.interceptor配置与使用. JFinal开发效率非常之高,相对Struts开发效率能提升五 ...

  5. 国内maven仓库地址

    Maven 中央仓库地址: 1.http://mvnrepository.com/ (推荐) 2.http://mirrors.ibiblio.org/maven2/ 3.http://repo1.m ...

  6. Luogu 3953[NOIP2017] 逛公园 堆优化dijkstra + 记忆化搜索

    题解 首先肯定是要求出单源最短路的,我用了堆优化dijikstra ,复杂度 mlogm,值得拥有!(只不过我在定义优先队列时把greater 打成了 less调了好久 然后我们就求出了$i$到源点的 ...

  7. Eloquent Observer 的小坑

    前言 最近开发新的项目不是基于完整的 laravel 框架,框架是基于 laravel ORM 的简单MVC模式.随着项目的成熟和业务需求,需要引入事件机制.简单地浏览了一下 symfony.lara ...

  8. Mysql 查看表结构的命令

    创建数据库create database abc; 显示数据库 show databases; 使用数据库 use 数据库名; 直接打开数据库 mysql -h localhost -u root - ...

  9. 电商类Web原型制作分享——聚美优品

    这是一家化妆品限时特卖商城.作为美妆电商类网站的佼佼者,网站以用户体验为核心,画面主色调符合女性消费者审美.排版整齐,布局合理.网站用弹出面板实现点击弹出内容,鼠标悬停文字按钮颜色改变等交互效果. 本 ...

  10. bitnami redmine svn配置

    采用bitnami 方案安装redmine svn服务器端会自己进行安装 1.创建版本库 首先进入remine安装目录的subversion/bin目录,例如我的安装目录是“/opt/redmine/ ...