Rate ctrl changes to track target bitrates closer
Turns off the DISABLE_RC_LONG_TERM_MEM macro and makes other changes in the way the bits are updated, to make 2-pass rate control track target bitrates closer. Change-Id: I5f3be4b11c2908e6a9a9a1dd4fcf4e65531c44d8
This commit is contained in:
@@ -1186,7 +1186,7 @@ static size_t write_compressed_header(VP9_COMP *cpi, uint8_t *data) {
|
|||||||
|
|
||||||
void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, size_t *size) {
|
void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, size_t *size) {
|
||||||
uint8_t *data = dest;
|
uint8_t *data = dest;
|
||||||
size_t first_part_size;
|
size_t first_part_size, uncompressed_hdr_size;
|
||||||
struct vp9_write_bit_buffer wb = {data, 0};
|
struct vp9_write_bit_buffer wb = {data, 0};
|
||||||
struct vp9_write_bit_buffer saved_wb;
|
struct vp9_write_bit_buffer saved_wb;
|
||||||
|
|
||||||
@@ -1194,7 +1194,8 @@ void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, size_t *size) {
|
|||||||
saved_wb = wb;
|
saved_wb = wb;
|
||||||
vp9_wb_write_literal(&wb, 0, 16); // don't know in advance first part. size
|
vp9_wb_write_literal(&wb, 0, 16); // don't know in advance first part. size
|
||||||
|
|
||||||
data += vp9_rb_bytes_written(&wb);
|
uncompressed_hdr_size = vp9_rb_bytes_written(&wb);
|
||||||
|
data += uncompressed_hdr_size;
|
||||||
|
|
||||||
vp9_compute_update_table();
|
vp9_compute_update_table();
|
||||||
|
|
||||||
|
|||||||
@@ -2336,6 +2336,7 @@ static void encode_rd_sb_row(VP9_COMP *cpi, const TileInfo *const tile,
|
|||||||
if ((cpi->sf.partition_search_type == SEARCH_PARTITION &&
|
if ((cpi->sf.partition_search_type == SEARCH_PARTITION &&
|
||||||
cpi->sf.use_lastframe_partitioning) ||
|
cpi->sf.use_lastframe_partitioning) ||
|
||||||
cpi->sf.partition_search_type == FIXED_PARTITION ||
|
cpi->sf.partition_search_type == FIXED_PARTITION ||
|
||||||
|
cpi->sf.partition_search_type == VAR_BASED_PARTITION ||
|
||||||
cpi->sf.partition_search_type == VAR_BASED_FIXED_PARTITION) {
|
cpi->sf.partition_search_type == VAR_BASED_FIXED_PARTITION) {
|
||||||
const int idx_str = cm->mi_stride * mi_row + mi_col;
|
const int idx_str = cm->mi_stride * mi_row + mi_col;
|
||||||
MODE_INFO **mi_8x8 = cm->mi_grid_visible + idx_str;
|
MODE_INFO **mi_8x8 = cm->mi_grid_visible + idx_str;
|
||||||
|
|||||||
@@ -54,8 +54,6 @@
|
|||||||
|
|
||||||
#define MIN_KF_BOOST 300
|
#define MIN_KF_BOOST 300
|
||||||
|
|
||||||
#define DISABLE_RC_LONG_TERM_MEM 0
|
|
||||||
|
|
||||||
#if CONFIG_MULTIPLE_ARF
|
#if CONFIG_MULTIPLE_ARF
|
||||||
// Set MIN_GF_INTERVAL to 1 for the full decomposition.
|
// Set MIN_GF_INTERVAL to 1 for the full decomposition.
|
||||||
#define MIN_GF_INTERVAL 2
|
#define MIN_GF_INTERVAL 2
|
||||||
@@ -1736,10 +1734,6 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
|
|||||||
{
|
{
|
||||||
// Adjust KF group bits and error remaining.
|
// Adjust KF group bits and error remaining.
|
||||||
twopass->kf_group_error_left -= (int64_t)gf_group_err;
|
twopass->kf_group_error_left -= (int64_t)gf_group_err;
|
||||||
twopass->kf_group_bits -= twopass->gf_group_bits;
|
|
||||||
|
|
||||||
if (twopass->kf_group_bits < 0)
|
|
||||||
twopass->kf_group_bits = 0;
|
|
||||||
|
|
||||||
// If this is an arf update we want to remove the score for the overlay
|
// If this is an arf update we want to remove the score for the overlay
|
||||||
// frame at the end which will usually be very cheap to code.
|
// frame at the end which will usually be very cheap to code.
|
||||||
@@ -1756,11 +1750,6 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
|
|||||||
twopass->gf_group_error_left = (int64_t)gf_group_err;
|
twopass->gf_group_error_left = (int64_t)gf_group_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
twopass->gf_group_bits -= twopass->gf_bits;
|
|
||||||
|
|
||||||
if (twopass->gf_group_bits < 0)
|
|
||||||
twopass->gf_group_bits = 0;
|
|
||||||
|
|
||||||
// This condition could fail if there are two kfs very close together
|
// This condition could fail if there are two kfs very close together
|
||||||
// despite MIN_GF_INTERVAL and would cause a divide by 0 in the
|
// despite MIN_GF_INTERVAL and would cause a divide by 0 in the
|
||||||
// calculation of alt_extra_bits.
|
// calculation of alt_extra_bits.
|
||||||
@@ -1769,8 +1758,9 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
|
|||||||
|
|
||||||
if (boost >= 150) {
|
if (boost >= 150) {
|
||||||
const int pct_extra = MIN(20, (boost - 100) / 50);
|
const int pct_extra = MIN(20, (boost - 100) / 50);
|
||||||
const int alt_extra_bits = (int)((twopass->gf_group_bits * pct_extra) /
|
const int alt_extra_bits = (int)((
|
||||||
100);
|
MAX(twopass->gf_group_bits - twopass->gf_bits, 0) *
|
||||||
|
pct_extra) / 100);
|
||||||
twopass->gf_group_bits -= alt_extra_bits;
|
twopass->gf_group_bits -= alt_extra_bits;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1823,10 +1813,6 @@ static void assign_std_frame_bits(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
|
|||||||
|
|
||||||
// Adjust error and bits remaining.
|
// Adjust error and bits remaining.
|
||||||
cpi->twopass.gf_group_error_left -= (int64_t)modified_err;
|
cpi->twopass.gf_group_error_left -= (int64_t)modified_err;
|
||||||
cpi->twopass.gf_group_bits -= target_frame_size;
|
|
||||||
|
|
||||||
if (cpi->twopass.gf_group_bits < 0)
|
|
||||||
cpi->twopass.gf_group_bits = 0;
|
|
||||||
|
|
||||||
// Per frame bit target for this frame.
|
// Per frame bit target for this frame.
|
||||||
vp9_rc_set_frame_target(cpi, target_frame_size);
|
vp9_rc_set_frame_target(cpi, target_frame_size);
|
||||||
@@ -2343,23 +2329,20 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
|
|||||||
subtract_stats(&twopass->total_left_stats, &this_frame);
|
subtract_stats(&twopass->total_left_stats, &this_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vp9_twopass_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) {
|
void vp9_twopass_postencode_update(VP9_COMP *cpi) {
|
||||||
#ifdef DISABLE_RC_LONG_TERM_MEM
|
const uint64_t bits_used = cpi->rc.projected_frame_size;
|
||||||
cpi->twopass.bits_left -= cpi->rc.this_frame_target;
|
cpi->twopass.bits_left -= bits_used;
|
||||||
#else
|
cpi->twopass.bits_left = MAX(cpi->twopass.bits_left, 0);
|
||||||
cpi->twopass.bits_left -= 8 * bytes_used;
|
|
||||||
// Update bits left to the kf and gf groups to account for overshoot or
|
// Update bits left to the kf and gf groups to account for overshoot or
|
||||||
// undershoot on these frames.
|
// undershoot on these frames.
|
||||||
if (cm->frame_type == KEY_FRAME) {
|
if (cpi->common.frame_type == KEY_FRAME) {
|
||||||
cpi->twopass.kf_group_bits += cpi->rc.this_frame_target -
|
// For key frames kf_group_bits already had the target bits subtracted out.
|
||||||
cpi->rc.projected_frame_size;
|
// So now update to the correct value based on the actual bits used.
|
||||||
|
cpi->twopass.kf_group_bits += cpi->rc.this_frame_target - bits_used;
|
||||||
cpi->twopass.kf_group_bits = MAX(cpi->twopass.kf_group_bits, 0);
|
} else {
|
||||||
} else if (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame) {
|
cpi->twopass.kf_group_bits -= bits_used;
|
||||||
cpi->twopass.gf_group_bits += cpi->rc.this_frame_target -
|
cpi->twopass.gf_group_bits -= bits_used;
|
||||||
cpi->rc.projected_frame_size;
|
|
||||||
|
|
||||||
cpi->twopass.gf_group_bits = MAX(cpi->twopass.gf_group_bits, 0);
|
cpi->twopass.gf_group_bits = MAX(cpi->twopass.gf_group_bits, 0);
|
||||||
}
|
}
|
||||||
#endif
|
cpi->twopass.kf_group_bits = MAX(cpi->twopass.kf_group_bits, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,8 +95,7 @@ int vp9_twopass_worst_quality(struct VP9_COMP *cpi, FIRSTPASS_STATS *fpstats,
|
|||||||
int section_target_bandwitdh);
|
int section_target_bandwitdh);
|
||||||
|
|
||||||
// Post encode update of the rate control parameters for 2-pass
|
// Post encode update of the rate control parameters for 2-pass
|
||||||
void vp9_twopass_postencode_update(struct VP9_COMP *cpi,
|
void vp9_twopass_postencode_update(struct VP9_COMP *cpi);
|
||||||
uint64_t bytes_used);
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -700,7 +700,6 @@ void vp9_new_framerate(VP9_COMP *cpi, double framerate) {
|
|||||||
rc->min_frame_bandwidth = (int)(rc->av_per_frame_bandwidth *
|
rc->min_frame_bandwidth = (int)(rc->av_per_frame_bandwidth *
|
||||||
oxcf->two_pass_vbrmin_section / 100);
|
oxcf->two_pass_vbrmin_section / 100);
|
||||||
|
|
||||||
|
|
||||||
rc->min_frame_bandwidth = MAX(rc->min_frame_bandwidth, FRAME_OVERHEAD_BITS);
|
rc->min_frame_bandwidth = MAX(rc->min_frame_bandwidth, FRAME_OVERHEAD_BITS);
|
||||||
|
|
||||||
// A maximum bitrate for a frame is defined.
|
// A maximum bitrate for a frame is defined.
|
||||||
@@ -2883,7 +2882,7 @@ static void Pass2Encode(VP9_COMP *cpi, size_t *size,
|
|||||||
vp9_rc_get_second_pass_params(cpi);
|
vp9_rc_get_second_pass_params(cpi);
|
||||||
encode_frame_to_data_rate(cpi, size, dest, frame_flags);
|
encode_frame_to_data_rate(cpi, size, dest, frame_flags);
|
||||||
|
|
||||||
vp9_twopass_postencode_update(cpi, *size);
|
vp9_twopass_postencode_update(cpi);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void check_initial_width(VP9_COMP *cpi, int subsampling_x,
|
static void check_initial_width(VP9_COMP *cpi, int subsampling_x,
|
||||||
|
|||||||
@@ -1150,10 +1150,9 @@ void vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) {
|
|||||||
|
|
||||||
// Actual bits spent
|
// Actual bits spent
|
||||||
rc->total_actual_bits += rc->projected_frame_size;
|
rc->total_actual_bits += rc->projected_frame_size;
|
||||||
|
rc->total_target_bits += (cm->show_frame ? rc->av_per_frame_bandwidth : 0);
|
||||||
|
|
||||||
// Debug stats
|
rc->total_target_vs_actual = rc->total_actual_bits - rc->total_target_bits;
|
||||||
rc->total_target_vs_actual += (rc->this_frame_target -
|
|
||||||
rc->projected_frame_size);
|
|
||||||
|
|
||||||
if (cpi->oxcf.play_alternate && cpi->refresh_alt_ref_frame &&
|
if (cpi->oxcf.play_alternate && cpi->refresh_alt_ref_frame &&
|
||||||
(cm->frame_type != KEY_FRAME))
|
(cm->frame_type != KEY_FRAME))
|
||||||
|
|||||||
@@ -75,7 +75,8 @@ typedef struct {
|
|||||||
int long_rolling_actual_bits;
|
int long_rolling_actual_bits;
|
||||||
|
|
||||||
int64_t total_actual_bits;
|
int64_t total_actual_bits;
|
||||||
int total_target_vs_actual; // debug stats
|
int64_t total_target_bits;
|
||||||
|
int64_t total_target_vs_actual;
|
||||||
|
|
||||||
int worst_quality;
|
int worst_quality;
|
||||||
int best_quality;
|
int best_quality;
|
||||||
|
|||||||
@@ -730,8 +730,8 @@ static vpx_codec_err_t vp9e_encode(vpx_codec_alg_priv_t *ctx,
|
|||||||
// Convert API flags to internal codec lib flags
|
// Convert API flags to internal codec lib flags
|
||||||
lib_flags = (flags & VPX_EFLAG_FORCE_KF) ? FRAMEFLAGS_KEY : 0;
|
lib_flags = (flags & VPX_EFLAG_FORCE_KF) ? FRAMEFLAGS_KEY : 0;
|
||||||
|
|
||||||
// vp8 use 10,000,000 ticks/second as time stamp
|
/* vp9 use 10,000,000 ticks/second as time stamp */
|
||||||
dst_time_stamp = pts * 10000000 * ctx->cfg.g_timebase.num
|
dst_time_stamp = (pts * 10000000 * ctx->cfg.g_timebase.num)
|
||||||
/ ctx->cfg.g_timebase.den;
|
/ ctx->cfg.g_timebase.den;
|
||||||
dst_end_time_stamp = (pts + duration) * 10000000 * ctx->cfg.g_timebase.num /
|
dst_end_time_stamp = (pts + duration) * 10000000 * ctx->cfg.g_timebase.num /
|
||||||
ctx->cfg.g_timebase.den;
|
ctx->cfg.g_timebase.den;
|
||||||
|
|||||||
Reference in New Issue
Block a user