Linux · C++20 · Cast Streaming

Native Chromecast display mirroring. Low latency. No Chrome.

CastMirror is a high-performance native sender that discovers Cast devices on your LAN, captures the Linux desktop or individual application windows with system audio, and streams H.264 + Opus over the native Cast RTP/RTCP media path.

⏱️ ~200 ms Target Playout 🧪 87 / 87 Tests Passed VAAPI HW Encode
CastMirror — Cast Tab
Cast Tab: Discover receivers, select screen or window with app icons, and tune bitrate.

Capabilities

Engineered for Linux desktop mirroring

CastMirror operates directly at the Cast V2 protocol level — speaking the same RTP/RTCP and TLS channels Chrome uses, without running a web browser.

📺

One-Click Cast & Discovery

Continuous mDNS detection for Chromecast dongles, Google TV Streamer, and Cast TVs. Recognizes device models with custom glyphs or connects to custom IPs.

🖥️

Screen & Window Sharing

Mirror an entire monitor or stream a single window. Features X11 XComposite redirection for occluded windows and Wayland portal picker integration.

📈

Real-Time Vector Sparklines

Live session telemetry with hardware-accelerated Cairo Bézier mini-charts tracking FPS, bitrate, round-trip time (RTT), and packet loss in real time.

🎬

Live Studio Controls

Freeze display sharing and mute TV audio on the fly without terminating the session, injecting clean silence frames to maintain audio sync.

🔄

Adaptive Bitrate Ladder

Always-on 8-rung ladder controller holds your target bitrate ceiling (1–25 Mbps), drops during network congestion, and aggressively recovers once clear.

🛠️

Diagnostics & Appearance

Integrated self-test diagnostic wizard tests capturers, encoders, audio, and network sockets. Includes Light, Dark, and System default themes.

Architecture

Native Capture to Cast UDP Pipeline

Target playout delay is ~200 ms. Desktop pixels and PulseAudio/PipeWire monitor audio are encoded into zero-latency elementary streams, encrypted with session AES-128-CTR, and packetized into Cast RTP over UDP.

CastMirror Media Pipeline Diagram

Hardware Matrix

Cast video devices Chrome can mirror to

Tested across physical Google Cast devices. Nest Hub devices are 720p-class.

📺 Chromecast (3rd Gen) · 1080p60 ⚡ Chromecast Ultra · 4K30 / 1080p60 🚀 Google TV Streamer · 4K60 / 1080p60 🖥️ Cast TVs (Sony, Vizio, Philips) · 1080p60 📟 Google Nest Hub · 720p60

Documentation

Complete Technical Manual & Guides

All project documentation open on the website, migrated directly from the source repository.

1. Building & Installation Guide

Guide

Linux is the primary supported platform. You need a modern C++20 compiler (GCC 11+ or Clang 14+), CMake 3.20+, Ninja, and developer libraries for GTK 4, Libadwaita, FFmpeg, and PulseAudio.

Prerequisites (Debian / Ubuntu / Kali)

sudo apt update
sudo apt install -y build-essential cmake ninja-build pkg-config protobuf-compiler libprotobuf-dev     libssl-dev libopus-dev libpulse-dev libx11-dev libxext-dev libxrandr-dev libxfixes-dev     libxcomposite-dev libxdamage-dev     libva-dev libavcodec-dev libswscale-dev libavutil-dev nlohmann-json3-dev libgtest-dev     libgtk-4-dev libadwaita-1-dev
Optional Window Sharing Packages: libxcomposite-dev and libxdamage-dev enable occluded-window capture and damage tracking for X11 window sharing.

Configure and Build

cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
cmake --build build -j"12"

Build Artifacts

Binary PathComponent Role
build/app/castmirror-guiModern GTK 4 + Libadwaita desktop graphical application
build/app/castmirrorInteractive and non-interactive command-line interface
build/tests/castmirror_testsFull Google Test test suite (87 tests)
build/tools/poc-*Protocol, encoding, and transport benchmark tools
build/tools/fake-receiverAutomated simulated Cast receiver for local loopback verification

Running the GUI & CLI

# Launch the GTK 4 desktop app
./build/app/castmirror-gui

# Cast a full monitor via CLI
./build/app/castmirror --device 192.168.0.164 --display 0 --preset High

# List available application windows, then mirror one
./build/app/castmirror --list-windows
./build/app/castmirror --device 192.168.0.164 --window 0x2400004

# Cast display without mirroring system audio
./build/app/castmirror --device 192.168.0.164 --no-audio

Environment Variables

  • CASTMIRROR_FORCE_SOFTWARE_ENCODE=1: Force FFmpeg libx264 software encoding even when VAAPI GPU acceleration is available.
  • CASTMIRROR_FORCE_X11=1: Force X11 display capture instead of the PipeWire portal when running under a Wayland compositor via XWayland.

Network & Firewall Configuration

Control traffic uses TCP 8009 (TLS) to the receiver. Media streams use UDP to the ephemeral port returned in the ANSWER. Both devices must be on the same local subnet. Helper script: scripts/setup_firewall.sh.

2. System Architecture & Design

Architecture

CastMirror is structured as a modular C++20 engine (castcore) with a decoupled GTK 4 + Libadwaita GUI (app/gui) and CLI (app/cli).

Performance & Latency Contract

  • Connect to First Frame: ≤ 8 seconds typical (including TLS, app launch, and OFFER/ANSWER negotiation).
  • Glass-to-Glass Latency: ≤ 200–250 ms on a clean 5 GHz LAN with targetDelay: 200.
  • Teardown Budget: Clean Stop within ≤ 500 ms (guaranteed halt of capture, encoders, and UDP sockets).
  • Idle Safety: Capture and encoders never run in the background when disconnected.

Media Pipeline

  • Video Path: X11 XRandR / PipeWire portal → BGRA frame → GpuProcessor (letterbox scaling, direct YUV420P/NV12 plane write) → Hardware VAAPI / libx264 encoder (0 B-frames, zerolatency) → Annex-B NALUs → FrameCrypto (AES-128-CTR) → RtpPacketizer (Cast RTP) → Paced UDP socket.
  • Audio Path: PulseAudio / PipeWire default sink monitor → PCM 48 kHz stereo (10 ms chunks) → Opus encoder (192 kbps) → FrameCryptoRtpPacketizer → UDP. Host audio sink is muted during streaming and restored on Stop.

State Machine

All subsystems coordinate strictly through an explicit thread-safe state machine:

Idle → Discovering → Ready → Connecting → Negotiating → Streaming ↔ Reconnecting → Stopping → Idle
(Failed state transitions gracefully back to Idle or Reconnecting)

Module Boundaries

ModuleResponsibilities
DeviceDiscoverymDNS _googlecast._tcp browsing + local subnet TCP port 8009 scan
CastChannelTLS 1.2/1.3 Cast V2 socket on port 8009, Protobuf packet framing, PING/PONG heartbeats
MirroringNegotiatorFirmware app launch (0F5096E8), JSON OFFER/ANSWER generation, AES key negotiation
IDisplayCaptureModular X11 (MIT-SHM, XComposite, XDamage, XFixes) and Wayland (PipeWire portal) backends
IAudioCapturePulseAudio loopback monitor sink with automatic host speaker muting and restoration
IVideoEncoderHardware VAAPI (h264_vaapi) with automatic fallback to FFmpeg libx264
CastTransportUDP Cast RTP packetization, pacing token bucket, RTCP feedback parser, duplicate NACK suppression
AdaptiveController8-rung dynamic adaptation ladder tracking packet loss, RTT, and jitter

3. Device Compatibility & Adaptation Ladder

Matrix

CastMirror classifies receivers using mDNS capability bitmasks (ca) and model identifiers (md), verified against the receiver's negotiation ANSWER.

Receiver Compatibility Matrix

Device ModelModel String (md)H.264 ProfileMax Resolution & FPSPlayout Delay
Chromecast (1st/2nd Gen)Chromecast / NC2-6A5Level 4.11080p30, 720p60400 ms
Chromecast (3rd Gen)GA00439Level 4.21080p60, 720p60200 - 400 ms
Chromecast UltraNC2-6A5-DLevel 5.14K30, 1080p60200 - 400 ms
Chromecast with Google TV (HD)G454VLevel 4.21080p60, 720p60200 - 400 ms
Chromecast with Google TV (4K)GZRNLLevel 5.14K60 (VP9), 4K30 (H.264), 1080p60200 - 400 ms
Google TV Streamer (4K)GR1XNLevel 5.24K60, 1080p60200 - 400 ms
Google Nest Hub (1st/2nd Gen)Google Nest HubLevel 3.1720p60, 720p30 (720p-class)400 ms
Cast TVs (Sony, Vizio, Philips)Cast TVLevel 4.21080p60, 720p60200 - 400 ms

8-Rung Dynamic Adaptation Ladder

RungResolutionFPSTarget BitrateTrigger Condition
0 (Ultra 4K)3840 × 21606025.0 Mbps4K device, 0% loss, RTT < 20 ms
1 (4K Standard)3840 × 21603018.0 Mbps4K device, loss < 1%, RTT < 35 ms
2 (1440p High)2560 × 14406012.0 Mbps1440p+ device, loss < 1.5%
3 (1080p60 Max)1920 × 1080608.0 MbpsGen3 / Ultra / Google TV, loss < 2%
4 (1080p30 Default)1920 × 1080305.0 MbpsDefault baseline for all video receivers
5 (720p60 Smooth)1280 × 720604.0 MbpsLoss 2% – 5%, RTT > 60 ms
6 (720p30 Resilient)1280 × 720302.5 MbpsLoss 5% – 10%, RTT > 90 ms
7 (540p30 Emergency)960 × 540301.2 MbpsLoss > 10%, RTT > 150 ms

4. Cast Streaming Protocol Specification

Protocol

Google Cast screen mirroring uses a specialized real-time media protocol (not WebRTC ICE/DTLS and not HLS media playback).

1. Control Plane (Cast V2 TLS :8009)

  • Connection: OpenSSL TLS connection to device port 8009.
  • Protobuf Frame: 4-byte big-endian length prefix followed by serialized CastMessage.
  • Namespaces:
    • urn:x-cast:com.google.cast.tp.connection — Virtual sender/receiver session bindings.
    • urn:x-cast:com.google.cast.tp.heartbeat — PING / PONG keepalive packets (5-second cadence).
    • urn:x-cast:com.google.cast.receiverLAUNCH, STOP, and GET_STATUS requests.
    • urn:x-cast:com.google.cast.webrtc — JSON OFFER / ANSWER session negotiation.
  • Firmware Mirroring App ID: 0F5096E8 (audio + video display mirroring) or 85CDB22F (audio-only).

2. Media Plane (Cast RTP / RTCP over UDP)

  • RTP Profile: rtpProfile: "cast" with a custom 7-byte Cast RTP header extension:
    Byte 0:    Flags (Keyframe marker, Reference frame present)
    Bytes 1-2: Frame ID (monotonically increasing 16-bit integer)
    Bytes 3-4: Packet ID (packet index within frame)
    Bytes 5-6: Max Packet ID (total packet count - 1)
  • AES-128-CTR Crypto: Fresh random 16-byte key and 16-byte IV mask per session. Per-frame IV mixes frame_id with the IV mask.
  • Compound RTCP: Sender Reports (SR) paired with receiver CAST feedback packets containing:
    • Checkpoint Frame IDs acknowledging complete display rendering.
    • Loss bitmasks (NACK / CST2) detailing dropped UDP packets for immediate retransmit.
    • Picture Loss Indicators (PLI) signaling decoder desync and requesting an immediate IDR keyframe.

5. Test & Verification Report

Verification

CastMirror undergoes rigorous automated verification including unit tests, integration suites, synthetic network impairments, and simulated receiver loopback.

Test Suite Status (87 / 87 Passed — 100%)

Test CategoryTest CountStatusCoverage
State Machine & Reconnection6 testsPassedState transitions, callback notifications, retry limits
Config Store & Migrations8 testsPassedv1 → v2 → v3 migration, persistence, round-trip serialization
Capability & Device Matching4 testsPassedmDNS TXT parsing, hardware classification, resolution bounds
OFFER / ANSWER Negotiation4 testsPassedJSON schemas, custom bitrates, status queries
AES-128-CTR Cryptography2 testsPassedRoundtrip encryption/decryption, per-frame ciphertext variance
RTP Packetization & RTCP Parser5 testsPassed7-byte Cast header, MTU slicing, checkpoint expansion
Adaptive Controller Ladder14 testsPassedLoss downshifts, RTT jitter delay scaling, bitrate ramp-up
Video & Audio Encoders8 testsPassedVAAPI hardware, libx264 multi-slice, Opus 10ms cadence
Display & Window Capture10 testsPassedXRandR, XComposite occluded window capture, DMA-BUF metadata
UDP Transport & Pacing5 testsPassedToken bucket rate limiter, duplicate NACK suppression
Session Recovery & Source Selection15 testsPassedWindow geometry tracking, synthetic source fallback, 30s timeout
End-to-End Receiver Simulation6 testsPassedFull TLS + OFFER/ANSWER + media streaming + hard Stop

Latency Budget & Performance Verification

MetricTarget BudgetMeasured ResultVerdict
1080p60 Video Encode Latency≤ 16.6 ms9.75 – 12.48 msPASSED
Session Teardown & Stop Latency≤ 500 ms93.6 – 121.6 msPASSED
Session Connect to Streaming≤ 8.0 s< 100 ms (local)PASSED
CPU Utilization (1080p60 HW)< 15% 1 core< 8%PASSED