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: omxVCM4P2_MCReconBlock.c 20 * OpenMAX DL: v1.0.2 21 * Revision: 9641 22 * Date: Thursday, February 7, 2008 23 * 24 * 25 * 26 * Description: 27 * MPEG4 motion compensation prediction for an 8x8 block using 28 * interpolation 29 * 30 */ 31 32 #include "omxtypes.h" 33 #include "armOMX.h" 34 #include "omxVC.h" 35 36 #include "armCOMM.h" 37 38 /** 39 * Function: armVCM4P2_HalfPelVer 40 * 41 * Description: 42 * Performs half pel motion compensation for an 8x8 block using vertical 43 * interpolation described in ISO/IEC 14496-2, subclause 7.6.2. 44 * 45 * Remarks: 46 * 47 * Parameters: 48 * [in] pSrc pointer to the block in the reference plane. 49 * [in] srcStep distance between the start of consecutive lines 50 * in the reference plane, in bytes; must be a multiple 51 * of 8. 52 * [in] rndVal rounding control parameter: 0 - disabled; 1 - enabled. 53 * [out] pDst pointer to the linaer 8x8 destination buffer; 54 * 55 */ 56 static OMXVoid armVCM4P2_HalfPelVer( 57 const OMX_U8 *pSrc, 58 OMX_INT srcStep, 59 OMX_U8 *pDst, 60 OMX_INT rndVal) 61 { 62 const OMX_U8 *pTempSrc1; 63 const OMX_U8 *pTempSrc2; 64 OMX_INT y, x; 65 66 pTempSrc1 = pSrc; 67 pTempSrc2 = pSrc + srcStep; 68 srcStep -= 8; 69 for (y = 0; y < 8; y++) 70 { 71 for (x = 0; x < 8; x++) 72 { 73 *pDst++ = ((*pTempSrc1++ + *pTempSrc2++) + 1 - rndVal) >> 1; 74 } 75 pTempSrc1 += srcStep; 76 pTempSrc2 += srcStep; 77 } 78 } 79 80 /** 81 * Function: armVCM4P2_HalfPelHor 82 * 83 * Description: 84 * Performs half pel motion compensation for an 8x8 block using horizontal 85 * interpolation described in ISO/IEC 14496-2, subclause 7.6.2. 86 * 87 * Remarks: 88 * 89 * Parameters: 90 * [in] pSrc pointer to the block in the reference plane. 91 * [in] srcStep distance between the start of consecutive lines 92 * in the reference plane, in bytes; must be a multiple 93 * of 8. 94 * [in] rndVal rounding control parameter: 0 - disabled; 1 - enabled. 95 * [out] pDst pointer to the linaer 8x8 destination buffer; 96 * 97 */ 98 static OMXVoid armVCM4P2_HalfPelHor( 99 const OMX_U8 *pSrc, 100 OMX_INT srcStep, 101 OMX_U8 *pDst, 102 OMX_INT rndVal) 103 { 104 const OMX_U8 *pTempSrc1; 105 const OMX_U8 *pTempSrc2; 106 OMX_INT y, x; 107 108 pTempSrc1 = pSrc; 109 pTempSrc2 = pTempSrc1 + 1; 110 111 srcStep -= 8; 112 for (y=0; y<8; y++) 113 { 114 for (x=0; x<8; x++) 115 { 116 *pDst++ = ((*pTempSrc1++ + *pTempSrc2++) + 1 - rndVal) >> 1; 117 } 118 pTempSrc1 += srcStep; 119 pTempSrc2 += srcStep; 120 } 121 } 122 123 124 /** 125 * Function: armVCM4P2_HalfPelVerHor 126 * 127 * Description: 128 * Performs half pel motion compensation for an 8x8 block using both 129 * horizontal and vertical interpolation described in ISO/IEC 14496-2, 130 * subclause 7.6.2. 131 * 132 * Remarks: 133 * 134 * Parameters: 135 * [in] pSrc pointer to the block in the reference plane. 136 * [in] srcStep distance between the start of consecutive lines 137 * in the reference plane, in bytes; must be a multiple 138 * of 8. 139 * [in] rndVal rounding control parameter: 0 - disabled; 1 - enabled. 140 * [out] pDst pointer to the linaer 8x8 destination buffer; 141 * 142 */ 143 static OMXVoid armVCM4P2_HalfPelVerHor( 144 const OMX_U8 *pSrc, 145 OMX_INT srcStep, 146 OMX_U8 *pDst, 147 OMX_INT rndVal) 148 { 149 const OMX_U8 *pTempSrc1; 150 const OMX_U8 *pTempSrc2; 151 const OMX_U8 *pTempSrc3; 152 const OMX_U8 *pTempSrc4; 153 OMX_INT y, x; 154 155 pTempSrc1 = pSrc; 156 pTempSrc2 = pSrc + srcStep; 157 pTempSrc3 = pSrc + 1; 158 pTempSrc4 = pSrc + srcStep + 1; 159 160 srcStep -= 8; 161 for (y=0; y<8; y++) 162 { 163 for (x=0; x<8; x++) 164 { 165 *pDst++ = ((*pTempSrc1++ + *pTempSrc2++ + *pTempSrc3++ + *pTempSrc4++) + 166 2 - rndVal) >> 2; 167 } 168 pTempSrc1 += srcStep; 169 pTempSrc2 += srcStep; 170 pTempSrc3 += srcStep; 171 pTempSrc4 += srcStep; 172 } 173 } 174 175 /** 176 * Function: armVCM4P2_MCReconBlock_NoRes 177 * 178 * Description: 179 * Do motion compensation and copy the result to the current block. 180 * 181 * Remarks: 182 * 183 * Parameters: 184 * [in] pSrc pointer to the block in the reference plane. 185 * [in] srcStep distance between the start of consecutive lines 186 * in the reference plane, in bytes; must be a multiple 187 * of 8. 188 * [in] dstStep distance between the start of consecutive lines in the 189 * destination plane, in bytes; must be a multiple of 8. 190 * [in] predictType bilinear interpolation type, as defined in section 6.2.1.2. 191 * [in] rndVal rounding control parameter: 0 - disabled; 1 - enabled. 192 * [out] pDst pointer to the destination buffer; must be 8-byte aligned. 193 * If prediction residuals are added then output intensities 194 * are clipped to the range [0,255]. 195 * 196 */ 197 static OMXVoid armVCM4P2_MCReconBlock_NoRes( 198 const OMX_U8 *pSrc, 199 OMX_INT srcStep, 200 OMX_U8 *pDst, 201 OMX_INT dstStep) 202 { 203 OMX_U8 x,y,count,index; 204 205 /* Copying the ref 8x8 blk to the curr blk */ 206 for (y = 0, count = 0, index = 0; y < 8; y++,index += (srcStep -8), count += (dstStep - 8)) 207 { 208 for (x = 0; x < 8; x++, count++,index++) 209 { 210 pDst[count] = pSrc[index]; 211 } 212 } 213 } 214 215 /** 216 * Function: armVCM4P2_MCReconBlock_Res 217 * 218 * Description: 219 * Reconstructs INTER block by summing the motion compensation results 220 * and the results of the inverse transformation (prediction residuals). 221 * Output intensities are clipped to the range [0,255]. 222 * 223 * Remarks: 224 * 225 * Parameters: 226 * [in] pSrc pointer to the block in the reference plane. 227 * [in] pSrcResidue pointer to a buffer containing the 16-bit prediction 228 * residuals. If the pointer is NULL,then no prediction 229 * is done, only motion compensation, i.e., the block is 230 * moved with interpolation. 231 * [in] dstStep distance between the start of consecutive lines in the 232 * destination plane, in bytes; must be a multiple of 8. 233 * [out] pDst pointer to the destination buffer; must be 8-byte aligned. 234 * If prediction residuals are added then output intensities 235 * are clipped to the range [0,255]. 236 * 237 */ 238 static OMXVoid armVCM4P2_MCReconBlock_Res( 239 const OMX_U8 *pSrc, 240 const OMX_S16 *pSrcResidue, 241 OMX_U8 *pDst, 242 OMX_INT dstStep) 243 { 244 245 OMX_U8 x,y; 246 OMX_INT temp; 247 248 for(y = 0; y < 8; y++) 249 { 250 for(x = 0; x < 8; x++) 251 { 252 temp = pSrc[x] + pSrcResidue[x]; 253 pDst[x] = armClip(0,255,temp); 254 } 255 pDst += dstStep; 256 pSrc += 8; 257 pSrcResidue += 8; 258 } 259 } 260 261 /** 262 * Function: omxVCM4P2_MCReconBlock (6.2.5.5.1) 263 * 264 * Description: 265 * Performs motion compensation prediction for an 8x8 block using 266 * interpolation described in [ISO14496-2], subclause 7.6.2. 267 * 268 * Input Arguments: 269 * 270 * pSrc - pointer to the block in the reference plane. 271 * srcStep - distance between the start of consecutive lines in the 272 * reference plane, in bytes; must be a multiple of 8. 273 * dstStep - distance between the start of consecutive lines in the 274 * destination plane, in bytes; must be a multiple of 8. 275 * pSrcResidue - pointer to a buffer containing the 16-bit prediction 276 * residuals; must be 16-byte aligned. If the pointer is NULL, then 277 * no prediction is done, only motion compensation, i.e., the block 278 * is moved with interpolation. 279 * predictType - bilinear interpolation type, as defined in section 280 * 6.2.1.2. 281 * rndVal - rounding control parameter: 0 - disabled; 1 - enabled. 282 * 283 * Output Arguments: 284 * 285 * pDst - pointer to the destination buffer; must be 8-byte aligned. If 286 * prediction residuals are added then output intensities are 287 * clipped to the range [0,255]. 288 * 289 * Return Value: 290 * 291 * OMX_Sts_NoErr - no error 292 * OMX_Sts_BadArgErr - bad arguments; returned under any of the following 293 * conditions: 294 * - pDst is not 8-byte aligned. 295 * - pSrcResidue is not 16-byte aligned. 296 * - one or more of the following pointers is NULL: pSrc or pDst. 297 * - either srcStep or dstStep is not a multiple of 8. 298 * - invalid type specified for the parameter predictType. 299 * - the parameter rndVal is not equal either to 0 or 1. 300 * 301 */ 302 OMXResult omxVCM4P2_MCReconBlock( 303 const OMX_U8 *pSrc, 304 OMX_INT srcStep, 305 const OMX_S16 *pSrcResidue, 306 OMX_U8 *pDst, 307 OMX_INT dstStep, 308 OMX_INT predictType, 309 OMX_INT rndVal) 310 { 311 /* Definitions and Initializations*/ 312 OMX_U8 pTempDst[64]; 313 314 /* Argument error checks */ 315 armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr); 316 armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr); 317 armRetArgErrIf(!armIs8ByteAligned(pDst), OMX_Sts_BadArgErr); 318 armRetArgErrIf(!armIs16ByteAligned(pSrcResidue), OMX_Sts_BadArgErr); 319 armRetArgErrIf(((dstStep % 8) || (srcStep % 8)), OMX_Sts_BadArgErr); 320 armRetArgErrIf(((predictType != OMX_VC_INTEGER_PIXEL) && 321 (predictType != OMX_VC_HALF_PIXEL_X) && 322 (predictType != OMX_VC_HALF_PIXEL_Y) && 323 (predictType != OMX_VC_HALF_PIXEL_XY) 324 ),OMX_Sts_BadArgErr); 325 armRetArgErrIf(((rndVal != 0) && (rndVal != 1)),OMX_Sts_BadArgErr); 326 327 switch(predictType) 328 { 329 case OMX_VC_INTEGER_PIXEL: 330 armVCM4P2_MCReconBlock_NoRes(pSrc, 331 srcStep, 332 &(pTempDst[0]), 333 8); 334 break; 335 case OMX_VC_HALF_PIXEL_X: 336 armVCM4P2_HalfPelHor(pSrc, 337 srcStep, 338 &(pTempDst[0]), 339 rndVal); 340 break; 341 case OMX_VC_HALF_PIXEL_Y: 342 armVCM4P2_HalfPelVer(pSrc, 343 srcStep, 344 &(pTempDst[0]), 345 rndVal); 346 break; 347 case OMX_VC_HALF_PIXEL_XY: 348 armVCM4P2_HalfPelVerHor(pSrc, 349 srcStep, 350 &(pTempDst[0]), 351 rndVal); 352 break; 353 } 354 355 if(pSrcResidue == NULL) 356 { 357 armVCM4P2_MCReconBlock_NoRes(&(pTempDst[0]), 358 8, 359 pDst, 360 dstStep); 361 } 362 else 363 { 364 armVCM4P2_MCReconBlock_Res(&(pTempDst[0]), 365 pSrcResidue, 366 pDst, 367 dstStep); 368 } 369 370 return OMX_Sts_NoErr; 371 } 372 373