aboutsummaryrefslogtreecommitdiff
path: root/Src/h264dec/ldecod/src/cabac.c
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/h264dec/ldecod/src/cabac.c
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/h264dec/ldecod/src/cabac.c')
-rw-r--r--Src/h264dec/ldecod/src/cabac.c2123
1 files changed, 2123 insertions, 0 deletions
diff --git a/Src/h264dec/ldecod/src/cabac.c b/Src/h264dec/ldecod/src/cabac.c
new file mode 100644
index 00000000..a3c43513
--- /dev/null
+++ b/Src/h264dec/ldecod/src/cabac.c
@@ -0,0 +1,2123 @@
+/*!
+*************************************************************************************
+* \file cabac.c
+*
+* \brief
+* CABAC entropy coding routines
+*
+* \author
+* Main contributors (see contributors.h for copyright, address and affiliation details)
+* - Detlev Marpe <marpe@hhi.de>
+**************************************************************************************
+*/
+
+#include "global.h"
+#include "cabac.h"
+#include "memalloc.h"
+#include "elements.h"
+#include "image.h"
+#include "biaridecod.h"
+#include "mb_access.h"
+#include "vlc.h"
+#include <mmintrin.h>
+#define get_bit(x, n) (_mm_cvtsi64_si32(_mm_srli_si64(*(__m64 *)&(x), n)) & 1)
+/*static inline int get_bit(int64 x,int n)
+{
+return (int)(((x >> n) & 1));
+}*/
+
+static __forceinline void or_bits_low(int64 *x, int mask, int position)
+{
+ *(int32_t *)x |= (mask << position);
+}
+
+static inline void or_bits(int64 *x, int mask, int position)
+{
+#ifdef _M_IX86
+ __m64 mmx_x = *(__m64 *)x;
+ __m64 mmx_mask = _mm_cvtsi32_si64(mask);
+ mmx_mask=_mm_slli_si64(mmx_mask, position);
+ mmx_x = _mm_or_si64(mmx_x, mmx_mask);
+ *(__m64 *)x = mmx_x;
+#else
+ *x |= ((int64) mask << position);
+#endif
+}
+#if TRACE
+int symbolCount = 0;
+#endif
+
+/***********************************************************************
+* L O C A L L Y D E F I N E D F U N C T I O N P R O T O T Y P E S
+***********************************************************************
+*/
+static unsigned int unary_bin_decode(DecodingEnvironmentPtr dep_dp,
+ BiContextTypePtr ctx,
+ int ctx_offset);
+static unsigned int unary_bin_max_decode(DecodingEnvironmentPtr dep_dp,
+ BiContextTypePtr ctx,
+ int ctx_offset,
+ unsigned int max_symbol);
+
+unsigned int unary_exp_golomb_mv_decode(DecodingEnvironmentPtr dep_dp, BiContextTypePtr ctx, unsigned int max_bin);
+unsigned int unary_exp_golomb_mv_decode3(DecodingEnvironmentPtr dep_dp, BiContextTypePtr ctx);
+
+void CheckAvailabilityOfNeighborsCABAC(Macroblock *currMB)
+{
+ VideoParameters *p_Vid = currMB->p_Vid;
+ PixelPos up, left;
+
+ p_Vid->getNeighbourLeftLuma(currMB, &left);
+ p_Vid->getNeighbourUpLuma(currMB, &up);
+
+ if (up.available)
+ currMB->mb_up = &p_Vid->mb_data[up.mb_addr];
+ else
+ currMB->mb_up = NULL;
+
+ if (left.available)
+ currMB->mb_left = &p_Vid->mb_data[left.mb_addr];
+ else
+ currMB->mb_left = NULL;
+}
+
+void cabac_new_slice(Slice *currSlice)
+{
+ currSlice->last_dquant=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
+* 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 );
+}
+
+
+/*!
+************************************************************************
+* \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 );
+}
+
+Boolean readFieldModeInfo_CABAC(Macroblock *currMB, DecodingEnvironmentPtr dep_dp)
+{
+ Slice *currSlice = currMB->p_Slice;
+ VideoParameters *p_Vid = currMB->p_Vid;
+ MotionInfoContexts *ctx = currSlice->mot_ctx;
+ int a = currMB->mb_avail_left ? p_Vid->mb_data[currMB->mb_addr_left].mb_field : 0;
+ int b = currMB->mb_avail_up ? p_Vid->mb_data[currMB->mb_addr_up].mb_field : 0;
+ int act_ctx = a + b;
+
+ return biari_decode_symbol (dep_dp, &ctx->mb_aff_contexts[act_ctx]);
+}
+
+
+int check_next_mb_and_get_field_mode_CABAC(Slice *currSlice, DataPartition *act_dp)
+{
+ VideoParameters *p_Vid = currSlice->p_Vid;
+ BiContextTypePtr mb_type_ctx_copy[3];
+ BiContextTypePtr mb_aff_ctx_copy;
+ DecodingEnvironmentPtr dep_dp_copy;
+
+ int length;
+ DecodingEnvironmentPtr dep_dp = &(act_dp->de_cabac);
+
+ int bframe = (currSlice->slice_type == B_SLICE);
+ int skip = 0;
+ int field = 0;
+ int i;
+
+ Macroblock *currMB;
+
+ //get next MB
+ ++p_Vid->current_mb_nr;
+
+ currMB = &p_Vid->mb_data[p_Vid->current_mb_nr];
+ currMB->p_Vid = p_Vid;
+ currMB->p_Slice = currSlice;
+ currMB->slice_nr = p_Vid->current_slice_nr;
+ currMB->mb_field = p_Vid->mb_data[p_Vid->current_mb_nr-1].mb_field;
+ currMB->mbAddrX = p_Vid->current_mb_nr;
+
+ CheckAvailabilityOfNeighbors(currMB);
+ CheckAvailabilityOfNeighborsCABAC(currMB);
+
+ //create
+ dep_dp_copy = (DecodingEnvironmentPtr) calloc(1, sizeof(DecodingEnvironment) );
+ for (i=0;i<3;++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<3;++i)
+ memcpy(mb_type_ctx_copy[i], currSlice->mot_ctx->mb_type_contexts[i],NUM_MB_TYPE_CTX*sizeof(BiContextType) );
+ memcpy(mb_aff_ctx_copy, currSlice->mot_ctx->mb_aff_contexts,NUM_MB_AFF_CTX*sizeof(BiContextType) );
+
+ //check_next_mb
+ currSlice->last_dquant = 0;
+ skip = readMB_skip_flagInfo_CABAC(currMB, dep_dp);
+
+ if (!skip)
+ {
+ field = readFieldModeInfo_CABAC(currMB, dep_dp);
+ p_Vid->mb_data[p_Vid->current_mb_nr-1].mb_field = field;
+ }
+
+ //reset
+ p_Vid->current_mb_nr--;
+
+ memcpy(dep_dp,dep_dp_copy,sizeof(DecodingEnvironment));
+ *(dep_dp->Dcodestrm_len) = length;
+ for (i=0;i<3;++i)
+ memcpy(currSlice->mot_ctx->mb_type_contexts[i],mb_type_ctx_copy[i], NUM_MB_TYPE_CTX*sizeof(BiContextType) );
+ memcpy( currSlice->mot_ctx->mb_aff_contexts,mb_aff_ctx_copy,NUM_MB_AFF_CTX*sizeof(BiContextType) );
+
+ CheckAvailabilityOfNeighborsCABAC(currMB);
+
+ //delete
+ free(dep_dp_copy);
+ for (i=0;i<3;++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.
+************************************************************************
+*/
+#if defined(_DEBUG) || !defined(_M_IX86)
+int decodeMVD_CABAC(DecodingEnvironmentPtr dep_dp, BiContextType mv_ctx[2][NUM_MV_RES_CTX], int act_ctx, int err)
+{
+ int act_sym = biari_decode_symbol(dep_dp,&mv_ctx[0][act_ctx+err] );
+
+ if (act_sym != 0)
+ {
+ int mv_sign;
+ act_sym = unary_exp_golomb_mv_decode3(dep_dp,mv_ctx[1]+act_ctx);
+ ++act_sym;
+ mv_sign = biari_decode_symbol_eq_prob(dep_dp);
+
+ if(mv_sign)
+ act_sym = -act_sym;
+ }
+ return act_sym;
+}
+#else
+int decodeMVD_CABAC(DecodingEnvironmentPtr dep_dp, BiContextType mv_ctx[2][NUM_MV_RES_CTX], int act_ctx, int err);
+#endif
+
+int readMVD_CABAC(Macroblock *currMB, DecodingEnvironmentPtr dep_dp, int k, int list_idx, int x, int y)
+{
+ VideoParameters *p_Vid = currMB->p_Vid;
+ Slice *currSlice = currMB->p_Slice;
+ MotionInfoContexts *ctx = currSlice->mot_ctx;
+ int a = 0, b = 0;
+// int act_ctx;
+// int act_sym;
+ int mv_local_err;
+ int err;
+
+ PixelPos block_a, block_b;
+
+ p_Vid->getNeighbourPXLumaNB_NoPos(currMB, y - 1, &block_b);
+ if (block_b.available)
+ {
+ b = abs(p_Vid->mb_data[block_b.mb_addr].mvd[list_idx][block_b.y>>2][x>>2][k]);
+ if (currSlice->mb_aff_frame_flag && (k==1))
+ {
+ if ((currMB->mb_field==0) && (p_Vid->mb_data[block_b.mb_addr].mb_field==1))
+ b *= 2;
+ else if ((currMB->mb_field==1) && (p_Vid->mb_data[block_b.mb_addr].mb_field==0))
+ b /= 2;
+ }
+ }
+
+ p_Vid->getNeighbourXPLumaNB_NoPos(currMB, x - 1, y , &block_a);
+ if (block_a.available)
+ {
+ a = abs(p_Vid->mb_data[block_a.mb_addr].mvd[list_idx][block_a.y>>2][block_a.x>>2][k]);
+ if (currSlice->mb_aff_frame_flag && (k==1))
+ {
+ if ((currMB->mb_field==0) && (p_Vid->mb_data[block_a.mb_addr].mb_field==1))
+ a *= 2;
+ else if ((currMB->mb_field==1) && (p_Vid->mb_data[block_a.mb_addr].mb_field==0))
+ a /= 2;
+ }
+ }
+
+ if ((mv_local_err = a + b)<3)
+ err = 0;
+ else
+ {
+ if (mv_local_err > 32)
+ err = 3;
+ else
+ err = 2;
+ }
+
+ return decodeMVD_CABAC(dep_dp, ctx->mv_res_contexts, 5*k, err);
+ /*
+ act_sym = biari_decode_symbol(dep_dp,&ctx->mv_res_contexts[0][act_ctx] );
+
+ if (act_sym != 0)
+ {
+ int mv_sign;
+ act_ctx = 5 * k;
+ act_sym = unary_exp_golomb_mv_decode3(dep_dp,ctx->mv_res_contexts[1]+act_ctx);
+ ++act_sym;
+ mv_sign = biari_decode_symbol_eq_prob(dep_dp);
+
+ if(mv_sign)
+ act_sym = -act_sym;
+ }
+ return act_sym;
+ */
+}
+
+
+/*!
+************************************************************************
+* \brief
+* This function is used to arithmetically decode the 8x8 block type.
+************************************************************************
+*/
+int readB8_typeInfo_CABAC(Slice *currSlice, DecodingEnvironmentPtr dep_dp)
+{
+ int act_sym = 0;
+ int bframe = (currSlice->slice_type == B_SLICE);
+
+ MotionInfoContexts *ctx = currSlice->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;
+ }
+ }
+ return act_sym;
+}
+
+/*!
+************************************************************************
+* \brief
+* This function is used to arithmetically decode the macroblock
+* type info of a given MB.
+************************************************************************
+*/
+#if defined(_DEBUG) || !defined(_M_IX86)
+int readMB_skip_flagInfo_CABAC(Macroblock *currMB, DecodingEnvironmentPtr dep_dp)
+{
+ Slice *currSlice = currMB->p_Slice;
+ int bframe=(currSlice->slice_type == B_SLICE);
+ MotionInfoContexts *ctx = currSlice->mot_ctx;
+ int a = (currMB->mb_left != NULL) ? (currMB->mb_left->skip_flag == 0) : 0;
+ int b = (currMB->mb_up != NULL) ? (currMB->mb_up ->skip_flag == 0) : 0;
+ int act_ctx;
+ int skip;
+
+ if (bframe)
+ {
+ act_ctx = 7 + a + b;
+
+ skip = biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][act_ctx]);
+ }
+ else
+ {
+ act_ctx = a + b;
+
+ skip = biari_decode_symbol(dep_dp, &ctx->mb_type_contexts[1][act_ctx]);
+ }
+
+ if (skip)
+ {
+ currSlice->last_dquant = 0;
+ }
+ return skip;
+}
+#endif
+
+/*!
+***************************************************************************
+* \brief
+* This function is used to arithmetically decode the macroblock
+* intra_pred_size flag info of a given MB.
+***************************************************************************
+*/
+
+Boolean readMB_transform_size_flag_CABAC(Macroblock *currMB, DecodingEnvironmentPtr dep_dp)
+{
+ Slice *currSlice = currMB->p_Slice;
+ TextureInfoContexts*ctx = currSlice->tex_ctx;
+
+ int b = (currMB->mb_up == NULL) ? 0 : currMB->mb_up->luma_transform_size_8x8_flag;
+ int a = (currMB->mb_left == NULL) ? 0 : currMB->mb_left->luma_transform_size_8x8_flag;
+
+ int act_ctx = a + b;
+ int act_sym = biari_decode_symbol(dep_dp, ctx->transform_size_contexts + act_ctx);
+
+ return act_sym;
+}
+
+/*!
+************************************************************************
+* \brief
+* This function is used to arithmetically decode the macroblock
+* type info of a given MB.
+************************************************************************
+*/
+int readMB_typeInfo_CABAC(Macroblock *currMB, DecodingEnvironmentPtr dep_dp)
+{
+ Slice *currSlice = currMB->p_Slice;
+ MotionInfoContexts *ctx = currSlice->mot_ctx;
+
+ int a = 0, b = 0;
+ int act_ctx;
+ int act_sym;
+ int bframe=(currSlice->slice_type == B_SLICE);
+ int mode_sym;
+ int curr_mb_type;
+
+ if(currSlice->slice_type == I_SLICE) // INTRA-frame
+ {
+ if (currMB->mb_up != NULL)
+ b = (((currMB->mb_up)->mb_type != I4MB && currMB->mb_up->mb_type != I8MB) ? 1 : 0 );
+
+ if (currMB->mb_left != NULL)
+ a = (((currMB->mb_left)->mb_type != I4MB && currMB->mb_left->mb_type != I8MB) ? 1 : 0 );
+
+ act_ctx = a + b;
+ act_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx);
+
+ if (act_sym==0) // 4x4 Intra
+ {
+ curr_mb_type = act_sym;
+ }
+ else // 16x16 Intra
+ {
+ mode_sym = biari_decode_final(dep_dp);
+ if(mode_sym == 1)
+ {
+ curr_mb_type = 25;
+ }
+ else
+ {
+ 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(currSlice->slice_type == SI_SLICE) // SI-frame
+ {
+ // special ctx's for SI4MB
+ if (currMB->mb_up != NULL)
+ b = (( (currMB->mb_up)->mb_type != SI4MB) ? 1 : 0 );
+
+ if (currMB->mb_left != NULL)
+ a = (( (currMB->mb_left)->mb_type != SI4MB) ? 1 : 0 );
+
+ act_ctx = a + b;
+ act_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[1] + act_ctx);
+
+ if (act_sym==0) // SI 4x4 Intra
+ {
+ curr_mb_type = 0;
+ }
+ else // analog INTRA_IMG
+ {
+ if (currMB->mb_up != NULL)
+ b = (( (currMB->mb_up)->mb_type != I4MB) ? 1 : 0 );
+
+ if (currMB->mb_left != NULL)
+ a = (( (currMB->mb_left)->mb_type != I4MB) ? 1 : 0 );
+
+ act_ctx = a + b;
+ act_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx);
+
+ if (act_sym==0) // 4x4 Intra
+ {
+ curr_mb_type = 1;
+ }
+ else // 16x16 Intra
+ {
+ mode_sym = biari_decode_final(dep_dp);
+ if( mode_sym==1 )
+ {
+ curr_mb_type = 26;
+ }
+ else
+ {
+ 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)
+ {
+ if (currMB->mb_up != NULL)
+ b = (( (currMB->mb_up)->mb_type != 0) ? 1 : 0 );
+
+ if (currMB->mb_left != NULL)
+ a = (( (currMB->mb_left)->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 (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 (biari_decode_symbol(dep_dp, &ctx->mb_type_contexts[1][7] )) act_sym = 7;
+ 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 || (((currSlice->slice_type == B_SLICE) ? 1 : 0) && act_sym<=23))
+ {
+ curr_mb_type = act_sym;
+ }
+ else // additional info for 16x16 Intra-mode
+ {
+ mode_sym = biari_decode_final(dep_dp);
+ if( mode_sym==1 )
+ {
+ if(bframe) // B frame
+ curr_mb_type = 48;
+ else // P frame
+ curr_mb_type = 31;
+ }
+ else
+ {
+ 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;
+ }
+ }
+ }
+ return curr_mb_type;
+}
+
+/*!
+************************************************************************
+* \brief
+* This function is used to arithmetically decode a pair of
+* intra prediction modes of a given MB.
+************************************************************************
+*/
+#if defined(_DEBUG) || !defined(_M_IX86)
+int readIntraPredMode_CABAC(Slice *currSlice, DecodingEnvironmentPtr dep_dp)
+{
+ TextureInfoContexts *ctx = currSlice->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 == 1)
+ {
+ return -1;
+ }
+ else
+ {
+ int pred_mode=0;
+ pred_mode |= (biari_decode_symbol(dep_dp, ctx->ipr_contexts+1) );
+ pred_mode |= (biari_decode_symbol(dep_dp, ctx->ipr_contexts+1) << 1);
+ pred_mode |= (biari_decode_symbol(dep_dp, ctx->ipr_contexts+1) << 2);
+ return pred_mode;
+ }
+}
+#endif
+/*!
+************************************************************************
+* \brief
+* This function is used to arithmetically decode the reference
+* parameter of a given MB.
+************************************************************************
+*/
+char readRefFrame_CABAC(Macroblock *currMB, DecodingEnvironmentPtr dep_dp, int list, int x, int y)
+{
+ Slice *currSlice = currMB->p_Slice;
+ VideoParameters *p_Vid = currMB->p_Vid;
+ StorablePicture *dec_picture = p_Vid->dec_picture;
+ MotionInfoContexts *ctx = currSlice->mot_ctx;
+ Macroblock *neighborMB = NULL;
+
+ int addctx = 0;
+ int a = 0, b = 0;
+ int act_ctx;
+ int act_sym;
+ PicMotion **refframe_array = dec_picture->motion.motion[list];
+
+ PixelPos block_a, block_b;
+
+ p_Vid->getNeighbourPXLuma(currMB, x, y - 1, &block_b);
+ // TODO: this gets called with x << 2 and y << 2, so we can undo the internal >> 2 easily by just passing x and y
+ if (block_b.available)
+ {
+ int b8b=((block_b.x >> 3) & 0x01)+((block_b.y>>2) & 0x02);
+ neighborMB = &p_Vid->mb_data[block_b.mb_addr];
+ if (!( (neighborMB->mb_type==IPCM) || IS_DIRECT(neighborMB) || (neighborMB->b8mode[b8b]==0 && neighborMB->b8pdir[b8b]==2)))
+ {
+ if (currSlice->mb_aff_frame_flag && (currMB->mb_field == FALSE) && (neighborMB->mb_field == TRUE))
+ b = (refframe_array[block_b.pos_y>>2][block_b.pos_x>>2].ref_idx > 1 ? 2 : 0);
+ else
+ b = (refframe_array[block_b.pos_y>>2][block_b.pos_x>>2].ref_idx > 0 ? 2 : 0);
+ }
+ }
+
+ p_Vid->getNeighbourXPLuma(currMB, x - 1, y , &block_a);
+ if (block_a.available)
+ {
+ int b8a=((block_a.x >> 3) & 0x01)+((block_a.y>>2) & 0x02);
+ neighborMB = &p_Vid->mb_data[block_a.mb_addr];
+ if (!((neighborMB->mb_type==IPCM) || IS_DIRECT(neighborMB) || (neighborMB->b8mode[b8a]==0 && neighborMB->b8pdir[b8a]==2)))
+ {
+ if (currSlice->mb_aff_frame_flag && (currMB->mb_field == FALSE) && (neighborMB->mb_field == 1))
+ a = (refframe_array[block_a.pos_y>>2][block_a.pos_x>>2].ref_idx > 1 ? 1 : 0);
+ else
+ a = (refframe_array[block_a.pos_y>>2][block_a.pos_x>>2].ref_idx > 0 ? 1 : 0);
+ }
+ }
+
+ act_ctx = a + b;
+
+ 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;
+ }
+ return act_sym;
+}
+
+// x == 0
+char readRefFrame_CABAC0(Macroblock *currMB, DecodingEnvironmentPtr dep_dp, int list, int y)
+{
+ Slice *currSlice = currMB->p_Slice;
+ VideoParameters *p_Vid = currMB->p_Vid;
+ StorablePicture *dec_picture = p_Vid->dec_picture;
+ MotionInfoContexts *ctx = currSlice->mot_ctx;
+ Macroblock *neighborMB = NULL;
+
+ int addctx = 0;
+ int a = 0, b = 0;
+ int act_ctx;
+ int act_sym;
+ PicMotion **refframe_array = dec_picture->motion.motion[list];
+
+ PixelPos block_a, block_b;
+
+ p_Vid->getNeighbour0XLuma(currMB, y - 1, &block_b);
+ // TODO: this gets called with x << 2 and y << 2, so we can undo the internal >> 2 easily by just passing x and y
+ if (block_b.available)
+ {
+ int b8b=0+((block_b.y>>2) & 0x02);
+ neighborMB = &p_Vid->mb_data[block_b.mb_addr];
+ if (!( (neighborMB->mb_type==IPCM) || IS_DIRECT(neighborMB) || (neighborMB->b8mode[b8b]==0 && neighborMB->b8pdir[b8b]==2)))
+ {
+ if (currSlice->mb_aff_frame_flag && (currMB->mb_field == FALSE) && (neighborMB->mb_field == TRUE))
+ b = (refframe_array[block_b.pos_y>>2][block_b.pos_x>>2].ref_idx > 1 ? 2 : 0);
+ else
+ b = (refframe_array[block_b.pos_y>>2][block_b.pos_x>>2].ref_idx > 0 ? 2 : 0);
+ }
+ }
+
+ p_Vid->getNeighbourNXLuma(currMB, y , &block_a);
+ if (block_a.available)
+ {
+ int b8a=((15 >> 3) & 0x01)+((block_a.y>>2) & 0x02);
+ neighborMB = &p_Vid->mb_data[block_a.mb_addr];
+ if (!((neighborMB->mb_type==IPCM) || IS_DIRECT(neighborMB) || (neighborMB->b8mode[b8a]==0 && neighborMB->b8pdir[b8a]==2)))
+ {
+ if (currSlice->mb_aff_frame_flag && (currMB->mb_field == FALSE) && (neighborMB->mb_field == 1))
+ a = (refframe_array[block_a.pos_y>>2][block_a.pos_x>>2].ref_idx > 1 ? 1 : 0);
+ else
+ a = (refframe_array[block_a.pos_y>>2][block_a.pos_x>>2].ref_idx > 0 ? 1 : 0);
+ }
+ }
+
+ act_ctx = a + b;
+
+ 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;
+ }
+ return act_sym;
+}
+
+
+/*!
+************************************************************************
+* \brief
+* This function is used to arithmetically decode the delta qp
+* of a given MB.
+************************************************************************
+*/
+#if defined(_DEBUG) || !defined(_M_IX86)
+short readDquant_CABAC(Slice *currSlice, DecodingEnvironmentPtr dep_dp)
+{
+ MotionInfoContexts *ctx = currSlice->mot_ctx;
+ short dquant;
+ int act_ctx = ((currSlice->last_dquant != 0) ? 1 : 0);
+ int 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) >> 1;
+ if((act_sym & 0x01)==0) // lsb is signed bit
+ dquant = -dquant;
+
+ currSlice->last_dquant = dquant;
+ return dquant;
+}
+#endif
+/*!
+************************************************************************
+* \brief
+* This function is used to arithmetically decode the coded
+* block pattern of a given MB.
+************************************************************************
+*/
+int readCBP_CABAC(Macroblock *currMB, DecodingEnvironmentPtr dep_dp)
+{
+ VideoParameters *p_Vid = currMB->p_Vid;
+ StorablePicture *dec_picture = p_Vid->dec_picture;
+ Slice *currSlice = currMB->p_Slice;
+ TextureInfoContexts *ctx = currSlice->tex_ctx;
+ Macroblock *neighborMB = NULL;
+
+ int a, b;
+ int curr_cbp_ctx;
+ int cbp = 0;
+ int cbp_bit;
+ PixelPos block_a;
+
+ // coding of luma part (bit by bit)
+ neighborMB = currMB->mb_up;
+ b = 0;
+
+ if (neighborMB != NULL)
+ {
+ if(neighborMB->mb_type!=IPCM)
+ b = (( (neighborMB->cbp & 4) == 0) ? 2 : 0);
+ }
+
+ p_Vid->getNeighbourLeftLuma(currMB, &block_a);
+ if (block_a.available)
+ {
+ if(p_Vid->mb_data[block_a.mb_addr].mb_type==IPCM)
+ a = 0;
+ else
+ a = (( (p_Vid->mb_data[block_a.mb_addr].cbp & (1<<(2*(block_a.y>>3)+1))) == 0) ? 1 : 0);
+ }
+ else
+ a=0;
+
+ curr_cbp_ctx = a + b;
+ cbp_bit = biari_decode_symbol(dep_dp, ctx->cbp_contexts[0] + curr_cbp_ctx );
+ //if (cbp_bit)
+ cbp += cbp_bit;//1;
+
+ if (neighborMB != NULL)
+ {
+ if(neighborMB->mb_type!=IPCM)
+ b = (( (neighborMB->cbp & 8) == 0) ? 2 : 0);
+ }
+
+ a = ( ((cbp & 1) == 0) ? 1: 0);
+
+ curr_cbp_ctx = a + b;
+
+ cbp_bit = biari_decode_symbol(dep_dp, ctx->cbp_contexts[0] + curr_cbp_ctx );
+ //if (cbp_bit)
+ cbp += (cbp_bit << 1); //2;
+
+ b = ( ((cbp & 1) == 0) ? 2: 0);
+
+ p_Vid->getNeighbourNPLumaNB(currMB, 8, &block_a);
+ if (block_a.available)
+ {
+ if(p_Vid->mb_data[block_a.mb_addr].mb_type==IPCM)
+ a = 0;
+ else
+ a = (( (p_Vid->mb_data[block_a.mb_addr].cbp & (1<<(2*(block_a.y>>3)+1))) == 0) ? 1 : 0);
+ }
+ else
+ a=0;
+
+ curr_cbp_ctx = a + b;
+ cbp_bit = biari_decode_symbol(dep_dp, ctx->cbp_contexts[0] + curr_cbp_ctx );
+ //if (cbp_bit)
+ cbp += (cbp_bit << 2); //4;
+
+ b = ( ((cbp & 2) == 0) ? 2: 0);
+ a = ( ((cbp & 4) == 0) ? 1: 0);
+
+ curr_cbp_ctx = a + b;
+ cbp_bit = biari_decode_symbol(dep_dp, ctx->cbp_contexts[0] + curr_cbp_ctx );
+ //if (cbp_bit)
+ cbp += (cbp_bit << 3); //8;
+
+ if ((dec_picture->chroma_format_idc != YUV400) && (dec_picture->chroma_format_idc != YUV444))
+ {
+ // coding of chroma part
+ // CABAC decoding for BinIdx 0
+ b = 0;
+ neighborMB = currMB->mb_up;
+ if (neighborMB != NULL)
+ {
+ if (neighborMB->mb_type==IPCM || (neighborMB->cbp > 15))
+ b = 2;
+ }
+
+ a = 0;
+ neighborMB = currMB->mb_left;
+ if (neighborMB != NULL)
+ {
+ if (neighborMB->mb_type==IPCM || (neighborMB->cbp > 15))
+ a = 1;
+ }
+
+ curr_cbp_ctx = a + b;
+ cbp_bit = biari_decode_symbol(dep_dp, ctx->cbp_contexts[1] + curr_cbp_ctx );
+
+ // CABAC decoding for BinIdx 1
+ if (cbp_bit) // set the chroma bits
+ {
+ b = 0;
+ neighborMB = currMB->mb_up;
+ if (neighborMB != NULL)
+ {
+ //if ((neighborMB->mb_type == IPCM) || ((neighborMB->cbp > 15) && ((neighborMB->cbp >> 4) == 2)))
+ if ((neighborMB->mb_type == IPCM) || ((neighborMB->cbp >> 4) == 2))
+ b = 2;
+ }
+
+
+ a = 0;
+ neighborMB = currMB->mb_left;
+ if (neighborMB != NULL)
+ {
+ if ((neighborMB->mb_type == IPCM) || ((neighborMB->cbp >> 4) == 2))
+ a = 1;
+ }
+
+ curr_cbp_ctx = a + b;
+ cbp_bit = biari_decode_symbol(dep_dp, ctx->cbp_contexts[2] + curr_cbp_ctx );
+ cbp += (16 << cbp_bit); // ? 32 : 16;
+ }
+ }
+
+
+ if (!cbp)
+ {
+ currSlice->last_dquant = 0;
+ }
+
+ return cbp;
+}
+
+/*!
+************************************************************************
+* \brief
+* This function is used to arithmetically decode the chroma
+* intra prediction mode of a given MB.
+************************************************************************
+*/
+char readCIPredMode_CABAC(Macroblock *currMB,
+ DecodingEnvironmentPtr dep_dp)
+{
+ Slice *currSlice = currMB->p_Slice;
+ TextureInfoContexts *ctx = currSlice->tex_ctx;
+ int act_sym;
+
+ Macroblock *MbUp = currMB->mb_up;
+ Macroblock *MbLeft = currMB->mb_left;
+
+ int b = (MbUp != NULL) ? (((MbUp->c_ipred_mode != 0) && (MbUp->mb_type != IPCM)) ? 1 : 0) : 0;
+ int a = (MbLeft != NULL) ? (((MbLeft->c_ipred_mode != 0) && (MbLeft->mb_type != IPCM)) ? 1 : 0) : 0;
+ int 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, 1) + 1;
+ return act_sym;
+
+}
+
+static const byte maxpos [] = {15, 14, 63, 31, 31, 15, 3, 14, 7, 15, 15, 14, 63, 31, 31, 15, 15, 14, 63, 31, 31, 15};
+static const byte c1isdc [] = { 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1};
+static const byte type2ctx_bcbp[] = { 0, 1, 2, 3, 3, 4, 5, 6, 5, 5, 10, 11, 12, 13, 13, 14, 16, 17, 18, 19, 19, 20};
+static const byte type2ctx_map [] = { 0, 1, 2, 3, 4, 5, 6, 7, 6, 6, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21}; // 8
+static const byte type2ctx_last[] = { 0, 1, 2, 3, 4, 5, 6, 7, 6, 6, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21}; // 8
+static const byte type2ctx_one [] = { 0, 1, 2, 3, 3, 4, 5, 6, 5, 5, 10, 11, 12, 13, 13, 14, 16, 17, 18, 19, 19, 20}; // 7
+static const byte type2ctx_abs [] = { 0, 1, 2, 3, 3, 4, 5, 6, 5, 5, 10, 11, 12, 13, 13, 14, 16, 17, 18, 19, 19, 20}; // 7
+static const byte max_c2 [] = { 4, 4, 4, 4, 4, 4, 3, 4, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}; // 9
+
+
+
+/*!
+************************************************************************
+* \brief
+* Read CBP4-BIT
+************************************************************************
+*/
+static int read_and_store_CBP_block_bit_444(Macroblock *currMB, DecodingEnvironmentPtr dep_dp, int type)
+{
+ Slice *currSlice = currMB->p_Slice;
+ VideoParameters *p_Vid = currMB->p_Vid;
+ StorablePicture *dec_picture = p_Vid->dec_picture;
+ TextureInfoContexts *tex_ctx = currSlice->tex_ctx;
+
+ int y_ac = (type==LUMA_16AC || type==LUMA_8x8 || type==LUMA_8x4 || type==LUMA_4x8 || type==LUMA_4x4
+ || type==CB_16AC || type==CB_8x8 || type==CB_8x4 || type==CB_4x8 || type==CB_4x4
+ || type==CR_16AC || type==CR_8x8 || type==CR_8x4 || type==CR_4x8 || type==CR_4x4);
+ int y_dc = (type==LUMA_16DC || type==CB_16DC || type==CR_16DC);
+ int u_ac = (type==CHROMA_AC && !currMB->is_v_block);
+ int v_ac = (type==CHROMA_AC && currMB->is_v_block);
+ int chroma_dc = (type==CHROMA_DC || type==CHROMA_DC_2x4 || type==CHROMA_DC_4x4);
+ int u_dc = (chroma_dc && !currMB->is_v_block);
+ int v_dc = (chroma_dc && currMB->is_v_block);
+ int j = (y_ac || u_ac || v_ac ? currMB->subblock_y : 0);
+ int i = (y_ac || u_ac || v_ac ? currMB->subblock_x : 0);
+ int bit = (y_dc ? 0 : y_ac ? 1 : u_dc ? 17 : v_dc ? 18 : u_ac ? 19 : 35);
+ int default_bit = (currMB->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;
+ int bit_pos_a = 0;
+ int bit_pos_b = 0;
+
+ PixelPos block_a, block_b;
+ if (y_ac)
+ {
+ get4x4NeighbourLuma(currMB, i - 1, j , &block_a);
+ get4x4NeighbourLuma(currMB, i , j - 1, &block_b);
+ if (block_a.available)
+ bit_pos_a = 4*block_a.y + block_a.x;
+ if (block_b.available)
+ bit_pos_b = 4*block_b.y + block_b.x;
+ }
+ else if (y_dc)
+ {
+ get4x4NeighbourLuma(currMB, i - 1, j , &block_a);
+ get4x4NeighbourLuma(currMB, i , j - 1, &block_b);
+ }
+ else if (u_ac||v_ac)
+ {
+ get4x4Neighbour(currMB, i - 1, j , p_Vid->mb_size[IS_CHROMA], &block_a);
+ get4x4Neighbour(currMB, i , j - 1, p_Vid->mb_size[IS_CHROMA], &block_b);
+ if (block_a.available)
+ bit_pos_a = 4*block_a.y + block_a.x;
+ if (block_b.available)
+ bit_pos_b = 4*block_b.y + block_b.x;
+ }
+ else
+ {
+ get4x4Neighbour(currMB, i - 1, j , p_Vid->mb_size[IS_CHROMA], &block_a);
+ get4x4Neighbour(currMB, i , j - 1, p_Vid->mb_size[IS_CHROMA], &block_b);
+ }
+
+ if (dec_picture->chroma_format_idc!=YUV444)
+ {
+ if (type!=LUMA_8x8)
+ {
+ //--- get bits from neighboring blocks ---
+ if (block_b.available)
+ {
+ if(p_Vid->mb_data[block_b.mb_addr].mb_type==IPCM)
+ upper_bit=1;
+ else
+ upper_bit = get_bit(p_Vid->mb_data[block_b.mb_addr].cbp_bits[0], bit + bit_pos_b);
+ }
+
+ if (block_a.available)
+ {
+ if(p_Vid->mb_data[block_a.mb_addr].mb_type==IPCM)
+ left_bit=1;
+ else
+ left_bit = get_bit(p_Vid->mb_data[block_a.mb_addr].cbp_bits[0],bit + bit_pos_a);
+ }
+
+
+ ctx = 2 * upper_bit + left_bit;
+ //===== encode symbol =====
+ cbp_bit = biari_decode_symbol (dep_dp, tex_ctx->bcbp_contexts[type2ctx_bcbp[type]] + ctx);
+ }
+ }
+ else if( IS_INDEPENDENT(p_Vid) )
+ {
+ if (type!=LUMA_8x8)
+ {
+ //--- get bits from neighbouring blocks ---
+ if (block_b.available)
+ {
+ if(p_Vid->mb_data[block_b.mb_addr].mb_type==IPCM)
+ upper_bit = 1;
+ else
+ upper_bit = get_bit(p_Vid->mb_data[block_b.mb_addr].cbp_bits[0],bit+bit_pos_b);
+ }
+
+
+ if (block_a.available)
+ {
+ if(p_Vid->mb_data[block_a.mb_addr].mb_type==IPCM)
+ left_bit = 1;
+ else
+ left_bit = get_bit(p_Vid->mb_data[block_a.mb_addr].cbp_bits[0],bit+bit_pos_a);
+ }
+
+
+ ctx = 2 * upper_bit + left_bit;
+ //===== encode symbol =====
+ cbp_bit = biari_decode_symbol (dep_dp, tex_ctx->bcbp_contexts[type2ctx_bcbp[type]] + ctx);
+ }
+ }
+ else {
+ if (block_b.available)
+ {
+ if(p_Vid->mb_data[block_b.mb_addr].mb_type==IPCM)
+ upper_bit=1;
+ else
+ {
+ if(type==LUMA_8x8)
+ upper_bit = get_bit(p_Vid->mb_data[block_b.mb_addr].cbp_bits_8x8[0], bit + bit_pos_b);
+ else if (type==CB_8x8)
+ upper_bit = get_bit(p_Vid->mb_data[block_b.mb_addr].cbp_bits_8x8[1], bit + bit_pos_b);
+ else if (type==CR_8x8)
+ upper_bit = get_bit(p_Vid->mb_data[block_b.mb_addr].cbp_bits_8x8[2], bit + bit_pos_b);
+ else if ((type==CB_4x4)||(type==CB_4x8)||(type==CB_8x4)||(type==CB_16AC)||(type==CB_16DC))
+ upper_bit = get_bit(p_Vid->mb_data[block_b.mb_addr].cbp_bits[1],bit+bit_pos_b);
+ else if ((type==CR_4x4)||(type==CR_4x8)||(type==CR_8x4)||(type==CR_16AC)||(type==CR_16DC))
+ upper_bit = get_bit(p_Vid->mb_data[block_b.mb_addr].cbp_bits[2],bit+bit_pos_b);
+ else
+ upper_bit = get_bit(p_Vid->mb_data[block_b.mb_addr].cbp_bits[0],bit+bit_pos_b);
+ }
+ }
+
+
+ if (block_a.available)
+ {
+ if(p_Vid->mb_data[block_a.mb_addr].mb_type==IPCM)
+ left_bit=1;
+ else
+ {
+ if(type==LUMA_8x8)
+ left_bit = get_bit(p_Vid->mb_data[block_a.mb_addr].cbp_bits_8x8[0],bit+bit_pos_a);
+ else if (type==CB_8x8)
+ left_bit = get_bit(p_Vid->mb_data[block_a.mb_addr].cbp_bits_8x8[1],bit+bit_pos_a);
+ else if (type==CR_8x8)
+ left_bit = get_bit(p_Vid->mb_data[block_a.mb_addr].cbp_bits_8x8[2],bit+bit_pos_a);
+ else if ((type==CB_4x4)||(type==CB_4x8)||(type==CB_8x4)||(type==CB_16AC)||(type==CB_16DC))
+ left_bit = get_bit(p_Vid->mb_data[block_a.mb_addr].cbp_bits[1],bit+bit_pos_a);
+ else if ((type==CR_4x4)||(type==CR_4x8)||(type==CR_8x4)||(type==CR_16AC)||(type==CR_16DC))
+ left_bit = get_bit(p_Vid->mb_data[block_a.mb_addr].cbp_bits[2],bit+bit_pos_a);
+ else
+ left_bit = get_bit(p_Vid->mb_data[block_a.mb_addr].cbp_bits[0],bit+bit_pos_a);
+ }
+ }
+
+ ctx = 2 * upper_bit + left_bit;
+ //===== encode symbol =====
+ cbp_bit = biari_decode_symbol (dep_dp, tex_ctx->bcbp_contexts[type2ctx_bcbp[type]] + ctx);
+ }
+
+ //--- set bits for current block ---
+ bit = (y_dc ? 0 : y_ac ? 1 + j + (i >> 2) : u_dc ? 17 : v_dc ? 18 : u_ac ? 19 + j + (i >> 2) : 35 + j + (i >> 2));
+
+ if (cbp_bit)
+ {
+ if (type==LUMA_8x8)
+ {
+ currMB->cbp_bits[0] |= ((int64) 0x33 << bit );
+
+ if (dec_picture->chroma_format_idc==YUV444)
+ {
+ currMB->cbp_bits_8x8[0] |= ((int64) 0x33 << bit );
+ }
+ }
+ else if (type==CB_8x8)
+ {
+ currMB->cbp_bits_8x8[1] |= ((int64) 0x33 << bit );
+ currMB->cbp_bits[1] |= ((int64) 0x33 << bit );
+ }
+ else if (type==CR_8x8)
+ {
+ currMB->cbp_bits_8x8[2] |= ((int64) 0x33 << bit );
+ currMB->cbp_bits[2] |= ((int64) 0x33 << bit );
+ }
+ else if (type==LUMA_8x4)
+ {
+ currMB->cbp_bits[0] |= ((int64) 0x03 << bit );
+ }
+ else if (type==CB_8x4)
+ {
+ currMB->cbp_bits[1] |= ((int64) 0x03 << bit );
+ }
+ else if (type==CR_8x4)
+ {
+ currMB->cbp_bits[2] |= ((int64) 0x03 << bit );
+ }
+ else if (type==LUMA_4x8)
+ {
+ currMB->cbp_bits[0] |= ((int64) 0x11<< bit );
+ }
+ else if (type==CB_4x8)
+ {
+ currMB->cbp_bits[1] |= ((int64)0x11<< bit );
+ }
+ else if (type==CR_4x8)
+ {
+ currMB->cbp_bits[2] |= ((int64)0x11<< bit );
+ }
+ else if ((type==CB_4x4)||(type==CB_16AC)||(type==CB_16DC))
+ {
+ currMB->cbp_bits[1] |= ((int64)0x01<<bit);
+ }
+ else if ((type==CR_4x4)||(type==CR_16AC)||(type==CR_16DC))
+ {
+ currMB->cbp_bits[2] |= ((int64)0x01<<bit);
+ }
+ else
+ {
+ currMB->cbp_bits[0] |= ((int64)0x01<<bit);
+ }
+ }
+ return cbp_bit;
+}
+
+
+
+/*!
+************************************************************************
+* \brief
+* Read CBP4-BIT
+************************************************************************
+*/
+static int read_and_store_CBP_block_bit_normal(Macroblock *currMB, DecodingEnvironmentPtr dep_dp, int type)
+{
+ Slice *currSlice = currMB->p_Slice;
+ VideoParameters *p_Vid = currMB->p_Vid;
+ TextureInfoContexts *tex_ctx = currSlice->tex_ctx;
+ int cbp_bit = 1; // always one for 8x8 mode
+
+ if (type==LUMA_16DC)
+ {
+
+ int upper_bit = 1;
+ int left_bit = 1;
+ int ctx;
+
+ PixelPos block_a, block_b;
+
+ //--- get bits from neighboring blocks ---
+ p_Vid->getNeighbour0X(currMB, -1, p_Vid->mb_size[IS_LUMA], &block_b);
+ if (block_b.available)
+ {
+ if(p_Vid->mb_data[block_b.mb_addr].mb_type==IPCM)
+ upper_bit=1;
+ else
+ upper_bit = (int)p_Vid->mb_data[block_b.mb_addr].cbp_bits[0]&1;
+ }
+
+ p_Vid->getNeighbourX0(currMB, -1, p_Vid->mb_size[IS_LUMA], &block_a);
+ if (block_a.available)
+ {
+ if(p_Vid->mb_data[block_a.mb_addr].mb_type==IPCM)
+ left_bit=1;
+ else
+ left_bit = (int)p_Vid->mb_data[block_a.mb_addr].cbp_bits[0]&1;
+ }
+
+ ctx = 2 * upper_bit + left_bit;
+ //===== encode symbol =====
+ cbp_bit = biari_decode_symbol (dep_dp, tex_ctx->bcbp_contexts[type2ctx_bcbp[LUMA_16DC]] + ctx);
+
+ //--- set bits for current block ---
+
+ if (cbp_bit)
+ {
+ currMB->cbp_bits[0] |= 0x01;
+ }
+ }
+ else if (type == LUMA_8x8)
+ {
+ int j = currMB->subblock_y;
+ int i = currMB->subblock_x;
+
+ //--- set bits for current block ---
+ int bit = 1 + j + (i >> 2);
+
+ or_bits(&currMB->cbp_bits[0], 0x33, bit);
+ }
+ else if (type <= LUMA_4x4) // type==LUMA_16AC || type==LUMA_8x4 || type==LUMA_4x8 || type==LUMA_4x4)
+ {
+ int j = currMB->subblock_y;
+ int i = currMB->subblock_x;
+ int bit;
+ int default_bit = (currMB->is_intra_block ? 1 : 0);
+ int upper_bit = default_bit;
+ int left_bit = default_bit;
+ int ctx;
+
+ //--- get bits from neighboring blocks ---
+ PixelPos block_a, block_b;
+ p_Vid->getNeighbourPXLumaNB_NoPos(currMB, j-1, &block_b);
+ if (block_b.available)
+ {
+ int bit_pos_b = (block_b.y&((short)~3)) + (i>>2);
+ if(p_Vid->mb_data[block_b.mb_addr].mb_type==IPCM)
+ upper_bit=1;
+ else
+ upper_bit = get_bit(p_Vid->mb_data[block_b.mb_addr].cbp_bits[0], 1 + bit_pos_b);
+ }
+
+ p_Vid->getNeighbourXPLumaNB_NoPos(currMB, i-1, j, &block_a);
+ if (block_a.available)
+ {
+ int bit_pos_a = (block_a.y&((short)~3)) + (block_a.x>>2);
+ if(p_Vid->mb_data[block_a.mb_addr].mb_type==IPCM)
+ left_bit=1;
+ else
+ left_bit = get_bit(p_Vid->mb_data[block_a.mb_addr].cbp_bits[0],1 + bit_pos_a);
+ }
+
+ ctx = 2 * upper_bit + left_bit;
+ //===== encode symbol =====
+ cbp_bit = biari_decode_symbol (dep_dp, tex_ctx->bcbp_contexts[type2ctx_bcbp[type]] + ctx);
+
+
+ //--- set bits for current block ---
+ bit = 1 + j + (i >> 2);
+
+ if (cbp_bit)
+ {
+ if (type==LUMA_8x4)
+ {
+ or_bits_low(&currMB->cbp_bits[0], 0x03, bit);
+ }
+ else if (type==LUMA_4x8)
+ {
+ or_bits_low(&currMB->cbp_bits[0], 0x011, bit);
+ }
+ else
+ {
+ or_bits_low(&currMB->cbp_bits[0], 0x01, bit);
+ }
+ }
+ }
+ else if (type == CHROMA_AC)
+ {
+ int u_ac = !currMB->is_v_block;
+
+ int default_bit = (currMB->is_intra_block ? 1 : 0);
+ int upper_bit = default_bit;
+ int left_bit = default_bit;
+ int ctx;
+
+ PixelPos block_a, block_b;
+
+ int j = currMB->subblock_y;
+ int i = currMB->subblock_x;
+ int bit = (u_ac ? 19 : 35);
+
+ p_Vid->getNeighbourXP_NoPos(currMB, i - 1, j , p_Vid->mb_size[IS_CHROMA], &block_a);
+ p_Vid->getNeighbourPX_NoPos(currMB, i , j - 1, p_Vid->mb_size[IS_CHROMA], &block_b);
+
+ //--- get bits from neighboring blocks ---
+ if (block_b.available)
+ {
+ if(p_Vid->mb_data[block_b.mb_addr].mb_type==IPCM)
+ upper_bit=1;
+ else
+ upper_bit = get_bit(p_Vid->mb_data[block_b.mb_addr].cbp_bits[0], bit + (block_b.y&((short)~3)) + (block_b.x>>2));
+ }
+
+ if (block_a.available)
+ {
+ if(p_Vid->mb_data[block_a.mb_addr].mb_type==IPCM)
+ left_bit=1;
+ else
+ left_bit = get_bit(p_Vid->mb_data[block_a.mb_addr].cbp_bits[0],bit + (block_a.y&((short)~3)) + (block_a.x>>2));
+ }
+
+ ctx = 2 * upper_bit + left_bit;
+ //===== encode symbol =====
+ cbp_bit = biari_decode_symbol (dep_dp, tex_ctx->bcbp_contexts[type2ctx_bcbp[CHROMA_AC]] + ctx);
+
+
+ //--- set bits for current block ---
+ if (cbp_bit)
+ {
+ or_bits(&currMB->cbp_bits[0], 0x01, bit + j + (i >> 2));
+ }
+
+ }
+ else if (type <= CHROMA_DC_4x4)
+ {
+ int v_dc = currMB->is_v_block;
+ int default_bit = (currMB->is_intra_block ? 1 : 0);
+ int upper_bit = default_bit;
+ int left_bit = default_bit;
+ int ctx;
+
+
+ PixelPos block_a, block_b;
+
+ int bit = (v_dc ? 18 : 17);
+ p_Vid->getNeighbourLeft(currMB, p_Vid->mb_size[IS_CHROMA], &block_a);
+ p_Vid->getNeighbourUp(currMB, p_Vid->mb_size[IS_CHROMA], &block_b);
+ //--- get bits from neighboring blocks ---
+ if (block_b.available)
+ {
+ if(p_Vid->mb_data[block_b.mb_addr].mb_type==IPCM)
+ upper_bit=1;
+ else
+ upper_bit = get_bit(p_Vid->mb_data[block_b.mb_addr].cbp_bits[0], bit);
+ }
+
+ if (block_a.available)
+ {
+ if(p_Vid->mb_data[block_a.mb_addr].mb_type==IPCM)
+ left_bit=1;
+ else
+ left_bit = get_bit(p_Vid->mb_data[block_a.mb_addr].cbp_bits[0],bit);
+ }
+
+ ctx = 2 * upper_bit + left_bit;
+ //===== encode symbol =====
+ cbp_bit = biari_decode_symbol (dep_dp, tex_ctx->bcbp_contexts[type2ctx_bcbp[type]] + ctx);
+
+
+ //--- set bits for current block ---
+ if (cbp_bit)
+ {
+ or_bits(&currMB->cbp_bits[0], 0x01, bit);
+ }
+
+
+ }
+ else
+ {
+ int default_bit = (currMB->is_intra_block ? 1 : 0);
+ int upper_bit = default_bit;
+ int left_bit = default_bit;
+ int ctx;
+
+
+ PixelPos block_a, block_b;
+
+ p_Vid->getNeighbourLeft(currMB, p_Vid->mb_size[IS_CHROMA], &block_a);
+ p_Vid->getNeighbourUp(currMB, p_Vid->mb_size[IS_CHROMA], &block_b);
+ //--- get bits from neighboring blocks ---
+ if (block_b.available)
+ {
+ if(p_Vid->mb_data[block_b.mb_addr].mb_type==IPCM)
+ upper_bit=1;
+ else
+ upper_bit = get_bit(p_Vid->mb_data[block_b.mb_addr].cbp_bits[0], 35);
+ }
+
+ if (block_a.available)
+ {
+ if(p_Vid->mb_data[block_a.mb_addr].mb_type==IPCM)
+ left_bit=1;
+ else
+ left_bit = get_bit(p_Vid->mb_data[block_a.mb_addr].cbp_bits[0],35);
+ }
+
+ ctx = 2 * upper_bit + left_bit;
+ //===== encode symbol =====
+ cbp_bit = biari_decode_symbol (dep_dp, tex_ctx->bcbp_contexts[type2ctx_bcbp[type]] + ctx);
+
+
+ //--- set bits for current block ---
+ if (cbp_bit)
+ {
+ or_bits(&currMB->cbp_bits[0], 0x01, 35);
+ }
+
+
+ }
+ return cbp_bit;
+}
+
+
+void set_read_and_store_CBP(Macroblock **currMB, int chroma_format_idc)
+{
+ if (chroma_format_idc == YUV444)
+ (*currMB)->read_and_store_CBP_block_bit = read_and_store_CBP_block_bit_444;
+ else
+ (*currMB)->read_and_store_CBP_block_bit = read_and_store_CBP_block_bit_normal;
+}
+
+
+
+
+
+//===== position -> ctx for MAP =====
+//--- zig-zag scan ----
+static const byte 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 byte 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 byte pos2ctx_map4x4 [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14}; // 15 CTX
+static const byte pos2ctx_map2x4c[] = { 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; // 15 CTX
+static const byte pos2ctx_map4x4c[] = { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2}; // 15 CTX
+static const byte* pos2ctx_map [] = {pos2ctx_map4x4, pos2ctx_map4x4, pos2ctx_map8x8, pos2ctx_map8x4,
+pos2ctx_map8x4, pos2ctx_map4x4, pos2ctx_map4x4, pos2ctx_map4x4,
+pos2ctx_map2x4c, pos2ctx_map4x4c,
+pos2ctx_map4x4, pos2ctx_map4x4, pos2ctx_map8x8,pos2ctx_map8x4,
+pos2ctx_map8x4, pos2ctx_map4x4,
+pos2ctx_map4x4, pos2ctx_map4x4, pos2ctx_map8x8,pos2ctx_map8x4,
+pos2ctx_map8x4,pos2ctx_map4x4};
+//--- interlace scan ----
+//taken from ABT
+static const byte 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 byte 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 byte 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 byte* pos2ctx_map_int[] = {pos2ctx_map4x4, pos2ctx_map4x4, pos2ctx_map8x8i,pos2ctx_map8x4i,
+pos2ctx_map4x8i,pos2ctx_map4x4, pos2ctx_map4x4, pos2ctx_map4x4,
+pos2ctx_map2x4c, pos2ctx_map4x4c,
+pos2ctx_map4x4, pos2ctx_map4x4, pos2ctx_map8x8i,pos2ctx_map8x4i,
+pos2ctx_map8x4i,pos2ctx_map4x4,
+pos2ctx_map4x4, pos2ctx_map4x4, pos2ctx_map8x8i,pos2ctx_map8x4i,
+pos2ctx_map8x4i,pos2ctx_map4x4};
+
+//===== position -> ctx for LAST =====
+static const byte 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 byte 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 byte pos2ctx_last4x4 [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; // 15 CTX
+static const byte pos2ctx_last2x4c[] = { 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; // 15 CTX
+static const byte pos2ctx_last4x4c[] = { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2}; // 15 CTX
+static const byte* pos2ctx_last [] = {pos2ctx_last4x4, pos2ctx_last4x4, pos2ctx_last8x8, pos2ctx_last8x4,
+pos2ctx_last8x4, pos2ctx_last4x4, pos2ctx_last4x4, pos2ctx_last4x4,
+pos2ctx_last2x4c, pos2ctx_last4x4c,
+pos2ctx_last4x4, pos2ctx_last4x4, pos2ctx_last8x8,pos2ctx_last8x4,
+pos2ctx_last8x4, pos2ctx_last4x4,
+pos2ctx_last4x4, pos2ctx_last4x4, pos2ctx_last8x8,pos2ctx_last8x4,
+pos2ctx_last8x4, pos2ctx_last4x4};
+
+
+
+/*!
+************************************************************************
+* \brief
+* Read Significance MAP
+************************************************************************
+*/
+
+#if defined(_DEBUG) || defined(_M_X64)
+static int read_significance_map(TextureInfoContexts *tex_ctx, const Macroblock *currMB, DecodingEnvironmentPtr dep_dp, int type, int16_t coeff[])
+{
+ int i;
+ int coeff_ctr = 0;
+ int i0 = 0;
+ int i1 = maxpos[type];
+ const VideoParameters *p_Vid = currMB->p_Vid;
+
+ int fld = ( p_Vid->structure!=FRAME || currMB->mb_field );
+ const byte *pos2ctx_Map = (fld) ? pos2ctx_map_int[type] : pos2ctx_map[type];
+ const byte *last = pos2ctx_last[type];
+
+ BiContextTypePtr map_ctx = tex_ctx->map_contexts[fld][type2ctx_map [type]];
+ BiContextTypePtr last_ctx = tex_ctx->last_contexts[fld][type2ctx_last[type]];
+
+ if (!c1isdc[type])
+ {
+ pos2ctx_Map++;
+ last++;
+ }
+
+ for (i=0; i < i1; ++i) // if last coeff is reached, it has to be significant
+ {
+ //--- read significance symbol ---
+ if (biari_decode_symbol (dep_dp, map_ctx + pos2ctx_Map[i]))
+ {
+ coeff[i] = 1;
+ ++coeff_ctr;
+ //--- read last coefficient symbol ---
+ if (biari_decode_symbol (dep_dp, last_ctx + last[i]))
+ {
+ while (i++ < i1)
+ {
+ coeff[i] = 0;
+ }
+ return coeff_ctr;
+ //memset(&coeff[i + 1], 0, (i1 - i) * sizeof(int));
+ //i = i1;
+ }
+ }
+ else
+ {
+ coeff[i] = 0;
+ }
+ }
+ //--- last coefficient must be significant if no last symbol was received ---
+ coeff[i] = 1;
+
+
+ return coeff_ctr+1;
+}
+#endif
+/*!
+************************************************************************
+* \brief
+* Read Levels
+************************************************************************
+*/
+#if defined(_DEBUG) || defined(_M_X64)
+/*!
+************************************************************************
+* \brief
+* Exp-Golomb decoding for LEVELS
+***********************************************************************
+*/
+unsigned int exp_golomb_decode_eq_prob( DecodingEnvironmentPtr dep_dp, int k);
+static unsigned int unary_exp_golomb_level_decode( DecodingEnvironmentPtr dep_dp,
+ BiContextTypePtr ctx)
+{
+ unsigned int symbol = biari_decode_symbol(dep_dp, ctx );
+
+ if (symbol==0)
+ return 0;
+ else
+ {
+ const unsigned int exp_start = 13;
+
+ for (symbol=0;symbol<(exp_start-1);symbol++)
+ {
+ if (!biari_decode_symbol(dep_dp, ctx))
+ return symbol;
+ }
+ return exp_golomb_decode_eq_prob(dep_dp,0)+13;
+ }
+}
+
+static void read_significant_coefficients (TextureInfoContexts *tex_ctx,
+ DecodingEnvironmentPtr dep_dp,
+ int type,
+ int16_t coeff[])
+{
+ static const int plus_one_clip4[5] = { 1, 2, 3, 4, 4 };
+ static const int plus_one_clip3[4] = { 1, 2, 3, 3 };
+ const int *c2_clip = (max_c2[type]==4)?plus_one_clip4:plus_one_clip3;
+ int i;
+ int c1 = 1;
+ int c2 = 0;
+ BiContextType *one_contexts = tex_ctx->one_contexts[type2ctx_one[type]];
+ BiContextType *abs_contexts = tex_ctx->abs_contexts[type2ctx_abs[type]];
+
+ for (i=maxpos[type]; i>=0; i--)
+ {
+ if (coeff[i]!=0)
+ {
+ coeff[i] += biari_decode_symbol (dep_dp, one_contexts + c1);
+ if (coeff[i]==2)
+ {
+ coeff[i] += unary_exp_golomb_level_decode (dep_dp, abs_contexts + c2);
+ c2 = c2_clip[c2];
+ c1=0;
+ }
+ else if (c1)
+ {
+ c1 = plus_one_clip4[c1];
+ }
+ if (biari_decode_symbol_eq_prob(dep_dp))
+ {
+ coeff[i] *= -1;
+ }
+ }
+ }
+}
+#else
+void read_significant_coefficients (TextureInfoContexts *tex_ctx,
+ DecodingEnvironmentPtr dep_dp,
+ int type,
+ int coeff[]);
+#endif
+
+/*!
+************************************************************************
+* \brief
+* Read Block-Transform Coefficients
+************************************************************************
+*/
+#if defined(_DEBUG) || defined(_M_X64)
+RunLevel readRunLevel_CABAC(Macroblock *currMB, DecodingEnvironmentPtr dep_dp, int context)
+{
+ RunLevel rl;
+ Slice *currSlice = currMB->p_Slice;
+ //--- read coefficients for whole block ---
+ if (currSlice->coeff_ctr < 0)
+ {
+ //===== decode CBP-BIT =====
+ if ((currSlice->coeff_ctr = currMB->read_and_store_CBP_block_bit (currMB, dep_dp, context) )!=0)
+ {
+ //===== decode significance map =====
+ currSlice->coeff_ctr = read_significance_map (currSlice->tex_ctx, currMB, dep_dp, context, currSlice->coeff);
+
+ //===== decode significant coefficients =====
+ read_significant_coefficients (currSlice->tex_ctx, dep_dp, context, currSlice->coeff);
+ }
+ }
+
+ //--- set run and level ---
+
+ rl.run=0;
+ if (currSlice->coeff_ctr--)
+ {
+ //--- set run and level (coefficient) ---
+ for (; currSlice->coeff[currSlice->pos] == 0; ++currSlice->pos, ++rl.run);
+ rl.level = currSlice->coeff[currSlice->pos++];
+ //--- decrement coefficient counter and re-set position ---
+ if (currSlice->coeff_ctr == 0)
+ currSlice->pos = 0;
+ return rl;
+ }
+ else
+ {
+ //--- set run and level (EOB) ---
+ currSlice->pos = 0;
+ rl.level = 0;
+ return rl;
+ }
+}
+#endif
+/*!
+************************************************************************
+* \brief
+* arideco_bits_read
+************************************************************************
+*/
+static int arideco_bits_read(const DecodingEnvironmentPtr dep)
+{
+ int tmp = ((*dep->Dcodestrm_len) << 3) - dep->DbitsLeft;
+
+#if (2==TRACE)
+ fprintf(p_trace, "tmp: %d\n", tmp);
+#endif
+ return tmp;
+}
+
+/*!
+************************************************************************
+* \brief
+* decoding of unary binarization using one or 2 distinct
+* models for the first and all remaining bins; no terminating
+* "0" for max_symbol
+***********************************************************************
+*/
+static unsigned int unary_bin_max_decode(DecodingEnvironmentPtr dep_dp,
+ BiContextTypePtr ctx,
+ int ctx_offset,
+ unsigned int max_symbol)
+{
+ unsigned int symbol = biari_decode_symbol(dep_dp, ctx );
+
+ if (symbol==0 || (max_symbol == 0))
+ return symbol;
+ else
+ {
+ unsigned int l;
+ ctx += ctx_offset;
+ symbol = 0;
+ do
+ {
+ l = biari_decode_symbol(dep_dp, ctx);
+ ++symbol;
+ }
+ while( (l != 0) && (symbol < max_symbol) );
+
+ if ((l != 0) && (symbol == max_symbol))
+ ++symbol;
+ return symbol;
+ }
+}
+
+
+/*!
+************************************************************************
+* \brief
+* decoding of unary binarization using one or 2 distinct
+* models for the first and all remaining bins
+***********************************************************************
+*/
+static unsigned int unary_bin_decode(DecodingEnvironmentPtr dep_dp,
+ BiContextTypePtr ctx,
+ int ctx_offset)
+{
+ unsigned int symbol = biari_decode_symbol(dep_dp, ctx );
+
+ if (symbol == 0)
+ return 0;
+ else
+ {
+ unsigned int l;
+ ctx += ctx_offset;;
+ symbol = 0;
+ do
+ {
+ l=biari_decode_symbol(dep_dp, ctx);
+ ++symbol;
+ }
+ while( l != 0 );
+ return symbol;
+ }
+}
+
+
+/*!
+************************************************************************
+* \brief
+* finding end of a slice in case this is not the end of a frame
+*
+* Unsure whether the "correction" below actually solves an off-by-one
+* problem or whether it introduces one in some cases :-( Anyway,
+* with this change the bit stream format works with CABAC again.
+* StW, 8.7.02
+************************************************************************
+*/
+int cabac_startcode_follows(Slice *currSlice, int eos_bit)
+{
+ unsigned int bit;
+
+ if( eos_bit )
+ {
+ const byte *partMap = assignSE2partition[currSlice->dp_mode];
+ DataPartition *dP = &(currSlice->partArr[partMap[SE_MBTYPE]]);
+ DecodingEnvironmentPtr dep_dp = &(dP->de_cabac);
+
+ bit = biari_decode_final (dep_dp); //GB
+
+#if TRACE
+ fprintf(p_trace, "@%-6d %-63s (%3d)\n",symbolCount++, "end_of_slice_flag", bit);
+ fflush(p_trace);
+#endif
+ }
+ else
+ {
+ bit = 0;
+ }
+
+ return bit;
+}
+
+/*!
+************************************************************************
+* \brief
+* Exp Golomb binarization and decoding of a symbol
+* with prob. of 0.5r
+************************************************************************
+*/
+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) // always returns 1 or zero
+ {
+ symbol += (l<<k); // l is guaranteed to be one
+ ++k;
+ }
+ }
+ while (l!=0);
+
+ while (k--) //next binary part
+ if (biari_decode_symbol_eq_prob(dep_dp)==1)
+ binary_symbol |= (1<<k);
+
+ return (unsigned int) (symbol + binary_symbol);
+}
+
+/*!
+************************************************************************
+* \brief
+* Exp-Golomb decoding for Motion Vectors
+***********************************************************************
+*/
+#if defined(_DEBUG) || defined(_M_X64)
+unsigned int unary_exp_golomb_mv_decode(DecodingEnvironmentPtr dep_dp,
+ BiContextTypePtr ctx,
+ unsigned int max_bin)
+{
+ unsigned int symbol = biari_decode_symbol(dep_dp, ctx );
+
+ if (symbol == 0)
+ return 0;
+ else
+ {
+ const unsigned int exp_start = 8;
+
+ ++ctx;
+ for (symbol=1;symbol<exp_start;)
+ {
+ if (!biari_decode_symbol(dep_dp, ctx))
+ return symbol;
+ if ((++symbol)==2) ctx++;
+ if (symbol==max_bin)
+ ++ctx;
+ }
+
+ return exp_start + exp_golomb_decode_eq_prob(dep_dp,3);
+ }
+}
+unsigned int unary_exp_golomb_mv_decode3(DecodingEnvironmentPtr dep_dp,
+ BiContextTypePtr ctx)
+{
+ unsigned int max_bin = 3;
+ unsigned int symbol = biari_decode_symbol(dep_dp, ctx );
+
+ if (symbol == 0)
+ return 0;
+ else
+ {
+ const unsigned int exp_start = 8;
+
+ ++ctx;
+ for (symbol=1;symbol<exp_start;)
+ {
+ if (!biari_decode_symbol(dep_dp, ctx))
+ return symbol;
+ if ((++symbol)==2) ctx++;
+ if (symbol==max_bin)
+ ++ctx;
+ }
+
+ return exp_start + exp_golomb_decode_eq_prob(dep_dp,3);
+ }
+}
+#endif
+
+/*!
+************************************************************************
+* \brief
+* Read I_PCM macroblock
+************************************************************************
+*/
+void readIPCM_CABAC(Slice *currSlice, struct datapartition *dP)
+{
+ VideoParameters *p_Vid = currSlice->p_Vid;
+ StorablePicture *dec_picture = p_Vid->dec_picture;
+ Bitstream* currStream = dP->bitstream;
+ DecodingEnvironmentPtr dep = &(dP->de_cabac);
+ byte *buf = currStream->streamBuffer;
+ int BitstreamLengthInBits = (dP->bitstream->bitstream_length << 3) + 7;
+
+ int val = 0;
+
+ int bits_read = 0;
+ int bitoffset, bitdepth;
+ int uv, i, j;
+
+ while (dep->DbitsLeft >= 8)
+ {
+ dep->Dvalue >>= 8;
+ dep->DbitsLeft -= 8;
+ (*dep->Dcodestrm_len)--;
+ }
+
+ bitoffset = (*dep->Dcodestrm_len) << 3;
+
+ // read luma values
+ bitdepth = p_Vid->bitdepth_luma;
+ for(i=0;i<MB_BLOCK_SIZE;++i)
+ {
+ for(j=0;j<MB_BLOCK_SIZE;++j)
+ {
+ bits_read += GetBits(buf, bitoffset, &val, BitstreamLengthInBits, bitdepth);
+ currSlice->ipcm[0][i][j] = val;
+ bitoffset += bitdepth;
+ }
+ }
+
+ // read chroma values
+ bitdepth = p_Vid->bitdepth_chroma;
+ if ((dec_picture->chroma_format_idc != YUV400) && !IS_INDEPENDENT(p_Vid))
+ {
+ for (uv=1; uv<3; ++uv)
+ {
+ for(i=0;i<p_Vid->mb_cr_size_y;++i)
+ {
+ for(j=0;j<p_Vid->mb_cr_size_x;++j)
+ {
+ bits_read += GetBits(buf, bitoffset, &val, BitstreamLengthInBits, bitdepth);
+ currSlice->ipcm[uv][i][j] = val;
+ bitoffset += bitdepth;
+ }
+ }
+ }
+ }
+
+ (*dep->Dcodestrm_len) += ( bits_read >> 3);
+ if (bits_read & 7)
+ {
+ ++(*dep->Dcodestrm_len);
+ }
+}
+