From 117fa0cbe52ea15b93b58f739c2704a876e64031 Mon Sep 17 00:00:00 2001 From: Craig Howard Date: Wed, 23 Mar 2022 16:21:24 -0700 Subject: tunnel-sink-new: refactor sink creation Move the sink creation logic to its own function. This is in preparation for sinks being created async. Store the relevant config parameters in userdata, so create_sink() can access that data. Part-of: --- src/modules/module-tunnel-sink-new.c | 104 ++++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 37 deletions(-) diff --git a/src/modules/module-tunnel-sink-new.c b/src/modules/module-tunnel-sink-new.c index 66a178717..6f5fccbee 100644 --- a/src/modules/module-tunnel-sink-new.c +++ b/src/modules/module-tunnel-sink-new.c @@ -85,6 +85,11 @@ struct userdata { char *cookie_file; char *remote_server; char *remote_sink_name; + char *sink_name; + + pa_proplist *sink_proplist; + pa_sample_spec sample_spec; + pa_channel_map channel_map; }; static const char* const valid_modargs[] = { @@ -487,14 +492,51 @@ static int sink_set_state_in_io_thread_cb(pa_sink *s, pa_sink_state_t new_state, return 0; } +static int create_sink(struct userdata *u) { + pa_sink_new_data sink_data; + + pa_assert_ctl_context(); + + /* Create sink */ + pa_sink_new_data_init(&sink_data); + sink_data.driver = __FILE__; + sink_data.module = u->module; + + pa_sink_new_data_set_name(&sink_data, u->sink_name); + pa_sink_new_data_set_sample_spec(&sink_data, &u->sample_spec); + pa_sink_new_data_set_channel_map(&sink_data, &u->channel_map); + + pa_proplist_update(sink_data.proplist, PA_UPDATE_REPLACE, u->sink_proplist); + + if (!(u->sink = pa_sink_new(u->module->core, &sink_data, PA_SINK_LATENCY | PA_SINK_DYNAMIC_LATENCY | PA_SINK_NETWORK))) { + pa_log("Failed to create sink."); + goto fail; + } + + pa_sink_new_data_done(&sink_data); + + u->sink->userdata = u; + u->sink->parent.process_msg = sink_process_msg_cb; + u->sink->set_state_in_io_thread = sink_set_state_in_io_thread_cb; + u->sink->update_requested_latency = sink_update_requested_latency_cb; + pa_sink_set_latency_range(u->sink, 0, MAX_LATENCY_USEC); + + /* set thread message queue */ + pa_sink_set_asyncmsgq(u->sink, u->thread_mq->inq); + pa_sink_set_rtpoll(u->sink, u->rtpoll); + + return 0; + +fail: + pa_sink_new_data_done(&sink_data); + + return -1; +} + int pa__init(pa_module *m) { struct userdata *u = NULL; pa_modargs *ma = NULL; - pa_sink_new_data sink_data; - pa_sample_spec ss; - pa_channel_map map; const char *remote_server = NULL; - const char *sink_name = NULL; char *default_sink_name = NULL; pa_assert(m); @@ -504,9 +546,13 @@ int pa__init(pa_module *m) { goto fail; } - ss = m->core->default_sample_spec; - map = m->core->default_channel_map; - if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) { + u = pa_xnew0(struct userdata, 1); + u->module = m; + m->userdata = u; + + u->sample_spec = m->core->default_sample_spec; + u->channel_map = m->core->default_channel_map; + if (pa_modargs_get_sample_spec_and_channel_map(ma, &u->sample_spec, &u->channel_map, PA_CHANNEL_MAP_DEFAULT) < 0) { pa_log("Invalid sample format specification or channel map"); goto fail; } @@ -517,9 +563,6 @@ int pa__init(pa_module *m) { goto fail; } - u = pa_xnew0(struct userdata, 1); - u->module = m; - m->userdata = u; u->remote_server = pa_xstrdup(remote_server); u->thread_mainloop = pa_mainloop_new(); if (u->thread_mainloop == NULL) { @@ -546,53 +589,34 @@ int pa__init(pa_module *m) { * with module-tunnel-sink-new. */ u->rtpoll = pa_rtpoll_new(); - /* Create sink */ - pa_sink_new_data_init(&sink_data); - sink_data.driver = __FILE__; - sink_data.module = m; - default_sink_name = pa_sprintf_malloc("tunnel-sink-new.%s", remote_server); - sink_name = pa_modargs_get_value(ma, "sink_name", default_sink_name); - - pa_sink_new_data_set_name(&sink_data, sink_name); - pa_sink_new_data_set_sample_spec(&sink_data, &ss); - pa_sink_new_data_set_channel_map(&sink_data, &map); + u->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink_name", default_sink_name)); - pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_CLASS, "sound"); - pa_proplist_setf(sink_data.proplist, + u->sink_proplist = pa_proplist_new(); + pa_proplist_sets(u->sink_proplist, PA_PROP_DEVICE_CLASS, "sound"); + pa_proplist_setf(u->sink_proplist, PA_PROP_DEVICE_DESCRIPTION, _("Tunnel to %s/%s"), remote_server, pa_strempty(u->remote_sink_name)); - if (pa_modargs_get_proplist(ma, "sink_properties", sink_data.proplist, PA_UPDATE_REPLACE) < 0) { + if (pa_modargs_get_proplist(ma, "sink_properties", u->sink_proplist, PA_UPDATE_REPLACE) < 0) { pa_log("Invalid properties"); - pa_sink_new_data_done(&sink_data); goto fail; } - if (!(u->sink = pa_sink_new(m->core, &sink_data, PA_SINK_LATENCY | PA_SINK_DYNAMIC_LATENCY | PA_SINK_NETWORK))) { + + if (create_sink(u) < 0) { pa_log("Failed to create sink."); - pa_sink_new_data_done(&sink_data); goto fail; } - pa_sink_new_data_done(&sink_data); - u->sink->userdata = u; - u->sink->parent.process_msg = sink_process_msg_cb; - u->sink->set_state_in_io_thread = sink_set_state_in_io_thread_cb; - u->sink->update_requested_latency = sink_update_requested_latency_cb; - pa_sink_set_latency_range(u->sink, 0, MAX_LATENCY_USEC); - - /* set thread message queue */ - pa_sink_set_asyncmsgq(u->sink, u->thread_mq->inq); - pa_sink_set_rtpoll(u->sink, u->rtpoll); - if (!(u->thread = pa_thread_new("tunnel-sink", thread_func, u))) { pa_log("Failed to create thread."); goto fail; } pa_sink_put(u->sink); + pa_modargs_free(ma); pa_xfree(default_sink_name); @@ -649,5 +673,11 @@ void pa__done(pa_module *m) { if (u->rtpoll) pa_rtpoll_free(u->rtpoll); + if (u->sink_proplist) + pa_proplist_free(u->sink_proplist); + + if (u->sink_name) + pa_xfree(u->sink_name); + pa_xfree(u); } -- cgit v1.2.1