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