Make lpf_sb work with loopfilter_level
Make lpf_sb compatible with loopfilter_level, when USE_GUESS_LEVEL = 1.
Filter levels will be selected based on q index and applied for
filtering on Y, U, V planes separately.
Current model only allows to guess one filter level.
Now Y_vert = Y_horz = U = V. In the future, we need to retrain the
model and get filter levels for Y_vert, Y_horz, U and V separately.
When USE_GUESS_LEVEL = 0, lpf_sb can't work with loopfilter_level yet.
Change-Id: Icd774a147c07a4035cf8204a8754b2a99668bbfd
diff --git a/av1/common/av1_loopfilter.c b/av1/common/av1_loopfilter.c
index d563aaf..43941cf 100644
--- a/av1/common/av1_loopfilter.c
+++ b/av1/common/av1_loopfilter.c
@@ -350,8 +350,13 @@
#endif
const MB_MODE_INFO *mbmi) {
#if CONFIG_LPF_SB
+#if CONFIG_LOOPFILTER_LEVEL
+ const int lvl_idx = plane == 0 ? dir_idx : plane + 1;
+ return cm->mi[mi_row * cm->mi_stride + mi_col].mbmi.filt_lvl[lvl_idx];
+#else
return cm->mi[mi_row * cm->mi_stride + mi_col].mbmi.filt_lvl;
#endif
+#endif
const int segment_id = mbmi->segment_id;
if (cm->delta_lf_present_flag) {
@@ -429,6 +434,9 @@
#if CONFIG_LPF_SB
void av1_loop_filter_sb_level_init(AV1_COMMON *cm, int mi_row, int mi_col,
+#if CONFIG_LOOPFILTER_LEVEL
+ int plane, int dir,
+#endif
int lvl) {
const int mi_row_start = AOMMAX(0, mi_row - FILT_BOUNDARY_MI_OFFSET);
const int mi_col_start = AOMMAX(0, mi_col - FILT_BOUNDARY_MI_OFFSET);
@@ -440,9 +448,14 @@
int row, col;
for (row = mi_row_start; row < mi_row_end; ++row) {
for (col = mi_col_start; col < mi_col_end; ++col) {
- // Note: can't use cm->mi_grid_visible. Because for each partition,
- // all visible pointers will point to the first of the partition.
+// Note: can't use cm->mi_grid_visible. Because for each partition,
+// all visible pointers will point to the first of the partition.
+#if CONFIG_LOOPFILTER_LEVEL
+ const int lvl_idx = plane == 0 ? dir : plane + 1;
+ cm->mi[row * cm->mi_stride + col].mbmi.filt_lvl[lvl_idx] = lvl;
+#else
cm->mi[row * cm->mi_stride + col].mbmi.filt_lvl = lvl;
+#endif // CONFIG_LOOPFILTER_LEVEL
}
}
}
@@ -939,7 +952,11 @@
txsize_vert_map[uv_txsize_lookup[block_size][mbmi->tx_size][1][1]];
#if CONFIG_EXT_DELTA_Q
#if CONFIG_LOOPFILTER_LEVEL
+#if CONFIG_LPF_SB
+ const int filter_level = get_filter_level(cm, lfi_n, 0, 0, 0, 0, mbmi);
+#else
const int filter_level = get_filter_level(cm, lfi_n, 0, 0, mbmi);
+#endif
#else
#if CONFIG_LPF_SB
const int filter_level = get_filter_level(cm, lfi_n, 0, 0, mbmi);
@@ -1033,7 +1050,11 @@
const BLOCK_SIZE block_size = mbmi->sb_type;
#if CONFIG_EXT_DELTA_Q
#if CONFIG_LOOPFILTER_LEVEL
+#if CONFIG_LPF_SB
+ const int filter_level = get_filter_level(cm, lfi_n, 0, 0, 0, 0, mbmi);
+#else
const int filter_level = get_filter_level(cm, lfi_n, 0, 0, mbmi);
+#endif
#else
#if CONFIG_LPF_SB
const int filter_level = get_filter_level(cm, lfi_n, 0, 0, mbmi);
@@ -1507,8 +1528,13 @@
// Filter level can vary per MI
#if CONFIG_EXT_DELTA_Q
#if CONFIG_LOOPFILTER_LEVEL
+#if CONFIG_LPF_SB
+ if (!(lfl_r[c_step] = get_filter_level(cm, &cm->lf_info, 0, 0, 0, 0, mbmi)))
+ continue;
+#else
if (!(lfl_r[c_step] = get_filter_level(cm, &cm->lf_info, 0, 0, mbmi)))
continue;
+#endif
#else
#if CONFIG_LPF_SB
if (!(lfl_r[c_step] =
@@ -2169,8 +2195,13 @@
#if CONFIG_EXT_DELTA_Q
#if CONFIG_LOOPFILTER_LEVEL
+#if CONFIG_LPF_SB
+ const uint32_t curr_level = get_filter_level(cm, &cm->lf_info, edge_dir,
+ plane, mi_row, mi_col, mbmi);
+#else
const uint32_t curr_level =
get_filter_level(cm, &cm->lf_info, edge_dir, plane, mbmi);
+#endif
#else
#if CONFIG_LPF_SB
const uint32_t curr_level =
@@ -2211,8 +2242,14 @@
#if CONFIG_EXT_DELTA_Q
#if CONFIG_LOOPFILTER_LEVEL
+#if CONFIG_LPF_SB
+ const uint32_t pv_lvl =
+ get_filter_level(cm, &cm->lf_info, edge_dir, plane, mi_row,
+ mi_col, &mi_prev->mbmi);
+#else
const uint32_t pv_lvl = get_filter_level(cm, &cm->lf_info, edge_dir,
plane, &mi_prev->mbmi);
+#endif
#else
#if CONFIG_LPF_SB
const uint32_t pv_lvl = get_filter_level(cm, &cm->lf_info, pv_row,
@@ -2620,8 +2657,12 @@
#endif
#if CONFIG_LPF_SB
- if (partial_frame && !frame_filter_level) return;
+#if CONFIG_LOOPFILTER_LEVEL
+ if (partial_frame && !frame_filter_level && !frame_filter_level_r) return;
#else
+ if (partial_frame && !frame_filter_level) return;
+#endif // CONFIG_LOOPFILTER_LEVEL
+#else // !CONFIG_LPF_SB
#if CONFIG_LOOPFILTER_LEVEL
if (!frame_filter_level && !frame_filter_level_r) return;
#else
@@ -2645,7 +2686,14 @@
end_mi_row = AOMMIN(mi_row_range, cm->mi_rows);
end_mi_col = AOMMIN(mi_col_range, cm->mi_cols);
+#if CONFIG_LOOPFILTER_LEVEL
+ av1_loop_filter_sb_level_init(cm, mi_row, mi_col, y_only, 0,
+ frame_filter_level);
+ av1_loop_filter_sb_level_init(cm, mi_row, mi_col, y_only, 1,
+ frame_filter_level_r);
+#else
av1_loop_filter_sb_level_init(cm, mi_row, mi_col, frame_filter_level);
+#endif
} else {
start_mi_row = 0;
mi_rows_to_filter = cm->mi_rows;
diff --git a/av1/common/av1_loopfilter.h b/av1/common/av1_loopfilter.h
index 75dda7d..78305ec 100644
--- a/av1/common/av1_loopfilter.h
+++ b/av1/common/av1_loopfilter.h
@@ -148,6 +148,9 @@
#if CONFIG_LPF_SB
void av1_loop_filter_frame(YV12_BUFFER_CONFIG *frame, struct AV1Common *cm,
struct macroblockd *mbd, int filter_level,
+#if CONFIG_LOOPFILTER_LEVEL
+ int frame_filter_level_r,
+#endif
int y_only, int partial_frame, int mi_row,
int mi_col);
@@ -158,6 +161,9 @@
int col_start, int col_end, int y_only);
void av1_loop_filter_sb_level_init(struct AV1Common *cm, int mi_row, int mi_col,
+#if CONFIG_LOOPFILTER_LEVEL
+ int plane, int dir,
+#endif
int lvl);
#else
void av1_loop_filter_frame(YV12_BUFFER_CONFIG *frame, struct AV1Common *cm,
diff --git a/av1/common/blockd.h b/av1/common/blockd.h
index 1cd667a..b2465ea 100644
--- a/av1/common/blockd.h
+++ b/av1/common/blockd.h
@@ -356,11 +356,19 @@
BOUNDARY_TYPE boundary_info;
#if CONFIG_LPF_SB
+#if CONFIG_LOOPFILTER_LEVEL
+ // 0: y plane vert, 1: y plane horz, 2: u plane, 3: v plane
+ uint8_t filt_lvl[4];
+ int reuse_sb_lvl[4];
+ int sign[4];
+ int delta[4];
+#else
uint8_t filt_lvl;
int reuse_sb_lvl;
int sign;
int delta;
-#endif
+#endif // CONFIG_LOOPFILTER_LEVEL
+#endif // CONFIG_LPF_SB
#if CONFIG_JNT_COMP
int compound_idx;
diff --git a/av1/common/entropymode.c b/av1/common/entropymode.c
index f211b9d..47c22b8 100644
--- a/av1/common/entropymode.c
+++ b/av1/common/entropymode.c
@@ -2829,6 +2829,64 @@
#endif // CONFIG_KF_CTX
#if CONFIG_LPF_SB
+#if CONFIG_LOOPFILTER_LEVEL
+static const aom_cdf_prob
+ default_lpf_reuse_cdf[4][LPF_REUSE_CONTEXT][CDF_SIZE(2)] = {
+ { { AOM_CDF2(4259) }, { AOM_CDF2(728) } },
+ { { AOM_CDF2(4259) }, { AOM_CDF2(728) } },
+ { { AOM_CDF2(4259) }, { AOM_CDF2(728) } },
+ { { AOM_CDF2(4259) }, { AOM_CDF2(728) } },
+ };
+
+static const aom_cdf_prob
+ default_lpf_delta_cdf[4][LPF_DELTA_CONTEXT][CDF_SIZE(DELTA_RANGE)] = {
+ { { AOM_CDF8(100, 688, 2128, 4642, 7895, 11851, 17050) },
+ { AOM_CDF8(100, 1291, 4358, 7425, 10654, 13559, 18563) },
+ { AOM_CDF8(100, 1086, 4982, 9134, 13031, 16991, 23123) },
+ { AOM_CDF8(100, 1068, 3395, 7973, 12512, 17967, 22812) },
+ { AOM_CDF8(100, 442, 2809, 7178, 12535, 17450, 22417) },
+ { AOM_CDF8(100, 561, 2246, 6050, 11103, 16592, 21353) },
+ { AOM_CDF8(100, 345, 2399, 5559, 9682, 13992, 20126) },
+ { AOM_CDF8(100, 337, 1540, 3573, 6438, 10196, 16320) } },
+ { { AOM_CDF8(100, 688, 2128, 4642, 7895, 11851, 17050) },
+ { AOM_CDF8(100, 1291, 4358, 7425, 10654, 13559, 18563) },
+ { AOM_CDF8(100, 1086, 4982, 9134, 13031, 16991, 23123) },
+ { AOM_CDF8(100, 1068, 3395, 7973, 12512, 17967, 22812) },
+ { AOM_CDF8(100, 442, 2809, 7178, 12535, 17450, 22417) },
+ { AOM_CDF8(100, 561, 2246, 6050, 11103, 16592, 21353) },
+ { AOM_CDF8(100, 345, 2399, 5559, 9682, 13992, 20126) },
+ { AOM_CDF8(100, 337, 1540, 3573, 6438, 10196, 16320) } },
+ { { AOM_CDF8(100, 688, 2128, 4642, 7895, 11851, 17050) },
+ { AOM_CDF8(100, 1291, 4358, 7425, 10654, 13559, 18563) },
+ { AOM_CDF8(100, 1086, 4982, 9134, 13031, 16991, 23123) },
+ { AOM_CDF8(100, 1068, 3395, 7973, 12512, 17967, 22812) },
+ { AOM_CDF8(100, 442, 2809, 7178, 12535, 17450, 22417) },
+ { AOM_CDF8(100, 561, 2246, 6050, 11103, 16592, 21353) },
+ { AOM_CDF8(100, 345, 2399, 5559, 9682, 13992, 20126) },
+ { AOM_CDF8(100, 337, 1540, 3573, 6438, 10196, 16320) } },
+ { { AOM_CDF8(100, 688, 2128, 4642, 7895, 11851, 17050) },
+ { AOM_CDF8(100, 1291, 4358, 7425, 10654, 13559, 18563) },
+ { AOM_CDF8(100, 1086, 4982, 9134, 13031, 16991, 23123) },
+ { AOM_CDF8(100, 1068, 3395, 7973, 12512, 17967, 22812) },
+ { AOM_CDF8(100, 442, 2809, 7178, 12535, 17450, 22417) },
+ { AOM_CDF8(100, 561, 2246, 6050, 11103, 16592, 21353) },
+ { AOM_CDF8(100, 345, 2399, 5559, 9682, 13992, 20126) },
+ { AOM_CDF8(100, 337, 1540, 3573, 6438, 10196, 16320) } },
+ };
+
+static const aom_cdf_prob
+ default_lpf_sign_cdf[4][LPF_REUSE_CONTEXT][LPF_SIGN_CONTEXT][CDF_SIZE(2)] =
+ {
+ { { { AOM_CDF2(100) }, { AOM_CDF2(11932) } },
+ { { AOM_CDF2(14785) }, { AOM_CDF2(8145) } } },
+ { { { AOM_CDF2(100) }, { AOM_CDF2(11932) } },
+ { { AOM_CDF2(14785) }, { AOM_CDF2(8145) } } },
+ { { { AOM_CDF2(100) }, { AOM_CDF2(11932) } },
+ { { AOM_CDF2(14785) }, { AOM_CDF2(8145) } } },
+ { { { AOM_CDF2(100) }, { AOM_CDF2(11932) } },
+ { { AOM_CDF2(14785) }, { AOM_CDF2(8145) } } },
+ };
+#else
static const aom_cdf_prob default_lpf_reuse_cdf[LPF_REUSE_CONTEXT][CDF_SIZE(
2)] = { { AOM_CDF2(4259) }, { AOM_CDF2(728) } };
@@ -2847,6 +2905,7 @@
{ { AOM_CDF2(100) }, { AOM_CDF2(11932) } },
{ { AOM_CDF2(14785) }, { AOM_CDF2(8145) } }
};
+#endif // CONFIG_LOOPFILTER_LEVEL
#endif // CONFIG_LPF_SB
#if CONFIG_EXT_INTRA_MOD
diff --git a/av1/common/entropymode.h b/av1/common/entropymode.h
index acb23c8..9b9f156 100644
--- a/av1/common/entropymode.h
+++ b/av1/common/entropymode.h
@@ -319,9 +319,16 @@
aom_cdf_prob cfl_alpha_cdf[CFL_ALPHA_CONTEXTS][CDF_SIZE(CFL_ALPHABET_SIZE)];
#endif
#if CONFIG_LPF_SB
+#if CONFIG_LOOPFILTER_LEVEL
+ aom_cdf_prob lpf_reuse_cdf[4][LPF_REUSE_CONTEXT][CDF_SIZE(2)];
+ aom_cdf_prob lpf_delta_cdf[4][LPF_DELTA_CONTEXT][CDF_SIZE(DELTA_RANGE)];
+ aom_cdf_prob lpf_sign_cdf[4][LPF_REUSE_CONTEXT][LPF_SIGN_CONTEXT]
+ [CDF_SIZE(2)];
+#else
aom_cdf_prob lpf_reuse_cdf[LPF_REUSE_CONTEXT][CDF_SIZE(2)];
aom_cdf_prob lpf_delta_cdf[LPF_DELTA_CONTEXT][CDF_SIZE(DELTA_RANGE)];
aom_cdf_prob lpf_sign_cdf[LPF_REUSE_CONTEXT][LPF_SIGN_CONTEXT][CDF_SIZE(2)];
+#endif
#endif // CONFIG_LPF_SB
} FRAME_CONTEXT;
@@ -429,9 +436,15 @@
[FILTER_INTRA_MODES];
#endif // CONFIG_FILTER_INTRA
#if CONFIG_LPF_SB
+#if CONFIG_LOOPFILTER_LEVEL
+ unsigned int lpf_reuse[4][LPF_REUSE_CONTEXT][2];
+ unsigned int lpf_delta[4][LPF_DELTA_CONTEXT][DELTA_RANGE];
+ unsigned int lpf_sign[4][LPF_REUSE_CONTEXT][LPF_SIGN_CONTEXT][2];
+#else
unsigned int lpf_reuse[LPF_REUSE_CONTEXT][2];
unsigned int lpf_delta[LPF_DELTA_CONTEXT][DELTA_RANGE];
unsigned int lpf_sign[LPF_REUSE_CONTEXT][LPF_SIGN_CONTEXT][2];
+#endif // CONFIG_LOOPFILTER_LEVEL
#endif // CONFIG_LPF_SB
} FRAME_COUNTS;
diff --git a/av1/common/enums.h b/av1/common/enums.h
index 3425c97..2d6184b 100644
--- a/av1/common/enums.h
+++ b/av1/common/enums.h
@@ -106,7 +106,7 @@
#define FILT_BOUNDARY_OFFSET 0
#define FILT_BOUNDARY_MI_OFFSET (FILT_BOUNDARY_OFFSET >> MI_SIZE_LOG2)
-#define USE_GUESS_LEVEL 0
+#define USE_GUESS_LEVEL 1
#define USE_LOOP_FILTER_SUPERBLOCK 1
#endif // CONFIG_LPF_SB