History

avfilter/vf_fps: extend support for expressions

AV_OPT_TYPE_VIDEO_RATE AVOption types are parsed as expressions, but in a limited way. For example, name constants can only be parsed alone and not as part of a longer expression. This change allows usage like ffmpeg -i IN -vf fps="if(eq(source_fps\,film)\,ntsc_film\,source_fps)" OUT

James Almer committed 5 years ago

Commit dd770881 parent 91ba7711 file · +60 −5Browse files

Showing the changes to libavfilter (1 of 1 file). Show all

Unified · Split

libavfilter/vf_fps.c+60−5
@@ -30,6 +30,7 @@ · 29 unmodified lines
3030 #include <stdint.h>
3131
3232 #include "libavutil/avassert.h"
33+#include "libavutil/eval.h"
3334 #include "libavutil/mathematics.h"
3435 #include "libavutil/opt.h"
3536 #include "avfilter.h"
@@ -42,12 +43,47 @@ enum EOFAction { · 6 unmodified lines
4243 EOF_ACTION_NB
4344 };
4445
46+static const char *const var_names[] = {
47+ "source_fps",
48+ "ntsc",
49+ "pal",
50+ "qntsc",
51+ "qpal",
52+ "sntsc",
53+ "spal",
54+ "film",
55+ "ntsc_film",
56+ NULL
57+};
58+
59+enum var_name {
60+ VAR_SOURCE_FPS,
61+ VAR_FPS_NTSC,
62+ VAR_FPS_PAL,
63+ VAR_FPS_QNTSC,
64+ VAR_FPS_QPAL,
65+ VAR_FPS_SNTSC,
66+ VAR_FPS_SPAL,
67+ VAR_FPS_FILM,
68+ VAR_FPS_NTSC_FILM,
69+ VARS_NB
70+};
71+
72+static const double ntsc_fps = 30000.0 / 1001.0;
73+static const double pal_fps = 25.0;
74+static const double qntsc_fps = 30000.0 / 1001.0;
75+static const double qpal_fps = 25.0;
76+static const double sntsc_fps = 30000.0 / 1001.0;
77+static const double spal_fps = 25.0;
78+static const double film_fps = 24.0;
79+static const double ntsc_film_fps = 24000.0 / 1001.0;
80+
4581 typedef struct FPSContext {
4682 const AVClass *class;
4783
4884 double start_time; ///< pts, in seconds, of the expected first frame
4985
50− AVRational framerate; ///< target framerate
86+ char *framerate; ///< expression that defines the target framerate
5187 int rounding; ///< AVRounding method for timestamps
5288 int eof_action; ///< action performed for last frame in FIFO
5389
@@ -76,7 +112,7 @@ typedef struct FPSContext { · 22 unmodified lines
76112 #define V AV_OPT_FLAG_VIDEO_PARAM
77113 #define F AV_OPT_FLAG_FILTERING_PARAM
78114 static const AVOption fps_options[] = {
79− { "fps", "A string describing desired output framerate", OFFSET(framerate), AV_OPT_TYPE_VIDEO_RATE, { .str = "25" }, 0, INT_MAX, V|F },
115+ { "fps", "A string describing desired output framerate", OFFSET(framerate), AV_OPT_TYPE_STRING, { .str = "25" }, 0, 0, V|F },
80116 { "start_time", "Assume the first PTS should be this value.", OFFSET(start_time), AV_OPT_TYPE_DOUBLE, { .dbl = DBL_MAX}, -DBL_MAX, DBL_MAX, V|F },
81117 { "round", "set rounding method for timestamps", OFFSET(rounding), AV_OPT_TYPE_INT, { .i64 = AV_ROUND_NEAR_INF }, 0, 5, V|F, "round" },
82118 { "zero", "round towards 0", 0, AV_OPT_TYPE_CONST, { .i64 = AV_ROUND_ZERO }, 0, 0, V|F, "round" },
@@ -99,7 +135,6 @@ static av_cold int init(AVFilterContext *ctx) · 16 unmodified lines
99135 s->status_pts = AV_NOPTS_VALUE;
100136 s->next_pts = AV_NOPTS_VALUE;
101137
102− av_log(ctx, AV_LOG_VERBOSE, "fps=%d/%d\n", s->framerate.num, s->framerate.den);
103138 return 0;
104139 }
105140
@@ -153,8 +188,26 @@ static int config_props(AVFilterLink* outlink) · 47 unmodified lines
153188 AVFilterLink *inlink = ctx->inputs[0];
154189 FPSContext *s = ctx->priv;
155190
156− outlink->time_base = av_inv_q(s->framerate);
157− outlink->frame_rate = s->framerate;
191+ double var_values[VARS_NB], res;
192+ int ret;
193+
194+ var_values[VAR_SOURCE_FPS] = av_q2d(inlink->frame_rate);
195+ var_values[VAR_FPS_NTSC] = ntsc_fps;
196+ var_values[VAR_FPS_PAL] = pal_fps;
197+ var_values[VAR_FPS_QNTSC] = qntsc_fps;
198+ var_values[VAR_FPS_QPAL] = qpal_fps;
199+ var_values[VAR_FPS_SNTSC] = sntsc_fps;
200+ var_values[VAR_FPS_SPAL] = spal_fps;
201+ var_values[VAR_FPS_FILM] = film_fps;
202+ var_values[VAR_FPS_NTSC_FILM] = ntsc_film_fps;
203+ ret = av_expr_parse_and_eval(&res, s->framerate,
204+ var_names, var_values,
205+ NULL, NULL, NULL, NULL, NULL, 0, ctx);
206+ if (ret < 0)
207+ return ret;
208+
209+ outlink->frame_rate = av_d2q(res, INT_MAX);
210+ outlink->time_base = av_inv_q(outlink->frame_rate);
158211
159212 /* Calculate the input and output pts offsets for start_time */
160213 if (s->start_time != DBL_MAX && s->start_time != AV_NOPTS_VALUE) {
@@ -173,6 +226,8 @@ static int config_props(AVFilterLink* outlink) · 12 unmodified lines
173226 s->in_pts_off, s->out_pts_off, s->start_time);
174227 }
175228
229+ av_log(ctx, AV_LOG_VERBOSE, "fps=%d/%d\n", outlink->frame_rate.num, outlink->frame_rate.den);
230+
176231 return 0;
177232 }
178233

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t