fmo.c
上传用户:hjq518
上传日期:2021-12-09
资源大小:5084k
文件大小:17k
源码类别:

Audio

开发平台:

Visual C++

  1. /*!
  2.  *****************************************************************************
  3.  *
  4.  * file fmo.c
  5.  *
  6.  * brief
  7.  *    Support for Flexible Macroblock Ordering (FMO)
  8.  *
  9.  * author
  10.  *    Main contributors (see contributors.h for copyright, address and affiliation details)
  11.  *    - Stephan Wenger      stewe@cs.tu-berlin.de
  12.  *    - Karsten Suehring    suehring@hhi.de
  13.  ******************************************************************************
  14.  */
  15. #include "global.h"
  16. #include "elements.h"
  17. #include "defines.h"
  18. #include "header.h"
  19. #include "fmo.h"
  20. //#define PRINT_FMO_MAPS
  21. int *MbToSliceGroupMap = NULL;
  22. int *MapUnitToSliceGroupMap = NULL;
  23. static int NumberOfSliceGroups;    // the number of slice groups -1 (0 == scan order, 7 == maximum)
  24. static void FmoGenerateType0MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits );
  25. static void FmoGenerateType1MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits );
  26. static void FmoGenerateType2MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits );
  27. static void FmoGenerateType3MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits );
  28. static void FmoGenerateType4MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits );
  29. static void FmoGenerateType5MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits );
  30. static void FmoGenerateType6MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits );
  31. /*!
  32.  ************************************************************************
  33.  * brief
  34.  *    Generates MapUnitToSliceGroupMap
  35.  *    Has to be called every time a new Picture Parameter Set is used
  36.  *
  37.  * param pps
  38.  *    Picture Parameter set to be used for map generation
  39.  * param sps
  40.  *    Sequence Parameter set to be used for map generation
  41.  *
  42.  ************************************************************************
  43.  */
  44. static int FmoGenerateMapUnitToSliceGroupMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps)
  45. {
  46.   unsigned int NumSliceGroupMapUnits;
  47.   NumSliceGroupMapUnits = (sps->pic_height_in_map_units_minus1+1)* (sps->pic_width_in_mbs_minus1+1);
  48.   if (pps->slice_group_map_type == 6)
  49.   {
  50.     if ((pps->num_slice_group_map_units_minus1+1) != NumSliceGroupMapUnits)
  51.     {
  52.       error ("wrong pps->num_slice_group_map_units_minus1 for used SPS and FMO type 6", 500);
  53.     }
  54.   }
  55.   // allocate memory for MapUnitToSliceGroupMap
  56.   if (MapUnitToSliceGroupMap)
  57.     free (MapUnitToSliceGroupMap);
  58.   if ((MapUnitToSliceGroupMap = malloc ((NumSliceGroupMapUnits) * sizeof (int))) == NULL)
  59.   {
  60.     printf ("cannot allocated %d bytes for MapUnitToSliceGroupMap, exitn", (int) ( (pps->num_slice_group_map_units_minus1+1) * sizeof (int)));
  61.     exit (-1);
  62.   }
  63.   if (pps->num_slice_groups_minus1 == 0)    // only one slice group
  64.   {
  65.     memset (MapUnitToSliceGroupMap, 0, NumSliceGroupMapUnits * sizeof (int));
  66.     return 0;
  67.   }
  68.   switch (pps->slice_group_map_type)
  69.   {
  70.   case 0:
  71.     FmoGenerateType0MapUnitMap (pps, sps, NumSliceGroupMapUnits);
  72.     break;
  73.   case 1:
  74.     FmoGenerateType1MapUnitMap (pps, sps, NumSliceGroupMapUnits);
  75.     break;
  76.   case 2:
  77.     FmoGenerateType2MapUnitMap (pps, sps, NumSliceGroupMapUnits);
  78.     break;
  79.   case 3:
  80.     FmoGenerateType3MapUnitMap (pps, sps, NumSliceGroupMapUnits);
  81.     break;
  82.   case 4:
  83.     FmoGenerateType4MapUnitMap (pps, sps, NumSliceGroupMapUnits);
  84.     break;
  85.   case 5:
  86.     FmoGenerateType5MapUnitMap (pps, sps, NumSliceGroupMapUnits);
  87.     break;
  88.   case 6:
  89.     FmoGenerateType6MapUnitMap (pps, sps, NumSliceGroupMapUnits);
  90.     break;
  91.   default:
  92.     printf ("Illegal slice_group_map_type %d , exit n", (int) pps->slice_group_map_type);
  93.     exit (-1);
  94.   }
  95.   return 0;
  96. }
  97. /*!
  98.  ************************************************************************
  99.  * brief
  100.  *    Generates MbToSliceGroupMap from MapUnitToSliceGroupMap
  101.  *
  102.  * param pps
  103.  *    Picture Parameter set to be used for map generation
  104.  * param sps
  105.  *    Sequence Parameter set to be used for map generation
  106.  *
  107.  ************************************************************************
  108.  */
  109. static int FmoGenerateMbToSliceGroupMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps)
  110. {
  111.   unsigned i;
  112.   // allocate memory for MbToSliceGroupMap
  113.   if (MbToSliceGroupMap)
  114.     free (MbToSliceGroupMap);
  115.   if ((MbToSliceGroupMap = malloc ((img->PicSizeInMbs) * sizeof (int))) == NULL)
  116.   {
  117.     printf ("cannot allocate %d bytes for MbToSliceGroupMap, exitn", (int) ((img->PicSizeInMbs) * sizeof (int)));
  118.     exit (-1);
  119.   }
  120.   if ((sps->frame_mbs_only_flag)|| img->field_pic_flag)
  121.   {
  122.     for (i=0; i<img->PicSizeInMbs; i++)
  123.     {
  124.       MbToSliceGroupMap[i] = MapUnitToSliceGroupMap[i];
  125.     }
  126.   }
  127.   else
  128.     if (sps->mb_adaptive_frame_field_flag  &&  (!img->field_pic_flag))
  129.     {
  130.       for (i=0; i<img->PicSizeInMbs; i++)
  131.       {
  132.         MbToSliceGroupMap[i] = MapUnitToSliceGroupMap[i/2];
  133.       }
  134.     }
  135.     else
  136.     {
  137.       for (i=0; i<img->PicSizeInMbs; i++)
  138.       {
  139.         MbToSliceGroupMap[i] = MapUnitToSliceGroupMap[(i/(2*img->PicWidthInMbs))*img->PicWidthInMbs+(i%img->PicWidthInMbs)];
  140.       }
  141.     }
  142.   return 0;
  143. }
  144. /*!
  145.  ************************************************************************
  146.  * brief
  147.  *    FMO initialization: Generates MapUnitToSliceGroupMap and MbToSliceGroupMap.
  148.  *
  149.  * param pps
  150.  *    Picture Parameter set to be used for map generation
  151.  * param sps
  152.  *    Sequence Parameter set to be used for map generation
  153.  ************************************************************************
  154.  */
  155. int FmoInit(pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps)
  156. {
  157. #ifdef PRINT_FMO_MAPS
  158.   unsigned i,j;
  159. #endif
  160.   FmoGenerateMapUnitToSliceGroupMap(pps, sps);
  161.   FmoGenerateMbToSliceGroupMap(pps, sps);
  162.   NumberOfSliceGroups = pps->num_slice_groups_minus1+1;
  163. #ifdef PRINT_FMO_MAPS
  164.   printf("n");
  165.   printf("FMO Map (Units):n");
  166.   for (j=0; j<img->PicHeightInMapUnits; j++)
  167.   {
  168.     for (i=0; i<img->PicWidthInMbs; i++)
  169.     {
  170.       printf("%c",48+MapUnitToSliceGroupMap[i+j*img->PicWidthInMbs]);
  171.     }
  172.     printf("n");
  173.   }
  174.   printf("n");
  175.   printf("FMO Map (Mb):n");
  176.   for (j=0; j<img->PicHeightInMbs; j++)
  177.   {
  178.     for (i=0; i<img->PicWidthInMbs; i++)
  179.     {
  180.       printf("%c",48+MbToSliceGroupMap[i+j*img->PicWidthInMbs]);
  181.     }
  182.     printf("n");
  183.   }
  184.   printf("n");
  185. #endif
  186.   return 0;
  187. }
  188. /*!
  189.  ************************************************************************
  190.  * brief
  191.  *    Free memory allocated by FMO functions
  192.  ************************************************************************
  193.  */
  194. int FmoFinit()
  195. {
  196.   if (MbToSliceGroupMap)
  197.   {
  198.     free (MbToSliceGroupMap);
  199.     MbToSliceGroupMap = NULL;
  200.   }
  201.   if (MapUnitToSliceGroupMap)
  202.   {
  203.     free (MapUnitToSliceGroupMap);
  204.     MapUnitToSliceGroupMap = NULL;
  205.   }
  206.   return 0;
  207. }
  208. /*!
  209.  ************************************************************************
  210.  * brief
  211.  *    FmoGetNumberOfSliceGroup()
  212.  *
  213.  * par Input:
  214.  *    None
  215.  ************************************************************************
  216.  */
  217. int FmoGetNumberOfSliceGroup()
  218. {
  219.   return NumberOfSliceGroups;
  220. }
  221. /*!
  222.  ************************************************************************
  223.  * brief
  224.  *    FmoGetLastMBOfPicture()
  225.  *    returns the macroblock number of the last MB in a picture.  This
  226.  *    mb happens to be the last macroblock of the picture if there is only
  227.  *    one slice group
  228.  *
  229.  * par Input:
  230.  *    None
  231.  ************************************************************************
  232.  */
  233. int FmoGetLastMBOfPicture()
  234. {
  235.   return FmoGetLastMBInSliceGroup (FmoGetNumberOfSliceGroup()-1);
  236. }
  237. /*!
  238.  ************************************************************************
  239.  * brief
  240.  *    FmoGetLastMBInSliceGroup: Returns MB number of last MB in SG
  241.  *
  242.  * par Input:
  243.  *    SliceGroupID (0 to 7)
  244.  ************************************************************************
  245.  */
  246. int FmoGetLastMBInSliceGroup (int SliceGroup)
  247. {
  248.   int i;
  249.   for (i=img->PicSizeInMbs-1; i>=0; i--)
  250.     if (FmoGetSliceGroupId (i) == SliceGroup)
  251.       return i;
  252.   return -1;
  253. }
  254. /*!
  255.  ************************************************************************
  256.  * brief
  257.  *    Returns SliceGroupID for a given MB
  258.  *
  259.  * param mb
  260.  *    Macroblock number (in scan order)
  261.  ************************************************************************
  262.  */
  263. int FmoGetSliceGroupId (int mb)
  264. {
  265.   assert (mb < (int)img->PicSizeInMbs);
  266.   assert (MbToSliceGroupMap != NULL);
  267.   return MbToSliceGroupMap[mb];
  268. }
  269. /*!
  270.  ************************************************************************
  271.  * brief
  272.  *    FmoGetNextMBBr: Returns the MB-Nr (in scan order) of the next
  273.  *    MB in the (scattered) Slice, -1 if the slice is finished
  274.  *
  275.  * param CurrentMbNr
  276.  *    number of the current macroblock
  277.  ************************************************************************
  278.  */
  279. int FmoGetNextMBNr (int CurrentMbNr)
  280. {
  281.   int SliceGroup = FmoGetSliceGroupId (CurrentMbNr);
  282.   while (++CurrentMbNr<(int)img->PicSizeInMbs && MbToSliceGroupMap [CurrentMbNr] != SliceGroup)
  283.     ;
  284.   if (CurrentMbNr >= (int)img->PicSizeInMbs)
  285.     return -1;    // No further MB in this slice (could be end of picture)
  286.   else
  287.     return CurrentMbNr;
  288. }
  289. /*!
  290.  ************************************************************************
  291.  * brief
  292.  *    Generate interleaved slice group map type MapUnit map (type 0)
  293.  *
  294.  ************************************************************************
  295.  */
  296. static void FmoGenerateType0MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits )
  297. {
  298.   unsigned iGroup, j;
  299.   unsigned i = 0;
  300.   do
  301.   {
  302.     for( iGroup = 0;
  303.          (iGroup <= pps->num_slice_groups_minus1) && (i < PicSizeInMapUnits);
  304.          i += pps->run_length_minus1[iGroup++] + 1 )
  305.     {
  306.       for( j = 0; j <= pps->run_length_minus1[ iGroup ] && i + j < PicSizeInMapUnits; j++ )
  307.         MapUnitToSliceGroupMap[i+j] = iGroup;
  308.     }
  309.   }
  310.   while( i < PicSizeInMapUnits );
  311. }
  312. /*!
  313.  ************************************************************************
  314.  * brief
  315.  *    Generate dispersed slice group map type MapUnit map (type 1)
  316.  *
  317.  ************************************************************************
  318.  */
  319. static void FmoGenerateType1MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits )
  320. {
  321.   unsigned i;
  322.   for( i = 0; i < PicSizeInMapUnits; i++ )
  323.   {
  324.     MapUnitToSliceGroupMap[i] = ((i%img->PicWidthInMbs)+(((i/img->PicWidthInMbs)*(pps->num_slice_groups_minus1+1))/2))
  325.                                 %(pps->num_slice_groups_minus1+1);
  326.   }
  327. }
  328. /*!
  329.  ************************************************************************
  330.  * brief
  331.  *    Generate foreground with left-over slice group map type MapUnit map (type 2)
  332.  *
  333.  ************************************************************************
  334.  */
  335. static void FmoGenerateType2MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits )
  336. {
  337.   int iGroup;
  338.   unsigned i, x, y;
  339.   unsigned yTopLeft, xTopLeft, yBottomRight, xBottomRight;
  340.   for( i = 0; i < PicSizeInMapUnits; i++ )
  341.     MapUnitToSliceGroupMap[ i ] = pps->num_slice_groups_minus1;
  342.   for( iGroup = pps->num_slice_groups_minus1 - 1 ; iGroup >= 0; iGroup-- )
  343.   {
  344.     yTopLeft = pps->top_left[ iGroup ] / img->PicWidthInMbs;
  345.     xTopLeft = pps->top_left[ iGroup ] % img->PicWidthInMbs;
  346.     yBottomRight = pps->bottom_right[ iGroup ] / img->PicWidthInMbs;
  347.     xBottomRight = pps->bottom_right[ iGroup ] % img->PicWidthInMbs;
  348.     for( y = yTopLeft; y <= yBottomRight; y++ )
  349.       for( x = xTopLeft; x <= xBottomRight; x++ )
  350.         MapUnitToSliceGroupMap[ y * img->PicWidthInMbs + x ] = iGroup;
  351.  }
  352. }
  353. /*!
  354.  ************************************************************************
  355.  * brief
  356.  *    Generate box-out slice group map type MapUnit map (type 3)
  357.  *
  358.  ************************************************************************
  359.  */
  360. static void FmoGenerateType3MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits )
  361. {
  362.   unsigned i, k;
  363.   int leftBound, topBound, rightBound, bottomBound;
  364.   int x, y, xDir, yDir;
  365.   int mapUnitVacant;
  366.   unsigned mapUnitsInSliceGroup0 = imin((pps->slice_group_change_rate_minus1 + 1) * img->slice_group_change_cycle, PicSizeInMapUnits);
  367.   for( i = 0; i < PicSizeInMapUnits; i++ )
  368.     MapUnitToSliceGroupMap[ i ] = 2;
  369.   x = ( img->PicWidthInMbs - pps->slice_group_change_direction_flag ) / 2;
  370.   y = ( img->PicHeightInMapUnits - pps->slice_group_change_direction_flag ) / 2;
  371.   leftBound   = x;
  372.   topBound    = y;
  373.   rightBound  = x;
  374.   bottomBound = y;
  375.   xDir =  pps->slice_group_change_direction_flag - 1;
  376.   yDir =  pps->slice_group_change_direction_flag;
  377.   for( k = 0; k < PicSizeInMapUnits; k += mapUnitVacant )
  378.   {
  379.     mapUnitVacant = ( MapUnitToSliceGroupMap[ y * img->PicWidthInMbs + x ]  ==  2 );
  380.     if( mapUnitVacant )
  381.        MapUnitToSliceGroupMap[ y * img->PicWidthInMbs + x ] = ( k >= mapUnitsInSliceGroup0 );
  382.     if( xDir  ==  -1  &&  x  ==  leftBound )
  383.     {
  384.       leftBound = imax( leftBound - 1, 0 );
  385.       x = leftBound;
  386.       xDir = 0;
  387.       yDir = 2 * pps->slice_group_change_direction_flag - 1;
  388.     }
  389.     else
  390.       if( xDir  ==  1  &&  x  ==  rightBound )
  391.       {
  392.         rightBound = imin( rightBound + 1, (int)img->PicWidthInMbs - 1 );
  393.         x = rightBound;
  394.         xDir = 0;
  395.         yDir = 1 - 2 * pps->slice_group_change_direction_flag;
  396.       }
  397.       else
  398.         if( yDir  ==  -1  &&  y  ==  topBound )
  399.         {
  400.           topBound = imax( topBound - 1, 0 );
  401.           y = topBound;
  402.           xDir = 1 - 2 * pps->slice_group_change_direction_flag;
  403.           yDir = 0;
  404.          }
  405.         else
  406.           if( yDir  ==  1  &&  y  ==  bottomBound )
  407.           {
  408.             bottomBound = imin( bottomBound + 1, (int)img->PicHeightInMapUnits - 1 );
  409.             y = bottomBound;
  410.             xDir = 2 * pps->slice_group_change_direction_flag - 1;
  411.             yDir = 0;
  412.           }
  413.           else
  414.           {
  415.             x = x + xDir;
  416.             y = y + yDir;
  417.           }
  418.   }
  419. }
  420. /*!
  421.  ************************************************************************
  422.  * brief
  423.  *    Generate raster scan slice group map type MapUnit map (type 4)
  424.  *
  425.  ************************************************************************
  426.  */
  427. static void FmoGenerateType4MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits )
  428. {
  429.   unsigned mapUnitsInSliceGroup0 = imin((pps->slice_group_change_rate_minus1 + 1) * img->slice_group_change_cycle, PicSizeInMapUnits);
  430.   unsigned sizeOfUpperLeftGroup = pps->slice_group_change_direction_flag ? ( PicSizeInMapUnits - mapUnitsInSliceGroup0 ) : mapUnitsInSliceGroup0;
  431.   unsigned i;
  432.   for( i = 0; i < PicSizeInMapUnits; i++ )
  433.     if( i < sizeOfUpperLeftGroup )
  434.         MapUnitToSliceGroupMap[ i ] = pps->slice_group_change_direction_flag;
  435.     else
  436.         MapUnitToSliceGroupMap[ i ] = 1 - pps->slice_group_change_direction_flag;
  437. }
  438. /*!
  439.  ************************************************************************
  440.  * brief
  441.  *    Generate wipe slice group map type MapUnit map (type 5)
  442.  *
  443.  ************************************************************************
  444.  */
  445. static void FmoGenerateType5MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits )
  446. {
  447.   unsigned mapUnitsInSliceGroup0 = imin((pps->slice_group_change_rate_minus1 + 1) * img->slice_group_change_cycle, PicSizeInMapUnits);
  448.   unsigned sizeOfUpperLeftGroup = pps->slice_group_change_direction_flag ? ( PicSizeInMapUnits - mapUnitsInSliceGroup0 ) : mapUnitsInSliceGroup0;
  449.   unsigned i,j, k = 0;
  450.   for( j = 0; j < img->PicWidthInMbs; j++ )
  451.     for( i = 0; i < img->PicHeightInMapUnits; i++ )
  452.         if( k++ < sizeOfUpperLeftGroup )
  453.             MapUnitToSliceGroupMap[ i * img->PicWidthInMbs + j ] = pps->slice_group_change_direction_flag;
  454.         else
  455.             MapUnitToSliceGroupMap[ i * img->PicWidthInMbs + j ] = 1 - pps->slice_group_change_direction_flag;
  456. }
  457. /*!
  458.  ************************************************************************
  459.  * brief
  460.  *    Generate explicit slice group map type MapUnit map (type 6)
  461.  *
  462.  ************************************************************************
  463.  */
  464. static void FmoGenerateType6MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits )
  465. {
  466.   unsigned i;
  467.   for (i=0; i<PicSizeInMapUnits; i++)
  468.   {
  469.     MapUnitToSliceGroupMap[i] = pps->slice_group_id[i];
  470.   }
  471. }