1 /* 2 * Copyright (C) 2009 The Android Open Source Project 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 express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /*------------------------------------------------------------------------------ 18 19 Table of contents 20 21 1. Include headers 22 2. External compiler flags 23 3. Module defines 24 4. Local function prototypes 25 5. Functions 26 DecodeInterleavedMap 27 DecodeDispersedMap 28 DecodeForegroundLeftOverMap 29 DecodeBoxOutMap 30 DecodeRasterScanMap 31 DecodeWipeMap 32 h264bsdDecodeSliceGroupMap 33 34 ------------------------------------------------------------------------------*/ 35 36 /*------------------------------------------------------------------------------ 37 1. Include headers 38 ------------------------------------------------------------------------------*/ 39 40 #include "basetype.h" 41 #include "h264bsd_slice_group_map.h" 42 #include "h264bsd_cfg.h" 43 #include "h264bsd_pic_param_set.h" 44 #include "h264bsd_util.h" 45 46 /*------------------------------------------------------------------------------ 47 2. External compiler flags 48 -------------------------------------------------------------------------------- 49 50 -------------------------------------------------------------------------------- 51 3. Module defines 52 ------------------------------------------------------------------------------*/ 53 54 /*------------------------------------------------------------------------------ 55 4. Local function prototypes 56 ------------------------------------------------------------------------------*/ 57 58 static void DecodeInterleavedMap( 59 u32 *map, 60 u32 numSliceGroups, 61 u32 *runLength, 62 u32 picSize); 63 64 static void DecodeDispersedMap( 65 u32 *map, 66 u32 numSliceGroups, 67 u32 picWidth, 68 u32 picHeight); 69 70 static void DecodeForegroundLeftOverMap( 71 u32 *map, 72 u32 numSliceGroups, 73 u32 *topLeft, 74 u32 *bottomRight, 75 u32 picWidth, 76 u32 picHeight); 77 78 static void DecodeBoxOutMap( 79 u32 *map, 80 u32 sliceGroupChangeDirectionFlag, 81 u32 unitsInSliceGroup0, 82 u32 picWidth, 83 u32 picHeight); 84 85 static void DecodeRasterScanMap( 86 u32 *map, 87 u32 sliceGroupChangeDirectionFlag, 88 u32 sizeOfUpperLeftGroup, 89 u32 picSize); 90 91 static void DecodeWipeMap( 92 u32 *map, 93 u32 sliceGroupChangeDirectionFlag, 94 u32 sizeOfUpperLeftGroup, 95 u32 picWidth, 96 u32 picHeight); 97 98 /*------------------------------------------------------------------------------ 99 100 Function: DecodeInterleavedMap 101 102 Functional description: 103 Function to decode interleaved slice group map type, i.e. slice 104 group map type 0. 105 106 Inputs: 107 map pointer to the map 108 numSliceGroups number of slice groups 109 runLength run_length[] values for each slice group 110 picSize picture size in macroblocks 111 112 Outputs: 113 map slice group map is stored here 114 115 Returns: 116 none 117 118 ------------------------------------------------------------------------------*/ 119 120 void DecodeInterleavedMap( 121 u32 *map, 122 u32 numSliceGroups, 123 u32 *runLength, 124 u32 picSize) 125 { 126 127 /* Variables */ 128 129 u32 i,j, group; 130 131 /* Code */ 132 133 ASSERT(map); 134 ASSERT(numSliceGroups >= 1 && numSliceGroups <= MAX_NUM_SLICE_GROUPS); 135 ASSERT(runLength); 136 137 i = 0; 138 139 do { 140 for (group = 0; group < numSliceGroups && i < picSize; 141 i += runLength[group++]) 142 { 143 ASSERT(runLength[group] <= picSize); 144 for (j = 0; j < runLength[group] && i + j < picSize; j++) 145 map[i+j] = group; 146 } 147 } while (i < picSize); 148 149 150 } 151 152 /*------------------------------------------------------------------------------ 153 154 Function: DecodeDispersedMap 155 156 Functional description: 157 Function to decode dispersed slice group map type, i.e. slice 158 group map type 1. 159 160 Inputs: 161 map pointer to the map 162 numSliceGroups number of slice groups 163 picWidth picture width in macroblocks 164 picHeight picture height in macroblocks 165 166 Outputs: 167 map slice group map is stored here 168 169 Returns: 170 none 171 172 ------------------------------------------------------------------------------*/ 173 174 void DecodeDispersedMap( 175 u32 *map, 176 u32 numSliceGroups, 177 u32 picWidth, 178 u32 picHeight) 179 { 180 181 /* Variables */ 182 183 u32 i, picSize; 184 185 /* Code */ 186 187 ASSERT(map); 188 ASSERT(numSliceGroups >= 1 && numSliceGroups <= MAX_NUM_SLICE_GROUPS); 189 ASSERT(picWidth); 190 ASSERT(picHeight); 191 192 picSize = picWidth * picHeight; 193 194 for (i = 0; i < picSize; i++) 195 map[i] = ((i % picWidth) + (((i / picWidth) * numSliceGroups) >> 1)) % 196 numSliceGroups; 197 198 199 } 200 201 /*------------------------------------------------------------------------------ 202 203 Function: DecodeForegroundLeftOverMap 204 205 Functional description: 206 Function to decode foreground with left-over slice group map type, 207 i.e. slice group map type 2. 208 209 Inputs: 210 map pointer to the map 211 numSliceGroups number of slice groups 212 topLeft top_left[] values 213 bottomRight bottom_right[] values 214 picWidth picture width in macroblocks 215 picHeight picture height in macroblocks 216 217 Outputs: 218 map slice group map is stored here 219 220 Returns: 221 none 222 223 ------------------------------------------------------------------------------*/ 224 225 void DecodeForegroundLeftOverMap( 226 u32 *map, 227 u32 numSliceGroups, 228 u32 *topLeft, 229 u32 *bottomRight, 230 u32 picWidth, 231 u32 picHeight) 232 { 233 234 /* Variables */ 235 236 u32 i,y,x,yTopLeft,yBottomRight,xTopLeft,xBottomRight, picSize; 237 u32 group; 238 239 /* Code */ 240 241 ASSERT(map); 242 ASSERT(numSliceGroups >= 1 && numSliceGroups <= MAX_NUM_SLICE_GROUPS); 243 ASSERT(topLeft); 244 ASSERT(bottomRight); 245 ASSERT(picWidth); 246 ASSERT(picHeight); 247 248 picSize = picWidth * picHeight; 249 250 for (i = 0; i < picSize; i++) 251 map[i] = numSliceGroups - 1; 252 253 for (group = numSliceGroups - 1; group--; ) 254 { 255 ASSERT( topLeft[group] <= bottomRight[group] && 256 bottomRight[group] < picSize ); 257 yTopLeft = topLeft[group] / picWidth; 258 xTopLeft = topLeft[group] % picWidth; 259 yBottomRight = bottomRight[group] / picWidth; 260 xBottomRight = bottomRight[group] % picWidth; 261 ASSERT(xTopLeft <= xBottomRight); 262 263 for (y = yTopLeft; y <= yBottomRight; y++) 264 for (x = xTopLeft; x <= xBottomRight; x++) 265 map[ y * picWidth + x ] = group; 266 } 267 268 269 } 270 271 /*------------------------------------------------------------------------------ 272 273 Function: DecodeBoxOutMap 274 275 Functional description: 276 Function to decode box-out slice group map type, i.e. slice group 277 map type 3. 278 279 Inputs: 280 map pointer to the map 281 sliceGroupChangeDirectionFlag slice_group_change_direction_flag 282 unitsInSliceGroup0 mbs on slice group 0 283 picWidth picture width in macroblocks 284 picHeight picture height in macroblocks 285 286 Outputs: 287 map slice group map is stored here 288 289 Returns: 290 none 291 292 ------------------------------------------------------------------------------*/ 293 294 void DecodeBoxOutMap( 295 u32 *map, 296 u32 sliceGroupChangeDirectionFlag, 297 u32 unitsInSliceGroup0, 298 u32 picWidth, 299 u32 picHeight) 300 { 301 302 /* Variables */ 303 304 u32 i, k, picSize; 305 i32 x, y, xDir, yDir, leftBound, topBound, rightBound, bottomBound; 306 u32 mapUnitVacant; 307 308 /* Code */ 309 310 ASSERT(map); 311 ASSERT(picWidth); 312 ASSERT(picHeight); 313 314 picSize = picWidth * picHeight; 315 ASSERT(unitsInSliceGroup0 <= picSize); 316 317 for (i = 0; i < picSize; i++) 318 map[i] = 1; 319 320 x = (picWidth - (u32)sliceGroupChangeDirectionFlag) >> 1; 321 y = (picHeight - (u32)sliceGroupChangeDirectionFlag) >> 1; 322 323 leftBound = x; 324 topBound = y; 325 326 rightBound = x; 327 bottomBound = y; 328 329 xDir = (i32)sliceGroupChangeDirectionFlag - 1; 330 yDir = (i32)sliceGroupChangeDirectionFlag; 331 332 for (k = 0; k < unitsInSliceGroup0; k += mapUnitVacant ? 1 : 0) 333 { 334 mapUnitVacant = (map[ (u32)y * picWidth + (u32)x ] == 1) ? 335 HANTRO_TRUE : HANTRO_FALSE; 336 337 if (mapUnitVacant) 338 map[ (u32)y * picWidth + (u32)x ] = 0; 339 340 if (xDir == -1 && x == leftBound) 341 { 342 leftBound = MAX(leftBound - 1, 0); 343 x = leftBound; 344 xDir = 0; 345 yDir = 2 * (i32)sliceGroupChangeDirectionFlag - 1; 346 } 347 else if (xDir == 1 && x == rightBound) 348 { 349 rightBound = MIN(rightBound + 1, (i32)picWidth - 1); 350 x = rightBound; 351 xDir = 0; 352 yDir = 1 - 2 * (i32)sliceGroupChangeDirectionFlag; 353 } 354 else if (yDir == -1 && y == topBound) 355 { 356 topBound = MAX(topBound - 1, 0); 357 y = topBound; 358 xDir = 1 - 2 * (i32)sliceGroupChangeDirectionFlag; 359 yDir = 0; 360 } 361 else if (yDir == 1 && y == bottomBound) 362 { 363 bottomBound = MIN(bottomBound + 1, (i32)picHeight - 1); 364 y = bottomBound; 365 xDir = 2 * (i32)sliceGroupChangeDirectionFlag - 1; 366 yDir = 0; 367 } 368 else 369 { 370 x += xDir; 371 y += yDir; 372 } 373 } 374 375 376 } 377 378 /*------------------------------------------------------------------------------ 379 380 Function: DecodeRasterScanMap 381 382 Functional description: 383 Function to decode raster scan slice group map type, i.e. slice 384 group map type 4. 385 386 Inputs: 387 map pointer to the map 388 sliceGroupChangeDirectionFlag slice_group_change_direction_flag 389 sizeOfUpperLeftGroup mbs in upperLeftGroup 390 picSize picture size in macroblocks 391 392 Outputs: 393 map slice group map is stored here 394 395 Returns: 396 none 397 398 ------------------------------------------------------------------------------*/ 399 400 void DecodeRasterScanMap( 401 u32 *map, 402 u32 sliceGroupChangeDirectionFlag, 403 u32 sizeOfUpperLeftGroup, 404 u32 picSize) 405 { 406 407 /* Variables */ 408 409 u32 i; 410 411 /* Code */ 412 413 ASSERT(map); 414 ASSERT(picSize); 415 ASSERT(sizeOfUpperLeftGroup <= picSize); 416 417 for (i = 0; i < picSize; i++) 418 if (i < sizeOfUpperLeftGroup) 419 map[i] = (u32)sliceGroupChangeDirectionFlag; 420 else 421 map[i] = 1 - (u32)sliceGroupChangeDirectionFlag; 422 423 424 } 425 426 /*------------------------------------------------------------------------------ 427 428 Function: DecodeWipeMap 429 430 Functional description: 431 Function to decode wipe slice group map type, i.e. slice group map 432 type 5. 433 434 Inputs: 435 sliceGroupChangeDirectionFlag slice_group_change_direction_flag 436 sizeOfUpperLeftGroup mbs in upperLeftGroup 437 picWidth picture width in macroblocks 438 picHeight picture height in macroblocks 439 440 Outputs: 441 map slice group map is stored here 442 443 Returns: 444 none 445 446 ------------------------------------------------------------------------------*/ 447 448 void DecodeWipeMap( 449 u32 *map, 450 u32 sliceGroupChangeDirectionFlag, 451 u32 sizeOfUpperLeftGroup, 452 u32 picWidth, 453 u32 picHeight) 454 { 455 456 /* Variables */ 457 458 u32 i,j,k; 459 460 /* Code */ 461 462 ASSERT(map); 463 ASSERT(picWidth); 464 ASSERT(picHeight); 465 ASSERT(sizeOfUpperLeftGroup <= picWidth * picHeight); 466 467 k = 0; 468 for (j = 0; j < picWidth; j++) 469 for (i = 0; i < picHeight; i++) 470 if (k++ < sizeOfUpperLeftGroup) 471 map[ i * picWidth + j ] = (u32)sliceGroupChangeDirectionFlag; 472 else 473 map[ i * picWidth + j ] = 1 - 474 (u32)sliceGroupChangeDirectionFlag; 475 476 477 } 478 479 /*------------------------------------------------------------------------------ 480 481 Function: h264bsdDecodeSliceGroupMap 482 483 Functional description: 484 Function to decode macroblock to slice group map. Construction 485 of different slice group map types is handled by separate 486 functions defined above. See standard for details how slice group 487 maps are computed. 488 489 Inputs: 490 pps active picture parameter set 491 sliceGroupChangeCycle slice_group_change_cycle 492 picWidth picture width in macroblocks 493 picHeight picture height in macroblocks 494 495 Outputs: 496 map slice group map is stored here 497 498 Returns: 499 none 500 501 ------------------------------------------------------------------------------*/ 502 503 void h264bsdDecodeSliceGroupMap( 504 u32 *map, 505 picParamSet_t *pps, 506 u32 sliceGroupChangeCycle, 507 u32 picWidth, 508 u32 picHeight) 509 { 510 511 /* Variables */ 512 513 u32 i, picSize, unitsInSliceGroup0 = 0, sizeOfUpperLeftGroup = 0; 514 515 /* Code */ 516 517 ASSERT(map); 518 ASSERT(pps); 519 ASSERT(picWidth); 520 ASSERT(picHeight); 521 ASSERT(pps->sliceGroupMapType < 7); 522 523 picSize = picWidth * picHeight; 524 525 /* just one slice group -> all macroblocks belong to group 0 */ 526 if (pps->numSliceGroups == 1) 527 { 528 H264SwDecMemset(map, 0, picSize * sizeof(u32)); 529 return; 530 } 531 532 if (pps->sliceGroupMapType > 2 && pps->sliceGroupMapType < 6) 533 { 534 ASSERT(pps->sliceGroupChangeRate && 535 pps->sliceGroupChangeRate <= picSize); 536 537 unitsInSliceGroup0 = 538 MIN(sliceGroupChangeCycle * pps->sliceGroupChangeRate, picSize); 539 540 if (pps->sliceGroupMapType == 4 || pps->sliceGroupMapType == 5) 541 sizeOfUpperLeftGroup = pps->sliceGroupChangeDirectionFlag ? 542 (picSize - unitsInSliceGroup0) : unitsInSliceGroup0; 543 } 544 545 switch (pps->sliceGroupMapType) 546 { 547 case 0: 548 DecodeInterleavedMap(map, pps->numSliceGroups, 549 pps->runLength, picSize); 550 break; 551 552 case 1: 553 DecodeDispersedMap(map, pps->numSliceGroups, picWidth, 554 picHeight); 555 break; 556 557 case 2: 558 DecodeForegroundLeftOverMap(map, pps->numSliceGroups, 559 pps->topLeft, pps->bottomRight, picWidth, picHeight); 560 break; 561 562 case 3: 563 DecodeBoxOutMap(map, pps->sliceGroupChangeDirectionFlag, 564 unitsInSliceGroup0, picWidth, picHeight); 565 break; 566 567 case 4: 568 DecodeRasterScanMap(map, 569 pps->sliceGroupChangeDirectionFlag, sizeOfUpperLeftGroup, 570 picSize); 571 break; 572 573 case 5: 574 DecodeWipeMap(map, pps->sliceGroupChangeDirectionFlag, 575 sizeOfUpperLeftGroup, picWidth, picHeight); 576 break; 577 578 default: 579 ASSERT(pps->sliceGroupId); 580 for (i = 0; i < picSize; i++) 581 { 582 ASSERT(pps->sliceGroupId[i] < pps->numSliceGroups); 583 map[i] = pps->sliceGroupId[i]; 584 } 585 break; 586 } 587 588 } 589 590