else
cpi->oxcf = *oxcf;
+ // change includes all joint functionality
+ vp8_change_config(ptr, oxcf);
- // Convert target bandwidth from Kbit/s to Bit/s
- cpi->oxcf.target_bandwidth *= 1000;
+ // Initialize active best and worst q and average q values.
+ cpi->active_worst_quality = cpi->oxcf.worst_allowed_q;
+ cpi->active_best_quality = cpi->oxcf.best_allowed_q;
+ cpi->avg_frame_qindex = cpi->oxcf.worst_allowed_q;
+
+ // Initialise the starting buffer levels
cpi->oxcf.starting_buffer_level =
rescale(cpi->oxcf.starting_buffer_level,
cpi->oxcf.target_bandwidth, 1000);
cpi->buffer_level = cpi->oxcf.starting_buffer_level;
cpi->bits_off_target = cpi->oxcf.starting_buffer_level;
- cpi->active_worst_quality = cpi->oxcf.worst_allowed_q;
- cpi->active_best_quality = cpi->oxcf.best_allowed_q;
- cpi->avg_frame_qindex = cpi->oxcf.worst_allowed_q;
-
cpi->rolling_target_bits = cpi->av_per_frame_bandwidth;
cpi->rolling_actual_bits = cpi->av_per_frame_bandwidth;
cpi->long_rolling_target_bits = cpi->av_per_frame_bandwidth;
cpi->total_actual_bits = 0;
cpi->total_target_vs_actual = 0;
- // change includes all joint functionality
- vp8_change_config(ptr, oxcf);
-
#if VP8_TEMPORAL_ALT_REF
cpi->use_weighted_temporal_filter = 0;
}
- cpi->baseline_gf_interval = cpi->oxcf.alt_freq ? cpi->oxcf.alt_freq : DEFAULT_GF_INTERVAL;
+ cpi->baseline_gf_interval =
+ cpi->oxcf.alt_freq ? cpi->oxcf.alt_freq : DEFAULT_GF_INTERVAL;
cpi->ref_frame_flags = VP8_ALT_FLAG | VP8_GOLD_FLAG | VP8_LAST_FLAG;
cm->refresh_entropy_probs = 1;
if (cpi->oxcf.token_partitions >= 0 && cpi->oxcf.token_partitions <= 3)
- cm->multi_token_partition = (TOKEN_PARTITION) cpi->oxcf.token_partitions;
+ cm->multi_token_partition =
+ (TOKEN_PARTITION) cpi->oxcf.token_partitions;
setup_features(cpi);
cpi->oxcf.starting_buffer_level = 60000;
cpi->oxcf.optimal_buffer_level = 60000;
cpi->oxcf.maximum_buffer_size = 240000;
-
}
// Convert target bandwidth from Kbit/s to Bit/s
cpi->oxcf.target_bandwidth *= 1000;
+ // Set or reset optimal and maximum buffer levels.
if (cpi->oxcf.optimal_buffer_level == 0)
cpi->oxcf.optimal_buffer_level = cpi->oxcf.target_bandwidth / 8;
else
rescale(cpi->oxcf.maximum_buffer_size,
cpi->oxcf.target_bandwidth, 1000);
+ // Set up frame rate and related parameters rate control values.
vp8_new_frame_rate(cpi, cpi->oxcf.frame_rate);
+
+ // Set absolute upper and lower quality limits
cpi->worst_quality = cpi->oxcf.worst_allowed_q;
cpi->best_quality = cpi->oxcf.best_allowed_q;
cpi->cq_target_quality = cpi->oxcf.cq_level;
// Only allow dropped frames in buffered mode
- cpi->drop_frames_allowed = cpi->oxcf.allow_df && cpi->buffered_mode;
+ cpi->drop_frames_allowed = cpi->oxcf.allow_df && cpi->buffered_mode;
- cm->filter_type = (LOOPFILTERTYPE) cpi->filter_type;
+ cm->filter_type = (LOOPFILTERTYPE) cpi->filter_type;
if (!cm->use_bilinear_mc_filter)
cm->mcomp_filter_type = SIXTAP;
cm->horiz_scale = cpi->horiz_scale;
cm->vert_scale = cpi->vert_scale ;
- cpi->intra_frame_target = (4 * (cm->Width + cm->Height) / 15) * 1000; // As per VP8
+ // As per VP8
+ cpi->intra_frame_target = (4 * (cm->Width + cm->Height) / 15) * 1000;
// VP8 sharpness level mapping 0-7 (vs 0-10 in general VPx dialogs)
if (cpi->oxcf.Sharpness > 7)
cm->Height = (vs - 1 + cpi->oxcf.Height * vr) / vs;
}
- if (((cm->Width + 15) & 0xfffffff0) != cm->yv12_fb[cm->lst_fb_idx].y_width ||
- ((cm->Height + 15) & 0xfffffff0) != cm->yv12_fb[cm->lst_fb_idx].y_height ||
+ if (((cm->Width + 15) & 0xfffffff0) !=
+ cm->yv12_fb[cm->lst_fb_idx].y_width ||
+ ((cm->Height + 15) & 0xfffffff0) !=
+ cm->yv12_fb[cm->lst_fb_idx].y_height ||
cm->yv12_fb[cm->lst_fb_idx].y_width == 0)
{
alloc_raw_frame_buffers(cpi);
}
}
- // If CBR and the buffer is as full then it is reasonable to allow higher quality on the frames
- // to prevent bits just going to waste.
+ // If CBR and the buffer is as full then it is reasonable to allow
+ // higher quality on the frames to prevent bits just going to waste.
if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
{
- // Note that the use of >= here elliminates the risk of a devide by 0 error in the else if clause
+ // Note that the use of >= here elliminates the risk of a devide
+ // by 0 error in the else if clause
if (cpi->buffer_level >= cpi->oxcf.maximum_buffer_size)
cpi->active_best_quality = cpi->best_quality;
}
}
}
+ // Make sure constrained quality mode limits are adhered to for the first
+ // few frames of one pass encodes
+ else if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY)
+ {
+ if ( (cm->frame_type == KEY_FRAME) ||
+ cm->refresh_golden_frame || cpi->common.refresh_alt_ref_frame )
+ {
+ cpi->active_best_quality = cpi->best_quality;
+ }
+ else if (cpi->active_best_quality < cpi->cq_target_quality)
+ {
+ cpi->active_best_quality = cpi->cq_target_quality;
+ }
+ }
// Clip the active best and worst quality values to limits
if (cpi->active_worst_quality > cpi->worst_quality)
{
int one_percent_bits = 1 + cpi->oxcf.optimal_buffer_level / 100;
- if ((cpi->buffer_level < cpi->oxcf.optimal_buffer_level) || (cpi->bits_off_target < cpi->oxcf.optimal_buffer_level))
+ if ((cpi->buffer_level < cpi->oxcf.optimal_buffer_level) ||
+ (cpi->bits_off_target < cpi->oxcf.optimal_buffer_level))
{
int percent_low = 0;
// If we are are below the optimal buffer fullness level and adherence
// to buffering contraints is important to the end useage then adjust
// the per frame target.
- if ((cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) && (cpi->buffer_level < cpi->oxcf.optimal_buffer_level))
+ if ((cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) &&
+ (cpi->buffer_level < cpi->oxcf.optimal_buffer_level))
{
- percent_low = (cpi->oxcf.optimal_buffer_level - cpi->buffer_level) / one_percent_bits;
+ percent_low =
+ (cpi->oxcf.optimal_buffer_level - cpi->buffer_level) /
+ one_percent_bits;
if (percent_low > 100)
percent_low = 100;
else if (cpi->bits_off_target < 0)
{
// Adjust per frame data target downwards to compensate.
- percent_low = (int)(100 * -cpi->bits_off_target / (cpi->total_byte_count * 8));
+ percent_low = (int)(100 * -cpi->bits_off_target /
+ (cpi->total_byte_count * 8));
if (percent_low > 100)
percent_low = 100;
}
// lower the target bandwidth for this frame.
- cpi->this_frame_target = (cpi->this_frame_target * (100 - (percent_low / 2))) / 100;
+ cpi->this_frame_target =
+ (cpi->this_frame_target * (100 - (percent_low / 2))) / 100;
- // Are we using allowing control of active_worst_allowed_q according to buffer level.
+ // Are we using allowing control of active_worst_allowed_q
+ // according to buffer level.
if (cpi->auto_worst_q)
{
int critical_buffer_level;
- // For streaming applications the most important factor is cpi->buffer_level as this takes
- // into account the specified short term buffering constraints. However, hitting the long
- // term clip data rate target is also important.
+ // For streaming applications the most important factor is
+ // cpi->buffer_level as this takes into account the
+ // specified short term buffering constraints. However,
+ // hitting the long term clip data rate target is also
+ // important.
if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
{
- // Take the smaller of cpi->buffer_level and cpi->bits_off_target
- critical_buffer_level = (cpi->buffer_level < cpi->bits_off_target) ? cpi->buffer_level : cpi->bits_off_target;
+ // Take the smaller of cpi->buffer_level and
+ // cpi->bits_off_target
+ critical_buffer_level =
+ (cpi->buffer_level < cpi->bits_off_target)
+ ? cpi->buffer_level : cpi->bits_off_target;
}
- // For local file playback short term buffering contraints are less of an issue
+ // For local file playback short term buffering contraints
+ // are less of an issue
else
{
- // Consider only how we are doing for the clip as a whole
+ // Consider only how we are doing for the clip as a
+ // whole
critical_buffer_level = cpi->bits_off_target;
}
- // Set the active worst quality based upon the selected buffer fullness number.
+ // Set the active worst quality based upon the selected
+ // buffer fullness number.
if (critical_buffer_level < cpi->oxcf.optimal_buffer_level)
{
- if (critical_buffer_level > (cpi->oxcf.optimal_buffer_level / 4))
+ if ( critical_buffer_level >
+ (cpi->oxcf.optimal_buffer_level >> 2) )
{
- int qadjustment_range = cpi->worst_quality - cpi->ni_av_qi;
- int above_base = (critical_buffer_level - (cpi->oxcf.optimal_buffer_level / 4));
-
- // Step active worst quality down from cpi->ni_av_qi when (critical_buffer_level == cpi->optimal_buffer_level)
- // to cpi->oxcf.worst_allowed_q when (critical_buffer_level == cpi->optimal_buffer_level/4)
- cpi->active_worst_quality = cpi->worst_quality - ((qadjustment_range * above_base) / (cpi->oxcf.optimal_buffer_level * 3 / 4));
+ INT64 qadjustment_range =
+ cpi->worst_quality - cpi->ni_av_qi;
+ INT64 above_base =
+ (critical_buffer_level -
+ (cpi->oxcf.optimal_buffer_level >> 2));
+
+ // Step active worst quality down from
+ // cpi->ni_av_qi when (critical_buffer_level ==
+ // cpi->optimal_buffer_level) to
+ // cpi->worst_quality when
+ // (critical_buffer_level ==
+ // cpi->optimal_buffer_level >> 2)
+ cpi->active_worst_quality =
+ cpi->worst_quality -
+ ((qadjustment_range * above_base) /
+ (cpi->oxcf.optimal_buffer_level*3>>2));
}
else
{
// Set the active worst quality
cpi->active_worst_quality = cpi->worst_quality;
}
+
+ // Special trap for constrained quality mode
+ // "active_worst_quality" may never drop below cq level
+ // for any frame type.
+ if ( cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY &&
+ cpi->active_worst_quality < cpi->cq_target_quality)
+ {
+ cpi->active_worst_quality = cpi->cq_target_quality;
+ }
}
// Test to see if we have to drop a frame