📄 cabac.c
字号:
mode_sym = mode_sym % 4; // coding of I pred-mode: 0,1,2,3
act_ctx = 10;
act_sym = mode_sym/2;
biari_encode_symbol(eep_dp, (unsigned char) act_sym, ctx->mb_type_contexts[1] + act_ctx );
act_sym = mode_sym%2;
biari_encode_symbol(eep_dp, (unsigned char) act_sym, ctx->mb_type_contexts[1] + act_ctx );
}
}
}
/*!
***************************************************************************
* \brief
* This function is used to arithmetically encode the 8x8 block
* type info
***************************************************************************
*/
void writeB8_typeInfo_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp)
{
int act_ctx;
int act_sym, csym;
int bframe=(img->type==B_SLICE);
MotionInfoContexts *ctx = (img->currentSlice)->mot_ctx;
act_sym = se->value1;
act_ctx = 0;
if (!bframe)
{
switch (act_sym)
{
case 0:
biari_encode_symbol (eep_dp, 1, &ctx->b8_type_contexts[0][1]);
break;
case 1:
biari_encode_symbol (eep_dp, 0, &ctx->b8_type_contexts[0][1]);
biari_encode_symbol (eep_dp, 0, &ctx->b8_type_contexts[0][3]);
break;
case 2:
biari_encode_symbol (eep_dp, 0, &ctx->b8_type_contexts[0][1]);
biari_encode_symbol (eep_dp, 1, &ctx->b8_type_contexts[0][3]);
biari_encode_symbol (eep_dp, 1, &ctx->b8_type_contexts[0][4]);
break;
case 3:
biari_encode_symbol (eep_dp, 0, &ctx->b8_type_contexts[0][1]);
biari_encode_symbol (eep_dp, 1, &ctx->b8_type_contexts[0][3]);
biari_encode_symbol (eep_dp, 0, &ctx->b8_type_contexts[0][4]);
break;
}
}
else //===== B-FRAME =====
{
if (act_sym==0)
{
biari_encode_symbol (eep_dp, 0, &ctx->b8_type_contexts[1][0]);
return;
}
else
{
biari_encode_symbol (eep_dp, 1, &ctx->b8_type_contexts[1][0]);
act_sym--;
}
if (act_sym<2)
{
biari_encode_symbol (eep_dp, 0, &ctx->b8_type_contexts[1][1]);
if (act_sym==0) biari_encode_symbol (eep_dp, 0, &ctx->b8_type_contexts[1][3]);
else biari_encode_symbol (eep_dp, 1, &ctx->b8_type_contexts[1][3]);
}
else if (act_sym<6)
{
biari_encode_symbol (eep_dp, 1, &ctx->b8_type_contexts[1][1]);
biari_encode_symbol (eep_dp, 0, &ctx->b8_type_contexts[1][2]);
csym=(((act_sym-2)>>1)&0x01);
if (csym) biari_encode_symbol (eep_dp, 1, &ctx->b8_type_contexts[1][3]);
else biari_encode_symbol (eep_dp, 0, &ctx->b8_type_contexts[1][3]);
csym=((act_sym-2)&0x01);
if (csym) biari_encode_symbol (eep_dp, 1, &ctx->b8_type_contexts[1][3]);
else biari_encode_symbol (eep_dp, 0, &ctx->b8_type_contexts[1][3]);
}
else
{
biari_encode_symbol (eep_dp, 1, &ctx->b8_type_contexts[1][1]);
biari_encode_symbol (eep_dp, 1, &ctx->b8_type_contexts[1][2]);
csym=(((act_sym-6)>>2)&0x01);
if (csym)
{
biari_encode_symbol (eep_dp, 1, &ctx->b8_type_contexts[1][3]);
csym=((act_sym-6)&0x01);
if (csym) biari_encode_symbol (eep_dp, 1, &ctx->b8_type_contexts[1][3]);
else biari_encode_symbol (eep_dp, 0, &ctx->b8_type_contexts[1][3]);
}
else
{
biari_encode_symbol (eep_dp, 0, &ctx->b8_type_contexts[1][3]);
csym=(((act_sym-6)>>1)&0x01);
if (csym) biari_encode_symbol (eep_dp, 1, &ctx->b8_type_contexts[1][3]);
else biari_encode_symbol (eep_dp, 0, &ctx->b8_type_contexts[1][3]);
csym=((act_sym-6)&0x01);
if (csym) biari_encode_symbol (eep_dp, 1, &ctx->b8_type_contexts[1][3]);
else biari_encode_symbol (eep_dp, 0, &ctx->b8_type_contexts[1][3]);
}
}
}
}
/*!
****************************************************************************
* \brief
* This function is used to arithmetically encode a pair of
* intra prediction modes of a given MB.
****************************************************************************
*/
void writeIntraPredMode_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp)
{
TextureInfoContexts *ctx = img->currentSlice->tex_ctx;
// use_most_probable_mode
if (se->value1 == -1)
biari_encode_symbol(eep_dp, 1, ctx->ipr_contexts);
else
{
biari_encode_symbol(eep_dp, 0, ctx->ipr_contexts);
// remaining_mode_selector
biari_encode_symbol(eep_dp,(signed short)( se->value1 & 0x1 ), ctx->ipr_contexts+1);
biari_encode_symbol(eep_dp,(signed short)((se->value1 & 0x2)>>1), ctx->ipr_contexts+1);
biari_encode_symbol(eep_dp,(signed short)((se->value1 & 0x4)>>2), ctx->ipr_contexts+1);
}
}
/*!
****************************************************************************
* \brief
* This function is used to arithmetically encode the reference
* parameter of a given MB.
****************************************************************************
*/
void writeRefFrame_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp)
{
MotionInfoContexts *ctx = img->currentSlice->mot_ctx;
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
int addctx = 0;
int a, b;
int act_ctx;
int act_sym;
int** refframe_array = enc_picture->ref_idx[se->value2];
int b8a, b8b;
PixelPos block_a, block_b;
getLuma4x4Neighbour(img->current_mb_nr, img->subblock_x, img->subblock_y, -1, 0, &block_a);
getLuma4x4Neighbour(img->current_mb_nr, img->subblock_x, img->subblock_y, 0, -1, &block_b);
b8a=((block_a.x/2)%2)+2*((block_a.y/2)%2);
b8b=((block_b.x/2)%2)+2*((block_b.y/2)%2);
if (!block_b.available)
b=0;
else if (IS_DIRECT(&img->mb_data[block_b.mb_addr]) || (img->mb_data[block_b.mb_addr].b8mode[b8b]==0 && img->mb_data[block_b.mb_addr].b8pdir[b8b]==2))
b=0;
else
{
if (img->MbaffFrameFlag && (currMB->mb_field == 0) && (img->mb_data[block_b.mb_addr].mb_field == 1))
b = (refframe_array[block_b.pos_x][block_b.pos_y] > 1 ? 1 : 0);
else
b = (refframe_array[block_b.pos_x][block_b.pos_y] > 0 ? 1 : 0);
}
if (!block_a.available)
a=0;
else if (IS_DIRECT(&img->mb_data[block_a.mb_addr]) || (img->mb_data[block_a.mb_addr].b8mode[b8a]==0 && img->mb_data[block_a.mb_addr].b8pdir[b8a]==2))
a=0;
else
{
if (img->MbaffFrameFlag && (currMB->mb_field == 0) && (img->mb_data[block_a.mb_addr].mb_field == 1))
a = (refframe_array[block_a.pos_x][block_a.pos_y] > 1 ? 1 : 0);
else
a = (refframe_array[block_a.pos_x][block_a.pos_y] > 0 ? 1 : 0);
}
act_ctx = a + 2*b;
se->context = act_ctx; // store context
act_sym = se->value1;
if (act_sym==0)
{
biari_encode_symbol(eep_dp, 0, ctx->ref_no_contexts[addctx] + act_ctx );
}
else
{
biari_encode_symbol(eep_dp, 1, ctx->ref_no_contexts[addctx] + act_ctx);
act_sym--;
act_ctx=4;
unary_bin_encode(eep_dp, act_sym,ctx->ref_no_contexts[addctx]+act_ctx,1);
}
}
/*!
****************************************************************************
* \brief
* This function is used to arithmetically encode the coded
* block pattern of a given delta quant.
****************************************************************************
*/
void writeDquant_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp)
{
MotionInfoContexts *ctx = img->currentSlice->mot_ctx;
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
int act_ctx;
int act_sym;
int dquant = se->value1;
int sign=0;
if (dquant <= 0)
sign = 1;
act_sym = abs(dquant) << 1;
act_sym += sign;
act_sym --;
if (currMB->mb_available_left == NULL)
act_ctx = 0;
else
act_ctx = ( ((currMB->mb_available_left)->delta_qp != 0) ? 1 : 0);
if (act_sym==0)
{
biari_encode_symbol(eep_dp, 0, ctx->delta_qp_contexts + act_ctx );
}
else
{
biari_encode_symbol(eep_dp, 1, ctx->delta_qp_contexts + act_ctx);
act_ctx=2;
act_sym--;
unary_bin_encode(eep_dp, act_sym,ctx->delta_qp_contexts+act_ctx,1);
}
}
/*!
****************************************************************************
* \brief
* This function is used to arithmetically encode the motion
* vector data of a B-frame MB.
****************************************************************************
*/
void writeMVD_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp)
{
int i = img->subblock_x;
int j = img->subblock_y;
int a, b;
int act_ctx;
int act_sym;
int mv_pred_res;
int mv_local_err;
int mv_sign;
int list_idx = se->value2 & 0x01;
int k = (se->value2>>1); // MVD component
PixelPos block_a, block_b;
MotionInfoContexts *ctx = img->currentSlice->mot_ctx;
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
getLuma4x4Neighbour(img->current_mb_nr, i, j, -1, 0, &block_a);
getLuma4x4Neighbour(img->current_mb_nr, i, j, 0, -1, &block_b);
if (block_b.available)
{
b = absm(img->mb_data[block_b.mb_addr].mvd[list_idx][block_b.y][block_b.x][k]);
if (img->MbaffFrameFlag && (k==1))
{
if ((currMB->mb_field==0) && (img->mb_data[block_b.mb_addr].mb_field==1))
b *= 2;
else if ((currMB->mb_field==1) && (img->mb_data[block_b.mb_addr].mb_field==0))
b /= 2;
}
}
else
b=0;
if (block_a.available)
{
a = absm(img->mb_data[block_a.mb_addr].mvd[list_idx][block_a.y][block_a.x][k]);
if (img->MbaffFrameFlag && (k==1))
{
if ((currMB->mb_field==0) && (img->mb_data[block_a.mb_addr].mb_field==1))
a *= 2;
else if ((currMB->mb_field==1) && (img->mb_data[block_a.mb_addr].mb_field==0))
a /= 2;
}
}
else
a = 0;
if ((mv_local_err=a+b)<3)
act_ctx = 5*k;
else
{
if (mv_local_err>32)
act_ctx=5*k+3;
else
act_ctx=5*k+2;
}
mv_pred_res = se->value1;
se->context = act_ctx;
act_sym = absm(mv_pred_res);
if (act_sym == 0)
biari_encode_symbol(eep_dp, 0, &ctx->mv_res_contexts[0][act_ctx] );
else
{
biari_encode_symbol(eep_dp, 1, &ctx->mv_res_contexts[0][act_ctx] );
act_sym--;
act_ctx=5*k;
unary_exp_golomb_mv_encode(eep_dp,act_sym,ctx->mv_res_contexts[1]+act_ctx,3);
mv_sign = (mv_pred_res<0) ? 1: 0;
biari_encode_symbol_eq_prob(eep_dp, (unsigned char) mv_sign);
}
}
/*!
****************************************************************************
* \brief
* This function is used to arithmetically encode the chroma
* intra prediction mode of an 8x8 block
****************************************************************************
*/
void writeCIPredMode_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp)
{
TextureInfoContexts *ctx = img->currentSlice->tex_ctx;
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
int act_ctx,a,b;
int act_sym = se->value1;
if (currMB->mb_available_up == NULL) b = 0;
else b = ( ((currMB->mb_available_up)->c_ipred_mode != 0) ? 1 : 0);
if (currMB->mb_available_left == NULL) a = 0;
else a = ( ((currMB->mb_available_left)->c_ipred_mode != 0) ? 1 : 0);
act_ctx = a+b;
if (act_sym==0) biari_encode_symbol(eep_dp, 0, ctx->cipr_contexts + act_ctx );
else
{
biari_encode_symbol(eep_dp, 1, ctx->cipr_contexts + act_ctx );
unary_bin_max_encode(eep_dp,(unsigned int) (act_sym-1),ctx->cipr_contexts+3,0,2);
}
}
/*!
****************************************************************************
* \brief
* This function is used to arithmetically encode the coded
* block pattern of an 8x8 block
****************************************************************************
*/
void writeCBP_BIT_CABAC (int b8, int bit, int cbp, Macroblock* currMB, int inter, EncodingEnvironmentPtr eep_dp)
{
int a, b;
//===== GET CONTEXT FOR CBP-BIT =====
if (b8/2 == 0) // upper block is in upper macroblock
{
if (currMB->mb_available_up == NULL)
b = 0;
else
b = ((currMB->mb_available_up->cbp & (1<<(b8+2))) == 0 ? 1 : 0);
}
else
b = ((cbp & (1<<(b8-2))) == 0 ? 1: 0);
if (b8%2 == 0) // left block is in left macroblock
{
if (currMB->mb_available_left == NULL)
a = 0;
else
a = ((currMB->mb_available_left->cbp & (1<<(b8+1))) == 0 ? 1 : 0);
}
else
a = ((cbp & (1<<(b8-1))) == 0 ? 1: 0);
//===== WRITE BIT =====
biari_encode_symbol (eep_dp, (unsigned char) bit,
img->currentSlice->tex_ctx->cbp_contexts[0] + a+2*b);
}
/*!
****************************************************************************
* \brief
* This function is used to arithmetically encode the coded
* block pattern of a macroblock
****************************************************************************
*/
void writeCBP_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_up != NULL)
b = ((currMB->mb_available_up)->cbp > 15) ? 1 : 0;
a = 0;
if (currMB->mb_available_left != NULL)
a = ((currMB->mb_available_left)->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[1] + curr_cbp_ctx );
if (cbp > 15)
{
b = 0;
if (currMB->mb_available_up != NULL)
if ((currMB->mb_available_up)->cbp > 15)
b = (( ((currMB->mb_available_up)->cbp >> 4) == 2) ? 1 : 0);
a = 0;
if (currMB->mb_available_left != NULL)
if ((currMB->mb_available_left)->cbp > 15)
a = (( ((currMB->mb_available_left)->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[2] + curr_cbp_ctx );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -