MP4封装格式

发布时间 2023-07-06 01:18:12作者: 沉默的思想

一、规范介绍

  ISO/IEC 14496是MPEG专家组指定的MPEG-4标准。该标准分为21个部分:

  • Part 1: Systems
  • Part 2: Visual
  • Part 3: Audio
  • Part 4: Conformance testing
  • Part 5: Reference software
  • Part 6: Delivery Multimedia Integration Framework (DMIF)
  • Part 7: Optimized reference software for coding of audio-visual objects
  • Part 8: Carriage of ISO/IEC 14496 contents over IP networks
  • Part 9: Reference hardware description
  • Part 10: Advanced Video Coding
  • Part 11: Scene description and application engine
  • Part 12: ISO base media file format
  • Part 13: Intellectual Property Management and Protection (IPMP) extensions
  • Part 14: MP4 file format
  • Part 15: Carriage of NAL unit structured video in the ISO Base Media File Format
  • Part 16: Animation Framework eXtension (AFX)
  • Part 17: Streaming text format
  • Part 18: Font compression and streaming
  • Part 19: Synthesized texture stream
  • Part 20: Lightweight Application Scene Representation (LASeR) and Simple Aggregation Format (SAF)
  • Part 21: MPEG-J Graphics Framework eXtensions (GFX)
  • Part 22: Open Font Format
  • Part 23: Symbolic Music Representation
  • Part 24: Audio and systems interaction
  • Part 25: 3D Graphics Compression Model
  • Part 26: Audio conformance
  • Part 27: 3D Graphics conformance
  • Part 28: Composite font representation
  • Part 29: Web video coding
  • Part 30: Timed text and other visual overlays in ISO base media file format
  • Part 31: Video Coding for Browsers

  MP4封装格式对应的标准为ISO/IEC 14496-12,即信息技术对象编码的第12部分:ISO基本媒体文件格式(Information technology Coding of audio-visual objects Part 12:ISO Base media file format)。

二、文件结构

      MP4文件由于各个不同类型的Box组成,Box可以包含Box,其组成大致如下:

     所有类型的Box如下表所示,其中标*号的是MP4文件中必须要带有的Box。

Box types, structure, and cross-reference (Informative)

ftyp

         

*

4.3

file type and compatibility

pdin

           

8.1.3

progressive download information

moov

         

*

8.2.1

container for all the metadata

 

mvhd

       

*

8.2.2

movie header, overall declarations

 

meta

         

8.11.1

metadata

 

trak

       

*

8.3.1

container for an individual track or stream

   

tkhd

     

*

8.3.2

track header, overall information about the track

   

tref

       

8.3.3

track reference container

   

trgr

       

8.3.4

track grouping indication

   

edts

       

8.6.4

edit list container

     

elst

     

8.6.6

an edit list

   

meta

       

8.11.1

metadata

   

mdia

     

*

8.4

container for the media information in a track

     

mdhd

   

*

8.4.2

media header, overall information about the media

     

hdlr

   

*

8.4.3

handler, declares the media (handler) type

     

elng

     

8.4.6

extended language tag

     

minf

   

*

8.4.4

media information container

       

vmhd

   

12.1.2

video media header, overall information (video track only)

       

smhd

   

12.2.2

sound media header, overall information (sound track only)

       

hmhd

   

12.4.2

hint media header, overall information (hint track only)

       

sthd

   

12.6.2

subtitle media header, overall information (subtitle track only)

       

nmhd

   

8.4.5.2

Null media header, overall information (some tracks only)

       

dinf

 

*

8.7.1

data information box, container

         

dref

*

8.7.2

data reference box, declares source(s) of media data in track

       

stbl

 

*

8.5.1

sample table box, container for the time/space map

         

stsd

*

8.5.2

sample descriptions (codec types, initialization etc.)

         

stts

*

8.6.1.2

(decoding) time-to-sample

         

ctts

 

8.6.1.3

(composition) time to sample

         

cslg

 

8.6.1.4

composition to decode timeline mapping

         

stsc

*

8.7.4

sample-to-chunk, partial data-offset information

         

stsz

 

8.7.3.2

sample sizes (framing)

         

stz2

 

8.7.3.3

compact sample sizes (framing)

         

stco

*

8.7.5

chunk offset, partial data-offset information

         

co64

 

8.7.5

64-bit chunk offset

         

stss

 

8.6.2

sync sample table

         

stsh

 

8.6.3

shadow sync sample table

         

padb

 

8.7.6

sample padding bits

         

stdp

 

8.7.6

sample degradation priority

         

sdtp

 

8.6.4

independent and disposable samples

         

sbgp

 

8.9.2

sample-to-group

         

sgpd

 

8.9.3

sample group description

         

subs

 

8.7.7

sub-sample information

         

saiz

 

8.7.8

sample auxiliary information sizes

         

saio

 

8.7.9

sample auxiliary information offsets

   

udta

       

8.10.1

user-data

 

mvex

         

8.8.1

movie extends box

   

mehd

       

8.8.2

movie extends header box

   

trex

     

*

8.8.3

track extends defaults

   

leva

       

8.8.13

level assignment

moof

           

8.8.4

movie fragment

 

mfhd

       

*

8.8.5

movie fragment header

 

meta

         

8.11.1

metadata

 

traf

         

8.8.6

track fragment

   

tfhd

     

*

8.8.7

track fragment header

   

trun

       

8.8.8

track fragment run

   

sbgp

       

8.9.2

sample-to-group

   

sgpd

       

8.9.3

sample group description

   

subs

       

8.7.7

sub-sample information

   

saiz

       

8.7.8

sample auxiliary information sizes

   

saio

       

8.7.9

sample auxiliary information offsets

   

tfdt

       

8.8.12

track fragment decode time

   

meta

       

8.11.1

metadata

mfra

           

8.8.9

movie fragment random access

 

tfra

         

8.8.10

track fragment random access

 

mfro

       

*

8.8.11

movie fragment random access offset

mdat

           

8.2.2

media data container

free

           

8.1.2

free space

skip

           

8.1.2

free space

 

udta

         

8.10.1

user-data

   

cprt

       

8.10.2

copyright etc.

   

tsel

       

8.10.3

track selection box

   

strk

       

8.14.3

sub track box

     

stri

     

8.14.4

sub track information box

     

strd

     

8.14.5

sub track definition box

meta

           

8.11.1

metadata

 

hdlr

       

*

8.4.3

handler, declares the metadata (handler) type

 

dinf

         

8.7.1

data information box, container

   

dref

       

8.7.2

data reference box, declares source(s) of metadata items

 

iloc

         

8.11.3

item location

 

ipro

         

8.11.5

item protection

   

sinf

       

8.12.1

protection scheme information box

     

frma

     

8.12.2

original format box

     

schm

     

8.12.5

scheme type box

     

schi

     

8.12.6

scheme information box

 

iinf

         

8.11.6

item information

 

xml

         

8.11.2

XML container

 

bxml

         

8.11.2

binary XML container

 

pitm

         

8.11.4

primary item reference

 

fiin

         

8.13.2

file delivery item information

   

paen

       

8.13.2

partition entry

     

fire

     

8.13.7

file reservoir

     

fpar

     

8.13.3

file partition

     

fecr

     

8.13.4

FEC reservoir

   

segr

       

8.13.5

file delivery session group

   

gitn

       

8.13.6

group id to name

 

idat

         

8.11.11

item data

 

iref

         

8.11.12

item reference

meco

           

8.11.7

additional metadata container

 

mere

         

8.11.8

metabox relation

   

meta

       

8.11.1

metadata

styp

           

8.16.2

segment type

sidx

           

8.16.3

segment index

ssix

           

8.16.4

subsegment index

prft

           

8.16.5

producer reference time

 

  其中,下面三个是必须必带的顶层Box:

ftyp: File Type Box,描述文件遵从的MP4规范;

moov:Movie Box,媒体的元数据信息,有且只有一个;

mdat:Media Data Box,存放实际的媒体数据(音频、视频);

  对MP4文件必须携带的Box通过思维导图梳理下:

 

 

三、关键BOX解析

  Box分为两种:Box和Full Box,区别为Box Header不一样,Full Box由Box派生得到,在尾部多了4字节的version(1字节)+flags(3字节);

       Box=Box header+Box body,结构入下图所示:

 

Box Header

    字段定义如下:

l  type:box类型,包括 “预定义类型”、“自定义扩展类型”,占4个字节(对应类型的ASCII码);

l  预定义类型:比如ftyp、moov、mdat等预定义好的类型;

l  自定义扩展类型:如果type==uuid,则表示是自定义扩展类型。size(或largesize)随后的16字节,为自定义类型的值(extended_type)

l  size:包含box header在内的整个box的大小,单位是字节。当size为0或1时,需要特殊处理:

l  size等于0:box的大小由后续的largesize确定(一般只有装载媒体数据的mdat box会用到largesize);

l  size等于1:当前box为文件的最后一个box,通常包含在mdat box中;

l  largesize:当size为0时才存在,表示box的大小,占8个字节;(一般不使用)

l  extended_type:自定义扩展类型,占16个字节;(type==uuid才存在)

Box Body

    box数据体,不同box包含的内容不同,需要参考具体box的定义。有的 box body 很简单,比如 ftyp。有的 box 比较复杂,可能嵌套了其他box,比如moov。

3.2    关键Box介绍
3.2.1 ftyp (File Type Box)

    isom(ISO Base Media file)是在 MPEG-4 Part 12 中定义的一种基础文件格式,MP4、3gp、QT 等常见的封装格式,都是基于这种基础文件格式衍生的。

    MP4 文件可能遵循的规范有mp41、mp42,而mp41、mp42又是基于isom衍生出来的。

3gp(3GPP):一种容器格式,主要用于3G手机上;
QT:QuickTime的缩写,.qt 文件代表苹果QuickTime媒体文件;

ftyp定义如下:

l  major_brand:比如常见的 isom、mp41、mp42、avc1、qt等。它表示“最好”基于哪种格式来解析当前的文件。举例,major_brand 是 A,compatible_brands 是 A1,当解码器同时支持 A、A1 规范时,最好使用A规范来解码当前媒体文件,如果不支持A规范,但支持A1规范,那么,可以使用A1规范来解码;

l  minor_version:提供 major_brand 的说明信息,比如版本号,不得用来判断媒体文件是否符合某个标准/规范;

l  compatible_brands:文件兼容的brand列表。比如 mp41 的兼容 brand 为 isom。通过兼容列表里的 brand 规范,可以将文件 部分(或全部)解码出来;

3.2.2 moov(Movie Box)

    Movie Box,存储 mp4 的 metadata,是描述媒体信息的最主要Box,通过包含多个子Box记录信息。

moov中,最重要的两个box是 mvhd 和 trak:

l  mvhd:Movie Header Box,mp4文件的整体信息,比如创建时间、文件时长等;

l  trak:Track Box,一个mp4可以包含一个或多个轨道(比如视频轨道、音频轨道),轨道相关的信息就在trak里。trak是container box,至少包含两个box,tkhd、mdia;

mvhd针对整个影片,tkhd针对单个track,mdhd针对媒体,vmhd针对视频,smhd针对音频,可以认为是从 宽泛 > 具体,前者一般是从后者推导出来的。

mvhdMovie Header Box

    MP4文件的整体信息,跟具体的视频流、音频流无关,比如创建时间、文件时长等。

 字段含义如下:

l  creation_time:文件创建时间;

l  modification_time:文件修改时间;

l  timescale:一秒包含的时间单位(整数)。举个例子,如果timescale等于1000,那么,一秒包含1000个时间单位(后面track等的时间,都要用这个来换算,比如track的duration为10,000,那么,track的实际时长为10,000/1000=10s);

l  duration:影片时长(整数),根据文件中的track的信息推导出来,等于时间最长的track的duration;

l  rate:推荐的播放速率,32位整数,高16位、低16位分别代表整数部分、小数部分([16.16]),举例 0x0001 0000 代表1.0,正常播放速度;

l  volume:播放音量,16位整数,高8位、低8位分别代表整数部分、小数部分([8.8]),举例 0x01 00 表示 1.0,即最大音量;

l  matrix:视频的转换矩阵,一般可以忽略不计;

l  next_track_ID:32位整数,非0,一般可以忽略不计。当要添加一个新的track到这个影片时,可以使用的track id,必须比当前已经使用的track id要大。也就是说,添加新的track时,需要遍历所有track,确认可用的track id;

tkhdTrack Box

 

单个 track 的 metadata,包含如下字段:

l  version:tkhd box的版本;

l  flags:按位或操作获得,默认值是7(0x000001 | 0x000002 | 0x000004),表示这个track是启用的、用于播放的 且 用于预览的。

    Track_enabled:值为0x000001,表示这个track是启用的,当值为0x000000,表示这个track没有启用;

    Track_in_movie:值为0x000002,表示当前track在播放时会用到;

    Track_in_preview:值为0x000004,表示当前track用于预览模式;

l  creation_time:当前track的创建时间;

l  modification_time:当前track的最近修改时间;

l  track_ID:当前track的唯一标识,不能为0,不能重复;

l  duration:当前track的完整时长(需要除以timescale得到具体秒数);

l  layer:视频轨道的叠加顺序,数字越小越靠近观看者,比如1比2靠上,0比1靠上;

l  alternate_group:当前track的分组ID,alternate_group值相同的track在同一个分组里面。同个分组里的track,同一时间只能有一个track处于播放状态。当alternate_group为0时,表示当前track没有跟其他track处于同个分组。一个分组里面,也可以只有一个track;

l  volume:audio track的音量,介于0.0~1.0之间;

l  matrix:视频的变换矩阵;

l  width、height:视频的宽高;

hdlrHandler Reference Box

 

声明当前track的类型,以及对应的处理器(handler)。

handler_type的取值包括:

l  vide(0x76 69 64 65),video track;

l  soun(0x73 6f 75 6e),audio track;

l  hint(0x68 69 6e 74),hint track;

l  name,为utf8字符串,对handler进行描述;

stblSample Table Box

    stbl是所有Box最复杂的一个Box,包含多个Box,也是携带信息最主要的Box。MP4文件的媒体数据部分在mdat box里,而stbl则包含了这些媒体数据的索引以及时间信息,了解stbl对解码、渲染MP4文件很关键。

    stbl中比较关键的box包含stsd、stco、stsc、stsz、stts、stss、ctts,概要介绍如下:

l  stsd:给出视频、音频的编码、宽高、音量等信息,以及每个sample中包含多少个frame;

l  stco:thunk在文件中的偏移;

l  stsc:每个thunk中包含几个sample;

l  stsz:每个sample的size(单位是字节);

l  stts:每个sample的时长;

l  stss:哪些sample是关键帧;

l  ctts:帧解码到渲染的时间差值,通常用在B帧的场景;

stsdSample Description Box

    stsd给出sample的描述信息,这里面包含了在解码阶段需要用到的任意初始化信息,比如编码等。对于视频、音频来说,所需要的初始化信息不同,这里以视频为例。

  在SampleDescriptionBox 中,handler_type 参数 为 track 的类型(soun、vide、hint),entry_count 变量代表当前box中 smaple description 的条目数。

    针对不同的handler_type,SampleDescriptionBox 后续应用不同的 SampleEntry 类型,比如当类型为video track时,SampleEntry为VisualSampleEntry,字段如下图:

VisualSampleEntry包含如下字段:

l  width、height:视频的宽高,单位是像素;

l  horizresolution、vertresolution:水平、垂直方向的分辨率(像素/英寸),16.16定点数,默认是0x00480000(72dpi);

l  frame_count:一个sample中包含多少个frame,对video track来说,默认是1;

l  compressorname:仅供参考的名字,通常用于展示,占32个字节,比如 AVC Coding。第一个字节,表示这个名字实际要占用N个字节的长度。第2到第N+1个字节,存储这个名字。第N+2到32个字节为填充字节。compressorname 可以设置为0;

l  depth:位图的深度信息,比如 0x0018(24),表示不带alpha通道的图片;

    其中codingname代表视频编码格式,例如,当视频编码格式为H.264时,codingname=’avc1‘或’avc2‘,该Box对应的规范在ISO/IEC 14496-Part 15: Carriage of NAL unit structured video in the ISO Base Media File Format

中规定。入下图所示,为'acv1'Box字段定义,’avc1‘ Box主要信息存在内部的’avcC‘ Box中,’avcC‘ Box主要如下图二所示。

 

 其中重要的字段如下:

l  lengthSizeMinusOne:代表在mdat Box中在每帧前用(lengthSizeMinusOne+1)个字节代表帧数据长度,一般取值是3,即用4个字节前缀记录帧长度;

l  numOfSequenceParameterSet~sequenceParametrSetNALUnit:保存SPS数据;

l  numOfPictureParameterSets~ pictureParameterSetNALUnit:保存PPS数据

stcoChunk Offset Box

    chunk在文件中的偏移量。针对小文件、大文件,有两种不同的box类型,分别是stco、co64,它们的结构是一样的,只是字段长度不同。

    chunk_offset 指的是在文件本身中的 offset,而不是某个box内部的偏移。

    在构建mp4文件的时候,需要特别注意 moov 所处的位置,它对于chunk_offset 的值是有影响的。有一些MP4文件的 moov 在文件末尾,为了优化首帧速度,需要将 moov 移到文件前面,此时,需要对 chunk_offset 进行改写。

stscSample To Chunk Box

    ample 以 chunk 为单位分成多个组。chunk的size可以是不同的,chunk里面的sample的size也可以是不同的。

l  entry_count:有多少个表项(每个表项,包含first_chunk、samples_per_chunk、sample_description_index信息);

l  first_chunk:当前表项中,对应的第一个chunk的序号;

l  samples_per_chunk:每个chunk包含的sample数;

l  sample_description_index:指向 stsd 中 sample description 的索引值(参考stsd小节);

l  前面描述比较抽象,这里看个例子,这里表示的是:

l  序号1~15的chunk,每个chunk包含15个sample;

l  序号16的chunk,包含30个sample;

l  序号17以及之后的chunk,每个chunk包含28个sample;

l  以上所有chunk中的sample,对应的sample description的索引都是1;

 stszSample Size Boxes

    每个sample的大小(字节),根据 sample_size 字段,可以知道当前track包含了多少个sample(或帧)。

l  sample_size:默认的sample大小(单位是byte),通常为0。如果sample_size不为0,那么,所有的sample都是同样的大小。如果sample_size为0,那么,sample的大小可能不一样。

l  sample_count:当前track里面的sample数目。如果 sample_size==0,那么,sample_count 等于下面entry的条目;

|  entry_size:单个sample的大小(如果sample_size==0的话);

sttsDecoding Time to Sample Box

    stts包含了DTS到sample number的映射表,主要用来推导每个帧的时长。

l  entry_count:stts 中包含的entry条目数;

l  sample_count:单个entry中,具有相同时长(duration 或 sample_delta)的连续sample的个数。

l  sample_delta:sample的时长(以timescale为计量)

stssSync Sample Box

    mp4文件中,关键帧所在的sample序号。如果没有stss的话,所有的sample中都是关键帧(I帧)。

l  entry_count:entry的条目数,可以认为是关键帧的数目;

l  sample_number:关键帧对应的sample的序号;(从1开始计算)

3.2.3 mdat(Movie Box)

 

l  data[]:保存实际的媒体数据,如果是视频数据,则data[0]~data[3]标识当前帧长度,data[4]~data[n]为当前帧数据=NALU不包含startcode数据。

四、参考

参考:ISO/IEC 14496-Part12和ISO/IEC 14496-Part15(规定AVC/HEVC BOX的语法)