LiveKit on host networking so WebRTC can advertise a reachable address, plus the server and website.
3.2 KiB
Spike: video performance on the Pi Zero 2W
The original question was whether WebKitGTK could reach hardware H.264 decode. That turned out to be moot: WebKitGTK ships without WebRTC at all, so the kiosk cannot receive media in the webview.
The kiosk now joins the room from Rust with the native LiveKit SDK. Decoding happens there, each frame is scaled and JPEG encoded, and the result is pushed to the webview to be drawn on a canvas. The question this spike answers has therefore changed: can a Zero 2W decode the incoming stream and re-encode it fast enough to look live.
The decode half is still worth measuring with the commands below, because libwebrtc uses the
same V4L2 path. The encode half is measured from the app itself, by lowering
PISTATION_VIDEO_MAX_WIDTH, PISTATION_VIDEO_FPS and PISTATION_VIDEO_QUALITY until the
picture keeps up.
Baseline
The Zero 2W has a VideoCore IV class block exposed through V4L2 stateful decode at
/dev/video10, reached through GStreamer's v4l2h264dec.
Steps
-
Confirm the kernel exposes the decoder.
ls -l /dev/video10 /dev/video11 /dev/video12 v4l2-ctl -d /dev/video10 --all | head -40/dev/video10must reportCodec Decodercapabilities. -
Confirm GStreamer picks the hardware element over the software one.
gst-inspect-1.0 v4l2h264dec gst-launch-1.0 videotestsrc num-buffers=600 ! video/x-raw,width=1280,height=720 \ ! x264enc tune=zerolatency ! h264parse ! v4l2h264dec ! fpsdisplaysink text-overlay=falseRecord the reported average FPS. Under 25 means the decode path is not viable.
-
Run the same clip through the software decoder for comparison.
gst-launch-1.0 videotestsrc num-buffers=600 ! video/x-raw,width=1280,height=720 \ ! x264enc tune=zerolatency ! h264parse ! avdec_h264 ! fpsdisplaysink text-overlay=falseIf step 2 and step 3 report similar numbers, WebKit is almost certainly using software decode and the hardware element is not being selected.
-
Measure the real path. Start the kiosk, join from a laptop, share a 1280x720 screen, and sample CPU while the stream is live.
systemctl start pistation-kiosk top -b -n 30 -d 1 | grep -E "WebKitWebProcess|pistation-kiosk"Sustained WebKitWebProcess CPU above roughly 85 percent of one core means the decode is running in software.
-
Force the issue if step 4 is inconclusive.
GST_DEBUG=v4l2*:5 systemctl start pistation-kiosk journalctl -u pistation-kiosk | grep -i v4l2h264dec
Recording the result
| Measurement | Value | Pass threshold |
|---|---|---|
v4l2h264dec 720p30 FPS |
25 or higher | |
| WebKitWebProcess CPU, 720p live share | under 85 percent of one core | |
| Frames dropped over 5 minutes | under 1 percent | |
| Annotation input to on-screen latency | under 250 ms |
If the spike fails
- Try 960x540 at 20 fps by capping the publisher in
apps/web-clientbefore declaring failure. The Zero 2W often passes at that resolution. - If it still fails, build
services/compositor-bot. GStreamer composites the screen share and the annotation canvas server side and sends the Pi one stream, which drops the Pi's job to plain video playback.