On Mon, 2016-12-19 at 23:01 +0000, Mark Thompson wrote: > Also adds support for fractional framerate. > > Signed-off-by: Mark Thompson <s...@jkqxz.net> > --- > src/gen9_vp9_encoder.c | 240 > ++++++++----------------------------------------- > src/gen9_vp9_encoder.h | 10 +-- > src/i965_drv_video.c | 10 +-- > src/i965_encoder.c | 36 ++++++++ > src/i965_encoder.h | 1 + > 5 files changed, 77 insertions(+), 220 deletions(-) > > diff --git a/src/gen9_vp9_encoder.c b/src/gen9_vp9_encoder.c > index 3ea1537..2e884e2 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,168 +3924,47 @@ 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) { > - 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"); > - 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; > > /* 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; > - } > + 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; > + > + vp9_state->gop_size = encoder_context->brc.gop_size; > + > + vp9_state->framerate = encoder_context->brc.framerate[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->vbv_buffer_size_in_bit = > encoder_context->brc.hrd_buffer_size; > + vp9_state->init_vbv_buffer_fullness_in_bit = > encoder_context->brc.hrd_initial_buffer_fullness;
vp9_state->init_vbv_buffer_fullness_in_bit may be overrode by the misc RC parameters (vp9_state->window_size) in the current code. > > - /* 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; > - } > - } > + } else { > + /* VBR mode */ > + if (!encoder_context->brc.framerate[0].num || > !encoder_context->brc.framerate[0].den || > + !encoder_context->brc.bits_per_second[0] || > !encoder_context->brc.target_percentage[0] || > + !encoder_context->brc.window_size) > + return VA_STATUS_ERROR_INVALID_PARAMETER; > + > + vp9_state->gop_size = encoder_context->brc.gop_size; > + > + vp9_state->framerate = encoder_context->brc.framerate[0]; > + vp9_state->max_bit_rate = > encoder_context->brc.bits_per_second[0]; > + vp9_state->target_percentage = > encoder_context->brc.target_percentage[0]; > + vp9_state->window_size = encoder_context->brc.window_size; > + > + 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; > + > + vp9_state->vbv_buffer_size_in_bit = (vp9_state->max_bit_rate > / 1000) * vp9_state->window_size; > + vp9_state->init_vbv_buffer_fullness_in_bit = > vp9_state->vbv_buffer_size_in_bit / 2; This patch uses two different ways to get vp9_state->vbv_buffer_size_in_bit for CBR and VBR. I think we should use the same way. I prefer the way used for CBR in your patch although it is not the same of the current code. > } > } > } > @@ -5805,47 +5682,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..76f58a6 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,7 +1918,7 @@ 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; > @@ -1936,7 +1929,6 @@ struct gen9_vp9_state { > 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 20ae554..192c8b8 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; _______________________________________________ Libva mailing list Libva@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libva