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 static void FmoGenerateType0MapUnitMap (ImageParameters *p_Img, unsigned PicSizeInMapUnits );
00026 static void FmoGenerateType1MapUnitMap (ImageParameters *p_Img, unsigned PicSizeInMapUnits );
00027 static void FmoGenerateType2MapUnitMap (ImageParameters *p_Img, unsigned PicSizeInMapUnits );
00028 static void FmoGenerateType3MapUnitMap (ImageParameters *p_Img, unsigned PicSizeInMapUnits );
00029 static void FmoGenerateType4MapUnitMap (ImageParameters *p_Img, unsigned PicSizeInMapUnits );
00030 static void FmoGenerateType5MapUnitMap (ImageParameters *p_Img, unsigned PicSizeInMapUnits );
00031 static void FmoGenerateType6MapUnitMap (ImageParameters *p_Img, unsigned PicSizeInMapUnits );
00032
00033
00045 static int FmoGenerateMapUnitToSliceGroupMap (ImageParameters *p_Img)
00046 {
00047 seq_parameter_set_rbsp_t* sps = p_Img->active_sps;
00048 pic_parameter_set_rbsp_t* pps = p_Img->active_pps;
00049
00050 unsigned int NumSliceGroupMapUnits;
00051
00052 NumSliceGroupMapUnits = (sps->pic_height_in_map_units_minus1+1)* (sps->pic_width_in_mbs_minus1+1);
00053
00054 if (pps->slice_group_map_type == 6)
00055 {
00056 if ((pps->pic_size_in_map_units_minus1 + 1) != NumSliceGroupMapUnits)
00057 {
00058 error ("wrong pps->pic_size_in_map_units_minus1 for used SPS and FMO type 6", 500);
00059 }
00060 }
00061
00062
00063 if (p_Img->MapUnitToSliceGroupMap)
00064 free (p_Img->MapUnitToSliceGroupMap);
00065 if ((p_Img->MapUnitToSliceGroupMap = malloc ((NumSliceGroupMapUnits) * sizeof (int))) == NULL)
00066 {
00067 printf ("cannot allocated %d bytes for p_Img->MapUnitToSliceGroupMap, exit\n", (int) ( (pps->pic_size_in_map_units_minus1+1) * sizeof (int)));
00068 exit (-1);
00069 }
00070
00071 if (pps->num_slice_groups_minus1 == 0)
00072 {
00073 memset (p_Img->MapUnitToSliceGroupMap, 0, NumSliceGroupMapUnits * sizeof (int));
00074 return 0;
00075 }
00076
00077 switch (pps->slice_group_map_type)
00078 {
00079 case 0:
00080 FmoGenerateType0MapUnitMap (p_Img, NumSliceGroupMapUnits);
00081 break;
00082 case 1:
00083 FmoGenerateType1MapUnitMap (p_Img, NumSliceGroupMapUnits);
00084 break;
00085 case 2:
00086 FmoGenerateType2MapUnitMap (p_Img, NumSliceGroupMapUnits);
00087 break;
00088 case 3:
00089 FmoGenerateType3MapUnitMap (p_Img, NumSliceGroupMapUnits);
00090 break;
00091 case 4:
00092 FmoGenerateType4MapUnitMap (p_Img, NumSliceGroupMapUnits);
00093 break;
00094 case 5:
00095 FmoGenerateType5MapUnitMap (p_Img, NumSliceGroupMapUnits);
00096 break;
00097 case 6:
00098 FmoGenerateType6MapUnitMap (p_Img, NumSliceGroupMapUnits);
00099 break;
00100 default:
00101 printf ("Illegal slice_group_map_type %d , exit \n", (int) pps->slice_group_map_type);
00102 exit (-1);
00103 }
00104 return 0;
00105 }
00106
00107
00118 static int FmoGenerateMbToSliceGroupMap (ImageParameters *p_Img)
00119 {
00120 seq_parameter_set_rbsp_t* sps = p_Img->active_sps;
00121
00122 unsigned i;
00123
00124
00125 if (p_Img->MbToSliceGroupMap)
00126 free (p_Img->MbToSliceGroupMap);
00127
00128 if ((p_Img->MbToSliceGroupMap = malloc ((p_Img->PicSizeInMbs) * sizeof (int))) == NULL)
00129 {
00130 printf ("cannot allocate %d bytes for p_Img->MbToSliceGroupMap, exit\n", (int) ((p_Img->PicSizeInMbs) * sizeof (int)));
00131 exit (-1);
00132 }
00133
00134
00135 if ((sps->frame_mbs_only_flag)|| p_Img->field_pic_flag)
00136 {
00137 for (i=0; i<p_Img->PicSizeInMbs; i++)
00138 {
00139 p_Img->MbToSliceGroupMap[i] = p_Img->MapUnitToSliceGroupMap[i];
00140 }
00141 }
00142 else
00143 if (sps->mb_adaptive_frame_field_flag && (!p_Img->field_pic_flag))
00144 {
00145 for (i=0; i<p_Img->PicSizeInMbs; i++)
00146 {
00147 p_Img->MbToSliceGroupMap[i] = p_Img->MapUnitToSliceGroupMap[i/2];
00148 }
00149 }
00150 else
00151 {
00152 for (i=0; i<p_Img->PicSizeInMbs; i++)
00153 {
00154 p_Img->MbToSliceGroupMap[i] = p_Img->MapUnitToSliceGroupMap[(i/(2*p_Img->PicWidthInMbs))*p_Img->PicWidthInMbs+(i%p_Img->PicWidthInMbs)];
00155 }
00156 }
00157 return 0;
00158 }
00159
00160
00170 int fmo_init(ImageParameters *p_Img)
00171 {
00172 pic_parameter_set_rbsp_t* pps = p_Img->active_pps;
00173
00174 #ifdef PRINT_FMO_MAPS
00175 unsigned i,j;
00176 #endif
00177
00178 FmoGenerateMapUnitToSliceGroupMap(p_Img);
00179 FmoGenerateMbToSliceGroupMap(p_Img);
00180
00181 p_Img->NumberOfSliceGroups = pps->num_slice_groups_minus1 + 1;
00182
00183 #ifdef PRINT_FMO_MAPS
00184 printf("\n");
00185 printf("FMO Map (Units):\n");
00186
00187 for (j=0; j<p_Img->PicHeightInMapUnits; j++)
00188 {
00189 for (i=0; i<p_Img->PicWidthInMbs; i++)
00190 {
00191 printf("%c",48+p_Img->MapUnitToSliceGroupMap[i+j*p_Img->PicWidthInMbs]);
00192 }
00193 printf("\n");
00194 }
00195 printf("\n");
00196 printf("FMO Map (Mb):\n");
00197
00198 for (j=0; j<p_Img->PicHeightInMbs; j++)
00199 {
00200 for (i=0; i<p_Img->PicWidthInMbs; i++)
00201 {
00202 printf("%c",48 + p_Img->MbToSliceGroupMap[i + j * p_Img->PicWidthInMbs]);
00203 }
00204 printf("\n");
00205 }
00206 printf("\n");
00207
00208 #endif
00209
00210 return 0;
00211 }
00212
00213
00220 int FmoFinit(ImageParameters *p_Img)
00221 {
00222 if (p_Img->MbToSliceGroupMap)
00223 {
00224 free (p_Img->MbToSliceGroupMap);
00225 p_Img->MbToSliceGroupMap = NULL;
00226 }
00227 if (p_Img->MapUnitToSliceGroupMap)
00228 {
00229 free (p_Img->MapUnitToSliceGroupMap);
00230 p_Img->MapUnitToSliceGroupMap = NULL;
00231 }
00232 return 0;
00233 }
00234
00235
00245 int FmoGetNumberOfSliceGroup(ImageParameters *p_Img)
00246 {
00247 return p_Img->NumberOfSliceGroups;
00248 }
00249
00250
00263 int FmoGetLastMBOfPicture(ImageParameters *p_Img)
00264 {
00265 return FmoGetLastMBInSliceGroup (p_Img, FmoGetNumberOfSliceGroup(p_Img)-1);
00266 }
00267
00268
00279 int FmoGetLastMBInSliceGroup (ImageParameters *p_Img, int SliceGroup)
00280 {
00281 int i;
00282
00283 for (i=p_Img->PicSizeInMbs-1; i>=0; i--)
00284 if (FmoGetSliceGroupId (p_Img, i) == SliceGroup)
00285 return i;
00286 return -1;
00287
00288 }
00289
00290
00302 int FmoGetSliceGroupId (ImageParameters *p_Img, int mb)
00303 {
00304 assert (mb < (int) p_Img->PicSizeInMbs);
00305 assert (p_Img->MbToSliceGroupMap != NULL);
00306 return p_Img->MbToSliceGroupMap[mb];
00307 }
00308
00309
00322 int FmoGetNextMBNr (ImageParameters *p_Img, int CurrentMbNr)
00323 {
00324 int SliceGroup = FmoGetSliceGroupId (p_Img, CurrentMbNr);
00325
00326 while (++CurrentMbNr<(int)p_Img->PicSizeInMbs && p_Img->MbToSliceGroupMap [CurrentMbNr] != SliceGroup)
00327 ;
00328
00329 if (CurrentMbNr >= (int)p_Img->PicSizeInMbs)
00330 return -1;
00331 else
00332 return CurrentMbNr;
00333 }
00334
00335
00343 static void FmoGenerateType0MapUnitMap (ImageParameters *p_Img, unsigned PicSizeInMapUnits )
00344 {
00345 pic_parameter_set_rbsp_t* pps = p_Img->active_pps;
00346 unsigned iGroup, j;
00347 unsigned i = 0;
00348 do
00349 {
00350 for( iGroup = 0;
00351 (iGroup <= pps->num_slice_groups_minus1) && (i < PicSizeInMapUnits);
00352 i += pps->run_length_minus1[iGroup++] + 1 )
00353 {
00354 for( j = 0; j <= pps->run_length_minus1[ iGroup ] && i + j < PicSizeInMapUnits; j++ )
00355 p_Img->MapUnitToSliceGroupMap[i+j] = iGroup;
00356 }
00357 }
00358 while( i < PicSizeInMapUnits );
00359 }
00360
00361
00369 static void FmoGenerateType1MapUnitMap (ImageParameters *p_Img, unsigned PicSizeInMapUnits )
00370 {
00371 pic_parameter_set_rbsp_t* pps = p_Img->active_pps;
00372 unsigned i;
00373 for( i = 0; i < PicSizeInMapUnits; i++ )
00374 {
00375 p_Img->MapUnitToSliceGroupMap[i] = ((i%p_Img->PicWidthInMbs)+(((i/p_Img->PicWidthInMbs)*(pps->num_slice_groups_minus1+1))/2))
00376 %(pps->num_slice_groups_minus1+1);
00377 }
00378 }
00379
00387 static void FmoGenerateType2MapUnitMap (ImageParameters *p_Img, unsigned PicSizeInMapUnits )
00388 {
00389 pic_parameter_set_rbsp_t* pps = p_Img->active_pps;
00390 int iGroup;
00391 unsigned i, x, y;
00392 unsigned yTopLeft, xTopLeft, yBottomRight, xBottomRight;
00393
00394 for( i = 0; i < PicSizeInMapUnits; i++ )
00395 p_Img->MapUnitToSliceGroupMap[ i ] = pps->num_slice_groups_minus1;
00396
00397 for( iGroup = pps->num_slice_groups_minus1 - 1 ; iGroup >= 0; iGroup-- )
00398 {
00399 yTopLeft = pps->top_left[ iGroup ] / p_Img->PicWidthInMbs;
00400 xTopLeft = pps->top_left[ iGroup ] % p_Img->PicWidthInMbs;
00401 yBottomRight = pps->bottom_right[ iGroup ] / p_Img->PicWidthInMbs;
00402 xBottomRight = pps->bottom_right[ iGroup ] % p_Img->PicWidthInMbs;
00403 for( y = yTopLeft; y <= yBottomRight; y++ )
00404 for( x = xTopLeft; x <= xBottomRight; x++ )
00405 p_Img->MapUnitToSliceGroupMap[ y * p_Img->PicWidthInMbs + x ] = iGroup;
00406 }
00407 }
00408
00409
00417 static void FmoGenerateType3MapUnitMap (ImageParameters *p_Img, unsigned PicSizeInMapUnits )
00418 {
00419 pic_parameter_set_rbsp_t* pps = p_Img->active_pps;
00420 unsigned i, k;
00421 int leftBound, topBound, rightBound, bottomBound;
00422 int x, y, xDir, yDir;
00423 int mapUnitVacant;
00424
00425 unsigned mapUnitsInSliceGroup0 = imin((pps->slice_group_change_rate_minus1 + 1) * p_Img->slice_group_change_cycle, PicSizeInMapUnits);
00426
00427 for( i = 0; i < PicSizeInMapUnits; i++ )
00428 p_Img->MapUnitToSliceGroupMap[ i ] = 2;
00429
00430 x = ( p_Img->PicWidthInMbs - pps->slice_group_change_direction_flag ) / 2;
00431 y = ( p_Img->PicHeightInMapUnits - pps->slice_group_change_direction_flag ) / 2;
00432
00433 leftBound = x;
00434 topBound = y;
00435 rightBound = x;
00436 bottomBound = y;
00437
00438 xDir = pps->slice_group_change_direction_flag - 1;
00439 yDir = pps->slice_group_change_direction_flag;
00440
00441 for( k = 0; k < PicSizeInMapUnits; k += mapUnitVacant )
00442 {
00443 mapUnitVacant = ( p_Img->MapUnitToSliceGroupMap[ y * p_Img->PicWidthInMbs + x ] == 2 );
00444 if( mapUnitVacant )
00445 p_Img->MapUnitToSliceGroupMap[ y * p_Img->PicWidthInMbs + x ] = ( k >= mapUnitsInSliceGroup0 );
00446
00447 if( xDir == -1 && x == leftBound )
00448 {
00449 leftBound = imax( leftBound - 1, 0 );
00450 x = leftBound;
00451 xDir = 0;
00452 yDir = 2 * pps->slice_group_change_direction_flag - 1;
00453 }
00454 else
00455 if( xDir == 1 && x == rightBound )
00456 {
00457 rightBound = imin( rightBound + 1, (int)p_Img->PicWidthInMbs - 1 );
00458 x = rightBound;
00459 xDir = 0;
00460 yDir = 1 - 2 * pps->slice_group_change_direction_flag;
00461 }
00462 else
00463 if( yDir == -1 && y == topBound )
00464 {
00465 topBound = imax( topBound - 1, 0 );
00466 y = topBound;
00467 xDir = 1 - 2 * pps->slice_group_change_direction_flag;
00468 yDir = 0;
00469 }
00470 else
00471 if( yDir == 1 && y == bottomBound )
00472 {
00473 bottomBound = imin( bottomBound + 1, (int)p_Img->PicHeightInMapUnits - 1 );
00474 y = bottomBound;
00475 xDir = 2 * pps->slice_group_change_direction_flag - 1;
00476 yDir = 0;
00477 }
00478 else
00479 {
00480 x = x + xDir;
00481 y = y + yDir;
00482 }
00483 }
00484
00485 }
00486
00494 static void FmoGenerateType4MapUnitMap (ImageParameters *p_Img, unsigned PicSizeInMapUnits )
00495 {
00496 pic_parameter_set_rbsp_t* pps = p_Img->active_pps;
00497
00498 unsigned mapUnitsInSliceGroup0 = imin((pps->slice_group_change_rate_minus1 + 1) * p_Img->slice_group_change_cycle, PicSizeInMapUnits);
00499 unsigned sizeOfUpperLeftGroup = pps->slice_group_change_direction_flag ? ( PicSizeInMapUnits - mapUnitsInSliceGroup0 ) : mapUnitsInSliceGroup0;
00500
00501 unsigned i;
00502
00503 for( i = 0; i < PicSizeInMapUnits; i++ )
00504 if( i < sizeOfUpperLeftGroup )
00505 p_Img->MapUnitToSliceGroupMap[ i ] = pps->slice_group_change_direction_flag;
00506 else
00507 p_Img->MapUnitToSliceGroupMap[ i ] = 1 - pps->slice_group_change_direction_flag;
00508
00509 }
00510
00518 static void FmoGenerateType5MapUnitMap (ImageParameters *p_Img, unsigned PicSizeInMapUnits )
00519 {
00520 pic_parameter_set_rbsp_t* pps = p_Img->active_pps;
00521
00522 unsigned mapUnitsInSliceGroup0 = imin((pps->slice_group_change_rate_minus1 + 1) * p_Img->slice_group_change_cycle, PicSizeInMapUnits);
00523 unsigned sizeOfUpperLeftGroup = pps->slice_group_change_direction_flag ? ( PicSizeInMapUnits - mapUnitsInSliceGroup0 ) : mapUnitsInSliceGroup0;
00524
00525 unsigned i,j, k = 0;
00526
00527 for( j = 0; j < p_Img->PicWidthInMbs; j++ )
00528 for( i = 0; i < p_Img->PicHeightInMapUnits; i++ )
00529 if( k++ < sizeOfUpperLeftGroup )
00530 p_Img->MapUnitToSliceGroupMap[ i * p_Img->PicWidthInMbs + j ] = pps->slice_group_change_direction_flag;
00531 else
00532 p_Img->MapUnitToSliceGroupMap[ i * p_Img->PicWidthInMbs + j ] = 1 - pps->slice_group_change_direction_flag;
00533
00534 }
00535
00543 static void FmoGenerateType6MapUnitMap (ImageParameters *p_Img, unsigned PicSizeInMapUnits )
00544 {
00545 pic_parameter_set_rbsp_t* pps = p_Img->active_pps;
00546 unsigned i;
00547 for (i=0; i<PicSizeInMapUnits; i++)
00548 {
00549 p_Img->MapUnitToSliceGroupMap[i] = pps->slice_group_id[i];
00550 }
00551 }
00552