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