diff options
author | Georg Chini <georg@chini.tk> | 2021-01-01 00:32:52 +0100 |
---|---|---|
committer | PulseAudio Marge Bot <pulseaudio-maintainers@lists.freedesktop.org> | 2021-11-03 18:37:31 +0000 |
commit | a37fd7eada375b0ae48150b46e48fcf8093cd526 (patch) | |
tree | 7ddf062cca1fd88c3f174cd27f32c8e273172499 /src/pulsecore | |
parent | 5c6d91a97cbc5f9202055efadd8ff340cbef3d2b (diff) | |
download | pulseaudio-a37fd7eada375b0ae48150b46e48fcf8093cd526.tar.gz |
sink-input: Query sink inputs for max_rewind value when setting max_rewind
This patch is in preparation of allowing virtual sinks to specify their own
max_rewind limit.
Currently pa_sink_set_max_rewind_within_thread() simply sets the value of
max_rewind and informs the sink inputs about the new value. Virtual sinks
may however provide their own limit on max_rewind.
This patch allows to query the active sink inputs for the max_rewind value
they support and sets max_rewind to the minimum supported value. This way,
the max_rewind value from the virtual sinks can be communicated to the master
sink.
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/120>
Diffstat (limited to 'src/pulsecore')
-rw-r--r-- | src/pulsecore/sink-input.c | 1 | ||||
-rw-r--r-- | src/pulsecore/sink-input.h | 7 | ||||
-rw-r--r-- | src/pulsecore/sink.c | 36 |
3 files changed, 44 insertions, 0 deletions
diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index b60f02a39..4380087ca 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -347,6 +347,7 @@ static void reset_callbacks(pa_sink_input *i) { i->send_event = NULL; i->volume_changed = NULL; i->mute_changed = NULL; + i->get_max_rewind_limit = NULL; } /* Called from main context */ diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h index 654539937..7a75c0f09 100644 --- a/src/pulsecore/sink-input.h +++ b/src/pulsecore/sink-input.h @@ -156,6 +156,13 @@ struct pa_sink_input { * changes. Called from IO context. */ void (*update_max_rewind) (pa_sink_input *i, size_t nbytes); /* may be NULL */ + /* Called whenever the maximum rewindable size of the sink + * changes. Used by virtual sinks to communicate rewind limits + * of the virtual sink to the master sink. Must return size_t (-1) + * if there is no limit or if the virtual sink is not opened. + * Called from IO context. */ + size_t (*get_max_rewind_limit) (pa_sink_input *i); /* may be NULL */ + /* Called whenever the maximum request size of the sink * changes. Called from IO context. */ void (*update_max_request) (pa_sink_input *i, size_t nbytes); /* may be NULL */ diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index a5691abef..3108ae765 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -2594,6 +2594,40 @@ static void set_shared_volume_within_thread(pa_sink *s) { } } +/* Called from IO thread. Gets max_rewind limit from sink inputs. + * This function is used to communicate the max_rewind value of a + * virtual sink to the master sink. The get_max_rewind_limit() + * callback is implemented by sink inputs connecting a virtual + * sink to its master. */ +static size_t get_max_rewind_limit(pa_sink *s, size_t requested_limit) { + pa_sink_input *i; + void *state = NULL; + size_t rewind_limit; + + pa_assert(s); + + /* Get rewind limit in sink sample spec from sink inputs */ + rewind_limit = (size_t)(-1); + if (PA_SINK_IS_LINKED(s->thread_info.state)) { + PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state) { + + if (i->get_max_rewind_limit) { + size_t limit; + + limit = i->get_max_rewind_limit(i); + if (rewind_limit == (size_t)(-1) || rewind_limit > limit) + rewind_limit = limit; + } + } + } + + /* Set max_rewind */ + if (rewind_limit != (size_t)(-1)) + requested_limit = PA_MIN(rewind_limit, requested_limit); + + return requested_limit; +} + /* Called from IO thread, except when it is not */ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) { pa_sink *s = PA_SINK(o); @@ -3143,6 +3177,8 @@ void pa_sink_set_max_rewind_within_thread(pa_sink *s, size_t max_rewind) { pa_sink_assert_ref(s); pa_sink_assert_io_context(s); + max_rewind = get_max_rewind_limit(s, max_rewind); + if (max_rewind == s->thread_info.max_rewind) return; |