📄 postprocessing.c
字号:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <memory.h>
#include "global.h"
#include "memalloc.h"
#include "malloc.h"
#include "defines.h"
#include "mbuffer.h"
#include "image.h"
#include "postprocessing.h"
#include "vlc.h"
#ifdef USE_POST_FILTER
#include "annexb.h"
#include "nalu.h"
#include "sei.h"
#include <fcntl.h>
#include "postprocessing.h"
#include "output.h"
#define USE_MAD
#define FILTER_SET_PER_SLICETYPE 1
#define MAX_SQR_FILT_LENGTH 25
#define REG 0.0001
#define FILTERS_SET_NUMBER 16
#define MAX_FILTER_NUMBER 16
imgpel **imgY_orgPP;
int FILTER_NUMBER;
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,
};
int sqrtTable[256];
int filterLengthPP;
int FilterSetPerQP=FILTER_SET_PER_SLICETYPE;
#define COEF_BITS_LOW 11
#define COEF_BITS_HIGH 15
int DiffQFilterCoeffIntPP[FILTERS_SET_NUMBER][MAX_FILTER_NUMBER][MAX_SQR_FILT_LENGTH];
int filterOverflowFlag[FILTERS_SET_NUMBER][MAX_FILTER_NUMBER];
void write_picture(StorablePicture *p, int p_out, int real_structure);
void buf2img ( imgpel** imgX, unsigned char* buf, int size_x, int size_y, int symbol_size_in_bytes );
int numQBitsIntPP[MAX_SQR_FILT_LENGTH] =
{
COEF_BITS_LOW, COEF_BITS_LOW, COEF_BITS_LOW, COEF_BITS_LOW, COEF_BITS_LOW,
COEF_BITS_LOW, COEF_BITS_LOW, COEF_BITS_LOW, COEF_BITS_LOW, COEF_BITS_LOW,
COEF_BITS_LOW, COEF_BITS_LOW, COEF_BITS_LOW, COEF_BITS_LOW, COEF_BITS_LOW,
COEF_BITS_LOW, COEF_BITS_LOW, COEF_BITS_LOW, COEF_BITS_LOW, COEF_BITS_LOW,
COEF_BITS_LOW, COEF_BITS_LOW, COEF_BITS_LOW, COEF_BITS_LOW, COEF_BITS_LOW,
};
// 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,
};
double filterCoeffPP[FILTERS_SET_NUMBER][MAX_FILTER_NUMBER][MAX_SQR_FILT_LENGTH];
double yGlobal[FILTERS_SET_NUMBER][MAX_FILTER_NUMBER][MAX_SQR_FILT_LENGTH], EGlobal[FILTERS_SET_NUMBER][MAX_FILTER_NUMBER][MAX_SQR_FILT_LENGTH][MAX_SQR_FILT_LENGTH];
int QP_set[FILTERS_SET_NUMBER],QP_table[FILTERS_SET_NUMBER],QP_count=0,QP_index;
int currentQP;
int *QP_map;
int *SeqNo_map;
int *Apply_filter_map;
void gnsSolveByChol_Post(double LHS[][MAX_SQR_FILT_LENGTH], double rhs[], double x[], int noEq);
void calcVar(int **imgY_var, imgpel **refY, int fl);
int sendPostFilterInteger(Bitstream *bitstream,int criteria,int padding,int QP_index,int fl);
void generatePrefixCodePP(int *prefixCode, int *prefixCodeLen, int size)
{
int i;
prefixCode[0] = 0;
prefixCodeLen[0] = 1;
for(i = 1; i < size-1; i++)
{
prefixCode[i] = (1<<(i+1))-2;
prefixCodeLen[i] = i+1;
}
prefixCode[size-1] = prefixCode[size-2]+1;
prefixCodeLen[size-1] = prefixCodeLen[size-2];
}
void generateThresPP(int *thres, int max, int size)
{
int i;
thres[0] = 0;
for(i = 0; i < size; i++)
thres[i+1] = max >> (size-1-i);
}
int writeCoeffPP(int coeffQ, Bitstream *bitstream, int numQBits, int depth, char *tracestring)
{
int prefixCode[100];
int prefixCodeLen[100];
int thres[100];
int sign = (coeffQ >= 0) ? 0:1;
int mag = (sign==0) ? coeffQ:(-coeffQ);
int rangeQ = 1<<(numQBits-1);
int len = 0;
int i;
int suffixLen;
int bin;
generatePrefixCodePP(prefixCode, prefixCodeLen, depth);
generateThresPP(thres, rangeQ, depth);
// find to which bin this value "mag" belongs
for(i = 0; i < depth; i++)
{
if(mag >= thres[i] && mag < thres[i+1])
break;
}
bin = i;
// assert(bin < depth);
suffixLen = numQBits-2;
for(i = depth-1; i > bin; i--)
suffixLen--;
if(bin == 0)
suffixLen++;
len += u_v(prefixCodeLen[bin], tracestring, prefixCode[bin], bitstream);
len += u_v(suffixLen, tracestring, mag-thres[bin], bitstream);
// sign bit
if(mag)
len += u_1(tracestring, sign, bitstream);
return len;
}
void QL_NumBitsInit(int bit_depth)
{
int i;
for (i=0;i<MAX_SQR_FILT_LENGTH;i++)
{
numQBitsIntPP[i]=bit_depth;
}
}
void QuantizeIntegerFilterPP(double *FilterCoeffQuan,int fl,int ind,int QPindex)
{
int i;
double diff, is;
int diffInt, sign, numBits, factor;
int *pDiffQFilterCoeffIntPP;
int *Overflow;
int sqrFiltLength=(fl+1)*(fl+1);
pDiffQFilterCoeffIntPP = DiffQFilterCoeffIntPP[QPindex][ind];
Overflow=&filterOverflowFlag[QPindex][ind];
if (ind >0)
{
double *pFilterPred=filterCoeffPP[QPindex][ind-1];
// predict from fixed filter and quantize
for(i = 0; i < sqrFiltLength; i++)
{
numBits = numQBitsIntPP[i]-1; // 1-bit for sign
factor = (1<<numBits);
diff = FilterCoeffQuan[i]-pFilterPred[i];
sign = (diff>0.) ? 1:-1;
diff = diff*sign;
diffInt = (int)(diff*(double)factor+0.5);
if(diffInt >= factor)
{
diffInt = factor-1;
*Overflow =1;
}
diffInt = diffInt*sign;
pDiffQFilterCoeffIntPP[i] = diffInt;
is = (double)diffInt/(double)(factor);
FilterCoeffQuan[i] = is+pFilterPred[i];
}
if (*Overflow==1)
{
pDiffQFilterCoeffIntPP[0] = 0;
FilterCoeffQuan[0] = 0;
pFilterPred[0]=0;
for(i = 1; i < sqrFiltLength; i++)
{
pFilterPred[i] = 0;;
FilterCoeffQuan[i] = 0;
pDiffQFilterCoeffIntPP[i] = 0;
}
}
}
else
{
// predict from fixed filter and quantize
for(i = 0; i < sqrFiltLength; i++)
{
numBits = numQBitsIntPP[i]-1; // 1-bit for sign
factor = (1<<numBits);
diff = FilterCoeffQuan[i];
sign = (diff>0.) ? 1:-1;
diff = diff*sign;
diffInt = (int)(diff*(double)factor+0.5);
if(diffInt >= factor)
{
diffInt = factor-1;
*Overflow =1;
}
diffInt = diffInt*sign;
pDiffQFilterCoeffIntPP[i] = diffInt;
is = (double)diffInt/(double)(factor);
FilterCoeffQuan[i] = is;
}
if (*Overflow ==1)
{
pDiffQFilterCoeffIntPP[0] = 0;
FilterCoeffQuan[0] = 0;
for(i = 1; i < sqrFiltLength; i++)
{
FilterCoeffQuan[i] = 0;
pDiffQFilterCoeffIntPP[i] = 0;
}
}
}
//for(i = 0; i < sqrFiltLength; i++)
// printf("FilterCoeffQuan[%d][%d]=%f\n",ind,i,FilterCoeffQuan[i]);
}
void QuantizeAllFiltersPP(int fl,int Numbits,Bitstream *bitstream)
{
int ind,QP_index;
int bit_ct=0,single_filter_bit;
u_v(4,"filter size", fl,bitstream);
u_v(8,"filter number per QP",FILTER_NUMBER ,bitstream);
u_1("FilterSetPerQP flag",FilterSetPerQP,bitstream);
if (FilterSetPerQP)
{
for (QP_index=0;QP_index<FILTERS_SET_NUMBER;QP_index++)
{
if (QP_set[QP_index]==1)
{
QP_count++;
}
}
u_v(4,"filter ", QP_count,bitstream);
}
for (QP_index=0;QP_index<FILTERS_SET_NUMBER;QP_index++)
{
if (QP_set[QP_index]==1)
{
QP_count++;
for (ind=0;ind<FILTER_NUMBER;ind++)
{
QL_NumBitsInit(Numbits);
QuantizeIntegerFilterPP(filterCoeffPP[QP_index][ind], fl,ind,QP_index);
single_filter_bit=sendPostFilterInteger(bitstream,ind,0,QP_index,fl);
bit_ct+=single_filter_bit;
}
}
}
}
int sendPostFilterInteger(Bitstream *bitstream,int ind,int padding,int QPindex,int fl)
{
int newStreamFlag;
int i;
int len = 0;
int *pDiffQFilterCoeffIntPP;
int *pDepthInt=NULL;
int sqrFiltLength=(fl+1)*(fl+1);
if (fl==4)
{
pDepthInt=depthInt9x9;
}
else if (fl==3)
{
pDepthInt=depthInt7x7;
}
else if (fl==2)
{
pDepthInt=depthInt5x5;
}
pDiffQFilterCoeffIntPP = DiffQFilterCoeffIntPP[QPindex][ind];
newStreamFlag = 0;
if (bitstream==NULL)
{
bitstream = (Bitstream *) calloc(1, sizeof(Bitstream));
bitstream->streamBuffer = (byte *) calloc(1000, sizeof(byte));
bitstream->bits_to_go=8;
bitstream->byte_buf=0;
bitstream->byte_pos=0;
newStreamFlag = 1;
}
// vlc for all
for(i = 0; i < sqrFiltLength; i++)
{
len += writeCoeffPP(pDiffQFilterCoeffIntPP[i], bitstream, numQBitsIntPP[i], pDepthInt[i], "SH: full-pel filter");
}
if (padding==1)
{
// try to put 0 at the end of slice
if (bitstream->bits_to_go != 8 )
{
while(bitstream->bits_to_go != 8)
{
len += u_1("QL: paddle", 1, bitstream);
}
}
}
if (newStreamFlag)
{
free(bitstream->streamBuffer);
bitstream->streamBuffer=NULL;
free(bitstream);
bitstream=NULL;
}
return len;
}
void calcVar(int **imgY_var, imgpel **refY, int fl)
{
int i, j, ii, jj, noSamp;
#ifndef USE_MAD
int tempInt=0;
#endif
int mean, var;
for (i = 0; i < input->img_height; ++i)
{
for (j = 0; j < input->img_width; ++j)
{
mean=0,var=0;noSamp=0;
for (jj=j-fl; jj<=j+fl; jj++)
{
if (jj>=0 && jj<input->img_width)
{
for (ii=i-fl; ii<=i+fl; ii++)
{
if (ii>=0 && ii<input->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 =25;
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 < input->img_height; ++i){
for (j = 0; j < input->img_width; ++j)
{
ind=min(varImg[i][j]*FILTER_NUMBER/16, FILTER_NUMBER-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(input->img_height-1,ii));
for (jj=j-fl; jj<=j+fl; jj++){
jjLimit=max(0, min(input->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];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -