⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 errorconcealment.c

📁 Nokia H.264/AVC Encoder/Decoder Usage Manual
💻 C
📖 第 1 页 / 共 3 页
字号:
    }  }  if (found == -1)     pEc->dirUp = 0;  return found;}/* * * selectOneMB: * * Parameters: *      pEc                   EC object   * * Function: *      Select the MB to be concealed, which has the highest rank. * * Returns: *      The index of the selected MB *      -1, if no MB is selected */static int selectOneMB(errorConcealment_s* pEc, int *isUpOrDown){  int found = -1;  if (pEc->dir == 0) { // going downwards    found = selectDownwards(pEc);    *isUpOrDown = 0;    if (found == -1) {      found = selectUpwards(pEc);      *isUpOrDown = 1;    }    if (pEc->dirUp) // change the dir      pEc->dir = 1;  }  else if (pEc->dir == 1) {               // going upwards    found = selectUpwards(pEc);    *isUpOrDown = 1;    if (found == -1) {      found = selectDownwards(pEc);      *isUpOrDown = 0;    }    if (pEc->dirDown)      pEc->dir = 0;  }  return found;}/* * * blkIntraConceal: * * Parameters: *      pEc                   EC object *      predY                 Return pointer for predicted luma pixels *      predC                 Return pointer for predicted chroma pixels *      currPic               The picture to be concealed *      idxX                  The position of the MB to be intra concealed *      idxY                  The position of the MB to be intra concealed * * Function: *      Do Intra concealment for an MB. * * Returns: *      - */static void blkIntraConceal(errorConcealment_s *pEc, u_int8 predY[MBK_SIZE][MBK_SIZE],                            u_int8 predC[MBK_SIZE/2][MBK_SIZE],                            frmBuf_s *currPic, int idxX, int idxY){  int pxlX, pxlY, x, y, weight, i, comp;  int picWidth = pEc->widthMbs * MBK_SIZE;  int picWidthC = picWidth >> 1;  u_int32 tmp;  int neighbourExist = 0;  u_int8 *pred, *currY, *currU, *currV, *currC, *src1, *src2;  u_int8 srcTop[MBK_SIZE];  u_int8 srcBottom[MBK_SIZE];  u_int8 srcLeft[MBK_SIZE];  u_int8 srcRight[MBK_SIZE];  int tmpPix, step;  int gradX, gradY;  static const int8 weightTab[16] =  {0, 0, 0, 0, 0, 16, 31, 16, 0, 1, 16, 1, 0, 16, 31, 16};  static const int8 gradXtab[16] =  {0, 0, 0, 0, 0, -1, -1, -1, 0, 1,  1, 1, 0,  0,  0,  0};  static const int8 gradYtab[16] =  {0, 0, 0, 0, 0,  1, -1,  0, 0, 1, -1, 0, 0,  1, -1,  0};  pxlX = idxX * MBK_SIZE;  pxlY = idxY * MBK_SIZE;  currY = currPic->y + pxlY * picWidth + pxlX;  currU = currPic->u + (pxlY>>1) * picWidthC + (pxlX>>1);  currV = currPic->v + (pxlY>>1) * picWidthC + (pxlX>>1);  // check if correctly received neighbours exist  // when the top mb is available  if ( idxY > 0 && pEc->decodedMbs[idxY-1][idxX] == 1 )    neighbourExist |= MASK_TOP;  // when the bottom mb is available  if ( idxY < (pEc->heightMbs-1) && pEc->decodedMbs[idxY+1][idxX] == 1 )    neighbourExist |= MASK_BOTTOM;  // when the left mb is available  if ( idxX > 0 && pEc->decodedMbs[idxY][idxX-1] == 1 )    neighbourExist |= MASK_LEFT;  // when the right mb is available  if ( idxX < (pEc->widthMbs-1) && pEc->decodedMbs[idxY][idxX+1] == 1 )    neighbourExist |= MASK_RIGHT;  if (neighbourExist == 0) {    // Correctly received neighbours does no exist, check if concealed neighbours exist    // when the top mb is available    if ( idxY > 0 && pEc->decodedMbs[idxY-1][idxX] == 2 )      neighbourExist |= MASK_TOP;    // when the bottom mb is available    if ( idxY < (pEc->heightMbs-1) && pEc->decodedMbs[idxY+1][idxX] == 2 )      neighbourExist |= MASK_BOTTOM;    // when the left mb is available    if ( idxX > 0 && pEc->decodedMbs[idxY][idxX-1] == 2 )      neighbourExist |= MASK_LEFT;    // when the right mb is available    if ( idxX < (pEc->widthMbs-1) && pEc->decodedMbs[idxY][idxX+1] == 2 )      neighbourExist |= MASK_RIGHT;  }  if (neighbourExist & MASK_TOP) {    for (i = 0; i < MBK_SIZE; i++)      srcTop[i] = currY[-picWidth + i];  }  if (neighbourExist & MASK_BOTTOM) {    for (i = 0; i < MBK_SIZE; i++)      srcBottom[i] = currY[MBK_SIZE*picWidth + i];  }  if (neighbourExist & MASK_LEFT) {    for (i = 0; i < MBK_SIZE; i++)      srcLeft[i] = currY[i*picWidth-1];  }  if (neighbourExist & MASK_RIGHT) {    for (i = 0; i < MBK_SIZE; i++)      srcRight[i] = currY[i*picWidth + MBK_SIZE];  }  if (neighbourExist & (MASK_TOP|MASK_BOTTOM)) {    /*     * Top and/or bottom macroblocks is available. Perform vertical linear     * interpolation.     */    if (neighbourExist & MASK_TOP) {      src1 = srcTop;      src2 = (neighbourExist & MASK_BOTTOM) ? srcBottom : srcTop;    }    else      src1 = src2 = srcBottom;    pred = &predY[0][0];    for (x = 0; x < MBK_SIZE; x++) {      tmpPix = src1[x] * 16;      step = src2[x] - src1[x];      for (y = 0; y < MBK_SIZE; y++) {        *pred = (u_int8)((tmpPix + 8) >> 4);        pred += MBK_SIZE;        tmpPix += step;      }      pred = pred - MBK_SIZE*MBK_SIZE + 1;    }    if (neighbourExist & (MASK_LEFT|MASK_RIGHT)) {      /*       * Left and/or right macroblocks is available. Perform horizontal linear       * interpolation and combine results with vertical interpolation results.       */      if (neighbourExist & MASK_LEFT) {        src1 = srcLeft;        src2 = (neighbourExist & MASK_RIGHT) ? srcRight : srcLeft;      }      else        src1 = src2 = srcRight;      weight = weightTab[neighbourExist]; // weight at top left corner      gradX  = gradXtab[neighbourExist];  // change in weight in horizontal direction      gradY  = gradYtab[neighbourExist];  // change in weight in vertical direction      pred = &predY[0][0];      for (y = 0; y < MBK_SIZE; y++) {        tmpPix = src1[y] * 16;        step = src2[y] - src1[y];        for (x = 0; x < MBK_SIZE; x++) {          tmp = (u_int32)weight*tmpPix + (u_int32)(32-weight)*16*(*pred);          *pred++ = (u_int8)((tmp + 256) >> 9);          tmpPix += step;          weight += gradX;        }        weight = weight - MBK_SIZE*gradX + gradY;      }    }  }  else {    /*     * Left and/or right macroblocks is available. Perform horizontal linear     * interpolation. Top and bottom macroblocks are not available.     */    if (neighbourExist & MASK_LEFT) {      src1 = srcLeft;      src2 = (neighbourExist & MASK_RIGHT) ? srcRight : srcLeft;    }    else      src1 = src2 = srcRight;    /* Horizontal linear interpolation */    pred = &predY[0][0];    for (y = 0; y < MBK_SIZE; y++) {      tmpPix = src1[y] * 16;      step = src2[y] - src1[y];      for (x = 0; x < MBK_SIZE; x++) {        *pred++ = (u_int8)((tmpPix + 8) >> 4);        tmpPix += step;      }    }  }  currC = currU;  for (comp = 0; comp < 2; comp++) {    if (neighbourExist & 0x1) {      for (i = 0; i < MBK_SIZE/2; i++)        srcTop[i] = currC[-picWidthC + i];    }    if (neighbourExist & 0x2) {      for (i = 0; i < MBK_SIZE/2; i++)        srcBottom[i] = currC[(MBK_SIZE/2)*picWidthC + i];    }    if (neighbourExist & 0x4) {      for (i = 0; i < MBK_SIZE/2; i++)        srcLeft[i] = currC[i*picWidthC-1];    }    if (neighbourExist & 0x8) {      for (i = 0; i < MBK_SIZE/2; i++)        srcRight[i] = currC[i*picWidthC + MBK_SIZE/2];    }    if (neighbourExist & (MASK_TOP|MASK_BOTTOM)) {      /*      * Top and/or bottom macroblocks is available. Perform vertical linear      * interpolation.      */      if (neighbourExist & MASK_TOP) {        src1 = srcTop;        src2 = (neighbourExist & MASK_BOTTOM) ? srcBottom : srcTop;      }      else        src1 = src2 = srcBottom;      pred = &predC[0][comp*(MBK_SIZE/2)];      for (x = 0; x < MBK_SIZE/2; x++) {        tmpPix = src1[x] * 8;        step = src2[x] - src1[x];        for (y = 0; y < MBK_SIZE/2; y++) {          *pred = (u_int8)((tmpPix + 4) >> 3);          pred += MBK_SIZE;          tmpPix += step;        }        pred = pred - (MBK_SIZE/2)*MBK_SIZE + 1;      }      if (neighbourExist & (MASK_LEFT|MASK_RIGHT)) {        /*        * Left and/or right macroblocks is available. Perform horizontal linear        * interpolation and combine results with vertical interpolation results.        */        if (neighbourExist & MASK_LEFT) {          src1 = srcLeft;          src2 = (neighbourExist & MASK_RIGHT) ? srcRight : srcLeft;        }        else          src1 = src2 = srcRight;        weight = weightTab[neighbourExist];  // weight at top left corner        gradX  = 2*gradXtab[neighbourExist]; // change in weight in horizontal direction        gradY  = 2*gradYtab[neighbourExist]; // change in weight in vertical direction        pred = &predC[0][comp*(MBK_SIZE/2)];        for (y = 0; y < MBK_SIZE/2; y++) {          tmpPix = src1[y] * 8;          step = src2[y] - src1[y];          for (x = 0; x < MBK_SIZE/2; x++) {            tmp = (u_int32)weight*tmpPix + (u_int32)(32-weight)*8*(*pred);            *pred++ = (u_int8)((tmp + 128) >> 8);            tmpPix += step;            weight += gradX;          }          pred += MBK_SIZE/2;          weight = weight - (MBK_SIZE/2)*gradX + gradY;        }      }    }    else {      /*      * Left and/or right macroblocks is available. Perform horizontal linear      * interpolation. Top and bottom macroblocks are not available.      */      if (neighbourExist & MASK_LEFT) {        src1 = srcLeft;        src2 = (neighbourExist & MASK_RIGHT) ? srcRight : srcLeft;      }      else        src1 = src2 = srcRight;      /* Horizontal linear interpolation */      pred = &predC[0][comp*(MBK_SIZE/2)];      for (y = 0; y < MBK_SIZE/2; y++) {        tmpPix = src1[y] * 8;        step = src2[y] - src1[y];        for (x = 0; x < MBK_SIZE/2; x++) {          *pred++ = (u_int8)((tmpPix + 4) >> 3);          tmpPix += step;        }        pred += MBK_SIZE/2;      }    }    currC = currV;  }}/* * * useIntra: * * Parameters: *      pEc                   EC object   *      refIdxTable           Reference Index table *      idxX                  The position of the MB to be concealed *      idxY                  The position of the MB to be concealed * * Function: *      Make the decision to do Intra concealment or Inter concealment * * Returns: *      1                      Do Intra concealment *      0                      Do Inter concealment */static int useIntra(errorConcealment_s* pEc, int8 *refIdxTable, int idxX, int idxY){  int flag = 0;  int mbX, mbY;  if (refIdxTable == NULL)    return 1;  // top  mbX = idxX;  mbY = idxY - 1;  if (mbY >= 0) {    if (refIdxTable[mbX+mbY*pEc->widthMbs] == -1 && pEc->decodedMbs[mbY][mbX] == 1)      flag++;  }  // bottom  mbX = idxX;  mbY = idxY + 1;  if (mbY < pEc->heightMbs) {    if (refIdxTable[mbX+mbY*pEc->widthMbs] == -1 && pEc->decodedMbs[mbY][mbX] == 1)      flag++;  }  // left  mbX = idxX - 1;  mbY = idxY;  if (mbX >= 0) {    if (refIdxTable[mbX+mbY*pEc->widthMbs] == -1 && pEc->decodedMbs[mbY][mbX] == 1)      flag++;  }  // right  mbX = idxX + 1;  mbY = idxY;  if (mbX < pEc->widthMbs) {    if (refIdxTable[mbX+mbY*pEc->widthMbs] == -1 && pEc->decodedMbs[mbY][mbX] == 1)      flag++;  }  if (flag >= 4)    return 1;  else    return 0;}/* * * bySceneCutDetection: * * Parameters: *      pEc                   EC object   *      currPic               The picture to be concealed * * Function: *      Check if the picture is scene cut picture by partly received picture. * * Returns: *      0:      Not scene cut picture, or failed in the algorithm *      1:      Scene cut picture */#define DEBUG_SCENE_CUT_DETECTION 0static int bySceneCutDetection(errorConcealment_s *pEc, frmBuf_s *currPic, dpb_s *dpb){  frmBuf_s *prevPic;  int      numMBs;  int      numSelectedMbs;  int      countMbs;  int      i;  int      j;  int      k;  int      x;  int      y;  int      xDir;  int      yDir;  int      mbOffset;  int      pixelOffset;  int32    diff;  int      leftBound;  int      rightBound;  int      topBound;  int      bottomBound;  int      visit;  int      diffTh = 44/2;#if DEBUG_SCENE_CUT_DETECTION  int      debugNum[11][9];  FILE     *fp;  static int count = 0;  unsigned char *curr, *prev;      #endif#if DEBUG_SCENE_CUT_DETECTION  for (y = 0; y < 9; y++) {    for (x = 0; x < 11; x++)      debugNum[x][y] = -1;  }  curr = malloc(176*144);  prev = malloc(176*144);  if (curr == NULL|| prev == NULL) {    printf("Error!");    exit(0);  }  memset(curr, 0, 176*144);  memset(prev, 0, 176*144);#endif  /* Find the latest decoded ref pic */  if (dpb->fullness > 0)    prevPic = dpb->buffers[0];  else    prevPic = NULL;  /* No stored pictures, we assume the current pictures to be a scene cut picture */  if (prevPic == NULL)    return 1;  /* 20% Mbs will be used for scene cut detection */  numMBs = pEc->widthMbs * pEc->heightMbs;  numSelectedMbs = numMBs / 5;  /* As per box-out order to select the MBs to do the scene cut detection */  // init position  x = pEc->widthMbs / 2;  y = pEc->heightMbs / 2;  // init dir  xDir = 0;  yDir = -1;  // init bound  leftBound = x;  rightBound = x;  topBound = y;  bottomBound = y;  visit = 0;  k = 0;  countMbs = 0;  diff = 0;  do {    /* calculate the diff */    if (!visit && pEc->decodedMbs[y][x] == 1 && pEc->prevDecodedMbs[y][x] == 1) {#if DEBUG_SCENE_CUT_DETECTION      debugNum[x][y] = k;#endif      countMbs++;      mbOffset = (y * pEc->widthMbs << 8) + (x << 4); //  y * MBK_SIZE * pEc->widthMbs * MBK_SIZE + x * MBK_SIZE;      for (j = 0; j < MBK_SIZE; j+=2) {        for (i = 0; i < MBK_SIZE; i++) {          pixelOffset = mbOffset + j * pEc->widthMbs * MBK_SIZE + i;          diff += abs(currPic->y[pixelOffset] - prevPic->y[pixelOffset]);#if DEBUG_SCENE_CUT_DETECTION          prev[pixelOffset] = prevPic->y[pixelOffset];          curr[pixelOffset] = currPic->y[pixelOffset];#endif        }      }    }    if (!visit)      k++;    if ( xDir == -1 &&  x == leftBound ) {      if (leftBound == 0)        visit = 1;      else {        visit = 0;        leftBound = leftBound - 1;        x = leftBound;      }      xDir = 0;      yDir = -1;    }     else if ( xDir == 1 && x == rightBound ) {      if (rightBound == pEc->widthMbs - 1)        visit = 1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -