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 h264bsdInterPrediction
27 MvPrediction16x16
28 MvPrediction16x8
29 MvPrediction8x16
30 MvPrediction8x8
31 MvPrediction
32 MedianFilter
33 GetInterNeighbour
34 GetPredictionMv
35
36 ------------------------------------------------------------------------------*/
37
38 /*------------------------------------------------------------------------------
39 1. Include headers
40 ------------------------------------------------------------------------------*/
41
42 #include "h264bsd_inter_prediction.h"
43 #include "h264bsd_neighbour.h"
44 #include "h264bsd_util.h"
45 #include "h264bsd_reconstruct.h"
46 #include "h264bsd_dpb.h"
47
48 /*------------------------------------------------------------------------------
49 2. External compiler flags
50 --------------------------------------------------------------------------------
51
52 --------------------------------------------------------------------------------
53 3. Module defines
54 ------------------------------------------------------------------------------*/
55
56 typedef struct
57 {
58 u32 available;
59 u32 refIndex;
60 mv_t mv;
61 } interNeighbour_t;
62
63 /*------------------------------------------------------------------------------
64 4. Local function prototypes
65 ------------------------------------------------------------------------------*/
66
67 static u32 MvPrediction16x16(mbStorage_t *pMb, mbPred_t *mbPred,
68 dpbStorage_t *dpb);
69 static u32 MvPrediction16x8(mbStorage_t *pMb, mbPred_t *mbPred,
70 dpbStorage_t *dpb);
71 static u32 MvPrediction8x16(mbStorage_t *pMb, mbPred_t *mbPred,
72 dpbStorage_t *dpb);
73 static u32 MvPrediction8x8(mbStorage_t *pMb, subMbPred_t *subMbPred,
74 dpbStorage_t *dpb);
75 static u32 MvPrediction(mbStorage_t *pMb, subMbPred_t *subMbPred,
76 u32 mbPartIdx, u32 subMbPartIdx);
77 static i32 MedianFilter(i32 a, i32 b, i32 c);
78
79 static void GetInterNeighbour(u32 sliceId, mbStorage_t *nMb,
80 interNeighbour_t *n, u32 index);
81 static void GetPredictionMv(mv_t *mv, interNeighbour_t *a, u32 refIndex);
82
83 static const neighbour_t N_A_SUB_PART[4][4][4] = {
84 { { {MB_A,5}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
85 { {MB_A,5}, {MB_A,7}, {MB_NA,0}, {MB_NA,0} },
86 { {MB_A,5}, {MB_CURR,0}, {MB_NA,0}, {MB_NA,0} },
87 { {MB_A,5}, {MB_CURR,0}, {MB_A,7}, {MB_CURR,2} } },
88
89 { { {MB_CURR,1}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
90 { {MB_CURR,1}, {MB_CURR,3}, {MB_NA,0}, {MB_NA,0} },
91 { {MB_CURR,1}, {MB_CURR,4}, {MB_NA,0}, {MB_NA,0} },
92 { {MB_CURR,1}, {MB_CURR,4}, {MB_CURR,3}, {MB_CURR,6} } },
93
94 { { {MB_A,13}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
95 { {MB_A,13}, {MB_A,15}, {MB_NA,0}, {MB_NA,0} },
96 { {MB_A,13}, {MB_CURR,8}, {MB_NA,0}, {MB_NA,0} },
97 { {MB_A,13}, {MB_CURR,8}, {MB_A,15}, {MB_CURR,10} } },
98
99 { { {MB_CURR,9}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
100 { {MB_CURR,9}, {MB_CURR,11}, {MB_NA,0}, {MB_NA,0} },
101 { {MB_CURR,9}, {MB_CURR,12}, {MB_NA,0}, {MB_NA,0} },
102 { {MB_CURR,9}, {MB_CURR,12}, {MB_CURR,11}, {MB_CURR,14} } } };
103
104 static const neighbour_t N_B_SUB_PART[4][4][4] = {
105 { { {MB_B,10}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
106 { {MB_B,10}, {MB_CURR,0}, {MB_NA,0}, {MB_NA,0} },
107 { {MB_B,10}, {MB_B,11}, {MB_NA,0}, {MB_NA,0} },
108 { {MB_B,10}, {MB_B,11}, {MB_CURR,0}, {MB_CURR,1} } },
109
110 { { {MB_B,14}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
111 { {MB_B,14}, {MB_CURR,4}, {MB_NA,0}, {MB_NA,0} },
112 { {MB_B,14}, {MB_B,15}, {MB_NA,0}, {MB_NA,0} },
113 { {MB_B,14}, {MB_B,15}, {MB_CURR,4}, {MB_CURR,5} } },
114
115 { { {MB_CURR,2}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
116 { {MB_CURR,2}, {MB_CURR,8}, {MB_NA,0}, {MB_NA,0} },
117 { {MB_CURR,2}, {MB_CURR,3}, {MB_NA,0}, {MB_NA,0} },
118 { {MB_CURR,2}, {MB_CURR,3}, {MB_CURR,8}, {MB_CURR,9} } },
119
120 { { {MB_CURR,6}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
121 { {MB_CURR,6}, {MB_CURR,12}, {MB_NA,0}, {MB_NA,0} },
122 { {MB_CURR,6}, {MB_CURR,7}, {MB_NA,0}, {MB_NA,0} },
123 { {MB_CURR,6}, {MB_CURR,7}, {MB_CURR,12}, {MB_CURR,13} } } };
124
125 static const neighbour_t N_C_SUB_PART[4][4][4] = {
126 { { {MB_B,14}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
127 { {MB_B,14}, {MB_NA,4}, {MB_NA,0}, {MB_NA,0} },
128 { {MB_B,11}, {MB_B,14}, {MB_NA,0}, {MB_NA,0} },
129 { {MB_B,11}, {MB_B,14}, {MB_CURR,1}, {MB_NA,4} } },
130
131 { { {MB_C,10}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
132 { {MB_C,10}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
133 { {MB_B,15}, {MB_C,10}, {MB_NA,0}, {MB_NA,0} },
134 { {MB_B,15}, {MB_C,10}, {MB_CURR,5}, {MB_NA,0} } },
135
136 { { {MB_CURR,6}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
137 { {MB_CURR,6}, {MB_NA,12}, {MB_NA,0}, {MB_NA,0} },
138 { {MB_CURR,3}, {MB_CURR,6}, {MB_NA,0}, {MB_NA,0} },
139 { {MB_CURR,3}, {MB_CURR,6}, {MB_CURR,9}, {MB_NA,12} } },
140
141 { { {MB_NA,2}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
142 { {MB_NA,2}, {MB_NA,8}, {MB_NA,0}, {MB_NA,0} },
143 { {MB_CURR,7}, {MB_NA,2}, {MB_NA,0}, {MB_NA,0} },
144 { {MB_CURR,7}, {MB_NA,2}, {MB_CURR,13}, {MB_NA,8} } } };
145
146 static const neighbour_t N_D_SUB_PART[4][4][4] = {
147 { { {MB_D,15}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
148 { {MB_D,15}, {MB_A,5}, {MB_NA,0}, {MB_NA,0} },
149 { {MB_D,15}, {MB_B,10}, {MB_NA,0}, {MB_NA,0} },
150 { {MB_D,15}, {MB_B,10}, {MB_A,5}, {MB_CURR,0} } },
151
152 { { {MB_B,11}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
153 { {MB_B,11}, {MB_CURR,1}, {MB_NA,0}, {MB_NA,0} },
154 { {MB_B,11}, {MB_B,14}, {MB_NA,0}, {MB_NA,0} },
155 { {MB_B,11}, {MB_B,14}, {MB_CURR,1}, {MB_CURR,4} } },
156
157 { { {MB_A,7}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
158 { {MB_A,7}, {MB_A,13}, {MB_NA,0}, {MB_NA,0} },
159 { {MB_A,7}, {MB_CURR,2}, {MB_NA,0}, {MB_NA,0} },
160 { {MB_A,7}, {MB_CURR,2}, {MB_A,13}, {MB_CURR,8} } },
161
162 { { {MB_CURR,3}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
163 { {MB_CURR,3}, {MB_CURR,9}, {MB_NA,0}, {MB_NA,0} },
164 { {MB_CURR,3}, {MB_CURR,6}, {MB_NA,0}, {MB_NA,0} },
165 { {MB_CURR,3}, {MB_CURR,6}, {MB_CURR,9}, {MB_CURR,12} } } };
166
167
168 #ifdef H264DEC_OMXDL
169
170 /*------------------------------------------------------------------------------
171
172 Function: h264bsdInterPrediction
173
174 Functional description:
175 Processes one inter macroblock. Performs motion vector prediction
176 and reconstructs prediction macroblock. Writes the final macroblock
177 (prediction + residual) into the output image (currImage)
178
179 Inputs:
180 pMb pointer to macroblock specific information
181 pMbLayer pointer to current macroblock data from stream
182 dpb pointer to decoded picture buffer
183 mbNum current macroblock number
184 currImage pointer to output image
185 data pointer where predicted macroblock will be stored
186
187 Outputs:
188 pMb structure is updated with current macroblock
189 currImage current macroblock is written into image
190 data prediction is stored here
191
192 Returns:
193 HANTRO_OK success
194 HANTRO_NOK error in motion vector prediction
195
196 ------------------------------------------------------------------------------*/
h264bsdInterPrediction(mbStorage_t * pMb,macroblockLayer_t * pMbLayer,dpbStorage_t * dpb,u32 mbNum,image_t * currImage,u8 * data)197 u32 h264bsdInterPrediction(mbStorage_t *pMb, macroblockLayer_t *pMbLayer,
198 dpbStorage_t *dpb, u32 mbNum, image_t *currImage, u8 *data)
199 {
200
201 /* Variables */
202
203 u32 i;
204 u32 x, y;
205 u32 colAndRow;
206 subMbPartMode_e subPartMode;
207 image_t refImage;
208 u8 fillBuff[32*21 + 15 + 32];
209 u8 *pFill;
210 u32 tmp;
211 /* Code */
212
213 ASSERT(pMb);
214 ASSERT(h264bsdMbPartPredMode(pMb->mbType) == PRED_MODE_INTER);
215 ASSERT(pMbLayer);
216
217 /* 16-byte alignment */
218 pFill = ALIGN(fillBuff, 16);
219
220 /* set row bits 15:0 */
221 colAndRow = mbNum / currImage->width;
222 /*set col to bits 31:16 */
223 colAndRow += (mbNum - colAndRow * currImage->width) << 16;
224 colAndRow <<= 4;
225
226 refImage.width = currImage->width;
227 refImage.height = currImage->height;
228
229 switch (pMb->mbType)
230 {
231 case P_Skip:
232 case P_L0_16x16:
233 if (MvPrediction16x16(pMb, &pMbLayer->mbPred, dpb) != HANTRO_OK)
234 return(HANTRO_NOK);
235 refImage.data = pMb->refAddr[0];
236 tmp = (0<<24) + (0<<16) + (16<<8) + 16;
237 h264bsdPredictSamples(data, pMb->mv, &refImage,
238 colAndRow, tmp, pFill);
239 break;
240
241 case P_L0_L0_16x8:
242 if ( MvPrediction16x8(pMb, &pMbLayer->mbPred, dpb) != HANTRO_OK)
243 return(HANTRO_NOK);
244 refImage.data = pMb->refAddr[0];
245 tmp = (0<<24) + (0<<16) + (16<<8) + 8;
246 h264bsdPredictSamples(data, pMb->mv, &refImage,
247 colAndRow, tmp, pFill);
248
249 refImage.data = pMb->refAddr[2];
250 tmp = (0<<24) + (8<<16) + (16<<8) + 8;
251 h264bsdPredictSamples(data, pMb->mv+8, &refImage,
252 colAndRow, tmp, pFill);
253 break;
254
255 case P_L0_L0_8x16:
256 if ( MvPrediction8x16(pMb, &pMbLayer->mbPred, dpb) != HANTRO_OK)
257 return(HANTRO_NOK);
258 refImage.data = pMb->refAddr[0];
259 tmp = (0<<24) + (0<<16) + (8<<8) + 16;
260 h264bsdPredictSamples(data, pMb->mv, &refImage,
261 colAndRow, tmp, pFill);
262 refImage.data = pMb->refAddr[1];
263 tmp = (8<<24) + (0<<16) + (8<<8) + 16;
264 h264bsdPredictSamples(data, pMb->mv+4, &refImage,
265 colAndRow, tmp, pFill);
266 break;
267
268 default: /* P_8x8 and P_8x8ref0 */
269 if ( MvPrediction8x8(pMb, &pMbLayer->subMbPred, dpb) != HANTRO_OK)
270 return(HANTRO_NOK);
271 for (i = 0; i < 4; i++)
272 {
273 refImage.data = pMb->refAddr[i];
274 subPartMode =
275 h264bsdSubMbPartMode(pMbLayer->subMbPred.subMbType[i]);
276 x = i & 0x1 ? 8 : 0;
277 y = i < 2 ? 0 : 8;
278 switch (subPartMode)
279 {
280 case MB_SP_8x8:
281 tmp = (x<<24) + (y<<16) + (8<<8) + 8;
282 h264bsdPredictSamples(data, pMb->mv+4*i, &refImage,
283 colAndRow, tmp, pFill);
284 break;
285
286 case MB_SP_8x4:
287 tmp = (x<<24) + (y<<16) + (8<<8) + 4;
288 h264bsdPredictSamples(data, pMb->mv+4*i, &refImage,
289 colAndRow, tmp, pFill);
290 tmp = (x<<24) + ((y+4)<<16) + (8<<8) + 4;
291 h264bsdPredictSamples(data, pMb->mv+4*i+2, &refImage,
292 colAndRow, tmp, pFill);
293 break;
294
295 case MB_SP_4x8:
296 tmp = (x<<24) + (y<<16) + (4<<8) + 8;
297 h264bsdPredictSamples(data, pMb->mv+4*i, &refImage,
298 colAndRow, tmp, pFill);
299 tmp = ((x+4)<<24) + (y<<16) + (4<<8) + 8;
300 h264bsdPredictSamples(data, pMb->mv+4*i+1, &refImage,
301 colAndRow, tmp, pFill);
302 break;
303
304 default:
305 tmp = (x<<24) + (y<<16) + (4<<8) + 4;
306 h264bsdPredictSamples(data, pMb->mv+4*i, &refImage,
307 colAndRow, tmp, pFill);
308 tmp = ((x+4)<<24) + (y<<16) + (4<<8) + 4;
309 h264bsdPredictSamples(data, pMb->mv+4*i+1, &refImage,
310 colAndRow, tmp, pFill);
311 tmp = (x<<24) + ((y+4)<<16) + (4<<8) + 4;
312 h264bsdPredictSamples(data, pMb->mv+4*i+2, &refImage,
313 colAndRow, tmp, pFill);
314 tmp = ((x+4)<<24) + ((y+4)<<16) + (4<<8) + 4;
315 h264bsdPredictSamples(data, pMb->mv+4*i+3, &refImage,
316 colAndRow, tmp, pFill);
317 break;
318 }
319 }
320 break;
321 }
322
323 /* if decoded flag > 1 -> mb has already been successfully decoded and
324 * written to output -> do not write again */
325 if (pMb->decoded > 1)
326 return HANTRO_OK;
327
328 return(HANTRO_OK);
329 }
330
331 #else /* H264DEC_OMXDL */
332
333 /*------------------------------------------------------------------------------
334
335 Function: h264bsdInterPrediction
336
337 Functional description:
338 Processes one inter macroblock. Performs motion vector prediction
339 and reconstructs prediction macroblock. Writes the final macroblock
340 (prediction + residual) into the output image (currImage)
341
342 Inputs:
343 pMb pointer to macroblock specific information
344 pMbLayer pointer to current macroblock data from stream
345 dpb pointer to decoded picture buffer
346 mbNum current macroblock number
347 currImage pointer to output image
348 data pointer where predicted macroblock will be stored
349
350 Outputs:
351 pMb structure is updated with current macroblock
352 currImage current macroblock is written into image
353 data prediction is stored here
354
355 Returns:
356 HANTRO_OK success
357 HANTRO_NOK error in motion vector prediction
358
359 ------------------------------------------------------------------------------*/
h264bsdInterPrediction(mbStorage_t * pMb,macroblockLayer_t * pMbLayer,dpbStorage_t * dpb,u32 mbNum,image_t * currImage,u8 * data)360 u32 h264bsdInterPrediction(mbStorage_t *pMb, macroblockLayer_t *pMbLayer,
361 dpbStorage_t *dpb, u32 mbNum, image_t *currImage, u8 *data)
362 {
363
364 /* Variables */
365
366 u32 i;
367 u32 x, y;
368 u32 row, col;
369 subMbPartMode_e subPartMode;
370 image_t refImage;
371
372 /* Code */
373
374 ASSERT(pMb);
375 ASSERT(h264bsdMbPartPredMode(pMb->mbType) == PRED_MODE_INTER);
376 ASSERT(pMbLayer);
377
378 row = mbNum / currImage->width;
379 col = mbNum - row * currImage->width;
380 row *= 16;
381 col *= 16;
382
383 refImage.width = currImage->width;
384 refImage.height = currImage->height;
385
386 switch (pMb->mbType)
387 {
388 case P_Skip:
389 case P_L0_16x16:
390 if (MvPrediction16x16(pMb, &pMbLayer->mbPred, dpb) != HANTRO_OK)
391 return(HANTRO_NOK);
392 refImage.data = pMb->refAddr[0];
393 h264bsdPredictSamples(data, pMb->mv, &refImage, col, row, 0, 0,
394 16, 16);
395 break;
396
397 case P_L0_L0_16x8:
398 if ( MvPrediction16x8(pMb, &pMbLayer->mbPred, dpb) != HANTRO_OK)
399 return(HANTRO_NOK);
400 refImage.data = pMb->refAddr[0];
401 h264bsdPredictSamples(data, pMb->mv, &refImage, col, row, 0, 0,
402 16, 8);
403 refImage.data = pMb->refAddr[2];
404 h264bsdPredictSamples(data, pMb->mv+8, &refImage, col, row, 0, 8,
405 16, 8);
406 break;
407
408 case P_L0_L0_8x16:
409 if ( MvPrediction8x16(pMb, &pMbLayer->mbPred, dpb) != HANTRO_OK)
410 return(HANTRO_NOK);
411 refImage.data = pMb->refAddr[0];
412 h264bsdPredictSamples(data, pMb->mv, &refImage, col, row, 0, 0,
413 8, 16);
414 refImage.data = pMb->refAddr[1];
415 h264bsdPredictSamples(data, pMb->mv+4, &refImage, col, row, 8, 0,
416 8, 16);
417 break;
418
419 default: /* P_8x8 and P_8x8ref0 */
420 if ( MvPrediction8x8(pMb, &pMbLayer->subMbPred, dpb) != HANTRO_OK)
421 return(HANTRO_NOK);
422 for (i = 0; i < 4; i++)
423 {
424 refImage.data = pMb->refAddr[i];
425 subPartMode =
426 h264bsdSubMbPartMode(pMbLayer->subMbPred.subMbType[i]);
427 x = i & 0x1 ? 8 : 0;
428 y = i < 2 ? 0 : 8;
429 switch (subPartMode)
430 {
431 case MB_SP_8x8:
432 h264bsdPredictSamples(data, pMb->mv+4*i, &refImage,
433 col, row, x, y, 8, 8);
434 break;
435
436 case MB_SP_8x4:
437 h264bsdPredictSamples(data, pMb->mv+4*i, &refImage,
438 col, row, x, y, 8, 4);
439 h264bsdPredictSamples(data, pMb->mv+4*i+2, &refImage,
440 col, row, x, y+4, 8, 4);
441 break;
442
443 case MB_SP_4x8:
444 h264bsdPredictSamples(data, pMb->mv+4*i, &refImage,
445 col, row, x, y, 4, 8);
446 h264bsdPredictSamples(data, pMb->mv+4*i+1, &refImage,
447 col, row, x+4, y, 4, 8);
448 break;
449
450 default:
451 h264bsdPredictSamples(data, pMb->mv+4*i, &refImage,
452 col, row, x, y, 4, 4);
453 h264bsdPredictSamples(data, pMb->mv+4*i+1, &refImage,
454 col, row, x+4, y, 4, 4);
455 h264bsdPredictSamples(data, pMb->mv+4*i+2, &refImage,
456 col, row, x, y+4, 4, 4);
457 h264bsdPredictSamples(data, pMb->mv+4*i+3, &refImage,
458 col, row, x+4, y+4, 4, 4);
459 break;
460 }
461 }
462 break;
463 }
464
465 /* if decoded flag > 1 -> mb has already been successfully decoded and
466 * written to output -> do not write again */
467 if (pMb->decoded > 1)
468 return HANTRO_OK;
469
470 if (pMb->mbType != P_Skip)
471 {
472 h264bsdWriteOutputBlocks(currImage, mbNum, data,
473 pMbLayer->residual.level);
474 }
475 else
476 {
477 h264bsdWriteMacroblock(currImage, data);
478 }
479
480 return(HANTRO_OK);
481 }
482 #endif /* H264DEC_OMXDL */
483
484 /*------------------------------------------------------------------------------
485
486 Function: MvPrediction16x16
487
488 Functional description:
489 Motion vector prediction for 16x16 partition mode
490
491 ------------------------------------------------------------------------------*/
492
MvPrediction16x16(mbStorage_t * pMb,mbPred_t * mbPred,dpbStorage_t * dpb)493 u32 MvPrediction16x16(mbStorage_t *pMb, mbPred_t *mbPred, dpbStorage_t *dpb)
494 {
495
496 /* Variables */
497
498 mv_t mv;
499 mv_t mvPred;
500 interNeighbour_t a[3]; /* A, B, C */
501 u32 refIndex;
502 u8 *tmp;
503 u32 *tmpMv1, *tmpMv2;
504
505 /* Code */
506
507 refIndex = mbPred->refIdxL0[0];
508
509 GetInterNeighbour(pMb->sliceId, pMb->mbA, a, 5);
510 GetInterNeighbour(pMb->sliceId, pMb->mbB, a+1, 10);
511 /*lint --e(740) Unusual pointer cast (incompatible indirect types) */
512 tmpMv1 = (u32*)(&a[0].mv); /* we test just that both MVs are zero */
513 /*lint --e(740) */
514 tmpMv2 = (u32*)(&a[1].mv); /* i.e. a[0].mv.hor == 0 && a[0].mv.ver == 0 */
515 if (pMb->mbType == P_Skip &&
516 (!a[0].available || !a[1].available ||
517 ( a[0].refIndex == 0 && ((u32)(*tmpMv1) == 0) ) ||
518 ( a[1].refIndex == 0 && ((u32)(*tmpMv2) == 0) )))
519 {
520 mv.hor = mv.ver = 0;
521 }
522 else
523 {
524 mv = mbPred->mvdL0[0];
525 GetInterNeighbour(pMb->sliceId, pMb->mbC, a+2, 10);
526 if (!a[2].available)
527 {
528 GetInterNeighbour(pMb->sliceId, pMb->mbD, a+2, 15);
529 }
530
531 GetPredictionMv(&mvPred, a, refIndex);
532
533 mv.hor += mvPred.hor;
534 mv.ver += mvPred.ver;
535
536 /* horizontal motion vector range [-2048, 2047.75] */
537 if ((u32)(i32)(mv.hor+8192) >= (16384))
538 return(HANTRO_NOK);
539
540 /* vertical motion vector range [-512, 511.75]
541 * (smaller for low levels) */
542 if ((u32)(i32)(mv.ver+2048) >= (4096))
543 return(HANTRO_NOK);
544 }
545
546 tmp = h264bsdGetRefPicData(dpb, refIndex);
547 if (tmp == NULL)
548 return(HANTRO_NOK);
549
550 pMb->mv[0] = pMb->mv[1] = pMb->mv[2] = pMb->mv[3] =
551 pMb->mv[4] = pMb->mv[5] = pMb->mv[6] = pMb->mv[7] =
552 pMb->mv[8] = pMb->mv[9] = pMb->mv[10] = pMb->mv[11] =
553 pMb->mv[12] = pMb->mv[13] = pMb->mv[14] = pMb->mv[15] = mv;
554
555 pMb->refPic[0] = refIndex;
556 pMb->refPic[1] = refIndex;
557 pMb->refPic[2] = refIndex;
558 pMb->refPic[3] = refIndex;
559 pMb->refAddr[0] = tmp;
560 pMb->refAddr[1] = tmp;
561 pMb->refAddr[2] = tmp;
562 pMb->refAddr[3] = tmp;
563
564 return(HANTRO_OK);
565
566 }
567
568 /*------------------------------------------------------------------------------
569
570 Function: MvPrediction16x8
571
572 Functional description:
573 Motion vector prediction for 16x8 partition mode
574
575 ------------------------------------------------------------------------------*/
576
MvPrediction16x8(mbStorage_t * pMb,mbPred_t * mbPred,dpbStorage_t * dpb)577 u32 MvPrediction16x8(mbStorage_t *pMb, mbPred_t *mbPred, dpbStorage_t *dpb)
578 {
579
580 /* Variables */
581
582 mv_t mv;
583 mv_t mvPred;
584 interNeighbour_t a[3]; /* A, B, C */
585 u32 refIndex;
586 u8 *tmp;
587
588 /* Code */
589
590 mv = mbPred->mvdL0[0];
591 refIndex = mbPred->refIdxL0[0];
592
593 GetInterNeighbour(pMb->sliceId, pMb->mbB, a+1, 10);
594
595 if (a[1].refIndex == refIndex)
596 mvPred = a[1].mv;
597 else
598 {
599 GetInterNeighbour(pMb->sliceId, pMb->mbA, a, 5);
600 GetInterNeighbour(pMb->sliceId, pMb->mbC, a+2, 10);
601 if (!a[2].available)
602 {
603 GetInterNeighbour(pMb->sliceId, pMb->mbD, a+2, 15);
604 }
605
606 GetPredictionMv(&mvPred, a, refIndex);
607
608 }
609 mv.hor += mvPred.hor;
610 mv.ver += mvPred.ver;
611
612 /* horizontal motion vector range [-2048, 2047.75] */
613 if ((u32)(i32)(mv.hor+8192) >= (16384))
614 return(HANTRO_NOK);
615
616 /* vertical motion vector range [-512, 511.75] (smaller for low levels) */
617 if ((u32)(i32)(mv.ver+2048) >= (4096))
618 return(HANTRO_NOK);
619
620 tmp = h264bsdGetRefPicData(dpb, refIndex);
621 if (tmp == NULL)
622 return(HANTRO_NOK);
623
624 pMb->mv[0] = pMb->mv[1] = pMb->mv[2] = pMb->mv[3] =
625 pMb->mv[4] = pMb->mv[5] = pMb->mv[6] = pMb->mv[7] = mv;
626 pMb->refPic[0] = refIndex;
627 pMb->refPic[1] = refIndex;
628 pMb->refAddr[0] = tmp;
629 pMb->refAddr[1] = tmp;
630
631 mv = mbPred->mvdL0[1];
632 refIndex = mbPred->refIdxL0[1];
633
634 GetInterNeighbour(pMb->sliceId, pMb->mbA, a, 13);
635 if (a[0].refIndex == refIndex)
636 mvPred = a[0].mv;
637 else
638 {
639 a[1].available = HANTRO_TRUE;
640 a[1].refIndex = pMb->refPic[0];
641 a[1].mv = pMb->mv[0];
642
643 /* c is not available */
644 GetInterNeighbour(pMb->sliceId, pMb->mbA, a+2, 7);
645
646 GetPredictionMv(&mvPred, a, refIndex);
647
648 }
649 mv.hor += mvPred.hor;
650 mv.ver += mvPred.ver;
651
652 /* horizontal motion vector range [-2048, 2047.75] */
653 if ((u32)(i32)(mv.hor+8192) >= (16384))
654 return(HANTRO_NOK);
655
656 /* vertical motion vector range [-512, 511.75] (smaller for low levels) */
657 if ((u32)(i32)(mv.ver+2048) >= (4096))
658 return(HANTRO_NOK);
659
660 tmp = h264bsdGetRefPicData(dpb, refIndex);
661 if (tmp == NULL)
662 return(HANTRO_NOK);
663
664 pMb->mv[8] = pMb->mv[9] = pMb->mv[10] = pMb->mv[11] =
665 pMb->mv[12] = pMb->mv[13] = pMb->mv[14] = pMb->mv[15] = mv;
666 pMb->refPic[2] = refIndex;
667 pMb->refPic[3] = refIndex;
668 pMb->refAddr[2] = tmp;
669 pMb->refAddr[3] = tmp;
670
671 return(HANTRO_OK);
672
673 }
674
675 /*------------------------------------------------------------------------------
676
677 Function: MvPrediction8x16
678
679 Functional description:
680 Motion vector prediction for 8x16 partition mode
681
682 ------------------------------------------------------------------------------*/
683
MvPrediction8x16(mbStorage_t * pMb,mbPred_t * mbPred,dpbStorage_t * dpb)684 u32 MvPrediction8x16(mbStorage_t *pMb, mbPred_t *mbPred, dpbStorage_t *dpb)
685 {
686
687 /* Variables */
688
689 mv_t mv;
690 mv_t mvPred;
691 interNeighbour_t a[3]; /* A, B, C */
692 u32 refIndex;
693 u8 *tmp;
694
695 /* Code */
696
697 mv = mbPred->mvdL0[0];
698 refIndex = mbPred->refIdxL0[0];
699
700 GetInterNeighbour(pMb->sliceId, pMb->mbA, a, 5);
701
702 if (a[0].refIndex == refIndex)
703 mvPred = a[0].mv;
704 else
705 {
706 GetInterNeighbour(pMb->sliceId, pMb->mbB, a+1, 10);
707 GetInterNeighbour(pMb->sliceId, pMb->mbB, a+2, 14);
708 if (!a[2].available)
709 {
710 GetInterNeighbour(pMb->sliceId, pMb->mbD, a+2, 15);
711 }
712
713 GetPredictionMv(&mvPred, a, refIndex);
714
715 }
716 mv.hor += mvPred.hor;
717 mv.ver += mvPred.ver;
718
719 /* horizontal motion vector range [-2048, 2047.75] */
720 if ((u32)(i32)(mv.hor+8192) >= (16384))
721 return(HANTRO_NOK);
722
723 /* vertical motion vector range [-512, 511.75] (smaller for low levels) */
724 if ((u32)(i32)(mv.ver+2048) >= (4096))
725 return(HANTRO_NOK);
726
727 tmp = h264bsdGetRefPicData(dpb, refIndex);
728 if (tmp == NULL)
729 return(HANTRO_NOK);
730
731 pMb->mv[0] = pMb->mv[1] = pMb->mv[2] = pMb->mv[3] =
732 pMb->mv[8] = pMb->mv[9] = pMb->mv[10] = pMb->mv[11] = mv;
733 pMb->refPic[0] = refIndex;
734 pMb->refPic[2] = refIndex;
735 pMb->refAddr[0] = tmp;
736 pMb->refAddr[2] = tmp;
737
738 mv = mbPred->mvdL0[1];
739 refIndex = mbPred->refIdxL0[1];
740
741 GetInterNeighbour(pMb->sliceId, pMb->mbC, a+2, 10);
742 if (!a[2].available)
743 {
744 GetInterNeighbour(pMb->sliceId, pMb->mbB, a+2, 11);
745 }
746 if (a[2].refIndex == refIndex)
747 mvPred = a[2].mv;
748 else
749 {
750 a[0].available = HANTRO_TRUE;
751 a[0].refIndex = pMb->refPic[0];
752 a[0].mv = pMb->mv[0];
753
754 GetInterNeighbour(pMb->sliceId, pMb->mbB, a+1, 14);
755
756 GetPredictionMv(&mvPred, a, refIndex);
757
758 }
759 mv.hor += mvPred.hor;
760 mv.ver += mvPred.ver;
761
762 /* horizontal motion vector range [-2048, 2047.75] */
763 if ((u32)(i32)(mv.hor+8192) >= (16384))
764 return(HANTRO_NOK);
765
766 /* vertical motion vector range [-512, 511.75] (smaller for low levels) */
767 if ((u32)(i32)(mv.ver+2048) >= (4096))
768 return(HANTRO_NOK);
769
770 tmp = h264bsdGetRefPicData(dpb, refIndex);
771 if (tmp == NULL)
772 return(HANTRO_NOK);
773
774 pMb->mv[4] = pMb->mv[5] = pMb->mv[6] = pMb->mv[7] =
775 pMb->mv[12] = pMb->mv[13] = pMb->mv[14] = pMb->mv[15] = mv;
776 pMb->refPic[1] = refIndex;
777 pMb->refPic[3] = refIndex;
778 pMb->refAddr[1] = tmp;
779 pMb->refAddr[3] = tmp;
780
781 return(HANTRO_OK);
782
783 }
784
785 /*------------------------------------------------------------------------------
786
787 Function: MvPrediction8x8
788
789 Functional description:
790 Motion vector prediction for 8x8 partition mode
791
792 ------------------------------------------------------------------------------*/
793
MvPrediction8x8(mbStorage_t * pMb,subMbPred_t * subMbPred,dpbStorage_t * dpb)794 u32 MvPrediction8x8(mbStorage_t *pMb, subMbPred_t *subMbPred, dpbStorage_t *dpb)
795 {
796
797 /* Variables */
798
799 u32 i, j;
800 u32 numSubMbPart;
801
802 /* Code */
803
804 for (i = 0; i < 4; i++)
805 {
806 numSubMbPart = h264bsdNumSubMbPart(subMbPred->subMbType[i]);
807 pMb->refPic[i] = subMbPred->refIdxL0[i];
808 pMb->refAddr[i] = h264bsdGetRefPicData(dpb, subMbPred->refIdxL0[i]);
809 if (pMb->refAddr[i] == NULL)
810 return(HANTRO_NOK);
811 for (j = 0; j < numSubMbPart; j++)
812 {
813 if (MvPrediction(pMb, subMbPred, i, j) != HANTRO_OK)
814 return(HANTRO_NOK);
815 }
816 }
817
818 return(HANTRO_OK);
819
820 }
821
822 /*------------------------------------------------------------------------------
823
824 Function: MvPrediction
825
826 Functional description:
827 Perform motion vector prediction for sub-partition
828
829 ------------------------------------------------------------------------------*/
830
MvPrediction(mbStorage_t * pMb,subMbPred_t * subMbPred,u32 mbPartIdx,u32 subMbPartIdx)831 u32 MvPrediction(mbStorage_t *pMb, subMbPred_t *subMbPred, u32 mbPartIdx,
832 u32 subMbPartIdx)
833 {
834
835 /* Variables */
836
837 mv_t mv, mvPred;
838 u32 refIndex;
839 subMbPartMode_e subMbPartMode;
840 const neighbour_t *n;
841 mbStorage_t *nMb;
842 interNeighbour_t a[3]; /* A, B, C */
843
844 /* Code */
845
846 mv = subMbPred->mvdL0[mbPartIdx][subMbPartIdx];
847 subMbPartMode = h264bsdSubMbPartMode(subMbPred->subMbType[mbPartIdx]);
848 refIndex = subMbPred->refIdxL0[mbPartIdx];
849
850 n = N_A_SUB_PART[mbPartIdx][subMbPartMode]+subMbPartIdx;
851 nMb = h264bsdGetNeighbourMb(pMb, n->mb);
852 GetInterNeighbour(pMb->sliceId, nMb, a, n->index);
853
854 n = N_B_SUB_PART[mbPartIdx][subMbPartMode]+subMbPartIdx;
855 nMb = h264bsdGetNeighbourMb(pMb, n->mb);
856 GetInterNeighbour(pMb->sliceId, nMb, a+1, n->index);
857
858 n = N_C_SUB_PART[mbPartIdx][subMbPartMode]+subMbPartIdx;
859 nMb = h264bsdGetNeighbourMb(pMb, n->mb);
860 GetInterNeighbour(pMb->sliceId, nMb, a+2, n->index);
861
862 if (!a[2].available)
863 {
864 n = N_D_SUB_PART[mbPartIdx][subMbPartMode]+subMbPartIdx;
865 nMb = h264bsdGetNeighbourMb(pMb, n->mb);
866 GetInterNeighbour(pMb->sliceId, nMb, a+2, n->index);
867 }
868
869 GetPredictionMv(&mvPred, a, refIndex);
870
871 mv.hor += mvPred.hor;
872 mv.ver += mvPred.ver;
873
874 /* horizontal motion vector range [-2048, 2047.75] */
875 if (((u32)(i32)(mv.hor+8192) >= (16384)))
876 return(HANTRO_NOK);
877
878 /* vertical motion vector range [-512, 511.75] (smaller for low levels) */
879 if (((u32)(i32)(mv.ver+2048) >= (4096)))
880 return(HANTRO_NOK);
881
882 switch (subMbPartMode)
883 {
884 case MB_SP_8x8:
885 pMb->mv[4*mbPartIdx] = mv;
886 pMb->mv[4*mbPartIdx + 1] = mv;
887 pMb->mv[4*mbPartIdx + 2] = mv;
888 pMb->mv[4*mbPartIdx + 3] = mv;
889 break;
890
891 case MB_SP_8x4:
892 pMb->mv[4*mbPartIdx + 2*subMbPartIdx] = mv;
893 pMb->mv[4*mbPartIdx + 2*subMbPartIdx + 1] = mv;
894 break;
895
896 case MB_SP_4x8:
897 pMb->mv[4*mbPartIdx + subMbPartIdx] = mv;
898 pMb->mv[4*mbPartIdx + subMbPartIdx + 2] = mv;
899 break;
900
901 case MB_SP_4x4:
902 pMb->mv[4*mbPartIdx + subMbPartIdx] = mv;
903 break;
904 }
905
906 return(HANTRO_OK);
907
908 }
909
910 /*------------------------------------------------------------------------------
911
912 Function: MedianFilter
913
914 Functional description:
915 Median filtering for motion vector prediction
916
917 ------------------------------------------------------------------------------*/
918
MedianFilter(i32 a,i32 b,i32 c)919 i32 MedianFilter(i32 a, i32 b, i32 c)
920 {
921
922 /* Variables */
923
924 i32 max,min,med;
925
926 /* Code */
927
928 max = min = med = a;
929 if (b > max)
930 {
931 max = b;
932 }
933 else if (b < min)
934 {
935 min = b;
936 }
937 if (c > max)
938 {
939 med = max;
940 }
941 else if (c < min)
942 {
943 med = min;
944 }
945 else
946 {
947 med = c;
948 }
949
950 return(med);
951 }
952
953 /*------------------------------------------------------------------------------
954
955 Function: GetInterNeighbour
956
957 Functional description:
958 Get availability, reference index and motion vector of a neighbour
959
960 ------------------------------------------------------------------------------*/
961
GetInterNeighbour(u32 sliceId,mbStorage_t * nMb,interNeighbour_t * n,u32 index)962 void GetInterNeighbour(u32 sliceId, mbStorage_t *nMb,
963 interNeighbour_t *n, u32 index)
964 {
965
966 n->available = HANTRO_FALSE;
967 n->refIndex = 0xFFFFFFFF;
968 n->mv.hor = n->mv.ver = 0;
969
970 if (nMb && (sliceId == nMb->sliceId))
971 {
972 u32 tmp;
973 mv_t tmpMv;
974
975 tmp = nMb->mbType;
976 n->available = HANTRO_TRUE;
977 /* MbPartPredMode "inlined" */
978 if (tmp <= P_8x8ref0)
979 {
980 tmpMv = nMb->mv[index];
981 tmp = nMb->refPic[index>>2];
982 n->refIndex = tmp;
983 n->mv = tmpMv;
984 }
985 }
986
987 }
988
989 /*------------------------------------------------------------------------------
990
991 Function: GetPredictionMv
992
993 Functional description:
994 Compute motion vector predictor based on neighbours A, B and C
995
996 ------------------------------------------------------------------------------*/
997
GetPredictionMv(mv_t * mv,interNeighbour_t * a,u32 refIndex)998 void GetPredictionMv(mv_t *mv, interNeighbour_t *a, u32 refIndex)
999 {
1000
1001 if ( a[1].available || a[2].available || !a[0].available)
1002 {
1003 u32 isA, isB, isC;
1004 isA = (a[0].refIndex == refIndex) ? HANTRO_TRUE : HANTRO_FALSE;
1005 isB = (a[1].refIndex == refIndex) ? HANTRO_TRUE : HANTRO_FALSE;
1006 isC = (a[2].refIndex == refIndex) ? HANTRO_TRUE : HANTRO_FALSE;
1007
1008 if (((u32)isA+(u32)isB+(u32)isC) != 1)
1009 {
1010 mv->hor = (i16)MedianFilter(a[0].mv.hor, a[1].mv.hor, a[2].mv.hor);
1011 mv->ver = (i16)MedianFilter(a[0].mv.ver, a[1].mv.ver, a[2].mv.ver);
1012 }
1013 else if (isA)
1014 *mv = a[0].mv;
1015 else if (isB)
1016 *mv = a[1].mv;
1017 else
1018 *mv = a[2].mv;
1019 }
1020 else
1021 {
1022 *mv = a[0].mv;
1023 }
1024
1025 }
1026
1027
1028