Some updates and fixes for layered CBR mode.
-Properly set the average frame size for each layer. -Allow each layer to update its average/last Q stats after encoding. -Initialize for some layer context variables. Change-Id: Iaa37d144fcf4f30ff4283a4e8db8b9ca8bf4c815
This commit is contained in:
parent
7c8a66664c
commit
812bacc919
@ -493,7 +493,10 @@ TEST_P(DatarateTestVP9, BasicRateTargeting3TemporalLayers) {
|
|||||||
cfg_.rc_buf_initial_sz = 500;
|
cfg_.rc_buf_initial_sz = 500;
|
||||||
cfg_.rc_buf_optimal_sz = 500;
|
cfg_.rc_buf_optimal_sz = 500;
|
||||||
cfg_.rc_buf_sz = 1000;
|
cfg_.rc_buf_sz = 1000;
|
||||||
cfg_.rc_dropframe_thresh = 1;
|
// TODO(marpan): For now keep frame dropper off. Need to investigate an
|
||||||
|
// issue (rate-mismatch) that occcurs at speed 3 and low bitrate (200k) when
|
||||||
|
// frame dropper is on.
|
||||||
|
cfg_.rc_dropframe_thresh = 0;
|
||||||
cfg_.rc_min_quantizer = 0;
|
cfg_.rc_min_quantizer = 0;
|
||||||
cfg_.rc_max_quantizer = 63;
|
cfg_.rc_max_quantizer = 63;
|
||||||
cfg_.rc_end_usage = VPX_CBR;
|
cfg_.rc_end_usage = VPX_CBR;
|
||||||
|
@ -1155,14 +1155,17 @@ static void init_layer_context(VP9_COMP *const cpi) {
|
|||||||
LAYER_CONTEXT *const lc = &cpi->svc.layer_context[temporal_layer];
|
LAYER_CONTEXT *const lc = &cpi->svc.layer_context[temporal_layer];
|
||||||
RATE_CONTROL *const lrc = &lc->rc;
|
RATE_CONTROL *const lrc = &lc->rc;
|
||||||
lrc->active_worst_quality = q_trans[oxcf->worst_allowed_q];
|
lrc->active_worst_quality = q_trans[oxcf->worst_allowed_q];
|
||||||
lrc->avg_frame_qindex[INTER_FRAME] = q_trans[oxcf->worst_allowed_q];
|
lrc->avg_frame_qindex[INTER_FRAME] = lrc->active_worst_quality;
|
||||||
lrc->last_q[INTER_FRAME] = q_trans[oxcf->worst_allowed_q];
|
lrc->last_q[INTER_FRAME] = lrc->active_worst_quality;
|
||||||
lrc->ni_av_qi = lrc->active_worst_quality;
|
lrc->ni_av_qi = lrc->active_worst_quality;
|
||||||
lrc->total_actual_bits = 0;
|
lrc->total_actual_bits = 0;
|
||||||
lrc->total_target_vs_actual = 0;
|
lrc->total_target_vs_actual = 0;
|
||||||
lrc->ni_tot_qi = 0;
|
lrc->ni_tot_qi = 0;
|
||||||
lrc->tot_q = 0.0;
|
lrc->tot_q = 0.0;
|
||||||
|
lrc->avg_q = 0.0;
|
||||||
lrc->ni_frames = 0;
|
lrc->ni_frames = 0;
|
||||||
|
lrc->decimation_count = 0;
|
||||||
|
lrc->decimation_factor = 0;
|
||||||
lrc->rate_correction_factor = 1.0;
|
lrc->rate_correction_factor = 1.0;
|
||||||
lrc->key_frame_rate_correction_factor = 1.0;
|
lrc->key_frame_rate_correction_factor = 1.0;
|
||||||
lc->target_bandwidth = oxcf->ts_target_bitrate[temporal_layer] *
|
lc->target_bandwidth = oxcf->ts_target_bitrate[temporal_layer] *
|
||||||
@ -1207,13 +1210,24 @@ static void update_layer_context_change_config(VP9_COMP *const cpi,
|
|||||||
// for the current layer.
|
// for the current layer.
|
||||||
static void update_layer_framerate(VP9_COMP *const cpi) {
|
static void update_layer_framerate(VP9_COMP *const cpi) {
|
||||||
int temporal_layer = cpi->svc.temporal_layer_id;
|
int temporal_layer = cpi->svc.temporal_layer_id;
|
||||||
|
const VP9_CONFIG *const oxcf = &cpi->oxcf;
|
||||||
LAYER_CONTEXT *const lc = &cpi->svc.layer_context[temporal_layer];
|
LAYER_CONTEXT *const lc = &cpi->svc.layer_context[temporal_layer];
|
||||||
RATE_CONTROL *const lrc = &lc->rc;
|
RATE_CONTROL *const lrc = &lc->rc;
|
||||||
lc->framerate = cpi->oxcf.framerate /
|
lc->framerate = oxcf->framerate / oxcf->ts_rate_decimator[temporal_layer];
|
||||||
cpi->oxcf.ts_rate_decimator[temporal_layer];
|
lrc->av_per_frame_bandwidth = (int)(lc->target_bandwidth / lc->framerate);
|
||||||
lrc->av_per_frame_bandwidth = (int)(lc->target_bandwidth /
|
|
||||||
lc->framerate);
|
|
||||||
lrc->max_frame_bandwidth = cpi->rc.max_frame_bandwidth;
|
lrc->max_frame_bandwidth = cpi->rc.max_frame_bandwidth;
|
||||||
|
// Update the average layer frame size (non-cumulative per-frame-bw).
|
||||||
|
if (temporal_layer == 0) {
|
||||||
|
lc->avg_frame_size = lrc->av_per_frame_bandwidth;
|
||||||
|
} else {
|
||||||
|
double prev_layer_framerate = oxcf->framerate /
|
||||||
|
oxcf->ts_rate_decimator[temporal_layer - 1];
|
||||||
|
int prev_layer_target_bandwidth =
|
||||||
|
oxcf->ts_target_bitrate[temporal_layer - 1] * 1000;
|
||||||
|
lc->avg_frame_size =
|
||||||
|
(int)(lc->target_bandwidth - prev_layer_target_bandwidth) /
|
||||||
|
(lc->framerate - prev_layer_framerate);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prior to encoding the frame, set the layer context, for the current layer
|
// Prior to encoding the frame, set the layer context, for the current layer
|
||||||
|
@ -401,6 +401,7 @@ typedef struct {
|
|||||||
int64_t optimal_buffer_level;
|
int64_t optimal_buffer_level;
|
||||||
int64_t maximum_buffer_size;
|
int64_t maximum_buffer_size;
|
||||||
double framerate;
|
double framerate;
|
||||||
|
int avg_frame_size;
|
||||||
} LAYER_CONTEXT;
|
} LAYER_CONTEXT;
|
||||||
|
|
||||||
typedef struct VP9_COMP {
|
typedef struct VP9_COMP {
|
||||||
|
@ -973,7 +973,8 @@ void vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) {
|
|||||||
rc->avg_frame_qindex[KEY_FRAME] = ROUND_POWER_OF_TWO(
|
rc->avg_frame_qindex[KEY_FRAME] = ROUND_POWER_OF_TWO(
|
||||||
3 * rc->avg_frame_qindex[KEY_FRAME] + cm->base_qindex, 2);
|
3 * rc->avg_frame_qindex[KEY_FRAME] + cm->base_qindex, 2);
|
||||||
} else if (!rc->is_src_frame_alt_ref &&
|
} else if (!rc->is_src_frame_alt_ref &&
|
||||||
(cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) {
|
(cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame) &&
|
||||||
|
!(cpi->use_svc && cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)) {
|
||||||
rc->last_q[2] = cm->base_qindex;
|
rc->last_q[2] = cm->base_qindex;
|
||||||
rc->avg_frame_qindex[2] = ROUND_POWER_OF_TWO(
|
rc->avg_frame_qindex[2] = ROUND_POWER_OF_TWO(
|
||||||
3 * rc->avg_frame_qindex[2] + cm->base_qindex, 2);
|
3 * rc->avg_frame_qindex[2] + cm->base_qindex, 2);
|
||||||
@ -1175,11 +1176,20 @@ static int calc_active_worst_quality_one_pass_cbr(const VP9_COMP *cpi) {
|
|||||||
static int calc_pframe_target_size_one_pass_cbr(const VP9_COMP *cpi) {
|
static int calc_pframe_target_size_one_pass_cbr(const VP9_COMP *cpi) {
|
||||||
const VP9_CONFIG *oxcf = &cpi->oxcf;
|
const VP9_CONFIG *oxcf = &cpi->oxcf;
|
||||||
const RATE_CONTROL *rc = &cpi->rc;
|
const RATE_CONTROL *rc = &cpi->rc;
|
||||||
int target = rc->av_per_frame_bandwidth;
|
|
||||||
const int min_frame_target = MAX(rc->av_per_frame_bandwidth >> 4,
|
|
||||||
FRAME_OVERHEAD_BITS);
|
|
||||||
const int64_t diff = oxcf->optimal_buffer_level - rc->buffer_level;
|
const int64_t diff = oxcf->optimal_buffer_level - rc->buffer_level;
|
||||||
const int one_pct_bits = 1 + oxcf->optimal_buffer_level / 100;
|
const int one_pct_bits = 1 + oxcf->optimal_buffer_level / 100;
|
||||||
|
int min_frame_target = MAX(rc->av_per_frame_bandwidth >> 4,
|
||||||
|
FRAME_OVERHEAD_BITS);
|
||||||
|
int target = rc->av_per_frame_bandwidth;
|
||||||
|
if (cpi->use_svc && cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) {
|
||||||
|
// Note that for layers, av_per_frame_bandwidth is the cumulative
|
||||||
|
// per-frame-bandwidth. For the target size of this frame, use the
|
||||||
|
// layer average frame size (i.e., non-cumulative per-frame-bw).
|
||||||
|
int current_temporal_layer = cpi->svc.temporal_layer_id;
|
||||||
|
const LAYER_CONTEXT *lc = &cpi->svc.layer_context[current_temporal_layer];
|
||||||
|
target = lc->avg_frame_size;
|
||||||
|
min_frame_target = MAX(lc->avg_frame_size >> 4, FRAME_OVERHEAD_BITS);
|
||||||
|
}
|
||||||
if (diff > 0) {
|
if (diff > 0) {
|
||||||
// Lower the target bandwidth for this frame.
|
// Lower the target bandwidth for this frame.
|
||||||
const int pct_low = MIN(diff / one_pct_bits, oxcf->under_shoot_pct);
|
const int pct_low = MIN(diff / one_pct_bits, oxcf->under_shoot_pct);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user