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

📄 adaptive_filter_decision.c

📁 JM 11.0 KTA 2.1 Source Code
💻 C
📖 第 1 页 / 共 2 页
字号:
//
//  Decides which adaptive filters should be used
//
//
#include <stdio.h>
#include <math.h>
#include <float.h>
#include <stdlib.h>
#include <memory.h>
#include <assert.h>

#include "defines.h"
#include "adaptive_filter.h"
#include "header.h"
#include "global.h" 
#include "image.h"

#ifdef E_DAIF
#define int_pos             -1            // This should go where the defines for a_pos - o_pos are

#define STD_INTERPOLATION   0             // Interpolation selection in GetAIFPixel()
#define AIF_INTERPOLATION   1

#define IS_REF_VALID(F)     ((F) != -1)   // Checks reference

#define D_SIZE              6             // Size of the decision vector (one integer + 5 sub-pel position)

#define USE_POC_WEIGHTS_IN_RDDECISION

extern int FILTER_OFFSET_INT;
extern int FILTER_SIZE;
extern double FilterCoefInt[SQR_FILTER_INT];
extern double FilterCoef[15][SQR_FILTER];
extern double STANDARD_2D_FILTER_orig[15][SQR_FILTER];
extern double STANDARD_2D_FILTER[15][SQR_FILTER];

//
//  Maps an integer or a sub-pixel position to an index in the range [0,...,d_size-1] 
//
static int SpPos2Idx(int position, int d_size)
{
  switch(d_size)
  {
  case 6:
    {
      static int map[16] = {0, 1, 2, 1,         // I, a, b, a
        1, 3, 4, 3,         // a, e, f, e 
        2, 4, 5, 4,         // b, f, j, f
        1, 3, 4, 3};        // a, e, f, e
      return map[position + 1];
    }
  case 9:
    {
      static int map[16] = {0, 1, 2, 1,         // I, a, b, a
        3, 4, 5, 4,         // d, e, f, e 
        6, 7, 8, 7,         // h, i, j, i
        3, 4, 5, 4};        // d, e, f, e
      return map[position + 1];
    }
  case 16:
    {
      static int map[16] = {0 , 1,  2,  3,       // I, a, b, c
        4,  5,  6,  7,       // d, e, f, g 
        8 , 9, 10, 11,       // h, i, j, k
        12, 13, 14, 15};      // l, m, n, o
      return map[position + 1];
    }
  default:
    {
      assert(0);
      return -1;
    }
  }
}

//
//  Maps an index in [0,...,d_size-1] to the corresponding integer or sub-pixel position 
//
static int Idx2SpPos(int position, int d_size)
{
  switch(d_size)
  {
  case 6:
    {
      static int map[6] = {int_pos, a_pos, b_pos, 
        e_pos, f_pos, j_pos};
      return map[position];
    }
  case 9:
    {
      static int map[9] = {int_pos, a_pos, b_pos, 
        d_pos, e_pos, f_pos, 
        h_pos, i_pos, j_pos};
      return map[position];
    }
  case 16:
    {
      static int map[16] = {int_pos, a_pos, b_pos, c_pos,
        d_pos, e_pos, f_pos, g_pos,
        h_pos, i_pos, j_pos, k_pos,
        l_pos, m_pos, n_pos, o_pos};
      return map[position];
    }
  default:
    {
      assert(0);
      return -1;
    }
  }
}


//
//  Return pixel after interpolation with AIF or standard filter
//
static double GetAIFPixel(imgpel **refY, int i, int j, int sub_pos, int mvx, int mvy, int method)
{
  int ii, jj;
  double pix = 0.0;
  int pos_x, pos_y;
  int img_width  = dpb.fs_ref[0]->frame->size_x;
  int img_height = dpb.fs_ref[0]->frame->size_y;

  if(method == STD_INTERPOLATION)
  {
    if(sub_pos == int_pos)
    {
      // Integer position
      pos_y = FindPositionInt(img_height, i, FILTER_OFFSET_INT, mvy);
      pos_x = FindPositionInt(img_width, j, FILTER_OFFSET_INT, mvx);
      pix = refY[pos_y][pos_x];
    }
    else
    {
      // Sub-pel position
      for(ii = 0; ii < FILTER_SIZE; ++ii)
      {
        for(jj = 0; jj < FILTER_SIZE; ++jj)
        {
          pos_y = FindPosition(img_height, i + ii, 0, mvy);
          pos_x = FindPosition(img_width,  j + jj, 0, mvx);
          pix += refY[pos_y][pos_x] * (input->UseAdaptiveFilter == FILTER_TYPE_EDAIF ? 
            STANDARD_2D_FILTER_orig[sub_pos][FILTER_SIZE * ii + jj]:STANDARD_2D_FILTER[sub_pos][FILTER_SIZE * ii + jj]);
        }
      }
    }
  }
  else if(method == AIF_INTERPOLATION)
  {
    if(sub_pos == int_pos)
    {
      // Integer position
      for(ii = 0; ii < FILTER_SIZE_INT; ++ii)
      {
        for(jj = 0; jj < FILTER_SIZE_INT; ++jj)
        {
          pos_y = FindPositionInt(img_height, i + ii, 0, mvy);
          pos_x = FindPositionInt(img_width, j + jj, 0, mvx);
          pix += refY[pos_y][pos_x] * FilterCoefInt[FILTER_SIZE_INT * ii + jj];
        }
      }
      pix += FilterCoefInt[SQR(FILTER_SIZE_INT)];
    }
    else
    {
      // Sub-pel position
      for(ii = 0; ii < FILTER_SIZE; ++ii)
      {
        for(jj = 0; jj < FILTER_SIZE; ++jj)
        {
          pos_y = FindPosition(img_height, i + ii, 0, mvy);
          pos_x = FindPosition(img_width, j + jj, 0, mvx);
          pix += refY[pos_y][pos_x] * FilterCoef[sub_pos][FILTER_SIZE * ii + jj];
        }
      }
      pix += FilterCoef[sub_pos][SQR(FILTER_SIZE)];
    }
  }
  else
  {
    assert(0);
  }
  return pix;
}

//
//  Returns the sub-pel position or -1 if integer
//
static int GetSubPos(int mvx, int mvy)
{
  int mvx_sub = (mvx >= 0)? mvx % 4: (4 - abs(mvx) % 4) % 4;
  int mvy_sub = (mvy >= 0)? mvy % 4: (4 - abs(mvy) % 4) % 4;
  return(mvx_sub + 4 * mvy_sub - 1);          // pos 0..14 in a 4x4 block
}

//
//  Return the cost in bits of the filter corresponding to D[pos]
//  Returned value takes into account whether the filter has already been sent
//
static int BitCost(int pos, int nBits[D_SIZE], int D[D_SIZE])
{
  if((D_SIZE == 6) || (D_SIZE == 9))
  {
    return nBits[pos];
  }
  else if(D_SIZE == 16)
  {
    switch(pos)
    {
    case  0:    // int_pos
    case  1:    // a_pos
    case  2:    // b_pos
    case  4:    // d_pos
    case  5:    // e_pos
    case  6:    // f_pos
    case  8:    // h_pos
    case  9:    // i_pos
    case 10:    // j_pos
      return nBits[pos];              // Primary filter, send cost
    case  3:    // c_pos
      return ((D[1])? 0: nBits[1]);   // If filter has not been sent then return cost
    case  7:    // g_pos
      return ((D[5])? 0: nBits[5]);
    case 11:    // k_pos
      return ((D[9])? 0: nBits[9]);
    case 12:    // l_pos
      return ((D[4])? 0: nBits[4]);
    case 13:    // m_pos
      return ((D[5] || D[7])? 0: nBits[5]);
    case 14:    // n_pos
      return ((D[6])? 0: nBits[6]);
    case 15:    // o_pos
      return ((D[5] || D[7] || D[13])? 0: nBits[5]);
    default:
      {
        assert(0);
        return -1;
      }
    }
  }
  else
  {
    assert(0);
    return -1;
  }
}

//
//  Decide filter usage by inspecting the diagonal of the cost matrix
//
static void Diagonal(double C[2][2][D_SIZE][D_SIZE], int AvailFilter[D_SIZE], int nBits[D_SIZE], int D[D_SIZE])
{
  int i;
  double adaptiveCost;
  double standardCost;
  double lambda; 
  int qp = input->UseRDO_Q ? img->masterQP:img->qp;

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

  for(i = 0; i < D_SIZE; ++i)
  {
    if(AvailFilter[i])
    {
      standardCost = C[0][0][i][i];
      adaptiveCost = C[1][1][i][i] + BitCost(i, nBits, D) * lambda;
      D[i] = (standardCost <= adaptiveCost)? 0: 1;
    }
    else
    {
      D[i] = 0;
    }
  }
}

//
//  Check whether a decision is incompatible with the filters available
//  If it is, converts the decision to a vector D[]
//
static int is_incompatible(int decision, int AvailFilter[D_SIZE], int D[D_SIZE])
{
  int i;
  for(i = 0; i < D_SIZE; ++i)
  {
    D[i] = decision & 0x1;
    if(D[i] && !AvailFilter[i])     // No corresponding filter
      return 1;
    else
      decision >>= 1;

⌨️ 快捷键说明

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