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

📄 postprocessing.c

📁 JM 11.0 KTA 2.1 Source Code
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -