📄 errorconcealment.c
字号:
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 + -