00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 #include "global.h"
00054
00055 #include "fmo.h"
00056
00057
00058 static int FirstMBInSlice[MAXSLICEGROUPIDS];
00059
00060 byte *MBAmap = NULL;
00061 byte *MapUnitToSliceGroupMap = NULL;
00062 unsigned int PicSizeInMapUnits;
00063
00064
00065 static void FmoGenerateType0MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps);
00066 static void FmoGenerateType1MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps);
00067 static void FmoGenerateType2MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps);
00068 static void FmoGenerateType3MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps);
00069 static void FmoGenerateType4MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps);
00070 static void FmoGenerateType5MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps);
00071 static void FmoGenerateType6MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps);
00072
00073
00074 static int FmoGenerateMapUnitToSliceGroupMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps);
00075 static int FmoGenerateMBAmap (ImageParameters * img, seq_parameter_set_rbsp_t* sps);
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 static int FmoGenerateMapUnitToSliceGroupMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps)
00091 {
00092 PicSizeInMapUnits = img->PicHeightInMapUnits * img->PicWidthInMbs;
00093
00094
00095 if (pps->slice_group_map_type == 6)
00096 {
00097 if ((pps->pic_size_in_map_units_minus1+1) != PicSizeInMapUnits)
00098 {
00099 error ("wrong pps->pic_size_in_map_units_minus1 for used SPS and FMO type 6", 500);
00100 }
00101 }
00102
00103
00104 if (MapUnitToSliceGroupMap)
00105 free (MapUnitToSliceGroupMap);
00106
00107 if ((MapUnitToSliceGroupMap = malloc ((PicSizeInMapUnits) * sizeof (byte))) == NULL)
00108 {
00109 printf ("cannot allocated %d bytes for MapUnitToSliceGroupMap, exit\n", (int) ( PicSizeInMapUnits * sizeof (byte)));
00110 exit (-1);
00111 }
00112
00113 if (pps->num_slice_groups_minus1 == 0)
00114 {
00115 memset (MapUnitToSliceGroupMap, 0, PicSizeInMapUnits * sizeof (byte));
00116 return 0;
00117 }
00118
00119 switch (pps->slice_group_map_type)
00120 {
00121 case 0:
00122 FmoGenerateType0MapUnitMap (img, pps);
00123 break;
00124 case 1:
00125 FmoGenerateType1MapUnitMap (img, pps);
00126 break;
00127 case 2:
00128 FmoGenerateType2MapUnitMap (img, pps);
00129 break;
00130 case 3:
00131 FmoGenerateType3MapUnitMap (img, pps);
00132 break;
00133 case 4:
00134 FmoGenerateType4MapUnitMap (img, pps);
00135 break;
00136 case 5:
00137 FmoGenerateType5MapUnitMap (img, pps);
00138 break;
00139 case 6:
00140 FmoGenerateType6MapUnitMap (img, pps);
00141 break;
00142 default:
00143 printf ("Illegal slice_group_map_type %d , exit \n", pps->slice_group_map_type);
00144 exit (-1);
00145 }
00146 return 0;
00147 }
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 static int FmoGenerateMBAmap (ImageParameters * img, seq_parameter_set_rbsp_t* sps)
00163 {
00164 unsigned i;
00165
00166
00167 if (MBAmap)
00168 free (MBAmap);
00169
00170
00171 if ((MBAmap = malloc ((img->PicSizeInMbs) * sizeof (byte))) == NULL)
00172 {
00173 printf ("cannot allocated %d bytes for MBAmap, exit\n", (int) ((img->PicSizeInMbs) * sizeof (byte)));
00174 exit (-1);
00175 }
00176
00177 if ((sps->frame_mbs_only_flag) || img->field_picture)
00178 {
00179 for (i=0; i<img->PicSizeInMbs; i++)
00180 {
00181 MBAmap[i] = MapUnitToSliceGroupMap[i];
00182 }
00183 }
00184 else
00185 if (sps->mb_adaptive_frame_field_flag && (! img->field_picture))
00186 {
00187 for (i=0; i<img->PicSizeInMbs; i++)
00188 {
00189 MBAmap[i] = MapUnitToSliceGroupMap[i/2];
00190 }
00191 }
00192 else
00193 {
00194 for (i=0; i<img->PicSizeInMbs; i++)
00195 {
00196 MBAmap[i] = MapUnitToSliceGroupMap[(i/(2*img->PicWidthInMbs))*img->PicWidthInMbs+(i%img->PicWidthInMbs)];
00197 }
00198 }
00199 return 0;
00200 }
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 int FmoInit(ImageParameters * img, pic_parameter_set_rbsp_t * pps, seq_parameter_set_rbsp_t * sps)
00217 {
00218
00219 #ifdef PRINT_FMO_MAPS
00220 unsigned i,j;
00221 int bottom;
00222 #endif
00223
00224 int k;
00225 for (k=0;k<MAXSLICEGROUPIDS;k++)
00226 FirstMBInSlice[k] = -1;
00227
00228
00229
00230 FmoGenerateMapUnitToSliceGroupMap(img, pps);
00231 FmoGenerateMBAmap(img, sps);
00232
00233 #ifdef PRINT_FMO_MAPS
00234 printf("\n");
00235 printf("FMO Map (Units):\n");
00236
00237 for (j=0; j<img->PicHeightInMapUnits; j++)
00238 {
00239 for (i=0; i<img->PicWidthInMbs; i++)
00240 {
00241 printf("%d ",MapUnitToSliceGroupMap[i+j*img->PicWidthInMbs]);
00242 }
00243 printf("\n");
00244 }
00245 printf("\n");
00246
00247 if(sps->mb_adaptive_frame_field_flag==0)
00248 {
00249 printf("FMO Map (Mb):\n");
00250 for (j=0; j<(img->PicSizeInMbs/img->PicWidthInMbs); j++)
00251 {
00252 for (i=0; i<img->PicWidthInMbs; i++)
00253 {
00254 printf("%d ",MBAmap[i+j*img->PicWidthInMbs]);
00255 }
00256 printf("\n");
00257 }
00258 printf("\n");
00259 }
00260 else
00261 {
00262 printf("FMO Map (Mb in scan order for MBAFF):\n");
00263 for (j=0; j<(img->PicSizeInMbs/img->PicWidthInMbs); j++)
00264 {
00265 for (i=0; i<img->PicWidthInMbs; i++)
00266 {
00267 bottom=(j%2);
00268 printf("%d ",MBAmap[(j-bottom)*img->PicWidthInMbs+i*2+bottom]);
00269 }
00270 printf("\n");
00271
00272 }
00273 printf("\n");
00274
00275 }
00276
00277 #endif
00278
00279 return 0;
00280 }
00281
00282
00283
00284
00285
00286
00287
00288
00289 void FmoUninit()
00290 {
00291 if (MBAmap)
00292 {
00293 free (MBAmap);
00294 MBAmap = NULL;
00295 }
00296 if (MapUnitToSliceGroupMap)
00297 {
00298 free (MapUnitToSliceGroupMap);
00299 MapUnitToSliceGroupMap = NULL;
00300 }
00301
00302 }
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316 static void FmoGenerateType0MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps )
00317 {
00318 unsigned iGroup, j;
00319 unsigned i = 0;
00320 do
00321 {
00322 for( iGroup = 0;
00323 (iGroup <= pps->num_slice_groups_minus1) && (i < PicSizeInMapUnits);
00324 i += pps->run_length_minus1[iGroup++] + 1)
00325 {
00326 for( j = 0; j <= pps->run_length_minus1[ iGroup ] && i + j < PicSizeInMapUnits; j++ )
00327 MapUnitToSliceGroupMap[i+j] = iGroup;
00328 }
00329 }
00330 while( i < PicSizeInMapUnits );
00331 }
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345 static void FmoGenerateType1MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps )
00346 {
00347 unsigned i;
00348 for( i = 0; i < PicSizeInMapUnits; i++ )
00349 {
00350 MapUnitToSliceGroupMap[i] = ((i%img->PicWidthInMbs)+(((i/img->PicWidthInMbs)*(pps->num_slice_groups_minus1+1))/2))
00351 %(pps->num_slice_groups_minus1+1);
00352 }
00353 }
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366 static void FmoGenerateType2MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps )
00367 {
00368 int iGroup;
00369 unsigned i, x, y;
00370 unsigned yTopLeft, xTopLeft, yBottomRight, xBottomRight;
00371
00372 for( i = 0; i < PicSizeInMapUnits; i++ )
00373 MapUnitToSliceGroupMap[ i ] = pps->num_slice_groups_minus1;
00374
00375 for( iGroup = pps->num_slice_groups_minus1 - 1 ; iGroup >= 0; iGroup-- )
00376 {
00377 yTopLeft = pps->top_left[ iGroup ] / img->PicWidthInMbs;
00378 xTopLeft = pps->top_left[ iGroup ] % img->PicWidthInMbs;
00379 yBottomRight = pps->bottom_right[ iGroup ] / img->PicWidthInMbs;
00380 xBottomRight = pps->bottom_right[ iGroup ] % img->PicWidthInMbs;
00381 for( y = yTopLeft; y <= yBottomRight; y++ )
00382 for( x = xTopLeft; x <= xBottomRight; x++ )
00383 MapUnitToSliceGroupMap[ y * img->PicWidthInMbs + x ] = iGroup;
00384 }
00385 }
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399 static void FmoGenerateType3MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps )
00400 {
00401 unsigned i, k;
00402 int leftBound, topBound, rightBound, bottomBound;
00403 int x, y, xDir, yDir;
00404 int mapUnitVacant;
00405
00406 unsigned mapUnitsInSliceGroup0 = imin((pps->slice_group_change_rate_minus1 + 1) * img->slice_group_change_cycle, PicSizeInMapUnits);
00407
00408 for( i = 0; i < PicSizeInMapUnits; i++ )
00409 MapUnitToSliceGroupMap[ i ] = 2;
00410
00411 x = ( img->PicWidthInMbs - pps->slice_group_change_direction_flag ) / 2;
00412 y = ( img->PicHeightInMapUnits - pps->slice_group_change_direction_flag ) / 2;
00413
00414 leftBound = x;
00415 topBound = y;
00416 rightBound = x;
00417 bottomBound = y;
00418
00419 xDir = pps->slice_group_change_direction_flag - 1;
00420 yDir = pps->slice_group_change_direction_flag;
00421
00422 for( k = 0; k < PicSizeInMapUnits; k += mapUnitVacant )
00423 {
00424 mapUnitVacant = ( MapUnitToSliceGroupMap[ y * img->PicWidthInMbs + x ] == 2 );
00425 if( mapUnitVacant )
00426 MapUnitToSliceGroupMap[ y * img->PicWidthInMbs + x ] = ( k >= mapUnitsInSliceGroup0 );
00427
00428 if( xDir == -1 && x == leftBound )
00429 {
00430 leftBound = imax( leftBound - 1, 0 );
00431 x = leftBound;
00432 xDir = 0;
00433 yDir = 2 * pps->slice_group_change_direction_flag - 1;
00434 }
00435 else
00436 if( xDir == 1 && x == rightBound )
00437 {
00438 rightBound = imin( rightBound + 1, (int)img->PicWidthInMbs - 1 );
00439 x = rightBound;
00440 xDir = 0;
00441 yDir = 1 - 2 * pps->slice_group_change_direction_flag;
00442 }
00443 else
00444 if( yDir == -1 && y == topBound )
00445 {
00446 topBound = imax( topBound - 1, 0 );
00447 y = topBound;
00448 xDir = 1 - 2 * pps->slice_group_change_direction_flag;
00449 yDir = 0;
00450 }
00451 else
00452 if( yDir == 1 && y == bottomBound )
00453 {
00454 bottomBound = imin( bottomBound + 1, (int)img->PicHeightInMapUnits - 1 );
00455 y = bottomBound;
00456 xDir = 2 * pps->slice_group_change_direction_flag - 1;
00457 yDir = 0;
00458 }
00459 else
00460 {
00461 x = x + xDir;
00462 y = y + yDir;
00463 }
00464 }
00465
00466 }
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479 static void FmoGenerateType4MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps )
00480 {
00481
00482 unsigned mapUnitsInSliceGroup0 = imin((pps->slice_group_change_rate_minus1 + 1) * img->slice_group_change_cycle, PicSizeInMapUnits);
00483 unsigned sizeOfUpperLeftGroup = pps->slice_group_change_direction_flag ? ( PicSizeInMapUnits - mapUnitsInSliceGroup0 ) : mapUnitsInSliceGroup0;
00484
00485 unsigned i;
00486
00487 for( i = 0; i < PicSizeInMapUnits; i++ )
00488 if( i < sizeOfUpperLeftGroup )
00489 MapUnitToSliceGroupMap[ i ] = pps->slice_group_change_direction_flag;
00490 else
00491 MapUnitToSliceGroupMap[ i ] = 1 - pps->slice_group_change_direction_flag;
00492
00493 }
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506 static void FmoGenerateType5MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps )
00507 {
00508
00509 unsigned mapUnitsInSliceGroup0 = imin((pps->slice_group_change_rate_minus1 + 1) * img->slice_group_change_cycle, PicSizeInMapUnits);
00510 unsigned sizeOfUpperLeftGroup = pps->slice_group_change_direction_flag ? ( PicSizeInMapUnits - mapUnitsInSliceGroup0 ) : mapUnitsInSliceGroup0;
00511
00512 unsigned i,j, k = 0;
00513
00514 for( j = 0; j < img->PicWidthInMbs; j++ )
00515 for( i = 0; i < img->PicHeightInMapUnits; i++ )
00516 if( k++ < sizeOfUpperLeftGroup )
00517 MapUnitToSliceGroupMap[ i * img->PicWidthInMbs + j ] = pps->slice_group_change_direction_flag;
00518 else
00519 MapUnitToSliceGroupMap[ i * img->PicWidthInMbs + j ] = 1 - pps->slice_group_change_direction_flag;
00520
00521 }
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534 static void FmoGenerateType6MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps )
00535 {
00536 unsigned i;
00537 for (i=0; i<PicSizeInMapUnits; i++)
00538 {
00539 MapUnitToSliceGroupMap[i] = pps->slice_group_id[i];
00540 }
00541 }
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552 int FmoStartPicture ()
00553 {
00554 int i;
00555
00556 assert (MBAmap != NULL);
00557
00558 for (i=0; i<MAXSLICEGROUPIDS; i++)
00559 FirstMBInSlice[i] = FmoGetFirstMBOfSliceGroup (i);
00560 return 0;
00561 }
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575 int FmoEndPicture ()
00576 {
00577
00578 return 0;
00579 }
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591 int FmoMB2SliceGroup ( int mb)
00592 {
00593 assert (mb < (int)img->PicSizeInMbs);
00594 assert (MBAmap != NULL);
00595 return MBAmap[mb];
00596 }
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608 int FmoGetNextMBNr (int CurrentMbNr)
00609 {
00610
00611 int SliceGroupID = FmoMB2SliceGroup (CurrentMbNr);
00612
00613 while (++CurrentMbNr<(int)img->PicSizeInMbs && MBAmap[CurrentMbNr] != SliceGroupID)
00614 ;
00615
00616 if (CurrentMbNr >= (int)img->PicSizeInMbs)
00617 return -1;
00618 else
00619 return CurrentMbNr;
00620 }
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633 int FmoGetPreviousMBNr (int CurrentMbNr)
00634 {
00635
00636 int SliceGroupID = FmoMB2SliceGroup (CurrentMbNr);
00637 CurrentMbNr--;
00638 while (CurrentMbNr>=0 && MBAmap[CurrentMbNr] != SliceGroupID)
00639 CurrentMbNr--;
00640
00641 if (CurrentMbNr < 0)
00642 return -1;
00643 else
00644 return CurrentMbNr;
00645 }
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658 int FmoGetFirstMBOfSliceGroup (int SliceGroupID)
00659 {
00660 int i = 0;
00661 while ((i<(int)img->PicSizeInMbs) && (FmoMB2SliceGroup (i) != SliceGroupID))
00662 i++;
00663
00664 if (i < (int)img->PicSizeInMbs)
00665 return i;
00666 else
00667 return -1;
00668 }
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684 int FmoGetLastCodedMBOfSliceGroup (int SliceGroupID)
00685 {
00686 int i;
00687 int LastMB = -1;
00688
00689 for (i=0; i<(int)img->PicSizeInMbs; i++)
00690 if (FmoMB2SliceGroup (i) == SliceGroupID)
00691 LastMB = i;
00692 return LastMB;
00693 }
00694
00695
00696 void FmoSetLastMacroblockInSlice ( int mb)
00697 {
00698
00699
00700
00701
00702 int currSliceGroup = FmoMB2SliceGroup (mb);
00703 assert (mb >= 0);
00704 mb = FmoGetNextMBNr (mb);
00705 FirstMBInSlice[currSliceGroup] = mb;
00706 }
00707
00708 int FmoGetFirstMacroblockInSlice ( int SliceGroup)
00709 {
00710 return FirstMBInSlice[SliceGroup];
00711
00712
00713 }
00714
00715
00716 int FmoSliceGroupCompletelyCoded( int SliceGroupID)
00717 {
00718 if (FmoGetFirstMacroblockInSlice (SliceGroupID) < 0)
00719 return TRUE;
00720 else
00721 return FALSE;
00722 }
00723
00724
00725