]> code.delx.au - pulseaudio/blob - src/pulsecore/sink.c
c1cd2db4f54ef0a49b2c526cea61de18a9658ab5
[pulseaudio] / src / pulsecore / sink.c
1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2004-2006 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
6
7 PulseAudio is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published
9 by the Free Software Foundation; either version 2.1 of the License,
10 or (at your option) any later version.
11
12 PulseAudio is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with PulseAudio; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 USA.
21 ***/
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30
31 #include <pulse/introspect.h>
32 #include <pulse/format.h>
33 #include <pulse/utf8.h>
34 #include <pulse/xmalloc.h>
35 #include <pulse/timeval.h>
36 #include <pulse/util.h>
37 #include <pulse/rtclock.h>
38 #include <pulse/internal.h>
39
40 #include <pulsecore/i18n.h>
41 #include <pulsecore/sink-input.h>
42 #include <pulsecore/namereg.h>
43 #include <pulsecore/core-util.h>
44 #include <pulsecore/sample-util.h>
45 #include <pulsecore/mix.h>
46 #include <pulsecore/core-subscribe.h>
47 #include <pulsecore/log.h>
48 #include <pulsecore/macro.h>
49 #include <pulsecore/play-memblockq.h>
50 #include <pulsecore/flist.h>
51
52 #include "sink.h"
53
54 #define MAX_MIX_CHANNELS 32
55 #define MIX_BUFFER_LENGTH (PA_PAGE_SIZE)
56 #define ABSOLUTE_MIN_LATENCY (500)
57 #define ABSOLUTE_MAX_LATENCY (10*PA_USEC_PER_SEC)
58 #define DEFAULT_FIXED_LATENCY (250*PA_USEC_PER_MSEC)
59
60 PA_DEFINE_PUBLIC_CLASS(pa_sink, pa_msgobject);
61
62 struct pa_sink_volume_change {
63 pa_usec_t at;
64 pa_cvolume hw_volume;
65
66 PA_LLIST_FIELDS(pa_sink_volume_change);
67 };
68
69 struct sink_message_set_port {
70 pa_device_port *port;
71 int ret;
72 };
73
74 static void sink_free(pa_object *s);
75
76 static void pa_sink_volume_change_push(pa_sink *s);
77 static void pa_sink_volume_change_flush(pa_sink *s);
78 static void pa_sink_volume_change_rewind(pa_sink *s, size_t nbytes);
79
80 pa_sink_new_data* pa_sink_new_data_init(pa_sink_new_data *data) {
81 pa_assert(data);
82
83 pa_zero(*data);
84 data->proplist = pa_proplist_new();
85 data->ports = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, (pa_free_cb_t) pa_device_port_unref);
86
87 return data;
88 }
89
90 void pa_sink_new_data_set_name(pa_sink_new_data *data, const char *name) {
91 pa_assert(data);
92
93 pa_xfree(data->name);
94 data->name = pa_xstrdup(name);
95 }
96
97 void pa_sink_new_data_set_sample_spec(pa_sink_new_data *data, const pa_sample_spec *spec) {
98 pa_assert(data);
99
100 if ((data->sample_spec_is_set = !!spec))
101 data->sample_spec = *spec;
102 }
103
104 void pa_sink_new_data_set_channel_map(pa_sink_new_data *data, const pa_channel_map *map) {
105 pa_assert(data);
106
107 if ((data->channel_map_is_set = !!map))
108 data->channel_map = *map;
109 }
110
111 void pa_sink_new_data_set_alternate_sample_rate(pa_sink_new_data *data, const uint32_t alternate_sample_rate) {
112 pa_assert(data);
113
114 data->alternate_sample_rate_is_set = true;
115 data->alternate_sample_rate = alternate_sample_rate;
116 }
117
118 void pa_sink_new_data_set_volume(pa_sink_new_data *data, const pa_cvolume *volume) {
119 pa_assert(data);
120
121 if ((data->volume_is_set = !!volume))
122 data->volume = *volume;
123 }
124
125 void pa_sink_new_data_set_muted(pa_sink_new_data *data, bool mute) {
126 pa_assert(data);
127
128 data->muted_is_set = true;
129 data->muted = !!mute;
130 }
131
132 void pa_sink_new_data_set_port(pa_sink_new_data *data, const char *port) {
133 pa_assert(data);
134
135 pa_xfree(data->active_port);
136 data->active_port = pa_xstrdup(port);
137 }
138
139 void pa_sink_new_data_done(pa_sink_new_data *data) {
140 pa_assert(data);
141
142 pa_proplist_free(data->proplist);
143
144 if (data->ports)
145 pa_hashmap_free(data->ports);
146
147 pa_xfree(data->name);
148 pa_xfree(data->active_port);
149 }
150
151 /* Called from main context */
152 static void reset_callbacks(pa_sink *s) {
153 pa_assert(s);
154
155 s->set_state = NULL;
156 s->get_volume = NULL;
157 s->set_volume = NULL;
158 s->write_volume = NULL;
159 s->get_mute = NULL;
160 s->set_mute = NULL;
161 s->request_rewind = NULL;
162 s->update_requested_latency = NULL;
163 s->set_port = NULL;
164 s->get_formats = NULL;
165 s->set_formats = NULL;
166 s->update_rate = NULL;
167 }
168
169 /* Called from main context */
170 pa_sink* pa_sink_new(
171 pa_core *core,
172 pa_sink_new_data *data,
173 pa_sink_flags_t flags) {
174
175 pa_sink *s;
176 const char *name;
177 char st[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
178 pa_source_new_data source_data;
179 const char *dn;
180 char *pt;
181
182 pa_assert(core);
183 pa_assert(data);
184 pa_assert(data->name);
185 pa_assert_ctl_context();
186
187 s = pa_msgobject_new(pa_sink);
188
189 if (!(name = pa_namereg_register(core, data->name, PA_NAMEREG_SINK, s, data->namereg_fail))) {
190 pa_log_debug("Failed to register name %s.", data->name);
191 pa_xfree(s);
192 return NULL;
193 }
194
195 pa_sink_new_data_set_name(data, name);
196
197 if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_NEW], data) < 0) {
198 pa_xfree(s);
199 pa_namereg_unregister(core, name);
200 return NULL;
201 }
202
203 /* FIXME, need to free s here on failure */
204
205 pa_return_null_if_fail(!data->driver || pa_utf8_valid(data->driver));
206 pa_return_null_if_fail(data->name && pa_utf8_valid(data->name) && data->name[0]);
207
208 pa_return_null_if_fail(data->sample_spec_is_set && pa_sample_spec_valid(&data->sample_spec));
209
210 if (!data->channel_map_is_set)
211 pa_return_null_if_fail(pa_channel_map_init_auto(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT));
212
213 pa_return_null_if_fail(pa_channel_map_valid(&data->channel_map));
214 pa_return_null_if_fail(data->channel_map.channels == data->sample_spec.channels);
215
216 /* FIXME: There should probably be a general function for checking whether
217 * the sink volume is allowed to be set, like there is for sink inputs. */
218 pa_assert(!data->volume_is_set || !(flags & PA_SINK_SHARE_VOLUME_WITH_MASTER));
219
220 if (!data->volume_is_set) {
221 pa_cvolume_reset(&data->volume, data->sample_spec.channels);
222 data->save_volume = false;
223 }
224
225 pa_return_null_if_fail(pa_cvolume_valid(&data->volume));
226 pa_return_null_if_fail(pa_cvolume_compatible(&data->volume, &data->sample_spec));
227
228 if (!data->muted_is_set)
229 data->muted = false;
230
231 if (data->card)
232 pa_proplist_update(data->proplist, PA_UPDATE_MERGE, data->card->proplist);
233
234 pa_device_init_description(data->proplist, data->card);
235 pa_device_init_icon(data->proplist, true);
236 pa_device_init_intended_roles(data->proplist);
237
238 if (!data->active_port) {
239 pa_device_port *p = pa_device_port_find_best(data->ports);
240 if (p)
241 pa_sink_new_data_set_port(data, p->name);
242 }
243
244 if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_FIXATE], data) < 0) {
245 pa_xfree(s);
246 pa_namereg_unregister(core, name);
247 return NULL;
248 }
249
250 s->parent.parent.free = sink_free;
251 s->parent.process_msg = pa_sink_process_msg;
252
253 s->core = core;
254 s->state = PA_SINK_INIT;
255 s->flags = flags;
256 s->priority = 0;
257 s->suspend_cause = data->suspend_cause;
258 pa_sink_set_mixer_dirty(s, false);
259 s->name = pa_xstrdup(name);
260 s->proplist = pa_proplist_copy(data->proplist);
261 s->driver = pa_xstrdup(pa_path_get_filename(data->driver));
262 s->module = data->module;
263 s->card = data->card;
264
265 s->priority = pa_device_init_priority(s->proplist);
266
267 s->sample_spec = data->sample_spec;
268 s->channel_map = data->channel_map;
269 s->default_sample_rate = s->sample_spec.rate;
270
271 if (data->alternate_sample_rate_is_set)
272 s->alternate_sample_rate = data->alternate_sample_rate;
273 else
274 s->alternate_sample_rate = s->core->alternate_sample_rate;
275
276 if (s->sample_spec.rate == s->alternate_sample_rate) {
277 pa_log_warn("Default and alternate sample rates are the same.");
278 s->alternate_sample_rate = 0;
279 }
280
281 s->inputs = pa_idxset_new(NULL, NULL);
282 s->n_corked = 0;
283 s->input_to_master = NULL;
284
285 s->reference_volume = s->real_volume = data->volume;
286 pa_cvolume_reset(&s->soft_volume, s->sample_spec.channels);
287 s->base_volume = PA_VOLUME_NORM;
288 s->n_volume_steps = PA_VOLUME_NORM+1;
289 s->muted = data->muted;
290 s->refresh_volume = s->refresh_muted = false;
291
292 reset_callbacks(s);
293 s->userdata = NULL;
294
295 s->asyncmsgq = NULL;
296
297 /* As a minor optimization we just steal the list instead of
298 * copying it here */
299 s->ports = data->ports;
300 data->ports = NULL;
301
302 s->active_port = NULL;
303 s->save_port = false;
304
305 if (data->active_port)
306 if ((s->active_port = pa_hashmap_get(s->ports, data->active_port)))
307 s->save_port = data->save_port;
308
309 /* Hopefully the active port has already been assigned in the previous call
310 to pa_device_port_find_best, but better safe than sorry */
311 if (!s->active_port)
312 s->active_port = pa_device_port_find_best(s->ports);
313
314 if (s->active_port)
315 s->latency_offset = s->active_port->latency_offset;
316 else
317 s->latency_offset = 0;
318
319 s->save_volume = data->save_volume;
320 s->save_muted = data->save_muted;
321
322 pa_silence_memchunk_get(
323 &core->silence_cache,
324 core->mempool,
325 &s->silence,
326 &s->sample_spec,
327 0);
328
329 s->thread_info.rtpoll = NULL;
330 s->thread_info.inputs = pa_hashmap_new_full(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func, NULL,
331 (pa_free_cb_t) pa_sink_input_unref);
332 s->thread_info.soft_volume = s->soft_volume;
333 s->thread_info.soft_muted = s->muted;
334 s->thread_info.state = s->state;
335 s->thread_info.rewind_nbytes = 0;
336 s->thread_info.rewind_requested = false;
337 s->thread_info.max_rewind = 0;
338 s->thread_info.max_request = 0;
339 s->thread_info.requested_latency_valid = false;
340 s->thread_info.requested_latency = 0;
341 s->thread_info.min_latency = ABSOLUTE_MIN_LATENCY;
342 s->thread_info.max_latency = ABSOLUTE_MAX_LATENCY;
343 s->thread_info.fixed_latency = flags & PA_SINK_DYNAMIC_LATENCY ? 0 : DEFAULT_FIXED_LATENCY;
344
345 PA_LLIST_HEAD_INIT(pa_sink_volume_change, s->thread_info.volume_changes);
346 s->thread_info.volume_changes_tail = NULL;
347 pa_sw_cvolume_multiply(&s->thread_info.current_hw_volume, &s->soft_volume, &s->real_volume);
348 s->thread_info.volume_change_safety_margin = core->deferred_volume_safety_margin_usec;
349 s->thread_info.volume_change_extra_delay = core->deferred_volume_extra_delay_usec;
350 s->thread_info.latency_offset = s->latency_offset;
351
352 /* FIXME: This should probably be moved to pa_sink_put() */
353 pa_assert_se(pa_idxset_put(core->sinks, s, &s->index) >= 0);
354
355 if (s->card)
356 pa_assert_se(pa_idxset_put(s->card->sinks, s, NULL) >= 0);
357
358 pt = pa_proplist_to_string_sep(s->proplist, "\n ");
359 pa_log_info("Created sink %u \"%s\" with sample spec %s and channel map %s\n %s",
360 s->index,
361 s->name,
362 pa_sample_spec_snprint(st, sizeof(st), &s->sample_spec),
363 pa_channel_map_snprint(cm, sizeof(cm), &s->channel_map),
364 pt);
365 pa_xfree(pt);
366
367 pa_source_new_data_init(&source_data);
368 pa_source_new_data_set_sample_spec(&source_data, &s->sample_spec);
369 pa_source_new_data_set_channel_map(&source_data, &s->channel_map);
370 pa_source_new_data_set_alternate_sample_rate(&source_data, s->alternate_sample_rate);
371 source_data.name = pa_sprintf_malloc("%s.monitor", name);
372 source_data.driver = data->driver;
373 source_data.module = data->module;
374 source_data.card = data->card;
375
376 dn = pa_proplist_gets(s->proplist, PA_PROP_DEVICE_DESCRIPTION);
377 pa_proplist_setf(source_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Monitor of %s", dn ? dn : s->name);
378 pa_proplist_sets(source_data.proplist, PA_PROP_DEVICE_CLASS, "monitor");
379
380 s->monitor_source = pa_source_new(core, &source_data,
381 ((flags & PA_SINK_LATENCY) ? PA_SOURCE_LATENCY : 0) |
382 ((flags & PA_SINK_DYNAMIC_LATENCY) ? PA_SOURCE_DYNAMIC_LATENCY : 0));
383
384 pa_source_new_data_done(&source_data);
385
386 if (!s->monitor_source) {
387 pa_sink_unlink(s);
388 pa_sink_unref(s);
389 return NULL;
390 }
391
392 s->monitor_source->monitor_of = s;
393
394 pa_source_set_latency_range(s->monitor_source, s->thread_info.min_latency, s->thread_info.max_latency);
395 pa_source_set_fixed_latency(s->monitor_source, s->thread_info.fixed_latency);
396 pa_source_set_max_rewind(s->monitor_source, s->thread_info.max_rewind);
397
398 return s;
399 }
400
401 /* Called from main context */
402 static int sink_set_state(pa_sink *s, pa_sink_state_t state) {
403 int ret;
404 bool suspend_change;
405 pa_sink_state_t original_state;
406
407 pa_assert(s);
408 pa_assert_ctl_context();
409
410 if (s->state == state)
411 return 0;
412
413 original_state = s->state;
414
415 suspend_change =
416 (original_state == PA_SINK_SUSPENDED && PA_SINK_IS_OPENED(state)) ||
417 (PA_SINK_IS_OPENED(original_state) && state == PA_SINK_SUSPENDED);
418
419 if (s->set_state)
420 if ((ret = s->set_state(s, state)) < 0)
421 return ret;
422
423 if (s->asyncmsgq)
424 if ((ret = pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), 0, NULL)) < 0) {
425
426 if (s->set_state)
427 s->set_state(s, original_state);
428
429 return ret;
430 }
431
432 s->state = state;
433
434 if (state != PA_SINK_UNLINKED) { /* if we enter UNLINKED state pa_sink_unlink() will fire the appropriate events */
435 pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_STATE_CHANGED], s);
436 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
437 }
438
439 if (suspend_change) {
440 pa_sink_input *i;
441 uint32_t idx;
442
443 /* We're suspending or resuming, tell everyone about it */
444
445 PA_IDXSET_FOREACH(i, s->inputs, idx)
446 if (s->state == PA_SINK_SUSPENDED &&
447 (i->flags & PA_SINK_INPUT_KILL_ON_SUSPEND))
448 pa_sink_input_kill(i);
449 else if (i->suspend)
450 i->suspend(i, state == PA_SINK_SUSPENDED);
451
452 if (s->monitor_source)
453 pa_source_sync_suspend(s->monitor_source);
454 }
455
456 return 0;
457 }
458
459 void pa_sink_set_get_volume_callback(pa_sink *s, pa_sink_cb_t cb) {
460 pa_assert(s);
461
462 s->get_volume = cb;
463 }
464
465 void pa_sink_set_set_volume_callback(pa_sink *s, pa_sink_cb_t cb) {
466 pa_sink_flags_t flags;
467
468 pa_assert(s);
469 pa_assert(!s->write_volume || cb);
470
471 s->set_volume = cb;
472
473 /* Save the current flags so we can tell if they've changed */
474 flags = s->flags;
475
476 if (cb) {
477 /* The sink implementor is responsible for setting decibel volume support */
478 s->flags |= PA_SINK_HW_VOLUME_CTRL;
479 } else {
480 s->flags &= ~PA_SINK_HW_VOLUME_CTRL;
481 /* See note below in pa_sink_put() about volume sharing and decibel volumes */
482 pa_sink_enable_decibel_volume(s, !(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER));
483 }
484
485 /* If the flags have changed after init, let any clients know via a change event */
486 if (s->state != PA_SINK_INIT && flags != s->flags)
487 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
488 }
489
490 void pa_sink_set_write_volume_callback(pa_sink *s, pa_sink_cb_t cb) {
491 pa_sink_flags_t flags;
492
493 pa_assert(s);
494 pa_assert(!cb || s->set_volume);
495
496 s->write_volume = cb;
497
498 /* Save the current flags so we can tell if they've changed */
499 flags = s->flags;
500
501 if (cb)
502 s->flags |= PA_SINK_DEFERRED_VOLUME;
503 else
504 s->flags &= ~PA_SINK_DEFERRED_VOLUME;
505
506 /* If the flags have changed after init, let any clients know via a change event */
507 if (s->state != PA_SINK_INIT && flags != s->flags)
508 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
509 }
510
511 void pa_sink_set_get_mute_callback(pa_sink *s, pa_sink_cb_t cb) {
512 pa_assert(s);
513
514 s->get_mute = cb;
515 }
516
517 void pa_sink_set_set_mute_callback(pa_sink *s, pa_sink_cb_t cb) {
518 pa_sink_flags_t flags;
519
520 pa_assert(s);
521
522 s->set_mute = cb;
523
524 /* Save the current flags so we can tell if they've changed */
525 flags = s->flags;
526
527 if (cb)
528 s->flags |= PA_SINK_HW_MUTE_CTRL;
529 else
530 s->flags &= ~PA_SINK_HW_MUTE_CTRL;
531
532 /* If the flags have changed after init, let any clients know via a change event */
533 if (s->state != PA_SINK_INIT && flags != s->flags)
534 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
535 }
536
537 static void enable_flat_volume(pa_sink *s, bool enable) {
538 pa_sink_flags_t flags;
539
540 pa_assert(s);
541
542 /* Always follow the overall user preference here */
543 enable = enable && s->core->flat_volumes;
544
545 /* Save the current flags so we can tell if they've changed */
546 flags = s->flags;
547
548 if (enable)
549 s->flags |= PA_SINK_FLAT_VOLUME;
550 else
551 s->flags &= ~PA_SINK_FLAT_VOLUME;
552
553 /* If the flags have changed after init, let any clients know via a change event */
554 if (s->state != PA_SINK_INIT && flags != s->flags)
555 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
556 }
557
558 void pa_sink_enable_decibel_volume(pa_sink *s, bool enable) {
559 pa_sink_flags_t flags;
560
561 pa_assert(s);
562
563 /* Save the current flags so we can tell if they've changed */
564 flags = s->flags;
565
566 if (enable) {
567 s->flags |= PA_SINK_DECIBEL_VOLUME;
568 enable_flat_volume(s, true);
569 } else {
570 s->flags &= ~PA_SINK_DECIBEL_VOLUME;
571 enable_flat_volume(s, false);
572 }
573
574 /* If the flags have changed after init, let any clients know via a change event */
575 if (s->state != PA_SINK_INIT && flags != s->flags)
576 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
577 }
578
579 /* Called from main context */
580 void pa_sink_put(pa_sink* s) {
581 pa_sink_assert_ref(s);
582 pa_assert_ctl_context();
583
584 pa_assert(s->state == PA_SINK_INIT);
585 pa_assert(!(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER) || s->input_to_master);
586
587 /* The following fields must be initialized properly when calling _put() */
588 pa_assert(s->asyncmsgq);
589 pa_assert(s->thread_info.min_latency <= s->thread_info.max_latency);
590
591 /* Generally, flags should be initialized via pa_sink_new(). As a
592 * special exception we allow some volume related flags to be set
593 * between _new() and _put() by the callback setter functions above.
594 *
595 * Thus we implement a couple safeguards here which ensure the above
596 * setters were used (or at least the implementor made manual changes
597 * in a compatible way).
598 *
599 * Note: All of these flags set here can change over the life time
600 * of the sink. */
601 pa_assert(!(s->flags & PA_SINK_HW_VOLUME_CTRL) || s->set_volume);
602 pa_assert(!(s->flags & PA_SINK_DEFERRED_VOLUME) || s->write_volume);
603 pa_assert(!(s->flags & PA_SINK_HW_MUTE_CTRL) || s->set_mute);
604
605 /* XXX: Currently decibel volume is disabled for all sinks that use volume
606 * sharing. When the master sink supports decibel volume, it would be good
607 * to have the flag also in the filter sink, but currently we don't do that
608 * so that the flags of the filter sink never change when it's moved from
609 * a master sink to another. One solution for this problem would be to
610 * remove user-visible volume altogether from filter sinks when volume
611 * sharing is used, but the current approach was easier to implement... */
612 /* We always support decibel volumes in software, otherwise we leave it to
613 * the sink implementor to set this flag as needed.
614 *
615 * Note: This flag can also change over the life time of the sink. */
616 if (!(s->flags & PA_SINK_HW_VOLUME_CTRL) && !(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER))
617 pa_sink_enable_decibel_volume(s, true);
618
619 /* If the sink implementor support DB volumes by itself, we should always
620 * try and enable flat volumes too */
621 if ((s->flags & PA_SINK_DECIBEL_VOLUME))
622 enable_flat_volume(s, true);
623
624 if (s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER) {
625 pa_sink *root_sink = pa_sink_get_master(s);
626
627 pa_assert(root_sink);
628
629 s->reference_volume = root_sink->reference_volume;
630 pa_cvolume_remap(&s->reference_volume, &root_sink->channel_map, &s->channel_map);
631
632 s->real_volume = root_sink->real_volume;
633 pa_cvolume_remap(&s->real_volume, &root_sink->channel_map, &s->channel_map);
634 } else
635 /* We assume that if the sink implementor changed the default
636 * volume he did so in real_volume, because that is the usual
637 * place where he is supposed to place his changes. */
638 s->reference_volume = s->real_volume;
639
640 s->thread_info.soft_volume = s->soft_volume;
641 s->thread_info.soft_muted = s->muted;
642 pa_sw_cvolume_multiply(&s->thread_info.current_hw_volume, &s->soft_volume, &s->real_volume);
643
644 pa_assert((s->flags & PA_SINK_HW_VOLUME_CTRL)
645 || (s->base_volume == PA_VOLUME_NORM
646 && ((s->flags & PA_SINK_DECIBEL_VOLUME || (s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)))));
647 pa_assert(!(s->flags & PA_SINK_DECIBEL_VOLUME) || s->n_volume_steps == PA_VOLUME_NORM+1);
648 pa_assert(!(s->flags & PA_SINK_DYNAMIC_LATENCY) == (s->thread_info.fixed_latency != 0));
649 pa_assert(!(s->flags & PA_SINK_LATENCY) == !(s->monitor_source->flags & PA_SOURCE_LATENCY));
650 pa_assert(!(s->flags & PA_SINK_DYNAMIC_LATENCY) == !(s->monitor_source->flags & PA_SOURCE_DYNAMIC_LATENCY));
651
652 pa_assert(s->monitor_source->thread_info.fixed_latency == s->thread_info.fixed_latency);
653 pa_assert(s->monitor_source->thread_info.min_latency == s->thread_info.min_latency);
654 pa_assert(s->monitor_source->thread_info.max_latency == s->thread_info.max_latency);
655
656 if (s->suspend_cause)
657 pa_assert_se(sink_set_state(s, PA_SINK_SUSPENDED) == 0);
658 else
659 pa_assert_se(sink_set_state(s, PA_SINK_IDLE) == 0);
660
661 pa_source_put(s->monitor_source);
662
663 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_NEW, s->index);
664 pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_PUT], s);
665 }
666
667 /* Called from main context */
668 void pa_sink_unlink(pa_sink* s) {
669 bool linked;
670 pa_sink_input *i, *j = NULL;
671
672 pa_assert(s);
673 pa_assert_ctl_context();
674
675 /* Please note that pa_sink_unlink() does more than simply
676 * reversing pa_sink_put(). It also undoes the registrations
677 * already done in pa_sink_new()! */
678
679 /* All operations here shall be idempotent, i.e. pa_sink_unlink()
680 * may be called multiple times on the same sink without bad
681 * effects. */
682
683 linked = PA_SINK_IS_LINKED(s->state);
684
685 if (linked)
686 pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_UNLINK], s);
687
688 if (s->state != PA_SINK_UNLINKED)
689 pa_namereg_unregister(s->core, s->name);
690 pa_idxset_remove_by_data(s->core->sinks, s, NULL);
691
692 if (s->card)
693 pa_idxset_remove_by_data(s->card->sinks, s, NULL);
694
695 while ((i = pa_idxset_first(s->inputs, NULL))) {
696 pa_assert(i != j);
697 pa_sink_input_kill(i);
698 j = i;
699 }
700
701 if (linked)
702 sink_set_state(s, PA_SINK_UNLINKED);
703 else
704 s->state = PA_SINK_UNLINKED;
705
706 reset_callbacks(s);
707
708 if (s->monitor_source)
709 pa_source_unlink(s->monitor_source);
710
711 if (linked) {
712 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_REMOVE, s->index);
713 pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_UNLINK_POST], s);
714 }
715 }
716
717 /* Called from main context */
718 static void sink_free(pa_object *o) {
719 pa_sink *s = PA_SINK(o);
720
721 pa_assert(s);
722 pa_assert_ctl_context();
723 pa_assert(pa_sink_refcnt(s) == 0);
724
725 if (PA_SINK_IS_LINKED(s->state))
726 pa_sink_unlink(s);
727
728 pa_log_info("Freeing sink %u \"%s\"", s->index, s->name);
729
730 if (s->monitor_source) {
731 pa_source_unref(s->monitor_source);
732 s->monitor_source = NULL;
733 }
734
735 pa_idxset_free(s->inputs, NULL);
736 pa_hashmap_free(s->thread_info.inputs);
737
738 if (s->silence.memblock)
739 pa_memblock_unref(s->silence.memblock);
740
741 pa_xfree(s->name);
742 pa_xfree(s->driver);
743
744 if (s->proplist)
745 pa_proplist_free(s->proplist);
746
747 if (s->ports)
748 pa_hashmap_free(s->ports);
749
750 pa_xfree(s);
751 }
752
753 /* Called from main context, and not while the IO thread is active, please */
754 void pa_sink_set_asyncmsgq(pa_sink *s, pa_asyncmsgq *q) {
755 pa_sink_assert_ref(s);
756 pa_assert_ctl_context();
757
758 s->asyncmsgq = q;
759
760 if (s->monitor_source)
761 pa_source_set_asyncmsgq(s->monitor_source, q);
762 }
763
764 /* Called from main context, and not while the IO thread is active, please */
765 void pa_sink_update_flags(pa_sink *s, pa_sink_flags_t mask, pa_sink_flags_t value) {
766 pa_sink_flags_t old_flags;
767 pa_sink_input *input;
768 uint32_t idx;
769
770 pa_sink_assert_ref(s);
771 pa_assert_ctl_context();
772
773 /* For now, allow only a minimal set of flags to be changed. */
774 pa_assert((mask & ~(PA_SINK_DYNAMIC_LATENCY|PA_SINK_LATENCY)) == 0);
775
776 old_flags = s->flags;
777 s->flags = (s->flags & ~mask) | (value & mask);
778
779 if (s->flags == old_flags)
780 return;
781
782 if ((s->flags & PA_SINK_LATENCY) != (old_flags & PA_SINK_LATENCY))
783 pa_log_debug("Sink %s: LATENCY flag %s.", s->name, (s->flags & PA_SINK_LATENCY) ? "enabled" : "disabled");
784
785 if ((s->flags & PA_SINK_DYNAMIC_LATENCY) != (old_flags & PA_SINK_DYNAMIC_LATENCY))
786 pa_log_debug("Sink %s: DYNAMIC_LATENCY flag %s.",
787 s->name, (s->flags & PA_SINK_DYNAMIC_LATENCY) ? "enabled" : "disabled");
788
789 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
790 pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_FLAGS_CHANGED], s);
791
792 if (s->monitor_source)
793 pa_source_update_flags(s->monitor_source,
794 ((mask & PA_SINK_LATENCY) ? PA_SOURCE_LATENCY : 0) |
795 ((mask & PA_SINK_DYNAMIC_LATENCY) ? PA_SOURCE_DYNAMIC_LATENCY : 0),
796 ((value & PA_SINK_LATENCY) ? PA_SOURCE_LATENCY : 0) |
797 ((value & PA_SINK_DYNAMIC_LATENCY) ? PA_SOURCE_DYNAMIC_LATENCY : 0));
798
799 PA_IDXSET_FOREACH(input, s->inputs, idx) {
800 if (input->origin_sink)
801 pa_sink_update_flags(input->origin_sink, mask, value);
802 }
803 }
804
805 /* Called from IO context, or before _put() from main context */
806 void pa_sink_set_rtpoll(pa_sink *s, pa_rtpoll *p) {
807 pa_sink_assert_ref(s);
808 pa_sink_assert_io_context(s);
809
810 s->thread_info.rtpoll = p;
811
812 if (s->monitor_source)
813 pa_source_set_rtpoll(s->monitor_source, p);
814 }
815
816 /* Called from main context */
817 int pa_sink_update_status(pa_sink*s) {
818 pa_sink_assert_ref(s);
819 pa_assert_ctl_context();
820 pa_assert(PA_SINK_IS_LINKED(s->state));
821
822 if (s->state == PA_SINK_SUSPENDED)
823 return 0;
824
825 return sink_set_state(s, pa_sink_used_by(s) ? PA_SINK_RUNNING : PA_SINK_IDLE);
826 }
827
828 /* Called from any context - must be threadsafe */
829 void pa_sink_set_mixer_dirty(pa_sink *s, bool is_dirty) {
830 pa_atomic_store(&s->mixer_dirty, is_dirty ? 1 : 0);
831 }
832
833 /* Called from main context */
834 int pa_sink_suspend(pa_sink *s, bool suspend, pa_suspend_cause_t cause) {
835 pa_sink_assert_ref(s);
836 pa_assert_ctl_context();
837 pa_assert(PA_SINK_IS_LINKED(s->state));
838 pa_assert(cause != 0);
839
840 if (suspend) {
841 s->suspend_cause |= cause;
842 s->monitor_source->suspend_cause |= cause;
843 } else {
844 s->suspend_cause &= ~cause;
845 s->monitor_source->suspend_cause &= ~cause;
846 }
847
848 if (!(s->suspend_cause & PA_SUSPEND_SESSION) && (pa_atomic_load(&s->mixer_dirty) != 0)) {
849 /* This might look racy but isn't: If somebody sets mixer_dirty exactly here,
850 it'll be handled just fine. */
851 pa_sink_set_mixer_dirty(s, false);
852 pa_log_debug("Mixer is now accessible. Updating alsa mixer settings.");
853 if (s->active_port && s->set_port) {
854 if (s->flags & PA_SINK_DEFERRED_VOLUME) {
855 struct sink_message_set_port msg = { .port = s->active_port, .ret = 0 };
856 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_PORT, &msg, 0, NULL) == 0);
857 }
858 else
859 s->set_port(s, s->active_port);
860 }
861 else {
862 if (s->set_mute)
863 s->set_mute(s);
864 if (s->set_volume)
865 s->set_volume(s);
866 }
867 }
868
869 if ((pa_sink_get_state(s) == PA_SINK_SUSPENDED) == !!s->suspend_cause)
870 return 0;
871
872 pa_log_debug("Suspend cause of sink %s is 0x%04x, %s", s->name, s->suspend_cause, s->suspend_cause ? "suspending" : "resuming");
873
874 if (s->suspend_cause)
875 return sink_set_state(s, PA_SINK_SUSPENDED);
876 else
877 return sink_set_state(s, pa_sink_used_by(s) ? PA_SINK_RUNNING : PA_SINK_IDLE);
878 }
879
880 /* Called from main context */
881 pa_queue *pa_sink_move_all_start(pa_sink *s, pa_queue *q) {
882 pa_sink_input *i, *n;
883 uint32_t idx;
884
885 pa_sink_assert_ref(s);
886 pa_assert_ctl_context();
887 pa_assert(PA_SINK_IS_LINKED(s->state));
888
889 if (!q)
890 q = pa_queue_new();
891
892 for (i = PA_SINK_INPUT(pa_idxset_first(s->inputs, &idx)); i; i = n) {
893 n = PA_SINK_INPUT(pa_idxset_next(s->inputs, &idx));
894
895 pa_sink_input_ref(i);
896
897 if (pa_sink_input_start_move(i) >= 0)
898 pa_queue_push(q, i);
899 else
900 pa_sink_input_unref(i);
901 }
902
903 return q;
904 }
905
906 /* Called from main context */
907 void pa_sink_move_all_finish(pa_sink *s, pa_queue *q, bool save) {
908 pa_sink_input *i;
909
910 pa_sink_assert_ref(s);
911 pa_assert_ctl_context();
912 pa_assert(PA_SINK_IS_LINKED(s->state));
913 pa_assert(q);
914
915 while ((i = PA_SINK_INPUT(pa_queue_pop(q)))) {
916 if (pa_sink_input_finish_move(i, s, save) < 0)
917 pa_sink_input_fail_move(i);
918
919 pa_sink_input_unref(i);
920 }
921
922 pa_queue_free(q, NULL);
923 }
924
925 /* Called from main context */
926 void pa_sink_move_all_fail(pa_queue *q) {
927 pa_sink_input *i;
928
929 pa_assert_ctl_context();
930 pa_assert(q);
931
932 while ((i = PA_SINK_INPUT(pa_queue_pop(q)))) {
933 pa_sink_input_fail_move(i);
934 pa_sink_input_unref(i);
935 }
936
937 pa_queue_free(q, NULL);
938 }
939
940 /* Called from IO thread context */
941 size_t pa_sink_process_input_underruns(pa_sink *s, size_t left_to_play) {
942 pa_sink_input *i;
943 void *state = NULL;
944 size_t result = 0;
945
946 pa_sink_assert_ref(s);
947 pa_sink_assert_io_context(s);
948
949 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state) {
950 size_t uf = i->thread_info.underrun_for_sink;
951 if (uf == 0)
952 continue;
953 if (uf >= left_to_play) {
954 if (pa_sink_input_process_underrun(i))
955 continue;
956 }
957 else if (uf > result)
958 result = uf;
959 }
960
961 if (result > 0)
962 pa_log_debug("Found underrun %ld bytes ago (%ld bytes ahead in playback buffer)", (long) result, (long) left_to_play - result);
963 return left_to_play - result;
964 }
965
966 /* Called from IO thread context */
967 void pa_sink_process_rewind(pa_sink *s, size_t nbytes) {
968 pa_sink_input *i;
969 void *state = NULL;
970
971 pa_sink_assert_ref(s);
972 pa_sink_assert_io_context(s);
973 pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
974
975 /* If nobody requested this and this is actually no real rewind
976 * then we can short cut this. Please note that this means that
977 * not all rewind requests triggered upstream will always be
978 * translated in actual requests! */
979 if (!s->thread_info.rewind_requested && nbytes <= 0)
980 return;
981
982 s->thread_info.rewind_nbytes = 0;
983 s->thread_info.rewind_requested = false;
984
985 if (nbytes > 0) {
986 pa_log_debug("Processing rewind...");
987 if (s->flags & PA_SINK_DEFERRED_VOLUME)
988 pa_sink_volume_change_rewind(s, nbytes);
989 }
990
991 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state) {
992 pa_sink_input_assert_ref(i);
993 pa_sink_input_process_rewind(i, nbytes);
994 }
995
996 if (nbytes > 0) {
997 if (s->monitor_source && PA_SOURCE_IS_LINKED(s->monitor_source->thread_info.state))
998 pa_source_process_rewind(s->monitor_source, nbytes);
999 }
1000 }
1001
1002 /* Called from IO thread context */
1003 static unsigned fill_mix_info(pa_sink *s, size_t *length, pa_mix_info *info, unsigned maxinfo) {
1004 pa_sink_input *i;
1005 unsigned n = 0;
1006 void *state = NULL;
1007 size_t mixlength = *length;
1008
1009 pa_sink_assert_ref(s);
1010 pa_sink_assert_io_context(s);
1011 pa_assert(info);
1012
1013 while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)) && maxinfo > 0) {
1014 pa_sink_input_assert_ref(i);
1015
1016 pa_sink_input_peek(i, *length, &info->chunk, &info->volume);
1017
1018 if (mixlength == 0 || info->chunk.length < mixlength)
1019 mixlength = info->chunk.length;
1020
1021 if (pa_memblock_is_silence(info->chunk.memblock)) {
1022 pa_memblock_unref(info->chunk.memblock);
1023 continue;
1024 }
1025
1026 info->userdata = pa_sink_input_ref(i);
1027
1028 pa_assert(info->chunk.memblock);
1029 pa_assert(info->chunk.length > 0);
1030
1031 info++;
1032 n++;
1033 maxinfo--;
1034 }
1035
1036 if (mixlength > 0)
1037 *length = mixlength;
1038
1039 return n;
1040 }
1041
1042 /* Called from IO thread context */
1043 static void inputs_drop(pa_sink *s, pa_mix_info *info, unsigned n, pa_memchunk *result) {
1044 pa_sink_input *i;
1045 void *state;
1046 unsigned p = 0;
1047 unsigned n_unreffed = 0;
1048
1049 pa_sink_assert_ref(s);
1050 pa_sink_assert_io_context(s);
1051 pa_assert(result);
1052 pa_assert(result->memblock);
1053 pa_assert(result->length > 0);
1054
1055 /* We optimize for the case where the order of the inputs has not changed */
1056
1057 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state) {
1058 unsigned j;
1059 pa_mix_info* m = NULL;
1060
1061 pa_sink_input_assert_ref(i);
1062
1063 /* Let's try to find the matching entry info the pa_mix_info array */
1064 for (j = 0; j < n; j ++) {
1065
1066 if (info[p].userdata == i) {
1067 m = info + p;
1068 break;
1069 }
1070
1071 p++;
1072 if (p >= n)
1073 p = 0;
1074 }
1075
1076 /* Drop read data */
1077 pa_sink_input_drop(i, result->length);
1078
1079 if (s->monitor_source && PA_SOURCE_IS_LINKED(s->monitor_source->thread_info.state)) {
1080
1081 if (pa_hashmap_size(i->thread_info.direct_outputs) > 0) {
1082 void *ostate = NULL;
1083 pa_source_output *o;
1084 pa_memchunk c;
1085
1086 if (m && m->chunk.memblock) {
1087 c = m->chunk;
1088 pa_memblock_ref(c.memblock);
1089 pa_assert(result->length <= c.length);
1090 c.length = result->length;
1091
1092 pa_memchunk_make_writable(&c, 0);
1093 pa_volume_memchunk(&c, &s->sample_spec, &m->volume);
1094 } else {
1095 c = s->silence;
1096 pa_memblock_ref(c.memblock);
1097 pa_assert(result->length <= c.length);
1098 c.length = result->length;
1099 }
1100
1101 while ((o = pa_hashmap_iterate(i->thread_info.direct_outputs, &ostate, NULL))) {
1102 pa_source_output_assert_ref(o);
1103 pa_assert(o->direct_on_input == i);
1104 pa_source_post_direct(s->monitor_source, o, &c);
1105 }
1106
1107 pa_memblock_unref(c.memblock);
1108 }
1109 }
1110
1111 if (m) {
1112 if (m->chunk.memblock) {
1113 pa_memblock_unref(m->chunk.memblock);
1114 pa_memchunk_reset(&m->chunk);
1115 }
1116
1117 pa_sink_input_unref(m->userdata);
1118 m->userdata = NULL;
1119
1120 n_unreffed += 1;
1121 }
1122 }
1123
1124 /* Now drop references to entries that are included in the
1125 * pa_mix_info array but don't exist anymore */
1126
1127 if (n_unreffed < n) {
1128 for (; n > 0; info++, n--) {
1129 if (info->userdata)
1130 pa_sink_input_unref(info->userdata);
1131 if (info->chunk.memblock)
1132 pa_memblock_unref(info->chunk.memblock);
1133 }
1134 }
1135
1136 if (s->monitor_source && PA_SOURCE_IS_LINKED(s->monitor_source->thread_info.state))
1137 pa_source_post(s->monitor_source, result);
1138 }
1139
1140 /* Called from IO thread context */
1141 void pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) {
1142 pa_mix_info info[MAX_MIX_CHANNELS];
1143 unsigned n;
1144 size_t block_size_max;
1145
1146 pa_sink_assert_ref(s);
1147 pa_sink_assert_io_context(s);
1148 pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
1149 pa_assert(pa_frame_aligned(length, &s->sample_spec));
1150 pa_assert(result);
1151
1152 pa_assert(!s->thread_info.rewind_requested);
1153 pa_assert(s->thread_info.rewind_nbytes == 0);
1154
1155 if (s->thread_info.state == PA_SINK_SUSPENDED) {
1156 result->memblock = pa_memblock_ref(s->silence.memblock);
1157 result->index = s->silence.index;
1158 result->length = PA_MIN(s->silence.length, length);
1159 return;
1160 }
1161
1162 pa_sink_ref(s);
1163
1164 if (length <= 0)
1165 length = pa_frame_align(MIX_BUFFER_LENGTH, &s->sample_spec);
1166
1167 block_size_max = pa_mempool_block_size_max(s->core->mempool);
1168 if (length > block_size_max)
1169 length = pa_frame_align(block_size_max, &s->sample_spec);
1170
1171 pa_assert(length > 0);
1172
1173 n = fill_mix_info(s, &length, info, MAX_MIX_CHANNELS);
1174
1175 if (n == 0) {
1176
1177 *result = s->silence;
1178 pa_memblock_ref(result->memblock);
1179
1180 if (result->length > length)
1181 result->length = length;
1182
1183 } else if (n == 1) {
1184 pa_cvolume volume;
1185
1186 *result = info[0].chunk;
1187 pa_memblock_ref(result->memblock);
1188
1189 if (result->length > length)
1190 result->length = length;
1191
1192 pa_sw_cvolume_multiply(&volume, &s->thread_info.soft_volume, &info[0].volume);
1193
1194 if (s->thread_info.soft_muted || pa_cvolume_is_muted(&volume)) {
1195 pa_memblock_unref(result->memblock);
1196 pa_silence_memchunk_get(&s->core->silence_cache,
1197 s->core->mempool,
1198 result,
1199 &s->sample_spec,
1200 result->length);
1201 } else if (!pa_cvolume_is_norm(&volume)) {
1202 pa_memchunk_make_writable(result, 0);
1203 pa_volume_memchunk(result, &s->sample_spec, &volume);
1204 }
1205 } else {
1206 void *ptr;
1207 result->memblock = pa_memblock_new(s->core->mempool, length);
1208
1209 ptr = pa_memblock_acquire(result->memblock);
1210 result->length = pa_mix(info, n,
1211 ptr, length,
1212 &s->sample_spec,
1213 &s->thread_info.soft_volume,
1214 s->thread_info.soft_muted);
1215 pa_memblock_release(result->memblock);
1216
1217 result->index = 0;
1218 }
1219
1220 inputs_drop(s, info, n, result);
1221
1222 pa_sink_unref(s);
1223 }
1224
1225 /* Called from IO thread context */
1226 void pa_sink_render_into(pa_sink*s, pa_memchunk *target) {
1227 pa_mix_info info[MAX_MIX_CHANNELS];
1228 unsigned n;
1229 size_t length, block_size_max;
1230
1231 pa_sink_assert_ref(s);
1232 pa_sink_assert_io_context(s);
1233 pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
1234 pa_assert(target);
1235 pa_assert(target->memblock);
1236 pa_assert(target->length > 0);
1237 pa_assert(pa_frame_aligned(target->length, &s->sample_spec));
1238
1239 pa_assert(!s->thread_info.rewind_requested);
1240 pa_assert(s->thread_info.rewind_nbytes == 0);
1241
1242 if (s->thread_info.state == PA_SINK_SUSPENDED) {
1243 pa_silence_memchunk(target, &s->sample_spec);
1244 return;
1245 }
1246
1247 pa_sink_ref(s);
1248
1249 length = target->length;
1250 block_size_max = pa_mempool_block_size_max(s->core->mempool);
1251 if (length > block_size_max)
1252 length = pa_frame_align(block_size_max, &s->sample_spec);
1253
1254 pa_assert(length > 0);
1255
1256 n = fill_mix_info(s, &length, info, MAX_MIX_CHANNELS);
1257
1258 if (n == 0) {
1259 if (target->length > length)
1260 target->length = length;
1261
1262 pa_silence_memchunk(target, &s->sample_spec);
1263 } else if (n == 1) {
1264 pa_cvolume volume;
1265
1266 if (target->length > length)
1267 target->length = length;
1268
1269 pa_sw_cvolume_multiply(&volume, &s->thread_info.soft_volume, &info[0].volume);
1270
1271 if (s->thread_info.soft_muted || pa_cvolume_is_muted(&volume))
1272 pa_silence_memchunk(target, &s->sample_spec);
1273 else {
1274 pa_memchunk vchunk;
1275
1276 vchunk = info[0].chunk;
1277 pa_memblock_ref(vchunk.memblock);
1278
1279 if (vchunk.length > length)
1280 vchunk.length = length;
1281
1282 if (!pa_cvolume_is_norm(&volume)) {
1283 pa_memchunk_make_writable(&vchunk, 0);
1284 pa_volume_memchunk(&vchunk, &s->sample_spec, &volume);
1285 }
1286
1287 pa_memchunk_memcpy(target, &vchunk);
1288 pa_memblock_unref(vchunk.memblock);
1289 }
1290
1291 } else {
1292 void *ptr;
1293
1294 ptr = pa_memblock_acquire(target->memblock);
1295
1296 target->length = pa_mix(info, n,
1297 (uint8_t*) ptr + target->index, length,
1298 &s->sample_spec,
1299 &s->thread_info.soft_volume,
1300 s->thread_info.soft_muted);
1301
1302 pa_memblock_release(target->memblock);
1303 }
1304
1305 inputs_drop(s, info, n, target);
1306
1307 pa_sink_unref(s);
1308 }
1309
1310 /* Called from IO thread context */
1311 void pa_sink_render_into_full(pa_sink *s, pa_memchunk *target) {
1312 pa_memchunk chunk;
1313 size_t l, d;
1314
1315 pa_sink_assert_ref(s);
1316 pa_sink_assert_io_context(s);
1317 pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
1318 pa_assert(target);
1319 pa_assert(target->memblock);
1320 pa_assert(target->length > 0);
1321 pa_assert(pa_frame_aligned(target->length, &s->sample_spec));
1322
1323 pa_assert(!s->thread_info.rewind_requested);
1324 pa_assert(s->thread_info.rewind_nbytes == 0);
1325
1326 if (s->thread_info.state == PA_SINK_SUSPENDED) {
1327 pa_silence_memchunk(target, &s->sample_spec);
1328 return;
1329 }
1330
1331 pa_sink_ref(s);
1332
1333 l = target->length;
1334 d = 0;
1335 while (l > 0) {
1336 chunk = *target;
1337 chunk.index += d;
1338 chunk.length -= d;
1339
1340 pa_sink_render_into(s, &chunk);
1341
1342 d += chunk.length;
1343 l -= chunk.length;
1344 }
1345
1346 pa_sink_unref(s);
1347 }
1348
1349 /* Called from IO thread context */
1350 void pa_sink_render_full(pa_sink *s, size_t length, pa_memchunk *result) {
1351 pa_sink_assert_ref(s);
1352 pa_sink_assert_io_context(s);
1353 pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
1354 pa_assert(length > 0);
1355 pa_assert(pa_frame_aligned(length, &s->sample_spec));
1356 pa_assert(result);
1357
1358 pa_assert(!s->thread_info.rewind_requested);
1359 pa_assert(s->thread_info.rewind_nbytes == 0);
1360
1361 pa_sink_ref(s);
1362
1363 pa_sink_render(s, length, result);
1364
1365 if (result->length < length) {
1366 pa_memchunk chunk;
1367
1368 pa_memchunk_make_writable(result, length);
1369
1370 chunk.memblock = result->memblock;
1371 chunk.index = result->index + result->length;
1372 chunk.length = length - result->length;
1373
1374 pa_sink_render_into_full(s, &chunk);
1375
1376 result->length = length;
1377 }
1378
1379 pa_sink_unref(s);
1380 }
1381
1382 /* Called from main thread */
1383 int pa_sink_update_rate(pa_sink *s, uint32_t rate, bool passthrough) {
1384 int ret = -1;
1385 uint32_t desired_rate = rate;
1386 uint32_t default_rate = s->default_sample_rate;
1387 uint32_t alternate_rate = s->alternate_sample_rate;
1388 uint32_t idx;
1389 pa_sink_input *i;
1390 bool use_alternate = false;
1391
1392 if (rate == s->sample_spec.rate)
1393 return 0;
1394
1395 if (!s->update_rate)
1396 return -1;
1397
1398 if (PA_UNLIKELY(default_rate == alternate_rate && !passthrough)) {
1399 pa_log_debug("Default and alternate sample rates are the same.");
1400 return -1;
1401 }
1402
1403 if (PA_SINK_IS_RUNNING(s->state)) {
1404 pa_log_info("Cannot update rate, SINK_IS_RUNNING, will keep using %u Hz",
1405 s->sample_spec.rate);
1406 return -1;
1407 }
1408
1409 if (s->monitor_source) {
1410 if (PA_SOURCE_IS_RUNNING(s->monitor_source->state) == true) {
1411 pa_log_info("Cannot update rate, monitor source is RUNNING");
1412 return -1;
1413 }
1414 }
1415
1416 if (PA_UNLIKELY(!pa_sample_rate_valid(desired_rate)))
1417 return -1;
1418
1419 if (!passthrough) {
1420 pa_assert((default_rate % 4000 == 0) || (default_rate % 11025 == 0));
1421 pa_assert((alternate_rate % 4000 == 0) || (alternate_rate % 11025 == 0));
1422
1423 if (default_rate % 11025 == 0) {
1424 if ((alternate_rate % 4000 == 0) && (desired_rate % 4000 == 0))
1425 use_alternate=true;
1426 } else {
1427 /* default is 4000 multiple */
1428 if ((alternate_rate % 11025 == 0) && (desired_rate % 11025 == 0))
1429 use_alternate=true;
1430 }
1431
1432 if (use_alternate)
1433 desired_rate = alternate_rate;
1434 else
1435 desired_rate = default_rate;
1436 } else {
1437 desired_rate = rate; /* use stream sampling rate, discard default/alternate settings */
1438 }
1439
1440 if (desired_rate == s->sample_spec.rate)
1441 return -1;
1442
1443 if (!passthrough && pa_sink_used_by(s) > 0)
1444 return -1;
1445
1446 pa_log_debug("Suspending sink %s due to changing the sample rate.", s->name);
1447 pa_sink_suspend(s, true, PA_SUSPEND_INTERNAL);
1448
1449 if (s->update_rate(s, desired_rate) >= 0) {
1450 /* update monitor source as well */
1451 if (s->monitor_source && !passthrough)
1452 pa_source_update_rate(s->monitor_source, desired_rate, false);
1453 pa_log_info("Changed sampling rate successfully");
1454
1455 PA_IDXSET_FOREACH(i, s->inputs, idx) {
1456 if (i->state == PA_SINK_INPUT_CORKED)
1457 pa_sink_input_update_rate(i);
1458 }
1459
1460 ret = 0;
1461 }
1462
1463 pa_sink_suspend(s, false, PA_SUSPEND_INTERNAL);
1464
1465 return ret;
1466 }
1467
1468 /* Called from main thread */
1469 pa_usec_t pa_sink_get_latency(pa_sink *s) {
1470 pa_usec_t usec = 0;
1471
1472 pa_sink_assert_ref(s);
1473 pa_assert_ctl_context();
1474 pa_assert(PA_SINK_IS_LINKED(s->state));
1475
1476 /* The returned value is supposed to be in the time domain of the sound card! */
1477
1478 if (s->state == PA_SINK_SUSPENDED)
1479 return 0;
1480
1481 if (!(s->flags & PA_SINK_LATENCY))
1482 return 0;
1483
1484 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_LATENCY, &usec, 0, NULL) == 0);
1485
1486 /* usec is unsigned, so check that the offset can be added to usec without
1487 * underflowing. */
1488 if (-s->latency_offset <= (int64_t) usec)
1489 usec += s->latency_offset;
1490 else
1491 usec = 0;
1492
1493 return usec;
1494 }
1495
1496 /* Called from IO thread */
1497 pa_usec_t pa_sink_get_latency_within_thread(pa_sink *s) {
1498 pa_usec_t usec = 0;
1499 pa_msgobject *o;
1500
1501 pa_sink_assert_ref(s);
1502 pa_sink_assert_io_context(s);
1503 pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
1504
1505 /* The returned value is supposed to be in the time domain of the sound card! */
1506
1507 if (s->thread_info.state == PA_SINK_SUSPENDED)
1508 return 0;
1509
1510 if (!(s->flags & PA_SINK_LATENCY))
1511 return 0;
1512
1513 o = PA_MSGOBJECT(s);
1514
1515 /* FIXME: We probably should make this a proper vtable callback instead of going through process_msg() */
1516
1517 if (o->process_msg(o, PA_SINK_MESSAGE_GET_LATENCY, &usec, 0, NULL) < 0)
1518 return -1;
1519
1520 /* usec is unsigned, so check that the offset can be added to usec without
1521 * underflowing. */
1522 if (-s->thread_info.latency_offset <= (int64_t) usec)
1523 usec += s->thread_info.latency_offset;
1524 else
1525 usec = 0;
1526
1527 return usec;
1528 }
1529
1530 /* Called from the main thread (and also from the IO thread while the main
1531 * thread is waiting).
1532 *
1533 * When a sink uses volume sharing, it never has the PA_SINK_FLAT_VOLUME flag
1534 * set. Instead, flat volume mode is detected by checking whether the root sink
1535 * has the flag set. */
1536 bool pa_sink_flat_volume_enabled(pa_sink *s) {
1537 pa_sink_assert_ref(s);
1538
1539 s = pa_sink_get_master(s);
1540
1541 if (PA_LIKELY(s))
1542 return (s->flags & PA_SINK_FLAT_VOLUME);
1543 else
1544 return false;
1545 }
1546
1547 /* Called from the main thread (and also from the IO thread while the main
1548 * thread is waiting). */
1549 pa_sink *pa_sink_get_master(pa_sink *s) {
1550 pa_sink_assert_ref(s);
1551
1552 while (s && (s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)) {
1553 if (PA_UNLIKELY(!s->input_to_master))
1554 return NULL;
1555
1556 s = s->input_to_master->sink;
1557 }
1558
1559 return s;
1560 }
1561
1562 /* Called from main context */
1563 bool pa_sink_is_passthrough(pa_sink *s) {
1564 pa_sink_input *alt_i;
1565 uint32_t idx;
1566
1567 pa_sink_assert_ref(s);
1568
1569 /* one and only one PASSTHROUGH input can possibly be connected */
1570 if (pa_idxset_size(s->inputs) == 1) {
1571 alt_i = pa_idxset_first(s->inputs, &idx);
1572
1573 if (pa_sink_input_is_passthrough(alt_i))
1574 return true;
1575 }
1576
1577 return false;
1578 }
1579
1580 /* Called from main context */
1581 void pa_sink_enter_passthrough(pa_sink *s) {
1582 pa_cvolume volume;
1583
1584 /* disable the monitor in passthrough mode */
1585 if (s->monitor_source) {
1586 pa_log_debug("Suspending monitor source %s, because the sink is entering the passthrough mode.", s->monitor_source->name);
1587 pa_source_suspend(s->monitor_source, true, PA_SUSPEND_PASSTHROUGH);
1588 }
1589
1590 /* set the volume to NORM */
1591 s->saved_volume = *pa_sink_get_volume(s, true);
1592 s->saved_save_volume = s->save_volume;
1593
1594 pa_cvolume_set(&volume, s->sample_spec.channels, PA_MIN(s->base_volume, PA_VOLUME_NORM));
1595 pa_sink_set_volume(s, &volume, true, false);
1596 }
1597
1598 /* Called from main context */
1599 void pa_sink_leave_passthrough(pa_sink *s) {
1600 /* Unsuspend monitor */
1601 if (s->monitor_source) {
1602 pa_log_debug("Resuming monitor source %s, because the sink is leaving the passthrough mode.", s->monitor_source->name);
1603 pa_source_suspend(s->monitor_source, false, PA_SUSPEND_PASSTHROUGH);
1604 }
1605
1606 /* Restore sink volume to what it was before we entered passthrough mode */
1607 pa_sink_set_volume(s, &s->saved_volume, true, s->saved_save_volume);
1608
1609 pa_cvolume_init(&s->saved_volume);
1610 s->saved_save_volume = false;
1611 }
1612
1613 /* Called from main context. */
1614 static void compute_reference_ratio(pa_sink_input *i) {
1615 unsigned c = 0;
1616 pa_cvolume remapped;
1617
1618 pa_assert(i);
1619 pa_assert(pa_sink_flat_volume_enabled(i->sink));
1620
1621 /*
1622 * Calculates the reference ratio from the sink's reference
1623 * volume. This basically calculates:
1624 *
1625 * i->reference_ratio = i->volume / i->sink->reference_volume
1626 */
1627
1628 remapped = i->sink->reference_volume;
1629 pa_cvolume_remap(&remapped, &i->sink->channel_map, &i->channel_map);
1630
1631 i->reference_ratio.channels = i->sample_spec.channels;
1632
1633 for (c = 0; c < i->sample_spec.channels; c++) {
1634
1635 /* We don't update when the sink volume is 0 anyway */
1636 if (remapped.values[c] <= PA_VOLUME_MUTED)
1637 continue;
1638
1639 /* Don't update the reference ratio unless necessary */
1640 if (pa_sw_volume_multiply(
1641 i->reference_ratio.values[c],
1642 remapped.values[c]) == i->volume.values[c])
1643 continue;
1644
1645 i->reference_ratio.values[c] = pa_sw_volume_divide(
1646 i->volume.values[c],
1647 remapped.values[c]);
1648 }
1649 }
1650
1651 /* Called from main context. Only called for the root sink in volume sharing
1652 * cases, except for internal recursive calls. */
1653 static void compute_reference_ratios(pa_sink *s) {
1654 uint32_t idx;
1655 pa_sink_input *i;
1656
1657 pa_sink_assert_ref(s);
1658 pa_assert_ctl_context();
1659 pa_assert(PA_SINK_IS_LINKED(s->state));
1660 pa_assert(pa_sink_flat_volume_enabled(s));
1661
1662 PA_IDXSET_FOREACH(i, s->inputs, idx) {
1663 compute_reference_ratio(i);
1664
1665 if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER))
1666 compute_reference_ratios(i->origin_sink);
1667 }
1668 }
1669
1670 /* Called from main context. Only called for the root sink in volume sharing
1671 * cases, except for internal recursive calls. */
1672 static void compute_real_ratios(pa_sink *s) {
1673 pa_sink_input *i;
1674 uint32_t idx;
1675
1676 pa_sink_assert_ref(s);
1677 pa_assert_ctl_context();
1678 pa_assert(PA_SINK_IS_LINKED(s->state));
1679 pa_assert(pa_sink_flat_volume_enabled(s));
1680
1681 PA_IDXSET_FOREACH(i, s->inputs, idx) {
1682 unsigned c;
1683 pa_cvolume remapped;
1684
1685 if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)) {
1686 /* The origin sink uses volume sharing, so this input's real ratio
1687 * is handled as a special case - the real ratio must be 0 dB, and
1688 * as a result i->soft_volume must equal i->volume_factor. */
1689 pa_cvolume_reset(&i->real_ratio, i->real_ratio.channels);
1690 i->soft_volume = i->volume_factor;
1691
1692 compute_real_ratios(i->origin_sink);
1693
1694 continue;
1695 }
1696
1697 /*
1698 * This basically calculates:
1699 *
1700 * i->real_ratio := i->volume / s->real_volume
1701 * i->soft_volume := i->real_ratio * i->volume_factor
1702 */
1703
1704 remapped = s->real_volume;
1705 pa_cvolume_remap(&remapped, &s->channel_map, &i->channel_map);
1706
1707 i->real_ratio.channels = i->sample_spec.channels;
1708 i->soft_volume.channels = i->sample_spec.channels;
1709
1710 for (c = 0; c < i->sample_spec.channels; c++) {
1711
1712 if (remapped.values[c] <= PA_VOLUME_MUTED) {
1713 /* We leave i->real_ratio untouched */
1714 i->soft_volume.values[c] = PA_VOLUME_MUTED;
1715 continue;
1716 }
1717
1718 /* Don't lose accuracy unless necessary */
1719 if (pa_sw_volume_multiply(
1720 i->real_ratio.values[c],
1721 remapped.values[c]) != i->volume.values[c])
1722
1723 i->real_ratio.values[c] = pa_sw_volume_divide(
1724 i->volume.values[c],
1725 remapped.values[c]);
1726
1727 i->soft_volume.values[c] = pa_sw_volume_multiply(
1728 i->real_ratio.values[c],
1729 i->volume_factor.values[c]);
1730 }
1731
1732 /* We don't copy the soft_volume to the thread_info data
1733 * here. That must be done by the caller */
1734 }
1735 }
1736
1737 static pa_cvolume *cvolume_remap_minimal_impact(
1738 pa_cvolume *v,
1739 const pa_cvolume *template,
1740 const pa_channel_map *from,
1741 const pa_channel_map *to) {
1742
1743 pa_cvolume t;
1744
1745 pa_assert(v);
1746 pa_assert(template);
1747 pa_assert(from);
1748 pa_assert(to);
1749 pa_assert(pa_cvolume_compatible_with_channel_map(v, from));
1750 pa_assert(pa_cvolume_compatible_with_channel_map(template, to));
1751
1752 /* Much like pa_cvolume_remap(), but tries to minimize impact when
1753 * mapping from sink input to sink volumes:
1754 *
1755 * If template is a possible remapping from v it is used instead
1756 * of remapping anew.
1757 *
1758 * If the channel maps don't match we set an all-channel volume on
1759 * the sink to ensure that changing a volume on one stream has no
1760 * effect that cannot be compensated for in another stream that
1761 * does not have the same channel map as the sink. */
1762
1763 if (pa_channel_map_equal(from, to))
1764 return v;
1765
1766 t = *template;
1767 if (pa_cvolume_equal(pa_cvolume_remap(&t, to, from), v)) {
1768 *v = *template;
1769 return v;
1770 }
1771
1772 pa_cvolume_set(v, to->channels, pa_cvolume_max(v));
1773 return v;
1774 }
1775
1776 /* Called from main thread. Only called for the root sink in volume sharing
1777 * cases, except for internal recursive calls. */
1778 static void get_maximum_input_volume(pa_sink *s, pa_cvolume *max_volume, const pa_channel_map *channel_map) {
1779 pa_sink_input *i;
1780 uint32_t idx;
1781
1782 pa_sink_assert_ref(s);
1783 pa_assert(max_volume);
1784 pa_assert(channel_map);
1785 pa_assert(pa_sink_flat_volume_enabled(s));
1786
1787 PA_IDXSET_FOREACH(i, s->inputs, idx) {
1788 pa_cvolume remapped;
1789
1790 if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)) {
1791 get_maximum_input_volume(i->origin_sink, max_volume, channel_map);
1792
1793 /* Ignore this input. The origin sink uses volume sharing, so this
1794 * input's volume will be set to be equal to the root sink's real
1795 * volume. Obviously this input's current volume must not then
1796 * affect what the root sink's real volume will be. */
1797 continue;
1798 }
1799
1800 remapped = i->volume;
1801 cvolume_remap_minimal_impact(&remapped, max_volume, &i->channel_map, channel_map);
1802 pa_cvolume_merge(max_volume, max_volume, &remapped);
1803 }
1804 }
1805
1806 /* Called from main thread. Only called for the root sink in volume sharing
1807 * cases, except for internal recursive calls. */
1808 static bool has_inputs(pa_sink *s) {
1809 pa_sink_input *i;
1810 uint32_t idx;
1811
1812 pa_sink_assert_ref(s);
1813
1814 PA_IDXSET_FOREACH(i, s->inputs, idx) {
1815 if (!i->origin_sink || !(i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER) || has_inputs(i->origin_sink))
1816 return true;
1817 }
1818
1819 return false;
1820 }
1821
1822 /* Called from main thread. Only called for the root sink in volume sharing
1823 * cases, except for internal recursive calls. */
1824 static void update_real_volume(pa_sink *s, const pa_cvolume *new_volume, pa_channel_map *channel_map) {
1825 pa_sink_input *i;
1826 uint32_t idx;
1827
1828 pa_sink_assert_ref(s);
1829 pa_assert(new_volume);
1830 pa_assert(channel_map);
1831
1832 s->real_volume = *new_volume;
1833 pa_cvolume_remap(&s->real_volume, channel_map, &s->channel_map);
1834
1835 PA_IDXSET_FOREACH(i, s->inputs, idx) {
1836 if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)) {
1837 if (pa_sink_flat_volume_enabled(s)) {
1838 pa_cvolume old_volume = i->volume;
1839
1840 /* Follow the root sink's real volume. */
1841 i->volume = *new_volume;
1842 pa_cvolume_remap(&i->volume, channel_map, &i->channel_map);
1843 compute_reference_ratio(i);
1844
1845 /* The volume changed, let's tell people so */
1846 if (!pa_cvolume_equal(&old_volume, &i->volume)) {
1847 if (i->volume_changed)
1848 i->volume_changed(i);
1849
1850 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1851 }
1852 }
1853
1854 update_real_volume(i->origin_sink, new_volume, channel_map);
1855 }
1856 }
1857 }
1858
1859 /* Called from main thread. Only called for the root sink in shared volume
1860 * cases. */
1861 static void compute_real_volume(pa_sink *s) {
1862 pa_sink_assert_ref(s);
1863 pa_assert_ctl_context();
1864 pa_assert(PA_SINK_IS_LINKED(s->state));
1865 pa_assert(pa_sink_flat_volume_enabled(s));
1866 pa_assert(!(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER));
1867
1868 /* This determines the maximum volume of all streams and sets
1869 * s->real_volume accordingly. */
1870
1871 if (!has_inputs(s)) {
1872 /* In the special case that we have no sink inputs we leave the
1873 * volume unmodified. */
1874 update_real_volume(s, &s->reference_volume, &s->channel_map);
1875 return;
1876 }
1877
1878 pa_cvolume_mute(&s->real_volume, s->channel_map.channels);
1879
1880 /* First let's determine the new maximum volume of all inputs
1881 * connected to this sink */
1882 get_maximum_input_volume(s, &s->real_volume, &s->channel_map);
1883 update_real_volume(s, &s->real_volume, &s->channel_map);
1884
1885 /* Then, let's update the real ratios/soft volumes of all inputs
1886 * connected to this sink */
1887 compute_real_ratios(s);
1888 }
1889
1890 /* Called from main thread. Only called for the root sink in shared volume
1891 * cases, except for internal recursive calls. */
1892 static void propagate_reference_volume(pa_sink *s) {
1893 pa_sink_input *i;
1894 uint32_t idx;
1895
1896 pa_sink_assert_ref(s);
1897 pa_assert_ctl_context();
1898 pa_assert(PA_SINK_IS_LINKED(s->state));
1899 pa_assert(pa_sink_flat_volume_enabled(s));
1900
1901 /* This is called whenever the sink volume changes that is not
1902 * caused by a sink input volume change. We need to fix up the
1903 * sink input volumes accordingly */
1904
1905 PA_IDXSET_FOREACH(i, s->inputs, idx) {
1906 pa_cvolume old_volume;
1907
1908 if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)) {
1909 propagate_reference_volume(i->origin_sink);
1910
1911 /* Since the origin sink uses volume sharing, this input's volume
1912 * needs to be updated to match the root sink's real volume, but
1913 * that will be done later in update_shared_real_volume(). */
1914 continue;
1915 }
1916
1917 old_volume = i->volume;
1918
1919 /* This basically calculates:
1920 *
1921 * i->volume := s->reference_volume * i->reference_ratio */
1922
1923 i->volume = s->reference_volume;
1924 pa_cvolume_remap(&i->volume, &s->channel_map, &i->channel_map);
1925 pa_sw_cvolume_multiply(&i->volume, &i->volume, &i->reference_ratio);
1926
1927 /* The volume changed, let's tell people so */
1928 if (!pa_cvolume_equal(&old_volume, &i->volume)) {
1929
1930 if (i->volume_changed)
1931 i->volume_changed(i);
1932
1933 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1934 }
1935 }
1936 }
1937
1938 /* Called from main thread. Only called for the root sink in volume sharing
1939 * cases, except for internal recursive calls. The return value indicates
1940 * whether any reference volume actually changed. */
1941 static bool update_reference_volume(pa_sink *s, const pa_cvolume *v, const pa_channel_map *channel_map, bool save) {
1942 pa_cvolume volume;
1943 bool reference_volume_changed;
1944 pa_sink_input *i;
1945 uint32_t idx;
1946
1947 pa_sink_assert_ref(s);
1948 pa_assert(PA_SINK_IS_LINKED(s->state));
1949 pa_assert(v);
1950 pa_assert(channel_map);
1951 pa_assert(pa_cvolume_valid(v));
1952
1953 volume = *v;
1954 pa_cvolume_remap(&volume, channel_map, &s->channel_map);
1955
1956 reference_volume_changed = !pa_cvolume_equal(&volume, &s->reference_volume);
1957 pa_sink_set_reference_volume_direct(s, &volume);
1958
1959 s->save_volume = (!reference_volume_changed && s->save_volume) || save;
1960
1961 if (!reference_volume_changed && !(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER))
1962 /* If the root sink's volume doesn't change, then there can't be any
1963 * changes in the other sinks in the sink tree either.
1964 *
1965 * It's probably theoretically possible that even if the root sink's
1966 * volume changes slightly, some filter sink doesn't change its volume
1967 * due to rounding errors. If that happens, we still want to propagate
1968 * the changed root sink volume to the sinks connected to the
1969 * intermediate sink that didn't change its volume. This theoretical
1970 * possibility is the reason why we have that !(s->flags &
1971 * PA_SINK_SHARE_VOLUME_WITH_MASTER) condition. Probably nobody would
1972 * notice even if we returned here false always if
1973 * reference_volume_changed is false. */
1974 return false;
1975
1976 PA_IDXSET_FOREACH(i, s->inputs, idx) {
1977 if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER))
1978 update_reference_volume(i->origin_sink, v, channel_map, false);
1979 }
1980
1981 return true;
1982 }
1983
1984 /* Called from main thread */
1985 void pa_sink_set_volume(
1986 pa_sink *s,
1987 const pa_cvolume *volume,
1988 bool send_msg,
1989 bool save) {
1990
1991 pa_cvolume new_reference_volume;
1992 pa_sink *root_sink;
1993
1994 pa_sink_assert_ref(s);
1995 pa_assert_ctl_context();
1996 pa_assert(PA_SINK_IS_LINKED(s->state));
1997 pa_assert(!volume || pa_cvolume_valid(volume));
1998 pa_assert(volume || pa_sink_flat_volume_enabled(s));
1999 pa_assert(!volume || volume->channels == 1 || pa_cvolume_compatible(volume, &s->sample_spec));
2000
2001 /* make sure we don't change the volume when a PASSTHROUGH input is connected ...
2002 * ... *except* if we're being invoked to reset the volume to ensure 0 dB gain */
2003 if (pa_sink_is_passthrough(s) && (!volume || !pa_cvolume_is_norm(volume))) {
2004 pa_log_warn("Cannot change volume, Sink is connected to PASSTHROUGH input");
2005 return;
2006 }
2007
2008 /* In case of volume sharing, the volume is set for the root sink first,
2009 * from which it's then propagated to the sharing sinks. */
2010 root_sink = pa_sink_get_master(s);
2011
2012 if (PA_UNLIKELY(!root_sink))
2013 return;
2014
2015 /* As a special exception we accept mono volumes on all sinks --
2016 * even on those with more complex channel maps */
2017
2018 if (volume) {
2019 if (pa_cvolume_compatible(volume, &s->sample_spec))
2020 new_reference_volume = *volume;
2021 else {
2022 new_reference_volume = s->reference_volume;
2023 pa_cvolume_scale(&new_reference_volume, pa_cvolume_max(volume));
2024 }
2025
2026 pa_cvolume_remap(&new_reference_volume, &s->channel_map, &root_sink->channel_map);
2027
2028 if (update_reference_volume(root_sink, &new_reference_volume, &root_sink->channel_map, save)) {
2029 if (pa_sink_flat_volume_enabled(root_sink)) {
2030 /* OK, propagate this volume change back to the inputs */
2031 propagate_reference_volume(root_sink);
2032
2033 /* And now recalculate the real volume */
2034 compute_real_volume(root_sink);
2035 } else
2036 update_real_volume(root_sink, &root_sink->reference_volume, &root_sink->channel_map);
2037 }
2038
2039 } else {
2040 /* If volume is NULL we synchronize the sink's real and
2041 * reference volumes with the stream volumes. */
2042
2043 pa_assert(pa_sink_flat_volume_enabled(root_sink));
2044
2045 /* Ok, let's determine the new real volume */
2046 compute_real_volume(root_sink);
2047
2048 /* Let's 'push' the reference volume if necessary */
2049 pa_cvolume_merge(&new_reference_volume, &s->reference_volume, &root_sink->real_volume);
2050 /* If the sink and its root don't have the same number of channels, we need to remap */
2051 if (s != root_sink && !pa_channel_map_equal(&s->channel_map, &root_sink->channel_map))
2052 pa_cvolume_remap(&new_reference_volume, &s->channel_map, &root_sink->channel_map);
2053 update_reference_volume(root_sink, &new_reference_volume, &root_sink->channel_map, save);
2054
2055 /* Now that the reference volume is updated, we can update the streams'
2056 * reference ratios. */
2057 compute_reference_ratios(root_sink);
2058 }
2059
2060 if (root_sink->set_volume) {
2061 /* If we have a function set_volume(), then we do not apply a
2062 * soft volume by default. However, set_volume() is free to
2063 * apply one to root_sink->soft_volume */
2064
2065 pa_cvolume_reset(&root_sink->soft_volume, root_sink->sample_spec.channels);
2066 if (!(root_sink->flags & PA_SINK_DEFERRED_VOLUME))
2067 root_sink->set_volume(root_sink);
2068
2069 } else
2070 /* If we have no function set_volume(), then the soft volume
2071 * becomes the real volume */
2072 root_sink->soft_volume = root_sink->real_volume;
2073
2074 /* This tells the sink that soft volume and/or real volume changed */
2075 if (send_msg)
2076 pa_assert_se(pa_asyncmsgq_send(root_sink->asyncmsgq, PA_MSGOBJECT(root_sink), PA_SINK_MESSAGE_SET_SHARED_VOLUME, NULL, 0, NULL) == 0);
2077 }
2078
2079 /* Called from the io thread if sync volume is used, otherwise from the main thread.
2080 * Only to be called by sink implementor */
2081 void pa_sink_set_soft_volume(pa_sink *s, const pa_cvolume *volume) {
2082
2083 pa_sink_assert_ref(s);
2084 pa_assert(!(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER));
2085
2086 if (s->flags & PA_SINK_DEFERRED_VOLUME)
2087 pa_sink_assert_io_context(s);
2088 else
2089 pa_assert_ctl_context();
2090
2091 if (!volume)
2092 pa_cvolume_reset(&s->soft_volume, s->sample_spec.channels);
2093 else
2094 s->soft_volume = *volume;
2095
2096 if (PA_SINK_IS_LINKED(s->state) && !(s->flags & PA_SINK_DEFERRED_VOLUME))
2097 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_VOLUME, NULL, 0, NULL) == 0);
2098 else
2099 s->thread_info.soft_volume = s->soft_volume;
2100 }
2101
2102 /* Called from the main thread. Only called for the root sink in volume sharing
2103 * cases, except for internal recursive calls. */
2104 static void propagate_real_volume(pa_sink *s, const pa_cvolume *old_real_volume) {
2105 pa_sink_input *i;
2106 uint32_t idx;
2107
2108 pa_sink_assert_ref(s);
2109 pa_assert(old_real_volume);
2110 pa_assert_ctl_context();
2111 pa_assert(PA_SINK_IS_LINKED(s->state));
2112
2113 /* This is called when the hardware's real volume changes due to
2114 * some external event. We copy the real volume into our
2115 * reference volume and then rebuild the stream volumes based on
2116 * i->real_ratio which should stay fixed. */
2117
2118 if (!(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)) {
2119 if (pa_cvolume_equal(old_real_volume, &s->real_volume))
2120 return;
2121
2122 /* 1. Make the real volume the reference volume */
2123 update_reference_volume(s, &s->real_volume, &s->channel_map, true);
2124 }
2125
2126 if (pa_sink_flat_volume_enabled(s)) {
2127
2128 PA_IDXSET_FOREACH(i, s->inputs, idx) {
2129 pa_cvolume old_volume = i->volume;
2130
2131 /* 2. Since the sink's reference and real volumes are equal
2132 * now our ratios should be too. */
2133 i->reference_ratio = i->real_ratio;
2134
2135 /* 3. Recalculate the new stream reference volume based on the
2136 * reference ratio and the sink's reference volume.
2137 *
2138 * This basically calculates:
2139 *
2140 * i->volume = s->reference_volume * i->reference_ratio
2141 *
2142 * This is identical to propagate_reference_volume() */
2143 i->volume = s->reference_volume;
2144 pa_cvolume_remap(&i->volume, &s->channel_map, &i->channel_map);
2145 pa_sw_cvolume_multiply(&i->volume, &i->volume, &i->reference_ratio);
2146
2147 /* Notify if something changed */
2148 if (!pa_cvolume_equal(&old_volume, &i->volume)) {
2149
2150 if (i->volume_changed)
2151 i->volume_changed(i);
2152
2153 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
2154 }
2155
2156 if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER))
2157 propagate_real_volume(i->origin_sink, old_real_volume);
2158 }
2159 }
2160
2161 /* Something got changed in the hardware. It probably makes sense
2162 * to save changed hw settings given that hw volume changes not
2163 * triggered by PA are almost certainly done by the user. */
2164 if (!(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER))
2165 s->save_volume = true;
2166 }
2167
2168 /* Called from io thread */
2169 void pa_sink_update_volume_and_mute(pa_sink *s) {
2170 pa_assert(s);
2171 pa_sink_assert_io_context(s);
2172
2173 pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_UPDATE_VOLUME_AND_MUTE, NULL, 0, NULL, NULL);
2174 }
2175
2176 /* Called from main thread */
2177 const pa_cvolume *pa_sink_get_volume(pa_sink *s, bool force_refresh) {
2178 pa_sink_assert_ref(s);
2179 pa_assert_ctl_context();
2180 pa_assert(PA_SINK_IS_LINKED(s->state));
2181
2182 if (s->refresh_volume || force_refresh) {
2183 struct pa_cvolume old_real_volume;
2184
2185 pa_assert(!(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER));
2186
2187 old_real_volume = s->real_volume;
2188
2189 if (!(s->flags & PA_SINK_DEFERRED_VOLUME) && s->get_volume)
2190 s->get_volume(s);
2191
2192 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_VOLUME, NULL, 0, NULL) == 0);
2193
2194 update_real_volume(s, &s->real_volume, &s->channel_map);
2195 propagate_real_volume(s, &old_real_volume);
2196 }
2197
2198 return &s->reference_volume;
2199 }
2200
2201 /* Called from main thread. In volume sharing cases, only the root sink may
2202 * call this. */
2203 void pa_sink_volume_changed(pa_sink *s, const pa_cvolume *new_real_volume) {
2204 pa_cvolume old_real_volume;
2205
2206 pa_sink_assert_ref(s);
2207 pa_assert_ctl_context();
2208 pa_assert(PA_SINK_IS_LINKED(s->state));
2209 pa_assert(!(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER));
2210
2211 /* The sink implementor may call this if the volume changed to make sure everyone is notified */
2212
2213 old_real_volume = s->real_volume;
2214 update_real_volume(s, new_real_volume, &s->channel_map);
2215 propagate_real_volume(s, &old_real_volume);
2216 }
2217
2218 /* Called from main thread */
2219 void pa_sink_set_mute(pa_sink *s, bool mute, bool save) {
2220 bool old_muted;
2221
2222 pa_sink_assert_ref(s);
2223 pa_assert_ctl_context();
2224 pa_assert(PA_SINK_IS_LINKED(s->state));
2225
2226 old_muted = s->muted;
2227 s->muted = mute;
2228 s->save_muted = (old_muted == s->muted && s->save_muted) || save;
2229
2230 if (!(s->flags & PA_SINK_DEFERRED_VOLUME) && s->set_mute)
2231 s->set_mute(s);
2232
2233 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_MUTE, NULL, 0, NULL) == 0);
2234
2235 if (old_muted != s->muted)
2236 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
2237 }
2238
2239 /* Called from main thread */
2240 bool pa_sink_get_mute(pa_sink *s, bool force_refresh) {
2241
2242 pa_sink_assert_ref(s);
2243 pa_assert_ctl_context();
2244 pa_assert(PA_SINK_IS_LINKED(s->state));
2245
2246 if (s->refresh_muted || force_refresh) {
2247 bool old_muted = s->muted;
2248
2249 if (!(s->flags & PA_SINK_DEFERRED_VOLUME) && s->get_mute)
2250 s->get_mute(s);
2251
2252 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_MUTE, NULL, 0, NULL) == 0);
2253
2254 if (old_muted != s->muted) {
2255 s->save_muted = true;
2256
2257 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
2258
2259 /* Make sure the soft mute status stays in sync */
2260 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_MUTE, NULL, 0, NULL) == 0);
2261 }
2262 }
2263
2264 return s->muted;
2265 }
2266
2267 /* Called from main thread */
2268 void pa_sink_mute_changed(pa_sink *s, bool new_muted) {
2269 pa_sink_assert_ref(s);
2270 pa_assert_ctl_context();
2271 pa_assert(PA_SINK_IS_LINKED(s->state));
2272
2273 /* The sink implementor may call this if the volume changed to make sure everyone is notified */
2274
2275 if (s->muted == new_muted)
2276 return;
2277
2278 s->muted = new_muted;
2279 s->save_muted = true;
2280
2281 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
2282 }
2283
2284 /* Called from main thread */
2285 bool pa_sink_update_proplist(pa_sink *s, pa_update_mode_t mode, pa_proplist *p) {
2286 pa_sink_assert_ref(s);
2287 pa_assert_ctl_context();
2288
2289 if (p)
2290 pa_proplist_update(s->proplist, mode, p);
2291
2292 if (PA_SINK_IS_LINKED(s->state)) {
2293 pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_PROPLIST_CHANGED], s);
2294 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
2295 }
2296
2297 return true;
2298 }
2299
2300 /* Called from main thread */
2301 /* FIXME -- this should be dropped and be merged into pa_sink_update_proplist() */
2302 void pa_sink_set_description(pa_sink *s, const char *description) {
2303 const char *old;
2304 pa_sink_assert_ref(s);
2305 pa_assert_ctl_context();
2306
2307 if (!description && !pa_proplist_contains(s->proplist, PA_PROP_DEVICE_DESCRIPTION))
2308 return;
2309
2310 old = pa_proplist_gets(s->proplist, PA_PROP_DEVICE_DESCRIPTION);
2311
2312 if (old && description && pa_streq(old, description))
2313 return;
2314
2315 if (description)
2316 pa_proplist_sets(s->proplist, PA_PROP_DEVICE_DESCRIPTION, description);
2317 else
2318 pa_proplist_unset(s->proplist, PA_PROP_DEVICE_DESCRIPTION);
2319
2320 if (s->monitor_source) {
2321 char *n;
2322
2323 n = pa_sprintf_malloc("Monitor Source of %s", description ? description : s->name);
2324 pa_source_set_description(s->monitor_source, n);
2325 pa_xfree(n);
2326 }
2327
2328 if (PA_SINK_IS_LINKED(s->state)) {
2329 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
2330 pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_PROPLIST_CHANGED], s);
2331 }
2332 }
2333
2334 /* Called from main thread */
2335 unsigned pa_sink_linked_by(pa_sink *s) {
2336 unsigned ret;
2337
2338 pa_sink_assert_ref(s);
2339 pa_assert_ctl_context();
2340 pa_assert(PA_SINK_IS_LINKED(s->state));
2341
2342 ret = pa_idxset_size(s->inputs);
2343
2344 /* We add in the number of streams connected to us here. Please
2345 * note the asymmetry to pa_sink_used_by()! */
2346
2347 if (s->monitor_source)
2348 ret += pa_source_linked_by(s->monitor_source);
2349
2350 return ret;
2351 }
2352
2353 /* Called from main thread */
2354 unsigned pa_sink_used_by(pa_sink *s) {
2355 unsigned ret;
2356
2357 pa_sink_assert_ref(s);
2358 pa_assert_ctl_context();
2359 pa_assert(PA_SINK_IS_LINKED(s->state));
2360
2361 ret = pa_idxset_size(s->inputs);
2362 pa_assert(ret >= s->n_corked);
2363
2364 /* Streams connected to our monitor source do not matter for
2365 * pa_sink_used_by()!.*/
2366
2367 return ret - s->n_corked;
2368 }
2369
2370 /* Called from main thread */
2371 unsigned pa_sink_check_suspend(pa_sink *s) {
2372 unsigned ret;
2373 pa_sink_input *i;
2374 uint32_t idx;
2375
2376 pa_sink_assert_ref(s);
2377 pa_assert_ctl_context();
2378
2379 if (!PA_SINK_IS_LINKED(s->state))
2380 return 0;
2381
2382 ret = 0;
2383
2384 PA_IDXSET_FOREACH(i, s->inputs, idx) {
2385 pa_sink_input_state_t st;
2386
2387 st = pa_sink_input_get_state(i);
2388
2389 /* We do not assert here. It is perfectly valid for a sink input to
2390 * be in the INIT state (i.e. created, marked done but not yet put)
2391 * and we should not care if it's unlinked as it won't contribute
2392 * towards our busy status.
2393 */
2394 if (!PA_SINK_INPUT_IS_LINKED(st))
2395 continue;
2396
2397 if (st == PA_SINK_INPUT_CORKED)
2398 continue;
2399
2400 if (i->flags & PA_SINK_INPUT_DONT_INHIBIT_AUTO_SUSPEND)
2401 continue;
2402
2403 ret ++;
2404 }
2405
2406 if (s->monitor_source)
2407 ret += pa_source_check_suspend(s->monitor_source);
2408
2409 return ret;
2410 }
2411
2412 /* Called from the IO thread */
2413 static void sync_input_volumes_within_thread(pa_sink *s) {
2414 pa_sink_input *i;
2415 void *state = NULL;
2416
2417 pa_sink_assert_ref(s);
2418 pa_sink_assert_io_context(s);
2419
2420 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state) {
2421 if (pa_cvolume_equal(&i->thread_info.soft_volume, &i->soft_volume))
2422 continue;
2423
2424 i->thread_info.soft_volume = i->soft_volume;
2425 pa_sink_input_request_rewind(i, 0, true, false, false);
2426 }
2427 }
2428
2429 /* Called from the IO thread. Only called for the root sink in volume sharing
2430 * cases, except for internal recursive calls. */
2431 static void set_shared_volume_within_thread(pa_sink *s) {
2432 pa_sink_input *i = NULL;
2433 void *state = NULL;
2434
2435 pa_sink_assert_ref(s);
2436
2437 PA_MSGOBJECT(s)->process_msg(PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_VOLUME_SYNCED, NULL, 0, NULL);
2438
2439 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state) {
2440 if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER))
2441 set_shared_volume_within_thread(i->origin_sink);
2442 }
2443 }
2444
2445 /* Called from IO thread, except when it is not */
2446 int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {
2447 pa_sink *s = PA_SINK(o);
2448 pa_sink_assert_ref(s);
2449
2450 switch ((pa_sink_message_t) code) {
2451
2452 case PA_SINK_MESSAGE_ADD_INPUT: {
2453 pa_sink_input *i = PA_SINK_INPUT(userdata);
2454
2455 /* If you change anything here, make sure to change the
2456 * sink input handling a few lines down at
2457 * PA_SINK_MESSAGE_FINISH_MOVE, too. */
2458
2459 pa_hashmap_put(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index), pa_sink_input_ref(i));
2460
2461 /* Since the caller sleeps in pa_sink_input_put(), we can
2462 * safely access data outside of thread_info even though
2463 * it is mutable */
2464
2465 if ((i->thread_info.sync_prev = i->sync_prev)) {
2466 pa_assert(i->sink == i->thread_info.sync_prev->sink);
2467 pa_assert(i->sync_prev->sync_next == i);
2468 i->thread_info.sync_prev->thread_info.sync_next = i;
2469 }
2470
2471 if ((i->thread_info.sync_next = i->sync_next)) {
2472 pa_assert(i->sink == i->thread_info.sync_next->sink);
2473 pa_assert(i->sync_next->sync_prev == i);
2474 i->thread_info.sync_next->thread_info.sync_prev = i;
2475 }
2476
2477 pa_assert(!i->thread_info.attached);
2478 i->thread_info.attached = true;
2479
2480 if (i->attach)
2481 i->attach(i);
2482
2483 pa_sink_input_set_state_within_thread(i, i->state);
2484
2485 /* The requested latency of the sink input needs to be fixed up and
2486 * then configured on the sink. If this causes the sink latency to
2487 * go down, the sink implementor is responsible for doing a rewind
2488 * in the update_requested_latency() callback to ensure that the
2489 * sink buffer doesn't contain more data than what the new latency
2490 * allows.
2491 *
2492 * XXX: Does it really make sense to push this responsibility to
2493 * the sink implementors? Wouldn't it be better to do it once in
2494 * the core than many times in the modules? */
2495
2496 if (i->thread_info.requested_sink_latency != (pa_usec_t) -1)
2497 pa_sink_input_set_requested_latency_within_thread(i, i->thread_info.requested_sink_latency);
2498
2499 pa_sink_input_update_max_rewind(i, s->thread_info.max_rewind);
2500 pa_sink_input_update_max_request(i, s->thread_info.max_request);
2501
2502 /* We don't rewind here automatically. This is left to the
2503 * sink input implementor because some sink inputs need a
2504 * slow start, i.e. need some time to buffer client
2505 * samples before beginning streaming.
2506 *
2507 * XXX: Does it really make sense to push this functionality to
2508 * the sink implementors? Wouldn't it be better to do it once in
2509 * the core than many times in the modules? */
2510
2511 /* In flat volume mode we need to update the volume as
2512 * well */
2513 return o->process_msg(o, PA_SINK_MESSAGE_SET_SHARED_VOLUME, NULL, 0, NULL);
2514 }
2515
2516 case PA_SINK_MESSAGE_REMOVE_INPUT: {
2517 pa_sink_input *i = PA_SINK_INPUT(userdata);
2518
2519 /* If you change anything here, make sure to change the
2520 * sink input handling a few lines down at
2521 * PA_SINK_MESSAGE_START_MOVE, too. */
2522
2523 if (i->detach)
2524 i->detach(i);
2525
2526 pa_sink_input_set_state_within_thread(i, i->state);
2527
2528 pa_assert(i->thread_info.attached);
2529 i->thread_info.attached = false;
2530
2531 /* Since the caller sleeps in pa_sink_input_unlink(),
2532 * we can safely access data outside of thread_info even
2533 * though it is mutable */
2534
2535 pa_assert(!i->sync_prev);
2536 pa_assert(!i->sync_next);
2537
2538 if (i->thread_info.sync_prev) {
2539 i->thread_info.sync_prev->thread_info.sync_next = i->thread_info.sync_prev->sync_next;
2540 i->thread_info.sync_prev = NULL;
2541 }
2542
2543 if (i->thread_info.sync_next) {
2544 i->thread_info.sync_next->thread_info.sync_prev = i->thread_info.sync_next->sync_prev;
2545 i->thread_info.sync_next = NULL;
2546 }
2547
2548 pa_hashmap_remove_and_free(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index));
2549 pa_sink_invalidate_requested_latency(s, true);
2550 pa_sink_request_rewind(s, (size_t) -1);
2551
2552 /* In flat volume mode we need to update the volume as
2553 * well */
2554 return o->process_msg(o, PA_SINK_MESSAGE_SET_SHARED_VOLUME, NULL, 0, NULL);
2555 }
2556
2557 case PA_SINK_MESSAGE_START_MOVE: {
2558 pa_sink_input *i = PA_SINK_INPUT(userdata);
2559
2560 /* We don't support moving synchronized streams. */
2561 pa_assert(!i->sync_prev);
2562 pa_assert(!i->sync_next);
2563 pa_assert(!i->thread_info.sync_next);
2564 pa_assert(!i->thread_info.sync_prev);
2565
2566 if (i->thread_info.state != PA_SINK_INPUT_CORKED) {
2567 pa_usec_t usec = 0;
2568 size_t sink_nbytes, total_nbytes;
2569
2570 /* The old sink probably has some audio from this
2571 * stream in its buffer. We want to "take it back" as
2572 * much as possible and play it to the new sink. We
2573 * don't know at this point how much the old sink can
2574 * rewind. We have to pick something, and that
2575 * something is the full latency of the old sink here.
2576 * So we rewind the stream buffer by the sink latency
2577 * amount, which may be more than what we should
2578 * rewind. This can result in a chunk of audio being
2579 * played both to the old sink and the new sink.
2580 *
2581 * FIXME: Fix this code so that we don't have to make
2582 * guesses about how much the sink will actually be
2583 * able to rewind. If someone comes up with a solution
2584 * for this, something to note is that the part of the
2585 * latency that the old sink couldn't rewind should
2586 * ideally be compensated after the stream has moved
2587 * to the new sink by adding silence. The new sink
2588 * most likely can't start playing the moved stream
2589 * immediately, and that gap should be removed from
2590 * the "compensation silence" (at least at the time of
2591 * writing this, the move finish code will actually
2592 * already take care of dropping the new sink's
2593 * unrewindable latency, so taking into account the
2594 * unrewindable latency of the old sink is the only
2595 * problem).
2596 *
2597 * The render_memblockq contents are discarded,
2598 * because when the sink changes, the format of the
2599 * audio stored in the render_memblockq may change
2600 * too, making the stored audio invalid. FIXME:
2601 * However, the read and write indices are moved back
2602 * the same amount, so if they are not the same now,
2603 * they won't be the same after the rewind either. If
2604 * the write index of the render_memblockq is ahead of
2605 * the read index, then the render_memblockq will feed
2606 * the new sink some silence first, which it shouldn't
2607 * do. The write index should be flushed to be the
2608 * same as the read index. */
2609
2610 /* Get the latency of the sink */
2611 usec = pa_sink_get_latency_within_thread(s);
2612 sink_nbytes = pa_usec_to_bytes(usec, &s->sample_spec);
2613 total_nbytes = sink_nbytes + pa_memblockq_get_length(i->thread_info.render_memblockq);
2614
2615 if (total_nbytes > 0) {
2616 i->thread_info.rewrite_nbytes = i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, total_nbytes) : total_nbytes;
2617 i->thread_info.rewrite_flush = true;
2618 pa_sink_input_process_rewind(i, sink_nbytes);
2619 }
2620 }
2621
2622 if (i->detach)
2623 i->detach(i);
2624
2625 pa_assert(i->thread_info.attached);
2626 i->thread_info.attached = false;
2627
2628 /* Let's remove the sink input ...*/
2629 pa_hashmap_remove_and_free(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index));
2630
2631 pa_sink_invalidate_requested_latency(s, true);
2632
2633 pa_log_debug("Requesting rewind due to started move");
2634 pa_sink_request_rewind(s, (size_t) -1);
2635
2636 /* In flat volume mode we need to update the volume as
2637 * well */
2638 return o->process_msg(o, PA_SINK_MESSAGE_SET_SHARED_VOLUME, NULL, 0, NULL);
2639 }
2640
2641 case PA_SINK_MESSAGE_FINISH_MOVE: {
2642 pa_sink_input *i = PA_SINK_INPUT(userdata);
2643
2644 /* We don't support moving synchronized streams. */
2645 pa_assert(!i->sync_prev);
2646 pa_assert(!i->sync_next);
2647 pa_assert(!i->thread_info.sync_next);
2648 pa_assert(!i->thread_info.sync_prev);
2649
2650 pa_hashmap_put(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index), pa_sink_input_ref(i));
2651
2652 pa_assert(!i->thread_info.attached);
2653 i->thread_info.attached = true;
2654
2655 if (i->attach)
2656 i->attach(i);
2657
2658 if (i->thread_info.state != PA_SINK_INPUT_CORKED) {
2659 pa_usec_t usec = 0;
2660 size_t nbytes;
2661
2662 /* In the ideal case the new sink would start playing
2663 * the stream immediately. That requires the sink to
2664 * be able to rewind all of its latency, which usually
2665 * isn't possible, so there will probably be some gap
2666 * before the moved stream becomes audible. We then
2667 * have two possibilities: 1) start playing the stream
2668 * from where it is now, or 2) drop the unrewindable
2669 * latency of the sink from the stream. With option 1
2670 * we won't lose any audio but the stream will have a
2671 * pause. With option 2 we may lose some audio but the
2672 * stream time will be somewhat in sync with the wall
2673 * clock. Lennart seems to have chosen option 2 (one
2674 * of the reasons might have been that option 1 is
2675 * actually much harder to implement), so we drop the
2676 * latency of the new sink from the moved stream and
2677 * hope that the sink will undo most of that in the
2678 * rewind. */
2679
2680 /* Get the latency of the sink */
2681 usec = pa_sink_get_latency_within_thread(s);
2682 nbytes = pa_usec_to_bytes(usec, &s->sample_spec);
2683
2684 if (nbytes > 0)
2685 pa_sink_input_drop(i, nbytes);
2686
2687 pa_log_debug("Requesting rewind due to finished move");
2688 pa_sink_request_rewind(s, nbytes);
2689 }
2690
2691 /* Updating the requested sink latency has to be done
2692 * after the sink rewind request, not before, because
2693 * otherwise the sink may limit the rewind amount
2694 * needlessly. */
2695
2696 if (i->thread_info.requested_sink_latency != (pa_usec_t) -1)
2697 pa_sink_input_set_requested_latency_within_thread(i, i->thread_info.requested_sink_latency);
2698
2699 pa_sink_input_update_max_rewind(i, s->thread_info.max_rewind);
2700 pa_sink_input_update_max_request(i, s->thread_info.max_request);
2701
2702 return o->process_msg(o, PA_SINK_MESSAGE_SET_SHARED_VOLUME, NULL, 0, NULL);
2703 }
2704
2705 case PA_SINK_MESSAGE_SET_SHARED_VOLUME: {
2706 pa_sink *root_sink = pa_sink_get_master(s);
2707
2708 if (PA_LIKELY(root_sink))
2709 set_shared_volume_within_thread(root_sink);
2710
2711 return 0;
2712 }
2713
2714 case PA_SINK_MESSAGE_SET_VOLUME_SYNCED:
2715
2716 if (s->flags & PA_SINK_DEFERRED_VOLUME) {
2717 s->set_volume(s);
2718 pa_sink_volume_change_push(s);
2719 }
2720 /* Fall through ... */
2721
2722 case PA_SINK_MESSAGE_SET_VOLUME:
2723
2724 if (!pa_cvolume_equal(&s->thread_info.soft_volume, &s->soft_volume)) {
2725 s->thread_info.soft_volume = s->soft_volume;
2726 pa_sink_request_rewind(s, (size_t) -1);
2727 }
2728
2729 /* Fall through ... */
2730
2731 case PA_SINK_MESSAGE_SYNC_VOLUMES:
2732 sync_input_volumes_within_thread(s);
2733 return 0;
2734
2735 case PA_SINK_MESSAGE_GET_VOLUME:
2736
2737 if ((s->flags & PA_SINK_DEFERRED_VOLUME) && s->get_volume) {
2738 s->get_volume(s);
2739 pa_sink_volume_change_flush(s);
2740 pa_sw_cvolume_divide(&s->thread_info.current_hw_volume, &s->real_volume, &s->soft_volume);
2741 }
2742
2743 /* In case sink implementor reset SW volume. */
2744 if (!pa_cvolume_equal(&s->thread_info.soft_volume, &s->soft_volume)) {
2745 s->thread_info.soft_volume = s->soft_volume;
2746 pa_sink_request_rewind(s, (size_t) -1);
2747 }
2748
2749 return 0;
2750
2751 case PA_SINK_MESSAGE_SET_MUTE:
2752
2753 if (s->thread_info.soft_muted != s->muted) {
2754 s->thread_info.soft_muted = s->muted;
2755 pa_sink_request_rewind(s, (size_t) -1);
2756 }
2757
2758 if (s->flags & PA_SINK_DEFERRED_VOLUME && s->set_mute)
2759 s->set_mute(s);
2760
2761 return 0;
2762
2763 case PA_SINK_MESSAGE_GET_MUTE:
2764
2765 if (s->flags & PA_SINK_DEFERRED_VOLUME && s->get_mute)
2766 s->get_mute(s);
2767
2768 return 0;
2769
2770 case PA_SINK_MESSAGE_SET_STATE: {
2771
2772 bool suspend_change =
2773 (s->thread_info.state == PA_SINK_SUSPENDED && PA_SINK_IS_OPENED(PA_PTR_TO_UINT(userdata))) ||
2774 (PA_SINK_IS_OPENED(s->thread_info.state) && PA_PTR_TO_UINT(userdata) == PA_SINK_SUSPENDED);
2775
2776 s->thread_info.state = PA_PTR_TO_UINT(userdata);
2777
2778 if (s->thread_info.state == PA_SINK_SUSPENDED) {
2779 s->thread_info.rewind_nbytes = 0;
2780 s->thread_info.rewind_requested = false;
2781 }
2782
2783 if (suspend_change) {
2784 pa_sink_input *i;
2785 void *state = NULL;
2786
2787 while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)))
2788 if (i->suspend_within_thread)
2789 i->suspend_within_thread(i, s->thread_info.state == PA_SINK_SUSPENDED);
2790 }
2791
2792 return 0;
2793 }
2794
2795 case PA_SINK_MESSAGE_GET_REQUESTED_LATENCY: {
2796
2797 pa_usec_t *usec = userdata;
2798 *usec = pa_sink_get_requested_latency_within_thread(s);
2799
2800 /* Yes, that's right, the IO thread will see -1 when no
2801 * explicit requested latency is configured, the main
2802 * thread will see max_latency */
2803 if (*usec == (pa_usec_t) -1)
2804 *usec = s->thread_info.max_latency;
2805
2806 return 0;
2807 }
2808
2809 case PA_SINK_MESSAGE_SET_LATENCY_RANGE: {
2810 pa_usec_t *r = userdata;
2811
2812 pa_sink_set_latency_range_within_thread(s, r[0], r[1]);
2813
2814 return 0;
2815 }
2816
2817 case PA_SINK_MESSAGE_GET_LATENCY_RANGE: {
2818 pa_usec_t *r = userdata;
2819
2820 r[0] = s->thread_info.min_latency;
2821 r[1] = s->thread_info.max_latency;
2822
2823 return 0;
2824 }
2825
2826 case PA_SINK_MESSAGE_GET_FIXED_LATENCY:
2827
2828 *((pa_usec_t*) userdata) = s->thread_info.fixed_latency;
2829 return 0;
2830
2831 case PA_SINK_MESSAGE_SET_FIXED_LATENCY:
2832
2833 pa_sink_set_fixed_latency_within_thread(s, (pa_usec_t) offset);
2834 return 0;
2835
2836 case PA_SINK_MESSAGE_GET_MAX_REWIND:
2837
2838 *((size_t*) userdata) = s->thread_info.max_rewind;
2839 return 0;
2840
2841 case PA_SINK_MESSAGE_GET_MAX_REQUEST:
2842
2843 *((size_t*) userdata) = s->thread_info.max_request;
2844 return 0;
2845
2846 case PA_SINK_MESSAGE_SET_MAX_REWIND:
2847
2848 pa_sink_set_max_rewind_within_thread(s, (size_t) offset);
2849 return 0;
2850
2851 case PA_SINK_MESSAGE_SET_MAX_REQUEST:
2852
2853 pa_sink_set_max_request_within_thread(s, (size_t) offset);
2854 return 0;
2855
2856 case PA_SINK_MESSAGE_SET_PORT:
2857
2858 pa_assert(userdata);
2859 if (s->set_port) {
2860 struct sink_message_set_port *msg_data = userdata;
2861 msg_data->ret = s->set_port(s, msg_data->port);
2862 }
2863 return 0;
2864
2865 case PA_SINK_MESSAGE_UPDATE_VOLUME_AND_MUTE:
2866 /* This message is sent from IO-thread and handled in main thread. */
2867 pa_assert_ctl_context();
2868
2869 /* Make sure we're not messing with main thread when no longer linked */
2870 if (!PA_SINK_IS_LINKED(s->state))
2871 return 0;
2872
2873 pa_sink_get_volume(s, true);
2874 pa_sink_get_mute(s, true);
2875 return 0;
2876
2877 case PA_SINK_MESSAGE_SET_LATENCY_OFFSET:
2878 s->thread_info.latency_offset = offset;
2879 return 0;
2880
2881 case PA_SINK_MESSAGE_GET_LATENCY:
2882 case PA_SINK_MESSAGE_MAX:
2883 ;
2884 }
2885
2886 return -1;
2887 }
2888
2889 /* Called from main thread */
2890 int pa_sink_suspend_all(pa_core *c, bool suspend, pa_suspend_cause_t cause) {
2891 pa_sink *sink;
2892 uint32_t idx;
2893 int ret = 0;
2894
2895 pa_core_assert_ref(c);
2896 pa_assert_ctl_context();
2897 pa_assert(cause != 0);
2898
2899 PA_IDXSET_FOREACH(sink, c->sinks, idx) {
2900 int r;
2901
2902 if ((r = pa_sink_suspend(sink, suspend, cause)) < 0)
2903 ret = r;
2904 }
2905
2906 return ret;
2907 }
2908
2909 /* Called from IO thread */
2910 void pa_sink_detach_within_thread(pa_sink *s) {
2911 pa_sink_input *i;
2912 void *state = NULL;
2913
2914 pa_sink_assert_ref(s);
2915 pa_sink_assert_io_context(s);
2916 pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
2917
2918 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state)
2919 if (i->detach)
2920 i->detach(i);
2921
2922 if (s->monitor_source)
2923 pa_source_detach_within_thread(s->monitor_source);
2924 }
2925
2926 /* Called from IO thread */
2927 void pa_sink_attach_within_thread(pa_sink *s) {
2928 pa_sink_input *i;
2929 void *state = NULL;
2930
2931 pa_sink_assert_ref(s);
2932 pa_sink_assert_io_context(s);
2933 pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
2934
2935 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state)
2936 if (i->attach)
2937 i->attach(i);
2938
2939 if (s->monitor_source)
2940 pa_source_attach_within_thread(s->monitor_source);
2941 }
2942
2943 /* Called from IO thread */
2944 void pa_sink_request_rewind(pa_sink*s, size_t nbytes) {
2945 pa_sink_assert_ref(s);
2946 pa_sink_assert_io_context(s);
2947 pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
2948
2949 if (nbytes == (size_t) -1)
2950 nbytes = s->thread_info.max_rewind;
2951
2952 nbytes = PA_MIN(nbytes, s->thread_info.max_rewind);
2953
2954 if (s->thread_info.rewind_requested &&
2955 nbytes <= s->thread_info.rewind_nbytes)
2956 return;
2957
2958 s->thread_info.rewind_nbytes = nbytes;
2959 s->thread_info.rewind_requested = true;
2960
2961 if (s->request_rewind)
2962 s->request_rewind(s);
2963 }
2964
2965 /* Called from IO thread */
2966 pa_usec_t pa_sink_get_requested_latency_within_thread(pa_sink *s) {
2967 pa_usec_t result = (pa_usec_t) -1;
2968 pa_sink_input *i;
2969 void *state = NULL;
2970 pa_usec_t monitor_latency;
2971
2972 pa_sink_assert_ref(s);
2973 pa_sink_assert_io_context(s);
2974
2975 if (!(s->flags & PA_SINK_DYNAMIC_LATENCY))
2976 return PA_CLAMP(s->thread_info.fixed_latency, s->thread_info.min_latency, s->thread_info.max_latency);
2977
2978 if (s->thread_info.requested_latency_valid)
2979 return s->thread_info.requested_latency;
2980
2981 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state)
2982 if (i->thread_info.requested_sink_latency != (pa_usec_t) -1 &&
2983 (result == (pa_usec_t) -1 || result > i->thread_info.requested_sink_latency))
2984 result = i->thread_info.requested_sink_latency;
2985
2986 monitor_latency = pa_source_get_requested_latency_within_thread(s->monitor_source);
2987
2988 if (monitor_latency != (pa_usec_t) -1 &&
2989 (result == (pa_usec_t) -1 || result > monitor_latency))
2990 result = monitor_latency;
2991
2992 if (result != (pa_usec_t) -1)
2993 result = PA_CLAMP(result, s->thread_info.min_latency, s->thread_info.max_latency);
2994
2995 if (PA_SINK_IS_LINKED(s->thread_info.state)) {
2996 /* Only cache if properly initialized */
2997 s->thread_info.requested_latency = result;
2998 s->thread_info.requested_latency_valid = true;
2999 }
3000
3001 return result;
3002 }
3003
3004 /* Called from main thread */
3005 pa_usec_t pa_sink_get_requested_latency(pa_sink *s) {
3006 pa_usec_t usec = 0;
3007
3008 pa_sink_assert_ref(s);
3009 pa_assert_ctl_context();
3010 pa_assert(PA_SINK_IS_LINKED(s->state));
3011
3012 if (s->state == PA_SINK_SUSPENDED)
3013 return 0;
3014
3015 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);
3016
3017 return usec;
3018 }
3019
3020 /* Called from IO as well as the main thread -- the latter only before the IO thread started up */
3021 void pa_sink_set_max_rewind_within_thread(pa_sink *s, size_t max_rewind) {
3022 pa_sink_input *i;
3023 void *state = NULL;
3024
3025 pa_sink_assert_ref(s);
3026 pa_sink_assert_io_context(s);
3027
3028 if (max_rewind == s->thread_info.max_rewind)
3029 return;
3030
3031 s->thread_info.max_rewind = max_rewind;
3032
3033 if (PA_SINK_IS_LINKED(s->thread_info.state))
3034 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state)
3035 pa_sink_input_update_max_rewind(i, s->thread_info.max_rewind);
3036
3037 if (s->monitor_source)
3038 pa_source_set_max_rewind_within_thread(s->monitor_source, s->thread_info.max_rewind);
3039 }
3040
3041 /* Called from main thread */
3042 void pa_sink_set_max_rewind(pa_sink *s, size_t max_rewind) {
3043 pa_sink_assert_ref(s);
3044 pa_assert_ctl_context();
3045
3046 if (PA_SINK_IS_LINKED(s->state))
3047 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_MAX_REWIND, NULL, max_rewind, NULL) == 0);
3048 else
3049 pa_sink_set_max_rewind_within_thread(s, max_rewind);
3050 }
3051
3052 /* Called from IO as well as the main thread -- the latter only before the IO thread started up */
3053 void pa_sink_set_max_request_within_thread(pa_sink *s, size_t max_request) {
3054 void *state = NULL;
3055
3056 pa_sink_assert_ref(s);
3057 pa_sink_assert_io_context(s);
3058
3059 if (max_request == s->thread_info.max_request)
3060 return;
3061
3062 s->thread_info.max_request = max_request;
3063
3064 if (PA_SINK_IS_LINKED(s->thread_info.state)) {
3065 pa_sink_input *i;
3066
3067 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state)
3068 pa_sink_input_update_max_request(i, s->thread_info.max_request);
3069 }
3070 }
3071
3072 /* Called from main thread */
3073 void pa_sink_set_max_request(pa_sink *s, size_t max_request) {
3074 pa_sink_assert_ref(s);
3075 pa_assert_ctl_context();
3076
3077 if (PA_SINK_IS_LINKED(s->state))
3078 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_MAX_REQUEST, NULL, max_request, NULL) == 0);
3079 else
3080 pa_sink_set_max_request_within_thread(s, max_request);
3081 }
3082
3083 /* Called from IO thread */
3084 void pa_sink_invalidate_requested_latency(pa_sink *s, bool dynamic) {
3085 pa_sink_input *i;
3086 void *state = NULL;
3087
3088 pa_sink_assert_ref(s);
3089 pa_sink_assert_io_context(s);
3090
3091 if ((s->flags & PA_SINK_DYNAMIC_LATENCY))
3092 s->thread_info.requested_latency_valid = false;
3093 else if (dynamic)
3094 return;
3095
3096 if (PA_SINK_IS_LINKED(s->thread_info.state)) {
3097
3098 if (s->update_requested_latency)
3099 s->update_requested_latency(s);
3100
3101 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state)
3102 if (i->update_sink_requested_latency)
3103 i->update_sink_requested_latency(i);
3104 }
3105 }
3106
3107 /* Called from main thread */
3108 void pa_sink_set_latency_range(pa_sink *s, pa_usec_t min_latency, pa_usec_t max_latency) {
3109 pa_sink_assert_ref(s);
3110 pa_assert_ctl_context();
3111
3112 /* min_latency == 0: no limit
3113 * min_latency anything else: specified limit
3114 *
3115 * Similar for max_latency */
3116
3117 if (min_latency < ABSOLUTE_MIN_LATENCY)
3118 min_latency = ABSOLUTE_MIN_LATENCY;
3119
3120 if (max_latency <= 0 ||
3121 max_latency > ABSOLUTE_MAX_LATENCY)
3122 max_latency = ABSOLUTE_MAX_LATENCY;
3123
3124 pa_assert(min_latency <= max_latency);
3125
3126 /* Hmm, let's see if someone forgot to set PA_SINK_DYNAMIC_LATENCY here... */
3127 pa_assert((min_latency == ABSOLUTE_MIN_LATENCY &&
3128 max_latency == ABSOLUTE_MAX_LATENCY) ||
3129 (s->flags & PA_SINK_DYNAMIC_LATENCY));
3130
3131 if (PA_SINK_IS_LINKED(s->state)) {
3132 pa_usec_t r[2];
3133
3134 r[0] = min_latency;
3135 r[1] = max_latency;
3136
3137 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_LATENCY_RANGE, r, 0, NULL) == 0);
3138 } else
3139 pa_sink_set_latency_range_within_thread(s, min_latency, max_latency);
3140 }
3141
3142 /* Called from main thread */
3143 void pa_sink_get_latency_range(pa_sink *s, pa_usec_t *min_latency, pa_usec_t *max_latency) {
3144 pa_sink_assert_ref(s);
3145 pa_assert_ctl_context();
3146 pa_assert(min_latency);
3147 pa_assert(max_latency);
3148
3149 if (PA_SINK_IS_LINKED(s->state)) {
3150 pa_usec_t r[2] = { 0, 0 };
3151
3152 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_LATENCY_RANGE, r, 0, NULL) == 0);
3153
3154 *min_latency = r[0];
3155 *max_latency = r[1];
3156 } else {
3157 *min_latency = s->thread_info.min_latency;
3158 *max_latency = s->thread_info.max_latency;
3159 }
3160 }
3161
3162 /* Called from IO thread */
3163 void pa_sink_set_latency_range_within_thread(pa_sink *s, pa_usec_t min_latency, pa_usec_t max_latency) {
3164 pa_sink_assert_ref(s);
3165 pa_sink_assert_io_context(s);
3166
3167 pa_assert(min_latency >= ABSOLUTE_MIN_LATENCY);
3168 pa_assert(max_latency <= ABSOLUTE_MAX_LATENCY);
3169 pa_assert(min_latency <= max_latency);
3170
3171 /* Hmm, let's see if someone forgot to set PA_SINK_DYNAMIC_LATENCY here... */
3172 pa_assert((min_latency == ABSOLUTE_MIN_LATENCY &&
3173 max_latency == ABSOLUTE_MAX_LATENCY) ||
3174 (s->flags & PA_SINK_DYNAMIC_LATENCY));
3175
3176 if (s->thread_info.min_latency == min_latency &&
3177 s->thread_info.max_latency == max_latency)
3178 return;
3179
3180 s->thread_info.min_latency = min_latency;
3181 s->thread_info.max_latency = max_latency;
3182
3183 if (PA_SINK_IS_LINKED(s->thread_info.state)) {
3184 pa_sink_input *i;
3185 void *state = NULL;
3186
3187 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state)
3188 if (i->update_sink_latency_range)
3189 i->update_sink_latency_range(i);
3190 }
3191
3192 pa_sink_invalidate_requested_latency(s, false);
3193
3194 pa_source_set_latency_range_within_thread(s->monitor_source, min_latency, max_latency);
3195 }
3196
3197 /* Called from main thread */
3198 void pa_sink_set_fixed_latency(pa_sink *s, pa_usec_t latency) {
3199 pa_sink_assert_ref(s);
3200 pa_assert_ctl_context();
3201
3202 if (s->flags & PA_SINK_DYNAMIC_LATENCY) {
3203 pa_assert(latency == 0);
3204 return;
3205 }
3206
3207 if (latency < ABSOLUTE_MIN_LATENCY)
3208 latency = ABSOLUTE_MIN_LATENCY;
3209
3210 if (latency > ABSOLUTE_MAX_LATENCY)
3211 latency = ABSOLUTE_MAX_LATENCY;
3212
3213 if (PA_SINK_IS_LINKED(s->state))
3214 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_FIXED_LATENCY, NULL, (int64_t) latency, NULL) == 0);
3215 else
3216 s->thread_info.fixed_latency = latency;
3217
3218 pa_source_set_fixed_latency(s->monitor_source, latency);
3219 }
3220
3221 /* Called from main thread */
3222 pa_usec_t pa_sink_get_fixed_latency(pa_sink *s) {
3223 pa_usec_t latency;
3224
3225 pa_sink_assert_ref(s);
3226 pa_assert_ctl_context();
3227
3228 if (s->flags & PA_SINK_DYNAMIC_LATENCY)
3229 return 0;
3230
3231 if (PA_SINK_IS_LINKED(s->state))
3232 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_FIXED_LATENCY, &latency, 0, NULL) == 0);
3233 else
3234 latency = s->thread_info.fixed_latency;
3235
3236 return latency;
3237 }
3238
3239 /* Called from IO thread */
3240 void pa_sink_set_fixed_latency_within_thread(pa_sink *s, pa_usec_t latency) {
3241 pa_sink_assert_ref(s);
3242 pa_sink_assert_io_context(s);
3243
3244 if (s->flags & PA_SINK_DYNAMIC_LATENCY) {
3245 pa_assert(latency == 0);
3246 s->thread_info.fixed_latency = 0;
3247
3248 if (s->monitor_source)
3249 pa_source_set_fixed_latency_within_thread(s->monitor_source, 0);
3250
3251 return;
3252 }
3253
3254 pa_assert(latency >= ABSOLUTE_MIN_LATENCY);
3255 pa_assert(latency <= ABSOLUTE_MAX_LATENCY);
3256
3257 if (s->thread_info.fixed_latency == latency)
3258 return;
3259
3260 s->thread_info.fixed_latency = latency;
3261
3262 if (PA_SINK_IS_LINKED(s->thread_info.state)) {
3263 pa_sink_input *i;
3264 void *state = NULL;
3265
3266 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state)
3267 if (i->update_sink_fixed_latency)
3268 i->update_sink_fixed_latency(i);
3269 }
3270
3271 pa_sink_invalidate_requested_latency(s, false);
3272
3273 pa_source_set_fixed_latency_within_thread(s->monitor_source, latency);
3274 }
3275
3276 /* Called from main context */
3277 void pa_sink_set_latency_offset(pa_sink *s, int64_t offset) {
3278 pa_sink_assert_ref(s);
3279
3280 s->latency_offset = offset;
3281
3282 if (PA_SINK_IS_LINKED(s->state))
3283 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_LATENCY_OFFSET, NULL, offset, NULL) == 0);
3284 else
3285 s->thread_info.latency_offset = offset;
3286 }
3287
3288 /* Called from main context */
3289 size_t pa_sink_get_max_rewind(pa_sink *s) {
3290 size_t r;
3291 pa_assert_ctl_context();
3292 pa_sink_assert_ref(s);
3293
3294 if (!PA_SINK_IS_LINKED(s->state))
3295 return s->thread_info.max_rewind;
3296
3297 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_MAX_REWIND, &r, 0, NULL) == 0);
3298
3299 return r;
3300 }
3301
3302 /* Called from main context */
3303 size_t pa_sink_get_max_request(pa_sink *s) {
3304 size_t r;
3305 pa_sink_assert_ref(s);
3306 pa_assert_ctl_context();
3307
3308 if (!PA_SINK_IS_LINKED(s->state))
3309 return s->thread_info.max_request;
3310
3311 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_MAX_REQUEST, &r, 0, NULL) == 0);
3312
3313 return r;
3314 }
3315
3316 /* Called from main context */
3317 int pa_sink_set_port(pa_sink *s, const char *name, bool save) {
3318 pa_device_port *port;
3319 int ret;
3320
3321 pa_sink_assert_ref(s);
3322 pa_assert_ctl_context();
3323
3324 if (!s->set_port) {
3325 pa_log_debug("set_port() operation not implemented for sink %u \"%s\"", s->index, s->name);
3326 return -PA_ERR_NOTIMPLEMENTED;
3327 }
3328
3329 if (!name)
3330 return -PA_ERR_NOENTITY;
3331
3332 if (!(port = pa_hashmap_get(s->ports, name)))
3333 return -PA_ERR_NOENTITY;
3334
3335 if (s->active_port == port) {
3336 s->save_port = s->save_port || save;
3337 return 0;
3338 }
3339
3340 if (s->flags & PA_SINK_DEFERRED_VOLUME) {
3341 struct sink_message_set_port msg = { .port = port, .ret = 0 };
3342 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_PORT, &msg, 0, NULL) == 0);
3343 ret = msg.ret;
3344 }
3345 else
3346 ret = s->set_port(s, port);
3347
3348 if (ret < 0)
3349 return -PA_ERR_NOENTITY;
3350
3351 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
3352
3353 pa_log_info("Changed port of sink %u \"%s\" to %s", s->index, s->name, port->name);
3354
3355 s->active_port = port;
3356 s->save_port = save;
3357
3358 pa_sink_set_latency_offset(s, s->active_port->latency_offset);
3359
3360 pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_PORT_CHANGED], s);
3361
3362 return 0;
3363 }
3364
3365 bool pa_device_init_icon(pa_proplist *p, bool is_sink) {
3366 const char *ff, *c, *t = NULL, *s = "", *profile, *bus;
3367
3368 pa_assert(p);
3369
3370 if (pa_proplist_contains(p, PA_PROP_DEVICE_ICON_NAME))
3371 return true;
3372
3373 if ((ff = pa_proplist_gets(p, PA_PROP_DEVICE_FORM_FACTOR))) {
3374
3375 if (pa_streq(ff, "microphone"))
3376 t = "audio-input-microphone";
3377 else if (pa_streq(ff, "webcam"))
3378 t = "camera-web";
3379 else if (pa_streq(ff, "computer"))
3380 t = "computer";
3381 else if (pa_streq(ff, "handset"))
3382 t = "phone";
3383 else if (pa_streq(ff, "portable"))
3384 t = "multimedia-player";
3385 else if (pa_streq(ff, "tv"))
3386 t = "video-display";
3387
3388 /*
3389 * The following icons are not part of the icon naming spec,
3390 * because Rodney Dawes sucks as the maintainer of that spec.
3391 *
3392 * http://lists.freedesktop.org/archives/xdg/2009-May/010397.html
3393 */
3394 else if (pa_streq(ff, "headset"))
3395 t = "audio-headset";
3396 else if (pa_streq(ff, "headphone"))
3397 t = "audio-headphones";
3398 else if (pa_streq(ff, "speaker"))
3399 t = "audio-speakers";
3400 else if (pa_streq(ff, "hands-free"))
3401 t = "audio-handsfree";
3402 }
3403
3404 if (!t)
3405 if ((c = pa_proplist_gets(p, PA_PROP_DEVICE_CLASS)))
3406 if (pa_streq(c, "modem"))
3407 t = "modem";
3408
3409 if (!t) {
3410 if (is_sink)
3411 t = "audio-card";
3412 else
3413 t = "audio-input-microphone";
3414 }
3415
3416 if ((profile = pa_proplist_gets(p, PA_PROP_DEVICE_PROFILE_NAME))) {
3417 if (strstr(profile, "analog"))
3418 s = "-analog";
3419 else if (strstr(profile, "iec958"))
3420 s = "-iec958";
3421 else if (strstr(profile, "hdmi"))
3422 s = "-hdmi";
3423 }
3424
3425 bus = pa_proplist_gets(p, PA_PROP_DEVICE_BUS);
3426
3427 pa_proplist_setf(p, PA_PROP_DEVICE_ICON_NAME, "%s%s%s%s", t, pa_strempty(s), bus ? "-" : "", pa_strempty(bus));
3428
3429 return true;
3430 }
3431
3432 bool pa_device_init_description(pa_proplist *p, pa_card *card) {
3433 const char *s, *d = NULL, *k;
3434 pa_assert(p);
3435
3436 if (pa_proplist_contains(p, PA_PROP_DEVICE_DESCRIPTION))
3437 return true;
3438
3439 if (card)
3440 if ((s = pa_proplist_gets(card->proplist, PA_PROP_DEVICE_DESCRIPTION)))
3441 d = s;
3442
3443 if (!d)
3444 if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_FORM_FACTOR)))
3445 if (pa_streq(s, "internal"))
3446 d = _("Built-in Audio");
3447
3448 if (!d)
3449 if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_CLASS)))
3450 if (pa_streq(s, "modem"))
3451 d = _("Modem");
3452
3453 if (!d)
3454 d = pa_proplist_gets(p, PA_PROP_DEVICE_PRODUCT_NAME);
3455
3456 if (!d)
3457 return false;
3458
3459 k = pa_proplist_gets(p, PA_PROP_DEVICE_PROFILE_DESCRIPTION);
3460
3461 if (d && k)
3462 pa_proplist_setf(p, PA_PROP_DEVICE_DESCRIPTION, "%s %s", d, k);
3463 else if (d)
3464 pa_proplist_sets(p, PA_PROP_DEVICE_DESCRIPTION, d);
3465
3466 return true;
3467 }
3468
3469 bool pa_device_init_intended_roles(pa_proplist *p) {
3470 const char *s;
3471 pa_assert(p);
3472
3473 if (pa_proplist_contains(p, PA_PROP_DEVICE_INTENDED_ROLES))
3474 return true;
3475
3476 if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_FORM_FACTOR)))
3477 if (pa_streq(s, "handset") || pa_streq(s, "hands-free")
3478 || pa_streq(s, "headset")) {
3479 pa_proplist_sets(p, PA_PROP_DEVICE_INTENDED_ROLES, "phone");
3480 return true;
3481 }
3482
3483 return false;
3484 }
3485
3486 unsigned pa_device_init_priority(pa_proplist *p) {
3487 const char *s;
3488 unsigned priority = 0;
3489
3490 pa_assert(p);
3491
3492 if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_CLASS))) {
3493
3494 if (pa_streq(s, "sound"))
3495 priority += 9000;
3496 else if (!pa_streq(s, "modem"))
3497 priority += 1000;
3498 }
3499
3500 if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_FORM_FACTOR))) {
3501
3502 if (pa_streq(s, "internal"))
3503 priority += 900;
3504 else if (pa_streq(s, "speaker"))
3505 priority += 500;
3506 else if (pa_streq(s, "headphone"))
3507 priority += 400;
3508 }
3509
3510 if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_BUS))) {
3511
3512 if (pa_streq(s, "pci"))
3513 priority += 50;
3514 else if (pa_streq(s, "usb"))
3515 priority += 40;
3516 else if (pa_streq(s, "bluetooth"))
3517 priority += 30;
3518 }
3519
3520 if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_PROFILE_NAME))) {
3521
3522 if (pa_startswith(s, "analog-"))
3523 priority += 9;
3524 else if (pa_startswith(s, "iec958-"))
3525 priority += 8;
3526 }
3527
3528 return priority;
3529 }
3530
3531 PA_STATIC_FLIST_DECLARE(pa_sink_volume_change, 0, pa_xfree);
3532
3533 /* Called from the IO thread. */
3534 static pa_sink_volume_change *pa_sink_volume_change_new(pa_sink *s) {
3535 pa_sink_volume_change *c;
3536 if (!(c = pa_flist_pop(PA_STATIC_FLIST_GET(pa_sink_volume_change))))
3537 c = pa_xnew(pa_sink_volume_change, 1);
3538
3539 PA_LLIST_INIT(pa_sink_volume_change, c);
3540 c->at = 0;
3541 pa_cvolume_reset(&c->hw_volume, s->sample_spec.channels);
3542 return c;
3543 }
3544
3545 /* Called from the IO thread. */
3546 static void pa_sink_volume_change_free(pa_sink_volume_change *c) {
3547 pa_assert(c);
3548 if (pa_flist_push(PA_STATIC_FLIST_GET(pa_sink_volume_change), c) < 0)
3549 pa_xfree(c);
3550 }
3551
3552 /* Called from the IO thread. */
3553 void pa_sink_volume_change_push(pa_sink *s) {
3554 pa_sink_volume_change *c = NULL;
3555 pa_sink_volume_change *nc = NULL;
3556 uint32_t safety_margin = s->thread_info.volume_change_safety_margin;
3557
3558 const char *direction = NULL;
3559
3560 pa_assert(s);
3561 nc = pa_sink_volume_change_new(s);
3562
3563 /* NOTE: There is already more different volumes in pa_sink that I can remember.
3564 * Adding one more volume for HW would get us rid of this, but I am trying
3565 * to survive with the ones we already have. */
3566 pa_sw_cvolume_divide(&nc->hw_volume, &s->real_volume, &s->soft_volume);
3567
3568 if (!s->thread_info.volume_changes && pa_cvolume_equal(&nc->hw_volume, &s->thread_info.current_hw_volume)) {
3569 pa_log_debug("Volume not changing");
3570 pa_sink_volume_change_free(nc);
3571 return;
3572 }
3573
3574 nc->at = pa_sink_get_latency_within_thread(s);
3575 nc->at += pa_rtclock_now() + s->thread_info.volume_change_extra_delay;
3576
3577 if (s->thread_info.volume_changes_tail) {
3578 for (c = s->thread_info.volume_changes_tail; c; c = c->prev) {
3579 /* If volume is going up let's do it a bit late. If it is going
3580 * down let's do it a bit early. */
3581 if (pa_cvolume_avg(&nc->hw_volume) > pa_cvolume_avg(&c->hw_volume)) {
3582 if (nc->at + safety_margin > c->at) {
3583 nc->at += safety_margin;
3584 direction = "up";
3585 break;
3586 }
3587 }
3588 else if (nc->at - safety_margin > c->at) {
3589 nc->at -= safety_margin;
3590 direction = "down";
3591 break;
3592 }
3593 }
3594 }
3595
3596 if (c == NULL) {
3597 if (pa_cvolume_avg(&nc->hw_volume) > pa_cvolume_avg(&s->thread_info.current_hw_volume)) {
3598 nc->at += safety_margin;
3599 direction = "up";
3600 } else {
3601 nc->at -= safety_margin;
3602 direction = "down";
3603 }
3604 PA_LLIST_PREPEND(pa_sink_volume_change, s->thread_info.volume_changes, nc);
3605 }
3606 else {
3607 PA_LLIST_INSERT_AFTER(pa_sink_volume_change, s->thread_info.volume_changes, c, nc);
3608 }
3609
3610 pa_log_debug("Volume going %s to %d at %llu", direction, pa_cvolume_avg(&nc->hw_volume), (long long unsigned) nc->at);
3611
3612 /* We can ignore volume events that came earlier but should happen later than this. */
3613 PA_LLIST_FOREACH(c, nc->next) {
3614 pa_log_debug("Volume change to %d at %llu was dropped", pa_cvolume_avg(&c->hw_volume), (long long unsigned) c->at);
3615 pa_sink_volume_change_free(c);
3616 }
3617 nc->next = NULL;
3618 s->thread_info.volume_changes_tail = nc;
3619 }
3620
3621 /* Called from the IO thread. */
3622 static void pa_sink_volume_change_flush(pa_sink *s) {
3623 pa_sink_volume_change *c = s->thread_info.volume_changes;
3624 pa_assert(s);
3625 s->thread_info.volume_changes = NULL;
3626 s->thread_info.volume_changes_tail = NULL;
3627 while (c) {
3628 pa_sink_volume_change *next = c->next;
3629 pa_sink_volume_change_free(c);
3630 c = next;
3631 }
3632 }
3633
3634 /* Called from the IO thread. */
3635 bool pa_sink_volume_change_apply(pa_sink *s, pa_usec_t *usec_to_next) {
3636 pa_usec_t now;
3637 bool ret = false;
3638
3639 pa_assert(s);
3640
3641 if (!s->thread_info.volume_changes || !PA_SINK_IS_LINKED(s->state)) {
3642 if (usec_to_next)
3643 *usec_to_next = 0;
3644 return ret;
3645 }
3646
3647 pa_assert(s->write_volume);
3648
3649 now = pa_rtclock_now();
3650
3651 while (s->thread_info.volume_changes && now >= s->thread_info.volume_changes->at) {
3652 pa_sink_volume_change *c = s->thread_info.volume_changes;
3653 PA_LLIST_REMOVE(pa_sink_volume_change, s->thread_info.volume_changes, c);
3654 pa_log_debug("Volume change to %d at %llu was written %llu usec late",
3655 pa_cvolume_avg(&c->hw_volume), (long long unsigned) c->at, (long long unsigned) (now - c->at));
3656 ret = true;
3657 s->thread_info.current_hw_volume = c->hw_volume;
3658 pa_sink_volume_change_free(c);
3659 }
3660
3661 if (ret)
3662 s->write_volume(s);
3663
3664 if (s->thread_info.volume_changes) {
3665 if (usec_to_next)
3666 *usec_to_next = s->thread_info.volume_changes->at - now;
3667 if (pa_log_ratelimit(PA_LOG_DEBUG))
3668 pa_log_debug("Next volume change in %lld usec", (long long) (s->thread_info.volume_changes->at - now));
3669 }
3670 else {
3671 if (usec_to_next)
3672 *usec_to_next = 0;
3673 s->thread_info.volume_changes_tail = NULL;
3674 }
3675 return ret;
3676 }
3677
3678 /* Called from the IO thread. */
3679 static void pa_sink_volume_change_rewind(pa_sink *s, size_t nbytes) {
3680 /* All the queued volume events later than current latency are shifted to happen earlier. */
3681 pa_sink_volume_change *c;
3682 pa_volume_t prev_vol = pa_cvolume_avg(&s->thread_info.current_hw_volume);
3683 pa_usec_t rewound = pa_bytes_to_usec(nbytes, &s->sample_spec);
3684 pa_usec_t limit = pa_sink_get_latency_within_thread(s);
3685
3686 pa_log_debug("latency = %lld", (long long) limit);
3687 limit += pa_rtclock_now() + s->thread_info.volume_change_extra_delay;
3688
3689 PA_LLIST_FOREACH(c, s->thread_info.volume_changes) {
3690 pa_usec_t modified_limit = limit;
3691 if (prev_vol > pa_cvolume_avg(&c->hw_volume))
3692 modified_limit -= s->thread_info.volume_change_safety_margin;
3693 else
3694 modified_limit += s->thread_info.volume_change_safety_margin;
3695 if (c->at > modified_limit) {
3696 c->at -= rewound;
3697 if (c->at < modified_limit)
3698 c->at = modified_limit;
3699 }
3700 prev_vol = pa_cvolume_avg(&c->hw_volume);
3701 }
3702 pa_sink_volume_change_apply(s, NULL);
3703 }
3704
3705 /* Called from the main thread */
3706 /* Gets the list of formats supported by the sink. The members and idxset must
3707 * be freed by the caller. */
3708 pa_idxset* pa_sink_get_formats(pa_sink *s) {
3709 pa_idxset *ret;
3710
3711 pa_assert(s);
3712
3713 if (s->get_formats) {
3714 /* Sink supports format query, all is good */
3715 ret = s->get_formats(s);
3716 } else {
3717 /* Sink doesn't support format query, so assume it does PCM */
3718 pa_format_info *f = pa_format_info_new();
3719 f->encoding = PA_ENCODING_PCM;
3720
3721 ret = pa_idxset_new(NULL, NULL);
3722 pa_idxset_put(ret, f, NULL);
3723 }
3724
3725 return ret;
3726 }
3727
3728 /* Called from the main thread */
3729 /* Allows an external source to set what formats a sink supports if the sink
3730 * permits this. The function makes a copy of the formats on success. */
3731 bool pa_sink_set_formats(pa_sink *s, pa_idxset *formats) {
3732 pa_assert(s);
3733 pa_assert(formats);
3734
3735 if (s->set_formats)
3736 /* Sink supports setting formats -- let's give it a shot */
3737 return s->set_formats(s, formats);
3738 else
3739 /* Sink doesn't support setting this -- bail out */
3740 return false;
3741 }
3742
3743 /* Called from the main thread */
3744 /* Checks if the sink can accept this format */
3745 bool pa_sink_check_format(pa_sink *s, pa_format_info *f) {
3746 pa_idxset *formats = NULL;
3747 bool ret = false;
3748
3749 pa_assert(s);
3750 pa_assert(f);
3751
3752 formats = pa_sink_get_formats(s);
3753
3754 if (formats) {
3755 pa_format_info *finfo_device;
3756 uint32_t i;
3757
3758 PA_IDXSET_FOREACH(finfo_device, formats, i) {
3759 if (pa_format_info_is_compatible(finfo_device, f)) {
3760 ret = true;
3761 break;
3762 }
3763 }
3764
3765 pa_idxset_free(formats, (pa_free_cb_t) pa_format_info_free);
3766 }
3767
3768 return ret;
3769 }
3770
3771 /* Called from the main thread */
3772 /* Calculates the intersection between formats supported by the sink and
3773 * in_formats, and returns these, in the order of the sink's formats. */
3774 pa_idxset* pa_sink_check_formats(pa_sink *s, pa_idxset *in_formats) {
3775 pa_idxset *out_formats = pa_idxset_new(NULL, NULL), *sink_formats = NULL;
3776 pa_format_info *f_sink, *f_in;
3777 uint32_t i, j;
3778
3779 pa_assert(s);
3780
3781 if (!in_formats || pa_idxset_isempty(in_formats))
3782 goto done;
3783
3784 sink_formats = pa_sink_get_formats(s);
3785
3786 PA_IDXSET_FOREACH(f_sink, sink_formats, i) {
3787 PA_IDXSET_FOREACH(f_in, in_formats, j) {
3788 if (pa_format_info_is_compatible(f_sink, f_in))
3789 pa_idxset_put(out_formats, pa_format_info_copy(f_in), NULL);
3790 }
3791 }
3792
3793 done:
3794 if (sink_formats)
3795 pa_idxset_free(sink_formats, (pa_free_cb_t) pa_format_info_free);
3796
3797 return out_formats;
3798 }
3799
3800 /* Called from the main thread. */
3801 void pa_sink_set_reference_volume_direct(pa_sink *s, const pa_cvolume *volume) {
3802 pa_cvolume old_volume;
3803 char old_volume_str[PA_CVOLUME_SNPRINT_VERBOSE_MAX];
3804 char new_volume_str[PA_CVOLUME_SNPRINT_VERBOSE_MAX];
3805
3806 pa_assert(s);
3807 pa_assert(volume);
3808
3809 old_volume = s->reference_volume;
3810
3811 if (pa_cvolume_equal(volume, &old_volume))
3812 return;
3813
3814 s->reference_volume = *volume;
3815 pa_log_debug("The reference volume of sink %s changed from %s to %s.", s->name,
3816 pa_cvolume_snprint_verbose(old_volume_str, sizeof(old_volume_str), &old_volume, &s->channel_map,
3817 s->flags & PA_SINK_DECIBEL_VOLUME),
3818 pa_cvolume_snprint_verbose(new_volume_str, sizeof(new_volume_str), volume, &s->channel_map,
3819 s->flags & PA_SINK_DECIBEL_VOLUME));
3820
3821 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
3822 }