Home | History | Annotate | Download | only in src
      1 /* ------------------------------------------------------------------
      2  * Copyright (C) 1998-2009 PacketVideo
      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
     13  * express or implied.
     14  * See the License for the specific language governing permissions
     15  * and limitations under the License.
     16  * -------------------------------------------------------------------
     17  */
     18 #include "avclib_common.h"
     19 #include "oscl_mem.h"
     20 
     21 /* see subclause 8.2.2 Decoding process for macroblock to slice group map */
     22 OSCL_EXPORT_REF AVCStatus FMOInit(AVCCommonObj *video)
     23 {
     24     AVCPicParamSet *currPPS = video->currPicParams;
     25     int *MbToSliceGroupMap = video->MbToSliceGroupMap;
     26     int PicSizeInMapUnits = video->PicSizeInMapUnits;
     27     int PicWidthInMbs = video->PicWidthInMbs;
     28 
     29     if (currPPS->num_slice_groups_minus1 == 0)
     30     {
     31         oscl_memset(video->MbToSliceGroupMap, 0, video->PicSizeInMapUnits*sizeof(uint));
     32     }
     33     else
     34     {
     35         switch (currPPS->slice_group_map_type)
     36         {
     37             case 0:
     38                 FmoGenerateType0MapUnitMap(MbToSliceGroupMap, currPPS->run_length_minus1, currPPS->num_slice_groups_minus1, PicSizeInMapUnits);
     39                 break;
     40             case 1:
     41                 FmoGenerateType1MapUnitMap(MbToSliceGroupMap, PicWidthInMbs, currPPS->num_slice_groups_minus1, PicSizeInMapUnits);
     42                 break;
     43             case 2:
     44                 FmoGenerateType2MapUnitMap(currPPS, MbToSliceGroupMap, PicWidthInMbs, currPPS->num_slice_groups_minus1, PicSizeInMapUnits);
     45                 break;
     46             case 3:
     47                 FmoGenerateType3MapUnitMap(video, currPPS, MbToSliceGroupMap, PicWidthInMbs);
     48                 break;
     49             case 4:
     50                 FmoGenerateType4MapUnitMap(MbToSliceGroupMap, video->MapUnitsInSliceGroup0, currPPS->slice_group_change_direction_flag, PicSizeInMapUnits);
     51                 break;
     52             case 5:
     53                 FmoGenerateType5MapUnitMap(MbToSliceGroupMap, video, currPPS->slice_group_change_direction_flag, PicSizeInMapUnits);
     54                 break;
     55             case 6:
     56                 FmoGenerateType6MapUnitMap(MbToSliceGroupMap, (int*)currPPS->slice_group_id, PicSizeInMapUnits);
     57                 break;
     58             default:
     59                 return AVC_FAIL; /* out of range, shouldn't come this far */
     60         }
     61     }
     62 
     63     return AVC_SUCCESS;
     64 }
     65 
     66 /* see subclause 8.2.2.1 interleaved slice group map type*/
     67 void FmoGenerateType0MapUnitMap(int *mapUnitToSliceGroupMap, uint *run_length_minus1, uint num_slice_groups_minus1, uint PicSizeInMapUnits)
     68 {
     69     uint iGroup, j;
     70     uint i = 0;
     71     do
     72     {
     73         for (iGroup = 0;
     74                 (iGroup <= num_slice_groups_minus1) && (i < PicSizeInMapUnits);
     75                 i += run_length_minus1[iGroup++] + 1)
     76         {
     77             for (j = 0; j <= run_length_minus1[ iGroup ] && i + j < PicSizeInMapUnits; j++)
     78                 mapUnitToSliceGroupMap[i+j] = iGroup;
     79         }
     80     }
     81     while (i < PicSizeInMapUnits);
     82 }
     83 
     84 /* see subclause 8.2.2.2 dispersed slice group map type*/
     85 void FmoGenerateType1MapUnitMap(int *mapUnitToSliceGroupMap, int PicWidthInMbs, uint num_slice_groups_minus1, uint PicSizeInMapUnits)
     86 {
     87     uint i;
     88     for (i = 0; i < PicSizeInMapUnits; i++)
     89     {
     90         mapUnitToSliceGroupMap[i] = ((i % PicWidthInMbs) + (((i / PicWidthInMbs) * (num_slice_groups_minus1 + 1)) / 2))
     91                                     % (num_slice_groups_minus1 + 1);
     92     }
     93 }
     94 
     95 /* see subclause 8.2.2.3 foreground with left-over slice group map type */
     96 void FmoGenerateType2MapUnitMap(AVCPicParamSet *pps, int *mapUnitToSliceGroupMap, int PicWidthInMbs,
     97                                 uint num_slice_groups_minus1, uint PicSizeInMapUnits)
     98 {
     99     int iGroup;
    100     uint i, x, y;
    101     uint yTopLeft, xTopLeft, yBottomRight, xBottomRight;
    102 
    103     for (i = 0; i < PicSizeInMapUnits; i++)
    104     {
    105         mapUnitToSliceGroupMap[ i ] = num_slice_groups_minus1;
    106     }
    107 
    108     for (iGroup = num_slice_groups_minus1 - 1 ; iGroup >= 0; iGroup--)
    109     {
    110         yTopLeft = pps->top_left[ iGroup ] / PicWidthInMbs;
    111         xTopLeft = pps->top_left[ iGroup ] % PicWidthInMbs;
    112         yBottomRight = pps->bottom_right[ iGroup ] / PicWidthInMbs;
    113         xBottomRight = pps->bottom_right[ iGroup ] % PicWidthInMbs;
    114         for (y = yTopLeft; y <= yBottomRight; y++)
    115         {
    116             for (x = xTopLeft; x <= xBottomRight; x++)
    117             {
    118                 mapUnitToSliceGroupMap[ y * PicWidthInMbs + x ] = iGroup;
    119             }
    120         }
    121     }
    122 }
    123 
    124 
    125 /* see subclause 8.2.2.4 box-out slice group map type */
    126 /* follow the text rather than the JM, it's quite different. */
    127 void FmoGenerateType3MapUnitMap(AVCCommonObj *video, AVCPicParamSet* pps, int *mapUnitToSliceGroupMap,
    128                                 int PicWidthInMbs)
    129 {
    130     uint i, k;
    131     int leftBound, topBound, rightBound, bottomBound;
    132     int x, y, xDir, yDir;
    133     int mapUnitVacant;
    134     uint PicSizeInMapUnits = video->PicSizeInMapUnits;
    135     uint MapUnitsInSliceGroup0 = video->MapUnitsInSliceGroup0;
    136 
    137     for (i = 0; i < PicSizeInMapUnits; i++)
    138     {
    139         mapUnitToSliceGroupMap[ i ] = 1;
    140     }
    141 
    142     x = (PicWidthInMbs - pps->slice_group_change_direction_flag) / 2;
    143     y = (video->PicHeightInMapUnits - pps->slice_group_change_direction_flag) / 2;
    144 
    145     leftBound   = x;
    146     topBound    = y;
    147     rightBound  = x;
    148     bottomBound = y;
    149 
    150     xDir =  pps->slice_group_change_direction_flag - 1;
    151     yDir =  pps->slice_group_change_direction_flag;
    152 
    153     for (k = 0; k < MapUnitsInSliceGroup0; k += mapUnitVacant)
    154     {
    155         mapUnitVacant = (mapUnitToSliceGroupMap[ y * PicWidthInMbs + x ]  ==  1);
    156         if (mapUnitVacant)
    157         {
    158             mapUnitToSliceGroupMap[ y * PicWidthInMbs + x ] = 0;
    159         }
    160 
    161         if (xDir  ==  -1  &&  x  ==  leftBound)
    162         {
    163             leftBound = AVC_MAX(leftBound - 1, 0);
    164             x = leftBound;
    165             xDir = 0;
    166             yDir = 2 * pps->slice_group_change_direction_flag - 1;
    167         }
    168         else if (xDir  ==  1  &&  x  ==  rightBound)
    169         {
    170             rightBound = AVC_MIN(rightBound + 1, (int)PicWidthInMbs - 1);
    171             x = rightBound;
    172             xDir = 0;
    173             yDir = 1 - 2 * pps->slice_group_change_direction_flag;
    174         }
    175         else if (yDir  ==  -1  &&  y  ==  topBound)
    176         {
    177             topBound = AVC_MAX(topBound - 1, 0);
    178             y = topBound;
    179             xDir = 1 - 2 * pps->slice_group_change_direction_flag;
    180             yDir = 0;
    181         }
    182         else  if (yDir  ==  1  &&  y  ==  bottomBound)
    183         {
    184             bottomBound = AVC_MIN(bottomBound + 1, (int)video->PicHeightInMapUnits - 1);
    185             y = bottomBound;
    186             xDir = 2 * pps->slice_group_change_direction_flag - 1;
    187             yDir = 0;
    188         }
    189         else
    190         {
    191             x = x + xDir;
    192             y = y + yDir;
    193         }
    194     }
    195 }
    196 
    197 /* see subclause 8.2.2.5 raster scan slice group map types */
    198 void FmoGenerateType4MapUnitMap(int *mapUnitToSliceGroupMap, int MapUnitsInSliceGroup0, int slice_group_change_direction_flag, uint PicSizeInMapUnits)
    199 {
    200     uint sizeOfUpperLeftGroup = slice_group_change_direction_flag ? (PicSizeInMapUnits - MapUnitsInSliceGroup0) : MapUnitsInSliceGroup0;
    201 
    202     uint i;
    203 
    204     for (i = 0; i < PicSizeInMapUnits; i++)
    205         if (i < sizeOfUpperLeftGroup)
    206             mapUnitToSliceGroupMap[ i ] = 1 - slice_group_change_direction_flag;
    207         else
    208             mapUnitToSliceGroupMap[ i ] = slice_group_change_direction_flag;
    209 
    210 }
    211 
    212 /* see subclause 8.2.2.6, wipe slice group map type. */
    213 void FmoGenerateType5MapUnitMap(int *mapUnitToSliceGroupMap, AVCCommonObj *video,
    214                                 int slice_group_change_direction_flag, uint PicSizeInMapUnits)
    215 {
    216     int PicWidthInMbs = video->PicWidthInMbs;
    217     int PicHeightInMapUnits = video->PicHeightInMapUnits;
    218     int MapUnitsInSliceGroup0 = video->MapUnitsInSliceGroup0;
    219     int sizeOfUpperLeftGroup = slice_group_change_direction_flag ? (PicSizeInMapUnits - MapUnitsInSliceGroup0) : MapUnitsInSliceGroup0;
    220     int i, j, k = 0;
    221 
    222     for (j = 0; j < PicWidthInMbs; j++)
    223     {
    224         for (i = 0; i < PicHeightInMapUnits; i++)
    225         {
    226             if (k++ < sizeOfUpperLeftGroup)
    227             {
    228                 mapUnitToSliceGroupMap[ i * PicWidthInMbs + j ] = 1 - slice_group_change_direction_flag;
    229             }
    230             else
    231             {
    232                 mapUnitToSliceGroupMap[ i * PicWidthInMbs + j ] = slice_group_change_direction_flag;
    233             }
    234         }
    235     }
    236 }
    237 
    238 /* see subclause 8.2.2.7, explicit slice group map */
    239 void FmoGenerateType6MapUnitMap(int *mapUnitToSliceGroupMap, int *slice_group_id, uint PicSizeInMapUnits)
    240 {
    241     uint i;
    242     for (i = 0; i < PicSizeInMapUnits; i++)
    243     {
    244         mapUnitToSliceGroupMap[i] = slice_group_id[i];
    245     }
    246 }
    247 
    248 
    249