cabac.c
来自「JM 11.0 KTA 2.1 Source Code」· C语言 代码 · 共 1,962 行 · 第 1/5 页
C
1,962 行
/*!
*************************************************************************************
* \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 <stdlib.h>
#include <assert.h>
#include <memory.h>
#include "global.h"
#include "cabac.h"
#include "image.h"
#include "mb_access.h"
#ifdef ADAPTIVE_FD_SD_CODING
#include "spatial_domain_coding.h"
extern int cabac_encoding;
#endif
#ifdef RDO_Q
estBitsCabacStruct estBitsCabac[NUM_BLOCK_TYPES];
int precalcUnaryLevelTab[128][MAX_PREC_COEFF];
extern int entropyBits[128];
#endif
static const int type2ctx_bcbp[] = { 0, 1, 2, 2, 3, 4, 5, 6, 5, 5}; // 7
#ifdef USE_INTRA_MDDT
static const int type2ctx_map [] = { 0, 1, 2, 3, 4, 5, 6, 7, 6, 6, 8}; // 9
static const int type2ctx_last[] = { 0, 1, 2, 3, 4, 5, 6, 7, 6, 6, 8}; // 9
static const int type2ctx_one [] = { 0, 1, 2, 3, 3, 4, 5, 6, 5, 5, 7}; // 8
static const int type2ctx_abs [] = { 0, 1, 2, 3, 3, 4, 5, 6, 5, 5, 7}; // 8
static const int max_c2 [] = { 4, 4, 4, 4, 4, 4, 3, 4, 3, 3, 4}; // 9
#else
static const int type2ctx_map [] = { 0, 1, 2, 3, 4, 5, 6, 7, 6, 6}; // 8
static const int type2ctx_last[] = { 0, 1, 2, 3, 4, 5, 6, 7, 6, 6}; // 8
static const int type2ctx_one [] = { 0, 1, 2, 3, 3, 4, 5, 6, 5, 5}; // 7
static const int type2ctx_abs [] = { 0, 1, 2, 3, 3, 4, 5, 6, 5, 5}; // 7
static const int max_c2 [] = { 4, 4, 4, 4, 4, 4, 3, 4, 3, 3}; // 9
#endif
#define BIT_SET(x,n) ((int)(((x)&((int64)1<<(n)))>>(n)))
int last_dquant = 0;
/***********************************************************************
* 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
***********************************************************************
*/
void unary_bin_encode(EncodingEnvironmentPtr eep_frame,
unsigned int symbol,
BiContextTypePtr ctx,
int ctx_offset);
void unary_bin_max_encode(EncodingEnvironmentPtr eep_frame,
unsigned int symbol,
BiContextTypePtr ctx,
int ctx_offset,
unsigned int max_symbol);
void unary_exp_golomb_level_encode( EncodingEnvironmentPtr eep_dp,
unsigned int symbol,
BiContextTypePtr ctx);
void unary_exp_golomb_mv_encode(EncodingEnvironmentPtr eep_dp,
unsigned int symbol,
BiContextTypePtr ctx,
unsigned int max_bin);
void cabac_new_slice(void)
{
last_dquant=0;
}
/*!
************************************************************************
* \brief
* Check for available neighbouring blocks
* and set pointers in current macroblock
************************************************************************
*/
void CheckAvailabilityOfNeighborsCABAC(void)
{
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
PixelPos up, left;
getNeighbour(img->current_mb_nr, -1, 0, 1, &left);
getNeighbour(img->current_mb_nr, 0, -1, 1, &up);
if (up.available)
currMB->mb_available_up = &img->mb_data[up.mb_addr];
else
currMB->mb_available_up = NULL;
if (left.available)
currMB->mb_available_left = &img->mb_data[left.mb_addr];
else
currMB->mb_available_left = NULL;
}
/*!
************************************************************************
* \brief
* Allocation of contexts models for the motion info
* used for arithmetic encoding
************************************************************************
*/
MotionInfoContexts* create_contexts_MotionInfo(void)
{
MotionInfoContexts* enco_ctx;
enco_ctx = (MotionInfoContexts*) calloc(1, sizeof(MotionInfoContexts) );
if( enco_ctx == NULL )
no_mem_exit("create_contexts_MotionInfo: enco_ctx");
return enco_ctx;
}
/*!
************************************************************************
* \brief
* Allocates of contexts models for the texture info
* used for arithmetic encoding
************************************************************************
*/
TextureInfoContexts* create_contexts_TextureInfo(void)
{
TextureInfoContexts* enco_ctx;
enco_ctx = (TextureInfoContexts*) calloc(1, sizeof(TextureInfoContexts) );
if( enco_ctx == NULL )
no_mem_exit("create_contexts_TextureInfo: enco_ctx");
return enco_ctx;
}
/*!
************************************************************************
* \brief
* Frees the memory of the contexts models
* used for arithmetic encoding of the motion info.
************************************************************************
*/
void delete_contexts_MotionInfo(MotionInfoContexts *enco_ctx)
{
if( enco_ctx == NULL )
return;
free( enco_ctx );
return;
}
/*!
************************************************************************
* \brief
* Frees the memory of the contexts models
* used for arithmetic encoding of the texture info.
************************************************************************
*/
void delete_contexts_TextureInfo(TextureInfoContexts *enco_ctx)
{
if( enco_ctx == NULL )
return;
free( enco_ctx );
return;
}
/*!
**************************************************************************
* \brief
* generates arithmetic code and passes the code to the buffer
**************************************************************************
*/
int writeSyntaxElement_CABAC(SyntaxElement *se, DataPartition *this_dataPart)
{
EncodingEnvironmentPtr eep_dp = &(this_dataPart->ee_cabac);
int curr_len = arienco_bits_written(eep_dp);
// perform the actual coding by calling the appropriate method
se->writing(se, eep_dp);
if(se->type != SE_HEADER)
this_dataPart->bitstream->write_flag = 1;
return (se->len = (arienco_bits_written(eep_dp) - curr_len));
}
/*!
***************************************************************************
* \brief
* This function is used to arithmetically encode the field
* mode info of a given MB in the case of mb-based frame/field decision
***************************************************************************
*/
void writeFieldModeInfo_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp)
{
int a,b,act_ctx;
MotionInfoContexts *ctx = (img->currentSlice)->mot_ctx;
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
int mb_field = se->value1;
a = currMB->mbAvailA ? img->mb_data[currMB->mbAddrA].mb_field : 0;
b = currMB->mbAvailB ? img->mb_data[currMB->mbAddrB].mb_field : 0;
act_ctx = a + b;
biari_encode_symbol(eep_dp, (signed short) (mb_field != 0),&ctx->mb_aff_contexts[act_ctx]);
se->context = act_ctx;
return;
}
#ifdef ADAPTIVE_FD_SD_CODING
void write_adaptive_prederror_coding_flag_for_MB(SyntaxElement *se, EncodingEnvironmentPtr eep_dp)
{
int a, b;
int ctx = 0;
int act_sym;
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
b = (currMB->mb_available_up == NULL) ? 0 : currMB->mb_available_up ->SD_Coding_on_off;
a = (currMB->mb_available_left == NULL) ? 0 : currMB->mb_available_left->SD_Coding_on_off;
ctx = a + 2 * b;
act_sym = se->value1;
biari_encode_symbol (eep_dp, (short)act_sym, img->currentSlice->tex_ctx->MB_adaptive_SD_context+ctx);
}
void write_spatial_domain_coding_flag_for_4x4block (Macroblock* currMB, EncodingEnvironmentPtr eep_dp, int type, int FD_SD_bit)
{
int y_ac = (type==LUMA_16AC || type==LUMA_8x8 || type==LUMA_8x4 || type==LUMA_4x8 || type==LUMA_4x4);
int y_dc = (type==LUMA_16DC);
int u_ac = (type==CHROMA_AC && !img->is_v_block);
int v_ac = (type==CHROMA_AC && img->is_v_block);
int chroma_dc = (type==CHROMA_DC || type==CHROMA_DC_2x4 || type==CHROMA_DC_4x4);
int u_dc = (chroma_dc && !img->is_v_block);
int v_dc = (chroma_dc && img->is_v_block);
int j = (y_ac || u_ac || v_ac ? img->subblock_y : 0);
int i = (y_ac || u_ac || v_ac ? img->subblock_x : 0);
int bit = (y_dc ? 0 : y_ac ? 1 : u_dc ? 17 : v_dc ? 18 : u_ac ? 19 : 23);
int default_bit = (img->is_intra_block ? 1 : 0);
int upper_bit = default_bit;
int left_bit = default_bit;
int ctx;
int bit_pos_a = 0;
int bit_pos_b = 0;
PixelPos block_a, block_b;
if (y_ac || y_dc)
{
getLuma4x4Neighbour(img->current_mb_nr, i, j, -1, 0, &block_a);
getLuma4x4Neighbour(img->current_mb_nr, i, j, 0, -1, &block_b);
if (y_ac)
{
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
{
getChroma4x4Neighbour(img->current_mb_nr, i, j, -1, 0, &block_a);
getChroma4x4Neighbour(img->current_mb_nr, i, j, 0, -1, &block_b);
if (u_ac||v_ac)
{
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;
}
}
bit = (y_dc ? 0 : y_ac ? 1+4*j+i : u_dc ? 17 : v_dc ? 18 : u_ac ? 19+4*j+i : 35+4*j+i);
//--- set bits for current block ---
if (FD_SD_bit)
{
if (type==LUMA_8x8)
{
currMB->FD_or_SD_bits |= ((int64)1<< bit );
currMB->FD_or_SD_bits |= ((int64)1<<(bit+1));
currMB->FD_or_SD_bits |= ((int64)1<<(bit+4));
currMB->FD_or_SD_bits |= ((int64)1<<(bit+5));
}
else if (type==LUMA_8x4)
{
currMB->FD_or_SD_bits |= ((int64)1<< bit );
currMB->FD_or_SD_bits |= ((int64)1<<(bit+1));
}
else if (type==LUMA_4x8)
{
currMB->FD_or_SD_bits |= ((int64)1<< bit );
currMB->FD_or_SD_bits |= ((int64)1<<(bit+4));
}
else
{
currMB->FD_or_SD_bits |= ((int64)1<<bit);
}
}
bit = (y_dc ? 0 : y_ac ? 1 : u_dc ? 17 : v_dc ? 18 : u_ac ? 19 : 35);
if (type!=LUMA_8x8)
{
if (block_b.available)
{
if(img->mb_data[block_b.mb_addr].mb_type==IPCM)
upper_bit=1;
else
upper_bit = BIT_SET(img->mb_data[block_b.mb_addr].FD_or_SD_bits,bit+bit_pos_b);
}
if (block_a.available)
{
if(img->mb_data[block_a.mb_addr].mb_type==IPCM)
left_bit=1;
else
left_bit = BIT_SET(img->mb_data[block_a.mb_addr].FD_or_SD_bits,bit+bit_pos_a);
}
ctx = 2*upper_bit+left_bit;
//===== encode symbol =====
biari_encode_symbol (eep_dp, (short)FD_SD_bit, img->currentSlice->tex_ctx->bcbp_contexts_FD_SD+ctx);
}
}
void write_spatial_domain_coding_flag_for_8x8block (Macroblock* currMB, EncodingEnvironmentPtr eep_dp, int type, int FD_SD_bit, int writing_b8)
{
int ctx=0;
int upper_bit = 0;
int left_bit = 0;
if (writing_b8==0)
{
upper_bit = (currMB->mb_available_up == NULL) ? 0 : (((currMB->mb_available_up ->SD_or_FD_t8x8) & 4)==0?0:1);
left_bit = (currMB->mb_available_left == NULL) ? 0 : (((currMB->mb_available_left->SD_or_FD_t8x8) & 2)==0?0:1);
}
else if (writing_b8==1)
{
upper_bit = (currMB->mb_available_up == NULL) ? 0 : (((currMB->mb_available_up ->SD_or_FD_t8x8) & 8)==0?0:1);
left_bit = (((currMB->SD_or_FD_t8x8) & 1)==0?0:1);
}
else if (writing_b8==2)
{
upper_bit = (((currMB->SD_or_FD_t8x8) & 1)==0?0:1);
left_bit = (currMB->mb_available_left == NULL) ? 0 : (((currMB->mb_available_left->SD_or_FD_t8x8) & 8)==0?0:1);
}
else
{
upper_bit = (((currMB->SD_or_FD_t8x8) & 2)==0?0:1);
left_bit = (((currMB->SD_or_FD_t8x8) & 4)==0?0:1);
}
ctx=2*upper_bit+left_bit;
//===== encode symbol =====
biari_encode_symbol (eep_dp, (short)FD_SD_bit, img->currentSlice->tex_ctx->bcbp8_contexts_FD_SD+ctx);
}
#endif
/*!
***************************************************************************
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?