📄 cabac.c
字号:
// *************************************************************************************
// *************************************************************************************
// Cabac.c CABAC entropy coding routines
//
// Main contributors (see contributors.h for copyright, address and affiliation details)
//
// Detlev Marpe <marpe@hhi.de>
// *************************************************************************************
// *************************************************************************************
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <memory.h>
#include <string.h>
#include "cabac.h"
#include "global.h"
#include "elements.h"
#include "bitsbuf.h"
extern const int BLOCK_STEP[8][2];
int symbolCount = 0;
/************************************************************************
*
* Name : create_contexts_MotionInfo()
*
* Description: Allocates of contexts models for the motion info
* used for arithmetic decoding
*
************************************************************************/
MotionInfoContexts* create_contexts_MotionInfo(void)
{
int j;
MotionInfoContexts *deco_ctx;
deco_ctx = (MotionInfoContexts*) calloc(1, sizeof(MotionInfoContexts) );
if( deco_ctx == NULL )
no_mem_exit(1);
for (j=0; j<2; j++)
{
deco_ctx->mb_type_contexts[j] = (BiContextTypePtr) malloc(NUM_MB_TYPE_CTX * sizeof( BiContextType ) );
if( deco_ctx->mb_type_contexts[j] == NULL )
no_mem_exit(1);
deco_ctx->mv_res_contexts[j] = (BiContextTypePtr) malloc(NUM_MV_RES_CTX * sizeof( BiContextType ) );
if( deco_ctx->mv_res_contexts[j] == NULL )
no_mem_exit(1);
}
deco_ctx->ref_no_contexts = (BiContextTypePtr) malloc(NUM_REF_NO_CTX * sizeof( BiContextType ) );
if( deco_ctx->ref_no_contexts == NULL )
no_mem_exit(1);
return deco_ctx;
}
/************************************************************************
*
* Name : create_contexts_TextureInfo()
*
* Description: Allocates of contexts models for the texture info
* used for arithmetic decoding
*
************************************************************************/
TextureInfoContexts* create_contexts_TextureInfo(void)
{
int j,k;
TextureInfoContexts *deco_ctx;
deco_ctx = (TextureInfoContexts*) calloc(1, sizeof(TextureInfoContexts) );
if( deco_ctx == NULL )
no_mem_exit(1);
for (j=0; j < 6; j++)
{
deco_ctx->ipr_contexts[j] = (BiContextTypePtr) malloc(NUM_IPR_CTX * sizeof( BiContextType ) );
if( deco_ctx->ipr_contexts[j] == NULL )
no_mem_exit(1);
}
for (k=0; k<2; k++)
for (j=0; j<3; j++)
{
deco_ctx->cbp_contexts[k][j] = (BiContextTypePtr) malloc(NUM_CBP_CTX * sizeof( BiContextType ) );
if( deco_ctx->cbp_contexts[k][j] == NULL )
no_mem_exit(1);
}
for (j=0; j < NUM_TRANS_TYPE; j++)
{
deco_ctx->level_context[j] = (BiContextTypePtr) malloc(NUM_LEVEL_CTX * sizeof( BiContextType ) );
if( deco_ctx->level_context[j] == NULL )
no_mem_exit(1);
deco_ctx->run_context[j] = (BiContextTypePtr) malloc(NUM_RUN_CTX * sizeof( BiContextType ) );
if( deco_ctx->run_context[j] == NULL )
no_mem_exit(1);
}
return deco_ctx;
}
/************************************************************************
*
* Name : init_contexts_MotionInfo()
*
* Description: Initializes an array of contexts models with some pre-defined
* counts (ini_flag = 1) or with a flat histogram (ini_flag = 0)
*
************************************************************************/
void init_contexts_MotionInfo(struct img_par *img, MotionInfoContexts *deco_ctx, int ini_flag)
{
int i,j;
int scale_factor;
if ( (img->width*img->height) <= (IMG_WIDTH * IMG_HEIGHT) ) /* format <= QCIF */
scale_factor=1;
else
scale_factor=2;
for (j=0; j<2; j++)
{
if (ini_flag)
{
for (i=0; i < NUM_MB_TYPE_CTX; i++)
biari_init_context(deco_ctx->mb_type_contexts[j] + i,MB_TYPE_Ini[j][i][0]*scale_factor,MB_TYPE_Ini[j][i][1]*scale_factor,MB_TYPE_Ini[j][i][2]*scale_factor);
}
else
{
for (i=0; i < NUM_MB_TYPE_CTX; i++)
biari_init_context(deco_ctx->mb_type_contexts[j] + i,1,1,1000);
}
if (ini_flag)
{
for (i=0; i < NUM_MV_RES_CTX; i++)
biari_init_context(deco_ctx->mv_res_contexts[j] + i,MV_RES_Ini[j][i][0]*scale_factor,MV_RES_Ini[j][i][1]*scale_factor,MV_RES_Ini[j][i][2]*scale_factor);
}
else
{
for (i=0; i < NUM_MV_RES_CTX; i++)
biari_init_context(deco_ctx->mv_res_contexts[j] + i,1,1,1000);
}
}
if (ini_flag)
{
for (i=0; i < NUM_REF_NO_CTX; i++)
biari_init_context(deco_ctx->ref_no_contexts + i,REF_NO_Ini[i][0]*scale_factor,REF_NO_Ini[i][1]*scale_factor,REF_NO_Ini[i][2]*scale_factor);
}
else
{
for (i=0; i < NUM_REF_NO_CTX; i++)
biari_init_context(deco_ctx->ref_no_contexts + i,1,1,1000);
}
}
/************************************************************************
*
* Name : init_contexts_TextureInfo()
*
* Description: Initializes an array of contexts models with some pre-defined
* counts (ini_flag = 1) or with a flat histogram (ini_flag = 0)
*
************************************************************************/
void init_contexts_TextureInfo(struct img_par *img, TextureInfoContexts *deco_ctx, int ini_flag)
{
int i,j,k;
int scale_factor;
if ( (img->width*img->height) <= (IMG_WIDTH * IMG_HEIGHT) ) /* format <= QCIF */
scale_factor=1;
else
scale_factor=2;
for (j=0; j < 6; j++)
{
if (ini_flag)
{
for (i=0; i < NUM_IPR_CTX; i++)
biari_init_context(deco_ctx->ipr_contexts[j] + i,IPR_Ini[j][i][0]*scale_factor,IPR_Ini[j][i][1]*scale_factor,IPR_Ini[j][i][2]*scale_factor);
}
else
{
for (i=0; i < NUM_IPR_CTX; i++)
biari_init_context(deco_ctx->ipr_contexts[j] + i,2,1,50);
}
}
for (k=0; k<2; k++)
for (j=0; j<3; j++)
{
if (ini_flag)
{
for (i=0; i < NUM_CBP_CTX; i++)
biari_init_context(deco_ctx->cbp_contexts[k][j] + i,CBP_Ini[k][j][i][0]*scale_factor,CBP_Ini[k][j][i][1]*scale_factor,CBP_Ini[k][j][i][2]*scale_factor);
}
else
{
for (i=0; i < NUM_CBP_CTX; i++)
biari_init_context(deco_ctx->cbp_contexts[k][j] + i,1,1,100);
}
}
for (j=0; j < NUM_TRANS_TYPE; j++)
{
if (ini_flag)
{
for (i=0; i < NUM_LEVEL_CTX; i++)
biari_init_context(deco_ctx->level_context[j] + i,Level_Ini[j][i][0]*scale_factor,Level_Ini[j][i][1]*scale_factor,Level_Ini[j][i][2]*scale_factor);
}
else
{
for (i=0; i < NUM_LEVEL_CTX; i++)
biari_init_context(deco_ctx->level_context[j] + i,2,1,100);
}
if (ini_flag)
{
for (i=0; i < NUM_RUN_CTX; i++)
biari_init_context(deco_ctx->run_context[j] + i,Run_Ini[j][i][0]*scale_factor,Run_Ini[j][i][1]*scale_factor,Run_Ini[j][i][2]*scale_factor);
}
else
{
for (i=0; i < NUM_RUN_CTX; i++)
biari_init_context(deco_ctx->run_context[j] + i,2,1,100);
}
}
}
/************************************************************************
*
* Name : delete_contexts_MotionInfo()
*
* Description: Frees the memory of the contexts models
* used for arithmetic decoding of the motion info.
*
************************************************************************/
void delete_contexts_MotionInfo(MotionInfoContexts *deco_ctx)
{
int j;
if( deco_ctx == NULL )
return;
for (j=0; j<2; j++)
{
if (deco_ctx->mb_type_contexts[j] != NULL)
free(deco_ctx->mb_type_contexts[j] );
if (deco_ctx->mv_res_contexts[j] != NULL)
free(deco_ctx->mv_res_contexts[j] );
}
if (deco_ctx->ref_no_contexts != NULL)
free(deco_ctx->ref_no_contexts);
free( deco_ctx );
return;
}
/************************************************************************
*
* Name : delete_contexts_TextureInfo()
*
* Description: Frees the memory of the contexts models
* used for arithmetic decoding of the texture info.
*
************************************************************************/
void delete_contexts_TextureInfo(TextureInfoContexts *deco_ctx)
{
int j,k;
if( deco_ctx == NULL )
return;
for (j=0; j < 6; j++)
{
if (deco_ctx->ipr_contexts[j] != NULL)
free(deco_ctx->ipr_contexts[j]);
}
for (k=0; k<2; k++)
for (j=0; j<3; j++)
{
if (deco_ctx->cbp_contexts[k][j] != NULL)
free(deco_ctx->cbp_contexts[k][j]);
}
for (j=0; j < NUM_TRANS_TYPE; j++)
{
if (deco_ctx->level_context[j] != NULL)
free(deco_ctx->level_context[j]);
if (deco_ctx->run_context[j] != NULL)
free(deco_ctx->run_context[j]);
}
free( deco_ctx );
return;
}
/****************************************************************************
*
* Function: readBiMVD2Buffer_CABAC()
*
* Purpose: This function is used to arithmetically decode the motion
* vector data of a B-frame MB.
*
*
***************************************************************************/
void readBiMVD2Buffer_CABAC( SyntaxElement *se,
struct inp_par *inp,
struct img_par *img,
DecodingEnvironmentPtr dep_dp)
{
int step_h, step_v;
int i = img->subblock_x;
int j = img->subblock_y;
int a, b;
int act_ctx, act_ctx1;
int act_sym;
int mv_local_err;
int mv_sign;
int backward = se->value2 & 0x01;
int k = (se->value2>>1); /* MVD component */
MotionInfoContexts *ctx = img->currentSlice->mot_ctx;
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
// int curr_mb_type = currMB->mb_type;
if(backward == 0)
{
step_h=img->fw_blc_size_h/BLOCK_SIZE; // horizontal stepsize
step_v=img->fw_blc_size_v/BLOCK_SIZE; // vertical stepsize
}
else
{
step_h=img->bw_blc_size_h/BLOCK_SIZE; // horizontal stepsize
step_v=img->bw_blc_size_v/BLOCK_SIZE; // vertical stepsize
}
if (j==0)
{
if (currMB->mb_available[0][1] == NULL)
b = 0;
else
b = absm((currMB->mb_available[0][1])->mvd[backward][BLOCK_SIZE-1][i][k]);
}
else
b = absm(currMB->mvd[backward][j-step_v][i][k]);
if (i==0)
{
if (currMB->mb_available[1][0] == NULL)
a = 0;
else
a = absm((currMB->mb_available[1][0])->mvd[backward][j][BLOCK_SIZE-1][k]);
}
else
a = absm(currMB->mvd[backward][j][i-step_h][k]);
if ((mv_local_err=a+b)<3)
act_ctx = 5*k;
else
{
if (mv_local_err>32)
act_ctx=5*k+3;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -