summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--filters/filter.c33
-rw-r--r--filters/filter.h4
2 files changed, 31 insertions, 6 deletions
diff --git a/filters/filter.c b/filters/filter.c
index 4134aff88b..cddeea0a3f 100644
--- a/filters/filter.c
+++ b/filters/filter.c
@@ -110,13 +110,13 @@ struct mp_filter_internal {
struct mp_filter *error_handler;
char *name;
+ bool high_priority;
bool pending;
bool async_pending;
bool failed;
};
-
// Called when new work needs to be done on a pin belonging to the filter:
// - new data was requested
// - new data has been queued
@@ -133,7 +133,11 @@ static void add_pending(struct mp_filter *f)
// This should probably really be some sort of priority queue, but for now
// something naive and dumb does the job too.
f->in->pending = true;
- MP_TARRAY_APPEND(r, r->pending, r->num_pending, f);
+ if (f->in->high_priority) {
+ MP_TARRAY_INSERT_AT(r, r->pending, r->num_pending, 0, f);
+ } else {
+ MP_TARRAY_APPEND(r, r->pending, r->num_pending, f);
+ }
}
static void add_pending_pin(struct mp_pin *p)
@@ -217,6 +221,8 @@ bool mp_filter_graph_run(struct mp_filter *filter)
flush_async_notifications(r);
+ bool exit_req = false;
+
while (1) {
if (atomic_exchange_explicit(&r->interrupt_flag, false,
memory_order_acq_rel))
@@ -226,7 +232,7 @@ bool mp_filter_graph_run(struct mp_filter *filter)
r->wakeup_cb(r->wakeup_ctx);
r->async_wakeup_sent = true;
pthread_mutex_unlock(&r->async_lock);
- break;
+ exit_req = true;
}
if (!r->num_pending) {
@@ -235,10 +241,20 @@ bool mp_filter_graph_run(struct mp_filter *filter)
break;
}
- struct mp_filter *next = r->pending[r->num_pending - 1];
- r->num_pending -= 1;
- next->in->pending = false;
+ struct mp_filter *next = NULL;
+
+ if (r->pending[0]->in->high_priority) {
+ next = r->pending[0];
+ MP_TARRAY_REMOVE_AT(r->pending, r->num_pending, 0);
+ } else if (!exit_req) {
+ next = r->pending[r->num_pending - 1];
+ r->num_pending -= 1;
+ }
+
+ if (!next)
+ break;
+ next->in->pending = false;
if (next->in->info->process)
next->in->info->process(next);
@@ -517,6 +533,11 @@ const struct mp_filter_info *mp_filter_get_info(struct mp_filter *f)
return f->in->info;
}
+void mp_filter_set_high_priority(struct mp_filter *f, bool pri)
+{
+ f->in->high_priority = pri;
+}
+
void mp_filter_set_name(struct mp_filter *f, const char *name)
{
talloc_free(f->in->name);
diff --git a/filters/filter.h b/filters/filter.h
index 34cfcf0f54..19aafc6f3d 100644
--- a/filters/filter.h
+++ b/filters/filter.h
@@ -346,6 +346,10 @@ const char *mp_filter_get_name(struct mp_filter *f);
// Change mp_filter_get_name() return value.
void mp_filter_set_name(struct mp_filter *f, const char *name);
+// Set filter priority. A higher priority gets processed first. Also, high
+// priority filters disable "interrupting" the filter graph.
+void mp_filter_set_high_priority(struct mp_filter *filter, bool pri);
+
// Get a pin from f->pins[] for which mp_pin_get_name() returns the same name.
// If name is NULL, always return NULL.
struct mp_pin *mp_filter_get_named_pin(struct mp_filter *f, const char *name);