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