Signed-off-by: Mark Thompson <s...@jkqxz.net> --- src/gen9_mfc.h | 6 ---- src/gen9_mfc_hevc.c | 83 ++++++++++------------------------------------------- src/i965_encoder.c | 74 +++++++++++++++++++++++++++++++++++++++++++---- 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 e5aff72..20ae554 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 -- 2.10.2 _______________________________________________ Libva mailing list Libva@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libva