[FFmpeg-devel,07/16] lavfi/framesync2: add common options.

Submitted by Nicolas George on Aug. 10, 2017, 11:46 a.m.

Details

Message ID 20170810114642.26779-7-george@nsup.org
State Accepted
Commit 05a23b2565849c9ad96526c9e2ccdb9272add565
Headers show

Commit Message

Nicolas George Aug. 10, 2017, 11:46 a.m.
Also add functions and macros to help filters chaining these
options to their own.

Signed-off-by: Nicolas George <george@nsup.org>
---
 libavfilter/framesync2.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++--
 libavfilter/framesync2.h | 44 +++++++++++++++++++++++++++++++++++++-
 2 files changed, 96 insertions(+), 3 deletions(-)


Unchanged.

Comments

Paul B Mahol Aug. 30, 2017, 9:25 a.m.
On 8/10/17, Nicolas George <george@nsup.org> wrote:
> Also add functions and macros to help filters chaining these
> options to their own.
>
> Signed-off-by: Nicolas George <george@nsup.org>
> ---
>  libavfilter/framesync2.c | 55
> ++++++++++++++++++++++++++++++++++++++++++++++--
>  libavfilter/framesync2.h | 44 +++++++++++++++++++++++++++++++++++++-
>  2 files changed, 96 insertions(+), 3 deletions(-)
>
>
> Unchanged.
>
>
> diff --git a/libavfilter/framesync2.c b/libavfilter/framesync2.c
> index 0f78a1733b..fae06aa1f5 100644
> --- a/libavfilter/framesync2.c
> +++ b/libavfilter/framesync2.c
> @@ -19,24 +19,43 @@
>   */
>
>  #include "libavutil/avassert.h"
> +#include "libavutil/opt.h"
>  #include "avfilter.h"
>  #include "filters.h"
>  #include "framesync2.h"
>  #include "internal.h"
>
>  #define OFFSET(member) offsetof(FFFrameSync, member)
> +#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
> +
> +enum EOFAction {
> +    EOF_ACTION_REPEAT,
> +    EOF_ACTION_ENDALL,
> +    EOF_ACTION_PASS
> +};
>
>  static const char *framesync_name(void *ptr)
>  {
>      return "framesync";
>  }
>
> +static const AVOption framesync_options[] = {
> +    { "eof_action", "Action to take when encountering EOF from secondary
> input ",
> +        OFFSET(opt_eof_action), AV_OPT_TYPE_INT, { .i64 = EOF_ACTION_REPEAT
> },
> +        EOF_ACTION_REPEAT, EOF_ACTION_PASS, .flags = FLAGS, "eof_action" },
> +        { "repeat", "Repeat the previous frame.",   0, AV_OPT_TYPE_CONST, {
> .i64 = EOF_ACTION_REPEAT }, .flags = FLAGS, "eof_action" },
> +        { "endall", "End both streams.",            0, AV_OPT_TYPE_CONST, {
> .i64 = EOF_ACTION_ENDALL }, .flags = FLAGS, "eof_action" },
> +        { "pass",   "Pass through the main input.", 0, AV_OPT_TYPE_CONST, {
> .i64 = EOF_ACTION_PASS },   .flags = FLAGS, "eof_action" },
> +    { "shortest", "force termination when the shortest input terminates",
> OFFSET(opt_shortest), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
> +    { "repeatlast", "repeat overlay of the last overlay frame",
> OFFSET(opt_repeatlast), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, FLAGS },

Overlay means something for overlay filter only for others its source
of confusion.
So description need be changed.

Patch hide | download patch | download mbox

diff --git a/libavfilter/framesync2.c b/libavfilter/framesync2.c
index 0f78a1733b..fae06aa1f5 100644
--- a/libavfilter/framesync2.c
+++ b/libavfilter/framesync2.c
@@ -19,24 +19,43 @@ 
  */
 
 #include "libavutil/avassert.h"
+#include "libavutil/opt.h"
 #include "avfilter.h"
 #include "filters.h"
 #include "framesync2.h"
 #include "internal.h"
 
 #define OFFSET(member) offsetof(FFFrameSync, member)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
+
+enum EOFAction {
+    EOF_ACTION_REPEAT,
+    EOF_ACTION_ENDALL,
+    EOF_ACTION_PASS
+};
 
 static const char *framesync_name(void *ptr)
 {
     return "framesync";
 }
 
+static const AVOption framesync_options[] = {
+    { "eof_action", "Action to take when encountering EOF from secondary input ",
+        OFFSET(opt_eof_action), AV_OPT_TYPE_INT, { .i64 = EOF_ACTION_REPEAT },
+        EOF_ACTION_REPEAT, EOF_ACTION_PASS, .flags = FLAGS, "eof_action" },
+        { "repeat", "Repeat the previous frame.",   0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_REPEAT }, .flags = FLAGS, "eof_action" },
+        { "endall", "End both streams.",            0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_ENDALL }, .flags = FLAGS, "eof_action" },
+        { "pass",   "Pass through the main input.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_PASS },   .flags = FLAGS, "eof_action" },
+    { "shortest", "force termination when the shortest input terminates", OFFSET(opt_shortest), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
+    { "repeatlast", "repeat overlay of the last overlay frame", OFFSET(opt_repeatlast), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, FLAGS },
+    { NULL }
+};
 static const AVClass framesync_class = {
     .version                   = LIBAVUTIL_VERSION_INT,
     .class_name                = "framesync",
     .item_name                 = framesync_name,
     .category                  = AV_CLASS_CATEGORY_FILTER,
-    .option                    = NULL,
+    .option                    = framesync_options,
     .parent_log_context_offset = OFFSET(parent),
 };
 
@@ -48,6 +67,19 @@  enum {
 
 static int consume_from_fifos(FFFrameSync *fs);
 
+const AVClass *framesync2_get_class(void)
+{
+    return &framesync_class;
+}
+
+void ff_framesync2_preinit(FFFrameSync *fs)
+{
+    if (fs->class)
+        return;
+    fs->class  = &framesync_class;
+    av_opt_set_defaults(fs);
+}
+
 int ff_framesync2_init(FFFrameSync *fs, AVFilterContext *parent, unsigned nb_in)
 {
     /* For filters with several outputs, we will not be able to assume which
@@ -55,7 +87,7 @@  int ff_framesync2_init(FFFrameSync *fs, AVFilterContext *parent, unsigned nb_in)
        ff_outlink_set_status(). To be designed when needed. */
     av_assert0(parent->nb_outputs == 1);
 
-    fs->class  = &framesync_class;
+    ff_framesync2_preinit(fs);
     fs->parent = parent;
     fs->nb_in  = nb_in;
 
@@ -93,6 +125,25 @@  int ff_framesync2_configure(FFFrameSync *fs)
     unsigned i;
     int64_t gcd, lcm;
 
+    if (!fs->opt_repeatlast || fs->opt_eof_action == EOF_ACTION_PASS) {
+        fs->opt_repeatlast = 0;
+        fs->opt_eof_action = EOF_ACTION_PASS;
+    }
+    if (fs->opt_shortest || fs->opt_eof_action == EOF_ACTION_ENDALL) {
+        fs->opt_shortest = 1;
+        fs->opt_eof_action = EOF_ACTION_ENDALL;
+    }
+    if (fs->opt_shortest) {
+        for (i = 0; i < fs->nb_in; i++)
+            fs->in[i].after = EXT_STOP;
+    }
+    if (!fs->opt_repeatlast) {
+        for (i = 1; i < fs->nb_in; i++) {
+            fs->in[i].after = EXT_NULL;
+            fs->in[i].sync  = 0;
+        }
+    }
+
     if (!fs->time_base.num) {
         for (i = 0; i < fs->nb_in; i++) {
             if (fs->in[i].sync) {
diff --git a/libavfilter/framesync2.h b/libavfilter/framesync2.h
index 9a54b2b701..745e896bc8 100644
--- a/libavfilter/framesync2.h
+++ b/libavfilter/framesync2.h
@@ -196,12 +196,30 @@  typedef struct FFFrameSync {
      */
     FFFrameSyncIn *in;
 
+    int opt_repeatlast;
+    int opt_shortest;
+    int opt_eof_action;
+
 } FFFrameSync;
 
 /**
- * Initialize a frame sync structure.
+ * Get the class for the framesync2 object.
+ */
+const AVClass *framesync2_get_class(void);
+
+/**
+ * Pre-initialize a frame sync structure.
  *
+ * It sets the class pointer and inits the options to their default values.
  * The entire structure is expected to be already set to 0.
+ * This step is optional, but necessary to use the options.
+ */
+void ff_framesync2_preinit(FFFrameSync *fs);
+
+/**
+ * Initialize a frame sync structure.
+ *
+ * The entire structure is expected to be already set to 0 or preinited.
  *
  * @param  fs      frame sync structure to initialize
  * @param  parent  parent AVFilterContext object
@@ -270,4 +288,28 @@  int ff_framesync2_dualinput_get(FFFrameSync *fs, AVFrame **f0, AVFrame **f1);
  */
 int ff_framesync2_dualinput_get_writable(FFFrameSync *fs, AVFrame **f0, AVFrame **f1);
 
+#define FRAMESYNC_DEFINE_CLASS(name, context, field) \
+static int name##_framesync_preinit(AVFilterContext *ctx) { \
+    context *s = ctx->priv; \
+    ff_framesync2_preinit(&s->field); \
+    return 0; \
+} \
+static const AVClass *name##_child_class_next(const AVClass *prev) { \
+    return prev ? NULL : framesync2_get_class(); \
+} \
+static void *name##_child_next(void *obj, void *prev) { \
+    context *s = obj; \
+    s->fs.class = framesync2_get_class(); /* FIXME */ \
+    return prev ? NULL : &s->field; \
+} \
+static const AVClass name##_class = { \
+    .class_name       = #name, \
+    .item_name        = av_default_item_name, \
+    .option           = name##_options, \
+    .version          = LIBAVUTIL_VERSION_INT, \
+    .category         = AV_CLASS_CATEGORY_FILTER, \
+    .child_class_next = name##_child_class_next, \
+    .child_next       = name##_child_next, \
+}
+
 #endif /* AVFILTER_FRAMESYNC2_H */