Home | History | Annotate | Download | only in src
      1 /**
      2  *
      3  * File Name:  armVCM4P2_ACDCPredict.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 DC/AC coefficient prediction
     14  *
     15  */
     16 
     17 #include "omxtypes.h"
     18 #include "armOMX.h"
     19 
     20 #include "armVC.h"
     21 #include "armCOMM.h"
     22 
     23 /**
     24  * Function: armVCM4P2_ACDCPredict
     25  *
     26  * Description:
     27  * Performs adaptive DC/AC coefficient prediction for an intra block. Prior
     28  * to the function call, prediction direction (predDir) should be selected
     29  * as specified in subclause 7.4.3.1 of ISO/IEC 14496-2.
     30  *
     31  * Remarks:
     32  *
     33  * Parameters:
     34  * [in] pSrcDst     pointer to the coefficient buffer which contains
     35  *                          the quantized coefficient residuals (PQF) of the
     36  *                          current block
     37  * [in] pPredBufRow pointer to the coefficient row buffer
     38  * [in] pPredBufCol pointer to the coefficient column buffer
     39  * [in] curQP       quantization parameter of the current block. curQP
     40  *                          may equal to predQP especially when the current
     41  *                          block and the predictor block are in the same
     42  *                          macroblock.
     43  * [in] predQP      quantization parameter of the predictor block
     44  * [in] predDir     indicates the prediction direction which takes one
     45  *                          of the following values:
     46  *                          OMX_VC_HORIZONTAL    predict horizontally
     47  *                          OMX_VC_VERTICAL      predict vertically
     48  * [in] ACPredFlag  a flag indicating if AC prediction should be
     49  *                          performed. It is equal to ac_pred_flag in the bit
     50  *                          stream syntax of MPEG-4
     51  * [in] videoComp   video component type (luminance, chrominance or
     52  *                          alpha) of the current block
     53  * [in] flag        This flag defines the if one wants to use this functions to
     54  *                  calculate PQF (set 1, prediction) or QF (set 0, reconstruction)
     55  * [out]    pPreACPredict   pointer to the predicted coefficients buffer.
     56  *                          Filled ONLY if it is not NULL
     57  * [out]    pSrcDst     pointer to the coefficient buffer which contains
     58  *                          the quantized coefficients (QF) of the current
     59  *                          block
     60  * [out]    pPredBufRow pointer to the updated coefficient row buffer
     61  * [out]    pPredBufCol pointer to the updated coefficient column buffer
     62  * [out]    pSumErr     pointer to the updated sum of the difference
     63  *                      between predicted and unpredicted coefficients
     64  *                      If this is NULL, do not update
     65  *
     66  * Return Value:
     67  * Standard OMXResult result. See enumeration for possible result codes.
     68  *
     69  */
     70 
     71 OMXResult armVCM4P2_ACDCPredict(
     72      OMX_S16 * pSrcDst,
     73      OMX_S16 * pPreACPredict,
     74      OMX_S16 * pPredBufRow,
     75      OMX_S16 * pPredBufCol,
     76      OMX_INT curQP,
     77      OMX_INT predQP,
     78      OMX_INT predDir,
     79      OMX_INT ACPredFlag,
     80      OMXVCM4P2VideoComponent videoComp,
     81      OMX_U8 flag,
     82      OMX_INT *pSumErr
     83 )
     84 {
     85     OMX_INT dcScaler, i;
     86     OMX_S16 tempPred;
     87 
     88     /* Argument error checks */
     89     armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr);
     90     armRetArgErrIf(pPredBufRow == NULL, OMX_Sts_BadArgErr);
     91     armRetArgErrIf(pPredBufCol == NULL, OMX_Sts_BadArgErr);
     92     armRetArgErrIf(curQP <= 0, OMX_Sts_BadArgErr);
     93     armRetArgErrIf(predQP <= 0, OMX_Sts_BadArgErr);
     94     armRetArgErrIf((predDir != 1) && (predDir != 2), OMX_Sts_BadArgErr);
     95     armRetArgErrIf(!armIs4ByteAligned(pSrcDst), OMX_Sts_BadArgErr);
     96     armRetArgErrIf(!armIs4ByteAligned(pPredBufRow), OMX_Sts_BadArgErr);
     97     armRetArgErrIf(!armIs4ByteAligned(pPredBufCol), OMX_Sts_BadArgErr);
     98 
     99 
    100     /* Set DC scaler value to avoid some compilers giving a warning. */
    101     dcScaler=0;
    102 
    103     /* Calculate the DC scaler value */
    104     if (videoComp == OMX_VC_LUMINANCE)
    105     {
    106         if (curQP >= 1 && curQP <= 4)
    107         {
    108             dcScaler = 8;
    109         }
    110         else if (curQP >= 5 && curQP <= 8)
    111         {
    112             dcScaler = 2 * curQP;
    113         }
    114         else if (curQP >= 9 && curQP <= 24)
    115         {
    116             dcScaler = curQP + 8;
    117         }
    118         else
    119         {
    120             dcScaler = (2 * curQP) - 16;
    121         }
    122     }
    123     else if (videoComp == OMX_VC_CHROMINANCE)
    124     {
    125         if (curQP >= 1 && curQP <= 4)
    126         {
    127             dcScaler = 8;
    128         }
    129         else if (curQP >= 5 && curQP <= 24)
    130         {
    131             dcScaler = (curQP + 13)/2;
    132         }
    133         else
    134         {
    135             dcScaler = curQP - 6;
    136         }
    137     }
    138 
    139     if (pPreACPredict != NULL)
    140     {
    141         pPreACPredict[0] = predDir;
    142     }
    143 
    144     if (predDir == OMX_VC_VERTICAL)
    145     {
    146         /* F[0][0]//dc_scaler */
    147         tempPred = armIntDivAwayFromZero(pPredBufRow[0], dcScaler);
    148     }
    149     else
    150     {
    151         /* F[0][0]//dc_scaler */
    152         tempPred = armIntDivAwayFromZero(pPredBufCol[0], dcScaler);
    153     }
    154 
    155     /* Updating the DC value to the row and col buffer */
    156     *(pPredBufRow - 8) = *pPredBufCol;
    157 
    158     if (flag)
    159     {
    160         /* Cal and store F[0][0] into the col buffer */
    161         *pPredBufCol = pSrcDst[0] * dcScaler;
    162 
    163         /* PQF = QF - F[0][0]//dc_scaler */
    164         pSrcDst[0] -= tempPred;
    165     }
    166     else
    167     {
    168         /* QF = PQF + F[0][0]//dc_scaler */
    169         pSrcDst[0] += tempPred;
    170 
    171         /* Saturate */
    172         pSrcDst[0] = armClip (-2048, 2047, pSrcDst[0]);
    173 
    174         /* Cal and store F[0][0] into the col buffer */
    175         *pPredBufCol = pSrcDst[0] * dcScaler;
    176     }
    177 
    178 
    179     if (ACPredFlag == 1)
    180     {
    181         if (predDir == OMX_VC_VERTICAL)
    182         {
    183             for (i = 1; i < 8; i++)
    184             {
    185                 tempPred = armIntDivAwayFromZero \
    186                               (pPredBufRow[i] * predQP, curQP);
    187                 if (flag)
    188                 {
    189                     /* Updating QF to the row buff */
    190                     pPredBufRow[i] = pSrcDst[i];
    191                     /*PQFX[v][0] = QFX[v][0] - (QFA[v][0] * QPA) // QPX */
    192                     pSrcDst[i] -= tempPred;
    193                     /* Sum of absolute values of AC prediction error, this can
    194                     be used as a reference to choose whether to use
    195                     AC prediction */
    196                     *pSumErr += armAbs(pSrcDst[i]);
    197                     /* pPreACPredict[1~7] store the error signal
    198                     after AC prediction */
    199                     pPreACPredict[i] = pSrcDst[i];
    200                 }
    201                 else
    202                 {
    203                     /*QFX[v][0] = PQFX[v][0] + (QFA[v][0] * QPA) // QPX */
    204                     pSrcDst[i] += tempPred;
    205 
    206                     /* Saturate */
    207                     pSrcDst[i] = armClip (-2048, 2047, pSrcDst[i]);
    208 
    209                     /* Updating QF to the row buff */
    210                     pPredBufRow[i] = pSrcDst[i];
    211                 }
    212             }
    213         }
    214         else
    215         {
    216             for (i = 8; i < 64; i += 8)
    217             {
    218                 tempPred = armIntDivAwayFromZero \
    219                               (pPredBufCol[i>>3] * predQP, curQP);
    220                 if (flag)
    221                 {
    222                     /* Updating QF to col buff */
    223                     pPredBufCol[i>>3] = pSrcDst[i];
    224                     /*PQFX[0][u] = QFX[0][u] - (QFA[0][u] * QPA) // QPX */
    225                     pSrcDst[i] -= tempPred;
    226                     /* Sum of absolute values of AC prediction error, this can
    227                     be used as a reference to choose whether to use AC
    228                     prediction */
    229                     *pSumErr += armAbs(pSrcDst[i]);
    230                     /* pPreACPredict[1~7] store the error signal
    231                     after AC prediction */
    232                     pPreACPredict[i>>3] = pSrcDst[i];
    233                 }
    234                 else
    235                 {
    236                     /*QFX[0][u] = PQFX[0][u] + (QFA[0][u] * QPA) // QPX */
    237                     pSrcDst[i] += tempPred;
    238 
    239                     /* Saturate */
    240                     pSrcDst[i] = armClip (-2048, 2047, pSrcDst[i]);
    241 
    242                     /* Updating QF to col buff */
    243                     pPredBufCol[i>>3] = pSrcDst[i];
    244                 }
    245             }
    246         }
    247     }
    248 
    249     return OMX_Sts_NoErr;
    250 }
    251 
    252 /*End of File*/
    253 
    254