在上一節《基於行的幀內編碼》介紹了在幀內編碼時將塊按水平或垂直劃分為1d塊,然後對每個1d塊按同樣的幀內模式逐行編碼。hevc在編碼端選擇幀內模式時使用兩階段方法降低複雜度,在第一階段使用快速rd cost方法計算所有幀內模式的rd cost,其中失真用hadamard變換估計。將rd cost最小的模式放入fimcl(fast intra mode candidate list)。然後在第二階段計算列表中的所有模式的rd cost,選擇rd cost最小的模式作為最佳模式。使用lip時,在上面的計算中不僅要考慮幀內模式還要考慮lip劃分(水平或垂直),這些模式的組合將大大增加計算複雜度。然而,有時並不需要編碼完所有1d塊才知道該模式是否是最優。因此本文將介紹幾種lip快速演算法。
上圖是使用加速演算法後的流程圖。
cu中所有lip劃分的1d塊都使用同一種幀內**模式,所以可以復用2d情況下的fimcl來確定要測試哪些模式。
從上面的流程圖可以看見,編碼器按順序處理每一行。假設cu劃分為n行,在第i次迭代時編碼第i行然後計算其rd cost,編碼完所有行後將各行rd cost相加得到整個cu的rd cost。
但是有時候並不需要計算完所有行也能判斷該模式是否是最優。假設在嘗試當前模式前已經獲得的最小rd cost為cmin,如果按當前模式編碼當前cu,在編碼第i行時rd cost已經大於cmin了那麼就沒有必要繼續編碼了,當前模式肯定不是最優的。否則繼續編碼第i+1行。如果編碼完後rd cost小於cmin則更新cmin。
對於上一步早停止來說初始cmin越小越好,這樣就可以使那些非最優模式盡早停止。為了使初始cmin最小我們需要最先嘗試那些可能是最優的模式。所以在嘗試劃分模式時首先嘗試那些劃分後行數少的模式,例如對4x16的塊如果水平劃分會產生16行(4x1),垂直劃分會產生4行(1x16),所以應該優先嘗試垂直劃分。
為了使lip避免嘗試那些最不可能的幀內模式和1d劃分模式的組合,需要對fimcl進行修正,分為三步。
對fimcl中的所有幀內模式使用2d dct-ii計算rd cost,並且儲存下來。
將第1步內最小的2d dct-ii rd cost乘以乙個閾值作為門限值,凡是2d dct-ii rd cost大於這個門限值的幀內模式都被排除掉。
對第2步列表內的剩餘模式測試1d劃分方式。
cbf語法元素用於標識乙個塊是否有非零係數。如果乙個塊的cbf等於0,通常表示這個塊內容非常平坦,rd cost非常小,在這種情況下沒必要對其使用lip模式。
對於那些進行2d dct-ii變換後signifificant coeffificients數量小於特定閾值的塊不使用lip模式,其中閾值由塊尺寸決定。
令r=log2(w/h),如果滿足下面其中乙個條件則跳過那些產生行數多的劃分模式(類似於前面的1d劃分順序),
|r|>1且幀內模式是非角度模式
|r|>2且幀內模式是角度模式
有時鄰近的角度模式(例如模式4和5)會產生相似的rd結果,因此將這些模式聚合為乙個集合,每個集合只測試乙個模式會大大降低計算複雜度。如果乙個集合測試的那個模式可能是最優模式則該集合內的所有模式都要測試一遍。
在1d劃分早停止中當編碼完第i行後就將si和cmin進行比較。如果假設cost在n行中均勻分布則可以將si和cmin的比例值進行比較,如下,
下表是不同加速演算法的效果。
下表version a沒有使用假設演算法,version i使用了上面所有加速演算法。
sqrt的快速演算法 參考)
在3d圖形程式設計中,經常要求平方根或平方根的倒數,例如 求向量的長度或將向量歸一化。c數學函式庫中的sqrt具有理想的精度,但對於3d遊戲程式來說速度太慢。我們希望能夠在保證足夠的精度的同時,進一步提高速度。carmack在quake3中使用了下面的演算法,它第一次在公眾場合出現的時候,幾乎震住了...
矩陣求逆的快速演算法
前 1 如果是正交矩陣,則它的轉置就是它的逆,2 boost下面有庫 ublas basic linear algebra library 基本的線性代數都有了,你去看看吧 www.boost.org3 對於2x2 3x3 公式,演算法介紹 矩陣求逆在3d程式中很常見,主要應用於求billboard...
大數乘法求尾數的快速演算法
今天,在做zju的題目的時候遇到了大數乘法求尾數的問題。最後發現了,其實不需要把實際數值求出來就可以知道尾數。只要每次都記錄最後一位模10的結果就可以了。原理如下 求 n m k 的最後一位數字。把 n m和k轉換成 10 進製 n a0 10 0 a1 10 1 a2 10 2 ai 10 i m...