summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorg Chini <georg@chini.tk>2021-01-01 00:32:52 +0100
committerPulseAudio Marge Bot <pulseaudio-maintainers@lists.freedesktop.org>2021-11-03 18:37:31 +0000
commita37fd7eada375b0ae48150b46e48fcf8093cd526 (patch)
tree7ddf062cca1fd88c3f174cd27f32c8e273172499
parent5c6d91a97cbc5f9202055efadd8ff340cbef3d2b (diff)
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>
-rw-r--r--src/pulsecore/sink-input.c1
-rw-r--r--src/pulsecore/sink-input.h7
-rw-r--r--src/pulsecore/sink.c36
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;