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