From 9cd57cf878ab988a254985a13a22eb9c9b8d2b00 Mon Sep 17 00:00:00 2001 From: Fergus Simpson Date: Mon, 12 Jun 2017 17:02:03 -0700 Subject: [PATCH] Make loop-restoration compatible w/ frame_superres There were several places where loop_restoration used the encoded width and height while superres was active. This patch changes it to use the upscaled width and height, since loop_restoration is supposed to occur after superres has done its upscaling. Change-Id: I2b9bbb06b5370618758bf81d8eb63f2eef26af80 --- av1/common/alloccommon.c | 15 ++++++++++---- av1/common/restoration.c | 15 +++++++++----- av1/encoder/encoder.c | 42 ++++++++++++++++++++++++++++------------ av1/encoder/ratectrl.c | 19 ++++++++---------- 4 files changed, 59 insertions(+), 32 deletions(-) diff --git a/av1/common/alloccommon.c b/av1/common/alloccommon.c index 80f6b095f..c37f1ea50 100644 --- a/av1/common/alloccommon.c +++ b/av1/common/alloccommon.c @@ -93,11 +93,18 @@ void av1_free_ref_frame_buffers(BufferPool *pool) { // Assumes cm->rst_info[p].restoration_tilesize is already initialized void av1_alloc_restoration_buffers(AV1_COMMON *cm) { int p; - av1_alloc_restoration_struct(cm, &cm->rst_info[0], cm->width, cm->height); +#if CONFIG_FRAME_SUPERRES + int width = cm->superres_upscaled_width; + int height = cm->superres_upscaled_height; +#else + int width = cm->width; + int height = cm->height; +#endif // CONFIG_FRAME_SUPERRES + av1_alloc_restoration_struct(cm, &cm->rst_info[0], width, height); for (p = 1; p < MAX_MB_PLANE; ++p) - av1_alloc_restoration_struct( - cm, &cm->rst_info[p], ROUND_POWER_OF_TWO(cm->width, cm->subsampling_x), - ROUND_POWER_OF_TWO(cm->height, cm->subsampling_y)); + av1_alloc_restoration_struct(cm, &cm->rst_info[p], + ROUND_POWER_OF_TWO(width, cm->subsampling_x), + ROUND_POWER_OF_TWO(height, cm->subsampling_y)); aom_free(cm->rst_internal.tmpbuf); CHECK_MEM_ERROR(cm, cm->rst_internal.tmpbuf, (int32_t *)aom_memalign(16, RESTORATION_TMPBUF_SIZE)); diff --git a/av1/common/restoration.c b/av1/common/restoration.c index 84c06fed7..8293af154 100644 --- a/av1/common/restoration.c +++ b/av1/common/restoration.c @@ -1261,8 +1261,8 @@ static void loop_restoration_rows(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm, #endif // CONFIG_HIGHBITDEPTH YV12_BUFFER_CONFIG dst_; - yend = AOMMIN(yend, cm->height); - uvend = AOMMIN(uvend, cm->subsampling_y ? (cm->height + 1) >> 1 : cm->height); + yend = AOMMIN(yend, yheight); + uvend = AOMMIN(uvend, uvheight); if (components_pattern == (1 << AOM_PLANE_Y)) { // Only y @@ -1400,11 +1400,16 @@ void av1_loop_restoration_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm, int partial_frame, YV12_BUFFER_CONFIG *dst) { int start_mi_row, end_mi_row, mi_rows_to_filter; start_mi_row = 0; +#if CONFIG_FRAME_SUPERRES + mi_rows_to_filter = + ALIGN_POWER_OF_TWO(cm->superres_upscaled_height, 3) >> MI_SIZE_LOG2; +#else mi_rows_to_filter = cm->mi_rows; - if (partial_frame && cm->mi_rows > 8) { - start_mi_row = cm->mi_rows >> 1; +#endif // CONFIG_FRAME_SUPERRES + if (partial_frame && mi_rows_to_filter > 8) { + start_mi_row = mi_rows_to_filter >> 1; start_mi_row &= 0xfffffff8; - mi_rows_to_filter = AOMMAX(cm->mi_rows / 8, 8); + mi_rows_to_filter = AOMMAX(mi_rows_to_filter / 8, 8); } end_mi_row = start_mi_row + mi_rows_to_filter; loop_restoration_init(&cm->rst_internal, cm->frame_type == KEY_FRAME); diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c index 30938ba0b..30d1188db 100644 --- a/av1/encoder/encoder.c +++ b/av1/encoder/encoder.c @@ -735,13 +735,18 @@ static void alloc_util_frame_buffers(AV1_COMP *cpi) { NULL, NULL)) aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR, "Failed to allocate last frame deblocked buffer"); - if (aom_realloc_frame_buffer(&cpi->trial_frame_rst, cm->width, cm->height, - cm->subsampling_x, cm->subsampling_y, + if (aom_realloc_frame_buffer( + &cpi->trial_frame_rst, +#if CONFIG_FRAME_SUPERRES + cm->superres_upscaled_width, cm->superres_upscaled_height, +#else + cm->width, cm->height, +#endif // CONFIG_FRAME_SUPERRES + cm->subsampling_x, cm->subsampling_y, #if CONFIG_HIGHBITDEPTH - cm->use_highbitdepth, + cm->use_highbitdepth, #endif - AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL, - NULL, NULL)) + AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL, NULL, NULL)) aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR, "Failed to allocate trial restored frame buffer"); int extra_rstbuf_sz = RESTORATION_EXTBUF_SIZE; @@ -3763,19 +3768,29 @@ static void set_frame_size(AV1_COMP *cpi, int width, int height) { "Failed to allocate frame buffer"); #if CONFIG_LOOP_RESTORATION - // TODO(afergs): Use cm->superres_upscaled_(width|height) - set_restoration_tilesize(cm->width, cm->height, cm->rst_info); + set_restoration_tilesize( +#if CONFIG_FRAME_SUPERRES + cm->superres_upscaled_width, cm->superres_upscaled_height, +#else + cm->width, cm->height, +#endif // CONFIG_FRAME_SUPERRES + cm->rst_info); for (int i = 0; i < MAX_MB_PLANE; ++i) cm->rst_info[i].frame_restoration_type = RESTORE_NONE; av1_alloc_restoration_buffers(cm); for (int i = 0; i < MAX_MB_PLANE; ++i) { cpi->rst_search[i].restoration_tilesize = cm->rst_info[i].restoration_tilesize; - av1_alloc_restoration_struct(cm, &cpi->rst_search[i], cm->width, - cm->height); + av1_alloc_restoration_struct(cm, &cpi->rst_search[i], +#if CONFIG_FRAME_SUPERRES + cm->superres_upscaled_width, + cm->superres_upscaled_height); +#else + cm->width, cm->height); +#endif // CONFIG_FRAME_SUPERRES } -#endif // CONFIG_LOOP_RESTORATION - alloc_util_frame_buffers(cpi); +#endif // CONFIG_LOOP_RESTORATION + alloc_util_frame_buffers(cpi); // TODO(afergs): Remove? Gets called anyways. init_motion_estimation(cpi); for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) { @@ -3831,8 +3846,11 @@ static void setup_frame_size(AV1_COMP *cpi) { AV1_COMMON *cm = &cpi->common; cm->superres_upscaled_width = encode_width; cm->superres_upscaled_height = encode_height; - av1_calculate_next_superres_scale(cpi, encode_width, encode_width); + cpi->common.superres_scale_numerator = + av1_calculate_next_superres_scale(cpi, encode_width, encode_width); av1_calculate_superres_size(cm, &encode_width, &encode_height); +// printf("Resize/superres %d x %d -> %d x %d\n", encode_width, encode_height, +// cm->superres_upscaled_width, cm->superres_upscaled_height); #endif // CONFIG_FRAME_SUPERRES set_frame_size(cpi, encode_width, encode_height); diff --git a/av1/encoder/ratectrl.c b/av1/encoder/ratectrl.c index ed6e9e639..9fa6d6aac 100644 --- a/av1/encoder/ratectrl.c +++ b/av1/encoder/ratectrl.c @@ -1704,18 +1704,15 @@ int av1_calculate_next_superres_scale(AV1_COMP *cpi, int width, int height) { (void)height; (void)oxcf; #if RANDOM_SUPERRES - if (cpi->common.frame_type != KEY_FRAME) { - if (oxcf->pass == 2 || oxcf->pass == 0) { - static unsigned int seed = 34567; - int new_num = lcg_rand16(&seed) % 9 + 8; - if (new_num * width / SUPERRES_SCALE_DENOMINATOR * 2 < oxcf->width || - new_num * height / SUPERRES_SCALE_DENOMINATOR * 2 < oxcf->height) - new_num = SUPERRES_SCALE_DENOMINATOR; - cpi->common.superres_scale_numerator = new_num; - return new_num; - } + if (oxcf->pass == 2 || oxcf->pass == 0) { + static unsigned int seed = 34567; + int new_num = lcg_rand16(&seed) % 9 + 8; + if (new_num * width / SUPERRES_SCALE_DENOMINATOR * 2 < oxcf->width || + new_num * height / SUPERRES_SCALE_DENOMINATOR * 2 < oxcf->height) + new_num = SUPERRES_SCALE_DENOMINATOR; + return new_num; } #endif // RANDOM_SUPERRES - return 16; + return SUPERRES_SCALE_DENOMINATOR; } #endif // CONFIG_FRAME_SUPERRES -- GitLab