omxVCM4P2_FindMVpred.c revision 0c1bc742181ded4930842b46e9507372f0b1b963
1/**
2 *
3 * File Name:  omxVCM4P2_FindMVpred.c
4 * OpenMAX DL: v1.0.2
5 * Revision:   9641
6 * Date:       Thursday, February 7, 2008
7 *
8 * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
9 *
10 *
11 *
12 * Description:
13 * Contains module for predicting MV of MB
14 *
15 */
16
17#include "omxtypes.h"
18#include "armOMX.h"
19#include "omxVC.h"
20
21#include "armCOMM.h"
22
23/**
24 * Function:  omxVCM4P2_FindMVpred   (6.2.3.1.1)
25 *
26 * Description:
27 * Predicts a motion vector for the current block using the procedure
28 * specified in [ISO14496-2], subclause 7.6.5.  The resulting predicted MV is
29 * returned in pDstMVPred. If the parameter pDstMVPredME if is not NULL then
30 * the set of three MV candidates used for prediction is also returned,
31 * otherwise pDstMVPredMEis NULL upon return.
32 *
33 * Input Arguments:
34 *
35 *   pSrcMVCurMB - pointer to the MV buffer associated with the current Y
36 *            macroblock; a value of NULL indicates unavailability.
37 *   pSrcCandMV1 - pointer to the MV buffer containing the 4 MVs associated
38 *            with the MB located to the left of the current MB; set to NULL
39 *            if there is no MB to the left.
40 *   pSrcCandMV2 - pointer to the MV buffer containing the 4 MVs associated
41 *            with the MB located above the current MB; set to NULL if there
42 *            is no MB located above the current MB.
43 *   pSrcCandMV3 - pointer to the MV buffer containing the 4 MVs associated
44 *            with the MB located to the right and above the current MB; set
45 *            to NULL if there is no MB located to the above-right.
46 *   iBlk - the index of block in the current macroblock
47 *   pDstMVPredME - MV candidate return buffer;  if set to NULL then
48 *            prediction candidate MVs are not returned and pDstMVPredME will
49 *            be NULL upon function return; if pDstMVPredME is non-NULL then it
50 *            must point to a buffer containing sufficient space for three
51 *            return MVs.
52 *
53 * Output Arguments:
54 *
55 *   pDstMVPred - pointer to the predicted motion vector
56 *   pDstMVPredME - if non-NULL upon input then pDstMVPredME  points upon
57 *            return to a buffer containing the three motion vector candidates
58 *            used for prediction as specified in [ISO14496-2], subclause
59 *            7.6.5, otherwise if NULL upon input then pDstMVPredME is NULL
60 *            upon output.
61 *
62 * Return Value:
63 *
64 *    OMX_Sts_NoErr - no error
65 *    OMX_Sts_BadArgErr - bad arguments; returned under any of the following
66 *              conditions:
67 *    -    the pointer pDstMVPred is NULL
68 *    -    the parameter iBlk does not fall into the range 0 <= iBlk<=3
69 *
70 */
71
72OMXResult omxVCM4P2_FindMVpred(
73     const OMXVCMotionVector* pSrcMVCurMB,
74     const OMXVCMotionVector* pSrcCandMV1,
75     const OMXVCMotionVector* pSrcCandMV2,
76     const OMXVCMotionVector* pSrcCandMV3,
77     OMXVCMotionVector* pDstMVPred,
78     OMXVCMotionVector* pDstMVPredME,
79     OMX_INT iBlk
80 )
81{
82    OMXVCMotionVector CandMV;
83	const OMXVCMotionVector *pCandMV1;
84    const OMXVCMotionVector *pCandMV2;
85    const OMXVCMotionVector *pCandMV3;
86
87    /* Argument error checks */
88	armRetArgErrIf(iBlk!=0 && pSrcMVCurMB == NULL, OMX_Sts_BadArgErr);
89    armRetArgErrIf(pDstMVPred == NULL, OMX_Sts_BadArgErr);
90    armRetArgErrIf((iBlk < 0) || (iBlk > 3), OMX_Sts_BadArgErr);
91
92    CandMV.dx = CandMV.dy = 0;
93	/* Based on the position of the block extract the motion vectors and
94       the tranperancy status */
95
96
97    /* Set the default value for these to be used if pSrcCandMV[1|2|3] == NULL */
98    pCandMV1 = pCandMV2 = pCandMV3 = &CandMV;
99
100
101    switch (iBlk)
102    {
103        case 0:
104        {
105            if(pSrcCandMV1 != NULL)
106            {
107			    pCandMV1 = &pSrcCandMV1[1];
108			}
109			if(pSrcCandMV2 != NULL)
110            {
111				pCandMV2 = &pSrcCandMV2[2];
112			}
113			if(pSrcCandMV3 != NULL)
114            {
115				pCandMV3 = &pSrcCandMV3[2];
116			}
117			if ((pSrcCandMV1 == NULL) && (pSrcCandMV2 == NULL))
118            {
119                pCandMV1 = pCandMV2 = pCandMV3;
120            }
121            else if((pSrcCandMV1 == NULL) && (pSrcCandMV3 == NULL))
122            {
123                pCandMV1 = pCandMV3 = pCandMV2;
124            }
125            else if((pSrcCandMV2 == NULL) && (pSrcCandMV3 == NULL))
126            {
127                pCandMV2 = pCandMV3 = pCandMV1;
128            }
129            break;
130        }
131        case 1:
132        {
133            pCandMV1 = &pSrcMVCurMB[0];
134			if(pSrcCandMV2 != NULL)
135            {
136				pCandMV2 = &pSrcCandMV2[3];
137			}
138			if(pSrcCandMV3 != NULL)
139            {
140				pCandMV3 = &pSrcCandMV3[2];
141			}
142			if((pSrcCandMV2 == NULL) && (pSrcCandMV3 == NULL))
143            {
144                pCandMV2 = pCandMV3 = pCandMV1;
145            }
146            break;
147        }
148        case 2:
149        {
150            if(pSrcCandMV1 != NULL)
151            {
152				pCandMV1 = &pSrcCandMV1[3];
153			}
154			pCandMV2 = &pSrcMVCurMB[0];
155			pCandMV3 = &pSrcMVCurMB[1];
156			break;
157        }
158        case 3:
159        {
160            pCandMV1 = &pSrcMVCurMB[2];
161			pCandMV2 = &pSrcMVCurMB[0];
162			pCandMV3 = &pSrcMVCurMB[1];
163			break;
164        }
165    }
166
167    /* Find the median of the 3 candidate MV's */
168    pDstMVPred->dx = armMedianOf3 (pCandMV1->dx, pCandMV2->dx, pCandMV3->dx);
169    pDstMVPred->dy = armMedianOf3 (pCandMV1->dy, pCandMV2->dy, pCandMV3->dy);
170
171    if (pDstMVPredME != NULL)
172    {
173        /* Store the candidate MV's into the pDstMVPredME, these can be used
174           in the fast algorithm if implemented */
175        pDstMVPredME[0].dx = pCandMV1->dx;
176        pDstMVPredME[0].dy = pCandMV1->dy;
177        pDstMVPredME[1].dx = pCandMV2->dx;
178        pDstMVPredME[1].dy = pCandMV2->dy;
179        pDstMVPredME[2].dx = pCandMV3->dx;
180        pDstMVPredME[2].dy = pCandMV3->dy;
181    }
182
183    return OMX_Sts_NoErr;
184}
185
186
187/* End of file */
188
189