I幀和IDR幀區別(轉載)

幀和 IDR 幀的區別:

    IDR 幀屬於 I 幀。解碼器收到 IDR frame  時,將所有的參考幀隊列丟棄 (用 x264_reference_reset 函數實現——在 encoder.c 文件中) 。這點是所有 I 幀共有的特性,但是收到 IDR 幀時,解碼器另外需要做的工作就是:把所有的 PPS 和 SPS 參數進行更新。由此可見,在編碼器端,每發一個 IDR ,就相應地發一個  PPS&SPS_nal_unit

     這是網上搜索到的一個答案,有一定參考價值吧。

 

先說明:所有的 IDR 幀都是 I 幀,但是並不是所有 I 幀都是 IDR 幀。就是說, IDR 幀是 I 幀的子集。 (我們程序中設定的是每250幀出現一個 IDR 幀)

我們用的程序是這樣的:

      /* ------------------- Setup frame context ----------------------------- */

     /* 5: Init da ta dependant of frame type */

     if ( h->fenc->i_type ==  X264_TYPE_IDR  )

     {

          /* reset ref pictures */

           x264_reference_reset ( h );

         i_nal_type      =  NAL_SLICE_IDR ;

         i_nal_ref_idc = NAL_PRIORITY_ HIGHEST ;

         i_slice_type = SLICE_TYPE_ ;

     }

      else if ( h->fenc->i_type ==  X264_TYPE_I  )

     {

         i_nal_type      =  NAL_SLICE ;

         i_nal_ref_idc = NAL_PRIORITY_ HIGH ;  /* Not completely true but for now it is (as all I/P are kept as ref)*/

         i_slice_type = SLICE_TYPE_ ;

     }

     else if ( h->fenc->i_type ==  X264_TYPE_P  )

     {

         i_nal_type      = NAL_SLICE;

         i_nal_ref_idc = NAL_PRIORITY_HIGH;  /* Not completely true but for now it is (as all I/P are kept as ref)*/

         i_slice_type = SLICE_TYPE_P;

     }

     else if ( h->fenc->i_type ==  X264_TYPE_BREF  )

     {

         i_nal_type      = NAL_SLICE;

         i_nal_ref_idc = NAL_PRIORITY_HIGH;  /* maybe add MMCO to forget it? -> low */

         i_slice_type = SLICE_TYPE_B;

     }

     else       /*  B  frame */

     {

         i_nal_type      = NAL_SLICE;

         i_nal_ref_idc = NAL_PRIORITY_DISPOSABLE;

         i_slice_type = SLICE_TYPE_B;

}

    x264_reference_reset 函數的定義如下: (其實,因爲這個代碼是通用的,所以應該是參考幀隊列。但是,我們只用一個參考幀,“隊列”並沒有意義。)

static inline void  x264_reference_reset( x264_t *h )

{

     int i;

     /* reset ref pictures */

     for ( i = 1; i < h->frames.i_max_dpb; i++ )

     {

         h->frames.reference[i]->i_poc = -1;

     }

     h->frames.reference[0]->i_poc = 0;

}

 

     看來,好像是遇到 IDR 幀時纔會 將所有的參考幀隊列丟棄( x264_reference_reset ( h ); ) 。其實,我們的程序默認只用一個參考幀,這個問題就不是十分有意義了。

 

    多參考幀情況下。

    舉個例子 :有如下幀序列: IPPPP PPP ……(我們程序沒有 B 幀,所以幀序列簡單些,但道理是一樣的)。按照 3 個參考幀編碼。

     因爲“按照 3 個參考幀編碼”,所以參考幀隊列長度爲 3 。

 

    遇到綠色的 時,並不清空參考幀隊列,把這個 I 幀加入參考幀隊列(當然 I 編碼時不用參考幀。)。再檢測到紅色的 幀時,用到的就是 PPI 三幀做參考了。

 

 

 

     不怕自己羅嗦(好記性不如爛筆頭),再強調一個: 一個參考幀,就是參考當前幀的前面的那幀(因爲沒涉及到 B 幀,所以“前面的那幀”既是播放順序的,也是編碼順序的)。多個參考幀是一個道理 。 ( 我以前一直誤解爲從前面的幾幀中找到最合適的一個參考幀)

     最後,“ 但是收到 IDR 幀時,解碼器另外需要做的工作就是:把所有的 PPS 和 SPS 參數進行更新。由此可見,在編碼器端,每發一個 IDR ,就相應地發一個  PPS&SPS_nal_unit ”應該是對的吧。先這樣認爲:)

偶然機會,查到: IDR-instantaneous decoding refresh (IDR)picture 

 

      A coded picture in which all slices are I or SI slices that causes the decoding process to mark all reference pictures as "unused for reference" immediately after decoding the IDR picture. After the decoding of an IDR picture all following coded pictures in decoding order can be decoded without inter prediction from any picture decoded prior to the IDR picture. The first picture of each coded video sequence is an IDR picture. 

     “也就是說 ,IDR 的出現其實是相當於向解碼器發出了一個清理 reference buffer 的信號吧,上面說前於這一幀的所有已編碼幀不能爲 inter 做參考幀了。”  

還有:“ 因爲 264 採用了多幀預測,就有可能在 display order 下 I 幀後的 P 會參考 I 幀前的幀,這樣在 random access 時如果只找 I 幀,隨後的幀的參考幀可能 unavailable , IDR 就是這樣一種特殊的 I 幀,把它定義爲確保後面的 P 一定不參考其前面的幀,可以放心地 random access 。

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