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