Open 21pages opened 2 years ago
The doc says that it supports dynamic change of bitrate,
I added the following code to ffmpeg qsvenc, and call it at the top of ff_qsv_encode, but check_enc_param failed, and bitrate change can't effect.
qsvenc
check_enc_param
static int reconfig_encoder(AVCodecContext *avctx, QSVEncContext *q) { if (q->av_bitrate != avctx->bit_rate) { float quant; int target_bitrate_kbps, max_bitrate_kbps, brc_param_multiplier; int buffer_size_in_kilobytes, initial_delay_in_kilobytes; AVCPBProperties *cpb_props; av_log(avctx, AV_LOG_INFO, "change bitrate from %d to %d.\n", q->av_bitrate, avctx->bit_rate); q->av_bitrate = avctx->bit_rate; //libmfx BRC parameters are 16 bits thus maybe overflow, then BRCParamMultiplier is needed buffer_size_in_kilobytes = avctx->rc_buffer_size / 8000; initial_delay_in_kilobytes = avctx->rc_initial_buffer_occupancy / 8000; target_bitrate_kbps = avctx->bit_rate / 1000; max_bitrate_kbps = avctx->rc_max_rate / 1000; brc_param_multiplier = (FFMAX(FFMAX3(target_bitrate_kbps, max_bitrate_kbps, buffer_size_in_kilobytes), initial_delay_in_kilobytes) + 0x10000) / 0x10000; switch (q->param.mfx.RateControlMethod) { case MFX_RATECONTROL_CBR: case MFX_RATECONTROL_VBR: #if QSV_HAVE_LA if (q->extbrc) { q->extco2.LookAheadDepth = q->look_ahead_depth; } #endif #if QSV_HAVE_VCM case MFX_RATECONTROL_VCM: #endif #if QSV_HAVE_QVBR case MFX_RATECONTROL_QVBR: #endif q->param.mfx.BufferSizeInKB = buffer_size_in_kilobytes / brc_param_multiplier; q->param.mfx.InitialDelayInKB = initial_delay_in_kilobytes / brc_param_multiplier; q->param.mfx.TargetKbps = target_bitrate_kbps / brc_param_multiplier; q->param.mfx.MaxKbps = max_bitrate_kbps / brc_param_multiplier; q->param.mfx.BRCParamMultiplier = brc_param_multiplier; #if QSV_HAVE_QVBR if (q->param.mfx.RateControlMethod == MFX_RATECONTROL_QVBR) q->extco3.QVBRQuality = av_clip(avctx->global_quality, 0, 51); #endif break; case MFX_RATECONTROL_CQP: quant = avctx->global_quality / FF_QP2LAMBDA; q->param.mfx.QPI = av_clip(quant * fabs(avctx->i_quant_factor) + avctx->i_quant_offset, 0, 51); q->param.mfx.QPP = av_clip(quant, 0, 51); q->param.mfx.QPB = av_clip(quant * fabs(avctx->b_quant_factor) + avctx->b_quant_offset, 0, 51); break; #if QSV_HAVE_AVBR case MFX_RATECONTROL_AVBR: q->param.mfx.TargetKbps = target_bitrate_kbps / brc_param_multiplier; q->param.mfx.Convergence = q->avbr_convergence; q->param.mfx.Accuracy = q->avbr_accuracy; q->param.mfx.BRCParamMultiplier = brc_param_multiplier; break; #endif #if QSV_HAVE_LA case MFX_RATECONTROL_LA: q->param.mfx.TargetKbps = target_bitrate_kbps / brc_param_multiplier; q->extco2.LookAheadDepth = q->look_ahead_depth; q->param.mfx.BRCParamMultiplier = brc_param_multiplier; break; #if QSV_HAVE_ICQ case MFX_RATECONTROL_LA_ICQ: q->extco2.LookAheadDepth = q->look_ahead_depth; case MFX_RATECONTROL_ICQ: q->param.mfx.ICQQuality = av_clip(avctx->global_quality, 1, 51); break; #endif #endif } if (!check_enc_param(avctx,q)) { av_log(avctx, AV_LOG_ERROR, "some encoding parameters are not supported by the QSV " "runtime. Please double check the input parameters.\n"); // return AVERROR(ENOSYS); } cpb_props = (AVCPBProperties *)avctx->coded_side_data[avctx->nb_coded_side_data - 1].data; if (!cpb_props) return AVERROR(ENOMEM); cpb_props->max_bitrate = avctx->rc_max_rate; cpb_props->min_bitrate = avctx->rc_min_rate; cpb_props->avg_bitrate = avctx->bit_rate; cpb_props->buffer_size = avctx->rc_buffer_size; av_log(avctx, AV_LOG_INFO, "change bitrate ok.\n"); } return 0; }
The doc says that it supports dynamic change of bitrate,
I added the following code to ffmpeg
qsvenc
, and call it at the top of ff_qsv_encode, butcheck_enc_param
failed, and bitrate change can't effect.