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 */
85 const u32 h264bsdBlockX[16] =
86     { 0, 4, 0, 4, 8, 12, 8, 12, 0, 4, 0, 4, 8, 12, 8, 12 };
87 const u32 h264bsdBlockY[16] =
88     { 0, 0, 4, 4, 0, 0, 4, 4, 8, 8, 12, 12, 8, 8, 12, 12 };
89 
90 const 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 ------------------------------------------------------------------------------*/
162 static void Get4x4NeighbourPels(u8 *a, u8 *l, u8 *data, u8 *above, u8 *left,
163     u32 blockNum);
164 static void Intra16x16VerticalPrediction(u8 *data, u8 *above);
165 static void Intra16x16HorizontalPrediction(u8 *data, u8 *left);
166 static void Intra16x16DcPrediction(u8 *data, u8 *above, u8 *left,
167     u32 A, u32 B);
168 static void Intra16x16PlanePrediction(u8 *data, u8 *above, u8 *left);
169 static void IntraChromaDcPrediction(u8 *data, u8 *above, u8 *left,
170     u32 A, u32 B);
171 static void IntraChromaHorizontalPrediction(u8 *data, u8 *left);
172 static void IntraChromaVerticalPrediction(u8 *data, u8 *above);
173 static void IntraChromaPlanePrediction(u8 *data, u8 *above, u8 *left);
174 
175 static void Intra4x4VerticalPrediction(u8 *data, u8 *above);
176 static void Intra4x4HorizontalPrediction(u8 *data, u8 *left);
177 static void Intra4x4DcPrediction(u8 *data, u8 *above, u8 *left, u32 A, u32 B);
178 static void Intra4x4DiagonalDownLeftPrediction(u8 *data, u8 *above);
179 static void Intra4x4DiagonalDownRightPrediction(u8 *data, u8 *above, u8 *left);
180 static void Intra4x4VerticalRightPrediction(u8 *data, u8 *above, u8 *left);
181 static void Intra4x4HorizontalDownPrediction(u8 *data, u8 *above, u8 *left);
182 static void Intra4x4VerticalLeftPrediction(u8 *data, u8 *above);
183 static void Intra4x4HorizontalUpPrediction(u8 *data, u8 *left);
184 void h264bsdAddResidual(u8 *data, i32 *residual, u32 blockNum);
185 
186 static void Write4x4To16x16(u8 *data, u8 *data4x4, u32 blockNum);
187 #endif /* H264DEC_OMXDL */
188 
189 static 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 ------------------------------------------------------------------------------*/
h264bsdIntra16x16Prediction(mbStorage_t * pMb,u8 * data,u8 * ptr,u32 width,u32 constrainedIntraPred)206 u32 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 ------------------------------------------------------------------------------*/
h264bsdIntra4x4Prediction(mbStorage_t * pMb,u8 * data,macroblockLayer_t * mbLayer,u8 * ptr,u32 width,u32 constrainedIntraPred,u32 block)261 u32 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 ------------------------------------------------------------------------------*/
h264bsdIntraChromaPrediction(mbStorage_t * pMb,u8 * data,image_t * image,u32 predMode,u32 constrainedIntraPred)372 u32 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 ------------------------------------------------------------------------------*/
h264bsdIntraPrediction(mbStorage_t * pMb,macroblockLayer_t * mbLayer,image_t * image,u32 mbNum,u32 constrainedIntraPred,u8 * data)473 u32 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 
h264bsdGetNeighbourPels(image_t * image,u8 * above,u8 * left,u32 mbNum)540 void 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 
h264bsdIntra16x16Prediction(mbStorage_t * pMb,u8 * data,i32 residual[][16],u8 * above,u8 * left,u32 constrainedIntraPred)622 u32 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 
h264bsdIntra4x4Prediction(mbStorage_t * pMb,u8 * data,macroblockLayer_t * mbLayer,u8 * above,u8 * left,u32 constrainedIntraPred)696 u32 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 
h264bsdIntraChromaPrediction(mbStorage_t * pMb,u8 * data,i32 residual[][16],u8 * above,u8 * left,u32 predMode,u32 constrainedIntraPred)840 u32 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
h264bsdAddResidual(u8 * data,i32 * residual,u32 blockNum)922 void 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 
Intra16x16VerticalPrediction(u8 * data,u8 * above)995 void 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 
Intra16x16HorizontalPrediction(u8 * data,u8 * left)1026 void 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 
Intra16x16DcPrediction(u8 * data,u8 * above,u8 * left,u32 availableA,u32 availableB)1057 void 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 
Intra16x16PlanePrediction(u8 * data,u8 * above,u8 * left)1108 void Intra16x16PlanePrediction(u8 *data, u8 *above, u8 *left)
1109 {
1110 
1111 /* Variables */
1112 
1113     i32 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 += (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 += (i + 1) * (left[8+i] - left[6-i]);
1131     /* p[-1,-1] has to be accessed through above pointer */
1132     c += (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 * (j - 7) + c * (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 
IntraChromaDcPrediction(u8 * data,u8 * above,u8 * left,u32 availableA,u32 availableB)1155 void 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 
IntraChromaHorizontalPrediction(u8 * data,u8 * left)1253 void 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 
IntraChromaVerticalPrediction(u8 * data,u8 * above)1288 void 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 
IntraChromaPlanePrediction(u8 * data,u8 * above,u8 * left)1323 void 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 
Get4x4NeighbourPels(u8 * a,u8 * l,u8 * data,u8 * above,u8 * left,u32 blockNum)1383 void 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 
Intra4x4VerticalPrediction(u8 * data,u8 * above)1488 void 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 
Intra4x4HorizontalPrediction(u8 * data,u8 * left)1520 void 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 
Intra4x4DcPrediction(u8 * data,u8 * above,u8 * left,u32 availableA,u32 availableB)1552 void 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 
Intra4x4DiagonalDownLeftPrediction(u8 * data,u8 * above)1607 void 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 
Intra4x4DiagonalDownRightPrediction(u8 * data,u8 * above,u8 * left)1645 void 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 
Intra4x4VerticalRightPrediction(u8 * data,u8 * above,u8 * left)1683 void 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 
Intra4x4HorizontalDownPrediction(u8 * data,u8 * above,u8 * left)1722 void 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 
Intra4x4VerticalLeftPrediction(u8 * data,u8 * above)1760 void 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 
Intra4x4HorizontalUpPrediction(u8 * data,u8 * left)1798 void 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 
Write4x4To16x16(u8 * data,u8 * data4x4,u32 blockNum)1839 void 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 
DetermineIntra4x4PredMode(macroblockLayer_t * pMbLayer,u32 available,neighbour_t * nA,neighbour_t * nB,u32 index,mbStorage_t * nMbA,mbStorage_t * nMbB)1881 u32 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