Commit 11eac7bf authored by David Barker's avatar David Barker

no-frame-context-signaling + q-adapt-probs: Fix interaction

Slightly change the way we save and reload frame contexts during
frame setup. For "normal" frames everything is the same, but for
error-resilient and/or intra-only frames, we now:

* Reset the frame context using setup_past_independence()
  (+ extra code if q-adapt-probs is enabled), as usual
* Store this frame context into a special slot in cm->frame_contexts
* Use that slot to fill in cm->pre_fc

The main difference from before is that (for error-resilient/intra-only
frames which are not key frames) we used to throw away the frame
context after setting it up, and would re-use whatever was set up
at the last keyframe.
This was fine when q_adapt_probs is disabled, but it caused an
inconsistency when combined with q_adapt_probs. See the attached
bug report for more details on that.

BUG=aomedia:1104

Change-Id: I9532b6b0e8ae29efbb4f059a0c67a73d7c7828ce
parent b9e16f2f
......@@ -3209,6 +3209,10 @@ void av1_setup_frame_contexts(AV1_COMMON *cm) {
if (cm->frame_type == KEY_FRAME) {
// Reset all frame contexts, as all reference frames will be lost.
for (i = 0; i < FRAME_CONTEXTS; ++i) cm->frame_contexts[i] = *cm->fc;
} else if (frame_is_intra_only(cm) || cm->error_resilient_mode) {
// Store the frame context into a special slot (not associated with any
// reference buffer), so that we can set up cm->pre_fc correctly later
cm->frame_contexts[FRAME_CONTEXT_DEFAULTS] = *cm->fc;
}
#else
if (cm->frame_type == KEY_FRAME || cm->error_resilient_mode ||
......@@ -3216,15 +3220,8 @@ void av1_setup_frame_contexts(AV1_COMMON *cm) {
// Reset all frame contexts.
for (i = 0; i < FRAME_CONTEXTS; ++i) cm->frame_contexts[i] = *cm->fc;
} else if (cm->reset_frame_context == RESET_FRAME_CONTEXT_CURRENT) {
#if CONFIG_NO_FRAME_CONTEXT_SIGNALING
// Reset the frame context of the first specified ref frame.
if (cm->frame_refs[0].idx >= 0) {
cm->frame_contexts[cm->frame_refs[0].idx] = *cm->fc;
}
#else
// Reset only the frame context specified in the frame header.
cm->frame_contexts[cm->frame_context_idx] = *cm->fc;
#endif // CONFIG_NO_FRAME_CONTEXT_SIGNALING
}
#endif // CONFIG_NO_FRAME_CONTEXT_SIGNALING
}
......
......@@ -356,16 +356,24 @@ static void setup_frame(AV1_COMP *cpi) {
#if CONFIG_REFERENCE_BUFFER
set_use_reference_buffer(cm, 0);
#endif // CONFIG_REFERENCE_BUFFER
#if CONFIG_NO_FRAME_CONTEXT_SIGNALING
cm->pre_fc = &cm->frame_contexts[FRAME_CONTEXT_DEFAULTS];
#else
cm->pre_fc = &cm->frame_contexts[cm->frame_context_idx];
#endif // CONFIG_NO_FRAME_CONTEXT_SIGNALING
} else {
#if CONFIG_NO_FRAME_CONTEXT_SIGNALING
if (frame_is_intra_only(cm) || cm->error_resilient_mode ||
cm->frame_refs[0].idx < 0) {
if (frame_is_intra_only(cm) || cm->error_resilient_mode) {
*cm->fc = cm->frame_contexts[FRAME_CONTEXT_DEFAULTS];
cm->pre_fc = &cm->frame_contexts[FRAME_CONTEXT_DEFAULTS];
} else {
assert(cm->frame_refs[0].idx >= 0);
*cm->fc = cm->frame_contexts[cm->frame_refs[0].idx];
cm->pre_fc = &cm->frame_contexts[cm->frame_refs[0].idx];
}
#else
*cm->fc = cm->frame_contexts[cm->frame_context_idx];
cm->pre_fc = &cm->frame_contexts[cm->frame_context_idx];
#endif // CONFIG_NO_FRAME_CONTEXT_SIGNALING
av1_zero(cpi->interp_filter_selected[0]);
}
......@@ -375,18 +383,6 @@ static void setup_frame(AV1_COMP *cpi) {
cpi->rc.is_bipred_frame = 1;
}
#endif // !CONFIG_EXT_COMP_REFS
#if CONFIG_NO_FRAME_CONTEXT_SIGNALING
if (frame_is_intra_only(cm) || cm->error_resilient_mode ||
cm->frame_refs[0].idx < 0) {
// use default frame context values
cm->pre_fc = &cm->frame_contexts[FRAME_CONTEXT_DEFAULTS];
} else {
*cm->fc = cm->frame_contexts[cm->frame_refs[0].idx];
cm->pre_fc = &cm->frame_contexts[cm->frame_refs[0].idx];
}
#else
cm->pre_fc = &cm->frame_contexts[cm->frame_context_idx];
#endif // CONFIG_NO_FRAME_CONTEXT_SIGNALING
cpi->vaq_refresh = 0;
}
......
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