📄 postproc.c
字号:
* INPUTS : None * * OUTPUTS : None * * RETURNS : None * * FUNCTION : Filter both horizontal and vertical edge in a band * * SPECIAL NOTES : * * REFERENCE : * * ERRORS : None. * ****************************************************************************/ void DeblockLoopFilteredBand( PB_INSTANCE *pbi, UINT8 *SrcPtr, UINT8 *DesPtr, UINT32 PlaneLineStep, UINT32 FragsAcross, UINT32 StartFrag, UINT32 *QuantScale ) { UINT32 j,k; UINT32 CurrentFrag=StartFrag; INT32 QStep; INT32 FLimit; UINT8 *Src, *Des; INT32 x[10]; INT32 pitch1, pitch2, pitch3, pitch4, pitch5; INT32 Sum1, Sum2; pitch1=PlaneLineStep; pitch2=PlaneLineStep * 2; pitch3=PlaneLineStep * 3; pitch4=PlaneLineStep * 4; pitch5=PlaneLineStep * 5; while(CurrentFrag < StartFrag + FragsAcross) { Src=SrcPtr+8*(CurrentFrag-StartFrag); Des=DesPtr+8*(CurrentFrag-StartFrag); { QStep = QuantScale[pbi->FragQIndex[CurrentFrag+FragsAcross]]; FLimit = ( QStep * 3 ) >> 2; for( j=0; j<8 ; j++) { x[0] = Src[-pitch5]; x[1] = Src[-pitch4]; x[2] = Src[-pitch3]; x[3] = Src[-pitch2]; x[4] = Src[-pitch1]; x[5] = Src[ 0]; x[6] = Src[+pitch1]; x[7] = Src[+pitch2]; x[8] = Src[+pitch3]; x[9] = Src[+pitch4]; Sum1=Sum2=0; for(k=1;k<=4;k++) { Sum1 += abs(x[k]-x[k-1]); Sum2 += abs(x[k+4]-x[k+5]); } pbi->FragmentVariances[CurrentFrag] +=((Sum1>255)?255:Sum1); pbi->FragmentVariances[CurrentFrag + FragsAcross] += ((Sum2>255)?255:Sum2); if( Sum1 < FLimit && Sum2 < FLimit && (x[5] - x[4]) < QStep && (x[4] - x[5]) < QStep ) { // low pass filtering (LPF7: 1 1 1 2 1 1 1) Des[-pitch4] = (UINT8)((x[0] + x[0] +x[0] + x[1] * 2 + x[2] + x[3] +x[4] + 4) >> 3); Des[-pitch3] = (UINT8)((x[0] + x[0] +x[1] + x[2] * 2 + x[3] + x[4] +x[5] + 4) >> 3); Des[-pitch2] = (UINT8)((x[0] + x[1] +x[2] + x[3] * 2 + x[4] + x[5] +x[6] + 4) >> 3); Des[-pitch1] = (UINT8)((x[1] + x[2] +x[3] + x[4] * 2 + x[5] + x[6] +x[7] + 4) >> 3); Des[ 0] = (UINT8)((x[2] + x[3] +x[4] + x[5] * 2 + x[6] + x[7] +x[8] + 4) >> 3); Des[ pitch1] = (UINT8)((x[3] + x[4] +x[5] + x[6] * 2 + x[7] + x[8] +x[9] + 4) >> 3); Des[ pitch2] = (UINT8)((x[4] + x[5] +x[6] + x[7] * 2 + x[8] + x[9] +x[9] + 4) >> 3); Des[ pitch3] = (UINT8)((x[5] + x[6] +x[7] + x[8] * 2 + x[9] + x[9] +x[9] + 4) >> 3); } else { //copy the pixels to destination Des[-pitch4]= (UINT8)x[1]; Des[-pitch3]= (UINT8)x[2]; Des[-pitch2]= (UINT8)x[3]; Des[-pitch1]= (UINT8)x[4]; Des[ 0]= (UINT8)x[5]; Des[+pitch1]= (UINT8)x[6]; Des[+pitch2]= (UINT8)x[7]; Des[+pitch3]= (UINT8)x[8]; } Src ++; Des ++; } }//if // done with filtering the horizontal edge, // now let's do the vertical one // skip the first one if(CurrentFrag==StartFrag) CurrentFrag++; else { Des=DesPtr-8*PlaneLineStep+8*(CurrentFrag-StartFrag); Src=Des; QStep = QuantScale[pbi->FragQIndex[CurrentFrag]]; FLimit = ( QStep * 3 ) >> 2; for( j=0; j<8 ; j++) { x[0] = Src[-5]; x[1] = Src[-4]; x[2] = Src[-3]; x[3] = Src[-2]; x[4] = Src[-1]; x[5] = Src[0]; x[6] = Src[+1]; x[7] = Src[+2]; x[8] = Src[+3]; x[9] = Src[+4]; Sum1=Sum2=0; for(k=1;k<=4;k++) { Sum1 += abs(x[k]-x[k-1]); Sum2 += abs(x[k+4]-x[k+5]); } pbi->FragmentVariances[CurrentFrag-1] += ((Sum1>255)?255:Sum1); pbi->FragmentVariances[CurrentFrag] += ((Sum2>255)?255:Sum2); if( Sum1 < FLimit && Sum2 < FLimit && (x[5] - x[4]) < QStep && (x[4] - x[5]) < QStep ) { // low pass filtering (LPF7: 1 1 1 2 1 1 1) Des[-4] = (UINT8)((x[0] + x[0] +x[0] + x[1] * 2 + x[2] + x[3] +x[4] + 4) >> 3); Des[-3] = (UINT8)((x[0] + x[0] +x[1] + x[2] * 2 + x[3] + x[4] +x[5] + 4) >> 3); Des[-2] = (UINT8)((x[0] + x[1] +x[2] + x[3] * 2 + x[4] + x[5] +x[6] + 4) >> 3); Des[-1] = (UINT8)((x[1] + x[2] +x[3] + x[4] * 2 + x[5] + x[6] +x[7] + 4) >> 3); Des[ 0] = (UINT8)((x[2] + x[3] +x[4] + x[5] * 2 + x[6] + x[7] +x[8] + 4) >> 3); Des[ 1] = (UINT8)((x[3] + x[4] +x[5] + x[6] * 2 + x[7] + x[8] +x[9] + 4) >> 3); Des[ 2] = (UINT8)((x[4] + x[5] +x[6] + x[7] * 2 + x[8] + x[9] +x[9] + 4) >> 3); Des[ 3] = (UINT8)((x[5] + x[6] +x[7] + x[8] * 2 + x[9] + x[9] +x[9] + 4) >> 3); } Src += PlaneLineStep; Des += PlaneLineStep; }//for CurrentFrag ++; }//else }//while}/**************************************************************************** * * ROUTINE : DeblockVerticalEdgesInLoopFilteredBand * * INPUTS : None * * OUTPUTS : None * * RETURNS : None * * FUNCTION : Filter the vertical edges in a band * * SPECIAL NOTES : Save the variance * * REFERENCE : * * ERRORS : None. * ****************************************************************************/void DeblockVerticalEdgesInLoopFilteredBand( PB_INSTANCE *pbi, UINT8 *SrcPtr, UINT8 *DesPtr, UINT32 PlaneLineStep, UINT32 FragsAcross, UINT32 StartFrag, UINT32 *QuantScale ){ UINT32 j,k; UINT32 CurrentFrag=StartFrag; INT32 QStep; INT32 FLimit; UINT8 *Src, *Des; INT32 x[10]; INT32 Sum1, Sum2; while(CurrentFrag < StartFrag + FragsAcross-1) { Src=SrcPtr+8*(CurrentFrag-StartFrag+1); Des=DesPtr+8*(CurrentFrag-StartFrag+1); { QStep = QuantScale[pbi->FragQIndex[CurrentFrag+1]]; FLimit = ( QStep * 3)>>2 ; for( j=0; j<8 ; j++) { x[0] = Src[-5]; x[1] = Src[-4]; x[2] = Src[-3]; x[3] = Src[-2]; x[4] = Src[-1]; x[5] = Src[0]; x[6] = Src[+1]; x[7] = Src[+2]; x[8] = Src[+3]; x[9] = Src[+4]; Sum1=Sum2=0; for(k=1;k<=4;k++) { Sum1 += abs(x[k]-x[k-1]); Sum2 += abs(x[k+4]-x[k+5]); } pbi->FragmentVariances[CurrentFrag] += ((Sum1>255)?255:Sum1); pbi->FragmentVariances[CurrentFrag+1] += ((Sum2>255)?255:Sum2); if( Sum1 < FLimit && Sum2 < FLimit && (x[5] - x[4]) < QStep && (x[4] - x[5]) < QStep ) { // low pass filtering (LPF7: 1 1 1 2 1 1 1) Des[-4] = (UINT8)((x[0] + x[0] +x[0] + x[1] * 2 + x[2] + x[3] +x[4] + 4) >> 3); Des[-3] = (UINT8)((x[0] + x[0] +x[1] + x[2] * 2 + x[3] + x[4] +x[5] + 4) >> 3); Des[-2] = (UINT8)((x[0] + x[1] +x[2] + x[3] * 2 + x[4] + x[5] +x[6] + 4) >> 3); Des[-1] = (UINT8)((x[1] + x[2] +x[3] + x[4] * 2 + x[5] + x[6] +x[7] + 4) >> 3); Des[ 0] = (UINT8)((x[2] + x[3] +x[4] + x[5] * 2 + x[6] + x[7] +x[8] + 4) >> 3); Des[ 1] = (UINT8)((x[3] + x[4] +x[5] + x[6] * 2 + x[7] + x[8] +x[9] + 4) >> 3); Des[ 2] = (UINT8)((x[4] + x[5] +x[6] + x[7] * 2 + x[8] + x[9] +x[9] + 4) >> 3); Des[ 3] = (UINT8)((x[5] + x[6] +x[7] + x[8] * 2 + x[9] + x[9] +x[9] + 4) >> 3); } Src +=PlaneLineStep; Des +=PlaneLineStep; } //for (j) loop }//if CurrentFrag ++; }//while }/**************************************************************************** * * ROUTINE : DeblockPlane * * INPUTS : None * * OUTPUTS : None * * RETURNS : None * * FUNCTION : Filtering the channel(Y or U or V ) for deblocking * * NOTE: : This function utilized the SAD as the criteria to * determine where to apply the new 7-tap deblocking * fitler. And at the same time it accumulates the SAD * value for every block, which will be used in subseuuent * deringing functions. * * ERRORS : None. * ****************************************************************************/void DeblockPlane( PB_INSTANCE *pbi, UINT8 *SourceBuffer, UINT8 *DestinationBuffer, UINT32 Channel ){ UINT32 i,k; UINT32 PlaneLineStep=0; UINT32 StartFrag =0; UINT32 PixelIndex=0; UINT8 * SrcPtr=0, * DesPtr=0; UINT32 FragsAcross=0; UINT32 FragsDown=0; UINT32 *QuantScale=0; typedef void (*ApplyFilterToBand) (xPB_INST, UINT8 *, UINT8 *, UINT32, UINT32, UINT32, UINT32 *); ApplyFilterToBand DeblockBand; ApplyFilterToBand DeblockVerticalEdgesInBand; DeblockBand = pbi->DeblockLoopFilteredBand; DeblockVerticalEdgesInBand = DeblockVerticalEdgesInLoopFilteredBand; switch( Channel ) { case 0: // Get the parameters PlaneLineStep = pbi->Configuration.YStride; FragsAcross = pbi->HFragments; FragsDown = pbi->VFragments; StartFrag = 0; PixelIndex = pbi->ReconYDataOffset; SrcPtr = & SourceBuffer[PixelIndex]; DesPtr = & DestinationBuffer[PixelIndex]; break; case 1: // Get the parameters PlaneLineStep = pbi->Configuration.UVStride; FragsAcross = pbi->HFragments / 2; FragsDown = pbi->VFragments / 2; StartFrag = pbi->YPlaneFragments; PixelIndex = pbi->ReconUDataOffset; SrcPtr = & SourceBuffer[PixelIndex]; DesPtr = & DestinationBuffer[PixelIndex]; break; default: // Get the parameters PlaneLineStep = pbi->Configuration.UVStride; FragsAcross = pbi->HFragments / 2; FragsDown = pbi->VFragments / 2; StartFrag = pbi->YPlaneFragments + pbi->UVPlaneFragments; PixelIndex = pbi->ReconVDataOffset; SrcPtr = & SourceBuffer[PixelIndex]; DesPtr = & DestinationBuffer[PixelIndex]; break; } QuantScale = DCQuantScaleV1; // In order to make use of the for(i=0;i<4;i++) { memcpy(DesPtr+i*PlaneLineStep, SrcPtr+i*PlaneLineStep, PlaneLineStep); } // loop to last band k = 1; while( k < FragsDown ) { SrcPtr += 8*PlaneLineStep; DesPtr += 8*PlaneLineStep; //Filter both the horizontal and vertical block edges inside the band DeblockBand( pbi, SrcPtr, DesPtr, PlaneLineStep, FragsAcross, StartFrag, QuantScale); //Move Pointers StartFrag += FragsAcross; k ++; } // The Last band for(i=0;i<4;i++) { memcpy(DesPtr+(i+4)*PlaneLineStep, SrcPtr+(i+4)*PlaneLineStep, PlaneLineStep); } DeblockVerticalEdgesInBand( pbi, SrcPtr, DesPtr, PlaneLineStep, FragsAcross, StartFrag, QuantScale);}/**************************************************************************** * * ROUTINE : DeblockFrame * * FUNCTION : Applies a loop filter to the edge pixels of coded blocks. * * NOTE: : This function utilized the SAD as the criteria to * determine where to apply the new 7-tap deblocking * fitler. And at the same time it accumulates the SAD * value for every block, which will be used in subseuuent * deringing functions. * ****************************************************************************/void DeblockFrame(PB_INSTANCE *pbi, UINT8 *SourceBuffer, UINT8 *DestinationBuffer){ memset(pbi->FragmentVariances, 0 , sizeof(INT32) * pbi->UnitFragments); UpdateFragQIndex(pbi); SetupLoopFilter(pbi); //Y DeblockPlane( pbi, SourceBuffer, DestinationBuffer, 0); //U DeblockPlane( pbi, SourceBuffer, DestinationBuffer, 1); //v DeblockPlane( pbi, SourceBuffer, DestinationBuffer, 2); }/**************************************************************************** * * ROUTINE : PostProcess * * INPUTS : None * * OUTPUTS : None * * RETURNS : None * * FUNCTION : Applies a loop filter to the edge pixels of coded blocks. * * SPECIAL NOTES : * * * ERRORS : None. * ****************************************************************************/void PostProcess(PB_INSTANCE *pbi){ switch (pbi->PostProcessingLevel) { case 8: // on a slow machine, use a simpler and faster deblocking filter DeblockFrame(pbi, pbi->LastFrameRecon,pbi->PostProcessBuffer); break; case 6: DeblockFrame(pbi, pbi->LastFrameRecon,pbi->PostProcessBuffer); UpdateUMVBorder(pbi, pbi->PostProcessBuffer ); DeringFrame(pbi, pbi->PostProcessBuffer, pbi->PostProcessBuffer); break; case 5: DeblockFrame(pbi, pbi->LastFrameRecon,pbi->PostProcessBuffer); UpdateUMVBorder(pbi, pbi->PostProcessBuffer ); DeringFrame(pbi, pbi->PostProcessBuffer, pbi->PostProcessBuffer); break; case 4: DeblockFrame(pbi, pbi->LastFrameRecon, pbi->PostProcessBuffer); break; case 1: UpdateFragQIndex(pbi); break; case 0: break; default: DeblockFrame(pbi, pbi->LastFrameRecon, pbi->PostProcessBuffer); UpdateUMVBorder(pbi, pbi->PostProcessBuffer ); DeringFrame(pbi, pbi->PostProcessBuffer, pbi->PostProcessBuffer); break; }}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -