• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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