ratelimit: fix log levels of log suppression messages
[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 <stdlib.h>
28 #include <string.h>
29 #include <stdio.h>
30
31 #include <pulse/introspect.h>
32 #include <pulse/utf8.h>
33 #include <pulse/xmalloc.h>
34 #include <pulse/timeval.h>
35 #include <pulse/util.h>
36 #include <pulse/i18n.h>
37 #include <pulse/rtclock.h>
38
39 #include <pulsecore/sink-input.h>
40 #include <pulsecore/namereg.h>
41 #include <pulsecore/core-util.h>
42 #include <pulsecore/sample-util.h>
43 #include <pulsecore/core-subscribe.h>
44 #include <pulsecore/log.h>
45 #include <pulsecore/macro.h>
46 #include <pulsecore/play-memblockq.h>
47 #include <pulsecore/flist.h>
48
49 #include "sink.h"
50
51 #define MAX_MIX_CHANNELS 32
52 #define MIX_BUFFER_LENGTH (PA_PAGE_SIZE)
53 #define ABSOLUTE_MIN_LATENCY (500)
54 #define ABSOLUTE_MAX_LATENCY (10*PA_USEC_PER_SEC)
55 #define DEFAULT_FIXED_LATENCY (250*PA_USEC_PER_MSEC)
56
57 PA_DEFINE_PUBLIC_CLASS(pa_sink, pa_msgobject);
58
59 struct pa_sink_volume_change {
60     pa_usec_t at;
61     pa_cvolume hw_volume;
62
63     PA_LLIST_FIELDS(pa_sink_volume_change);
64 };
65
66 struct sink_message_set_port {
67     pa_device_port *port;
68     int ret;
69 };
70
71 static void sink_free(pa_object *s);
72
73 static void pa_sink_volume_change_push(pa_sink *s);
74 static void pa_sink_volume_change_flush(pa_sink *s);
75 static void pa_sink_volume_change_rewind(pa_sink *s, size_t nbytes);
76
77 pa_sink_new_data* pa_sink_new_data_init(pa_sink_new_data *data) {
78     pa_assert(data);
79
80     pa_zero(*data);
81     data->proplist = pa_proplist_new();
82
83     return data;
84 }
85
86 void pa_sink_new_data_set_name(pa_sink_new_data *data, const char *name) {
87     pa_assert(data);
88
89     pa_xfree(data->name);
90     data->name = pa_xstrdup(name);
91 }
92
93 void pa_sink_new_data_set_sample_spec(pa_sink_new_data *data, const pa_sample_spec *spec) {
94     pa_assert(data);
95
96     if ((data->sample_spec_is_set = !!spec))
97         data->sample_spec = *spec;
98 }
99
100 void pa_sink_new_data_set_channel_map(pa_sink_new_data *data, const pa_channel_map *map) {
101     pa_assert(data);
102
103     if ((data->channel_map_is_set = !!map))
104         data->channel_map = *map;
105 }
106
107 void pa_sink_new_data_set_volume(pa_sink_new_data *data, const pa_cvolume *volume) {
108     pa_assert(data);
109
110     if ((data->volume_is_set = !!volume))
111         data->volume = *volume;
112 }
113
114 void pa_sink_new_data_set_muted(pa_sink_new_data *data, pa_bool_t mute) {
115     pa_assert(data);
116
117     data->muted_is_set = TRUE;
118     data->muted = !!mute;
119 }
120
121 void pa_sink_new_data_set_port(pa_sink_new_data *data, const char *port) {
122     pa_assert(data);
123
124     pa_xfree(data->active_port);
125     data->active_port = pa_xstrdup(port);
126 }
127
128 void pa_sink_new_data_done(pa_sink_new_data *data) {
129     pa_assert(data);
130
131     pa_proplist_free(data->proplist);
132
133     if (data->ports) {
134         pa_device_port *p;
135
136         while ((p = pa_hashmap_steal_first(data->ports)))
137             pa_device_port_free(p);
138
139         pa_hashmap_free(data->ports, NULL, NULL);
140     }
141
142     pa_xfree(data->name);
143     pa_xfree(data->active_port);
144 }
145
146 pa_device_port *pa_device_port_new(const char *name, const char *description, size_t extra) {
147     pa_device_port *p;
148
149     pa_assert(name);
150
151     p = pa_xmalloc(PA_ALIGN(sizeof(pa_device_port)) + extra);
152     p->name = pa_xstrdup(name);
153     p->description = pa_xstrdup(description);
154
155     p->priority = 0;
156
157     return p;
158 }
159
160 void pa_device_port_free(pa_device_port *p) {
161     pa_assert(p);
162
163     pa_xfree(p->name);
164     pa_xfree(p->description);
165     pa_xfree(p);
166 }
167
168 /* Called from main context */
169 static void reset_callbacks(pa_sink *s) {
170     pa_assert(s);
171
172     s->set_state = NULL;
173     s->get_volume = NULL;
174     s->set_volume = NULL;
175     s->get_mute = NULL;
176     s->set_mute = NULL;
177     s->request_rewind = NULL;
178     s->update_requested_latency = NULL;
179     s->set_port = NULL;
180 }
181
182 /* Called from main context */
183 pa_sink* pa_sink_new(
184         pa_core *core,
185         pa_sink_new_data *data,
186         pa_sink_flags_t flags) {
187
188     pa_sink *s;
189     const char *name;
190     char st[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
191     pa_source_new_data source_data;
192     const char *dn;
193     char *pt;
194
195     pa_assert(core);
196     pa_assert(data);
197     pa_assert(data->name);
198     pa_assert_ctl_context();
199
200     s = pa_msgobject_new(pa_sink);
201
202     if (!(name = pa_namereg_register(core, data->name, PA_NAMEREG_SINK, s, data->namereg_fail))) {
203         pa_log_debug("Failed to register name %s.", data->name);
204         pa_xfree(s);
205         return NULL;
206     }
207
208     pa_sink_new_data_set_name(data, name);
209
210     if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_NEW], data) < 0) {
211         pa_xfree(s);
212         pa_namereg_unregister(core, name);
213         return NULL;
214     }
215
216     /* FIXME, need to free s here on failure */
217
218     pa_return_null_if_fail(!data->driver || pa_utf8_valid(data->driver));
219     pa_return_null_if_fail(data->name && pa_utf8_valid(data->name) && data->name[0]);
220
221     pa_return_null_if_fail(data->sample_spec_is_set && pa_sample_spec_valid(&data->sample_spec));
222
223     if (!data->channel_map_is_set)
224         pa_return_null_if_fail(pa_channel_map_init_auto(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT));
225
226     pa_return_null_if_fail(pa_channel_map_valid(&data->channel_map));
227     pa_return_null_if_fail(data->channel_map.channels == data->sample_spec.channels);
228
229     if (!data->volume_is_set)
230         pa_cvolume_reset(&data->volume, data->sample_spec.channels);
231
232     pa_return_null_if_fail(pa_cvolume_valid(&data->volume));
233     pa_return_null_if_fail(pa_cvolume_compatible(&data->volume, &data->sample_spec));
234
235     if (!data->muted_is_set)
236         data->muted = FALSE;
237
238     if (data->card)
239         pa_proplist_update(data->proplist, PA_UPDATE_MERGE, data->card->proplist);
240
241     pa_device_init_description(data->proplist);
242     pa_device_init_icon(data->proplist, TRUE);
243     pa_device_init_intended_roles(data->proplist);
244
245     if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_FIXATE], data) < 0) {
246         pa_xfree(s);
247         pa_namereg_unregister(core, name);
248         return NULL;
249     }
250
251     s->parent.parent.free = sink_free;
252     s->parent.process_msg = pa_sink_process_msg;
253
254     s->core = core;
255     s->state = PA_SINK_INIT;
256     s->flags = flags;
257     s->priority = 0;
258     s->suspend_cause = 0;
259     s->name = pa_xstrdup(name);
260     s->proplist = pa_proplist_copy(data->proplist);
261     s->driver = pa_xstrdup(pa_path_get_filename(data->driver));
262     s->module = data->module;
263     s->card = data->card;
264
265     s->priority = pa_device_init_priority(s->proplist);
266
267     s->sample_spec = data->sample_spec;
268     s->channel_map = data->channel_map;
269
270     s->inputs = pa_idxset_new(NULL, NULL);
271     s->n_corked = 0;
272
273     s->reference_volume = s->real_volume = data->volume;
274     pa_cvolume_reset(&s->soft_volume, s->sample_spec.channels);
275     s->base_volume = PA_VOLUME_NORM;
276     s->n_volume_steps = PA_VOLUME_NORM+1;
277     s->muted = data->muted;
278     s->refresh_volume = s->refresh_muted = FALSE;
279
280     reset_callbacks(s);
281     s->userdata = NULL;
282
283     s->asyncmsgq = NULL;
284
285     /* As a minor optimization we just steal the list instead of
286      * copying it here */
287     s->ports = data->ports;
288     data->ports = NULL;
289
290     s->active_port = NULL;
291     s->save_port = FALSE;
292
293     if (data->active_port && s->ports)
294         if ((s->active_port = pa_hashmap_get(s->ports, data->active_port)))
295             s->save_port = data->save_port;
296
297     if (!s->active_port && s->ports) {
298         void *state;
299         pa_device_port *p;
300
301         PA_HASHMAP_FOREACH(p, s->ports, state)
302             if (!s->active_port || p->priority > s->active_port->priority)
303                 s->active_port = p;
304     }
305
306     s->save_volume = data->save_volume;
307     s->save_muted = data->save_muted;
308
309     pa_silence_memchunk_get(
310             &core->silence_cache,
311             core->mempool,
312             &s->silence,
313             &s->sample_spec,
314             0);
315
316     s->thread_info.rtpoll = NULL;
317     s->thread_info.inputs = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
318     s->thread_info.soft_volume =  s->soft_volume;
319     s->thread_info.soft_muted = s->muted;
320     s->thread_info.state = s->state;
321     s->thread_info.rewind_nbytes = 0;
322     s->thread_info.rewind_requested = FALSE;
323     s->thread_info.max_rewind = 0;
324     s->thread_info.max_request = 0;
325     s->thread_info.requested_latency_valid = FALSE;
326     s->thread_info.requested_latency = 0;
327     s->thread_info.min_latency = ABSOLUTE_MIN_LATENCY;
328     s->thread_info.max_latency = ABSOLUTE_MAX_LATENCY;
329     s->thread_info.fixed_latency = flags & PA_SINK_DYNAMIC_LATENCY ? 0 : DEFAULT_FIXED_LATENCY;
330
331     PA_LLIST_HEAD_INIT(pa_sink_volume_change, s->thread_info.volume_changes);
332     s->thread_info.volume_changes_tail = NULL;
333     pa_sw_cvolume_multiply(&s->thread_info.current_hw_volume, &s->soft_volume, &s->real_volume);
334     s->thread_info.volume_change_safety_margin = core->sync_volume_safety_margin_usec;
335     s->thread_info.volume_change_extra_delay = core->sync_volume_extra_delay_usec;
336
337     /* FIXME: This should probably be moved to pa_sink_put() */
338     pa_assert_se(pa_idxset_put(core->sinks, s, &s->index) >= 0);
339
340     if (s->card)
341         pa_assert_se(pa_idxset_put(s->card->sinks, s, NULL) >= 0);
342
343     pt = pa_proplist_to_string_sep(s->proplist, "\n    ");
344     pa_log_info("Created sink %u \"%s\" with sample spec %s and channel map %s\n    %s",
345                 s->index,
346                 s->name,
347                 pa_sample_spec_snprint(st, sizeof(st), &s->sample_spec),
348                 pa_channel_map_snprint(cm, sizeof(cm), &s->channel_map),
349                 pt);
350     pa_xfree(pt);
351
352     pa_source_new_data_init(&source_data);
353     pa_source_new_data_set_sample_spec(&source_data, &s->sample_spec);
354     pa_source_new_data_set_channel_map(&source_data, &s->channel_map);
355     source_data.name = pa_sprintf_malloc("%s.monitor", name);
356     source_data.driver = data->driver;
357     source_data.module = data->module;
358     source_data.card = data->card;
359
360     dn = pa_proplist_gets(s->proplist, PA_PROP_DEVICE_DESCRIPTION);
361     pa_proplist_setf(source_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Monitor of %s", dn ? dn : s->name);
362     pa_proplist_sets(source_data.proplist, PA_PROP_DEVICE_CLASS, "monitor");
363
364     s->monitor_source = pa_source_new(core, &source_data,
365                                       ((flags & PA_SINK_LATENCY) ? PA_SOURCE_LATENCY : 0) |
366                                       ((flags & PA_SINK_DYNAMIC_LATENCY) ? PA_SOURCE_DYNAMIC_LATENCY : 0));
367
368     pa_source_new_data_done(&source_data);
369
370     if (!s->monitor_source) {
371         pa_sink_unlink(s);
372         pa_sink_unref(s);
373         return NULL;
374     }
375
376     s->monitor_source->monitor_of = s;
377
378     pa_source_set_latency_range(s->monitor_source, s->thread_info.min_latency, s->thread_info.max_latency);
379     pa_source_set_fixed_latency(s->monitor_source, s->thread_info.fixed_latency);
380     pa_source_set_max_rewind(s->monitor_source, s->thread_info.max_rewind);
381
382     return s;
383 }
384
385 /* Called from main context */
386 static int sink_set_state(pa_sink *s, pa_sink_state_t state) {
387     int ret;
388     pa_bool_t suspend_change;
389     pa_sink_state_t original_state;
390
391     pa_assert(s);
392     pa_assert_ctl_context();
393
394     if (s->state == state)
395         return 0;
396
397     original_state = s->state;
398
399     suspend_change =
400         (original_state == PA_SINK_SUSPENDED && PA_SINK_IS_OPENED(state)) ||
401         (PA_SINK_IS_OPENED(original_state) && state == PA_SINK_SUSPENDED);
402
403     if (s->set_state)
404         if ((ret = s->set_state(s, state)) < 0)
405             return ret;
406
407     if (s->asyncmsgq)
408         if ((ret = pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), 0, NULL)) < 0) {
409
410             if (s->set_state)
411                 s->set_state(s, original_state);
412
413             return ret;
414         }
415
416     s->state = state;
417
418     if (state != PA_SINK_UNLINKED) { /* if we enter UNLINKED state pa_sink_unlink() will fire the apropriate events */
419         pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_STATE_CHANGED], s);
420         pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
421     }
422
423     if (suspend_change) {
424         pa_sink_input *i;
425         uint32_t idx;
426
427         /* We're suspending or resuming, tell everyone about it */
428
429         PA_IDXSET_FOREACH(i, s->inputs, idx)
430             if (s->state == PA_SINK_SUSPENDED &&
431                 (i->flags & PA_SINK_INPUT_KILL_ON_SUSPEND))
432                 pa_sink_input_kill(i);
433             else if (i->suspend)
434                 i->suspend(i, state == PA_SINK_SUSPENDED);
435
436         if (s->monitor_source)
437             pa_source_sync_suspend(s->monitor_source);
438     }
439
440     return 0;
441 }
442
443 /* Called from main context */
444 void pa_sink_put(pa_sink* s) {
445     pa_sink_assert_ref(s);
446     pa_assert_ctl_context();
447
448     pa_assert(s->state == PA_SINK_INIT);
449
450     /* The following fields must be initialized properly when calling _put() */
451     pa_assert(s->asyncmsgq);
452     pa_assert(s->thread_info.min_latency <= s->thread_info.max_latency);
453
454     /* Generally, flags should be initialized via pa_sink_new(). As a
455      * special exception we allow volume related flags to be set
456      * between _new() and _put(). */
457
458     if (!(s->flags & PA_SINK_HW_VOLUME_CTRL))
459         s->flags |= PA_SINK_DECIBEL_VOLUME;
460
461     if ((s->flags & PA_SINK_DECIBEL_VOLUME) && s->core->flat_volumes)
462         s->flags |= PA_SINK_FLAT_VOLUME;
463
464     /* We assume that if the sink implementor changed the default
465      * volume he did so in real_volume, because that is the usual
466      * place where he is supposed to place his changes.  */
467     s->reference_volume = s->real_volume;
468
469     s->thread_info.soft_volume = s->soft_volume;
470     s->thread_info.soft_muted = s->muted;
471     pa_sw_cvolume_multiply(&s->thread_info.current_hw_volume, &s->soft_volume, &s->real_volume);
472
473     pa_assert((s->flags & PA_SINK_HW_VOLUME_CTRL) || (s->base_volume == PA_VOLUME_NORM && s->flags & PA_SINK_DECIBEL_VOLUME));
474     pa_assert(!(s->flags & PA_SINK_DECIBEL_VOLUME) || s->n_volume_steps == PA_VOLUME_NORM+1);
475     pa_assert(!(s->flags & PA_SINK_DYNAMIC_LATENCY) == (s->thread_info.fixed_latency != 0));
476     pa_assert(!(s->flags & PA_SINK_LATENCY) == !(s->monitor_source->flags & PA_SOURCE_LATENCY));
477     pa_assert(!(s->flags & PA_SINK_DYNAMIC_LATENCY) == !(s->monitor_source->flags & PA_SOURCE_DYNAMIC_LATENCY));
478     pa_assert(!(s->flags & PA_SINK_HW_VOLUME_CTRL) || s->set_volume);
479     pa_assert(!(s->flags & PA_SINK_SYNC_VOLUME) || (s->flags & PA_SINK_HW_VOLUME_CTRL));
480     pa_assert(!(s->flags & PA_SINK_SYNC_VOLUME) || s->write_volume);
481     pa_assert(!(s->flags & PA_SINK_HW_MUTE_CTRL) || s->set_mute);
482
483     pa_assert(s->monitor_source->thread_info.fixed_latency == s->thread_info.fixed_latency);
484     pa_assert(s->monitor_source->thread_info.min_latency == s->thread_info.min_latency);
485     pa_assert(s->monitor_source->thread_info.max_latency == s->thread_info.max_latency);
486
487     pa_assert_se(sink_set_state(s, PA_SINK_IDLE) == 0);
488
489     pa_source_put(s->monitor_source);
490
491     pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_NEW, s->index);
492     pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_PUT], s);
493 }
494
495 /* Called from main context */
496 void pa_sink_unlink(pa_sink* s) {
497     pa_bool_t linked;
498     pa_sink_input *i, *j = NULL;
499
500     pa_assert(s);
501     pa_assert_ctl_context();
502
503     /* Please note that pa_sink_unlink() does more than simply
504      * reversing pa_sink_put(). It also undoes the registrations
505      * already done in pa_sink_new()! */
506
507     /* All operations here shall be idempotent, i.e. pa_sink_unlink()
508      * may be called multiple times on the same sink without bad
509      * effects. */
510
511     linked = PA_SINK_IS_LINKED(s->state);
512
513     if (linked)
514         pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_UNLINK], s);
515
516     if (s->state != PA_SINK_UNLINKED)
517         pa_namereg_unregister(s->core, s->name);
518     pa_idxset_remove_by_data(s->core->sinks, s, NULL);
519
520     if (s->card)
521         pa_idxset_remove_by_data(s->card->sinks, s, NULL);
522
523     while ((i = pa_idxset_first(s->inputs, NULL))) {
524         pa_assert(i != j);
525         pa_sink_input_kill(i);
526         j = i;
527     }
528
529     if (linked)
530         sink_set_state(s, PA_SINK_UNLINKED);
531     else
532         s->state = PA_SINK_UNLINKED;
533
534     reset_callbacks(s);
535
536     if (s->monitor_source)
537         pa_source_unlink(s->monitor_source);
538
539     if (linked) {
540         pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_REMOVE, s->index);
541         pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_UNLINK_POST], s);
542     }
543 }
544
545 /* Called from main context */
546 static void sink_free(pa_object *o) {
547     pa_sink *s = PA_SINK(o);
548     pa_sink_input *i;
549
550     pa_assert(s);
551     pa_assert_ctl_context();
552     pa_assert(pa_sink_refcnt(s) == 0);
553
554     if (PA_SINK_IS_LINKED(s->state))
555         pa_sink_unlink(s);
556
557     pa_log_info("Freeing sink %u \"%s\"", s->index, s->name);
558
559     if (s->monitor_source) {
560         pa_source_unref(s->monitor_source);
561         s->monitor_source = NULL;
562     }
563
564     pa_idxset_free(s->inputs, NULL, NULL);
565
566     while ((i = pa_hashmap_steal_first(s->thread_info.inputs)))
567         pa_sink_input_unref(i);
568
569     pa_hashmap_free(s->thread_info.inputs, NULL, NULL);
570
571     if (s->silence.memblock)
572         pa_memblock_unref(s->silence.memblock);
573
574     pa_xfree(s->name);
575     pa_xfree(s->driver);
576
577     if (s->proplist)
578         pa_proplist_free(s->proplist);
579
580     if (s->ports) {
581         pa_device_port *p;
582
583         while ((p = pa_hashmap_steal_first(s->ports)))
584             pa_device_port_free(p);
585
586         pa_hashmap_free(s->ports, NULL, NULL);
587     }
588
589     pa_xfree(s);
590 }
591
592 /* Called from main context, and not while the IO thread is active, please */
593 void pa_sink_set_asyncmsgq(pa_sink *s, pa_asyncmsgq *q) {
594     pa_sink_assert_ref(s);
595     pa_assert_ctl_context();
596
597     s->asyncmsgq = q;
598
599     if (s->monitor_source)
600         pa_source_set_asyncmsgq(s->monitor_source, q);
601 }
602
603 /* Called from main context, and not while the IO thread is active, please */
604 void pa_sink_update_flags(pa_sink *s, pa_sink_flags_t mask, pa_sink_flags_t value) {
605     pa_sink_assert_ref(s);
606     pa_assert_ctl_context();
607
608     if (mask == 0)
609         return;
610
611     /* For now, allow only a minimal set of flags to be changed. */
612     pa_assert((mask & ~(PA_SINK_DYNAMIC_LATENCY|PA_SINK_LATENCY)) == 0);
613
614     s->flags = (s->flags & ~mask) | (value & mask);
615
616     pa_source_update_flags(s->monitor_source,
617                            ((mask & PA_SINK_LATENCY) ? PA_SOURCE_LATENCY : 0) |
618                            ((mask & PA_SINK_DYNAMIC_LATENCY) ? PA_SOURCE_DYNAMIC_LATENCY : 0),
619                            ((value & PA_SINK_LATENCY) ? PA_SOURCE_LATENCY : 0) |
620                            ((value & PA_SINK_DYNAMIC_LATENCY) ? PA_SINK_DYNAMIC_LATENCY : 0));
621 }
622
623 /* Called from IO context, or before _put() from main context */
624 void pa_sink_set_rtpoll(pa_sink *s, pa_rtpoll *p) {
625     pa_sink_assert_ref(s);
626     pa_sink_assert_io_context(s);
627
628     s->thread_info.rtpoll = p;
629
630     if (s->monitor_source)
631         pa_source_set_rtpoll(s->monitor_source, p);
632 }
633
634 /* Called from main context */
635 int pa_sink_update_status(pa_sink*s) {
636     pa_sink_assert_ref(s);
637     pa_assert_ctl_context();
638     pa_assert(PA_SINK_IS_LINKED(s->state));
639
640     if (s->state == PA_SINK_SUSPENDED)
641         return 0;
642
643     return sink_set_state(s, pa_sink_used_by(s) ? PA_SINK_RUNNING : PA_SINK_IDLE);
644 }
645
646 /* Called from main context */
647 int pa_sink_suspend(pa_sink *s, pa_bool_t suspend, pa_suspend_cause_t cause) {
648     pa_sink_assert_ref(s);
649     pa_assert_ctl_context();
650     pa_assert(PA_SINK_IS_LINKED(s->state));
651     pa_assert(cause != 0);
652
653     if (suspend) {
654         s->suspend_cause |= cause;
655         s->monitor_source->suspend_cause |= cause;
656     } else {
657         s->suspend_cause &= ~cause;
658         s->monitor_source->suspend_cause &= ~cause;
659     }
660
661     if ((pa_sink_get_state(s) == PA_SINK_SUSPENDED) == !!s->suspend_cause)
662         return 0;
663
664     pa_log_debug("Suspend cause of sink %s is 0x%04x, %s", s->name, s->suspend_cause, s->suspend_cause ? "suspending" : "resuming");
665
666     if (s->suspend_cause)
667         return sink_set_state(s, PA_SINK_SUSPENDED);
668     else
669         return sink_set_state(s, pa_sink_used_by(s) ? PA_SINK_RUNNING : PA_SINK_IDLE);
670 }
671
672 /* Called from main context */
673 pa_queue *pa_sink_move_all_start(pa_sink *s, pa_queue *q) {
674     pa_sink_input *i, *n;
675     uint32_t idx;
676
677     pa_sink_assert_ref(s);
678     pa_assert_ctl_context();
679     pa_assert(PA_SINK_IS_LINKED(s->state));
680
681     if (!q)
682         q = pa_queue_new();
683
684     for (i = PA_SINK_INPUT(pa_idxset_first(s->inputs, &idx)); i; i = n) {
685         n = PA_SINK_INPUT(pa_idxset_next(s->inputs, &idx));
686
687         pa_sink_input_ref(i);
688
689         if (pa_sink_input_start_move(i) >= 0)
690             pa_queue_push(q, i);
691         else
692             pa_sink_input_unref(i);
693     }
694
695     return q;
696 }
697
698 /* Called from main context */
699 void pa_sink_move_all_finish(pa_sink *s, pa_queue *q, pa_bool_t save) {
700     pa_sink_input *i;
701
702     pa_sink_assert_ref(s);
703     pa_assert_ctl_context();
704     pa_assert(PA_SINK_IS_LINKED(s->state));
705     pa_assert(q);
706
707     while ((i = PA_SINK_INPUT(pa_queue_pop(q)))) {
708         if (pa_sink_input_finish_move(i, s, save) < 0)
709             pa_sink_input_fail_move(i);
710
711         pa_sink_input_unref(i);
712     }
713
714     pa_queue_free(q, NULL, NULL);
715 }
716
717 /* Called from main context */
718 void pa_sink_move_all_fail(pa_queue *q) {
719     pa_sink_input *i;
720
721     pa_assert_ctl_context();
722     pa_assert(q);
723
724     while ((i = PA_SINK_INPUT(pa_queue_pop(q)))) {
725         pa_sink_input_fail_move(i);
726         pa_sink_input_unref(i);
727     }
728
729     pa_queue_free(q, NULL, NULL);
730 }
731
732 /* Called from IO thread context */
733 void pa_sink_process_rewind(pa_sink *s, size_t nbytes) {
734     pa_sink_input *i;
735     void *state = NULL;
736
737     pa_sink_assert_ref(s);
738     pa_sink_assert_io_context(s);
739     pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
740
741     /* If nobody requested this and this is actually no real rewind
742      * then we can short cut this. Please note that this means that
743      * not all rewind requests triggered upstream will always be
744      * translated in actual requests! */
745     if (!s->thread_info.rewind_requested && nbytes <= 0)
746         return;
747
748     s->thread_info.rewind_nbytes = 0;
749     s->thread_info.rewind_requested = FALSE;
750
751     if (s->thread_info.state == PA_SINK_SUSPENDED)
752         return;
753
754     if (nbytes > 0) {
755         pa_log_debug("Processing rewind...");
756         if (s->flags & PA_SINK_SYNC_VOLUME)
757             pa_sink_volume_change_rewind(s, nbytes);
758     }
759
760     PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state) {
761         pa_sink_input_assert_ref(i);
762         pa_sink_input_process_rewind(i, nbytes);
763     }
764
765     if (nbytes > 0) {
766         if (s->monitor_source && PA_SOURCE_IS_LINKED(s->monitor_source->thread_info.state))
767             pa_source_process_rewind(s->monitor_source, nbytes);
768     }
769 }
770
771 /* Called from IO thread context */
772 static unsigned fill_mix_info(pa_sink *s, size_t *length, pa_mix_info *info, unsigned maxinfo) {
773     pa_sink_input *i;
774     unsigned n = 0;
775     void *state = NULL;
776     size_t mixlength = *length;
777
778     pa_sink_assert_ref(s);
779     pa_sink_assert_io_context(s);
780     pa_assert(info);
781
782     while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)) && maxinfo > 0) {
783         pa_sink_input_assert_ref(i);
784
785         pa_sink_input_peek(i, *length, &info->chunk, &info->volume);
786
787         if (mixlength == 0 || info->chunk.length < mixlength)
788             mixlength = info->chunk.length;
789
790         if (pa_memblock_is_silence(info->chunk.memblock)) {
791             pa_memblock_unref(info->chunk.memblock);
792             continue;
793         }
794
795         info->userdata = pa_sink_input_ref(i);
796
797         pa_assert(info->chunk.memblock);
798         pa_assert(info->chunk.length > 0);
799
800         info++;
801         n++;
802         maxinfo--;
803     }
804
805     if (mixlength > 0)
806         *length = mixlength;
807
808     return n;
809 }
810
811 /* Called from IO thread context */
812 static void inputs_drop(pa_sink *s, pa_mix_info *info, unsigned n, pa_memchunk *result) {
813     pa_sink_input *i;
814     void *state;
815     unsigned p = 0;
816     unsigned n_unreffed = 0;
817
818     pa_sink_assert_ref(s);
819     pa_sink_assert_io_context(s);
820     pa_assert(result);
821     pa_assert(result->memblock);
822     pa_assert(result->length > 0);
823
824     /* We optimize for the case where the order of the inputs has not changed */
825
826     PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state) {
827         unsigned j;
828         pa_mix_info* m = NULL;
829
830         pa_sink_input_assert_ref(i);
831
832         /* Let's try to find the matching entry info the pa_mix_info array */
833         for (j = 0; j < n; j ++) {
834
835             if (info[p].userdata == i) {
836                 m = info + p;
837                 break;
838             }
839
840             p++;
841             if (p >= n)
842                 p = 0;
843         }
844
845         /* Drop read data */
846         pa_sink_input_drop(i, result->length);
847
848         if (s->monitor_source && PA_SOURCE_IS_LINKED(s->monitor_source->thread_info.state)) {
849
850             if (pa_hashmap_size(i->thread_info.direct_outputs) > 0) {
851                 void *ostate = NULL;
852                 pa_source_output *o;
853                 pa_memchunk c;
854
855                 if (m && m->chunk.memblock) {
856                     c = m->chunk;
857                     pa_memblock_ref(c.memblock);
858                     pa_assert(result->length <= c.length);
859                     c.length = result->length;
860
861                     pa_memchunk_make_writable(&c, 0);
862                     pa_volume_memchunk(&c, &s->sample_spec, &m->volume);
863                 } else {
864                     c = s->silence;
865                     pa_memblock_ref(c.memblock);
866                     pa_assert(result->length <= c.length);
867                     c.length = result->length;
868                 }
869
870                 while ((o = pa_hashmap_iterate(i->thread_info.direct_outputs, &ostate, NULL))) {
871                     pa_source_output_assert_ref(o);
872                     pa_assert(o->direct_on_input == i);
873                     pa_source_post_direct(s->monitor_source, o, &c);
874                 }
875
876                 pa_memblock_unref(c.memblock);
877             }
878         }
879
880         if (m) {
881             if (m->chunk.memblock)
882                 pa_memblock_unref(m->chunk.memblock);
883                 pa_memchunk_reset(&m->chunk);
884
885             pa_sink_input_unref(m->userdata);
886             m->userdata = NULL;
887
888             n_unreffed += 1;
889         }
890     }
891
892     /* Now drop references to entries that are included in the
893      * pa_mix_info array but don't exist anymore */
894
895     if (n_unreffed < n) {
896         for (; n > 0; info++, n--) {
897             if (info->userdata)
898                 pa_sink_input_unref(info->userdata);
899             if (info->chunk.memblock)
900                 pa_memblock_unref(info->chunk.memblock);
901         }
902     }
903
904     if (s->monitor_source && PA_SOURCE_IS_LINKED(s->monitor_source->thread_info.state))
905         pa_source_post(s->monitor_source, result);
906 }
907
908 /* Called from IO thread context */
909 void pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) {
910     pa_mix_info info[MAX_MIX_CHANNELS];
911     unsigned n;
912     size_t block_size_max;
913
914     pa_sink_assert_ref(s);
915     pa_sink_assert_io_context(s);
916     pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
917     pa_assert(pa_frame_aligned(length, &s->sample_spec));
918     pa_assert(result);
919
920     pa_assert(!s->thread_info.rewind_requested);
921     pa_assert(s->thread_info.rewind_nbytes == 0);
922
923     if (s->thread_info.state == PA_SINK_SUSPENDED) {
924         result->memblock = pa_memblock_ref(s->silence.memblock);
925         result->index = s->silence.index;
926         result->length = PA_MIN(s->silence.length, length);
927         return;
928     }
929
930     pa_sink_ref(s);
931
932     if (length <= 0)
933         length = pa_frame_align(MIX_BUFFER_LENGTH, &s->sample_spec);
934
935     block_size_max = pa_mempool_block_size_max(s->core->mempool);
936     if (length > block_size_max)
937         length = pa_frame_align(block_size_max, &s->sample_spec);
938
939     pa_assert(length > 0);
940
941     n = fill_mix_info(s, &length, info, MAX_MIX_CHANNELS);
942
943     if (n == 0) {
944
945         *result = s->silence;
946         pa_memblock_ref(result->memblock);
947
948         if (result->length > length)
949             result->length = length;
950
951     } else if (n == 1) {
952         pa_cvolume volume;
953
954         *result = info[0].chunk;
955         pa_memblock_ref(result->memblock);
956
957         if (result->length > length)
958             result->length = length;
959
960         pa_sw_cvolume_multiply(&volume, &s->thread_info.soft_volume, &info[0].volume);
961
962         if (s->thread_info.soft_muted || pa_cvolume_is_muted(&volume)) {
963             pa_memblock_unref(result->memblock);
964             pa_silence_memchunk_get(&s->core->silence_cache,
965                                     s->core->mempool,
966                                     result,
967                                     &s->sample_spec,
968                                     result->length);
969         } else if (!pa_cvolume_is_norm(&volume)) {
970             pa_memchunk_make_writable(result, 0);
971             pa_volume_memchunk(result, &s->sample_spec, &volume);
972         }
973     } else {
974         void *ptr;
975         result->memblock = pa_memblock_new(s->core->mempool, length);
976
977         ptr = pa_memblock_acquire(result->memblock);
978         result->length = pa_mix(info, n,
979                                 ptr, length,
980                                 &s->sample_spec,
981                                 &s->thread_info.soft_volume,
982                                 s->thread_info.soft_muted);
983         pa_memblock_release(result->memblock);
984
985         result->index = 0;
986     }
987
988     inputs_drop(s, info, n, result);
989
990     pa_sink_unref(s);
991 }
992
993 /* Called from IO thread context */
994 void pa_sink_render_into(pa_sink*s, pa_memchunk *target) {
995     pa_mix_info info[MAX_MIX_CHANNELS];
996     unsigned n;
997     size_t length, block_size_max;
998
999     pa_sink_assert_ref(s);
1000     pa_sink_assert_io_context(s);
1001     pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
1002     pa_assert(target);
1003     pa_assert(target->memblock);
1004     pa_assert(target->length > 0);
1005     pa_assert(pa_frame_aligned(target->length, &s->sample_spec));
1006
1007     pa_assert(!s->thread_info.rewind_requested);
1008     pa_assert(s->thread_info.rewind_nbytes == 0);
1009
1010     if (s->thread_info.state == PA_SINK_SUSPENDED) {
1011         pa_silence_memchunk(target, &s->sample_spec);
1012         return;
1013     }
1014
1015     pa_sink_ref(s);
1016
1017     length = target->length;
1018     block_size_max = pa_mempool_block_size_max(s->core->mempool);
1019     if (length > block_size_max)
1020         length = pa_frame_align(block_size_max, &s->sample_spec);
1021
1022     pa_assert(length > 0);
1023
1024     n = fill_mix_info(s, &length, info, MAX_MIX_CHANNELS);
1025
1026     if (n == 0) {
1027         if (target->length > length)
1028             target->length = length;
1029
1030         pa_silence_memchunk(target, &s->sample_spec);
1031     } else if (n == 1) {
1032         pa_cvolume volume;
1033
1034         if (target->length > length)
1035             target->length = length;
1036
1037         pa_sw_cvolume_multiply(&volume, &s->thread_info.soft_volume, &info[0].volume);
1038
1039         if (s->thread_info.soft_muted || pa_cvolume_is_muted(&volume))
1040             pa_silence_memchunk(target, &s->sample_spec);
1041         else {
1042             pa_memchunk vchunk;
1043
1044             vchunk = info[0].chunk;
1045             pa_memblock_ref(vchunk.memblock);
1046
1047             if (vchunk.length > length)
1048                 vchunk.length = length;
1049
1050             if (!pa_cvolume_is_norm(&volume)) {
1051                 pa_memchunk_make_writable(&vchunk, 0);
1052                 pa_volume_memchunk(&vchunk, &s->sample_spec, &volume);
1053             }
1054
1055             pa_memchunk_memcpy(target, &vchunk);
1056             pa_memblock_unref(vchunk.memblock);
1057         }
1058
1059     } else {
1060         void *ptr;
1061
1062         ptr = pa_memblock_acquire(target->memblock);
1063
1064         target->length = pa_mix(info, n,
1065                                 (uint8_t*) ptr + target->index, length,
1066                                 &s->sample_spec,
1067                                 &s->thread_info.soft_volume,
1068                                 s->thread_info.soft_muted);
1069
1070         pa_memblock_release(target->memblock);
1071     }
1072
1073     inputs_drop(s, info, n, target);
1074
1075     pa_sink_unref(s);
1076 }
1077
1078 /* Called from IO thread context */
1079 void pa_sink_render_into_full(pa_sink *s, pa_memchunk *target) {
1080     pa_memchunk chunk;
1081     size_t l, d;
1082
1083     pa_sink_assert_ref(s);
1084     pa_sink_assert_io_context(s);
1085     pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
1086     pa_assert(target);
1087     pa_assert(target->memblock);
1088     pa_assert(target->length > 0);
1089     pa_assert(pa_frame_aligned(target->length, &s->sample_spec));
1090
1091     pa_assert(!s->thread_info.rewind_requested);
1092     pa_assert(s->thread_info.rewind_nbytes == 0);
1093
1094     if (s->thread_info.state == PA_SINK_SUSPENDED) {
1095         pa_silence_memchunk(target, &s->sample_spec);
1096         return;
1097     }
1098
1099     pa_sink_ref(s);
1100
1101     l = target->length;
1102     d = 0;
1103     while (l > 0) {
1104         chunk = *target;
1105         chunk.index += d;
1106         chunk.length -= d;
1107
1108         pa_sink_render_into(s, &chunk);
1109
1110         d += chunk.length;
1111         l -= chunk.length;
1112     }
1113
1114     pa_sink_unref(s);
1115 }
1116
1117 /* Called from IO thread context */
1118 void pa_sink_render_full(pa_sink *s, size_t length, pa_memchunk *result) {
1119     pa_sink_assert_ref(s);
1120     pa_sink_assert_io_context(s);
1121     pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
1122     pa_assert(length > 0);
1123     pa_assert(pa_frame_aligned(length, &s->sample_spec));
1124     pa_assert(result);
1125
1126     pa_assert(!s->thread_info.rewind_requested);
1127     pa_assert(s->thread_info.rewind_nbytes == 0);
1128
1129     pa_sink_ref(s);
1130
1131     pa_sink_render(s, length, result);
1132
1133     if (result->length < length) {
1134         pa_memchunk chunk;
1135
1136         pa_memchunk_make_writable(result, length);
1137
1138         chunk.memblock = result->memblock;
1139         chunk.index = result->index + result->length;
1140         chunk.length = length - result->length;
1141
1142         pa_sink_render_into_full(s, &chunk);
1143
1144         result->length = length;
1145     }
1146
1147     pa_sink_unref(s);
1148 }
1149
1150 /* Called from main thread */
1151 pa_usec_t pa_sink_get_latency(pa_sink *s) {
1152     pa_usec_t usec = 0;
1153
1154     pa_sink_assert_ref(s);
1155     pa_assert_ctl_context();
1156     pa_assert(PA_SINK_IS_LINKED(s->state));
1157
1158     /* The returned value is supposed to be in the time domain of the sound card! */
1159
1160     if (s->state == PA_SINK_SUSPENDED)
1161         return 0;
1162
1163     if (!(s->flags & PA_SINK_LATENCY))
1164         return 0;
1165
1166     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_LATENCY, &usec, 0, NULL) == 0);
1167
1168     return usec;
1169 }
1170
1171 /* Called from IO thread */
1172 pa_usec_t pa_sink_get_latency_within_thread(pa_sink *s) {
1173     pa_usec_t usec = 0;
1174     pa_msgobject *o;
1175
1176     pa_sink_assert_ref(s);
1177     pa_sink_assert_io_context(s);
1178     pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
1179
1180     /* The returned value is supposed to be in the time domain of the sound card! */
1181
1182     if (s->thread_info.state == PA_SINK_SUSPENDED)
1183         return 0;
1184
1185     if (!(s->flags & PA_SINK_LATENCY))
1186         return 0;
1187
1188     o = PA_MSGOBJECT(s);
1189
1190     /* FIXME: We probably should make this a proper vtable callback instead of going through process_msg() */
1191
1192     if (o->process_msg(o, PA_SINK_MESSAGE_GET_LATENCY, &usec, 0, NULL) < 0)
1193         return -1;
1194
1195     return usec;
1196 }
1197
1198 static pa_cvolume* cvolume_remap_minimal_impact(
1199         pa_cvolume *v,
1200         const pa_cvolume *template,
1201         const pa_channel_map *from,
1202         const pa_channel_map *to) {
1203
1204     pa_cvolume t;
1205
1206     pa_assert(v);
1207     pa_assert(template);
1208     pa_assert(from);
1209     pa_assert(to);
1210
1211     pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(v, from), NULL);
1212     pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(template, to), NULL);
1213
1214     /* Much like pa_cvolume_remap(), but tries to minimize impact when
1215      * mapping from sink input to sink volumes:
1216      *
1217      * If template is a possible remapping from v it is used instead
1218      * of remapping anew.
1219      *
1220      * If the channel maps don't match we set an all-channel volume on
1221      * the sink to ensure that changing a volume on one stream has no
1222      * effect that cannot be compensated for in another stream that
1223      * does not have the same channel map as the sink. */
1224
1225     if (pa_channel_map_equal(from, to))
1226         return v;
1227
1228     t = *template;
1229     if (pa_cvolume_equal(pa_cvolume_remap(&t, to, from), v)) {
1230         *v = *template;
1231         return v;
1232     }
1233
1234     pa_cvolume_set(v, to->channels, pa_cvolume_max(v));
1235     return v;
1236 }
1237
1238 /* Called from main context */
1239 static void compute_reference_ratios(pa_sink *s) {
1240     uint32_t idx;
1241     pa_sink_input *i;
1242
1243     pa_sink_assert_ref(s);
1244     pa_assert_ctl_context();
1245     pa_assert(PA_SINK_IS_LINKED(s->state));
1246     pa_assert(s->flags & PA_SINK_FLAT_VOLUME);
1247
1248     PA_IDXSET_FOREACH(i, s->inputs, idx) {
1249         unsigned c;
1250         pa_cvolume remapped;
1251
1252         /*
1253          * Calculates the reference volume from the sink's reference
1254          * volume. This basically calculates:
1255          *
1256          * i->reference_ratio = i->volume / s->reference_volume
1257          */
1258
1259         remapped = s->reference_volume;
1260         pa_cvolume_remap(&remapped, &s->channel_map, &i->channel_map);
1261
1262         i->reference_ratio.channels = i->sample_spec.channels;
1263
1264         for (c = 0; c < i->sample_spec.channels; c++) {
1265
1266             /* We don't update when the sink volume is 0 anyway */
1267             if (remapped.values[c] <= PA_VOLUME_MUTED)
1268                 continue;
1269
1270             /* Don't update the reference ratio unless necessary */
1271             if (pa_sw_volume_multiply(
1272                         i->reference_ratio.values[c],
1273                         remapped.values[c]) == i->volume.values[c])
1274                 continue;
1275
1276             i->reference_ratio.values[c] = pa_sw_volume_divide(
1277                     i->volume.values[c],
1278                     remapped.values[c]);
1279         }
1280     }
1281 }
1282
1283 /* Called from main context */
1284 static void compute_real_ratios(pa_sink *s) {
1285     pa_sink_input *i;
1286     uint32_t idx;
1287
1288     pa_sink_assert_ref(s);
1289     pa_assert_ctl_context();
1290     pa_assert(PA_SINK_IS_LINKED(s->state));
1291     pa_assert(s->flags & PA_SINK_FLAT_VOLUME);
1292
1293     PA_IDXSET_FOREACH(i, s->inputs, idx) {
1294         unsigned c;
1295         pa_cvolume remapped;
1296
1297         /*
1298          * This basically calculates:
1299          *
1300          * i->real_ratio := i->volume / s->real_volume
1301          * i->soft_volume := i->real_ratio * i->volume_factor
1302          */
1303
1304         remapped = s->real_volume;
1305         pa_cvolume_remap(&remapped, &s->channel_map, &i->channel_map);
1306
1307         i->real_ratio.channels = i->sample_spec.channels;
1308         i->soft_volume.channels = i->sample_spec.channels;
1309
1310         for (c = 0; c < i->sample_spec.channels; c++) {
1311
1312             if (remapped.values[c] <= PA_VOLUME_MUTED) {
1313                 /* We leave i->real_ratio untouched */
1314                 i->soft_volume.values[c] = PA_VOLUME_MUTED;
1315                 continue;
1316             }
1317
1318             /* Don't lose accuracy unless necessary */
1319             if (pa_sw_volume_multiply(
1320                         i->real_ratio.values[c],
1321                         remapped.values[c]) != i->volume.values[c])
1322
1323                 i->real_ratio.values[c] = pa_sw_volume_divide(
1324                         i->volume.values[c],
1325                         remapped.values[c]);
1326
1327             i->soft_volume.values[c] = pa_sw_volume_multiply(
1328                     i->real_ratio.values[c],
1329                     i->volume_factor.values[c]);
1330         }
1331
1332         /* We don't copy the soft_volume to the thread_info data
1333          * here. That must be done by the caller */
1334     }
1335 }
1336
1337 /* Called from main thread */
1338 static void compute_real_volume(pa_sink *s) {
1339     pa_sink_input *i;
1340     uint32_t idx;
1341
1342     pa_sink_assert_ref(s);
1343     pa_assert_ctl_context();
1344     pa_assert(PA_SINK_IS_LINKED(s->state));
1345     pa_assert(s->flags & PA_SINK_FLAT_VOLUME);
1346
1347     /* This determines the maximum volume of all streams and sets
1348      * s->real_volume accordingly. */
1349
1350     if (pa_idxset_isempty(s->inputs)) {
1351         /* In the special case that we have no sink input we leave the
1352          * volume unmodified. */
1353         s->real_volume = s->reference_volume;
1354         return;
1355     }
1356
1357     pa_cvolume_mute(&s->real_volume, s->channel_map.channels);
1358
1359     /* First let's determine the new maximum volume of all inputs
1360      * connected to this sink */
1361     PA_IDXSET_FOREACH(i, s->inputs, idx) {
1362         pa_cvolume remapped;
1363
1364         remapped = i->volume;
1365         cvolume_remap_minimal_impact(&remapped, &s->real_volume, &i->channel_map, &s->channel_map);
1366         pa_cvolume_merge(&s->real_volume, &s->real_volume, &remapped);
1367     }
1368
1369     /* Then, let's update the real ratios/soft volumes of all inputs
1370      * connected to this sink */
1371     compute_real_ratios(s);
1372 }
1373
1374 /* Called from main thread */
1375 static void propagate_reference_volume(pa_sink *s) {
1376     pa_sink_input *i;
1377     uint32_t idx;
1378
1379     pa_sink_assert_ref(s);
1380     pa_assert_ctl_context();
1381     pa_assert(PA_SINK_IS_LINKED(s->state));
1382     pa_assert(s->flags & PA_SINK_FLAT_VOLUME);
1383
1384     /* This is called whenever the sink volume changes that is not
1385      * caused by a sink input volume change. We need to fix up the
1386      * sink input volumes accordingly */
1387
1388     PA_IDXSET_FOREACH(i, s->inputs, idx) {
1389         pa_cvolume old_volume, remapped;
1390
1391         old_volume = i->volume;
1392
1393         /* This basically calculates:
1394          *
1395          * i->volume := s->reference_volume * i->reference_ratio  */
1396
1397         remapped = s->reference_volume;
1398         pa_cvolume_remap(&remapped, &s->channel_map, &i->channel_map);
1399         pa_sw_cvolume_multiply(&i->volume, &remapped, &i->reference_ratio);
1400
1401         /* The volume changed, let's tell people so */
1402         if (!pa_cvolume_equal(&old_volume, &i->volume)) {
1403
1404             if (i->volume_changed)
1405                 i->volume_changed(i);
1406
1407             pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1408         }
1409     }
1410 }
1411
1412 /* Called from main thread */
1413 void pa_sink_set_volume(
1414         pa_sink *s,
1415         const pa_cvolume *volume,
1416         pa_bool_t send_msg,
1417         pa_bool_t save) {
1418
1419     pa_cvolume old_reference_volume;
1420     pa_bool_t reference_changed;
1421
1422     pa_sink_assert_ref(s);
1423     pa_assert_ctl_context();
1424     pa_assert(PA_SINK_IS_LINKED(s->state));
1425     pa_assert(!volume || pa_cvolume_valid(volume));
1426     pa_assert(volume || (s->flags & PA_SINK_FLAT_VOLUME));
1427     pa_assert(!volume || volume->channels == 1 || pa_cvolume_compatible(volume, &s->sample_spec));
1428
1429     /* make sure we don't change the volume when a PASSTHROUGH input is connected */
1430     if (s->flags & PA_SINK_PASSTHROUGH) {
1431         pa_sink_input *alt_i;
1432         uint32_t idx;
1433
1434         /* one and only one PASSTHROUGH input can possibly be connected */
1435         if (pa_idxset_size(s->inputs) == 1) {
1436
1437             alt_i = pa_idxset_first(s->inputs, &idx);
1438
1439             if (alt_i->flags & PA_SINK_INPUT_PASSTHROUGH) {
1440                 /* FIXME: Need to notify client that volume control is disabled */
1441                 pa_log_warn("Cannot change volume, Sink is connected to PASSTHROUGH input");
1442                 return;
1443             }
1444         }
1445     }
1446
1447     /* As a special exception we accept mono volumes on all sinks --
1448      * even on those with more complex channel maps */
1449
1450     /* If volume is NULL we synchronize the sink's real and reference
1451      * volumes with the stream volumes. If it is not NULL we update
1452      * the reference_volume with it. */
1453
1454     old_reference_volume = s->reference_volume;
1455
1456     if (volume) {
1457
1458         if (pa_cvolume_compatible(volume, &s->sample_spec))
1459             s->reference_volume = *volume;
1460         else
1461             pa_cvolume_scale(&s->reference_volume, pa_cvolume_max(volume));
1462
1463         if (s->flags & PA_SINK_FLAT_VOLUME) {
1464             /* OK, propagate this volume change back to the inputs */
1465             propagate_reference_volume(s);
1466
1467             /* And now recalculate the real volume */
1468             compute_real_volume(s);
1469         } else
1470             s->real_volume = s->reference_volume;
1471
1472     } else {
1473         pa_assert(s->flags & PA_SINK_FLAT_VOLUME);
1474
1475         /* Ok, let's determine the new real volume */
1476         compute_real_volume(s);
1477
1478         /* Let's 'push' the reference volume if necessary */
1479         pa_cvolume_merge(&s->reference_volume, &s->reference_volume, &s->real_volume);
1480
1481         /* We need to fix the reference ratios of all streams now that
1482          * we changed the reference volume */
1483         compute_reference_ratios(s);
1484     }
1485
1486     reference_changed = !pa_cvolume_equal(&old_reference_volume, &s->reference_volume);
1487     s->save_volume = (!reference_changed && s->save_volume) || save;
1488
1489     if (s->set_volume) {
1490         /* If we have a function set_volume(), then we do not apply a
1491          * soft volume by default. However, set_volume() is free to
1492          * apply one to s->soft_volume */
1493
1494         pa_cvolume_reset(&s->soft_volume, s->sample_spec.channels);
1495         if (!(s->flags & PA_SINK_SYNC_VOLUME))
1496             s->set_volume(s);
1497         else
1498             send_msg = TRUE;
1499
1500     } else
1501         /* If we have no function set_volume(), then the soft volume
1502          * becomes the virtual volume */
1503         s->soft_volume = s->real_volume;
1504
1505     /* This tells the sink that soft and/or virtual volume changed */
1506     if (send_msg)
1507         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_VOLUME_SYNCED, NULL, 0, NULL) == 0);
1508
1509     if (reference_changed)
1510         pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
1511 }
1512
1513 /* Called from the io thread if sync volume is used, otherwise from the main thread.
1514  * Only to be called by sink implementor */
1515 void pa_sink_set_soft_volume(pa_sink *s, const pa_cvolume *volume) {
1516     pa_sink_assert_ref(s);
1517     if (s->flags & PA_SINK_SYNC_VOLUME)
1518         pa_sink_assert_io_context(s);
1519     else
1520         pa_assert_ctl_context();
1521
1522     if (!volume)
1523         pa_cvolume_reset(&s->soft_volume, s->sample_spec.channels);
1524     else
1525         s->soft_volume = *volume;
1526
1527     if (PA_SINK_IS_LINKED(s->state) && !(s->flags & PA_SINK_SYNC_VOLUME))
1528         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_VOLUME, NULL, 0, NULL) == 0);
1529     else
1530         s->thread_info.soft_volume = s->soft_volume;
1531 }
1532
1533 static void propagate_real_volume(pa_sink *s, const pa_cvolume *old_real_volume) {
1534     pa_sink_input *i;
1535     uint32_t idx;
1536     pa_cvolume old_reference_volume;
1537
1538     pa_sink_assert_ref(s);
1539     pa_assert_ctl_context();
1540     pa_assert(PA_SINK_IS_LINKED(s->state));
1541
1542     /* This is called when the hardware's real volume changes due to
1543      * some external event. We copy the real volume into our
1544      * reference volume and then rebuild the stream volumes based on
1545      * i->real_ratio which should stay fixed. */
1546
1547     if (old_real_volume && pa_cvolume_equal(old_real_volume, &s->real_volume))
1548         return;
1549
1550     old_reference_volume = s->reference_volume;
1551
1552     /* 1. Make the real volume the reference volume */
1553     s->reference_volume = s->real_volume;
1554
1555     if (s->flags & PA_SINK_FLAT_VOLUME) {
1556
1557         PA_IDXSET_FOREACH(i, s->inputs, idx) {
1558             pa_cvolume old_volume, remapped;
1559
1560             old_volume = i->volume;
1561
1562             /* 2. Since the sink's reference and real volumes are equal
1563              * now our ratios should be too. */
1564             i->reference_ratio = i->real_ratio;
1565
1566             /* 3. Recalculate the new stream reference volume based on the
1567              * reference ratio and the sink's reference volume.
1568              *
1569              * This basically calculates:
1570              *
1571              * i->volume = s->reference_volume * i->reference_ratio
1572              *
1573              * This is identical to propagate_reference_volume() */
1574             remapped = s->reference_volume;
1575             pa_cvolume_remap(&remapped, &s->channel_map, &i->channel_map);
1576             pa_sw_cvolume_multiply(&i->volume, &remapped, &i->reference_ratio);
1577
1578             /* Notify if something changed */
1579             if (!pa_cvolume_equal(&old_volume, &i->volume)) {
1580
1581                 if (i->volume_changed)
1582                     i->volume_changed(i);
1583
1584                 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1585             }
1586         }
1587     }
1588
1589     /* Something got changed in the hardware. It probably makes sense
1590      * to save changed hw settings given that hw volume changes not
1591      * triggered by PA are almost certainly done by the user. */
1592     s->save_volume = TRUE;
1593
1594     if (!pa_cvolume_equal(&old_reference_volume, &s->reference_volume))
1595         pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
1596 }
1597
1598 /* Called from io thread */
1599 void pa_sink_update_volume_and_mute(pa_sink *s) {
1600     pa_assert(s);
1601     pa_sink_assert_io_context(s);
1602
1603     pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_UPDATE_VOLUME_AND_MUTE, NULL, 0, NULL, NULL);
1604 }
1605
1606 /* Called from main thread */
1607 const pa_cvolume *pa_sink_get_volume(pa_sink *s, pa_bool_t force_refresh) {
1608     pa_sink_assert_ref(s);
1609     pa_assert_ctl_context();
1610     pa_assert(PA_SINK_IS_LINKED(s->state));
1611
1612     if (s->refresh_volume || force_refresh) {
1613         struct pa_cvolume old_real_volume;
1614
1615         old_real_volume = s->real_volume;
1616
1617         if (!(s->flags & PA_SINK_SYNC_VOLUME) && s->get_volume)
1618             s->get_volume(s);
1619
1620         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_VOLUME, NULL, 0, NULL) == 0);
1621
1622         propagate_real_volume(s, &old_real_volume);
1623     }
1624
1625     return &s->reference_volume;
1626 }
1627
1628 /* Called from main thread */
1629 void pa_sink_volume_changed(pa_sink *s, const pa_cvolume *new_real_volume) {
1630     pa_cvolume old_real_volume;
1631
1632     pa_sink_assert_ref(s);
1633     pa_assert_ctl_context();
1634     pa_assert(PA_SINK_IS_LINKED(s->state));
1635
1636     /* The sink implementor may call this if the volume changed to make sure everyone is notified */
1637
1638     old_real_volume = s->real_volume;
1639     s->real_volume = *new_real_volume;
1640
1641     propagate_real_volume(s, &old_real_volume);
1642 }
1643
1644 /* Called from main thread */
1645 void pa_sink_set_mute(pa_sink *s, pa_bool_t mute, pa_bool_t save) {
1646     pa_bool_t old_muted;
1647
1648     pa_sink_assert_ref(s);
1649     pa_assert_ctl_context();
1650     pa_assert(PA_SINK_IS_LINKED(s->state));
1651
1652     old_muted = s->muted;
1653     s->muted = mute;
1654     s->save_muted = (old_muted == s->muted && s->save_muted) || save;
1655
1656     if (!(s->flags & PA_SINK_SYNC_VOLUME) && s->set_mute)
1657         s->set_mute(s);
1658
1659     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_MUTE, NULL, 0, NULL) == 0);
1660
1661     if (old_muted != s->muted)
1662         pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
1663 }
1664
1665 /* Called from main thread */
1666 pa_bool_t pa_sink_get_mute(pa_sink *s, pa_bool_t force_refresh) {
1667
1668     pa_sink_assert_ref(s);
1669     pa_assert_ctl_context();
1670     pa_assert(PA_SINK_IS_LINKED(s->state));
1671
1672     if (s->refresh_muted || force_refresh) {
1673         pa_bool_t old_muted = s->muted;
1674
1675         if (!(s->flags & PA_SINK_SYNC_VOLUME) && s->get_mute)
1676             s->get_mute(s);
1677
1678         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_MUTE, NULL, 0, NULL) == 0);
1679
1680         if (old_muted != s->muted) {
1681             s->save_muted = TRUE;
1682
1683             pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
1684
1685             /* Make sure the soft mute status stays in sync */
1686             pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_MUTE, NULL, 0, NULL) == 0);
1687         }
1688     }
1689
1690     return s->muted;
1691 }
1692
1693 /* Called from main thread */
1694 void pa_sink_mute_changed(pa_sink *s, pa_bool_t new_muted) {
1695     pa_sink_assert_ref(s);
1696     pa_assert_ctl_context();
1697     pa_assert(PA_SINK_IS_LINKED(s->state));
1698
1699     /* The sink implementor may call this if the volume changed to make sure everyone is notified */
1700
1701     if (s->muted == new_muted)
1702         return;
1703
1704     s->muted = new_muted;
1705     s->save_muted = TRUE;
1706
1707     pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
1708 }
1709
1710 /* Called from main thread */
1711 pa_bool_t pa_sink_update_proplist(pa_sink *s, pa_update_mode_t mode, pa_proplist *p) {
1712     pa_sink_assert_ref(s);
1713     pa_assert_ctl_context();
1714
1715     if (p)
1716         pa_proplist_update(s->proplist, mode, p);
1717
1718     if (PA_SINK_IS_LINKED(s->state)) {
1719         pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_PROPLIST_CHANGED], s);
1720         pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
1721     }
1722
1723     return TRUE;
1724 }
1725
1726 /* Called from main thread */
1727 /* FIXME -- this should be dropped and be merged into pa_sink_update_proplist() */
1728 void pa_sink_set_description(pa_sink *s, const char *description) {
1729     const char *old;
1730     pa_sink_assert_ref(s);
1731     pa_assert_ctl_context();
1732
1733     if (!description && !pa_proplist_contains(s->proplist, PA_PROP_DEVICE_DESCRIPTION))
1734         return;
1735
1736     old = pa_proplist_gets(s->proplist, PA_PROP_DEVICE_DESCRIPTION);
1737
1738     if (old && description && pa_streq(old, description))
1739         return;
1740
1741     if (description)
1742         pa_proplist_sets(s->proplist, PA_PROP_DEVICE_DESCRIPTION, description);
1743     else
1744         pa_proplist_unset(s->proplist, PA_PROP_DEVICE_DESCRIPTION);
1745
1746     if (s->monitor_source) {
1747         char *n;
1748
1749         n = pa_sprintf_malloc("Monitor Source of %s", description ? description : s->name);
1750         pa_source_set_description(s->monitor_source, n);
1751         pa_xfree(n);
1752     }
1753
1754     if (PA_SINK_IS_LINKED(s->state)) {
1755         pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
1756         pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_PROPLIST_CHANGED], s);
1757     }
1758 }
1759
1760 /* Called from main thread */
1761 unsigned pa_sink_linked_by(pa_sink *s) {
1762     unsigned ret;
1763
1764     pa_sink_assert_ref(s);
1765     pa_assert_ctl_context();
1766     pa_assert(PA_SINK_IS_LINKED(s->state));
1767
1768     ret = pa_idxset_size(s->inputs);
1769
1770     /* We add in the number of streams connected to us here. Please
1771      * note the asymmmetry to pa_sink_used_by()! */
1772
1773     if (s->monitor_source)
1774         ret += pa_source_linked_by(s->monitor_source);
1775
1776     return ret;
1777 }
1778
1779 /* Called from main thread */
1780 unsigned pa_sink_used_by(pa_sink *s) {
1781     unsigned ret;
1782
1783     pa_sink_assert_ref(s);
1784     pa_assert_ctl_context();
1785     pa_assert(PA_SINK_IS_LINKED(s->state));
1786
1787     ret = pa_idxset_size(s->inputs);
1788     pa_assert(ret >= s->n_corked);
1789
1790     /* Streams connected to our monitor source do not matter for
1791      * pa_sink_used_by()!.*/
1792
1793     return ret - s->n_corked;
1794 }
1795
1796 /* Called from main thread */
1797 unsigned pa_sink_check_suspend(pa_sink *s) {
1798     unsigned ret;
1799     pa_sink_input *i;
1800     uint32_t idx;
1801
1802     pa_sink_assert_ref(s);
1803     pa_assert_ctl_context();
1804
1805     if (!PA_SINK_IS_LINKED(s->state))
1806         return 0;
1807
1808     ret = 0;
1809
1810     PA_IDXSET_FOREACH(i, s->inputs, idx) {
1811         pa_sink_input_state_t st;
1812
1813         st = pa_sink_input_get_state(i);
1814
1815         /* We do not assert here. It is perfectly valid for a sink input to
1816          * be in the INIT state (i.e. created, marked done but not yet put)
1817          * and we should not care if it's unlinked as it won't contribute
1818          * towarards our busy status.
1819          */
1820         if (!PA_SINK_INPUT_IS_LINKED(st))
1821             continue;
1822
1823         if (st == PA_SINK_INPUT_CORKED)
1824             continue;
1825
1826         if (i->flags & PA_SINK_INPUT_DONT_INHIBIT_AUTO_SUSPEND)
1827             continue;
1828
1829         ret ++;
1830     }
1831
1832     if (s->monitor_source)
1833         ret += pa_source_check_suspend(s->monitor_source);
1834
1835     return ret;
1836 }
1837
1838 /* Called from the IO thread */
1839 static void sync_input_volumes_within_thread(pa_sink *s) {
1840     pa_sink_input *i;
1841     void *state = NULL;
1842
1843     pa_sink_assert_ref(s);
1844     pa_sink_assert_io_context(s);
1845
1846     PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state) {
1847         if (pa_atomic_load(&i->before_ramping_v))
1848             i->thread_info.future_soft_volume = i->soft_volume;
1849
1850         if (pa_cvolume_equal(&i->thread_info.soft_volume, &i->soft_volume))
1851             continue;
1852
1853         if (!pa_atomic_load(&i->before_ramping_v))
1854             i->thread_info.soft_volume = i->soft_volume;
1855         pa_sink_input_request_rewind(i, 0, TRUE, FALSE, FALSE);
1856     }
1857 }
1858
1859 /* Called from IO thread, except when it is not */
1860 int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {
1861     pa_sink *s = PA_SINK(o);
1862     pa_sink_assert_ref(s);
1863
1864     switch ((pa_sink_message_t) code) {
1865
1866         case PA_SINK_MESSAGE_ADD_INPUT: {
1867             pa_sink_input *i = PA_SINK_INPUT(userdata);
1868
1869             /* If you change anything here, make sure to change the
1870              * sink input handling a few lines down at
1871              * PA_SINK_MESSAGE_FINISH_MOVE, too. */
1872
1873             pa_hashmap_put(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index), pa_sink_input_ref(i));
1874
1875             /* Since the caller sleeps in pa_sink_input_put(), we can
1876              * safely access data outside of thread_info even though
1877              * it is mutable */
1878
1879             if ((i->thread_info.sync_prev = i->sync_prev)) {
1880                 pa_assert(i->sink == i->thread_info.sync_prev->sink);
1881                 pa_assert(i->sync_prev->sync_next == i);
1882                 i->thread_info.sync_prev->thread_info.sync_next = i;
1883             }
1884
1885             if ((i->thread_info.sync_next = i->sync_next)) {
1886                 pa_assert(i->sink == i->thread_info.sync_next->sink);
1887                 pa_assert(i->sync_next->sync_prev == i);
1888                 i->thread_info.sync_next->thread_info.sync_prev = i;
1889             }
1890
1891             pa_assert(!i->thread_info.attached);
1892             i->thread_info.attached = TRUE;
1893
1894             if (i->attach)
1895                 i->attach(i);
1896
1897             pa_sink_input_set_state_within_thread(i, i->state);
1898
1899             /* The requested latency of the sink input needs to be
1900              * fixed up and then configured on the sink */
1901
1902             if (i->thread_info.requested_sink_latency != (pa_usec_t) -1)
1903                 pa_sink_input_set_requested_latency_within_thread(i, i->thread_info.requested_sink_latency);
1904
1905             pa_sink_input_update_max_rewind(i, s->thread_info.max_rewind);
1906             pa_sink_input_update_max_request(i, s->thread_info.max_request);
1907
1908             /* We don't rewind here automatically. This is left to the
1909              * sink input implementor because some sink inputs need a
1910              * slow start, i.e. need some time to buffer client
1911              * samples before beginning streaming. */
1912
1913             /* In flat volume mode we need to update the volume as
1914              * well */
1915             return o->process_msg(o, PA_SINK_MESSAGE_SET_VOLUME_SYNCED, NULL, 0, NULL);
1916         }
1917
1918         case PA_SINK_MESSAGE_REMOVE_INPUT: {
1919             pa_sink_input *i = PA_SINK_INPUT(userdata);
1920
1921             /* If you change anything here, make sure to change the
1922              * sink input handling a few lines down at
1923              * PA_SINK_MESSAGE_PREPAPRE_MOVE, too. */
1924
1925             if (i->detach)
1926                 i->detach(i);
1927
1928             pa_sink_input_set_state_within_thread(i, i->state);
1929
1930             pa_assert(i->thread_info.attached);
1931             i->thread_info.attached = FALSE;
1932
1933             /* Since the caller sleeps in pa_sink_input_unlink(),
1934              * we can safely access data outside of thread_info even
1935              * though it is mutable */
1936
1937             pa_assert(!i->sync_prev);
1938             pa_assert(!i->sync_next);
1939
1940             if (i->thread_info.sync_prev) {
1941                 i->thread_info.sync_prev->thread_info.sync_next = i->thread_info.sync_prev->sync_next;
1942                 i->thread_info.sync_prev = NULL;
1943             }
1944
1945             if (i->thread_info.sync_next) {
1946                 i->thread_info.sync_next->thread_info.sync_prev = i->thread_info.sync_next->sync_prev;
1947                 i->thread_info.sync_next = NULL;
1948             }
1949
1950             if (pa_hashmap_remove(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index)))
1951                 pa_sink_input_unref(i);
1952
1953             pa_sink_invalidate_requested_latency(s, TRUE);
1954             pa_sink_request_rewind(s, (size_t) -1);
1955
1956             /* In flat volume mode we need to update the volume as
1957              * well */
1958             return o->process_msg(o, PA_SINK_MESSAGE_SET_VOLUME_SYNCED, NULL, 0, NULL);
1959         }
1960
1961         case PA_SINK_MESSAGE_START_MOVE: {
1962             pa_sink_input *i = PA_SINK_INPUT(userdata);
1963
1964             /* We don't support moving synchronized streams. */
1965             pa_assert(!i->sync_prev);
1966             pa_assert(!i->sync_next);
1967             pa_assert(!i->thread_info.sync_next);
1968             pa_assert(!i->thread_info.sync_prev);
1969
1970             if (i->thread_info.state != PA_SINK_INPUT_CORKED) {
1971                 pa_usec_t usec = 0;
1972                 size_t sink_nbytes, total_nbytes;
1973
1974                 /* Get the latency of the sink */
1975                 usec = pa_sink_get_latency_within_thread(s);
1976                 sink_nbytes = pa_usec_to_bytes(usec, &s->sample_spec);
1977                 total_nbytes = sink_nbytes + pa_memblockq_get_length(i->thread_info.render_memblockq);
1978
1979                 if (total_nbytes > 0) {
1980                     i->thread_info.rewrite_nbytes = i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, total_nbytes) : total_nbytes;
1981                     i->thread_info.rewrite_flush = TRUE;
1982                     pa_sink_input_process_rewind(i, sink_nbytes);
1983                 }
1984             }
1985
1986             if (i->detach)
1987                 i->detach(i);
1988
1989             pa_assert(i->thread_info.attached);
1990             i->thread_info.attached = FALSE;
1991
1992             /* Let's remove the sink input ...*/
1993             if (pa_hashmap_remove(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index)))
1994                 pa_sink_input_unref(i);
1995
1996             pa_sink_invalidate_requested_latency(s, TRUE);
1997
1998             pa_log_debug("Requesting rewind due to started move");
1999             pa_sink_request_rewind(s, (size_t) -1);
2000
2001             /* In flat volume mode we need to update the volume as
2002              * well */
2003             return o->process_msg(o, PA_SINK_MESSAGE_SET_VOLUME_SYNCED, NULL, 0, NULL);
2004         }
2005
2006         case PA_SINK_MESSAGE_FINISH_MOVE: {
2007             pa_sink_input *i = PA_SINK_INPUT(userdata);
2008
2009             /* We don't support moving synchronized streams. */
2010             pa_assert(!i->sync_prev);
2011             pa_assert(!i->sync_next);
2012             pa_assert(!i->thread_info.sync_next);
2013             pa_assert(!i->thread_info.sync_prev);
2014
2015             pa_hashmap_put(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index), pa_sink_input_ref(i));
2016
2017             pa_assert(!i->thread_info.attached);
2018             i->thread_info.attached = TRUE;
2019
2020             if (i->attach)
2021                 i->attach(i);
2022
2023             if (i->thread_info.requested_sink_latency != (pa_usec_t) -1)
2024                 pa_sink_input_set_requested_latency_within_thread(i, i->thread_info.requested_sink_latency);
2025
2026             pa_sink_input_update_max_rewind(i, s->thread_info.max_rewind);
2027             pa_sink_input_update_max_request(i, s->thread_info.max_request);
2028
2029             if (i->thread_info.state != PA_SINK_INPUT_CORKED) {
2030                 pa_usec_t usec = 0;
2031                 size_t nbytes;
2032
2033                 /* Get the latency of the sink */
2034                 usec = pa_sink_get_latency_within_thread(s);
2035                 nbytes = pa_usec_to_bytes(usec, &s->sample_spec);
2036
2037                 if (nbytes > 0)
2038                     pa_sink_input_drop(i, nbytes);
2039
2040                 pa_log_debug("Requesting rewind due to finished move");
2041                 pa_sink_request_rewind(s, nbytes);
2042             }
2043
2044             /* In flat volume mode we need to update the volume as
2045              * well */
2046             return o->process_msg(o, PA_SINK_MESSAGE_SET_VOLUME_SYNCED, NULL, 0, NULL);
2047         }
2048
2049         case PA_SINK_MESSAGE_SET_VOLUME_SYNCED:
2050
2051             if (s->flags & PA_SINK_SYNC_VOLUME) {
2052                 s->set_volume(s);
2053                 pa_sink_volume_change_push(s);
2054             }
2055             /* Fall through ... */
2056
2057         case PA_SINK_MESSAGE_SET_VOLUME:
2058
2059             if (!pa_cvolume_equal(&s->thread_info.soft_volume, &s->soft_volume)) {
2060                 s->thread_info.soft_volume = s->soft_volume;
2061                 pa_sink_request_rewind(s, (size_t) -1);
2062             }
2063
2064             if (!(s->flags & PA_SINK_FLAT_VOLUME))
2065                 return 0;
2066
2067             /* Fall through ... */
2068
2069         case PA_SINK_MESSAGE_SYNC_VOLUMES:
2070             sync_input_volumes_within_thread(s);
2071             return 0;
2072
2073         case PA_SINK_MESSAGE_GET_VOLUME:
2074
2075             if ((s->flags & PA_SINK_SYNC_VOLUME) && s->get_volume) {
2076                 s->get_volume(s);
2077                 pa_sink_volume_change_flush(s);
2078                 pa_sw_cvolume_divide(&s->thread_info.current_hw_volume, &s->real_volume, &s->soft_volume);
2079             }
2080
2081             /* In case sink implementor reset SW volume. */
2082             if (!pa_cvolume_equal(&s->thread_info.soft_volume, &s->soft_volume)) {
2083                 s->thread_info.soft_volume = s->soft_volume;
2084                 pa_sink_request_rewind(s, (size_t) -1);
2085             }
2086
2087             return 0;
2088
2089         case PA_SINK_MESSAGE_SET_MUTE:
2090
2091             if (s->thread_info.soft_muted != s->muted) {
2092                 s->thread_info.soft_muted = s->muted;
2093                 pa_sink_request_rewind(s, (size_t) -1);
2094             }
2095
2096             if (s->flags & PA_SINK_SYNC_VOLUME && s->set_mute)
2097                 s->set_mute(s);
2098
2099             return 0;
2100
2101         case PA_SINK_MESSAGE_GET_MUTE:
2102
2103             if (s->flags & PA_SINK_SYNC_VOLUME && s->get_mute)
2104                 s->get_mute(s);
2105
2106             return 0;
2107
2108         case PA_SINK_MESSAGE_SET_STATE: {
2109
2110             pa_bool_t suspend_change =
2111                 (s->thread_info.state == PA_SINK_SUSPENDED && PA_SINK_IS_OPENED(PA_PTR_TO_UINT(userdata))) ||
2112                 (PA_SINK_IS_OPENED(s->thread_info.state) && PA_PTR_TO_UINT(userdata) == PA_SINK_SUSPENDED);
2113
2114             s->thread_info.state = PA_PTR_TO_UINT(userdata);
2115
2116             if (s->thread_info.state == PA_SINK_SUSPENDED) {
2117                 s->thread_info.rewind_nbytes = 0;
2118                 s->thread_info.rewind_requested = FALSE;
2119             }
2120
2121             if (suspend_change) {
2122                 pa_sink_input *i;
2123                 void *state = NULL;
2124
2125                 while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)))
2126                     if (i->suspend_within_thread)
2127                         i->suspend_within_thread(i, s->thread_info.state == PA_SINK_SUSPENDED);
2128             }
2129
2130             return 0;
2131         }
2132
2133         case PA_SINK_MESSAGE_DETACH:
2134
2135             /* Detach all streams */
2136             pa_sink_detach_within_thread(s);
2137             return 0;
2138
2139         case PA_SINK_MESSAGE_ATTACH:
2140
2141             /* Reattach all streams */
2142             pa_sink_attach_within_thread(s);
2143             return 0;
2144
2145         case PA_SINK_MESSAGE_GET_REQUESTED_LATENCY: {
2146
2147             pa_usec_t *usec = userdata;
2148             *usec = pa_sink_get_requested_latency_within_thread(s);
2149
2150             /* Yes, that's right, the IO thread will see -1 when no
2151              * explicit requested latency is configured, the main
2152              * thread will see max_latency */
2153             if (*usec == (pa_usec_t) -1)
2154                 *usec = s->thread_info.max_latency;
2155
2156             return 0;
2157         }
2158
2159         case PA_SINK_MESSAGE_SET_LATENCY_RANGE: {
2160             pa_usec_t *r = userdata;
2161
2162             pa_sink_set_latency_range_within_thread(s, r[0], r[1]);
2163
2164             return 0;
2165         }
2166
2167         case PA_SINK_MESSAGE_GET_LATENCY_RANGE: {
2168             pa_usec_t *r = userdata;
2169
2170             r[0] = s->thread_info.min_latency;
2171             r[1] = s->thread_info.max_latency;
2172
2173             return 0;
2174         }
2175
2176         case PA_SINK_MESSAGE_GET_FIXED_LATENCY:
2177
2178             *((pa_usec_t*) userdata) = s->thread_info.fixed_latency;
2179             return 0;
2180
2181         case PA_SINK_MESSAGE_SET_FIXED_LATENCY:
2182
2183             pa_sink_set_fixed_latency_within_thread(s, (pa_usec_t) offset);
2184             return 0;
2185
2186         case PA_SINK_MESSAGE_GET_MAX_REWIND:
2187
2188             *((size_t*) userdata) = s->thread_info.max_rewind;
2189             return 0;
2190
2191         case PA_SINK_MESSAGE_GET_MAX_REQUEST:
2192
2193             *((size_t*) userdata) = s->thread_info.max_request;
2194             return 0;
2195
2196         case PA_SINK_MESSAGE_SET_MAX_REWIND:
2197
2198             pa_sink_set_max_rewind_within_thread(s, (size_t) offset);
2199             return 0;
2200
2201         case PA_SINK_MESSAGE_SET_MAX_REQUEST:
2202
2203             pa_sink_set_max_request_within_thread(s, (size_t) offset);
2204             return 0;
2205
2206         case PA_SINK_MESSAGE_SET_PORT:
2207
2208             pa_assert(userdata);
2209             if (s->set_port) {
2210                 struct sink_message_set_port *msg_data = userdata;
2211                 msg_data->ret = s->set_port(s, msg_data->port);
2212             }
2213             return 0;
2214
2215         case PA_SINK_MESSAGE_UPDATE_VOLUME_AND_MUTE:
2216             /* This message is sent from IO-thread and handled in main thread. */
2217             pa_assert_ctl_context();
2218
2219             pa_sink_get_volume(s, TRUE);
2220             pa_sink_get_mute(s, TRUE);
2221             return 0;
2222
2223         case PA_SINK_MESSAGE_GET_LATENCY:
2224         case PA_SINK_MESSAGE_MAX:
2225             ;
2226     }
2227
2228     return -1;
2229 }
2230
2231 /* Called from main thread */
2232 int pa_sink_suspend_all(pa_core *c, pa_bool_t suspend, pa_suspend_cause_t cause) {
2233     pa_sink *sink;
2234     uint32_t idx;
2235     int ret = 0;
2236
2237     pa_core_assert_ref(c);
2238     pa_assert_ctl_context();
2239     pa_assert(cause != 0);
2240
2241     PA_IDXSET_FOREACH(sink, c->sinks, idx) {
2242         int r;
2243
2244         if ((r = pa_sink_suspend(sink, suspend, cause)) < 0)
2245             ret = r;
2246     }
2247
2248     return ret;
2249 }
2250
2251 /* Called from main thread */
2252 void pa_sink_detach(pa_sink *s) {
2253     pa_sink_assert_ref(s);
2254     pa_assert_ctl_context();
2255     pa_assert(PA_SINK_IS_LINKED(s->state));
2256
2257     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_DETACH, NULL, 0, NULL) == 0);
2258 }
2259
2260 /* Called from main thread */
2261 void pa_sink_attach(pa_sink *s) {
2262     pa_sink_assert_ref(s);
2263     pa_assert_ctl_context();
2264     pa_assert(PA_SINK_IS_LINKED(s->state));
2265
2266     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_ATTACH, NULL, 0, NULL) == 0);
2267 }
2268
2269 /* Called from IO thread */
2270 void pa_sink_detach_within_thread(pa_sink *s) {
2271     pa_sink_input *i;
2272     void *state = NULL;
2273
2274     pa_sink_assert_ref(s);
2275     pa_sink_assert_io_context(s);
2276     pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
2277
2278     PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state)
2279         if (i->detach)
2280             i->detach(i);
2281
2282     if (s->monitor_source)
2283         pa_source_detach_within_thread(s->monitor_source);
2284 }
2285
2286 /* Called from IO thread */
2287 void pa_sink_attach_within_thread(pa_sink *s) {
2288     pa_sink_input *i;
2289     void *state = NULL;
2290
2291     pa_sink_assert_ref(s);
2292     pa_sink_assert_io_context(s);
2293     pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
2294
2295     PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state)
2296         if (i->attach)
2297             i->attach(i);
2298
2299     if (s->monitor_source)
2300         pa_source_attach_within_thread(s->monitor_source);
2301 }
2302
2303 /* Called from IO thread */
2304 void pa_sink_request_rewind(pa_sink*s, size_t nbytes) {
2305     pa_sink_assert_ref(s);
2306     pa_sink_assert_io_context(s);
2307     pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
2308
2309     if (s->thread_info.state == PA_SINK_SUSPENDED)
2310         return;
2311
2312     if (nbytes == (size_t) -1)
2313         nbytes = s->thread_info.max_rewind;
2314
2315     nbytes = PA_MIN(nbytes, s->thread_info.max_rewind);
2316
2317     if (s->thread_info.rewind_requested &&
2318         nbytes <= s->thread_info.rewind_nbytes)
2319         return;
2320
2321     s->thread_info.rewind_nbytes = nbytes;
2322     s->thread_info.rewind_requested = TRUE;
2323
2324     if (s->request_rewind)
2325         s->request_rewind(s);
2326 }
2327
2328 /* Called from IO thread */
2329 pa_usec_t pa_sink_get_requested_latency_within_thread(pa_sink *s) {
2330     pa_usec_t result = (pa_usec_t) -1;
2331     pa_sink_input *i;
2332     void *state = NULL;
2333     pa_usec_t monitor_latency;
2334
2335     pa_sink_assert_ref(s);
2336     pa_sink_assert_io_context(s);
2337
2338     if (!(s->flags & PA_SINK_DYNAMIC_LATENCY))
2339         return PA_CLAMP(s->thread_info.fixed_latency, s->thread_info.min_latency, s->thread_info.max_latency);
2340
2341     if (s->thread_info.requested_latency_valid)
2342         return s->thread_info.requested_latency;
2343
2344     PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state)
2345         if (i->thread_info.requested_sink_latency != (pa_usec_t) -1 &&
2346             (result == (pa_usec_t) -1 || result > i->thread_info.requested_sink_latency))
2347             result = i->thread_info.requested_sink_latency;
2348
2349     monitor_latency = pa_source_get_requested_latency_within_thread(s->monitor_source);
2350
2351     if (monitor_latency != (pa_usec_t) -1 &&
2352         (result == (pa_usec_t) -1 || result > monitor_latency))
2353         result = monitor_latency;
2354
2355     if (result != (pa_usec_t) -1)
2356         result = PA_CLAMP(result, s->thread_info.min_latency, s->thread_info.max_latency);
2357
2358     if (PA_SINK_IS_LINKED(s->thread_info.state)) {
2359         /* Only cache if properly initialized */
2360         s->thread_info.requested_latency = result;
2361         s->thread_info.requested_latency_valid = TRUE;
2362     }
2363
2364     return result;
2365 }
2366
2367 /* Called from main thread */
2368 pa_usec_t pa_sink_get_requested_latency(pa_sink *s) {
2369     pa_usec_t usec = 0;
2370
2371     pa_sink_assert_ref(s);
2372     pa_assert_ctl_context();
2373     pa_assert(PA_SINK_IS_LINKED(s->state));
2374
2375     if (s->state == PA_SINK_SUSPENDED)
2376         return 0;
2377
2378     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);
2379     return usec;
2380 }
2381
2382 /* Called from IO as well as the main thread -- the latter only before the IO thread started up */
2383 void pa_sink_set_max_rewind_within_thread(pa_sink *s, size_t max_rewind) {
2384     pa_sink_input *i;
2385     void *state = NULL;
2386
2387     pa_sink_assert_ref(s);
2388     pa_sink_assert_io_context(s);
2389
2390     if (max_rewind == s->thread_info.max_rewind)
2391         return;
2392
2393     s->thread_info.max_rewind = max_rewind;
2394
2395     if (PA_SINK_IS_LINKED(s->thread_info.state))
2396         PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state)
2397             pa_sink_input_update_max_rewind(i, s->thread_info.max_rewind);
2398
2399     if (s->monitor_source)
2400         pa_source_set_max_rewind_within_thread(s->monitor_source, s->thread_info.max_rewind);
2401 }
2402
2403 /* Called from main thread */
2404 void pa_sink_set_max_rewind(pa_sink *s, size_t max_rewind) {
2405     pa_sink_assert_ref(s);
2406     pa_assert_ctl_context();
2407
2408     if (PA_SINK_IS_LINKED(s->state))
2409         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_MAX_REWIND, NULL, max_rewind, NULL) == 0);
2410     else
2411         pa_sink_set_max_rewind_within_thread(s, max_rewind);
2412 }
2413
2414 /* Called from IO as well as the main thread -- the latter only before the IO thread started up */
2415 void pa_sink_set_max_request_within_thread(pa_sink *s, size_t max_request) {
2416     void *state = NULL;
2417
2418     pa_sink_assert_ref(s);
2419     pa_sink_assert_io_context(s);
2420
2421     if (max_request == s->thread_info.max_request)
2422         return;
2423
2424     s->thread_info.max_request = max_request;
2425
2426     if (PA_SINK_IS_LINKED(s->thread_info.state)) {
2427         pa_sink_input *i;
2428
2429         PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state)
2430             pa_sink_input_update_max_request(i, s->thread_info.max_request);
2431     }
2432 }
2433
2434 /* Called from main thread */
2435 void pa_sink_set_max_request(pa_sink *s, size_t max_request) {
2436     pa_sink_assert_ref(s);
2437     pa_assert_ctl_context();
2438
2439     if (PA_SINK_IS_LINKED(s->state))
2440         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_MAX_REQUEST, NULL, max_request, NULL) == 0);
2441     else
2442         pa_sink_set_max_request_within_thread(s, max_request);
2443 }
2444
2445 /* Called from IO thread */
2446 void pa_sink_invalidate_requested_latency(pa_sink *s, pa_bool_t dynamic) {
2447     pa_sink_input *i;
2448     void *state = NULL;
2449
2450     pa_sink_assert_ref(s);
2451     pa_sink_assert_io_context(s);
2452
2453     if ((s->flags & PA_SINK_DYNAMIC_LATENCY))
2454         s->thread_info.requested_latency_valid = FALSE;
2455     else if (dynamic)
2456         return;
2457
2458     if (PA_SINK_IS_LINKED(s->thread_info.state)) {
2459
2460         if (s->update_requested_latency)
2461             s->update_requested_latency(s);
2462
2463         PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state)
2464             if (i->update_sink_requested_latency)
2465                 i->update_sink_requested_latency(i);
2466     }
2467 }
2468
2469 /* Called from main thread */
2470 void pa_sink_set_latency_range(pa_sink *s, pa_usec_t min_latency, pa_usec_t max_latency) {
2471     pa_sink_assert_ref(s);
2472     pa_assert_ctl_context();
2473
2474     /* min_latency == 0:           no limit
2475      * min_latency anything else:  specified limit
2476      *
2477      * Similar for max_latency */
2478
2479     if (min_latency < ABSOLUTE_MIN_LATENCY)
2480         min_latency = ABSOLUTE_MIN_LATENCY;
2481
2482     if (max_latency <= 0 ||
2483         max_latency > ABSOLUTE_MAX_LATENCY)
2484         max_latency = ABSOLUTE_MAX_LATENCY;
2485
2486     pa_assert(min_latency <= max_latency);
2487
2488     /* Hmm, let's see if someone forgot to set PA_SINK_DYNAMIC_LATENCY here... */
2489     pa_assert((min_latency == ABSOLUTE_MIN_LATENCY &&
2490                max_latency == ABSOLUTE_MAX_LATENCY) ||
2491               (s->flags & PA_SINK_DYNAMIC_LATENCY));
2492
2493     if (PA_SINK_IS_LINKED(s->state)) {
2494         pa_usec_t r[2];
2495
2496         r[0] = min_latency;
2497         r[1] = max_latency;
2498
2499         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_LATENCY_RANGE, r, 0, NULL) == 0);
2500     } else
2501         pa_sink_set_latency_range_within_thread(s, min_latency, max_latency);
2502 }
2503
2504 /* Called from main thread */
2505 void pa_sink_get_latency_range(pa_sink *s, pa_usec_t *min_latency, pa_usec_t *max_latency) {
2506    pa_sink_assert_ref(s);
2507    pa_assert_ctl_context();
2508    pa_assert(min_latency);
2509    pa_assert(max_latency);
2510
2511    if (PA_SINK_IS_LINKED(s->state)) {
2512        pa_usec_t r[2] = { 0, 0 };
2513
2514        pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_LATENCY_RANGE, r, 0, NULL) == 0);
2515
2516        *min_latency = r[0];
2517        *max_latency = r[1];
2518    } else {
2519        *min_latency = s->thread_info.min_latency;
2520        *max_latency = s->thread_info.max_latency;
2521    }
2522 }
2523
2524 /* Called from IO thread */
2525 void pa_sink_set_latency_range_within_thread(pa_sink *s, pa_usec_t min_latency, pa_usec_t max_latency) {
2526     pa_sink_assert_ref(s);
2527     pa_sink_assert_io_context(s);
2528
2529     pa_assert(min_latency >= ABSOLUTE_MIN_LATENCY);
2530     pa_assert(max_latency <= ABSOLUTE_MAX_LATENCY);
2531     pa_assert(min_latency <= max_latency);
2532
2533     /* Hmm, let's see if someone forgot to set PA_SINK_DYNAMIC_LATENCY here... */
2534     pa_assert((min_latency == ABSOLUTE_MIN_LATENCY &&
2535                max_latency == ABSOLUTE_MAX_LATENCY) ||
2536               (s->flags & PA_SINK_DYNAMIC_LATENCY));
2537
2538     if (s->thread_info.min_latency == min_latency &&
2539         s->thread_info.max_latency == max_latency)
2540         return;
2541
2542     s->thread_info.min_latency = min_latency;
2543     s->thread_info.max_latency = max_latency;
2544
2545     if (PA_SINK_IS_LINKED(s->thread_info.state)) {
2546         pa_sink_input *i;
2547         void *state = NULL;
2548
2549         PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state)
2550             if (i->update_sink_latency_range)
2551                 i->update_sink_latency_range(i);
2552     }
2553
2554     pa_sink_invalidate_requested_latency(s, FALSE);
2555
2556     pa_source_set_latency_range_within_thread(s->monitor_source, min_latency, max_latency);
2557 }
2558
2559 /* Called from main thread */
2560 void pa_sink_set_fixed_latency(pa_sink *s, pa_usec_t latency) {
2561     pa_sink_assert_ref(s);
2562     pa_assert_ctl_context();
2563
2564     if (s->flags & PA_SINK_DYNAMIC_LATENCY) {
2565         pa_assert(latency == 0);
2566         return;
2567     }
2568
2569     if (latency < ABSOLUTE_MIN_LATENCY)
2570         latency = ABSOLUTE_MIN_LATENCY;
2571
2572     if (latency > ABSOLUTE_MAX_LATENCY)
2573         latency = ABSOLUTE_MAX_LATENCY;
2574
2575     if (PA_SINK_IS_LINKED(s->state))
2576         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_FIXED_LATENCY, NULL, (int64_t) latency, NULL) == 0);
2577     else
2578         s->thread_info.fixed_latency = latency;
2579
2580     pa_source_set_fixed_latency(s->monitor_source, latency);
2581 }
2582
2583 /* Called from main thread */
2584 pa_usec_t pa_sink_get_fixed_latency(pa_sink *s) {
2585     pa_usec_t latency;
2586
2587     pa_sink_assert_ref(s);
2588     pa_assert_ctl_context();
2589
2590     if (s->flags & PA_SINK_DYNAMIC_LATENCY)
2591         return 0;
2592
2593     if (PA_SINK_IS_LINKED(s->state))
2594         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_FIXED_LATENCY, &latency, 0, NULL) == 0);
2595     else
2596         latency = s->thread_info.fixed_latency;
2597
2598     return latency;
2599 }
2600
2601 /* Called from IO thread */
2602 void pa_sink_set_fixed_latency_within_thread(pa_sink *s, pa_usec_t latency) {
2603     pa_sink_assert_ref(s);
2604     pa_sink_assert_io_context(s);
2605
2606     if (s->flags & PA_SINK_DYNAMIC_LATENCY) {
2607         pa_assert(latency == 0);
2608         return;
2609     }
2610
2611     pa_assert(latency >= ABSOLUTE_MIN_LATENCY);
2612     pa_assert(latency <= ABSOLUTE_MAX_LATENCY);
2613
2614     if (s->thread_info.fixed_latency == latency)
2615         return;
2616
2617     s->thread_info.fixed_latency = latency;
2618
2619     if (PA_SINK_IS_LINKED(s->thread_info.state)) {
2620         pa_sink_input *i;
2621         void *state = NULL;
2622
2623         PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state)
2624             if (i->update_sink_fixed_latency)
2625                 i->update_sink_fixed_latency(i);
2626     }
2627
2628     pa_sink_invalidate_requested_latency(s, FALSE);
2629
2630     pa_source_set_fixed_latency_within_thread(s->monitor_source, latency);
2631 }
2632
2633 /* Called from main context */
2634 size_t pa_sink_get_max_rewind(pa_sink *s) {
2635     size_t r;
2636     pa_sink_assert_ref(s);
2637     pa_assert_ctl_context();
2638
2639     if (!PA_SINK_IS_LINKED(s->state))
2640         return s->thread_info.max_rewind;
2641
2642     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_MAX_REWIND, &r, 0, NULL) == 0);
2643
2644     return r;
2645 }
2646
2647 /* Called from main context */
2648 size_t pa_sink_get_max_request(pa_sink *s) {
2649     size_t r;
2650     pa_sink_assert_ref(s);
2651     pa_assert_ctl_context();
2652
2653     if (!PA_SINK_IS_LINKED(s->state))
2654         return s->thread_info.max_request;
2655
2656     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_MAX_REQUEST, &r, 0, NULL) == 0);
2657
2658     return r;
2659 }
2660
2661 /* Called from main context */
2662 int pa_sink_set_port(pa_sink *s, const char *name, pa_bool_t save) {
2663     pa_device_port *port;
2664     int ret;
2665     pa_sink_assert_ref(s);
2666     pa_assert_ctl_context();
2667
2668     if (!s->set_port) {
2669         pa_log_debug("set_port() operation not implemented for sink %u \"%s\"", s->index, s->name);
2670         return -PA_ERR_NOTIMPLEMENTED;
2671     }
2672
2673     if (!s->ports)
2674         return -PA_ERR_NOENTITY;
2675
2676     if (!(port = pa_hashmap_get(s->ports, name)))
2677         return -PA_ERR_NOENTITY;
2678
2679     if (s->active_port == port) {
2680         s->save_port = s->save_port || save;
2681         return 0;
2682     }
2683
2684     if (s->flags & PA_SINK_SYNC_VOLUME) {
2685         struct sink_message_set_port msg = { .port = port, .ret = 0 };
2686         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_PORT, &msg, 0, NULL) == 0);
2687         ret = msg.ret;
2688     }
2689     else
2690         ret = s->set_port(s, port);
2691
2692     if (ret < 0)
2693         return -PA_ERR_NOENTITY;
2694
2695     pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
2696
2697     pa_log_info("Changed port of sink %u \"%s\" to %s", s->index, s->name, port->name);
2698
2699     s->active_port = port;
2700     s->save_port = save;
2701
2702     return 0;
2703 }
2704
2705 pa_bool_t pa_device_init_icon(pa_proplist *p, pa_bool_t is_sink) {
2706     const char *ff, *c, *t = NULL, *s = "", *profile, *bus;
2707
2708     pa_assert(p);
2709
2710     if (pa_proplist_contains(p, PA_PROP_DEVICE_ICON_NAME))
2711         return TRUE;
2712
2713     if ((ff = pa_proplist_gets(p, PA_PROP_DEVICE_FORM_FACTOR))) {
2714
2715         if (pa_streq(ff, "microphone"))
2716             t = "audio-input-microphone";
2717         else if (pa_streq(ff, "webcam"))
2718             t = "camera-web";
2719         else if (pa_streq(ff, "computer"))
2720             t = "computer";
2721         else if (pa_streq(ff, "handset"))
2722             t = "phone";
2723         else if (pa_streq(ff, "portable"))
2724             t = "multimedia-player";
2725         else if (pa_streq(ff, "tv"))
2726             t = "video-display";
2727
2728         /*
2729          * The following icons are not part of the icon naming spec,
2730          * because Rodney Dawes sucks as the maintainer of that spec.
2731          *
2732          * http://lists.freedesktop.org/archives/xdg/2009-May/010397.html
2733          */
2734         else if (pa_streq(ff, "headset"))
2735             t = "audio-headset";
2736         else if (pa_streq(ff, "headphone"))
2737             t = "audio-headphones";
2738         else if (pa_streq(ff, "speaker"))
2739             t = "audio-speakers";
2740         else if (pa_streq(ff, "hands-free"))
2741             t = "audio-handsfree";
2742     }
2743
2744     if (!t)
2745         if ((c = pa_proplist_gets(p, PA_PROP_DEVICE_CLASS)))
2746             if (pa_streq(c, "modem"))
2747                 t = "modem";
2748
2749     if (!t) {
2750         if (is_sink)
2751             t = "audio-card";
2752         else
2753             t = "audio-input-microphone";
2754     }
2755
2756     if ((profile = pa_proplist_gets(p, PA_PROP_DEVICE_PROFILE_NAME))) {
2757         if (strstr(profile, "analog"))
2758             s = "-analog";
2759         else if (strstr(profile, "iec958"))
2760             s = "-iec958";
2761         else if (strstr(profile, "hdmi"))
2762             s = "-hdmi";
2763     }
2764
2765     bus = pa_proplist_gets(p, PA_PROP_DEVICE_BUS);
2766
2767     pa_proplist_setf(p, PA_PROP_DEVICE_ICON_NAME, "%s%s%s%s", t, pa_strempty(s), bus ? "-" : "", pa_strempty(bus));
2768
2769     return TRUE;
2770 }
2771
2772 pa_bool_t pa_device_init_description(pa_proplist *p) {
2773     const char *s, *d = NULL, *k;
2774     pa_assert(p);
2775
2776     if (pa_proplist_contains(p, PA_PROP_DEVICE_DESCRIPTION))
2777         return TRUE;
2778
2779     if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_FORM_FACTOR)))
2780         if (pa_streq(s, "internal"))
2781             d = _("Internal Audio");
2782
2783     if (!d)
2784         if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_CLASS)))
2785             if (pa_streq(s, "modem"))
2786                 d = _("Modem");
2787
2788     if (!d)
2789         d = pa_proplist_gets(p, PA_PROP_DEVICE_PRODUCT_NAME);
2790
2791     if (!d)
2792         return FALSE;
2793
2794     k = pa_proplist_gets(p, PA_PROP_DEVICE_PROFILE_DESCRIPTION);
2795
2796     if (d && k)
2797         pa_proplist_setf(p, PA_PROP_DEVICE_DESCRIPTION, _("%s %s"), d, k);
2798     else if (d)
2799         pa_proplist_sets(p, PA_PROP_DEVICE_DESCRIPTION, d);
2800
2801     return TRUE;
2802 }
2803
2804 pa_bool_t pa_device_init_intended_roles(pa_proplist *p) {
2805     const char *s;
2806     pa_assert(p);
2807
2808     if (pa_proplist_contains(p, PA_PROP_DEVICE_INTENDED_ROLES))
2809         return TRUE;
2810
2811     if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_FORM_FACTOR)))
2812         if (pa_streq(s, "handset") || pa_streq(s, "hands-free")
2813             || pa_streq(s, "headset")) {
2814             pa_proplist_sets(p, PA_PROP_DEVICE_INTENDED_ROLES, "phone");
2815             return TRUE;
2816         }
2817
2818     return FALSE;
2819 }
2820
2821 unsigned pa_device_init_priority(pa_proplist *p) {
2822     const char *s;
2823     unsigned priority = 0;
2824
2825     pa_assert(p);
2826
2827     if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_CLASS))) {
2828
2829         if (pa_streq(s, "sound"))
2830             priority += 9000;
2831         else if (!pa_streq(s, "modem"))
2832             priority += 1000;
2833     }
2834
2835     if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_FORM_FACTOR))) {
2836
2837         if (pa_streq(s, "internal"))
2838             priority += 900;
2839         else if (pa_streq(s, "speaker"))
2840             priority += 500;
2841         else if (pa_streq(s, "headphone"))
2842             priority += 400;
2843     }
2844
2845     if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_BUS))) {
2846
2847         if (pa_streq(s, "pci"))
2848             priority += 50;
2849         else if (pa_streq(s, "usb"))
2850             priority += 40;
2851         else if (pa_streq(s, "bluetooth"))
2852             priority += 30;
2853     }
2854
2855     if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_PROFILE_NAME))) {
2856
2857         if (pa_startswith(s, "analog-"))
2858             priority += 9;
2859         else if (pa_startswith(s, "iec958-"))
2860             priority += 8;
2861     }
2862
2863     return priority;
2864 }
2865
2866 PA_STATIC_FLIST_DECLARE(pa_sink_volume_change, 0, pa_xfree);
2867
2868 /* Called from the IO thread. */
2869 static pa_sink_volume_change *pa_sink_volume_change_new(pa_sink *s) {
2870     pa_sink_volume_change *c;
2871     if (!(c = pa_flist_pop(PA_STATIC_FLIST_GET(pa_sink_volume_change))))
2872         c = pa_xnew(pa_sink_volume_change, 1);
2873
2874     PA_LLIST_INIT(pa_sink_volume_change, c);
2875     c->at = 0;
2876     pa_cvolume_reset(&c->hw_volume, s->sample_spec.channels);
2877     return c;
2878 }
2879
2880 /* Called from the IO thread. */
2881 static void pa_sink_volume_change_free(pa_sink_volume_change *c) {
2882     pa_assert(c);
2883     if (pa_flist_push(PA_STATIC_FLIST_GET(pa_sink_volume_change), c) < 0)
2884         pa_xfree(c);
2885 }
2886
2887 /* Called from the IO thread. */
2888 void pa_sink_volume_change_push(pa_sink *s) {
2889     pa_sink_volume_change *c = NULL;
2890     pa_sink_volume_change *nc = NULL;
2891     uint32_t safety_margin = s->thread_info.volume_change_safety_margin;
2892
2893     const char *direction = NULL;
2894
2895     pa_assert(s);
2896     nc = pa_sink_volume_change_new(s);
2897
2898     /* NOTE: There is already more different volumes in pa_sink that I can remember.
2899      *       Adding one more volume for HW would get us rid of this, but I am trying
2900      *       to survive with the ones we already have. */
2901     pa_sw_cvolume_divide(&nc->hw_volume, &s->real_volume, &s->soft_volume);
2902
2903     if (!s->thread_info.volume_changes && pa_cvolume_equal(&nc->hw_volume, &s->thread_info.current_hw_volume)) {
2904         pa_log_debug("Volume not changing");
2905         pa_sink_volume_change_free(nc);
2906         return;
2907     }
2908
2909     nc->at = pa_sink_get_latency_within_thread(s);
2910     nc->at += pa_rtclock_now() + s->thread_info.volume_change_extra_delay;
2911
2912     if (s->thread_info.volume_changes_tail) {
2913         for (c = s->thread_info.volume_changes_tail; c; c = c->prev) {
2914             /* If volume is going up let's do it a bit late. If it is going
2915              * down let's do it a bit early. */
2916             if (pa_cvolume_avg(&nc->hw_volume) > pa_cvolume_avg(&c->hw_volume)) {
2917                 if (nc->at + safety_margin > c->at) {
2918                     nc->at += safety_margin;
2919                     direction = "up";
2920                     break;
2921                 }
2922             }
2923             else if (nc->at - safety_margin > c->at) {
2924                     nc->at -= safety_margin;
2925                     direction = "down";
2926                     break;
2927             }
2928         }
2929     }
2930
2931     if (c == NULL) {
2932         if (pa_cvolume_avg(&nc->hw_volume) > pa_cvolume_avg(&s->thread_info.current_hw_volume)) {
2933             nc->at += safety_margin;
2934             direction = "up";
2935         } else {
2936             nc->at -= safety_margin;
2937             direction = "down";
2938         }
2939         PA_LLIST_PREPEND(pa_sink_volume_change, s->thread_info.volume_changes, nc);
2940     }
2941     else {
2942         PA_LLIST_INSERT_AFTER(pa_sink_volume_change, s->thread_info.volume_changes, c, nc);
2943     }
2944
2945     pa_log_debug("Volume going %s to %d at %llu", direction, pa_cvolume_avg(&nc->hw_volume), nc->at);
2946
2947     /* We can ignore volume events that came earlier but should happen later than this. */
2948     PA_LLIST_FOREACH(c, nc->next) {
2949         pa_log_debug("Volume change to %d at %llu was dropped", pa_cvolume_avg(&c->hw_volume), c->at);
2950         pa_sink_volume_change_free(c);
2951     }
2952     nc->next = NULL;
2953     s->thread_info.volume_changes_tail = nc;
2954 }
2955
2956 /* Called from the IO thread. */
2957 static void pa_sink_volume_change_flush(pa_sink *s) {
2958     pa_sink_volume_change *c = s->thread_info.volume_changes;
2959     pa_assert(s);
2960     s->thread_info.volume_changes = NULL;
2961     s->thread_info.volume_changes_tail = NULL;
2962     while (c) {
2963         pa_sink_volume_change *next = c->next;
2964         pa_sink_volume_change_free(c);
2965         c = next;
2966     }
2967 }
2968
2969 /* Called from the IO thread. */
2970 pa_bool_t pa_sink_volume_change_apply(pa_sink *s, pa_usec_t *usec_to_next) {
2971     pa_usec_t now = pa_rtclock_now();
2972     pa_bool_t ret = FALSE;
2973
2974     pa_assert(s);
2975     pa_assert(s->write_volume);
2976
2977     while (s->thread_info.volume_changes && now >= s->thread_info.volume_changes->at) {
2978         pa_sink_volume_change *c = s->thread_info.volume_changes;
2979         PA_LLIST_REMOVE(pa_sink_volume_change, s->thread_info.volume_changes, c);
2980         pa_log_debug("Volume change to %d at %llu was written %llu usec late", pa_cvolume_avg(&c->hw_volume), c->at, now - c->at);
2981         ret = TRUE;
2982         s->thread_info.current_hw_volume = c->hw_volume;
2983         pa_sink_volume_change_free(c);
2984     }
2985
2986     if (s->write_volume && ret)
2987         s->write_volume(s);
2988
2989     if (s->thread_info.volume_changes) {
2990         if (usec_to_next)
2991             *usec_to_next = s->thread_info.volume_changes->at - now;
2992         if (pa_log_ratelimit(PA_LOG_DEBUG))
2993             pa_log_debug("Next volume change in %lld usec", s->thread_info.volume_changes->at - now);
2994     }
2995     else {
2996         if (usec_to_next)
2997             *usec_to_next = 0;
2998         s->thread_info.volume_changes_tail = NULL;
2999     }
3000     return ret;
3001 }
3002
3003 /* Called from the IO thread. */
3004 static void pa_sink_volume_change_rewind(pa_sink *s, size_t nbytes) {
3005     /* All the queued volume events later than current latency are shifted to happen earlier. */
3006     pa_sink_volume_change *c;
3007     pa_volume_t prev_vol = pa_cvolume_avg(&s->thread_info.current_hw_volume);
3008     pa_usec_t rewound = pa_bytes_to_usec(nbytes, &s->sample_spec);
3009     pa_usec_t limit = pa_sink_get_latency_within_thread(s);
3010
3011     pa_log_debug("latency = %lld", limit);
3012     limit += pa_rtclock_now() + s->thread_info.volume_change_extra_delay;
3013
3014     PA_LLIST_FOREACH(c, s->thread_info.volume_changes) {
3015         pa_usec_t modified_limit = limit;
3016         if (prev_vol > pa_cvolume_avg(&c->hw_volume))
3017             modified_limit -= s->thread_info.volume_change_safety_margin;
3018         else
3019             modified_limit += s->thread_info.volume_change_safety_margin;
3020         if (c->at > modified_limit) {
3021             c->at -= rewound;
3022             if (c->at < modified_limit)
3023                 c->at = modified_limit;
3024         }
3025         prev_vol = pa_cvolume_avg(&c->hw_volume);
3026     }
3027     pa_sink_volume_change_apply(s, NULL);
3028 }