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