Home | History | Annotate | Download | only in src
      1 /* ----------------------------------------------------------------
      2  *
      3  *
      4  * File Name:  omxVCM4P10_PredictIntra_16x16.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 16x16 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  * Function:  omxVCM4P10_PredictIntra_16x16   (6.3.3.1.2)
     26  *
     27  * Description:
     28  * Perform Intra_16x16 prediction for luma samples. If the upper-right block
     29  * is not available, then duplication work should be handled inside the
     30  * function. Users need not define them outside.
     31  *
     32  * Input Arguments:
     33  *
     34  *   pSrcLeft - Pointer to the buffer of 16 left pixels: p[x, y] (x = -1, y =
     35  *            0..15)
     36  *   pSrcAbove - Pointer to the buffer of 16 above pixels: p[x,y] (x = 0..15,
     37  *            y= -1); must be aligned on a 16-byte boundary.
     38  *   pSrcAboveLeft - Pointer to the above left pixels: p[x,y] (x = -1, y = -1)
     39  *   leftStep - Step of left pixel buffer; must be a multiple of 16.
     40  *   dstStep - Step of the destination buffer; must be a multiple of 16.
     41  *   predMode - Intra_16x16 prediction mode, please refer to section 3.4.1.
     42  *   availability - Neighboring 16x16 MB availability flag. Refer to
     43  *                  section 3.4.4.
     44  *
     45  * Output Arguments:
     46  *
     47  *   pDst -Pointer to the destination buffer; must be aligned on a 16-byte
     48  *            boundary.
     49  *
     50  * Return Value:
     51  *    If the function runs without error, it returns OMX_Sts_NoErr.
     52  *    If one of the following cases occurs, the function returns
     53  *              OMX_Sts_BadArgErr:
     54  *    pDst is NULL.
     55  *    dstStep < 16. or dstStep is not a multiple of 16.
     56  *    leftStep is not a multiple of 16.
     57  *    predMode is not in the valid range of enumeration
     58  *              OMXVCM4P10Intra16x16PredMode
     59  *    predMode is OMX_VC_16X16_VERT, but availability doesn't set
     60  *              OMX_VC_UPPER indicating p[x,-1] (x = 0..15) is not available.
     61  *    predMode is OMX_VC_16X16_HOR, but availability doesn't set OMX_VC_LEFT
     62  *              indicating p[-1,y] (y = 0..15) is not available.
     63  *    predMode is OMX_VC_16X16_PLANE, but availability doesn't set
     64  *              OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating
     65  *              p[x,-1](x = 0..15), or p[-1,y] (y = 0..15), or p[-1,-1] is not
     66  *              available.
     67  *    availability sets OMX_VC_UPPER, but pSrcAbove is NULL.
     68  *    availability sets OMX_VC_LEFT, but pSrcLeft is NULL.
     69  *    availability sets OMX_VC_UPPER_LEFT, but pSrcAboveLeft is NULL.
     70  *    either pSrcAbove or pDst is not aligned on a 16-byte boundary.
     71  *
     72  * Note:
     73  *     pSrcAbove, pSrcAbove, pSrcAboveLeft may be invalid pointers if
     74  *     they are not used by intra prediction implied in predMode.
     75  * Note:
     76  *     OMX_VC_UPPER_RIGHT is not used in intra_16x16 luma prediction.
     77  *
     78  */
     79 OMXResult omxVCM4P10_PredictIntra_16x16(
     80     const OMX_U8* pSrcLeft,
     81     const OMX_U8 *pSrcAbove,
     82     const OMX_U8 *pSrcAboveLeft,
     83     OMX_U8* pDst,
     84     OMX_INT leftStep,
     85     OMX_INT dstStep,
     86     OMXVCM4P10Intra16x16PredMode predMode,
     87     OMX_S32 availability)
     88 {
     89     int x,y,Sum,Count;
     90     int H,V,a,b,c;
     91 
     92     armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr);
     93     armRetArgErrIf(dstStep < 16,  OMX_Sts_BadArgErr);
     94     armRetArgErrIf((dstStep % 16) != 0,  OMX_Sts_BadArgErr);
     95     armRetArgErrIf((leftStep % 16) != 0,  OMX_Sts_BadArgErr);
     96     armRetArgErrIf(armNot16ByteAligned(pSrcAbove), OMX_Sts_BadArgErr);
     97     armRetArgErrIf(armNot16ByteAligned(pDst), OMX_Sts_BadArgErr);
     98     armRetArgErrIf((availability & OMX_VC_UPPER)      && pSrcAbove     == NULL, OMX_Sts_BadArgErr);
     99     armRetArgErrIf((availability & OMX_VC_LEFT )      && pSrcLeft      == NULL, OMX_Sts_BadArgErr);
    100     armRetArgErrIf((availability & OMX_VC_UPPER_LEFT) && pSrcAboveLeft == NULL, OMX_Sts_BadArgErr);
    101     armRetArgErrIf(predMode==OMX_VC_16X16_VERT  && !(availability & OMX_VC_UPPER),      OMX_Sts_BadArgErr);
    102     armRetArgErrIf(predMode==OMX_VC_16X16_HOR   && !(availability & OMX_VC_LEFT),       OMX_Sts_BadArgErr);
    103     armRetArgErrIf(predMode==OMX_VC_16X16_PLANE && !(availability & OMX_VC_UPPER),      OMX_Sts_BadArgErr);
    104     armRetArgErrIf(predMode==OMX_VC_16X16_PLANE && !(availability & OMX_VC_UPPER_LEFT), OMX_Sts_BadArgErr);
    105     armRetArgErrIf(predMode==OMX_VC_16X16_PLANE && !(availability & OMX_VC_LEFT),       OMX_Sts_BadArgErr);
    106     armRetArgErrIf((unsigned)predMode > OMX_VC_16X16_PLANE,  OMX_Sts_BadArgErr);
    107 
    108     switch (predMode)
    109     {
    110     case OMX_VC_16X16_VERT:
    111         for (y=0; y<16; y++)
    112         {
    113             for (x=0; x<16; x++)
    114             {
    115                 pDst[y*dstStep+x] = pSrcAbove[x];
    116             }
    117         }
    118         break;
    119 
    120     case OMX_VC_16X16_HOR:
    121         for (y=0; y<16; y++)
    122         {
    123             for (x=0; x<16; x++)
    124             {
    125                 pDst[y*dstStep+x] = pSrcLeft[y*leftStep];
    126             }
    127         }
    128         break;
    129 
    130     case OMX_VC_16X16_DC:
    131         /* This can always be used even if no blocks available */
    132         Sum = 0;
    133         Count = 0;
    134         if (availability & OMX_VC_LEFT)
    135         {
    136             for (y=0; y<16; y++)
    137             {
    138                 Sum += pSrcLeft[y*leftStep];
    139             }
    140             Count++;
    141         }
    142         if (availability & OMX_VC_UPPER)
    143         {
    144             for (x=0; x<16; x++)
    145             {
    146                 Sum += pSrcAbove[x];
    147             }
    148             Count++;
    149         }
    150         if (Count==0)
    151         {
    152             Sum = 128;
    153         }
    154         else if (Count==1)
    155         {
    156             Sum = (Sum + 8) >> 4;
    157         }
    158         else /* Count = 2 */
    159         {
    160             Sum = (Sum + 16) >> 5;
    161         }
    162         for (y=0; y<16; y++)
    163         {
    164             for (x=0; x<16; x++)
    165             {
    166                 pDst[y*dstStep+x] = (OMX_U8)Sum;
    167             }
    168         }
    169         break;
    170 
    171     case OMX_VC_16X16_PLANE:
    172         H = 8*(pSrcAbove[15] - pSrcAboveLeft[0]);
    173         for (x=6; x>=0; x--)
    174         {
    175             H += (x+1)*(pSrcAbove[8+x] - pSrcAbove[6-x]);
    176         }
    177         V = 8*(pSrcLeft[15*leftStep] - pSrcAboveLeft[0]);
    178         for (y=6; y>=0; y--)
    179         {
    180             V += (y+1)*(pSrcLeft[(8+y)*leftStep] - pSrcLeft[(6-y)*leftStep]);
    181         }
    182         a = 16*(pSrcAbove[15] + pSrcLeft[15*leftStep]);
    183         b = (5*H+32)>>6;
    184         c = (5*V+32)>>6;
    185         for (y=0; y<16; y++)
    186         {
    187             for (x=0; x<16; x++)
    188             {
    189                 Sum = (a + b*(x-7) + c*(y-7) + 16)>>5;
    190                 pDst[y*dstStep+x] = (OMX_U8)armClip(0,255,Sum);
    191             }
    192         }
    193         break;
    194     }
    195 
    196     return OMX_Sts_NoErr;
    197 }
    198 
    199