blob: 9d22f51e1612cce58bfa2e2f82ac27e6d5401688 [file] [log] [blame]
/*!
*****************************************************************************
*
* \file intrarefresh.c
*
* \brief
* Encoder support for pseudo-random intra macroblock refresh
*
* \date
* 16 June 2002
*
* \author
* Stephan Wenger stewe@cs.tu-berlin.de
*****************************************************************************/
#include <stdlib.h>
#include <assert.h>
#include "global.h"
static int *RefreshPattern;
static int *IntraMBs;
static int WalkAround = 0;
static int NumberOfMBs = 0;
static int NumberIntraPerPicture;
/*!
************************************************************************
* \brief
* RandomIntraInit: Initializes Random Intra module. Should be called
* only after initialization (or changes) of the picture size or the
* random intra refresh value. In version jm2.1 it is impossible to
* change those values on-the-fly, hence RandomIntraInit should be
* called immediately after the parsing of the config file
*
* \par Input:
* xsize, ysize: size of the picture (in MBs)
* refresh : refresh rate in MBs per picture
************************************************************************
*/
void RandomIntraInit(int xsize, int ysize, int refresh)
{
int i, pos;
srand (1); // A fixed random initializer to make things reproducible
NumberOfMBs = xsize * ysize;
NumberIntraPerPicture = refresh;
if (refresh != 0)
{
RefreshPattern = malloc (sizeof (int) * NumberOfMBs);
if (RefreshPattern == NULL) no_mem_exit("RandomIntraInit: RefreshPattern");
IntraMBs = malloc (sizeof (int) * refresh);
if (IntraMBs == NULL) no_mem_exit("RandomIntraInit: IntraMBs");
for (i= 0; i<NumberOfMBs; i++)
RefreshPattern[i] = -1;
for (i=0; i<NumberOfMBs; i++)
{
do
{
pos = rand() % NumberOfMBs;
} while (RefreshPattern [pos] != -1);
RefreshPattern [pos] = i;
}
/*
for (i=0; i<NumberOfMBs; i++) printf ("%d\t", RefreshPattern[i]);
getchar();
*/
}
else
{
RefreshPattern = NULL;
IntraMBs = NULL;
}
}
/*!
************************************************************************
* \brief
* RandomIntra: Code an MB as Intra?
*
* \par Input
* MacroblockNumberInScanOrder
* \par Output
* 1 if an MB should be forced to Intra, according the the
* RefreshPattern
* 0 otherwise
*
************************************************************************
*/
int RandomIntra (int mb)
{
int i;
for (i=0; i<NumberIntraPerPicture; i++)
if (IntraMBs[i] == mb)
return 1;
return 0;
}
/*!
************************************************************************
* \brief
* RandomIntraNewPicture: Selects new set of MBs for forced Intra
*
* \par
* This function should be called exactly once per picture, and
* requires a finished initialization
*
************************************************************************
*/
void RandomIntraNewPicture ()
{
int i, j;
WalkAround += NumberIntraPerPicture;
for (j=0,i=WalkAround; j<NumberIntraPerPicture; j++, i++)
IntraMBs[j] = RefreshPattern [i%NumberOfMBs];
}
void RandomIntraUninit()
{
if (NumberIntraPerPicture >0 )
{
free(RefreshPattern);
free(IntraMBs);
}
}