📄 cabac.c
字号:
for (j=0; j < NUM_TRANS_TYPE; j++)
{
if (enco_ctx->level_context[j] != NULL)
free(enco_ctx->level_context[j]);
if (enco_ctx->run_context[j] != NULL)
free(enco_ctx->run_context[j]);
}
free( enco_ctx );
return;
}
/*!
**************************************************************************
* \brief
* generates arithmetic code and passes the code to the buffer
**************************************************************************
*/
int writeSyntaxElement_CABAC(SyntaxElement *se, DataPartition *this_dataPart)
{
int curr_len;
EncodingEnvironmentPtr eep_dp = &(this_dataPart->ee_cabac);
curr_len = arienco_bits_written(eep_dp);
// perform the actual coding by calling the appropriate method
se->writing(se, eep_dp);
if(se->type != SE_HEADER)
this_dataPart->bitstream->write_flag = 1;
return (se->len = (arienco_bits_written(eep_dp) - curr_len));
}
/*!
***************************************************************************
* \brief
* This function is used to arithmetically encode the macroblock
* type info of a given MB.
***************************************************************************
*/
void writeMB_typeInfo2Buffer_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp)
{
int l;
int a, b;
int act_ctx;
int act_sym;
int log_sym;
int mode_sym=0;
int mask;
int mode16x16;
MotionInfoContexts *ctx = (img->currentSlice)->mot_ctx;
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
int curr_mb_type = se->value1;
if(img->type == INTRA_IMG) // INTRA-frame
{
if (currMB->mb_available[0][1] == NULL)
b = 0;
else
b = (( (currMB->mb_available[0][1])->mb_type != 0) ? 1 : 0 );
if (currMB->mb_available[1][0] == NULL)
a = 0;
else
a = (( (currMB->mb_available[1][0])->mb_type != 0) ? 1 : 0 );
act_ctx = a + b;
act_sym = curr_mb_type;
se->context = act_ctx; // store context
if (act_sym==0) // 4x4 Intra
biari_encode_symbol(eep_dp, 0, ctx->mb_type_contexts[0] + act_ctx );
else // 16x16 Intra
{
biari_encode_symbol(eep_dp, 1, ctx->mb_type_contexts[0] + act_ctx );
mode_sym=act_sym-1; // Values in the range of 0...23
act_ctx = 4;
act_sym = mode_sym/12;
biari_encode_symbol(eep_dp, (unsigned char) act_sym, ctx->mb_type_contexts[0] + act_ctx ); // coding of AC/no AC
mode_sym = mode_sym % 12;
act_sym = mode_sym / 4; // coding of cbp: 0,1,2
act_ctx = 5;
if (act_sym==0)
{
biari_encode_symbol(eep_dp, 0, ctx->mb_type_contexts[0] + act_ctx );
}
else
{
biari_encode_symbol(eep_dp, 1, ctx->mb_type_contexts[0] + act_ctx );
act_ctx=6;
if (act_sym==1)
{
biari_encode_symbol(eep_dp, 0, ctx->mb_type_contexts[0] + act_ctx );
}
else
{
biari_encode_symbol(eep_dp, 1, ctx->mb_type_contexts[0] + act_ctx );
}
}
mode_sym = mode_sym % 4; // coding of I pred-mode: 0,1,2,3
act_sym = mode_sym/2;
act_ctx = 7;
biari_encode_symbol(eep_dp, (unsigned char) act_sym, ctx->mb_type_contexts[0] + act_ctx );
act_ctx = 8;
act_sym = mode_sym%2;
biari_encode_symbol(eep_dp, (unsigned char) act_sym, ctx->mb_type_contexts[0] + act_ctx );
}
}
else
{
if (currMB->mb_available[0][1] == NULL)
b = 0;
else
b = (( (currMB->mb_available[0][1])->mb_type != 0) ? 1 : 0 );
if (currMB->mb_available[1][0] == NULL)
a = 0;
else
a = (( (currMB->mb_available[1][0])->mb_type != 0) ? 1 : 0 );
act_sym = curr_mb_type;
if(act_sym>=(mode16x16=(8*img->type+1))) // 16x16 Intra-mode: mode16x16=9 (P-frame) mode16x16=17 (B-frame)
{
mode_sym=act_sym-mode16x16;
act_sym=mode16x16; // 16x16 mode info
}
act_sym++;
for (log_sym = 0; (1<<log_sym) <= act_sym; log_sym++);
log_sym--;
act_ctx = a + b;
se->context = act_ctx; // store context
if (log_sym==0)
{
biari_encode_symbol(eep_dp, 0, &ctx->mb_type_contexts[1][act_ctx] );
}
else
{
// code unary part
biari_encode_symbol(eep_dp, 1, &ctx->mb_type_contexts[1][act_ctx] );
act_ctx=4;
if (log_sym==1)
{
biari_encode_symbol(eep_dp, 0, &ctx->mb_type_contexts[1][act_ctx ] );
}
else
{
for(l=0;l<log_sym-1;l++)
{
biari_encode_symbol(eep_dp, 1, &ctx->mb_type_contexts[1][act_ctx] );
if (l==0) act_ctx=5;
}
if ( log_sym < (3+((img->type == B_IMG)?1:0)) ) // maximum mode no. is 9 (P-frame) or 17 (B-frame)
biari_encode_symbol(eep_dp, 0, &ctx->mb_type_contexts[1][act_ctx ] );
}
// code binary part
act_ctx=6;
if (log_sym==(3+((img->type == B_IMG)?1:0)) ) log_sym=2; // only 2 LSBs are actually set for mode 7-9 (P-frame) or 15-17 (B-frame)
mask = (1<<log_sym); // MSB
for(l=0;l<log_sym;l++)
{
mask >>=1;
biari_encode_symbol(eep_dp, (unsigned char) (act_sym & mask), &ctx->mb_type_contexts[1][act_ctx] );
}
}
if(act_sym==(mode16x16+1)) // additional info for 16x16 Intra-mode
{
act_ctx = 7;
act_sym = mode_sym/12;
biari_encode_symbol(eep_dp, (unsigned char) act_sym, ctx->mb_type_contexts[1] + act_ctx ); // coding of AC/no AC
mode_sym = mode_sym % 12;
act_sym = mode_sym / 4; // coding of cbp: 0,1,2
act_ctx = 8;
if (act_sym==0)
{
biari_encode_symbol(eep_dp, 0, ctx->mb_type_contexts[1] + act_ctx );
}
else
{
biari_encode_symbol(eep_dp, 1, ctx->mb_type_contexts[1] + act_ctx );
if (act_sym==1)
{
biari_encode_symbol(eep_dp, 0, ctx->mb_type_contexts[1] + act_ctx );
}
else
{
biari_encode_symbol(eep_dp, 1, ctx->mb_type_contexts[1] + act_ctx );
}
}
mode_sym = mode_sym % 4; // coding of I pred-mode: 0,1,2,3
act_ctx = 9;
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 a pair of
* intra prediction modes of a given MB.
****************************************************************************
*/
void writeIntraPredMode2Buffer_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp)
{
static int prev_sym = 0;
static int count = 0; // to detect a new row of intra prediction modes
TextureInfoContexts *ctx = img->currentSlice->tex_ctx;
if (count % 2 == 0)
prev_sym = 0;
unary_bin_max_encode(eep_dp,(unsigned int) se->value1,ctx->ipr_contexts[prev_sym],1,5);
prev_sym = se->value1;
unary_bin_max_encode(eep_dp,(unsigned int) se->value2,ctx->ipr_contexts[prev_sym],1,5);
prev_sym = se->value2;
if(++count == MB_BLOCK_SIZE/2) // all modes of one MB have been processed
count=0;
}
/*!
****************************************************************************
* \brief
* This function is used to arithmetically encode the reference
* parameter of a given MB.
****************************************************************************
*/
void writeRefFrame2Buffer_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp)
{
MotionInfoContexts *ctx = img->currentSlice->mot_ctx;
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
int a, b;
int act_ctx;
int act_sym;
if (currMB->mb_available[0][1] == NULL)
b = 0;
else
b = ( ((currMB->mb_available[0][1])->ref_frame != 0) ? 1 : 0);
if (currMB->mb_available[1][0] == NULL)
a = 0;
else
a = ( ((currMB->mb_available[1][0])->ref_frame != 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 + act_ctx );
}
else
{
biari_encode_symbol(eep_dp, 1, ctx->ref_no_contexts + act_ctx);
act_sym--;
act_ctx=4;
unary_bin_encode(eep_dp, act_sym,ctx->ref_no_contexts+act_ctx,1);
}
}
/*!
****************************************************************************
* \brief
* This function is used to arithmetically encode the motion
* vector data of a given MB.
****************************************************************************
*/
void writeMVD2Buffer_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp)
{
int step_h, step_v;
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 k = se->value2; // MVD component
MotionInfoContexts *ctx = img->currentSlice->mot_ctx;
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
int curr_mb_type = currMB->mb_type;
step_h=input->blc_size[curr_mb_type][0]/BLOCK_SIZE;
step_v=input->blc_size[curr_mb_type][1]/BLOCK_SIZE;
if (j==0)
{
if (currMB->mb_available[0][1] == NULL)
b = 0;
else
b = absm((currMB->mb_available[0][1])->mvd[0][BLOCK_SIZE-1][i][k]);
}
else
b = absm(currMB->mvd[0][j-step_v][i][k]);
if (i==0)
{
if (currMB->mb_available[1][0] == NULL)
a = 0;
else
a = absm((currMB->mb_available[1][0])->mvd[0][j][BLOCK_SIZE-1][k]);
}
else
a = absm(currMB->mvd[0][j][i-step_h][k]);
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_mv_encode(eep_dp,act_sym,ctx->mv_res_contexts[1]+act_ctx,3);
mv_sign = (mv_pred_res<0) ? 1: 0;
act_ctx=5*k+4;
biari_encode_symbol(eep_dp, (unsigned char) mv_sign, &ctx->mv_res_contexts[1][act_ctx] );
}
}
/*!
****************************************************************************
* \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[1][0] == NULL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -