omxVCM4P10_PredictIntra_16x16.c revision 0c1bc742181ded4930842b46e9507372f0b1b963
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 */
79OMXResult 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