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