int mb_to_bottom_edge;
FRAME_CONTEXT *fc;
- int frame_parallel_decoding_mode;
/* pointers to reference frames */
RefBuffer *block_refs[2];
RESET_FRAME_CONTEXT_ALL = 2,
} RESET_FRAME_CONTEXT_MODE;
+typedef enum {
+ /**
+ * Don't update frame context
+ */
+ REFRESH_FRAME_CONTEXT_OFF,
+ /**
+ * Update frame context to values resulting from forward probability
+ * updates signaled in the frame header
+ */
+ REFRESH_FRAME_CONTEXT_FORWARD,
+ /**
+ * Update frame context to values resulting from backward probability
+ * updates based on entropy/counts in the decoded frame
+ */
+ REFRESH_FRAME_CONTEXT_BACKWARD,
+} REFRESH_FRAME_CONTEXT_MODE;
+
typedef struct {
int_mv mv[2];
MV_REFERENCE_FRAME ref_frame[2];
loop_filter_info_n lf_info;
- int refresh_frame_context; /* Two state 0 = NO, 1 = YES */
+ // Flag signaling how frame contexts should be updated at the end of
+ // a frame decode
+ REFRESH_FRAME_CONTEXT_MODE refresh_frame_context;
int ref_frame_sign_bias[MAX_REF_FRAMES]; /* Two state 0, 1 */
#endif
int error_resilient_mode;
- int frame_parallel_decoding_mode;
int log2_tile_cols, log2_tile_rows;
int byte_alignment;
memcpy(xd->plane[i].seg_dequant, cm->uv_dequant, sizeof(cm->uv_dequant));
}
xd->fc = cm->fc;
- xd->frame_parallel_decoding_mode = cm->frame_parallel_decoding_mode;
}
xd->above_seg_context = cm->above_seg_context;
tile_data->cm = cm;
tile_data->xd = pbi->mb;
tile_data->xd.corrupted = 0;
- tile_data->xd.counts = cm->frame_parallel_decoding_mode ?
- NULL : &cm->counts;
+ tile_data->xd.counts =
+ cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD ?
+ &cm->counts : NULL;
vp10_zero(tile_data->dqcoeff);
vp10_tile_init(&tile_data->xd.tile, tile_data->cm, tile_row, tile_col);
setup_token_decoder(buf->data, data_end, buf->size, &cm->error,
}
// Initialize thread frame counts.
- if (!cm->frame_parallel_decoding_mode) {
+ if (cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
int i;
for (i = 0; i < num_workers; ++i) {
tile_data->pbi = pbi;
tile_data->xd = pbi->mb;
tile_data->xd.corrupted = 0;
- tile_data->xd.counts = cm->frame_parallel_decoding_mode ?
- 0 : &tile_data->counts;
+ tile_data->xd.counts =
+ cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD ?
+ &tile_data->counts : NULL;
vp10_zero(tile_data->dqcoeff);
vp10_tile_init(tile, cm, 0, buf->col);
vp10_tile_init(&tile_data->xd.tile, cm, 0, buf->col);
}
// Accumulate thread frame counts.
- if (n >= tile_cols && !cm->frame_parallel_decoding_mode) {
+ if (n >= tile_cols &&
+ cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
for (i = 0; i < num_workers; ++i) {
TileWorkerData *const tile_data =
(TileWorkerData*)pbi->tile_workers[i].data1;
}
if (!cm->error_resilient_mode) {
- cm->refresh_frame_context = vpx_rb_read_bit(rb);
- cm->frame_parallel_decoding_mode = vpx_rb_read_bit(rb);
+ cm->refresh_frame_context =
+ vpx_rb_read_bit(rb) ? REFRESH_FRAME_CONTEXT_FORWARD
+ : REFRESH_FRAME_CONTEXT_OFF;
+ if (cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_FORWARD) {
+ cm->refresh_frame_context =
+ vpx_rb_read_bit(rb) ? REFRESH_FRAME_CONTEXT_FORWARD
+ : REFRESH_FRAME_CONTEXT_BACKWARD;
+#if !CONFIG_MISC_FIXES
+ } else {
+ vpx_rb_read_bit(rb); // parallel decoding mode flag
+#endif
+ }
} else {
- cm->refresh_frame_context = 0;
- cm->frame_parallel_decoding_mode = 1;
+ cm->refresh_frame_context = REFRESH_FRAME_CONTEXT_OFF;
}
// This flag will be overridden by the call to vp10_setup_past_independence
// If encoded in frame parallel mode, frame context is ready after decoding
// the frame header.
- if (cm->frame_parallel_decode && cm->frame_parallel_decoding_mode) {
+ if (cm->frame_parallel_decode &&
+ cm->refresh_frame_context != REFRESH_FRAME_CONTEXT_BACKWARD) {
VPxWorker *const worker = pbi->frame_worker_owner;
FrameWorkerData *const frame_worker_data = worker->data1;
- if (cm->refresh_frame_context) {
+ if (cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_FORWARD) {
context_updated = 1;
cm->frame_contexts[cm->frame_context_idx] = *cm->fc;
}
}
if (!xd->corrupted) {
- if (!cm->error_resilient_mode && !cm->frame_parallel_decoding_mode) {
+ if (cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
vp10_adapt_coef_probs(cm);
if (!frame_is_intra_only(cm)) {
}
// Non frame parallel update frame context here.
- if (cm->refresh_frame_context && !context_updated)
+ if (cm->refresh_frame_context != REFRESH_FRAME_CONTEXT_OFF &&
+ !context_updated)
cm->frame_contexts[cm->frame_context_idx] = *cm->fc;
}
}
if (!cm->error_resilient_mode) {
- vpx_wb_write_bit(wb, cm->refresh_frame_context);
- vpx_wb_write_bit(wb, cm->frame_parallel_decoding_mode);
+ vpx_wb_write_bit(wb,
+ cm->refresh_frame_context != REFRESH_FRAME_CONTEXT_OFF);
+#if CONFIG_MISC_FIXES
+ if (cm->refresh_frame_context != REFRESH_FRAME_CONTEXT_OFF)
+#endif
+ vpx_wb_write_bit(wb, cm->refresh_frame_context !=
+ REFRESH_FRAME_CONTEXT_BACKWARD);
}
vpx_wb_write_literal(wb, cm->frame_context_idx, FRAME_CONTEXTS_LOG2);
cpi->refresh_golden_frame = 0;
cpi->refresh_last_frame = 1;
- cm->refresh_frame_context = 1;
+ cm->refresh_frame_context =
+ oxcf->error_resilient_mode ? REFRESH_FRAME_CONTEXT_OFF :
+ oxcf->frame_parallel_decoding_mode ? REFRESH_FRAME_CONTEXT_FORWARD
+ : REFRESH_FRAME_CONTEXT_BACKWARD;
cm->reset_frame_context = RESET_FRAME_CONTEXT_NONE;
vp10_reset_segment_features(&cm->seg);
cpi->rc.source_alt_ref_active = 0;
cm->error_resilient_mode = oxcf->error_resilient_mode;
- cm->frame_parallel_decoding_mode = oxcf->frame_parallel_decoding_mode;
// By default, encoder assumes decoder can use prev_mi.
if (cm->error_resilient_mode) {
- cm->frame_parallel_decoding_mode = 1;
cm->reset_frame_context = RESET_FRAME_CONTEXT_NONE;
- cm->refresh_frame_context = 0;
+ cm->refresh_frame_context = REFRESH_FRAME_CONTEXT_OFF;
} else if (cm->intra_only) {
// Only reset the current context.
cm->reset_frame_context = RESET_FRAME_CONTEXT_CURRENT;
full_to_model_counts(cpi->td.counts->coef[t],
cpi->td.rd_counts.coef_counts[t]);
- if (!cm->error_resilient_mode && !cm->frame_parallel_decoding_mode)
+ if (cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD)
vp10_adapt_coef_probs(cm);
if (!frame_is_intra_only(cm)) {
- if (!cm->error_resilient_mode && !cm->frame_parallel_decoding_mode) {
+ if (cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
vp10_adapt_mode_probs(cm);
vp10_adapt_mv_probs(cm, cm->allow_high_precision_mv);
}
cpi->refresh_last_frame ||
cpi->refresh_golden_frame ||
cpi->refresh_alt_ref_frame ||
- cm->refresh_frame_context ||
+ cm->refresh_frame_context != REFRESH_FRAME_CONTEXT_OFF ||
cm->lf.mode_ref_delta_update ||
cm->seg.update_map ||
cm->seg.update_data;
// Normal defaults
cm->reset_frame_context = RESET_FRAME_CONTEXT_NONE;
- cm->refresh_frame_context = 1;
+ cm->refresh_frame_context =
+ oxcf->error_resilient_mode ? REFRESH_FRAME_CONTEXT_OFF :
+ oxcf->frame_parallel_decoding_mode ? REFRESH_FRAME_CONTEXT_FORWARD
+ : REFRESH_FRAME_CONTEXT_BACKWARD;
cpi->refresh_last_frame = 1;
cpi->refresh_golden_frame = 0;
Pass0Encode(cpi, size, dest, frame_flags);
}
- if (cm->refresh_frame_context)
+ if (cm->refresh_frame_context != REFRESH_FRAME_CONTEXT_OFF)
cm->frame_contexts[cm->frame_context_idx] = *cm->fc;
// No frame encoded, or frame was dropped, release scaled references.