/* * Copyright (c) 2021 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.
*/
VP8_COMMON *cm = &cpi_->common;
VP8_CONFIG *oxcf = &cpi_->oxcf; constunsignedint prev_number_of_layers = oxcf->number_of_layers;
vpx_clear_system_state();
cm->Width = rc_cfg.width;
cm->Height = rc_cfg.height;
oxcf->Width = rc_cfg.width;
oxcf->Height = rc_cfg.height;
oxcf->worst_allowed_q = kQTrans[rc_cfg.max_quantizer];
oxcf->best_allowed_q = kQTrans[rc_cfg.min_quantizer];
cpi_->worst_quality = oxcf->worst_allowed_q;
cpi_->best_quality = oxcf->best_allowed_q;
cpi_->output_framerate = rc_cfg.framerate;
oxcf->target_bandwidth = static_cast<unsignedint>(1000 * rc_cfg.target_bandwidth);
cpi_->ref_framerate = cpi_->output_framerate;
oxcf->fixed_q = -1;
oxcf->error_resilient_mode = 1;
oxcf->starting_buffer_level_in_ms = rc_cfg.buf_initial_sz;
oxcf->optimal_buffer_level_in_ms = rc_cfg.buf_optimal_sz;
oxcf->maximum_buffer_size_in_ms = rc_cfg.buf_sz;
oxcf->starting_buffer_level = rc_cfg.buf_initial_sz;
oxcf->optimal_buffer_level = rc_cfg.buf_optimal_sz;
oxcf->maximum_buffer_size = rc_cfg.buf_sz;
oxcf->number_of_layers = rc_cfg.ts_number_layers;
cpi_->buffered_mode = oxcf->optimal_buffer_level > 0;
oxcf->under_shoot_pct = rc_cfg.undershoot_pct;
oxcf->over_shoot_pct = rc_cfg.overshoot_pct;
oxcf->drop_frames_water_mark = rc_cfg.frame_drop_thresh; if (oxcf->drop_frames_water_mark > 0) cpi_->drop_frames_allowed = 1;
cpi_->oxcf.rc_max_intra_bitrate_pct = rc_cfg.max_intra_bitrate_pct;
cpi_->framerate = rc_cfg.framerate; for (int i = 0; i < KEY_FRAME_CONTEXT; ++i) {
cpi_->prior_key_frame_distance[i] = static_cast<int>(cpi_->output_framerate);
}
oxcf->screen_content_mode = rc_cfg.is_screen; if (oxcf->number_of_layers > 1 || prev_number_of_layers > 1) {
memcpy(oxcf->target_bitrate, rc_cfg.layer_target_bitrate, sizeof(rc_cfg.layer_target_bitrate));
memcpy(oxcf->rate_decimator, rc_cfg.ts_rate_decimator, sizeof(rc_cfg.ts_rate_decimator)); if (cm->current_video_frame == 0) { double prev_layer_framerate = 0; for (unsignedint i = 0; i < oxcf->number_of_layers; ++i) {
vp8_init_temporal_layer_context(cpi_, oxcf, i, prev_layer_framerate);
prev_layer_framerate = cpi_->output_framerate / oxcf->rate_decimator[i];
}
} elseif (oxcf->number_of_layers != prev_number_of_layers) { // The number of temporal layers has changed, so reset/initialize the // temporal layer context for the new layer configuration: this means // calling vp8_reset_temporal_layer_change() below.
// Start at the base of the pattern cycle, so set the layer id to 0 and // reset the temporal pattern counter. // TODO(marpan/jianj): don't think lines 148-151 are needed (user controls // the layer_id) so remove. if (cpi_->temporal_layer_id > 0) {
cpi_->temporal_layer_id = 0;
}
cpi_->temporal_pattern_counter = 0;
/* Clip the active best and worst quality values to limits */ if (cpi_->active_worst_quality > cpi_->worst_quality) {
cpi_->active_worst_quality = cpi_->worst_quality;
} if (cpi_->active_best_quality < cpi_->best_quality) {
cpi_->active_best_quality = cpi_->best_quality;
} if (cpi_->active_worst_quality < cpi_->active_best_quality) {
cpi_->active_worst_quality = cpi_->active_best_quality;
}
// This model is from linear regression if (cm->Width * cm->Height <= 320 * 240) {
cm->filter_level = static_cast<int>(0.352685 * qp + 2.957774);
} elseif (cm->Width * cm->Height <= 640 * 480) {
cm->filter_level = static_cast<int>(0.485069 * qp - 0.534462);
} else {
cm->filter_level = static_cast<int>(0.314875 * qp + 7.959003);
}
int min_filter_level = 0; // This logic is from get_min_filter_level() in picklpf.c if (q_ > 6 && q_ <= 16) {
min_filter_level = 1;
} else {
min_filter_level = (q_ / 8);
}
constint max_filter_level = 63; if (cm->filter_level < min_filter_level) cm->filter_level = min_filter_level; if (cm->filter_level > max_filter_level) cm->filter_level = max_filter_level;
return cm->filter_level;
}
void VP8RateControlRTC::PostEncodeUpdate(uint64_t encoded_frame_size) {
VP8_COMMON *const cm = &cpi_->common;
vpx_clear_system_state();
cpi_->total_byte_count += encoded_frame_size;
cpi_->projected_frame_size = static_cast<int>(encoded_frame_size << 3); if (cpi_->oxcf.number_of_layers > 1) { for (unsignedint i = cpi_->current_layer + 1;
i < cpi_->oxcf.number_of_layers; ++i) {
cpi_->layer_context[i].total_byte_count += encoded_frame_size;
}
}
vp8_update_rate_correction_factors(cpi_, 2);
cpi_->last_q[cm->frame_type] = cm->base_qindex;
if (cm->frame_type == KEY_FRAME) {
vp8_adjust_key_frame_context(cpi_);
}
/* Keep a record of ambient average Q. */ if (cm->frame_type != KEY_FRAME) {
cpi_->avg_frame_qindex =
(2 + 3 * cpi_->avg_frame_qindex + cm->base_qindex) >> 2;
} /* Keep a record from which we can calculate the average Q excluding * key frames.
*/ if (cm->frame_type != KEY_FRAME) {
cpi_->ni_frames++; /* Damp value for first few frames */ if (cpi_->ni_frames > 150) {
cpi_->ni_tot_qi += q_;
cpi_->ni_av_qi = (cpi_->ni_tot_qi / cpi_->ni_frames);
} else {
cpi_->ni_tot_qi += q_;
cpi_->ni_av_qi =
((cpi_->ni_tot_qi / cpi_->ni_frames) + cpi_->worst_quality + 1) / 2;
}
/* If the average Q is higher than what was used in the last * frame (after going through the recode loop to keep the frame * size within range) then use the last frame value - 1. The -1 * is designed to stop Q and hence the data rate, from * progressively falling away during difficult sections, but at * the same time reduce the number of itterations around the * recode loop.
*/ if (q_ > cpi_->ni_av_qi) cpi_->ni_av_qi = q_ - 1;
}
/* Propagate values to higher temporal layers */ if (cpi_->oxcf.number_of_layers > 1) { for (unsignedint i = cpi_->current_layer + 1;
i < cpi_->oxcf.number_of_layers; ++i) {
LAYER_CONTEXT *lc = &cpi_->layer_context[i]; int bits_off_for_this_layer = (int)round(
lc->target_bandwidth / lc->framerate - cpi_->projected_frame_size);
lc->bits_off_target += bits_off_for_this_layer;
/* Clip buffer level to maximum buffer size for the layer */ if (lc->bits_off_target > lc->maximum_buffer_size) {
lc->bits_off_target = lc->maximum_buffer_size;
}
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.