MP4簡介

聲明:

    在我的工作中需要查看一些關於MP4格式的問題,所以對MP4進行了簡單的瞭解,這裏對這部分知識做個簡單的總結,但是文中主要是參考mp4文件格式解析,這裏進行說明,同時我也使用了一些自己工作中的例子作講解,希望可以對你有所幫助。

 

參考文章:

FFmpeg中mp4的demuxer(mov.c)代碼閱讀 : https://www.jianshu.com/p/f78defe0e485

介紹MP4格式的文章:

mp4文件格式解析 : https://www.jianshu.com/p/529c3729f357

多媒體文件格式之MP4 : https://www.cnblogs.com/tocy/p/media_container_3_mp4.html

Android音視頻系列:視頻容器操作篇 -- mp4容器打包實現 : https://mp.weixin.qq.com/s/BOkaNcPQWKkeAS1it3aE-w

 

軟件推薦:Mp4Explorer

    一個非常友好,可以很清楚的將MP4各種需要的信息使用表格的方式例舉出來的軟件,界面爲:

 

 

封裝格式重要概念

1 box

mp4文件由若干個box組成。下面是box結構的一個示意圖。

 

  • box由header和body組成,其中header指明box的size和type。size是包含box header的整個box的大小。
  • box type,通常是4個ASCII碼的字符如“ftyp”、“moov”等,這些box type都是已經預定義好的,表示固定的含義。如果是“uuid”,表示該box爲用戶自定義擴展類型,如果box type是未定義的,應該將其忽略。
  • 如果header中的size爲1,則表示box長度需要更多的bits位來描述,在後面會有一個64bits位的largesize用來描述box的長度。如果size爲0,表示該box爲文件的最後一個box,文件結尾(同樣只存在於“mdat”類型的box中)。

 

2 track

一些sample的集合,對於媒體數據來說,track表示一個視頻或者音頻序列。

3 sample

video sample即爲一幀或者一組連續視頻幀,audio sample即爲一段連續的音頻。

4. sample table

指明sample時序和物理佈局的表。

5. chunk

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

    mp4文件中,媒體內容在moov的box中。一個moov包含多個track。每個track就是一個隨時間變化的媒體序列,track裏的每個時間單位是一個sample,sample按照時間順序排列。注意,一幀音頻可以分解成多個音頻sample,所以音頻一般用sample作爲單位,而不用幀。

    sample是媒體數據存儲的單位,存儲在media的chunk中,chunk和sample的長度均可互不相同,如下圖所示。

 

 

重要box介紹:

 

 

實例分析:

 

    上圖是我之前分析的一個MP4 文件的結構圖,在這個文件中音頻和視頻是間隔放置的,其中紅色的爲音頻,藍色的爲視頻。而在每個音視頻塊中有其對應的偏移量(pos),也就是他們在文件中的位置。而在pos左右兩邊爲音視頻的dts值通過dts可以實現音視頻的同步播放)。而再往兩邊對應的數據爲音視頻中每個chunk的偏移量(STCO)。chunk是由一個或者多個sample組成,如粉框中多個sample對應一個chunk。而在最左邊和最右邊是每個音視頻的sample的大小(STSZ),我們可以通過偏移量和每個sample的大小來計算出每個chunk的大小以及他在文件中所在的位置。因此我們瞭解MP4文件的時候通常需要結合STCO表和STSZ表來了解MP4的組成結構。

    但是我們在瞭解了MP4音視頻位置信息後不一定知道他是不是可以正常的播放,因爲在播放器中,音視頻的同步播放是要通過很多的信息來實現的,例如在視頻播放之前我們需要知道一些信息來對播放器做初始化設置:

audio信息:

  1. smplrate:sample rate(採樣率)。
  2. channel:通道個數。
  3. bitrate:比特率。
  4. audiosamplenum:音頻sample的個數。
  5. 採樣位數
  6. 音頻格式

 

video信息:

  1. width、height:視頻的寬/高。
  2. bitrate:比特率(碼率),秒爲單位。等於視頻總的大小/時長。
  3. frames:視頻幀數。
  4. fps:幀率(frame per second)。
  5. total_time:時間長度,ms爲單位。等於duration/timescale。
  6. timescale:時間的粒度,1000表示1000個單位爲1s。
  7. duration:時間粒度的個數。
  8. videosamplenum:視頻sample的個數。

 

    在上面列舉了對於音視頻來說十分重要的參數,而這些參數就是通過解析moov中各個box獲得的。可以通過參考上面重要box中的各個參數的說明來了解各個參數在哪個box中:

 

 

播放器中如何實現音視頻同步:

    通過解析moov中各個box獲得需要的參數對播放器進行初始化,之後就需要獲得真正的音視頻數據來做同步播放了,我們可以想象音視頻爲兩隊排隊進入民政的情侶,他們只有一一對應好才能跟自己的女朋友結婚,否則就容易出現錯誤。而對於音視頻來說也是這樣的,只有dts相同的數據寫入到播放器中才可以音視頻同步播放。

    現在我們想一下,民政局其實是有窗口限制的,只能同時給一定數量的情侶辦理結婚,辦完一對走一對,接着辦下一對。 這裏我們認爲這個民政局同時可以爲10對情侶辦理業務,也就是說播放器最多隻能接受20個音頻或者視頻。如果不消耗用來顯示輸出而是讓他們等待就會出問題。

    我們知道音視頻的存放方式爲:一段音頻一段視頻,依次交替。而回到我們的例子中就是男生和女生是分開排隊的,一隊男生一隊女生,依次交替。現在他們需要進入民政局辦理結婚了,我們理想的情況下是,一隊男生進來後沒有坐滿民政局的窗口,這個時候一隊女生來了,他們找到自己的男朋友,辦理完手續就走了,由下一對接着辦理。而對應在播放器中就是讀入一段音頻,這個時候內存還允許,繼續讀一段視頻,音視頻同步輸出後,釋放內存讓後面的音視頻使用。

    但是有的時候是有意外存在的,那就是這一隊的男生超出了20個人,來了21個人,這個時候後面進來的不是女生,不能辦理結婚,出現這個問題就需要民政局的辦事人員去問在一號窗口的男生,“你的女朋友是誰啊,她在什麼位置啊,我給你帶過來”,這樣你們辦理完後面就好辦理了。而這個過程相對於正常的流程來說需要民政局的人幫忙去後面找自己的女票是十分繁瑣的事情。

    而對應到播放器中就是當音頻的數據讀滿buffer的時候,這個時候還沒有視頻數據到來(或者視頻數據讀滿buffer,而音頻數據沒有到來),播放器就需要去找此時排在最前面的音頻對應dts的視頻,這樣就可以將他們寫入播放器,從而釋放音頻的內存來存放其他的數據。而找視頻的這個過程就需要使用到seek的操作。當從網絡讀取數據時,就需要使用HTTP去GET請求視頻所有的位置,之後從這個位置開始讀取數據。而通常上面這樣的操作是十分繁瑣的,也影響視頻的下載。

    針對上面這種排序有問題的文件的一個修改辦法就是加大buffer。這樣可以接收更多的音視頻,從而更容易做同步。

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