summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Thompson <sw@jkqxz.net>2016-12-23 01:10:04 +0000
committerXiang, Haihao <haihao.xiang@intel.com>2016-12-23 23:25:44 +0800
commit27c4b94fd13055afd30a62af62384d738c950103 (patch)
tree892f067614c5193a1c0cb3e3dc9de7b140c0d811
parent66cc985a48ceb69711d606c50c9f6f6f8eb5ab6f (diff)
HEVC encoder: use generic rate control parameters
Signed-off-by: Mark Thompson <sw@jkqxz.net> Reviewed-by: Xiang, Haihao<haihao.xiang@intel.com>
-rw-r--r--src/gen9_mfc.h6
-rw-r--r--src/gen9_mfc_hevc.c83
-rw-r--r--src/i965_encoder.c74
3 files changed, 84 insertions, 79 deletions
diff --git a/src/gen9_mfc.h b/src/gen9_mfc.h
index f7dc572..8e7d5ad 100644
--- a/src/gen9_mfc.h
+++ b/src/gen9_mfc.h
@@ -153,12 +153,6 @@ struct gen9_hcpe_context {
int target_frame_size[3]; // I,P,B
double bits_per_frame;
double qpf_rounding_accumulator;
-
- double saved_bps;
- double saved_fps;
- int saved_intra_period;
- int saved_ip_period;
- int saved_idr_period;
} brc;
struct {
diff --git a/src/gen9_mfc_hevc.c b/src/gen9_mfc_hevc.c
index be5666c..8a84c1c 100644
--- a/src/gen9_mfc_hevc.c
+++ b/src/gen9_mfc_hevc.c
@@ -524,7 +524,7 @@ gen9_hcpe_hevc_pic_state(VADriverContextP ctx, struct encode_state *encode_state
int ctb_size = 1 << log2_ctb_size;
double rawctubits = 8 * 3 * ctb_size * ctb_size / 2.0;
int maxctubits = (int)(5 * rawctubits / 3) ;
- double bitrate = seq_param->bits_per_second * 1.0;
+ double bitrate = (double)encoder_context->brc.bits_per_second[0];
double framebitrate = bitrate / 32 / 8; //32 byte unit
int minframebitrate = 0;//(int) (framebitrate * 3 / 10);
int maxframebitrate = (int)(framebitrate * 10 / 10);
@@ -2163,15 +2163,16 @@ VAStatus intel_hcpe_hevc_prepare(VADriverContextP ctx,
static void
intel_hcpe_bit_rate_control_context_init(struct encode_state *encode_state,
- struct gen9_hcpe_context *mfc_context)
+ struct intel_encoder_context *encoder_context)
{
+ struct gen9_hcpe_context *mfc_context = encoder_context->mfc_context;
VAEncSequenceParameterBufferHEVC *pSequenceParameter = (VAEncSequenceParameterBufferHEVC *)encode_state->seq_param_ext->buffer;
int ctb_size = 16;
int width_in_mbs = (pSequenceParameter->pic_width_in_luma_samples + ctb_size - 1) / ctb_size;
int height_in_mbs = (pSequenceParameter->pic_height_in_luma_samples + ctb_size - 1) / ctb_size;
- float fps = pSequenceParameter->vui_time_scale / pSequenceParameter->vui_num_units_in_tick ;
- double bitrate = pSequenceParameter->bits_per_second * 1.0;
+ double fps = (double)encoder_context->brc.framerate[0].num / (double)encoder_context->brc.framerate[0].den;
+ double bitrate = encoder_context->brc.bits_per_second[0];
int inter_mb_size = bitrate * 1.0 / (fps + 4.0) / width_in_mbs / height_in_mbs;
int intra_mb_size = inter_mb_size * 5.0;
int i;
@@ -2214,11 +2215,9 @@ static void intel_hcpe_brc_init(struct encode_state *encode_state,
{
struct gen9_hcpe_context *mfc_context = encoder_context->mfc_context;
VAEncSequenceParameterBufferHEVC *pSequenceParameter = (VAEncSequenceParameterBufferHEVC *)encode_state->seq_param_ext->buffer;
- VAEncMiscParameterHRD* pParameterHRD = NULL;
- VAEncMiscParameterBuffer* pMiscParamHRD = NULL;
- double bitrate = pSequenceParameter->bits_per_second * 1.0;
- double framerate = (double)pSequenceParameter->vui_time_scale / (double)pSequenceParameter->vui_num_units_in_tick;
+ double bitrate = (double)encoder_context->brc.bits_per_second[0];
+ double framerate = (double)encoder_context->brc.framerate[0].num / (double)encoder_context->brc.framerate[0].den;
int inum = 1, pnum = 0, bnum = 0; /* Gop structure: number of I, P, B frames in the Gop. */
int intra_period = pSequenceParameter->intra_period;
int ip_period = pSequenceParameter->ip_period;
@@ -2238,12 +2237,6 @@ static void intel_hcpe_brc_init(struct encode_state *encode_state,
qp1_size = qp1_size * bpp;
qp51_size = qp51_size * bpp;
- if (!encode_state->misc_param[VAEncMiscParameterTypeHRD][0] || !encode_state->misc_param[VAEncMiscParameterTypeHRD][0]->buffer)
- return;
-
- pMiscParamHRD = (VAEncMiscParameterBuffer*)encode_state->misc_param[VAEncMiscParameterTypeHRD][0]->buffer;
- pParameterHRD = (VAEncMiscParameterHRD*)pMiscParamHRD->data;
-
if (pSequenceParameter->ip_period) {
pnum = (intra_period + ip_period - 1) / ip_period - 1;
bnum = intra_period - inum - pnum;
@@ -2262,7 +2255,7 @@ static void intel_hcpe_brc_init(struct encode_state *encode_state,
bpf = mfc_context->brc.bits_per_frame = bitrate / framerate;
- if (!pParameterHRD || pParameterHRD->buffer_size <= 0)
+ if (!encoder_context->brc.hrd_buffer_size)
{
mfc_context->hrd.buffer_size = bitrate * ratio;
mfc_context->hrd.current_buffer_fullness =
@@ -2270,7 +2263,7 @@ static void intel_hcpe_brc_init(struct encode_state *encode_state,
bitrate * ratio/2 : mfc_context->hrd.buffer_size / 2.;
}else
{
- buffer_size = (double)pParameterHRD->buffer_size ;
+ buffer_size = (double)encoder_context->brc.hrd_buffer_size;
if(buffer_size < bitrate * ratio_min)
{
buffer_size = bitrate * ratio_min;
@@ -2279,11 +2272,11 @@ static void intel_hcpe_brc_init(struct encode_state *encode_state,
buffer_size = bitrate * ratio_max ;
}
mfc_context->hrd.buffer_size =buffer_size;
- if(pParameterHRD->initial_buffer_fullness > 0)
+ if(encoder_context->brc.hrd_initial_buffer_fullness)
{
mfc_context->hrd.current_buffer_fullness =
- (double)(pParameterHRD->initial_buffer_fullness < mfc_context->hrd.buffer_size) ?
- pParameterHRD->initial_buffer_fullness : mfc_context->hrd.buffer_size / 2.;
+ (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.;
}else
{
mfc_context->hrd.current_buffer_fullness = mfc_context->hrd.buffer_size / 2.;
@@ -2468,9 +2461,8 @@ static void intel_hcpe_hrd_context_init(struct encode_state *encode_state,
struct intel_encoder_context *encoder_context)
{
struct gen9_hcpe_context *mfc_context = encoder_context->mfc_context;
- VAEncSequenceParameterBufferHEVC *pSequenceParameter = (VAEncSequenceParameterBufferHEVC *)encode_state->seq_param_ext->buffer;
unsigned int rate_control_mode = encoder_context->rate_control_mode;
- int target_bit_rate = pSequenceParameter->bits_per_second;
+ unsigned int target_bit_rate = encoder_context->brc.bits_per_second[0];
// current we only support CBR mode.
if (rate_control_mode == VA_RC_CBR) {
@@ -2519,51 +2511,6 @@ int intel_hcpe_interlace_check(VADriverContextP ctx,
return 1;
}
-/*
- * Check whether the parameters related with CBR are updated and decide whether
- * it needs to reinitialize the configuration related with CBR.
- * Currently it will check the following parameters:
- * bits_per_second
- * frame_rate
- * gop_configuration(intra_period, ip_period, intra_idr_period)
- */
-static bool intel_hcpe_brc_updated_check(struct encode_state *encode_state,
- struct intel_encoder_context *encoder_context)
-{
- /* to do */
- unsigned int rate_control_mode = encoder_context->rate_control_mode;
- struct gen9_hcpe_context *mfc_context = encoder_context->mfc_context;
- double cur_fps, cur_bitrate;
- VAEncSequenceParameterBufferHEVC *pSequenceParameter;
-
-
- if (rate_control_mode != VA_RC_CBR) {
- return false;
- }
-
- pSequenceParameter = (VAEncSequenceParameterBufferHEVC *)encode_state->seq_param_ext->buffer;
-
- cur_bitrate = pSequenceParameter->bits_per_second;
- cur_fps = (double)pSequenceParameter->vui_time_scale /
- (double)pSequenceParameter->vui_num_units_in_tick;
-
- if ((cur_bitrate == mfc_context->brc.saved_bps) &&
- (cur_fps == mfc_context->brc.saved_fps) &&
- (pSequenceParameter->intra_period == mfc_context->brc.saved_intra_period) &&
- (pSequenceParameter->intra_idr_period == mfc_context->brc.saved_idr_period) &&
- (pSequenceParameter->intra_period == mfc_context->brc.saved_intra_period)) {
- /* the parameters related with CBR are not updaetd */
- return false;
- }
-
- mfc_context->brc.saved_ip_period = pSequenceParameter->ip_period;
- mfc_context->brc.saved_intra_period = pSequenceParameter->intra_period;
- mfc_context->brc.saved_idr_period = pSequenceParameter->intra_idr_period;
- mfc_context->brc.saved_fps = cur_fps;
- mfc_context->brc.saved_bps = cur_bitrate;
- return true;
-}
-
void intel_hcpe_brc_prepare(struct encode_state *encode_state,
struct intel_encoder_context *encoder_context)
{
@@ -2574,12 +2521,12 @@ void intel_hcpe_brc_prepare(struct encode_state *encode_state,
bool brc_updated;
assert(encoder_context->codec != CODEC_MPEG2);
- brc_updated = intel_hcpe_brc_updated_check(encode_state, encoder_context);
+ brc_updated = encoder_context->brc.need_reset;
/*Programing bit rate control */
if ((mfc_context->bit_rate_control_context[HEVC_SLICE_I].MaxSizeInWord == 0) ||
brc_updated) {
- intel_hcpe_bit_rate_control_context_init(encode_state, mfc_context);
+ intel_hcpe_bit_rate_control_context_init(encode_state, encoder_context);
intel_hcpe_brc_init(encode_state, encoder_context);
}
diff --git a/src/i965_encoder.c b/src/i965_encoder.c
index 3aaac34..76789f3 100644
--- a/src/i965_encoder.c
+++ b/src/i965_encoder.c
@@ -432,19 +432,83 @@ intel_encoder_check_brc_vp8_sequence_parameter(VADriverContextP ctx,
}
static VAStatus
+intel_encoder_check_brc_hevc_sequence_parameter(VADriverContextP ctx,
+ struct encode_state *encode_state,
+ struct intel_encoder_context *encoder_context)
+{
+ VAEncSequenceParameterBufferHEVC *seq_param = (VAEncSequenceParameterBufferHEVC*)encode_state->seq_param_ext->buffer;
+ struct intel_fraction framerate;
+ unsigned int gop_size, num_iframes_in_gop, num_pframes_in_gop, num_bframes_in_gop;
+
+ if (!encoder_context->is_new_sequence)
+ return VA_STATUS_SUCCESS;
+ if (!seq_param)
+ return VA_STATUS_ERROR_INVALID_PARAMETER;
+
+ if (!seq_param->vui_time_scale || !seq_param->vui_num_units_in_tick)
+ framerate = (struct intel_fraction) { 30, 1 };
+ else
+ framerate = (struct intel_fraction) { seq_param->vui_time_scale, seq_param->vui_num_units_in_tick };
+ framerate = reduce_fraction(framerate);
+
+ num_iframes_in_gop = 1;
+ if (seq_param->intra_period == 0) {
+ gop_size = -1;
+ num_pframes_in_gop = -1;
+ } else if (seq_param->intra_period == 1) {
+ gop_size = 1;
+ num_pframes_in_gop = 0;
+ } else {
+ gop_size = seq_param->intra_period;
+ num_pframes_in_gop = (seq_param->intra_period + seq_param->ip_period - 1) / seq_param->ip_period - 1;
+ }
+ num_bframes_in_gop = gop_size - num_iframes_in_gop - num_pframes_in_gop;
+
+ if (encoder_context->brc.framerate[0].num != framerate.num ||
+ encoder_context->brc.framerate[0].den != framerate.den) {
+ encoder_context->brc.framerate[0] = framerate;
+ encoder_context->brc.need_reset = 1;
+ }
+
+ if (encoder_context->brc.gop_size != gop_size ||
+ encoder_context->brc.num_iframes_in_gop != num_iframes_in_gop ||
+ encoder_context->brc.num_pframes_in_gop != num_pframes_in_gop ||
+ encoder_context->brc.num_bframes_in_gop != num_bframes_in_gop) {
+ encoder_context->brc.gop_size = gop_size;
+ encoder_context->brc.num_iframes_in_gop = num_iframes_in_gop;
+ encoder_context->brc.num_pframes_in_gop = num_pframes_in_gop;
+ encoder_context->brc.num_bframes_in_gop = num_bframes_in_gop;
+ encoder_context->brc.need_reset = 1;
+ }
+
+ if (encoder_context->brc.bits_per_second[0] != seq_param->bits_per_second) {
+ encoder_context->brc.bits_per_second[0] = seq_param->bits_per_second;
+ encoder_context->brc.need_reset = 1;
+ }
+
+ return VA_STATUS_SUCCESS;
+}
+
+static VAStatus
intel_encoder_check_brc_sequence_parameter(VADriverContextP ctx,
struct encode_state *encode_state,
struct intel_encoder_context *encoder_context)
{
- if (encoder_context->codec == CODEC_H264 ||
- encoder_context->codec == CODEC_H264_MVC)
+ switch (encoder_context->codec) {
+ case CODEC_H264:
+ case CODEC_H264_MVC:
return intel_encoder_check_brc_h264_sequence_parameter(ctx, encode_state, encoder_context);
- if (encoder_context->codec == CODEC_VP8)
+ case CODEC_VP8:
return intel_encoder_check_brc_vp8_sequence_parameter(ctx, encode_state, encoder_context);
- // TODO: other codecs
- return VA_STATUS_SUCCESS;
+ case CODEC_HEVC:
+ return intel_encoder_check_brc_hevc_sequence_parameter(ctx, encode_state, encoder_context);
+
+ default:
+ // TODO: other codecs
+ return VA_STATUS_SUCCESS;
+ }
}
static void