www.pudn.com > jm50g.zip > cabac.c
/* *********************************************************************** * COPYRIGHT AND WARRANTY INFORMATION * * Copyright 2001, International Telecommunications Union, Geneva * * DISCLAIMER OF WARRANTY * * These software programs are available to the user without any * license fee or royalty on an "as is" basis. The ITU disclaims * any and all warranties, whether express, implied, or * statutory, including any implied warranties of merchantability * or of fitness for a particular purpose. In no event shall the * contributor or the ITU be liable for any incidental, punitive, or * consequential damages of any kind whatsoever arising from the * use of these programs. * * This disclaimer of warranty extends to the user of these programs * and user's customers, employees, agents, transferees, successors, * and assigns. * * The ITU does not represent or warrant that the programs furnished * hereunder are free of infringement of any third-party patents. * Commercial implementations of ITU-T Recommendations, including * shareware, may be subject to royalty fees to patent holders. * Information regarding the ITU-T patent policy is available from * the ITU Web site at http://www.itu.int. * * THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE ITU-T PATENT POLICY. ************************************************************************ */ /*! ************************************************************************************* * \file cabac.c * * \brief * CABAC entropy coding routines * * \author * Main contributors (see contributors.h for copyright, address and affiliation details) * - Detlev Marpe************************************************************************************** */ #include #include #include #include // for debugging #include #include "cabac.h" #include "memalloc.h" #include "bitsbuf.h" #include "header.h" #include "elements.h" int symbolCount = 0; /*! ************************************************************************ * \brief * Allocation of contexts models for the motion info * used for arithmetic decoding * ************************************************************************ */ MotionInfoContexts* create_contexts_MotionInfo(void) { MotionInfoContexts *deco_ctx; deco_ctx = (MotionInfoContexts*) calloc(1, sizeof(MotionInfoContexts) ); if( deco_ctx == NULL ) no_mem_exit("create_contexts_MotionInfo: deco_ctx"); return deco_ctx; } /*! ************************************************************************ * \brief * Allocates of contexts models for the texture info * used for arithmetic decoding ************************************************************************ */ TextureInfoContexts* create_contexts_TextureInfo(void) { TextureInfoContexts *deco_ctx; deco_ctx = (TextureInfoContexts*) calloc(1, sizeof(TextureInfoContexts) ); if( deco_ctx == NULL ) no_mem_exit("create_contexts_TextureInfo: deco_ctx"); return deco_ctx; } /*! ************************************************************************ * \brief * Initializes an array of contexts models with some pre-defined * counts (ini_flag = 1) or with a flat histogram (ini_flag = 0) * ************************************************************************ */ #define INIT_CTX(jj,ii,ctx,ini) {for(j=0;j ABT_mode_contexts, ABT_MODE_Ini); INIT_CTX (4, NUM_MB_TYPE_CTX, enco_ctx->mb_type_contexts, MB_TYPE_Ini ); INIT_CTX (2, NUM_B8_TYPE_CTX, enco_ctx->b8_type_contexts, B8_TYPE_Ini ); INIT_CTX (2, NUM_MV_RES_CTX, enco_ctx->mv_res_contexts, MV_RES_Ini ); INIT_CTX (2, NUM_REF_NO_CTX, enco_ctx->ref_no_contexts, REF_NO_Ini ); INIT_CTX (1, NUM_DELTA_QP_CTX, &enco_ctx->delta_qp_contexts, &DELTA_QP_Ini ); INIT_CTX (1, NUM_MB_AFF_CTX, &enco_ctx->mb_aff_contexts, &MB_AFF_Ini ); } /*! ************************************************************************ * \brief * Initializes an array of contexts models with some pre-defined * counts (ini_flag = 1) or with a flat histogram (ini_flag = 0) ************************************************************************ */ void init_contexts_TextureInfo(struct img_par *img, TextureInfoContexts *enco_ctx) { int i,j; int intra = (img->type==INTRA_IMG ? 1 : 0); INIT_CTX (3, NUM_CBP_CTX, enco_ctx->cbp_contexts, CBP_Ini[!intra]); INIT_CTX (1, NUM_IPR_CTX, &enco_ctx->ipr_contexts, &IPR_Ini ); INIT_CTX (1, NUM_CIPR_CTX, &enco_ctx->cipr_contexts, &CIPR_Ini ); INIT_CTX (NUM_BLOCK_TYPES, NUM_BCBP_CTX, enco_ctx->bcbp_contexts, BCBP_Ini[intra]); INIT_CTX (NUM_BLOCK_TYPES, NUM_MAP_CTX, enco_ctx->map_contexts, MAP_Ini [intra]); INIT_CTX (NUM_BLOCK_TYPES, NUM_LAST_CTX, enco_ctx->last_contexts, LAST_Ini[intra]); INIT_CTX (NUM_BLOCK_TYPES, NUM_ONE_CTX, enco_ctx->one_contexts, ONE_Ini [intra]); INIT_CTX (NUM_BLOCK_TYPES, NUM_ABS_CTX, enco_ctx->abs_contexts, ABS_Ini [intra]); } /*! ************************************************************************ * \brief * Frees the memory of the contexts models * used for arithmetic decoding of the motion info. ************************************************************************ */ void delete_contexts_MotionInfo(MotionInfoContexts *deco_ctx) { if( deco_ctx == NULL ) return; free( deco_ctx ); return; } /*! ************************************************************************ * \brief * Frees the memory of the contexts models * used for arithmetic decoding of the texture info. ************************************************************************ */ void delete_contexts_TextureInfo(TextureInfoContexts *deco_ctx) { if( deco_ctx == NULL ) return; free( deco_ctx ); return; } void readFieldModeInfoFromBuffer_CABAC( SyntaxElement *se, struct inp_par *inp, struct img_par *img, DecodingEnvironmentPtr dep_dp) { int a,b,act_ctx; MotionInfoContexts *ctx = (img->currentSlice)->mot_ctx; Macroblock *currMB = &img->mb_data[img->map_mb_nr];//GB current_mb_nr]; if (currMB->field_available[0] == NULL) b = 0; else b = currMB->field_available[0]->mb_field; if (currMB->field_available[1] == NULL) a = 0; else a = currMB->field_available[1]->mb_field; act_ctx = a + b; se->value1 = biari_decode_symbol (dep_dp, &ctx->mb_aff_contexts[act_ctx]); #if TRACE fprintf(p_trace, "@%d %s\t\t%d\n",symbolCount++, se->tracestring, se->value1); fflush(p_trace); #endif } int check_next_mb_and_get_field_mode_CABAC( SyntaxElement *se, struct img_par *img, struct inp_par *inp, DataPartition *act_dp) { BiContextTypePtr mb_type_ctx_copy[4]; BiContextTypePtr mb_aff_ctx_copy; DecodingEnvironmentPtr dep_dp_copy; int length; DecodingEnvironmentPtr dep_dp = &(act_dp->de_cabac); int bframe = (img->type==B_IMG_1 || img->type==B_IMG_MULT); int skip = 0; int field = 0; int i; Macroblock *currMB; //get next MB img->current_mb_nr++; setRealMB_nr(img); currMB = &img->mb_data[img->map_mb_nr]; currMB->slice_nr = img->current_slice_nr; CheckAvailabilityOfNeighborsForSkip(img); CheckAvailabilityOfNeighborsForAff(img); //create dep_dp_copy = (DecodingEnvironmentPtr) calloc(1, sizeof(DecodingEnvironment) ); for (i=0;i<4;i++) mb_type_ctx_copy[i] = (BiContextTypePtr) calloc(NUM_MB_TYPE_CTX, sizeof(BiContextType) ); mb_aff_ctx_copy = (BiContextTypePtr) calloc(NUM_MB_AFF_CTX, sizeof(BiContextType) ); //copy memcpy(dep_dp_copy,dep_dp,sizeof(DecodingEnvironment)); length = *(dep_dp_copy->Dcodestrm_len) = *(dep_dp->Dcodestrm_len); for (i=0;i<4;i++) memcpy(mb_type_ctx_copy[i], img->currentSlice->mot_ctx->mb_type_contexts[i],NUM_MB_TYPE_CTX*sizeof(BiContextType) ); memcpy(mb_aff_ctx_copy, img->currentSlice->mot_ctx->mb_aff_contexts,NUM_MB_AFF_CTX*sizeof(BiContextType) ); //check_next_mb #if TRACE strncpy(se->tracestring, "Check MB skipflag", TRACESTRING_SIZE); #endif readMB_skip_flagInfoFromBuffer_CABAC(se,inp,img,dep_dp); skip = (bframe)? (se->value1==0 && se->value2==0) : (se->value1==0); if (!skip) { #if TRACE strncpy(se->tracestring, "Get Field mode", TRACESTRING_SIZE); #endif readFieldModeInfoFromBuffer_CABAC( se,inp,img,dep_dp); field = se->value1; } //reset img->current_mb_nr--; setRealMB_nr(img); memcpy(dep_dp,dep_dp_copy,sizeof(DecodingEnvironment)); *(dep_dp->Dcodestrm_len) = length; for (i=0;i<4;i++) memcpy(img->currentSlice->mot_ctx->mb_type_contexts[i],mb_type_ctx_copy[i], NUM_MB_TYPE_CTX*sizeof(BiContextType) ); memcpy( img->currentSlice->mot_ctx->mb_aff_contexts,mb_aff_ctx_copy,NUM_MB_AFF_CTX*sizeof(BiContextType) ); //delete free(dep_dp_copy); for (i=0;i<4;i++) free(mb_type_ctx_copy[i]); free(mb_aff_ctx_copy); return skip; } /*! ************************************************************************ * \brief * This function is used to arithmetically decode the motion * vector data of a B-frame MB. ************************************************************************ */ void readBiMVD2Buffer_CABAC( SyntaxElement *se, struct inp_par *inp, struct img_par *img, DecodingEnvironmentPtr dep_dp) { int i = img->subblock_x; int j = img->subblock_y; int a, b; int act_ctx; int act_sym; int mv_local_err; int mv_sign; int backward = se->value2 & 0x01; int k = (se->value2>>1); // MVD component MotionInfoContexts *ctx = img->currentSlice->mot_ctx; Macroblock *currMB = &img->mb_data[img->map_mb_nr];//GB current_mb_nr]; if (j==0) { if (currMB->mb_available[0][1] == NULL) b = 0; else b = absm((currMB->mb_available[0][1])->mvd[backward][BLOCK_SIZE-1][i][k]); } else b = absm(currMB->mvd[backward][j-1/*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[backward][j][BLOCK_SIZE-1][k]); } else a = absm(currMB->mvd[backward][j][i-1/*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; } se->context = act_ctx; act_sym = biari_decode_symbol(dep_dp,&ctx->mv_res_contexts[0][act_ctx] ); if (act_sym != 0) { act_ctx = 5*k+4; mv_sign = biari_decode_symbol_eq_prob(dep_dp); act_ctx=5*k; act_sym = unary_exp_golomb_mv_decode(dep_dp,ctx->mv_res_contexts[1]+act_ctx,3); act_sym++; if(mv_sign) act_sym = -act_sym; } se->value1 = act_sym; #if TRACE fprintf(p_trace, "@%d %s\t\t\t%d \n",symbolCount++, se->tracestring, se->value1); fflush(p_trace); #endif } /*! *************************************************************************** * \brief * This function is used to arithmetically encode the intra_block_modeABT *************************************************************************** */ void readABTIntraBlkModeInfo2Buffer_CABAC(SyntaxElement *se, struct inp_par *inp, struct img_par *img, DecodingEnvironmentPtr dep_dp) { int act_sym = 0; int ftype = (img->type==INTRA_IMG?0:1); MotionInfoContexts *ctx = (img->currentSlice)->mot_ctx; if (biari_decode_symbol (dep_dp, ctx->ABT_mode_contexts[ftype]+0)) { if (biari_decode_symbol (dep_dp, ctx->ABT_mode_contexts[ftype]+2)) act_sym = 3; else act_sym = 0; } else { if (biari_decode_symbol (dep_dp, ctx->ABT_mode_contexts[ftype]+1)) act_sym = 2; else act_sym = 1; } se->value1 = act_sym; } /*! ************************************************************************ * \brief * This function is used to arithmetically decode the 8x8 block type. ************************************************************************ */ void readB8_typeInfoFromBuffer_CABAC (SyntaxElement *se, struct inp_par *inp, struct img_par *img, DecodingEnvironmentPtr dep_dp) { int act_sym = 0; int bframe = (img->type==B_IMG_1 || img->type==B_IMG_MULT); MotionInfoContexts *ctx = (img->currentSlice)->mot_ctx; if (!bframe) { if (biari_decode_symbol (dep_dp, &ctx->b8_type_contexts[0][1])) { act_sym = 0; } else { if (biari_decode_symbol (dep_dp, &ctx->b8_type_contexts[0][3])) { if (biari_decode_symbol (dep_dp, &ctx->b8_type_contexts[0][4])) act_sym = 2; else act_sym = 3; } else { act_sym = 1; } } } else { if (biari_decode_symbol (dep_dp, &ctx->b8_type_contexts[1][0])) { if (biari_decode_symbol (dep_dp, &ctx->b8_type_contexts[1][1])) { if (biari_decode_symbol (dep_dp, &ctx->b8_type_contexts[1][2])) { if (biari_decode_symbol (dep_dp, &ctx->b8_type_contexts[1][3])) { act_sym = 10; if (biari_decode_symbol (dep_dp, &ctx->b8_type_contexts[1][3])) act_sym++; } else { act_sym = 6; if (biari_decode_symbol (dep_dp, &ctx->b8_type_contexts[1][3])) act_sym+=2; if (biari_decode_symbol (dep_dp, &ctx->b8_type_contexts[1][3])) act_sym++; } } else { act_sym=2; if (biari_decode_symbol (dep_dp, &ctx->b8_type_contexts[1][3])) act_sym+=2; if (biari_decode_symbol (dep_dp, &ctx->b8_type_contexts[1][3])) act_sym+=1; } } else { if (biari_decode_symbol (dep_dp, &ctx->b8_type_contexts[1][3])) act_sym = 1; else act_sym = 0; } act_sym++; } else { act_sym= 0; } } se->value1 = act_sym; // if (act_sym == 13) printf(" stop"); } /*! ************************************************************************ * \brief * This function is used to arithmetically decode the macroblock * type info of a given MB. ************************************************************************ */ void readMB_skip_flagInfoFromBuffer_CABAC( SyntaxElement *se, struct inp_par *inp, struct img_par *img, DecodingEnvironmentPtr dep_dp) { int a, b; int act_ctx; int bframe=(img->type==B_IMG_1 || img->type==B_IMG_MULT); MotionInfoContexts *ctx = (img->currentSlice)->mot_ctx; Macroblock *currMB = &img->mb_data[img->map_mb_nr];//GB current_mb_nr]; if (bframe) { if (currMB->skip_mb_available[0][1] == NULL) b = 0; else b = (currMB->skip_mb_available[0][1]->mb_type==0 && currMB->skip_mb_available[0][1]->cbp==0 ? 0 : 1); if (currMB->skip_mb_available[1][0] == NULL) a = 0; else a = (currMB->skip_mb_available[1][0]->mb_type==0 && currMB->skip_mb_available[1][0]->cbp==0 ? 0 : 1); act_ctx = 7 + a + b; if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][act_ctx]) == 0) se->value1 = se->value2 = 0; else se->value1 = se->value2 = 1; } else { if (currMB->skip_mb_available[0][1] == NULL) b = 0; else b = (( (currMB->skip_mb_available[0][1])->mb_type != 0) ? 1 : 0 ); if (currMB->skip_mb_available[1][0] == NULL) a = 0; else a = (( (currMB->skip_mb_available[1][0])->mb_type != 0) ? 1 : 0 ); act_ctx = a + b; if (biari_decode_symbol(dep_dp, &ctx->mb_type_contexts[1][act_ctx]) == 0) se->value1 = 0; else se->value1 = 1; } #if TRACE fprintf(p_trace, "@%d %s\t\t%d\t%d %d\n",symbolCount++, se->tracestring, se->value1,a,b); fflush(p_trace); #endif return; } /*! ************************************************************************ * \brief * This function is used to arithmetically decode the macroblock * type info of a given MB. ************************************************************************ */ void readMB_typeInfoFromBuffer_CABAC( SyntaxElement *se, struct inp_par *inp, struct img_par *img, DecodingEnvironmentPtr dep_dp) { int a, b; int act_ctx; int act_sym; int bframe=(img->type==B_IMG_1 || img->type==B_IMG_MULT); int mode_sym; int ct = 0; int curr_mb_type; int useABT = ((inp->abt==INTER_INTRA_ABT) || (inp->abt==INTER_ABT)); MotionInfoContexts *ctx = (img->currentSlice)->mot_ctx; Macroblock *currMB = &img->mb_data[img->map_mb_nr];//GB current_mb_nr]; 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 != I4MB) ? 1 : 0 ); if (currMB->mb_available[1][0] == NULL) a = 0; else a = (( (currMB->mb_available[1][0])->mb_type != I4MB) ? 1 : 0 ); act_ctx = a + b; act_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx); se->context = act_ctx; // store context if (act_sym==0) // 4x4 Intra { curr_mb_type = act_sym; } else // 16x16 Intra { act_sym = 1; act_ctx = 4; mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx ); // decoding of AC/no AC act_sym += mode_sym*12; act_ctx = 5; // decoding of cbp: 0,1,2 mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx ); if (mode_sym!=0) { act_ctx=6; mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx ); act_sym+=4; if (mode_sym!=0) act_sym+=4; } // decoding of I pred-mode: 0,1,2,3 act_ctx = 7; mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx ); act_sym += mode_sym*2; act_ctx = 8; mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx ); act_sym += mode_sym; curr_mb_type = act_sym; } } else if(img->type == SI_IMG) // SI-frame { // special ctx's for SI4MB if (currMB->mb_available[0][1] == NULL) b = 0; else b = (( (currMB->mb_available[0][1])->mb_type != SI4MB) ? 1 : 0 ); if (currMB->mb_available[1][0] == NULL) a = 0; else a = (( (currMB->mb_available[1][0])->mb_type != SI4MB) ? 1 : 0 ); act_ctx = a + b; act_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[4] + act_ctx); se->context = act_ctx; // store context if (act_sym==0) // SI 4x4 Intra { curr_mb_type = 0; } else // analog INTRA_IMG { if (currMB->mb_available[0][1] == NULL) b = 0; else b = (( (currMB->mb_available[0][1])->mb_type != I4MB) ? 1 : 0 ); if (currMB->mb_available[1][0] == NULL) a = 0; else a = (( (currMB->mb_available[1][0])->mb_type != I4MB) ? 1 : 0 ); act_ctx = a + b; act_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx); se->context = act_ctx; // store context if (act_sym==0) // 4x4 Intra { curr_mb_type = 1; } else // 16x16 Intra { act_sym = 2; act_ctx = 4; mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx ); // decoding of AC/no AC act_sym += mode_sym*12; act_ctx = 5; // decoding of cbp: 0,1,2 mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx ); if (mode_sym!=0) { act_ctx=6; mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx ); act_sym+=4; if (mode_sym!=0) act_sym+=4; } // decoding of I pred-mode: 0,1,2,3 act_ctx = 7; mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx ); act_sym += mode_sym*2; act_ctx = 8; mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx ); act_sym += mode_sym; curr_mb_type = act_sym; } } } else { if (bframe) { ct = 1; 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; if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][act_ctx])) { if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][4])) { if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][5])) { act_sym=12; if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][6])) act_sym+=8; if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][6])) act_sym+=4; if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][6])) act_sym+=2; if (act_sym==24) act_sym=11; else if (act_sym==26) act_sym=22; else { if (act_sym==22) act_sym=23; if ((!useABT) || (act_sym != 23)) if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][6])) act_sym+=1; } } else { act_sym=3; if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][6])) act_sym+=4; if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][6])) act_sym+=2; if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][6])) act_sym+=1; } } else { if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][6])) act_sym=2; else act_sym=1; } } else { act_sym = 0; } } else // P-frame { { if (biari_decode_symbol(dep_dp, &ctx->mb_type_contexts[1][4] )) { if (!useABT) { if (biari_decode_symbol(dep_dp, &ctx->mb_type_contexts[1][7] )) act_sym = 7; else act_sym = 6; } else act_sym = 6; } else { if (biari_decode_symbol(dep_dp, &ctx->mb_type_contexts[1][5] )) { if (biari_decode_symbol(dep_dp, &ctx->mb_type_contexts[1][7] )) act_sym = 2; else act_sym = 3; } else { if (biari_decode_symbol(dep_dp, &ctx->mb_type_contexts[1][6] )) act_sym = 4; else act_sym = 1; } } } } if (act_sym<=6 || (((img->type == B_IMG_1 || img->type == B_IMG_MULT)?1:0) && act_sym<=23)) { curr_mb_type = act_sym; } else // additional info for 16x16 Intra-mode { act_ctx = 8; mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[1] + act_ctx ); // decoding of AC/no AC act_sym += mode_sym*12; // decoding of cbp: 0,1,2 act_ctx = 9; mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[1] + act_ctx ); if (mode_sym != 0) { act_sym+=4; mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[1] + act_ctx ); if (mode_sym != 0) act_sym+=4; } // decoding of I pred-mode: 0,1,2,3 act_ctx = 10; mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[1] + act_ctx ); act_sym += mode_sym*2; mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[1] + act_ctx ); act_sym += mode_sym; curr_mb_type = act_sym; } } se->value1 = curr_mb_type; // if (curr_mb_type >= 23) printf(" stopx"); #if TRACE fprintf(p_trace, "@%d%s\t\t\t%d\n",symbolCount++, se->tracestring, se->value1); fflush(p_trace); #endif } /*! ************************************************************************ * \brief * This function is used to arithmetically decode a pair of * intra prediction modes of a given MB. ************************************************************************ */ void readIntraPredModeFromBuffer_CABAC( SyntaxElement *se, struct inp_par *inp, struct img_par *img, DecodingEnvironmentPtr dep_dp) { TextureInfoContexts *ctx = img->currentSlice->tex_ctx; int act_sym; // use_most_probable_mode act_sym = biari_decode_symbol(dep_dp, ctx->ipr_contexts); // remaining_mode_selector if (act_sym == 0) se->value1 = -1; else { se->value1 = 0; se->value1 |= (biari_decode_symbol(dep_dp, ctx->ipr_contexts+1) << 2); se->value1 |= (biari_decode_symbol(dep_dp, ctx->ipr_contexts+1) << 1); se->value1 |= biari_decode_symbol(dep_dp, ctx->ipr_contexts+1); } #if TRACE fprintf(p_trace, "@%d%s\t\t\t%d\n",symbolCount++, se->tracestring, se->value1); fflush(p_trace); #endif } /*! ************************************************************************ * \brief * This function is used to arithmetically decode the reference * parameter of a given MB. ************************************************************************ */ void readRefFrameFromBuffer_CABAC( SyntaxElement *se, struct inp_par *inp, struct img_par *img, DecodingEnvironmentPtr dep_dp) { MotionInfoContexts *ctx = img->currentSlice->mot_ctx; Macroblock *currMB = &img->mb_data[img->map_mb_nr];//GB current_mb_nr]; int addctx = se->context; int a, b; int act_ctx; int act_sym; int** refframe_array = ((img->type==B_IMG_1 || img->type==B_IMG_MULT) ? img->fw_refFrArr : refFrArr); int block_y = img->block_y; if( img->mb_frame_field_flag ) { if( !img->mb_field ) { refframe_array = ((img->type==B_IMG_1 || img->type==B_IMG_MULT) ? img->fw_refFrArr_frm : refFrArr_frm); } else if ( img->current_mb_nr % 2 ) { refframe_array = ((img->type==B_IMG_1 || img->type==B_IMG_MULT) ? img->fw_refFrArr_bot : refFrArr_bot); block_y = ( img->block_y - 4 ) / 2; } else { refframe_array = ((img->type==B_IMG_1 || img->type==B_IMG_MULT) ? img->fw_refFrArr_top : refFrArr_top); block_y = img->block_y / 2; } } if (currMB->mb_available[0][1] == NULL) b = 0; else if (IS_DIRECT(currMB->mb_available[0][1])) b = 0; else b = (refframe_array[block_y+img->subblock_y-1][img->block_x+img->subblock_x] > 0 ? 1 : 0); if (currMB->mb_available[1][0] == NULL) a = 0; else if (IS_DIRECT(currMB->mb_available[1][0])) a = 0; else a = (refframe_array[block_y+img->subblock_y][img->block_x+img->subblock_x-1] > 0 ? 1 : 0); act_ctx = a + 2*b; se->context = act_ctx; // store context act_sym = biari_decode_symbol(dep_dp,ctx->ref_no_contexts[addctx] + act_ctx ); if (act_sym != 0) { act_ctx = 4; act_sym = unary_bin_decode(dep_dp,ctx->ref_no_contexts[addctx]+act_ctx,1); act_sym++; } se->value1 = act_sym; #if TRACE fprintf(p_trace, "@%d %s\t\t\t%d \n",symbolCount++, se->tracestring, se->value1); // fprintf(p_trace," c: %d :%d \n",ctx->ref_no_contexts[addctx][act_ctx].cum_freq[0],ctx->ref_no_contexts[addctx][act_ctx].cum_freq[1]); fflush(p_trace); // commented out, does not compile. karll@real.com #endif } /*! ************************************************************************ * \brief * This function is used to arithmetically decode the backward reference * parameter of a given MB. ************************************************************************ */ void readBwdRefFrameFromBuffer_CABAC( SyntaxElement *se, struct inp_par *inp, struct img_par *img, DecodingEnvironmentPtr dep_dp) { MotionInfoContexts *ctx = img->currentSlice->mot_ctx; Macroblock *currMB = &img->mb_data[img->map_mb_nr];//GB current_mb_nr]; int addctx = se->context; int a, b; int act_ctx; int act_sym; int** refframe_array = img->bw_refFrArr; int block_y = img->block_y; if( img->mb_frame_field_flag ) { if( !img->mb_field ) { refframe_array = img->bw_refFrArr_frm; } else if ( img->current_mb_nr % 2 ) { refframe_array = img->bw_refFrArr_bot; block_y = ( img->block_y - 4 ) / 2; } else { refframe_array = img->bw_refFrArr_top; block_y = img->block_y / 2; } } #define REF_IDX(r) ((img->num_ref_pic_active_bwd>1 && (r)<2) ? (1-(r)):(r)) if (currMB->mb_available[0][1] == NULL) b = 0; else if (IS_DIRECT(currMB->mb_available[0][1])) b = 0; else b = (REF_IDX(refframe_array[block_y+img->subblock_y-1][img->block_x+img->subblock_x]) > 0 ? 1 : 0); if (currMB->mb_available[1][0] == NULL) a = 0; else if (IS_DIRECT(currMB->mb_available[1][0])) a = 0; else a = (REF_IDX(refframe_array[block_y+img->subblock_y][img->block_x+img->subblock_x-1]) > 0 ? 1 : 0); #undef REF_IDX act_ctx = a + 2*b; se->context = act_ctx; // store context act_sym = biari_decode_symbol(dep_dp,ctx->ref_no_contexts[addctx] + act_ctx ); if (act_sym != 0) { act_ctx = 4; act_sym = unary_bin_decode(dep_dp,ctx->ref_no_contexts[addctx]+act_ctx,1); act_sym++; } se->value1 = act_sym; #if TRACE fprintf(p_trace, "@%d%s\t\t\t%d",symbolCount++, se->tracestring, se->value1); // fprintf(p_trace," c: %d :%d \n",ctx->ref_no_contexts[addctx][act_ctx].cum_freq[0],ctx->ref_no_contexts[addctx][act_ctx].cum_freq[1]); fflush(p_trace); // commented out, does not compile. karll@real.com #endif } /*! ************************************************************************ * \brief * This function is used to arithmetically decode the motion * vector data of a given MB. ************************************************************************ */ void readMVDFromBuffer_CABAC(SyntaxElement *se, struct inp_par *inp, struct img_par *img, DecodingEnvironmentPtr dep_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 k = se->value2; // MVD component MotionInfoContexts *ctx = img->currentSlice->mot_ctx; Macroblock *currMB = &img->mb_data[img->map_mb_nr];//GB current_mb_nr]; 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-1/*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-1/*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; } se->context = act_ctx; act_sym = biari_decode_symbol(dep_dp, &ctx->mv_res_contexts[0][act_ctx] ); if (act_sym == 0) { mv_pred_res = 0; } else { act_ctx=5*k+4; mv_sign = biari_decode_symbol_eq_prob(dep_dp); act_ctx=5*k; act_sym = unary_exp_golomb_mv_decode(dep_dp,ctx->mv_res_contexts[1]+act_ctx,3); act_sym++; mv_pred_res = ((mv_sign != 0) ? (-act_sym) : act_sym); } se->value1 = mv_pred_res; #if TRACE fprintf(p_trace, "@%d %s\t\t\t%d %d\n",symbolCount++, se->tracestring, se->value1,a+b); fflush(p_trace); #endif } /*! ************************************************************************ * \brief * This function is used to arithmetically decode the delta qp * of a given MB. ************************************************************************ */ void readDquant_FromBuffer_CABAC(SyntaxElement *se, struct inp_par *inp, struct img_par *img, DecodingEnvironmentPtr dep_dp) { MotionInfoContexts *ctx = img->currentSlice->mot_ctx; Macroblock *currMB = &img->mb_data[img->map_mb_nr];//GB current_mb_nr]; int act_ctx; int act_sym; int dquant; if (currMB->mb_available[1][0] == NULL) act_ctx = 0; else act_ctx = ( ((currMB->mb_available[1][0])->delta_quant != 0) ? 1 : 0); act_sym = biari_decode_symbol(dep_dp,ctx->delta_qp_contexts + act_ctx ); if (act_sym != 0) { act_ctx = 2; act_sym = unary_bin_decode(dep_dp,ctx->delta_qp_contexts+act_ctx,1); act_sym++; } dquant = (act_sym+1)/2; if((act_sym & 0x01)==0) // lsb is signed bit dquant = -dquant; se->value1 = dquant; #if TRACE fprintf(p_trace, "@%d%s\t\t\t%d\n",symbolCount++, se->tracestring, se->value1); fflush(p_trace); #endif } /*! ************************************************************************ * \brief * This function is used to arithmetically decode the coded * block pattern of a given MB. ************************************************************************ */ void readCBPFromBuffer_CABAC(SyntaxElement *se, struct inp_par *inp, struct img_par *img, DecodingEnvironmentPtr dep_dp) { TextureInfoContexts *ctx = img->currentSlice->tex_ctx; Macroblock *currMB = &img->mb_data[img->map_mb_nr];//GB current_mb_nr]; int mb_x, mb_y; int a, b; int curr_cbp_ctx, curr_cbp_idx; int cbp = 0; int cbp_bit; int mask; // coding of luma part (bit by bit) for (mb_y=0; mb_y < 4; mb_y += 2) { for (mb_x=0; mb_x < 4; mb_x += 2) { if (currMB->b8mode[mb_y+(mb_x/2)]==IBLOCK) curr_cbp_idx = 0; else curr_cbp_idx = 1; if (mb_y == 0) { if (currMB->mb_available[0][1] == NULL) b = 0; else b = (( ((currMB->mb_available[0][1])->cbp & (1<<(2+mb_x/2))) == 0) ? 1 : 0); } else b = ( ((cbp & (1<<(mb_x/2))) == 0) ? 1: 0); if (mb_x == 0) { if (currMB->mb_available[1][0] == NULL) a = 0; else a = (( ((currMB->mb_available[1][0])->cbp & (1<<(mb_y+1))) == 0) ? 1 : 0); } else a = ( ((cbp & (1< cbp_contexts[0] + curr_cbp_ctx ); if (cbp_bit) cbp += mask; } } 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 = biari_decode_symbol(dep_dp, ctx->cbp_contexts[1] + curr_cbp_ctx ); if (cbp_bit) // set the chroma bits { 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 = biari_decode_symbol(dep_dp, ctx->cbp_contexts[2] + curr_cbp_ctx ); cbp += (cbp_bit == 1) ? 32 : 16; } se->value1 = cbp; #if TRACE fprintf(p_trace, "@%d %s\t\t\t%d\n",symbolCount++, se->tracestring, se->value1); fflush(p_trace); #endif } /*! ************************************************************************ * \brief * This function is used to arithmetically decode the chroma * intra prediction mode of a given MB. ************************************************************************ */ //GB void readCIPredMode_FromBuffer_CABAC(SyntaxElement *se, struct inp_par *inp, struct img_par *img, DecodingEnvironmentPtr dep_dp) { TextureInfoContexts *ctx = img->currentSlice->tex_ctx; Macroblock *currMB = &img->mb_data[img->map_mb_nr]; int act_ctx,a,b; int act_sym = se->value1; if (currMB->mb_available[0][1] == NULL) b = 0; else b = ( ((currMB->mb_available[0][1])->c_ipred_mode != 0) ? 1 : 0); if (currMB->mb_available[1][0] == NULL) a = 0; else a = ( ((currMB->mb_available[1][0])->c_ipred_mode != 0) ? 1 : 0); act_ctx = a+b; act_sym = biari_decode_symbol(dep_dp, ctx->cipr_contexts + act_ctx ); if (act_sym!=0) act_sym = unary_bin_max_decode(dep_dp,ctx->cipr_contexts+3,0,2)+1; se->value1 = act_sym; #if TRACE fprintf(p_trace, "@%d%s\t\t\t%d\n",symbolCount++, se->tracestring, se->value1); fflush(p_trace); #endif } static const int maxpos [] = {16, 15, 64, 32, 32, 16, 4, 15}; static const int c1isdc [] = { 1, 0, 1, 1, 1, 1, 1, 0}; static const int type2ctx_bcbp[] = { 0, 1, 2, 2, 3, 4, 5, 6}; // 7 static const int type2ctx_map [] = { 0, 1, 2, 3, 4, 5, 6, 7}; // 8 static const int type2ctx_last[] = { 0, 1, 2, 3, 4, 5, 6, 7}; // 8 static const int type2ctx_one [] = { 0, 1, 2, 3, 3, 4, 5, 6}; // 7 static const int type2ctx_abs [] = { 0, 1, 2, 3, 3, 4, 5, 6}; // 7 /*! ************************************************************************ * \brief * Read CBP4-BIT ************************************************************************ */ int read_and_store_CBP_block_bit (Macroblock *currMB, DecodingEnvironmentPtr dep_dp, struct img_par *img, int type) { #define BIT_SET(x,n) ((int)(((x)&(1<<(n)))>>(n))) int y_ac = (type==LUMA_16AC || type==LUMA_8x8 || type==LUMA_8x4 || type==LUMA_4x8 || type==LUMA_4x4); int y_dc = (type==LUMA_16DC); int u_ac = (type==CHROMA_AC && !img->is_v_block); int v_ac = (type==CHROMA_AC && img->is_v_block); int u_dc = (type==CHROMA_DC && !img->is_v_block); int v_dc = (type==CHROMA_DC && img->is_v_block); int j = (y_ac || u_ac || v_ac ? img->subblock_y : 0); int i = (y_ac || u_ac || v_ac ? img->subblock_x : 0); int bit = (y_dc ? 0 : y_ac ? 1+4*j+i : u_dc ? 17 : v_dc ? 18 : u_ac ? 19+2*j+i : 23+2*j+i); int ystep_back = (y_ac ? 12 : u_ac || v_ac ? 2 : 0); int xstep_back = (y_ac ? 3 : u_ac || v_ac ? 1 : 0); int ystep = (y_ac ? 4 : u_ac || v_ac ? 2 : 0); int default_bit = (img->is_intra_block ? 1 : 0); int upper_bit = default_bit; int left_bit = default_bit; int cbp_bit = 1; // always one for 8x8 mode int ctx; if (type!=LUMA_8x8) { //--- get bits from neighbouring blocks --- if (j==0) { if (currMB->mb_available[0][1]) { upper_bit = BIT_SET(currMB->mb_available[0][1]->cbp_bits,bit+ystep_back); } } else { upper_bit = BIT_SET(currMB->cbp_bits,bit-ystep); } if (i==0) { if (currMB->mb_available[1][0]) { left_bit = BIT_SET(currMB->mb_available[1][0]->cbp_bits,bit+xstep_back); } } else { left_bit = BIT_SET(currMB->cbp_bits,bit-1); } ctx = 2*upper_bit+left_bit; //===== encode symbol ===== cbp_bit = biari_decode_symbol (dep_dp, img->currentSlice->tex_ctx->bcbp_contexts[type2ctx_bcbp[type]] + ctx); } //--- set bits for current block --- if (cbp_bit) { if (type==LUMA_8x8) { currMB->cbp_bits |= (1<< bit ); currMB->cbp_bits |= (1<<(bit+1)); currMB->cbp_bits |= (1<<(bit+4)); currMB->cbp_bits |= (1<<(bit+5)); } else if (type==LUMA_8x4) { currMB->cbp_bits |= (1<< bit ); currMB->cbp_bits |= (1<<(bit+1)); } else if (type==LUMA_4x8) { currMB->cbp_bits |= (1<< bit ); currMB->cbp_bits |= (1<<(bit+4)); } else { currMB->cbp_bits |= (1< ctx for MAP ===== //--- zig-zag scan ---- static const int pos2ctx_map8x8 [] = { 0, 1, 2, 3, 4, 5, 5, 4, 4, 3, 3, 4, 4, 4, 5, 5, 4, 4, 4, 4, 3, 3, 6, 7, 7, 7, 8, 9, 10, 9, 8, 7, 7, 6, 11, 12, 13, 11, 6, 7, 8, 9, 14, 10, 9, 8, 6, 11, 12, 13, 11, 6, 9, 14, 10, 9, 11, 12, 13, 11 ,14, 10, 12, 14}; // 15 CTX static const int pos2ctx_map8x4 [] = { 0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 9, 8, 6, 7, 8, 9, 10, 11, 9, 8, 6, 12, 8, 9, 10, 11, 9, 13, 13, 14, 14}; // 15 CTX static const int pos2ctx_map4x4 [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14}; // 15 CTX static const int* pos2ctx_map [] = {pos2ctx_map4x4, pos2ctx_map4x4, pos2ctx_map8x8, pos2ctx_map8x4, pos2ctx_map8x4, pos2ctx_map4x4, pos2ctx_map4x4, pos2ctx_map4x4}; //--- interlace scan ---- static const int pos2ctx_map8x8i[] = { 0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 7, 7, 8, 4, 5, 6, 9, 10, 10, 8, 11, 12, 11, 9, 9, 10, 10, 8, 11, 12, 11, 9, 9, 10, 10, 8, 11, 12, 11, 9, 9, 10, 10, 8, 13, 13, 9, 9, 10, 10, 8, 13, 13, 9, 9, 10, 10, 14, 14, 14, 14, 14, 14}; // 15 CTX static const int pos2ctx_map8x4i[] = { 0, 1, 2, 3, 4, 5, 6, 3, 4, 5, 6, 3, 4, 7, 6, 8, 9, 7, 6, 8, 9, 10, 11, 12, 12, 10, 11, 13, 13, 14, 14, 14}; // 15 CTX static const int pos2ctx_map4x8i[] = { 0, 1, 1, 1, 2, 3, 3, 4, 4, 4, 5, 6, 2, 7, 7, 8, 8, 8, 5, 6, 9, 10, 10, 11, 11, 11, 12, 13, 13, 14, 14, 14}; // 15 CTX static const int* pos2ctx_map_int[] = {pos2ctx_map4x4, pos2ctx_map4x4, pos2ctx_map8x8i,pos2ctx_map8x4i, pos2ctx_map4x8i,pos2ctx_map4x4, pos2ctx_map4x4, pos2ctx_map4x4}; //===== position -> ctx for LAST ===== static const int pos2ctx_last8x8 [] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8}; // 9 CTX static const int pos2ctx_last8x4 [] = { 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8}; // 9 CTX static const int pos2ctx_last4x4 [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; // 15 CTX static const int* pos2ctx_last [] = {pos2ctx_last4x4, pos2ctx_last4x4, pos2ctx_last8x8, pos2ctx_last8x4, pos2ctx_last8x4, pos2ctx_last4x4, pos2ctx_last4x4, pos2ctx_last4x4}; /*! ************************************************************************ * \brief * Read Significance MAP ************************************************************************ */ int read_significance_map (Macroblock *currMB, DecodingEnvironmentPtr dep_dp, struct img_par *img, int type, int coeff[]) { int i, sig; int coeff_ctr = 0; int i0 = 0; int i1 = maxpos[type]-1; if (!c1isdc[type]) { i0++; i1++; coeff--; } for (i=i0; i structure!=FRAME) sig = biari_decode_symbol (dep_dp, img->currentSlice->tex_ctx->map_contexts [type2ctx_map [type]] + pos2ctx_map_int [type][i]); else sig = biari_decode_symbol (dep_dp, img->currentSlice->tex_ctx->map_contexts [type2ctx_map [type]] + pos2ctx_map [type][i]); if (sig) { coeff[i] = 1; coeff_ctr++; //--- read last coefficient symbol --- if (biari_decode_symbol (dep_dp, img->currentSlice->tex_ctx->last_contexts[type2ctx_last[type]] + pos2ctx_last[type][i])) { for (i++; i =0; i--) { if (coeff[i]!=0) { ctx = min (c1,4); coeff[i] += biari_decode_symbol (dep_dp, img->currentSlice->tex_ctx->one_contexts[type2ctx_one[type]] + ctx); if (coeff[i]==2) { ctx = min (c2,4); coeff[i] += unary_exp_golomb_level_decode (dep_dp, img->currentSlice->tex_ctx->abs_contexts[type2ctx_abs[type]]+ctx); c1=0; c2++; } else if (c1) { c1++; } if (biari_decode_symbol_eq_prob(dep_dp)) { coeff[i] *= -1; } } } } /*! ************************************************************************ * \brief * Read Block-Transform Coefficients ************************************************************************ */ void readRunLevelFromBuffer_CABAC (SyntaxElement *se, struct inp_par *inp, struct img_par *img, DecodingEnvironmentPtr dep_dp) { static int coeff[64]; // one more for EOB static int coeff_ctr = -1; static int pos = 0; Macroblock *currMB = &img->mb_data[img->map_mb_nr];//GB current_mb_nr]; //--- read coefficients for whole block --- if (coeff_ctr < 0) { //===== decode CBP-BIT ===== if ((coeff_ctr = read_and_store_CBP_block_bit (currMB, dep_dp, img, se->context))) { //===== decode significance map ===== coeff_ctr = read_significance_map (currMB, dep_dp, img, se->context, coeff); //===== decode significant coefficients ===== read_significant_coefficients (currMB, dep_dp, img, se->context, coeff); } } //--- set run and level --- if (coeff_ctr) { //--- set run and level (coefficient) --- for (se->value2=0; coeff[pos]==0; pos++, se->value2++); se->value1=coeff[pos++]; } else { //--- set run and level (EOB) --- se->value1 = se->value2 = 0; } //--- decrement coefficient counter and re-set position --- if (coeff_ctr-- == 0) pos=0; #if TRACE fprintf(p_trace, "@%d%s\t\t\t%d\t%d\n",symbolCount++, se->tracestring, se->value1,se->value2); fflush(p_trace); #endif } /*! ************************************************************************ * \brief * arithmetic decoding ************************************************************************ */ int readSyntaxElement_CABAC(SyntaxElement *se, struct img_par *img, struct inp_par *inp, DataPartition *this_dataPart) { int curr_len; DecodingEnvironmentPtr dep_dp = &(this_dataPart->de_cabac); curr_len = arideco_bits_read(dep_dp); // perform the actual decoding by calling the appropriate method se->reading(se, inp, img, dep_dp); return (se->len = (arideco_bits_read(dep_dp) - curr_len)); } /*! ************************************************************************ * \brief * get slice and header ************************************************************************ */ int readSliceCABAC(struct img_par *img, struct inp_par *inp) { Slice *currSlice = img->currentSlice; Bitstream *currStream = currSlice->partArr[0].bitstream; unsigned char *code_buffer = currStream->streamBuffer; int *read_len = &(currStream->read_len); DecodingEnvironmentPtr dep = &((currSlice->partArr[0]).de_cabac); int current_header; int BitstreamLengthInBytes; int BitsUsedByHeader = 0, ByteStartPosition; int newframe = 0; //WYK: Oct. 8, 2001, change the method to find a new frame int startcodeprefix_len; //Number of bytes taken by start code prefix currStream->frame_bitoffset =0; memset (code_buffer, 0xff, MAX_CODED_FRAME_SIZE); // this prevents a buffer full with zeros BitstreamLengthInBytes = currStream->bitstream_length = GetOneSliceIntoSourceBitBuffer(img, inp, code_buffer, &startcodeprefix_len); // Here we are ready to interpret the picture and slice headers. Since // SliceHeader() gets the data out of the UVLC's len/info // array, we need to convert the start of our slice to such a format. if (BitstreamLengthInBytes < startcodeprefix_len) return EOS; BitstreamLengthInBytes = currStream->bitstream_length = EBSPtoRBSP(code_buffer, currStream->bitstream_length, startcodeprefix_len); BitstreamLengthInBytes = currStream->bitstream_length = RBSPtoSODB(code_buffer, currStream->bitstream_length); // Now we have the bits between the current startcode (inclusive) and the // next start code in code_buffer. Now decode the start codes and the headers currStream->frame_bitoffset += startcodeprefix_len * 8; BitsUsedByHeader+=SliceHeader(img, inp); //WYK: Oct. 8, 2001, change the method to find a new frame if(img->tr != img->tr_old) newframe = 1; else newframe = 0; // printf ("readSlice_CABAC: tr_old %d, tr %d, startcodeprefix_len %d, newframe %d\n", img->tr_old, img->tr, startcodeprefix_len, newframe); img->tr_old = img->tr; // if the TR of current slice is not identical to the TR of previous received slice, we have a new frame if(newframe) current_header = SOP; else current_header = SOS; ByteStartPosition = currStream->frame_bitoffset/8; if ((currStream->frame_bitoffset)%8 != 0) ByteStartPosition++; arideco_start_decoding(dep, code_buffer, ByteStartPosition, read_len, img->type); currSlice->picture_id = img->tr; return current_header; } /*! ************************************************************************ * \brief * decoding of unary binarization using one or 2 distinct * models for the first and all remaining bins; no terminating * "0" for max_symbol *********************************************************************** */ unsigned int unary_bin_max_decode(DecodingEnvironmentPtr dep_dp, BiContextTypePtr ctx, int ctx_offset, unsigned int max_symbol) { unsigned int l; unsigned int symbol; BiContextTypePtr ictx; symbol = biari_decode_symbol(dep_dp, ctx ); if (symbol==0) return 0; else { if (max_symbol == 1) return symbol; symbol=0; ictx=ctx+ctx_offset; do { l=biari_decode_symbol(dep_dp, ictx); symbol++; } while( (l!=0) && (symbol currentSlice; int *partMap = assignSE2partition[currSlice->dp_mode]; DataPartition *dP; unsigned int bit; DecodingEnvironmentPtr dep_dp; if(img->type == B_IMG_1 || img->type == B_IMG_MULT) dP = &(currSlice->partArr[partMap[SE_BFRAME]]); else dP = &(currSlice->partArr[partMap[SE_MBTYPE]]); dep_dp = &(dP->de_cabac); if( eos_bit ) { bit = biari_decode_final (dep_dp); //GB #if TRACE // strncpy(se->tracestring, "Decode Sliceterm", TRACESTRING_SIZE); fprintf(p_trace, "@%d %s\t\t%d\n",symbolCount++, "Decode Sliceterm", bit); fflush(p_trace); #endif } else { bit = 0; } return (bit==1?1:0); } /*! ************************************************************************ * \brief * Exp Golomb binarization and decoding of a symbol * with prob. of 0.5 ************************************************************************ */ unsigned int exp_golomb_decode_eq_prob( DecodingEnvironmentPtr dep_dp, int k) { unsigned int l; int symbol = 0; int binary_symbol = 0; do { l=biari_decode_symbol_eq_prob(dep_dp); if (l==1) { symbol += (1<