Hi Mark, Thanks for your patch, is there any benefit to use a fraction? using 100 as framerate_den works well in the driver.
Regards Haihao > Update references in both H.264 encoders (gen6_mfc and gen9_vdenc). > > Signed-off-by: Mark Thompson <[email protected]> > --- > src/gen6_mfc_common.c | 11 ++++++---- > src/gen9_vdenc.c | 29 ++++++++++++++---------- > src/gen9_vdenc.h | 3 ++- > src/i965_encoder.c | 61 +++++++++++++++++++++++++++++++++++++-- > ------------ > src/i965_encoder.h | 3 ++- > 5 files changed, 72 insertions(+), 35 deletions(-) > > diff --git a/src/gen6_mfc_common.c b/src/gen6_mfc_common.c > index 68d030e..c29817e 100644 > --- a/src/gen6_mfc_common.c > +++ b/src/gen6_mfc_common.c > @@ -119,16 +119,19 @@ static void intel_mfc_brc_init(struct > encode_state *encode_state, > > if (i == 0) { > bitrate = encoder_context->brc.bits_per_second[0]; > - framerate = (double)encoder_context- > >brc.framerate_per_100s[0] / 100.0; > + framerate = (double)encoder_context- > >brc.framerate_num[0] / (double)encoder_context- > >brc.framerate_den[0]; > } else { > bitrate = (encoder_context->brc.bits_per_second[i] - > encoder_context->brc.bits_per_second[i - 1]); > - framerate = (double)(encoder_context- > >brc.framerate_per_100s[i] - encoder_context- > >brc.framerate_per_100s[i - 1]) / 100.0; > + framerate = ((double)encoder_context- > >brc.framerate_num[i] / (double)encoder_context- > >brc.framerate_den[i]) - > + ((double)encoder_context->brc.framerate_num[i - 1] / > (double)encoder_context->brc.framerate_den[i - 1]); > } > > 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[encoder_context->layer.num_layers - 1]; > + else { > + factor = ((double)encoder_context->brc.framerate_num[i] > / (double)encoder_context->brc.framerate_den[i]) / > + ((double)encoder_context->brc.framerate_num[i - 1] / > (double)encoder_context->brc.framerate_den[i - 1]); > + } > > hrd_factor = (double)bitrate / encoder_context- > >brc.bits_per_second[encoder_context->layer.num_layers - 1]; > > diff --git a/src/gen9_vdenc.c b/src/gen9_vdenc.c > index 8009b31..b2d0b21 100644 > --- a/src/gen9_vdenc.c > +++ b/src/gen9_vdenc.c > @@ -851,7 +851,8 @@ > gen9_vdenc_update_misc_parameters(VADriverContextP ctx, > if (vdenc_context->internal_rate_mode != I965_BRC_CQP && > encoder_context->brc.need_reset) { > /* So far, vdenc doesn't support temporal layer */ > - vdenc_context->frames_per_100s = encoder_context- > >brc.framerate_per_100s[0]; > + vdenc_context->framerate_num = encoder_context- > >brc.framerate_num[0]; > + vdenc_context->framerate_den = encoder_context- > >brc.framerate_den[0]; > > vdenc_context->vbv_buffer_size_in_bit = encoder_context- > >brc.hrd_buffer_size; > vdenc_context->init_vbv_buffer_fullness_in_bit = > encoder_context->brc.hrd_initial_buffer_fullness; > @@ -927,7 +928,8 @@ gen9_vdenc_update_parameters(VADriverContextP > ctx, > !vdenc_context->vbv_buffer_size_in_bit || > !vdenc_context->max_bit_rate || > !vdenc_context->target_bit_rate || > - !vdenc_context->frames_per_100s)) > + !vdenc_context->framerate_num || > + !vdenc_context->framerate_den)) > vdenc_context->brc_enabled = 0; > > if (!vdenc_context->brc_enabled) { > @@ -1565,7 +1567,8 @@ > gen9_vdenc_get_profile_level_max_frame(VADriverContextP ctx, > tmpf = max_mbps / 172.0; > > max_byte_per_frame0 = (uint64_t)(tmpf * bits_per_mb); > - max_byte_per_frame1 = (uint64_t)(((double)max_mbps * 100) / > vdenc_context->frames_per_100s *bits_per_mb); > + max_byte_per_frame1 = (uint64_t)(((double)max_mbps * > vdenc_context->framerate_den) / > + (double)vdenc_context- > >framerate_num * bits_per_mb); > > /* TODO: check VAEncMiscParameterTypeMaxFrameSize */ > ret = (unsigned int)MIN(max_byte_per_frame0, > max_byte_per_frame1); > @@ -1586,12 +1589,12 @@ > gen9_vdenc_calculate_initial_qp(VADriverContextP ctx, > > frame_size = (vdenc_context->frame_width * vdenc_context- > >frame_height * 3 / 2); > qp = (int)(1.0 / 1.2 * pow(10.0, > - (log10(frame_size * 2.0 / 3.0 * > ((float)vdenc_context->frames_per_100s) / > - ((float)(vdenc_context- > >target_bit_rate * 1000) * 100)) - x0) * > + (log10(frame_size * 2.0 / 3.0 * > vdenc_context->framerate_num / > + ((double)vdenc_context- > >target_bit_rate * 1000.0 * vdenc_context->framerate_den)) - x0) * > (y1 - y0) / (x1 - x0) + y0) + 0.5); > qp += 2; > - delat_qp = (int)(9 - (vdenc_context->vbv_buffer_size_in_bit * > ((float)vdenc_context->frames_per_100s) / > - ((float)(vdenc_context->target_bit_rate * > 1000) * 100))); > + delat_qp = (int)(9 - (vdenc_context->vbv_buffer_size_in_bit * > ((double)vdenc_context->framerate_num) / > + ((double)vdenc_context->target_bit_rate * > 1000.0 * vdenc_context->framerate_den))); > if (delat_qp > 0) > qp += delat_qp; > > @@ -1615,7 +1618,8 @@ > gen9_vdenc_update_huc_brc_init_dmem(VADriverContextP ctx, > double input_bits_per_frame, bps_ratio; > int i; > > - vdenc_context->brc_init_reset_input_bits_per_frame = > ((double)(vdenc_context->max_bit_rate * 1000) * 100) / vdenc_context- > >frames_per_100s; > + vdenc_context->brc_init_reset_input_bits_per_frame = > + ((double)vdenc_context->max_bit_rate * 1000.0 * > vdenc_context->framerate_den) / vdenc_context->framerate_num; > vdenc_context->brc_init_current_target_buf_full_in_bits = > vdenc_context->brc_init_reset_input_bits_per_frame; > vdenc_context->brc_target_size = vdenc_context- > >init_vbv_buffer_fullness_in_bit; > > @@ -1645,8 +1649,8 @@ > gen9_vdenc_update_huc_brc_init_dmem(VADriverContextP ctx, > else if (vdenc_context->internal_rate_mode == I965_BRC_VBR) > dmem->brc_flag |= 0x20; > > - dmem->frame_rate_m = vdenc_context->frames_per_100s; > - dmem->frame_rate_d = 100; > + dmem->frame_rate_m = vdenc_context->framerate_num; > + dmem->frame_rate_d = vdenc_context->framerate_den; > > dmem->profile_level_max_frame = > gen9_vdenc_get_profile_level_max_frame(ctx, encoder_context, > seq_param->level_idc); > > @@ -1656,8 +1660,9 @@ > gen9_vdenc_update_huc_brc_init_dmem(VADriverContextP ctx, > dmem->min_qp = 10; > dmem->max_qp = 51; > > - input_bits_per_frame = ((double)vdenc_context->max_bit_rate * > 1000 * 100) / vdenc_context->frames_per_100s; > - bps_ratio = input_bits_per_frame / ((double)vdenc_context- > >vbv_buffer_size_in_bit * 100 / vdenc_context->frames_per_100s); > + input_bits_per_frame = ((double)vdenc_context->max_bit_rate * > 1000 * vdenc_context->framerate_den) / vdenc_context->framerate_num; > + bps_ratio = input_bits_per_frame / > + ((double)vdenc_context->vbv_buffer_size_in_bit * > vdenc_context->framerate_den / vdenc_context->framerate_num); > > if (bps_ratio < 0.1) > bps_ratio = 0.1; > diff --git a/src/gen9_vdenc.h b/src/gen9_vdenc.h > index e790497..5b80a4a 100644 > --- a/src/gen9_vdenc.h > +++ b/src/gen9_vdenc.h > @@ -741,7 +741,8 @@ struct gen9_vdenc_context > uint32_t min_bit_rate; /* in kbps */ > uint64_t init_vbv_buffer_fullness_in_bit; > uint64_t vbv_buffer_size_in_bit; > - uint32_t frames_per_100s; > + uint32_t framerate_num; > + uint32_t framerate_den; > uint32_t gop_size; > uint32_t ref_dist; > uint32_t brc_target_size; > diff --git a/src/i965_encoder.c b/src/i965_encoder.c > index d874322..75a6a1f 100644 > --- a/src/i965_encoder.c > +++ b/src/i965_encoder.c > @@ -42,6 +42,18 @@ > > #include "i965_post_processing.h" > > +static void > +reduce_fraction(unsigned int *num, unsigned int *den) > +{ > + unsigned int a = *num, b = *den, c; > + while (c = a % b) { > + a = b; > + b = c; > + } > + *num /= b; > + *den /= b; > +} > + > static VAStatus > clear_border(struct object_surface *obj_surface) > { > @@ -307,7 +319,7 @@ > intel_encoder_check_brc_h264_sequence_parameter(VADriverContextP ctx, > { > VAEncSequenceParameterBufferH264 *seq_param = > (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext- > >buffer; > unsigned short num_pframes_in_gop, num_bframes_in_gop; > - unsigned int bits_per_second, framerate_per_100s; > + unsigned int bits_per_second, framerate_num, framerate_den; > > if (!encoder_context->is_new_sequence) > return VA_STATUS_SUCCESS; > @@ -315,10 +327,15 @@ > intel_encoder_check_brc_h264_sequence_parameter(VADriverContextP ctx, > assert(seq_param); > bits_per_second = seq_param->bits_per_second; // for the highest > layer > > - if (!seq_param->num_units_in_tick || !seq_param->time_scale) > - framerate_per_100s = 3000; > - else > - framerate_per_100s = seq_param->time_scale * 100 / (2 * > seq_param->num_units_in_tick); // for the highest layer > + if (!seq_param->num_units_in_tick || !seq_param->time_scale) { > + framerate_num = 30; > + framerate_den = 1; > + } else { > + // for the highest layer > + framerate_num = seq_param->time_scale; > + framerate_den = 2 * seq_param->num_units_in_tick; > + } > + reduce_fraction(&framerate_num, &framerate_den); > > encoder_context->brc.num_iframes_in_gop = 1; // Always 1 > > @@ -326,7 +343,7 @@ > intel_encoder_check_brc_h264_sequence_parameter(VADriverContextP ctx, > if (seq_param->ip_period == 0) > goto error; > > - encoder_context->brc.gop_size = (unsigned > int)(framerate_per_100s / 100.0 + 0.5); // fake > + encoder_context->brc.gop_size = (framerate_num + > framerate_den - 1) / framerate_den; // fake > num_pframes_in_gop = (encoder_context->brc.gop_size + > seq_param->ip_period - 1) / seq_param- > >ip_period - 1; > } else if (seq_param->intra_period == 1) { // E.g. IDRIII... > @@ -347,11 +364,13 @@ > intel_encoder_check_brc_h264_sequence_parameter(VADriverContextP ctx, > if (num_pframes_in_gop != encoder_context- > >brc.num_pframes_in_gop || > num_bframes_in_gop != encoder_context- > >brc.num_bframes_in_gop || > bits_per_second != encoder_context- > >brc.bits_per_second[encoder_context->layer.num_layers - 1] || > - framerate_per_100s != encoder_context- > >brc.framerate_per_100s[encoder_context->layer.num_layers - 1]) { > + framerate_num != encoder_context- > >brc.framerate_num[encoder_context->layer.num_layers - 1] || > + framerate_den != encoder_context- > >brc.framerate_den[encoder_context->layer.num_layers - 1]) { > 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.bits_per_second[encoder_context- > >layer.num_layers - 1] = bits_per_second; > - encoder_context->brc.framerate_per_100s[encoder_context- > >layer.num_layers - 1] = framerate_per_100s; > + encoder_context->brc.framerate_num[encoder_context- > >layer.num_layers - 1] = framerate_num; > + encoder_context->brc.framerate_den[encoder_context- > >layer.num_layers - 1] = framerate_den; > encoder_context->brc.need_reset = 1; > } > > @@ -392,8 +411,10 @@ > intel_encoder_check_brc_vp8_sequence_parameter(VADriverContextP ctx, > num_pframes_in_gop = encoder_context->brc.gop_size - 1; > bits_per_second = seq_param->bits_per_second; // for the > highest layer > > - if (!encoder_context->brc.framerate_per_100s[encoder_context- > >layer.num_layers - 1]) { > - encoder_context->brc.framerate_per_100s[encoder_context- > >layer.num_layers - 1] = 3000; // for the highest layer > + if (!encoder_context->brc.framerate_num[encoder_context- > >layer.num_layers - 1]) { > + // for the highest layer > + encoder_context->brc.framerate_num[encoder_context- > >layer.num_layers - 1] = 30; > + encoder_context->brc.framerate_den[encoder_context- > >layer.num_layers - 1] = 1; > encoder_context->brc.need_reset = 1; > } > > @@ -480,7 +501,7 @@ > intel_encoder_check_framerate_parameter(VADriverContextP ctx, > struct intel_encoder_context > *encoder_context, > VAEncMiscParameterFrameRate > *misc) > { > - int framerate_per_100s; > + unsigned int framerate_num, framerate_den; > int temporal_id = 0; > > if (encoder_context->layer.num_layers >= 2) > @@ -489,13 +510,19 @@ > intel_encoder_check_framerate_parameter(VADriverContextP ctx, > if (temporal_id >= encoder_context->layer.num_layers) > return; > > - if (misc->framerate & 0xffff0000) > - framerate_per_100s = (misc->framerate & 0xffff) * 100 / > ((misc->framerate >> 16) & 0xffff); > - else > - framerate_per_100s = misc->framerate * 100; > + if (misc->framerate & 0xffff0000) { > + framerate_num = misc->framerate >> 16 & 0xffff; > + framerate_den = misc->framerate & 0xffff; > + } else { > + framerate_num = misc->framerate; > + framerate_den = 1; > + } > + reduce_fraction(&framerate_num, &framerate_den); > > - if (encoder_context->brc.framerate_per_100s[temporal_id] != > framerate_per_100s) { > - encoder_context->brc.framerate_per_100s[temporal_id] = > framerate_per_100s; > + if (encoder_context->brc.framerate_num[temporal_id] != > framerate_num || > + encoder_context->brc.framerate_den[temporal_id] != > framerate_den) { > + encoder_context->brc.framerate_num[temporal_id] = > framerate_num; > + encoder_context->brc.framerate_den[temporal_id] = > framerate_den; > encoder_context->brc.need_reset = 1; > } > } > diff --git a/src/i965_encoder.h b/src/i965_encoder.h > index 0b636d6..4547849 100644 > --- a/src/i965_encoder.h > +++ b/src/i965_encoder.h > @@ -80,7 +80,8 @@ struct intel_encoder_context > unsigned short num_pframes_in_gop; > unsigned short num_bframes_in_gop; > unsigned int bits_per_second[MAX_TEMPORAL_LAYERS]; > - unsigned int framerate_per_100s[MAX_TEMPORAL_LAYERS]; > + unsigned int framerate_num[MAX_TEMPORAL_LAYERS]; > + unsigned int framerate_den[MAX_TEMPORAL_LAYERS]; > unsigned int mb_rate_control[MAX_TEMPORAL_LAYERS]; > unsigned int target_percentage[MAX_TEMPORAL_LAYERS]; > unsigned int hrd_buffer_size; _______________________________________________ Libva mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libva
