mici fallback too

This commit is contained in:
firestar5683
2026-07-22 14:16:16 -05:00
parent 6230d08c0f
commit d16d72afc6
2 changed files with 40 additions and 8 deletions
+29 -2
View File
@@ -128,6 +128,8 @@ class CameraView(Widget):
self._enhance_driver_val = rl.ffi.new("int[1]", [1 if stream_type == VisionStreamType.VISION_STREAM_DRIVER else 0])
self.frame: VisionBuf | None = None
self._last_frame_id = -1
self._regressive_frame_count = 0
self.texture_y: rl.Texture | None = None
self.texture_uv: rl.Texture | None = None
@@ -160,6 +162,7 @@ class CameraView(Widget):
# camerad allocation until this view happens to render again.
self._clear_textures()
self.frame = None
self._last_frame_id = -1
self.available_streams.clear()
self.client = VisionIpcClient(self._name, self._stream_type, conflate=True)
self._target_client = None
@@ -209,6 +212,7 @@ class CameraView(Widget):
self.shader.id = 0
self.frame = None
self._last_frame_id = -1
self.available_streams.clear()
self.client = None
self._target_client = None
@@ -242,11 +246,13 @@ class CameraView(Widget):
self._draw_placeholder(rect)
return
if self._use_egl:
self._observe_displayed_frame()
# Try to get a new buffer without blocking
buffer = self.client.recv(timeout_ms=0)
if buffer:
self._texture_needs_update = True
self.frame = buffer
self._accept_frame(buffer, self.client.frame_id)
elif not self.client.is_connected():
# ensure we clear the displayed frame when the connection is lost
self.frame = None
@@ -284,6 +290,25 @@ class CameraView(Widget):
if self._placeholder_color:
rl.draw_rectangle_rec(rect, self._placeholder_color)
def _observe_displayed_frame(self) -> None:
if self.frame is not None:
self._last_frame_id = max(self._last_frame_id, int(self.frame.frame_id))
def _accept_frame(self, frame: VisionBuf, packet_frame_id: int) -> bool:
content_frame_id = int(frame.frame_id)
if content_frame_id < self._last_frame_id:
self._regressive_frame_count += 1
if self._regressive_frame_count == 1 or self._regressive_frame_count % 100 == 0:
message = f"Dropping regressive {self._name} frame: content={content_frame_id}, packet={packet_frame_id}, "
message += f"displayed={self._last_frame_id}, idx={frame.idx}, count={self._regressive_frame_count}"
cloudlog.warning(message)
return False
self.frame = frame
self._last_frame_id = content_frame_id
self._texture_needs_update = True
return True
def _render_egl(self, src_rect: rl.Rectangle, dst_rect: rl.Rectangle) -> None:
"""Render using EGL for direct buffer access"""
if self.frame is None or self.egl_texture is None:
@@ -344,6 +369,7 @@ class CameraView(Widget):
def _ensure_connection(self) -> bool:
if not self.client.is_connected():
self.frame = None
self._last_frame_id = -1
self.available_streams.clear()
# Throttle connection attempts
@@ -392,6 +418,7 @@ class CameraView(Widget):
# Switch to target
self.client = self._target_client
self._stream_type = self._target_stream_type
self._last_frame_id = int(self.frame.frame_id) if self.frame is not None else -1
self._texture_needs_update = True
# Reset state
+11 -6
View File
@@ -1,4 +1,7 @@
from openpilot.selfdrive.ui.onroad import cameraview
import pytest
from openpilot.selfdrive.ui.mici.onroad import cameraview as mici_cameraview
from openpilot.selfdrive.ui.onroad import cameraview as big_cameraview
class FakeFrame:
@@ -7,7 +10,7 @@ class FakeFrame:
self.idx = idx
def _camera_view():
def _camera_view(cameraview):
view = cameraview.CameraView.__new__(cameraview.CameraView)
view._name = "camerad"
view.frame = None
@@ -18,9 +21,10 @@ def _camera_view():
return view
def test_reused_egl_slot_cannot_move_camera_backwards(monkeypatch):
@pytest.mark.parametrize("cameraview", [big_cameraview, mici_cameraview])
def test_reused_egl_slot_cannot_move_camera_backwards(monkeypatch, cameraview):
monkeypatch.setattr(cameraview.cloudlog, "warning", lambda *_args, **_kwargs: None)
view = _camera_view()
view = _camera_view(cameraview)
displayed = FakeFrame(frame_id=10, idx=0)
assert view._accept_frame(displayed, packet_frame_id=10)
@@ -36,8 +40,9 @@ def test_reused_egl_slot_cannot_move_camera_backwards(monkeypatch):
assert view._regressive_frame_count == 1
def test_newer_camera_frame_is_accepted():
view = _camera_view()
@pytest.mark.parametrize("cameraview", [big_cameraview, mici_cameraview])
def test_newer_camera_frame_is_accepted(cameraview):
view = _camera_view(cameraview)
view._last_frame_id = 30
newer = FakeFrame(frame_id=31, idx=2)