]> code.delx.au - pulseaudio/blob - src/pulsecore/sink.c
94ddac96eb462e12b0432a7ce5461d90bdb799af
[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 new_input_volume;
1839
1840 /* Follow the root sink's real volume. */
1841 new_input_volume = *new_volume;
1842 pa_cvolume_remap(&new_input_volume, channel_map, &i->channel_map);
1843 pa_sink_input_set_volume_direct(i, &new_input_volume);
1844 compute_reference_ratio(i);
1845 }
1846
1847 update_real_volume(i->origin_sink, new_volume, channel_map);
1848 }
1849 }
1850 }
1851
1852 /* Called from main thread. Only called for the root sink in shared volume
1853 * cases. */
1854 static void compute_real_volume(pa_sink *s) {
1855 pa_sink_assert_ref(s);
1856 pa_assert_ctl_context();
1857 pa_assert(PA_SINK_IS_LINKED(s->state));
1858 pa_assert(pa_sink_flat_volume_enabled(s));
1859 pa_assert(!(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER));
1860
1861 /* This determines the maximum volume of all streams and sets
1862 * s->real_volume accordingly. */
1863
1864 if (!has_inputs(s)) {
1865 /* In the special case that we have no sink inputs we leave the
1866 * volume unmodified. */
1867 update_real_volume(s, &s->reference_volume, &s->channel_map);
1868 return;
1869 }
1870
1871 pa_cvolume_mute(&s->real_volume, s->channel_map.channels);
1872
1873 /* First let's determine the new maximum volume of all inputs
1874 * connected to this sink */
1875 get_maximum_input_volume(s, &s->real_volume, &s->channel_map);
1876 update_real_volume(s, &s->real_volume, &s->channel_map);
1877
1878 /* Then, let's update the real ratios/soft volumes of all inputs
1879 * connected to this sink */
1880 compute_real_ratios(s);
1881 }
1882
1883 /* Called from main thread. Only called for the root sink in shared volume
1884 * cases, except for internal recursive calls. */
1885 static void propagate_reference_volume(pa_sink *s) {
1886 pa_sink_input *i;
1887 uint32_t idx;
1888
1889 pa_sink_assert_ref(s);
1890 pa_assert_ctl_context();
1891 pa_assert(PA_SINK_IS_LINKED(s->state));
1892 pa_assert(pa_sink_flat_volume_enabled(s));
1893
1894 /* This is called whenever the sink volume changes that is not
1895 * caused by a sink input volume change. We need to fix up the
1896 * sink input volumes accordingly */
1897
1898 PA_IDXSET_FOREACH(i, s->inputs, idx) {
1899 pa_cvolume new_volume;
1900
1901 if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)) {
1902 propagate_reference_volume(i->origin_sink);
1903
1904 /* Since the origin sink uses volume sharing, this input's volume
1905 * needs to be updated to match the root sink's real volume, but
1906 * that will be done later in update_shared_real_volume(). */
1907 continue;
1908 }
1909
1910 /* This basically calculates:
1911 *
1912 * i->volume := s->reference_volume * i->reference_ratio */
1913
1914 new_volume = s->reference_volume;
1915 pa_cvolume_remap(&new_volume, &s->channel_map, &i->channel_map);
1916 pa_sw_cvolume_multiply(&new_volume, &new_volume, &i->reference_ratio);
1917 pa_sink_input_set_volume_direct(i, &new_volume);
1918 }
1919 }
1920
1921 /* Called from main thread. Only called for the root sink in volume sharing
1922 * cases, except for internal recursive calls. The return value indicates
1923 * whether any reference volume actually changed. */
1924 static bool update_reference_volume(pa_sink *s, const pa_cvolume *v, const pa_channel_map *channel_map, bool save) {
1925 pa_cvolume volume;
1926 bool reference_volume_changed;
1927 pa_sink_input *i;
1928 uint32_t idx;
1929
1930 pa_sink_assert_ref(s);
1931 pa_assert(PA_SINK_IS_LINKED(s->state));
1932 pa_assert(v);
1933 pa_assert(channel_map);
1934 pa_assert(pa_cvolume_valid(v));
1935
1936 volume = *v;
1937 pa_cvolume_remap(&volume, channel_map, &s->channel_map);
1938
1939 reference_volume_changed = !pa_cvolume_equal(&volume, &s->reference_volume);
1940 pa_sink_set_reference_volume_direct(s, &volume);
1941
1942 s->save_volume = (!reference_volume_changed && s->save_volume) || save;
1943
1944 if (!reference_volume_changed && !(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER))
1945 /* If the root sink's volume doesn't change, then there can't be any
1946 * changes in the other sinks in the sink tree either.
1947 *
1948 * It's probably theoretically possible that even if the root sink's
1949 * volume changes slightly, some filter sink doesn't change its volume
1950 * due to rounding errors. If that happens, we still want to propagate
1951 * the changed root sink volume to the sinks connected to the
1952 * intermediate sink that didn't change its volume. This theoretical
1953 * possibility is the reason why we have that !(s->flags &
1954 * PA_SINK_SHARE_VOLUME_WITH_MASTER) condition. Probably nobody would
1955 * notice even if we returned here false always if
1956 * reference_volume_changed is false. */
1957 return false;
1958
1959 PA_IDXSET_FOREACH(i, s->inputs, idx) {
1960 if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER))
1961 update_reference_volume(i->origin_sink, v, channel_map, false);
1962 }
1963
1964 return true;
1965 }
1966
1967 /* Called from main thread */
1968 void pa_sink_set_volume(
1969 pa_sink *s,
1970 const pa_cvolume *volume,
1971 bool send_msg,
1972 bool save) {
1973
1974 pa_cvolume new_reference_volume;
1975 pa_sink *root_sink;
1976
1977 pa_sink_assert_ref(s);
1978 pa_assert_ctl_context();
1979 pa_assert(PA_SINK_IS_LINKED(s->state));
1980 pa_assert(!volume || pa_cvolume_valid(volume));
1981 pa_assert(volume || pa_sink_flat_volume_enabled(s));
1982 pa_assert(!volume || volume->channels == 1 || pa_cvolume_compatible(volume, &s->sample_spec));
1983
1984 /* make sure we don't change the volume when a PASSTHROUGH input is connected ...
1985 * ... *except* if we're being invoked to reset the volume to ensure 0 dB gain */
1986 if (pa_sink_is_passthrough(s) && (!volume || !pa_cvolume_is_norm(volume))) {
1987 pa_log_warn("Cannot change volume, Sink is connected to PASSTHROUGH input");
1988 return;
1989 }
1990
1991 /* In case of volume sharing, the volume is set for the root sink first,
1992 * from which it's then propagated to the sharing sinks. */
1993 root_sink = pa_sink_get_master(s);
1994
1995 if (PA_UNLIKELY(!root_sink))
1996 return;
1997
1998 /* As a special exception we accept mono volumes on all sinks --
1999 * even on those with more complex channel maps */
2000
2001 if (volume) {
2002 if (pa_cvolume_compatible(volume, &s->sample_spec))
2003 new_reference_volume = *volume;
2004 else {
2005 new_reference_volume = s->reference_volume;
2006 pa_cvolume_scale(&new_reference_volume, pa_cvolume_max(volume));
2007 }
2008
2009 pa_cvolume_remap(&new_reference_volume, &s->channel_map, &root_sink->channel_map);
2010
2011 if (update_reference_volume(root_sink, &new_reference_volume, &root_sink->channel_map, save)) {
2012 if (pa_sink_flat_volume_enabled(root_sink)) {
2013 /* OK, propagate this volume change back to the inputs */
2014 propagate_reference_volume(root_sink);
2015
2016 /* And now recalculate the real volume */
2017 compute_real_volume(root_sink);
2018 } else
2019 update_real_volume(root_sink, &root_sink->reference_volume, &root_sink->channel_map);
2020 }
2021
2022 } else {
2023 /* If volume is NULL we synchronize the sink's real and
2024 * reference volumes with the stream volumes. */
2025
2026 pa_assert(pa_sink_flat_volume_enabled(root_sink));
2027
2028 /* Ok, let's determine the new real volume */
2029 compute_real_volume(root_sink);
2030
2031 /* Let's 'push' the reference volume if necessary */
2032 pa_cvolume_merge(&new_reference_volume, &s->reference_volume, &root_sink->real_volume);
2033 /* If the sink and its root don't have the same number of channels, we need to remap */
2034 if (s != root_sink && !pa_channel_map_equal(&s->channel_map, &root_sink->channel_map))
2035 pa_cvolume_remap(&new_reference_volume, &s->channel_map, &root_sink->channel_map);
2036 update_reference_volume(root_sink, &new_reference_volume, &root_sink->channel_map, save);
2037
2038 /* Now that the reference volume is updated, we can update the streams'
2039 * reference ratios. */
2040 compute_reference_ratios(root_sink);
2041 }
2042
2043 if (root_sink->set_volume) {
2044 /* If we have a function set_volume(), then we do not apply a
2045 * soft volume by default. However, set_volume() is free to
2046 * apply one to root_sink->soft_volume */
2047
2048 pa_cvolume_reset(&root_sink->soft_volume, root_sink->sample_spec.channels);
2049 if (!(root_sink->flags & PA_SINK_DEFERRED_VOLUME))
2050 root_sink->set_volume(root_sink);
2051
2052 } else
2053 /* If we have no function set_volume(), then the soft volume
2054 * becomes the real volume */
2055 root_sink->soft_volume = root_sink->real_volume;
2056
2057 /* This tells the sink that soft volume and/or real volume changed */
2058 if (send_msg)
2059 pa_assert_se(pa_asyncmsgq_send(root_sink->asyncmsgq, PA_MSGOBJECT(root_sink), PA_SINK_MESSAGE_SET_SHARED_VOLUME, NULL, 0, NULL) == 0);
2060 }
2061
2062 /* Called from the io thread if sync volume is used, otherwise from the main thread.
2063 * Only to be called by sink implementor */
2064 void pa_sink_set_soft_volume(pa_sink *s, const pa_cvolume *volume) {
2065
2066 pa_sink_assert_ref(s);
2067 pa_assert(!(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER));
2068
2069 if (s->flags & PA_SINK_DEFERRED_VOLUME)
2070 pa_sink_assert_io_context(s);
2071 else
2072 pa_assert_ctl_context();
2073
2074 if (!volume)
2075 pa_cvolume_reset(&s->soft_volume, s->sample_spec.channels);
2076 else
2077 s->soft_volume = *volume;
2078
2079 if (PA_SINK_IS_LINKED(s->state) && !(s->flags & PA_SINK_DEFERRED_VOLUME))
2080 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_VOLUME, NULL, 0, NULL) == 0);
2081 else
2082 s->thread_info.soft_volume = s->soft_volume;
2083 }
2084
2085 /* Called from the main thread. Only called for the root sink in volume sharing
2086 * cases, except for internal recursive calls. */
2087 static void propagate_real_volume(pa_sink *s, const pa_cvolume *old_real_volume) {
2088 pa_sink_input *i;
2089 uint32_t idx;
2090
2091 pa_sink_assert_ref(s);
2092 pa_assert(old_real_volume);
2093 pa_assert_ctl_context();
2094 pa_assert(PA_SINK_IS_LINKED(s->state));
2095
2096 /* This is called when the hardware's real volume changes due to
2097 * some external event. We copy the real volume into our
2098 * reference volume and then rebuild the stream volumes based on
2099 * i->real_ratio which should stay fixed. */
2100
2101 if (!(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)) {
2102 if (pa_cvolume_equal(old_real_volume, &s->real_volume))
2103 return;
2104
2105 /* 1. Make the real volume the reference volume */
2106 update_reference_volume(s, &s->real_volume, &s->channel_map, true);
2107 }
2108
2109 if (pa_sink_flat_volume_enabled(s)) {
2110
2111 PA_IDXSET_FOREACH(i, s->inputs, idx) {
2112 pa_cvolume new_volume;
2113
2114 /* 2. Since the sink's reference and real volumes are equal
2115 * now our ratios should be too. */
2116 i->reference_ratio = i->real_ratio;
2117
2118 /* 3. Recalculate the new stream reference volume based on the
2119 * reference ratio and the sink's reference volume.
2120 *
2121 * This basically calculates:
2122 *
2123 * i->volume = s->reference_volume * i->reference_ratio
2124 *
2125 * This is identical to propagate_reference_volume() */
2126 new_volume = s->reference_volume;
2127 pa_cvolume_remap(&new_volume, &s->channel_map, &i->channel_map);
2128 pa_sw_cvolume_multiply(&new_volume, &new_volume, &i->reference_ratio);
2129 pa_sink_input_set_volume_direct(i, &new_volume);
2130
2131 if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER))
2132 propagate_real_volume(i->origin_sink, old_real_volume);
2133 }
2134 }
2135
2136 /* Something got changed in the hardware. It probably makes sense
2137 * to save changed hw settings given that hw volume changes not
2138 * triggered by PA are almost certainly done by the user. */
2139 if (!(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER))
2140 s->save_volume = true;
2141 }
2142
2143 /* Called from io thread */
2144 void pa_sink_update_volume_and_mute(pa_sink *s) {
2145 pa_assert(s);
2146 pa_sink_assert_io_context(s);
2147
2148 pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_UPDATE_VOLUME_AND_MUTE, NULL, 0, NULL, NULL);
2149 }
2150
2151 /* Called from main thread */
2152 const pa_cvolume *pa_sink_get_volume(pa_sink *s, bool force_refresh) {
2153 pa_sink_assert_ref(s);
2154 pa_assert_ctl_context();
2155 pa_assert(PA_SINK_IS_LINKED(s->state));
2156
2157 if (s->refresh_volume || force_refresh) {
2158 struct pa_cvolume old_real_volume;
2159
2160 pa_assert(!(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER));
2161
2162 old_real_volume = s->real_volume;
2163
2164 if (!(s->flags & PA_SINK_DEFERRED_VOLUME) && s->get_volume)
2165 s->get_volume(s);
2166
2167 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_VOLUME, NULL, 0, NULL) == 0);
2168
2169 update_real_volume(s, &s->real_volume, &s->channel_map);
2170 propagate_real_volume(s, &old_real_volume);
2171 }
2172
2173 return &s->reference_volume;
2174 }
2175
2176 /* Called from main thread. In volume sharing cases, only the root sink may
2177 * call this. */
2178 void pa_sink_volume_changed(pa_sink *s, const pa_cvolume *new_real_volume) {
2179 pa_cvolume old_real_volume;
2180
2181 pa_sink_assert_ref(s);
2182 pa_assert_ctl_context();
2183 pa_assert(PA_SINK_IS_LINKED(s->state));
2184 pa_assert(!(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER));
2185
2186 /* The sink implementor may call this if the volume changed to make sure everyone is notified */
2187
2188 old_real_volume = s->real_volume;
2189 update_real_volume(s, new_real_volume, &s->channel_map);
2190 propagate_real_volume(s, &old_real_volume);
2191 }
2192
2193 /* Called from main thread */
2194 void pa_sink_set_mute(pa_sink *s, bool mute, bool save) {
2195 bool old_muted;
2196
2197 pa_sink_assert_ref(s);
2198 pa_assert_ctl_context();
2199
2200 old_muted = s->muted;
2201
2202 if (mute == old_muted) {
2203 s->save_muted |= save;
2204 return;
2205 }
2206
2207 s->muted = mute;
2208 s->save_muted = save;
2209
2210 if (!(s->flags & PA_SINK_DEFERRED_VOLUME) && s->set_mute) {
2211 s->set_mute_in_progress = true;
2212 s->set_mute(s);
2213 s->set_mute_in_progress = false;
2214 }
2215
2216 if (!PA_SINK_IS_LINKED(s->state))
2217 return;
2218
2219 pa_log_debug("The mute of sink %s changed from %s to %s.", s->name, pa_yes_no(old_muted), pa_yes_no(mute));
2220 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_MUTE, NULL, 0, NULL) == 0);
2221 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
2222 }
2223
2224 /* Called from main thread */
2225 bool pa_sink_get_mute(pa_sink *s, bool force_refresh) {
2226
2227 pa_sink_assert_ref(s);
2228 pa_assert_ctl_context();
2229 pa_assert(PA_SINK_IS_LINKED(s->state));
2230
2231 if (s->refresh_muted || force_refresh) {
2232 bool old_muted = s->muted;
2233
2234 if (!(s->flags & PA_SINK_DEFERRED_VOLUME) && s->get_mute)
2235 s->get_mute(s);
2236
2237 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_MUTE, NULL, 0, NULL) == 0);
2238
2239 if (old_muted != s->muted) {
2240 s->save_muted = true;
2241
2242 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
2243
2244 /* Make sure the soft mute status stays in sync */
2245 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_MUTE, NULL, 0, NULL) == 0);
2246 }
2247 }
2248
2249 return s->muted;
2250 }
2251
2252 /* Called from main thread */
2253 void pa_sink_mute_changed(pa_sink *s, bool new_muted) {
2254 pa_sink_assert_ref(s);
2255 pa_assert_ctl_context();
2256 pa_assert(PA_SINK_IS_LINKED(s->state));
2257
2258 if (s->set_mute_in_progress)
2259 return;
2260
2261 /* pa_sink_set_mute() does this same check, so this may appear redundant,
2262 * but we must have this here also, because the save parameter of
2263 * pa_sink_set_mute() would otherwise have unintended side effects (saving
2264 * the mute state when it shouldn't be saved). */
2265 if (new_muted == s->muted)
2266 return;
2267
2268 pa_sink_set_mute(s, new_muted, true);
2269 }
2270
2271 /* Called from main thread */
2272 bool pa_sink_update_proplist(pa_sink *s, pa_update_mode_t mode, pa_proplist *p) {
2273 pa_sink_assert_ref(s);
2274 pa_assert_ctl_context();
2275
2276 if (p)
2277 pa_proplist_update(s->proplist, mode, p);
2278
2279 if (PA_SINK_IS_LINKED(s->state)) {
2280 pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_PROPLIST_CHANGED], s);
2281 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
2282 }
2283
2284 return true;
2285 }
2286
2287 /* Called from main thread */
2288 /* FIXME -- this should be dropped and be merged into pa_sink_update_proplist() */
2289 void pa_sink_set_description(pa_sink *s, const char *description) {
2290 const char *old;
2291 pa_sink_assert_ref(s);
2292 pa_assert_ctl_context();
2293
2294 if (!description && !pa_proplist_contains(s->proplist, PA_PROP_DEVICE_DESCRIPTION))
2295 return;
2296
2297 old = pa_proplist_gets(s->proplist, PA_PROP_DEVICE_DESCRIPTION);
2298
2299 if (old && description && pa_streq(old, description))
2300 return;
2301
2302 if (description)
2303 pa_proplist_sets(s->proplist, PA_PROP_DEVICE_DESCRIPTION, description);
2304 else
2305 pa_proplist_unset(s->proplist, PA_PROP_DEVICE_DESCRIPTION);
2306
2307 if (s->monitor_source) {
2308 char *n;
2309
2310 n = pa_sprintf_malloc("Monitor Source of %s", description ? description : s->name);
2311 pa_source_set_description(s->monitor_source, n);
2312 pa_xfree(n);
2313 }
2314
2315 if (PA_SINK_IS_LINKED(s->state)) {
2316 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
2317 pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_PROPLIST_CHANGED], s);
2318 }
2319 }
2320
2321 /* Called from main thread */
2322 unsigned pa_sink_linked_by(pa_sink *s) {
2323 unsigned ret;
2324
2325 pa_sink_assert_ref(s);
2326 pa_assert_ctl_context();
2327 pa_assert(PA_SINK_IS_LINKED(s->state));
2328
2329 ret = pa_idxset_size(s->inputs);
2330
2331 /* We add in the number of streams connected to us here. Please
2332 * note the asymmetry to pa_sink_used_by()! */
2333
2334 if (s->monitor_source)
2335 ret += pa_source_linked_by(s->monitor_source);
2336
2337 return ret;
2338 }
2339
2340 /* Called from main thread */
2341 unsigned pa_sink_used_by(pa_sink *s) {
2342 unsigned ret;
2343
2344 pa_sink_assert_ref(s);
2345 pa_assert_ctl_context();
2346 pa_assert(PA_SINK_IS_LINKED(s->state));
2347
2348 ret = pa_idxset_size(s->inputs);
2349 pa_assert(ret >= s->n_corked);
2350
2351 /* Streams connected to our monitor source do not matter for
2352 * pa_sink_used_by()!.*/
2353
2354 return ret - s->n_corked;
2355 }
2356
2357 /* Called from main thread */
2358 unsigned pa_sink_check_suspend(pa_sink *s) {
2359 unsigned ret;
2360 pa_sink_input *i;
2361 uint32_t idx;
2362
2363 pa_sink_assert_ref(s);
2364 pa_assert_ctl_context();
2365
2366 if (!PA_SINK_IS_LINKED(s->state))
2367 return 0;
2368
2369 ret = 0;
2370
2371 PA_IDXSET_FOREACH(i, s->inputs, idx) {
2372 pa_sink_input_state_t st;
2373
2374 st = pa_sink_input_get_state(i);
2375
2376 /* We do not assert here. It is perfectly valid for a sink input to
2377 * be in the INIT state (i.e. created, marked done but not yet put)
2378 * and we should not care if it's unlinked as it won't contribute
2379 * towards our busy status.
2380 */
2381 if (!PA_SINK_INPUT_IS_LINKED(st))
2382 continue;
2383
2384 if (st == PA_SINK_INPUT_CORKED)
2385 continue;
2386
2387 if (i->flags & PA_SINK_INPUT_DONT_INHIBIT_AUTO_SUSPEND)
2388 continue;
2389
2390 ret ++;
2391 }
2392
2393 if (s->monitor_source)
2394 ret += pa_source_check_suspend(s->monitor_source);
2395
2396 return ret;
2397 }
2398
2399 /* Called from the IO thread */
2400 static void sync_input_volumes_within_thread(pa_sink *s) {
2401 pa_sink_input *i;
2402 void *state = NULL;
2403
2404 pa_sink_assert_ref(s);
2405 pa_sink_assert_io_context(s);
2406
2407 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state) {
2408 if (pa_cvolume_equal(&i->thread_info.soft_volume, &i->soft_volume))
2409 continue;
2410
2411 i->thread_info.soft_volume = i->soft_volume;
2412 pa_sink_input_request_rewind(i, 0, true, false, false);
2413 }
2414 }
2415
2416 /* Called from the IO thread. Only called for the root sink in volume sharing
2417 * cases, except for internal recursive calls. */
2418 static void set_shared_volume_within_thread(pa_sink *s) {
2419 pa_sink_input *i = NULL;
2420 void *state = NULL;
2421
2422 pa_sink_assert_ref(s);
2423
2424 PA_MSGOBJECT(s)->process_msg(PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_VOLUME_SYNCED, NULL, 0, NULL);
2425
2426 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state) {
2427 if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER))
2428 set_shared_volume_within_thread(i->origin_sink);
2429 }
2430 }
2431
2432 /* Called from IO thread, except when it is not */
2433 int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {
2434 pa_sink *s = PA_SINK(o);
2435 pa_sink_assert_ref(s);
2436
2437 switch ((pa_sink_message_t) code) {
2438
2439 case PA_SINK_MESSAGE_ADD_INPUT: {
2440 pa_sink_input *i = PA_SINK_INPUT(userdata);
2441
2442 /* If you change anything here, make sure to change the
2443 * sink input handling a few lines down at
2444 * PA_SINK_MESSAGE_FINISH_MOVE, too. */
2445
2446 pa_hashmap_put(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index), pa_sink_input_ref(i));
2447
2448 /* Since the caller sleeps in pa_sink_input_put(), we can
2449 * safely access data outside of thread_info even though
2450 * it is mutable */
2451
2452 if ((i->thread_info.sync_prev = i->sync_prev)) {
2453 pa_assert(i->sink == i->thread_info.sync_prev->sink);
2454 pa_assert(i->sync_prev->sync_next == i);
2455 i->thread_info.sync_prev->thread_info.sync_next = i;
2456 }
2457
2458 if ((i->thread_info.sync_next = i->sync_next)) {
2459 pa_assert(i->sink == i->thread_info.sync_next->sink);
2460 pa_assert(i->sync_next->sync_prev == i);
2461 i->thread_info.sync_next->thread_info.sync_prev = i;
2462 }
2463
2464 pa_assert(!i->thread_info.attached);
2465 i->thread_info.attached = true;
2466
2467 if (i->attach)
2468 i->attach(i);
2469
2470 pa_sink_input_set_state_within_thread(i, i->state);
2471
2472 /* The requested latency of the sink input needs to be fixed up and
2473 * then configured on the sink. If this causes the sink latency to
2474 * go down, the sink implementor is responsible for doing a rewind
2475 * in the update_requested_latency() callback to ensure that the
2476 * sink buffer doesn't contain more data than what the new latency
2477 * allows.
2478 *
2479 * XXX: Does it really make sense to push this responsibility to
2480 * the sink implementors? Wouldn't it be better to do it once in
2481 * the core than many times in the modules? */
2482
2483 if (i->thread_info.requested_sink_latency != (pa_usec_t) -1)
2484 pa_sink_input_set_requested_latency_within_thread(i, i->thread_info.requested_sink_latency);
2485
2486 pa_sink_input_update_max_rewind(i, s->thread_info.max_rewind);
2487 pa_sink_input_update_max_request(i, s->thread_info.max_request);
2488
2489 /* We don't rewind here automatically. This is left to the
2490 * sink input implementor because some sink inputs need a
2491 * slow start, i.e. need some time to buffer client
2492 * samples before beginning streaming.
2493 *
2494 * XXX: Does it really make sense to push this functionality to
2495 * the sink implementors? Wouldn't it be better to do it once in
2496 * the core than many times in the modules? */
2497
2498 /* In flat volume mode we need to update the volume as
2499 * well */
2500 return o->process_msg(o, PA_SINK_MESSAGE_SET_SHARED_VOLUME, NULL, 0, NULL);
2501 }
2502
2503 case PA_SINK_MESSAGE_REMOVE_INPUT: {
2504 pa_sink_input *i = PA_SINK_INPUT(userdata);
2505
2506 /* If you change anything here, make sure to change the
2507 * sink input handling a few lines down at
2508 * PA_SINK_MESSAGE_START_MOVE, too. */
2509
2510 if (i->detach)
2511 i->detach(i);
2512
2513 pa_sink_input_set_state_within_thread(i, i->state);
2514
2515 pa_assert(i->thread_info.attached);
2516 i->thread_info.attached = false;
2517
2518 /* Since the caller sleeps in pa_sink_input_unlink(),
2519 * we can safely access data outside of thread_info even
2520 * though it is mutable */
2521
2522 pa_assert(!i->sync_prev);
2523 pa_assert(!i->sync_next);
2524
2525 if (i->thread_info.sync_prev) {
2526 i->thread_info.sync_prev->thread_info.sync_next = i->thread_info.sync_prev->sync_next;
2527 i->thread_info.sync_prev = NULL;
2528 }
2529
2530 if (i->thread_info.sync_next) {
2531 i->thread_info.sync_next->thread_info.sync_prev = i->thread_info.sync_next->sync_prev;
2532 i->thread_info.sync_next = NULL;
2533 }
2534
2535 pa_hashmap_remove_and_free(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index));
2536 pa_sink_invalidate_requested_latency(s, true);
2537 pa_sink_request_rewind(s, (size_t) -1);
2538
2539 /* In flat volume mode we need to update the volume as
2540 * well */
2541 return o->process_msg(o, PA_SINK_MESSAGE_SET_SHARED_VOLUME, NULL, 0, NULL);
2542 }
2543
2544 case PA_SINK_MESSAGE_START_MOVE: {
2545 pa_sink_input *i = PA_SINK_INPUT(userdata);
2546
2547 /* We don't support moving synchronized streams. */
2548 pa_assert(!i->sync_prev);
2549 pa_assert(!i->sync_next);
2550 pa_assert(!i->thread_info.sync_next);
2551 pa_assert(!i->thread_info.sync_prev);
2552
2553 if (i->thread_info.state != PA_SINK_INPUT_CORKED) {
2554 pa_usec_t usec = 0;
2555 size_t sink_nbytes, total_nbytes;
2556
2557 /* The old sink probably has some audio from this
2558 * stream in its buffer. We want to "take it back" as
2559 * much as possible and play it to the new sink. We
2560 * don't know at this point how much the old sink can
2561 * rewind. We have to pick something, and that
2562 * something is the full latency of the old sink here.
2563 * So we rewind the stream buffer by the sink latency
2564 * amount, which may be more than what we should
2565 * rewind. This can result in a chunk of audio being
2566 * played both to the old sink and the new sink.
2567 *
2568 * FIXME: Fix this code so that we don't have to make
2569 * guesses about how much the sink will actually be
2570 * able to rewind. If someone comes up with a solution
2571 * for this, something to note is that the part of the
2572 * latency that the old sink couldn't rewind should
2573 * ideally be compensated after the stream has moved
2574 * to the new sink by adding silence. The new sink
2575 * most likely can't start playing the moved stream
2576 * immediately, and that gap should be removed from
2577 * the "compensation silence" (at least at the time of
2578 * writing this, the move finish code will actually
2579 * already take care of dropping the new sink's
2580 * unrewindable latency, so taking into account the
2581 * unrewindable latency of the old sink is the only
2582 * problem).
2583 *
2584 * The render_memblockq contents are discarded,
2585 * because when the sink changes, the format of the
2586 * audio stored in the render_memblockq may change
2587 * too, making the stored audio invalid. FIXME:
2588 * However, the read and write indices are moved back
2589 * the same amount, so if they are not the same now,
2590 * they won't be the same after the rewind either. If
2591 * the write index of the render_memblockq is ahead of
2592 * the read index, then the render_memblockq will feed
2593 * the new sink some silence first, which it shouldn't
2594 * do. The write index should be flushed to be the
2595 * same as the read index. */
2596
2597 /* Get the latency of the sink */
2598 usec = pa_sink_get_latency_within_thread(s);
2599 sink_nbytes = pa_usec_to_bytes(usec, &s->sample_spec);
2600 total_nbytes = sink_nbytes + pa_memblockq_get_length(i->thread_info.render_memblockq);
2601
2602 if (total_nbytes > 0) {
2603 i->thread_info.rewrite_nbytes = i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, total_nbytes) : total_nbytes;
2604 i->thread_info.rewrite_flush = true;
2605 pa_sink_input_process_rewind(i, sink_nbytes);
2606 }
2607 }
2608
2609 if (i->detach)
2610 i->detach(i);
2611
2612 pa_assert(i->thread_info.attached);
2613 i->thread_info.attached = false;
2614
2615 /* Let's remove the sink input ...*/
2616 pa_hashmap_remove_and_free(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index));
2617
2618 pa_sink_invalidate_requested_latency(s, true);
2619
2620 pa_log_debug("Requesting rewind due to started move");
2621 pa_sink_request_rewind(s, (size_t) -1);
2622
2623 /* In flat volume mode we need to update the volume as
2624 * well */
2625 return o->process_msg(o, PA_SINK_MESSAGE_SET_SHARED_VOLUME, NULL, 0, NULL);
2626 }
2627
2628 case PA_SINK_MESSAGE_FINISH_MOVE: {
2629 pa_sink_input *i = PA_SINK_INPUT(userdata);
2630
2631 /* We don't support moving synchronized streams. */
2632 pa_assert(!i->sync_prev);
2633 pa_assert(!i->sync_next);
2634 pa_assert(!i->thread_info.sync_next);
2635 pa_assert(!i->thread_info.sync_prev);
2636
2637 pa_hashmap_put(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index), pa_sink_input_ref(i));
2638
2639 pa_assert(!i->thread_info.attached);
2640 i->thread_info.attached = true;
2641
2642 if (i->attach)
2643 i->attach(i);
2644
2645 if (i->thread_info.state != PA_SINK_INPUT_CORKED) {
2646 pa_usec_t usec = 0;
2647 size_t nbytes;
2648
2649 /* In the ideal case the new sink would start playing
2650 * the stream immediately. That requires the sink to
2651 * be able to rewind all of its latency, which usually
2652 * isn't possible, so there will probably be some gap
2653 * before the moved stream becomes audible. We then
2654 * have two possibilities: 1) start playing the stream
2655 * from where it is now, or 2) drop the unrewindable
2656 * latency of the sink from the stream. With option 1
2657 * we won't lose any audio but the stream will have a
2658 * pause. With option 2 we may lose some audio but the
2659 * stream time will be somewhat in sync with the wall
2660 * clock. Lennart seems to have chosen option 2 (one
2661 * of the reasons might have been that option 1 is
2662 * actually much harder to implement), so we drop the
2663 * latency of the new sink from the moved stream and
2664 * hope that the sink will undo most of that in the
2665 * rewind. */
2666
2667 /* Get the latency of the sink */
2668 usec = pa_sink_get_latency_within_thread(s);
2669 nbytes = pa_usec_to_bytes(usec, &s->sample_spec);
2670
2671 if (nbytes > 0)
2672 pa_sink_input_drop(i, nbytes);
2673
2674 pa_log_debug("Requesting rewind due to finished move");
2675 pa_sink_request_rewind(s, nbytes);
2676 }
2677
2678 /* Updating the requested sink latency has to be done
2679 * after the sink rewind request, not before, because
2680 * otherwise the sink may limit the rewind amount
2681 * needlessly. */
2682
2683 if (i->thread_info.requested_sink_latency != (pa_usec_t) -1)
2684 pa_sink_input_set_requested_latency_within_thread(i, i->thread_info.requested_sink_latency);
2685
2686 pa_sink_input_update_max_rewind(i, s->thread_info.max_rewind);
2687 pa_sink_input_update_max_request(i, s->thread_info.max_request);
2688
2689 return o->process_msg(o, PA_SINK_MESSAGE_SET_SHARED_VOLUME, NULL, 0, NULL);
2690 }
2691
2692 case PA_SINK_MESSAGE_SET_SHARED_VOLUME: {
2693 pa_sink *root_sink = pa_sink_get_master(s);
2694
2695 if (PA_LIKELY(root_sink))
2696 set_shared_volume_within_thread(root_sink);
2697
2698 return 0;
2699 }
2700
2701 case PA_SINK_MESSAGE_SET_VOLUME_SYNCED:
2702
2703 if (s->flags & PA_SINK_DEFERRED_VOLUME) {
2704 s->set_volume(s);
2705 pa_sink_volume_change_push(s);
2706 }
2707 /* Fall through ... */
2708
2709 case PA_SINK_MESSAGE_SET_VOLUME:
2710
2711 if (!pa_cvolume_equal(&s->thread_info.soft_volume, &s->soft_volume)) {
2712 s->thread_info.soft_volume = s->soft_volume;
2713 pa_sink_request_rewind(s, (size_t) -1);
2714 }
2715
2716 /* Fall through ... */
2717
2718 case PA_SINK_MESSAGE_SYNC_VOLUMES:
2719 sync_input_volumes_within_thread(s);
2720 return 0;
2721
2722 case PA_SINK_MESSAGE_GET_VOLUME:
2723
2724 if ((s->flags & PA_SINK_DEFERRED_VOLUME) && s->get_volume) {
2725 s->get_volume(s);
2726 pa_sink_volume_change_flush(s);
2727 pa_sw_cvolume_divide(&s->thread_info.current_hw_volume, &s->real_volume, &s->soft_volume);
2728 }
2729
2730 /* In case sink implementor reset SW volume. */
2731 if (!pa_cvolume_equal(&s->thread_info.soft_volume, &s->soft_volume)) {
2732 s->thread_info.soft_volume = s->soft_volume;
2733 pa_sink_request_rewind(s, (size_t) -1);
2734 }
2735
2736 return 0;
2737
2738 case PA_SINK_MESSAGE_SET_MUTE:
2739
2740 if (s->thread_info.soft_muted != s->muted) {
2741 s->thread_info.soft_muted = s->muted;
2742 pa_sink_request_rewind(s, (size_t) -1);
2743 }
2744
2745 if (s->flags & PA_SINK_DEFERRED_VOLUME && s->set_mute)
2746 s->set_mute(s);
2747
2748 return 0;
2749
2750 case PA_SINK_MESSAGE_GET_MUTE:
2751
2752 if (s->flags & PA_SINK_DEFERRED_VOLUME && s->get_mute)
2753 s->get_mute(s);
2754
2755 return 0;
2756
2757 case PA_SINK_MESSAGE_SET_STATE: {
2758
2759 bool suspend_change =
2760 (s->thread_info.state == PA_SINK_SUSPENDED && PA_SINK_IS_OPENED(PA_PTR_TO_UINT(userdata))) ||
2761 (PA_SINK_IS_OPENED(s->thread_info.state) && PA_PTR_TO_UINT(userdata) == PA_SINK_SUSPENDED);
2762
2763 s->thread_info.state = PA_PTR_TO_UINT(userdata);
2764
2765 if (s->thread_info.state == PA_SINK_SUSPENDED) {
2766 s->thread_info.rewind_nbytes = 0;
2767 s->thread_info.rewind_requested = false;
2768 }
2769
2770 if (suspend_change) {
2771 pa_sink_input *i;
2772 void *state = NULL;
2773
2774 while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)))
2775 if (i->suspend_within_thread)
2776 i->suspend_within_thread(i, s->thread_info.state == PA_SINK_SUSPENDED);
2777 }
2778
2779 return 0;
2780 }
2781
2782 case PA_SINK_MESSAGE_GET_REQUESTED_LATENCY: {
2783
2784 pa_usec_t *usec = userdata;
2785 *usec = pa_sink_get_requested_latency_within_thread(s);
2786
2787 /* Yes, that's right, the IO thread will see -1 when no
2788 * explicit requested latency is configured, the main
2789 * thread will see max_latency */
2790 if (*usec == (pa_usec_t) -1)
2791 *usec = s->thread_info.max_latency;
2792
2793 return 0;
2794 }
2795
2796 case PA_SINK_MESSAGE_SET_LATENCY_RANGE: {
2797 pa_usec_t *r = userdata;
2798
2799 pa_sink_set_latency_range_within_thread(s, r[0], r[1]);
2800
2801 return 0;
2802 }
2803
2804 case PA_SINK_MESSAGE_GET_LATENCY_RANGE: {
2805 pa_usec_t *r = userdata;
2806
2807 r[0] = s->thread_info.min_latency;
2808 r[1] = s->thread_info.max_latency;
2809
2810 return 0;
2811 }
2812
2813 case PA_SINK_MESSAGE_GET_FIXED_LATENCY:
2814
2815 *((pa_usec_t*) userdata) = s->thread_info.fixed_latency;
2816 return 0;
2817
2818 case PA_SINK_MESSAGE_SET_FIXED_LATENCY:
2819
2820 pa_sink_set_fixed_latency_within_thread(s, (pa_usec_t) offset);
2821 return 0;
2822
2823 case PA_SINK_MESSAGE_GET_MAX_REWIND:
2824
2825 *((size_t*) userdata) = s->thread_info.max_rewind;
2826 return 0;
2827
2828 case PA_SINK_MESSAGE_GET_MAX_REQUEST:
2829
2830 *((size_t*) userdata) = s->thread_info.max_request;
2831 return 0;
2832
2833 case PA_SINK_MESSAGE_SET_MAX_REWIND:
2834
2835 pa_sink_set_max_rewind_within_thread(s, (size_t) offset);
2836 return 0;
2837
2838 case PA_SINK_MESSAGE_SET_MAX_REQUEST:
2839
2840 pa_sink_set_max_request_within_thread(s, (size_t) offset);
2841 return 0;
2842
2843 case PA_SINK_MESSAGE_SET_PORT:
2844
2845 pa_assert(userdata);
2846 if (s->set_port) {
2847 struct sink_message_set_port *msg_data = userdata;
2848 msg_data->ret = s->set_port(s, msg_data->port);
2849 }
2850 return 0;
2851
2852 case PA_SINK_MESSAGE_UPDATE_VOLUME_AND_MUTE:
2853 /* This message is sent from IO-thread and handled in main thread. */
2854 pa_assert_ctl_context();
2855
2856 /* Make sure we're not messing with main thread when no longer linked */
2857 if (!PA_SINK_IS_LINKED(s->state))
2858 return 0;
2859
2860 pa_sink_get_volume(s, true);
2861 pa_sink_get_mute(s, true);
2862 return 0;
2863
2864 case PA_SINK_MESSAGE_SET_LATENCY_OFFSET:
2865 s->thread_info.latency_offset = offset;
2866 return 0;
2867
2868 case PA_SINK_MESSAGE_GET_LATENCY:
2869 case PA_SINK_MESSAGE_MAX:
2870 ;
2871 }
2872
2873 return -1;
2874 }
2875
2876 /* Called from main thread */
2877 int pa_sink_suspend_all(pa_core *c, bool suspend, pa_suspend_cause_t cause) {
2878 pa_sink *sink;
2879 uint32_t idx;
2880 int ret = 0;
2881
2882 pa_core_assert_ref(c);
2883 pa_assert_ctl_context();
2884 pa_assert(cause != 0);
2885
2886 PA_IDXSET_FOREACH(sink, c->sinks, idx) {
2887 int r;
2888
2889 if ((r = pa_sink_suspend(sink, suspend, cause)) < 0)
2890 ret = r;
2891 }
2892
2893 return ret;
2894 }
2895
2896 /* Called from IO thread */
2897 void pa_sink_detach_within_thread(pa_sink *s) {
2898 pa_sink_input *i;
2899 void *state = NULL;
2900
2901 pa_sink_assert_ref(s);
2902 pa_sink_assert_io_context(s);
2903 pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
2904
2905 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state)
2906 if (i->detach)
2907 i->detach(i);
2908
2909 if (s->monitor_source)
2910 pa_source_detach_within_thread(s->monitor_source);
2911 }
2912
2913 /* Called from IO thread */
2914 void pa_sink_attach_within_thread(pa_sink *s) {
2915 pa_sink_input *i;
2916 void *state = NULL;
2917
2918 pa_sink_assert_ref(s);
2919 pa_sink_assert_io_context(s);
2920 pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
2921
2922 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state)
2923 if (i->attach)
2924 i->attach(i);
2925
2926 if (s->monitor_source)
2927 pa_source_attach_within_thread(s->monitor_source);
2928 }
2929
2930 /* Called from IO thread */
2931 void pa_sink_request_rewind(pa_sink*s, size_t nbytes) {
2932 pa_sink_assert_ref(s);
2933 pa_sink_assert_io_context(s);
2934 pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
2935
2936 if (nbytes == (size_t) -1)
2937 nbytes = s->thread_info.max_rewind;
2938
2939 nbytes = PA_MIN(nbytes, s->thread_info.max_rewind);
2940
2941 if (s->thread_info.rewind_requested &&
2942 nbytes <= s->thread_info.rewind_nbytes)
2943 return;
2944
2945 s->thread_info.rewind_nbytes = nbytes;
2946 s->thread_info.rewind_requested = true;
2947
2948 if (s->request_rewind)
2949 s->request_rewind(s);
2950 }
2951
2952 /* Called from IO thread */
2953 pa_usec_t pa_sink_get_requested_latency_within_thread(pa_sink *s) {
2954 pa_usec_t result = (pa_usec_t) -1;
2955 pa_sink_input *i;
2956 void *state = NULL;
2957 pa_usec_t monitor_latency;
2958
2959 pa_sink_assert_ref(s);
2960 pa_sink_assert_io_context(s);
2961
2962 if (!(s->flags & PA_SINK_DYNAMIC_LATENCY))
2963 return PA_CLAMP(s->thread_info.fixed_latency, s->thread_info.min_latency, s->thread_info.max_latency);
2964
2965 if (s->thread_info.requested_latency_valid)
2966 return s->thread_info.requested_latency;
2967
2968 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state)
2969 if (i->thread_info.requested_sink_latency != (pa_usec_t) -1 &&
2970 (result == (pa_usec_t) -1 || result > i->thread_info.requested_sink_latency))
2971 result = i->thread_info.requested_sink_latency;
2972
2973 monitor_latency = pa_source_get_requested_latency_within_thread(s->monitor_source);
2974
2975 if (monitor_latency != (pa_usec_t) -1 &&
2976 (result == (pa_usec_t) -1 || result > monitor_latency))
2977 result = monitor_latency;
2978
2979 if (result != (pa_usec_t) -1)
2980 result = PA_CLAMP(result, s->thread_info.min_latency, s->thread_info.max_latency);
2981
2982 if (PA_SINK_IS_LINKED(s->thread_info.state)) {
2983 /* Only cache if properly initialized */
2984 s->thread_info.requested_latency = result;
2985 s->thread_info.requested_latency_valid = true;
2986 }
2987
2988 return result;
2989 }
2990
2991 /* Called from main thread */
2992 pa_usec_t pa_sink_get_requested_latency(pa_sink *s) {
2993 pa_usec_t usec = 0;
2994
2995 pa_sink_assert_ref(s);
2996 pa_assert_ctl_context();
2997 pa_assert(PA_SINK_IS_LINKED(s->state));
2998
2999 if (s->state == PA_SINK_SUSPENDED)
3000 return 0;
3001
3002 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);
3003
3004 return usec;
3005 }
3006
3007 /* Called from IO as well as the main thread -- the latter only before the IO thread started up */
3008 void pa_sink_set_max_rewind_within_thread(pa_sink *s, size_t max_rewind) {
3009 pa_sink_input *i;
3010 void *state = NULL;
3011
3012 pa_sink_assert_ref(s);
3013 pa_sink_assert_io_context(s);
3014
3015 if (max_rewind == s->thread_info.max_rewind)
3016 return;
3017
3018 s->thread_info.max_rewind = max_rewind;
3019
3020 if (PA_SINK_IS_LINKED(s->thread_info.state))
3021 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state)
3022 pa_sink_input_update_max_rewind(i, s->thread_info.max_rewind);
3023
3024 if (s->monitor_source)
3025 pa_source_set_max_rewind_within_thread(s->monitor_source, s->thread_info.max_rewind);
3026 }
3027
3028 /* Called from main thread */
3029 void pa_sink_set_max_rewind(pa_sink *s, size_t max_rewind) {
3030 pa_sink_assert_ref(s);
3031 pa_assert_ctl_context();
3032
3033 if (PA_SINK_IS_LINKED(s->state))
3034 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_MAX_REWIND, NULL, max_rewind, NULL) == 0);
3035 else
3036 pa_sink_set_max_rewind_within_thread(s, max_rewind);
3037 }
3038
3039 /* Called from IO as well as the main thread -- the latter only before the IO thread started up */
3040 void pa_sink_set_max_request_within_thread(pa_sink *s, size_t max_request) {
3041 void *state = NULL;
3042
3043 pa_sink_assert_ref(s);
3044 pa_sink_assert_io_context(s);
3045
3046 if (max_request == s->thread_info.max_request)
3047 return;
3048
3049 s->thread_info.max_request = max_request;
3050
3051 if (PA_SINK_IS_LINKED(s->thread_info.state)) {
3052 pa_sink_input *i;
3053
3054 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state)
3055 pa_sink_input_update_max_request(i, s->thread_info.max_request);
3056 }
3057 }
3058
3059 /* Called from main thread */
3060 void pa_sink_set_max_request(pa_sink *s, size_t max_request) {
3061 pa_sink_assert_ref(s);
3062 pa_assert_ctl_context();
3063
3064 if (PA_SINK_IS_LINKED(s->state))
3065 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_MAX_REQUEST, NULL, max_request, NULL) == 0);
3066 else
3067 pa_sink_set_max_request_within_thread(s, max_request);
3068 }
3069
3070 /* Called from IO thread */
3071 void pa_sink_invalidate_requested_latency(pa_sink *s, bool dynamic) {
3072 pa_sink_input *i;
3073 void *state = NULL;
3074
3075 pa_sink_assert_ref(s);
3076 pa_sink_assert_io_context(s);
3077
3078 if ((s->flags & PA_SINK_DYNAMIC_LATENCY))
3079 s->thread_info.requested_latency_valid = false;
3080 else if (dynamic)
3081 return;
3082
3083 if (PA_SINK_IS_LINKED(s->thread_info.state)) {
3084
3085 if (s->update_requested_latency)
3086 s->update_requested_latency(s);
3087
3088 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state)
3089 if (i->update_sink_requested_latency)
3090 i->update_sink_requested_latency(i);
3091 }
3092 }
3093
3094 /* Called from main thread */
3095 void pa_sink_set_latency_range(pa_sink *s, pa_usec_t min_latency, pa_usec_t max_latency) {
3096 pa_sink_assert_ref(s);
3097 pa_assert_ctl_context();
3098
3099 /* min_latency == 0: no limit
3100 * min_latency anything else: specified limit
3101 *
3102 * Similar for max_latency */
3103
3104 if (min_latency < ABSOLUTE_MIN_LATENCY)
3105 min_latency = ABSOLUTE_MIN_LATENCY;
3106
3107 if (max_latency <= 0 ||
3108 max_latency > ABSOLUTE_MAX_LATENCY)
3109 max_latency = ABSOLUTE_MAX_LATENCY;
3110
3111 pa_assert(min_latency <= max_latency);
3112
3113 /* Hmm, let's see if someone forgot to set PA_SINK_DYNAMIC_LATENCY here... */
3114 pa_assert((min_latency == ABSOLUTE_MIN_LATENCY &&
3115 max_latency == ABSOLUTE_MAX_LATENCY) ||
3116 (s->flags & PA_SINK_DYNAMIC_LATENCY));
3117
3118 if (PA_SINK_IS_LINKED(s->state)) {
3119 pa_usec_t r[2];
3120
3121 r[0] = min_latency;
3122 r[1] = max_latency;
3123
3124 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_LATENCY_RANGE, r, 0, NULL) == 0);
3125 } else
3126 pa_sink_set_latency_range_within_thread(s, min_latency, max_latency);
3127 }
3128
3129 /* Called from main thread */
3130 void pa_sink_get_latency_range(pa_sink *s, pa_usec_t *min_latency, pa_usec_t *max_latency) {
3131 pa_sink_assert_ref(s);
3132 pa_assert_ctl_context();
3133 pa_assert(min_latency);
3134 pa_assert(max_latency);
3135
3136 if (PA_SINK_IS_LINKED(s->state)) {
3137 pa_usec_t r[2] = { 0, 0 };
3138
3139 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_LATENCY_RANGE, r, 0, NULL) == 0);
3140
3141 *min_latency = r[0];
3142 *max_latency = r[1];
3143 } else {
3144 *min_latency = s->thread_info.min_latency;
3145 *max_latency = s->thread_info.max_latency;
3146 }
3147 }
3148
3149 /* Called from IO thread */
3150 void pa_sink_set_latency_range_within_thread(pa_sink *s, pa_usec_t min_latency, pa_usec_t max_latency) {
3151 pa_sink_assert_ref(s);
3152 pa_sink_assert_io_context(s);
3153
3154 pa_assert(min_latency >= ABSOLUTE_MIN_LATENCY);
3155 pa_assert(max_latency <= ABSOLUTE_MAX_LATENCY);
3156 pa_assert(min_latency <= max_latency);
3157
3158 /* Hmm, let's see if someone forgot to set PA_SINK_DYNAMIC_LATENCY here... */
3159 pa_assert((min_latency == ABSOLUTE_MIN_LATENCY &&
3160 max_latency == ABSOLUTE_MAX_LATENCY) ||
3161 (s->flags & PA_SINK_DYNAMIC_LATENCY));
3162
3163 if (s->thread_info.min_latency == min_latency &&
3164 s->thread_info.max_latency == max_latency)
3165 return;
3166
3167 s->thread_info.min_latency = min_latency;
3168 s->thread_info.max_latency = max_latency;
3169
3170 if (PA_SINK_IS_LINKED(s->thread_info.state)) {
3171 pa_sink_input *i;
3172 void *state = NULL;
3173
3174 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state)
3175 if (i->update_sink_latency_range)
3176 i->update_sink_latency_range(i);
3177 }
3178
3179 pa_sink_invalidate_requested_latency(s, false);
3180
3181 pa_source_set_latency_range_within_thread(s->monitor_source, min_latency, max_latency);
3182 }
3183
3184 /* Called from main thread */
3185 void pa_sink_set_fixed_latency(pa_sink *s, pa_usec_t latency) {
3186 pa_sink_assert_ref(s);
3187 pa_assert_ctl_context();
3188
3189 if (s->flags & PA_SINK_DYNAMIC_LATENCY) {
3190 pa_assert(latency == 0);
3191 return;
3192 }
3193
3194 if (latency < ABSOLUTE_MIN_LATENCY)
3195 latency = ABSOLUTE_MIN_LATENCY;
3196
3197 if (latency > ABSOLUTE_MAX_LATENCY)
3198 latency = ABSOLUTE_MAX_LATENCY;
3199
3200 if (PA_SINK_IS_LINKED(s->state))
3201 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_FIXED_LATENCY, NULL, (int64_t) latency, NULL) == 0);
3202 else
3203 s->thread_info.fixed_latency = latency;
3204
3205 pa_source_set_fixed_latency(s->monitor_source, latency);
3206 }
3207
3208 /* Called from main thread */
3209 pa_usec_t pa_sink_get_fixed_latency(pa_sink *s) {
3210 pa_usec_t latency;
3211
3212 pa_sink_assert_ref(s);
3213 pa_assert_ctl_context();
3214
3215 if (s->flags & PA_SINK_DYNAMIC_LATENCY)
3216 return 0;
3217
3218 if (PA_SINK_IS_LINKED(s->state))
3219 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_FIXED_LATENCY, &latency, 0, NULL) == 0);
3220 else
3221 latency = s->thread_info.fixed_latency;
3222
3223 return latency;
3224 }
3225
3226 /* Called from IO thread */
3227 void pa_sink_set_fixed_latency_within_thread(pa_sink *s, pa_usec_t latency) {
3228 pa_sink_assert_ref(s);
3229 pa_sink_assert_io_context(s);
3230
3231 if (s->flags & PA_SINK_DYNAMIC_LATENCY) {
3232 pa_assert(latency == 0);
3233 s->thread_info.fixed_latency = 0;
3234
3235 if (s->monitor_source)
3236 pa_source_set_fixed_latency_within_thread(s->monitor_source, 0);
3237
3238 return;
3239 }
3240
3241 pa_assert(latency >= ABSOLUTE_MIN_LATENCY);
3242 pa_assert(latency <= ABSOLUTE_MAX_LATENCY);
3243
3244 if (s->thread_info.fixed_latency == latency)
3245 return;
3246
3247 s->thread_info.fixed_latency = latency;
3248
3249 if (PA_SINK_IS_LINKED(s->thread_info.state)) {
3250 pa_sink_input *i;
3251 void *state = NULL;
3252
3253 PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state)
3254 if (i->update_sink_fixed_latency)
3255 i->update_sink_fixed_latency(i);
3256 }
3257
3258 pa_sink_invalidate_requested_latency(s, false);
3259
3260 pa_source_set_fixed_latency_within_thread(s->monitor_source, latency);
3261 }
3262
3263 /* Called from main context */
3264 void pa_sink_set_latency_offset(pa_sink *s, int64_t offset) {
3265 pa_sink_assert_ref(s);
3266
3267 s->latency_offset = offset;
3268
3269 if (PA_SINK_IS_LINKED(s->state))
3270 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_LATENCY_OFFSET, NULL, offset, NULL) == 0);
3271 else
3272 s->thread_info.latency_offset = offset;
3273 }
3274
3275 /* Called from main context */
3276 size_t pa_sink_get_max_rewind(pa_sink *s) {
3277 size_t r;
3278 pa_assert_ctl_context();
3279 pa_sink_assert_ref(s);
3280
3281 if (!PA_SINK_IS_LINKED(s->state))
3282 return s->thread_info.max_rewind;
3283
3284 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_MAX_REWIND, &r, 0, NULL) == 0);
3285
3286 return r;
3287 }
3288
3289 /* Called from main context */
3290 size_t pa_sink_get_max_request(pa_sink *s) {
3291 size_t r;
3292 pa_sink_assert_ref(s);
3293 pa_assert_ctl_context();
3294
3295 if (!PA_SINK_IS_LINKED(s->state))
3296 return s->thread_info.max_request;
3297
3298 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_MAX_REQUEST, &r, 0, NULL) == 0);
3299
3300 return r;
3301 }
3302
3303 /* Called from main context */
3304 int pa_sink_set_port(pa_sink *s, const char *name, bool save) {
3305 pa_device_port *port;
3306 int ret;
3307
3308 pa_sink_assert_ref(s);
3309 pa_assert_ctl_context();
3310
3311 if (!s->set_port) {
3312 pa_log_debug("set_port() operation not implemented for sink %u \"%s\"", s->index, s->name);
3313 return -PA_ERR_NOTIMPLEMENTED;
3314 }
3315
3316 if (!name)
3317 return -PA_ERR_NOENTITY;
3318
3319 if (!(port = pa_hashmap_get(s->ports, name)))
3320 return -PA_ERR_NOENTITY;
3321
3322 if (s->active_port == port) {
3323 s->save_port = s->save_port || save;
3324 return 0;
3325 }
3326
3327 if (s->flags & PA_SINK_DEFERRED_VOLUME) {
3328 struct sink_message_set_port msg = { .port = port, .ret = 0 };
3329 pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_PORT, &msg, 0, NULL) == 0);
3330 ret = msg.ret;
3331 }
3332 else
3333 ret = s->set_port(s, port);
3334
3335 if (ret < 0)
3336 return -PA_ERR_NOENTITY;
3337
3338 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
3339
3340 pa_log_info("Changed port of sink %u \"%s\" to %s", s->index, s->name, port->name);
3341
3342 s->active_port = port;
3343 s->save_port = save;
3344
3345 pa_sink_set_latency_offset(s, s->active_port->latency_offset);
3346
3347 pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_PORT_CHANGED], s);
3348
3349 return 0;
3350 }
3351
3352 bool pa_device_init_icon(pa_proplist *p, bool is_sink) {
3353 const char *ff, *c, *t = NULL, *s = "", *profile, *bus;
3354
3355 pa_assert(p);
3356
3357 if (pa_proplist_contains(p, PA_PROP_DEVICE_ICON_NAME))
3358 return true;
3359
3360 if ((ff = pa_proplist_gets(p, PA_PROP_DEVICE_FORM_FACTOR))) {
3361
3362 if (pa_streq(ff, "microphone"))
3363 t = "audio-input-microphone";
3364 else if (pa_streq(ff, "webcam"))
3365 t = "camera-web";
3366 else if (pa_streq(ff, "computer"))
3367 t = "computer";
3368 else if (pa_streq(ff, "handset"))
3369 t = "phone";
3370 else if (pa_streq(ff, "portable"))
3371 t = "multimedia-player";
3372 else if (pa_streq(ff, "tv"))
3373 t = "video-display";
3374
3375 /*
3376 * The following icons are not part of the icon naming spec,
3377 * because Rodney Dawes sucks as the maintainer of that spec.
3378 *
3379 * http://lists.freedesktop.org/archives/xdg/2009-May/010397.html
3380 */
3381 else if (pa_streq(ff, "headset"))
3382 t = "audio-headset";
3383 else if (pa_streq(ff, "headphone"))
3384 t = "audio-headphones";
3385 else if (pa_streq(ff, "speaker"))
3386 t = "audio-speakers";
3387 else if (pa_streq(ff, "hands-free"))
3388 t = "audio-handsfree";
3389 }
3390
3391 if (!t)
3392 if ((c = pa_proplist_gets(p, PA_PROP_DEVICE_CLASS)))
3393 if (pa_streq(c, "modem"))
3394 t = "modem";
3395
3396 if (!t) {
3397 if (is_sink)
3398 t = "audio-card";
3399 else
3400 t = "audio-input-microphone";
3401 }
3402
3403 if ((profile = pa_proplist_gets(p, PA_PROP_DEVICE_PROFILE_NAME))) {
3404 if (strstr(profile, "analog"))
3405 s = "-analog";
3406 else if (strstr(profile, "iec958"))
3407 s = "-iec958";
3408 else if (strstr(profile, "hdmi"))
3409 s = "-hdmi";
3410 }
3411
3412 bus = pa_proplist_gets(p, PA_PROP_DEVICE_BUS);
3413
3414 pa_proplist_setf(p, PA_PROP_DEVICE_ICON_NAME, "%s%s%s%s", t, pa_strempty(s), bus ? "-" : "", pa_strempty(bus));
3415
3416 return true;
3417 }
3418
3419 bool pa_device_init_description(pa_proplist *p, pa_card *card) {
3420 const char *s, *d = NULL, *k;
3421 pa_assert(p);
3422
3423 if (pa_proplist_contains(p, PA_PROP_DEVICE_DESCRIPTION))
3424 return true;
3425
3426 if (card)
3427 if ((s = pa_proplist_gets(card->proplist, PA_PROP_DEVICE_DESCRIPTION)))
3428 d = s;
3429
3430 if (!d)
3431 if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_FORM_FACTOR)))
3432 if (pa_streq(s, "internal"))
3433 d = _("Built-in Audio");
3434
3435 if (!d)
3436 if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_CLASS)))
3437 if (pa_streq(s, "modem"))
3438 d = _("Modem");
3439
3440 if (!d)
3441 d = pa_proplist_gets(p, PA_PROP_DEVICE_PRODUCT_NAME);
3442
3443 if (!d)
3444 return false;
3445
3446 k = pa_proplist_gets(p, PA_PROP_DEVICE_PROFILE_DESCRIPTION);
3447
3448 if (d && k)
3449 pa_proplist_setf(p, PA_PROP_DEVICE_DESCRIPTION, "%s %s", d, k);
3450 else if (d)
3451 pa_proplist_sets(p, PA_PROP_DEVICE_DESCRIPTION, d);
3452
3453 return true;
3454 }
3455
3456 bool pa_device_init_intended_roles(pa_proplist *p) {
3457 const char *s;
3458 pa_assert(p);
3459
3460 if (pa_proplist_contains(p, PA_PROP_DEVICE_INTENDED_ROLES))
3461 return true;
3462
3463 if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_FORM_FACTOR)))
3464 if (pa_streq(s, "handset") || pa_streq(s, "hands-free")
3465 || pa_streq(s, "headset")) {
3466 pa_proplist_sets(p, PA_PROP_DEVICE_INTENDED_ROLES, "phone");
3467 return true;
3468 }
3469
3470 return false;
3471 }
3472
3473 unsigned pa_device_init_priority(pa_proplist *p) {
3474 const char *s;
3475 unsigned priority = 0;
3476
3477 pa_assert(p);
3478
3479 if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_CLASS))) {
3480
3481 if (pa_streq(s, "sound"))
3482 priority += 9000;
3483 else if (!pa_streq(s, "modem"))
3484 priority += 1000;
3485 }
3486
3487 if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_FORM_FACTOR))) {
3488
3489 if (pa_streq(s, "internal"))
3490 priority += 900;
3491 else if (pa_streq(s, "speaker"))
3492 priority += 500;
3493 else if (pa_streq(s, "headphone"))
3494 priority += 400;
3495 }
3496
3497 if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_BUS))) {
3498
3499 if (pa_streq(s, "pci"))
3500 priority += 50;
3501 else if (pa_streq(s, "usb"))
3502 priority += 40;
3503 else if (pa_streq(s, "bluetooth"))
3504 priority += 30;
3505 }
3506
3507 if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_PROFILE_NAME))) {
3508
3509 if (pa_startswith(s, "analog-"))
3510 priority += 9;
3511 else if (pa_startswith(s, "iec958-"))
3512 priority += 8;
3513 }
3514
3515 return priority;
3516 }
3517
3518 PA_STATIC_FLIST_DECLARE(pa_sink_volume_change, 0, pa_xfree);
3519
3520 /* Called from the IO thread. */
3521 static pa_sink_volume_change *pa_sink_volume_change_new(pa_sink *s) {
3522 pa_sink_volume_change *c;
3523 if (!(c = pa_flist_pop(PA_STATIC_FLIST_GET(pa_sink_volume_change))))
3524 c = pa_xnew(pa_sink_volume_change, 1);
3525
3526 PA_LLIST_INIT(pa_sink_volume_change, c);
3527 c->at = 0;
3528 pa_cvolume_reset(&c->hw_volume, s->sample_spec.channels);
3529 return c;
3530 }
3531
3532 /* Called from the IO thread. */
3533 static void pa_sink_volume_change_free(pa_sink_volume_change *c) {
3534 pa_assert(c);
3535 if (pa_flist_push(PA_STATIC_FLIST_GET(pa_sink_volume_change), c) < 0)
3536 pa_xfree(c);
3537 }
3538
3539 /* Called from the IO thread. */
3540 void pa_sink_volume_change_push(pa_sink *s) {
3541 pa_sink_volume_change *c = NULL;
3542 pa_sink_volume_change *nc = NULL;
3543 uint32_t safety_margin = s->thread_info.volume_change_safety_margin;
3544
3545 const char *direction = NULL;
3546
3547 pa_assert(s);
3548 nc = pa_sink_volume_change_new(s);
3549
3550 /* NOTE: There is already more different volumes in pa_sink that I can remember.
3551 * Adding one more volume for HW would get us rid of this, but I am trying
3552 * to survive with the ones we already have. */
3553 pa_sw_cvolume_divide(&nc->hw_volume, &s->real_volume, &s->soft_volume);
3554
3555 if (!s->thread_info.volume_changes && pa_cvolume_equal(&nc->hw_volume, &s->thread_info.current_hw_volume)) {
3556 pa_log_debug("Volume not changing");
3557 pa_sink_volume_change_free(nc);
3558 return;
3559 }
3560
3561 nc->at = pa_sink_get_latency_within_thread(s);
3562 nc->at += pa_rtclock_now() + s->thread_info.volume_change_extra_delay;
3563
3564 if (s->thread_info.volume_changes_tail) {
3565 for (c = s->thread_info.volume_changes_tail; c; c = c->prev) {
3566 /* If volume is going up let's do it a bit late. If it is going
3567 * down let's do it a bit early. */
3568 if (pa_cvolume_avg(&nc->hw_volume) > pa_cvolume_avg(&c->hw_volume)) {
3569 if (nc->at + safety_margin > c->at) {
3570 nc->at += safety_margin;
3571 direction = "up";
3572 break;
3573 }
3574 }
3575 else if (nc->at - safety_margin > c->at) {
3576 nc->at -= safety_margin;
3577 direction = "down";
3578 break;
3579 }
3580 }
3581 }
3582
3583 if (c == NULL) {
3584 if (pa_cvolume_avg(&nc->hw_volume) > pa_cvolume_avg(&s->thread_info.current_hw_volume)) {
3585 nc->at += safety_margin;
3586 direction = "up";
3587 } else {
3588 nc->at -= safety_margin;
3589 direction = "down";
3590 }
3591 PA_LLIST_PREPEND(pa_sink_volume_change, s->thread_info.volume_changes, nc);
3592 }
3593 else {
3594 PA_LLIST_INSERT_AFTER(pa_sink_volume_change, s->thread_info.volume_changes, c, nc);
3595 }
3596
3597 pa_log_debug("Volume going %s to %d at %llu", direction, pa_cvolume_avg(&nc->hw_volume), (long long unsigned) nc->at);
3598
3599 /* We can ignore volume events that came earlier but should happen later than this. */
3600 PA_LLIST_FOREACH(c, nc->next) {
3601 pa_log_debug("Volume change to %d at %llu was dropped", pa_cvolume_avg(&c->hw_volume), (long long unsigned) c->at);
3602 pa_sink_volume_change_free(c);
3603 }
3604 nc->next = NULL;
3605 s->thread_info.volume_changes_tail = nc;
3606 }
3607
3608 /* Called from the IO thread. */
3609 static void pa_sink_volume_change_flush(pa_sink *s) {
3610 pa_sink_volume_change *c = s->thread_info.volume_changes;
3611 pa_assert(s);
3612 s->thread_info.volume_changes = NULL;
3613 s->thread_info.volume_changes_tail = NULL;
3614 while (c) {
3615 pa_sink_volume_change *next = c->next;
3616 pa_sink_volume_change_free(c);
3617 c = next;
3618 }
3619 }
3620
3621 /* Called from the IO thread. */
3622 bool pa_sink_volume_change_apply(pa_sink *s, pa_usec_t *usec_to_next) {
3623 pa_usec_t now;
3624 bool ret = false;
3625
3626 pa_assert(s);
3627
3628 if (!s->thread_info.volume_changes || !PA_SINK_IS_LINKED(s->state)) {
3629 if (usec_to_next)
3630 *usec_to_next = 0;
3631 return ret;
3632 }
3633
3634 pa_assert(s->write_volume);
3635
3636 now = pa_rtclock_now();
3637
3638 while (s->thread_info.volume_changes && now >= s->thread_info.volume_changes->at) {
3639 pa_sink_volume_change *c = s->thread_info.volume_changes;
3640 PA_LLIST_REMOVE(pa_sink_volume_change, s->thread_info.volume_changes, c);
3641 pa_log_debug("Volume change to %d at %llu was written %llu usec late",
3642 pa_cvolume_avg(&c->hw_volume), (long long unsigned) c->at, (long long unsigned) (now - c->at));
3643 ret = true;
3644 s->thread_info.current_hw_volume = c->hw_volume;
3645 pa_sink_volume_change_free(c);
3646 }
3647
3648 if (ret)
3649 s->write_volume(s);
3650
3651 if (s->thread_info.volume_changes) {
3652 if (usec_to_next)
3653 *usec_to_next = s->thread_info.volume_changes->at - now;
3654 if (pa_log_ratelimit(PA_LOG_DEBUG))
3655 pa_log_debug("Next volume change in %lld usec", (long long) (s->thread_info.volume_changes->at - now));
3656 }
3657 else {
3658 if (usec_to_next)
3659 *usec_to_next = 0;
3660 s->thread_info.volume_changes_tail = NULL;
3661 }
3662 return ret;
3663 }
3664
3665 /* Called from the IO thread. */
3666 static void pa_sink_volume_change_rewind(pa_sink *s, size_t nbytes) {
3667 /* All the queued volume events later than current latency are shifted to happen earlier. */
3668 pa_sink_volume_change *c;
3669 pa_volume_t prev_vol = pa_cvolume_avg(&s->thread_info.current_hw_volume);
3670 pa_usec_t rewound = pa_bytes_to_usec(nbytes, &s->sample_spec);
3671 pa_usec_t limit = pa_sink_get_latency_within_thread(s);
3672
3673 pa_log_debug("latency = %lld", (long long) limit);
3674 limit += pa_rtclock_now() + s->thread_info.volume_change_extra_delay;
3675
3676 PA_LLIST_FOREACH(c, s->thread_info.volume_changes) {
3677 pa_usec_t modified_limit = limit;
3678 if (prev_vol > pa_cvolume_avg(&c->hw_volume))
3679 modified_limit -= s->thread_info.volume_change_safety_margin;
3680 else
3681 modified_limit += s->thread_info.volume_change_safety_margin;
3682 if (c->at > modified_limit) {
3683 c->at -= rewound;
3684 if (c->at < modified_limit)
3685 c->at = modified_limit;
3686 }
3687 prev_vol = pa_cvolume_avg(&c->hw_volume);
3688 }
3689 pa_sink_volume_change_apply(s, NULL);
3690 }
3691
3692 /* Called from the main thread */
3693 /* Gets the list of formats supported by the sink. The members and idxset must
3694 * be freed by the caller. */
3695 pa_idxset* pa_sink_get_formats(pa_sink *s) {
3696 pa_idxset *ret;
3697
3698 pa_assert(s);
3699
3700 if (s->get_formats) {
3701 /* Sink supports format query, all is good */
3702 ret = s->get_formats(s);
3703 } else {
3704 /* Sink doesn't support format query, so assume it does PCM */
3705 pa_format_info *f = pa_format_info_new();
3706 f->encoding = PA_ENCODING_PCM;
3707
3708 ret = pa_idxset_new(NULL, NULL);
3709 pa_idxset_put(ret, f, NULL);
3710 }
3711
3712 return ret;
3713 }
3714
3715 /* Called from the main thread */
3716 /* Allows an external source to set what formats a sink supports if the sink
3717 * permits this. The function makes a copy of the formats on success. */
3718 bool pa_sink_set_formats(pa_sink *s, pa_idxset *formats) {
3719 pa_assert(s);
3720 pa_assert(formats);
3721
3722 if (s->set_formats)
3723 /* Sink supports setting formats -- let's give it a shot */
3724 return s->set_formats(s, formats);
3725 else
3726 /* Sink doesn't support setting this -- bail out */
3727 return false;
3728 }
3729
3730 /* Called from the main thread */
3731 /* Checks if the sink can accept this format */
3732 bool pa_sink_check_format(pa_sink *s, pa_format_info *f) {
3733 pa_idxset *formats = NULL;
3734 bool ret = false;
3735
3736 pa_assert(s);
3737 pa_assert(f);
3738
3739 formats = pa_sink_get_formats(s);
3740
3741 if (formats) {
3742 pa_format_info *finfo_device;
3743 uint32_t i;
3744
3745 PA_IDXSET_FOREACH(finfo_device, formats, i) {
3746 if (pa_format_info_is_compatible(finfo_device, f)) {
3747 ret = true;
3748 break;
3749 }
3750 }
3751
3752 pa_idxset_free(formats, (pa_free_cb_t) pa_format_info_free);
3753 }
3754
3755 return ret;
3756 }
3757
3758 /* Called from the main thread */
3759 /* Calculates the intersection between formats supported by the sink and
3760 * in_formats, and returns these, in the order of the sink's formats. */
3761 pa_idxset* pa_sink_check_formats(pa_sink *s, pa_idxset *in_formats) {
3762 pa_idxset *out_formats = pa_idxset_new(NULL, NULL), *sink_formats = NULL;
3763 pa_format_info *f_sink, *f_in;
3764 uint32_t i, j;
3765
3766 pa_assert(s);
3767
3768 if (!in_formats || pa_idxset_isempty(in_formats))
3769 goto done;
3770
3771 sink_formats = pa_sink_get_formats(s);
3772
3773 PA_IDXSET_FOREACH(f_sink, sink_formats, i) {
3774 PA_IDXSET_FOREACH(f_in, in_formats, j) {
3775 if (pa_format_info_is_compatible(f_sink, f_in))
3776 pa_idxset_put(out_formats, pa_format_info_copy(f_in), NULL);
3777 }
3778 }
3779
3780 done:
3781 if (sink_formats)
3782 pa_idxset_free(sink_formats, (pa_free_cb_t) pa_format_info_free);
3783
3784 return out_formats;
3785 }
3786
3787 /* Called from the main thread. */
3788 void pa_sink_set_reference_volume_direct(pa_sink *s, const pa_cvolume *volume) {
3789 pa_cvolume old_volume;
3790 char old_volume_str[PA_CVOLUME_SNPRINT_VERBOSE_MAX];
3791 char new_volume_str[PA_CVOLUME_SNPRINT_VERBOSE_MAX];
3792
3793 pa_assert(s);
3794 pa_assert(volume);
3795
3796 old_volume = s->reference_volume;
3797
3798 if (pa_cvolume_equal(volume, &old_volume))
3799 return;
3800
3801 s->reference_volume = *volume;
3802 pa_log_debug("The reference volume of sink %s changed from %s to %s.", s->name,
3803 pa_cvolume_snprint_verbose(old_volume_str, sizeof(old_volume_str), &old_volume, &s->channel_map,
3804 s->flags & PA_SINK_DECIBEL_VOLUME),
3805 pa_cvolume_snprint_verbose(new_volume_str, sizeof(new_volume_str), volume, &s->channel_map,
3806 s->flags & PA_SINK_DECIBEL_VOLUME));
3807
3808 pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
3809 }