diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index c025c5c3dc..bd1a0e53cb 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -2110,12 +2110,13 @@ typedef struct AVCodecContext { int rc_override_count; RcOverride *rc_override; +#if FF_API_MPV_OPT /** - * rate control equation - * - encoding: Set by user - * - decoding: unused + * @deprecated use encoder private options instead */ + attribute_deprecated const char *rc_eq; +#endif /** * maximum bitrate diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h index e96671be14..1b72960e49 100644 --- a/libavcodec/mpegvideo.h +++ b/libavcodec/mpegvideo.h @@ -638,6 +638,8 @@ typedef struct MpegEncContext { float rc_qmod_amp; int rc_qmod_freq; + char *rc_eq; + /* temp buffers for rate control */ float *cplx_tab, *bits_tab; @@ -686,7 +688,12 @@ typedef struct MpegEncContext { {"qsquish", "how to keep quantizer between qmin and qmax (0 = clip, 1 = use differentiable function)", \ FF_MPV_OFFSET(rc_qsquish), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, 0, 99, FF_MPV_OPT_FLAGS}, \ {"rc_qmod_amp", "experimental quantizer modulation", FF_MPV_OFFSET(rc_qmod_amp), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS}, \ -{"rc_qmod_freq", "experimental quantizer modulation", FF_MPV_OFFSET(rc_qmod_freq), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS}, +{"rc_qmod_freq", "experimental quantizer modulation", FF_MPV_OFFSET(rc_qmod_freq), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS}, \ +{"rc_eq", "Set rate control equation. When computing the expression, besides the standard functions " \ + "defined in the section 'Expression Evaluation', the following functions are available: " \ + "bits2qp(bits), qp2bits(qp). Also the following constants are available: iTex pTex tex mv " \ + "fCode iCount mcVar var isI isP isB avgQP qComp avgIITex avgPITex avgPPTex avgBPTex avgTex.", \ + FF_MPV_OFFSET(rc_eq), AV_OPT_TYPE_STRING, .flags = FF_MPV_OPT_FLAGS }, extern const AVOption ff_mpv_generic_options[]; diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index 952a34a8c3..2a25545869 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -830,6 +830,13 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx) s->rc_qmod_amp = avctx->rc_qmod_amp; if (avctx->rc_qmod_freq) s->rc_qmod_freq = avctx->rc_qmod_freq; + + if (avctx->rc_eq) { + av_freep(&s->rc_eq); + s->rc_eq = av_strdup(avctx->rc_eq); + if (!s->rc_eq) + return AVERROR(ENOMEM); + } FF_ENABLE_DEPRECATION_WARNINGS #endif diff --git a/libavcodec/options.c b/libavcodec/options.c index 3acf3afdf0..c00dca078e 100644 --- a/libavcodec/options.c +++ b/libavcodec/options.c @@ -27,6 +27,7 @@ #include "avcodec.h" #include "internal.h" #include "libavutil/avassert.h" +#include "libavutil/internal.h" #include "libavutil/mem.h" #include "libavutil/opt.h" #include /* FLT_MIN, FLT_MAX */ @@ -174,17 +175,21 @@ int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src) dest->internal = NULL; /* reallocate values that should be allocated separately */ - dest->rc_eq = NULL; dest->extradata = NULL; dest->intra_matrix = NULL; dest->inter_matrix = NULL; dest->rc_override = NULL; dest->subtitle_header = NULL; +#if FF_API_MPV_OPT + FF_DISABLE_DEPRECATION_WARNINGS + dest->rc_eq = NULL; if (src->rc_eq) { dest->rc_eq = av_strdup(src->rc_eq); if (!dest->rc_eq) return AVERROR(ENOMEM); } + FF_ENABLE_DEPRECATION_WARNINGS +#endif #define alloc_and_copy_or_fail(obj, size, pad) \ if (src->obj && size > 0) { \ @@ -211,7 +216,11 @@ fail: av_freep(&dest->intra_matrix); av_freep(&dest->inter_matrix); av_freep(&dest->extradata); +#if FF_API_MPV_OPT + FF_DISABLE_DEPRECATION_WARNINGS av_freep(&dest->rc_eq); + FF_ENABLE_DEPRECATION_WARNINGS +#endif return AVERROR(ENOMEM); } diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h index ef89e7a8cd..bf33f9ae8f 100644 --- a/libavcodec/options_table.h +++ b/libavcodec/options_table.h @@ -169,11 +169,9 @@ static const AVOption avcodec_options[] = { {"rc_qmod_freq", "deprecated, use encoder private options instead", OFFSET(rc_qmod_freq), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, #endif {"rc_override_count", NULL, OFFSET(rc_override_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, -{"rc_eq", "Set rate control equation. When computing the expression, besides the standard functions " - "defined in the section 'Expression Evaluation', the following functions are available: " - "bits2qp(bits), qp2bits(qp). Also the following constants are available: iTex pTex tex mv " - "fCode iCount mcVar var isI isP isB avgQP qComp avgIITex avgPITex avgPPTex avgBPTex avgTex.", - OFFSET(rc_eq), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, V|E}, +#if FF_API_MPV_OPT +{"rc_eq", "deprecated, use encoder private options instead", OFFSET(rc_eq), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, V|E}, +#endif {"maxrate", "Set maximum bitrate tolerance (in bits/s). Requires bufsize to be set.", OFFSET(rc_max_rate), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|A|E}, {"minrate", "Set minimum bitrate tolerance (in bits/s). Most useful in setting up a CBR encode. It is of little use otherwise.", OFFSET(rc_min_rate), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|A|E}, diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c index 92438b46f0..3aa3e27602 100644 --- a/libavcodec/ratecontrol.c +++ b/libavcodec/ratecontrol.c @@ -126,11 +126,11 @@ av_cold int ff_rate_control_init(MpegEncContext *s) emms_c(); res = av_expr_parse(&rcc->rc_eq_eval, - s->avctx->rc_eq ? s->avctx->rc_eq : "tex^qComp", + s->rc_eq ? s->rc_eq : "tex^qComp", const_names, func1_names, func1, NULL, NULL, 0, s->avctx); if (res < 0) { - av_log(s->avctx, AV_LOG_ERROR, "Error parsing rc_eq \"%s\"\n", s->avctx->rc_eq); + av_log(s->avctx, AV_LOG_ERROR, "Error parsing rc_eq \"%s\"\n", s->rc_eq); return res; } @@ -382,7 +382,7 @@ static double get_qscale(MpegEncContext *s, RateControlEntry *rce, bits = av_expr_eval(rcc->rc_eq_eval, const_values, rce); if (isnan(bits)) { - av_log(s->avctx, AV_LOG_ERROR, "Error evaluating rc_eq \"%s\"\n", s->avctx->rc_eq); + av_log(s->avctx, AV_LOG_ERROR, "Error evaluating rc_eq \"%s\"\n", s->rc_eq); return -1; }