?
一.mp4文件的組織
1. mp4文件的box(ffmpeg中叫atom)
mp4是由一系列的box組成的,每個box的header是8個字節(4字節的長度,4字節的type)
第一個box比較特殊,其type類型為ftyp,還包含一個sub-type
0000000:?0000 0020 6674 7970 6973 6f6d 0000 0200?...?ftypisom....
0000010:?6973 6f6d 6973 6f32 6176 6331 6d70 3431 isomiso2avc1mp41
0000020:?0000 0008 6672 6565?0609 6f8e 6d64 6174?....free..o.mdat
0000030:?0000 028c 0605 ffff 88dc 45e9 bde6 d948?..........E....H
0000040:?b796 2cd8 20d9 23ee ef78 3236 3420 2d20?..,.?.#..x264?-?
0000050:?636f 7265 2031 3030 202d 2048 2e32 3634 core 100?-?H.264?
0000060:?2f4d 5045 472d 3420 4156 4320 636f 6465?/MPEG-4 AVC code
0000 0020 6674 7970??--> 第1個box的長度為0x20, type=ftyp
6973 6f6d ?-->其sub-type=isom
0000 0008 6672 6565??--> 第2個box的長度為0x08, type=free
0609 6f8e 6d64 6174 ? --> 第3個box的長度為0x06096F8E, type=mdat
由此可以看出第4個box:
0x06096F8E+0x08+0x20=0x06096FB6處是第4個box
000c ca81 6d6f 6f76 ? ?--> 第4個box的長度是0x0cca81, type=moov
?
1.2 計算文件的大小
所以整個文件的大小為?0x20+0x08+0x0x06096F8E+0x0cca81=0x6163A37=102119991
cong@msi:/work/ffmpeg/ffmpeg-3.0.1$ ls -l ../san.mp4
-rw-rw-r-- 1 cong cong 102119991 Sep 10 ?2015 ../san.mp4
1.3?關于box-type:
box-type可以是如下一個:
"ftyp",?"mdat",?"moov",?"pnot",?"udta",?"uuid",?"moof",?"free",?"skip",?"jP2 ",?"wide",?"load",?"ctab",?"imap",?"matt",?"kmat",?"clip",?"crgn",?"sync",?"chap",?"tmcd",?"scpt",?"ssrc",?"PICT".
sub-type可以取如下一個:
sub-type which must be one of values:?"avc1",?"iso2",?"isom",?"mmp4",?"mp41",?"mp42",?"mp71",?"msnv",?"ndas",?"ndsc",?"ndsh",?"ndsm",?"ndsp",?"ndss",?"ndxc","ndxh",?"ndxm",?"ndxp",?"ndxs".
?
1.4總結
一個mov文件就是由ftyp free mdat moov這四個部分組成
ftyp --> 格式
free --> 不關心
mdat --> 音視頻數據
moov --> 包含一系列次級box:一個mvhd及多個trak
?
1.5 如下圖所示:
清楚了
?
二. BOX的具體解析
2.1FileTypeBox--> ftype解析
0000000:?0000 0020 6674 7970 6973 6f6d 0000 0200?...?ftypisom....
0000010:?6973 6f6d 6973 6f32 6176 6331 6d70 3431 isomiso2avc1mp41
0000 0020 6674 7970??--> 第1個box的長度為0x20, type=ftyp
6973 6f6d ? ? ? ? ? ? ? ? ? ? --> major_brand: isom
0000 0200 ? ? ? ? ? ? ? ? ? ?--> minor_verion: isom的版本號
6973 6f6d 6973 6f32 6176 6331 6d70 3431--> 兼容isom iso2 avc1 mp41這四個協議
ISO14496-12 的 4.3.2 Syntax?
aligned(8)?class?FileTypeBox?extends Box(‘ftyp’)?{?unsigned?int(32)?major_brand;?unsigned?int(32)?minor_version;?unsigned?int(32)?compatible_brands[];?//?to?end?of the box?
}
沒有ftyp后面就不知道用什么去解析這個媒體文件
2.2?Free Space Box -->free解析
沒啥作用
ISO14496-12 的8.24.2 Syntax?
aligned(8)?class?FreeSpaceBox extends Box(free_type)?{?unsigned?int(8)?data[];?
}
2.3?Media Data Box -->mdat解析
這個box里面全部都是數據
ISO14496-12 的8.2.2 Syntax?
aligned(8)?class?MediaDataBox extends Box(‘mdat’)?{?bit(8)?data[];?
}
2.4?Movie Box ?-->moov解析 (很復雜)
6096fb0:?9002 1900 2380?000c ca81 6d6f 6f76?0000?....#.....moov..
6096fc0:?006c 6d76 6864 0000 0000 7c25 b080 7c25?.lmvhd....|%..|%
6096fd0:?b080 0000 03e8 0014 6995 0001 0000 0100?........i.......
6096fe0:?0000 0000 0000 0000 0000 0001 0000 0000?................
6096ff0:?0000 0000 0000 0000 0000 0001 0000 0000?................
6097000:?0000 0000 0000 0000 0000 4000 0000 0000?..........@.....
6097010:?0000 0000 0000 0000 0000 0000 0000 0000?................
6097020:?0000 0000 0000 0000 0003?0005 bf9d 7472?..............tr
6097030:?616b?0000 005c 746b 6864 0000 000f 7c25 ak...\tkhd....|%
6097040:?b080 7c25 b080 0000 0001 0000 0000 0014?..|%............
6097050:?6595 0000 0000 0000 0000 0000 0000 0000?e...............
6097060: 0000 0001 0000 0000 0000 0000 0000 0000 ?................
6097070: 0000 0001 0000 0000 0000 0000 0000 0000 ?................
6097080: 0000 4000 0000 01d6 0000 0160 0000?0000??..@........`....
6097090: 0024?6564 7473 0000 001c 656c 7374 0000 ?.$edts....elst..
60970a0: 0000?0000?0001 0014 6595 0000 03e9 0001 ?........e.......
60970b0: 0000?0005 bf15 6d64 6961 0000 0020 6d64 ?......mdia... md
000c ca81 6d6f 6f76 ? ?--> moov的長度是0x0cca81, type=moov
0000?006c 6d76 6864 ?-->?mvhd的長度是0x6c ? ?,type=mvhd
0000 0000 ? ? ? ? ? ? ? ? ? ?--> version=0x0
7c25 b080?7c25 b080 ?--> create_time=modify_time=0x7c25b080
0000 03e8????????????????? ? --> timescale=0x3e8=1000 ?
0014 6995 ?????????????? ? ? --> duration=0x146995(單位是time_units)
0001 0000 ? ? ? ? ? ? ? ? ? ?--> rate=0x00010000
0100 ? ? ? ? ? ? ? ? ? ? ? ? ? ? --> volume=0x0100
0005 bf9d 7472 616b? ?--> track的長度是0x5bf9d,type=trak
0000 005c 746b?6864 ?--> tkhd的長度是0x5c, type=tkhd
0000 ? ? ? ? ? ? ? ? ? ? ? ? ? ? -->version
000F ? ? ? ? ? ? ? ? ? ? ? ? ? ? --> flag
7c25 b080 7c25 b080 ?-->create_time=modify_time=0x7c25b080
0000 0001?????????????? ? ? ?--> trackID=1
0000 0000 ? ? ? ? ? ? ? ? ? ?--> reserve
0014 6595 ? ? ? ? ? ? ? ? ? ?--> duration=0x146595
0000 0000 ?????????????? ? ? -->?reserved
0000 0000 ?????????????? ? ??-->?reserved
0000 0000 ?????????????? ? ??-->?layer+group
0000?0000 ?????????????? ? ??-->?volum+resever
0001 0000 0000 0000 0000 0000 ? matrix
0000?0000 0001 0000 0000 0000?
0000 0000 0000 ?0000 4000 0000?
01d6 0000 0160 0000 ? -->??width=0x1d6?height=0x160(這兒都需要向右移16位)
0000?0024 6564 7473 ? -->edts的長度是0x24,type=edts
注意:?
a.媒體文件在播放過程中用的時間單位,是由timescale計算出來的
一個time units=1s/timescale=1ms,這兒1 time_unts=1ms
b.通過duration可計算媒體的播放時間 0x146995*1ms=1337749ms=1337.749s,對上了
附1.mvhd
ISO14496-12 的8.3.2 Syntax?
aligned(8)?class?MovieHeaderBox extends FullBox(‘mvhd’,?version,?0)?{?
if?(version==1)?{?unsigned?int(64)?creation_time;?unsigned?int(64)?modification_time;?unsigned?int(32)?timescale;?unsigned?int(64)?duration;?
}?else?{?//?version==0?unsigned?int(32)?creation_time;?unsigned?int(32)?modification_time;?unsigned?int(32)?timescale;?unsigned?int(32)?duration;?
}?
template?int(32)?rate?=?0x00010000;?//?typically 1.0?
template?int(16)?volume?=?0x0100;?//?typically,?full volume?
const?bit(16)?reserved?=?0;?
const?unsigned?int(32)[2]?reserved?=?0;?
template?int(32)[9]?matrix?=?{?0x00010000,0,0,0,0x00010000,0,0,0,0x40000000?};?
//?Unity matrix?
bit(32)[6]?pre_defined?=?0;?
unsigned?int(32)?next_track_ID;?
}
附2.trak
?
8.5.2 Syntax aligned(8)?class?TrackHeaderBox?
extends FullBox(‘tkhd’,?version,?flags){?if?(version==1)?{?unsigned?int(64)?creation_time;?unsigned?int(64)?modification_time;?unsigned?int(32)?track_ID;?const?unsigned?int(32)?reserved?=?0;?unsigned?int(64)?duration;?}?else?{?//?version==0?unsigned?int(32)?creation_time;?unsigned?int(32)?modification_time;?unsigned?int(32)?track_ID;?const?unsigned?int(32)?reserved?=?0;?unsigned?int(32)?duration;?}?const?unsigned?int(32)[2]?reserved?=?0;?template?int(16)?layer?=?0;?template?int(16)?alternate_group?=?0;?template?int(16)?volume?=?{if?track_is_audio 0x0100?else?0};?const?unsigned?int(16)?reserved?=?0;?template?int(32)[9]?matrix=?{?0x00010000,0,0,0,0x00010000,0,0,0,0x40000000?};?//?unity matrix?unsigned?int(32)?width;?unsigned?int(32)?height;?
}
?
三.ffmpeg中對mp4的處理
3.1 對mp4文件的probe -->?在libavformat/mov.c中
有兩個宏需要關注一下:
#define MKTAG(a,b,c,d)?((a)?|?((b)?<<?8)?|?((c)?<<?16)?|?((unsigned)(d)?<<?24))# define AV_RL32(x)?\(((uint32_t)((const?uint8_t*)(x))[3]?<<?24)?|?\(((const?uint8_t*)(x))[2]?<<?16)?|?\(((const?uint8_t*)(x))[1]?<<?8)?|?\((const?uint8_t*)(x))[0])
這兩個宏都是把4個char組成一個int
3.2 mov_probe
static?int?mov_probe(AVProbeData?*p)
{int64_t offset;uint32_t tag;int?score?=?0;int?moov_offset?=?-1;dbmsg();/*?check file header?*/offset?=?0;for?(;;)?{tag?=?AV_RL32(p->buf?+?offset?+?4); ? ?//將p->buf+4即‘f’ ‘t’ 'y' 'p'組成一個intswitch(tag)?{ ? ? ? ? ? ? ? ? ? ? ? ? ?//判斷這個int是不是ftypcase?MKTAG('f','t','y','p'):score?=?AVPROBE_SCORE_MAX; ? ??//如果是的話score=100,說明就是mov格式的文件break;}}return score;
}
精簡一下mov_probe,其實就是判斷第一個box是不是ftyp,若是則就是mov格式的了。
3.3.1 對ftype的讀取
static?int?mov_read_ftyp(MOVContext?*c,?AVIOContext?*pb,?MOVAtom atom)
{//讀4個字節的major_brand,并存到dict中ffio_read_size(pb,?type,?4);av_dict_set(&c->fc->metadata,?"major_brand",?type,?0);//讀4個字節的minor_ver,并存到dict中minor_ver?=?avio_rb32(pb);av_dict_set_int(&c->fc->metadata,?"minor_version",?minor_ver,?0);//讀剩余的字節,即comp_brands_str,并存到dict中comp_brand_size?=?atom.size?-?8;? ??//atom.size己經是去除8字節頭,余下的sizeffio_read_size(pb,?comp_brands_str,?comp_brand_size);comp_brands_str[comp_brand_size]?=?0;av_dict_set(&c->fc->metadata,?"compatible_brands",?comp_brands_str,?0);return 0;
}
3.3.2 對free的讀取
static?int?mov_read_free(MOVContext?*c,?AVIOContext?*pb,?MOVAtom atom)
{//沒什么作用,只是讀取出來,把文件指針指向下一下box而己avio_read(pb,?content,?FFMIN(sizeof(content),?atom.size));return 0;
}
3.3.3對mdat的讀取
static?int?mov_read_mdat(MOVContext?*c,?AVIOContext?*pb,?MOVAtom atom)
{//mdat更簡單,只把標志設置了一下c->found_mdat=1;return 0;?/*?now?go?for?moov?*/
}
3.3.4對moov的讀取
?
三.附錄: ISO/IEC 14496 MPEG的協議標準
轉自:?http://blog.csdn.net/yu_yuan_1314/article/details/9406587
- ISO/IEC 14496是MPEG專家組制定的MPEG-4標準于1998年10月公布第1版,1999年1月成為國際標準,1999年12月公布了第2版,2000年初成為國際標準。
- 全文分為27個部分:
- (1)ISO/IEC 14496-1系統部分,描述視頻和音頻數據流的控制、同步以及混合方式(即混流 Multiplexing,簡寫為MUX)。
- (2)ISO/IEC 14496-2視頻部分,定義了一個對各種視覺信息(包括自然視頻、靜止紋理、計算機合成圖形等等)的編解碼器。(例如XviD編碼就屬于MPEG-4 Part 2)。
- (3)ISO/IEC 14496-3音頻部分,定義了一個對各種音頻信號進行編碼的編解碼器的集合。包括高級音頻編碼(Advanced Audio Coding,縮寫為AAC)的若干變形和其他一些音頻/語音編碼工具。
- (4)ISO/IEC 14496-4一致性部分,定義了比特流和設備的一致性條件,用來測試MPEG-4的實現。
- (5)ISO/IEC 14496-5參考軟件,提供了用于演示功能和說明本標準其他部分功能的軟件。
- (6)ISO/IEC 14496-6多媒體傳送整體框架DMIF,這是MPEG-4應用層與傳輸網絡的接口,定義了通信協議,使MPEG-4系統的數據流能進入各種傳輸網絡。還包含一個存儲格式MP4,用于存儲編碼的場景。
- (7)?ISO/IEC 14496-7優化的參考軟件,提供了對實現進行優化的例子(這里的實現指的是第五部分)。
- (8)ISO/IEC 14496-8在IP網絡上傳輸,定義了在IP網絡上傳輸MPEG-4內容的方式。
- (9)ISO/IEC 14496-9參考硬件描述,提供了用于演示怎樣在硬件上實現本標準其他部分功能的硬件設計方案
- (10)ISO/IEC 14496-10高級視頻編碼AVC,定義了一個視頻編解碼器(codec)。AVC和XviD都屬于MPEG-4編碼,但由于AVC屬于MPEG-4 Part 10,在技術特性上比屬于MPEG-4 Part2的XviD要先進。另外,它和ITU-T H.264標準是一致的,故又稱為H.264。
- (11)ISO/IEC 14496-11場景描述和應用引擎。
- (12)ISO/IEC 14496-12ISO媒體文件格式,定義了一個存儲媒體內容的文件格式。
- (13)ISO/IEC 14496-13知識產權管理和保護(IPMP:Intellectual?Property?Management?and?Protection)擴展。
- (14)ISO/IEC 14496-14MP4文件格式,定義了基于第十二部分的用于存儲MPEG-4內容的容器文件格式。
- (15)ISO/IEC 14496-15AVC文件格式,定義了基于第十二部分的用于存儲第十部分的視頻內容的文件格式。
- (16)ISO/IEC 14496-16動畫框架擴展AFX(Animation Framework eXtension)。
- (17)ISO/IEC 14496-17同步文本字幕格式。
- (18)ISO/IEC 14496-18字體壓縮和流式傳輸(針對公開字體格式)。
- (19)ISO/IEC 14496-19合成材質流(Synthesized Texture Stream)。
- (20)ISO/IEC 14496-20簡單場景表示(LASeR?for?Lightweight Scene Representation)。
- (21)ISO/IEC 14496-21用于描繪(Rendering)的MPEG-J拓展。
- (22)ISO/IEC 14496-22開放字體格式(Open Font Format)。
- (23)ISO/IEC 14496-2符號化音樂表示(Symbolic Music Representation)。
- (24)ISO/IEC 14496-24音頻與系統交互作用(Audio?and?systems interaction)。
- (25)ISO/IEC 14496-253D圖形壓縮模型(3D Graphics Compression Model)。
- (26)ISO/IEC 14496-26音頻一致性檢查:定義了測試音頻數據與ISO/IEC 14496-3是否一致的方法(Audio conformance)。
- (27)ISO/IEC 14496-273D圖形一致性檢查:定義了測試3D圖形數據與ISO/IEC 14496-11:2005,?ISO/IEC 14496-16:2006,?ISO/IEC 14496-21:2006,?和 ISO/IEC 14496-25:2009是否一致的方法(3D Graphics conformance)。