Commit 9a50fec3 authored by Yunqing Wang's avatar Yunqing Wang

Update the encoder flags for reference frames using and updating

Updated the encoder flags for externally setting reference frames using
and updating to include latest changes in AV1.

1. For what reference frames to use, always initilize
cpi->ref_frame_flags with AOM_REFFRAME_ALL at the beginning of encoding
a frame. The internal ref_frame_flags starts from external flags. Added
AOM_EFLAG_NO_REF_LAST2 and AOM_EFLAG_NO_REF_LAST3 for LAST2 and LAST3.

2. For what reference frames to update, added ext_refresh_bwd_ref_frame
and ext_refresh_alt2_ref_frame for BWD and ALT2. Also, removed
AOM_EFLAG_FORCE_GF and AOM_EFLAG_FORCE_ARF since these are never
actually used. They can be added back if needed later.

Change-Id: I1e4429290f09bfcd1b26f2babc0cf556fc6fbc6c
parent 8d88b297
......@@ -48,14 +48,27 @@ extern aom_codec_iface_t *aom_codec_av1_cx(void);
* last frame or not automatically.
*/
#define AOM_EFLAG_NO_REF_LAST (1 << 16)
/*!\brief Don't reference the last2 frame
*
* When this flag is set, the encoder will not use the last2 frame as a
* predictor. When not set, the encoder will choose whether to use the
* last2 frame or not automatically.
*/
#define AOM_EFLAG_NO_REF_LAST2 (1 << 17)
/*!\brief Don't reference the last3 frame
*
* When this flag is set, the encoder will not use the last3 frame as a
* predictor. When not set, the encoder will choose whether to use the
* last3 frame or not automatically.
*/
#define AOM_EFLAG_NO_REF_LAST3 (1 << 18)
/*!\brief Don't reference the golden frame
*
* When this flag is set, the encoder will not use the golden frame as a
* predictor. When not set, the encoder will choose whether to use the
* golden frame or not automatically.
*/
#define AOM_EFLAG_NO_REF_GF (1 << 17)
#define AOM_EFLAG_NO_REF_GF (1 << 19)
/*!\brief Don't reference the alternate reference frame
*
......@@ -63,49 +76,48 @@ extern aom_codec_iface_t *aom_codec_av1_cx(void);
* predictor. When not set, the encoder will choose whether to use the
* alt ref frame or not automatically.
*/
#define AOM_EFLAG_NO_REF_ARF (1 << 21)
#define AOM_EFLAG_NO_REF_ARF (1 << 20)
/*!\brief Don't reference the bwd reference frame
*
* When this flag is set, the encoder will not use the bwd ref frame as a
* predictor. When not set, the encoder will choose whether to use the
* bwd ref frame or not automatically.
*/
#define AOM_EFLAG_NO_REF_BWD (1 << 21)
/*!\brief Don't reference the alt2 reference frame
*
* When this flag is set, the encoder will not use the alt2 ref frame as a
* predictor. When not set, the encoder will choose whether to use the
* alt2 ref frame or not automatically.
*/
#define AOM_EFLAG_NO_REF_ARF2 (1 << 22)
/*!\brief Don't update the last frame
*
* When this flag is set, the encoder will not update the last frame with
* the contents of the current frame.
*/
#define AOM_EFLAG_NO_UPD_LAST (1 << 18)
#define AOM_EFLAG_NO_UPD_LAST (1 << 23)
/*!\brief Don't update the golden frame
*
* When this flag is set, the encoder will not update the golden frame with
* the contents of the current frame.
*/
#define AOM_EFLAG_NO_UPD_GF (1 << 22)
#define AOM_EFLAG_NO_UPD_GF (1 << 24)
/*!\brief Don't update the alternate reference frame
*
* When this flag is set, the encoder will not update the alt ref frame with
* the contents of the current frame.
*/
#define AOM_EFLAG_NO_UPD_ARF (1 << 23)
/*!\brief Force golden frame update
*
* When this flag is set, the encoder copy the contents of the current frame
* to the golden frame buffer.
*/
#define AOM_EFLAG_FORCE_GF (1 << 19)
/*!\brief Force alternate reference frame update
*
* When this flag is set, the encoder copy the contents of the current frame
* to the alternate reference frame buffer.
*/
#define AOM_EFLAG_FORCE_ARF (1 << 24)
#define AOM_EFLAG_NO_UPD_ARF (1 << 25)
/*!\brief Disable entropy update
*
* When this flag is set, the encoder will not update its internal entropy
* model based on the entropy of this frame.
*/
#define AOM_EFLAG_NO_UPD_ENTROPY (1 << 20)
#define AOM_EFLAG_NO_UPD_ENTROPY (1 << 26)
/*!\brief AVx encoder control functions
*
......
......@@ -1184,13 +1184,6 @@ static aom_codec_err_t encoder_encode(aom_codec_alg_priv_t *ctx,
volatile aom_enc_frame_flags_t flags = enc_flags;
// Handle Flags
if (((flags & AOM_EFLAG_NO_UPD_GF) && (flags & AOM_EFLAG_FORCE_GF)) ||
((flags & AOM_EFLAG_NO_UPD_ARF) && (flags & AOM_EFLAG_FORCE_ARF))) {
ctx->base.err_detail = "Conflicting flags.";
return AOM_CODEC_INVALID_PARAM;
}
if (setjmp(cpi->common.error.jmp)) {
cpi->common.error.setjmp = 0;
res = update_error_state(ctx, &cpi->common.error);
......@@ -1199,6 +1192,9 @@ static aom_codec_err_t encoder_encode(aom_codec_alg_priv_t *ctx,
}
cpi->common.error.setjmp = 1;
// Note(yunqing): While applying encoding flags, always start from enabling
// all, and then modifying according to the flags. Previous frame's flags are
// overwritten.
av1_apply_encoding_flags(cpi, flags);
// Handle fixed keyframe intervals
......
......@@ -3364,10 +3364,12 @@ int av1_use_as_reference(AV1_COMP *cpi, int ref_frame_flags) {
return 0;
}
void av1_update_reference(AV1_COMP *cpi, int ref_frame_flags) {
cpi->ext_refresh_golden_frame = (ref_frame_flags & AOM_GOLD_FLAG) != 0;
cpi->ext_refresh_alt_ref_frame = (ref_frame_flags & AOM_ALT_FLAG) != 0;
cpi->ext_refresh_last_frame = (ref_frame_flags & AOM_LAST_FLAG) != 0;
void av1_update_reference(AV1_COMP *cpi, int ref_frame_upd_flags) {
cpi->ext_refresh_last_frame = (ref_frame_upd_flags & AOM_LAST_FLAG) != 0;
cpi->ext_refresh_golden_frame = (ref_frame_upd_flags & AOM_GOLD_FLAG) != 0;
cpi->ext_refresh_alt_ref_frame = (ref_frame_upd_flags & AOM_ALT_FLAG) != 0;
cpi->ext_refresh_bwd_ref_frame = (ref_frame_upd_flags & AOM_BWD_FLAG) != 0;
cpi->ext_refresh_alt2_ref_frame = (ref_frame_upd_flags & AOM_ALT2_FLAG) != 0;
cpi->ext_refresh_frame_flags_pending = 1;
}
......@@ -5101,7 +5103,9 @@ static int get_ref_frame_flags(const AV1_COMP *cpi) {
// No.7 Priority: ALTREF2_FRAME
int flags = AOM_REFFRAME_ALL;
// After av1_apply_encoding_flags() is called, cpi->ref_frame_flags might be
// adjusted according to external encoder flags.
int flags = cpi->ref_frame_flags;
if (cpi->rc.frames_till_gf_update_due == INT_MAX) flags &= ~AOM_GOLD_FLAG;
......@@ -5140,6 +5144,8 @@ static void set_ext_overrides(AV1_COMP *cpi) {
cpi->refresh_last_frame = cpi->ext_refresh_last_frame;
cpi->refresh_golden_frame = cpi->ext_refresh_golden_frame;
cpi->refresh_alt_ref_frame = cpi->ext_refresh_alt_ref_frame;
cpi->refresh_bwd_ref_frame = cpi->ext_refresh_bwd_ref_frame;
cpi->refresh_alt2_ref_frame = cpi->ext_refresh_alt2_ref_frame;
cpi->ext_refresh_frame_flags_pending = 0;
}
}
......@@ -6714,37 +6720,54 @@ int av1_set_internal_size(AV1_COMP *cpi, AOM_SCALING horiz_mode,
int av1_get_quantizer(AV1_COMP *cpi) { return cpi->common.base_qindex; }
void av1_apply_encoding_flags(AV1_COMP *cpi, aom_enc_frame_flags_t flags) {
// TODO(yunqingwang): For what references to use, external encoding flags
// should be consistent with internal reference frame selection. Need to
// 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. If only one reference frame is used, it must be
// LAST.
cpi->ref_frame_flags = AOM_REFFRAME_ALL;
if (flags &
(AOM_EFLAG_NO_REF_LAST | AOM_EFLAG_NO_REF_GF | AOM_EFLAG_NO_REF_ARF)) {
int ref = AOM_REFFRAME_ALL;
(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 |
AOM_EFLAG_NO_REF_ARF2)) {
if (flags & AOM_EFLAG_NO_REF_LAST) {
ref ^= AOM_LAST_FLAG;
ref ^= AOM_LAST2_FLAG;
ref ^= AOM_LAST3_FLAG;
}
cpi->ref_frame_flags = 0;
} else {
int ref = AOM_REFFRAME_ALL;
if (flags & AOM_EFLAG_NO_REF_GF) ref ^= AOM_GOLD_FLAG;
if (flags & AOM_EFLAG_NO_REF_LAST2) ref ^= AOM_LAST2_FLAG;
if (flags & AOM_EFLAG_NO_REF_LAST3) ref ^= AOM_LAST3_FLAG;
if (flags & AOM_EFLAG_NO_REF_ARF) ref ^= AOM_ALT_FLAG;
if (flags & AOM_EFLAG_NO_REF_GF) ref ^= AOM_GOLD_FLAG;
av1_use_as_reference(cpi, ref);
if (flags & AOM_EFLAG_NO_REF_ARF) {
ref ^= AOM_ALT_FLAG;
ref ^= AOM_BWD_FLAG;
ref ^= AOM_ALT2_FLAG;
} else {
if (flags & AOM_EFLAG_NO_REF_BWD) ref ^= AOM_BWD_FLAG;
if (flags & AOM_EFLAG_NO_REF_ARF2) ref ^= AOM_ALT2_FLAG;
}
av1_use_as_reference(cpi, ref);
}
}
if (flags &
(AOM_EFLAG_NO_UPD_LAST | AOM_EFLAG_NO_UPD_GF | AOM_EFLAG_NO_UPD_ARF |
AOM_EFLAG_FORCE_GF | AOM_EFLAG_FORCE_ARF)) {
(AOM_EFLAG_NO_UPD_LAST | AOM_EFLAG_NO_UPD_GF | AOM_EFLAG_NO_UPD_ARF)) {
int upd = AOM_REFFRAME_ALL;
if (flags & AOM_EFLAG_NO_UPD_LAST) {
upd ^= AOM_LAST_FLAG;
upd ^= AOM_LAST2_FLAG;
upd ^= AOM_LAST3_FLAG;
}
// Refreshing LAST/LAST2/LAST3 is handled by 1 common flag.
if (flags & AOM_EFLAG_NO_UPD_LAST) upd ^= AOM_LAST_FLAG;
if (flags & AOM_EFLAG_NO_UPD_GF) upd ^= AOM_GOLD_FLAG;
if (flags & AOM_EFLAG_NO_UPD_ARF) upd ^= AOM_ALT_FLAG;
if (flags & AOM_EFLAG_NO_UPD_ARF) {
upd ^= AOM_ALT_FLAG;
upd ^= AOM_BWD_FLAG;
upd ^= AOM_ALT2_FLAG;
}
av1_update_reference(cpi, upd);
}
......
......@@ -424,6 +424,8 @@ typedef struct AV1_COMP {
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;
......
......@@ -190,9 +190,8 @@ static aom_fixed_buf_t pass0(aom_image_t *raw, FILE *infile,
die_codec(&codec, "Failed to set reference flags");
// Reference frames can be encoded encoded without tiles.
++frame_count;
get_frame_stats(&codec, raw, frame_count, 1,
AOM_EFLAG_FORCE_GF | AOM_EFLAG_NO_UPD_ENTROPY, deadline,
&stats);
get_frame_stats(&codec, raw, frame_count, 1, AOM_EFLAG_NO_UPD_ENTROPY,
deadline, &stats);
ref_frame.idx = 0;
aom_codec_control(&codec, AV1_GET_REFERENCE, &ref_frame);
aom_img_copy(&ref_frame.img, &reference_images[frame_count - 1]);
......@@ -317,9 +316,8 @@ static void pass1(aom_image_t *raw, FILE *infile, const char *outfile_name,
++frame_count;
printf("Encoding reference image %d of %d\n", bv * u_blocks + bu,
u_blocks * v_blocks);
encode_frame(&codec, raw, frame_count, 1,
AOM_EFLAG_FORCE_GF | AOM_EFLAG_NO_UPD_ENTROPY, deadline,
writer);
encode_frame(&codec, raw, frame_count, 1, AOM_EFLAG_NO_UPD_ENTROPY,
deadline, writer);
ref_frame.idx = 0;
aom_codec_control(&codec, AV1_GET_REFERENCE, &ref_frame);
aom_img_copy(&ref_frame.img, &reference_images[frame_count - 1]);
......
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