天天看點

H.264 中的相關問題

幀内解碼時,在解碼端,首先通過目前宏塊左邊、上邊已經解碼完成的宏塊使用目前宏塊的預測模式(預測模式計算過程請參見我的論文《H.264數字視訊差錯控制技術的研究》,在群FTP“本群原創資料”目錄中)得到目前宏塊的像素預測值。然後通過對碼流進行解碼得到目前宏塊的像素殘差。最後将殘差和預測值加在一起就得到重構的像素值。如果目前宏塊的左邊或者右邊的宏塊不存在(即目前宏塊為圖像邊界上的宏塊),那麼其預測值全部為128。

幀間解碼時,在解碼端,首先對碼流進行解碼得到目前宏塊的參考幀,然後通過目前宏塊周圍宏塊計算運動矢量預測值(具體方法見畢厚傑書99頁,标準中也有,但我一時不知道在什麼地方了)。然後通過對碼流進行解碼得到目前宏塊的運動矢量殘差。将運動矢量殘差與運動矢量預測值相加得到實際的運動矢量。然後通過對碼流進行解碼得到目前宏塊的像素殘差(如果目前宏塊有像素殘差的話)。然後通過參考幀與上面計算得到的MV計算出目前宏塊的像素預測值。再将像素預測值與像素殘差相加就得到目前宏塊的重構。

說明:

1、以上過程為 JM86 的解碼過程。并不一定所有代碼都按照這個流程;    

2、上面說的運動矢量預測值的計算過程實際是以4*4塊為機關,參考幀也是針對4*4塊做的。這裡寫成宏塊主要是友善大家了解。

RDO

Rate-Distortion Optimization 是視訊編碼中最優選擇mode的一種方法。比如h.264裡好多mode 8x8 16x16 I4x4 I16 在給定的條件下,哪個是最好的?

Distortion 是指選用candidate mode産生的失真,rate是用這個mode需要的rate.他們換算成RDCost = Distortion + lamda * rate. 兩個mode誰的rdcost 低就選誰,其中的數學原理是條件極值轉非條件極值。

JM 裡用的RDO是比較經典的方法。最早是Gary J.Sullivan做的 參見 IEEE Signal Processing Magazine 1998 Nov.  "Rate-Distortion Optimization for video compression" rdo的經典。 h264裡的rdo還可參考CSVT H.264 special issue.

在H.264裡面目前幀屬于哪個slice的決定形式是多種多樣的,對于JM中的碼流中,一般一幀圖象就認為是一個slice,那麼如果目前幀是一個I幀,那麼它就屬于一個I slice.這時整個frame的為一個slice.但是具體我們用什麼樣的方式來進行slice type的決策呢,這也是一個問題。我們看一下T264裡面是如何處理這個問題的。

在T264中,如果我們設定了,USE_SCENEDETECT的話,目前的slice種類是由目前幀的幀号與設定的idrframe,iframe跟bframe相關的,如果frame_no%idrframe==0的話,那麼說明目前幀是屬于一個IDR slice的,如果frame_no%iframe==0的話,該幀屬于一個I slice.如果上面的情況不滿足那麼是屬于P slice或B slice.由于碼流中隻有如下幾種類型:0) I P P P ..... I P P P  1) I B P B P.....B P B P   2) I B B P B B P.....B B P I B B P,是以如果frame_no%(bframe+1)==0的話,就屬于P slice,如果不是的話屬于B slice.

如果沒有使用USE_SCENEDETECT的話,是用MeAnalysis來決定目前屬于什麼slice的。這種形式是動态式地決定是不是要加入一個I slice。決定流程如下:如果我們達到了我們在config裡面設定的iframe interval的話,目前幀就是一個I slice.我們設定一個INTRA_THRESHOLD,對幀中的每一個宏塊進行預測,來計算sad.這個過程因為計算量比較大,是以使用了簡化算法,首先用前一幀的mv做預測值,計算sad,如果這個值大于我們設定的SEARCH_THRESHOLD的話,說明上一幀的mv已不适合做目前幀的預測,我們會使用一個簡化的diamond search來簡單地找一下目前宏塊的mv,進行sad計算。整個幀的sad計算結束之後,我們與INTRA_THRESHOLD進行比較,如果sad大的話,這一幀為I slice中的一幀,如果小的話,我們認為它是一個P或B幀。對于目前幀是P還是B幀還是用上面的方法進行。

繼續閱讀