Commit 7166f22a authored by Debargha Mukherjee's avatar Debargha Mukherjee

Add a q index based frame superres mode

Refactors and adds superres-mode 3 and associated
paramters --superres-qthresh and --superres-kf-qthresh
that are used to trigger superres mode when the qindex
for any frame exceeds the thresholds provided for non-key
and key-frames respenctively. The superres scale factor
numerator is progressively reduced from 16 starting from
that q threshold following a fixed slope.

Change-Id: If1c782993667a6fbaaa01bbde77c4924008c0d28
parent 34e1201a
......@@ -395,7 +395,7 @@ typedef struct aom_codec_enc_cfg {
* using restoration filters should allow it to outperform normal resizing.
*
* Mode 0 is SUPERRES_NONE, mode 1 is SUPERRES_FIXED, and mode 2 is
* SUPERRES_DYNAMIC.
* SUPERRES_RANDOM.
*/
unsigned int rc_superres_mode;
......@@ -407,7 +407,7 @@ typedef struct aom_codec_enc_cfg {
*
* Valid numerators are 8 to 16.
*
* Ignored by SUPERRES_DYNAMIC.
* Used only by SUPERRES_FIXED.
*/
unsigned int rc_superres_numerator;
......@@ -421,6 +421,24 @@ typedef struct aom_codec_enc_cfg {
*/
unsigned int rc_superres_kf_numerator;
/*!\brief Frame super-resolution q threshold.
*
* The q level threshold after which superres is used.
* Valid values are 1 to 63.
*
* Used only by SUPERRES_QTHRESH
*/
unsigned int rc_superres_qthresh;
/*!\brief Keyframe super-resolution q threshold.
*
* The q level threshold after which superres is used for key frames.
* Valid values are 1 to 63.
*
* Used only by SUPERRES_QTHRESH
*/
unsigned int rc_superres_kf_qthresh;
/*!\brief Rate control algorithm to use.
*
* Indicates whether the end usage of this stream is to be streamed over
......
......@@ -302,6 +302,11 @@ static const arg_def_t superres_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_qthresh = ARG_DEF(
NULL, "superres-qthresh", 1, "Frame super-resolution qindex threshold");
static const arg_def_t superres_kf_qthresh =
ARG_DEF(NULL, "superres-kf-qthresh", 1,
"Frame super-resolution keyframe qindex threshold");
#endif // CONFIG_FRAME_SUPERRES
static const struct arg_enum_list end_usage_enum[] = { { "vbr", AOM_VBR },
{ "cbr", AOM_CBR },
......@@ -334,6 +339,8 @@ static const arg_def_t *rc_args[] = { &dropframe_thresh,
&superres_mode,
&superres_numerator,
&superres_kf_numerator,
&superres_qthresh,
&superres_kf_qthresh,
#endif // CONFIG_FRAME_SUPERRES
&end_usage,
&target_bitrate,
......@@ -1055,6 +1062,10 @@ static int parse_stream_params(struct AvxEncoderConfig *global,
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_qthresh, argi)) {
config->cfg.rc_superres_qthresh = arg_parse_uint(&arg);
} else if (arg_match(&arg, &superres_kf_qthresh, argi)) {
config->cfg.rc_superres_kf_qthresh = arg_parse_uint(&arg);
#endif // CONFIG_FRAME_SUPERRES
} else if (arg_match(&arg, &end_usage, argi)) {
config->cfg.rc_end_usage = arg_parse_enum_or_int(&arg);
......@@ -1267,6 +1278,8 @@ static void show_stream_config(struct stream_state *stream,
SHOW(rc_superres_mode);
SHOW(rc_superres_numerator);
SHOW(rc_superres_kf_numerator);
SHOW(rc_superres_qthresh);
SHOW(rc_superres_kf_qthresh);
#endif // CONFIG_FRAME_SUPERRES
SHOW(rc_end_usage);
SHOW(rc_target_bitrate);
......
......@@ -8,7 +8,6 @@
* Media Patent License 1.0 was not distributed with this source code in the
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#include <stdlib.h>
#include <string.h>
......@@ -251,17 +250,19 @@ static aom_codec_err_t validate_config(aom_codec_alg_priv_t *ctx,
(MAX_LAG_BUFFERS - 1));
}
RANGE_CHECK_HI(cfg, rc_resize_mode, RESIZE_DYNAMIC);
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);
#if CONFIG_FRAME_SUPERRES
RANGE_CHECK_HI(cfg, rc_superres_mode, SUPERRES_DYNAMIC);
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_qthresh, 1, 63);
RANGE_CHECK(cfg, rc_superres_kf_qthresh, 1, 63);
#endif // CONFIG_FRAME_SUPERRES
// AV1 does not support a lower bound on the keyframe interval in
......@@ -513,10 +514,20 @@ static aom_codec_err_t set_encoder_config(
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_qthresh =
extra_cfg->lossless ? 255
: av1_quantizer_to_qindex(cfg->rc_superres_qthresh);
oxcf->superres_kf_qthresh =
extra_cfg->lossless
? 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_mode = SUPERRES_NONE;
if (oxcf->superres_mode == SUPERRES_QTHRESH &&
oxcf->superres_qthresh == 255 && oxcf->superres_kf_qthresh == 255)
oxcf->superres_mode = SUPERRES_NONE;
#endif // CONFIG_FRAME_SUPERRES
oxcf->maximum_buffer_size_ms = is_vbr ? 240000 : cfg->rc_buf_sz;
......@@ -1617,6 +1628,8 @@ static aom_codec_enc_cfg_map_t encoder_usage_cfg_map[] = {
0, // rc_superres_mode
SCALE_DENOMINATOR, // rc_superres_numerator
SCALE_DENOMINATOR, // rc_superres_kf_numerator
63, // rc_superres_qthresh
63, // rc_superres_kf_qthresh
AOM_VBR, // rc_end_usage
{ NULL, 0 }, // rc_twopass_stats_in
......
......@@ -19,6 +19,22 @@
#include "av1/common/entropymv.h"
#include "av1/common/onyxc_int.h"
int av1_get_MBs(int width, int height) {
const int aligned_width = ALIGN_POWER_OF_TWO(width, 3);
const int aligned_height = ALIGN_POWER_OF_TWO(height, 3);
const int mi_cols = aligned_width >> MI_SIZE_LOG2;
const int mi_rows = aligned_height >> MI_SIZE_LOG2;
#if CONFIG_CB4X4
const int mb_cols = (mi_cols + 2) >> 2;
const int mb_rows = (mi_rows + 2) >> 2;
#else
const int mb_cols = (mi_cols + 1) >> 1;
const int mb_rows = (mi_rows + 1) >> 1;
#endif
return mb_rows * mb_cols;
}
void av1_set_mb_mi(AV1_COMMON *cm, int width, int height) {
// Ensure that the decoded width and height are both multiples of
// 8 luma pixels (note: this may only be a multiple of 4 chroma pixels if
......
......@@ -37,6 +37,7 @@ int av1_alloc_state_buffers(struct AV1Common *cm, int width, int height);
void av1_free_state_buffers(struct AV1Common *cm);
void av1_set_mb_mi(struct AV1Common *cm, int width, int height);
int av1_get_MBs(int width, int height);
void av1_swap_current_and_last_seg_map(struct AV1Common *cm);
......
This diff is collapsed.
......@@ -134,14 +134,20 @@ typedef enum {
#endif
typedef enum {
RESIZE_NONE = 0, // No frame resizing allowed.
RESIZE_FIXED = 1, // All frames are coded at the specified dimension.
RESIZE_DYNAMIC = 2 // Coded size of each frame is determined by the codec.
RESIZE_FIXED = 1, // All frames are coded at the specified scale.
RESIZE_RANDOM = 2, // All frames are coded at a random scale.
RESIZE_MODES
} RESIZE_MODE;
#if CONFIG_FRAME_SUPERRES
typedef enum {
SUPERRES_NONE = 0,
SUPERRES_FIXED = 1,
SUPERRES_DYNAMIC = 2
SUPERRES_NONE = 0, // No frame superres allowed
SUPERRES_FIXED = 1, // All frames are coded at the specified scale,
// and super-resolved.
SUPERRES_RANDOM = 2, // All frames are coded at a random scale,
// and super-resolved.
SUPERRES_QTHRESH = 3, // Superres scale for a frame is determined based on
// q_index
SUPERRES_MODES
} SUPERRES_MODE;
#endif // CONFIG_FRAME_SUPERRES
......@@ -224,6 +230,8 @@ typedef struct AV1EncoderConfig {
SUPERRES_MODE superres_mode;
uint8_t superres_scale_numerator;
uint8_t superres_kf_scale_numerator;
int superres_qthresh;
int superres_kf_qthresh;
#endif // CONFIG_FRAME_SUPERRES
// Enable feature to reduce the frame quantization every x frames.
......
This diff is collapsed.
......@@ -49,6 +49,13 @@ typedef enum {
} RATE_FACTOR_LEVEL;
#endif // CONFIG_EXT_REFS
typedef struct {
uint8_t resize_num;
#if CONFIG_FRAME_SUPERRES
uint8_t superres_num;
#endif // CONFIG_FRAME_SUPERRES
} size_params_type;
typedef struct {
// Rate targetting variables
int base_frame_target; // A baseline frame target before adjustment
......@@ -189,10 +196,6 @@ int av1_rc_get_default_max_gf_interval(double framerate, int min_frame_rate);
void av1_rc_get_one_pass_vbr_params(struct AV1_COMP *cpi);
void av1_rc_get_one_pass_cbr_params(struct AV1_COMP *cpi);
// How many times less pixels there are to encode given the current scaling.
// Temporary replacement for rcf_mult and rate_thresh_mult.
double av1_resize_rate_factor(const struct AV1_COMP *cpi);
// Post encode update of the rate control parameters based
// on bytes used
void av1_rc_postencode_update(struct AV1_COMP *cpi, uint64_t bytes_used);
......@@ -201,7 +204,8 @@ void av1_rc_postencode_update_drop_frame(struct AV1_COMP *cpi);
// Updates rate correction factors
// Changes only the rate correction factors in the rate control structure.
void av1_rc_update_rate_correction_factors(struct AV1_COMP *cpi);
void av1_rc_update_rate_correction_factors(struct AV1_COMP *cpi, int width,
int height);
// Decide if we should drop this frame: For 1-pass CBR.
// Changes only the decimation count in the rate control structure
......@@ -214,12 +218,13 @@ void av1_rc_compute_frame_size_bounds(const struct AV1_COMP *cpi,
int *frame_over_shoot_limit);
// Picks q and q bounds given the target for bits
int av1_rc_pick_q_and_bounds(const struct AV1_COMP *cpi, int *bottom_index,
int *top_index);
int av1_rc_pick_q_and_bounds(const struct AV1_COMP *cpi, int width, int height,
int *bottom_index, int *top_index);
// Estimates q to achieve a target bits per frame
int av1_rc_regulate_q(const struct AV1_COMP *cpi, int target_bits_per_frame,
int active_best_quality, int active_worst_quality);
int active_best_quality, int active_worst_quality,
int width, int height);
// Estimates bits per mb for a given qindex and correction factor.
int av1_rc_bits_per_mb(FRAME_TYPE frame_type, int qindex,
......@@ -247,20 +252,15 @@ int av1_compute_qdelta_by_rate(const RATE_CONTROL *rc, FRAME_TYPE frame_type,
int av1_frame_type_qdelta(const struct AV1_COMP *cpi, int rf_level, int q);
void av1_rc_update_framerate(struct AV1_COMP *cpi);
void av1_rc_update_framerate(struct AV1_COMP *cpi, int width, int height);
void av1_rc_set_gf_interval_range(const struct AV1_COMP *const cpi,
RATE_CONTROL *const rc);
void av1_set_target_rate(struct AV1_COMP *cpi);
void av1_set_target_rate(struct AV1_COMP *cpi, int width, int height);
int av1_resize_one_pass_cbr(struct AV1_COMP *cpi);
uint8_t av1_calculate_next_resize_scale(const struct AV1_COMP *cpi);
#if CONFIG_FRAME_SUPERRES
uint8_t av1_calculate_next_superres_scale(const struct AV1_COMP *cpi, int width,
int height);
#endif // CONFIG_FRAME_SUPERRES
#ifdef __cplusplus
} // extern "C"
#endif
......
......@@ -7067,7 +7067,7 @@ static void single_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x,
if (tlevel < 5) step_param += 2;
// prev_mv_sad is not setup for dynamically scaled frames.
if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
if (cpi->oxcf.resize_mode != RESIZE_RANDOM) {
int i;
for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment