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

Tanu Kaskinen tanuk at iki.fi
Thu Jul 2 08:13:11 PDT 2015

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.

> > 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.

> > 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?


More information about the pulseaudio-discuss mailing list