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