Commit ebcee0b6 authored by Cheng Chen's avatar Cheng Chen

LPF_SB: select filter level and apply for superblock

For each superblock, select the best deblocking filter level and apply
filtering. The filter level is signaled to decoder using a delta based
scheme.

Change-Id: I53e32589cabac9e2a4e580808fdd39ac878fe8c6
parent 6b56e99c
......@@ -2282,9 +2282,10 @@ static const uint8_t *decode_tiles(AV1Decoder *pbi, const uint8_t *data,
#if CONFIG_LPF_SB
if (USE_LOOP_FILTER_SUPERBLOCK) {
// apply deblocking filtering right after each superblock is decoded
const int guess_filter_lvl = FAKE_FILTER_LEVEL;
const int filter_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,
guess_filter_lvl, 0, 1, mi_row, mi_col);
filter_lvl, 0, 1, mi_row, mi_col);
}
#endif // CONFIG_LPF_SB
}
......
......@@ -2295,7 +2295,7 @@ static void write_modes_sb(AV1_COMP *const cpi, const TileInfo *const tile,
// send filter level for each superblock (64x64)
if (bsize == cm->sb_size) {
if (mi_row == 0 && mi_col == 0) {
aom_write_literal(w, cm->mi_grid_visible[0]->mbmi.filt_lvl, 6);
aom_write_literal(w, cm->mi[0].mbmi.filt_lvl, 6);
cm->mi_grid_visible[0]->mbmi.reuse_sb_lvl = 0;
cm->mi_grid_visible[0]->mbmi.delta = 0;
cm->mi_grid_visible[0]->mbmi.sign = 0;
......
......@@ -52,6 +52,9 @@
#endif
#include "av1/encoder/ethread.h"
#include "av1/encoder/extend.h"
#if CONFIG_LPF_SB
#include "av1/encoder/picklpf.h"
#endif
#include "av1/encoder/rd.h"
#include "av1/encoder/rdopt.h"
#include "av1/encoder/segmentation.h"
......@@ -3503,9 +3506,25 @@ static void encode_rd_sb_row(AV1_COMP *cpi, ThreadData *td,
#if CONFIG_LPF_SB
if (USE_LOOP_FILTER_SUPERBLOCK) {
// apply deblocking filtering right after each superblock is encoded.
const int guess_filter_lvl = FAKE_FILTER_LEVEL;
av1_loop_filter_frame(get_frame_new_buffer(cm), cm, xd, guess_filter_lvl,
0, 1, mi_row, mi_col);
int last_lvl;
if (mi_row == 0 && mi_col == 0) {
last_lvl = 0;
} else {
if (mi_col == 0) {
last_lvl =
cm->mi[(mi_row - MAX_MIB_SIZE) * cm->mi_stride].mbmi.filt_lvl;
} else {
last_lvl = cm->mi[mi_row * cm->mi_stride + mi_col - MAX_MIB_SIZE]
.mbmi.filt_lvl;
}
}
const int filter_lvl = av1_search_filter_level(cpi->source, cpi, 1, NULL,
mi_row, mi_col, last_lvl);
av1_loop_filter_frame(get_frame_new_buffer(cm), cm, xd, filter_lvl, 0, 1,
mi_row, mi_col);
// if filter_lvl is 0, we still need to set mi info
if (filter_lvl == 0)
av1_loop_filter_sb_level_init(cm, mi_row, mi_col, filter_lvl);
}
#endif // CONFIG_LPF_SB
}
......@@ -3674,6 +3693,10 @@ static void encode_tiles(AV1_COMP *cpi) {
av1_init_tile_data(cpi);
#if CONFIG_LPF_SB
cm->frame_to_show = get_frame_new_buffer(cm);
#endif
for (tile_row = 0; tile_row < cm->tile_rows; ++tile_row)
for (tile_col = 0; tile_col < cm->tile_cols; ++tile_col)
av1_encode_tile(cpi, &cpi->td, tile_row, tile_col);
......
......@@ -4657,7 +4657,11 @@ static void loopfilter_frame(AV1_COMP *cpi, AV1_COMMON *cm) {
|| cm->single_tile_decoding
#endif // CONFIG_EXT_TILE
) {
#if CONFIG_LPF_SB
if (!USE_LOOP_FILTER_SUPERBLOCK) no_loopfilter = 1;
#else
no_loopfilter = 1;
#endif // CONFIG_LPF_SB
#if CONFIG_LOOP_RESTORATION
no_restoration = 1;
#endif // CONFIG_LOOP_RESTORATION
......@@ -4689,7 +4693,9 @@ static void loopfilter_frame(AV1_COMP *cpi, AV1_COMMON *cm) {
aom_usec_timer_start(&timer);
#if !CONFIG_LPF_SB
av1_pick_filter_level(cpi->source, cpi, cpi->sf.lpf_pick);
#endif
aom_usec_timer_mark(&timer);
cpi->time_pick_lpf += aom_usec_timer_elapsed(&timer);
......
......@@ -144,9 +144,9 @@ static int try_filter_superblock(const YV12_BUFFER_CONFIG *sd,
return filt_err;
}
static int search_filter_level(const YV12_BUFFER_CONFIG *sd, AV1_COMP *cpi,
int partial_frame, double *best_cost_ret,
int mi_row, int mi_col, int last_lvl) {
int av1_search_filter_level(const YV12_BUFFER_CONFIG *sd, AV1_COMP *cpi,
int partial_frame, double *best_cost_ret,
int mi_row, int mi_col, int last_lvl) {
assert(partial_frame == 1);
assert(last_lvl >= 0);
......@@ -466,8 +466,13 @@ void av1_pick_filter_level(const YV12_BUFFER_CONFIG *sd, AV1_COMP *cpi,
// there're (FILT_BOUNDAR_OFFSET + 16) pixels.
for (mi_row = 0; mi_row < cm->mi_rows; mi_row += MAX_MIB_SIZE) {
for (mi_col = 0; mi_col < cm->mi_cols; mi_col += MAX_MIB_SIZE) {
#if CONFIG_LPF_SB
int lvl =
av1_search_filter_level(sd, cpi, 1, NULL, mi_row, mi_col, last_lvl);
#else
int lvl =
search_filter_level(sd, cpi, 1, NULL, mi_row, mi_col, last_lvl);
#endif
if (USE_LOOP_FILTER_SUPERBLOCK) lvl = FAKE_FILTER_LEVEL;
av1_loop_filter_sb_level_init(cm, mi_row, mi_col, lvl);
......
......@@ -23,6 +23,11 @@ struct AV1_COMP;
int av1_get_max_filter_level(const AV1_COMP *cpi);
void av1_pick_filter_level(const struct yv12_buffer_config *sd,
struct AV1_COMP *cpi, LPF_PICK_METHOD method);
#if CONFIG_LPF_SB
int av1_search_filter_level(const YV12_BUFFER_CONFIG *sd, AV1_COMP *cpi,
int partial_frame, double *best_cost_ret,
int mi_row, int mi_col, int last_lvl);
#endif // CONFIG_LPF_SB
#ifdef __cplusplus
} // extern "C"
#endif
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment