diff options
author | Minghai Shang <minghai@google.com> | 2014-08-25 14:29:49 -0700 |
---|---|---|
committer | Gerrit Code Review <gerrit@gerrit.golo.chromium.org> | 2014-08-25 14:29:49 -0700 |
commit | 42ad07a138d0c0345c08101673f5ad473af48d99 (patch) | |
tree | 0d958004d9d1bc29b276a8d9960646dc27e8b97f /vp9 | |
parent | 48d36e9cac21ce2b4c08621b6cab2a4163eddc03 (diff) | |
parent | d4a407c051a1aa85214e7b96c1ad1e0ba41c6e9e (diff) | |
download | libvpx-42ad07a138d0c0345c08101673f5ad473af48d99.tar libvpx-42ad07a138d0c0345c08101673f5ad473af48d99.tar.gz libvpx-42ad07a138d0c0345c08101673f5ad473af48d99.tar.bz2 libvpx-42ad07a138d0c0345c08101673f5ad473af48d99.zip |
Merge "[spatial svc]Multiple frame context feature"
Diffstat (limited to 'vp9')
-rw-r--r-- | vp9/encoder/vp9_bitstream.c | 11 | ||||
-rw-r--r-- | vp9/encoder/vp9_encoder.c | 25 | ||||
-rw-r--r-- | vp9/encoder/vp9_svc_layercontext.c | 1 | ||||
-rw-r--r-- | vp9/encoder/vp9_svc_layercontext.h | 1 | ||||
-rw-r--r-- | vp9/vp9_cx_iface.c | 2 |
5 files changed, 37 insertions, 3 deletions
diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index bdb133882..8ca05c1c0 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -1083,7 +1083,16 @@ static void write_uncompressed_header(VP9_COMP *cpi, write_bitdepth_colorspace_sampling(cm, wb); write_frame_size(cm, wb); } else { - if (!cm->show_frame) + // In spatial svc if it's not error_resilient_mode then we need to code all + // visible frames as invisible. But we need to keep the show_frame flag so + // that the publisher could know whether it is supposed to be visible. + // So we will code the show_frame flag as it is. Then code the intra_only + // bit here. This will make the bitstream incompatible. In the player we + // will change to show_frame flag to 0, then add an one byte frame with + // show_existing_frame flag which tells the decoder which frame we want to + // show. + if (!cm->show_frame || + (is_spatial_svc(cpi) && cm->error_resilient_mode == 0)) vp9_wb_write_bit(wb, cm->intra_only); if (!cm->error_resilient_mode) diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index 5b710ff5b..4be604af7 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -2123,6 +2123,19 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, cm->reset_frame_context = 2; } } + if (is_spatial_svc(cpi) && cm->error_resilient_mode == 0) { + cm->frame_context_idx = cpi->svc.spatial_layer_id; + + // The probs will be updated based on the frame type of its previous + // frame if frame_parallel_decoding_mode is 0. The type may vary for + // the frame after a key frame in base layer since we may drop enhancement + // layers. So set frame_parallel_decoding_mode to 1 in this case. + if (cpi->svc.spatial_layer_id == 0 && + cpi->svc.layer_context[0].last_frame_type == KEY_FRAME) + cm->frame_parallel_decoding_mode = 1; + else + cm->frame_parallel_decoding_mode = 0; + } // Configure experimental use of segmentation for enhanced coding of // static regions if indicated. @@ -2298,8 +2311,12 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, cm->last_height = cm->height; // reset to normal state now that we are done. - if (!cm->show_existing_frame) - cm->last_show_frame = cm->show_frame; + if (!cm->show_existing_frame) { + if (is_spatial_svc(cpi) && cm->error_resilient_mode == 0) + cm->last_show_frame = 0; + else + cm->last_show_frame = cm->show_frame; + } if (cm->show_frame) { vp9_swap_mi_and_prev_mi(cm); @@ -2310,6 +2327,10 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, if (cpi->use_svc) vp9_inc_frame_in_layer(&cpi->svc); } + + if (is_spatial_svc(cpi)) + cpi->svc.layer_context[cpi->svc.spatial_layer_id].last_frame_type = + cm->frame_type; } static void SvcEncode(VP9_COMP *cpi, size_t *size, uint8_t *dest, diff --git a/vp9/encoder/vp9_svc_layercontext.c b/vp9/encoder/vp9_svc_layercontext.c index fb52d1ab7..9bd9792bd 100644 --- a/vp9/encoder/vp9_svc_layercontext.c +++ b/vp9/encoder/vp9_svc_layercontext.c @@ -36,6 +36,7 @@ void vp9_init_layer_context(VP9_COMP *const cpi) { int i; lc->current_video_frame_in_layer = 0; lc->layer_size = 0; + lc->last_frame_type = FRAME_TYPES; lrc->ni_av_qi = oxcf->worst_allowed_q; lrc->total_actual_bits = 0; lrc->total_target_vs_actual = 0; diff --git a/vp9/encoder/vp9_svc_layercontext.h b/vp9/encoder/vp9_svc_layercontext.h index 0857e39cd..d475d5fcd 100644 --- a/vp9/encoder/vp9_svc_layercontext.h +++ b/vp9/encoder/vp9_svc_layercontext.h @@ -28,6 +28,7 @@ typedef struct { vpx_fixed_buf_t rc_twopass_stats_in; unsigned int current_video_frame_in_layer; int is_key_frame; + FRAME_TYPE last_frame_type; vpx_svc_parameters_t svc_params_received; struct lookahead_entry *alt_ref_source; int alt_ref_idx; diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c index 83f8abb16..0130e9d9e 100644 --- a/vp9/vp9_cx_iface.c +++ b/vp9/vp9_cx_iface.c @@ -176,6 +176,8 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx, if (alt_ref_sum > REF_FRAMES - cfg->ss_number_layers) ERROR("Not enough ref buffers for svc alt ref frames"); } + if (cfg->ss_number_layers > 3 && cfg->g_error_resilient == 0) + ERROR("Multiple frame contexts are not supported for more than 3 layers"); #endif RANGE_CHECK(cfg, ts_number_layers, 1, VPX_TS_MAX_LAYERS); |