Home | History | Annotate | Download | only in source
      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 
    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 
    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 
    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 
    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 
    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 
    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 
    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