summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Thompson <sw@jkqxz.net>2016-12-23 01:11:38 +0000
committerXiang, Haihao <haihao.xiang@intel.com>2016-12-23 23:25:55 +0800
commitb86c3e9149ddd35113d39935a948e457eff74287 (patch)
tree6da94adf04cef4de20ae96d12ce7df146381c6c9
parente80ea9ba75776584d573ac7e75c1a2309dc12d93 (diff)
VP9 encoder: use generic rate control parameters
Also adds support for fractional framerate. Signed-off-by: Mark Thompson <sw@jkqxz.net> Reviewed-by: Xiang, Haihao<haihao.xiang@intel.com>
-rw-r--r--src/gen9_vp9_encoder.c232
-rw-r--r--src/gen9_vp9_encoder.h12
-rw-r--r--src/i965_drv_video.c10
-rw-r--r--src/i965_encoder.c36
-rw-r--r--src/i965_encoder.h1
5 files changed, 69 insertions, 222 deletions
diff --git a/src/gen9_vp9_encoder.c b/src/gen9_vp9_encoder.c
index 3ea1537..05d86da 100644
--- a/src/gen9_vp9_encoder.c
+++ b/src/gen9_vp9_encoder.c
@@ -1201,8 +1201,8 @@ void gen9_vp9_set_curbe_brc(VADriverContextP ctx,
VP9_BRC_KBPS;
cmd->dw9.min_bit_rate = (vp9_state->min_bit_rate + VP9_BRC_KBPS - 1) / VP9_BRC_KBPS *
VP9_BRC_KBPS;
- cmd->dw10.frame_ratem = vp9_state->frame_rate;
- cmd->dw11.frame_rated = 1;
+ cmd->dw10.frame_ratem = vp9_state->framerate.num;
+ cmd->dw11.frame_rated = vp9_state->framerate.den;
cmd->dw14.avbr_accuracy = 30;
cmd->dw14.avbr_convergence = 150;
@@ -1235,8 +1235,8 @@ void gen9_vp9_set_curbe_brc(VADriverContextP ctx,
cmd->dw17.enable_dynamic_scaling = vp9_state->dys_in_use;
cmd->dw17.brc_overshoot_cbr_pct = 150;
- dInputBitsPerFrame = (double)(cmd->dw8.max_bit_rate) / (vp9_state->frame_rate);
- dbps_ratio = dInputBitsPerFrame / ((double)(vp9_state->vbv_buffer_size_in_bit) / 30);
+ dInputBitsPerFrame = (double)cmd->dw8.max_bit_rate * (double)vp9_state->framerate.den / (double)vp9_state->framerate.num;
+ dbps_ratio = dInputBitsPerFrame / ((double)vp9_state->vbv_buffer_size_in_bit / 30.0);
if (dbps_ratio < 0.1)
dbps_ratio = 0.1;
if (dbps_ratio > 3.5)
@@ -1423,7 +1423,6 @@ gen9_vp9_brc_init_reset_kernel(VADriverContextP ctx,
brc_initreset_curbe.initbrc = !vp9_state->brc_inited;
brc_initreset_curbe.mbbrc_enabled = 0;
brc_initreset_curbe.ref_frame_flag = vp9_state->ref_frame_flag;
- brc_initreset_curbe.frame_rate = vp9_state->frame_rate;
vme_context->pfn_set_curbe_brc(ctx, encode_state,
gpe_context,
@@ -1523,7 +1522,6 @@ gen9_vp9_brc_intra_dist_kernel(VADriverContextP ctx,
brc_intra_dist_curbe.initbrc = !vp9_state->brc_inited;
brc_intra_dist_curbe.mbbrc_enabled = 0;
brc_intra_dist_curbe.ref_frame_flag = vp9_state->ref_frame_flag;
- brc_intra_dist_curbe.frame_rate = vp9_state->frame_rate;
vme_context->pfn_set_curbe_brc(ctx, encode_state,
gpe_context,
@@ -3926,169 +3924,40 @@ gen9_encode_vp9_check_parameter(VADriverContextP ctx,
return VA_STATUS_ERROR_UNIMPLEMENTED;
if (vp9_state->brc_enabled) {
- if (vp9_state->brc_flag_check & VP9_BRC_FAILURE) {
- WARN_ONCE("Rate control misc_parameter is required for BRC\n");
- return VA_STATUS_ERROR_INVALID_PARAMETER;
- }
+ if (vp9_state->first_frame || vp9_state->picture_coding_type == KEY_FRAME) {
+ vp9_state->brc_reset = encoder_context->brc.need_reset || vp9_state->first_frame;
- if (vp9_state->first_frame) {
- unsigned int brc_flag;
- VAEncMiscParameterBuffer *misc_param;
-
- brc_flag = VP9_BRC_SEQ | VP9_BRC_RC;
- if ((vp9_state->brc_flag_check & brc_flag) != brc_flag) {
- WARN_ONCE("SPS/RC misc is required for BRC\n");
+ if (!encoder_context->brc.framerate[0].num || !encoder_context->brc.framerate[0].den ||
+ !encoder_context->brc.bits_per_second[0])
return VA_STATUS_ERROR_INVALID_PARAMETER;
- }
- /* check the corresponding BRC parameter for CBR and VBR */
- if (encoder_context->rate_control_mode == VA_RC_CBR) {
- vp9_state->target_bit_rate = seq_param->bits_per_second;
- vp9_state->gop_size = seq_param->intra_period;
-
- if (vp9_state->brc_flag_check & VP9_BRC_HRD) {
- VAEncMiscParameterHRD *misc_param_hrd;
-
- misc_param = (VAEncMiscParameterBuffer *)
- encode_state->misc_param[VAEncMiscParameterTypeHRD][0]->buffer;
- misc_param_hrd = (VAEncMiscParameterHRD *)misc_param->data;
-
- vp9_state->init_vbv_buffer_fullness_in_bit = misc_param_hrd->initial_buffer_fullness;
- vp9_state->vbv_buffer_size_in_bit = misc_param_hrd->buffer_size;
- }
-
- if (vp9_state->brc_flag_check & VP9_BRC_FR) {
- VAEncMiscParameterFrameRate *misc_param_fr;
-
- misc_param = (VAEncMiscParameterBuffer *)
- encode_state->misc_param[VAEncMiscParameterTypeFrameRate][0]->buffer;
- misc_param_fr = (VAEncMiscParameterFrameRate *)misc_param->data;
-
- vp9_state->frame_rate = misc_param_fr->framerate;
- } else {
- /* Assign the default frame rate */
- vp9_state->frame_rate = 30;
- }
-
- /* RC misc will override HRD parameter */
- if (vp9_state->brc_flag_check & VP9_BRC_RC) {
- VAEncMiscParameterRateControl *misc_param_rc;
-
- misc_param = (VAEncMiscParameterBuffer *)
- encode_state->misc_param[VAEncMiscParameterTypeRateControl][0]->buffer;
- misc_param_rc = (VAEncMiscParameterRateControl *)misc_param->data;
-
- vp9_state->target_bit_rate = misc_param_rc->bits_per_second;
- vp9_state->vbv_buffer_size_in_bit = (misc_param_rc->bits_per_second / 1000) *
- misc_param_rc->window_size;
- vp9_state->init_vbv_buffer_fullness_in_bit = vp9_state->vbv_buffer_size_in_bit / 2;
- vp9_state->window_size = misc_param_rc->window_size;
- }
+ vp9_state->gop_size = encoder_context->brc.gop_size;
+ vp9_state->framerate = encoder_context->brc.framerate[0];
+
+ if (encoder_context->rate_control_mode == VA_RC_CBR ||
+ !encoder_context->brc.target_percentage[0]) {
+ vp9_state->target_bit_rate = encoder_context->brc.bits_per_second[0];
vp9_state->max_bit_rate = vp9_state->target_bit_rate;
vp9_state->min_bit_rate = vp9_state->target_bit_rate;
} else {
- /* VBR mode */
- brc_flag = VP9_BRC_SEQ | VP9_BRC_RC;
- vp9_state->target_bit_rate = seq_param->bits_per_second;
- vp9_state->gop_size = seq_param->intra_period;
-
- if (vp9_state->brc_flag_check & VP9_BRC_FR) {
- VAEncMiscParameterFrameRate *misc_param_fr;
-
- misc_param = (VAEncMiscParameterBuffer *)
- encode_state->misc_param[VAEncMiscParameterTypeFrameRate][0]->buffer;
- misc_param_fr = (VAEncMiscParameterFrameRate *)misc_param->data;
-
- vp9_state->frame_rate = misc_param_fr->framerate;
- } else {
- /* Assign the default frame rate */
- vp9_state->frame_rate = 30;
- }
-
- if (vp9_state->brc_flag_check & VP9_BRC_RC) {
- VAEncMiscParameterRateControl *misc_param_rc;
-
- misc_param = (VAEncMiscParameterBuffer *)
- encode_state->misc_param[VAEncMiscParameterTypeRateControl][0]->buffer;
- misc_param_rc = (VAEncMiscParameterRateControl *)misc_param->data;
-
- vp9_state->max_bit_rate = misc_param_rc->bits_per_second;
- vp9_state->vbv_buffer_size_in_bit = (misc_param_rc->bits_per_second / 1000) *
- misc_param_rc->window_size;
- vp9_state->init_vbv_buffer_fullness_in_bit = vp9_state->vbv_buffer_size_in_bit / 2;
- vp9_state->target_bit_rate = (misc_param_rc->bits_per_second / 100) *
- misc_param_rc->target_percentage;
- vp9_state->min_bit_rate = (misc_param_rc->bits_per_second / 100) *
- (2 * misc_param_rc->target_percentage - 100);
- vp9_state->target_percentage = misc_param_rc->target_percentage;
- vp9_state->window_size = misc_param_rc->window_size;
- }
- }
- }
- else if (vp9_state->picture_coding_type == KEY_FRAME){
- VAEncMiscParameterBuffer *misc_param;
- /* update the BRC parameter only when it is key-frame */
- /* If the parameter related with RC is changed. Reset BRC */
- if (vp9_state->brc_flag_check & VP9_BRC_FR) {
- VAEncMiscParameterFrameRate *misc_param_fr;
-
- misc_param = (VAEncMiscParameterBuffer *)
- encode_state->misc_param[VAEncMiscParameterTypeFrameRate][0]->buffer;
- misc_param_fr = (VAEncMiscParameterFrameRate *)misc_param->data;
-
- if (vp9_state->frame_rate != misc_param_fr->framerate) {
- vp9_state->brc_reset = 1;
- vp9_state->frame_rate = misc_param_fr->framerate;
- }
- }
-
- /* check the GOP size. And bit_per_second in SPS is ignored */
- if (vp9_state->brc_flag_check & VP9_BRC_SEQ) {
- if (vp9_state->gop_size != seq_param->intra_period) {
- vp9_state->brc_reset = 1;
- vp9_state->gop_size = seq_param->intra_period;
- }
+ vp9_state->max_bit_rate = encoder_context->brc.bits_per_second[0];
+ vp9_state->target_bit_rate = vp9_state->max_bit_rate * encoder_context->brc.target_percentage[0] / 100;
+ if (2 * vp9_state->target_bit_rate < vp9_state->max_bit_rate)
+ vp9_state->min_bit_rate = 0;
+ else
+ vp9_state->min_bit_rate = 2 * vp9_state->target_bit_rate - vp9_state->max_bit_rate;
}
- /* update the bit_per_second */
- if (vp9_state->brc_flag_check & VP9_BRC_RC) {
- VAEncMiscParameterRateControl *misc_param_rc;
-
- misc_param = (VAEncMiscParameterBuffer *)
- encode_state->misc_param[VAEncMiscParameterTypeRateControl][0]->buffer;
- misc_param_rc = (VAEncMiscParameterRateControl *)misc_param->data;
-
- if (encoder_context->rate_control_mode == VA_RC_CBR) {
- if (vp9_state->target_bit_rate != misc_param_rc->bits_per_second ||
- vp9_state->window_size != misc_param_rc->window_size) {
- vp9_state->target_bit_rate = misc_param_rc->bits_per_second;
- vp9_state->vbv_buffer_size_in_bit = (misc_param_rc->bits_per_second / 1000) *
- misc_param_rc->window_size;
- vp9_state->init_vbv_buffer_fullness_in_bit = vp9_state->vbv_buffer_size_in_bit * 2;
- vp9_state->window_size = misc_param_rc->window_size;
- vp9_state->max_bit_rate = vp9_state->target_bit_rate;
- vp9_state->min_bit_rate = vp9_state->target_bit_rate;
- vp9_state->brc_reset = 1;
- }
- } else {
- /* VBR mode */
- if (vp9_state->max_bit_rate != misc_param_rc->bits_per_second ||
- vp9_state->target_percentage != misc_param_rc->target_percentage) {
-
- vp9_state->target_bit_rate = (misc_param_rc->bits_per_second / 100) *
- misc_param_rc->target_percentage;
- vp9_state->min_bit_rate = (misc_param_rc->bits_per_second / 100) *
- (2 * misc_param_rc->target_percentage - 100);
- vp9_state->max_bit_rate = misc_param_rc->bits_per_second;
- vp9_state->vbv_buffer_size_in_bit = (misc_param_rc->bits_per_second / 1000) *
- misc_param_rc->window_size;
- vp9_state->init_vbv_buffer_fullness_in_bit = vp9_state->vbv_buffer_size_in_bit / 2;
- vp9_state->target_percentage = misc_param_rc->target_percentage;
- vp9_state->window_size = misc_param_rc->window_size;
- vp9_state->brc_reset = 1;
- }
- }
- }
+ if (encoder_context->brc.hrd_buffer_size)
+ vp9_state->vbv_buffer_size_in_bit = encoder_context->brc.hrd_buffer_size;
+ else if (encoder_context->brc.window_size)
+ vp9_state->vbv_buffer_size_in_bit = (uint64_t)vp9_state->max_bit_rate * encoder_context->brc.window_size / 1000;
+ else
+ vp9_state->vbv_buffer_size_in_bit = vp9_state->max_bit_rate;
+ if (encoder_context->brc.hrd_initial_buffer_fullness)
+ vp9_state->init_vbv_buffer_fullness_in_bit = encoder_context->brc.hrd_initial_buffer_fullness;
+ else
+ vp9_state->init_vbv_buffer_fullness_in_bit = vp9_state->vbv_buffer_size_in_bit / 2;
}
}
@@ -5805,47 +5674,6 @@ static void
gen9_vp9_pak_brc_prepare(struct encode_state *encode_state,
struct intel_encoder_context *encoder_context)
{
- struct gen9_encoder_context_vp9 *pak_context = encoder_context->mfc_context;
- struct gen9_vp9_state *vp9_state;
-
- vp9_state = (struct gen9_vp9_state *)(encoder_context->enc_priv_state);
-
- if (!vp9_state || !pak_context)
- return;
-
- if (vp9_state->brc_enabled) {
- /* check the buffer related with BRC */
- vp9_state->brc_flag_check = 0;
- if (encode_state->seq_param_ext && encode_state->seq_param_ext->buffer) {
- vp9_state->brc_flag_check |= VP9_BRC_SEQ;
- }
-
- /* Frame_rate */
- if (encode_state->misc_param[VAEncMiscParameterTypeFrameRate][0] &&
- encode_state->misc_param[VAEncMiscParameterTypeFrameRate][0]->buffer) {
- vp9_state->brc_flag_check |= VP9_BRC_FR;
- }
-
- /* HRD */
- if (encode_state->misc_param[VAEncMiscParameterTypeRateControl][0] &&
- encode_state->misc_param[VAEncMiscParameterTypeRateControl][0]->buffer) {
- vp9_state->brc_flag_check |= VP9_BRC_RC;
- }
-
- if (encode_state->misc_param[VAEncMiscParameterTypeHRD][0] &&
- encode_state->misc_param[VAEncMiscParameterTypeHRD][0]->buffer) {
- vp9_state->brc_flag_check |= VP9_BRC_HRD;
- }
-
- /*
- * If user-app doesn't pass the buffer related with BRC for the first
- * frame, the error flag is returned.
- */
- if (vp9_state->brc_flag_check == 0 && vp9_state->first_frame) {
- vp9_state->brc_flag_check |= VP9_BRC_FAILURE;
- }
- }
- return;
}
static void
diff --git a/src/gen9_vp9_encoder.h b/src/gen9_vp9_encoder.h
index ad2d875..972e2ad 100644
--- a/src/gen9_vp9_encoder.h
+++ b/src/gen9_vp9_encoder.h
@@ -1552,7 +1552,6 @@ struct gen9_vp9_brc_curbe_param
int32_t brc_num_pak_passes;
bool multi_ref_qp_check;
int16_t frame_number;
- int32_t frame_rate;
VP9_MEDIA_STATE_TYPE media_state_type;
};
@@ -1649,12 +1648,6 @@ typedef struct _vp9_frame_status_
uint8_t intra_only;
} vp9_frame_status;
-#define VP9_BRC_SEQ 0x01
-#define VP9_BRC_HRD 0x02
-#define VP9_BRC_RC 0x04
-#define VP9_BRC_FR 0x08
-#define VP9_BRC_FAILURE (1 << 31)
-
struct gen9_hcpe_pipe_mode_select_param
{
uint32_t codec_mode;
@@ -1925,18 +1918,15 @@ struct gen9_vp9_state {
unsigned long init_vbv_buffer_fullness_in_bit;
unsigned long vbv_buffer_size_in_bit;
int frame_number;
- uint32_t frame_rate;
+ struct intel_fraction framerate;
uint8_t ref_frame_flag;
uint8_t dys_ref_frame_flag;
uint8_t picture_coding_type;
unsigned int adaptive_transform_decision_enabled;
int curr_mode_decision_index;
int target_usage;
- int window_size;
- int target_percentage;
unsigned int mb_data_offset;
int curr_pak_pass;
- unsigned int brc_flag_check;
bool first_frame;
bool dys_enabled;
bool dys_in_use;
diff --git a/src/i965_drv_video.c b/src/i965_drv_video.c
index e602b4e..15920f5 100644
--- a/src/i965_drv_video.c
+++ b/src/i965_drv_video.c
@@ -2794,7 +2794,7 @@ i965_BeginPicture(VADriverContextP ctx,
struct object_surface *obj_surface = SURFACE(render_target);
struct object_config *obj_config;
VAStatus vaStatus = VA_STATUS_SUCCESS;
- int i, j;
+ int i;
ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
@@ -2848,14 +2848,6 @@ i965_BeginPicture(VADriverContextP ctx,
i965_release_buffer_store(&obj_context->codec_state.encode.misc_param[VAEncMiscParameterTypeROI][0]);
i965_release_buffer_store(&obj_context->codec_state.encode.encmb_map);
-
- if (obj_config->profile == VAProfileVP9Profile0) {
- for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.misc_param); i++)
- for (j = 0; j < ARRAY_ELEMS(obj_context->codec_state.encode.misc_param[0]); j++)
- i965_release_buffer_store(&obj_context->codec_state.encode.misc_param[i][j]);
-
- i965_release_buffer_store(&obj_context->codec_state.encode.seq_param_ext);
- }
} else {
obj_context->codec_state.decode.current_render_target = render_target;
i965_release_buffer_store(&obj_context->codec_state.decode.pic_param);
diff --git a/src/i965_encoder.c b/src/i965_encoder.c
index 76789f3..be37b84 100644
--- a/src/i965_encoder.c
+++ b/src/i965_encoder.c
@@ -490,6 +490,34 @@ intel_encoder_check_brc_hevc_sequence_parameter(VADriverContextP ctx,
}
static VAStatus
+intel_encoder_check_brc_vp9_sequence_parameter(VADriverContextP ctx,
+ struct encode_state *encode_state,
+ struct intel_encoder_context *encoder_context)
+{
+ VAEncSequenceParameterBufferVP9 *seq_param = (VAEncSequenceParameterBufferVP9*)encode_state->seq_param_ext->buffer;
+ unsigned int gop_size;
+
+ if (!encoder_context->is_new_sequence)
+ return VA_STATUS_SUCCESS;
+ if (!seq_param)
+ return VA_STATUS_ERROR_INVALID_PARAMETER;
+
+ if (seq_param->intra_period == 0)
+ gop_size = -1; // Dummy value (infinity).
+ else
+ gop_size = seq_param->intra_period;
+
+ if (encoder_context->brc.bits_per_second[0] != seq_param->bits_per_second ||
+ encoder_context->brc.gop_size != gop_size) {
+ encoder_context->brc.bits_per_second[0] = seq_param->bits_per_second;
+ encoder_context->brc.gop_size = gop_size;
+ 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)
@@ -505,6 +533,9 @@ intel_encoder_check_brc_sequence_parameter(VADriverContextP ctx,
case CODEC_HEVC:
return intel_encoder_check_brc_hevc_sequence_parameter(ctx, encode_state, encoder_context);
+ case CODEC_VP9:
+ return intel_encoder_check_brc_vp9_sequence_parameter(ctx, encode_state, encoder_context);
+
default:
// TODO: other codecs
return VA_STATUS_SUCCESS;
@@ -541,6 +572,11 @@ intel_encoder_check_rate_control_parameter(VADriverContextP ctx,
encoder_context->brc.target_percentage[temporal_id] = misc->target_percentage;
encoder_context->brc.need_reset = 1;
}
+
+ if (encoder_context->brc.window_size != misc->window_size) {
+ encoder_context->brc.window_size = misc->window_size;
+ encoder_context->brc.need_reset = 1;
+ }
}
static void
diff --git a/src/i965_encoder.h b/src/i965_encoder.h
index 7016975..be19ce6 100644
--- a/src/i965_encoder.h
+++ b/src/i965_encoder.h
@@ -91,6 +91,7 @@ struct intel_encoder_context
unsigned int target_percentage[MAX_TEMPORAL_LAYERS];
unsigned int hrd_buffer_size;
unsigned int hrd_initial_buffer_fullness;
+ unsigned int window_size;
unsigned int need_reset;
unsigned int num_roi;