omxVCM4P10_PredictIntraChroma_8x8.c revision 0c1bc742181ded4930842b46e9507372f0b1b963
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
42static 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
104static 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 */
199OMXResult 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