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

📄 errorconcealment.c

📁 Nokia H.264/AVC Encoder/Decoder Usage Manual
💻 C
📖 第 1 页 / 共 3 页
字号:
      else {        visit = 0;        rightBound = rightBound + 1;        x = rightBound;      }      xDir = 0;      yDir = 1;    }     else if ( yDir == -1 && y == topBound ) {      if (topBound == 0)        visit = 1;      else {        visit = 0;        topBound = topBound - 1;        y = topBound;      }      xDir = 1;      yDir = 0;    }     else if( yDir == 1 && y == bottomBound ) {      if (bottomBound == pEc->heightMbs - 1)        visit = 1;      else {        visit = 0;        bottomBound = bottomBound + 1;        y = bottomBound;      }      xDir = -1;      yDir = 0;    }     else {      x = x + xDir;      y = y + yDir;    }  } while (k < numMBs && countMbs < numSelectedMbs);#if DEBUG_SCENE_CUT_DETECTION  fp = fopen("dddd.txt", "wt");  for (y = 0; y < 9; y++) {    for (x = 0; x < 11; x++)      fprintf(fp, "%d\t", debugNum[x][y]);    fprintf(fp, "\n");  }  fclose(fp);  count++;  fp = fopen("prev.yuv", "wb");  fwrite(prev, 1, 176*144, fp);  memset(prev, 128, 176*144/2);  fwrite(prev, 1, 176*144/2, fp);  fclose(fp);  fp = fopen("curr.yuv", "wb");  fwrite(curr, 1, 176*144, fp);  memset(curr, 128, 176*144/2);  fwrite(curr, 1, 176*144/2, fp);  fclose(fp);  free(curr);  free(prev);#endif  /* If there are not enough MBs or the diff is small enough, not a scene cut! */  if (countMbs < numSelectedMbs || diff < (diffTh * numSelectedMbs << 8) ) { // * MBK_SIZE * MBK_SIZE#if DEBUG_SCENE_CUT_DETECTION    printf("Inter concealing at pic layer (%d).\n", diff / (numSelectedMbs * MBK_SIZE * MBK_SIZE));#endif    return 0;  }  else {#if DEBUG_SCENE_CUT_DETECTION    printf("INTRA concealing at pic layer (%d).\n", diff / (numSelectedMbs * MBK_SIZE * MBK_SIZE));#endif    return 1;  }}/* concealCurrPicPFC: * * Parameters: *      pEc                   EC object   *      currPic               The picture to be concealed *      mbData                Table of MB attributes *      dpb                   Decoded picture buffer *      pps                   Picture parameter set * * Function: *      Conceal the lost area in current picture MB by MB. Note that whole picture losses are  *      not handled. * * Returns: *      - */static void concealCurrPicPFC(errorConcealment_s* pEc, frmBuf_s *currPic, mbAttributes_s *mbData,                               dpb_s *dpb, pic_parameter_set_s *pps){  int     idxX, idxY;  int     x, y;  int     width, height;  u_int8 *currPtr;  u_int8    predY[MBK_SIZE][MBK_SIZE];  u_int8    predC[MBK_SIZE/2][MBK_SIZE];  frmBuf_s  *refPicList0[DPB_MAX_SIZE+1];  int       numRefFrames;  width  = pEc->widthMbs * MBK_SIZE;  height = pEc->heightMbs * MBK_SIZE;  /* Choose number of reference frames and build reference picture list */  /* Use the parameters in the PPS to build the ref list */  /* Alternatively, we can use the received slices in the same frame if available - a little more complex */  numRefFrames = pps->num_ref_idx_l0_active_minus1 + 1;  sliceInitRefPicList(dpb, refPicList0, numRefFrames);   for (idxY = 0; idxY < pEc->heightMbs; idxY++) {    for (idxX = 0; idxX < pEc->widthMbs; idxX++) {      /* Current MB is not decoded (pEc->decodedMbs[idxX][idxY] == 0), conceal it */      if (pEc->decodedMbs[idxY][idxX] != 0)        continue;      fillMotionVectors(idxX, idxY, width, height, mbData->refIdxTable, mbData->motVecTable, 0);      mcpGetPred(predY, predC, idxX, idxY, refPicList0, width,                  height, mbData->motVecTable, mbData->refIdxTable);      /* Y */      currPtr = currPic->y + idxY*MBK_SIZE*width + idxX*MBK_SIZE;      for (y = 0; y < MBK_SIZE; y++) {        for (x = 0; x < MBK_SIZE; x++) {          currPtr[y*width+x] = predY[y][x];        }      }      /* U */      currPtr = currPic->u + idxY *MBK_SIZE/2 * width/2 + idxX*MBK_SIZE/2;      for (y = 0; y < MBK_SIZE/2; y++) {        for (x = 0; x < MBK_SIZE/2; x++) {          currPtr[y*width/2+x] = predC[y][0+x];        }      }      /* V */      currPtr = currPic->v + idxY *MBK_SIZE/2 * width/2 + idxX*MBK_SIZE/2;      for (y = 0; y < MBK_SIZE/2; y++) {        for (x = 0; x < MBK_SIZE/2; x++) {          currPtr[y*width/2+x] = predC[y][MBK_SIZE/2 +x];        }      }      pEc->decodedMbs[idxY][idxX] = 2;    }  }}/* * * concealCurrPic: * * Parameters: *      pEc                   EC object   *      currPic               The picture to be concealed *      mbData                Table of MB attributes *      dpb                   Decoded picture buffer *      pps                   Picture parameter set * * Function: *      Conceal the lost area in current picture MB by MB. Note that whole picture losses are  *      not handled. * * Returns: *      - */static void concealCurrPicTCON(errorConcealment_s* pEc, frmBuf_s *currPic,                           mbAttributes_s *mbData, dpb_s *dpb,                           pic_parameter_set_s *pps){  int idxX, idxY, idxMB;  int x, y;  int width, height;  u_int8 *currPtr;  int isUpOrDown;  int intra;  u_int8 predY[MBK_SIZE][MBK_SIZE];  u_int8 predC[MBK_SIZE/2][MBK_SIZE];  int fromBest;  frmBuf_s *refPicList0[DPB_MAX_SIZE+1];  int numRefFrames;  width = pEc->widthMbs * MBK_SIZE;  height = pEc->heightMbs * MBK_SIZE;  /* Choose number of reference frames and build reference picture list */  /* Use the parameters in the PPS to build the ref list */  /* Alternatively, we can use the received slices in the same frame if available - a little more complex */  numRefFrames = pps->num_ref_idx_l0_active_minus1 + 1;  sliceInitRefPicList(dpb, refPicList0, numRefFrames);  initDir(pEc);  /* Make a decision to do intra concealment on picture layer */  /* The first picture of the sequence */  if (pEc->isFirstPicOfSeq)    intra = 1;  /* Having scene info SEI */  else if (pEc->hasSceneInfo) {    intra = currPic->sceneCut;  }  /* Using scene cut detection */  else {    intra = bySceneCutDetection(pEc, currPic, dpb);  }  while ((idxMB = selectOneMB(pEc, &isUpOrDown)) >= 0) {    //idxY = idxMB / pEc->widthMbs;    idxY = (int)(((int32)idxMB * pEc->inverseOfWidthMbs) >> pEc->numFractBits);    //idxX = idxMB % pEc->widthMbs;    idxX = idxMB - idxY*pEc->widthMbs;    /* Current MB is not decoded (pEc->decodedMbs[idxY][idxX] == 0), conceal it */    /* do Intra concealment or Inter concealment? */    if ( intra || useIntra(pEc, mbData->refIdxTable, idxX, idxY) ) {      mbData->mbTypeTable[idxMB] = MBK_INTRA;      blkIntraConceal(pEc, predY, predC, currPic, idxX, idxY);    }    else {      mbData->mbTypeTable[idxMB] = MBK_INTER;      fromBest = selectDir(pEc, isUpOrDown, idxX, idxY);      fillMotionVectors(idxX, idxY, width, height, mbData->refIdxTable, mbData->motVecTable, fromBest);      mcpGetPred(predY, predC, idxX, idxY, refPicList0, width,                  height, mbData->motVecTable, mbData->refIdxTable);    }    mbData->qpTable[idxMB] = MAX_QP;    mbData->cbpTable[idxMB] = 0;    mbData->alphaOffset[idxMB] = 0;    mbData->betaOffset[idxMB] = 0;    mbData->filterModeTab[idxMB] = 0;    /* Y */    currPtr = currPic->y + idxY*MBK_SIZE*width + idxX*MBK_SIZE;    for (y = 0; y < MBK_SIZE; y++) {      for (x = 0; x < MBK_SIZE; x++) {        currPtr[y*width+x] = predY[y][x];      }    }    /* U */    currPtr = currPic->u + idxY *MBK_SIZE/2 * width/2 + idxX*MBK_SIZE/2;    for (y = 0; y < MBK_SIZE/2; y++) {      for (x = 0; x < MBK_SIZE/2; x++) {        currPtr[y*width/2+x] = predC[y][0+x];      }    }    /* V */    currPtr = currPic->v + idxY *MBK_SIZE/2 * width/2 + idxX*MBK_SIZE/2;    for (y = 0; y < MBK_SIZE/2; y++) {      for (x = 0; x < MBK_SIZE/2; x++) {        currPtr[y*width/2+x] = predC[y][MBK_SIZE/2 +x];      }    }    pEc->decodedMbs[idxY][idxX] = 2;  }}/* * * ercConcealMbs: * * Parameters: *      seq                   Sequence object *      currPic               The picture to be concealed *      mbData                Table of MB attributes *      dpb                   Decoded picture buffer *      pps                   Picture parameter set * * Function: *      Call concealCurrPic *      Interface of the error concealment * * Returns: *      - */void ercConcealMbs(errorConcealment_s *pEc, frmBuf_s *currPic,                   mbAttributes_s *mbData, dpb_s *dpb,                   pic_parameter_set_s *pps){  {  switch (pEc->alg) {  case 0:    /* PFC */    concealCurrPicPFC(pEc, currPic, mbData, dpb, pps);    break;  case 1:    /* TCON-like */    concealCurrPicTCON(pEc, currPic, mbData, dpb, pps);    break;  default:    break;  }}  }/* * * ercConcealWholePic: * * Parameters: *      seq                   Sequence object *      currPic               The picture to be concealed *      mbData                Table of MB attributes *      dpb                   Decoded picture buffer *      pps                   Picture parameter set * * Function: *      Although the wholly lost pictures will not be outputted currently, *      we copy the content of the last decoded picture to the buffer as  *      a concealment. This is due to the wholly lost pictures will still  *      serve as ref pictures for the subsequent pictures. * * Returns: *      - */void ercConcealWholePic(errorConcealment_s *pEc, frmBuf_s *currPic,                        mbAttributes_s *mbData, dpb_s *dpb){  int i, j;  int mbsPerRow = currPic->width/MBK_SIZE;  int mbsPerCol = currPic->height/MBK_SIZE;  frmBuf_s *tmpFrm = dpb->buffers[0];  pEc->dir;  if (dpb->fullness == 0)    return;  memcpy(currPic->y, tmpFrm->y, currPic->width * currPic->height);  memcpy(currPic->u, tmpFrm->u, currPic->width * currPic->height / 4);  memcpy(currPic->v, tmpFrm->v, currPic->width * currPic->height / 4);  /* Switch off loopfilter for this picture */  for (j = 0; j < mbsPerCol; j++)    for (i = 0; i < mbsPerRow; i++)      mbData->filterModeTab[j*mbsPerRow+i] = 1;}/* * * ercInit: * * Parameters: *      wMbs                  The picture width in MBs *      hMbs                  The picture height in MBs * * Function: *      Initialization for the error concealment. * * Returns: *      The Error Concealment object. */errorConcealment_s* ercOpen(int wMbs, int hMbs){  int i;  errorConcealment_s* pEc;  if ((pEc = (errorConcealment_s*)nccMalloc(sizeof(errorConcealment_s))) == NULL)    return NULL;  memset(pEc, 0, sizeof(errorConcealment_s));  if ((pEc->decodedMbs = (int **)nccMalloc(sizeof(int*)*hMbs)) == NULL)    return NULL;  if ((pEc->decodedMbs[0] = (int*)nccMalloc(sizeof(int)*wMbs*hMbs)) == NULL)    return NULL;  for (i = 1; i < hMbs; i++)    pEc->decodedMbs[i] = pEc->decodedMbs[0] + i*wMbs;  if ((pEc->prevDecodedMbs = (int **)nccMalloc(sizeof(int*)*hMbs)) == NULL)    return NULL;  if ((pEc->prevDecodedMbs[0] = (int*)nccMalloc(sizeof(int)*wMbs*hMbs)) == NULL)    return NULL;  for (i = 1; i < hMbs; i++)    pEc->prevDecodedMbs[i] = pEc->prevDecodedMbs[0] + i*wMbs;  pEc->widthMbs = wMbs;  pEc->heightMbs = hMbs;  pEc->hasSceneInfo = 0;  for (i = 15; i > 0; i--) {    if ((wMbs>>i) & 1)      break;  }  pEc->numFractBits = 14+i;  pEc->inverseOfWidthMbs = (int)((((int32)1<<pEc->numFractBits)) / wMbs + 1);  ercClear(pEc);  return pEc;}/* * * ercClose: * * Parameters: *      pEc                   The EC object * * Function: *      Close the object of error concealment. * * Returns: *      - */void ercClose(errorConcealment_s* pEc){  if (pEc == NULL)    return;  nccFree(pEc->decodedMbs[0]);  nccFree(pEc->decodedMbs);  nccFree(pEc->prevDecodedMbs[0]);  nccFree(pEc->prevDecodedMbs);  nccFree(pEc);}/* * * ercClear: * * Parameters: *      pEc                   The EC object * * Function: *      Reset the indicators for all the MBs. * * Returns: *      - */void ercClear(errorConcealment_s* pEc){  int i, j;  for (j = 0; j < pEc->heightMbs; j++) {    for (i = 0; i < pEc->widthMbs; i++) {      pEc->prevDecodedMbs[j][i] = pEc->decodedMbs[j][i];    }  }  for (j = 0; j < pEc->heightMbs; j++) {    for (i = 0; i < pEc->widthMbs; i++) {      pEc->decodedMbs[j][i] = 0;    }  }}/* * * ercDecodeMb: * * Parameters: *      pEc                   The EC object *      mbX                   The column of the decoded MBs *      mbY                   The row of the decoded MBs * * Function: *      Set the indicator for the decoded MB. * * Returns: *      - */void ercDecodeMb(errorConcealment_s *pEc, int mbX, int mbY){  pEc->decodedMbs[mbY][mbX] = 1;}/* * * ercCheck: * * Parameters: *      pEc                   The EC object * * Function: *      Check whether all the MBs in current picture are decoded correctly. * * Returns: *      0:                    Not all the MBs are correctly decoded. *      1:                    All the MBs are correctly decoded. *       */int ercCheck(errorConcealment_s *pEc){  int i, j;  for (j = 0; j < pEc->heightMbs; j++) {    for (i = 0; i < pEc->widthMbs; i++) {      if (pEc->decodedMbs[j][i] == 0)        return 0;    }  }  return 1;}/* * * ercCheckAndConceal: * * Parameters: *      pEc                   The EC object *      currPic               The picture to be concealed *      mbData                Table of MB attributes *      dpb                   Decoded picture buffer *      pps                   Picture parameter set * * Function: *      Check whether all the MBs in current picture are decoded correctly. *      If not, conceal the lost area. * * Returns: *      - *       */void ercCheckAndConceal(errorConcealment_s *pEc, frmBuf_s *currPic,                        mbAttributes_s *mbData, dpb_s *dpb,                        pic_parameter_set_s *pps){    /* NOT all MBs of the current picture are decoded */    if ( ercCheck(pEc) == 0) {      /* For the simple EC: PFC, copy the lost MBs from the previous reference picture */      ercConcealMbs(pEc, currPic, mbData, dpb, pps);    }}#endif  /* ERROR_CONCEALMENT */

⌨️ 快捷键说明

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