FRAME_SUPERRES: Rework to use scale factor of 8/D
Earlier, the superres scale was in the form of:
N/16, where N ranged from 8 to 16.
We change this to the form:
8/D, where D ranges from 8 to 16.
This helps on the decoder side, by making it possible to work on 8x8
blocks at a time.
Change-Id: I6c72d4b3e8d1c830e61d4bb8d7f6337a100c3064
diff --git a/aom/aom_encoder.h b/aom/aom_encoder.h
index c8fe996..208ba01 100644
--- a/aom/aom_encoder.h
+++ b/aom/aom_encoder.h
@@ -372,21 +372,21 @@
*/
unsigned int rc_resize_mode;
- /*!\brief Frame resize numerator.
+ /*!\brief Frame resize denominator.
*
- * The numerator for resize to use, assuming 16 as the denominator.
+ * The denominator for resize to use, assuming 8 as the numerator.
*
- * Valid numerators are 8 - 16 for now.
+ * Valid denominators are 8 - 16 for now.
*/
- unsigned int rc_resize_numerator;
+ unsigned int rc_resize_denominator;
- /*!\brief Keyframe resize numerator.
+ /*!\brief Keyframe resize denominator.
*
- * The numerator for resize to use, assuming 16 as the denominator.
+ * The denominator for resize to use, assuming 8 as the numerator.
*
- * Valid numerators are 8 - 16 for now.
+ * Valid denominators are 8 - 16 for now.
*/
- unsigned int rc_resize_kf_numerator;
+ unsigned int rc_resize_kf_denominator;
/*!\brief Frame super-resolution scaling mode.
*
@@ -399,27 +399,27 @@
*/
unsigned int rc_superres_mode;
- /*!\brief Frame super-resolution numerator.
+ /*!\brief Frame super-resolution denominator.
*
- * The numerator for superres to use. If fixed it will only change if the
+ * The denominator for superres to use. If fixed it will only change if the
* cumulative scale change over resizing and superres is greater than 1/2;
* this forces superres to reduce scaling.
*
- * Valid numerators are 8 to 16.
+ * Valid denominators are 8 to 16.
*
* Used only by SUPERRES_FIXED.
*/
- unsigned int rc_superres_numerator;
+ unsigned int rc_superres_denominator;
- /*!\brief Keyframe super-resolution numerator.
+ /*!\brief Keyframe super-resolution denominator.
*
- * The numerator for superres to use. If fixed it will only change if the
+ * The denominator for superres to use. If fixed it will only change if the
* cumulative scale change over resizing and superres is greater than 1/2;
* this forces superres to reduce scaling.
*
- * Valid numerators are 8 - 16 for now.
+ * Valid denominators are 8 - 16 for now.
*/
- unsigned int rc_superres_kf_numerator;
+ unsigned int rc_superres_kf_denominator;
/*!\brief Frame super-resolution q threshold.
*
diff --git a/aomenc.c b/aomenc.c
index 99463a3..43ad4bf 100644
--- a/aomenc.c
+++ b/aomenc.c
@@ -290,18 +290,18 @@
ARG_DEF(NULL, "drop-frame", 1, "Temporal resampling threshold (buf %)");
static const arg_def_t resize_mode =
ARG_DEF(NULL, "resize-mode", 1, "Frame resize mode");
-static const arg_def_t resize_numerator =
- ARG_DEF(NULL, "resize-numerator", 1, "Frame resize numerator");
-static const arg_def_t resize_kf_numerator =
- ARG_DEF(NULL, "resize-kf-numerator", 1, "Frame resize keyframe numerator");
+static const arg_def_t resize_denominator =
+ ARG_DEF(NULL, "resize-denominator", 1, "Frame resize denominator");
+static const arg_def_t resize_kf_denominator = ARG_DEF(
+ NULL, "resize-kf-denominator", 1, "Frame resize keyframe denominator");
#if CONFIG_FRAME_SUPERRES
static const arg_def_t superres_mode =
ARG_DEF(NULL, "superres-mode", 1, "Frame super-resolution mode");
-static const arg_def_t superres_numerator =
- ARG_DEF(NULL, "superres-numerator", 1, "Frame super-resolution numerator");
-static const arg_def_t superres_kf_numerator =
- ARG_DEF(NULL, "superres-kf-numerator", 1,
- "Frame super-resolution keyframe numerator");
+static const arg_def_t superres_denominator = ARG_DEF(
+ NULL, "superres-denominator", 1, "Frame super-resolution denominator");
+static const arg_def_t superres_kf_denominator =
+ ARG_DEF(NULL, "superres-kf-denominator", 1,
+ "Frame super-resolution keyframe denominator");
static const arg_def_t superres_qthresh = ARG_DEF(
NULL, "superres-qthresh", 1, "Frame super-resolution qindex threshold");
static const arg_def_t superres_kf_qthresh =
@@ -333,12 +333,12 @@
ARG_DEF(NULL, "buf-optimal-sz", 1, "Client optimal buffer size (ms)");
static const arg_def_t *rc_args[] = { &dropframe_thresh,
&resize_mode,
- &resize_numerator,
- &resize_kf_numerator,
+ &resize_denominator,
+ &resize_kf_denominator,
#if CONFIG_FRAME_SUPERRES
&superres_mode,
- &superres_numerator,
- &superres_kf_numerator,
+ &superres_denominator,
+ &superres_kf_denominator,
&superres_qthresh,
&superres_kf_qthresh,
#endif // CONFIG_FRAME_SUPERRES
@@ -1057,17 +1057,17 @@
config->cfg.rc_dropframe_thresh = arg_parse_uint(&arg);
} else if (arg_match(&arg, &resize_mode, argi)) {
config->cfg.rc_resize_mode = arg_parse_uint(&arg);
- } else if (arg_match(&arg, &resize_numerator, argi)) {
- config->cfg.rc_resize_numerator = arg_parse_uint(&arg);
- } else if (arg_match(&arg, &resize_kf_numerator, argi)) {
- config->cfg.rc_resize_kf_numerator = arg_parse_uint(&arg);
+ } else if (arg_match(&arg, &resize_denominator, argi)) {
+ config->cfg.rc_resize_denominator = arg_parse_uint(&arg);
+ } else if (arg_match(&arg, &resize_kf_denominator, argi)) {
+ config->cfg.rc_resize_kf_denominator = arg_parse_uint(&arg);
#if CONFIG_FRAME_SUPERRES
} else if (arg_match(&arg, &superres_mode, argi)) {
config->cfg.rc_superres_mode = arg_parse_uint(&arg);
- } else if (arg_match(&arg, &superres_numerator, argi)) {
- config->cfg.rc_superres_numerator = arg_parse_uint(&arg);
- } else if (arg_match(&arg, &superres_kf_numerator, argi)) {
- config->cfg.rc_superres_kf_numerator = arg_parse_uint(&arg);
+ } else if (arg_match(&arg, &superres_denominator, argi)) {
+ config->cfg.rc_superres_denominator = arg_parse_uint(&arg);
+ } else if (arg_match(&arg, &superres_kf_denominator, argi)) {
+ config->cfg.rc_superres_kf_denominator = arg_parse_uint(&arg);
} else if (arg_match(&arg, &superres_qthresh, argi)) {
config->cfg.rc_superres_qthresh = arg_parse_uint(&arg);
} else if (arg_match(&arg, &superres_kf_qthresh, argi)) {
@@ -1286,12 +1286,12 @@
#endif // CONFIG_EXT_TILE
SHOW(rc_dropframe_thresh);
SHOW(rc_resize_mode);
- SHOW(rc_resize_numerator);
- SHOW(rc_resize_kf_numerator);
+ SHOW(rc_resize_denominator);
+ SHOW(rc_resize_kf_denominator);
#if CONFIG_FRAME_SUPERRES
SHOW(rc_superres_mode);
- SHOW(rc_superres_numerator);
- SHOW(rc_superres_kf_numerator);
+ SHOW(rc_superres_denominator);
+ SHOW(rc_superres_kf_denominator);
SHOW(rc_superres_qthresh);
SHOW(rc_superres_kf_qthresh);
#endif // CONFIG_FRAME_SUPERRES
diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c
index 457c32c..2444d32 100644
--- a/av1/av1_cx_iface.c
+++ b/av1/av1_cx_iface.c
@@ -251,16 +251,16 @@
}
RANGE_CHECK_HI(cfg, rc_resize_mode, RESIZE_MODES - 1);
- RANGE_CHECK(cfg, rc_resize_numerator, SCALE_DENOMINATOR / 2,
- SCALE_DENOMINATOR);
- RANGE_CHECK(cfg, rc_resize_kf_numerator, SCALE_DENOMINATOR / 2,
- SCALE_DENOMINATOR);
+ RANGE_CHECK(cfg, rc_resize_denominator, SCALE_NUMERATOR,
+ SCALE_NUMERATOR << 1);
+ RANGE_CHECK(cfg, rc_resize_kf_denominator, SCALE_NUMERATOR,
+ SCALE_NUMERATOR << 1);
#if CONFIG_FRAME_SUPERRES
RANGE_CHECK_HI(cfg, rc_superres_mode, SUPERRES_MODES - 1);
- RANGE_CHECK(cfg, rc_superres_numerator, SCALE_DENOMINATOR / 2,
- SCALE_DENOMINATOR);
- RANGE_CHECK(cfg, rc_superres_kf_numerator, SCALE_DENOMINATOR / 2,
- SCALE_DENOMINATOR);
+ RANGE_CHECK(cfg, rc_superres_denominator, SCALE_NUMERATOR,
+ SCALE_NUMERATOR << 1);
+ RANGE_CHECK(cfg, rc_superres_kf_denominator, SCALE_NUMERATOR,
+ SCALE_NUMERATOR << 1);
RANGE_CHECK(cfg, rc_superres_qthresh, 1, 63);
RANGE_CHECK(cfg, rc_superres_kf_qthresh, 1, 63);
#endif // CONFIG_FRAME_SUPERRES
@@ -516,17 +516,18 @@
oxcf->over_shoot_pct = cfg->rc_overshoot_pct;
oxcf->resize_mode = (RESIZE_MODE)cfg->rc_resize_mode;
- oxcf->resize_scale_numerator = (uint8_t)cfg->rc_resize_numerator;
- oxcf->resize_kf_scale_numerator = (uint8_t)cfg->rc_resize_kf_numerator;
+ oxcf->resize_scale_denominator = (uint8_t)cfg->rc_resize_denominator;
+ oxcf->resize_kf_scale_denominator = (uint8_t)cfg->rc_resize_kf_denominator;
if (oxcf->resize_mode == RESIZE_FIXED &&
- oxcf->resize_scale_numerator == SCALE_DENOMINATOR &&
- oxcf->resize_kf_scale_numerator == SCALE_DENOMINATOR)
+ oxcf->resize_scale_denominator == SCALE_NUMERATOR &&
+ oxcf->resize_kf_scale_denominator == SCALE_NUMERATOR)
oxcf->resize_mode = RESIZE_NONE;
#if CONFIG_FRAME_SUPERRES
oxcf->superres_mode = (SUPERRES_MODE)cfg->rc_superres_mode;
- oxcf->superres_scale_numerator = (uint8_t)cfg->rc_superres_numerator;
- oxcf->superres_kf_scale_numerator = (uint8_t)cfg->rc_superres_kf_numerator;
+ oxcf->superres_scale_denominator = (uint8_t)cfg->rc_superres_denominator;
+ oxcf->superres_kf_scale_denominator =
+ (uint8_t)cfg->rc_superres_kf_denominator;
oxcf->superres_qthresh =
extra_cfg->lossless ? 255
: av1_quantizer_to_qindex(cfg->rc_superres_qthresh);
@@ -535,8 +536,8 @@
? 255
: av1_quantizer_to_qindex(cfg->rc_superres_kf_qthresh);
if (oxcf->superres_mode == SUPERRES_FIXED &&
- oxcf->superres_scale_numerator == SCALE_DENOMINATOR &&
- oxcf->superres_kf_scale_numerator == SCALE_DENOMINATOR)
+ oxcf->superres_scale_denominator == SCALE_NUMERATOR &&
+ oxcf->superres_kf_scale_denominator == SCALE_NUMERATOR)
oxcf->superres_mode = SUPERRES_NONE;
if (oxcf->superres_mode == SUPERRES_QTHRESH &&
oxcf->superres_qthresh == 255 && oxcf->superres_kf_qthresh == 255)
@@ -1646,16 +1647,16 @@
25, // g_lag_in_frames
- 0, // rc_dropframe_thresh
- RESIZE_NONE, // rc_resize_mode
- SCALE_DENOMINATOR, // rc_resize_numerator
- SCALE_DENOMINATOR, // rc_resize_kf_numerator
+ 0, // rc_dropframe_thresh
+ RESIZE_NONE, // rc_resize_mode
+ SCALE_NUMERATOR, // rc_resize_denominator
+ SCALE_NUMERATOR, // rc_resize_kf_denominator
- 0, // rc_superres_mode
- SCALE_DENOMINATOR, // rc_superres_numerator
- SCALE_DENOMINATOR, // rc_superres_kf_numerator
- 63, // rc_superres_qthresh
- 63, // rc_superres_kf_qthresh
+ 0, // rc_superres_mode
+ SCALE_NUMERATOR, // rc_superres_denominator
+ SCALE_NUMERATOR, // rc_superres_kf_denominator
+ 63, // rc_superres_qthresh
+ 63, // rc_superres_kf_qthresh
AOM_VBR, // rc_end_usage
{ NULL, 0 }, // rc_twopass_stats_in
diff --git a/av1/common/enums.h b/av1/common/enums.h
index c1d084d..aeae71c 100644
--- a/av1/common/enums.h
+++ b/av1/common/enums.h
@@ -736,7 +736,7 @@
#if CONFIG_FRAME_SUPERRES
#define SUPERRES_SCALE_BITS 3
-#define SUPERRES_SCALE_NUMERATOR_MIN 8
+#define SUPERRES_SCALE_DENOMINATOR_MIN 8
#endif // CONFIG_FRAME_SUPERRES
#if CONFIG_LPF_DIRECT
diff --git a/av1/common/onyxc_int.h b/av1/common/onyxc_int.h
index 7035825..ec6c98a 100644
--- a/av1/common/onyxc_int.h
+++ b/av1/common/onyxc_int.h
@@ -368,8 +368,8 @@
loop_filter_info_n lf_info;
#if CONFIG_FRAME_SUPERRES
- // The numerator of the superres scale; the denominator is fixed.
- uint8_t superres_scale_numerator;
+ // The denominator of the superres scale; the numerator is fixed.
+ uint8_t superres_scale_denominator;
int superres_upscaled_width;
int superres_upscaled_height;
#endif // CONFIG_FRAME_SUPERRES
diff --git a/av1/common/resize.c b/av1/common/resize.c
index 125f755..fd66ad9 100644
--- a/av1/common/resize.c
+++ b/av1/common/resize.c
@@ -1168,24 +1168,22 @@
}
}
-void av1_calculate_scaled_size(int *width, int *height, int num) {
- if (num != SCALE_DENOMINATOR) {
- *width = *width * num / SCALE_DENOMINATOR;
- *height = *height * num / SCALE_DENOMINATOR;
+void av1_calculate_scaled_size(int *width, int *height, int denom) {
+ if (denom != SCALE_NUMERATOR) {
+ *width = *width * SCALE_NUMERATOR / denom;
+ *height = *height * SCALE_NUMERATOR / denom;
// Make width and height even
*width += *width & 1;
*height += *height & 1;
}
}
-// Inverse of av1_calculate_scaled_size() above: calculates the original size
-// from the given scaled dimensions and the scale numerator.
-void av1_calculate_unscaled_size(int *width, int *height, int num) {
- if (num != SCALE_DENOMINATOR) {
+void av1_calculate_unscaled_size(int *width, int *height, int denom) {
+ if (denom != SCALE_NUMERATOR) {
// Note: av1_calculate_scaled_size() rounds *up* after division when the
// resulting dimensions are odd. So here, we round *down*.
- *width = *width * SCALE_DENOMINATOR / num;
- *height = *height * SCALE_DENOMINATOR / num;
+ *width = *width * denom / SCALE_NUMERATOR;
+ *height = *height * denom / SCALE_NUMERATOR;
}
}
diff --git a/av1/common/resize.h b/av1/common/resize.h
index 47dbf21..7834dfa 100644
--- a/av1/common/resize.h
+++ b/av1/common/resize.h
@@ -86,19 +86,19 @@
YV12_BUFFER_CONFIG *scaled);
// Calculates the scaled size from the given original dimensions and the scale
-// numerator.
-void av1_calculate_scaled_size(int *width, int *height, int num);
+// denominator.
+void av1_calculate_scaled_size(int *width, int *height, int denom);
// Inverse of av1_calculate_scaled_size() above: calculates the original size
-// from the given scaled dimensions and the scale numerator.
-void av1_calculate_unscaled_size(int *width, int *height, int num);
+// from the given scaled dimensions and the scale denominator.
+void av1_calculate_unscaled_size(int *width, int *height, int denom);
#if CONFIG_FRAME_SUPERRES
void av1_superres_upscale(AV1_COMMON *cm, BufferPool *const pool);
// Returns 1 if a superres upscaled frame is unscaled and 0 otherwise.
static INLINE int av1_superres_unscaled(const AV1_COMMON *cm) {
- return (cm->superres_scale_numerator == SCALE_DENOMINATOR);
+ return (cm->superres_scale_denominator == SCALE_NUMERATOR);
}
#endif // CONFIG_FRAME_SUPERRES
diff --git a/av1/common/restoration.c b/av1/common/restoration.c
index 613ad83..fb47b66 100644
--- a/av1/common/restoration.c
+++ b/av1/common/restoration.c
@@ -1782,8 +1782,8 @@
#if CONFIG_FRAME_SUPERRES
const int frame_w = cm->superres_upscaled_width;
const int frame_h = cm->superres_upscaled_height;
- const int mi_to_px = MI_SIZE * cm->superres_scale_numerator;
- const int denom = SCALE_DENOMINATOR;
+ const int mi_to_px = MI_SIZE * SCALE_NUMERATOR;
+ const int denom = cm->superres_scale_denominator;
#else
const int frame_w = cm->width;
const int frame_h = cm->height;
diff --git a/av1/common/scale.h b/av1/common/scale.h
index 3aa61eb..900e6bf 100644
--- a/av1/common/scale.h
+++ b/av1/common/scale.h
@@ -19,7 +19,7 @@
extern "C" {
#endif
-#define SCALE_DENOMINATOR 16
+#define SCALE_NUMERATOR 8
#define REF_SCALE_SHIFT 14
#define REF_NO_SCALE (1 << REF_SCALE_SHIFT)
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index c2a48c4..e140847 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -3038,15 +3038,15 @@
cm->superres_upscaled_width = *width;
cm->superres_upscaled_height = *height;
if (aom_rb_read_bit(rb)) {
- cm->superres_scale_numerator =
+ cm->superres_scale_denominator =
(uint8_t)aom_rb_read_literal(rb, SUPERRES_SCALE_BITS);
- cm->superres_scale_numerator += SUPERRES_SCALE_NUMERATOR_MIN;
+ cm->superres_scale_denominator += SUPERRES_SCALE_DENOMINATOR_MIN;
// Don't edit cm->width or cm->height directly, or the buffers won't get
// resized correctly
- av1_calculate_scaled_size(width, height, cm->superres_scale_numerator);
+ av1_calculate_scaled_size(width, height, cm->superres_scale_denominator);
} else {
// 1:1 scaling - ie. no scaling, scale not provided
- cm->superres_scale_numerator = SCALE_DENOMINATOR;
+ cm->superres_scale_denominator = SCALE_NUMERATOR;
}
}
#endif // CONFIG_FRAME_SUPERRES
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index 799ee81..302b56c 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -4249,12 +4249,12 @@
static void write_superres_scale(const AV1_COMMON *const cm,
struct aom_write_bit_buffer *wb) {
// First bit is whether to to scale or not
- if (cm->superres_scale_numerator == SCALE_DENOMINATOR) {
+ if (cm->superres_scale_denominator == SCALE_NUMERATOR) {
aom_wb_write_bit(wb, 0); // no scaling
} else {
aom_wb_write_bit(wb, 1); // scaling, write scale factor
aom_wb_write_literal(
- wb, cm->superres_scale_numerator - SUPERRES_SCALE_NUMERATOR_MIN,
+ wb, cm->superres_scale_denominator - SUPERRES_SCALE_DENOMINATOR_MIN,
SUPERRES_SCALE_BITS);
}
}
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index 2de36de..46cf279 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -3088,7 +3088,7 @@
av1_loop_filter_init(cm);
#if CONFIG_FRAME_SUPERRES
- cm->superres_scale_numerator = SCALE_DENOMINATOR;
+ cm->superres_scale_denominator = SCALE_NUMERATOR;
cm->superres_upscaled_width = oxcf->width;
cm->superres_upscaled_height = oxcf->height;
#endif // CONFIG_FRAME_SUPERRES
@@ -4429,21 +4429,21 @@
// Choose an arbitrary random number
static unsigned int seed = 56789;
const AV1EncoderConfig *oxcf = &cpi->oxcf;
- if (oxcf->pass == 1) return SCALE_DENOMINATOR;
- uint8_t new_num = SCALE_DENOMINATOR;
+ if (oxcf->pass == 1) return SCALE_NUMERATOR;
+ uint8_t new_denom = SCALE_NUMERATOR;
switch (oxcf->resize_mode) {
- case RESIZE_NONE: new_num = SCALE_DENOMINATOR; break;
+ case RESIZE_NONE: new_denom = SCALE_NUMERATOR; break;
case RESIZE_FIXED:
if (cpi->common.frame_type == KEY_FRAME)
- new_num = oxcf->resize_kf_scale_numerator;
+ new_denom = oxcf->resize_kf_scale_denominator;
else
- new_num = oxcf->resize_scale_numerator;
+ new_denom = oxcf->resize_scale_denominator;
break;
- case RESIZE_RANDOM: new_num = lcg_rand16(&seed) % 9 + 8; break;
+ case RESIZE_RANDOM: new_denom = lcg_rand16(&seed) % 9 + 8; break;
default: assert(0);
}
- return new_num;
+ return new_denom;
}
#if CONFIG_FRAME_SUPERRES
@@ -4451,19 +4451,19 @@
// Choose an arbitrary random number
static unsigned int seed = 34567;
const AV1EncoderConfig *oxcf = &cpi->oxcf;
- if (oxcf->pass == 1) return SCALE_DENOMINATOR;
- uint8_t new_num = SCALE_DENOMINATOR;
+ if (oxcf->pass == 1) return SCALE_NUMERATOR;
+ uint8_t new_denom = SCALE_NUMERATOR;
int bottom_index, top_index, q, qthresh;
switch (oxcf->superres_mode) {
- case SUPERRES_NONE: new_num = SCALE_DENOMINATOR; break;
+ case SUPERRES_NONE: new_denom = SCALE_NUMERATOR; break;
case SUPERRES_FIXED:
if (cpi->common.frame_type == KEY_FRAME)
- new_num = oxcf->superres_kf_scale_numerator;
+ new_denom = oxcf->superres_kf_scale_denominator;
else
- new_num = oxcf->superres_scale_numerator;
+ new_denom = oxcf->superres_scale_denominator;
break;
- case SUPERRES_RANDOM: new_num = lcg_rand16(&seed) % 9 + 8; break;
+ case SUPERRES_RANDOM: new_denom = lcg_rand16(&seed) % 9 + 8; break;
case SUPERRES_QTHRESH:
qthresh = (cpi->common.frame_type == KEY_FRAME ? oxcf->superres_kf_qthresh
: oxcf->superres_qthresh);
@@ -4471,74 +4471,86 @@
q = av1_rc_pick_q_and_bounds(cpi, cpi->oxcf.width, cpi->oxcf.height,
&bottom_index, &top_index);
if (q < qthresh) {
- new_num = SCALE_DENOMINATOR;
+ new_denom = SCALE_NUMERATOR;
} else {
- new_num = SCALE_DENOMINATOR - 1 - ((q - qthresh) >> 3);
- new_num = AOMMAX(SCALE_DENOMINATOR / 2, new_num);
- // printf("SUPERRES: q %d, qthresh %d: num %d\n", q, qthresh, new_num);
+ new_denom = SCALE_NUMERATOR + 1 + ((q - qthresh) >> 3);
+ new_denom = AOMMIN(SCALE_NUMERATOR << 1, new_denom);
+ // printf("SUPERRES: q %d, qthresh %d: denom %d\n", q, qthresh,
+ // new_denom);
}
break;
default: assert(0);
}
- return new_num;
+ return new_denom;
}
+static int dimension_is_ok(int orig_dim, int resized_dim, int denom) {
+ return (resized_dim * SCALE_NUMERATOR >= orig_dim * denom / 2);
+}
+
+static int dimensions_are_ok(int owidth, int oheight, size_params_type *rsz) {
+ return dimension_is_ok(owidth, rsz->resize_width, rsz->superres_denom) &&
+ dimension_is_ok(oheight, rsz->resize_height, rsz->superres_denom);
+}
+
+#define DIVIDE_AND_ROUND(x, y) (((x) + ((y) >> 1)) / (y))
+
static int validate_size_scales(RESIZE_MODE resize_mode,
SUPERRES_MODE superres_mode, int owidth,
int oheight, size_params_type *rsz) {
- if (rsz->resize_width * rsz->superres_num >= SCALE_DENOMINATOR * owidth / 2 &&
- rsz->resize_height * rsz->superres_num >= SCALE_DENOMINATOR * oheight / 2)
+ if (dimensions_are_ok(owidth, oheight, rsz)) { // Nothing to do.
return 1;
- int resize_num = AOMMIN(((rsz->resize_width * 16 + owidth / 2) / owidth),
- ((rsz->resize_height * 16 + oheight / 2) / oheight));
+ }
+
+ // Calculate current resize scale.
+ int resize_denom =
+ AOMMAX(DIVIDE_AND_ROUND(owidth * SCALE_NUMERATOR, rsz->resize_width),
+ DIVIDE_AND_ROUND(oheight * SCALE_NUMERATOR, rsz->resize_height));
+
if (resize_mode != RESIZE_RANDOM && superres_mode == SUPERRES_RANDOM) {
- rsz->superres_num =
- (SCALE_DENOMINATOR * SCALE_DENOMINATOR + 2 * resize_num - 1) /
- (2 * resize_num);
- if (rsz->resize_width * rsz->superres_num <
- SCALE_DENOMINATOR * owidth / 2 ||
- rsz->resize_height * rsz->superres_num <
- SCALE_DENOMINATOR * oheight / 2) {
- if (rsz->superres_num < SCALE_DENOMINATOR) rsz->superres_num++;
+ // Alter superres scale as needed to enforce conformity.
+ rsz->superres_denom =
+ (2 * SCALE_NUMERATOR * SCALE_NUMERATOR) / resize_denom;
+ if (!dimensions_are_ok(owidth, oheight, rsz)) {
+ if (rsz->superres_denom > SCALE_NUMERATOR) --rsz->superres_denom;
}
} else if (resize_mode == RESIZE_RANDOM && superres_mode != SUPERRES_RANDOM) {
- resize_num =
- (SCALE_DENOMINATOR * SCALE_DENOMINATOR + 2 * rsz->superres_num - 1) /
- (2 * rsz->superres_num);
+ // Alter resize scale as needed to enforce conformity.
+ resize_denom =
+ (2 * SCALE_NUMERATOR * SCALE_NUMERATOR) / rsz->superres_denom;
rsz->resize_width = owidth;
rsz->resize_height = oheight;
av1_calculate_scaled_size(&rsz->resize_width, &rsz->resize_height,
- resize_num);
- if (rsz->resize_width * rsz->superres_num <
- SCALE_DENOMINATOR * owidth / 2 ||
- rsz->resize_height * rsz->superres_num <
- SCALE_DENOMINATOR * oheight / 2) {
- if (resize_num < SCALE_DENOMINATOR) resize_num++;
+ resize_denom);
+ if (!dimensions_are_ok(owidth, oheight, rsz)) {
+ if (resize_denom > SCALE_NUMERATOR) {
+ --resize_denom;
+ rsz->resize_width = owidth;
+ rsz->resize_height = oheight;
+ av1_calculate_scaled_size(&rsz->resize_width, &rsz->resize_height,
+ resize_denom);
+ }
}
} else if (resize_mode == RESIZE_RANDOM && superres_mode == SUPERRES_RANDOM) {
+ // Alter both resize and superres scales as needed to enforce conformity.
do {
- if (resize_num < rsz->superres_num)
- ++resize_num;
+ if (resize_denom > rsz->superres_denom)
+ --resize_denom;
else
- ++rsz->superres_num;
+ --rsz->superres_denom;
rsz->resize_width = owidth;
rsz->resize_height = oheight;
av1_calculate_scaled_size(&rsz->resize_width, &rsz->resize_height,
- resize_num);
- } while ((rsz->resize_width * rsz->superres_num <
- SCALE_DENOMINATOR * owidth / 2 ||
- rsz->resize_height * rsz->superres_num <
- SCALE_DENOMINATOR * oheight / 2) &&
- (resize_num < SCALE_DENOMINATOR ||
- rsz->superres_num < SCALE_DENOMINATOR));
- } else {
+ resize_denom);
+ } while (!dimensions_are_ok(owidth, oheight, rsz) &&
+ (resize_denom > SCALE_NUMERATOR ||
+ rsz->superres_denom > SCALE_NUMERATOR));
+ } else { // We are allowed to alter neither resize scale nor superres scale.
return 0;
}
- if (rsz->resize_width * rsz->superres_num >= SCALE_DENOMINATOR * owidth / 2 &&
- rsz->resize_height * rsz->superres_num >= SCALE_DENOMINATOR * oheight / 2)
- return 1;
- return 0;
+ return dimensions_are_ok(owidth, oheight, rsz);
}
+#undef DIVIDE_AND_ROUND
#endif // CONFIG_FRAME_SUPERRES
// Calculates resize and superres params for next frame
@@ -4548,24 +4560,24 @@
oxcf->width,
oxcf->height,
#if CONFIG_FRAME_SUPERRES
- SCALE_DENOMINATOR
+ SCALE_NUMERATOR
#endif // CONFIG_FRAME_SUPERRES
};
- int resize_num;
+ int resize_denom;
if (oxcf->pass == 1) return rsz;
if (cpi->resize_pending_width && cpi->resize_pending_height) {
rsz.resize_width = cpi->resize_pending_width;
rsz.resize_height = cpi->resize_pending_height;
cpi->resize_pending_width = cpi->resize_pending_height = 0;
} else {
- resize_num = calculate_next_resize_scale(cpi);
+ resize_denom = calculate_next_resize_scale(cpi);
rsz.resize_width = cpi->oxcf.width;
rsz.resize_height = cpi->oxcf.height;
av1_calculate_scaled_size(&rsz.resize_width, &rsz.resize_height,
- resize_num);
+ resize_denom);
}
#if CONFIG_FRAME_SUPERRES
- rsz.superres_num = calculate_next_superres_scale(cpi);
+ rsz.superres_denom = calculate_next_superres_scale(cpi);
if (!validate_size_scales(oxcf->resize_mode, oxcf->superres_mode, oxcf->width,
oxcf->height, &rsz))
assert(0 && "Invalid scale parameters");
@@ -4581,8 +4593,8 @@
AV1_COMMON *cm = &cpi->common;
cm->superres_upscaled_width = encode_width;
cm->superres_upscaled_height = encode_height;
- cm->superres_scale_numerator = rsz->superres_num;
- av1_calculate_scaled_size(&encode_width, &encode_height, rsz->superres_num);
+ cm->superres_scale_denominator = rsz->superres_denom;
+ av1_calculate_scaled_size(&encode_width, &encode_height, rsz->superres_denom);
#endif // CONFIG_FRAME_SUPERRES
set_frame_size(cpi, encode_width, encode_height);
}
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index 27f96b5..eb779a3 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -218,14 +218,14 @@
#endif
// Internal frame size scaling.
RESIZE_MODE resize_mode;
- uint8_t resize_scale_numerator;
- uint8_t resize_kf_scale_numerator;
+ uint8_t resize_scale_denominator;
+ uint8_t resize_kf_scale_denominator;
#if CONFIG_FRAME_SUPERRES
// Frame Super-Resolution size scaling.
SUPERRES_MODE superres_mode;
- uint8_t superres_scale_numerator;
- uint8_t superres_kf_scale_numerator;
+ uint8_t superres_scale_denominator;
+ uint8_t superres_kf_scale_denominator;
int superres_qthresh;
int superres_kf_qthresh;
#endif // CONFIG_FRAME_SUPERRES
diff --git a/av1/encoder/pickrst.c b/av1/encoder/pickrst.c
index 28f3a0c..3da7789 100644
--- a/av1/encoder/pickrst.c
+++ b/av1/encoder/pickrst.c
@@ -546,9 +546,9 @@
// top-left and bottom-right of the tile.
if (!av1_superres_unscaled(cm)) {
av1_calculate_unscaled_size(&tile_col_start, &tile_row_start,
- cm->superres_scale_numerator);
+ cm->superres_scale_denominator);
av1_calculate_unscaled_size(&tile_col_end, &tile_row_end,
- cm->superres_scale_numerator);
+ cm->superres_scale_denominator);
// Make sure we don't fall off the bottom-right of the frame.
tile_col_end = AOMMIN(tile_col_end, ctxt->plane_width);
tile_row_end = AOMMIN(tile_row_end, ctxt->plane_height);
diff --git a/av1/encoder/ratectrl.h b/av1/encoder/ratectrl.h
index 9172ca7..8b410e7 100644
--- a/av1/encoder/ratectrl.h
+++ b/av1/encoder/ratectrl.h
@@ -53,7 +53,7 @@
int resize_width;
int resize_height;
#if CONFIG_FRAME_SUPERRES
- uint8_t superres_num;
+ uint8_t superres_denom;
#endif // CONFIG_FRAME_SUPERRES
} size_params_type;