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