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