Preserve RRD preview frames and clarify onboard K1 status

This commit is contained in:
DCCONSTRUCTIONS
2026-09-07 15:27:13 +03:00
parent 67398fef10
commit 92b60de945
19 changed files with 516 additions and 94 deletions
+58 -5
View File
@@ -4,7 +4,7 @@ import queue
import pytest
from aiortc import RTCConfiguration, RTCPeerConnection, RTCSessionDescription
from k1link.viewer.node_media import NodeMediaPeers, admit_sdp
from k1link.viewer.node_media import MEDIA_PROTOCOL, NodeMediaPeers, admit_sdp
SDP_HEADER = "v=0\r\nm=application 9 UDP/DTLS/SCTP webrtc-datachannel\r\n"
@@ -51,7 +51,7 @@ def test_native_webrtc_roundtrip_and_missing_camera_preserve_rrd(monkeypatch):
class Subscription:
def __init__(self):
self.output = queue.Queue()
self.output.put(b"RRF2-transport-fixture")
self.output.put(payload)
def read(self):
try:
@@ -68,7 +68,16 @@ def test_native_webrtc_roundtrip_and_missing_camera_preserve_rrd(monkeypatch):
class Camera:
def snapshot(self):
return {"generation": None}
return {"generation": None, "phase": "error"}
# The old test's sub-16KB fake payload missed the actual fragmentation bug.
import numpy as np
import rerun as rr
recording = rr.RecordingStream("synthetic-node-media")
binary = recording.binary_stream()
recording.log("points", rr.Points3D(np.random.default_rng(42).random((5000, 3))))
payload = binary.read()
assert payload.startswith(b"RRF2") and len(payload) > 16384
async def run():
peers = NodeMediaPeers(Hub(), Camera())
@@ -82,7 +91,8 @@ def test_native_webrtc_roundtrip_and_missing_camera_preserve_rrd(monkeypatch):
@channel.on("message")
def message(data):
payloads.append(data)
received.set()
if len(payloads) > 1 and sum(map(len, payloads[1:])) == len(payload):
received.set()
try:
await client.setLocalDescription(await client.createOffer())
@@ -91,7 +101,10 @@ def test_native_webrtc_roundtrip_and_missing_camera_preserve_rrd(monkeypatch):
RTCSessionDescription(sdp=answer["sdp"], type="answer")
)
await asyncio.wait_for(received.wait(), timeout=8)
assert payloads == [b"RRF2-transport-fixture"]
assert answer["media_protocol"] == MEDIA_PROTOCOL
assert payloads[0] == b"MCF1" + len(payload).to_bytes(4, "big")
assert b"".join(payloads[1:]) == payload
assert all(len(part) <= 16384 for part in payloads[1:])
assert answer["peer_id"] in peers.items
assert channel.readyState == "open"
finally:
@@ -100,3 +113,43 @@ def test_native_webrtc_roundtrip_and_missing_camera_preserve_rrd(monkeypatch):
assert not peers.items
asyncio.run(run())
def test_camera_waits_for_post_calibration_producer_and_delivers_metadata():
class Camera:
calls = 0
opened = []
def snapshot(self):
self.calls += 1
return {"generation": None} if self.calls < 2 else {
"generation": 3, "delivery": {"media_type": "video/mp4"}}
def open_delivery(self, generation):
self.opened.append(generation)
return "lease"
class Channel:
messages = []
def send(self, data):
self.messages.append(data)
async def run():
camera, channel = Camera(), Channel()
peers = NodeMediaPeers(None, camera)
peers.items["synthetic"] = {}
assert await peers.camera_delivery("synthetic", channel) == "lease"
assert camera.opened == [3]
import json
assert json.loads(channel.messages[0]) == {"type": "camera-ready", "mime": "video/mp4"}
asyncio.run(run())
def test_installed_camera_uses_declared_os_ffmpeg():
from pathlib import Path
root = Path(__file__).resolve().parents[1]
unit = (root / "plugins/xgrids-k1/packaging/mission-core-k1.service").read_text()
assert "Environment=MISSIONCORE_FFMPEG_BINARY=/usr/bin/ffmpeg" in unit
assert "iproute2, ffmpeg" in (root / "plugins/xgrids-k1/packaging/build_deb.py").read_text()