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 */
FMOInit(AVCCommonObj * video)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*/
FmoGenerateType0MapUnitMap(int * mapUnitToSliceGroupMap,uint * run_length_minus1,uint num_slice_groups_minus1,uint PicSizeInMapUnits)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*/
FmoGenerateType1MapUnitMap(int * mapUnitToSliceGroupMap,int PicWidthInMbs,uint num_slice_groups_minus1,uint PicSizeInMapUnits)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 */
FmoGenerateType2MapUnitMap(AVCPicParamSet * pps,int * mapUnitToSliceGroupMap,int PicWidthInMbs,uint num_slice_groups_minus1,uint PicSizeInMapUnits)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. */
FmoGenerateType3MapUnitMap(AVCCommonObj * video,AVCPicParamSet * pps,int * mapUnitToSliceGroupMap,int PicWidthInMbs)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 */
FmoGenerateType4MapUnitMap(int * mapUnitToSliceGroupMap,int MapUnitsInSliceGroup0,int slice_group_change_direction_flag,uint PicSizeInMapUnits)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. */
FmoGenerateType5MapUnitMap(int * mapUnitToSliceGroupMap,AVCCommonObj * video,int slice_group_change_direction_flag,uint PicSizeInMapUnits)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 */
FmoGenerateType6MapUnitMap(int * mapUnitToSliceGroupMap,int * slice_group_id,uint PicSizeInMapUnits)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