blob: 0c85617b9b99f460d8830a56f091f9eadc34c55f [file] [log] [blame]
/*!
***********************************************************************
* \file errorconcealment.c
*
* \brief
* Implements error concealment scheme for H.264 decoder
*
* \date
* 6.10.2000
*
* \version
* 1.0
*
* \note
* This simple error concealment implemented in this decoder uses
* the existing dependencies of syntax elements.
* In case that an element is detected as false this elements and all
* dependend elements are marked as elements to conceal in the ec_flag[]
* array. If the decoder requests a new element by the function
* readSyntaxElement_xxxx() this array is checked first if an error concealment has
* to be applied on this element.
* In case that an error occured a concealed element is given to the
* decoding function in macroblock().
*
* \author
* Main contributors (see contributors.h for copyright, address and affiliation details)
* - Sebastian Purreiter <sebastian.purreiter@mch.siemens.de>
***********************************************************************
*/
#include "contributors.h"
#include "global.h"
#include "elements.h"
static int ec_flag[SE_MAX_ELEMENTS]; //!< array to set errorconcealment
/*
static char SEtypes[][25] =
{
"SE_HEADER",
"SE_PTYPE",
"SE_MBTYPE",
"SE_REFFRAME",
"SE_INTRAPREDMODE",
"SE_MVD",
"SE_CBP_INTRA",
"SE_LUM_DC_INTRA",
"SE_CHR_DC_INTRA",
"SE_LUM_AC_INTRA",
"SE_CHR_AC_INTRA",
"SE_CBP_INTER",
"SE_LUM_DC_INTER",
"SE_CHR_DC_INTER",
"SE_LUM_AC_INTER",
"SE_CHR_AC_INTER",
"SE_DELTA_QUANT_INTER",
"SE_DELTA_QUANT_INTRA",
"SE_BFRAME",
"SE_EOS"
};
*/
/*!
***********************************************************************
* \brief
* set concealment for all elements in same partition
* and dependend syntax elements
* \return
* EC_REQ, elements of same type or depending type need error concealment. \n
* EX_SYNC sync on next header
***********************************************************************
*/
int set_ec_flag(
int se) //!< type of syntax element to conceal
{
/*
if (ec_flag[se] == NO_EC)
printf("Error concealment on element %s\n",SEtypes[se]);
*/
switch (se)
{
case SE_HEADER :
ec_flag[SE_HEADER] = EC_REQ;
case SE_PTYPE :
ec_flag[SE_PTYPE] = EC_REQ;
case SE_MBTYPE :
ec_flag[SE_MBTYPE] = EC_REQ;
case SE_REFFRAME :
ec_flag[SE_REFFRAME] = EC_REQ;
ec_flag[SE_MVD] = EC_REQ; // set all motion vectors to zero length
se = SE_CBP_INTER; // conceal also Inter texture elements
break;
case SE_INTRAPREDMODE :
ec_flag[SE_INTRAPREDMODE] = EC_REQ;
se = SE_CBP_INTRA; // conceal also Intra texture elements
break;
case SE_MVD :
ec_flag[SE_MVD] = EC_REQ;
se = SE_CBP_INTER; // conceal also Inter texture elements
break;
default:
break;
}
switch (se)
{
case SE_CBP_INTRA :
ec_flag[SE_CBP_INTRA] = EC_REQ;
case SE_LUM_DC_INTRA :
ec_flag[SE_LUM_DC_INTRA] = EC_REQ;
case SE_CHR_DC_INTRA :
ec_flag[SE_CHR_DC_INTRA] = EC_REQ;
case SE_LUM_AC_INTRA :
ec_flag[SE_LUM_AC_INTRA] = EC_REQ;
case SE_CHR_AC_INTRA :
ec_flag[SE_CHR_AC_INTRA] = EC_REQ;
break;
case SE_CBP_INTER :
ec_flag[SE_CBP_INTER] = EC_REQ;
case SE_LUM_DC_INTER :
ec_flag[SE_LUM_DC_INTER] = EC_REQ;
case SE_CHR_DC_INTER :
ec_flag[SE_CHR_DC_INTER] = EC_REQ;
case SE_LUM_AC_INTER :
ec_flag[SE_LUM_AC_INTER] = EC_REQ;
case SE_CHR_AC_INTER :
ec_flag[SE_CHR_AC_INTER] = EC_REQ;
break;
case SE_DELTA_QUANT_INTER :
ec_flag[SE_DELTA_QUANT_INTER] = EC_REQ;
break;
case SE_DELTA_QUANT_INTRA :
ec_flag[SE_DELTA_QUANT_INTRA] = EC_REQ;
break;
default:
break;
}
return EC_REQ;
}
/*!
***********************************************************************
* \brief
* resets EC_Flags called at the start of each slice
*
***********************************************************************
*/
void reset_ec_flags()
{
int i;
for (i=0; i<SE_MAX_ELEMENTS; i++)
ec_flag[i] = NO_EC;
}
/*!
***********************************************************************
* \brief
* get error concealed element in dependence of syntax
* element se. \n
* This function implements the error concealment.
* \return
* NO_EC if no error concealment required \n
* EC_REQ if element requires error concealment
***********************************************************************
*/
int get_concealed_element(SyntaxElement *sym)
{
if (ec_flag[sym->type] == NO_EC)
return NO_EC;
/*
#if TRACE
printf("TRACE: get concealed element for %s!!!\n", SEtypes[sym->type]);
#endif
*/
switch (sym->type)
{
case SE_HEADER :
sym->len = 31;
sym->inf = 0; // Picture Header
break;
case SE_PTYPE : // inter_img_1
case SE_MBTYPE : // set COPY_MB
case SE_REFFRAME :
sym->len = 1;
sym->inf = 0;
break;
case SE_INTRAPREDMODE :
case SE_MVD :
sym->len = 1;
sym->inf = 0; // set vector to zero length
break;
case SE_CBP_INTRA :
sym->len = 5;
sym->inf = 0; // codenumber 3 <=> no CBP information for INTRA images
break;
case SE_LUM_DC_INTRA :
case SE_CHR_DC_INTRA :
case SE_LUM_AC_INTRA :
case SE_CHR_AC_INTRA :
sym->len = 1;
sym->inf = 0; // return EOB
break;
case SE_CBP_INTER :
sym->len = 1;
sym->inf = 0; // codenumber 1 <=> no CBP information for INTER images
break;
case SE_LUM_DC_INTER :
case SE_CHR_DC_INTER :
case SE_LUM_AC_INTER :
case SE_CHR_AC_INTER :
sym->len = 1;
sym->inf = 0; // return EOB
break;
case SE_DELTA_QUANT_INTER:
sym->len = 1;
sym->inf = 0;
break;
case SE_DELTA_QUANT_INTRA:
sym->len = 1;
sym->inf = 0;
break;
default:
break;
}
return EC_REQ;
}