MP4封裝格式簡介

視頻封裝格式是指視頻數據如何存儲的,視頻編碼格式是指原始視頻數據如何編碼爲二進制數據碼流。編碼後的視頻數據最終通過視頻封裝格式存儲爲視頻文件。

本文對視頻封裝格式MP4做一些介紹。主要介紹了Atom結構和Atom中數據的意義。

一、MP4封裝格式
ISO/IEC 14496-12(MPEG-4 Part 12 ISO base media file format)定義了一種通用的數字媒體文件格式標準,其基礎是2001年版的Apple QuickTime文件格式。
ISO/IEC 14496-14標準中定義了ISO/IEC 14496-12的一種多媒體容器格式實現,即我們現在熟知的MP4(MPEG-4 Part 14),它屬於MPEG-4的一部分。

MP4文件由若干稱爲Atom(或稱爲box)的數據對象組成,每個Atom的起首爲四個字節的數據長度(Big Endian)和四個字節的類型標識,數據長度和類型標誌都可以擴展。Atom可以嵌套,即其數據域可以由若干其它Atom組成,從而實現結構化的數據。

MP4是一種描述較爲全面的容器格式,被認爲可以在其中嵌入任何形式的數據,包括各種編碼的視頻、音頻,我們常見的大部分的MP4文件存放的AVC(H.264)或MPEG-4(Part 2)編碼的視頻和AAC編碼的音頻。

MP4格式的官方文件後綴名是“.mp4”,還有其他的以mp4爲基礎進行的擴展或者是縮水版本的格式,包括:M4V, 3GP, F4V等。

說明:
QuickTime影片格式是Apple公司開發的一種音頻、視頻文件格式,用於存儲常用數字媒體類型。其擴展名爲.mov。

二、MP4文件結構
MP4是由Atom嵌套來存放媒體信息。Atom的基本結構是:

[4bytes atom length] [4bytes atom name] [8bytes largesize, if size ==1] [contents of the atom, if any]

結構如圖:
這裏寫圖片描述

SIZE表示整個Atom所佔用的大小,包括header部分。如果Atom很大,超過了uint32的最大數值(例如存放具體視頻數據的mdat),size就被設置爲1,並用接下來的LARGESIZE來存放數據大小。
TYPE表示這個Atom的類型,主要有ftyp、moov、mdat等。
LARGESIZE,如果SIZE==1,則使用8bytes uint64來存儲該Atom大小。
DATA是實際的數據。

MP4文件含有很多Atom,主要的Atom和嵌套結構如圖。
這裏寫圖片描述

三、一個典型的MP4文件實例
MP4文件需要有ftyp、moov、mdat,它們都是頂級Atom,不能被其他Atom嵌套。
ftyp標示了MP4文件,必須出現在第一個。
moov保存了視頻的基本信息,mdat保存視頻和音頻數據。這兩個Atom順序不固定。

一個moov在mdat之後的MP4文件的Atom結構:
這裏寫圖片描述

由於moov中保存了視頻數據的索引,對於在線播放的場景,需要moov在mdat之前,才能流式讀取視頻數據。

部分攝像設備生成的MP4文件中,moov在mdat之前,兩者之間可能還存在一個Atom free,即moov-free-mdat。
free中爲全0,只是用於佔位。

一個moov在mdat之前的MP4文件的Atom結構:
這裏寫圖片描述

四、ATOM說明
1、FTYP
ftyp是整個文件的第一個Atom,通過判斷該Atom來確定文件的類型。該Atom有且只有1個,並且只能被包含在文件層,而不能被其他Atom包含。該Atom應該被放在文件的最開始,指示文件的相關信息。
文件的最開始的四個字節就是“ftyp”Atom的大小,然後是該Atom的類型。 “ftyp”的body依次包括1個32位的major brand(4個字符),1個32位的minor version(整數)和1個以32位(4個字符)爲單位元素的數組compatible brands。這些都是用來指示文件應用級別的信息。以一個MP4文件的“ftyp”Atom爲例,如下所示:
0000000: 0000 0018 6674 7970 6d70 3432 0000 0000 ....ftypmp42....
0000010: 6d70 3432 6d70 3431 0528 834f 6d64 6174 mp42mp41.(.Omdat

其中,
(1)0x00 00 00 18是“ftyp”Atom的大小,爲24個字節,這在一般情況下爲一個固定值。
(2)0x66 74 79 70是“ftyp”四個字符的ASCII值,也就是該Atom的類型。
(3)0x6D 70 34 32是major brand,這裏爲“mp42”,對於不同的文件,該值可能是不一樣的。
(4)0x00 00 00 00是minor version。
(5)0x6D 70 34 32和0x6D 70 34 31是compatible brands,”mp42”和“mp41”

FTYP到底是什麼呢?
ftyp就是一個由四個字符組成的碼字,用來標識編碼類型、兼容性或者媒體文件的用途。它存在於MP4文件和MOV文件中,當然,也存在於3GP文件中。
雖然MP4文件、MOV文件和3GP文件採用了相同的封裝標準,但由於是由不同的廠商合成,因此還是存在差別的。即使是同一種媒體文件,比如MP4文件,由不同developers開發的MP4也是存在差別的。ftyp簡單的說就是爲了標識它的developer是誰,兼容哪些標準等。
比如上面的例子,“mp42”表示它的major brand是MP4 v2 [ISO 14496-14],而“mp42”和“mp41”則表示它的compatible brands是MP4 v2 [ISO 14496-14]和MP4 v1 [ISO 14496-1:ch13]。

2、FREE
free是可選的,如果存在,則通常出現在moov與mdat之間,即moov-free-mdat。
free中的數據通常爲全0,其作用相當於佔位符,在實時拍攝視頻,moov數據增多時分配給moov使用。
因爲設備錄製視頻時並不能預先知道視頻數據大小,如果moov在mdat之前,隨着拍攝mdat的數據會增加,moov數據也會增多,如果沒有free預留的空間,則要不停的向後移動mdat數據以騰出moov空間。

3、MOOV
moov中主要保存了媒體的時間信息、trak信息和媒體索引等。

3.1 媒體時間信息
moov-mvhd中有一個time scale,以1/n秒的形式給出一個總的時間粒度,moov-trak-tkhd中以此時間粒度給出各個track的duration;

3.2 trak信息
moov中通常包含兩個trak,一個視頻索引,一個音頻索引。

3.2.1 trak類型
trak的類型在moov-trak-mdia-hdlr中給出,包括’vide’, ‘soun’和’hint’三種。

3.2.2 trak的時間
moov-trak-mdia-mdhd中以1/n秒的形式給出各個媒體的時間粒度以及以此時間粒度爲單位的duration。
moov-trak-mdia-minf-stbl-stts中有媒體幀之間的時間間隔,單位是moov-trak-tkhd中的時間粒度。

3.2.3 索引信息
moov-trak-mdia-minf-stbl比較重要,其中保存瞭解碼器需要的信息和索引信息,以下Atom都是stbl Atom的孩子。
stsd中保存瞭解碼器需要的媒體描述信息。
這裏寫圖片描述

stss, Sync Sample Atom
標識了媒體流中的關鍵幀,提供了隨機訪問點。每個entry標識了一個關鍵幀。
關鍵幀號是按照增長順序排列的。如果該Atom不存在,表示所有幀都是關鍵幀。
這裏寫圖片描述

Sync Sample Table的佈局

stts, Time-To-Sample Atoms
stts給出每個數據幀之間的時間間隔,單位是moov-trak-tkhd中的時間粒度。
Atom的每個entry給出了具有相同時間間隔的連續幀的個數,這些幀的時間間隔值,結構如圖。

這裏寫圖片描述

Time-To-Sample的table entry佈局

如果連續的幀有相同的時長,他們會被放在同一個entry中。如果所有的幀具有相同的時長,那麼Atom中就只有一個entry。

stts實例
下圖通過3個entries來描述9個幀。需要說明的是,這裏的entry和chunk不是對應的。例如,4、5、6幀可以在同一個chunk中,但是,由於它們的時長不同,4幀的時長爲3,而5、6幀的時長爲1,因此,保存在不同的entry中。

這裏寫圖片描述

stco/co64, Chunk Offset Atom
stco/co64給出每個數據Chunk在文件中的偏移。Chunk Offset Atom的每個entry給出了每個chunk在文件中的偏移。
如果Chunk Offset Atom的類型爲stco,則保存的偏移量是32位;如果是co64,則保存的偏移量是64位的。佈局如圖。

這裏寫圖片描述

chunk offset table的佈局
需要注意的是,該Atom中只給出了每個chunk的偏移量,並沒有給出每個sample的偏移量。因此,如果要獲得每個sample的偏移量,還需要用到Sample Size Table和Sample-To-Chunk Table。

stsc, Sample-To-Chunk Atom
stsc給出各個數據Chunk中包含的數據幀。一個chunk可能會包含一個或者幾個幀。每個chunk會有不同的size,每個chunk中的幀也會有不同的size。
entry中保存了第一個chunk號、每個chunk包含的幀數、幀描述ID。

這裏寫圖片描述

Sample-To-Chunk Atom的table entry佈局

每個entry包含一組chunk,其中每個chunk的幀數相同。而且,這些chunk中的每個幀都必須使用相同的幀描述。
如果chunk中的幀數或者幀描述改變,必須創建一個新的entry。
如果所有的chunk包含的幀數和幀描述相同,那麼只有一個entry。

stsc實例
圖中表示至少有5個chunk,第1、2個chunk分別包含3個幀,幀描述ID是23;第3、4個chunk分別包含1個幀,幀描述ID是23;第5個及以後的chunk,包含1個幀,幀描述ID是24。
對於最後一個entry需要特殊的處理,因爲無法判斷什麼時候結束。

這裏寫圖片描述

stsz, Sample Size Atom

這裏寫圖片描述

sample size table的佈局

3.3 用戶定義數據
udta中保存了用戶定義數據,例如iTune使用的meta數據就保存在udta中。

3.4 用戶擴展數據
Atom的擴展通過uuid實現。用戶可以使用類型爲’uuid’的Atom,以16個特定的字節作爲標識,定義自己的數據格式。

4、MDAT
所有媒體數據統一存放在mdat中,沒有同步字,沒有分隔符,只能根據索引進行訪問。
mdat的位置比較靈活,可以位於moov之前,也可以位於moov之後,但必須和stbl中的信息保持一致。

另外,在寫mp4文件的時候,對於mdat這個Atom,一般是先將Atom size填寫0,待數據寫完之後,再回過來填入具體大小。

5、其他ATOM
5.1、THMB
Atom moov @ 13840405 of size: 355190, ends @ 14195595
…….
Atom udta @ 14146330 of size: 49265, ends @ 14195595
Atom thmb @ 14146338 of size: 49197, ends @ 14195535
Atom cprt [zho] @ 14195535 of size: 30, ends @ 14195565
Atom perf [zho] @ 14195565 of size: 30, ends @ 14195595

thmb 結構:
atom size (49197)
atom type (thmb)
thmb size (0)
thmb type (jpeg)
thmb data

五、實際應用場景
1、把文件尾部的moov移到文件頭
對於流媒體播放,如果mdat的位置在moov之前,通過流的方式播放文件會出現問題,因爲沒有辦法在一開始就獲得文件的媒體信息和索引。
這種情況需要對視頻做預處理,把moov移動到文件頭。通過遍歷Atom可以很容易找到moov Atom。

需要注意的是,移動moov到文件頭,同時需要修改moov中的stco/co64。因爲這裏保存了chunk數據的偏移量,移動moov後,需要根據moov的新位置更新stco/co64 。

stco/co64的結構如下:
這裏寫圖片描述

可參考 python開源庫 qtfaststart。

2、分割MP4文件
在視頻點播服務中,需要將MP4文件分割爲多個分片,此時需要獲取關鍵幀、切割時間軸、更新moov和生成各個分片文件。

可參考 http://www.cnblogs.com/haibindev/archive/2011/10/17/2214518.html

附 查看Atom相關工具
Windows:mp4info,解析和用樹形顯示文件的atom
Linux:AtomicParsley,C++編寫,解析文件的atom

附錄: ISO/IEC 14496 MPEG的協議標準
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)。

參考
http://blog.csdn.net/yu_yuan_1314/article/details/9406587
http://m.blog.chinaunix.net/uid-26009923-id-5702652.html

視頻格式說明
http://www.zhihu.com/question/20997688

atom說明
http://wiki.multimedia.cx/?title=QuickTime_container
http://atomicparsley.sourceforge.net/mpeg-4files.html
http://www.ftyps.com/what.html
http://blog.csdn.net/yu_yuan_1314/article/details/9366703
http://blog.csdn.net/yu_yuan_1314/article/details/9078287

開源庫
qtfaststart python編寫的,如果moov在文件尾部,移動到文件頭部
https://github.com/danielgtaylor/qtfaststart.git

@[TOC](這裏寫自定義目錄標題)

歡迎使用Markdown編輯器

你好! 這是你第一次使用 Markdown編輯器 所展示的歡迎頁。如果你想學習如何使用Markdown編輯器, 可以仔細閱讀這篇文章,瞭解一下Markdown的基本語法知識。

新的改變

我們對Markdown編輯器進行了一些功能拓展與語法支持,除了標準的Markdown編輯器功能,我們增加了如下幾點新功能,幫助你用它寫博客:

  1. 全新的界面設計 ,將會帶來全新的寫作體驗;
  2. 在創作中心設置你喜愛的代碼高亮樣式,Markdown 將代碼片顯示選擇的高亮樣式 進行展示;
  3. 增加了 圖片拖拽 功能,你可以將本地的圖片直接拖拽到編輯區域直接展示;
  4. 全新的 KaTeX數學公式 語法;
  5. 增加了支持甘特圖的mermaid語法1 功能;
  6. 增加了 多屏幕編輯 Markdown文章功能;
  7. 增加了 焦點寫作模式、預覽模式、簡潔寫作模式、左右區域同步滾輪設置 等功能,功能按鈕位於編輯區域與預覽區域中間;
  8. 增加了 檢查列表 功能。

功能快捷鍵

撤銷:Ctrl/Command + Z
重做:Ctrl/Command + Y
加粗:Ctrl/Command + B
斜體:Ctrl/Command + I
標題:Ctrl/Command + Shift + H
無序列表:Ctrl/Command + Shift + U
有序列表:Ctrl/Command + Shift + O
檢查列表:Ctrl/Command + Shift + C
插入代碼:Ctrl/Command + Shift + K
插入鏈接:Ctrl/Command + Shift + L
插入圖片:Ctrl/Command + Shift + G

合理的創建標題,有助於目錄的生成

直接輸入1次#,並按下space後,將生成1級標題。
輸入2次#,並按下space後,將生成2級標題。
以此類推,我們支持6級標題。有助於使用TOC語法後生成一個完美的目錄。

如何改變文本的樣式

強調文本 強調文本

加粗文本 加粗文本

標記文本

刪除文本

引用文本

H2O is是液體。

210 運算結果是 1024.

插入鏈接與圖片

鏈接: link.

圖片: Alt

帶尺寸的圖片: Alt

居中的圖片: Alt

居中並且帶尺寸的圖片: Alt

當然,我們爲了讓用戶更加便捷,我們增加了圖片拖拽功能。

如何插入一段漂亮的代碼片

博客設置頁面,選擇一款你喜歡的代碼片高亮樣式,下面展示同樣高亮的 代碼片.

// An highlighted block
var foo = 'bar';

生成一個適合你的列表

  • 項目
    • 項目
      • 項目
  1. 項目1
  2. 項目2
  3. 項目3
  • 計劃任務
  • 完成任務

創建一個表格

一個簡單的表格是這麼創建的:

項目 Value
電腦 $1600
手機 $12
導管 $1

設定內容居中、居左、居右

使用:---------:居中
使用:----------居左
使用----------:居右

第一列 第二列 第三列
第一列文本居中 第二列文本居右 第三列文本居左

SmartyPants

SmartyPants將ASCII標點字符轉換爲“智能”印刷標點HTML實體。例如:

TYPE ASCII HTML
Single backticks 'Isn't this fun?' ‘Isn’t this fun?’
Quotes "Isn't this fun?" “Isn’t this fun?”
Dashes -- is en-dash, --- is em-dash – is en-dash, — is em-dash

創建一個自定義列表

Markdown
Text-to-HTML conversion tool
Authors
John
Luke

如何創建一個註腳

一個具有註腳的文本。2

註釋也是必不可少的

Markdown將文本轉換爲 HTML

KaTeX數學公式

您可以使用渲染LaTeX數學表達式 KaTeX:

Gamma公式展示 Γ(n)=(n1)!nN\Gamma(n) = (n-1)!\quad\forall n\in\mathbb N 是通過歐拉積分

Γ(z)=0tz1etdt . \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,.

你可以找到更多關於的信息 LaTeX 數學表達式here.

新的甘特圖功能,豐富你的文章

Mon 06Mon 13Mon 20已完成 進行中 計劃一 計劃二 現有任務Adding GANTT diagram functionality to mermaid
  • 關於 甘特圖 語法,參考 這兒,

UML 圖表

可以使用UML圖表進行渲染。 Mermaid. 例如下面產生的一個序列圖::

張三李四王五你好!李四, 最近怎麼樣?你最近怎麼樣,王五?我很好,謝謝!我很好,謝謝!李四想了很長時間,文字太長了不適合放在一行.打量着王五...很好... 王五, 你怎麼樣?張三李四王五

這將產生一個流程圖。:

鏈接
長方形
圓角長方形
菱形
  • 關於 Mermaid 語法,參考 這兒,

FLowchart流程圖

我們依舊會支持flowchart的流程圖:

Created with Raphaël 2.2.0開始我的操作確認?結束yesno
  • 關於 Flowchart流程圖 語法,參考 這兒.

導出與導入

導出

如果你想嘗試使用此編輯器, 你可以在此篇文章任意編輯。當你完成了一篇文章的寫作, 在上方工具欄找到 文章導出 ,生成一個.md文件或者.html文件進行本地保存。

導入

如果你想加載一篇你寫過的.md文件或者.html文件,在上方工具欄可以選擇導入功能進行對應擴展名的文件導入,
繼續你的創作。


  1. mermaid語法說明 ↩︎

  2. 註腳的解釋 ↩︎

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章