[FFmpeg-devel,v2] avfilter/f_realtime: add option to scale speed

Submitted by Moritz Barsnick on May 1, 2019, 2:12 p.m.

Details

Message ID 20190501141259.24297-1-barsnick@gmx.net
State New
Headers show

Commit Message

Moritz Barsnick May 1, 2019, 2:12 p.m.
---
 doc/filters.texi         | 8 ++++++++
 libavfilter/f_realtime.c | 7 +++++--
 2 files changed, 13 insertions(+), 2 deletions(-)

--
2.14.5

Comments

Nicolas George May 2, 2019, 9:29 a.m.
Moritz Barsnick (12019-05-01):
> ---
>  doc/filters.texi         | 8 ++++++++
>  libavfilter/f_realtime.c | 7 +++++--
>  2 files changed, 13 insertions(+), 2 deletions(-)

LGTM.

Regards,
Paul B Mahol May 4, 2019, 2:19 p.m.
On 5/1/19, Moritz Barsnick <barsnick@gmx.net> wrote:
> ---
>  doc/filters.texi         | 8 ++++++++
>  libavfilter/f_realtime.c | 7 +++++--
>  2 files changed, 13 insertions(+), 2 deletions(-)
>
> diff --git a/doc/filters.texi b/doc/filters.texi
> index cd82869849..2f9333c3f3 100644
> --- a/doc/filters.texi
> +++ b/doc/filters.texi
> @@ -21136,6 +21136,14 @@ They accept the following options:
>  @item limit
>  Time limit for the pauses. Any pause longer than that will be considered
>  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
>
>  @anchor{select}
> diff --git a/libavfilter/f_realtime.c b/libavfilter/f_realtime.c
> index 171c16aaaa..6fd3559dac 100644
> --- a/libavfilter/f_realtime.c
> +++ b/libavfilter/f_realtime.c
> @@ -22,11 +22,13 @@
>  #include "libavutil/time.h"
>  #include "avfilter.h"
>  #include "internal.h"
> +#include <float.h>
>
>  typedef struct RealtimeContext {
>      const AVClass *class;
>      int64_t delta;
>      int64_t limit;
> +    double speed;
>      unsigned inited;
>  } RealtimeContext;
>
> @@ -36,7 +38,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame
> *frame)
>      RealtimeContext *s = ctx->priv;
>
>      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 sleep = pts - now + s->delta;
>          if (!s->inited) {
> @@ -44,7 +46,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame
> *frame)
>              sleep = 0;
>              s->delta = now - pts;
>          }
> -        if (sleep > s->limit || sleep < -s->limit) {
> +        if (FFABS(sleep) > s->limit / s->speed) {
>              av_log(ctx, AV_LOG_WARNING,
>                     "time discontinuity detected: %"PRIi64" us,
> resetting\n",
>                     sleep);
> @@ -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
>  static const AVOption options[] = {
>      { "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 },

Why is this allowed to be negative?

>      { NULL }
>  };
>
> --
> 2.14.5
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
Moritz Barsnick May 4, 2019, 2:53 p.m.
On Sat, May 04, 2019 at 16:19:13 +0200, Paul B Mahol wrote:
> > +    { "speed", "speed factor", OFFSET(speed), AV_OPT_TYPE_DOUBLE, { .dbl =
> > 1.0 }, DBL_MIN, DBL_MAX, FLAGS },
>
> Why is this allowed to be negative?

In my reading (and intent), it's forbidden to be negative. Both min and
max are macros representing positives.

I don't own a standard, but web sources tell me DBL_MIN is the
"minimum, normalized, positive value of [type] double", e.g.
https://en.cppreference.com/w/c/types/limits

Moritz
Paul B Mahol May 4, 2019, 3:08 p.m.
On 5/4/19, Moritz Barsnick <barsnick@gmx.net> wrote:
> On Sat, May 04, 2019 at 16:19:13 +0200, Paul B Mahol wrote:
>> > +    { "speed", "speed factor", OFFSET(speed), AV_OPT_TYPE_DOUBLE, {
>> > .dbl =
>> > 1.0 }, DBL_MIN, DBL_MAX, FLAGS },
>>
>> Why is this allowed to be negative?
>
> In my reading (and intent), it's forbidden to be negative. Both min and
> max are macros representing positives.
>
> I don't own a standard, but web sources tell me DBL_MIN is the
> "minimum, normalized, positive value of [type] double", e.g.
> https://en.cppreference.com/w/c/types/limits
>

Thanks, will apply soon.

Patch hide | download patch | download mbox

diff --git a/doc/filters.texi b/doc/filters.texi
index cd82869849..2f9333c3f3 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -21136,6 +21136,14 @@  They accept the following options:
 @item limit
 Time limit for the pauses. Any pause longer than that will be considered
 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

 @anchor{select}
diff --git a/libavfilter/f_realtime.c b/libavfilter/f_realtime.c
index 171c16aaaa..6fd3559dac 100644
--- a/libavfilter/f_realtime.c
+++ b/libavfilter/f_realtime.c
@@ -22,11 +22,13 @@ 
 #include "libavutil/time.h"
 #include "avfilter.h"
 #include "internal.h"
+#include <float.h>

 typedef struct RealtimeContext {
     const AVClass *class;
     int64_t delta;
     int64_t limit;
+    double speed;
     unsigned inited;
 } RealtimeContext;

@@ -36,7 +38,7 @@  static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
     RealtimeContext *s = ctx->priv;

     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 sleep = pts - now + s->delta;
         if (!s->inited) {
@@ -44,7 +46,7 @@  static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
             sleep = 0;
             s->delta = now - pts;
         }
-        if (sleep > s->limit || sleep < -s->limit) {
+        if (FFABS(sleep) > s->limit / s->speed) {
             av_log(ctx, AV_LOG_WARNING,
                    "time discontinuity detected: %"PRIi64" us, resetting\n",
                    sleep);
@@ -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
 static const AVOption options[] = {
     { "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 }
 };