00001
00018 #include "global.h"
00019 #include "erc_do.h"
00020
00021 static void concealBlocks ( ImageParameters *p_Img, int lastColumn, int lastRow, int comp, frame *recfr, int picSizeX, int *condition );
00022 static void pixMeanInterpolateBlock( ImageParameters *p_Img, imgpel *src[], imgpel *block, int blockSize, int frameWidth );
00023
00044 int ercConcealIntraFrame( ImageParameters *p_Img, frame *recfr, int picSizeX, int picSizeY, ercVariables_t *errorVar )
00045 {
00046 int lastColumn = 0, lastRow = 0;
00047
00048
00049 if ( errorVar && errorVar->concealment )
00050 {
00051
00052 if ( errorVar->nOfCorruptedSegments )
00053 {
00054
00055 lastRow = (int) (picSizeY>>3);
00056 lastColumn = (int) (picSizeX>>3);
00057 concealBlocks( p_Img, lastColumn, lastRow, 0, recfr, picSizeX, errorVar->yCondition );
00058
00059
00060 lastRow = (int) (picSizeY>>4);
00061 lastColumn = (int) (picSizeX>>4);
00062 concealBlocks( p_Img, lastColumn, lastRow, 1, recfr, picSizeX, errorVar->uCondition );
00063
00064
00065 concealBlocks( p_Img, lastColumn, lastRow, 2, recfr, picSizeX, errorVar->vCondition );
00066 }
00067 return 1;
00068 }
00069 else
00070 return 0;
00071 }
00072
00094 void ercPixConcealIMB(ImageParameters *p_Img, imgpel *currFrame, int row, int column, int predBlocks[], int frameWidth, int mbWidthInBlocks)
00095 {
00096 imgpel *src[8]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
00097 imgpel *currBlock = NULL;
00098
00099
00100 if (predBlocks[0])
00101 src[0] = currFrame + (row-mbWidthInBlocks)*frameWidth*8 + (column+mbWidthInBlocks)*8;
00102 if (predBlocks[1])
00103 src[1] = currFrame + (row-mbWidthInBlocks)*frameWidth*8 + (column-mbWidthInBlocks)*8;
00104 if (predBlocks[2])
00105 src[2] = currFrame + (row+mbWidthInBlocks)*frameWidth*8 + (column-mbWidthInBlocks)*8;
00106 if (predBlocks[3])
00107 src[3] = currFrame + (row+mbWidthInBlocks)*frameWidth*8 + (column+mbWidthInBlocks)*8;
00108 if (predBlocks[4])
00109 src[4] = currFrame + (row-mbWidthInBlocks)*frameWidth*8 + column*8;
00110 if (predBlocks[5])
00111 src[5] = currFrame + row*frameWidth*8 + (column-mbWidthInBlocks)*8;
00112 if (predBlocks[6])
00113 src[6] = currFrame + (row+mbWidthInBlocks)*frameWidth*8 + column*8;
00114 if (predBlocks[7])
00115 src[7] = currFrame + row*frameWidth*8 + (column+mbWidthInBlocks)*8;
00116
00117 currBlock = currFrame + row*frameWidth*8 + column*8;
00118 pixMeanInterpolateBlock( p_Img, src, currBlock, mbWidthInBlocks*8, frameWidth );
00119 }
00120
00154 int ercCollect8PredBlocks( int predBlocks[], int currRow, int currColumn, int *condition,
00155 int maxRow, int maxColumn, int step, byte fNoCornerNeigh )
00156 {
00157 int srcCounter = 0;
00158 int srcCountMin = (fNoCornerNeigh ? 2 : 4);
00159 int threshold = ERC_BLOCK_OK;
00160
00161 memset( predBlocks, 0, 8*sizeof(int) );
00162
00163
00164 do
00165 {
00166 srcCounter = 0;
00167
00168 if (currRow > 0 && condition[ (currRow-1)*maxColumn + currColumn ] >= threshold )
00169 {
00170 predBlocks[4] = condition[ (currRow-1)*maxColumn + currColumn ];
00171 srcCounter++;
00172 }
00173
00174 if ( currRow < (maxRow-step) && condition[ (currRow+step)*maxColumn + currColumn ] >= threshold )
00175 {
00176 predBlocks[6] = condition[ (currRow+step)*maxColumn + currColumn ];
00177 srcCounter++;
00178 }
00179
00180 if ( currColumn > 0 )
00181 {
00182
00183 if ( condition[ currRow*maxColumn + currColumn - 1 ] >= threshold )
00184 {
00185 predBlocks[5] = condition[ currRow*maxColumn + currColumn - 1 ];
00186 srcCounter++;
00187 }
00188
00189 if ( !fNoCornerNeigh )
00190 {
00191
00192 if ( currRow > 0 && condition[ (currRow-1)*maxColumn + currColumn - 1 ] >= threshold )
00193 {
00194 predBlocks[1] = condition[ (currRow-1)*maxColumn + currColumn - 1 ];
00195 srcCounter++;
00196 }
00197
00198 if ( currRow < (maxRow-step) && condition[ (currRow+step)*maxColumn + currColumn - 1 ] >= threshold )
00199 {
00200 predBlocks[2] = condition[ (currRow+step)*maxColumn + currColumn - 1 ];
00201 srcCounter++;
00202 }
00203 }
00204 }
00205
00206 if ( currColumn < (maxColumn-step) )
00207 {
00208
00209 if ( condition[ currRow*maxColumn+currColumn + step ] >= threshold )
00210 {
00211 predBlocks[7] = condition[ currRow*maxColumn+currColumn + step ];
00212 srcCounter++;
00213 }
00214
00215 if ( !fNoCornerNeigh )
00216 {
00217
00218 if ( currRow > 0 && condition[ (currRow-1)*maxColumn + currColumn + step ] >= threshold )
00219 {
00220 predBlocks[0] = condition[ (currRow-1)*maxColumn + currColumn + step ];
00221 srcCounter++;
00222 }
00223
00224 if ( currRow < (maxRow-step) && condition[ (currRow+step)*maxColumn + currColumn + step ] >= threshold )
00225 {
00226 predBlocks[3] = condition[ (currRow+step)*maxColumn + currColumn + step ];
00227 srcCounter++;
00228 }
00229 }
00230 }
00231
00232 threshold--;
00233 if (threshold < ERC_BLOCK_CONCEALED)
00234 break;
00235 } while ( srcCounter < srcCountMin);
00236
00237 return srcCounter;
00238 }
00239
00263 int ercCollectColumnBlocks( int predBlocks[], int currRow, int currColumn, int *condition, int maxRow, int maxColumn, int step )
00264 {
00265 int srcCounter = 0, threshold = ERC_BLOCK_CORRUPTED;
00266
00267 memset( predBlocks, 0, 8*sizeof(int) );
00268
00269
00270 if ( condition[ (currRow-1)*maxColumn + currColumn ] > threshold )
00271 {
00272 predBlocks[4] = 1;
00273 srcCounter++;
00274 }
00275 if ( condition[ (currRow+step)*maxColumn + currColumn ] > threshold )
00276 {
00277 predBlocks[6] = 1;
00278 srcCounter++;
00279 }
00280
00281 return srcCounter;
00282 }
00283
00309 static void concealBlocks( ImageParameters *p_Img, int lastColumn, int lastRow, int comp, frame *recfr, int picSizeX, int *condition )
00310 {
00311 int row, column, srcCounter = 0, thr = ERC_BLOCK_CORRUPTED,
00312 lastCorruptedRow = -1, firstCorruptedRow = -1, currRow = 0,
00313 areaHeight = 0, i = 0, smoothColumn = 0;
00314 int predBlocks[8], step = 1;
00315
00316
00317
00318 if ( comp == 0 )
00319 step = 2;
00320 else
00321 step = 1;
00322
00323 for ( column = 0; column < lastColumn; column += step )
00324 {
00325 for ( row = 0; row < lastRow; row += step )
00326 {
00327 if ( condition[row*lastColumn+column] <= thr )
00328 {
00329 firstCorruptedRow = row;
00330
00331 for ( lastCorruptedRow = row+step; lastCorruptedRow < lastRow; lastCorruptedRow += step )
00332 {
00333
00334 if ( condition[ lastCorruptedRow*lastColumn + column ] > thr )
00335 {
00336
00337 lastCorruptedRow -= step;
00338 break;
00339 }
00340 }
00341 if ( lastCorruptedRow >= lastRow )
00342 {
00343
00344 lastCorruptedRow = lastRow-step;
00345 for ( currRow = firstCorruptedRow; currRow < lastRow; currRow += step )
00346 {
00347 srcCounter = ercCollect8PredBlocks( predBlocks, currRow, column, condition, lastRow, lastColumn, step, 1 );
00348
00349 switch( comp )
00350 {
00351 case 0 :
00352 ercPixConcealIMB( p_Img, recfr->yptr, currRow, column, predBlocks, picSizeX, 2 );
00353 break;
00354 case 1 :
00355 ercPixConcealIMB( p_Img, recfr->uptr, currRow, column, predBlocks, (picSizeX>>1), 1 );
00356 break;
00357 case 2 :
00358 ercPixConcealIMB( p_Img, recfr->vptr, currRow, column, predBlocks, (picSizeX>>1), 1 );
00359 break;
00360 }
00361
00362 if ( comp == 0 )
00363 {
00364 condition[ currRow*lastColumn+column] = ERC_BLOCK_CONCEALED;
00365 condition[ currRow*lastColumn+column + 1] = ERC_BLOCK_CONCEALED;
00366 condition[ currRow*lastColumn+column + lastColumn] = ERC_BLOCK_CONCEALED;
00367 condition[ currRow*lastColumn+column + lastColumn + 1] = ERC_BLOCK_CONCEALED;
00368 }
00369 else
00370 {
00371 condition[ currRow*lastColumn+column] = ERC_BLOCK_CONCEALED;
00372 }
00373
00374 }
00375 row = lastRow;
00376 }
00377 else if ( firstCorruptedRow == 0 )
00378 {
00379
00380 for ( currRow = lastCorruptedRow; currRow >= 0; currRow -= step )
00381 {
00382 srcCounter = ercCollect8PredBlocks( predBlocks, currRow, column, condition, lastRow, lastColumn, step, 1 );
00383
00384 switch( comp )
00385 {
00386 case 0 :
00387 ercPixConcealIMB( p_Img, recfr->yptr, currRow, column, predBlocks, picSizeX, 2 );
00388 break;
00389 case 1 :
00390 ercPixConcealIMB( p_Img, recfr->uptr, currRow, column, predBlocks, (picSizeX>>1), 1 );
00391 break;
00392 case 2 :
00393 ercPixConcealIMB( p_Img, recfr->vptr, currRow, column, predBlocks, (picSizeX>>1), 1 );
00394 break;
00395 }
00396
00397 if ( comp == 0 )
00398 {
00399 condition[ currRow*lastColumn+column] = ERC_BLOCK_CONCEALED;
00400 condition[ currRow*lastColumn+column + 1] = ERC_BLOCK_CONCEALED;
00401 condition[ currRow*lastColumn+column + lastColumn] = ERC_BLOCK_CONCEALED;
00402 condition[ currRow*lastColumn+column + lastColumn + 1] = ERC_BLOCK_CONCEALED;
00403 }
00404 else
00405 {
00406 condition[ currRow*lastColumn+column] = ERC_BLOCK_CONCEALED;
00407 }
00408
00409 }
00410
00411 row = lastCorruptedRow+step;
00412 }
00413 else
00414 {
00415
00416
00417 row = lastCorruptedRow+step;
00418 areaHeight = lastCorruptedRow-firstCorruptedRow+step;
00419
00420
00421 for ( i = 0; i < areaHeight; i += step )
00422 {
00423 if ( i % 2 )
00424 {
00425 currRow = lastCorruptedRow;
00426 lastCorruptedRow -= step;
00427 }
00428 else
00429 {
00430 currRow = firstCorruptedRow;
00431 firstCorruptedRow += step;
00432 }
00433
00434 if (smoothColumn > 0)
00435 {
00436 srcCounter = ercCollectColumnBlocks( predBlocks, currRow, column, condition, lastRow, lastColumn, step );
00437 }
00438 else
00439 {
00440 srcCounter = ercCollect8PredBlocks( predBlocks, currRow, column, condition, lastRow, lastColumn, step, 1 );
00441 }
00442
00443 switch( comp )
00444 {
00445 case 0 :
00446 ercPixConcealIMB( p_Img, recfr->yptr, currRow, column, predBlocks, picSizeX, 2 );
00447 break;
00448
00449 case 1 :
00450 ercPixConcealIMB( p_Img, recfr->uptr, currRow, column, predBlocks, (picSizeX>>1), 1 );
00451 break;
00452
00453 case 2 :
00454 ercPixConcealIMB( p_Img, recfr->vptr, currRow, column, predBlocks, (picSizeX>>1), 1 );
00455 break;
00456 }
00457
00458 if ( comp == 0 )
00459 {
00460 condition[ currRow*lastColumn+column] = ERC_BLOCK_CONCEALED;
00461 condition[ currRow*lastColumn+column + 1] = ERC_BLOCK_CONCEALED;
00462 condition[ currRow*lastColumn+column + lastColumn] = ERC_BLOCK_CONCEALED;
00463 condition[ currRow*lastColumn+column + lastColumn + 1] = ERC_BLOCK_CONCEALED;
00464 }
00465 else
00466 {
00467 condition[ currRow*lastColumn+column ] = ERC_BLOCK_CONCEALED;
00468 }
00469 }
00470 }
00471
00472 lastCorruptedRow = -1;
00473 firstCorruptedRow = -1;
00474
00475 }
00476 }
00477 }
00478 }
00479
00497 static void pixMeanInterpolateBlock( ImageParameters *p_Img, imgpel *src[], imgpel *block, int blockSize, int frameWidth )
00498 {
00499 int row, column, k, tmp, srcCounter = 0, weight = 0, bmax = blockSize - 1;
00500
00501 k = 0;
00502 for ( row = 0; row < blockSize; row++ )
00503 {
00504 for ( column = 0; column < blockSize; column++ )
00505 {
00506 tmp = 0;
00507 srcCounter = 0;
00508
00509 if ( src[4] != NULL )
00510 {
00511 weight = blockSize-row;
00512 tmp += weight * (*(src[4]+bmax*frameWidth+column));
00513 srcCounter += weight;
00514 }
00515
00516 if ( src[5] != NULL )
00517 {
00518 weight = blockSize-column;
00519 tmp += weight * (*(src[5]+row*frameWidth+bmax));
00520 srcCounter += weight;
00521 }
00522
00523 if ( src[6] != NULL )
00524 {
00525 weight = row+1;
00526 tmp += weight * (*(src[6]+column));
00527 srcCounter += weight;
00528 }
00529
00530 if ( src[7] != NULL )
00531 {
00532 weight = column+1;
00533 tmp += weight * (*(src[7]+row*frameWidth));
00534 srcCounter += weight;
00535 }
00536
00537 if ( srcCounter > 0 )
00538 block[ k + column ] = (byte)(tmp/srcCounter);
00539 else
00540 block[ k + column ] = blockSize == 8 ? p_Img->dc_pred_value_comp[1] : p_Img->dc_pred_value_comp[0];
00541 }
00542 k += frameWidth;
00543 }
00544 }