【H.264/AVC视频编解码技术具体解释】十三、熵编码算法(4):H.264使用CAVLC解析宏块的残差数据...
《H.264/AVC視頻編解碼技術具體解釋》視頻教程已經在“CSDN學院”上線,視頻中詳述了H.264的背景、標準協議和實現,并通過一個實戰project的形式對H.264的標準進行解析和實現,歡迎觀看!
“紙上得來終覺淺。絕知此事要躬行”。僅僅有自己依照標準文檔以代碼的形式操作一遍,才干對視頻壓縮編碼標準的思想和方法有足夠深刻的理解和體會。
鏈接地址:H.264/AVC視頻編解碼技術具體解釋
GitHub代碼地址:點擊這里
1. H.264的CAVLC解析宏塊殘差數據的流程
在H.264的解碼器在解析宏塊的殘差數據時。其流程相似于上文提到的CAVLC編碼的逆過程。
在解析一個宏塊殘差的時候。首先解析的是殘差矩陣的非零系數以及拖尾系數的個數numCoeff和trailingOnes。隨后是每個拖尾系數的符號trailingSigns。而后是每個非拖尾非零系數level的值。然后解析的是最高頻非零系數前面的零的總個數totalZeros。最后是每個非零系數前連續零的個數runBefore。
2. 計算CAVLC解析殘差的上下文參數
CAVLC編解碼過程中的上下文即為當前塊值numberCurrent。該值與當前像素塊的左側鄰塊和上方鄰塊中非零系數的個數有關。
以尺寸為4×4宏塊切割方式為例。當前像素塊同左側和上方鄰塊的相對位置關系例如以下圖:
對于當前像素塊。若其上方和左側相鄰塊都不可見(unavailable),那么當前像素塊的numberCurrent值為0;若上方或左側,有且僅有一個相鄰塊是可見的。那么當前像素塊的numberCurrent值即為這個鄰塊中非零系數的個數numCoeff;若兩個鄰塊都是可見的,那么當前像素塊的numberCurrent值為兩個鄰塊numCoeff的四舍五入平均值。
3. 解析非零系數總個數和拖尾系數個數
在CAVLC的解析過程中。非零系數總個數numCoeff和拖尾系數個數trailingOnes兩個值是一起解析出來的。
解析這兩個值依據的是標準文檔中的表9-5,例如以下表即是表9-5的部分:
依據之前解析出來的numberCurrent值,在這個表格中選擇一列作為解碼數據的參考。此后,從碼流中讀取對應長度的二進制碼流。與表格中的值相比較。當碼流與表格中的值匹配時,表格的前兩列作為數組的下標。其值即等于希望解析出來的numCoeff和trailingOnes的值。
4. 解析拖尾系數的符號
我們知道變換系數矩陣中最高頻的幾個絕對值為1的非零系數稱之為拖尾系數,其個數范圍為0~3個。
表示每個拖尾系數的符號能夠一個bit的trailing_ones_sign_flag表示:
- 當trailing_ones_sign_flag為1,拖尾系數符號為-。
- 當trailing_ones_sign_flag為0,拖尾系數符號為+;
5. 解析非零系數的幅值
非拖尾的非零系數的幅值通常表示為levels。
Levels的解析相對較為復雜。該部分是從最高頻開始解析到最低頻的非零系數為止。也就是說,levels部分是按頻率倒序解析的。
在解析每個level的時候。每個值都會依照前綴(prefix)和后綴(suffix)兩部分進行解析。
5.1 解析level_prefix部分:
Level_prefix部分即level的前綴部分,該部分的解析較為簡單,以偽代碼表示如:
leadingZeroBits = ?1 for( b = 0; !b; leadingZeroBits++ )b = read_bits( 1 ) level_prefix = leadingZeroBits結合標準文檔中的表9-6的表述可知。level的前綴值即為當前碼流的下一個比特1之前連續的比特0的個數。
5.2 解析level_suffix部分:
Level_suffix部分的解析比prefix部分復雜,整體上能夠分為下面幾個步驟:
5.3 由level_prefix和level_suffix部分組合成為levelCode
在解析完畢level_prefix和level_suffix之后,將二者組合生成levelCode。
計算方法為:levelCode=(Min(15,level_prefix)<
5.3 由levelCode計算level
依據計算得到的levelCode的奇偶性。推斷level的符號:
- 若levelCode是偶數,返回level值為(levelCode + 2)>>1;
- 若levelCode為奇數,返回level值為(?levelCode?1)>>1;
5.4 更新suffixLength的值
在解析過程中更新suffixLength體現了上下文自適應的思想。
- 當suffixLength = 0時。suffixLength更新為1;
- 當suffixLength小于6。且剛剛解析出來的level值大于閾值threshold時,suffixLength自增1;閾值threshold定義為( 3 << ( suffixLength ? 1 ) );
6. 解析零系數信息
變換系數矩陣中的零系數也是重要的信息。CAVLC解析的零系數信息主要分兩類:
- totalZeros:每個矩陣一個值,表示最高頻非零系數前零系數的總個數;
- runBefore:每個非零系數一個值,表示該非零系數前連續0的總個數。
解析totalZeros的過程與解析numCoeff和trailingOnes相似,都是從一個二維表格中查找某列表格,在從碼流中查找與表格中匹配的值。然后索引便是所求的totalZeros值。解析totalZeros的表格為標準文檔中的表9-7。下圖是表9-7的局部:
在解析totalZeros的過程中。選擇表格的索引值等于當前矩陣塊的非零系數個數numCoeff。
解析每個非零系數的runBefore時,也是依照從高頻到低頻逆序處理的。每次解析的runBefore也是依照相似上述的解析方法。從碼流中讀取對應長度的碼流并與表格中的值比對,匹配后返回索引值作為解析的值。解析runBefore參考標準文檔的表9-10:
每次解析出一個runBefore后,totalZeros都要減去該值,然后進行下一次處理。若有n個非零系數。則總共須要解析n-1個runBefore。最低頻率的非零系數前的runBefore不須要寫在碼流中,由于能夠通過上述信息推算出。
以上就是解析一個宏塊的4×4殘差系數矩陣對應語法元素的主要思想和過程。當然實際的解析過程比此要復雜得多,更具體的情況可到CSDN學院的課程:H.264/AVC視頻編解碼技術具體解釋中觀看。
轉載于:https://www.cnblogs.com/lxjshuju/p/7296094.html
總結
以上是生活随笔為你收集整理的【H.264/AVC视频编解码技术具体解释】十三、熵编码算法(4):H.264使用CAVLC解析宏块的残差数据...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 技术面试的时候应该了解公司点什么
- 下一篇: Hybris IMPEX.