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:  omxVCM4P10_SubAndTransformQDQResidual.c
     20  * OpenMAX DL: v1.0.2
     21  * Revision:   9641
     22  * Date:       Thursday, February 7, 2008
     23  *
     24  *
     25  *
     26  * Description:
     27  * This function will calculate SAD for 4x4 blocks
     28  *
     29  */
     30 
     31 #include "omxtypes.h"
     32 #include "armOMX.h"
     33 #include "omxVC.h"
     34 
     35 #include "armCOMM.h"
     36 #include "armVC.h"
     37 
     38 /**
     39  * Function:  omxVCM4P10_SubAndTransformQDQResidual   (6.3.5.8.1)
     40  *
     41  * Description:
     42  * This function subtracts the prediction signal from the original signal to
     43  * produce the difference signal and then performs a 4x4 integer transform and
     44  * quantization. The quantized transformed coefficients are stored as
     45  * pDstQuantCoeff. This function can also output dequantized coefficients or
     46  * unquantized DC coefficients optionally by setting the pointers
     47  * pDstDeQuantCoeff, pDCCoeff.
     48  *
     49  * Input Arguments:
     50  *
     51  *   pSrcOrg - Pointer to original signal. 4-byte alignment required.
     52  *   pSrcPred - Pointer to prediction signal. 4-byte alignment required.
     53  *   iSrcOrgStep - Step of the original signal buffer; must be a multiple of
     54  *            4.
     55  *   iSrcPredStep - Step of the prediction signal buffer; must be a multiple
     56  *            of 4.
     57  *   pNumCoeff -Number of non-zero coefficients after quantization. If this
     58  *            parameter is not required, it is set to NULL.
     59  *   nThreshSAD - Zero-block early detection threshold. If this parameter is
     60  *            not required, it is set to 0.
     61  *   iQP - Quantization parameter; must be in the range [0,51].
     62  *   bIntra - Indicates whether this is an INTRA block, either 1-INTRA or
     63  *            0-INTER
     64  *
     65  * Output Arguments:
     66  *
     67  *   pDstQuantCoeff - Pointer to the quantized transformed coefficients.
     68  *            8-byte alignment required.
     69  *   pDstDeQuantCoeff - Pointer to the dequantized transformed coefficients
     70  *            if this parameter is not equal to NULL.  8-byte alignment
     71  *            required.
     72  *   pDCCoeff - Pointer to the unquantized DC coefficient if this parameter
     73  *            is not equal to NULL.
     74  *
     75  * Return Value:
     76  *
     77  *    OMX_Sts_NoErr - no error
     78  *    OMX_Sts_BadArgErr - bad arguments; returned if any of the following
     79  *              conditions are true:
     80  *    -    at least one of the following pointers is NULL:
     81  *            pSrcOrg, pSrcPred, pNumCoeff, pDstQuantCoeff,
     82  *            pDstDeQuantCoeff, pDCCoeff
     83  *    -    pSrcOrg is not aligned on a 4-byte boundary
     84  *    -    pSrcPred is not aligned on a 4-byte boundary
     85  *    -    iSrcOrgStep is not a multiple of 4
     86  *    -    iSrcPredStep is not a multiple of 4
     87  *    -    pDstQuantCoeff or pDstDeQuantCoeff is not aligned on an 8-byte boundary
     88  *
     89  */
     90  OMXResult omxVCM4P10_SubAndTransformQDQResidual (
     91 	 const OMX_U8*		pSrcOrg,
     92 	 const OMX_U8*		pSrcPred,
     93 	 OMX_U32		iSrcOrgStep,
     94 	 OMX_U32		iSrcPredStep,
     95 	 OMX_S16*	    pDstQuantCoeff,
     96 	 OMX_S16* 	    pDstDeQuantCoeff,
     97 	 OMX_S16*	    pDCCoeff,
     98 	 OMX_S8*		pNumCoeff,
     99 	 OMX_U32		nThreshSAD,
    100 	 OMX_U32		iQP,
    101 	 OMX_U8		    bIntra
    102 )
    103 {
    104     OMX_INT     i, j;
    105     OMX_S8      NumCoeff = 0;
    106     OMX_S16     Buf[16], m[16];
    107     OMX_U32     QBits, QPper, QPmod, f;
    108     OMX_S32     Value, MF, ThreshDC;
    109 
    110     /* check for argument error */
    111     armRetArgErrIf(pSrcOrg == NULL, OMX_Sts_BadArgErr)
    112 	armRetArgErrIf(pDstDeQuantCoeff == NULL, OMX_Sts_BadArgErr)
    113 	armRetArgErrIf(pNumCoeff == NULL, OMX_Sts_BadArgErr)
    114 	armRetArgErrIf(pDCCoeff == NULL, OMX_Sts_BadArgErr)
    115     armRetArgErrIf(armNot4ByteAligned(pSrcOrg), OMX_Sts_BadArgErr)
    116     armRetArgErrIf(pSrcPred == NULL, OMX_Sts_BadArgErr)
    117     armRetArgErrIf(armNot4ByteAligned(pSrcPred), OMX_Sts_BadArgErr)
    118     armRetArgErrIf(pDstQuantCoeff == NULL, OMX_Sts_BadArgErr)
    119     armRetArgErrIf(armNot8ByteAligned(pDstQuantCoeff), OMX_Sts_BadArgErr)
    120     armRetArgErrIf((pDstDeQuantCoeff != NULL) &&
    121 			armNot8ByteAligned(pDstDeQuantCoeff), OMX_Sts_BadArgErr)
    122     armRetArgErrIf((bIntra != 0) && (bIntra != 1), OMX_Sts_BadArgErr)
    123     armRetArgErrIf(iQP > 51, OMX_Sts_BadArgErr)
    124     armRetArgErrIf(iSrcOrgStep == 0, OMX_Sts_BadArgErr)
    125     armRetArgErrIf(iSrcPredStep == 0, OMX_Sts_BadArgErr)
    126     armRetArgErrIf(iSrcOrgStep & 3, OMX_Sts_BadArgErr)
    127     armRetArgErrIf(iSrcPredStep & 3, OMX_Sts_BadArgErr)
    128 
    129     /*
    130      * Zero-Block Early detection using nThreshSAD param
    131      */
    132 
    133     QPper = iQP / 6;
    134     QPmod = iQP % 6;
    135     QBits = 15 + QPper;
    136 
    137     f = (1 << QBits) / (bIntra ? 3 : 6);
    138 
    139     /* Do Zero-Block Early detection if enabled */
    140     if (nThreshSAD)
    141     {
    142         ThreshDC = ((1 << QBits) - f) / armVCM4P10_MFMatrix[QPmod][0];
    143         if (nThreshSAD < ThreshDC)
    144         {
    145             /* Set block to zero */
    146             if (pDCCoeff != NULL)
    147             {
    148                 *pDCCoeff = 0;
    149             }
    150 
    151             for (j = 0; j < 4; j++)
    152             {
    153                 for (i = 0; i < 4; i++)
    154                 {
    155                     pDstQuantCoeff [4 * j + i] = 0;
    156                     if (pDstDeQuantCoeff != NULL)
    157                     {
    158                         pDstDeQuantCoeff [4 * j + i] = 0;
    159                     }
    160                 }
    161             }
    162 
    163             if (pNumCoeff != NULL)
    164             {
    165                 *pNumCoeff = 0;
    166             }
    167             return OMX_Sts_NoErr;
    168         }
    169     }
    170 
    171 
    172    /* Calculate difference */
    173     for (j = 0; j < 4; j++)
    174     {
    175         for (i = 0; i < 4; i++)
    176         {
    177             Buf [j * 4 + i] =
    178                 pSrcOrg [j * iSrcOrgStep + i] - pSrcPred [j * iSrcPredStep + i];
    179         }
    180     }
    181 
    182     /* Residual Transform */
    183     armVCM4P10_FwdTransformResidual4x4 (m, Buf);
    184 
    185     if (pDCCoeff != NULL)
    186     {
    187         /* Copy unquantized DC value into pointer */
    188         *pDCCoeff = m[0];
    189     }
    190 
    191     /* Quantization */
    192     for (j = 0; j < 4; j++)
    193     {
    194         for (i = 0; i < 4; i++)
    195         {
    196             MF = armVCM4P10_MFMatrix[QPmod][armVCM4P10_PosToVCol4x4[j * 4 + i]];
    197             Value = armAbs(m[j * 4 + i]) * MF + f;
    198             Value >>= QBits;
    199             Value = m[j * 4 + i] < 0 ? -Value : Value;
    200             Buf[4 * j + i] = pDstQuantCoeff [4 * j + i] = (OMX_S16)Value;
    201             if ((pNumCoeff != NULL) && Value)
    202             {
    203                 NumCoeff++;
    204             }
    205         }
    206     }
    207 
    208     /* Output number of non-zero Coeffs */
    209     if (pNumCoeff != NULL)
    210     {
    211         *pNumCoeff = NumCoeff;
    212     }
    213 
    214     /* Residual Inv Transform */
    215     if (pDstDeQuantCoeff != NULL)
    216     {
    217         /* Re Scale */
    218         for (j = 0; j < 4; j++)
    219         {
    220             for (i = 0; i < 4; i++)
    221             {
    222                 m [j * 4 + i]  = Buf [j * 4 + i] * (1 << QPper) *
    223                     armVCM4P10_VMatrix[QPmod][armVCM4P10_PosToVCol4x4[j * 4 + i]];
    224             }
    225         }
    226         armVCM4P10_TransformResidual4x4 (pDstDeQuantCoeff, m);
    227     }
    228 
    229     return OMX_Sts_NoErr;
    230 }
    231 
    232 /*****************************************************************************
    233  *                              END OF FILE
    234  *****************************************************************************/
    235 
    236