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