ext_tile: add 2 tile encoding modes
Added 2 tile encoding modes: TILE_NORMAL mode supports the large-scale tile coding up to 1024 x 1024 tiles; TILE_VR mode supports the large-scale tile coding and also the decoding of a single tile. TILE_NORMAL mode allows the non-vr content to be encoded in multiple tiles without using the coding tool that are designed for vr applications. Change-Id: Id804806a1bbcb916b7f5dc7e2c5509d88f3defcb
This commit is contained in:
Родитель
7a84fd8c68
Коммит
d8cd55f4dd
12
aom/aomcx.h
12
aom/aomcx.h
|
@ -502,6 +502,15 @@ enum aome_enc_control_id {
|
|||
* Experiment: LOOPFILTERING_ACROSS_TILES
|
||||
*/
|
||||
AV1E_SET_TILE_LOOPFILTER,
|
||||
|
||||
/*!\brief Codec control function to set the tile encoding mode to 0 or 1.
|
||||
*
|
||||
* 0 means that the tile encoding mode is TILE_NORMAL, and 1 means that the
|
||||
* tile encoding mode is TILE_VR.
|
||||
*
|
||||
* Experiment: EXT_TILE
|
||||
*/
|
||||
AV1E_SET_TILE_ENCODING_MODE,
|
||||
};
|
||||
|
||||
/*!\brief aom 1-D scaling mode
|
||||
|
@ -703,6 +712,9 @@ AOM_CTRL_USE_TYPE(AV1E_GET_LEVEL, int *)
|
|||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ANS_WINDOW_SIZE_LOG2, unsigned int)
|
||||
#define AOM_CTRL_AV1E_SET_ANS_WINDOW_SIZE_LOG2
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_TILE_ENCODING_MODE, unsigned int)
|
||||
#define AOM_CTRL_AV1E_SET_TILE_ENCODING_MODE
|
||||
/*!\endcond */
|
||||
/*! @} - end defgroup aom_encoder */
|
||||
#ifdef __cplusplus
|
||||
|
|
12
aomenc.c
12
aomenc.c
|
@ -370,6 +370,12 @@ static const arg_def_t tile_cols =
|
|||
static const arg_def_t tile_rows =
|
||||
ARG_DEF(NULL, "tile-rows", 1,
|
||||
"Number of tile rows to use, log2 (set to 0 while threads > 1)");
|
||||
#if CONFIG_EXT_TILE
|
||||
static const arg_def_t tile_encoding_mode =
|
||||
ARG_DEF(NULL, "tile-encoding-mode", 1,
|
||||
"Tile encoding mode (0: normal"
|
||||
" (default), 1: vr)");
|
||||
#endif
|
||||
#if CONFIG_DEPENDENT_HORZTILES
|
||||
static const arg_def_t tile_dependent_rows =
|
||||
ARG_DEF(NULL, "tile-dependent-rows", 1, "Enable dependent Tile rows");
|
||||
|
@ -474,6 +480,9 @@ static const arg_def_t *av1_args[] = { &cpu_used_av1,
|
|||
&static_thresh,
|
||||
&tile_cols,
|
||||
&tile_rows,
|
||||
#if CONFIG_EXT_TILE
|
||||
&tile_encoding_mode,
|
||||
#endif
|
||||
#if CONFIG_DEPENDENT_HORZTILES
|
||||
&tile_dependent_rows,
|
||||
#endif
|
||||
|
@ -522,6 +531,9 @@ static const int av1_arg_ctrl_map[] = { AOME_SET_CPUUSED,
|
|||
AOME_SET_STATIC_THRESHOLD,
|
||||
AV1E_SET_TILE_COLUMNS,
|
||||
AV1E_SET_TILE_ROWS,
|
||||
#if CONFIG_EXT_TILE
|
||||
AV1E_SET_TILE_ENCODING_MODE,
|
||||
#endif
|
||||
#if CONFIG_DEPENDENT_HORZTILES
|
||||
AV1E_SET_TILE_DEPENDENT_ROWS,
|
||||
#endif
|
||||
|
|
|
@ -75,6 +75,9 @@ struct av1_extracfg {
|
|||
#if CONFIG_ANS && ANS_MAX_SYMBOLS
|
||||
int ans_window_size_log2;
|
||||
#endif
|
||||
#if CONFIG_EXT_TILE
|
||||
unsigned int tile_encoding_mode;
|
||||
#endif // CONFIG_EXT_TILE
|
||||
};
|
||||
|
||||
static struct av1_extracfg default_extra_cfg = {
|
||||
|
@ -134,6 +137,9 @@ static struct av1_extracfg default_extra_cfg = {
|
|||
#if CONFIG_ANS && ANS_MAX_SYMBOLS
|
||||
23, // ans_window_size_log2
|
||||
#endif
|
||||
#if CONFIG_EXT_TILE
|
||||
0, // Tile encoding mode is TILE_NORMAL by default.
|
||||
#endif // CONFIG_EXT_TILE
|
||||
};
|
||||
|
||||
struct aom_codec_alg_priv {
|
||||
|
@ -270,6 +276,7 @@ static aom_codec_err_t validate_config(aom_codec_alg_priv_t *ctx,
|
|||
if (extra_cfg->tile_rows != UINT_MAX)
|
||||
RANGE_CHECK(extra_cfg, tile_rows, 1, 64);
|
||||
}
|
||||
RANGE_CHECK_HI(extra_cfg, tile_encoding_mode, 1);
|
||||
#else
|
||||
RANGE_CHECK_HI(extra_cfg, tile_columns, 6);
|
||||
RANGE_CHECK_HI(extra_cfg, tile_rows, 2);
|
||||
|
@ -520,6 +527,7 @@ static aom_codec_err_t set_encoder_config(
|
|||
#endif // CONFIG_EXT_PARTITION
|
||||
oxcf->tile_columns = AOMMIN(extra_cfg->tile_columns, max);
|
||||
oxcf->tile_rows = AOMMIN(extra_cfg->tile_rows, max);
|
||||
oxcf->tile_encoding_mode = extra_cfg->tile_encoding_mode;
|
||||
}
|
||||
#else
|
||||
oxcf->tile_columns = extra_cfg->tile_columns;
|
||||
|
@ -822,6 +830,15 @@ static aom_codec_err_t ctrl_set_frame_parallel_decoding_mode(
|
|||
return update_extra_cfg(ctx, &extra_cfg);
|
||||
}
|
||||
|
||||
#if CONFIG_EXT_TILE
|
||||
static aom_codec_err_t ctrl_set_tile_encoding_mode(aom_codec_alg_priv_t *ctx,
|
||||
va_list args) {
|
||||
struct av1_extracfg extra_cfg = ctx->extra_cfg;
|
||||
extra_cfg.tile_encoding_mode = CAST(AV1E_SET_TILE_ENCODING_MODE, args);
|
||||
return update_extra_cfg(ctx, &extra_cfg);
|
||||
}
|
||||
#endif // CONFIG_EXT_TILE
|
||||
|
||||
static aom_codec_err_t ctrl_set_aq_mode(aom_codec_alg_priv_t *ctx,
|
||||
va_list args) {
|
||||
struct av1_extracfg extra_cfg = ctx->extra_cfg;
|
||||
|
@ -1449,6 +1466,9 @@ static aom_codec_ctrl_fn_map_t encoder_ctrl_maps[] = {
|
|||
#if CONFIG_ANS && ANS_MAX_SYMBOLS
|
||||
{ AV1E_SET_ANS_WINDOW_SIZE_LOG2, ctrl_set_ans_window_size_log2 },
|
||||
#endif
|
||||
#if CONFIG_EXT_TILE
|
||||
{ AV1E_SET_TILE_ENCODING_MODE, ctrl_set_tile_encoding_mode },
|
||||
#endif // CONFIG_EXT_TILE
|
||||
|
||||
// Getters
|
||||
{ AOME_GET_LAST_QUANTIZER, ctrl_get_quantizer },
|
||||
|
|
|
@ -759,7 +759,8 @@ static aom_image_t *decoder_get_frame(aom_codec_alg_priv_t *ctx,
|
|||
yuvconfig2image(&ctx->img, &sd, frame_worker_data->user_priv);
|
||||
|
||||
#if CONFIG_EXT_TILE
|
||||
if (frame_worker_data->pbi->dec_tile_row >= 0) {
|
||||
if (cm->tile_encoding_mode &&
|
||||
frame_worker_data->pbi->dec_tile_row >= 0) {
|
||||
const int tile_row =
|
||||
AOMMIN(frame_worker_data->pbi->dec_tile_row, cm->tile_rows - 1);
|
||||
const int mi_row = tile_row * cm->tile_height;
|
||||
|
@ -774,7 +775,8 @@ static aom_image_t *decoder_get_frame(aom_codec_alg_priv_t *ctx,
|
|||
AOMMIN(cm->tile_height, cm->mi_rows - mi_row) * MI_SIZE;
|
||||
}
|
||||
|
||||
if (frame_worker_data->pbi->dec_tile_col >= 0) {
|
||||
if (cm->tile_encoding_mode &&
|
||||
frame_worker_data->pbi->dec_tile_col >= 0) {
|
||||
const int tile_col =
|
||||
AOMMIN(frame_worker_data->pbi->dec_tile_col, cm->tile_cols - 1);
|
||||
const int mi_col = tile_col * cm->tile_width;
|
||||
|
|
|
@ -861,11 +861,7 @@ int av1_is_intra_filter_switchable(int angle);
|
|||
#endif // CONFIG_INTRA_INTERP
|
||||
#endif // CONFIG_EXT_INTRA
|
||||
|
||||
#if CONFIG_EXT_TILE
|
||||
#define FIXED_TX_TYPE 1
|
||||
#else
|
||||
#define FIXED_TX_TYPE 0
|
||||
#endif
|
||||
|
||||
// Converts block_index for given transform size to index of the block in raster
|
||||
// order.
|
||||
|
|
|
@ -55,6 +55,9 @@ extern "C" {
|
|||
|
||||
// Maximum number of tile rows and tile columns
|
||||
#if CONFIG_EXT_TILE
|
||||
#define TILE_NORMAL 0
|
||||
#define TILE_VR 1
|
||||
|
||||
#define MAX_TILE_ROWS 1024
|
||||
#define MAX_TILE_COLS 1024
|
||||
#else
|
||||
|
|
|
@ -356,6 +356,9 @@ typedef struct AV1Common {
|
|||
#endif // !CONFIG_EXT_TILE
|
||||
int tile_cols, tile_rows;
|
||||
int tile_width, tile_height; // In MI units
|
||||
#if CONFIG_EXT_TILE
|
||||
unsigned int tile_encoding_mode;
|
||||
#endif // CONFIG_EXT_TILE
|
||||
|
||||
#if CONFIG_DEPENDENT_HORZTILES
|
||||
int dependent_horz_tiles;
|
||||
|
|
|
@ -2934,6 +2934,7 @@ static void read_tile_info(AV1Decoder *const pbi,
|
|||
struct aom_read_bit_buffer *const rb) {
|
||||
AV1_COMMON *const cm = &pbi->common;
|
||||
#if CONFIG_EXT_TILE
|
||||
cm->tile_encoding_mode = aom_rb_read_literal(rb, 1);
|
||||
// Read the tile width/height
|
||||
#if CONFIG_EXT_PARTITION
|
||||
if (cm->sb_size == BLOCK_128X128) {
|
||||
|
@ -3051,7 +3052,8 @@ static void get_tile_buffer(const uint8_t *const data_end,
|
|||
const uint8_t **data, aom_decrypt_cb decrypt_cb,
|
||||
void *decrypt_state,
|
||||
TileBufferDec (*const tile_buffers)[MAX_TILE_COLS],
|
||||
int tile_size_bytes, int col, int row) {
|
||||
int tile_size_bytes, int col, int row,
|
||||
unsigned int tile_encoding_mode) {
|
||||
size_t size;
|
||||
|
||||
size_t copy_size = 0;
|
||||
|
@ -3070,8 +3072,9 @@ static void get_tile_buffer(const uint8_t *const data_end,
|
|||
size = mem_get_varsize(*data, tile_size_bytes);
|
||||
}
|
||||
|
||||
// The top bit indicates copy mode
|
||||
if ((size >> (tile_size_bytes * 8 - 1)) == 1) {
|
||||
// If cm->tile_encoding_mode = 1 (i.e. TILE_VR), then the top bit of the tile
|
||||
// header indicates copy mode.
|
||||
if (tile_encoding_mode && (size >> (tile_size_bytes * 8 - 1)) == 1) {
|
||||
// The remaining bits in the top byte signal the row offset
|
||||
int offset = (size >> (tile_size_bytes - 1) * 8) & 0x7f;
|
||||
|
||||
|
@ -3167,7 +3170,7 @@ static void get_tile_buffers(
|
|||
|
||||
get_tile_buffer(tile_col_data_end[c], &pbi->common.error, &data,
|
||||
pbi->decrypt_cb, pbi->decrypt_state, tile_buffers,
|
||||
tile_size_bytes, c, r);
|
||||
tile_size_bytes, c, r, cm->tile_encoding_mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3182,7 +3185,7 @@ static void get_tile_buffers(
|
|||
|
||||
get_tile_buffer(tile_col_data_end[c], &pbi->common.error, &data,
|
||||
pbi->decrypt_cb, pbi->decrypt_state, tile_buffers,
|
||||
tile_size_bytes, c, r);
|
||||
tile_size_bytes, c, r, cm->tile_encoding_mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3548,7 +3551,9 @@ static const uint8_t *decode_tiles(AV1Decoder *pbi, const uint8_t *data,
|
|||
// after the entire frame is decoded.
|
||||
#if !CONFIG_VAR_TX && !CONFIG_PARALLEL_DEBLOCKING && !CONFIG_CB4X4
|
||||
// Loopfilter one tile row.
|
||||
if (cm->lf.filter_level && !cm->skip_loop_filter) {
|
||||
// Note: If out-of-order tile decoding is used(for example, inv_row_order
|
||||
// = 1), the loopfiltering has be done after all tile rows are decoded.
|
||||
if (!inv_row_order && cm->lf.filter_level && !cm->skip_loop_filter) {
|
||||
LFWorkerData *const lf_data = (LFWorkerData *)pbi->lf_worker.data1;
|
||||
const int lf_start = AOMMAX(0, tile_info.mi_row_start - cm->mib_size);
|
||||
const int lf_end = tile_info.mi_row_end - cm->mib_size;
|
||||
|
@ -4842,6 +4847,17 @@ void av1_decode_frame(AV1Decoder *pbi, const uint8_t *data,
|
|||
|
||||
first_partition_size = read_uncompressed_header(
|
||||
pbi, init_read_bit_buffer(pbi, &rb, data, data_end, clear_data));
|
||||
|
||||
#if CONFIG_EXT_TILE
|
||||
// If cm->tile_encoding_mode == TILE_NORMAL, the independent decoding of a
|
||||
// single tile or a section of a frame is not allowed.
|
||||
if (!cm->tile_encoding_mode &&
|
||||
(pbi->dec_tile_row >= 0 || pbi->dec_tile_col >= 0)) {
|
||||
pbi->dec_tile_row = -1;
|
||||
pbi->dec_tile_col = -1;
|
||||
}
|
||||
#endif // CONFIG_EXT_TILE
|
||||
|
||||
#if CONFIG_TILE_GROUPS
|
||||
pbi->first_partition_size = first_partition_size;
|
||||
pbi->uncomp_hdr_size = aom_rb_bytes_read(&rb);
|
||||
|
|
|
@ -3731,6 +3731,8 @@ static void write_tile_info(const AV1_COMMON *const cm,
|
|||
assert(tile_width > 0);
|
||||
assert(tile_height > 0);
|
||||
|
||||
aom_wb_write_literal(wb, cm->tile_encoding_mode, 1);
|
||||
|
||||
// Write the tile sizes
|
||||
#if CONFIG_EXT_PARTITION
|
||||
if (cm->sb_size == BLOCK_128X128) {
|
||||
|
@ -3990,10 +3992,11 @@ static uint32_t write_tiles(AV1_COMP *const cpi, uint8_t *const dst,
|
|||
// tile header: size of this tile, or copy offset
|
||||
uint32_t tile_header = tile_size;
|
||||
|
||||
// Check if this tile is a copy tile.
|
||||
// If the tile_encoding_mode is 1 (i.e. TILE_VR), check if this tile is
|
||||
// a copy tile.
|
||||
// Very low chances to have copy tiles on the key frames, so don't
|
||||
// search on key frames to reduce unnecessary search.
|
||||
if (cm->frame_type != KEY_FRAME) {
|
||||
if (cm->frame_type != KEY_FRAME && cm->tile_encoding_mode) {
|
||||
const int idendical_tile_offset =
|
||||
find_identical_tile(tile_row, tile_col, tile_buffers);
|
||||
|
||||
|
|
|
@ -4824,6 +4824,10 @@ static void encode_frame_to_data_rate(AV1_COMP *cpi, size_t *size,
|
|||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_EXT_TILE
|
||||
cm->tile_encoding_mode = cpi->oxcf.tile_encoding_mode;
|
||||
#endif // CONFIG_EXT_TILE
|
||||
|
||||
#if CONFIG_XIPHRC
|
||||
if (drop_this_frame) {
|
||||
av1_rc_postencode_update_drop_frame(cpi);
|
||||
|
|
|
@ -267,6 +267,9 @@ typedef struct AV1EncoderConfig {
|
|||
#if CONFIG_ANS && ANS_MAX_SYMBOLS
|
||||
int ans_window_size_log2;
|
||||
#endif // CONFIG_ANS && ANS_MAX_SYMBOLS
|
||||
#if CONFIG_EXT_TILE
|
||||
unsigned int tile_encoding_mode;
|
||||
#endif // CONFIG_EXT_TILE
|
||||
} AV1EncoderConfig;
|
||||
|
||||
static INLINE int is_lossless_requested(const AV1EncoderConfig *cfg) {
|
||||
|
|
|
@ -206,6 +206,6 @@ void av1_pick_filter_level(const YV12_BUFFER_CONFIG *sd, AV1_COMP *cpi,
|
|||
// TODO(any): 0 loopfilter level is only necessary if individual tile
|
||||
// decoding is required. We need to communicate this requirement to this
|
||||
// code and force loop filter level 0 only if required.
|
||||
lf->filter_level = 0;
|
||||
if (cm->tile_encoding_mode) lf->filter_level = 0;
|
||||
#endif // CONFIG_EXT_TILE
|
||||
}
|
||||
|
|
|
@ -371,11 +371,7 @@ void av1_set_speed_features_framesize_independent(AV1_COMP *cpi) {
|
|||
sf->disable_filter_search_var_thresh = 0;
|
||||
sf->adaptive_interp_filter_search = 0;
|
||||
sf->allow_partition_search_skip = 0;
|
||||
#if CONFIG_EXT_TILE
|
||||
sf->use_upsampled_references = 0;
|
||||
#else
|
||||
sf->use_upsampled_references = 1;
|
||||
#endif // CONFIG_EXT_TILE
|
||||
#if CONFIG_EXT_INTER
|
||||
sf->disable_wedge_search_var_thresh = 0;
|
||||
sf->fast_wedge_sign_estimate = 0;
|
||||
|
@ -406,12 +402,8 @@ void av1_set_speed_features_framesize_independent(AV1_COMP *cpi) {
|
|||
sf->partition_search_breakout_rate_thr = 0;
|
||||
sf->simple_model_rd_from_var = 0;
|
||||
|
||||
// Set this at the appropriate speed levels
|
||||
#if CONFIG_EXT_TILE
|
||||
sf->use_transform_domain_distortion = 1;
|
||||
#else
|
||||
// Set this at the appropriate speed levels
|
||||
sf->use_transform_domain_distortion = 0;
|
||||
#endif // CONFIG_EXT_TILE
|
||||
|
||||
if (oxcf->mode == GOOD
|
||||
#if CONFIG_XIPHRC
|
||||
|
|
|
@ -30,6 +30,8 @@ const int kTIleSizeInPixels = (kTileSize << 6);
|
|||
const int kImgWidth = 704;
|
||||
const int kImgHeight = 576;
|
||||
|
||||
// This test tests "tile_encoding_mode = TILE_VR" case. The TILE_NORMAL case is
|
||||
// tested by the tile_independence test.
|
||||
class AV1ExtTileTest
|
||||
: public ::libaom_test::EncoderTest,
|
||||
public ::libaom_test::CodecTestWith2Params<libaom_test::TestMode, int> {
|
||||
|
@ -81,6 +83,7 @@ class AV1ExtTileTest
|
|||
// The tile size is 64x64.
|
||||
encoder->Control(AV1E_SET_TILE_COLUMNS, kTileSize);
|
||||
encoder->Control(AV1E_SET_TILE_ROWS, kTileSize);
|
||||
encoder->Control(AV1E_SET_TILE_ENCODING_MODE, 1); // TILE_VR
|
||||
#if CONFIG_EXT_PARTITION
|
||||
// Always use 64x64 max partition.
|
||||
encoder->Control(AV1E_SET_SUPERBLOCK_SIZE, AOM_SUPERBLOCK_SIZE_64X64);
|
||||
|
|
|
@ -62,6 +62,9 @@ class TileIndependenceTest
|
|||
if (video->frame() == 1) {
|
||||
encoder->Control(AV1E_SET_TILE_COLUMNS, n_tile_cols_);
|
||||
encoder->Control(AV1E_SET_TILE_ROWS, n_tile_rows_);
|
||||
#if CONFIG_EXT_TILE
|
||||
encoder->Control(AV1E_SET_TILE_ENCODING_MODE, 0); // TILE_NORMAL
|
||||
#endif // CONFIG_EXT_TILE
|
||||
#if CONFIG_LOOPFILTERING_ACROSS_TILES
|
||||
encoder->Control(AV1E_SET_TILE_LOOPFILTER, 0);
|
||||
#endif // CONFIG_LOOPFILTERING_ACROSS_TILES
|
||||
|
|
Загрузка…
Ссылка в новой задаче