1 #pragma once
2 
3 #include <stddef.h>
4 
5 #include "filter.h"
6 
7 // Flag the thread as needing mp_filter_process() to be called. Useful for
8 // (some) async filters only. Idempotent.
9 // Explicitly thread-safe.
10 void mp_filter_wakeup(struct mp_filter *f);
11 
12 // Same as mp_filter_wakeup(), but skip the wakeup, and only mark the filter
13 // as requiring processing to possibly update pin states changed due to async
14 // processing.
15 // Explicitly thread-safe.
16 void mp_filter_mark_async_progress(struct mp_filter *f);
17 
18 // Flag the thread as needing mp_filter_process() to be called. Unlike
19 // mp_filter_wakeup(), not thread-safe, and must be called from the process()
20 // function of f (in exchange this is very light-weight).
21 // In practice, this means process() is repeated.
22 void mp_filter_internal_mark_progress(struct mp_filter *f);
23 
24 // Flag the filter as having failed, and propagate the error to the parent
25 // filter. The error propagation stops either at the root filter, or if a filter
26 // has an error handler set.
27 // Must be called from f's process function.
28 void mp_filter_internal_mark_failed(struct mp_filter *f);
29 
30 // If handler is not NULL, then if filter f errors, don't propagate the error
31 // flag to its parent. Also invoke the handler's process() function, which is
32 // supposed to use mp_filter_has_failed(f) to check any filters for which it has
33 // set itself as error handler.
34 // A filter must manually unset itself as error handler if it gets destroyed
35 // before the filter f, otherwise dangling pointers will occur.
36 void mp_filter_set_error_handler(struct mp_filter *f, struct mp_filter *handler);
37 
38 // Add a pin. Returns the private handle (same as f->ppins[f->num_pins-1]).
39 // The name must be unique across all filter pins (you must verify this
40 // yourself if filter names are from user input). name=="" is not allowed.
41 // Never returns NULL. dir should be the external filter direction (a filter
42 // input will use dir==MP_PIN_IN, and the returned pin will use MP_PIN_OUT,
43 // because the internal pin is the opposite end of the external one).
44 struct mp_pin *mp_filter_add_pin(struct mp_filter *f, enum mp_pin_dir dir,
45                                  const char *name);
46 
47 // Remove and deallocate a pin. The caller must be sure that nothing else
48 // references the pin anymore. You must pass the private pin (from
49 // mp_filter.ppin). This removes/deallocates the public paired pin as well.
50 void mp_filter_remove_pin(struct mp_filter *f, struct mp_pin *p);
51 
52 // Free all filters which have f as parent. (This has nothing to do with
53 // talloc.)
54 void mp_filter_free_children(struct mp_filter *f);
55 
56 struct mp_filter_params;
57 
58 struct mp_filter_info {
59     // Informational name, in some cases might be used for filter discovery.
60     const char *name;
61 
62     // mp_filter.priv is set to memory allocated with this size (if > 0)
63     size_t priv_size;
64 
65     // Called during mp_filter_create(). Optional, can be NULL if use of a
66     // constructor function is required, which sets up the real filter after
67     // creation. Actually turns out nothing uses this.
68     bool (*init)(struct mp_filter *f, struct mp_filter_params *params);
69 
70     // Free internal resources. Optional.
71     void (*destroy)(struct mp_filter *f);
72 
73     // Called if any mp_pin was signalled (i.e. likely new data to process), or
74     // an async wakeup was received some time earlier.
75     // Generally, the implementation would consist of 2 stages:
76     //  1. check for the pin states, possibly request/probe for input/output
77     //  2. if data flow can happen, read a frame, perform actual work, write
78     //     result
79     // The process function will usually run very often, when pin states are
80     // updated, so the generic code can determine where data flow can happen.
81     // The common case will be that process() is called running stage 1 a bunch
82     // of times, until it finally can run stage 2 too.
83     // Optional.
84     void (*process)(struct mp_filter *f);
85 
86     // Clear internal state and buffers (e.g. on seeks). Filtering can restart
87     // after this, and all settings are preserved. It makes sense to preserve
88     // internal resources for further filtering as well if you can.
89     // Input/output pins are always cleared by the common code before invoking
90     // this callback.
91     // Optional, can be NULL for filters without state.
92     // Don't create or destroy filters in this function, don't reconnect pins,
93     // don't access pins.
94     void (*reset)(struct mp_filter *f);
95 
96     // Send a command to the filter. Highly implementation specific, usually
97     // user-initiated. Optional.
98     bool (*command)(struct mp_filter *f, struct mp_filter_command *cmd);
99 };
100 
101 // Return the mp_filter_info this filter was crated with.
102 const struct mp_filter_info *mp_filter_get_info(struct mp_filter *f);
103 
104 // Create a filter instance. Returns NULL on failure.
105 // Destroy/free with talloc_free().
106 // This is for filter implementers only. Filters are created with their own
107 // constructor functions (instead of a generic one), which call this function
108 // to create the filter itself.
109 // parent is never NULL; use mp_filter_create_root() to create a top most
110 // filter.
111 // The parent does not imply anything about the position of the filter in
112 // the dataflow (only the mp_pin connections matter). The parent exists for
113 // convenience, which includes:
114 //  - passing down implicit and explicit parameters (such as the filter driver
115 //    loop)
116 //  - auto freeing child filters if the parent is free'd
117 //  - propagating errors
118 //  - setting the parent as default manual connection for new external filter
119 //    pins
120 // The parent filter stays valid for the lifetime of any filters having it
121 // directly or indirectly as parent. If the parent is free'd, all children are
122 // automatically free'd.
123 // All filters in the same parent tree must be driven in the same thread (or be
124 // explicitly synchronized otherwise).
125 struct mp_filter *mp_filter_create(struct mp_filter *parent,
126                                    const struct mp_filter_info *info);
127 
128 struct mp_filter_params {
129     // Identifies the filter and its implementation. The pointer must stay
130     // valid for the life time of the created filter instance.
131     const struct mp_filter_info *info;
132 
133     // Must be set if global==NULL. See mp_filter_create() for remarks.
134     struct mp_filter *parent;
135 
136     // Must be set if parent==NULL, can otherwise be NULL.
137     struct mpv_global *global;
138 
139     // Filter specific parameters. Most filters will have a constructor
140     // function, and pass in something internal.
141     void *params;
142 };
143 
144 // Same as mp_filter_create(), but technically more flexible.
145 struct mp_filter *mp_filter_create_with_params(struct mp_filter_params *params);
146