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