Replace bilateral filter with domain transform RF
The main objective is to reduce computational complexity.
The domain transform filter has an effect of edge preserving smoothing
at a lower computational cost than the bilateral filter, and can be
readily paralelized.
A little drop in coding efficiency about 0.06% for lowres, 0.16% for
midres.
Change-Id: Id949406b7e5afe9b64588d130065c63a76e4f3f9
diff --git a/av1/common/alloccommon.c b/av1/common/alloccommon.c
index 9930da3..86051c8 100644
--- a/av1/common/alloccommon.c
+++ b/av1/common/alloccommon.c
@@ -90,8 +90,6 @@
void av1_free_restoration_buffers(AV1_COMMON *cm) {
aom_free(cm->rst_info.restoration_type);
cm->rst_info.restoration_type = NULL;
- aom_free(cm->rst_info.bilateral_info);
- cm->rst_info.bilateral_info = NULL;
aom_free(cm->rst_info.wiener_info);
cm->rst_info.wiener_info = NULL;
aom_free(cm->rst_info.sgrproj_info);
diff --git a/av1/common/entropymode.c b/av1/common/entropymode.c
index 9aeb408..28f67a4 100644
--- a/av1/common/entropymode.c
+++ b/av1/common/entropymode.c
@@ -1204,20 +1204,13 @@
#if CONFIG_LOOP_RESTORATION
const aom_tree_index av1_switchable_restore_tree[TREE_SIZE(
RESTORE_SWITCHABLE_TYPES)] = {
- // -RESTORE_NONE, 2, -RESTORE_SGRPROJ, 4, -RESTORE_BILATERAL, -RESTORE_WIENER,
- -RESTORE_NONE,
- 2,
- 4,
- 6,
- -RESTORE_SGRPROJ,
- -RESTORE_DOMAINTXFMRF,
- -RESTORE_BILATERAL,
- -RESTORE_WIENER,
+ -RESTORE_NONE, 2, -RESTORE_WIENER, 4, -RESTORE_SGRPROJ, -RESTORE_DOMAINTXFMRF,
};
-static const aom_prob default_switchable_restore_prob[RESTORE_SWITCHABLE_TYPES -
- 1] = { 32, 128, 128,
- 128 };
+static const aom_prob
+ default_switchable_restore_prob[RESTORE_SWITCHABLE_TYPES - 1] = {
+ 32, 128, 128,
+ };
#endif // CONFIG_LOOP_RESTORATION
#if CONFIG_PALETTE
@@ -2113,14 +2106,6 @@
// To force update of the sharpness
lf->last_sharpness_level = -1;
-#if CONFIG_LOOP_RESTORATION
- if (cm->rst_info.bilateral_info) {
- int s;
- for (i = 0; i < cm->rst_internal.ntiles; ++i)
- for (s = 0; s < BILATERAL_SUBTILES; ++s)
- cm->rst_info.bilateral_info[i].level[s] = -1;
- }
-#endif // CONFIG_LOOP_RESTORATION
av1_default_coef_probs(cm);
init_mode_probs(cm->fc);
diff --git a/av1/common/enums.h b/av1/common/enums.h
index 7d91bba..ebea307 100644
--- a/av1/common/enums.h
+++ b/av1/common/enums.h
@@ -489,11 +489,10 @@
#if CONFIG_LOOP_RESTORATION
typedef enum {
RESTORE_NONE = 0,
- RESTORE_SGRPROJ = 1,
- RESTORE_BILATERAL = 2,
- RESTORE_WIENER = 3,
- RESTORE_DOMAINTXFMRF = 4,
- RESTORE_SWITCHABLE = 5,
+ RESTORE_WIENER = 1,
+ RESTORE_SGRPROJ = 2,
+ RESTORE_DOMAINTXFMRF = 3,
+ RESTORE_SWITCHABLE = 4,
RESTORE_SWITCHABLE_TYPES = RESTORE_SWITCHABLE,
RESTORE_TYPES,
} RestorationType;
diff --git a/av1/common/restoration.c b/av1/common/restoration.c
index b8e6a93..201e60c 100644
--- a/av1/common/restoration.c
+++ b/av1/common/restoration.c
@@ -30,40 +30,6 @@
136, 138, 140, 142, 146, 150, 154, 158, 162, 166, 170, 174
};
-#define BILATERAL_PARAM_PRECISION 16
-#define BILATERAL_AMP_RANGE 256
-#define BILATERAL_AMP_RANGE_SYM (2 * BILATERAL_AMP_RANGE + 1)
-
-static uint8_t bilateral_filter_coeffs_r_kf[BILATERAL_LEVELS_KF]
- [BILATERAL_AMP_RANGE_SYM];
-static uint8_t bilateral_filter_coeffs_r[BILATERAL_LEVELS]
- [BILATERAL_AMP_RANGE_SYM];
-static uint8_t bilateral_filter_coeffs_s_kf[BILATERAL_LEVELS_KF]
- [RESTORATION_WIN][RESTORATION_WIN];
-static uint8_t bilateral_filter_coeffs_s[BILATERAL_LEVELS][RESTORATION_WIN]
- [RESTORATION_WIN];
-
-typedef struct bilateral_params {
- int sigma_x; // spatial variance x
- int sigma_y; // spatial variance y
- int sigma_r; // range variance
-} BilateralParamsType;
-
-static BilateralParamsType bilateral_level_to_params_arr[BILATERAL_LEVELS] = {
- // Values are rounded to 1/16 th precision
- { 8, 9, 30 }, { 9, 8, 30 }, { 9, 11, 32 }, { 11, 9, 32 },
- { 14, 14, 36 }, { 18, 18, 36 }, { 24, 24, 40 }, { 32, 32, 40 },
-};
-
-static BilateralParamsType
- bilateral_level_to_params_arr_kf[BILATERAL_LEVELS_KF] = {
- // Values are rounded to 1/16 th precision
- { 8, 8, 30 }, { 9, 9, 32 }, { 10, 10, 32 }, { 12, 12, 32 },
- { 14, 14, 32 }, { 18, 18, 36 }, { 24, 24, 40 }, { 30, 30, 44 },
- { 36, 36, 48 }, { 42, 42, 48 }, { 48, 48, 48 }, { 48, 48, 56 },
- { 56, 56, 48 }, { 56, 56, 56 }, { 56, 56, 64 }, { 64, 64, 48 },
- };
-
const sgr_params_type sgr_params[SGRPROJ_PARAMS] = {
// r1, eps1, r2, eps2
{ 2, 27, 1, 11 }, { 2, 31, 1, 12 }, { 2, 37, 1, 12 }, { 2, 44, 1, 12 },
@@ -80,12 +46,6 @@
int bit_depth);
#endif // CONFIG_AOM_HIGHBITDEPTH
-static INLINE BilateralParamsType av1_bilateral_level_to_params(int index,
- int kf) {
- return kf ? bilateral_level_to_params_arr_kf[index]
- : bilateral_level_to_params_arr[index];
-}
-
static void GenDomainTxfmRFVtable() {
int i, j;
const double sigma_s = sqrt(2.0);
@@ -105,79 +65,7 @@
}
}
-static void GenBilateralTables() {
- int i;
- for (i = 0; i < BILATERAL_LEVELS_KF; i++) {
- const BilateralParamsType param = av1_bilateral_level_to_params(i, 1);
- const int sigma_x = param.sigma_x;
- const int sigma_y = param.sigma_y;
- const int sigma_r = param.sigma_r;
- const double sigma_r_d = (double)sigma_r / BILATERAL_PARAM_PRECISION;
- const double sigma_x_d = (double)sigma_x / BILATERAL_PARAM_PRECISION;
- const double sigma_y_d = (double)sigma_y / BILATERAL_PARAM_PRECISION;
-
- uint8_t *fr = bilateral_filter_coeffs_r_kf[i] + BILATERAL_AMP_RANGE;
- int j, x, y;
- for (j = 0; j <= BILATERAL_AMP_RANGE; j++) {
- fr[j] = (uint8_t)(0.5 +
- RESTORATION_FILT_STEP *
- exp(-(j * j) / (2 * sigma_r_d * sigma_r_d)));
- fr[-j] = fr[j];
- }
- for (y = -RESTORATION_HALFWIN; y <= RESTORATION_HALFWIN; y++) {
- for (x = -RESTORATION_HALFWIN; x <= RESTORATION_HALFWIN; x++) {
- bilateral_filter_coeffs_s_kf[i][y + RESTORATION_HALFWIN]
- [x + RESTORATION_HALFWIN] = (uint8_t)(
- 0.5 +
- RESTORATION_FILT_STEP *
- exp(-(x * x) / (2 * sigma_x_d *
- sigma_x_d) -
- (y * y) / (2 * sigma_y_d *
- sigma_y_d)));
- }
- }
- }
- for (i = 0; i < BILATERAL_LEVELS; i++) {
- const BilateralParamsType param = av1_bilateral_level_to_params(i, 0);
- const int sigma_x = param.sigma_x;
- const int sigma_y = param.sigma_y;
- const int sigma_r = param.sigma_r;
- const double sigma_r_d = (double)sigma_r / BILATERAL_PARAM_PRECISION;
- const double sigma_x_d = (double)sigma_x / BILATERAL_PARAM_PRECISION;
- const double sigma_y_d = (double)sigma_y / BILATERAL_PARAM_PRECISION;
-
- uint8_t *fr = bilateral_filter_coeffs_r[i] + BILATERAL_AMP_RANGE;
- int j, x, y;
- for (j = 0; j <= BILATERAL_AMP_RANGE; j++) {
- fr[j] = (uint8_t)(0.5 +
- RESTORATION_FILT_STEP *
- exp(-(j * j) / (2 * sigma_r_d * sigma_r_d)));
- fr[-j] = fr[j];
- }
- for (y = -RESTORATION_HALFWIN; y <= RESTORATION_HALFWIN; y++) {
- for (x = -RESTORATION_HALFWIN; x <= RESTORATION_HALFWIN; x++) {
- bilateral_filter_coeffs_s[i][y + RESTORATION_HALFWIN]
- [x + RESTORATION_HALFWIN] = (uint8_t)(
- 0.5 +
- RESTORATION_FILT_STEP *
- exp(-(x * x) /
- (2 * sigma_x_d * sigma_x_d) -
- (y * y) /
- (2 * sigma_y_d * sigma_y_d)));
- }
- }
- }
-}
-
-void av1_loop_restoration_precal() {
- GenBilateralTables();
- GenDomainTxfmRFVtable();
-}
-
-int av1_bilateral_level_bits(const AV1_COMMON *const cm) {
- return cm->frame_type == KEY_FRAME ? BILATERAL_LEVEL_BITS_KF
- : BILATERAL_LEVEL_BITS;
-}
+void av1_loop_restoration_precal() { GenDomainTxfmRFVtable(); }
void av1_loop_restoration_init(RestorationInternal *rst, RestorationInfo *rsi,
int kf, int width, int height) {
@@ -228,75 +116,6 @@
}
}
-static void loop_bilateral_filter_tile(uint8_t *data, int tile_idx, int width,
- int height, int stride,
- RestorationInternal *rst,
- uint8_t *tmpdata, int tmpstride) {
- int i, j, subtile_idx;
- int h_start, h_end, v_start, v_end;
- const int tile_width = rst->tile_width >> rst->subsampling_x;
- const int tile_height = rst->tile_height >> rst->subsampling_y;
-
- for (subtile_idx = 0; subtile_idx < BILATERAL_SUBTILES; ++subtile_idx) {
- uint8_t *data_p, *tmpdata_p;
- const int level = rst->rsi->bilateral_info[tile_idx].level[subtile_idx];
- uint8_t(*wx_lut)[RESTORATION_WIN];
- uint8_t *wr_lut_;
-
- if (level < 0) continue;
- wr_lut_ = (rst->keyframe ? bilateral_filter_coeffs_r_kf[level]
- : bilateral_filter_coeffs_r[level]) +
- BILATERAL_AMP_RANGE;
- wx_lut = rst->keyframe ? bilateral_filter_coeffs_s_kf[level]
- : bilateral_filter_coeffs_s[level];
-
- av1_get_rest_tile_limits(tile_idx, subtile_idx, BILATERAL_SUBTILE_BITS,
- rst->nhtiles, rst->nvtiles, tile_width,
- tile_height, width, height, 1, 1, &h_start, &h_end,
- &v_start, &v_end);
-
- data_p = data + h_start + v_start * stride;
- tmpdata_p = tmpdata + h_start + v_start * tmpstride;
-
- for (i = 0; i < (v_end - v_start); ++i) {
- for (j = 0; j < (h_end - h_start); ++j) {
- int x, y, wt;
- int64_t flsum = 0, wtsum = 0;
- uint8_t *data_p2 = data_p + j - RESTORATION_HALFWIN * stride;
- for (y = -RESTORATION_HALFWIN; y <= RESTORATION_HALFWIN; ++y) {
- for (x = -RESTORATION_HALFWIN; x <= RESTORATION_HALFWIN; ++x) {
- wt = (int)wx_lut[y + RESTORATION_HALFWIN][x + RESTORATION_HALFWIN] *
- (int)wr_lut_[data_p2[x] - data_p[j]];
- wtsum += (int64_t)wt;
- flsum += (int64_t)wt * data_p2[x];
- }
- data_p2 += stride;
- }
- if (wtsum > 0)
- tmpdata_p[j] = clip_pixel((int)((flsum + wtsum / 2) / wtsum));
- else
- tmpdata_p[j] = data_p[j];
- }
- tmpdata_p += tmpstride;
- data_p += stride;
- }
- for (i = v_start; i < v_end; ++i) {
- memcpy(data + i * stride + h_start, tmpdata + i * tmpstride + h_start,
- (h_end - h_start) * sizeof(*data));
- }
- }
-}
-
-static void loop_bilateral_filter(uint8_t *data, int width, int height,
- int stride, RestorationInternal *rst,
- uint8_t *tmpdata, int tmpstride) {
- int tile_idx;
- for (tile_idx = 0; tile_idx < rst->ntiles; ++tile_idx) {
- loop_bilateral_filter_tile(data, tile_idx, width, height, stride, rst,
- tmpdata, tmpstride);
- }
-}
-
uint8_t hor_sym_filter(uint8_t *d, int *hfilter) {
int32_t s =
(1 << (RESTORATION_FILT_BITS - 1)) + d[0] * hfilter[RESTORATION_HALFWIN];
@@ -853,10 +672,7 @@
tmpdata_p += tmpstride;
}
for (tile_idx = 0; tile_idx < rst->ntiles; ++tile_idx) {
- if (rst->rsi->restoration_type[tile_idx] == RESTORE_BILATERAL) {
- loop_bilateral_filter_tile(data, tile_idx, width, height, stride, rst,
- tmpdata, tmpstride);
- } else if (rst->rsi->restoration_type[tile_idx] == RESTORE_WIENER) {
+ if (rst->rsi->restoration_type[tile_idx] == RESTORE_WIENER) {
loop_wiener_filter_tile(data, tile_idx, width, height, stride, rst,
tmpdata, tmpstride);
} else if (rst->rsi->restoration_type[tile_idx] == RESTORE_SGRPROJ) {
@@ -871,81 +687,6 @@
}
#if CONFIG_AOM_HIGHBITDEPTH
-static void loop_bilateral_filter_tile_highbd(uint16_t *data, int tile_idx,
- int width, int height, int stride,
- RestorationInternal *rst,
- uint16_t *tmpdata, int tmpstride,
- int bit_depth) {
- const int tile_width = rst->tile_width >> rst->subsampling_x;
- const int tile_height = rst->tile_height >> rst->subsampling_y;
- int i, j, subtile_idx;
- int h_start, h_end, v_start, v_end;
- const int shift = bit_depth - 8;
-
- for (subtile_idx = 0; subtile_idx < BILATERAL_SUBTILES; ++subtile_idx) {
- uint16_t *data_p, *tmpdata_p;
- const int level = rst->rsi->bilateral_info[tile_idx].level[subtile_idx];
- uint8_t(*wx_lut)[RESTORATION_WIN];
- uint8_t *wr_lut_;
-
- if (level < 0) continue;
- wr_lut_ = (rst->keyframe ? bilateral_filter_coeffs_r_kf[level]
- : bilateral_filter_coeffs_r[level]) +
- BILATERAL_AMP_RANGE;
- wx_lut = rst->keyframe ? bilateral_filter_coeffs_s_kf[level]
- : bilateral_filter_coeffs_s[level];
- av1_get_rest_tile_limits(tile_idx, subtile_idx, BILATERAL_SUBTILE_BITS,
- rst->nhtiles, rst->nvtiles, tile_width,
- tile_height, width, height, 1, 1, &h_start, &h_end,
- &v_start, &v_end);
-
- data_p = data + h_start + v_start * stride;
- tmpdata_p = tmpdata + h_start + v_start * tmpstride;
-
- for (i = 0; i < (v_end - v_start); ++i) {
- for (j = 0; j < (h_end - h_start); ++j) {
- int x, y, wt;
- int64_t flsum = 0, wtsum = 0;
- uint16_t *data_p2 = data_p + j - RESTORATION_HALFWIN * stride;
- for (y = -RESTORATION_HALFWIN; y <= RESTORATION_HALFWIN; ++y) {
- for (x = -RESTORATION_HALFWIN; x <= RESTORATION_HALFWIN; ++x) {
- wt = (int)wx_lut[y + RESTORATION_HALFWIN][x + RESTORATION_HALFWIN] *
- (int)wr_lut_[(data_p2[x] >> shift) - (data_p[j] >> shift)];
- wtsum += (int64_t)wt;
- flsum += (int64_t)wt * data_p2[x];
- }
- data_p2 += stride;
- }
- if (wtsum > 0)
- tmpdata_p[j] =
- clip_pixel_highbd((int)((flsum + wtsum / 2) / wtsum), bit_depth);
- else
- tmpdata_p[j] = data_p[j];
- }
- tmpdata_p += tmpstride;
- data_p += stride;
- }
- for (i = v_start; i < v_end; ++i) {
- memcpy(data + i * stride + h_start, tmpdata + i * tmpstride + h_start,
- (h_end - h_start) * sizeof(*data));
- }
- }
-}
-
-static void loop_bilateral_filter_highbd(uint8_t *data8, int width, int height,
- int stride, RestorationInternal *rst,
- uint8_t *tmpdata8, int tmpstride,
- int bit_depth) {
- int tile_idx;
- uint16_t *data = CONVERT_TO_SHORTPTR(data8);
- uint16_t *tmpdata = CONVERT_TO_SHORTPTR(tmpdata8);
-
- for (tile_idx = 0; tile_idx < rst->ntiles; ++tile_idx) {
- loop_bilateral_filter_tile_highbd(data, tile_idx, width, height, stride,
- rst, tmpdata, tmpstride, bit_depth);
- }
-}
-
uint16_t hor_sym_filter_highbd(uint16_t *d, int *hfilter, int bd) {
int32_t s =
(1 << (RESTORATION_FILT_BITS - 1)) + d[0] * hfilter[RESTORATION_HALFWIN];
@@ -1223,10 +964,7 @@
tmpdata_p += tmpstride;
}
for (tile_idx = 0; tile_idx < rst->ntiles; ++tile_idx) {
- if (rst->rsi->restoration_type[tile_idx] == RESTORE_BILATERAL) {
- loop_bilateral_filter_tile_highbd(data, tile_idx, width, height, stride,
- rst, tmpdata, tmpstride, bit_depth);
- } else if (rst->rsi->restoration_type[tile_idx] == RESTORE_WIENER) {
+ if (rst->rsi->restoration_type[tile_idx] == RESTORE_WIENER) {
loop_wiener_filter_tile_highbd(data, tile_idx, width, height, stride, rst,
tmpdata, tmpstride, bit_depth);
} else if (rst->rsi->restoration_type[tile_idx] == RESTORE_SGRPROJ) {
@@ -1251,20 +989,14 @@
const int uvstart = ystart >> cm->subsampling_y;
int yend = end_mi_row << MI_SIZE_LOG2;
int uvend = yend >> cm->subsampling_y;
- restore_func_type restore_funcs[RESTORE_TYPES] = { NULL,
+ restore_func_type restore_funcs[RESTORE_TYPES] = { NULL, loop_wiener_filter,
loop_sgrproj_filter,
- loop_bilateral_filter,
- loop_wiener_filter,
loop_domaintxfmrf_filter,
loop_switchable_filter };
#if CONFIG_AOM_HIGHBITDEPTH
restore_func_highbd_type restore_funcs_highbd[RESTORE_TYPES] = {
- NULL,
- loop_sgrproj_filter_highbd,
- loop_bilateral_filter_highbd,
- loop_wiener_filter_highbd,
- loop_domaintxfmrf_filter_highbd,
- loop_switchable_filter_highbd
+ NULL, loop_wiener_filter_highbd, loop_sgrproj_filter_highbd,
+ loop_domaintxfmrf_filter_highbd, loop_switchable_filter_highbd
};
#endif // CONFIG_AOM_HIGHBITDEPTH
restore_func_type restore_func =
diff --git a/av1/common/restoration.h b/av1/common/restoration.h
index 167120b..63e78a1 100644
--- a/av1/common/restoration.h
+++ b/av1/common/restoration.h
@@ -60,14 +60,6 @@
#define SGRPROJ_BITS (SGRPROJ_PRJ_BITS * 2 + SGRPROJ_PARAMS_BITS)
-#define BILATERAL_LEVEL_BITS_KF 4
-#define BILATERAL_LEVELS_KF (1 << BILATERAL_LEVEL_BITS_KF)
-#define BILATERAL_LEVEL_BITS 3
-#define BILATERAL_LEVELS (1 << BILATERAL_LEVEL_BITS)
-
-#define BILATERAL_SUBTILE_BITS 1
-#define BILATERAL_SUBTILES (1 << (2 * BILATERAL_SUBTILE_BITS))
-
#define RESTORATION_HALFWIN 3
#define RESTORATION_HALFWIN1 (RESTORATION_HALFWIN + 1)
#define RESTORATION_WIN (2 * RESTORATION_HALFWIN + 1)
@@ -94,8 +86,6 @@
#define WIENER_FILT_TAP2_MAXV \
(WIENER_FILT_TAP2_MINV - 1 + (1 << WIENER_FILT_TAP2_BITS))
-typedef struct { int level[BILATERAL_SUBTILES]; } BilateralInfo;
-
typedef struct {
int level;
int vfilter[RESTORATION_WIN], hfilter[RESTORATION_WIN];
@@ -122,8 +112,6 @@
typedef struct {
RestorationType frame_restoration_type;
RestorationType *restoration_type;
- // Bilateral filter
- BilateralInfo *bilateral_info;
// Wiener filter
WienerInfo *wiener_info;
// Selfguided proj filter
@@ -210,7 +198,6 @@
int stride, int param, int bit_depth);
#endif // CONFIG_AOM_HIGHBITDEPTH
void decode_xq(int *xqd, int *xq);
-int av1_bilateral_level_bits(const struct AV1Common *const cm);
void av1_loop_restoration_init(RestorationInternal *rst, RestorationInfo *rsi,
int kf, int width, int height);
void av1_loop_restoration_frame(YV12_BUFFER_CONFIG *frame, struct AV1Common *cm,
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index e35bda6..f6111f3 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -2268,11 +2268,9 @@
if (aom_rb_read_bit(rb)) {
if (aom_rb_read_bit(rb))
rsi->frame_restoration_type =
- (aom_rb_read_bit(rb) ? RESTORE_WIENER : RESTORE_BILATERAL);
- else
- rsi->frame_restoration_type =
(aom_rb_read_bit(rb) ? RESTORE_DOMAINTXFMRF : RESTORE_SGRPROJ);
- // rsi->frame_restoration_type = RESTORE_SGRPROJ;
+ else
+ rsi->frame_restoration_type = RESTORE_WIENER;
} else {
rsi->frame_restoration_type =
aom_rb_read_bit(rb) ? RESTORE_SWITCHABLE : RESTORE_NONE;
@@ -2314,20 +2312,6 @@
aom_read_literal(rb, DOMAINTXFMRF_PARAMS_BITS, ACCT_STR);
}
-static void read_bilateral_filter(const AV1_COMMON *cm,
- BilateralInfo *bilateral_info,
- aom_reader *rb) {
- int s;
- for (s = 0; s < BILATERAL_SUBTILES; ++s) {
- if (aom_read(rb, RESTORE_NONE_BILATERAL_PROB, ACCT_STR)) {
- bilateral_info->level[s] =
- aom_read_literal(rb, av1_bilateral_level_bits(cm), ACCT_STR);
- } else {
- bilateral_info->level[s] = -1;
- }
- }
-}
-
static void decode_restoration(AV1_COMMON *cm, aom_reader *rb) {
int i;
RestorationInfo *rsi = &cm->rst_info;
@@ -2337,9 +2321,6 @@
rsi->restoration_type = (RestorationType *)aom_realloc(
rsi->restoration_type, sizeof(*rsi->restoration_type) * ntiles);
if (rsi->frame_restoration_type == RESTORE_SWITCHABLE) {
- rsi->bilateral_info = (BilateralInfo *)aom_realloc(
- rsi->bilateral_info, sizeof(*rsi->bilateral_info) * ntiles);
- assert(rsi->bilateral_info != NULL);
rsi->wiener_info = (WienerInfo *)aom_realloc(
rsi->wiener_info, sizeof(*rsi->wiener_info) * ntiles);
assert(rsi->wiener_info != NULL);
@@ -2356,13 +2337,6 @@
if (rsi->restoration_type[i] == RESTORE_WIENER) {
rsi->wiener_info[i].level = 1;
read_wiener_filter(&rsi->wiener_info[i], rb);
- } else if (rsi->restoration_type[i] == RESTORE_BILATERAL) {
-#if BILATERAL_SUBTILES == 0
- rsi->bilateral_info[i].level[0] =
- aom_read_literal(rb, av1_bilateral_level_bits(cm), ACCT_STR);
-#else
- read_bilateral_filter(cm, &rsi->bilateral_info[i], rb);
-#endif
} else if (rsi->restoration_type[i] == RESTORE_SGRPROJ) {
rsi->sgrproj_info[i].level = 1;
read_sgrproj_filter(&rsi->sgrproj_info[i], rb);
@@ -2385,14 +2359,6 @@
rsi->restoration_type[i] = RESTORE_NONE;
}
}
- } else if (rsi->frame_restoration_type == RESTORE_BILATERAL) {
- rsi->bilateral_info = (BilateralInfo *)aom_realloc(
- rsi->bilateral_info, sizeof(*rsi->bilateral_info) * ntiles);
- assert(rsi->bilateral_info != NULL);
- for (i = 0; i < ntiles; ++i) {
- rsi->restoration_type[i] = RESTORE_BILATERAL;
- read_bilateral_filter(cm, &rsi->bilateral_info[i], rb);
- }
} else if (rsi->frame_restoration_type == RESTORE_SGRPROJ) {
rsi->sgrproj_info = (SgrprojInfo *)aom_realloc(
rsi->sgrproj_info, sizeof(*rsi->sgrproj_info) * ntiles);
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index 72ebc8a..81d8b39 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -2991,34 +2991,22 @@
aom_wb_write_bit(wb, 0);
aom_wb_write_bit(wb, 0);
break;
- case RESTORE_SWITCHABLE:
- aom_wb_write_bit(wb, 0);
+ case RESTORE_WIENER:
aom_wb_write_bit(wb, 1);
+ aom_wb_write_bit(wb, 0);
break;
- /*
- case RESTORE_SGRPROJ:
- aom_wb_write_bit(wb, 1);
- aom_wb_write_bit(wb, 0);
- break;
- */
case RESTORE_SGRPROJ:
aom_wb_write_bit(wb, 1);
- aom_wb_write_bit(wb, 0);
+ aom_wb_write_bit(wb, 1);
aom_wb_write_bit(wb, 0);
break;
case RESTORE_DOMAINTXFMRF:
aom_wb_write_bit(wb, 1);
- aom_wb_write_bit(wb, 0);
+ aom_wb_write_bit(wb, 1);
aom_wb_write_bit(wb, 1);
break;
- case RESTORE_BILATERAL:
- aom_wb_write_bit(wb, 1);
- aom_wb_write_bit(wb, 1);
+ case RESTORE_SWITCHABLE:
aom_wb_write_bit(wb, 0);
- break;
- case RESTORE_WIENER:
- aom_wb_write_bit(wb, 1);
- aom_wb_write_bit(wb, 1);
aom_wb_write_bit(wb, 1);
break;
default: assert(0);
@@ -3053,19 +3041,6 @@
aom_write_literal(wb, domaintxfmrf_info->sigma_r, DOMAINTXFMRF_PARAMS_BITS);
}
-static void write_bilateral_filter(const AV1_COMMON *cm,
- BilateralInfo *bilateral_info,
- aom_writer *wb) {
- int s;
- for (s = 0; s < BILATERAL_SUBTILES; ++s) {
- aom_write(wb, bilateral_info->level[s] >= 0, RESTORE_NONE_BILATERAL_PROB);
- if (bilateral_info->level[s] >= 0) {
- aom_write_literal(wb, bilateral_info->level[s],
- av1_bilateral_level_bits(cm));
- }
- }
-}
-
static void encode_restoration(AV1_COMMON *cm, aom_writer *wb) {
int i;
RestorationInfo *rsi = &cm->rst_info;
@@ -3076,14 +3051,7 @@
av1_write_token(
wb, av1_switchable_restore_tree, cm->fc->switchable_restore_prob,
&switchable_restore_encodings[rsi->restoration_type[i]]);
- if (rsi->restoration_type[i] == RESTORE_BILATERAL) {
-#if BILATERAL_SUBTILES == 0
- aom_write_literal(wb, rsi->bilateral_info[i].level[0],
- av1_bilateral_level_bits(cm));
-#else
- write_bilateral_filter(cm, &rsi->bilateral_info[i], wb);
-#endif
- } else if (rsi->restoration_type[i] == RESTORE_WIENER) {
+ if (rsi->restoration_type[i] == RESTORE_WIENER) {
write_wiener_filter(&rsi->wiener_info[i], wb);
} else if (rsi->restoration_type[i] == RESTORE_SGRPROJ) {
write_sgrproj_filter(&rsi->sgrproj_info[i], wb);
@@ -3091,10 +3059,6 @@
write_domaintxfmrf_filter(&rsi->domaintxfmrf_info[i], wb);
}
}
- } else if (rsi->frame_restoration_type == RESTORE_BILATERAL) {
- for (i = 0; i < cm->rst_internal.ntiles; ++i) {
- write_bilateral_filter(cm, &rsi->bilateral_info[i], wb);
- }
} else if (rsi->frame_restoration_type == RESTORE_WIENER) {
for (i = 0; i < cm->rst_internal.ntiles; ++i) {
aom_write(wb, rsi->wiener_info[i].level != 0, RESTORE_NONE_WIENER_PROB);
diff --git a/av1/encoder/pickrst.c b/av1/encoder/pickrst.c
index 07e738d..64687a2 100644
--- a/av1/encoder/pickrst.c
+++ b/av1/encoder/pickrst.c
@@ -34,8 +34,7 @@
int partial_frame, RestorationInfo *info,
double *best_tile_cost);
-// const int frame_level_restore_bits[RESTORE_TYPES] = { 2, 2, 3, 3, 2 };
-const int frame_level_restore_bits[RESTORE_TYPES] = { 2, 3, 3, 3, 3, 2 };
+const int frame_level_restore_bits[RESTORE_TYPES] = { 2, 2, 3, 3, 2 };
static int64_t sse_restoration_tile(const YV12_BUFFER_CONFIG *src,
AV1_COMMON *const cm, int h_start,
@@ -476,7 +475,8 @@
RestorationInfo *info,
double *best_tile_cost) {
DomaintxfmrfInfo *domaintxfmrf_info = info->domaintxfmrf_info;
- double err, cost_norestore, cost_domaintxfmrf;
+ double cost_norestore, cost_domaintxfmrf;
+ int64_t err;
int bits;
MACROBLOCK *x = &cpi->td.mb;
AV1_COMMON *const cm = &cpi->common;
@@ -561,116 +561,6 @@
return cost_domaintxfmrf;
}
-static double search_bilateral(const YV12_BUFFER_CONFIG *src, AV1_COMP *cpi,
- int filter_level, int partial_frame,
- RestorationInfo *info, double *best_tile_cost) {
- BilateralInfo *bilateral_info = info->bilateral_info;
- AV1_COMMON *const cm = &cpi->common;
- int i, tile_idx, subtile_idx;
- int64_t err;
- int bits;
- double cost, best_cost, cost_bilateral, cost_norestore_subtile;
- const int bilateral_level_bits = av1_bilateral_level_bits(&cpi->common);
- const int bilateral_levels = 1 << bilateral_level_bits;
- MACROBLOCK *x = &cpi->td.mb;
- RestorationInfo rsi;
- int tile_width, tile_height, nhtiles, nvtiles;
- int h_start, h_end, v_start, v_end;
- const int ntiles = av1_get_rest_ntiles(cm->width, cm->height, &tile_width,
- &tile_height, &nhtiles, &nvtiles);
-
- // Make a copy of the unfiltered / processed recon buffer
- aom_yv12_copy_y(cm->frame_to_show, &cpi->last_frame_uf);
- av1_loop_filter_frame(cm->frame_to_show, cm, &cpi->td.mb.e_mbd, filter_level,
- 1, partial_frame);
- aom_yv12_copy_y(cm->frame_to_show, &cpi->last_frame_db);
-
- rsi.frame_restoration_type = RESTORE_BILATERAL;
- rsi.bilateral_info =
- (BilateralInfo *)aom_malloc(sizeof(*rsi.bilateral_info) * ntiles);
- assert(rsi.bilateral_info != NULL);
-
- for (tile_idx = 0; tile_idx < ntiles; ++tile_idx)
- for (subtile_idx = 0; subtile_idx < BILATERAL_SUBTILES; ++subtile_idx)
- bilateral_info[tile_idx].level[subtile_idx] =
- rsi.bilateral_info[tile_idx].level[subtile_idx] = -1;
-
- // Find best filter for each tile
- for (tile_idx = 0; tile_idx < ntiles; ++tile_idx) {
- for (subtile_idx = 0; subtile_idx < BILATERAL_SUBTILES; ++subtile_idx) {
- av1_get_rest_tile_limits(tile_idx, subtile_idx, BILATERAL_SUBTILE_BITS,
- nhtiles, nvtiles, tile_width, tile_height,
- cm->width, cm->height, 0, 0, &h_start, &h_end,
- &v_start, &v_end);
- err = sse_restoration_tile(src, cm, h_start, h_end - h_start, v_start,
- v_end - v_start);
-#if BILATERAL_SUBTILES
- // #bits when a subtile is not restored
- bits = av1_cost_bit(RESTORE_NONE_BILATERAL_PROB, 0);
-#else
- bits = 0;
-#endif
- cost_norestore_subtile =
- RDCOST_DBL(x->rdmult, x->rddiv, (bits >> 4), err);
- best_cost = cost_norestore_subtile;
-
- for (i = 0; i < bilateral_levels; ++i) {
- rsi.bilateral_info[tile_idx].level[subtile_idx] = i;
- err = try_restoration_tile(src, cpi, &rsi, partial_frame, tile_idx,
- subtile_idx, BILATERAL_SUBTILE_BITS);
- bits = bilateral_level_bits << AV1_PROB_COST_SHIFT;
- bits += av1_cost_bit(RESTORE_NONE_BILATERAL_PROB, 1);
- cost = RDCOST_DBL(x->rdmult, x->rddiv, (bits >> 4), err);
- if (cost < best_cost) {
- bilateral_info[tile_idx].level[subtile_idx] = i;
- best_cost = cost;
- }
- rsi.bilateral_info[tile_idx].level[subtile_idx] = -1;
- }
- }
- bits = 0;
- for (subtile_idx = 0; subtile_idx < BILATERAL_SUBTILES; ++subtile_idx) {
- rsi.bilateral_info[tile_idx].level[subtile_idx] =
- bilateral_info[tile_idx].level[subtile_idx];
- if (rsi.bilateral_info[tile_idx].level[subtile_idx] >= 0)
- bits += bilateral_level_bits << AV1_PROB_COST_SHIFT;
-#if BILATERAL_SUBTILES
- bits +=
- av1_cost_bit(RESTORE_NONE_BILATERAL_PROB,
- rsi.bilateral_info[tile_idx].level[subtile_idx] >= 0);
-#endif
- }
- err = try_restoration_tile(src, cpi, &rsi, partial_frame, tile_idx, 0, 0);
- best_tile_cost[tile_idx] = RDCOST_DBL(
- x->rdmult, x->rddiv,
- (bits + cpi->switchable_restore_cost[RESTORE_BILATERAL]) >> 4, err);
- }
- // Find cost for combined configuration
- bits = frame_level_restore_bits[rsi.frame_restoration_type]
- << AV1_PROB_COST_SHIFT;
- for (tile_idx = 0; tile_idx < ntiles; ++tile_idx) {
- for (subtile_idx = 0; subtile_idx < BILATERAL_SUBTILES; ++subtile_idx) {
- rsi.bilateral_info[tile_idx].level[subtile_idx] =
- bilateral_info[tile_idx].level[subtile_idx];
- if (rsi.bilateral_info[tile_idx].level[subtile_idx] >= 0) {
- bits += bilateral_level_bits << AV1_PROB_COST_SHIFT;
- }
-#if BILATERAL_SUBTILES
- bits +=
- av1_cost_bit(RESTORE_NONE_BILATERAL_PROB,
- rsi.bilateral_info[tile_idx].level[subtile_idx] >= 0);
-#endif
- }
- }
- err = try_restoration_frame(src, cpi, &rsi, partial_frame);
- cost_bilateral = RDCOST_DBL(x->rdmult, x->rddiv, (bits >> 4), err);
-
- aom_free(rsi.bilateral_info);
-
- aom_yv12_copy_y(&cpi->last_frame_uf, cm->frame_to_show);
- return cost_bilateral;
-}
-
static double find_average(uint8_t *src, int h_start, int h_end, int v_start,
int v_end, int stride) {
uint64_t sum = 0;
@@ -1173,8 +1063,7 @@
void av1_pick_filter_restoration(const YV12_BUFFER_CONFIG *src, AV1_COMP *cpi,
LPF_PICK_METHOD method) {
static search_restore_type search_restore_fun[RESTORE_SWITCHABLE_TYPES] = {
- search_norestore, search_sgrproj, search_bilateral,
- search_wiener, search_domaintxfmrf,
+ search_norestore, search_wiener, search_sgrproj, search_domaintxfmrf,
};
AV1_COMMON *const cm = &cpi->common;
struct loopfilter *const lf = &cm->lf;
@@ -1188,10 +1077,6 @@
cm->rst_info.restoration_type = (RestorationType *)aom_realloc(
cm->rst_info.restoration_type,
sizeof(*cm->rst_info.restoration_type) * ntiles);
- cm->rst_info.bilateral_info = (BilateralInfo *)aom_realloc(
- cm->rst_info.bilateral_info,
- sizeof(*cm->rst_info.bilateral_info) * ntiles);
- assert(cm->rst_info.bilateral_info != NULL);
cm->rst_info.wiener_info = (WienerInfo *)aom_realloc(
cm->rst_info.wiener_info, sizeof(*cm->rst_info.wiener_info) * ntiles);
assert(cm->rst_info.wiener_info != NULL);
@@ -1264,10 +1149,10 @@
}
cm->rst_info.frame_restoration_type = best_restore;
/*
- printf("Frame %d/%d frame_restore_type %d : %f %f %f %f %f %f\n",
+ printf("Frame %d/%d frame_restore_type %d : %f %f %f %f %f\n",
cm->current_video_frame, cm->show_frame,
cm->rst_info.frame_restoration_type, cost_restore[0], cost_restore[1],
- cost_restore[2], cost_restore[3], cost_restore[4], cost_restore[5]);
+ cost_restore[2], cost_restore[3], cost_restore[4]);
*/
for (r = 0; r < RESTORE_SWITCHABLE_TYPES; r++) aom_free(tile_cost[r]);
}