热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

H264CAVLC研究

目录1CAVLC概念2CAVLC原理3CAVLC编码流程4CAVLC解码流程展开全部1CAVLC概念2CAVLC原理3CAVLC编码流程4CAVLC解码流程收起摘要纠错编辑摘要CA
目录
  • 1 CAVLC概念
  • 2 CAVLC原理
  • 3 CAVLC编码流程
  • 4 CAVLC解码流程
  • 展开全部
  • 1 CAVLC概念
  • 2 CAVLC原理
  • 3 CAVLC编码流程
  • 4 CAVLC解码流程
  • 收起


摘要纠错编辑摘要

CAVLC即基于上下文的自适应变长编码。H.264标准中使用CAVLC对4*4模块的亮度和色度残差数据进行编码。



CAVLC-CAVLC概念

CAVLC的全称是Context-Adaptive Varialbe-Length Coding,即基于上下文的自适应变长编码。CAVLC的本质是变长编码,它的特性主要体现在自适应能力上,CAVLC可以根据已编码句法元素的情况动态的选择编码中使用的码表,并且随时更新拖尾系数后缀的长度,从而获得极高的压缩比。H.264标准中使用CAVLC对4×4模块的亮度和色度残差数据进行编码。


CAVLC-CAVLC原理


在H.264标准编码体系中,视频图像在经过了预测、变换及量化编码后表现出如下的特性:4×4块残差数据块比较稀疏,其中非零系数主要集中在低频部分,而高频系数大部分是零;量化后的数据经过zig-zag扫描,DC系数附近的非零系数值较大,而高频位置上的非零系数值大部分是+1和-1;相邻的4×4块的非零系数的数目是相关的。CAVLC就是利用编码后残差数据的这些特性,通过自适应对不同码表的选择,利用较少的编码数据对残差数据进行无损的熵编码,进一步减少了编码数据的冗余和相关性,提高了H.264的压缩效率。


CAVLC-CAVLC编码流程


视频图像在经过预测、变换和量化编码后,需要经过Zig-zag扫描和重新的排序过程,为后序的CAVLC编码进行准备。一个残差数据块的CAVLC熵编码的流程如图所示:


CAVLC熵编码处理流程CAVLC熵编码处理流程

1、TotalCoeffs和TrailingOnes的编码


从码流的起始位置开始计算整个编码块中非零系数的数目(TotalCoeffs),非零系数的数目为从0-16,非零系数的数目被赋值给变量TotalCoeffs。
拖尾系数是指码流中正或者负1的个数(+/-1)。拖尾系数的数目(TrailingOnes)被限定在3个以内,如果+/-1的数目超过3个,则只有最后3个被视为拖尾系数,其余的被视为普通的非零系数,拖尾系数的数目被赋值为变量TrailingOnes。 

2、判断计算nC值

nC(Number Current 当前块值)值的计算集中体现了CAVLC的基于上下文的思想,通过nC值选择不同H.264标准附录CAVLC码表。 

3、查表获得coeff_token编码

根据之前编码和计算过程所得的变量TotalCoeffs、TrailingOnes和nC值可以查H.264标准附录CAVLC码表,即可得出coeff_token编码序列。

4、编码每个拖尾系数的符号:前面的coeff_token编码中已经包含了拖尾系数的总数,还需进一步对拖尾系数的符号进行编码。由于拖尾系数符合为正(+)或负(-),因此,在H.264标准中规定用0表示正1(+1)、1表示负1(-1)。当拖尾系数的数目超过3个只有最后3个被认定为拖尾系数,因此对符号的编码顺序应按照反向扫描的顺序进行。

5、编码除拖尾系数之外的非零系数的幅值(Levels)

非零系数的幅值(Levels)由两个部分组成:前缀(level_prefix)和后缀(level_suffix)。levelCode、levelSuffixsSize和suffixLength是编码过程中需要使用的三个变量,其中levelCode是中间过程中用到的无符号数,levelSuffixsSize表示后缀长度位数,suffixLength代表Level的码表序号。

6、编码最后一个非零系数前零的数目(TotalZeros)

TotalZeros指的是在最后一个非零系数前零的数目,此非零系数指的是按照正向扫描的最后一个非零系数。因为非零系数数目(TotalCoeffs)是已知,这就决定了TotalZeros可能的最大值。根据TotalCoeffs值,H.264标准共提供了25个变长表格供查找,其中编码亮度数据时有15个表格供查找,编码色度DC 2×2块(4:2:0格式)有3个表格、编码色度DC 2×4块(4:2:2格式)有7个表格。

7、编码每个非零系数前零的个数(RunBefore)

在CAVLC中,变量 ZerosLeft表示当前非零系数左边的所有零的个数,ZerosLeft的初始值等于TotalZeros。每个非零系数前零的个数(RunBefore)是按照反序来进行编码的,从最高频的非零系数开始。H.264标准中根据不同ZerosLeft和RunBefore,构建了RunBefore编码表格供编码查找使用。根据表格每编码完一个RunBefore,对ZerosLeft的值进行更新,继续编码下一个RunBefore,直至全部完成所有非零系数前零的个数的编码。当ZerosLeft=0即没有剩余0需要编码时或者只有一个非零系数时,均不需要再进行RunBefore编码。


CAVLC-CAVLC解码流程

CAVLC熵解码是上述CAVLC熵编码的逆过程,CAVLC熵解码的输入数据是来自片层数据的比特流,解码的基本单位是一个4×4的像素块,输出为包含4×4块每个像素点所有幅值的序列。CAVLC解码步骤如下:
1. 初始化所有的系数幅值
2. 解码非零系数个数(TotalCoeff)和拖尾系数个数(TrailingOnes)。
3. 解码拖尾系数符号(trailing_ones_sign_flag)
4. 解码非零系数幅值
5. 解码total_zeros和run_before
6. 组合非零系数幅值和游程信息,得到整个残差数据块

 


H.264 CAVLC编解码详解

2007-04-20 21:53


CAVLC: Context-Adaptive Variable-Length Coding
用于亮度和色度残差数据的编码.
经过变化量化后的残差有如下特性:非零系数集中在低频部分,而高频系数大部分是零; 量化后的数据经Zig-Zag扫描后DC系数附近的非零系数数值较大,而高频位置上的非零系数值大部分是+1和-1;相邻4*4块的非零系数的数码是相关的.

CAVLC模型选择主要体现:非零系数编码所需表格的选择和拖尾系数后缀长度的更新;

编码过程
1.初始化
确定NC值
NC则与当前块左边非零系数数目NA和上面块的非零系数数目NB求得的:
NC = (NA+NB)/2   NA,NB都可以能是没有的(处于边缘时),此时以0计之
色度的直流系数NC=-1
NC值与表格的对应 0-1:Num-VLC0 2-3:Num-VLC1 4-7:Num-VLC2 >=8:FLC(定长表格)

2.编码非零系数的数目(TotalCoeffs: 0-16)和拖尾系数数目(TrailingOnes: 0-3)
两个数目的编码过程是通过查表实现的,而表格的选择是根据变量NC(Number Current,当前块值);

3.编码每个拖尾系数的符号
符号用一个比特表示 0表示+ 1表示-

4.编码除了拖尾系数之外的非零系数的幅值Levels
过程:
1)将有符号的Level[i]转换成无符号的LevelCode
Level[i]为正, levelCode&#61;(Level[i]<<1)-2;
Level[i]为负, levelCode&#61;-(Level[i]<<1)-1;
2)计算level_prefix
level_prefix&#61;levelCode/(1<3)计算level_suffix
level_suffix&#61;levelCode%(1<4)根据suffixLength的值确定后缀的长度

5)更新suffixLength
if(suffixLength &#61;&#61; 0)&#43;&#43;suffixLength;
else if(levelCode > (3<

5.编码最后一个非零系数前零的数目TotalZeros
查标准中的表9-7

6.编码每个非零系数前零的个数RunBefore
查标准中的表9-10


解码过程
1.初始化
确定NC值

2.确定TotalCoeffs和TrailingOnes
根据NC值和coeff_token值查表9-5

3.根据TrailingOnes确定拖尾1的符号

4.解析除拖尾系数之外的非零系数的幅值(解码Levels)
1)确定suffixLength初始值
if(TotalCoeffs>10 && TrailingOnes<3)suffixLength&#61;1;
else suffixLength&#61;0;

2)计算得到Level[i]
先得到level_prefix(形式如{0}^*1: n个0后一个1)
根据suffixLength读取编码中的suffixLength位作为level_suffix
levelCode&#61;level_prefix<if(levelCode%2&#61;&#61;0)Level[i]&#61;(levelCode&#43;2)/2
else Level[i]&#61;(-levelCode-1)/2

3)更新suffixLength
if(suffixLength &#61;&#61; 0)&#43;&#43;suffixLength;
else if(levelCode > (3<

5.根据得到的TotalCoeff数值和TotalZeros编码值得到TotalZeros数值

6.解析每个非零系数前零的数目(解码RunBefore)
zeroleft &#61; TotalZeros;
i&#61;TotalCoeffs-1;
while(zeroleft>0 && i>0)
{
   根据zeroleft查找匹配的run_before[i]值;
   i&#61;i-1;
   zeroleft &#61; zeroleft-runbefore[i];
   if(zeroleft&#61;&#61;0 || i&#61;&#61;0)
   {
     run_before[i]&#61;zeroleft;
     break;
   }
}

例子:假定用了Num-VLC0表
4*4 Block
{
0,3,-1,0;
0,-1,1,0;
1,0,0,0;
0,0,0,0;
}

Reodered block:
0,3,0,1,-1,-1,0,1,0,...
TotalCoeffs&#61;5
TotalZeros&#61;3
TrailingOnes&#61;3

编码
Element   Value      Code
coeff_token   TotalCoeffs&#61;5, T1s&#61;3    0000100;根据coeff_token到TotalCoeff和TrailingOnes映射表
T1 sign (4)   &#43;      0
T1 sign (3)   -      1
T1 sign (2)   -      1
Level (1)   &#43;1 (use Level_VLC0)    1;
Level (0)   &#43;3 (use Level_VLC1)    0010;
TotalZeros   3      111;TotalCoeff和TotalZeros的映射表
run_before(4)   ZerosLeft&#61;3; run_before&#61;1   10;run_before表
run_before(3)   ZerosLeft&#61;2; run_before&#61;0   1
run_before(2)   ZerosLeft&#61;2; run_before&#61;0   1
run_before(1)   ZerosLeft&#61;2; run_before&#61;1   01
run_before(0)   ZerosLeft&#61;1; run_before&#61;1   No code required; last coefficient.

Decoding:
Code    Element Value      Output array
0000100   coeff_token TotalCoeffs&#61;5, T1s&#61;3   Empty
0    T1 sign &#43;      1
1    T1 sign -      -1, 1
1    T1 sign -      -1, -1, 1
1    Level &#43;1      1, -1, -1, 1
0010    Level &#43;3      3, 1, -1, -1, 1
111    TotalZeros 3      3, 1, -1, -1, 1
10    run_before 1      3, 1, -1, -1, 0, 1
1    run_before 0      3, 1, -1, -1, 0, 1
1    run_before 0      3, 1, -1, -1, 0, 1
01    run_before 1      3, 0, 1, -1, -1, 0, 1

 

 

 

 


[转贴] CAVLC编码过程详解——Sunrise

谨以此文献给QQ群“H.264乐园”和群里那些无私奉献的同行朋友&#xff01;
也希望能对刚进入这个领域的朋友有所帮助&#xff0c;欢迎做过CAVLC的同行能批评指正&#xff01;

编码过程&#xff1a;
假设有一个4*4数据块
{
0, 3, -1, 0,
0, -1, 1, 0,
1, 0, 0, 0,
0, 0, 0, 0
}
数据重排列&#xff1a;0&#xff0c;3&#xff0c;0&#xff0c;1&#xff0c;-1&#xff0c;-1&#xff0c;0&#xff0c;1&#xff0c;0……


1&#xff09; 初始值设定&#xff1a;
非零系数的数目&#xff08;TotalCoeffs&#xff09; &#61; 5&#xff1b;
拖尾系数的数目&#xff08;TrailingOnes&#xff09;&#61; 3&#xff1b;
最后一个非零系数前零的数目&#xff08;Total_zeros&#xff09; &#61; 3&#xff1b;
变量NC&#61;1;
&#xff08;说明&#xff1a;NC值的确定&#xff1a;色度的直流系数NC&#61;-1&#xff1b;其他系数类型NC值是根据当前块左边4*4块的非零系数数目&#xff08;NA&#xff09;当前块上面4*4块的非零系数数目&#xff08;NB&#xff09;求得的&#xff0c;见毕厚杰书P120表6.10&#xff09;
suffixLength &#61; 0&#xff1b;
i &#61; TotalCoeffs &#61; 5;

2&#xff09; 编码coeff_token&#xff1a;
查标准&#xff08;BS ISO/IEC 14496-10:2003&#xff09;Table 9-5&#xff0c;可得&#xff1a;
If (TotalCoeffs &#61;&#61; 5 && TrailingOnes &#61;&#61; 3 && 0 <&#61; NC <2)
coeff_token &#61; 0000 100;
Code &#61; 0000 100;

3&#xff09; 编码所有TrailingOnes的符号&#xff1a;
逆序编码&#xff0c;三个拖尾系数的符号依次是&#xff0b;&#xff08;0&#xff09;&#xff0c;&#xff0d;&#xff08;1&#xff09;&#xff0c;&#xff0d;&#xff08;1&#xff09;&#xff1b;
即:
TrailingOne sign[i--] &#61; 0;
TrailingOne sign[i--] &#61; 1;
TrailingOne sign[i--] &#61; 1;
Code &#61; 0000 1000 11;

4&#xff09; 编码除了拖尾系数以外非零系数幅值Levels&#xff1a;
过程如下&#xff1a;
&#xff08;1&#xff09;将有符号的Level[ i ]转换成无符号的levelCode&#xff1b;
如果Level[ i ]是正的&#xff0c;levelCode &#61; (Level[ i ]<<1) – 2;  
如果Level[ i ]是负的&#xff0c;levelCode &#61; - (Level[ i ]<<1) – 1;
&#xff08;2&#xff09;计算level_prefix&#xff1a;level_prefix &#61; levelCode / (1<查表9-6可得所对应的bit string&#xff1b;
&#xff08;3&#xff09;计算level_suffix&#xff1a;level_suffix &#61; levelCode % (1<&#xff08;4&#xff09;根据suffixLength的值来确定后缀的长度&#xff1b;
&#xff08;5&#xff09;suffixLength updata&#xff1a;
If ( suffixLength &#61;&#61; 0 )
suffixLength&#43;&#43;&#xff1b;
else if ( levelCode > (3<suffixLength&#43;&#43;;

回到例子中&#xff0c;依然按照逆序&#xff0c;Level[i--] &#61; 1&#xff1b;&#xff08;此时i &#61; 1&#xff09;
levelCode &#61; 0&#xff1b;level_prefix &#61; 0&#xff1b;
查表9-6&#xff0c;可得level_prefix &#61; 0时对应的bit string &#61; 1&#xff1b;
因为suffixLength初始化为0&#xff0c;故该Level没有后缀&#xff1b;
因为suffixLength &#61; 0&#xff0c;故suffixLength&#43;&#43;&#xff1b;
Code &#61; 0000 1000 111&#xff1b;
编码下一个Level&#xff1a;Level[0] &#61; 3&#xff1b;
levelCode &#61; 4&#xff1b;level_prefix &#61; 2&#xff1b;查表得bit string &#61; 001&#xff1b;
level_suffix &#61; 0&#xff1b;suffixLength &#61; 1&#xff1b;故码流为0010&#xff1b;
Code &#61; 0000 1000 1110 010&#xff1b;
i &#61; 0&#xff0c;编码Level结束。

5&#xff09;编码最后一个非零系数前零的数目&#xff08;TotalZeros&#xff09;&#xff1a;
查表9-7&#xff0c;当TotalCoeffs &#61; 5&#xff0c;total_zero &#61; 3时&#xff0c;bit string &#61; 111&#xff1b;
Code &#61; 0000 1000 1110 0101 11&#xff1b;

6&#xff09; 对每个非零系数前零的个数&#xff08;RunBefore&#xff09;进行编码&#xff1a;
i &#61; TotalCoeffs &#61; 5&#xff1b;ZerosLeft &#61; Total_zeros &#61; 3&#xff1b;查表9-10&#xff1a;
依然按照逆序编码
ZerosLeft &#61;3, run_before &#61; 1 run_before[4]&#61;10;
ZerosLeft &#61;2, run_before &#61; 0 run_before[3]&#61;1;
ZerosLeft &#61;2, run_before &#61; 0 run_before[2]&#61;1;
ZerosLeft &#61;2, run_before &#61; 1 run_before[1]&#61;01;
ZerosLeft &#61;1, run_before &#61; 1 run_before[0]不需要码流来表示
Code &#61; 0000 1000 1110 0101 1110 1101&#xff1b;
编码完毕。

----------------------------------Sunrise------

[[i] 本帖最后由 firstime 于 2008-9-4 02:49 PM 编辑 [/i]]

davesliu 发表于 2006-11-20 12:03 PM

请问斑竹&#xff0c;老毕书上120页表6.10中第2行和第三行的NA和NB是不是给弄反了&#xff1f;

vcforever 发表于 2006-12-7 11:06 PM

应该是弄反了

dmsd 发表于 2006-12-18 05:42 PM

请问trailing ones是指所有绝对值为1的系数的个数还是连续绝对值为1的系数的个数。

谢谢。

firstime 发表于 2006-12-18 11:29 PM

倒数三个 &#43;/-1

另&#xff1a;可结合本论坛帖子“[url&#61;http://bbs.chinavideo.org/viewthread.php?tid&#61;1057][color&#61;blue][b]CAVLC中的前缀和后缀[/b][/color][/url]”学习。

[[i] 本帖最后由 firstime 于 2008-5-20 09:59 PM 编辑 [/i]]

achen 发表于 2007-1-17 05:50 PM

“如果Level[ i ]是负的&#xff0c;levelCode &#61; - (Level[ i ]<<1) – 1”
假如Level[ i ]&#61;-3,levelCode值是多少啊&#xff1f;
还有能不能详细讲解一下如何确定suffixLength的取值&#xff0c;它跟域值的关系怎么确定&#xff1f;
谢谢&#xff01;

[[i] 本帖最后由 firstime 于 2007-1-27 10:06 PM 编辑 [/i]]

dcfarmer 发表于 2007-1-28 11:22 AM


讨论

是JM86运行后的trace记录

&#64;160   Luma # c & tr.1s(0,0) vlc&#61;0 #c&#61;11 #t1&#61;1         000000000001110 ( 11)
&#64;175   Luma trailing ones sign (0,0)                                 0 (  0)
&#64;176   Luma lev (0,0) k&#61;9 vlc&#61;1 lev&#61; -2                             11 ( -1)
&#64;178   Luma lev (0,0) k&#61;8 vlc&#61;1 lev&#61; -1                             11 ( -1)
&#64;180   Luma lev (0,0) k&#61;7 vlc&#61;1 lev&#61;  1                             10 (  1)
&#64;182   Luma lev (0,0) k&#61;6 vlc&#61;1 lev&#61; -5                         000011 ( -5)
&#64;188   Luma lev (0,0) k&#61;5 vlc&#61;2 lev&#61;-11                       00000101 (-11)
&#64;196   Luma lev (0,0) k&#61;4 vlc&#61;3 lev&#61; -3                           1101 ( -3)
&#64;200   Luma lev (0,0) k&#61;3 vlc&#61;3 lev&#61;  3                           1100 (  3)
&#64;204   Luma lev (0,0) k&#61;2 vlc&#61;3 lev&#61;  3                           1100 (  3)
&#64;208   Luma lev (0,0) k&#61;1 vlc&#61;3 lev&#61;-12                         001111 (-12)
&#64;214   Luma lev (0,0) k&#61;0 vlc&#61;3 lev&#61;  9                         001000 (  9)
上面这段是trace.txt中的记录&#xff0c;根据前面的vlc&#61;0 #c&#61;11 #t1&#61;1&#xff0c;就是trailing_ones 的个数是1个&#xff08;&#64;175   Luma trailing ones sign (0,0)        0 (  0) &#xff09;也能说明&#xff0c;但是在下面的level中&#xff0c;明明还要-1,1可以作为trailing_ones的&#xff0c;为什么不把这两个数当作trailing_ones呢&#xff1f;&#xff1f;而是作为level呢&#xff1f;&#xff1f;&#xff1f;&#xff1f;

dcfarmer 发表于 2007-1-28 11:40 AM


回答

接上面的问题&#xff0c;在群里面讨论弄明白了
在CAVLC编码中&#xff0c;从右往左看&#xff0c;算trailing_ones时&#xff0c;在右边不能有abs&#xff08;&#xff09;>1的数&#xff0c;还有算trailing_ones的个数的话&#xff0c;也不能被别的abs&#xff08;&#xff09;>1的数隔断&#xff0c;如果隔断的话&#xff0c;只能计数到隔断数为止,而且要保证个数<&#61;3。例如。。。。2&#xff0c;3&#xff0c;0&#xff0c;0&#xff0c;0&#xff0c;1&#xff0c;1&#xff0c;1&#xff0c;0&#xff0c;0&#xff0c;2 &#xff0c;这个序列中triailing_ones是没有的。还有。。。。。1&#xff0c;0&#xff0c;0&#xff0c;&#xff0d;1&#xff0c;3&#xff0c;1&#xff0c;0&#xff0c;0&#xff0c;0&#xff0c;0&#xff0c;算trailing_ones 个数时&#xff0c;只能有一个也就是3后面的“1”算一个&#xff0c;3前面的&#xff0d;1和1由于被3隔断&#xff0c;所以不能算入其中。

[[i] 本帖最后由 dcfarmer 于 2007-6-7 03:27 PM 编辑 [/i]]

zjh1004 发表于 2007-8-26 09:55 PM

ZerosLeft &#61;1, run_before &#61; 1      run_before[0]不需要码流来表示

请问&#xff1a;为什么不需要码流来表示&#xff1f;
是因为是最后一位吗&#xff1f;
查表知&#xff1a;此时 run_before[0]&#61;0

timek 发表于 2007-9-11 06:35 PM


回复 #6 achen 的帖子

Level[ i ]&#61;-3,levelCode值是多少啊&#xff1f;

levelcode应该是3

grassland_fly 发表于 2007-9-12 03:47 PM

[size&#61;12px]ZerosLeft &#61;1, run_before &#61; 1      run_before[0]不需要码流来表示

请问&#xff1a;为什么不需要码流来表示&#xff1f;
是因为是最后一位吗&#xff1f;
查表知&#xff1a;此时 run_before[0]&#61;0[/size]
[size&#61;12px] [/size]
[size&#61;12px]---------------------------------------------------------[/size]
[size&#61;12px] [/size]
[size&#61;12px]I think it&#39;s because can know the vaule based on the value before. :)[/size]

generalair 发表于 2007-10-22 02:51 PM

2007-1-28 11:22 AM dcfarmer
讨论

是JM86运行后的trace记录

&#64;160   Luma # c & tr.1s(0,0) vlc&#61;0 #c&#61;11 #t1&#61;1         000000000001110 ( 11)
&#64;175   Luma trailing ones sign (0,0)                                 0 (  0)
&#64;176   Luma lev (0,0) k&#61;9 vlc&#61;1 lev&#61; -2                             11 ( -1)
&#64;178   Luma lev (0,0) k&#61;8 vlc&#61;1 lev&#61; -1                             11 ( -1)
&#64;180   Luma lev (0,0) k&#61;7 vlc&#61;1 lev&#61;  1                             10 (  1)
&#64;182   Luma lev (0,0) k&#61;6 vlc&#61;1 lev&#61; -5                         000011 ( -5)
&#64;188   Luma lev (0,0) k&#61;5 vlc&#61;2 lev&#61;-11                       00000101 (-11)
&#64;196   Luma lev (0,0) k&#61;4 vlc&#61;3 lev&#61; -3                           1101 ( -3)
&#64;200   Luma lev (0,0) k&#61;3 vlc&#61;3 lev&#61;  3                           1100 (  3)
&#64;204   Luma lev (0,0) k&#61;2 vlc&#61;3 lev&#61;  3                           1100 (  3)
&#64;208   Luma lev (0,0) k&#61;1 vlc&#61;3 lev&#61;-12                         001111 (-12)
&#64;214   Luma lev (0,0) k&#61;0 vlc&#61;3 lev&#61;  9                         001000 (  9)


请问上面这段TRACE记录对应的16个系数序列是什么&#xff1f;谢谢

boleaon 发表于 2007-11-8 04:46 PM

好贴...

kdjwang 发表于 2008-10-10 03:52 PM


回复 #10 timek 的帖子

levelcode应该是5&#xff0c;level先乘2为-6&#xff0c;再取反减1
解码时因为levelcode为奇数&#xff0c;level &#61; (‐levelCode‐1)/2

libra811 发表于 2008-12-29 10:44 PM

刚学习&#xff0c;受用了。谢谢

peiyangpr 发表于 2009-1-4 05:28 PM

毕厚杰P123&#xff0c;6.8.6节中所给例子是否有误&#xff1f;是否应如下编码&#xff1f;

0        0        -1        0
5        2        0        0
3        0        0        0
1        0        0        0        
数据重排&#xff1a;0&#xff0c;0&#xff0c;5&#xff0c;3&#xff0c;2&#xff0c;-1&#xff0c;0&#xff0c;0&#xff0c;0&#xff0c;1……
其中TotalCoeffs &#61; 5, TrailingOnes &#61; 2, Total_zeros &#61; 5, NC &#61; 3

编码过程&#xff1a;
元素                                                   数值                                                            编码
Coeff_token                                      TotalCoeffs &#61; 5, TrailingOnes &#61; 2               0000101
Trailingones_sign_flag(1)                 &#43;                                                                  0
Tranlingones_sign_flag(0)                -                                                                   1
Level(2)                                            1 (suffixLenth &#61; 0)                                        1
Level(1)                                            3 (suffixLength &#61; 1)                                      0010
Level(0)                                            5 (suffixLength &#61; 1)                                      000010
Total_zeros                                      5                                                                   101
Run_before(4)                                 Zeroleft &#61; 5, run_before &#61; 3                          010
Run_before(4)                                 Zeroleft &#61; 2, run_before &#61; 0                          1
Run_before(4)                                 Zeroleft &#61; 2, run_before &#61; 0                          1
Run_before(4)                                 Zeroleft &#61; 2, run_before &#61; 0                          1
Run_before(4)                                    Zeroleft &#61; 2, run_before &#61; 2                               无

最终编码输出&#xff1a;000010110010000010101010111

[[i] 本帖最后由 peiyangpr 于 2009-1-4 09:16 PM 编辑 [/i]]

 

residual_block_cavlc( coeffLevel, maxNumCoeff ) {  C      Descriptor
    for( i &#61; 0; i         coeffLevel[ i ] &#61; 0     
    // coeff_token      指明了非零系数的个数&#xff0c;拖尾系数的个数。      
    coeff_token 
    if( TotalCoeff( coeff_token ) > 0 ) {          
        if( TotalCoeff( coeff_token ) > 10    &&    TrailingOnes( coeff_token ) <
3 )
            suffixLength &#61; 1          
        else          
            suffixLength &#61; 0          
        for( i &#61; 0; i             if( i                 // trailing_ones_sign_flag  拖尾系数的符号
                    -     如果trailing_ones_sign_flag &#61; 0,  相应的拖尾系数是&#43;1。
                    -     否则&#xff0c;trailing_ones_sign_flag &#61;1&#xff0c;相应的拖尾系数是-1。 
                trailing_ones_sign_flag  
                level[ i ] &#61; 1 – 2 * trailing_ones_sign_flag          
            } else {          
                // level_prefix and level_suffix  非零系数值的前缀和后缀。 
                level_prefix 
                levelCode &#61; ( level_prefix <                if( suffixLength > 0    | |    level_prefix >&#61; 14 ) {          
                    level_suffix  
                    levelCode &#43;&#61; level_suffix          
                }          
                if( level_prefix    &#61; &#61;    15    &&    suffixLength    &#61; &#61;    0 )          
                    levelCode &#43;&#61; 15          
                if( i    &#61; &#61;    TrailingOnes( coeff_token )    &&    
                      TrailingOnes( coeff_token ) <3 )
                    levelCode &#43;&#61; 2          
                if( levelCode % 2    &#61; &#61;    0 )          
                    level[ i ] &#61; ( levelCode &#43; 2 ) >> 1          
                else          
                    level[ i ] &#61; ( –levelCode – 1 ) >> 1          
                if( suffixLength    &#61; &#61;    0 )          
                    suffixLength &#61; 1          
                if( Abs( level[ i ] )    >    ( 3 <<( suffixLength – 1 ) )    &&    
                      suffixLength <6 )
                    suffixLength&#43;&#43;          
            }          
        if( TotalCoeff( coeff_token )             // total_zeros    系数中 0 的总个数。
            total_zeros   
            zerosLeft &#61; total_zeros          
        } else          
            zerosLeft &#61; 0          
        for( i &#61; 0; i             if( zerosLeft > 0 ) {          
               
                run_before   
                run[ i ] &#61; run_before          
            } else          
                run[ i ] &#61; 0          
            zerosLeft &#61; zerosLeft – run[ i ]          
        }          
        run[ TotalCoeff( coeff_token ) – 1 ] &#61; zerosLeft          
        coeffNum &#61; -1          
        for( i &#61; TotalCoeff( coeff_token ) – 1; i >&#61; 0; i-- ) {          
            coeffNum &#43;&#61; run[ i ] &#43; 1          
            coeffLevel[ coeffNum ] &#61; level[ i ]            
        }          
    }          
}

 

本文来自CSDN博客&#xff0c;转载请标明出处&#xff1a;http://blog.csdn.net/xfding/archive/2010/04/12/5477464.aspx


推荐阅读
  • DVWA学习笔记系列:深入理解CSRF攻击机制
    DVWA学习笔记系列:深入理解CSRF攻击机制 ... [详细]
  • 基于Net Core 3.0与Web API的前后端分离开发:Vue.js在前端的应用
    本文介绍了如何使用Net Core 3.0和Web API进行前后端分离开发,并重点探讨了Vue.js在前端的应用。后端采用MySQL数据库和EF Core框架进行数据操作,开发环境为Windows 10和Visual Studio 2019,MySQL服务器版本为8.0.16。文章详细描述了API项目的创建过程、启动步骤以及必要的插件安装,为开发者提供了一套完整的开发指南。 ... [详细]
  • 在C#编程中,设计流畅的用户界面是一项重要的任务。本文分享了实现Fluent界面设计的技巧与方法,特别是通过编写领域特定语言(DSL)来简化字符串操作。我们探讨了如何在不使用`+`符号的情况下,通过方法链式调用来组合字符串,从而提高代码的可读性和维护性。文章还介绍了如何利用静态方法和扩展方法来实现这一目标,并提供了一些实用的示例代码。 ... [详细]
  • 在对WordPress Duplicator插件0.4.4版本的安全评估中,发现其存在跨站脚本(XSS)攻击漏洞。此漏洞可能被利用进行恶意操作,建议用户及时更新至最新版本以确保系统安全。测试方法仅限于安全研究和教学目的,使用时需自行承担风险。漏洞编号:HTB23162。 ... [详细]
  • 您的数据库配置是否安全?DBSAT工具助您一臂之力!
    本文探讨了Oracle提供的免费工具DBSAT,该工具能够有效协助用户检测和优化数据库配置的安全性。通过全面的分析和报告,DBSAT帮助用户识别潜在的安全漏洞,并提供针对性的改进建议,确保数据库系统的稳定性和安全性。 ... [详细]
  • 深入解析:Synchronized 关键字在 Java 中对 int 和 Integer 对象的作用与影响
    深入探讨了 `Synchronized` 关键字在 Java 中对 `int` 和 `Integer` 对象的影响。尽管初看此题似乎简单,但其实质在于理解对象的概念。根据《Java编程思想》第二章的观点,一切皆为对象。本文详细分析了 `Synchronized` 关键字在不同数据类型上的作用机制,特别是对基本数据类型 `int` 和包装类 `Integer` 的区别处理,帮助读者深入理解 Java 中的同步机制及其在多线程环境中的应用。 ... [详细]
  • 如何将TS文件转换为M3U8直播流:HLS与M3U8格式详解
    在视频传输领域,MP4虽然常见,但在直播场景中直接使用MP4格式存在诸多问题。例如,MP4文件的头部信息(如ftyp、moov)较大,导致初始加载时间较长,影响用户体验。相比之下,HLS(HTTP Live Streaming)协议及其M3U8格式更具优势。HLS通过将视频切分成多个小片段,并生成一个M3U8播放列表文件,实现低延迟和高稳定性。本文详细介绍了如何将TS文件转换为M3U8直播流,包括技术原理和具体操作步骤,帮助读者更好地理解和应用这一技术。 ... [详细]
  • 本文详细解析了 Yii2 框架中视图和布局的各种函数,并综述了它们在实际开发中的应用场景。通过深入探讨每个函数的功能和用法,为开发者提供了全面的参考,帮助他们在项目中更高效地利用这些工具。 ... [详细]
  • 本文介绍了一种自定义的Android圆形进度条视图,支持在进度条上显示数字,并在圆心位置展示文字内容。通过自定义绘图和组件组合的方式实现,详细展示了自定义View的开发流程和关键技术点。示例代码和效果展示将在文章末尾提供。 ... [详细]
  • 使用Maven JAR插件将单个或多个文件及其依赖项合并为一个可引用的JAR包
    本文介绍了如何利用Maven中的maven-assembly-plugin插件将单个或多个Java文件及其依赖项打包成一个可引用的JAR文件。首先,需要创建一个新的Maven项目,并将待打包的Java文件复制到该项目中。通过配置maven-assembly-plugin,可以实现将所有文件及其依赖项合并为一个独立的JAR包,方便在其他项目中引用和使用。此外,该方法还支持自定义装配描述符,以满足不同场景下的需求。 ... [详细]
  • 在 Linux 环境下,多线程编程是实现高效并发处理的重要技术。本文通过具体的实战案例,详细分析了多线程编程的关键技术和常见问题。文章首先介绍了多线程的基本概念和创建方法,然后通过实例代码展示了如何使用 pthreads 库进行线程同步和通信。此外,还探讨了多线程程序中的性能优化技巧和调试方法,为开发者提供了宝贵的实践经验。 ... [详细]
  • 动态壁纸 LiveWallPaper:让您的桌面栩栩如生(第二篇)
    在本文中,我们将继续探讨如何开发动态壁纸 LiveWallPaper,使您的桌面更加生动有趣。作为 2010 年 Google 暑期大学生博客分享大赛 Android 篇的一部分,我们将详细介绍 Ed Burnette 的《Hello, Android》第三版中的相关内容,并分享一些实用的开发技巧和经验。通过本篇文章,您将了解到如何利用 Android SDK 创建引人入胜的动态壁纸,提升用户体验。 ... [详细]
  • 在多线程环境中,IpcChannel的性能表现并未如预期般优于Tcp和Http通道。实际测试结果显示,在IIS6中通过Remoting创建的Ipc通道,其速度比Tcp通道慢了约20倍。本文详细分析了这一现象的原因,并提出了针对性的优化建议,以提升IpcChannel在高并发场景下的性能表现。 ... [详细]
  • Unity3D 中 AsyncOperation 实现异步场景加载及进度显示优化技巧
    在Unity3D中,通过使用`AsyncOperation`可以实现高效的异步场景加载,并结合进度条显示来提升用户体验。本文详细介绍了如何利用`AsyncOperation`进行异步加载,并提供了优化技巧,包括进度条的动态更新和加载过程中的性能优化方法。此外,还探讨了如何处理加载过程中可能出现的异常情况,确保加载过程的稳定性和可靠性。 ... [详细]
  • 本文详细介绍了在CodeUp平台中实现大数进制转换的技术方法。具体而言,该问题要求将一个最多包含30位数字的十进制非负整数转换为二进制表示。输入数据包含多行,每行包含一个不超过30位的十进制非负整数。通过高效的算法设计,确保了大数转换的准确性和性能。 ... [详细]
author-avatar
mobiledu2502931473
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有