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

📄 adaptive_filter.c

📁 JM 11.0 KTA 2.1 Source Code
💻 C
📖 第 1 页 / 共 5 页
字号:
  block_x_nr = img->width/4;
}


/*!
************************************************************************
* \brief
*    resets all filter data
************************************************************************
*/
void ResetAdaptiveFilter()
{
  int i, j, k;
  if(!UseAdaptiveFilterForCurrentFrame())
  {
    return;
  }
  else
  {
    for(k = 0; k < 15; k++)
    {
      for(i = 0; i < SQR_FILTER; i++)
      {
        for(j = 0; j < SQR_FILTER; j++)
        {
          NxN_Matrix[k][i][j] = 0.0;
        }
        N_Vector[k][i]       = 0.0;
        FilterCoef[k][i]     = 0.0;
        QFilterCoef[k][i]    = 0;
        PredFilterCoef[k][i] = 0.0;
      }
      FilterFlag[k] = 0;
    }
#ifdef E_DAIF
    for(i = 0; i < SQR_FILTER_INT; ++i)
    {
      for(j = 0; j < SQR_FILTER_INT; ++j)
      {
        NxN_Matrix_Int[i][j] = 0.0;
      }
      N_Vector_Int[i] = 0.0;
      FilterCoefInt[i] = 0.0;
    }
    FilterFlagInt = 0;
#endif 
  }
  NumberOfQBits = DEFAULT_QUANT;
}


/*!
************************************************************************
* \brief
*    return if adaptive filter is used for current frame
************************************************************************
*/
int UseAdaptiveFilterForCurrentFrame(void)
{
  if((img->type == P_SLICE || img->type == B_SLICE) && input->UseAdaptiveFilter)
    return 1;
  else
    return 0;
}


/*!
************************************************************************
* \brief
*    sets necessary filter data for current macroblock
************************************************************************
*/
void SetAdaptiveFilter(void)
{
  Macroblock *currMB = &img->mb_data[img->current_mb_nr];
  int i, j, x, y, xj, yi;
  float b_scaling=1.0;
  int run=0, rerun=0;
  int equation=0;
  int mvx_subF=0, mvy_subF=0;
  int mvx_subB=0, mvy_subB=0;
  int mvx=0,  mvy=0;
  int mvxF=0, mvyF=0;
  int mvxB=0, mvyB=0;
  int sub_pos=0;
  int sub_posF=0;
  int sub_posB=0;
  int ref_frame=0;
  int ref_frameF=-1;
  int ref_frameB=-1;
  int subblock=0;
  int filter_pos_x1, filter_pos_y1, filter_pos_x2, filter_pos_y2;
  int x_orig, y_orig;       // absolute distances from current macroblock
  int h1, h2, h3;
  int *new_filter_pos, *new_eq, *new_sub_pos;
  int number_equation;
  imgpel **RecY=NULL;
  imgpel **RecYF=NULL;
  imgpel **RecYB=NULL;
  new_filter_pos = &h1;
  new_eq = &h2;
  new_sub_pos = &h3;
#ifdef EIGHTH_PEL
  if(img->mv_res)
  {
    SetAdaptiveFilterEighthpel();
    return;
  }
#endif
  if(IS_INTRA(currMB)) //intra macroblocks are not used for calculation of the filter coeffs.
    return;

  x_orig = MB_BLOCK_SIZE*(img->block_x/4);
  y_orig = MB_BLOCK_SIZE*(img->block_y/4);
  for(subblock = 0; subblock < 16; subblock++)
  {
    x = x_orig+4*(subblock%4);
    y = y_orig+4*(subblock/4);
    mvxF = enc_picture->mv[LIST_0][y/4][x/4][0];
    mvyF = enc_picture->mv[LIST_0][y/4][x/4][1];
    if(mvxF >= 0)
      mvx_subF = mvxF%4;      // x-sub-coordinate in a 4x4block
    else
      mvx_subF = (4-abs(mvxF)%4)%4;
    if(mvyF >= 0)
      mvy_subF = mvyF%4;      // y-sub-coordinate in a 4x4block
    else
      mvy_subF = (4-abs(mvyF)%4)%4;

    sub_posF = mvx_subF + 4*mvy_subF-1;    // pos 0..14 in a 4x4 block
    ref_frameF = enc_picture->ref_idx[LIST_0][y/4][x/4];
    if(ref_frameF != -1)
      RecYF  = listX[LIST_0][ref_frameF]->imgY;
    if(img->type == B_SLICE)
    {
      mvxB= enc_picture->mv[LIST_1][y/4][x/4][0];
      mvyB= enc_picture->mv[LIST_1][y/4][x/4][1];
      if(mvxB >= 0)
        mvx_subB = mvxB%4;      // x-sub-coordinate in a 4x4block
      else
        mvx_subB = (4-abs(mvxB)%4)%4;
      if(mvyB >= 0)
        mvy_subB = mvyB%4;      // y-sub-coordinate in a 4x4block
      else
        mvy_subB = (4-abs(mvyB)%4)%4;

      sub_posB = mvx_subB + 4*mvy_subB-1;    // pos 0..14 in a 4x4 block
      ref_frameB = enc_picture->ref_idx[LIST_1][y/4][x/4];
      if(ref_frameB != -1)
        RecYB  = listX[LIST_1][ref_frameB]->imgY;
      rerun = 1;
    }
    else
      rerun = 0;
    if(ref_frameB != -1 && ref_frameF != -1)
      b_scaling = 0.5;
    else
      b_scaling = 1.0;
    for(run = 0; run <= rerun; run++)
    {
      if(run == 0)
      {
        sub_pos = sub_posF;
        mvx = mvxF;
        mvy = mvyF;
        RecY = RecYF;
        ref_frame = ref_frameF;
      }
      else
      {
        sub_pos = sub_posB;
        mvx = mvxB;
        mvy = mvyB;
        RecY = RecYB;
        ref_frame = ref_frameB;
      }

      if(sub_pos != -1 && ref_frame != -1 ) // if no full-pel motion
      {
#ifndef DIRECTIONAL_FILTER
        if((sub_pos+1)%4 == 0 || (sub_pos+1)/4 == 0)      // if line or column, then only 1D-Filter,
          number_equation = FILTER_SIZE;                  // hor or vert. resp.
        else
          number_equation = SQR(FILTER_SIZE);
#else
        if (Is1DPosition_orig[sub_pos])// separate branch for Z18 filter
          number_equation = FILTER_SIZE;          // 1D case
        else
          number_equation = SQR(FILTER_SIZE);
#endif

        for(yi = 0; yi < 4; yi++)    //y
        {
          for(xj = 0; xj < 4; xj++)  //x
          {
            for(equation = 0; equation < number_equation; equation++)
            {
              if(number_equation == SQR(FILTER_SIZE))
              {
                filter_pos_x1 = FindPosition(img->width, x+xj,equation%FILTER_SIZE,mvx);          //current derivation (h_ij)
                filter_pos_y1 = FindPosition(img->height,y+yi,equation/FILTER_SIZE,mvy);          //current derivation (h_ij)
#ifdef DIRECTIONAL_FILTER
                if (IsDiagonal1D[sub_pos]==0)
#endif
                {
                  for(i = 0; i < FILTER_SIZE; i++)
                  {
                    for(j = 0; j < FILTER_SIZE; j++)
                    {
                      filter_pos_x2 = FindPosition(img->width, x+xj,j,mvx);
                      filter_pos_y2 = FindPosition(img->height,y+yi,i,mvy);
                      ReorderPosition(new_filter_pos,  new_eq,   new_sub_pos,
                        FILTER_SIZE*i+j, equation, sub_pos);
                      NxN_Matrix[*new_sub_pos][*new_eq][*new_filter_pos] += b_scaling*
                        RecY[filter_pos_y1][filter_pos_x1]*
                        RecY[filter_pos_y2][filter_pos_x2];
                    }
                  }
                }
#ifdef DIRECTIONAL_FILTER
                else if (IsDiagonal1D[sub_pos]==1)//NW-SE
                {
                  // Count correlation functions only for diagonal NW-SE
                  if (!((equation==0)||(equation==7)||(equation==14)||
                    (equation==21)||(equation==28)||(equation==35)))
                    continue;
                  for(i = 0; i < FILTER_SIZE; i++)
                  {
                    j = i;
                    filter_pos_x2 = FindPosition(img->width, x+xj,j,mvx);
                    filter_pos_y2 = FindPosition(img->height,y+yi,i,mvy);
                    ReorderPosition(new_filter_pos,  new_eq,   new_sub_pos,
                      FILTER_SIZE*i+j, equation, sub_pos);
                    NxN_Matrix[*new_sub_pos][*new_eq][*new_filter_pos] += b_scaling*
                      RecY[filter_pos_y1][filter_pos_x1]*
                      RecY[filter_pos_y2][filter_pos_x2];
                  }
                }else if (IsDiagonal1D[sub_pos]==2)//NE-SW
                {
                  // Count correlation functions only for diagonal NE-SW
                  if (!((equation==5)||(equation==10)||(equation==15)||
                    (equation==20)||(equation==25)||(equation==30)))

                    continue;
                  for(i = FILTER_SIZE-1; i >=0; i--)
                  {
                    j = FILTER_SIZE-1 - i;
                    filter_pos_x2 = FindPosition(img->width, x+xj,j,mvx);
                    filter_pos_y2 = FindPosition(img->height,y+yi,i,mvy);
                    ReorderPosition(new_filter_pos,  new_eq,   new_sub_pos,
                      FILTER_SIZE*i+j, equation, sub_pos);
                    NxN_Matrix[*new_sub_pos][*new_eq][*new_filter_pos] += b_scaling*
                      RecY[filter_pos_y1][filter_pos_x1]*
                      RecY[filter_pos_y2][filter_pos_x2];
                  }
                }
                else if (IsDiagonal1D[sub_pos]==3)//NW-SE & NE-SW
                {
                  // Count correlation functions only for diagonal NW-SE
                  if (!((equation==0)||(equation==7)||(equation==14)||
                    (equation== 5)||(equation==10)||(equation==15)||
                    (equation==20)||(equation==25)||(equation==30)||
                    (equation==21)||(equation==28)||(equation==35)))
                    continue;
                  for(i = 0; i < FILTER_SIZE; i++)
                  {
                    j = i;
                    filter_pos_x2 = FindPosition(img->width, x+xj,j,mvx);
                    filter_pos_y2 = FindPosition(img->height,y+yi,i,mvy);
                    ReorderPosition(new_filter_pos,  new_eq,   new_sub_pos,
                      FILTER_SIZE*i+j, equation, sub_pos);
                    NxN_Matrix[*new_sub_pos][*new_eq][*new_filter_pos] += b_scaling*
                      RecY[filter_pos_y1][filter_pos_x1]*
                      RecY[filter_pos_y2][filter_pos_x2];
                    {//  Compute XCors for diagonal filter
                      j = FILTER_SIZE-1 - i;
                      filter_pos_x2 = FindPosition(img->width, x+xj,j,mvx);
                      filter_pos_y2 = FindPosition(img->height,y+yi,i,mvy);
                      ReorderPosition(new_filter_pos,  new_eq,   new_sub_pos,
                        FILTER_SIZE*i+j, equation, sub_pos);
                      NxN_Matrix[*new_sub_pos][*new_eq][*new_filter_pos] += b_scaling*
                        RecY[filter_pos_y1][filter_pos_x1]*
                        RecY[filter_pos_y2][filter_pos_x2];
                    }
                  }
                }
#endif
              }
              else   // 1D-Filter case
              {
                if((sub_pos+1) / 4 == 0)  // horizontal
                {
                  filter_pos_x1 = FindPosition(img->width, x+xj,equation%FILTER_SIZE,mvx);                                               //current derivation (h_ij)
                  filter_pos_y1 = FindPosition(img->height,y+yi,FILTER_OFFSET,mvy);                                               //current derivation (h_ij)
                  for(i = 0; i < FILTER_SIZE; i++)
                  {
                    filter_pos_x2 = FindPosition(img->width, x+xj, i,mvx);
                    filter_pos_y2 = FindPosition(img->height,y+yi, FILTER_OFFSET,mvy);
                    ReorderPosition(new_filter_pos,   new_eq, new_sub_pos,
                      i, equation,   sub_pos);

                    NxN_Matrix[*new_sub_pos][*new_eq][*new_filter_pos] += b_scaling*
                      RecY[filter_pos_y1][filter_pos_x1]*
                      RecY[filter_pos_y2][filter_pos_x2];
                  }
                }
                else // vertical
                {
                  filter_pos_x1 = FindPosition(img->width, x+xj,FILTER_OFFSET,mvx);                                                  //current derivation (h_ij)
                  filter_pos_y1 = FindPosition(img->height,y+yi,equation%FILTER_SIZE,mvy);                                              //current derivation (h_ij)
                  for(i = 0; i < FILTER_SIZE; i++)
                  {
                    filter_pos_x2 = FindPosition(img->width, x+xj, FILTER_OFFSET,mvx);
                    filter_pos_y2 = FindPosition(img->height,y+yi, i,mvy);
                    ReorderPosition(new_filter_pos,   new_eq, new_sub_pos,
                      i, equation,   sub_pos);
                    NxN_Matrix[*new_sub_pos][*new_eq][*new_filter_pos] += b_scaling*
                      RecY[filter_pos_y1][filter_pos_x1]*
                      RecY[filter_pos_y2][filter_pos_x2];
                  }
                }
              }
#ifdef DIRECTIONAL_FILTER
              if (IsDiagonal1D[sub_pos]==1)//NW-SE
              {
                // Count correlation functions only for diagonal NW-SE
                if (!((equation==0)||(equation==7)||(equation==14)||
                  (equation==21)||(equation==28)||(equation==35)))
                  continue;
              }
              else if (IsDiagonal1D[sub_pos]==2)//NE-SW

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -