• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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