diff options
Diffstat (limited to 'vp9')
-rw-r--r-- | vp9/encoder/vp9_encoder.c | 58 | ||||
-rw-r--r-- | vp9/encoder/vp9_ratectrl.c | 4 | ||||
-rw-r--r-- | vp9/encoder/vp9_speed_features.c | 8 | ||||
-rw-r--r-- | vp9/encoder/vp9_svc_layercontext.c | 18 | ||||
-rw-r--r-- | vp9/encoder/vp9_svc_layercontext.h | 4 | ||||
-rw-r--r-- | vp9/vp9_cx_iface.c | 7 |
6 files changed, 68 insertions, 31 deletions
diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index 6fca23074..128574adf 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -3751,6 +3751,24 @@ static void encode_without_recode_loop(VP9_COMP *cpi, size_t *size, suppress_active_map(cpi); + // For SVC on non-zero spatial layer: if the previous spatial layer + // was dropped then disable the prediciton from this (scaled) reference. + if (cpi->use_svc && cpi->svc.spatial_layer_id > 0 && + cpi->svc.drop_spatial_layer[cpi->svc.spatial_layer_id - 1]) { + MV_REFERENCE_FRAME ref_frame; + static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG, + VP9_ALT_FLAG }; + for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) { + const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame); + if (yv12 != NULL && (cpi->ref_frame_flags & flag_list[ref_frame])) { + const struct scale_factors *const scale_fac = + &cm->frame_refs[ref_frame - 1].sf; + if (vp9_is_scaled(scale_fac)) + cpi->ref_frame_flags &= (~flag_list[ref_frame]); + } + } + } + // Variance adaptive and in frame q adjustment experiments are mutually // exclusive. if (cpi->oxcf.aq_mode == VARIANCE_AQ) { @@ -4504,6 +4522,9 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, size_t *size, vp9_rc_postencode_update_drop_frame(cpi); vp9_inc_frame_in_layer(cpi); cpi->ext_refresh_frame_flags_pending = 0; + cpi->last_frame_dropped = 1; + cpi->svc.last_layer_dropped[cpi->svc.spatial_layer_id] = 1; + cpi->svc.drop_spatial_layer[cpi->svc.spatial_layer_id] = 1; return; } @@ -4591,28 +4612,31 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, size_t *size, } // For 1 pass CBR, check if we are dropping this frame. - // For spatial layers, for now if we decide to drop current spatial - // layer then we will also drop all upper spatial layers. - // TODO(marpan): Allow for the case of dropping single layer only without - // dropping all upper layers. + // Never drop on key frame, of if base layer is key for svc. if (oxcf->pass == 0 && oxcf->rc_mode == VPX_CBR && - cm->frame_type != KEY_FRAME) { - if (vp9_rc_drop_frame(cpi) || - (is_one_pass_cbr_svc(cpi) && - cpi->svc.rc_drop_spatial_layer[cpi->svc.spatial_layer_id] == 1)) { + cm->frame_type != KEY_FRAME && + (!cpi->use_svc || + !cpi->svc.layer_context[cpi->svc.temporal_layer_id].is_key_frame)) { + if (vp9_rc_drop_frame(cpi)) { vp9_rc_postencode_update_drop_frame(cpi); cpi->ext_refresh_frame_flags_pending = 0; cpi->last_frame_dropped = 1; + cpi->svc.last_layer_dropped[cpi->svc.spatial_layer_id] = 1; if (cpi->use_svc) { - int i; - // If we are dropping this spatial layer, then we will drop all - // upper spatial layers. - for (i = cpi->svc.spatial_layer_id; i < cpi->svc.number_spatial_layers; - i++) - cpi->svc.rc_drop_spatial_layer[i] = 1; + cpi->svc.drop_spatial_layer[cpi->svc.spatial_layer_id] = 1; vp9_inc_frame_in_layer(cpi); - if (cpi->svc.rc_drop_spatial_layer[0] == 0) - cpi->svc.skip_enhancement_layer = 1; + cpi->svc.skip_enhancement_layer = 1; + if (cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1) { + int i; + int all_layers_drop = 1; + for (i = 0; i < cpi->svc.spatial_layer_id; i++) { + if (cpi->svc.drop_spatial_layer[i] == 0) { + all_layers_drop = 0; + break; + } + } + if (all_layers_drop == 1) cpi->svc.skip_enhancement_layer = 0; + } } return; } @@ -4632,7 +4656,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, size_t *size, } cpi->last_frame_dropped = 0; - cpi->svc.last_layer_encoded = cpi->svc.spatial_layer_id; + cpi->svc.last_layer_dropped[cpi->svc.spatial_layer_id] = 0; // Disable segmentation if it decrease rate/distortion ratio if (cpi->oxcf.aq_mode == LOOKAHEAD_AQ) diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index a34eaf869..46c917b8e 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -396,9 +396,7 @@ void vp9_rc_init(const VP9EncoderConfig *oxcf, int pass, RATE_CONTROL *rc) { int vp9_rc_drop_frame(VP9_COMP *cpi) { const VP9EncoderConfig *oxcf = &cpi->oxcf; RATE_CONTROL *const rc = &cpi->rc; - if (!oxcf->drop_frames_water_mark || - (is_one_pass_cbr_svc(cpi) && - cpi->svc.rc_drop_spatial_layer[cpi->svc.spatial_layer_id] == 1)) { + if (!oxcf->drop_frames_water_mark) { return 0; } else { if (rc->buffer_level < 0) { diff --git a/vp9/encoder/vp9_speed_features.c b/vp9/encoder/vp9_speed_features.c index c5eae6263..cfa6aa403 100644 --- a/vp9/encoder/vp9_speed_features.c +++ b/vp9/encoder/vp9_speed_features.c @@ -596,7 +596,8 @@ static void set_rt_speed_feature_framesize_independent( if (!cpi->last_frame_dropped && cpi->resize_state == ORIG && !cpi->external_resize && (!cpi->use_svc || - cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1)) { + (cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1 && + !cpi->svc.last_layer_dropped[cpi->svc.number_spatial_layers - 1]))) { sf->copy_partition_flag = 1; cpi->max_copied_frame = 2; // The top temporal enhancement layer (for number of temporal layers > 1) @@ -666,6 +667,11 @@ static void set_rt_speed_feature_framesize_independent( (uint8_t *)vpx_calloc((cm->mi_stride >> 3) * ((cm->mi_rows >> 3) + 1), sizeof(*cpi->count_lastgolden_frame_usage)); } + // Disable adaptive_rd_thresh for row_mt for SVC with frame dropping. + // This is causing some tests to fail. + // TODO(marpan/jianj): Look into this failure and re-enable later. + if (cpi->use_svc && cpi->oxcf.drop_frames_water_mark) + sf->adaptive_rd_thresh_row_mt = 0; } void vp9_set_speed_features_framesize_dependent(VP9_COMP *cpi) { diff --git a/vp9/encoder/vp9_svc_layercontext.c b/vp9/encoder/vp9_svc_layercontext.c index 2b68047c5..1957bb9ec 100644 --- a/vp9/encoder/vp9_svc_layercontext.c +++ b/vp9/encoder/vp9_svc_layercontext.c @@ -38,11 +38,11 @@ void vp9_init_layer_context(VP9_COMP *const cpi) { svc->current_superframe = 0; svc->non_reference_frame = 0; svc->skip_enhancement_layer = 0; - svc->last_layer_encoded = 0; for (i = 0; i < REF_FRAMES; ++i) svc->ref_frame_index[i] = -1; for (sl = 0; sl < oxcf->ss_number_layers; ++sl) { - svc->rc_drop_spatial_layer[sl] = 0; + svc->last_layer_dropped[sl] = 0; + svc->drop_spatial_layer[sl] = 0; svc->ext_frame_flags[sl] = 0; svc->ext_lst_fb_idx[sl] = 0; svc->ext_gld_fb_idx[sl] = 1; @@ -649,11 +649,12 @@ int vp9_one_pass_cbr_svc_start_layer(VP9_COMP *const cpi) { } } - // Reset the drop flags for all spatial lauyers, on the base layer. + // Reset the drop flags for all spatial layers, on the base layer. if (cpi->svc.spatial_layer_id == 0) { int i; - for (i = 0; i < cpi->svc.number_spatial_layers; i++) - cpi->svc.rc_drop_spatial_layer[i] = 0; + for (i = 0; i < cpi->svc.number_spatial_layers; i++) { + cpi->svc.drop_spatial_layer[i] = 0; + } } lc = &cpi->svc.layer_context[cpi->svc.spatial_layer_id * @@ -702,6 +703,13 @@ int vp9_one_pass_cbr_svc_start_layer(VP9_COMP *const cpi) { break; } } + // For non-zero spatial layers: if the previous spatial layer was dropped + // disable the base_mv and partition_reuse features. + if (cpi->svc.spatial_layer_id > 0 && + cpi->svc.drop_spatial_layer[cpi->svc.spatial_layer_id - 1]) { + cpi->svc.use_base_mv = 0; + cpi->svc.use_partition_reuse = 0; + } } cpi->svc.non_reference_frame = 0; diff --git a/vp9/encoder/vp9_svc_layercontext.h b/vp9/encoder/vp9_svc_layercontext.h index 0addb57d8..9bf62ee61 100644 --- a/vp9/encoder/vp9_svc_layercontext.h +++ b/vp9/encoder/vp9_svc_layercontext.h @@ -57,7 +57,6 @@ typedef struct SVC { int spatial_layer_to_encode; int first_spatial_layer_to_encode; - int rc_drop_spatial_layer[VPX_MAX_LAYERS]; // Workaround for multiple frame contexts enum { ENCODED = 0, ENCODING, NEED_TO_ENCODE } encode_empty_frame_state; @@ -107,7 +106,8 @@ typedef struct SVC { int lower_layer_qindex; - int last_layer_encoded; + int last_layer_dropped[VPX_MAX_LAYERS]; + int drop_spatial_layer[VPX_MAX_LAYERS]; } SVC; struct VP9_COMP; diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c index 387d6dc9a..a2c5dc83e 100644 --- a/vp9/vp9_cx_iface.c +++ b/vp9/vp9_cx_iface.c @@ -1205,8 +1205,8 @@ static vpx_codec_err_t encoder_encode(vpx_codec_alg_priv_t *ctx, cx_data_sz -= size; pkt.data.frame.width[cpi->svc.spatial_layer_id] = cpi->common.width; pkt.data.frame.height[cpi->svc.spatial_layer_id] = cpi->common.height; - pkt.data.frame.last_spatial_layer_encoded = - cpi->svc.last_layer_encoded; + pkt.data.frame.spatial_layer_encoded[cpi->svc.spatial_layer_id] = + 1 - cpi->svc.drop_spatial_layer[cpi->svc.spatial_layer_id]; if (ctx->output_cx_pkt_cb.output_cx_pkt) { pkt.kind = VPX_CODEC_CX_FRAME_PKT; @@ -1235,7 +1235,8 @@ static vpx_codec_err_t encoder_encode(vpx_codec_alg_priv_t *ctx, pkt.data.frame.flags = get_frame_pkt_flags(cpi, lib_flags); pkt.data.frame.width[cpi->svc.spatial_layer_id] = cpi->common.width; pkt.data.frame.height[cpi->svc.spatial_layer_id] = cpi->common.height; - pkt.data.frame.last_spatial_layer_encoded = cpi->svc.last_layer_encoded; + pkt.data.frame.spatial_layer_encoded[cpi->svc.spatial_layer_id] = + 1 - cpi->svc.drop_spatial_layer[cpi->svc.spatial_layer_id]; if (ctx->pending_cx_data) { if (size) ctx->pending_frame_sizes[ctx->pending_frame_count++] = size; |