Support matrix
What each shipped recipe has been taken through, and against which pins. Every column but the last two is read from the recipe’s lock — the exact pins a build resolves — so this table cannot claim a combination that was never built.
| Status | Meaning |
|---|---|
validated | An image built from this recipe booted on the hardware. |
expected | Derived from a validated sibling, differing only along an axis not expected to change the outcome; never built, or built and never booted. |
experimental | Under active bring-up. It may not build. |
The date is when the claim was last established: for validated, the day the image
booted; otherwise the day the claim was last assessed. Re-pinning a lock under a
validated claim is flagged by boot2deb update, because moving the pins retires
the evidence the claim rested on.
A status says how far a build point has been taken, not that everything on the board works. What each one does not do is under Caveats below, and is printed at the end of a build of that recipe.
| Recipe | Device | Suite | Kernel | Patches | U-boot | Modules | Status | As of |
|---|---|---|---|---|---|---|---|---|
asus-c100p/forky | asus-c100p | forky | debian-armmp (from the suite) | none | none | none | expected | 2026-07-20 |
asus-c100p/trixie | asus-c100p | trixie | debian-armmp (from the suite) | none | none | none | expected | 2026-07-20 |
asus-c201-libreboot/forky | asus-c201-libreboot | forky | debian-armmp (from the suite) | none | none | none | expected | 2026-07-31 |
asus-c201-libreboot/libre-forky | asus-c201-libreboot | forky | rk3288-libre-7.2 sources/v7.2.8-gnu | rk3288-fixes main (14e7a6de48ff) | none | none | expected | 2026-08-21 |
asus-c201-libreboot/mainline-forky | asus-c201-libreboot | forky | rk3288-mainline-7.2 v7.2.9 | rk3288-fixes main (2fd63c3c0259) | none | none | expected | 2026-08-21 |
asus-c201/forky | asus-c201 | forky | debian-armmp (from the suite) | none | none | none | validated | 2026-07-14 |
asus-c201/libre-forky | asus-c201 | forky | rk3288-libre-7.2 sources/v7.2.8-gnu | rk3288-fixes main (14e7a6de48ff) | none | none | expected | 2026-08-21 |
asus-c201/mainline-forky | asus-c201 | forky | rk3288-mainline-7.2 v7.2.9 | rk3288-fixes main (2fd63c3c0259) | none | none | expected | 2026-08-21 |
asus-c201/trixie | asus-c201 | trixie | debian-armmp (from the suite) | none | none | none | expected | 2026-07-20 |
asus-chromebit-cs10/forky | asus-chromebit-cs10 | forky | debian-armmp (from the suite) | none | none | none | expected | 2026-07-20 |
asus-chromebit-cs10/trixie | asus-chromebit-cs10 | trixie | debian-armmp (from the suite) | none | none | none | expected | 2026-07-20 |
h96-max-m9/forky | h96-max-m9 | forky | rk3576-mainline-7.2 v7.2.9 | rk3576-fixes, rk3576-npu main (2fd63c3c0259) | rk3576-display main (2fd63c3c0259) | aic8800 main (d13d07963cd1) | expected | 2026-08-21 |
h96-max-m9/media-accel | h96-max-m9 | forky | rk3576-mainline-7.2 v7.2.9 | rk3576-fixes, rk3576-npu, rk3576-rga, rk3576-media main (2fd63c3c0259) | rk3576-display main (2fd63c3c0259) | aic8800 main (d13d07963cd1) | expected | 2026-09-14 |
h96-max-m9/util | h96-max-m9 | — | (u-boot only) | none | h96-max-m9-util main (14e7a6de48ff) | none | expected | 2026-07-22 |
rk3576-evb1-v10/forky | rk3576-evb1-v10 | forky | rk3576-mainline-7.2 v7.2.9 | rk3576-fixes main (2fd63c3c0259) | rk3576-loader main (2fd63c3c0259) | none | expected | 2026-08-21 |
rk3576-generic/loader | rk3576-generic | — | (u-boot only) | none | rk3576-loader main (14e7a6de48ff) | none | expected | 2026-07-21 |
rk3576-generic/util | rk3576-generic | — | (u-boot only) | none | rk3576-util main (14e7a6de48ff) | none | expected | 2026-07-21 |
turing-rk1/forky | turing-rk1 | forky | rk3588-mainline-7.2 v7.2.9 | rk3588-accel main (7b945e71fd55) | turing-rk1-recovery main (7b945e71fd55) | none | expected | 2026-09-05 |
turing-rk1/jellyfin-forky | turing-rk1 | forky | rk3588-mainline-7.2 v7.2.9 | rk3588-accel main (7b945e71fd55) | turing-rk1-recovery main (7b945e71fd55) | none | expected | 2026-09-05 |
turing-rk1/jellyfin-trixie | turing-rk1 | trixie | rk3588-mainline-7.2 v7.2.9 | rk3588-accel main (7b945e71fd55) | turing-rk1-recovery main (7b945e71fd55) | none | experimental | 2026-08-21 |
turing-rk1/media-accel-forky | turing-rk1 | forky | rk3588-mainline-7.2 v7.2.9 | rk3588-accel main (7b945e71fd55) | turing-rk1-recovery main (7b945e71fd55) | none | expected | 2026-09-05 |
turing-rk1/media-accel-trixie | turing-rk1 | trixie | rk3588-mainline-7.2 v7.2.9 | rk3588-accel main (7b945e71fd55) | turing-rk1-recovery main (7b945e71fd55) | none | expected | 2026-08-21 |
turing-rk1/trixie | turing-rk1 | trixie | rk3588-mainline-7.2 v7.2.9 | rk3588-accel main (7b945e71fd55) | turing-rk1-recovery main (7b945e71fd55) | none | expected | 2026-08-21 |
turing-rk1/util | turing-rk1 | — | (u-boot only) | none | turing-rk1-util main (4350b1a5e405) | none | expected | 2026-08-05 |
Caveats
Limitations that hold whatever you build: they come from the silicon, the board, a
capability the recipe selected, or the build point itself, and no rebuild lifts them.
The first two are listed once per device, since they hold for every recipe on it; the
rest are listed per recipe, and a (feature) tag marks the ones that follow their
capability onto any other recipe composing it. A recipe with none listed is not a
recipe with none — nothing mechanical establishes that — only one that states none.
Anything a running system could be asked about belongs in that board’s selftest expectations instead, where it fails rather than merely informs. These are the ones that cannot be checked from the running system.
asus-c100p
- (SoC) HDMI tops out at 4K30 and cannot reach 4K60. The RK3288 caps TMDS at 340 MHz, and its PHY has no scrambling above that. The VOP cannot emit YUV420, so there is no reduced-rate path either.
- (board) Two display controllers advertise the same maximum resolution, and DRM decides at runtime which one the HDMI encoder lands on. The smaller of the two (VOPL) tops out at 2560x1600. A 4K display showing only part of the picture is that, and
dmesg | grep -i vopsays which controller it got.
asus-c201-libreboot
- (SoC) HDMI tops out at 4K30 and cannot reach 4K60. The RK3288 caps TMDS at 340 MHz, and its PHY has no scrambling above that. The VOP cannot emit YUV420, so there is no reduced-rate path either.
- (board) Two display controllers advertise the same maximum resolution, and DRM decides at runtime which one the HDMI encoder lands on. The smaller of the two (VOPL) tops out at 2560x1600. A 4K display showing only part of the picture is that, and
dmesg | grep -i vopsays which controller it got.
asus-c201
- (SoC) HDMI tops out at 4K30 and cannot reach 4K60. The RK3288 caps TMDS at 340 MHz, and its PHY has no scrambling above that. The VOP cannot emit YUV420, so there is no reduced-rate path either.
- (board) Two display controllers advertise the same maximum resolution, and DRM decides at runtime which one the HDMI encoder lands on. The smaller of the two (VOPL) tops out at 2560x1600. A 4K display showing only part of the picture is that, and
dmesg | grep -i vopsays which controller it got.
asus-chromebit-cs10
- (SoC) HDMI tops out at 4K30 and cannot reach 4K60. The RK3288 caps TMDS at 340 MHz, and its PHY has no scrambling above that. The VOP cannot emit YUV420, so there is no reduced-rate path either.
h96-max-m9
- (SoC) HDMI tops out at 4K30 and cannot reach 4K60. The dw-hdmi-qp bridge has no SCDC/scrambling support and rejects every mode above 340 MHz TMDS, even where the display advertises 4K60. This is upstream behavior, not a device-tree limitation.
- (SoC) There is no mainline hardware video encoder for this SoC. Decode is driven (VDPU383, H.264 and HEVC, 1080p and 4K). Encode is not driven at all.
- (SoC) Hardware H.264 decode has a silicon erratum here, and the kernel this builder ships works around it. Whether the decoder comes up correct is decided when its power domain powers up. Unwarmed, roughly one power-up in three comes up bad: 634 of 2000 measured power-ups, 95% CI 30-34%. Resolution makes no difference, at 92 of 300 against 84 of 300 interleaved.
- (SoC) The bad-power-up draw is independent every time, so no boot is luckier than another. A power-up that decoded correctly says nothing about the next one. Every H.264 decode made on a bad power-up is corrupt, and retrying does not help until the block powers down and up again.
- (SoC) H.264 corruption from a bad power-up is visible, about 17 dB PSNR, and diverges from the first frame. Exactly one row in eight of each plane is wrong, because a deblocking filter runs on a horizontal edge the stream does not contain. The damage lands in the reference buffers, so motion compensation spreads it across the rest of the picture within a few frames.
- (SoC) The H.264 work-around decodes a canned 2x2 frame on the decoder at every runtime resume, before any decode of that power cycle can run. It holds across system sleep as well as runtime PM. On the shipped kernel, 0 of 400 power-ups came up corrupt against an interleaved control’s 128 of 400. A further 200 alternating 1080p and 4K were also clean.
- (SoC) If the warm-up ever fails the driver says so in dmesg:
vdpu383 warm-up job timed out, or... not ready. H.264 decoded on that power cycle is then suspect. HEVC is unaffected either way, and is bit-exact against software on every run at every block size. Do not rely on a kernel without the work-around for hardware H.264 decode on this SoC. Its software decoder is correct and fast enough, at about 160 fps at 1080p and 40 at 4K. - (SoC) The NPU computes but nothing can drive it yet: the rocket userspace stack targets RK3588 only, so no RK3576 userspace exists.
- (board) Only the blue port beside HDMI carries USB 3.0. It reaches 5 Gbps and holds ~154 MB/s over sustained reads. The black ports never will – they sit behind an internal USB 2.0 hub, and their SuperSpeed lane reaches no connector.
- (board) A drive in the blue port that enumerates at 480 Mb/s is usually not seated. With the board sitting back from the enclosure’s front panel, a plug bottoms out on the case before the connector’s recessed SuperSpeed contacts mate. USB 2.0 then works perfectly and SuperSpeed is silent. Push the plug fully home, or reseat the board against the panel.
- (board) There is no SD-card slot: it is depopulated on this box. eMMC and USB are the only storage.
rk3576-evb1-v10
- (SoC) HDMI tops out at 4K30 and cannot reach 4K60. The dw-hdmi-qp bridge has no SCDC/scrambling support and rejects every mode above 340 MHz TMDS, even where the display advertises 4K60. This is upstream behavior, not a device-tree limitation.
- (SoC) There is no mainline hardware video encoder for this SoC. Decode is driven (VDPU383, H.264 and HEVC, 1080p and 4K). Encode is not driven at all.
- (SoC) Hardware H.264 decode has a silicon erratum here, and the kernel this builder ships works around it. Whether the decoder comes up correct is decided when its power domain powers up. Unwarmed, roughly one power-up in three comes up bad: 634 of 2000 measured power-ups, 95% CI 30-34%. Resolution makes no difference, at 92 of 300 against 84 of 300 interleaved.
- (SoC) The bad-power-up draw is independent every time, so no boot is luckier than another. A power-up that decoded correctly says nothing about the next one. Every H.264 decode made on a bad power-up is corrupt, and retrying does not help until the block powers down and up again.
- (SoC) H.264 corruption from a bad power-up is visible, about 17 dB PSNR, and diverges from the first frame. Exactly one row in eight of each plane is wrong, because a deblocking filter runs on a horizontal edge the stream does not contain. The damage lands in the reference buffers, so motion compensation spreads it across the rest of the picture within a few frames.
- (SoC) The H.264 work-around decodes a canned 2x2 frame on the decoder at every runtime resume, before any decode of that power cycle can run. It holds across system sleep as well as runtime PM. On the shipped kernel, 0 of 400 power-ups came up corrupt against an interleaved control’s 128 of 400. A further 200 alternating 1080p and 4K were also clean.
- (SoC) If the warm-up ever fails the driver says so in dmesg:
vdpu383 warm-up job timed out, or... not ready. H.264 decoded on that power cycle is then suspect. HEVC is unaffected either way, and is bit-exact against software on every run at every block size. Do not rely on a kernel without the work-around for hardware H.264 decode on this SoC. Its software decoder is correct and fast enough, at about 160 fps at 1080p and 40 at 4K. - (SoC) The NPU computes but nothing can drive it yet: the rocket userspace stack targets RK3588 only, so no RK3576 userspace exists.
rk3576-generic
- (SoC) HDMI tops out at 4K30 and cannot reach 4K60. The dw-hdmi-qp bridge has no SCDC/scrambling support and rejects every mode above 340 MHz TMDS, even where the display advertises 4K60. This is upstream behavior, not a device-tree limitation.
- (SoC) There is no mainline hardware video encoder for this SoC. Decode is driven (VDPU383, H.264 and HEVC, 1080p and 4K). Encode is not driven at all.
- (SoC) Hardware H.264 decode has a silicon erratum here, and the kernel this builder ships works around it. Whether the decoder comes up correct is decided when its power domain powers up. Unwarmed, roughly one power-up in three comes up bad: 634 of 2000 measured power-ups, 95% CI 30-34%. Resolution makes no difference, at 92 of 300 against 84 of 300 interleaved.
- (SoC) The bad-power-up draw is independent every time, so no boot is luckier than another. A power-up that decoded correctly says nothing about the next one. Every H.264 decode made on a bad power-up is corrupt, and retrying does not help until the block powers down and up again.
- (SoC) H.264 corruption from a bad power-up is visible, about 17 dB PSNR, and diverges from the first frame. Exactly one row in eight of each plane is wrong, because a deblocking filter runs on a horizontal edge the stream does not contain. The damage lands in the reference buffers, so motion compensation spreads it across the rest of the picture within a few frames.
- (SoC) The H.264 work-around decodes a canned 2x2 frame on the decoder at every runtime resume, before any decode of that power cycle can run. It holds across system sleep as well as runtime PM. On the shipped kernel, 0 of 400 power-ups came up corrupt against an interleaved control’s 128 of 400. A further 200 alternating 1080p and 4K were also clean.
- (SoC) If the warm-up ever fails the driver says so in dmesg:
vdpu383 warm-up job timed out, or... not ready. H.264 decoded on that power cycle is then suspect. HEVC is unaffected either way, and is bit-exact against software on every run at every block size. Do not rely on a kernel without the work-around for hardware H.264 decode on this SoC. Its software decoder is correct and fast enough, at about 160 fps at 1080p and 40 at 4K. - (SoC) The NPU computes but nothing can drive it yet: the rocket userspace stack targets RK3588 only, so no RK3576 userspace exists.
asus-c201-libreboot/libre-forky
- The internal BCM4354 Wi-Fi and Bluetooth do not work. linux-libre removes brcmfmac’s firmware request and btbcm’s patchram filename. This radio is the one part of the board that cannot run without a blob. An AR9271 USB adapter (firmware-ath9k-htc, in Debian main and already installed) is the supported way onto a network.
asus-c201/libre-forky
- The internal BCM4354 Wi-Fi and Bluetooth do not work. linux-libre removes brcmfmac’s firmware request and btbcm’s patchram filename. This radio is the one part of the board that cannot run without a blob. An AR9271 USB adapter (firmware-ath9k-htc, in Debian main and already installed) is the supported way onto a network.
h96-max-m9/media-accel
- (feature) 10-bit content decodes to
NV15, packed 10-bit 4:2:0. The decoder cannot be asked forP010instead, because the hardware writesNV15natively. ffmpeg here carries theNV15format patches, so a 10-bit frame reacheshwdownloadand the software filters. What that costs is a CPU conversion, because no filter in this build readsNV15directly. - (feature) The zero-copy route for 10-bit is the display, not a filter. The display controller scans
NV15out unconverted. A player that hands the decoder’s DMA-BUF straight to a KMS plane therefore plays 10-bit unconverted. RGA is no 10-bit route either. It takesNV15in but writes no 10-bit format out: this SoC has RGA2 cores only, andP010output is an RGA3 capability. - (feature) Nothing packaged by Debian can use this decoder.
ffmpeg-rkinstalls to/opt, so it coexists with the system FFmpeg. Debian’s own libavcodec is built without--enable-v4l2-request. It carries noh264_v4l2requestorhevc_v4l2requesthwaccel at all. mpv, Kodi and VLC from the archive link that libavcodec, so they decode in software. Reaching the hardware from a player means building the player against this FFmpeg. - (feature) ffmpeg has no RGA filters here.
scale_rkrgaandvpp_rkrganeed--enable-rkmpp, and MPP needs the vendormpp_servicekernel framework that mainline does not have. ffmpeg scales on the CPU. RGA is reached through librga by a program that speaks its API. - (feature) This GPU has no Vulkan driver. Mesa’s PanVk declines the Mali-G52 unless
PAN_I_WANT_A_BROKEN_VULKAN_DRIVERis set. With it set, Mesa 26.1 and 26.2 compute wrong chroma in ffmpeg’s Vulkan filters. The image therefore installs none, andscale_vulkan,libplaceboand the other Vulkan filters fail at device creation. Installingmesa-vulkan-driversadds onlylvp, the llvmpipe software device, which runs those filters on the CPU more slowly than swscale. OpenGL ES is unaffected: Panfrost drives GLES 3.1 on this GPU. - (feature) RGA color conversion covers BT.601 limited and full range and BT.709, but not BT.2020.
- (feature) Pass RGA its buffers as DMA-BUF file descriptors (
importbuffer_fd). librga’s virtual-address import builds an IOMMU mapping per call over ordinary process memory. That faults the RGA IOMMU on roughly a third of jobs. The job then times out after a second, the core is soft-reset, and the destination is left untouched. The same operations over DMA-BUF run clean and about seven times faster.
turing-rk1/jellyfin-forky
- (feature) Scaling and compositing inside a hardware transcode run on RGA, but only when the RKMPP device is named explicitly. The RGA filters (
scale_rkrga,vpp_rkrga,overlay_rkrga) allocate their output pool from an RKMPP device. They take one from-filter_hw_devicewhen the incoming frames carry a different one. A chain fed by-hwaccel v4l2requesttherefore needs-init_hw_device rkmpp=rk -filter_hw_device rk, and then keeps every frame in hardware from decode to encode. Without it the filters fail to configure withNo RKMPP hardware context provided, which reads like a frame-format problem and is not one. - (feature)
hwmapdoes not bridge a Vulkan frame to an RKMPP one in either direction. A Vulkan filter stage must therefore round-trip through system memory before the encoder. - (feature) The
h264_rkmpp,hevc_rkmpp,vp8_rkmppandvp9_rkmppdecoders are compiled in but fail to open. MPP finds no decode client on a mainline kernel, whererkvdecis a V4L2 stateless driver rather than an MPP service. Hardware decode is reached with-hwaccel v4l2request. The matching*_rkmppencoders do work. - (feature) 10-bit decoded frames are
NV15, packed 4:2:0 at four samples per five bytes. The decoder cannot be asked forP010instead:rkvdecdeclaresNV12/NV15/NV16/NV20and noP010, because the hardware writes packed. - (feature) Two routes consume
NV15. RGA (scale_rkrga,vpp_rkrga,overlay_rkrga) converts it in hardware on the way out.hwdownload,format=nv15brings it to system memory, where a secondformat=yuv420p10leunpacks it in swscale. That is what lets a GPU tone mapper such aslibplacebosee a hardware-decoded HDR frame. - (feature)
hwdownloadoffers only the frame’s own format, so asking foryuv420p10lein one step leaves the graph with no viable target.hwmapdoes not substitute either: deriving a Vulkan frames context from the mapped frame fails withUnsupported pixel format: nv15. - (feature) Vulkan cannot import
NV15at all, because there is no VkFormat for a packed 10-bit 4:2:0 sample. A Vulkan stage always needs the swscale unpack in front of it. It must uploadyuv420p10lerather thanp010le, which corrupts silently. - (feature) Hardware JPEG encode is
mjpeg_v4l2m2m, and it is a different device from the H.264/HEVC encoders with different rules. It is the mainline VEPU121 on/dev/video2rather than MPP, so it takes system-memory frames only:yuv420p,nv12,yuyv422oruyvy422, neverdrm_prime. A hardware-decoded frame reaches it through FFmpeg’s own transfer or an explicithwdownload,format=nv12, not through-filter_hw_device. - (feature) JPEG quality is
-quality 5..100, or-q:von the same scale, larger being better. Omitting both keeps the driver default of 50. That inverts the softwaremjpegencoder, where-q:vis a quantizer and lower is better. A value carried over from a software command line therefore asks for the opposite quality. - (feature) What the JPEG device buys is CPU rather than elapsed time. It holds a fixed 4.9 CPU-seconds per 300 1080p frames, but software
mjpegthreads across all eight cores while this path submits serially. A batch therefore finishes slower in wall clock for about half the CPU. - (feature) Two JPEG limits are the driver’s, not the wrapper’s. The largest frame it accepts is 8176x8176, which is 511 macroblocks in each axis and the most the hardware’s nine-bit dimension registers hold. Widths are rounded up to a multiple of 4, which the encoder reports when it happens.
- (feature) Clamp your own JPEG input to 8176 rather than relying on the refusal. V4L2 has the driver substitute a size it can do. A larger request is honored at 8176 while ffmpeg keeps feeding the wider frame in. The result is a JPEG whose header looks right and whose picture is garbage. The encoder logs
encoder coded size is ...first, so treat that message as an error whenever the size it reports is smaller than the one requested. - (feature) AVS2 and AVS3 do not decode unless the
avs-decodefeature is composed in. The hardware has no V4L2 route to either codec, and without that feature this ffmpeg is not built with--enable-libdavs2or--enable-libuavs3d. Such a stream demuxes, because theavs2andavs3demuxers are always present, and then fails with no decoder found. Theavsandcavsdecoders a listing shows are a 1990s game FMV format and AVS1-P2 JiZhun respectively. Only AVS1 plays here on its own. - (feature) Every
ffmpeg-rkinvocation writesmpp_platform: client N driver is not ready!to standard error, once per vendor service client MPP looks for and does not find on a mainline kernel. It is harmless and appears even forffmpeg -version, but it is captured by anything that logs the process’s stderr. - Transcoding is hardware-encode only. The seeded /etc/jellyfin/encoding.xml selects the
rkmppacceleration type with an empty hardware-decoding codec list, so video is decoded and scaled on the CPU and encoded on the VEPU580. Re-enabling any codec under Playback > Transcoding > “Enable hardware decoding for” makes Jellyfin emit-hwaccel rkmpp, whose decoder cannot open on a mainline kernel, and those streams fail outright rather than falling back to software. - Jellyfin’s bundled FFmpeg is not installed — the recipe supplies /opt/ffmpeg-rk/bin/ffmpeg instead, which is the only build here that can reach the VEPU580. There is therefore no second encoder to fall back to. Jellyfin validates the path during startup and exits if the binary does not run. An
<EncoderAppPath>in /etc/jellyfin/encoding.xml that names no working FFmpeg therefore stops the server rather than leaving it to transcode in software. The dashboard’s “FFmpeg path” field only displays that path: change it by editing the file with the service stopped.
turing-rk1/jellyfin-trixie
- (feature) Scaling and compositing inside a hardware transcode run on RGA, but only when the RKMPP device is named explicitly. The RGA filters (
scale_rkrga,vpp_rkrga,overlay_rkrga) allocate their output pool from an RKMPP device. They take one from-filter_hw_devicewhen the incoming frames carry a different one. A chain fed by-hwaccel v4l2requesttherefore needs-init_hw_device rkmpp=rk -filter_hw_device rk, and then keeps every frame in hardware from decode to encode. Without it the filters fail to configure withNo RKMPP hardware context provided, which reads like a frame-format problem and is not one. - (feature)
hwmapdoes not bridge a Vulkan frame to an RKMPP one in either direction. A Vulkan filter stage must therefore round-trip through system memory before the encoder. - (feature) The
h264_rkmpp,hevc_rkmpp,vp8_rkmppandvp9_rkmppdecoders are compiled in but fail to open. MPP finds no decode client on a mainline kernel, whererkvdecis a V4L2 stateless driver rather than an MPP service. Hardware decode is reached with-hwaccel v4l2request. The matching*_rkmppencoders do work. - (feature) 10-bit decoded frames are
NV15, packed 4:2:0 at four samples per five bytes. The decoder cannot be asked forP010instead:rkvdecdeclaresNV12/NV15/NV16/NV20and noP010, because the hardware writes packed. - (feature) Two routes consume
NV15. RGA (scale_rkrga,vpp_rkrga,overlay_rkrga) converts it in hardware on the way out.hwdownload,format=nv15brings it to system memory, where a secondformat=yuv420p10leunpacks it in swscale. That is what lets a GPU tone mapper such aslibplacebosee a hardware-decoded HDR frame. - (feature)
hwdownloadoffers only the frame’s own format, so asking foryuv420p10lein one step leaves the graph with no viable target.hwmapdoes not substitute either: deriving a Vulkan frames context from the mapped frame fails withUnsupported pixel format: nv15. - (feature) Vulkan cannot import
NV15at all, because there is no VkFormat for a packed 10-bit 4:2:0 sample. A Vulkan stage always needs the swscale unpack in front of it. It must uploadyuv420p10lerather thanp010le, which corrupts silently. - (feature) Hardware JPEG encode is
mjpeg_v4l2m2m, and it is a different device from the H.264/HEVC encoders with different rules. It is the mainline VEPU121 on/dev/video2rather than MPP, so it takes system-memory frames only:yuv420p,nv12,yuyv422oruyvy422, neverdrm_prime. A hardware-decoded frame reaches it through FFmpeg’s own transfer or an explicithwdownload,format=nv12, not through-filter_hw_device. - (feature) JPEG quality is
-quality 5..100, or-q:von the same scale, larger being better. Omitting both keeps the driver default of 50. That inverts the softwaremjpegencoder, where-q:vis a quantizer and lower is better. A value carried over from a software command line therefore asks for the opposite quality. - (feature) What the JPEG device buys is CPU rather than elapsed time. It holds a fixed 4.9 CPU-seconds per 300 1080p frames, but software
mjpegthreads across all eight cores while this path submits serially. A batch therefore finishes slower in wall clock for about half the CPU. - (feature) Two JPEG limits are the driver’s, not the wrapper’s. The largest frame it accepts is 8176x8176, which is 511 macroblocks in each axis and the most the hardware’s nine-bit dimension registers hold. Widths are rounded up to a multiple of 4, which the encoder reports when it happens.
- (feature) Clamp your own JPEG input to 8176 rather than relying on the refusal. V4L2 has the driver substitute a size it can do. A larger request is honored at 8176 while ffmpeg keeps feeding the wider frame in. The result is a JPEG whose header looks right and whose picture is garbage. The encoder logs
encoder coded size is ...first, so treat that message as an error whenever the size it reports is smaller than the one requested. - (feature) AVS2 and AVS3 do not decode unless the
avs-decodefeature is composed in. The hardware has no V4L2 route to either codec, and without that feature this ffmpeg is not built with--enable-libdavs2or--enable-libuavs3d. Such a stream demuxes, because theavs2andavs3demuxers are always present, and then fails with no decoder found. Theavsandcavsdecoders a listing shows are a 1990s game FMV format and AVS1-P2 JiZhun respectively. Only AVS1 plays here on its own. - (feature) Every
ffmpeg-rkinvocation writesmpp_platform: client N driver is not ready!to standard error, once per vendor service client MPP looks for and does not find on a mainline kernel. It is harmless and appears even forffmpeg -version, but it is captured by anything that logs the process’s stderr. - Transcoding is hardware-encode only. The seeded /etc/jellyfin/encoding.xml selects the
rkmppacceleration type with an empty hardware-decoding codec list, so video is decoded and scaled on the CPU and encoded on the VEPU580. Re-enabling any codec under Playback > Transcoding > “Enable hardware decoding for” makes Jellyfin emit-hwaccel rkmpp, whose decoder cannot open on a mainline kernel, and those streams fail outright rather than falling back to software. - Jellyfin’s bundled FFmpeg is not installed — the recipe supplies /opt/ffmpeg-rk/bin/ffmpeg instead, which is the only build here that can reach the VEPU580. There is therefore no second encoder to fall back to. Jellyfin validates the path during startup and exits if the binary does not run. An
<EncoderAppPath>in /etc/jellyfin/encoding.xml that names no working FFmpeg therefore stops the server rather than leaving it to transcode in software. The dashboard’s “FFmpeg path” field only displays that path: change it by editing the file with the service stopped.
turing-rk1/media-accel-forky
- (feature) Scaling and compositing inside a hardware transcode run on RGA, but only when the RKMPP device is named explicitly. The RGA filters (
scale_rkrga,vpp_rkrga,overlay_rkrga) allocate their output pool from an RKMPP device. They take one from-filter_hw_devicewhen the incoming frames carry a different one. A chain fed by-hwaccel v4l2requesttherefore needs-init_hw_device rkmpp=rk -filter_hw_device rk, and then keeps every frame in hardware from decode to encode. Without it the filters fail to configure withNo RKMPP hardware context provided, which reads like a frame-format problem and is not one. - (feature)
hwmapdoes not bridge a Vulkan frame to an RKMPP one in either direction. A Vulkan filter stage must therefore round-trip through system memory before the encoder. - (feature) The
h264_rkmpp,hevc_rkmpp,vp8_rkmppandvp9_rkmppdecoders are compiled in but fail to open. MPP finds no decode client on a mainline kernel, whererkvdecis a V4L2 stateless driver rather than an MPP service. Hardware decode is reached with-hwaccel v4l2request. The matching*_rkmppencoders do work. - (feature) 10-bit decoded frames are
NV15, packed 4:2:0 at four samples per five bytes. The decoder cannot be asked forP010instead:rkvdecdeclaresNV12/NV15/NV16/NV20and noP010, because the hardware writes packed. - (feature) Two routes consume
NV15. RGA (scale_rkrga,vpp_rkrga,overlay_rkrga) converts it in hardware on the way out.hwdownload,format=nv15brings it to system memory, where a secondformat=yuv420p10leunpacks it in swscale. That is what lets a GPU tone mapper such aslibplacebosee a hardware-decoded HDR frame. - (feature)
hwdownloadoffers only the frame’s own format, so asking foryuv420p10lein one step leaves the graph with no viable target.hwmapdoes not substitute either: deriving a Vulkan frames context from the mapped frame fails withUnsupported pixel format: nv15. - (feature) Vulkan cannot import
NV15at all, because there is no VkFormat for a packed 10-bit 4:2:0 sample. A Vulkan stage always needs the swscale unpack in front of it. It must uploadyuv420p10lerather thanp010le, which corrupts silently. - (feature) Hardware JPEG encode is
mjpeg_v4l2m2m, and it is a different device from the H.264/HEVC encoders with different rules. It is the mainline VEPU121 on/dev/video2rather than MPP, so it takes system-memory frames only:yuv420p,nv12,yuyv422oruyvy422, neverdrm_prime. A hardware-decoded frame reaches it through FFmpeg’s own transfer or an explicithwdownload,format=nv12, not through-filter_hw_device. - (feature) JPEG quality is
-quality 5..100, or-q:von the same scale, larger being better. Omitting both keeps the driver default of 50. That inverts the softwaremjpegencoder, where-q:vis a quantizer and lower is better. A value carried over from a software command line therefore asks for the opposite quality. - (feature) What the JPEG device buys is CPU rather than elapsed time. It holds a fixed 4.9 CPU-seconds per 300 1080p frames, but software
mjpegthreads across all eight cores while this path submits serially. A batch therefore finishes slower in wall clock for about half the CPU. - (feature) Two JPEG limits are the driver’s, not the wrapper’s. The largest frame it accepts is 8176x8176, which is 511 macroblocks in each axis and the most the hardware’s nine-bit dimension registers hold. Widths are rounded up to a multiple of 4, which the encoder reports when it happens.
- (feature) Clamp your own JPEG input to 8176 rather than relying on the refusal. V4L2 has the driver substitute a size it can do. A larger request is honored at 8176 while ffmpeg keeps feeding the wider frame in. The result is a JPEG whose header looks right and whose picture is garbage. The encoder logs
encoder coded size is ...first, so treat that message as an error whenever the size it reports is smaller than the one requested. - (feature) AVS2 and AVS3 do not decode unless the
avs-decodefeature is composed in. The hardware has no V4L2 route to either codec, and without that feature this ffmpeg is not built with--enable-libdavs2or--enable-libuavs3d. Such a stream demuxes, because theavs2andavs3demuxers are always present, and then fails with no decoder found. Theavsandcavsdecoders a listing shows are a 1990s game FMV format and AVS1-P2 JiZhun respectively. Only AVS1 plays here on its own. - (feature) Every
ffmpeg-rkinvocation writesmpp_platform: client N driver is not ready!to standard error, once per vendor service client MPP looks for and does not find on a mainline kernel. It is harmless and appears even forffmpeg -version, but it is captured by anything that logs the process’s stderr. - (feature) This feature adds 25 packages and roughly 305 MiB to the installed system, measured against the RK3588 media-accel package set on forky. Two thirds of it is not the driver.
mesa-vulkan-driversis 144 MiB, and it depends onlibllvm21(127 MiB) and through itlibz3-4(25 MiB). Those two are there for thelvpsoftware rasterizer Debian ships in the same package, rather than for PanVk. - (feature) Debian offers no per-driver package.
mesa-vulkan-driverscarries the AMD, Intel, NVIDIA, virtio and software back ends as well as the Mali one this hardware uses. An image that wants PanVk therefore takes all of them and the LLVM they imply. - (feature) Vulkan support is a per-GPU fact, not a per-feature one. PanVk is conformant on the RK3588’s Mali-G610. On the RK3576’s Mali-G52 it declines the device unless
PAN_I_WANT_A_BROKEN_VULKAN_DRIVERis set. With it set, Mesa 26.1 and 26.2 compute wrong chroma in ffmpeg’s Vulkan filters. The same package installs on both, and on the RK3576 its only working device islvp. - (feature) A software Vulkan device (
lvp, llvmpipe) enumerates alongside the hardware one. Anything that leaves device selection to the default can bind it and run GPU work on the CPU. That is slower than not using this feature at all, and it does not announce itself.
turing-rk1/media-accel-trixie
- (feature) Scaling and compositing inside a hardware transcode run on RGA, but only when the RKMPP device is named explicitly. The RGA filters (
scale_rkrga,vpp_rkrga,overlay_rkrga) allocate their output pool from an RKMPP device. They take one from-filter_hw_devicewhen the incoming frames carry a different one. A chain fed by-hwaccel v4l2requesttherefore needs-init_hw_device rkmpp=rk -filter_hw_device rk, and then keeps every frame in hardware from decode to encode. Without it the filters fail to configure withNo RKMPP hardware context provided, which reads like a frame-format problem and is not one. - (feature)
hwmapdoes not bridge a Vulkan frame to an RKMPP one in either direction. A Vulkan filter stage must therefore round-trip through system memory before the encoder. - (feature) The
h264_rkmpp,hevc_rkmpp,vp8_rkmppandvp9_rkmppdecoders are compiled in but fail to open. MPP finds no decode client on a mainline kernel, whererkvdecis a V4L2 stateless driver rather than an MPP service. Hardware decode is reached with-hwaccel v4l2request. The matching*_rkmppencoders do work. - (feature) 10-bit decoded frames are
NV15, packed 4:2:0 at four samples per five bytes. The decoder cannot be asked forP010instead:rkvdecdeclaresNV12/NV15/NV16/NV20and noP010, because the hardware writes packed. - (feature) Two routes consume
NV15. RGA (scale_rkrga,vpp_rkrga,overlay_rkrga) converts it in hardware on the way out.hwdownload,format=nv15brings it to system memory, where a secondformat=yuv420p10leunpacks it in swscale. That is what lets a GPU tone mapper such aslibplacebosee a hardware-decoded HDR frame. - (feature)
hwdownloadoffers only the frame’s own format, so asking foryuv420p10lein one step leaves the graph with no viable target.hwmapdoes not substitute either: deriving a Vulkan frames context from the mapped frame fails withUnsupported pixel format: nv15. - (feature) Vulkan cannot import
NV15at all, because there is no VkFormat for a packed 10-bit 4:2:0 sample. A Vulkan stage always needs the swscale unpack in front of it. It must uploadyuv420p10lerather thanp010le, which corrupts silently. - (feature) Hardware JPEG encode is
mjpeg_v4l2m2m, and it is a different device from the H.264/HEVC encoders with different rules. It is the mainline VEPU121 on/dev/video2rather than MPP, so it takes system-memory frames only:yuv420p,nv12,yuyv422oruyvy422, neverdrm_prime. A hardware-decoded frame reaches it through FFmpeg’s own transfer or an explicithwdownload,format=nv12, not through-filter_hw_device. - (feature) JPEG quality is
-quality 5..100, or-q:von the same scale, larger being better. Omitting both keeps the driver default of 50. That inverts the softwaremjpegencoder, where-q:vis a quantizer and lower is better. A value carried over from a software command line therefore asks for the opposite quality. - (feature) What the JPEG device buys is CPU rather than elapsed time. It holds a fixed 4.9 CPU-seconds per 300 1080p frames, but software
mjpegthreads across all eight cores while this path submits serially. A batch therefore finishes slower in wall clock for about half the CPU. - (feature) Two JPEG limits are the driver’s, not the wrapper’s. The largest frame it accepts is 8176x8176, which is 511 macroblocks in each axis and the most the hardware’s nine-bit dimension registers hold. Widths are rounded up to a multiple of 4, which the encoder reports when it happens.
- (feature) Clamp your own JPEG input to 8176 rather than relying on the refusal. V4L2 has the driver substitute a size it can do. A larger request is honored at 8176 while ffmpeg keeps feeding the wider frame in. The result is a JPEG whose header looks right and whose picture is garbage. The encoder logs
encoder coded size is ...first, so treat that message as an error whenever the size it reports is smaller than the one requested. - (feature) AVS2 and AVS3 do not decode unless the
avs-decodefeature is composed in. The hardware has no V4L2 route to either codec, and without that feature this ffmpeg is not built with--enable-libdavs2or--enable-libuavs3d. Such a stream demuxes, because theavs2andavs3demuxers are always present, and then fails with no decoder found. Theavsandcavsdecoders a listing shows are a 1990s game FMV format and AVS1-P2 JiZhun respectively. Only AVS1 plays here on its own. - (feature) Every
ffmpeg-rkinvocation writesmpp_platform: client N driver is not ready!to standard error, once per vendor service client MPP looks for and does not find on a mainline kernel. It is harmless and appears even forffmpeg -version, but it is captured by anything that logs the process’s stderr. - (feature) This feature adds 25 packages and roughly 305 MiB to the installed system, measured against the RK3588 media-accel package set on forky. Two thirds of it is not the driver.
mesa-vulkan-driversis 144 MiB, and it depends onlibllvm21(127 MiB) and through itlibz3-4(25 MiB). Those two are there for thelvpsoftware rasterizer Debian ships in the same package, rather than for PanVk. - (feature) Debian offers no per-driver package.
mesa-vulkan-driverscarries the AMD, Intel, NVIDIA, virtio and software back ends as well as the Mali one this hardware uses. An image that wants PanVk therefore takes all of them and the LLVM they imply. - (feature) Vulkan support is a per-GPU fact, not a per-feature one. PanVk is conformant on the RK3588’s Mali-G610. On the RK3576’s Mali-G52 it declines the device unless
PAN_I_WANT_A_BROKEN_VULKAN_DRIVERis set. With it set, Mesa 26.1 and 26.2 compute wrong chroma in ffmpeg’s Vulkan filters. The same package installs on both, and on the RK3576 its only working device islvp. - (feature) A software Vulkan device (
lvp, llvmpipe) enumerates alongside the hardware one. Anything that leaves device selection to the default can bind it and run GPU work on the CPU. That is slower than not using this feature at all, and it does not announce itself.