Move frame_type to EncodeFrameParams
In this patch I move all frame_type (i.e. key, S, inter, intra-only)
determining logic above the av1_encode() boundary. frame_type is now
passed into the low-level encoder as EncodeFrameParams.frame_type and is
not modified below that boundary. This also means
cm->current_frame.frame_type (including functions like
frame_is_sframe()) should not be used before av1_encode(), as this is a
lower-level variable.
As part of this, calls to av1_tpl_setup_stats() and
av1_rc_get_second_pass_params() are moved to av1_encode_strategy() since
they are used to work out high-level pass2 strategy.
Also, remove the reset_decoder_state variable from the encoder as it
wasn't doing anything useful. So, move it from AV1_COMMON to Av1Decoder
This forms part of wider restructuring and refactoring in order to
achieve a clean API separation at the entry to the low-level encoder.
BUG=aomedia:2244
Change-Id: I672c435dfff88bb982ea904b5547e5d3294ef37c
diff --git a/av1/common/onyxc_int.h b/av1/common/onyxc_int.h
index e6cd60f..9e9158b 100644
--- a/av1/common/onyxc_int.h
+++ b/av1/common/onyxc_int.h
@@ -378,7 +378,6 @@
int show_frame;
int showable_frame; // frame can be used as show existing frame in future
int show_existing_frame;
- int reset_decoder_state;
uint8_t disable_cdf_update;
int allow_high_precision_mv;
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index 2c91f4a..26e91d5 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -4854,7 +4854,7 @@
cm->error_resilient_mode = 1;
} else {
cm->show_existing_frame = aom_rb_read_bit(rb);
- cm->reset_decoder_state = 0;
+ pbi->reset_decoder_state = 0;
if (cm->show_existing_frame) {
if (pbi->sequence_header_changed) {
@@ -4896,7 +4896,7 @@
// assign_frame_buffer_p()!
assert(!cm->cur_frame->raw_frame_buffer.data);
assign_frame_buffer_p(&cm->cur_frame, frame_to_show);
- cm->reset_decoder_state = frame_to_show->frame_type == KEY_FRAME;
+ pbi->reset_decoder_state = frame_to_show->frame_type == KEY_FRAME;
unlock_buffer_pool(pool);
cm->lf.filter_level[0] = 0;
@@ -4906,11 +4906,11 @@
if (!frame_to_show->showable_frame) {
aom_merge_corrupted_flag(&xd->corrupted, 1);
}
- if (cm->reset_decoder_state) frame_to_show->showable_frame = 0;
+ if (pbi->reset_decoder_state) frame_to_show->showable_frame = 0;
cm->film_grain_params = frame_to_show->film_grain_params;
- if (cm->reset_decoder_state) {
+ if (pbi->reset_decoder_state) {
show_existing_frame_reset(pbi, existing_frame_idx);
} else {
current_frame->refresh_frame_flags = 0;
@@ -5508,7 +5508,7 @@
if (cm->show_existing_frame) {
// showing a frame directly
*p_data_end = data + uncomp_hdr_size;
- if (cm->reset_decoder_state) {
+ if (pbi->reset_decoder_state) {
// Use the default frame context values.
*cm->fc = *cm->default_frame_context;
if (!cm->fc->initialized)
diff --git a/av1/decoder/decoder.c b/av1/decoder/decoder.c
index 743f2cf..bff4b7a 100644
--- a/av1/decoder/decoder.c
+++ b/av1/decoder/decoder.c
@@ -361,7 +361,7 @@
assert(IMPLIES(!pbi->hold_ref_buf,
cm->current_frame.refresh_frame_flags == 0));
assert(IMPLIES(!pbi->hold_ref_buf,
- cm->show_existing_frame && !cm->reset_decoder_state));
+ cm->show_existing_frame && !pbi->reset_decoder_state));
// The following two for loops need to release the reference stored in
// cm->ref_frame_map[ref_index] before transferring the reference stored
@@ -374,7 +374,7 @@
}
const int check_on_show_existing_frame =
- !cm->show_existing_frame || cm->reset_decoder_state;
+ !cm->show_existing_frame || pbi->reset_decoder_state;
for (; ref_index < REF_FRAMES && check_on_show_existing_frame;
++ref_index) {
decrease_ref_count(cm->ref_frame_map[ref_index], pool);
diff --git a/av1/decoder/decoder.h b/av1/decoder/decoder.h
index 3e9d4c2..467c8a2 100644
--- a/av1/decoder/decoder.h
+++ b/av1/decoder/decoder.h
@@ -200,6 +200,7 @@
int need_resync; // wait for key/intra-only frame.
int hold_ref_buf; // Boolean: whether we are holding reference buffers in
// common.next_ref_frame_map.
+ int reset_decoder_state;
int tile_size_bytes;
int tile_col_size_bytes;
diff --git a/av1/encoder/encode_strategy.c b/av1/encoder/encode_strategy.c
index 272f170..741ba0c 100644
--- a/av1/encoder/encode_strategy.c
+++ b/av1/encoder/encode_strategy.c
@@ -23,6 +23,8 @@
#include "av1/encoder/encoder.h"
#include "av1/encoder/encode_strategy.h"
+#include "av1/encoder/firstpass.h"
+#include "av1/encoder/tpl_model.h"
static void set_additional_frame_flags(const AV1_COMMON *const cm,
unsigned int *const frame_flags) {
@@ -134,7 +136,7 @@
AV1_COMMON *const cm = &cpi->common;
if (cpi->ext_use_s_frame) {
- cm->current_frame.frame_type = S_FRAME;
+ frame_params->frame_type = S_FRAME;
}
cm->force_primary_ref_none = cpi->ext_use_primary_ref_none;
@@ -156,10 +158,9 @@
// A keyframe is already error resilient and keyframes with
// error_resilient_mode interferes with the use of show_existing_frame
// when forward reference keyframes are enabled.
- frame_params->error_resilient_mode &=
- cm->current_frame.frame_type != KEY_FRAME;
+ frame_params->error_resilient_mode &= frame_params->frame_type != KEY_FRAME;
// For bitstream conformance, s-frames must be error-resilient
- frame_params->error_resilient_mode |= frame_is_sframe(cm);
+ frame_params->error_resilient_mode |= frame_params->frame_type == S_FRAME;
}
static int get_ref_frame_flags(const AV1_COMP *const cpi) {
@@ -241,9 +242,9 @@
EncodeFrameParams *const frame_params,
EncodeFrameResults *const frame_results) {
if (cpi->oxcf.rc_mode == AOM_CBR) {
- av1_rc_get_one_pass_cbr_params(cpi);
+ av1_rc_get_one_pass_cbr_params(cpi, frame_params);
} else {
- av1_rc_get_one_pass_vbr_params(cpi);
+ av1_rc_get_one_pass_vbr_params(cpi, frame_params);
}
// Apply external override flags
@@ -270,7 +271,17 @@
static int Pass1Encode(AV1_COMP *const cpi,
const EncodeFrameInput *const frame_input,
EncodeFrameParams *const frame_params) {
+ const CurrentFrame *const current_frame = &cpi->common.current_frame;
+
cpi->td.mb.e_mbd.lossless[0] = is_lossless_requested(&cpi->oxcf);
+
+ if (!cpi->refresh_alt_ref_frame && (current_frame->frame_number == 0 ||
+ (cpi->frame_flags & FRAMEFLAGS_KEY))) {
+ frame_params->frame_type = KEY_FRAME;
+ } else {
+ frame_params->frame_type = INTER_FRAME;
+ }
+
av1_encode(cpi, NULL, frame_input, frame_params, NULL);
return AOM_CODEC_OK;
}
@@ -324,12 +335,33 @@
uint8_t *const dest, unsigned int *frame_flags,
const EncodeFrameInput *const frame_input) {
const AV1EncoderConfig *const oxcf = &cpi->oxcf;
+ AV1_COMMON *const cm = &cpi->common;
EncodeFrameParams frame_params;
EncodeFrameResults frame_results;
memset(&frame_params, 0, sizeof(frame_params));
memset(&frame_results, 0, sizeof(frame_results));
+ if (oxcf->pass == 2 &&
+ (!cm->show_existing_frame || cpi->rc.is_src_frame_alt_ref)) {
+ // GF_GROUP needs updating for arf overlays as well as non-show-existing
+ av1_rc_get_second_pass_params(cpi, &frame_params);
+ }
+ if (cm->show_existing_frame && frame_params.frame_type != KEY_FRAME) {
+ // Force show-existing frames to be INTER, except forward keyframes
+ frame_params.frame_type = INTER_FRAME;
+ }
+
+ if (!cm->show_existing_frame) {
+ cm->using_qmatrix = cpi->oxcf.using_qm;
+ cm->min_qmlevel = cpi->oxcf.qm_minlevel;
+ cm->max_qmlevel = cpi->oxcf.qm_maxlevel;
+ if (cpi->twopass.gf_group.index == 1 && cpi->oxcf.enable_tpl_model) {
+ av1_set_frame_size(cpi, cm->width, cm->height);
+ av1_tpl_setup_stats(cpi, frame_input);
+ }
+ }
+
frame_params.frame_flags = frame_flags;
// TODO(david.turner@argondesign.com): Move all the encode strategy
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index f0003c5..1037318 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -71,7 +71,6 @@
#include "av1/encoder/segmentation.h"
#include "av1/encoder/speed_features.h"
#include "av1/encoder/temporal_filter.h"
-#include "av1/encoder/tpl_model.h"
#include "av1/encoder/reconinter_enc.h"
#define DEFAULT_EXPLICIT_ORDER_HINT_BITS 7
@@ -4031,7 +4030,7 @@
return 0;
}
-static void set_frame_size(AV1_COMP *cpi, int width, int height) {
+void av1_set_frame_size(AV1_COMP *cpi, int width, int height) {
AV1_COMMON *const cm = &cpi->common;
const SequenceHeader *const seq_params = &cm->seq_params;
const int num_planes = av1_num_planes(cm);
@@ -4265,7 +4264,7 @@
}
// Calculates resize and superres params for next frame
-size_params_type av1_calculate_next_size_params(AV1_COMP *cpi) {
+static size_params_type calculate_next_size_params(AV1_COMP *cpi) {
const AV1EncoderConfig *oxcf = &cpi->oxcf;
size_params_type rsz = { oxcf->width, oxcf->height, SCALE_NUMERATOR };
int resize_denom;
@@ -4299,13 +4298,13 @@
cm->superres_scale_denominator = rsz->superres_denom;
av1_calculate_scaled_superres_size(&encode_width, &encode_height,
rsz->superres_denom);
- set_frame_size(cpi, encode_width, encode_height);
+ av1_set_frame_size(cpi, encode_width, encode_height);
}
static void setup_frame_size(AV1_COMP *cpi) {
// Reset superres params from previous frame.
cpi->common.superres_scale_denominator = SCALE_NUMERATOR;
- const size_params_type rsz = av1_calculate_next_size_params(cpi);
+ const size_params_type rsz = calculate_next_size_params(cpi);
setup_frame_size_from_params(cpi, &rsz);
}
@@ -4549,11 +4548,6 @@
}
assert(frame_to_show->ref_count > 0);
assign_frame_buffer_p(&cm->cur_frame, frame_to_show);
- if (cm->reset_decoder_state && frame_to_show->frame_type != KEY_FRAME) {
- aom_internal_error(
- &cm->error, AOM_CODEC_UNSUP_BITSTREAM,
- "show_existing_frame to reset state on KEY_FRAME only");
- }
}
if (!encode_show_existing_frame(cm) &&
@@ -5166,11 +5160,6 @@
if (encode_show_existing_frame(cm)) {
// NOTE(zoeliu): In BIDIR_PRED, the existing frame to show is the current
// BWDREF_FRAME in the reference frame buffer.
- if (current_frame->frame_type == KEY_FRAME) {
- cm->reset_decoder_state = 1;
- } else {
- current_frame->frame_type = INTER_FRAME;
- }
cm->show_frame = 1;
cpi->frame_flags = *frame_flags;
@@ -5533,6 +5522,7 @@
cpi->unscaled_last_source = frame_input->last_source;
cm->error_resilient_mode = frame_params->error_resilient_mode;
+ cm->current_frame.frame_type = frame_params->frame_type;
cpi->ref_frame_flags = frame_params->ref_frame_flags;
cpi->speed = frame_params->speed;
@@ -6070,7 +6060,6 @@
// Initialize fields related to forward keyframes
cpi->no_show_kf = 0;
- cm->reset_decoder_state = 0;
cm->show_existing_frame &= allow_show_existing(cpi);
@@ -6134,24 +6123,7 @@
cpi->common.frame_presentation_time = (uint32_t)pts64;
}
- if (oxcf->pass == 2) {
- // GF_GROUP needs updating for arf overlays as well as non-show-existing
- if (!cm->show_existing_frame || cpi->rc.is_src_frame_alt_ref) {
- av1_rc_get_second_pass_params(cpi);
- }
- } else if (oxcf->pass == 1) {
- setup_frame_size(cpi);
- }
-
- if (!cm->show_existing_frame) {
- cm->using_qmatrix = cpi->oxcf.using_qm;
- cm->min_qmlevel = cpi->oxcf.qm_minlevel;
- cm->max_qmlevel = cpi->oxcf.qm_maxlevel;
- if (cpi->twopass.gf_group.index == 1 && cpi->oxcf.enable_tpl_model) {
- set_frame_size(cpi, cm->width, cm->height);
- av1_tpl_setup_stats(cpi, &frame_input);
- }
- }
+ if (oxcf->pass == 1) setup_frame_size(cpi);
if (av1_encode_strategy(cpi, size, dest, frame_flags, &frame_input) !=
AOM_CODEC_OK) {
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index 407f986..9a4e533 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -877,8 +877,9 @@
// EncodeFrameParams contains per-frame encoding parameters decided upon by
// av1_encode_strategy() and passed down to av1_encode()
-typedef struct {
+struct EncodeFrameParams {
int error_resilient_mode;
+ FRAME_TYPE frame_type;
// This is a bitmask of which reference slots can be used in this frame
int ref_frame_flags;
@@ -887,7 +888,8 @@
int speed;
unsigned int *frame_flags;
-} EncodeFrameParams;
+};
+typedef struct EncodeFrameParams EncodeFrameParams;
// EncodeFrameResults contains information about the result of encoding a
// single frame
@@ -936,6 +938,8 @@
int av1_set_reference_enc(AV1_COMP *cpi, int idx, YV12_BUFFER_CONFIG *sd);
+void av1_set_frame_size(AV1_COMP *cpi, int width, int height);
+
int av1_update_entropy(AV1_COMP *cpi, int update);
int av1_set_active_map(AV1_COMP *cpi, unsigned char *map, int rows, int cols);
diff --git a/av1/encoder/firstpass.c b/av1/encoder/firstpass.c
index 8349ee7..3f50204 100644
--- a/av1/encoder/firstpass.c
+++ b/av1/encoder/firstpass.c
@@ -449,18 +449,6 @@
return i;
}
-static void set_first_pass_params(AV1_COMP *cpi) {
- AV1_COMMON *const cm = &cpi->common;
- if (!cpi->refresh_alt_ref_frame && (cm->current_frame.frame_number == 0 ||
- (cpi->frame_flags & FRAMEFLAGS_KEY))) {
- cm->current_frame.frame_type = KEY_FRAME;
- } else {
- cm->current_frame.frame_type = INTER_FRAME;
- }
- // Do not use periodic key frames.
- cpi->rc.frames_to_key = INT_MAX;
-}
-
static double raw_motion_error_stdev(int *raw_motion_err_list,
int raw_motion_err_counts) {
int64_t sum_raw_err = 0;
@@ -558,7 +546,9 @@
brightness_factor = 0.0;
neutral_count = 0.0;
- set_first_pass_params(cpi);
+ // Do not use periodic key frames.
+ cpi->rc.frames_to_key = INT_MAX;
+
av1_set_quantizer(cm, qindex);
av1_setup_block_planes(&x->e_mbd, seq_params->subsampling_x,
@@ -1719,11 +1709,12 @@
return AOMMIN(max_gf_length_allowed, MAX_GF_INTERVAL);
}
-static void define_customized_gf_group_structure(AV1_COMP *cpi) {
+static void define_customized_gf_group_structure(
+ AV1_COMP *cpi, const EncodeFrameParams *const frame_params) {
RATE_CONTROL *const rc = &cpi->rc;
TWO_PASS *const twopass = &cpi->twopass;
GF_GROUP *const gf_group = &twopass->gf_group;
- const int key_frame = cpi->common.current_frame.frame_type == KEY_FRAME;
+ const int key_frame = frame_params->frame_type == KEY_FRAME;
assert(rc->baseline_gf_interval >= MIN_GF_INTERVAL &&
rc->baseline_gf_interval <=
@@ -1794,7 +1785,8 @@
// result in exactly the same GF group structure as
// define_customized_gf_group_structure() when rc->baseline_gf_interval == 4
-static void define_gf_group_structure(AV1_COMP *cpi) {
+static void define_gf_group_structure(
+ AV1_COMP *cpi, const EncodeFrameParams *const frame_params) {
RATE_CONTROL *const rc = &cpi->rc;
const int max_pyr_height = cpi->oxcf.gf_max_pyr_height;
@@ -1805,7 +1797,7 @@
// used the new structure only if extra_arf is allowed
if (valid_customized_gf_length && rc->source_alt_ref_pending &&
cpi->extra_arf_allowed > 0) {
- define_customized_gf_group_structure(cpi);
+ define_customized_gf_group_structure(cpi, frame_params);
cpi->new_bwdref_update_rule = 1;
return;
} else {
@@ -1816,7 +1808,7 @@
GF_GROUP *const gf_group = &twopass->gf_group;
int i;
int frame_index = 0;
- const int key_frame = cpi->common.current_frame.frame_type == KEY_FRAME;
+ const int key_frame = frame_params->frame_type == KEY_FRAME;
// The use of bi-predictive frames are only enabled when following 3
// conditions are met:
@@ -2031,25 +2023,24 @@
static double lvl_budget_factor[MAX_PYRAMID_LVL - 1][MAX_PYRAMID_LVL - 1] = {
{ 1.0, 0.0, 0.0 }, { 0.6, 0.4, 0 }, { 0.45, 0.35, 0.20 }
};
-static void allocate_gf_group_bits(AV1_COMP *cpi, int64_t gf_group_bits,
- double group_error, int gf_arf_bits) {
+static void allocate_gf_group_bits(
+ AV1_COMP *cpi, int64_t gf_group_bits, double group_error, int gf_arf_bits,
+ const EncodeFrameParams *const frame_params) {
RATE_CONTROL *const rc = &cpi->rc;
const AV1EncoderConfig *const oxcf = &cpi->oxcf;
TWO_PASS *const twopass = &cpi->twopass;
GF_GROUP *const gf_group = &twopass->gf_group;
int i;
int frame_index = 0;
- int key_frame;
+ const int key_frame = frame_params->frame_type == KEY_FRAME;
const int max_bits = frame_max_bits(&cpi->rc, &cpi->oxcf);
int64_t total_group_bits = gf_group_bits;
int ext_arf_boost[MAX_EXT_ARFS];
- define_gf_group_structure(cpi);
+ define_gf_group_structure(cpi, frame_params);
av1_zero_array(ext_arf_boost, MAX_EXT_ARFS);
- key_frame = cpi->common.current_frame.frame_type == KEY_FRAME;
-
// For key frames the frame target rate is already set and it
// is also the golden frame.
// === [frame_index == 0] ===
@@ -2210,7 +2201,8 @@
#define ARF_ABS_ZOOM_THRESH 4.4
// Analyse and define a gf/arf group.
-static void define_gf_group(AV1_COMP *cpi, FIRSTPASS_STATS *this_frame) {
+static void define_gf_group(AV1_COMP *cpi, FIRSTPASS_STATS *this_frame,
+ const EncodeFrameParams *const frame_params) {
AV1_COMMON *const cm = &cpi->common;
RATE_CONTROL *const rc = &cpi->rc;
AV1EncoderConfig *const oxcf = &cpi->oxcf;
@@ -2249,14 +2241,15 @@
int64_t gf_group_bits;
double gf_group_error_left;
int gf_arf_bits;
- const int is_key_frame = frame_is_intra_only(cm);
- const int arf_active_or_kf = is_key_frame || rc->source_alt_ref_active;
+ const int is_intra_only = frame_params->frame_type == KEY_FRAME ||
+ frame_params->frame_type == INTRA_ONLY_FRAME;
+ const int arf_active_or_kf = is_intra_only || rc->source_alt_ref_active;
cpi->extra_arf_allowed = 1;
// Reset the GF group data structures unless this is a key
// frame in which case it will already have been done.
- if (is_key_frame == 0) {
+ if (!is_intra_only) {
av1_zero(twopass->gf_group);
}
@@ -2560,20 +2553,21 @@
// also a key frame in which case it has already been accounted for.
if (rc->source_alt_ref_pending) {
gf_group_error_left = gf_group_err - mod_frame_err;
- } else if (is_key_frame == 0) {
+ } else if (!is_intra_only) {
gf_group_error_left = gf_group_err - gf_first_frame_err;
} else {
gf_group_error_left = gf_group_err;
}
// Allocate bits to each of the frames in the GF group.
- allocate_gf_group_bits(cpi, gf_group_bits, gf_group_error_left, gf_arf_bits);
+ allocate_gf_group_bits(cpi, gf_group_bits, gf_group_error_left, gf_arf_bits,
+ frame_params);
// Reset the file position.
reset_fpf_position(twopass, start_pos);
// Calculate a section intra ratio used in setting max loop filter.
- if (cpi->common.current_frame.frame_type != KEY_FRAME) {
+ if (frame_params->frame_type != KEY_FRAME) {
twopass->section_intra_rating = calculate_section_intra_ratio(
start_pos, twopass->stats_in_end, rc->baseline_gf_interval);
}
@@ -2712,7 +2706,6 @@
av1_zero(next_frame);
- cpi->common.current_frame.frame_type = KEY_FRAME;
rc->frames_since_key = 0;
// Reset the GF group data structures.
@@ -3005,7 +2998,8 @@
twopass->stats_in->pcnt_inter - twopass->stats_in->pcnt_motion == 1);
}
-void av1_rc_get_second_pass_params(AV1_COMP *cpi) {
+void av1_rc_get_second_pass_params(AV1_COMP *cpi,
+ EncodeFrameParams *const frame_params) {
AV1_COMMON *const cm = &cpi->common;
CurrentFrame *const current_frame = &cm->current_frame;
RATE_CONTROL *const rc = &cpi->rc;
@@ -3031,9 +3025,9 @@
if (cpi->no_show_kf) {
assert(gf_group->update_type[gf_group->index] == ARF_UPDATE);
- current_frame->frame_type = KEY_FRAME;
+ frame_params->frame_type = KEY_FRAME;
} else {
- current_frame->frame_type = INTER_FRAME;
+ frame_params->frame_type = INTER_FRAME;
}
// Do the firstpass stats indicate that this frame is skippable for the
@@ -3088,16 +3082,17 @@
if (rc->frames_to_key == 0 || (cpi->frame_flags & FRAMEFLAGS_KEY)) {
FIRSTPASS_STATS this_frame_copy;
this_frame_copy = this_frame;
+ frame_params->frame_type = KEY_FRAME;
// Define next KF group and assign bits to it.
find_next_key_frame(cpi, &this_frame);
this_frame = this_frame_copy;
} else {
- current_frame->frame_type = INTER_FRAME;
+ frame_params->frame_type = INTER_FRAME;
}
// Define a new GF/ARF group. (Should always enter here for key frames).
if (rc->frames_till_gf_update_due == 0) {
- define_gf_group(cpi, &this_frame);
+ define_gf_group(cpi, &this_frame, frame_params);
rc->frames_till_gf_update_due = rc->baseline_gf_interval;
@@ -3125,7 +3120,7 @@
target_rate = gf_group->bit_allocation[gf_group->index];
- if (cpi->common.current_frame.frame_type == KEY_FRAME)
+ if (frame_params->frame_type == KEY_FRAME)
target_rate = av1_rc_clamp_iframe_target_size(cpi, target_rate);
else
target_rate = av1_rc_clamp_pframe_target_size(cpi, target_rate);
diff --git a/av1/encoder/firstpass.h b/av1/encoder/firstpass.h
index 9bb1df5..b61116f 100644
--- a/av1/encoder/firstpass.h
+++ b/av1/encoder/firstpass.h
@@ -171,6 +171,7 @@
} TWO_PASS;
struct AV1_COMP;
+struct EncodeFrameParams;
void av1_init_first_pass(struct AV1_COMP *cpi);
void av1_rc_get_first_pass_params(struct AV1_COMP *cpi);
@@ -178,7 +179,8 @@
void av1_end_first_pass(struct AV1_COMP *cpi);
void av1_init_second_pass(struct AV1_COMP *cpi);
-void av1_rc_get_second_pass_params(struct AV1_COMP *cpi);
+void av1_rc_get_second_pass_params(
+ struct AV1_COMP *cpi, struct EncodeFrameParams *const frame_params);
void av1_configure_buffer_updates_firstpass(struct AV1_COMP *cpi,
FRAME_UPDATE_TYPE update_type);
diff --git a/av1/encoder/ratectrl.c b/av1/encoder/ratectrl.c
index f952b35..e34349a 100644
--- a/av1/encoder/ratectrl.c
+++ b/av1/encoder/ratectrl.c
@@ -1586,7 +1586,8 @@
return av1_rc_clamp_iframe_target_size(cpi, target);
}
-void av1_rc_get_one_pass_vbr_params(AV1_COMP *cpi) {
+void av1_rc_get_one_pass_vbr_params(AV1_COMP *cpi,
+ EncodeFrameParams *const frame_params) {
AV1_COMMON *const cm = &cpi->common;
RATE_CONTROL *const rc = &cpi->rc;
CurrentFrame *const current_frame = &cm->current_frame;
@@ -1600,44 +1601,41 @@
(current_frame->frame_number == 0 ||
(cpi->frame_flags & FRAMEFLAGS_KEY) || rc->frames_to_key == 0 ||
(cpi->oxcf.auto_key && 0))) {
- current_frame->frame_type = KEY_FRAME;
+ frame_params->frame_type = KEY_FRAME;
rc->this_key_frame_forced =
current_frame->frame_number != 0 && rc->frames_to_key == 0;
rc->frames_to_key = cpi->oxcf.key_freq;
rc->kf_boost = DEFAULT_KF_BOOST;
rc->source_alt_ref_active = 0;
} else {
- current_frame->frame_type = INTER_FRAME;
+ frame_params->frame_type = INTER_FRAME;
if (sframe_enabled) {
if (altref_enabled) {
if (sframe_mode == 1) {
// sframe_mode == 1: insert sframe if it matches altref frame.
if (current_frame->frame_number % sframe_dist == 0 &&
- current_frame->frame_type != KEY_FRAME &&
current_frame->frame_number != 0 && cpi->refresh_alt_ref_frame) {
- current_frame->frame_type = S_FRAME;
+ frame_params->frame_type = S_FRAME;
}
} else {
// sframe_mode != 1: if sframe will be inserted at the next available
// altref frame
if (current_frame->frame_number % sframe_dist == 0 &&
- current_frame->frame_type != KEY_FRAME &&
current_frame->frame_number != 0) {
rc->sframe_due = 1;
}
if (rc->sframe_due && cpi->refresh_alt_ref_frame) {
- current_frame->frame_type = S_FRAME;
+ frame_params->frame_type = S_FRAME;
rc->sframe_due = 0;
}
}
} else {
if (current_frame->frame_number % sframe_dist == 0 &&
- current_frame->frame_type != KEY_FRAME &&
current_frame->frame_number != 0) {
- current_frame->frame_type = S_FRAME;
+ frame_params->frame_type = S_FRAME;
}
}
}
@@ -1660,7 +1658,7 @@
if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
av1_cyclic_refresh_update_parameters(cpi);
- if (current_frame->frame_type == KEY_FRAME)
+ if (frame_params->frame_type == KEY_FRAME)
target = calc_iframe_target_size_one_pass_vbr(cpi);
else
target = calc_pframe_target_size_one_pass_vbr(cpi);
@@ -1726,7 +1724,8 @@
return av1_rc_clamp_iframe_target_size(cpi, target);
}
-void av1_rc_get_one_pass_cbr_params(AV1_COMP *cpi) {
+void av1_rc_get_one_pass_cbr_params(AV1_COMP *cpi,
+ EncodeFrameParams *const frame_params) {
AV1_COMMON *const cm = &cpi->common;
RATE_CONTROL *const rc = &cpi->rc;
CurrentFrame *const current_frame = &cm->current_frame;
@@ -1735,14 +1734,14 @@
if ((current_frame->frame_number == 0 ||
(cpi->frame_flags & FRAMEFLAGS_KEY) || rc->frames_to_key == 0 ||
(cpi->oxcf.auto_key && 0))) {
- current_frame->frame_type = KEY_FRAME;
+ frame_params->frame_type = KEY_FRAME;
rc->this_key_frame_forced =
current_frame->frame_number != 0 && rc->frames_to_key == 0;
rc->frames_to_key = cpi->oxcf.key_freq;
rc->kf_boost = DEFAULT_KF_BOOST;
rc->source_alt_ref_active = 0;
} else {
- current_frame->frame_type = INTER_FRAME;
+ frame_params->frame_type = INTER_FRAME;
}
if (rc->frames_till_gf_update_due == 0) {
if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
@@ -1763,7 +1762,7 @@
if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
av1_cyclic_refresh_update_parameters(cpi);
- if (current_frame->frame_type == KEY_FRAME)
+ if (frame_params->frame_type == KEY_FRAME)
target = calc_iframe_target_size_one_pass_cbr(cpi);
else
target = calc_pframe_target_size_one_pass_cbr(cpi);
diff --git a/av1/encoder/ratectrl.h b/av1/encoder/ratectrl.h
index 3613555..78c23cf 100644
--- a/av1/encoder/ratectrl.h
+++ b/av1/encoder/ratectrl.h
@@ -199,8 +199,11 @@
// Functions to set parameters for encoding before the actual
// encode_frame_to_data_rate() function.
-void av1_rc_get_one_pass_vbr_params(struct AV1_COMP *cpi);
-void av1_rc_get_one_pass_cbr_params(struct AV1_COMP *cpi);
+struct EncodeFrameParams;
+void av1_rc_get_one_pass_vbr_params(
+ struct AV1_COMP *cpi, struct EncodeFrameParams *const frame_params);
+void av1_rc_get_one_pass_cbr_params(
+ struct AV1_COMP *cpi, struct EncodeFrameParams *const frame_params);
// Post encode update of the rate control parameters based
// on bytes used