📄 pp.c
字号:
/******************************************************************** * * * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * * * * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2003 * * by the Xiph.Org Foundation http://www.xiph.org/ * * * ******************************************************************** function: last mod: $Id: pp.c 11442 2006-05-27 17:28:08Z giles $ ********************************************************************/#include <stdlib.h>#include <string.h>#include "codec_internal.h"#include "pp.h"#include "dsp.h"#define MAX(a, b) ((a>b)?a:b)#define MIN(a, b) ((a<b)?a:b)#define PP_QUALITY_THRESH 49static const ogg_int32_t SharpenModifier[ Q_TABLE_SIZE ] ={ -12, -11, -10, -10, -9, -9, -9, -9, -6, -6, -6, -6, -6, -6, -6, -6, -4, -4, -4, -4, -4, -4, -4, -4, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};static const ogg_uint32_t DcQuantScaleV1[ Q_TABLE_SIZE ] = { 22, 20, 19, 18, 17, 17, 16, 16, 15, 15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 9, 8, 8, 8, 7, 7, 7, 6, 6, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1};static const ogg_uint32_t * const DeringModifierV1=DcQuantScaleV1;static void PClearFrameInfo(PP_INSTANCE * ppi){ int i; if(ppi->ScanPixelIndexTable) _ogg_free(ppi->ScanPixelIndexTable); ppi->ScanPixelIndexTable=0; if(ppi->ScanDisplayFragments) _ogg_free(ppi->ScanDisplayFragments); ppi->ScanDisplayFragments=0; for(i = 0 ; i < MAX_PREV_FRAMES ; i ++) if(ppi->PrevFragments[i]){ _ogg_free(ppi->PrevFragments[i]); ppi->PrevFragments[i]=0; } if(ppi->FragScores) _ogg_free(ppi->FragScores); ppi->FragScores=0; if(ppi->SameGreyDirPixels) _ogg_free(ppi->SameGreyDirPixels); ppi->SameGreyDirPixels=0; if(ppi->FragDiffPixels) _ogg_free(ppi->FragDiffPixels); ppi->FragDiffPixels=0; if(ppi->BarBlockMap) _ogg_free(ppi->BarBlockMap); ppi->BarBlockMap=0; if(ppi->TmpCodedMap) _ogg_free(ppi->TmpCodedMap); ppi->TmpCodedMap=0; if(ppi->RowChangedPixels) _ogg_free(ppi->RowChangedPixels); ppi->RowChangedPixels=0; if(ppi->PixelScores) _ogg_free(ppi->PixelScores); ppi->PixelScores=0; if(ppi->PixelChangedMap) _ogg_free(ppi->PixelChangedMap); ppi->PixelChangedMap=0; if(ppi->ChLocals) _ogg_free(ppi->ChLocals); ppi->ChLocals=0; if(ppi->yuv_differences) _ogg_free(ppi->yuv_differences); ppi->yuv_differences=0;}void PInitFrameInfo(PP_INSTANCE * ppi){ int i; PClearFrameInfo(ppi); ppi->ScanPixelIndexTable = _ogg_malloc(ppi->ScanFrameFragments*sizeof(*ppi->ScanPixelIndexTable)); ppi->ScanDisplayFragments = _ogg_malloc(ppi->ScanFrameFragments*sizeof(*ppi->ScanDisplayFragments)); for(i = 0 ; i < MAX_PREV_FRAMES ; i ++) ppi->PrevFragments[i] = _ogg_malloc(ppi->ScanFrameFragments*sizeof(*ppi->PrevFragments)); ppi->FragScores = _ogg_malloc(ppi->ScanFrameFragments*sizeof(*ppi->FragScores)); ppi->SameGreyDirPixels = _ogg_malloc(ppi->ScanFrameFragments*sizeof(*ppi->SameGreyDirPixels)); ppi->FragDiffPixels = _ogg_malloc(ppi->ScanFrameFragments*sizeof(*ppi->FragScores)); ppi->BarBlockMap= _ogg_malloc(3 * ppi->ScanHFragments*sizeof(*ppi->BarBlockMap)); ppi->TmpCodedMap = _ogg_malloc(ppi->ScanHFragments*sizeof(*ppi->TmpCodedMap)); ppi->RowChangedPixels = _ogg_malloc(3 * ppi->ScanConfig.VideoFrameHeight* sizeof(*ppi->RowChangedPixels)); ppi->PixelScores = _ogg_malloc(ppi->ScanConfig.VideoFrameWidth* sizeof(*ppi->PixelScores) * PSCORE_CB_ROWS); ppi->PixelChangedMap = _ogg_malloc(ppi->ScanConfig.VideoFrameWidth* sizeof(*ppi->PixelChangedMap) * PMAP_CB_ROWS); ppi->ChLocals = _ogg_malloc(ppi->ScanConfig.VideoFrameWidth* sizeof(*ppi->ChLocals) * CHLOCALS_CB_ROWS); ppi->yuv_differences = _ogg_malloc(ppi->ScanConfig.VideoFrameWidth* sizeof(*ppi->yuv_differences) * YDIFF_CB_ROWS);}void ClearPPInstance(PP_INSTANCE *ppi){ PClearFrameInfo(ppi);}void InitPPInstance(PP_INSTANCE *ppi, DspFunctions *funcs){ memset(ppi,0,sizeof(*ppi)); memcpy(&ppi->dsp, funcs, sizeof(DspFunctions)); /* Initializations */ ppi->PrevFrameLimit = 3; /* Must not exceed MAX_PREV_FRAMES (Note that this number includes the current frame so "1 = no effect") */ /* Scan control variables. */ ppi->HFragPixels = 8; ppi->VFragPixels = 8; ppi->SRFGreyThresh = 4; ppi->SRFColThresh = 5; ppi->NoiseSupLevel = 3; ppi->SgcLevelThresh = 3; ppi->SuvcLevelThresh = 4; /* Variables controlling S.A.D. breakouts. */ ppi->GrpLowSadThresh = 10; ppi->GrpHighSadThresh = 64; ppi->PrimaryBlockThreshold = 5; ppi->SgcThresh = 16; /* (Default values for 8x8 blocks). */ ppi->UVBlockThreshCorrection = 1.25; ppi->UVSgcCorrection = 1.5; ppi->MaxLineSearchLen = MAX_SEARCH_LINE_LEN;}static void DeringBlockStrong(unsigned char *SrcPtr, unsigned char *DstPtr, ogg_int32_t Pitch, ogg_uint32_t FragQIndex, const ogg_uint32_t *QuantScale){ ogg_int16_t UDMod[72]; ogg_int16_t LRMod[72]; unsigned int j,k,l; const unsigned char * Src; unsigned int QValue = QuantScale[FragQIndex]; unsigned char p; unsigned char pl; unsigned char pr; unsigned char pu; unsigned char pd; int al; int ar; int au; int ad; int atot; int B; int newVal; const unsigned char *curRow = SrcPtr - 1; /* avoid negative array indexes */ unsigned char *dstRow = DstPtr; const unsigned char *lastRow = SrcPtr-Pitch; const unsigned char *nextRow = SrcPtr+Pitch; unsigned int rowOffset = 0; unsigned int round = (1<<6); int High; int Low; int TmpMod; int Sharpen = SharpenModifier[FragQIndex]; High = 3 * QValue; if(High>32)High=32; Low = 0; /* Initialize the Mod Data */ Src = SrcPtr-Pitch; for(k=0;k<9;k++){ for(j=0;j<8;j++){ TmpMod = 32 + QValue - (abs(Src[j+Pitch]-Src[j])); if(TmpMod< -64) TmpMod = Sharpen; else if(TmpMod<Low) TmpMod = Low; else if(TmpMod>High) TmpMod = High; UDMod[k*8+j] = (ogg_int16_t)TmpMod; } Src +=Pitch; } Src = SrcPtr-1; for(k=0;k<8;k++){ for(j=0;j<9;j++){ TmpMod = 32 + QValue - (abs(Src[j+1]-Src[j])); if(TmpMod< -64 ) TmpMod = Sharpen; else if(TmpMod<0) TmpMod = Low; else if(TmpMod>High) TmpMod = High; LRMod[k*9+j] = (ogg_int16_t)TmpMod; } Src+=Pitch; } for(k=0;k<8;k++){ /* In the case that this function called with same buffer for source and destination, To keep the c and the mmx version to have consistant results, intermediate buffer is used to store the eight pixel value before writing them to destination (i.e. Overwriting souce for the speical case) */ for(l=0;l<8;l++){ atot = 128; B = round; p = curRow[ rowOffset +l +1]; pl = curRow[ rowOffset +l]; al = LRMod[k*9+l]; atot -= al; B += al * pl; pu = lastRow[ rowOffset +l]; au = UDMod[k*8+l]; atot -= au; B += au * pu; pd = nextRow[ rowOffset +l]; ad = UDMod[(k+1)*8+l]; atot -= ad; B += ad * pd; pr = curRow[ rowOffset +l+2]; ar = LRMod[k*9+l+1]; atot -= ar; B += ar * pr; newVal = ( atot * p + B) >> 7; dstRow[ rowOffset +l]= clamp255( newVal ); } rowOffset += Pitch; }}static void DeringBlockWeak(unsigned char *SrcPtr, unsigned char *DstPtr, ogg_int32_t Pitch, ogg_uint32_t FragQIndex, const ogg_uint32_t *QuantScale){ ogg_int16_t UDMod[72]; ogg_int16_t LRMod[72]; unsigned int j,k; const unsigned char * Src; unsigned int QValue = QuantScale[FragQIndex]; unsigned char p; unsigned char pl; unsigned char pr; unsigned char pu; unsigned char pd; int al; int ar; int au; int ad; int atot; int B; int newVal; const unsigned char *curRow = SrcPtr-1; unsigned char *dstRow = DstPtr; const unsigned char *lastRow = SrcPtr-Pitch; const unsigned char *nextRow = SrcPtr+Pitch; unsigned int rowOffset = 0; unsigned int round = (1<<6); int High; int Low; int TmpMod; int Sharpen = SharpenModifier[FragQIndex]; High = 3 * QValue; if(High>24) High=24; Low = 0 ; /* Initialize the Mod Data */ Src=SrcPtr-Pitch; for(k=0;k<9;k++) { for(j=0;j<8;j++) { TmpMod = 32 + QValue - 2*(abs(Src[j+Pitch]-Src[j])); if(TmpMod< -64) TmpMod = Sharpen; else if(TmpMod<Low) TmpMod = Low; else if(TmpMod>High) TmpMod = High; UDMod[k*8+j] = (ogg_int16_t)TmpMod; } Src +=Pitch; } Src = SrcPtr-1; for(k=0;k<8;k++){ for(j=0;j<9;j++){ TmpMod = 32 + QValue - 2*(abs(Src[j+1]-Src[j])); if(TmpMod< -64 ) TmpMod = Sharpen; else if(TmpMod<Low) TmpMod = Low; else if(TmpMod>High) TmpMod = High; LRMod[k*9+j] = (ogg_int16_t)TmpMod; } Src+=Pitch; } for(k=0;k<8;k++) { for(j=0;j<8;j++){ atot = 128; B = round; p = curRow[ rowOffset +j+1]; pl = curRow[ rowOffset +j]; al = LRMod[k*9+j]; atot -= al; B += al * pl; pu = lastRow[ rowOffset +j]; au = UDMod[k*8+j]; atot -= au; B += au * pu; pd = nextRow[ rowOffset +j]; ad = UDMod[(k+1)*8+j]; atot -= ad; B += ad * pd; pr = curRow[ rowOffset +j+2]; ar = LRMod[k*9+j+1]; atot -= ar; B += ar * pr; newVal = ( atot * p + B) >> 7; dstRow[ rowOffset +j] = clamp255( newVal ); } rowOffset += Pitch; }}static void DeringFrame(PB_INSTANCE *pbi, unsigned char *Src, unsigned char *Dst){ ogg_uint32_t col,row; unsigned char *SrcPtr; unsigned char *DestPtr; ogg_uint32_t BlocksAcross,BlocksDown; const ogg_uint32_t *QuantScale; ogg_uint32_t Block; ogg_uint32_t LineLength; ogg_int32_t Thresh1,Thresh2,Thresh3,Thresh4; Thresh1 = 384; Thresh2 = 4 * Thresh1; Thresh3 = 5 * Thresh2/4; Thresh4 = 5 * Thresh2/2; QuantScale = DeringModifierV1; BlocksAcross = pbi->HFragments; BlocksDown = pbi->VFragments; SrcPtr = Src + pbi->ReconYDataOffset; DestPtr = Dst + pbi->ReconYDataOffset; LineLength = pbi->YStride; Block = 0; for ( row = 0 ; row < BlocksDown; row ++){ for (col = 0; col < BlocksAcross; col ++){ ogg_uint32_t Quality = pbi->FragQIndex[Block]; ogg_int32_t Variance = pbi->FragmentVariances[Block]; if( pbi->PostProcessingLevel >5 && Variance > Thresh3 ){ DeringBlockStrong(SrcPtr + 8 * col, DestPtr + 8 * col, LineLength,Quality,QuantScale); if( (col > 0 && pbi->FragmentVariances[Block-1] > Thresh4 ) || (col + 1 < BlocksAcross && pbi->FragmentVariances[Block+1] > Thresh4 ) || (row + 1 < BlocksDown && pbi->FragmentVariances[Block+BlocksAcross] > Thresh4) || (row > 0 && pbi->FragmentVariances[Block-BlocksAcross] > Thresh4) ){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -