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