1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2010 Intel Corporation
5 Contributor: Pierre-Louis Bossart <pierre-louis.bossart@intel.com>
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, see <http://www.gnu.org/licenses/>.
19 ***/
20
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24
25 #include <pulse/gccmacro.h>
26 #include <pulse/xmalloc.h>
27
28 #include <pulsecore/i18n.h>
29 #include <pulsecore/namereg.h>
30 #include <pulsecore/sink.h>
31 #include <pulsecore/module.h>
32 #include <pulsecore/core-util.h>
33 #include <pulsecore/modargs.h>
34 #include <pulsecore/log.h>
35 #include <pulsecore/rtpoll.h>
36 #include <pulsecore/sample-util.h>
37 #include <pulsecore/ltdl-helper.h>
38
39 PA_MODULE_AUTHOR("Pierre-Louis Bossart");
40 PA_MODULE_DESCRIPTION(_("Virtual sink"));
41 PA_MODULE_VERSION(PACKAGE_VERSION);
42 PA_MODULE_LOAD_ONCE(false);
43 PA_MODULE_USAGE(
44 _("sink_name=<name for the sink> "
45 "sink_properties=<properties for the sink> "
46 "master=<name of sink to filter> "
47 "rate=<sample rate> "
48 "channels=<number of channels> "
49 "channel_map=<channel map> "
50 "use_volume_sharing=<yes or no> "
51 "force_flat_volume=<yes or no> "
52 ));
53
54 #define MEMBLOCKQ_MAXLENGTH (16*1024*1024)
55
56 struct userdata {
57 pa_module *module;
58
59 /* FIXME: Uncomment this and take "autoloaded" as a modarg if this is a filter */
60 /* bool autoloaded; */
61
62 pa_sink *sink;
63 pa_sink_input *sink_input;
64
65 pa_memblockq *memblockq;
66
67 bool auto_desc;
68 unsigned channels;
69 };
70
71 static const char* const valid_modargs[] = {
72 "sink_name",
73 "sink_properties",
74 "master",
75 "rate",
76 "channels",
77 "channel_map",
78 "use_volume_sharing",
79 "force_flat_volume",
80 NULL
81 };
82
83 /* Called from I/O thread context */
sink_process_msg_cb(pa_msgobject * o,int code,void * data,int64_t offset,pa_memchunk * chunk)84 static int sink_process_msg_cb(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
85 struct userdata *u = PA_SINK(o)->userdata;
86
87 switch (code) {
88
89 case PA_SINK_MESSAGE_GET_LATENCY:
90
91 /* The sink is _put() before the sink input is, so let's
92 * make sure we don't access it in that time. Also, the
93 * sink input is first shut down, the sink second. */
94 if (!PA_SINK_IS_LINKED(u->sink->thread_info.state) ||
95 !PA_SINK_INPUT_IS_LINKED(u->sink_input->thread_info.state)) {
96 *((int64_t*) data) = 0;
97 return 0;
98 }
99
100 *((int64_t*) data) =
101
102 /* Get the latency of the master sink */
103 pa_sink_get_latency_within_thread(u->sink_input->sink, true) +
104
105 /* Add the latency internal to our sink input on top */
106 pa_bytes_to_usec(pa_memblockq_get_length(u->sink_input->thread_info.render_memblockq), &u->sink_input->sink->sample_spec);
107
108 /* Add resampler latency */
109 *((int64_t*) data) += pa_resampler_get_delay_usec(u->sink_input->thread_info.resampler);
110
111 return 0;
112 }
113
114 return pa_sink_process_msg(o, code, data, offset, chunk);
115 }
116
117 /* Called from main context */
sink_set_state_in_main_thread_cb(pa_sink * s,pa_sink_state_t state,pa_suspend_cause_t suspend_cause)118 static int sink_set_state_in_main_thread_cb(pa_sink *s, pa_sink_state_t state, pa_suspend_cause_t suspend_cause) {
119 struct userdata *u;
120
121 pa_sink_assert_ref(s);
122 pa_assert_se(u = s->userdata);
123
124 if (!PA_SINK_IS_LINKED(state) ||
125 !PA_SINK_INPUT_IS_LINKED(u->sink_input->state))
126 return 0;
127
128 pa_sink_input_cork(u->sink_input, state == PA_SINK_SUSPENDED);
129 return 0;
130 }
131
132 /* Called from the IO thread. */
sink_set_state_in_io_thread_cb(pa_sink * s,pa_sink_state_t new_state,pa_suspend_cause_t new_suspend_cause)133 static int sink_set_state_in_io_thread_cb(pa_sink *s, pa_sink_state_t new_state, pa_suspend_cause_t new_suspend_cause) {
134 struct userdata *u;
135
136 pa_assert(s);
137 pa_assert_se(u = s->userdata);
138
139 /* When set to running or idle for the first time, request a rewind
140 * of the master sink to make sure we are heard immediately */
141 if (PA_SINK_IS_OPENED(new_state) && s->thread_info.state == PA_SINK_INIT) {
142 pa_log_debug("Requesting rewind due to state change.");
143 pa_sink_input_request_rewind(u->sink_input, 0, false, true, true);
144 }
145
146 return 0;
147 }
148
149 /* Called from I/O thread context */
sink_request_rewind_cb(pa_sink * s)150 static void sink_request_rewind_cb(pa_sink *s) {
151 struct userdata *u;
152
153 pa_sink_assert_ref(s);
154 pa_assert_se(u = s->userdata);
155
156 if (!PA_SINK_IS_LINKED(u->sink->thread_info.state) ||
157 !PA_SINK_INPUT_IS_LINKED(u->sink_input->thread_info.state))
158 return;
159
160 /* Just hand this one over to the master sink */
161 pa_sink_input_request_rewind(u->sink_input,
162 s->thread_info.rewind_nbytes +
163 pa_memblockq_get_length(u->memblockq), true, false, false);
164 }
165
166 /* Called from I/O thread context */
sink_update_requested_latency_cb(pa_sink * s)167 static void sink_update_requested_latency_cb(pa_sink *s) {
168 struct userdata *u;
169
170 pa_sink_assert_ref(s);
171 pa_assert_se(u = s->userdata);
172
173 if (!PA_SINK_IS_LINKED(u->sink->thread_info.state) ||
174 !PA_SINK_INPUT_IS_LINKED(u->sink_input->thread_info.state))
175 return;
176
177 /* Just hand this one over to the master sink */
178 pa_sink_input_set_requested_latency_within_thread(
179 u->sink_input,
180 pa_sink_get_requested_latency_within_thread(s));
181 }
182
183 /* Called from main context */
sink_set_volume_cb(pa_sink * s)184 static void sink_set_volume_cb(pa_sink *s) {
185 struct userdata *u;
186
187 pa_sink_assert_ref(s);
188 pa_assert_se(u = s->userdata);
189
190 if (!PA_SINK_IS_LINKED(s->state) ||
191 !PA_SINK_INPUT_IS_LINKED(u->sink_input->state))
192 return;
193
194 pa_sink_input_set_volume(u->sink_input, &s->real_volume, s->save_volume, true);
195 }
196
197 /* Called from main context */
sink_set_mute_cb(pa_sink * s)198 static void sink_set_mute_cb(pa_sink *s) {
199 struct userdata *u;
200
201 pa_sink_assert_ref(s);
202 pa_assert_se(u = s->userdata);
203
204 if (!PA_SINK_IS_LINKED(s->state) ||
205 !PA_SINK_INPUT_IS_LINKED(u->sink_input->state))
206 return;
207
208 pa_sink_input_set_mute(u->sink_input, s->muted, s->save_muted);
209 }
210
211 /* Called from I/O thread context */
sink_input_pop_cb(pa_sink_input * i,size_t nbytes,pa_memchunk * chunk)212 static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk) {
213 struct userdata *u;
214 float *src, *dst;
215 size_t fs;
216 unsigned n, c;
217 pa_memchunk tchunk;
218 pa_usec_t current_latency PA_GCC_UNUSED;
219
220 pa_sink_input_assert_ref(i);
221 pa_assert(chunk);
222 pa_assert_se(u = i->userdata);
223
224 if (!PA_SINK_IS_LINKED(u->sink->thread_info.state))
225 return -1;
226
227 /* Hmm, process any rewind request that might be queued up */
228 pa_sink_process_rewind(u->sink, 0);
229
230 /* (1) IF YOU NEED A FIXED BLOCK SIZE USE
231 * pa_memblockq_peek_fixed_size() HERE INSTEAD. NOTE THAT FILTERS
232 * WHICH CAN DEAL WITH DYNAMIC BLOCK SIZES ARE HIGHLY
233 * PREFERRED. */
234 while (pa_memblockq_peek(u->memblockq, &tchunk) < 0) {
235 pa_memchunk nchunk;
236
237 pa_sink_render(u->sink, nbytes, &nchunk);
238 pa_memblockq_push(u->memblockq, &nchunk);
239 pa_memblock_unref(nchunk.memblock);
240 }
241
242 /* (2) IF YOU NEED A FIXED BLOCK SIZE, THIS NEXT LINE IS NOT
243 * NECESSARY */
244 tchunk.length = PA_MIN(nbytes, tchunk.length);
245 pa_assert(tchunk.length > 0);
246
247 fs = pa_frame_size(&i->sample_spec);
248 n = (unsigned) (tchunk.length / fs);
249
250 pa_assert(n > 0);
251
252 chunk->index = 0;
253 chunk->length = n*fs;
254 chunk->memblock = pa_memblock_new(i->sink->core->mempool, chunk->length);
255
256 pa_memblockq_drop(u->memblockq, chunk->length);
257
258 src = pa_memblock_acquire_chunk(&tchunk);
259 dst = pa_memblock_acquire(chunk->memblock);
260
261 /* (3) PUT YOUR CODE HERE TO DO SOMETHING WITH THE DATA */
262
263 /* As an example, copy input to output */
264 for (c = 0; c < u->channels; c++) {
265 pa_sample_clamp(PA_SAMPLE_FLOAT32NE,
266 dst+c, u->channels * sizeof(float),
267 src+c, u->channels * sizeof(float),
268 n);
269 }
270
271 pa_memblock_release(tchunk.memblock);
272 pa_memblock_release(chunk->memblock);
273
274 pa_memblock_unref(tchunk.memblock);
275
276 /* (4) IF YOU NEED THE LATENCY FOR SOMETHING ACQUIRE IT LIKE THIS: */
277 current_latency =
278 /* Get the latency of the master sink */
279 pa_sink_get_latency_within_thread(i->sink, false) +
280
281 /* Add the latency internal to our sink input on top */
282 pa_bytes_to_usec(pa_memblockq_get_length(i->thread_info.render_memblockq), &i->sink->sample_spec);
283
284 return 0;
285 }
286
287 /* Called from I/O thread context */
sink_input_process_rewind_cb(pa_sink_input * i,size_t nbytes)288 static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes) {
289 struct userdata *u;
290 size_t amount = 0;
291
292 pa_sink_input_assert_ref(i);
293 pa_assert_se(u = i->userdata);
294
295 /* If the sink is not yet linked, there is nothing to rewind */
296 if (!PA_SINK_IS_LINKED(u->sink->thread_info.state))
297 return;
298
299 if (u->sink->thread_info.rewind_nbytes > 0) {
300 size_t max_rewrite;
301
302 max_rewrite = nbytes + pa_memblockq_get_length(u->memblockq);
303 amount = PA_MIN(u->sink->thread_info.rewind_nbytes, max_rewrite);
304 u->sink->thread_info.rewind_nbytes = 0;
305
306 if (amount > 0) {
307 pa_memblockq_seek(u->memblockq, - (int64_t) amount, PA_SEEK_RELATIVE, true);
308
309 /* (5) PUT YOUR CODE HERE TO RESET YOUR FILTER */
310 }
311 }
312
313 pa_sink_process_rewind(u->sink, amount);
314 pa_memblockq_rewind(u->memblockq, nbytes);
315 }
316
317 /* Called from I/O thread context */
sink_input_update_max_rewind_cb(pa_sink_input * i,size_t nbytes)318 static void sink_input_update_max_rewind_cb(pa_sink_input *i, size_t nbytes) {
319 struct userdata *u;
320
321 pa_sink_input_assert_ref(i);
322 pa_assert_se(u = i->userdata);
323
324 /* FIXME: Too small max_rewind:
325 * https://bugs.freedesktop.org/show_bug.cgi?id=53709 */
326 pa_memblockq_set_maxrewind(u->memblockq, nbytes);
327 pa_sink_set_max_rewind_within_thread(u->sink, nbytes);
328 }
329
330 /* Called from I/O thread context */
sink_input_update_max_request_cb(pa_sink_input * i,size_t nbytes)331 static void sink_input_update_max_request_cb(pa_sink_input *i, size_t nbytes) {
332 struct userdata *u;
333
334 pa_sink_input_assert_ref(i);
335 pa_assert_se(u = i->userdata);
336
337 /* (6) IF YOU NEED A FIXED BLOCK SIZE ROUND nbytes UP TO MULTIPLES
338 * OF IT HERE. THE PA_ROUND_UP MACRO IS USEFUL FOR THAT. */
339
340 pa_sink_set_max_request_within_thread(u->sink, nbytes);
341 }
342
343 /* Called from I/O thread context */
sink_input_update_sink_latency_range_cb(pa_sink_input * i)344 static void sink_input_update_sink_latency_range_cb(pa_sink_input *i) {
345 struct userdata *u;
346
347 pa_sink_input_assert_ref(i);
348 pa_assert_se(u = i->userdata);
349
350 pa_sink_set_latency_range_within_thread(u->sink, i->sink->thread_info.min_latency, i->sink->thread_info.max_latency);
351 }
352
353 /* Called from I/O thread context */
sink_input_update_sink_fixed_latency_cb(pa_sink_input * i)354 static void sink_input_update_sink_fixed_latency_cb(pa_sink_input *i) {
355 struct userdata *u;
356
357 pa_sink_input_assert_ref(i);
358 pa_assert_se(u = i->userdata);
359
360 /* (7) IF YOU NEED A FIXED BLOCK SIZE ADD THE LATENCY FOR ONE
361 * BLOCK MINUS ONE SAMPLE HERE. pa_usec_to_bytes_round_up() IS
362 * USEFUL FOR THAT. */
363
364 pa_sink_set_fixed_latency_within_thread(u->sink, i->sink->thread_info.fixed_latency);
365 }
366
367 /* Called from I/O thread context */
sink_input_detach_cb(pa_sink_input * i)368 static void sink_input_detach_cb(pa_sink_input *i) {
369 struct userdata *u;
370
371 pa_sink_input_assert_ref(i);
372 pa_assert_se(u = i->userdata);
373
374 if (PA_SINK_IS_LINKED(u->sink->thread_info.state))
375 pa_sink_detach_within_thread(u->sink);
376
377 pa_sink_set_rtpoll(u->sink, NULL);
378 }
379
380 /* Called from I/O thread context */
sink_input_attach_cb(pa_sink_input * i)381 static void sink_input_attach_cb(pa_sink_input *i) {
382 struct userdata *u;
383
384 pa_sink_input_assert_ref(i);
385 pa_assert_se(u = i->userdata);
386
387 pa_sink_set_rtpoll(u->sink, i->sink->thread_info.rtpoll);
388 pa_sink_set_latency_range_within_thread(u->sink, i->sink->thread_info.min_latency, i->sink->thread_info.max_latency);
389
390 /* (8.1) IF YOU NEED A FIXED BLOCK SIZE ADD THE LATENCY FOR ONE
391 * BLOCK MINUS ONE SAMPLE HERE. SEE (7) */
392 pa_sink_set_fixed_latency_within_thread(u->sink, i->sink->thread_info.fixed_latency);
393
394 /* (8.2) IF YOU NEED A FIXED BLOCK SIZE ROUND
395 * pa_sink_input_get_max_request(i) UP TO MULTIPLES OF IT
396 * HERE. SEE (6) */
397 pa_sink_set_max_request_within_thread(u->sink, pa_sink_input_get_max_request(i));
398
399 /* FIXME: Too small max_rewind:
400 * https://bugs.freedesktop.org/show_bug.cgi?id=53709 */
401 pa_sink_set_max_rewind_within_thread(u->sink, pa_sink_input_get_max_rewind(i));
402
403 if (PA_SINK_IS_LINKED(u->sink->thread_info.state))
404 pa_sink_attach_within_thread(u->sink);
405 }
406
407 /* Called from main context */
sink_input_kill_cb(pa_sink_input * i)408 static void sink_input_kill_cb(pa_sink_input *i) {
409 struct userdata *u;
410
411 pa_sink_input_assert_ref(i);
412 pa_assert_se(u = i->userdata);
413
414 /* The order here matters! We first kill the sink so that streams
415 * can properly be moved away while the sink input is still connected
416 * to the master. */
417 pa_sink_input_cork(u->sink_input, true);
418 pa_sink_unlink(u->sink);
419 pa_sink_input_unlink(u->sink_input);
420
421 pa_sink_input_unref(u->sink_input);
422 u->sink_input = NULL;
423
424 pa_sink_unref(u->sink);
425 u->sink = NULL;
426
427 pa_module_unload_request(u->module, true);
428 }
429
430 /* Called from main context */
sink_input_moving_cb(pa_sink_input * i,pa_sink * dest)431 static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest) {
432 struct userdata *u;
433
434 pa_sink_input_assert_ref(i);
435 pa_assert_se(u = i->userdata);
436
437 if (dest) {
438 pa_sink_set_asyncmsgq(u->sink, dest->asyncmsgq);
439 pa_sink_update_flags(u->sink, PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY, dest->flags);
440 } else
441 pa_sink_set_asyncmsgq(u->sink, NULL);
442
443 if (u->auto_desc && dest) {
444 const char *z;
445 pa_proplist *pl;
446
447 pl = pa_proplist_new();
448 z = pa_proplist_gets(dest->proplist, PA_PROP_DEVICE_DESCRIPTION);
449 pa_proplist_setf(pl, PA_PROP_DEVICE_DESCRIPTION, "Virtual Sink %s on %s",
450 pa_proplist_gets(u->sink->proplist, "device.vsink.name"), z ? z : dest->name);
451
452 pa_sink_update_proplist(u->sink, PA_UPDATE_REPLACE, pl);
453 pa_proplist_free(pl);
454 }
455 }
456
457 /* Called from main context */
sink_input_volume_changed_cb(pa_sink_input * i)458 static void sink_input_volume_changed_cb(pa_sink_input *i) {
459 struct userdata *u;
460
461 pa_sink_input_assert_ref(i);
462 pa_assert_se(u = i->userdata);
463
464 pa_sink_volume_changed(u->sink, &i->volume);
465 }
466
467 /* Called from main context */
sink_input_mute_changed_cb(pa_sink_input * i)468 static void sink_input_mute_changed_cb(pa_sink_input *i) {
469 struct userdata *u;
470
471 pa_sink_input_assert_ref(i);
472 pa_assert_se(u = i->userdata);
473
474 pa_sink_mute_changed(u->sink, i->muted);
475 }
476
pa__init(pa_module * m)477 int pa__init(pa_module*m) {
478 struct userdata *u;
479 pa_sample_spec ss;
480 pa_channel_map map;
481 pa_modargs *ma;
482 pa_sink *master=NULL;
483 pa_sink_input_new_data sink_input_data;
484 pa_sink_new_data sink_data;
485 bool use_volume_sharing = true;
486 bool force_flat_volume = false;
487 pa_memchunk silence;
488
489 pa_assert(m);
490
491 if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
492 pa_log("Failed to parse module arguments.");
493 goto fail;
494 }
495
496 if (!(master = pa_namereg_get(m->core, pa_modargs_get_value(ma, "master", NULL), PA_NAMEREG_SINK))) {
497 pa_log("Master sink not found");
498 goto fail;
499 }
500
501 pa_assert(master);
502
503 ss = master->sample_spec;
504 ss.format = PA_SAMPLE_FLOAT32;
505 map = master->channel_map;
506 if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) {
507 pa_log("Invalid sample format specification or channel map");
508 goto fail;
509 }
510
511 if (pa_modargs_get_value_boolean(ma, "use_volume_sharing", &use_volume_sharing) < 0) {
512 pa_log("use_volume_sharing= expects a boolean argument");
513 goto fail;
514 }
515
516 if (pa_modargs_get_value_boolean(ma, "force_flat_volume", &force_flat_volume) < 0) {
517 pa_log("force_flat_volume= expects a boolean argument");
518 goto fail;
519 }
520
521 if (use_volume_sharing && force_flat_volume) {
522 pa_log("Flat volume can't be forced when using volume sharing.");
523 goto fail;
524 }
525
526 u = pa_xnew0(struct userdata, 1);
527 u->module = m;
528 m->userdata = u;
529 u->channels = ss.channels;
530
531 /* Create sink */
532 pa_sink_new_data_init(&sink_data);
533 sink_data.driver = __FILE__;
534 sink_data.module = m;
535 if (!(sink_data.name = pa_xstrdup(pa_modargs_get_value(ma, "sink_name", NULL))))
536 sink_data.name = pa_sprintf_malloc("%s.vsink", master->name);
537 pa_sink_new_data_set_sample_spec(&sink_data, &ss);
538 pa_sink_new_data_set_channel_map(&sink_data, &map);
539 pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_MASTER_DEVICE, master->name);
540 pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_CLASS, "filter");
541 pa_proplist_sets(sink_data.proplist, "device.vsink.name", sink_data.name);
542
543 if (pa_modargs_get_proplist(ma, "sink_properties", sink_data.proplist, PA_UPDATE_REPLACE) < 0) {
544 pa_log("Invalid properties");
545 pa_sink_new_data_done(&sink_data);
546 goto fail;
547 }
548
549 if ((u->auto_desc = !pa_proplist_contains(sink_data.proplist, PA_PROP_DEVICE_DESCRIPTION))) {
550 const char *z;
551
552 z = pa_proplist_gets(master->proplist, PA_PROP_DEVICE_DESCRIPTION);
553 pa_proplist_setf(sink_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Virtual Sink %s on %s", sink_data.name, z ? z : master->name);
554 }
555
556 u->sink = pa_sink_new(m->core, &sink_data, (master->flags & (PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY))
557 | (use_volume_sharing ? PA_SINK_SHARE_VOLUME_WITH_MASTER : 0));
558 pa_sink_new_data_done(&sink_data);
559
560 if (!u->sink) {
561 pa_log("Failed to create sink.");
562 goto fail;
563 }
564
565 u->sink->parent.process_msg = sink_process_msg_cb;
566 u->sink->set_state_in_main_thread = sink_set_state_in_main_thread_cb;
567 u->sink->set_state_in_io_thread = sink_set_state_in_io_thread_cb;
568 u->sink->update_requested_latency = sink_update_requested_latency_cb;
569 u->sink->request_rewind = sink_request_rewind_cb;
570 pa_sink_set_set_mute_callback(u->sink, sink_set_mute_cb);
571 if (!use_volume_sharing) {
572 pa_sink_set_set_volume_callback(u->sink, sink_set_volume_cb);
573 pa_sink_enable_decibel_volume(u->sink, true);
574 }
575 /* Normally this flag would be enabled automatically be we can force it. */
576 if (force_flat_volume)
577 u->sink->flags |= PA_SINK_FLAT_VOLUME;
578 u->sink->userdata = u;
579
580 pa_sink_set_asyncmsgq(u->sink, master->asyncmsgq);
581
582 /* Create sink input */
583 pa_sink_input_new_data_init(&sink_input_data);
584 sink_input_data.driver = __FILE__;
585 sink_input_data.module = m;
586 pa_sink_input_new_data_set_sink(&sink_input_data, master, false, true);
587 sink_input_data.origin_sink = u->sink;
588 pa_proplist_setf(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Virtual Sink Stream from %s", pa_proplist_gets(u->sink->proplist, PA_PROP_DEVICE_DESCRIPTION));
589 pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter");
590 pa_sink_input_new_data_set_sample_spec(&sink_input_data, &ss);
591 pa_sink_input_new_data_set_channel_map(&sink_input_data, &map);
592 sink_input_data.flags |= PA_SINK_INPUT_START_CORKED;
593
594 pa_sink_input_new(&u->sink_input, m->core, &sink_input_data);
595 pa_sink_input_new_data_done(&sink_input_data);
596
597 if (!u->sink_input)
598 goto fail;
599
600 u->sink_input->pop = sink_input_pop_cb;
601 u->sink_input->process_rewind = sink_input_process_rewind_cb;
602 u->sink_input->update_max_rewind = sink_input_update_max_rewind_cb;
603 u->sink_input->update_max_request = sink_input_update_max_request_cb;
604 u->sink_input->update_sink_latency_range = sink_input_update_sink_latency_range_cb;
605 u->sink_input->update_sink_fixed_latency = sink_input_update_sink_fixed_latency_cb;
606 u->sink_input->kill = sink_input_kill_cb;
607 u->sink_input->attach = sink_input_attach_cb;
608 u->sink_input->detach = sink_input_detach_cb;
609 u->sink_input->moving = sink_input_moving_cb;
610 u->sink_input->volume_changed = use_volume_sharing ? NULL : sink_input_volume_changed_cb;
611 u->sink_input->mute_changed = sink_input_mute_changed_cb;
612 u->sink_input->userdata = u;
613
614 u->sink->input_to_master = u->sink_input;
615
616 pa_sink_input_get_silence(u->sink_input, &silence);
617 u->memblockq = pa_memblockq_new("module-virtual-sink memblockq", 0, MEMBLOCKQ_MAXLENGTH, 0, &ss, 1, 1, 0, &silence);
618 pa_memblock_unref(silence.memblock);
619
620 /* (9) INITIALIZE ANYTHING ELSE YOU NEED HERE */
621
622 /* The order here is important. The input must be put first,
623 * otherwise streams might attach to the sink before the sink
624 * input is attached to the master. */
625 pa_sink_input_put(u->sink_input);
626 pa_sink_put(u->sink);
627 pa_sink_input_cork(u->sink_input, false);
628
629 pa_modargs_free(ma);
630
631 return 0;
632
633 fail:
634 if (ma)
635 pa_modargs_free(ma);
636
637 pa__done(m);
638
639 return -1;
640 }
641
pa__get_n_used(pa_module * m)642 int pa__get_n_used(pa_module *m) {
643 struct userdata *u;
644
645 pa_assert(m);
646 pa_assert_se(u = m->userdata);
647
648 return pa_sink_linked_by(u->sink);
649 }
650
pa__done(pa_module * m)651 void pa__done(pa_module*m) {
652 struct userdata *u;
653
654 pa_assert(m);
655
656 if (!(u = m->userdata))
657 return;
658
659 /* See comments in sink_input_kill_cb() above regarding
660 * destruction order! */
661
662 if (u->sink_input)
663 pa_sink_input_cork(u->sink_input, true);
664
665 if (u->sink)
666 pa_sink_unlink(u->sink);
667
668 if (u->sink_input) {
669 pa_sink_input_unlink(u->sink_input);
670 pa_sink_input_unref(u->sink_input);
671 }
672
673 if (u->sink)
674 pa_sink_unref(u->sink);
675
676 if (u->memblockq)
677 pa_memblockq_free(u->memblockq);
678
679 pa_xfree(u);
680 }
681