📄 cfmo.cpp
字号:
/*!
*****************************************************************************
*
* \file Cfmo.c
*
* \brief
* Support for Flexible Macroblock Ordering (FMO)
*
* \author
* Main contributors (see contributors.h for copyright, address and affiliation details)
* - Stephan Wenger stewe@cs.tu-berlin.de
* - Karsten Suehring suehring@hhi.de
*
*\ modified by
* Tae Meon Bae heartles@icu.ac.kr
*
******************************************************************************
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "H264AVCCommonLib.h"
#include "H264AVCCommonLib/CFMO.h"
H264AVC_NAMESPACE_BEGIN
//#define PRINT_FMO_MAPS
//#define min(a,b) ((a)>(b))?b:a
//#define max(a,b) ((a)<(b))?b:a
//#define PRINT_FMO_MAPS
Bool FMO::m_siSGId[Max_Num_Slice_Groups];
int FMO::m_iPOC = -1;
int FMO::m_iFrame = -1;
/*!
************************************************************************
* \brief
* Generates MapUnitToSliceGroupMap_
* Has to be called every time a new Picture Parameter Set is used
*
* \param pps
* Picture Parameter set to be used for map generation
* \param sps
* Sequence Parameter set to be used for map generation
*
************************************************************************
*/
int FMO::GenerateMapUnitToSliceGroupMap()
{
if (initMapUnitToSliceGroupMap() == 0) return 0;
switch (pps_.slice_group_map_type)
{
case 0:
GenerateType0MapUnitMap ();
break;
case 1:
GenerateType1MapUnitMap ();
break;
case 2:
GenerateType2MapUnitMap ();
break;
case 3:
GenerateType3MapUnitMap ();
break;
case 4:
GenerateType4MapUnitMap ();
break;
case 5:
GenerateType5MapUnitMap ();
break;
case 6:
GenerateType6MapUnitMap ();
break;
default:
printf ("Illegal slice_group_map_type %d , exit \n", pps_.slice_group_map_type);
exit (-1);
}
return 0;
}
/*!
************************************************************************
* \brief
* Generates MbToSliceGroupMap_ from MapUnitToSliceGroupMap
*
* \param pps
* Picture Parameter set to be used for map generation
* \param sps
* Sequence Parameter set to be used for map generation
*
************************************************************************
*/
int FMO::GenerateMbToSliceGroupMap()
{
// allocate memory for MbToSliceGroupMap_
mallocMbToSliceGroupMap();
if (sps_.frame_mbs_only_flag|| img_.field_pic_flag)
{
for (unsigned i=0; i<img_.PicSizeInMbs; i++)
{
MbToSliceGroupMap_[i] = MapUnitToSliceGroupMap_[i];
}
}
else
if (sps_.mb_adaptive_frame_field_flag && (!img_.field_pic_flag))
{
for (unsigned i=0; i<img_.PicSizeInMbs; i++)
{
MbToSliceGroupMap_[i] = MapUnitToSliceGroupMap_[i/2];
}
}
else
{
for (unsigned i=0; i<img_.PicSizeInMbs; i++)
{
MbToSliceGroupMap_[i] = MapUnitToSliceGroupMap_[(i/(2*img_.PicWidthInMbs))*img_.PicWidthInMbs+(i%img_.PicWidthInMbs)];
}
}
return 0;
}
/*!
************************************************************************
* \brief
* FMO initialization: Generates MapUnitToSliceGroupMap and MbToSliceGroupMap_.
*
* \param pps
* Picture Parameter set to be used for map generation
* \param sps
* Sequence Parameter set to be used for map generation
************************************************************************
*/
Void FMO::printFmoMaps()
{
#if 1 // debug
return;
#endif
unsigned i,j;
printf("\n");
printf("FMO Map (Units):\n");
for (j=0; j<img_.PicHeightInMapUnits; j++)
{
for (i=0; i<img_.PicWidthInMbs; i++)
{
printf("%c",48+MapUnitToSliceGroupMap_[i+j*img_.PicWidthInMbs]);
}
printf("\n");
}
printf("\n");
printf("FMO Map (Mb):\n");
for (j=0; j<=sps_.pic_height_in_map_units_minus1; j++)
{
for (i=0; i<=sps_.pic_width_in_mbs_minus1; i++)
{
printf("%c",48+MbToSliceGroupMap_[i+j*img_.PicWidthInMbs]);
}
printf("\n");
}
printf("\n");
}
int FMO::init(FMO_PPS* pps, FMO_SPS* sps)
{
if(MbToSliceGroupMap_)
{
delete[] MbToSliceGroupMap_;
MbToSliceGroupMap_ = NULL;
}
if (MapUnitToSliceGroupMap_)
{
delete[] MapUnitToSliceGroupMap_;
MapUnitToSliceGroupMap_ = NULL;
}
InitFirstMBsInSlices();
GenerateMapUnitToSliceGroupMap();
GenerateMbToSliceGroupMap();
NumberOfSliceGroups_ = pps_.num_slice_groups_minus1+1;
calcMbNumInSliceGroup();
printFmoMaps();
return 0;
}
/*!
************************************************************************
* \brief
* Free memory allocated by FMO functions
************************************************************************
*/
int FMO::finit()
{
if (MbToSliceGroupMap_)
{
delete[] MbToSliceGroupMap_;
MbToSliceGroupMap_ = NULL;
}
if (MapUnitToSliceGroupMap_)
{
delete[] MapUnitToSliceGroupMap_;
MapUnitToSliceGroupMap_ = NULL;
}
if( numMbInSliceGroup_ ) // fix HS
{ // fix HS
delete[] numMbInSliceGroup_; // fix HS
numMbInSliceGroup_ = NULL;
}
return 0;
}
/*!
************************************************************************
* \brief
* FmoGetNumberOfSliceGroup()
*
* \par Input:
* None
************************************************************************
*/
int FMO::getNumberOfSliceGroup()
{
return NumberOfSliceGroups_;
}
/*!
************************************************************************
* \brief
* FmoGetLastMBOfPicture()
* returns the macroblock number of the last MB in a picture. This
* mb happens to be the last macroblock of the picture if there is only
* one slice group
*
* \par Input:
* None
************************************************************************
*/
int FMO::getLastMBOfPicture()
{
return getLastMBInSliceGroup (getNumberOfSliceGroup()-1);
}
/*!
************************************************************************
* \brief
* FmoGetLastMBInSliceGroup: Returns MB number of last MB in SG
*
* \par Input:
* SliceGroupID (0 to 7)
************************************************************************
*/
int FMO::getLastMBInSliceGroup (int SliceGroup)
{
for (int i=img_.PicSizeInMbs-1; i>=0; i--)
if (getSliceGroupId (i) == SliceGroup)
return i;
return -1;
};
/*!
************************************************************************
* \brief
* Returns SliceGroupID for a given MB
*
* \param mb
* Macroblock number (in scan order)
************************************************************************
*/
int FMO::getSliceGroupId (int mb)
{
assert (mb < (int)img_.PicSizeInMbs);
assert (MbToSliceGroupMap_ != NULL);
return MbToSliceGroupMap_[mb];
}
Void FMO::calcMbNumInSliceGroup()
{
if( numMbInSliceGroup_ != NULL)
delete[] numMbInSliceGroup_;
numMbInSliceGroup_ = new int[NumberOfSliceGroups_];
int i;
for( i=0; i<NumberOfSliceGroups_; i++)
numMbInSliceGroup_[i] = 0;
for( i=0; i<(Int)PicSizeInMapUnits_; i++)
numMbInSliceGroup_[getSliceGroupId(i)]++;
}
int FMO::getNumMbInSliceGroup(int sliceGroupID)
{
return numMbInSliceGroup_[sliceGroupID];
}
/*!
************************************************************************
* \brief
* FmoGetNextMBBr: Returns the MB-Nr (in scan order) of the next
* MB in the (scattered) Slice, -1 if the slice is finished
*
* \param CurrentMbNr
* number of the current macroblock
************************************************************************
*/
int FMO::getNextMBNr (int CurrentMbNr)
{
int SliceGroup = getSliceGroupId (CurrentMbNr);
while (++CurrentMbNr<(int)img_.PicSizeInMbs && MbToSliceGroupMap_ [CurrentMbNr] != SliceGroup)
;
if (CurrentMbNr >= (int)img_.PicSizeInMbs)
return -1; // No further MB in this slice (could be end of picture)
else
return CurrentMbNr;
}
/*!
************************************************************************
* \brief
* Generate interleaved slice group map type MapUnit map (type 0)
*
************************************************************************
*/
Void FMO::GenerateType0MapUnitMap ()
{
unsigned iGroup, j;
unsigned i = 0;
do
{
for( iGroup = 0;
(iGroup <= pps_.num_slice_groups_minus1) && (i < PicSizeInMapUnits_);
i += pps_.run_length_minus1[iGroup++] + 1 )
{
for( j = 0; j <= pps_.run_length_minus1[ iGroup ] && i + j < PicSizeInMapUnits_; j++ )
MapUnitToSliceGroupMap_[i+j] = iGroup;
}
}
while( i < PicSizeInMapUnits_);
}
/*!
************************************************************************
* \brief
* Generate dispersed slice group map type MapUnit map (type 1)
*
************************************************************************
*/
Void FMO::GenerateType1MapUnitMap()
{
unsigned i;
for( i = 0; i < PicSizeInMapUnits_; i++ )
{
MapUnitToSliceGroupMap_[i] = ((i%img_.PicWidthInMbs)+(((i/img_.PicWidthInMbs)*(pps_.num_slice_groups_minus1+1))/2))
%(pps_.num_slice_groups_minus1+1);
}
}
/*!
************************************************************************
* \brief
* Generate foreground with left-over slice group map type MapUnit map (type 2)
*
************************************************************************
*/
Void FMO::GenerateType2MapUnitMap ()
{
int iGroup;
unsigned i, x, y;
unsigned yTopLeft, xTopLeft, yBottomRight, xBottomRight;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -