[pulseaudio-discuss] [RFC] Dynamically created PCM devices for HDMI/DisplayPort

Alexander E. Patrakov patrakov at gmail.com
Thu Jul 2 10:07:31 PDT 2015

02.07.2015 20:13, Tanu Kaskinen wrote:
> On Tue, 2015-06-30 at 22:29 +0500, Alexander E. Patrakov wrote:
>> 30.06.2015 20:08, Tanu Kaskinen wrote:
>>> Event: monitor gets plugged in
>>> ------------------------------
>>> The first thing that happens should be that PulseAudio gets a wakeup
>>> from the alsa mixer, when a new ELD control for the monitor is added.
>>> This is important, because the mixer should be ready when PulseAudio
>>> starts to use the new PCM device. It's up to the driver developer to do
>>> this right. This wakeup can be ignored, so no code changes are needed in
>>> PulseAudio to handle this.
>>> The second thing that happens is that udev notifies PulseAudio about a
>>> new PCM device. Interfacing with udev is done in
>>> src/modules/module-udev-detect.c. Currently PulseAudio only cares about
>>> new and removed cards, so module-udev-detect has to be modified to also
>>> keep track of what PCM devices each card has, so that new devices can be
>>> noticed.
>> I am not sure whether this "wakeup from alsa mixer first, from udev
>> second" ordering is something that can be relied on. But a "ELD control
>> exists when udev notifies us" requirement looks sensible.
> Do you mean a case where the mixer control and the PCM device get added
> so quickly that when it comes to waking up the pulseaudio process,
> pulseaudio notices the PCM device change first? I suppose that could
> happen. Luckily that's not an issue. The only thing that matters is that
> the mixer control is there when pulseaudio looks for it.

Yes, that's what I mean.

>>> pa_alsa_card should be defined in src/modules/alsa/alsa-card.[ch] and
>>> included in the libalsa-util.la helper library.
>>> When moving the code from module-alsa-card to pa_alsa_card, some changes
>>> to the sink and source error handling is needed. Currently, if something
>>> fails in the IO thread of an alsa sink or source, the sink/source
>>> unloads the module that owns the sink/source (see the end of
>>> thread_func() in alsa-sink.c and alsa-source.c). Now the owner module of
>>> alsa sinks and sources becomes module-udev-detect, and we certainly
>>> don't want to unload that if a single sink or source fails. The
>>> sink/source should notify the pa_alsa_card object of the failure (new
>>> functions pa_alsa_card_sink_failed() and pa_alsa_card_source_failed()),
>>> and pa_alsa_card should free the failed pa_alsa_sink or pa_alsa_source
>>> object.
>> The case of manually-loaded module-alsa-sink is not described here, but
>> should be.
> Right. When the IO thread fails, that needs to be handled in somehow
> also when using module-alsa-sink (or -source). Either pa_alsa_sink needs
> to act differently depending on whether it's owned by pa_alsa_card or by
> module-alsa-sink, or pa_alsa_sink should have callback that it calls on
> failure (pa_alsa_card and module-alsa-card would then set that callback
> and handle the failure in their own ways). I'd prefer the callback
> approach, but that's not a strong preference.


>>> Event: monitor gets unplugged
>>> -----------------------------
>>> When a monitor gets unplugged, module-udev-detect gets a notified, and
>>> it should figure out that a PCM device has disappeared. It should then
>>> call pa_alsa_card_pcm_removed(), which is a new function that needs to
>>> be implemented.
>> Again, the case of manually loaded module-alsa-sink is not considered.
> For simplicity, I propose that no special handling is added to
> module-alsa-sink. If the module is loaded for a dynamic PCM that goes
> away, that presumably will cause the IO thread to fail. The module then
> unloads itself.

Yes, that would work. OTOH, I think that the IO thread would notice the 
error before module-udev-detect gets the notification. So I am not sure 
whether any special handling of unplug events is needed in 
module-udev-detect. It would be needed if we wanted to distinguish 
between "card failed" and "card no longer exists" (like the kernel keeps 
dead /dev/sd* devices for USB flash drives that were yanked while mounted).

>>> pa_alsa_card_pcm_removed() should mirror pa_alsa_card_pcm_added(), just
>>> undoing the things that _added() did, in reverse order. So, first it
>>> should call pa_card_remove_profile(). That function doesn't exist
>>> currently, so it needs to be implemented. Next
>>> pa_alsa_card_pcm_removed() should free the pa_alsa_profile,
>>> pa_alsa_mapping and pa_alsa_path objects corresponding to the removed
>>> device. I think that's it for pa_alsa_card_pcm_removed().
>>> If the profile that is being removed is active, pa_card_remove_profile()
>>> should change the card profile to something else. I suppose it should
>>> use the same logic as what pa_card_new() uses when choosing the default
>>> profile.
>> What else is missing is the big picture of the available multi-monitor
>> use cases.
>> Currently, if one has a card with multiple HDMI outputs, one can use
>> audio from one monitor at a time, using profiles. I.e. there are no
>> profiles like "HDMI Digital Stereo Output + HDMI 3 Digital Surround
>> Output" (with the possibility to move individual streams between
>> monitors), presumably due to the combinatorial explosion. Will this
>> limitation be lifted?
> Since the dynamic profiles are created only when HDMI devices are
> actually plugged in, I guess that will avoid too bad combinatorial
> explosion. So yeah, I suppose it could be lifted for dynamic HDMI
> devices. Not a hard requirement, though.
>> Also, AFAIR, there was a discussion of a possibility to send the same
>> PCM stream to two monitors. How would that work?
> I don't remember reading that discussion, was it some other thread than
> the one I linked to? If one PCM device is connected to two HDMI devices,
> then that sounds like the PCM device is not dynamically added on monitor
> hotplug. I have the assumption that the dynamic HDMI PCM devices that
> this proposal addresses are dedicated to one HDMI output only. Is the
> situation actually more complex?

I can't find that discussion either :(

Let's suppose this is just my bad memory. Anyway, here is an old patch 
series that fixed a bug that manifested itself as "the same audio sent 
to three monitors", so this setup is definitely achievable if desired:


Alexander E. Patrakov

More information about the pulseaudio-discuss mailing list