add horizontal tile dependence support Change-Id: I1050b69045407381d4626b65a0bf6f35957a66f4
diff --git a/aom/aomcx.h b/aom/aomcx.h index ef9d6ca..9003dca 100644 --- a/aom/aomcx.h +++ b/aom/aomcx.h
@@ -286,7 +286,6 @@ * By default, the value is 0, i.e. one single row tile for entire image. */ AV1E_SET_TILE_ROWS, - #if CONFIG_LOOPFILTERING_ACROSS_TILES /*!\brief Codec control function to set loop_filter_across_tiles_enabled. * @@ -482,6 +481,20 @@ */ AV1E_SET_MTU, + /*!\brief Codec control function to set dependent_horz_tiles. + * + * In encoding and decoding, AV1 allows enabling dependent horizontal tile + * The parameter for this control describes the value of this flag, + * which has a valid range [0, 1]: + * 0 = disable dependent horizontal tile + * 1 = enable dependent horizontal tile, + * + * By default, the value is 0, i.e. disable dependent horizontal tile. + * + * Supported in codecs: AV1 + */ + AV1E_SET_TILE_DEPENDENT_ROWS, + /*!\brief Codec control function to set the number of symbols in an ANS data * window. * @@ -606,6 +619,12 @@ #define AOM_CTRL_AV1E_SET_TILE_COLUMNS AOM_CTRL_USE_TYPE(AV1E_SET_TILE_ROWS, int) #define AOM_CTRL_AV1E_SET_TILE_ROWS + +#if CONFIG_DEPENDENT_HORZTILES +AOM_CTRL_USE_TYPE(AV1E_SET_TILE_DEPENDENT_ROWS, int) +#define AOM_CTRL_AV1E_SET_TILE_DEPENDENT_ROWS +#endif + #if CONFIG_LOOPFILTERING_ACROSS_TILES AOM_CTRL_USE_TYPE(AV1E_SET_TILE_LOOPFILTER, int) #define AOM_CTRL_AV1E_SET_TILE_LOOPFILTER
diff --git a/aomenc.c b/aomenc.c index bbbf5c1..e667348 100644 --- a/aomenc.c +++ b/aomenc.c
@@ -376,6 +376,10 @@ static const arg_def_t tile_rows = ARG_DEF(NULL, "tile-rows", 1, "Number of tile rows to use, log2 (set to 0 while threads > 1)"); +#if CONFIG_DEPENDENT_HORZTILES +static const arg_def_t tile_dependent_rows = + ARG_DEF(NULL, "tile-dependent-rows", 1, "Enable dependent Tile rows"); +#endif #if CONFIG_LOOPFILTERING_ACROSS_TILES static const arg_def_t tile_loopfilter = ARG_DEF( NULL, "tile-loopfilter", 1, "Enable loop filter across tile boundary"); @@ -476,6 +480,9 @@ &static_thresh, &tile_cols, &tile_rows, +#if CONFIG_DEPENDENT_HORZTILES + &tile_dependent_rows, +#endif #if CONFIG_LOOPFILTERING_ACROSS_TILES &tile_loopfilter, #endif // CONFIG_LOOPFILTERING_ACROSS_TILES @@ -521,6 +528,9 @@ AOME_SET_STATIC_THRESHOLD, AV1E_SET_TILE_COLUMNS, AV1E_SET_TILE_ROWS, +#if CONFIG_DEPENDENT_HORZTILES + AV1E_SET_TILE_DEPENDENT_ROWS, +#endif #if CONFIG_LOOPFILTERING_ACROSS_TILES AV1E_SET_TILE_LOOPFILTER, #endif // CONFIG_LOOPFILTERING_ACROSS_TILES
diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c index a8f975b..ee5e2c5 100644 --- a/av1/av1_cx_iface.c +++ b/av1/av1_cx_iface.c
@@ -34,6 +34,9 @@ unsigned int static_thresh; unsigned int tile_columns; unsigned int tile_rows; +#if CONFIG_DEPENDENT_HORZTILES + unsigned int dependent_horz_tiles; +#endif #if CONFIG_LOOPFILTERING_ACROSS_TILES unsigned int loop_filter_across_tiles_enabled; #endif // CONFIG_LOOPFILTERING_ACROSS_TILES @@ -90,6 +93,9 @@ 0, // tile_columns 0, // tile_rows #endif // CONFIG_EXT_TILE +#if CONFIG_DEPENDENT_HORZTILES + 0, // Depdendent Horizontal tiles +#endif #if CONFIG_LOOPFILTERING_ACROSS_TILES 1, // loop_filter_across_tiles_enabled #endif // CONFIG_LOOPFILTERING_ACROSS_TILES @@ -268,6 +274,9 @@ RANGE_CHECK_HI(extra_cfg, tile_columns, 6); RANGE_CHECK_HI(extra_cfg, tile_rows, 2); #endif // CONFIG_EXT_TILE +#if CONFIG_DEPENDENT_HORZTILES + RANGE_CHECK_HI(extra_cfg, dependent_horz_tiles, 1); +#endif #if CONFIG_LOOPFILTERING_ACROSS_TILES RANGE_CHECK_HI(extra_cfg, loop_filter_across_tiles_enabled, 1); #endif // CONFIG_LOOPFILTERING_ACROSS_TILES @@ -512,12 +521,13 @@ oxcf->tile_columns = extra_cfg->tile_columns; oxcf->tile_rows = extra_cfg->tile_rows; #endif // CONFIG_EXT_TILE - +#if CONFIG_DEPENDENT_HORZTILES + oxcf->dependent_horz_tiles = extra_cfg->dependent_horz_tiles; +#endif #if CONFIG_LOOPFILTERING_ACROSS_TILES oxcf->loop_filter_across_tiles_enabled = extra_cfg->loop_filter_across_tiles_enabled; #endif // CONFIG_LOOPFILTERING_ACROSS_TILES - oxcf->error_resilient_mode = cfg->g_error_resilient; oxcf->frame_parallel_decoding_mode = extra_cfg->frame_parallel_decoding_mode; @@ -679,7 +689,14 @@ extra_cfg.tile_rows = CAST(AV1E_SET_TILE_ROWS, args); return update_extra_cfg(ctx, &extra_cfg); } - +#if CONFIG_DEPENDENT_HORZTILES +static aom_codec_err_t ctrl_set_tile_dependent_rows(aom_codec_alg_priv_t *ctx, + va_list args) { + struct av1_extracfg extra_cfg = ctx->extra_cfg; + extra_cfg.dependent_horz_tiles = CAST(AV1E_SET_TILE_DEPENDENT_ROWS, args); + return update_extra_cfg(ctx, &extra_cfg); +} +#endif #if CONFIG_LOOPFILTERING_ACROSS_TILES static aom_codec_err_t ctrl_set_tile_loopfilter(aom_codec_alg_priv_t *ctx, va_list args) { @@ -1390,6 +1407,9 @@ { AOME_SET_STATIC_THRESHOLD, ctrl_set_static_thresh }, { AV1E_SET_TILE_COLUMNS, ctrl_set_tile_columns }, { AV1E_SET_TILE_ROWS, ctrl_set_tile_rows }, +#if CONFIG_DEPENDENT_HORZTILES + { AV1E_SET_TILE_DEPENDENT_ROWS, ctrl_set_tile_dependent_rows }, +#endif #if CONFIG_LOOPFILTERING_ACROSS_TILES { AV1E_SET_TILE_LOOPFILTER, ctrl_set_tile_loopfilter }, #endif // CONFIG_LOOPFILTERING_ACROSS_TILES
diff --git a/av1/common/mvref_common.c b/av1/common/mvref_common.c index 297cba0..f83f98d 100644 --- a/av1/common/mvref_common.c +++ b/av1/common/mvref_common.c
@@ -191,7 +191,12 @@ mi_pos.row = row_offset; mi_pos.col = i; +#if CONFIG_DEPENDENT_HORZTILES + if (is_inside(tile, mi_col, mi_row, cm->mi_rows, cm->dependent_horz_tiles, + &mi_pos)) { +#else if (is_inside(tile, mi_col, mi_row, &mi_pos)) { +#endif const MODE_INFO *const candidate_mi = xd->mi[mi_pos.row * xd->mi_stride + mi_pos.col]; const MB_MODE_INFO *const candidate = &candidate_mi->mbmi; @@ -238,7 +243,12 @@ mi_pos.row = i; mi_pos.col = col_offset; +#if CONFIG_DEPENDENT_HORZTILES + if (is_inside(tile, mi_col, mi_row, cm->mi_rows, cm->dependent_horz_tiles, + &mi_pos)) { +#else if (is_inside(tile, mi_col, mi_row, &mi_pos)) { +#endif const MODE_INFO *const candidate_mi = xd->mi[mi_pos.row * xd->mi_stride + mi_pos.col]; const MB_MODE_INFO *const candidate = &candidate_mi->mbmi; @@ -271,8 +281,14 @@ mi_pos.row = row_offset; mi_pos.col = col_offset; +#if CONFIG_DEPENDENT_HORZTILES + if (is_inside(tile, mi_col, mi_row, cm->mi_rows, cm->dependent_horz_tiles, + &mi_pos) && + *refmv_count < MAX_REF_MV_STACK_SIZE) { +#else if (is_inside(tile, mi_col, mi_row, &mi_pos) && *refmv_count < MAX_REF_MV_STACK_SIZE) { +#endif const MODE_INFO *const candidate_mi = xd->mi[mi_pos.row * xd->mi_stride + mi_pos.col]; const MB_MODE_INFO *const candidate = &candidate_mi->mbmi; @@ -348,7 +364,13 @@ mi_pos.row = blk_row; mi_pos.col = blk_col; +#if CONFIG_DEPENDENT_HORZTILES + if (!is_inside(&xd->tile, mi_col, mi_row, cm->mi_rows, + cm->dependent_horz_tiles, &mi_pos)) + return coll_blk_count; +#else if (!is_inside(&xd->tile, mi_col, mi_row, &mi_pos)) return coll_blk_count; +#endif for (ref = 0; ref < 2; ++ref) { if (prev_frame_mvs->ref_frame[ref] == ref_frame) { @@ -607,7 +629,12 @@ // and we also need to keep a mode count. for (i = 0; i < 2; ++i) { const POSITION *const mv_ref = &mv_ref_search[i]; +#if CONFIG_DEPENDENT_HORZTILES + if (is_inside(tile, mi_col, mi_row, cm->mi_rows, cm->dependent_horz_tiles, + mv_ref)) { +#else if (is_inside(tile, mi_col, mi_row, mv_ref)) { +#endif const MODE_INFO *const candidate_mi = xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride]; const MB_MODE_INFO *const candidate = &candidate_mi->mbmi; @@ -629,7 +656,12 @@ // mode counts. for (; i < MVREF_NEIGHBOURS; ++i) { const POSITION *const mv_ref = &mv_ref_search[i]; +#if CONFIG_DEPENDENT_HORZTILES + if (is_inside(tile, mi_col, mi_row, cm->mi_rows, cm->dependent_horz_tiles, + mv_ref)) { +#else if (is_inside(tile, mi_col, mi_row, mv_ref)) { +#endif const MB_MODE_INFO *const candidate = !xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride] ? NULL @@ -683,7 +715,12 @@ if (different_ref_found) { for (i = 0; i < MVREF_NEIGHBOURS; ++i) { const POSITION *mv_ref = &mv_ref_search[i]; +#if CONFIG_DEPENDENT_HORZTILES + if (is_inside(tile, mi_col, mi_row, cm->mi_rows, cm->dependent_horz_tiles, + mv_ref)) { +#else if (is_inside(tile, mi_col, mi_row, mv_ref)) { +#endif const MB_MODE_INFO *const candidate = !xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride] ? NULL @@ -793,7 +830,12 @@ // If the size < 8x8, we get the mv from the bmi substructure; for (i = 0; i < 2; ++i) { const POSITION *const mv_ref = &mv_ref_search[i]; +#if CONFIG_DEPENDENT_HORZTILES + if (is_inside(tile, mi_col, mi_row, cm->mi_rows, cm->dependent_horz_tiles, + mv_ref)) { +#else if (is_inside(tile, mi_col, mi_row, mv_ref)) { +#endif const MODE_INFO *const candidate_mi = xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride]; const MB_MODE_INFO *const candidate = &candidate_mi->mbmi;
diff --git a/av1/common/mvref_common.h b/av1/common/mvref_common.h index 930abaa..6b83097 100644 --- a/av1/common/mvref_common.h +++ b/av1/common/mvref_common.h
@@ -345,6 +345,23 @@ // Checks that the given mi_row, mi_col and search point // are inside the borders of the tile. +#if CONFIG_DEPENDENT_HORZTILES +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 (dependent_horz_tile_flag) { + return !(mi_row + mi_pos->row < 0 || + mi_col + mi_pos->col < tile->mi_col_start || + mi_row + mi_pos->row >= mi_rows || + mi_col + mi_pos->col >= tile->mi_col_end); + } else { + return !(mi_row + mi_pos->row < tile->mi_row_start || + mi_col + mi_pos->col < tile->mi_col_start || + mi_row + mi_pos->row >= tile->mi_row_end || + mi_col + mi_pos->col >= tile->mi_col_end); + } +} +#else static INLINE int is_inside(const TileInfo *const tile, int mi_col, int mi_row, const POSITION *mi_pos) { return !(mi_row + mi_pos->row < tile->mi_row_start || @@ -352,6 +369,7 @@ mi_row + mi_pos->row >= tile->mi_row_end || mi_col + mi_pos->col >= tile->mi_col_end); } +#endif static INLINE void lower_mv_precision(MV *mv, int allow_hp) { if (!allow_hp) {
diff --git a/av1/common/onyxc_int.h b/av1/common/onyxc_int.h index 2e024e3..c1c2982 100644 --- a/av1/common/onyxc_int.h +++ b/av1/common/onyxc_int.h
@@ -368,6 +368,9 @@ int tile_cols, tile_rows; int tile_width, tile_height; // In MI units +#if CONFIG_DEPENDENT_HORZTILES + int dependent_horz_tiles; +#endif #if CONFIG_LOOPFILTERING_ACROSS_TILES int loop_filter_across_tiles_enabled; #endif // CONFIG_LOOPFILTERING_ACROSS_TILES @@ -580,6 +583,54 @@ } } +#if CONFIG_DEPENDENT_HORZTILES +static INLINE void set_mi_row_col(MACROBLOCKD *xd, const TileInfo *const tile, + int mi_row, int bh, int mi_col, int bw, + int mi_rows, int mi_cols, + int dependent_horz_tile_flag) { + xd->mb_to_top_edge = -((mi_row * MI_SIZE) * 8); + xd->mb_to_bottom_edge = ((mi_rows - bh - mi_row) * MI_SIZE) * 8; + xd->mb_to_left_edge = -((mi_col * MI_SIZE) * 8); + xd->mb_to_right_edge = ((mi_cols - bw - mi_col) * MI_SIZE) * 8; + + if (dependent_horz_tile_flag) { + xd->up_available = (mi_row > 0); + } else { + // Are edges available for intra prediction? + xd->up_available = (mi_row > tile->mi_row_start); + } + + xd->left_available = (mi_col > tile->mi_col_start); + if (xd->up_available) { + xd->above_mi = xd->mi[-xd->mi_stride]; + // above_mi may be NULL in encoder's first pass. + xd->above_mbmi = xd->above_mi ? &xd->above_mi->mbmi : NULL; + } else { + xd->above_mi = NULL; + xd->above_mbmi = NULL; + } + + if (xd->left_available) { + xd->left_mi = xd->mi[-1]; + // left_mi may be NULL in encoder's first pass. + xd->left_mbmi = xd->left_mi ? &xd->left_mi->mbmi : NULL; + } else { + xd->left_mi = NULL; + xd->left_mbmi = NULL; + } + + xd->n8_h = bh; + xd->n8_w = bw; +#if CONFIG_REF_MV + xd->is_sec_rect = 0; + if (xd->n8_w < xd->n8_h) + if (mi_col & (xd->n8_h - 1)) xd->is_sec_rect = 1; + + if (xd->n8_w > xd->n8_h) + if (mi_row & (xd->n8_w - 1)) xd->is_sec_rect = 1; +#endif +} +#else static INLINE void set_mi_row_col(MACROBLOCKD *xd, const TileInfo *const tile, int mi_row, int bh, int mi_col, int bw, int mi_rows, int mi_cols) { @@ -620,6 +671,7 @@ if (mi_row & (xd->n8_w - 1)) xd->is_sec_rect = 1; #endif } +#endif static INLINE const aom_prob *get_y_mode_probs(const AV1_COMMON *cm, const MODE_INFO *mi,
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c index 2823d1f..78df99c 100644 --- a/av1/decoder/decodeframe.c +++ b/av1/decoder/decodeframe.c
@@ -641,9 +641,14 @@ xd->max_tx_size = max_txsize_lookup[bsize]; #endif - // Distance of Mb to the various image edges. These are specified to 8th pel - // as they are always compared to values that are in 1/8th pel units +// Distance of Mb to the various image edges. These are specified to 8th pel +// as they are always compared to values that are in 1/8th pel units +#if CONFIG_DEPENDENT_HORZTILES + set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols, + cm->dependent_horz_tiles); +#else set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols); +#endif av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col); return &xd->mi[0]->mbmi; @@ -664,8 +669,13 @@ const int offset = mi_row_ori * cm->mi_stride + mi_col_ori; xd->mi = cm->mi_grid_visible + offset; xd->mi[0] = cm->mi + offset; +#if CONFIG_DEPENDENT_HORZTILES + set_mi_row_col(xd, tile, mi_row_pred, bh, mi_col_pred, bw, cm->mi_rows, + cm->mi_cols, cm->dependent_horz_tiles); +#else set_mi_row_col(xd, tile, mi_row_pred, bh, mi_col_pred, bw, cm->mi_rows, cm->mi_cols); +#endif xd->up_available = (mi_row_ori > tile->mi_row_start); xd->left_available = (mi_col_ori > tile->mi_col_start); @@ -688,7 +698,12 @@ for (y = 0; y < y_mis; ++y) for (x = !y; x < x_mis; ++x) xd->mi[y * cm->mi_stride + x] = xd->mi[0]; +#if CONFIG_DEPENDENT_HORZTILES + set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols, + cm->dependent_horz_tiles); +#else set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols); +#endif return &xd->mi[0]->mbmi; } @@ -704,7 +719,12 @@ set_plane_n4(xd, bw, bh); +#if CONFIG_DEPENDENT_HORZTILES + set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols, + cm->dependent_horz_tiles); +#else set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols); +#endif av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col); } @@ -2173,8 +2193,14 @@ xd->mi = cm->mi_grid_visible + offset; xd->mi[0] = cm->mi + offset; +#if CONFIG_DEPENDENT_HORZTILES + set_mi_row_col(xd, tile, mi_row, mi_size_high[bsize], mi_col, + mi_size_wide[bsize], cm->mi_rows, cm->mi_cols, + cm->dependent_horz_tiles); +#else set_mi_row_col(xd, tile, mi_row, mi_size_high[bsize], mi_col, mi_size_wide[bsize], cm->mi_rows, cm->mi_cols); +#endif set_skip_context(xd, mi_row, mi_col); skip = read_skip(cm, xd, xd->mi[0]->mbmi.segment_id_supertx, r); if (skip) { @@ -2990,6 +3016,13 @@ pbi->tile_col_size_bytes = aom_rb_read_literal(rb, 2) + 1; pbi->tile_size_bytes = aom_rb_read_literal(rb, 2) + 1; } + +#if CONFIG_DEPENDENT_HORZTILES + if (cm->tile_rows <= 1) + cm->dependent_horz_tiles = aom_rb_read_bit(rb); + else + cm->dependent_horz_tiles = 0; +#endif #else int min_log2_tile_cols, max_log2_tile_cols, max_ones; av1_get_tile_n_bits(cm->mi_cols, &min_log2_tile_cols, &max_log2_tile_cols); @@ -3006,7 +3039,12 @@ // 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_DEPENDENT_HORZTILES + if (cm->log2_tile_rows != 0) + cm->dependent_horz_tiles = aom_rb_read_bit(rb); + else + cm->dependent_horz_tiles = 0; +#endif #if CONFIG_LOOPFILTERING_ACROSS_TILES cm->loop_filter_across_tiles_enabled = aom_rb_read_bit(rb); #endif // CONFIG_LOOPFILTERING_ACROSS_TILES @@ -3479,7 +3517,14 @@ av1_tile_set_col(&tile_info, cm, col); +#if CONFIG_DEPENDENT_HORZTILES + if (!cm->dependent_horz_tiles || tile_row == 0) { + av1_zero_above_context(cm, tile_info.mi_col_start, + tile_info.mi_col_end); + } +#else av1_zero_above_context(cm, tile_info.mi_col_start, tile_info.mi_col_end); +#endif for (mi_row = tile_info.mi_row_start; mi_row < tile_info.mi_row_end; mi_row += cm->mib_size) { @@ -3490,7 +3535,6 @@ for (mi_col = tile_info.mi_col_start; mi_col < tile_info.mi_col_end; mi_col += cm->mib_size) { av1_update_boundary_info(cm, &tile_info, mi_row, mi_col); - decode_partition(pbi, &td->xd, #if CONFIG_SUPERTX 0, @@ -3625,8 +3669,13 @@ tile_data->error_info.setjmp = 1; tile_data->xd.error_info = &tile_data->error_info; - +#if CONFIG_DEPENDENT_HORZTILES + if (!cm->dependent_horz_tiles) { + av1_zero_above_context(&pbi->common, tile->mi_col_start, tile->mi_col_end); + } +#else av1_zero_above_context(&pbi->common, tile->mi_col_start, tile->mi_col_end); +#endif for (mi_row = tile->mi_row_start; mi_row < tile->mi_row_end; mi_row += cm->mib_size) {
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c index af96f43..6a002d8 100644 --- a/av1/encoder/bitstream.c +++ b/av1/encoder/bitstream.c
@@ -1927,7 +1927,12 @@ cpi->td.mb.mbmi_ext = cpi->mbmi_ext_base + (mi_row * cm->mi_cols + mi_col); +#if CONFIG_DEPENDENT_HORZTILES + set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols, + cm->dependent_horz_tiles); +#else set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols); +#endif if (frame_is_intra_only(cm)) { write_mb_modes_kf(cm, xd, xd->mi, w); @@ -1998,10 +2003,15 @@ bh = mi_size_high[m->mbmi.sb_type]; bw = mi_size_wide[m->mbmi.sb_type]; - cpi->td.mb.mbmi_ext = cpi->mbmi_ext_base + (mi_row * cm->mi_cols + mi_col); +#if CONFIG_DEPENDENT_HORZTILES + set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols, + cm->dependent_horz_tiles); +#else set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols); +#endif + #if CONFIG_PVQ mbmi = &m->mbmi; bsize = mbmi->sb_type; @@ -2474,8 +2484,14 @@ #if CONFIG_SUPERTX mbmi = &cm->mi_grid_visible[mi_offset]->mbmi; xd->mi = cm->mi_grid_visible + mi_offset; +#if CONFIG_DEPENDENT_HORZTILES + set_mi_row_col(xd, tile, mi_row, mi_size_high[bsize], mi_col, + mi_size_wide[bsize], cm->mi_rows, cm->mi_cols, + cm->dependent_horz_tiles); +#else set_mi_row_col(xd, tile, mi_row, mi_size_high[bsize], mi_col, mi_size_wide[bsize], cm->mi_rows, cm->mi_cols); +#endif if (!supertx_enabled && !frame_is_intra_only(cm) && partition != PARTITION_NONE && bsize <= MAX_SUPERTX_BLOCK_SIZE && !xd->lossless[0]) { @@ -2564,8 +2580,13 @@ const int bsh = mi_size_high[bsize]; xd->mi = cm->mi_grid_visible + mi_offset; supertx_size = mbmi->tx_size; +#if CONFIG_DEPENDENT_HORZTILES + set_mi_row_col(xd, tile, mi_row, bsh, mi_col, bsw, cm->mi_rows, cm->mi_cols, + cm->dependent_horz_tiles); +#else set_mi_row_col(xd, tile, mi_row, bsh, mi_col, bsw, cm->mi_rows, cm->mi_cols); +#endif assert(IMPLIES(!cm->seg.enabled, mbmi->segment_id_supertx == 0)); assert(mbmi->segment_id_supertx < MAX_SEGMENTS); @@ -2737,7 +2758,14 @@ const int mi_col_start = tile->mi_col_start; const int mi_col_end = tile->mi_col_end; int mi_row, mi_col; + +#if CONFIG_DEPENDENT_HORZTILES + if (!cm->dependent_horz_tiles || mi_row_start == 0) { + av1_zero_above_context(cm, mi_col_start, mi_col_end); + } +#else av1_zero_above_context(cm, mi_col_start, mi_col_end); +#endif #if CONFIG_PVQ assert(cpi->td.mb.pvq_q->curr_pos == 0); #endif @@ -3667,6 +3695,10 @@ if (cm->log2_tile_rows != 0) aom_wb_write_bit(wb, cm->log2_tile_rows != 1); #endif // CONFIG_EXT_TILE +#if CONFIG_DEPENDENT_HORZTILES + if (cm->log2_tile_rows != 0) aom_wb_write_bit(wb, cm->dependent_horz_tiles); +#endif + #if CONFIG_LOOPFILTERING_ACROSS_TILES aom_wb_write_bit(wb, cm->loop_filter_across_tiles_enabled); #endif // CONFIG_LOOPFILTERING_ACROSS_TILES
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c index c6a7c8a..754a472 100644 --- a/av1/encoder/encodeframe.c +++ b/av1/encoder/encodeframe.c
@@ -293,8 +293,13 @@ // Set up distance of MB to edge of frame in 1/8th pel units. assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1))); +#if CONFIG_DEPENDENT_HORZTILES + set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width, cm->mi_rows, + cm->mi_cols, cm->dependent_horz_tiles); +#else set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width, cm->mi_rows, cm->mi_cols); +#endif // Set up source buffers. av1_setup_src_planes(x, cpi->Source, mi_row, mi_col); @@ -345,8 +350,11 @@ MACROBLOCKD *const xd = &x->e_mbd; const int mi_width = mi_size_wide[bsize]; const int mi_height = mi_size_high[bsize]; - +#if CONFIG_DEPENDENT_HORZTILES + set_mode_info_offsets(cpi, x, xd, mi_row, mi_col, cm->dependent_horz_tiles); +#else set_mode_info_offsets(cpi, x, xd, mi_row, mi_col); +#endif // Set up distance of MB to edge of frame in 1/8th pel units. assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1))); @@ -367,7 +375,12 @@ const int mi_width = mi_size_wide[bsize_pred]; const int mi_height = mi_size_high[bsize_pred]; +#if CONFIG_DEPENDENT_HORZTILES + set_mode_info_offsets(cpi, x, xd, mi_row_ori, mi_col_ori, + cm->dependent_horz_tiles); +#else set_mode_info_offsets(cpi, x, xd, mi_row_ori, mi_col_ori); +#endif // Set up limit values for MV components. // Mv beyond the range do not produce new/different prediction block. @@ -4817,8 +4830,13 @@ #if CONFIG_PVQ od_adapt_ctx *adapt; #endif - +#if CONFIG_DEPENDENT_HORZTILES + if ((!cm->dependent_horz_tiles) || (tile_row == 0)) { + av1_zero_above_context(cm, tile_info->mi_col_start, tile_info->mi_col_end); + } +#else av1_zero_above_context(cm, tile_info->mi_col_start, tile_info->mi_col_end); +#endif // Set up pointers to per thread motion search counters. this_tile->m_search_count = 0; // Count of motion search hits.
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c index d119268..f4e7531 100644 --- a/av1/encoder/encoder.c +++ b/av1/encoder/encoder.c
@@ -868,6 +868,11 @@ cm->tile_height = ALIGN_POWER_OF_TWO(cm->tile_height, MAX_MIB_SIZE_LOG2); #endif // CONFIG_EXT_TILE +#if CONFIG_DEPENDENT_HORZTILES + cm->dependent_horz_tiles = cpi->oxcf.dependent_horz_tiles; + if (cm->log2_tile_rows == 0) cm->dependent_horz_tiles = 0; +#endif + #if CONFIG_LOOPFILTERING_ACROSS_TILES cm->loop_filter_across_tiles_enabled = cpi->oxcf.loop_filter_across_tiles_enabled;
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h index cb83027..63b8497 100644 --- a/av1/encoder/encoder.h +++ b/av1/encoder/encoder.h
@@ -242,6 +242,9 @@ int tile_columns; int tile_rows; +#if CONFIG_DEPENDENT_HORZTILES + int dependent_horz_tiles; +#endif #if CONFIG_LOOPFILTERING_ACROSS_TILES int loop_filter_across_tiles_enabled; #endif // CONFIG_LOOPFILTERING_ACROSS_TILES
diff --git a/av1/encoder/firstpass.c b/av1/encoder/firstpass.c index 28eaf94..8b80797 100644 --- a/av1/encoder/firstpass.c +++ b/av1/encoder/firstpass.c
@@ -633,9 +633,16 @@ xd->left_available = (mb_col != 0); xd->mi[0]->mbmi.sb_type = bsize; xd->mi[0]->mbmi.ref_frame[0] = INTRA_FRAME; +#if CONFIG_DEPENDENT_HORZTILES + set_mi_row_col(xd, &tile, mb_row * mb_scale, mi_size_high[bsize], + mb_col * mb_scale, mi_size_wide[bsize], cm->mi_rows, + cm->mi_cols, cm->dependent_horz_tiles); +#else set_mi_row_col(xd, &tile, mb_row * mb_scale, mi_size_high[bsize], mb_col * mb_scale, mi_size_wide[bsize], cm->mi_rows, cm->mi_cols); +#endif + set_plane_n4(xd, mi_size_wide[bsize], mi_size_high[bsize]); // Do intra 16x16 prediction.
diff --git a/av1/encoder/segmentation.c b/av1/encoder/segmentation.c index b291b29..1b28f41 100644 --- a/av1/encoder/segmentation.c +++ b/av1/encoder/segmentation.c
@@ -129,7 +129,12 @@ xd->mi = mi; segment_id = xd->mi[0]->mbmi.segment_id; +#if CONFIG_DEPENDENT_HORZTILES + set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols, + cm->dependent_horz_tiles); +#else set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols); +#endif // Count the number of hits on each segment with no prediction no_pred_segcounts[segment_id]++;
diff --git a/configure b/configure index 6a86f05..dadedcc 100755 --- a/configure +++ b/configure
@@ -300,6 +300,7 @@ coef_interleave entropy_stats masked_tx + dependent_horztiles daala_dist tripred "