summaryrefslogtreecommitdiff
path: root/src/modules/module-virtual-source.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/module-virtual-source.c')
-rw-r--r--src/modules/module-virtual-source.c35
1 files changed, 26 insertions, 9 deletions
diff --git a/src/modules/module-virtual-source.c b/src/modules/module-virtual-source.c
index 42aefd058..94907dfa9 100644
--- a/src/modules/module-virtual-source.c
+++ b/src/modules/module-virtual-source.c
@@ -263,6 +263,9 @@ static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk)
pa_source_output_assert_io_context(o);
pa_assert_se(u = o->userdata);
+ if (!PA_SOURCE_IS_LINKED(u->source->thread_info.state))
+ return;
+
if (!PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u->source_output))) {
pa_log("push when no link?");
return;
@@ -356,6 +359,10 @@ static void source_output_process_rewind_cb(pa_source_output *o, size_t nbytes)
pa_source_output_assert_io_context(o);
pa_assert_se(u = o->userdata);
+ /* If the source is not yet linked, there is nothing to rewind */
+ if (PA_SOURCE_IS_LINKED(u->source->thread_info.state))
+ pa_source_process_rewind(u->source, nbytes);
+
/* FIXME, no idea what I am doing here */
#if 0
pa_asyncmsgq_post(u->asyncmsgq, PA_MSGOBJECT(u->sink_input), SINK_INPUT_MESSAGE_REWIND, NULL, (int64_t) nbytes, NULL, NULL);
@@ -376,7 +383,8 @@ static void source_output_attach_cb(pa_source_output *o) {
pa_source_set_fixed_latency_within_thread(u->source, o->source->thread_info.fixed_latency);
pa_source_set_max_rewind_within_thread(u->source, pa_source_output_get_max_rewind(o));
- pa_source_attach_within_thread(u->source);
+ if (PA_SOURCE_IS_LINKED(u->source->thread_info.state))
+ pa_source_attach_within_thread(u->source);
}
/* Called from output thread context */
@@ -387,7 +395,8 @@ static void source_output_detach_cb(pa_source_output *o) {
pa_source_output_assert_io_context(o);
pa_assert_se(u = o->userdata);
- pa_source_detach_within_thread(u->source);
+ if (PA_SOURCE_IS_LINKED(u->source->thread_info.state))
+ pa_source_detach_within_thread(u->source);
pa_source_set_rtpoll(u->source, NULL);
}
@@ -419,11 +428,12 @@ static void source_output_kill_cb(pa_source_output *o) {
pa_assert_ctl_context();
pa_assert_se(u = o->userdata);
- /* The order here matters! We first kill the source output, followed
- * by the source. That means the source callbacks must be protected
- * against an unconnected source output! */
- pa_source_output_unlink(u->source_output);
+ /* The order here matters! We first kill the source so that streams
+ * can properly be moved away while the source output is still connected
+ * to the master. */
+ pa_source_output_cork(u->source_output, true);
pa_source_unlink(u->source);
+ pa_source_output_unlink(u->source_output);
pa_source_output_unref(u->source_output);
u->source_output = NULL;
@@ -585,6 +595,7 @@ int pa__init(pa_module*m) {
pa_proplist_sets(source_output_data.proplist, PA_PROP_MEDIA_ROLE, "filter");
pa_source_output_new_data_set_sample_spec(&source_output_data, &ss);
pa_source_output_new_data_set_channel_map(&source_output_data, &map);
+ source_output_data.flags |= PA_SOURCE_OUTPUT_START_CORKED;
pa_source_output_new(&u->source_output, m->core, &source_output_data);
pa_source_output_new_data_done(&source_output_data);
@@ -603,8 +614,12 @@ int pa__init(pa_module*m) {
u->source->output_from_master = u->source_output;
- pa_source_put(u->source);
+ /* The order here is important. The output must be put first,
+ * otherwise streams might attach to the source before the
+ * source output is attached to the master. */
pa_source_output_put(u->source_output);
+ pa_source_put(u->source);
+ pa_source_output_cork(u->source_output, false);
/* Create optional uplink sink */
pa_sink_new_data_init(&sink_data);
@@ -694,13 +709,15 @@ void pa__done(pa_module*m) {
* destruction order! */
if (u->source_output)
- pa_source_output_unlink(u->source_output);
+ pa_source_output_cork(u->source_output, true);
if (u->source)
pa_source_unlink(u->source);
- if (u->source_output)
+ if (u->source_output) {
+ pa_source_output_unlink(u->source_output);
pa_source_output_unref(u->source_output);
+ }
if (u->source)
pa_source_unref(u->source);