From: Jingning Han Date: Thu, 21 May 2015 19:44:29 +0000 (-0700) Subject: Enable arbitrary tile size support X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c604b9a86c4f4a069fe49b08eaca97523ce5fb10;p=libvpx Enable arbitrary tile size support This commit allows the encoder to process tile coding per 64x64 block. The supported upper limit of tile resolution is the minimum of frame size and 4096 in each dimension. To turn on, set --experiment --row-tile and compile. It overwrite the old --tile-columns and --tile-rows configurations. These two parameters now tell the encoder the width and height of tile in the unit of 64x64 block. For example, --tile-columns=1 --tile-rows=1 will make a tile contains a single 64x64 block. Change-Id: Id515749a05cfeb9e9d008291b76bdfb720de0948 --- diff --git a/vp9/decoder/vp9_decodeframe.c b/vp9/decoder/vp9_decodeframe.c index 6c6c82483..dd3298ab9 100644 --- a/vp9/decoder/vp9_decodeframe.c +++ b/vp9/decoder/vp9_decodeframe.c @@ -1862,6 +1862,27 @@ static void setup_frame_size_with_refs(VP9_COMMON *cm, } static void setup_tile_info(VP9_COMMON *cm, struct vp9_read_bit_buffer *rb) { +#if CONFIG_ROW_TILE + cm->tile_width = vp9_rb_read_literal(rb, 6); + cm->tile_height = vp9_rb_read_literal(rb, 6); + + cm->tile_width = clamp(cm->tile_width, + 1, 64) << MI_BLOCK_SIZE_LOG2; + cm->tile_height = clamp(cm->tile_height, + 1, 64) << MI_BLOCK_SIZE_LOG2; + + cm->tile_width = MIN(cm->tile_width, cm->mi_cols); + cm->tile_height = MIN(cm->tile_height, cm->mi_rows); + + // Get tile numbers + cm->tile_cols = 1; + while (cm->tile_cols * cm->tile_width < cm->mi_cols) + ++cm->tile_cols; + + cm->tile_rows = 1; + while (cm->tile_rows * cm->tile_height < cm->mi_rows) + ++cm->tile_rows; +#else int min_log2_tiles, max_log2_tiles, max_ones; vp9_get_tile_n_bits(cm->mi_cols, &min_log2_tiles, &max_log2_tiles); @@ -1876,21 +1897,9 @@ static void setup_tile_info(VP9_COMMON *cm, struct vp9_read_bit_buffer *rb) { "Invalid number of tile columns"); // rows -#if CONFIG_ROW_TILE - vp9_get_tile_n_bits(cm->mi_rows, &min_log2_tiles, &max_log2_tiles); - max_ones = max_log2_tiles - min_log2_tiles; - cm->log2_tile_rows = min_log2_tiles; - while (max_ones-- && vp9_rb_read_bit(rb)) - ++cm->log2_tile_rows; - - if (cm->log2_tile_rows > 10) - vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, - "Invalid number of tile rows"); -#else cm->log2_tile_rows = vp9_rb_read_bit(rb); if (cm->log2_tile_rows) cm->log2_tile_rows += vp9_rb_read_bit(rb); -#endif cm->tile_cols = 1 << cm->log2_tile_cols; cm->tile_rows = 1 << cm->log2_tile_rows; @@ -1900,6 +1909,7 @@ static void setup_tile_info(VP9_COMMON *cm, struct vp9_read_bit_buffer *rb) { // round to integer multiples of 8 cm->tile_width = mi_cols_aligned_to_sb(cm->tile_width); cm->tile_height = mi_cols_aligned_to_sb(cm->tile_height); +#endif } // Reads the next tile returning its size and adjusting '*data' accordingly diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index af9c4fb14..4edc12a0b 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -1866,6 +1866,13 @@ static void fix_interp_filter(VP9_COMMON *cm) { static void write_tile_info(const VP9_COMMON *const cm, struct vp9_write_bit_buffer *wb) { +#if CONFIG_ROW_TILE + int tile_width = mi_cols_aligned_to_sb(cm->tile_width) >> MI_BLOCK_SIZE_LOG2; + int tile_height = + mi_cols_aligned_to_sb(cm->tile_height) >> MI_BLOCK_SIZE_LOG2; + vp9_wb_write_literal(wb, tile_width, 6); + vp9_wb_write_literal(wb, tile_height, 6); +#else int min_log2_tiles, max_log2_tiles, ones; vp9_get_tile_n_bits(cm->mi_cols, &min_log2_tiles, &max_log2_tiles); @@ -1878,15 +1885,6 @@ static void write_tile_info(const VP9_COMMON *const cm, vp9_wb_write_bit(wb, 0); // rows -#if CONFIG_ROW_TILE - vp9_get_tile_n_bits(cm->mi_rows, &min_log2_tiles, &max_log2_tiles); - ones = cm->log2_tile_rows - min_log2_tiles; - while (ones--) - vp9_wb_write_bit(wb, 1); - - if (cm->log2_tile_rows < max_log2_tiles) - vp9_wb_write_bit(wb, 0); -#else vp9_wb_write_bit(wb, cm->log2_tile_rows != 0); if (cm->log2_tile_rows != 0) vp9_wb_write_bit(wb, cm->log2_tile_rows != 1); @@ -1924,11 +1922,17 @@ static size_t encode_tiles(VP9_COMP *cpi, uint8_t *data_ptr) { vp9_writer residual_bc; int tile_row, tile_col; - TOKENEXTRA *tok[4][1 << 6], *tok_end; +#if CONFIG_ROW_TILE + TOKENEXTRA *(*tok)[1024] = cpi->tile_tok; + TileInfo (*tile)[1024] = cpi->tile_info; +#else + TOKENEXTRA *tok[4][1 << 6]; + TileInfo tile[4][1 << 6]; +#endif + TOKENEXTRA *tok_end; size_t total_size = 0; const int tile_cols = cm->tile_cols; const int tile_rows = cm->tile_rows; - TileInfo tile[4][1 << 6]; TOKENEXTRA *pre_tok = cpi->tok; int tile_tok = 0; diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index 4dc88d430..e379ea535 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -572,19 +572,32 @@ void vp9_new_framerate(VP9_COMP *cpi, double framerate) { static void set_tile_limits(VP9_COMP *cpi) { VP9_COMMON *const cm = &cpi->common; +#if CONFIG_ROW_TILE + cm->tile_width = clamp(cpi->oxcf.tile_columns + 1, + 1, 64) << MI_BLOCK_SIZE_LOG2; + cm->tile_height = clamp(cpi->oxcf.tile_rows + 1, + 1, 64) << MI_BLOCK_SIZE_LOG2; + + cm->tile_width = MIN(cm->tile_width, cm->mi_cols); + cm->tile_height = MIN(cm->tile_height, cm->mi_rows); + + // Get tile numbers + cm->tile_cols = 1; + while (cm->tile_cols * cm->tile_width < cm->mi_cols) + ++cm->tile_cols; + + cm->tile_rows = 1; + while (cm->tile_rows * cm->tile_height < cm->mi_rows) + ++cm->tile_rows; + +#else int min_log2_tiles, max_log2_tiles; vp9_get_tile_n_bits(cm->mi_cols, &min_log2_tiles, &max_log2_tiles); cm->log2_tile_cols = clamp(cpi->oxcf.tile_columns, min_log2_tiles, max_log2_tiles); -#if CONFIG_ROW_TILE - vp9_get_tile_n_bits(cm->mi_rows, &min_log2_tiles, &max_log2_tiles); - cm->log2_tile_rows = clamp(cpi->oxcf.tile_rows, - min_log2_tiles, max_log2_tiles); -#else - cm->log2_tile_rows = cpi->oxcf.tile_rows; -#endif + cm->log2_tile_rows = cpi->oxcf.tile_rows; cm->tile_cols = 1 << cm->log2_tile_cols; cm->tile_rows = 1 << cm->log2_tile_rows; @@ -593,6 +606,7 @@ static void set_tile_limits(VP9_COMP *cpi) { // round to integer multiples of 8 cm->tile_width = mi_cols_aligned_to_sb(cm->tile_width); cm->tile_height = mi_cols_aligned_to_sb(cm->tile_height); +#endif } static void init_buffer_indices(VP9_COMP *cpi) { diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c index b6f071e15..bf7f8b803 100644 --- a/vp9/vp9_cx_iface.c +++ b/vp9/vp9_cx_iface.c @@ -207,8 +207,13 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx, RANGE_CHECK(extra_cfg, enable_auto_alt_ref, 0, 2); RANGE_CHECK(extra_cfg, cpu_used, -16, 16); RANGE_CHECK_HI(extra_cfg, noise_sensitivity, 6); +#if CONFIG_ROW_TILE + RANGE_CHECK(extra_cfg, tile_columns, 0, 63); + RANGE_CHECK(extra_cfg, tile_rows, 0, 63); +#else RANGE_CHECK(extra_cfg, tile_columns, 0, 6); - RANGE_CHECK(extra_cfg, tile_rows, 0, 6); + RANGE_CHECK(extra_cfg, tile_rows, 0, 2); +#endif RANGE_CHECK_HI(extra_cfg, sharpness, 7); RANGE_CHECK(extra_cfg, arnr_max_frames, 0, 15); RANGE_CHECK_HI(extra_cfg, arnr_strength, 6);