📄 erc_do_i.c
字号:
if ( condition[ (currRow+step)*maxColumn + currColumn ] > threshold )
{
predBlocks[6] = 1;
srcCounter++;
}
return srcCounter;
}
/*!
************************************************************************
* \brief
* Core for the Intra blocks concealment.
* It is called for each color component (Y,U,V) seperately
* Finds the corrupted blocks and calls pixel interpolation functions
* to correct them, one block at a time.
* Scanning is done vertically and each corrupted column is corrected
* bi-directionally, i.e., first block, last block, first block+1, last block -1 ...
* \param lastColumn
* Number of block columns in the frame
* \param lastRow
* Number of block rows in the frame
* \param comp
* color component
* \param recfr
* Reconstructed frame buffer
* \param picSizeX
* Width of the frame in pixels
* \param condition
* The block condition (ok, lost) table
************************************************************************
*/
static void concealBlocks( int lastColumn, int lastRow, int comp, frame *recfr, int32 picSizeX, int *condition )
{
int row, column, srcCounter = 0, thr = ERC_BLOCK_CORRUPTED,
lastCorruptedRow = -1, firstCorruptedRow = -1, currRow = 0,
areaHeight = 0, i = 0, smoothColumn = 0;
int predBlocks[8], step = 1;
/* in the Y component do the concealment MB-wise (not block-wise):
this is useful if only whole MBs can be damaged or lost */
if ( comp == 0 )
step = 2;
else
step = 1;
for ( column = 0; column < lastColumn; column += step )
{
for ( row = 0; row < lastRow; row += step )
{
if ( condition[row*lastColumn+column] <= thr )
{
firstCorruptedRow = row;
/* find the last row which has corrupted blocks (in same continuous area) */
for ( lastCorruptedRow = row+step; lastCorruptedRow < lastRow; lastCorruptedRow += step )
{
/* check blocks in the current column */
if ( condition[ lastCorruptedRow*lastColumn + column ] > thr )
{
/* current one is already OK, so the last was the previous one */
lastCorruptedRow -= step;
break;
}
}
if ( lastCorruptedRow >= lastRow )
{
/* correct only from above */
lastCorruptedRow = lastRow-step;
for ( currRow = firstCorruptedRow; currRow < lastRow; currRow += step )
{
srcCounter = ercCollect8PredBlocks( predBlocks, currRow, column, condition, lastRow, lastColumn, step, 1 );
switch( comp )
{
case 0 :
ercPixConcealIMB( recfr->yptr, currRow, column, predBlocks, picSizeX, 2 );
break;
case 1 :
ercPixConcealIMB( recfr->uptr, currRow, column, predBlocks, (picSizeX>>1), 1 );
break;
case 2 :
ercPixConcealIMB( recfr->vptr, currRow, column, predBlocks, (picSizeX>>1), 1 );
break;
}
if ( comp == 0 )
{
condition[ currRow*lastColumn+column] = ERC_BLOCK_CONCEALED;
condition[ currRow*lastColumn+column + 1] = ERC_BLOCK_CONCEALED;
condition[ currRow*lastColumn+column + lastColumn] = ERC_BLOCK_CONCEALED;
condition[ currRow*lastColumn+column + lastColumn + 1] = ERC_BLOCK_CONCEALED;
}
else
{
condition[ currRow*lastColumn+column] = ERC_BLOCK_CONCEALED;
}
}
row = lastRow;
}
else if ( firstCorruptedRow == 0 )
{
/* correct only from below */
for ( currRow = lastCorruptedRow; currRow >= 0; currRow -= step )
{
srcCounter = ercCollect8PredBlocks( predBlocks, currRow, column, condition, lastRow, lastColumn, step, 1 );
switch( comp )
{
case 0 :
ercPixConcealIMB( recfr->yptr, currRow, column, predBlocks, picSizeX, 2 );
break;
case 1 :
ercPixConcealIMB( recfr->uptr, currRow, column, predBlocks, (picSizeX>>1), 1 );
break;
case 2 :
ercPixConcealIMB( recfr->vptr, currRow, column, predBlocks, (picSizeX>>1), 1 );
break;
}
if ( comp == 0 )
{
condition[ currRow*lastColumn+column] = ERC_BLOCK_CONCEALED;
condition[ currRow*lastColumn+column + 1] = ERC_BLOCK_CONCEALED;
condition[ currRow*lastColumn+column + lastColumn] = ERC_BLOCK_CONCEALED;
condition[ currRow*lastColumn+column + lastColumn + 1] = ERC_BLOCK_CONCEALED;
}
else
{
condition[ currRow*lastColumn+column] = ERC_BLOCK_CONCEALED;
}
}
row = lastCorruptedRow+step;
}
else
{
/* correct bi-directionally */
row = lastCorruptedRow+step;
areaHeight = lastCorruptedRow-firstCorruptedRow+step;
/*
* Conceal the corrupted area switching between the up and the bottom rows
*/
for ( i = 0; i < areaHeight; i += step )
{
if ( i % 2 )
{
currRow = lastCorruptedRow;
lastCorruptedRow -= step;
}
else
{
currRow = firstCorruptedRow;
firstCorruptedRow += step;
}
if (smoothColumn > 0)
{
srcCounter = ercCollectColumnBlocks( predBlocks, currRow, column, condition, lastRow, lastColumn, step );
}
else
{
srcCounter = ercCollect8PredBlocks( predBlocks, currRow, column, condition, lastRow, lastColumn, step, 1 );
}
switch( comp )
{
case 0 :
ercPixConcealIMB( recfr->yptr, currRow, column, predBlocks, picSizeX, 2 );
break;
case 1 :
ercPixConcealIMB( recfr->uptr, currRow, column, predBlocks, (picSizeX>>1), 1 );
break;
case 2 :
ercPixConcealIMB( recfr->vptr, currRow, column, predBlocks, (picSizeX>>1), 1 );
break;
}
if ( comp == 0 )
{
condition[ currRow*lastColumn+column] = ERC_BLOCK_CONCEALED;
condition[ currRow*lastColumn+column + 1] = ERC_BLOCK_CONCEALED;
condition[ currRow*lastColumn+column + lastColumn] = ERC_BLOCK_CONCEALED;
condition[ currRow*lastColumn+column + lastColumn + 1] = ERC_BLOCK_CONCEALED;
}
else
{
condition[ currRow*lastColumn+column ] = ERC_BLOCK_CONCEALED;
}
}
}
lastCorruptedRow = -1;
firstCorruptedRow = -1;
}
}
}
}
/*!
************************************************************************
* \brief
* Does the actual pixel based interpolation for block[]
* using weighted average
* \param src[]
* pointers to neighboring source blocks
* \param block
* destination block
* \param blockSize
* 16 for Y, 8 for U/V components
* \param frameWidth
* Width of the frame in pixels
************************************************************************
*/
static void pixMeanInterpolateBlock( imgpel *src[], imgpel *block, int blockSize, int frameWidth )
{
int row, column, k, tmp, srcCounter = 0, weight = 0, bmax = blockSize - 1;
k = 0;
for ( row = 0; row < blockSize; row++ )
{
for ( column = 0; column < blockSize; column++ )
{
tmp = 0;
srcCounter = 0;
/* above */
if ( src[4] != NULL )
{
weight = blockSize-row;
tmp += weight * (*(src[4]+bmax*frameWidth+column));
srcCounter += weight;
}
/* left */
if ( src[5] != NULL )
{
weight = blockSize-column;
tmp += weight * (*(src[5]+row*frameWidth+bmax));
srcCounter += weight;
}
/* below */
if ( src[6] != NULL )
{
weight = row+1;
tmp += weight * (*(src[6]+column));
srcCounter += weight;
}
/* right */
if ( src[7] != NULL )
{
weight = column+1;
tmp += weight * (*(src[7]+row*frameWidth));
srcCounter += weight;
}
if ( srcCounter > 0 )
block[ k + column ] = (byte)(tmp/srcCounter);
else
block[ k + column ] = img->dc_pred_value; //FREXT
}
k += frameWidth;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -