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