--- title: wl2kodi related: - "[Kodi](../guides/kodi.md)" - "[send2kodi](send2kodi.md)" - "[browser2kodi](browser2kodi.md)" categories: - Tools and applications --- **wl2kodi** mirrors the screen of a wlroots Wayland desktop to Kodi with low latency. The stream is hardware-encoded on the sender's GPU and hardware-decoded on the receiver, so the TV box stays idle. ## Why Most screen-mirroring setups make the receiver do real work. That fails on a Raspberry Pi: it has a capable video decoder but a weak CPU, so anything that misses the hardware decode path turns into a slideshow. wl2kodi puts every expensive step on the sender. The laptop captures its own framebuffer without a copy, encodes H.264 on its GPU, and sends a plain MPEG-TS stream over UDP. The Pi only does hardware decode straight to the display plane. On a Raspberry Pi 3 receiving 1080p30, the CPU sits around 13%, mostly Kodi's own interface. ``` ┌─────────────── laptop ───────────────┐ ┌──────── Raspberry Pi ────────┐ │ compositor ──DMA-BUF──▶ GPU encoder │ │ V4L2 M2M ──DRM PRIME──▶ TV │ │ (no copy) (H.264) │─UDP─▶│ hardware decode, zero-copy │ └──────────────────────────────────────┘ └──────────────────────────────┘ ``` It is deliberately not a new protocol: H.264 MPEG-TS over UDP is what Kodi already plays for IPTV. ## Requirements - **Sender:** a wlroots compositor (Hyprland, Sway, river...), a VAAPI-capable GPU, `wf-recorder` and `curl`. - **Receiver:** Kodi with hardware decoding on, and *Settings → Services → Control → Allow remote control via HTTP* enabled. ``` # pacman -S wf-recorder curl ``` ## Installation ``` $ git clone https://github.com/hugoocoto/wl2kodi $ install -Dm755 wl2kodi/wl2kodi ~/.local/bin/wl2kodi ``` It is also available through the [pm user repository](pm-user-repository.md). ## Usage ``` $ wl2kodi --tv 192.168.1.50 ``` It detects the monitor and its resolution, asks Kodi what the TV runs at, sizes the stream to match, picks a render node, starts encoding and tells the TV to tune in. Ctrl-C stops the encoder and the playback on the TV. ``` $ wl2kodi --tv 192.168.1.50 --mode fill # crop to the TV's aspect $ wl2kodi --tv 192.168.1.50 --res 720 # lower latency, softer text $ wl2kodi --tv 192.168.1.50 --res 720 --fifo 300 --bitrate 5M # lowest latency $ wl2kodi --tv 192.168.1.50 --dry-run # show what it would do ``` Every option also works as an environment variable; see `wl2kodi --help`. ## Latency Expect 200–500 ms. Kodi does not expose its decode and render queues, so that is a floor. Fine for slides, demos, video and browsing; not for gaming. > [!TIP] > Put the receiver on Ethernet and turn on the TV's Game Mode. Those two beat > every option inside the tool. ### How it stays fast | Decision | Reason | |---|---| | DMA-BUF capture | The frame never touches system RAM on the way to the encoder | | No B-frames | B-frames reference future frames, so they buffer by definition | | `low_power=1` | Uses the GPU's low-latency encode path | | Keyframe every 0.5 s | A lost packet resolves twice as fast | | Bounded receive FIFO | ffmpeg's default holds seconds of video; wl2kodi caps it (`--fifo`) | | UDP | No retransmission stalls; a late frame is worse than a lost one | | `pkt_size=1316` | Exactly 7 MPEG-TS packets, so datagrams never fragment | ### The macroblock ceiling H.264 Level 4.1 allows 8192 macroblocks. 1920×1080 is 8160; a 16:10 panel at 1920×1200 is 9000. Over the limit, the receiver silently falls back to software decoding. wl2kodi always scales on the sender and refuses to emit more than `--max-mb` (default 8192). ## Troubleshooting - **Nothing appears, but Kodi says OK:** check Kodi's log for `failed to configure renderer`, and don't start a stream within ~30 s of restarting Kodi. - **wf-recorder is already running:** `pkill -x wf-recorder`. - **Washed-out colors:** the encoder emits full range; not handled yet. ## Limitations - Video only, no audio yet. - wlroots compositors only; GNOME and KDE would need a PipeWire portal. - H.264 only, one receiver at a time. ## See also - [Kodi](../guides/kodi.md), setting Kodi up for this and its sibling tools - [Source code](https://github.com/hugoocoto/wl2kodi) (MIT) - [send2kodi](send2kodi.md), to send a link or a file instead of the screen - [browser2kodi](browser2kodi.md), to send what you are looking at in the browser