KiteGC 1.0.0-RC1
Pre-release
Kite Ground Control is a modern, cross-platform ground station for INAV, ArduPilot and PX4. RC1 is
the first release candidate for 1.0. It delivers the reworked video pipeline promised in Beta 3 —
rebuilt from the ground up and validated on Windows, Linux (including Raspberry Pi) and macOS — and
clears the platform-specific defects Beta 3 shipped with.
Important
This is a release candidate — feature-complete for 1.0, but not yet a final release. Please
report anything you hit. It runs alongside your existing setup; back up flight logs and mission files
as a precaution.
Video paths at a glance
Which pipeline a stream takes is decided automatically, per source and per system, and the panel now
names the path it actually chose. It also decides which helper program you need:
| Source | Path taken | Helper needed | Where |
|---|---|---|---|
| RTSP · H.264 | go2rtc → WebRTC, decoded by the WebView (hardware, where the system offers it) | go2rtc | Windows, macOS, and Linux where the WebView provides WebRTC |
| RTSP · H.264, no WebRTC | ffmpeg converts to MJPEG, drawn in-app | ffmpeg | Linux systems whose WebKitGTK has no WebRTC |
| RTSP · MJPEG | ffmpeg stream-copies the source (no re-encoding), drawn in-app | ffmpeg | all platforms, WebRTC or not |
| Capture device, native mode | the WebView's own <video> where it can address the device; otherwise ffmpeg → in-app MJPEG |
ffmpeg for the fallback | all platforms |
| Webcam / camera | the WebView's own <video> |
— | all platforms |
Two consequences worth knowing:
- MJPEG never travels over WebRTC — the standard carries H.264, VP8, VP9 and AV1, not MJPEG. An
MJPEG RTSP source therefore uses the in-app image path even on a machine with full WebRTC support,
and go2rtc is not involved. Where WebRTC is missing entirely, go2rtc is not needed at all any more —
neither the Start button nor the download prompt asks for it there. - Hardware assistance for a conversion is Linux-only. On Windows and macOS a conversion never
arises for RTSP, because both always have WebRTC; it only occurs for a capture device delivering raw
or H.264, and runs in software there.
What's changed
Added
- RTSP video, rebuilt (all platforms). A saved connection list with names and a
per-connection transport (Auto / TCP / UDP), and automatic reconnection that keeps retrying
indefinitely with an overlay showing the attempt and a Stop button. Validated over LTE. - RTSP video through the WebRTC path on Linux — WebKitGTK's WebRTC support is now enabled at
startup, so Linux is no longer restricted to the expensive conversion. This depends on the
distribution: WebKitGTK implements WebRTC through GStreamer'swebrtcbin, which many distributions
do not install by default, and it needs WebKitGTK 2.38 or newer. Where either is missing, Kite falls
back to the conversion path automatically and says so in the log. - Native capture devices with full control (all platforms) — device, pixel format, resolution and
frame rate, each offered from what the device itself reports (V4L2 on Linux, DirectShow on Windows,
AVFoundation on macOS). This is what makes HDMI/USB capture dongles usable that browser camera access
does not expose at all. - Hardware-assisted conversion (Linux only) — VAAPI on desktop GPUs, and the SoC's own H.264
decoder on Raspberry Pi 3/4-class boards, which there is the difference between a usable picture and
none. Availability is probed by actually decoding a short clip, the verdict is cached, and repeated
failures fall back to software on their own. A "Disable hardware acceleration" toggle in the panel
overrides it for drivers that claim more than they deliver. - Codec, bitrate and an honest pipeline readout in the Video panel (all platforms) — the info
line under the picture reads e.g.720x576 · 60 fps · MJPEG · 17.1 Mbit/s, and the pipeline line
names stream copy vs. hardware vs. software conversion, and a hardware or software surface. - Video diagnostics in the in-app Debug Monitor (all platforms) — WebRTC pipeline statistics
(received/decoded frame rate, dropped frames, packet loss, freezes, jitter, playout delay) and MJPEG
reader statistics (arrival and drawn rates, dropped and corrupt frames, decode time, and the longest
arrival/draw gap beside a main-thread stall probe). - Diagnostics that survive a release build (all platforms) — the log file path is shown as
selectable text in Settings, with a fallback for desktops that cannot open a folder at all; frontend
events are written into the same log; and the session header records the executable path and the
resolved helper directory. - Media-stack self-check (Linux only) — Kite reports at startup which GStreamer components
WebKitGTK found, so a missing WebRTC or H.264 plugin is visible in the log instead of silently
degrading video. The AppImage brings its own media stack, so it does not depend on the host's;
.deb/.rpminstalls use the system's. - Power Saving now also drops the smooth bar animations in the speed and battery widgets (all
platforms) — the values read the same, the CPU cost during a flight does not. The setting was
renamed from "3D Power Saving" to "Power Saving" accordingly. - Unified download names for every artifact, and portable builds ship as a ZIP with the
.portable
marker already inside.
Changed
- MJPEG is read, decoded and drawn off the main thread (all platforms, by different routes) — one
reader feeds every visible surface (panel, widget, floating window, map) instead of each opening its
own stream, and a frame superseded while a decode is in flight is dropped rather than queued, the way
a real player behaves. On Windows the frames are drawn entirely off-thread; on the WebKit engines
(Linux, macOS) the decode stays off-thread and only the final draw returns to the main thread,
because WebKit cannot sustain more than one off-thread canvas. A WebView that refuses the path falls
back to the plain image sink automatically. - blackbox_decode installs itself on Linux and macOS too — the release archive is unpacked in-app
instead of pointing the user at a manual install. On macOS it also lands in a writable location now,
which it did not in Beta 3 (#20). - Looping status indicators blink at 1 Hz (Linux only) instead of animating continuously. On
WebKitGTK a looping animation makes the compositor rebuild the whole window per frame, so a single
eight-pixel dot measured about 46 % of a core — regardless of its size or whether it was on screen at
all. Windows and macOS keep the smooth pulses. - Bluetooth LE discovery runs in short, bounded scan windows (all platforms) — one on entering
BLE and one each time the device list is opened — instead of holding the adapter in continuous
discovery.
Fixed
- RTSP MJPEG stutter and multi-hundred-millisecond freezes (all platforms) — the long-standing
complaint. The MJPEG path ran through go2rtc, which repacked an already-MJPEG stream through
RTP/JPEG; measured against the same source over 120 s, the source itself had zero arrival gaps
above 200 ms and go2rtc's output had 69, each about 338 ms. Kite now reads the source directly
with ffmpeg, which measures as clean as the source. Field-verified at 576p60, and at 720p60 with the
source itself swinging between 45 and 60 fps. - Windows: an RTSP H.264 stream never played from an installed build. go2rtc splits its ffmpeg
setting on whitespace, so the path underC:\Program Files\…was truncated at the first space and
every stream failed into an endless reconnect. Only installed builds were affected, which is why it
survived development. MJPEG sources were never affected — that path starts ffmpeg itself. - Windows: an RTSP H.264 stream stayed black in a system-wide installation while the same
executable played fine from a portable folder. The WebView hid the local address behind an mDNS
alias, which cannot pair with go2rtc's loopback address, so no connection was ever established. - Windows: an RTSP H.264 stream could fail to start at all, repeatedly — the port search could land
inside a range that Hyper-V/WSL/Docker reserve, and kept drawing from the same range. - Linux: about 80 % idle CPU load and video stutter, caused by continuous Bluetooth LE discovery
flooding the system bus — not by Kite's rendering, which is where it had been looked for. - Linux: the Video panel could loop endlessly enumerating capture devices.
- Linux: roughly 300 % CPU that persisted after stopping a video feed in the AppImage. The cause was
the WebKitGTK version it bundled, so the Linux builds moved to a newer base — which also raises the
system requirement, see Installation. - Linux (AppImage): video and blackbox decoding failed because the AppImage's private library path
was inherited by every helper process it started. - Linux (Raspberry Pi): the window showed a garbled first frame until something forced a redraw.
- Helper downloads failed with HTTP 403 behind shared or carrier-grade NAT addresses (all
platforms, seen first on a Raspberry Pi over LTE) — go2rtc, ffmpeg and blackbox_decode now resolve
their download without the rate-limited GitHub API. - A dead RTSP source left the picture frozen instead of reconnecting (all platforms): the feed
ending is now signalled explicitly, on both render paths.
Contributors
- @SebastianKumor — macOS CI fix for the ffmpeg sidecar (#19).
Installation
Downloads follow one naming scheme: KiteGC_<OS>_<Arch>_<Version>_<Type>.
- Windows:
KiteGC_Windows_x64_1.0.0-rc1_installer.exe(NSIS installer), or..._portable.zip. - Linux (x86-64 and ARM64):
..._installer.deb/..._installer.rpm, the self-contained
..._standalone.AppImage, or..._portable.zip. - macOS (universal):
..._installer.dmg, or..._standalone.zipcontaining the app bundle. The
build is unsigned, so on first launch right-click the app → Open (or run
xattr -dr com.apple.quarantine "/Applications/Kite Ground Control.app"). - Portable (Windows & Linux): the ZIP already contains the empty
.portablemarker, so all data
stays in adata/folder beside the executable.
Important
The Linux system requirement has risen. All Linux artifacts are now built on Ubuntu 24.04 and
require glibc 2.39 or newer (Ubuntu 24.04, Debian 13, Raspberry Pi OS Trixie and later). Debian 12
and Raspberry Pi OS Bookworm are no longer covered by the prebuilt downloads — building from source on
those systems still works. The alternative was shipping a browser engine that burns a CPU core after
every video stop.
Known issues
- The macOS build is unsigned and not notarized (see Installation).
- RTSP is H.264 and MJPEG only. H.265 sources are not supported on either path.
- On Linux, WebRTC depends on the distribution (GStreamer
webrtcbin, WebKitGTK ≥ 2.38). Without
it, an H.264 RTSP stream is converted by ffmpeg, which costs noticeably more CPU; the AppImage avoids
the problem by bundling its own media stack. - The 3D map requires an internet connection — terrain and imagery are streamed and are not cached
for offline use. - Video relies on helper programs (go2rtc, ffmpeg) that Kite downloads on demand; on a machine
without internet access they have to be placed next to the executable manually.
Documentation
Guides and reference: https://b14ckyy.github.io/Kite-GC/
Feedback
Report bugs and ideas at https://github.com/b14ckyy/Kite-GC/issues (include the in-app diagnostics log
and your OS / autopilot / firmware versions).
Support
Donations toward development are appreciated: https://paypal.me/b14ckyy
GPL-3.0-or-later · © 2026 Marc Hoffmann (b14ckyy)