Home | History | Annotate | Download | only in src
      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 
     87 OMXResult 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