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