-
Major bug and Armbians Updated Framework
waiting on new kernel build before spouting off
- "[PATCH v6 00/15] Support 10-bit YUV422 and 8/10-bit YUV420 color format on DW HDMI QP".
-
"[PATCH v6 00/15] Support 10-bit YUV422 and 8/10-bit YUV420 color format on DW HDMI QP".
@igorpaunovic The HDMI finding, in full. What the series does. Cristian Ciocaltea's 15 patches teach the RK3588's HDMI 2.1 block (the Synopsys DW HDMI QP) to output YUV422 at 10 bits and YUV420 at 8 or 10 bits, instead of RGB only. That matters for 4K at 120 Hz over HDMI 2.0-class links and for HDR sinks that want YUV. Patches 1 to 10 are VOP2 fixes and clock plumbing, 13 and 14 add the formats, 15 is the device tree. Heiko took all of it into drm-misc-next on 2026-11-06, so it is headed for the next merge window. Where the pixels come from. The VOP2 is the display controller that feeds the HDMI block. Its video port has a dither stage, and one bit in the port's control register, called pre-dither-down, converts the 10-bit pipeline to 8 bits with Allegro dithering before the data leaves the VOP. The TRM entry for that bit reads "10bit to 8bit (allegro)". Pre-dither exists so that an 8-bit output does not get a hard truncation. The HDMI block then takes what the VOP hands it. If the VOP already dithered to 8 bits, a 10-bit link carries 8-bit content padded to 10. The bug. Mainline's dither setup has two parts. The switch on the bus format enables pre-dither for the 8-bit YUV formats, which is right. But after the switch it also enables pre-dither for any output mode other than the plain RGB mode, unconditionally. That line predates the series. Before the series it was harmless, because every non-RGB mode the driver could produce was 8-bit anyway. The series adds two 10-bit YUV bus formats and routes them through the same function, and that line fires for them too. So selecting the new "10-bit YUV422" or "10-bit YUV420" modes gets you 8-bit dithered content on a 10-bit link. Why we are confident without hardware. Rockchip's own driver, the one in our vendor kernel, handles exactly this: its version of the same function has an explicit case for the 10-bit formats (YUYV10, YUV10, UYYVYY10 and RGB101010) that turns pre-dither off, and a second rule that turns it off for all YUV output on ports without the newer frame-rate-conversion block. Mainline has neither. The register semantics come from the TRM, the vendor behaviour from Rockchip, and the mainline code is what we read in drm-misc-next this morning. What we cannot do here is prove it on a panel: that needs a 10-bit sink and either a capture card or a gradient test pattern on a display that shows banding, and a mainline kernel on the test board, which is not our daily lane. Why nobody caught it. The series was reviewed for apply-cleanliness, clocks and the HDMI side. The reviewers tested that the modes negotiate and display, which they will. 8-bit dithered 10-bit looks fine to the eye on most content. A bot reviewer flagged other things in v5 but not this. The dither line is not in the series' diff, so a diff-only review never sees it. What a report would say. A short mail to the v6 thread on linux-rockchip and dri-devel, to Cristian and Heiko: the line, the TRM bit description, the vendor driver's handling, and the suggested fix, which is to skip pre-dither when the output bit depth is above 8 or when the bus format is one of the 10-bit ones. It is a one-liner to fix and a follow-up patch rather than a revert. I would post it as a finding rather than a patch, stated plainly as a code-and-TRM reading with no hardware proof, since Cristian has the hardware to confirm it and write the fix. If you want to run with it yourself, go ahead; I am short on time right now (new job, working nights). For Your Consideration defcom5-rockchip
-
rockchip-vaapi Ver. 4.0.0 Number Nine "Pepper Pro" Video Driver Released With Custom MPP (RK3588)
Two releases are out for RK3588 / RK3588S boards running a Rockchip vendor (BSP) kernel. Not for mainline kernels. rockchip-vaapi 4.0.0 "Pepper Pro" is the VA-API driver that lets Firefox, mpv, ffmpeg and VA-API builds of Chromium decode H.264, HEVC, VP9 and AV1 (8- and 10-bit) on the board's video engine, through Rockchip's MPP library. This release fixes H.264 and HEVC streams the hardware used to get wrong: custom quantisation tables (common in Blu-ray and broadcast encodes), interlaced H.264, some multi-slice and High 10 H.264, and HEVC streams with less common header layouts. Standard conformance streams decoded bit-exact on the hardware: H.264 74 → 111 of 135, H.264 High profiles 6 → 48 of 48, HEVC 17 → 141 of 147. Interlaced H.264 now comes out weaved; deinterlacing is up to the player (mpv --deinterlace=yes, in software). VP9 and AV1 are unchanged, except that an AV1 stream that grows mid-stream no longer crashes ffmpeg. MPP +pd35 is an unofficial build of Rockchip's MPP with three fixes for RK3588: AV1 film grain applied by the hardware (new), VP9 on both decoder cores without the errors that started after about 65,000 frames (18 minutes at 60 fps), and 4K60 AV1 in Firefox keeping up (each picture decoded once, not twice). Where it works SoC: RK3588 and RK3588S. RK3576 untested (it has AV1 hardware, but this driver's AV1 path has only run on RK3588). RK356x untested, no AV1. Kernel: vendor kernel with MPP; check with: ls /dev/mpp_service. Tested on Armbian's vendor branch (6.1.189-vendor-rk35xx); earlier releases also on ubuntu-rockchip 6.1.0-1027. Armbian current/edge (mainline) have no MPP, so the driver does not apply there. Boards: Orange Pi 5B (all numbers above). Orange Pi 5 Plus confirmed by a forum tester on earlier releases. Other RK3588/RK3588S boards on a vendor kernel should work; reports welcome. Distro: the driver package is built and tested on Ubuntu 26.04 and should install on 24.04 (not tested yet). It needs glibc 2.38 or newer, so not Ubuntu 22.04 or Debian 12; Debian 13 untested. It also needs librockchip-mpp1 and librga2, which Ubuntu, Debian and Armbian's repository do not carry. On 24.04 they come from the rockchip-multimedia PPA (ppa:jjriek/rockchip-multimedia; Ubuntu-Rockchip images already have it, and adding it also replaces ffmpeg, GStreamer and mpv with its builds). Check with: apt-cache policy librockchip-mpp1 librga2 GPU: works with Arm's Mali driver, panfork Mesa, or Panthor. 4K needs more CMA memory: on Armbian add extraargs=cma=512M to /boot/armbianEnv.txt and reboot (check: grep CmaTotal /proc/meminfo). Install Driver: https://github.com/defcom5-rockchip/rockchip-vaapi/releases/tag/v4.0.0 then: sudo apt install ./rockchip-vaapi_4.0.0-1_arm64.deb (add --allow-change-held-packages if your image holds it). The package sets the VA-API environment for every user; log out and back in. MPP: https://github.com/defcom5-rockchip/mpp/releases/tag/pd35 (files for 24.04 and 26.04, and how to go back). Optional if you already have MPP from the PPA, but the PPA build loses VP9 frames in long sessions, and 4K60 AV1 in Firefox needs this one. Firefox needs three about:config settings, four for HEVC: https://github.com/defcom5-rockchip/rockchip-vaapi/blob/main/INSTALL.md . Chromium builds that decode through libv4l-rkmpp (some vendor images) do not use this driver; chrome://gpu shows which path you have. Problems or reports from other boards: https://github.com/defcom5-rockchip/rockchip-vaapi/issues with board, uname -a, distro, apt-cache policy librockchip-mpp1, and the codec and resolution (full list in KNOWN-ISSUES.md, "Reporting"). The code was written and debugged with an AI assistant (Claude) under my direction, credited per commit. Every number above comes from runs on real hardware, kept in the repository's evidence/2026-10-25-* folders.
-
Widevine DRM in Chromium and Firefox on arm64 Linux, using the module from Google Chrome
As a side note when I switched back to Firefox from Chrome The picture quality seemed much better.. No Test done just an observation. added Info: The test clips are ready on .214 in ~/Videos/levels/: levels-8-av1.mp4 and levels-10-av1.mp4, with copies on the NAS. Each is 30 seconds of 1080p AV1 with two rows of patches: Top row: a below-black patch (8), black (16), then dark steps from 17 to 40. Bottom row: light steps from 200 up, white (235), and above-white patches. I decoded both clips and checked every patch: all 26 hold their exact values at both bit depths. That check caught an ffmpeg quirk on the first try that had shifted and clipped the levels; the fix was to tag the colour information at the input, not the output. Tomorrow's test: play each clip in Chrome forced onto software decoding (the same drawing path Netflix uses) and in Firefox, and count how many dark steps you can tell apart. FFmpeg 9: I read the official changelog for 9.0 through 9.0.2. There's nothing that would change black levels or our picture problem. The colour items are AMD's AMF converter getting HDR, Vulkan support in the scaler, and a set of scaler crash and overflow fixes. More to the point, Netflix doesn't go through FFmpeg in either browser: Google's DRM module decodes the video itself. So FFmpeg 9 can't be the fix here. It does matter for mpv and Firefox's non-DRM playback, so it's worth a separate look when Ubuntu packages it.
-
Widevine DRM in Chromium and Firefox on arm64 Linux, using the module from Google Chrome
Netflix plays in all three browsers on the Orange Pi 5B: Chrome 156, Chromium 156 (xtradeb) and Firefox 158 (Mozilla Team PPA, the deb; I haven't tried the snap, which is confined and probably can't read /opt/google), all using Chrome's Widevine 4.10.3112.0. Tested on a Plaid Pi 6.0 test build rather than the release image I mentioned. Two corrections to my first post: step 3 (Firefox) and step 4 (the check). Step 3: the folder layout I gave is wrong. With it, Firefox's Widevine plugin crashes as soon as a site starts using it: Netflix shows F7701-1003, Firefox says the Widevine plugin crashed, and the crash core points at Firefox's "Plugin file does not exist" check. Firefox takes the module's file name from the parent of the MOZ_GMP_PATH folder: a parent named gmp-widevinecdm makes it load libwidevinecdm.so (in my tests, a parent named gmp-foo made it look for libfoo.so). The inner folder's name doesn't matter. mkdir -p ~/.local/share/widevine-from-chrome/gmp-widevinecdm/system-installed cd ~/.local/share/widevine-from-chrome/gmp-widevinecdm/system-installed ln -sfn /opt/google/chrome/WidevineCdm/_platform_specific/linux_arm64/libwidevinecdm.so . ln -sfn /opt/google/chrome/WidevineCdm/manifest.json . MOZ_GMP_PATH=$HOME/.local/share/widevine-from-chrome/gmp-widevinecdm/system-installed firefox Quit Firefox completely before the last line (Ctrl+Q, not just closing the window): a running Firefox only opens a new window and never sees the variable. The about:config prefs from step 3 stay as they were. If you made the variable permanent (a launcher script or ~/.config/environment.d/), change the path there too; environment.d needs a log out and back in. The two old links directly in ~/.local/share/widevine-from-chrome can be deleted. Step 4: in Firefox, the console check I posted only shows the module's manifest was found. It answered ok with the layout from my first post, while the module itself couldn't load. This version loads the module and asks it to create a license request; the snippet sends nothing to any server. Open the developer console (F12) on any https page (the Bitmovin demo page will do) and paste it. In a fresh profile the console first asks you to type "allow pasting". (async()=>{const id=[0xed,0xef,0x8b,0xa9,0x79,0xd6,0x4a,0xce,0xa3,0xc8,0x27,0xdc,0xd5,0x1d,0x21,0xed],d=[0x12,0x10,...Array(16).fill(1)];const pssh=new Uint8Array([0,0,0,32+d.length,0x70,0x73,0x73,0x68,0,0,0,0,...id,0,0,0,d.length,...d]);try{const a=await navigator.requestMediaKeySystemAccess("com.widevine.alpha",[{initDataTypes:["cenc"],videoCapabilities:[{contentType:'video/mp4; codecs="avc1.42E01E"',robustness:"SW_SECURE_DECODE"}]}]);const s=(await a.createMediaKeys()).createSession();s.onmessage=e=>console.log("Widevine works: license request of "+e.message.byteLength+" bytes");await s.generateRequest("cenc",pssh)}catch(e){console.log("Widevine failed: "+e.name+" "+e.message)}})() Working: "Widevine works: license request of 1701 bytes" (the size may differ). Chromium without the hint file: "Widevine failed: NotSupportedError Unsupported keySystem or supportedConfigurations." Firefox with my first post's layout: "Widevine failed: NS_ERROR_FAILURE". Some other wrong layouts print nothing at all, so no answer after twenty seconds is also a failure. Checked in fresh headless profiles of all three browsers, and the corrected Firefox commands above were run as written. What playback costs: decoding is all software. The board's hardware video decoders stayed idle (no interrupts in ten-second samples during playback in each browser). The DRM process is the biggest single load in Chromium and Chrome; in Firefox the main process uses as much. ps showed the DRM process at about 46% of one core in Firefox, 118% in Chromium and 152% in Chrome; I didn't check which codec Netflix sent each one. The heaviest is about 1.5 cores, under a fifth of the RK3588's eight (four of which are the small A55s). I didn't check the resolution either; at Widevine L3, services generally cap Linux browsers at SD or 720p. A correction to my first post's last paragraph: I said the image's first-boot check verifies both pointers. It checks that the pieces are in place; it doesn't load the module, which is how the broken Firefox layout got past it. Plaid Pi 6.0 (still in test) builds the corrected layout in its Firefox launcher, and its first-boot check now confirms the launcher uses it. An LLM assistant (Claude) found the cause from Firefox's crash core, wrote and ran the headless console tests and the gmp-foo test, took the CPU and interrupt measurements, and drafted this post. I did the Netflix playback tests on the board.
-
Widevine DRM in Chromium and Firefox on arm64 Linux, using the module from Google Chrome
Short version: Google's arm64 Linux Chrome package ships Widevine, the DRM module streaming services use. Chromium and Firefox on arm64 don't ship it (Chromium is built with Widevine support but without the module; Mozilla ships no Widevine for aarch64 Linux at all), but both can use Chrome's copy if you tell them where it is. Nothing gets copied, so Google's licence on the module isn't an issue: it stays Google's install, and the pointer is your own configuration. Tested on an Orange Pi 5B (Armbian's rk-6.1 vendor kernel, Ubuntu 26.04 userspace) with Chrome 156, Chromium 156 (the xtradeb build) and Firefox 158 (Mozilla Team PPA). None of this is board-specific; it should work on any arm64 desktop where the arm64 Chrome .deb installs. 1. Install Google Chrome https://dl.google.com/linux/direct/google-chrome-stable_current_arm64.deb and sudo apt install ./google-chrome-stable_current_arm64.deb The module lands in /opt/google/chrome/WidevineCdm (libwidevinecdm.so under _platform_specific/linux_arm64, plus manifest.json). Chrome plays protected streams straight away. 2. Chromium Chromium looks for a one-line "hint" file in its profile, the same file Chrome writes in its own profile. Create it with the version from Chrome's manifest: mkdir -p ~/.config/chromium/WidevineCdm V=$(sed -n 's/.*"version"[[:space:]]*:[[:space:]]*"\([0-9.]*\)".*/\1/p' /opt/google/chrome/WidevineCdm/manifest.json) printf '{"LastBundledVersion":"%s","Path":"/opt/google/chrome/WidevineCdm"}' "$V" > ~/.config/chromium/WidevineCdm/latest-component-updated-widevine-cdm Restart Chromium. Two things that do NOT work, so you don't waste time on them: a copy of the module in ~/.local/lib/libwidevinecdm.so, and a copy of Chrome's WidevineCdm folder into the Chromium profile. Only the hint file worked here. 3. Firefox Firefox loads Widevine from folders named in the MOZ_GMP_PATH environment variable. Make a folder with two symlinks to Chrome's files, then start Firefox with the variable set: mkdir -p ~/.local/share/widevine-from-chrome ln -sfn /opt/google/chrome/WidevineCdm/_platform_specific/linux_arm64/libwidevinecdm.so ~/.local/share/widevine-from-chrome/ ln -sfn /opt/google/chrome/WidevineCdm/manifest.json ~/.local/share/widevine-from-chrome/ MOZ_GMP_PATH=$HOME/.local/share/widevine-from-chrome firefox In about:config set media.gmp-widevinecdm.visible = true, media.gmp-widevinecdm.enabled = true and media.eme.enabled = true (the first is false by default on platforms Mozilla doesn't ship Widevine for, which hides the whole thing). media.gmp-widevinecdm.autoupdate = false keeps the plugin updater from looking for a copy Mozilla doesn't have. To make it permanent, put the variable in a launcher script or in ~/.config/environment.d/. 4. Checking it Before trying a service, this page tells you whether the module loaded: open https://bitmovin.com/demos/drm (Widevine test streams) or ask the browser directly from the console: navigator.requestMediaKeySystemAccess("com.widevine.alpha",[{initDataTypes:["cenc"],videoCapabilities:[{contentType:'video/mp4; codecs="avc1.42E01E"'}]}]).then(a=>console.log("ok",a.getConfiguration().videoCapabilities[0].robustness)).catch(e=>console.log("no",e.name)) Here all three browsers answer ok with robustness SW_SECURE_DECODE, which means the module loaded. That level is Widevine L3, so services serve SD or 720p on Linux; that is Widevine's rule, not the hardware's. I'll add playback results with real services once I've run them on the release image. EVIDENCE I've automated both pointers in Plaid Pi, my GNOME 50 image for the Orange Pi 5 and 5B (Ubuntu 26.04 packages, built with the Armbian framework): a /etc/chromium.d snippet writes Chromium's hint at every start, the Firefox launcher keeps the symlink folder and sets MOZ_GMP_PATH, and the image's first-boot check verifies both. The current release is 5.5; the version with these pieces is 6.0, in test now. Recipe: https://github.com/defcom5-rockchip/pi-desktop-recipe (the two files land there with the 6.0 release). Releases: https://github.com/defcom5-rockchip/pi-desktop/releases. An LLM assistant (Claude) did the probing with me; I ran it on the hardware.
-
Firefox for Rockchip
More Testing On The new Patch.... Firefox was glitching but now the numbers have changed. Confirmed the AV1 decode is now working off a healthy ~35MB read-ahead burst instead of the previous bare 9 Mbit/s trickle, giving it the buffer cushion it was missing. I'm setting a watcher for the glitch pattern (decoder stalls/resumes) and will report back with a summary in about 10 minutes.
-
Firefox for Rockchip
I dropped a 4k 60fps VP9 on Firefox last night and ran into glitches over the NAS... Claude said Firefox handles Network differently than MPV... They are Fashioning it to work... updates to come.
-
Linux-Rockchip-MPP - VP9 Fix
Tests are 4k@60FPS
-
Linux-Rockchip-MPP - VP9 Fix
Update and numbers.... They had me change the methodology of my patch and the numbers look great. On these clips the default task count gives +44 % / +29 % (10-bit / 8-bit) over the one-task reference; with hal_task_count = 2 on the earlier clips it was +26 % / +25 % — different clips, so only indicative. "Thanks for confirming on your side. When this is merged, it will go through our internal Gerrit review, and your commit will keep your authorship and Signed-off-by."
-
Firefox for Rockchip
update to Firefox... Submitted 2nd patch with 4 changes. New email added a person... Claude > I've logged it; there's nothing to do. "pasik" is almost certainly Pasi Kärkkäinen, going by the address pasik@iki.fi. He's a long-time Linux and Xen community member who follows Linux hardware-video bugs in Firefox. I don't know of him being a Mozilla maintainer, so I'd read this as an interested watcher rather than a reviewer. He CC'd himself on the 15th, the same day as Robert Mader, which was the day the triager said the approach was right — so the bug got noticed then. Current state of the bug: Stránský still holds the needinfo ("will look at it"), with Mader and Pasi watching. I'll suggest a nudge only if it's still quiet in about a week.
-
Firefox for Rockchip
For your consideration: <Claude> On Jellyfin's code: they don't deal with the issue at all. That's why they hit it. jellyfin-ffmpeg builds its own private copy of MPP, pinned in builder/scripts.d/50-rkmpp.sh: SCRIPT_REPO="https://github.com/nyanmisaka/rk-mirrors.git" SCRIPT_COMMIT="a9380ef333102ac318628f83b5f7a460d377749e" SCRIPT_BRANCH="jellyfin-mpp-next" That branch carries commit 960b7198a392 (nyanmisaka, 2025-12-24), which undoes Rockchip's guard: Revert "fix[hal_vp9d]: not support fast mode for rk3588" This reverts commit 0d6cc57d44e79f8521ac2fc117571edb3224564b. --- a/mpp/hal/rkdec/vp9d/hal_vp9d_api.c +++ b/mpp/hal/rkdec/vp9d/hal_vp9d_api.c @@ -72,7 +72,7 @@ MPP_RET hal_vp9d_init(void *ctx, MppHalCfg *cfg) p->api = &hal_vp9d_vdpu34x; cfg->support_fast_mode = 1; if (mpp_get_soc_type() == ROCKCHIP_SOC_RK3588) - cfg->support_fast_mode = 0; + cfg->cfg->status.hal_task_count = 2; How that compares with ours: That's the same line as the second half of our fix: dual-core VP9 with 2 tasks. They switched it on without the counter wrap, the first half of our fix. So their transcodes still fail after about 65,536 frames, which is the 30% frame loss we measured on the real film. Rockchip had the opposite half-answer: switch dual-core off and lose the speed. Our patch does both, so you get the speed without the storm.
-
Firefox for Rockchip
We did it, Found the code that Rockchip disabled for multi core decode and fixed it proper for VP9 8 and 10 bit. I'm running soak test and then PR for MPP. 28% faster with no shit storms. some initial numbers. 127 dropped of 40k Claude> 127 of 40,000 is 0.3%, which is excellent for 4K60 in a browser. The decoder log agrees: 10.5 minutes in, 40,701 jobs split evenly across both cores (20,351 and 20,350), 0 resets, and no AV1 mixed in. That's about 62% of the way to the old wall, which comes at about 15:07 on the board's clock, roughly 6–7 minutes from now. The timer runs on to about 15:15. I'm too low on tokens for Firefox 4 Agent Review till tomorrow... But looking good for next release or two. As well i'm not releasing the VA-API driver and MPP LIbrary Fork till after the 4 agent review and JFL Test. Rockchip be looking good my friends
-
Firefox for Rockchip
Where we are : Yes, that one is a buffer issue, in timing rather than size. Chromium hands the driver an empty buffer and asks for a frame to be decoded into it. A new buffer starts out all zeros, and zeros in the video format Chromium uses show as green. Chromium never asks "is it ready?" It assumes the frame is done the moment the decode call returns. Its own source code says so. Our AV1 path holds the newest frame back until the next one arrives, because the video interface never passes a piece of information the decoder needs. So the first frames of a video, and the first frames after YouTube steps up to 4K, can be shown before they're decoded. Later in playback a buffer being reused shows the previous frame instead of green, which is the flicker. Firefox is fine because it waits for each frame before using it. Not a memory or size problem: buffers are plentiful, and the memory checks for 3.5.0 are confirming that. The fix is in our driver, parked for the next version: finish those first frames before handing them back to Chromium.