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