我们常说的视频文件格式常常只是多媒体封装格式,里面不仅包含了视频,还有音频、字幕等媒体信息。而纯视频码流的格式更多使用使用编码格式表达。
多媒体封装格式 (M ultimedia C ontainer Format,简称MCF、多媒体容器),是一种开放(没有身份规限,免费)、自由的数据格式。
多媒体文件是个容器。容器里面存在多个流(stream/track) 。每种流是由不同的编码器编程生成的。从流中读出的数据称为包 。在一个包中包含一个或多个帧。
容器格式内部对音视频数据的处理都是大同小异,区别点并不大。更多的差距在于它们对于不同编码格式的支持程度、元数据的详细程度以及对于是否能够支持音视频以外的数据。
不同的容器具有不同的特点,下面简单介绍常用的多媒体容器。
AVI
AVI,Audio Video Interleave。
- 机构:Mircrosoft
- 不支持流媒体
- 支持编解码器:几乎所有
- BT下载视频
一种RIFF(Resource Interchange File Format)文件格式。同样使用RIFF文件格式还有WAV格式文件。RIFF使用小端序存储。
主体中的图像数据和声音数据是交叉存放的,以此达到音视频同步。从尾部的索引可以跳转到要播放的位置。
播放时间没有直接的字段由读取的帧数和帧率计算得出。
缺点:
- 由于索引在文件尾部,所以不适合用来流传输。
- 容器中我没有时间戳,只能通过帧数和帧率计算得出。在索引中也没有写明时间戳和媒体位置的信息,所以在播放AVI时seek操作还需要额外的技术手段。
- 由于媒体数据分块存放,使得它对很多使用运动预测特定的视频编码的支持不是很好,因为预测帧需要访问帧外的数据。
二进制构成
AVI文件是一个类型为AVI
的RIFF块,主要有三个subchunk构成:
hdrl
LIST,信息块:元数据movi
LIST,数据块:保存音视频序列数据idxl
LIST,索引块(可选)
结构示意:
scss
RIFF ('AVI '
LIST ('hdrl'
'avih'(主AVI信息头数据)
LIST ('strl'
'strh' (流的头信息数据)
'strf' (流的格式信息数据)
['strd' (可选的额外的头信息数据) ]
['strn' (可选的流的名字) ]
...
)
...
)
LIST ('movi'
{ SubChunk | LIST ('rec '
SubChunk1
SubChunk2
...
)
...
}
...
)
['idx1' (可选的AVI索引块数据) ]
)
参考:
MOV
MOV,QuickTime File Format(QTFF)
-
机构:Apple
-
支持流媒体
-
支持编解码器:
- 音:AAC、MPEG-1 Layers I/II/III、AC-3等
- 视:MPEG-2/4、H.264等
-
点播、直播
相关概念
atom:QTFF的基本数据单元,可以来容纳实际的音视频数据,也可以放置元数据和字幕等信息,通过层层嵌套方式形成树状结构。atom容纳的数据类型和大小在atom头部进行描述。
MP4
MP4,MPEG-4 Part14
-
机构:MPEG
-
支持流媒体
-
支持编解码器:
- 音:AAC、MPEG-1 Layers I/II/III、AC-3等
- 视:MPEG-2/4、H.264、H.263等
-
互联网视频网站
MP4由多个包含不同信息的box,以树形式组织构成,与MOV的atom几乎一致。
根结点下包含三个box:
ftyp
:文件类型moov
:元数据mdat
:媒体数据
把moov放到mdat前面可以更快准备播放。
box结构
构成:
-
header:指明box大小和类型;
- 增加了
version
(8位)和flags
(24位)字段的成为FullBox。 - 当size等于0时,代表这个box是文件最后一个box。当size等于1时,说明box长度需要更多的位来描述,在后面会定义一个64位的largesize来描述box的长度。
- 增加了
-
body:数据或box
常用容器
-
moov,音视频数据的元数据信息
-
mvhd,影片文件头信息,未压缩过的影片信息的头容器
-
trak,多个,各轨道信息容器
-
tkhd,轨道元数据(TrackID、Duration、音量等等)
-
edts
- 如果没有该表,那么这个轨道会立即开始播放,一个空的 edts 数据用来定位对轨道的起始时间偏移位置
-
mdia
-
mdhd,媒体头
-
hdlr,句柄参考
-
minf,媒体信息
- vmhd,视频信息头
- smhd,音频信息头
- dinf,数据信息
- stdl,采样表
-
-
-
mdat
box中的多媒体数据是没有结构的,是参考moov
的track
box解析。moov
包含了整个多媒体文件的元数据,seek也是通过该box实现,通过其中的各个表查到数据偏移位置。
FLV
FLV,FLash Video。
-
机构:Adobe
-
支持流媒体
-
支持编解码器:
- 音:MP3、ADPCM、Linear PCM、AAC等
- 视:Sorenson、VP6、H.264
-
互联网视频
FLV常用做流媒体。
结构:
-
FLV Header
- 字符 FLV 签名字段
- 版本
- 保留标记
- 音视频标记
- 数据偏移
-
FLV Body,这里body只是一个概念,具体直接就是PreviousTagSize和Tag
-
PreviousTagSize #0:0
-
TAG #1
-
TAG Header
- Type
- DataSize
- TimeStamp
-
TAG Data
-
Audio Tag Data
- 第一个字节包含音频数据的参数信息
- 第二个字节开始为音频流数据
-
Video Tag Data(同上)
-
Script Tag Data
- 常用于展示元数据,存储的数据格式一般为 AMF 格式
-
-
-
PreviousTagSize #1:上一个TAG大小。
-
TAG #2
-
PreviousTagSize #2
-
...
-
参考:
TS
TS,MPEG2-TS
-
机构:MPEG
-
支持流媒体
-
支持编解码器:
- 音:MPEG-1 Layers I/II/III、AAC
- 视:MPEG-1/2/4、H.264
-
IPTV,低延时直播
TS文件为传输流文件,其特点是要求从视频流的任意片段开始都是可以独立解码的。TS容器是为了流传输而设计的。
在MPEG-2标准中,有两种不同类型的码流输出到信道:一种是节目码流(Program Stream, PS),适用于没有误差产生的媒体存储,如DVD等存储介质(.vob)。另一种是传送流(Transport stream, TS),适用于有信道噪声产生的传输,目前TS流广泛应用于广播电视中,如机顶盒等。
TS文件分层:
- ES,Elementary Stream:原始流,直接从编码器出来的裸数据。
- PES,Packet Elemental Stream:分割打包的ES流,加入了PES头(PTS、DTS等)。PES由包头和playload组成。
- TS层,Transport Stream:传输流。是在PES层的基础上加入数据流的识别和传输必须的信息。固定包长度为188字节,以便于找到帧的起始位置,易于从丢包中恢复。
为了便于传输,实现时分复用,基本流ES必须打包,就是将顺序连续、连续传输的数据流按一定的时间长度进行分割,分割的小段叫包,因此打包也称为分组。
MKV
MKV,Matroska Video File
- 机构:Matroska
- 支持流媒体
- 支持编解码器:几乎所有
- 点播、直播
开放标准、免费使用,可放入多种媒体信息,且不限数量。而且是目前唯一一个支持封装ASS字幕的格式。