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

Audio

开发平台:

Visual C++

  1. /*!
  2.  *************************************************************************************
  3.  * file
  4.  *      erc_do_p.c
  5.  *
  6.  * brief
  7.  *      Inter (P) frame error concealment algorithms for decoder
  8.  *
  9.  *  author
  10.  *      - Viktor Varsa                     <viktor.varsa@nokia.com>
  11.  *      - Ye-Kui Wang                      <wyk@ieee.org>
  12.  *      - Jill Boyce                       <jill.boyce@thomson.net>
  13.  *      - Saurav K Bandyopadhyay           <saurav@ieee.org>
  14.  *      - Zhenyu Wu                        <Zhenyu.Wu@thomson.net>
  15.  *      - Purvin Pandit                    <Purvin.Pandit@thomson.net>
  16.  *
  17.  *************************************************************************************
  18.  */
  19. #include "global.h"
  20. #include "mbuffer.h"
  21. #include "memalloc.h"
  22. #include "erc_do.h"
  23. #include "image.h"
  24. #include "mc_prediction.h"
  25. extern int erc_mvperMB;
  26. ImageParameters *erc_img;
  27. // picture error concealment
  28. // concealment_head points to first node in list, concealment_end points to
  29. // last node in list. Initialize both to NULL, meaning no nodes in list yet
  30. struct concealment_node *concealment_head = NULL;
  31. struct concealment_node *concealment_end = NULL;
  32. // static function declarations
  33. static int concealByCopy(frame *recfr, int currMBNum, objectBuffer_t *object_list, int picSizeX);
  34. static int concealByTrial(frame *recfr, imgpel *predMB,
  35.                           int currMBNum, objectBuffer_t *object_list, int predBlocks[],
  36.                           int picSizeX, int picSizeY, int *yCondition);
  37. static int edgeDistortion (int predBlocks[], int currYBlockNum, imgpel *predMB,
  38.                            imgpel *recY, int picSizeX, int regionSize);
  39. static void copyBetweenFrames (frame *recfr, int currYBlockNum, int picSizeX, int regionSize);
  40. static void buildPredRegionYUV(ImageParameters *img, int *mv, int x, int y, imgpel *predMB);
  41. // picture error concealment
  42. static void buildPredblockRegionYUV(ImageParameters *img, int *mv,
  43.                                     int x, int y, imgpel *predMB, int list);
  44. static void CopyImgData(imgpel **inputY, imgpel ***inputUV, imgpel **outputY, imgpel ***outputUV, 
  45.                         int img_width, int img_height, int img_width_cr, int img_height_cr);
  46. static void copyPredMB (int currYBlockNum, imgpel *predMB, frame *recfr,
  47.                         int picSizeX, int regionSize);
  48. extern const unsigned char subblk_offset_y[3][8][4];
  49. extern const unsigned char subblk_offset_x[3][8][4];
  50. static int uv_div[2][4] = {{0, 1, 1, 0}, {0, 1, 0, 0}}; //[x/y][yuv_format]
  51. /*!
  52.  ************************************************************************
  53.  * brief
  54.  *      The main function for Inter (P) frame concealment.
  55.  * return
  56.  *      0, if the concealment was not successful and simple concealment should be used
  57.  *      1, otherwise (even if none of the blocks were concealed)
  58.  * param recfr
  59.  *      Reconstructed frame buffer
  60.  * param object_list
  61.  *      Motion info for all MBs in the frame
  62.  * param picSizeX
  63.  *      Width of the frame in pixels
  64.  * param picSizeY
  65.  *      Height of the frame in pixels
  66.  * param errorVar
  67.  *      Variables for error concealment
  68.  * param chroma_format_idc
  69.  *      Chroma format IDC
  70.  ************************************************************************
  71.  */
  72. int ercConcealInterFrame(frame *recfr, objectBuffer_t *object_list,
  73.                          int picSizeX, int picSizeY, ercVariables_t *errorVar, int chroma_format_idc )
  74. {
  75.   int lastColumn = 0, lastRow = 0, predBlocks[8];
  76.   int lastCorruptedRow = -1, firstCorruptedRow = -1, currRow = 0,
  77.     row, column, columnInd, areaHeight = 0, i = 0;
  78.   imgpel *predMB;
  79.   /* if concealment is on */
  80.   if ( errorVar && errorVar->concealment )
  81.   {
  82.     /* if there are segments to be concealed */
  83.     if ( errorVar->nOfCorruptedSegments )
  84.     {
  85.       if (chroma_format_idc != YUV400)
  86.         predMB = (imgpel *) malloc ( (256 + (img->mb_cr_size_x*img->mb_cr_size_y)*2) * sizeof (imgpel));
  87.       else
  88.         predMB = (imgpel *) malloc(256 * sizeof (imgpel));
  89.       if ( predMB == NULL ) no_mem_exit("ercConcealInterFrame: predMB");
  90.       lastRow = (int) (picSizeY>>4);
  91.       lastColumn = (int) (picSizeX>>4);
  92.       for ( columnInd = 0; columnInd < lastColumn; columnInd ++)
  93.       {
  94.         column = ((columnInd%2) ? (lastColumn - columnInd/2 -1) : (columnInd/2));
  95.         for ( row = 0; row < lastRow; row++)
  96.         {
  97.           if ( errorVar->yCondition[MBxy2YBlock(column, row, 0, picSizeX)] <= ERC_BLOCK_CORRUPTED )
  98.           {                           // ERC_BLOCK_CORRUPTED (1) or ERC_BLOCK_EMPTY (0)
  99.             firstCorruptedRow = row;
  100.             /* find the last row which has corrupted blocks (in same continuous area) */
  101.             for ( lastCorruptedRow = row+1; lastCorruptedRow < lastRow; lastCorruptedRow++)
  102.             {
  103.               /* check blocks in the current column */
  104.               if (errorVar->yCondition[MBxy2YBlock(column, lastCorruptedRow, 0, picSizeX)] > ERC_BLOCK_CORRUPTED)
  105.               {
  106.                 /* current one is already OK, so the last was the previous one */
  107.                 lastCorruptedRow --;
  108.                 break;
  109.               }
  110.             }
  111.             if ( lastCorruptedRow >= lastRow )
  112.             {
  113.               /* correct only from above */
  114.               lastCorruptedRow = lastRow-1;
  115.               for ( currRow = firstCorruptedRow; currRow < lastRow; currRow++ )
  116.               {
  117.                 ercCollect8PredBlocks (predBlocks, (currRow<<1), (column<<1),
  118.                   errorVar->yCondition, (lastRow<<1), (lastColumn<<1), 2, 0);
  119.                 if(erc_mvperMB >= MVPERMB_THR)
  120.                   concealByTrial(recfr, predMB,
  121.                     currRow*lastColumn+column, object_list, predBlocks,
  122.                     picSizeX, picSizeY,
  123.                     errorVar->yCondition);
  124.                 else
  125.                   concealByCopy(recfr, currRow*lastColumn+column,
  126.                     object_list, picSizeX);
  127.                 ercMarkCurrMBConcealed (currRow*lastColumn+column, -1, picSizeX, errorVar);
  128.               }
  129.               row = lastRow;
  130.             }
  131.             else if ( firstCorruptedRow == 0 )
  132.             {
  133.               /* correct only from below */
  134.               for ( currRow = lastCorruptedRow; currRow >= 0; currRow-- )
  135.               {
  136.                 ercCollect8PredBlocks (predBlocks, (currRow<<1), (column<<1),
  137.                   errorVar->yCondition, (lastRow<<1), (lastColumn<<1), 2, 0);
  138.                 if(erc_mvperMB >= MVPERMB_THR)
  139.                   concealByTrial(recfr, predMB,
  140.                     currRow*lastColumn+column, object_list, predBlocks,
  141.                     picSizeX, picSizeY,
  142.                     errorVar->yCondition);
  143.                 else
  144.                   concealByCopy(recfr, currRow*lastColumn+column,
  145.                     object_list, picSizeX);
  146.                 ercMarkCurrMBConcealed (currRow*lastColumn+column, -1, picSizeX, errorVar);
  147.               }
  148.               row = lastCorruptedRow+1;
  149.             }
  150.             else
  151.             {
  152.               /* correct bi-directionally */
  153.               row = lastCorruptedRow+1;
  154.               areaHeight = lastCorruptedRow-firstCorruptedRow+1;
  155.               /*
  156.               *  Conceal the corrupted area switching between the up and the bottom rows
  157.               */
  158.               for ( i = 0; i < areaHeight; i++)
  159.               {
  160.                 if ( i % 2 )
  161.                 {
  162.                   currRow = lastCorruptedRow;
  163.                   lastCorruptedRow --;
  164.                 }
  165.                 else
  166.                 {
  167.                   currRow = firstCorruptedRow;
  168.                   firstCorruptedRow ++;
  169.                 }
  170.                 ercCollect8PredBlocks (predBlocks, (currRow<<1), (column<<1),
  171.                   errorVar->yCondition, (lastRow<<1), (lastColumn<<1), 2, 0);
  172.                 if(erc_mvperMB >= MVPERMB_THR)
  173.                   concealByTrial(recfr, predMB,
  174.                     currRow*lastColumn+column, object_list, predBlocks,
  175.                     picSizeX, picSizeY,
  176.                     errorVar->yCondition);
  177.                 else
  178.                   concealByCopy(recfr, currRow*lastColumn+column,
  179.                     object_list, picSizeX);
  180.                 ercMarkCurrMBConcealed (currRow*lastColumn+column, -1, picSizeX, errorVar);
  181.               }
  182.             }
  183.             lastCorruptedRow = -1;
  184.             firstCorruptedRow = -1;
  185.           }
  186.         }
  187.       }
  188.       free(predMB);
  189.     }
  190.     return 1;
  191.   }
  192.   else
  193.     return 0;
  194. }
  195. /*!
  196.  ************************************************************************
  197.  * brief
  198.  *      It conceals a given MB by simply copying the pixel area from the reference image
  199.  *      that is at the same location as the macroblock in the current image. This correcponds
  200.  *      to COPY MBs.
  201.  * return
  202.  *      Always zero (0).
  203.  * param recfr
  204.  *      Reconstructed frame buffer
  205.  * param currMBNum
  206.  *      current MB index
  207.  * param object_list
  208.  *      Motion info for all MBs in the frame
  209.  * param picSizeX
  210.  *      Width of the frame in pixels
  211.  ************************************************************************
  212.  */
  213. static int concealByCopy(frame *recfr, int currMBNum,
  214.                          objectBuffer_t *object_list, int picSizeX)
  215. {
  216.   objectBuffer_t *currRegion;
  217.   currRegion = object_list+(currMBNum<<2);
  218.   currRegion->regionMode = REGMODE_INTER_COPY;
  219.   currRegion->xMin = (xPosMB(currMBNum,picSizeX)<<4);
  220.   currRegion->yMin = (yPosMB(currMBNum,picSizeX)<<4);
  221.   copyBetweenFrames (recfr, MBNum2YBlock(currMBNum,0,picSizeX), picSizeX, 16);
  222.   return 0;
  223. }
  224. /*!
  225.  ************************************************************************
  226.  * brief
  227.  *      Copies the co-located pixel values from the reference to the current frame.
  228.  *      Used by concealByCopy
  229.  * param recfr
  230.  *      Reconstructed frame buffer
  231.  * param currYBlockNum
  232.  *      index of the block (8x8) in the Y plane
  233.  * param picSizeX
  234.  *      Width of the frame in pixels
  235.  * param regionSize
  236.  *      can be 16 or 8 to tell the dimension of the region to copy
  237.  ************************************************************************
  238.  */
  239. static void copyBetweenFrames (frame *recfr, int currYBlockNum, int picSizeX, int regionSize)
  240. {
  241.   int j, k, location, xmin, ymin;
  242.   StorablePicture* refPic = listX[0][0];
  243.   /* set the position of the region to be copied */
  244.   xmin = (xPosYBlock(currYBlockNum,picSizeX)<<3);
  245.   ymin = (yPosYBlock(currYBlockNum,picSizeX)<<3);
  246.   for (j = ymin; j < ymin + regionSize; j++)
  247.     for (k = xmin; k < xmin + regionSize; k++)
  248.     {
  249.       location = j * picSizeX + k;
  250. //th      recfr->yptr[location] = dec_picture->imgY[j][k];
  251.       recfr->yptr[location] = refPic->imgY[j][k];
  252.     }
  253.     for (j = ymin >> uv_div[1][dec_picture->chroma_format_idc]; j < (ymin + regionSize) >> uv_div[1][dec_picture->chroma_format_idc]; j++)
  254.       for (k = xmin >> uv_div[0][dec_picture->chroma_format_idc]; k < (xmin + regionSize) >> uv_div[0][dec_picture->chroma_format_idc]; k++)
  255.       {
  256. //        location = j * picSizeX / 2 + k;
  257.         location = ((j * picSizeX) >> uv_div[0][dec_picture->chroma_format_idc]) + k;
  258. //th        recfr->uptr[location] = dec_picture->imgUV[0][j][k];
  259. //th        recfr->vptr[location] = dec_picture->imgUV[1][j][k];
  260.         recfr->uptr[location] = refPic->imgUV[0][j][k];
  261.         recfr->vptr[location] = refPic->imgUV[1][j][k];
  262.       }
  263. }
  264. /*!
  265.  ************************************************************************
  266.  * brief
  267.  *      It conceals a given MB by using the motion vectors of one reliable neighbor. That MV of a
  268.  *      neighbor is selected wich gives the lowest pixel difference at the edges of the MB
  269.  *      (see function edgeDistortion). This corresponds to a spatial smoothness criteria.
  270.  * return
  271.  *      Always zero (0).
  272.  * param recfr
  273.  *      Reconstructed frame buffer
  274.  * param predMB
  275.  *      memory area for storing temporary pixel values for a macroblock
  276.  *      the Y,U,V planes are concatenated y = predMB, u = predMB+256, v = predMB+320
  277.  * param currMBNum
  278.  *      current MB index
  279.  * param object_list
  280.  *      array of region structures storing region mode and mv for each region
  281.  * param predBlocks
  282.  *      status array of the neighboring blocks (if they are OK, concealed or lost)
  283.  * param picSizeX
  284.  *      Width of the frame in pixels
  285.  * param picSizeY
  286.  *      Height of the frame in pixels
  287.  * param yCondition
  288.  *      array for conditions of Y blocks from ercVariables_t
  289.  ************************************************************************
  290.  */
  291. static int concealByTrial(frame *recfr, imgpel *predMB,
  292.                           int currMBNum, objectBuffer_t *object_list, int predBlocks[],
  293.                           int picSizeX, int picSizeY, int *yCondition)
  294. {
  295.   int predMBNum = 0, numMBPerLine,
  296.       compSplit1 = 0, compSplit2 = 0, compLeft = 1, comp = 0, compPred, order = 1,
  297.       fInterNeighborExists, numIntraNeighbours,
  298.       fZeroMotionChecked, predSplitted = 0,
  299.       threshold = ERC_BLOCK_OK,
  300.       minDist, currDist, i, k, bestDir;
  301.   int regionSize;
  302.   objectBuffer_t *currRegion;
  303.   int mvBest[3] , mvPred[3], *mvptr;
  304.   numMBPerLine = (int) (picSizeX>>4);
  305.   img->current_mb_nr = currMBNum;
  306.   comp = 0;
  307.   regionSize = 16;
  308.   do
  309.   { /* 4 blocks loop */
  310.     currRegion = object_list+(currMBNum<<2)+comp;
  311.     /* set the position of the region to be concealed */
  312.     currRegion->xMin = (xPosYBlock(MBNum2YBlock(currMBNum,comp,picSizeX),picSizeX)<<3);
  313.     currRegion->yMin = (yPosYBlock(MBNum2YBlock(currMBNum,comp,picSizeX),picSizeX)<<3);
  314.     do
  315.     { /* reliability loop */
  316.       minDist = 0;
  317.       fInterNeighborExists = 0;
  318.       numIntraNeighbours = 0;
  319.       fZeroMotionChecked = 0;
  320.       /* loop the 4 neighbours */
  321.       for (i = 4; i < 8; i++)
  322.       {
  323.         /* if reliable, try it */
  324.         if (predBlocks[i] >= threshold)
  325.         {
  326.           switch (i)
  327.           {
  328.           case 4:
  329.             predMBNum = currMBNum-numMBPerLine;
  330.             compSplit1 = 2;
  331.             compSplit2 = 3;
  332.             break;
  333.           case 5:
  334.             predMBNum = currMBNum-1;
  335.             compSplit1 = 1;
  336.             compSplit2 = 3;
  337.             break;
  338.           case 6:
  339.             predMBNum = currMBNum+numMBPerLine;
  340.             compSplit1 = 0;
  341.             compSplit2 = 1;
  342.             break;
  343.           case 7:
  344.             predMBNum = currMBNum+1;
  345.             compSplit1 = 0;
  346.             compSplit2 = 2;
  347.             break;
  348.           }
  349.           /* try the concealment with the Motion Info of the current neighbour
  350.           only try if the neighbour is not Intra */
  351.           if (isBlock(object_list,predMBNum,compSplit1,INTRA) ||
  352.             isBlock(object_list,predMBNum,compSplit2,INTRA))
  353.           {
  354.             numIntraNeighbours++;
  355.           }
  356.           else
  357.           {
  358.             /* if neighbour MB is splitted, try both neighbour blocks */
  359.             for (predSplitted = isSplitted(object_list, predMBNum),
  360.               compPred = compSplit1;
  361.               predSplitted >= 0;
  362.               compPred = compSplit2,
  363.               predSplitted -= ((compSplit1 == compSplit2) ? 2 : 1))
  364.             {
  365.               /* if Zero Motion Block, do the copying. This option is tried only once */
  366.               if (isBlock(object_list, predMBNum, compPred, INTER_COPY))
  367.               {
  368.                 if (fZeroMotionChecked)
  369.                 {
  370.                   continue;
  371.                 }
  372.                 else
  373.                 {
  374.                   fZeroMotionChecked = 1;
  375.                   mvPred[0] = mvPred[1] = 0;
  376.                   mvPred[2] = 0;
  377.                   buildPredRegionYUV(erc_img, mvPred, currRegion->xMin, currRegion->yMin, predMB);
  378.                 }
  379.               }
  380.               /* build motion using the neighbour's Motion Parameters */
  381.               else if (isBlock(object_list,predMBNum,compPred,INTRA))
  382.               {
  383.                 continue;
  384.               }
  385.               else
  386.               {
  387.                 mvptr = getParam(object_list, predMBNum, compPred, mv);
  388.                 mvPred[0] = mvptr[0];
  389.                 mvPred[1] = mvptr[1];
  390.                 mvPred[2] = mvptr[2];
  391.                 buildPredRegionYUV(erc_img, mvPred, currRegion->xMin, currRegion->yMin, predMB);
  392.               }
  393.               /* measure absolute boundary pixel difference */
  394.               currDist = edgeDistortion(predBlocks,
  395.                 MBNum2YBlock(currMBNum,comp,picSizeX),
  396.                 predMB, recfr->yptr, picSizeX, regionSize);
  397.               /* if so far best -> store the pixels as the best concealment */
  398.               if (currDist < minDist || !fInterNeighborExists)
  399.               {
  400.                 minDist = currDist;
  401.                 bestDir = i;
  402.                 for (k=0;k<3;k++)
  403.                   mvBest[k] = mvPred[k];
  404.                 currRegion->regionMode =
  405.                   (isBlock(object_list, predMBNum, compPred, INTER_COPY)) ?
  406.                   ((regionSize == 16) ? REGMODE_INTER_COPY : REGMODE_INTER_COPY_8x8) :
  407.                   ((regionSize == 16) ? REGMODE_INTER_PRED : REGMODE_INTER_PRED_8x8);
  408.                 copyPredMB(MBNum2YBlock(currMBNum,comp,picSizeX), predMB, recfr,
  409.                   picSizeX, regionSize);
  410.               }
  411.               fInterNeighborExists = 1;
  412.             }
  413.           }
  414.         }
  415.     }
  416.     threshold--;
  417.     } while ((threshold >= ERC_BLOCK_CONCEALED) && (fInterNeighborExists == 0));
  418.     /* always try zero motion */
  419.     if (!fZeroMotionChecked)
  420.     {
  421.       mvPred[0] = mvPred[1] = 0;
  422.       mvPred[2] = 0;
  423.       buildPredRegionYUV(erc_img, mvPred, currRegion->xMin, currRegion->yMin, predMB);
  424.       currDist = edgeDistortion(predBlocks,
  425.         MBNum2YBlock(currMBNum,comp,picSizeX),
  426.         predMB, recfr->yptr, picSizeX, regionSize);
  427.       if (currDist < minDist || !fInterNeighborExists)
  428.       {
  429.         minDist = currDist;
  430.         for (k=0;k<3;k++)
  431.           mvBest[k] = mvPred[k];
  432.         currRegion->regionMode =
  433.           ((regionSize == 16) ? REGMODE_INTER_COPY : REGMODE_INTER_COPY_8x8);
  434.         copyPredMB(MBNum2YBlock(currMBNum,comp,picSizeX), predMB, recfr,
  435.           picSizeX, regionSize);
  436.       }
  437.     }
  438.     for (i=0; i<3; i++)
  439.       currRegion->mv[i] = mvBest[i];
  440.     yCondition[MBNum2YBlock(currMBNum,comp,picSizeX)] = ERC_BLOCK_CONCEALED;
  441.     comp = (comp+order+4)%4;
  442.     compLeft--;
  443.     } while (compLeft);
  444.     return 0;
  445. }
  446. /*!
  447. ************************************************************************
  448. * brief
  449. *      Builds the motion prediction pixels from the given location (in 1/4 pixel units)
  450. *      of the reference frame. It not only copies the pixel values but builds the interpolation
  451. *      when the pixel positions to be copied from is not full pixel (any 1/4 pixel position).
  452. *      It copies the resulting pixel vlaues into predMB.
  453. * param img
  454. *      The pointer of img_par struture of current frame
  455. * param mv
  456. *      The pointer of the predicted MV of the current (being concealed) MB
  457. * param x
  458. *      The x-coordinate of the above-left corner pixel of the current MB
  459. * param y
  460. *      The y-coordinate of the above-left corner pixel of the current MB
  461. * param predMB
  462. *      memory area for storing temporary pixel values for a macroblock
  463. *      the Y,U,V planes are concatenated y = predMB, u = predMB+256, v = predMB+320
  464. ************************************************************************
  465. */
  466. static void buildPredRegionYUV(ImageParameters *img, int *mv, int x, int y, imgpel *predMB)
  467. {
  468.   static imgpel tmp_block[MB_BLOCK_SIZE][MB_BLOCK_SIZE];
  469.   int i=0, j=0, ii=0, jj=0,i1=0,j1=0,j4=0,i4=0;
  470.   int jf=0;
  471.   int uv;
  472.   int vec1_x=0,vec1_y=0;
  473.   int ioff,joff;
  474.   imgpel *pMB = predMB;
  475.   int ii0,jj0,ii1,jj1,if1,jf1,if0,jf0;
  476.   int mv_mul;
  477.   //FRExt
  478.   int f1_x, f1_y, f2_x, f2_y, f3, f4, ifx;
  479.   int b8, b4;
  480.   int yuv = dec_picture->chroma_format_idc - 1;
  481.   int ref_frame = imax (mv[2], 0); // !!KS: quick fix, we sometimes seem to get negative ref_pic here, so restrict to zero and above
  482.   /* Update coordinates of the current concealed macroblock */
  483.   img->mb_x = x/MB_BLOCK_SIZE;
  484.   img->mb_y = y/MB_BLOCK_SIZE;
  485.   img->block_y = img->mb_y * BLOCK_SIZE;
  486.   img->pix_c_y = img->mb_y * img->mb_cr_size_y;
  487.   img->block_x = img->mb_x * BLOCK_SIZE;
  488.   img->pix_c_x = img->mb_x * img->mb_cr_size_x;
  489.   mv_mul=4;
  490.   // luma *******************************************************
  491.   for(j=0;j<MB_BLOCK_SIZE/BLOCK_SIZE;j++)
  492.   {
  493.     joff=j*4;
  494.     j4=img->block_y+j;
  495.     for(i=0;i<MB_BLOCK_SIZE/BLOCK_SIZE;i++)
  496.     {
  497.       ioff=i*4;
  498.       i4=img->block_x+i;
  499.       vec1_x = i4*4*mv_mul + mv[0];
  500.       vec1_y = j4*4*mv_mul + mv[1];
  501.       get_block_luma(PLANE_Y, listX[0][ref_frame], vec1_x, vec1_y, BLOCK_SIZE, BLOCK_SIZE, img, tmp_block);  
  502.       for(ii=0;ii<BLOCK_SIZE;ii++)
  503.         for(jj=0;jj<MB_BLOCK_SIZE/BLOCK_SIZE;jj++)
  504.           img->mb_pred[LumaComp][jj+joff][ii+ioff]=tmp_block[jj][ii];
  505.     }
  506.   }
  507.   for (j = 0; j < 16; j++)
  508.   {
  509.     for (i = 0; i < 16; i++)
  510.     {
  511.       pMB[j*16+i] = img->mb_pred[LumaComp][j][i];
  512.     }
  513.   }
  514.   pMB += 256;
  515.   if (dec_picture->chroma_format_idc != YUV400)
  516.   {
  517.     // chroma *******************************************************
  518.     f1_x = 64/img->mb_cr_size_x;
  519.     f2_x=f1_x-1;
  520.     f1_y = 64/img->mb_cr_size_y;
  521.     f2_y=f1_y-1;
  522.     f3=f1_x*f1_y;
  523.     f4=f3>>1;
  524.     for(uv=0;uv<2;uv++)
  525.     {
  526.       for (b8=0;b8<(img->num_uv_blocks);b8++)
  527.       {
  528.         for(b4=0;b4<4;b4++)
  529.         {
  530.           joff = subblk_offset_y[yuv][b8][b4];
  531.           j4=img->pix_c_y+joff;
  532.           ioff = subblk_offset_x[yuv][b8][b4];
  533.           i4=img->pix_c_x+ioff;
  534.           for(jj=0;jj<4;jj++)
  535.           {
  536.             jf=(j4+jj)/(img->mb_cr_size_y/4);     // jf  = Subblock_y-coordinate
  537.             for(ii=0;ii<4;ii++)
  538.             {
  539.               ifx=(i4+ii)/(img->mb_cr_size_x/4);  // ifx = Subblock_x-coordinate
  540.               i1=(i4+ii)*f1_x + mv[0];
  541.               j1=(j4+jj)*f1_y + mv[1];
  542.               ii0=iClip3 (0, dec_picture->size_x_cr-1, i1/f1_x);
  543.               jj0=iClip3 (0, dec_picture->size_y_cr-1, j1/f1_y);
  544.               ii1=iClip3 (0, dec_picture->size_x_cr-1, ((i1+f2_x)/f1_x));
  545.               jj1=iClip3 (0, dec_picture->size_y_cr-1, ((j1+f2_y)/f1_y));
  546.               if1=(i1 & f2_x);
  547.               jf1=(j1 & f2_y);
  548.               if0=f1_x-if1;
  549.               jf0=f1_y-jf1;
  550.               img->mb_pred[uv + 1][jj+joff][ii+ioff]=(if0*jf0*listX[0][ref_frame]->imgUV[uv][jj0][ii0]+
  551.                                           if1*jf0*listX[0][ref_frame]->imgUV[uv][jj0][ii1]+
  552.                                           if0*jf1*listX[0][ref_frame]->imgUV[uv][jj1][ii0]+
  553.                                           if1*jf1*listX[0][ref_frame]->imgUV[uv][jj1][ii1]+f4)/f3;
  554.             }
  555.           }
  556.         }
  557.       }
  558.       for (j = 0; j < 8; j++)
  559.       {
  560.         for (i = 0; i < 8; i++)
  561.         {
  562.           pMB[j*8+i] = img->mb_pred[uv + 1][j][i];
  563.         }
  564.       }
  565.       pMB += 64;
  566.     }
  567.   }
  568. }
  569. /*!
  570.  ************************************************************************
  571.  * brief
  572.  *      Copies pixel values between a YUV frame and the temporary pixel value storage place. This is
  573.  *      used to save some pixel values temporarily before overwriting it, or to copy back to a given
  574.  *      location in a frame the saved pixel values.
  575.  * param currYBlockNum
  576.  *      index of the block (8x8) in the Y plane
  577.  * param predMB
  578.  *      memory area where the temporary pixel values are stored
  579.  *      the Y,U,V planes are concatenated y = predMB, u = predMB+256, v = predMB+320
  580.  * param recfr
  581.  *      pointer to a YUV frame
  582.  * param picSizeX
  583.  *      picture width in pixels
  584.  * param regionSize
  585.  *      can be 16 or 8 to tell the dimension of the region to copy
  586.  ************************************************************************
  587.  */
  588. static void copyPredMB (int currYBlockNum, imgpel *predMB, frame *recfr,
  589.                         int picSizeX, int regionSize)
  590. {
  591.   int j, k, xmin, ymin, xmax, ymax;
  592.   int locationTmp, locationPred;
  593.   int uv_x = uv_div[0][dec_picture->chroma_format_idc];
  594.   int uv_y = uv_div[1][dec_picture->chroma_format_idc];
  595.   xmin = (xPosYBlock(currYBlockNum,picSizeX)<<3);
  596.   ymin = (yPosYBlock(currYBlockNum,picSizeX)<<3);
  597.   xmax = xmin + regionSize -1;
  598.   ymax = ymin + regionSize -1;
  599.   for (j = ymin; j <= ymax; j++)
  600.   {
  601.     for (k = xmin; k <= xmax; k++)
  602.     {
  603.       locationPred = j * picSizeX + k;
  604.       locationTmp = (j-ymin) * 16 + (k-xmin);
  605.       dec_picture->imgY[j][k] = predMB[locationTmp];
  606.     }
  607.   }
  608.   if (dec_picture->chroma_format_idc != YUV400)
  609.   {
  610.     for (j = (ymin>>uv_y); j <= (ymax>>uv_y); j++)
  611.     {
  612.       for (k = (xmin>>uv_x); k <= (xmax>>uv_x); k++)
  613.       {
  614.         locationPred = ((j * picSizeX) >> uv_x) + k;
  615.         locationTmp = (j-(ymin>>uv_y)) * img->mb_cr_size_x + (k-(xmin>>1)) + 256;
  616.         dec_picture->imgUV[0][j][k] = predMB[locationTmp];
  617.         locationTmp += 64;
  618.         dec_picture->imgUV[1][j][k] = predMB[locationTmp];
  619.       }
  620.     }
  621.   }
  622. }
  623. /*!
  624.  ************************************************************************
  625.  * brief
  626.  *      Calculates a weighted pixel difference between edge Y pixels of the macroblock stored in predMB
  627.  *      and the pixels in the given Y plane of a frame (recY) that would become neighbor pixels if
  628.  *      predMB was placed at currYBlockNum block position into the frame. This "edge distortion" value
  629.  *      is used to determine how well the given macroblock in predMB would fit into the frame when
  630.  *      considering spatial smoothness. If there are correctly received neighbor blocks (status stored
  631.  *      in predBlocks) only they are used in calculating the edge distorion; otherwise also the already
  632.  *      concealed neighbor blocks can also be used.
  633.  * return
  634.  *      The calculated weighted pixel difference at the edges of the MB.
  635.  * param predBlocks
  636.  *      status array of the neighboring blocks (if they are OK, concealed or lost)
  637.  * param currYBlockNum
  638.  *      index of the block (8x8) in the Y plane
  639.  * param predMB
  640.  *      memory area where the temporary pixel values are stored
  641.  *      the Y,U,V planes are concatenated y = predMB, u = predMB+256, v = predMB+320
  642.  * param recY
  643.  *      pointer to a Y plane of a YUV frame
  644.  * param picSizeX
  645.  *      picture width in pixels
  646.  * param regionSize
  647.  *      can be 16 or 8 to tell the dimension of the region to copy
  648.  ************************************************************************
  649.  */
  650. static int edgeDistortion (int predBlocks[], int currYBlockNum, imgpel *predMB,
  651.                            imgpel *recY, int picSizeX, int regionSize)
  652. {
  653.   int i, j, distortion, numOfPredBlocks, threshold = ERC_BLOCK_OK;
  654.   imgpel *currBlock = NULL, *neighbor = NULL;
  655.   int currBlockOffset = 0;
  656.   currBlock = recY + (yPosYBlock(currYBlockNum,picSizeX)<<3)*picSizeX + (xPosYBlock(currYBlockNum,picSizeX)<<3);
  657.   do
  658.   {
  659.     distortion = 0; numOfPredBlocks = 0;
  660.     // loop the 4 neighbors
  661.     for (j = 4; j < 8; j++)
  662.     {
  663.       /* if reliable, count boundary pixel difference */
  664.       if (predBlocks[j] >= threshold)
  665.       {
  666.         switch (j)
  667.         {
  668.         case 4:
  669.           neighbor = currBlock - picSizeX;
  670.           for ( i = 0; i < regionSize; i++ )
  671.           {
  672.             distortion += iabs((int)(predMB[i] - neighbor[i]));
  673.           }
  674.           break;
  675.         case 5:
  676.           neighbor = currBlock - 1;
  677.           for ( i = 0; i < regionSize; i++ )
  678.           {
  679.             distortion += iabs((int)(predMB[i*16] - neighbor[i*picSizeX]));
  680.           }
  681.           break;
  682.         case 6:
  683.           neighbor = currBlock + regionSize*picSizeX;
  684.           currBlockOffset = (regionSize-1)*16;
  685.           for ( i = 0; i < regionSize; i++ )
  686.           {
  687.             distortion += iabs((int)(predMB[i+currBlockOffset] - neighbor[i]));
  688.           }
  689.           break;
  690.         case 7:
  691.           neighbor = currBlock + regionSize;
  692.           currBlockOffset = regionSize-1;
  693.           for ( i = 0; i < regionSize; i++ )
  694.           {
  695.             distortion += iabs((int)(predMB[i*16+currBlockOffset] - neighbor[i*picSizeX]));
  696.           }
  697.           break;
  698.         }
  699.         numOfPredBlocks++;
  700.       }
  701.     }
  702.     threshold--;
  703.     if (threshold < ERC_BLOCK_CONCEALED)
  704.       break;
  705.   } while (numOfPredBlocks == 0);
  706.   if(numOfPredBlocks == 0)
  707.   {
  708.     return 0;
  709.     // assert (numOfPredBlocks != 0); !!!KS hmm, trying to continue...
  710.   }
  711.   return (distortion/numOfPredBlocks);
  712. }
  713. // picture error concealment below
  714. /*!
  715. ************************************************************************
  716. * brief
  717. * The motion prediction pixels are calculated from the given location (in
  718. * 1/4 pixel units) of the referenced frame. It copies the sub block from the
  719. * corresponding reference to the frame to be concealed.
  720. *
  721. *************************************************************************
  722. */
  723. static void buildPredblockRegionYUV(ImageParameters *img, int *mv,
  724.                                     int x, int y, imgpel *predMB, int list)
  725. {
  726.   static imgpel tmp_block[MB_BLOCK_SIZE][MB_BLOCK_SIZE];
  727.   int i=0,j=0,ii=0,jj=0,i1=0,j1=0,j4=0,i4=0;
  728.   int jf=0;
  729.   int uv;
  730.   int vec1_x=0,vec1_y=0;
  731.   int ioff,joff;
  732.   imgpel *pMB = predMB;
  733.   int ii0,jj0,ii1,jj1,if1,jf1,if0,jf0;
  734.   int mv_mul;
  735.   //FRExt
  736.   int f1_x, f1_y, f2_x, f2_y, f3, f4, ifx;
  737.   int yuv = dec_picture->chroma_format_idc - 1;
  738.   int ref_frame = mv[2];
  739.   /* Update coordinates of the current concealed macroblock */
  740.   img->mb_x = x/BLOCK_SIZE;
  741.   img->mb_y = y/BLOCK_SIZE;
  742.   img->block_y = img->mb_y * BLOCK_SIZE;
  743.   img->pix_c_y = img->mb_y * img->mb_cr_size_y/4;
  744.   img->block_x = img->mb_x * BLOCK_SIZE;
  745.   img->pix_c_x = img->mb_x * img->mb_cr_size_x/4;
  746.   mv_mul=4;
  747.   // luma *******************************************************
  748.   vec1_x = x*mv_mul + mv[0];
  749.   vec1_y = y*mv_mul + mv[1];
  750.   get_block_luma(PLANE_Y, listX[list][ref_frame], vec1_x,vec1_y, BLOCK_SIZE, BLOCK_SIZE, img, tmp_block);  
  751.   for(jj=0;jj<MB_BLOCK_SIZE/BLOCK_SIZE;jj++)
  752.     for(ii=0;ii<BLOCK_SIZE;ii++)
  753.       img->mb_pred[LumaComp][jj][ii]=tmp_block[jj][ii];
  754.   for (j = 0; j < 4; j++)
  755.   {
  756.     for (i = 0; i < 4; i++)
  757.     {
  758.       pMB[j*4+i] = img->mb_pred[LumaComp][j][i];
  759.     }
  760.   }
  761.   pMB += 16;
  762.   if (dec_picture->chroma_format_idc != YUV400)
  763.   {
  764.     // chroma *******************************************************
  765.     f1_x = 64/(img->mb_cr_size_x);
  766.     f2_x=f1_x-1;
  767.     f1_y = 64/(img->mb_cr_size_y);
  768.     f2_y=f1_y-1;
  769.     f3=f1_x*f1_y;
  770.     f4=f3>>1;
  771.     for(uv=0;uv<2;uv++)
  772.     {
  773.       joff = subblk_offset_y[yuv][0][0];
  774.       j4=img->pix_c_y+joff;
  775.       ioff = subblk_offset_x[yuv][0][0];
  776.       i4=img->pix_c_x+ioff;
  777.       for(jj=0;jj<2;jj++)
  778.       {
  779.         jf=(j4+jj)/(img->mb_cr_size_y/4);     // jf  = Subblock_y-coordinate
  780.         for(ii=0;ii<2;ii++)
  781.         {
  782.           ifx=(i4+ii)/(img->mb_cr_size_x/4);  // ifx = Subblock_x-coordinate
  783.           i1=(i4+ii)*f1_x + mv[0];
  784.           j1=(j4+jj)*f1_y + mv[1];
  785.           ii0=iClip3 (0, dec_picture->size_x_cr-1, i1/f1_x);
  786.           jj0=iClip3 (0, dec_picture->size_y_cr-1, j1/f1_y);
  787.           ii1=iClip3 (0, dec_picture->size_x_cr-1, ((i1+f2_x)/f1_x));
  788.           jj1=iClip3 (0, dec_picture->size_y_cr-1, ((j1+f2_y)/f1_y));
  789.           if1=(i1 & f2_x);
  790.           jf1=(j1 & f2_y);
  791.           if0=f1_x-if1;
  792.           jf0=f1_y-jf1;
  793.           img->mb_pred[uv + 1][jj][ii]=(if0*jf0*listX[list][ref_frame]->imgUV[uv][jj0][ii0]+
  794.             if1*jf0*listX[list][ref_frame]->imgUV[uv][jj0][ii1]+
  795.             if0*jf1*listX[list][ref_frame]->imgUV[uv][jj1][ii0]+
  796.             if1*jf1*listX[list][ref_frame]->imgUV[uv][jj1][ii1]+f4)/f3;
  797.         }
  798.       }
  799.       for (j = 0; j < 2; j++)
  800.       {
  801.         for (i = 0; i < 2; i++)
  802.         {
  803.           pMB[j*2+i] = img->mb_pred[uv + 1][j][i];
  804.         }
  805.       }
  806.       pMB += 4;
  807.     }
  808.   }
  809. }
  810. /*!
  811. ************************************************************************
  812. * brief
  813. *    compares two stored pictures by picture number for qsort in descending order
  814. *
  815. ************************************************************************
  816. */
  817. static int compare_pic_by_pic_num_desc( const void *arg1, const void *arg2 )
  818. {
  819.   if ( (*(StorablePicture**)arg1)->pic_num < (*(StorablePicture**)arg2)->pic_num)
  820.     return 1;
  821.   if ( (*(StorablePicture**)arg1)->pic_num > (*(StorablePicture**)arg2)->pic_num)
  822.     return -1;
  823.   else
  824.     return 0;
  825. }
  826. /*!
  827. ************************************************************************
  828. * brief
  829. *    compares two stored pictures by picture number for qsort in descending order
  830. *
  831. ************************************************************************
  832. */
  833. static int compare_pic_by_lt_pic_num_asc( const void *arg1, const void *arg2 )
  834. {
  835.   if ( (*(StorablePicture**)arg1)->long_term_pic_num < (*(StorablePicture**)arg2)->long_term_pic_num)
  836.     return -1;
  837.   if ( (*(StorablePicture**)arg1)->long_term_pic_num > (*(StorablePicture**)arg2)->long_term_pic_num)
  838.     return 1;
  839.   else
  840.     return 0;
  841. }
  842. /*!
  843. ************************************************************************
  844. * brief
  845. *    compares two stored pictures by poc for qsort in ascending order
  846. *
  847. ************************************************************************
  848. */
  849. static int compare_pic_by_poc_asc( const void *arg1, const void *arg2 )
  850. {
  851.   if ( (*(StorablePicture**)arg1)->poc < (*(StorablePicture**)arg2)->poc)
  852.     return -1;
  853.   if ( (*(StorablePicture**)arg1)->poc > (*(StorablePicture**)arg2)->poc)
  854.     return 1;
  855.   else
  856.     return 0;
  857. }
  858. /*!
  859. ************************************************************************
  860. * brief
  861. *    compares two stored pictures by poc for qsort in descending order
  862. *
  863. ************************************************************************
  864. */
  865. static int compare_pic_by_poc_desc( const void *arg1, const void *arg2 )
  866. {
  867.   if ( (*(StorablePicture**)arg1)->poc < (*(StorablePicture**)arg2)->poc)
  868.     return 1;
  869.   if ( (*(StorablePicture**)arg1)->poc > (*(StorablePicture**)arg2)->poc)
  870.     return -1;
  871.   else
  872.     return 0;
  873. }
  874. /*!
  875. ************************************************************************
  876. * brief
  877. *    Copy image data from one array to another array
  878. ************************************************************************
  879. */
  880. static void CopyImgData(imgpel **inputY, imgpel ***inputUV, imgpel **outputY, imgpel ***outputUV, 
  881.                         int img_width, int img_height, int img_width_cr, int img_height_cr)
  882. {
  883.   int x, y;
  884.   for (y=0; y<img_height; y++)
  885.     for (x=0; x<img_width; x++)
  886.       outputY[y][x] = inputY[y][x];
  887.   for (y=0; y<img_height_cr; y++)
  888.     for (x=0; x<img_width_cr; x++)
  889.     {
  890.       outputUV[0][y][x] = inputUV[0][y][x];
  891.       outputUV[1][y][x] = inputUV[1][y][x];
  892.     }
  893. }
  894. /*!
  895. ************************************************************************
  896. * brief
  897. *    Copies the last reference frame for concealing reference frame loss.
  898. ************************************************************************
  899. */
  900. static StorablePicture* get_last_ref_pic_from_dpb()
  901. {
  902.   int used_size = dpb.used_size - 1;
  903.   int i;
  904.   for(i = used_size; i >= 0; i--)
  905.   {
  906.     if (dpb.fs[i]->is_used==3)
  907.     {
  908.       if (((dpb.fs[i]->frame->used_for_reference) &&
  909.         (!dpb.fs[i]->frame->is_long_term)) /*||  ((dpb.fs[i]->frame->used_for_reference==0)
  910.                                            && (dpb.fs[i]->frame->slice_type == P_SLICE))*/ )
  911.       {
  912.         return dpb.fs[i]->frame;
  913.       }
  914.     }
  915.   }
  916.   return NULL;
  917. }
  918. /*!
  919. ************************************************************************
  920. * brief
  921. * Conceals the lost reference or non reference frame by either frame copy
  922. * or motion vector copy concealment.
  923. *
  924. ************************************************************************
  925. */
  926. static void copy_to_conceal(StorablePicture *src, StorablePicture *dst, ImageParameters *img)
  927. {
  928.   int i=0;
  929.   int mv[3];
  930.   int multiplier;
  931.   imgpel *predMB, *storeYUV;
  932.   int j, y, x, mb_height, mb_width, ii=0, jj=0;
  933.   int uv;
  934.   int mm, nn;
  935.   int scale = 1;
  936.   // struct inp_par *test;
  937.   img->current_mb_nr = 0;
  938.   dst->PicSizeInMbs  = src->PicSizeInMbs;
  939.   dst->slice_type = src->slice_type = img->conceal_slice_type;
  940.   dst->idr_flag = FALSE; //since we do not want to clears the ref list
  941.   dst->no_output_of_prior_pics_flag = src->no_output_of_prior_pics_flag;
  942.   dst->long_term_reference_flag = src->long_term_reference_flag;
  943.   dst->adaptive_ref_pic_buffering_flag = src->adaptive_ref_pic_buffering_flag = 0;
  944.   dst->chroma_format_idc = src->chroma_format_idc;
  945.   dst->frame_mbs_only_flag = src->frame_mbs_only_flag;
  946.   dst->frame_cropping_flag = src->frame_cropping_flag;
  947.   dst->frame_cropping_rect_left_offset = src->frame_cropping_rect_left_offset;
  948.   dst->frame_cropping_rect_right_offset = src->frame_cropping_rect_right_offset;
  949.   dst->frame_cropping_rect_bottom_offset = src->frame_cropping_rect_bottom_offset;
  950.   dst->frame_cropping_rect_top_offset = src->frame_cropping_rect_top_offset;
  951.   dst->qp = src->qp;
  952.   dst->slice_qp_delta = src->slice_qp_delta;
  953.   dec_picture = src;
  954.   // Conceals the missing frame by frame copy concealment
  955.   if (img->conceal_mode==1)
  956.   {
  957.     // We need these initializations for using deblocking filter for frame copy
  958.     // concealment as well.
  959.     dst->PicWidthInMbs = src->PicWidthInMbs;
  960.     dst->PicSizeInMbs = src->PicSizeInMbs;
  961.     CopyImgData( src->imgY, src->imgUV, dst->imgY, dst->imgUV, img->width, img->height, img->width_cr, img->height_cr);
  962.   }
  963.   // Conceals the missing frame by motion vector copy concealment
  964.   if (img->conceal_mode==2)
  965.   {
  966.     if (dec_picture->chroma_format_idc != YUV400)
  967.     {
  968.       storeYUV = (imgpel *) malloc ( (16 + (img->mb_cr_size_x*img->mb_cr_size_y)*2/16) * sizeof (imgpel));
  969.     }
  970.     else
  971.     {
  972.       storeYUV = (imgpel *) malloc (16  * sizeof (imgpel));
  973.     }
  974.     erc_img = img;
  975.     dst->PicWidthInMbs = src->PicWidthInMbs;
  976.     dst->PicSizeInMbs = src->PicSizeInMbs;
  977.     mb_width = dst->PicWidthInMbs;
  978.     mb_height = (dst->PicSizeInMbs)/(dst->PicWidthInMbs);
  979.     scale = (img->conceal_slice_type == B_SLICE) ? 2 : 1;
  980.     if(img->conceal_slice_type == B_SLICE)
  981.       init_lists_for_non_reference_loss(dst->slice_type, img->currentSlice->structure);
  982.     else
  983.       init_lists(dst->slice_type, img->currentSlice->structure);
  984.     multiplier = BLOCK_SIZE;
  985.     for(i=0;i<mb_height*4;i++)
  986.     {
  987.       mm = i * BLOCK_SIZE;
  988.       for(j=0;j<mb_width*4;j++)
  989.       {
  990.         nn = j * BLOCK_SIZE;
  991.         mv[0] = src->motion.mv[LIST_0][i][j][0] / scale;
  992.         mv[1] = src->motion.mv[LIST_0][i][j][1] / scale;
  993.         mv[2] = src->motion.ref_idx[LIST_0][i][j];
  994.         if(mv[2]<0)
  995.           mv[2]=0;
  996.         dst->motion.mv[LIST_0][i][j][0] = mv[0];
  997.         dst->motion.mv[LIST_0][i][j][1] = mv[1];
  998.         dst->motion.ref_idx[LIST_0][i][j] = mv[2];
  999.         x = (j) * multiplier;
  1000.         y = (i) * multiplier;
  1001.         if ((mm%16==0) && (nn%16==0))
  1002.           img->current_mb_nr++;
  1003.         buildPredblockRegionYUV(erc_img, mv, x, y, storeYUV, LIST_0);
  1004.         predMB = storeYUV;
  1005.         for(ii=0;ii<multiplier;ii++)
  1006.         {
  1007.           for(jj=0;jj<multiplier;jj++)
  1008.           {
  1009.             dst->imgY[i*multiplier+ii][j*multiplier+jj] = predMB[ii*(multiplier)+jj];
  1010.           }
  1011.         }
  1012.         predMB = predMB + (multiplier*multiplier);
  1013.         if (dec_picture->chroma_format_idc != YUV400)
  1014.         {
  1015.           for(uv=0;uv<2;uv++)
  1016.           {
  1017.             for(ii=0;ii< (multiplier/2);ii++)
  1018.             {
  1019.               for(jj=0;jj< (multiplier/2);jj++)
  1020.               {
  1021.                 dst->imgUV[uv][i*multiplier/2 +ii][j*multiplier/2 +jj] = predMB[ii*(multiplier/2)+jj];
  1022.               }
  1023.             }
  1024.             predMB = predMB + (multiplier*multiplier/4);
  1025.           }
  1026.         }
  1027.       }
  1028.     }
  1029.     free(storeYUV);
  1030.   }
  1031. }
  1032. /*!
  1033. ************************************************************************
  1034. * brief
  1035. * Uses the previous reference pic for concealment of reference frames
  1036. *
  1037. ************************************************************************
  1038. */
  1039. static void
  1040. copy_prev_pic_to_concealed_pic(StorablePicture *picture, ImageParameters *img)
  1041. {
  1042.   StorablePicture *ref_pic;
  1043.   /* get the last ref pic in dpb */
  1044.   ref_pic = get_last_ref_pic_from_dpb();
  1045.   assert(ref_pic != NULL);
  1046.   /* copy all the struc from this to current concealment pic */
  1047.   img->conceal_slice_type = P_SLICE;
  1048.   copy_to_conceal(ref_pic, picture, img);
  1049. }
  1050. /*!
  1051. ************************************************************************
  1052. * brief
  1053. * This function conceals a missing reference frame. The routine is called
  1054. * based on the difference in frame number. It conceals an IDR frame loss
  1055. * based on the sudden decrease in frame number.
  1056. *
  1057. ************************************************************************
  1058. */
  1059. void conceal_lost_frames(ImageParameters *img)
  1060. {
  1061.   int CurrFrameNum;
  1062.   int UnusedShortTermFrameNum;
  1063.   StorablePicture *picture = NULL;
  1064.   int tmp1 = img->delta_pic_order_cnt[0];
  1065.   int tmp2 = img->delta_pic_order_cnt[1];
  1066.   int i;
  1067.   img->delta_pic_order_cnt[0] = img->delta_pic_order_cnt[1] = 0;
  1068.   // printf("A gap in frame number is found, try to fill it.n");
  1069.   if(img->IDR_concealment_flag == 1)
  1070.   {
  1071.     // Conceals an IDR frame loss. Uses the reference frame in the previous
  1072.     // GOP for concealment.
  1073.     UnusedShortTermFrameNum = 0;
  1074.     img->last_ref_pic_poc = -img->poc_gap;
  1075.     img->earlier_missing_poc = 0;
  1076.   }
  1077.   else
  1078.     UnusedShortTermFrameNum = (img->pre_frame_num + 1) % img->MaxFrameNum;
  1079.   CurrFrameNum = img->frame_num;
  1080.   while (CurrFrameNum != UnusedShortTermFrameNum)
  1081.   {
  1082.     picture = alloc_storable_picture (FRAME, img->width, img->height, img->width_cr, img->height_cr);
  1083.     picture->coded_frame = 1;
  1084.     picture->pic_num = UnusedShortTermFrameNum;
  1085.     picture->frame_num = UnusedShortTermFrameNum;
  1086.     picture->non_existing = 0;
  1087.     picture->is_output = 0;
  1088.     picture->used_for_reference = 1;
  1089.     picture->concealed_pic = 1;
  1090.     picture->adaptive_ref_pic_buffering_flag = 0;
  1091.     img->frame_num = UnusedShortTermFrameNum;
  1092.     picture->top_poc=img->last_ref_pic_poc + img->ref_poc_gap;
  1093.     picture->bottom_poc=picture->top_poc;
  1094.     picture->frame_poc=picture->top_poc;
  1095.     picture->poc=picture->top_poc;
  1096.     img->last_ref_pic_poc = picture->poc;
  1097.     copy_prev_pic_to_concealed_pic(picture, img);
  1098.     //if (UnusedShortTermFrameNum == 0)
  1099.     if(img->IDR_concealment_flag == 1)
  1100.     {
  1101.       picture->slice_type = I_SLICE;
  1102.       picture->idr_flag = TRUE;
  1103.       flush_dpb();
  1104.       picture->top_poc= 0;
  1105.       picture->bottom_poc=picture->top_poc;
  1106.       picture->frame_poc=picture->top_poc;
  1107.       picture->poc=picture->top_poc;
  1108.       img->last_ref_pic_poc = picture->poc;
  1109.     }
  1110.     store_picture_in_dpb(picture);
  1111.     picture=NULL;
  1112.     img->pre_frame_num = UnusedShortTermFrameNum;
  1113.     UnusedShortTermFrameNum = (UnusedShortTermFrameNum + 1) % img->MaxFrameNum;
  1114.     // update reference flags and set current flag.
  1115.     for(i=16;i>0;i--)
  1116.     {
  1117.       ref_flag[i] = ref_flag[i-1];
  1118.     }
  1119.     ref_flag[0] = 0;
  1120.   }
  1121.   img->delta_pic_order_cnt[0] = tmp1;
  1122.   img->delta_pic_order_cnt[1] = tmp2;
  1123.   img->frame_num = CurrFrameNum;
  1124. }
  1125. /*!
  1126. ************************************************************************
  1127. * brief
  1128. * Updates the reference list for motion vector copy concealment for non-
  1129. * reference frame loss.
  1130. *
  1131. ************************************************************************
  1132. */
  1133. void update_ref_list_for_concealment()
  1134. {
  1135.   unsigned i, j;
  1136.   for (i=0, j=0; i<dpb.used_size; i++)
  1137.   {
  1138.     if (dpb.fs[i]->concealment_reference)
  1139.     {
  1140.       dpb.fs_ref[j++]=dpb.fs[i];
  1141.     }
  1142.   }
  1143.   dpb.ref_frames_in_buffer = active_pps->num_ref_idx_l0_active_minus1;
  1144. }
  1145. /*!
  1146. ************************************************************************
  1147. * brief
  1148. *    Initialize the list based on the B frame or non reference 'p' frame
  1149. *    to be concealed. The function initialize listX[0] and list 1 depending
  1150. *    on current picture type
  1151. *
  1152. ************************************************************************
  1153. */
  1154. void init_lists_for_non_reference_loss(int currSliceType, PictureStructure currPicStructure)
  1155. {
  1156.   unsigned i;
  1157.   int j;
  1158.   int MaxFrameNum = 1 << (active_sps->log2_max_frame_num_minus4 + 4);
  1159.   int diff;
  1160.   int list0idx = 0;
  1161.   int list0idx_1 = 0;
  1162.   StorablePicture *tmp_s;
  1163.   if (currPicStructure == FRAME)
  1164.   {
  1165.     for(i=0;i<dpb.ref_frames_in_buffer; i++)
  1166.     {
  1167.       if(dpb.fs[i]->concealment_reference == 1)
  1168.       {
  1169.         if(dpb.fs[i]->frame_num > img->frame_to_conceal)
  1170.           dpb.fs_ref[i]->frame_num_wrap = dpb.fs[i]->frame_num - MaxFrameNum;
  1171.         else
  1172.           dpb.fs_ref[i]->frame_num_wrap = dpb.fs[i]->frame_num;
  1173.         dpb.fs_ref[i]->frame->pic_num = dpb.fs_ref[i]->frame_num_wrap;
  1174.       }
  1175.     }
  1176.   }
  1177.   if (currSliceType == P_SLICE)
  1178.   {
  1179.     // Calculate FrameNumWrap and PicNum
  1180.     if (currPicStructure == FRAME)
  1181.     {
  1182.       for(i=0;i<dpb.used_size; i++)
  1183.       {
  1184.         if(dpb.fs[i]->concealment_reference == 1)
  1185.         {
  1186.           listX[0][list0idx++] = dpb.fs[i]->frame;
  1187.         }
  1188.       }
  1189.       // order list 0 by PicNum
  1190.       qsort((void *)listX[0], list0idx, sizeof(StorablePicture*), compare_pic_by_pic_num_desc);
  1191.       listXsize[0] = list0idx;
  1192.     }
  1193.   }
  1194.   if (currSliceType == B_SLICE)
  1195.   {
  1196.     if (currPicStructure == FRAME)
  1197.     {
  1198.       //      for(i=0;i<dpb.ref_frames_in_buffer; i++)
  1199.       for(i=0;i<dpb.used_size; i++)
  1200.       {
  1201.         if(dpb.fs[i]->concealment_reference == 1)
  1202.         {
  1203.           if(img->earlier_missing_poc > dpb.fs[i]->frame->poc)
  1204.             listX[0][list0idx++] = dpb.fs[i]->frame;
  1205.         }
  1206.       }
  1207.       qsort((void *)listX[0], list0idx, sizeof(StorablePicture*), compare_pic_by_poc_desc);
  1208.       list0idx_1 = list0idx;
  1209.       //      for(i=0;i<dpb.ref_frames_in_buffer; i++)
  1210.       for(i=0;i<dpb.used_size; i++)
  1211.       {
  1212.         if(dpb.fs[i]->concealment_reference == 1)
  1213.         {
  1214.           if(img->earlier_missing_poc < dpb.fs[i]->frame->poc)
  1215.             listX[0][list0idx++] = dpb.fs[i]->frame;
  1216.         }
  1217.       }
  1218.       qsort((void *)&listX[0][list0idx_1], list0idx-list0idx_1, sizeof(StorablePicture*), compare_pic_by_poc_asc);
  1219.       for (j=0; j<list0idx_1; j++)
  1220.       {
  1221.         listX[1][list0idx-list0idx_1+j]=listX[0][j];
  1222.       }
  1223.       for (j=list0idx_1; j<list0idx; j++)
  1224.       {
  1225.         listX[1][j-list0idx_1]=listX[0][j];
  1226.       }
  1227.       listXsize[0] = listXsize[1] = list0idx;
  1228.       qsort((void *)&listX[0][listXsize[0]], list0idx-listXsize[0], sizeof(StorablePicture*), compare_pic_by_lt_pic_num_asc);
  1229.       qsort((void *)&listX[1][listXsize[0]], list0idx-listXsize[0], sizeof(StorablePicture*), compare_pic_by_lt_pic_num_asc);
  1230.       listXsize[0] = listXsize[1] = list0idx;
  1231.     }
  1232.   }
  1233.   if ((listXsize[0] == listXsize[1]) && (listXsize[0] > 1))
  1234.   {
  1235.     // check if lists are identical, if yes swap first two elements of listX[1]
  1236.     diff=0;
  1237.     for (j = 0; j< listXsize[0]; j++)
  1238.     {
  1239.       if (listX[0][j]!=listX[1][j])
  1240.         diff=1;
  1241.     }
  1242.     if (!diff)
  1243.     {
  1244.       tmp_s = listX[1][0];
  1245.       listX[1][0]=listX[1][1];
  1246.       listX[1][1]=tmp_s;
  1247.     }
  1248.   }
  1249.   // set max size
  1250.   listXsize[0] = imin (listXsize[0], (int)active_sps->num_ref_frames);
  1251.   listXsize[1] = imin (listXsize[1], (int)active_sps->num_ref_frames);
  1252.   listXsize[1] = 0;
  1253.   // set the unused list entries to NULL
  1254.   for (i=listXsize[0]; i< (MAX_LIST_SIZE) ; i++)
  1255.   {
  1256.     listX[0][i] = NULL;
  1257.   }
  1258.   for (i=listXsize[1]; i< (MAX_LIST_SIZE) ; i++)
  1259.   {
  1260.     listX[1][i] = NULL;
  1261.   }
  1262. }
  1263. /*!
  1264. ************************************************************************
  1265. * brief
  1266. * Get from the dpb the picture corresponding to a POC.  The POC varies
  1267. * depending on whether it is a frame copy or motion vector copy concealment.
  1268. * The frame corresponding to the POC is returned.
  1269. *
  1270. ************************************************************************
  1271. */
  1272. StorablePicture *get_pic_from_dpb(int missingpoc, unsigned int *pos)
  1273. {
  1274.   int used_size = dpb.used_size - 1;
  1275.   int i, concealfrom = 0;
  1276.   if(img->conceal_mode == 1)
  1277.     concealfrom = missingpoc - img->poc_gap;
  1278.   else if (img->conceal_mode == 2)
  1279.     concealfrom = missingpoc + img->poc_gap;
  1280.   for(i = used_size; i >= 0; i--)
  1281.   {
  1282.     if(dpb.fs[i]->poc == concealfrom)
  1283.     {
  1284.       *pos = i;
  1285.       return dpb.fs[i]->frame;
  1286.     }
  1287.   }
  1288.   return NULL;
  1289. }
  1290. /*!
  1291. ************************************************************************
  1292. * brief
  1293. * Function to sort the POC and find the lowest number in the POC list
  1294. * Compare the integers
  1295. *
  1296. ************************************************************************
  1297. */
  1298. int comp(const void *i, const void *j)
  1299. {
  1300.   return *(int *)i - *(int *)j;
  1301. }
  1302. /*!
  1303. ************************************************************************
  1304. * brief
  1305. * Initialises a node, allocates memory for the node, and returns
  1306. * a pointer to the new node.
  1307. *
  1308. ************************************************************************
  1309. */
  1310. struct concealment_node * init_node( StorablePicture* picture, int missingpoc )
  1311. {
  1312.   struct concealment_node *ptr;
  1313.   ptr = (struct concealment_node *) calloc( 1, sizeof(struct concealment_node ) );
  1314.   if( ptr == NULL )
  1315.     return (struct concealment_node *) NULL;
  1316.   else {
  1317.     ptr->picture = picture;
  1318.     ptr->missingpocs = missingpoc;
  1319.     ptr->next = NULL;
  1320.     return ptr;
  1321.   }
  1322. }
  1323. /*!
  1324. ************************************************************************
  1325. * brief
  1326. * Prints the details of a node
  1327. *
  1328. ************************************************************************
  1329. */
  1330. void print_node( struct concealment_node *ptr )
  1331. {
  1332.   printf("Missing POC=%dn", ptr->missingpocs );
  1333. }
  1334. /*!
  1335. ************************************************************************
  1336. * brief
  1337. * Prints all nodes from the current address passed to it.
  1338. *
  1339. ************************************************************************
  1340. */
  1341. void print_list( struct concealment_node *ptr )
  1342. {
  1343.   while( ptr != NULL )
  1344.   {
  1345.     print_node( ptr );
  1346.     ptr = ptr->next;
  1347.   }
  1348. }
  1349. /*!
  1350. ************************************************************************
  1351. * brief
  1352. * Adds a node to the end of the list.
  1353. *
  1354. ************************************************************************
  1355. */
  1356. void add_node( struct concealment_node *concealment_new )
  1357. {
  1358.   if( concealment_head == NULL )
  1359.   {
  1360.     concealment_end = concealment_head = concealment_new;
  1361.     return;
  1362.   }
  1363.   concealment_end->next = concealment_new;
  1364.   concealment_end = concealment_new;
  1365. }
  1366. /*!
  1367. ************************************************************************
  1368. * brief
  1369. * Deletes the specified node pointed to by 'ptr' from the list
  1370. *
  1371. ************************************************************************
  1372. */
  1373. void delete_node( struct concealment_node *ptr )
  1374. {
  1375.   // We only need to delete the first node in the linked list
  1376.   if( ptr == concealment_head ) 
  1377.   {
  1378.     concealment_head = concealment_head->next;
  1379.     if( concealment_end == ptr )
  1380.       concealment_end = concealment_end->next;
  1381.     free(ptr);
  1382.   }
  1383. }
  1384. /*!
  1385. ************************************************************************
  1386. * brief
  1387. * Deletes all nodes from the place specified by ptr
  1388. *
  1389. ************************************************************************
  1390. */
  1391. void delete_list( struct concealment_node *ptr )
  1392. {
  1393.   struct concealment_node *temp;
  1394.   if( concealment_head == NULL ) return;
  1395.   if( ptr == concealment_head ) 
  1396.   {
  1397.     concealment_head = NULL;
  1398.     concealment_end = NULL;
  1399.   }
  1400.   else
  1401.   {
  1402.     temp = concealment_head;
  1403.     while( temp->next != ptr )
  1404.       temp = temp->next;
  1405.     concealment_end = temp;
  1406.   }
  1407.   while( ptr != NULL ) 
  1408.   {
  1409.     temp = ptr->next;
  1410.     free( ptr );
  1411.     ptr = temp;
  1412.   }
  1413. }
  1414. /*!
  1415. ************************************************************************
  1416. * brief
  1417. * Stores the missing non reference frames in the concealment buffer. The
  1418. * detection is based on the POC difference in the sorted POC array. A missing
  1419. * non reference frame is detected when the dpb is full. A singly linked list
  1420. * is maintained for storing the missing non reference frames.
  1421. *
  1422. ************************************************************************
  1423. */
  1424. void conceal_non_ref_pics(int diff)
  1425. {
  1426.   int missingpoc = 0;
  1427.   unsigned int i, pos = 0;
  1428.   StorablePicture *conceal_from_picture = NULL;
  1429.   StorablePicture *conceal_to_picture = NULL;
  1430.   struct concealment_node *concealment_ptr = NULL;
  1431.   int temp_used_size = dpb.used_size;
  1432.   if(dpb.used_size == 0 )
  1433.     return;
  1434.   qsort(pocs_in_dpb, dpb.size, sizeof(int), comp);
  1435.   for(i=0;i<dpb.size-diff;i++)
  1436.   {
  1437.     dpb.used_size = dpb.size;
  1438.     if((pocs_in_dpb[i+1]-pocs_in_dpb[i])>img->poc_gap)
  1439.     {
  1440.       conceal_to_picture = alloc_storable_picture (FRAME, img->width, img->height, img->width_cr, img->height_cr);
  1441.       missingpoc = pocs_in_dpb[i] + img->poc_gap;
  1442.       // Diagnostics
  1443.       // printf("n missingpoc = %dn",missingpoc);
  1444.       if(missingpoc > img->earlier_missing_poc)
  1445.       {
  1446.         img->earlier_missing_poc = missingpoc;
  1447.         conceal_to_picture->top_poc= missingpoc;
  1448.         conceal_to_picture->bottom_poc=missingpoc;
  1449.         conceal_to_picture->frame_poc=missingpoc;
  1450.         conceal_to_picture->poc=missingpoc;
  1451.         conceal_from_picture = get_pic_from_dpb(missingpoc, &pos);
  1452.         assert(conceal_from_picture != NULL);
  1453.         dpb.used_size = pos+1;
  1454.         img->frame_to_conceal = conceal_from_picture->frame_num + 1;
  1455.         update_ref_list_for_concealment();
  1456.         img->conceal_slice_type = B_SLICE;
  1457.         copy_to_conceal(conceal_from_picture, conceal_to_picture, img);
  1458.         concealment_ptr = init_node( conceal_to_picture, missingpoc );
  1459.         add_node(concealment_ptr);
  1460.         // Diagnostics
  1461.         // print_node(concealment_ptr);
  1462.       }
  1463.     }
  1464.   }
  1465.   //restore the original value
  1466.   //dpb.used_size = dpb.size;
  1467.   dpb.used_size = temp_used_size;
  1468. }
  1469. /*!
  1470. ************************************************************************
  1471. * brief
  1472. * Perform Sliding window decoded reference picture marking process. It
  1473. * maintains the POC s stored in the dpb at a specific instance.
  1474. *
  1475. ************************************************************************
  1476. */
  1477. void sliding_window_poc_management(StorablePicture *p)
  1478. {
  1479.   unsigned int i;
  1480.   if (dpb.used_size == dpb.size)
  1481.   {
  1482.     for(i=0;i<dpb.size-1; i++)
  1483.       pocs_in_dpb[i] = pocs_in_dpb[i+1];
  1484.   }
  1485.   //    pocs_in_dpb[dpb.used_size-1] = p->poc;
  1486. }
  1487. /*!
  1488. ************************************************************************
  1489. * brief
  1490. * Outputs the non reference frames. The POCs in the concealment buffer are
  1491. * sorted in ascending order and outputted when the lowest POC in the
  1492. * concealment buffer is lower than the lowest in the dpb. The linked list
  1493. * entry corresponding to the outputted POC is immediately deleted.
  1494. *
  1495. ************************************************************************
  1496. */
  1497. void write_lost_non_ref_pic(int poc, int p_out)
  1498. {
  1499.   FrameStore concealment_fs;
  1500.   if(poc > 0)
  1501.   {
  1502.     if((poc - dpb.last_output_poc) > img->poc_gap)
  1503.     {
  1504.       concealment_fs.frame = concealment_head->picture;
  1505.       concealment_fs.is_output = 0;
  1506.       concealment_fs.is_reference = 0;
  1507.       concealment_fs.is_used = 3;
  1508.       write_stored_frame(&concealment_fs, p_out);
  1509.       delete_node(concealment_head);
  1510.     }
  1511.   }
  1512. }
  1513. /*!
  1514. ************************************************************************
  1515. * brief
  1516. * Conceals frame loss immediately after the IDR. This special case produces
  1517. * the same result for either frame copy or motion vector copy concealment.
  1518. *
  1519. ************************************************************************
  1520. */
  1521. void write_lost_ref_after_idr(int pos)
  1522. {
  1523.   int temp = 1;
  1524.   if(last_out_fs->frame == NULL)
  1525.   {
  1526.     last_out_fs->frame = alloc_storable_picture (FRAME, img->width, img->height,
  1527.       img->width_cr, img->height_cr);
  1528.     last_out_fs->is_used = 3;
  1529.   }
  1530.   if(img->conceal_mode == 2)
  1531.   {
  1532.     temp = 2;
  1533.     img->conceal_mode = 1;
  1534.   }
  1535.   copy_to_conceal(dpb.fs[pos]->frame, last_out_fs->frame, img);
  1536.   img->conceal_mode = temp;
  1537. }