📄 cabac.c
字号:
//===== WRITE BIT =====
biari_encode_symbol (eep_dp, (unsigned char) bit,
img->currentSlice->tex_ctx->cbp_contexts[inter][0] + a+2*b);
}
/*!
****************************************************************************
* \brief
* This function is used to arithmetically encode the coded
* block pattern of a macroblock
****************************************************************************
*/
void writeCBP2Buffer_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp)
{
TextureInfoContexts *ctx = img->currentSlice->tex_ctx;
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
int a, b;
int curr_cbp_ctx, curr_cbp_idx;
int cbp = se->value1; // symbol to encode
int cbp_bit;
int b8;
for (b8=0; b8<4; b8++)
{
curr_cbp_idx = (currMB->b8mode[b8] == IBLOCK ? 0 : 1);
writeCBP_BIT_CABAC (b8, cbp&(1<<b8), cbp, currMB, curr_cbp_idx, eep_dp);
}
if ( se->type == SE_CBP_INTRA )
curr_cbp_idx = 0;
else
curr_cbp_idx = 1;
// coding of chroma part
b = 0;
if (currMB->mb_available[0][1] != NULL)
b = ((currMB->mb_available[0][1])->cbp > 15) ? 1 : 0;
a = 0;
if (currMB->mb_available[1][0] != NULL)
a = ((currMB->mb_available[1][0])->cbp > 15) ? 1 : 0;
curr_cbp_ctx = a+2*b;
cbp_bit = (cbp > 15 ) ? 1 : 0;
biari_encode_symbol(eep_dp, (unsigned char) cbp_bit, ctx->cbp_contexts[curr_cbp_idx][1] + curr_cbp_ctx );
if (cbp > 15)
{
b = 0;
if (currMB->mb_available[0][1] != NULL)
if ((currMB->mb_available[0][1])->cbp > 15)
b = (( ((currMB->mb_available[0][1])->cbp >> 4) == 2) ? 1 : 0);
a = 0;
if (currMB->mb_available[1][0] != NULL)
if ((currMB->mb_available[1][0])->cbp > 15)
a = (( ((currMB->mb_available[1][0])->cbp >> 4) == 2) ? 1 : 0);
curr_cbp_ctx = a+2*b;
cbp_bit = ((cbp>>4) == 2) ? 1 : 0;
biari_encode_symbol(eep_dp, (unsigned char) cbp_bit, ctx->cbp_contexts[curr_cbp_idx][2] + curr_cbp_ctx );
}
}
/*!
****************************************************************************
* \brief
* This function is used to arithmetically encode coeff_count, level and
* run of a given MB.
****************************************************************************
*/
void writeRunLevel2Buffer_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp)
{
const int level = se->value1;
const int run = se->value2;
int curr_ctx_idx = se->context;
int sign_of_level;
int max_run;
static int coeff_can[2][17] = {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
static int coeff_count=0;
int i,j,a,b;
int max_coeff[9] = {8,16,16,16,15,4,4,15,15};
int curr_run_ctx, curr_level_ctx;
int act_ctx=0;
static int count[3] = {0,0,0};
static int prev_sym[3] = {0,0,0};
int prevLevel = 0;
int absLevel;
int changed_ctx_idx=curr_ctx_idx;
TextureInfoContexts *ctx = img->currentSlice->tex_ctx;
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
if (level != 0)
{
coeff_can[0][coeff_count] = level;
coeff_can[1][coeff_count] = run;
coeff_count++;
}
else
{
//send coeff_count
switch(curr_ctx_idx)
{
case 0://max 8 coeffs, double_scan
{
//context determination
act_ctx = (count[0] == 0) ? 0 : ((prev_sym[0] == 0) ? 1 : 2);
prev_sym[0] = coeff_count;
if(++count[0] == 2) count[0]=0;
if (coeff_count == 0)
biari_encode_symbol(eep_dp, 0, ctx->coeff_count_context[curr_ctx_idx] + act_ctx);
else
{
biari_encode_symbol(eep_dp, 1, ctx->coeff_count_context[curr_ctx_idx] + act_ctx);
unary_bin_max_encode(eep_dp,(unsigned int) coeff_count-1,ctx->coeff_count_context[curr_ctx_idx]+4,1,max_coeff[curr_ctx_idx]-1);
}
break;
}
case 1: //max 16 coeffs //single scan
case 2:
{
//context termination
j = img->subblock_y;
i = img->subblock_x;
if (j==0)
b = (currMB->mb_available[0][1] == NULL)?0:(((currMB->mb_available[0][1])->coeffs_count[BLOCK_SIZE-1][i]==0)?0:1);
else
b = (currMB->coeffs_count[j-1][i]==0)?0:1;
if (i==0)
a = (currMB->mb_available[1][0] == NULL)?0:(((currMB->mb_available[1][0])->coeffs_count[j][BLOCK_SIZE-1]==0)?0:1);
else
a = (currMB->coeffs_count[j][i-1]==0)?0:1;
act_ctx = a+2*b;
if (coeff_count == 0)
biari_encode_symbol(eep_dp, 0, ctx->coeff_count_context[curr_ctx_idx] + act_ctx);
else
{
biari_encode_symbol(eep_dp, 1, ctx->coeff_count_context[curr_ctx_idx] + act_ctx);
unary_bin_max_encode(eep_dp,(unsigned int) coeff_count-1,ctx->coeff_count_context[curr_ctx_idx]+4,1,max_coeff[curr_ctx_idx]-1);
}
currMB->coeffs_count[j][i] = coeff_count;
break;
}
case 4://max 15 coeffs // 16x16 luma ac
{
//context determination
act_ctx = (count[2] == 0) ? 0 : ((prev_sym[2] == 0) ? 1 : 2);
prev_sym[2] = coeff_count;
if(++count[2] == 16) count[2]=0;
if (coeff_count == 0)
biari_encode_symbol(eep_dp, 0, ctx->coeff_count_context[curr_ctx_idx] + act_ctx);
else
{
biari_encode_symbol(eep_dp, 1, ctx->coeff_count_context[curr_ctx_idx] + act_ctx);
unary_bin_max_encode(eep_dp,(unsigned int) coeff_count-1,ctx->coeff_count_context[curr_ctx_idx]+4,1,max_coeff[curr_ctx_idx]-1);
}
break;
}
case 5:
case 6://max 4 coeffs, chroma dc different ctx uv for first bin
{
act_ctx = (se->k == 0)?0:1;
if (coeff_count == 0)
biari_encode_symbol(eep_dp, 0, ctx->coeff_count_context[curr_ctx_idx] + act_ctx);
else
{
biari_encode_symbol(eep_dp, 1, ctx->coeff_count_context[curr_ctx_idx] + act_ctx);
unary_bin_max_encode(eep_dp,(unsigned int) coeff_count-1,ctx->coeff_count_context[curr_ctx_idx]+4,1,max_coeff[curr_ctx_idx]-1);
}
break;
}
case 7:
case 8://max 15 coeffs, chroma ac different ctx uv for first bin
{
act_ctx = (se->k < 4)?0:1;
if (coeff_count == 0)
biari_encode_symbol(eep_dp, 0, ctx->coeff_count_context[curr_ctx_idx] + act_ctx);
else
{
biari_encode_symbol(eep_dp, 1, ctx->coeff_count_context[curr_ctx_idx] + act_ctx);
unary_bin_max_encode(eep_dp,(unsigned int) coeff_count-1,ctx->coeff_count_context[curr_ctx_idx]+4,1,max_coeff[curr_ctx_idx]-1);
}
break;
}
case 3: //max 16 coeffs // 16x16 luma dc
{
act_ctx = 0;
if (coeff_count == 0)
biari_encode_symbol(eep_dp, 0, ctx->coeff_count_context[curr_ctx_idx] + act_ctx);
else
{
biari_encode_symbol(eep_dp, 1, ctx->coeff_count_context[curr_ctx_idx] + act_ctx);
unary_bin_max_encode(eep_dp,(unsigned int) coeff_count-1,ctx->coeff_count_context[curr_ctx_idx]+4,1,max_coeff[curr_ctx_idx]-1);
}
break;
}
default: printf("ERROR");
}
prevLevel = 0;
for(i=0; i<coeff_count;i++)
{
//determine run ctx
switch (curr_ctx_idx)
{
case 1:
case 2:
curr_run_ctx = ((coeff_count) >= 4) ? 1 : 0;
break;
case 3:
curr_run_ctx = ((coeff_count-i) >= 4) ? 1 : 0;
break;
case 4:
case 7:
case 8:
case 0:
curr_run_ctx = ((coeff_count-i) >= 3) ? 1 : 0;
break;
case 5:
case 6:
curr_run_ctx = ((coeff_count-i) >= 2) ? 1 : 0;
break;
}
curr_run_ctx = 9*curr_run_ctx + curr_ctx_idx;
//send run
if (i==0)
max_run = max_coeff[curr_ctx_idx]-coeff_count;
if ((max_run != 0) )
unary_bin_max_encode(eep_dp,(unsigned int) coeff_can[1][i],ctx->run_context[curr_run_ctx],1,max_run);
max_run -= coeff_can[1][i];
//determine level ctx
changed_ctx_idx = curr_ctx_idx;
absLevel = absm(coeff_can[0][i]);
changed_ctx_idx += 9*prevLevel;
prevLevel = absLevel > 3 ? 3 : absLevel;
// send level
unary_level_encode(eep_dp,(unsigned int) absm(coeff_can[0][i])-1,ctx->level_context[changed_ctx_idx]);
sign_of_level = ((coeff_can[0][i] < 0) ? 1 : 0);
curr_level_ctx = 3;
biari_encode_symbol(eep_dp, (unsigned char) sign_of_level, ctx->level_context[curr_ctx_idx]+ curr_level_ctx );
}
coeff_count=0;
}
}
/*!
************************************************************************
* \brief
* Unary binarization and encoding of a symbol by using
* one or two distinct models for the first two and all
* remaining bins
*
************************************************************************/
void unary_bin_encode(EncodingEnvironmentPtr eep_dp,
unsigned int symbol,
BiContextTypePtr ctx,
int ctx_offset)
{
unsigned int l;
BiContextTypePtr ictx;
if (symbol==0)
{
biari_encode_symbol(eep_dp, 0, ctx );
return;
}
else
{
biari_encode_symbol(eep_dp, 1, ctx );
l=symbol;
ictx=ctx+ctx_offset;
while ((--l)>0)
biari_encode_symbol(eep_dp, 1, ictx);
biari_encode_symbol(eep_dp, 0, ictx);
}
return;
}
/*!
************************************************************************
* \brief
* Unary binarization and encoding of a symbol by using
* one or two distinct models for the first two and all
* remaining bins; no terminating "0" for max_symbol
* (finite symbol alphabet)
************************************************************************
*/
void unary_bin_max_encode(EncodingEnvironmentPtr eep_dp,
unsigned int symbol,
BiContextTypePtr ctx,
int ctx_offset,
unsigned int max_symbol)
{
unsigned int l;
BiContextTypePtr ictx;
if (symbol==0)
{
biari_encode_symbol(eep_dp, 0, ctx );
return;
}
else
{
biari_encode_symbol(eep_dp, 1, ctx );
l=symbol;
ictx=ctx+ctx_offset;
while ((--l)>0)
biari_encode_symbol(eep_dp, 1, ictx);
if (symbol<max_symbol)
biari_encode_symbol(eep_dp, 0, ictx);
}
return;
}
/*!
************************************************************************
* \brief
* Unary binarization and encoding of a symbol by using
* three distinct models for the first, the second and all
* remaining bins
************************************************************************
*/
void unary_level_encode(EncodingEnvironmentPtr eep_dp,
unsigned int symbol,
BiContextTypePtr ctx)
{
unsigned int l;
int bin=1;
BiContextTypePtr ictx=ctx;
if (symbol==0)
{
biari_encode_symbol(eep_dp, 0, ictx );
return;
}
else
{
biari_encode_symbol(eep_dp, 1, ictx );
l=symbol;
ictx++;
while ((--l)>0)
{
biari_encode_symbol(eep_dp, 1, ictx );
if ((++bin)==2) ictx++;
}
biari_encode_symbol(eep_dp, 0, ictx );
}
return;
}
/*!
************************************************************************
* \brief
* Unary binarization and encoding of a symbol by using
* four distinct models for the first, the second, intermediate
* and all remaining bins
************************************************************************
*/
void unary_mv_encode(EncodingEnvironmentPtr eep_dp,
unsigned int symbol,
BiContextTypePtr ctx,
unsigned int max_bin)
{
unsigned int l;
unsigned int bin=1;
BiContextTypePtr ictx=ctx;
if (symbol==0)
{
biari_encode_symbol(eep_dp, 0, ictx );
return;
}
else
{
biari_encode_symbol(eep_dp, 1, ictx );
l=symbol;
ictx++;
while ((--l)>0)
{
biari_encode_symbol(eep_dp, 1, ictx );
if ((++bin)==2) ictx++;
if (bin==max_bin) ictx++;
}
biari_encode_symbol(eep_dp, 0, ictx );
}
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -