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