1/* 2 * Copyright (C) 2007-2008 ARM Limited 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * 16 */ 17/** 18 * 19 * File Name: omxVCM4P10_BlockMatch_Integer.c 20 * OpenMAX DL: v1.0.2 21 * Revision: 9641 22 * Date: Thursday, February 7, 2008 23 * 24 * 25 * 26 * 27 * Description: 28 * Contains modules for Block matching, a full search algorithm 29 * is implemented 30 * 31 */ 32 33#include "omxtypes.h" 34#include "armOMX.h" 35#include "omxVC.h" 36 37#include "armVC.h" 38#include "armCOMM.h" 39 40/** 41 * Function: omxVCM4P10_BlockMatch_Integer (6.3.5.2.1) 42 * 43 * Description: 44 * Performs integer block match. Returns best MV and associated cost. 45 * 46 * Input Arguments: 47 * 48 * pSrcOrgY - Pointer to the top-left corner of the current block. If 49 * iBlockWidth==4, 4-byte alignment required. If iBlockWidth==8, 50 * 8-byte alignment required. If iBlockWidth==16, 16-byte alignment 51 * required. 52 * pSrcRefY - Pointer to the top-left corner of the co-located block in the 53 * reference picture. If iBlockWidth==4, 4-byte alignment 54 * required. If iBlockWidth==8, 8-byte alignment required. If 55 * iBlockWidth==16, 16-byte alignment required. 56 * nSrcOrgStep - Stride of the original picture plane, expressed in terms 57 * of integer pixels; must be a multiple of iBlockWidth. 58 * nSrcRefStep - Stride of the reference picture plane, expressed in terms 59 * of integer pixels 60 * pRefRect - pointer to the valid reference rectangle inside the reference 61 * picture plane 62 * nCurrPointPos - position of the current block in the current plane 63 * iBlockWidth - Width of the current block, expressed in terms of integer 64 * pixels; must be equal to either 4, 8, or 16. 65 * iBlockHeight - Height of the current block, expressed in terms of 66 * integer pixels; must be equal to either 4, 8, or 16. 67 * nLamda - Lamda factor; used to compute motion cost 68 * pMVPred - Predicted MV; used to compute motion cost, expressed in terms 69 * of 1/4-pel units 70 * pMVCandidate - Candidate MV; used to initialize the motion search, 71 * expressed in terms of integer pixels 72 * pMESpec - pointer to the ME specification structure 73 * 74 * Output Arguments: 75 * 76 * pDstBestMV - Best MV resulting from integer search, expressed in terms 77 * of 1/4-pel units 78 * pBestCost - Motion cost associated with the best MV; computed as 79 * SAD+Lamda*BitsUsedByMV 80 * 81 * Return Value: 82 * OMX_Sts_NoErr, if the function runs without error. 83 * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs: 84 * - any of the following poitners are NULL: 85 * pSrcOrgY, pSrcRefY, pRefRect, pMVPred, pMVCandidate, or pMESpec. 86 * - Either iBlockWidth or iBlockHeight are values other than 4, 8, or 16. 87 * - Any alignment restrictions are violated 88 * 89 */ 90 91 OMXResult omxVCM4P10_BlockMatch_Integer ( 92 const OMX_U8 *pSrcOrgY, 93 OMX_S32 nSrcOrgStep, 94 const OMX_U8 *pSrcRefY, 95 OMX_S32 nSrcRefStep, 96 const OMXRect *pRefRect, 97 const OMXVCM4P2Coordinate *pCurrPointPos, 98 OMX_U8 iBlockWidth, 99 OMX_U8 iBlockHeight, 100 OMX_U32 nLamda, 101 const OMXVCMotionVector *pMVPred, 102 const OMXVCMotionVector *pMVCandidate, 103 OMXVCMotionVector *pBestMV, 104 OMX_S32 *pBestCost, 105 void *pMESpec 106) 107{ 108 /* Definitions and Initializations*/ 109 OMX_INT candSAD; 110 OMX_INT fromX, toX, fromY, toY; 111 /* Offset to the reference at the begining of the bounding box */ 112 const OMX_U8 *pTempSrcRefY, *pTempSrcOrgY; 113 OMX_S16 x, y; 114 OMXVCMotionVector diffMV; 115 OMX_S32 nSearchRange; 116 ARMVCM4P10_MESpec *armMESpec = (ARMVCM4P10_MESpec *) pMESpec; 117 118 /* Argument error checks */ 119 armRetArgErrIf((iBlockWidth == 4) && (!armIs4ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr); 120 armRetArgErrIf((iBlockWidth == 8) && (!armIs8ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr); 121 armRetArgErrIf((iBlockWidth == 16) && (!armIs16ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr); 122 armRetArgErrIf((iBlockWidth == 4) && (!armIs4ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr); 123 armRetArgErrIf((iBlockWidth == 8) && (!armIs8ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr); 124 armRetArgErrIf((iBlockWidth == 16) && (!armIs16ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr); 125 armRetArgErrIf(pSrcOrgY == NULL, OMX_Sts_BadArgErr); 126 armRetArgErrIf(pSrcRefY == NULL, OMX_Sts_BadArgErr); 127 armRetArgErrIf(pMVPred == NULL, OMX_Sts_BadArgErr); 128 armRetArgErrIf(pMVCandidate == NULL, OMX_Sts_BadArgErr); 129 armRetArgErrIf(pBestMV == NULL, OMX_Sts_BadArgErr); 130 armRetArgErrIf(pBestCost == NULL, OMX_Sts_BadArgErr); 131 armRetArgErrIf(((iBlockWidth!=4)&&(iBlockWidth!=8)&&(iBlockWidth!=16)) , OMX_Sts_BadArgErr); 132 armRetArgErrIf(((iBlockHeight!=4)&&(iBlockHeight!=8)&&(iBlockHeight!=16)) , OMX_Sts_BadArgErr); 133 armIgnore (pMESpec); 134 135 if(iBlockWidth == 4) 136 { 137 nSearchRange = armMESpec->MEParams.searchRange4x4; 138 } 139 else if(iBlockWidth == 8) 140 { 141 nSearchRange = armMESpec->MEParams.searchRange8x8; 142 } 143 else 144 { 145 nSearchRange = armMESpec->MEParams.searchRange16x16; 146 } 147 /* Check for valid region */ 148 fromX = nSearchRange; 149 toX = nSearchRange; 150 fromY = nSearchRange; 151 toY = nSearchRange; 152 153 if ((pCurrPointPos->x - nSearchRange) < pRefRect->x) 154 { 155 fromX = pCurrPointPos->x - pRefRect->x; 156 } 157 158 if ((pCurrPointPos->x + iBlockWidth + nSearchRange) > (pRefRect->x + pRefRect->width)) 159 { 160 toX = pRefRect->width - (pCurrPointPos->x - pRefRect->x) - iBlockWidth; 161 } 162 163 if ((pCurrPointPos->y - nSearchRange) < pRefRect->y) 164 { 165 fromY = pCurrPointPos->y - pRefRect->y; 166 } 167 168 if ((pCurrPointPos->y + iBlockWidth + nSearchRange) > (pRefRect->y + pRefRect->height)) 169 { 170 toY = pRefRect->width - (pCurrPointPos->y - pRefRect->y) - iBlockWidth; 171 } 172 173 pBestMV->dx = -fromX * 4; 174 pBestMV->dy = -fromY * 4; 175 /* Initialize to max value as a start point */ 176 *pBestCost = 0x7fffffff; 177 178 /* Looping on y- axis */ 179 for (y = -fromY; y <= toY; y++) 180 { 181 /* Looping on x- axis */ 182 for (x = -fromX; x <= toX; x++) 183 { 184 /* Positioning the pointer */ 185 pTempSrcRefY = pSrcRefY + (nSrcRefStep * y) + x; 186 pTempSrcOrgY = pSrcOrgY; 187 188 /* Calculate the SAD */ 189 armVCCOMM_SAD( 190 pTempSrcOrgY, 191 nSrcOrgStep, 192 pTempSrcRefY, 193 nSrcRefStep, 194 &candSAD, 195 iBlockHeight, 196 iBlockWidth); 197 198 diffMV.dx = (x * 4) - pMVPred->dx; 199 diffMV.dy = (y * 4) - pMVPred->dy; 200 201 /* Result calculations */ 202 armVCM4P10_CompareMotionCostToMV ((x * 4), (y * 4), diffMV, candSAD, pBestMV, nLamda, pBestCost); 203 204 } /* End of x- axis */ 205 } /* End of y-axis */ 206 207 return OMX_Sts_NoErr; 208 209} 210 211/* End of file */ 212