Re: [pulseaudio-discuss] [PATCH] added two new commands to native API to control the combine sink slaves after the combine sink has been created

2017-01-27 Thread Steffen Pfendtner
To catch up your points:

I will synchronise the pactl to pacmd. pulseaudio-dlna is using pactl
too. I just missed that point.

I share your view regarding the location of the new functions. A new
file set src/pulsecore/combine-sink.[ch] is a good idea to remove this
from the standard sink stuff.

Regarding multiple instances of module combine sink.
I though I've added the instance id of the combine module to the API.
This way the user or an external application can address which of the
instances he would like to modify or query.
This way no central management inside pulseaudio over all sinks on all
combined sinks is needed. In this way the patch is as essential as it
can be. You can even add a sink to two different combine sinks or a
combine sink as input sink to another one if you like to. 

If the module combine is not loaded and you call the API functions they
will simply return an error. If you unload the module while its running
it is part of the module instance to clean up on exit. 
Simple and stupid and not as complex as some dynamic API stuff.

On Thu, 2017-01-12 at 03:56 +0200 Tanu Kaskinen wrote:
> On Wed, 2017-01-11 at 17:44 +0530, Arun Raghavan wrote:
> > On Wed, 11 Jan 2017, at 03:45 AM, Tanu Kaskinen wrote:
> > > Thanks for the patch!
> > > 
> > > On Thu, 2017-01-05 at 20:13 +0100, Steffen Pfendtner wrote:
> > > > Subject: [PATCH] added two new commands to native API to control the 
> > > > combine sink slaves after the combine sink has been created
> > > 
> > > There's a misunderstanding: you edited the command line interface, not
> > > the native protocol. Applications use libpulse, which implements the
> > > native protocol, so that's where the client interface should be added.
> > > The command line interface is used by pacmd and the startup script
> > > interpreter. If you already integrated this feature in pulseaudio-dlna, 
> > > I guess you run pacmd commands from pulseaudio-dlna?
> > > 
> > > We have two similar tools: pacmd and pactl. Unlike pacmd, pactl is a
> > > regular client that uses libpulse to interact with the server. It's
> > > pretty pointless to have two tools that do the same thing, so I hope we
> > > can get rid of pacmd some day. pacmd doesn't work over the network, and
> > > also doesn't work when pulseaudio runs in the system mode.
> > > 
> > > You can add this functionality in the command line interface if you
> > > really want to, but if you do that, you have to add it to pactl as
> > > well, because I don't want new features in pacmd that are not supported
> > > by pactl. Adding the functionality to pactl is highly desirable even if
> > > you don't add the functionality to the command line interface, though.
> > > 
> > > Assuming that the API is added to the "core" instead as a protocol
> > > extension (see my previous mails: [1][2][3]), you'll need to add new
> > > commands that are sent from src/pulse/introspect.c and handled in
> > > src/pulsecore/protocol-native.c. I would suggest adding
> > > src/pulsecore/combine-sink.[ch] that has pa_combine_sink_add_output()
> > > and pa_combine_sink_remove_output() along with anything else protocol-
> > > native.c needs for dealing with the new commands. The API shouldn't be
> > > in sink.h, because that's for common sink functionality, while this API
> > > is only for one specific sink implementation.
> > 
> > First, to make this concrete. module-combine currently allows multiple
> > instances, so I guess we would either need to change it to allow a
> > single instance, or add a module-combine-manager module to implement the
> > extension API. I prefer the former.
> 
> Presumably you'd then add some new argument to module-combine-sink to
> signal that it should run in the "manager mode"? If we are going the
> extension route, I would prefer a separate manager module, but I don't
> care about that detail very much.
> 
> > While I'm not entirely against the idea of having this in core, I look
> > at this in terms of what do we gain, and what do we lose. If we were to
> > make this API core:
> > 
> > 1. We gain a little bit by not jumping through the extension API hoops
> 
> In my opinion avoiding the extension API hoops is a pretty big
> advantage. Normally an extension can disappear at any time, because the
> module can be unloaded. Do you think this should also be the case for
> the combine-manager API? If the extension can be or become unavailable,
> that will inherently make the API more complex.
> 
> One option would be to implement some kind of transparent on-demand
> loading of the manager module, and prevent it from being unloaded while
> there are clients using it. That would still require applications to
> register themselves as users of the API, which could be avoided if the
> API was always available.
> 
> > 2. We lose a little flexibility, because IMO the core API is more of a
> > commitment for us than an extension API (we would still want to be very
> > very reluctant to ever break it)
> 
> I don't think 

Re: [pulseaudio-discuss] [PATCH] added two new commands to native API to control the combine sink slaves after the combine sink has been created

2017-01-11 Thread Tanu Kaskinen
On Wed, 2017-01-11 at 17:44 +0530, Arun Raghavan wrote:
> On Wed, 11 Jan 2017, at 03:45 AM, Tanu Kaskinen wrote:
> > Thanks for the patch!
> > 
> > On Thu, 2017-01-05 at 20:13 +0100, Steffen Pfendtner wrote:
> > > Subject: [PATCH] added two new commands to native API to control the 
> > > combine sink slaves after the combine sink has been created
> > 
> > There's a misunderstanding: you edited the command line interface, not
> > the native protocol. Applications use libpulse, which implements the
> > native protocol, so that's where the client interface should be added.
> > The command line interface is used by pacmd and the startup script
> > interpreter. If you already integrated this feature in pulseaudio-dlna, 
> > I guess you run pacmd commands from pulseaudio-dlna?
> > 
> > We have two similar tools: pacmd and pactl. Unlike pacmd, pactl is a
> > regular client that uses libpulse to interact with the server. It's
> > pretty pointless to have two tools that do the same thing, so I hope we
> > can get rid of pacmd some day. pacmd doesn't work over the network, and
> > also doesn't work when pulseaudio runs in the system mode.
> > 
> > You can add this functionality in the command line interface if you
> > really want to, but if you do that, you have to add it to pactl as
> > well, because I don't want new features in pacmd that are not supported
> > by pactl. Adding the functionality to pactl is highly desirable even if
> > you don't add the functionality to the command line interface, though.
> > 
> > Assuming that the API is added to the "core" instead as a protocol
> > extension (see my previous mails: [1][2][3]), you'll need to add new
> > commands that are sent from src/pulse/introspect.c and handled in
> > src/pulsecore/protocol-native.c. I would suggest adding
> > src/pulsecore/combine-sink.[ch] that has pa_combine_sink_add_output()
> > and pa_combine_sink_remove_output() along with anything else protocol-
> > native.c needs for dealing with the new commands. The API shouldn't be
> > in sink.h, because that's for common sink functionality, while this API
> > is only for one specific sink implementation.
> 
> First, to make this concrete. module-combine currently allows multiple
> instances, so I guess we would either need to change it to allow a
> single instance, or add a module-combine-manager module to implement the
> extension API. I prefer the former.

Presumably you'd then add some new argument to module-combine-sink to
signal that it should run in the "manager mode"? If we are going the
extension route, I would prefer a separate manager module, but I don't
care about that detail very much.

> While I'm not entirely against the idea of having this in core, I look
> at this in terms of what do we gain, and what do we lose. If we were to
> make this API core:
> 
> 1. We gain a little bit by not jumping through the extension API hoops

In my opinion avoiding the extension API hoops is a pretty big
advantage. Normally an extension can disappear at any time, because the
module can be unloaded. Do you think this should also be the case for
the combine-manager API? If the extension can be or become unavailable,
that will inherently make the API more complex.

One option would be to implement some kind of transparent on-demand
loading of the manager module, and prevent it from being unloaded while
there are clients using it. That would still require applications to
register themselves as users of the API, which could be avoided if the
API was always available.

> 2. We lose a little flexibility, because IMO the core API is more of a
> commitment for us than an extension API (we would still want to be very
> very reluctant to ever break it)

I don't think there's any real difference in commitment. An API break
is an API break, the effects are the same regardless of whether the API
is labeled as "core" or "extension".

> 3. We lose a little more flexibility because combine becomes THE way to
> group outputs in the core API, or we have API duplication if we revisit
> other mechanisms (such as the node routing layer)

I don't have high hopes for the new routing layer being resurrected
anytime soon, but even if it will be, it will anyway duplicate all
existing routing APIs, so I don't feel it's that bad adding another bit
of routing APIs that might get duplicated by the new layer.

> There are minor concerns around what happens if-module-combine-sink
> isn't available for some reason in both cases, but that's not something
> that would swing my opinion either way.

I'm not sure what you mean by "not available". Do you mean that the
module is not installed, or not loaded? If you mean not installed, I
think that case is safe to ignore. If a distribution doesn't install
module-combine-sink along with the main pulseaudio package, that's
their fault. I don't think we need to support that.

> Given this, I lean towards having an extension API. If you have strong
> reasons to prefer the core API, I'm still 

Re: [pulseaudio-discuss] [PATCH] added two new commands to native API to control the combine sink slaves after the combine sink has been created

2017-01-11 Thread Arun Raghavan
On Wed, 11 Jan 2017, at 03:45 AM, Tanu Kaskinen wrote:
> Thanks for the patch!
> 
> On Thu, 2017-01-05 at 20:13 +0100, Steffen Pfendtner wrote:
> > Subject: [PATCH] added two new commands to native API to control the 
> > combine sink slaves after the combine sink has been created
> 
> There's a misunderstanding: you edited the command line interface, not
> the native protocol. Applications use libpulse, which implements the
> native protocol, so that's where the client interface should be added.
> The command line interface is used by pacmd and the startup script
> interpreter. If you already integrated this feature in pulseaudio-dlna, 
> I guess you run pacmd commands from pulseaudio-dlna?
> 
> We have two similar tools: pacmd and pactl. Unlike pacmd, pactl is a
> regular client that uses libpulse to interact with the server. It's
> pretty pointless to have two tools that do the same thing, so I hope we
> can get rid of pacmd some day. pacmd doesn't work over the network, and
> also doesn't work when pulseaudio runs in the system mode.
> 
> You can add this functionality in the command line interface if you
> really want to, but if you do that, you have to add it to pactl as
> well, because I don't want new features in pacmd that are not supported
> by pactl. Adding the functionality to pactl is highly desirable even if
> you don't add the functionality to the command line interface, though.
> 
> Assuming that the API is added to the "core" instead as a protocol
> extension (see my previous mails: [1][2][3]), you'll need to add new
> commands that are sent from src/pulse/introspect.c and handled in
> src/pulsecore/protocol-native.c. I would suggest adding
> src/pulsecore/combine-sink.[ch] that has pa_combine_sink_add_output()
> and pa_combine_sink_remove_output() along with anything else protocol-
> native.c needs for dealing with the new commands. The API shouldn't be
> in sink.h, because that's for common sink functionality, while this API
> is only for one specific sink implementation.

First, to make this concrete. module-combine currently allows multiple
instances, so I guess we would either need to change it to allow a
single instance, or add a module-combine-manager module to implement the
extension API. I prefer the former.

While I'm not entirely against the idea of having this in core, I look
at this in terms of what do we gain, and what do we lose. If we were to
make this API core:

1. We gain a little bit by not jumping through the extension API hoops

2. We lose a little flexibility, because IMO the core API is more of a
commitment for us than an extension API (we would still want to be very
very reluctant to ever break it)

3. We lose a little more flexibility because combine becomes THE way to
group outputs in the core API, or we have API duplication if we revisit
other mechanisms (such as the node routing layer)

There are minor concerns around what happens if-module-combine-sink
isn't available for some reason in both cases, but that's not something
that would swing my opinion either way.

Given this, I lean towards having an extension API. If you have strong
reasons to prefer the core API, I'm still quite open to being convinced.
:)

Cheers,
Arun
___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH] added two new commands to native API to control the combine sink slaves after the combine sink has been created

2017-01-10 Thread Tanu Kaskinen
Thanks for the patch!

On Thu, 2017-01-05 at 20:13 +0100, Steffen Pfendtner wrote:
> Subject: [PATCH] added two new commands to native API to control the combine 
> sink slaves after the combine sink has been created

There's a misunderstanding: you edited the command line interface, not
the native protocol. Applications use libpulse, which implements the
native protocol, so that's where the client interface should be added.
The command line interface is used by pacmd and the startup script
interpreter. If you already integrated this feature in pulseaudio-dlna, 
I guess you run pacmd commands from pulseaudio-dlna?

We have two similar tools: pacmd and pactl. Unlike pacmd, pactl is a
regular client that uses libpulse to interact with the server. It's
pretty pointless to have two tools that do the same thing, so I hope we
can get rid of pacmd some day. pacmd doesn't work over the network, and
also doesn't work when pulseaudio runs in the system mode.

You can add this functionality in the command line interface if you
really want to, but if you do that, you have to add it to pactl as
well, because I don't want new features in pacmd that are not supported
by pactl. Adding the functionality to pactl is highly desirable even if
you don't add the functionality to the command line interface, though.

Assuming that the API is added to the "core" instead as a protocol
extension (see my previous mails: [1][2][3]), you'll need to add new
commands that are sent from src/pulse/introspect.c and handled in
src/pulsecore/protocol-native.c. I would suggest adding
src/pulsecore/combine-sink.[ch] that has pa_combine_sink_add_output()
and pa_combine_sink_remove_output() along with anything else protocol-
native.c needs for dealing with the new commands. The API shouldn't be
in sink.h, because that's for common sink functionality, while this API
is only for one specific sink implementation.

[1] 
https://lists.freedesktop.org/archives/pulseaudio-discuss/2016-December/027234.html
[2] 
https://lists.freedesktop.org/archives/pulseaudio-discuss/2016-December/027235.html
[3] 
https://lists.freedesktop.org/archives/pulseaudio-discuss/2016-December/027236.html

-- 
Tanu

https://www.patreon.com/tanuk
___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH] added two new commands to native API to control the combine sink slaves after the combine sink has been created

2017-01-05 Thread Steffen Pfendtner
---
 src/modules/module-combine-sink.c | 92 +++
 src/pulsecore/cli-command.c   | 78 +
 src/pulsecore/sink.c  | 32 ++
 src/pulsecore/sink.h  |  8 
 4 files changed, 210 insertions(+)

diff --git a/src/modules/module-combine-sink.c 
b/src/modules/module-combine-sink.c
index b6322c6..4a91901 100644
--- a/src/modules/module-combine-sink.c
+++ b/src/modules/module-combine-sink.c
@@ -1249,6 +1249,95 @@ static pa_hook_result_t 
sink_state_changed_hook_cb(pa_core *c, pa_sink *s, struc
 return PA_HOOK_OK;
 }
 
+void update_slaves_prop(pa_sink *combine_sink, struct userdata *u) {
+
+uint32_t idx;
+char *t;
+bool first = true;
+struct output *o;
+pa_proplist *pl;
+
+PA_IDXSET_FOREACH(o, u->outputs, idx) {
+char *e;
+if (first) {
+e = pa_sprintf_malloc("%s", pa_strnull(o->sink->name));
+first = false;
+} else {
+e = pa_sprintf_malloc("%s, %s", t, pa_strnull(o->sink->name));
+pa_xfree(t);
+}
+t = e;
+}
+/* if still first we have no outputs in the list */
+if (first) {
+t = pa_sprintf_malloc("");
+}
+
+pl = pa_proplist_new();
+pa_proplist_setf(pl, "combine.slaves", t);
+pa_xfree(t);
+pa_sink_update_proplist(combine_sink, PA_UPDATE_REPLACE, pl);
+pa_proplist_free(pl);
+}
+
+/* Called from main context on native API call */
+static int add_output(pa_sink *combine_sink, pa_sink *slave_sink) {
+struct userdata *u;
+struct output *o;
+
+pa_sink_assert_ref(combine_sink);
+pa_sink_assert_ref(slave_sink);
+pa_assert_se(u = combine_sink->userdata);
+
+if (u->automatic) {
+pa_log("combine sink is automatic, cannot add: '%s'.", 
slave_sink->name);
+return -2;
+}
+
+if ((o = find_output(u, slave_sink))) {
+pa_log("Sink already on combine sink: '%s'.", slave_sink->name);
+return -3;
+}
+
+if (!(o = output_new(u, slave_sink))) {
+pa_log("Failed to add sink to combine sink: '%s'.", slave_sink->name);
+return -4;
+}
+output_verify(o);
+update_slaves_prop(combine_sink, u);
+
+pa_log("Add output sink");
+return 0;
+}
+
+/* Called from main context on native API call */
+static int del_output(pa_sink *combine_sink, pa_sink *slave_sink) {
+struct userdata *u;
+struct output *o;
+
+pa_sink_assert_ref(combine_sink);
+pa_sink_assert_ref(slave_sink);
+pa_assert_se(u = combine_sink->userdata);
+
+if (u->automatic) {
+pa_log("combine sink is automatic, cannot del: '%s'.", 
slave_sink->name);
+return -2;
+}
+
+if (!(o = find_output(u, slave_sink))) {
+pa_log("Could not remove %s from combine sink, output was not found",
+slave_sink->name);
+return -3;
+}
+
+pa_idxset_remove_by_data(u->outputs, o, NULL);
+output_free(o);
+update_description(u);
+update_slaves_prop(combine_sink, u);
+pa_log("Del output sink");
+return 0;
+}
+
 int pa__init(pa_module*m) {
 struct userdata *u;
 pa_modargs *ma = NULL;
@@ -1401,6 +1490,9 @@ int pa__init(pa_module*m) {
 u->sink->set_state = sink_set_state;
 u->sink->update_requested_latency = sink_update_requested_latency;
 u->sink->userdata = u;
+u->sink->module = m;
+u->sink->combine_add_output = add_output;
+u->sink->combine_del_output = del_output;
 
 pa_sink_set_rtpoll(u->sink, u->rtpoll);
 pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq);
diff --git a/src/pulsecore/cli-command.c b/src/pulsecore/cli-command.c
index 9a73605..ba168d5 100644
--- a/src/pulsecore/cli-command.c
+++ b/src/pulsecore/cli-command.c
@@ -135,6 +135,8 @@ static int pa_cli_command_sink_port(pa_core *c, 
pa_tokenizer *t, pa_strbuf *buf,
 static int pa_cli_command_source_port(pa_core *c, pa_tokenizer *t, pa_strbuf 
*buf, bool *fail);
 static int pa_cli_command_port_offset(pa_core *c, pa_tokenizer *t, pa_strbuf 
*buf, bool *fail);
 static int pa_cli_command_dump_volumes(pa_core *c, pa_tokenizer *t, pa_strbuf 
*buf, bool *fail);
+static int pa_cli_command_combine_sink_add_output(pa_core *c, pa_tokenizer *t, 
pa_strbuf *buf, bool *fail);
+static int pa_cli_command_combine_sink_del_output(pa_core *c, pa_tokenizer *t, 
pa_strbuf *buf, bool *fail);
 
 /* A method table for all available commands */
 
@@ -191,6 +193,8 @@ static const struct command commands[] = {
 { "set-log-meta",pa_cli_command_log_meta,   "Show 
source code location in log messages (args: bool)", 2},
 { "set-log-time",pa_cli_command_log_time,   "Show 
timestamps in log messages (args: bool)", 2},
 { "set-log-backtrace",   pa_cli_command_log_backtrace,  "Show 
backtrace in log messages (args: frames)", 2},
+{ "combine-sink-add-output", pa_cli_command_combine_sink_add_output, "Add 
a output sink to the