h264bsd_intra_prediction.c revision 0c1bc742181ded4930842b46e9507372f0b1b963
1/*
2 * Copyright (C) 2009 The Android Open Source Project
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    Table of contents
20
21     1. Include headers
22     2. External compiler flags
23     3. Module defines
24     4. Local function prototypes
25     5. Functions
26          h264bsdIntraPrediction
27          h264bsdGetNeighbourPels
28          h264bsdIntra16x16Prediction
29          h264bsdIntra4x4Prediction
30          h264bsdIntraChromaPrediction
31          h264bsdAddResidual
32          Intra16x16VerticalPrediction
33          Intra16x16HorizontalPrediction
34          Intra16x16DcPrediction
35          Intra16x16PlanePrediction
36          IntraChromaDcPrediction
37          IntraChromaHorizontalPrediction
38          IntraChromaVerticalPrediction
39          IntraChromaPlanePrediction
40          Get4x4NeighbourPels
41          Write4x4To16x16
42          Intra4x4VerticalPrediction
43          Intra4x4HorizontalPrediction
44          Intra4x4DcPrediction
45          Intra4x4DiagonalDownLeftPrediction
46          Intra4x4DiagonalDownRightPrediction
47          Intra4x4VerticalRightPrediction
48          Intra4x4HorizontalDownPrediction
49          Intra4x4VerticalLeftPrediction
50          Intra4x4HorizontalUpPrediction
51          DetermineIntra4x4PredMode
52
53------------------------------------------------------------------------------*/
54
55/*------------------------------------------------------------------------------
56    1. Include headers
57------------------------------------------------------------------------------*/
58
59#include "h264bsd_intra_prediction.h"
60#include "h264bsd_util.h"
61#include "h264bsd_macroblock_layer.h"
62#include "h264bsd_neighbour.h"
63#include "h264bsd_image.h"
64
65#ifdef H264DEC_OMXDL
66#include "omxtypes.h"
67#include "omxVC.h"
68#endif /* H264DEC_OMXDL */
69
70/*------------------------------------------------------------------------------
71    2. External compiler flags
72--------------------------------------------------------------------------------
73
74--------------------------------------------------------------------------------
75    3. Module defines
76------------------------------------------------------------------------------*/
77
78/* Switch off the following Lint messages for this file:
79 * Info 702: Shift right of signed quantity (int)
80 */
81/*lint -e702 */
82
83
84/* x- and y-coordinates for each block */
85const u32 h264bsdBlockX[16] =
86    { 0, 4, 0, 4, 8, 12, 8, 12, 0, 4, 0, 4, 8, 12, 8, 12 };
87const u32 h264bsdBlockY[16] =
88    { 0, 0, 4, 4, 0, 0, 4, 4, 8, 8, 12, 12, 8, 8, 12, 12 };
89
90const u8 h264bsdClip[1280] =
91{
92    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
93    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
94    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
95    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
96    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
97    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
98    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
99    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
100    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
101    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
102    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
103    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
104    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
105    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
106    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
107    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
108    0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
109    16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
110    32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
111    48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
112    64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
113    80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
114    96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
115    112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
116    128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
117    144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
118    160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
119    176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
120    192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
121    208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
122    224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
123    240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
124    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
125    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
126    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
127    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
128    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
129    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
130    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
131    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
132    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
133    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
134    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
135    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
136    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
137    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
138    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
139    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
140    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
141    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
142    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
143    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
144    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
145    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
146    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
147    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
148    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
149    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
150    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
151    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
152    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
153    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
154    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
155    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
156};
157
158#ifndef H264DEC_OMXDL
159/*------------------------------------------------------------------------------
160    4. Local function prototypes
161------------------------------------------------------------------------------*/
162static void Get4x4NeighbourPels(u8 *a, u8 *l, u8 *data, u8 *above, u8 *left,
163    u32 blockNum);
164static void Intra16x16VerticalPrediction(u8 *data, u8 *above);
165static void Intra16x16HorizontalPrediction(u8 *data, u8 *left);
166static void Intra16x16DcPrediction(u8 *data, u8 *above, u8 *left,
167    u32 A, u32 B);
168static void Intra16x16PlanePrediction(u8 *data, u8 *above, u8 *left);
169static void IntraChromaDcPrediction(u8 *data, u8 *above, u8 *left,
170    u32 A, u32 B);
171static void IntraChromaHorizontalPrediction(u8 *data, u8 *left);
172static void IntraChromaVerticalPrediction(u8 *data, u8 *above);
173static void IntraChromaPlanePrediction(u8 *data, u8 *above, u8 *left);
174
175static void Intra4x4VerticalPrediction(u8 *data, u8 *above);
176static void Intra4x4HorizontalPrediction(u8 *data, u8 *left);
177static void Intra4x4DcPrediction(u8 *data, u8 *above, u8 *left, u32 A, u32 B);
178static void Intra4x4DiagonalDownLeftPrediction(u8 *data, u8 *above);
179static void Intra4x4DiagonalDownRightPrediction(u8 *data, u8 *above, u8 *left);
180static void Intra4x4VerticalRightPrediction(u8 *data, u8 *above, u8 *left);
181static void Intra4x4HorizontalDownPrediction(u8 *data, u8 *above, u8 *left);
182static void Intra4x4VerticalLeftPrediction(u8 *data, u8 *above);
183static void Intra4x4HorizontalUpPrediction(u8 *data, u8 *left);
184void h264bsdAddResidual(u8 *data, i32 *residual, u32 blockNum);
185
186static void Write4x4To16x16(u8 *data, u8 *data4x4, u32 blockNum);
187#endif /* H264DEC_OMXDL */
188
189static u32 DetermineIntra4x4PredMode(macroblockLayer_t *pMbLayer,
190    u32 available, neighbour_t *nA, neighbour_t *nB, u32 index,
191    mbStorage_t *nMbA, mbStorage_t *nMbB);
192
193
194#ifdef H264DEC_OMXDL
195
196/*------------------------------------------------------------------------------
197
198    Function: h264bsdIntra16x16Prediction
199
200        Functional description:
201          Perform intra 16x16 prediction mode for luma pixels and add
202          residual into prediction. The resulting luma pixels are
203          stored in macroblock array 'data'.
204
205------------------------------------------------------------------------------*/
206u32 h264bsdIntra16x16Prediction(mbStorage_t *pMb, u8 *data, u8 *ptr,
207                                u32 width, u32 constrainedIntraPred)
208{
209
210/* Variables */
211
212    u32 availableA, availableB, availableD;
213    OMXResult omxRes;
214
215/* Code */
216    ASSERT(pMb);
217    ASSERT(data);
218    ASSERT(ptr);
219    ASSERT(h264bsdPredModeIntra16x16(pMb->mbType) < 4);
220
221    availableA = h264bsdIsNeighbourAvailable(pMb, pMb->mbA);
222    if (availableA && constrainedIntraPred &&
223       (h264bsdMbPartPredMode(pMb->mbA->mbType) == PRED_MODE_INTER))
224        availableA = HANTRO_FALSE;
225    availableB = h264bsdIsNeighbourAvailable(pMb, pMb->mbB);
226    if (availableB && constrainedIntraPred &&
227       (h264bsdMbPartPredMode(pMb->mbB->mbType) == PRED_MODE_INTER))
228        availableB = HANTRO_FALSE;
229    availableD = h264bsdIsNeighbourAvailable(pMb, pMb->mbD);
230    if (availableD && constrainedIntraPred &&
231       (h264bsdMbPartPredMode(pMb->mbD->mbType) == PRED_MODE_INTER))
232        availableD = HANTRO_FALSE;
233
234    omxRes = omxVCM4P10_PredictIntra_16x16( (ptr-1),
235                                    (ptr - width),
236                                    (ptr - width-1),
237                                    data,
238                                    (i32)width,
239                                    16,
240                                    (OMXVCM4P10Intra16x16PredMode)
241                                    h264bsdPredModeIntra16x16(pMb->mbType),
242                                    (i32)(availableB + (availableA<<1) +
243                                     (availableD<<5)) );
244    if (omxRes != OMX_Sts_NoErr)
245        return HANTRO_NOK;
246    else
247        return(HANTRO_OK);
248}
249
250/*------------------------------------------------------------------------------
251
252    Function: h264bsdIntra4x4Prediction
253
254        Functional description:
255          Perform intra 4x4 prediction for luma pixels and add residual
256          into prediction. The resulting luma pixels are stored in
257          macroblock array 'data'. The intra 4x4 prediction mode for each
258          block is stored in 'pMb' structure.
259
260------------------------------------------------------------------------------*/
261u32 h264bsdIntra4x4Prediction(mbStorage_t *pMb, u8 *data,
262                              macroblockLayer_t *mbLayer,
263                              u8 *ptr, u32 width,
264                              u32 constrainedIntraPred, u32 block)
265{
266
267/* Variables */
268    u32 mode;
269    neighbour_t neighbour, neighbourB;
270    mbStorage_t *nMb, *nMb2;
271    u32 availableA, availableB, availableC, availableD;
272
273    OMXResult omxRes;
274    u32 x, y;
275    u8 *l, *a, *al;
276/* Code */
277    ASSERT(pMb);
278    ASSERT(data);
279    ASSERT(mbLayer);
280    ASSERT(ptr);
281    ASSERT(pMb->intra4x4PredMode[block] < 9);
282
283    neighbour = *h264bsdNeighbour4x4BlockA(block);
284    nMb = h264bsdGetNeighbourMb(pMb, neighbour.mb);
285    availableA = h264bsdIsNeighbourAvailable(pMb, nMb);
286    if (availableA && constrainedIntraPred &&
287       ( h264bsdMbPartPredMode(nMb->mbType) == PRED_MODE_INTER) )
288    {
289        availableA = HANTRO_FALSE;
290    }
291
292    neighbourB = *h264bsdNeighbour4x4BlockB(block);
293    nMb2 = h264bsdGetNeighbourMb(pMb, neighbourB.mb);
294    availableB = h264bsdIsNeighbourAvailable(pMb, nMb2);
295    if (availableB && constrainedIntraPred &&
296       ( h264bsdMbPartPredMode(nMb2->mbType) == PRED_MODE_INTER) )
297    {
298        availableB = HANTRO_FALSE;
299    }
300
301    mode = DetermineIntra4x4PredMode(mbLayer,
302        (u32)(availableA && availableB),
303        &neighbour, &neighbourB, block, nMb, nMb2);
304    pMb->intra4x4PredMode[block] = (u8)mode;
305
306    neighbour = *h264bsdNeighbour4x4BlockC(block);
307    nMb = h264bsdGetNeighbourMb(pMb, neighbour.mb);
308    availableC = h264bsdIsNeighbourAvailable(pMb, nMb);
309    if (availableC && constrainedIntraPred &&
310       ( h264bsdMbPartPredMode(nMb->mbType) == PRED_MODE_INTER) )
311    {
312        availableC = HANTRO_FALSE;
313    }
314
315    neighbour = *h264bsdNeighbour4x4BlockD(block);
316    nMb = h264bsdGetNeighbourMb(pMb, neighbour.mb);
317    availableD = h264bsdIsNeighbourAvailable(pMb, nMb);
318    if (availableD && constrainedIntraPred &&
319       ( h264bsdMbPartPredMode(nMb->mbType) == PRED_MODE_INTER) )
320    {
321        availableD = HANTRO_FALSE;
322    }
323
324    x = h264bsdBlockX[block];
325    y = h264bsdBlockY[block];
326
327    if (y == 0)
328        a = ptr - width + x;
329    else
330        a = data-16;
331
332    if (x == 0)
333        l = ptr + y * width -1;
334    else
335    {
336        l = data-1;
337        width = 16;
338    }
339
340    if (x == 0)
341        al = l-width;
342    else
343        al = a-1;
344
345    omxRes = omxVCM4P10_PredictIntra_4x4( l,
346                                          a,
347                                          al,
348                                          data,
349                                          (i32)width,
350                                          16,
351                                          (OMXVCM4P10Intra4x4PredMode)mode,
352                                          (i32)(availableB +
353                                          (availableA<<1) +
354                                          (availableD<<5) +
355                                          (availableC<<6)) );
356    if (omxRes != OMX_Sts_NoErr)
357        return HANTRO_NOK;
358
359    return(HANTRO_OK);
360
361}
362
363/*------------------------------------------------------------------------------
364
365    Function: h264bsdIntraChromaPrediction
366
367        Functional description:
368          Perform intra prediction for chroma pixels and add residual
369          into prediction. The resulting chroma pixels are stored in 'data'.
370
371------------------------------------------------------------------------------*/
372u32 h264bsdIntraChromaPrediction(mbStorage_t *pMb, u8 *data, image_t *image,
373                                        u32 predMode, u32 constrainedIntraPred)
374{
375
376/* Variables */
377
378    u32 availableA, availableB, availableD;
379    OMXResult omxRes;
380    u8 *ptr;
381    u32 width;
382
383/* Code */
384    ASSERT(pMb);
385    ASSERT(data);
386    ASSERT(image);
387    ASSERT(predMode < 4);
388
389    availableA = h264bsdIsNeighbourAvailable(pMb, pMb->mbA);
390    if (availableA && constrainedIntraPred &&
391       (h264bsdMbPartPredMode(pMb->mbA->mbType) == PRED_MODE_INTER))
392        availableA = HANTRO_FALSE;
393    availableB = h264bsdIsNeighbourAvailable(pMb, pMb->mbB);
394    if (availableB && constrainedIntraPred &&
395       (h264bsdMbPartPredMode(pMb->mbB->mbType) == PRED_MODE_INTER))
396        availableB = HANTRO_FALSE;
397    availableD = h264bsdIsNeighbourAvailable(pMb, pMb->mbD);
398    if (availableD && constrainedIntraPred &&
399       (h264bsdMbPartPredMode(pMb->mbD->mbType) == PRED_MODE_INTER))
400        availableD = HANTRO_FALSE;
401
402    ptr = image->cb;
403    width = image->width*8;
404
405    omxRes = omxVCM4P10_PredictIntraChroma_8x8( (ptr-1),
406                                                (ptr - width),
407                                                (ptr - width -1),
408                                                data,
409                                                (i32)width,
410                                                8,
411                                                (OMXVCM4P10IntraChromaPredMode)
412                                                predMode,
413                                                (i32)(availableB +
414                                                 (availableA<<1) +
415                                                 (availableD<<5)) );
416    if (omxRes != OMX_Sts_NoErr)
417        return HANTRO_NOK;
418
419    /* advance pointers */
420    data += 64;
421    ptr = image->cr;
422
423    omxRes = omxVCM4P10_PredictIntraChroma_8x8( (ptr-1),
424                                                (ptr - width),
425                                                (ptr - width -1),
426                                                data,
427                                                (i32)width,
428                                                8,
429                                                (OMXVCM4P10IntraChromaPredMode)
430                                                predMode,
431                                                (i32)(availableB +
432                                                 (availableA<<1) +
433                                                 (availableD<<5)) );
434    if (omxRes != OMX_Sts_NoErr)
435        return HANTRO_NOK;
436
437    return(HANTRO_OK);
438
439}
440
441
442#else /* H264DEC_OMXDL */
443
444
445/*------------------------------------------------------------------------------
446
447    Function: h264bsdIntraPrediction
448
449        Functional description:
450          Processes one intra macroblock. Performs intra prediction using
451          specified prediction mode. Writes the final macroblock
452          (prediction + residual) into the output image (image)
453
454        Inputs:
455          pMb           pointer to macroblock specific information
456          mbLayer       pointer to current macroblock data from stream
457          image         pointer to output image
458          mbNum         current macroblock number
459          constrainedIntraPred  flag specifying if neighbouring inter
460                                macroblocks are used in intra prediction
461          data          pointer where output macroblock will be stored
462
463        Outputs:
464          pMb           structure is updated with current macroblock
465          image         current macroblock is written into image
466          data          current macroblock is stored here
467
468        Returns:
469          HANTRO_OK     success
470          HANTRO_NOK    error in intra prediction
471
472------------------------------------------------------------------------------*/
473u32 h264bsdIntraPrediction(mbStorage_t *pMb, macroblockLayer_t *mbLayer,
474    image_t *image, u32 mbNum, u32 constrainedIntraPred, u8 *data)
475{
476
477/* Variables */
478
479    /* pelAbove and pelLeft contain samples above and left to the current
480     * macroblock. Above array contains also sample above-left to the current
481     * mb as well as 4 samples above-right to the current mb (latter only for
482     * luma) */
483    /* lumD + lumB + lumC + cbD + cbB + crD + crB */
484    u8 pelAbove[1 + 16 + 4 + 1 + 8 + 1 + 8];
485    /* lumA + cbA + crA */
486    u8 pelLeft[16 + 8 + 8];
487    u32 tmp;
488
489/* Code */
490
491    ASSERT(pMb);
492    ASSERT(image);
493    ASSERT(mbNum < image->width * image->height);
494    ASSERT(h264bsdMbPartPredMode(pMb->mbType) != PRED_MODE_INTER);
495
496    h264bsdGetNeighbourPels(image, pelAbove, pelLeft, mbNum);
497
498    if (h264bsdMbPartPredMode(pMb->mbType) == PRED_MODE_INTRA16x16)
499    {
500        tmp = h264bsdIntra16x16Prediction(pMb, data, mbLayer->residual.level,
501            pelAbove, pelLeft, constrainedIntraPred);
502        if (tmp != HANTRO_OK)
503            return(tmp);
504    }
505    else
506    {
507        tmp = h264bsdIntra4x4Prediction(pMb, data, mbLayer,
508            pelAbove, pelLeft, constrainedIntraPred);
509        if (tmp != HANTRO_OK)
510            return(tmp);
511    }
512
513    tmp = h264bsdIntraChromaPrediction(pMb, data + 256,
514            mbLayer->residual.level+16, pelAbove + 21, pelLeft + 16,
515            mbLayer->mbPred.intraChromaPredMode, constrainedIntraPred);
516    if (tmp != HANTRO_OK)
517        return(tmp);
518
519    /* if decoded flag > 1 -> mb has already been successfully decoded and
520     * written to output -> do not write again */
521    if (pMb->decoded > 1)
522        return HANTRO_OK;
523
524    h264bsdWriteMacroblock(image, data);
525
526    return(HANTRO_OK);
527
528}
529
530/*------------------------------------------------------------------------------
531
532    Function: h264bsdGetNeighbourPels
533
534        Functional description:
535          Get pixel values from neighbouring macroblocks into 'above'
536          and 'left' arrays.
537
538------------------------------------------------------------------------------*/
539
540void h264bsdGetNeighbourPels(image_t *image, u8 *above, u8 *left, u32 mbNum)
541{
542
543/* Variables */
544
545    u32 i;
546    u32 width, picSize;
547    u8 *ptr, *tmp;
548    u32 row, col;
549
550/* Code */
551
552    ASSERT(image);
553    ASSERT(above);
554    ASSERT(left);
555    ASSERT(mbNum < image->width * image->height);
556
557    if (!mbNum)
558        return;
559
560    width = image->width;
561    picSize = width * image->height;
562    row = mbNum / width;
563    col = mbNum - row * width;
564
565    width *= 16;
566    ptr = image->data + row * 16 * width  + col * 16;
567
568    /* note that luma samples above-right to current macroblock do not make
569     * sense when current mb is the right-most mb in a row. Same applies to
570     * sample above-left if col is zero. However, usage of pels in prediction
571     * is controlled by neighbour availability information in actual prediction
572     * process */
573    if (row)
574    {
575        tmp = ptr - (width + 1);
576        for (i = 21; i--;)
577            *above++ = *tmp++;
578    }
579
580    if (col)
581    {
582        ptr--;
583        for (i = 16; i--; ptr+=width)
584            *left++ = *ptr;
585    }
586
587    width >>= 1;
588    ptr = image->data + picSize * 256 + row * 8 * width  + col * 8;
589
590    if (row)
591    {
592        tmp = ptr - (width + 1);
593        for (i = 9; i--;)
594            *above++ = *tmp++;
595        tmp += (picSize * 64) - 9;
596        for (i = 9; i--;)
597            *above++ = *tmp++;
598    }
599
600    if (col)
601    {
602        ptr--;
603        for (i = 8; i--; ptr+=width)
604            *left++ = *ptr;
605        ptr += (picSize * 64) - 8 * width;
606        for (i = 8; i--; ptr+=width)
607            *left++ = *ptr;
608    }
609}
610
611/*------------------------------------------------------------------------------
612
613    Function: Intra16x16Prediction
614
615        Functional description:
616          Perform intra 16x16 prediction mode for luma pixels and add
617          residual into prediction. The resulting luma pixels are
618          stored in macroblock array 'data'.
619
620------------------------------------------------------------------------------*/
621
622u32 h264bsdIntra16x16Prediction(mbStorage_t *pMb, u8 *data, i32 residual[][16],
623                                u8 *above, u8 *left, u32 constrainedIntraPred)
624{
625
626/* Variables */
627
628    u32 i;
629    u32 availableA, availableB, availableD;
630
631/* Code */
632
633    ASSERT(data);
634    ASSERT(residual);
635    ASSERT(above);
636    ASSERT(left);
637    ASSERT(h264bsdPredModeIntra16x16(pMb->mbType) < 4);
638
639    availableA = h264bsdIsNeighbourAvailable(pMb, pMb->mbA);
640    if (availableA && constrainedIntraPred &&
641       (h264bsdMbPartPredMode(pMb->mbA->mbType) == PRED_MODE_INTER))
642        availableA = HANTRO_FALSE;
643    availableB = h264bsdIsNeighbourAvailable(pMb, pMb->mbB);
644    if (availableB && constrainedIntraPred &&
645       (h264bsdMbPartPredMode(pMb->mbB->mbType) == PRED_MODE_INTER))
646        availableB = HANTRO_FALSE;
647    availableD = h264bsdIsNeighbourAvailable(pMb, pMb->mbD);
648    if (availableD && constrainedIntraPred &&
649       (h264bsdMbPartPredMode(pMb->mbD->mbType) == PRED_MODE_INTER))
650        availableD = HANTRO_FALSE;
651
652    switch(h264bsdPredModeIntra16x16(pMb->mbType))
653    {
654        case 0: /* Intra_16x16_Vertical */
655            if (!availableB)
656                return(HANTRO_NOK);
657            Intra16x16VerticalPrediction(data, above+1);
658            break;
659
660        case 1: /* Intra_16x16_Horizontal */
661            if (!availableA)
662                return(HANTRO_NOK);
663            Intra16x16HorizontalPrediction(data, left);
664            break;
665
666        case 2: /* Intra_16x16_DC */
667            Intra16x16DcPrediction(data, above+1, left, availableA, availableB);
668            break;
669
670        default: /* case 3: Intra_16x16_Plane */
671            if (!availableA || !availableB || !availableD)
672                return(HANTRO_NOK);
673            Intra16x16PlanePrediction(data, above+1, left);
674            break;
675    }
676    /* add residual */
677    for (i = 0; i < 16; i++)
678        h264bsdAddResidual(data, residual[i], i);
679
680    return(HANTRO_OK);
681
682}
683
684/*------------------------------------------------------------------------------
685
686    Function: Intra4x4Prediction
687
688        Functional description:
689          Perform intra 4x4 prediction for luma pixels and add residual
690          into prediction. The resulting luma pixels are stored in
691          macroblock array 'data'. The intra 4x4 prediction mode for each
692          block is stored in 'pMb' structure.
693
694------------------------------------------------------------------------------*/
695
696u32 h264bsdIntra4x4Prediction(mbStorage_t *pMb, u8 *data,
697                              macroblockLayer_t *mbLayer, u8 *above,
698                              u8 *left, u32 constrainedIntraPred)
699{
700
701/* Variables */
702
703    u32 block;
704    u32 mode;
705    neighbour_t neighbour, neighbourB;
706    mbStorage_t *nMb, *nMb2;
707    u8 a[1 + 4 + 4], l[1 + 4];
708    u32 data4x4[4];
709    u32 availableA, availableB, availableC, availableD;
710
711/* Code */
712
713    ASSERT(data);
714    ASSERT(mbLayer);
715    ASSERT(above);
716    ASSERT(left);
717
718    for (block = 0; block < 16; block++)
719    {
720
721        ASSERT(pMb->intra4x4PredMode[block] < 9);
722
723        neighbour = *h264bsdNeighbour4x4BlockA(block);
724        nMb = h264bsdGetNeighbourMb(pMb, neighbour.mb);
725        availableA = h264bsdIsNeighbourAvailable(pMb, nMb);
726        if (availableA && constrainedIntraPred &&
727           ( h264bsdMbPartPredMode(nMb->mbType) == PRED_MODE_INTER) )
728        {
729            availableA = HANTRO_FALSE;
730        }
731
732        neighbourB = *h264bsdNeighbour4x4BlockB(block);
733        nMb2 = h264bsdGetNeighbourMb(pMb, neighbourB.mb);
734        availableB = h264bsdIsNeighbourAvailable(pMb, nMb2);
735        if (availableB && constrainedIntraPred &&
736           ( h264bsdMbPartPredMode(nMb2->mbType) == PRED_MODE_INTER) )
737        {
738            availableB = HANTRO_FALSE;
739        }
740
741        mode = DetermineIntra4x4PredMode(mbLayer,
742            (u32)(availableA && availableB),
743            &neighbour, &neighbourB, block, nMb, nMb2);
744        pMb->intra4x4PredMode[block] = (u8)mode;
745
746        neighbour = *h264bsdNeighbour4x4BlockC(block);
747        nMb = h264bsdGetNeighbourMb(pMb, neighbour.mb);
748        availableC = h264bsdIsNeighbourAvailable(pMb, nMb);
749        if (availableC && constrainedIntraPred &&
750           ( h264bsdMbPartPredMode(nMb->mbType) == PRED_MODE_INTER) )
751        {
752            availableC = HANTRO_FALSE;
753        }
754
755        neighbour = *h264bsdNeighbour4x4BlockD(block);
756        nMb = h264bsdGetNeighbourMb(pMb, neighbour.mb);
757        availableD = h264bsdIsNeighbourAvailable(pMb, nMb);
758        if (availableD && constrainedIntraPred &&
759           ( h264bsdMbPartPredMode(nMb->mbType) == PRED_MODE_INTER) )
760        {
761            availableD = HANTRO_FALSE;
762        }
763
764        Get4x4NeighbourPels(a, l, data, above, left, block);
765
766        switch(mode)
767        {
768            case 0: /* Intra_4x4_Vertical */
769                if (!availableB)
770                    return(HANTRO_NOK);
771                Intra4x4VerticalPrediction((u8*)data4x4, a + 1);
772                break;
773            case 1: /* Intra_4x4_Horizontal */
774                if (!availableA)
775                    return(HANTRO_NOK);
776                Intra4x4HorizontalPrediction((u8*)data4x4, l + 1);
777                break;
778            case 2: /* Intra_4x4_DC */
779                Intra4x4DcPrediction((u8*)data4x4, a + 1, l + 1,
780                    availableA, availableB);
781                break;
782            case 3: /* Intra_4x4_Diagonal_Down_Left */
783                if (!availableB)
784                    return(HANTRO_NOK);
785                if (!availableC)
786                {
787                    a[5] = a[6] = a[7] = a[8] = a[4];
788                }
789                Intra4x4DiagonalDownLeftPrediction((u8*)data4x4, a + 1);
790                break;
791            case 4: /* Intra_4x4_Diagonal_Down_Right */
792                if (!availableA || !availableB || !availableD)
793                    return(HANTRO_NOK);
794                Intra4x4DiagonalDownRightPrediction((u8*)data4x4, a + 1, l + 1);
795                break;
796            case 5: /* Intra_4x4_Vertical_Right */
797                if (!availableA || !availableB || !availableD)
798                    return(HANTRO_NOK);
799                Intra4x4VerticalRightPrediction((u8*)data4x4, a + 1, l + 1);
800                break;
801            case 6: /* Intra_4x4_Horizontal_Down */
802                if (!availableA || !availableB || !availableD)
803                    return(HANTRO_NOK);
804                Intra4x4HorizontalDownPrediction((u8*)data4x4, a + 1, l + 1);
805                break;
806            case 7: /* Intra_4x4_Vertical_Left */
807                if (!availableB)
808                    return(HANTRO_NOK);
809                if (!availableC)
810                {
811                    a[5] = a[6] = a[7] = a[8] = a[4];
812                }
813                Intra4x4VerticalLeftPrediction((u8*)data4x4, a + 1);
814                break;
815            default: /* case 8 Intra_4x4_Horizontal_Up */
816                if (!availableA)
817                    return(HANTRO_NOK);
818                Intra4x4HorizontalUpPrediction((u8*)data4x4, l + 1);
819                break;
820        }
821
822        Write4x4To16x16(data, (u8*)data4x4, block);
823        h264bsdAddResidual(data, mbLayer->residual.level[block], block);
824    }
825
826    return(HANTRO_OK);
827
828}
829
830/*------------------------------------------------------------------------------
831
832    Function: IntraChromaPrediction
833
834        Functional description:
835          Perform intra prediction for chroma pixels and add residual
836          into prediction. The resulting chroma pixels are stored in 'data'.
837
838------------------------------------------------------------------------------*/
839
840u32 h264bsdIntraChromaPrediction(mbStorage_t *pMb, u8 *data, i32 residual[][16],
841                    u8 *above, u8 *left, u32 predMode, u32 constrainedIntraPred)
842{
843
844/* Variables */
845
846    u32 i, comp, block;
847    u32 availableA, availableB, availableD;
848
849/* Code */
850
851    ASSERT(data);
852    ASSERT(residual);
853    ASSERT(above);
854    ASSERT(left);
855    ASSERT(predMode < 4);
856
857    availableA = h264bsdIsNeighbourAvailable(pMb, pMb->mbA);
858    if (availableA && constrainedIntraPred &&
859       (h264bsdMbPartPredMode(pMb->mbA->mbType) == PRED_MODE_INTER))
860        availableA = HANTRO_FALSE;
861    availableB = h264bsdIsNeighbourAvailable(pMb, pMb->mbB);
862    if (availableB && constrainedIntraPred &&
863       (h264bsdMbPartPredMode(pMb->mbB->mbType) == PRED_MODE_INTER))
864        availableB = HANTRO_FALSE;
865    availableD = h264bsdIsNeighbourAvailable(pMb, pMb->mbD);
866    if (availableD && constrainedIntraPred &&
867       (h264bsdMbPartPredMode(pMb->mbD->mbType) == PRED_MODE_INTER))
868        availableD = HANTRO_FALSE;
869
870    for (comp = 0, block = 16; comp < 2; comp++)
871    {
872        switch(predMode)
873        {
874            case 0: /* Intra_Chroma_DC */
875                IntraChromaDcPrediction(data, above+1, left, availableA,
876                    availableB);
877                break;
878
879            case 1: /* Intra_Chroma_Horizontal */
880                if (!availableA)
881                    return(HANTRO_NOK);
882                IntraChromaHorizontalPrediction(data, left);
883                break;
884
885            case 2: /* Intra_Chroma_Vertical */
886                if (!availableB)
887                    return(HANTRO_NOK);
888                IntraChromaVerticalPrediction(data, above+1);
889
890                break;
891
892            default: /* case 3: Intra_Chroma_Plane */
893                if (!availableA || !availableB || !availableD)
894                    return(HANTRO_NOK);
895                IntraChromaPlanePrediction(data, above+1, left);
896                break;
897        }
898        for (i = 0; i < 4; i++, block++)
899            h264bsdAddResidual(data, residual[i], block);
900
901        /* advance pointers */
902        data += 64;
903        above += 9;
904        left += 8;
905        residual += 4;
906    }
907
908    return(HANTRO_OK);
909
910}
911
912/*------------------------------------------------------------------------------
913
914    Function: h264bsdAddResidual
915
916        Functional description:
917          Add residual of a block into prediction in macroblock array 'data'.
918          The result (residual + prediction) is stored in 'data'.
919
920------------------------------------------------------------------------------*/
921#ifndef H264DEC_OMXDL
922void h264bsdAddResidual(u8 *data, i32 *residual, u32 blockNum)
923{
924
925/* Variables */
926
927    u32 i;
928    u32 x, y;
929    u32 width;
930    i32 tmp1, tmp2, tmp3, tmp4;
931    u8 *tmp;
932    const u8 *clp = h264bsdClip + 512;
933
934/* Code */
935
936    ASSERT(data);
937    ASSERT(residual);
938    ASSERT(blockNum < 16 + 4 + 4);
939
940    if (IS_RESIDUAL_EMPTY(residual))
941        return;
942
943    RANGE_CHECK_ARRAY(residual, -512, 511, 16);
944
945    if (blockNum < 16)
946    {
947        width = 16;
948        x = h264bsdBlockX[blockNum];
949        y = h264bsdBlockY[blockNum];
950    }
951    else
952    {
953        width = 8;
954        x = h264bsdBlockX[blockNum & 0x3];
955        y = h264bsdBlockY[blockNum & 0x3];
956    }
957
958    tmp = data + y*width + x;
959    for (i = 4; i; i--)
960    {
961        tmp1 = *residual++;
962        tmp2 = tmp[0];
963        tmp3 = *residual++;
964        tmp4 = tmp[1];
965
966        tmp[0] = clp[tmp1 + tmp2];
967
968        tmp1 = *residual++;
969        tmp2 = tmp[2];
970
971        tmp[1] = clp[tmp3 + tmp4];
972
973        tmp3 = *residual++;
974        tmp4 = tmp[3];
975
976        tmp1 = clp[tmp1 + tmp2];
977        tmp3 = clp[tmp3 + tmp4];
978        tmp[2] = (u8)tmp1;
979        tmp[3] = (u8)tmp3;
980
981        tmp += width;
982    }
983
984}
985#endif
986/*------------------------------------------------------------------------------
987
988    Function: Intra16x16VerticalPrediction
989
990        Functional description:
991          Perform intra 16x16 vertical prediction mode.
992
993------------------------------------------------------------------------------*/
994
995void Intra16x16VerticalPrediction(u8 *data, u8 *above)
996{
997
998/* Variables */
999
1000    u32 i, j;
1001
1002/* Code */
1003
1004    ASSERT(data);
1005    ASSERT(above);
1006
1007    for (i = 0; i < 16; i++)
1008    {
1009        for (j = 0; j < 16; j++)
1010        {
1011            *data++ = above[j];
1012        }
1013    }
1014
1015}
1016
1017/*------------------------------------------------------------------------------
1018
1019    Function: Intra16x16HorizontalPrediction
1020
1021        Functional description:
1022          Perform intra 16x16 horizontal prediction mode.
1023
1024------------------------------------------------------------------------------*/
1025
1026void Intra16x16HorizontalPrediction(u8 *data, u8 *left)
1027{
1028
1029/* Variables */
1030
1031    u32 i, j;
1032
1033/* Code */
1034
1035    ASSERT(data);
1036    ASSERT(left);
1037
1038    for (i = 0; i < 16; i++)
1039    {
1040        for (j = 0; j < 16; j++)
1041        {
1042            *data++ = left[i];
1043        }
1044    }
1045
1046}
1047
1048/*------------------------------------------------------------------------------
1049
1050    Function: Intra16x16DcPrediction
1051
1052        Functional description:
1053          Perform intra 16x16 DC prediction mode.
1054
1055------------------------------------------------------------------------------*/
1056
1057void Intra16x16DcPrediction(u8 *data, u8 *above, u8 *left, u32 availableA,
1058    u32 availableB)
1059{
1060
1061/* Variables */
1062
1063    u32 i, tmp;
1064
1065/* Code */
1066
1067    ASSERT(data);
1068    ASSERT(above);
1069    ASSERT(left);
1070
1071    if (availableA && availableB)
1072    {
1073        for (i = 0, tmp = 0; i < 16; i++)
1074            tmp += above[i] + left[i];
1075        tmp = (tmp + 16) >> 5;
1076    }
1077    else if (availableA)
1078    {
1079        for (i = 0, tmp = 0; i < 16; i++)
1080            tmp += left[i];
1081        tmp = (tmp + 8) >> 4;
1082    }
1083    else if (availableB)
1084    {
1085        for (i = 0, tmp = 0; i < 16; i++)
1086            tmp += above[i];
1087        tmp = (tmp + 8) >> 4;
1088    }
1089    /* neither A nor B available */
1090    else
1091    {
1092        tmp = 128;
1093    }
1094    for (i = 0; i < 256; i++)
1095        data[i] = (u8)tmp;
1096
1097}
1098
1099/*------------------------------------------------------------------------------
1100
1101    Function: Intra16x16PlanePrediction
1102
1103        Functional description:
1104          Perform intra 16x16 plane prediction mode.
1105
1106------------------------------------------------------------------------------*/
1107
1108void Intra16x16PlanePrediction(u8 *data, u8 *above, u8 *left)
1109{
1110
1111/* Variables */
1112
1113    u32 i, j;
1114    i32 a, b, c;
1115    i32 tmp;
1116
1117/* Code */
1118
1119    ASSERT(data);
1120    ASSERT(above);
1121    ASSERT(left);
1122
1123    a = 16 * (above[15] + left[15]);
1124
1125    for (i = 0, b = 0; i < 8; i++)
1126        b += ((i32)i + 1) * (above[8+i] - above[6-i]);
1127    b = (5 * b + 32) >> 6;
1128
1129    for (i = 0, c = 0; i < 7; i++)
1130        c += ((i32)i + 1) * (left[8+i] - left[6-i]);
1131    /* p[-1,-1] has to be accessed through above pointer */
1132    c += ((i32)i + 1) * (left[8+i] - above[-1]);
1133    c = (5 * c + 32) >> 6;
1134
1135    for (i = 0; i < 16; i++)
1136    {
1137        for (j = 0; j < 16; j++)
1138        {
1139            tmp = (a + b * ((i32)j - 7) + c * ((i32)i - 7) + 16) >> 5;
1140            data[i*16+j] = (u8)CLIP1(tmp);
1141        }
1142    }
1143
1144}
1145
1146/*------------------------------------------------------------------------------
1147
1148    Function: IntraChromaDcPrediction
1149
1150        Functional description:
1151          Perform intra chroma DC prediction mode.
1152
1153------------------------------------------------------------------------------*/
1154
1155void IntraChromaDcPrediction(u8 *data, u8 *above, u8 *left, u32 availableA,
1156    u32 availableB)
1157{
1158
1159/* Variables */
1160
1161    u32 i;
1162    u32 tmp1, tmp2;
1163
1164/* Code */
1165
1166    ASSERT(data);
1167    ASSERT(above);
1168    ASSERT(left);
1169
1170    /* y = 0..3 */
1171    if (availableA && availableB)
1172    {
1173        tmp1 = above[0] + above[1] + above[2] + above[3] +
1174              left[0] + left[1] + left[2] + left[3];
1175        tmp1 = (tmp1 + 4) >> 3;
1176        tmp2 = (above[4] + above[5] + above[6] + above[7] + 2) >> 2;
1177    }
1178    else if (availableB)
1179    {
1180        tmp1 = (above[0] + above[1] + above[2] + above[3] + 2) >> 2;
1181        tmp2 = (above[4] + above[5] + above[6] + above[7] + 2) >> 2;
1182    }
1183    else if (availableA)
1184    {
1185        tmp1 = (left[0] + left[1] + left[2] + left[3] + 2) >> 2;
1186        tmp2 = tmp1;
1187    }
1188    /* neither A nor B available */
1189    else
1190    {
1191        tmp1 = tmp2 = 128;
1192    }
1193
1194    ASSERT(tmp1 < 256 && tmp2 < 256);
1195    for (i = 4; i--;)
1196    {
1197        *data++ = (u8)tmp1;
1198        *data++ = (u8)tmp1;
1199        *data++ = (u8)tmp1;
1200        *data++ = (u8)tmp1;
1201        *data++ = (u8)tmp2;
1202        *data++ = (u8)tmp2;
1203        *data++ = (u8)tmp2;
1204        *data++ = (u8)tmp2;
1205    }
1206
1207    /* y = 4...7 */
1208    if (availableA)
1209    {
1210        tmp1 = (left[4] + left[5] + left[6] + left[7] + 2) >> 2;
1211        if (availableB)
1212        {
1213            tmp2 = above[4] + above[5] + above[6] + above[7] +
1214                   left[4] + left[5] + left[6] + left[7];
1215            tmp2 = (tmp2 + 4) >> 3;
1216        }
1217        else
1218            tmp2 = tmp1;
1219    }
1220    else if (availableB)
1221    {
1222        tmp1 = (above[0] + above[1] + above[2] + above[3] + 2) >> 2;
1223        tmp2 = (above[4] + above[5] + above[6] + above[7] + 2) >> 2;
1224    }
1225    else
1226    {
1227        tmp1 = tmp2 = 128;
1228    }
1229
1230    ASSERT(tmp1 < 256 && tmp2 < 256);
1231    for (i = 4; i--;)
1232    {
1233        *data++ = (u8)tmp1;
1234        *data++ = (u8)tmp1;
1235        *data++ = (u8)tmp1;
1236        *data++ = (u8)tmp1;
1237        *data++ = (u8)tmp2;
1238        *data++ = (u8)tmp2;
1239        *data++ = (u8)tmp2;
1240        *data++ = (u8)tmp2;
1241    }
1242}
1243
1244/*------------------------------------------------------------------------------
1245
1246    Function: IntraChromaHorizontalPrediction
1247
1248        Functional description:
1249          Perform intra chroma horizontal prediction mode.
1250
1251------------------------------------------------------------------------------*/
1252
1253void IntraChromaHorizontalPrediction(u8 *data, u8 *left)
1254{
1255
1256/* Variables */
1257
1258    u32 i;
1259
1260/* Code */
1261
1262    ASSERT(data);
1263    ASSERT(left);
1264
1265    for (i = 8; i--;)
1266    {
1267        *data++ = *left;
1268        *data++ = *left;
1269        *data++ = *left;
1270        *data++ = *left;
1271        *data++ = *left;
1272        *data++ = *left;
1273        *data++ = *left;
1274        *data++ = *left++;
1275    }
1276
1277}
1278
1279/*------------------------------------------------------------------------------
1280
1281    Function: IntraChromaVerticalPrediction
1282
1283        Functional description:
1284          Perform intra chroma vertical prediction mode.
1285
1286------------------------------------------------------------------------------*/
1287
1288void IntraChromaVerticalPrediction(u8 *data, u8 *above)
1289{
1290
1291/* Variables */
1292
1293    u32 i;
1294
1295/* Code */
1296
1297    ASSERT(data);
1298    ASSERT(above);
1299
1300    for (i = 8; i--;data++/*above-=8*/)
1301    {
1302        data[0] = *above;
1303        data[8] = *above;
1304        data[16] = *above;
1305        data[24] = *above;
1306        data[32] = *above;
1307        data[40] = *above;
1308        data[48] = *above;
1309        data[56] = *above++;
1310    }
1311
1312}
1313
1314/*------------------------------------------------------------------------------
1315
1316    Function: IntraChromaPlanePrediction
1317
1318        Functional description:
1319          Perform intra chroma plane prediction mode.
1320
1321------------------------------------------------------------------------------*/
1322
1323void IntraChromaPlanePrediction(u8 *data, u8 *above, u8 *left)
1324{
1325
1326/* Variables */
1327
1328    u32 i;
1329    i32 a, b, c;
1330    i32 tmp;
1331    const u8 *clp = h264bsdClip + 512;
1332
1333/* Code */
1334
1335    ASSERT(data);
1336    ASSERT(above);
1337    ASSERT(left);
1338
1339    a = 16 * (above[7] + left[7]);
1340
1341    b = (above[4] - above[2]) + 2 * (above[5] - above[1])
1342        + 3 * (above[6] - above[0]) + 4 * (above[7] - above[-1]);
1343    b = (17 * b + 16) >> 5;
1344
1345    /* p[-1,-1] has to be accessed through above pointer */
1346    c = (left[4] - left[2]) + 2 * (left[5] - left[1])
1347        + 3 * (left[6] - left[0]) + 4 * (left[7] - above[-1]);
1348    c = (17 * c + 16) >> 5;
1349
1350    /*a += 16;*/
1351    a = a - 3 * c + 16;
1352    for (i = 8; i--; a += c)
1353    {
1354        tmp = (a - 3 * b);
1355        *data++ = clp[tmp>>5];
1356        tmp += b;
1357        *data++ = clp[tmp>>5];
1358        tmp += b;
1359        *data++ = clp[tmp>>5];
1360        tmp += b;
1361        *data++ = clp[tmp>>5];
1362        tmp += b;
1363        *data++ = clp[tmp>>5];
1364        tmp += b;
1365        *data++ = clp[tmp>>5];
1366        tmp += b;
1367        *data++ = clp[tmp>>5];
1368        tmp += b;
1369        *data++ = clp[tmp>>5];
1370    }
1371
1372}
1373
1374/*------------------------------------------------------------------------------
1375
1376    Function: Get4x4NeighbourPels
1377
1378        Functional description:
1379          Get neighbouring pixels of a 4x4 block into 'a' and 'l'.
1380
1381------------------------------------------------------------------------------*/
1382
1383void Get4x4NeighbourPels(u8 *a, u8 *l, u8 *data, u8 *above, u8 *left,
1384    u32 blockNum)
1385{
1386
1387/* Variables */
1388
1389    u32 x, y;
1390    u8 t1, t2;
1391
1392/* Code */
1393
1394    ASSERT(a);
1395    ASSERT(l);
1396    ASSERT(data);
1397    ASSERT(above);
1398    ASSERT(left);
1399    ASSERT(blockNum < 16);
1400
1401    x = h264bsdBlockX[blockNum];
1402    y = h264bsdBlockY[blockNum];
1403
1404    /* A and D */
1405    if (x == 0)
1406    {
1407        t1 = left[y    ];
1408        t2 = left[y + 1];
1409        l[1] = t1;
1410        l[2] = t2;
1411        t1 = left[y + 2];
1412        t2 = left[y + 3];
1413        l[3] = t1;
1414        l[4] = t2;
1415    }
1416    else
1417    {
1418        t1 = data[y * 16 + x - 1     ];
1419        t2 = data[y * 16 + x - 1 + 16];
1420        l[1] = t1;
1421        l[2] = t2;
1422        t1 = data[y * 16 + x - 1 + 32];
1423        t2 = data[y * 16 + x - 1 + 48];
1424        l[3] = t1;
1425        l[4] = t2;
1426    }
1427
1428    /* B, C and D */
1429    if (y == 0)
1430    {
1431        t1 = above[x    ];
1432        t2 = above[x    ];
1433        l[0] = t1;
1434        a[0] = t2;
1435        t1 = above[x + 1];
1436        t2 = above[x + 2];
1437        a[1] = t1;
1438        a[2] = t2;
1439        t1 = above[x + 3];
1440        t2 = above[x + 4];
1441        a[3] = t1;
1442        a[4] = t2;
1443        t1 = above[x + 5];
1444        t2 = above[x + 6];
1445        a[5] = t1;
1446        a[6] = t2;
1447        t1 = above[x + 7];
1448        t2 = above[x + 8];
1449        a[7] = t1;
1450        a[8] = t2;
1451    }
1452    else
1453    {
1454        t1 = data[(y - 1) * 16 + x    ];
1455        t2 = data[(y - 1) * 16 + x + 1];
1456        a[1] = t1;
1457        a[2] = t2;
1458        t1 = data[(y - 1) * 16 + x + 2];
1459        t2 = data[(y - 1) * 16 + x + 3];
1460        a[3] = t1;
1461        a[4] = t2;
1462        t1 = data[(y - 1) * 16 + x + 4];
1463        t2 = data[(y - 1) * 16 + x + 5];
1464        a[5] = t1;
1465        a[6] = t2;
1466        t1 = data[(y - 1) * 16 + x + 6];
1467        t2 = data[(y - 1) * 16 + x + 7];
1468        a[7] = t1;
1469        a[8] = t2;
1470
1471        if (x == 0)
1472            l[0] = a[0] = left[y-1];
1473        else
1474            l[0] = a[0] = data[(y - 1) * 16 + x - 1];
1475    }
1476}
1477
1478
1479/*------------------------------------------------------------------------------
1480
1481    Function: Intra4x4VerticalPrediction
1482
1483        Functional description:
1484          Perform intra 4x4 vertical prediction mode.
1485
1486------------------------------------------------------------------------------*/
1487
1488void Intra4x4VerticalPrediction(u8 *data, u8 *above)
1489{
1490
1491/* Variables */
1492
1493    u8 t1, t2;
1494
1495/* Code */
1496
1497    ASSERT(data);
1498    ASSERT(above);
1499
1500    t1 = above[0];
1501    t2 = above[1];
1502    data[0] = data[4] = data[8] = data[12] = t1;
1503    data[1] = data[5] = data[9] = data[13] = t2;
1504    t1 = above[2];
1505    t2 = above[3];
1506    data[2] = data[6] = data[10] = data[14] = t1;
1507    data[3] = data[7] = data[11] = data[15] = t2;
1508
1509}
1510
1511/*------------------------------------------------------------------------------
1512
1513    Function: Intra4x4HorizontalPrediction
1514
1515        Functional description:
1516          Perform intra 4x4 horizontal prediction mode.
1517
1518------------------------------------------------------------------------------*/
1519
1520void Intra4x4HorizontalPrediction(u8 *data, u8 *left)
1521{
1522
1523/* Variables */
1524
1525    u8 t1, t2;
1526
1527/* Code */
1528
1529    ASSERT(data);
1530    ASSERT(left);
1531
1532    t1 = left[0];
1533    t2 = left[1];
1534    data[0] = data[1] = data[2] = data[3] = t1;
1535    data[4] = data[5] = data[6] = data[7] = t2;
1536    t1 = left[2];
1537    t2 = left[3];
1538    data[8] = data[9] = data[10] = data[11] = t1;
1539    data[12] = data[13] = data[14] = data[15] = t2;
1540
1541}
1542
1543/*------------------------------------------------------------------------------
1544
1545    Function: Intra4x4DcPrediction
1546
1547        Functional description:
1548          Perform intra 4x4 DC prediction mode.
1549
1550------------------------------------------------------------------------------*/
1551
1552void Intra4x4DcPrediction(u8 *data, u8 *above, u8 *left, u32 availableA,
1553    u32 availableB)
1554{
1555
1556/* Variables */
1557
1558    u32 tmp;
1559    u8 t1, t2, t3, t4;
1560
1561/* Code */
1562
1563    ASSERT(data);
1564    ASSERT(above);
1565    ASSERT(left);
1566
1567    if (availableA && availableB)
1568    {
1569        t1 = above[0]; t2 = above[1]; t3 = above[2]; t4 = above[3];
1570        tmp = t1 + t2 + t3 + t4;
1571        t1 = left[0]; t2 = left[1]; t3 = left[2]; t4 = left[3];
1572        tmp += t1 + t2 + t3 + t4;
1573        tmp = (tmp + 4) >> 3;
1574    }
1575    else if (availableA)
1576    {
1577        t1 = left[0]; t2 = left[1]; t3 = left[2]; t4 = left[3];
1578        tmp = (t1 + t2 + t3 + t4 + 2) >> 2;
1579    }
1580    else if (availableB)
1581    {
1582        t1 = above[0]; t2 = above[1]; t3 = above[2]; t4 = above[3];
1583        tmp = (t1 + t2 + t3 + t4 + 2) >> 2;
1584    }
1585    else
1586    {
1587        tmp = 128;
1588    }
1589
1590    ASSERT(tmp < 256);
1591    data[0] = data[1] = data[2] = data[3] =
1592    data[4] = data[5] = data[6] = data[7] =
1593    data[8] = data[9] = data[10] = data[11] =
1594    data[12] = data[13] = data[14] = data[15] = (u8)tmp;
1595
1596}
1597
1598/*------------------------------------------------------------------------------
1599
1600    Function: Intra4x4DiagonalDownLeftPrediction
1601
1602        Functional description:
1603          Perform intra 4x4 diagonal down-left prediction mode.
1604
1605------------------------------------------------------------------------------*/
1606
1607void Intra4x4DiagonalDownLeftPrediction(u8 *data, u8 *above)
1608{
1609
1610/* Variables */
1611
1612/* Code */
1613
1614    ASSERT(data);
1615    ASSERT(above);
1616
1617    data[ 0] = (above[0] + 2 * above[1] + above[2] + 2) >> 2;
1618    data[ 1] = (above[1] + 2 * above[2] + above[3] + 2) >> 2;
1619    data[ 4] = (above[1] + 2 * above[2] + above[3] + 2) >> 2;
1620    data[ 2] = (above[2] + 2 * above[3] + above[4] + 2) >> 2;
1621    data[ 5] = (above[2] + 2 * above[3] + above[4] + 2) >> 2;
1622    data[ 8] = (above[2] + 2 * above[3] + above[4] + 2) >> 2;
1623    data[ 3] = (above[3] + 2 * above[4] + above[5] + 2) >> 2;
1624    data[ 6] = (above[3] + 2 * above[4] + above[5] + 2) >> 2;
1625    data[ 9] = (above[3] + 2 * above[4] + above[5] + 2) >> 2;
1626    data[12] = (above[3] + 2 * above[4] + above[5] + 2) >> 2;
1627    data[ 7] = (above[4] + 2 * above[5] + above[6] + 2) >> 2;
1628    data[10] = (above[4] + 2 * above[5] + above[6] + 2) >> 2;
1629    data[13] = (above[4] + 2 * above[5] + above[6] + 2) >> 2;
1630    data[11] = (above[5] + 2 * above[6] + above[7] + 2) >> 2;
1631    data[14] = (above[5] + 2 * above[6] + above[7] + 2) >> 2;
1632    data[15] = (above[6] + 3 * above[7] + 2) >> 2;
1633
1634}
1635
1636/*------------------------------------------------------------------------------
1637
1638    Function: Intra4x4DiagonalDownRightPrediction
1639
1640        Functional description:
1641          Perform intra 4x4 diagonal down-right prediction mode.
1642
1643------------------------------------------------------------------------------*/
1644
1645void Intra4x4DiagonalDownRightPrediction(u8 *data, u8 *above, u8 *left)
1646{
1647
1648/* Variables */
1649
1650/* Code */
1651
1652    ASSERT(data);
1653    ASSERT(above);
1654    ASSERT(left);
1655
1656    data[ 0] = (above[0] + 2 * above[-1] + left[0] + 2) >> 2;
1657    data[ 5] = (above[0] + 2 * above[-1] + left[0] + 2) >> 2;
1658    data[10] = (above[0] + 2 * above[-1] + left[0] + 2) >> 2;
1659    data[15] = (above[0] + 2 * above[-1] + left[0] + 2) >> 2;
1660    data[ 1] = (above[-1] + 2 * above[0] + above[1] + 2) >> 2;
1661    data[ 6] = (above[-1] + 2 * above[0] + above[1] + 2) >> 2;
1662    data[11] = (above[-1] + 2 * above[0] + above[1] + 2) >> 2;
1663    data[ 2] = (above[0] + 2 * above[1] + above[2] + 2) >> 2;
1664    data[ 7] = (above[0] + 2 * above[1] + above[2] + 2) >> 2;
1665    data[ 3] = (above[1] + 2 * above[2] + above[3] + 2) >> 2;
1666    data[ 4] = (left[-1] + 2 * left[0] + left[1] + 2) >> 2;
1667    data[ 9] = (left[-1] + 2 * left[0] + left[1] + 2) >> 2;
1668    data[14] = (left[-1] + 2 * left[0] + left[1] + 2) >> 2;
1669    data[ 8] = (left[0] + 2 * left[1] + left[2] + 2) >> 2;
1670    data[13] = (left[0] + 2 * left[1] + left[2] + 2) >> 2;
1671    data[12] = (left[1] + 2 * left[2] + left[3] + 2) >> 2;
1672}
1673
1674/*------------------------------------------------------------------------------
1675
1676    Function: Intra4x4VerticalRightPrediction
1677
1678        Functional description:
1679          Perform intra 4x4 vertical right prediction mode.
1680
1681------------------------------------------------------------------------------*/
1682
1683void Intra4x4VerticalRightPrediction(u8 *data, u8 *above, u8 *left)
1684{
1685
1686/* Variables */
1687
1688/* Code */
1689
1690    ASSERT(data);
1691    ASSERT(above);
1692    ASSERT(left);
1693
1694    data[ 0] = (above[-1] + above[0] + 1) >> 1;
1695    data[ 9] = (above[-1] + above[0] + 1) >> 1;
1696    data[ 5] = (above[-1] + 2 * above[0] + above[1] + 2) >> 2;
1697    data[14] = (above[-1] + 2 * above[0] + above[1] + 2) >> 2;
1698    data[ 4] = (above[0] + 2 * above[-1] + left[0] + 2) >> 2;
1699    data[13] = (above[0] + 2 * above[-1] + left[0] + 2) >> 2;
1700    data[ 1] = (above[0] + above[1] + 1) >> 1;
1701    data[10] = (above[0] + above[1] + 1) >> 1;
1702    data[ 6] = (above[0] + 2 * above[1] + above[2] + 2) >> 2;
1703    data[15] = (above[0] + 2 * above[1] + above[2] + 2) >> 2;
1704    data[ 2] = (above[1] + above[2] + 1) >> 1;
1705    data[11] = (above[1] + above[2] + 1) >> 1;
1706    data[ 7] = (above[1] + 2 * above[2] + above[3] + 2) >> 2;
1707    data[ 3] = (above[2] + above[3] + 1) >> 1;
1708    data[ 8] = (left[1] + 2 * left[0] + left[-1] + 2) >> 2;
1709    data[12] = (left[2] + 2 * left[1] + left[0] + 2) >> 2;
1710
1711}
1712
1713/*------------------------------------------------------------------------------
1714
1715    Function: Intra4x4HorizontalDownPrediction
1716
1717        Functional description:
1718          Perform intra 4x4 horizontal down prediction mode.
1719
1720------------------------------------------------------------------------------*/
1721
1722void Intra4x4HorizontalDownPrediction(u8 *data, u8 *above, u8 *left)
1723{
1724
1725/* Variables */
1726
1727/* Code */
1728
1729    ASSERT(data);
1730    ASSERT(above);
1731    ASSERT(left);
1732
1733    data[ 0] = (left[-1] + left[0] + 1) >> 1;
1734    data[ 6] = (left[-1] + left[0] + 1) >> 1;
1735    data[ 5] = (left[-1] + 2 * left[0] + left[1] + 2) >> 2;
1736    data[11] = (left[-1] + 2 * left[0] + left[1] + 2) >> 2;
1737    data[ 4] = (left[0] + left[1] + 1) >> 1;
1738    data[10] = (left[0] + left[1] + 1) >> 1;
1739    data[ 9] = (left[0] + 2 * left[1] + left[2] + 2) >> 2;
1740    data[15] = (left[0] + 2 * left[1] + left[2] + 2) >> 2;
1741    data[ 8] = (left[1] + left[2] + 1) >> 1;
1742    data[14] = (left[1] + left[2] + 1) >> 1;
1743    data[13] = (left[1] + 2 * left[2] + left[3] + 2) >> 2;
1744    data[12] = (left[2] + left[3] + 1) >> 1;
1745    data[ 1] = (above[0] + 2 * above[-1] + left[0] + 2) >> 2;
1746    data[ 7] = (above[0] + 2 * above[-1] + left[0] + 2) >> 2;
1747    data[ 2] = (above[1] + 2 * above[0] + above[-1] + 2) >> 2;
1748    data[ 3] = (above[2] + 2 * above[1] + above[0] + 2) >> 2;
1749}
1750
1751/*------------------------------------------------------------------------------
1752
1753    Function: Intra4x4VerticalLeftPrediction
1754
1755        Functional description:
1756          Perform intra 4x4 vertical left prediction mode.
1757
1758------------------------------------------------------------------------------*/
1759
1760void Intra4x4VerticalLeftPrediction(u8 *data, u8 *above)
1761{
1762
1763/* Variables */
1764
1765/* Code */
1766
1767    ASSERT(data);
1768    ASSERT(above);
1769
1770    data[ 0] = (above[0] + above[1] + 1) >> 1;
1771    data[ 1] = (above[1] + above[2] + 1) >> 1;
1772    data[ 2] = (above[2] + above[3] + 1) >> 1;
1773    data[ 3] = (above[3] + above[4] + 1) >> 1;
1774    data[ 4] = (above[0] + 2 * above[1] + above[2] + 2) >> 2;
1775    data[ 5] = (above[1] + 2 * above[2] + above[3] + 2) >> 2;
1776    data[ 6] = (above[2] + 2 * above[3] + above[4] + 2) >> 2;
1777    data[ 7] = (above[3] + 2 * above[4] + above[5] + 2) >> 2;
1778    data[ 8] = (above[1] + above[2] + 1) >> 1;
1779    data[ 9] = (above[2] + above[3] + 1) >> 1;
1780    data[10] = (above[3] + above[4] + 1) >> 1;
1781    data[11] = (above[4] + above[5] + 1) >> 1;
1782    data[12] = (above[1] + 2 * above[2] + above[3] + 2) >> 2;
1783    data[13] = (above[2] + 2 * above[3] + above[4] + 2) >> 2;
1784    data[14] = (above[3] + 2 * above[4] + above[5] + 2) >> 2;
1785    data[15] = (above[4] + 2 * above[5] + above[6] + 2) >> 2;
1786
1787}
1788
1789/*------------------------------------------------------------------------------
1790
1791    Function: Intra4x4HorizontalUpPrediction
1792
1793        Functional description:
1794          Perform intra 4x4 horizontal up prediction mode.
1795
1796------------------------------------------------------------------------------*/
1797
1798void Intra4x4HorizontalUpPrediction(u8 *data, u8 *left)
1799{
1800
1801/* Variables */
1802
1803/* Code */
1804
1805    ASSERT(data);
1806    ASSERT(left);
1807
1808    data[ 0] = (left[0] + left[1] + 1) >> 1;
1809    data[ 1] = (left[0] + 2 * left[1] + left[2] + 2) >> 2;
1810    data[ 2] = (left[1] + left[2] + 1) >> 1;
1811    data[ 3] = (left[1] + 2 * left[2] + left[3] + 2) >> 2;
1812    data[ 4] = (left[1] + left[2] + 1) >> 1;
1813    data[ 5] = (left[1] + 2 * left[2] + left[3] + 2) >> 2;
1814    data[ 6] = (left[2] + left[3] + 1) >> 1;
1815    data[ 7] = (left[2] + 3 * left[3] + 2) >> 2;
1816    data[ 8] = (left[2] + left[3] + 1) >> 1;
1817    data[ 9] = (left[2] + 3 * left[3] + 2) >> 2;
1818    data[10] = left[3];
1819    data[11] = left[3];
1820    data[12] = left[3];
1821    data[13] = left[3];
1822    data[14] = left[3];
1823    data[15] = left[3];
1824
1825}
1826
1827#endif /* H264DEC_OMXDL */
1828
1829/*------------------------------------------------------------------------------
1830
1831    Function: Write4x4To16x16
1832
1833        Functional description:
1834          Write a 4x4 block (data4x4) into correct position
1835          in 16x16 macroblock (data).
1836
1837------------------------------------------------------------------------------*/
1838
1839void Write4x4To16x16(u8 *data, u8 *data4x4, u32 blockNum)
1840{
1841
1842/* Variables */
1843
1844    u32 x, y;
1845    u32 *in32, *out32;
1846
1847/* Code */
1848
1849    ASSERT(data);
1850    ASSERT(data4x4);
1851    ASSERT(blockNum < 16);
1852
1853    x = h264bsdBlockX[blockNum];
1854    y = h264bsdBlockY[blockNum];
1855
1856    data += y*16+x;
1857
1858    ASSERT(((u32)data&0x3) == 0);
1859
1860    /*lint --e(826) */
1861    out32 = (u32 *)data;
1862    /*lint --e(826) */
1863    in32 = (u32 *)data4x4;
1864
1865    out32[0] = *in32++;
1866    out32[4] = *in32++;
1867    out32[8] = *in32++;
1868    out32[12] = *in32++;
1869}
1870
1871/*------------------------------------------------------------------------------
1872
1873    Function: DetermineIntra4x4PredMode
1874
1875        Functional description:
1876          Returns the intra 4x4 prediction mode of a block based on the
1877          neighbouring macroblocks and information parsed from stream.
1878
1879------------------------------------------------------------------------------*/
1880
1881u32 DetermineIntra4x4PredMode(macroblockLayer_t *pMbLayer,
1882    u32 available, neighbour_t *nA, neighbour_t *nB, u32 index,
1883    mbStorage_t *nMbA, mbStorage_t *nMbB)
1884{
1885
1886/* Variables */
1887
1888    u32 mode1, mode2;
1889    mbStorage_t *pMb;
1890
1891/* Code */
1892
1893    ASSERT(pMbLayer);
1894
1895    /* dc only prediction? */
1896    if (!available)
1897        mode1 = 2;
1898    else
1899    {
1900        pMb = nMbA;
1901        if (h264bsdMbPartPredMode(pMb->mbType) == PRED_MODE_INTRA4x4)
1902        {
1903            mode1 = pMb->intra4x4PredMode[nA->index];
1904        }
1905        else
1906            mode1 = 2;
1907
1908        pMb = nMbB;
1909        if (h264bsdMbPartPredMode(pMb->mbType) == PRED_MODE_INTRA4x4)
1910        {
1911            mode2 = pMb->intra4x4PredMode[nB->index];
1912        }
1913        else
1914            mode2 = 2;
1915
1916        mode1 = MIN(mode1, mode2);
1917    }
1918
1919    if (!pMbLayer->mbPred.prevIntra4x4PredModeFlag[index])
1920    {
1921        if (pMbLayer->mbPred.remIntra4x4PredMode[index] < mode1)
1922        {
1923            mode1 = pMbLayer->mbPred.remIntra4x4PredMode[index];
1924        }
1925        else
1926        {
1927            mode1 = pMbLayer->mbPred.remIntra4x4PredMode[index] + 1;
1928        }
1929    }
1930
1931    return(mode1);
1932}
1933
1934
1935/*lint +e702 */
1936
1937
1938