2124 lines
60 KiB
C
2124 lines
60 KiB
C
/*!
|
|
*************************************************************************************
|
|
* \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);
|
|
}
|
|
}
|
|
|