Move interp_filter_selected to RefCntBuffer
cpi->interp_filter_selected is currently indexed by reference, so a
swathe of memcpys are required to keep it in sync with reference frame
refreshing and reference reassignment. In this commit I move it to
RefCntBuffer so it is automatically refreshed and and assigned.
Because the old memcpys did not exactly mirror reference buffer
refreshing and re-assignment, behaviour is changed slightly by this
patch when the interp filter mask speed-feature is enabled (speed >= 2),
however rdcost change seems to be negligible.
STATS_CHANGED
AWCY for speed=2: https://arewecompressedyet.com/?job=base%402019-02-15T16%3A59%3A48.521Z&job=test%402019-02-15T17%3A01%3A42.026Z
AWCY for speed=5: https://arewecompressedyet.com/?job=base%402019-02-16T21%3A13%3A27.877Z&job=test%402019-02-16T21%3A13%3A36.627Z
Change-Id: Iad492bc4b76ded5b57576a19b20c348ab5906415
diff --git a/av1/common/onyxc_int.h b/av1/common/onyxc_int.h
index d5668a7..4b9529d 100644
--- a/av1/common/onyxc_int.h
+++ b/av1/common/onyxc_int.h
@@ -136,8 +136,6 @@
// - Total 'n' of the variables / array elements above have value 'k' (that
// is, they are pointing to buffer at index 'k').
// Then, pool->frame_bufs[k].ref_count = n.
- // TODO(david.turner@argondesign.com) Check whether this helpful comment is
- // still correct after we finish restructuring
int ref_count;
unsigned int order_hint;
@@ -161,6 +159,10 @@
hash_table hash_table;
FRAME_TYPE frame_type;
+ // This is only used in the encoder but needs to be indexed per ref frame
+ // so it's extremely convenient to keep it here.
+ int interp_filter_selected[SWITCHABLE];
+
// Inter frame reference frame delta for loop filter
int8_t ref_deltas[REF_FRAMES];
@@ -643,6 +645,7 @@
cm->cur_frame = &cm->buffer_pool->frame_bufs[new_fb_idx];
cm->cur_frame->buf.buf_8bit_valid = 0;
+ av1_zero(cm->cur_frame->interp_filter_selected);
return cm->cur_frame;
}
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index 8e4daf7..766c9e0 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -627,7 +627,7 @@
av1_extract_interp_filter(mbmi->interp_filters, dir);
aom_write_symbol(w, filter, ec_ctx->switchable_interp_cdf[ctx],
SWITCHABLE_FILTERS);
- ++cpi->interp_filter_selected[0][filter];
+ ++cm->cur_frame->interp_filter_selected[filter];
if (cm->seq_params.enable_dual_filter == 0) return;
}
}
diff --git a/av1/encoder/encode_strategy.c b/av1/encoder/encode_strategy.c
index f47eef2..db38581 100644
--- a/av1/encoder/encode_strategy.c
+++ b/av1/encoder/encode_strategy.c
@@ -814,12 +814,6 @@
const int ref_idx = ref_frame - LAST_FRAME;
cpi->common.remapped_ref_idx[ref_idx] =
cpi->common.remapped_ref_idx[ref_idx - 1];
-
- if (!cpi->rc.is_src_frame_alt_ref) {
- memcpy(cpi->interp_filter_selected[ref_frame],
- cpi->interp_filter_selected[ref_frame - 1],
- sizeof(cpi->interp_filter_selected[ref_frame - 1]));
- }
}
}
@@ -833,11 +827,6 @@
EXTREF_FRAME };
for (int i = 2; i > 0; --i) {
- // [0] is allocated to the current coded frame, i.e. bwdref
- memcpy(cpi->interp_filter_selected[ordered_bwd[i]],
- cpi->interp_filter_selected[ordered_bwd[i - 1]],
- sizeof(cpi->interp_filter_selected[ordered_bwd[i - 1]]));
-
cpi->common.remapped_ref_idx[ordered_bwd[i] - LAST_FRAME] =
cpi->common.remapped_ref_idx[ordered_bwd[i - 1] - LAST_FRAME];
}
@@ -853,11 +842,6 @@
EXTREF_FRAME };
for (int i = 0; i < 2; ++i) {
- // [0] is allocated to the current coded frame, i.e. bwdref
- memcpy(cpi->interp_filter_selected[ordered_bwd[i]],
- cpi->interp_filter_selected[ordered_bwd[i + 1]],
- sizeof(cpi->interp_filter_selected[ordered_bwd[i + 1]]));
-
cpi->common.remapped_ref_idx[ordered_bwd[i] - LAST_FRAME] =
cpi->common.remapped_ref_idx[ordered_bwd[i + 1] - LAST_FRAME];
}
@@ -901,9 +885,6 @@
cm->remapped_ref_idx[ALTREF_FRAME - LAST_FRAME] =
get_ref_frame_map_idx(cm, GOLDEN_FRAME);
cm->remapped_ref_idx[GOLDEN_FRAME - LAST_FRAME] = tmp;
-
- // TODO(zoeliu): Do we need to copy cpi->interp_filter_selected[0] over to
- // cpi->interp_filter_selected[GOLDEN_FRAME]?
} else if (cpi->rc.is_src_frame_ext_arf && encode_show_existing_frame(cm)) {
const int bwdref_to_show =
(cpi->new_bwdref_update_rule == 1) ? BWDREF_FRAME : ALTREF2_FRAME;
@@ -916,9 +897,6 @@
cm->remapped_ref_idx[LAST_FRAME - LAST_FRAME] =
get_ref_frame_map_idx(cm, bwdref_to_show);
- memcpy(cpi->interp_filter_selected[LAST_FRAME],
- cpi->interp_filter_selected[bwdref_to_show],
- sizeof(cpi->interp_filter_selected[bwdref_to_show]));
if (cpi->new_bwdref_update_rule == 1) {
lshift_bwd_ref_frames(cpi);
// pass outdated forward reference frame (previous LAST3) to the
@@ -928,39 +906,19 @@
cm->remapped_ref_idx[bwdref_to_show - LAST_FRAME] = last3_remapped_idx;
}
} else { /* For non key/golden frames */
- if (cpi->refresh_alt_ref_frame && !cm->show_existing_frame) {
- // === ALTREF_FRAME ===
- memcpy(cpi->interp_filter_selected[ALTREF_FRAME],
- cpi->interp_filter_selected[0],
- sizeof(cpi->interp_filter_selected[0]));
- } else if (cpi->refresh_golden_frame && !cm->show_existing_frame) {
- // === GOLDEN_FRAME ===
- memcpy(cpi->interp_filter_selected[GOLDEN_FRAME],
- cpi->interp_filter_selected[0],
- sizeof(cpi->interp_filter_selected[0]));
-
- } else if (cpi->refresh_bwd_ref_frame && !cm->show_existing_frame) {
- if (cpi->new_bwdref_update_rule) {
- // === BWDREF_FRAME ===
- // (Nothing to do for BWDREF_FRAME show_existing_frame because the
- // reference frame update has been done previously when handling the
- // LAST_BIPRED_FRAME right before BWDREF_FRAME (in the display order))
- // We shift the backward reference frame as follows:
- // BWDREF -> ALTREF2 -> EXTREF
- // and assign the newly coded frame to BWDREF so that it always
- // keeps the nearest future frame
- const int tmp = get_ref_frame_map_idx(cm, EXTREF_FRAME);
- rshift_bwd_ref_frames(cpi);
- cm->remapped_ref_idx[BWDREF_FRAME - LAST_FRAME] = tmp;
- }
- memcpy(cpi->interp_filter_selected[BWDREF_FRAME],
- cpi->interp_filter_selected[0],
- sizeof(cpi->interp_filter_selected[0]));
- } else if (cpi->refresh_alt2_ref_frame && !cm->show_existing_frame) {
- // === ALTREF2_FRAME ===
- memcpy(cpi->interp_filter_selected[ALTREF2_FRAME],
- cpi->interp_filter_selected[0],
- sizeof(cpi->interp_filter_selected[0]));
+ if (cpi->refresh_bwd_ref_frame && !cm->show_existing_frame &&
+ cpi->new_bwdref_update_rule) {
+ // === BWDREF_FRAME ===
+ // (Nothing to do for BWDREF_FRAME show_existing_frame because the
+ // reference frame update has been done previously when handling the
+ // LAST_BIPRED_FRAME right before BWDREF_FRAME (in the display order))
+ // We shift the backward reference frame as follows:
+ // BWDREF -> ALTREF2 -> EXTREF
+ // and assign the newly coded frame to BWDREF so that it always
+ // keeps the nearest future frame
+ const int tmp = get_ref_frame_map_idx(cm, EXTREF_FRAME);
+ rshift_bwd_ref_frames(cpi);
+ cm->remapped_ref_idx[BWDREF_FRAME - LAST_FRAME] = tmp;
}
}
@@ -1002,11 +960,6 @@
shift_last_ref_frames(cpi);
cm->remapped_ref_idx[LAST_FRAME - LAST_FRAME] = last3_remapped_idx;
- // TODO(dwt): This copy should actually follow the assign_frame_buffer.
- memcpy(cpi->interp_filter_selected[LAST_FRAME],
- cpi->interp_filter_selected[0],
- sizeof(cpi->interp_filter_selected[0]));
-
// If the new structure is used, we will always have overlay frames coupled
// with bwdref frames. Therefore, we won't have to perform this update
// in advance (we do this update when the overlay frame shows up).
@@ -1026,10 +979,6 @@
cm->remapped_ref_idx[LAST_FRAME - LAST_FRAME] =
get_ref_frame_map_idx(cm, BWDREF_FRAME);
cm->remapped_ref_idx[BWDREF_FRAME - LAST_FRAME] = last3_remapped_idx;
-
- memcpy(cpi->interp_filter_selected[LAST_FRAME],
- cpi->interp_filter_selected[BWDREF_FRAME],
- sizeof(cpi->interp_filter_selected[BWDREF_FRAME]));
}
}
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index be5471d..af09dad 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -358,10 +358,8 @@
}
if (cm->current_frame.frame_type == KEY_FRAME && cm->show_frame) {
- av1_zero(cpi->interp_filter_selected);
set_sb_size(&cm->seq_params, select_sb_size(cpi));
} else if (frame_is_sframe(cm)) {
- av1_zero(cpi->interp_filter_selected);
set_sb_size(&cm->seq_params, select_sb_size(cpi));
} else {
const RefCntBuffer *const primary_ref_buf = get_primary_ref_frame_buf(cm);
@@ -372,9 +370,9 @@
} else {
*cm->fc = primary_ref_buf->frame_context;
}
- av1_zero(cpi->interp_filter_selected[0]);
}
+ av1_zero(cm->cur_frame->interp_filter_selected);
cm->prev_frame = get_primary_ref_frame_buf(cm);
cpi->vaq_refresh = 0;
}
@@ -4621,32 +4619,45 @@
}
#endif // DUMP_RECON_FRAMES
-static int setup_interp_filter_search_mask(AV1_COMP *cpi) {
- InterpFilters ifilter;
- int ref_total[REF_FRAMES] = { 0 };
- MV_REFERENCE_FRAME ref;
- int mask = 0;
- int arf_idx = ALTREF_FRAME;
- if (cpi->common.last_frame_type == KEY_FRAME || cpi->refresh_alt_ref_frame)
- return mask;
- for (ref = LAST_FRAME; ref <= ALTREF_FRAME; ++ref)
- for (ifilter = EIGHTTAP_REGULAR; ifilter <= MULTITAP_SHARP; ++ifilter)
- ref_total[ref] += cpi->interp_filter_selected[ref][ifilter];
+static int get_interp_filter_selected(const AV1_COMMON *const cm,
+ MV_REFERENCE_FRAME ref,
+ InterpFilters ifilter) {
+ const RefCntBuffer *const buf = get_ref_frame_buf(cm, ref);
+ if (buf == NULL) return 0;
+ return buf->interp_filter_selected[ifilter];
+}
- for (ifilter = EIGHTTAP_REGULAR; ifilter <= MULTITAP_SHARP; ++ifilter) {
- if ((ref_total[LAST_FRAME] &&
- cpi->interp_filter_selected[LAST_FRAME][ifilter] * 30 <=
- ref_total[LAST_FRAME]) &&
- (((cpi->interp_filter_selected[LAST2_FRAME][ifilter] * 20) +
- (cpi->interp_filter_selected[LAST3_FRAME][ifilter] * 20) +
- (cpi->interp_filter_selected[GOLDEN_FRAME][ifilter] * 20) +
- (cpi->interp_filter_selected[BWDREF_FRAME][ifilter] * 10) +
- (cpi->interp_filter_selected[ALTREF2_FRAME][ifilter] * 10) +
- (cpi->interp_filter_selected[arf_idx][ifilter] * 10)) <
- (ref_total[LAST2_FRAME] + ref_total[LAST3_FRAME] +
- ref_total[GOLDEN_FRAME] + ref_total[BWDREF_FRAME] +
- ref_total[ALTREF2_FRAME] + ref_total[ALTREF_FRAME])))
- mask |= 1 << ifilter;
+static int setup_interp_filter_search_mask(AV1_COMP *cpi) {
+ const AV1_COMMON *const cm = &cpi->common;
+ int ref_total[REF_FRAMES] = { 0 };
+
+ if (cpi->common.last_frame_type == KEY_FRAME || cpi->refresh_alt_ref_frame)
+ return 0;
+
+ for (MV_REFERENCE_FRAME ref = LAST_FRAME; ref <= ALTREF_FRAME; ++ref) {
+ for (InterpFilters ifilter = EIGHTTAP_REGULAR; ifilter <= MULTITAP_SHARP;
+ ++ifilter) {
+ ref_total[ref] += get_interp_filter_selected(cm, ref, ifilter);
+ }
+ }
+ int ref_total_total = (ref_total[LAST2_FRAME] + ref_total[LAST3_FRAME] +
+ ref_total[GOLDEN_FRAME] + ref_total[BWDREF_FRAME] +
+ ref_total[ALTREF2_FRAME] + ref_total[ALTREF_FRAME]);
+
+ int mask = 0;
+ for (InterpFilters ifilter = EIGHTTAP_REGULAR; ifilter <= MULTITAP_SHARP;
+ ++ifilter) {
+ int last_score = get_interp_filter_selected(cm, LAST_FRAME, ifilter) * 30;
+ if (ref_total[LAST_FRAME] && last_score <= ref_total[LAST_FRAME]) {
+ int filter_score =
+ get_interp_filter_selected(cm, LAST2_FRAME, ifilter) * 20 +
+ get_interp_filter_selected(cm, LAST3_FRAME, ifilter) * 20 +
+ get_interp_filter_selected(cm, GOLDEN_FRAME, ifilter) * 20 +
+ get_interp_filter_selected(cm, BWDREF_FRAME, ifilter) * 10 +
+ get_interp_filter_selected(cm, ALTREF2_FRAME, ifilter) * 10 +
+ get_interp_filter_selected(cm, ALTREF_FRAME, ifilter) * 10;
+ if (filter_score < ref_total_total) mask |= 1 << ifilter;
+ }
}
return mask;
}
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index 5042f4f..794b31f 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -769,12 +769,6 @@
RATE_CONTROL rc;
double framerate;
- // Relevant for an inter frame.
- // - Index '0' corresponds to the values for the currently coded frame.
- // - Indices LAST_FRAME ... EXTREF_FRAMES are used to store values for all the
- // possible inter reference frames.
- int interp_filter_selected[REF_FRAMES + 1][SWITCHABLE];
-
struct aom_codec_pkt_list *output_pkt_list;
MBGRAPH_FRAME_STATS mbgraph_stats[MAX_LAG_BUFFERS];