diff options
author | Ronald S. Bultje <rsbultje@gmail.com> | 2015-09-08 14:20:48 -0400 |
---|---|---|
committer | Ronald S. Bultje <rsbultje@gmail.com> | 2015-09-11 19:33:46 -0400 |
commit | d1474f02aaf324112e63879b12c0f61553eed2a8 (patch) | |
tree | 703fa2b8698185478e1a1de7952f7be18ebb9241 | |
parent | c92c50f2fe3e511365ab8859064f6c9b5acb04d8 (diff) | |
download | libvpx-d1474f02aaf324112e63879b12c0f61553eed2a8.tar.gz |
vp10: merge frame_parallel_decoding_mode and refresh_frame_context.
See issue 1030. The value of frame_parallel_decoding_mode was ignored
in vp9 if refresh_frame_context was 0, so instead make it a 3-member
enum where the dependency is obviously stated.
Change-Id: I37f0177e5759f54e2e6cc6217023d5681de92438
-rw-r--r-- | vp10/common/blockd.h | 1 | ||||
-rw-r--r-- | vp10/common/onyxc_int.h | 23 | ||||
-rw-r--r-- | vp10/decoder/decodeframe.c | 42 | ||||
-rw-r--r-- | vp10/encoder/bitstream.c | 9 | ||||
-rw-r--r-- | vp10/encoder/encoder.c | 22 |
5 files changed, 68 insertions, 29 deletions
diff --git a/vp10/common/blockd.h b/vp10/common/blockd.h index 52c77cd4f..3e455cbef 100644 --- a/vp10/common/blockd.h +++ b/vp10/common/blockd.h @@ -176,7 +176,6 @@ typedef struct macroblockd { int mb_to_bottom_edge; FRAME_CONTEXT *fc; - int frame_parallel_decoding_mode; /* pointers to reference frames */ RefBuffer *block_refs[2]; diff --git a/vp10/common/onyxc_int.h b/vp10/common/onyxc_int.h index 303a154b4..b88aa7d0e 100644 --- a/vp10/common/onyxc_int.h +++ b/vp10/common/onyxc_int.h @@ -63,6 +63,23 @@ typedef enum { 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]; @@ -226,7 +243,9 @@ typedef struct VP10Common { 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 */ @@ -257,7 +276,6 @@ typedef struct VP10Common { #endif int error_resilient_mode; - int frame_parallel_decoding_mode; int log2_tile_cols, log2_tile_rows; int byte_alignment; @@ -372,7 +390,6 @@ static INLINE void vp10_init_macroblockd(VP10_COMMON *cm, MACROBLOCKD *xd, 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; diff --git a/vp10/decoder/decodeframe.c b/vp10/decoder/decodeframe.c index 16706eeec..f1a7aa1b3 100644 --- a/vp10/decoder/decodeframe.c +++ b/vp10/decoder/decodeframe.c @@ -1454,8 +1454,9 @@ static const uint8_t *decode_tiles(VP10Decoder *pbi, 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, @@ -1652,7 +1653,7 @@ static const uint8_t *decode_tiles_mt(VP10Decoder *pbi, } // 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) { @@ -1674,8 +1675,9 @@ static const uint8_t *decode_tiles_mt(VP10Decoder *pbi, 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); @@ -1714,7 +1716,8 @@ static const uint8_t *decode_tiles_mt(VP10Decoder *pbi, } // 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; @@ -1948,11 +1951,20 @@ static size_t read_uncompressed_header(VP10Decoder *pbi, } 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 @@ -2187,10 +2199,11 @@ void vp10_decode_frame(VP10Decoder *pbi, // 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; } @@ -2224,7 +2237,7 @@ void vp10_decode_frame(VP10Decoder *pbi, } 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)) { @@ -2240,6 +2253,7 @@ void vp10_decode_frame(VP10Decoder *pbi, } // 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; } diff --git a/vp10/encoder/bitstream.c b/vp10/encoder/bitstream.c index c41f0ef79..eb5a86714 100644 --- a/vp10/encoder/bitstream.c +++ b/vp10/encoder/bitstream.c @@ -1142,8 +1142,13 @@ static void write_uncompressed_header(VP10_COMP *cpi, } 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); diff --git a/vp10/encoder/encoder.c b/vp10/encoder/encoder.c index 85659a244..06cce93c0 100644 --- a/vp10/encoder/encoder.c +++ b/vp10/encoder/encoder.c @@ -1421,7 +1421,10 @@ void vp10_change_config(struct VP10_COMP *cpi, const VP10EncoderConfig *oxcf) { 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); @@ -3549,13 +3552,11 @@ static void encode_frame_to_data_rate(VP10_COMP *cpi, 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; @@ -3641,11 +3642,11 @@ static void encode_frame_to_data_rate(VP10_COMP *cpi, 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); } @@ -3828,7 +3829,7 @@ static int frame_is_reference(const VP10_COMP *cpi) { 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; @@ -3956,7 +3957,10 @@ int vp10_get_compressed_data(VP10_COMP *cpi, unsigned int *frame_flags, // 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; @@ -4100,7 +4104,7 @@ int vp10_get_compressed_data(VP10_COMP *cpi, unsigned int *frame_flags, 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. |