| @@ -2110,12 +2110,13 @@ typedef struct AVCodecContext { | |||||
| int rc_override_count; | int rc_override_count; | ||||
| RcOverride *rc_override; | 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; | const char *rc_eq; | ||||
| #endif | |||||
| /** | /** | ||||
| * maximum bitrate | * maximum bitrate | ||||
| @@ -638,6 +638,8 @@ typedef struct MpegEncContext { | |||||
| float rc_qmod_amp; | float rc_qmod_amp; | ||||
| int rc_qmod_freq; | int rc_qmod_freq; | ||||
| char *rc_eq; | |||||
| /* temp buffers for rate control */ | /* temp buffers for rate control */ | ||||
| float *cplx_tab, *bits_tab; | 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)", \ | {"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}, \ | 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_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[]; | extern const AVOption ff_mpv_generic_options[]; | ||||
| @@ -830,6 +830,13 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx) | |||||
| s->rc_qmod_amp = avctx->rc_qmod_amp; | s->rc_qmod_amp = avctx->rc_qmod_amp; | ||||
| if (avctx->rc_qmod_freq) | if (avctx->rc_qmod_freq) | ||||
| s->rc_qmod_freq = 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 | FF_ENABLE_DEPRECATION_WARNINGS | ||||
| #endif | #endif | ||||
| @@ -27,6 +27,7 @@ | |||||
| #include "avcodec.h" | #include "avcodec.h" | ||||
| #include "internal.h" | #include "internal.h" | ||||
| #include "libavutil/avassert.h" | #include "libavutil/avassert.h" | ||||
| #include "libavutil/internal.h" | |||||
| #include "libavutil/mem.h" | #include "libavutil/mem.h" | ||||
| #include "libavutil/opt.h" | #include "libavutil/opt.h" | ||||
| #include <float.h> /* FLT_MIN, FLT_MAX */ | #include <float.h> /* FLT_MIN, FLT_MAX */ | ||||
| @@ -174,17 +175,21 @@ int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src) | |||||
| dest->internal = NULL; | dest->internal = NULL; | ||||
| /* reallocate values that should be allocated separately */ | /* reallocate values that should be allocated separately */ | ||||
| dest->rc_eq = NULL; | |||||
| dest->extradata = NULL; | dest->extradata = NULL; | ||||
| dest->intra_matrix = NULL; | dest->intra_matrix = NULL; | ||||
| dest->inter_matrix = NULL; | dest->inter_matrix = NULL; | ||||
| dest->rc_override = NULL; | dest->rc_override = NULL; | ||||
| dest->subtitle_header = NULL; | dest->subtitle_header = NULL; | ||||
| #if FF_API_MPV_OPT | |||||
| FF_DISABLE_DEPRECATION_WARNINGS | |||||
| dest->rc_eq = NULL; | |||||
| if (src->rc_eq) { | if (src->rc_eq) { | ||||
| dest->rc_eq = av_strdup(src->rc_eq); | dest->rc_eq = av_strdup(src->rc_eq); | ||||
| if (!dest->rc_eq) | if (!dest->rc_eq) | ||||
| return AVERROR(ENOMEM); | return AVERROR(ENOMEM); | ||||
| } | } | ||||
| FF_ENABLE_DEPRECATION_WARNINGS | |||||
| #endif | |||||
| #define alloc_and_copy_or_fail(obj, size, pad) \ | #define alloc_and_copy_or_fail(obj, size, pad) \ | ||||
| if (src->obj && size > 0) { \ | if (src->obj && size > 0) { \ | ||||
| @@ -211,7 +216,11 @@ fail: | |||||
| av_freep(&dest->intra_matrix); | av_freep(&dest->intra_matrix); | ||||
| av_freep(&dest->inter_matrix); | av_freep(&dest->inter_matrix); | ||||
| av_freep(&dest->extradata); | av_freep(&dest->extradata); | ||||
| #if FF_API_MPV_OPT | |||||
| FF_DISABLE_DEPRECATION_WARNINGS | |||||
| av_freep(&dest->rc_eq); | av_freep(&dest->rc_eq); | ||||
| FF_ENABLE_DEPRECATION_WARNINGS | |||||
| #endif | |||||
| return AVERROR(ENOMEM); | return AVERROR(ENOMEM); | ||||
| } | } | ||||
| @@ -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}, | {"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 | #endif | ||||
| {"rc_override_count", NULL, OFFSET(rc_override_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, | {"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}, | {"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.", | {"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}, | OFFSET(rc_min_rate), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|A|E}, | ||||
| @@ -126,11 +126,11 @@ av_cold int ff_rate_control_init(MpegEncContext *s) | |||||
| emms_c(); | emms_c(); | ||||
| res = av_expr_parse(&rcc->rc_eq_eval, | 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, | const_names, func1_names, func1, | ||||
| NULL, NULL, 0, s->avctx); | NULL, NULL, 0, s->avctx); | ||||
| if (res < 0) { | 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; | 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); | bits = av_expr_eval(rcc->rc_eq_eval, const_values, rce); | ||||
| if (isnan(bits)) { | 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; | return -1; | ||||
| } | } | ||||