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

📄 adaptive_filter_decision.c

📁 JM 11.0 KTA 2.1 Source Code
💻 C
📖 第 1 页 / 共 2 页
字号:
  }
  return 0;
}

//
//  Decide filter usage by exhaustive search
//
static void Exhaustive(double C[2][2][D_SIZE][D_SIZE], int AvailFilter[D_SIZE], int nBits[D_SIZE], int D[D_SIZE])
{
  int i, j;
  int decision;
  double BestCost = DBL_MAX;
  double TmpCost; 
  int TmpD[D_SIZE] = {0};
  double lambda; 
#ifdef RDO_Q
  int qp = input->UseRDO_Q ? img->masterQP:img->qp;
#else
  int qp = img->qp;
#endif

  if ((img->type==B_SLICE) && img->nal_reference_idc)
  {
    lambda = img->lambda_me[5][qp];  
  }
  else
  {
    lambda = img->lambda_me[img->type][qp];
  }

  for(decision = 0; decision < (1 << D_SIZE); ++decision)
  {
    if(is_incompatible(decision, AvailFilter, TmpD))
      continue;

    TmpCost = 0.0;

    for(i = 0; i < D_SIZE; ++i)
      for(j = 0; j < D_SIZE; ++j)
        TmpCost += C[TmpD[i]][TmpD[j]][i][j];

    for(i = 0; i < D_SIZE; ++i)
      if(TmpD[i])
        TmpCost += BitCost(i, nBits, TmpD) * lambda;

    if(TmpCost < BestCost)
    {
      BestCost = TmpCost;
      for(i = 0; i < D_SIZE; ++i)
        D[i] = TmpD[i];
    }
  }
}

//
//  SAD-based optimal decision on the integer and sub-pel positions
//
void AIFDecision(int *FilterFlagInt, int *FilterFlag, int *SymmetryPosition)
{
  int img_width, img_height;
  int mbx, mby; 
  int x_orig, y_orig;
  int curr_mb_nr;
  int subblock;
  int max_mb_nr = (img->width * img->height) / 256;
  double C[2][2][D_SIZE][D_SIZE] = {{{{0.0}}}};
  int nBits[D_SIZE] = {0};                // Bits required to encode offset and filter coefficients
  int AvailFilter[D_SIZE] = {0};          // 1 if the corresponding filter is available
  int D[D_SIZE] = {0};                    // Decision vector (0/1 don't use/use corresponding filter)
  int x, y;
  int ref_frameF, ref_frameB;
  int F_nrefs = 0;                        // Counts number of F and B references
  int B_nrefs = 0;
  int mvxF = 0;
  int mvyF = 0;
  int mvxB = 0;
  int mvyB = 0;
  int sub_posF = 0;
  int sub_posB = 0;
  imgpel **refYF = NULL;
  imgpel **refYB = NULL;
  int sub_pos;
  float b_scaling = 1.0;
  double pix_00, pix_01, pix_10, pix_11;
  imgpel rec_00, rec_01, rec_10, rec_11;
  imgpel orig;
  int filterF, filterB;
  int i, j;
  double pixAifF, pixAifB;
  double pixStdF, pixStdB;

#ifdef  INTERNAL_BIT_DEPTH_INCREASE
  imgpel max_pixel_value = (1 << img->bitdepth_luma) - 1;
#else
  imgpel max_pixel_value = 255;
#endif

  img_width  = dpb.fs_ref[0]->frame->size_x;
  img_height = dpb.fs_ref[0]->frame->size_y;

  // Cost of encoding offset and coefficients
  if(*FilterFlagInt && input->UseAdaptiveFilter == FILTER_TYPE_EDAIF)
  {
    nBits[SpPos2Idx(int_pos, D_SIZE)] = sendAIFInteger_EDAIF(NULL) + sendAIFOffset(-1, NULL);
    AvailFilter[SpPos2Idx(int_pos, D_SIZE)] = 1;
  }

  for(sub_pos = a_pos; sub_pos <= o_pos; ++sub_pos)
  {
    if(SymmetryPosition[sub_pos] && FilterFlag[sub_pos])
    {
      nBits[SpPos2Idx(sub_pos, D_SIZE)] = estimateCostOfCoefs_EDAIF(sub_pos);
      if(input->UseAdaptiveFilter == FILTER_TYPE_EDAIF)
        nBits[SpPos2Idx(sub_pos, D_SIZE)] += sendAIFOffset(sub_pos, NULL);
      AvailFilter[SpPos2Idx(sub_pos, D_SIZE)] |= FilterFlag[sub_pos];
    }
  }

  // SAD computation
  for(curr_mb_nr = 0; curr_mb_nr < max_mb_nr; ++curr_mb_nr)
  {
    mbx = curr_mb_nr % (img_width / MB_BLOCK_SIZE);
    mby = curr_mb_nr / (img_width / MB_BLOCK_SIZE); 
    x_orig = mbx * MB_BLOCK_SIZE;
    y_orig = mby * MB_BLOCK_SIZE;

    if(IS_INTRA(&img->mb_data[curr_mb_nr]))
      continue; 

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

      ref_frameF = enc_picture->ref_idx[LIST_0][y / 4][x / 4];
      ref_frameB = enc_picture->ref_idx[LIST_1][y / 4][x / 4];

      if(IS_REF_VALID(ref_frameF))
      {
        mvxF = enc_picture->mv[LIST_0][y / 4][x / 4][0];
        mvyF = enc_picture->mv[LIST_0][y / 4][x / 4][1];
        sub_posF = GetSubPos(mvxF, mvyF);
        refYF = listX[LIST_0][ref_frameF]->imgY;
        ++F_nrefs;
      }

      if(IS_REF_VALID(ref_frameB))
      {
        mvxB = enc_picture->mv[LIST_1][y / 4][x / 4][0];
        mvyB = enc_picture->mv[LIST_1][y / 4][x / 4][1];
        sub_posB = GetSubPos(mvxB, mvyB);
        refYB = listX[LIST_1][ref_frameB]->imgY; 
        ++B_nrefs;
      }

      // b_scaling computation
      if(IS_REF_VALID(ref_frameF) && IS_REF_VALID(ref_frameB))
      {
#ifdef USE_POC_WEIGHTS_IN_RDDECISION
        int td, tb;
        td = Clip3(-128, 127, (listX[LIST_1][ref_frameB]->poc - listX[LIST_0][ref_frameF]->poc));
        tb = Clip3(-128, 127, (enc_picture->poc - listX[LIST_0][ref_frameF]->poc));
        if (td != 0)
          b_scaling = (float) tb / (float) td;      // POC-based
        else
#endif
          b_scaling = 0.5;                          // 1/2
      }
      else if(IS_REF_VALID(ref_frameF) || IS_REF_VALID(ref_frameB))
      {
        b_scaling = 1.0; 
      }

      // Check if the filters exist and is primary
      filterF = IS_REF_VALID(ref_frameF)? ((sub_posF == int_pos)? *FilterFlagInt: FilterFlag[sub_posF]): 0;
      filterB = IS_REF_VALID(ref_frameB)? ((sub_posB == int_pos)? *FilterFlagInt: FilterFlag[sub_posB]): 0;
      if(!filterF && !filterB)
        continue;


      // Bidirectional
      if(IS_REF_VALID(ref_frameF) && IS_REF_VALID(ref_frameB))
      {
        for(i = y; i < y + 4; ++i)
        {
          for(j = x; j < x + 4; ++j)
          {
            if(filterF)
              pixAifF = GetAIFPixel(refYF, i, j, sub_posF, mvxF, mvyF, AIF_INTERPOLATION);
            else
              pixAifF = GetAIFPixel(refYF, i, j, sub_posF, mvxF, mvyF, STD_INTERPOLATION);

            if(filterB)
              pixAifB = GetAIFPixel(refYB, i, j, sub_posB, mvxB, mvyB, AIF_INTERPOLATION);
            else
              pixAifB = GetAIFPixel(refYB, i, j, sub_posB, mvxB, mvyB, STD_INTERPOLATION);

            pixStdF = GetAIFPixel(refYF, i, j, sub_posF, mvxF, mvyF, STD_INTERPOLATION);
            pixStdB = GetAIFPixel(refYB, i, j, sub_posB, mvxB, mvyB, STD_INTERPOLATION);

            pix_00 = (1 - b_scaling) * pixStdF + b_scaling * pixStdB;
            pix_01 = (1 - b_scaling) * pixStdF + b_scaling * pixAifB;
            pix_10 = (1 - b_scaling) * pixAifF + b_scaling * pixStdB;
            pix_11 = (1 - b_scaling) * pixAifF + b_scaling * pixAifB;

            rec_00 = max(0, min(max_pixel_value, (int)(pix_00 + 0.5)));
            rec_01 = max(0, min(max_pixel_value, (int)(pix_01 + 0.5)));
            rec_10 = max(0, min(max_pixel_value, (int)(pix_10 + 0.5)));
            rec_11 = max(0, min(max_pixel_value, (int)(pix_11 + 0.5)));

            orig = (int)(imgY_org[i][j]);

            if(filterF && filterB)
            {
              // Both filters are valid
              C[0][0][SpPos2Idx(sub_posF, D_SIZE)][SpPos2Idx(sub_posB, D_SIZE)] += (double)abs(orig - rec_00);
              C[1][1][SpPos2Idx(sub_posF, D_SIZE)][SpPos2Idx(sub_posB, D_SIZE)] += (double)abs(orig - rec_11);

              if(sub_posF != sub_posB)
              {
                // Sub-pel positions are not using the same filter
                C[0][1][SpPos2Idx(sub_posF, D_SIZE)][SpPos2Idx(sub_posB, D_SIZE)] += (double)abs(orig - rec_01);
                C[1][0][SpPos2Idx(sub_posF, D_SIZE)][SpPos2Idx(sub_posB, D_SIZE)] += (double)abs(orig - rec_10);
              }
            } 
            else if(filterF)
            {
              // Filter F is valid
              C[0][0][SpPos2Idx(sub_posF, D_SIZE)][SpPos2Idx(sub_posB, D_SIZE)] += (double)abs(orig - rec_00);
              C[1][0][SpPos2Idx(sub_posF, D_SIZE)][SpPos2Idx(sub_posB, D_SIZE)] += (double)abs(orig - rec_10);
            }
            else
            {
              // Filter B is valid
              C[0][0][SpPos2Idx(sub_posF, D_SIZE)][SpPos2Idx(sub_posB, D_SIZE)] += (double)abs(orig - rec_00);
              C[0][1][SpPos2Idx(sub_posF, D_SIZE)][SpPos2Idx(sub_posB, D_SIZE)] += (double)abs(orig - rec_01);
            }
          }
        }
      }
      else
      {
        if(IS_REF_VALID(ref_frameB))
        {
          if(!filterB)
          {
            continue;
          }
          else
          {
            sub_posF = sub_posB;
            mvxF = mvxB; 
            mvyF = mvyB; 
            refYF = refYB;
          }
        }
        else if(!filterF)
        {
          continue;
        }

        for(i = y; i < y + 4; ++i)
        {
          for(j = x; j < x + 4; ++j)
          {            
            pix_00 = GetAIFPixel(refYF, i, j, sub_posF, mvxF, mvyF, STD_INTERPOLATION);
            pix_11 = GetAIFPixel(refYF, i, j, sub_posF, mvxF, mvyF, AIF_INTERPOLATION);

            rec_00 = max(0, min(max_pixel_value, (int)(pix_00 + 0.5)));
            rec_11 = max(0, min(max_pixel_value, (int)(pix_11 + 0.5)));

            orig   = (int)(imgY_org[i][j]);

            C[0][0][SpPos2Idx(sub_posF, D_SIZE)][SpPos2Idx(sub_posF, D_SIZE)] += (double)abs(orig - rec_00);
            C[1][1][SpPos2Idx(sub_posF, D_SIZE)][SpPos2Idx(sub_posF, D_SIZE)] += (double)abs(orig - rec_11);
          }
        }
      }     // Bidirectional if
    }     // Subblock loop
  }     // Macroblock loop

  // Decision
  if((F_nrefs == 0) || (B_nrefs == 0))
    Diagonal(C, AvailFilter, nBits, D);            // All references from the same direction
  else
    Exhaustive(C, AvailFilter, nBits, D);

  // Output
  *FilterFlagInt = D[0];
  for(i = 1; i < D_SIZE; ++i)
    FilterFlag[Idx2SpPos(i, D_SIZE)] = D[i];
}

#endif // E_DAIF

⌨️ 快捷键说明

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