From: Ronald S. Bultje Date: Wed, 6 Feb 2013 23:30:21 +0000 (-0800) Subject: Add tile column size limits (256 pixels min, 4096 pixels max). X-Git-Tag: v1.3.0~1151^2~183 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f496f601fb2e48390c822f89df60c6b2398026ab;p=platform%2Fupstream%2Flibvpx.git Add tile column size limits (256 pixels min, 4096 pixels max). This is after discussion with the hardware team. Update the unit test to take these sizes into account. Split out some duplicate code into a separate file so it can be shared. Change-Id: I8311d11b0191d8bb37e8eb4ac962beb217e1bff5 --- diff --git a/test/tile_independence_test.cc b/test/tile_independence_test.cc index e9d2ca8..c9f82ef 100644 --- a/test/tile_independence_test.cc +++ b/test/tile_independence_test.cc @@ -29,8 +29,8 @@ class TileIndependenceTest : public ::libvpx_test::EncoderTest, md5_fw_order_(), md5_inv_order_() { init_flags_ = VPX_CODEC_USE_PSNR; vpx_codec_dec_cfg_t cfg; - cfg.w = 352; - cfg.h = 288; + cfg.w = 704; + cfg.h = 144; cfg.threads = 1; cfg.inv_tile_order = 0; fw_dec_ = codec_->CreateDecoder(cfg, 0); @@ -83,7 +83,7 @@ TEST_P(TileIndependenceTest, MD5Match) { cfg_.g_lag_in_frames = 25; cfg_.rc_end_usage = VPX_VBR; - libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, + libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 704, 144, timebase.den, timebase.num, 0, 30); ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); @@ -97,7 +97,6 @@ TEST_P(TileIndependenceTest, MD5Match) { } VP9_INSTANTIATE_TEST_CASE(TileIndependenceTest, - ::testing::Values(VP8_TWO_TILE_COLUMNS, - VP8_FOUR_TILE_COLUMNS)); + ::testing::Range(0, 2, 1)); } // namespace diff --git a/vp9/common/vp9_onyxc_int.h b/vp9/common/vp9_onyxc_int.h index 5e57228..a333a4b 100644 --- a/vp9/common/vp9_onyxc_int.h +++ b/vp9/common/vp9_onyxc_int.h @@ -279,7 +279,7 @@ typedef struct VP9Common { int error_resilient_mode; int frame_parallel_decoding_mode; - int tile_columns; + int tile_columns, log2_tile_columns; int cur_tile_mb_col_start, cur_tile_mb_col_end, cur_tile_idx; } VP9_COMMON; diff --git a/vp9/common/vp9_tile_common.c b/vp9/common/vp9_tile_common.c new file mode 100644 index 0000000..02e0d14 --- /dev/null +++ b/vp9/common/vp9_tile_common.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2010 The WebM project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "vp9/common/vp9_tile_common.h" + +void vp9_get_tile_offsets(VP9_COMMON *cm, int *min_tile_off, + int *max_tile_off) { + const int log2_n_tiles = cm->log2_tile_columns; + const int tile_idx = cm->cur_tile_idx; + const int mb_cols = cm->mb_cols; + const int sb_cols = (mb_cols + 3) >> 2; + const int sb_off1 = (tile_idx * sb_cols) >> log2_n_tiles; + const int sb_off2 = ((tile_idx + 1) * sb_cols) >> log2_n_tiles; + + *min_tile_off = (sb_off1 << 2) > mb_cols ? mb_cols : (sb_off1 << 2); + *max_tile_off = (sb_off2 << 2) > mb_cols ? mb_cols : (sb_off2 << 2); +} + +#define MIN_TILE_WIDTH_SBS (MIN_TILE_WIDTH >> 6) +#define MAX_TILE_WIDTH_SBS (MAX_TILE_WIDTH >> 6) + +void vp9_get_tile_n_bits(VP9_COMMON *cm, int *min_log2_n_tiles_ptr, + int *delta_log2_n_tiles) { + const int sb_cols = (cm->mb_cols + 3) >> 2; + int min_log2_n_tiles, max_log2_n_tiles; + + for (max_log2_n_tiles = 0; + (sb_cols >> max_log2_n_tiles) >= MIN_TILE_WIDTH_SBS; + max_log2_n_tiles++) {} + for (min_log2_n_tiles = 0; + (MAX_TILE_WIDTH_SBS << min_log2_n_tiles) < sb_cols; + min_log2_n_tiles++) {} + + *min_log2_n_tiles_ptr = min_log2_n_tiles; + *delta_log2_n_tiles = max_log2_n_tiles - min_log2_n_tiles; +} diff --git a/vp9/common/vp9_tile_common.h b/vp9/common/vp9_tile_common.h new file mode 100644 index 0000000..653b6b4 --- /dev/null +++ b/vp9/common/vp9_tile_common.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2010 The WebM project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef VP9_COMMON_VP9_TILE_COMMON_H_ +#define VP9_COMMON_VP9_TILE_COMMON_H_ + +#include "vp9/common/vp9_onyxc_int.h" + +#define MIN_TILE_WIDTH 256 +#define MAX_TILE_WIDTH 4096 + +extern void vp9_get_tile_offsets(VP9_COMMON *cm, int *min_tile_off, + int *max_tile_off); + +extern void vp9_get_tile_n_bits(VP9_COMMON *cm, int *min_log2_n_tiles, + int *delta_log2_n_tiles); + +#endif // VP9_COMMON_VP9_TILE_COMMON_H_ diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c index 3324186..b8e867a 100644 --- a/vp9/decoder/vp9_decodframe.c +++ b/vp9/decoder/vp9_decodframe.c @@ -31,6 +31,7 @@ #include "vp9/decoder/vp9_dboolhuff.h" #include "vp9/common/vp9_seg_common.h" +#include "vp9/common/vp9_tile_common.h" #include "vp9_rtcd.h" #include @@ -1769,15 +1770,18 @@ int vp9_decode_frame(VP9D_COMP *pbi, const unsigned char **p_data_end) { /* tile info */ { - int log2_tile_cols; const unsigned char *data_ptr = data + first_partition_length_in_bytes; - int tile, mb_start, mb_end; + int tile, delta_log2_tiles; - log2_tile_cols = vp9_read_bit(&header_bc); - if (log2_tile_cols) { - log2_tile_cols += vp9_read_bit(&header_bc); + vp9_get_tile_n_bits(pc, &pc->log2_tile_columns, &delta_log2_tiles); + while (delta_log2_tiles--) { + if (vp9_read_bit(&header_bc)) { + pc->log2_tile_columns++; + } else { + break; + } } - pc->tile_columns = 1 << log2_tile_cols; + pc->tile_columns = 1 << pc->log2_tile_columns; vpx_memset(pc->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) * pc->mb_cols); @@ -1793,39 +1797,25 @@ int vp9_decode_frame(VP9D_COMP *pbi, const unsigned char **p_data_end) { data_ptr2[tile - 1] += 4; data_ptr2[tile] = data_ptr2[tile - 1] + size; } - for (mb_end = pc->mb_cols, tile = pc->tile_columns - 1; - tile >= 0; tile--) { - // calculate end of tile column - const int sb_cols = (pc->mb_cols + 3) >> 2; - const int sb_start = (sb_cols * tile) >> log2_tile_cols; - mb_start = ((sb_start << 2) > pc->mb_cols) ? - pc->mb_cols : (sb_start << 2); - + for (tile = pc->tile_columns - 1; tile >= 0; tile--) { pc->cur_tile_idx = tile; - pc->cur_tile_mb_col_start = mb_start; - pc->cur_tile_mb_col_end = mb_end; - + vp9_get_tile_offsets(pc, &pc->cur_tile_mb_col_start, + &pc->cur_tile_mb_col_end); setup_token_decoder(pbi, data_ptr2[tile], &residual_bc); /* Decode a row of superblocks */ for (mb_row = 0; mb_row < pc->mb_rows; mb_row += 4) { decode_sb_row(pbi, pc, mb_row, xd, &residual_bc); } - mb_end = mb_start; if (tile == pc->tile_columns - 1) bc_bak = residual_bc; } residual_bc = bc_bak; } else { - for (mb_start = 0, tile = 0; tile < pc->tile_columns; tile++) { - // calculate end of tile column - const int sb_cols = (pc->mb_cols + 3) >> 2; - const int sb_end = (sb_cols * (tile + 1)) >> log2_tile_cols; - mb_end = ((sb_end << 2) > pc->mb_cols) ? pc->mb_cols : (sb_end << 2); - + for (tile = 0; tile < pc->tile_columns; tile++) { pc->cur_tile_idx = tile; - pc->cur_tile_mb_col_start = mb_start; - pc->cur_tile_mb_col_end = mb_end; + vp9_get_tile_offsets(pc, &pc->cur_tile_mb_col_start, + &pc->cur_tile_mb_col_end); if (tile < pc->tile_columns - 1) setup_token_decoder(pbi, data_ptr + 4, &residual_bc); @@ -1836,7 +1826,6 @@ int vp9_decode_frame(VP9D_COMP *pbi, const unsigned char **p_data_end) { for (mb_row = 0; mb_row < pc->mb_rows; mb_row += 4) { decode_sb_row(pbi, pc, mb_row, xd, &residual_bc); } - mb_start = mb_end; if (tile < pc->tile_columns - 1) { int size = data_ptr[0] + (data_ptr[1] << 8) + (data_ptr[2] << 16) + (data_ptr[3] << 24); diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index a3c4078..c5f2a70 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -14,6 +14,7 @@ #include "vp9/common/vp9_entropymode.h" #include "vp9/common/vp9_entropymv.h" #include "vp9/common/vp9_findnearmv.h" +#include "vp9/common/vp9_tile_common.h" #include "vp9/encoder/vp9_mcomp.h" #include "vp9/common/vp9_systemdependent.h" #include @@ -2026,9 +2027,19 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest, } /* tiling */ - vp9_write(&header_bc, pc->tile_columns > 1, 128); - if (pc->tile_columns > 1) { - vp9_write(&header_bc, pc->tile_columns > 2, 128); + { + int min_log2_tiles, delta_log2_tiles, n_tile_bits, n; + + vp9_get_tile_n_bits(pc, &min_log2_tiles, &delta_log2_tiles); + n_tile_bits = pc->log2_tile_columns - min_log2_tiles; + for (n = 0; n < delta_log2_tiles; n++) { + if (n_tile_bits--) { + vp9_write_bit(&header_bc, 1); + } else { + vp9_write_bit(&header_bc, 0); + break; + } + } } vp9_stop_encode(&header_bc); @@ -2058,21 +2069,14 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest, } { - int mb_start = 0, tile; - int total_size = 0; + int tile, total_size = 0; unsigned char *data_ptr = cx_data + header_bc.pos; TOKENEXTRA *tok = cpi->tok; for (tile = 0; tile < pc->tile_columns; tile++) { - // calculate end of tile column - const int sb_cols = (pc->mb_cols + 3) >> 2; - const int sb_end = (sb_cols * (tile + 1)) >> cpi->oxcf.tile_columns; - const int mb_end = ((sb_end << 2) > pc->mb_cols) ? - pc->mb_cols : (sb_end << 2); - pc->cur_tile_idx = tile; - pc->cur_tile_mb_col_start = mb_start; - pc->cur_tile_mb_col_end = mb_end; + vp9_get_tile_offsets(pc, &pc->cur_tile_mb_col_start, + &pc->cur_tile_mb_col_end); if (tile < pc->tile_columns - 1) vp9_start_encode(&residual_bc, data_ptr + total_size + 4); @@ -2089,7 +2093,6 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest, total_size += 4; } - mb_start = mb_end; total_size += residual_bc.pos; } diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index 927a1b9..c5f717f 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -28,6 +28,7 @@ #include "vp9/common/vp9_findnearmv.h" #include "vp9/common/vp9_reconintra.h" #include "vp9/common/vp9_seg_common.h" +#include "vp9/common/vp9_tile_common.h" #include "vp9/encoder/vp9_tokenize.h" #include "vp9_rtcd.h" #include @@ -1312,23 +1313,16 @@ static void encode_frame_internal(VP9_COMP *cpi) { { // Take tiles into account and give start/end MB - int tile, mb_start = 0; + int tile; for (tile = 0; tile < cm->tile_columns; tile++) { - // calculate end of tile column - const int sb_cols = (cm->mb_cols + 3) >> 2; - const int sb_end = (sb_cols * (tile + 1)) >> cpi->oxcf.tile_columns; - const int mb_end = ((sb_end << 2) > cm->mb_cols) ? - cm->mb_cols : (sb_end << 2); - // For each row of SBs in the frame cm->cur_tile_idx = tile; - cm->cur_tile_mb_col_start = mb_start; - cm->cur_tile_mb_col_end = mb_end; + vp9_get_tile_offsets(cm, &cm->cur_tile_mb_col_start, + &cm->cur_tile_mb_col_end); for (mb_row = 0; mb_row < cm->mb_rows; mb_row += 4) { encode_sb_row(cpi, mb_row, &tp, &totalrate); } - mb_start = mb_end; } cpi->tok_count = (unsigned int)(tp - cpi->tok); diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c index ad5fe78..73b7b1f 100644 --- a/vp9/encoder/vp9_onyx_if.c +++ b/vp9/encoder/vp9_onyx_if.c @@ -23,6 +23,7 @@ #include "vp9/common/vp9_extend.h" #include "vp9/encoder/vp9_ratectrl.h" #include "vp9/common/vp9_quant_common.h" +#include "vp9/common/vp9_tile_common.h" #include "vp9/encoder/vp9_segmentation.h" #include "./vp9_rtcd.h" #include "./vpx_scale_rtcd.h" @@ -949,7 +950,6 @@ void vp9_alloc_compressor_data(VP9_COMP *cpi) { vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, "Failed to allocate scaled source buffer"); - vpx_free(cpi->tok); { @@ -1107,6 +1107,17 @@ rescale(int val, int num, int denom) { return (int)(llval * llnum / llden); } +static void set_tile_limits(VP9_COMMON *cm) { + int min_log2_tiles, max_log2_tiles; + + vp9_get_tile_n_bits(cm, &min_log2_tiles, &max_log2_tiles); + max_log2_tiles += min_log2_tiles; + if (cm->log2_tile_columns < min_log2_tiles) + cm->log2_tile_columns = min_log2_tiles; + else if (cm->log2_tile_columns > max_log2_tiles) + cm->log2_tile_columns = max_log2_tiles; + cm->tile_columns = 1 << cm->log2_tile_columns; +} static void init_config(VP9_PTR ptr, VP9_CONFIG *oxcf) { VP9_COMP *cpi = (VP9_COMP *)(ptr); @@ -1145,7 +1156,8 @@ static void init_config(VP9_PTR ptr, VP9_CONFIG *oxcf) { cpi->gld_fb_idx = 1; cpi->alt_fb_idx = 2; - cm->tile_columns = 1 << cpi->oxcf.tile_columns; + cm->log2_tile_columns = cpi->oxcf.tile_columns; + set_tile_limits(cm); #if VP9_TEMPORAL_ALT_REF { @@ -1372,7 +1384,8 @@ void vp9_change_config(VP9_PTR ptr, VP9_CONFIG *oxcf) { cpi->last_frame_distortion = 0; #endif - cm->tile_columns = 1 << cpi->oxcf.tile_columns; + cm->log2_tile_columns = cpi->oxcf.tile_columns; + set_tile_limits(cm); } #define M_LOG2_E 0.693147180559945309417 diff --git a/vp9/encoder/vp9_segmentation.c b/vp9/encoder/vp9_segmentation.c index 17d8f25..710ca7e 100644 --- a/vp9/encoder/vp9_segmentation.c +++ b/vp9/encoder/vp9_segmentation.c @@ -13,6 +13,7 @@ #include "vpx_mem/vpx_mem.h" #include "vp9/encoder/vp9_segmentation.h" #include "vp9/common/vp9_pred_common.h" +#include "vp9/common/vp9_tile_common.h" void vp9_update_gf_useage_maps(VP9_COMP *cpi, VP9_COMMON *cm, MACROBLOCK *x) { int mb_row, mb_col; @@ -254,7 +255,7 @@ void vp9_choose_segmap_coding_method(VP9_COMP *cpi) { int t_pred_cost = INT_MAX; int i; - int tile, mb_row, mb_col, mb_start = 0; + int tile, mb_row, mb_col; int temporal_predictor_count[PREDICTION_PROBS][2]; int no_pred_segcounts[MAX_MB_SEGMENTS]; @@ -283,20 +284,14 @@ void vp9_choose_segmap_coding_method(VP9_COMP *cpi) { // predicts this one for (tile = 0; tile < cm->tile_columns; tile++) { - // calculate end of tile column - const int sb_cols = (cm->mb_cols + 3) >> 2; - const int sb_end = (sb_cols * (tile + 1)) >> cpi->oxcf.tile_columns; - const int mb_end = ((sb_end << 2) > cm->mb_cols) ? - cm->mb_cols : (sb_end << 2); - cm->cur_tile_idx = tile; - cm->cur_tile_mb_col_start = mb_start; - cm->cur_tile_mb_col_end = mb_end; - - mi_ptr = cm->mi + mb_start; + vp9_get_tile_offsets(cm, &cm->cur_tile_mb_col_start, + &cm->cur_tile_mb_col_end); + mi_ptr = cm->mi + cm->cur_tile_mb_col_start; for (mb_row = 0; mb_row < cm->mb_rows; mb_row += 4, mi_ptr += 4 * mis) { mi = mi_ptr; - for (mb_col = mb_start; mb_col < mb_end; mb_col += 4, mi += 4) { + for (mb_col = cm->cur_tile_mb_col_start; + mb_col < cm->cur_tile_mb_col_end; mb_col += 4, mi += 4) { if (mi->mbmi.sb_type == BLOCK_SIZE_SB64X64) { count_segs(cpi, mi, no_pred_segcounts, temporal_predictor_count, t_unpred_seg_counts, 4, mb_row, mb_col); @@ -338,8 +333,6 @@ void vp9_choose_segmap_coding_method(VP9_COMP *cpi) { } } } - - mb_start = mb_end; } // Work out probability tree for coding segments without prediction diff --git a/vp9/vp9_common.mk b/vp9/vp9_common.mk index d8d95a1..eb152f5 100644 --- a/vp9/vp9_common.mk +++ b/vp9/vp9_common.mk @@ -59,6 +59,8 @@ VP9_COMMON_SRCS-yes += common/vp9_setupintrarecon.h VP9_COMMON_SRCS-yes += common/vp9_swapyv12buffer.h VP9_COMMON_SRCS-yes += common/vp9_systemdependent.h VP9_COMMON_SRCS-yes += common/vp9_textblit.h +VP9_COMMON_SRCS-yes += common/vp9_tile_common.h +VP9_COMMON_SRCS-yes += common/vp9_tile_common.c VP9_COMMON_SRCS-yes += common/vp9_treecoder.h VP9_COMMON_SRCS-yes += common/vp9_invtrans.c VP9_COMMON_SRCS-yes += common/vp9_loopfilter.c diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c index 0b86772..80320c4 100644 --- a/vp9/vp9_cx_iface.c +++ b/vp9/vp9_cx_iface.c @@ -54,7 +54,7 @@ static const struct extraconfig_map extracfg_map[] = { 0, /* noise_sensitivity */ 0, /* Sharpness */ 0, /* static_thresh */ - VP8_ONE_TILE_COLUMN, /* tile_columns */ + 0, /* tile_columns */ 0, /* arnr_max_frames */ 3, /* arnr_strength */ 3, /* arnr_type*/ @@ -171,8 +171,7 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx, RANGE_CHECK_HI(vp8_cfg, noise_sensitivity, 6); - RANGE_CHECK(vp8_cfg, tile_columns, - VP8_ONE_TILE_COLUMN, VP8_FOUR_TILE_COLUMNS); + RANGE_CHECK(vp8_cfg, tile_columns, 0, 6); RANGE_CHECK_HI(vp8_cfg, Sharpness, 7); RANGE_CHECK(vp8_cfg, arnr_max_frames, 0, 15); RANGE_CHECK_HI(vp8_cfg, arnr_strength, 6); diff --git a/vpx/vp8cx.h b/vpx/vp8cx.h index 79bb582..d483c47 100644 --- a/vpx/vp8cx.h +++ b/vpx/vp8cx.h @@ -256,19 +256,6 @@ typedef enum { } vp8e_token_partitions; -/*!\brief VP8 tile column mode - * - * This defines VP9 tiling mode for compressed data, i.e., the number of - * sub-streams in the bitstream. Used for parallelized encoding/decoding. - * - */ - -typedef enum { - VP8_ONE_TILE_COLUMN = 0, - VP8_TWO_TILE_COLUMNS = 1, - VP8_FOUR_TILE_COLUMNS = 2 -} vp8e_tile_column_mode; - /*!\brief VP8 model tuning parameters * * Changes the encoder to tune for certain types of input material.