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

Audio

开发平台:

Visual C++

  1. /*!
  2.  *************************************************************************************
  3.  * file erc_api.c
  4.  *
  5.  * brief
  6.  *    External (still inside video decoder) interface for error concealment module
  7.  *
  8.  *  author
  9.  *     - Ari Hourunranta                <ari.hourunranta@nokia.com>
  10.  *     - Viktor Varsa                     <viktor.varsa@nokia.com>
  11.  *     - Ye-Kui Wang                   <wyk@ieee.org>
  12.  *
  13.  *************************************************************************************
  14.  */
  15. #include "global.h"
  16. #include "memalloc.h"
  17. #include "erc_api.h"
  18. objectBuffer_t *erc_object_list = NULL;
  19. ercVariables_t *erc_errorVar = NULL;
  20. frame erc_recfr;
  21. int erc_mvperMB;
  22. /*!
  23.  ************************************************************************
  24.  * brief
  25.  *    Initinize the error concealment module
  26.  ************************************************************************
  27.  */
  28. void ercInit(int pic_sizex, int pic_sizey, int flag)
  29. {
  30.   ercClose(erc_errorVar);
  31.   erc_object_list = (objectBuffer_t *) calloc((pic_sizex * pic_sizey) >> 6, sizeof(objectBuffer_t));
  32.   if (erc_object_list == NULL) no_mem_exit("ercInit: erc_object_list");
  33.   // the error concealment instance is allocated
  34.   erc_errorVar = ercOpen();
  35.   // set error concealment ON
  36.   ercSetErrorConcealment(erc_errorVar, flag);
  37. }
  38. /*!
  39.  ************************************************************************
  40.  * brief
  41.  *      Allocates data structures used in error concealment.
  42.  *return
  43.  *      The allocated ercVariables_t is returned.
  44.  ************************************************************************
  45.  */
  46. ercVariables_t *ercOpen( void )
  47. {
  48.   ercVariables_t *errorVar = NULL;
  49.   errorVar = (ercVariables_t *)malloc( sizeof(ercVariables_t));
  50.   if ( errorVar == NULL ) no_mem_exit("ercOpen: errorVar");
  51.   errorVar->nOfMBs = 0;
  52.   errorVar->segments = NULL;
  53.   errorVar->currSegment = 0;
  54.   errorVar->yCondition = NULL;
  55.   errorVar->uCondition = NULL;
  56.   errorVar->vCondition = NULL;
  57.   errorVar->prevFrameYCondition = NULL;
  58.   errorVar->concealment = 1;
  59.   return errorVar;
  60. }
  61. /*!
  62.  ************************************************************************
  63.  * brief
  64.  *      Resets the variables used in error detection.
  65.  *      Should be called always when starting to decode a new frame.
  66.  * param errorVar
  67.  *      Variables for error concealment
  68.  * param nOfMBs
  69.  *      Number of macroblocks in a frame
  70.  * param numOfSegments
  71.  *    Estimated number of segments (memory reserved)
  72.  * param picSizeX
  73.  *      Width of the frame in pixels.
  74.  ************************************************************************
  75.  */
  76. void ercReset( ercVariables_t *errorVar, int nOfMBs, int numOfSegments, int picSizeX )
  77. {
  78.   int *tmp = NULL;
  79.   int i = 0;
  80.   if ( errorVar && errorVar->concealment )
  81.   {
  82.     // If frame size has been changed
  83.     if ( nOfMBs != errorVar->nOfMBs && errorVar->yCondition != NULL )
  84.     {
  85.       free( errorVar->yCondition );
  86.       errorVar->yCondition = NULL;
  87.       free( errorVar->prevFrameYCondition );
  88.       errorVar->prevFrameYCondition = NULL;
  89.       free( errorVar->uCondition );
  90.       errorVar->uCondition = NULL;
  91.       free( errorVar->vCondition );
  92.       errorVar->vCondition = NULL;
  93.       free( errorVar->segments );
  94.       errorVar->segments = NULL;
  95.     }
  96.     // If the structures are uninitialized (first frame, or frame size is changed)
  97.     if ( errorVar->yCondition == NULL )
  98.     {
  99.       errorVar->segments = (ercSegment_t *)malloc( numOfSegments*sizeof(ercSegment_t) );
  100.       if ( errorVar->segments == NULL ) no_mem_exit("ercReset: errorVar->segments");
  101.       memset( errorVar->segments, 0, numOfSegments*sizeof(ercSegment_t));
  102.       errorVar->nOfSegments = numOfSegments;
  103.       errorVar->yCondition = (int *)malloc( 4*nOfMBs*sizeof(int) );
  104.       if ( errorVar->yCondition == NULL ) no_mem_exit("ercReset: errorVar->yCondition");
  105.       errorVar->prevFrameYCondition = (int *)malloc( 4*nOfMBs*sizeof(int) );
  106.       if ( errorVar->prevFrameYCondition == NULL ) no_mem_exit("ercReset: errorVar->prevFrameYCondition");
  107.       errorVar->uCondition = (int *)malloc( nOfMBs*sizeof(int) );
  108.       if ( errorVar->uCondition == NULL ) no_mem_exit("ercReset: errorVar->uCondition");
  109.       errorVar->vCondition = (int *)malloc( nOfMBs*sizeof(int) );
  110.       if ( errorVar->vCondition == NULL ) no_mem_exit("ercReset: errorVar->vCondition");
  111.       errorVar->nOfMBs = nOfMBs;
  112.     }
  113.     else
  114.     {
  115.       // Store the yCondition struct of the previous frame
  116.       tmp = errorVar->prevFrameYCondition;
  117.       errorVar->prevFrameYCondition = errorVar->yCondition;
  118.       errorVar->yCondition = tmp;
  119.     }
  120.     // Reset tables and parameters
  121.     memset( errorVar->yCondition, 0, 4*nOfMBs*sizeof(*errorVar->yCondition));
  122.     memset( errorVar->uCondition, 0,   nOfMBs*sizeof(*errorVar->uCondition));
  123.     memset( errorVar->vCondition, 0,   nOfMBs*sizeof(*errorVar->vCondition));
  124.     if (errorVar->nOfSegments != numOfSegments)
  125.     {
  126.       free( errorVar->segments );
  127.       errorVar->segments = NULL;
  128.       errorVar->segments = (ercSegment_t *)malloc( numOfSegments*sizeof(ercSegment_t) );
  129.       if ( errorVar->segments == NULL ) no_mem_exit("ercReset: errorVar->segments");
  130.       errorVar->nOfSegments = numOfSegments;
  131.     }
  132.     memset( errorVar->segments, 0, errorVar->nOfSegments*sizeof(ercSegment_t));
  133.     for ( i = 0; i < errorVar->nOfSegments; i++ )
  134.     {
  135.       errorVar->segments[i].fCorrupted = 1; //! mark segments as corrupted
  136.       errorVar->segments[i].startMBPos = 0;
  137.       errorVar->segments[i].endMBPos = nOfMBs - 1;
  138.     }
  139.     errorVar->currSegment = 0;
  140.     errorVar->nOfCorruptedSegments = 0;
  141.   }
  142. }
  143. /*!
  144.  ************************************************************************
  145.  * brief
  146.  *      Resets the variables used in error detection.
  147.  *      Should be called always when starting to decode a new frame.
  148.  * param errorVar
  149.  *      Variables for error concealment
  150.  ************************************************************************
  151.  */
  152. void ercClose( ercVariables_t *errorVar )
  153. {
  154.   if ( errorVar != NULL )
  155.   {
  156.     if (errorVar->yCondition != NULL)
  157.     {
  158.       free( errorVar->segments );
  159.       free( errorVar->yCondition );
  160.       free( errorVar->uCondition );
  161.       free( errorVar->vCondition );
  162.       free( errorVar->prevFrameYCondition );
  163.     }
  164.     free( errorVar );
  165.     errorVar = NULL;
  166.   }
  167.   if (erc_object_list)
  168.   {
  169.     free(erc_object_list);
  170.     erc_object_list=NULL;
  171.   }
  172. }
  173. /*!
  174.  ************************************************************************
  175.  * brief
  176.  *      Sets error concealment ON/OFF. Can be invoked only between frames, not during a frame
  177.  * param errorVar
  178.  *      Variables for error concealment
  179.  * param value
  180.  *      New value
  181.  ************************************************************************
  182.  */
  183. void ercSetErrorConcealment( ercVariables_t *errorVar, int value )
  184. {
  185.   if ( errorVar != NULL )
  186.     errorVar->concealment = value;
  187. }
  188. /*!
  189.  ************************************************************************
  190.  * brief
  191.  *      Creates a new segment in the segment-list, and marks the start MB and bit position.
  192.  *      If the end of the previous segment was not explicitly marked by "ercStopSegment",
  193.  *      also marks the end of the previous segment.
  194.  *      If needed, it reallocates the segment-list for a larger storage place.
  195.  * param currMBNum
  196.  *      The MB number where the new slice/segment starts
  197.  * param segment
  198.  *      Segment/Slice No. counted by the caller
  199.  * param bitPos
  200.  *      Bitstream pointer: number of bits read from the buffer.
  201.  * param errorVar
  202.  *      Variables for error detector
  203.  ************************************************************************
  204.  */
  205. void ercStartSegment( int currMBNum, int segment, unsigned int bitPos, ercVariables_t *errorVar )
  206. {
  207.   if ( errorVar && errorVar->concealment )
  208.   {
  209.     errorVar->currSegmentCorrupted = 0;
  210.     errorVar->segments[ segment ].fCorrupted = 0;
  211.     errorVar->segments[ segment ].startMBPos = currMBNum;
  212.   }
  213. }
  214. /*!
  215.  ************************************************************************
  216.  * brief
  217.  *      Marks the end position of a segment.
  218.  * param currMBNum
  219.  *      The last MB number of the previous segment
  220.  * param segment
  221.  *      Segment/Slice No. counted by the caller
  222.  *      If (segment<0) the internal segment counter is used.
  223.  * param bitPos
  224.  *      Bitstream pointer: number of bits read from the buffer.
  225.  * param errorVar
  226.  *      Variables for error detector
  227.  ************************************************************************
  228.  */
  229. void ercStopSegment( int currMBNum, int segment, unsigned int bitPos, ercVariables_t *errorVar )
  230. {
  231.   if ( errorVar && errorVar->concealment )
  232.   {
  233.     errorVar->segments[ segment ].endMBPos = currMBNum; //! Changed TO 12.11.2001
  234.     errorVar->currSegment++;
  235.   }
  236. }
  237. /*!
  238.  ************************************************************************
  239.  * brief
  240.  *      Marks the current segment (the one which has the "currMBNum" MB in it)
  241.  *      as lost: all the blocks of the MBs in the segment as corrupted.
  242.  * param picSizeX
  243.  *      Width of the frame in pixels.
  244.  * param errorVar
  245.  *      Variables for error detector
  246.  ************************************************************************
  247.  */
  248. void ercMarkCurrSegmentLost(int picSizeX, ercVariables_t *errorVar )
  249. {
  250.   int j = 0;
  251.   int current_segment;
  252.   current_segment = errorVar->currSegment-1;
  253.   if ( errorVar && errorVar->concealment )
  254.   {
  255.     if (errorVar->currSegmentCorrupted == 0)
  256.     {
  257.       errorVar->nOfCorruptedSegments++;
  258.       errorVar->currSegmentCorrupted = 1;
  259.     }
  260.     for ( j = errorVar->segments[current_segment].startMBPos; j <= errorVar->segments[current_segment].endMBPos; j++ )
  261.     {
  262.       errorVar->yCondition[MBNum2YBlock (j, 0, picSizeX)] = ERC_BLOCK_CORRUPTED;
  263.       errorVar->yCondition[MBNum2YBlock (j, 1, picSizeX)] = ERC_BLOCK_CORRUPTED;
  264.       errorVar->yCondition[MBNum2YBlock (j, 2, picSizeX)] = ERC_BLOCK_CORRUPTED;
  265.       errorVar->yCondition[MBNum2YBlock (j, 3, picSizeX)] = ERC_BLOCK_CORRUPTED;
  266.       errorVar->uCondition[j] = ERC_BLOCK_CORRUPTED;
  267.       errorVar->vCondition[j] = ERC_BLOCK_CORRUPTED;
  268.     }
  269.     errorVar->segments[current_segment].fCorrupted = 1;
  270.   }
  271. }
  272. /*!
  273.  ************************************************************************
  274.  * brief
  275.  *      Marks the current segment (the one which has the "currMBNum" MB in it)
  276.  *      as OK: all the blocks of the MBs in the segment as OK.
  277.  * param picSizeX
  278.  *      Width of the frame in pixels.
  279.  * param errorVar
  280.  *      Variables for error detector
  281.  ************************************************************************
  282.  */
  283. void ercMarkCurrSegmentOK(int picSizeX, ercVariables_t *errorVar )
  284. {
  285.   int j = 0;
  286.   int current_segment;
  287.   current_segment = errorVar->currSegment-1;
  288.   if ( errorVar && errorVar->concealment )
  289.   {
  290.     // mark all the Blocks belonging to the segment as OK */
  291.     for ( j = errorVar->segments[current_segment].startMBPos; j <= errorVar->segments[current_segment].endMBPos; j++ )
  292.     {
  293.       errorVar->yCondition[MBNum2YBlock (j, 0, picSizeX)] = ERC_BLOCK_OK;
  294.       errorVar->yCondition[MBNum2YBlock (j, 1, picSizeX)] = ERC_BLOCK_OK;
  295.       errorVar->yCondition[MBNum2YBlock (j, 2, picSizeX)] = ERC_BLOCK_OK;
  296.       errorVar->yCondition[MBNum2YBlock (j, 3, picSizeX)] = ERC_BLOCK_OK;
  297.       errorVar->uCondition[j] = ERC_BLOCK_OK;
  298.       errorVar->vCondition[j] = ERC_BLOCK_OK;
  299.     }
  300.     errorVar->segments[current_segment].fCorrupted = 0;
  301.   }
  302. }
  303. /*!
  304.  ************************************************************************
  305.  * brief
  306.  *      Marks the Blocks of the given component (YUV) of the current MB as concealed.
  307.  * param currMBNum
  308.  *      Selects the segment where this MB number is in.
  309.  * param comp
  310.  *      Component to mark (0:Y, 1:U, 2:V, <0:All)
  311.  * param picSizeX
  312.  *      Width of the frame in pixels.
  313.  * param errorVar
  314.  *      Variables for error detector
  315.  ************************************************************************
  316.  */
  317. void ercMarkCurrMBConcealed( int currMBNum, int comp, int picSizeX, ercVariables_t *errorVar )
  318. {
  319.   int setAll = 0;
  320.   if ( errorVar && errorVar->concealment )
  321.   {
  322.     if (comp < 0)
  323.     {
  324.       setAll = 1;
  325.       comp = 0;
  326.     }
  327.     switch (comp)
  328.     {
  329.     case 0:
  330.       errorVar->yCondition[MBNum2YBlock (currMBNum, 0, picSizeX)] = ERC_BLOCK_CONCEALED;
  331.       errorVar->yCondition[MBNum2YBlock (currMBNum, 1, picSizeX)] = ERC_BLOCK_CONCEALED;
  332.       errorVar->yCondition[MBNum2YBlock (currMBNum, 2, picSizeX)] = ERC_BLOCK_CONCEALED;
  333.       errorVar->yCondition[MBNum2YBlock (currMBNum, 3, picSizeX)] = ERC_BLOCK_CONCEALED;
  334.       if (!setAll)
  335.         break;
  336.     case 1:
  337.       errorVar->uCondition[currMBNum] = ERC_BLOCK_CONCEALED;
  338.       if (!setAll)
  339.         break;
  340.     case 2:
  341.       errorVar->vCondition[currMBNum] = ERC_BLOCK_CONCEALED;
  342.     }
  343.   }
  344. }