Skip to content

feat(VideoManager): add WebSocket JPEG video source - #14731

Open
alireza787b wants to merge 26 commits into
mavlink:masterfrom
alireza787b:agent/websocket-jpeg-video-source-v3
Open

feat(VideoManager): add WebSocket JPEG video source#14731
alireza787b wants to merge 26 commits into
mavlink:masterfrom
alireza787b:agent/websocket-jpeg-video-source-v3

Conversation

@alireza787b

@alireza787b alireza787b commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Description

This adds a generic WebSocket JPEG Video Stream source. Each binary WebSocket message carries one complete JPEG image; text messages are ignored.

The implementation:

  • accepts full ws:// and wss:// URLs in Video settings;
  • owns QWebSocket on a dedicated Qt event-loop thread and feeds bounded appsrc ! jpegparse into the existing receiver;
  • limits compressed messages to 16 MiB, dimensions to 8,192 pixels, and the decoded four-byte display-surface budget to 64 MiB;
  • retains at most two compressed frames and drops older queued frames when decoding falls behind;
  • verifies WSS certificates with QGC's trust configuration, rejects redirects and URL user information, and uses logging-safe diagnostics;
  • reports malformed JPEG messages, handshake failures, disconnects, and TLS failures through the receiver pipeline bus and reconnect lifecycle; and
  • requires Qt WebSockets only when GStreamer video is enabled.

This first transport slice proves live reception. It does not change recording policy and supports unauthenticated endpoints only; authorization headers and secret storage belong in a separate generic security proposal.

This is stacked after #14730, which carries #14727 and #14729. Compared with the exact HTTP head, the WebSocket slice is 17 files with 1,325 additions and 27 deletions, with substantial validation, TLS, delivery, failure, and lifecycle coverage.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update
  • Refactoring
  • CI/Build changes
  • Other

Testing

  • Tested locally
  • Added/updated unit tests
  • Tested with simulator (not applicable)
  • Tested with camera hardware

An integrated candidate containing this transport was manually exercised on Linux, Windows, and Android. Camera-free tests cover valid and fragmented JPEG delivery, malformed-message closure, baseline and progressive JPEG validation, decoded-size limits, bounded queues, trusted and untrusted WSS, handshake failure, remote disconnect, immediate teardown, unsafe URLs, and receiver lifecycle.

The focused transport probe previously passed 100/100 delivery runs and 100/100 untrusted-WSS error-delivery runs; the same paths passed 20/20 each under ASan/UBSan.

Exact PR head: 082bc258bd0bf007f813c6c805ceb830820062aa.

Exact-head QGC CI is complete: Linux x64/arm64 release builds, unit and integration tests, ASan/UBSan, coverage thresholds, Windows, macOS, iOS, Android, Docker, custom-plugin, and CodeQL checks passed. Linux evidence: run 30598327092.

Platforms Tested

  • Linux
  • Windows
  • macOS (QGC exact-head CI build)
  • Android
  • iOS (QGC exact-head CI build)

Flight Stacks Tested

Not applicable; this change is confined to video reception.

Screenshots

Not applicable; the UI addition uses the existing Video settings layout.

Checklist

  • I have read the Contribution Guidelines
  • I have read the Code of Conduct
  • My code follows the project coding standards
  • I have added tests that prove the feature works
  • New and existing unit and integration tests pass at the exact head in QGC CI

Related Issues


By submitting this pull request, I confirm that my contribution is made under the terms of the project's dual license (Apache 2.0 and GPL v3).

@github-actions github-actions Bot added Docs github_actions Pull requests that update GitHub Actions code CMake Tests Video size/XL labels Jul 28, 2026
@alireza787b
alireza787b force-pushed the agent/websocket-jpeg-video-source-v3 branch from 3bbdf58 to c2e4e9f Compare July 28, 2026 10:13
@alireza787b
alireza787b force-pushed the agent/websocket-jpeg-video-source-v3 branch 3 times, most recently from df8edb0 to e2b9427 Compare July 28, 2026 11:28
@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Build Results

Platform Status

Platform Status Details
Linux Passed View
Windows Passed View
MacOS Passed View
Android Passed View

All builds passed.

Pre-commit

Check Status Details
pre-commit Failed (non-blocking) View

Pre-commit hooks: 0 passed, 0 failed, 0 skipped.

Test Results

linux-coverage-integration: 37 passed, 0 skipped
linux-coverage-unit: 119 passed, 0 skipped
linux-sanitizers-integration: 20 passed, 0 skipped
linux-sanitizers-unit: 119 passed, 0 skipped
Total: 295 passed, 0 skipped

Code Coverage

Coverage: 69.5%

No baseline available for comparison

Artifact Sizes

Artifact Size
QGroundControl 221.99 MB
QGroundControl-aarch64 179.51 MB
QGroundControl-installer-AMD64 138.01 MB
QGroundControl-installer-AMD64-ARM64 80.36 MB
QGroundControl-installer-ARM64 109.24 MB
QGroundControl-linux 87.48 MB
QGroundControl-mac 87.48 MB
QGroundControl-x86_64 191.76 MB
No baseline available for comparison

Updated: 2026-07-31 02:53:08 UTC • Commit: 082bc25 • Triggered by: Android

@alireza787b
alireza787b force-pushed the agent/websocket-jpeg-video-source-v3 branch 3 times, most recently from 365a7e8 to 1b02cf9 Compare July 28, 2026 17:16
@codecov

codecov Bot commented Jul 28, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 32.70548% with 393 lines in your changes missing coverage. Please review.
✅ Project coverage is 32.70%. Comparing base (f29efd3) to head (082bc25).
⚠️ Report is 236 commits behind head on master.

Files with missing lines Patch % Lines
...VideoReceiver/GStreamer/QGCWebSocketVideoSource.cc 50.57% 41 Missing and 87 partials ⚠️
...anager/VideoReceiver/GStreamer/GstSourceFactory.cc 30.00% 34 Missing and 85 partials ⚠️
...anager/VideoReceiver/GStreamer/GstVideoReceiver.cc 0.00% 93 Missing ⚠️
src/Settings/VideoSettings.cc 19.44% 21 Missing and 8 partials ⚠️
src/VideoManager/VideoManager.cc 0.00% 19 Missing ⚠️
src/Camera/VehicleCameraControl.cc 0.00% 4 Missing ⚠️
...anager/VideoReceiver/GStreamer/GStreamerHelpers.cc 0.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master   #14731      +/-   ##
==========================================
+ Coverage   25.47%   32.70%   +7.23%     
==========================================
  Files         769      785      +16     
  Lines       65912    68063    +2151     
  Branches    30495    31556    +1061     
==========================================
+ Hits        16788    22261    +5473     
+ Misses      37285    30761    -6524     
- Partials    11839    15041    +3202     
Flag Coverage Δ
unittests 32.70% <32.70%> (+7.23%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/Settings/VideoSettings.h 100.00% <100.00%> (+85.71%) ⬆️
src/Utilities/Network/QGCNetworkHelper.h 0.00% <ø> (ø)
...Manager/VideoReceiver/GStreamer/GstVideoReceiver.h 0.00% <ø> (ø)
...anager/VideoReceiver/GStreamer/GStreamerHelpers.cc 38.65% <0.00%> (+1.96%) ⬆️
src/Camera/VehicleCameraControl.cc 9.52% <0.00%> (+7.77%) ⬆️
src/VideoManager/VideoManager.cc 7.83% <0.00%> (+5.93%) ⬆️
src/Settings/VideoSettings.cc 31.90% <19.44%> (+16.11%) ⬆️
...anager/VideoReceiver/GStreamer/GstVideoReceiver.cc 2.98% <0.00%> (+0.08%) ⬆️
...anager/VideoReceiver/GStreamer/GstSourceFactory.cc 30.90% <30.00%> (ø)
...VideoReceiver/GStreamer/QGCWebSocketVideoSource.cc 50.57% <50.57%> (ø)

... and 469 files with indirect coverage changes


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ed09a05...082bc25. Read the comment docs.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@alireza787b
alireza787b marked this pull request as ready for review July 28, 2026 18:56
@alireza787b
alireza787b requested a review from HTRamsey as a code owner July 28, 2026 18:56
@alireza787b

alireza787b commented Jul 28, 2026

Copy link
Copy Markdown
Contributor Author

@HTRamsey, this focused WS/WSS JPEG transport slice is ready for review at
cefd23dfb4a432bd5cb0dd7d25bc895a551648ea.

It is stacked directly on the HTTP MJPEG source in #14730. The incremental
delta is 17 files, with the production source accompanied by camera-free
delivery, malformed-input, WSS trust, failure propagation, and lifecycle
tests. The integrated candidate was also exercised on Linux, Windows, and
Android.

The exact head passed Linux release builds, 189 unit and 63 integration tests,
ASan/UBSan (189 unit and 46 integration tests), coverage thresholds, Windows,
Android, macOS, iOS, Custom Build, pre-commit, CodeQL, and both Codecov checks.
All eight Docker variants built successfully. Fedora then failed only in the
post-build Anchore step when the external Grype installer received an HTTP 302
for its GitHub release asset. I do not have permission to rerun an upstream
Actions job; a maintainer rerun of that single failed job would be appreciated.
The preceding production head passed the complete Docker matrix, and the only
subsequent change is the focused test polling correction.

This transport remains generic and unauthenticated. It does not add
PixEagle-specific behavior, Authorization headers, Origin configuration,
custom CAs, or secret persistence; those require a separate security design.

For clarity, the aggregate build comment labels pre-commit as “failed
(non-blocking)” while also reporting 0 passed, 0 failed, and 0 skipped. The
linked pre-commit workflow and its GitHub check both concluded success.
Likewise, both codecov/project and codecov/patch concluded success; their
check-run results are authoritative over the report comment icon.

@DonLakeFlyer DonLakeFlyer added this to the Release V5.2 milestone Jul 29, 2026
@alireza787b
alireza787b force-pushed the agent/websocket-jpeg-video-source-v3 branch from cefd23d to 4939a8f Compare July 31, 2026 01:26
@alireza787b
alireza787b force-pushed the agent/websocket-jpeg-video-source-v3 branch from 4939a8f to a686beb Compare July 31, 2026 01:39
@alireza787b
alireza787b force-pushed the agent/websocket-jpeg-video-source-v3 branch from a686beb to 924ad71 Compare July 31, 2026 01:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CMake Docs github_actions Pull requests that update GitHub Actions code size/XL Tests Video

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants