metadata都在moov box中,比较复杂的是分别存储在不同的box中的。
media info
media info在moov的子box mvhd中,在本文中会以moov/mvhd的形式表示。像moov这样包含子box的box被称为container box。
mvhd的格式定义如下
其中需要注意的是duration和timescale。这里的duration是所有track的duration中的最大值。这里解释一下timescale,这个整数值表示1秒钟包含多少个time unit,相当于该文件定义的一个时间单位。
track info
媒体流的metadata在moov/trak box中,每一个trak box代表一个音视频流。流的信息在moov/trak/tkhd box
需要关注的是duration和width、height。视频流的width和height就是视频的宽、高,音频流两者都是0。
track的duration和tiemscale在moov/trak/mdia/mdhd中
这里的duration的单位是timescale
流的类型在moov/trak/mdia/hdlr中
从handler_type中可以知道流的类型,"vide"为视频流,"soun"为音频流。
时间戳
sample的时间戳信息分散在moov/trak/mdia/minf/stbl/stts和moov/trak/mdia/minf/stbl/ctts中。
decode time(DT)可以通过stts计算得到,DT(n)=sample_delta(0)+sample_delta(1)+...+sample_delta(n-1)
ctts中保存DT和CT(composition time)之间的offset,CT(n)=DT(n)+ctts(n),ctts可以没有,没有ctts时,DT和CT相同。
offset
sample offset的计算比较复杂,需要综合moov/trak/mdia/minf/stbl/stco,moov/trak/mdia/minf/stbl/stsc和moov/trak/mdia/minf/stbl/stsz才能得到。
stco是chunk offset box,从中可以知道chunk的数量以及每一个chunk在整个文件的offset。
entry_count就是文件中chunk的总量。
stsc是sample to chunk box,从中可以知道sample对应的chunk是哪个。
这个数据代表的意思是从first_chunk开始的每个chunk包含smples_per_chunk个sample,这样的chunk总共有多少个呢?用下一个entry的first_chunk减去当前entry的first_chunk就得到chunk的数量。最后一个entry表示从first_chunk到最后一个chunk,这里就需要用到上面从stco得到的chunk的总量。
stsz是sample size box,从中可以知道每个sample的size。
sample_size是默认的sample大小,如果sample_size不等于0,表示所有的sample有相同的大小,都是sample_size。否则需要从后面的entry table读取每一个sample的大小。
这样我们就知道了所有chunk的offset,每一个chunk包含多少sample,以及所有sample的size,就可以计算sample的offset了。用sample所在的chunk的offset,加上该chunk内该sample之前的所有sample的size之和,就可以得到sample的offset。