Add Ground Station Streaming: hand video/telemetry ports to an external app - #125
Add Ground Station Streaming: hand video/telemetry ports to an external app#125mengelh wants to merge 1 commit into
Conversation
…al app PixelPilot's own WfbngLink::initAgg() already sends decrypted video (RTP/H264) and MAVLink to 127.0.0.1:5600/14550 unconditionally via wfb-ng's AggregatorUDPv4 -- but the app's own in-app video player and MAVLink OSD parser also bind those same ports, so nothing else on the device can. This adds a way to free them up for any other UDP-based ground station app (QGroundControl, Mission Planner, a custom OSD, ...) running on the same device, without touching devourer/wfb-ng at all. Two independent settings-menu toggles under "Ground Station Streaming", "Video" and "Telemetry" (a ground station app might only care about one channel -- e.g. a video-only OSD box, or a telemetry-only companion computer): - Video: stops/starts the in-app UDPReceiver + decoder on port 5600. - Telemetry: stops/starts the in-app MAVLink OSD parser on port 14550. Both apply immediately (no restart) by starting/stopping the relevant in-app consumer right away, and persist via SharedPreferences so they survive a restart. onPause()/onStop() now skip wfbLinkManager.stopAdapters() while either channel is streaming, since the whole point is for wfb-ng to keep forwarding while this Activity is backgrounded (e.g. the ground station app in the foreground instead) -- both channels share one USB/wfb-ng adapter, so it can't be paused for one channel while kept alive for the other. This only covers ordinary Activity lifecycle transitions, not memory-pressure eviction; a Foreground Service would be needed for guaranteed long-running background survival, which is out of scope here. Verified on-device (RTL8812AU, Galaxy Tab S7 FE) with QGroundControl: both video and telemetry arrive correctly with their respective toggle enabled; each toggle independently frees/rebinds only its own port; the USB/wfb-ng pipeline is never restarted by toggling or by backgrounding while streaming is active; background/foreground cycling with only one channel enabled still keeps the pipeline alive. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
PR Summary by QodoAdd ground station video and telemetry streaming controls
AI Description
Diagram
High-Level Assessment
Files changed (1)
|
Code Review by Qodo
1. Telemetry never returns in-app
|
| MavlinkNative.nativeStop(this); | ||
| handler.removeCallbacks(runnable); | ||
| } else { | ||
| MavlinkNative.nativeStart(this); | ||
| handler.post(runnable); |
There was a problem hiding this comment.
1. Telemetry never returns in-app 🐞 Bug ≡ Correctness
setTelemetryStreamingEnabled() calls nativeStop() and later nativeStart(), but the native stop signal is only incremented and is never reset before a replacement listener starts. Every enable-then-disable cycle therefore launches a listener that exits immediately, while a rapid cycle can additionally bind before the old socket releases port 14550.
Agent Prompt
## Issue description
Make the native MAVLink listener safely reusable so disabling ground-station telemetry reliably restores the in-app telemetry display.
## Issue Context
The new toggle stops and restarts the listener, but `nativeStop()` permanently increments a process-global signal and does not wait for the existing socket thread to finish. `nativeStart()` neither resets that signal nor synchronizes against the previous listener.
## Fix Focus Areas
- app/src/main/java/com/openipc/pixelpilot/VideoActivity.java[1236-1244]
- app/mavlink/src/main/cpp/mavlink.cpp[57-58]
- app/mavlink/src/main/cpp/mavlink.cpp[377-388]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| if (!isGroundStationStreamingActive()) { | ||
| wfbLinkManager.stopAdapters(); | ||
| } |
There was a problem hiding this comment.
2. Exiting leaves the radio pipeline running 🐞 Bug ☼ Reliability
The new lifecycle conditions skip stopAdapters() whenever either persisted streaming preference is enabled, but the activity has no destruction cleanup for the retained native link, USB connection, thread, or callback timer. Finishing or recreating the activity therefore leaves its old pipeline holding the adapter and activity context, and reopening constructs another link that attempts to use the same statically tracked device.
Agent Prompt
## Issue description
Preserve streaming during temporary background transitions without orphaning the USB and native pipeline when the activity is actually destroyed.
## Issue Context
The activity now skips adapter shutdown in both pause and stop, while `WfbNgLink` owns per-instance native state, threads, USB connections, and a timer retaining the activity. Add explicit terminal cleanup or move ownership into a lifecycle-appropriate service; distinguish ordinary backgrounding from finishing or recreation.
## Fix Focus Areas
- app/src/main/java/com/openipc/pixelpilot/VideoActivity.java[1660-1662]
- app/src/main/java/com/openipc/pixelpilot/VideoActivity.java[1676-1680]
- app/wfbngrtl8812/src/main/java/com/openipc/wfbngrtl8812/WfbNgLink.java[53-67]
- app/src/main/java/com/openipc/pixelpilot/WfbLinkManager.java[209-233]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
PixelPilot's own WfbngLink::initAgg() already sends decrypted video
(RTP/H264) and MAVLink to 127.0.0.1:5600/14550 unconditionally via
wfb-ng's AggregatorUDPv4 -- but the app's own in-app video player and
MAVLink OSD parser also bind those same ports, so nothing else on the
device can. This adds a way to free them up for any other UDP-based
ground station app (QGroundControl, Mission Planner, a custom OSD, ...)
running on the same device, without touching devourer/wfb-ng at all.
Two independent settings-menu toggles under "Ground Station Streaming",
"Video" and "Telemetry" (a ground station app might only care about
one channel -- e.g. a video-only OSD box, or a telemetry-only
companion computer):
Both apply immediately (no restart) by starting/stopping the relevant
in-app consumer right away, and persist via SharedPreferences so they
survive a restart.
onPause()/onStop() now skip wfbLinkManager.stopAdapters() while either
channel is streaming, since the whole point is for wfb-ng to keep
forwarding while this Activity is backgrounded (e.g. the ground station
app in the foreground instead) -- both channels share one USB/wfb-ng
adapter, so it can't be paused for one channel while kept alive for the
other. This only covers ordinary Activity lifecycle transitions, not
memory-pressure eviction; a Foreground Service would be needed for
guaranteed long-running background survival, which is out of scope
here.
Verified on-device (RTL8812AU, Galaxy Tab S7 FE) with QGroundControl:
both video and telemetry arrive correctly with their respective toggle
enabled; each toggle independently frees/rebinds only its own port;
the USB/wfb-ng pipeline is never restarted by toggling or by
backgrounding while streaming is active; background/foreground cycling
with only one channel enabled still keeps the pipeline alive.
🤖 Generated with Claude Code