diff options
Diffstat (limited to 'src/modules/module-virtual-source.c')
-rw-r--r-- | src/modules/module-virtual-source.c | 35 |
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); |