📄 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); 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] ); 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] ); act_sym--; act_ctx=5*k; unary_mv_encode(eep_dp,act_sym,ctx->mv_res_contexts[1]+act_ctx,3); }}/*! **************************************************************************** * \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) act_ctx = 0; else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -