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_Half.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 half pel Block matching, 29 * 30 */ 31 32 #include "omxtypes.h" 33 #include "armOMX.h" 34 #include "omxVC.h" 35 36 #include "armVC.h" 37 #include "armCOMM.h" 38 39 40 /** 41 * Function: omxVCM4P10_BlockMatch_Half (6.3.5.2.2) 42 * 43 * Description: 44 * Performs a half-pel block match using results from a prior integer search. 45 * Returns the best MV and associated cost. This function estimates the 46 * half-pixel motion vector by interpolating the integer resolution motion 47 * vector referenced by the input parameter pSrcDstBestMV, i.e., the initial 48 * integer MV is generated externally. The function 49 * omxVCM4P10_BlockMatch_Integer may be used for integer motion estimation. 50 * 51 * Input Arguments: 52 * 53 * pSrcOrgY - Pointer to the current position in original picture plane. If 54 * iBlockWidth==4, 4-byte alignment required. If iBlockWidth==8, 55 * 8-byte alignment required. If iBlockWidth==16, 16-byte alignment 56 * required. 57 * pSrcRefY - Pointer to the top-left corner of the co-located block in the 58 * reference picture If iBlockWidth==4, 4-byte alignment 59 * required. If iBlockWidth==8, 8-byte alignment required. If 60 * iBlockWidth==16, 16-byte alignment required. 61 * nSrcOrgStep - Stride of the original picture plane in terms of full 62 * pixels; must be a multiple of iBlockWidth. 63 * nSrcRefStep - Stride of the reference picture plane in terms of full 64 * pixels 65 * iBlockWidth - Width of the current block in terms of full pixels; must 66 * be equal to either 4, 8, or 16. 67 * iBlockHeight - Height of the current block in terms of full pixels; must 68 * be equal to either 4, 8, or 16. 69 * nLamda - Lamda factor, used to compute motion cost 70 * pMVPred - Predicted MV, represented in terms of 1/4-pel units; used to 71 * compute motion cost 72 * pSrcDstBestMV - The best MV resulting from a prior integer search, 73 * represented in terms of 1/4-pel units 74 * 75 * Output Arguments: 76 * 77 * pSrcDstBestMV - Best MV resulting from the half-pel search, expressed in 78 * terms of 1/4-pel units 79 * pBestCost - Motion cost associated with the best MV; computed as 80 * SAD+Lamda*BitsUsedByMV 81 * 82 * Return Value: 83 * OMX_Sts_NoErr, if the function runs without error. 84 * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs: 85 * - any of the following pointers is NULL: pSrcOrgY, pSrcRefY, 86 * pSrcDstBestMV, pMVPred, pBestCost 87 * - iBlockWidth or iBlockHeight are equal to values other than 4, 8, or 16. 88 * - Any alignment restrictions are violated 89 * 90 */ 91 92 OMXResult omxVCM4P10_BlockMatch_Half( 93 const OMX_U8* pSrcOrgY, 94 OMX_S32 nSrcOrgStep, 95 const OMX_U8* pSrcRefY, 96 OMX_S32 nSrcRefStep, 97 OMX_U8 iBlockWidth, 98 OMX_U8 iBlockHeight, 99 OMX_U32 nLamda, 100 const OMXVCMotionVector* pMVPred, 101 OMXVCMotionVector* pSrcDstBestMV, 102 OMX_S32* pBestCost 103 ) 104 { 105 /* Definitions and Initializations*/ 106 OMX_INT candSAD; 107 OMX_INT fromX, toX, fromY, toY; 108 /* Offset to the reference at the begining of the bounding box */ 109 const OMX_U8 *pTempSrcRefY, *pTempSrcOrgY; 110 OMX_S16 x, y; 111 OMXVCMotionVector diffMV, candMV, integerMV; 112 OMX_U8 interpolY[256]; 113 114 /* Argument error checks */ 115 armRetArgErrIf((iBlockWidth == 4) && (!armIs4ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr); 116 armRetArgErrIf((iBlockWidth == 8) && (!armIs8ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr); 117 armRetArgErrIf((iBlockWidth == 16) && (!armIs16ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr); 118 armRetArgErrIf((iBlockWidth == 4) && (!armIs4ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr); 119 armRetArgErrIf((iBlockWidth == 8) && (!armIs8ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr); 120 armRetArgErrIf((iBlockWidth == 16) && (!armIs16ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr); 121 armRetArgErrIf((nSrcOrgStep % iBlockWidth), OMX_Sts_BadArgErr); 122 armRetArgErrIf(pSrcOrgY == NULL, OMX_Sts_BadArgErr); 123 armRetArgErrIf(pSrcRefY == NULL, OMX_Sts_BadArgErr); 124 armRetArgErrIf(pMVPred == NULL, OMX_Sts_BadArgErr); 125 armRetArgErrIf(pSrcDstBestMV == NULL, OMX_Sts_BadArgErr); 126 armRetArgErrIf(pBestCost == NULL, OMX_Sts_BadArgErr); 127 armRetArgErrIf(((iBlockWidth!=4)&&(iBlockWidth!=8)&&(iBlockWidth!=16)) , OMX_Sts_BadArgErr); 128 armRetArgErrIf(((iBlockHeight!=4)&&(iBlockHeight!=8)&&(iBlockHeight!=16)) , OMX_Sts_BadArgErr); 129 130 131 /* Check for valid region */ 132 fromX = 1; 133 toX = 1; 134 fromY = 1; 135 toY = 1; 136 137 /* Initialize to max value as a start point */ 138 *pBestCost = 0x7fffffff; 139 140 integerMV.dx = pSrcDstBestMV->dx; 141 integerMV.dy = pSrcDstBestMV->dy; 142 143 /* Looping on y- axis */ 144 for (y = -fromY; y <= toY; y++) 145 { 146 /* Looping on x- axis */ 147 for (x = -fromX; x <= toX; x++) 148 { 149 /* Positioning the pointer */ 150 pTempSrcRefY = pSrcRefY + (nSrcRefStep * (integerMV.dy/4)) + (integerMV.dx/4); 151 if (x < 0) 152 { 153 pTempSrcRefY = pTempSrcRefY + x; 154 } 155 if (y < 0) 156 { 157 pTempSrcRefY = pTempSrcRefY + (y * nSrcRefStep); 158 } 159 pTempSrcOrgY = pSrcOrgY; 160 161 /* Prepare cand MV */ 162 candMV.dx = integerMV.dx + x * 2; 163 candMV.dy = integerMV.dy + y * 2; 164 165 /* Interpolate half pel for the current position*/ 166 armVCM4P10_Interpolate_Luma( 167 pTempSrcRefY, 168 nSrcRefStep, 169 interpolY, 170 iBlockWidth, 171 iBlockWidth, 172 iBlockHeight, 173 armAbs(x) * 2, 174 armAbs(y) * 2); 175 176 /* Calculate the SAD */ 177 armVCCOMM_SAD( 178 pTempSrcOrgY, 179 nSrcOrgStep, 180 interpolY, 181 iBlockWidth, 182 &candSAD, 183 iBlockHeight, 184 iBlockWidth); 185 186 diffMV.dx = candMV.dx - pMVPred->dx; 187 diffMV.dy = candMV.dy - pMVPred->dy; 188 189 /* Result calculations */ 190 armVCM4P10_CompareMotionCostToMV ( 191 candMV.dx, 192 candMV.dy, 193 diffMV, 194 candSAD, 195 pSrcDstBestMV, 196 nLamda, 197 pBestCost); 198 199 } /* End of x- axis */ 200 } /* End of y-axis */ 201 202 return OMX_Sts_NoErr; 203 204 } 205 206 /* End of file */ 207