From 73126c08c7da6a4da9e394b60ecb3aedbb47892f Mon Sep 17 00:00:00 2001 From: Fangwen Fu Date: Wed, 8 Feb 2017 22:37:47 -0800 Subject: [PATCH] dependent tiles togeter with tile groups Change-Id: I378eb5b2c03a4c30d261128bcf9ef00ea987ed40 --- av1/common/mvref_common.h | 6 ++++++ av1/common/onyxc_int.h | 8 ++++++++ av1/common/tile_common.c | 27 +++++++++++++++++++++++++++ av1/common/tile_common.h | 6 +++++- av1/decoder/decodeframe.c | 22 ++++++++++++++++++++++ av1/encoder/bitstream.c | 8 ++++++++ av1/encoder/encodeframe.c | 5 +++++ av1/encoder/encoder.c | 28 +++++++++++++++++++++++++++- av1/encoder/segmentation.c | 3 +++ 9 files changed, 111 insertions(+), 2 deletions(-) diff --git a/av1/common/mvref_common.h b/av1/common/mvref_common.h index f5a391939..d91efb2c3 100644 --- a/av1/common/mvref_common.h +++ b/av1/common/mvref_common.h @@ -349,7 +349,11 @@ static INLINE int_mv scale_mv(const MB_MODE_INFO *mbmi, int ref, static INLINE int is_inside(const TileInfo *const tile, int mi_col, int mi_row, int mi_rows, int dependent_horz_tile_flag, const POSITION *mi_pos) { +#if CONFIG_TILE_GROUPS + if (dependent_horz_tile_flag && !tile->tg_horz_boundary) { +#else if (dependent_horz_tile_flag) { +#endif return !(mi_row + mi_pos->row < 0 || mi_col + mi_pos->col < tile->mi_col_start || mi_row + mi_pos->row >= mi_rows || @@ -410,6 +414,7 @@ static INLINE int8_t av1_ref_frame_type(const MV_REFERENCE_FRAME *const rf) { return rf[0]; } +// clang-format off static MV_REFERENCE_FRAME ref_frame_map[COMP_REFS][2] = { #if CONFIG_EXT_REFS { LAST_FRAME, BWDREF_FRAME }, { LAST2_FRAME, BWDREF_FRAME }, @@ -421,6 +426,7 @@ static MV_REFERENCE_FRAME ref_frame_map[COMP_REFS][2] = { { LAST_FRAME, ALTREF_FRAME }, { GOLDEN_FRAME, ALTREF_FRAME } #endif }; +// clang-format on static INLINE void av1_set_ref_frame(MV_REFERENCE_FRAME *rf, int8_t ref_frame_type) { diff --git a/av1/common/onyxc_int.h b/av1/common/onyxc_int.h index 772c379b1..f0d6dab84 100644 --- a/av1/common/onyxc_int.h +++ b/av1/common/onyxc_int.h @@ -374,6 +374,10 @@ typedef struct AV1Common { #if CONFIG_DEPENDENT_HORZTILES int dependent_horz_tiles; +#if CONFIG_TILE_GROUPS + int tile_group_start_row[MAX_TILE_ROWS][MAX_TILE_COLS]; + int tile_group_start_col[MAX_TILE_ROWS][MAX_TILE_COLS]; +#endif #endif #if CONFIG_LOOPFILTERING_ACROSS_TILES int loop_filter_across_tiles_enabled; @@ -603,7 +607,11 @@ static INLINE void set_mi_row_col(MACROBLOCKD *xd, const TileInfo *const tile, xd->mb_to_right_edge = ((mi_cols - bw - mi_col) * MI_SIZE) * 8; if (dependent_horz_tile_flag) { +#if CONFIG_TILE_GROUPS + xd->up_available = (mi_row > tile->mi_row_start) || !tile->tg_horz_boundary; +#else xd->up_available = (mi_row > 0); +#endif } else { // Are edges available for intra prediction? xd->up_available = (mi_row > tile->mi_row_start); diff --git a/av1/common/tile_common.c b/av1/common/tile_common.c index 76a7e9da0..f61acab32 100644 --- a/av1/common/tile_common.c +++ b/av1/common/tile_common.c @@ -23,9 +23,27 @@ void av1_tile_set_col(TileInfo *tile, const AV1_COMMON *cm, int col) { tile->mi_col_end = AOMMIN(tile->mi_col_start + cm->tile_width, cm->mi_cols); } +#if CONFIG_DEPENDENT_HORZTILES && CONFIG_TILE_GROUPS +void av1_tile_set_tg_boundary(TileInfo *tile, const AV1_COMMON *const cm, + int row, int col) { + if (row < cm->tile_rows - 1) { + tile->tg_horz_boundary = + col >= cm->tile_group_start_col[row][col] + ? (row == cm->tile_group_start_row[row][col] ? 1 : 0) + : (row == cm->tile_group_start_row[row + 1][col] ? 1 : 0); + } else { + assert(col >= cm->tile_group_start_col[row][col]); + tile->tg_horz_boundary = + (row == cm->tile_group_start_row[row][col] ? 1 : 0); + } +} +#endif void av1_tile_init(TileInfo *tile, const AV1_COMMON *cm, int row, int col) { av1_tile_set_row(tile, cm, row); av1_tile_set_col(tile, cm, col); +#if CONFIG_DEPENDENT_HORZTILES && CONFIG_TILE_GROUPS + av1_tile_set_tg_boundary(tile, cm, row, col); +#endif } #if !CONFIG_EXT_TILE @@ -69,7 +87,16 @@ void av1_update_boundary_info(const struct AV1Common *cm, MODE_INFO *const mi = cm->mi + row * cm->mi_stride + col; mi->mbmi.boundary_info = 0; if (cm->tile_cols * cm->tile_rows > 1) { +#if CONFIG_DEPENDENT_HORZTILES + if (row == tile_info->mi_row_start && + (!cm->dependent_horz_tiles || tile_info->tg_horz_boundary)) +#if CONFIG_TILE_GROUPS +#else + if (row == tile_info->mi_row_start && !cm->dependent_horz_tiles) +#endif // CONFIG_TILE_GROUPS +#else if (row == tile_info->mi_row_start) +#endif // CONFIG_DEPENDENT_HORZTILES mi->mbmi.boundary_info |= TILE_ABOVE_BOUNDARY; if (col == tile_info->mi_col_start) mi->mbmi.boundary_info |= TILE_LEFT_BOUNDARY; diff --git a/av1/common/tile_common.h b/av1/common/tile_common.h index 65ad323b1..19daac2a5 100644 --- a/av1/common/tile_common.h +++ b/av1/common/tile_common.h @@ -25,6 +25,7 @@ struct AV1Common; typedef struct TileInfo { int mi_row_start, mi_row_end; int mi_col_start, mi_col_end; + int tg_horz_boundary; } TileInfo; // initializes 'tile->mi_(row|col)_(start|end)' for (row, col) based on @@ -34,7 +35,10 @@ void av1_tile_init(TileInfo *tile, const struct AV1Common *cm, int row, void av1_tile_set_row(TileInfo *tile, const struct AV1Common *cm, int row); void av1_tile_set_col(TileInfo *tile, const struct AV1Common *cm, int col); - +#if CONFIG_DEPENDENT_HORZTILES && CONFIG_TILE_GROUPS +void av1_tile_set_tg_boundary(TileInfo *tile, const struct AV1Common *cm, + int row, int col); +#endif void av1_get_tile_n_bits(const int mi_cols, int *min_log2_tile_cols, int *max_log2_tile_cols); diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c index 6a42c3eff..0a33c4884 100644 --- a/av1/decoder/decodeframe.c +++ b/av1/decoder/decodeframe.c @@ -3349,6 +3349,10 @@ static void get_tile_buffers( const int num_bits = OD_ILOG(num_tiles) - 1; const int hdr_size = pbi->uncomp_hdr_size + pbi->first_partition_size; const int tg_size_bit_offset = pbi->tg_size_bit_offset; +#if CONFIG_DEPENDENT_HORZTILES + int tile_group_start_col = 0; + int tile_group_start_row = 0; +#endif for (r = 0; r < tile_rows; ++r) { for (c = 0; c < tile_cols; ++c, ++tc) { @@ -3363,6 +3367,10 @@ static void get_tile_buffers( if (num_tiles) { pbi->tg_start = aom_rb_read_literal(&rb_tg_hdr, num_bits); pbi->tg_size = 1 + aom_rb_read_literal(&rb_tg_hdr, num_bits); +#if CONFIG_DEPENDENT_HORZTILES + tile_group_start_row = r; + tile_group_start_col = c; +#endif } } first_tile_in_tg += tc == first_tile_in_tg ? pbi->tg_size : 0; @@ -3370,6 +3378,10 @@ static void get_tile_buffers( get_tile_buffer(data_end, pbi->tile_size_bytes, is_last, &pbi->common.error, &data, pbi->decrypt_cb, pbi->decrypt_state, buf); +#if CONFIG_DEPENDENT_HORZTILES + cm->tile_group_start_row[r][c] = tile_group_start_row; + cm->tile_group_start_col[r][c] = tile_group_start_col; +#endif } } #else @@ -3580,7 +3592,13 @@ static const uint8_t *decode_tiles(AV1Decoder *pbi, const uint8_t *data, av1_tile_set_col(&tile_info, cm, col); #if CONFIG_DEPENDENT_HORZTILES +#if CONFIG_TILE_GROUPS + av1_tile_set_tg_boundary(&tile_info, cm, tile_row, tile_col); + if (!cm->dependent_horz_tiles || tile_row == 0 || + tile_info.tg_horz_boundary) { +#else if (!cm->dependent_horz_tiles || tile_row == 0) { +#endif av1_zero_above_context(cm, tile_info.mi_col_start, tile_info.mi_col_end); } @@ -3732,7 +3750,11 @@ static int tile_worker_hook(TileWorkerData *const tile_data, tile_data->error_info.setjmp = 1; tile_data->xd.error_info = &tile_data->error_info; #if CONFIG_DEPENDENT_HORZTILES +#if CONFIG_TILE_GROUPS + if (!cm->dependent_horz_tiles || tile->tg_horz_boundary) { +#else if (!cm->dependent_horz_tiles) { +#endif av1_zero_above_context(&pbi->common, tile->mi_col_start, tile->mi_col_end); } #else diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c index 6749a73b6..c39da5bde 100644 --- a/av1/encoder/bitstream.c +++ b/av1/encoder/bitstream.c @@ -2887,7 +2887,12 @@ static void write_modes(AV1_COMP *const cpi, const TileInfo *const tile, int mi_row, mi_col; #if CONFIG_DEPENDENT_HORZTILES +#if CONFIG_TILE_GROUPS + if (!cm->dependent_horz_tiles || mi_row_start == 0 || + tile->tg_horz_boundary) { +#else if (!cm->dependent_horz_tiles || mi_row_start == 0) { +#endif av1_zero_above_context(cm, mi_col_start, mi_col_end); } #else @@ -4179,6 +4184,9 @@ static uint32_t write_tiles(AV1_COMP *const cpi, uint8_t *const dst, #endif av1_tile_set_col(&tile_info, cm, tile_col); +#if CONFIG_DEPENDENT_HORZTILES && CONFIG_TILE_GROUPS + av1_tile_set_tg_boundary(&tile_info, cm, tile_row, tile_col); +#endif buf->data = dst + total_size; // The last tile does not have a header. diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c index eb5d5ee87..174e79639 100644 --- a/av1/encoder/encodeframe.c +++ b/av1/encoder/encodeframe.c @@ -4849,7 +4849,12 @@ void av1_encode_tile(AV1_COMP *cpi, ThreadData *td, int tile_row, od_adapt_ctx *adapt; #endif #if CONFIG_DEPENDENT_HORZTILES +#if CONFIG_TILE_GROUPS + if ((!cm->dependent_horz_tiles) || (tile_row == 0) || + tile_info->tg_horz_boundary) { +#else if ((!cm->dependent_horz_tiles) || (tile_row == 0)) { +#endif av1_zero_above_context(cm, tile_info->mi_col_start, tile_info->mi_col_end); } #else diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c index 3ebddaba0..b3bb62b6d 100644 --- a/av1/encoder/encoder.c +++ b/av1/encoder/encoder.c @@ -821,7 +821,10 @@ void av1_new_framerate(AV1_COMP *cpi, double framerate) { static void set_tile_info(AV1_COMP *cpi) { AV1_COMMON *const cm = &cpi->common; - +#if CONFIG_TILE_GROUPS && CONFIG_DEPENDENT_HORZTILES + int tile_row, tile_col, num_tiles_in_tg; + int tg_row_start, tg_col_start; +#endif #if CONFIG_EXT_TILE #if CONFIG_EXT_PARTITION if (cpi->oxcf.superblock_size != AOM_SUPERBLOCK_SIZE_64X64) { @@ -878,6 +881,29 @@ static void set_tile_info(AV1_COMP *cpi) { #if CONFIG_DEPENDENT_HORZTILES cm->dependent_horz_tiles = cpi->oxcf.dependent_horz_tiles; if (cm->log2_tile_rows == 0) cm->dependent_horz_tiles = 0; +#if CONFIG_TILE_GROUPS + if (cpi->oxcf.mtu == 0) { + cm->num_tg = cpi->oxcf.num_tile_groups; + } else { + // Use a default value for the purposes of weighting costs in probability + // updates + cm->num_tg = DEFAULT_MAX_NUM_TG; + } + num_tiles_in_tg = + (cm->tile_cols * cm->tile_rows + cm->num_tg - 1) / cm->num_tg; + tg_row_start = 0; + tg_col_start = 0; + for (tile_row = 0; tile_row < cm->tile_rows; ++tile_row) { + for (tile_col = 0; tile_col < cm->tile_cols; ++tile_col) { + if ((tile_row * cm->tile_cols + tile_col) % num_tiles_in_tg == 0) { + tg_row_start = tile_row; + tg_col_start = tile_col; + } + cm->tile_group_start_row[tile_row][tile_col] = tg_row_start; + cm->tile_group_start_col[tile_row][tile_col] = tg_col_start; + } + } +#endif #endif #if CONFIG_LOOPFILTERING_ACROSS_TILES diff --git a/av1/encoder/segmentation.c b/av1/encoder/segmentation.c index 1b28f41a9..c83522ec8 100644 --- a/av1/encoder/segmentation.c +++ b/av1/encoder/segmentation.c @@ -328,6 +328,9 @@ void av1_choose_segmap_coding_method(AV1_COMMON *cm, MACROBLOCKD *xd) { for (tile_col = 0; tile_col < cm->tile_cols; tile_col++) { MODE_INFO **mi_ptr; av1_tile_set_col(&tile_info, cm, tile_col); +#if CONFIG_TILE_GROUPS && CONFIG_DEPENDENT_HORZTILES + av1_tile_set_tg_boundary(&tile_info, cm, tile_row, tile_col); +#endif mi_ptr = cm->mi_grid_visible + tile_info.mi_row_start * cm->mi_stride + tile_info.mi_col_start; for (mi_row = tile_info.mi_row_start; mi_row < tile_info.mi_row_end; -- GitLab