Commit 765e34e3 authored by Cheng Chen's avatar Cheng Chen

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
parent 13c42779
...@@ -350,7 +350,12 @@ static uint8_t get_filter_level(const AV1_COMMON *cm, ...@@ -350,7 +350,12 @@ static uint8_t get_filter_level(const AV1_COMMON *cm,
#endif #endif
const MB_MODE_INFO *mbmi) { const MB_MODE_INFO *mbmi) {
#if CONFIG_LPF_SB #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; return cm->mi[mi_row * cm->mi_stride + mi_col].mbmi.filt_lvl;
#endif
#endif #endif
const int segment_id = mbmi->segment_id; const int segment_id = mbmi->segment_id;
...@@ -429,6 +434,9 @@ void av1_loop_filter_init(AV1_COMMON *cm) { ...@@ -429,6 +434,9 @@ void av1_loop_filter_init(AV1_COMMON *cm) {
#if CONFIG_LPF_SB #if CONFIG_LPF_SB
void av1_loop_filter_sb_level_init(AV1_COMMON *cm, int mi_row, int mi_col, 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) { int lvl) {
const int mi_row_start = AOMMAX(0, mi_row - FILT_BOUNDARY_MI_OFFSET); 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); const int mi_col_start = AOMMAX(0, mi_col - FILT_BOUNDARY_MI_OFFSET);
...@@ -440,9 +448,14 @@ void av1_loop_filter_sb_level_init(AV1_COMMON *cm, int mi_row, int mi_col, ...@@ -440,9 +448,14 @@ void av1_loop_filter_sb_level_init(AV1_COMMON *cm, int mi_row, int mi_col,
int row, col; int row, col;
for (row = mi_row_start; row < mi_row_end; ++row) { for (row = mi_row_start; row < mi_row_end; ++row) {
for (col = mi_col_start; col < mi_col_end; ++col) { for (col = mi_col_start; col < mi_col_end; ++col) {
// Note: can't use cm->mi_grid_visible. Because for each partition, // Note: can't use cm->mi_grid_visible. Because for each partition,
// all visible pointers will point to the first of the 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; cm->mi[row * cm->mi_stride + col].mbmi.filt_lvl = lvl;
#endif // CONFIG_LOOPFILTER_LEVEL
} }
} }
} }
...@@ -939,7 +952,11 @@ static void build_masks(AV1_COMMON *const cm, ...@@ -939,7 +952,11 @@ static void build_masks(AV1_COMMON *const cm,
txsize_vert_map[uv_txsize_lookup[block_size][mbmi->tx_size][1][1]]; txsize_vert_map[uv_txsize_lookup[block_size][mbmi->tx_size][1][1]];
#if CONFIG_EXT_DELTA_Q #if CONFIG_EXT_DELTA_Q
#if CONFIG_LOOPFILTER_LEVEL #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); const int filter_level = get_filter_level(cm, lfi_n, 0, 0, mbmi);
#endif
#else #else
#if CONFIG_LPF_SB #if CONFIG_LPF_SB
const int filter_level = get_filter_level(cm, lfi_n, 0, 0, mbmi); const int filter_level = get_filter_level(cm, lfi_n, 0, 0, mbmi);
...@@ -1033,7 +1050,11 @@ static void build_y_mask(AV1_COMMON *const cm, ...@@ -1033,7 +1050,11 @@ static void build_y_mask(AV1_COMMON *const cm,
const BLOCK_SIZE block_size = mbmi->sb_type; const BLOCK_SIZE block_size = mbmi->sb_type;
#if CONFIG_EXT_DELTA_Q #if CONFIG_EXT_DELTA_Q
#if CONFIG_LOOPFILTER_LEVEL #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); const int filter_level = get_filter_level(cm, lfi_n, 0, 0, mbmi);
#endif
#else #else
#if CONFIG_LPF_SB #if CONFIG_LPF_SB
const int filter_level = get_filter_level(cm, lfi_n, 0, 0, mbmi); const int filter_level = get_filter_level(cm, lfi_n, 0, 0, mbmi);
...@@ -1507,8 +1528,13 @@ static void get_filter_level_and_masks_non420( ...@@ -1507,8 +1528,13 @@ static void get_filter_level_and_masks_non420(
// Filter level can vary per MI // Filter level can vary per MI
#if CONFIG_EXT_DELTA_Q #if CONFIG_EXT_DELTA_Q
#if CONFIG_LOOPFILTER_LEVEL #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))) if (!(lfl_r[c_step] = get_filter_level(cm, &cm->lf_info, 0, 0, mbmi)))
continue; continue;
#endif
#else #else
#if CONFIG_LPF_SB #if CONFIG_LPF_SB
if (!(lfl_r[c_step] = if (!(lfl_r[c_step] =
...@@ -2169,8 +2195,13 @@ static void set_lpf_parameters( ...@@ -2169,8 +2195,13 @@ static void set_lpf_parameters(
#if CONFIG_EXT_DELTA_Q #if CONFIG_EXT_DELTA_Q
#if CONFIG_LOOPFILTER_LEVEL #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 = const uint32_t curr_level =
get_filter_level(cm, &cm->lf_info, edge_dir, plane, mbmi); get_filter_level(cm, &cm->lf_info, edge_dir, plane, mbmi);
#endif
#else #else
#if CONFIG_LPF_SB #if CONFIG_LPF_SB
const uint32_t curr_level = const uint32_t curr_level =
...@@ -2211,8 +2242,14 @@ static void set_lpf_parameters( ...@@ -2211,8 +2242,14 @@ static void set_lpf_parameters(
#if CONFIG_EXT_DELTA_Q #if CONFIG_EXT_DELTA_Q
#if CONFIG_LOOPFILTER_LEVEL #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, const uint32_t pv_lvl = get_filter_level(cm, &cm->lf_info, edge_dir,
plane, &mi_prev->mbmi); plane, &mi_prev->mbmi);
#endif
#else #else
#if CONFIG_LPF_SB #if CONFIG_LPF_SB
const uint32_t pv_lvl = get_filter_level(cm, &cm->lf_info, pv_row, const uint32_t pv_lvl = get_filter_level(cm, &cm->lf_info, pv_row,
...@@ -2620,8 +2657,12 @@ void av1_loop_filter_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm, ...@@ -2620,8 +2657,12 @@ void av1_loop_filter_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm,
#endif #endif
#if CONFIG_LPF_SB #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 #else
if (partial_frame && !frame_filter_level) return;
#endif // CONFIG_LOOPFILTER_LEVEL
#else // !CONFIG_LPF_SB
#if CONFIG_LOOPFILTER_LEVEL #if CONFIG_LOOPFILTER_LEVEL
if (!frame_filter_level && !frame_filter_level_r) return; if (!frame_filter_level && !frame_filter_level_r) return;
#else #else
...@@ -2645,7 +2686,14 @@ void av1_loop_filter_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm, ...@@ -2645,7 +2686,14 @@ void av1_loop_filter_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm,
end_mi_row = AOMMIN(mi_row_range, cm->mi_rows); end_mi_row = AOMMIN(mi_row_range, cm->mi_rows);
end_mi_col = AOMMIN(mi_col_range, cm->mi_cols); 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); av1_loop_filter_sb_level_init(cm, mi_row, mi_col, frame_filter_level);
#endif
} else { } else {
start_mi_row = 0; start_mi_row = 0;
mi_rows_to_filter = cm->mi_rows; mi_rows_to_filter = cm->mi_rows;
......
...@@ -148,6 +148,9 @@ void av1_loop_filter_frame_init(struct AV1Common *cm, int default_filt_lvl, ...@@ -148,6 +148,9 @@ void av1_loop_filter_frame_init(struct AV1Common *cm, int default_filt_lvl,
#if CONFIG_LPF_SB #if CONFIG_LPF_SB
void av1_loop_filter_frame(YV12_BUFFER_CONFIG *frame, struct AV1Common *cm, void av1_loop_filter_frame(YV12_BUFFER_CONFIG *frame, struct AV1Common *cm,
struct macroblockd *mbd, int filter_level, 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 y_only, int partial_frame, int mi_row,
int mi_col); int mi_col);
...@@ -158,6 +161,9 @@ void av1_loop_filter_rows(YV12_BUFFER_CONFIG *frame_buffer, ...@@ -158,6 +161,9 @@ void av1_loop_filter_rows(YV12_BUFFER_CONFIG *frame_buffer,
int col_start, int col_end, int y_only); 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, 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); int lvl);
#else #else
void av1_loop_filter_frame(YV12_BUFFER_CONFIG *frame, struct AV1Common *cm, void av1_loop_filter_frame(YV12_BUFFER_CONFIG *frame, struct AV1Common *cm,
......
...@@ -356,11 +356,19 @@ typedef struct MB_MODE_INFO { ...@@ -356,11 +356,19 @@ typedef struct MB_MODE_INFO {
BOUNDARY_TYPE boundary_info; BOUNDARY_TYPE boundary_info;
#if CONFIG_LPF_SB #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; uint8_t filt_lvl;
int reuse_sb_lvl; int reuse_sb_lvl;
int sign; int sign;
int delta; int delta;
#endif #endif // CONFIG_LOOPFILTER_LEVEL
#endif // CONFIG_LPF_SB
#if CONFIG_JNT_COMP #if CONFIG_JNT_COMP
int compound_idx; int compound_idx;
......
...@@ -2829,6 +2829,64 @@ const aom_cdf_prob ...@@ -2829,6 +2829,64 @@ const aom_cdf_prob
#endif // CONFIG_KF_CTX #endif // CONFIG_KF_CTX
#if CONFIG_LPF_SB #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( static const aom_cdf_prob default_lpf_reuse_cdf[LPF_REUSE_CONTEXT][CDF_SIZE(
2)] = { { AOM_CDF2(4259) }, { AOM_CDF2(728) } }; 2)] = { { AOM_CDF2(4259) }, { AOM_CDF2(728) } };
...@@ -2847,6 +2905,7 @@ static const aom_cdf_prob ...@@ -2847,6 +2905,7 @@ static const aom_cdf_prob
{ { AOM_CDF2(100) }, { AOM_CDF2(11932) } }, { { AOM_CDF2(100) }, { AOM_CDF2(11932) } },
{ { AOM_CDF2(14785) }, { AOM_CDF2(8145) } } { { AOM_CDF2(14785) }, { AOM_CDF2(8145) } }
}; };
#endif // CONFIG_LOOPFILTER_LEVEL
#endif // CONFIG_LPF_SB #endif // CONFIG_LPF_SB
#if CONFIG_EXT_INTRA_MOD #if CONFIG_EXT_INTRA_MOD
......
...@@ -319,9 +319,16 @@ typedef struct frame_contexts { ...@@ -319,9 +319,16 @@ typedef struct frame_contexts {
aom_cdf_prob cfl_alpha_cdf[CFL_ALPHA_CONTEXTS][CDF_SIZE(CFL_ALPHABET_SIZE)]; aom_cdf_prob cfl_alpha_cdf[CFL_ALPHA_CONTEXTS][CDF_SIZE(CFL_ALPHABET_SIZE)];
#endif #endif
#if CONFIG_LPF_SB #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_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_delta_cdf[LPF_DELTA_CONTEXT][CDF_SIZE(DELTA_RANGE)];
aom_cdf_prob lpf_sign_cdf[LPF_REUSE_CONTEXT][LPF_SIGN_CONTEXT][CDF_SIZE(2)]; aom_cdf_prob lpf_sign_cdf[LPF_REUSE_CONTEXT][LPF_SIGN_CONTEXT][CDF_SIZE(2)];
#endif
#endif // CONFIG_LPF_SB #endif // CONFIG_LPF_SB
} FRAME_CONTEXT; } FRAME_CONTEXT;
...@@ -429,9 +436,15 @@ typedef struct FRAME_COUNTS { ...@@ -429,9 +436,15 @@ typedef struct FRAME_COUNTS {
[FILTER_INTRA_MODES]; [FILTER_INTRA_MODES];
#endif // CONFIG_FILTER_INTRA #endif // CONFIG_FILTER_INTRA
#if CONFIG_LPF_SB #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_reuse[LPF_REUSE_CONTEXT][2];
unsigned int lpf_delta[LPF_DELTA_CONTEXT][DELTA_RANGE]; unsigned int lpf_delta[LPF_DELTA_CONTEXT][DELTA_RANGE];
unsigned int lpf_sign[LPF_REUSE_CONTEXT][LPF_SIGN_CONTEXT][2]; unsigned int lpf_sign[LPF_REUSE_CONTEXT][LPF_SIGN_CONTEXT][2];
#endif // CONFIG_LOOPFILTER_LEVEL
#endif // CONFIG_LPF_SB #endif // CONFIG_LPF_SB
} FRAME_COUNTS; } FRAME_COUNTS;
......
...@@ -106,7 +106,7 @@ extern "C" { ...@@ -106,7 +106,7 @@ extern "C" {
#define FILT_BOUNDARY_OFFSET 0 #define FILT_BOUNDARY_OFFSET 0
#define FILT_BOUNDARY_MI_OFFSET (FILT_BOUNDARY_OFFSET >> MI_SIZE_LOG2) #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 #define USE_LOOP_FILTER_SUPERBLOCK 1
#endif // CONFIG_LPF_SB #endif // CONFIG_LPF_SB
......
...@@ -792,6 +792,77 @@ static void decode_partition(AV1Decoder *const pbi, MACROBLOCKD *const xd, ...@@ -792,6 +792,77 @@ static void decode_partition(AV1Decoder *const pbi, MACROBLOCKD *const xd,
#endif // CONFIG_EXT_PARTITION_TYPES #endif // CONFIG_EXT_PARTITION_TYPES
#if CONFIG_LPF_SB #if CONFIG_LPF_SB
#if CONFIG_LOOPFILTER_LEVEL
if (bsize == cm->sb_size && !USE_GUESS_LEVEL) {
int lvl_idx;
int filt_lvl[4];
if (mi_row == 0 && mi_col == 0) {
filt_lvl[0] = aom_read_literal(r, 6, ACCT_STR);
filt_lvl[1] = aom_read_literal(r, 6, ACCT_STR);
if (filt_lvl[0] || filt_lvl[1]) {
filt_lvl[2] = aom_read_literal(r, 6, ACCT_STR);
filt_lvl[3] = aom_read_literal(r, 6, ACCT_STR);
}
for (lvl_idx = 0; lvl_idx < 4; ++lvl_idx) {
cm->mi_grid_visible[0]->mbmi.reuse_sb_lvl[lvl_idx] = 0;
cm->mi_grid_visible[0]->mbmi.delta[lvl_idx] = 0;
cm->mi_grid_visible[0]->mbmi.sign[lvl_idx] = 0;
}
} else {
int prev_mi_row, prev_mi_col;
if (mi_col - MAX_MIB_SIZE < 0) {
prev_mi_row = mi_row - MAX_MIB_SIZE;
prev_mi_col = mi_col;
} else {
prev_mi_row = mi_row;
prev_mi_col = mi_col - MAX_MIB_SIZE;
}
MB_MODE_INFO *curr_mbmi =
&cm->mi_grid_visible[mi_row * cm->mi_stride + mi_col]->mbmi;
MB_MODE_INFO *prev_mbmi =
&cm->mi_grid_visible[prev_mi_row * cm->mi_stride + prev_mi_col]->mbmi;
for (lvl_idx = 0; lvl_idx < 4; ++lvl_idx) {
const uint8_t prev_lvl = prev_mbmi->filt_lvl[lvl_idx];
const int reuse_ctx = prev_mbmi->reuse_sb_lvl[lvl_idx];
const int reuse_prev_lvl = aom_read_symbol(
r, xd->tile_ctx->lpf_reuse_cdf[lvl_idx][reuse_ctx], 2, ACCT_STR);
curr_mbmi->reuse_sb_lvl[lvl_idx] = reuse_prev_lvl;
if (reuse_prev_lvl) {
filt_lvl[lvl_idx] = prev_lvl;
curr_mbmi->delta[lvl_idx] = 0;
curr_mbmi->sign[lvl_idx] = 0;
} else {
const int delta_ctx = prev_mbmi->delta[lvl_idx];
unsigned int delta = aom_read_symbol(
r, xd->tile_ctx->lpf_delta_cdf[lvl_idx][delta_ctx], DELTA_RANGE,
ACCT_STR);
curr_mbmi->delta[lvl_idx] = delta;
delta *= LPF_STEP;
if (delta) {
const int sign_ctx = prev_mbmi->sign[lvl_idx];
const int sign = aom_read_symbol(
r, xd->tile_ctx->lpf_sign_cdf[lvl_idx][reuse_ctx][sign_ctx], 2,
ACCT_STR);
curr_mbmi->sign[lvl_idx] = sign;
filt_lvl[lvl_idx] = sign ? prev_lvl + delta : prev_lvl - delta;
} else {
filt_lvl[lvl_idx] = prev_lvl;
curr_mbmi->sign[lvl_idx] = 0;
}
}
}
}
av1_loop_filter_sb_level_init(cm, mi_row, mi_col, 0, 0, filt_lvl[0]);
av1_loop_filter_sb_level_init(cm, mi_row, mi_col, 0, 1, filt_lvl[1]);
av1_loop_filter_sb_level_init(cm, mi_row, mi_col, 1, 0, filt_lvl[2]);
av1_loop_filter_sb_level_init(cm, mi_row, mi_col, 2, 0, filt_lvl[3]);
}
#else
if (bsize == cm->sb_size && !USE_GUESS_LEVEL) { if (bsize == cm->sb_size && !USE_GUESS_LEVEL) {
int filt_lvl; int filt_lvl;
if (mi_row == 0 && mi_col == 0) { if (mi_row == 0 && mi_col == 0) {
...@@ -846,7 +917,8 @@ static void decode_partition(AV1Decoder *const pbi, MACROBLOCKD *const xd, ...@@ -846,7 +917,8 @@ static void decode_partition(AV1Decoder *const pbi, MACROBLOCKD *const xd,
av1_loop_filter_sb_level_init(cm, mi_row, mi_col, filt_lvl); av1_loop_filter_sb_level_init(cm, mi_row, mi_col, filt_lvl);
} }
#endif #endif // CONFIG_LOOPFILTER_LEVEL
#endif // CONFIG_LPF_SB
#if CONFIG_LOOP_RESTORATION #if CONFIG_LOOP_RESTORATION
for (int plane = 0; plane < av1_num_planes(cm); ++plane) { for (int plane = 0; plane < av1_num_planes(cm); ++plane) {
...@@ -1114,12 +1186,18 @@ static void setup_loopfilter(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) { ...@@ -1114,12 +1186,18 @@ static void setup_loopfilter(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
#endif // CONFIG_INTRABC && !CONFIG_LPF_SB #endif // CONFIG_INTRABC && !CONFIG_LPF_SB
struct loopfilter *lf = &cm->lf; struct loopfilter *lf = &cm->lf;
#if CONFIG_LOOPFILTER_LEVEL #if CONFIG_LOOPFILTER_LEVEL
lf->filter_level[0] = aom_rb_read_literal(rb, 6); #if CONFIG_LPF_SB
lf->filter_level[1] = aom_rb_read_literal(rb, 6); if (USE_GUESS_LEVEL) {
if (lf->filter_level[0] || lf->filter_level[1]) { #endif // CONFIG_LPF_SB
lf->filter_level_u = aom_rb_read_literal(rb, 6); lf->filter_level[0] = aom_rb_read_literal(rb, 6);
lf->filter_level_v = aom_rb_read_literal(rb, 6); lf->filter_level[1] = aom_rb_read_literal(rb, 6);
if (lf->filter_level[0] || lf->filter_level[1]) {
lf->filter_level_u = aom_rb_read_literal(rb, 6);
lf->filter_level_v = aom_rb_read_literal(rb, 6);
}
#if CONFIG_LPF_SB
} }
#endif // CONFIG_LPF_SB
#else #else
#if CONFIG_LPF_SB #if CONFIG_LPF_SB
if (USE_GUESS_LEVEL) lf->filter_level = aom_rb_read_literal(rb, 6); if (USE_GUESS_LEVEL) lf->filter_level = aom_rb_read_literal(rb, 6);
...@@ -2216,11 +2294,30 @@ static const uint8_t *decode_tiles(AV1Decoder *pbi, const uint8_t *data, ...@@ -2216,11 +2294,30 @@ static const uint8_t *decode_tiles(AV1Decoder *pbi, const uint8_t *data,
cm->sb_size); cm->sb_size);
#if CONFIG_LPF_SB #if CONFIG_LPF_SB
if (USE_LOOP_FILTER_SUPERBLOCK) { if (USE_LOOP_FILTER_SUPERBLOCK) {
#if CONFIG_LOOPFILTER_LEVEL
if (USE_GUESS_LEVEL) {
if (cm->lf.filter_level[0] || cm->lf.filter_level[1]) {
av1_loop_filter_frame(get_frame_new_buffer(cm), cm, &pbi->mb,
cm->lf.filter_level[0],
cm->lf.filter_level[1], 0, 1, mi_row,
mi_col);
av1_loop_filter_frame(get_frame_new_buffer(cm), cm, &pbi->mb,
cm->lf.filter_level_u,
cm->lf.filter_level_u, 1, 1, mi_row,
mi_col);
av1_loop_filter_frame(get_frame_new_buffer(cm), cm, &pbi->mb,
cm->lf.filter_level_v,
cm->lf.filter_level_v, 2, 1, mi_row,
mi_col);
}
}
#else
// apply deblocking filtering right after each superblock is decoded // apply deblocking filtering right after each superblock is decoded
const int filter_lvl = const int filter_lvl =
cm->mi[mi_row * cm->mi_stride + mi_col].mbmi.filt_lvl; cm->mi[mi_row * cm->mi_stride + mi_col].mbmi.filt_lvl;
av1_loop_filter_frame(get_frame_new_buffer(cm), cm, &pbi->mb, av1_loop_filter_frame(get_frame_new_buffer(cm), cm, &pbi->mb,
filter_lvl, 0, 1, mi_row, mi_col); filter_lvl, 0, 1, mi_row, mi_col);
#endif // CONFIG_LOOPFILTER_LEVEL
} }
#endif // CONFIG_LPF_SB #endif // CONFIG_LPF_SB
} }
...@@ -2253,7 +2350,7 @@ static const uint8_t *decode_tiles(AV1Decoder *pbi, const uint8_t *data, ...@@ -2253,7 +2350,7 @@ static const uint8_t *decode_tiles(AV1Decoder *pbi, const uint8_t *data,
#if CONFIG_OBU #if CONFIG_OBU
if (endTile == cm->tile_rows * cm->tile_cols - 1) if (endTile == cm->tile_rows * cm->tile_cols - 1)
#endif #endif
#if CONFIG_LOOPFILTER_LEVEL #if CONFIG_LOOPFILTER_LEVEL && !CONFIG_LPF_SB
if (cm->lf.filter_level[0] || cm->lf.filter_level[1]) { if (cm->lf.filter_level[0] || cm->lf.filter_level[1]) {
av1_loop_filter_frame(get_frame_new_buffer(cm), cm, &pbi->mb, av1_loop_filter_frame(get_frame_new_buffer(cm), cm, &pbi->mb,
cm->lf.filter_level[0], cm->lf.filter_level[1], 0, cm->lf.filter_level[0], cm->lf.filter_level[1], 0,
...@@ -2265,7 +2362,7 @@ static const uint8_t *decode_tiles(AV1Decoder *pbi, const uint8_t *data, ...@@ -2265,7 +2362,7 @@ static const uint8_t *decode_tiles(AV1Decoder *pbi, const uint8_t *data,
cm->lf.filter_level_v, cm->lf.filter_level_v, 2, cm->lf.filter_level_v, cm->lf.filter_level_v, 2,
0); 0);
} }
#else #elif !CONFIG_LPF_SB
av1_loop_filter_frame(get_frame_new_buffer(cm), cm, &pbi->mb, av1_loop_filter_frame(get_frame_new_buffer(cm), cm, &pbi->mb,
cm->lf.filter_level, 0, 0); cm->lf.filter_level, 0, 0);
#endif // CONFIG_LOOPFILTER_LEVEL #endif // CONFIG_LOOPFILTER_LEVEL
......
...@@ -2298,11 +2298,26 @@ static void write_modes_sb(AV1_COMP *const cpi, const TileInfo *const tile, ...@@ -2298,11 +2298,26 @@ static void write_modes_sb(AV1_COMP *const cpi, const TileInfo *const tile,
#if CONFIG_LPF_SB #if CONFIG_LPF_SB
// send filter level for each superblock (64x64) // send filter level for each superblock (64x64)
if (bsize == cm->sb_size && !USE_GUESS_LEVEL) { if (bsize == cm->sb_size && !USE_GUESS_LEVEL) {