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