[FFmpeg-devel] [PATCH 1/5] lavfi: remplace passthrough_filter_frame with a flag.

Clément Bœsch ubitux at gmail.com
Sat May 11 22:48:02 CEST 2013


On Sat, May 11, 2013 at 04:50:36PM +0200, Stefano Sabatini wrote:
[...]
> This is my attempt. I just replaced "generic" with "default" since
> default_filter_frame() is used, "internal" may be replaced by "auto"
> or "automatic" but I'm not really satisfied with that as well, since
> the user may guess that this is "automatically" executed by the
> framework (rather than by the filter code).
> 
> Other alternatives to "generic":
> external framework default
> 
> Other alternatives to "internal":
> callback
> 
> 
> /**
>  * Some filters support a generic "enable" expression option that can be used
>  * to enable or disable a filter in the timeline. Filters supporting this
>  * option have this flag set. When the enable expression is false, the
>  * default no-op filter_frame() function is called in place of the
>  * filter_frame() callback defined on each input pad, thus the frame
>  * is passed unchanged to the next filters.
>  */
> #define AVFILTER_FLAG_SUPPORT_TIMELINE_DEFAULT   (1 << 16)
> 
> /**
>  * Same as AVFILTER_FLAG_SUPPORT_TIMELINE_DEFAULT, except that the filter will have its
>  * filter_frame() callback(s) called as usual even when the enable
>  * expression is false. The filter will disable filtering
>  * within the filter_frame() callback(s) itself, for example executing
>  * code depending on the AVFilterContext->is_disabled value.
>  */
> #define AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL     (1 << 17)
> 
> Note that at this point I'm not against keeping the original terms
> "generic" and "internal", but even in this case I suggest to specify
> the "variant" after "timeline", as in
> AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC.

Perfectly fine, thank you. New patch attached. I also added an assert to
make sure both default & internal are not set.

-- 
Clément B.
-------------- next part --------------
From 54c52c2ded283f30509c5da394f4de6d4b1f6b7d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= <ubitux at gmail.com>
Date: Thu, 9 May 2013 01:04:41 +0200
Subject: [PATCH 1/5] lavfi: replace passthrough_filter_frame with a flag.

With the introduction of AVFilterContext->is_disabled, we can simplify
the custom passthrough mode in filters.

This commit is technically a small compat break, but the timeline was
introduced very recently.

Doxy by Stefano Sabatini.
---
 libavfilter/af_apad.c              |  3 +--
 libavfilter/af_volume.c            |  2 +-
 libavfilter/avfilter.c             |  9 ++++++---
 libavfilter/avfilter.h             | 33 ++++++++++++++++++---------------
 libavfilter/vf_boxblur.c           |  2 +-
 libavfilter/vf_colorbalance.c      |  2 +-
 libavfilter/vf_colorchannelmixer.c |  2 +-
 libavfilter/vf_colormatrix.c       |  2 +-
 libavfilter/vf_cropdetect.c        |  2 +-
 libavfilter/vf_curves.c            |  2 +-
 libavfilter/vf_delogo.c            |  2 +-
 libavfilter/vf_drawbox.c           |  2 +-
 libavfilter/vf_edgedetect.c        |  2 +-
 libavfilter/vf_gradfun.c           |  2 +-
 libavfilter/vf_histeq.c            |  2 +-
 libavfilter/vf_hue.c               |  2 +-
 libavfilter/vf_lut.c               |  2 +-
 libavfilter/vf_noise.c             |  2 +-
 libavfilter/vf_overlay.c           | 25 ++++---------------------
 libavfilter/vf_pp.c                |  2 +-
 libavfilter/vf_removelogo.c        |  2 +-
 libavfilter/vf_smartblur.c         |  2 +-
 libavfilter/vf_unsharp.c           |  2 +-
 23 files changed, 48 insertions(+), 60 deletions(-)

diff --git a/libavfilter/af_apad.c b/libavfilter/af_apad.c
index 265b76a..710baaa 100644
--- a/libavfilter/af_apad.c
+++ b/libavfilter/af_apad.c
@@ -131,7 +131,6 @@ static const AVFilterPad apad_inputs[] = {
         .name         = "default",
         .type         = AVMEDIA_TYPE_AUDIO,
         .filter_frame = filter_frame,
-        .passthrough_filter_frame = filter_frame,
     },
     { NULL },
 };
@@ -153,5 +152,5 @@ AVFilter avfilter_af_apad = {
     .inputs        = apad_inputs,
     .outputs       = apad_outputs,
     .priv_class    = &apad_class,
-    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
diff --git a/libavfilter/af_volume.c b/libavfilter/af_volume.c
index b7aec8d..d9a5d4a 100644
--- a/libavfilter/af_volume.c
+++ b/libavfilter/af_volume.c
@@ -296,5 +296,5 @@ AVFilter avfilter_af_volume = {
     .init           = init,
     .inputs         = avfilter_af_volume_inputs,
     .outputs        = avfilter_af_volume_outputs,
-    .flags          = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags          = AVFILTER_FLAG_SUPPORT_TIMELINE_DEFAULT,
 };
diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index 2b95b65..2f30ad9 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -453,6 +453,9 @@ int avfilter_register(AVFilter *filter)
     AVFilter **f = &first_filter;
     int i;
 
+    /* the filter must select internal or default */
+    av_assert0((filter->flags & AVFILTER_FLAG_SUPPORT_TIMELINE) != AVFILTER_FLAG_SUPPORT_TIMELINE);
+
     for(i=0; filter->inputs && filter->inputs[i].name; i++) {
         const AVFilterPad *input = &filter->inputs[i];
         av_assert0(     !input->filter_frame
@@ -995,9 +998,9 @@ static int ff_filter_frame_framed(AVFilterLink *link, AVFrame *frame)
         dstctx->var_values[VAR_POS] = pos == -1 ? NAN : pos;
 
         dstctx->is_disabled = !av_expr_eval(dstctx->enable, dstctx->var_values, NULL);
-        if (dstctx->is_disabled)
-            filter_frame = dst->passthrough_filter_frame ? dst->passthrough_filter_frame
-                                                         : default_filter_frame;
+        if (dstctx->is_disabled &&
+            (dstctx->filter->flags & AVFILTER_FLAG_SUPPORT_TIMELINE_DEFAULT))
+            filter_frame = default_filter_frame;
     }
     ret = filter_frame(link, out);
     link->frame_count++;
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index a79c86c..fe0c3e0 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -385,19 +385,6 @@ struct AVFilterPad {
     int needs_fifo;
 
     int needs_writable;
-
-    /**
-     * Passthrough filtering callback.
-     *
-     * If a filter supports timeline editing (in case
-     * AVFILTER_FLAG_SUPPORT_TIMELINE is enabled) then it can implement a
-     * custom passthrough callback to update its local context (for example to
-     * keep a frame reference, or simply send the filter to a custom outlink).
-     * The filter must not do any change to the frame in this callback.
-     *
-     * Input pads only.
-     */
-    int (*passthrough_filter_frame)(AVFilterLink *link, AVFrame *frame);
 };
 #endif
 
@@ -444,9 +431,25 @@ enum AVMediaType avfilter_pad_get_type(const AVFilterPad *pads, int pad_idx);
 /**
  * Some filters support a generic "enable" expression option that can be used
  * to enable or disable a filter in the timeline. Filters supporting this
- * option have this flag set.
+ * option have this flag set. When the enable expression is false, the
+ * default no-op filter_frame() function is called in place of the
+ * filter_frame() callback defined on each input pad, thus the frame
+ * is passed unchanged to the next filters.
+ */
+#define AVFILTER_FLAG_SUPPORT_TIMELINE_DEFAULT  (1 << 16)
+/**
+ * Same as AVFILTER_FLAG_SUPPORT_TIMELINE_DEFAULT, except that the filter will have its
+ * filter_frame() callback(s) called as usual even when the enable
+ * expression is false. The filter will disable filtering
+ * within the filter_frame() callback(s) itself, for example executing
+ * code depending on the AVFilterContext->is_disabled value.
+ */
+#define AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL (1 << 17)
+/**
+ * Handy mask to test whether the filter supports or no the timeline feature
+ * (internally or generically).
  */
-#define AVFILTER_FLAG_SUPPORT_TIMELINE      (1 << 16)
+#define AVFILTER_FLAG_SUPPORT_TIMELINE (AVFILTER_FLAG_SUPPORT_TIMELINE_DEFAULT | AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL)
 
 /**
  * Filter definition. This defines the pads a filter contains, and all the
diff --git a/libavfilter/vf_boxblur.c b/libavfilter/vf_boxblur.c
index a8a2014..35564a6 100644
--- a/libavfilter/vf_boxblur.c
+++ b/libavfilter/vf_boxblur.c
@@ -383,5 +383,5 @@ AVFilter avfilter_vf_boxblur = {
 
     .inputs    = avfilter_vf_boxblur_inputs,
     .outputs   = avfilter_vf_boxblur_outputs,
-    .flags     = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags     = AVFILTER_FLAG_SUPPORT_TIMELINE_DEFAULT,
 };
diff --git a/libavfilter/vf_colorbalance.c b/libavfilter/vf_colorbalance.c
index b09d170..e72a037 100644
--- a/libavfilter/vf_colorbalance.c
+++ b/libavfilter/vf_colorbalance.c
@@ -209,5 +209,5 @@ AVFilter avfilter_vf_colorbalance = {
     .query_formats = query_formats,
     .inputs        = colorbalance_inputs,
     .outputs       = colorbalance_outputs,
-    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_DEFAULT,
 };
diff --git a/libavfilter/vf_colorchannelmixer.c b/libavfilter/vf_colorchannelmixer.c
index 343faac..08514a8 100644
--- a/libavfilter/vf_colorchannelmixer.c
+++ b/libavfilter/vf_colorchannelmixer.c
@@ -356,5 +356,5 @@ AVFilter avfilter_vf_colorchannelmixer = {
     .query_formats = query_formats,
     .inputs        = colorchannelmixer_inputs,
     .outputs       = colorchannelmixer_outputs,
-    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_DEFAULT,
 };
diff --git a/libavfilter/vf_colormatrix.c b/libavfilter/vf_colormatrix.c
index 8db5fcf..17dbcc2 100644
--- a/libavfilter/vf_colormatrix.c
+++ b/libavfilter/vf_colormatrix.c
@@ -385,5 +385,5 @@ AVFilter avfilter_vf_colormatrix = {
     .inputs        = colormatrix_inputs,
     .outputs       = colormatrix_outputs,
     .priv_class    = &colormatrix_class,
-    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_DEFAULT,
 };
diff --git a/libavfilter/vf_cropdetect.c b/libavfilter/vf_cropdetect.c
index cb170d0..d6eb71c 100644
--- a/libavfilter/vf_cropdetect.c
+++ b/libavfilter/vf_cropdetect.c
@@ -233,5 +233,5 @@ AVFilter avfilter_vf_cropdetect = {
     .query_formats = query_formats,
     .inputs    = avfilter_vf_cropdetect_inputs,
     .outputs   = avfilter_vf_cropdetect_outputs,
-    .flags     = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags     = AVFILTER_FLAG_SUPPORT_TIMELINE_DEFAULT,
 };
diff --git a/libavfilter/vf_curves.c b/libavfilter/vf_curves.c
index faa4d66..e0754b3 100644
--- a/libavfilter/vf_curves.c
+++ b/libavfilter/vf_curves.c
@@ -548,5 +548,5 @@ AVFilter avfilter_vf_curves = {
     .inputs        = curves_inputs,
     .outputs       = curves_outputs,
     .priv_class    = &curves_class,
-    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_DEFAULT,
 };
diff --git a/libavfilter/vf_delogo.c b/libavfilter/vf_delogo.c
index b644190..61aaa83 100644
--- a/libavfilter/vf_delogo.c
+++ b/libavfilter/vf_delogo.c
@@ -271,5 +271,5 @@ AVFilter avfilter_vf_delogo = {
 
     .inputs    = avfilter_vf_delogo_inputs,
     .outputs   = avfilter_vf_delogo_outputs,
-    .flags     = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags     = AVFILTER_FLAG_SUPPORT_TIMELINE_DEFAULT,
 };
diff --git a/libavfilter/vf_drawbox.c b/libavfilter/vf_drawbox.c
index c2ffbf3..e988c84 100644
--- a/libavfilter/vf_drawbox.c
+++ b/libavfilter/vf_drawbox.c
@@ -181,5 +181,5 @@ AVFilter avfilter_vf_drawbox = {
     .query_formats   = query_formats,
     .inputs    = avfilter_vf_drawbox_inputs,
     .outputs   = avfilter_vf_drawbox_outputs,
-    .flags     = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags     = AVFILTER_FLAG_SUPPORT_TIMELINE_DEFAULT,
 };
diff --git a/libavfilter/vf_edgedetect.c b/libavfilter/vf_edgedetect.c
index b4698a8..4bd098d 100644
--- a/libavfilter/vf_edgedetect.c
+++ b/libavfilter/vf_edgedetect.c
@@ -327,5 +327,5 @@ AVFilter avfilter_vf_edgedetect = {
     .inputs        = edgedetect_inputs,
     .outputs       = edgedetect_outputs,
     .priv_class    = &edgedetect_class,
-    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_DEFAULT,
 };
diff --git a/libavfilter/vf_gradfun.c b/libavfilter/vf_gradfun.c
index 52c67ff..da052db 100644
--- a/libavfilter/vf_gradfun.c
+++ b/libavfilter/vf_gradfun.c
@@ -260,5 +260,5 @@ AVFilter avfilter_vf_gradfun = {
     .query_formats = query_formats,
     .inputs        = avfilter_vf_gradfun_inputs,
     .outputs       = avfilter_vf_gradfun_outputs,
-    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_DEFAULT,
 };
diff --git a/libavfilter/vf_histeq.c b/libavfilter/vf_histeq.c
index a4166c6..d82df99 100644
--- a/libavfilter/vf_histeq.c
+++ b/libavfilter/vf_histeq.c
@@ -279,5 +279,5 @@ AVFilter avfilter_vf_histeq = {
     .inputs        = histeq_inputs,
     .outputs       = histeq_outputs,
     .priv_class    = &histeq_class,
-    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_DEFAULT,
 };
diff --git a/libavfilter/vf_hue.c b/libavfilter/vf_hue.c
index cba39d0..a0fd629 100644
--- a/libavfilter/vf_hue.c
+++ b/libavfilter/vf_hue.c
@@ -373,5 +373,5 @@ AVFilter avfilter_vf_hue = {
     .inputs          = hue_inputs,
     .outputs         = hue_outputs,
     .priv_class      = &hue_class,
-    .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_DEFAULT,
 };
diff --git a/libavfilter/vf_lut.c b/libavfilter/vf_lut.c
index d544419..edf44c9 100644
--- a/libavfilter/vf_lut.c
+++ b/libavfilter/vf_lut.c
@@ -353,7 +353,7 @@ static const AVFilterPad outputs[] = {
                                                                         \
         .inputs        = inputs,                                        \
         .outputs       = outputs,                                       \
-        .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE,                \
+        .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_DEFAULT,        \
     }
 
 #if CONFIG_LUT_FILTER
diff --git a/libavfilter/vf_noise.c b/libavfilter/vf_noise.c
index da418fe..74786e3 100644
--- a/libavfilter/vf_noise.c
+++ b/libavfilter/vf_noise.c
@@ -471,5 +471,5 @@ AVFilter avfilter_vf_noise = {
     .inputs        = noise_inputs,
     .outputs       = noise_outputs,
     .priv_class    = &noise_class,
-    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_DEFAULT,
 };
diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c
index 6494bad..ec58dc4 100644
--- a/libavfilter/vf_overlay.c
+++ b/libavfilter/vf_overlay.c
@@ -88,7 +88,6 @@ enum var_name {
 typedef struct {
     const AVClass *class;
     int x, y;                   ///< position of overlayed picture
-    int enable;                 ///< tells if blending is enabled
 
     int allow_packed_rgb;
     uint8_t frame_requested;
@@ -597,7 +596,7 @@ static int try_filter_frame(AVFilterContext *ctx, AVFrame *mainpic)
                    over->var_values[VAR_X], over->x,
                    over->var_values[VAR_Y], over->y);
         }
-        if (over->enable)
+        if (!ctx->is_disabled)
             blend_image(ctx, mainpic, over->overpicref, over->x, over->y);
 
     }
@@ -663,20 +662,6 @@ static int filter_frame_over(AVFilterLink *inlink, AVFrame *inpicref)
     return ret == AVERROR(EAGAIN) ? 0 : ret;
 }
 
-#define DEF_FILTER_FRAME(name, mode, enable_value)                              \
-static int filter_frame_##name##_##mode(AVFilterLink *inlink, AVFrame *frame)   \
-{                                                                               \
-    AVFilterContext *ctx = inlink->dst;                                         \
-    OverlayContext *over = ctx->priv;                                           \
-    over->enable = enable_value;                                                \
-    return filter_frame_##name(inlink, frame);                                  \
-}
-
-DEF_FILTER_FRAME(main, enabled,  1);
-DEF_FILTER_FRAME(main, disabled, 0);
-DEF_FILTER_FRAME(over, enabled,  1);
-DEF_FILTER_FRAME(over, disabled, 0);
-
 static int request_frame(AVFilterLink *outlink)
 {
     AVFilterContext *ctx = outlink->src;
@@ -734,16 +719,14 @@ static const AVFilterPad avfilter_vf_overlay_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .get_video_buffer = ff_null_get_video_buffer,
         .config_props = config_input_main,
-        .filter_frame             = filter_frame_main_enabled,
-        .passthrough_filter_frame = filter_frame_main_disabled,
+        .filter_frame = filter_frame_main,
         .needs_writable = 1,
     },
     {
         .name         = "overlay",
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_input_overlay,
-        .filter_frame             = filter_frame_over_enabled,
-        .passthrough_filter_frame = filter_frame_over_disabled,
+        .filter_frame = filter_frame_over,
     },
     { NULL }
 };
@@ -773,5 +756,5 @@ AVFilter avfilter_vf_overlay = {
 
     .inputs    = avfilter_vf_overlay_inputs,
     .outputs   = avfilter_vf_overlay_outputs,
-    .flags     = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags     = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
diff --git a/libavfilter/vf_pp.c b/libavfilter/vf_pp.c
index 0571cfc..1fbfeb4 100644
--- a/libavfilter/vf_pp.c
+++ b/libavfilter/vf_pp.c
@@ -180,5 +180,5 @@ AVFilter avfilter_vf_pp = {
     .outputs         = pp_outputs,
     .process_command = pp_process_command,
     .priv_class      = &pp_class,
-    .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_DEFAULT,
 };
diff --git a/libavfilter/vf_removelogo.c b/libavfilter/vf_removelogo.c
index 589c43a..2354975 100644
--- a/libavfilter/vf_removelogo.c
+++ b/libavfilter/vf_removelogo.c
@@ -578,5 +578,5 @@ AVFilter avfilter_vf_removelogo = {
     .inputs        = removelogo_inputs,
     .outputs       = removelogo_outputs,
     .priv_class    = &removelogo_class,
-    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_DEFAULT,
 };
diff --git a/libavfilter/vf_smartblur.c b/libavfilter/vf_smartblur.c
index daf7451..6f0243f 100644
--- a/libavfilter/vf_smartblur.c
+++ b/libavfilter/vf_smartblur.c
@@ -302,5 +302,5 @@ AVFilter avfilter_vf_smartblur = {
     .inputs        = smartblur_inputs,
     .outputs       = smartblur_outputs,
     .priv_class    = &smartblur_class,
-    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_DEFAULT,
 };
diff --git a/libavfilter/vf_unsharp.c b/libavfilter/vf_unsharp.c
index fc0628e..db0f458 100644
--- a/libavfilter/vf_unsharp.c
+++ b/libavfilter/vf_unsharp.c
@@ -316,5 +316,5 @@ AVFilter avfilter_vf_unsharp = {
 
     .inputs    = avfilter_vf_unsharp_inputs,
     .outputs   = avfilter_vf_unsharp_outputs,
-    .flags     = AVFILTER_FLAG_SUPPORT_TIMELINE,
+    .flags     = AVFILTER_FLAG_SUPPORT_TIMELINE_DEFAULT,
 };
-- 
1.8.2.3

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 490 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20130511/8ee70c28/attachment.asc>


More information about the ffmpeg-devel mailing list