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

Audio

开发平台:

Visual C++

  1. /*!
  2.  *****************************************************************************
  3.  *
  4.  * file fmo.c
  5.  *
  6.  * brief
  7.  *    Support for Flexible Macroblock Ordering for different Slice Group Modes: MBAmap handling
  8.  *
  9.  * date
  10.  *    16 June, 2002  Modified April 25, 2004
  11.  *
  12.  * author
  13.  *    Stephan Wenger   stewe@cs.tu-berlin.de
  14.  *    Dong Wang        Dong.Wang@bristol.ac.uk
  15.  *
  16.  *****************************************************************************/
  17. /*!
  18.  ****************************************************************************
  19.  *   Notes by Dong Wang (April 25 2004)
  20.  *
  21.  *  Source codes are modified to support 7 slice group types (fmo modes).
  22.  *  The functions for generating map are very similar to that in decoder, but have
  23.  *  a little difference.
  24.  *
  25.  *  The MB map is calculated at the beginning of coding of each picture (frame or field).
  26.  *
  27.  *  'slice_group_change_cycle' in structure 'ImageParameters' is the syntax in the slice
  28.  *  header. It's set to be 1 before the initialization of FMO in function code_a_picture().
  29.  *  It can be changed every time if needed.
  30.  *
  31.  ****************************************************************************
  32.  */
  33. /*!
  34.  *****************************************************************************
  35.  *  How does a MBAmap look like?
  36.  *
  37.  *  An MBAmap is a one-diemnsional array of ints.  Each int
  38.  *  represents an MB in scan order.  A zero or positive value represents
  39.  *  a slice group ID.  Negative values are reserved for future extensions.
  40.  *  The numbering range for the SliceGroupIDs is 0..7 as per JVT-C167.
  41.  *
  42.  *  This module contains a static variable MBAmap.  This is the MBAmap of the
  43.  *  picture currently coded.  It can be accessed only through the access
  44.  *  functions.
  45.  *****************************************************************************
  46. */
  47. //#define PRINT_FMO_MAPS  1
  48. #include "global.h"
  49. #include "fmo.h"
  50. static int FirstMBInSlice[MAXSLICEGROUPIDS];
  51. byte *MBAmap = NULL;
  52. byte *MapUnitToSliceGroupMap = NULL;
  53. unsigned int PicSizeInMapUnits;
  54. static void FmoGenerateType0MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps);
  55. static void FmoGenerateType1MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps);
  56. static void FmoGenerateType2MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps);
  57. static void FmoGenerateType3MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps);
  58. static void FmoGenerateType4MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps);
  59. static void FmoGenerateType5MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps);
  60. static void FmoGenerateType6MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps);
  61. static int FmoGenerateMapUnitToSliceGroupMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps);
  62. static int FmoGenerateMBAmap (ImageParameters * img, seq_parameter_set_rbsp_t* sps);
  63. /*!
  64.  ************************************************************************
  65.  * brief
  66.  *    Generates MapUnitToSliceGroupMap
  67.  *
  68.  * param img
  69.  *    Image Parameter to be used for map generation
  70.  * param pps
  71.  *    Picture Parameter set to be used for map generation
  72.  *
  73.  ************************************************************************
  74.  */
  75. static int FmoGenerateMapUnitToSliceGroupMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps)
  76. {
  77.   PicSizeInMapUnits = img->PicHeightInMapUnits * img->PicWidthInMbs;
  78.   if (pps->slice_group_map_type == 6)
  79.   {
  80.     if ((pps->pic_size_in_map_units_minus1+1) != PicSizeInMapUnits)
  81.     {
  82.       error ("wrong pps->pic_size_in_map_units_minus1 for used SPS and FMO type 6", 500);
  83.     }
  84.   }
  85.   // allocate memory for MapUnitToSliceGroupMap
  86.   if (MapUnitToSliceGroupMap)
  87.     free (MapUnitToSliceGroupMap);
  88.   if ((MapUnitToSliceGroupMap = malloc ((PicSizeInMapUnits) * sizeof (byte))) == NULL)
  89.   {
  90.     printf ("cannot allocated %d bytes for MapUnitToSliceGroupMap, exitn", (int) ( PicSizeInMapUnits * sizeof (byte)));
  91.     exit (-1);
  92.   }
  93.   if (pps->num_slice_groups_minus1 == 0)    // only one slice group
  94.   {
  95.     memset (MapUnitToSliceGroupMap, 0,  PicSizeInMapUnits * sizeof (byte));
  96.     return 0;
  97.   }
  98.   switch (pps->slice_group_map_type)
  99.   {
  100.   case 0:
  101.     FmoGenerateType0MapUnitMap (img, pps);
  102.     break;
  103.   case 1:
  104.     FmoGenerateType1MapUnitMap (img, pps);
  105.     break;
  106.   case 2:
  107.     FmoGenerateType2MapUnitMap (img, pps);
  108.     break;
  109.   case 3:
  110.     FmoGenerateType3MapUnitMap (img, pps);
  111.     break;
  112.   case 4:
  113.     FmoGenerateType4MapUnitMap (img, pps);
  114.     break;
  115.   case 5:
  116.     FmoGenerateType5MapUnitMap (img, pps);
  117.     break;
  118.   case 6:
  119.     FmoGenerateType6MapUnitMap (img, pps);
  120.     break;
  121.   default:
  122.     printf ("Illegal slice_group_map_type %d , exit n", pps->slice_group_map_type);
  123.     exit (-1);
  124.   }
  125.   return 0;
  126. }
  127. /*!
  128.  ************************************************************************
  129.  * brief
  130.  *    Generates MBAmap from MapUnitToSliceGroupMap
  131.  *
  132.  * param img
  133.  *    Image Parameter to be used for map generation
  134.  * param sps
  135.  *    Sequence Parameter set to be used for map generation
  136.  *
  137.  ************************************************************************
  138.  */
  139. static int FmoGenerateMBAmap (ImageParameters * img, seq_parameter_set_rbsp_t* sps)
  140. {
  141.   unsigned i;
  142.   // allocate memory for MBAmap
  143.   if (MBAmap)
  144.     free (MBAmap);
  145.   if ((MBAmap = malloc ((img->PicSizeInMbs) * sizeof (byte))) == NULL)
  146.   {
  147.     printf ("cannot allocated %d bytes for MBAmap, exitn", (int) ((img->PicSizeInMbs) * sizeof (byte)));
  148.     exit (-1);
  149.   }
  150.   if ((sps->frame_mbs_only_flag) || img->field_picture)
  151.   {
  152.     for (i=0; i<img->PicSizeInMbs; i++)
  153.     {
  154.       MBAmap[i] = MapUnitToSliceGroupMap[i];
  155.     }
  156.   }
  157.   else
  158.     if (sps->mb_adaptive_frame_field_flag  &&  (! img->field_picture))
  159.     {
  160.       for (i=0; i<img->PicSizeInMbs; i++)
  161.       {
  162.         MBAmap[i] = MapUnitToSliceGroupMap[i/2];
  163.       }
  164.     }
  165.     else
  166.     {
  167.       for (i=0; i<img->PicSizeInMbs; i++)
  168.       {
  169.         MBAmap[i] = MapUnitToSliceGroupMap[(i/(2*img->PicWidthInMbs))*img->PicWidthInMbs+(i%img->PicWidthInMbs)];
  170.       }
  171.     }
  172.     return 0;
  173. }
  174. /*!
  175.  ************************************************************************
  176.  * brief
  177.  *    FMO initialization: Generates MapUnitToSliceGroupMap and MBAmap.
  178.  *
  179.  * param img
  180.  *    Image Parameter to be used for map generation
  181.  * param pps
  182.  *    Picture Parameter set to be used for map generation
  183.  * param sps
  184.  *    Sequence Parameter set to be used for map generation
  185.  ************************************************************************
  186.  */
  187. int FmoInit(ImageParameters * img, pic_parameter_set_rbsp_t * pps, seq_parameter_set_rbsp_t * sps)
  188. {
  189. #ifdef PRINT_FMO_MAPS
  190.   unsigned i,j;
  191.   int bottom;
  192. #endif
  193.   int k;
  194.   for (k=0;k<MAXSLICEGROUPIDS;k++)
  195.     FirstMBInSlice[k] = -1;
  196.   FmoGenerateMapUnitToSliceGroupMap(img, pps);
  197.   FmoGenerateMBAmap(img, sps);
  198. #ifdef PRINT_FMO_MAPS
  199.   printf("n");
  200.   printf("FMO Map (Units):n");
  201.   for (j=0; j<img->PicHeightInMapUnits; j++)
  202.   {
  203.     for (i=0; i<img->PicWidthInMbs; i++)
  204.     {
  205.       printf("%d ",MapUnitToSliceGroupMap[i+j*img->PicWidthInMbs]);
  206.     }
  207.     printf("n");
  208.   }
  209.   printf("n");
  210.   if(sps->mb_adaptive_frame_field_flag==0)
  211.   {
  212.     printf("FMO Map (Mb):n");
  213.     for (j=0; j<(img->PicSizeInMbs/img->PicWidthInMbs); j++)
  214.     {
  215.       for (i=0; i<img->PicWidthInMbs; i++)
  216.       {
  217.         printf("%d ",MBAmap[i+j*img->PicWidthInMbs]);
  218.       }
  219.       printf("n");
  220.     }
  221.     printf("n");
  222.   }
  223.   else
  224.   {
  225.     printf("FMO Map (Mb in scan order for MBAFF):n");
  226.     for (j=0; j<(img->PicSizeInMbs/img->PicWidthInMbs); j++)
  227.     {
  228.       for (i=0; i<img->PicWidthInMbs; i++)
  229.       {
  230.         bottom=(j%2);
  231.         printf("%d ",MBAmap[(j-bottom)*img->PicWidthInMbs+i*2+bottom]);
  232.       }
  233.       printf("n");
  234.     }
  235.     printf("n");
  236.   }
  237. #endif
  238.   return 0;
  239. }
  240. /*!
  241.  ************************************************************************
  242.  * brief
  243.  *    Free memory if allocated by FMO functions
  244.  ************************************************************************
  245.  */
  246. void FmoUninit()
  247. {
  248.   if (MBAmap)
  249.   {
  250.     free (MBAmap);
  251.     MBAmap = NULL;
  252.   }
  253.   if (MapUnitToSliceGroupMap)
  254.   {
  255.     free (MapUnitToSliceGroupMap);
  256.     MapUnitToSliceGroupMap = NULL;
  257.   }
  258. }
  259. /*!
  260.  ************************************************************************
  261.  * brief
  262.  *    Generate interleaved slice group map type MapUnit map (type 0)
  263.  *
  264.  * param img
  265.  *    Image Parameter to be used for map generation
  266.  * param pps
  267.  *    Picture Parameter set to be used for map generation
  268.  ************************************************************************
  269.  */
  270. static void FmoGenerateType0MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps )
  271. {
  272.   unsigned iGroup, j;
  273.   unsigned i = 0;
  274.   do
  275.   {
  276.     for( iGroup = 0;
  277.     (iGroup <= pps->num_slice_groups_minus1) && (i < PicSizeInMapUnits);
  278.     i += pps->run_length_minus1[iGroup++] + 1)
  279.     {
  280.       for( j = 0; j <= pps->run_length_minus1[ iGroup ] && i + j < PicSizeInMapUnits; j++ )
  281.         MapUnitToSliceGroupMap[i+j] = iGroup;
  282.     }
  283.   }
  284.   while( i < PicSizeInMapUnits );
  285. }
  286. /*!
  287.  ************************************************************************
  288.  * brief
  289.  *    Generate dispersed slice group map type MapUnit map (type 1)
  290.  *
  291.  * param img
  292.  *    Image Parameter to be used for map generation
  293.  * param pps
  294.  *    Picture Parameter set to be used for map generation
  295.  ************************************************************************
  296.  */
  297. static void FmoGenerateType1MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps )
  298. {
  299.   unsigned i;
  300.   for( i = 0; i < PicSizeInMapUnits; i++ )
  301.   {
  302.     MapUnitToSliceGroupMap[i] = ((i%img->PicWidthInMbs)+(((i/img->PicWidthInMbs)*(pps->num_slice_groups_minus1+1))/2))
  303.       %(pps->num_slice_groups_minus1+1);
  304.   }
  305. }
  306. /*!
  307.  ************************************************************************
  308.  * brief
  309.  *    Generate foreground with left-over slice group map type MapUnit map (type 2)
  310.  *
  311.  * param img
  312.  *    Image Parameter to be used for map generation
  313.  * param pps
  314.  *    Picture Parameter set to be used for map generation
  315.  ************************************************************************
  316.  */
  317. static void FmoGenerateType2MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps )
  318. {
  319.   int iGroup;
  320.   unsigned i, x, y;
  321.   unsigned yTopLeft, xTopLeft, yBottomRight, xBottomRight;
  322.   for( i = 0; i < PicSizeInMapUnits; i++ )
  323.     MapUnitToSliceGroupMap[ i ] = pps->num_slice_groups_minus1;
  324.   for( iGroup = pps->num_slice_groups_minus1 - 1 ; iGroup >= 0; iGroup-- )
  325.   {
  326.     yTopLeft = pps->top_left[ iGroup ] / img->PicWidthInMbs;
  327.     xTopLeft = pps->top_left[ iGroup ] % img->PicWidthInMbs;
  328.     yBottomRight = pps->bottom_right[ iGroup ] / img->PicWidthInMbs;
  329.     xBottomRight = pps->bottom_right[ iGroup ] % img->PicWidthInMbs;
  330.     for( y = yTopLeft; y <= yBottomRight; y++ )
  331.       for( x = xTopLeft; x <= xBottomRight; x++ )
  332.         MapUnitToSliceGroupMap[ y * img->PicWidthInMbs + x ] = iGroup;
  333.   }
  334. }
  335. /*!
  336.  ************************************************************************
  337.  * brief
  338.  *    Generate box-out slice group map type MapUnit map (type 3)
  339.  *
  340.  * param img
  341.  *    Image Parameter to be used for map generation
  342.  * param pps
  343.  *    Picture Parameter set to be used for map generation
  344.  ************************************************************************
  345.  */
  346. static void FmoGenerateType3MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps )
  347. {
  348.   unsigned i, k;
  349.   int leftBound, topBound, rightBound, bottomBound;
  350.   int x, y, xDir, yDir;
  351.   int mapUnitVacant;
  352.   unsigned mapUnitsInSliceGroup0 = imin((pps->slice_group_change_rate_minus1 + 1) * img->slice_group_change_cycle, PicSizeInMapUnits);
  353.   for( i = 0; i < PicSizeInMapUnits; i++ )
  354.     MapUnitToSliceGroupMap[ i ] = 2;
  355.   x = ( img->PicWidthInMbs - pps->slice_group_change_direction_flag ) / 2;
  356.   y = ( img->PicHeightInMapUnits - pps->slice_group_change_direction_flag ) / 2;
  357.   leftBound   = x;
  358.   topBound    = y;
  359.   rightBound  = x;
  360.   bottomBound = y;
  361.   xDir =  pps->slice_group_change_direction_flag - 1;
  362.   yDir =  pps->slice_group_change_direction_flag;
  363.   for( k = 0; k < PicSizeInMapUnits; k += mapUnitVacant )
  364.   {
  365.     mapUnitVacant = ( MapUnitToSliceGroupMap[ y * img->PicWidthInMbs + x ]  ==  2 );
  366.     if( mapUnitVacant )
  367.       MapUnitToSliceGroupMap[ y * img->PicWidthInMbs + x ] = ( k >= mapUnitsInSliceGroup0 );
  368.     if( xDir  ==  -1  &&  x  ==  leftBound )
  369.     {
  370.       leftBound = imax( leftBound - 1, 0 );
  371.       x = leftBound;
  372.       xDir = 0;
  373.       yDir = 2 * pps->slice_group_change_direction_flag - 1;
  374.     }
  375.     else
  376.       if( xDir  ==  1  &&  x  ==  rightBound )
  377.       {
  378.         rightBound = imin( rightBound + 1, (int)img->PicWidthInMbs - 1 );
  379.         x = rightBound;
  380.         xDir = 0;
  381.         yDir = 1 - 2 * pps->slice_group_change_direction_flag;
  382.       }
  383.       else
  384.         if( yDir  ==  -1  &&  y  ==  topBound )
  385.         {
  386.           topBound = imax( topBound - 1, 0 );
  387.           y = topBound;
  388.           xDir = 1 - 2 * pps->slice_group_change_direction_flag;
  389.           yDir = 0;
  390.         }
  391.         else
  392.           if( yDir  ==  1  &&  y  ==  bottomBound )
  393.           {
  394.             bottomBound = imin( bottomBound + 1, (int)img->PicHeightInMapUnits - 1 );
  395.             y = bottomBound;
  396.             xDir = 2 * pps->slice_group_change_direction_flag - 1;
  397.             yDir = 0;
  398.           }
  399.           else
  400.           {
  401.             x = x + xDir;
  402.             y = y + yDir;
  403.           }
  404.   }
  405. }
  406. /*!
  407.  ************************************************************************
  408.  * brief
  409.  *    Generate raster scan slice group map type MapUnit map (type 4)
  410.  *
  411.  * param img
  412.  *    Image Parameter to be used for map generation
  413.  * param pps
  414.  *    Picture Parameter set to be used for map generation
  415.  ************************************************************************
  416.  */
  417. static void FmoGenerateType4MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps )
  418. {
  419.   unsigned mapUnitsInSliceGroup0 = imin((pps->slice_group_change_rate_minus1 + 1) * img->slice_group_change_cycle, PicSizeInMapUnits);
  420.   unsigned sizeOfUpperLeftGroup = pps->slice_group_change_direction_flag ? ( PicSizeInMapUnits - mapUnitsInSliceGroup0 ) : mapUnitsInSliceGroup0;
  421.   unsigned i;
  422.   for( i = 0; i < PicSizeInMapUnits; i++ )
  423.     if( i < sizeOfUpperLeftGroup )
  424.       MapUnitToSliceGroupMap[ i ] = pps->slice_group_change_direction_flag;
  425.     else
  426.       MapUnitToSliceGroupMap[ i ] = 1 - pps->slice_group_change_direction_flag;
  427. }
  428. /*!
  429.  ************************************************************************
  430.  * brief
  431.  *    Generate wipe slice group map type MapUnit map (type 5)
  432.  *
  433.  * param img
  434.  *    Image Parameter to be used for map generation
  435.  * param pps
  436.  *    Picture Parameter set to be used for map generation
  437.  ************************************************************************
  438. */
  439. static void FmoGenerateType5MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps )
  440. {
  441.   unsigned mapUnitsInSliceGroup0 = imin((pps->slice_group_change_rate_minus1 + 1) * img->slice_group_change_cycle, PicSizeInMapUnits);
  442.   unsigned sizeOfUpperLeftGroup = pps->slice_group_change_direction_flag ? ( PicSizeInMapUnits - mapUnitsInSliceGroup0 ) : mapUnitsInSliceGroup0;
  443.   unsigned i,j, k = 0;
  444.   for( j = 0; j < img->PicWidthInMbs; j++ )
  445.     for( i = 0; i < img->PicHeightInMapUnits; i++ )
  446.       if( k++ < sizeOfUpperLeftGroup )
  447.         MapUnitToSliceGroupMap[ i * img->PicWidthInMbs + j ] = pps->slice_group_change_direction_flag;
  448.       else
  449.         MapUnitToSliceGroupMap[ i * img->PicWidthInMbs + j ] = 1 - pps->slice_group_change_direction_flag;
  450. }
  451. /*!
  452.  ************************************************************************
  453.  * brief
  454.  *    Generate explicit slice group map type MapUnit map (type 6)
  455.  *
  456.  * param img
  457.  *    Image Parameter to be used for map generation
  458.  * param pps
  459.  *    Picture Parameter set to be used for map generation
  460.  ************************************************************************
  461.  */
  462. static void FmoGenerateType6MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps )
  463. {
  464.   unsigned i;
  465.   for (i=0; i<PicSizeInMapUnits; i++)
  466.   {
  467.     MapUnitToSliceGroupMap[i] = pps->slice_group_id[i];
  468.   }
  469. }
  470. /*!
  471.  ************************************************************************
  472.  * brief
  473.  *    FmoStartPicture: initializes FMO at the begin of each new picture
  474.  *
  475.  * par Input:
  476.  *    None
  477.  ************************************************************************
  478.  */
  479. int FmoStartPicture ()
  480. {
  481.   int i;
  482.   assert (MBAmap != NULL);
  483.   for (i=0; i<MAXSLICEGROUPIDS; i++)
  484.     FirstMBInSlice[i] = FmoGetFirstMBOfSliceGroup (i);
  485.   return 0;
  486. }
  487. /*!
  488.  ************************************************************************
  489.  * brief
  490.  *    FmoEndPicture: Ends the Scattered Slices Module (called once
  491.  *    per picture).
  492.  *
  493.  * par Input:
  494.  *    None
  495.  ************************************************************************
  496.  */
  497. int FmoEndPicture ()
  498. {
  499.   // Do nothing
  500.   return 0;
  501. }
  502. /*!
  503.  ************************************************************************
  504.  * brief
  505.  *    FmoMB2Slice: Returns SliceID for a given MB
  506.  *
  507.  * par Input:
  508.  *    Macroblock Nr (in scan order)
  509.  ************************************************************************
  510.  */
  511. int FmoMB2SliceGroup ( int mb)
  512. {
  513.   assert (mb < (int)img->PicSizeInMbs);
  514.   assert (MBAmap != NULL);
  515.   return MBAmap[mb];
  516. }
  517. /*!
  518.  ************************************************************************
  519.  * brief
  520.  *    FmoGetNextMBBr: Returns the MB-Nr (in scan order) of the next
  521.  *    MB in the (FMO) Slice, -1 if the SliceGroup is finished
  522.  *
  523.  * par Input:
  524.  *    CurrentMbNr
  525.  ************************************************************************
  526.  */
  527. int FmoGetNextMBNr (int CurrentMbNr)
  528. {
  529.   int  SliceGroupID = FmoMB2SliceGroup (CurrentMbNr);
  530.   while (++CurrentMbNr<(int)img->PicSizeInMbs &&  MBAmap[CurrentMbNr] != SliceGroupID)
  531.     ;
  532.   if (CurrentMbNr >= (int)img->PicSizeInMbs)
  533.     return -1;    // No further MB in this slice (could be end of picture)
  534.   else
  535.     return CurrentMbNr;
  536. }
  537. /*!
  538.  ************************************************************************
  539.  * brief
  540.  *    FmoGetNextMBBr: Returns the MB-Nr (in scan order) of the next
  541.  *    MB in the (FMO) Slice, -1 if the SliceGroup is finished
  542.  *
  543.  * par Input:
  544.  *    CurrentMbNr
  545.  ************************************************************************
  546.  */
  547. int FmoGetPreviousMBNr (int CurrentMbNr)
  548. {
  549.   int  SliceGroupID = FmoMB2SliceGroup (CurrentMbNr);
  550.   CurrentMbNr--;
  551.   while (CurrentMbNr>=0 &&  MBAmap[CurrentMbNr] != SliceGroupID)
  552.     CurrentMbNr--;
  553.   if (CurrentMbNr < 0)
  554.     return -1;    // No previous MB in this slice
  555.   else
  556.     return CurrentMbNr;
  557. }
  558. /*!
  559.  ************************************************************************
  560.  * brief
  561.  *    FmoGetFirstMBOfSliceGroup: Returns the MB-Nr (in scan order) of the
  562.  *    next first MB of the Slice group, -1 if no such MB exists
  563.  *
  564.  * par Input:
  565.  *    SliceGroupID: Id of SliceGroup
  566.  ************************************************************************
  567.  */
  568. int FmoGetFirstMBOfSliceGroup (int SliceGroupID)
  569. {
  570.   int i = 0;
  571.   while ((i<(int)img->PicSizeInMbs) && (FmoMB2SliceGroup (i) != SliceGroupID))
  572.     i++;
  573.   if (i < (int)img->PicSizeInMbs)
  574.     return i;
  575.   else
  576.     return -1;
  577. }
  578. /*!
  579.  ************************************************************************
  580.  * brief
  581.  *    FmoGetLastCodedMBOfSlice: Returns the MB-Nr (in scan order) of
  582.  *    the last MB of the slice group
  583.  *
  584.  * par Input:
  585.  *    SliceGroupID
  586.  * par Return
  587.  *    MB Nr in case of success (is always >= 0)
  588.  *    -1 if the SliceGroup doesn't exist
  589.  ************************************************************************
  590.  */
  591. int FmoGetLastCodedMBOfSliceGroup (int SliceGroupID)
  592. {
  593.   int i;
  594.   int LastMB = -1;
  595.   for (i=0; i<(int)img->PicSizeInMbs; i++)
  596.     if (FmoMB2SliceGroup (i) == SliceGroupID)
  597.       LastMB = i;
  598.   return LastMB;
  599. }
  600. void FmoSetLastMacroblockInSlice ( int mb)
  601. {
  602.   // called by terminate_slice(), writes the last processed MB into the
  603.   // FirstMBInSlice[MAXSLICEGROUPIDS] array.  FmoGetFirstMacroblockInSlice()
  604.   // uses this info to identify the first uncoded MB in each slice group
  605.   int currSliceGroup = FmoMB2SliceGroup (mb);
  606.   assert (mb >= 0);
  607.   mb = FmoGetNextMBNr (mb);   // The next (still uncoded) MB, or -1 if SG is finished
  608.   FirstMBInSlice[currSliceGroup] = mb;
  609. }
  610. int FmoGetFirstMacroblockInSlice ( int SliceGroup)
  611. {
  612.   return FirstMBInSlice[SliceGroup];
  613.   // returns the first uncoded MB in each slice group, -1 if there is no
  614.   // more to do in this slice group
  615. }
  616. int FmoSliceGroupCompletelyCoded( int SliceGroupID)
  617. {
  618.   if (FmoGetFirstMacroblockInSlice (SliceGroupID) < 0)  // slice group completelty coded or not present
  619.     return TRUE;
  620.   else
  621.     return FALSE;
  622. }