/* * Copyright (c) 2020 The WebM project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree.
*/ #include"vp9/ratectrl_rtc.h"
for (int tl = 0; tl < cpi_->svc.number_temporal_layers; ++tl) {
oxcf->ts_rate_decimator[tl] = rc_cfg.ts_rate_decimator[tl];
} for (int sl = 0; sl < cpi_->svc.number_spatial_layers; ++sl) { for (int tl = 0; tl < cpi_->svc.number_temporal_layers; ++tl) { constint layer =
LAYER_IDS_TO_IDX(sl, tl, cpi_->svc.number_temporal_layers);
LAYER_CONTEXT *lc = &cpi_->svc.layer_context[layer];
RATE_CONTROL *const lrc = &lc->rc;
oxcf->layer_target_bitrate[layer] =
1000 * rc_cfg.layer_target_bitrate[layer];
lrc->worst_quality =
vp9_quantizer_to_qindex(rc_cfg.max_quantizers[layer]);
lrc->best_quality = vp9_quantizer_to_qindex(rc_cfg.min_quantizers[layer]);
lc->scaling_factor_num = rc_cfg.scaling_factor_num[sl];
lc->scaling_factor_den = rc_cfg.scaling_factor_den[sl];
}
}
vp9_set_rc_buffer_sizes(cpi_);
vp9_new_framerate(cpi_, cpi_->framerate); if (cpi_->svc.number_temporal_layers > 1 ||
cpi_->svc.number_spatial_layers > 1) { if (cm->current_video_frame == 0) {
vp9_init_layer_context(cpi_); // svc->framedrop_mode is not currently exposed, so only allow for // full superframe drop for now.
cpi_->svc.framedrop_mode = FULL_SUPERFRAME_DROP;
}
vp9_update_layer_context_change_config(cpi_,
(int)cpi_->oxcf.target_bandwidth);
cpi_->svc.max_consec_drop = rc_cfg.max_consec_drop;
}
vp9_check_reset_rc_flag(cpi_);
cpi_->common.error.setjmp = 0; returntrue;
}
// Compute the QP for the frame. If the frame is dropped this function // returns kDrop, and no QP is computed. If the frame is encoded (not dropped) // the QP is computed and kOk is returned.
FrameDropDecision VP9RateControlRTC::ComputeQP( const VP9FrameParamsQpRTC &frame_params) {
VP9_COMMON *const cm = &cpi_->common; int width, height;
cpi_->svc.spatial_layer_id = frame_params.spatial_layer_id;
cpi_->svc.temporal_layer_id = frame_params.temporal_layer_id; if (cpi_->svc.number_spatial_layers > 1) { constint layer = LAYER_IDS_TO_IDX(cpi_->svc.spatial_layer_id,
cpi_->svc.temporal_layer_id,
cpi_->svc.number_temporal_layers);
LAYER_CONTEXT *lc = &cpi_->svc.layer_context[layer];
get_layer_resolution(cpi_->oxcf.width, cpi_->oxcf.height,
lc->scaling_factor_num, lc->scaling_factor_den, &width,
&height);
cm->width = width;
cm->height = height;
}
vp9_set_mb_mi(cm, cm->width, cm->height);
cm->frame_type = static_cast<FRAME_TYPE>(frame_params.frame_type); // This is needed to ensure key frame does not get unset in rc_get_svc_params.
cpi_->frame_flags = (cm->frame_type == KEY_FRAME) ? FRAMEFLAGS_KEY : 0;
cpi_->refresh_golden_frame = (cm->frame_type == KEY_FRAME) ? 1 : 0;
cpi_->sf.use_nonrd_pick_mode = 1; if (cpi_->svc.number_spatial_layers == 1 &&
cpi_->svc.number_temporal_layers == 1) { int target = 0; if (cpi_->oxcf.rc_mode == VPX_CBR) { if (cpi_->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
vp9_cyclic_refresh_update_parameters(cpi_); if (frame_is_intra_only(cm))
target = vp9_calc_iframe_target_size_one_pass_cbr(cpi_); else
target = vp9_calc_pframe_target_size_one_pass_cbr(cpi_);
} elseif (cpi_->oxcf.rc_mode == VPX_VBR) { if (cm->frame_type == KEY_FRAME) {
cpi_->rc.this_key_frame_forced = cm->current_video_frame != 0;
cpi_->rc.frames_to_key = cpi_->oxcf.key_freq;
}
vp9_set_gf_update_one_pass_vbr(cpi_); if (cpi_->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
vp9_cyclic_refresh_update_parameters(cpi_); if (frame_is_intra_only(cm))
target = vp9_calc_iframe_target_size_one_pass_vbr(cpi_); else
target = vp9_calc_pframe_target_size_one_pass_vbr(cpi_);
}
vp9_rc_set_frame_target(cpi_, target);
vp9_update_buffer_level_preencode(cpi_);
} else {
vp9_update_temporal_layer_framerate(cpi_);
vp9_restore_layer_context(cpi_);
vp9_rc_get_svc_params(cpi_);
} if (cpi_->svc.spatial_layer_id == 0) vp9_zero(cpi_->svc.drop_spatial_layer); // SVC: check for skip encoding of enhancement layer if the // layer target bandwidth = 0. if (vp9_svc_check_skip_enhancement_layer(cpi_)) return FrameDropDecision::kDrop; // Check for dropping this frame based on buffer level. // Never drop on key frame, or if base layer is key for svc, if (!frame_is_intra_only(cm) &&
(!cpi_->use_svc ||
!cpi_->svc.layer_context[cpi_->svc.temporal_layer_id].is_key_frame)) { if (vp9_rc_drop_frame(cpi_)) { // For FULL_SUPERFRAME_DROP mode (the only mode considered here): // if the superframe drop is decided we need to save the layer context for // all spatial layers, and call update_buffer_level and postencode_drop // for all spatial layers. if (cpi_->svc.number_spatial_layers > 1 ||
cpi_->svc.number_temporal_layers > 1) {
vp9_save_layer_context(cpi_); for (int sl = 1; sl < cpi_->svc.number_spatial_layers; sl++) {
cpi_->svc.spatial_layer_id = sl;
vp9_restore_layer_context(cpi_);
vp9_update_buffer_level_svc_preencode(cpi_);
vp9_rc_postencode_update_drop_frame(cpi_);
vp9_save_layer_context(cpi_);
}
} return FrameDropDecision::kDrop;
}
} // Compute the QP for the frame. int bottom_index, top_index;
cpi_->common.base_qindex =
vp9_rc_pick_q_and_bounds(cpi_, &bottom_index, &top_index);
if (cpi_->oxcf.aq_mode == CYCLIC_REFRESH_AQ) vp9_cyclic_refresh_setup(cpi_); if (cpi_->svc.number_spatial_layers > 1 ||
cpi_->svc.number_temporal_layers > 1)
vp9_save_layer_context(cpi_);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.