📄 adaptive_filter_decision.c
字号:
//
// 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 + -