/** * Part of HEVC Encoder * By Marko Viitanen ( fador at iki.fi ), Tampere University of Technology, Department of Computer Systems. */ /*! \file context.c \brief Functions for context derication \author Marko Viitanen \date 2012-08 This file contains context derivation functions */ #include #include #include #include "global.h" #include "config.h" #include "encoder.h" #include "cabac.h" #include "context.h" /* CONTEXTS */ /* ToDo: move somewhere else */ cabac_ctx *SplitFlagSCModel; cabac_ctx g_SplitFlagSCModel[3]; /*QP, INIT_SPLIT_FLAG[SLICE][0]); ctx_init(&g_SplitFlagSCModel[1], encoder->QP, INIT_SPLIT_FLAG[SLICE][1]); ctx_init(&g_SplitFlagSCModel[2], encoder->QP, INIT_SPLIT_FLAG[SLICE][2]); ctx_init(&g_IntraModeSCModel, encoder->QP, INIT_INTRA_PRED_MODE[SLICE]); ctx_init(&g_ChromaPredSCModel[0], encoder->QP, INIT_CHROMA_PRED_MODE[SLICE][0]); ctx_init(&g_ChromaPredSCModel[1], encoder->QP, INIT_CHROMA_PRED_MODE[SLICE][1]); ctx_init(&g_cCUAbsSCModel_chroma[0], encoder->QP, INIT_ABS_FLAG[SLICE][4]); ctx_init(&g_cCUAbsSCModel_chroma[1], encoder->QP, INIT_ABS_FLAG[SLICE][5]); for(i = 0; i < 4; i++) { ctx_init(&g_CUSigCoeffGroupSCModel[i], encoder->QP, INIT_SIG_CG_FLAG[SLICE][i]); ctx_init(&g_cCUAbsSCModel_luma[i], encoder->QP, INIT_ABS_FLAG[SLICE][i]); } for(i = 0; i < 3; i++) { ctx_init(&g_TransSubdivSCModel[i], encoder->QP, INIT_TRANS_SUBDIV_FLAG[SLICE][i]); ctx_init(&g_QtCbfSCModelY[i], encoder->QP, INIT_QT_CBF[SLICE][i]); ctx_init(&g_QtCbfSCModelU[i], encoder->QP, INIT_QT_CBF[SLICE][i+3]); //cxt_init(&g_QtCbfSCModelV[i], encoder->QP, INIT_QT_CBF[SLICE][i]); } for(i = 0; i < 8; i++) { ctx_init(&g_CUOneSCModel_chroma[i], encoder->QP, INIT_ONE_FLAG[SLICE][i+16]); } for(i = 0; i < 15; i++) { ctx_init(&g_CuCtxLastY_luma[i], encoder->QP, INIT_LAST[SLICE][i] ); ctx_init(&g_CuCtxLastX_luma[i], encoder->QP, INIT_LAST[SLICE][i] ); ctx_init(&g_CuCtxLastY_chroma[i], encoder->QP, INIT_LAST[SLICE][i+15] ); ctx_init(&g_CuCtxLastX_chroma[i], encoder->QP, INIT_LAST[SLICE][i+15] ); ctx_init(&g_CUOneSCModel_luma[i], encoder->QP, INIT_ONE_FLAG[SLICE][i]); } for(i = 0; i < 27; i++) { ctx_init(&g_CUSigSCModel_luma[i], encoder->QP, INIT_SIG_FLAG[SLICE][i]); if(i < 15) { ctx_init(&g_CUSigSCModel_chroma[i], encoder->QP, INIT_SIG_FLAG[SLICE][i+27]); } } } uint32_t context_get_sigCoeffGroup( uint32_t* uiSigCoeffGroupFlag, uint32_t uiCGPosX, uint32_t uiCGPosY, uint32_t scanIdx, int32_t width) { uint32_t uiRight = 0; uint32_t uiLower = 0; width >>= 2; if( uiCGPosX < width - 1 ) uiRight = (uiSigCoeffGroupFlag[ uiCGPosY * width + uiCGPosX + 1 ] != 0); if (uiCGPosY < width - 1 ) uiLower = (uiSigCoeffGroupFlag[ (uiCGPosY + 1 ) * width + uiCGPosX ] != 0); return (uiRight || uiLower); } //uint8_t get_context_coeff_abs_significant_flag(uint8_t /** Pattern decision for context derivation process of significant_coeff_flag * \param sigCoeffGroupFlag pointer to prior coded significant coeff group * \param posXCG column of current coefficient group * \param posYCG row of current coefficient group * \param width width of the block * \param height height of the block * \returns pattern for current coefficient group */ int32_t context_calcPatternSigCtx( const uint32_t* sigCoeffGroupFlag, uint32_t posXCG, uint32_t posYCG, int32_t width) { if( width == 4) return -1; { uint32_t sigRight = 0; uint32_t sigLower = 0; width >>= 2; if( posXCG < width - 1 ) { sigRight = (sigCoeffGroupFlag[ posYCG * width + posXCG + 1 ] != 0); } if (posYCG < width - 1 ) { sigLower = (sigCoeffGroupFlag[ (posYCG + 1 ) * width + posXCG ] != 0); } return sigRight + (sigLower<<1); } } /** Context derivation process of coeff_abs_significant_flag * \param patternSigCtx pattern for current coefficient group * \param posX column of current scan position * \param posY row of current scan position * \param blockType log2 value of block size if square block, or 4 otherwise * \param width width of the block * \param textureType texture type (TEXT_LUMA...) * \returns ctxInc for current scan position */ int32_t context_getSigCtxInc(int32_t patternSigCtx,uint32_t scanIdx,int32_t posX, int32_t posY,int32_t blockType,int32_t width, int8_t textureType) { const int32_t ctxIndMap[16] = { 0, 1, 4, 5, 2, 3, 4, 5, 6, 6, 8, 8, 7, 7, 8, 8 }; if( posX + posY == 0 ) return 0; if ( blockType == 2 ) return ctxIndMap[ 4 * posY + posX ]; { int32_t cnt = 0; int32_t offset = blockType == 3 ? (scanIdx==SCAN_DIAG ? 9 : 15) : (textureType == 0 ? 21 : 12); int32_t posXinSubset = posX-((posX>>2)<<2); int32_t posYinSubset = posY-((posY>>2)<<2); if(patternSigCtx==0) { cnt = posXinSubset+posYinSubset<=2 ? (posXinSubset+posYinSubset==0 ? 2 : 1) : 0; } else if(patternSigCtx==1) { cnt = posYinSubset<=1 ? (posYinSubset==0 ? 2 : 1) : 0; } else if(patternSigCtx==2) { cnt = posXinSubset<=1 ? (posXinSubset==0 ? 2 : 1) : 0; } else { cnt = 2; } return (( textureType == 0 && ((posX>>2) + (posY>>2)) > 0 ) ? 3 : 0) + offset + cnt; } }