Use the HDMI/Diplayport device's eld info to automatically determine sink formats and bitrate
This might belong on a different bug tracker, or it might be misconfiguration on my part so please let me know if this should be reported elsewhere.
My audio receiver supports DTS and AC3, this works great once the relevant checkboxes have been checked in pavucontrol:
VLC picks this up and AC3/DTS audio is automatically passed through the HDMI instead of the default analogue Line Out.
The problem however is that every time the TV is turned on this setting is reset and I have to go back into pavucontrol to check the DTS/AC3 checkboxes. This specific TV has a 'problem' where waking up from standby causes the PC to think it disconnected, and immediately reconnected (i.e. the KDE Plasma desktop flashes a couple of times as it adjusts the display configuration, this happens in Windows as well). The same happens if I unplug, and re-plug the HDMI cable, the "advanced options" in pavucontrol are reset.
This has been an annoyance for a while, even before the switch from pulseaudio to pipewire/wireplumber. However, I recently discovered that Windows somehow manages to auto-detect that the receiver supports DTS and AC3, which makes pass-through work out of the box (if allowing exclusive control of the audio interface is enabled) and also eliminates the problem where I have to manually set the supported formats every time the TV turns on.
This got me thinking that this auto-detection and configuration should in theory also be possible in Linux. After all, if it works in Windows this means the hardware certainly supports detecting which encoded formats are supported. Unfortunately despite a lot of searching I could not find a way to accomplish this and fix my problem. So my question is:
- What would it take to automatically detect the supported encoded audio formats of a connected display or receiver? I suppose some sort of handshake is involved, does the Linux kernel support this?
- If we can automatically detect this, how can I configure wireplumber/pipewire to use the supported formats automatically? Perhaps I can write some sort of script to automatically set the supported formats and run this after wireplumber/pipewire starts and when udev detects that a new output has been connected.
- If automatic detection and configuration is not possible? Would it be possible for wireplumber to remember the settings of a connected display? I.e. store the supported encoded formats on disconnect and restore these settings if the same display/receiver is connected again.
[EDIT]
- What would it take to automatically detect the supported encoded audio formats of a connected display or receiver? I suppose some sort of handshake is involved, does the Linux kernel support this?
To answer my first question myself, I just now discover that cat /proc/asound/card1/eld\#2.0
contains this information:
monitor_present 1
eld_valid 1
codec_pin_nid 0x4
codec_dev_id 0x0
codec_cvt_nid 0x3
monitor_name HKC-TV
connection_type DisplayPort
eld_version [0x2] CEA-861D or below
edid_version [0x3] CEA-861-B, C or D
manufacture_id 0x6321
product_id 0x0
port_id 0x0
support_hdcp 0
support_ai 1
audio_sync_delay 0
speakers [0xf] FL/FR LFE FC RL/RR
sad_count 4
sad0_coding_type [0x1] LPCM
sad0_channels 2
sad0_rates [0x1ee0] 32000 44100 48000 88200 96000 176400 192000
sad0_bits [0xe0000] 16 20 24
sad1_coding_type [0x1] LPCM
sad1_channels 6
sad1_rates [0x1ee0] 32000 44100 48000 88200 96000 176400 192000
sad1_bits [0xe0000] 16 20 24
sad2_coding_type [0x2] AC-3
sad2_channels 6
sad2_rates [0x1ee0] 32000 44100 48000 88200 96000 176400 192000
sad2_max_bitrate 640000
sad3_coding_type [0x7] DTS
sad3_channels 6
sad3_rates [0x1ee0] 32000 44100 48000 88200 96000 176400 192000
sad3_max_bitrate 1536000
This means that the kernel and ALSA at least know that the connected display/reciever supports AC3 and DTS, thus this part of the auto-detection is already in place. The question that remains is how to get wireplumber/pipewire to use this information.