diff mbox series

[FFmpeg-devel,3/9] lavfi: use AVFrame.duration instead of AVFrame.pkt_duration

Message ID 20220713091725.16638-3-anton@khirnov.net
State Accepted
Commit 357ba45a5ca3864b0eba07747ab6ea1614f2646b
Headers show
Series [FFmpeg-devel,1/9] lavu/frame: add a duration field to AVFrame | expand

Checks

Context Check Description
andriy/configure_x86 warning Failed to apply patch

Commit Message

Anton Khirnov July 13, 2022, 9:17 a.m. UTC
---
 doc/filters.texi                |  2 +-
 libavfilter/buffersrc.c         |  7 +++++++
 libavfilter/f_loop.c            | 14 ++++++++++++++
 libavfilter/vf_deshake_opencl.c |  7 +++++++
 libavfilter/vf_drawtext.c       | 16 ++++++++++++++++
 5 files changed, 45 insertions(+), 1 deletion(-)

Comments

Nicolas George July 13, 2022, 3:02 p.m. UTC | #1
Anton Khirnov (12022-07-13):
> ---
>  doc/filters.texi                |  2 +-
>  libavfilter/buffersrc.c         |  7 +++++++
>  libavfilter/f_loop.c            | 14 ++++++++++++++
>  libavfilter/vf_deshake_opencl.c |  7 +++++++
>  libavfilter/vf_drawtext.c       | 16 ++++++++++++++++
>  5 files changed, 45 insertions(+), 1 deletion(-)

No objection from me.

But pkt_duration is mostly unused in libavfilter: the authoritative
information about a packet duration is given by the timestamp of the
next packet. What f_loop and vf_deshake_opencl currently do is slightly
bogus.

Regards,
Anton Khirnov July 14, 2022, 8:46 a.m. UTC | #2
Quoting Nicolas George (2022-07-13 17:02:04)
> Anton Khirnov (12022-07-13):
> > ---
> >  doc/filters.texi                |  2 +-
> >  libavfilter/buffersrc.c         |  7 +++++++
> >  libavfilter/f_loop.c            | 14 ++++++++++++++
> >  libavfilter/vf_deshake_opencl.c |  7 +++++++
> >  libavfilter/vf_drawtext.c       | 16 ++++++++++++++++
> >  5 files changed, 45 insertions(+), 1 deletion(-)
> 
> No objection from me.
> 
> But pkt_duration is mostly unused in libavfilter: the authoritative
> information about a packet duration is given by the timestamp of the
> next packet. What f_loop and vf_deshake_opencl currently do is slightly
> bogus.

I am aware.

Timestamp of the next packet requires you to have the next packet, which
means extra latency, so using durations is better. My plan for the
future is to handle durations in all filters that may modify timestamps,
so durations propagate through lavfi properly. Later on, some mechanism
could be added to automatically compute durations when they are not
available on input, so that filters may rely on the duration being
known and don't need to buffer frames themselves.
diff mbox series

Patch

diff --git a/doc/filters.texi b/doc/filters.texi
index 40f21fb34c..0e7beac63d 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -11842,7 +11842,7 @@  The current packet's position in the input file or stream
 (in bytes, from the start of the input). A value of -1 indicates
 this info is not available.
 
-@item pkt_duration
+@item duration
 The current packet's duration, in seconds.
 
 @item pkt_size
diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c
index a3190468bb..ae8bba19b0 100644
--- a/libavfilter/buffersrc.c
+++ b/libavfilter/buffersrc.c
@@ -243,6 +243,13 @@  FF_ENABLE_DEPRECATION_WARNINGS
         }
     }
 
+#if FF_API_PKT_DURATION
+FF_DISABLE_DEPRECATION_WARNINGS
+    if (copy->pkt_duration && copy->pkt_duration != copy->duration)
+        copy->duration = copy->pkt_duration;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
     ret = ff_filter_frame(ctx->outputs[0], copy);
     if (ret < 0)
         return ret;
diff --git a/libavfilter/f_loop.c b/libavfilter/f_loop.c
index 672aa4c8f7..d217efe2fd 100644
--- a/libavfilter/f_loop.c
+++ b/libavfilter/f_loop.c
@@ -331,9 +331,16 @@  static int push_frame(AVFilterContext *ctx)
     if (!out)
         return AVERROR(ENOMEM);
     out->pts += s->duration - s->start_pts;
+#if FF_API_PKT_DURATION
+FF_DISABLE_DEPRECATION_WARNINGS
     if (out->pkt_duration)
         duration = out->pkt_duration;
     else
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+    if (out->duration)
+        duration = out->duration;
+    else
         duration = av_rescale_q(1, av_inv_q(outlink->frame_rate), outlink->time_base);
     pts = out->pts + duration;
     ret = ff_filter_frame(outlink, out);
@@ -368,9 +375,16 @@  static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
                 return AVERROR(ENOMEM);
             }
             s->nb_frames++;
+#if FF_API_PKT_DURATION
+FF_DISABLE_DEPRECATION_WARNINGS
             if (frame->pkt_duration)
                 duration = frame->pkt_duration;
             else
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+            if (frame->duration)
+                duration = frame->duration;
+            else
                 duration = av_rescale_q(1, av_inv_q(outlink->frame_rate), outlink->time_base);
             s->duration = frame->pts + duration;
             ret = ff_filter_frame(outlink, frame);
diff --git a/libavfilter/vf_deshake_opencl.c b/libavfilter/vf_deshake_opencl.c
index c2b5bef897..d488da7fa0 100644
--- a/libavfilter/vf_deshake_opencl.c
+++ b/libavfilter/vf_deshake_opencl.c
@@ -1413,8 +1413,15 @@  static int filter_frame(AVFilterLink *link, AVFrame *input_frame)
             &debug_matches, 1);
     }
 
+#if FF_API_PKT_DURATION
+FF_DISABLE_DEPRECATION_WARNINGS
     if (input_frame->pkt_duration) {
         duration = input_frame->pkt_duration;
+    } else
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+    if (input_frame->duration) {
+        duration = input_frame->duration;
     } else {
         duration = av_rescale_q(1, av_inv_q(outlink->frame_rate), outlink->time_base);
     }
diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c
index feb6898848..50012bb258 100644
--- a/libavfilter/vf_drawtext.c
+++ b/libavfilter/vf_drawtext.c
@@ -91,8 +91,11 @@  static const char *const var_names[] = {
     "y",
     "pict_type",
     "pkt_pos",
+#if FF_API_PKT_DURATION
     "pkt_duration",
+#endif
     "pkt_size",
+    "duration",
     NULL
 };
 
@@ -131,8 +134,11 @@  enum var_name {
     VAR_Y,
     VAR_PICT_TYPE,
     VAR_PKT_POS,
+#if FF_API_PKT_DURATION
     VAR_PKT_DURATION,
+#endif
     VAR_PKT_SIZE,
+    VAR_DURATION,
     VAR_VARS_NB
 };
 
@@ -1649,8 +1655,18 @@  static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
 
     s->var_values[VAR_PICT_TYPE] = frame->pict_type;
     s->var_values[VAR_PKT_POS] = frame->pkt_pos;
+#if FF_API_PKT_DURATION
+FF_DISABLE_DEPRECATION_WARNINGS
     s->var_values[VAR_PKT_DURATION] = frame->pkt_duration * av_q2d(inlink->time_base);
+
+    if (frame->pkt_duration)
+        s->var_values[VAR_DURATION] = frame->pkt_duration * av_q2d(inlink->time_base);
+    else
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+    s->var_values[VAR_DURATION] = frame->duration * av_q2d(inlink->time_base);
     s->var_values[VAR_PKT_SIZE] = frame->pkt_size;
+
     s->metadata = frame->metadata;
 
     for (int i = 0; i < loop; i++) {