小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

從Slice_Header學(xué)習(xí)H.264(三.1)--相關(guān)細(xì)節(jié)之 POC的計(jì)算

 mediatv 2013-09-16

三、slice頭相關(guān)的一些細(xì)節(jié)

 

1.關(guān)于POC的計(jì)算

      

       圖像序列號(hào)(POC)主要用于標(biāo)識(shí)圖象的播放順序,同時(shí)還用于在對幀間預(yù)測片解碼時(shí),標(biāo)記參考圖像的初始圖像序號(hào)。

       對于每個(gè)編碼幀有兩個(gè)圖像序列號(hào),分別稱為頂場序列號(hào)(TopFieldOrderCnt)和底場序列號(hào)(BottomFieldOrderCnt );對于每個(gè)編碼場有一個(gè)圖像序列號(hào),對于一個(gè)編碼頂場其稱為TopFieldOrderCnt,對于編碼底場,其稱為 BottomFieldOrderCnt ;對于每個(gè)編碼場對有兩個(gè)圖像序列號(hào),TopFieldOrderCnt 和BottomFieldOrderCnt 分別用于標(biāo)記該場對的頂場和底場。

opFieldOrderCnt 和BottomFieldOrderCnt 分別指明了相應(yīng)的頂場/ 底場相對于前一個(gè)IDR 圖像,或解碼順序中前一個(gè)包含memory_management_control_operation=5的參考圖像(此值為5表示清空參考幀隊(duì)列,因 此有著跟IDR同樣的效果),的第一個(gè)輸出場的相對位置。這也意味著,只要遇到IDR圖像或 memory_management_control_operation=5的參考圖像,相應(yīng)的POC就等于零。

在H.264中,由于B幀可以進(jìn)行雙向預(yù)測,因此圖像的解碼順序可以不同于播放順序。

前面已經(jīng)提到,計(jì)算POC(也就是計(jì)算TopFieldOrderCnt和BottomFieldOrderCnt),有三種方法,具體使用哪種由序列參數(shù)集中的pic_order_cnt_type元素指定。下面一次介紹三種方法。

(1)      pic_order_cnt_type=0

本過程的輸入是在本節(jié)規(guī)定的解碼順序中前一圖像的PicOrderCntMsb,也即prevOrderCntMsb 。 關(guān)于Msb:POC由高位Msb和低位Lsb兩部分組成,當(dāng)Lsb發(fā)生溢出時(shí),會(huì)向Msb進(jìn)位,Msb+Lsb=POC。

本過程的輸出是TopFieldOrderCnt  和BottomFieldOrderCnt ,或者其中之一。

 

大致流程:首先計(jì)算變量 prevPicOrderCntMsb,然后計(jì)算當(dāng)前圖像的PicOrderCntMsb (剛剛提到POC=Msb+Lsb,Lsb已經(jīng)在碼流的slice_header中由pic_order_cnt_lsb指定,因此主要任務(wù)其實(shí)就是計(jì)算 Msb),最后計(jì)算當(dāng)前圖像的TopFieldOrderCnt  和(或) BottomFieldOrderCnt。

 

流程圖:


              其中,MaxPicOrderCntLsb由序列參數(shù)集中的log2_max_pic_order_cnt_lsb_minus4元素確定;delta_pic_order_cnt_bottom在片頭中指定,上文介紹POC時(shí)已介紹過。

              圖中所提到的“亂序”,指的是,解碼順序是否與播放順序不一致,準(zhǔn)確的說,如果當(dāng)前圖像的播放順序POC比上一個(gè)解碼圖像的播放順序prePOC小,就是 發(fā)生了亂序。那如何判斷是否發(fā)生亂序了呢?一般情況下,Msb在解碼順序相鄰的兩個(gè)圖片間不發(fā)生變化時(shí)(即Lsb不發(fā)生溢出或借位),只要判斷當(dāng)前解碼的 Lsb是否比之前解碼的Lsb小即可,如果比之前的小,說明亂序發(fā)生;但是如果Lsb發(fā)生溢出或借位時(shí),就不能這樣簡單的判斷了(前后兩幀的Msb將不再 相同),那如何判斷Lsb是否發(fā)生了溢出或借位呢?這就要用到一個(gè)規(guī)則:解碼順序相鄰的兩個(gè)圖像,他們的播放順序POC之差(的絕對值)不會(huì)超過MaxPicOrderCntLsb / 2,根據(jù)這個(gè)規(guī)則,計(jì)算解碼順序相鄰的兩幅圖像的Lsb之差,并與MaxPicOrderCntLsb/2進(jìn)行比較,就可判斷Lsb是否發(fā)生了溢出或借位。在標(biāo)準(zhǔn)中,關(guān)于Msb的計(jì)算是這樣描述的:

 

if( ( pic_order_cnt_lsb  < prevPicOrderCntLsb ) &&  

         ( ( prevPicOrderCntLsb ? pic_order_cnt_lsb )  >= ( MaxPicOrderCntLsb / 2 ) ) )

         PicOrderCntMsb = prevPicOrderCntMsb + MaxPicOrderCntLsb 

else if( ( pic_order_cnt_lsb  > prevPicOrderCntLsb )  &&

           ( ( pic_order_cnt_lsb ? prevPicOrderCntLsb )  >  (MaxPicOrderCntLsb / 2 ) ) )

         PicOrderCntMsb = prevPicOrderCntMsb ? MaxPicOrderCntLsb (這一步亂序發(fā)生)

else

         PicOrderCntMsb = prevPicOrderCntMsb

      

 

(1)      pic_order_cnt_type=1

本過程的輸入是在本節(jié)規(guī)定的解碼順序中前一圖像的FrameNumOffset。

本過程的輸出是TopFieldOrderCnt  和BottomFieldOrderCnt ,或者其中之一。

計(jì)算過程中涉及到兩個(gè)變量prevFrameNum  和prevFrameNumOffset ,其中prevFrameNum 是前一圖像的frame_num  ,而對于prevFrameNumOffset ,如當(dāng)前圖像不是IDR ,而前一圖像的memory_management_control_operation等于5 ,prevFrameNumOffset 設(shè)為0;否則,prevFrameNumOffset 設(shè)置等于前一圖像的FrameNumOffset;注意,當(dāng)序列參數(shù)及中的gaps_in_frame_num_value_allowed_flag 等于1 時(shí)(表示相鄰解碼圖像的frame_num可以出現(xiàn)間隔),通過frame_num 間隔的解碼過程可能會(huì)推斷出解碼順序中的前一幅圖像為“不存在”幀。

大致流程:


       畢厚杰書中的插圖并沒有完全解釋清楚,有很多細(xì)節(jié)沒有說明,看了這個(gè)圖還是感覺什么都沒看懂,所以這部分還是結(jié)合標(biāo)準(zhǔn)中的說明來看比較好,但標(biāo)準(zhǔn)中只是說了每個(gè)值該如何計(jì)算,而沒有詳細(xì)講解,因此要想搞懂每一步的意義也要費(fèi)點(diǎn)腦細(xì)胞才行。

a.關(guān)于absFrameNum:可以理解成“絕對幀序號(hào)”,而原來的frame_num則應(yīng)理解為相對幀序號(hào)。前面講frame_num時(shí)提到, 當(dāng)一個(gè)序列中的參考幀數(shù)量超過MaxFramenum時(shí),frame_num在達(dá)到MaxFramenum后會(huì)重新從0開始循環(huán)計(jì)數(shù),這樣的話,一個(gè)序列 中可能會(huì)存在兩個(gè)或多個(gè)參考圖像擁有相同的“相對幀序號(hào)(即frame_num)”的情況 。因此,如果需要一個(gè)符號(hào)來唯一地標(biāo)識(shí)一個(gè)序列中的所有參考幀,用相對幀序號(hào)是不行的,于是就需要為每個(gè)參考幀分配一個(gè)絕對幀序 號(hào):absFrameNum=FrameNumOffset + frame_num,F(xiàn)rameNumOffset代表當(dāng)前序列中frame_num已經(jīng)循環(huán)的次數(shù)與MaxFrameNum的積。 absFrameNum的具體計(jì)算過程如下:

       if(num_ref_frames_in_pic_order_cnt_cycle !=  0 )

            absFrameNum = FrameNumOffset +frame_num

    else 

            absFrameNum = 0

    if( nal_ref_idc  = = 0  &&  absFrameNum >  0 )

            absFrameNum = absFrameNum ? 1

 

       其中,num_ref_frames_in_pic_order_cnt_cycle在序列參數(shù)集中指定,其取值范圍[0,255],它是數(shù)組 offset_for_ref_frame[]的變化周期(或者說數(shù)組長度),這個(gè)數(shù)組也是在序列參數(shù)集中指定的,這個(gè)周期和這個(gè)數(shù)組到底什么意思呢?在 用第二種POC計(jì)算方法時(shí),一個(gè)參考幀跟下一個(gè)參考幀,他們POC的差值不能是任意的,必須是周期變化的,即每隔 num_ref_frames_in_pic_order_cnt_cycle個(gè)參考幀,相鄰參考幀之間POC的差值循環(huán)一次,而每個(gè)周期中,第i個(gè)差值 即為offset_for_ref_frame[i],正是這個(gè)規(guī)律,才使得第二種POC算法變得可行,在步驟c、d中將會(huì)看到這個(gè)數(shù)組的作用。

nal_ref_idc  = =  0 表示當(dāng)前圖像不是參考圖像。當(dāng)當(dāng)前圖像不是參考圖像時(shí),absFrameNum要額外減1。

 

b. picOrderCntCycleCnt 和 frameNumInPicOrderCntCycle 這倆分別代表absFrameNum對num_ref_frames_in_pic_order_cnt_cycle(前面說到的周期值)取模和取余。當(dāng) absFrameNum 大于0 時(shí),二者的值由如下方法得到:

if(absFrameNum  >  0 ) {

picOrderCntCycleCnt=(absFrameNum? 1 ) / num_ref_frames_in_pic_order_cnt_cycle ;

       //得到完整周期數(shù)。

frameNumInPicOrderCntCycle=(absFrameNum?1)%num_ref_frames_in_pic_order_cnt_cycle;

       //得到最后一個(gè)不完整的周期中參考幀的數(shù)量

}

 

c.關(guān)于expectedDeltaPerPicOrderCntCycle:代表每隔一個(gè)完整周期,POC總的變化量。求這個(gè)值只需將上面說到的數(shù)組中各個(gè)元素相加即可。

expectedDeltaPerPicOrderCntCycle = 0

for( i = 0;  i <num_ref_frames_in_pic_order_cnt_cycle; i++ )

expectedDeltaPerPicOrderCntCycle += offset_for_ref_frame[ i ] 

      

       d.關(guān)于expectedPicOrderCnt:期望的POC值。要得到這個(gè)值,只需用POC在一個(gè)完整周期內(nèi)的總變化量乘以周期數(shù),再加上最后一個(gè)不完整周期跨越的POC數(shù)量即可。

              if(absFrameNum > 0 ){

                     expectedPicOrderCnt=picOrderCntCycleCnt* expectedDeltaPerPicOrderCntCycle

           for( i = 0; i <= frameNumInPicOrderCntCycle; i++ )

 //循環(huán)計(jì)算最后一個(gè)不完整周期所跨越的POC數(shù)量。

expectedPicOrderCnt = expectedPicOrderCnt + offset_for_ref_frame[ i]

        } else

           expectedPicOrderCnt = 0

      if( nal_ref_idc  = =  0 )      //對于非參考圖像

           expectedPicOrderCnt = expectedPicOrderCnt + offset_for_non_ref_pic

              其中,offset_for_ref_frame[ i ](前面已經(jīng)說過)和offset_for_non_ref_pic都是在序列參數(shù)集中指定,他們的取值范圍都是[-2^31,2^31-1]。

 

e.變量TopFieldOrderCnt  或 BottomFieldOrderCnt 的值由如下方法得到:

if( !field_pic_flag ) {    //當(dāng)前圖像不是場圖像

           TopFieldOrderCnt = expectedPicOrderCnt + delta_pic_order_cnt[ 0 ]

           BottomFieldOrderCnt = TopFieldOrderCnt +

                          offset_for_top_to_bottom_field + delta_pic_order_cnt[ 1 ]  

        } else if( !bottom_field_flag )

            TopFieldOrderCnt = expectedPicOrderCnt + delta_pic_order_cnt[ 0 ]

      else

           BottomFieldOrderCnt =  expectedPicOrderCnt + offset_for_top_to_bottom_field +delta_pic_order_cnt[ 0 ]

      

       其中,offset_for_top_to_bottom_field在序列參數(shù)集中指定,delta_pic_order_cnt[ 0或1 ]在片頭指定。

       補(bǔ)充:從上面的過程中可以看到,當(dāng)圖像序列中出現(xiàn)兩個(gè)或多個(gè)連續(xù)的非參考幀時(shí),這些非參考幀將具有相同的POC期望值(即 expectedPicOrderCnt),但是他們的頂場序號(hào)和底場序號(hào)可以通過各自的delta_pic_order_cnt[0和1 ]加以區(qū)別。因此第二種POC計(jì)算方法也是支持圖像序列中出現(xiàn)連續(xù)非參考幀的。而下面將介紹的第三種POC計(jì)算方法則不支持連續(xù)的非參考幀。

 

 

(1)      pic_order_cnt_type=2

第三種POC計(jì)算方法所依賴的額外參數(shù)最少(可以節(jié)省片頭的比特?cái)?shù)),它只根據(jù)frame_num就可以得到頂、底場的序列號(hào)。但是缺點(diǎn)是,用這種方法時(shí),不允許圖像序列中出現(xiàn)連續(xù)的非參考幀。

大致流程:



這個(gè)方法不像第二種那么麻煩,從圖示中已可以看出完整的過程。唯一需要說的一點(diǎn)是,最后計(jì)算頂、底場序號(hào)時(shí)的規(guī)則(這個(gè)規(guī)則在三種方法中各不相同):

       if(!field_pic_flag ) {

           TopFieldOrderCnt = tempPicOrderCnt

           BottomFieldOrderCnt = tempPicOrderCnt 

} else if(bottom_field_flag )

           BottomFieldOrderCnt = tempPicOrderCnt

else

            TopFieldOrderCnt = tempPicOrderCnt

 

       在這種方法中,如果解碼順序相鄰的兩個(gè)幀具有相同的frame_num,那么其中必有一個(gè)是參考幀,而另一個(gè)則是非參考幀,而且參考幀總是在非參考幀之前進(jìn)行編解碼(和傳輸),但非參考幀比參考幀先采樣和播放(即非參考幀的POC更靠前)。

 

 


    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多