Commit 98541f70 authored by Moritz Barsnick's avatar Moritz Barsnick Committed by Paul B Mahol

avfilter/f_realtime: add option to scale speed

parent e94447cd
...@@ -21136,6 +21136,14 @@ They accept the following options: ...@@ -21136,6 +21136,14 @@ They accept the following options:
@item limit @item limit
Time limit for the pauses. Any pause longer than that will be considered Time limit for the pauses. Any pause longer than that will be considered
a timestamp discontinuity and reset the timer. Default is 2 seconds. a timestamp discontinuity and reset the timer. Default is 2 seconds.
@item speed
Speed factor for processing. The value must be a float larger than zero.
Values larger than 1.0 will result in faster than realtime processing,
smaller will slow processing down. The @var{limit} is automatically adapted
accordingly. Default is 1.0.
A processing speed faster than what is possible without these filters cannot
be achieved.
@end table @end table
@anchor{select} @anchor{select}
......
...@@ -22,11 +22,13 @@ ...@@ -22,11 +22,13 @@
#include "libavutil/time.h" #include "libavutil/time.h"
#include "avfilter.h" #include "avfilter.h"
#include "internal.h" #include "internal.h"
#include <float.h>
typedef struct RealtimeContext { typedef struct RealtimeContext {
const AVClass *class; const AVClass *class;
int64_t delta; int64_t delta;
int64_t limit; int64_t limit;
double speed;
unsigned inited; unsigned inited;
} RealtimeContext; } RealtimeContext;
...@@ -36,7 +38,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) ...@@ -36,7 +38,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
RealtimeContext *s = ctx->priv; RealtimeContext *s = ctx->priv;
if (frame->pts != AV_NOPTS_VALUE) { if (frame->pts != AV_NOPTS_VALUE) {
int64_t pts = av_rescale_q(frame->pts, inlink->time_base, AV_TIME_BASE_Q); int64_t pts = av_rescale_q(frame->pts, inlink->time_base, AV_TIME_BASE_Q) / s->speed;
int64_t now = av_gettime_relative(); int64_t now = av_gettime_relative();
int64_t sleep = pts - now + s->delta; int64_t sleep = pts - now + s->delta;
if (!s->inited) { if (!s->inited) {
...@@ -44,7 +46,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) ...@@ -44,7 +46,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
sleep = 0; sleep = 0;
s->delta = now - pts; s->delta = now - pts;
} }
if (sleep > s->limit || sleep < -s->limit) { if (FFABS(sleep) > s->limit / s->speed) {
av_log(ctx, AV_LOG_WARNING, av_log(ctx, AV_LOG_WARNING,
"time discontinuity detected: %"PRIi64" us, resetting\n", "time discontinuity detected: %"PRIi64" us, resetting\n",
sleep); sleep);
...@@ -65,6 +67,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) ...@@ -65,6 +67,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
static const AVOption options[] = { static const AVOption options[] = {
{ "limit", "sleep time limit", OFFSET(limit), AV_OPT_TYPE_DURATION, { .i64 = 2000000 }, 0, INT64_MAX, FLAGS }, { "limit", "sleep time limit", OFFSET(limit), AV_OPT_TYPE_DURATION, { .i64 = 2000000 }, 0, INT64_MAX, FLAGS },
{ "speed", "speed factor", OFFSET(speed), AV_OPT_TYPE_DOUBLE, { .dbl = 1.0 }, DBL_MIN, DBL_MAX, FLAGS },
{ NULL } { NULL }
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment