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