Skip to content

Releases: OpenIPC/PixelPilot

v0.25.0

Choose a tag to compare

@github-actions github-actions released this 02 Sep 21:15
3d6ca17
Bound how long the packet queue holds a frame back (#120)

* Bound how long the packet queue holds a frame back

BufferedPacketQueue reorders the RTP stream before it reaches the parser. When a packet is
missing it holds everything behind the gap, which is right for a reorder and wrong for a loss
- and past wfb-ng, on a loopback socket, a gap is almost always a loss that FEC could not
recover. Three things made that wait longer than it needs to be.

The monotonic-increase escape hatch, which exists precisely to notice "the sequence numbers
keep climbing but the gap is not filling", never fires. calculateDistance(a, b) is how far b
is ahead of a - seqLessThan reads it that way - but the call site asks for the distance from
the incoming packet to the last delivered one. For a gap ahead of us that is negative, so the
else branch clears the counter on every single packet.

Fixing the argument order alone is not enough: the counter is only incremented while
abs(dist) < MONOTONIC_THRESHOLD, and dist grows by one with every packet held back. Compared
against the same constant that gates it, the counter tops out at three and can never reach
five. The gate is now its own constant, so a run past a gap releases the buffer after five
packets instead of never.

That leaves MAX_BUFFER_SIZE as the only bound, and how much latency fifteen packets is depends
entirely on the packet rate: about 20ms on a 1080p video stream, but roughly 300ms on the
audio stream, which runs at a fraction of it. The buffer is now also bounded in time, so the
worst case is the same on both. Twenty milliseconds is a little over one frame at 60fps and
several orders of magnitude more than a loopback socket needs to reorder anything.

Nothing is dropped by any of this - the buffered packets are still delivered, just without
waiting on one that is not coming.

The test target could not be built on a case-sensitive filesystem, since CMakeLists.txt
spelled the source BufferedPacketqueue_test.cpp. The existing two cases both turn out to feed
a strictly in-order stream, so neither reached the buffer at all; the new ones cover a
permanent gap, the age bound, a reorder that resolves inside it, and a jump too large to be
one. They drive the clock themselves rather than reading it, so the age bound cannot make them
flaky on a loaded machine.

* Advance the queue past everything a flush delivered

Two problems with the flush, both found in review.

restartBuffering() set mLastPacketIdx to the packet that triggered the flush rather than the
newest one delivered. With 1..5 delivered, 6 lost, then 7 8 9 12 10, the flush hands over
7 8 9 10 12 but leaves the pointer on 10 - so 11 would be delivered after 12, and 13..16 are
held until 17 arrives. The queue re-created the stall it exists to prevent. bufferPacket()
always runs before the flush, so the triggering packet is in the buffer either way and
mLastPacketIdx = drainBufferInOrder() is all that was needed; restartBuffering() is gone.

That alone would have broken the resync on a large jump, because drainBufferInOrder() seeded
`highest` from mLastPacketIdx and compared with calculateDistance(), which reads as negative
past half the sequence space. RTP starts at a random sequence number, so a VTX that reboots
mid-session lands exactly there: fed 1, 2, then 40000, 40001, ..., neither the seed nor the
comparison ever moves and every packet comes out one flush late, forever. On video the
fifteen-packet cap used to paper over it by rewinding to currPacketIdx; on audio nothing did.
`highest` is now seeded from a packet that is actually in the buffer.

While sorting the flush: by raw value a block straddling the wrap point (65534, 65535, 0, 1)
sorts to 0, 1, 65534, 65535 and was handed to the parser in that order. Sorting by distance
from the last delivered packet fixes the order and makes the last element the newest.

Three tests added, one per problem. The large-jump case uses 40000 - the existing
LargeJumpFallsBackToTheBufferCap uses 30000, which is still positive as an int16 and does not
reach any of this.

v0.24.0

Choose a tag to compare

@github-actions github-actions released this 02 Sep 19:09
adc9ee5
Feat: Add Real-time Object Detection with MediaPipe (#108)

* feat(detection): add real-time object detection using Google MediaPipe

- Replace main SurfaceView with TextureView to support capturing frame Bitmaps via getBitmap().
- Add ObjectDetectorHelper to encapsulate MediaPipe Object Detector Task API with CPU/GPU delegates.
- Create OverlayView for scaling and rendering bounding boxes and classification labels onto standard video stream.
- Integrate background detection thread execution loop (~10 FPS) in VideoActivity with lifecycle management.
- Set up automated downloads for EfficientDet-Lite0 and EfficientDet-Lite2 model assets in app/build.gradle.
- Add user menu toggles for object detection settings, persisting config values via SharedPreferences.
- Update README.md with detailed instructions for the object detection feature.

Reference: https://github.com/google-ai-edge/mediapipe-samples/tree/main/examples/object_detection

* Optimize size

- Removed tflite file from apk;
- Optimize MediaPipe size (Keep arm64, remove 32bit support);
- Compress releasefile

Final apk 9.4MB :app-release_object_detection.apk

Test build — MediaTek no-video fix (issue #6)

Choose a tag to compare

@josephnef josephnef released this 20 Jul 11:37

Unofficial test build for #6 (no video on MediaTek devices).

Contains the devourer 16 KB RX URB fix (OpenIPC/devourer#317) + heap RX ring, built from branch restore-mtk-16k-fix (PR #107) at commit 609110e. Not an official release — for validation on affected MediaTek devices (Dimensity 810, Helio G99, MT6765) before the PR is merged.

Built by GitHub Actions from the PR branch. Reproduce: check out PR #107.

v0.23.1

Choose a tag to compare

@github-actions github-actions released this 08 Aug 20:21
Actually enable SIMD FEC

v0.23.0

Choose a tag to compare

@github-actions github-actions released this 08 Aug 18:48

v0.22.0

Choose a tag to compare

@github-actions github-actions released this 27 Jul 15:49

This release fixes compatibility issue with Bonnet device

v0.21.0

Choose a tag to compare

@github-actions github-actions released this 08 Jun 22:09

v0.9.0

Choose a tag to compare

@github-actions github-actions released this 27 May 20:36
333ef5b
Fix FEC calculation for 0 FEC, initialise FEC properly (#71)

v0.8.1

Choose a tag to compare

@github-actions github-actions released this 24 May 15:04
Format sources

v0.8.0

Choose a tag to compare

@github-actions github-actions released this 19 May 21:35
c7936de
Stop VPN service when minimized (#70)