Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Latest firmware outputs HDMI 7.1 channel PCM as 5.1 #450

Closed
tghewett opened this issue Nov 27, 2013 · 39 comments
Closed

Latest firmware outputs HDMI 7.1 channel PCM as 5.1 #450

tghewett opened this issue Nov 27, 2013 · 39 comments

Comments

@tghewett
Copy link

The latest firmware (based on 3.10.19+) produces 7.1 channel PCM as 5.1 at the receiver.

Using the current raspberry.org download of Arch Linux with its older firmware produces 7.1 channel PCM as 7.1 channels at the receiver, something went wrong around the time of the up-step from 3.6.x to 3.10.x.

Copying the current *.dat, *.bin and *.elf files to the stock Arch Linux installation makes the problem happen there too. Running a 3.10.19+ kernel built using the Arch Linux config doesn't fix it.

(Also the solution for the previous problem of S/PDIF encoded audio not being decoded at the receiver doesn't work with Arch Linux and 3.10.19+, though it is fine on Raspbian with the same firmware and the same 3.10.19+ source kernel built using the Raspbian config (which Arch Linux won't boot) ... Does the fix need a particular kernel option enabled or disabled? Both had the same *.elf, *.dat and /opt/vc files.)

@popcornmix
Copy link
Collaborator

What program are you using to output 7.1 audio?
Already formatted S/PDIF output as stereo PCM requires in config.txt:
no_hdmi_resample=1
hdmi_stream_channels=1

@tghewett
Copy link
Author

The 5.1/7.1 problem happens with hello_audio, the same source as provided with a previous issue but set for 8 channels instead of 2.

(Arch Linux now playing 5.1 encoded audio fine)

@popcornmix
Copy link
Collaborator

I've just connected an HDMI analyser.

./hello_audio.bin 1 8

reports 8 channels (FL/FR/LFE/FC/RL/RR/FLC/FRC) and no complaints.

Are you sure Arch has the latest hello_audio code? Latest GPU firmware (vcgencmd version)?
It was tweaked when adding proper multichannel PCM support to omxplayer/xbmc.

@tghewett
Copy link
Author

The latest hello_audio code, built in a snapshot of 26/11/13, does the same.

At present Arch >doesn't< have the latest *.elf and *.dat firmware, only that which comes in the raspberry.org download, and it works fine, 7.1 channels at the receiver. The problem only starts when updating these to the latest files.

Arch download vcgencmd version:

Jul 19 2013 23:48:50
Copyright (c) 2012 Broadcom
version 8b570d997388ca7989be17029f79180f98465e3c (clean) (release)

version for firmware downloaded on 26/11/13, which has the problem:

Nov 15 2013 14:17:01
Copyright (c) 2012 Broadcom
version 162026b1448f491e97e3b3b57cdca29be6a1d61a (tainted) (release)

I tried copying in the /opt/vc tree from the 26/11/13 firmware, no difference.

A further observation is that (albeit with only 5.1 channels at the receiver) 7.1 channel output has become reliable at 96kHz, previously it kept dropping out unless the RP was overclocked to 1GHz.

@tghewett
Copy link
Author

The version numbers seem to have been interpreted as links, here they are respectively:

"8b570d997388ca7989be17029f79180f98465e3c"
"162026b1448f491e97e3b3b57cdca29be6a1d61a"

@popcornmix
Copy link
Collaborator

I'd suggest you get the Nov 27th which did have an hdmi audio fix in (fix for "chirping").

Can you try on a different receiver?
Can you try with my hello_audio:
https://dl.dropboxusercontent.com/u/3669512/temp/hello_audio.bin

Can you try with "hdmi_stream_channels=1" removed?

Here is what hdmi analyser shows with "hello_audio.bin 1 8"
https://dl.dropboxusercontent.com/u/3669512/temp/photo.JPG

@tghewett
Copy link
Author

I'd suggest you get the Nov 27th which did have an hdmi audio fix in (fix for "chirping").

Have tried today's *.bin, *.dat and *.elf, no change.

Can you try on a different receiver?

Only one receiver unfortunately, Onkyo-based (Teac).

Can you try with my hello_audio

It produces an error: ./hello_audio.bin: error while loading shared libraries: libEGL.so.1: cannot open shared object file: No such file or directory

Tried creating a .conf in /etc/ld.so.conf.d containing "/opt/vc/lib", then "ldconfig, no change.

Can you try with "hdmi_stream_channels=1" removed?

No change. (I find this isn't needed for 5.1 encoded audio to work BTW, so it seems)

Here is what hdmi analyser shows with "hello_audio.bin 1 8"

That looks nice. Handy item to have around.

@popcornmix
Copy link
Collaborator

I'm not very familiar with Arch. I'd imagine it's safe to do

sudo SKIP_KERNEL=1 rpi-update

which would get the latest hello_audio.
Otherwise you could try a raspbian install and then rpi-update it to see if that works.

I'd like to find out if your problem is Arch installation related, or if the Onkyo doesn't like our 7.1 output.

@tghewett
Copy link
Author

tghewett commented Dec 3, 2013

Just tried a complete reinstall from the latest Raspbian image, followed by "sudo SKIP_KERNEL=1 rpi-update" and then ./hello_audio.bin 1 8", still the same 5.1 channels at the receiver.

@popcornmix
Copy link
Collaborator

I've got a Onkyo 606 here
./hello_audio.bin 1 8
and recever displays "MCH PCM 7.1"

@tghewett
Copy link
Author

tghewett commented Dec 3, 2013

The amp has been set to the "direct" listening mode for this input and audio type, I suspect your Onkyo has much the same set of options. Have tried setting it to "multich", still the same.

Just connected a Mac to it by HDMI and 8-ch PCM is received at the amp as 7.1 channels. Perhaps your Onkyo is more forgiving?

@tghewett
Copy link
Author

tghewett commented Apr 9, 2015

I am wondering if you can tell me which source files were modified to cause my amp to display 5.1ch instead of 7.1ch (as I still experience it, including with a Raspberry Pi 2 running kernel 3.18). I would like to be able to reverse it but keep a more recent kernel, the RP2 seems unable to build a 3.6 kernel as it came along later. I assume it is the kernel which was changed to cause this and not something in the other firmware files.

@popcornmix
Copy link
Collaborator

It's nothing to do with the kernel. It will be the start.elf firmware.
You suggest the problem occurred between "Jul 19 2013 23:48:50" and "Nov 15 2013 14:17:01".
If you could identify the exact firmware revision, I could explain exactly what changed.
I'd suggest you test with a Pi1 (older firmware won't support Pi2) and run:
sudo SKIP_KERNEL=1 rpi-update <hash>
where the hash comes from:
https://github.com/Hexxeh/rpi-firmware/commits/master

(click on a firmware version for the hash). If you identify the first version with the problem, I'll investigate.

@tghewett
Copy link
Author

tghewett commented Apr 9, 2015

Yes, it starts at hash code 5f4e0ba, Nov 6 2013, just after the bump to kernel 3.10.18. Hash code dc709fa just before it is fine.

@popcornmix
Copy link
Collaborator

Unfortunately that update was quite a big rewrite of the multichannel audio code.
You can narrow it down further using the next tree:
https://github.com/Hexxeh/rpi-firmware/commits/next

Can you identify when that tree broke? (It will be near the date you identified).

@tghewett
Copy link
Author

Yes, it starts with the commit on 22 Oct 2013, hash code 6f5c2e5. The commit before this on 18 Oct (a7a5b4b) is fine.

@popcornmix
Copy link
Collaborator

With latest firmware can you run:

vcgencmd hdmi_channel_map 0x13fac688
/opt/vc/src/hello_pi/hello_audio/hello_audio.bin 1 8

and report what the receiver reports?

@tghewett
Copy link
Author

Yes, the "vcgencmd hdmi_channel_map 0x13fac688" command gets 7.1ch PCM back, both for hello_audio and my own app. It also works for the RP2.

@tghewett
Copy link
Author

Additional: after running the vcgencmd command the amp now shows 7.1ch PCM for all output formats, e.g. stereo, not just 8ch output. (EDIT: this applies only to the RP2, the original RP is fine)

@popcornmix
Copy link
Collaborator

There is a little information of that gencmd here:
raspberrypi/firmware#299 (comment)

Simple solution it to run:

vcgencmd hdmi_channel_map 0

When you have finished with 7.1 audio and want to revert to default behaviour.

Audio infoframe byte 4 is described here. We used to use:
19 "RRC RLC RR RL FC LFE FR FL"
but now use
31 "FRC FLC RR RL FC LFE FR FL"
but you can override that with the hdmi_channel_map gencmd.

@tghewett
Copy link
Author

With the current default map, are these symptoms showing up a problem in the amp or is the map itself non-standard in some way? I ask because when connecting a Mac to the same amp by HDMI and setting audio output to 8 channels, the amp shows 7.1ch PCM, not 5.1ch as with the RP.

You may not have noticed my edit saying that the "stuck 7.1ch" issue only applies to the RP2, as this was added afterwards.

@popcornmix
Copy link
Collaborator

The map is standard. See the linked document there are two layouts for 7.1 audio.
I'm guessing your receiver has been set up to describe the speaker placement and it more closely matches the "19" layout. When given the "31" layout it presumably says I don't have FRC/FLC speakers and so drops (or downmixes) two channels.

I suspect if you played with the receiver settings you could claim the "31" layout and then you would see "7.1" with recent firmware and "5.1" with older firmware.

There might be an argument for changing the default for 7.1 to "19". We do use "19" for omxplayer and xbmc/kodi when in 7.1 mode as that seemed to match the channel layout kodi uses internally more closely (not exactly unfortunately - the final two channels are actually side left/side right which isn't an option though hdmi).

But if you are writing your own software that outputs multichanel audio then using the hdmi_channel_map gencmd is probably wise.

@tghewett
Copy link
Author

Thank you, that works, including on the RP2.

Does the call to vc_gencmd() fork a subprocess to run vcgencmd in a shell or does it remain entirely within the running process?

@popcornmix
Copy link
Collaborator

The gencmd is a global setting, so you will have issues with multiple processes using different settings.
However these values are written to the hdmi hardware, so supporting multiple concurrent settings is never going to work.

@tghewett
Copy link
Author

I'm interested really in the question of performance, i.e. does vc_gencmd() communicate directly with the hardware or just run vcgencmd as a sub process with the given string parameters.

@popcornmix
Copy link
Collaborator

vcgencmd is a RPC to the GPU (comparable to an openmax, mmal, or snd-bcm2835 operation). I'm assuming you are only calling it once per "playback" (e.g. song or video), so it's going to be negligible (e.g. sub millisecond).

@tghewett
Copy link
Author

Sub millisecond is no problem at all.

As an aside, is there any scope for adapting the ALSA driver to support all the HDMI formats as indicated by the equipment EDID information? Is this information accessible to the driver for it to do this when equipment is connected? I'm not sure what normally happens on Linux with HDMI interfaces, I think I saw a PC one which always provided all permissible HDMI sample rates up to 192k regardless of equipment support. Macs always provide the formats supported by the equipment (and no more), sometimes limited to 96k, but certainly using the EDID info. This is just something I'm interested in doing myself if it is at all feasible.

@pelwell
Copy link
Contributor

pelwell commented Apr 12, 2015

To be explicit, vcgencmd is a utility that calls vc_gencmd, not vice versa.

@popcornmix
Copy link
Collaborator

Unfortunately edid information is not always accurate.
We used to set defaults for passthrough support, number of channels and max sample rates from the EDID in xbmc, but have since let the user configure this manually as too many EDIDs were incorrect.

@tghewett
Copy link
Author

As I have a workable solution I'll close the issue. I have no particular view on whether the default value for the channel map is right or wrong, though remain a little concerned that the same amp (with the same configuration) behaves fine with a Mac as described previously.

Thanks for the information about the EDID information.

popcornmix pushed a commit that referenced this issue Jun 22, 2015
When the following filter is used it causes a warning to trigger:

 # cd /sys/kernel/debug/tracing
 # echo "((dev==1)blocks==2)" > events/ext4/ext4_truncate_exit/filter
-bash: echo: write error: Invalid argument
 # cat events/ext4/ext4_truncate_exit/filter
((dev==1)blocks==2)
^
parse_error: No error

 ------------[ cut here ]------------
 WARNING: CPU: 2 PID: 1223 at kernel/trace/trace_events_filter.c:1640 replace_preds+0x3c5/0x990()
 Modules linked in: bnep lockd grace bluetooth  ...
 CPU: 3 PID: 1223 Comm: bash Tainted: G        W       4.1.0-rc3-test+ #450
 Hardware name: Hewlett-Packard HP Compaq Pro 6300 SFF/339A, BIOS K01 v02.05 05/07/2012
  0000000000000668 ffff8800c106bc98 ffffffff816ed4f9 ffff88011ead0cf0
  0000000000000000 ffff8800c106bcd8 ffffffff8107fb07 ffffffff8136b46c
  ffff8800c7d81d48 ffff8800d4c2bc00 ffff8800d4d4f920 00000000ffffffea
 Call Trace:
  [<ffffffff816ed4f9>] dump_stack+0x4c/0x6e
  [<ffffffff8107fb07>] warn_slowpath_common+0x97/0xe0
  [<ffffffff8136b46c>] ? _kstrtoull+0x2c/0x80
  [<ffffffff8107fb6a>] warn_slowpath_null+0x1a/0x20
  [<ffffffff81159065>] replace_preds+0x3c5/0x990
  [<ffffffff811596b2>] create_filter+0x82/0xb0
  [<ffffffff81159944>] apply_event_filter+0xd4/0x180
  [<ffffffff81152bbf>] event_filter_write+0x8f/0x120
  [<ffffffff811db2a8>] __vfs_write+0x28/0xe0
  [<ffffffff811dda43>] ? __sb_start_write+0x53/0xf0
  [<ffffffff812e51e0>] ? security_file_permission+0x30/0xc0
  [<ffffffff811dc408>] vfs_write+0xb8/0x1b0
  [<ffffffff811dc72f>] SyS_write+0x4f/0xb0
  [<ffffffff816f5217>] system_call_fastpath+0x12/0x6a
 ---[ end trace e11028bd95818dcd ]---

Worse yet, reading the error message (the filter again) it says that
there was no error, when there clearly was. The issue is that the
code that checks the input does not check for balanced ops. That is,
having an op between a closed parenthesis and the next token.

This would only cause a warning, and fail out before doing any real
harm, but it should still not caues a warning, and the error reported
should work:

 # cd /sys/kernel/debug/tracing
 # echo "((dev==1)blocks==2)" > events/ext4/ext4_truncate_exit/filter
-bash: echo: write error: Invalid argument
 # cat events/ext4/ext4_truncate_exit/filter
((dev==1)blocks==2)
^
parse_error: Meaningless filter expression

And give no kernel warning.

Link: http://lkml.kernel.org/r/20150615175025.7e809215@gandalf.local.home

Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: stable@vger.kernel.org # 2.6.31+
Reported-by: Vince Weaver <vincent.weaver@maine.edu>
Tested-by: Vince Weaver <vincent.weaver@maine.edu>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
popcornmix pushed a commit that referenced this issue Jun 30, 2015
commit 2cf30dc upstream.

When the following filter is used it causes a warning to trigger:

 # cd /sys/kernel/debug/tracing
 # echo "((dev==1)blocks==2)" > events/ext4/ext4_truncate_exit/filter
-bash: echo: write error: Invalid argument
 # cat events/ext4/ext4_truncate_exit/filter
((dev==1)blocks==2)
^
parse_error: No error

 ------------[ cut here ]------------
 WARNING: CPU: 2 PID: 1223 at kernel/trace/trace_events_filter.c:1640 replace_preds+0x3c5/0x990()
 Modules linked in: bnep lockd grace bluetooth  ...
 CPU: 3 PID: 1223 Comm: bash Tainted: G        W       4.1.0-rc3-test+ #450
 Hardware name: Hewlett-Packard HP Compaq Pro 6300 SFF/339A, BIOS K01 v02.05 05/07/2012
  0000000000000668 ffff8800c106bc98 ffffffff816ed4f9 ffff88011ead0cf0
  0000000000000000 ffff8800c106bcd8 ffffffff8107fb07 ffffffff8136b46c
  ffff8800c7d81d48 ffff8800d4c2bc00 ffff8800d4d4f920 00000000ffffffea
 Call Trace:
  [<ffffffff816ed4f9>] dump_stack+0x4c/0x6e
  [<ffffffff8107fb07>] warn_slowpath_common+0x97/0xe0
  [<ffffffff8136b46c>] ? _kstrtoull+0x2c/0x80
  [<ffffffff8107fb6a>] warn_slowpath_null+0x1a/0x20
  [<ffffffff81159065>] replace_preds+0x3c5/0x990
  [<ffffffff811596b2>] create_filter+0x82/0xb0
  [<ffffffff81159944>] apply_event_filter+0xd4/0x180
  [<ffffffff81152bbf>] event_filter_write+0x8f/0x120
  [<ffffffff811db2a8>] __vfs_write+0x28/0xe0
  [<ffffffff811dda43>] ? __sb_start_write+0x53/0xf0
  [<ffffffff812e51e0>] ? security_file_permission+0x30/0xc0
  [<ffffffff811dc408>] vfs_write+0xb8/0x1b0
  [<ffffffff811dc72f>] SyS_write+0x4f/0xb0
  [<ffffffff816f5217>] system_call_fastpath+0x12/0x6a
 ---[ end trace e11028bd95818dcd ]---

Worse yet, reading the error message (the filter again) it says that
there was no error, when there clearly was. The issue is that the
code that checks the input does not check for balanced ops. That is,
having an op between a closed parenthesis and the next token.

This would only cause a warning, and fail out before doing any real
harm, but it should still not caues a warning, and the error reported
should work:

 # cd /sys/kernel/debug/tracing
 # echo "((dev==1)blocks==2)" > events/ext4/ext4_truncate_exit/filter
-bash: echo: write error: Invalid argument
 # cat events/ext4/ext4_truncate_exit/filter
((dev==1)blocks==2)
^
parse_error: Meaningless filter expression

And give no kernel warning.

Link: http://lkml.kernel.org/r/20150615175025.7e809215@gandalf.local.home

Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Reported-by: Vince Weaver <vincent.weaver@maine.edu>
Tested-by: Vince Weaver <vincent.weaver@maine.edu>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
popcornmix pushed a commit that referenced this issue Aug 4, 2015
Even though it is documented how to specifiy efi parameters, it is
possible to cause a kernel panic due to a dereference of a NULL pointer when
parsing such parameters if "efi" alone is given:

PANIC: early exception 0e rip 10:ffffffff812fb361 error 0 cr2 0
[ 0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 4.2.0-rc1+ #450
[ 0.000000]  ffffffff81fe20a9 ffffffff81e03d50 ffffffff8184bb0f 00000000000003f8
[ 0.000000]  0000000000000000 ffffffff81e03e08 ffffffff81f371a1 64656c62616e6520
[ 0.000000]  0000000000000069 000000000000005f 0000000000000000 0000000000000000
[ 0.000000] Call Trace:
[ 0.000000]  [<ffffffff8184bb0f>] dump_stack+0x45/0x57
[ 0.000000]  [<ffffffff81f371a1>] early_idt_handler_common+0x81/0xae
[ 0.000000]  [<ffffffff812fb361>] ? parse_option_str+0x11/0x90
[ 0.000000]  [<ffffffff81f4dd69>] arch_parse_efi_cmdline+0x15/0x42
[ 0.000000]  [<ffffffff81f376e1>] do_early_param+0x50/0x8a
[ 0.000000]  [<ffffffff8106b1b3>] parse_args+0x1e3/0x400
[ 0.000000]  [<ffffffff81f37a43>] parse_early_options+0x24/0x28
[ 0.000000]  [<ffffffff81f37691>] ? loglevel+0x31/0x31
[ 0.000000]  [<ffffffff81f37a78>] parse_early_param+0x31/0x3d
[ 0.000000]  [<ffffffff81f3ae98>] setup_arch+0x2de/0xc08
[ 0.000000]  [<ffffffff8109629a>] ? vprintk_default+0x1a/0x20
[ 0.000000]  [<ffffffff81f37b20>] start_kernel+0x90/0x423
[ 0.000000]  [<ffffffff81f37495>] x86_64_start_reservations+0x2a/0x2c
[ 0.000000]  [<ffffffff81f37582>] x86_64_start_kernel+0xeb/0xef
[ 0.000000] RIP 0xffffffff81ba2efc

This panic is not reproducible with "efi=" as this will result in a non-NULL
zero-length string.

Thus, verify that the pointer to the parameter string is not NULL. This is
consistent with other parameter-parsing functions which check for NULL pointers.

Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
Cc: Dave Young <dyoung@redhat.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
popcornmix pushed a commit that referenced this issue Aug 12, 2015
commit 9115c75 upstream.

Even though it is documented how to specifiy efi parameters, it is
possible to cause a kernel panic due to a dereference of a NULL pointer when
parsing such parameters if "efi" alone is given:

PANIC: early exception 0e rip 10:ffffffff812fb361 error 0 cr2 0
[ 0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 4.2.0-rc1+ #450
[ 0.000000]  ffffffff81fe20a9 ffffffff81e03d50 ffffffff8184bb0f 00000000000003f8
[ 0.000000]  0000000000000000 ffffffff81e03e08 ffffffff81f371a1 64656c62616e6520
[ 0.000000]  0000000000000069 000000000000005f 0000000000000000 0000000000000000
[ 0.000000] Call Trace:
[ 0.000000]  [<ffffffff8184bb0f>] dump_stack+0x45/0x57
[ 0.000000]  [<ffffffff81f371a1>] early_idt_handler_common+0x81/0xae
[ 0.000000]  [<ffffffff812fb361>] ? parse_option_str+0x11/0x90
[ 0.000000]  [<ffffffff81f4dd69>] arch_parse_efi_cmdline+0x15/0x42
[ 0.000000]  [<ffffffff81f376e1>] do_early_param+0x50/0x8a
[ 0.000000]  [<ffffffff8106b1b3>] parse_args+0x1e3/0x400
[ 0.000000]  [<ffffffff81f37a43>] parse_early_options+0x24/0x28
[ 0.000000]  [<ffffffff81f37691>] ? loglevel+0x31/0x31
[ 0.000000]  [<ffffffff81f37a78>] parse_early_param+0x31/0x3d
[ 0.000000]  [<ffffffff81f3ae98>] setup_arch+0x2de/0xc08
[ 0.000000]  [<ffffffff8109629a>] ? vprintk_default+0x1a/0x20
[ 0.000000]  [<ffffffff81f37b20>] start_kernel+0x90/0x423
[ 0.000000]  [<ffffffff81f37495>] x86_64_start_reservations+0x2a/0x2c
[ 0.000000]  [<ffffffff81f37582>] x86_64_start_kernel+0xeb/0xef
[ 0.000000] RIP 0xffffffff81ba2efc

This panic is not reproducible with "efi=" as this will result in a non-NULL
zero-length string.

Thus, verify that the pointer to the parameter string is not NULL. This is
consistent with other parameter-parsing functions which check for NULL pointers.

Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
Cc: Dave Young <dyoung@redhat.com>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
@lbschenkel
Copy link

Sorry to bump this old issue, but is there any way to tell the firmware to use "19" for 7.1 without explicitly setting hdmi_channel_map? The problem with setting it explicitly is that it signals all output to be 7.1, even stereo, preventing a receiver from doing ProLogic II decoding, for example.

@popcornmix
Copy link
Collaborator

It might help if you explained what you were doing and how audio was being output.

@lbschenkel
Copy link

lbschenkel commented Feb 27, 2018

Sure. (I contacted you privately via e-mail yesterday about this, by the way.)

My intent is to send arbitrary audio files via HDMI to an amp/receiver using OMX (let's say via omxplayer). The reason for using OMX and not ALSA is because not all my audio is stereo: some is high-res, some multi-channel, etc. When I don't set any hdmi_channel_map, then the channels from the audio itself get transmitted via the stream and recognized as such by the receiver: 2.0->2.0, 5.1->5.1, etc. The problem is that in the default firmware behaviour, a 7.1 source is annotated with the "31" layout and my receiver does not like that: it displays the source as being 5.1 and just drops the other channels. I was hoping I could tell the firmware to annotate a 7.1 source with "17" instead, which does get interpreted correctly by my receiver as 7.1.

I can work around it by setting hdmi_channel_map to 0x13fac688, as previously discussed, however this has an unfortunate side effect: now all streams are annotated as being 7.1, and all the missing channels are padded with silence. The receiver now thinks this is a multi-channel source, even if the audio is actually stereo, and I cannot tell the receiver to upmix it or apply Dolby ProLogic II for example.

Now, if I could tell the firmware that 7.1 sources map to layout "17" instead of "31" (which was the old default behaviour, by the way) but without forcing any specific hdmi_channel_map, this would allow 2.0 audio to be recognized as by the receiver as 2.0, 5.1 as 5.1 and 7.1 as 7.1.

Does this clarify things?

@popcornmix
Copy link
Collaborator

Now, if I could tell the firmware that 7.1 sources map to layout "17" instead of "31" (which was the old default behaviour, by the way)

Can you clarify this? I don't believe anything has changed in this area in firmware for years - when do you believe this changed?

@lbschenkel
Copy link

lbschenkel commented Feb 27, 2018

I believe the default at some time in the past used to be "17" based on your message in this very issue:
#450 (comment)

P.S.: Sorry, I meant "19" when I wrote "17".

@popcornmix
Copy link
Collaborator

Okay, so years ago.
You say 17, but I suspect you mean 19 (0x13) which changed to 31 (0x1f) way back.
17 is 5.1 audio. 19 is 7.1 audio.

@lbschenkel
Copy link

Yes, I added a P.S. to my previous message. I meant "19" but I mistakenly wrote "17".

@popcornmix
Copy link
Collaborator

Have you tried kodi which does use hdmi_channel_map itself? I wonder if that behaves any differently.

@lbschenkel
Copy link

lbschenkel commented Feb 27, 2018

Not yet (and I will), but I have read the source code and I think I have a pretty good grasp of what it does. It looks at the channels of the input source and calculates what the hdmi_channel_map itself should look like, and sets that via vc_gencmd. Note that it uses 19, and not 31, for 7.1 channels:
https://github.com/xbmc/xbmc/blob/master/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp#L170
https://github.com/xbmc/xbmc/blob/master/xbmc/cores/omxplayer/OMXAudio.cpp#L534

So no change from what I'm doing manually, it just does that automatically on playback (and when the source attributes change). I was hoping to find a solution that does not involve setting hdmi_channel_map due to my workflow. I don't plan to run Kodi, my end goal is to run MPD.

I am trying to make MPD output the audio via OMX (for the reasons I mentioned before). MPD does not have a OMX plugin at the moment (I'm considering contributing one at the end of this ordeal), but for now I have configured an ALSA device that pipes a wave file to a script that I wrote. The script uses GStreamer and omxhdmiaudiosink to play the input (my attempts to use omxplayer were not successful, it crashes when reading from stdin). I even have implemented logic to set hdmi_channel_map before playback based on the number of channels, just like Kodi does. However this does not work very well, because the ALSA device is not closed/reopened between files, so the script is not reinvoked and it can't set the a new map if the file being played now has a different number of channels.

I feel that trying to set the channel map at runtime introduces added complexity and fragility for something that is actually quite simple.

Ideally there could be a setting in config.txt that could allow selecting if 0x13 or 0x1F should be used by the firmware for indicating 7.1 channels when hdmi_channel_map is left at its default value of 0.

As an alternative, I could patch the firmware binary and replace 0x1F for 0x13 but I don't know where to look. Maybe you could help me out?

popcornmix pushed a commit that referenced this issue Feb 20, 2020
commit db6a501 upstream.

rcu_read_lock is needed to protect access to psock inside sock_map_unref
when tearing down the map. However, we can't afford to sleep in lock_sock
while in RCU read-side critical section. Grab the RCU lock only after we
have locked the socket.

This fixes RCU warnings triggerable on a VM with 1 vCPU when free'ing a
sockmap/sockhash that contains at least one socket:

| =============================
| WARNING: suspicious RCU usage
| 5.5.0-04005-g8fc91b972b73 #450 Not tainted
| -----------------------------
| include/linux/rcupdate.h:272 Illegal context switch in RCU read-side critical section!
|
| other info that might help us debug this:
|
|
| rcu_scheduler_active = 2, debug_locks = 1
| 4 locks held by kworker/0:1/62:
|  #0: ffff88813b019748 ((wq_completion)events){+.+.}, at: process_one_work+0x1d7/0x5e0
|  #1: ffffc900000abe50 ((work_completion)(&map->work)){+.+.}, at: process_one_work+0x1d7/0x5e0
|  #2: ffffffff82065d20 (rcu_read_lock){....}, at: sock_map_free+0x5/0x170
|  #3: ffff8881368c5df8 (&stab->lock){+...}, at: sock_map_free+0x64/0x170
|
| stack backtrace:
| CPU: 0 PID: 62 Comm: kworker/0:1 Not tainted 5.5.0-04005-g8fc91b972b73 #450
| Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS ?-20190727_073836-buildvm-ppc64le-16.ppc.fedoraproject.org-3.fc31 04/01/2014
| Workqueue: events bpf_map_free_deferred
| Call Trace:
|  dump_stack+0x71/0xa0
|  ___might_sleep+0x105/0x190
|  lock_sock_nested+0x28/0x90
|  sock_map_free+0x95/0x170
|  bpf_map_free_deferred+0x58/0x80
|  process_one_work+0x260/0x5e0
|  worker_thread+0x4d/0x3e0
|  kthread+0x108/0x140
|  ? process_one_work+0x5e0/0x5e0
|  ? kthread_park+0x90/0x90
|  ret_from_fork+0x3a/0x50

| =============================
| WARNING: suspicious RCU usage
| 5.5.0-04005-g8fc91b972b73-dirty #452 Not tainted
| -----------------------------
| include/linux/rcupdate.h:272 Illegal context switch in RCU read-side critical section!
|
| other info that might help us debug this:
|
|
| rcu_scheduler_active = 2, debug_locks = 1
| 4 locks held by kworker/0:1/62:
|  #0: ffff88813b019748 ((wq_completion)events){+.+.}, at: process_one_work+0x1d7/0x5e0
|  #1: ffffc900000abe50 ((work_completion)(&map->work)){+.+.}, at: process_one_work+0x1d7/0x5e0
|  #2: ffffffff82065d20 (rcu_read_lock){....}, at: sock_hash_free+0x5/0x1d0
|  #3: ffff888139966e00 (&htab->buckets[i].lock){+...}, at: sock_hash_free+0x92/0x1d0
|
| stack backtrace:
| CPU: 0 PID: 62 Comm: kworker/0:1 Not tainted 5.5.0-04005-g8fc91b972b73-dirty #452
| Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS ?-20190727_073836-buildvm-ppc64le-16.ppc.fedoraproject.org-3.fc31 04/01/2014
| Workqueue: events bpf_map_free_deferred
| Call Trace:
|  dump_stack+0x71/0xa0
|  ___might_sleep+0x105/0x190
|  lock_sock_nested+0x28/0x90
|  sock_hash_free+0xec/0x1d0
|  bpf_map_free_deferred+0x58/0x80
|  process_one_work+0x260/0x5e0
|  worker_thread+0x4d/0x3e0
|  kthread+0x108/0x140
|  ? process_one_work+0x5e0/0x5e0
|  ? kthread_park+0x90/0x90
|  ret_from_fork+0x3a/0x50

Fixes: 7e81a35 ("bpf: Sockmap, ensure sock lock held during tear down")
Signed-off-by: Jakub Sitnicki <jakub@cloudflare.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: John Fastabend <john.fastabend@gmail.com>
Link: https://lore.kernel.org/bpf/20200206111652.694507-2-jakub@cloudflare.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
popcornmix pushed a commit that referenced this issue Feb 20, 2020
commit db6a501 upstream.

rcu_read_lock is needed to protect access to psock inside sock_map_unref
when tearing down the map. However, we can't afford to sleep in lock_sock
while in RCU read-side critical section. Grab the RCU lock only after we
have locked the socket.

This fixes RCU warnings triggerable on a VM with 1 vCPU when free'ing a
sockmap/sockhash that contains at least one socket:

| =============================
| WARNING: suspicious RCU usage
| 5.5.0-04005-g8fc91b972b73 #450 Not tainted
| -----------------------------
| include/linux/rcupdate.h:272 Illegal context switch in RCU read-side critical section!
|
| other info that might help us debug this:
|
|
| rcu_scheduler_active = 2, debug_locks = 1
| 4 locks held by kworker/0:1/62:
|  #0: ffff88813b019748 ((wq_completion)events){+.+.}, at: process_one_work+0x1d7/0x5e0
|  #1: ffffc900000abe50 ((work_completion)(&map->work)){+.+.}, at: process_one_work+0x1d7/0x5e0
|  #2: ffffffff82065d20 (rcu_read_lock){....}, at: sock_map_free+0x5/0x170
|  #3: ffff8881368c5df8 (&stab->lock){+...}, at: sock_map_free+0x64/0x170
|
| stack backtrace:
| CPU: 0 PID: 62 Comm: kworker/0:1 Not tainted 5.5.0-04005-g8fc91b972b73 #450
| Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS ?-20190727_073836-buildvm-ppc64le-16.ppc.fedoraproject.org-3.fc31 04/01/2014
| Workqueue: events bpf_map_free_deferred
| Call Trace:
|  dump_stack+0x71/0xa0
|  ___might_sleep+0x105/0x190
|  lock_sock_nested+0x28/0x90
|  sock_map_free+0x95/0x170
|  bpf_map_free_deferred+0x58/0x80
|  process_one_work+0x260/0x5e0
|  worker_thread+0x4d/0x3e0
|  kthread+0x108/0x140
|  ? process_one_work+0x5e0/0x5e0
|  ? kthread_park+0x90/0x90
|  ret_from_fork+0x3a/0x50

| =============================
| WARNING: suspicious RCU usage
| 5.5.0-04005-g8fc91b972b73-dirty #452 Not tainted
| -----------------------------
| include/linux/rcupdate.h:272 Illegal context switch in RCU read-side critical section!
|
| other info that might help us debug this:
|
|
| rcu_scheduler_active = 2, debug_locks = 1
| 4 locks held by kworker/0:1/62:
|  #0: ffff88813b019748 ((wq_completion)events){+.+.}, at: process_one_work+0x1d7/0x5e0
|  #1: ffffc900000abe50 ((work_completion)(&map->work)){+.+.}, at: process_one_work+0x1d7/0x5e0
|  #2: ffffffff82065d20 (rcu_read_lock){....}, at: sock_hash_free+0x5/0x1d0
|  #3: ffff888139966e00 (&htab->buckets[i].lock){+...}, at: sock_hash_free+0x92/0x1d0
|
| stack backtrace:
| CPU: 0 PID: 62 Comm: kworker/0:1 Not tainted 5.5.0-04005-g8fc91b972b73-dirty #452
| Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS ?-20190727_073836-buildvm-ppc64le-16.ppc.fedoraproject.org-3.fc31 04/01/2014
| Workqueue: events bpf_map_free_deferred
| Call Trace:
|  dump_stack+0x71/0xa0
|  ___might_sleep+0x105/0x190
|  lock_sock_nested+0x28/0x90
|  sock_hash_free+0xec/0x1d0
|  bpf_map_free_deferred+0x58/0x80
|  process_one_work+0x260/0x5e0
|  worker_thread+0x4d/0x3e0
|  kthread+0x108/0x140
|  ? process_one_work+0x5e0/0x5e0
|  ? kthread_park+0x90/0x90
|  ret_from_fork+0x3a/0x50

Fixes: 7e81a35 ("bpf: Sockmap, ensure sock lock held during tear down")
Signed-off-by: Jakub Sitnicki <jakub@cloudflare.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: John Fastabend <john.fastabend@gmail.com>
Link: https://lore.kernel.org/bpf/20200206111652.694507-2-jakub@cloudflare.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants