zillevdr / vdr-plugin-softhddevice-drm

drm fork
7 stars 6 forks source link

SIGSEGV in VideoRenderFrame() with MMAL on DVB-T2 #11

Open dr-m opened 2 years ago

dr-m commented 2 years ago

I was curious to see if this could be a viable work-around of reufer/rpihddevice#5 for my Raspberry Pi 2.

Good news first: the code as of cbccef7cc37c3122c75f58000a50227fe468ca45 compiled out of the box after the following:

sudo apt install libasound2-dev libavfilter-dev

and applying the patch:

diff --git a/Makefile b/Makefile
index 93391b5..f51e21b 100644
--- a/Makefile
+++ b/Makefile
@@ -12,7 +12,7 @@ PLUGIN = softhddevice-drm
 ### Configuration (edit this for your needs)

    # enable this for MMAL (RaspberryPi 2)
-MMAL ?= 0
+MMAL ?= 1

 CONFIG := #-DDEBUG                 # enable debug output+functions
 #CONFIG += -DAV_SYNC_DEBUG     # enable debug messages AV_SYNC

On startup, I got an on-screen-display layer for the current channel, followed by a SIGSEGV before any video or audio played:

vdr --no-kbd --lirc -Psofthddevice-drm -v /var/lib/vdr/video

Here is the output followed by a stack trace of the crashing thread:

mmal: mmal_vc_port_info_set: failed to set port info (2:0): EINVAL
mmal: mmal_vc_port_set_format: mmal_vc_port_info_set failed 0x6131e720 (EINVAL)
Failed to commit deinterlace intput format (status=3 EINVAL)
mmal: mmal_vc_port_enable: failed to enable port vc.ril.image_fx:in:0(OPQV): EINVAL
mmal: mmal_port_enable: failed to enable port vc.ril.image_fx:in:0(OPQV)(0x6131e720) (EINVAL)
Failed to enable deinterlace input port vc.ril.image_fx:in:0(OPQV) (3, EINVAL)
mmal: mmal_vc_port_info_set: failed to set port info (3:0): EINVAL
mmal: mmal_vc_port_set_format: mmal_vc_port_info_set failed 0x6131eae0 (EINVAL)
Failed to commit deinterlace output format (status=3 EINVAL)
mmal: mmal_vc_port_enable: failed to enable port vc.ril.image_fx:out:0(OPQV): EINVAL
mmal: mmal_port_enable: failed to enable port vc.ril.image_fx:out:0(OPQV)(0x6131eae0) (EINVAL)
Failed to enable deinterlacer output port vc.ril.image_fx:out:0(OPQV) (3, EINVAL)
Failed send buffer to deinterlacer output port (3, EINVAL)
Failed send buffer to deinterlacer output port (3, EINVAL)
Failed send buffer to deinterlacer output port (3, EINVAL)

Thread 15 "softhddev video" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x612ff400 (LWP 2379)]
VideoRenderFrame (render=0x2ea2e0, video_ctx=<optimized out>, 
    frame=<optimized out>) at video_mmal.c:889
889     memcpy(qbuffer->data, buffer->data, buffer->length);
(gdb) bt
#0  VideoRenderFrame (render=0x2ea2e0, video_ctx=<optimized out>, 
    frame=<optimized out>) at video_mmal.c:889
#1  0x76454fe4 in CodecVideoReceiveFrame (decoder=0x309328, 
    no_deint=no_deint@entry=0) at codec.c:376
#2  0x7644e9d0 in VideoDecodeInput (stream=0x7646a858 <MyVideoStream>)
    at softhddev.c:1117
#3  0x76450498 in DisplayHandlerThread (arg=0x2ea2e0) at video_mmal.c:723
#4  0x76f4f494 in start_thread (arg=0x612ff400) at pthread_create.c:486
#5  0x76bb0dd8 in ?? () at ../sysdeps/unix/sysv/linux/arm/clone.S:73
   from /lib/arm-linux-gnueabihf/libc.so.6
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

This is not a permission issue, because I got the same crash when running the software as the super user. I repeated this crash on two kernel versions:

Linux version 5.10.63-v7+ (dom@buildbot) (arm-linux-gnueabihf-gcc-8 (Ubuntu/Linaro 8.4.0-3ubuntu1) 8.4.0, GNU ld (GNU Binutils for Ubuntu) 2.34) #1496 SMP Wed Dec 1 15:58:11 GMT 2021

and the newest that is currently available in Raspberry OS Lite (Legacy), raspberrypi/rpi-firmware@921f5efeaed8a27980e5a6cfa2d2dee43410d60d:

Linux version 5.15.78-v7+ (dom@buildbot) (arm-linux-gnueabihf-gcc-8 (Ubuntu/Linaro 8.4.0-3ubuntu1) 8.4.0, GNU ld (GNU Binutils for Ubuntu) 2.34) #1599 SMP Fri Nov 11 12:23:22 GMT 2022

The current channel was in a DVB-T2 bouguet. After I edited CurrentChannel in setup.conf to point to a DVB-T channel, it started to work, with subtitles and everything, using between 10% and 40% of one CPU core. There was nothing output to the standard output or error streams until I attempted to switch to a DVB-T channel:

AlsaPlayer: ring buffer empty
mmal: mmal_vc_port_info_set: failed to set port info (2:0): EINVAL
mmal: mmal_vc_port_set_format: mmal_vc_port_info_set failed 0x221b490 (EINVAL)
Failed to commit deinterlace intput format (status=3 EINVAL)
mmal: mmal_vc_port_enable: failed to enable port vc.ril.image_fx:in:0(OPQV): EINVAL
mmal: mmal_port_enable: failed to enable port vc.ril.image_fx:in:0(OPQV)(0x221b490) (EINVAL)
Failed to enable deinterlace input port vc.ril.image_fx:in:0(OPQV) (3, EINVAL)
mmal: mmal_vc_port_info_set: failed to set port info (3:0): EINVAL
mmal: mmal_vc_port_set_format: mmal_vc_port_info_set failed 0x221b7a0 (EINVAL)
Failed to commit deinterlace output format (status=3 EINVAL)
mmal: mmal_vc_port_enable: failed to enable port vc.ril.image_fx:out:0(OPQV): EINVAL
mmal: mmal_port_enable: failed to enable port vc.ril.image_fx:out:0(OPQV)(0x221b7a0) (EINVAL)
Failed to enable deinterlacer output port vc.ril.image_fx:out:0(OPQV) (3, EINVAL)

These messages were followed by SIGSEGV with the above stack trace. If I understood correctly, DVB-T2 here uses the H.264 encoding. It is supported natively by rpihddevice.

zillevdr commented 2 years ago

Hi Marko, what I see is that the deinterlacer doesn't accept the video format that came from the decoder. It's curiously. Do you know the format from the picture? Can I get a small piece ( 1 minute ) video? Regards zille. Edit: The video format from the decoder should supported by the deinterlacer. libavfilter isn't used there, only MMAL.

dr-m commented 2 years ago

Every Finnish free-to-view DVB-T2 channel or recording that I tried provokes the crash.

To hopefully avoid any copyright infringement, I made a 25-megabyte recording (over 30 seconds) from Estradi HD, which appears to exist so that anyone can broadcast (for a fee). Most of the time (including this time), it streams looped recordings of Finnish sceneries, with no sound or text. An attempt to play back the recording triggers this as well. The messages that precede the SIGSEGV are the same, only with different pointer addresses for the mmal_port_enable messages.

I will try to figure out a way how to get the recording to you.

dr-m commented 2 years ago

I educated myself a little further. There are two interfaces to the Videocore IV GPU: MMAL and OMX. Both are obsolescent according to raspberrypi/firmware#1168. The rpihddevice plugin uses OMX, while one of the supported interfaces of this plugin is MMAL. The future appears to be V4L2 M2M, but it is unclear to me if that interface is supported on the Raspberry Pi 2.

When I enabled the OpenGL driver in raspi-config, I got a /dev/dri/card0 that the non-MMAL build of softhddevice-drm would look for. But, unfortunately it used CPU-based decoding. Even for DVB-T, I got very jerky playback. After I switched to a DVB-T2 channel, all I got was one still frame.

I will try to debug this further, because my goal is to be able to use the Raspberry Pi 2 that I already have. This is also a nice challenge to learn a little more about video decoding.

zillevdr commented 2 years ago

The recording are h264 1024i coded. Here it play fine. The easiest way to get a working setup is to use an older version of firmware. You can also make a bug report on raspberrypi/firmware. V4L2 M2M isn't a solution. There are no deinterlacer.

dr-m commented 2 years ago

@zillevdr Thank you, I will try to test with older firmware. I understood that it works with raspberrypi/firmware@b324aea801f669b6ab18441f970e74a5a7346684 (Linux 5.4.79) on your system. It crashed on my system with raspberrypi/firmware@4877a7d918be6fab22ce5d345feefd9c43200a90 (Linux 5.10.63) and raspberrypi/firmware@74c4307951701f93bd94b4fd37e6adc44910d6e0 (Linux 5.10.103).

I think that the most interesting versions to test would be raspberrypi/firmware@70f1581eec2c036b7e9309f1af41c651fb125447 (Linux 5.4.83) and its successor in https://downloads.raspberrypi.org/raspios_oldstable_lite_armhf/release_notes.txt, raspberrypi/firmware@fcf8d2f7639ad8d0330db9c8db9b71bd33eaaa28 (Linux 5.10.17).

dr-m commented 2 years ago

With raspberrypi/firmware@70f1581eec2c036b7e9309f1af41c651fb125447 (Linux 5.4.83) the DVB-T2 playback does not crash, and on some DVB-T2 channels I get a smooth playback after some initial delay of a few seconds. On other DVB-T2 channels, I get intermittent video or audio. My remote control unit did not work with this kernel, so I had to issue HITK commands via SVDRP; I apologize for some accidentally opened tickets when some blindly typed keyboard input went to the web browser window.

With raspberrypi/firmware@fcf8d2f7639ad8d0330db9c8db9b71bd33eaaa28 or raspberrypi/firmware@518ee7c871aaa9aaa88116953d57e73787ee6e43 (both claim to be Linux 5.10.17) the playback does not crash, and I get a better DVB-T2 playback on all channels that I tried.

The next firmware upgrade listed in https://downloads.raspberrypi.org/raspios_oldstable_lite_armhf/release_notes.txt is raspberrypi/firmware@4877a7d918be6fab22ce5d345feefd9c43200a90 (Linux 5.10.63). I had already tested it, but I upgraded to it again to double check, and I instantly got the SIGSEGV.

So, there seems to be a regression somewhere in the proprietary MMAL subsystem between Linux kernel version 5.10.17 and 5.10.63.