summaryrefslogtreecommitdiffstats
path: root/filters/filter.h
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2020-02-29 21:04:24 +0100
committerwm4 <wm4@nowhere>2020-02-29 21:49:14 +0100
commitf29623786b871807a663ce922d9afbf0d716a387 (patch)
treed74e2ce26267ba29ff3159357ab9542ea930a763 /filters/filter.h
parentd45d4f86e1c509d95d105df3063ae70ad3d340bb (diff)
downloadmpv-f29623786b871807a663ce922d9afbf0d716a387.tar.bz2
mpv-f29623786b871807a663ce922d9afbf0d716a387.tar.xz
filter: decide how multi-threading is supposed to work
Instead of vague ideas about making different filter graphs on different threads interact directly, this have no direct support. Instead, helpers are required (such as added with the next commit). Document it. Different root filters (i.e. separate filter graphs) are now considered to be part of separate threads, so assert() if they're found to accidentally interact.
Diffstat (limited to 'filters/filter.h')
-rw-r--r--filters/filter.h21
1 files changed, 13 insertions, 8 deletions
diff --git a/filters/filter.h b/filters/filter.h
index 5e09a17ee7..34146af98d 100644
--- a/filters/filter.h
+++ b/filters/filter.h
@@ -217,12 +217,6 @@ const char *mp_pin_get_name(struct mp_pin *p);
* call the first filter's process() function, which will filter and output
* the frame, and the frame is iteratively filtered until it reaches the output.
*
- * (The mp_pin_* calls can recursively start filtering, but this is only the
- * case if you access a separate graph with a different filter root. Most
- * importantly, calling them from outside the filter's process() function (e.g.
- * an outside filter user) will enter filtering. Within the filter, mp_pin_*
- * will usually only set or query flags.)
- *
* --- General rules for thread safety:
*
* Filters are by default not thread safe. However, some filters can be
@@ -231,6 +225,14 @@ const char *mp_pin_get_name(struct mp_pin *p);
* for some utility functions explicitly marked as such, and which are meant
* to make implementing threaded filters easier.
*
+ * (Semi-)automatic filter communication such as pins must always be within the
+ * same root filter. This is meant to help with ensuring thread-safety. Every
+ * thread that wants to run filters "on its own" should use a different filter
+ * graph, and disallowing different root filters ensures these graphs are not
+ * accidentally connected using non-thread safe mechanisms. Actual threaded
+ * filter graphs would use several independent graphs connected by asynchronous
+ * helpers (such as queues instead of mp_pin connections).
+ *
* --- Rules for manual connections:
*
* A pin can be marked for manual connection via mp_pin_set_manual_connection().
@@ -272,6 +274,11 @@ const char *mp_pin_get_name(struct mp_pin *p);
* For running parts of a filter graph on a different thread, f_async_queue.h
* can be used.
*
+ * With different filter graphs working asynchronously, reset handling and start
+ * of filtering becomes more difficult. Since filtering is always triggered by
+ * requesting output from a filter, a simple way to solve this is to trigger
+ * resets from the consumer, and to synchronously reset the producer.
+ *
* --- Format conversions and mid-stream format changes:
*
* Generally, all filters must support all formats, as well as mid-stream
@@ -402,8 +409,6 @@ struct AVBufferRef *mp_filter_load_hwdec_device(struct mp_filter *f, int avtype)
// Perform filtering. This runs until the filter graph is blocked (due to
// missing external input or unread output). It returns whether any outside
// pins have changed state.
-// Does not perform recursive filtering to connected filters with different
-// root filter, though it notifies them.
bool mp_filter_run(struct mp_filter *f);
// Create a root dummy filter with no inputs or outputs. This fulfills the