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