📄 postprocessing.c
字号:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include "postprocessing.h"
#include "vlc.h"
#include "memalloc.h"
#include <memory.h>
#ifdef USE_POST_FILTER
#define USE_MAD
#define MAX_SQR_FILT_LENGTH 25
#define REG 0.0001
#define MAX_FILTERS_SET_NUMBER 16
#define MAX_FILTER_NUMBER 16
#define COEF_BITS_HIGH 15
int sqrtTable[256];
int patternFullPel9x9[81] = {
24, 19, 14, 9, 4, 9, 14, 19, 24,
23, 18, 13, 8, 3, 8, 13, 18, 23,
22, 17, 12, 7, 2, 7, 12, 17, 22,
21, 16, 11, 6, 1, 6, 11, 16, 21,
20, 15, 10, 5, 0, 5, 10, 15, 20,
21, 16, 11, 6, 1, 6, 11, 16, 21,
22, 17, 12, 7, 2, 7, 12, 17, 22,
23, 18, 13, 8, 3, 8, 13, 18, 23,
24, 19, 14, 9, 4, 9, 14, 19, 24
};
int patternFullPel7x7[49] = {
15, 11, 7, 3, 8, 11, 15,
14, 10, 6, 2, 7, 10, 14,
13, 9, 5, 1, 6, 9, 13,
12, 8, 4, 0, 4, 8, 12,
13, 9, 5, 1, 6, 9, 13,
14, 10, 6, 2, 7, 10, 14,
15, 11, 7, 3, 8, 11, 15,
};
int patternFullPel5x5[25] = {
8, 5, 2, 5, 8,
7, 4, 1, 4, 7,
6, 3, 0, 3, 6,
7, 4, 1, 4, 7,
8, 5, 2, 5, 8,
};
double filterCoeffPP[MAX_FILTERS_SET_NUMBER][MAX_FILTER_NUMBER][MAX_SQR_FILT_LENGTH];
int QP_table[MAX_FILTERS_SET_NUMBER],QP_count=0,QP_table_count=0;
int DiffQFilterCoeffIntPP[MAX_FILTERS_SET_NUMBER][MAX_FILTER_NUMBER][MAX_SQR_FILT_LENGTH];
int filterOverflowFlag[MAX_FILTERS_SET_NUMBER][MAX_FILTER_NUMBER];
int PostFilterFlagInt= -1;
int varBest;
int filter_size=0;
int filters_per_set=0;
int FilterSetPerQP;
int numQBitsIntPP[MAX_SQR_FILT_LENGTH] =
{
COEF_BITS_HIGH, COEF_BITS_HIGH, COEF_BITS_HIGH, COEF_BITS_HIGH, COEF_BITS_HIGH,
COEF_BITS_HIGH, COEF_BITS_HIGH, COEF_BITS_HIGH, COEF_BITS_HIGH, COEF_BITS_HIGH,
COEF_BITS_HIGH, COEF_BITS_HIGH, COEF_BITS_HIGH, COEF_BITS_HIGH, COEF_BITS_HIGH,
COEF_BITS_HIGH, COEF_BITS_HIGH, COEF_BITS_HIGH, COEF_BITS_HIGH, COEF_BITS_HIGH,
COEF_BITS_HIGH, COEF_BITS_HIGH, COEF_BITS_HIGH, COEF_BITS_HIGH, COEF_BITS_HIGH,
};
// for symmetric filter
int depthInt9x9[25] =
{
5, 5, 6, 7, 7,
5, 6, 7, 7, 8,
6, 7, 7, 8, 8,
7, 7, 8, 8, 9,
7, 8, 8, 9, 9,
};
int depthInt7x7[16] =
{
5, 5, 6, 7,
5, 6, 7, 7,
6, 7, 7, 8,
7, 7, 8, 8,
};
int depthInt5x5[9] =
{
5, 6, 7,
6, 7, 7,
7, 7, 8,
};
void generateSqrtTable()
{
int i,j;
sqrtTable[0]=0;
for (i=1;i<16;++i)
{
int start=i*i;
for (j=start;j<start+i+1;++j)
{
sqrtTable[j]=i;
}
for (j=start+i+1;j<(i+1)*(i+1);++j)
{
sqrtTable[j]=i+1;
}
}
}
int readCoeffPP(char *tracestring, int numQBits, int depth,Bitstream *bitstream)
{
int prefix, suffix, suffixLen;
int coeffQ;
int sign, mag;
int rangeQ = 1<<(numQBits-1);
int i, bit;
// read prefix code
for(i = 0; i < depth-1; i++)
{
bit = u_1(tracestring, bitstream);
if(!bit)
break;
}
prefix = i;
// read suffix code
suffixLen = numQBits-2-(depth-1-prefix);
if(prefix == 0)
suffixLen++;
suffix = u_v(suffixLen, tracestring, bitstream);
// get the magnitude
if(prefix == 0)
mag = 0;
else
mag = rangeQ>>(depth-prefix);
mag += suffix;
/// read sign bit
if(mag)
sign = u_1(tracestring, bitstream);
else
sign = 0;
coeffQ = sign ? -mag:mag;
return coeffQ;
}
void readAIFIntegerPP(Bitstream *currStream,int bit)
{
int i,j;
int QP_index;
int *pDepthInt=NULL;
filter_size = u_v(4, "filter size", currStream);
filters_per_set = u_v(8,"filter number per QP" ,currStream);
FilterSetPerQP=u_1("FilterSetPerQP flag",currStream);
if (FilterSetPerQP)
QP_count=u_v(4,"filter ",currStream);
else
QP_count=1;
if (filter_size==4)
{
pDepthInt=depthInt9x9;
}
else if (filter_size==3)
{
pDepthInt=depthInt7x7;
}
else if (filter_size==2)
{
pDepthInt=depthInt5x5;
}
for (QP_index=0;QP_index<QP_count;QP_index++)
{
for (j=0;j<filters_per_set;j++)
{
for(i = 0; i < (filter_size+1)*(filter_size+1); i++)
{
DiffQFilterCoeffIntPP[QP_index][j][i] = readCoeffPP("SH: full-pel filter", bit, pDepthInt[i],currStream);
}
}
}
}
void CalculateFilterCoefficientsIntPP(int bit)
{
int i;
int factor;
double is;
int *pDiffQFilterCoeffIntPP;
int j;
int QP_index;
int sqrFiltLength=(filter_size+1)*(filter_size+1);
int all_zero=0;
for (QP_index=0;QP_index<QP_count;QP_index++)
{
pDiffQFilterCoeffIntPP = DiffQFilterCoeffIntPP[QP_index][0];
// predict top-left quadrant from fixed filter and quantize
all_zero=0;
filterOverflowFlag[QP_index][0]=0;
for(i = 0; i < sqrFiltLength; i++)
{
factor = (1<<(bit-1));
is = (double)(pDiffQFilterCoeffIntPP[i])/(double)factor;
filterCoeffPP[QP_index][0][i] = is;
if (filterCoeffPP[QP_index][0][i]==0)
all_zero++;
}
if (all_zero==sqrFiltLength)
filterOverflowFlag[QP_index][0]=1;
for (j=1;j<filters_per_set;j++)
{
all_zero=0;
pDiffQFilterCoeffIntPP = DiffQFilterCoeffIntPP[QP_index][j];
filterOverflowFlag[QP_index][j]=0;
//predict top-left quadrant from fixed filter and quantize
for(i = 0; i < sqrFiltLength; i++)
{
factor = (1<<(bit-1));
is = (double)(pDiffQFilterCoeffIntPP[i])/(double)factor;
filterCoeffPP[QP_index][j][i] = is+filterCoeffPP[QP_index][j-1][i];
if (filterCoeffPP[QP_index][j][i]==0)
all_zero++;
}
if (all_zero==sqrFiltLength)
filterOverflowFlag[QP_index][0]=1;
}
for (j=0;j<filters_per_set;j++)
for(i = 0; i < sqrFiltLength; i++)
printf("FilterCoeffQuan[%d][%d]=%f\n",j,i,filterCoeffPP[QP_index][j][i]);
}
}
void QL_readInterCoeff(StorablePicture *dec_picture)
{
static int first=0;
if (first==0)
{
if (img->filterbitstream!=NULL)
{
readAIFIntegerPP(img->filterbitstream,COEF_BITS_HIGH);
CalculateFilterCoefficientsIntPP(COEF_BITS_HIGH);
}
first =1;
}
if (img->filterbitstream!=NULL)
PostFilterFlagInt = u_1("QL: PostFilterFlagInt", img->filterbitstream);
else
PostFilterFlagInt=0;
}
void calcVar(int **imgY_var, imgpel **refY, int fl)
{
int i, j, ii, jj,noSamp;
int mean, var;
for (i = 0; i < img->height; ++i)
{
for (j = 0; j < img->width; ++j)
{
mean=0,var=0,noSamp=0;
for (jj=j-fl; jj<=j+fl; jj++)// column wise scan
{
if (jj>=0 && jj<img->width)
{
for (ii=i-fl; ii<=i+fl; ii++)
{
if (ii>=0 && ii<img->height)
{
#ifdef USE_MAD
var +=abs(refY[i][j]-refY[ii][jj]);
noSamp++;
#else
var +=refY[ii][jj]*refY[ii][jj];
mean+=refY[ii][jj];
noSamp++;
#endif
}
}
}
}
#ifdef USE_MAD
noSamp=32;
imgY_var[i][j]=min(max(0,var/noSamp),15);
#else
tempInt=( var*noSamp-mean*mean)/(noSamp*noSamp);
tempInt=min(max(0,tempInt),255);
imgY_var[i][j] = sqrtTable[tempInt];
#endif
}
}
}
void filter_frame(imgpel **imgY_filt, imgpel **refY, int fl, int **varImg,int QPindex)
{
int i, j, ii, jj, iiLimit, jjLimit, k, ind;
int vectorInd, ELocal[MAX_SQR_FILT_LENGTH], pixelInt;
double pixelDouble;
int sqrFiltLength=(fl+1)*(fl+1);
int *pPattern=NULL;
if (fl ==4)
{
pPattern=patternFullPel9x9;
}
else if (fl ==3)
{
pPattern=patternFullPel7x7;
}
else if (fl ==2)
{
pPattern=patternFullPel5x5;
}
for (i = 0; i < img->height; ++i)
{
for (j = 0; j < img->width; ++j)
{
ind=min(varImg[i][j]*filters_per_set/16, filters_per_set-1);
if (filterOverflowFlag[QPindex][ind]==0)
{
k=0; memset(ELocal, 0, sqrFiltLength*sizeof(int));
for (ii=i-fl; ii<=i+fl; ii++)
{
iiLimit=max(0, min(img->height-1,ii));
for (jj=j-fl; jj<=j+fl; jj++)
{
jjLimit=max(0, min(img->width-1,jj));
vectorInd=pPattern[k++];
ELocal[vectorInd]+=refY[iiLimit][jjLimit];
}
}
pixelDouble=0;
for (k=0; k<sqrFiltLength; k++)
{
pixelDouble+=(double)(ELocal[k]*filterCoeffPP[QPindex][ind][k]);
}
pixelInt=(int)floor(pixelDouble+0.5);
imgY_filt[i][j]=max(0, min(pixelInt,((1<<img->bitdepth_luma)-1)));
}
else
{
imgY_filt[i][j]=refY[i][j];
}
}//j
}//i
}
void postProcessing(StorablePicture *dec_picture)
{
static imgpel **imgY_filt;
int i, j;
imgpel **refY;
int memory_size = 0;
static int first=0;
static int **imgY_var;
get_mem2Dpel (&(dec_picture->imgY_post), img->height, img->width);
refY = dec_picture->imgY_post;
for (i = 0; i < img->height; ++i)
{
for (j = 0; j < img->width; ++j)
{
refY[i][j]=dec_picture->imgY[i][j];
}
}
if (first==0)
{
generateSqrtTable();
memory_size += get_mem2Dpel(&imgY_filt, img->height, img->width);
memory_size += get_mem2Dint(&imgY_var, img->height, img->width);
first=1;
}
calcVar(imgY_var, refY, filter_size);
if (dec_picture->slice_type !=B_SLICE || FilterSetPerQP==0)
{
varBest=0;
}
else if (!dec_picture->used_for_reference)
{
varBest=1;
}
else
{
varBest=2;
}
if ((varBest >= 0 && varBest <QP_count)||varBest == 0 )
{
filter_frame(imgY_filt, refY, filter_size, imgY_var, varBest);
}
else
{
printf("cannot find filter\n");
}
for (i = 0; i < img->height; ++i)
{
for (j = 0; j < img->width; ++j)
{
refY[i][j]=imgY_filt[i][j];
}
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -