From: Guillaume Martres Date: Fri, 11 Oct 2013 23:14:29 +0000 (-0700) Subject: Use a separate MODE_INFO stream for each tile column X-Git-Tag: v1.3.0~199^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5b984b36ca1e45171e0c4be49c6909696ab068e3;p=libvpx Use a separate MODE_INFO stream for each tile column This should make parallel tiles decoding easier to implement. Change-Id: I6226456dd11f275fa991e4a7a930549da6675915 --- diff --git a/vp9/common/vp9_blockd.h b/vp9/common/vp9_blockd.h index e42e9f9ac..0a441bdf0 100644 --- a/vp9/common/vp9_blockd.h +++ b/vp9/common/vp9_blockd.h @@ -198,8 +198,6 @@ typedef struct macroblockd { MODE_INFO *last_mi; int mode_info_stride; - MODE_INFO *mic_stream_ptr; - // A NULL indicates that the 8x8 is not part of the image MODE_INFO **mi_8x8; MODE_INFO **prev_mi_8x8; diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c index adfa88cba..b914de793 100644 --- a/vp9/decoder/vp9_decodframe.c +++ b/vp9/decoder/vp9_decodframe.c @@ -174,6 +174,7 @@ static int decode_tokens(VP9D_COMP *pbi, BLOCK_SIZE bsize, vp9_reader *r) { } static void set_offsets(VP9D_COMP *pbi, BLOCK_SIZE bsize, + int tile_col, int mi_row, int mi_col) { VP9_COMMON *const cm = &pbi->common; MACROBLOCKD *const xd = &pbi->mb; @@ -187,9 +188,9 @@ static void set_offsets(VP9D_COMP *pbi, BLOCK_SIZE bsize, xd->prev_mi_8x8 = cm->prev_mi_grid_visible + offset; // we are using the mode info context stream here - xd->mi_8x8[0] = xd->mic_stream_ptr; + xd->mi_8x8[0] = pbi->mi_streams[tile_col]; xd->mi_8x8[0]->mbmi.sb_type = bsize; - xd->mic_stream_ptr++; + pbi->mi_streams[tile_col]++; // Special case: if prev_mi is NULL, the previous mode info context // cannot be used. @@ -221,7 +222,8 @@ static void set_ref(VP9D_COMP *pbi, int i, int mi_row, int mi_col) { xd->corrupted |= cfg->corrupted; } -static void decode_modes_b(VP9D_COMP *pbi, int mi_row, int mi_col, +static void decode_modes_b(VP9D_COMP *pbi, int tile_col, + int mi_row, int mi_col, vp9_reader *r, BLOCK_SIZE bsize) { MACROBLOCKD *const xd = &pbi->mb; const int less8x8 = bsize < BLOCK_8X8; @@ -232,7 +234,7 @@ static void decode_modes_b(VP9D_COMP *pbi, int mi_row, int mi_col, if (xd->ab_index > 0) return; - set_offsets(pbi, bsize, mi_row, mi_col); + set_offsets(pbi, bsize, tile_col, mi_row, mi_col); vp9_read_mode_info(pbi, mi_row, mi_col, r); if (less8x8) @@ -269,7 +271,8 @@ static void decode_modes_b(VP9D_COMP *pbi, int mi_row, int mi_col, xd->corrupted |= vp9_reader_has_error(r); } -static void decode_modes_sb(VP9D_COMP *pbi, int mi_row, int mi_col, +static void decode_modes_sb(VP9D_COMP *pbi, int tile_col, + int mi_row, int mi_col, vp9_reader* r, BLOCK_SIZE bsize) { VP9_COMMON *const cm = &pbi->common; MACROBLOCKD *const xd = &pbi->mb; @@ -307,26 +310,27 @@ static void decode_modes_sb(VP9D_COMP *pbi, int mi_row, int mi_col, switch (partition) { case PARTITION_NONE: - decode_modes_b(pbi, mi_row, mi_col, r, subsize); + decode_modes_b(pbi, tile_col, mi_row, mi_col, r, subsize); break; case PARTITION_HORZ: - decode_modes_b(pbi, mi_row, mi_col, r, subsize); + decode_modes_b(pbi, tile_col, mi_row, mi_col, r, subsize); *get_sb_index(xd, subsize) = 1; if (mi_row + hbs < cm->mi_rows) - decode_modes_b(pbi, mi_row + hbs, mi_col, r, subsize); + decode_modes_b(pbi, tile_col, mi_row + hbs, mi_col, r, subsize); break; case PARTITION_VERT: - decode_modes_b(pbi, mi_row, mi_col, r, subsize); + decode_modes_b(pbi, tile_col, mi_row, mi_col, r, subsize); *get_sb_index(xd, subsize) = 1; if (mi_col + hbs < cm->mi_cols) - decode_modes_b(pbi, mi_row, mi_col + hbs, r, subsize); + decode_modes_b(pbi, tile_col, mi_row, mi_col + hbs, r, subsize); break; case PARTITION_SPLIT: { int n; for (n = 0; n < 4; n++) { const int j = n >> 1, i = n & 1; *get_sb_index(xd, subsize) = n; - decode_modes_sb(pbi, mi_row + j * hbs, mi_col + i * hbs, r, subsize); + decode_modes_sb(pbi, tile_col, mi_row + j * hbs, mi_col + i * hbs, + r, subsize); } } break; default: @@ -582,7 +586,7 @@ static void setup_frame_size_with_refs(VP9D_COMP *pbi, setup_display_size(cm, rb); } -static void decode_tile(VP9D_COMP *pbi, vp9_reader *r) { +static void decode_tile(VP9D_COMP *pbi, vp9_reader *r, int tile_col) { const int num_threads = pbi->oxcf.max_threads; VP9_COMMON *const cm = &pbi->common; int mi_row, mi_col; @@ -607,7 +611,7 @@ static void decode_tile(VP9D_COMP *pbi, vp9_reader *r) { vp9_zero(cm->left_seg_context); for (mi_col = cm->cur_tile_mi_col_start; mi_col < cm->cur_tile_mi_col_end; mi_col += MI_BLOCK_SIZE) - decode_modes_sb(pbi, mi_row, mi_col, r, BLOCK_64X64); + decode_modes_sb(pbi, tile_col, mi_row, mi_col, r, BLOCK_64X64); if (pbi->do_loopfilter_inline) { // delay the loopfilter by 1 macroblock row. @@ -709,7 +713,7 @@ static const uint8_t *decode_tiles(VP9D_COMP *pbi, const uint8_t *data) { setup_token_decoder(pbi, data_ptr2[tile_row][tile_col], data_end - data_ptr2[tile_row][tile_col], &residual_bc); - decode_tile(pbi, &residual_bc); + decode_tile(pbi, &residual_bc, tile_col); if (tile_row == tile_rows - 1 && tile_col == tile_cols - 1) bc_bak = residual_bc; } @@ -738,7 +742,7 @@ static const uint8_t *decode_tiles(VP9D_COMP *pbi, const uint8_t *data) { } setup_token_decoder(pbi, data, size, &residual_bc); - decode_tile(pbi, &residual_bc); + decode_tile(pbi, &residual_bc, tile_col); data += size; } } @@ -954,6 +958,8 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) { const size_t first_partition_size = read_uncompressed_header(pbi, &rb); const int keyframe = cm->frame_type == KEY_FRAME; YV12_BUFFER_CONFIG *new_fb = &cm->yv12_fb[cm->new_fb_idx]; + const int tile_cols = 1 << cm->log2_tile_cols; + int tile_col; if (!first_partition_size) { if (!keyframe) { @@ -982,9 +988,17 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) { setup_plane_dequants(cm, &pbi->mb, cm->base_qindex); xd->mi_8x8 = cm->mi_grid_visible; - xd->mic_stream_ptr = cm->mi; xd->mode_info_stride = cm->mode_info_stride; + CHECK_MEM_ERROR(cm, pbi->mi_streams, + 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); + pbi->mi_streams[tile_col] = + &cm->mi[cm->mi_rows * cm->cur_tile_mi_col_start]; + } + cm->fc = cm->frame_contexts[cm->frame_context_idx]; vp9_zero(cm->counts); diff --git a/vp9/decoder/vp9_onyxd_if.c b/vp9/decoder/vp9_onyxd_if.c index bc7ced0ff..c1fbee312 100644 --- a/vp9/decoder/vp9_onyxd_if.c +++ b/vp9/decoder/vp9_onyxd_if.c @@ -163,6 +163,7 @@ void vp9_remove_decompressor(VP9D_PTR ptr) { vp9_remove_common(&pbi->common); vp9_worker_end(&pbi->lf_worker); vpx_free(pbi->lf_worker.data1); + vpx_free(pbi->mi_streams); vpx_free(pbi); } diff --git a/vp9/decoder/vp9_onyxd_int.h b/vp9/decoder/vp9_onyxd_int.h index 76d7c5765..68b30347e 100644 --- a/vp9/decoder/vp9_onyxd_int.h +++ b/vp9/decoder/vp9_onyxd_int.h @@ -39,6 +39,10 @@ typedef struct VP9Decompressor { int do_loopfilter_inline; // apply loopfilter to available rows immediately VP9Worker lf_worker; + + /* Each tile column has its own MODE_INFO stream. This array indexes them by + tile column index. */ + MODE_INFO **mi_streams; } VP9D_COMP; #endif // VP9_DECODER_VP9_ONYXD_INT_H_ diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index d76c23c0b..20e4d71c8 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -1942,7 +1942,6 @@ static void encode_frame_internal(VP9_COMP *cpi) { xd->mi_8x8 = cm->mi_grid_visible; // required for vp9_frame_init_quantizer xd->mi_8x8[0] = cm->mi; - xd->mic_stream_ptr = cm->mi; xd->last_mi = cm->prev_mi; diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c index d78804989..7157451b2 100644 --- a/vp9/encoder/vp9_firstpass.c +++ b/vp9/encoder/vp9_firstpass.c @@ -519,7 +519,6 @@ void vp9_first_pass(VP9_COMP *cpi) { xd->mi_8x8 = cm->mi_grid_visible; // required for vp9_frame_init_quantizer xd->mi_8x8[0] = cm->mi; - xd->mic_stream_ptr = cm->mi; setup_block_dptrs(&x->e_mbd, cm->subsampling_x, cm->subsampling_y);