OMXResult omxVCCOMM_Copy16x16( const OMX_U8 *pSrc, OMX_U8 *pDst, OMX_INT step) { /* Definitions and Initializations*/ OMX_INT count,index, x, y; /* Argument error checks */ armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(!armIs16ByteAligned(pSrc), OMX_Sts_BadArgErr); armRetArgErrIf(!armIs16ByteAligned(pDst), OMX_Sts_BadArgErr); armRetArgErrIf(((step < 16) || (step % 16)), OMX_Sts_BadArgErr); /* Copying the ref 16x16 blk to the curr blk */ for (y = 0, count = 0, index = 0; y < 16; y++, count = count + step - 16) { for (x = 0; x < 16; x++, count++, index++) { pDst[index] = pSrc[count]; } } return OMX_Sts_NoErr; }
OMXResult omxVCM4P10_DeblockLuma_I( OMX_U8* pSrcDst, OMX_S32 srcdstStep, const OMX_U8* pAlpha, const OMX_U8* pBeta, const OMX_U8* pThresholds, const OMX_U8 *pBS ) { OMXResult errorCode; armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(armNot8ByteAligned(pSrcDst), OMX_Sts_BadArgErr); armRetArgErrIf(srcdstStep & 7, OMX_Sts_BadArgErr); armRetArgErrIf(pAlpha == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pBeta == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pThresholds == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(armNot4ByteAligned(pThresholds), OMX_Sts_BadArgErr); armRetArgErrIf(pBS == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(armNot4ByteAligned(pBS), OMX_Sts_BadArgErr); errorCode = omxVCM4P10_FilterDeblockingLuma_VerEdge_I( pSrcDst, srcdstStep, pAlpha, pBeta, pThresholds, pBS); armRetArgErrIf(errorCode != OMX_Sts_NoErr, errorCode) errorCode = omxVCM4P10_FilterDeblockingLuma_HorEdge_I( pSrcDst, srcdstStep, pAlpha+2, pBeta+2, pThresholds+16, pBS+16); return errorCode; }
OMXResult omxSP_FFTGetBufSize_R_S16S32( OMX_INT order, OMX_INT *pSize ) { OMX_INT Nby2; OMX_INT N; /* Input parameter check */ armRetArgErrIf(pSize == NULL, OMX_Sts_BadArgErr) armRetArgErrIf(order < 0, OMX_Sts_BadArgErr) armRetArgErrIf(order > 12, OMX_Sts_BadArgErr) /* Check for order zero */ if (order == 0) { *pSize = sizeof(ARMsFFTSpec_FC64); return OMX_Sts_NoErr; } Nby2 = 1 << (order - 1); N = 1 << order; /* 2 pointers to store bitreversed array and twiddle factor array */ *pSize = sizeof(ARMsFFTSpec_FC64) /* N bitreversed Numbers */ + sizeof(OMX_U16) * Nby2 /* Twiddle factors */ + sizeof(OMX_FC64) * Nby2 + sizeof(OMX_F64) * (2 + N); return OMX_Sts_NoErr; }
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_DCT8x8blk (const OMX_S16 *pSrc, OMX_S16 *pDst) { OMX_INT x, y, u, v; /* Argument error checks */ armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(!armIs16ByteAligned(pSrc), OMX_Sts_BadArgErr); armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(!armIs16ByteAligned(pDst), OMX_Sts_BadArgErr); for (u = 0; u < 8; u++) { for (v = 0; v < 8; v++) { OMX_F64 sum = 0.0; for (x = 0; x < 8; x++) { for (y = 0; y < 8; y++) { sum += pSrc[(x * 8) + y] * armVCM4P2_preCalcDCTCos[x][u] * armVCM4P2_preCalcDCTCos[y][v]; } } pDst[(u * 8) + v]= armRoundFloatToS16 (sum); } } return OMX_Sts_NoErr; }
OMXResult omxVCM4P10_MEInit( OMXVCM4P10MEMode MEMode, const OMXVCM4P10MEParams *pMEParams, void *pMESpec ) { ARMVCM4P10_MESpec *armMESpec = (ARMVCM4P10_MESpec *) pMESpec; armRetArgErrIf(!pMEParams, OMX_Sts_BadArgErr); armRetArgErrIf(!pMESpec, OMX_Sts_BadArgErr); armRetArgErrIf((MEMode != OMX_VC_M4P10_FAST_SEARCH) && (MEMode != OMX_VC_M4P10_FULL_SEARCH), OMX_Sts_BadArgErr); armRetArgErrIf((pMEParams->searchRange16x16 <= 0) || (pMEParams->searchRange8x8 <= 0) || (pMEParams->searchRange4x4 <= 0), OMX_Sts_BadArgErr); armMESpec->MEParams.blockSplitEnable8x8 = pMEParams->blockSplitEnable8x8; armMESpec->MEParams.blockSplitEnable4x4 = pMEParams->blockSplitEnable4x4; armMESpec->MEParams.halfSearchEnable = pMEParams->halfSearchEnable; armMESpec->MEParams.quarterSearchEnable = pMEParams->quarterSearchEnable; armMESpec->MEParams.intraEnable4x4 = pMEParams->intraEnable4x4; armMESpec->MEParams.searchRange16x16 = pMEParams->searchRange16x16; armMESpec->MEParams.searchRange8x8 = pMEParams->searchRange8x8; armMESpec->MEParams.searchRange4x4 = pMEParams->searchRange4x4; armMESpec->MEMode = MEMode; 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 omxVCM4P2_BlockMatch_Integer_16x16( 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 = 16; /* Argument error checks */ armRetArgErrIf(!armIs16ByteAligned(pSrcCurrBuf), OMX_Sts_BadArgErr); return ( armVCM4P2_BlockMatch_Integer( pSrcRefBuf, refWidth, pRefRect, pSrcCurrBuf, pCurrPointPos, pSrcPreMV, pSrcPreSAD, pMESpec, pDstMV, pDstSAD, BlockSize) ); }
/** * Function: omxVCM4P2_EncodeVLCZigzag_Inter (6.2.4.5.3) * * Description: * Performs classical zigzag scanning and VLC encoding for one inter block. * * Input Arguments: * * ppBitStream - pointer to the pointer to the current byte in the bit * stream * pBitOffset - pointer to the bit position in the byte pointed by * *ppBitStream. Valid within 0 to 7 * pQDctBlkCoef - pointer to the quantized DCT coefficient * pattern - block pattern which is used to decide whether this block is * encoded * shortVideoHeader - binary flag indicating presence of * short_video_header; escape modes 0-3 are used if * shortVideoHeader==0, and escape mode 4 is used when * shortVideoHeader==1. * * Output Arguments: * * ppBitStream - *ppBitStream is updated after the block is encoded so that * it points to the current byte in the bit stream buffer. * pBitOffset - *pBitOffset is updated so that it points to the current bit * position in the byte pointed by *ppBitStream. * * Return Value: * * OMX_Sts_NoErr - no error * OMX_Sts_BadArgErr - Bad arguments * - At least one of the pointers: is NULL: ppBitStream, *ppBitStream, * pBitOffset, pQDctBlkCoef * - *pBitOffset < 0, or *pBitOffset >7. * */ OMXResult omxVCM4P2_EncodeVLCZigzag_Inter( OMX_U8 **ppBitStream, OMX_INT * pBitOffset, const OMX_S16 *pQDctBlkCoef, OMX_U8 pattern, OMX_INT shortVideoHeader ) { OMX_U8 start = 0; const OMX_U8 *pZigzagTable = armVCM4P2_aClassicalZigzagScan; /* Argument error checks */ armRetArgErrIf(ppBitStream == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(*ppBitStream == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pBitOffset == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pQDctBlkCoef == NULL, OMX_Sts_BadArgErr); armRetArgErrIf((*pBitOffset < 0) || (*pBitOffset >7), OMX_Sts_BadArgErr); if (pattern) { armVCM4P2_PutVLCBits ( ppBitStream, pBitOffset, pQDctBlkCoef, shortVideoHeader, start, 26, 40, 10, 1, armVCM4P2_InterL0RunIdx, armVCM4P2_InterVlcL0, armVCM4P2_InterL1RunIdx, armVCM4P2_InterVlcL1, armVCM4P2_InterL0LMAX, armVCM4P2_InterL1LMAX, armVCM4P2_InterL0RMAX, armVCM4P2_InterL1RMAX, pZigzagTable ); } /* Pattern check ends*/ return OMX_Sts_NoErr; }
/** * Function: omxVCCOMM_ExpandFrame_I (6.1.3.2.1) * * Description: * This function expands a reconstructed frame in-place. The unexpanded * source frame should be stored in a plane buffer with sufficient space * pre-allocated for edge expansion, and the input frame should be located in * the plane buffer center. This function executes the pixel expansion by * replicating source frame edge pixel intensities in the empty pixel * locations (expansion region) between the source frame edge and the plane * buffer edge. The width/height of the expansion regions on the * horizontal/vertical edges is controlled by the parameter iExpandPels. * * Input Arguments: * * pSrcDstPlane - pointer to the top-left corner of the frame to be * expanded; must be aligned on an 8-byte boundary. * iFrameWidth - frame width; must be a multiple of 8. * iFrameHeight -frame height; must be a multiple of 8. * iExpandPels - number of pixels to be expanded in the horizontal and * vertical directions; must be a multiple of 8. * iPlaneStep - distance, in bytes, between the start of consecutive lines * in the plane buffer; must be larger than or equal to * (iFrameWidth + 2 * iExpandPels). * * Output Arguments: * * pSrcDstPlane -Pointer to the top-left corner of the frame (NOT the * top-left corner of the plane); must be aligned on an 8-byte * boundary. * * Return Value: * * OMX_Sts_NoErr - no error * OMX_Sts_BadArgErr - bad arguments; returned under any of the following * conditions: * - pSrcDstPlane is NULL. * - pSrcDstPlane is not aligned on an 8-byte boundary. * - one of the following parameters is either equal to zero or is a * non-multiple of 8: iFrameHeight, iFrameWidth, iPlaneStep, or * iExpandPels. * - iPlaneStep < (iFrameWidth + 2 * iExpandPels). * */ OMXResult omxVCCOMM_ExpandFrame_I( OMX_U8* pSrcDstPlane, OMX_U32 iFrameWidth, OMX_U32 iFrameHeight, OMX_U32 iExpandPels, OMX_U32 iPlaneStep ) { OMX_INT x, y; OMX_U8* pLeft; OMX_U8* pRight; OMX_U8* pTop; OMX_U8* pBottom; /* check for argument error */ armRetArgErrIf(pSrcDstPlane == NULL, OMX_Sts_BadArgErr) armRetArgErrIf(armNot8ByteAligned(pSrcDstPlane), OMX_Sts_BadArgErr) armRetArgErrIf(iFrameWidth == 0 || iFrameWidth & 7, OMX_Sts_BadArgErr) armRetArgErrIf(iFrameHeight== 0 || iFrameHeight & 7, OMX_Sts_BadArgErr) armRetArgErrIf(iExpandPels == 0 || iExpandPels & 7, OMX_Sts_BadArgErr) armRetArgErrIf(iPlaneStep == 0 || iPlaneStep & 7, OMX_Sts_BadArgErr) armRetArgErrIf(iPlaneStep < (iFrameWidth + 2 * iExpandPels), OMX_Sts_BadArgErr) /* Top and Bottom */ pTop = pSrcDstPlane - (iExpandPels * iPlaneStep); pBottom = pSrcDstPlane + (iFrameHeight * iPlaneStep); for (y = 0; y < (OMX_INT)iExpandPels; y++) { for (x = 0; x < (OMX_INT)iFrameWidth; x++) { pTop [y * iPlaneStep + x] = pSrcDstPlane [x]; pBottom [y * iPlaneStep + x] = pSrcDstPlane [(iFrameHeight - 1) * iPlaneStep + x]; } } /* Left, Right and Corners */ pLeft = pSrcDstPlane - iExpandPels; pRight = pSrcDstPlane + iFrameWidth; for (y = -(OMX_INT)iExpandPels; y < (OMX_INT)(iFrameHeight + iExpandPels); y++) { for (x = 0; x < (OMX_INT)iExpandPels; x++) { pLeft [y * iPlaneStep + x] = pSrcDstPlane [y * iPlaneStep + 0]; pRight [y * iPlaneStep + x] = pSrcDstPlane [y * iPlaneStep + (iFrameWidth - 1)]; } } return OMX_Sts_NoErr; }
OMXResult omxVCM4P2_BlockMatch_Half_8x8( const OMX_U8 *pSrcRefBuf, OMX_INT refWidth, const OMXRect *pRefRect, const OMX_U8 *pSrcCurrBuf, const OMXVCM4P2Coordinate *pSearchPointRefPos, OMX_INT rndVal, OMXVCMotionVector *pSrcDstMV, OMX_INT *pDstSAD ) { /* For a blocksize of 8x8 */ OMX_U8 BlockSize = 8; /* Argument error checks */ armRetArgErrIf(pSrcRefBuf == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pRefRect == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pSrcCurrBuf == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pSearchPointRefPos == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pSrcDstMV == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(!armIs8ByteAligned(pSrcCurrBuf), OMX_Sts_BadArgErr); return (armVCM4P2_BlockMatch_Half( pSrcRefBuf, refWidth, pRefRect, pSrcCurrBuf, pSearchPointRefPos, rndVal, pSrcDstMV, pDstSAD, BlockSize)); }
OMXResult omxVCM4P2_MEInit( OMXVCM4P2MEMode MEMode, const OMXVCM4P2MEParams *pMEParams, void *pMESpec ) { ARMVCM4P2_MESpec *armMESpec = (ARMVCM4P2_MESpec *) pMESpec; armRetArgErrIf(!pMEParams, OMX_Sts_BadArgErr); armRetArgErrIf(!pMESpec, OMX_Sts_BadArgErr); armRetArgErrIf((MEMode != OMX_VC_M4P2_FAST_SEARCH) && (MEMode != OMX_VC_M4P2_FULL_SEARCH), OMX_Sts_BadArgErr); armRetArgErrIf(pMEParams->searchRange <= 0, OMX_Sts_BadArgErr); armMESpec->MEParams.searchEnable8x8 = pMEParams->searchEnable8x8; armMESpec->MEParams.halfPelSearchEnable = pMEParams->halfPelSearchEnable; armMESpec->MEParams.searchRange = pMEParams->searchRange; armMESpec->MEParams.rndVal = pMEParams->rndVal; armMESpec->MEMode = MEMode; return OMX_Sts_NoErr; }
OMXResult armVCM4P10_InterpolateHalfHor_Luma( const OMX_U8* pSrc, OMX_U32 iSrcStep, OMX_U8* pDst, OMX_U32 iDstStep, OMX_U32 iWidth, OMX_U32 iHeight ) { OMX_INT x, y; OMX_S32 HalfCoeff, pos; /* check for argument error */ armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr) armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr) for (y = 0; y < iHeight; y++) { for (x = 0; x < iWidth; x++) { pos = y * iSrcStep + x; HalfCoeff = pSrc [pos - 2] - 5 * pSrc [pos - 1] + 20 * pSrc [pos] + 20 * pSrc [pos + 1] - 5 * pSrc [pos + 2] + pSrc [pos + 3]; HalfCoeff = (HalfCoeff + 16) >> 5; HalfCoeff = armClip(0, 255, HalfCoeff); pDst [y * iDstStep + x] = HalfCoeff; } /* x */ } /* y */ return OMX_Sts_NoErr; }
/** * Functions: armSwapElem * * Description: * These function swaps two elements at the specified pointer locations. * The size of each element could be anything as specified by <elemSize> * * Return Value: * OMXResult -- Error status from the function */ OMXResult armSwapElem( OMX_U8 *pBuf1, OMX_U8 *pBuf2, OMX_INT elemSize ) { OMX_INT i; OMX_U8 temp; armRetArgErrIf(!pBuf1 || !pBuf2, OMX_Sts_NullPtrErr); for(i = 0; i < elemSize; i++) { temp = *(pBuf1 + i); *(pBuf1 + i) = *(pBuf2 + i); *(pBuf2 + i) = temp; } return OMX_Sts_NoErr; }
OMXResult omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC ( const OMX_U8** ppBitStream, OMX_S32* pOffset, OMX_U8* pNumCoeff, OMX_U8** ppPosCoefbuf ) { armRetArgErrIf(ppBitStream==NULL , OMX_Sts_BadArgErr); armRetArgErrIf(*ppBitStream==NULL , OMX_Sts_BadArgErr); armRetArgErrIf(pOffset==NULL , OMX_Sts_BadArgErr); armRetArgErrIf(*pOffset<0 , OMX_Sts_BadArgErr); armRetArgErrIf(*pOffset>7 , OMX_Sts_BadArgErr); armRetArgErrIf(pNumCoeff==NULL , OMX_Sts_BadArgErr); armRetArgErrIf(ppPosCoefbuf==NULL , OMX_Sts_BadArgErr); armRetArgErrIf(*ppPosCoefbuf==NULL , OMX_Sts_BadArgErr); return armVCM4P10_DecodeCoeffsToPair(ppBitStream, pOffset, pNumCoeff, ppPosCoefbuf, 4, 4); }
OMXResult omxVCM4P2_TransRecBlockCoef_inter( const OMX_S16 *pSrc, OMX_S16 * pDst, OMX_S16 * pRec, OMX_U8 QP, OMX_INT shortVideoHeader ) { /* 64 elements are needed but to align it to 16 bytes need 8 more elements of padding */ OMX_S16 tempBuffer[72]; OMX_S16 *pTempBuffer; OMX_INT i; /* Aligning the local buffers */ pTempBuffer = armAlignTo16Bytes(tempBuffer); /* Argument error checks */ armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pRec == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(!armIs16ByteAligned(pSrc), OMX_Sts_BadArgErr); armRetArgErrIf(!armIs16ByteAligned(pRec), OMX_Sts_BadArgErr); armRetArgErrIf(!armIs16ByteAligned(pDst), OMX_Sts_BadArgErr); armRetArgErrIf(((QP <= 0) || (QP >= 32)), OMX_Sts_BadArgErr); omxVCM4P2_DCT8x8blk (pSrc, pDst); omxVCM4P2_QuantInter_I( pDst, QP, shortVideoHeader); for (i = 0; i < 64; i++) { pTempBuffer[i] = pDst[i]; } omxVCM4P2_QuantInvInter_I( pTempBuffer, QP); omxVCM4P2_IDCT8x8blk (pTempBuffer, pRec); return OMX_Sts_NoErr; }
OMXResult omxSP_FIROne_Direct_S16( OMX_S16 val, OMX_S16 * pResult, const OMX_S16 * pTapsQ15, OMX_INT tapsLen, OMX_S16 * pDelayLine, OMX_INT * pDelayLineIndex ) { OMX_U32 index; OMX_S32 accum; OMX_S16 *pDelayCurrent; /* Input parameter check */ armRetArgErrIf((pResult == NULL), OMX_Sts_BadArgErr) armRetArgErrIf((pTapsQ15 == NULL), OMX_Sts_BadArgErr) armRetArgErrIf((tapsLen <= 0), OMX_Sts_BadArgErr) armRetArgErrIf((pDelayLine == NULL), OMX_Sts_BadArgErr) armRetArgErrIf((pDelayLineIndex == NULL), OMX_Sts_BadArgErr) armRetArgErrIf((*pDelayLineIndex < 0), OMX_Sts_BadArgErr) armRetArgErrIf((*pDelayLineIndex >= tapsLen), OMX_Sts_BadArgErr) /* Update the delay state */ pDelayCurrent = &pDelayLine [*pDelayLineIndex]; /* Copy input to current delay line position */ pDelayCurrent [0] = pDelayCurrent [tapsLen] = val; accum = 0; for (index = 0; index < tapsLen; index++) { accum += (OMX_S32)pTapsQ15 [index] * (OMX_S32)pDelayCurrent [index]; } if (--(*pDelayLineIndex) < 0) { *pDelayLineIndex = tapsLen - 1; } /* Store the result */ *pResult = armSatRoundLeftShift_S32(accum, -15); return OMX_Sts_NoErr; }
OMXResult omxSP_IIROne_BiQuadDirect_S16_I( OMX_S16 * pValResult, const OMX_S16 * pTaps, OMX_INT numBiquad, OMX_S32 * pDelayLine ) { OMXResult errorCode; armRetArgErrIf(pValResult == NULL, OMX_Sts_BadArgErr) errorCode = omxSP_IIROne_BiQuadDirect_S16( *pValResult, pValResult, pTaps, numBiquad, pDelayLine); return errorCode; }
OMXResult omxVCM4P10_TransformDequantChromaDCFromPair( const OMX_U8 **ppSrc, OMX_S16* pDst, OMX_INT QP ) { armRetArgErrIf(ppSrc == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(*ppSrc == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(armNot4ByteAligned(pDst), OMX_Sts_BadArgErr); armRetArgErrIf(QP<0, OMX_Sts_BadArgErr); armRetArgErrIf(QP>51, OMX_Sts_BadArgErr); armVCM4P10_UnpackBlock2x2(ppSrc, pDst); InvTransformDC2x2(pDst); DequantChromaDC2x2(pDst, QP); return OMX_Sts_NoErr; }
OMXResult armVCM4P2_DecodeVLCZigzag_Intra( const OMX_U8 ** ppBitStream, OMX_INT * pBitOffset, OMX_S16 * pDst, OMX_U8 predDir, OMX_INT shortVideoHeader, OMX_U8 start ) { OMX_U8 last = 0; const OMX_U8 *pZigzagTable = armVCM4P2_aClassicalZigzagScan; OMXResult errorCode; /* Argument error checks */ armRetArgErrIf(ppBitStream == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(*ppBitStream == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pBitOffset == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(!armIs4ByteAligned(pDst), OMX_Sts_BadArgErr); armRetArgErrIf((*pBitOffset < 0) || (*pBitOffset >7), OMX_Sts_BadArgErr); armRetArgErrIf((predDir > 2), OMX_Sts_BadArgErr); switch (predDir) { case OMX_VC_NONE: { pZigzagTable = armVCM4P2_aClassicalZigzagScan; break; } case OMX_VC_HORIZONTAL: { pZigzagTable = armVCM4P2_aVerticalZigzagScan; break; } case OMX_VC_VERTICAL: { pZigzagTable = armVCM4P2_aHorizontalZigzagScan; break; } } errorCode = armVCM4P2_GetVLCBits ( ppBitStream, pBitOffset, pDst, shortVideoHeader, start, &last, 10, 62, 7, 21, armVCM4P2_IntraL0RunIdx, armVCM4P2_IntraVlcL0, armVCM4P2_IntraL1RunIdx, armVCM4P2_IntraVlcL1, armVCM4P2_IntraL0LMAX, armVCM4P2_IntraL1LMAX, armVCM4P2_IntraL0RMAX, armVCM4P2_IntraL1RMAX, pZigzagTable ); armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode); if (last == 0) { return OMX_Sts_Err; } return OMX_Sts_NoErr; }
OMXResult omxVCM4P10_DequantTransformResidualFromPairAndAdd( const OMX_U8 **ppSrc, const OMX_U8 *pPred, const OMX_S16 *pDC, OMX_U8 *pDst, OMX_INT predStep, OMX_INT dstStep, OMX_INT QP, OMX_INT AC ) { OMX_S16 pBuffer[16+4]; OMX_S16 *pDelta; int i,x,y; armRetArgErrIf(pPred == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(armNot4ByteAligned(pPred),OMX_Sts_BadArgErr); armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(armNot4ByteAligned(pDst), OMX_Sts_BadArgErr); armRetArgErrIf(predStep & 3, OMX_Sts_BadArgErr); armRetArgErrIf(dstStep & 3, OMX_Sts_BadArgErr); armRetArgErrIf(AC!=0 && (QP<0), OMX_Sts_BadArgErr); armRetArgErrIf(AC!=0 && (QP>51), OMX_Sts_BadArgErr); armRetArgErrIf(AC!=0 && ppSrc==NULL, OMX_Sts_BadArgErr); armRetArgErrIf(AC!=0 && *ppSrc==NULL, OMX_Sts_BadArgErr); armRetArgErrIf(AC==0 && pDC==NULL, OMX_Sts_BadArgErr); pDelta = armAlignTo8Bytes(pBuffer); for (i=0; i<16; i++) { pDelta[i] = 0; } if (AC) { armVCM4P10_UnpackBlock4x4(ppSrc, pDelta); DequantLumaAC4x4(pDelta, QP); } if (pDC) { pDelta[0] = pDC[0]; } armVCM4P10_TransformResidual4x4(pDelta,pDelta); for (y=0; y<4; y++) { for (x=0; x<4; x++) { pDst[y*dstStep+x] = (OMX_U8)armClip(0,255,pPred[y*predStep+x] + pDelta[4*y+x]); } } return OMX_Sts_NoErr; }
/** * Function: omxVCM4P10_InvTransformDequant_LumaDC (6.3.5.6.3) * * Description: * This function performs inverse 4x4 Hadamard transform and then dequantizes * the coefficients. * * Input Arguments: * * pSrc - Pointer to the 4x4 array of the 4x4 Hadamard-transformed and * quantized coefficients. 16 byte alignment required. * iQP - Quantization parameter; must be in the range [0,51]. * * Output Arguments: * * pDst - Pointer to inverse-transformed and dequantized coefficients. * 16-byte alignment required. * * Return Value: * * OMX_Sts_NoErr - no error * OMX_Sts_BadArgErr - bad arguments; returned if any of the following * conditions are true: * - at least one of the following pointers is NULL: pSrc * - pSrc or pDst is not aligned on a 16-byte boundary * */ OMXResult omxVCM4P10_InvTransformDequant_LumaDC( const OMX_S16* pSrc, OMX_S16* pDst, OMX_U32 iQP ) { OMX_INT i, j; OMX_S32 m1[4][4], m2[4][4], Value; OMX_S32 QPer, V; /* check for argument error */ armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr) armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr) armRetArgErrIf(iQP > 51, OMX_Sts_BadArgErr) armRetArgErrIf(armNot16ByteAligned(pSrc), OMX_Sts_BadArgErr) armRetArgErrIf(armNot16ByteAligned(pDst), OMX_Sts_BadArgErr) /* Inv Hadamard Transform for DC Luma 4x4 block */ /* Horizontal */ for (i = 0; i < 4; i++) { j = i * 4; m1[i][0] = pSrc[j + 0] + pSrc[j + 2]; /* a+c */ m1[i][1] = pSrc[j + 1] + pSrc[j + 3]; /* b+d */ m1[i][2] = pSrc[j + 0] - pSrc[j + 2]; /* a-c */ m1[i][3] = pSrc[j + 1] - pSrc[j + 3]; /* b-d */ m2[i][0] = m1[i][0] + m1[i][1]; /* a+b+c+d */ m2[i][1] = m1[i][2] + m1[i][3]; /* a+b-c-d */ m2[i][2] = m1[i][2] - m1[i][3]; /* a-b-c+d */ m2[i][3] = m1[i][0] - m1[i][1]; /* a-b+c-d */ } /* Vertical */ for (i = 0; i < 4; i++) { m1[0][i] = m2[0][i] + m2[2][i]; m1[1][i] = m2[1][i] + m2[3][i]; m1[2][i] = m2[0][i] - m2[2][i]; m1[3][i] = m2[1][i] - m2[3][i]; m2[0][i] = m1[0][i] + m1[1][i]; m2[1][i] = m1[2][i] + m1[3][i]; m2[2][i] = m1[2][i] - m1[3][i]; m2[3][i] = m1[0][i] - m1[1][i]; } /* Scaling */ QPer = iQP / 6; V = armVCM4P10_VMatrix [iQP % 6][0]; for (j = 0; j < 4; j++) { for (i = 0; i < 4; i++) { if (QPer < 2) { Value = (m2[j][i] * V + (1 << (1 - QPer))) >> (2 - QPer); } else { Value = m2[j][i] * V * (1 << (QPer - 2)); } pDst[j * 4 + i] = (OMX_S16) Value; }
/** * Function: omxVCM4P10_GetVLCInfo (6.3.5.9.1) * * Description: * This function extracts run-length encoding (RLE) information from the * coefficient matrix. The results are returned in an OMXVCM4P10VLCInfo * structure. * * Input Arguments: * * pSrcCoeff - pointer to the transform coefficient matrix. 8-byte * alignment required. * pScanMatrix - pointer to the scan order definition matrix. For a luma * block the scan matrix should follow [ISO14496-10] section 8.5.4, * and should contain the values 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, * 10, 7, 11, 14, 15. For a chroma block, the scan matrix should * contain the values 0, 1, 2, 3. * bAC - indicates presence of a DC coefficient; 0 = DC coefficient * present, 1= DC coefficient absent. * MaxNumCoef - specifies the number of coefficients contained in the * transform coefficient matrix, pSrcCoeff. The value should be 16 * for blocks of type LUMADC, LUMAAC, LUMALEVEL, and CHROMAAC. The * value should be 4 for blocks of type CHROMADC. * * Output Arguments: * * pDstVLCInfo - pointer to structure that stores information for * run-length coding. * * Return Value: * * OMX_Sts_NoErr - no error * OMX_Sts_BadArgErr - bad arguments; returned if any of the following * conditions are true: * - at least one of the following pointers is NULL: * pSrcCoeff, pScanMatrix, pDstVLCInfo * - pSrcCoeff is not aligned on an 8-byte boundary * */ OMXResult omxVCM4P10_GetVLCInfo ( const OMX_S16* pSrcCoeff, const OMX_U8* pScanMatrix, OMX_U8 bAC, OMX_U32 MaxNumCoef, OMXVCM4P10VLCInfo* pDstVLCInfo ) { OMX_INT i, MinIndex; OMX_S32 Value; OMX_U32 Mask = 4, RunBefore; OMX_S16 *pLevel; OMX_U8 *pRun; OMX_S16 Buf [16]; /* check for argument error */ armRetArgErrIf(pSrcCoeff == NULL, OMX_Sts_BadArgErr) armRetArgErrIf(armNot8ByteAligned(pSrcCoeff), OMX_Sts_BadArgErr) armRetArgErrIf(pScanMatrix == NULL, OMX_Sts_BadArgErr) armRetArgErrIf(pDstVLCInfo == NULL, OMX_Sts_BadArgErr) armRetArgErrIf(bAC > 1, OMX_Sts_BadArgErr) armRetArgErrIf(MaxNumCoef > 16, OMX_Sts_BadArgErr) /* Initialize RLE Info structure */ pDstVLCInfo->uTrailing_Ones = 0; pDstVLCInfo->uTrailing_One_Signs = 0; pDstVLCInfo->uNumCoeffs = 0; pDstVLCInfo->uTotalZeros = 0; for (i = 0; i < 16; i++) { pDstVLCInfo->iLevels [i] = 0; pDstVLCInfo->uRuns [i] = 0; } MinIndex = (bAC == 0 && MaxNumCoef == 15) ? 1 : 0; for (i = MinIndex; i < (MaxNumCoef + MinIndex); i++) { /* Scan */ Buf [i - MinIndex] = pSrcCoeff [pScanMatrix [i]]; } /* skip zeros at the end */ i = MaxNumCoef - 1; while (!Buf [i] && i >= 0) { i--; } if (i < 0) { return OMX_Sts_NoErr; } /* Fill RLE Info structure */ pLevel = pDstVLCInfo->iLevels; pRun = pDstVLCInfo->uRuns; RunBefore = 0; /* Handle first non zero separate */ pDstVLCInfo->uNumCoeffs++; Value = Buf [i]; if (Value == 1 || Value == -1) { pDstVLCInfo->uTrailing_Ones++; pDstVLCInfo->uTrailing_One_Signs |= Value == -1 ? Mask : 0; Mask >>= 1; }
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 omxSP_FFTFwd_CToC_SC16_Sfs( const OMX_SC16 *pSrc, OMX_SC16 *pDst, const OMXFFTSpec_C_SC16 *pFFTSpec, OMX_INT scaleFactor ) { OMX_INT block, point; OMX_INT i, j, N, NBy2; OMX_U16 *pRevIndex; OMX_FC64 *out; OMX_FC64 *pT1, *pT2, *pT, *pTw, T; ARMsFFTSpec_FC64 *pFFTStruct; /* Input parameter check */ armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr) armRetArgErrIf(armNot32ByteAligned(pSrc), OMX_Sts_BadArgErr) armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr) armRetArgErrIf(armNot32ByteAligned(pDst), OMX_Sts_BadArgErr) armRetArgErrIf(pFFTSpec == NULL, OMX_Sts_BadArgErr) armRetArgErrIf(scaleFactor < 0, OMX_Sts_BadArgErr) armRetArgErrIf(scaleFactor > 16, OMX_Sts_BadArgErr) /* Order range check */ pFFTStruct = (ARMsFFTSpec_FC64 *) pFFTSpec; N = pFFTStruct->N; armRetArgErrIf(N < 1, OMX_Sts_BadArgErr) armRetArgErrIf(N > (1 << 12), OMX_Sts_BadArgErr) /* Handle order zero case separate */ if (N == 1) { pDst [0].Re = armSatRoundRightShift_S32_S16 (pSrc[0].Re, scaleFactor); pDst [0].Im = armSatRoundRightShift_S32_S16 (pSrc[0].Im, scaleFactor); return OMX_Sts_NoErr; } /* Do fft in float */ out = pFFTStruct->pBuf; /* bit reversal */ pRevIndex = pFFTStruct->pBitRev; for (i = 0; i < N; i++) { out [pRevIndex [i]].Re = (OMX_F64) pSrc [i]. Re; out [pRevIndex [i]].Im = (OMX_F64) pSrc [i]. Im; } NBy2 = N >> 1; pT = &T; point = 2; for (block = NBy2; block > 0; block >>= 1) { pTw = pFFTStruct->pTwiddle; for (i = 0; i < point / 2; i++) { pT1 = out + i; pT2 = pT1 + (point / 2); for (j = 0; j < block; j++) { armSP_CPLX_MUL (pT, pTw, pT2); armSP_CPLX_SUB (pT2, pT1, pT); armSP_CPLX_ADD (pT1, pT1, pT); pT1 += point; pT2 += point; } pTw += block; } point <<= 1; } /* revert back from float */ for (i = 0; i < N; i++) { out [i].Re /= (1 << scaleFactor); out [i].Im /= (1 << scaleFactor); pDst [i]. Re = armSatRoundFloatToS16 (out [i].Re); pDst [i]. Im = armSatRoundFloatToS16 (out [i].Im); } 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_TransRecBlockCoef_intra( const OMX_U8 *pSrc, OMX_S16 * pDst, OMX_U8 * pRec, OMX_S16 *pPredBufRow, OMX_S16 *pPredBufCol, OMX_S16 * pPreACPredict, OMX_INT *pSumErr, OMX_INT blockIndex, OMX_U8 curQp, const OMX_U8 *pQpBuf, OMX_INT srcStep, OMX_INT dstStep, OMX_INT shortVideoHeader ) { /* 64 elements are needed but to align it to 16 bytes need 8 more elements of padding */ OMX_S16 tempBuf1[79], tempBuf2[79]; OMX_S16 tempBuf3[79]; OMX_S16 *pTempBuf1, *pTempBuf2,*pTempBuf3; OMXVCM4P2VideoComponent videoComp; OMX_U8 flag; OMX_INT x, y, count, predDir; OMX_INT predQP, ACPredFlag; /* Aligning the local buffers */ pTempBuf1 = armAlignTo16Bytes(tempBuf1); pTempBuf2 = armAlignTo16Bytes(tempBuf2); pTempBuf3 = armAlignTo16Bytes(tempBuf3); /* Argument error checks */ armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pRec == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(!armIs8ByteAligned(pSrc), OMX_Sts_BadArgErr); armRetArgErrIf(!armIs8ByteAligned(pRec), OMX_Sts_BadArgErr); armRetArgErrIf(!armIs16ByteAligned(pDst), OMX_Sts_BadArgErr); armRetArgErrIf(pPredBufRow == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pPredBufCol == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pPreACPredict == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pSumErr == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pQpBuf == NULL, OMX_Sts_BadArgErr); armRetArgErrIf((srcStep <= 0) || (dstStep <= 0) || (dstStep & 7) || (srcStep & 7) , OMX_Sts_BadArgErr); armRetArgErrIf((blockIndex < 0) || (blockIndex > 9), OMX_Sts_BadArgErr); armRetArgErrIf((curQp <= 0) || (curQp >=32), OMX_Sts_BadArgErr); /* Setting the videoComp */ if (blockIndex <= 3) { videoComp = OMX_VC_LUMINANCE; } else { videoComp = OMX_VC_CHROMINANCE; } /* Converting from 2-d to 1-d buffer */ for (y = 0, count = 0; y < 8; y++) { for(x= 0; x < 8; x++, count++) { pTempBuf1[count] = pSrc[(y*srcStep) + x]; } } omxVCM4P2_DCT8x8blk (pTempBuf1, pTempBuf2); omxVCM4P2_QuantIntra_I( pTempBuf2, curQp, blockIndex, shortVideoHeader); /* Converting from 1-D to 2-D buffer */ for (y = 0, count = 0; y < 8; y++) { for(x = 0; x < 8; x++, count++) { /* storing tempbuf2 to tempbuf1 */ pTempBuf1[count] = pTempBuf2[count]; pDst[(y*dstStep) + x] = pTempBuf2[count]; } } /* AC and DC prediction */ armVCM4P2_SetPredDir( blockIndex, pPredBufRow, pPredBufCol, &predDir, &predQP, pQpBuf); armRetDataErrIf(((predQP <= 0) || (predQP >= 32)), OMX_Sts_BadArgErr); flag = 1; if (*pSumErr < 0) { ACPredFlag = 0; } else { ACPredFlag = 1; } armVCM4P2_ACDCPredict( pTempBuf2, pPreACPredict, pPredBufRow, pPredBufCol, curQp, predQP, predDir, ACPredFlag, videoComp, flag, pSumErr); /* Reconstructing the texture data */ omxVCM4P2_QuantInvIntra_I( pTempBuf1, curQp, videoComp, shortVideoHeader); omxVCM4P2_IDCT8x8blk (pTempBuf1, pTempBuf3); for(count = 0; count < 64; count++) { pRec[count] = armMax(0,pTempBuf3[count]); } 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; }
OMXResult armVCM4P10_InterpolateHalfDiag_Luma( const OMX_U8* pSrc, OMX_U32 iSrcStep, OMX_U8* pDst, OMX_U32 iDstStep, OMX_U32 iWidth, OMX_U32 iHeight ) { OMX_S32 HalfCoeff, pos; OMX_S16 Buf [21 * 16]; /* 21 rows by 16 pixels per row */ OMX_U32 y, x; /* check for argument error */ armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr) armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr) /* * Intermediate values will be 1/2 pel at Horizontal direction * Starting at (0.5, -2) at top extending to (0.5, height + 3) at bottom * Buf contains a 2D array of size (iWidth)X(iHeight + 5) */ for (y = 0; y < iHeight + 5; y++) { for (x = 0; x < iWidth; x++) { pos = (y-2) * iSrcStep + x; HalfCoeff = pSrc [pos - 2] - 5 * pSrc [pos - 1] + 20 * pSrc [pos] + 20 * pSrc [pos + 1] - 5 * pSrc [pos + 2] + pSrc [pos + 3]; Buf [y * iWidth + x] = (OMX_S16)HalfCoeff; } /* x */ } /* y */ /* Vertical interpolate */ for (y = 0; y < iHeight; y++) { for (x = 0; x < iWidth; x++) { pos = y * iWidth + x; HalfCoeff = Buf [pos] - 5 * Buf [pos + 1 * iWidth] + 20 * Buf [pos + 2 * iWidth] + 20 * Buf [pos + 3 * iWidth] - 5 * Buf [pos + 4 * iWidth] + Buf [pos + 5 * iWidth]; HalfCoeff = (HalfCoeff + 512) >> 10; HalfCoeff = armClip(0, 255, HalfCoeff); pDst [y * iDstStep + x] = (OMX_U8) HalfCoeff; } } return OMX_Sts_NoErr; }