omxhdmiaudiosink: Center/LFE channels reversed on RPi
Submitted by Leonardo Brondani Schenkel
- Hardware: Raspberry Pi model B+
- Firmware/Kernel: https://github.com/Hexxeh/rpi-firmware/commit/ab90bf1971e4b6cd8c75d6ff7c20bf08166b613e (2018-02-23)
- uname -a: Linux rpi-d98c1025 4.14.21+
#1095Fri Feb 23 17:57:30 GMT 2018 armv6l GNU/Linux
- /etc/debian_version: 9.3
- gst-launch-1.0 --version:
gst-launch-1.0 version 1.10.4
Raspberry Pi is connected via HDMI to a Denon AVR-1911 receiver.
Steps to reproduce:
Navigate to https://www2.iis.fraunhofer.de/AAC/multichannel.html, "7.1 Channel identification", and download the file 7.1auditionOutLeader%20v2.wav:
curl -O https://www2.iis.fraunhofer.de/AAC/7.1auditionOutLeader%20v2.wav
Play the file using gstreamer:
gst-launch-1.0 -v filesrc location=7.1auditionOutLeader%20v2.wav ! decodebin ! audioconvert ! omxhdmiaudiosink
The "front center" announcement comes out from the subwoofer, not the center channel. Subwoofer channel is not audible, since it is routed to the center speaker and it is below the crossover.
At first I believed it was a Pi/firmware/kernel problem, but when I play the exact same file via omxplayer instead:
omxplayer --layout 7.1 7.1auditionOutLeader%20v2.wav
the file is played correctly, with the center channel being routed to the center speaker. Thus I believe that the channel mapping in the OMX GStreamer's plugin is reversing the channels.
As an experiment, I did try reversing the channels by setting hdmi_channel_map to 0x13FAC4C8 (110 101 100 010 011 001 000) and this worked, in the sense that GStreamer now output the channels correctly (and omxplayer incorrectly). But this has a side effect of forcing 7.1 in all output, including stereo, which prevents my receiver from upmixing or applying Dolby ProLogic.
I tried to inspect the source code to identify what omxhdmiaudiosink is doing differently than omxplayer. I am not knowledgeable enough in OMX to be able to definitely pinpoint the problem, but I have a guess.
What omxplayer does it the following:
In particular, line 454 first invokes BuildChannelMapCEA() (defined in 1409) which creates a channel map in which LFE comes before center (which I confirmed being the order in the CEA spec), and uses it to remap the PCM channels (line 458) before setting up the OMX channel map (line 462).
I also noticed that Kodi does something similar (both the AudioEngine implementation for the Pi and Kodi's omxplayer), however instead of reversing the PCM channels it computes a HDMI channel remap on-the-fly and sets "hdmi_channel_map" via vc_gencmd().
The fact that different are doing this hints to me they're working around a hardware/firmware bug in which the OMX implementation sends the center/LFE channels incorrectly via HDMI, so they remap the incoming PCM stream or tell the firmware to do a on-the-fly remap. Anyway, from the user perspective it results in everything working by default.
In turn, this is the code for the OMX sink:
I cannot see any remap functionality there, it just assembles a straightforward OMX channel map which results in the center/LFE channels being reversed in the output. From the user perspective, it looks like the OMX plugin is broken.
If my evaluation of this problem is correct, as an user I would be extremely happy if omxhdmiaudiosink worked by default by remapping the incoming PCM channels like omxplayer does, or alternatively setting "hdmi_channel_map" like Kodi. This could be configurable by a sink property, and if backwards-compatibility is important in this case it could be made opt-in.
Alternatively, an element that can invert center/LFE that could be inserted in the pipeline before omxhdmiaudiosink would also work. (I do not believe such element exists today that could be used from the command-line.)
Please let me know if you need any additional information. I would have submitted patches, but I do not have a development environment right now nor I know enough of GStreamer to be able to do so.