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

📄 switched_filters.c

📁 JM 11.0 KTA 2.1 Source Code
💻 C
📖 第 1 页 / 共 4 页
字号:
  // While SAD can be improved
  while((minSAD = get_min_d(err, min_d, tmp_d, oldSAD)) < oldSAD)
  {
    oldSAD = minSAD;        
    memcpy(min_d, tmp_d, sizeof(int) * 16);
  }

  // Copy result
  memcpy(out, min_d, sizeof(int) * 16);
}


//
//  Compute filter combination for frame and sequence
//
static void ComputeFilterCombination_B()
{
  ComputeFilterCombination_B_gd(AccErrorB, BestCombFilterB);
  ComputeFilterCombination_B_gd(SequenceAccErrorB, SequenceBestCombFilterB);
}

//
//
//
static void ResetAll(int slice)
{
  int a, b, c, d;
  static int firstP = 1;
  static int firstB = 1;

  if(slice == P_SLICE)
  {
    memset(SamplesSubPelOffset, 0, 16 * sizeof(int));
    memset(SamplesFrameOffsetP, 0, MAX_REFERENCE_PICTURES * sizeof(int));

    for(a = 0; a < NUM_SIFO; ++a)
      for(b = 0; b < 16; ++b)
        AccErrorP[a][b] = 0;

    for(a = 0; a < MAX_REFERENCE_PICTURES; ++a)
      for(b = 0; b < 16; ++b)
        for(c = 0; c < NUM_SIFO; ++c)
          AccFrameOffsetP[a][b][c] = 0;

    if(firstP == 1)
    {
      firstP = 0;

      for(a = 0; a < 16; ++a)
        for(b = 0; b < NUM_SIFO; ++b)
          SequenceAccErrorP[b][a] = 0;
    }
    else
    {
      for(a = 0; a < 16; ++a)
        for(b = 0; b < NUM_SIFO; ++b)
          SequenceAccErrorP[b][a] *= NORM_FACTOR;
    }
  }
  else if(slice == B_SLICE)
  {
    // Error
    for(a = 0; a < NUM_SIFO; ++a)
      for(b = 0; b < NUM_SIFO; ++b)
        for(c = 0; c < 16; ++c)
          for(d = 0; d < 16; ++d)
          {
            AccErrorB[a][b][c][d] = 0.0;
            SamplesB[a][b][c][d] = 0;
          }

    // Frame offsets
    for(a = 0; a < MAX_REFERENCE_PICTURES; ++a)
    {
      AccFrameOffsetF[a] = AccFrameOffsetB[a] = 0;
      FrameOffsetF[a] = FrameOffsetB[a] = 0;
      SamplesFrameOffsetF[a] = SamplesFrameOffsetB[a] = 0;
    }

    // SubPel offsets
    memset(AccSubPelOffsetF, 0, 16 * sizeof(double));
    memset(AccSubPelOffsetB, 0, 16 * sizeof(double));
    memset(SubPelOffsetF, 0, 16 * sizeof(int));
    memset(SubPelOffsetB, 0, 16 * sizeof(int));
    memset(SamplesSubPelOffsetF, 0, 16 * sizeof(int));
    memset(SamplesSubPelOffsetB, 0, 16 * sizeof(int));
    memset(BestCombFilterB, 0, 16 * sizeof(int));

    if(firstB == 1)
    {    
      firstB = 0;
      memset(SequenceBestCombFilterB, 0, 16 * sizeof(int));

      for(a = 0; a < NUM_SIFO; ++a)
        for(b = 0; b < NUM_SIFO; ++b)
          for(c = 0; c < 16; ++c)
            for(d = 0; d < 16; ++d)
              SequenceAccErrorB[a][b][c][d] = 0;
    }
    else
    {
      for(a = 0; a < NUM_SIFO; ++a)
        for(b = 0; b < NUM_SIFO; ++b)
          for(c = 0; c < 16; ++c)
            for(d = 0; d < 16; ++d)
              SequenceAccErrorB[a][b][c][d] *= NORM_FACTOR;
    }
  }  
}

//
//  Return the value of a pixel interpolated with filter filterNo 
//
static int GetInterpolatedPixel(unsigned short ** img, int icoord, int jcoord, 
                         int img_width, int img_height, int sub_pos, int filterNo)
{
  int pos_x, pos_y;
  double ipVal;
  int out;
  int ii, jj;
  int i, j;

#define FILTER_SIZE       6                     // Undefined at the end of the function
#define FILTER_OFFSET     (6 / 2 - 1)           // Undefined at the end of the function

  assert(filterNo < NUM_SIFO);

  ipVal = 0.0;
  i = icoord - 4 * IMG_PAD_SIZE;
  j = jcoord - 4 * IMG_PAD_SIZE;
  if(sub_pos)
  {
    for(ii = 0; ii < FILTER_SIZE; ++ii)
    {
      for(jj = 0; jj < FILTER_SIZE; ++jj)
      {
        pos_y = Clip3Fun(0, img_height - 1, i / 4 - FILTER_OFFSET + ii);
        if((i < 0) && (pos_y > 0))
          pos_y -= 1;
        pos_x = Clip3Fun(0, img_width - 1, j / 4 - FILTER_OFFSET + jj);
        if((j < 0) && (pos_x > 0))
          pos_x -=1;
        ipVal += (SIFO_FILTER[filterNo][sub_pos - 1][FILTER_SIZE * ii + jj] * img[pos_y][pos_x]);
      }
    }
    out = Clip3Fun(0, 255, (int)(ipVal + 0.5));
  }
  else
  {
    out = img[Clip3Fun(0, img_height - 1, i / 4)][Clip3Fun(0, img_width - 1, j / 4)];
  }

#undef FILTER_OFFSET
#undef FILTER_SIZE

  return out;
}

//
//
//
static void AccumulateError_P(int x_orig, int y_orig)
{
  int x, y, xj, yi, temp, valOrg;
  int mvx = 0,  mvy = 0;
  int sub_pos = 0, mvx_sub, mvy_sub;
  int ref_frame = 0;
  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;
  unsigned short ** imgY;
  int f;

  for(subblock = 0; subblock < 16; ++subblock)
  {
    x = x_orig + 4 * (subblock % 4);
    y = y_orig + 4 * (subblock / 4);
    mvx = enc_picture->mv[LIST_0][y / 4][x / 4][0];
    mvy = enc_picture->mv[LIST_0][y / 4][x / 4][1];

    mvx_sub = (mvx >= 0)? mvx % 4: (4 - abs(mvx) % 4) % 4;
    mvy_sub = (mvy >= 0)? mvy % 4: (4 - abs(mvy) % 4) % 4;
    sub_pos = mvx_sub + 4 * mvy_sub;    // pos 0..15 in a 4x4 block 

    ref_frame = enc_picture->ref_idx[LIST_0][y / 4][x / 4];

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

      for(yi = 0; yi < 4; ++yi)
      {
        for(xj = 0; xj < 4; ++xj)
        {
          int xcoord = Clip3Fun(0, out4Y_width, 4 * (x + xj) + 4 * IMG_PAD_SIZE + mvx);
          int ycoord = Clip3Fun(0, out4Y_height, 4 * (y + yi) + 4 * IMG_PAD_SIZE + mvy);

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

          for(f = 0; f < NUM_SIFO; ++f)
          {
            temp = valOrg - GetInterpolatedPixel(imgY, ycoord, xcoord, img->width, img->height, sub_pos, f);
            AccFrameOffsetP[ref_frame][sub_pos][f] += temp;
            AccErrorP[f][sub_pos] += temp * temp;
          }

          SamplesFrameOffsetP[ref_frame]++;

          if(ref_frame == 0)
            SamplesSubPelOffset[sub_pos]++;
        }
      }
    }
  }
}


//
//
//
static void ComputeFiltersAndOffsets_P()
{
  int i, frame, ind, offset;
  double combAccSamplesFrameOffsetP[MAX_REFERENCE_PICTURES], combAccFrameOffsetP[16], minVal;
    
  // Filter selection based on the current frame
  for(i = 0; i < 16; ++i)
  {
    img->filterFrame[i] = 0;
    minVal = AccErrorP[0][i];
    for(ind = 1; ind < NUM_SIFO; ++ind)
    {
      if(AccErrorP[ind][i] < minVal)
      {
        img->filterFrame[i] = ind;
        minVal = AccErrorP[ind][i];
      }
    }
  }

  // Frame offsets corresponding to the frame filters
  for(frame = 0; frame < listXsize[LIST_0]; ++frame)
  {
    combAccFrameOffsetP[frame] = 0;
    for(i = 0; i < 16; ++i)
      combAccFrameOffsetP[frame] += AccFrameOffsetP[frame][i][img->filterFrame[i]];

    img->imgOffset_list0[frame] = 0;
    if(SamplesFrameOffsetP[frame] > 0)
    {
      offset = (int)(fabs(combAccFrameOffsetP[frame]) / (double)SamplesFrameOffsetP[frame] + 0.5);
      img->imgOffset_list0[frame] = (combAccFrameOffsetP[frame] >= 0)? offset: -offset;
    }
  }

  // Sub-pel offsets
  for(i = 0; i < 16; ++i)
  {
    combAccSamplesFrameOffsetP[i] = AccFrameOffsetP[0][i][img->filterFrame[i]];

    img->subpelOffset_list0[i] = 0;
    if(SamplesSubPelOffset[i] > 0)
    {
      offset = (int)((double)fabs(combAccSamplesFrameOffsetP[i]) / (double)SamplesSubPelOffset[i] + 0.5);
      img->subpelOffset_list0[i] = (combAccSamplesFrameOffsetP[i] >= 0)? offset: -offset;
    }
  }
}

//
//
//
static void UpdateSequenceFilters_P(void)
{
  int i, f, ind;
  double minVal;

  // Filter selection based on the sequence 
  for(i = 0; i < 16; ++i)
  {
    for(f = 0; f < NUM_SIFO; ++f)
      SequenceAccErrorP[f][i] += AccErrorP[f][i];

    img->filterSequence[i] = 0;
    minVal = SequenceAccErrorP[0][i];
    for(ind = 1; ind < NUM_SIFO; ++ind)
    {
      if(SequenceAccErrorP[ind][i] < minVal)
      {
        img->filterSequence[i] = ind;
        minVal = SequenceAccErrorP[ind][i];
      }
    }
  }
}




//
//  Accumulate squared error to compute best filter combination
//
static void AccumulateError_B(int x_orig, int y_orig)
{
  int x, y, xj, yi, valOrg, i, j;
  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 apply_weights = ((img->filterParam == SIFO_SEQ_FILTER) && (active_pps->pic_parameter_set_id == 2));
  unsigned short ** imgY0;
  unsigned short ** imgY1;
  unsigned short ** imgY;
  int f;

  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))
      continue;     // Intra macroblocks are not used for calculation

    if ((ref_frame[0] != -1) && (ref_frame[1] != -1)) // Bi-predicted
    {
      int tempF[NUM_SIFO], tempB[NUM_SIFO];
      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;

      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];

          for(f = 0; f < NUM_SIFO; ++f)
          {
            tempF[f] = GetInterpolatedPixel(imgY0, ycoord0, xcoord0, img->width, img->height, sub_pos[0], f);          
            tempB[f] = GetInterpolatedPixel(imgY1, ycoord1, xcoord1, img->width, img->height, sub_pos[1], f);
          }

          for(i = 0; i < NUM_SIFO; ++i)
          {
            for(j = 0; j < NUM_SIFO; ++j)
            {
              if(apply_weights)
              {            
                tmp = valOrg - clip1a(((wbp_weight[0][fw_ref_idx][bw_ref_idx][0] * tempF[i] + 
                  wbp_weight[1][fw_ref_idx][bw_ref_idx][0] * tempB[j] + 
                  (wp_offset[0][fw_ref_idx][0] + wp_offset[1][bw_ref_idx][0]) * 2 * wp_luma_round +

⌨️ 快捷键说明

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