00001
00021 #include "global.h"
00022 #include "mbuffer.h"
00023 #include "memalloc.h"
00024 #include "erc_do.h"
00025 #include "image.h"
00026 #include "mc_prediction.h"
00027 #include "macroblock.h"
00028
00029 extern int erc_mvperMB;
00030 ImageParameters *erc_img;
00031
00032
00033
00034
00035 struct concealment_node *concealment_head = NULL;
00036 struct concealment_node *concealment_end = NULL;
00037
00038
00039 static int concealByCopy(frame *recfr, int currMBNum, objectBuffer_t *object_list, int picSizeX);
00040 static int concealByTrial(frame *recfr, imgpel *predMB,
00041 int currMBNum, objectBuffer_t *object_list, int predBlocks[],
00042 int picSizeX, int picSizeY, int *yCondition);
00043 static int edgeDistortion (int predBlocks[], int currYBlockNum, imgpel *predMB,
00044 imgpel *recY, int picSizeX, int regionSize);
00045 static void copyBetweenFrames (frame *recfr, int currYBlockNum, int picSizeX, int regionSize);
00046 static void buildPredRegionYUV(ImageParameters *img, int *mv, int x, int y, imgpel *predMB);
00047
00048
00049 static void buildPredblockRegionYUV(ImageParameters *img, int *mv,
00050 int x, int y, imgpel *predMB, int list);
00051 static void CopyImgData(imgpel **inputY, imgpel ***inputUV, imgpel **outputY, imgpel ***outputUV,
00052 int img_width, int img_height, int img_width_cr, int img_height_cr);
00053
00054 static void copyPredMB (int currYBlockNum, imgpel *predMB, frame *recfr,
00055 int picSizeX, int regionSize);
00056
00057 static int uv_div[2][4] = {{0, 1, 1, 0}, {0, 1, 0, 0}};
00058
00080 int ercConcealInterFrame(frame *recfr, objectBuffer_t *object_list,
00081 int picSizeX, int picSizeY, ercVariables_t *errorVar, int chroma_format_idc )
00082 {
00083 int lastColumn = 0, lastRow = 0, predBlocks[8];
00084 int lastCorruptedRow = -1, firstCorruptedRow = -1, currRow = 0,
00085 row, column, columnInd, areaHeight = 0, i = 0;
00086 imgpel *predMB;
00087
00088
00089 if ( errorVar && errorVar->concealment )
00090 {
00091
00092 if ( errorVar->nOfCorruptedSegments )
00093 {
00094 if (chroma_format_idc != YUV400)
00095 predMB = (imgpel *) malloc ( (256 + (img->mb_cr_size_x*img->mb_cr_size_y)*2) * sizeof (imgpel));
00096 else
00097 predMB = (imgpel *) malloc(256 * sizeof (imgpel));
00098
00099 if ( predMB == NULL ) no_mem_exit("ercConcealInterFrame: predMB");
00100
00101 lastRow = (int) (picSizeY>>4);
00102 lastColumn = (int) (picSizeX>>4);
00103
00104 for ( columnInd = 0; columnInd < lastColumn; columnInd ++)
00105 {
00106
00107 column = ((columnInd%2) ? (lastColumn - columnInd/2 -1) : (columnInd/2));
00108
00109 for ( row = 0; row < lastRow; row++)
00110 {
00111
00112 if ( errorVar->yCondition[MBxy2YBlock(column, row, 0, picSizeX)] <= ERC_BLOCK_CORRUPTED )
00113 {
00114 firstCorruptedRow = row;
00115
00116 for ( lastCorruptedRow = row+1; lastCorruptedRow < lastRow; lastCorruptedRow++)
00117 {
00118
00119 if (errorVar->yCondition[MBxy2YBlock(column, lastCorruptedRow, 0, picSizeX)] > ERC_BLOCK_CORRUPTED)
00120 {
00121
00122 lastCorruptedRow --;
00123 break;
00124 }
00125 }
00126 if ( lastCorruptedRow >= lastRow )
00127 {
00128
00129 lastCorruptedRow = lastRow-1;
00130 for ( currRow = firstCorruptedRow; currRow < lastRow; currRow++ )
00131 {
00132
00133 ercCollect8PredBlocks (predBlocks, (currRow<<1), (column<<1),
00134 errorVar->yCondition, (lastRow<<1), (lastColumn<<1), 2, 0);
00135
00136 if(erc_mvperMB >= MVPERMB_THR)
00137 concealByTrial(recfr, predMB,
00138 currRow*lastColumn+column, object_list, predBlocks,
00139 picSizeX, picSizeY,
00140 errorVar->yCondition);
00141 else
00142 concealByCopy(recfr, currRow*lastColumn+column,
00143 object_list, picSizeX);
00144
00145 ercMarkCurrMBConcealed (currRow*lastColumn+column, -1, picSizeX, errorVar);
00146 }
00147 row = lastRow;
00148 }
00149 else if ( firstCorruptedRow == 0 )
00150 {
00151
00152 for ( currRow = lastCorruptedRow; currRow >= 0; currRow-- )
00153 {
00154
00155 ercCollect8PredBlocks (predBlocks, (currRow<<1), (column<<1),
00156 errorVar->yCondition, (lastRow<<1), (lastColumn<<1), 2, 0);
00157
00158 if(erc_mvperMB >= MVPERMB_THR)
00159 concealByTrial(recfr, predMB,
00160 currRow*lastColumn+column, object_list, predBlocks,
00161 picSizeX, picSizeY,
00162 errorVar->yCondition);
00163 else
00164 concealByCopy(recfr, currRow*lastColumn+column,
00165 object_list, picSizeX);
00166
00167 ercMarkCurrMBConcealed (currRow*lastColumn+column, -1, picSizeX, errorVar);
00168 }
00169
00170 row = lastCorruptedRow+1;
00171 }
00172 else
00173 {
00174
00175
00176 row = lastCorruptedRow+1;
00177
00178 areaHeight = lastCorruptedRow-firstCorruptedRow+1;
00179
00180
00181
00182
00183 for ( i = 0; i < areaHeight; i++)
00184 {
00185 if ( i % 2 )
00186 {
00187 currRow = lastCorruptedRow;
00188 lastCorruptedRow --;
00189 }
00190 else
00191 {
00192 currRow = firstCorruptedRow;
00193 firstCorruptedRow ++;
00194 }
00195
00196 ercCollect8PredBlocks (predBlocks, (currRow<<1), (column<<1),
00197 errorVar->yCondition, (lastRow<<1), (lastColumn<<1), 2, 0);
00198
00199 if(erc_mvperMB >= MVPERMB_THR)
00200 concealByTrial(recfr, predMB,
00201 currRow*lastColumn+column, object_list, predBlocks,
00202 picSizeX, picSizeY,
00203 errorVar->yCondition);
00204 else
00205 concealByCopy(recfr, currRow*lastColumn+column,
00206 object_list, picSizeX);
00207
00208 ercMarkCurrMBConcealed (currRow*lastColumn+column, -1, picSizeX, errorVar);
00209
00210 }
00211 }
00212 lastCorruptedRow = -1;
00213 firstCorruptedRow = -1;
00214 }
00215 }
00216 }
00217
00218 free(predMB);
00219 }
00220 return 1;
00221 }
00222 else
00223 return 0;
00224 }
00225
00244 static int concealByCopy(frame *recfr, int currMBNum,
00245 objectBuffer_t *object_list, int picSizeX)
00246 {
00247 objectBuffer_t *currRegion;
00248
00249 currRegion = object_list+(currMBNum<<2);
00250 currRegion->regionMode = REGMODE_INTER_COPY;
00251
00252 currRegion->xMin = (xPosMB(currMBNum,picSizeX)<<4);
00253 currRegion->yMin = (yPosMB(currMBNum,picSizeX)<<4);
00254
00255 copyBetweenFrames (recfr, MBNum2YBlock(currMBNum,0,picSizeX), picSizeX, 16);
00256
00257 return 0;
00258 }
00259
00275 static void copyBetweenFrames (frame *recfr, int currYBlockNum, int picSizeX, int regionSize)
00276 {
00277 int j, k, location, xmin, ymin;
00278 StorablePicture* refPic = listX[0][0];
00279
00280
00281 xmin = (xPosYBlock(currYBlockNum,picSizeX)<<3);
00282 ymin = (yPosYBlock(currYBlockNum,picSizeX)<<3);
00283
00284 for (j = ymin; j < ymin + regionSize; j++)
00285 for (k = xmin; k < xmin + regionSize; k++)
00286 {
00287 location = j * picSizeX + k;
00288
00289 recfr->yptr[location] = refPic->imgY[j][k];
00290 }
00291
00292 for (j = ymin >> uv_div[1][dec_picture->chroma_format_idc]; j < (ymin + regionSize) >> uv_div[1][dec_picture->chroma_format_idc]; j++)
00293 for (k = xmin >> uv_div[0][dec_picture->chroma_format_idc]; k < (xmin + regionSize) >> uv_div[0][dec_picture->chroma_format_idc]; k++)
00294 {
00295
00296 location = ((j * picSizeX) >> uv_div[0][dec_picture->chroma_format_idc]) + k;
00297
00298
00299
00300 recfr->uptr[location] = refPic->imgUV[0][j][k];
00301 recfr->vptr[location] = refPic->imgUV[1][j][k];
00302 }
00303 }
00304
00332 static int concealByTrial(frame *recfr, imgpel *predMB,
00333 int currMBNum, objectBuffer_t *object_list, int predBlocks[],
00334 int picSizeX, int picSizeY, int *yCondition)
00335 {
00336 int predMBNum = 0, numMBPerLine,
00337 compSplit1 = 0, compSplit2 = 0, compLeft = 1, comp = 0, compPred, order = 1,
00338 fInterNeighborExists, numIntraNeighbours,
00339 fZeroMotionChecked, predSplitted = 0,
00340 threshold = ERC_BLOCK_OK,
00341 minDist, currDist, i, k, bestDir;
00342 int regionSize;
00343 objectBuffer_t *currRegion;
00344 int mvBest[3] , mvPred[3], *mvptr;
00345
00346 numMBPerLine = (int) (picSizeX>>4);
00347
00348 img->current_mb_nr = currMBNum;
00349
00350 comp = 0;
00351 regionSize = 16;
00352
00353 do
00354 {
00355
00356 currRegion = object_list+(currMBNum<<2)+comp;
00357
00358
00359
00360 currRegion->xMin = (xPosYBlock(MBNum2YBlock(currMBNum,comp,picSizeX),picSizeX)<<3);
00361 currRegion->yMin = (yPosYBlock(MBNum2YBlock(currMBNum,comp,picSizeX),picSizeX)<<3);
00362
00363 do
00364 {
00365
00366 minDist = 0;
00367 fInterNeighborExists = 0;
00368 numIntraNeighbours = 0;
00369 fZeroMotionChecked = 0;
00370
00371
00372 for (i = 4; i < 8; i++)
00373 {
00374
00375
00376 if (predBlocks[i] >= threshold)
00377 {
00378 switch (i)
00379 {
00380 case 4:
00381 predMBNum = currMBNum-numMBPerLine;
00382 compSplit1 = 2;
00383 compSplit2 = 3;
00384 break;
00385
00386 case 5:
00387 predMBNum = currMBNum-1;
00388 compSplit1 = 1;
00389 compSplit2 = 3;
00390 break;
00391
00392 case 6:
00393 predMBNum = currMBNum+numMBPerLine;
00394 compSplit1 = 0;
00395 compSplit2 = 1;
00396 break;
00397
00398 case 7:
00399 predMBNum = currMBNum+1;
00400 compSplit1 = 0;
00401 compSplit2 = 2;
00402 break;
00403 }
00404
00405
00406
00407 if (isBlock(object_list,predMBNum,compSplit1,INTRA) ||
00408 isBlock(object_list,predMBNum,compSplit2,INTRA))
00409 {
00410 numIntraNeighbours++;
00411 }
00412 else
00413 {
00414
00415 for (predSplitted = isSplitted(object_list, predMBNum),
00416 compPred = compSplit1;
00417 predSplitted >= 0;
00418 compPred = compSplit2,
00419 predSplitted -= ((compSplit1 == compSplit2) ? 2 : 1))
00420 {
00421
00422
00423 if (isBlock(object_list, predMBNum, compPred, INTER_COPY))
00424 {
00425
00426 if (fZeroMotionChecked)
00427 {
00428 continue;
00429 }
00430 else
00431 {
00432 fZeroMotionChecked = 1;
00433
00434 mvPred[0] = mvPred[1] = 0;
00435 mvPred[2] = 0;
00436
00437 buildPredRegionYUV(erc_img, mvPred, currRegion->xMin, currRegion->yMin, predMB);
00438 }
00439 }
00440
00441 else if (isBlock(object_list,predMBNum,compPred,INTRA))
00442 {
00443 continue;
00444 }
00445 else
00446 {
00447 mvptr = getParam(object_list, predMBNum, compPred, mv);
00448
00449 mvPred[0] = mvptr[0];
00450 mvPred[1] = mvptr[1];
00451 mvPred[2] = mvptr[2];
00452
00453 buildPredRegionYUV(erc_img, mvPred, currRegion->xMin, currRegion->yMin, predMB);
00454 }
00455
00456
00457 currDist = edgeDistortion(predBlocks,
00458 MBNum2YBlock(currMBNum,comp,picSizeX),
00459 predMB, recfr->yptr, picSizeX, regionSize);
00460
00461
00462 if (currDist < minDist || !fInterNeighborExists)
00463 {
00464
00465 minDist = currDist;
00466 bestDir = i;
00467
00468 for (k=0;k<3;k++)
00469 mvBest[k] = mvPred[k];
00470
00471 currRegion->regionMode =
00472 (isBlock(object_list, predMBNum, compPred, INTER_COPY)) ?
00473 ((regionSize == 16) ? REGMODE_INTER_COPY : REGMODE_INTER_COPY_8x8) :
00474 ((regionSize == 16) ? REGMODE_INTER_PRED : REGMODE_INTER_PRED_8x8);
00475
00476 copyPredMB(MBNum2YBlock(currMBNum,comp,picSizeX), predMB, recfr,
00477 picSizeX, regionSize);
00478 }
00479
00480 fInterNeighborExists = 1;
00481 }
00482 }
00483 }
00484 }
00485
00486 threshold--;
00487
00488 } while ((threshold >= ERC_BLOCK_CONCEALED) && (fInterNeighborExists == 0));
00489
00490
00491 if (!fZeroMotionChecked)
00492 {
00493 mvPred[0] = mvPred[1] = 0;
00494 mvPred[2] = 0;
00495
00496 buildPredRegionYUV(erc_img, mvPred, currRegion->xMin, currRegion->yMin, predMB);
00497
00498 currDist = edgeDistortion(predBlocks,
00499 MBNum2YBlock(currMBNum,comp,picSizeX),
00500 predMB, recfr->yptr, picSizeX, regionSize);
00501
00502 if (currDist < minDist || !fInterNeighborExists)
00503 {
00504
00505 minDist = currDist;
00506 for (k=0;k<3;k++)
00507 mvBest[k] = mvPred[k];
00508
00509 currRegion->regionMode =
00510 ((regionSize == 16) ? REGMODE_INTER_COPY : REGMODE_INTER_COPY_8x8);
00511
00512 copyPredMB(MBNum2YBlock(currMBNum,comp,picSizeX), predMB, recfr,
00513 picSizeX, regionSize);
00514 }
00515 }
00516
00517 for (i=0; i<3; i++)
00518 currRegion->mv[i] = mvBest[i];
00519
00520 yCondition[MBNum2YBlock(currMBNum,comp,picSizeX)] = ERC_BLOCK_CONCEALED;
00521 comp = (comp+order+4)%4;
00522 compLeft--;
00523
00524 } while (compLeft);
00525
00526 return 0;
00527 }
00528
00549 static void buildPredRegionYUV(ImageParameters *img, int *mv, int x, int y, imgpel *predMB)
00550 {
00551 static imgpel **tmp_block;
00552 int i=0, j=0, ii=0, jj=0,i1=0,j1=0,j4=0,i4=0;
00553 int jf=0;
00554 int uv;
00555 int vec1_x=0,vec1_y=0;
00556 int ioff,joff;
00557 imgpel *pMB = predMB;
00558
00559 int ii0,jj0,ii1,jj1,if1,jf1,if0,jf0;
00560 int mv_mul;
00561
00562
00563 int f1_x, f1_y, f2_x, f2_y, f3, f4, ifx;
00564 int b8, b4;
00565 int yuv = dec_picture->chroma_format_idc - 1;
00566
00567 int ref_frame = imax (mv[2], 0);
00568
00569
00570 get_mem2Dpel(&tmp_block, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
00571
00572
00573 img->mb_x = x/MB_BLOCK_SIZE;
00574 img->mb_y = y/MB_BLOCK_SIZE;
00575 img->block_y = img->mb_y * BLOCK_SIZE;
00576 img->pix_c_y = img->mb_y * img->mb_cr_size_y;
00577 img->block_x = img->mb_x * BLOCK_SIZE;
00578 img->pix_c_x = img->mb_x * img->mb_cr_size_x;
00579
00580 mv_mul=4;
00581
00582
00583
00584 for(j=0;j<MB_BLOCK_SIZE/BLOCK_SIZE;j++)
00585 {
00586 joff=j*4;
00587 j4=img->block_y+j;
00588 for(i=0;i<MB_BLOCK_SIZE/BLOCK_SIZE;i++)
00589 {
00590 ioff=i*4;
00591 i4=img->block_x+i;
00592
00593 vec1_x = i4*4*mv_mul + mv[0];
00594 vec1_y = j4*4*mv_mul + mv[1];
00595
00596 get_block_luma(PLANE_Y, listX[0][ref_frame], vec1_x, vec1_y, BLOCK_SIZE, BLOCK_SIZE, img, tmp_block);
00597
00598 for(ii=0;ii<BLOCK_SIZE;ii++)
00599 for(jj=0;jj<MB_BLOCK_SIZE/BLOCK_SIZE;jj++)
00600 img->mb_pred[LumaComp][jj+joff][ii+ioff]=tmp_block[jj][ii];
00601 }
00602 }
00603
00604
00605 for (j = 0; j < 16; j++)
00606 {
00607 for (i = 0; i < 16; i++)
00608 {
00609 pMB[j*16+i] = img->mb_pred[LumaComp][j][i];
00610 }
00611 }
00612 pMB += 256;
00613
00614 if (dec_picture->chroma_format_idc != YUV400)
00615 {
00616
00617 f1_x = 64/img->mb_cr_size_x;
00618 f2_x=f1_x-1;
00619
00620 f1_y = 64/img->mb_cr_size_y;
00621 f2_y=f1_y-1;
00622
00623 f3=f1_x*f1_y;
00624 f4=f3>>1;
00625
00626 for(uv=0;uv<2;uv++)
00627 {
00628 for (b8=0;b8<(img->num_uv_blocks);b8++)
00629 {
00630 for(b4=0;b4<4;b4++)
00631 {
00632 joff = subblk_offset_y[yuv][b8][b4];
00633 j4=img->pix_c_y+joff;
00634 ioff = subblk_offset_x[yuv][b8][b4];
00635 i4=img->pix_c_x+ioff;
00636
00637 for(jj=0;jj<4;jj++)
00638 {
00639 jf=(j4+jj)/(img->mb_cr_size_y/4);
00640 for(ii=0;ii<4;ii++)
00641 {
00642 ifx=(i4+ii)/(img->mb_cr_size_x/4);
00643
00644 i1=(i4+ii)*f1_x + mv[0];
00645 j1=(j4+jj)*f1_y + mv[1];
00646
00647 ii0=iClip3 (0, dec_picture->size_x_cr-1, i1/f1_x);
00648 jj0=iClip3 (0, dec_picture->size_y_cr-1, j1/f1_y);
00649 ii1=iClip3 (0, dec_picture->size_x_cr-1, ((i1+f2_x)/f1_x));
00650 jj1=iClip3 (0, dec_picture->size_y_cr-1, ((j1+f2_y)/f1_y));
00651
00652 if1=(i1 & f2_x);
00653 jf1=(j1 & f2_y);
00654 if0=f1_x-if1;
00655 jf0=f1_y-jf1;
00656
00657 img->mb_pred[uv + 1][jj+joff][ii+ioff]=(if0*jf0*listX[0][ref_frame]->imgUV[uv][jj0][ii0]+
00658 if1*jf0*listX[0][ref_frame]->imgUV[uv][jj0][ii1]+
00659 if0*jf1*listX[0][ref_frame]->imgUV[uv][jj1][ii0]+
00660 if1*jf1*listX[0][ref_frame]->imgUV[uv][jj1][ii1]+f4)/f3;
00661 }
00662 }
00663 }
00664 }
00665
00666 for (j = 0; j < 8; j++)
00667 {
00668 for (i = 0; i < 8; i++)
00669 {
00670 pMB[j*8+i] = img->mb_pred[uv + 1][j][i];
00671 }
00672 }
00673 pMB += 64;
00674
00675 }
00676 }
00677
00678 free_mem2Dpel(tmp_block);
00679 }
00699 static void copyPredMB (int currYBlockNum, imgpel *predMB, frame *recfr,
00700 int picSizeX, int regionSize)
00701 {
00702
00703 int j, k, xmin, ymin, xmax, ymax;
00704 int locationTmp, locationPred;
00705 int uv_x = uv_div[0][dec_picture->chroma_format_idc];
00706 int uv_y = uv_div[1][dec_picture->chroma_format_idc];
00707
00708 xmin = (xPosYBlock(currYBlockNum,picSizeX)<<3);
00709 ymin = (yPosYBlock(currYBlockNum,picSizeX)<<3);
00710 xmax = xmin + regionSize -1;
00711 ymax = ymin + regionSize -1;
00712
00713 for (j = ymin; j <= ymax; j++)
00714 {
00715 for (k = xmin; k <= xmax; k++)
00716 {
00717 locationPred = j * picSizeX + k;
00718 locationTmp = (j-ymin) * 16 + (k-xmin);
00719 dec_picture->imgY[j][k] = predMB[locationTmp];
00720 }
00721 }
00722
00723 if (dec_picture->chroma_format_idc != YUV400)
00724 {
00725 for (j = (ymin>>uv_y); j <= (ymax>>uv_y); j++)
00726 {
00727 for (k = (xmin>>uv_x); k <= (xmax>>uv_x); k++)
00728 {
00729 locationPred = ((j * picSizeX) >> uv_x) + k;
00730 locationTmp = (j-(ymin>>uv_y)) * img->mb_cr_size_x + (k-(xmin>>1)) + 256;
00731 dec_picture->imgUV[0][j][k] = predMB[locationTmp];
00732
00733 locationTmp += 64;
00734
00735 dec_picture->imgUV[1][j][k] = predMB[locationTmp];
00736 }
00737 }
00738 }
00739 }
00740
00768 static int edgeDistortion (int predBlocks[], int currYBlockNum, imgpel *predMB,
00769 imgpel *recY, int picSizeX, int regionSize)
00770 {
00771 int i, j, distortion, numOfPredBlocks, threshold = ERC_BLOCK_OK;
00772 imgpel *currBlock = NULL, *neighbor = NULL;
00773 int currBlockOffset = 0;
00774
00775 currBlock = recY + (yPosYBlock(currYBlockNum,picSizeX)<<3)*picSizeX + (xPosYBlock(currYBlockNum,picSizeX)<<3);
00776
00777 do
00778 {
00779
00780 distortion = 0; numOfPredBlocks = 0;
00781
00782
00783 for (j = 4; j < 8; j++)
00784 {
00785
00786 if (predBlocks[j] >= threshold)
00787 {
00788
00789 switch (j)
00790 {
00791 case 4:
00792 neighbor = currBlock - picSizeX;
00793 for ( i = 0; i < regionSize; i++ )
00794 {
00795 distortion += iabs((int)(predMB[i] - neighbor[i]));
00796 }
00797 break;
00798 case 5:
00799 neighbor = currBlock - 1;
00800 for ( i = 0; i < regionSize; i++ )
00801 {
00802 distortion += iabs((int)(predMB[i*16] - neighbor[i*picSizeX]));
00803 }
00804 break;
00805 case 6:
00806 neighbor = currBlock + regionSize*picSizeX;
00807 currBlockOffset = (regionSize-1)*16;
00808 for ( i = 0; i < regionSize; i++ )
00809 {
00810 distortion += iabs((int)(predMB[i+currBlockOffset] - neighbor[i]));
00811 }
00812 break;
00813 case 7:
00814 neighbor = currBlock + regionSize;
00815 currBlockOffset = regionSize-1;
00816 for ( i = 0; i < regionSize; i++ )
00817 {
00818 distortion += iabs((int)(predMB[i*16+currBlockOffset] - neighbor[i*picSizeX]));
00819 }
00820 break;
00821 }
00822
00823 numOfPredBlocks++;
00824 }
00825 }
00826
00827 threshold--;
00828 if (threshold < ERC_BLOCK_CONCEALED)
00829 break;
00830 } while (numOfPredBlocks == 0);
00831
00832 if(numOfPredBlocks == 0)
00833 {
00834 return 0;
00835
00836 }
00837 return (distortion/numOfPredBlocks);
00838 }
00839
00840
00841
00851 static void buildPredblockRegionYUV(ImageParameters *img, int *mv,
00852 int x, int y, imgpel *predMB, int list)
00853 {
00854 static imgpel **tmp_block;
00855 int i=0,j=0,ii=0,jj=0,i1=0,j1=0,j4=0,i4=0;
00856 int jf=0;
00857 int uv;
00858 int vec1_x=0,vec1_y=0;
00859 int ioff,joff;
00860 imgpel *pMB = predMB;
00861
00862 int ii0,jj0,ii1,jj1,if1,jf1,if0,jf0;
00863 int mv_mul;
00864
00865
00866 int f1_x, f1_y, f2_x, f2_y, f3, f4, ifx;
00867 int yuv = dec_picture->chroma_format_idc - 1;
00868
00869 int ref_frame = mv[2];
00870
00871 get_mem2Dpel(&tmp_block, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
00872
00873
00874
00875 img->mb_x = x/BLOCK_SIZE;
00876 img->mb_y = y/BLOCK_SIZE;
00877 img->block_y = img->mb_y * BLOCK_SIZE;
00878 img->pix_c_y = img->mb_y * img->mb_cr_size_y/4;
00879 img->block_x = img->mb_x * BLOCK_SIZE;
00880 img->pix_c_x = img->mb_x * img->mb_cr_size_x/4;
00881
00882 mv_mul=4;
00883
00884
00885
00886 vec1_x = x*mv_mul + mv[0];
00887 vec1_y = y*mv_mul + mv[1];
00888 get_block_luma(PLANE_Y, listX[list][ref_frame], vec1_x,vec1_y, BLOCK_SIZE, BLOCK_SIZE, img, tmp_block);
00889
00890 for(jj=0;jj<MB_BLOCK_SIZE/BLOCK_SIZE;jj++)
00891 for(ii=0;ii<BLOCK_SIZE;ii++)
00892 img->mb_pred[LumaComp][jj][ii]=tmp_block[jj][ii];
00893
00894
00895 for (j = 0; j < 4; j++)
00896 {
00897 for (i = 0; i < 4; i++)
00898 {
00899 pMB[j*4+i] = img->mb_pred[LumaComp][j][i];
00900 }
00901 }
00902 pMB += 16;
00903
00904 if (dec_picture->chroma_format_idc != YUV400)
00905 {
00906
00907 f1_x = 64/(img->mb_cr_size_x);
00908 f2_x=f1_x-1;
00909
00910 f1_y = 64/(img->mb_cr_size_y);
00911 f2_y=f1_y-1;
00912
00913 f3=f1_x*f1_y;
00914 f4=f3>>1;
00915
00916 for(uv=0;uv<2;uv++)
00917 {
00918 joff = subblk_offset_y[yuv][0][0];
00919 j4=img->pix_c_y+joff;
00920 ioff = subblk_offset_x[yuv][0][0];
00921 i4=img->pix_c_x+ioff;
00922
00923 for(jj=0;jj<2;jj++)
00924 {
00925 jf=(j4+jj)/(img->mb_cr_size_y/4);
00926 for(ii=0;ii<2;ii++)
00927 {
00928 ifx=(i4+ii)/(img->mb_cr_size_x/4);
00929
00930 i1=(i4+ii)*f1_x + mv[0];
00931 j1=(j4+jj)*f1_y + mv[1];
00932
00933 ii0=iClip3 (0, dec_picture->size_x_cr-1, i1/f1_x);
00934 jj0=iClip3 (0, dec_picture->size_y_cr-1, j1/f1_y);
00935 ii1=iClip3 (0, dec_picture->size_x_cr-1, ((i1+f2_x)/f1_x));
00936 jj1=iClip3 (0, dec_picture->size_y_cr-1, ((j1+f2_y)/f1_y));
00937
00938 if1=(i1 & f2_x);
00939 jf1=(j1 & f2_y);
00940 if0=f1_x-if1;
00941 jf0=f1_y-jf1;
00942
00943 img->mb_pred[uv + 1][jj][ii]=(if0*jf0*listX[list][ref_frame]->imgUV[uv][jj0][ii0]+
00944 if1*jf0*listX[list][ref_frame]->imgUV[uv][jj0][ii1]+
00945 if0*jf1*listX[list][ref_frame]->imgUV[uv][jj1][ii0]+
00946 if1*jf1*listX[list][ref_frame]->imgUV[uv][jj1][ii1]+f4)/f3;
00947 }
00948 }
00949
00950 for (j = 0; j < 2; j++)
00951 {
00952 for (i = 0; i < 2; i++)
00953 {
00954 pMB[j*2+i] = img->mb_pred[uv + 1][j][i];
00955 }
00956 }
00957 pMB += 4;
00958
00959 }
00960 }
00961 free_mem2Dpel(tmp_block);
00962 }
00963
00971 static int compare_pic_by_pic_num_desc( const void *arg1, const void *arg2 )
00972 {
00973 if ( (*(StorablePicture**)arg1)->pic_num < (*(StorablePicture**)arg2)->pic_num)
00974 return 1;
00975 if ( (*(StorablePicture**)arg1)->pic_num > (*(StorablePicture**)arg2)->pic_num)
00976 return -1;
00977 else
00978 return 0;
00979 }
00980
00988 static int compare_pic_by_lt_pic_num_asc( const void *arg1, const void *arg2 )
00989 {
00990 if ( (*(StorablePicture**)arg1)->long_term_pic_num < (*(StorablePicture**)arg2)->long_term_pic_num)
00991 return -1;
00992 if ( (*(StorablePicture**)arg1)->long_term_pic_num > (*(StorablePicture**)arg2)->long_term_pic_num)
00993 return 1;
00994 else
00995 return 0;
00996 }
00997
01005 static int compare_pic_by_poc_asc( const void *arg1, const void *arg2 )
01006 {
01007 if ( (*(StorablePicture**)arg1)->poc < (*(StorablePicture**)arg2)->poc)
01008 return -1;
01009 if ( (*(StorablePicture**)arg1)->poc > (*(StorablePicture**)arg2)->poc)
01010 return 1;
01011 else
01012 return 0;
01013 }
01014
01015
01023 static int compare_pic_by_poc_desc( const void *arg1, const void *arg2 )
01024 {
01025 if ( (*(StorablePicture**)arg1)->poc < (*(StorablePicture**)arg2)->poc)
01026 return 1;
01027 if ( (*(StorablePicture**)arg1)->poc > (*(StorablePicture**)arg2)->poc)
01028 return -1;
01029 else
01030 return 0;
01031 }
01032
01040 static void CopyImgData(imgpel **inputY, imgpel ***inputUV, imgpel **outputY, imgpel ***outputUV,
01041 int img_width, int img_height, int img_width_cr, int img_height_cr)
01042 {
01043 int x, y;
01044
01045 for (y=0; y<img_height; y++)
01046 for (x=0; x<img_width; x++)
01047 outputY[y][x] = inputY[y][x];
01048
01049 for (y=0; y<img_height_cr; y++)
01050 for (x=0; x<img_width_cr; x++)
01051 {
01052 outputUV[0][y][x] = inputUV[0][y][x];
01053 outputUV[1][y][x] = inputUV[1][y][x];
01054 }
01055 }
01056
01064 static StorablePicture* get_last_ref_pic_from_dpb()
01065 {
01066 int used_size = dpb.used_size - 1;
01067 int i;
01068
01069 for(i = used_size; i >= 0; i--)
01070 {
01071 if (dpb.fs[i]->is_used==3)
01072 {
01073 if (((dpb.fs[i]->frame->used_for_reference) &&
01074 (!dpb.fs[i]->frame->is_long_term))
01075 )
01076 {
01077 return dpb.fs[i]->frame;
01078 }
01079 }
01080 }
01081
01082 return NULL;
01083 }
01084
01094 static void copy_to_conceal(StorablePicture *src, StorablePicture *dst, ImageParameters *img)
01095 {
01096 int i=0;
01097 int mv[3];
01098 int multiplier;
01099 imgpel *predMB, *storeYUV;
01100 int j, y, x, mb_height, mb_width, ii=0, jj=0;
01101 int uv;
01102 int mm, nn;
01103 int scale = 1;
01104
01105
01106 img->current_mb_nr = 0;
01107
01108 dst->PicSizeInMbs = src->PicSizeInMbs;
01109
01110 dst->slice_type = src->slice_type = img->conceal_slice_type;
01111
01112 dst->idr_flag = FALSE;
01113
01114 dst->no_output_of_prior_pics_flag = src->no_output_of_prior_pics_flag;
01115 dst->long_term_reference_flag = src->long_term_reference_flag;
01116 dst->adaptive_ref_pic_buffering_flag = src->adaptive_ref_pic_buffering_flag = 0;
01117 dst->chroma_format_idc = src->chroma_format_idc;
01118 dst->frame_mbs_only_flag = src->frame_mbs_only_flag;
01119 dst->frame_cropping_flag = src->frame_cropping_flag;
01120 dst->frame_cropping_rect_left_offset = src->frame_cropping_rect_left_offset;
01121 dst->frame_cropping_rect_right_offset = src->frame_cropping_rect_right_offset;
01122 dst->frame_cropping_rect_bottom_offset = src->frame_cropping_rect_bottom_offset;
01123 dst->frame_cropping_rect_top_offset = src->frame_cropping_rect_top_offset;
01124 dst->qp = src->qp;
01125 dst->slice_qp_delta = src->slice_qp_delta;
01126
01127 dec_picture = src;
01128
01129
01130 if (img->conceal_mode==1)
01131 {
01132
01133
01134 dst->PicWidthInMbs = src->PicWidthInMbs;
01135 dst->PicSizeInMbs = src->PicSizeInMbs;
01136
01137 CopyImgData( src->imgY, src->imgUV, dst->imgY, dst->imgUV, img->width, img->height, img->width_cr, img->height_cr);
01138 }
01139
01140
01141 if (img->conceal_mode==2)
01142 {
01143 if (dec_picture->chroma_format_idc != YUV400)
01144 {
01145 storeYUV = (imgpel *) malloc ( (16 + (img->mb_cr_size_x*img->mb_cr_size_y)*2/16) * sizeof (imgpel));
01146 }
01147 else
01148 {
01149 storeYUV = (imgpel *) malloc (16 * sizeof (imgpel));
01150 }
01151
01152 erc_img = img;
01153
01154 dst->PicWidthInMbs = src->PicWidthInMbs;
01155 dst->PicSizeInMbs = src->PicSizeInMbs;
01156 mb_width = dst->PicWidthInMbs;
01157 mb_height = (dst->PicSizeInMbs)/(dst->PicWidthInMbs);
01158 scale = (img->conceal_slice_type == B_SLICE) ? 2 : 1;
01159
01160 if(img->conceal_slice_type == B_SLICE)
01161 init_lists_for_non_reference_loss(dst->slice_type, img->currentSlice->structure);
01162 else
01163 init_lists(dst->slice_type, img->currentSlice->structure);
01164
01165 multiplier = BLOCK_SIZE;
01166
01167 for(i=0;i<mb_height*4;i++)
01168 {
01169 mm = i * BLOCK_SIZE;
01170 for(j=0;j<mb_width*4;j++)
01171 {
01172 nn = j * BLOCK_SIZE;
01173
01174 mv[0] = src->motion.mv[LIST_0][i][j][0] / scale;
01175 mv[1] = src->motion.mv[LIST_0][i][j][1] / scale;
01176 mv[2] = src->motion.ref_idx[LIST_0][i][j];
01177
01178 if(mv[2]<0)
01179 mv[2]=0;
01180
01181 dst->motion.mv[LIST_0][i][j][0] = mv[0];
01182 dst->motion.mv[LIST_0][i][j][1] = mv[1];
01183 dst->motion.ref_idx[LIST_0][i][j] = mv[2];
01184
01185 x = (j) * multiplier;
01186 y = (i) * multiplier;
01187
01188 if ((mm%16==0) && (nn%16==0))
01189 img->current_mb_nr++;
01190
01191 buildPredblockRegionYUV(erc_img, mv, x, y, storeYUV, LIST_0);
01192
01193 predMB = storeYUV;
01194
01195 for(ii=0;ii<multiplier;ii++)
01196 {
01197 for(jj=0;jj<multiplier;jj++)
01198 {
01199 dst->imgY[i*multiplier+ii][j*multiplier+jj] = predMB[ii*(multiplier)+jj];
01200 }
01201 }
01202
01203 predMB = predMB + (multiplier*multiplier);
01204
01205 if (dec_picture->chroma_format_idc != YUV400)
01206 {
01207
01208 for(uv=0;uv<2;uv++)
01209 {
01210 for(ii=0;ii< (multiplier/2);ii++)
01211 {
01212 for(jj=0;jj< (multiplier/2);jj++)
01213 {
01214 dst->imgUV[uv][i*multiplier/2 +ii][j*multiplier/2 +jj] = predMB[ii*(multiplier/2)+jj];
01215 }
01216 }
01217 predMB = predMB + (multiplier*multiplier/4);
01218 }
01219 }
01220 }
01221 }
01222 free(storeYUV);
01223 }
01224 }
01225
01234 static void
01235 copy_prev_pic_to_concealed_pic(StorablePicture *picture, ImageParameters *img)
01236 {
01237
01238 StorablePicture *ref_pic;
01239
01240 ref_pic = get_last_ref_pic_from_dpb();
01241
01242 assert(ref_pic != NULL);
01243
01244
01245 img->conceal_slice_type = P_SLICE;
01246 copy_to_conceal(ref_pic, picture, img);
01247 }
01248
01249
01260 void conceal_lost_frames(ImageParameters *img)
01261 {
01262 int CurrFrameNum;
01263 int UnusedShortTermFrameNum;
01264 StorablePicture *picture = NULL;
01265 int tmp1 = img->delta_pic_order_cnt[0];
01266 int tmp2 = img->delta_pic_order_cnt[1];
01267 int i;
01268
01269 img->delta_pic_order_cnt[0] = img->delta_pic_order_cnt[1] = 0;
01270
01271
01272
01273 if(img->IDR_concealment_flag == 1)
01274 {
01275
01276
01277 UnusedShortTermFrameNum = 0;
01278 img->last_ref_pic_poc = -img->poc_gap;
01279 img->earlier_missing_poc = 0;
01280 }
01281 else
01282 UnusedShortTermFrameNum = (img->pre_frame_num + 1) % img->MaxFrameNum;
01283
01284 CurrFrameNum = img->frame_num;
01285
01286 while (CurrFrameNum != UnusedShortTermFrameNum)
01287 {
01288 picture = alloc_storable_picture (FRAME, img->width, img->height, img->width_cr, img->height_cr);
01289
01290 picture->coded_frame = 1;
01291 picture->pic_num = UnusedShortTermFrameNum;
01292 picture->frame_num = UnusedShortTermFrameNum;
01293 picture->non_existing = 0;
01294 picture->is_output = 0;
01295 picture->used_for_reference = 1;
01296 picture->concealed_pic = 1;
01297
01298 picture->adaptive_ref_pic_buffering_flag = 0;
01299
01300 img->frame_num = UnusedShortTermFrameNum;
01301
01302 picture->top_poc=img->last_ref_pic_poc + img->ref_poc_gap;
01303 picture->bottom_poc=picture->top_poc;
01304 picture->frame_poc=picture->top_poc;
01305 picture->poc=picture->top_poc;
01306 img->last_ref_pic_poc = picture->poc;
01307
01308 copy_prev_pic_to_concealed_pic(picture, img);
01309
01310
01311 if(img->IDR_concealment_flag == 1)
01312 {
01313 picture->slice_type = I_SLICE;
01314 picture->idr_flag = TRUE;
01315 flush_dpb();
01316 picture->top_poc= 0;
01317 picture->bottom_poc=picture->top_poc;
01318 picture->frame_poc=picture->top_poc;
01319 picture->poc=picture->top_poc;
01320 img->last_ref_pic_poc = picture->poc;
01321 }
01322
01323 store_picture_in_dpb(picture);
01324
01325 picture=NULL;
01326
01327 img->pre_frame_num = UnusedShortTermFrameNum;
01328 UnusedShortTermFrameNum = (UnusedShortTermFrameNum + 1) % img->MaxFrameNum;
01329
01330
01331 for(i=16;i>0;i--)
01332 {
01333 ref_flag[i] = ref_flag[i-1];
01334 }
01335 ref_flag[0] = 0;
01336 }
01337 img->delta_pic_order_cnt[0] = tmp1;
01338 img->delta_pic_order_cnt[1] = tmp2;
01339 img->frame_num = CurrFrameNum;
01340 }
01341
01351 void update_ref_list_for_concealment()
01352 {
01353 unsigned i, j;
01354 for (i=0, j=0; i<dpb.used_size; i++)
01355 {
01356 if (dpb.fs[i]->concealment_reference)
01357 {
01358 dpb.fs_ref[j++]=dpb.fs[i];
01359 }
01360 }
01361
01362 dpb.ref_frames_in_buffer = active_pps->num_ref_idx_l0_active_minus1;
01363 }
01364
01374 void init_lists_for_non_reference_loss(int currSliceType, PictureStructure currPicStructure)
01375 {
01376 unsigned i;
01377 int j;
01378 int MaxFrameNum = 1 << (active_sps->log2_max_frame_num_minus4 + 4);
01379 int diff;
01380
01381 int list0idx = 0;
01382 int list0idx_1 = 0;
01383
01384 StorablePicture *tmp_s;
01385
01386 if (currPicStructure == FRAME)
01387 {
01388 for(i=0;i<dpb.ref_frames_in_buffer; i++)
01389 {
01390 if(dpb.fs[i]->concealment_reference == 1)
01391 {
01392 if(dpb.fs[i]->frame_num > img->frame_to_conceal)
01393 dpb.fs_ref[i]->frame_num_wrap = dpb.fs[i]->frame_num - MaxFrameNum;
01394 else
01395 dpb.fs_ref[i]->frame_num_wrap = dpb.fs[i]->frame_num;
01396 dpb.fs_ref[i]->frame->pic_num = dpb.fs_ref[i]->frame_num_wrap;
01397 }
01398 }
01399 }
01400
01401 if (currSliceType == P_SLICE)
01402 {
01403
01404 if (currPicStructure == FRAME)
01405 {
01406 for(i=0;i<dpb.used_size; i++)
01407 {
01408 if(dpb.fs[i]->concealment_reference == 1)
01409 {
01410 listX[0][list0idx++] = dpb.fs[i]->frame;
01411 }
01412 }
01413
01414 qsort((void *)listX[0], list0idx, sizeof(StorablePicture*), compare_pic_by_pic_num_desc);
01415 listXsize[0] = list0idx;
01416 }
01417 }
01418
01419 if (currSliceType == B_SLICE)
01420 {
01421 if (currPicStructure == FRAME)
01422 {
01423
01424 for(i=0;i<dpb.used_size; i++)
01425 {
01426 if(dpb.fs[i]->concealment_reference == 1)
01427 {
01428 if(img->earlier_missing_poc > dpb.fs[i]->frame->poc)
01429 listX[0][list0idx++] = dpb.fs[i]->frame;
01430 }
01431 }
01432
01433 qsort((void *)listX[0], list0idx, sizeof(StorablePicture*), compare_pic_by_poc_desc);
01434 list0idx_1 = list0idx;
01435
01436
01437 for(i=0;i<dpb.used_size; i++)
01438 {
01439 if(dpb.fs[i]->concealment_reference == 1)
01440 {
01441 if(img->earlier_missing_poc < dpb.fs[i]->frame->poc)
01442 listX[0][list0idx++] = dpb.fs[i]->frame;
01443 }
01444 }
01445
01446 qsort((void *)&listX[0][list0idx_1], list0idx-list0idx_1, sizeof(StorablePicture*), compare_pic_by_poc_asc);
01447
01448 for (j=0; j<list0idx_1; j++)
01449 {
01450 listX[1][list0idx-list0idx_1+j]=listX[0][j];
01451 }
01452 for (j=list0idx_1; j<list0idx; j++)
01453 {
01454 listX[1][j-list0idx_1]=listX[0][j];
01455 }
01456
01457 listXsize[0] = listXsize[1] = list0idx;
01458
01459 qsort((void *)&listX[0][listXsize[0]], list0idx-listXsize[0], sizeof(StorablePicture*), compare_pic_by_lt_pic_num_asc);
01460 qsort((void *)&listX[1][listXsize[0]], list0idx-listXsize[0], sizeof(StorablePicture*), compare_pic_by_lt_pic_num_asc);
01461 listXsize[0] = listXsize[1] = list0idx;
01462 }
01463 }
01464
01465 if ((listXsize[0] == listXsize[1]) && (listXsize[0] > 1))
01466 {
01467
01468 diff=0;
01469 for (j = 0; j< listXsize[0]; j++)
01470 {
01471 if (listX[0][j]!=listX[1][j])
01472 diff=1;
01473 }
01474 if (!diff)
01475 {
01476 tmp_s = listX[1][0];
01477 listX[1][0]=listX[1][1];
01478 listX[1][1]=tmp_s;
01479 }
01480 }
01481
01482
01483
01484 listXsize[0] = imin (listXsize[0], (int)active_sps->num_ref_frames);
01485 listXsize[1] = imin (listXsize[1], (int)active_sps->num_ref_frames);
01486
01487 listXsize[1] = 0;
01488
01489 for (i=listXsize[0]; i< (MAX_LIST_SIZE) ; i++)
01490 {
01491 listX[0][i] = NULL;
01492 }
01493 for (i=listXsize[1]; i< (MAX_LIST_SIZE) ; i++)
01494 {
01495 listX[1][i] = NULL;
01496 }
01497 }
01498
01499
01510 StorablePicture *get_pic_from_dpb(int missingpoc, unsigned int *pos)
01511 {
01512 int used_size = dpb.used_size - 1;
01513 int i, concealfrom = 0;
01514
01515 if(img->conceal_mode == 1)
01516 concealfrom = missingpoc - img->poc_gap;
01517 else if (img->conceal_mode == 2)
01518 concealfrom = missingpoc + img->poc_gap;
01519
01520 for(i = used_size; i >= 0; i--)
01521 {
01522 if(dpb.fs[i]->poc == concealfrom)
01523 {
01524 *pos = i;
01525 return dpb.fs[i]->frame;
01526 }
01527 }
01528
01529 return NULL;
01530 }
01531
01541 int comp(const void *i, const void *j)
01542 {
01543 return *(int *)i - *(int *)j;
01544 }
01545
01555 struct concealment_node * init_node( StorablePicture* picture, int missingpoc )
01556 {
01557 struct concealment_node *ptr;
01558
01559 ptr = (struct concealment_node *) calloc( 1, sizeof(struct concealment_node ) );
01560
01561 if( ptr == NULL )
01562 return (struct concealment_node *) NULL;
01563 else {
01564 ptr->picture = picture;
01565 ptr->missingpocs = missingpoc;
01566 ptr->next = NULL;
01567 return ptr;
01568 }
01569 }
01570
01579 void print_node( struct concealment_node *ptr )
01580 {
01581 printf("Missing POC=%d\n", ptr->missingpocs );
01582 }
01583
01584
01593 void print_list( struct concealment_node *ptr )
01594 {
01595 while( ptr != NULL )
01596 {
01597 print_node( ptr );
01598 ptr = ptr->next;
01599 }
01600 }
01601
01611 void add_node( struct concealment_node *concealment_new )
01612 {
01613 if( concealment_head == NULL )
01614 {
01615 concealment_end = concealment_head = concealment_new;
01616 return;
01617 }
01618 concealment_end->next = concealment_new;
01619 concealment_end = concealment_new;
01620 }
01621
01622
01632 void delete_node( struct concealment_node *ptr )
01633 {
01634
01635 if( ptr == concealment_head )
01636 {
01637 concealment_head = concealment_head->next;
01638 if( concealment_end == ptr )
01639 concealment_end = concealment_end->next;
01640 free(ptr);
01641 }
01642 }
01643
01652 void delete_list( struct concealment_node *ptr )
01653 {
01654 struct concealment_node *temp;
01655
01656 if( concealment_head == NULL ) return;
01657
01658 if( ptr == concealment_head )
01659 {
01660 concealment_head = NULL;
01661 concealment_end = NULL;
01662 }
01663 else
01664 {
01665 temp = concealment_head;
01666
01667 while( temp->next != ptr )
01668 temp = temp->next;
01669 concealment_end = temp;
01670 }
01671
01672 while( ptr != NULL )
01673 {
01674 temp = ptr->next;
01675 free( ptr );
01676 ptr = temp;
01677 }
01678 }
01679
01691 void conceal_non_ref_pics(int diff)
01692 {
01693 int missingpoc = 0;
01694 unsigned int i, pos = 0;
01695 StorablePicture *conceal_from_picture = NULL;
01696 StorablePicture *conceal_to_picture = NULL;
01697 struct concealment_node *concealment_ptr = NULL;
01698 int temp_used_size = dpb.used_size;
01699
01700 if(dpb.used_size == 0 )
01701 return;
01702
01703 qsort(pocs_in_dpb, dpb.size, sizeof(int), comp);
01704
01705 for(i=0;i<dpb.size-diff;i++)
01706 {
01707 dpb.used_size = dpb.size;
01708 if((pocs_in_dpb[i+1]-pocs_in_dpb[i])>img->poc_gap)
01709 {
01710 conceal_to_picture = alloc_storable_picture (FRAME, img->width, img->height, img->width_cr, img->height_cr);
01711
01712 missingpoc = pocs_in_dpb[i] + img->poc_gap;
01713
01714
01715
01716 if(missingpoc > img->earlier_missing_poc)
01717 {
01718 img->earlier_missing_poc = missingpoc;
01719 conceal_to_picture->top_poc= missingpoc;
01720 conceal_to_picture->bottom_poc=missingpoc;
01721 conceal_to_picture->frame_poc=missingpoc;
01722 conceal_to_picture->poc=missingpoc;
01723 conceal_from_picture = get_pic_from_dpb(missingpoc, &pos);
01724
01725 assert(conceal_from_picture != NULL);
01726
01727 dpb.used_size = pos+1;
01728
01729 img->frame_to_conceal = conceal_from_picture->frame_num + 1;
01730
01731 update_ref_list_for_concealment();
01732 img->conceal_slice_type = B_SLICE;
01733 copy_to_conceal(conceal_from_picture, conceal_to_picture, img);
01734 concealment_ptr = init_node( conceal_to_picture, missingpoc );
01735 add_node(concealment_ptr);
01736
01737
01738 }
01739 }
01740 }
01741
01742
01743
01744 dpb.used_size = temp_used_size;
01745 }
01746
01756 void sliding_window_poc_management(StorablePicture *p)
01757 {
01758 unsigned int i;
01759
01760 if (dpb.used_size == dpb.size)
01761 {
01762 for(i=0;i<dpb.size-1; i++)
01763 pocs_in_dpb[i] = pocs_in_dpb[i+1];
01764 }
01765
01766
01767 }
01768
01769
01781 void write_lost_non_ref_pic(int poc, int p_out)
01782 {
01783 FrameStore concealment_fs;
01784 if(poc > 0)
01785 {
01786 if((poc - dpb.last_output_poc) > img->poc_gap)
01787 {
01788
01789 concealment_fs.frame = concealment_head->picture;
01790 concealment_fs.is_output = 0;
01791 concealment_fs.is_reference = 0;
01792 concealment_fs.is_used = 3;
01793
01794 write_stored_frame(&concealment_fs, p_out);
01795 delete_node(concealment_head);
01796 }
01797 }
01798 }
01799
01809 void write_lost_ref_after_idr(int pos)
01810 {
01811 int temp = 1;
01812
01813 if(last_out_fs->frame == NULL)
01814 {
01815 last_out_fs->frame = alloc_storable_picture (FRAME, img->width, img->height,
01816 img->width_cr, img->height_cr);
01817 last_out_fs->is_used = 3;
01818 }
01819
01820 if(img->conceal_mode == 2)
01821 {
01822 temp = 2;
01823 img->conceal_mode = 1;
01824 }
01825 copy_to_conceal(dpb.fs[pos]->frame, last_out_fs->frame, img);
01826
01827 img->conceal_mode = temp;
01828 }
01829