最近為了更加深入了解音視頻demux這塊的功能,準備著手寫個demuxer,提取視頻流。
MP4簡介 MP4的定義MP4是一種常用的視音頻流封裝格式,按照指定的協議來存放媒體數據;因為mp4是基于蘋果QuickTime文件格式,所以與mov有很多相同之處,在蘋果開發者平臺可以看到詳細的有關封裝文檔(https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-25615)
MP4的封裝格式MP4格式預覽—mp4是由多個box嵌套組成的
MP4主要的頂部box
ftyp box:描述MP4鎖遵循的規范和版本
mdat box :存放媒體數據
moov box:存放媒體參數(pps、sps等)相關信息和用于索引媒體數據存儲位置的信息
MP4常用box
字段分布圖
字段解析
major_brand:比如常見的 isom、mp41、mp42、avc1、qt等。它表示“最好”基于哪種格式來解析當前的文件。舉例,major_brand 是 A,compatible_brands 是 A1,當解碼器同時支持 A、A1 規范時,最好使用A規范來解碼當前媒體文件,如果不支持A規范,但支持A1規范,那么,可以使用A1規范來解碼;
minor_version:提供 major_brand 的說明信息,比如版本號,不得用來判斷媒體文件是否符合某個標準/規范;
compatible_brands:文件兼容的brand列表。比如 mp41 的兼容 brand 為 isom。通過兼容列表里的 brand 規范,可以將文件 部分(或全部)解碼出來;
字段分布圖
字段解析
version :一字節用于指定mvhd的版本
flags:3字節,預留
Create time:媒體創建時間,與UTC時間不同的是,此時間是從1904年1月1日0:0:0開始計算的,而utc是從1970年1月1日0:0:0開始計算,故Create time須要減去時間差換算成utc時間
// 注:66年時間差不是66*365*24*3600來計算
creation_time_utc = creation_time - (66年時間差) = creation_time - 2082844800
Modification time:媒體最后被修改的時間,計算方式同Create time
Timescale:一秒包含的時間單位(整數)。舉個例子,如果timescale等于1000,那么,一秒包含1000個時間單位(后面track等的時間,都要用這個來換算,比如track的duration為10,000,那么,track的實際時長為10,000/1000=10s);
Duration:影片時長(整數),根據文件中的track的信息推導出來,等于時間最長的track的duration;
Preferred rate:推薦的播放速率,32位整數,高16位、低16位分別代表整數部分、小數部分([16.16]),舉例 0x0001 0000 代表1.0,正常播放速度;
Preferred volume:播放音量,16位整數,高8位、低8位分別代表整數部分、小數部分([8.8]),舉例 0x01 00 表示 1.0,即大音量;
Matrix struct:視頻的轉換矩陣,詳情看
Basic Data Types
Next_track_ID:32位整數,非0,一般可以忽略不計。當要添加一個新的track到這個影片時,可以使用的track id,必須比當前已經使用的track id要大。也就是說,添加新的track時,需要遍歷所有track,確認可用的track id;
字段分布圖
字段解析
字段分布圖
字段解析
數據結構分布圖
注意:取到的frame前四個字節為frame數據的長度字節,須要偏移去掉
主要存放了媒體參數(pps、sps、vps等)相關信息和用于解析mdat中視音頻數據的關鍵信息
字段分布圖
字段解析
avc1 box
字段分布圖
字段解析
這個在https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html的“Sample Description Atoms”一節可以研究下
avcC box(包含了視頻關鍵參數,在ISO/IEC 14496-15中定義)
字段分布圖
字段解析
其他字段可以自行在ISO/IEC 14496-15中查到
字段分布圖
字段解析
字段分布圖
字段解析
Sample-to-chunk table示意圖
字段分布圖
字段解析
字段分布圖
字段解析
Time-to-sample table:示意圖
sample1 - sample4的sample duration是4
字段分布圖
字段解析
獲取sps pps參數
解析stsd box,其中contain avc1 box和avcC box(此步驟詳解見上文)
解析avcC box可以獲取到sps和pps
以下為ISO/IEC 14496-15中解析avcC的偽代碼
aligned(8) class AVCDecoderConfigurationRecord { unsigned int(8) configurationVersion = 1;
unsigned int(8) AVCProfileIndication;
unsigned int(8) profile_compatibility;
unsigned int(8) AVCLevelIndication;
bit(6) reserved = ‘111111’b;
unsigned int(2) lengthSizeMinusOne;
bit(3) reserved = ‘111’b;
unsigned int(5) numOfSequenceParameterSets;
for (i=0; i< numOfSequenceParameterSets; i++) { unsigned int(16) sequenceParameterSetLength ;
bit(8*sequenceParameterSetLength) sequenceParameterSetNALUnit;
}
unsigned int(8) numOfPictureParameterSets;
for (i=0; i< numOfPictureParameterSets; i++) { unsigned int(16) pictureParameterSetLength;
bit(8*pictureParameterSetLength) pictureParameterSetNALUnit;
}
if( profile_idc == 100 || profile_idc == 110 ||
profile_idc == 122 || profile_idc == 144 )
{ bit(6) reserved = ‘111111’b;
unsigned int(2) chroma_format;
bit(5) reserved = ‘11111’b;
unsigned int(3) bit_depth_luma_minus8;
bit(5) reserved = ‘11111’b;
unsigned int(3) bit_depth_chroma_minus8;
unsigned int(8) numOfSequenceParameterSetExt;
for (i=0; i< numOfSequenceParameterSetExt; i++) { unsigned int(16) sequenceParameterSetExtLength;
bit(8*sequenceParameterSetExtLength) sequenceParameterSetExtNALUnit;
}
}
}
獲取關鍵幀位置
解析stss box可以知道哪一個sample中包含關鍵幀
獲取chunk位置
解析stco box可以獲取到每個chunk在視頻文件中的索引
獲取每個chunk中sample個數
解析stsc box可以獲取到每個chunk包含多少個sample
獲取sample大小
解析stsz box可以獲取到每個sample的大小
獲取frame位置(demo視頻文件一個sample只包含一個frame,所以sample的位置和大小就是frame的位置和大小)
獲取到一幀數據后
保存成h264文件,可使用ffplay和potplay播放
注意:有些非字串的字段為大端字節序,須要轉換
總結:mp4info—可以看到相關box的字節信息,但發現對avcC的解析漏掉了幾個字節
mp4 exploer—可以更加直觀的看到視音頻數據信息
https://github.com/TaoChou/demuxer-c
參考你是否還在尋找穩定的海外服務器提供商?創新互聯www.cdcxhl.cn海外機房具備T級流量清洗系統配攻擊溯源,準確流量調度確保服務器高可用性,企業級服務器適合批量采購,新人活動首月15元起,快前往官網查看詳情吧
文章標題:c實現mp4解封裝-創新互聯
瀏覽地址:http://vcdvsql.cn/article26/didscg.html
成都網站建設公司_創新互聯,為您提供微信小程序、品牌網站建設、Google、移動網站建設、建站公司、自適應網站
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯