LibreMoon - Just enough OS for moonlight(qt) - rk3399


  • I was exploring options for game streaming on a RK3399 SBC and LibreELEC was a clear starting point — the V4L2 Request + DRM PRIME hwaccel pipeline is already working and well-tested there. The options I found were script.luna (originally from CoreELEC, using moonlight-embedded, potentially adaptable) and a solution that ran moonlight-qt inside Docker on LibreELEC. The CoreELEC path was decent but moonlight-embedded lacked the DRM PRIME backend that moonlight-qt has — moonlight-qt integrates FFmpeg decode and direct DRM output in a way that moonlight-embedded doesn't. (I was able to add it, but ran into KMS DRM master conflicts with Kodi in the way that can probably be sorted out.) Wanting to squeeze every bit of performance out of decade-old hardware, and not have kodi+docker overhead, I set out to splice LibreELEC and moonlight-qt together: strip Kodi, build Qt6 for the target, and have the box boot straight into moonlight-qt with full rkvdec hardware decode and zero overhead.

    It worked. 1080p60 HEVC @ 20 Mbps, 2.7ms average decode time, 0% frame drops. Working audio and controller. No stutter.

    Due to the nature of SoCs this should be portable across all RK3399 boards with only the U-Boot target needing to change.

    All credit goes to the LibreELEC project and the moonlight-qt project:

    GitHub - LibreELEC/LibreELEC.tv: Just enough OS for KODI
    Just enough OS for KODI. Contribute to LibreELEC/LibreELEC.tv development by creating an account on GitHub.
    github.com
    GitHub - moonlight-stream/moonlight-qt: GameStream client for PCs (Windows, Mac, Linux, and Steam Link)
    GameStream client for PCs (Windows, Mac, Linux, and Steam Link) - moonlight-stream/moonlight-qt
    github.com

    Most of the heavy lifting was done with Claude Code, working through ~25 build failures, mostly around Qt6 host vs. target cross-compilation. I merely gave it the goal and guided it through the problem space with documentation to kept it from going down rabbit holes, and tested the builds.

    I've uploaded the build for my board (RockPro64) along with the build tools and a readme if anyone wants to try it on their own rockpro64 or build it for another rk3399 board The Rock Pi 4 is going for around $60 now, not a bad price for a dedicated game streaming box. There's also an interesting future direction here: Qt6 and moonlight-qt could potentially be integrated into mainline LibreELEC, or the hwaccel backend from this project could be used with the Kodi interface instead of Qt, which is essentially what script.luna did with moonlight-embedded on CoreELEC. Could be a meaningful contribution to the project.

    I have helped moonlight-qt project in the past by helping supply examples of getting HDR going kmsdrm with atomic commits, and will submit what I did with adding the ffmpeg v4l2 drmprime pathway as a backend option to moonlight-embedded before pivoting to moonlight-qt, so moonlight embedded may have that down the road instad of having to bring QT along as an interface.

    Build comes in at 142MB

    Readme
    Fork

  • LE13 now has support for flatpak add-ons with the Chrome add-on experience where Kodi is stopped, the flatpak app runs, and when you exit the app Kodi is restarted. We already added the SteamLink flatpak. We'd prefer to see a Moonlight flatpak add-on (assuming it works) as this would have less maintenance and faster compile than dealing with Qt6 from source.

    You could also investigate the LEIoT distro which coexists in the buildsystem as the base for a more minimal image. LEIoT drops all the background plumbing for Kodi (which you're probably not using) with a base image around 85MB in size (including Docker). You could drop docker and add moonlight-qt to ADDITIONAL_PACKAGES+= and see what happens or leave it and package the Qt6 things you need into a container (or be lazy and pull someone else's) .. there's lots of options.

    NB: I'd suggest creating your own $DEVICE in the buildsystem else future changes we push will trample on yours in a rebase. I plan to drop current Rockchip devices after LE13 and reconfigure the buildsystem to have two new ones; a single 'arm' image (RK3288) and single 'aarch64' image (RK3328 thru RK3588) using a common kernel/patchset.