[Libva] [Libva-intel-driver][PATCH] svct: hrd check per layer
Xiang, Haihao
haihao.xiang at intel.com
Thu Oct 27 14:41:46 UTC 2016
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 <fei.w.wang at intel.com>
Signed-off-by: Xiang, Haihao <haihao.xiang at intel.com>
---
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;
--
1.9.1
More information about the Libva
mailing list