欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

c實(shí)現(xiàn)mp4解封裝-創(chuàng)新互聯(lián)

文章目錄
    • 前序
    • MP4簡(jiǎn)介
      • MP4的定義
      • MP4的封裝格式
    • Box類(lèi)型詳解
      • Box格式
      • ftyp box
      • mvhd box
      • tkhd box
      • hdlr box
      • mdat box
      • stbl box
      • stsd box
      • stco box
      • stsc box
      • stsz box
      • stts box
      • stss box
    • demuxer demo的實(shí)現(xiàn)(視頻數(shù)據(jù)部分)
    • 總結(jié):
    • 工具介紹
    • 源碼
    • 參考

我們提供的服務(wù)有:做網(wǎng)站、網(wǎng)站設(shè)計(jì)、微信公眾號(hào)開(kāi)發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、江孜ssl等。為上千余家企事業(yè)單位解決了網(wǎng)站和推廣的問(wèn)題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的江孜網(wǎng)站制作公司前序

最近為了更加深入了解音視頻demux這塊的功能,準(zhǔn)備著手寫(xiě)個(gè)demuxer,提取視頻流。

MP4簡(jiǎn)介 MP4的定義

MP4是一種常用的視音頻流封裝格式,按照指定的協(xié)議來(lái)存放媒體數(shù)據(jù);因?yàn)閙p4是基于蘋(píng)果QuickTime文件格式,所以與mov有很多相同之處,在蘋(píng)果開(kāi)發(fā)者平臺(tái)可以看到詳細(xì)的有關(guān)封裝文檔(https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-25615)

MP4的封裝格式
  • MP4格式預(yù)覽—mp4是由多個(gè)box嵌套組成的
    在這里插入圖片描述

  • MP4主要的頂部box

    ftyp box:描述MP4鎖遵循的規(guī)范和版本

    mdat box :存放媒體數(shù)據(jù)

    moov box:存放媒體參數(shù)(pps、sps等)相關(guān)信息和用于索引媒體數(shù)據(jù)存儲(chǔ)位置的信息

  • MP4常用box
    在這里插入圖片描述

Box類(lèi)型詳解 Box格式

在這里插入圖片描述

  1. size字段為整個(gè)box的大小,包括box header和box body
  2. type為box的類(lèi)型,通常為四字節(jié)的字符串,例如ftyp
  3. 當(dāng)size == 0時(shí),box的大小為large size
  4. 當(dāng)box為full box時(shí),存在version和flags字段,具體含義因box不同而不同
  5. 若box沒(méi)有嵌套其他box,例如ftyp box,則box body部分根據(jù)具體規(guī)范解析相應(yīng)字段;若box為container box,則box body部分嵌套其它box,還需一步步解套獲取最終的數(shù)據(jù)
ftyp box
  • 字段分布圖
    在這里插入圖片描述

  • 字段解析

  • major_brand:比如常見(jiàn)的 isom、mp41、mp42、avc1、qt等。它表示“最好”基于哪種格式來(lái)解析當(dāng)前的文件。舉例,major_brand 是 A,compatible_brands 是 A1,當(dāng)解碼器同時(shí)支持 A、A1 規(guī)范時(shí),最好使用A規(guī)范來(lái)解碼當(dāng)前媒體文件,如果不支持A規(guī)范,但支持A1規(guī)范,那么,可以使用A1規(guī)范來(lái)解碼;

  • minor_version:提供 major_brand 的說(shuō)明信息,比如版本號(hào),不得用來(lái)判斷媒體文件是否符合某個(gè)標(biāo)準(zhǔn)/規(guī)范;

  • compatible_brands:文件兼容的brand列表。比如 mp41 的兼容 brand 為 isom。通過(guò)兼容列表里的 brand 規(guī)范,可以將文件 部分(或全部)解碼出來(lái);

mvhd box
  • 字段分布圖
    在這里插入圖片描述

  • 字段解析

    • version :一字節(jié)用于指定mvhd的版本

    • flags:3字節(jié),預(yù)留

    • Create time:媒體創(chuàng)建時(shí)間,與UTC時(shí)間不同的是,此時(shí)間是從1904年1月1日0:0:0開(kāi)始計(jì)算的,而utc是從1970年1月1日0:0:0開(kāi)始計(jì)算,故Create time須要減去時(shí)間差換算成utc時(shí)間

      // 注:66年時(shí)間差不是66*365*24*3600來(lái)計(jì)算
      creation_time_utc = creation_time - (66年時(shí)間差) = creation_time - 2082844800
    • Modification time:媒體最后被修改的時(shí)間,計(jì)算方式同Create time

    • Timescale:一秒包含的時(shí)間單位(整數(shù))。舉個(gè)例子,如果timescale等于1000,那么,一秒包含1000個(gè)時(shí)間單位(后面track等的時(shí)間,都要用這個(gè)來(lái)?yè)Q算,比如track的duration為10,000,那么,track的實(shí)際時(shí)長(zhǎng)為10,000/1000=10s);

    • Duration:影片時(shí)長(zhǎng)(整數(shù)),根據(jù)文件中的track的信息推導(dǎo)出來(lái),等于時(shí)間最長(zhǎng)的track的duration;

    • Preferred rate:推薦的播放速率,32位整數(shù),高16位、低16位分別代表整數(shù)部分、小數(shù)部分([16.16]),舉例 0x0001 0000 代表1.0,正常播放速度;

    • Preferred volume:播放音量,16位整數(shù),高8位、低8位分別代表整數(shù)部分、小數(shù)部分([8.8]),舉例 0x01 00 表示 1.0,即大音量;

    • Matrix struct:視頻的轉(zhuǎn)換矩陣,詳情看

      Basic Data Types

    • Next_track_ID:32位整數(shù),非0,一般可以忽略不計(jì)。當(dāng)要添加一個(gè)新的track到這個(gè)影片時(shí),可以使用的track id,必須比當(dāng)前已經(jīng)使用的track id要大。也就是說(shuō),添加新的track時(shí),需要遍歷所有track,確認(rèn)可用的track id;

tkhd box
  • 字段分布圖
    在這里插入圖片描述

  • 字段解析

    • version:tkhd box的版本;
    • flags:按位或操作獲得,默認(rèn)值是7(0x000001 | 0x000002 | 0x000004),表示這個(gè)track是啟用的、用于播放的 且 用于預(yù)覽的。
      • Track_enabled:值為0x000001,表示這個(gè)track是啟用的,當(dāng)值為0x000000,表示這個(gè)track沒(méi)有啟用;
      • Track_in_movie:值為0x000002,表示當(dāng)前track在播放時(shí)會(huì)用到;
      • Track_in_preview:值為0x000004,表示當(dāng)前track用于預(yù)覽模式;
    • Creation time:當(dāng)前track的創(chuàng)建時(shí)間;
    • Modification time:當(dāng)前track的最近修改時(shí)間;
    • Track ID:當(dāng)前track的唯一標(biāo)識(shí),不能為0,不能重復(fù);
    • Duration:當(dāng)前track的完整時(shí)長(zhǎng)(需要除以timescale得到具體秒數(shù));
    • Layer:視頻軌道的疊加順序,數(shù)字越小越靠近觀看者,比如1比2靠上,0比1靠上;
    • Alternate_group:當(dāng)前track的分組ID,alternate_group值相同的track在同一個(gè)分組里面。同個(gè)分組里的track,同一時(shí)間只能有一個(gè)track處于播放狀態(tài)。當(dāng)alternate_group為0時(shí),表示當(dāng)前track沒(méi)有跟其他track處于同個(gè)分組。一個(gè)分組里面,也可以只有一個(gè)track;
    • Volume:audio track的音量,介于0.0~1.0之間;
    • Matrix structure:視頻的變換矩陣;
    • Track width:視頻的寬
    • Track height:視頻的高
hdlr box
  • 字段分布圖
    在這里插入圖片描述

  • 字段解析

    • Version:hdlr box的版本
    • Flags:置0
    • Component type:四字節(jié)子串定義handler的類(lèi)型;此字段只有兩種值合法:'mhlr’(media handlers)和’dhlr’(data handlers)
    • Component subtype:針對(duì)Component type進(jìn)行細(xì)分類(lèi)型,例如’vide’定義為視頻數(shù)據(jù),'soun’定義為音頻數(shù)據(jù)
    • Component manufacturer:保留,置0
    • Component flags:保留,置0
    • Component flags mask:保留,置0
    • Component name:子串指定Component 的名字,可能為空
mdat box
  • 數(shù)據(jù)結(jié)構(gòu)分布圖
    在這里插入圖片描述

    注意:取到的frame前四個(gè)字節(jié)為frame數(shù)據(jù)的長(zhǎng)度字節(jié),須要偏移去掉

stbl box

主要存放了媒體參數(shù)(pps、sps、vps等)相關(guān)信息和用于解析mdat中視音頻數(shù)據(jù)的關(guān)鍵信息

  • stsd:給出視音頻的相關(guān)參數(shù)信息,有高寬、音量、位深度和每個(gè)sample多少個(gè)frame
  • stco:chunk在文件中的偏移
  • stsc:每個(gè)chunk中包含幾個(gè)sample
  • stsz:每個(gè)sample的size(單位是字節(jié))
  • stts:每個(gè)sample的時(shí)長(zhǎng)
  • stss:哪些sample是關(guān)鍵幀
stsd box
  • 字段分布圖
    在這里插入圖片描述

  • 字段解析

    • Version:stsd box的版本
    • Flags:置0
    • Number of entries:Sample description table的個(gè)數(shù)
    • Sample description table:以視頻為例,此時(shí)Sample description table字段中為若干個(gè)視頻編碼相關(guān)的box,例如avc1 box
      • avc1 box

        • 字段分布圖
          在這里插入圖片描述

        • 字段解析

          這個(gè)在https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html的“Sample Description Atoms”一節(jié)可以研究下

      • avcC box(包含了視頻關(guān)鍵參數(shù),在ISO/IEC 14496-15中定義)

        • 字段分布圖
          在這里插入圖片描述

        • 字段解析

          • num_of_sps:sps的個(gè)數(shù)
          • sps_length:sps的長(zhǎng)度
          • sps_nal_unit:長(zhǎng)度為sps_length的sps
          • num_of_pps:pps的個(gè)數(shù)
          • pps_length:pps的長(zhǎng)度
          • pps_nal_unit:長(zhǎng)度為pps_length的pps

          其他字段可以自行在ISO/IEC 14496-15中查到

stco box
  • 字段分布圖
    在這里插入圖片描述

  • 字段解析

    • Version:stco box的版本
    • Flags:置0
    • Number of entries:chunk的個(gè)數(shù)
    • Chunk offset table:每個(gè)chunk在整個(gè)視頻文件的偏移值,每個(gè)值的長(zhǎng)度為4字節(jié)
stsc box
  • 字段分布圖
    在這里插入圖片描述

  • 字段解析

    • Version:stsc box的版本
    • Flags:置0
    • Number of entries:”Sample-to-chunk table”的條數(shù)
    • Sample-to-chunk table:
      • First chunk:chunk的索引
      • Samples per chunk:從’First chunk’開(kāi)始,每個(gè)chunk中sample的個(gè)數(shù)
      • Sample description ID:stsd box中‘Sample description table’的下標(biāo)
  • Sample-to-chunk table示意圖
    在這里插入圖片描述

    • chunk1-chunk2:每個(gè)chunk中有3個(gè)sample,并且Sample description ID為23
    • chunk3-chunk4:每個(gè)chunk中有1個(gè)sample,并且Sample description ID為23
    • chunk5:每個(gè)chunk中有3個(gè)sample,并且Sample description ID為24
stsz box
  • 字段分布圖
    在這里插入圖片描述

  • 字段解析

    • Version:stsz box的版本
    • Flags:置0
    • Sample size:為0則表示所有sample的大小不一定一樣,不為0則表示所有sample的大小一樣
    • Number of entries:”Sample size table”的條數(shù)
    • Sample size table:每個(gè)sample的size,每個(gè)sample size的長(zhǎng)度為4字節(jié)
stts box
  • 字段分布圖
    在這里插入圖片描述

  • 字段解析

    • Version:stts box的版本
    • Flags:置0
    • Number of entries:“Time-to-sample table”的條數(shù)
    • Time-to-sample table:
      • Sample count:具有相同“Sample duration”的個(gè)數(shù)
      • Sample duration:sample的時(shí)長(zhǎng)(以timescale為計(jì)量)
  • Time-to-sample table:示意圖
    在這里插入圖片描述

    sample1 - sample4的sample duration是4

stss box
  • 字段分布圖
    在這里插入圖片描述

  • 字段解析

    • Version:stts box的版本
    • Flags:置0
    • Number of entries:“Sync sample table”的條數(shù)
    • Sync sample table:關(guān)鍵幀對(duì)應(yīng)的sample index
demuxer demo的實(shí)現(xiàn)(視頻數(shù)據(jù)部分)
  1. 獲取sps pps參數(shù)

    1. 解析stsd box,其中contain avc1 box和avcC box(此步驟詳解見(jiàn)上文)

    2. 解析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; 
    		 } 
    	 } 
    }
  2. 獲取關(guān)鍵幀位置

    解析stss box可以知道哪一個(gè)sample中包含關(guān)鍵幀

  3. 獲取chunk位置

    解析stco box可以獲取到每個(gè)chunk在視頻文件中的索引

  4. 獲取每個(gè)chunk中sample個(gè)數(shù)

    解析stsc box可以獲取到每個(gè)chunk包含多少個(gè)sample

  5. 獲取sample大小

    解析stsz box可以獲取到每個(gè)sample的大小

  6. 獲取frame位置(demo視頻文件一個(gè)sample只包含一個(gè)frame,所以sample的位置和大小就是frame的位置和大小)

    1. 根據(jù)stsd解析到每個(gè)sample中有多少個(gè)frame
    2. 然后再根據(jù)trunk的位置和sample的大小來(lái)定位frame起始地址
    3. mdat中frame的數(shù)據(jù)格式為: | 4字節(jié)數(shù)據(jù)長(zhǎng)度 | frame數(shù)據(jù)|,所以根據(jù)字節(jié)長(zhǎng)度讀取相應(yīng)個(gè)數(shù)frame
  7. 獲取到一幀數(shù)據(jù)后

    1. 判斷當(dāng)前frame為I幀,則添加寫(xiě)入(start_code+sps) + (start_code+pps) + (start_code + frame數(shù)據(jù))到輸出文件
    2. 判斷當(dāng)前frame不為I幀,則寫(xiě)入(start_code + frame數(shù)據(jù))到輸出文件
  8. 保存成h264文件,可使用ffplay和potplay播放

注意:有些非字串的字段為大端字節(jié)序,須要轉(zhuǎn)換

總結(jié):
  1. 解析非字符串的數(shù)據(jù)時(shí),需要注意大小端的問(wèn)題
  2. 解析對(duì)應(yīng)的box獲取到sps、vps、pps
  3. 解析對(duì)應(yīng)的box拿到視頻幀數(shù)據(jù)
  4. 將視頻幀寫(xiě)入本地文件的時(shí)候要注意
    1. 視頻幀前四個(gè)字節(jié)為視頻幀數(shù)據(jù)長(zhǎng)度
    2. 若為I幀則需要加上sps、vps、pps
    3. 視頻幀注意加上start_code
工具介紹
  1. mp4info—可以看到相關(guān)box的字節(jié)信息,但發(fā)現(xiàn)對(duì)avcC的解析漏掉了幾個(gè)字節(jié)
    在這里插入圖片描述

  2. mp4 exploer—可以更加直觀的看到視音頻數(shù)據(jù)信息
    在這里插入圖片描述

源碼

https://github.com/TaoChou/demuxer-c

參考
  1. https://zhuanlan.zhihu.com/p/333765990
  2. https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-25691
  3. ISO/IEC 14496-15

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧

文章標(biāo)題:c實(shí)現(xiàn)mp4解封裝-創(chuàng)新互聯(lián)
瀏覽地址:http://chinadenli.net/article26/didscg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信小程序品牌網(wǎng)站建設(shè)Google移動(dòng)網(wǎng)站建設(shè)建站公司自適應(yīng)網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)