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