/*
* 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;
}