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