Add an experiment to disable lpf on tile boundaries
This commit adds a new experiment to allow disabling of loop filtering on tile boundaries. It is implemented by adding a syntax field "loopfilter_across_tiles_enabled" into the uncompressed frame header. If it is set to 0, decoder and encoder will disables loop filtering for block edges that are also tile boundaries. Change-Id: Ib80bfd82d49c74f1ba46ae18ceedb30704ac8aa5
This commit is contained in:
Родитель
900243b9c0
Коммит
7386eda0e0
20
aom/aomcx.h
20
aom/aomcx.h
|
@ -277,6 +277,22 @@ enum aome_enc_control_id {
|
||||||
*/
|
*/
|
||||||
AV1E_SET_TILE_ROWS,
|
AV1E_SET_TILE_ROWS,
|
||||||
|
|
||||||
|
#if CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
/*!\brief Codec control function to set loop_filter_across_tiles_enabled.
|
||||||
|
*
|
||||||
|
* In encoding and decoding, AV1 allows disabling loop filter across tile
|
||||||
|
* boundary The parameter for this control describes the value of this flag,
|
||||||
|
* which has a valid range [0, 1]:
|
||||||
|
* 0 = disable loop filter across tile boundary
|
||||||
|
* 1 = enable loop filter across tile boundary
|
||||||
|
*
|
||||||
|
* By default, the value is 0, i.e. disable loop filter across tile boundary.
|
||||||
|
*
|
||||||
|
* Supported in codecs: AV1
|
||||||
|
*/
|
||||||
|
AV1E_SET_TILE_LOOPFILTER,
|
||||||
|
#endif
|
||||||
|
|
||||||
/*!\brief Codec control function to enable frame parallel decoding feature.
|
/*!\brief Codec control function to enable frame parallel decoding feature.
|
||||||
*
|
*
|
||||||
* AV1 has a bitstream feature to reduce decoding dependency between frames
|
* AV1 has a bitstream feature to reduce decoding dependency between frames
|
||||||
|
@ -568,6 +584,10 @@ AOM_CTRL_USE_TYPE(AV1E_SET_TILE_COLUMNS, int)
|
||||||
#define AOM_CTRL_AV1E_SET_TILE_COLUMNS
|
#define AOM_CTRL_AV1E_SET_TILE_COLUMNS
|
||||||
AOM_CTRL_USE_TYPE(AV1E_SET_TILE_ROWS, int)
|
AOM_CTRL_USE_TYPE(AV1E_SET_TILE_ROWS, int)
|
||||||
#define AOM_CTRL_AV1E_SET_TILE_ROWS
|
#define AOM_CTRL_AV1E_SET_TILE_ROWS
|
||||||
|
#if CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
AOM_CTRL_USE_TYPE(AV1E_SET_TILE_LOOPFILTER, int)
|
||||||
|
#define AOM_CTRL_AV1E_SET_TILE_LOOPFILTER
|
||||||
|
#endif // CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
|
||||||
AOM_CTRL_USE_TYPE(AOME_GET_LAST_QUANTIZER, int *)
|
AOM_CTRL_USE_TYPE(AOME_GET_LAST_QUANTIZER, int *)
|
||||||
#define AOM_CTRL_AOME_GET_LAST_QUANTIZER
|
#define AOM_CTRL_AOME_GET_LAST_QUANTIZER
|
||||||
|
|
10
aomenc.c
10
aomenc.c
|
@ -376,6 +376,10 @@ static const arg_def_t tile_cols =
|
||||||
static const arg_def_t tile_rows =
|
static const arg_def_t tile_rows =
|
||||||
ARG_DEF(NULL, "tile-rows", 1,
|
ARG_DEF(NULL, "tile-rows", 1,
|
||||||
"Number of tile rows to use, log2 (set to 0 while threads > 1)");
|
"Number of tile rows to use, log2 (set to 0 while threads > 1)");
|
||||||
|
#if CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
static const arg_def_t tile_loopfilter = ARG_DEF(
|
||||||
|
NULL, "tile-loopfilter", 1, "Enable loop filter across tile boundary");
|
||||||
|
#endif // CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
static const arg_def_t lossless =
|
static const arg_def_t lossless =
|
||||||
ARG_DEF(NULL, "lossless", 1, "Lossless mode (0: false (default), 1: true)");
|
ARG_DEF(NULL, "lossless", 1, "Lossless mode (0: false (default), 1: true)");
|
||||||
#if CONFIG_AOM_QM
|
#if CONFIG_AOM_QM
|
||||||
|
@ -468,6 +472,9 @@ static const arg_def_t *av1_args[] = { &cpu_used_av1,
|
||||||
&static_thresh,
|
&static_thresh,
|
||||||
&tile_cols,
|
&tile_cols,
|
||||||
&tile_rows,
|
&tile_rows,
|
||||||
|
#if CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
&tile_loopfilter,
|
||||||
|
#endif // CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
&arnr_maxframes,
|
&arnr_maxframes,
|
||||||
&arnr_strength,
|
&arnr_strength,
|
||||||
&tune_ssim,
|
&tune_ssim,
|
||||||
|
@ -507,6 +514,9 @@ static const int av1_arg_ctrl_map[] = { AOME_SET_CPUUSED,
|
||||||
AOME_SET_STATIC_THRESHOLD,
|
AOME_SET_STATIC_THRESHOLD,
|
||||||
AV1E_SET_TILE_COLUMNS,
|
AV1E_SET_TILE_COLUMNS,
|
||||||
AV1E_SET_TILE_ROWS,
|
AV1E_SET_TILE_ROWS,
|
||||||
|
#if CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
AV1E_SET_TILE_LOOPFILTER,
|
||||||
|
#endif // CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
AOME_SET_ARNR_MAXFRAMES,
|
AOME_SET_ARNR_MAXFRAMES,
|
||||||
AOME_SET_ARNR_STRENGTH,
|
AOME_SET_ARNR_STRENGTH,
|
||||||
AOME_SET_TUNING,
|
AOME_SET_TUNING,
|
||||||
|
|
|
@ -34,6 +34,9 @@ struct av1_extracfg {
|
||||||
unsigned int static_thresh;
|
unsigned int static_thresh;
|
||||||
unsigned int tile_columns;
|
unsigned int tile_columns;
|
||||||
unsigned int tile_rows;
|
unsigned int tile_rows;
|
||||||
|
#if CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
unsigned int loop_filter_across_tiles_enabled;
|
||||||
|
#endif // CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
unsigned int arnr_max_frames;
|
unsigned int arnr_max_frames;
|
||||||
unsigned int arnr_strength;
|
unsigned int arnr_strength;
|
||||||
unsigned int min_gf_interval;
|
unsigned int min_gf_interval;
|
||||||
|
@ -81,6 +84,9 @@ static struct av1_extracfg default_extra_cfg = {
|
||||||
0, // tile_columns
|
0, // tile_columns
|
||||||
0, // tile_rows
|
0, // tile_rows
|
||||||
#endif // CONFIG_EXT_TILE
|
#endif // CONFIG_EXT_TILE
|
||||||
|
#if CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
0, // loop_filter_across_tiles_enabled
|
||||||
|
#endif // CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
7, // arnr_max_frames
|
7, // arnr_max_frames
|
||||||
5, // arnr_strength
|
5, // arnr_strength
|
||||||
0, // min_gf_interval; 0 -> default decision
|
0, // min_gf_interval; 0 -> default decision
|
||||||
|
@ -250,6 +256,9 @@ static aom_codec_err_t validate_config(aom_codec_alg_priv_t *ctx,
|
||||||
RANGE_CHECK_HI(extra_cfg, tile_columns, 6);
|
RANGE_CHECK_HI(extra_cfg, tile_columns, 6);
|
||||||
RANGE_CHECK_HI(extra_cfg, tile_rows, 2);
|
RANGE_CHECK_HI(extra_cfg, tile_rows, 2);
|
||||||
#endif // CONFIG_EXT_TILE
|
#endif // CONFIG_EXT_TILE
|
||||||
|
#if CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
RANGE_CHECK_HI(extra_cfg, loop_filter_across_tiles_enabled, 1);
|
||||||
|
#endif // CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
RANGE_CHECK_HI(extra_cfg, sharpness, 7);
|
RANGE_CHECK_HI(extra_cfg, sharpness, 7);
|
||||||
RANGE_CHECK_HI(extra_cfg, arnr_max_frames, 15);
|
RANGE_CHECK_HI(extra_cfg, arnr_max_frames, 15);
|
||||||
RANGE_CHECK_HI(extra_cfg, arnr_strength, 6);
|
RANGE_CHECK_HI(extra_cfg, arnr_strength, 6);
|
||||||
|
@ -483,6 +492,11 @@ static aom_codec_err_t set_encoder_config(
|
||||||
oxcf->tile_rows = extra_cfg->tile_rows;
|
oxcf->tile_rows = extra_cfg->tile_rows;
|
||||||
#endif // CONFIG_EXT_TILE
|
#endif // CONFIG_EXT_TILE
|
||||||
|
|
||||||
|
#if CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
oxcf->loop_filter_across_tiles_enabled =
|
||||||
|
extra_cfg->loop_filter_across_tiles_enabled;
|
||||||
|
#endif // CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
|
||||||
oxcf->error_resilient_mode = cfg->g_error_resilient;
|
oxcf->error_resilient_mode = cfg->g_error_resilient;
|
||||||
oxcf->frame_parallel_decoding_mode = extra_cfg->frame_parallel_decoding_mode;
|
oxcf->frame_parallel_decoding_mode = extra_cfg->frame_parallel_decoding_mode;
|
||||||
|
|
||||||
|
@ -645,6 +659,16 @@ static aom_codec_err_t ctrl_set_tile_rows(aom_codec_alg_priv_t *ctx,
|
||||||
return update_extra_cfg(ctx, &extra_cfg);
|
return update_extra_cfg(ctx, &extra_cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
static aom_codec_err_t ctrl_set_tile_loopfilter(aom_codec_alg_priv_t *ctx,
|
||||||
|
va_list args) {
|
||||||
|
struct av1_extracfg extra_cfg = ctx->extra_cfg;
|
||||||
|
extra_cfg.loop_filter_across_tiles_enabled =
|
||||||
|
CAST(AV1E_SET_TILE_LOOPFILTER, args);
|
||||||
|
return update_extra_cfg(ctx, &extra_cfg);
|
||||||
|
}
|
||||||
|
#endif // CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
|
||||||
static aom_codec_err_t ctrl_set_arnr_max_frames(aom_codec_alg_priv_t *ctx,
|
static aom_codec_err_t ctrl_set_arnr_max_frames(aom_codec_alg_priv_t *ctx,
|
||||||
va_list args) {
|
va_list args) {
|
||||||
struct av1_extracfg extra_cfg = ctx->extra_cfg;
|
struct av1_extracfg extra_cfg = ctx->extra_cfg;
|
||||||
|
@ -1329,6 +1353,9 @@ static aom_codec_ctrl_fn_map_t encoder_ctrl_maps[] = {
|
||||||
{ AOME_SET_STATIC_THRESHOLD, ctrl_set_static_thresh },
|
{ AOME_SET_STATIC_THRESHOLD, ctrl_set_static_thresh },
|
||||||
{ AV1E_SET_TILE_COLUMNS, ctrl_set_tile_columns },
|
{ AV1E_SET_TILE_COLUMNS, ctrl_set_tile_columns },
|
||||||
{ AV1E_SET_TILE_ROWS, ctrl_set_tile_rows },
|
{ AV1E_SET_TILE_ROWS, ctrl_set_tile_rows },
|
||||||
|
#if CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
{ AV1E_SET_TILE_LOOPFILTER, ctrl_set_tile_loopfilter },
|
||||||
|
#endif // CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
{ AOME_SET_ARNR_MAXFRAMES, ctrl_set_arnr_max_frames },
|
{ AOME_SET_ARNR_MAXFRAMES, ctrl_set_arnr_max_frames },
|
||||||
{ AOME_SET_ARNR_STRENGTH, ctrl_set_arnr_strength },
|
{ AOME_SET_ARNR_STRENGTH, ctrl_set_arnr_strength },
|
||||||
{ AOME_SET_TUNING, ctrl_set_tuning },
|
{ AOME_SET_TUNING, ctrl_set_tuning },
|
||||||
|
|
|
@ -350,6 +350,9 @@ typedef struct {
|
||||||
int num_proj_ref[2];
|
int num_proj_ref[2];
|
||||||
WarpedMotionParams wm_params[2];
|
WarpedMotionParams wm_params[2];
|
||||||
#endif // CONFIG_WARPED_MOTION
|
#endif // CONFIG_WARPED_MOTION
|
||||||
|
#if CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
TILE_BOUNDARY_TYPE tile_boundary_info;
|
||||||
|
#endif // CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
} MB_MODE_INFO;
|
} MB_MODE_INFO;
|
||||||
|
|
||||||
typedef struct MODE_INFO {
|
typedef struct MODE_INFO {
|
||||||
|
|
|
@ -222,6 +222,15 @@ typedef enum {
|
||||||
TX_TYPES,
|
TX_TYPES,
|
||||||
} TX_TYPE;
|
} TX_TYPE;
|
||||||
|
|
||||||
|
#if CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
typedef enum {
|
||||||
|
TILE_LEFT_BOUNDARY = 1,
|
||||||
|
TILE_RIGHT_BOUNDARY = 2,
|
||||||
|
TILE_ABOVE_BOUNDARY = 4,
|
||||||
|
TILE_BOTTOM_BOUNDARY = 8,
|
||||||
|
} TILE_BOUNDARY_TYPE;
|
||||||
|
#endif // CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
|
||||||
#if CONFIG_EXT_TX
|
#if CONFIG_EXT_TX
|
||||||
#define EXT_TX_SIZES 4 // number of sizes that use extended transforms
|
#define EXT_TX_SIZES 4 // number of sizes that use extended transforms
|
||||||
#define EXT_TX_SETS_INTER 4 // Sets of transform selections for INTER
|
#define EXT_TX_SETS_INTER 4 // Sets of transform selections for INTER
|
||||||
|
|
|
@ -884,6 +884,34 @@ static void build_y_mask(const loop_filter_info_n *const lfi_n,
|
||||||
*int_4x4_y |= (size_mask[block_size] & 0xffffffffffffffffULL) << shift_y;
|
*int_4x4_y |= (size_mask[block_size] & 0xffffffffffffffffULL) << shift_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
// This function update the bit masks for the entire 64x64 region represented
|
||||||
|
// by mi_row, mi_col. In case one of the edge is a tile boundary, loop filtering
|
||||||
|
// for that edge is disabled. This function only check the tile boundary info
|
||||||
|
// for the top left corner mi to determine the boundary information for the
|
||||||
|
// top and left edge of the whole super block
|
||||||
|
static void update_tile_boundary_filter_mask(AV1_COMMON *const cm,
|
||||||
|
const int mi_row, const int mi_col,
|
||||||
|
LOOP_FILTER_MASK *lfm) {
|
||||||
|
int i;
|
||||||
|
MODE_INFO *const mi = cm->mi + mi_row * cm->mi_stride + mi_col;
|
||||||
|
|
||||||
|
if (mi->mbmi.tile_boundary_info & TILE_LEFT_BOUNDARY) {
|
||||||
|
for (i = 0; i <= TX_32X32; i++) {
|
||||||
|
lfm->left_y[i] &= 0xfefefefefefefefeULL;
|
||||||
|
lfm->left_uv[i] &= 0xeeee;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mi->mbmi.tile_boundary_info & TILE_ABOVE_BOUNDARY) {
|
||||||
|
for (i = 0; i <= TX_32X32; i++) {
|
||||||
|
lfm->above_y[i] &= 0xffffffffffffff00ULL;
|
||||||
|
lfm->above_uv[i] &= 0xfff0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
|
||||||
// This function sets up the bit masks for the entire 64x64 region represented
|
// This function sets up the bit masks for the entire 64x64 region represented
|
||||||
// by mi_row, mi_col.
|
// by mi_row, mi_col.
|
||||||
// TODO(JBB): This function only works for yv12.
|
// TODO(JBB): This function only works for yv12.
|
||||||
|
@ -1169,6 +1197,12 @@ void av1_setup_mask(AV1_COMMON *const cm, const int mi_row, const int mi_col,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
if (av1_disable_loopfilter_on_tile_boundary(cm)) {
|
||||||
|
update_tile_boundary_filter_mask(cm, mi_row, mi_col, lfm);
|
||||||
|
}
|
||||||
|
#endif // CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
|
||||||
// Assert if we try to apply 2 different loop filters at the same position.
|
// Assert if we try to apply 2 different loop filters at the same position.
|
||||||
assert(!(lfm->left_y[TX_16X16] & lfm->left_y[TX_8X8]));
|
assert(!(lfm->left_y[TX_16X16] & lfm->left_y[TX_8X8]));
|
||||||
assert(!(lfm->left_y[TX_16X16] & lfm->left_y[TX_4X4]));
|
assert(!(lfm->left_y[TX_16X16] & lfm->left_y[TX_4X4]));
|
||||||
|
@ -1410,8 +1444,15 @@ void av1_filter_block_plane_non420_ver(AV1_COMMON *cm,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable filtering on the leftmost column
|
// Disable filtering on the leftmost column or tile boundary
|
||||||
border_mask = ~(mi_col == 0);
|
border_mask = ~(mi_col == 0);
|
||||||
|
#if CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
if (av1_disable_loopfilter_on_tile_boundary(cm) &&
|
||||||
|
((mib[0]->mbmi.tile_boundary_info & TILE_LEFT_BOUNDARY) != 0)) {
|
||||||
|
border_mask = 0xfffffffe;
|
||||||
|
}
|
||||||
|
#endif // CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
|
||||||
#if CONFIG_AOM_HIGHBITDEPTH
|
#if CONFIG_AOM_HIGHBITDEPTH
|
||||||
if (cm->use_highbitdepth) {
|
if (cm->use_highbitdepth) {
|
||||||
highbd_filter_selectively_vert(
|
highbd_filter_selectively_vert(
|
||||||
|
@ -1602,10 +1643,21 @@ void av1_filter_block_plane_non420_hor(AV1_COMMON *cm,
|
||||||
unsigned int mask_8x8_r;
|
unsigned int mask_8x8_r;
|
||||||
unsigned int mask_4x4_r;
|
unsigned int mask_4x4_r;
|
||||||
|
|
||||||
|
#if CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
// Disable filtering on the abovemost row or tile boundary
|
||||||
|
const MODE_INFO *mi = cm->mi + (mi_row + r) * cm->mi_stride;
|
||||||
|
if ((av1_disable_loopfilter_on_tile_boundary(cm) &&
|
||||||
|
(mi->mbmi.tile_boundary_info & TILE_ABOVE_BOUNDARY)) ||
|
||||||
|
(mi_row + idx_r == 0)) {
|
||||||
|
mask_16x16_r = 0;
|
||||||
|
mask_8x8_r = 0;
|
||||||
|
mask_4x4_r = 0;
|
||||||
|
#else
|
||||||
if (mi_row + idx_r == 0) {
|
if (mi_row + idx_r == 0) {
|
||||||
mask_16x16_r = 0;
|
mask_16x16_r = 0;
|
||||||
mask_8x8_r = 0;
|
mask_8x8_r = 0;
|
||||||
mask_4x4_r = 0;
|
mask_4x4_r = 0;
|
||||||
|
#endif // CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
} else {
|
} else {
|
||||||
mask_16x16_r = mask_16x16[r];
|
mask_16x16_r = mask_16x16[r];
|
||||||
mask_8x8_r = mask_8x8[r];
|
mask_8x8_r = mask_8x8[r];
|
||||||
|
|
|
@ -363,6 +363,10 @@ typedef struct AV1Common {
|
||||||
int tile_cols, tile_rows;
|
int tile_cols, tile_rows;
|
||||||
int tile_width, tile_height; // In MI units
|
int tile_width, tile_height; // In MI units
|
||||||
|
|
||||||
|
#if CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
int loop_filter_across_tiles_enabled;
|
||||||
|
#endif // CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
|
||||||
int byte_alignment;
|
int byte_alignment;
|
||||||
int skip_loop_filter;
|
int skip_loop_filter;
|
||||||
|
|
||||||
|
|
|
@ -59,3 +59,29 @@ void av1_get_tile_n_bits(const int mi_cols, int *min_log2_tile_cols,
|
||||||
assert(*min_log2_tile_cols <= *max_log2_tile_cols);
|
assert(*min_log2_tile_cols <= *max_log2_tile_cols);
|
||||||
}
|
}
|
||||||
#endif // !CONFIG_EXT_TILE
|
#endif // !CONFIG_EXT_TILE
|
||||||
|
|
||||||
|
#if CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
void av1_update_tile_boundary_info(const struct AV1Common *cm,
|
||||||
|
const TileInfo *const tile_info, int mi_row,
|
||||||
|
int mi_col) {
|
||||||
|
int row, col;
|
||||||
|
for (row = mi_row; row < (mi_row + cm->mib_size); row++)
|
||||||
|
for (col = mi_col; col < (mi_col + cm->mib_size); col++) {
|
||||||
|
MODE_INFO *const mi = cm->mi + row * cm->mi_stride + col;
|
||||||
|
mi->mbmi.tile_boundary_info = 0;
|
||||||
|
if (row == tile_info->mi_row_start)
|
||||||
|
mi->mbmi.tile_boundary_info |= TILE_ABOVE_BOUNDARY;
|
||||||
|
if (col == tile_info->mi_col_start)
|
||||||
|
mi->mbmi.tile_boundary_info |= TILE_LEFT_BOUNDARY;
|
||||||
|
if ((row + 1) >= tile_info->mi_row_end)
|
||||||
|
mi->mbmi.tile_boundary_info |= TILE_BOTTOM_BOUNDARY;
|
||||||
|
if ((col + 1) >= tile_info->mi_col_end)
|
||||||
|
mi->mbmi.tile_boundary_info |= TILE_RIGHT_BOUNDARY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int av1_disable_loopfilter_on_tile_boundary(const struct AV1Common *cm) {
|
||||||
|
return (!cm->loop_filter_across_tiles_enabled &&
|
||||||
|
(cm->tile_cols * cm->tile_rows > 1));
|
||||||
|
}
|
||||||
|
#endif // CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
|
|
@ -38,6 +38,13 @@ void av1_tile_set_col(TileInfo *tile, const struct AV1Common *cm, int col);
|
||||||
void av1_get_tile_n_bits(const int mi_cols, int *min_log2_tile_cols,
|
void av1_get_tile_n_bits(const int mi_cols, int *min_log2_tile_cols,
|
||||||
int *max_log2_tile_cols);
|
int *max_log2_tile_cols);
|
||||||
|
|
||||||
|
#if CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
void av1_update_tile_boundary_info(const struct AV1Common *cm,
|
||||||
|
const TileInfo *const tile_info, int mi_row,
|
||||||
|
int mi_col);
|
||||||
|
int av1_disable_loopfilter_on_tile_boundary(const struct AV1Common *cm);
|
||||||
|
#endif // CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2764,6 +2764,10 @@ static void read_tile_info(AV1Decoder *const pbi,
|
||||||
cm->tile_height = aom_rb_read_literal(rb, 6) + 1;
|
cm->tile_height = aom_rb_read_literal(rb, 6) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
cm->loop_filter_across_tiles_enabled = aom_rb_read_bit(rb);
|
||||||
|
#endif // CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
|
||||||
cm->tile_width <<= cm->mib_size_log2;
|
cm->tile_width <<= cm->mib_size_log2;
|
||||||
cm->tile_height <<= cm->mib_size_log2;
|
cm->tile_height <<= cm->mib_size_log2;
|
||||||
|
|
||||||
|
@ -2799,6 +2803,10 @@ static void read_tile_info(AV1Decoder *const pbi,
|
||||||
cm->log2_tile_rows = aom_rb_read_bit(rb);
|
cm->log2_tile_rows = aom_rb_read_bit(rb);
|
||||||
if (cm->log2_tile_rows) cm->log2_tile_rows += aom_rb_read_bit(rb);
|
if (cm->log2_tile_rows) cm->log2_tile_rows += aom_rb_read_bit(rb);
|
||||||
|
|
||||||
|
#if CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
cm->loop_filter_across_tiles_enabled = aom_rb_read_bit(rb);
|
||||||
|
#endif // CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
|
||||||
cm->tile_cols = 1 << cm->log2_tile_cols;
|
cm->tile_cols = 1 << cm->log2_tile_cols;
|
||||||
cm->tile_rows = 1 << cm->log2_tile_rows;
|
cm->tile_rows = 1 << cm->log2_tile_rows;
|
||||||
|
|
||||||
|
@ -3264,6 +3272,12 @@ static const uint8_t *decode_tiles(AV1Decoder *pbi, const uint8_t *data,
|
||||||
|
|
||||||
for (mi_col = tile_info.mi_col_start; mi_col < tile_info.mi_col_end;
|
for (mi_col = tile_info.mi_col_start; mi_col < tile_info.mi_col_end;
|
||||||
mi_col += cm->mib_size) {
|
mi_col += cm->mib_size) {
|
||||||
|
#if CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
if (av1_disable_loopfilter_on_tile_boundary(cm)) {
|
||||||
|
av1_update_tile_boundary_info(cm, &tile_info, mi_row, mi_col);
|
||||||
|
}
|
||||||
|
#endif // CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
|
||||||
decode_partition(pbi, &td->xd,
|
decode_partition(pbi, &td->xd,
|
||||||
#if CONFIG_SUPERTX
|
#if CONFIG_SUPERTX
|
||||||
0,
|
0,
|
||||||
|
|
|
@ -3382,6 +3382,10 @@ static void write_tile_info(const AV1_COMMON *const cm,
|
||||||
aom_wb_write_bit(wb, cm->log2_tile_rows != 0);
|
aom_wb_write_bit(wb, cm->log2_tile_rows != 0);
|
||||||
if (cm->log2_tile_rows != 0) aom_wb_write_bit(wb, cm->log2_tile_rows != 1);
|
if (cm->log2_tile_rows != 0) aom_wb_write_bit(wb, cm->log2_tile_rows != 1);
|
||||||
#endif // CONFIG_EXT_TILE
|
#endif // CONFIG_EXT_TILE
|
||||||
|
|
||||||
|
#if CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
aom_wb_write_bit(wb, cm->loop_filter_across_tiles_enabled);
|
||||||
|
#endif // CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_refresh_mask(AV1_COMP *cpi) {
|
static int get_refresh_mask(AV1_COMP *cpi) {
|
||||||
|
|
|
@ -4380,6 +4380,11 @@ static void encode_rd_sb_row(AV1_COMP *cpi, ThreadData *td,
|
||||||
MODE_INFO **mi = cm->mi_grid_visible + idx_str;
|
MODE_INFO **mi = cm->mi_grid_visible + idx_str;
|
||||||
PC_TREE *const pc_root = td->pc_root[cm->mib_size_log2 - MIN_MIB_SIZE_LOG2];
|
PC_TREE *const pc_root = td->pc_root[cm->mib_size_log2 - MIN_MIB_SIZE_LOG2];
|
||||||
|
|
||||||
|
#if CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
if (av1_disable_loopfilter_on_tile_boundary(cm)) {
|
||||||
|
av1_update_tile_boundary_info(cm, tile_info, mi_row, mi_col);
|
||||||
|
}
|
||||||
|
#endif // CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
if (sf->adaptive_pred_interp_filter) {
|
if (sf->adaptive_pred_interp_filter) {
|
||||||
for (i = 0; i < leaf_nodes; ++i)
|
for (i = 0; i < leaf_nodes; ++i)
|
||||||
td->leaf_tree[i].pred_interp_filter = SWITCHABLE;
|
td->leaf_tree[i].pred_interp_filter = SWITCHABLE;
|
||||||
|
|
|
@ -863,6 +863,11 @@ static void set_tile_info(AV1_COMP *cpi) {
|
||||||
cm->tile_width = ALIGN_POWER_OF_TWO(cm->tile_width, MAX_MIB_SIZE_LOG2);
|
cm->tile_width = ALIGN_POWER_OF_TWO(cm->tile_width, MAX_MIB_SIZE_LOG2);
|
||||||
cm->tile_height = ALIGN_POWER_OF_TWO(cm->tile_height, MAX_MIB_SIZE_LOG2);
|
cm->tile_height = ALIGN_POWER_OF_TWO(cm->tile_height, MAX_MIB_SIZE_LOG2);
|
||||||
#endif // CONFIG_EXT_TILE
|
#endif // CONFIG_EXT_TILE
|
||||||
|
|
||||||
|
#if CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
cm->loop_filter_across_tiles_enabled =
|
||||||
|
cpi->oxcf.loop_filter_across_tiles_enabled;
|
||||||
|
#endif // CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_frame_size(AV1_COMP *cpi) {
|
static void update_frame_size(AV1_COMP *cpi) {
|
||||||
|
|
|
@ -238,6 +238,9 @@ typedef struct AV1EncoderConfig {
|
||||||
|
|
||||||
int tile_columns;
|
int tile_columns;
|
||||||
int tile_rows;
|
int tile_rows;
|
||||||
|
#if CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
int loop_filter_across_tiles_enabled;
|
||||||
|
#endif // CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
|
||||||
int max_threads;
|
int max_threads;
|
||||||
|
|
||||||
|
|
|
@ -288,6 +288,7 @@ EXPERIMENT_LIST="
|
||||||
adapt_scan
|
adapt_scan
|
||||||
filter_7bit
|
filter_7bit
|
||||||
parallel_deblocking
|
parallel_deblocking
|
||||||
|
deblocking_across_tiles
|
||||||
tile_groups
|
tile_groups
|
||||||
ec_adapt
|
ec_adapt
|
||||||
rd_debug
|
rd_debug
|
||||||
|
|
|
@ -83,6 +83,9 @@ class AVxEncoderThreadTest
|
||||||
encoder->Control(AV1E_SET_TILE_COLUMNS, 2);
|
encoder->Control(AV1E_SET_TILE_COLUMNS, 2);
|
||||||
encoder->Control(AV1E_SET_TILE_ROWS, 0);
|
encoder->Control(AV1E_SET_TILE_ROWS, 0);
|
||||||
#endif // CONFIG_AV1 && CONFIG_EXT_TILE
|
#endif // CONFIG_AV1 && CONFIG_EXT_TILE
|
||||||
|
#if CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
encoder->Control(AV1E_SET_TILE_LOOPFILTER, 0);
|
||||||
|
#endif // CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
encoder->Control(AOME_SET_CPUUSED, set_cpu_used_);
|
encoder->Control(AOME_SET_CPUUSED, set_cpu_used_);
|
||||||
if (encoding_mode_ != ::libaom_test::kRealTime) {
|
if (encoding_mode_ != ::libaom_test::kRealTime) {
|
||||||
encoder->Control(AOME_SET_ENABLEAUTOALTREF, 1);
|
encoder->Control(AOME_SET_ENABLEAUTOALTREF, 1);
|
||||||
|
|
|
@ -52,6 +52,9 @@ class SuperframeTest
|
||||||
encoder->Control(AOME_SET_CPUUSED, 2);
|
encoder->Control(AOME_SET_CPUUSED, 2);
|
||||||
encoder->Control(AV1E_SET_TILE_COLUMNS, n_tile_cols_);
|
encoder->Control(AV1E_SET_TILE_COLUMNS, n_tile_cols_);
|
||||||
encoder->Control(AV1E_SET_TILE_ROWS, n_tile_rows_);
|
encoder->Control(AV1E_SET_TILE_ROWS, n_tile_rows_);
|
||||||
|
#if CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
encoder->Control(AV1E_SET_TILE_LOOPFILTER, 0);
|
||||||
|
#endif // CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,9 @@ class TileIndependenceTest
|
||||||
if (video->frame() == 1) {
|
if (video->frame() == 1) {
|
||||||
encoder->Control(AV1E_SET_TILE_COLUMNS, n_tile_cols_);
|
encoder->Control(AV1E_SET_TILE_COLUMNS, n_tile_cols_);
|
||||||
encoder->Control(AV1E_SET_TILE_ROWS, n_tile_rows_);
|
encoder->Control(AV1E_SET_TILE_ROWS, n_tile_rows_);
|
||||||
|
#if CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
|
encoder->Control(AV1E_SET_TILE_LOOPFILTER, 0);
|
||||||
|
#endif // CONFIG_DEBLOCKING_ACROSS_TILES
|
||||||
SetCpuUsed(encoder);
|
SetCpuUsed(encoder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче