vdr-plugin-softhddevice-drm-gles 1.6.2
Readme - softhddevice-drm-gles

A software and GPU emulated HD output device for VDR
(https://github.com/rellla/vdr-plugin-softhddevice-drm-gles)

Features

  • Hardware accelerated video decoding (depending on hardware and FFmpeg support)
    • MPEG2
    • H.264
    • HEVC (10bit)
  • Hardware accelerated video deinterlacing (depending on hardware and FFmpeg support)
  • Software fallback for decoding and deinterlacing
  • Optional GPU accelerated OSD composing (OpenGL/ES)
  • Audio decoding with alsa (PCM)
  • Audio passthrough support (AC3, E-AC3, DTS)
  • UHD support
  • HDR display support
  • Picture-in-picture support (depending on hardware)
  • Integrated minimalistic media player
  • Grabbing support
  • Detach/Attach support (release display, audio and GPU resources, but keep VDR running)
  • Many adjustable (expert) settings via setup menu

Supported Hardware

In general, any device that provides a DRM/KMS output and is supported by FFmpeg should work. This is true for most of the devices, that are supported by LibreELEC.

Current development happens on a Raspberry PI 4 and a Radxa Rock 4B Plus (RK3399).

576i MPEG2 720p H.264 1080i H.264 1080p HEVC
Allwinner Not tested Not tested Not tested Not tested
Amlogic Not tested Not tested Not tested Not tested
Raspberry Pi 2 SW SW SW
Raspberry Pi 3 Not tested Not tested Not tested Not tested
Raspberry Pi 4 SW
Raspberry Pi 5 SW SW SW
Rockchip RK3399

✅= Hardware decoding
SW = Device does not support hardware decoding. Software decoding is used.
❌= Device supports hardware decoding, but it is not implemented in this plugin.

Why do we need another softhddevice version?

This was basically a fork of https://github.com/zillevdr/vdr-plugin-softhddevice-drm.git but has received major rewrites across most of the code.

The target of this version are embedded devices, see supported hardware.

The difference in function to the original fork is, that it adds some additional features like resized video, hardware accelerated OSD rendering, support for Rpi4/5 and Amlogic devices, detach/attach functionality and many more things. Read the commit history for detailed info.

The main difference in design is, that the code base was moved to a class orientated, mostly C++-based code. Moving between the different states (Detach, Buffering, Play, Stop, ...) is implemented with a state machine. AV-Sync and buffering have been completely rewritten.

As a principle, this softhddevice version is only dealing with mainline versions and standards, which means you can (and have to) use mainline (or to be mainlined) kernel, FFmpeg and mesa version. This code does not work with vendor provided software or even closed source binaries.

www.LibreELEC.tv is good source to look for what is possible with mainlined media related software. In the LibreELEC project you can find at least patches for all the software, even if some piece of code isn't able to be mainlined or simply not already there. Because LibreELEC is a distribution to run kodi on, you'll find everything you need.

How does it internally work?

  • FFmpeg for video decoding and deinterlacing
  • Alsa for audio output
  • Kernel mode setting with DRM (zero-copy)
  • OSD rendering with OpenGL/ES

Video decoding is done with FFmpeg. If your hardware has some hardware decoder and/or deinterlacer which is supported by FFmpeg, the video is hardware decoded (depending on the codec), otherwise software decoding/ deinterlacing is done. For software deinterlacing FFmpeg's bwdif (Bob Weaver Deinterlacing Filter) is used. This is the highest quality software deinterlacer available in FFmpeg. The OSD is either composed with OpenGL/ES or with CPU (see below). Both, video and OSD are rendered directly on seperate drm planes with kms. When the video is hardware decoded, we don't need much CPU, because everything is done with a zero-copy approach. That's the same for OpenGL/ES OSD. Audio output is handled by Alsa.

See the developer page for helpful descriptions, graphs and diagrams of VDR and softhddevice internals to see how things work together.

A doxygen documentation is available here and is updated on every commit automatically.

Known Bugs/ TODO

Requirements

  • No running X!
  • VDR (version >=2.6.6)

    Video Disk Recorder - turns a pc into a powerful set top box for DVB (http://www.tvdr.de/).

  • FFmpeg

    Depending on upstreaming efforts a patched FFmpeg version may be needed to take advantage of hardware accelerated decoding and deinterlacing (see below).

  • Kernel

    Depending on upstreaming efforts a patched kernel may be needed (WIP LE version)

    Have a look at https://github.com/LibreELEC/LibreELEC.tv/tree/master/packages/linux and choose the linux source and patches which matches your platform. Some of the needed patches have not yet been upstreamed, so you probably need to build the kernel on your own. LibreELEC supports Rockchip, Allwinner, Raspberry PI and (kind of) Amlogic. Have a look at https://github.com/LibreELEC/LibreELEC.tv/tree/master/projects to find platform specific patches.

  • alsa-lib

    Advanced Linux Sound Architecture Library http://www.alsa-project.org

  • For OpenGL/ES support:
    • gles2 (Mesa)
    • egl (Mesa)
    • gbm (Mesa)
    • freetype2
    • glm - OpenGL Mathematics (GLM)

Installation

git clone https://github.com/rellla/vdr-plugin-softhddevice-drm-gles.git
cd vdr-plugin-softhddevice-drm-gles
make
make install

Commandline Arguments

Use vdr -h to see the command line arguments supported by the plugin.

-a audio_device (e.g. hw:0,1)
-p device for pass-through (e.g. hw:0,1)
-c audio mixer channel name (e.g. PCM)
-d display resolution (e.g. 1920x1080@50)
-D  start plugin in detached state
-w workarounds
    disable-ogl-osd (to disable HW accelerated OSD)
    disable-pip (to force disabling the pip feature)

Setup: Environment Variables

ALSA_DEVICE=default
    alsa PCM device name
ALSA_PASSTHROUGH_DEVICE=
    alsa pass-though (AC-3,E-AC-3,DTS,...) device name
ALSA_MIXER=default
    alsa control device name
ALSA_MIXER_CHANNEL=PCM
    alsa control channel name

Setup: /etc/vdr/setup.conf

softhddevice-drm-gles.HideMainMenuEntry = 0
    0 = show softhddevice main menu entry, 1 = hide entry

softhddevice-drm-gles.VideoEnableHdr = 0
    0 = disable HDR, 1 = enable HDR

softhddevice-drm-gles.MaxSizeGPUImageCache = 128
    how many GPU memory should be used for image caching

softhddevice-drm-gles.AdditionalBufferLengthMs = 0
    0 = default (min 450ms fixed)
    1 - 1000 = length of additional buffering duration in ms

softhddevice-drm-gles.AudioDelay = 0
    +n or -n ms
    delay audio or delay video

softhddevice-drm-gles.AudioPassthrough = 0
    0 = none, 4 = AC-3, 8 = EAC-3, 16 = DTS

    For AC-3/EAC-3/DTS the passthrough device is used and the audio
    stream is passed undecoded to the output device.
    Add the values above: e.g. 12 = AC-3 + EAC-3
    negating the value disables passthrough but remembers the setting
    (note: TrueHD... isn't supported yet)

softhddevice-drm-gles.AudioDownmix = 0
    0 = none, 1 = downmix
    Use FFmpeg downmix of AC-3/EAC-3 audio to stereo.

softhddevice-drm-gles.AudioSoftvol = 0
    0 = off, use hardware volume control
    1 = on, use software volume control

softhddevice-drm-gles.AudioNormalize = 0
    0 = off, 1 = enable audio normalize

softhddevice-drm-gles.AudioMaxNormalize = 0
    maximal volume factor/1000 of the normalize filter

softhddevice-drm-gles.AudioCompression = 0
    0 = off, 1 = enable audio compression

softhddevice-drm-gles.AudioMaxCompression = 0
    maximal volume factor/1000 of the compression filter

softhddevice-drm-gles.AudioStereoDescent = 0
    reduce volume level (/1000) for stereo sources

softhddevice-drm-gles.AudioAutoAES = 0
    0 = disabled
    1 = auto append AES string to the audio device

softhddevice-drm-gles.AudioEq = 0
    0 = Equalizer disabled
    1 = Equalizer enabled

softhddevice-drm-gles.AudioEqBand[01b..18b] = 0
    -15 to 1 = equalizer band gain (see Setup menu)

softhddevice-drm-gles.LogLevel = 0
    0 = default (no debug logs)
    value is the sum of the following levels
        1     Standard debug logs
        2     AV-Sync debug logs
        4     Sound/Audio debug logs
        8     Osd debug logs
        16    DRM debug logs
        32    Codec (audio+video) debug logs
        64    Stillpicture debug logs
        128   Trickspeed debug logs
        256   Mediaplayer debug logs
        512   OpenGL/ES debug logs
        1024  OpenGL/ES Osd flush time measurement
        2048  OpenGL/ES Osd single command time measurement
        4096  Packet tracking logs (decoder + display)
        8192  Grabbing debug logs
        16384 FFmpeg debug logs

softhddevice-drm-gles.DisableDeint = 0
    0 = deinterlacer active if available
    1 = deinterlacer is disabled

softhddevice-drm-gles.DecoderNeedsIFrame = 0
    0 = H.264 HW decoder is started as soon as any frame arrives
    1 = H.264 HW decoder needs to wait for an I-Frame to start

softhddevice-drm-gles.ParseH264Dimensions = 0
    0 = don't parse width and height before decoder start
    1 = H.264 HW decoder wants decoded width and height before starting

softhddevice-drm-gles.DecoderFallbackToSw = 0
    0 = always use hardware decoder if available
    1 = fallback to software decoder if hardware decoder
        fails after num packets (see below)

softhddevice-drm-gles.DecoderFallbackToSwNumPkts = 22
    maximum number of packets sent to the hardware decoder
    until the software fallback jumps in

softhddevice-drm-gles.ParseH264StreamStart = 0
    0 = disable parsing, 1-20 = parse H.264 stream up to the given number of I-Frames

softhddevice-drm-gles.DropInvalidH264PFrames = 0
    1 = drop H.264 P-Frames with an invalid backwards reference

softhddevice-drm-gles.PipScalePercent = 25
    10 - 100 = scale factor for pip (%)

softhddevice-drm-gles.PipLeftPercent = 100
    0 - 100 = video left (%)
    0 = left aligned, 100 = right aligned

softhddevice-drm-gles.PipTopPercent = 0
    0 - 100 = video top (%)
    0 = top aligned, 100 = bottom aligned

softhddevice-drm-gles.PipAltScalePercent = 25
    10 - 100 = scale factor for alternative pip (%)

softhddevice-drm-gles.PipAltLeftPercent = 0
    0 - 100 = video left for alternative pip (%)
    0 = left aligned, 100 = right aligned

softhddevice-drm-gles.PipAltTopPercent = 0
    0 - 100 = video top for alternative pip (%)
    0 = top aligned, 100 = bottom aligned

SVDRP Commands

PLAY Url    Play the media from the given url.
    Tested extension: *.mp3, *.mp4, *.m3u, *.m3u8

    Url can be a
        - local file: /path_to_file/media_file.mp4
        - playlist: playlist_name.m3u
        - link: http://www.media-server/path_to_file/media_file.mp4

DETA         Detach the plugin.
    An "ATTA" is needed in order to exit a detached state and to continue playback.

ATTA         Attach the plugin again.

STAT         Get attached/detached status.
    910 -> ATTACHED
    911 -> DETACHED

PION         Enable picture-in-picture.

PIOF         Disable picture-in-picture.

PITO         Toggle picture-in-picture on/off.

PIPU         Switch one channel up in pip window.

PIPD         Switch one channel down in pip window.

PIPC         Swap pip with main stream.

PIPS         Switch main stream to pip stream and close the pip window.

PIPP         Swap pip position between normal and alternative.

Keymacros

See keymacros.conf how to setup the macros.

Currently supported:

@softhddevice-drm-gles Blue 1      Toggle pip
@softhddevice-drm-gles Blue 2      Pip channel +
@softhddevice-drm-gles Blue 3      Pip channel -
@softhddevice-drm-gles Blue 4      Swap pip and live stream
@softhddevice-drm-gles Blue 5      Swap pip position
@softhddevice-drm-gles Blue 6      Switch main stream to pip channel and close pip
@softhddevice-drm-gles Red 1       Detach device
@softhddevice-drm-gles Red 2       Attach device

OpenGL/ES

OpenGL/ES support is based on the work of Stefan Braun (https://github.com/louisbraun/softhddevice-openglosd)

This enables GPU accelerated OSD rendering. OpenGL/ES support is enabled, if gles2, egl and gbm are found on the system To disable OpenGL/ES support (if autodetected), simply build with

GLES=0 make

In this case, VDR is using CPU based OSD rendering.

FFmpeg

The plugin should work with any recent upstream FFmpeg version but may lack hardware decoder acceleration. If you want to drive the plugin with a hardware acclerated decoder, you may need to build FFmpeg on your own.

LibreELEC is a good source to find out the current status of what is already upstreamed and supported. Have a look at https://github.com/LibreELEC/LibreELEC.tv/tree/master/packages/multimedia/ffmpeg and choose the FFmpeg source and patches which match your platform. Most of them have not yet been upstreamed, so you probably need to build FFmpeg on your own. LibreELEC supports Rockchip, Allwinner, Raspberry PI and (kind of) Amlogic. Have a look at https://github.com/LibreELEC/LibreELEC.tv/tree/master/projects to find platform specific patches.

The following instructions may help you to setup FFmpeg (may be outdated):

  • Raspberry Pi, Amlogic:
    • rpi-ffmpeg is the very recent version for RPI4/RPI5 and Amlogic (For Raspberry Pi LibreELEC normally patches the upstream FFmpeg version to get the version from jc-kynesim)
    • check out a recent branch (note: the master branch is not the one you want to have)
    • most likely this branch has everything you need and you don't need any further patches (in doubt, check how it is handled in LibreELEC)
    • build FFmpeg as usual with the "configure - make - make install" logic
    • For Raspberry Pi building with the following configure options should enable hardware acceleration:
        --disable-static --enable-shared --enable-pic --enable-bsfs --enable-filters --enable-v4l2_m2m --enable-libdrm --enable-libudev --enable-v4l2-request --enable-sand --enable-hwaccels --enable-neon --disable-vdpau --disable-vaapi --disable-mmal
      
    • For Amlogic building with the following configure options should enable hardware acceleration:
        --disable-static --enable-shared --enable-pic --enable-bsfs --enable-filters --enable-v4l2_m2m --enable-libdrm --enable-hwaccels --enable-neon --disable-vdpau --disable-vaapi --disable-libudev --disable-v4l2-request
      
  • Rockchip, Allwinner:
    • use mainline FFmpeg with version mentioned in LibreELEC package file
    • patch the mainline version with the patchsets which where mentioned for your platform in the package.mk
    • build FFmpeg as usual with the "configure - make - make install" logic
    • building with the following configure options should enable hardware acceleration:
        --disable-static --enable-shared --enable-pic --enable-bsfs --enable-filters --enable-v4l2_m2m --enable-libdrm --enable-libudev --enable-v4l2-request --enable-hwaccels --enable-neon --disable-vdpau --disable-vaapi
      

Display Resolution

Setting the display resolution is possible with the -d switch (see below). If no specific resolution is stated, the plugin searches for resolutions with a refresh rate of 50Hz. If one is found, the highest possbile is used. If no resolution at 50Hz is found, the plugin searches for resolutions at 60Hz and uses the highest possbile. If neither 50Hz or 60Hz can be found, the plugin uses the highest possbile resolution with a refresh rate which is first discovered.

When the plugin is unable to detect any resolution (e.g. if there is no TV/Monitor attached, the plugin will not start. You can workaorund this by submitting a fixed EDID to your config (see Documentation, way differs from architecture)

When using the -d switch, make sure you use the syntax of "widthXheight@refreshrate", so for example: "-d 3840x2160@50" for 4K at 50Hz.

Picture-in-Picture (PiP)

The plugins supports the picture-in-picture feature. This allows you to move your current stream into a small overlay window and continue watching TV as usual. You can change channels on the main and in the pip window. It's also possible to swap both windows. Audio is only available in the main stream. The pip window is always opened with the current channel and does not remember the last pip channel. You can define your individual pip window size and position and an alternative window. It's possible to swap between the two positions. PiP can be controlled via SVDRP, menu or via remote control keys, which are defined as hotkeys in the keymacros.conf. If your VDR has enough devices assigned, you can watch channels on different transponders. On one-tuner systems, pip should only show the channels like if you are doing a concurrent recording.

Note: Be aware, that the pip feature works in general but is still a little bit experimental.

Mediaplayer

The plugin has an integrated mediaplayer reduced to the most important player functions. Playback can be started with svdrp or via the main menu. If the mediaplayer is called via the main menu, you can either choose a previously created playlist, create a new playlist or simply play a single file.

In replay mode, you can control playback with the following keys:

OK:          Show/ Hide replay menu
Play/Up:     Play if paused
Pause/Down:  Pause if playing, play again if paused
Left:        Jump 5s backwards
Right:       Jump 5s forward
Green:       Jump 60s backwards
Yellow:      Jump 60s forward
Blue/Back:   Stop replay and end player
Next:        Continue with next file in playlist if available

Hints for Raspberry Pi 4/5

It is highly recommended to use the kms driver with Raspberry Pi 4/5 and not the outdated fkms driver. Be sure you have the following dtoverlay activated in your /boot/config.txt:

dtoverlay=vc4-kms-v3d,cma-512

vc4-kms-v3d enables the new kms driver, cma-512 sets a custom cma size of 512MB. This is the recommended size. Only change it when you exactly know what you are doing.

While using the outdated fkms driver still works with this plugin, there might be some problems when viewing interlaced material and displaying the OSD.

To enable 4k resolution at 50Hz or 60Hz you have to set "hdmi_enable_4kp60=1" in /boot/config.txt. Otherwise the Raspberry Pi is only capable of displaying 4K at 30Hz and the plugin will use 1080p at 50Hz according to the algorithm described above.

In case of permission problems under Raspberry Pi OS 5 with VDR installed via apt, you might need to add the vdr user to the audio and render groups:

usermod -a -G audio vdr
usermod -a -G render vdr

Copyright

Copyright 2011 - 2013 by Johns. All Rights Reserved.
Copyright 2018 - 2021 by zillevdr. All Rights Reserved.
Copyright 2020 - 2026 by rellla. All Rights Reserved.

License

AGPL version 3.0 or later