1:MP4的box有很多,见过的70多个吧,这里一共写了必须的10多个,剩下的可以扩展,有:fpyt,free,mdat,moov,mvhd,trak,
tkhd,mdia,mdhd,hdlr,minf,vmhd,smhd,dinf,stbl,stsd,stts,stsc,stsz,stco,stss,ctts(可选),avc1,accC,mp4a,esds。
2:time scale 和 duration的关系
time scale 是单位 以秒为单位 duration 是时常,可以以毫秒为单位也可以不是,只要算出来那个值就行了:例如:
time scale = 600, duration = 42000 算出来 duration/timescale = 70.00 , time scale = 1000 , duration = 70000,算出来 duration/timescale = 70.00 相同的值,道理就是这样。本程序需要三个这样的值,一个是文件总的时常,二是音频的时常,三个是视频的时常,存储在不同的box中,这些数值,具体看官方文档。
3:本程序有一个简便的方法,MP4中引用了很多chunk和sampel的关系如下图:
但问程序为了简便,将chunk和sample 一一对应,也就是说一个chunk中只有一个sample,这里要注意。
4:stts:TimeToSampleBox
结构如下:
如果多个sample有相同的duration,可以只用一项描述所有这些samples,数量字段说明sample的个数。例如,如果一个视 频媒体的帧率保持不变,整个表可以只有一项,数量就是全部的帧数。
例1: 视频
entry_count:1
sample_count:37 //上面已经有duration时间了,duration指整个mdat中video的时长,这里37却为chunks数目
sample_delta:1001 //1001 * 37=37037 sample_delta*sample_count=duration
例2: 音频
sentry_count:1
sample_count:67 //音频分了67个chunks
sample_delta:1024 //同上
5:stsz:SampleSizeBox
结构如下:
就是表示每一个sample的大小,视频的时候,这里一定要注意 这个长度是 4个字节的长度前缀加上数据的长度,要不然播放不出来。
6: stsd:SampleDescriptionBox
结构如下:
这个box中包含的音频的采样率,声道,样本,视频的sps,pps等信息,这些信息的结构可以看官方文档
如图:
视频:AVC sequence header就是AVCDecoderConfigurationRecord结构,该结构在标准文档“ISO-14496-15 AVC file format”中有详细说明。
视频和flv的相同。avcc结构。
音频:有两种:
1):
AAC sequence header存放的是AudioSpecificConfig结构,该结构则在“ISO-14496-3 Audio”中描述。AudioSpecificConfig结构的描述非常复杂,这里我做一下简化,事先设定要将要编码的音频格式,其中,选择"AAC-LC"为音频编码,音频采样率为44100,于是AudioSpecificConfig简化为下表:
这种的和flv的相同里面存放了采样率,声道等信息。
2):mp4a(box)->esds(box)
这种的信息请看条目11。
这里还有一点要注意:MP4中所有的项都是box,stsd下面有几种box,视频:stsd->
avc1(box)->avcC(box),
音频:stsd->mp4a(box)->esds(box),是box就有box头,一定要注意。
7:stss:SyncSampleBox
结构如下:
stss: syn Sample box
例1: 视频
entry_count:1
sample_number:1
但音频里没有这个box,
这个Box非常重要, 决定了整个mp4文件是否可以拖拉, 如果这个box只有一个entry,则拖拉时将cpu达到100%, 如果这个box不存在, 可以拖拉, 也不会达到 100%, 但是会略等一会, 通常做法可以搞100条.
“stss”确定media中的关键帧。对于压缩媒体数据,关键帧是一系列压缩序列的开始帧,其解压缩时不依赖以前的帧,而后续帧的解压缩将依赖于这个关键帧。“stss”可以非常紧凑的标记媒体内的随机存取点,它包含一个sample序号表,表内的每一项严格按照sample的序号排列,说明了媒体中的哪一个sample是关键帧。如果此表不存在,说明每一个sample都是一个关键帧,是一个随机存取点。
这里没有chunk的概念,entry_count:一共有多少个关键帧,sample_number:关键帧sample的标号。
8:stco:ChunkOffsetBox
结构如下:
“stco”定义了每个chunk在媒体流中的位置。位置有两种可能,32位的和64位的,后者对非常大的电影很有用。在一个表中只会有一种可能,这个位置是在整个文件中的,而不是在任何box中的,这样做就可以直接在文件中找到媒体数据,而不用解释box。需要注意的是一旦前面的box有了任何改变,这张表都要重新建立,因为位置信息已经改变了。
9: stsc:SampleToChunkBox
结构如下:
First chunk Samples per chunk Sample description ID
1 4 1
4 3 1
5 4 1
8 3 1
可以看出chunk1、chunk2、chunk3都有4个sample,chunk4有3个sample,chunk5、chunk6、chunk7有4个sample……
就是这个意思。
用chunk组织sample可以方便优化数据获取,一个thunk包含一个或多个sample。“stsc”中用一个表描述了sample与chunk的映射关系,查看这张表就可以找到包含指定sample的thunk,从而找到这个sample。
10:
avc1(box)->avcC(box)
acc1 box size //32
avc1 boxheader: //32
const unsigned int(8)[6] reserved = 0;
unsigned int(16) data_reference_index;
unsigned int(16) pre_defined = 0;
const unsigned int(16) reserved = 0;
unsigned int(32)[3] pre_defined = 0;
unsigned int(16) width;
unsigned int(16) height;
template unsigned int(32) horizresolution = 0x00480000; // 72 dpi
template unsigned int(32) vertresolution = 0x00480000; // 72 dpi
const unsigned int(32) reserved = 0;
template unsigned int(16) frame_count = 1;
string[32] compressorname;
template unsigned int(16) depth = 0x0018;
int(16) pre_defined = -1;
accC box size //32
avcC boxheader: //32
unsigned char configurationVersion; //8;= 0x01
unsigned char AVCProfileIndication; //sps即sps的第2字节,所谓的AVCProfileIndication
unsigned char profile_compatibility; //sps即sps的第3字节,所谓的profile_compatibility
unsigned char AVCLevelIndication; //sps即sps的第4字节,所谓的AVCLevelIndication
unsigned char reserved_1; //‘111111’b;
unsigned char lengthSizeMinusOne; //NALUnitLength 的长度 -1 一般为0x03
unsigned char reserved_2; //‘111’b;
unsigned char numOfSequenceParameterSets; //一般都是一个
unsigned int sequenceParameterSetLength; //sps长度
unsigned char * sequenceParameterSetNALUnit; //sps数据
unsigned char numOfPictureParameterSets; //一般都是一个
unsigned int pictureParameterSetLength; //pps长度
unsigned char * pictureParameterSetNALUnit;//pps数据
这样结构就完成了。最简便的方式。
11: mp4a(box)->AudioSpecificConfig(这里用的是esds的名称)
mp4a box size //32
mp4a boxheader: //32
const unsigned int(8)[6] reserved = 0;
unsigned int(16) data_reference_index;
const unsigned int(32)[2] reserved = 0;
template unsigned int(16) channelcount = 2;
template unsigned int(16) samplesize = 16;
unsigned int(16) pre_defined = 0;
const unsigned int(16) reserved = 0 ;
template unsigned int(32) samplerate = {timescale of media}<<16;
esdsbox size //32
esds boxheader: //32
version,flag //32
unsigned char audioObjectType; //5;编解码类型:AAC-LC = 0x02
unsigned char samplingFrequencyIndex; //4;采样率 44100 = 0x04
unsigned char channelConfiguration; //4;声道 = 2
unsigned char framelengthFlag; //1;标志位,位于表明IMDCT窗口长度 = 0
unsigned char dependsOnCoreCoder; //1;标志位,表明是否依赖于corecoder = 0
unsigned char extensionFlag; //1;选择了AAC-LC = 0
按照这个结构写填写vlc也能正常播放,估计是vlc 比较强大。
12:mp4a(box)->esds(box)
mp4a box size //32
mp4a boxheader: //32
const unsigned int(8)[6] reserved = 0;
unsigned int(16) data_reference_index;
const unsigned int(32)[2] reserved = 0;
template unsigned int(16) channelcount = 2;
template unsigned int(16) samplesize = 16;
unsigned int(16) pre_defined = 0;
const unsigned int(16) reserved = 0 ;
template unsigned int(32) samplerate = {timescale of media}<<16;
esdsbox size //32
esds boxheader: //32
version,flag //32
unsigned char tag; //8
unsigned char Length_Field; //8 Length Field:25
unsigned int ES_ID; //bit(16) ES_ID: 是0
unsigned char streamDependenceFlag; //bit(1) steamDependenceFlag,如果为1,则有16bits的
unsigned char URL_Flag; //bit(1) :URL_Flag,如果为1,后边则有8bits URLlength, 和相应的URLstring(URLlength)
unsigned char OCRstreamFlag; //bit(1) 如果为1,有16bits OCR_ES_id;
unsigned char streamPriority; //bit(5)
unsigned char DecoderConfigDescriptor_tag; //8 = 0x04
unsigned char Length_Field_1; //8 = 0x11
unsigned char objectTypeIndication; //8 = 0x40 14496-1 Table8, 0x40是Audio ISO/IEC 14496-3
unsigned char streamType ; //6 5是Audio Stream, 14496-1 Table9
unsigned char upStream; //1
unsigned char reserved; //1
unsigned int bufferSizeDB;//24 //这里是调节比特率的
unsigned int maxBitrate; //32
unsigned int avgBitrate; //32
unsigned char DecSpecificInfotag; //8 = 0x05
unsigned char Length_Field_2; //8 = 0x02
unsigned char audioObjectType_2_GASpecificConfig; //5 //编解码类型:AAC-LC = 0x02
unsigned char samplingFrequencyIndex; //4 //采样率 44100 = 0x04
unsigned char channelConfiguration; //4 //声道 = 2
unsigned char cpConfig; //2
unsigned char directMapping;// 1
unsigned char SLConfigDescrTag;//8 = 0x06
unsigned char Length_Field_3;//8 = 0x01
unsigned char predefined;//8 predefined 0x02 Reserved for use in MP4 files
这个box的信息是从:http://blog.csdn.net/coreavs163/article/details/8603026 这位网友的分享中看到的,一直没找到官方文档的信息,
不过有这些已经够了,将采样率,声道都填入到了这个box里面。
如果用上面的AudioSpecificConfig,文件夹中的小图标是不能显示mp4的图像的。
13:ctts:CompositionOffsetBox(可选)
这个box具体是怎么应用的不太清楚,网上也没找到相关的解析,应该是个可选的box,不过我看一般的MP4文件都有这个box,期待高手给解析吧,如果哪位高手知道这个box是怎么填写的,请联系我。
注:本demo地址:http://download.csdn.net/detail/zhuweigangzwg/5580637
交流请加QQ:379969650