From 58a0f6dbdd69540653d8e13e06948c53a527259a Mon Sep 17 00:00:00 2001 From: James Zern <jzern@google.com> Date: Fri, 25 Oct 2013 17:18:04 +0200 Subject: [PATCH] vp9: add TileInfo replaces use of cur_tile_mi_(row|col)_(start|end) by VP9_COMMON, making it less stateful and more reusable for parallel tile decoding Change-Id: I1df09382b4567a0e5f4434825d47c79afe2399be --- vp9/common/vp9_findnearmv.c | 3 +- vp9/common/vp9_findnearmv.h | 4 +- vp9/common/vp9_mvref_common.c | 16 ++-- vp9/common/vp9_mvref_common.h | 4 +- vp9/common/vp9_onyxc_int.h | 16 ++-- vp9/common/vp9_tile_common.c | 21 +++-- vp9/common/vp9_tile_common.h | 12 ++- vp9/decoder/vp9_decodemv.c | 15 ++-- vp9/decoder/vp9_decodemv.h | 3 + vp9/decoder/vp9_decodframe.c | 51 +++++++----- vp9/encoder/vp9_bitstream.c | 46 ++++++----- vp9/encoder/vp9_encodeframe.c | 147 +++++++++++++++++---------------- vp9/encoder/vp9_firstpass.c | 9 +- vp9/encoder/vp9_rdopt.c | 39 +++++---- vp9/encoder/vp9_rdopt.h | 18 +++- vp9/encoder/vp9_segmentation.c | 36 ++++---- 16 files changed, 252 insertions(+), 188 deletions(-) diff --git a/vp9/common/vp9_findnearmv.c b/vp9/common/vp9_findnearmv.c index 592ef6afa0..b91c501435 100644 --- a/vp9/common/vp9_findnearmv.c +++ b/vp9/common/vp9_findnearmv.c @@ -35,6 +35,7 @@ void vp9_find_best_ref_mvs(MACROBLOCKD *xd, int allow_hp, } void vp9_append_sub8x8_mvs_for_idx(VP9_COMMON *cm, MACROBLOCKD *xd, + const TileInfo *const tile, int_mv *dst_nearest, int_mv *dst_near, int block_idx, int ref_idx, @@ -46,7 +47,7 @@ void vp9_append_sub8x8_mvs_for_idx(VP9_COMMON *cm, MACROBLOCKD *xd, assert(ref_idx == 0 || ref_idx == 1); assert(MAX_MV_REF_CANDIDATES == 2); // makes code here slightly easier - vp9_find_mv_refs_idx(cm, xd, mi, xd->last_mi, + vp9_find_mv_refs_idx(cm, xd, tile, mi, xd->last_mi, mi->mbmi.ref_frame[ref_idx], mv_list, block_idx, mi_row, mi_col); diff --git a/vp9/common/vp9_findnearmv.h b/vp9/common/vp9_findnearmv.h index 95b46d4cf6..2362caa417 100644 --- a/vp9/common/vp9_findnearmv.h +++ b/vp9/common/vp9_findnearmv.h @@ -34,8 +34,8 @@ static void clamp_mv2(MV *mv, const MACROBLOCKD *xd) { xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN); } -void vp9_append_sub8x8_mvs_for_idx(VP9_COMMON *cm, - MACROBLOCKD *xd, +void vp9_append_sub8x8_mvs_for_idx(VP9_COMMON *cm, MACROBLOCKD *xd, + const TileInfo *const tile, int_mv *dst_nearest, int_mv *dst_near, int block_idx, int ref_idx, diff --git a/vp9/common/vp9_mvref_common.c b/vp9/common/vp9_mvref_common.c index 6590796390..8df8aec848 100644 --- a/vp9/common/vp9_mvref_common.c +++ b/vp9/common/vp9_mvref_common.c @@ -170,17 +170,19 @@ static INLINE int_mv scale_mv(const MB_MODE_INFO *mbmi, int ref, // Checks that the given mi_row, mi_col and search point // are inside the borders of the tile. -static INLINE int is_inside(const VP9_COMMON *cm, int mi_col, int mi_row, +static INLINE int is_inside(const TileInfo *const tile, + int mi_col, int mi_row, int mi_rows, const MV *mv) { return !(mi_row + mv->row < 0 || - mi_col + mv->col < cm->cur_tile_mi_col_start || - mi_row + mv->row >= cm->mi_rows || - mi_col + mv->col >= cm->cur_tile_mi_col_end); + mi_col + mv->col < tile->mi_col_start || + mi_row + mv->row >= mi_rows || + mi_col + mv->col >= tile->mi_col_end); } // This function searches the neighbourhood of a given MB/SB // to try and find candidate reference vectors. void vp9_find_mv_refs_idx(const VP9_COMMON *cm, const MACROBLOCKD *xd, + const TileInfo *const tile, MODE_INFO *mi, const MODE_INFO *prev_mi, MV_REFERENCE_FRAME ref_frame, int_mv *mv_ref_list, @@ -201,7 +203,7 @@ void vp9_find_mv_refs_idx(const VP9_COMMON *cm, const MACROBLOCKD *xd, // and we also need to keep a mode count. for (i = 0; i < 2; ++i) { const MV *const mv_ref = &mv_ref_search[i]; - if (is_inside(cm, mi_col, mi_row, mv_ref)) { + if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { const MODE_INFO *const candidate_mi = xd->mi_8x8[mv_ref->col + mv_ref->row * xd->mode_info_stride]; const MB_MODE_INFO *const candidate = &candidate_mi->mbmi; @@ -228,7 +230,7 @@ void vp9_find_mv_refs_idx(const VP9_COMMON *cm, const MACROBLOCKD *xd, // mode counts. for (; i < MVREF_NEIGHBOURS; ++i) { const MV *const mv_ref = &mv_ref_search[i]; - if (is_inside(cm, mi_col, mi_row, mv_ref)) { + if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { const MB_MODE_INFO *const candidate = &xd->mi_8x8[mv_ref->col + mv_ref->row * xd->mode_info_stride]->mbmi; @@ -258,7 +260,7 @@ void vp9_find_mv_refs_idx(const VP9_COMMON *cm, const MACROBLOCKD *xd, if (different_ref_found) { for (i = 0; i < MVREF_NEIGHBOURS; ++i) { const MV *mv_ref = &mv_ref_search[i]; - if (is_inside(cm, mi_col, mi_row, mv_ref)) { + if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { const MB_MODE_INFO *const candidate = &xd->mi_8x8[mv_ref->col + mv_ref->row * xd->mode_info_stride]->mbmi; diff --git a/vp9/common/vp9_mvref_common.h b/vp9/common/vp9_mvref_common.h index 39ebdb078d..ce4c55983b 100644 --- a/vp9/common/vp9_mvref_common.h +++ b/vp9/common/vp9_mvref_common.h @@ -15,6 +15,7 @@ #define VP9_COMMON_VP9_MVREF_COMMON_H_ void vp9_find_mv_refs_idx(const VP9_COMMON *cm, const MACROBLOCKD *xd, + const TileInfo *const tile, MODE_INFO *mi, const MODE_INFO *prev_mi, MV_REFERENCE_FRAME ref_frame, int_mv *mv_ref_list, @@ -22,11 +23,12 @@ void vp9_find_mv_refs_idx(const VP9_COMMON *cm, const MACROBLOCKD *xd, int mi_row, int mi_col); static INLINE void vp9_find_mv_refs(const VP9_COMMON *cm, const MACROBLOCKD *xd, + const TileInfo *const tile, MODE_INFO *mi, const MODE_INFO *prev_mi, MV_REFERENCE_FRAME ref_frame, int_mv *mv_ref_list, int mi_row, int mi_col) { - vp9_find_mv_refs_idx(cm, xd, mi, prev_mi, ref_frame, + vp9_find_mv_refs_idx(cm, xd, tile, mi, prev_mi, ref_frame, mv_ref_list, -1, mi_row, mi_col); } diff --git a/vp9/common/vp9_onyxc_int.h b/vp9/common/vp9_onyxc_int.h index 130ac7c944..31166b79cc 100644 --- a/vp9/common/vp9_onyxc_int.h +++ b/vp9/common/vp9_onyxc_int.h @@ -19,6 +19,7 @@ #include "vp9/common/vp9_entropy.h" #include "vp9/common/vp9_entropymode.h" #include "vp9/common/vp9_quant_common.h" +#include "vp9/common/vp9_tile_common.h" #if CONFIG_VP9_POSTPROC #include "vp9/common/vp9_postproc.h" @@ -207,8 +208,6 @@ typedef struct VP9Common { int frame_parallel_decoding_mode; int log2_tile_cols, log2_tile_rows; - int cur_tile_mi_col_start, cur_tile_mi_col_end; - int cur_tile_mi_row_start, cur_tile_mi_row_end; } VP9_COMMON; // ref == 0 => LAST_FRAME @@ -279,17 +278,18 @@ static int check_bsize_coverage(int bs, int mi_rows, int mi_cols, return -1; } -static void set_mi_row_col(VP9_COMMON *cm, MACROBLOCKD *xd, - int mi_row, int bh, - int mi_col, int bw) { +static 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) { xd->mb_to_top_edge = -((mi_row * MI_SIZE) * 8); - xd->mb_to_bottom_edge = ((cm->mi_rows - bh - 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 = ((cm->mi_cols - bw - mi_col) * MI_SIZE) * 8; + xd->mb_to_right_edge = ((mi_cols - bw - mi_col) * MI_SIZE) * 8; // Are edges available for intra prediction? xd->up_available = (mi_row != 0); - xd->left_available = (mi_col > cm->cur_tile_mi_col_start); + xd->left_available = (mi_col > tile->mi_col_start); } static void set_prev_mi(VP9_COMMON *cm) { diff --git a/vp9/common/vp9_tile_common.c b/vp9/common/vp9_tile_common.c index 1791c1a8fb..e3035d076b 100644 --- a/vp9/common/vp9_tile_common.c +++ b/vp9/common/vp9_tile_common.c @@ -10,6 +10,8 @@ #include "vp9/common/vp9_tile_common.h" +#include "vp9/common/vp9_onyxc_int.h" + #define MIN_TILE_WIDTH_B64 4 #define MAX_TILE_WIDTH_B64 64 @@ -17,8 +19,8 @@ static int to_sbs(n_mis) { return mi_cols_aligned_to_sb(n_mis) >> MI_BLOCK_SIZE_LOG2; } -static void vp9_get_tile_offsets(int *min_tile_off, int *max_tile_off, - int tile_idx, int log2_n_tiles, int n_mis) { +static void get_tile_offsets(int *min_tile_off, int *max_tile_off, + int tile_idx, int log2_n_tiles, int n_mis) { const int n_sbs = to_sbs(n_mis); const int sb_off1 = (tile_idx * n_sbs) >> log2_n_tiles; const int sb_off2 = ((tile_idx + 1) * n_sbs) >> log2_n_tiles; @@ -27,17 +29,14 @@ static void vp9_get_tile_offsets(int *min_tile_off, int *max_tile_off, *max_tile_off = MIN(sb_off2 << 3, n_mis); } -void vp9_get_tile_col_offsets(VP9_COMMON *cm, int tile_col_idx) { - vp9_get_tile_offsets(&cm->cur_tile_mi_col_start, &cm->cur_tile_mi_col_end, - tile_col_idx, cm->log2_tile_cols, cm->mi_cols); -} - -void vp9_get_tile_row_offsets(VP9_COMMON *cm, int tile_row_idx) { - vp9_get_tile_offsets(&cm->cur_tile_mi_row_start, &cm->cur_tile_mi_row_end, - tile_row_idx, cm->log2_tile_rows, cm->mi_rows); +void vp9_tile_init(TileInfo *tile, const VP9_COMMON *cm, + int row_idx, int col_idx) { + get_tile_offsets(&tile->mi_row_start, &tile->mi_row_end, + row_idx, cm->log2_tile_rows, cm->mi_rows); + get_tile_offsets(&tile->mi_col_start, &tile->mi_col_end, + col_idx, cm->log2_tile_cols, cm->mi_cols); } - void vp9_get_tile_n_bits(int mi_cols, int *min_log2_tile_cols, int *max_log2_tile_cols) { const int sb_cols = to_sbs(mi_cols); diff --git a/vp9/common/vp9_tile_common.h b/vp9/common/vp9_tile_common.h index 6d14560b91..a110abbdb9 100644 --- a/vp9/common/vp9_tile_common.h +++ b/vp9/common/vp9_tile_common.h @@ -11,11 +11,17 @@ #ifndef VP9_COMMON_VP9_TILE_COMMON_H_ #define VP9_COMMON_VP9_TILE_COMMON_H_ -#include "vp9/common/vp9_onyxc_int.h" +struct VP9Common; -void vp9_get_tile_col_offsets(VP9_COMMON *cm, int tile_col_idx); +typedef struct TileInfo { + int mi_row_start, mi_row_end; + int mi_col_start, mi_col_end; +} TileInfo; -void vp9_get_tile_row_offsets(VP9_COMMON *cm, int tile_row_idx); +// initializes 'tile->mi_(row|col)_(start|end)' for (row_idx, col_idx) based on +// 'cm->log2_tile_(rows|cols)' & 'cm->mi_(rows|cols)' +void vp9_tile_init(TileInfo *tile, const struct VP9Common *cm, + int row_idx, int col_idx); void vp9_get_tile_n_bits(int mi_cols, int *min_log2_tile_cols, int *max_log2_tile_cols); diff --git a/vp9/decoder/vp9_decodemv.c b/vp9/decoder/vp9_decodemv.c index 78c85b03ac..6bc51e8946 100644 --- a/vp9/decoder/vp9_decodemv.c +++ b/vp9/decoder/vp9_decodemv.c @@ -414,6 +414,7 @@ static int read_is_inter_block(VP9_COMMON *const cm, MACROBLOCKD *const xd, static void read_inter_block_mode_info(VP9_COMMON *const cm, MACROBLOCKD *const xd, + const TileInfo *const tile, MODE_INFO *const mi, int mi_row, int mi_col, vp9_reader *r) { MB_MODE_INFO *const mbmi = &mi->mbmi; @@ -430,7 +431,7 @@ static void read_inter_block_mode_info(VP9_COMMON *const cm, ref0 = mbmi->ref_frame[0]; is_compound = has_second_ref(mbmi); - vp9_find_mv_refs(cm, xd, mi, xd->last_mi, ref0, mbmi->ref_mvs[ref0], + vp9_find_mv_refs(cm, xd, tile, mi, xd->last_mi, ref0, mbmi->ref_mvs[ref0], mi_row, mi_col); inter_mode_ctx = mbmi->mode_context[ref0]; @@ -456,7 +457,7 @@ static void read_inter_block_mode_info(VP9_COMMON *const cm, if (is_compound) { const MV_REFERENCE_FRAME ref1 = mbmi->ref_frame[1]; - vp9_find_mv_refs(cm, xd, mi, xd->last_mi, + vp9_find_mv_refs(cm, xd, tile, mi, xd->last_mi, ref1, mbmi->ref_mvs[ref1], mi_row, mi_col); if (bsize < BLOCK_8X8 || mbmi->mode != ZEROMV) { @@ -482,12 +483,12 @@ static void read_inter_block_mode_info(VP9_COMMON *const cm, b_mode = read_inter_mode(cm, r, inter_mode_ctx); if (b_mode == NEARESTMV || b_mode == NEARMV) { - vp9_append_sub8x8_mvs_for_idx(cm, xd, &nearest[0], + vp9_append_sub8x8_mvs_for_idx(cm, xd, tile, &nearest[0], &nearmv[0], j, 0, mi_row, mi_col); if (is_compound) - vp9_append_sub8x8_mvs_for_idx(cm, xd, &nearest[1], + vp9_append_sub8x8_mvs_for_idx(cm, xd, tile, &nearest[1], &nearmv[1], j, 1, mi_row, mi_col); } @@ -523,6 +524,7 @@ static void read_inter_block_mode_info(VP9_COMMON *const cm, static void read_inter_frame_mode_info(VP9_COMMON *const cm, MACROBLOCKD *const xd, + const TileInfo *const tile, MODE_INFO *const mi, int mi_row, int mi_col, vp9_reader *r) { MB_MODE_INFO *const mbmi = &mi->mbmi; @@ -537,12 +539,13 @@ static void read_inter_frame_mode_info(VP9_COMMON *const cm, !mbmi->skip_coeff || !inter_block, r); if (inter_block) - read_inter_block_mode_info(cm, xd, mi, mi_row, mi_col, r); + read_inter_block_mode_info(cm, xd, tile, mi, mi_row, mi_col, r); else read_intra_block_mode_info(cm, mi, r); } void vp9_read_mode_info(VP9_COMMON *cm, MACROBLOCKD *xd, + const TileInfo *const tile, int mi_row, int mi_col, vp9_reader *r) { MODE_INFO *const mi = xd->mi_8x8[0]; const BLOCK_SIZE bsize = mi->mbmi.sb_type; @@ -555,7 +558,7 @@ void vp9_read_mode_info(VP9_COMMON *cm, MACROBLOCKD *xd, if (frame_is_intra_only(cm)) read_intra_frame_mode_info(cm, xd, mi, mi_row, mi_col, r); else - read_inter_frame_mode_info(cm, xd, mi, mi_row, mi_col, r); + read_inter_frame_mode_info(cm, xd, tile, mi, mi_row, mi_col, r); for (y = 0, z = 0; y < y_mis; y++, z += cm->mode_info_stride) { for (x = !y; x < x_mis; x++) { diff --git a/vp9/decoder/vp9_decodemv.h b/vp9/decoder/vp9_decodemv.h index cec99f2530..8e9ae4a548 100644 --- a/vp9/decoder/vp9_decodemv.h +++ b/vp9/decoder/vp9_decodemv.h @@ -14,7 +14,10 @@ #include "vp9/decoder/vp9_onyxd_int.h" #include "vp9/decoder/vp9_dboolhuff.h" +struct TileInfo; + void vp9_read_mode_info(VP9_COMMON *cm, MACROBLOCKD *xd, + const struct TileInfo *const tile, int mi_row, int mi_col, vp9_reader *r); #endif // VP9_DECODER_VP9_DECODEMV_H_ diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c index eaf0ab8b99..7ccc78d6cf 100644 --- a/vp9/decoder/vp9_decodframe.c +++ b/vp9/decoder/vp9_decodframe.c @@ -211,9 +211,11 @@ static void alloc_tile_storage(VP9D_COMP *pbi, int tile_cols) { vpx_realloc(pbi->mi_streams, tile_cols * sizeof(*pbi->mi_streams))); for (tile_col = 0; tile_col < tile_cols; ++tile_col) { - vp9_get_tile_col_offsets(cm, tile_col); + TileInfo tile; + + vp9_tile_init(&tile, cm, 0, tile_col); pbi->mi_streams[tile_col] = - &cm->mi[cm->mi_rows * cm->cur_tile_mi_col_start]; + &cm->mi[cm->mi_rows * tile.mi_col_start]; } // 2 contexts per 'mi unit', so that we have one context per 4x4 txfm @@ -327,6 +329,7 @@ static int decode_tokens(VP9_COMMON *const cm, MACROBLOCKD *const xd, } static void set_offsets(VP9_COMMON *const cm, MACROBLOCKD *const xd, + const TileInfo *const tile, BLOCK_SIZE bsize, int mi_row, int mi_col) { const int bh = num_8x8_blocks_high_lookup[bsize]; const int bw = num_8x8_blocks_wide_lookup[bsize]; @@ -350,7 +353,7 @@ static void set_offsets(VP9_COMMON *const cm, MACROBLOCKD *const xd, // 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 - set_mi_row_col(cm, xd, mi_row, bh, mi_col, bw); + set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols); setup_dst_planes(xd, get_frame_new_buffer(cm), mi_row, mi_col); } @@ -371,6 +374,7 @@ static void set_ref(VP9_COMMON *const cm, MACROBLOCKD *const xd, } static void decode_modes_b(VP9_COMMON *const cm, MACROBLOCKD *const xd, + const TileInfo *const tile, int mi_row, int mi_col, vp9_reader *r, BLOCK_SIZE bsize, int index) { const int less8x8 = bsize < BLOCK_8X8; @@ -381,8 +385,8 @@ static void decode_modes_b(VP9_COMMON *const cm, MACROBLOCKD *const xd, if (index > 0) return; - set_offsets(cm, xd, bsize, mi_row, mi_col); - vp9_read_mode_info(cm, xd, mi_row, mi_col, r); + set_offsets(cm, xd, tile, bsize, mi_row, mi_col); + vp9_read_mode_info(cm, xd, tile, mi_row, mi_col, r); if (less8x8) bsize = BLOCK_8X8; @@ -419,6 +423,7 @@ static void decode_modes_b(VP9_COMMON *const cm, MACROBLOCKD *const xd, } static void decode_modes_sb(VP9_COMMON *const cm, MACROBLOCKD *const xd, + const TileInfo *const tile, int mi_row, int mi_col, vp9_reader* r, BLOCK_SIZE bsize, int index) { const int hbs = num_8x8_blocks_wide_lookup[bsize] / 2; @@ -455,23 +460,23 @@ static void decode_modes_sb(VP9_COMMON *const cm, MACROBLOCKD *const xd, switch (partition) { case PARTITION_NONE: - decode_modes_b(cm, xd, mi_row, mi_col, r, subsize, 0); + decode_modes_b(cm, xd, tile, mi_row, mi_col, r, subsize, 0); break; case PARTITION_HORZ: - decode_modes_b(cm, xd, mi_row, mi_col, r, subsize, 0); + decode_modes_b(cm, xd, tile, mi_row, mi_col, r, subsize, 0); if (mi_row + hbs < cm->mi_rows) - decode_modes_b(cm, xd, mi_row + hbs, mi_col, r, subsize, 1); + decode_modes_b(cm, xd, tile, mi_row + hbs, mi_col, r, subsize, 1); break; case PARTITION_VERT: - decode_modes_b(cm, xd, mi_row, mi_col, r, subsize, 0); + decode_modes_b(cm, xd, tile, mi_row, mi_col, r, subsize, 0); if (mi_col + hbs < cm->mi_cols) - decode_modes_b(cm, xd, mi_row, mi_col + hbs, r, subsize, 1); + decode_modes_b(cm, xd, tile, mi_row, mi_col + hbs, r, subsize, 1); break; case PARTITION_SPLIT: { int n; for (n = 0; n < 4; n++) { const int j = n >> 1, i = n & 1; - decode_modes_sb(cm, xd, mi_row + j * hbs, mi_col + i * hbs, + decode_modes_sb(cm, xd, tile, mi_row + j * hbs, mi_col + i * hbs, r, subsize, n); } } break; @@ -737,7 +742,8 @@ static void setup_tile_context(VP9D_COMP *const pbi, MACROBLOCKD *const xd, xd->above_seg_context = pbi->above_seg_context; } -static void decode_tile(VP9D_COMP *pbi, vp9_reader *r) { +static void decode_tile(VP9D_COMP *pbi, const TileInfo *const tile, + vp9_reader *r) { const int num_threads = pbi->oxcf.max_threads; VP9_COMMON *const cm = &pbi->common; int mi_row, mi_col; @@ -753,14 +759,14 @@ static void decode_tile(VP9D_COMP *pbi, vp9_reader *r) { vp9_loop_filter_frame_init(cm, cm->lf.filter_level); } - for (mi_row = cm->cur_tile_mi_row_start; mi_row < cm->cur_tile_mi_row_end; + for (mi_row = tile->mi_row_start; mi_row < tile->mi_row_end; mi_row += MI_BLOCK_SIZE) { // For a SB there are 2 left contexts, each pertaining to a MB row within vp9_zero(xd->left_context); vp9_zero(xd->left_seg_context); - for (mi_col = cm->cur_tile_mi_col_start; mi_col < cm->cur_tile_mi_col_end; + for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end; mi_col += MI_BLOCK_SIZE) - decode_modes_sb(cm, xd, mi_row, mi_col, r, BLOCK_64X64, 0); + decode_modes_sb(cm, xd, tile, mi_row, mi_col, r, BLOCK_64X64, 0); if (pbi->do_loopfilter_inline) { const int lf_start = mi_row - MI_BLOCK_SIZE; @@ -770,7 +776,7 @@ static void decode_tile(VP9D_COMP *pbi, vp9_reader *r) { if (lf_start < 0) continue; // decoding has completed: finish up the loop filter in this thread. - if (mi_row + MI_BLOCK_SIZE >= cm->cur_tile_mi_row_end) continue; + if (mi_row + MI_BLOCK_SIZE >= tile->mi_row_end) continue; vp9_worker_sync(&pbi->lf_worker); lf_data->start = lf_start; @@ -852,14 +858,15 @@ static const uint8_t *decode_tiles(VP9D_COMP *pbi, const uint8_t *data) { } for (tile_row = 0; tile_row < tile_rows; tile_row++) { - vp9_get_tile_row_offsets(cm, tile_row); for (tile_col = tile_cols - 1; tile_col >= 0; tile_col--) { - vp9_get_tile_col_offsets(cm, tile_col); + TileInfo tile; + + vp9_tile_init(&tile, cm, tile_row, tile_col); setup_token_decoder(data_ptr2[tile_row][tile_col], data_end, data_end - data_ptr2[tile_row][tile_col], &cm->error, &residual_bc); setup_tile_context(pbi, xd, tile_col); - decode_tile(pbi, &residual_bc); + decode_tile(pbi, &tile, &residual_bc); if (tile_row == tile_rows - 1 && tile_col == tile_cols - 1) bc_bak = residual_bc; } @@ -869,11 +876,11 @@ static const uint8_t *decode_tiles(VP9D_COMP *pbi, const uint8_t *data) { int has_more; for (tile_row = 0; tile_row < tile_rows; tile_row++) { - vp9_get_tile_row_offsets(cm, tile_row); for (tile_col = 0; tile_col < tile_cols; tile_col++) { + TileInfo tile; size_t size; - vp9_get_tile_col_offsets(cm, tile_col); + vp9_tile_init(&tile, cm, tile_row, tile_col); has_more = tile_col < tile_cols - 1 || tile_row < tile_rows - 1; if (has_more) { @@ -889,7 +896,7 @@ static const uint8_t *decode_tiles(VP9D_COMP *pbi, const uint8_t *data) { setup_token_decoder(data, data_end, size, &cm->error, &residual_bc); setup_tile_context(pbi, xd, tile_col); - decode_tile(pbi, &residual_bc); + decode_tile(pbi, &tile, &residual_bc); data += size; } } diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index 9c4bfb3ee8..6b98f32d97 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -561,7 +561,8 @@ static void write_mb_modes_kf(const VP9_COMP *cpi, MODE_INFO **mi_8x8, write_intra_mode(bc, m->mbmi.uv_mode, vp9_kf_uv_mode_prob[ym]); } -static void write_modes_b(VP9_COMP *cpi, MODE_INFO **mi_8x8, vp9_writer *bc, +static void write_modes_b(VP9_COMP *cpi, const TileInfo *const tile, + MODE_INFO **mi_8x8, vp9_writer *bc, TOKENEXTRA **tok, TOKENEXTRA *tok_end, int mi_row, int mi_col, int index) { VP9_COMMON *const cm = &cpi->common; @@ -574,9 +575,10 @@ static void write_modes_b(VP9_COMP *cpi, MODE_INFO **mi_8x8, vp9_writer *bc, xd->mi_8x8 = mi_8x8; - set_mi_row_col(&cpi->common, xd, + set_mi_row_col(xd, tile, mi_row, num_8x8_blocks_high_lookup[m->mbmi.sb_type], - mi_col, num_8x8_blocks_wide_lookup[m->mbmi.sb_type]); + mi_col, num_8x8_blocks_wide_lookup[m->mbmi.sb_type], + cm->mi_rows, cm->mi_cols); if (frame_is_intra_only(cm)) { write_mb_modes_kf(cpi, mi_8x8, bc); #ifdef ENTROPY_STATS @@ -593,7 +595,8 @@ static void write_modes_b(VP9_COMP *cpi, MODE_INFO **mi_8x8, vp9_writer *bc, pack_mb_tokens(bc, tok, tok_end); } -static void write_modes_sb(VP9_COMP *cpi, MODE_INFO **mi_8x8, vp9_writer *bc, +static void write_modes_sb(VP9_COMP *cpi, const TileInfo *const tile, + MODE_INFO **mi_8x8, vp9_writer *bc, TOKENEXTRA **tok, TOKENEXTRA *tok_end, int mi_row, int mi_col, BLOCK_SIZE bsize, int index) { @@ -634,24 +637,25 @@ static void write_modes_sb(VP9_COMP *cpi, MODE_INFO **mi_8x8, vp9_writer *bc, switch (partition) { case PARTITION_NONE: - write_modes_b(cpi, mi_8x8, bc, tok, tok_end, mi_row, mi_col, 0); + write_modes_b(cpi, tile, mi_8x8, bc, tok, tok_end, mi_row, mi_col, 0); break; case PARTITION_HORZ: - write_modes_b(cpi, mi_8x8, bc, tok, tok_end, mi_row, mi_col, 0); + write_modes_b(cpi, tile, mi_8x8, bc, tok, tok_end, mi_row, mi_col, 0); if ((mi_row + bs) < cm->mi_rows) - write_modes_b(cpi, mi_8x8 + bs * mis, bc, tok, tok_end, mi_row + bs, - mi_col, 1); + write_modes_b(cpi, tile, mi_8x8 + bs * mis, bc, tok, tok_end, + mi_row + bs, mi_col, 1); break; case PARTITION_VERT: - write_modes_b(cpi, mi_8x8, bc, tok, tok_end, mi_row, mi_col, 0); + write_modes_b(cpi, tile, mi_8x8, bc, tok, tok_end, mi_row, mi_col, 0); if ((mi_col + bs) < cm->mi_cols) - write_modes_b(cpi, mi_8x8 + bs, bc, tok, tok_end, mi_row, mi_col + bs, - 1); + write_modes_b(cpi, tile, mi_8x8 + bs, bc, tok, tok_end, + mi_row, mi_col + bs, 1); break; case PARTITION_SPLIT: for (n = 0; n < 4; n++) { const int j = n >> 1, i = n & 1; - write_modes_sb(cpi, mi_8x8 + j * bs * mis + i * bs, bc, tok, tok_end, + write_modes_sb(cpi, tile, mi_8x8 + j * bs * mis + i * bs, bc, + tok, tok_end, mi_row + j * bs, mi_col + i * bs, subsize, n); } break; @@ -666,7 +670,8 @@ static void write_modes_sb(VP9_COMP *cpi, MODE_INFO **mi_8x8, vp9_writer *bc, mi_row, mi_col, subsize, bsize); } -static void write_modes(VP9_COMP *cpi, vp9_writer* const bc, +static void write_modes(VP9_COMP *cpi, const TileInfo *const tile, + vp9_writer* const bc, TOKENEXTRA **tok, TOKENEXTRA *tok_end) { VP9_COMMON *const cm = &cpi->common; const int mis = cm->mode_info_stride; @@ -674,15 +679,15 @@ static void write_modes(VP9_COMP *cpi, vp9_writer* const bc, MODE_INFO **mi_8x8 = cm->mi_grid_visible; MODE_INFO **m_8x8; - mi_8x8 += cm->cur_tile_mi_col_start + cm->cur_tile_mi_row_start * mis; + mi_8x8 += tile->mi_col_start + tile->mi_row_start * mis; - for (mi_row = cm->cur_tile_mi_row_start; mi_row < cm->cur_tile_mi_row_end; + for (mi_row = tile->mi_row_start; mi_row < tile->mi_row_end; mi_row += 8, mi_8x8 += 8 * mis) { m_8x8 = mi_8x8; vp9_zero(cpi->left_seg_context); - for (mi_col = cm->cur_tile_mi_col_start; mi_col < cm->cur_tile_mi_col_end; + for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end; mi_col += MI_BLOCK_SIZE, m_8x8 += MI_BLOCK_SIZE) { - write_modes_sb(cpi, m_8x8, bc, tok, tok_end, mi_row, mi_col, + write_modes_sb(cpi, tile, m_8x8, bc, tok, tok_end, mi_row, mi_col, BLOCK_64X64, 0); } } @@ -1218,9 +1223,10 @@ static size_t encode_tiles(VP9_COMP *cpi, uint8_t *data_ptr) { } for (tile_row = 0; tile_row < tile_rows; tile_row++) { - vp9_get_tile_row_offsets(cm, tile_row); for (tile_col = 0; tile_col < tile_cols; tile_col++) { - vp9_get_tile_col_offsets(cm, tile_col); + TileInfo tile; + + vp9_tile_init(&tile, cm, 0, tile_col); tok_end = tok[tile_row][tile_col] + cpi->tok_count[tile_row][tile_col]; if (tile_col < tile_cols - 1 || tile_row < tile_rows - 1) @@ -1228,7 +1234,7 @@ static size_t encode_tiles(VP9_COMP *cpi, uint8_t *data_ptr) { else vp9_start_encode(&residual_bc, data_ptr + total_size); - write_modes(cpi, &residual_bc, &tok[tile_row][tile_col], tok_end); + write_modes(cpi, &tile, &residual_bc, &tok[tile_row][tile_col], tok_end); assert(tok[tile_row][tile_col] == tok_end); vp9_stop_encode(&residual_bc); if (tile_col < tile_cols - 1 || tile_row < tile_rows - 1) { diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index f263aff2d3..5ff59a8c18 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -484,8 +484,8 @@ void vp9_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src, x->e_mbd.plane[i].subsampling_y); } -static void set_offsets(VP9_COMP *cpi, int mi_row, int mi_col, - BLOCK_SIZE bsize) { +static void set_offsets(VP9_COMP *cpi, const TileInfo *const tile, + int mi_row, int mi_col, BLOCK_SIZE bsize) { MACROBLOCK *const x = &cpi->mb; VP9_COMMON *const cm = &cpi->common; MACROBLOCKD *const xd = &x->e_mbd; @@ -528,7 +528,8 @@ static void set_offsets(VP9_COMP *cpi, int mi_row, int mi_col, // 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))); - set_mi_row_col(cm, xd, mi_row, mi_height, mi_col, mi_width); + set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width, + cm->mi_rows, cm->mi_cols); /* set up source buffers */ vp9_setup_src_planes(x, cpi->Source, mi_row, mi_col); @@ -555,9 +556,8 @@ static void set_offsets(VP9_COMP *cpi, int mi_row, int mi_col, const int x = mb_col & ~3; const int p16 = ((mb_row & 1) << 1) + (mb_col & 1); const int p32 = ((mb_row & 2) << 2) + ((mb_col & 2) << 1); - const int tile_progress = cm->cur_tile_mi_col_start * cm->mb_rows >> 1; - const int mb_cols = (cm->cur_tile_mi_col_end - cm->cur_tile_mi_col_start) - >> 1; + const int tile_progress = tile->mi_col_start * cm->mb_rows >> 1; + const int mb_cols = (tile->mi_col_end - tile->mi_col_start) >> 1; cpi->seg0_progress = ((y * mb_cols + x * 4 + p32 + p16 + tile_progress) << 16) / cm->MBs; @@ -570,7 +570,8 @@ static void set_offsets(VP9_COMP *cpi, int mi_row, int mi_col, } } -static void pick_sb_modes(VP9_COMP *cpi, int mi_row, int mi_col, +static void pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile, + int mi_row, int mi_col, int *totalrate, int64_t *totaldist, BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx, int64_t best_rd) { @@ -596,7 +597,7 @@ static void pick_sb_modes(VP9_COMP *cpi, int mi_row, int mi_col, } } - set_offsets(cpi, mi_row, mi_col, bsize); + set_offsets(cpi, tile, mi_row, mi_col, bsize); xd->mi_8x8[0]->mbmi.sb_type = bsize; // Set to zero to make sure we do not use the previous encoded frame stats @@ -632,10 +633,10 @@ static void pick_sb_modes(VP9_COMP *cpi, int mi_row, int mi_col, best_rd); } else { if (bsize >= BLOCK_8X8) - vp9_rd_pick_inter_mode_sb(cpi, x, mi_row, mi_col, totalrate, totaldist, - bsize, ctx, best_rd); + vp9_rd_pick_inter_mode_sb(cpi, x, tile, mi_row, mi_col, + totalrate, totaldist, bsize, ctx, best_rd); else - vp9_rd_pick_inter_mode_sub8x8(cpi, x, mi_row, mi_col, totalrate, + vp9_rd_pick_inter_mode_sub8x8(cpi, x, tile, mi_row, mi_col, totalrate, totaldist, bsize, ctx, best_rd); } @@ -769,7 +770,8 @@ static void save_context(VP9_COMP *cpi, int mi_row, int mi_col, sizeof(cpi->left_seg_context[0]) * mi_height); } -static void encode_b(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row, int mi_col, +static void encode_b(VP9_COMP *cpi, const TileInfo *const tile, + TOKENEXTRA **tp, int mi_row, int mi_col, int output_enabled, BLOCK_SIZE bsize, int sub_index) { VP9_COMMON * const cm = &cpi->common; MACROBLOCK * const x = &cpi->mb; @@ -787,7 +789,7 @@ static void encode_b(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row, int mi_col, if (xd->ab_index > 0) return; } - set_offsets(cpi, mi_row, mi_col, bsize); + set_offsets(cpi, tile, mi_row, mi_col, bsize); update_state(cpi, get_block_context(x, bsize), bsize, output_enabled); encode_superblock(cpi, tp, output_enabled, mi_row, mi_col, bsize); @@ -799,7 +801,8 @@ static void encode_b(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row, int mi_col, } } -static void encode_sb(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row, int mi_col, +static void encode_sb(VP9_COMP *cpi, const TileInfo *const tile, + TOKENEXTRA **tp, int mi_row, int mi_col, int output_enabled, BLOCK_SIZE bsize) { VP9_COMMON * const cm = &cpi->common; MACROBLOCK * const x = &cpi->mb; @@ -826,19 +829,19 @@ static void encode_sb(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row, int mi_col, case PARTITION_NONE: if (output_enabled && bsize >= BLOCK_8X8) cpi->partition_count[pl][PARTITION_NONE]++; - encode_b(cpi, tp, mi_row, mi_col, output_enabled, c1, -1); + encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, c1, -1); break; case PARTITION_VERT: if (output_enabled) cpi->partition_count[pl][PARTITION_VERT]++; - encode_b(cpi, tp, mi_row, mi_col, output_enabled, c1, 0); - encode_b(cpi, tp, mi_row, mi_col + bs, output_enabled, c1, 1); + encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, c1, 0); + encode_b(cpi, tile, tp, mi_row, mi_col + bs, output_enabled, c1, 1); break; case PARTITION_HORZ: if (output_enabled) cpi->partition_count[pl][PARTITION_HORZ]++; - encode_b(cpi, tp, mi_row, mi_col, output_enabled, c1, 0); - encode_b(cpi, tp, mi_row + bs, mi_col, output_enabled, c1, 1); + encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, c1, 0); + encode_b(cpi, tile, tp, mi_row + bs, mi_col, output_enabled, c1, 1); break; case PARTITION_SPLIT: subsize = get_subsize(bsize, PARTITION_SPLIT); @@ -850,7 +853,7 @@ static void encode_sb(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row, int mi_col, const int x_idx = i & 1, y_idx = i >> 1; *get_sb_index(xd, subsize) = i; - encode_sb(cpi, tp, mi_row + y_idx * bs, mi_col + x_idx * bs, + encode_sb(cpi, tile, tp, mi_row + y_idx * bs, mi_col + x_idx * bs, output_enabled, subsize); } break; @@ -889,13 +892,13 @@ static BLOCK_SIZE find_partition_size(BLOCK_SIZE bsize, // However, at the bottom and right borders of the image the requested size // may not be allowed in which case this code attempts to choose the largest // allowable partition. -static void set_partitioning(VP9_COMP *cpi, MODE_INFO **mi_8x8, - int mi_row, int mi_col) { +static void set_partitioning(VP9_COMP *cpi, const TileInfo *const tile, + MODE_INFO **mi_8x8, int mi_row, int mi_col) { VP9_COMMON *const cm = &cpi->common; BLOCK_SIZE bsize = cpi->sf.always_this_block_size; const int mis = cm->mode_info_stride; - int row8x8_remaining = cm->cur_tile_mi_row_end - mi_row; - int col8x8_remaining = cm->cur_tile_mi_col_end - mi_col; + int row8x8_remaining = tile->mi_row_end - mi_row; + int col8x8_remaining = tile->mi_col_end - mi_col; int block_row, block_col; MODE_INFO * mi_upper_left = cm->mi + mi_row * mis + mi_col; int bh = num_8x8_blocks_high_lookup[bsize]; @@ -970,7 +973,9 @@ static int sb_has_motion(VP9_COMP *cpi, MODE_INFO **prev_mi_8x8) { return 0; } -static void rd_use_partition(VP9_COMP *cpi, MODE_INFO **mi_8x8, +static void rd_use_partition(VP9_COMP *cpi, + const TileInfo *const tile, + MODE_INFO **mi_8x8, TOKENEXTRA **tp, int mi_row, int mi_col, BLOCK_SIZE bsize, int *rate, int64_t *dist, int do_recon) { @@ -1022,7 +1027,7 @@ static void rd_use_partition(VP9_COMP *cpi, MODE_INFO **mi_8x8, save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); if (bsize == BLOCK_16X16) { - set_offsets(cpi, mi_row, mi_col, bsize); + set_offsets(cpi, tile, mi_row, mi_col, bsize); x->mb_energy = vp9_block_energy(cpi, x, bsize); } @@ -1049,7 +1054,7 @@ static void rd_use_partition(VP9_COMP *cpi, MODE_INFO **mi_8x8, mi_row + (ms >> 1) < cm->mi_rows && mi_col + (ms >> 1) < cm->mi_cols) { *(get_sb_partitioning(x, bsize)) = bsize; - pick_sb_modes(cpi, mi_row, mi_col, &none_rate, &none_dist, bsize, + pick_sb_modes(cpi, tile, mi_row, mi_col, &none_rate, &none_dist, bsize, get_block_context(x, bsize), INT64_MAX); pl = partition_plane_context(cpi->above_seg_context, @@ -1065,12 +1070,12 @@ static void rd_use_partition(VP9_COMP *cpi, MODE_INFO **mi_8x8, switch (partition) { case PARTITION_NONE: - pick_sb_modes(cpi, mi_row, mi_col, &last_part_rate, &last_part_dist, + pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rate, &last_part_dist, bsize, get_block_context(x, bsize), INT64_MAX); break; case PARTITION_HORZ: *get_sb_index(xd, subsize) = 0; - pick_sb_modes(cpi, mi_row, mi_col, &last_part_rate, &last_part_dist, + pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rate, &last_part_dist, subsize, get_block_context(x, subsize), INT64_MAX); if (last_part_rate != INT_MAX && bsize >= BLOCK_8X8 && mi_row + (mh >> 1) < cm->mi_rows) { @@ -1079,7 +1084,7 @@ static void rd_use_partition(VP9_COMP *cpi, MODE_INFO **mi_8x8, update_state(cpi, get_block_context(x, subsize), subsize, 0); encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize); *get_sb_index(xd, subsize) = 1; - pick_sb_modes(cpi, mi_row + (ms >> 1), mi_col, &rt, &dt, subsize, + pick_sb_modes(cpi, tile, mi_row + (ms >> 1), mi_col, &rt, &dt, subsize, get_block_context(x, subsize), INT64_MAX); if (rt == INT_MAX || dt == INT_MAX) { last_part_rate = INT_MAX; @@ -1093,7 +1098,7 @@ static void rd_use_partition(VP9_COMP *cpi, MODE_INFO **mi_8x8, break; case PARTITION_VERT: *get_sb_index(xd, subsize) = 0; - pick_sb_modes(cpi, mi_row, mi_col, &last_part_rate, &last_part_dist, + pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rate, &last_part_dist, subsize, get_block_context(x, subsize), INT64_MAX); if (last_part_rate != INT_MAX && bsize >= BLOCK_8X8 && mi_col + (ms >> 1) < cm->mi_cols) { @@ -1102,7 +1107,7 @@ static void rd_use_partition(VP9_COMP *cpi, MODE_INFO **mi_8x8, update_state(cpi, get_block_context(x, subsize), subsize, 0); encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize); *get_sb_index(xd, subsize) = 1; - pick_sb_modes(cpi, mi_row, mi_col + (ms >> 1), &rt, &dt, subsize, + pick_sb_modes(cpi, tile, mi_row, mi_col + (ms >> 1), &rt, &dt, subsize, get_block_context(x, subsize), INT64_MAX); if (rt == INT_MAX || dt == INT_MAX) { last_part_rate = INT_MAX; @@ -1129,7 +1134,7 @@ static void rd_use_partition(VP9_COMP *cpi, MODE_INFO **mi_8x8, *get_sb_index(xd, subsize) = i; - rd_use_partition(cpi, mi_8x8 + jj * bss * mis + ii * bss, tp, + rd_use_partition(cpi, tile, mi_8x8 + jj * bss * mis + ii * bss, tp, mi_row + y_idx, mi_col + x_idx, subsize, &rt, &dt, i != 3); if (rt == INT_MAX || dt == INT_MAX) { @@ -1178,7 +1183,7 @@ static void rd_use_partition(VP9_COMP *cpi, MODE_INFO **mi_8x8, save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); - pick_sb_modes(cpi, mi_row + y_idx, mi_col + x_idx, &rt, &dt, + pick_sb_modes(cpi, tile, mi_row + y_idx, mi_col + x_idx, &rt, &dt, split_subsize, get_block_context(x, split_subsize), INT64_MAX); @@ -1191,7 +1196,7 @@ static void rd_use_partition(VP9_COMP *cpi, MODE_INFO **mi_8x8, } if (i != 3) - encode_sb(cpi, tp, mi_row + y_idx, mi_col + x_idx, 0, + encode_sb(cpi, tile, tp, mi_row + y_idx, mi_col + x_idx, 0, split_subsize); split_rate += rt; @@ -1237,7 +1242,7 @@ static void rd_use_partition(VP9_COMP *cpi, MODE_INFO **mi_8x8, assert(chosen_rate < INT_MAX && chosen_dist < INT_MAX); if (do_recon) - encode_sb(cpi, tp, mi_row, mi_col, bsize == BLOCK_64X64, bsize); + encode_sb(cpi, tile, tp, mi_row, mi_col, bsize == BLOCK_64X64, bsize); *rate = chosen_rate; *dist = chosen_dist; @@ -1285,7 +1290,8 @@ static void get_sb_partition_size_range(VP9_COMP *cpi, MODE_INFO ** mi_8x8, // Look at neighboring blocks and set a min and max partition size based on // what they chose. -static void rd_auto_partition_range(VP9_COMP *cpi, int row, int col, +static void rd_auto_partition_range(VP9_COMP *cpi, const TileInfo *const tile, + int row, int col, BLOCK_SIZE *min_block_size, BLOCK_SIZE *max_block_size) { VP9_COMMON * const cm = &cpi->common; @@ -1299,8 +1305,8 @@ static void rd_auto_partition_range(VP9_COMP *cpi, int row, int col, MODE_INFO ** above_sb64_mi_8x8; MODE_INFO ** left_sb64_mi_8x8; - int row8x8_remaining = cm->cur_tile_mi_row_end - row; - int col8x8_remaining = cm->cur_tile_mi_col_end - col; + int row8x8_remaining = tile->mi_row_end - row; + int col8x8_remaining = tile->mi_col_end - col; int bh, bw; // Trap case where we do not have a prediction. @@ -1450,7 +1456,8 @@ static INLINE void load_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) { // TODO(jingning,jimbankoski,rbultje): properly skip partition types that are // unlikely to be selected depending on previous rate-distortion optimization // results, for encoding speed-up. -static void rd_pick_partition(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row, +static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile, + TOKENEXTRA **tp, int mi_row, int mi_col, BLOCK_SIZE bsize, int *rate, int64_t *dist, int do_recon, int64_t best_rd) { VP9_COMMON * const cm = &cpi->common; @@ -1490,7 +1497,7 @@ static void rd_pick_partition(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row, assert(mi_height_log2(bsize) == mi_width_log2(bsize)); if (bsize == BLOCK_16X16) { - set_offsets(cpi, mi_row, mi_col, bsize); + set_offsets(cpi, tile, mi_row, mi_col, bsize); x->mb_energy = vp9_block_energy(cpi, x, bsize); } @@ -1527,7 +1534,7 @@ static void rd_pick_partition(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row, // PARTITION_NONE if (partition_none_allowed) { - pick_sb_modes(cpi, mi_row, mi_col, &this_rate, &this_dist, bsize, + pick_sb_modes(cpi, tile, mi_row, mi_col, &this_rate, &this_dist, bsize, get_block_context(x, bsize), best_rd); if (this_rate != INT_MAX) { if (bsize >= BLOCK_8X8) { @@ -1581,7 +1588,7 @@ static void rd_pick_partition(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row, *get_sb_index(xd, subsize) = i; if (cpi->sf.adaptive_motion_search) load_pred_mv(x, get_block_context(x, bsize)); - rd_pick_partition(cpi, tp, mi_row + y_idx, mi_col + x_idx, subsize, + rd_pick_partition(cpi, tile, tp, mi_row + y_idx, mi_col + x_idx, subsize, &this_rate, &this_dist, i != 3, best_rd - sum_rd); if (this_rate == INT_MAX) { @@ -1628,7 +1635,7 @@ static void rd_pick_partition(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row, *get_sb_index(xd, subsize) = 0; if (cpi->sf.adaptive_motion_search) load_pred_mv(x, get_block_context(x, bsize)); - pick_sb_modes(cpi, mi_row, mi_col, &sum_rate, &sum_dist, subsize, + pick_sb_modes(cpi, tile, mi_row, mi_col, &sum_rate, &sum_dist, subsize, get_block_context(x, subsize), best_rd); sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); @@ -1639,7 +1646,7 @@ static void rd_pick_partition(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row, *get_sb_index(xd, subsize) = 1; if (cpi->sf.adaptive_motion_search) load_pred_mv(x, get_block_context(x, bsize)); - pick_sb_modes(cpi, mi_row + ms, mi_col, &this_rate, + pick_sb_modes(cpi, tile, mi_row + ms, mi_col, &this_rate, &this_dist, subsize, get_block_context(x, subsize), best_rd - sum_rd); if (this_rate == INT_MAX) { @@ -1673,7 +1680,7 @@ static void rd_pick_partition(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row, *get_sb_index(xd, subsize) = 0; if (cpi->sf.adaptive_motion_search) load_pred_mv(x, get_block_context(x, bsize)); - pick_sb_modes(cpi, mi_row, mi_col, &sum_rate, &sum_dist, subsize, + pick_sb_modes(cpi, tile, mi_row, mi_col, &sum_rate, &sum_dist, subsize, get_block_context(x, subsize), best_rd); sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); if (sum_rd < best_rd && mi_col + ms < cm->mi_cols) { @@ -1683,7 +1690,7 @@ static void rd_pick_partition(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row, *get_sb_index(xd, subsize) = 1; if (cpi->sf.adaptive_motion_search) load_pred_mv(x, get_block_context(x, bsize)); - pick_sb_modes(cpi, mi_row, mi_col + ms, &this_rate, + pick_sb_modes(cpi, tile, mi_row, mi_col + ms, &this_rate, &this_dist, subsize, get_block_context(x, subsize), best_rd - sum_rd); if (this_rate == INT_MAX) { @@ -1715,7 +1722,7 @@ static void rd_pick_partition(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row, *dist = best_dist; if (best_rate < INT_MAX && best_dist < INT64_MAX && do_recon) - encode_sb(cpi, tp, mi_row, mi_col, bsize == BLOCK_64X64, bsize); + encode_sb(cpi, tile, tp, mi_row, mi_col, bsize == BLOCK_64X64, bsize); if (bsize == BLOCK_64X64) { assert(tp_orig < *tp); assert(best_rate < INT_MAX); @@ -1726,7 +1733,8 @@ static void rd_pick_partition(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row, } // Examines 64x64 block and chooses a best reference frame -static void rd_pick_reference_frame(VP9_COMP *cpi, int mi_row, int mi_col) { +static void rd_pick_reference_frame(VP9_COMP *cpi, const TileInfo *const tile, + int mi_row, int mi_col) { VP9_COMMON * const cm = &cpi->common; MACROBLOCK * const x = &cpi->mb; int bsl = b_width_log2(BLOCK_64X64), bs = 1 << bsl; @@ -1746,7 +1754,7 @@ static void rd_pick_reference_frame(VP9_COMP *cpi, int mi_row, int mi_col) { if ((mi_row + (ms >> 1) < cm->mi_rows) && (mi_col + (ms >> 1) < cm->mi_cols)) { cpi->set_ref_frame_mask = 1; - pick_sb_modes(cpi, mi_row, mi_col, &r, &d, BLOCK_64X64, + pick_sb_modes(cpi, tile, mi_row, mi_col, &r, &d, BLOCK_64X64, get_block_context(x, BLOCK_64X64), INT64_MAX); pl = partition_plane_context(cpi->above_seg_context, cpi->left_seg_context, mi_row, mi_col, BLOCK_64X64); @@ -1759,8 +1767,8 @@ static void rd_pick_reference_frame(VP9_COMP *cpi, int mi_row, int mi_col) { restore_context(cpi, mi_row, mi_col, a, l, sa, sl, BLOCK_64X64); } -static void encode_sb_row(VP9_COMP *cpi, int mi_row, TOKENEXTRA **tp, - int *totalrate) { +static void encode_sb_row(VP9_COMP *cpi, const TileInfo *const tile, + int mi_row, TOKENEXTRA **tp, int *totalrate) { VP9_COMMON * const cm = &cpi->common; int mi_col; @@ -1769,7 +1777,7 @@ static void encode_sb_row(VP9_COMP *cpi, int mi_row, TOKENEXTRA **tp, vpx_memset(cpi->left_seg_context, 0, sizeof(cpi->left_seg_context)); // Code each SB in the row - for (mi_col = cm->cur_tile_mi_col_start; mi_col < cm->cur_tile_mi_col_end; + for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end; mi_col += MI_BLOCK_SIZE) { int dummy_rate; int64_t dummy_dist; @@ -1777,7 +1785,7 @@ static void encode_sb_row(VP9_COMP *cpi, int mi_row, TOKENEXTRA **tp, vp9_zero(cpi->mb.pred_mv); if (cpi->sf.reference_masking) - rd_pick_reference_frame(cpi, mi_row, mi_col); + rd_pick_reference_frame(cpi, tile, mi_row, mi_col); if (cpi->sf.use_lastframe_partitioning || cpi->sf.use_one_partition_size_always ) { @@ -1787,9 +1795,9 @@ static void encode_sb_row(VP9_COMP *cpi, int mi_row, TOKENEXTRA **tp, cpi->mb.source_variance = UINT_MAX; if (cpi->sf.use_one_partition_size_always) { - set_offsets(cpi, mi_row, mi_col, BLOCK_64X64); - set_partitioning(cpi, mi_8x8, mi_row, mi_col); - rd_use_partition(cpi, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64, + set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64); + set_partitioning(cpi, tile, mi_8x8, mi_row, mi_col); + rd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64, &dummy_rate, &dummy_dist, 1); } else { if ((cpi->common.current_video_frame @@ -1803,28 +1811,28 @@ static void encode_sb_row(VP9_COMP *cpi, int mi_row, TOKENEXTRA **tp, sb_has_motion(cpi, prev_mi_8x8))) { // If required set upper and lower partition size limits if (cpi->sf.auto_min_max_partition_size) { - set_offsets(cpi, mi_row, mi_col, BLOCK_64X64); - rd_auto_partition_range(cpi, mi_row, mi_col, + set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64); + rd_auto_partition_range(cpi, tile, mi_row, mi_col, &cpi->sf.min_partition_size, &cpi->sf.max_partition_size); } - rd_pick_partition(cpi, tp, mi_row, mi_col, BLOCK_64X64, + rd_pick_partition(cpi, tile, tp, mi_row, mi_col, BLOCK_64X64, &dummy_rate, &dummy_dist, 1, INT64_MAX); } else { copy_partitioning(cpi, mi_8x8, prev_mi_8x8); - rd_use_partition(cpi, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64, + rd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64, &dummy_rate, &dummy_dist, 1); } } } else { // If required set upper and lower partition size limits if (cpi->sf.auto_min_max_partition_size) { - set_offsets(cpi, mi_row, mi_col, BLOCK_64X64); - rd_auto_partition_range(cpi, mi_row, mi_col, + set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64); + rd_auto_partition_range(cpi, tile, mi_row, mi_col, &cpi->sf.min_partition_size, &cpi->sf.max_partition_size); } - rd_pick_partition(cpi, tp, mi_row, mi_col, BLOCK_64X64, + rd_pick_partition(cpi, tile, tp, mi_row, mi_col, BLOCK_64X64, &dummy_rate, &dummy_dist, 1, INT64_MAX); } } @@ -1979,16 +1987,15 @@ static void encode_frame_internal(VP9_COMP *cpi) { const int tile_rows = 1 << cm->log2_tile_rows; for (tile_row = 0; tile_row < tile_rows; tile_row++) { - vp9_get_tile_row_offsets(cm, tile_row); - for (tile_col = 0; tile_col < tile_cols; tile_col++) { + TileInfo tile; TOKENEXTRA *tp_old = tp; // For each row of SBs in the frame - vp9_get_tile_col_offsets(cm, tile_col); - for (mi_row = cm->cur_tile_mi_row_start; - mi_row < cm->cur_tile_mi_row_end; mi_row += 8) - encode_sb_row(cpi, mi_row, &tp, &totalrate); + vp9_tile_init(&tile, cm, tile_row, tile_col); + for (mi_row = tile.mi_row_start; + mi_row < tile.mi_row_end; mi_row += 8) + encode_sb_row(cpi, &tile, mi_row, &tp, &totalrate); cpi->tok_count[tile_row][tile_col] = (unsigned int)(tp - tp_old); assert(tp - cpi->tok <= get_token_alloc(cm->mb_rows, cm->mb_cols)); diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c index dc323a2b4d..c83954e0ce 100644 --- a/vp9/encoder/vp9_firstpass.c +++ b/vp9/encoder/vp9_firstpass.c @@ -481,6 +481,7 @@ void vp9_first_pass(VP9_COMP *cpi) { MACROBLOCK *const x = &cpi->mb; VP9_COMMON *const cm = &cpi->common; MACROBLOCKD *const xd = &x->e_mbd; + TileInfo tile; int recon_yoffset, recon_uvoffset; const int lst_yv12_idx = cm->ref_frame_map[cpi->lst_fb_idx]; @@ -532,6 +533,9 @@ void vp9_first_pass(VP9_COMP *cpi) { vp9_initialize_rd_consts(cpi); } + // tiling is ignored in the first pass + vp9_tile_init(&tile, cm, 0, 0); + // for each macroblock row in image for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) { int_mv best_ref_mv; @@ -578,11 +582,12 @@ void vp9_first_pass(VP9_COMP *cpi) { } } xd->mi_8x8[0]->mbmi.ref_frame[0] = INTRA_FRAME; - set_mi_row_col(cm, xd, + set_mi_row_col(xd, &tile, mb_row << 1, 1 << mi_height_log2(xd->mi_8x8[0]->mbmi.sb_type), mb_col << 1, - 1 << mi_width_log2(xd->mi_8x8[0]->mbmi.sb_type)); + 1 << mi_width_log2(xd->mi_8x8[0]->mbmi.sb_type), + cm->mi_rows, cm->mi_cols); if (cpi->sf.variance_adaptive_quantization) { int energy = vp9_block_energy(cpi, x, xd->mi_8x8[0]->mbmi.sb_type); diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index d9a28c15a8..d25112b30e 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c @@ -1432,10 +1432,6 @@ static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x, int mi_row, int mi_col, int_mv single_newmv[MAX_REF_FRAMES], int *rate_mv); -static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x, - BLOCK_SIZE bsize, - int mi_row, int mi_col, - int_mv *tmp_mv, int *rate_mv); static int labels2mode(MACROBLOCK *x, int i, MB_PREDICTION_MODE this_mode, @@ -1646,6 +1642,7 @@ static INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src, } static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x, + const TileInfo *const tile, BEST_SEG_INFO *bsi_buf, int filter_idx, int_mv seg_mvs[4][MAX_REF_FRAMES], int mi_row, int mi_col) { @@ -1691,13 +1688,13 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x, i = idy * 2 + idx; frame_mv[ZEROMV][mbmi->ref_frame[0]].as_int = 0; - vp9_append_sub8x8_mvs_for_idx(&cpi->common, &x->e_mbd, + vp9_append_sub8x8_mvs_for_idx(&cpi->common, &x->e_mbd, tile, &frame_mv[NEARESTMV][mbmi->ref_frame[0]], &frame_mv[NEARMV][mbmi->ref_frame[0]], i, 0, mi_row, mi_col); if (has_second_rf) { frame_mv[ZEROMV][mbmi->ref_frame[1]].as_int = 0; - vp9_append_sub8x8_mvs_for_idx(&cpi->common, &x->e_mbd, + vp9_append_sub8x8_mvs_for_idx(&cpi->common, &x->e_mbd, tile, &frame_mv[NEARESTMV][mbmi->ref_frame[1]], &frame_mv[NEARMV][mbmi->ref_frame[1]], i, 1, mi_row, mi_col); @@ -2027,6 +2024,7 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x, } static int64_t rd_pick_best_mbsegmentation(VP9_COMP *cpi, MACROBLOCK *x, + const TileInfo *const tile, int_mv *best_ref_mv, int_mv *second_best_ref_mv, int64_t best_rd, @@ -2057,7 +2055,8 @@ static int64_t rd_pick_best_mbsegmentation(VP9_COMP *cpi, MACROBLOCK *x, for (i = 0; i < 4; i++) bsi->modes[i] = ZEROMV; - rd_check_segment_txsize(cpi, x, bsi_buf, filter_idx, seg_mvs, mi_row, mi_col); + rd_check_segment_txsize(cpi, x, tile, bsi_buf, filter_idx, seg_mvs, + mi_row, mi_col); if (bsi->segment_rd > best_rd) return INT64_MAX; @@ -2253,6 +2252,7 @@ static void setup_pred_block(const MACROBLOCKD *xd, } static void setup_buffer_inter(VP9_COMP *cpi, MACROBLOCK *x, + const TileInfo *const tile, int idx, MV_REFERENCE_FRAME frame_type, BLOCK_SIZE block_size, int mi_row, int mi_col, @@ -2281,7 +2281,7 @@ static void setup_buffer_inter(VP9_COMP *cpi, MACROBLOCK *x, &scale[frame_type], &scale[frame_type]); // Gets an initial list of candidate vectors from neighbours and orders them - vp9_find_mv_refs(&cpi->common, xd, xd->mi_8x8[0], + vp9_find_mv_refs(cm, xd, tile, xd->mi_8x8[0], xd->last_mi, frame_type, mbmi->ref_mvs[frame_type], mi_row, mi_col); @@ -2318,6 +2318,7 @@ static INLINE int get_switchable_rate(const MACROBLOCK *x) { } static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x, + const TileInfo *const tile, BLOCK_SIZE bsize, int mi_row, int mi_col, int_mv *tmp_mv, int *rate_mv) { @@ -2614,6 +2615,7 @@ static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x, } static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, + const TileInfo *const tile, BLOCK_SIZE bsize, int64_t txfm_cache[], int *rate2, int64_t *distortion, @@ -2672,7 +2674,8 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, *rate2 += rate_mv; } else { int_mv tmp_mv; - single_motion_search(cpi, x, bsize, mi_row, mi_col, &tmp_mv, &rate_mv); + single_motion_search(cpi, x, tile, bsize, mi_row, mi_col, + &tmp_mv, &rate_mv); *rate2 += rate_mv; frame_mv[refs[0]].as_int = xd->mi_8x8[0]->bmi[0].as_mv[0].as_int = tmp_mv.as_int; @@ -3083,6 +3086,7 @@ void vp9_rd_pick_intra_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, } int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, + const TileInfo *const tile, int mi_row, int mi_col, int *returnrate, int64_t *returndistortion, @@ -3193,8 +3197,9 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) { if (cpi->ref_frame_flags & flag_list[ref_frame]) { - setup_buffer_inter(cpi, x, idx_list[ref_frame], ref_frame, block_size, - mi_row, mi_col, frame_mv[NEARESTMV], frame_mv[NEARMV], + setup_buffer_inter(cpi, x, tile, idx_list[ref_frame], ref_frame, + block_size, mi_row, mi_col, + frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb, scale_factor); } frame_mv[NEWMV][ref_frame].as_int = INVALID_MV; @@ -3438,7 +3443,7 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, } else { mbmi->mode = this_mode; compmode_cost = vp9_cost_bit(comp_mode_p, second_ref_frame > INTRA_FRAME); - this_rd = handle_inter_mode(cpi, x, bsize, + this_rd = handle_inter_mode(cpi, x, tile, bsize, tx_cache, &rate2, &distortion2, &skippable, &rate_y, &distortion_y, @@ -3780,6 +3785,7 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x, + const TileInfo *const tile, int mi_row, int mi_col, int *returnrate, int64_t *returndistortion, @@ -3864,8 +3870,9 @@ int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x, for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) { if (cpi->ref_frame_flags & flag_list[ref_frame]) { - setup_buffer_inter(cpi, x, idx_list[ref_frame], ref_frame, block_size, - mi_row, mi_col, frame_mv[NEARESTMV], frame_mv[NEARMV], + setup_buffer_inter(cpi, x, tile, idx_list[ref_frame], ref_frame, + block_size, mi_row, mi_col, + frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb, scale_factor); } frame_mv[NEWMV][ref_frame].as_int = INVALID_MV; @@ -4095,7 +4102,7 @@ int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x, mbmi->interp_filter = switchable_filter_index; vp9_setup_interp_filters(xd, mbmi->interp_filter, &cpi->common); - tmp_rd = rd_pick_best_mbsegmentation(cpi, x, + tmp_rd = rd_pick_best_mbsegmentation(cpi, x, tile, &mbmi->ref_mvs[ref_frame][0], second_ref, best_yrd, @@ -4159,7 +4166,7 @@ int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x, if (!pred_exists) { // Handles the special case when a filter that is not in the // switchable list (bilinear, 6-tap) is indicated at the frame level - tmp_rd = rd_pick_best_mbsegmentation(cpi, x, + tmp_rd = rd_pick_best_mbsegmentation(cpi, x, tile, &mbmi->ref_mvs[ref_frame][0], second_ref, best_yrd, diff --git a/vp9/encoder/vp9_rdopt.h b/vp9/encoder/vp9_rdopt.h index 0b0bb18d7b..92fb23548e 100644 --- a/vp9/encoder/vp9_rdopt.h +++ b/vp9/encoder/vp9_rdopt.h @@ -18,6 +18,8 @@ (((128 + ((int64_t)R) * (RM)) >> 8) + (D << DM)) #define QIDX_SKIP_THRESH 115 +struct TileInfo; + int vp9_compute_rd_mult(VP9_COMP *cpi, int qindex); void vp9_initialize_rd_consts(VP9_COMP *cpi); @@ -29,14 +31,22 @@ void vp9_rd_pick_intra_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, PICK_MODE_CONTEXT *ctx, int64_t best_rd); int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, + const struct TileInfo *const tile, int mi_row, int mi_col, - int *r, int64_t *d, BLOCK_SIZE bsize, - PICK_MODE_CONTEXT *ctx, int64_t best_rd); + int *returnrate, + int64_t *returndistortion, + BLOCK_SIZE bsize, + PICK_MODE_CONTEXT *ctx, + int64_t best_rd_so_far); int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x, + const struct TileInfo *const tile, int mi_row, int mi_col, - int *r, int64_t *d, BLOCK_SIZE bsize, - PICK_MODE_CONTEXT *ctx, int64_t best_rd); + int *returnrate, + int64_t *returndistortion, + BLOCK_SIZE bsize, + PICK_MODE_CONTEXT *ctx, + int64_t best_rd_so_far); void vp9_init_me_luts(); diff --git a/vp9/encoder/vp9_segmentation.c b/vp9/encoder/vp9_segmentation.c index 72e6be1e8c..24f011f830 100644 --- a/vp9/encoder/vp9_segmentation.c +++ b/vp9/encoder/vp9_segmentation.c @@ -117,7 +117,8 @@ static int cost_segmap(int *segcounts, vp9_prob *probs) { return cost; } -static void count_segs(VP9_COMP *cpi, MODE_INFO **mi_8x8, +static void count_segs(VP9_COMP *cpi, const TileInfo *const tile, + MODE_INFO **mi_8x8, int *no_pred_segcounts, int (*temporal_predictor_count)[2], int *t_unpred_seg_counts, @@ -132,7 +133,7 @@ static void count_segs(VP9_COMP *cpi, MODE_INFO **mi_8x8, xd->mi_8x8 = mi_8x8; segment_id = xd->mi_8x8[0]->mbmi.segment_id; - set_mi_row_col(cm, xd, mi_row, bh, mi_col, bw); + set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols); // Count the number of hits on each segment with no prediction no_pred_segcounts[segment_id]++; @@ -157,7 +158,8 @@ static void count_segs(VP9_COMP *cpi, MODE_INFO **mi_8x8, } } -static void count_segs_sb(VP9_COMP *cpi, MODE_INFO **mi_8x8, +static void count_segs_sb(VP9_COMP *cpi, const TileInfo *const tile, + MODE_INFO **mi_8x8, int *no_pred_segcounts, int (*temporal_predictor_count)[2], int *t_unpred_seg_counts, @@ -175,19 +177,20 @@ static void count_segs_sb(VP9_COMP *cpi, MODE_INFO **mi_8x8, bh = num_8x8_blocks_high_lookup[mi_8x8[0]->mbmi.sb_type]; if (bw == bs && bh == bs) { - count_segs(cpi, mi_8x8, no_pred_segcounts, temporal_predictor_count, + count_segs(cpi, tile, mi_8x8, no_pred_segcounts, temporal_predictor_count, t_unpred_seg_counts, bs, bs, mi_row, mi_col); } else if (bw == bs && bh < bs) { - count_segs(cpi, mi_8x8, no_pred_segcounts, temporal_predictor_count, + count_segs(cpi, tile, mi_8x8, no_pred_segcounts, temporal_predictor_count, t_unpred_seg_counts, bs, hbs, mi_row, mi_col); - count_segs(cpi, mi_8x8 + hbs * mis, no_pred_segcounts, + count_segs(cpi, tile, mi_8x8 + hbs * mis, no_pred_segcounts, temporal_predictor_count, t_unpred_seg_counts, bs, hbs, mi_row + hbs, mi_col); } else if (bw < bs && bh == bs) { - count_segs(cpi, mi_8x8, no_pred_segcounts, temporal_predictor_count, + count_segs(cpi, tile, mi_8x8, no_pred_segcounts, temporal_predictor_count, t_unpred_seg_counts, hbs, bs, mi_row, mi_col); - count_segs(cpi, mi_8x8 + hbs, no_pred_segcounts, temporal_predictor_count, - t_unpred_seg_counts, hbs, bs, mi_row, mi_col + hbs); + count_segs(cpi, tile, mi_8x8 + hbs, + no_pred_segcounts, temporal_predictor_count, t_unpred_seg_counts, + hbs, bs, mi_row, mi_col + hbs); } else { const BLOCK_SIZE subsize = subsize_lookup[PARTITION_SPLIT][bsize]; int n; @@ -198,7 +201,7 @@ static void count_segs_sb(VP9_COMP *cpi, MODE_INFO **mi_8x8, const int mi_dc = hbs * (n & 1); const int mi_dr = hbs * (n >> 1); - count_segs_sb(cpi, &mi_8x8[mi_dr * mis + mi_dc], + count_segs_sb(cpi, tile, &mi_8x8[mi_dr * mis + mi_dc], no_pred_segcounts, temporal_predictor_count, t_unpred_seg_counts, mi_row + mi_dr, mi_col + mi_dc, subsize); @@ -234,15 +237,18 @@ void vp9_choose_segmap_coding_method(VP9_COMP *cpi) { // First of all generate stats regarding how well the last segment map // predicts this one for (tile_col = 0; tile_col < 1 << cm->log2_tile_cols; tile_col++) { - vp9_get_tile_col_offsets(cm, tile_col); - mi_ptr = cm->mi_grid_visible + cm->cur_tile_mi_col_start; + TileInfo tile; + + vp9_tile_init(&tile, cm, 0, tile_col); + mi_ptr = cm->mi_grid_visible + tile.mi_col_start; for (mi_row = 0; mi_row < cm->mi_rows; mi_row += 8, mi_ptr += 8 * mis) { mi = mi_ptr; - for (mi_col = cm->cur_tile_mi_col_start; mi_col < cm->cur_tile_mi_col_end; + for (mi_col = tile.mi_col_start; mi_col < tile.mi_col_end; mi_col += 8, mi += 8) - count_segs_sb(cpi, mi, no_pred_segcounts, temporal_predictor_count, - t_unpred_seg_counts, mi_row, mi_col, BLOCK_64X64); + count_segs_sb(cpi, &tile, mi, no_pred_segcounts, + temporal_predictor_count, t_unpred_seg_counts, + mi_row, mi_col, BLOCK_64X64); } } -- GitLab