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           DecodeInterleavedMap
27           DecodeDispersedMap
28           DecodeForegroundLeftOverMap
29           DecodeBoxOutMap
30           DecodeRasterScanMap
31           DecodeWipeMap
32           h264bsdDecodeSliceGroupMap
33 
34 ------------------------------------------------------------------------------*/
35 
36 /*------------------------------------------------------------------------------
37     1. Include headers
38 ------------------------------------------------------------------------------*/
39 
40 #include "basetype.h"
41 #include "h264bsd_slice_group_map.h"
42 #include "h264bsd_cfg.h"
43 #include "h264bsd_pic_param_set.h"
44 #include "h264bsd_util.h"
45 
46 /*------------------------------------------------------------------------------
47     2. External compiler flags
48 --------------------------------------------------------------------------------
49 
50 --------------------------------------------------------------------------------
51     3. Module defines
52 ------------------------------------------------------------------------------*/
53 
54 /*------------------------------------------------------------------------------
55     4. Local function prototypes
56 ------------------------------------------------------------------------------*/
57 
58 static void DecodeInterleavedMap(
59   u32 *map,
60   u32 numSliceGroups,
61   u32 *runLength,
62   u32 picSize);
63 
64 static void DecodeDispersedMap(
65   u32 *map,
66   u32 numSliceGroups,
67   u32 picWidth,
68   u32 picHeight);
69 
70 static void DecodeForegroundLeftOverMap(
71   u32 *map,
72   u32 numSliceGroups,
73   u32 *topLeft,
74   u32 *bottomRight,
75   u32 picWidth,
76   u32 picHeight);
77 
78 static void DecodeBoxOutMap(
79   u32 *map,
80   u32 sliceGroupChangeDirectionFlag,
81   u32 unitsInSliceGroup0,
82   u32 picWidth,
83   u32 picHeight);
84 
85 static void DecodeRasterScanMap(
86   u32 *map,
87   u32 sliceGroupChangeDirectionFlag,
88   u32 sizeOfUpperLeftGroup,
89   u32 picSize);
90 
91 static void DecodeWipeMap(
92   u32 *map,
93   u32 sliceGroupChangeDirectionFlag,
94   u32 sizeOfUpperLeftGroup,
95   u32 picWidth,
96   u32 picHeight);
97 
98 /*------------------------------------------------------------------------------
99 
100     Function: DecodeInterleavedMap
101 
102         Functional description:
103             Function to decode interleaved slice group map type, i.e. slice
104             group map type 0.
105 
106         Inputs:
107             map             pointer to the map
108             numSliceGroups  number of slice groups
109             runLength       run_length[] values for each slice group
110             picSize         picture size in macroblocks
111 
112         Outputs:
113             map             slice group map is stored here
114 
115         Returns:
116             none
117 
118 ------------------------------------------------------------------------------*/
119 
DecodeInterleavedMap(u32 * map,u32 numSliceGroups,u32 * runLength,u32 picSize)120 void DecodeInterleavedMap(
121   u32 *map,
122   u32 numSliceGroups,
123   u32 *runLength,
124   u32 picSize)
125 {
126 
127 /* Variables */
128 
129     u32 i,j, group;
130 
131 /* Code */
132 
133     ASSERT(map);
134     ASSERT(numSliceGroups >= 1 && numSliceGroups <= MAX_NUM_SLICE_GROUPS);
135     ASSERT(runLength);
136 
137     i = 0;
138 
139     do {
140         for (group = 0; group < numSliceGroups && i < picSize;
141           i += runLength[group++])
142         {
143             ASSERT(runLength[group] <= picSize);
144             for (j = 0; j < runLength[group] && i + j < picSize; j++)
145                 map[i+j] = group;
146         }
147     } while (i < picSize);
148 
149 
150 }
151 
152 /*------------------------------------------------------------------------------
153 
154     Function: DecodeDispersedMap
155 
156         Functional description:
157             Function to decode dispersed slice group map type, i.e. slice
158             group map type 1.
159 
160         Inputs:
161             map               pointer to the map
162             numSliceGroups    number of slice groups
163             picWidth          picture width in macroblocks
164             picHeight         picture height in macroblocks
165 
166         Outputs:
167             map               slice group map is stored here
168 
169         Returns:
170             none
171 
172 ------------------------------------------------------------------------------*/
173 
DecodeDispersedMap(u32 * map,u32 numSliceGroups,u32 picWidth,u32 picHeight)174 void DecodeDispersedMap(
175   u32 *map,
176   u32 numSliceGroups,
177   u32 picWidth,
178   u32 picHeight)
179 {
180 
181 /* Variables */
182 
183     u32 i, picSize;
184 
185 /* Code */
186 
187     ASSERT(map);
188     ASSERT(numSliceGroups >= 1 && numSliceGroups <= MAX_NUM_SLICE_GROUPS);
189     ASSERT(picWidth);
190     ASSERT(picHeight);
191 
192     picSize = picWidth * picHeight;
193 
194     for (i = 0; i < picSize; i++)
195         map[i] = ((i % picWidth) + (((i / picWidth) * numSliceGroups) >> 1)) %
196             numSliceGroups;
197 
198 
199 }
200 
201 /*------------------------------------------------------------------------------
202 
203     Function: DecodeForegroundLeftOverMap
204 
205         Functional description:
206             Function to decode foreground with left-over slice group map type,
207             i.e. slice group map type 2.
208 
209         Inputs:
210             map               pointer to the map
211             numSliceGroups    number of slice groups
212             topLeft           top_left[] values
213             bottomRight       bottom_right[] values
214             picWidth          picture width in macroblocks
215             picHeight         picture height in macroblocks
216 
217         Outputs:
218             map               slice group map is stored here
219 
220         Returns:
221             none
222 
223 ------------------------------------------------------------------------------*/
224 
DecodeForegroundLeftOverMap(u32 * map,u32 numSliceGroups,u32 * topLeft,u32 * bottomRight,u32 picWidth,u32 picHeight)225 void DecodeForegroundLeftOverMap(
226   u32 *map,
227   u32 numSliceGroups,
228   u32 *topLeft,
229   u32 *bottomRight,
230   u32 picWidth,
231   u32 picHeight)
232 {
233 
234 /* Variables */
235 
236     u32 i,y,x,yTopLeft,yBottomRight,xTopLeft,xBottomRight, picSize;
237     u32 group;
238 
239 /* Code */
240 
241     ASSERT(map);
242     ASSERT(numSliceGroups >= 1 && numSliceGroups <= MAX_NUM_SLICE_GROUPS);
243     ASSERT(topLeft);
244     ASSERT(bottomRight);
245     ASSERT(picWidth);
246     ASSERT(picHeight);
247 
248     picSize = picWidth * picHeight;
249 
250     for (i = 0; i < picSize; i++)
251         map[i] = numSliceGroups - 1;
252 
253     for (group = numSliceGroups - 1; group--; )
254     {
255         ASSERT( topLeft[group] <= bottomRight[group] &&
256                 bottomRight[group] < picSize );
257         yTopLeft = topLeft[group] / picWidth;
258         xTopLeft = topLeft[group] % picWidth;
259         yBottomRight = bottomRight[group] / picWidth;
260         xBottomRight = bottomRight[group] % picWidth;
261         ASSERT(xTopLeft <= xBottomRight);
262 
263         for (y = yTopLeft; y <= yBottomRight; y++)
264             for (x = xTopLeft; x <= xBottomRight; x++)
265                 map[ y * picWidth + x ] = group;
266     }
267 
268 
269 }
270 
271 /*------------------------------------------------------------------------------
272 
273     Function: DecodeBoxOutMap
274 
275         Functional description:
276             Function to decode box-out slice group map type, i.e. slice group
277             map type 3.
278 
279         Inputs:
280             map                               pointer to the map
281             sliceGroupChangeDirectionFlag     slice_group_change_direction_flag
282             unitsInSliceGroup0                mbs on slice group 0
283             picWidth                          picture width in macroblocks
284             picHeight                         picture height in macroblocks
285 
286         Outputs:
287             map                               slice group map is stored here
288 
289         Returns:
290             none
291 
292 ------------------------------------------------------------------------------*/
293 
DecodeBoxOutMap(u32 * map,u32 sliceGroupChangeDirectionFlag,u32 unitsInSliceGroup0,u32 picWidth,u32 picHeight)294 void DecodeBoxOutMap(
295   u32 *map,
296   u32 sliceGroupChangeDirectionFlag,
297   u32 unitsInSliceGroup0,
298   u32 picWidth,
299   u32 picHeight)
300 {
301 
302 /* Variables */
303 
304     u32 i, k, picSize;
305     i32 x, y, xDir, yDir, leftBound, topBound, rightBound, bottomBound;
306     u32 mapUnitVacant;
307 
308 /* Code */
309 
310     ASSERT(map);
311     ASSERT(picWidth);
312     ASSERT(picHeight);
313 
314     picSize = picWidth * picHeight;
315     ASSERT(unitsInSliceGroup0 <= picSize);
316 
317     for (i = 0; i < picSize; i++)
318         map[i] = 1;
319 
320     x = (picWidth - (u32)sliceGroupChangeDirectionFlag) >> 1;
321     y = (picHeight - (u32)sliceGroupChangeDirectionFlag) >> 1;
322 
323     leftBound = x;
324     topBound = y;
325 
326     rightBound = x;
327     bottomBound = y;
328 
329     xDir = (i32)sliceGroupChangeDirectionFlag - 1;
330     yDir = (i32)sliceGroupChangeDirectionFlag;
331 
332     for (k = 0; k < unitsInSliceGroup0; k += mapUnitVacant ? 1 : 0)
333     {
334         mapUnitVacant = (map[ (u32)y * picWidth + (u32)x ] == 1) ?
335                                         HANTRO_TRUE : HANTRO_FALSE;
336 
337         if (mapUnitVacant)
338             map[ (u32)y * picWidth + (u32)x ] = 0;
339 
340         if (xDir == -1 && x == leftBound)
341         {
342             leftBound = MAX(leftBound - 1, 0);
343             x = leftBound;
344             xDir = 0;
345             yDir = 2 * (i32)sliceGroupChangeDirectionFlag - 1;
346         }
347         else if (xDir == 1 && x == rightBound)
348         {
349             rightBound = MIN(rightBound + 1, (i32)picWidth - 1);
350             x = rightBound;
351             xDir = 0;
352             yDir = 1 - 2 * (i32)sliceGroupChangeDirectionFlag;
353         }
354         else if (yDir == -1 && y == topBound)
355         {
356             topBound = MAX(topBound - 1, 0);
357             y = topBound;
358             xDir = 1 - 2 * (i32)sliceGroupChangeDirectionFlag;
359             yDir = 0;
360         }
361         else if (yDir == 1 && y == bottomBound)
362         {
363             bottomBound = MIN(bottomBound + 1, (i32)picHeight - 1);
364             y = bottomBound;
365             xDir = 2 * (i32)sliceGroupChangeDirectionFlag - 1;
366             yDir = 0;
367         }
368         else
369         {
370             x += xDir;
371             y += yDir;
372         }
373     }
374 
375 
376 }
377 
378 /*------------------------------------------------------------------------------
379 
380     Function: DecodeRasterScanMap
381 
382         Functional description:
383             Function to decode raster scan slice group map type, i.e. slice
384             group map type 4.
385 
386         Inputs:
387             map                               pointer to the map
388             sliceGroupChangeDirectionFlag     slice_group_change_direction_flag
389             sizeOfUpperLeftGroup              mbs in upperLeftGroup
390             picSize                           picture size in macroblocks
391 
392         Outputs:
393             map                               slice group map is stored here
394 
395         Returns:
396             none
397 
398 ------------------------------------------------------------------------------*/
399 
DecodeRasterScanMap(u32 * map,u32 sliceGroupChangeDirectionFlag,u32 sizeOfUpperLeftGroup,u32 picSize)400 void DecodeRasterScanMap(
401   u32 *map,
402   u32 sliceGroupChangeDirectionFlag,
403   u32 sizeOfUpperLeftGroup,
404   u32 picSize)
405 {
406 
407 /* Variables */
408 
409     u32 i;
410 
411 /* Code */
412 
413     ASSERT(map);
414     ASSERT(picSize);
415     ASSERT(sizeOfUpperLeftGroup <= picSize);
416 
417     for (i = 0; i < picSize; i++)
418         if (i < sizeOfUpperLeftGroup)
419             map[i] = (u32)sliceGroupChangeDirectionFlag;
420         else
421             map[i] = 1 - (u32)sliceGroupChangeDirectionFlag;
422 
423 
424 }
425 
426 /*------------------------------------------------------------------------------
427 
428     Function: DecodeWipeMap
429 
430         Functional description:
431             Function to decode wipe slice group map type, i.e. slice group map
432             type 5.
433 
434         Inputs:
435             sliceGroupChangeDirectionFlag     slice_group_change_direction_flag
436             sizeOfUpperLeftGroup              mbs in upperLeftGroup
437             picWidth                          picture width in macroblocks
438             picHeight                         picture height in macroblocks
439 
440         Outputs:
441             map                               slice group map is stored here
442 
443         Returns:
444             none
445 
446 ------------------------------------------------------------------------------*/
447 
DecodeWipeMap(u32 * map,u32 sliceGroupChangeDirectionFlag,u32 sizeOfUpperLeftGroup,u32 picWidth,u32 picHeight)448 void DecodeWipeMap(
449   u32 *map,
450   u32 sliceGroupChangeDirectionFlag,
451   u32 sizeOfUpperLeftGroup,
452   u32 picWidth,
453   u32 picHeight)
454 {
455 
456 /* Variables */
457 
458     u32 i,j,k;
459 
460 /* Code */
461 
462     ASSERT(map);
463     ASSERT(picWidth);
464     ASSERT(picHeight);
465     ASSERT(sizeOfUpperLeftGroup <= picWidth * picHeight);
466 
467     k = 0;
468     for (j = 0; j < picWidth; j++)
469         for (i = 0; i < picHeight; i++)
470             if (k++ < sizeOfUpperLeftGroup)
471                 map[ i * picWidth + j ] = (u32)sliceGroupChangeDirectionFlag;
472             else
473                 map[ i * picWidth + j ] = 1 -
474                     (u32)sliceGroupChangeDirectionFlag;
475 
476 
477 }
478 
479 /*------------------------------------------------------------------------------
480 
481     Function: h264bsdDecodeSliceGroupMap
482 
483         Functional description:
484             Function to decode macroblock to slice group map. Construction
485             of different slice group map types is handled by separate
486             functions defined above. See standard for details how slice group
487             maps are computed.
488 
489         Inputs:
490             pps                     active picture parameter set
491             sliceGroupChangeCycle   slice_group_change_cycle
492             picWidth                picture width in macroblocks
493             picHeight               picture height in macroblocks
494 
495         Outputs:
496             map                     slice group map is stored here
497 
498         Returns:
499             none
500 
501 ------------------------------------------------------------------------------*/
502 
h264bsdDecodeSliceGroupMap(u32 * map,picParamSet_t * pps,u32 sliceGroupChangeCycle,u32 picWidth,u32 picHeight)503 void h264bsdDecodeSliceGroupMap(
504   u32 *map,
505   picParamSet_t *pps,
506   u32 sliceGroupChangeCycle,
507   u32 picWidth,
508   u32 picHeight)
509 {
510 
511 /* Variables */
512 
513     u32 i, picSize, unitsInSliceGroup0 = 0, sizeOfUpperLeftGroup = 0;
514 
515 /* Code */
516 
517     ASSERT(map);
518     ASSERT(pps);
519     ASSERT(picWidth);
520     ASSERT(picHeight);
521     ASSERT(pps->sliceGroupMapType < 7);
522 
523     picSize = picWidth * picHeight;
524 
525     /* just one slice group -> all macroblocks belong to group 0 */
526     if (pps->numSliceGroups == 1)
527     {
528         H264SwDecMemset(map, 0, picSize * sizeof(u32));
529         return;
530     }
531 
532     if (pps->sliceGroupMapType > 2 && pps->sliceGroupMapType < 6)
533     {
534         ASSERT(pps->sliceGroupChangeRate &&
535                pps->sliceGroupChangeRate <= picSize);
536 
537         unitsInSliceGroup0 =
538             MIN(sliceGroupChangeCycle * pps->sliceGroupChangeRate, picSize);
539 
540         if (pps->sliceGroupMapType == 4 || pps->sliceGroupMapType == 5)
541             sizeOfUpperLeftGroup = pps->sliceGroupChangeDirectionFlag ?
542                 (picSize - unitsInSliceGroup0) : unitsInSliceGroup0;
543     }
544 
545     switch (pps->sliceGroupMapType)
546     {
547         case 0:
548             DecodeInterleavedMap(map, pps->numSliceGroups,
549               pps->runLength, picSize);
550             break;
551 
552         case 1:
553             DecodeDispersedMap(map, pps->numSliceGroups, picWidth,
554               picHeight);
555             break;
556 
557         case 2:
558             DecodeForegroundLeftOverMap(map, pps->numSliceGroups,
559               pps->topLeft, pps->bottomRight, picWidth, picHeight);
560             break;
561 
562         case 3:
563             DecodeBoxOutMap(map, pps->sliceGroupChangeDirectionFlag,
564               unitsInSliceGroup0, picWidth, picHeight);
565             break;
566 
567         case 4:
568             DecodeRasterScanMap(map,
569               pps->sliceGroupChangeDirectionFlag, sizeOfUpperLeftGroup,
570               picSize);
571             break;
572 
573         case 5:
574             DecodeWipeMap(map, pps->sliceGroupChangeDirectionFlag,
575               sizeOfUpperLeftGroup, picWidth, picHeight);
576             break;
577 
578         default:
579             ASSERT(pps->sliceGroupId);
580             for (i = 0; i < picSize; i++)
581             {
582                 ASSERT(pps->sliceGroupId[i] < pps->numSliceGroups);
583                 map[i] = pps->sliceGroupId[i];
584             }
585             break;
586     }
587 
588 }
589 
590