From f7a39d7f08e6c29b93f450e4b66df92f8da5c892 Mon Sep 17 00:00:00 2001 From: Jingning Han Date: Tue, 26 May 2015 12:29:49 -0700 Subject: [PATCH] Make the tile coding syntax support large scale tile decoding This commit makes the bit-stream syntax support fast selective tile decoding in a large scale tile array. It reduces the computational complexity of computing the target tile offset in the bit-stream from quadratic to linear scale, while maintaining relatively small stack space requirement (in the order of 1024 bytes instead of 1M bytes). The overhead cost due to tile separation remains identical. Change-Id: Id60c6915733d33a627f49e167c57d2534e70aa96 --- configure | 1 + vp9/decoder/vp9_decodeframe.c | 42 +++++++++++++++++++++++++++++++++++ vp9/encoder/vp9_bitstream.c | 33 +++++++++++++++++++++++++++ 3 files changed, 76 insertions(+) diff --git a/configure b/configure index 8b4f651d8..0f0659f95 100755 --- a/configure +++ b/configure @@ -296,6 +296,7 @@ EXPERIMENT_LIST=" intrabc loop_postfilter row_tile + key_frame_tile new_inter bitstream_fixes newmvref diff --git a/vp9/decoder/vp9_decodeframe.c b/vp9/decoder/vp9_decodeframe.c index 4676c868e..4f8a56854 100644 --- a/vp9/decoder/vp9_decodeframe.c +++ b/vp9/decoder/vp9_decodeframe.c @@ -1952,6 +1952,47 @@ static void get_tile_buffer(const uint8_t *const data_end, *data += size; } +#if CONFIG_ROW_TILE +static void get_tile_buffers(VP9Decoder *pbi, + const uint8_t *data, const uint8_t *data_end, + int tile_cols, int tile_rows, + TileBuffer (*tile_buffers)[1024]) { + int r, c; + const uint8_t *orig_data = data; + const uint8_t *tile_end_col[1024]; + size_t tile_col_size; + + for (c = 0; c < tile_cols; ++c) { + if (c < tile_cols - 1) { + tile_col_size = mem_get_be32(data); + data += 4; + tile_end_col[c] = data + tile_col_size; + } else { + tile_col_size = data_end - data; + tile_end_col[c] = data_end; + } + data += tile_col_size; + } + + data = orig_data; + for (c = 0; c < tile_cols; ++c) { + if (c > 0) + data = tile_end_col[c - 1]; + + if (c < tile_cols - 1) + data += 4; + + for (r = 0; r < tile_rows; ++r) { + const int is_last = (r == tile_rows - 1); + TileBuffer *const buf = &tile_buffers[r][c]; + buf->col = c; + get_tile_buffer(tile_end_col[c], is_last, + &pbi->common.error, &data, + pbi->decrypt_cb, pbi->decrypt_state, buf); + } + } +} +#else static void get_tile_buffers(VP9Decoder *pbi, const uint8_t *data, const uint8_t *data_end, int tile_cols, int tile_rows, @@ -1968,6 +2009,7 @@ static void get_tile_buffers(VP9Decoder *pbi, } } } +#endif static const uint8_t *decode_tiles(VP9Decoder *pbi, const uint8_t *data, diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index a2bab85d7..44c0352e1 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -1949,6 +1949,38 @@ static size_t encode_tiles(VP9_COMP *cpi, uint8_t *data_ptr) { } } +#if CONFIG_ROW_TILE + for (tile_col = 0; tile_col < tile_cols; tile_col++) { + int is_last_col = (tile_col == tile_cols - 1); + size_t col_offset = total_size; + + if (!is_last_col) + total_size += 4; + + for (tile_row = 0; tile_row < tile_rows; tile_row++) { + const TileInfo * const ptile = &tile[tile_row][tile_col]; + tok_end = tok[tile_row][tile_col] + cpi->tok_count[tile_row][tile_col]; + + if (tile_row < tile_rows - 1) + vp9_start_encode(&residual_bc, data_ptr + total_size + 4); + else + vp9_start_encode(&residual_bc, data_ptr + total_size); + + write_modes(cpi, ptile, &residual_bc, &tok[tile_row][tile_col], tok_end); + assert(tok[tile_row][tile_col] == tok_end); + vp9_stop_encode(&residual_bc); + if (tile_row < tile_rows - 1) { + // size of this tile + mem_put_be32(data_ptr + total_size, residual_bc.pos); + total_size += 4; + } + total_size += residual_bc.pos; + } + + if (!is_last_col) + mem_put_be32(data_ptr + col_offset, total_size - col_offset - 4); + } +#else for (tile_row = 0; tile_row < tile_rows; tile_row++) { for (tile_col = 0; tile_col < tile_cols; tile_col++) { const TileInfo * const ptile = &tile[tile_row][tile_col]; @@ -1972,6 +2004,7 @@ static size_t encode_tiles(VP9_COMP *cpi, uint8_t *data_ptr) { total_size += residual_bc.pos; } } +#endif return total_size; }