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 /** x
18 *
19 * File Name: omxVCM4P10_MotionEstimationMB.c
20 * OpenMAX DL: v1.0.2
21 * Revision: 9641
22 * Date: Thursday, February 7, 2008
23 *
24 *
25 *
26 * Description:
27 * This function perform MB level motion estimation
28 *
29 */
30
31 #include "omxtypes.h"
32 #include "armOMX.h"
33 #include "omxVC.h"
34
35 #include "armCOMM.h"
36 #include "armVC.h"
37
38 #define ARM_VCM4P10_MAX_FRAMES (15)
39 #define ARM_VCM4P10_MAX_4x4_SAD (0xffff)
40 #define ARM_VCM4P10_MAX_MODE_VALUE (0xffffffff)
41 #define ARM_VCM4P10_MAX_MODES (16)
42 #define ARM_VCM4P10_MB_BLOCK_SIZE (16)
43 #define ARM_VCM4P10_MEDIAN(a,b,c) (a>b?a>c?b>c?b:c:a:b>c?a>c?a:c:b)
44 #define ARM_VCM4P10_SHIFT_QP (12)
45
46 #define ARM_VCM4P10_MVPRED_MEDIAN (0)
47 #define ARM_VCM4P10_MVPRED_L (1)
48 #define ARM_VCM4P10_MVPRED_U (2)
49 #define ARM_VCM4P10_MVPRED_UR (3)
50
51 #define ARM_VCM4P10_MB_BLOCK_SIZE (16)
52 #define ARM_VCM4P10_BLOCK_SIZE (4)
53 #define ARM_VCM4P10_MAX_COST (1 << 30)
54 #define ARM_VCM4P10_INVALID_BLOCK (-2)
55
56
57 /**
58 * Function: armVCM4P10_CalculateBlockSAD
59 *
60 * Description:
61 * Calculate SAD value for the selected MB encoding mode and update
62 * pDstBlockSAD parameter. These SAD values are calculated 4x4 blocks at
63 * a time and in the scan order.
64 *
65 * Remarks:
66 *
67 * Parameters:
68 * [in] pSrcMBInfo -
69 * [in] pSrcCurrBuf -
70 * [in] SrcCurrStep -
71 * [in] pSrcRefBufList-
72 * [in] SrcRefStep -
73 * [in] pSrcRecBuf -
74 * [in] SrcRecStep -
75 * [in] pRefRect -
76 * [in] pCurrPointPos -
77 * [in] Lambda -
78 * [in] pMESpec -
79 * [in] pMBInter -
80 * [in] pMBIntra -
81 * [out] pDstBlockSAD - pointer to 16 element array for SAD corresponding to 4x4 blocks
82 * Return Value:
83 * None
84 *
85 */
86
armVCM4P10_CalculateBlockSAD(OMXVCM4P10MBInfo * pSrcMBInfo,const OMX_U8 * pSrcCurrBuf,OMX_S32 SrcCurrStep,const OMX_U8 * pSrcRefBufList[ARM_VCM4P10_MAX_FRAMES],OMX_S32 SrcRefStep,const OMX_U8 * pSrcRecBuf,OMX_S32 SrcRecStep,const OMXRect * pRefRect,const OMXVCM4P2Coordinate * pCurrPointPos,const OMXVCM4P10MBInfoPtr * pMBInter,const OMXVCM4P10MBInfoPtr * pMBIntra,OMX_U16 * pDstBlockSAD)87 static OMXResult armVCM4P10_CalculateBlockSAD(
88 OMXVCM4P10MBInfo *pSrcMBInfo,
89 const OMX_U8 *pSrcCurrBuf,
90 OMX_S32 SrcCurrStep,
91 const OMX_U8 *pSrcRefBufList[ARM_VCM4P10_MAX_FRAMES],
92 OMX_S32 SrcRefStep,
93 const OMX_U8 *pSrcRecBuf,
94 OMX_S32 SrcRecStep,
95 const OMXRect *pRefRect,
96 const OMXVCM4P2Coordinate *pCurrPointPos,
97 const OMXVCM4P10MBInfoPtr *pMBInter,
98 const OMXVCM4P10MBInfoPtr *pMBIntra,
99 OMX_U16 *pDstBlockSAD)
100 {
101 OMX_INT InvalidSAD = 0;
102 OMX_INT i;
103
104 OMX_U8 Buffer [16*16 + 15];
105 OMX_U8 *pTempDstBuf;
106 OMX_S32 TempDstStep;
107 OMX_U8 *pTempRefBuf;
108 OMX_S32 TempRefStep;
109
110 /* Temporary buffer to store the predicted mb coefficients */
111 pTempDstBuf = armAlignTo16Bytes(Buffer);
112 TempDstStep = 16;
113
114 /* Update pDstBlockSAD if MB is a valid type */
115 if (pSrcMBInfo)
116 {
117 OMX_U32 Width=0, Height=0, MaxXPart, MaxYPart,MaxSubXPart,MaxSubYPart;
118
119 /* Depending on type of MB, do prediction and fill temp buffer */
120 switch (pSrcMBInfo->mbType)
121 {
122 case OMX_VC_P_16x16:
123 Width = 16;
124 Height = 16;
125 break;
126 case OMX_VC_P_16x8:
127 Width = 16;
128 Height = 8;
129 break;
130 case OMX_VC_P_8x16:
131 Width = 8;
132 Height = 16;
133 break;
134 case OMX_VC_P_8x8:
135 Width = 8;
136 Height = 8;
137 break;
138 case OMX_VC_INTRA_4x4:
139 {
140 /* Create predicted MB Intra4x4 mode */
141 OMX_S32 PredIntra4x4Mode [5][9];
142 OMX_S32 x, y, Block8x8, Block4x4, BlockX, BlockY;
143 OMX_U8 pSrcYBuff [(16*3)*(16*2)];
144 OMX_U8 *pSrcY;
145 OMX_S32 StepSrcY;
146 OMX_S32 availability;
147
148 for (y = 0; y < 5; y++)
149 {
150 for (x = 0; x < 9; x++)
151 {
152 /*
153 * Initialize with value of ARM_VCM4P10_INVALID_BLOCK, to mean this
154 * 4x4 block is not available
155 */
156 PredIntra4x4Mode [y][x] = ARM_VCM4P10_INVALID_BLOCK;
157 }
158 }
159
160 /* Replace ARM_VCM4P10_INVALID_BLOCK value with available MBs values*/
161 for (x = 0; x < 4; x++)
162 {
163 /* Store values of b0, b1, b2, b3 */
164 if (pMBIntra[1] != NULL)
165 {
166 PredIntra4x4Mode [0][x + 1] =
167 pMBIntra[1]->pIntra4x4PredMode[3*4 + x];
168 }
169
170 /* Store values of d0, d1, d2, d3 */
171 if (pMBIntra[3] != NULL)
172 {
173 PredIntra4x4Mode [0][x + 5] =
174 pMBIntra[3]->pIntra4x4PredMode[3*4 + x];
175 }
176 }
177
178 /* Store values of c3 */
179 if (pMBIntra[2] != NULL)
180 {
181 PredIntra4x4Mode [0][0] = pMBIntra[2]->pIntra4x4PredMode[15];
182 }
183
184 for (y = 0; y < 4; y++)
185 {
186 /* Store values of a0, a1, a2, a3 */
187 if (pMBIntra[0] != NULL)
188 {
189 PredIntra4x4Mode [y + 1][0] =
190 pMBIntra[0]->pIntra4x4PredMode[y*4 + 3];
191 }
192 }
193
194 /*
195 * Update neighbouring Pred mode array which will be used for
196 * prediction of Intra4x4 modes.
197 */
198
199 pSrcY = pSrcYBuff;
200 StepSrcY = 16 * 3;
201 for (y = 0; y < (16 * 2); y++)
202 {
203 for (x = 0; x < (16 * 3); x++)
204 {
205 pSrcY [StepSrcY * y + x] =
206 pSrcRecBuf [SrcRecStep * (y - 16) + x - 16];
207 }
208 }
209
210
211 /* for each 8x8 block */
212 for (Block8x8 = 0; Block8x8 < 4; Block8x8++)
213 {
214 /* for each 4x4 block inside 8x8 block */
215 for (Block4x4 = 0; Block4x4 < 4; Block4x4++)
216 {
217 /* Get block cordinates from 8x8 block index and 4x4 block index */
218 BlockX = ((Block8x8 & 1) << 1) + (Block4x4 & 1);
219 BlockY = ((Block8x8 >> 1) << 1) + (Block4x4 >> 1);
220
221 /* Add offset to point to start of current MB in the array pIntra4x4PredMode */
222 x = BlockX + 1;
223 y = BlockY + 1;
224
225 availability = 0;
226
227 /* Check for availability of LEFT Block */
228 if (PredIntra4x4Mode [y][x - 1] != ARM_VCM4P10_INVALID_BLOCK)
229 {
230 availability |= OMX_VC_LEFT;
231 }
232
233 /* Check for availability of UPPER Block */
234 if (PredIntra4x4Mode [y - 1][x] != ARM_VCM4P10_INVALID_BLOCK)
235 {
236 availability |= OMX_VC_UPPER;
237 }
238
239 /* Check for availability of UPPER LEFT Block */
240 if (PredIntra4x4Mode [y - 1][x - 1] != ARM_VCM4P10_INVALID_BLOCK)
241 {
242 availability |= OMX_VC_UPPER_LEFT;
243 }
244
245 PredIntra4x4Mode [y][x] = pSrcMBInfo->pIntra4x4PredMode[BlockY*4+BlockX];
246 x = BlockX * 4;
247 y = BlockY * 4;
248
249 pSrcY = pSrcYBuff + 16 * StepSrcY + 16 + y * StepSrcY + x;
250
251 omxVCM4P10_PredictIntra_4x4(
252 pSrcY - 1,
253 pSrcY - StepSrcY,
254 pSrcY - StepSrcY - 1,
255 pTempDstBuf + x + y * TempDstStep,
256 StepSrcY,
257 TempDstStep,
258 pSrcMBInfo->pIntra4x4PredMode[BlockY*4+BlockX],
259 availability);
260
261 for (BlockY=0;BlockY<4;BlockY++)
262 {
263 for(BlockX=0;BlockX<4;BlockX++)
264 {
265 pSrcY [BlockY * StepSrcY + BlockX] =
266 (OMX_U8)(*(pTempDstBuf + x + y * TempDstStep + BlockY * TempDstStep + BlockX));
267 }
268 }
269
270 }
271 }
272 break;
273 }
274 case OMX_VC_INTRA_16x16:
275 {
276 OMX_U32 MBPosX = pCurrPointPos->x >> 4;
277 OMX_U32 MBPosY = pCurrPointPos->y >> 4;
278 OMX_U32 availability = 0;
279
280 /* Check for availability of LEFT MB */
281 if ((MBPosX != 0) && (pMBIntra [0] != 0 || pMBInter [0] != 0))
282 {
283 availability |= OMX_VC_LEFT;
284 }
285
286 /* Check for availability of UP MB */
287 if ((MBPosY != 0) && (pMBIntra [1] != 0 || pMBInter [1] != 0))
288 {
289 availability |= OMX_VC_UPPER;
290 }
291
292 /* Check for availability of UP-LEFT MB */
293 if ((MBPosX > 0) && (MBPosY > 0) &&
294 (pMBIntra [2] != 0 || pMBInter [2] != 0))
295 {
296 availability |= OMX_VC_UPPER_LEFT;
297 }
298
299 omxVCM4P10_PredictIntra_16x16(
300 pSrcRecBuf - 1,
301 pSrcRecBuf - SrcRecStep,
302 pSrcRecBuf - SrcRecStep - 1,
303 pTempDstBuf,
304 SrcRecStep,
305 TempDstStep,
306 pSrcMBInfo->Intra16x16PredMode,
307 availability);
308
309 break;
310 }
311
312 case OMX_VC_INTER_SKIP:
313 case OMX_VC_PREF0_8x8:
314 case OMX_VC_INTRA_PCM:
315 default:
316 /* These cases will update pDstBlockSAD with MAX value */
317 InvalidSAD = 1;
318 break;
319 }
320
321 /* INTER MB */
322 if ((pSrcMBInfo->mbType == OMX_VC_P_16x16) ||
323 (pSrcMBInfo->mbType == OMX_VC_P_8x16) ||
324 (pSrcMBInfo->mbType == OMX_VC_P_16x8) ||
325 (pSrcMBInfo->mbType == OMX_VC_P_8x8))
326 {
327 const OMX_U8 *pTempSrcBuf;
328 OMX_S32 TempSrcStep;
329 OMX_S32 mvx,mvy;
330 OMX_U32 PartX, PartY, SubPartX, SubPartY;
331
332 TempSrcStep = SrcRefStep;
333
334 MaxXPart = 16/Width;
335 MaxYPart = 16/Height;
336
337
338 for (PartY = 0; PartY < MaxYPart; PartY++)
339 {
340 for (PartX = 0; PartX < MaxXPart; PartX++)
341 {
342
343 pTempSrcBuf = pSrcRefBufList[pSrcMBInfo->pRefL0Idx[PartY * 2 + PartX]];
344
345 if (MaxXPart == 2 && MaxYPart == 2)
346 {
347 switch (pSrcMBInfo->subMBType[PartY*2+PartX])
348 {
349 case OMX_VC_SUB_P_8x8:
350 Width = 8;
351 Height = 8;
352 break;
353 case OMX_VC_SUB_P_8x4:
354 Width = 8;
355 Height = 4;
356 break;
357 case OMX_VC_SUB_P_4x8:
358 Width = 4;
359 Height = 8;
360 break;
361 case OMX_VC_SUB_P_4x4:
362 Width = 4;
363 Height = 4;
364 break;
365 default:
366 /* Default */
367 Width = 4;
368 Height = 4;
369 break;
370 }
371
372 MaxSubXPart = 8/Width;
373 MaxSubYPart = 8/Height;
374
375 for (SubPartY = 0; SubPartY < MaxSubYPart; SubPartY++)
376 {
377 for (SubPartX = 0; SubPartX < MaxSubXPart; SubPartX++)
378 {
379 mvx = pSrcMBInfo->pMV0 [2*PartY + SubPartY][2*PartX + SubPartX].dx;
380 mvy = pSrcMBInfo->pMV0 [2*PartY + SubPartY][2*PartX + SubPartX].dy;
381 armVCM4P10_Interpolate_Luma(
382 pTempSrcBuf + (8*PartX + 4*SubPartX + (mvx/4)) + (8*PartY + 4*SubPartY + (mvy/4)) * TempSrcStep,
383 TempSrcStep,
384 pTempDstBuf + (8*PartX + 4*SubPartX) + (8*PartY + 4*SubPartY) * TempDstStep,
385 TempDstStep,
386 Width,
387 Height,
388 mvx & 3,
389 mvy & 3
390 );
391 }
392 }
393 }
394 else
395 {
396
397 mvx = pSrcMBInfo->pMV0 [2*PartY][2*PartX].dx;
398 mvy = pSrcMBInfo->pMV0 [2*PartY][2*PartX].dy;
399 armVCM4P10_Interpolate_Luma(
400 pTempSrcBuf + (8*PartX + (mvx/4)) + (8*PartY + (mvy/4)) * TempSrcStep,
401 TempSrcStep,
402 pTempDstBuf + (8*PartX) + (8*PartY) * TempDstStep,
403 TempDstStep,
404 Width,
405 Height,
406 mvx & 3,
407 mvy & 3
408 );
409
410 }
411 }
412 }
413 }
414 }
415 else
416 {
417 InvalidSAD = 1;
418 }
419
420 /* Calculate SAD from predicted buffer */
421 if (!InvalidSAD)
422 {
423 OMX_U32 x8x8, y8x8, x4x4, y4x4, Block8x8, Block4x4;
424 OMX_S32 SAD;
425
426 pTempRefBuf = pTempDstBuf;
427 TempRefStep = 16;
428
429 /* SAD for each 4x4 block in scan order */
430 for (Block8x8 = 0; Block8x8 < 4; Block8x8++)
431 {
432 x8x8 = 8*(Block8x8 & 1);
433 y8x8 = 8*(Block8x8 >> 1);
434 for (Block4x4 = 0; Block4x4 < 4; Block4x4++)
435 {
436 x4x4 = 4*(Block4x4 & 1);
437 y4x4 = 4*(Block4x4 >> 1);
438
439 armVCCOMM_SAD(
440 pSrcCurrBuf + (x8x8 + x4x4) + (y8x8 + y4x4) * SrcCurrStep,
441 SrcCurrStep,
442 pTempRefBuf + (x8x8 + x4x4) + (y8x8 + y4x4) * TempRefStep,
443 TempRefStep,
444 &SAD,
445 4, /* Height */
446 4); /* Width */
447 *(pDstBlockSAD + 4 * Block8x8 + Block4x4) = (SAD < 0x7fff) ? (OMX_U16) SAD : ARM_VCM4P10_MAX_MODE_VALUE;
448 }
449 }
450 }
451 else
452 {
453 /* Fill SADs with max values and return*/
454 for (i = 0; i < 16; i++)
455 {
456 pDstBlockSAD [i] = ARM_VCM4P10_MAX_4x4_SAD;
457 }
458 }
459 return OMX_Sts_NoErr;
460 }
461
462
463
464 /**
465 * Function: armVCM4P10_Mode4x4Decision
466 *
467 * Description:
468 * Intra 4x4 Mode decision by calculating cost for all possible modes and
469 * choosing the best mode
470 *
471 * Remarks:
472 *
473 * Parameters:
474 * [in] pSrcCurrBuf - Pointer to the start of current Macroblock
475 * [in] SrcCurrStep - Step size of the pointer pSrcCurrBuf
476 * [in/out] pSrcDstMBCurr - Pointer to the OMXVCM4P10MBInfo which will be updated for
477 * field pIntra4x4PredMode of the current block.
478 * [in] Block8x8 - Index 8x8 block in which current 4x4 block belongs
479 * [in] Block4x4 - Index of current 4x4 block
480 * [in/out] pPredIntra4x4SrcY - Pointer to current block location in buffer
481 * with reconstructed values. This will be modified by this
482 * function with best mode predicted values
483 * [in] StepPredIntra4x4SrcY - Step size of the pointer pPredIntra4x4SrcY
484 * [in] pIntra4x4PredMode - Array of Intra 4x4 prediction mode for the MB.
485 * Current MB modes starts at [1,1].
486 * [in] pBestCost - Cost for the Best Intra 4x4 mode
487 * Return Value:
488 * None
489 *
490 */
armVCM4P10_Mode4x4Decision(const OMX_U8 * pSrcCurrBuf,OMX_S32 SrcCurrStep,OMXVCM4P10MBInfo * pSrcDstMBCurr,OMX_S32 Block8x8,OMX_S32 Block4x4,OMX_U8 * pPredIntra4x4SrcY,OMX_S32 StepPredIntra4x4SrcY,OMX_S32 pIntra4x4PredMode[][9],OMX_S32 * pBestCost)491 static OMXVoid armVCM4P10_Mode4x4Decision (
492 const OMX_U8* pSrcCurrBuf,
493 OMX_S32 SrcCurrStep,
494 OMXVCM4P10MBInfo *pSrcDstMBCurr,
495 OMX_S32 Block8x8,
496 OMX_S32 Block4x4,
497 OMX_U8 *pPredIntra4x4SrcY,
498 OMX_S32 StepPredIntra4x4SrcY,
499 OMX_S32 pIntra4x4PredMode [][9],
500 OMX_S32 *pBestCost
501 )
502 {
503 OMX_S32 i, j, x, y, BlockX, BlockY, mode;
504 OMX_S32 Cost, BestCost;
505 OMX_U8 *pSrcY;
506 OMX_S32 StepSrcY;
507 OMX_S32 availability = 0;
508 OMX_U8 pPredBlock [4*4];
509 OMXResult Ret = OMX_Sts_Err;
510
511 /* Get block cordinates from 8x8 block index and 4x4 block index */
512 BlockX = ((Block8x8 & 1) << 1) + (Block4x4 & 1);
513 BlockY = ((Block8x8 >> 1) << 1) + (Block4x4 >> 1);
514
515 /* Add offset to point to start of current MB in the array pIntra4x4PredMode */
516 x = BlockX + 1;
517 y = BlockY + 1;
518
519 /* Check for availability of LEFT Block */
520 if (pIntra4x4PredMode [y][x - 1] != ARM_VCM4P10_INVALID_BLOCK)
521 {
522 availability |= OMX_VC_LEFT;
523 }
524
525 /* Check for availability of UPPER Block */
526 if (pIntra4x4PredMode [y - 1][x] != ARM_VCM4P10_INVALID_BLOCK)
527 {
528 availability |= OMX_VC_UPPER;
529 }
530
531 /* Check for availability of UPPER LEFT Block */
532 if (pIntra4x4PredMode [y - 1][x - 1] != ARM_VCM4P10_INVALID_BLOCK)
533 {
534 availability |= OMX_VC_UPPER_LEFT;
535 }
536
537 pSrcY = pPredIntra4x4SrcY +
538 StepPredIntra4x4SrcY * (BlockY << 2) +
539 (BlockX << 2);
540
541 StepSrcY = StepPredIntra4x4SrcY;
542
543 x = BlockX * 4;
544 y = BlockY * 4;
545
546 Cost = BestCost = ARM_VCM4P10_MAX_COST;
547
548 /* Go through each mode for minim cost */
549 for (mode = 0; mode < 9; mode++)
550 {
551 Ret = omxVCM4P10_PredictIntra_4x4(
552 pSrcY - 1,
553 pSrcY - StepSrcY,
554 pSrcY - StepSrcY - 1,
555 pPredBlock,
556 StepSrcY,
557 4,
558 (OMXVCM4P10Intra4x4PredMode) mode,
559 availability);
560
561 if (Ret == OMX_Sts_NoErr)
562 {
563 armVCCOMM_SAD(
564 pSrcCurrBuf + (y * SrcCurrStep) + x,
565 SrcCurrStep,
566 pPredBlock,
567 4,
568 &Cost,
569 4,
570 4);
571
572 if (Cost < BestCost)
573 {
574 BestCost = Cost;
575
576 pIntra4x4PredMode [BlockY + 1][BlockX + 1] =
577 (OMXVCM4P10Intra4x4PredMode) mode;
578 pSrcDstMBCurr->pIntra4x4PredMode [BlockY * 4 + BlockX] =
579 (OMXVCM4P10Intra4x4PredMode) mode;
580
581 for (j = 0; j < 4; j++)
582 {
583 for (i = 0; i < 4; i++)
584 {
585 pSrcY [StepSrcY * j + i] = pPredBlock [4 * j + i];
586 }
587 }
588 }
589 }
590 }
591
592 *pBestCost = BestCost;
593 return;
594 }
595
596 /**
597 * Function: armVCM4P10_SetMotionVectorPredictor
598 *
599 * Description:
600 * This function will do the MV Prediction for Inter MBs
601 *
602 * Parameters:
603 * [in] BlockStartX - Start X index in integer pels in current Block
604 * [in] BlockStartY - Start Y index in integer pels in current Block
605 * [in] BlockSizeX - Width of current block
606 * [in] BlockSizeY - Height of current block
607 * [in] RefFrame - Index of the reference frame for prediction
608 * [in] pRefFrArr - Pointer to Ref array storing neighbouring MVs for MV prediction
609 * [in] pMVArr - Pointer to MV array storing neighbouring MVs for MV prediction
610 * [out] pMVPred - Pointer to predicted MVs
611 * Remarks:
612 *
613 * Return Value:
614 * None
615 *
616 */
armVCM4P10_SetMotionVectorPredictor(OMX_U32 BlockStartX,OMX_U32 BlockStartY,OMX_U32 BlockSizex,OMX_U32 BlockSizey,OMX_S32 RefFrame,OMX_S32 pRefFrArr[][6],OMXVCMotionVector pMVArr[][12],OMXVCMotionVector * pMVPred)617 static OMXVoid armVCM4P10_SetMotionVectorPredictor(
618 OMX_U32 BlockStartX,
619 OMX_U32 BlockStartY,
620 OMX_U32 BlockSizex,
621 OMX_U32 BlockSizey,
622 OMX_S32 RefFrame,
623 OMX_S32 pRefFrArr[][6],
624 OMXVCMotionVector pMVArr[][12],
625 OMXVCMotionVector *pMVPred
626 )
627 {
628 OMX_S32 RFrameL; /* Left */
629 OMX_S32 RFrameU; /* Up */
630 OMX_S32 RFrameUR; /* Up-Right */
631
632 OMX_S32 BlockX, BlockY, BlockXFr, BlockYFr, MVPredType;
633 OMX_S32 BlockXPlusOff, BlockXPlusOffFr, BlockXMin1Fr, BlockYMin1Fr;
634
635 BlockX = 4 + (BlockStartX >> 2);
636 BlockY = 4 + (BlockStartY >> 2);
637 BlockXPlusOff = BlockX + (BlockSizex >> 2);
638
639 BlockXFr = BlockX >> 1;
640 BlockYFr = BlockY >> 1;
641 BlockXMin1Fr = (BlockX - 1) >> 1;
642 BlockYMin1Fr = (BlockY - 1) >> 1;
643 BlockXPlusOffFr = BlockXPlusOff >> 1;
644
645 MVPredType = ARM_VCM4P10_MVPRED_MEDIAN;
646
647 RFrameL = pRefFrArr [BlockYFr][BlockXMin1Fr];
648 RFrameU = pRefFrArr [BlockYMin1Fr][BlockXFr];
649 RFrameUR = pRefFrArr [BlockYMin1Fr][BlockXPlusOffFr];
650
651 if (RFrameUR == ARM_VCM4P10_INVALID_BLOCK)
652 {
653 RFrameUR = pRefFrArr [BlockYMin1Fr][BlockXMin1Fr];
654 }
655
656 /*
657 * Prediction if only one of the neighbors uses the reference frame
658 * we are checking
659 */
660
661 if (RFrameL == RefFrame && RFrameU != RefFrame && RFrameUR != RefFrame)
662 {
663 MVPredType = ARM_VCM4P10_MVPRED_L;
664 }
665 else if(RFrameL != RefFrame && RFrameU == RefFrame && RFrameUR != RefFrame)
666 {
667 MVPredType = ARM_VCM4P10_MVPRED_U;
668 }
669 else if(RFrameL != RefFrame && RFrameU != RefFrame && RFrameUR == RefFrame)
670 {
671 MVPredType = ARM_VCM4P10_MVPRED_UR;
672 }
673
674 /* Directional predictions */
675 else if(BlockSizex == 8 && BlockSizey == 16)
676 {
677 if(BlockStartX == 0)
678 {
679 if(RFrameL == RefFrame)
680 {
681 MVPredType = ARM_VCM4P10_MVPRED_L;
682 }
683 }
684 else
685 {
686 if (RFrameUR == RefFrame)
687 {
688 MVPredType = ARM_VCM4P10_MVPRED_UR;
689 }
690 }
691 }
692 else if(BlockSizex == 16 && BlockSizey == 8)
693 {
694 if(BlockStartY == 0)
695 {
696 if(RFrameU == RefFrame)
697 {
698 MVPredType = ARM_VCM4P10_MVPRED_U;
699 }
700 }
701 else
702 {
703 if(RFrameL == RefFrame)
704 {
705 MVPredType = ARM_VCM4P10_MVPRED_L;
706 }
707 }
708 }
709
710 switch (MVPredType)
711 {
712 case ARM_VCM4P10_MVPRED_MEDIAN:
713 if (!(pRefFrArr [BlockYMin1Fr][BlockXMin1Fr] == ARM_VCM4P10_INVALID_BLOCK ||
714 pRefFrArr [BlockYMin1Fr][BlockXFr] == ARM_VCM4P10_INVALID_BLOCK ||
715 pRefFrArr [BlockYMin1Fr][BlockXPlusOffFr] == ARM_VCM4P10_INVALID_BLOCK))
716 {
717 pMVPred->dx = pMVArr [BlockY][BlockX - 1].dx;
718 pMVPred->dy = pMVArr [BlockY][BlockX - 1].dy;
719 }
720 else
721 {
722 pMVPred->dx =
723 ARM_VCM4P10_MEDIAN(pMVArr [BlockY][BlockX - 1].dx,
724 pMVArr [BlockY - 1][BlockX].dx,
725 pMVArr [BlockY - 1][BlockXPlusOff].dx);
726 pMVPred->dy =
727 ARM_VCM4P10_MEDIAN(pMVArr [BlockY][BlockX - 1].dy,
728 pMVArr [BlockY - 1][BlockX].dy,
729 pMVArr [BlockY - 1][BlockXPlusOff].dy);
730 }
731 break;
732
733 case ARM_VCM4P10_MVPRED_L:
734 pMVPred->dx = pMVArr [BlockY][BlockX - 1].dx;
735 pMVPred->dy = pMVArr [BlockY][BlockX - 1].dy;
736 break;
737 case ARM_VCM4P10_MVPRED_U:
738 pMVPred->dx = pMVArr [BlockY - 1][BlockX].dx;
739 pMVPred->dy = pMVArr [BlockY - 1][BlockX].dy;
740 break;
741 case ARM_VCM4P10_MVPRED_UR:
742 if (pRefFrArr [BlockYMin1Fr][BlockXPlusOffFr] != ARM_VCM4P10_INVALID_BLOCK)
743 {
744 pMVPred->dx = pMVArr [BlockY - 1][BlockXPlusOff].dx;
745 pMVPred->dy = pMVArr [BlockY - 1][BlockXPlusOff].dy;
746 }
747 else
748 {
749 pMVPred->dx = pMVArr [BlockY - 1][BlockX - 1].dx;
750 pMVPred->dy = pMVArr [BlockY - 1][BlockX - 1].dy;
751 }
752 break;
753 default:
754 break;
755 }
756
757 return;
758 }
759
760 /**
761 * Function: armVCM4P10_BlockMotionSearch
762 *
763 * Description:
764 * Gets best MV for the current block
765 *
766 * Parameters:
767 * [in] pSrcCurrBuf - Pointer to the start of luma component of current Macroblock
768 * [in] SrcCurrStep - Step size for the pointer pSrcCurrBuf
769 * [in] pSrcRefY - Pointer to the start of luma component of co-located reference MB
770 * [in] nSrcRefStep - Step size for the pointer pSrcRefY
771 * [in] pRefRect Pointer to the valid reference rectangle; relative to the image origin.
772 * [in] pCurrPointPos Position of the current macroblock in the current plane.
773 * [in] pMESpec - Motion estimation structure
774 * [in] pMBInter - Array, of dimension four, containing pointers to information associated with four
775 * adjacent type INTER MBs (Left, Top, Top-Left, Top-Right).
776 * [in] nLamda - For calculating the cost
777 * [out] pBestCost - Minimum cost for encoding current block
778 * [out] pBestMV - MV corresponding to best cost
779 * [in] BlockStartX - Block start X index in integer pels
780 * [in] BlockStartY - Block start Y index in integer pels
781 * [in] BlockSizeX - Width of current block
782 * [in] BlockSizeY - Height of current block
783 * [in] RefFrame - Index of the reference frame for prediction
784 * [in] pRefFrArr - Pointer to reference frame array storing neighbouring MVs for prediction
785 * [in] pMVArr - Pointer to MV array storing neighbouring MVs for MV prediction
786 * [in] pMVPred - Pointer to MV predicted from neighbour MVs
787 * Remarks:
788 *
789 * Return Value:
790 * OMXResult
791 *
792 */
armVCM4P10_BlockMotionSearch(const OMX_U8 * pSrcCurrBuf,OMX_S32 SrcCurrStep,const OMX_U8 * pSrcRefY,OMX_S32 nSrcRefStep,const OMXRect * pRefRect,const OMXVCM4P2Coordinate * pCurrPointPos,void * pMESpec,OMX_S32 nLamda,OMX_S32 * pBestCost,OMXVCMotionVector * pBestMV,OMX_U32 BlockStartX,OMX_U32 BlockStartY,OMX_U32 BlockSizeX,OMX_U32 BlockSizeY,OMX_S32 RefFrame,OMX_S32 pRefFrArr[][6],OMXVCMotionVector pMVArr[][12],OMXVCMotionVector * pMVPred)793 static OMXResult armVCM4P10_BlockMotionSearch(
794 const OMX_U8* pSrcCurrBuf,
795 OMX_S32 SrcCurrStep,
796 const OMX_U8* pSrcRefY,
797 OMX_S32 nSrcRefStep,
798 const OMXRect *pRefRect,
799 const OMXVCM4P2Coordinate *pCurrPointPos,
800 void* pMESpec,
801
802 OMX_S32 nLamda,
803 OMX_S32* pBestCost,
804 OMXVCMotionVector *pBestMV,
805
806 OMX_U32 BlockStartX,
807 OMX_U32 BlockStartY,
808 OMX_U32 BlockSizeX,
809 OMX_U32 BlockSizeY,
810 OMX_S32 RefFrame,
811 OMX_S32 pRefFrArr [][6],
812 OMXVCMotionVector pMVArr [][12],
813 OMXVCMotionVector *pMVPred
814 )
815 {
816
817 OMXVCMotionVector MVCalculated, MVCandidate;
818 OMX_S32 Cost;
819 OMXResult RetValue;
820 OMXVCM4P10MEParams *pMEParams;
821 OMXVCM4P2Coordinate CurrBlockPos;
822
823 /* Get Predicted Motion Vectors */
824 armVCM4P10_SetMotionVectorPredictor (
825 BlockStartX,
826 BlockStartY,
827 BlockSizeX,
828 BlockSizeY,
829 RefFrame,
830 pRefFrArr,
831 pMVArr,
832 pMVPred);
833
834 /* Initialize candidate MV */
835 MVCandidate.dx = 0;
836 MVCandidate.dy = 0;
837
838 CurrBlockPos.x = pCurrPointPos->x + BlockStartX;
839 CurrBlockPos.y = pCurrPointPos->y + BlockStartY;
840
841 /* Block Match Integer */
842 RetValue = omxVCM4P10_BlockMatch_Integer (
843 pSrcCurrBuf,
844 SrcCurrStep,
845 pSrcRefY,
846 nSrcRefStep,
847 pRefRect,
848 &CurrBlockPos,
849 BlockSizeX,
850 BlockSizeY,
851 nLamda,
852 pMVPred,
853 &MVCandidate,
854 &MVCalculated,
855 &Cost,
856 pMESpec);
857
858 /* updated BestMV*/
859 /**pBestCost = Cost;
860 pBestMV->dx = MVCalculated.dx;
861 pBestMV->dy = MVCalculated.dy;*/
862
863 pMEParams = (OMXVCM4P10MEParams *) pMESpec;
864
865 /* Block Match Half pel */
866 if (pMEParams->halfSearchEnable)
867 {
868 RetValue = omxVCM4P10_BlockMatch_Half(
869 pSrcCurrBuf,
870 SrcCurrStep,
871 pSrcRefY,
872 nSrcRefStep,
873 BlockSizeX,
874 BlockSizeY,
875 nLamda,
876 pMVPred,
877 &MVCalculated, /* input/output*/
878 &Cost);
879 }
880
881 /* Block Match Quarter pel */
882 if (pMEParams->quarterSearchEnable)
883 {
884 RetValue = omxVCM4P10_BlockMatch_Quarter(
885 pSrcCurrBuf,
886 SrcCurrStep,
887 pSrcRefY,
888 nSrcRefStep,
889 BlockSizeX,
890 BlockSizeY,
891 nLamda,
892 pMVPred,
893 &MVCalculated,
894 &Cost);
895 }
896
897 /* updated Best Cost and Best MV */
898 *pBestCost = Cost;
899 pBestMV->dx = MVCalculated.dx;
900 pBestMV->dy = MVCalculated.dy;
901
902 /*
903 * Skip MB cost calculations of 16x16 inter mode
904 */
905 return RetValue;
906 }
907
908 /**
909 * Function: armVCM4P10_PartitionME
910 *
911 * Description:
912 * Gets best cost for the current partition
913 *
914 * Parameters:
915 * [in] pSrcCurrBuf - Pointer to the start of luma component of current Macroblock
916 * [in] SrcCurrStep - Step size for the pointer pSrcCurrBuf
917 * [in] pSrcRefBufList - Pointer to List of ref buffer of co-located reference MB
918 * [in] nSrcRefStep - Step size for the pointer pSrcRefY
919 * [in] pRefRect Pointer to the valid reference rectangle; relative to the image origin.
920 * [in] pCurrPointPos Position of the current macroblock in the current plane.
921 * [in] pMESpec - Motion estimation structure
922 * [in] PartWidth - Width of current partition
923 * [in] PartHeight - Height of current partition
924 * [in] BlockWidth - Width of current block
925 * [in] BlockHeight - Height of current block
926 * [in] PartStartX - Partition start X index in integer pels
927 * [in] PartStartY - Partition start Y index in integer pels
928 * [in] pMVArr - Pointer to MV array storing neighbouring MVs for MV prediction
929 * [in] pRefFrArr - Pointer to reference frame array storing neighbouring MVs for prediction
930 * [in] Lambda - For calculating the cost
931 * [out] pCost - Pointer to cost for Inter MB
932 *
933 * Return Value:
934 * OMXResult
935 *
936 */
armVCM4P10_PartitionME(const OMX_U8 * pSrcCurrBuf,OMX_S32 SrcCurrStep,const OMX_U8 * pSrcRefBufList[ARM_VCM4P10_MAX_FRAMES],OMX_S32 SrcRefStep,const OMXRect * pRefRect,const OMXVCM4P2Coordinate * pCurrPointPos,void * pMESpec,OMX_S32 PartWidth,OMX_S32 PartHeight,OMX_S32 BlockWidth,OMX_S32 BlockHeight,OMX_S32 PartStartX,OMX_S32 PartStartY,OMXVCMotionVector pMVArr[][12],OMX_S32 pRefFrArr[][6],OMXVCMotionVector pMVPredArr[][4],OMX_S32 Lambda,OMX_S32 * pCost)937 static OMXResult armVCM4P10_PartitionME (
938 const OMX_U8* pSrcCurrBuf,
939 OMX_S32 SrcCurrStep,
940 const OMX_U8 *pSrcRefBufList[ARM_VCM4P10_MAX_FRAMES],
941 OMX_S32 SrcRefStep,
942 const OMXRect *pRefRect,
943 const OMXVCM4P2Coordinate *pCurrPointPos,
944 void* pMESpec,
945
946 OMX_S32 PartWidth,
947 OMX_S32 PartHeight,
948 OMX_S32 BlockWidth,
949 OMX_S32 BlockHeight,
950 OMX_S32 PartStartX,
951 OMX_S32 PartStartY,
952
953 OMXVCMotionVector pMVArr [][12],
954 OMX_S32 pRefFrArr [][6],
955 OMXVCMotionVector pMVPredArr [][4],
956
957 OMX_S32 Lambda,
958 OMX_S32 *pCost
959 )
960 {
961 OMX_U32 x, y, i, j, ref, OffX, OffY, OffSrc, OffRef;
962 OMX_S32 BlockCost, PartitionCost, BestCost;
963 OMX_S32 BestRefFrame=0;
964 OMXVCMotionVector BestMV [4][4];
965 OMXVCMotionVector BestMVPred [4][4];
966 OMXVCMotionVector MVPred;
967 OMXVCMotionVector DstMV;
968
969 BestCost = ARM_VCM4P10_MAX_COST;
970
971 for (ref = 0; ref < ARM_VCM4P10_MAX_FRAMES; ref++)
972 {
973 if (pSrcRefBufList [ref] == NULL)
974 {
975 /* No reference frame, continue */
976 continue;
977 }
978
979 PartitionCost = 0;
980
981 for (y = 0; y < PartHeight; y += BlockHeight)
982 {
983 for (x = 0; x < PartWidth; x += BlockWidth)
984 {
985 OffSrc = SrcCurrStep * (PartStartY + y) + PartStartX + x;
986 OffRef = SrcRefStep * (PartStartY + y) + PartStartX + x;
987 armVCM4P10_BlockMotionSearch (
988 pSrcCurrBuf + OffSrc,
989 SrcCurrStep,
990 pSrcRefBufList [ref] + OffRef,
991 SrcRefStep,
992 pRefRect,
993 pCurrPointPos,
994 pMESpec,
995
996 Lambda,
997 &BlockCost,
998 &DstMV,
999
1000 x + PartStartX,
1001 y + PartStartY,
1002 BlockWidth,
1003 BlockHeight,
1004 ref,
1005 pRefFrArr,
1006 pMVArr,
1007 &MVPred);
1008
1009 PartitionCost += BlockCost;
1010
1011 OffX = (PartStartX + x) >> 2;
1012 OffY = (PartStartY + y) >> 2;
1013
1014 for (j = 0; j < (BlockHeight >> 2); j++)
1015 {
1016 for (i = 0; i < (BlockWidth >> 2); i++)
1017 {
1018 pMVArr [4 + OffY + j][4 + OffX + i].dx = DstMV.dx;
1019 pMVArr [4 + OffY + j][4 + OffX + i].dy = DstMV.dy;
1020 pMVPredArr [OffY + j][OffX + i].dx = MVPred.dx;
1021 pMVPredArr [OffY + j][OffX + i].dy = MVPred.dy;
1022 }
1023 }
1024
1025 pRefFrArr [2 + (OffY >> 1)][2 + (OffX >> 1)] = ref;
1026 for (j = 0; j < (BlockHeight >> 3); j++)
1027 {
1028 for (i = 0; i < (BlockWidth >> 3); i++)
1029 {
1030 pRefFrArr [2 + (OffY >> 1) + j][2 + (OffX >> 1) + i] = ref;
1031 }
1032 }
1033
1034 }
1035 }
1036
1037 /*
1038 * If PartitionCost is less for this reference frame, motion vectors needs to be backedup
1039 */
1040 if (PartitionCost <= BestCost)
1041 {
1042 BestCost = PartitionCost;
1043 BestRefFrame = ref;
1044
1045 for (y = 0; y < (PartHeight/BlockHeight); y++)
1046 {
1047 for (x = 0; x < (PartWidth/BlockWidth); x++)
1048 {
1049 OffX = (PartStartX + x * BlockWidth) >> 2;
1050 OffY = (PartStartY + y * BlockHeight) >> 2;
1051
1052 BestMV[y][x].dx = pMVArr [4 + OffY][4 + OffX].dx;
1053 BestMV[y][x].dy = pMVArr [4 + OffY][4 + OffX].dy;
1054 BestMVPred[y][x].dx = pMVPredArr [OffY][OffX].dx;
1055 BestMVPred[y][x].dy = pMVPredArr [OffY][OffX].dy;
1056 }
1057 }
1058 }
1059
1060 }
1061
1062 /*
1063 * Copy back best reference frame, motion vectors and cost.
1064 */
1065 for (y = 0; y < (PartHeight/BlockHeight); y++)
1066 {
1067 for (x = 0; x < (PartWidth/BlockWidth); x++)
1068 {
1069 OffX = (PartStartX + x * BlockWidth) >> 2;
1070 OffY = (PartStartY + y * BlockHeight) >> 2;
1071
1072 for (j = 0; j < (BlockHeight >> 2); j++)
1073 {
1074 for (i = 0; i < (BlockWidth >> 2); i++)
1075 {
1076 pMVArr [4 + OffY + j][4 + OffX + i].dx = BestMV[y][x].dx;
1077 pMVArr [4 + OffY + j][4 + OffX + i].dy = BestMV[y][x].dy;
1078 pMVPredArr [OffY + j][OffX + i].dx = BestMVPred[y][x].dx;
1079 pMVPredArr [OffY + j][OffX + i].dy = BestMVPred[y][x].dy;
1080 }
1081 }
1082
1083 for (j = 0; j < (BlockHeight >> 3); j++)
1084 {
1085 for (i = 0; i < (BlockWidth >> 3); i++)
1086 {
1087 pRefFrArr [2 + (OffY >> 1) + j][2 + (OffX >> 1) + i] = BestRefFrame;
1088 }
1089 }
1090 }
1091 }
1092
1093 *pCost = BestCost;
1094 return OMX_Sts_NoErr;
1095
1096 }
1097
1098 /**
1099 * Function: armVCM4P10_Intra16x16Estimation
1100 *
1101 * Description:
1102 * Performs MB-level motion estimation for INTER MB type and selects best motion estimation strategy from
1103 * the set of modes supported in baseline profile ISO/IEC 14496-10.
1104 *
1105 * Remarks:
1106 *
1107 * Parameters:
1108 * [in] pSrcCurrBuf - Pointer to the start of luma component of current Macroblock
1109 * [in] SrcCurrStep - Step size for the pointer pSrcCurrBuf
1110 * [in] pSrcRecBuf - Pointer to the start of luma component of co-located reconstructed MB
1111 * [in] SrcRecStep - Step size for the pointer pSrcRecBuf
1112 * [in] nMBPosX - Position of MB in the frame w.r.t X axis
1113 * [in] nMBPosY - Position of MB in the frame w.r.t Y axis
1114 * [in] pMBInter - Array, of dimension four, containing pointers to information associated with four
1115 * adjacent type INTER MBs (Left, Top, Top-Left, Top-Right).
1116 * [in] pMBIntra - Array, of dimension four, containing pointers to information associated with four
1117 * adjacent type INTRA MBs (Left, Top, Top-Left, Top-Right).
1118 * [in/out] pSrcDstMBCurr - Pointer to information structure for the current MB. Following member should be set
1119 * before calling this function
1120 * [in] Lambda - For calculating the cost
1121 * [out] pCost - Pointer to cost for Intra16x16
1122 * Return Value:
1123 * OMX_Sts_NoErr - No Error
1124 * OMX_Sts_BadArgErr - Bad arguments:
1125 *
1126 */
1127
armVCM4P10_Intra16x16Estimation(const OMX_U8 * pSrcCurrBuf,OMX_S32 SrcCurrStep,const OMX_U8 * pSrcRecBuf,OMX_S32 SrcRecStep,const OMXVCM4P2Coordinate * pCurrPointPos,const OMXVCM4P10MBInfoPtr * pMBInter,const OMXVCM4P10MBInfoPtr * pMBIntra,OMXVCM4P10MBInfo * pSrcDstMBCurr,OMX_U32 * pCost)1128 static OMXResult armVCM4P10_Intra16x16Estimation(
1129 const OMX_U8* pSrcCurrBuf,
1130 OMX_S32 SrcCurrStep,
1131 const OMX_U8* pSrcRecBuf,
1132 OMX_S32 SrcRecStep,
1133 const OMXVCM4P2Coordinate *pCurrPointPos,
1134 const OMXVCM4P10MBInfoPtr *pMBInter,
1135 const OMXVCM4P10MBInfoPtr *pMBIntra,
1136 OMXVCM4P10MBInfo *pSrcDstMBCurr,
1137 OMX_U32 *pCost)
1138 {
1139 OMX_U8 PredBuf [16*16 + 16];
1140 OMX_U8 *pPred;
1141 OMX_S32 mode;
1142 OMX_S32 Cost;
1143 OMX_S32 availability = 0;
1144 OMXResult Ret;
1145 OMXVCM4P10Intra16x16PredMode IntraMode16x16 [4] =
1146 {OMX_VC_16X16_VERT, OMX_VC_16X16_HOR,
1147 OMX_VC_16X16_DC, OMX_VC_16X16_PLANE};
1148 OMX_U32 MBPosX = pCurrPointPos->x >> 4;
1149 OMX_U32 MBPosY = pCurrPointPos->y >> 4;
1150
1151 pPred = armAlignTo16Bytes(PredBuf);
1152
1153 /* Check for availability of LEFT MB */
1154 if ((MBPosX != 0) && (pMBIntra [0] != 0 || pMBInter [0] != 0))
1155 {
1156 availability |= OMX_VC_LEFT;
1157 }
1158
1159 /* Check for availability of UP MB */
1160 if ((MBPosY != 0) && (pMBIntra [1] != 0 || pMBInter [1] != 0))
1161 {
1162 availability |= OMX_VC_UPPER;
1163 }
1164
1165 /* Check for availability of UP-LEFT MB */
1166 if ((MBPosX > 0) && (MBPosY > 0) &&
1167 (pMBIntra [2] != 0 || pMBInter [2] != 0))
1168 {
1169 availability |= OMX_VC_UPPER_LEFT;
1170 }
1171
1172 *pCost = ARM_VCM4P10_MAX_COST;
1173 for (mode = 0; mode < 4; mode++)
1174 {
1175 Ret = omxVCM4P10_PredictIntra_16x16(
1176 pSrcRecBuf - 1,
1177 pSrcRecBuf - SrcRecStep,
1178 pSrcRecBuf - SrcRecStep - 1,
1179 pPred,
1180 SrcRecStep,
1181 16,
1182 IntraMode16x16 [mode],
1183 availability);
1184 if (Ret == OMX_Sts_NoErr)
1185 {
1186 armVCCOMM_SAD(
1187 pSrcCurrBuf,
1188 SrcCurrStep,
1189 pPred,
1190 16,
1191 &Cost,
1192 16,
1193 16);
1194 if (Cost < *pCost)
1195 {
1196 *pCost = Cost;
1197 pSrcDstMBCurr->Intra16x16PredMode = IntraMode16x16 [mode];
1198 }
1199
1200 }
1201
1202 }
1203
1204 return OMX_Sts_NoErr;
1205 }
1206
1207 /**
1208 * Function: armVCM4P10_Intra4x4Estimation
1209 *
1210 * Description:
1211 * Performs MB-level motion estimation for Intra 4x4 MB type and selects
1212 * the best set of modes supported in baseline profile.
1213 *
1214 * Parameters:
1215 * [in] pSrcCurrBuf - Pointer to the start of luma component of current Macroblock
1216 * [in] SrcCurrStep - Step size for the pointer pSrcCurrBuf
1217 * [in] pSrcRecBuf - Pointer to the start of luma component of co-located reconstructed MB
1218 * [in] SrcRecStep - Step size for the pointer pSrcRecBuf
1219 * [in] nMBPosX - Position of MB in the frame w.r.t X axis
1220 * [in] nMBPosY - Position of MB in the frame w.r.t Y axis
1221 * [in] pMBIntra - Array, of dimension four, containing pointers to information associated with four
1222 * adjacent type INTRA MBs (Left, Top, Top-Left, Top-Right).
1223 * [in/out] pSrcDstMBCurr - Pointer to information structure for the current MB. Following member should be set
1224 * before calling this function
1225 * [in] Lambda - For calculating the cost
1226 * [out] pCost - Pointer to cost for Intra4x4
1227 * Return Value:
1228 * OMX_Sts_NoErr - No Error
1229 * OMX_Sts_BadArgErr - Bad arguments:
1230 *
1231 */
1232
armVCM4P10_Intra4x4Estimation(const OMX_U8 * pSrcCurrBuf,OMX_S32 SrcCurrStep,const OMX_U8 * pSrcRecBuf,OMX_S32 SrcRecStep,const OMXVCM4P10MBInfoPtr * pMBIntra,OMXVCM4P10MBInfo * pSrcDstMBCurr,OMX_U32 * pCost)1233 static OMXResult armVCM4P10_Intra4x4Estimation(
1234 const OMX_U8* pSrcCurrBuf,
1235 OMX_S32 SrcCurrStep,
1236 const OMX_U8* pSrcRecBuf,
1237 OMX_S32 SrcRecStep,
1238 const OMXVCM4P10MBInfoPtr *pMBIntra,
1239 OMXVCM4P10MBInfo *pSrcDstMBCurr,
1240 OMX_U32 *pCost)
1241 {
1242 OMX_S32 x, y, Block4x4, Block8x8;
1243 OMX_S32 Cost;
1244
1245 /*
1246 * PredIntra4x4Mode will store prediction modes of 4x4 blocks.
1247 * Modes for current MB starts at index [1][1].
1248 * Modes of nighbouring MB's will be as shown below
1249 * A value of ARM_VCM4P10_INVALID_BLOCK for any block in this array means
1250 * that block is not available for prediction.
1251 *
1252 * c3 b0 b1 b2 b3 d0 d1 d2 d3
1253 * a0 xx xx xx xx - - - -
1254 * a1 xx xx xx xx - - - -
1255 * a2 xx xx xx xx - - - -
1256 * a3 xx xx xx xx - - - -
1257 *
1258 */
1259 OMX_S32 PredIntra4x4Mode [5][9];
1260
1261 /*
1262 * pSrcY stores re-construsted source array of size 3MB X 2MB as below
1263 *
1264 * MB11 MB12 MB13
1265 * MB21 MB22 MB23
1266 *
1267 * This array will be used for local reconstruction of 4x4 blocks
1268 * with best prediction mode within an MB
1269 */
1270 OMX_U8 pSrcY [(16*3)*(16*2)];
1271 OMX_S32 StepSrcY;
1272
1273 /* init */
1274 *pCost = 0;
1275
1276 for (y = 0; y < 5; y++)
1277 {
1278 for (x = 0; x < 9; x++)
1279 {
1280 /*
1281 * Initialize with value of ARM_VCM4P10_INVALID_BLOCK, to mean this
1282 * 4x4 block is not available
1283 */
1284 PredIntra4x4Mode [y][x] = ARM_VCM4P10_INVALID_BLOCK;
1285 }
1286 }
1287
1288 /* Replace ARM_VCM4P10_INVALID_BLOCK value with available MBs values*/
1289 for (x = 0; x < 4; x++)
1290 {
1291 /* Store values of b0, b1, b2, b3 */
1292 if (pMBIntra[1] != NULL)
1293 {
1294 PredIntra4x4Mode [0][x + 1] =
1295 pMBIntra[1]->pIntra4x4PredMode[3*4 + x];
1296 }
1297
1298 /* Store values of d0, d1, d2, d3 */
1299 if (pMBIntra[3] != NULL)
1300 {
1301 PredIntra4x4Mode [0][x + 5] =
1302 pMBIntra[3]->pIntra4x4PredMode[3*4 + x];
1303 }
1304 }
1305
1306 /* Store values of c3 */
1307 if (pMBIntra[2] != NULL)
1308 {
1309 PredIntra4x4Mode [0][0] = pMBIntra[2]->pIntra4x4PredMode[15];
1310 }
1311
1312 for (y = 0; y < 4; y++)
1313 {
1314 /* Store values of a0, a1, a2, a3 */
1315 if (pMBIntra[0] != NULL)
1316 {
1317 PredIntra4x4Mode [y + 1][0] =
1318 pMBIntra[0]->pIntra4x4PredMode[y*4 + 3];
1319 }
1320 }
1321
1322 /*
1323 * Update neighbouring Pred mode array which will be used for
1324 * prediction of Intra4x4 modes.
1325 */
1326
1327 StepSrcY = 16 * 3;
1328 for (y = 0; y < (16 * 2); y++)
1329 {
1330 for (x = 0; x < (16 * 3); x++)
1331 {
1332 pSrcY [StepSrcY * y + x] =
1333 pSrcRecBuf [SrcRecStep * (y - 16) + x - 16];
1334 }
1335 }
1336
1337 /* for each 8x8 block */
1338 for (Block8x8 = 0; Block8x8 < 4; Block8x8++)
1339 {
1340 /* for each 4x4 block inside 8x8 block */
1341 for (Block4x4 = 0; Block4x4 < 4; Block4x4++)
1342 {
1343 armVCM4P10_Mode4x4Decision (
1344 pSrcCurrBuf,
1345 SrcCurrStep,
1346 pSrcDstMBCurr,
1347 Block8x8,
1348 Block4x4,
1349 pSrcY + 16 * StepSrcY + 16,
1350 StepSrcY,
1351 PredIntra4x4Mode,
1352 &Cost);
1353
1354 *pCost += Cost;
1355 }
1356 }
1357 return OMX_Sts_NoErr;
1358 }
1359
1360 /**
1361 * Function: armVCM4P10_InterMEMB
1362 *
1363 * Description:
1364 * Performs MB-level motion estimation for INTER MB type and selects best motion estimation strategy from
1365 * the set of modes supported in baseline profile ISO/IEC 14496-10.
1366 *
1367 * Remarks:
1368 *
1369 * Parameters:
1370 * [in] pSrcCurrBuf - Pointer to the start of luma component of current Macroblock
1371 * [in] SrcCurrStep - Step size for the pointer pSrcCurrBuf
1372 * [in] pSrcRefBufList - Pointer to the start of luma component of co-located reference MB
1373 * [in] SrcRefStep - Step size for the pointer pSrcRefY
1374 * [in] pRefRect Pointer to the valid reference rectangle; relative to the image origin.
1375 * [in] pCurrPointPos Position of the current macroblock in the current plane.
1376 * [in] pMESpec - Motion estimation structure
1377 * [in] pMBInter - Array, of dimension four, containing pointers to information associated with four
1378 * adjacent type INTER MBs (Left, Top, Top-Left, Top-Right).
1379 * [in/out] pSrcDstMBCurr - Pointer to information structure for the current MB. Following member should be set
1380 * before calling this function
1381 * [in] Lambda - For calculating the cost
1382 * [out] pDstCost - Pointer to cost for Inter MB
1383 * Return Value:
1384 * OMX_Sts_NoErr - No Error
1385 * OMX_Sts_BadArgErr - Bad arguments:
1386 *
1387 */
1388
armVCM4P10_InterMEMB(const OMX_U8 * pSrcCurrBuf,OMX_S32 SrcCurrStep,const OMX_U8 * pSrcRefBufList[ARM_VCM4P10_MAX_FRAMES],OMX_S32 SrcRefStep,const OMXRect * pRefRect,const OMXVCM4P2Coordinate * pCurrPointPos,OMX_U32 Lambda,void * pMESpec,const OMXVCM4P10MBInfoPtr * pMBInter,OMXVCM4P10MBInfoPtr pSrcDstMBCurr,OMX_U32 * pDstCost)1389 static OMXResult armVCM4P10_InterMEMB(
1390 const OMX_U8 *pSrcCurrBuf,
1391 OMX_S32 SrcCurrStep,
1392 const OMX_U8 *pSrcRefBufList[ARM_VCM4P10_MAX_FRAMES],
1393 OMX_S32 SrcRefStep,
1394 const OMXRect *pRefRect,
1395 const OMXVCM4P2Coordinate *pCurrPointPos,
1396 OMX_U32 Lambda,
1397 void *pMESpec,
1398 const OMXVCM4P10MBInfoPtr *pMBInter,
1399 OMXVCM4P10MBInfoPtr pSrcDstMBCurr,
1400 OMX_U32 *pDstCost)
1401 {
1402 OMX_S32 i, j, x, y, mode;
1403 OMX_U32 Block8x8, XPerMB, YPerMB, Block2x, Block2y;
1404 OMX_S32 PartStartX = 0, PartStartY = 0;
1405 OMX_S32 PartWidth = 8, PartHeight = 8, BlockWidth = 4, BlockHeight = 4;
1406 const OMX_U32 BlkSz [4][2] = {{4,4}, {4,8}, {8,4}};
1407 const OMX_U32 PartSz [4][2] = {{8,8}, {8,16}, {16,8}, {16,16}};
1408 const OMXVCM4P10SubMacroblockType
1409 ModeSubMBType4x4 [] = {OMX_VC_SUB_P_4x4, OMX_VC_SUB_P_4x8,
1410 OMX_VC_SUB_P_8x4, OMX_VC_SUB_P_8x8};
1411 const OMXVCM4P10MacroblockType
1412 ModeMBType [] = {OMX_VC_P_8x8, OMX_VC_P_8x16, OMX_VC_P_16x8, OMX_VC_P_16x16};
1413
1414 OMXVCM4P10MEParams *pMBOptions;
1415 /*
1416 * RefFrArr and MVArr will be used for temporary storage of Reference frame index and MVs
1417 * It will store RefIndex and MVs of 6 MBs as shown below
1418 *
1419 * |------|------|------|
1420 * |Tp-Lt |Top |Tp-R |
1421 * | MB | MB | MB |
1422 * |------|------|------|
1423 * |Left | Curr | |
1424 * | MB | MB | |
1425 * |------|------|------|
1426 */
1427 OMX_S32 RefFrArr [4][6];
1428 OMXVCMotionVector MVArr [8][12];
1429 OMXVCMotionVector MVPredArr [4][4];
1430
1431 /*
1432 * IndexToLoc will translate pMBInter index into spacial arrangement of MBs
1433 */
1434 OMX_S32 IndexToLoc [] = {2,1,3,0};
1435 OMX_U32 part, MaxPart;
1436 OMX_S32 Cost, MotionCost8x8 [4], MBCost, BestCost;
1437
1438 /*
1439 * Update neighbouring MV array and Ref frame array which will be used for
1440 * prediction of MVs and Ref frames.
1441 */
1442
1443 /* Set cost to a high value */
1444 Cost = BestCost = ARM_VCM4P10_MAX_COST;
1445
1446 for (y = 0; y < 8; y++)
1447 {
1448 for (x = 0; x < 12; x++)
1449 {
1450 i = 3 * (y >> 2) + (x >> 2);
1451 if ((y < 4 || x < 4) && (pMBInter[IndexToLoc[i]] != NULL))
1452 {
1453 MVArr [y][x].dx =
1454 pMBInter[IndexToLoc[i]]->pMV0[y % 4][x % 4].dx;
1455 MVArr [y][x].dy =
1456 pMBInter[IndexToLoc[i]]->pMV0[y % 4][x % 4].dy;
1457 }
1458 else
1459 {
1460 MVArr [y][x].dx = 0;
1461 MVArr [y][x].dy = 0;
1462 }
1463 }
1464 }
1465
1466 for (y = 0; y < 4; y++)
1467 {
1468 for (x = 0; x < 6; x++)
1469 {
1470 i = 3 * (y >> 1) + (x >> 1);
1471 if ((y < 2 || x < 2) && (pMBInter[IndexToLoc[i]] != NULL))
1472 {
1473 RefFrArr [y][x] =
1474 pMBInter[IndexToLoc[i]]->pRefL0Idx [(y % 2) * 2 + (x % 2)];
1475 }
1476 else
1477 {
1478 RefFrArr [y][x] = ARM_VCM4P10_INVALID_BLOCK;
1479 }
1480 }
1481 }
1482
1483 for (y = 0; y < 4; y++)
1484 {
1485 for (x = 0; x < 4; x++)
1486 {
1487 MVPredArr [y][x].dx = 0;
1488 MVPredArr [y][x].dy = 0;
1489 }
1490 }
1491 /*
1492 * Motion Estimation for 8x8 MB Partition
1493 */
1494
1495 for (i = 0; i < 4; i++)
1496 {
1497 MotionCost8x8 [i] = 0;
1498 }
1499
1500 pMBOptions = (OMXVCM4P10MEParams *) pMESpec;
1501
1502 if (pMBOptions->blockSplitEnable8x8 == 1 &&
1503 pMBOptions->blockSplitEnable4x4 == 1)
1504 {
1505 pSrcDstMBCurr->mbType = OMX_VC_P_8x8;
1506
1507 PartWidth = PartSz [0][0];
1508 PartHeight = PartSz [0][1];
1509
1510 /* For each 8x8 partitions */
1511 for (Block8x8 = 0; Block8x8 < 4; Block8x8++)
1512 {
1513 PartStartX = (Block8x8 % 2) << 3;
1514 PartStartY = (Block8x8 / 2) << 3;
1515
1516 Block2x = (Block8x8 & 1) << 1;
1517 Block2y = (Block8x8 >> 1) << 1;
1518
1519 BestCost = ARM_VCM4P10_MAX_COST;
1520 for (mode = 0; mode < 3; mode++)
1521 {
1522 BlockWidth = BlkSz [mode][0];
1523 BlockHeight = BlkSz [mode][1];
1524
1525 armVCM4P10_PartitionME (
1526 pSrcCurrBuf,
1527 SrcCurrStep,
1528 pSrcRefBufList,
1529 SrcRefStep,
1530 pRefRect,
1531 pCurrPointPos,
1532 pMESpec,
1533
1534 PartWidth,
1535 PartHeight,
1536 BlockWidth,
1537 BlockHeight,
1538 PartStartX,
1539 PartStartY,
1540
1541 MVArr,
1542 RefFrArr,
1543 MVPredArr,
1544
1545 Lambda,
1546 &Cost);
1547
1548 if (Cost <= BestCost)
1549 {
1550 /* Update cost */
1551 BestCost = Cost;
1552
1553 /* Update MBCurr struct */
1554 pSrcDstMBCurr->subMBType [Block8x8] = ModeSubMBType4x4 [mode];
1555
1556 pSrcDstMBCurr->pRefL0Idx [Block8x8] = RefFrArr [2 + (PartStartY >> 3)][2 + (PartStartX >> 3)];
1557
1558 /* Update pMV0 and pMVPred of MBCurr struct */
1559 for (j = 0; j < 2; j++)
1560 {
1561 for (i = 0; i < 2; i++)
1562 {
1563 pSrcDstMBCurr->pMV0 [Block2y + j][Block2x + i].dx =
1564 MVArr [4 + Block2y + j][4 + Block2x + i].dx;
1565 pSrcDstMBCurr->pMV0 [Block2y + j][Block2x + i].dy =
1566 MVArr [4 + Block2y + j][4 + Block2x + i].dy;
1567
1568 pSrcDstMBCurr->pMVPred [Block2y + j][Block2x + i].dx =
1569 MVPredArr [Block2y + j][Block2x + i].dx;
1570 pSrcDstMBCurr->pMVPred [Block2y + j][Block2x + i].dy =
1571 MVPredArr [Block2y + j][Block2x + i].dy;
1572 }
1573 }
1574 }
1575 }
1576
1577 /* Update cost */
1578 MotionCost8x8 [Block8x8] = BestCost;
1579 }
1580
1581 /* Cost for mbType OMX_VC_P_8x8 */
1582 BestCost = 0;
1583 for (i = 0; i < 4; i++)
1584 {
1585 BestCost += MotionCost8x8 [i];
1586 }
1587 }
1588 else
1589 {
1590 /* Set sub MB type to 8x8 */
1591 for (i = 0; i < 4; i++)
1592 {
1593 pSrcDstMBCurr->subMBType [i] = OMX_VC_SUB_P_8x8;
1594 }
1595 }
1596
1597 /*
1598 * Motion Estimation for 8x8, 8x16, 16x8 and 16x16 MB Partition
1599 * If pMBOptions->b8x8BlockSplitEnable is 0, do only 16x16 ME (mode 3)
1600 */
1601 for (mode = (pMBOptions->blockSplitEnable8x8 == 1 ? 0 : 3); mode < 4; mode++)
1602 {
1603 BlockWidth = PartWidth = PartSz [mode][0];
1604 BlockHeight = PartHeight = PartSz [mode][1];
1605
1606 XPerMB = 16 / PartWidth;
1607 YPerMB = 16 / PartHeight;
1608 MaxPart = XPerMB * YPerMB;
1609
1610 MBCost = 0;
1611
1612 /* part size 4, 2, 2 and 1 corresponding to 8x8, 8x16, 16x8 and 16x16 MB */
1613 for (part = 0; part < MaxPart; part++)
1614 {
1615 PartStartX = (part % XPerMB) * PartWidth;
1616 PartStartY = (part / XPerMB) * PartHeight;
1617
1618 armVCM4P10_PartitionME (
1619 pSrcCurrBuf,
1620 SrcCurrStep,
1621 pSrcRefBufList,
1622 SrcRefStep,
1623 pRefRect,
1624 pCurrPointPos,
1625 pMESpec,
1626
1627 PartWidth,
1628 PartHeight,
1629 BlockWidth,
1630 BlockHeight,
1631 PartStartX,
1632 PartStartY,
1633
1634 MVArr,
1635 RefFrArr,
1636 MVPredArr,
1637
1638 Lambda,
1639 &Cost);
1640
1641 MBCost += Cost;
1642 }
1643
1644 if (MBCost <= BestCost)
1645 {
1646 /* Update cost */
1647 BestCost = MBCost;
1648
1649 /* Update mbType of MBCurr struct */
1650 pSrcDstMBCurr->mbType = ModeMBType [mode];
1651
1652 /* Update pMV0 and pMVPred of MBCurr struct */
1653 for (j = 0; j < 4; j++)
1654 {
1655 for (i = 0; i < 4; i++)
1656 {
1657 pSrcDstMBCurr->pMV0 [j][i].dx = MVArr [4+j][4+i].dx;
1658 pSrcDstMBCurr->pMV0 [j][i].dy = MVArr [4+j][4+i].dy;
1659 pSrcDstMBCurr->pMVPred [j][i].dx = MVPredArr [j][i].dx;
1660 pSrcDstMBCurr->pMVPred [j][i].dy = MVPredArr [j][i].dy;
1661 }
1662 }
1663 for (j = 0; j < 2; j++)
1664 {
1665 for (i = 0; i < 2; i++)
1666 {
1667 pSrcDstMBCurr->pRefL0Idx [j*2+i] = RefFrArr [2+j][2+i];
1668 }
1669 }
1670 }
1671
1672 }
1673
1674 /* Update Best Cost */
1675 *pDstCost = BestCost;
1676
1677 return OMX_Sts_NoErr;
1678 }
1679
1680 /**
1681 * Function: omxVCM4P10_MotionEstimationMB (6.3.5.3.1)
1682 *
1683 * Description:
1684 * Performs MB-level motion estimation and selects best motion estimation
1685 * strategy from the set of modes supported in baseline profile [ISO14496-10].
1686 *
1687 * Input Arguments:
1688 *
1689 * pSrcCurrBuf - Pointer to the current position in original picture plane;
1690 * 16-byte alignment required
1691 * pSrcRefBufList - Pointer to an array with 16 entries. Each entry points
1692 * to the top-left corner of the co-located MB in a reference
1693 * picture. The array is filled from low-to-high with valid
1694 * reference frame pointers; the unused high entries should be set
1695 * to NULL. Ordering of the reference frames should follow
1696 * [ISO14496-10] subclause 8.2.4 Decoding Process for Reference
1697 * Picture Lists. The entries must be 16-byte aligned.
1698 * pSrcRecBuf - Pointer to the top-left corner of the co-located MB in the
1699 * reconstructed picture; must be 16-byte aligned.
1700 * SrcCurrStep - Width of the original picture plane in terms of full
1701 * pixels; must be a multiple of 16.
1702 * SrcRefStep - Width of the reference picture plane in terms of full
1703 * pixels; must be a multiple of 16.
1704 * SrcRecStep - Width of the reconstructed picture plane in terms of full
1705 * pixels; must be a multiple of 16.
1706 * pRefRect - Pointer to the valid reference rectangle; relative to the
1707 * image origin.
1708 * pCurrPointPos - Position of the current macroblock in the current plane.
1709 * Lambda - Lagrange factor for computing the cost function
1710 * pMESpec - Pointer to the motion estimation specification structure; must
1711 * have been allocated and initialized prior to calling this
1712 * function.
1713 * pMBInter - Array, of dimension four, containing pointers to information
1714 * associated with four adjacent type INTER MBs (Left, Top,
1715 * Top-Left, Top-Right). Any pointer in the array may be set equal
1716 * to NULL if the corresponding MB doesn t exist or is not of type
1717 * INTER. pMBInter[0] - Pointer to left MB information pMBInter[1]
1718 * - Pointer to top MB information pMBInter[2] - Pointer to
1719 * top-left MB information pMBInter[3] - Pointer to top-right MB
1720 * information
1721 * pMBIntra - Array, of dimension four, containing pointers to information
1722 * associated with four adjacent type INTRA MBs (Left, Top,
1723 * Top-Left, Top-Right). Any pointer in the array may be set equal
1724 * to NULL if the corresponding MB doesn t exist or is not of type
1725 * INTRA. pMBIntra[0] - Pointer to left MB information pMBIntra[1]
1726 * - Pointer to top MB information pMBIntra[2] - Pointer to
1727 * top-left MB information pMBIntra[3] - Pointer to top-right MB
1728 * information
1729 * pSrcDstMBCurr - Pointer to information structure for the current MB.
1730 * The following entries should be set prior to calling the
1731 * function: sliceID - the number of the slice the to which the
1732 * current MB belongs.
1733 *
1734 * Output Arguments:
1735 *
1736 * pDstCost - Pointer to the minimum motion cost for the current MB.
1737 * pDstBlockSAD - Pointer to the array of SADs for each of the sixteen luma
1738 * 4x4 blocks in each MB. The block SADs are in scan order for
1739 * each MB. For implementations that cannot compute the SAD values
1740 * individually, the maximum possible value (0xffff) is returned
1741 * for each of the 16 block SAD entries.
1742 * pSrcDstMBCurr - Pointer to updated information structure for the current
1743 * MB after MB-level motion estimation has been completed. The
1744 * following fields are updated by the ME function. The following
1745 * parameter set quantifies the MB-level ME search results: MbType
1746 * subMBType[4] pMV0[4][4] pMVPred[4][4] pRefL0Idx[4]
1747 * Intra16x16PredMode pIntra4x4PredMode[4][4]
1748 *
1749 * Return Value:
1750 * OMX_Sts_NoErr, if the function runs without error.
1751 * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
1752 * - One of more of the following pointers is NULL: pSrcCurrBuf,
1753 * pSrcRefBufList, pSrcRecBuf, pRefRect, pCurrPointPos, pMESpec,
1754 * pMBInter, pMBIntra,pSrcDstMBCurr, pDstCost, pSrcRefBufList[0]
1755 * - SrcRefStep, SrcRecStep are not multiples of 16
1756 * - iBlockWidth or iBlockHeight are values other than 4, 8, or 16.
1757 * - Any alignment restrictions are violated
1758 *
1759 */
1760
omxVCM4P10_MotionEstimationMB(const OMX_U8 * pSrcCurrBuf,OMX_S32 SrcCurrStep,const OMX_U8 * pSrcRefBufList[ARM_VCM4P10_MAX_FRAMES],OMX_S32 SrcRefStep,const OMX_U8 * pSrcRecBuf,OMX_S32 SrcRecStep,const OMXRect * pRefRect,const OMXVCM4P2Coordinate * pCurrPointPos,OMX_U32 Lambda,void * pMESpec,const OMXVCM4P10MBInfoPtr * pMBInter,const OMXVCM4P10MBInfoPtr * pMBIntra,OMXVCM4P10MBInfo * pSrcDstMBCurr,OMX_INT * pDstCost,OMX_U16 * pDstBlockSAD)1761 OMXResult omxVCM4P10_MotionEstimationMB(
1762 const OMX_U8 *pSrcCurrBuf,
1763 OMX_S32 SrcCurrStep,
1764 const OMX_U8 *pSrcRefBufList[ARM_VCM4P10_MAX_FRAMES],
1765 OMX_S32 SrcRefStep,
1766 const OMX_U8 *pSrcRecBuf,
1767 OMX_S32 SrcRecStep,
1768 const OMXRect *pRefRect,
1769 const OMXVCM4P2Coordinate *pCurrPointPos,
1770 OMX_U32 Lambda,
1771 void *pMESpec,
1772 const OMXVCM4P10MBInfoPtr *pMBInter,
1773 const OMXVCM4P10MBInfoPtr *pMBIntra,
1774 OMXVCM4P10MBInfo *pSrcDstMBCurr,
1775 OMX_INT *pDstCost,
1776 OMX_U16 *pDstBlockSAD)
1777 {
1778 OMX_U32 Cost, i, IntraFlag = 1;
1779 OMXVCM4P10MEParams *pMEParams;
1780
1781 /* check for argument error */
1782 armRetArgErrIf(pSrcCurrBuf == NULL, OMX_Sts_BadArgErr)
1783 armRetArgErrIf(pSrcRefBufList == NULL, OMX_Sts_BadArgErr)
1784 armRetArgErrIf(pSrcRecBuf == NULL, OMX_Sts_BadArgErr)
1785 armRetArgErrIf(pRefRect == NULL, OMX_Sts_BadArgErr)
1786 armRetArgErrIf(pCurrPointPos == NULL, OMX_Sts_BadArgErr)
1787 armRetArgErrIf(pMESpec == NULL, OMX_Sts_BadArgErr)
1788 armRetArgErrIf(pMBInter == NULL, OMX_Sts_BadArgErr)
1789 armRetArgErrIf(pMBIntra == NULL, OMX_Sts_BadArgErr)
1790 armRetArgErrIf(pSrcDstMBCurr == NULL, OMX_Sts_BadArgErr)
1791 armRetArgErrIf(pDstCost == NULL, OMX_Sts_BadArgErr)
1792 armRetArgErrIf(SrcRefStep <= 0 || SrcRefStep & 15, OMX_Sts_BadArgErr)
1793 armRetArgErrIf(SrcRecStep <= 0 || SrcRecStep & 15, OMX_Sts_BadArgErr)
1794 armRetArgErrIf(SrcCurrStep <= 0 || SrcCurrStep & 15, OMX_Sts_BadArgErr)
1795
1796 armRetArgErrIf(armNot16ByteAligned(pSrcCurrBuf), OMX_Sts_BadArgErr)
1797 armRetArgErrIf(armNot16ByteAligned(pSrcRecBuf), OMX_Sts_BadArgErr)
1798
1799 for (i = 0; i < ARM_VCM4P10_MAX_FRAMES; i++)
1800 {
1801 armRetArgErrIf(pSrcRefBufList [i] != NULL &&
1802 armNot16ByteAligned(pSrcRefBufList [i]), OMX_Sts_BadArgErr)
1803
1804 /* Check if current MB needs INTER cost calculations */
1805 if (pSrcRefBufList [i] != NULL && IntraFlag == 1)
1806 {
1807 IntraFlag = 0;
1808 }
1809 }
1810
1811 *pDstCost = ARM_VCM4P10_MAX_COST;
1812 /*
1813 * Inter cost calculations
1814 */
1815
1816 /* check this MB can be Inter */
1817 if (IntraFlag != 1)
1818 {
1819 armVCM4P10_InterMEMB(
1820 pSrcCurrBuf,
1821 SrcCurrStep,
1822 pSrcRefBufList,
1823 SrcRefStep,
1824 pRefRect,
1825 pCurrPointPos,
1826 Lambda,
1827 pMESpec,
1828 pMBInter,
1829 pSrcDstMBCurr,
1830 &Cost
1831 );
1832
1833 *pDstCost = Cost;
1834 }
1835
1836 pMEParams = (OMXVCM4P10MEParams *)pMESpec;
1837
1838 if (pMEParams->intraEnable4x4 == 1)
1839 {
1840 /*
1841 * Intra 4x4 cost calculations
1842 */
1843 armVCM4P10_Intra4x4Estimation(
1844 pSrcCurrBuf,
1845 SrcCurrStep,
1846 pSrcRecBuf,
1847 SrcRecStep,
1848 pMBIntra,
1849 pSrcDstMBCurr,
1850 &Cost
1851 );
1852
1853 if (Cost <= *pDstCost)
1854 {
1855 *pDstCost = Cost;
1856 pSrcDstMBCurr->mbType = OMX_VC_INTRA_4x4;
1857
1858 }
1859
1860 }
1861
1862 /*
1863 * Cost for Intra 16x16 mode
1864 */
1865
1866 armVCM4P10_Intra16x16Estimation(
1867 pSrcCurrBuf,
1868 SrcCurrStep,
1869 pSrcRecBuf,
1870 SrcRecStep,
1871 pCurrPointPos,
1872 pMBInter,
1873 pMBIntra,
1874 pSrcDstMBCurr,
1875 &Cost
1876 );
1877
1878 if (Cost <= *pDstCost)
1879 {
1880 *pDstCost = Cost;
1881 pSrcDstMBCurr->mbType = OMX_VC_INTRA_16x16;
1882 }
1883
1884 /*
1885 * Update pDstBlockSAD to max value
1886 */
1887 armVCM4P10_CalculateBlockSAD( pSrcDstMBCurr,
1888 pSrcCurrBuf,
1889 SrcCurrStep,
1890 pSrcRefBufList,
1891 SrcRefStep,
1892 pSrcRecBuf,
1893 SrcRecStep,
1894 pRefRect,
1895 pCurrPointPos,
1896 pMBInter,
1897 pMBIntra,
1898 pDstBlockSAD);
1899
1900
1901 return OMX_Sts_NoErr;
1902 }
1903
1904
1905 /*****************************************************************************
1906 * END OF FILE
1907 *****************************************************************************/
1908