For any spatial, limits the amount of consecutive frame drop.
Change-Id: I692d90363f329f571f2b59e12cc680ad2e76065d
svc_drop_frame.framedrop_mode = LAYER_DROP;
for (i = 0; i < number_spatial_layers_; i++)
svc_drop_frame.framedrop_thresh[i] = 30;
+ svc_drop_frame.max_consec_drop = 30;
encoder->Control(VP9E_SET_SVC_FRAME_DROP_LAYER, &svc_drop_frame);
}
}
cm->frame_type != KEY_FRAME &&
(!cpi->use_svc ||
!cpi->svc.layer_context[cpi->svc.temporal_layer_id].is_key_frame)) {
+ SVC *svc = &cpi->svc;
int svc_prev_layer_dropped = 0;
// In the constrained or full_superframe framedrop mode for svc
// (framedrop_mode != LAYER_DROP), if the previous spatial layer was
// dropped, drop the current spatial layer.
- if (cpi->use_svc && cpi->svc.spatial_layer_id > 0 &&
- cpi->svc.drop_spatial_layer[cpi->svc.spatial_layer_id - 1])
+ if (cpi->use_svc && svc->spatial_layer_id > 0 &&
+ svc->drop_spatial_layer[svc->spatial_layer_id - 1])
svc_prev_layer_dropped = 1;
- if ((svc_prev_layer_dropped && cpi->svc.framedrop_mode != LAYER_DROP) ||
+ if ((svc_prev_layer_dropped && svc->framedrop_mode != LAYER_DROP) ||
vp9_rc_drop_frame(cpi)) {
vp9_rc_postencode_update_drop_frame(cpi);
cpi->ext_refresh_frame_flags_pending = 0;
cpi->last_frame_dropped = 1;
if (cpi->use_svc) {
- cpi->svc.last_layer_dropped[cpi->svc.spatial_layer_id] = 1;
- cpi->svc.drop_spatial_layer[cpi->svc.spatial_layer_id] = 1;
- cpi->svc.skip_enhancement_layer = 1;
- if (cpi->svc.framedrop_mode == LAYER_DROP ||
- cpi->svc.drop_spatial_layer[0] == 0) {
+ svc->last_layer_dropped[svc->spatial_layer_id] = 1;
+ svc->drop_spatial_layer[svc->spatial_layer_id] = 1;
+ svc->drop_count[svc->spatial_layer_id]++;
+ svc->skip_enhancement_layer = 1;
+ if (svc->framedrop_mode == LAYER_DROP ||
+ svc->drop_spatial_layer[0] == 0) {
// For the case of constrained drop mode where the base is dropped
// (drop_spatial_layer[0] == 1), which means full superframe dropped,
// we don't increment the svc frame counters. In particular temporal
// issue with temporal alignement with full superframe dropping.
vp9_inc_frame_in_layer(cpi);
}
- if (cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1) {
+ if (svc->spatial_layer_id == 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) {
+ for (i = 0; i < svc->spatial_layer_id; i++) {
+ if (svc->drop_spatial_layer[i] == 0) {
all_layers_drop = 0;
break;
}
}
- if (all_layers_drop == 1) cpi->svc.skip_enhancement_layer = 0;
+ if (all_layers_drop == 1) svc->skip_enhancement_layer = 0;
}
}
return;
int vp9_rc_drop_frame(VP9_COMP *cpi) {
const VP9EncoderConfig *oxcf = &cpi->oxcf;
RATE_CONTROL *const rc = &cpi->rc;
+ SVC *svc = &cpi->svc;
int drop_frames_water_mark = oxcf->drop_frames_water_mark;
- if (cpi->use_svc)
- drop_frames_water_mark =
- cpi->svc.framedrop_thresh[cpi->svc.spatial_layer_id];
+ if (cpi->use_svc) {
+ // If we have dropped max_consec_drop frames, then we don't
+ // drop this spatial layer, and reset counter to 0.
+ if (svc->drop_count[svc->spatial_layer_id] == svc->max_consec_drop) {
+ svc->drop_count[svc->spatial_layer_id] = 0;
+ return 0;
+ } else {
+ drop_frames_water_mark = svc->framedrop_thresh[svc->spatial_layer_id];
+ }
+ }
if (!drop_frames_water_mark ||
- (cpi->svc.spatial_layer_id > 0 &&
- cpi->svc.framedrop_mode == FULL_SUPERFRAME_DROP)) {
+ (svc->spatial_layer_id > 0 &&
+ svc->framedrop_mode == FULL_SUPERFRAME_DROP)) {
return 0;
} else {
- if ((rc->buffer_level < 0 &&
- cpi->svc.framedrop_mode != FULL_SUPERFRAME_DROP) ||
+ if ((rc->buffer_level < 0 && svc->framedrop_mode != FULL_SUPERFRAME_DROP) ||
(check_buffer_below_thresh(cpi, -1) &&
- cpi->svc.framedrop_mode == FULL_SUPERFRAME_DROP)) {
+ svc->framedrop_mode == FULL_SUPERFRAME_DROP)) {
// Always drop if buffer is below 0.
return 1;
} else {
svc->downsample_filter_phase[sl] = 8; // Set to 8 for averaging filter.
svc->framedrop_thresh[sl] = oxcf->drop_frames_water_mark;
svc->fb_idx_upd_tl0[sl] = -1;
+ svc->drop_count[sl] = 0;
}
+ svc->max_consec_drop = INT_MAX;
if (cpi->oxcf.error_resilient_mode == 0 && cpi->oxcf.pass == 2) {
if (vpx_realloc_frame_buffer(&cpi->svc.empty_frame.img, SMALL_FRAME_WIDTH,
int last_layer_dropped[VPX_MAX_LAYERS];
int drop_spatial_layer[VPX_MAX_LAYERS];
int framedrop_thresh[VPX_MAX_LAYERS];
+ int drop_count[VPX_MAX_LAYERS];
+ int max_consec_drop;
SVC_LAYER_DROP_MODE framedrop_mode;
INTER_LAYER_PRED disable_inter_layer_pred;
cpi->svc.framedrop_mode = data->framedrop_mode;
for (sl = 0; sl < cpi->svc.number_spatial_layers; ++sl)
cpi->svc.framedrop_thresh[sl] = data->framedrop_thresh[sl];
+ cpi->svc.max_consec_drop = data->max_consec_drop;
return VPX_CODEC_OK;
}
typedef struct vpx_svc_frame_drop {
int framedrop_thresh[VPX_SS_MAX_LAYERS]; /**< Frame drop thresholds */
SVC_LAYER_DROP_MODE
- framedrop_mode; /**< Layer-based or constrained dropping. */
+ framedrop_mode; /**< Layer-based or constrained dropping. */
+ int max_consec_drop; /**< Maximum consecutive drops, for any layer. */
} vpx_svc_frame_drop_t;
/*!\cond */