mp4文件格式解析(轉(zhuǎn))

原文鏈接:?

http://blog.sina.com.cn/s/blog_48f93b530100jz4x.html

https://www.cnblogs.com/ranson7zop/p/7889272.html


目前MP4的概念被炒得很火,也很亂。最開始MP4指的是音頻(MP3的升級版),即MPEG-2 AAC標準。隨后MP4概念被轉(zhuǎn)移到視頻上,對應(yīng)的是MPEG-4標準。而現(xiàn)在我們流行的叫法,多半是指能播放MPEG-4標準編碼格式視頻的播放器。但是這篇文章介紹的內(nèi)容跟上面這些都無關(guān),我們要討論的是MP4文件封裝格式,對應(yīng)的標準為ISO/IEC 14496-12,即信息技術(shù)?視聽對象編碼的第12部分:ISO?基本媒體文件格式(Information technology Coding of audio-visual objects Part 12: ISO base media file format)。ISO/IEC組織指定的標準一般用數(shù)字表示,ISO/IEC 14496即MPEG-4標準。

MP4視頻文件封裝格式是基于QuickTime容器格式定義的,因此參考QuickTime的格式定義對理解MP4文件格式很有幫助。MP4文件格式是一個十分開放的容器,幾乎可以用來描述所有的媒體結(jié)構(gòu),MP4文件中的媒體描述與媒體數(shù)據(jù)是分開的,并且媒體數(shù)據(jù)的組織也很自由,不一定要按照時間順序排列,甚至媒體數(shù)據(jù)可以直接引用其他文件。同時,MP4也支持流媒體。MP4目前被廣泛用于封裝h.264視頻和AAC音頻,是高清視頻的代表。


????現(xiàn)在我們就來看看MP4文件格式到底是什么樣的。

1、概述

????MP4文件中的所有數(shù)據(jù)都裝在box(QuickTime中為atom)中,也就是說MP4文件由若干個box組成,每個box有類型和長度,可以將box理解為一個數(shù)據(jù)對象塊。box中可以包含另一個box,這種box稱為container box。一個MP4文件首先會有且只有一個“ftyp”類型的box,作為MP4格式的標志并包含關(guān)于文件的一些信息;之后會有且只有一個“moov”類型的box(Movie Box),它是一種container box,子box包含了媒體的metadata信息;MP4文件的媒體數(shù)據(jù)包含在“mdat”類型的box(Midia Data Box)中,該類型的box也是container box,可以有多個,也可以沒有(當(dāng)媒體數(shù)據(jù)全部引用其他文件時),媒體數(shù)據(jù)的結(jié)構(gòu)由metadata進行描述。

????下面是一些概念:

track表示一些sample的集合,對于媒體數(shù)據(jù)來說,track表示一個視頻或音頻序列。

hint track這個特殊的track并不包含媒體數(shù)據(jù),而是包含了一些將其他數(shù)據(jù)track打包成流媒體的指示信息。

sample對于非hint track來說,video sample即為一幀視頻,或一組連續(xù)視頻幀,audio sample即為一段連續(xù)的壓縮音頻,它們統(tǒng)稱sample。對于hint track,sample定義一個或多個流媒體包的格式。

sample table指明sampe時序和物理布局的表。

chunk一個track的幾個sample組成的單元。

????在本文中,我們不討論涉及hint的內(nèi)容,只關(guān)注包含媒體數(shù)據(jù)的本地MP4文件。下圖為一個典型的MP4文件的結(jié)構(gòu)樹。


2、Box

???????首先需要說明的是,box中的字節(jié)序為網(wǎng)絡(luò)字節(jié)序,也就是大端字節(jié)序(Big-Endian),簡單的說,就是一個32位的4字節(jié)整數(shù)存儲方式為高位字節(jié)在內(nèi)存的低端。Box由header和body組成,其中header統(tǒng)一指明box的大小和類型,body根據(jù)類型有不同的意義和格式。

???????標準的box開頭的4個字節(jié)(32位)為box size,該大小包括box header和box body整個box的大小,這樣我們就可以在文件中定位各個box。如果size為1,則表示這個box的大小為large size,真正的size值要在largesize域上得到。(實際上只有“mdat”類型的box才有可能用到large size。)如果size為0,表示該box為文件的最后一個box,文件結(jié)尾即為該box結(jié)尾。(同樣只存在于“mdat”類型的box中。)

???????size后面緊跟的32位為box type,一般是4個字符,如“ftyp”、“moov”等,這些box type都是已經(jīng)預(yù)定義好的,分別表示固定的意義。如果是“uuid”,表示該box為用戶擴展類型。如果box type是未定義的,應(yīng)該將其忽略。

3、File Type Box(ftyp)

????該box有且只有1個,并且只能被包含在文件層,而不能被其他box包含。該box應(yīng)該被放在文件的最開始,指示該MP4文件應(yīng)用的相關(guān)信息。

????“ftyp” body依次包括1個32位的major brand(4個字符),1個32位的minor version(整數(shù))和1個以32位(4個字符)為單位元素的數(shù)組compatible brands。這些都是用來指示文件應(yīng)用級別的信息。該box的字節(jié)實例如下:

4、Movie Box(moov)

????該box包含了文件媒體的metadata信息,“moov”是一個container box,具體內(nèi)容信息由子box詮釋。同F(xiàn)ile Type Box一樣,該box有且只有一個,且只被包含在文件層。一般情況下,“moov”會緊隨“ftyp”出現(xiàn)。

????一般情況下(限于篇幅,本文只講解常見的MP4文件結(jié)構(gòu)),“moov”中會包含1個“mvhd”和若干個“trak”。其中“mvhd”為header box,一般作為“moov”的第一個子box出現(xiàn)(對于其他container box來說,header box都應(yīng)作為首個子box出現(xiàn))?!皌rak”包含了一個track的相關(guān)信息,是一個container box。下圖為部分“moov”的字節(jié)實例,其中紅色部分為box header,綠色為“mvhd”,黃色為一部分“trak”。

4.1 Movie Header Box(mvhd)

“mvhd”結(jié)構(gòu)如下表。


字段字節(jié)數(shù)意義

box size4box大小

box type4box類型

version1box版本,0或1,一般為0。(以下字節(jié)數(shù)均按version=0)

flags3?

creation time4創(chuàng)建時間(相對于UTC時間1904-01-01零點的秒數(shù))

modification time4修改時間

time scale4文件媒體在1秒時間內(nèi)的刻度值,可以理解為1秒長度的時間單元數(shù)

duration4該track的時間長度,用duration和time scale值可以計算track時長,比如audio track的time scale = 8000, duration = 560128,時長為70.016,video track的time scale = 600, duration = 42000,時長為70

rate4推薦播放速率,高16位和低16位分別為小數(shù)點整數(shù)部分和小數(shù)部分,即[16.16] 格式,該值為1.0(0x00010000)表示正常前向播放

volume2與rate類似,[8.8] 格式,1.0(0x0100)表示最大音量

reserved10保留位

matrix36視頻變換矩陣

pre-defined24?

next track id4下一個track使用的id號



“mvhd”的字節(jié)實例如下圖,各字段已經(jīng)用顏色區(qū)分開:

4.2 Track Box(trak)

????“trak”也是一個container box,其子box包含了該track的媒體數(shù)據(jù)引用和描述(hint track除外)。一個MP4文件中的媒體可以包含多個track,且至少有一個track,這些track之間彼此獨立,有自己的時間和空間信息?!皌rak”必須包含一個“tkhd”和一個“mdia”,此外還有很多可選的box(略)。其中“tkhd”為track header box,“mdia”為media box,該box是一個包含一些track媒體數(shù)據(jù)信息box的container box。

????“trak”的部分字節(jié)實例如下圖,其中黃色為“trak”box的頭,綠色為“tkhd”,藍色為“edts”(一個可選box),紅色為一部分“mdia”。


4.2.1 Track Header Box(tkhd)

“tkhd”結(jié)構(gòu)如下表。?

字段字節(jié)數(shù)意義

box size4box大小

box type4box類型

version1box版本,0或1,一般為0。(以下字節(jié)數(shù)均按version=0)

flags3按位或操作結(jié)果值,預(yù)定義如下:

0x000001 track_enabled,否則該track不被播放;

0x000002 track_in_movie,表示該track在播放中被引用;

0x000004 track_in_preview,表示該track在預(yù)覽時被引用。

一般該值為7,如果一個媒體所有track均未設(shè)置track_in_movie和track_in_preview,將被理解為所有track均設(shè)置了這兩項;對于hint track,該值為0

creation time4創(chuàng)建時間(相對于UTC時間1904-01-01零點的秒數(shù))

modification time4修改時間

track id4id號,不能重復(fù)且不能為0

reserved4保留位

duration4track的時間長度

reserved8保留位

layer2視頻層,默認為0,值小的在上層

alternate group2track分組信息,默認為0表示該track未與其他track有群組關(guān)系

volume2[8.8] 格式,如果為音頻track,1.0(0x0100)表示最大音量;否則為0

reserved2保留位

matrix36視頻變換矩陣

width4寬

height4高,均為 [16.16] 格式值,與sample描述中的實際畫面大小比值,用于播放時的展示寬高



“tkhd”的字節(jié)實例如下圖,各字段已經(jīng)用顏色區(qū)分開:

4.2.2 Media Box(mdia)

“mdia”也是個container box,其子box的結(jié)構(gòu)和種類還是比較復(fù)雜的。先來看一個“mdia”的實例結(jié)構(gòu)樹圖。

總體來說,“mdia”定義了track媒體類型以及sample數(shù)據(jù),描述sample信息。一般“mdia”包含一個“mdhd”,一個“hdlr”和一個“minf”,其中“mdhd”為media header box,“hdlr”為handler reference box,“minf”為media information box。下面依次看一下這幾個box的結(jié)構(gòu)。

4.2.2.1 Media Header Box(mdhd)

“mdhd”結(jié)構(gòu)如下表。?

字段字節(jié)數(shù)意義

box size4box大小

box type4box類型

version1box版本,0或1,一般為0。(以下字節(jié)數(shù)均按version=0)

flags3?

creation time4創(chuàng)建時間(相對于UTC時間1904-01-01零點的秒數(shù))

modification time4修改時間

time scale4同前表

duration4track的時間長度

language2媒體語言碼。最高位為0,后面15位為3個字符(見ISO 639-2/T標準中定義)

pre-defined2?


“mdhd”的字節(jié)實例如下圖,各字段已經(jīng)用顏色區(qū)分開:

4.2.2.2 Handler Reference Box(hdlr)

“hdlr”解釋了媒體的播放過程信息,該box也可以被包含在meta box(meta)中?!癶dlr”結(jié)構(gòu)如下表。


字段字節(jié)數(shù)意義

box size4box大小

box type4box類型

version1box版本,0或1,一般為0。(以下字節(jié)數(shù)均按version=0)

flags3?

pre-defined4?

handler type4在media box中,該值為4個字符:

“vide”— video track

“soun”— audio track

“hint”— hint track

reserved12?

name不定track type name,以‘\0’結(jié)尾的字符串


“hdlr”的字節(jié)實例如下圖,各字段已經(jīng)用顏色區(qū)分開:

4.2.2.3 Media Information Box(minf)

????“minf”存儲了解釋track媒體數(shù)據(jù)的handler-specific信息,media handler用這些信息將媒體時間映射到媒體數(shù)據(jù)并進行處理?!癿inf”中的信息格式和內(nèi)容與媒體類型以及解釋媒體數(shù)據(jù)的media handler密切相關(guān),其他media handler不知道如何解釋這些信息。“minf”是一個container box,其實際內(nèi)容由子box說明。

????一般情況下,“minf”包含一個header box,一個“dinf”和一個“stbl”,其中,header box根據(jù)track type(即media handler type)分為“vmhd”、“smhd”、“hmhd”和“nmhd”,“dinf”為data information box,“stbl”為sample table box。下面分別介紹。

????下圖為“minf”部分字節(jié)實例,其中紅色為box header,藍色為“smhd”,綠色為“dinf”,黃色為一部分“stbl”。


4.2.2.3.1 Media Information Header Box(vmhd、smhd、hmhd、nmhd)

Video Media Header Box(vmhd)

字段字節(jié)數(shù)意義

box size4box大小

box type4box類型

version1box版本,0或1,一般為0。(以下字節(jié)數(shù)均按version=0)

flags3?

graphics mode4視頻合成模式,為0時拷貝原始圖像,否則與opcolor進行合成

opcolor2×3{red,green,blue}


Sound Media Header Box(smhd)

字段字節(jié)數(shù)意義

box size4box大小

box type4box類型

version1box版本,0或1,一般為0。(以下字節(jié)數(shù)均按version=0)

flags3?

balance2立體聲平衡,[8.8] 格式值,一般為0,-1.0表示全部左聲道,1.0表示全部右聲道

reserved2?


Hint Media Header Box(hmhd)

????略

Null Media Header Box(nmhd)

????非視音頻媒體使用該box,略。

4.2.2.3.2 Data Information Box(dinf)

????“dinf”解釋如何定位媒體信息,是一個container box。“dinf”一般包含一個“dref”,即data reference box;“dref”下會包含若干個“url”或“urn”,這些box組成一個表,用來定位track數(shù)據(jù)。簡單的說,track可以被分成若干段,每一段都可以根據(jù)“url”或“urn”指向的地址來獲取數(shù)據(jù),sample描述中會用這些片段的序號將這些片段組成一個完整的track。一般情況下,當(dāng)數(shù)據(jù)被完全包含在文件中時,“url”或“urn”中的定位字符串是空的。

????“dref”的字節(jié)結(jié)構(gòu)如下表。?

字段字節(jié)數(shù)意義

box size4box大小

box type4box類型

version1box版本,0或1,一般為0。(以下字節(jié)數(shù)均按version=0)

flags3?

entry count4“url”或“urn”表的元素個數(shù)

“url”或“urn”列表不定?


“url”或“urn”都是box,“url”的內(nèi)容為字符串(location string),“urn”的內(nèi)容為一對字符串(name string and location string)。當(dāng)“url”或“urn”的box flag為1時,字符串均為空。

下面是一個“dinf”的字節(jié)實例圖。其中黃色為“dinf”的box header,由紅色部分我們知道包含的“url”或“urn”個數(shù)為1,紅色后面為“url”box的內(nèi)容。紫色為“url”的box header(根據(jù)box type我們知道是個“url”),綠色為box flag,值為1,說明“url”中的字符串為空,表示track數(shù)據(jù)已包含在文件中。

4.2.2.3.3 Sample Table Box(stbl)

“stbl”幾乎是普通的MP4文件中最復(fù)雜的一個box了,首先需要回憶一下sample的概念。sample是媒體數(shù)據(jù)存儲的單位,存儲在media的chunk中,chunk和sample的長度均可互不相同,如下圖所示。

????“stbl”包含了關(guān)于track中sample所有時間和位置的信息,以及sample的編解碼等信息。利用這個表,可以解釋sample的時序、類型、大小以及在各自存儲容器中的位置?!皊tbl”是一個container box,其子box包括:sample description box(stsd)、time to sample box(stts)、sample size box(stsz或stz2)、sample to chunk box(stsc)、chunk offset box(stco或co64)、composition time to sample box(ctts)、sync sample box(stss)等。

????“stsd”必不可少,且至少包含一個條目,該box包含了data reference box進行sample數(shù)據(jù)檢索的信息。沒有“stsd”就無法計算media sample的存儲位置?!皊tsd”包含了編碼的信息,其存儲的信息隨媒體類型不同而不同。

Sample Description Box(stsd)

????box header和version字段后會有一個entry count字段,根據(jù)entry的個數(shù),每個entry會有type信息,如“vide”、“sund”等,根據(jù)type不同sample description會提供不同的信息,例如對于video track,會有“VisualSampleEntry”類型信息,對于audio track會有“AudioSampleEntry”類型信息。

????視頻的編碼類型、寬高、長度,音頻的聲道、采樣等信息都會出現(xiàn)在這個box中。

Time To Sample Box(stts)

????“stts”存儲了sample的duration,描述了sample時序的映射方法,我們通過它可以找到任何時間的sample?!皊tts”可以包含一個壓縮的表來映射時間和sample序號,用其他的表來提供每個sample的長度和指針。表中每個條目提供了在同一個時間偏移量里面連續(xù)的sample序號,以及samples的偏移量。遞增這些偏移量,就可以建立一個完整的time to sample表。

Sample Size Box(stsz)

????“stsz” 定義了每個sample的大小,包含了媒體中全部sample的數(shù)目和一張給出每個sample大小的表。這個box相對來說體積是比較大的。

Sample To Chunk Box(stsc)

????用chunk組織sample可以方便優(yōu)化數(shù)據(jù)獲取,一個thunk包含一個或多個sample?!皊tsc”中用一個表描述了sample與chunk的映射關(guān)系,查看這張表就可以找到包含指定sample的thunk,從而找到這個sample。

Sync Sample Box(stss)

????“stss”確定media中的關(guān)鍵幀。對于壓縮媒體數(shù)據(jù),關(guān)鍵幀是一系列壓縮序列的開始幀,其解壓縮時不依賴以前的幀,而后續(xù)幀的解壓縮將依賴于這個關(guān)鍵幀。“stss”可以非常緊湊的標記媒體內(nèi)的隨機存取點,它包含一個sample序號表,表內(nèi)的每一項嚴格按照sample的序號排列,說明了媒體中的哪一個sample是關(guān)鍵幀。如果此表不存在,說明每一個sample都是一個關(guān)鍵幀,是一個隨機存取點。

Chunk Offset Box(stco)

????“stco”定義了每個thunk在媒體流中的位置。位置有兩種可能,32位的和64位的,后者對非常大的電影很有用。在一個表中只會有一種可能,這個位置是在整個文件中的,而不是在任何box中的,這樣做就可以直接在文件中找到媒體數(shù)據(jù),而不用解釋box。需要注意的是一旦前面的box有了任何改變,這張表都要重新建立,因為位置信息已經(jīng)改變了。

5、Free Space Box(free或skip)

“free”中的內(nèi)容是無關(guān)緊要的,可以被忽略。該box被刪除后,不會對播放產(chǎn)生任何影響。

6、Meida Data Box(mdat)

????該box包含于文件層,可以有多個,也可以沒有(當(dāng)媒體數(shù)據(jù)全部為外部文件引用時),用來存儲媒體數(shù)據(jù)。數(shù)據(jù)直接跟在box type字段后面,具體數(shù)據(jù)結(jié)構(gòu)的意義需要參考metadata(主要在sample table中描述)。


????普通MP4文件的結(jié)構(gòu)就講完了,可能會比較亂,下面這張圖是常見的box的樹結(jié)構(gòu)圖,可以用來大致了解MP4文件的構(gòu)造。


這篇文章主要面向一些對MP4文件結(jié)構(gòu)沒有太多了解的初學(xué)者,算是篇比較初級的文章,本人也是參考了一些資料寫出來的,對于MP4文件中涉及的一些概念沒有太深入的了解,因此其中應(yīng)該是有一些錯誤理解,希望大家抱著批判的眼光讀這篇文章。如果有錯誤的地方,還請大家不吝賜教。

該文主要參考了標準和網(wǎng)友wqyuwss的blog系列文章:mp4文件格式

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,428評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,024評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 175,285評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,548評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,328評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,878評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,971評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,098評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,616評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,554評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,725評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,243評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 43,971評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,361評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,613評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,339評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 47,695評論 2 370

推薦閱讀更多精彩內(nèi)容