make a few functions return void where the retval isn't used/never != 0
[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 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
37 #include <pulsecore/sink-input.h>
38 #include <pulsecore/namereg.h>
39 #include <pulsecore/core-util.h>
40 #include <pulsecore/sample-util.h>
41 #include <pulsecore/core-subscribe.h>
42 #include <pulsecore/log.h>
43 #include <pulsecore/macro.h>
44 #include <pulsecore/play-memblockq.h>
45
46 #include "sink.h"
47
48 #define MAX_MIX_CHANNELS 32
49 #define MIX_BUFFER_LENGTH (PA_PAGE_SIZE)
50 #define DEFAULT_MIN_LATENCY (4*PA_USEC_PER_MSEC)
51
52 static PA_DEFINE_CHECK_TYPE(pa_sink, pa_msgobject);
53
54 static void sink_free(pa_object *s);
55
56 pa_sink_new_data* pa_sink_new_data_init(pa_sink_new_data *data) {
57     pa_assert(data);
58
59     memset(data, 0, sizeof(*data));
60     data->proplist = pa_proplist_new();
61
62     return data;
63 }
64
65 void pa_sink_new_data_set_name(pa_sink_new_data *data, const char *name) {
66     pa_assert(data);
67
68     pa_xfree(data->name);
69     data->name = pa_xstrdup(name);
70 }
71
72 void pa_sink_new_data_set_sample_spec(pa_sink_new_data *data, const pa_sample_spec *spec) {
73     pa_assert(data);
74
75     if ((data->sample_spec_is_set = !!spec))
76         data->sample_spec = *spec;
77 }
78
79 void pa_sink_new_data_set_channel_map(pa_sink_new_data *data, const pa_channel_map *map) {
80     pa_assert(data);
81
82     if ((data->channel_map_is_set = !!map))
83         data->channel_map = *map;
84 }
85
86 void pa_sink_new_data_set_volume(pa_sink_new_data *data, const pa_cvolume *volume) {
87     pa_assert(data);
88
89     if ((data->volume_is_set = !!volume))
90         data->volume = *volume;
91 }
92
93 void pa_sink_new_data_set_muted(pa_sink_new_data *data, pa_bool_t mute) {
94     pa_assert(data);
95
96     data->muted_is_set = TRUE;
97     data->muted = !!mute;
98 }
99
100 void pa_sink_new_data_done(pa_sink_new_data *data) {
101     pa_assert(data);
102
103     pa_xfree(data->name);
104     pa_proplist_free(data->proplist);
105 }
106
107 /* Called from main context */
108 static void reset_callbacks(pa_sink *s) {
109     pa_assert(s);
110
111     s->set_state = NULL;
112     s->get_volume = NULL;
113     s->set_volume = NULL;
114     s->get_mute = NULL;
115     s->set_mute = NULL;
116     s->request_rewind = NULL;
117     s->update_requested_latency = NULL;
118 }
119
120 /* Called from main context */
121 pa_sink* pa_sink_new(
122         pa_core *core,
123         pa_sink_new_data *data,
124         pa_sink_flags_t flags) {
125
126     pa_sink *s;
127     const char *name;
128     char st[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
129     pa_source_new_data source_data;
130     const char *dn;
131     char *pt;
132
133     pa_assert(core);
134     pa_assert(data);
135     pa_assert(data->name);
136
137     s = pa_msgobject_new(pa_sink);
138
139     if (!(name = pa_namereg_register(core, data->name, PA_NAMEREG_SINK, s, data->namereg_fail))) {
140         pa_xfree(s);
141         return NULL;
142     }
143
144     pa_sink_new_data_set_name(data, name);
145
146     if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_NEW], data) < 0) {
147         pa_xfree(s);
148         pa_namereg_unregister(core, name);
149         return NULL;
150     }
151
152     pa_return_null_if_fail(!data->driver || pa_utf8_valid(data->driver));
153     pa_return_null_if_fail(data->name && pa_utf8_valid(data->name) && data->name[0]);
154
155     pa_return_null_if_fail(data->sample_spec_is_set && pa_sample_spec_valid(&data->sample_spec));
156
157     if (!data->channel_map_is_set)
158         pa_return_null_if_fail(pa_channel_map_init_auto(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT));
159
160     pa_return_null_if_fail(pa_channel_map_valid(&data->channel_map));
161     pa_return_null_if_fail(data->channel_map.channels == data->sample_spec.channels);
162
163     if (!data->volume_is_set)
164         pa_cvolume_reset(&data->volume, data->sample_spec.channels);
165
166     pa_return_null_if_fail(pa_cvolume_valid(&data->volume));
167     pa_return_null_if_fail(data->volume.channels == data->sample_spec.channels);
168
169     if (!data->muted_is_set)
170         data->muted = FALSE;
171
172     if (data->card)
173         pa_proplist_update(data->proplist, PA_UPDATE_MERGE, data->card->proplist);
174
175     if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_FIXATE], data) < 0) {
176         pa_xfree(s);
177         pa_namereg_unregister(core, name);
178         return NULL;
179     }
180
181     s->parent.parent.free = sink_free;
182     s->parent.process_msg = pa_sink_process_msg;
183
184     s->core = core;
185     s->state = PA_SINK_INIT;
186     s->flags = flags;
187     s->name = pa_xstrdup(name);
188     s->proplist = pa_proplist_copy(data->proplist);
189     s->driver = pa_xstrdup(pa_path_get_filename(data->driver));
190     s->module = data->module;
191     s->card = data->card;
192
193     s->sample_spec = data->sample_spec;
194     s->channel_map = data->channel_map;
195
196     s->inputs = pa_idxset_new(NULL, NULL);
197     s->n_corked = 0;
198
199     s->virtual_volume = data->volume;
200     pa_cvolume_reset(&s->soft_volume, s->sample_spec.channels);
201     s->base_volume = PA_VOLUME_NORM;
202     s->n_volume_steps = PA_VOLUME_NORM+1;
203     s->muted = data->muted;
204     s->refresh_volume = s->refresh_muted = FALSE;
205
206     reset_callbacks(s);
207     s->userdata = NULL;
208
209     s->asyncmsgq = NULL;
210     s->rtpoll = NULL;
211
212     pa_silence_memchunk_get(
213             &core->silence_cache,
214             core->mempool,
215             &s->silence,
216             &s->sample_spec,
217             0);
218
219     s->thread_info.inputs = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
220     s->thread_info.soft_volume =  s->soft_volume;
221     s->thread_info.soft_muted = s->muted;
222     s->thread_info.state = s->state;
223     s->thread_info.rewind_nbytes = 0;
224     s->thread_info.rewind_requested = FALSE;
225     s->thread_info.max_rewind = 0;
226     s->thread_info.max_request = 0;
227     s->thread_info.requested_latency_valid = FALSE;
228     s->thread_info.requested_latency = 0;
229     s->thread_info.min_latency = DEFAULT_MIN_LATENCY;
230     s->thread_info.max_latency = 0;
231
232     pa_assert_se(pa_idxset_put(core->sinks, s, &s->index) >= 0);
233
234     if (s->card)
235         pa_assert_se(pa_idxset_put(s->card->sinks, s, NULL) >= 0);
236
237     pt = pa_proplist_to_string_sep(s->proplist, "\n    ");
238     pa_log_info("Created sink %u \"%s\" with sample spec %s and channel map %s\n    %s",
239                 s->index,
240                 s->name,
241                 pa_sample_spec_snprint(st, sizeof(st), &s->sample_spec),
242                 pa_channel_map_snprint(cm, sizeof(cm), &s->channel_map),
243                 pt);
244     pa_xfree(pt);
245
246     pa_source_new_data_init(&source_data);
247     pa_source_new_data_set_sample_spec(&source_data, &s->sample_spec);
248     pa_source_new_data_set_channel_map(&source_data, &s->channel_map);
249     source_data.name = pa_sprintf_malloc("%s.monitor", name);
250     source_data.driver = data->driver;
251     source_data.module = data->module;
252     source_data.card = data->card;
253
254     dn = pa_proplist_gets(s->proplist, PA_PROP_DEVICE_DESCRIPTION);
255     pa_proplist_setf(source_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Monitor of %s", dn ? dn : s->name);
256     pa_proplist_sets(source_data.proplist, PA_PROP_DEVICE_CLASS, "monitor");
257
258     s->monitor_source = pa_source_new(core, &source_data, PA_SOURCE_LATENCY);
259
260     pa_source_new_data_done(&source_data);
261
262     if (!s->monitor_source) {
263         pa_sink_unlink(s);
264         pa_sink_unref(s);
265         return NULL;
266     }
267
268     s->monitor_source->monitor_of = s;
269
270     pa_source_set_latency_range(s->monitor_source, s->thread_info.min_latency, s->thread_info.max_latency);
271     pa_source_set_max_rewind(s->monitor_source, s->thread_info.max_rewind);
272
273     return s;
274 }
275
276 /* Called from main context */
277 static int sink_set_state(pa_sink *s, pa_sink_state_t state) {
278     int ret;
279     pa_bool_t suspend_change;
280     pa_sink_state_t original_state;
281
282     pa_assert(s);
283
284     if (s->state == state)
285         return 0;
286
287     original_state = s->state;
288
289     suspend_change =
290         (original_state == PA_SINK_SUSPENDED && PA_SINK_IS_OPENED(state)) ||
291         (PA_SINK_IS_OPENED(original_state) && state == PA_SINK_SUSPENDED);
292
293     if (s->set_state)
294         if ((ret = s->set_state(s, state)) < 0)
295             return ret;
296
297     if (s->asyncmsgq)
298         if ((ret = pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), 0, NULL)) < 0) {
299
300             if (s->set_state)
301                 s->set_state(s, original_state);
302
303             return ret;
304         }
305
306     s->state = state;
307
308     if (state != PA_SINK_UNLINKED) { /* if we enter UNLINKED state pa_sink_unlink() will fire the apropriate events */
309         pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_STATE_CHANGED], s);
310         pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
311     }
312
313     if (suspend_change) {
314         pa_sink_input *i;
315         uint32_t idx;
316
317         /* We're suspending or resuming, tell everyone about it */
318
319         for (i = PA_SINK_INPUT(pa_idxset_first(s->inputs, &idx)); i; i = PA_SINK_INPUT(pa_idxset_next(s->inputs, &idx)))
320             if (s->state == PA_SINK_SUSPENDED &&
321                 (i->flags & PA_SINK_INPUT_FAIL_ON_SUSPEND))
322                 pa_sink_input_kill(i);
323             else if (i->suspend)
324                 i->suspend(i, state == PA_SINK_SUSPENDED);
325     }
326
327     return 0;
328 }
329
330 /* Called from main context */
331 void pa_sink_put(pa_sink* s) {
332     pa_sink_assert_ref(s);
333
334     pa_assert(s->state == PA_SINK_INIT);
335
336     /* The following fields must be initialized properly when calling _put() */
337     pa_assert(s->asyncmsgq);
338     pa_assert(s->rtpoll);
339     pa_assert(!s->thread_info.min_latency || !s->thread_info.max_latency ||
340               s->thread_info.min_latency <= s->thread_info.max_latency);
341
342     if (!(s->flags & PA_SINK_HW_VOLUME_CTRL)) {
343         s->flags |= PA_SINK_DECIBEL_VOLUME;
344
345         s->thread_info.soft_volume = s->soft_volume;
346         s->thread_info.soft_muted = s->muted;
347     }
348
349     if (s->flags & PA_SINK_DECIBEL_VOLUME)
350         s->n_volume_steps = PA_VOLUME_NORM+1;
351
352     if (s->core->flat_volumes)
353         if (s->flags & PA_SINK_DECIBEL_VOLUME)
354             s->flags |= PA_SINK_FLAT_VOLUME;
355
356     pa_assert_se(sink_set_state(s, PA_SINK_IDLE) == 0);
357
358     pa_source_put(s->monitor_source);
359
360     pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_NEW, s->index);
361     pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_PUT], s);
362 }
363
364 /* Called from main context */
365 void pa_sink_unlink(pa_sink* s) {
366     pa_bool_t linked;
367     pa_sink_input *i, *j = NULL;
368
369     pa_assert(s);
370
371     /* Please note that pa_sink_unlink() does more than simply
372      * reversing pa_sink_put(). It also undoes the registrations
373      * already done in pa_sink_new()! */
374
375     /* All operations here shall be idempotent, i.e. pa_sink_unlink()
376      * may be called multiple times on the same sink without bad
377      * effects. */
378
379     linked = PA_SINK_IS_LINKED(s->state);
380
381     if (linked)
382         pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_UNLINK], s);
383
384     if (s->state != PA_SINK_UNLINKED)
385         pa_namereg_unregister(s->core, s->name);
386     pa_idxset_remove_by_data(s->core->sinks, s, NULL);
387
388     if (s->card)
389         pa_idxset_remove_by_data(s->card->sinks, s, NULL);
390
391     while ((i = pa_idxset_first(s->inputs, NULL))) {
392         pa_assert(i != j);
393         pa_sink_input_kill(i);
394         j = i;
395     }
396
397     if (linked)
398         sink_set_state(s, PA_SINK_UNLINKED);
399     else
400         s->state = PA_SINK_UNLINKED;
401
402     reset_callbacks(s);
403
404     if (s->monitor_source)
405         pa_source_unlink(s->monitor_source);
406
407     if (linked) {
408         pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_REMOVE, s->index);
409         pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_UNLINK_POST], s);
410     }
411 }
412
413 /* Called from main context */
414 static void sink_free(pa_object *o) {
415     pa_sink *s = PA_SINK(o);
416     pa_sink_input *i;
417
418     pa_assert(s);
419     pa_assert(pa_sink_refcnt(s) == 0);
420
421     if (PA_SINK_IS_LINKED(s->state))
422         pa_sink_unlink(s);
423
424     pa_log_info("Freeing sink %u \"%s\"", s->index, s->name);
425
426     if (s->monitor_source) {
427         pa_source_unref(s->monitor_source);
428         s->monitor_source = NULL;
429     }
430
431     pa_idxset_free(s->inputs, NULL, NULL);
432
433     while ((i = pa_hashmap_steal_first(s->thread_info.inputs)))
434         pa_sink_input_unref(i);
435
436     pa_hashmap_free(s->thread_info.inputs, NULL, NULL);
437
438     if (s->silence.memblock)
439         pa_memblock_unref(s->silence.memblock);
440
441     pa_xfree(s->name);
442     pa_xfree(s->driver);
443
444     if (s->proplist)
445         pa_proplist_free(s->proplist);
446
447     pa_xfree(s);
448 }
449
450 /* Called from main context */
451 void pa_sink_set_asyncmsgq(pa_sink *s, pa_asyncmsgq *q) {
452     pa_sink_assert_ref(s);
453
454     s->asyncmsgq = q;
455
456     if (s->monitor_source)
457         pa_source_set_asyncmsgq(s->monitor_source, q);
458 }
459
460 /* Called from main context */
461 void pa_sink_set_rtpoll(pa_sink *s, pa_rtpoll *p) {
462     pa_sink_assert_ref(s);
463
464     s->rtpoll = p;
465     if (s->monitor_source)
466         pa_source_set_rtpoll(s->monitor_source, p);
467 }
468
469 /* Called from main context */
470 int pa_sink_update_status(pa_sink*s) {
471     pa_sink_assert_ref(s);
472     pa_assert(PA_SINK_IS_LINKED(s->state));
473
474     if (s->state == PA_SINK_SUSPENDED)
475         return 0;
476
477     return sink_set_state(s, pa_sink_used_by(s) ? PA_SINK_RUNNING : PA_SINK_IDLE);
478 }
479
480 /* Called from main context */
481 int pa_sink_suspend(pa_sink *s, pa_bool_t suspend) {
482     pa_sink_assert_ref(s);
483     pa_assert(PA_SINK_IS_LINKED(s->state));
484
485     if (suspend)
486         return sink_set_state(s, PA_SINK_SUSPENDED);
487     else
488         return sink_set_state(s, pa_sink_used_by(s) ? PA_SINK_RUNNING : PA_SINK_IDLE);
489 }
490
491 /* Called from main context */
492 pa_queue *pa_sink_move_all_start(pa_sink *s) {
493     pa_queue *q;
494     pa_sink_input *i, *n;
495     uint32_t idx;
496
497     pa_sink_assert_ref(s);
498     pa_assert(PA_SINK_IS_LINKED(s->state));
499
500     q = pa_queue_new();
501
502     for (i = PA_SINK_INPUT(pa_idxset_first(s->inputs, &idx)); i; i = n) {
503         n = PA_SINK_INPUT(pa_idxset_next(s->inputs, &idx));
504
505         if (pa_sink_input_start_move(i) >= 0)
506             pa_queue_push(q, pa_sink_input_ref(i));
507     }
508
509     return q;
510 }
511
512 /* Called from main context */
513 void pa_sink_move_all_finish(pa_sink *s, pa_queue *q, pa_bool_t save) {
514     pa_sink_input *i;
515
516     pa_sink_assert_ref(s);
517     pa_assert(PA_SINK_IS_LINKED(s->state));
518     pa_assert(q);
519
520     while ((i = PA_SINK_INPUT(pa_queue_pop(q)))) {
521         if (pa_sink_input_finish_move(i, s, save) < 0)
522             pa_sink_input_unlink(i);
523
524         pa_sink_input_unref(i);
525     }
526
527     pa_queue_free(q, NULL, NULL);
528 }
529
530 /* Called from main context */
531 void pa_sink_move_all_fail(pa_queue *q) {
532     pa_sink_input *i;
533     pa_assert(q);
534
535     while ((i = PA_SINK_INPUT(pa_queue_pop(q)))) {
536         pa_sink_input_unlink(i);
537         pa_sink_input_unref(i);
538     }
539
540     pa_queue_free(q, NULL, NULL);
541 }
542
543 /* Called from IO thread context */
544 void pa_sink_process_rewind(pa_sink *s, size_t nbytes) {
545     pa_sink_input *i;
546     void *state = NULL;
547     pa_sink_assert_ref(s);
548     pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
549
550     /* If nobody requested this and this is actually no real rewind
551      * then we can short cut this */
552     if (!s->thread_info.rewind_requested && nbytes <= 0)
553         return;
554
555     s->thread_info.rewind_nbytes = 0;
556     s->thread_info.rewind_requested = FALSE;
557
558     if (s->thread_info.state == PA_SINK_SUSPENDED)
559         return;
560
561     if (nbytes > 0)
562         pa_log_debug("Processing rewind...");
563
564     while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL))) {
565         pa_sink_input_assert_ref(i);
566         pa_sink_input_process_rewind(i, nbytes);
567     }
568
569     if (nbytes > 0)
570         if (s->monitor_source && PA_SOURCE_IS_LINKED(s->monitor_source->thread_info.state))
571             pa_source_process_rewind(s->monitor_source, nbytes);
572 }
573
574 /* Called from IO thread context */
575 static unsigned fill_mix_info(pa_sink *s, size_t *length, pa_mix_info *info, unsigned maxinfo) {
576     pa_sink_input *i;
577     unsigned n = 0;
578     void *state = NULL;
579     size_t mixlength = *length;
580
581     pa_sink_assert_ref(s);
582     pa_assert(info);
583
584     while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)) && maxinfo > 0) {
585         pa_sink_input_assert_ref(i);
586
587         pa_sink_input_peek(i, *length, &info->chunk, &info->volume);
588
589         if (mixlength == 0 || info->chunk.length < mixlength)
590             mixlength = info->chunk.length;
591
592         if (pa_memblock_is_silence(info->chunk.memblock)) {
593             pa_memblock_unref(info->chunk.memblock);
594             continue;
595         }
596
597         info->userdata = pa_sink_input_ref(i);
598
599         pa_assert(info->chunk.memblock);
600         pa_assert(info->chunk.length > 0);
601
602         info++;
603         n++;
604         maxinfo--;
605     }
606
607     if (mixlength > 0)
608         *length = mixlength;
609
610     return n;
611 }
612
613 /* Called from IO thread context */
614 static void inputs_drop(pa_sink *s, pa_mix_info *info, unsigned n, pa_memchunk *result) {
615     pa_sink_input *i;
616     void *state = NULL;
617     unsigned p = 0;
618     unsigned n_unreffed = 0;
619
620     pa_sink_assert_ref(s);
621     pa_assert(result);
622     pa_assert(result->memblock);
623     pa_assert(result->length > 0);
624
625     /* We optimize for the case where the order of the inputs has not changed */
626
627     while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL))) {
628         unsigned j;
629         pa_mix_info* m = NULL;
630
631         pa_sink_input_assert_ref(i);
632
633         /* Let's try to find the matching entry info the pa_mix_info array */
634         for (j = 0; j < n; j ++) {
635
636             if (info[p].userdata == i) {
637                 m = info + p;
638                 break;
639             }
640
641             p++;
642             if (p >= n)
643                 p = 0;
644         }
645
646         /* Drop read data */
647         pa_sink_input_drop(i, result->length);
648
649         if (s->monitor_source && PA_SOURCE_IS_LINKED(s->monitor_source->thread_info.state)) {
650
651             if (pa_hashmap_size(i->thread_info.direct_outputs) > 0) {
652                 void *ostate = NULL;
653                 pa_source_output *o;
654                 pa_memchunk c;
655
656                 if (m && m->chunk.memblock) {
657                     c = m->chunk;
658                     pa_memblock_ref(c.memblock);
659                     pa_assert(result->length <= c.length);
660                     c.length = result->length;
661
662                     pa_memchunk_make_writable(&c, 0);
663                     pa_volume_memchunk(&c, &s->sample_spec, &m->volume);
664                 } else {
665                     c = s->silence;
666                     pa_memblock_ref(c.memblock);
667                     pa_assert(result->length <= c.length);
668                     c.length = result->length;
669                 }
670
671                 while ((o = pa_hashmap_iterate(i->thread_info.direct_outputs, &ostate, NULL))) {
672                     pa_source_output_assert_ref(o);
673                     pa_assert(o->direct_on_input == i);
674                     pa_source_post_direct(s->monitor_source, o, &c);
675                 }
676
677                 pa_memblock_unref(c.memblock);
678             }
679         }
680
681         if (m) {
682             if (m->chunk.memblock)
683                 pa_memblock_unref(m->chunk.memblock);
684                 pa_memchunk_reset(&m->chunk);
685
686             pa_sink_input_unref(m->userdata);
687             m->userdata = NULL;
688
689             n_unreffed += 1;
690         }
691     }
692
693     /* Now drop references to entries that are included in the
694      * pa_mix_info array but don't exist anymore */
695
696     if (n_unreffed < n) {
697         for (; n > 0; info++, n--) {
698             if (info->userdata)
699                 pa_sink_input_unref(info->userdata);
700             if (info->chunk.memblock)
701                 pa_memblock_unref(info->chunk.memblock);
702         }
703     }
704
705     if (s->monitor_source && PA_SOURCE_IS_LINKED(s->monitor_source->thread_info.state))
706         pa_source_post(s->monitor_source, result);
707 }
708
709 /* Called from IO thread context */
710 void pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) {
711     pa_mix_info info[MAX_MIX_CHANNELS];
712     unsigned n;
713     size_t block_size_max;
714
715     pa_sink_assert_ref(s);
716     pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
717     pa_assert(pa_frame_aligned(length, &s->sample_spec));
718     pa_assert(result);
719
720     pa_sink_ref(s);
721
722     pa_assert(!s->thread_info.rewind_requested);
723     pa_assert(s->thread_info.rewind_nbytes == 0);
724
725     if (s->thread_info.state == PA_SINK_SUSPENDED) {
726         result->memblock = pa_memblock_ref(s->silence.memblock);
727         result->index = s->silence.index;
728         result->length = PA_MIN(s->silence.length, length);
729         return;
730     }
731
732     if (length <= 0)
733         length = pa_frame_align(MIX_BUFFER_LENGTH, &s->sample_spec);
734
735     block_size_max = pa_mempool_block_size_max(s->core->mempool);
736     if (length > block_size_max)
737         length = pa_frame_align(block_size_max, &s->sample_spec);
738
739     pa_assert(length > 0);
740
741     n = fill_mix_info(s, &length, info, MAX_MIX_CHANNELS);
742
743     if (n == 0) {
744
745         *result = s->silence;
746         pa_memblock_ref(result->memblock);
747
748         if (result->length > length)
749             result->length = length;
750
751     } else if (n == 1) {
752         pa_cvolume volume;
753
754         *result = info[0].chunk;
755         pa_memblock_ref(result->memblock);
756
757         if (result->length > length)
758             result->length = length;
759
760         pa_sw_cvolume_multiply(&volume, &s->thread_info.soft_volume, &info[0].volume);
761
762         if (s->thread_info.soft_muted || !pa_cvolume_is_norm(&volume)) {
763             pa_memchunk_make_writable(result, 0);
764             if (s->thread_info.soft_muted || pa_cvolume_is_muted(&volume))
765                 pa_silence_memchunk(result, &s->sample_spec);
766             else
767                 pa_volume_memchunk(result, &s->sample_spec, &volume);
768         }
769     } else {
770         void *ptr;
771         result->memblock = pa_memblock_new(s->core->mempool, length);
772
773         ptr = pa_memblock_acquire(result->memblock);
774         result->length = pa_mix(info, n,
775                                 ptr, length,
776                                 &s->sample_spec,
777                                 &s->thread_info.soft_volume,
778                                 s->thread_info.soft_muted);
779         pa_memblock_release(result->memblock);
780
781         result->index = 0;
782     }
783
784     inputs_drop(s, info, n, result);
785
786     pa_sink_unref(s);
787 }
788
789 /* Called from IO thread context */
790 void pa_sink_render_into(pa_sink*s, pa_memchunk *target) {
791     pa_mix_info info[MAX_MIX_CHANNELS];
792     unsigned n;
793     size_t length, block_size_max;
794
795     pa_sink_assert_ref(s);
796     pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
797     pa_assert(target);
798     pa_assert(target->memblock);
799     pa_assert(target->length > 0);
800     pa_assert(pa_frame_aligned(target->length, &s->sample_spec));
801
802     pa_sink_ref(s);
803
804     pa_assert(!s->thread_info.rewind_requested);
805     pa_assert(s->thread_info.rewind_nbytes == 0);
806
807     if (s->thread_info.state == PA_SINK_SUSPENDED) {
808         pa_silence_memchunk(target, &s->sample_spec);
809         return;
810     }
811
812     length = target->length;
813     block_size_max = pa_mempool_block_size_max(s->core->mempool);
814     if (length > block_size_max)
815         length = pa_frame_align(block_size_max, &s->sample_spec);
816
817     pa_assert(length > 0);
818
819     n = fill_mix_info(s, &length, info, MAX_MIX_CHANNELS);
820
821     if (n == 0) {
822         if (target->length > length)
823             target->length = length;
824
825         pa_silence_memchunk(target, &s->sample_spec);
826     } else if (n == 1) {
827         pa_cvolume volume;
828
829         if (target->length > length)
830             target->length = length;
831
832         pa_sw_cvolume_multiply(&volume, &s->thread_info.soft_volume, &info[0].volume);
833
834         if (s->thread_info.soft_muted || pa_cvolume_is_muted(&volume))
835             pa_silence_memchunk(target, &s->sample_spec);
836         else {
837             pa_memchunk vchunk;
838
839             vchunk = info[0].chunk;
840             pa_memblock_ref(vchunk.memblock);
841
842             if (vchunk.length > length)
843                 vchunk.length = length;
844
845             if (!pa_cvolume_is_norm(&volume)) {
846                 pa_memchunk_make_writable(&vchunk, 0);
847                 pa_volume_memchunk(&vchunk, &s->sample_spec, &volume);
848             }
849
850             pa_memchunk_memcpy(target, &vchunk);
851             pa_memblock_unref(vchunk.memblock);
852         }
853
854     } else {
855         void *ptr;
856
857         ptr = pa_memblock_acquire(target->memblock);
858
859         target->length = pa_mix(info, n,
860                                 (uint8_t*) ptr + target->index, length,
861                                 &s->sample_spec,
862                                 &s->thread_info.soft_volume,
863                                 s->thread_info.soft_muted);
864
865         pa_memblock_release(target->memblock);
866     }
867
868     inputs_drop(s, info, n, target);
869
870     pa_sink_unref(s);
871 }
872
873 /* Called from IO thread context */
874 void pa_sink_render_into_full(pa_sink *s, pa_memchunk *target) {
875     pa_memchunk chunk;
876     size_t l, d;
877
878     pa_sink_assert_ref(s);
879     pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
880     pa_assert(target);
881     pa_assert(target->memblock);
882     pa_assert(target->length > 0);
883     pa_assert(pa_frame_aligned(target->length, &s->sample_spec));
884
885     pa_sink_ref(s);
886
887     pa_assert(!s->thread_info.rewind_requested);
888     pa_assert(s->thread_info.rewind_nbytes == 0);
889
890     l = target->length;
891     d = 0;
892     while (l > 0) {
893         chunk = *target;
894         chunk.index += d;
895         chunk.length -= d;
896
897         pa_sink_render_into(s, &chunk);
898
899         d += chunk.length;
900         l -= chunk.length;
901     }
902
903     pa_sink_unref(s);
904 }
905
906 /* Called from IO thread context */
907 void pa_sink_render_full(pa_sink *s, size_t length, pa_memchunk *result) {
908     pa_sink_assert_ref(s);
909     pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
910     pa_assert(length > 0);
911     pa_assert(pa_frame_aligned(length, &s->sample_spec));
912     pa_assert(result);
913
914     pa_assert(!s->thread_info.rewind_requested);
915     pa_assert(s->thread_info.rewind_nbytes == 0);
916
917     /*** This needs optimization ***/
918
919     result->index = 0;
920     result->length = length;
921     result->memblock = pa_memblock_new(s->core->mempool, length);
922
923     pa_sink_render_into_full(s, result);
924 }
925
926 /* Called from main thread */
927 pa_usec_t pa_sink_get_latency(pa_sink *s) {
928     pa_usec_t usec = 0;
929
930     pa_sink_assert_ref(s);
931     pa_assert(PA_SINK_IS_LINKED(s->state));
932
933     /* The returned value is supposed to be in the time domain of the sound card! */
934
935     if (s->state == PA_SINK_SUSPENDED)
936         return 0;
937
938     if (!(s->flags & PA_SINK_LATENCY))
939         return 0;
940
941     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_LATENCY, &usec, 0, NULL) == 0);
942
943     return usec;
944 }
945
946 /* Called from main thread */
947 void pa_sink_update_flat_volume(pa_sink *s, pa_cvolume *new_volume) {
948     pa_sink_input *i;
949     uint32_t idx;
950
951     pa_sink_assert_ref(s);
952     pa_assert(new_volume);
953     pa_assert(PA_SINK_IS_LINKED(s->state));
954     pa_assert(s->flags & PA_SINK_FLAT_VOLUME);
955
956     /* This is called whenever a sink input volume changes and we
957      * might need to fix up the sink volume accordingly. Please note
958      * that we don't actually update the sinks volume here, we only
959      * return how it needs to be updated. The caller should then call
960      * pa_sink_set_flat_volume().*/
961
962     if (pa_idxset_isempty(s->inputs)) {
963         /* In the special case that we have no sink input we leave the
964          * volume unmodified. */
965         *new_volume = s->virtual_volume;
966         return;
967     }
968
969     pa_cvolume_mute(new_volume, s->channel_map.channels);
970
971     /* First let's determine the new maximum volume of all inputs
972      * connected to this sink */
973     for (i = PA_SINK_INPUT(pa_idxset_first(s->inputs, &idx)); i; i = PA_SINK_INPUT(pa_idxset_next(s->inputs, &idx))) {
974         unsigned c;
975         pa_cvolume remapped_volume;
976
977         remapped_volume = i->virtual_volume;
978         pa_cvolume_remap(&remapped_volume, &i->channel_map, &s->channel_map);
979
980         for (c = 0; c < new_volume->channels; c++)
981             if (remapped_volume.values[c] > new_volume->values[c])
982                 new_volume->values[c] = remapped_volume.values[c];
983     }
984
985     /* Then, let's update the soft volumes of all inputs connected
986      * to this sink */
987     for (i = PA_SINK_INPUT(pa_idxset_first(s->inputs, &idx)); i; i = PA_SINK_INPUT(pa_idxset_next(s->inputs, &idx))) {
988         pa_cvolume remapped_new_volume;
989
990         remapped_new_volume = *new_volume;
991         pa_cvolume_remap(&remapped_new_volume, &s->channel_map, &i->channel_map);
992         pa_sw_cvolume_divide(&i->soft_volume, &i->virtual_volume, &remapped_new_volume);
993
994         /* Hooks have the ability to play games with i->soft_volume */
995         pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_INPUT_SET_VOLUME], i);
996
997         /* We don't issue PA_SINK_INPUT_MESSAGE_SET_VOLUME because
998          * we want the update to have atomically with the sink
999          * volume update, hence we do it within the
1000          * pa_sink_set_flat_volume() call below*/
1001     }
1002 }
1003
1004 /* Called from main thread */
1005 void pa_sink_propagate_flat_volume(pa_sink *s, const pa_cvolume *old_volume) {
1006     pa_sink_input *i;
1007     uint32_t idx;
1008
1009     pa_sink_assert_ref(s);
1010     pa_assert(old_volume);
1011     pa_assert(PA_SINK_IS_LINKED(s->state));
1012     pa_assert(s->flags & PA_SINK_FLAT_VOLUME);
1013
1014     /* This is called whenever the sink volume changes that is not
1015      * caused by a sink input volume change. We need to fix up the
1016      * sink input volumes accordingly */
1017
1018     for (i = PA_SINK_INPUT(pa_idxset_first(s->inputs, &idx)); i; i = PA_SINK_INPUT(pa_idxset_next(s->inputs, &idx))) {
1019         pa_cvolume remapped_old_volume, remapped_new_volume, fixed_volume;
1020         unsigned c;
1021
1022         remapped_new_volume = s->virtual_volume;
1023         pa_cvolume_remap(&remapped_new_volume, &s->channel_map, &i->channel_map);
1024
1025         remapped_old_volume = *old_volume;
1026         pa_cvolume_remap(&remapped_old_volume, &s->channel_map, &i->channel_map);
1027
1028         for (c = 0; c < i->sample_spec.channels; c++)
1029
1030             if (remapped_old_volume.values[c] == PA_VOLUME_MUTED)
1031                 fixed_volume.values[c] = PA_VOLUME_MUTED;
1032             else
1033                 fixed_volume.values[c] = (pa_volume_t)
1034                     ((uint64_t) i->virtual_volume.values[c] *
1035                      (uint64_t) remapped_new_volume.values[c] /
1036                      (uint64_t) remapped_old_volume.values[c]);
1037
1038         fixed_volume.channels = i->virtual_volume.channels;
1039
1040         if (!pa_cvolume_equal(&fixed_volume, &i->virtual_volume)) {
1041             i->virtual_volume = fixed_volume;
1042
1043             /* The virtual volume changed, let's tell people so */
1044             pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1045         }
1046     }
1047 }
1048
1049 /* Called from main thread */
1050 void pa_sink_set_volume(pa_sink *s, const pa_cvolume *volume, pa_bool_t propagate, pa_bool_t sendmsg) {
1051     pa_cvolume old_virtual_volume;
1052     pa_bool_t virtual_volume_changed;
1053
1054     pa_sink_assert_ref(s);
1055     pa_assert(PA_SINK_IS_LINKED(s->state));
1056     pa_assert(volume);
1057     pa_assert(pa_cvolume_valid(volume));
1058     pa_assert(pa_cvolume_compatible(volume, &s->sample_spec));
1059
1060     old_virtual_volume = s->virtual_volume;
1061     s->virtual_volume = *volume;
1062     virtual_volume_changed = !pa_cvolume_equal(&old_virtual_volume, &s->virtual_volume);
1063
1064     /* Propagate this volume change back to the inputs */
1065     if (virtual_volume_changed)
1066         if (propagate && (s->flags & PA_SINK_FLAT_VOLUME))
1067             pa_sink_propagate_flat_volume(s, &old_virtual_volume);
1068
1069     if (s->set_volume) {
1070         /* If we have a function set_volume(), then we do not apply a
1071          * soft volume by default. However, set_volume() is apply one
1072          * to s->soft_volume */
1073
1074         pa_cvolume_reset(&s->soft_volume, s->sample_spec.channels);
1075         s->set_volume(s);
1076
1077     } else
1078         /* If we have no function set_volume(), then the soft volume
1079          * becomes the virtual volume */
1080         s->soft_volume = s->virtual_volume;
1081
1082     /* This tells the sink that soft and/or virtual volume changed */
1083     if (sendmsg)
1084         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_VOLUME, NULL, 0, NULL) == 0);
1085
1086     if (virtual_volume_changed)
1087         pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
1088 }
1089
1090 /* Called from main thread. Only to be called by sink implementor */
1091 void pa_sink_set_soft_volume(pa_sink *s, const pa_cvolume *volume) {
1092     pa_sink_assert_ref(s);
1093     pa_assert(volume);
1094
1095     s->soft_volume = *volume;
1096
1097     if (PA_SINK_IS_LINKED(s->state))
1098         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_VOLUME, NULL, 0, NULL) == 0);
1099     else
1100         s->thread_info.soft_volume = *volume;
1101 }
1102
1103 /* Called from main thread */
1104 const pa_cvolume *pa_sink_get_volume(pa_sink *s, pa_bool_t force_refresh) {
1105     pa_sink_assert_ref(s);
1106
1107     if (s->refresh_volume || force_refresh) {
1108         struct pa_cvolume old_virtual_volume = s->virtual_volume;
1109
1110         if (s->get_volume)
1111             s->get_volume(s);
1112
1113         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_VOLUME, NULL, 0, NULL) == 0);
1114
1115         if (!pa_cvolume_equal(&old_virtual_volume, &s->virtual_volume)) {
1116
1117             if (s->flags & PA_SINK_FLAT_VOLUME)
1118                 pa_sink_propagate_flat_volume(s, &old_virtual_volume);
1119
1120             pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
1121         }
1122     }
1123
1124     return &s->virtual_volume;
1125 }
1126
1127 /* Called from main thread */
1128 void pa_sink_set_mute(pa_sink *s, pa_bool_t mute) {
1129     pa_bool_t old_muted;
1130
1131     pa_sink_assert_ref(s);
1132     pa_assert(PA_SINK_IS_LINKED(s->state));
1133
1134     old_muted = s->muted;
1135     s->muted = mute;
1136
1137     if (s->set_mute)
1138         s->set_mute(s);
1139
1140     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_MUTE, NULL, 0, NULL) == 0);
1141
1142     if (old_muted != s->muted)
1143         pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
1144 }
1145
1146 /* Called from main thread */
1147 pa_bool_t pa_sink_get_mute(pa_sink *s, pa_bool_t force_refresh) {
1148
1149     pa_sink_assert_ref(s);
1150
1151     if (s->refresh_muted || force_refresh) {
1152         pa_bool_t old_muted = s->muted;
1153
1154         if (s->get_mute)
1155             s->get_mute(s);
1156
1157         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_MUTE, NULL, 0, NULL) == 0);
1158
1159         if (old_muted != s->muted)
1160             pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
1161     }
1162
1163     return s->muted;
1164 }
1165
1166 /* Called from main thread */
1167 pa_bool_t pa_sink_update_proplist(pa_sink *s, pa_update_mode_t mode, pa_proplist *p) {
1168
1169     pa_sink_assert_ref(s);
1170     pa_assert(p);
1171
1172     pa_proplist_update(s->proplist, mode, p);
1173
1174     if (PA_SINK_IS_LINKED(s->state)) {
1175         pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_PROPLIST_CHANGED], s);
1176         pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
1177     }
1178
1179     return TRUE;
1180 }
1181
1182 /* Called from main thread */
1183 void pa_sink_set_description(pa_sink *s, const char *description) {
1184     const char *old;
1185     pa_sink_assert_ref(s);
1186
1187     if (!description && !pa_proplist_contains(s->proplist, PA_PROP_DEVICE_DESCRIPTION))
1188         return;
1189
1190     old = pa_proplist_gets(s->proplist, PA_PROP_DEVICE_DESCRIPTION);
1191
1192     if (old && description && !strcmp(old, description))
1193         return;
1194
1195     if (description)
1196         pa_proplist_sets(s->proplist, PA_PROP_DEVICE_DESCRIPTION, description);
1197     else
1198         pa_proplist_unset(s->proplist, PA_PROP_DEVICE_DESCRIPTION);
1199
1200     if (s->monitor_source) {
1201         char *n;
1202
1203         n = pa_sprintf_malloc("Monitor Source of %s", description ? description : s->name);
1204         pa_source_set_description(s->monitor_source, n);
1205         pa_xfree(n);
1206     }
1207
1208     if (PA_SINK_IS_LINKED(s->state)) {
1209         pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
1210         pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_PROPLIST_CHANGED], s);
1211     }
1212 }
1213
1214 /* Called from main thread */
1215 unsigned pa_sink_linked_by(pa_sink *s) {
1216     unsigned ret;
1217
1218     pa_sink_assert_ref(s);
1219     pa_assert(PA_SINK_IS_LINKED(s->state));
1220
1221     ret = pa_idxset_size(s->inputs);
1222
1223     /* We add in the number of streams connected to us here. Please
1224      * note the asymmmetry to pa_sink_used_by()! */
1225
1226     if (s->monitor_source)
1227         ret += pa_source_linked_by(s->monitor_source);
1228
1229     return ret;
1230 }
1231
1232 /* Called from main thread */
1233 unsigned pa_sink_used_by(pa_sink *s) {
1234     unsigned ret;
1235
1236     pa_sink_assert_ref(s);
1237     pa_assert(PA_SINK_IS_LINKED(s->state));
1238
1239     ret = pa_idxset_size(s->inputs);
1240     pa_assert(ret >= s->n_corked);
1241
1242     /* Streams connected to our monitor source do not matter for
1243      * pa_sink_used_by()!.*/
1244
1245     return ret - s->n_corked;
1246 }
1247
1248 /* Called from main thread */
1249 unsigned pa_sink_check_suspend(pa_sink *s) {
1250     unsigned ret;
1251     pa_sink_input *i;
1252     uint32_t idx;
1253
1254     pa_sink_assert_ref(s);
1255
1256     if (!PA_SINK_IS_LINKED(s->state))
1257         return 0;
1258
1259     ret = 0;
1260
1261     for (i = PA_SINK_INPUT(pa_idxset_first(s->inputs, &idx)); i; i = PA_SINK_INPUT(pa_idxset_next(s->inputs, &idx))) {
1262         pa_sink_input_state_t st;
1263
1264         st = pa_sink_input_get_state(i);
1265         pa_assert(PA_SINK_INPUT_IS_LINKED(st));
1266
1267         if (st == PA_SINK_INPUT_CORKED)
1268             continue;
1269
1270         if (i->flags & PA_SINK_INPUT_DONT_INHIBIT_AUTO_SUSPEND)
1271             continue;
1272
1273         ret ++;
1274     }
1275
1276     if (s->monitor_source)
1277         ret += pa_source_check_suspend(s->monitor_source);
1278
1279     return ret;
1280 }
1281
1282 /* Called from the IO thread */
1283 static void sync_input_volumes_within_thread(pa_sink *s) {
1284     pa_sink_input *i;
1285     void *state = NULL;
1286
1287     pa_sink_assert_ref(s);
1288
1289     while ((i = PA_SINK_INPUT(pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)))) {
1290         if (pa_cvolume_equal(&i->thread_info.soft_volume, &i->soft_volume))
1291             continue;
1292
1293         i->thread_info.soft_volume = i->soft_volume;
1294         pa_sink_input_request_rewind(i, 0, TRUE, FALSE, FALSE);
1295     }
1296 }
1297
1298 /* Called from IO thread, except when it is not */
1299 int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {
1300     pa_sink *s = PA_SINK(o);
1301     pa_sink_assert_ref(s);
1302
1303     switch ((pa_sink_message_t) code) {
1304
1305         case PA_SINK_MESSAGE_ADD_INPUT: {
1306             pa_sink_input *i = PA_SINK_INPUT(userdata);
1307
1308             /* If you change anything here, make sure to change the
1309              * sink input handling a few lines down at
1310              * PA_SINK_MESSAGE_FINISH_MOVE, too. */
1311
1312             pa_hashmap_put(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index), pa_sink_input_ref(i));
1313
1314             /* Since the caller sleeps in pa_sink_input_put(), we can
1315              * safely access data outside of thread_info even though
1316              * it is mutable */
1317
1318             if ((i->thread_info.sync_prev = i->sync_prev)) {
1319                 pa_assert(i->sink == i->thread_info.sync_prev->sink);
1320                 pa_assert(i->sync_prev->sync_next == i);
1321                 i->thread_info.sync_prev->thread_info.sync_next = i;
1322             }
1323
1324             if ((i->thread_info.sync_next = i->sync_next)) {
1325                 pa_assert(i->sink == i->thread_info.sync_next->sink);
1326                 pa_assert(i->sync_next->sync_prev == i);
1327                 i->thread_info.sync_next->thread_info.sync_prev = i;
1328             }
1329
1330             pa_assert(!i->thread_info.attached);
1331             i->thread_info.attached = TRUE;
1332
1333             if (i->attach)
1334                 i->attach(i);
1335
1336             pa_sink_input_set_state_within_thread(i, i->state);
1337
1338             /* The requested latency of the sink input needs to be
1339              * fixed up and then configured on the sink */
1340
1341             if (i->thread_info.requested_sink_latency != (pa_usec_t) -1)
1342                 pa_sink_input_set_requested_latency_within_thread(i, i->thread_info.requested_sink_latency);
1343
1344             pa_sink_input_update_max_rewind(i, s->thread_info.max_rewind);
1345             pa_sink_input_update_max_request(i, s->thread_info.max_request);
1346
1347             /* We don't rewind here automatically. This is left to the
1348              * sink input implementor because some sink inputs need a
1349              * slow start, i.e. need some time to buffer client
1350              * samples before beginning streaming. */
1351
1352             /* In flat volume mode we need to update the volume as
1353              * well */
1354             return o->process_msg(o, PA_SINK_MESSAGE_SET_VOLUME, NULL, 0, NULL);
1355         }
1356
1357         case PA_SINK_MESSAGE_REMOVE_INPUT: {
1358             pa_sink_input *i = PA_SINK_INPUT(userdata);
1359
1360             /* If you change anything here, make sure to change the
1361              * sink input handling a few lines down at
1362              * PA_SINK_MESSAGE_PREPAPRE_MOVE, too. */
1363
1364             if (i->detach)
1365                 i->detach(i);
1366
1367             pa_sink_input_set_state_within_thread(i, i->state);
1368
1369             pa_assert(i->thread_info.attached);
1370             i->thread_info.attached = FALSE;
1371
1372             /* Since the caller sleeps in pa_sink_input_unlink(),
1373              * we can safely access data outside of thread_info even
1374              * though it is mutable */
1375
1376             pa_assert(!i->sync_prev);
1377             pa_assert(!i->sync_next);
1378
1379             if (i->thread_info.sync_prev) {
1380                 i->thread_info.sync_prev->thread_info.sync_next = i->thread_info.sync_prev->sync_next;
1381                 i->thread_info.sync_prev = NULL;
1382             }
1383
1384             if (i->thread_info.sync_next) {
1385                 i->thread_info.sync_next->thread_info.sync_prev = i->thread_info.sync_next->sync_prev;
1386                 i->thread_info.sync_next = NULL;
1387             }
1388
1389             if (pa_hashmap_remove(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index)))
1390                 pa_sink_input_unref(i);
1391
1392             pa_sink_invalidate_requested_latency(s);
1393             pa_sink_request_rewind(s, (size_t) -1);
1394
1395             /* In flat volume mode we need to update the volume as
1396              * well */
1397             return o->process_msg(o, PA_SINK_MESSAGE_SET_VOLUME, NULL, 0, NULL);
1398         }
1399
1400         case PA_SINK_MESSAGE_START_MOVE: {
1401             pa_sink_input *i = PA_SINK_INPUT(userdata);
1402
1403             /* We don't support moving synchronized streams. */
1404             pa_assert(!i->sync_prev);
1405             pa_assert(!i->sync_next);
1406             pa_assert(!i->thread_info.sync_next);
1407             pa_assert(!i->thread_info.sync_prev);
1408
1409             if (i->thread_info.state != PA_SINK_INPUT_CORKED) {
1410                 pa_usec_t usec = 0;
1411                 size_t sink_nbytes, total_nbytes;
1412
1413                 /* Get the latency of the sink */
1414                 if (!(s->flags & PA_SINK_LATENCY) ||
1415                     PA_MSGOBJECT(s)->process_msg(PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_LATENCY, &usec, 0, NULL) < 0)
1416                     usec = 0;
1417
1418                 sink_nbytes = pa_usec_to_bytes(usec, &s->sample_spec);
1419                 total_nbytes = sink_nbytes + pa_memblockq_get_length(i->thread_info.render_memblockq);
1420
1421                 if (total_nbytes > 0) {
1422                     i->thread_info.rewrite_nbytes = i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, total_nbytes) : total_nbytes;
1423                     i->thread_info.rewrite_flush = TRUE;
1424                     pa_sink_input_process_rewind(i, sink_nbytes);
1425                 }
1426             }
1427
1428             if (i->detach)
1429                 i->detach(i);
1430
1431             pa_assert(i->thread_info.attached);
1432             i->thread_info.attached = FALSE;
1433
1434             /* Let's remove the sink input ...*/
1435             if (pa_hashmap_remove(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index)))
1436                 pa_sink_input_unref(i);
1437
1438             pa_sink_invalidate_requested_latency(s);
1439
1440             pa_log_debug("Requesting rewind due to started move");
1441             pa_sink_request_rewind(s, (size_t) -1);
1442
1443             /* In flat volume mode we need to update the volume as
1444              * well */
1445             return o->process_msg(o, PA_SINK_MESSAGE_SET_VOLUME, NULL, 0, NULL);
1446         }
1447
1448         case PA_SINK_MESSAGE_FINISH_MOVE: {
1449             pa_sink_input *i = PA_SINK_INPUT(userdata);
1450
1451             /* We don't support moving synchronized streams. */
1452             pa_assert(!i->sync_prev);
1453             pa_assert(!i->sync_next);
1454             pa_assert(!i->thread_info.sync_next);
1455             pa_assert(!i->thread_info.sync_prev);
1456
1457             pa_hashmap_put(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index), pa_sink_input_ref(i));
1458
1459             pa_assert(!i->thread_info.attached);
1460             i->thread_info.attached = TRUE;
1461
1462             if (i->attach)
1463                 i->attach(i);
1464
1465             if (i->thread_info.requested_sink_latency != (pa_usec_t) -1)
1466                 pa_sink_input_set_requested_latency_within_thread(i, i->thread_info.requested_sink_latency);
1467
1468             pa_sink_input_update_max_rewind(i, s->thread_info.max_rewind);
1469             pa_sink_input_update_max_request(i, s->thread_info.max_request);
1470
1471             if (i->thread_info.state != PA_SINK_INPUT_CORKED) {
1472                 pa_usec_t usec = 0;
1473                 size_t nbytes;
1474
1475                 /* Get the latency of the sink */
1476                 if (!(s->flags & PA_SINK_LATENCY) ||
1477                     PA_MSGOBJECT(s)->process_msg(PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_LATENCY, &usec, 0, NULL) < 0)
1478                     usec = 0;
1479
1480                 nbytes = pa_usec_to_bytes(usec, &s->sample_spec);
1481
1482                 if (nbytes > 0)
1483                     pa_sink_input_drop(i, nbytes);
1484
1485                 pa_log_debug("Requesting rewind due to finished move");
1486                 pa_sink_request_rewind(s, nbytes);
1487             }
1488
1489             /* In flat volume mode we need to update the volume as
1490              * well */
1491             return o->process_msg(o, PA_SINK_MESSAGE_SET_VOLUME, NULL, 0, NULL);
1492         }
1493
1494         case PA_SINK_MESSAGE_SET_VOLUME:
1495
1496             if (!pa_cvolume_equal(&s->thread_info.soft_volume, &s->soft_volume)) {
1497                 s->thread_info.soft_volume = s->soft_volume;
1498                 pa_sink_request_rewind(s, (size_t) -1);
1499             }
1500
1501             if (s->flags & PA_SINK_FLAT_VOLUME)
1502                 sync_input_volumes_within_thread(s);
1503
1504             return 0;
1505
1506         case PA_SINK_MESSAGE_GET_VOLUME:
1507             return 0;
1508
1509         case PA_SINK_MESSAGE_SET_MUTE:
1510
1511             if (s->thread_info.soft_muted != s->muted) {
1512                 s->thread_info.soft_muted = s->muted;
1513                 pa_sink_request_rewind(s, (size_t) -1);
1514             }
1515
1516             return 0;
1517
1518         case PA_SINK_MESSAGE_GET_MUTE:
1519             return 0;
1520
1521         case PA_SINK_MESSAGE_SET_STATE:
1522
1523             s->thread_info.state = PA_PTR_TO_UINT(userdata);
1524
1525             if (s->thread_info.state == PA_SINK_SUSPENDED)
1526                 s->thread_info.rewind_requested = FALSE;
1527
1528             return 0;
1529
1530         case PA_SINK_MESSAGE_DETACH:
1531
1532             /* Detach all streams */
1533             pa_sink_detach_within_thread(s);
1534             return 0;
1535
1536         case PA_SINK_MESSAGE_ATTACH:
1537
1538             /* Reattach all streams */
1539             pa_sink_attach_within_thread(s);
1540             return 0;
1541
1542         case PA_SINK_MESSAGE_GET_REQUESTED_LATENCY: {
1543
1544             pa_usec_t *usec = userdata;
1545             *usec = pa_sink_get_requested_latency_within_thread(s);
1546
1547             if (*usec == (pa_usec_t) -1)
1548                 *usec = s->thread_info.max_latency;
1549
1550             return 0;
1551         }
1552
1553         case PA_SINK_MESSAGE_SET_LATENCY_RANGE: {
1554             pa_usec_t *r = userdata;
1555
1556             pa_sink_update_latency_range(s, r[0], r[1]);
1557
1558             return 0;
1559         }
1560
1561         case PA_SINK_MESSAGE_GET_LATENCY_RANGE: {
1562             pa_usec_t *r = userdata;
1563
1564             r[0] = s->thread_info.min_latency;
1565             r[1] = s->thread_info.max_latency;
1566
1567             return 0;
1568         }
1569
1570         case PA_SINK_MESSAGE_GET_MAX_REWIND:
1571
1572             *((size_t*) userdata) = s->thread_info.max_rewind;
1573             return 0;
1574
1575         case PA_SINK_MESSAGE_GET_MAX_REQUEST:
1576
1577             *((size_t*) userdata) = s->thread_info.max_request;
1578             return 0;
1579
1580         case PA_SINK_MESSAGE_GET_LATENCY:
1581         case PA_SINK_MESSAGE_MAX:
1582             ;
1583     }
1584
1585     return -1;
1586 }
1587
1588 /* Called from main thread */
1589 int pa_sink_suspend_all(pa_core *c, pa_bool_t suspend) {
1590     pa_sink *sink;
1591     uint32_t idx;
1592     int ret = 0;
1593
1594     pa_core_assert_ref(c);
1595
1596     for (sink = PA_SINK(pa_idxset_first(c->sinks, &idx)); sink; sink = PA_SINK(pa_idxset_next(c->sinks, &idx)))
1597         ret -= pa_sink_suspend(sink, suspend) < 0;
1598
1599     return ret;
1600 }
1601
1602 /* Called from main thread */
1603 void pa_sink_detach(pa_sink *s) {
1604     pa_sink_assert_ref(s);
1605     pa_assert(PA_SINK_IS_LINKED(s->state));
1606
1607     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_DETACH, NULL, 0, NULL) == 0);
1608 }
1609
1610 /* Called from main thread */
1611 void pa_sink_attach(pa_sink *s) {
1612     pa_sink_assert_ref(s);
1613     pa_assert(PA_SINK_IS_LINKED(s->state));
1614
1615     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_ATTACH, NULL, 0, NULL) == 0);
1616 }
1617
1618 /* Called from IO thread */
1619 void pa_sink_detach_within_thread(pa_sink *s) {
1620     pa_sink_input *i;
1621     void *state = NULL;
1622
1623     pa_sink_assert_ref(s);
1624     pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
1625
1626     while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)))
1627         if (i->detach)
1628             i->detach(i);
1629
1630     if (s->monitor_source)
1631         pa_source_detach_within_thread(s->monitor_source);
1632 }
1633
1634 /* Called from IO thread */
1635 void pa_sink_attach_within_thread(pa_sink *s) {
1636     pa_sink_input *i;
1637     void *state = NULL;
1638
1639     pa_sink_assert_ref(s);
1640     pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
1641
1642     while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)))
1643         if (i->attach)
1644             i->attach(i);
1645
1646     if (s->monitor_source)
1647         pa_source_attach_within_thread(s->monitor_source);
1648 }
1649
1650 /* Called from IO thread */
1651 void pa_sink_request_rewind(pa_sink*s, size_t nbytes) {
1652     pa_sink_assert_ref(s);
1653     pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
1654
1655     if (s->thread_info.state == PA_SINK_SUSPENDED)
1656         return;
1657
1658     if (nbytes == (size_t) -1)
1659         nbytes = s->thread_info.max_rewind;
1660
1661     nbytes = PA_MIN(nbytes, s->thread_info.max_rewind);
1662
1663     if (s->thread_info.rewind_requested &&
1664         nbytes <= s->thread_info.rewind_nbytes)
1665         return;
1666
1667     s->thread_info.rewind_nbytes = nbytes;
1668     s->thread_info.rewind_requested = TRUE;
1669
1670     if (s->request_rewind)
1671         s->request_rewind(s);
1672 }
1673
1674 /* Called from IO thread */
1675 pa_usec_t pa_sink_get_requested_latency_within_thread(pa_sink *s) {
1676     pa_usec_t result = (pa_usec_t) -1;
1677     pa_sink_input *i;
1678     void *state = NULL;
1679     pa_usec_t monitor_latency;
1680
1681     pa_sink_assert_ref(s);
1682
1683     if (s->thread_info.requested_latency_valid)
1684         return s->thread_info.requested_latency;
1685
1686     while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)))
1687
1688         if (i->thread_info.requested_sink_latency != (pa_usec_t) -1 &&
1689             (result == (pa_usec_t) -1 || result > i->thread_info.requested_sink_latency))
1690             result = i->thread_info.requested_sink_latency;
1691
1692     monitor_latency = pa_source_get_requested_latency_within_thread(s->monitor_source);
1693
1694     if (monitor_latency != (pa_usec_t) -1 &&
1695         (result == (pa_usec_t) -1 || result > monitor_latency))
1696         result = monitor_latency;
1697
1698     if (result != (pa_usec_t) -1) {
1699         if (s->thread_info.max_latency > 0 && result > s->thread_info.max_latency)
1700             result = s->thread_info.max_latency;
1701
1702         if (s->thread_info.min_latency > 0 && result < s->thread_info.min_latency)
1703             result = s->thread_info.min_latency;
1704     }
1705
1706     s->thread_info.requested_latency = result;
1707     s->thread_info.requested_latency_valid = TRUE;
1708
1709     return result;
1710 }
1711
1712 /* Called from main thread */
1713 pa_usec_t pa_sink_get_requested_latency(pa_sink *s) {
1714     pa_usec_t usec = 0;
1715
1716     pa_sink_assert_ref(s);
1717     pa_assert(PA_SINK_IS_LINKED(s->state));
1718
1719     if (s->state == PA_SINK_SUSPENDED)
1720         return 0;
1721
1722     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);
1723     return usec;
1724 }
1725
1726 /* Called from IO thread */
1727 void pa_sink_set_max_rewind(pa_sink *s, size_t max_rewind) {
1728     pa_sink_input *i;
1729     void *state = NULL;
1730
1731     pa_sink_assert_ref(s);
1732
1733     if (max_rewind == s->thread_info.max_rewind)
1734         return;
1735
1736     s->thread_info.max_rewind = max_rewind;
1737
1738     if (PA_SINK_IS_LINKED(s->thread_info.state)) {
1739         while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)))
1740             pa_sink_input_update_max_rewind(i, s->thread_info.max_rewind);
1741     }
1742
1743     if (s->monitor_source)
1744         pa_source_set_max_rewind(s->monitor_source, s->thread_info.max_rewind);
1745 }
1746
1747 /* Called from IO thread */
1748 void pa_sink_set_max_request(pa_sink *s, size_t max_request) {
1749     void *state = NULL;
1750
1751     pa_sink_assert_ref(s);
1752
1753     if (max_request == s->thread_info.max_request)
1754         return;
1755
1756     s->thread_info.max_request = max_request;
1757
1758     if (PA_SINK_IS_LINKED(s->thread_info.state)) {
1759         pa_sink_input *i;
1760
1761         while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)))
1762             pa_sink_input_update_max_request(i, s->thread_info.max_request);
1763     }
1764 }
1765
1766 /* Called from IO thread */
1767 void pa_sink_invalidate_requested_latency(pa_sink *s) {
1768     pa_sink_input *i;
1769     void *state = NULL;
1770
1771     pa_sink_assert_ref(s);
1772
1773     s->thread_info.requested_latency_valid = FALSE;
1774
1775     if (s->update_requested_latency)
1776         s->update_requested_latency(s);
1777
1778     while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)))
1779         if (i->update_sink_requested_latency)
1780             i->update_sink_requested_latency(i);
1781 }
1782
1783 /* Called from main thread */
1784 void pa_sink_set_latency_range(pa_sink *s, pa_usec_t min_latency, pa_usec_t max_latency) {
1785     pa_sink_assert_ref(s);
1786
1787     /* min_latency == 0:           no limit
1788      * min_latency == (size_t) -1: default limit
1789      * min_latency anything else:  specified limit
1790      *
1791      * Similar for max_latency */
1792
1793     if (min_latency == (pa_usec_t) -1)
1794         min_latency = DEFAULT_MIN_LATENCY;
1795
1796     if (max_latency == (pa_usec_t) -1)
1797         max_latency = min_latency;
1798
1799     pa_assert(!min_latency || !max_latency ||
1800               min_latency <= max_latency);
1801
1802     if (PA_SINK_IS_LINKED(s->state)) {
1803         pa_usec_t r[2];
1804
1805         r[0] = min_latency;
1806         r[1] = max_latency;
1807
1808         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_LATENCY_RANGE, r, 0, NULL) == 0);
1809     } else {
1810         s->thread_info.min_latency = min_latency;
1811         s->thread_info.max_latency = max_latency;
1812
1813         s->monitor_source->thread_info.min_latency = min_latency;
1814         s->monitor_source->thread_info.max_latency = max_latency;
1815
1816         s->thread_info.requested_latency_valid = s->monitor_source->thread_info.requested_latency_valid = FALSE;
1817     }
1818 }
1819
1820 /* Called from main thread */
1821 void pa_sink_get_latency_range(pa_sink *s, pa_usec_t *min_latency, pa_usec_t *max_latency) {
1822    pa_sink_assert_ref(s);
1823    pa_assert(min_latency);
1824    pa_assert(max_latency);
1825
1826    if (PA_SINK_IS_LINKED(s->state)) {
1827        pa_usec_t r[2] = { 0, 0 };
1828
1829        pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_LATENCY_RANGE, r, 0, NULL) == 0);
1830
1831        *min_latency = r[0];
1832        *max_latency = r[1];
1833    } else {
1834        *min_latency = s->thread_info.min_latency;
1835        *max_latency = s->thread_info.max_latency;
1836    }
1837 }
1838
1839 /* Called from IO thread */
1840 void pa_sink_update_latency_range(pa_sink *s, pa_usec_t min_latency, pa_usec_t max_latency) {
1841     pa_sink_input *i;
1842     void *state = NULL;
1843
1844     pa_sink_assert_ref(s);
1845
1846     s->thread_info.min_latency = min_latency;
1847     s->thread_info.max_latency = max_latency;
1848
1849     while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)))
1850         if (i->update_sink_latency_range)
1851             i->update_sink_latency_range(i);
1852
1853     pa_sink_invalidate_requested_latency(s);
1854
1855     pa_source_update_latency_range(s->monitor_source, min_latency, max_latency);
1856 }
1857
1858 /* Called from main context */
1859 size_t pa_sink_get_max_rewind(pa_sink *s) {
1860     size_t r;
1861     pa_sink_assert_ref(s);
1862
1863     if (!PA_SINK_IS_LINKED(s->state))
1864         return s->thread_info.max_rewind;
1865
1866     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_MAX_REWIND, &r, 0, NULL) == 0);
1867
1868     return r;
1869 }
1870
1871 /* Called from main context */
1872 size_t pa_sink_get_max_request(pa_sink *s) {
1873     size_t r;
1874     pa_sink_assert_ref(s);
1875
1876     if (!PA_SINK_IS_LINKED(s->state))
1877         return s->thread_info.max_request;
1878
1879     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_MAX_REQUEST, &r, 0, NULL) == 0);
1880
1881     return r;
1882 }