PageRenderTime 982ms CodeModel.GetById 212ms app.highlight 542ms RepoModel.GetById 215ms app.codeStats 1ms

/Avc/fmo.cpp

http://github.com/mbebenita/Broadway
C++ | 249 lines | 197 code | 26 blank | 26 comment | 42 complexity | daaa410633e1c28c850d93b0d8c93b56 MD5 | raw file
  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 */
 23OSCL_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*/
 68void 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*/
 86void 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 */
 97void 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. */
128void 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 */
199void 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. */
214void 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 */
240void 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