⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 postprocessing.c

📁 JM 11.0 KTA 2.1 Source Code
💻 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 + -