Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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.

StatusMeaning
validatedAn image built from this recipe booted on the hardware.
expectedDerived from a validated sibling, differing only along an axis not expected to change the outcome; never built, or built and never booted.
experimentalUnder 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.

RecipeDeviceSuiteKernelPatchesU-bootModulesStatusAs of
asus-c100p/forkyasus-c100pforkydebian-armmp (from the suite)nonenonenoneexpected2026-07-20
asus-c100p/trixieasus-c100ptrixiedebian-armmp (from the suite)nonenonenoneexpected2026-07-20
asus-c201-libreboot/forkyasus-c201-librebootforkydebian-armmp (from the suite)nonenonenoneexpected2026-07-31
asus-c201-libreboot/libre-forkyasus-c201-librebootforkyrk3288-libre-7.2 sources/v7.2.8-gnurk3288-fixes main (14e7a6de48ff)nonenoneexpected2026-08-21
asus-c201-libreboot/mainline-forkyasus-c201-librebootforkyrk3288-mainline-7.2 v7.2.9rk3288-fixes main (2fd63c3c0259)nonenoneexpected2026-08-21
asus-c201/forkyasus-c201forkydebian-armmp (from the suite)nonenonenonevalidated2026-07-14
asus-c201/libre-forkyasus-c201forkyrk3288-libre-7.2 sources/v7.2.8-gnurk3288-fixes main (14e7a6de48ff)nonenoneexpected2026-08-21
asus-c201/mainline-forkyasus-c201forkyrk3288-mainline-7.2 v7.2.9rk3288-fixes main (2fd63c3c0259)nonenoneexpected2026-08-21
asus-c201/trixieasus-c201trixiedebian-armmp (from the suite)nonenonenoneexpected2026-07-20
asus-chromebit-cs10/forkyasus-chromebit-cs10forkydebian-armmp (from the suite)nonenonenoneexpected2026-07-20
asus-chromebit-cs10/trixieasus-chromebit-cs10trixiedebian-armmp (from the suite)nonenonenoneexpected2026-07-20
h96-max-m9/forkyh96-max-m9forkyrk3576-mainline-7.2 v7.2.9rk3576-fixes, rk3576-npu main (2fd63c3c0259)rk3576-display main (2fd63c3c0259)aic8800 main (d13d07963cd1)expected2026-08-21
h96-max-m9/media-accelh96-max-m9forkyrk3576-mainline-7.2 v7.2.9rk3576-fixes, rk3576-npu, rk3576-rga, rk3576-media main (2fd63c3c0259)rk3576-display main (2fd63c3c0259)aic8800 main (d13d07963cd1)expected2026-09-14
h96-max-m9/utilh96-max-m9—(u-boot only)noneh96-max-m9-util main (14e7a6de48ff)noneexpected2026-07-22
rk3576-evb1-v10/forkyrk3576-evb1-v10forkyrk3576-mainline-7.2 v7.2.9rk3576-fixes main (2fd63c3c0259)rk3576-loader main (2fd63c3c0259)noneexpected2026-08-21
rk3576-generic/loaderrk3576-generic—(u-boot only)nonerk3576-loader main (14e7a6de48ff)noneexpected2026-07-21
rk3576-generic/utilrk3576-generic—(u-boot only)nonerk3576-util main (14e7a6de48ff)noneexpected2026-07-21
turing-rk1/forkyturing-rk1forkyrk3588-mainline-7.2 v7.2.9rk3588-accel main (7b945e71fd55)turing-rk1-recovery main (7b945e71fd55)noneexpected2026-09-05
turing-rk1/jellyfin-forkyturing-rk1forkyrk3588-mainline-7.2 v7.2.9rk3588-accel main (7b945e71fd55)turing-rk1-recovery main (7b945e71fd55)noneexpected2026-09-05
turing-rk1/jellyfin-trixieturing-rk1trixierk3588-mainline-7.2 v7.2.9rk3588-accel main (7b945e71fd55)turing-rk1-recovery main (7b945e71fd55)noneexperimental2026-08-21
turing-rk1/media-accel-forkyturing-rk1forkyrk3588-mainline-7.2 v7.2.9rk3588-accel main (7b945e71fd55)turing-rk1-recovery main (7b945e71fd55)noneexpected2026-09-05
turing-rk1/media-accel-trixieturing-rk1trixierk3588-mainline-7.2 v7.2.9rk3588-accel main (7b945e71fd55)turing-rk1-recovery main (7b945e71fd55)noneexpected2026-08-21
turing-rk1/trixieturing-rk1trixierk3588-mainline-7.2 v7.2.9rk3588-accel main (7b945e71fd55)turing-rk1-recovery main (7b945e71fd55)noneexpected2026-08-21
turing-rk1/utilturing-rk1—(u-boot only)noneturing-rk1-util main (4350b1a5e405)noneexpected2026-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 vop says 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 vop says 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 vop says 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 for P010 instead, because the hardware writes NV15 natively. ffmpeg here carries the NV15 format patches, so a 10-bit frame reaches hwdownload and the software filters. What that costs is a CPU conversion, because no filter in this build reads NV15 directly.
  • (feature) The zero-copy route for 10-bit is the display, not a filter. The display controller scans NV15 out 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 takes NV15 in but writes no 10-bit format out: this SoC has RGA2 cores only, and P010 output is an RGA3 capability.
  • (feature) Nothing packaged by Debian can use this decoder. ffmpeg-rk installs to /opt, so it coexists with the system FFmpeg. Debian’s own libavcodec is built without --enable-v4l2-request. It carries no h264_v4l2request or hevc_v4l2request hwaccel 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_rkrga and vpp_rkrga need --enable-rkmpp, and MPP needs the vendor mpp_service kernel 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_DRIVER is set. With it set, Mesa 26.1 and 26.2 compute wrong chroma in ffmpeg’s Vulkan filters. The image therefore installs none, and scale_vulkan, libplacebo and the other Vulkan filters fail at device creation. Installing mesa-vulkan-drivers adds only lvp, 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_device when the incoming frames carry a different one. A chain fed by -hwaccel v4l2request therefore 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 with No RKMPP hardware context provided, which reads like a frame-format problem and is not one.
  • (feature) hwmap does 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_rkmpp and vp9_rkmpp decoders are compiled in but fail to open. MPP finds no decode client on a mainline kernel, where rkvdec is a V4L2 stateless driver rather than an MPP service. Hardware decode is reached with -hwaccel v4l2request. The matching *_rkmpp encoders do work.
  • (feature) 10-bit decoded frames are NV15, packed 4:2:0 at four samples per five bytes. The decoder cannot be asked for P010 instead: rkvdec declares NV12/NV15/NV16/NV20 and no P010, 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=nv15 brings it to system memory, where a second format=yuv420p10le unpacks it in swscale. That is what lets a GPU tone mapper such as libplacebo see a hardware-decoded HDR frame.
  • (feature) hwdownload offers only the frame’s own format, so asking for yuv420p10le in one step leaves the graph with no viable target. hwmap does not substitute either: deriving a Vulkan frames context from the mapped frame fails with Unsupported pixel format: nv15.
  • (feature) Vulkan cannot import NV15 at 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 upload yuv420p10le rather than p010le, 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/video2 rather than MPP, so it takes system-memory frames only: yuv420p, nv12, yuyv422 or uyvy422, never drm_prime. A hardware-decoded frame reaches it through FFmpeg’s own transfer or an explicit hwdownload,format=nv12, not through -filter_hw_device.
  • (feature) JPEG quality is -quality 5..100, or -q:v on the same scale, larger being better. Omitting both keeps the driver default of 50. That inverts the software mjpeg encoder, where -q:v is 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 mjpeg threads 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-decode feature is composed in. The hardware has no V4L2 route to either codec, and without that feature this ffmpeg is not built with --enable-libdavs2 or --enable-libuavs3d. Such a stream demuxes, because the avs2 and avs3 demuxers are always present, and then fails with no decoder found. The avs and cavs decoders a listing shows are a 1990s game FMV format and AVS1-P2 JiZhun respectively. Only AVS1 plays here on its own.
  • (feature) Every ffmpeg-rk invocation writes mpp_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 for ffmpeg -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 rkmpp acceleration 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_device when the incoming frames carry a different one. A chain fed by -hwaccel v4l2request therefore 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 with No RKMPP hardware context provided, which reads like a frame-format problem and is not one.
  • (feature) hwmap does 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_rkmpp and vp9_rkmpp decoders are compiled in but fail to open. MPP finds no decode client on a mainline kernel, where rkvdec is a V4L2 stateless driver rather than an MPP service. Hardware decode is reached with -hwaccel v4l2request. The matching *_rkmpp encoders do work.
  • (feature) 10-bit decoded frames are NV15, packed 4:2:0 at four samples per five bytes. The decoder cannot be asked for P010 instead: rkvdec declares NV12/NV15/NV16/NV20 and no P010, 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=nv15 brings it to system memory, where a second format=yuv420p10le unpacks it in swscale. That is what lets a GPU tone mapper such as libplacebo see a hardware-decoded HDR frame.
  • (feature) hwdownload offers only the frame’s own format, so asking for yuv420p10le in one step leaves the graph with no viable target. hwmap does not substitute either: deriving a Vulkan frames context from the mapped frame fails with Unsupported pixel format: nv15.
  • (feature) Vulkan cannot import NV15 at 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 upload yuv420p10le rather than p010le, 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/video2 rather than MPP, so it takes system-memory frames only: yuv420p, nv12, yuyv422 or uyvy422, never drm_prime. A hardware-decoded frame reaches it through FFmpeg’s own transfer or an explicit hwdownload,format=nv12, not through -filter_hw_device.
  • (feature) JPEG quality is -quality 5..100, or -q:v on the same scale, larger being better. Omitting both keeps the driver default of 50. That inverts the software mjpeg encoder, where -q:v is 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 mjpeg threads 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-decode feature is composed in. The hardware has no V4L2 route to either codec, and without that feature this ffmpeg is not built with --enable-libdavs2 or --enable-libuavs3d. Such a stream demuxes, because the avs2 and avs3 demuxers are always present, and then fails with no decoder found. The avs and cavs decoders a listing shows are a 1990s game FMV format and AVS1-P2 JiZhun respectively. Only AVS1 plays here on its own.
  • (feature) Every ffmpeg-rk invocation writes mpp_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 for ffmpeg -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 rkmpp acceleration 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_device when the incoming frames carry a different one. A chain fed by -hwaccel v4l2request therefore 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 with No RKMPP hardware context provided, which reads like a frame-format problem and is not one.
  • (feature) hwmap does 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_rkmpp and vp9_rkmpp decoders are compiled in but fail to open. MPP finds no decode client on a mainline kernel, where rkvdec is a V4L2 stateless driver rather than an MPP service. Hardware decode is reached with -hwaccel v4l2request. The matching *_rkmpp encoders do work.
  • (feature) 10-bit decoded frames are NV15, packed 4:2:0 at four samples per five bytes. The decoder cannot be asked for P010 instead: rkvdec declares NV12/NV15/NV16/NV20 and no P010, 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=nv15 brings it to system memory, where a second format=yuv420p10le unpacks it in swscale. That is what lets a GPU tone mapper such as libplacebo see a hardware-decoded HDR frame.
  • (feature) hwdownload offers only the frame’s own format, so asking for yuv420p10le in one step leaves the graph with no viable target. hwmap does not substitute either: deriving a Vulkan frames context from the mapped frame fails with Unsupported pixel format: nv15.
  • (feature) Vulkan cannot import NV15 at 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 upload yuv420p10le rather than p010le, 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/video2 rather than MPP, so it takes system-memory frames only: yuv420p, nv12, yuyv422 or uyvy422, never drm_prime. A hardware-decoded frame reaches it through FFmpeg’s own transfer or an explicit hwdownload,format=nv12, not through -filter_hw_device.
  • (feature) JPEG quality is -quality 5..100, or -q:v on the same scale, larger being better. Omitting both keeps the driver default of 50. That inverts the software mjpeg encoder, where -q:v is 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 mjpeg threads 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-decode feature is composed in. The hardware has no V4L2 route to either codec, and without that feature this ffmpeg is not built with --enable-libdavs2 or --enable-libuavs3d. Such a stream demuxes, because the avs2 and avs3 demuxers are always present, and then fails with no decoder found. The avs and cavs decoders a listing shows are a 1990s game FMV format and AVS1-P2 JiZhun respectively. Only AVS1 plays here on its own.
  • (feature) Every ffmpeg-rk invocation writes mpp_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 for ffmpeg -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-drivers is 144 MiB, and it depends on libllvm21 (127 MiB) and through it libz3-4 (25 MiB). Those two are there for the lvp software rasterizer Debian ships in the same package, rather than for PanVk.
  • (feature) Debian offers no per-driver package. mesa-vulkan-drivers carries 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_DRIVER is 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 is lvp.
  • (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_device when the incoming frames carry a different one. A chain fed by -hwaccel v4l2request therefore 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 with No RKMPP hardware context provided, which reads like a frame-format problem and is not one.
  • (feature) hwmap does 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_rkmpp and vp9_rkmpp decoders are compiled in but fail to open. MPP finds no decode client on a mainline kernel, where rkvdec is a V4L2 stateless driver rather than an MPP service. Hardware decode is reached with -hwaccel v4l2request. The matching *_rkmpp encoders do work.
  • (feature) 10-bit decoded frames are NV15, packed 4:2:0 at four samples per five bytes. The decoder cannot be asked for P010 instead: rkvdec declares NV12/NV15/NV16/NV20 and no P010, 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=nv15 brings it to system memory, where a second format=yuv420p10le unpacks it in swscale. That is what lets a GPU tone mapper such as libplacebo see a hardware-decoded HDR frame.
  • (feature) hwdownload offers only the frame’s own format, so asking for yuv420p10le in one step leaves the graph with no viable target. hwmap does not substitute either: deriving a Vulkan frames context from the mapped frame fails with Unsupported pixel format: nv15.
  • (feature) Vulkan cannot import NV15 at 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 upload yuv420p10le rather than p010le, 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/video2 rather than MPP, so it takes system-memory frames only: yuv420p, nv12, yuyv422 or uyvy422, never drm_prime. A hardware-decoded frame reaches it through FFmpeg’s own transfer or an explicit hwdownload,format=nv12, not through -filter_hw_device.
  • (feature) JPEG quality is -quality 5..100, or -q:v on the same scale, larger being better. Omitting both keeps the driver default of 50. That inverts the software mjpeg encoder, where -q:v is 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 mjpeg threads 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-decode feature is composed in. The hardware has no V4L2 route to either codec, and without that feature this ffmpeg is not built with --enable-libdavs2 or --enable-libuavs3d. Such a stream demuxes, because the avs2 and avs3 demuxers are always present, and then fails with no decoder found. The avs and cavs decoders a listing shows are a 1990s game FMV format and AVS1-P2 JiZhun respectively. Only AVS1 plays here on its own.
  • (feature) Every ffmpeg-rk invocation writes mpp_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 for ffmpeg -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-drivers is 144 MiB, and it depends on libllvm21 (127 MiB) and through it libz3-4 (25 MiB). Those two are there for the lvp software rasterizer Debian ships in the same package, rather than for PanVk.
  • (feature) Debian offers no per-driver package. mesa-vulkan-drivers carries 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_DRIVER is 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 is lvp.
  • (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.