Modularize external interface flags in AV1_COMP
This CL groups together external interface flags from AV1_COMP into a
new struct ExternalFlags, adds relevant documentation and cleans up
function interfaces.
BUG=aomedia:2610
Change-Id: I2ea0631cd99276e1da73b1edb9d8816cdb5191ca
diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c
index e701d35..e4f9bdf 100644
--- a/av1/av1_cx_iface.c
+++ b/av1/av1_cx_iface.c
@@ -2399,7 +2399,7 @@
va_list args) {
const int reference_flag = va_arg(args, int);
- av1_use_as_reference(ctx->cpi, reference_flag);
+ av1_use_as_reference(&ctx->cpi->ext_flags.ref_frame_flags, reference_flag);
return AOM_CODEC_OK;
}
diff --git a/av1/encoder/encode_strategy.c b/av1/encoder/encode_strategy.c
index c202fe8..a2b5f55 100644
--- a/av1/encoder/encode_strategy.c
+++ b/av1/encoder/encode_strategy.c
@@ -43,6 +43,7 @@
// NOTE(weitinglin): Should we define another function to take care of
// cpi->rc.is_$Source_Type to make this function as it is in the comment?
+ const ExternalFlags *const ext_flags = &cpi->ext_flags;
cpi->rc.is_src_frame_alt_ref = 0;
switch (type) {
@@ -96,11 +97,11 @@
default: assert(0); break;
}
- if (cpi->ext_refresh_frame_flags_pending &&
+ if (ext_flags->refresh_frame_flags_pending &&
(!is_stat_generation_stage(cpi))) {
- frame_params->refresh_golden_frame = cpi->ext_refresh_golden_frame;
- frame_params->refresh_alt_ref_frame = cpi->ext_refresh_alt_ref_frame;
- frame_params->refresh_bwd_ref_frame = cpi->ext_refresh_bwd_ref_frame;
+ frame_params->refresh_golden_frame = ext_flags->refresh_golden_frame;
+ frame_params->refresh_alt_ref_frame = ext_flags->refresh_alt_ref_frame;
+ frame_params->refresh_bwd_ref_frame = ext_flags->refresh_bwd_ref_frame;
}
if (force_refresh_all) {
@@ -136,16 +137,17 @@
}
}
-static INLINE int is_frame_droppable(const AV1_COMP *const cpi) {
+static INLINE int is_frame_droppable(const SVC *const svc,
+ const ExternalFlags *const ext_flags) {
// Droppable frame is only used by external refresh flags. VoD setting won't
// trigger its use case.
- if (cpi->svc.external_ref_frame_config)
- return cpi->svc.non_reference_frame;
- else if (cpi->ext_refresh_frame_flags_pending)
- return !(cpi->ext_refresh_alt_ref_frame ||
- cpi->ext_refresh_alt2_ref_frame ||
- cpi->ext_refresh_bwd_ref_frame || cpi->ext_refresh_golden_frame ||
- cpi->ext_refresh_last_frame);
+ if (svc->external_ref_frame_config)
+ return svc->non_reference_frame;
+ else if (ext_flags->refresh_frame_flags_pending)
+ return !(ext_flags->refresh_alt_ref_frame ||
+ ext_flags->refresh_alt2_ref_frame ||
+ ext_flags->refresh_bwd_ref_frame ||
+ ext_flags->refresh_golden_frame || ext_flags->refresh_last_frame);
else
return 0;
}
@@ -155,7 +157,8 @@
// is a work-around to handle the condition when a frame is drop.
// We should fix the cpi->common.show_frame flag
// instead of checking the other condition to update the counter properly.
- if (cpi->common.show_frame || is_frame_droppable(cpi)) {
+ if (cpi->common.show_frame ||
+ is_frame_droppable(&cpi->svc, &cpi->ext_flags)) {
// Decrement count down till next gf
if (cpi->rc.frames_till_gf_update_due > 0)
cpi->rc.frames_till_gf_update_due--;
@@ -179,26 +182,25 @@
update_gf_group_index(cpi);
}
-static void set_ext_overrides(AV1_COMP *const cpi,
- EncodeFrameParams *const frame_params) {
+static void set_ext_overrides(AV1_COMMON *const cm,
+ EncodeFrameParams *const frame_params,
+ ExternalFlags *const ext_flags) {
// Overrides the defaults with the externally supplied values with
// av1_update_reference() and av1_update_entropy() calls
// Note: The overrides are valid only for the next frame passed
// to av1_encode_lowlevel()
- AV1_COMMON *const cm = &cpi->common;
-
- if (cpi->ext_use_s_frame) {
+ if (ext_flags->use_s_frame) {
frame_params->frame_type = S_FRAME;
}
- if (cpi->ext_refresh_frame_context_pending) {
- cm->features.refresh_frame_context = cpi->ext_refresh_frame_context;
- cpi->ext_refresh_frame_context_pending = 0;
+ if (ext_flags->refresh_frame_context_pending) {
+ cm->features.refresh_frame_context = ext_flags->refresh_frame_context;
+ ext_flags->refresh_frame_context_pending = 0;
}
- cm->features.allow_ref_frame_mvs = cpi->ext_use_ref_frame_mvs;
+ cm->features.allow_ref_frame_mvs = ext_flags->use_ref_frame_mvs;
- frame_params->error_resilient_mode = cpi->ext_use_error_resilient;
+ frame_params->error_resilient_mode = ext_flags->use_error_resilient;
// 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.
@@ -235,7 +237,7 @@
const int intra_only = frame_params->frame_type == KEY_FRAME ||
frame_params->frame_type == INTRA_ONLY_FRAME;
if (intra_only || frame_params->error_resilient_mode || cpi->use_svc ||
- cpi->ext_use_primary_ref_none) {
+ cpi->ext_flags.use_primary_ref_none) {
return PRIMARY_REF_NONE;
}
@@ -268,7 +270,7 @@
get_current_frame_ref_type(cpi, frame_params);
if (frame_is_intra_only(cm) || cm->features.error_resilient_mode ||
- cpi->ext_use_primary_ref_none) {
+ cpi->ext_flags.use_primary_ref_none) {
for (int i = 0; i < REF_FRAMES; i++) {
fb_of_context_type[i] = -1;
}
@@ -638,7 +640,7 @@
// expressed than converting the frame update type.
if (frame_is_sframe(cm)) frame_update_type = KEY_FRAME;
- if (is_frame_droppable(cpi)) return;
+ if (is_frame_droppable(&cpi->svc, &cpi->ext_flags)) return;
switch (frame_update_type) {
case KEY_FRAME:
@@ -725,7 +727,8 @@
FRAME_UPDATE_TYPE frame_update_type,
const RefBufferStack *const ref_buffer_stack) {
const AV1_COMMON *const cm = &cpi->common;
-
+ const ExternalFlags *const ext_flags = &cpi->ext_flags;
+ const SVC *const svc = &cpi->svc;
// Switch frames and shown key-frames overwrite all reference slots
if ((frame_params->frame_type == KEY_FRAME && frame_params->show_frame) ||
frame_params->frame_type == S_FRAME)
@@ -739,16 +742,15 @@
return 0;
}
- if (is_frame_droppable(cpi)) return 0;
+ if (is_frame_droppable(svc, ext_flags)) return 0;
int refresh_mask = 0;
- if (cpi->ext_refresh_frame_flags_pending) {
- if (cpi->svc.external_ref_frame_config) {
+ if (ext_flags->refresh_frame_flags_pending) {
+ if (svc->external_ref_frame_config) {
for (unsigned int i = 0; i < INTER_REFS_PER_FRAME; i++) {
- int ref_frame_map_idx = cpi->svc.ref_idx[i];
- refresh_mask |= cpi->svc.refresh[ref_frame_map_idx]
- << ref_frame_map_idx;
+ int ref_frame_map_idx = svc->ref_idx[i];
+ refresh_mask |= svc->refresh[ref_frame_map_idx] << ref_frame_map_idx;
}
return refresh_mask;
}
@@ -757,28 +759,28 @@
// order to preserve the behaviour of the flag overrides.
int ref_frame_map_idx = get_ref_frame_map_idx(cm, LAST_FRAME);
if (ref_frame_map_idx != INVALID_IDX)
- refresh_mask |= cpi->ext_refresh_last_frame << ref_frame_map_idx;
+ refresh_mask |= ext_flags->refresh_last_frame << ref_frame_map_idx;
ref_frame_map_idx = get_ref_frame_map_idx(cm, EXTREF_FRAME);
if (ref_frame_map_idx != INVALID_IDX)
- refresh_mask |= cpi->ext_refresh_bwd_ref_frame << ref_frame_map_idx;
+ refresh_mask |= ext_flags->refresh_bwd_ref_frame << ref_frame_map_idx;
ref_frame_map_idx = get_ref_frame_map_idx(cm, ALTREF2_FRAME);
if (ref_frame_map_idx != INVALID_IDX)
- refresh_mask |= cpi->ext_refresh_alt2_ref_frame << ref_frame_map_idx;
+ refresh_mask |= ext_flags->refresh_alt2_ref_frame << ref_frame_map_idx;
if (frame_update_type == OVERLAY_UPDATE) {
ref_frame_map_idx = get_ref_frame_map_idx(cm, ALTREF_FRAME);
if (ref_frame_map_idx != INVALID_IDX)
- refresh_mask |= cpi->ext_refresh_golden_frame << ref_frame_map_idx;
+ refresh_mask |= ext_flags->refresh_golden_frame << ref_frame_map_idx;
} else {
ref_frame_map_idx = get_ref_frame_map_idx(cm, GOLDEN_FRAME);
if (ref_frame_map_idx != INVALID_IDX)
- refresh_mask |= cpi->ext_refresh_golden_frame << ref_frame_map_idx;
+ refresh_mask |= ext_flags->refresh_golden_frame << ref_frame_map_idx;
ref_frame_map_idx = get_ref_frame_map_idx(cm, ALTREF_FRAME);
if (ref_frame_map_idx != INVALID_IDX)
- refresh_mask |= cpi->ext_refresh_alt_ref_frame << ref_frame_map_idx;
+ refresh_mask |= ext_flags->refresh_alt_ref_frame << ref_frame_map_idx;
}
return refresh_mask;
}
@@ -1047,6 +1049,7 @@
const AV1EncoderConfig *const oxcf = &cpi->oxcf;
AV1_COMMON *const cm = &cpi->common;
GF_GROUP *gf_group = &cpi->gf_group;
+ ExternalFlags *const ext_flags = &cpi->ext_flags;
EncodeFrameInput frame_input;
EncodeFrameParams frame_params;
@@ -1196,7 +1199,8 @@
#endif
}
- if (!is_stat_generation_stage(cpi)) set_ext_overrides(cpi, &frame_params);
+ if (!is_stat_generation_stage(cpi))
+ set_ext_overrides(cm, &frame_params, ext_flags);
// Shown keyframes and S frames refresh all reference buffers
const int force_refresh_all =
@@ -1211,7 +1215,7 @@
const RefCntBuffer *ref_frames[INTER_REFS_PER_FRAME];
const YV12_BUFFER_CONFIG *ref_frame_buf[INTER_REFS_PER_FRAME];
- if (!cpi->ext_refresh_frame_flags_pending) {
+ if (!ext_flags->refresh_frame_flags_pending) {
av1_get_ref_frames(cpi, &cpi->ref_buffer_stack);
} else if (cpi->svc.external_ref_frame_config) {
for (unsigned int i = 0; i < INTER_REFS_PER_FRAME; i++)
@@ -1224,7 +1228,8 @@
ref_frame_buf[i] = ref_frames[i] != NULL ? &ref_frames[i]->buf : NULL;
}
// Work out which reference frame slots may be used.
- frame_params.ref_frame_flags = get_ref_frame_flags(cpi, ref_frame_buf);
+ frame_params.ref_frame_flags = get_ref_frame_flags(
+ &cpi->sf, ref_frame_buf, ext_flags->ref_frame_flags);
frame_params.primary_ref_frame =
choose_primary_ref_frame(cpi, &frame_params);
@@ -1286,7 +1291,7 @@
// First pass doesn't modify reference buffer assignment or produce frame
// flags
update_frame_flags(cpi, frame_flags);
- if (!cpi->ext_refresh_frame_flags_pending) {
+ if (!ext_flags->refresh_frame_flags_pending) {
int ref_map_index =
av1_get_refresh_ref_frame_map(cm->current_frame.refresh_frame_flags);
av1_update_ref_frame_map(cpi, frame_update_type, cm->show_existing_frame,
@@ -1319,7 +1324,7 @@
// Leave a signal for a higher level caller about if this frame is droppable
if (*size > 0) {
- cpi->droppable = is_frame_droppable(cpi);
+ cpi->droppable = is_frame_droppable(&cpi->svc, ext_flags);
}
if (cpi->use_svc) av1_save_layer_context(cpi);
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index 32e552f..93eefca 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -615,7 +615,7 @@
// context 1 for ALTREF frames and context 0 for the others.
if (frame_is_intra_only(cm) || cm->features.error_resilient_mode ||
- cpi->ext_use_primary_ref_none) {
+ cpi->ext_flags.use_primary_ref_none) {
av1_setup_past_independence(cm);
}
@@ -2951,8 +2951,8 @@
set_tile_info(cpi);
if (!cpi->svc.external_ref_frame_config)
- cpi->ext_refresh_frame_flags_pending = 0;
- cpi->ext_refresh_frame_context_pending = 0;
+ cpi->ext_flags.refresh_frame_flags_pending = 0;
+ cpi->ext_flags.refresh_frame_context_pending = 0;
#if CONFIG_AV1_HIGHBITDEPTH
highbd_set_var_fns(cpi);
@@ -3701,10 +3701,10 @@
aom_codec_pkt_list_add(cpi->output_pkt_list, &pkt);
}
-int av1_use_as_reference(AV1_COMP *cpi, int ref_frame_flags) {
+int av1_use_as_reference(int *ext_ref_frame_flags, int ref_frame_flags) {
if (ref_frame_flags > ((1 << INTER_REFS_PER_FRAME) - 1)) return -1;
- cpi->ext_ref_frame_flags = ref_frame_flags;
+ *ext_ref_frame_flags = ref_frame_flags;
return 0;
}
@@ -3732,9 +3732,10 @@
}
}
-int av1_update_entropy(AV1_COMP *cpi, int update) {
- cpi->ext_refresh_frame_context = update;
- cpi->ext_refresh_frame_context_pending = 1;
+int av1_update_entropy(bool *ext_refresh_frame_context,
+ bool *ext_refresh_frame_context_pending, bool update) {
+ *ext_refresh_frame_context = update;
+ *ext_refresh_frame_context_pending = 1;
return 0;
}
@@ -7026,17 +7027,18 @@
return AOM_CODEC_OK;
}
-static void svc_set_updates_external_ref_frame_config(AV1_COMP *cpi) {
- cpi->ext_refresh_frame_flags_pending = 1;
- cpi->ext_refresh_last_frame = cpi->svc.refresh[cpi->svc.ref_idx[0]];
- cpi->ext_refresh_golden_frame = cpi->svc.refresh[cpi->svc.ref_idx[3]];
- cpi->ext_refresh_bwd_ref_frame = cpi->svc.refresh[cpi->svc.ref_idx[4]];
- cpi->ext_refresh_alt2_ref_frame = cpi->svc.refresh[cpi->svc.ref_idx[5]];
- cpi->ext_refresh_alt_ref_frame = cpi->svc.refresh[cpi->svc.ref_idx[6]];
- cpi->svc.non_reference_frame = 1;
+static void svc_set_updates_external_ref_frame_config(
+ ExternalFlags *const ext_flags, SVC *const svc) {
+ ext_flags->refresh_frame_flags_pending = 1;
+ ext_flags->refresh_last_frame = svc->refresh[svc->ref_idx[0]];
+ ext_flags->refresh_golden_frame = svc->refresh[svc->ref_idx[3]];
+ ext_flags->refresh_bwd_ref_frame = svc->refresh[svc->ref_idx[4]];
+ ext_flags->refresh_alt2_ref_frame = svc->refresh[svc->ref_idx[5]];
+ ext_flags->refresh_alt_ref_frame = svc->refresh[svc->ref_idx[6]];
+ svc->non_reference_frame = 1;
for (int i = 0; i < REF_FRAMES; i++) {
- if (cpi->svc.refresh[i] == 1) {
- cpi->svc.non_reference_frame = 0;
+ if (svc->refresh[i] == 1) {
+ svc->non_reference_frame = 0;
break;
}
}
@@ -7058,7 +7060,9 @@
// ensure that there is not conflict between the two. In AV1 encoder, the
// priority rank for 7 reference frames are: LAST, ALTREF, LAST2, LAST3,
// GOLDEN, BWDREF, ALTREF2.
- cpi->ext_ref_frame_flags = AOM_REFFRAME_ALL;
+
+ ExternalFlags *const ext_flags = &cpi->ext_flags;
+ ext_flags->ref_frame_flags = AOM_REFFRAME_ALL;
if (flags &
(AOM_EFLAG_NO_REF_LAST | AOM_EFLAG_NO_REF_LAST2 | AOM_EFLAG_NO_REF_LAST3 |
AOM_EFLAG_NO_REF_GF | AOM_EFLAG_NO_REF_ARF | AOM_EFLAG_NO_REF_BWD |
@@ -7080,11 +7084,11 @@
if (flags & AOM_EFLAG_NO_REF_ARF2) ref ^= AOM_ALT2_FLAG;
}
- av1_use_as_reference(cpi, ref);
+ av1_use_as_reference(&ext_flags->ref_frame_flags, ref);
} else {
if (cpi->svc.external_ref_frame_config) {
int ref = svc_set_references_external_ref_frame_config(cpi);
- av1_use_as_reference(cpi, ref);
+ av1_use_as_reference(&ext_flags->ref_frame_flags, ref);
}
}
@@ -7103,29 +7107,31 @@
upd ^= AOM_ALT2_FLAG;
}
- cpi->ext_refresh_last_frame = (upd & AOM_LAST_FLAG) != 0;
- cpi->ext_refresh_golden_frame = (upd & AOM_GOLD_FLAG) != 0;
- cpi->ext_refresh_alt_ref_frame = (upd & AOM_ALT_FLAG) != 0;
- cpi->ext_refresh_bwd_ref_frame = (upd & AOM_BWD_FLAG) != 0;
- cpi->ext_refresh_alt2_ref_frame = (upd & AOM_ALT2_FLAG) != 0;
- cpi->ext_refresh_frame_flags_pending = 1;
+ ext_flags->refresh_last_frame = (upd & AOM_LAST_FLAG) != 0;
+ ext_flags->refresh_golden_frame = (upd & AOM_GOLD_FLAG) != 0;
+ ext_flags->refresh_alt_ref_frame = (upd & AOM_ALT_FLAG) != 0;
+ ext_flags->refresh_bwd_ref_frame = (upd & AOM_BWD_FLAG) != 0;
+ ext_flags->refresh_alt2_ref_frame = (upd & AOM_ALT2_FLAG) != 0;
+ ext_flags->refresh_frame_flags_pending = 1;
} else {
if (cpi->svc.external_ref_frame_config)
- svc_set_updates_external_ref_frame_config(cpi);
+ svc_set_updates_external_ref_frame_config(ext_flags, &cpi->svc);
else
- cpi->ext_refresh_frame_flags_pending = 0;
+ ext_flags->refresh_frame_flags_pending = 0;
}
- cpi->ext_use_ref_frame_mvs = cpi->oxcf.allow_ref_frame_mvs &
- ((flags & AOM_EFLAG_NO_REF_FRAME_MVS) == 0);
- cpi->ext_use_error_resilient = cpi->oxcf.error_resilient_mode |
- ((flags & AOM_EFLAG_ERROR_RESILIENT) != 0);
- cpi->ext_use_s_frame =
+ ext_flags->use_ref_frame_mvs = cpi->oxcf.allow_ref_frame_mvs &
+ ((flags & AOM_EFLAG_NO_REF_FRAME_MVS) == 0);
+ ext_flags->use_error_resilient = cpi->oxcf.error_resilient_mode |
+ ((flags & AOM_EFLAG_ERROR_RESILIENT) != 0);
+ ext_flags->use_s_frame =
cpi->oxcf.s_frame_mode | ((flags & AOM_EFLAG_SET_S_FRAME) != 0);
- cpi->ext_use_primary_ref_none = (flags & AOM_EFLAG_SET_PRIMARY_REF_NONE) != 0;
+ ext_flags->use_primary_ref_none =
+ (flags & AOM_EFLAG_SET_PRIMARY_REF_NONE) != 0;
if (flags & AOM_EFLAG_NO_UPD_ENTROPY) {
- av1_update_entropy(cpi, 0);
+ av1_update_entropy(&ext_flags->refresh_frame_context,
+ &ext_flags->refresh_frame_context_pending, 0);
}
}
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index 0de8b2b..4a3cb4f 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -958,6 +958,43 @@
} WinnerModeParams;
typedef struct {
+ // Bit mask to disable certain reference frame types.
+ int ref_frame_flags;
+
+ // Flags to determine which reference buffers are refreshed by this frame.
+ // When set, the encoder will update the particular reference frame buffer
+ // with the contents of the current frame.
+ bool refresh_last_frame;
+ bool refresh_golden_frame;
+ bool refresh_bwd_ref_frame;
+ bool refresh_alt2_ref_frame;
+ bool refresh_alt_ref_frame;
+
+ // Flag to indicate that updation of refresh frame flags from external
+ // interface is pending.
+ bool refresh_frame_flags_pending;
+
+ // Flag to enable the updation of frame contexts at the end of a frame decode.
+ bool refresh_frame_context;
+
+ // Flag to indicate that updation of refresh_frame_context from external
+ // interface is pending.
+ bool refresh_frame_context_pending;
+
+ // Flag to enable temporal MV prediction.
+ bool use_ref_frame_mvs;
+
+ // Flag to code the frame as error-resilient.
+ bool use_error_resilient;
+
+ // Flag to code the frame as s-frame.
+ bool use_s_frame;
+
+ // Flag to set the frame's primary_ref_frame to PRIMARY_REF_NONE.
+ bool use_primary_ref_none;
+} ExternalFlags;
+
+typedef struct {
int arf_stack[FRAME_BUFFERS];
int arf_stack_size;
int lst_stack[FRAME_BUFFERS];
@@ -1071,19 +1108,8 @@
// frame of the same type as the current frame).
int fb_of_context_type[REF_FRAMES];
- int ext_refresh_frame_flags_pending;
- int ext_refresh_last_frame;
- int ext_refresh_golden_frame;
- int ext_refresh_bwd_ref_frame;
- int ext_refresh_alt2_ref_frame;
- int ext_refresh_alt_ref_frame;
-
- int ext_refresh_frame_context_pending;
- int ext_refresh_frame_context;
- int ext_use_ref_frame_mvs;
- int ext_use_error_resilient;
- int ext_use_s_frame;
- int ext_use_primary_ref_none;
+ // Flags signalled by the external interface at frame level.
+ ExternalFlags ext_flags;
YV12_BUFFER_CONFIG last_frame_uf;
YV12_BUFFER_CONFIG trial_frame_rst;
@@ -1110,7 +1136,6 @@
struct aom_codec_pkt_list *output_pkt_list;
int ref_frame_flags;
- int ext_ref_frame_flags;
// speed is passed as a per-frame parameter into the encoder
int speed;
@@ -1396,7 +1421,7 @@
YV12_BUFFER_CONFIG *new_frame,
YV12_BUFFER_CONFIG *sd);
-int av1_use_as_reference(AV1_COMP *cpi, int ref_frame_flags);
+int av1_use_as_reference(int *ext_ref_frame_flags, int ref_frame_flags);
int av1_copy_reference_enc(AV1_COMP *cpi, int idx, YV12_BUFFER_CONFIG *sd);
@@ -1406,7 +1431,8 @@
void av1_set_frame_size(AV1_COMP *cpi, int width, int height);
-int av1_update_entropy(AV1_COMP *cpi, int update);
+int av1_update_entropy(bool *ext_refresh_frame_context,
+ bool *ext_refresh_frame_context_pending, bool update);
int av1_set_active_map(AV1_COMP *cpi, unsigned char *map, int rows, int cols);
@@ -1731,22 +1757,23 @@
ALTREF2_FRAME, LAST2_FRAME, LAST3_FRAME,
};
-static INLINE int get_ref_frame_flags(const AV1_COMP *const cpi,
- const YV12_BUFFER_CONFIG **ref_frames) {
- // cpi->ext_ref_frame_flags allows certain reference types to be disabled
- // by the external interface. These are set by av1_apply_encoding_flags().
- // Start with what the external interface allows, then suppress any reference
- // types which we have found to be duplicates.
- int flags = cpi->ext_ref_frame_flags;
+static INLINE int get_ref_frame_flags(const SPEED_FEATURES *const sf,
+ const YV12_BUFFER_CONFIG **ref_frames,
+ const int ext_ref_frame_flags) {
+ // cpi->ext_flags.ref_frame_flags allows certain reference types to be
+ // disabled by the external interface. These are set by
+ // av1_apply_encoding_flags(). Start with what the external interface allows,
+ // then suppress any reference types which we have found to be duplicates.
+ int flags = ext_ref_frame_flags;
for (int i = 1; i < INTER_REFS_PER_FRAME; ++i) {
const YV12_BUFFER_CONFIG *const this_ref = ref_frames[i];
// If this_ref has appeared before, mark the corresponding ref frame as
// invalid. For nonrd mode, only disable GOLDEN_FRAME if it's the same
// as LAST_FRAME or ALTREF_FRAME (if ALTREF is being used in nonrd).
- int index = (cpi->sf.rt_sf.use_nonrd_pick_mode &&
+ int index = (sf->rt_sf.use_nonrd_pick_mode &&
ref_frame_priority_order[i] == GOLDEN_FRAME)
- ? (1 + cpi->sf.rt_sf.use_nonrd_altref_frame)
+ ? (1 + sf->rt_sf.use_nonrd_altref_frame)
: i;
for (int j = 0; j < index; ++j) {
if (this_ref == ref_frames[j]) {
diff --git a/av1/encoder/ratectrl.c b/av1/encoder/ratectrl.c
index 144d9e0..eec48bd 100644
--- a/av1/encoder/ratectrl.c
+++ b/av1/encoder/ratectrl.c
@@ -1957,6 +1957,8 @@
static void set_reference_structure_one_pass_rt(AV1_COMP *cpi, int gf_update) {
AV1_COMMON *const cm = &cpi->common;
+ ExternalFlags *const ext_flags = &cpi->ext_flags;
+ SVC *const svc = &cpi->svc;
// Specify the reference prediction structure, for 1 layer nonrd mode.
// Current structue is to use 3 references (LAST, GOLDEN, ALTREF),
// where ALT_REF always behind current by lag_alt frames, and GOLDEN is
@@ -1968,18 +1970,18 @@
int last_idx_refresh = 0;
int gld_idx = 0;
int alt_ref_idx = 0;
- cpi->ext_refresh_frame_flags_pending = 1;
- cpi->svc.external_ref_frame_config = 1;
- cpi->ext_ref_frame_flags = 0;
- cpi->ext_refresh_last_frame = 1;
- cpi->ext_refresh_golden_frame = 0;
- cpi->ext_refresh_alt_ref_frame = 0;
- for (int i = 0; i < INTER_REFS_PER_FRAME; ++i) cpi->svc.ref_idx[i] = 7;
- for (int i = 0; i < REF_FRAMES; ++i) cpi->svc.refresh[i] = 0;
+ ext_flags->refresh_frame_flags_pending = 1;
+ svc->external_ref_frame_config = 1;
+ ext_flags->ref_frame_flags = 0;
+ ext_flags->refresh_last_frame = 1;
+ ext_flags->refresh_golden_frame = 0;
+ ext_flags->refresh_alt_ref_frame = 0;
+ for (int i = 0; i < INTER_REFS_PER_FRAME; ++i) svc->ref_idx[i] = 7;
+ for (int i = 0; i < REF_FRAMES; ++i) svc->refresh[i] = 0;
// Always reference LAST, GOLDEN, ALTREF
- cpi->ext_ref_frame_flags ^= AOM_LAST_FLAG;
- cpi->ext_ref_frame_flags ^= AOM_GOLD_FLAG;
- cpi->ext_ref_frame_flags ^= AOM_ALT_FLAG;
+ ext_flags->ref_frame_flags ^= AOM_LAST_FLAG;
+ ext_flags->ref_frame_flags ^= AOM_GOLD_FLAG;
+ ext_flags->ref_frame_flags ^= AOM_ALT_FLAG;
const int sh = 7 - gld_fixed_slot;
// Moving index slot for last: 0 - (sh - 1).
if (cm->current_frame.frame_number > 1)
@@ -1997,16 +1999,16 @@
// Moving index for alt_ref, lag behind LAST by lag_alt frames.
if (cm->current_frame.frame_number > lag_alt)
alt_ref_idx = ((cm->current_frame.frame_number - lag_alt) % sh);
- cpi->svc.ref_idx[0] = last_idx; // LAST
- cpi->svc.ref_idx[1] = last_idx_refresh; // LAST2 (for refresh of last).
- cpi->svc.ref_idx[3] = gld_idx; // GOLDEN
- cpi->svc.ref_idx[6] = alt_ref_idx; // ALT_REF
+ svc->ref_idx[0] = last_idx; // LAST
+ svc->ref_idx[1] = last_idx_refresh; // LAST2 (for refresh of last).
+ svc->ref_idx[3] = gld_idx; // GOLDEN
+ svc->ref_idx[6] = alt_ref_idx; // ALT_REF
// Refresh this slot, which will become LAST on next frame.
- cpi->svc.refresh[last_idx_refresh] = 1;
+ svc->refresh[last_idx_refresh] = 1;
// Update GOLDEN on period for fixed slot case.
if (gld_fixed_slot && gf_update) {
- cpi->ext_refresh_golden_frame = 1;
- cpi->svc.refresh[gld_idx] = 1;
+ ext_flags->refresh_golden_frame = 1;
+ svc->refresh[gld_idx] = 1;
}
}
diff --git a/av1/encoder/tpl_model.c b/av1/encoder/tpl_model.c
index af192f6..1736750 100644
--- a/av1/encoder/tpl_model.c
+++ b/av1/encoder/tpl_model.c
@@ -715,7 +715,8 @@
}
// Work out which reference frame slots may be used.
- ref_frame_flags = get_ref_frame_flags(cpi, ref_frames_ordered);
+ ref_frame_flags = get_ref_frame_flags(&cpi->sf, ref_frames_ordered,
+ cpi->ext_flags.ref_frame_flags);
enforce_max_ref_frames(cpi, &ref_frame_flags);