[pulseaudio-discuss] RFC: Public API for managing nodes

Tanu Kaskinen tanu.kaskinen at linux.intel.com
Tue Aug 6 05:30:40 PDT 2013


On Tue, 2013-08-06 at 13:26 +0200, David Henningsson wrote:
> On 08/05/2013 01:37 PM, Tanu Kaskinen wrote:
> > On Wed, 2013-07-17 at 12:26 +0200, David Henningsson wrote:
> >> On 07/17/2013 11:22 AM, Tanu Kaskinen wrote:
> >>> On Wed, 2013-07-17 at 09:27 +0200, David Henningsson wrote:
> >>>> On 07/16/2013 03:20 PM, Tanu Kaskinen wrote:
> >>>>> Yes, there can be both an explicit and a default connection between two
> >>>>> nodes, or it can be also thought as being one connection that is both
> >>>>> explicit and default. I don't know what is a better way to think about
> >>>>> it, but perhaps it doesn't matter anyway.
> >>>>
> >>>> I would prefer the latter way. I would then see "default" and "explicit"
> >>>> as a property of the edge.
> >>>
> >>> I agree about that, at a conceptual level. Would you perhaps like to
> >>> have it this way also at the code level, i.e. have connection objects
> >>> with "default" and "explicit" fields instead of storing the information
> >>> in the nodes?
> >>
> >> Good question. Actually one option could be to store the connections as 
> >> global list-like matrix instead of lists on the individual node objects. 
> >> After all, you'll need the connection on both sides, and unless you want 
> >> to duplicate information, you'll have to do a global search on one of 
> >> the sides anyway. Since the number of nodes < 100, I don't think this 
> >> would matter from a performance standpoint.
> >>
> >> You would end up with a global list with entries looking something like:
> >>
> >> struct pa_node_connection_t {
> >>    pa_node *from_node;
> >>    pa_node *to_node;
> >>    bool default;
> > 
> > A single "default" boolean isn't enough. A connection may be part of
> > both endpoints' default routing, or just one. It's necessary to
> > differentiate between the different cases, because disabling one node's
> > default connections may not remove the connection, if it's also a
> > default connection of the other node.
> 
> I'm not sure I know the background enough to understand why you need to
> store whether the connection is done on the basis on a request from the
> from_node or to_node (?), but at this point, sure, we can have a bool
> from_default and a bool to_default if that solves your problem.

When you proposed the struct, you assumed that blacklisting would be
available, and in that case you might not need to know the origin of the
default connection. I failed to take this into account when I said that
a single boolean isn't enough.

If default connections are removed by disabling all default routing for
a node, as opposed to blacklisting certain connections, then you need to
know which node you need to request to disable its default routing in
order to get rid of the default connection.

> >>>>> What operations do you mean? Moving or removing a default connection is
> >>>>> not supported as such, but if the client tries that anyway, we can
> >>>>> implicitly convert the connection to an explicit one and disable default
> >>>>> connections, or we can require the client to do these operations
> >>>>> explicitly, but I think the latter would be too inconvenient for the
> >>>>> client.
> >>>>
> >>>> Ok, I think I didn't read the proposal well enough. Having done that, I
> >>>> understand that you're suggesting a global switch "default connections
> >>>> on/off" only. Or is it a per-node switch?
> >>>
> >>> It is a per-node switch.
> >>>
> >>>> I have another idea that might be worth considering: how about that the
> >>>> "explicit" layer can both enable and disable connections? So that there
> >>>> could be a default connection between A and B, but there is also some
> >>>> sort of explicit override that disables it. This would be more flexible
> >>>> than a more global on/off switch.
> >>>
> >>> I'm not sure what you mean. Do you perhaps mean that the default
> >>> connection on/off switch should be per-node (which it already is in my
> >>> proposal), or that it should be per-connection (so that if there are
> >>> multiple default from node A, it's possible to disable only a subset of
> >>> those)?
> >>>
> >>> I didn't make make it possible to disable individual default
> >>> connections, because I had a feeling that it would have very messy
> >>> semantics. If default connection from A to B is disabled, what is the
> >>> routing code supposed to do when conditions change and the default
> >>> routing is re-evaluated? Can it ever reactivate the connection between A
> >>> and B again? Is the per-connection disabling handled as a blacklist of
> >>> connections that must never be automatically activated?
> >>
> >> If the A -> B route is explicitly_disabled, that overrides any default 
> >> connections the routing system tries to make.
> > 
> > What is the use case for explicitly disabled connections? I'll assume
> > here that your idea was to allow moving a default connection elsewhere
> > (making the connection explicit in the process) without disabling all
> > default connections for the node.
> > 
> > When the user moves a default connection, the routing system obviously
> > shouldn't immediately create another default connection elsewhere to
> > replace the disabled connection.
> > 
> > On the other hand, if the routing system doesn't create replacement
> > connections, then that results in weird behaviour. Let's say that
> > there's a default connection A -> B, and the user moves the connection
> > to A -> C. Then B disappears. The routing changes its opinion of the
> > best available routing for A, which might be D. So removing node B
> > resulted in audio suddenly appearing in node D, even though nothing was
> > playing to B.
> > 
> 
> Assume your example of a default connection A -> B which the user
> changes into A -> C, by adding an explicit A -> C connection. Without
> some sort of explicitly_disabled blacklist that would then include A ->
> B, the routing system would be free to route A to *both* B and C.

My solution is that the application disables the default routing
altogether for A, if it doesn't want to have the default connection A ->
B. It seems to me that this causes fewer surprises than the blacklisting
approach.

> Whether this is implemented as a bool flag or as a separate blacklist is
> an implementation detail, but a bool flag just seemed simpler and faster
> to me, than having to look in several lists to figure out whether a
> connection exists or not.

You don't need to look in several lists to figure out whether a
connection exists or not. If we have connection objects, which I think
we both want to have, it's enough to get the list all connections and
see whether a particular connection is included in that list.

-- 
Tanu



More information about the pulseaudio-discuss mailing list