Skip to content
This repository has been archived by the owner on May 17, 2023. It is now read-only.

Dynamic change bitrate failed #2947

Open
21pages opened this issue Jun 11, 2022 · 0 comments
Open

Dynamic change bitrate failed #2947

21pages opened this issue Jun 11, 2022 · 0 comments

Comments

@21pages
Copy link

21pages commented Jun 11, 2022

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.

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;
}
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant