mp4文件结构举例

来源:互联网 发布:php简单商城源代码 编辑:程序博客网 时间:2024/05/12 22:23

MP4文件结构由MPEG定义,由14496-12和14496-14具体定义。其中,14496定义了一个通用的标准和大体框架,它适用于多种文件格式的定义。14496-14是对其中一种文件格式(MP4)的具体定义。

1. 文件结构

整个文件由Box组成,所有的数据都在Box内定义。Box可以层级嵌套,例如,moov可以包含多个trak。Box结构应该不用缀述,简单列一下:

[cpp] view plaincopy
  1. aligned(8) class Box (unsigned int(32) boxtype, optional unsigned int(8)[16] extended_type)   
  2. {  
  3.   unsigned int(32) size;  
  4.   unsigned int(32) type = boxtype;  
  5.   if (size==1)   
  6.    {  
  7.     unsigned int(64) largesize;  
  8.    }   
  9.    else if (size==0)   
  10.    {  
  11.      // box extends to end of file  
  12.    }  
  13.    if (boxtype==‘uuid’) {  
  14.       unsigned int(8)[16] usertype = extended_type;  
  15.    }  
  16. }  

就是说一般情况下Box是以8个字节开头,接着就是Box的数据。这个8个字节分别表示size和type。size是整个Box的字节数,含size和type本身。type是4个可读的字符。例如:File Type Box的type就ftyp。 标准的type都是4个字符,如果要自定义的type,则需要把type设为"uuid",然后再附上16个字符作为自定义type

还有一种FullBox结构,对Box做了一些扩展,添加了2个字段:

[cpp] view plaincopy
  1. aligned(8) class FullBox(unsigned int(32) boxtype, unsigned int(8) v, bit(24) f) extends Box(boxtype)  
  2. {  
  3.    unsigned int(8) version = v;  
  4.    bit(24) flags = f;  
  5. }  

2. 数据类型

整数  : 以big-endian存储

unsigned int(8)

unsigned int(32)


定点小数 fixed point

template int(32) rate = 0x00010000;

其字段标明是16.16的fixed point number,表示前16位表示整数部分,后16位表示小数部分。例如,0x00010100 = 1.25 (0x0100 / 0x10000)


短阵 matrix

短阵只在MovieHeaderBox中用到,限定为3x3的矩阵,也就是9个元素。

(p q 1) * | a b u | = (m n z)
               | c d v |
               | x y w |

template int(32)[9] matrix =
{ 0x00010000,0,0,0,0x00010000,0,0,0,0x40000000 };

注意,{a,b,u, c,d,v, x,y,w}.中,u,v,w是2.30的fixed point,其他是16.16的fixed point,这个默认矩阵

0x00010000     0            0

0              0x00010000   0

0                       0          0x40000000

换算一下就是

1  0  0

0  1  0

0  0  1

也就是说转换后坐标p' =p, q'=q,即原番不变。


template 与 pre-defined

template表示预留给其他文档用,在本文档中可以忽略(这个字段存在,值总是默认值)

pre-defined表示此字段在先前版本中出现




以一个长度为10秒的MP4为例,其结构可能如下:

type: ftyp,        size:       24
type: mdat,     size:  8884701
type: mdat,     size:   136125
type: moov,     size:     4656

1. ftyp

一个ftyp对文件的类型进行描述,指明其符合哪些格式。一般就是mp4格式了。符合本文档的媒体类型有很多种,box条目的种类也不同,所以需要brand与compatible_brands的来说明此文件内的box的种类。文档中定义了isom, avc1, iso2, mp71, iso3这些brand应有的格式,当解码器在读出其brand后,就知道该文件的格式了。

[cpp] view plaincopy
  1. aligned(8) class FileTypeBox extends Box(‘ftyp’) {  
  2.   unsigned int(32) major_brand;  
  3.   unsigned int(32) minor_version;  
  4.   unsigned int(32) compatible_brands[]; // to end of the box  
  5. }  

2. mdat

上例中有2个mdat,一个是视频内容、另一个音频内容。对于h264, aac编码的媒体来说,其视频mdat中内容是nal,对于音频来说,其内容为aac的一帧。mdat中的帧依次存放,每个帧的位置、时间、长度都由moov中的信息指定。可以看出,mdat是很好组建的,这种Box只含有数据。

[cpp] view plaincopy
  1. aligned(8) class MediaDataBox extends Box(‘mdat’) {  
  2.    bit(8) data[];  
  3. }  

3. moov

moov存放影片的所有信息,一个moov含有多个trak。通常对于一个片子来说,就是一个视频trak,一个音频trak。MP4文件的重点也在于此。


(1) trak / tkhd

对于视频trak,存宽、高信息;对于音频trak,存音量信息。并不是太重要,真正初始化解码器要靠 stsd中的信息。

(2) trak / mdia / hdlr

标明该trak是视频还是音频

(3) trak / mdia / minf / stbl

所有重要的表都在这里。其中,

   - stsd: 编码器CODEC信息

   - stsz: 用于sample的划分,通常一个sample可以对应于frame。

   - stsc: 多个sample组成一个trunk,不过实际操作中可以让一个sample直接构成一个trunk

   - stco: trunk在文件中的位置,用于定位。

   - stts / ctts: 指定每个sample的PTS, DTS

(4) trak / edts / elst

把视频分为多段segment, 每个的起始时间和时长