raspberrypi / linux

Kernel source tree for Raspberry Pi-provided kernel builds. Issues unrelated to the linux kernel should be posted on the community forum at https://forums.raspberrypi.com/
Other
11.15k stars 5k forks source link

No HDMI audio with KMS #5525

Open physkets opened 1 year ago

physkets commented 1 year ago

Describe the bug

When I use the KMS driver, there is no HDMI audio device present, as per alsamixer. In spite of that, when using VLC, the connected HDMI television does play audio. However, I hear nothing when using Chromium.

Upon switching to fKMS, all applications generate audio.

Steps to reproduce the behaviour

  1. Open Chromium
  2. Navigate to YouTube
  3. Play any link
  4. Hear no sound

Device (s)

Raspberry Pi 4 Mod. B

System

With fKMS: info_raspi_fKMS.txt

With KMS: info_raspi_KMS.txt

Logs

No response

Additional context

I had first raised this issue on the forum: https://forums.raspberrypi.com/viewtopic.php?p=2116517

6by9 commented 1 year ago

What does aplay -l report?

The HDMI driver with KMS has no controls at the ALSA level. It needs IEC958 formatted data, which is normally done via either the ALSA conf file, or via Pulseaudio / Pipewire.

If VLC can play audio, then it's more likely to be a configuration issue in Chromium than a kernel issue. VLC has config options for playing the audio through the non-default device, which AFAIK Chromium doesn't.

physkets commented 1 year ago
$ aplay -l 
**** List of PLAYBACK Hardware Devices ****
card 0: Headphones [bcm2835 Headphones], device 0: bcm2835 Headphones [bcm2835 Headphones]
  Subdevices: 8/8
  Subdevice #0: subdevice #0
  Subdevice #1: subdevice #1
  Subdevice #2: subdevice #2
  Subdevice #3: subdevice #3
  Subdevice #4: subdevice #4
  Subdevice #5: subdevice #5
  Subdevice #6: subdevice #6
  Subdevice #7: subdevice #7
card 1: vc4hdmi0 [vc4-hdmi-0], device 0: MAI PCM i2s-hifi-0 [MAI PCM i2s-hifi-0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 2: vc4hdmi1 [vc4-hdmi-1], device 0: MAI PCM i2s-hifi-0 [MAI PCM i2s-hifi-0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

I see.. how do I play around with the audio configuration of Chromium? I don't see anything in its settings.

6by9 commented 1 year ago

I suspect Chromium is using the system defaults. If you right click the speaker icon in the top right tool bar, then there should be a drop down list of the available audio devices. HDMI should be in that list (potentially as HDMI-1 and HDMI-2 if you have 2 HDMI monitors connected).

physkets commented 1 year ago

I already have HDMI selected from that drop-down menu.

popcornmix commented 1 year ago

There is also a "device profiles" option there. I assume that is set to "Digital Stereo (HDMI) Output" and not "Off"?

popcornmix commented 1 year ago

If you have a spare sdcard, then it would be useful to install a clean RPiOS Bullseye on it, and then test chromium audio before any other package installs or configuration changes.

I've just tested chromium on RPiOS bullseye and I hear the hdmi audio through youtube just fine.

It would be good to confirm if your issue is broken from a clean image (which suggests, perhaps TV related). Or whether it is some package that has been installed, or config files edited that has stopped it working.

popcornmix commented 1 year ago

Ah - I tried using your edid file, and I do see in dmesg:

[   13.696169] hdmi-audio-codec hdmi-audio-codec.0.auto: Not able to map channels to speakers (-22)
[   13.696189] hdmi-audio-codec hdmi-audio-codec.0.auto: ASoC: error at snd_soc_pcm_dai_prepare on i2s-hifi: -22
[   13.696196]  MAI: ASoC: error at __soc_pcm_prepare on MAI: -22

which I also see in your log file.

I am getting audio, but it sounds a little glitchy.

Let me see what's in your edid that causes the channel mapping complaints.

popcornmix commented 1 year ago

Okay I understand the channel mapping complaints. From your edid:

  Audio Data Block:
    Linear PCM:
      Max channels: 2
      Supported sample rates (kHz): 48 44.1 32
      Supported sample sizes (bits): 24 20 16
    AAC LC:
      Max channels: 6
      Supported sample rates (kHz): 48 44.1 32
      Maximum bit rate: 640 kb/s
  Speaker Allocation Data Block:
    FL/FR - Front Left/Right

It looks like alsa tries both of these formats: [ 18.667295] hdmi-audio-codec hdmi-audio-codec.0.auto: hdmi_codec_prepare() width 32 rate 44100 channels 6 [ 18.668837] hdmi-audio-codec hdmi-audio-codec.0.auto: Not able to map channels to speakers (-22) [ 18.668852] hdmi-audio-codec hdmi-audio-codec.0.auto: ASoC: error at snd_soc_pcm_dai_prepare on i2s-hifi: -22 [ 18.707694] hdmi-audio-codec hdmi-audio-codec.0.auto: hdmi_codec_prepare() width 32 rate 44100 channels 2

But reasonably says 6 channels and 2 speakers doesn't match. But it's not an error - the 2 channel output succeeds.

I've also changed hdmi cable and audio is perfect (I was also getting video dropouts previously). I've now switched to 1080p60 output (which matches your log) and again its is fine.

So currently I can't see an issue here, so I'd like to know the results of a clean install.

Ping @HiassofT - AAC passthrough support seems very unusual. But I wonder if ALSA should even be considering opening PCM with 6 channels - possibly an additional case from https://github.com/raspberrypi/linux/pull/5518

HiassofT commented 1 year ago

@popcornmix is pulse's output profile set to multichannel HDMi output maybe? I'd guess it should work fine if set to Digital Stereo (HDMI) as then pulse should request only 2ch output from ALSA

popcornmix commented 1 year ago

Yes, profile was Digital stereo but we get this call:

[   18.341589] hdmi-audio-codec hdmi-audio-codec.0.auto: hdmi_codec_prepare() width 32 rate 44100 channels 6

with this backtrace:

[   18.342038]  hdmi_codec_prepare+0xec/0x170 [snd_soc_hdmi_codec]
[   18.342049]  snd_soc_pcm_dai_prepare+0x5c/0x108 [snd_soc_core]
[   18.342123]  __soc_pcm_prepare+0x4c/0x120 [snd_soc_core]
[   18.342164]  soc_pcm_prepare+0x38/0x60 [snd_soc_core]
[   18.342206]  snd_pcm_do_prepare+0x38/0x58 [snd_pcm]
[   18.342246]  snd_pcm_action_single+0x50/0xb0 [snd_pcm]
[   18.342271]  snd_pcm_action_nonatomic+0xa8/0xb0 [snd_pcm]
[   18.342296]  snd_pcm_prepare+0x78/0xa8 [snd_pcm]
[   18.342320]  snd_pcm_common_ioctl+0xef0/0x1550 [snd_pcm]
[   18.342345]  snd_pcm_ioctl+0x38/0x50 [snd_pcm]
[   18.342370]  __arm64_sys_ioctl+0xb0/0xf8
HiassofT commented 1 year ago

Do these messages only appear on pulse startup? If yes my guess is pulse is probing available formats/channels and the message can be safely ignored - kernel is rightfully rejecting 6ch mode.

Fixing the AAC constraints should remove the messages but alas I don't have specs for it (my guess is they could be the same as for AC3/DTS, i.e. 2ch at 32/44.1/48 but I'm not 100% sure)

physkets commented 1 year ago

There is also a "device profiles" option there. I assume that is set to "Digital Stereo (HDMI) Output" and not "Off"?

Yes, the device profile is set to Digital Stereo.

It would be good to confirm if your issue is broken from a clean image (which suggests, perhaps TV related).

This occurs with a clean install as well (aside from adding SSH & WiFi through the Imager and then connecting a Bluetooth keyboard).

If it is an issue with the TV, why is Chromium able to play audio when on fKMS? And why is VLC able to produce sound even otherwise?

popcornmix commented 1 year ago

kms and fkms have completely different alas drivers (one runs on the firmware, one on the arm in the kernel). They report different names and supported formats. There are many reasons why they may behave differently.

I'm not an expert on pulseaudio, but could you run this command:

pactl list sink-inputs sinks

when playing a youtube video through chromium (and hearing no sound) and when playing with VLC (and hearing sounds), and report the output of each.

I'd like to know if pulse believes it is active in both cases, and if there's any difference in paramaters (e.g. number of channels and sample rate) in each case.

physkets commented 1 year ago

I am attaching outputs of the command for three cases:

  1. Nothing playing: pactl_sinks_control.txt
  2. Audio playing on VLC: pactl_sinks_ok-audio_vlc.txt
  3. No audio on Chromium: pactl_sinks_no-audio_chromium.txt

The only difference between the VLC and Chromium files seems to be the sample rate. When I'm playing a YouTube video on Chromium that generates no audio, it shows 44100Hz, while when VLC plays music that does produce sound, it shows 48000Hz. Could that be causing the this behaviour?

popcornmix commented 1 year ago

It's quite possible the sample rate is relevant (e.g. the display doesn't actually support 44100Hz despite reporting support in the edid).

Can you edit /etc/pulse/daemon.conf and add the line

default-sample-rate = 48000

(without a ; at start) and reboot and try again? pactl list sink-inputs sinks should now report Sample Specification: s16le 2ch 48000Hz Do you get audio?

physkets commented 1 year ago

Yess!! That worked!

So how is the fKMS driver able to pick/pass-on the right sample rate, if the EDID reports one that is unsupported?

macmpi commented 1 year ago

It's quite possible the sample rate is relevant (e.g. the display doesn't actually support 44100Hz despite reporting support in the edid).

Interesting! Would there be a similar trick on pure ALSA setup ?

popcornmix commented 1 year ago

Editing the edid to remove advertising of 44100Hz support would likely work with alsa and non alsa.

physkets commented 1 year ago

Do I close this issue? I'm still a bit confused as to where the actual issue lies.

popcornmix commented 1 year ago

Leave it for now. I'm just seeing if a hdmi analyser can see any issue with the kms audio output at 44.1kHz compared to fkms.

HiassofT commented 1 year ago

Removing 44.1 from EDID won't help, 32/44.1/48kHz are mandatory rates for all HDMI devices supporting audio (and the kernel driver will always allow them).

The issue is the TV which doesn't conform to the HDMI standard. EDIT: scratch that, if fkms is working it's likely something else

BTW: for ALSA only you can simply force a fixed rate by using this ~/.asoundrc (the default alsa PCM will then automatically resample any rate to 48kHz)

pcm.!default {
    type plug
    slave {
        pcm "hdmi:CARD=vc4hdmi0,DEV=0"
        rate 48000
    }
}
popcornmix commented 1 year ago

@HiassofT I am seeing something suspicious. When running with pulseaudio and a 44.1kHz client. e.g.

aplay  ~/dell/audio/norah.wav
Playing WAVE '/home/pi/dell/audio/norah.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo

We output 44.1kHz audio over hdmi. But the analyser shows the channel status bits as 04 82 00 02 which decodes as 48kHz

If I add logging to alsa-lib here I see those numbers.

If I change this to be unconditional, then we replace the final 02 with a 00 and the analyser decodes the CSB as 44.1kHz (and the red timing errors go away).

If I stop pulseaudio, and run the aplay line again, alsalib is called with 04 82 00 00 and analyser gets 44.1kHz and is happy.

So it feels like pulseaudio is opening alsa with an incorrect AES setting (saying 48kHz when it's 44.1kHz) and causing this issue.

Although a quick grep through pulseaudio doesn't look like it is setting AES (except in passthrough mode).

HiassofT commented 1 year ago

@popcornmix looking at the pcm_iec958 code I think it could happen when pulse calls hw_params multiple times with different rates, without re-opening the alsa device.

If no rate info is provided in AES (the default unless set explicitly), i.e. rate is NOTID then the first hw_params call will fill in the rate, but subsequent calls won't (as it's no longer NOTID).

could you try with this alsa-lib patch? iec.patch.txt

popcornmix commented 1 year ago

I don't have analyser here, but from logging I don't think that helped. I play youtube video and get:

$ cat /proc/asound/card1/pcm0p/sub0/hw_params 
access: MMAP_INTERLEAVED
format: IEC958_SUBFRAME_LE
subformat: STD
channels: 2
rate: 44100 (44100/1)
period_size: 661
buffer_size: 2644

I've added logging (here) and get:

_snd_pcm_iec958_open: hdmi:1: status:7fa0005270)
_snd_pcm_iec958_open: hdmi:1: STATUS bits: 04 82 00 02
snd_pcm_iec958_open: name:hdmi:1 4 82 0 2 (1)
snd_pcm_iec958_hw_params: 4 82 0 2
snd_pcm_iec958_hw_params: 4 82 0 2
_snd_pcm_iec958_open: hdmi:1: status:7fa0004010)
_snd_pcm_iec958_open: hdmi:1: STATUS bits: 04 82 00 02
snd_pcm_iec958_open: name:hdmi:1 4 82 0 2 (1)
snd_pcm_iec958_hw_params: 4 82 0 2
snd_pcm_iec958_hw_params: 4 82 0 2

so it looks like _snd_pcm_iec958_open is called with a "status" config entry that decodes to "4 82 0 2" which is the incorrect 48000.

HiassofT commented 1 year ago

Thanks for testing!

I did some tests, too, and noticed the AES3 value 0x02 is coming from the hdmi PCM definition here: https://github.com/alsa-project/alsa-lib/blob/master/src/conf/pcm/hdmi.conf#L53

pulse just opens the device "hdmi:1" (1 is the card number) so doesn't set any AES bits and the default in pcm.conf is used.

Changing the default to 0x01 (NOTID) gave correct channel status bits. This is a bit hacky (it might cause issues on non-RPi systems that don't fill in values for NOTID) but will work fine on RPi. I'll keep thinking about some solution that could be upstreamed

popcornmix commented 1 year ago

@physkets can you remove the previous fix and instead edit /usr/share/alsa/pcm/hdmi.conf

    @args.AES3 {
        type integer
        # fs=48000Hz, clock accuracy=1000ppm
        default 0x02
    }

and replace the 0x02 after default with 0x01.

That will confirm if your audio issue is definitely caused by the channel status bits.

physkets commented 1 year ago

That does indeed fix the issue as well.

I removed the previous change and rebooted to check if the audio stopped playing. I then made this new change and after rebooting, the audio was back.

Do I keep it as is right now? Or go back to the previous fix?

popcornmix commented 1 year ago

The new fix is better so stick with it. I'll let you know when there is an update that allows you to remove it.

popcornmix commented 1 year ago

For interest, using bookworm, which uses pipewire this issue doesn't happen by default. But that is because they avoid it with a default setting from /usr/share/pipewire/pipewire.conf of

default.clock.allowed-rates = [ 48000 ]

If I add 44.1kHz into there, I get the same error with 44.1KHz audio being used but 48kHz transmitted in csb.

Ah - I've found where pipewire enabled 44.1kHz and then reverted it due so complaints (almost certainly due to this issue) https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/2462

archerindigo commented 1 year ago

Hi, I also encountered the same issue where the audio couldn't work on Chromium browser. I can confirm the modification on /usr/share/alsa/pcm/hdmi.conf fixes the issue. Looking forward to a proper update in the future.

Although the issue is fixed, I notice the following error messages during system bootup (both before and after the fix). Not sure if there is any thing related to this issue.

[   23.045143] hdmi-audio-codec hdmi-audio-codec.0.auto: Not able to map channels to speakers (-22)
[   23.045201] hdmi-audio-codec hdmi-audio-codec.0.auto: ASoC: error at snd_soc_pcm_dai_prepare on i2s-hifi: -22
[   23.045210]  MAI: ASoC: error at __soc_pcm_prepare on MAI: -22
[   23.045520] hdmi-audio-codec hdmi-audio-codec.0.auto: Not able to map channels to speakers (-22)
[   23.045529] hdmi-audio-codec hdmi-audio-codec.0.auto: ASoC: error at snd_soc_pcm_dai_prepare on i2s-hifi: -22
[   23.045535]  MAI: ASoC: error at __soc_pcm_prepare on MAI: -22
(The error repeated for like 20 times and then stopped)

Despite the error, I don't experience any actual problem with the audio.