lavfi: allow user-provided execute() callbacks
authorAnton Khirnov <anton@khirnov.net>
Thu, 8 Aug 2013 14:28:41 +0000 (16:28 +0200)
committerAnton Khirnov <anton@khirnov.net>
Sat, 28 Sep 2013 06:06:19 +0000 (08:06 +0200)
doc/APIchanges
libavfilter/avfilter.c
libavfilter/avfilter.h
libavfilter/avfiltergraph.c
libavfilter/internal.h
libavfilter/pthread.c
libavfilter/thread.h
libavfilter/version.h

index 85c02d670e6473287018562bc283bf2a658c6a8a..20fb16e28dfe49c90f30ad62a076b507e6dc9b68 100644 (file)
@@ -13,6 +13,10 @@ libavutil:     2012-10-22
 
 API changes, most recent first:
 
+2013-08-xx - xxxxxxx - lavfi 3.11.0 - avfilter.h
+  Add AVFilterGraph.execute and AVFilterGraph.opaque for custom slice threading
+  implementations.
+
 2013-09-21 - xxxxxxx - lavu 52.16.0 - pixfmt.h
   Add interleaved 4:2:2 8/10-bit formats AV_PIX_FMT_NV16 and
   AV_PIX_FMT_NV20.
index bfbc0389a954ca305f559421d648ba8f62db8ea3..88e39bf720cc16a7be79b5710183cba6637152f9 100644 (file)
@@ -371,7 +371,7 @@ static const AVClass avfilter_class = {
     .option           = avfilter_options,
 };
 
-static int default_execute(AVFilterContext *ctx, action_func *func, void *arg,
+static int default_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg,
                            int *ret, int nb_jobs)
 {
     int i;
index c5efdb8374f32fcdb830080eec06eff8c20fb59a..ca11be9bc6a459f14b714f0028d34d185a6f2d83 100644 (file)
@@ -899,6 +899,35 @@ const AVClass *avfilter_get_class(void);
 
 typedef struct AVFilterGraphInternal AVFilterGraphInternal;
 
+/**
+ * A function pointer passed to the @ref AVFilterGraph.execute callback to be
+ * executed multiple times, possibly in parallel.
+ *
+ * @param ctx the filter context the job belongs to
+ * @param arg an opaque parameter passed through from @ref
+ *            AVFilterGraph.execute
+ * @param jobnr the index of the job being executed
+ * @param nb_jobs the total number of jobs
+ *
+ * @return 0 on success, a negative AVERROR on error
+ */
+typedef int (avfilter_action_func)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs);
+
+/**
+ * A function executing multiple jobs, possibly in parallel.
+ *
+ * @param ctx the filter context to which the jobs belong
+ * @param func the function to be called multiple times
+ * @param arg the argument to be passed to func
+ * @param ret a nb_jobs-sized array to be filled with return values from each
+ *            invocation of func
+ * @param nb_jobs the number of jobs to execute
+ *
+ * @return 0 on success, a negative AVERROR on error
+ */
+typedef int (avfilter_execute_func)(AVFilterContext *ctx, avfilter_action_func *func,
+                                    void *arg, int *ret, int nb_jobs);
+
 typedef struct AVFilterGraph {
     const AVClass *av_class;
 #if FF_API_FOO_COUNT
@@ -941,6 +970,27 @@ typedef struct AVFilterGraph {
      * Opaque object for libavfilter internal use.
      */
     AVFilterGraphInternal *internal;
+
+    /**
+     * Opaque user data. May be set by the caller to an arbitrary value, e.g. to
+     * be used from callbacks like @ref AVFilterGraph.execute.
+     * Libavfilter will not touch this field in any way.
+     */
+    void *opaque;
+
+    /**
+     * This callback may be set by the caller immediately after allocating the
+     * graph and before adding any filters to it, to provide a custom
+     * multithreading implementation.
+     *
+     * If set, filters with slice threading capability will call this callback
+     * to execute multiple jobs in parallel.
+     *
+     * If this field is left unset, libavfilter will use its internal
+     * implementation, which may or may not be multithreaded depending on the
+     * platform and build options.
+     */
+    avfilter_execute_func *execute;
 } AVFilterGraph;
 
 /**
index de827355b8e8ff58c935c09cc23c4d23774ff45d..0fc385c3a663a76aed96172b7390b5c096f6dc3c 100644 (file)
@@ -168,11 +168,15 @@ AVFilterContext *avfilter_graph_alloc_filter(AVFilterGraph *graph,
 {
     AVFilterContext **filters, *s;
 
-    if (graph->thread_type && !graph->internal->thread) {
-        int ret = ff_graph_thread_init(graph);
-        if (ret < 0) {
-            av_log(graph, AV_LOG_ERROR, "Error initializing threading.\n");
-            return NULL;
+    if (graph->thread_type && !graph->internal->thread_execute) {
+        if (graph->execute) {
+            graph->internal->thread_execute = graph->execute;
+        } else {
+            int ret = ff_graph_thread_init(graph);
+            if (ret < 0) {
+                av_log(graph, AV_LOG_ERROR, "Error initializing threading.\n");
+                return NULL;
+            }
         }
     }
 
index 12655bc3e608bedc6de85a2537ef7e19f4f12274..44e75832d0bb80c81e5596f2d1e7ee8d208d0aab 100644 (file)
@@ -122,13 +122,11 @@ struct AVFilterPad {
 
 struct AVFilterGraphInternal {
     void *thread;
-    int (*thread_execute)(AVFilterContext *ctx, action_func *func, void *arg,
-                          int *ret, int nb_jobs);
+    avfilter_execute_func *thread_execute;
 };
 
 struct AVFilterInternal {
-    int (*execute)(AVFilterContext *ctx, action_func *func, void *arg,
-                   int *ret, int nb_jobs);
+    avfilter_execute_func *execute;
 };
 
 #if FF_API_AVFILTERBUFFER
index 2af0936ab5acc0df0df53508ade580f2c5a7702e..a4f45c82cd50b6921e425d76b456676b45e53f15 100644 (file)
@@ -43,7 +43,7 @@ typedef struct ThreadContext {
 
     int nb_threads;
     pthread_t *workers;
-    action_func *func;
+    avfilter_action_func *func;
 
     /* per-execute perameters */
     AVFilterContext *ctx;
@@ -114,7 +114,7 @@ static void slice_thread_park_workers(ThreadContext *c)
     pthread_mutex_unlock(&c->current_job_lock);
 }
 
-static int thread_execute(AVFilterContext *ctx, action_func *func,
+static int thread_execute(AVFilterContext *ctx, avfilter_action_func *func,
                           void *arg, int *ret, int nb_jobs)
 {
     ThreadContext *c = ctx->graph->internal->thread;
index 49134d948a0eddba4ea733a3b169196c6c2aed50..1cfea3e7ba4c1553752515db4cf16ff984cd3220 100644 (file)
@@ -22,8 +22,6 @@
 
 #include "avfilter.h"
 
-typedef int (action_func)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs);
-
 int ff_graph_thread_init(AVFilterGraph *graph);
 
 void ff_graph_thread_free(AVFilterGraph *graph);
index cb692282135f7696e47120edcf898cc52cbc682d..9c84e0f85ac67f512a42b06b20566f525e432f9b 100644 (file)
@@ -30,7 +30,7 @@
 #include "libavutil/avutil.h"
 
 #define LIBAVFILTER_VERSION_MAJOR  3
-#define LIBAVFILTER_VERSION_MINOR  10
+#define LIBAVFILTER_VERSION_MINOR  11
 #define LIBAVFILTER_VERSION_MICRO  0
 
 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \