UI: cache camera clients (#39166)

This commit is contained in:
Adeeb Shihadeh
2026-11-02 06:48:19 +00:00
committed by firestar5683
parent 77cf37119c
commit 5808a49a52
+12 -18
View File
@@ -88,8 +88,9 @@ class CameraView(Widget):
def __init__(self, name: str, stream_type: VisionStreamType):
super().__init__()
self._name = name
# Primary stream
self.client = VisionIpcClient(name, stream_type, conflate=True)
# Reuse subscribers: destroying a VisionIpcClient doesn't reclaim its msgq reader slot.
self._clients = {stream: VisionIpcClient(name, stream, conflate=True) for stream in VisionStreamType}
self.client = self._clients[stream_type]
self._stream_type: VisionStreamType = stream_type
self.available_streams: list[VisionStreamType] = []
@@ -130,16 +131,14 @@ class CameraView(Widget):
ui_state.add_offroad_transition_callback(self._offroad_transition)
def _offroad_transition(self):
# Reconnect if not first time going onroad
# Discard queued frames from the previous drive without recreating subscribers.
if ui_state.is_onroad() and self.frame is not None:
# Prevent old frames from showing when going onroad. Qt has a separate thread
# which drains the VisionIpcClient SubSocket for us. Re-connecting is not enough
# and only clears internal buffers, not the message queue.
self.frame = None
self.available_streams.clear()
if self.client:
del self.client
self.client = VisionIpcClient(self._name, self._stream_type, conflate=True)
for client in self._clients.values():
client.recv(timeout_ms=0)
self._target_client = None
self._target_stream_type = None
self._switching = False
def _set_placeholder_color(self, color: rl.Color):
"""Set a placeholder color to be drawn when no frame is available."""
@@ -154,11 +153,8 @@ class CameraView(Widget):
cloudlog.debug(f'Preparing switch from {self._stream_type} to {stream_type}')
if self._target_client:
del self._target_client
self._target_stream_type = stream_type
self._target_client = VisionIpcClient(self._name, stream_type, conflate=True)
self._target_client = self._clients[stream_type]
self._switching = True
@property
@@ -181,6 +177,8 @@ class CameraView(Widget):
self.frame = None
self.available_streams.clear()
self.client = None
self._target_client = None
self._clients.clear()
def __del__(self):
self.close()
@@ -350,10 +348,6 @@ class CameraView(Widget):
def _complete_switch(self) -> None:
"""Instantly switch to target stream."""
cloudlog.debug(f"Switching to {self._target_stream_type}")
# Clean up current resources
if self.client:
del self.client
# Switch to target
assert self._target_client is not None and self._target_stream_type is not None
self.client = self._target_client