[PATCH 2/9] Add a time_base field to AVFilterPad.

Stefano Sabatini stefano.sabatini-lala
Mon Sep 27 20:24:44 CEST 2010


This is required for allowing a filter to use a time base different
from AV_TIME_BASE_Q, as it was previously assumed.
---
 libavfilter/avfilter.c |   21 +++++++++++++++++++++
 libavfilter/avfilter.h |   15 ++++++++++++++-
 libavfilter/defaults.c |    1 +
 3 files changed, 36 insertions(+), 1 deletions(-)

diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index ea6f9fe..bbe8d78 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -23,6 +23,7 @@
 
 #include "libavcodec/audioconvert.c"
 #include "libavutil/pixdesc.h"
+#include "libavutil/rational.h"
 #include "libavcore/imgutils.h"
 #include "avfilter.h"
 #include "internal.h"
@@ -179,10 +180,20 @@ int avfilter_config_links(AVFilterContext *filter)
             if (config_link(link))
                 return -1;
 
+            if (link->srcpad->time_base.num == 0 && link->srcpad->time_base.den == 0) {
+                if (link->src->input_count)
+                    link->srcpad->time_base = link->src->input_pads[0].time_base;
+                else
+                    link->srcpad->time_base = AV_TIME_BASE_Q;
+            }
+
             if ((config_link = link->dstpad->config_props))
                 if (config_link(link))
                     return -1;
 
+            if (link->dstpad->time_base.num == 0 && link->dstpad->time_base.den == 0)
+                link->dstpad->time_base = link->srcpad->time_base;
+
             link->init_state = AVLINK_INIT;
         }
     }
@@ -315,6 +326,7 @@ void avfilter_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
 {
     void (*start_frame)(AVFilterLink *, AVFilterBufferRef *);
     AVFilterPad *dst = link->dstpad;
+    AVFilterPad *src = link->srcpad;
 
     FF_DPRINTF_START(NULL, start_frame); ff_dprintf_link(NULL, link, 0); dprintf(NULL, " "); ff_dprintf_ref(NULL, picref, 1);
 
@@ -336,6 +348,15 @@ void avfilter_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
     else
         link->cur_buf = picref;
 
+    if (av_cmp_q(dst->time_base, src->time_base)) {
+        int64_t av_unused pts1 = picref->pts;
+        link->cur_buf->pts = av_rescale_q(picref->pts, src->time_base, dst->time_base);
+        FF_DPRINTF_START(NULL, start_frame); ff_dprintf_link(NULL, link, 0);
+        dprintf(NULL, " Converting PTS tb1:%d/%d pts1:%"PRId64" -> tb2:%d/%d pts2:%"PRId64"\n",
+                src->time_base.num, src->time_base.den, pts1,
+                dst->time_base.num, dst->time_base.den, link->cur_buf->pts);
+    }
+
     start_frame(link, link->cur_buf);
 }
 
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index bb3312a..e4b0b3e 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -127,7 +127,14 @@ typedef struct AVFilterBufferRef {
     int linesize[8];            ///< number of bytes per line
     int format;                 ///< media format
 
-    int64_t pts;                ///< presentation timestamp in units of 1/AV_TIME_BASE
+    /**
+     * presentation timestamp. The time unit may change during
+     * filtering, as it is specified in the input and output pads of a
+     * link. The framework automatically rescale the timestamp when
+     * sending a picref through a link and the source and destination
+     * time units differ.
+     */
+    int64_t pts;
     int64_t pos;                ///< byte position in stream, -1 if unknown
 
     int perms;                  ///< permissions, see the AV_PERM_* flags
@@ -424,6 +431,12 @@ struct AVFilterPad {
      * and another value on error.
      */
     int (*config_props)(AVFilterLink *link);
+
+    /**
+     * Define the time base used by the PTS of the frames/samples
+     * which will pass through this link.
+     */
+    AVRational time_base;
 };
 
 /** default handler for start_frame() for video inputs */
diff --git a/libavfilter/defaults.c b/libavfilter/defaults.c
index cb9ed19..509bd8b 100644
--- a/libavfilter/defaults.c
+++ b/libavfilter/defaults.c
@@ -235,6 +235,7 @@ int avfilter_default_config_output_link(AVFilterLink *link)
         if (link->type == AVMEDIA_TYPE_VIDEO) {
             link->w = link->src->inputs[0]->w;
             link->h = link->src->inputs[0]->h;
+            link->srcpad->time_base = link->src->input_pads[0].time_base;
         } else if (link->type == AVMEDIA_TYPE_AUDIO) {
             link->channel_layout = link->src->inputs[0]->channel_layout;
             link->sample_rate    = link->src->inputs[0]->sample_rate;
-- 
1.7.1


--GvXjxJ+pjyke8COw--



More information about the ffmpeg-devel mailing list