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