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