summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2020-08-28 20:06:18 +0200
committerwm4 <wm4@nowhere>2020-08-28 20:06:18 +0200
commit86068af1785305101bbad842ab7472f5366d2adc (patch)
tree8baadc686874e414a494e162bff5ce26eab6ad0f
parent2c7139753d1e1530da44b781e9ae7c65874bb677 (diff)
downloadmpv-86068af1785305101bbad842ab7472f5366d2adc.tar.bz2
mpv-86068af1785305101bbad842ab7472f5366d2adc.tar.xz
f_async_queue: change reset behavior
Do not make resetting the "access" filters reset the queue itself. This is more flexible, and will be used in a later commit. Also, if the queue is not in the reset state while the input access filter is reset, make it immediately request data again. This is more consistent, because it'll enter the state it "should" be, rather when the filter's process function is called at an (essentially) random point in the future. This means the filter graph will resume work on its own if the queue was not reset before filter reset. This could affect the only current user of f_async_queue, the code for the --vd-queue-enable/--ad-queue-enable feature in f_decoder_wrapper. But it looks like this already uses it in a compatible way.
-rw-r--r--filters/f_async_queue.c8
-rw-r--r--filters/f_async_queue.h10
2 files changed, 15 insertions, 3 deletions
diff --git a/filters/f_async_queue.c b/filters/f_async_queue.c
index 696649f3d1..8aa2041dd9 100644
--- a/filters/f_async_queue.c
+++ b/filters/f_async_queue.c
@@ -248,7 +248,12 @@ static void reset(struct mp_filter *f)
struct priv *p = f->priv;
struct async_queue *q = p->q;
- reset_queue(q);
+ pthread_mutex_lock(&q->lock);
+ // If the queue is in reading state, it is logical that it should request
+ // input immediately.
+ if (mp_pin_get_dir(f->pins[0]) == MP_PIN_IN && q->reading)
+ mp_filter_wakeup(f);
+ pthread_mutex_unlock(&q->lock);
}
// producer
@@ -266,7 +271,6 @@ static const struct mp_filter_info info_out = {
.priv_size = sizeof(struct priv),
.destroy = destroy,
.process = process_out,
- .reset = reset,
};
struct mp_filter *mp_async_queue_create_filter(struct mp_filter *parent,
diff --git a/filters/f_async_queue.h b/filters/f_async_queue.h
index 6b1ffabe36..dcc5ba57eb 100644
--- a/filters/f_async_queue.h
+++ b/filters/f_async_queue.h
@@ -24,6 +24,8 @@ void mp_async_queue_reset(struct mp_async_queue *queue);
// Put the queue into "active" mode. If it wasn't, then the consumer is woken
// up (and if there is no data in the queue, this will in turn wake up the
// producer, i.e. start transfers automatically).
+// If there is a writer end but no reader end, this will simply make the queue
+// fill up.
void mp_async_queue_resume(struct mp_async_queue *queue);
// Create a filter to access the queue, and connect it. It's not allowed to
@@ -34,11 +36,17 @@ void mp_async_queue_resume(struct mp_async_queue *queue);
// the producer to write any data. You need to call mp_async_queue_resume() to
// start communication. Actual transfers happen only once the consumer filter
// has read requests on its mp_pin.
-// Resetting any of the consumer/producer filters calls mp_async_queue_reset().
// If the producer filter requested a new frame from its filter graph, and the
// queue is asynchronously set to "inactive", then the requested frame will be
// silently discarded once it reaches the producer filter.
//
+// Resetting a queue filter does not affect the queue at all. Managing the
+// queue state is the API user's responsibility. Note that resetting an input
+// filter (dir==MP_PIN_IN) while the queue is active and in "reading" state
+// (the output filter requested data at any point before the last
+// mp_async_queue_reset() was called), the
+// filter will immediately request data after the reset.
+//
// For proper global reset, this order should be preferred:
// - mp_async_queue_reset()
// - reset producer and consumer filters on their respective threads (in any