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