Merge commit 'coling/lgpl21'
[platform/upstream/pulseaudio.git] / src / pulsecore / source.c
1 /***
2   This file is part of PulseAudio.
3
4   Copyright 2004-2006 Lennart Poettering
5   Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
6
7   PulseAudio is free software; you can redistribute it and/or modify
8   it under the terms of the GNU Lesser General Public License as published
9   by the Free Software Foundation; either version 2.1 of the License,
10   or (at your option) any later version.
11
12   PulseAudio is distributed in the hope that it will be useful, but
13   WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   General Public License for more details.
16
17   You should have received a copy of the GNU Lesser General Public License
18   along with PulseAudio; if not, write to the Free Software
19   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20   USA.
21 ***/
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30
31 #include <pulse/utf8.h>
32 #include <pulse/xmalloc.h>
33 #include <pulse/timeval.h>
34 #include <pulse/util.h>
35
36 #include <pulsecore/source-output.h>
37 #include <pulsecore/namereg.h>
38 #include <pulsecore/core-subscribe.h>
39 #include <pulsecore/log.h>
40 #include <pulsecore/sample-util.h>
41
42 #include "source.h"
43
44 #define DEFAULT_MIN_LATENCY (4*PA_USEC_PER_MSEC)
45
46 static PA_DEFINE_CHECK_TYPE(pa_source, pa_msgobject);
47
48 static void source_free(pa_object *o);
49
50 pa_source_new_data* pa_source_new_data_init(pa_source_new_data *data) {
51     pa_assert(data);
52
53     memset(data, 0, sizeof(*data));
54     data->proplist = pa_proplist_new();
55
56     return data;
57 }
58
59 void pa_source_new_data_set_name(pa_source_new_data *data, const char *name) {
60     pa_assert(data);
61
62     pa_xfree(data->name);
63     data->name = pa_xstrdup(name);
64 }
65
66 void pa_source_new_data_set_sample_spec(pa_source_new_data *data, const pa_sample_spec *spec) {
67     pa_assert(data);
68
69     if ((data->sample_spec_is_set = !!spec))
70         data->sample_spec = *spec;
71 }
72
73 void pa_source_new_data_set_channel_map(pa_source_new_data *data, const pa_channel_map *map) {
74     pa_assert(data);
75
76     if ((data->channel_map_is_set = !!map))
77         data->channel_map = *map;
78 }
79
80 void pa_source_new_data_set_volume(pa_source_new_data *data, const pa_cvolume *volume) {
81     pa_assert(data);
82
83     if ((data->volume_is_set = !!volume))
84         data->volume = *volume;
85 }
86
87 void pa_source_new_data_set_muted(pa_source_new_data *data, pa_bool_t mute) {
88     pa_assert(data);
89
90     data->muted_is_set = TRUE;
91     data->muted = !!mute;
92 }
93
94 void pa_source_new_data_done(pa_source_new_data *data) {
95     pa_assert(data);
96
97     pa_xfree(data->name);
98     pa_proplist_free(data->proplist);
99 }
100
101 /* Called from main context */
102 static void reset_callbacks(pa_source *s) {
103     pa_assert(s);
104
105     s->set_state = NULL;
106     s->get_volume = NULL;
107     s->set_volume = NULL;
108     s->get_mute = NULL;
109     s->set_mute = NULL;
110     s->update_requested_latency = NULL;
111 }
112
113 /* Called from main context */
114 pa_source* pa_source_new(
115         pa_core *core,
116         pa_source_new_data *data,
117         pa_source_flags_t flags) {
118
119     pa_source *s;
120     const char *name;
121     char st[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
122     char *pt;
123
124     pa_assert(core);
125     pa_assert(data);
126     pa_assert(data->name);
127
128     s = pa_msgobject_new(pa_source);
129
130     if (!(name = pa_namereg_register(core, data->name, PA_NAMEREG_SOURCE, s, data->namereg_fail))) {
131         pa_xfree(s);
132         return NULL;
133     }
134
135     pa_source_new_data_set_name(data, name);
136
137     if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_SOURCE_NEW], data) < 0) {
138         pa_xfree(s);
139         pa_namereg_unregister(core, name);
140         return NULL;
141     }
142
143     pa_return_null_if_fail(!data->driver || pa_utf8_valid(data->driver));
144     pa_return_null_if_fail(data->name && pa_utf8_valid(data->name) && data->name[0]);
145
146     pa_return_null_if_fail(data->sample_spec_is_set && pa_sample_spec_valid(&data->sample_spec));
147
148     if (!data->channel_map_is_set)
149         pa_return_null_if_fail(pa_channel_map_init_auto(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT));
150
151     pa_return_null_if_fail(pa_channel_map_valid(&data->channel_map));
152     pa_return_null_if_fail(data->channel_map.channels == data->sample_spec.channels);
153
154     if (!data->volume_is_set)
155         pa_cvolume_reset(&data->volume, data->sample_spec.channels);
156
157     pa_return_null_if_fail(pa_cvolume_valid(&data->volume));
158     pa_return_null_if_fail(data->volume.channels == data->sample_spec.channels);
159
160     if (!data->muted_is_set)
161         data->muted = FALSE;
162
163     if (data->card)
164         pa_proplist_update(data->proplist, PA_UPDATE_MERGE, data->card->proplist);
165
166     pa_device_init_description(data->proplist);
167     pa_device_init_icon(data->proplist, FALSE);
168
169     if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_SOURCE_FIXATE], data) < 0) {
170         pa_xfree(s);
171         pa_namereg_unregister(core, name);
172         return NULL;
173     }
174
175     s->parent.parent.free = source_free;
176     s->parent.process_msg = pa_source_process_msg;
177
178     s->core = core;
179     s->state = PA_SOURCE_INIT;
180     s->flags = flags;
181     s->name = pa_xstrdup(name);
182     s->proplist = pa_proplist_copy(data->proplist);
183     s->driver = pa_xstrdup(pa_path_get_filename(data->driver));
184     s->module = data->module;
185     s->card = data->card;
186
187     s->sample_spec = data->sample_spec;
188     s->channel_map = data->channel_map;
189
190     s->outputs = pa_idxset_new(NULL, NULL);
191     s->n_corked = 0;
192     s->monitor_of = NULL;
193
194     s->virtual_volume = data->volume;
195     pa_cvolume_reset(&s->soft_volume, s->sample_spec.channels);
196     s->base_volume = PA_VOLUME_NORM;
197     s->n_volume_steps = PA_VOLUME_NORM+1;
198     s->muted = data->muted;
199     s->refresh_volume = s->refresh_muted = FALSE;
200
201     reset_callbacks(s);
202     s->userdata = NULL;
203
204     s->asyncmsgq = NULL;
205     s->rtpoll = NULL;
206
207     pa_silence_memchunk_get(
208             &core->silence_cache,
209             core->mempool,
210             &s->silence,
211             &s->sample_spec,
212             0);
213
214     s->thread_info.outputs = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
215     s->thread_info.soft_volume = s->soft_volume;
216     s->thread_info.soft_muted = s->muted;
217     s->thread_info.state = s->state;
218     s->thread_info.max_rewind = 0;
219     s->thread_info.requested_latency_valid = FALSE;
220     s->thread_info.requested_latency = 0;
221     s->thread_info.min_latency = DEFAULT_MIN_LATENCY;
222     s->thread_info.max_latency = 0;
223
224     pa_assert_se(pa_idxset_put(core->sources, s, &s->index) >= 0);
225
226     if (s->card)
227         pa_assert_se(pa_idxset_put(s->card->sources, s, NULL) >= 0);
228
229     pt = pa_proplist_to_string_sep(s->proplist, "\n    ");
230     pa_log_info("Created source %u \"%s\" with sample spec %s and channel map %s\n    %s",
231                 s->index,
232                 s->name,
233                 pa_sample_spec_snprint(st, sizeof(st), &s->sample_spec),
234                 pa_channel_map_snprint(cm, sizeof(cm), &s->channel_map),
235                 pt);
236     pa_xfree(pt);
237
238     return s;
239 }
240
241 /* Called from main context */
242 static int source_set_state(pa_source *s, pa_source_state_t state) {
243     int ret;
244     pa_bool_t suspend_change;
245     pa_source_state_t original_state;
246
247     pa_assert(s);
248
249     if (s->state == state)
250         return 0;
251
252     original_state = s->state;
253
254     suspend_change =
255         (original_state == PA_SOURCE_SUSPENDED && PA_SOURCE_IS_OPENED(state)) ||
256         (PA_SOURCE_IS_OPENED(original_state) && state == PA_SOURCE_SUSPENDED);
257
258     if (s->set_state)
259         if ((ret = s->set_state(s, state)) < 0)
260             return ret;
261
262     if (s->asyncmsgq)
263         if ((ret = pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), 0, NULL)) < 0) {
264
265             if (s->set_state)
266                 s->set_state(s, original_state);
267
268             return ret;
269         }
270
271     s->state = state;
272
273     if (state != PA_SOURCE_UNLINKED) { /* if we enter UNLINKED state pa_source_unlink() will fire the apropriate events */
274         pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_STATE_CHANGED], s);
275         pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
276     }
277
278     if (suspend_change) {
279         pa_source_output *o;
280         uint32_t idx;
281
282         /* We're suspending or resuming, tell everyone about it */
283
284         for (o = PA_SOURCE_OUTPUT(pa_idxset_first(s->outputs, &idx)); o; o = PA_SOURCE_OUTPUT(pa_idxset_next(s->outputs, &idx)))
285             if (s->state == PA_SOURCE_SUSPENDED &&
286                 (o->flags & PA_SOURCE_OUTPUT_FAIL_ON_SUSPEND))
287                 pa_source_output_kill(o);
288             else if (o->suspend)
289                 o->suspend(o, state == PA_SOURCE_SUSPENDED);
290     }
291
292
293     return 0;
294 }
295
296 /* Called from main context */
297 void pa_source_put(pa_source *s) {
298     pa_source_assert_ref(s);
299
300     pa_assert(s->state == PA_SOURCE_INIT);
301
302     /* The following fields must be initialized properly when calling _put() */
303     pa_assert(s->asyncmsgq);
304     pa_assert(s->rtpoll);
305     pa_assert(!s->thread_info.min_latency || !s->thread_info.max_latency ||
306               s->thread_info.min_latency <= s->thread_info.max_latency);
307
308     if (!(s->flags & PA_SOURCE_HW_VOLUME_CTRL)) {
309         s->flags |= PA_SOURCE_DECIBEL_VOLUME;
310
311         s->thread_info.soft_volume = s->soft_volume;
312         s->thread_info.soft_muted = s->muted;
313     }
314
315     if (s->flags & PA_SOURCE_DECIBEL_VOLUME)
316         s->n_volume_steps = PA_VOLUME_NORM+1;
317
318     pa_assert_se(source_set_state(s, PA_SOURCE_IDLE) == 0);
319
320     pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_NEW, s->index);
321     pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_PUT], s);
322 }
323
324 /* Called from main context */
325 void pa_source_unlink(pa_source *s) {
326     pa_bool_t linked;
327     pa_source_output *o, *j = NULL;
328
329     pa_assert(s);
330
331     /* See pa_sink_unlink() for a couple of comments how this function
332      * works. */
333
334     linked = PA_SOURCE_IS_LINKED(s->state);
335
336     if (linked)
337         pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], s);
338
339     if (s->state != PA_SOURCE_UNLINKED)
340         pa_namereg_unregister(s->core, s->name);
341     pa_idxset_remove_by_data(s->core->sources, s, NULL);
342
343     if (s->card)
344         pa_idxset_remove_by_data(s->card->sources, s, NULL);
345
346     while ((o = pa_idxset_first(s->outputs, NULL))) {
347         pa_assert(o != j);
348         pa_source_output_kill(o);
349         j = o;
350     }
351
352     if (linked)
353         source_set_state(s, PA_SOURCE_UNLINKED);
354     else
355         s->state = PA_SOURCE_UNLINKED;
356
357     reset_callbacks(s);
358
359     if (linked) {
360         pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_REMOVE, s->index);
361         pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK_POST], s);
362     }
363 }
364
365 /* Called from main context */
366 static void source_free(pa_object *o) {
367     pa_source_output *so;
368     pa_source *s = PA_SOURCE(o);
369
370     pa_assert(s);
371     pa_assert(pa_source_refcnt(s) == 0);
372
373     if (PA_SOURCE_IS_LINKED(s->state))
374         pa_source_unlink(s);
375
376     pa_log_info("Freeing source %u \"%s\"", s->index, s->name);
377
378     pa_idxset_free(s->outputs, NULL, NULL);
379
380     while ((so = pa_hashmap_steal_first(s->thread_info.outputs)))
381         pa_source_output_unref(so);
382
383     pa_hashmap_free(s->thread_info.outputs, NULL, NULL);
384
385     if (s->silence.memblock)
386         pa_memblock_unref(s->silence.memblock);
387
388     pa_xfree(s->name);
389     pa_xfree(s->driver);
390
391     if (s->proplist)
392         pa_proplist_free(s->proplist);
393
394     pa_xfree(s);
395 }
396
397 /* Called from main context */
398 void pa_source_set_asyncmsgq(pa_source *s, pa_asyncmsgq *q) {
399     pa_source_assert_ref(s);
400
401     s->asyncmsgq = q;
402 }
403
404 /* Called from main context */
405 void pa_source_set_rtpoll(pa_source *s, pa_rtpoll *p) {
406     pa_source_assert_ref(s);
407
408     s->rtpoll = p;
409 }
410
411 /* Called from main context */
412 int pa_source_update_status(pa_source*s) {
413     pa_source_assert_ref(s);
414     pa_assert(PA_SOURCE_IS_LINKED(s->state));
415
416     if (s->state == PA_SOURCE_SUSPENDED)
417         return 0;
418
419     return source_set_state(s, pa_source_used_by(s) ? PA_SOURCE_RUNNING : PA_SOURCE_IDLE);
420 }
421
422 /* Called from main context */
423 int pa_source_suspend(pa_source *s, pa_bool_t suspend) {
424     pa_source_assert_ref(s);
425     pa_assert(PA_SOURCE_IS_LINKED(s->state));
426
427     if (suspend)
428         return source_set_state(s, PA_SOURCE_SUSPENDED);
429     else
430         return source_set_state(s, pa_source_used_by(s) ? PA_SOURCE_RUNNING : PA_SOURCE_IDLE);
431 }
432
433 /* Called from main context */
434 pa_queue *pa_source_move_all_start(pa_source *s) {
435     pa_queue *q;
436     pa_source_output *o, *n;
437     uint32_t idx;
438
439     pa_source_assert_ref(s);
440     pa_assert(PA_SOURCE_IS_LINKED(s->state));
441
442     q = pa_queue_new();
443
444     for (o = PA_SOURCE_OUTPUT(pa_idxset_first(s->outputs, &idx)); o; o = n) {
445         n = PA_SOURCE_OUTPUT(pa_idxset_next(s->outputs, &idx));
446
447         if (pa_source_output_start_move(o) >= 0)
448             pa_queue_push(q, pa_source_output_ref(o));
449     }
450
451     return q;
452 }
453
454 /* Called from main context */
455 void pa_source_move_all_finish(pa_source *s, pa_queue *q, pa_bool_t save) {
456     pa_source_output *o;
457
458     pa_source_assert_ref(s);
459     pa_assert(PA_SOURCE_IS_LINKED(s->state));
460     pa_assert(q);
461
462     while ((o = PA_SOURCE_OUTPUT(pa_queue_pop(q)))) {
463         if (pa_source_output_finish_move(o, s, save) < 0)
464             pa_source_output_kill(o);
465
466         pa_source_output_unref(o);
467     }
468
469     pa_queue_free(q, NULL, NULL);
470 }
471
472 /* Called from main context */
473 void pa_source_move_all_fail(pa_queue *q) {
474     pa_source_output *o;
475     pa_assert(q);
476
477     while ((o = PA_SOURCE_OUTPUT(pa_queue_pop(q)))) {
478         if (pa_hook_fire(&o->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_MOVE_FAIL], o) == PA_HOOK_OK) {
479             pa_source_output_kill(o);
480             pa_source_output_unref(o);
481         }
482     }
483
484     pa_queue_free(q, NULL, NULL);
485 }
486
487 /* Called from IO thread context */
488 void pa_source_process_rewind(pa_source *s, size_t nbytes) {
489     pa_source_output *o;
490     void *state = NULL;
491
492     pa_source_assert_ref(s);
493     pa_assert(PA_SOURCE_IS_LINKED(s->thread_info.state));
494
495     if (s->thread_info.state == PA_SOURCE_SUSPENDED)
496         return;
497
498     if (nbytes <= 0)
499         return;
500
501     pa_log_debug("Processing rewind...");
502
503     while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL))) {
504         pa_source_output_assert_ref(o);
505         pa_source_output_process_rewind(o, nbytes);
506     }
507 }
508
509 /* Called from IO thread context */
510 void pa_source_post(pa_source*s, const pa_memchunk *chunk) {
511     pa_source_output *o;
512     void *state = NULL;
513
514     pa_source_assert_ref(s);
515     pa_assert(PA_SOURCE_IS_LINKED(s->thread_info.state));
516     pa_assert(chunk);
517
518     if (s->thread_info.state == PA_SOURCE_SUSPENDED)
519         return;
520
521     if (s->thread_info.soft_muted || !pa_cvolume_is_norm(&s->thread_info.soft_volume)) {
522         pa_memchunk vchunk = *chunk;
523
524         pa_memblock_ref(vchunk.memblock);
525         pa_memchunk_make_writable(&vchunk, 0);
526
527         if (s->thread_info.soft_muted || pa_cvolume_is_muted(&s->thread_info.soft_volume))
528             pa_silence_memchunk(&vchunk, &s->sample_spec);
529         else
530             pa_volume_memchunk(&vchunk, &s->sample_spec, &s->thread_info.soft_volume);
531
532         while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL))) {
533             pa_source_output_assert_ref(o);
534
535             if (!o->thread_info.direct_on_input)
536                 pa_source_output_push(o, &vchunk);
537         }
538
539         pa_memblock_unref(vchunk.memblock);
540     } else {
541
542         while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL))) {
543             pa_source_output_assert_ref(o);
544
545             if (!o->thread_info.direct_on_input)
546                 pa_source_output_push(o, chunk);
547         }
548     }
549 }
550
551 /* Called from IO thread context */
552 void pa_source_post_direct(pa_source*s, pa_source_output *o, const pa_memchunk *chunk) {
553     pa_source_assert_ref(s);
554     pa_assert(PA_SOURCE_IS_LINKED(s->thread_info.state));
555     pa_source_output_assert_ref(o);
556     pa_assert(o->thread_info.direct_on_input);
557     pa_assert(chunk);
558
559     if (s->thread_info.state == PA_SOURCE_SUSPENDED)
560         return;
561
562     if (s->thread_info.soft_muted || !pa_cvolume_is_norm(&s->thread_info.soft_volume)) {
563         pa_memchunk vchunk = *chunk;
564
565         pa_memblock_ref(vchunk.memblock);
566         pa_memchunk_make_writable(&vchunk, 0);
567
568         if (s->thread_info.soft_muted || pa_cvolume_is_muted(&s->thread_info.soft_volume))
569             pa_silence_memchunk(&vchunk, &s->sample_spec);
570         else
571             pa_volume_memchunk(&vchunk, &s->sample_spec, &s->thread_info.soft_volume);
572
573         pa_source_output_push(o, &vchunk);
574
575         pa_memblock_unref(vchunk.memblock);
576     } else
577         pa_source_output_push(o, chunk);
578 }
579
580 /* Called from main thread */
581 pa_usec_t pa_source_get_latency(pa_source *s) {
582     pa_usec_t usec;
583
584     pa_source_assert_ref(s);
585     pa_assert(PA_SOURCE_IS_LINKED(s->state));
586
587     if (s->state == PA_SOURCE_SUSPENDED)
588         return 0;
589
590     if (!(s->flags & PA_SOURCE_LATENCY))
591         return 0;
592
593     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_LATENCY, &usec, 0, NULL) == 0);
594
595     return usec;
596 }
597
598 /* Called from main thread */
599 void pa_source_set_volume(pa_source *s, const pa_cvolume *volume) {
600     pa_cvolume old_virtual_volume;
601     pa_bool_t virtual_volume_changed;
602
603     pa_source_assert_ref(s);
604     pa_assert(PA_SOURCE_IS_LINKED(s->state));
605     pa_assert(volume);
606     pa_assert(pa_cvolume_valid(volume));
607     pa_assert(pa_cvolume_compatible(volume, &s->sample_spec));
608
609     old_virtual_volume = s->virtual_volume;
610     s->virtual_volume = *volume;
611     virtual_volume_changed = !pa_cvolume_equal(&old_virtual_volume, &s->virtual_volume);
612
613     if (s->set_volume) {
614         pa_cvolume_reset(&s->soft_volume, s->sample_spec.channels);
615         s->set_volume(s);
616     } else
617         s->soft_volume = s->virtual_volume;
618
619     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_VOLUME, NULL, 0, NULL) == 0);
620
621     if (virtual_volume_changed)
622         pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
623 }
624
625 /* Called from main thread. Only to be called by source implementor */
626 void pa_source_set_soft_volume(pa_source *s, const pa_cvolume *volume) {
627     pa_source_assert_ref(s);
628     pa_assert(volume);
629
630     if (PA_SOURCE_IS_LINKED(s->state))
631         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_VOLUME, NULL, 0, NULL) == 0);
632     else
633         s->thread_info.soft_volume = *volume;
634 }
635
636 /* Called from main thread */
637 const pa_cvolume *pa_source_get_volume(pa_source *s, pa_bool_t force_refresh) {
638     pa_source_assert_ref(s);
639     pa_assert(PA_SOURCE_IS_LINKED(s->state));
640
641     if (s->refresh_volume || force_refresh) {
642         pa_cvolume old_virtual_volume = s->virtual_volume;
643
644         if (s->get_volume)
645             s->get_volume(s);
646
647         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_VOLUME, NULL, 0, NULL) == 0);
648
649         if (!pa_cvolume_equal(&old_virtual_volume, &s->virtual_volume))
650             pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
651     }
652
653     return &s->virtual_volume;
654 }
655
656 /* Called from main thread */
657 void pa_source_set_mute(pa_source *s, pa_bool_t mute) {
658     pa_bool_t old_muted;
659
660     pa_source_assert_ref(s);
661     pa_assert(PA_SOURCE_IS_LINKED(s->state));
662
663     old_muted = s->muted;
664     s->muted = mute;
665
666     if (s->set_mute)
667         s->set_mute(s);
668
669     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_MUTE, NULL, 0, NULL) == 0);
670
671     if (old_muted != s->muted)
672         pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
673 }
674
675 /* Called from main thread */
676 pa_bool_t pa_source_get_mute(pa_source *s, pa_bool_t force_refresh) {
677
678     pa_source_assert_ref(s);
679     pa_assert(PA_SOURCE_IS_LINKED(s->state));
680
681     if (s->refresh_muted || force_refresh) {
682         pa_bool_t old_muted = s->muted;
683
684         if (s->get_mute)
685             s->get_mute(s);
686
687         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_MUTE, NULL, 0, NULL) == 0);
688
689         if (old_muted != s->muted)
690             pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
691     }
692
693     return s->muted;
694 }
695
696 /* Called from main thread */
697 pa_bool_t pa_source_update_proplist(pa_source *s, pa_update_mode_t mode, pa_proplist *p) {
698     pa_source_assert_ref(s);
699     pa_assert(p);
700
701     pa_proplist_update(s->proplist, mode, p);
702
703     if (PA_SOURCE_IS_LINKED(s->state)) {
704         pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_PROPLIST_CHANGED], s);
705         pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
706     }
707
708     return TRUE;
709 }
710
711 /* Called from main thread */
712 void pa_source_set_description(pa_source *s, const char *description) {
713     const char *old;
714     pa_source_assert_ref(s);
715
716     if (!description && !pa_proplist_contains(s->proplist, PA_PROP_DEVICE_DESCRIPTION))
717         return;
718
719     old = pa_proplist_gets(s->proplist, PA_PROP_DEVICE_DESCRIPTION);
720
721     if (old && description && !strcmp(old, description))
722         return;
723
724     if (description)
725         pa_proplist_sets(s->proplist, PA_PROP_DEVICE_DESCRIPTION, description);
726     else
727         pa_proplist_unset(s->proplist, PA_PROP_DEVICE_DESCRIPTION);
728
729     if (PA_SOURCE_IS_LINKED(s->state)) {
730         pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
731         pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_PROPLIST_CHANGED], s);
732     }
733 }
734
735 /* Called from main thread */
736 unsigned pa_source_linked_by(pa_source *s) {
737     pa_source_assert_ref(s);
738     pa_assert(PA_SOURCE_IS_LINKED(s->state));
739
740     return pa_idxset_size(s->outputs);
741 }
742
743 /* Called from main thread */
744 unsigned pa_source_used_by(pa_source *s) {
745     unsigned ret;
746
747     pa_source_assert_ref(s);
748     pa_assert(PA_SOURCE_IS_LINKED(s->state));
749
750     ret = pa_idxset_size(s->outputs);
751     pa_assert(ret >= s->n_corked);
752
753     return ret - s->n_corked;
754 }
755
756 /* Called from main thread */
757 unsigned pa_source_check_suspend(pa_source *s) {
758     unsigned ret;
759     pa_source_output *o;
760     uint32_t idx;
761
762     pa_source_assert_ref(s);
763
764     if (!PA_SOURCE_IS_LINKED(s->state))
765         return 0;
766
767     ret = 0;
768
769     for (o = PA_SOURCE_OUTPUT(pa_idxset_first(s->outputs, &idx)); o; o = PA_SOURCE_OUTPUT(pa_idxset_next(s->outputs, &idx))) {
770         pa_source_output_state_t st;
771
772         st = pa_source_output_get_state(o);
773         pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(st));
774
775         if (st == PA_SOURCE_OUTPUT_CORKED)
776             continue;
777
778         if (o->flags & PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND)
779             continue;
780
781         ret ++;
782     }
783
784     return ret;
785 }
786
787 /* Called from IO thread, except when it is not */
788 int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {
789     pa_source *s = PA_SOURCE(object);
790     pa_source_assert_ref(s);
791
792     switch ((pa_source_message_t) code) {
793
794         case PA_SOURCE_MESSAGE_ADD_OUTPUT: {
795             pa_source_output *o = PA_SOURCE_OUTPUT(userdata);
796
797             pa_hashmap_put(s->thread_info.outputs, PA_UINT32_TO_PTR(o->index), pa_source_output_ref(o));
798
799             if (o->direct_on_input) {
800                 o->thread_info.direct_on_input = o->direct_on_input;
801                 pa_hashmap_put(o->thread_info.direct_on_input->thread_info.direct_outputs, PA_UINT32_TO_PTR(o->index), o);
802             }
803
804             pa_assert(!o->thread_info.attached);
805             o->thread_info.attached = TRUE;
806
807             if (o->attach)
808                 o->attach(o);
809
810             pa_source_output_set_state_within_thread(o, o->state);
811
812             if (o->thread_info.requested_source_latency != (pa_usec_t) -1)
813                 pa_source_output_set_requested_latency_within_thread(o, o->thread_info.requested_source_latency);
814
815             pa_source_output_update_max_rewind(o, s->thread_info.max_rewind);
816
817             /* We don't just invalidate the requested latency here,
818              * because if we are in a move we might need to fix up the
819              * requested latency. */
820             pa_source_output_set_requested_latency_within_thread(o, o->thread_info.requested_source_latency);
821
822             return 0;
823         }
824
825         case PA_SOURCE_MESSAGE_REMOVE_OUTPUT: {
826             pa_source_output *o = PA_SOURCE_OUTPUT(userdata);
827
828             pa_source_output_set_state_within_thread(o, o->state);
829
830             if (o->detach)
831                 o->detach(o);
832
833             pa_assert(o->thread_info.attached);
834             o->thread_info.attached = FALSE;
835
836             if (o->thread_info.direct_on_input) {
837                 pa_hashmap_remove(o->thread_info.direct_on_input->thread_info.direct_outputs, PA_UINT32_TO_PTR(o->index));
838                 o->thread_info.direct_on_input = NULL;
839             }
840
841             if (pa_hashmap_remove(s->thread_info.outputs, PA_UINT32_TO_PTR(o->index)))
842                 pa_source_output_unref(o);
843
844             pa_source_invalidate_requested_latency(s);
845
846             return 0;
847         }
848
849         case PA_SOURCE_MESSAGE_SET_VOLUME:
850             s->thread_info.soft_volume = s->soft_volume;
851             return 0;
852
853         case PA_SOURCE_MESSAGE_GET_VOLUME:
854             return 0;
855
856         case PA_SOURCE_MESSAGE_SET_MUTE:
857             s->thread_info.soft_muted = s->muted;
858             return 0;
859
860         case PA_SOURCE_MESSAGE_GET_MUTE:
861             return 0;
862
863         case PA_SOURCE_MESSAGE_SET_STATE:
864             s->thread_info.state = PA_PTR_TO_UINT(userdata);
865             return 0;
866
867         case PA_SOURCE_MESSAGE_DETACH:
868
869             /* Detach all streams */
870             pa_source_detach_within_thread(s);
871             return 0;
872
873         case PA_SOURCE_MESSAGE_ATTACH:
874
875             /* Reattach all streams */
876             pa_source_attach_within_thread(s);
877             return 0;
878
879         case PA_SOURCE_MESSAGE_GET_REQUESTED_LATENCY: {
880
881             pa_usec_t *usec = userdata;
882             *usec = pa_source_get_requested_latency_within_thread(s);
883
884             if (*usec == (pa_usec_t) -1)
885                 *usec = s->thread_info.max_latency;
886
887             return 0;
888         }
889
890         case PA_SOURCE_MESSAGE_SET_LATENCY_RANGE: {
891             pa_usec_t *r = userdata;
892
893             pa_source_update_latency_range(s, r[0], r[1]);
894
895             return 0;
896         }
897
898         case PA_SOURCE_MESSAGE_GET_LATENCY_RANGE: {
899             pa_usec_t *r = userdata;
900
901             r[0] = s->thread_info.min_latency;
902             r[1] = s->thread_info.max_latency;
903
904             return 0;
905         }
906
907         case PA_SOURCE_MESSAGE_GET_MAX_REWIND:
908
909             *((size_t*) userdata) = s->thread_info.max_rewind;
910             return 0;
911
912         case PA_SOURCE_MESSAGE_GET_LATENCY:
913
914             if (s->monitor_of) {
915                 *((pa_usec_t*) userdata) = 0;
916                 return 0;
917             }
918
919             /* Implementors need to overwrite this implementation! */
920             return -1;
921
922         case PA_SOURCE_MESSAGE_MAX:
923             ;
924     }
925
926     return -1;
927 }
928
929 /* Called from main thread */
930 int pa_source_suspend_all(pa_core *c, pa_bool_t suspend) {
931     uint32_t idx;
932     pa_source *source;
933     int ret = 0;
934
935     pa_core_assert_ref(c);
936
937     for (source = PA_SOURCE(pa_idxset_first(c->sources, &idx)); source; source = PA_SOURCE(pa_idxset_next(c->sources, &idx)))
938         ret -= pa_source_suspend(source, suspend) < 0;
939
940     return ret;
941 }
942
943 /* Called from main thread */
944 void pa_source_detach(pa_source *s) {
945     pa_source_assert_ref(s);
946     pa_assert(PA_SOURCE_IS_LINKED(s->state));
947
948     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_DETACH, NULL, 0, NULL) == 0);
949 }
950
951 /* Called from main thread */
952 void pa_source_attach(pa_source *s) {
953     pa_source_assert_ref(s);
954     pa_assert(PA_SOURCE_IS_LINKED(s->state));
955
956     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_ATTACH, NULL, 0, NULL) == 0);
957 }
958
959 /* Called from IO thread */
960 void pa_source_detach_within_thread(pa_source *s) {
961     pa_source_output *o;
962     void *state = NULL;
963
964     pa_source_assert_ref(s);
965     pa_assert(PA_SOURCE_IS_LINKED(s->thread_info.state));
966
967     while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL)))
968         if (o->detach)
969             o->detach(o);
970 }
971
972 /* Called from IO thread */
973 void pa_source_attach_within_thread(pa_source *s) {
974     pa_source_output *o;
975     void *state = NULL;
976
977     pa_source_assert_ref(s);
978     pa_assert(PA_SOURCE_IS_LINKED(s->thread_info.state));
979
980     while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL)))
981         if (o->attach)
982             o->attach(o);
983 }
984
985 /* Called from IO thread */
986 pa_usec_t pa_source_get_requested_latency_within_thread(pa_source *s) {
987     pa_usec_t result = (pa_usec_t) -1;
988     pa_source_output *o;
989     void *state = NULL;
990
991     pa_source_assert_ref(s);
992
993     if (s->thread_info.requested_latency_valid)
994         return s->thread_info.requested_latency;
995
996     while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL)))
997
998         if (o->thread_info.requested_source_latency != (pa_usec_t) -1 &&
999             (result == (pa_usec_t) -1 || result > o->thread_info.requested_source_latency))
1000             result = o->thread_info.requested_source_latency;
1001
1002     if (result != (pa_usec_t) -1) {
1003         if (s->thread_info.max_latency > 0 && result > s->thread_info.max_latency)
1004             result = s->thread_info.max_latency;
1005
1006         if (s->thread_info.min_latency > 0 && result < s->thread_info.min_latency)
1007             result = s->thread_info.min_latency;
1008     }
1009
1010     s->thread_info.requested_latency = result;
1011     s->thread_info.requested_latency_valid = TRUE;
1012
1013     return result;
1014 }
1015
1016 /* Called from main thread */
1017 pa_usec_t pa_source_get_requested_latency(pa_source *s) {
1018     pa_usec_t usec;
1019
1020     pa_source_assert_ref(s);
1021     pa_assert(PA_SOURCE_IS_LINKED(s->state));
1022
1023     if (s->state == PA_SOURCE_SUSPENDED)
1024         return 0;
1025
1026     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);
1027
1028     return usec;
1029 }
1030
1031 /* Called from IO thread */
1032 void pa_source_set_max_rewind(pa_source *s, size_t max_rewind) {
1033     pa_source_output *o;
1034     void *state = NULL;
1035
1036     pa_source_assert_ref(s);
1037
1038     if (max_rewind == s->thread_info.max_rewind)
1039         return;
1040
1041     s->thread_info.max_rewind = max_rewind;
1042
1043     if (PA_SOURCE_IS_LINKED(s->thread_info.state)) {
1044         while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL)))
1045             pa_source_output_update_max_rewind(o, s->thread_info.max_rewind);
1046     }
1047 }
1048
1049 void pa_source_invalidate_requested_latency(pa_source *s) {
1050     pa_source_output *o;
1051     void *state = NULL;
1052
1053     pa_source_assert_ref(s);
1054
1055     s->thread_info.requested_latency_valid = FALSE;
1056
1057     if (s->update_requested_latency)
1058         s->update_requested_latency(s);
1059
1060     while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL)))
1061         if (o->update_source_requested_latency)
1062             o->update_source_requested_latency(o);
1063
1064     if (s->monitor_of)
1065         pa_sink_invalidate_requested_latency(s->monitor_of);
1066 }
1067
1068 void pa_source_set_latency_range(pa_source *s, pa_usec_t min_latency, pa_usec_t max_latency) {
1069     pa_source_assert_ref(s);
1070
1071     /* min_latency == 0:           no limit
1072      * min_latency == (size_t) -1: default limit
1073      * min_latency anything else:  specified limit
1074      *
1075      * Similar for max_latency */
1076
1077     if (min_latency == (pa_usec_t) -1)
1078         min_latency = DEFAULT_MIN_LATENCY;
1079
1080     if (max_latency == (pa_usec_t) -1)
1081         max_latency = min_latency;
1082
1083     pa_assert(!min_latency || !max_latency ||
1084               min_latency <= max_latency);
1085
1086     if (PA_SOURCE_IS_LINKED(s->state)) {
1087         pa_usec_t r[2];
1088
1089         r[0] = min_latency;
1090         r[1] = max_latency;
1091
1092         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_LATENCY_RANGE, r, 0, NULL) == 0);
1093     } else {
1094         s->thread_info.min_latency = min_latency;
1095         s->thread_info.max_latency = max_latency;
1096
1097         s->thread_info.requested_latency_valid = FALSE;
1098     }
1099 }
1100
1101 void pa_source_get_latency_range(pa_source *s, pa_usec_t *min_latency, pa_usec_t *max_latency) {
1102    pa_source_assert_ref(s);
1103    pa_assert(min_latency);
1104    pa_assert(max_latency);
1105
1106    if (PA_SOURCE_IS_LINKED(s->state)) {
1107        pa_usec_t r[2] = { 0, 0 };
1108
1109        pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_LATENCY_RANGE, r, 0, NULL) == 0);
1110
1111        *min_latency = r[0];
1112        *max_latency = r[1];
1113    } else {
1114        *min_latency = s->thread_info.min_latency;
1115        *max_latency = s->thread_info.max_latency;
1116    }
1117 }
1118
1119 /* Called from IO thread */
1120 void pa_source_update_latency_range(pa_source *s, pa_usec_t min_latency, pa_usec_t max_latency) {
1121     pa_source_output *o;
1122     void *state = NULL;
1123
1124     pa_source_assert_ref(s);
1125
1126     pa_assert(!min_latency || !max_latency ||
1127               min_latency <= max_latency);
1128
1129     s->thread_info.min_latency = min_latency;
1130     s->thread_info.max_latency = max_latency;
1131
1132     while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL)))
1133         if (o->update_source_latency_range)
1134             o->update_source_latency_range(o);
1135
1136     pa_source_invalidate_requested_latency(s);
1137 }
1138
1139 size_t pa_source_get_max_rewind(pa_source *s) {
1140     size_t r;
1141     pa_source_assert_ref(s);
1142
1143     if (!PA_SOURCE_IS_LINKED(s->state))
1144         return s->thread_info.max_rewind;
1145
1146     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_MAX_REWIND, &r, 0, NULL) == 0);
1147
1148     return r;
1149 }