Merge branch 'master-tx'
[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         pa_sw_cvolume_multiply(&i->soft_volume, &i->soft_volume, &i->volume_factor);
994
995         /* Hooks have the ability to play games with i->soft_volume */
996         pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_INPUT_SET_VOLUME], i);
997
998         /* We don't issue PA_SINK_INPUT_MESSAGE_SET_VOLUME because
999          * we want the update to have atomically with the sink
1000          * volume update, hence we do it within the
1001          * pa_sink_set_flat_volume() call below*/
1002     }
1003 }
1004
1005 /* Called from main thread */
1006 void pa_sink_propagate_flat_volume(pa_sink *s, const pa_cvolume *old_volume) {
1007     pa_sink_input *i;
1008     uint32_t idx;
1009
1010     pa_sink_assert_ref(s);
1011     pa_assert(old_volume);
1012     pa_assert(PA_SINK_IS_LINKED(s->state));
1013     pa_assert(s->flags & PA_SINK_FLAT_VOLUME);
1014
1015     /* This is called whenever the sink volume changes that is not
1016      * caused by a sink input volume change. We need to fix up the
1017      * sink input volumes accordingly */
1018
1019     for (i = PA_SINK_INPUT(pa_idxset_first(s->inputs, &idx)); i; i = PA_SINK_INPUT(pa_idxset_next(s->inputs, &idx))) {
1020         pa_cvolume remapped_old_volume, remapped_new_volume, fixed_volume;
1021         unsigned c;
1022
1023         remapped_new_volume = s->virtual_volume;
1024         pa_cvolume_remap(&remapped_new_volume, &s->channel_map, &i->channel_map);
1025
1026         remapped_old_volume = *old_volume;
1027         pa_cvolume_remap(&remapped_old_volume, &s->channel_map, &i->channel_map);
1028
1029         for (c = 0; c < i->sample_spec.channels; c++)
1030
1031             if (remapped_old_volume.values[c] == PA_VOLUME_MUTED)
1032                 fixed_volume.values[c] = PA_VOLUME_MUTED;
1033             else
1034                 fixed_volume.values[c] = (pa_volume_t)
1035                     ((uint64_t) i->virtual_volume.values[c] *
1036                      (uint64_t) remapped_new_volume.values[c] /
1037                      (uint64_t) remapped_old_volume.values[c]);
1038
1039         fixed_volume.channels = i->virtual_volume.channels;
1040
1041         if (!pa_cvolume_equal(&fixed_volume, &i->virtual_volume)) {
1042             i->virtual_volume = fixed_volume;
1043
1044             /* The virtual volume changed, let's tell people so */
1045             pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1046         }
1047     }
1048 }
1049
1050 /* Called from main thread */
1051 void pa_sink_set_volume(pa_sink *s, const pa_cvolume *volume, pa_bool_t propagate, pa_bool_t sendmsg) {
1052     pa_cvolume old_virtual_volume;
1053     pa_bool_t virtual_volume_changed;
1054
1055     pa_sink_assert_ref(s);
1056     pa_assert(PA_SINK_IS_LINKED(s->state));
1057     pa_assert(volume);
1058     pa_assert(pa_cvolume_valid(volume));
1059     pa_assert(pa_cvolume_compatible(volume, &s->sample_spec));
1060
1061     old_virtual_volume = s->virtual_volume;
1062     s->virtual_volume = *volume;
1063     virtual_volume_changed = !pa_cvolume_equal(&old_virtual_volume, &s->virtual_volume);
1064
1065     /* Propagate this volume change back to the inputs */
1066     if (virtual_volume_changed)
1067         if (propagate && (s->flags & PA_SINK_FLAT_VOLUME))
1068             pa_sink_propagate_flat_volume(s, &old_virtual_volume);
1069
1070     if (s->set_volume) {
1071         /* If we have a function set_volume(), then we do not apply a
1072          * soft volume by default. However, set_volume() is apply one
1073          * to s->soft_volume */
1074
1075         pa_cvolume_reset(&s->soft_volume, s->sample_spec.channels);
1076         s->set_volume(s);
1077
1078     } else
1079         /* If we have no function set_volume(), then the soft volume
1080          * becomes the virtual volume */
1081         s->soft_volume = s->virtual_volume;
1082
1083     /* This tells the sink that soft and/or virtual volume changed */
1084     if (sendmsg)
1085         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_VOLUME, NULL, 0, NULL) == 0);
1086
1087     if (virtual_volume_changed)
1088         pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
1089 }
1090
1091 /* Called from main thread. Only to be called by sink implementor */
1092 void pa_sink_set_soft_volume(pa_sink *s, const pa_cvolume *volume) {
1093     pa_sink_assert_ref(s);
1094     pa_assert(volume);
1095
1096     s->soft_volume = *volume;
1097
1098     if (PA_SINK_IS_LINKED(s->state))
1099         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_VOLUME, NULL, 0, NULL) == 0);
1100     else
1101         s->thread_info.soft_volume = *volume;
1102 }
1103
1104 /* Called from main thread */
1105 const pa_cvolume *pa_sink_get_volume(pa_sink *s, pa_bool_t force_refresh) {
1106     pa_sink_assert_ref(s);
1107
1108     if (s->refresh_volume || force_refresh) {
1109         struct pa_cvolume old_virtual_volume = s->virtual_volume;
1110
1111         if (s->get_volume)
1112             s->get_volume(s);
1113
1114         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_VOLUME, NULL, 0, NULL) == 0);
1115
1116         if (!pa_cvolume_equal(&old_virtual_volume, &s->virtual_volume)) {
1117
1118             if (s->flags & PA_SINK_FLAT_VOLUME)
1119                 pa_sink_propagate_flat_volume(s, &old_virtual_volume);
1120
1121             pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
1122         }
1123     }
1124
1125     return &s->virtual_volume;
1126 }
1127
1128 /* Called from main thread */
1129 void pa_sink_set_mute(pa_sink *s, pa_bool_t mute) {
1130     pa_bool_t old_muted;
1131
1132     pa_sink_assert_ref(s);
1133     pa_assert(PA_SINK_IS_LINKED(s->state));
1134
1135     old_muted = s->muted;
1136     s->muted = mute;
1137
1138     if (s->set_mute)
1139         s->set_mute(s);
1140
1141     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_MUTE, NULL, 0, NULL) == 0);
1142
1143     if (old_muted != s->muted)
1144         pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
1145 }
1146
1147 /* Called from main thread */
1148 pa_bool_t pa_sink_get_mute(pa_sink *s, pa_bool_t force_refresh) {
1149
1150     pa_sink_assert_ref(s);
1151
1152     if (s->refresh_muted || force_refresh) {
1153         pa_bool_t old_muted = s->muted;
1154
1155         if (s->get_mute)
1156             s->get_mute(s);
1157
1158         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_MUTE, NULL, 0, NULL) == 0);
1159
1160         if (old_muted != s->muted)
1161             pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
1162     }
1163
1164     return s->muted;
1165 }
1166
1167 /* Called from main thread */
1168 pa_bool_t pa_sink_update_proplist(pa_sink *s, pa_update_mode_t mode, pa_proplist *p) {
1169
1170     pa_sink_assert_ref(s);
1171     pa_assert(p);
1172
1173     pa_proplist_update(s->proplist, mode, p);
1174
1175     if (PA_SINK_IS_LINKED(s->state)) {
1176         pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_PROPLIST_CHANGED], s);
1177         pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
1178     }
1179
1180     return TRUE;
1181 }
1182
1183 /* Called from main thread */
1184 void pa_sink_set_description(pa_sink *s, const char *description) {
1185     const char *old;
1186     pa_sink_assert_ref(s);
1187
1188     if (!description && !pa_proplist_contains(s->proplist, PA_PROP_DEVICE_DESCRIPTION))
1189         return;
1190
1191     old = pa_proplist_gets(s->proplist, PA_PROP_DEVICE_DESCRIPTION);
1192
1193     if (old && description && !strcmp(old, description))
1194         return;
1195
1196     if (description)
1197         pa_proplist_sets(s->proplist, PA_PROP_DEVICE_DESCRIPTION, description);
1198     else
1199         pa_proplist_unset(s->proplist, PA_PROP_DEVICE_DESCRIPTION);
1200
1201     if (s->monitor_source) {
1202         char *n;
1203
1204         n = pa_sprintf_malloc("Monitor Source of %s", description ? description : s->name);
1205         pa_source_set_description(s->monitor_source, n);
1206         pa_xfree(n);
1207     }
1208
1209     if (PA_SINK_IS_LINKED(s->state)) {
1210         pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
1211         pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_PROPLIST_CHANGED], s);
1212     }
1213 }
1214
1215 /* Called from main thread */
1216 unsigned pa_sink_linked_by(pa_sink *s) {
1217     unsigned ret;
1218
1219     pa_sink_assert_ref(s);
1220     pa_assert(PA_SINK_IS_LINKED(s->state));
1221
1222     ret = pa_idxset_size(s->inputs);
1223
1224     /* We add in the number of streams connected to us here. Please
1225      * note the asymmmetry to pa_sink_used_by()! */
1226
1227     if (s->monitor_source)
1228         ret += pa_source_linked_by(s->monitor_source);
1229
1230     return ret;
1231 }
1232
1233 /* Called from main thread */
1234 unsigned pa_sink_used_by(pa_sink *s) {
1235     unsigned ret;
1236
1237     pa_sink_assert_ref(s);
1238     pa_assert(PA_SINK_IS_LINKED(s->state));
1239
1240     ret = pa_idxset_size(s->inputs);
1241     pa_assert(ret >= s->n_corked);
1242
1243     /* Streams connected to our monitor source do not matter for
1244      * pa_sink_used_by()!.*/
1245
1246     return ret - s->n_corked;
1247 }
1248
1249 /* Called from main thread */
1250 unsigned pa_sink_check_suspend(pa_sink *s) {
1251     unsigned ret;
1252     pa_sink_input *i;
1253     uint32_t idx;
1254
1255     pa_sink_assert_ref(s);
1256
1257     if (!PA_SINK_IS_LINKED(s->state))
1258         return 0;
1259
1260     ret = 0;
1261
1262     for (i = PA_SINK_INPUT(pa_idxset_first(s->inputs, &idx)); i; i = PA_SINK_INPUT(pa_idxset_next(s->inputs, &idx))) {
1263         pa_sink_input_state_t st;
1264
1265         st = pa_sink_input_get_state(i);
1266         pa_assert(PA_SINK_INPUT_IS_LINKED(st));
1267
1268         if (st == PA_SINK_INPUT_CORKED)
1269             continue;
1270
1271         if (i->flags & PA_SINK_INPUT_DONT_INHIBIT_AUTO_SUSPEND)
1272             continue;
1273
1274         ret ++;
1275     }
1276
1277     if (s->monitor_source)
1278         ret += pa_source_check_suspend(s->monitor_source);
1279
1280     return ret;
1281 }
1282
1283 /* Called from the IO thread */
1284 static void sync_input_volumes_within_thread(pa_sink *s) {
1285     pa_sink_input *i;
1286     void *state = NULL;
1287
1288     pa_sink_assert_ref(s);
1289
1290     while ((i = PA_SINK_INPUT(pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)))) {
1291         if (pa_cvolume_equal(&i->thread_info.soft_volume, &i->soft_volume))
1292             continue;
1293
1294         i->thread_info.soft_volume = i->soft_volume;
1295         pa_sink_input_request_rewind(i, 0, TRUE, FALSE, FALSE);
1296     }
1297 }
1298
1299 /* Called from IO thread, except when it is not */
1300 int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {
1301     pa_sink *s = PA_SINK(o);
1302     pa_sink_assert_ref(s);
1303
1304     switch ((pa_sink_message_t) code) {
1305
1306         case PA_SINK_MESSAGE_ADD_INPUT: {
1307             pa_sink_input *i = PA_SINK_INPUT(userdata);
1308
1309             /* If you change anything here, make sure to change the
1310              * sink input handling a few lines down at
1311              * PA_SINK_MESSAGE_FINISH_MOVE, too. */
1312
1313             pa_hashmap_put(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index), pa_sink_input_ref(i));
1314
1315             /* Since the caller sleeps in pa_sink_input_put(), we can
1316              * safely access data outside of thread_info even though
1317              * it is mutable */
1318
1319             if ((i->thread_info.sync_prev = i->sync_prev)) {
1320                 pa_assert(i->sink == i->thread_info.sync_prev->sink);
1321                 pa_assert(i->sync_prev->sync_next == i);
1322                 i->thread_info.sync_prev->thread_info.sync_next = i;
1323             }
1324
1325             if ((i->thread_info.sync_next = i->sync_next)) {
1326                 pa_assert(i->sink == i->thread_info.sync_next->sink);
1327                 pa_assert(i->sync_next->sync_prev == i);
1328                 i->thread_info.sync_next->thread_info.sync_prev = i;
1329             }
1330
1331             pa_assert(!i->thread_info.attached);
1332             i->thread_info.attached = TRUE;
1333
1334             if (i->attach)
1335                 i->attach(i);
1336
1337             pa_sink_input_set_state_within_thread(i, i->state);
1338
1339             /* The requested latency of the sink input needs to be
1340              * fixed up and then configured on the sink */
1341
1342             if (i->thread_info.requested_sink_latency != (pa_usec_t) -1)
1343                 pa_sink_input_set_requested_latency_within_thread(i, i->thread_info.requested_sink_latency);
1344
1345             pa_sink_input_update_max_rewind(i, s->thread_info.max_rewind);
1346             pa_sink_input_update_max_request(i, s->thread_info.max_request);
1347
1348             /* We don't rewind here automatically. This is left to the
1349              * sink input implementor because some sink inputs need a
1350              * slow start, i.e. need some time to buffer client
1351              * samples before beginning streaming. */
1352
1353             /* In flat volume mode we need to update the volume as
1354              * well */
1355             return o->process_msg(o, PA_SINK_MESSAGE_SET_VOLUME, NULL, 0, NULL);
1356         }
1357
1358         case PA_SINK_MESSAGE_REMOVE_INPUT: {
1359             pa_sink_input *i = PA_SINK_INPUT(userdata);
1360
1361             /* If you change anything here, make sure to change the
1362              * sink input handling a few lines down at
1363              * PA_SINK_MESSAGE_PREPAPRE_MOVE, too. */
1364
1365             if (i->detach)
1366                 i->detach(i);
1367
1368             pa_sink_input_set_state_within_thread(i, i->state);
1369
1370             pa_assert(i->thread_info.attached);
1371             i->thread_info.attached = FALSE;
1372
1373             /* Since the caller sleeps in pa_sink_input_unlink(),
1374              * we can safely access data outside of thread_info even
1375              * though it is mutable */
1376
1377             pa_assert(!i->sync_prev);
1378             pa_assert(!i->sync_next);
1379
1380             if (i->thread_info.sync_prev) {
1381                 i->thread_info.sync_prev->thread_info.sync_next = i->thread_info.sync_prev->sync_next;
1382                 i->thread_info.sync_prev = NULL;
1383             }
1384
1385             if (i->thread_info.sync_next) {
1386                 i->thread_info.sync_next->thread_info.sync_prev = i->thread_info.sync_next->sync_prev;
1387                 i->thread_info.sync_next = NULL;
1388             }
1389
1390             if (pa_hashmap_remove(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index)))
1391                 pa_sink_input_unref(i);
1392
1393             pa_sink_invalidate_requested_latency(s);
1394             pa_sink_request_rewind(s, (size_t) -1);
1395
1396             /* In flat volume mode we need to update the volume as
1397              * well */
1398             return o->process_msg(o, PA_SINK_MESSAGE_SET_VOLUME, NULL, 0, NULL);
1399         }
1400
1401         case PA_SINK_MESSAGE_START_MOVE: {
1402             pa_sink_input *i = PA_SINK_INPUT(userdata);
1403
1404             /* We don't support moving synchronized streams. */
1405             pa_assert(!i->sync_prev);
1406             pa_assert(!i->sync_next);
1407             pa_assert(!i->thread_info.sync_next);
1408             pa_assert(!i->thread_info.sync_prev);
1409
1410             if (i->thread_info.state != PA_SINK_INPUT_CORKED) {
1411                 pa_usec_t usec = 0;
1412                 size_t sink_nbytes, total_nbytes;
1413
1414                 /* Get the latency of the sink */
1415                 if (!(s->flags & PA_SINK_LATENCY) ||
1416                     PA_MSGOBJECT(s)->process_msg(PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_LATENCY, &usec, 0, NULL) < 0)
1417                     usec = 0;
1418
1419                 sink_nbytes = pa_usec_to_bytes(usec, &s->sample_spec);
1420                 total_nbytes = sink_nbytes + pa_memblockq_get_length(i->thread_info.render_memblockq);
1421
1422                 if (total_nbytes > 0) {
1423                     i->thread_info.rewrite_nbytes = i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, total_nbytes) : total_nbytes;
1424                     i->thread_info.rewrite_flush = TRUE;
1425                     pa_sink_input_process_rewind(i, sink_nbytes);
1426                 }
1427             }
1428
1429             if (i->detach)
1430                 i->detach(i);
1431
1432             pa_assert(i->thread_info.attached);
1433             i->thread_info.attached = FALSE;
1434
1435             /* Let's remove the sink input ...*/
1436             if (pa_hashmap_remove(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index)))
1437                 pa_sink_input_unref(i);
1438
1439             pa_sink_invalidate_requested_latency(s);
1440
1441             pa_log_debug("Requesting rewind due to started move");
1442             pa_sink_request_rewind(s, (size_t) -1);
1443
1444             /* In flat volume mode we need to update the volume as
1445              * well */
1446             return o->process_msg(o, PA_SINK_MESSAGE_SET_VOLUME, NULL, 0, NULL);
1447         }
1448
1449         case PA_SINK_MESSAGE_FINISH_MOVE: {
1450             pa_sink_input *i = PA_SINK_INPUT(userdata);
1451
1452             /* We don't support moving synchronized streams. */
1453             pa_assert(!i->sync_prev);
1454             pa_assert(!i->sync_next);
1455             pa_assert(!i->thread_info.sync_next);
1456             pa_assert(!i->thread_info.sync_prev);
1457
1458             pa_hashmap_put(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index), pa_sink_input_ref(i));
1459
1460             pa_assert(!i->thread_info.attached);
1461             i->thread_info.attached = TRUE;
1462
1463             if (i->attach)
1464                 i->attach(i);
1465
1466             if (i->thread_info.requested_sink_latency != (pa_usec_t) -1)
1467                 pa_sink_input_set_requested_latency_within_thread(i, i->thread_info.requested_sink_latency);
1468
1469             pa_sink_input_update_max_rewind(i, s->thread_info.max_rewind);
1470             pa_sink_input_update_max_request(i, s->thread_info.max_request);
1471
1472             if (i->thread_info.state != PA_SINK_INPUT_CORKED) {
1473                 pa_usec_t usec = 0;
1474                 size_t nbytes;
1475
1476                 /* Get the latency of the sink */
1477                 if (!(s->flags & PA_SINK_LATENCY) ||
1478                     PA_MSGOBJECT(s)->process_msg(PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_LATENCY, &usec, 0, NULL) < 0)
1479                     usec = 0;
1480
1481                 nbytes = pa_usec_to_bytes(usec, &s->sample_spec);
1482
1483                 if (nbytes > 0)
1484                     pa_sink_input_drop(i, nbytes);
1485
1486                 pa_log_debug("Requesting rewind due to finished move");
1487                 pa_sink_request_rewind(s, nbytes);
1488             }
1489
1490             /* In flat volume mode we need to update the volume as
1491              * well */
1492             return o->process_msg(o, PA_SINK_MESSAGE_SET_VOLUME, NULL, 0, NULL);
1493         }
1494
1495         case PA_SINK_MESSAGE_SET_VOLUME:
1496
1497             if (!pa_cvolume_equal(&s->thread_info.soft_volume, &s->soft_volume)) {
1498                 s->thread_info.soft_volume = s->soft_volume;
1499                 pa_sink_request_rewind(s, (size_t) -1);
1500             }
1501
1502             if (s->flags & PA_SINK_FLAT_VOLUME)
1503                 sync_input_volumes_within_thread(s);
1504
1505             return 0;
1506
1507         case PA_SINK_MESSAGE_GET_VOLUME:
1508             return 0;
1509
1510         case PA_SINK_MESSAGE_SET_MUTE:
1511
1512             if (s->thread_info.soft_muted != s->muted) {
1513                 s->thread_info.soft_muted = s->muted;
1514                 pa_sink_request_rewind(s, (size_t) -1);
1515             }
1516
1517             return 0;
1518
1519         case PA_SINK_MESSAGE_GET_MUTE:
1520             return 0;
1521
1522         case PA_SINK_MESSAGE_SET_STATE:
1523
1524             s->thread_info.state = PA_PTR_TO_UINT(userdata);
1525
1526             if (s->thread_info.state == PA_SINK_SUSPENDED)
1527                 s->thread_info.rewind_requested = FALSE;
1528
1529             return 0;
1530
1531         case PA_SINK_MESSAGE_DETACH:
1532
1533             /* Detach all streams */
1534             pa_sink_detach_within_thread(s);
1535             return 0;
1536
1537         case PA_SINK_MESSAGE_ATTACH:
1538
1539             /* Reattach all streams */
1540             pa_sink_attach_within_thread(s);
1541             return 0;
1542
1543         case PA_SINK_MESSAGE_GET_REQUESTED_LATENCY: {
1544
1545             pa_usec_t *usec = userdata;
1546             *usec = pa_sink_get_requested_latency_within_thread(s);
1547
1548             if (*usec == (pa_usec_t) -1)
1549                 *usec = s->thread_info.max_latency;
1550
1551             return 0;
1552         }
1553
1554         case PA_SINK_MESSAGE_SET_LATENCY_RANGE: {
1555             pa_usec_t *r = userdata;
1556
1557             pa_sink_update_latency_range(s, r[0], r[1]);
1558
1559             return 0;
1560         }
1561
1562         case PA_SINK_MESSAGE_GET_LATENCY_RANGE: {
1563             pa_usec_t *r = userdata;
1564
1565             r[0] = s->thread_info.min_latency;
1566             r[1] = s->thread_info.max_latency;
1567
1568             return 0;
1569         }
1570
1571         case PA_SINK_MESSAGE_GET_MAX_REWIND:
1572
1573             *((size_t*) userdata) = s->thread_info.max_rewind;
1574             return 0;
1575
1576         case PA_SINK_MESSAGE_GET_MAX_REQUEST:
1577
1578             *((size_t*) userdata) = s->thread_info.max_request;
1579             return 0;
1580
1581         case PA_SINK_MESSAGE_GET_LATENCY:
1582         case PA_SINK_MESSAGE_MAX:
1583             ;
1584     }
1585
1586     return -1;
1587 }
1588
1589 /* Called from main thread */
1590 int pa_sink_suspend_all(pa_core *c, pa_bool_t suspend) {
1591     pa_sink *sink;
1592     uint32_t idx;
1593     int ret = 0;
1594
1595     pa_core_assert_ref(c);
1596
1597     for (sink = PA_SINK(pa_idxset_first(c->sinks, &idx)); sink; sink = PA_SINK(pa_idxset_next(c->sinks, &idx)))
1598         ret -= pa_sink_suspend(sink, suspend) < 0;
1599
1600     return ret;
1601 }
1602
1603 /* Called from main thread */
1604 void pa_sink_detach(pa_sink *s) {
1605     pa_sink_assert_ref(s);
1606     pa_assert(PA_SINK_IS_LINKED(s->state));
1607
1608     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_DETACH, NULL, 0, NULL) == 0);
1609 }
1610
1611 /* Called from main thread */
1612 void pa_sink_attach(pa_sink *s) {
1613     pa_sink_assert_ref(s);
1614     pa_assert(PA_SINK_IS_LINKED(s->state));
1615
1616     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_ATTACH, NULL, 0, NULL) == 0);
1617 }
1618
1619 /* Called from IO thread */
1620 void pa_sink_detach_within_thread(pa_sink *s) {
1621     pa_sink_input *i;
1622     void *state = NULL;
1623
1624     pa_sink_assert_ref(s);
1625     pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
1626
1627     while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)))
1628         if (i->detach)
1629             i->detach(i);
1630
1631     if (s->monitor_source)
1632         pa_source_detach_within_thread(s->monitor_source);
1633 }
1634
1635 /* Called from IO thread */
1636 void pa_sink_attach_within_thread(pa_sink *s) {
1637     pa_sink_input *i;
1638     void *state = NULL;
1639
1640     pa_sink_assert_ref(s);
1641     pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
1642
1643     while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)))
1644         if (i->attach)
1645             i->attach(i);
1646
1647     if (s->monitor_source)
1648         pa_source_attach_within_thread(s->monitor_source);
1649 }
1650
1651 /* Called from IO thread */
1652 void pa_sink_request_rewind(pa_sink*s, size_t nbytes) {
1653     pa_sink_assert_ref(s);
1654     pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
1655
1656     if (s->thread_info.state == PA_SINK_SUSPENDED)
1657         return;
1658
1659     if (nbytes == (size_t) -1)
1660         nbytes = s->thread_info.max_rewind;
1661
1662     nbytes = PA_MIN(nbytes, s->thread_info.max_rewind);
1663
1664     if (s->thread_info.rewind_requested &&
1665         nbytes <= s->thread_info.rewind_nbytes)
1666         return;
1667
1668     s->thread_info.rewind_nbytes = nbytes;
1669     s->thread_info.rewind_requested = TRUE;
1670
1671     if (s->request_rewind)
1672         s->request_rewind(s);
1673 }
1674
1675 /* Called from IO thread */
1676 pa_usec_t pa_sink_get_requested_latency_within_thread(pa_sink *s) {
1677     pa_usec_t result = (pa_usec_t) -1;
1678     pa_sink_input *i;
1679     void *state = NULL;
1680     pa_usec_t monitor_latency;
1681
1682     pa_sink_assert_ref(s);
1683
1684     if (s->thread_info.requested_latency_valid)
1685         return s->thread_info.requested_latency;
1686
1687     while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)))
1688
1689         if (i->thread_info.requested_sink_latency != (pa_usec_t) -1 &&
1690             (result == (pa_usec_t) -1 || result > i->thread_info.requested_sink_latency))
1691             result = i->thread_info.requested_sink_latency;
1692
1693     monitor_latency = pa_source_get_requested_latency_within_thread(s->monitor_source);
1694
1695     if (monitor_latency != (pa_usec_t) -1 &&
1696         (result == (pa_usec_t) -1 || result > monitor_latency))
1697         result = monitor_latency;
1698
1699     if (result != (pa_usec_t) -1) {
1700         if (s->thread_info.max_latency > 0 && result > s->thread_info.max_latency)
1701             result = s->thread_info.max_latency;
1702
1703         if (s->thread_info.min_latency > 0 && result < s->thread_info.min_latency)
1704             result = s->thread_info.min_latency;
1705     }
1706
1707     s->thread_info.requested_latency = result;
1708     s->thread_info.requested_latency_valid = TRUE;
1709
1710     return result;
1711 }
1712
1713 /* Called from main thread */
1714 pa_usec_t pa_sink_get_requested_latency(pa_sink *s) {
1715     pa_usec_t usec = 0;
1716
1717     pa_sink_assert_ref(s);
1718     pa_assert(PA_SINK_IS_LINKED(s->state));
1719
1720     if (s->state == PA_SINK_SUSPENDED)
1721         return 0;
1722
1723     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);
1724     return usec;
1725 }
1726
1727 /* Called from IO thread */
1728 void pa_sink_set_max_rewind(pa_sink *s, size_t max_rewind) {
1729     pa_sink_input *i;
1730     void *state = NULL;
1731
1732     pa_sink_assert_ref(s);
1733
1734     if (max_rewind == s->thread_info.max_rewind)
1735         return;
1736
1737     s->thread_info.max_rewind = max_rewind;
1738
1739     if (PA_SINK_IS_LINKED(s->thread_info.state)) {
1740         while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)))
1741             pa_sink_input_update_max_rewind(i, s->thread_info.max_rewind);
1742     }
1743
1744     if (s->monitor_source)
1745         pa_source_set_max_rewind(s->monitor_source, s->thread_info.max_rewind);
1746 }
1747
1748 /* Called from IO thread */
1749 void pa_sink_set_max_request(pa_sink *s, size_t max_request) {
1750     void *state = NULL;
1751
1752     pa_sink_assert_ref(s);
1753
1754     if (max_request == s->thread_info.max_request)
1755         return;
1756
1757     s->thread_info.max_request = max_request;
1758
1759     if (PA_SINK_IS_LINKED(s->thread_info.state)) {
1760         pa_sink_input *i;
1761
1762         while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)))
1763             pa_sink_input_update_max_request(i, s->thread_info.max_request);
1764     }
1765 }
1766
1767 /* Called from IO thread */
1768 void pa_sink_invalidate_requested_latency(pa_sink *s) {
1769     pa_sink_input *i;
1770     void *state = NULL;
1771
1772     pa_sink_assert_ref(s);
1773
1774     s->thread_info.requested_latency_valid = FALSE;
1775
1776     if (s->update_requested_latency)
1777         s->update_requested_latency(s);
1778
1779     while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)))
1780         if (i->update_sink_requested_latency)
1781             i->update_sink_requested_latency(i);
1782 }
1783
1784 /* Called from main thread */
1785 void pa_sink_set_latency_range(pa_sink *s, pa_usec_t min_latency, pa_usec_t max_latency) {
1786     pa_sink_assert_ref(s);
1787
1788     /* min_latency == 0:           no limit
1789      * min_latency == (size_t) -1: default limit
1790      * min_latency anything else:  specified limit
1791      *
1792      * Similar for max_latency */
1793
1794     if (min_latency == (pa_usec_t) -1)
1795         min_latency = DEFAULT_MIN_LATENCY;
1796
1797     if (max_latency == (pa_usec_t) -1)
1798         max_latency = min_latency;
1799
1800     pa_assert(!min_latency || !max_latency ||
1801               min_latency <= max_latency);
1802
1803     if (PA_SINK_IS_LINKED(s->state)) {
1804         pa_usec_t r[2];
1805
1806         r[0] = min_latency;
1807         r[1] = max_latency;
1808
1809         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_LATENCY_RANGE, r, 0, NULL) == 0);
1810     } else {
1811         s->thread_info.min_latency = min_latency;
1812         s->thread_info.max_latency = max_latency;
1813
1814         s->monitor_source->thread_info.min_latency = min_latency;
1815         s->monitor_source->thread_info.max_latency = max_latency;
1816
1817         s->thread_info.requested_latency_valid = s->monitor_source->thread_info.requested_latency_valid = FALSE;
1818     }
1819 }
1820
1821 /* Called from main thread */
1822 void pa_sink_get_latency_range(pa_sink *s, pa_usec_t *min_latency, pa_usec_t *max_latency) {
1823    pa_sink_assert_ref(s);
1824    pa_assert(min_latency);
1825    pa_assert(max_latency);
1826
1827    if (PA_SINK_IS_LINKED(s->state)) {
1828        pa_usec_t r[2] = { 0, 0 };
1829
1830        pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_LATENCY_RANGE, r, 0, NULL) == 0);
1831
1832        *min_latency = r[0];
1833        *max_latency = r[1];
1834    } else {
1835        *min_latency = s->thread_info.min_latency;
1836        *max_latency = s->thread_info.max_latency;
1837    }
1838 }
1839
1840 /* Called from IO thread */
1841 void pa_sink_update_latency_range(pa_sink *s, pa_usec_t min_latency, pa_usec_t max_latency) {
1842     pa_sink_input *i;
1843     void *state = NULL;
1844
1845     pa_sink_assert_ref(s);
1846
1847     s->thread_info.min_latency = min_latency;
1848     s->thread_info.max_latency = max_latency;
1849
1850     while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)))
1851         if (i->update_sink_latency_range)
1852             i->update_sink_latency_range(i);
1853
1854     pa_sink_invalidate_requested_latency(s);
1855
1856     pa_source_update_latency_range(s->monitor_source, min_latency, max_latency);
1857 }
1858
1859 /* Called from main context */
1860 size_t pa_sink_get_max_rewind(pa_sink *s) {
1861     size_t r;
1862     pa_sink_assert_ref(s);
1863
1864     if (!PA_SINK_IS_LINKED(s->state))
1865         return s->thread_info.max_rewind;
1866
1867     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_MAX_REWIND, &r, 0, NULL) == 0);
1868
1869     return r;
1870 }
1871
1872 /* Called from main context */
1873 size_t pa_sink_get_max_request(pa_sink *s) {
1874     size_t r;
1875     pa_sink_assert_ref(s);
1876
1877     if (!PA_SINK_IS_LINKED(s->state))
1878         return s->thread_info.max_request;
1879
1880     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_MAX_REQUEST, &r, 0, NULL) == 0);
1881
1882     return r;
1883 }