幀間運動是基于視訊亮度(luma)不發生改變的一個假設,而在視訊序列中經常能遇到亮度變化的場景,比如淡入淡出、鏡頭光圈調整、整體或局部光源改變等,在這些場景中,簡單幀間運動補償的效果可想而知(實際編碼中遇到亮度變化的宏塊,R-D模型的最後結果通常都是用幀内預測編碼),權重預測的提出就是為 了應對亮度變化的場景。
在h.264中兩種預測模式:顯示模式(explicit mode)與隐式模式(implicit mode),另外還有一種預設預測模式,不過這相當于不進行預測。
P幀與B幀都有顯式模式,隐式模式隻有B幀适用。至于怎麼區分兩種模式,簡單來說,顯式模式,需要在片頭中傳輸權重(weight),而隐式模式則不需要。
權重預測可以分為三個步驟:
- 亮度變化檢測。一般是用門檻值判斷亮度是否發生變化。
- 确定權重與偏移。就目前來說,用的都是簡單的權重預測算法,這步是跟亮度變化檢測連在一起的,因為是用權重來判斷亮度是否發生了變化。
- 亮度補償,把參考幀通過權重與偏移的線性補償得到權重參考幀。
顯式模式
對于顯式模式來說,我們可以認為亮度在目前幀與參考幀是線性變化的,既有如下關系:
LumaCur=weight×LumaRef+offset25LumaCur=weight×LumaRef+offset25
其中權重(weight)會被歸一化為32(2^5),是以我們就可以用weight與offset來表示兩幀亮度的變化:
weight=25⋅∑LumaCurij∑LumaRefijweight=25⋅∑LumaCurij∑LumaRefij
{0≤i<imgWidth0≤j<imgHeight{0≤i<imgWidth0≤j<imgHeight
盡管這種用整個幀的亮度做比較會忽視圖像的局部變化,但是由于其簡單的計算方式,目前JM還是用的這種方法來得到權重。當然,在得到權重之後我們需要判斷該權重是否超出既定的門檻值,如果超出門檻值則表示亮度沒有發生變化,采用預設的權重預測(即不預測)。
offset=0offset=0 在JM中offsetoffset預設為0
隐式模式
隐式模式也同樣是基于亮度線性變化的假設。B幀與其兩個參考幀:RefFront與RefBack在POC位置上保持着線性的關系
weightBackweightFront=26⋅LengthFrontLengthFront+LengthBack=26−weightBackweightBack=26⋅LengthFrontLengthFront+LengthBackweightFront=26−weightBack
無論前向參考幀與後向參考幀距離有多長,最終都會歸一化為64,然後求出兩個參考幀的權重
最後的亮度補償隻是把參考幀用weight與offset進行線性處理而已
Lumaij′=weight×LumaRefij+offset2nLumaij′=weight×LumaRefij+offset2n
最最後需要補充一句的是,因為目前還沒确定應該用參考幀清單中的哪一幀作為目前幀的參考幀,是以權重預測必須對目前參考幀清單中的所有幀求出weightweight與offsetoffset,而隐式模式,更是需要對listX[0]listX[0]與listX[1]listX[1]兩個參考幀清單中所有的幀進行listXSize[0]×listXSize[1]listXSize[0]×listXSize[1]次配對後,再分别求出每對參考幀的兩個weightweight與offset