/* * Copyright (c) 2011 Intel Corporation. All Rights Reserved. * Copyright (c) Imagination Technologies Limited, UK * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Authors: * Edward Lin <edward.lin@intel.com> * */ #include <unistd.h> #include <stdio.h> #include <memory.h> #include "hwdefs/topazhp_core_regs.h" #include "hwdefs/topaz_vlc_regs.h" #include "hwdefs/topazhp_multicore_regs.h" #include "hwdefs/topazhp_multicore_regs_old.h" #include "psb_drv_video.h" #include "tng_cmdbuf.h" #include "tng_hostbias.h" #include "psb_drv_debug.h" #include <stdlib.h> #define UNINIT_PARAM 0xCDCDCDCD #define TOPAZHP_DEFAULT_bZeroDetectionDisable IMG_FALSE #define TH_SKIP_IPE 6 #define TH_INTER 60 #define TH_INTER_QP 10 #define TH_INTER_MAX_LEVEL 1500 #define TH_SKIP_SPE 6 #define TOPAZHP_DEFAULT_uTHInter TH_INTER #define TOPAZHP_DEFAULT_uTHInterQP TH_INTER_QP #define TOPAZHP_DEFAULT_uTHInterMaxLevel TH_INTER_MAX_LEVEL #define TOPAZHP_DEFAULT_uTHSkipIPE TH_SKIP_IPE #define TOPAZHP_DEFAULT_uTHSkipSPE TH_SKIP_SPE #define MIN_32_REV 0x00030200 #define MAX_32_REV 0x00030299 // New MP4 Lambda table static IMG_UINT8 MPEG4_QPLAMBDA_MAP[31] = { 0, 0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13 }; static IMG_UINT8 H263_QPLAMBDA_MAP[31] = { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 10,10 }; // new H.264 Lambda static IMG_INT8 H264_QPLAMBDA_MAP_SAD[40] = { 2, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9, 11, 13, 14, 15, 17, 20, 23, 27, 31, 36, 41, 51, 62, 74, 79, 85, 91 }; static IMG_INT8 H264_QPLAMBDA_MAP_SATD_TABLES[][52] = { //table 0 { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 17, 18, 20, 21, 23, 25, 27, 30, 32, 38, 44, 50, 56, 63, 67, 72, 77, 82, 87, 92 }, }; static IMG_INT32 H264_DIRECT_BIAS[27] = { 24, 24, 24, 24, 24, 24, 24, 24, 36, 48, 48, 60, 60, 72, 72, 84, 96, 108, 200, 324, 384, 528, 672, 804, 924, 1044, 1104 }; static IMG_INT32 H264_INTRA8_SCALE[27] = { (234 + 8) >> 4, (231 + 8) >> 4, (226 + 8) >> 4, (221 + 8) >> 4, (217 + 8) >> 4, (213 + 8) >> 4, (210 + 8) >> 4, (207 + 8) >> 4, (204 + 8) >> 4, (202 + 8) >> 4, (200 + 8) >> 4, (199 + 8) >> 4, (197 + 8) >> 4, (197 + 8) >> 4, (196 + 8) >> 4, (196 + 8) >> 4, (197 + 8) >> 4, (197 + 8) >> 4, (198 + 8) >> 4, (200 + 8) >> 4, (202 + 8) >> 4, (204 + 8) >> 4, (207 + 8) >> 4, (210 + 8) >> 4, (213 + 8) >> 4, (217 + 8) >> 4, (217 + 8) >> 4 }; /*********************************************************************************** * Function Name : H264InterBias * Inputs : ui8QP * Outputs : * Returns : IMG_INT16 * Description : return the Inter Bias Value to use for the given QP ************************************************************************************/ static IMG_INT16 H264_InterIntraBias[27] = { 20, 20, 20, 20, 20, 20, 50, 100, 210, 420, 420, 445, 470, 495, 520, 535, 550, 570, 715, 860, 900, 1000, 1200, 1400, 1600, 1800, 2000 }; static IMG_INT16 tng__H264ES_inter_bias(IMG_INT8 i8QP) { if (i8QP < 1) { i8QP = 1; } if (i8QP > 51) { i8QP = 51; } //return aui16InterBiasValues[i8QP-36]; return H264_InterIntraBias[(i8QP+1)>>1]; } /***************************************************************************** * Function Name : CalculateDCScaler * Inputs : iQP, bChroma * Outputs : iDCScaler * Returns : IMG_INT * Description : Calculates either the Luma or Chroma DC scaler from the quantization scaler *******************************************************************************/ IMG_INT CalculateDCScaler(IMG_INT iQP, IMG_BOOL bChroma) { IMG_INT iDCScaler; if(!bChroma) { if (iQP > 0 && iQP < 5) { iDCScaler = 8; } else if (iQP > 4 && iQP < 9) { iDCScaler = 2 * iQP; } else if (iQP > 8 && iQP < 25) { iDCScaler = iQP + 8; } else { iDCScaler = 2 * iQP -16; } } else { if (iQP > 0 && iQP < 5) { iDCScaler = 8; } else if (iQP > 4 && iQP < 25) { iDCScaler = (iQP + 13) / 2; } else { iDCScaler = iQP - 6; } } return iDCScaler; } /************************************************************************************************** * Function: MPEG4_GenerateBiasTables * Description: Genereate the bias tables for MPEG4 * ***************************************************************************************************/ void tng__MPEG4ES_generate_bias_tables( context_ENC_p ctx) { IMG_INT16 n; IMG_INT16 iX; IMG_UINT32 ui32RegVal; IMG_UINT8 uiDCScaleL,uiDCScaleC,uiLambda; IMG_UINT32 uDirectVecBias,iInterMBBias,iIntra16Bias; IMG_BIAS_PARAMS *psBiasParams = &(ctx->sBiasParams); ctx->sBiasTables.ui32LritcCacheChunkConfig = F_ENCODE(ctx->uChunksPerMb, INTEL_CH_PM) | F_ENCODE(ctx->uMaxChunks, INTEL_CH_MX) | F_ENCODE(ctx->uMaxChunks - ctx->uPriorityChunks, INTEL_CH_PY); for(n=31;n>=1;n--) { iX = n-12; if(iX < 0) { iX = 0; } // Dont Write QP Values To ESB -- IPE will write these values // Update the quantization parameter which includes doing Lamda and the Chroma QP uiDCScaleL = CalculateDCScaler(n, IMG_FALSE); uiDCScaleC = CalculateDCScaler(n, IMG_TRUE); uiLambda = psBiasParams->uLambdaSAD ? psBiasParams->uLambdaSAD : MPEG4_QPLAMBDA_MAP[n - 1]; ui32RegVal = uiDCScaleL; ui32RegVal |= (uiDCScaleC)<<8; ui32RegVal |= (uiLambda)<<16; ctx->sBiasTables.aui32LambdaBias[n] = ui32RegVal; } for(n=31;n>=1;n-=2) { if(psBiasParams->bRCEnable || psBiasParams->bRCBiases) { uDirectVecBias = psBiasParams->uTHSkipIPE * uiLambda; iInterMBBias = psBiasParams->uTHInter * (n - psBiasParams->uTHInterQP); //if(iInterMBBias < 0) // iInterMBBias = 0; if(iInterMBBias > psBiasParams->uTHInterMaxLevel) iInterMBBias = psBiasParams->uTHInterMaxLevel; iIntra16Bias = 0; } else { uDirectVecBias = psBiasParams->uIPESkipVecBias; iInterMBBias = psBiasParams->iInterMBBias; iIntra16Bias = psBiasParams->iIntra16Bias; } ctx->sBiasTables.aui32IntraBias[n] = iIntra16Bias; ctx->sBiasTables.aui32InterBias_P[n] = iInterMBBias; ctx->sBiasTables.aui32DirectBias_P[n] = uDirectVecBias; } if(psBiasParams->bRCEnable || psBiasParams->bRCBiases) ctx->sBiasTables.ui32sz1 = psBiasParams->uisz1; else ctx->sBiasTables.ui32sz1 = psBiasParams->uisz2; } /************************************************************************************************** * Function: H263_GenerateBiasTables * Description: Genereate the bias tables for H.263 * ***************************************************************************************************/ void tng__H263ES_generate_bias_tables( context_ENC_p ctx) { IMG_INT16 n; IMG_INT16 iX; IMG_UINT32 ui32RegVal; IMG_UINT8 uiDCScaleL,uiDCScaleC,uiLambda; IMG_UINT32 uDirectVecBias,iInterMBBias,iIntra16Bias; IMG_BIAS_PARAMS * psBiasParams = &(ctx->sBiasParams); ctx->sBiasTables.ui32LritcCacheChunkConfig = F_ENCODE(ctx->uChunksPerMb, INTEL_CH_PM) | F_ENCODE(ctx->uMaxChunks, INTEL_CH_MX) | F_ENCODE(ctx->uMaxChunks - ctx->uPriorityChunks, INTEL_CH_PY); for(n=31;n>=1;n--) { iX = n-12; if(iX < 0) { iX = 0; } // Dont Write QP Values To ESB -- IPE will write these values // Update the quantization parameter which includes doing Lamda and the Chroma QP uiDCScaleL = CalculateDCScaler(n, IMG_FALSE); uiDCScaleC = CalculateDCScaler(n, IMG_TRUE); uiLambda = psBiasParams->uLambdaSAD ? psBiasParams->uLambdaSAD : H263_QPLAMBDA_MAP[n - 1]; ui32RegVal=uiDCScaleL; ui32RegVal |= (uiDCScaleC)<<8; ui32RegVal |= (uiLambda)<<16; ctx->sBiasTables.aui32LambdaBias[n] = ui32RegVal; } for(n=31;n>=1;n-=2) { if(psBiasParams->bRCEnable || psBiasParams->bRCBiases) { uDirectVecBias = psBiasParams->uTHSkipIPE * uiLambda; iInterMBBias = psBiasParams->uTHInter * (n - psBiasParams->uTHInterQP); //if(iInterMBBias < 0) // iInterMBBias = 0; if(iInterMBBias > psBiasParams->uTHInterMaxLevel) iInterMBBias = psBiasParams->uTHInterMaxLevel; iIntra16Bias = 0; } else { uDirectVecBias = psBiasParams->uIPESkipVecBias; iInterMBBias = psBiasParams->iInterMBBias; iIntra16Bias = psBiasParams->iIntra16Bias; } ctx->sBiasTables.aui32IntraBias[n] = iIntra16Bias; ctx->sBiasTables.aui32InterBias_P[n] = iInterMBBias; ctx->sBiasTables.aui32DirectBias_P[n] = uDirectVecBias; } if(psBiasParams->bRCEnable || psBiasParams->bRCBiases) ctx->sBiasTables.ui32sz1 = psBiasParams->uisz1; else ctx->sBiasTables.ui32sz1 = psBiasParams->uisz2; } /************************************************************************************************** * Function: H264_GenerateBiasTables * Description: Generate the bias tables for H.264 * ***************************************************************************************************/ static void tng__H264ES_generate_bias_tables(context_ENC_p ctx) { IMG_INT32 n; IMG_UINT32 ui32RegVal; IMG_UINT32 iIntra16Bias, uisz2, uIntra8Scale, uDirectVecBias_P, iInterMBBias_P, uDirectVecBias_B, iInterMBBias_B; IMG_BIAS_PARAMS * psBiasParams = &(ctx->sBiasParams); IMG_BYTE PVR_QP_SCALE_CR[52] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 34, 35, 35, 36, 36, 37, 37, 37, 38, 38, 38, 39, 39, 39, 39 }; ctx->sBiasTables.ui32LritcCacheChunkConfig = F_ENCODE(ctx->uChunksPerMb, INTEL_CH_PM) | F_ENCODE(ctx->uMaxChunks, INTEL_CH_MX) | F_ENCODE(ctx->uMaxChunks - ctx->uPriorityChunks, INTEL_CH_PY); uIntra8Scale = 0; for (n = 51; n >= 0; n--) { IMG_INT32 iX; IMG_UINT32 uiLambdaSAD, uiLambdaSATD; iX = n - 12; if (iX < 0) iX = 0; uiLambdaSAD = H264_QPLAMBDA_MAP_SAD[iX]; uiLambdaSATD = H264_QPLAMBDA_MAP_SATD_TABLES[psBiasParams->uLambdaSATDTable][n]; if (psBiasParams->uLambdaSAD != 0) uiLambdaSAD = psBiasParams->uLambdaSAD; if (psBiasParams->uLambdaSATD != 0) uiLambdaSATD = psBiasParams->uLambdaSATD; // Dont Write QP Values To ESB -- IPE will write these values // Update the quantization parameter which includes doing Lamda and the Chroma QP ui32RegVal = PVR_QP_SCALE_CR[n]; ui32RegVal |= (uiLambdaSATD) << 8; //SATD lambda ui32RegVal |= (uiLambdaSAD) << 16; //SAD lambda ctx->sBiasTables.aui32LambdaBias[n] = ui32RegVal; } for (n = 52; n >= 0; n -= 2) { IMG_INT8 qp = n; if (qp > 51) qp = 51; if (psBiasParams->bRCEnable || psBiasParams->bRCBiases) { iInterMBBias_P = tng__H264ES_inter_bias(qp); uDirectVecBias_P = H264_DIRECT_BIAS[n/2]; iInterMBBias_B = iInterMBBias_P; uDirectVecBias_B = uDirectVecBias_P ; iIntra16Bias = 0; uIntra8Scale = H264_INTRA8_SCALE[n/2] - 8; if (psBiasParams->uDirectVecBias != UNINIT_PARAM) uDirectVecBias_B = psBiasParams->uDirectVecBias; if (psBiasParams->iInterMBBiasB != UNINIT_PARAM) iInterMBBias_B = psBiasParams->iInterMBBiasB; if (psBiasParams->uIPESkipVecBias != UNINIT_PARAM) uDirectVecBias_P = psBiasParams->uIPESkipVecBias; if (psBiasParams->iInterMBBias != UNINIT_PARAM) iInterMBBias_P = psBiasParams->iInterMBBias; if (psBiasParams->iIntra16Bias != UNINIT_PARAM) iIntra16Bias = psBiasParams->iIntra16Bias; } else { if (psBiasParams->uDirectVecBias == UNINIT_PARAM || psBiasParams->iInterMBBiasB == UNINIT_PARAM) { drv_debug_msg(VIDEO_DEBUG_GENERAL, "ERROR: Bias for B pictures not set up ... uDirectVecBias = 0x%x, iInterMBBiasB = 0x%x\n", psBiasParams->uDirectVecBias, psBiasParams->iInterMBBiasB); abort(); } uDirectVecBias_B = psBiasParams->uDirectVecBias; iInterMBBias_B = psBiasParams->iInterMBBiasB; if (psBiasParams->uIPESkipVecBias == UNINIT_PARAM || psBiasParams->iInterMBBias == UNINIT_PARAM) { drv_debug_msg(VIDEO_DEBUG_GENERAL, "ERROR: Bias for I/P pictures not set up ... uIPESkipVecBias = 0x%x, iInterMBBias = 0x%x\n", psBiasParams->uIPESkipVecBias, psBiasParams->iInterMBBias); abort(); } uDirectVecBias_P = psBiasParams->uIPESkipVecBias; iInterMBBias_P = psBiasParams->iInterMBBias; iIntra16Bias = psBiasParams->iIntra16Bias; uisz2 = psBiasParams->uisz2; } #ifdef BRN_30029 //adjust the intra8x8 bias so that we don't do anything silly when 8x8 mode is not in use. if (ctx->ui32PredCombControl & F_ENCODE(1, TOPAZHP_CR_INTRA8X8_DISABLE)) { iIntra16Bias |= 0x7fff << 16; } #endif // drv_debug_msg(VIDEO_DEBUG_GENERAL, "qp %d, iIntra16Bias %d, iInterMBBias %d, uDirectVecBias %d\n", qp, iIntra16Bias, iInterMBBias, uDirectVecBias); ctx->sBiasTables.aui32IntraBias[n] = iIntra16Bias; ctx->sBiasTables.aui32InterBias_P[n] = iInterMBBias_P; ctx->sBiasTables.aui32DirectBias_P[n] = uDirectVecBias_P; ctx->sBiasTables.aui32InterBias_B[n] = iInterMBBias_B; ctx->sBiasTables.aui32DirectBias_B[n] = uDirectVecBias_B; ctx->sBiasTables.aui32IntraScale[n] = uIntra8Scale; } if (psBiasParams->bRCEnable || psBiasParams->bRCBiases) ctx->sBiasTables.ui32sz1 = psBiasParams->uisz1; else ctx->sBiasTables.ui32sz1 = psBiasParams->uisz2; if (psBiasParams->bZeroDetectionDisable) { ctx->sBiasTables.ui32RejectThresholdH264 = F_ENCODE(0, INTEL_H264_ConfigReg1) | F_ENCODE(0, INTEL_H264_ConfigReg2); } else { ctx->sBiasTables.ui32RejectThresholdH264 = F_ENCODE(psBiasParams->uzb4, INTEL_H264_ConfigReg1) | F_ENCODE(psBiasParams->uzb8, INTEL_H264_ConfigReg2); } } /************************************************************************************************** * Function: VIDEO_GenerateBias * Description: Generate the bias tables * ***************************************************************************************************/ VAStatus tng__generate_bias(context_ENC_p ctx) { assert(ctx); switch (ctx->eStandard) { case IMG_STANDARD_H264: tng__H264ES_generate_bias_tables(ctx); break; case IMG_STANDARD_H263: tng__H263ES_generate_bias_tables(ctx); break; case IMG_STANDARD_MPEG4: tng__MPEG4ES_generate_bias_tables(ctx); break; /* case IMG_STANDARD_MPEG2: MPEG2_GenerateBiasTables(ctx, psBiasParams); break; */ default: break; } return VA_STATUS_SUCCESS; } //load bias static IMG_INT H264_LAMBDA_COEFFS[4][3] = { {175, -10166, 163244 }, //SATD Lambda High { 16, -236, 8693 }, //SATD Lambda Low {198, -12240, 198865 }, //SAD Lambda High { 12, -176, 1402 }, //SAD Lambda Low }; static IMG_INT MPEG4_LAMBDA_COEFFS[3] = { 0, 458, 1030 }; static IMG_INT H263_LAMBDA_COEFFS[3] = { 0, 333, 716 }; static void tng__H263ES_load_bias_tables( context_ENC_p ctx, IMG_FRAME_TYPE __maybe_unused eFrameType) { IMG_INT32 n; IMG_UINT32 ui32RegVal; IMG_UINT32 count = 0, cmd_word = 0; tng_cmdbuf_p cmdbuf = ctx->obj_context->tng_cmdbuf; IMG_BIAS_TABLES* psBiasTables = &(ctx->sBiasTables); IMG_UINT32 *pCount; IMG_UINT32 ui8Pipe; cmd_word = (MTX_CMDID_SW_WRITEREG & MTX_CMDWORD_ID_MASK) << MTX_CMDWORD_ID_SHIFT; *cmdbuf->cmd_idx++ = cmd_word; pCount = cmdbuf->cmd_idx; cmdbuf->cmd_idx++; ctx->ui32CoreRev = 0x00030401; for (ui8Pipe = 0; ui8Pipe < ctx->ui8PipesToUse; ui8Pipe++) tng_cmdbuf_insert_reg_write(TOPAZ_CORE_REG, TOPAZHP_CR_SEQUENCER_CONFIG, 0, psBiasTables->ui32SeqConfigInit); if (ctx->ui32CoreRev <= MAX_32_REV) { for(n=31;n>=1;n--) { //FIXME: Zhaohan, missing register TOPAZHP_TOP_CR_LAMBDA_DC_TABLE //tng_cmdbuf_insert_reg_write(TOPAZHP_TOP_CR_LAMBDA_DC_TABLE, 0, psBiasTables->aui32LambdaBias[n]); } } else { ui32RegVal = (((H263_LAMBDA_COEFFS[0]) << (SHIFT_TOPAZHP_TOP_CR_POLYNOM_ALPHA_COEFF_CORE_00)) & (MASK_TOPAZHP_TOP_CR_POLYNOM_ALPHA_COEFF_CORE_00)); ui32RegVal |= (((H263_LAMBDA_COEFFS[1]) << (SHIFT_TOPAZHP_TOP_CR_POLYNOM_BETA_COEFF_CORE_00)) & (MASK_TOPAZHP_TOP_CR_POLYNOM_BETA_COEFF_CORE_00)); tng_cmdbuf_insert_reg_write(TOPAZ_MULTICORE_REG, TOPAZHP_TOP_CR_POLYNOM_ALPHA_COEFF_CORE_0, 0, ui32RegVal); ui32RegVal = (((H263_LAMBDA_COEFFS[2]) << (SHIFT_TOPAZHP_TOP_CR_POLYNOM_GAMMA_COEFF_CORE_01)) & (MASK_TOPAZHP_TOP_CR_POLYNOM_GAMMA_COEFF_CORE_01)); tng_cmdbuf_insert_reg_write(TOPAZ_MULTICORE_REG, TOPAZHP_TOP_CR_POLYNOM_GAMMA_COEFF_CORE_0, 0, ui32RegVal); ui32RegVal = 0x3f; tng_cmdbuf_insert_reg_write(TOPAZ_MULTICORE_REG, TOPAZHP_TOP_CR_POLYNOM_CUTOFF_CORE_0, 0, ui32RegVal); } for(n=31;n>=1;n-=2) { tng_cmdbuf_insert_reg_write(TOPAZ_MULTICORE_REG, TOPAZHP_TOP_CR_INTRA_BIAS_TABLE, 0, psBiasTables->aui32IntraBias[n]); tng_cmdbuf_insert_reg_write(TOPAZ_MULTICORE_REG, TOPAZHP_TOP_CR_INTER_BIAS_TABLE, 0, psBiasTables->aui32InterBias_P[n]); tng_cmdbuf_insert_reg_write(TOPAZ_MULTICORE_REG, TOPAZHP_TOP_CR_DIRECT_BIAS_TABLE, 0, psBiasTables->aui32DirectBias_P[n]); } for (ui8Pipe = 0; ui8Pipe < ctx->ui8PipesToUse; ui8Pipe++) { tng_cmdbuf_insert_reg_write(TOPAZ_CORE_REG, INTEL_SZ, 0, psBiasTables->ui32sz1); } for (ui8Pipe = 0; ui8Pipe < ctx->ui8PipesToUse; ui8Pipe++) tng_cmdbuf_insert_reg_write(TOPAZ_CORE_REG, INTEL_CHCF, 0, psBiasTables->ui32LritcCacheChunkConfig); *pCount = count; } static void tng__MPEG4_load_bias_tables(context_ENC_p ctx) { IMG_INT32 n; IMG_UINT32 ui32RegVal; IMG_UINT32 count = 0, cmd_word = 0; tng_cmdbuf_p cmdbuf = ctx->obj_context->tng_cmdbuf; IMG_BIAS_TABLES* psBiasTables = &(ctx->sBiasTables); IMG_UINT32 *pCount; IMG_UINT8 ui8Pipe; cmd_word = (MTX_CMDID_SW_WRITEREG & MTX_CMDWORD_ID_MASK) << MTX_CMDWORD_ID_SHIFT; *cmdbuf->cmd_idx++ = cmd_word; pCount = cmdbuf->cmd_idx; cmdbuf->cmd_idx++; ctx->ui32CoreRev = 0x00030401; for (ui8Pipe = 0; ui8Pipe < ctx->ui8PipesToUse; ui8Pipe++) tng_cmdbuf_insert_reg_write(TOPAZ_CORE_REG, TOPAZHP_CR_SEQUENCER_CONFIG, 0, psBiasTables->ui32SeqConfigInit); if (ctx->ui32CoreRev <= MAX_32_REV) { for (n=31; n >= 1; n--) { //FIXME: Zhaohan, missing register TOPAZHP_TOP_CR_LAMBDA_DC_TABLE //tng_cmdbuf_insert_reg_write(TOPAZHP_TOP_CR_LAMBDA_DC_TABLE, 0, psBiasTables->aui32LambdaBias[n]); } } else { //ui32RegVal = MPEG4_LAMBDA_COEFFS[0]| (MPEG4_LAMBDA_COEFFS[1]<<8); ui32RegVal = (((MPEG4_LAMBDA_COEFFS[0]) << (SHIFT_TOPAZHP_TOP_CR_POLYNOM_ALPHA_COEFF_CORE_00)) & (MASK_TOPAZHP_TOP_CR_POLYNOM_ALPHA_COEFF_CORE_00)); ui32RegVal |= (((MPEG4_LAMBDA_COEFFS[1]) << (SHIFT_TOPAZHP_TOP_CR_POLYNOM_BETA_COEFF_CORE_00)) & (MASK_TOPAZHP_TOP_CR_POLYNOM_BETA_COEFF_CORE_00)); tng_cmdbuf_insert_reg_write(TOPAZ_MULTICORE_REG, TOPAZHP_TOP_CR_POLYNOM_ALPHA_COEFF_CORE_0, 0, ui32RegVal); //ui32RegVal = MPEG4_LAMBDA_COEFFS[2]; ui32RegVal = (((MPEG4_LAMBDA_COEFFS[2]) << (SHIFT_TOPAZHP_TOP_CR_POLYNOM_GAMMA_COEFF_CORE_01)) & (MASK_TOPAZHP_TOP_CR_POLYNOM_GAMMA_COEFF_CORE_01)); tng_cmdbuf_insert_reg_write(TOPAZ_MULTICORE_REG, TOPAZHP_TOP_CR_POLYNOM_GAMMA_COEFF_CORE_0, 0, ui32RegVal); ui32RegVal = 0x3f; tng_cmdbuf_insert_reg_write(TOPAZ_MULTICORE_REG, TOPAZHP_TOP_CR_POLYNOM_CUTOFF_CORE_0, 0, ui32RegVal); } for(n=31;n>=1;n-=2) { tng_cmdbuf_insert_reg_write(TOPAZ_MULTICORE_REG, TOPAZHP_TOP_CR_INTRA_BIAS_TABLE, 0, psBiasTables->aui32IntraBias[n]); tng_cmdbuf_insert_reg_write(TOPAZ_MULTICORE_REG, TOPAZHP_TOP_CR_INTER_BIAS_TABLE, 0, psBiasTables->aui32InterBias_P[n]); tng_cmdbuf_insert_reg_write(TOPAZ_MULTICORE_REG, TOPAZHP_TOP_CR_DIRECT_BIAS_TABLE, 0, psBiasTables->aui32DirectBias_P[n]); } for (ui8Pipe = 0; ui8Pipe < ctx->ui8PipesToUse; ui8Pipe++) { tng_cmdbuf_insert_reg_write(TOPAZ_CORE_REG, INTEL_SZ, 0, psBiasTables->ui32sz1); //VLC RSize is fcode - 1 and only done for mpeg4 AND mpeg2 not H263 tng_cmdbuf_insert_reg_write(TOPAZ_VLC_REG, TOPAZ_VLC_CR_VLC_MPEG4_CFG, 0, F_ENCODE(psBiasTables->ui32FCode - 1, TOPAZ_VLC_CR_RSIZE)); } for (ui8Pipe = 0; ui8Pipe < ctx->ui8PipesToUse; ui8Pipe++) tng_cmdbuf_insert_reg_write(TOPAZ_CORE_REG, INTEL_CHCF, 0, psBiasTables->ui32LritcCacheChunkConfig); *pCount = count; } static void tng__H264ES_load_bias_tables( context_ENC_p ctx, IMG_FRAME_TYPE eFrameType) { IMG_INT32 n; IMG_UINT32 ui32RegVal; IMG_BIAS_TABLES* psBiasTables = &(ctx->sBiasTables); tng_cmdbuf_p cmdbuf = ctx->obj_context->tng_cmdbuf; IMG_UINT32 count = 0, cmd_word = 0; IMG_UINT32 *pCount; IMG_UINT32 ui8Pipe; drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: start\n", __FUNCTION__); cmd_word = (MTX_CMDID_SW_WRITEREG & MTX_CMDWORD_ID_MASK) << MTX_CMDWORD_ID_SHIFT; *cmdbuf->cmd_idx++ = cmd_word; pCount = cmdbuf->cmd_idx; cmdbuf->cmd_idx++; psBiasTables->ui32SeqConfigInit = 0x40038412; for (ui8Pipe = 0; ui8Pipe < ctx->ui8PipesToUse; ui8Pipe++) tng_cmdbuf_insert_reg_write(TOPAZ_CORE_REG, TOPAZHP_CR_SEQUENCER_CONFIG, 0, psBiasTables->ui32SeqConfigInit); ctx->ui32CoreRev = 0x00030401; if (ctx->ui32CoreRev <= MAX_32_REV) { for (n=51; n >= 0; n--) { //FIXME: Zhaohan, missing register TOPAZHP_TOP_CR_LAMBDA_DC_TABLE //tng_cmdbuf_insert_reg_write(TOPAZHP_TOP_CR_LAMBDA_DC_TABLE, 0, psBiasTables->aui32LambdaBias[n]); } } else { //Load the lambda coeffs for (n = 0; n < 4; n++) { //ui32RegVal = H264_LAMBDA_COEFFS[n][0]| (H264_LAMBDA_COEFFS[n][1]<<8); ui32RegVal = (((H264_LAMBDA_COEFFS[n][0]) << (SHIFT_TOPAZHP_TOP_CR_POLYNOM_ALPHA_COEFF_CORE_00)) & (MASK_TOPAZHP_TOP_CR_POLYNOM_ALPHA_COEFF_CORE_00)); ui32RegVal |= (((H264_LAMBDA_COEFFS[n][1]) << (SHIFT_TOPAZHP_TOP_CR_POLYNOM_BETA_COEFF_CORE_00)) & (MASK_TOPAZHP_TOP_CR_POLYNOM_BETA_COEFF_CORE_00)); tng_cmdbuf_insert_reg_write(TOPAZ_MULTICORE_REG, TOPAZHP_TOP_CR_POLYNOM_ALPHA_COEFF_CORE_0, 0, ui32RegVal); tng_cmdbuf_insert_reg_write(TOPAZ_MULTICORE_REG, TOPAZHP_TOP_CR_POLYNOM_ALPHA_COEFF_CORE_1, 0, ui32RegVal); tng_cmdbuf_insert_reg_write(TOPAZ_MULTICORE_REG, TOPAZHP_TOP_CR_POLYNOM_ALPHA_COEFF_CORE_2, 0, ui32RegVal); //ui32RegVal = H264_LAMBDA_COEFFS[n][2]; ui32RegVal = (((H264_LAMBDA_COEFFS[n][2]) << (SHIFT_TOPAZHP_TOP_CR_POLYNOM_GAMMA_COEFF_CORE_01)) & (MASK_TOPAZHP_TOP_CR_POLYNOM_GAMMA_COEFF_CORE_01)); tng_cmdbuf_insert_reg_write(TOPAZ_MULTICORE_REG, TOPAZHP_TOP_CR_POLYNOM_GAMMA_COEFF_CORE_0, 0, ui32RegVal); tng_cmdbuf_insert_reg_write(TOPAZ_MULTICORE_REG, TOPAZHP_TOP_CR_POLYNOM_GAMMA_COEFF_CORE_1, 0, ui32RegVal); tng_cmdbuf_insert_reg_write(TOPAZ_MULTICORE_REG, TOPAZHP_TOP_CR_POLYNOM_GAMMA_COEFF_CORE_2, 0, ui32RegVal); } ui32RegVal = 29 |(29<<6); tng_cmdbuf_insert_reg_write(TOPAZ_MULTICORE_REG, TOPAZHP_TOP_CR_POLYNOM_CUTOFF_CORE_0, 0, ui32RegVal); tng_cmdbuf_insert_reg_write(TOPAZ_MULTICORE_REG, TOPAZHP_TOP_CR_POLYNOM_CUTOFF_CORE_1, 0, ui32RegVal); tng_cmdbuf_insert_reg_write(TOPAZ_MULTICORE_REG, TOPAZHP_TOP_CR_POLYNOM_CUTOFF_CORE_2, 0, ui32RegVal); } for (n=52;n>=0;n-=2) { if (eFrameType == IMG_INTER_B) { tng_cmdbuf_insert_reg_write(TOPAZ_MULTICORE_REG, TOPAZHP_TOP_CR_INTER_BIAS_TABLE, 0, psBiasTables->aui32InterBias_B[n]); tng_cmdbuf_insert_reg_write(TOPAZ_MULTICORE_REG, TOPAZHP_TOP_CR_DIRECT_BIAS_TABLE, 0, psBiasTables->aui32DirectBias_B[n]); } else { tng_cmdbuf_insert_reg_write(TOPAZ_MULTICORE_REG, TOPAZHP_TOP_CR_INTER_BIAS_TABLE, 0, psBiasTables->aui32InterBias_P[n]); tng_cmdbuf_insert_reg_write(TOPAZ_MULTICORE_REG, TOPAZHP_TOP_CR_DIRECT_BIAS_TABLE, 0, psBiasTables->aui32DirectBias_P[n]); } tng_cmdbuf_insert_reg_write(TOPAZ_MULTICORE_REG, TOPAZHP_TOP_CR_INTRA_BIAS_TABLE, 0, psBiasTables->aui32IntraBias[n]); tng_cmdbuf_insert_reg_write(TOPAZ_MULTICORE_REG, TOPAZHP_TOP_CR_INTRA_SCALE_TABLE, 0, psBiasTables->aui32IntraScale[n]); } //aui32HpCoreRegId[ui32Pipe] for (ui8Pipe = 0; ui8Pipe < ctx->ui8PipesToUse; ui8Pipe++) { tng_cmdbuf_insert_reg_write(TOPAZ_CORE_REG, INTEL_SZ, 0, psBiasTables->ui32sz1); tng_cmdbuf_insert_reg_write(TOPAZ_CORE_REG, INTEL_H264_RT, 0, psBiasTables->ui32RejectThresholdH264); } // tng_cmdbuf_insert_reg_write(TOPAZHP_TOP_CR_FIRMWARE_REG_1, (MTX_SCRATCHREG_TOMTX<<2), ui32BuffersReg); // tng_cmdbuf_insert_reg_write(TOPAZHP_TOP_CR_FIRMWARE_REG_1, (MTX_SCRATCHREG_TOHOST<<2),ui32ToHostReg); // now setup the LRITC chache priority { //aui32HpCoreRegId[ui32Pipe] for (ui8Pipe = 0; ui8Pipe < ctx->ui8PipesToUse; ui8Pipe++) { tng_cmdbuf_insert_reg_write(TOPAZ_CORE_REG, INTEL_CHCF, 0, psBiasTables->ui32LritcCacheChunkConfig); } } drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: count = %d\n", __FUNCTION__, (int)count); *pCount = count; } VAStatus tng_load_bias(context_ENC_p ctx, IMG_FRAME_TYPE eFrameType) { IMG_STANDARD eStandard = ctx->eStandard; switch (eStandard) { case IMG_STANDARD_H264: tng__H264ES_load_bias_tables(ctx, eFrameType); //IMG_INTER_P); break; case IMG_STANDARD_H263: tng__H263ES_load_bias_tables(ctx, eFrameType); //IMG_INTER_P); break; case IMG_STANDARD_MPEG4: tng__MPEG4_load_bias_tables(ctx); break; /* case IMG_STANDARD_MPEG2: tng__MPEG2_LoadBiasTables(psBiasTables); break; */ default: break; } return VA_STATUS_SUCCESS; } void tng_init_bias_params(context_ENC_p ctx) { IMG_BIAS_PARAMS * psBiasParams = &(ctx->sBiasParams); memset(psBiasParams, 0, sizeof(IMG_BIAS_PARAMS)); //default psBiasParams->uLambdaSAD = 0; psBiasParams->uLambdaSATD = 0; psBiasParams->uLambdaSATDTable = 0; psBiasParams->bRCEnable = ctx->sRCParams.bRCEnable; psBiasParams->bRCBiases = IMG_TRUE; psBiasParams->iIntra16Bias = UNINIT_PARAM; psBiasParams->iInterMBBias = UNINIT_PARAM; psBiasParams->iInterMBBiasB = UNINIT_PARAM; psBiasParams->uDirectVecBias = UNINIT_PARAM; psBiasParams->uIPESkipVecBias = UNINIT_PARAM; psBiasParams->uSPESkipVecBias = 0; //not in spec psBiasParams->uisz1 = 6; psBiasParams->uisz2 = 6; psBiasParams->bZeroDetectionDisable = TOPAZHP_DEFAULT_bZeroDetectionDisable; psBiasParams->uzb4 = 6; psBiasParams->uzb8 = 4; psBiasParams->uTHInter = TOPAZHP_DEFAULT_uTHInter; psBiasParams->uTHInterQP = TOPAZHP_DEFAULT_uTHInterQP; psBiasParams->uTHInterMaxLevel = TOPAZHP_DEFAULT_uTHInterMaxLevel; psBiasParams->uTHSkipIPE = TOPAZHP_DEFAULT_uTHSkipIPE; psBiasParams->uTHSkipSPE = TOPAZHP_DEFAULT_uTHSkipSPE; }