I帧和IDR帧区别
From:?http://blog.csdn.net/skygray/article/details/6223358
I?幀和?IDR?幀的區(qū)別:
??? IDR?幀屬于?I?幀。解碼器收到?IDR frame??時(shí),將所有的參考幀隊(duì)列丟棄?(用x264_reference_reset?函數(shù)實(shí)現(xiàn)——在?encoder.c?文件中)?。這點(diǎn)是所有?I?幀共有的特性,但是收到?IDR?幀時(shí),解碼器另外需要做的工作就是:把所有的?PPS?和?SPS?參數(shù)進(jìn)行更新。由此可見,在編碼器端,每發(fā)一個(gè)?IDR?,就相應(yīng)地發(fā)一個(gè)??PPS&SPS_nal_unit
?????這是網(wǎng)上搜索到的一個(gè)答案,有一定參考價(jià)值吧。
先說明:所有的?IDR?幀都是?I?幀,但是并不是所有?I?幀都是?IDR?幀。就是說,?IDR?幀是?I?幀的子集。?(我們程序中設(shè)定的是每250幀出現(xiàn)一個(gè)?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_?I?;
?????}
??????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_?I?;
?????}
?????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?函數(shù)的定義如下:?(其實(shí),因?yàn)檫@個(gè)代碼是通用的,所以應(yīng)該是參考幀隊(duì)列。但是,我們只用一個(gè)參考幀,“隊(duì)列”并沒有意義。)
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?幀時(shí)才會(huì)?將所有的參考幀隊(duì)列丟棄(?x264_reference_reset?( h );?)?。其實(shí),我們的程序默認(rèn)只用一個(gè)參考幀,這個(gè)問題就不是十分有意義了。
??? 多參考幀情況下。
??? 舉個(gè)例子?:有如下幀序列:?IPPPP?I?P?PPP?……(我們程序沒有?B?幀,所以幀序列簡(jiǎn)單些,但道理是一樣的)。按照?3?個(gè)參考幀編碼。
?????因?yàn)椤鞍凑?3?個(gè)參考幀編碼”,所以參考幀隊(duì)列長(zhǎng)度為?3?。
??? 遇到綠色的?I?時(shí),并不清空參考幀隊(duì)列,把這個(gè)?I?幀加入?yún)⒖紟?duì)列(當(dāng)然?I?編碼時(shí)不用參考幀。)。再檢測(cè)到紅色的?P?幀時(shí),用到的就是?PPI?三幀做參考了。
?????不怕自己羅嗦(好記性不如爛筆頭),再?gòu)?qiáng)調(diào)一個(gè):?一個(gè)參考幀,就是參考當(dāng)前幀的前面的那幀(因?yàn)闆]涉及到?B?幀,所以“前面的那幀”既是播放順序的,也是編碼順序的)。多個(gè)參考幀是一個(gè)道理?。?(?我以前一直誤解為從前面的幾幀中找到最合適的一個(gè)參考幀)
?????最后,“?但是收到?IDR?幀時(shí),解碼器另外需要做的工作就是:把所有的?PPS?和?SPS?參數(shù)進(jìn)行更新。由此可見,在編碼器端,每發(fā)一個(gè)?IDR?,就相應(yīng)地發(fā)一個(gè)??PPS&SPS_nal_unit?”應(yīng)該是對(duì)的吧。先這樣認(rèn)為:)
偶然機(jī)會(huì),查到:?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?的出現(xiàn)其實(shí)是相當(dāng)于向解碼器發(fā)出了一個(gè)清理?reference buffer?的信號(hào)吧,上面說前于這一幀的所有已編碼幀不能為?inter?做參考幀了。”??
還有:“?因?yàn)?264?采用了多幀預(yù)測(cè),就有可能在?display order?下?I?幀后的?P?會(huì)參考?I?幀前的幀,這樣在?random access?時(shí)如果只找?I?幀,隨后的幀的參考幀可能?unavailable?,?IDR?就是這樣一種特殊的?I?幀,把它定義為確保后面的?P?一定不參考其前面的幀,可以放心地?random access?。
總結(jié)
- 上一篇: 产品经理的高阶能力:架构图的设计与画法
- 下一篇: maven正确的集成命令-U-B