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