/H264Dec/source/h264bsd_slice_group_map.c
C | 589 lines | 278 code | 98 blank | 213 comment | 51 complexity | 131c784c8f14a43d9fc79b055ee2341f MD5 | raw file
Possible License(s): BSD-3-Clause
- /*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- /*------------------------------------------------------------------------------
- Table of contents
- 1. Include headers
- 2. External compiler flags
- 3. Module defines
- 4. Local function prototypes
- 5. Functions
- DecodeInterleavedMap
- DecodeDispersedMap
- DecodeForegroundLeftOverMap
- DecodeBoxOutMap
- DecodeRasterScanMap
- DecodeWipeMap
- h264bsdDecodeSliceGroupMap
- ------------------------------------------------------------------------------*/
- /*------------------------------------------------------------------------------
- 1. Include headers
- ------------------------------------------------------------------------------*/
- #include "basetype.h"
- #include "h264bsd_slice_group_map.h"
- #include "h264bsd_cfg.h"
- #include "h264bsd_pic_param_set.h"
- #include "h264bsd_util.h"
- /*------------------------------------------------------------------------------
- 2. External compiler flags
- --------------------------------------------------------------------------------
- --------------------------------------------------------------------------------
- 3. Module defines
- ------------------------------------------------------------------------------*/
- /*------------------------------------------------------------------------------
- 4. Local function prototypes
- ------------------------------------------------------------------------------*/
- static void DecodeInterleavedMap(
- u32 *map,
- u32 numSliceGroups,
- u32 *runLength,
- u32 picSize);
- static void DecodeDispersedMap(
- u32 *map,
- u32 numSliceGroups,
- u32 picWidth,
- u32 picHeight);
- static void DecodeForegroundLeftOverMap(
- u32 *map,
- u32 numSliceGroups,
- u32 *topLeft,
- u32 *bottomRight,
- u32 picWidth,
- u32 picHeight);
- static void DecodeBoxOutMap(
- u32 *map,
- u32 sliceGroupChangeDirectionFlag,
- u32 unitsInSliceGroup0,
- u32 picWidth,
- u32 picHeight);
- static void DecodeRasterScanMap(
- u32 *map,
- u32 sliceGroupChangeDirectionFlag,
- u32 sizeOfUpperLeftGroup,
- u32 picSize);
- static void DecodeWipeMap(
- u32 *map,
- u32 sliceGroupChangeDirectionFlag,
- u32 sizeOfUpperLeftGroup,
- u32 picWidth,
- u32 picHeight);
- /*------------------------------------------------------------------------------
- Function: DecodeInterleavedMap
- Functional description:
- Function to decode interleaved slice group map type, i.e. slice
- group map type 0.
- Inputs:
- map pointer to the map
- numSliceGroups number of slice groups
- runLength run_length[] values for each slice group
- picSize picture size in macroblocks
- Outputs:
- map slice group map is stored here
- Returns:
- none
- ------------------------------------------------------------------------------*/
- void DecodeInterleavedMap(
- u32 *map,
- u32 numSliceGroups,
- u32 *runLength,
- u32 picSize)
- {
- /* Variables */
- u32 i,j, group;
- /* Code */
- ASSERT(map);
- ASSERT(numSliceGroups >= 1 && numSliceGroups <= MAX_NUM_SLICE_GROUPS);
- ASSERT(runLength);
- i = 0;
- do {
- for (group = 0; group < numSliceGroups && i < picSize;
- i += runLength[group++])
- {
- ASSERT(runLength[group] <= picSize);
- for (j = 0; j < runLength[group] && i + j < picSize; j++)
- map[i+j] = group;
- }
- } while (i < picSize);
- }
- /*------------------------------------------------------------------------------
- Function: DecodeDispersedMap
- Functional description:
- Function to decode dispersed slice group map type, i.e. slice
- group map type 1.
- Inputs:
- map pointer to the map
- numSliceGroups number of slice groups
- picWidth picture width in macroblocks
- picHeight picture height in macroblocks
- Outputs:
- map slice group map is stored here
- Returns:
- none
- ------------------------------------------------------------------------------*/
- void DecodeDispersedMap(
- u32 *map,
- u32 numSliceGroups,
- u32 picWidth,
- u32 picHeight)
- {
- /* Variables */
- u32 i, picSize;
- /* Code */
- ASSERT(map);
- ASSERT(numSliceGroups >= 1 && numSliceGroups <= MAX_NUM_SLICE_GROUPS);
- ASSERT(picWidth);
- ASSERT(picHeight);
- picSize = picWidth * picHeight;
- for (i = 0; i < picSize; i++)
- map[i] = ((i % picWidth) + (((i / picWidth) * numSliceGroups) >> 1)) %
- numSliceGroups;
- }
- /*------------------------------------------------------------------------------
- Function: DecodeForegroundLeftOverMap
- Functional description:
- Function to decode foreground with left-over slice group map type,
- i.e. slice group map type 2.
- Inputs:
- map pointer to the map
- numSliceGroups number of slice groups
- topLeft top_left[] values
- bottomRight bottom_right[] values
- picWidth picture width in macroblocks
- picHeight picture height in macroblocks
- Outputs:
- map slice group map is stored here
- Returns:
- none
- ------------------------------------------------------------------------------*/
- void DecodeForegroundLeftOverMap(
- u32 *map,
- u32 numSliceGroups,
- u32 *topLeft,
- u32 *bottomRight,
- u32 picWidth,
- u32 picHeight)
- {
- /* Variables */
- u32 i,y,x,yTopLeft,yBottomRight,xTopLeft,xBottomRight, picSize;
- u32 group;
- /* Code */
- ASSERT(map);
- ASSERT(numSliceGroups >= 1 && numSliceGroups <= MAX_NUM_SLICE_GROUPS);
- ASSERT(topLeft);
- ASSERT(bottomRight);
- ASSERT(picWidth);
- ASSERT(picHeight);
- picSize = picWidth * picHeight;
- for (i = 0; i < picSize; i++)
- map[i] = numSliceGroups - 1;
- for (group = numSliceGroups - 1; group--; )
- {
- ASSERT( topLeft[group] <= bottomRight[group] &&
- bottomRight[group] < picSize );
- yTopLeft = topLeft[group] / picWidth;
- xTopLeft = topLeft[group] % picWidth;
- yBottomRight = bottomRight[group] / picWidth;
- xBottomRight = bottomRight[group] % picWidth;
- ASSERT(xTopLeft <= xBottomRight);
- for (y = yTopLeft; y <= yBottomRight; y++)
- for (x = xTopLeft; x <= xBottomRight; x++)
- map[ y * picWidth + x ] = group;
- }
- }
- /*------------------------------------------------------------------------------
- Function: DecodeBoxOutMap
- Functional description:
- Function to decode box-out slice group map type, i.e. slice group
- map type 3.
- Inputs:
- map pointer to the map
- sliceGroupChangeDirectionFlag slice_group_change_direction_flag
- unitsInSliceGroup0 mbs on slice group 0
- picWidth picture width in macroblocks
- picHeight picture height in macroblocks
- Outputs:
- map slice group map is stored here
- Returns:
- none
- ------------------------------------------------------------------------------*/
- void DecodeBoxOutMap(
- u32 *map,
- u32 sliceGroupChangeDirectionFlag,
- u32 unitsInSliceGroup0,
- u32 picWidth,
- u32 picHeight)
- {
- /* Variables */
- u32 i, k, picSize;
- i32 x, y, xDir, yDir, leftBound, topBound, rightBound, bottomBound;
- u32 mapUnitVacant;
- /* Code */
- ASSERT(map);
- ASSERT(picWidth);
- ASSERT(picHeight);
- picSize = picWidth * picHeight;
- ASSERT(unitsInSliceGroup0 <= picSize);
- for (i = 0; i < picSize; i++)
- map[i] = 1;
- x = (picWidth - (u32)sliceGroupChangeDirectionFlag) >> 1;
- y = (picHeight - (u32)sliceGroupChangeDirectionFlag) >> 1;
- leftBound = x;
- topBound = y;
- rightBound = x;
- bottomBound = y;
- xDir = (i32)sliceGroupChangeDirectionFlag - 1;
- yDir = (i32)sliceGroupChangeDirectionFlag;
- for (k = 0; k < unitsInSliceGroup0; k += mapUnitVacant ? 1 : 0)
- {
- mapUnitVacant = (map[ (u32)y * picWidth + (u32)x ] == 1) ?
- HANTRO_TRUE : HANTRO_FALSE;
- if (mapUnitVacant)
- map[ (u32)y * picWidth + (u32)x ] = 0;
- if (xDir == -1 && x == leftBound)
- {
- leftBound = MAX(leftBound - 1, 0);
- x = leftBound;
- xDir = 0;
- yDir = 2 * (i32)sliceGroupChangeDirectionFlag - 1;
- }
- else if (xDir == 1 && x == rightBound)
- {
- rightBound = MIN(rightBound + 1, (i32)picWidth - 1);
- x = rightBound;
- xDir = 0;
- yDir = 1 - 2 * (i32)sliceGroupChangeDirectionFlag;
- }
- else if (yDir == -1 && y == topBound)
- {
- topBound = MAX(topBound - 1, 0);
- y = topBound;
- xDir = 1 - 2 * (i32)sliceGroupChangeDirectionFlag;
- yDir = 0;
- }
- else if (yDir == 1 && y == bottomBound)
- {
- bottomBound = MIN(bottomBound + 1, (i32)picHeight - 1);
- y = bottomBound;
- xDir = 2 * (i32)sliceGroupChangeDirectionFlag - 1;
- yDir = 0;
- }
- else
- {
- x += xDir;
- y += yDir;
- }
- }
- }
- /*------------------------------------------------------------------------------
- Function: DecodeRasterScanMap
- Functional description:
- Function to decode raster scan slice group map type, i.e. slice
- group map type 4.
- Inputs:
- map pointer to the map
- sliceGroupChangeDirectionFlag slice_group_change_direction_flag
- sizeOfUpperLeftGroup mbs in upperLeftGroup
- picSize picture size in macroblocks
- Outputs:
- map slice group map is stored here
- Returns:
- none
- ------------------------------------------------------------------------------*/
- void DecodeRasterScanMap(
- u32 *map,
- u32 sliceGroupChangeDirectionFlag,
- u32 sizeOfUpperLeftGroup,
- u32 picSize)
- {
- /* Variables */
- u32 i;
- /* Code */
- ASSERT(map);
- ASSERT(picSize);
- ASSERT(sizeOfUpperLeftGroup <= picSize);
- for (i = 0; i < picSize; i++)
- if (i < sizeOfUpperLeftGroup)
- map[i] = (u32)sliceGroupChangeDirectionFlag;
- else
- map[i] = 1 - (u32)sliceGroupChangeDirectionFlag;
- }
- /*------------------------------------------------------------------------------
- Function: DecodeWipeMap
- Functional description:
- Function to decode wipe slice group map type, i.e. slice group map
- type 5.
- Inputs:
- sliceGroupChangeDirectionFlag slice_group_change_direction_flag
- sizeOfUpperLeftGroup mbs in upperLeftGroup
- picWidth picture width in macroblocks
- picHeight picture height in macroblocks
- Outputs:
- map slice group map is stored here
- Returns:
- none
- ------------------------------------------------------------------------------*/
- void DecodeWipeMap(
- u32 *map,
- u32 sliceGroupChangeDirectionFlag,
- u32 sizeOfUpperLeftGroup,
- u32 picWidth,
- u32 picHeight)
- {
- /* Variables */
- u32 i,j,k;
- /* Code */
- ASSERT(map);
- ASSERT(picWidth);
- ASSERT(picHeight);
- ASSERT(sizeOfUpperLeftGroup <= picWidth * picHeight);
- k = 0;
- for (j = 0; j < picWidth; j++)
- for (i = 0; i < picHeight; i++)
- if (k++ < sizeOfUpperLeftGroup)
- map[ i * picWidth + j ] = (u32)sliceGroupChangeDirectionFlag;
- else
- map[ i * picWidth + j ] = 1 -
- (u32)sliceGroupChangeDirectionFlag;
- }
- /*------------------------------------------------------------------------------
- Function: h264bsdDecodeSliceGroupMap
- Functional description:
- Function to decode macroblock to slice group map. Construction
- of different slice group map types is handled by separate
- functions defined above. See standard for details how slice group
- maps are computed.
- Inputs:
- pps active picture parameter set
- sliceGroupChangeCycle slice_group_change_cycle
- picWidth picture width in macroblocks
- picHeight picture height in macroblocks
- Outputs:
- map slice group map is stored here
- Returns:
- none
- ------------------------------------------------------------------------------*/
- void h264bsdDecodeSliceGroupMap(
- u32 *map,
- picParamSet_t *pps,
- u32 sliceGroupChangeCycle,
- u32 picWidth,
- u32 picHeight)
- {
- /* Variables */
- u32 i, picSize, unitsInSliceGroup0 = 0, sizeOfUpperLeftGroup = 0;
- /* Code */
- ASSERT(map);
- ASSERT(pps);
- ASSERT(picWidth);
- ASSERT(picHeight);
- ASSERT(pps->sliceGroupMapType < 7);
- picSize = picWidth * picHeight;
- /* just one slice group -> all macroblocks belong to group 0 */
- if (pps->numSliceGroups == 1)
- {
- H264SwDecMemset(map, 0, picSize * sizeof(u32));
- return;
- }
- if (pps->sliceGroupMapType > 2 && pps->sliceGroupMapType < 6)
- {
- ASSERT(pps->sliceGroupChangeRate &&
- pps->sliceGroupChangeRate <= picSize);
- unitsInSliceGroup0 =
- MIN(sliceGroupChangeCycle * pps->sliceGroupChangeRate, picSize);
- if (pps->sliceGroupMapType == 4 || pps->sliceGroupMapType == 5)
- sizeOfUpperLeftGroup = pps->sliceGroupChangeDirectionFlag ?
- (picSize - unitsInSliceGroup0) : unitsInSliceGroup0;
- }
- switch (pps->sliceGroupMapType)
- {
- case 0:
- DecodeInterleavedMap(map, pps->numSliceGroups,
- pps->runLength, picSize);
- break;
- case 1:
- DecodeDispersedMap(map, pps->numSliceGroups, picWidth,
- picHeight);
- break;
- case 2:
- DecodeForegroundLeftOverMap(map, pps->numSliceGroups,
- pps->topLeft, pps->bottomRight, picWidth, picHeight);
- break;
- case 3:
- DecodeBoxOutMap(map, pps->sliceGroupChangeDirectionFlag,
- unitsInSliceGroup0, picWidth, picHeight);
- break;
- case 4:
- DecodeRasterScanMap(map,
- pps->sliceGroupChangeDirectionFlag, sizeOfUpperLeftGroup,
- picSize);
- break;
- case 5:
- DecodeWipeMap(map, pps->sliceGroupChangeDirectionFlag,
- sizeOfUpperLeftGroup, picWidth, picHeight);
- break;
- default:
- ASSERT(pps->sliceGroupId);
- for (i = 0; i < picSize; i++)
- {
- ASSERT(pps->sliceGroupId[i] < pps->numSliceGroups);
- map[i] = pps->sliceGroupId[i];
- }
- break;
- }
- }