Admit onboard camera preview only after its acquisition producer is ready
This commit is contained in:
@@ -970,7 +970,9 @@ class XgridsK1CameraGateway:
|
||||
)
|
||||
return self.snapshot()
|
||||
|
||||
def open_delivery(self, generation: int) -> CameraProcessLease:
|
||||
def open_delivery(
|
||||
self, generation: int, *, require_recording: bool = False
|
||||
) -> CameraProcessLease:
|
||||
with self._lifecycle_lock:
|
||||
with self._lock:
|
||||
self._require_open_locked()
|
||||
@@ -978,6 +980,8 @@ class XgridsK1CameraGateway:
|
||||
raise ValueError("camera preview generation не активно")
|
||||
producer = self._producer
|
||||
recording_active = self._recording_root is not None
|
||||
if require_recording and (not recording_active or producer is None):
|
||||
raise RuntimeError("camera acquisition producer is not ready")
|
||||
if producer is None:
|
||||
# An acquisition owns its producer lifecycle. Once an epoch is
|
||||
# sealed, a disposable browser reconnect must not resurrect the
|
||||
|
||||
@@ -133,8 +133,23 @@ class NodeMediaPeers:
|
||||
while identifier in self.items and time.monotonic() < deadline:
|
||||
state = self.camera.snapshot()
|
||||
delivery = state.get("delivery") or {}
|
||||
if state.get("generation") is not None and delivery.get("media_type"):
|
||||
lease = await asyncio.to_thread(self.camera.open_delivery, state["generation"])
|
||||
recording = state.get("recording") or {}
|
||||
if recording.get("source_end_expected"):
|
||||
break
|
||||
if (state.get("generation") is not None and delivery.get("media_type")
|
||||
and recording.get("active") is True
|
||||
and recording.get("producer_alive") is True
|
||||
and recording.get("media_ready") is True
|
||||
and recording.get("active_epoch") == state["generation"]):
|
||||
try:
|
||||
lease = await asyncio.to_thread(
|
||||
self.camera.open_delivery, state["generation"], require_recording=True
|
||||
)
|
||||
except (ValueError, RuntimeError):
|
||||
# The acquisition owner may replace an epoch between this
|
||||
# snapshot and lease admission. Observe its next ready epoch.
|
||||
await asyncio.sleep(0.25)
|
||||
continue
|
||||
try:
|
||||
channel.send(json.dumps({
|
||||
"type": "camera-ready", "mime": delivery["media_type"],
|
||||
@@ -143,8 +158,6 @@ class NodeMediaPeers:
|
||||
self.camera.release_delivery(lease, client_closed=True)
|
||||
raise
|
||||
return lease
|
||||
if state.get("phase") == "error":
|
||||
break
|
||||
await asyncio.sleep(0.25)
|
||||
return None
|
||||
|
||||
|
||||
Reference in New Issue
Block a user