使用Intel media SDK h264編碼後的數據幀分析及用vlc播放不出原因分析

使用Intel media SDK硬編碼H264數據然後保存成264文件,用vlc播放失敗。

默認編碼是第一幀有IDR幀,後續都沒有I幀,這裏打開保存的264文件分析數據幀時發現其數據幀如下

 

從上圖中可以看到,第一個00 00 00 01 09可以判斷出是分界符的類型,第二個00 00 00 01 27是SPS,第三個00 00 00 01 28是PPS,第四個00 00 00 01 06是SEI,第五個00 00 01 25纔是IDR。判斷類型補充如下,參考https://blog.csdn.net/jefry_xdz/article/details/8461343

我們還是接着看最上面圖的碼流對應的數據來層層分析,以00 00 00 01分割之後的下一個字節就是NALU類型,將其轉爲二進制數據後,解讀順序爲從左往右算,如下:
(1)第1位禁止位,值爲1表示語法出錯
(2)第2~3位爲參考級別
(3)第4~8爲是nal單元類型

例如上面00000001後有67,68以及65

其中0x67的二進制碼爲:
0110 0111
4-8爲00111,轉爲十進制7,參考第二幅圖:7對應序列參數集SPS

其中0x68的二進制碼爲:
0110 1000
4-8爲01000,轉爲十進制8,參考第二幅圖:8對應圖像參數集PPS

其中0x65的二進制碼爲:
0110 0101
4-8爲00101,轉爲十進制5,參考第二幅圖:5對應IDR圖像中的片(I幀)

接着是後面的非IDR幀數據,如下圖

依次分別是0x00 00 00 01 09(分隔符)|| 0x00 00 00 01 28(PPS)|| 0x00 00 00 01 06(SEI)|| 0x00 00 01 21(非IDR)。

所以用vlc播放失敗的原因就在於這個分隔符,必須去掉這個分隔符才行。

Intel media SDK裏有個sample_encode命令行程序,在執行sample_encode.exe h264 -i out.yuv -o out.264 -w 544 -h 960 -PicTimingSEI:off的時候,發現仍然沒有去掉這個0x00 00 00 01 09(分隔符),通過參考https://blog.jianchihu.net/intel-media-sdk-remove-unused.html,發現在代碼裏pipeline_encode.cpp文件裏添加m_CodingOption.AUDelimiter = MFX_CODINGOPTION_OFF;能去掉分隔符,如下:

   //-PicTimingSEI:off添加這個選項pInParams->nPicTimingSEI就會爲true
if (pInParams->nPicTimingSEI || pInParams->nNalHrdConformance || pInParams->nVuiNalHrdParameters)
    {
        //只有進入到這裏通過設置bCodingOption爲true,m_CodingOption的配置才能生效
        m_CodingOption.PicTimingSEI = pInParams->nPicTimingSEI;
        m_CodingOption.NalHrdConformance = pInParams->nNalHrdConformance;
        m_CodingOption.VuiNalHrdParameters = pInParams->nVuiNalHrdParameters;
        
        //這行代碼纔是關鍵,很奇怪的是在inter media sdk說明文檔裏對這個測試程序的附加選項中沒有這個值的對應選項,目前只能在代碼裏設置,不能通過命令行來設置
        m_CodingOption.AUDelimiter = MFX_CODINGOPTION_OFF;
        bCodingOption = true;
    }
    if (bCodingOption)
    {
        m_EncExtParams.push_back((mfxExtBuffer *)&m_CodingOption);
    }

 

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