Discussion:
[Libva-intel-driver][PATCH 2/5] svct: Save the current frame size per layer
(too old to reply)
Xiang, Haihao
2016-10-24 04:49:39 UTC
Permalink
Use the the right previous frame size to estimate a QP for next frame in the
same layer

Signed-off-by: Xiang, Haihao <***@intel.com>
---
src/gen6_mfc.h | 1 +
src/gen6_mfc_common.c | 7 +++++++
2 files changed, 8 insertions(+)

diff --git a/src/gen6_mfc.h b/src/gen6_mfc.h
index e0972bb..e68c5c5 100644
--- a/src/gen6_mfc.h
+++ b/src/gen6_mfc.h
@@ -233,6 +233,7 @@ struct gen6_mfc_context
int qp_prime_y[MAX_TEMPORAL_LAYERS][3];
double bits_per_frame[MAX_TEMPORAL_LAYERS];
double qpf_rounding_accumulator[MAX_TEMPORAL_LAYERS];
+ int bits_prev_frame[MAX_TEMPORAL_LAYERS];

double saved_bps;
double saved_fps;
diff --git a/src/gen6_mfc_common.c b/src/gen6_mfc_common.c
index fbce493..a38c6d0 100644
--- a/src/gen6_mfc_common.c
+++ b/src/gen6_mfc_common.c
@@ -225,11 +225,18 @@ int intel_mfc_brc_postpack(struct encode_state *encode_state,
next_frame_layer_id = curr_frame_layer_id;
}

+ mfc_context->brc.bits_prev_frame[curr_frame_layer_id] = frame_bits;
+ frame_bits = mfc_context->brc.bits_prev_frame[next_frame_layer_id];
+
if (encoder_context->layer.num_layers < 2 || encoder_context->layer.size_frame_layer_ids == 0)
factor = 1.0;
else
factor = (double)encoder_context->brc.framerate_per_100s[next_frame_layer_id] / encoder_context->brc.framerate_per_100s[encoder_context->layer.num_layers - 1];

+ /* 0 means the next frame is the first frame of next layer */
+ if (frame_bits == 0)
+ return sts;
+
qpi = mfc_context->brc.qp_prime_y[next_frame_layer_id][SLICE_TYPE_I];
qpp = mfc_context->brc.qp_prime_y[next_frame_layer_id][SLICE_TYPE_P];
qpb = mfc_context->brc.qp_prime_y[next_frame_layer_id][SLICE_TYPE_B];
--
1.9.1
Xiang, Haihao
2016-10-24 04:49:41 UTC
Permalink
Use the right frame numbers in a GOP to estimate a QP for next frame

Signed-off-by: Xiang, Haihao <***@intel.com>
---
src/gen6_mfc.h | 2 +-
src/gen6_mfc_common.c | 37 +++++++++++++++++++++++--------------
src/gen8_mfc.c | 6 +++---
3 files changed, 27 insertions(+), 18 deletions(-)

diff --git a/src/gen6_mfc.h b/src/gen6_mfc.h
index bc3465f..025858d 100644
--- a/src/gen6_mfc.h
+++ b/src/gen6_mfc.h
@@ -228,7 +228,7 @@ struct gen6_mfc_context

struct {
int mode;
- int gop_nums[3];
+ int gop_nums[MAX_MFC_REFERENCE_SURFACES][3];
int target_frame_size[MAX_TEMPORAL_LAYERS][3]; // I,P,B
int qp_prime_y[MAX_TEMPORAL_LAYERS][3];
double bits_per_frame[MAX_TEMPORAL_LAYERS];
diff --git a/src/gen6_mfc_common.c b/src/gen6_mfc_common.c
index 62fe8cf..4f4377f 100644
--- a/src/gen6_mfc_common.c
+++ b/src/gen6_mfc_common.c
@@ -106,10 +106,6 @@ static void intel_mfc_brc_init(struct encode_state *encode_state,

mfc_context->brc.mode = encoder_context->rate_control_mode;

- mfc_context->brc.gop_nums[SLICE_TYPE_I] = inum;
- mfc_context->brc.gop_nums[SLICE_TYPE_P] = pnum;
- mfc_context->brc.gop_nums[SLICE_TYPE_B] = bnum;
-
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) ?
@@ -134,10 +130,28 @@ static void intel_mfc_brc_init(struct encode_state *encode_state,
if (i == encoder_context->layer.num_layers - 1)
factor = 1.0;
else
- factor = (double)encoder_context->brc.framerate_per_100s[i] / encoder_context->brc.framerate_per_100s[i + 1];
+ factor = (double)encoder_context->brc.framerate_per_100s[i] / encoder_context->brc.framerate_per_100s[encoder_context->layer.num_layers - 1];
+
+ if (encoder_context->layer.num_layers > 1) {
+ if (i == 0) {
+ intra_period = (int)(encoder_context->brc.gop_size * factor);
+ inum = 1;
+ pnum = (int)(encoder_context->brc.num_pframes_in_gop * factor);
+ bnum = intra_period - inum - pnum;
+ } else {
+ intra_period = (int)(encoder_context->brc.gop_size * factor) - intra_period;
+ inum = 0;
+ pnum = (int)(encoder_context->brc.num_pframes_in_gop * factor) - pnum;
+ bnum = intra_period - inum - pnum;
+ }
+ }

- mfc_context->brc.target_frame_size[i][SLICE_TYPE_I] = (int)((double)((bitrate * intra_period * factor)/framerate) /
- (double)(inum + BRC_PWEIGHT * pnum * factor + BRC_BWEIGHT * bnum * factor));
+ mfc_context->brc.gop_nums[i][SLICE_TYPE_I] = inum;
+ mfc_context->brc.gop_nums[i][SLICE_TYPE_P] = pnum;
+ mfc_context->brc.gop_nums[i][SLICE_TYPE_B] = bnum;
+
+ mfc_context->brc.target_frame_size[i][SLICE_TYPE_I] = (int)((double)((bitrate * intra_period)/framerate) /
+ (double)(inum + BRC_PWEIGHT * pnum + BRC_BWEIGHT * bnum));
mfc_context->brc.target_frame_size[i][SLICE_TYPE_P] = BRC_PWEIGHT * mfc_context->brc.target_frame_size[i][SLICE_TYPE_I];
mfc_context->brc.target_frame_size[i][SLICE_TYPE_B] = BRC_BWEIGHT * mfc_context->brc.target_frame_size[i][SLICE_TYPE_I];

@@ -206,7 +220,7 @@ int intel_mfc_brc_postpack(struct encode_state *encode_state,
* y - how far we are from target HRD buffer fullness
*/
double x, y;
- double frame_size_alpha, factor;
+ double frame_size_alpha;

if (encoder_context->layer.num_layers < 2 || encoder_context->layer.size_frame_layer_ids == 0) {
curr_frame_layer_id = 0;
@@ -231,11 +245,6 @@ int intel_mfc_brc_postpack(struct encode_state *encode_state,
mfc_context->brc.prev_slice_type[curr_frame_layer_id] = slicetype;
slicetype = mfc_context->brc.prev_slice_type[next_frame_layer_id];

- if (encoder_context->layer.num_layers < 2 || encoder_context->layer.size_frame_layer_ids == 0)
- factor = 1.0;
- else
- factor = (double)encoder_context->brc.framerate_per_100s[next_frame_layer_id] / encoder_context->brc.framerate_per_100s[encoder_context->layer.num_layers - 1];
-
/* 0 means the next frame is the first frame of next layer */
if (frame_bits == 0)
return sts;
@@ -250,7 +259,7 @@ int intel_mfc_brc_postpack(struct encode_state *encode_state,
if (mfc_context->hrd.buffer_capacity < 5)
frame_size_alpha = 0;
else
- frame_size_alpha = (double)mfc_context->brc.gop_nums[slicetype] * factor;
+ frame_size_alpha = (double)mfc_context->brc.gop_nums[next_frame_layer_id][slicetype];
if (frame_size_alpha > 30) frame_size_alpha = 30;
frame_size_next = target_frame_size + (double)(target_frame_size - frame_bits) /
(double)(frame_size_alpha + 1.);
diff --git a/src/gen8_mfc.c b/src/gen8_mfc.c
index 6576950..716b8e9 100644
--- a/src/gen8_mfc.c
+++ b/src/gen8_mfc.c
@@ -3344,8 +3344,8 @@ static void gen8_mfc_vp8_brc_init(struct encode_state *encode_state,
(double)(inum + BRC_PWEIGHT * pnum ));
mfc_context->brc.target_frame_size[0][SLICE_TYPE_P] = BRC_PWEIGHT * mfc_context->brc.target_frame_size[0][SLICE_TYPE_I];

- mfc_context->brc.gop_nums[SLICE_TYPE_I] = inum;
- mfc_context->brc.gop_nums[SLICE_TYPE_P] = pnum;
+ mfc_context->brc.gop_nums[0][SLICE_TYPE_I] = inum;
+ mfc_context->brc.gop_nums[0][SLICE_TYPE_P] = pnum;

mfc_context->brc.bits_per_frame[0] = bitrate/frame_rate;

@@ -3398,7 +3398,7 @@ static int gen8_mfc_vp8_brc_postpack(struct encode_state *encode_state,
if (mfc_context->hrd.buffer_capacity < 5)
frame_size_alpha = 0;
else
- frame_size_alpha = (double)mfc_context->brc.gop_nums[slicetype];
+ frame_size_alpha = (double)mfc_context->brc.gop_nums[0][slicetype];
if (frame_size_alpha > 30) frame_size_alpha = 30;
frame_size_next = target_frame_size + (double)(target_frame_size - frame_bits) /
(double)(frame_size_alpha + 1.);
--
1.9.1
Xiang, Haihao
2016-10-24 04:49:40 UTC
Permalink
Use the right previous slice type to estimate a QP for next frame
in the same layer

Signed-off-by: Xiang, Haihao <***@intel.com>
---
src/gen6_mfc.h | 1 +
src/gen6_mfc_common.c | 3 +++
2 files changed, 4 insertions(+)

diff --git a/src/gen6_mfc.h b/src/gen6_mfc.h
index e68c5c5..bc3465f 100644
--- a/src/gen6_mfc.h
+++ b/src/gen6_mfc.h
@@ -234,6 +234,7 @@ struct gen6_mfc_context
double bits_per_frame[MAX_TEMPORAL_LAYERS];
double qpf_rounding_accumulator[MAX_TEMPORAL_LAYERS];
int bits_prev_frame[MAX_TEMPORAL_LAYERS];
+ int prev_slice_type[MAX_TEMPORAL_LAYERS];

double saved_bps;
double saved_fps;
diff --git a/src/gen6_mfc_common.c b/src/gen6_mfc_common.c
index a38c6d0..62fe8cf 100644
--- a/src/gen6_mfc_common.c
+++ b/src/gen6_mfc_common.c
@@ -228,6 +228,9 @@ int intel_mfc_brc_postpack(struct encode_state *encode_state,
mfc_context->brc.bits_prev_frame[curr_frame_layer_id] = frame_bits;
frame_bits = mfc_context->brc.bits_prev_frame[next_frame_layer_id];

+ mfc_context->brc.prev_slice_type[curr_frame_layer_id] = slicetype;
+ slicetype = mfc_context->brc.prev_slice_type[next_frame_layer_id];
+
if (encoder_context->layer.num_layers < 2 || encoder_context->layer.size_frame_layer_ids == 0)
factor = 1.0;
else
--
1.9.1
Xiang, Haihao
2016-10-24 04:49:38 UTC
Permalink
We can do QP compensation per layer.

Signed-off-by: Xiang, Haihao <***@intel.com>
---
src/gen6_mfc.h | 2 +-
src/gen6_mfc_common.c | 10 +++++-----
src/gen8_mfc.c | 10 +++++-----
3 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/src/gen6_mfc.h b/src/gen6_mfc.h
index 02591a3..e0972bb 100644
--- a/src/gen6_mfc.h
+++ b/src/gen6_mfc.h
@@ -232,7 +232,7 @@ struct gen6_mfc_context
int target_frame_size[MAX_TEMPORAL_LAYERS][3]; // I,P,B
int qp_prime_y[MAX_TEMPORAL_LAYERS][3];
double bits_per_frame[MAX_TEMPORAL_LAYERS];
- double qpf_rounding_accumulator;
+ double qpf_rounding_accumulator[MAX_TEMPORAL_LAYERS];

double saved_bps;
double saved_fps;
diff --git a/src/gen6_mfc_common.c b/src/gen6_mfc_common.c
index 33226a5..fbce493 100644
--- a/src/gen6_mfc_common.c
+++ b/src/gen6_mfc_common.c
@@ -254,13 +254,13 @@ int intel_mfc_brc_postpack(struct encode_state *encode_state,

if (qpn == qp) {
/* setting qpn we round qpf making mistakes: now we are trying to compensate this */
- mfc_context->brc.qpf_rounding_accumulator += qpf - qpn;
- if (mfc_context->brc.qpf_rounding_accumulator > 1.0) {
+ mfc_context->brc.qpf_rounding_accumulator[next_frame_layer_id] += qpf - qpn;
+ if (mfc_context->brc.qpf_rounding_accumulator[next_frame_layer_id] > 1.0) {
qpn++;
- mfc_context->brc.qpf_rounding_accumulator = 0.;
- } else if (mfc_context->brc.qpf_rounding_accumulator < -1.0) {
+ mfc_context->brc.qpf_rounding_accumulator[next_frame_layer_id] = 0.;
+ } else if (mfc_context->brc.qpf_rounding_accumulator[next_frame_layer_id] < -1.0) {
qpn--;
- mfc_context->brc.qpf_rounding_accumulator = 0.;
+ mfc_context->brc.qpf_rounding_accumulator[next_frame_layer_id] = 0.;
}
}
/* making sure that QP is not changing too fast */
diff --git a/src/gen8_mfc.c b/src/gen8_mfc.c
index e4506b6..6576950 100644
--- a/src/gen8_mfc.c
+++ b/src/gen8_mfc.c
@@ -3412,13 +3412,13 @@ static int gen8_mfc_vp8_brc_postpack(struct encode_state *encode_state,

if (qpn == qp) {
/* setting qpn we round qpf making mistakes: now we are trying to compensate this */
- mfc_context->brc.qpf_rounding_accumulator += qpf - qpn;
- if (mfc_context->brc.qpf_rounding_accumulator > 1.0) {
+ mfc_context->brc.qpf_rounding_accumulator[0] += qpf - qpn;
+ if (mfc_context->brc.qpf_rounding_accumulator[0] > 1.0) {
qpn++;
- mfc_context->brc.qpf_rounding_accumulator = 0.;
- } else if (mfc_context->brc.qpf_rounding_accumulator < -1.0) {
+ mfc_context->brc.qpf_rounding_accumulator[0] = 0.;
+ } else if (mfc_context->brc.qpf_rounding_accumulator[0] < -1.0) {
qpn--;
- mfc_context->brc.qpf_rounding_accumulator = 0.;
+ mfc_context->brc.qpf_rounding_accumulator[0] = 0.;
}
}
--
1.9.1
Xiang, Haihao
2016-10-24 04:49:42 UTC
Permalink
Signed-off-by: Xiang, Haihao <***@intel.com>
---
src/gen6_mfc_common.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/src/gen6_mfc_common.c b/src/gen6_mfc_common.c
index 4f4377f..add73a6 100644
--- a/src/gen6_mfc_common.c
+++ b/src/gen6_mfc_common.c
@@ -95,8 +95,9 @@ static void intel_mfc_brc_init(struct encode_state *encode_state,
{
struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
double bitrate, framerate;
- double qp1_size = 0.1 * 8 * 3 * encoder_context->frame_width_in_pixel * encoder_context->frame_height_in_pixel / 2;
- double qp51_size = 0.001 * 8 * 3 * encoder_context->frame_width_in_pixel * encoder_context->frame_height_in_pixel / 2;
+ 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;
int inum = encoder_context->brc.num_iframes_in_gop,
pnum = encoder_context->brc.num_pframes_in_gop,
@@ -104,6 +105,9 @@ static void intel_mfc_brc_init(struct encode_state *encode_state,
int intra_period = encoder_context->brc.gop_size;
int i;

+ if (encoder_context->layer.num_layers > 1)
+ qp1_size = 0.15 * frame_per_bits;
+
mfc_context->brc.mode = encoder_context->rate_control_mode;

mfc_context->hrd.buffer_size = encoder_context->brc.hrd_buffer_size;
--
1.9.1
Sean V Kelley
2016-10-24 22:48:18 UTC
Permalink
This patch series updates the bitrate control per layer and makes the
bitrate per
layer is close to the setting.
  svct: Usa an array to store QP rounding accumulator
  svct: Save the current frame size per layer
  svct: Save the current slice type per layer
  svct: Save the frame numbers for each frame type in a GOP per layer
  svct: Adjust the estimated frame size for QP=1
Better tracking. Reviewed. lgtm.

Applied, thanks.

Sean
 src/gen6_mfc.h        |  6 +++--
 src/gen6_mfc_common.c | 63 +++++++++++++++++++++++++++++++++++----
------------
 src/gen8_mfc.c        | 16 ++++++-------
 3 files changed, 55 insertions(+), 30 deletions(-)
Loading...