summaryrefslogtreecommitdiff
path: root/vp9
diff options
context:
space:
mode:
Diffstat (limited to 'vp9')
-rw-r--r--vp9/encoder/vp9_encoder.c58
-rw-r--r--vp9/encoder/vp9_ratectrl.c4
-rw-r--r--vp9/encoder/vp9_speed_features.c8
-rw-r--r--vp9/encoder/vp9_svc_layercontext.c18
-rw-r--r--vp9/encoder/vp9_svc_layercontext.h4
-rw-r--r--vp9/vp9_cx_iface.c7
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;