Commit de71d142 authored by Urvang Joshi's avatar Urvang Joshi

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
parent e61923fa
...@@ -372,21 +372,21 @@ typedef struct aom_codec_enc_cfg { ...@@ -372,21 +372,21 @@ typedef struct aom_codec_enc_cfg {
*/ */
unsigned int rc_resize_mode; 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. /*!\brief Frame super-resolution scaling mode.
* *
...@@ -399,27 +399,27 @@ typedef struct aom_codec_enc_cfg { ...@@ -399,27 +399,27 @@ typedef struct aom_codec_enc_cfg {
*/ */
unsigned int rc_superres_mode; 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; * cumulative scale change over resizing and superres is greater than 1/2;
* this forces superres to reduce scaling. * this forces superres to reduce scaling.
* *
* Valid numerators are 8 to 16. * Valid denominators are 8 to 16.
* *
* Used only by SUPERRES_FIXED. * 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; * cumulative scale change over resizing and superres is greater than 1/2;
* this forces superres to reduce scaling. * 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. /*!\brief Frame super-resolution q threshold.
* *
......
...@@ -290,18 +290,18 @@ static const arg_def_t dropframe_thresh = ...@@ -290,18 +290,18 @@ static const arg_def_t dropframe_thresh =
ARG_DEF(NULL, "drop-frame", 1, "Temporal resampling threshold (buf %)"); ARG_DEF(NULL, "drop-frame", 1, "Temporal resampling threshold (buf %)");
static const arg_def_t resize_mode = static const arg_def_t resize_mode =
ARG_DEF(NULL, "resize-mode", 1, "Frame resize mode"); ARG_DEF(NULL, "resize-mode", 1, "Frame resize mode");
static const arg_def_t resize_numerator = static const arg_def_t resize_denominator =
ARG_DEF(NULL, "resize-numerator", 1, "Frame resize numerator"); ARG_DEF(NULL, "resize-denominator", 1, "Frame resize denominator");
static const arg_def_t resize_kf_numerator = static const arg_def_t resize_kf_denominator = ARG_DEF(
ARG_DEF(NULL, "resize-kf-numerator", 1, "Frame resize keyframe numerator"); NULL, "resize-kf-denominator", 1, "Frame resize keyframe denominator");
#if CONFIG_FRAME_SUPERRES #if CONFIG_FRAME_SUPERRES
static const arg_def_t superres_mode = static const arg_def_t superres_mode =
ARG_DEF(NULL, "superres-mode", 1, "Frame super-resolution mode"); ARG_DEF(NULL, "superres-mode", 1, "Frame super-resolution mode");
static const arg_def_t superres_numerator = static const arg_def_t superres_denominator = ARG_DEF(
ARG_DEF(NULL, "superres-numerator", 1, "Frame super-resolution numerator"); NULL, "superres-denominator", 1, "Frame super-resolution denominator");
static const arg_def_t superres_kf_numerator = static const arg_def_t superres_kf_denominator =
ARG_DEF(NULL, "superres-kf-numerator", 1, ARG_DEF(NULL, "superres-kf-denominator", 1,
"Frame super-resolution keyframe numerator"); "Frame super-resolution keyframe denominator");
static const arg_def_t superres_qthresh = ARG_DEF( static const arg_def_t superres_qthresh = ARG_DEF(
NULL, "superres-qthresh", 1, "Frame super-resolution qindex threshold"); NULL, "superres-qthresh", 1, "Frame super-resolution qindex threshold");
static const arg_def_t superres_kf_qthresh = static const arg_def_t superres_kf_qthresh =
...@@ -333,12 +333,12 @@ static const arg_def_t buf_optimal_sz = ...@@ -333,12 +333,12 @@ static const arg_def_t buf_optimal_sz =
ARG_DEF(NULL, "buf-optimal-sz", 1, "Client optimal buffer size (ms)"); ARG_DEF(NULL, "buf-optimal-sz", 1, "Client optimal buffer size (ms)");
static const arg_def_t *rc_args[] = { &dropframe_thresh, static const arg_def_t *rc_args[] = { &dropframe_thresh,
&resize_mode, &resize_mode,
&resize_numerator, &resize_denominator,
&resize_kf_numerator, &resize_kf_denominator,
#if CONFIG_FRAME_SUPERRES #if CONFIG_FRAME_SUPERRES
&superres_mode, &superres_mode,
&superres_numerator, &superres_denominator,
&superres_kf_numerator, &superres_kf_denominator,
&superres_qthresh, &superres_qthresh,
&superres_kf_qthresh, &superres_kf_qthresh,
#endif // CONFIG_FRAME_SUPERRES #endif // CONFIG_FRAME_SUPERRES
...@@ -1057,17 +1057,17 @@ static int parse_stream_params(struct AvxEncoderConfig *global, ...@@ -1057,17 +1057,17 @@ static int parse_stream_params(struct AvxEncoderConfig *global,
config->cfg.rc_dropframe_thresh = arg_parse_uint(&arg); config->cfg.rc_dropframe_thresh = arg_parse_uint(&arg);
} else if (arg_match(&arg, &resize_mode, argi)) { } else if (arg_match(&arg, &resize_mode, argi)) {
config->cfg.rc_resize_mode = arg_parse_uint(&arg); config->cfg.rc_resize_mode = arg_parse_uint(&arg);
} else if (arg_match(&arg, &resize_numerator, argi)) { } else if (arg_match(&arg, &resize_denominator, argi)) {
config->cfg.rc_resize_numerator = arg_parse_uint(&arg); config->cfg.rc_resize_denominator = arg_parse_uint(&arg);
} else if (arg_match(&arg, &resize_kf_numerator, argi)) { } else if (arg_match(&arg, &resize_kf_denominator, argi)) {
config->cfg.rc_resize_kf_numerator = arg_parse_uint(&arg); config->cfg.rc_resize_kf_denominator = arg_parse_uint(&arg);
#if CONFIG_FRAME_SUPERRES #if CONFIG_FRAME_SUPERRES
} else if (arg_match(&arg, &superres_mode, argi)) { } else if (arg_match(&arg, &superres_mode, argi)) {
config->cfg.rc_superres_mode = arg_parse_uint(&arg); config->cfg.rc_superres_mode = arg_parse_uint(&arg);
} else if (arg_match(&arg, &superres_numerator, argi)) { } else if (arg_match(&arg, &superres_denominator, argi)) {
config->cfg.rc_superres_numerator = arg_parse_uint(&arg); config->cfg.rc_superres_denominator = arg_parse_uint(&arg);
} else if (arg_match(&arg, &superres_kf_numerator, argi)) { } else if (arg_match(&arg, &superres_kf_denominator, argi)) {
config->cfg.rc_superres_kf_numerator = arg_parse_uint(&arg); config->cfg.rc_superres_kf_denominator = arg_parse_uint(&arg);
} else if (arg_match(&arg, &superres_qthresh, argi)) { } else if (arg_match(&arg, &superres_qthresh, argi)) {
config->cfg.rc_superres_qthresh = arg_parse_uint(&arg); config->cfg.rc_superres_qthresh = arg_parse_uint(&arg);
} else if (arg_match(&arg, &superres_kf_qthresh, argi)) { } else if (arg_match(&arg, &superres_kf_qthresh, argi)) {
...@@ -1286,12 +1286,12 @@ static void show_stream_config(struct stream_state *stream, ...@@ -1286,12 +1286,12 @@ static void show_stream_config(struct stream_state *stream,
#endif // CONFIG_EXT_TILE #endif // CONFIG_EXT_TILE
SHOW(rc_dropframe_thresh); SHOW(rc_dropframe_thresh);
SHOW(rc_resize_mode); SHOW(rc_resize_mode);
SHOW(rc_resize_numerator); SHOW(rc_resize_denominator);
SHOW(rc_resize_kf_numerator); SHOW(rc_resize_kf_denominator);
#if CONFIG_FRAME_SUPERRES #if CONFIG_FRAME_SUPERRES
SHOW(rc_superres_mode); SHOW(rc_superres_mode);
SHOW(rc_superres_numerator); SHOW(rc_superres_denominator);
SHOW(rc_superres_kf_numerator); SHOW(rc_superres_kf_denominator);
SHOW(rc_superres_qthresh); SHOW(rc_superres_qthresh);
SHOW(rc_superres_kf_qthresh); SHOW(rc_superres_kf_qthresh);
#endif // CONFIG_FRAME_SUPERRES #endif // CONFIG_FRAME_SUPERRES
......
...@@ -251,16 +251,16 @@ static aom_codec_err_t validate_config(aom_codec_alg_priv_t *ctx, ...@@ -251,16 +251,16 @@ static aom_codec_err_t validate_config(aom_codec_alg_priv_t *ctx,
} }
RANGE_CHECK_HI(cfg, rc_resize_mode, RESIZE_MODES - 1); RANGE_CHECK_HI(cfg, rc_resize_mode, RESIZE_MODES - 1);
RANGE_CHECK(cfg, rc_resize_numerator, SCALE_DENOMINATOR / 2, RANGE_CHECK(cfg, rc_resize_denominator, SCALE_NUMERATOR,
SCALE_DENOMINATOR); SCALE_NUMERATOR << 1);
RANGE_CHECK(cfg, rc_resize_kf_numerator, SCALE_DENOMINATOR / 2, RANGE_CHECK(cfg, rc_resize_kf_denominator, SCALE_NUMERATOR,
SCALE_DENOMINATOR); SCALE_NUMERATOR << 1);
#if CONFIG_FRAME_SUPERRES #if CONFIG_FRAME_SUPERRES
RANGE_CHECK_HI(cfg, rc_superres_mode, SUPERRES_MODES - 1); RANGE_CHECK_HI(cfg, rc_superres_mode, SUPERRES_MODES - 1);
RANGE_CHECK(cfg, rc_superres_numerator, SCALE_DENOMINATOR / 2, RANGE_CHECK(cfg, rc_superres_denominator, SCALE_NUMERATOR,
SCALE_DENOMINATOR); SCALE_NUMERATOR << 1);
RANGE_CHECK(cfg, rc_superres_kf_numerator, SCALE_DENOMINATOR / 2, RANGE_CHECK(cfg, rc_superres_kf_denominator, SCALE_NUMERATOR,
SCALE_DENOMINATOR); SCALE_NUMERATOR << 1);
RANGE_CHECK(cfg, rc_superres_qthresh, 1, 63); RANGE_CHECK(cfg, rc_superres_qthresh, 1, 63);
RANGE_CHECK(cfg, rc_superres_kf_qthresh, 1, 63); RANGE_CHECK(cfg, rc_superres_kf_qthresh, 1, 63);
#endif // CONFIG_FRAME_SUPERRES #endif // CONFIG_FRAME_SUPERRES
...@@ -516,17 +516,18 @@ static aom_codec_err_t set_encoder_config( ...@@ -516,17 +516,18 @@ static aom_codec_err_t set_encoder_config(
oxcf->over_shoot_pct = cfg->rc_overshoot_pct; oxcf->over_shoot_pct = cfg->rc_overshoot_pct;
oxcf->resize_mode = (RESIZE_MODE)cfg->rc_resize_mode; oxcf->resize_mode = (RESIZE_MODE)cfg->rc_resize_mode;
oxcf->resize_scale_numerator = (uint8_t)cfg->rc_resize_numerator; oxcf->resize_scale_denominator = (uint8_t)cfg->rc_resize_denominator;
oxcf->resize_kf_scale_numerator = (uint8_t)cfg->rc_resize_kf_numerator; oxcf->resize_kf_scale_denominator = (uint8_t)cfg->rc_resize_kf_denominator;
if (oxcf->resize_mode == RESIZE_FIXED && if (oxcf->resize_mode == RESIZE_FIXED &&
oxcf->resize_scale_numerator == SCALE_DENOMINATOR && oxcf->resize_scale_denominator == SCALE_NUMERATOR &&
oxcf->resize_kf_scale_numerator == SCALE_DENOMINATOR) oxcf->resize_kf_scale_denominator == SCALE_NUMERATOR)
oxcf->resize_mode = RESIZE_NONE; oxcf->resize_mode = RESIZE_NONE;
#if CONFIG_FRAME_SUPERRES #if CONFIG_FRAME_SUPERRES
oxcf->superres_mode = (SUPERRES_MODE)cfg->rc_superres_mode; oxcf->superres_mode = (SUPERRES_MODE)cfg->rc_superres_mode;
oxcf->superres_scale_numerator = (uint8_t)cfg->rc_superres_numerator; oxcf->superres_scale_denominator = (uint8_t)cfg->rc_superres_denominator;
oxcf->superres_kf_scale_numerator = (uint8_t)cfg->rc_superres_kf_numerator; oxcf->superres_kf_scale_denominator =
(uint8_t)cfg->rc_superres_kf_denominator;
oxcf->superres_qthresh = oxcf->superres_qthresh =
extra_cfg->lossless ? 255 extra_cfg->lossless ? 255
: av1_quantizer_to_qindex(cfg->rc_superres_qthresh); : av1_quantizer_to_qindex(cfg->rc_superres_qthresh);
...@@ -535,8 +536,8 @@ static aom_codec_err_t set_encoder_config( ...@@ -535,8 +536,8 @@ static aom_codec_err_t set_encoder_config(
? 255 ? 255
: av1_quantizer_to_qindex(cfg->rc_superres_kf_qthresh); : av1_quantizer_to_qindex(cfg->rc_superres_kf_qthresh);
if (oxcf->superres_mode == SUPERRES_FIXED && if (oxcf->superres_mode == SUPERRES_FIXED &&
oxcf->superres_scale_numerator == SCALE_DENOMINATOR && oxcf->superres_scale_denominator == SCALE_NUMERATOR &&
oxcf->superres_kf_scale_numerator == SCALE_DENOMINATOR) oxcf->superres_kf_scale_denominator == SCALE_NUMERATOR)
oxcf->superres_mode = SUPERRES_NONE; oxcf->superres_mode = SUPERRES_NONE;
if (oxcf->superres_mode == SUPERRES_QTHRESH && if (oxcf->superres_mode == SUPERRES_QTHRESH &&
oxcf->superres_qthresh == 255 && oxcf->superres_kf_qthresh == 255) oxcf->superres_qthresh == 255 && oxcf->superres_kf_qthresh == 255)
...@@ -1646,16 +1647,16 @@ static aom_codec_enc_cfg_map_t encoder_usage_cfg_map[] = { ...@@ -1646,16 +1647,16 @@ static aom_codec_enc_cfg_map_t encoder_usage_cfg_map[] = {
25, // g_lag_in_frames 25, // g_lag_in_frames
0, // rc_dropframe_thresh 0, // rc_dropframe_thresh
RESIZE_NONE, // rc_resize_mode RESIZE_NONE, // rc_resize_mode
SCALE_DENOMINATOR, // rc_resize_numerator SCALE_NUMERATOR, // rc_resize_denominator
SCALE_DENOMINATOR, // rc_resize_kf_numerator SCALE_NUMERATOR, // rc_resize_kf_denominator
0, // rc_superres_mode 0, // rc_superres_mode
SCALE_DENOMINATOR, // rc_superres_numerator SCALE_NUMERATOR, // rc_superres_denominator
SCALE_DENOMINATOR, // rc_superres_kf_numerator SCALE_NUMERATOR, // rc_superres_kf_denominator
63, // rc_superres_qthresh 63, // rc_superres_qthresh
63, // rc_superres_kf_qthresh 63, // rc_superres_kf_qthresh
AOM_VBR, // rc_end_usage AOM_VBR, // rc_end_usage
{ NULL, 0 }, // rc_twopass_stats_in { NULL, 0 }, // rc_twopass_stats_in
......
...@@ -736,7 +736,7 @@ typedef enum { ...@@ -736,7 +736,7 @@ typedef enum {
#if CONFIG_FRAME_SUPERRES #if CONFIG_FRAME_SUPERRES
#define SUPERRES_SCALE_BITS 3 #define SUPERRES_SCALE_BITS 3
#define SUPERRES_SCALE_NUMERATOR_MIN 8 #define SUPERRES_SCALE_DENOMINATOR_MIN 8
#endif // CONFIG_FRAME_SUPERRES #endif // CONFIG_FRAME_SUPERRES
#if CONFIG_LPF_DIRECT #if CONFIG_LPF_DIRECT
......
...@@ -368,8 +368,8 @@ typedef struct AV1Common { ...@@ -368,8 +368,8 @@ typedef struct AV1Common {
loop_filter_info_n lf_info; loop_filter_info_n lf_info;
#if CONFIG_FRAME_SUPERRES #if CONFIG_FRAME_SUPERRES
// The numerator of the superres scale; the denominator is fixed. // The denominator of the superres scale; the numerator is fixed.
uint8_t superres_scale_numerator; uint8_t superres_scale_denominator;
int superres_upscaled_width; int superres_upscaled_width;
int superres_upscaled_height; int superres_upscaled_height;
#endif // CONFIG_FRAME_SUPERRES #endif // CONFIG_FRAME_SUPERRES
......
...@@ -1168,24 +1168,22 @@ YV12_BUFFER_CONFIG *av1_scale_if_required(AV1_COMMON *cm, ...@@ -1168,24 +1168,22 @@ YV12_BUFFER_CONFIG *av1_scale_if_required(AV1_COMMON *cm,
} }
} }
void av1_calculate_scaled_size(int *width, int *height, int num) { void av1_calculate_scaled_size(int *width, int *height, int denom) {
if (num != SCALE_DENOMINATOR) { if (denom != SCALE_NUMERATOR) {
*width = *width * num / SCALE_DENOMINATOR; *width = *width * SCALE_NUMERATOR / denom;
*height = *height * num / SCALE_DENOMINATOR; *height = *height * SCALE_NUMERATOR / denom;
// Make width and height even // Make width and height even
*width += *width & 1; *width += *width & 1;
*height += *height & 1; *height += *height & 1;
} }
} }
// Inverse of av1_calculate_scaled_size() above: calculates the original size void av1_calculate_unscaled_size(int *width, int *height, int denom) {
// from the given scaled dimensions and the scale numerator. if (denom != SCALE_NUMERATOR) {
void av1_calculate_unscaled_size(int *width, int *height, int num) {
if (num != SCALE_DENOMINATOR) {
// Note: av1_calculate_scaled_size() rounds *up* after division when the // Note: av1_calculate_scaled_size() rounds *up* after division when the
// resulting dimensions are odd. So here, we round *down*. // resulting dimensions are odd. So here, we round *down*.
*width = *width * SCALE_DENOMINATOR / num; *width = *width * denom / SCALE_NUMERATOR;
*height = *height * SCALE_DENOMINATOR / num; *height = *height * denom / SCALE_NUMERATOR;
} }
} }
......
...@@ -86,19 +86,19 @@ YV12_BUFFER_CONFIG *av1_scale_if_required(AV1_COMMON *cm, ...@@ -86,19 +86,19 @@ YV12_BUFFER_CONFIG *av1_scale_if_required(AV1_COMMON *cm,
YV12_BUFFER_CONFIG *scaled); YV12_BUFFER_CONFIG *scaled);
// Calculates the scaled size from the given original dimensions and the scale // Calculates the scaled size from the given original dimensions and the scale
// numerator. // denominator.
void av1_calculate_scaled_size(int *width, int *height, int num); void av1_calculate_scaled_size(int *width, int *height, int denom);
// Inverse of av1_calculate_scaled_size() above: calculates the original size // Inverse of av1_calculate_scaled_size() above: calculates the original size
// from the given scaled dimensions and the scale numerator. // from the given scaled dimensions and the scale denominator.
void av1_calculate_unscaled_size(int *width, int *height, int num); void av1_calculate_unscaled_size(int *width, int *height, int denom);
#if CONFIG_FRAME_SUPERRES #if CONFIG_FRAME_SUPERRES
void av1_superres_upscale(AV1_COMMON *cm, BufferPool *const pool); void av1_superres_upscale(AV1_COMMON *cm, BufferPool *const pool);
// Returns 1 if a superres upscaled frame is unscaled and 0 otherwise. // Returns 1 if a superres upscaled frame is unscaled and 0 otherwise.
static INLINE int av1_superres_unscaled(const AV1_COMMON *cm) { 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 #endif // CONFIG_FRAME_SUPERRES
......
...@@ -1782,8 +1782,8 @@ int av1_loop_restoration_corners_in_sb(const struct AV1Common *cm, int plane, ...@@ -1782,8 +1782,8 @@ int av1_loop_restoration_corners_in_sb(const struct AV1Common *cm, int plane,
#if CONFIG_FRAME_SUPERRES #if CONFIG_FRAME_SUPERRES
const int frame_w = cm->superres_upscaled_width; const int frame_w = cm->superres_upscaled_width;
const int frame_h = cm->superres_upscaled_height; const int frame_h = cm->superres_upscaled_height;
const int mi_to_px = MI_SIZE * cm->superres_scale_numerator; const int mi_to_px = MI_SIZE * SCALE_NUMERATOR;
const int denom = SCALE_DENOMINATOR; const int denom = cm->superres_scale_denominator;
#else #else
const int frame_w = cm->width; const int frame_w = cm->width;
const int frame_h = cm->height; const int frame_h = cm->height;
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
extern "C" { extern "C" {
#endif #endif
#define SCALE_DENOMINATOR 16 #define SCALE_NUMERATOR 8
#define REF_SCALE_SHIFT 14 #define REF_SCALE_SHIFT 14
#define REF_NO_SCALE (1 << REF_SCALE_SHIFT) #define REF_NO_SCALE (1 << REF_SCALE_SHIFT)
......
...@@ -3038,15 +3038,15 @@ static void setup_superres(AV1_COMMON *const cm, struct aom_read_bit_buffer *rb, ...@@ -3038,15 +3038,15 @@ static void setup_superres(AV1_COMMON *const cm, struct aom_read_bit_buffer *rb,
cm->superres_upscaled_width = *width; cm->superres_upscaled_width = *width;
cm->superres_upscaled_height = *height; cm->superres_upscaled_height = *height;
if (aom_rb_read_bit(rb)) { if (aom_rb_read_bit(rb)) {
cm->superres_scale_numerator = cm->superres_scale_denominator =
(uint8_t)aom_rb_read_literal(rb, SUPERRES_SCALE_BITS); (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 // Don't edit cm->width or cm->height directly, or the buffers won't get
// resized correctly // resized correctly
av1_calculate_scaled_size(width, height, cm->superres_scale_numerator); av1_calculate_scaled_size(width, height, cm->superres_scale_denominator);
} else { } else {
// 1:1 scaling - ie. no scaling, scale not provided // 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 #endif // CONFIG_FRAME_SUPERRES
......
...@@ -4249,12 +4249,12 @@ static void write_render_size(const AV1_COMMON *cm, ...@@ -4249,12 +4249,12 @@ static void write_render_size(const AV1_COMMON *cm,
static void write_superres_scale(const AV1_COMMON *const cm, static void write_superres_scale(const AV1_COMMON *const cm,
struct aom_write_bit_buffer *wb) { struct aom_write_bit_buffer *wb) {
// First bit is whether to to scale or not // 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 aom_wb_write_bit(wb, 0); // no scaling
} else { } else {
aom_wb_write_bit(wb, 1); // scaling, write scale factor aom_wb_write_bit(wb, 1); // scaling, write scale factor
aom_wb_write_literal( 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); SUPERRES_SCALE_BITS);
} }
} }
......
...@@ -3088,7 +3088,7 @@ AV1_COMP *av1_create_compressor(AV1EncoderConfig *oxcf, ...@@ -3088,7 +3088,7 @@ AV1_COMP *av1_create_compressor(AV1EncoderConfig *oxcf,
av1_loop_filter_init(cm); av1_loop_filter_init(cm);
#if CONFIG_FRAME_SUPERRES #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_width = oxcf->width;
cm->superres_upscaled_height = oxcf->height; cm->superres_upscaled_height = oxcf->height;
#endif // CONFIG_FRAME_SUPERRES #endif // CONFIG_FRAME_SUPERRES
...@@ -4429,21 +4429,21 @@ static uint8_t calculate_next_resize_scale(const AV1_COMP *cpi) { ...@@ -4429,21 +4429,21 @@ static uint8_t calculate_next_resize_scale(const AV1_COMP *cpi) {
// Choose an arbitrary random number // Choose an arbitrary random number
static unsigned int seed = 56789; static unsigned int seed = 56789;
const AV1EncoderConfig *oxcf = &cpi->oxcf; const AV1EncoderConfig *oxcf = &cpi->oxcf;
if (oxcf->pass == 1) return SCALE_DENOMINATOR; if (oxcf->pass == 1) return SCALE_NUMERATOR;
uint8_t new_num = SCALE_DENOMINATOR; uint8_t new_denom = SCALE_NUMERATOR;
switch (oxcf->resize_mode) { switch (oxcf->resize_mode) {
case RESIZE_NONE: new_num = SCALE_DENOMINATOR; break; case RESIZE_NONE: new_denom = SCALE_NUMERATOR; break;
case RESIZE_FIXED: case RESIZE_FIXED:
if (cpi->common.frame_type == KEY_FRAME) if (cpi->common.frame_type == KEY_FRAME)
new_num = oxcf->resize_kf_scale_numerator; new_denom = oxcf->resize_kf_scale_denominator;
else else
new_num = oxcf->resize_scale_numerator; new_denom = oxcf->resize_scale_denominator;
break; 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); default: assert(0);
} }
return new_num; return new_denom;
} }
#if CONFIG_FRAME_SUPERRES #if CONFIG_FRAME_SUPERRES
...@@ -4451,19 +4451,19 @@ static uint8_t calculate_next_superres_scale(AV1_COMP *cpi) { ...@@ -4451,19 +4451,19 @@ static uint8_t calculate_next_superres_scale(AV1_COMP *cpi) {
// Choose an arbitrary random number // Choose an arbitrary random number
static unsigned int seed = 34567; static unsigned int seed = 34567;
const AV1EncoderConfig *oxcf = &cpi->oxcf; const AV1EncoderConfig *oxcf = &cpi->oxcf;
if (oxcf->pass == 1) return SCALE_DENOMINATOR; if (oxcf->pass == 1) return SCALE_NUMERATOR;
uint8_t new_num = SCALE_DENOMINATOR; uint8_t new_denom = SCALE_NUMERATOR;
int bottom_index, top_index, q, qthresh; int bottom_index, top_index, q, qthresh;
switch (oxcf->superres_mode) { switch (oxcf->superres_mode) {
case SUPERRES_NONE: new_num = SCALE_DENOMINATOR; break; case SUPERRES_NONE: new_denom = SCALE_NUMERATOR; break;
case SUPERRES_FIXED: case SUPERRES_FIXED:
if (cpi->common.frame_type == KEY_FRAME) if (cpi->common.frame_type == KEY_FRAME)
new_num = oxcf->superres_kf_scale_numerator; new_denom = oxcf->superres_kf_scale_denominator;
else else
new_num = oxcf->superres_scale_numerator; new_denom = oxcf->superres_scale_denominator;
break; 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: case SUPERRES_QTHRESH:
qthresh = (cpi->common.frame_type == KEY_FRAME ? oxcf->superres_kf_qthresh qthresh = (cpi->common.frame_type == KEY_FRAME ? oxcf->superres_kf_qthresh
: oxcf->superres_qthresh); : oxcf->superres_qthresh);
...@@ -4471,74 +4471,86 @@ static uint8_t calculate_next_superres_scale(AV1_COMP *cpi) { ...@@ -4471,74 +4471,86 @@ static uint8_t calculate_next_superres_scale(AV1_COMP *cpi) {
q = av1_rc_pick_q_and_bounds(cpi, cpi->oxcf.width, cpi->oxcf.height, q = av1_rc_pick_q_and_bounds(cpi, cpi->oxcf.width, cpi->oxcf.height,
&bottom_index, &top_index); &bottom_index, &top_index);
if (q < qthresh) { if (q < qthresh) {
new_num = SCALE_DENOMINATOR; new_denom = SCALE_NUMERATOR;
} else { } else {
new_num = SCALE_DENOMINATOR - 1 - ((q - qthresh) >> 3); new_denom = SCALE_NUMERATOR + 1 + ((q - qthresh) >> 3);
new_num = AOMMAX(SCALE_DENOMINATOR / 2, new_num); new_denom = AOMMIN(SCALE_NUMERATOR << 1, new_denom);
// printf("SUPERRES: q %d, qthresh %d: num %d\n", q, qthresh, new_num); // printf("SUPERRES: q %d, qthresh %d: denom %d\n", q, qthresh,
// new_denom);
} }
break; break;
default: assert(0); 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, static int validate_size_scales(RESIZE_MODE resize_mode,
SUPERRES_MODE superres_mode, int owidth, SUPERRES_MODE superres_mode, int owidth,
int oheight, size_params_type *rsz) { int oheight, size_params_type *rsz) {
if (rsz->resize_width * rsz->superres_num >= SCALE_DENOMINATOR * owidth / 2 && if (dimensions_are_ok(owidth, oheight, rsz)) { // Nothing to do.
rsz->resize_height * rsz->superres_num >= SCALE_DENOMINATOR * oheight / 2)
return 1; 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) { if (resize_mode != RESIZE_RANDOM && superres_mode == SUPERRES_RANDOM) {
rsz->superres_num = // Alter superres scale as needed to enforce conformity.
(SCALE_DENOMINATOR * SCALE_DENOMINATOR + 2 * resize_num - 1) / rsz->superres_denom =
(2 * resize_num); (2 * SCALE_NUMERATOR * SCALE_NUMERATOR) / resize_denom;
if (rsz->resize_width * rsz->superres_num < if (!dimensions_are_ok(owidth, oheight, rsz)) {
SCALE_DENOMINATOR * owidth / 2 || if (rsz->superres_denom > SCALE_NUMERATOR) --rsz->superres_denom;
rsz->resize_height * rsz->superres_num <
SCALE_DENOMINATOR * oheight / 2) {
if (rsz->superres_num < SCALE_DENOMINATOR) rsz->superres_num++;
} }
} else if (resize_mode == RESIZE_RANDOM && superres_mode != SUPERRES_RANDOM) { } else if (resize_mode == RESIZE_RANDOM && superres_mode != SUPERRES_RANDOM) {
resize_num = // Alter resize scale as needed to enforce conformity.
(SCALE_DENOMINATOR * SCALE_DENOMINATOR + 2 * rsz->superres_num - 1) / resize_denom =
(2 * rsz->superres_num); (2 * SCALE_NUMERATOR * SCALE_NUMERATOR) / rsz->superres_denom;
rsz->resize_width = owidth; rsz->resize_width = owidth;
rsz->resize_height = oheight; rsz->resize_height = oheight;
av1_calculate_scaled_size(&rsz->resize_width, &rsz->resize_height, av1_calculate_scaled_size(&rsz->resize_width, &rsz->resize_height,
resize_num); resize_denom);
if (rsz->resize_width * rsz->superres_num < if (!dimensions_are_ok(owidth, oheight, rsz)) {
SCALE_DENOMINATOR * owidth / 2 || if (resize_denom > SCALE_NUMERATOR) {
rsz->resize_height * rsz->superres_num < --resize_denom;
SCALE_DENOMINATOR * oheight / 2) { rsz->resize_width = owidth;
if (resize_num < SCALE_DENOMINATOR) resize_num++; 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) { } else if (resize_mode == RESIZE_RANDOM && superres_mode == SUPERRES_RANDOM) {
// Alter both resize and superres scales as needed to enforce conformity.
do { do {
if (resize_num < rsz->superres_num) if (resize_denom > rsz->superres_denom)
++resize_num;