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.
This commit is contained in:
wm4 2020-08-28 20:06:18 +02:00
parent 2c7139753d
commit 86068af178
2 changed files with 15 additions and 3 deletions

View File

@ -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,

View File

@ -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