Home | History | Annotate | Download | only in src
      1 /* ----------------------------------------------------------------
      2  *
      3  *
      4  * File Name:  omxVCM4P10_PredictIntraChroma_8x8.c
      5  * OpenMAX DL: v1.0.2
      6  * Revision:   9641
      7  * Date:       Thursday, February 7, 2008
      8  *
      9  * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
     10  *
     11  *
     12  *
     13  * H.264 Chroma 8x8 intra prediction module
     14  *
     15  */
     16 
     17 #include "omxtypes.h"
     18 #include "armOMX.h"
     19 #include "omxVC.h"
     20 
     21 #include "armCOMM.h"
     22 #include "armVC.h"
     23 
     24 /*
     25  * Description:
     26  * Perform DC style intra prediction, upper block has priority
     27  *
     28  * Parameters:
     29  * [in]	pSrcLeft		Pointer to the buffer of 16 left coefficients:
     30  *								p[x, y] (x = -1, y = 0..3)
     31  * [in]	pSrcAbove		Pointer to the buffer of 16 above coefficients:
     32  *								p[x,y] (x = 0..3, y = -1)
     33  * [in]	leftStep		Step of left coefficient buffer
     34  * [in]	dstStep			Step of the destination buffer
     35  * [in]	availability	Neighboring 16x16 MB availability flag
     36  * [out]	pDst			Pointer to the destination buffer
     37  *
     38  * Return Value:
     39  * None
     40  */
     41 
     42 static void armVCM4P10_PredictIntraDCUp4x4(
     43      const OMX_U8* pSrcLeft,
     44      const OMX_U8 *pSrcAbove,
     45      OMX_U8* pDst,
     46      OMX_INT leftStep,
     47      OMX_INT dstStep,
     48      OMX_S32 availability
     49 )
     50 {
     51     int x, y, Sum=0, Count = 0;
     52 
     53     if (availability & OMX_VC_UPPER)
     54     {
     55         for (x=0; x<4; x++)
     56         {
     57             Sum += pSrcAbove[x];
     58         }
     59         Count++;
     60     }
     61     else if (availability & OMX_VC_LEFT)
     62     {
     63         for (y=0; y<4; y++)
     64         {
     65             Sum += pSrcLeft[y*leftStep];
     66         }
     67         Count++;
     68     }
     69     if (Count==0)
     70     {
     71         Sum = 128;
     72     }
     73     else
     74     {
     75         Sum = (Sum + 2) >> 2;
     76     }
     77     for (y=0; y<4; y++)
     78     {
     79         for (x=0; x<4; x++)
     80         {
     81             pDst[y*dstStep+x] = (OMX_U8)Sum;
     82         }
     83     }
     84 }
     85 
     86 /*
     87  * Description:
     88  * Perform DC style intra prediction, left block has priority
     89  *
     90  * Parameters:
     91  * [in]	pSrcLeft		Pointer to the buffer of 16 left coefficients:
     92  *								p[x, y] (x = -1, y = 0..3)
     93  * [in]	pSrcAbove		Pointer to the buffer of 16 above coefficients:
     94  *								p[x,y] (x = 0..3, y = -1)
     95  * [in]	leftStep		Step of left coefficient buffer
     96  * [in]	dstStep			Step of the destination buffer
     97  * [in]	availability	Neighboring 16x16 MB availability flag
     98  * [out]	pDst			Pointer to the destination buffer
     99  *
    100  * Return Value:
    101  * None
    102  */
    103 
    104 static void armVCM4P10_PredictIntraDCLeft4x4(
    105      const OMX_U8* pSrcLeft,
    106      const OMX_U8 *pSrcAbove,
    107      OMX_U8* pDst,
    108      OMX_INT leftStep,
    109      OMX_INT dstStep,
    110      OMX_S32 availability
    111 )
    112 {
    113     int x, y, Sum=0, Count = 0;
    114 
    115     if (availability & OMX_VC_LEFT)
    116     {
    117         for (y=0; y<4; y++)
    118         {
    119             Sum += pSrcLeft[y*leftStep];
    120         }
    121         Count++;
    122     }
    123     else if (availability & OMX_VC_UPPER)
    124     {
    125         for (x=0; x<4; x++)
    126         {
    127             Sum += pSrcAbove[x];
    128         }
    129         Count++;
    130     }
    131     if (Count==0)
    132     {
    133         Sum = 128;
    134     }
    135     else
    136     {
    137         Sum = (Sum + 2) >> 2;
    138     }
    139     for (y=0; y<4; y++)
    140     {
    141         for (x=0; x<4; x++)
    142         {
    143             pDst[y*dstStep+x] = (OMX_U8)Sum;
    144         }
    145     }
    146 }
    147 
    148 /**
    149  * Function:  omxVCM4P10_PredictIntraChroma_8x8   (6.3.3.1.3)
    150  *
    151  * Description:
    152  * Performs intra prediction for chroma samples.
    153  *
    154  * Input Arguments:
    155  *
    156  *   pSrcLeft - Pointer to the buffer of 8 left pixels: p[x, y] (x = -1, y=
    157  *            0..7).
    158  *   pSrcAbove - Pointer to the buffer of 8 above pixels: p[x,y] (x = 0..7, y
    159  *            = -1); must be aligned on an 8-byte boundary.
    160  *   pSrcAboveLeft - Pointer to the above left pixels: p[x,y] (x = -1, y = -1)
    161  *   leftStep - Step of left pixel buffer; must be a multiple of 8.
    162  *   dstStep - Step of the destination buffer; must be a multiple of 8.
    163  *   predMode - Intra chroma prediction mode, please refer to section 3.4.3.
    164  *   availability - Neighboring chroma block availability flag, please refer
    165  *            to  "Neighboring Macroblock Availability".
    166  *
    167  * Output Arguments:
    168  *
    169  *   pDst - Pointer to the destination buffer; must be aligned on an 8-byte
    170  *            boundary.
    171  *
    172  * Return Value:
    173  *    If the function runs without error, it returns OMX_Sts_NoErr.
    174  *    If any of the following cases occurs, the function returns
    175  *              OMX_Sts_BadArgErr:
    176  *    pDst is NULL.
    177  *    dstStep < 8 or dstStep is not a multiple of 8.
    178  *    leftStep is not a multiple of 8.
    179  *    predMode is not in the valid range of enumeration
    180  *              OMXVCM4P10IntraChromaPredMode.
    181  *    predMode is OMX_VC_CHROMA_VERT, but availability doesn't set
    182  *              OMX_VC_UPPER indicating p[x,-1] (x = 0..7) is not available.
    183  *    predMode is OMX_VC_CHROMA_HOR, but availability doesn't set OMX_VC_LEFT
    184  *              indicating p[-1,y] (y = 0..7) is not available.
    185  *    predMode is OMX_VC_CHROMA_PLANE, but availability doesn't set
    186  *              OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating
    187  *              p[x,-1](x = 0..7), or p[-1,y] (y = 0..7), or p[-1,-1] is not
    188  *              available.
    189  *    availability sets OMX_VC_UPPER, but pSrcAbove is NULL.
    190  *    availability sets OMX_VC_LEFT, but pSrcLeft is NULL.
    191  *    availability sets OMX_VC_UPPER_LEFT, but pSrcAboveLeft is NULL.
    192  *    either pSrcAbove or pDst is not aligned on a 8-byte boundary.  Note:
    193  *              pSrcAbove, pSrcAbove, pSrcAboveLeft may be invalid pointer if
    194  *              they are not used by intra prediction implied in predMode.
    195  *               Note: OMX_VC_UPPER_RIGHT is not used in intra chroma
    196  *              prediction.
    197  *
    198  */
    199 OMXResult omxVCM4P10_PredictIntraChroma_8x8(
    200      const OMX_U8* pSrcLeft,
    201      const OMX_U8 *pSrcAbove,
    202      const OMX_U8 *pSrcAboveLeft,
    203      OMX_U8* pDst,
    204      OMX_INT leftStep,
    205      OMX_INT dstStep,
    206      OMXVCM4P10IntraChromaPredMode predMode,
    207      OMX_S32 availability
    208  )
    209 {
    210     int x, y, Sum;
    211     int H, V, a, b, c;
    212 
    213     armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr);
    214     armRetArgErrIf(dstStep < 8,  OMX_Sts_BadArgErr);
    215     armRetArgErrIf((dstStep % 8) != 0,  OMX_Sts_BadArgErr);
    216     armRetArgErrIf((leftStep % 8) != 0,  OMX_Sts_BadArgErr);
    217     armRetArgErrIf(armNot8ByteAligned(pSrcAbove), OMX_Sts_BadArgErr);
    218     armRetArgErrIf(armNot8ByteAligned(pDst), OMX_Sts_BadArgErr);
    219     armRetArgErrIf((availability & OMX_VC_UPPER)      && pSrcAbove     == NULL, OMX_Sts_BadArgErr);
    220     armRetArgErrIf((availability & OMX_VC_LEFT )      && pSrcLeft      == NULL, OMX_Sts_BadArgErr);
    221     armRetArgErrIf((availability & OMX_VC_UPPER_LEFT) && pSrcAboveLeft == NULL, OMX_Sts_BadArgErr);
    222     armRetArgErrIf(predMode==OMX_VC_CHROMA_VERT  && !(availability & OMX_VC_UPPER),      OMX_Sts_BadArgErr);
    223     armRetArgErrIf(predMode==OMX_VC_CHROMA_HOR   && !(availability & OMX_VC_LEFT),       OMX_Sts_BadArgErr);
    224     armRetArgErrIf(predMode==OMX_VC_CHROMA_PLANE && !(availability & OMX_VC_UPPER),      OMX_Sts_BadArgErr);
    225     armRetArgErrIf(predMode==OMX_VC_CHROMA_PLANE && !(availability & OMX_VC_UPPER_LEFT), OMX_Sts_BadArgErr);
    226     armRetArgErrIf(predMode==OMX_VC_CHROMA_PLANE && !(availability & OMX_VC_LEFT),       OMX_Sts_BadArgErr);
    227     armRetArgErrIf((unsigned)predMode > OMX_VC_CHROMA_PLANE,   OMX_Sts_BadArgErr);
    228 
    229     switch (predMode)
    230     {
    231     case OMX_VC_CHROMA_DC:
    232         armVCM4P10_PredictIntraDC4x4(       pSrcLeft,            pSrcAbove,   pDst,             leftStep, dstStep, availability);
    233         armVCM4P10_PredictIntraDCUp4x4(     pSrcLeft,            pSrcAbove+4, pDst+4,           leftStep, dstStep, availability);
    234         armVCM4P10_PredictIntraDCLeft4x4(   pSrcLeft+4*leftStep, pSrcAbove,   pDst+4*dstStep,   leftStep, dstStep, availability);
    235         armVCM4P10_PredictIntraDC4x4(       pSrcLeft+4*leftStep, pSrcAbove+4, pDst+4+4*dstStep, leftStep, dstStep, availability);
    236         break;
    237 
    238     case OMX_VC_CHROMA_HOR:
    239         for (y=0; y<8; y++)
    240         {
    241             for (x=0; x<8; x++)
    242             {
    243                 pDst[y*dstStep+x] = pSrcLeft[y*leftStep];
    244             }
    245         }
    246         break;
    247 
    248     case OMX_VC_CHROMA_VERT:
    249         for (y=0; y<8; y++)
    250         {
    251             for (x=0; x<8; x++)
    252             {
    253                 pDst[y*dstStep+x] = pSrcAbove[x];
    254             }
    255         }
    256         break;
    257 
    258     case OMX_VC_CHROMA_PLANE:
    259         H = 4*(pSrcAbove[7] - pSrcAboveLeft[0]);
    260         for (x=2; x>=0; x--)
    261         {
    262             H += (x+1)*(pSrcAbove[4+x] - pSrcAbove[2-x]);
    263         }
    264         V = 4*(pSrcLeft[7*leftStep] - pSrcAboveLeft[0]);
    265         for (y=2; y>=0; y--)
    266         {
    267             V += (y+1)*(pSrcLeft[(4+y)*leftStep] - pSrcLeft[(2-y)*leftStep]);
    268         }
    269         a = 16*(pSrcAbove[7] + pSrcLeft[7*leftStep]);
    270         b = (17*H+16)>>5;
    271         c = (17*V+16)>>5;
    272         for (y=0; y<8; y++)
    273         {
    274             for (x=0; x<8; x++)
    275             {
    276                 Sum = (a + b*(x-3) + c*(y-3) + 16)>>5;
    277                 pDst[y*dstStep+x] = (OMX_U8)armClip(0,255,Sum);
    278             }
    279         }
    280         break;
    281     }
    282 
    283     return OMX_Sts_NoErr;
    284 }
    285