On 11/07/2013 07:27 AM, Tanu Kaskinen wrote: > On Wed, 2013-11-06 at 21:42 +0100, David Henningsson wrote: >> On 11/06/2013 06:52 PM, Tanu Kaskinen wrote: >>> On Wed, 2013-11-06 at 15:38 +0100, David Henningsson wrote: >>>> Activating a port is done by selecting a profile on a card, then >>>> selecting a port on a sink/source. >>>> And all profiles, ports, and the relationship between them, are visible >>>> to the core. >>> >>> Yes, if there is one stream that needs to be routed to a port, it's easy >>> to just go ahead and activate the port. However, consider this example: >>> there is a playback stream and a capture stream. There's an alsa card >>> which is currently having the "off" profile active. The routing policy >>> decides that the playback stream should be routed to the analog output >>> port of the alsa card. But there are two profiles to choose from: >>> analog-output+analog-input and analog-output+digital-input. If the >>> profile is chosen randomly, it may be that the preferred source won't be >>> available for the capture stream by the time the routing algorithm >>> starts finding a target for it. If a different profile would have been >>> selected earlier, both streams could have been routed to their preferred >>> targets. >>> >>> This example doesn't actually prove anything regarding whether the port >>> activation logic should be in the router or in the node backend. >>> Instead, this example shows that we need to split the routing into two >>> phases: planning and execution. In the planning phase ports are >>> allocated, and if there are multiple ways to activate them, the final >>> decisions are made only after all allocations have been done. Before the >>> final decisions all available options are kept open. This is an >>> essential aspect of the design, and I really hope I will be able to >>> convince you that it's necessary. If I can do that, then it will become >>> apparent that having access to the mapping objects is necessary in the >>> planning phase, because otherwise you don't know which ports conflict >>> with each other and which ports can be used at the same time. >> >> I'm understanding the concepts of first have a planning phase and then >> an execution phase. It seems reasonable. > > I'm very glad to hear that! > >> But which ports are in conflict with each other is also something that's >> visible to the core today - it's given by the simple constraint that >> every sink/source can have one port active only. >> >> In the case of having more than one sink (or source) per profile, maybe >> we need to make some more information available to the core to make it >> understand which port belongs to which sink. That seems to be a useful >> addition, that would be reasonably straight forward to implement, I think? > > OK, if exposing the mappings to the core is sufficient, then doing the > profile and port selection outside the node back-end is fine. However, > there are more cases to consider. > > Bluetooth: how is the core supposed to know which profile to allocate, > when there is only one node for output that is used by both A2DP and HFP > profiles? My proposal is that the core calls pa_node_allocate(), with > "connection requirement" information (if you recall from my > presentation, connection requirements were things like minimum sample > rate). When executing the routing plan, the Bluetooth back-end knows > what was requested during the planning, so it can select the appropriate > profile in pa_node_activate(). > > Allocating other resources in ALSA than just ports: if there is limited > amount of DSP processing capacity, the capacity should be reserved > during the planning phase. For this pa_node_allocate() seems like a good > solution. > > In general, it seems to me that doing resource allocation in the node > back-end is the right thing to do, because the core doesn't necessarily > have information about all resources in the back-end that affect the > node availability. The other way to go is to make that information available to the core. I think that would be a better way and allow for more reuse between backends, e g, your bluetooth example could very well apply to some ASoC scenarios too (when I was working with the Nexus 4 it had one PCM for low latency and another PCM for higher latencies). For handling DSP processing capacity, I'm not sure what is the best solution, because there are too many missing pieces. Are you planning to implement that in the ALSA backend? A new type of backend? Or was it just a random thought? Unless it's an initial requirement to support this DSP allocator, I suggest we postpone that problem/discussion. -- David Henningsson, Canonical Ltd. https://launchpad.net/~diwic