OMXResult omxVCM4P2_QuantInvInter_I( OMX_S16 * pSrcDst, OMX_INT QP ) { OMX_INT coeffCount, Sign; /* Argument error checks */ armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(((QP <= 0) || (QP >= 32)), OMX_Sts_BadArgErr); /* Second Inverse quantisation method */ for (coeffCount = 0; coeffCount < 64; coeffCount++) { /* check sign */ Sign = armSignCheck (pSrcDst[coeffCount]); /* Quantize the coeff */ if (QP & 0x1) { pSrcDst[coeffCount] = (2* armAbs(pSrcDst[coeffCount]) + 1) * QP; pSrcDst[coeffCount] *= Sign; } else { pSrcDst[coeffCount] = (2* armAbs(pSrcDst[coeffCount]) + 1) * QP - 1; pSrcDst[coeffCount] *= Sign; } /* Saturate */ pSrcDst[coeffCount] = armClip (-2048, 2047, pSrcDst[coeffCount]); } return OMX_Sts_NoErr; }
OMXResult omxVCM4P2_QuantInter_I( OMX_S16 * pSrcDst, OMX_U8 QP, OMX_INT shortVideoHeader ) { /* Definitions and Initializations*/ OMX_INT coeffCount; OMX_INT fSign; OMX_INT maxClpAC = 0, minClpAC = 0; OMX_INT maxClpDC = 0, minClpDC = 0; /* Argument error checks */ armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(((QP <= 0) || (QP >= 32)), OMX_Sts_BadArgErr); /* One argument check is delayed until we have ascertained that */ /* pQMatrix is not NULL. */ /* Set the Clip Range based on SVH on/off */ if(shortVideoHeader == 1) { maxClpDC = 254; minClpDC = 1; maxClpAC = 127; minClpAC = -127; } else { maxClpDC = 2047; minClpDC = -2047; maxClpAC = 2047; minClpAC = -2047; } /* Second Inverse quantisation method */ for (coeffCount = 0; coeffCount < 64; coeffCount++) { fSign = armSignCheck (pSrcDst[coeffCount]); pSrcDst[coeffCount] = (armAbs(pSrcDst[coeffCount]) - (QP/2))/(2 * QP); pSrcDst[coeffCount] *= fSign; /* Clip */ if (coeffCount == 0) { pSrcDst[coeffCount] = (OMX_S16) armClip (minClpDC, maxClpDC, pSrcDst[coeffCount]); } else { pSrcDst[coeffCount] = (OMX_S16) armClip (minClpAC, maxClpAC, pSrcDst[coeffCount]); } } return OMX_Sts_NoErr; }
OMXResult armVCM4P2_SetPredDir( OMX_INT blockIndex, OMX_S16 *pCoefBufRow, OMX_S16 *pCoefBufCol, OMX_INT *predDir, OMX_INT *predQP, const OMX_U8 *pQpBuf ) { OMX_U8 blockDCLeft; OMX_U8 blockDCTop; OMX_U8 blockDCTopLeft; if (blockIndex == 3) { blockDCTop = *(pCoefBufCol - 8); } else { blockDCTop = *pCoefBufRow; } blockDCLeft = *pCoefBufCol; blockDCTopLeft = *(pCoefBufRow - 8); if (armAbs(blockDCLeft - blockDCTopLeft) < armAbs(blockDCTopLeft \ - blockDCTop)) { *predDir = OMX_VC_VERTICAL; *predQP = pQpBuf[1]; } else { *predDir = OMX_VC_HORIZONTAL; *predQP = pQpBuf[0]; } return OMX_Sts_NoErr; }
static OMX_U16 armVCM4P10_ExpGolBitsUsed (OMX_S16 val) { OMX_U16 sizeCodeNum, codeNum; /* Mapping val to codeNum */ codeNum = armAbs (val); if (val > 0) { codeNum = (2 * codeNum) - 1; } else { codeNum = 2 * codeNum; } /* Size of the exp-golomb code */ sizeCodeNum = (2 * armLogSize (codeNum + 1)) - 1; return sizeCodeNum; }
OMXResult omxVCM4P2_QuantIntra_I( OMX_S16 * pSrcDst, OMX_U8 QP, OMX_INT blockIndex, OMX_INT shortVideoHeader ) { /* Definitions and Initializations*/ /* Initialized to remove compilation error */ OMX_INT dcScaler = 0, coeffCount,fSign; OMX_INT maxClpAC, minClpAC; /* Argument error checks */ armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(((blockIndex < 0) || (blockIndex >= 10)), OMX_Sts_BadArgErr); armRetArgErrIf(((QP <= 0) || (QP >= 32)), OMX_Sts_BadArgErr); /* One argument check is delayed until we have ascertained that */ /* pQMatrix is not NULL. */ /* Set the Clip Range based on SVH on/off */ if(shortVideoHeader == 1) { maxClpAC = 127; minClpAC = -127; dcScaler = 8; /* Dequant the DC value, this applies to both the methods */ pSrcDst[0] = armIntDivAwayFromZero (pSrcDst[0], dcScaler); /* Clip between 1 and 254 */ pSrcDst[0] = (OMX_S16) armClip (1, 254, pSrcDst[0]); } else { maxClpAC = 2047; minClpAC = -2047; /* Calculate the DC scaler value */ if ((blockIndex < 4) || (blockIndex > 5)) { if (QP >= 1 && QP <= 4) { dcScaler = 8; } else if (QP >= 5 && QP <= 8) { dcScaler = 2 * QP; } else if (QP >= 9 && QP <= 24) { dcScaler = QP + 8; } else { dcScaler = (2 * QP) - 16; } } else if (blockIndex < 6) { if (QP >= 1 && QP <= 4) { dcScaler = 8; } else if (QP >= 5 && QP <= 24) { dcScaler = (QP + 13)/2; } else { dcScaler = QP - 6; } } /* Dequant the DC value, this applies to both the methods */ pSrcDst[0] = armIntDivAwayFromZero (pSrcDst[0], dcScaler); } /* Second Inverse quantisation method */ for (coeffCount = 1; coeffCount < 64; coeffCount++) { fSign = armSignCheck (pSrcDst[coeffCount]); pSrcDst[coeffCount] = armAbs(pSrcDst[coeffCount])/(2 * QP); pSrcDst[coeffCount] *= fSign; /* Clip */ pSrcDst[coeffCount] = (OMX_S16) armClip (minClpAC, maxClpAC, pSrcDst[coeffCount]); } return OMX_Sts_NoErr; }
OMXResult omxVCM4P2_MotionEstimationMB ( const OMX_U8 *pSrcCurrBuf, OMX_S32 srcCurrStep, const OMX_U8 *pSrcRefBuf, OMX_S32 srcRefStep, const OMXRect*pRefRect, const OMXVCM4P2Coordinate *pCurrPointPos, void *pMESpec, const OMXVCM4P2MBInfoPtr *pMBInfo, OMXVCM4P2MBInfo *pSrcDstMBCurr, OMX_U16 *pDstSAD, OMX_U16 *pDstBlockSAD ) { OMX_INT intraSAD, average, count, index, x, y; OMXVCMotionVector dstMV16x16; OMX_INT dstSAD16x16; OMX_INT dstSAD8x8; OMXVCM4P2MEParams *pMEParams; OMXVCM4P2Coordinate TempCurrPointPos; OMXVCM4P2Coordinate *pTempCurrPointPos; OMX_U8 aTempSrcCurrBuf[271]; OMX_U8 *pTempSrcCurrBuf; OMX_U8 *pDst; OMX_U8 aDst[71]; OMX_S32 dstStep = 8; OMX_INT predictType; OMX_S32 Sad; const OMX_U8 *pTempSrcRefBuf; OMXVCMotionVector* pSrcCandMV1[4]; OMXVCMotionVector* pSrcCandMV2[4]; OMXVCMotionVector* pSrcCandMV3[4]; /* Argument error checks */ armRetArgErrIf(!armIs16ByteAligned(pSrcCurrBuf), OMX_Sts_BadArgErr); armRetArgErrIf(!armIs16ByteAligned(pSrcRefBuf), OMX_Sts_BadArgErr); armRetArgErrIf(((srcCurrStep % 16) || (srcRefStep % 16)), OMX_Sts_BadArgErr); armRetArgErrIf(pSrcCurrBuf == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pSrcRefBuf == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pRefRect == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pCurrPointPos == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pSrcDstMBCurr == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr); pTempCurrPointPos = &(TempCurrPointPos); pTempSrcCurrBuf = armAlignTo16Bytes(aTempSrcCurrBuf); pMEParams = (OMXVCM4P2MEParams *)pMESpec; pTempCurrPointPos->x = pCurrPointPos->x; pTempCurrPointPos->y = pCurrPointPos->y; pSrcDstMBCurr->mbType = OMX_VC_INTER; /* Preparing a linear buffer for block match */ for (y = 0, index = count = 0; y < 16; y++, index += srcCurrStep - 16) { for(x = 0; x < 16; x++, count++, index++) { pTempSrcCurrBuf[count] = pSrcCurrBuf[index]; } } for(y = 0, index = 0; y < 2; y++) { for(x = 0; x < 2; x++,index++) { if((pMBInfo[0] != NULL) && (pMBInfo[0]->mbType != OMX_VC_INTRA)) { pSrcCandMV1[index] = &(pMBInfo[0]->pMV0[y][x]); } else { pSrcCandMV1[index] = NULL; } if((pMBInfo[1] != NULL) && (pMBInfo[1]->mbType != OMX_VC_INTRA)) { pSrcCandMV2[index] = &(pMBInfo[1]->pMV0[y][x]); } else { pSrcCandMV2[index] = NULL; } if((pMBInfo[3] != NULL) && (pMBInfo[3]->mbType != OMX_VC_INTRA)) { pSrcCandMV3[index] = &(pMBInfo[3]->pMV0[y][x]); } else { pSrcCandMV3[index] = NULL; } } } /* Calculating SAD at MV(0,0) */ armVCCOMM_SAD(pTempSrcCurrBuf, 16, pSrcRefBuf, srcRefStep, &Sad, 16, 16); *pDstSAD = Sad; /* Mode decision for NOT_CODED MB */ if(*pDstSAD == 0) { pSrcDstMBCurr->pMV0[0][0].dx = 0; pSrcDstMBCurr->pMV0[0][0].dy = 0; *pDstSAD = 0; return OMX_Sts_NoErr; } omxVCM4P2_FindMVpred( &(pSrcDstMBCurr->pMV0[0][0]), pSrcCandMV1[0], pSrcCandMV2[0], pSrcCandMV3[0], &(pSrcDstMBCurr->pMVPred[0][0]), NULL, 0); /* Inter 1 MV */ armVCM4P2_BlockMatch_16x16( pSrcRefBuf, srcRefStep, pRefRect, pTempSrcCurrBuf, pCurrPointPos, &(pSrcDstMBCurr->pMVPred[0][0]), NULL, pMEParams, &dstMV16x16, &dstSAD16x16); /* Initialize all with 1 MV values */ pSrcDstMBCurr->pMV0[0][0].dx = dstMV16x16.dx; pSrcDstMBCurr->pMV0[0][0].dy = dstMV16x16.dy; pSrcDstMBCurr->pMV0[0][1].dx = dstMV16x16.dx; pSrcDstMBCurr->pMV0[0][1].dy = dstMV16x16.dy; pSrcDstMBCurr->pMV0[1][0].dx = dstMV16x16.dx; pSrcDstMBCurr->pMV0[1][0].dy = dstMV16x16.dy; pSrcDstMBCurr->pMV0[1][1].dx = dstMV16x16.dx; pSrcDstMBCurr->pMV0[1][1].dy = dstMV16x16.dy; *pDstSAD = dstSAD16x16; if (pMEParams->searchEnable8x8) { /* Inter 4MV */ armVCM4P2_BlockMatch_8x8 (pSrcRefBuf, srcRefStep, pRefRect, pTempSrcCurrBuf, pTempCurrPointPos, &(pSrcDstMBCurr->pMVPred[0][0]), NULL, pMEParams, &(pSrcDstMBCurr->pMV0[0][0]), &dstSAD8x8 ); pDstBlockSAD[0] = dstSAD8x8; *pDstSAD = dstSAD8x8; pTempCurrPointPos->x += 8; pSrcRefBuf += 8; omxVCM4P2_FindMVpred( &(pSrcDstMBCurr->pMV0[0][1]), pSrcCandMV1[1], pSrcCandMV2[1], pSrcCandMV3[1], &(pSrcDstMBCurr->pMVPred[0][1]), NULL, 1); armVCM4P2_BlockMatch_8x8 (pSrcRefBuf, srcRefStep, pRefRect, pTempSrcCurrBuf, pTempCurrPointPos, &(pSrcDstMBCurr->pMVPred[0][1]), NULL, pMEParams, &(pSrcDstMBCurr->pMV0[0][1]), &dstSAD8x8 ); pDstBlockSAD[1] = dstSAD8x8; *pDstSAD += dstSAD8x8; pTempCurrPointPos->x -= 8; pTempCurrPointPos->y += 8; pSrcRefBuf += (srcRefStep * 8) - 8; omxVCM4P2_FindMVpred( &(pSrcDstMBCurr->pMV0[1][0]), pSrcCandMV1[2], pSrcCandMV2[2], pSrcCandMV3[2], &(pSrcDstMBCurr->pMVPred[1][0]), NULL, 2); armVCM4P2_BlockMatch_8x8 (pSrcRefBuf, srcRefStep, pRefRect, pTempSrcCurrBuf, pTempCurrPointPos, &(pSrcDstMBCurr->pMVPred[1][0]), NULL, pMEParams, &(pSrcDstMBCurr->pMV0[1][0]), &dstSAD8x8 ); pDstBlockSAD[2] = dstSAD8x8; *pDstSAD += dstSAD8x8; pTempCurrPointPos->x += 8; pSrcRefBuf += 8; omxVCM4P2_FindMVpred( &(pSrcDstMBCurr->pMV0[1][1]), pSrcCandMV1[3], pSrcCandMV2[3], pSrcCandMV3[3], &(pSrcDstMBCurr->pMVPred[1][1]), NULL, 3); armVCM4P2_BlockMatch_8x8 (pSrcRefBuf, srcRefStep, pRefRect, pTempSrcCurrBuf, pTempCurrPointPos, &(pSrcDstMBCurr->pMVPred[1][1]), NULL, pMEParams, &(pSrcDstMBCurr->pMV0[1][1]), &dstSAD8x8 ); pDstBlockSAD[3] = dstSAD8x8; *pDstSAD += dstSAD8x8; /* Checking if 4MV is equal to 1MV */ if ( (pSrcDstMBCurr->pMV0[0][0].dx != dstMV16x16.dx) || (pSrcDstMBCurr->pMV0[0][0].dy != dstMV16x16.dy) || (pSrcDstMBCurr->pMV0[0][1].dx != dstMV16x16.dx) || (pSrcDstMBCurr->pMV0[0][1].dy != dstMV16x16.dy) || (pSrcDstMBCurr->pMV0[1][0].dx != dstMV16x16.dx) || (pSrcDstMBCurr->pMV0[1][0].dy != dstMV16x16.dy) || (pSrcDstMBCurr->pMV0[1][1].dx != dstMV16x16.dx) || (pSrcDstMBCurr->pMV0[1][1].dy != dstMV16x16.dy) ) { /* select the 4 MV */ pSrcDstMBCurr->mbType = OMX_VC_INTER4V; } } /* finding the error in intra mode */ for (count = 0, average = 0; count < 256 ; count++) { average = average + pTempSrcCurrBuf[count]; } average = average/256; intraSAD = 0; /* Intra SAD calculation */ for (count = 0; count < 256 ; count++) { intraSAD += armAbs ((pTempSrcCurrBuf[count]) - (average)); } /* Using the MPEG4 VM formula for intra/inter mode decision Var < (SAD - 2*NB) where NB = N^2 is the number of pixels of the macroblock.*/ if (intraSAD <= (*pDstSAD - 512)) { pSrcDstMBCurr->mbType = OMX_VC_INTRA; pSrcDstMBCurr->pMV0[0][0].dx = 0; pSrcDstMBCurr->pMV0[0][0].dy = 0; *pDstSAD = intraSAD; pDstBlockSAD[0] = 0xFFFF; pDstBlockSAD[1] = 0xFFFF; pDstBlockSAD[2] = 0xFFFF; pDstBlockSAD[3] = 0xFFFF; } if(pSrcDstMBCurr->mbType == OMX_VC_INTER) { pTempSrcRefBuf = pSrcRefBuf + (srcRefStep * dstMV16x16.dy) + dstMV16x16.dx; if((dstMV16x16.dx & 0x1) && (dstMV16x16.dy & 0x1)) { predictType = OMX_VC_HALF_PIXEL_XY; } else if(dstMV16x16.dx & 0x1) { predictType = OMX_VC_HALF_PIXEL_X; } else if(dstMV16x16.dy & 0x1) { predictType = OMX_VC_HALF_PIXEL_Y; } else { predictType = OMX_VC_INTEGER_PIXEL; } pDst = armAlignTo8Bytes(&(aDst[0])); /* Calculating Block SAD at MV(dstMV16x16.dx,dstMV16x16.dy) */ /* Block 0 */ omxVCM4P2_MCReconBlock(pTempSrcRefBuf, srcRefStep, NULL, pDst, dstStep, predictType, pMEParams->rndVal); armVCCOMM_SAD(pTempSrcCurrBuf, 16, pDst, dstStep, &Sad, 8, 8); pDstBlockSAD[0] = Sad; /* Block 1 */ omxVCM4P2_MCReconBlock(pTempSrcRefBuf + 8, srcRefStep, NULL, pDst, dstStep, predictType, pMEParams->rndVal); armVCCOMM_SAD(pTempSrcCurrBuf + 8, 16, pDst, dstStep, &Sad, 8, 8); pDstBlockSAD[1] = Sad; /* Block 2 */ omxVCM4P2_MCReconBlock(pTempSrcRefBuf + (srcRefStep*8), srcRefStep, NULL, pDst, dstStep, predictType, pMEParams->rndVal); armVCCOMM_SAD(pTempSrcCurrBuf + (16*8), 16, pDst, dstStep, &Sad, 8, 8); pDstBlockSAD[2] = Sad; /* Block 3 */ omxVCM4P2_MCReconBlock(pTempSrcRefBuf + (srcRefStep*8) + 8, srcRefStep, NULL, pDst, dstStep, predictType, pMEParams->rndVal); armVCCOMM_SAD(pTempSrcCurrBuf + (16*8) + 8, 16, pDst, dstStep, &Sad, 8, 8); pDstBlockSAD[3] = Sad; } return OMX_Sts_NoErr; }
OMXResult armVCM4P2_BlockMatch_Integer( const OMX_U8 *pSrcRefBuf, OMX_INT refWidth, const OMXRect *pRefRect, const OMX_U8 *pSrcCurrBuf, const OMXVCM4P2Coordinate *pCurrPointPos, const OMXVCMotionVector *pSrcPreMV, const OMX_INT *pSrcPreSAD, void *pMESpec, OMXVCMotionVector *pDstMV, OMX_INT *pDstSAD, OMX_U8 BlockSize ) { /* Definitions and Initializations*/ OMX_INT outer, inner, count,index; OMX_INT candSAD; /*(256*256 +1) this is to make the SAD max initially*/ OMX_INT minSAD = 0x10001, fromX, toX, fromY, toY; /* Offset to the reference at the begining of the bounding box */ const OMX_U8 *pTempSrcRefBuf; OMX_S16 x, y; OMX_INT searchRange; /* Argument error checks */ armRetArgErrIf(pSrcRefBuf == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pRefRect == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pSrcCurrBuf == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pCurrPointPos == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pMESpec == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pDstMV == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr); searchRange = ((OMXVCM4P2MEParams *)pMESpec)->searchRange; /* Check for valid region */ fromX = searchRange; toX = searchRange; fromY = searchRange; toY = searchRange; if ((pCurrPointPos->x - searchRange) < pRefRect->x) { fromX = pCurrPointPos->x - pRefRect->x; } if ((pCurrPointPos->x + BlockSize + searchRange) > (pRefRect->x + pRefRect->width)) { toX = pRefRect->width - (pCurrPointPos->x - pRefRect->x) - BlockSize; } if ((pCurrPointPos->y - searchRange) < pRefRect->y) { fromY = pCurrPointPos->y - pRefRect->y; } if ((pCurrPointPos->y + BlockSize + searchRange) > (pRefRect->y + pRefRect->height)) { toY = pRefRect->width - (pCurrPointPos->y - pRefRect->y) - BlockSize; } pDstMV->dx = -fromX; pDstMV->dy = -fromY; /* Looping on y- axis */ for (y = -fromY; y <= toY; y++) { /* Looping on x- axis */ for (x = -fromX; x <= toX; x++) { /* Positioning the pointer */ pTempSrcRefBuf = pSrcRefBuf + (refWidth * y) + x; /* Calculate the SAD */ for (outer = 0, count = 0, index = 0, candSAD = 0; outer < BlockSize; outer++, index += refWidth - BlockSize) { for (inner = 0; inner < BlockSize; inner++, count++, index++) { candSAD += armAbs (pTempSrcRefBuf[index] - pSrcCurrBuf[count]); } } /* Result calculations */ if (armVCM4P2_CompareMV (x, y, candSAD, pDstMV->dx/2, pDstMV->dy/2, minSAD)) { *pDstSAD = candSAD; minSAD = candSAD; pDstMV->dx = x*2; pDstMV->dy = y*2; } } /* End of x- axis */ } /* End of y-axis */ return OMX_Sts_NoErr; }
OMXResult omxVCM4P2_EncodeMV( OMX_U8 **ppBitStream, OMX_INT *pBitOffset, const OMXVCMotionVector * pMVCurMB, const OMXVCMotionVector * pSrcMVLeftMB, const OMXVCMotionVector * pSrcMVUpperMB, const OMXVCMotionVector * pSrcMVUpperRightMB, OMX_INT fcodeForward, OMXVCM4P2MacroblockType MBType ) { OMXVCMotionVector dstMVPred, diffMV; OMXVCMotionVector dstMVPredME[12]; /* Initialized to remove compilation warning */ OMX_INT iBlk, i, count = 1; OMX_S32 mvHorResidual, mvVerResidual, mvHorData, mvVerData; OMX_U8 scaleFactor, index; /* Argument error checks */ armRetArgErrIf(ppBitStream == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(*ppBitStream == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pBitOffset == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pMVCurMB == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(((*pBitOffset < 0) || (*pBitOffset > 7)), OMX_Sts_BadArgErr); armRetArgErrIf(((fcodeForward < 1) || (fcodeForward > 7)), \ OMX_Sts_BadArgErr); if ((MBType == OMX_VC_INTRA) || (MBType == OMX_VC_INTRA_Q) ) { /* No candidate vectors hence make them zero */ for (i = 0; i < 12; i++) { dstMVPredME[i].dx = 0; dstMVPredME[i].dy = 0; } return OMX_Sts_NoErr; } if ((MBType == OMX_VC_INTER4V) || (MBType == OMX_VC_INTER4V_Q)) { count = 4; } else if ((MBType == OMX_VC_INTER) || (MBType == OMX_VC_INTER_Q)) { count = 1; } /* Calculating the scale factor */ scaleFactor = 1 << (fcodeForward -1); for (iBlk = 0; iBlk < count; iBlk++) { /* Find the predicted vector */ omxVCM4P2_FindMVpred ( pMVCurMB, pSrcMVLeftMB, pSrcMVUpperMB, pSrcMVUpperRightMB, &dstMVPred, dstMVPredME, iBlk ); /* Calculating the differential motion vector (diffMV) */ diffMV.dx = pMVCurMB[iBlk].dx - dstMVPred.dx; diffMV.dy = pMVCurMB[iBlk].dy - dstMVPred.dy; /* Calculating the mv_data and mv_residual for Horizantal MV */ if (diffMV.dx == 0) { mvHorResidual = 0; mvHorData = 0; } else { mvHorResidual = ( armAbs(diffMV.dx) - 1) % scaleFactor; mvHorData = (armAbs(diffMV.dx) - mvHorResidual + (scaleFactor - 1)) / scaleFactor; if (diffMV.dx < 0) { mvHorData = -mvHorData; } } /* Calculating the mv_data and mv_residual for Vertical MV */ if (diffMV.dy == 0) { mvVerResidual = 0; mvVerData = 0; } else { mvVerResidual = ( armAbs(diffMV.dy) - 1) % scaleFactor; mvVerData = (armAbs(diffMV.dy) - mvVerResidual + (scaleFactor - 1)) / scaleFactor; if (diffMV.dy < 0) { mvVerData = -mvVerData; } } /* Huffman encoding */ /* The index is actually calculate as index = ((float) (mvHorData/2) + 16) * 2, meaning the MV data is halfed and then normalized to begin with zero and then doubled to take care of indexing the fractional part included */ index = mvHorData + 32; armPackVLC32 (ppBitStream, pBitOffset, armVCM4P2_aVlcMVD[index]); if ((fcodeForward > 1) && (diffMV.dx != 0)) { armPackBits (ppBitStream, pBitOffset, mvHorResidual, (fcodeForward -1)); } /* The index is actually calculate as index = ((float) (mvVerData/2) + 16) * 2, meaning the MV data is halfed and then normalized to begin with zero and then doubled to take care of indexing the fractional part included */ index = mvVerData + 32; armPackVLC32 (ppBitStream, pBitOffset, armVCM4P2_aVlcMVD[index]); if ((fcodeForward > 1) && (diffMV.dy != 0)) { armPackBits (ppBitStream, pBitOffset, mvVerResidual, (fcodeForward -1)); } } return OMX_Sts_NoErr; }
OMX_U8 armVCM4P2_CheckVLCEscapeMode( OMX_U32 run, OMX_U32 runPlus, OMX_S16 level, OMX_S16 levelPlus, OMX_U8 maxStoreRun, OMX_U8 maxRunForMultipleEntries, OMX_INT shortVideoHeader, const OMX_U8 *pRunIndexTable ) { OMX_U8 escape = 0, fMode = 0, entries; level = armAbs (level); levelPlus = armAbs (levelPlus); /* Check for a valid entry with run, level and Last combination Mode 0 check */ if (run <= maxStoreRun) { entries = pRunIndexTable[run + 1] - pRunIndexTable[run]; if (run > maxRunForMultipleEntries) { entries = 1; } if (level > entries) { escape = 1; } } else { escape = 1; } if(escape && shortVideoHeader) { escape = 0; fMode = 4; } /* Check for a valid entry with run, levelPlus and Last combination Mode 1 check */ if (escape) { escape = 0; fMode = 1; if (run <= maxStoreRun) { entries = pRunIndexTable[run + 1] - pRunIndexTable[run]; if (run > maxRunForMultipleEntries) { entries = 1; } if (levelPlus > entries) { escape = 1; } } else { escape = 1; } } /* Check for a valid entry with runPlus, level and Last combination Mode 2 check */ if (escape) { escape = 0; fMode = 2; if (runPlus <= maxStoreRun) { entries = pRunIndexTable[runPlus + 1] - pRunIndexTable[runPlus]; if (runPlus > maxRunForMultipleEntries) { entries = 1; } if (level > entries) { escape = 1; } } else { escape = 1; } } /* select mode 3 --> FLC */ if (escape) { fMode = 3; } return fMode; }
void armVCM4P10_DeBlockPixel( OMX_U8 *pQ0, /* pointer to the pixel q0 */ int Step, /* step between pixels q0 and q1 */ int tC0, /* edge threshold value */ int alpha, /* alpha */ int beta, /* beta */ int bS, /* deblocking strength */ int ChromaFlag ) { int p3, p2, p1, p0, q0, q1, q2, q3; int ap, aq, delta; if (bS==0) { return; } p3 = pQ0[-4*Step]; p2 = pQ0[-3*Step]; p1 = pQ0[-2*Step]; p0 = pQ0[-1*Step]; q0 = pQ0[ 0*Step]; q1 = pQ0[ 1*Step]; q2 = pQ0[ 2*Step]; q3 = pQ0[ 3*Step]; if (armAbs(p0-q0)>=alpha || armAbs(p1-p0)>=beta || armAbs(q1-q0)>=beta) { DEBUG_PRINTF_10("DeBlockPixel: %02x %02x %02x %02x | %02x %02x %02x %02x alpha=%d beta=%d\n", p3, p2, p1, p0, q0, q1, q2, q3, alpha, beta); return; } ap = armAbs(p2 - p0); aq = armAbs(q2 - q0); if (bS < 4) { int tC = tC0; if (ChromaFlag) { tC++; } else { if (ap < beta) { tC++; } if (aq < beta) { tC++; } } delta = (((q0-p0)<<2) + (p1-q1) + 4) >> 3; delta = armClip(-tC, tC, delta); pQ0[-1*Step] = (OMX_U8)armClip(0, 255, p0 + delta); pQ0[ 0*Step] = (OMX_U8)armClip(0, 255, q0 - delta); if (ChromaFlag==0 && ap<beta) { delta = (p2 + ((p0+q0+1)>>1) - (p1<<1))>>1; delta = armClip(-tC0, tC0, delta); pQ0[-2*Step] = (OMX_U8)(p1 + delta); }
OMXResult armVCM4P2_FillVLCBuffer ( OMX_U8 **ppBitStream, OMX_INT * pBitOffset, OMX_U32 run, OMX_S16 level, OMX_U32 runPlus, OMX_S16 levelPlus, OMX_U8 fMode, OMX_U8 last, OMX_U8 maxRunForMultipleEntries, const OMX_U8 *pRunIndexTable, const ARM_VLC32 *pVlcTable ) { OMX_INT tempIndex; OMX_U32 tempRun = run, sign = 0; OMX_S16 tempLevel = level; /* Escape sequence addition */ if (fMode == 1) { armPackBits(ppBitStream, pBitOffset, 3, 7); armPackBits(ppBitStream, pBitOffset, 0, 1); tempLevel = levelPlus; } else if(fMode == 2) { armPackBits(ppBitStream, pBitOffset, 3, 7); armPackBits(ppBitStream, pBitOffset, 2, 2); tempRun = runPlus; } else if (fMode == 3) { armPackBits(ppBitStream, pBitOffset, 3, 7); armPackBits(ppBitStream, pBitOffset, 3, 2); } else if (fMode == 4) { armPackBits(ppBitStream, pBitOffset, 3, 7); armPackBits(ppBitStream, pBitOffset, (OMX_U32)last, 1); armPackBits(ppBitStream, pBitOffset, tempRun, 6); if((tempLevel != 0) && (tempLevel != -128)) { armPackBits(ppBitStream, pBitOffset, (OMX_U32) tempLevel, 8); } return OMX_Sts_NoErr; } if (tempLevel < 0) { sign = 1; tempLevel = armAbs(tempLevel); } /* Putting VLC bits in the stream */ if (fMode < 3) { if (tempRun > maxRunForMultipleEntries) { tempIndex = pRunIndexTable [maxRunForMultipleEntries + 1] + (tempRun - maxRunForMultipleEntries - 1); } else { tempIndex = pRunIndexTable [tempRun] + (tempLevel -1); } armPackVLC32 (ppBitStream, pBitOffset, pVlcTable [tempIndex]); armPackBits(ppBitStream, pBitOffset, (OMX_U32)sign, 1); } else { if (sign) { tempLevel = -tempLevel; } tempRun = run; armPackBits(ppBitStream, pBitOffset, (OMX_U32)last, 1); armPackBits(ppBitStream, pBitOffset, tempRun, 6); armPackBits(ppBitStream, pBitOffset, 1, 1); armPackBits(ppBitStream, pBitOffset, (OMX_U32) tempLevel, 12); armPackBits(ppBitStream, pBitOffset, 1, 1); } return OMX_Sts_NoErr; }
OMXResult omxVCM4P2_QuantInvIntra_I( OMX_S16 * pSrcDst, OMX_INT QP, OMXVCM4P2VideoComponent videoComp, OMX_INT shortVideoHeader ) { /* Initialized to remove compilation error */ OMX_INT dcScaler = 0, coeffCount, Sign; /* Argument error checks */ armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(((QP <= 0) || (QP >= 32)), OMX_Sts_BadArgErr); armRetArgErrIf(((videoComp != OMX_VC_LUMINANCE) && (videoComp != OMX_VC_CHROMINANCE)), OMX_Sts_BadArgErr); /* Calculate the DC scaler value */ /* linear intra DC mode */ if(shortVideoHeader) { dcScaler = 8; } /* nonlinear intra DC mode */ else { if (videoComp == OMX_VC_LUMINANCE) { if (QP >= 1 && QP <= 4) { dcScaler = 8; } else if (QP >= 5 && QP <= 8) { dcScaler = 2 * QP; } else if (QP >= 9 && QP <= 24) { dcScaler = QP + 8; } else { dcScaler = (2 * QP) - 16; } } else if (videoComp == OMX_VC_CHROMINANCE) { if (QP >= 1 && QP <= 4) { dcScaler = 8; } else if (QP >= 5 && QP <= 24) { dcScaler = (QP + 13)/2; } else { dcScaler = QP - 6; } } } /* Dequant the DC value, this applies to both the methods */ pSrcDst[0] = pSrcDst[0] * dcScaler; /* Saturate */ pSrcDst[0] = armClip (-2048, 2047, pSrcDst[0]); /* Second Inverse quantisation method */ for (coeffCount = 1; coeffCount < 64; coeffCount++) { /* check sign */ Sign = armSignCheck (pSrcDst[coeffCount]); if (QP & 0x1) { pSrcDst[coeffCount] = (2* armAbs(pSrcDst[coeffCount]) + 1) * QP; pSrcDst[coeffCount] *= Sign; } else { pSrcDst[coeffCount] = (2* armAbs(pSrcDst[coeffCount]) + 1) * QP - 1; pSrcDst[coeffCount] *= Sign; } /* Saturate */ pSrcDst[coeffCount] = armClip (-2048, 2047, pSrcDst[coeffCount]); } return OMX_Sts_NoErr; }