From 972c1c67fbfb83f37a6aef7af7be32ffbdc7f7f8 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Thu, 27 Oct 2016 22:41:46 +0800 Subject: [PATCH] svct: hrd check per layer Hence we can use separate parameters to estimate QP per layer and get more accurate QP for next frame in the same layer. Tested-by: Wang, Fei W Signed-off-by: Xiang, Haihao Reviewed-by: Sean V Kelley --- src/gen6_mfc.h | 8 ++++---- src/gen6_mfc_common.c | 47 ++++++++++++++++++++++++++--------------------- src/gen8_mfc.c | 24 ++++++++++++------------ 3 files changed, 42 insertions(+), 37 deletions(-) diff --git a/src/gen6_mfc.h b/src/gen6_mfc.h index 025858d..30b5fd9 100644 --- a/src/gen6_mfc.h +++ b/src/gen6_mfc.h @@ -244,10 +244,10 @@ struct gen6_mfc_context } brc; struct { - double current_buffer_fullness; - double target_buffer_fullness; - double buffer_capacity; - unsigned int buffer_size; + double current_buffer_fullness[MAX_TEMPORAL_LAYERS]; + double target_buffer_fullness[MAX_TEMPORAL_LAYERS]; + double buffer_capacity[MAX_TEMPORAL_LAYERS]; + unsigned int buffer_size[MAX_TEMPORAL_LAYERS]; unsigned int violation_noted; } hrd; diff --git a/src/gen6_mfc_common.c b/src/gen6_mfc_common.c index add73a6..68d030e 100644 --- a/src/gen6_mfc_common.c +++ b/src/gen6_mfc_common.c @@ -98,7 +98,7 @@ static void intel_mfc_brc_init(struct encode_state *encode_state, double frame_per_bits = 8 * 3 * encoder_context->frame_width_in_pixel * encoder_context->frame_height_in_pixel / 2; double qp1_size = 0.1 * frame_per_bits; double qp51_size = 0.001 * frame_per_bits; - double bpf, factor; + double bpf, factor, hrd_factor; int inum = encoder_context->brc.num_iframes_in_gop, pnum = encoder_context->brc.num_pframes_in_gop, bnum = encoder_context->brc.num_bframes_in_gop; /* Gop structure: number of I, P, B frames in the Gop. */ @@ -110,12 +110,6 @@ static void intel_mfc_brc_init(struct encode_state *encode_state, mfc_context->brc.mode = encoder_context->rate_control_mode; - mfc_context->hrd.buffer_size = encoder_context->brc.hrd_buffer_size; - mfc_context->hrd.current_buffer_fullness = - (double)(encoder_context->brc.hrd_initial_buffer_fullness < mfc_context->hrd.buffer_size) ? - encoder_context->brc.hrd_initial_buffer_fullness : mfc_context->hrd.buffer_size / 2.; - mfc_context->hrd.target_buffer_fullness = (double)mfc_context->hrd.buffer_size/2.; - mfc_context->hrd.buffer_capacity = (double)mfc_context->hrd.buffer_size/qp1_size; mfc_context->hrd.violation_noted = 0; for (i = 0; i < encoder_context->layer.num_layers; i++) { @@ -136,6 +130,16 @@ static void intel_mfc_brc_init(struct encode_state *encode_state, else factor = (double)encoder_context->brc.framerate_per_100s[i] / encoder_context->brc.framerate_per_100s[encoder_context->layer.num_layers - 1]; + hrd_factor = (double)bitrate / encoder_context->brc.bits_per_second[encoder_context->layer.num_layers - 1]; + + mfc_context->hrd.buffer_size[i] = (unsigned int)(encoder_context->brc.hrd_buffer_size * hrd_factor); + mfc_context->hrd.current_buffer_fullness[i] = + (double)(encoder_context->brc.hrd_initial_buffer_fullness < encoder_context->brc.hrd_buffer_size) ? + encoder_context->brc.hrd_initial_buffer_fullness : encoder_context->brc.hrd_buffer_size / 2.; + mfc_context->hrd.current_buffer_fullness[i] *= hrd_factor; + mfc_context->hrd.target_buffer_fullness[i] = (double)encoder_context->brc.hrd_buffer_size * hrd_factor / 2.; + mfc_context->hrd.buffer_capacity[i] = (double)encoder_context->brc.hrd_buffer_size * hrd_factor / qp1_size; + if (encoder_context->layer.num_layers > 1) { if (i == 0) { intra_period = (int)(encoder_context->brc.gop_size * factor); @@ -183,21 +187,22 @@ int intel_mfc_update_hrd(struct encode_state *encode_state, int frame_bits) { struct gen6_mfc_context *mfc_context = encoder_context->mfc_context; - double prev_bf = mfc_context->hrd.current_buffer_fullness; + int layer_id = encoder_context->layer.curr_frame_layer_id; + double prev_bf = mfc_context->hrd.current_buffer_fullness[layer_id]; - mfc_context->hrd.current_buffer_fullness -= frame_bits; + mfc_context->hrd.current_buffer_fullness[layer_id] -= frame_bits; - if (mfc_context->hrd.buffer_size > 0 && mfc_context->hrd.current_buffer_fullness <= 0.) { - mfc_context->hrd.current_buffer_fullness = prev_bf; + if (mfc_context->hrd.buffer_size[layer_id] > 0 && mfc_context->hrd.current_buffer_fullness[layer_id] <= 0.) { + mfc_context->hrd.current_buffer_fullness[layer_id] = prev_bf; return BRC_UNDERFLOW; } - mfc_context->hrd.current_buffer_fullness += mfc_context->brc.bits_per_frame[encoder_context->layer.curr_frame_layer_id]; - if (mfc_context->hrd.buffer_size > 0 && mfc_context->hrd.current_buffer_fullness > mfc_context->hrd.buffer_size) { + mfc_context->hrd.current_buffer_fullness[layer_id] += mfc_context->brc.bits_per_frame[layer_id]; + if (mfc_context->hrd.buffer_size[layer_id] > 0 && mfc_context->hrd.current_buffer_fullness[layer_id] > mfc_context->hrd.buffer_size[layer_id]) { if (mfc_context->brc.mode == VA_RC_VBR) - mfc_context->hrd.current_buffer_fullness = mfc_context->hrd.buffer_size; + mfc_context->hrd.current_buffer_fullness[layer_id] = mfc_context->hrd.buffer_size[layer_id]; else { - mfc_context->hrd.current_buffer_fullness = prev_bf; + mfc_context->hrd.current_buffer_fullness[layer_id] = prev_bf; return BRC_OVERFLOW; } } @@ -260,7 +265,7 @@ int intel_mfc_brc_postpack(struct encode_state *encode_state, qp = mfc_context->brc.qp_prime_y[next_frame_layer_id][slicetype]; target_frame_size = mfc_context->brc.target_frame_size[next_frame_layer_id][slicetype]; - if (mfc_context->hrd.buffer_capacity < 5) + if (mfc_context->hrd.buffer_capacity[next_frame_layer_id] < 5) frame_size_alpha = 0; else frame_size_alpha = (double)mfc_context->brc.gop_nums[next_frame_layer_id][slicetype]; @@ -293,14 +298,14 @@ int intel_mfc_brc_postpack(struct encode_state *encode_state, BRC_CLIP(qpn, 1, 51); /* calculating QP delta as some function*/ - x = mfc_context->hrd.target_buffer_fullness - mfc_context->hrd.current_buffer_fullness; + x = mfc_context->hrd.target_buffer_fullness[next_frame_layer_id] - mfc_context->hrd.current_buffer_fullness[next_frame_layer_id]; if (x > 0) { - x /= mfc_context->hrd.target_buffer_fullness; - y = mfc_context->hrd.current_buffer_fullness; + x /= mfc_context->hrd.target_buffer_fullness[next_frame_layer_id]; + y = mfc_context->hrd.current_buffer_fullness[next_frame_layer_id]; } else { - x /= (mfc_context->hrd.buffer_size - mfc_context->hrd.target_buffer_fullness); - y = mfc_context->hrd.buffer_size - mfc_context->hrd.current_buffer_fullness; + x /= (mfc_context->hrd.buffer_size[next_frame_layer_id] - mfc_context->hrd.target_buffer_fullness[next_frame_layer_id]); + y = mfc_context->hrd.buffer_size[next_frame_layer_id] - mfc_context->hrd.current_buffer_fullness[next_frame_layer_id]; } if (y < 0.01) y = 0.01; if (x > 1) x = 1; diff --git a/src/gen8_mfc.c b/src/gen8_mfc.c index 716b8e9..63ffea5 100644 --- a/src/gen8_mfc.c +++ b/src/gen8_mfc.c @@ -3358,12 +3358,12 @@ static void gen8_mfc_vp8_brc_init(struct encode_state *encode_state, mfc_context->brc.target_frame_size[0][SLICE_TYPE_P], 0); - mfc_context->hrd.buffer_size = (double)param_hrd->buffer_size; - mfc_context->hrd.current_buffer_fullness = - (double)(param_hrd->initial_buffer_fullness < mfc_context->hrd.buffer_size)? - param_hrd->initial_buffer_fullness: mfc_context->hrd.buffer_size/2.; - mfc_context->hrd.target_buffer_fullness = (double)mfc_context->hrd.buffer_size/2.; - mfc_context->hrd.buffer_capacity = (double)mfc_context->hrd.buffer_size/max_frame_size; + mfc_context->hrd.buffer_size[0] = (double)param_hrd->buffer_size; + mfc_context->hrd.current_buffer_fullness[0] = + (double)(param_hrd->initial_buffer_fullness < mfc_context->hrd.buffer_size[0])? + param_hrd->initial_buffer_fullness: mfc_context->hrd.buffer_size[0]/2.; + mfc_context->hrd.target_buffer_fullness[0] = (double)mfc_context->hrd.buffer_size[0]/2.; + mfc_context->hrd.buffer_capacity[0] = (double)mfc_context->hrd.buffer_size[0]/max_frame_size; mfc_context->hrd.violation_noted = 0; } @@ -3395,7 +3395,7 @@ static int gen8_mfc_vp8_brc_postpack(struct encode_state *encode_state, qp = mfc_context->brc.qp_prime_y[0][slicetype]; target_frame_size = mfc_context->brc.target_frame_size[0][slicetype]; - if (mfc_context->hrd.buffer_capacity < 5) + if (mfc_context->hrd.buffer_capacity[0] < 5) frame_size_alpha = 0; else frame_size_alpha = (double)mfc_context->brc.gop_nums[0][slicetype]; @@ -3432,14 +3432,14 @@ static int gen8_mfc_vp8_brc_postpack(struct encode_state *encode_state, sts = intel_mfc_update_hrd(encode_state, encoder_context, frame_bits); /* calculating QP delta as some function*/ - x = mfc_context->hrd.target_buffer_fullness - mfc_context->hrd.current_buffer_fullness; + x = mfc_context->hrd.target_buffer_fullness[0] - mfc_context->hrd.current_buffer_fullness[0]; if (x > 0) { - x /= mfc_context->hrd.target_buffer_fullness; - y = mfc_context->hrd.current_buffer_fullness; + x /= mfc_context->hrd.target_buffer_fullness[0]; + y = mfc_context->hrd.current_buffer_fullness[0]; } else { - x /= (mfc_context->hrd.buffer_size - mfc_context->hrd.target_buffer_fullness); - y = mfc_context->hrd.buffer_size - mfc_context->hrd.current_buffer_fullness; + x /= (mfc_context->hrd.buffer_size[0] - mfc_context->hrd.target_buffer_fullness[0]); + y = mfc_context->hrd.buffer_size[0] - mfc_context->hrd.current_buffer_fullness[0]; } if (y < 0.01) y = 0.01; if (x > 1) x = 1; -- 2.11.0