2012年10月31日 星期三

[多媒體] FLV文件格式解析 Part 2 - H.264詳解

承繼 Part 1概說之後,接下來針對 Video Tag 中 H.264 資訊進行解析。

零、準備工具
1. Hex 文件編輯工具 (Ex: NotePad ++)
2. flvParser - flv文件分析器
3. 支援 FLV 格式的播放器 (Ex: VLC player)


一、分析RTMP上行的h264視頻流 (FLV格式)
    Figure 1. FLV 文件以 HEX 格式呈現 [#1]

    我們對照flv標準文檔來逐個分析
    171-keyframe  7-avc
    00AVC sequence header -- AVC packet type
    00 00 00composition timeAVC時,全0,無意義
    因為AVC packet type=AVC sequence header,接下來就是AVCDecoderConfigurationRecord的內容
    01configurationVersion
    42AVCProfileIndication
    00profile_compatibility
    1f:AVCLevelIndication
     fflengthSizeMinusOne -- FLVNALU包長資料所使用的位元組數,(lengthSizeMinusOne & 3+1,實際測試時發現總為ff,計算結果為4,下文還會提到這個資料

    E1numOfSequenceParameterSets -- SPS 的個數,numOfSequenceParameterSets & 0x1F,實際測試時發現總為E1,計算結果為1
    00 31sequenceParameterSetLength -- SPS 的長度,2個位元組,計算結果49
    67 42 80 1f 96 54 05 01 ed 80 a8 40 00 00 03 00 40 00 00 07 b8 00 00 20 00 00 03 01 00 01 fc 63 8c 00 00 10 00 00 03 00 80 00 fe 31 c3 b4 24 4d 40sequenceParameterSetNALUnits -- SPS,為剛才計算的49個位元組, SPS中包含了視頻長、寬的資訊

    01numOfPictureParameterSets -- PPS 的個數,實際測試時發現總為E1,計算結果為1
    00 04pictureParameterSetLength -- PPS 的長度
    68 ce 35 20:pictureParameterSetNALUnits -- PPS

    這裡插入一點NALU的小知識,每個NALU第一個位元組的前5位元標明的是該NAL包的類型,即NAL nal_unit_type


    前面我們解析的sps頭位元組為6767&0x1f = 7pps頭位元組為6868&0x1f=8,正好能對應上。


    接下來又是新的一包video tag資料
    171-keyframe  7-avc
    01AVC NALU
    00 00 00composition timeAVC時,全0,無意義
    因為AVCPacket type = AVC NALU,接下來就是一個或多個NALU
    每個NALU包前面都有 (lengthSizeMinusOne & 3+1個位元組的NAL包長度描述(前文提到的,還記得嗎),前面計算結果為4個位元組

    00 00 00 02 2 -- NALU length
    09 10NAL
    09&0x1f=9,訪問單元分隔符號

    00 00 00 29:說明接下來的NAL包長度為41
    06 00 11 80 00 af c8 00 00 03 00 00 03 00 00 af c8 00 00 03 00 00 40 01 0c 00 00 03 00 00 03 00 90 80 08 00 00 03 00 08 8006&0x1f=6 -- SEI
    00 00 3c d0:接下來的NAL包長度
    65 88 80……65&0x1f=5 -- I幀數據

    這包video tag分析到此結束了,下面會緊接著來一些該I幀對應的P幀資料, 見下圖
 
    00003d80那行,前面的內容一直到53 4f 7f都是上一個video tag的內容,即前面說的65 88 80那個I幀的資料拉,27開始是新的一個video tag

    272-inter frameP幀,7-codecid=AVC
    01AVCPacket type = AVC NALU
    00 00 00composition timeAVC時,全0,無意義

    00 00 00 02 09 30:跟上面分析的一樣拉,2個位元組的nal包,訪問單元分隔符號
    00 00 00 1117位元組的NAL
    06 01 0c 00 00 80 00 00 90 80 18 00 00 03 00 08 8006&0x1f=6-SEI
    00 00 46 85 NAL包數據長度
    41 9a 02…… 41&0x1f=1P幀數據


二、 H.264 轉換成 FLV 格式

    大致總結下flv h264流,按順序依次是
    1、一個video tag,包含的資訊:SPSPPS,訪問單元分隔符號,SEII幀包
    2、一個或多個video tag,包含的資訊:訪問單元分隔符號,SEIP幀包可為多個

    這裡需要說明下,做轉換這一步時,我們只需要從video tag中獲取到所有的、一個一個的NAL包就可以了,至於它是I幀、P幀及其他類型,實際上我們並不需要關心,這裡只是為了更好的分析資料。

    h264NALUNALU之間是由00 00 01(也可以是00 00 00 01)分隔開的,我們組成h264之後的格式為
    100 00 00 01 SPS 00 00 00 01 PPS 00 00 00 01 訪問單元分隔符號 00 00 00 01 SEI 00 00 00 01 I 00 00 00 01 P 00 00 00 01 P幀……(P幀數量不定)

    其中的訪問單元分隔符號和SEI不是必須的,將h264以二進位的形式寫入檔,使用 VLC 就可以播放了




[ Reference ]
#1> RTMP中FLV流到标准h264、aac的转换

沒有留言: