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

📄 switched_filters.c

📁 JM 11.0 KTA 2.1 Source Code
💻 C
📖 第 1 页 / 共 4 页
字号:
                  2 * wp_luma_round * (1 - img->bipred_rounding_control)) >> (luma_log_weight_denom + 1))); 
              }
              else
              {
                tmp = valOrg - ((tempF[i] + tempB[j] + 1 - img->bipred_rounding_control) >> 1); 
              }

              AccErrorB[i][j][sub_pos[0]][sub_pos[1]] += (tmp * tmp);
              SamplesB[i][j][sub_pos[0]][sub_pos[1]]++;
              SequenceAccErrorB[i][j][sub_pos[0]][sub_pos[1]] += (tmp * tmp);
            }
          }
        } // x
      } // y
    }
    else //uni-directional
    {
      int ref_index = (ref_frame[0]!= -1)? LIST_0: LIST_1;
      int ind = (ref_frame[0]!= -1)? 0: 1;

      imgY = listX[ref_index][ref_frame[ind]]->imgY;

      for(yi = 0; yi < 4; ++yi)
      {    
        for(xj = 0; xj < 4; ++xj)
        {
          int xcoordind = Clip3Fun(0 , out4Y_width,  4 * (x + xj) + 4 * IMG_PAD_SIZE + mvx[ind]);
          int ycoordind = Clip3Fun(0 , out4Y_height, 4 * (y + yi) + 4 * IMG_PAD_SIZE + mvy[ind]);

          valOrg = imgY_org[y+yi][x+xj];

          for(i = 0; i < NUM_SIFO; ++i)
          {
            // Unidirectional error is accumulated along the diagonal
            tmp = valOrg - GetInterpolatedPixel(imgY, ycoordind, xcoordind, img->width, img->height, sub_pos[ind], i);
            AccErrorB[i][i][sub_pos[ind]][sub_pos[ind]] += (tmp * tmp);
            SamplesB[i][i][sub_pos[ind]][sub_pos[ind]]++;
            SequenceAccErrorB[i][i][sub_pos[ind]][sub_pos[ind]] += (tmp * tmp);
          }
        } // x
      } // y
    } // if bidirectional
  } // for(subblock = 0; subblock < 16; subblock++)
}

//
//  Accumulate values to compute offset for F reference frames
//
static void AccumulateOffset0_B(int x_orig, int y_orig)
{
  int x, y, xj, yi, valOrg, i;
  int mvx[2], mvy[2];
  int sub_pos[2], mvx_sub, mvy_sub;
  int ref_frame[2];
  int subblock = 0;
  int out4Y_width  = (img->width + 2 * IMG_PAD_SIZE) * 4 - 1;  
  int out4Y_height = (img->height + 2 * IMG_PAD_SIZE) * 4 - 1;
  double tmp;
  int filterF;
  unsigned short ** imgY;

  if(img->type == B_SLICE)
  {
    for(subblock = 0; subblock < 16; ++subblock)
    {
      x = x_orig + 4 * (subblock % 4);
      y = y_orig + 4 * (subblock / 4);

      //get motion information
      for (i = 0; i < 2; ++i)
      {
        mvx[i] = enc_picture->mv[LIST_0+i][y/4][x/4][0];
        mvy[i] = enc_picture->mv[LIST_0+i][y/4][x/4][1];

        mvx_sub = (mvx[i] >= 0)? mvx[i] % 4: (4 - abs(mvx[i]) % 4) % 4;
        mvy_sub = (mvy[i] >= 0)? mvy[i] % 4: (4 - abs(mvy[i]) % 4) % 4;

        sub_pos[i] = mvx_sub + 4 * mvy_sub;    // pos 0..15 in a 4x4 block
        ref_frame[i] = enc_picture->ref_idx[LIST_0+i][y/4][x/4];
      }

      if(ref_frame[0] != -1)
      {
        imgY = listX[LIST_0][ref_frame[0]]->imgY;

        for(yi = 0; yi < 4; ++yi)
        {
          for(xj = 0; xj < 4;++xj)
          {
            int xcoord0 = Clip3Fun(0 , out4Y_width,  4 * (x + xj) + 4 * IMG_PAD_SIZE + mvx[0]);
            int ycoord0 = Clip3Fun(0 , out4Y_height, 4 * (y + yi) + 4 * IMG_PAD_SIZE + mvy[0]);

            valOrg = imgY_org[y+yi][x+xj];
            filterF = BestCombFilterB[sub_pos[0]];      // Use best filter

            tmp = valOrg - GetInterpolatedPixel(imgY, ycoord0, xcoord0, img->width, img->height, sub_pos[0], filterF);

            AccFrameOffsetF[ref_frame[0]] += tmp;
            SamplesFrameOffsetF[ref_frame[0]]++;
            if(ref_frame[0] == 0)
            {
              AccSubPelOffsetF[sub_pos[0]] += tmp;
              SamplesSubPelOffsetF[sub_pos[0]]++;
            }
          } // x
        } // y
      }
    } // for(subblock = 0; subblock < 16; subblock++)
  } // if (img->type==B_SLICE)
}

//
//  Computes the offsets for the F reference frames
//
static void ComputeOffset0(void)
{
  int i;
  int offset;

  // Frame offsets
  for (i = 0; i < listXsize[LIST_0]; ++i)
  {
    if(SamplesFrameOffsetF[i] > 0)
    {
      offset = (int)((double)fabs(AccFrameOffsetF[i]) / (double)SamplesFrameOffsetF[i] + 0.5);
      if (AccFrameOffsetF[i] < 0)
        offset = -offset;
    }
    else
    {
      offset = 0;
    }
    FrameOffsetF[i] = offset; // Frame offset
  }

  // SubPel offsets
  for(i = 0; i < 16; ++i)
  {
    if(SamplesSubPelOffsetF[i] > 0)
    {
      offset = (int)((double)fabs(AccSubPelOffsetF[i]) / (double)SamplesSubPelOffsetF[i] + 0.5);
      if (AccSubPelOffsetF[i] < 0)
        offset = -offset;
    }
    else
    {
      offset = 0;
    }
    SubPelOffsetF[i] = offset;
  }
}


//
//  Accumulate values to compute offset for B reference frames
//
static void AccumulateOffset1_B(int x_orig, int y_orig)
{
  int x, y, xj, yi, valOrg,i;
  int mvx[2],  mvy[2];
  int sub_pos[2], mvx_sub, mvy_sub;
  int ref_frame[2];
  int subblock = 0;
  int out4Y_width  = (img->width + 2 * IMG_PAD_SIZE) * 4 - 1;  
  int out4Y_height = (img->height + 2 * IMG_PAD_SIZE) * 4 - 1;
  double tmp, tmp1, tmp2;
  double w0, w1, denom, round;
  unsigned short ** imgY0;
  unsigned short ** imgY1;
  unsigned short ** imgY;
  int tempF, tempB, tempFsp;
  int filterF, filterB;

  int apply_weights = ((img->filterParam == SIFO_SEQ_FILTER) && (active_pps->pic_parameter_set_id == 2));

  for(subblock = 0; subblock < 16; ++subblock)
  {
    x = x_orig+4*(subblock%4);
    y = y_orig+4*(subblock/4);

    //get motion information
    for (i = 0; i < 2; ++i)
    {
      mvx[i] = enc_picture->mv[LIST_0+i][y/4][x/4][0];
      mvy[i] = enc_picture->mv[LIST_0+i][y/4][x/4][1];

      mvx_sub = (mvx[i] >= 0)? mvx[i] % 4: (4 - abs(mvx[i]) % 4) % 4;
      mvy_sub = (mvy[i] >= 0)? mvy[i] % 4: (4 - abs(mvy[i]) % 4) % 4;

      sub_pos[i] = mvx_sub + 4 * mvy_sub;    // pos 0..15 in a 4x4 block
      ref_frame[i] = enc_picture->ref_idx[LIST_0+i][y/4][x/4];
    }

    if ((ref_frame[0] != -1) && (ref_frame[1] != -1)) // bi-directional
    {
      int fw_ref_idx = ref_frame[0];
      int bw_ref_idx = ref_frame[1];

      imgY0 = listX[LIST_0][fw_ref_idx]->imgY;
      imgY1 = listX[LIST_1][bw_ref_idx]->imgY;

      if(apply_weights)
      {
        w0 = wbp_weight[0][fw_ref_idx][bw_ref_idx][0];
        w1 = wbp_weight[1][fw_ref_idx][bw_ref_idx][0];
        denom = (double)(1 << (luma_log_weight_denom + 1));
        round = 2.0 * wp_luma_round * (1 - img->bipred_rounding_control);
      }
      else
      {
        w0 = 1.0;
        w1 = 1.0;
        denom = 2.0;
        round = 1.0 - img->bipred_rounding_control;
      }

      for(yi = 0; yi < 4; ++yi)
      {
        for(xj = 0; xj < 4; ++xj)
        {
          int xcoord0 = Clip3Fun(0 , out4Y_width,  4 * (x + xj) + 4 * IMG_PAD_SIZE + mvx[0]);
          int ycoord0 = Clip3Fun(0 , out4Y_height, 4 * (y + yi) + 4 * IMG_PAD_SIZE + mvy[0]);
          int xcoord1 = Clip3Fun(0 , out4Y_width,  4 * (x + xj) + 4 * IMG_PAD_SIZE + mvx[1]);
          int ycoord1 = Clip3Fun(0 , out4Y_height, 4 * (y + yi) + 4 * IMG_PAD_SIZE + mvy[1]);

          valOrg   = imgY_org[y+yi][x+xj];

          filterF = BestCombFilterB[sub_pos[0]];
          filterB = BestCombFilterB[sub_pos[1]];

          tempF = GetInterpolatedPixel(imgY0, ycoord0, xcoord0, img->width, img->height, sub_pos[0], filterF) 
            + FrameOffsetF[fw_ref_idx];
          tempB = GetInterpolatedPixel(imgY1, ycoord1, xcoord1, img->width, img->height, sub_pos[1], filterB);
       
          tmp1 = valOrg - clip1a((int)(((w0 * tempF) + (w1 * tempB) + round) / denom)); 
          AccFrameOffsetB[bw_ref_idx] += (denom / w1) * tmp1;
          SamplesFrameOffsetB[bw_ref_idx]++;

          // Sub pel calculation is for B, so it is for sub_pos[1]
          if(ref_frame[1] == 0)
          {
            tempFsp = GetInterpolatedPixel(imgY0, ycoord0, xcoord0, img->width, img->height, sub_pos[0], filterF) 
              + SubPelOffsetF[sub_pos[0]];
            tmp2 = valOrg - clip1a((int)(((w0 * tempFsp) + (w1 * tempB) + round) / denom)); 
            AccSubPelOffsetB[sub_pos[1]] += (denom / w1) * tmp2;
            SamplesSubPelOffsetB[sub_pos[1]]++;
          }
        } // x
      } // y
    }
    else if(ref_frame[1] != -1)   // Unidirectional, consider only B
    {
      imgY = listX[LIST_1][ref_frame[1]]->imgY;

      for(yi = 0; yi < 4; ++yi)
      {
        for(xj = 0; xj < 4; ++xj)
        {
          int xcoord1 = Clip3Fun(0 , out4Y_width,  4 * (x + xj) + 4 * IMG_PAD_SIZE + mvx[1]);
          int ycoord1 = Clip3Fun(0 , out4Y_height, 4 * (y + yi) + 4 * IMG_PAD_SIZE + mvy[1]);

          valOrg = imgY_org[y+yi][x+xj];

          filterB = BestCombFilterB[sub_pos[1]];
          tempB = GetInterpolatedPixel(imgY, ycoord1, xcoord1, img->width, img->height, sub_pos[1], filterB);
          tmp = valOrg - tempB;    // Use best filter

          AccFrameOffsetB[ref_frame[1]] += tmp;
          SamplesFrameOffsetB[ref_frame[1]]++;
          if(ref_frame[1] == 0)
          {
            AccSubPelOffsetB[sub_pos[1]] += tmp;
            SamplesSubPelOffsetB[sub_pos[1]]++;
          }
        } // x
      } // y
    }
  }
}

//
//  Computes the offsets for the B reference frames
//
static void ComputeOffset1(void)
{
  int i;
  int offset;

  // Frame offsets
  for(i = 0; i < listXsize[LIST_1]; ++i)
  {
    if(SamplesFrameOffsetB[i] > 0)
    {
      offset = (int)((double)fabs(AccFrameOffsetB[i]) / (double)SamplesFrameOffsetB[i] + 0.5);
      if (AccFrameOffsetB[i] < 0)
        offset = -offset;
    }
    else
    {
      offset = 0;
    }
    FrameOffsetB[i] = offset; // Frame offset
  }

  // SubPel offsets
  for(i = 0; i < 16; ++i)
  {
    if(SamplesSubPelOffsetB[i] > 0)
    {
      offset = (int)((double)fabs(AccSubPelOffsetB[i]) / (double)SamplesSubPelOffsetB[i] + 0.5);
      if(AccSubPelOffsetB[i] < 0)
        offset = -offset;
    }
    else
    {
      offset = 0;
    }
    SubPelOffsetB[i] = offset;
  }
}


//
//
//
void SwapFilteredFrames(void)
{
  unsigned frame;

  for(frame = 0; frame < dpb.ref_frames_in_buffer; ++frame)
  {
    dpb.fs_ref[frame]->frame->p_imgY_filt = dpb.fs_ref[frame]->frame->imgY_filt;
    dpb.fs_ref[frame]->frame->imgY_filt = dpb.fs_ref[frame]->frame->imgY;
    dpb.fs_ref[frame]->frame->imgY = dpb.fs_ref[frame]->frame->p_imgY_filt;

    dpb.fs_ref[frame]->frame->p_imgY_11_filt = dpb.fs_ref[frame]->frame->imgY_11_filt;
    dpb.fs_ref[frame]->frame->imgY_11_filt = dpb.fs_ref[frame]->frame->imgY_11;
    dpb.fs_ref[frame]->frame->imgY_11 = dpb.fs_ref[frame]->frame->p_imgY_11_filt;
  }
}


//
//
//
static void ScanMacroblocksAndApplyFunction(void fun(int, int))
{
  int i, j;

  if((img->type == P_SLICE) || (img->type == B_SLICE))
  {
    // Loop over all macroblocks and call fun()
    for (i = 0; i < img->height; i = i + MB_BLOCK_SIZE)
      for (j = 0; j < img->width; j = j + MB_BLOCK_SIZE)
        fun(j, i);
  }
}

//
//  Update the filter choice for the sequence
//
static void UpdateSequenceFilters_B(void)
{
  int i;
  for(i = 0; i < 16; ++i)
    img->filterSequence[i] = SequenceBestCombFilterB[i];
}

// 
//  Main entry point
//
static int ComputeFiltersAndOffsets(void)
{
  int i;

⌨️ 快捷键说明

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