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