Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions av2/encoder/encode_strategy.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@ static INLINE void update_frames_till_gf_update(AV2_COMP *cpi) {
}

static INLINE void update_gf_group_index(AV2_COMP *cpi) {
if (cpi->oxcf.mode == REALTIME && cpi->oxcf.gf_cfg.lag_in_frames == 0) {
cpi->gf_group.index = 0;
return;
}
// Increment the gf group index ready for the next frame. If this is
// a show_existing_frame with a source other than altref, or if it is not
// a displayed forward keyframe, the index was incremented when it was
Expand Down Expand Up @@ -1223,8 +1227,13 @@ int av2_encode_strategy(AV2_COMP *const cpi, size_t *const size,
// Work out some encoding parameters specific to the pass:

if (has_no_stats_stage(cpi)) {
if (*frame_flags & FRAMEFLAGS_KEY) {
frame_params.frame_type = KEY_FRAME;
if (cpi->oxcf.gf_cfg.lag_in_frames == 0 && cpi->oxcf.mode == REALTIME) {
av2_get_one_pass_rt_params(cpi, &frame_params.frame_type, *frame_flags);
frame_update_type = get_frame_update_type(gf_group);
} else {
if (*frame_flags & FRAMEFLAGS_KEY) {
frame_params.frame_type = KEY_FRAME;
}
}
if (oxcf->q_cfg.aq_mode == CYCLIC_REFRESH_AQ) {
av2_cyclic_refresh_update_parameters(cpi, frame_params.frame_type);
Expand Down
58 changes: 57 additions & 1 deletion av2/encoder/ratectrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1771,7 +1771,9 @@ void av2_rc_postencode_update(AV2_COMP *cpi, uint64_t bytes_used) {
rc->avg_frame_qindex[KEY_FRAME] =
ROUND_POWER_OF_TWO(3 * rc->avg_frame_qindex[KEY_FRAME] + qindex, 2);
} else {
if ((!rc->is_src_frame_alt_ref && !(level <= 1 || is_intrnl_arf))) {
if (!rc->is_src_frame_alt_ref &&
(((cpi->oxcf.mode == REALTIME && cpi->oxcf.gf_cfg.lag_in_frames == 0) ||
!(level <= 1 || is_intrnl_arf)))) {
rc->last_q[INTER_FRAME] = qindex;
rc->avg_frame_qindex[INTER_FRAME] =
ROUND_POWER_OF_TWO(3 * rc->avg_frame_qindex[INTER_FRAME] + qindex, 2);
Expand Down Expand Up @@ -2125,3 +2127,57 @@ int av2_calc_iframe_target_size_one_pass_cbr(const AV2_COMP *cpi) {
}
return av2_rc_clamp_iframe_target_size(cpi, target);
}

#define DEFAULT_KF_BOOST_RT 2000

static inline int set_key_frame(AV2_COMP *cpi, unsigned int frame_flags) {
RATE_CONTROL *const rc = &cpi->rc;
AV2_COMMON *const cm = &cpi->common;
// Very first frame has to be key frame.
if (cm->current_frame.frame_number == 0) return 1;
// Set key frame if forced by frame flags.
if (frame_flags & FRAMEFLAGS_KEY) return 1;
if (cpi->oxcf.kf_cfg.auto_key && rc->frames_to_key == 0) return 1;
return 0;
}

void av2_get_one_pass_rt_params(AV2_COMP *cpi, FRAME_TYPE *const frame_type,
unsigned int frame_flags) {
RATE_CONTROL *const rc = &cpi->rc;
AV2_COMMON *const cm = &cpi->common;
cpi->gf_group.index = 0;
cpi->gf_group.size = 1;
GF_GROUP *const gf_group = &cpi->gf_group;
int target;
// Set frame type.
if (set_key_frame(cpi, frame_flags)) {
*frame_type = KEY_FRAME;
rc->this_key_frame_forced =
cm->current_frame.frame_number != 0 && rc->frames_to_key == 0;
rc->frames_to_key = cpi->oxcf.kf_cfg.key_freq_max;
rc->kf_boost = DEFAULT_KF_BOOST_RT;
gf_group->update_type[gf_group->index] = KF_UPDATE;
} else {
*frame_type = INTER_FRAME;
gf_group->update_type[gf_group->index] = LF_UPDATE;
}
// Set target size.
if (cpi->oxcf.rc_cfg.mode == AVM_CBR) {
if (*frame_type == KEY_FRAME || *frame_type == INTRA_ONLY_FRAME) {
target = av2_calc_iframe_target_size_one_pass_cbr(cpi);
} else {
target = av2_calc_pframe_target_size_one_pass_cbr(
cpi, gf_group->update_type[gf_group->index]);
}
} else {
if (*frame_type == KEY_FRAME || *frame_type == INTRA_ONLY_FRAME) {
target = av2_calc_iframe_target_size_one_pass_vbr(cpi);
} else {
target = av2_calc_pframe_target_size_one_pass_vbr(
cpi, gf_group->update_type[gf_group->index]);
}
}
av2_rc_set_frame_target(cpi, target, cm->width, cm->height);
rc->base_frame_target = target;
cm->current_frame.frame_type = *frame_type;
}
14 changes: 14 additions & 0 deletions av2/encoder/ratectrl.h
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,20 @@ int av2_calc_pframe_target_size_one_pass_cbr(
*/
int av2_calc_iframe_target_size_one_pass_cbr(const struct AV2_COMP *cpi);

/*!\brief Setup the rate control parameters for 1 pass real-time mode.
*
* \ingroup rate_control
* \param[in,out] cpi Top level encoder structure
* \param[out] frame_type Encoder frame type
* \param[in] frame_flags Encoder frame flags
*
* \remark Nothing is returned. Instead the settings computed in this
* function are set in: \c frame_type, \c cpi->common, \c cpi->rc.
*/
void av2_get_one_pass_rt_params(struct AV2_COMP *cpi,
FRAME_TYPE *const frame_type,
unsigned int frame_flags);

#ifdef __cplusplus
} // extern "C"
#endif
Expand Down