下面的软件下载地址:http://download.csdn.net/source/2607382
ftyp: |
这是一个筐,可以装mdat等其他Box。 例:00 00 00 14 66 74 79 70 69 73 6F 6D 00 00 02 00 6D 70 34 31 语义为:ftyp: Major brand: isom Minor version: 512 Compatible brand: mp41 free|skip 空白Box.装在ftyp等筐里 例:00 00 00 08 66 72 65 语意为: free: (null) |
moov: |
这是一个筐,里面很丰富 例:00 00 07 63 6D 6F 6F 76 本身属性没有。但后面全是它的内容 |
moov:mvhd: |
这是moov的header. 例:00 00 00 6C 6D 76 68 64 00 00 00 00 7C 25 B0 80 7C 25 B0 80 00 00 03 E8 00 00 06 14 00 01 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 语义: creation_time:2082844800modification_time:2082844800 timescale:1000//一秒分多少份,这里1000表示时间单位为1毫秒,这个设置很重要 duration:1556rate:10000 表示1.0volume:100 表示最大声 reserved:0reserved[0]:0reserved[1]:0 Matric[0]:10000Matric[1]:0Matric[2]:0Matric[3]:0Matric[4]:10000 Matric[5]:0 Matric[6]:0Matric[7]:0Matric[8]:40000000 Predefined[0]:0Predefined[1]:0Predefined[2]:0Predefined[3]:0 Predefined[4]:0Predefined[5]:0next_track_ID:3 |
moov:trak: tkhd: |
这是track header 例1:00 00 00 5C 74 6B 68 64 00 00 00 0F 7C 25 B0 80 7C 25 B0 80 00 00 00 01 00 00 00 00 00 00 06 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 00 02 40 00 00 01 E0 00 00 语义: creation_time:2082844800modification_time:2082844800 track_ID:1 第一轨index, 这个值很重要, 直接决定了视频和音频是否能同时出现, 如果音频和视频的track_ID都是1, 则会导致播放器无法播放. reserved_1:0 duration:1544//这个值对播放器很重要, 具体时间还和mvhd的timescale相关,用来指定了时长,1544个时间单位,如果是毫秒为单位,则为1544毫秒, volume:0 //这是视频轨,无音响 reserved_2[0]:0reserved_2[1]:0 layer:0 //由于我们的视频只有一层,所以这里总是0 alternate_group:0 reserved_3:0 Matric[0]:10000Matric[1]:0Matric[2]:0Matric[3]:0Matric[4]:10000 Matric[5]:0Matric[6]:0Matric[7]:0Matric[8]:40000000 width:2400000 height:1e00000//这两个单位都要右移16位才靠谱 例2语义: creation_time:2082844800modification_time:2082844800 track_ID:2 reserved_1:0 duration:1556//这个值对播放器很重要, 用来指定了时长,具体时间还和mvhd的timescale相关 volume:100 //这是音频轨,最大声 reserved_2[0]:0reserved_2[1]:0 layer:0 //只对视频有意义 alternate_group:0 //总是0 reserved_3:0Matric[0]:10000Matric[1]:0Matric[2]:0Matric[3]:0 Matric[4]:10000Matric[5]:0Matric[6]:0Matric[7]:0Matric[8]:40000000 width:0 height:0 |
moov:trak: mdia: |
这个Box没有属性,是一个筐,装在trak里 |
moov:trak: mdia: mdhd |
例1:视频 creation_time:2082844800modification_time:2082844800 timescale:24000//这个位决定了播放的速度,不过他与duration的相乘后还是可以对应上面的mvhd设置 duration:37037 pad:0 Language[0]:21Language[1]:14Language[2]:4 pre_defined:0
例2:声频 creation_time:2082844800modification_time:2082844800 timescale:44100 duration:68608 pad:0//这个位无意义,是为了将后面language凑够16位之用 Language[0]:21Language[1]:14Language[2]:4 pre_defined:0 hdlr:handler 例1:视频 pre_defined:0 handler_type:vide //似乎除了handler_type以外,其余的属性无意义 reserved0reserved:0reserved:0 例2:声频 pre_defined:0 handler_type:soun reserved:0reserved:0reserved:0
|
moov:trak: mdia: minf: vmhd |
Video media header 例: graphicsmode:0//Video轨的合成模式,未知语义 opcolor:0opcolor:0opcolor:0//同样未知 |
moov:trak: mdia: minf: dinf: dref |
Data referrence 例: entry_count:1//只有一条Entry url://即使有也是没内容,测试文件无论音视都没有内容 |
moov:trak: mdia: minf: stbl: stsd |
stsd: Sample Description box 这是一个table, 里面放有很多entry 例:entry_count:1 //视频,有一条entry VisualSampleEntry: stsd里装的一条一条的视频entry, 例: data_reference_index:1 pre_defined[0]:0 pre_defined[1]:0pre_defined[2]:0 width:576 height:480 horizresolution:480000 vertresolution:480000//常数,即72dpi reserved:0 frame_count:1compressorname://无 depth:24//颜色深度 pre_defined:-1 AudioSampleEntry: stsd里装的一条一条音频entry 例:reserved[0]:0reserved[1]:0 channelcount:2 samplesize:16 pre_defined:0 reserved_2:0 samplerate:ac440000//显然要右移16位才有意义 |
moov:trak: mdia: minf: stbl: stsd :mp4a |
mp4a: aac box 这个box实际就是继承了audio sample entry box reserved[0]:0reserved[1]:0 channelcount:2 samplesize:16 pre_defined:0 reserved_2:0 samplerate:56220000 |
moov:trak: mdia: minf: stbl: stsd : esds |
esds: 包含在mp4a里, length:3 ES_ID:6400 streamDependenceFlag:0 URL_Flag=0reserved=0 streamPriority:1 streamDependenceFlag:0 dependsOn_ES_ID:52685 m_iData_Size:23//data的长度,算出来的 Data[23]//这里面有很一堆不知所云的数据, 一直到stts,但这堆数据极度重要,直接决定了解码器能否解码,在14496-1里有定义 //实践证明: 这组数据与采样率有关,44100一组, 22050一组, 48000又是一组, 44100可以与48000共用一组 |
moov:trak: mdia: minf: stbl: stts |
stts: Time to 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//同上 |
moov:trak: mdia: minf: stbl: stss |
stss: syn Sample box 例1: 视频 entry_count:1 sample_number:1 但音频里没有这个box, 这个Box非常重要, 决定了整个mp4文件是否可以拖拉, 如果这个box只有一个entry,则拖拉时将cpu达到100%, 如果这个box不存在, 可以拖拉, 也不会达到100%, 但是会略等一会, 通常做法可以搞100条. |
moov:trak: mdia: minf: stbl: stsc |
stsc: Sample To Chunk Box 这个box非常重要,指示了在某一个chunk开始后面的chunks里每chunk有多少个sample, 一个sample就是一帧 例1:视频 entry_count:1 first chunk: 1, sample per chunk: 1, sample description index 1 例2:音频 entry_count:1 first chunk: 1, sample per chunk: 1, sample description index 1 |
moov:trak: mdia: minf: stbl: stsz |
stsz: Sample Size Box, 这个box乃重中之重, 指示了每个sample的大小 例1:视频 sample size: 0sample count: 37 5127855830232727422373271623653061 217018882427257822182084213823192586 272823223505262415512725250220721720 138226532177132314921801176519855028 3467 例2:音频 sample size: 0sample count: 65 219205207182213194195194212 188159179186189184184190188 190186195196182197182186182 182185182193186184187175173 170185171181178178185192188 187175167177182167173177175 176174170168169180164167176 170 mdat Box中被划分为很多个chunk,这里指出了每个chunk的大小. |
moov:trak: mdia: minf: stbl: stco |
stco: Chunk Offset Box,这也是最重要的box, 指示了每个chunk的开始位置 例1: 视频 entry_count:37 0x240x15d30x1aaf0x1f840x2a200x35aa0x404a0x4c530x5705 0x64700x6da60x767c0x81740x8d000x97250xa0030xa9c90xb447 0xbfdc0xcbf70xd5b80xe4c00xf0640xf7da0x103ea 0x10e70 0x117ff 0x1200d 0x126da0x1328b 0x13bbd 0x14247 0x14973 0x151cd 0x15a0a 0x16272 0x17770
例2:音频 entry_count:65 0x142b0x15060x192a0x19f90x1ded0x1ec20x289b0x295e 0x34d60x3eef0x3fab0x4ae60x4b990x55900x564d0x62fa 0x63b20x6cea0x75060x75be0x7ff70x80b10x8b860x8c4a 0x95aa0x966f0x9f490xa85d0xa9130xb2d80xb3910xbe61 0xbf220xca840xcb3c0xd5090xe3690xe4160xef000xefb9 0xf6730xf7280x1027f 0x10331 0x10db0 0x11688 0x11744 0x11eb7 0x11f66 0x12573 0x12624 0x13137 0x131de 0x13b0c 0x140e8 0x14197 0x1481b 0x148c90x1507c 0x15124 0x158b2 0x15966 0x161cb 0x17616 0x176c6 |
moov:trak: mdia: minf: stbl: smhd |
smhd: sound media header 例: balance:0 reserved:0 暂时未知语义
|
avcC: AVC descriptor box |
avcC: AVC descriptor box非常重要, SPS PPS 都放这 在14496-15定义 例: configurationVersion:1AVCProfileIndication:66 profile_compatibility:192AVCLevelIndication;31 reserved_1:63lengthSizeMinusOne:3 reserved_2:7 numOfSequenceParameterSets:1 numOfPictureParameterSets:1 SPS length: 24//第一个SPS的长度, 多个SPS可以继续往下 PPS length: 4//第一个PPS的长度, 多个PPS可以继续往下 aligned(8) class AVCDecoderConfigurationRecord { unsigned int(8) configurationVersion = 1; unsigned int(8) AVCProfileIndication; unsigned int(8) profile_compatibility; unsigned int(8) AVCLevelIndication; bit(6) reserved = ‘111111’b; unsigned int(2) lengthSizeMinusOne; bit(3) reserved = ‘111’b; unsigned int(5) numOfSequenceParameterSets; for (i=0; i< numOfSequenceParameterSets; i++) { unsigned int(16) sequenceParameterSetLength ; bit(8*sequenceParameterSetLength) sequenceParameterSetNALUnit; } unsigned int(8) numOfPictureParameterSets; for (i=0; i< numOfPictureParameterSets; i++) { unsigned int(16) pictureParameterSetLength; bit(8*pictureParameterSetLength) pictureParameterSetNALUnit; } } 见http://www.nhzjj.com/asp/admin/editor/newsfile/201011314552121.pdf |
btrt: bit rate box |
btrt: bit rate box bufferSizeDB:7858//告诉decoder开辟缓冲区大小? maxBitrate:413432//最大Bit rate avgBitrate:371960//平均Bit rate |
avc1 |
class AVCSampleEntry() extends VisualSampleEntry (‘avc1’){ AVCConfigurationBox config; MPEG4BitRateBox (); // optional MPEG4ExtensionDescriptorsBox (); // optional } class AVCConfigurationBox extends Box(‘avcC’) { AVCDecoderConfigurationRecord() AVCConfig; } class MPEG4BitRateBox extends Box(‘btrt’){ unsigned int(32) bufferSizeDB; unsigned int(32) maxBitrate; unsigned int(32) avgBitrate; } class MPEG4ExtensionDescriptorsBox extends Box(‘m4ds’) { Descriptor Descr[0 .. 255]; } |
:
Trouble shooting
1, 播放速度不正常, 哪个参数可调?
mdhd->timescale, 数字越大, 则播放速度越快
2, 拖拉不正常, 哪个Box可调?
stss, 如果只有一条entry, 则拖拉会产生cpu 100%的情况. 如果没有entry, 则拖拉会略有停顿
3, 音频,视频分别整合成mp4文件可以播放, 但音频,视频都整合进mp4文件以后就无法播放.
trak->track_id, 两轨可能都用同一ID, 则不成. 视频为1, 音频为2,则可以解决这个问题
其实以上文章只是个简单的翻译,详细的文档可参考:
ISO_IEC14496-12_2005(E)
Information technology — Coding of
audio-visual objects —
Part 12:
ISO base media file format
Technologies de l'information — Codage des objets audiovisuels —
Partie 12: Format ISO de base pour les fichiers médias
ISO_IEC14496-14_2003(E)
Information technology — Coding of
audio-visual objects —
Part 14:
MP4 file format
Technologies de l'information — Codage des objets audiovisuels —
Partie 14: Format de fichier MP4
网上比较难于下载到,有需要的朋友可以email:[email protected] 找我索要。