日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

【H.264/AVC视频编解码技术具体解释】十三、熵编码算法(4):H.264使用CAVLC解析宏块的残差数据...

發布時間:2025/4/16 c/c++ 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【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編碼的逆過程。

在解析一個宏塊殘差的時候。首先解析的是殘差矩陣的非零系數以及拖尾系數的個數numCoefftrailingOnes。隨后是每個拖尾系數的符號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部分復雜,整體上能夠分為下面幾個步驟:

  • 解析過程開始之前。初始化suffixLength的值:當非零系數總數numCoeff大于10且拖尾系數個數trailingOnes等于3時,suffixLength初始化為1,否則初始化為0;
  • 確定levelSuffixSize的值:通常情況下,levelSuffixSize的值等于當前的suffixLength。除了下列兩種意外情況:第一。level_prefix的值等于14且suffixLength為0,此時levelSuffixSize設為4;第二,level_prefix大于等于15,此時levelSuffixSize設為level_prefix-3。
  • 解析level_suffix的值:依據levelSuffixSize的值作為長度。在碼流中讀取對應的二進制數據作為level_suffix。若levelSuffixSize為0。則level_suffix的值為0;
  • 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解析宏块的残差数据...的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。