MP4文件格式分析及分割實現(附源碼)

轉載地址:http://www.cnblogs.com/Kingfans/p/7170478.html

MP4文件格式分析

  MP4(MPEG-4 Part 14)是一種常見的多媒體容器格式,它是在“ISO/IEC 14496-14”標準文件中定義的,屬於MPEG-4的一部分,是“ISO/IEC 14496-12(MPEG-4 Part 12 ISO base media file format)”標準中所定義的媒體格式的一種實現,後者定義了一種通用的媒體文件結構標準。MP4是一種描述較爲全面的容器格式,被認爲可以在其中嵌入任何形式的數據,各種編碼的視頻、音頻等都不在話下,不過我們常見的大部分的MP4文件存放的AVC(H.264)MPEG-4(Part 2)編碼的視頻和AAC編碼的音頻。MP4格式的官方文件後綴名是“.mp4”,還有其他的以mp4爲基礎進行的擴展或者是縮水版本的格式,包括:M4V,3GP,F4V等。

 

  一個mp4文件有可能包含非常多的box(全部大約70多個),在很大程度上增加了解析的複雜性。如果要全部解析必要性不是很大。大部分mp4文件沒有那麼多的box類型,下圖就是一個簡化了的,常見的mp4文件結構:

下圖是節點box詳細說明:

下面我們將對以上主要box的解析進行詳細說明:

1. 一級box

  一級box主要包含ftyp、moov、free、mdat等等。

1.1 ftyp box

結構:

/********************************************************************************************
**                            File Type Box (ftyp)
**
--------------------------------------------------------------------------------------------
**        字段名稱              |    長度(bytes)   |        有關描述
--------------------------------------------------------------------------------------------
**        boxsize               |    4            |        box的長度
**        boxtype               |    4            |        box的類型
**        major_brand           |    4            |
**        minor_version         |    4            |        版本號
**        compatible_brands     |    4 * N        |        本文件遵從的多種協議(ismo, iso2, mp41)
********************************************************************************************/

運行結果:

1.2 moov box

結構:

/********************************************************************************************
**        字段名稱            |    長度(bytes)   |        有關描述
--------------------------------------------------------------------------------------------
**        boxsize            |    4            |        box的長度
**        boxtype            |    4            |        box的類型
********************************************************************************************/

1.3 free box

結構:

/********************************************************************************************
**        字段名稱            |    長度(bytes)   |        有關描述
--------------------------------------------------------------------------------------------
**        boxsize            |    4            |        box的長度
**        boxtype            |    4            |        box的類型
********************************************************************************************/

1.4 mdat box

結構:

/********************************************************************************************
**        字段名稱             |    長度(bytes)    |        有關描述
--------------------------------------------------------------------------------------------
**        boxsize             |    4             |        box的長度
**        boxtype             |    4             |        box的類型
**                                               |        後面全是真實數據
********************************************************************************************/

運行結果:

2. 二級box

  本節所說的二級box皆爲moov的子box,主要包含mvhd、trak、udat等等。

2.1 mvhd box

結構:

/************************************************************************************************************
**                                            mvhd
**
--------------------------------------------------------------------------------------------
**        字段名稱              |    長度(bytes)   |        有關描述
--------------------------------------------------------------------------------------------
**        boxsize               |    4            |        box的長度
**        boxtype               |    4            |        box的類型
**        version               |    1            |        box版本,0或1,一般爲0(以下字節數均按version = 0)
**        flags                 |    3            |        
**        creation time         |    4            |        創建時間(相對於UTC時間1904 - 01 - 01零點的秒數)
**        modification time     |    4            |        修改時間
**        time scale            |    4            |        文件媒體在1秒時間內的刻度值,可以理解爲1秒長度的時間單元數
**        duration              |    4            |        該track的時間長度,用duration和time scale值可以計算track時長
**        rate                  |    4            |        推薦播放速率,高16位和低16位分別爲小數點整數部分和小數部分,即[16.16] 格式.該值爲1.0 (0x00010000)
**        volume                |    2            |        與rate類似,[8.8] 格式,1.0(0x0100)表示最大音量
**        reserved              |    10           |        保留位
**        matrix                |    36           |        視頻變換矩陣
**        pre-defined           |    24           |        
**        next track id         |    4            |        下一個track使用的id號
************************************************************************************************************/

運行結果:

2.2 trak box

結構:

/********************************************************************************************
**        字段名稱            |    長度(bytes)   |        有關描述
--------------------------------------------------------------------------------------------
**        boxsize            |    4            |        box的長度
**        boxtype            |    4            |        box的類型
********************************************************************************************/

2.3 udat box

結構:

/************************************************************************************************************
**           udat
**
--------------------------------------------------------------------------------------------
**  字段名稱 | 長度(bytes)  |  有關描述
--------------------------------------------------------------------------------------------
**  boxsize     | 4        |  box的長度
**  boxtype     | 4        |  box的類型
**                    |  用戶自定義數據解析
************************************************************************************************************/

運行結果:

3. 三級box

  本節所說的三級box皆爲trak的子box,主要包含tkhd、mdia等。

3.1 tkhd box

結構:

/************************************************************************************************************
**                                        tkhd
**
-------------------------------------------------------------------------------------------------------------
**        字段名稱               |    長度(bytes)   |        有關描述
-------------------------------------------------------------------------------------------------------------
**        boxsize                |    4            |        box的長度
**        boxtype                |    4            |        box的類型
**        version                |    1            |        box版本,0或1,一般爲0。(以下字節數均按version = 0)
**        flags                  |    3            |        按位或操作結果值,預定義如下;
                                                         0x000001 track_enabled,否則該track不被播放;
                                                         0x000002 track_in_movie,表示該track在播放中被引用;
                                                         0x000004 track_in_preview,表示該track在預覽時被引用。
                                                         一般該值爲7,如果一個媒體所有track均未設置track_in_movie和track_in_preview,將被理解爲所有track均設置了這兩項;
                                                         對於hint track,該值爲0;
**        creation_time          |    4            |        創建時間(相對於UTC時間1904 - 01 - 01零點的秒數)
**        modification_time      |    4            |        修改時間
**        track_id               |    4            |        id號 不能重複且不能爲0
**        reserved               |    4            |        保留位
**        duration               |    4            |        track的時間長度
**        reserved               |    8            |        保留位
**        layer                  |    2            |        視頻層,默認爲0,值小的在上層
**        alternate_group        |    2            |        track分組信息,默認爲0表示該track未與其他track有羣組關係
**        volume                 |    2            |        [8.8] 格式,如果爲音頻track,1.0(0x0100)表示最大音量;否則爲0
**        reserved               |    2            |        保留位
**        matrix                 |    36           |        視頻變換矩陣
**        width                  |    4            |        寬
**        height                 |    4            |        高,均爲[16.16] 格式值 與sample描述中的實際畫面大小比值,用於播放時的展示寬高
************************************************************************************************************/

運行結果:

3.2 mdia box

結構:

/********************************************************************************************
**        字段名稱            |    長度(bytes)   |        有關描述
--------------------------------------------------------------------------------------------
**        boxsize            |    4            |        box的長度
**        boxtype            |    4            |        box的類型
********************************************************************************************/

4. 四級box

  本節所說的四級box皆爲mdia的子box,主要包含mdhd、hdlr、minf等。

4.1 mdhd box

結構:

/************************************************************************************************************
**                                        tkhd
**
-------------------------------------------------------------------------------------------------------------
**        字段名稱              |      長度(bytes)   |        有關描述
-------------------------------------------------------------------------------------------------------------
**        boxsize               |    4                |        box的長度
**        boxtype               |    4                |        box的類型
**        version               |    1           |        box版本0或1 一般爲0 (以下字節數均按version=0)
**        flags                 |    3                |        
**        creation_time         |    4                |        創建時間(相對於UTC時間1904 - 01 - 01零點的秒數)
**        modification_time     |    4                |        修改時間
**        time_scale            |    4                |        
**        duration              |    4               |        track的時間長度
**        language              |    2               |        媒體語言碼,最高位爲0 後面15位爲3個字符[見ISO 639-2/T標準中定義]
**        pre-defined           |    2                |        保留位
************************************************************************************************************/

結果:

4.2 hdlr box

結構:

/************************************************************************************************************
**                                        hdlr
**
-------------------------------------------------------------------------------------------------------------
**        字段名稱               |    長度(bytes)    |        有關描述
-------------------------------------------------------------------------------------------------------------
**        boxsize                |    4             |        box的長度
**        boxtype                |    4             |        box的類型
**        version                |    1             |        box版本0或1 一般爲0 (以下字節數均按version=0)
**        flags                  |    3             |
**        pre-defined            |    4             |
**        handler type           |    4             |        在media box中,該值爲4個字符
                                                          "vide"— video track
                                                          "soun"— audio track
                                                          "hint"— hint track
**        reserved               |    12            |
**        name                   |    不定           |        track type name,以‘\0’結尾的字符串
************************************************************************************************************/

結果:

4.3 minf box

結構:

/********************************************************************************************
**        字段名稱            |    長度(bytes)   |        有關描述
--------------------------------------------------------------------------------------------
**        boxsize            |    4            |        box的長度
**        boxtype            |    4            |        box的類型
********************************************************************************************/

5. 五級box

  本節所說的五級box皆爲minf的子box,主要包含header box(vmhd/smhd/hmld/nmld)、stbl等。

5.1 header box

本處的headerbox會根據前面的handler type數值選擇哪個box。 

"vide"—vmhd 視頻

"soun"— smhd 音頻

"hint"—hmhd 忽略

vmhd結構:

/************************************************************************************************************
**                                        vmhd
**
-------------------------------------------------------------------------------------------------------------
**        字段名稱            |    長度(bytes)    |        有關描述
-------------------------------------------------------------------------------------------------------------
**        boxsize                |    4            |        box的長度
**        boxtype                |    4            |        box的類型
**        version                |    1            |        box版本0或1 一般爲0 (以下字節數均按version=0)
**        flags                |    3            |
**        graphics_mode        |    4            |        視頻合成模式,爲0時拷貝原始圖像,否則與opcolor進行合成
**        opcolor                |    2 ×3        |        {red,green,blue}
************************************************************************************************************/

結果:

5.2 stbl box

結構:

/********************************************************************************************
**        字段名稱            |    長度(bytes)   |        有關描述
--------------------------------------------------------------------------------------------
**        boxsize            |    4            |        box的長度
**        boxtype            |    4            |        box的類型
********************************************************************************************/

6. 六級box

  本節所說的六級box皆爲stbl的子box,主要包含stsd、stts、stsz、stsc、stss、stco等,這些也是mp4文件設計的精髓所在,主要控制chunk、sample、mdat之間的映射關係。

6.1 stsd box

stsd: Sample Description Box,解析stsd可獲得coding類型、視頻寬高、音頻samplesize、channelcount這些和解碼器有關信息。

6.2 stts box

stts: Decoding Time to Sample Box,時間戳和Sample映射表

上圖是一個video trak,說明該視頻包含87幀數據,每幀包含512個採樣。

總共512*87=44544個採樣,和我們前面mdhd box的Duration完全一致。

Duration / TimeScale = 44544 / 12288 = 3.625秒 正是我們的視頻播放長度。

12288 / 512 = 24 p/s (幀率)。

6.3 stsz box

stsz, stz2: Sample Size Boxes,每個Sample大小的表

一共87幀 每幀的字節大小。

6.4 stsc box

stsc: Sample to chunk 的映射表。

前面說了一共87幀數據,放在83個chunk中。1~82個chunk每個裏面放1幀,第83個chunk放了5幀。

6.5 stss box

stss: 關鍵幀索引表。

第1、13、25、37、49、61、73、85.... 這些幀都是關鍵幀。

每12幀就有一個關鍵幀, 前面我們計算得知fps是24。由此可知該視頻關鍵幀間隔爲0.5秒。

6.6 stco box

'stco','co64': Chunk位置偏移表

一共83個chunk,記錄在mdat真實數據中的字節偏移量。

 

下圖爲第三方MP4文件解析結果:

MP4文件格式解析源碼:https://github.com/kingsunc/AVFileParse

搞清楚stbl的映射關係後 我們就可以進行MP4文件的分割實現(也就是所謂的點播拖動)。

MP4分割實現源碼:https://github.com/kingsunc/AVFileParse/tree/master/Mp4_Segment

 

 

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