00001
00017 #include "global.h"
00018 #include "elements.h"
00019 #include "defines.h"
00020 #include "header.h"
00021 #include "fmo.h"
00022
00023
00024
00025 int *MbToSliceGroupMap = NULL;
00026 int *MapUnitToSliceGroupMap = NULL;
00027
00028 static int NumberOfSliceGroups;
00029
00030 static void FmoGenerateType0MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits );
00031 static void FmoGenerateType1MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits );
00032 static void FmoGenerateType2MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits );
00033 static void FmoGenerateType3MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits );
00034 static void FmoGenerateType4MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits );
00035 static void FmoGenerateType5MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits );
00036 static void FmoGenerateType6MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits );
00037
00038
00052 static int FmoGenerateMapUnitToSliceGroupMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps)
00053 {
00054 unsigned int NumSliceGroupMapUnits;
00055
00056 NumSliceGroupMapUnits = (sps->pic_height_in_map_units_minus1+1)* (sps->pic_width_in_mbs_minus1+1);
00057
00058 if (pps->slice_group_map_type == 6)
00059 {
00060 if ((pps->num_slice_group_map_units_minus1+1) != NumSliceGroupMapUnits)
00061 {
00062 error ("wrong pps->num_slice_group_map_units_minus1 for used SPS and FMO type 6", 500);
00063 }
00064 }
00065
00066
00067 if (MapUnitToSliceGroupMap)
00068 free (MapUnitToSliceGroupMap);
00069 if ((MapUnitToSliceGroupMap = malloc ((NumSliceGroupMapUnits) * sizeof (int))) == NULL)
00070 {
00071 printf ("cannot allocated %d bytes for MapUnitToSliceGroupMap, exit\n", (int) ( (pps->num_slice_group_map_units_minus1+1) * sizeof (int)));
00072 exit (-1);
00073 }
00074
00075 if (pps->num_slice_groups_minus1 == 0)
00076 {
00077 memset (MapUnitToSliceGroupMap, 0, NumSliceGroupMapUnits * sizeof (int));
00078 return 0;
00079 }
00080
00081 switch (pps->slice_group_map_type)
00082 {
00083 case 0:
00084 FmoGenerateType0MapUnitMap (pps, sps, NumSliceGroupMapUnits);
00085 break;
00086 case 1:
00087 FmoGenerateType1MapUnitMap (pps, sps, NumSliceGroupMapUnits);
00088 break;
00089 case 2:
00090 FmoGenerateType2MapUnitMap (pps, sps, NumSliceGroupMapUnits);
00091 break;
00092 case 3:
00093 FmoGenerateType3MapUnitMap (pps, sps, NumSliceGroupMapUnits);
00094 break;
00095 case 4:
00096 FmoGenerateType4MapUnitMap (pps, sps, NumSliceGroupMapUnits);
00097 break;
00098 case 5:
00099 FmoGenerateType5MapUnitMap (pps, sps, NumSliceGroupMapUnits);
00100 break;
00101 case 6:
00102 FmoGenerateType6MapUnitMap (pps, sps, NumSliceGroupMapUnits);
00103 break;
00104 default:
00105 printf ("Illegal slice_group_map_type %d , exit \n", (int) pps->slice_group_map_type);
00106 exit (-1);
00107 }
00108 return 0;
00109 }
00110
00111
00124 static int FmoGenerateMbToSliceGroupMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps)
00125 {
00126 unsigned i;
00127
00128
00129 if (MbToSliceGroupMap)
00130 free (MbToSliceGroupMap);
00131
00132 if ((MbToSliceGroupMap = malloc ((img->PicSizeInMbs) * sizeof (int))) == NULL)
00133 {
00134 printf ("cannot allocate %d bytes for MbToSliceGroupMap, exit\n", (int) ((img->PicSizeInMbs) * sizeof (int)));
00135 exit (-1);
00136 }
00137
00138
00139 if ((sps->frame_mbs_only_flag)|| img->field_pic_flag)
00140 {
00141 for (i=0; i<img->PicSizeInMbs; i++)
00142 {
00143 MbToSliceGroupMap[i] = MapUnitToSliceGroupMap[i];
00144 }
00145 }
00146 else
00147 if (sps->mb_adaptive_frame_field_flag && (!img->field_pic_flag))
00148 {
00149 for (i=0; i<img->PicSizeInMbs; i++)
00150 {
00151 MbToSliceGroupMap[i] = MapUnitToSliceGroupMap[i/2];
00152 }
00153 }
00154 else
00155 {
00156 for (i=0; i<img->PicSizeInMbs; i++)
00157 {
00158 MbToSliceGroupMap[i] = MapUnitToSliceGroupMap[(i/(2*img->PicWidthInMbs))*img->PicWidthInMbs+(i%img->PicWidthInMbs)];
00159 }
00160 }
00161 return 0;
00162 }
00163
00164
00176 int FmoInit(pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps)
00177 {
00178 #ifdef PRINT_FMO_MAPS
00179 unsigned i,j;
00180 #endif
00181
00182 FmoGenerateMapUnitToSliceGroupMap(pps, sps);
00183 FmoGenerateMbToSliceGroupMap(pps, sps);
00184
00185 NumberOfSliceGroups = pps->num_slice_groups_minus1+1;
00186
00187 #ifdef PRINT_FMO_MAPS
00188 printf("\n");
00189 printf("FMO Map (Units):\n");
00190
00191 for (j=0; j<img->PicHeightInMapUnits; j++)
00192 {
00193 for (i=0; i<img->PicWidthInMbs; i++)
00194 {
00195 printf("%c",48+MapUnitToSliceGroupMap[i+j*img->PicWidthInMbs]);
00196 }
00197 printf("\n");
00198 }
00199 printf("\n");
00200 printf("FMO Map (Mb):\n");
00201
00202 for (j=0; j<img->PicHeightInMbs; j++)
00203 {
00204 for (i=0; i<img->PicWidthInMbs; i++)
00205 {
00206 printf("%c",48+MbToSliceGroupMap[i+j*img->PicWidthInMbs]);
00207 }
00208 printf("\n");
00209 }
00210 printf("\n");
00211
00212 #endif
00213
00214 return 0;
00215 }
00216
00217
00224 int FmoFinit()
00225 {
00226 if (MbToSliceGroupMap)
00227 {
00228 free (MbToSliceGroupMap);
00229 MbToSliceGroupMap = NULL;
00230 }
00231 if (MapUnitToSliceGroupMap)
00232 {
00233 free (MapUnitToSliceGroupMap);
00234 MapUnitToSliceGroupMap = NULL;
00235 }
00236 return 0;
00237 }
00238
00239
00249 int FmoGetNumberOfSliceGroup()
00250 {
00251 return NumberOfSliceGroups;
00252 }
00253
00254
00267 int FmoGetLastMBOfPicture()
00268 {
00269 return FmoGetLastMBInSliceGroup (FmoGetNumberOfSliceGroup()-1);
00270 }
00271
00272
00283 int FmoGetLastMBInSliceGroup (int SliceGroup)
00284 {
00285 int i;
00286
00287 for (i=img->PicSizeInMbs-1; i>=0; i--)
00288 if (FmoGetSliceGroupId (i) == SliceGroup)
00289 return i;
00290 return -1;
00291
00292 }
00293
00294
00304 int FmoGetSliceGroupId (int mb)
00305 {
00306 assert (mb < (int)img->PicSizeInMbs);
00307 assert (MbToSliceGroupMap != NULL);
00308 return MbToSliceGroupMap[mb];
00309 }
00310
00311
00322 int FmoGetNextMBNr (int CurrentMbNr)
00323 {
00324 int SliceGroup = FmoGetSliceGroupId (CurrentMbNr);
00325
00326 while (++CurrentMbNr<(int)img->PicSizeInMbs && MbToSliceGroupMap [CurrentMbNr] != SliceGroup)
00327 ;
00328
00329 if (CurrentMbNr >= (int)img->PicSizeInMbs)
00330 return -1;
00331 else
00332 return CurrentMbNr;
00333 }
00334
00335
00343 static void FmoGenerateType0MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits )
00344 {
00345 unsigned iGroup, j;
00346 unsigned i = 0;
00347 do
00348 {
00349 for( iGroup = 0;
00350 (iGroup <= pps->num_slice_groups_minus1) && (i < PicSizeInMapUnits);
00351 i += pps->run_length_minus1[iGroup++] + 1 )
00352 {
00353 for( j = 0; j <= pps->run_length_minus1[ iGroup ] && i + j < PicSizeInMapUnits; j++ )
00354 MapUnitToSliceGroupMap[i+j] = iGroup;
00355 }
00356 }
00357 while( i < PicSizeInMapUnits );
00358 }
00359
00360
00368 static void FmoGenerateType1MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits )
00369 {
00370 unsigned i;
00371 for( i = 0; i < PicSizeInMapUnits; i++ )
00372 {
00373 MapUnitToSliceGroupMap[i] = ((i%img->PicWidthInMbs)+(((i/img->PicWidthInMbs)*(pps->num_slice_groups_minus1+1))/2))
00374 %(pps->num_slice_groups_minus1+1);
00375 }
00376 }
00377
00385 static void FmoGenerateType2MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits )
00386 {
00387 int iGroup;
00388 unsigned i, x, y;
00389 unsigned yTopLeft, xTopLeft, yBottomRight, xBottomRight;
00390
00391 for( i = 0; i < PicSizeInMapUnits; i++ )
00392 MapUnitToSliceGroupMap[ i ] = pps->num_slice_groups_minus1;
00393
00394 for( iGroup = pps->num_slice_groups_minus1 - 1 ; iGroup >= 0; iGroup-- )
00395 {
00396 yTopLeft = pps->top_left[ iGroup ] / img->PicWidthInMbs;
00397 xTopLeft = pps->top_left[ iGroup ] % img->PicWidthInMbs;
00398 yBottomRight = pps->bottom_right[ iGroup ] / img->PicWidthInMbs;
00399 xBottomRight = pps->bottom_right[ iGroup ] % img->PicWidthInMbs;
00400 for( y = yTopLeft; y <= yBottomRight; y++ )
00401 for( x = xTopLeft; x <= xBottomRight; x++ )
00402 MapUnitToSliceGroupMap[ y * img->PicWidthInMbs + x ] = iGroup;
00403 }
00404 }
00405
00406
00414 static void FmoGenerateType3MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits )
00415 {
00416 unsigned i, k;
00417 int leftBound, topBound, rightBound, bottomBound;
00418 int x, y, xDir, yDir;
00419 int mapUnitVacant;
00420
00421 unsigned mapUnitsInSliceGroup0 = imin((pps->slice_group_change_rate_minus1 + 1) * img->slice_group_change_cycle, PicSizeInMapUnits);
00422
00423 for( i = 0; i < PicSizeInMapUnits; i++ )
00424 MapUnitToSliceGroupMap[ i ] = 2;
00425
00426 x = ( img->PicWidthInMbs - pps->slice_group_change_direction_flag ) / 2;
00427 y = ( img->PicHeightInMapUnits - pps->slice_group_change_direction_flag ) / 2;
00428
00429 leftBound = x;
00430 topBound = y;
00431 rightBound = x;
00432 bottomBound = y;
00433
00434 xDir = pps->slice_group_change_direction_flag - 1;
00435 yDir = pps->slice_group_change_direction_flag;
00436
00437 for( k = 0; k < PicSizeInMapUnits; k += mapUnitVacant )
00438 {
00439 mapUnitVacant = ( MapUnitToSliceGroupMap[ y * img->PicWidthInMbs + x ] == 2 );
00440 if( mapUnitVacant )
00441 MapUnitToSliceGroupMap[ y * img->PicWidthInMbs + x ] = ( k >= mapUnitsInSliceGroup0 );
00442
00443 if( xDir == -1 && x == leftBound )
00444 {
00445 leftBound = imax( leftBound - 1, 0 );
00446 x = leftBound;
00447 xDir = 0;
00448 yDir = 2 * pps->slice_group_change_direction_flag - 1;
00449 }
00450 else
00451 if( xDir == 1 && x == rightBound )
00452 {
00453 rightBound = imin( rightBound + 1, (int)img->PicWidthInMbs - 1 );
00454 x = rightBound;
00455 xDir = 0;
00456 yDir = 1 - 2 * pps->slice_group_change_direction_flag;
00457 }
00458 else
00459 if( yDir == -1 && y == topBound )
00460 {
00461 topBound = imax( topBound - 1, 0 );
00462 y = topBound;
00463 xDir = 1 - 2 * pps->slice_group_change_direction_flag;
00464 yDir = 0;
00465 }
00466 else
00467 if( yDir == 1 && y == bottomBound )
00468 {
00469 bottomBound = imin( bottomBound + 1, (int)img->PicHeightInMapUnits - 1 );
00470 y = bottomBound;
00471 xDir = 2 * pps->slice_group_change_direction_flag - 1;
00472 yDir = 0;
00473 }
00474 else
00475 {
00476 x = x + xDir;
00477 y = y + yDir;
00478 }
00479 }
00480
00481 }
00482
00490 static void FmoGenerateType4MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits )
00491 {
00492
00493 unsigned mapUnitsInSliceGroup0 = imin((pps->slice_group_change_rate_minus1 + 1) * img->slice_group_change_cycle, PicSizeInMapUnits);
00494 unsigned sizeOfUpperLeftGroup = pps->slice_group_change_direction_flag ? ( PicSizeInMapUnits - mapUnitsInSliceGroup0 ) : mapUnitsInSliceGroup0;
00495
00496 unsigned i;
00497
00498 for( i = 0; i < PicSizeInMapUnits; i++ )
00499 if( i < sizeOfUpperLeftGroup )
00500 MapUnitToSliceGroupMap[ i ] = pps->slice_group_change_direction_flag;
00501 else
00502 MapUnitToSliceGroupMap[ i ] = 1 - pps->slice_group_change_direction_flag;
00503
00504 }
00505
00513 static void FmoGenerateType5MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits )
00514 {
00515
00516 unsigned mapUnitsInSliceGroup0 = imin((pps->slice_group_change_rate_minus1 + 1) * img->slice_group_change_cycle, PicSizeInMapUnits);
00517 unsigned sizeOfUpperLeftGroup = pps->slice_group_change_direction_flag ? ( PicSizeInMapUnits - mapUnitsInSliceGroup0 ) : mapUnitsInSliceGroup0;
00518
00519 unsigned i,j, k = 0;
00520
00521 for( j = 0; j < img->PicWidthInMbs; j++ )
00522 for( i = 0; i < img->PicHeightInMapUnits; i++ )
00523 if( k++ < sizeOfUpperLeftGroup )
00524 MapUnitToSliceGroupMap[ i * img->PicWidthInMbs + j ] = pps->slice_group_change_direction_flag;
00525 else
00526 MapUnitToSliceGroupMap[ i * img->PicWidthInMbs + j ] = 1 - pps->slice_group_change_direction_flag;
00527
00528 }
00529
00537 static void FmoGenerateType6MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits )
00538 {
00539 unsigned i;
00540 for (i=0; i<PicSizeInMapUnits; i++)
00541 {
00542 MapUnitToSliceGroupMap[i] = pps->slice_group_id[i];
00543 }
00544 }
00545