forked from mainsail-crew/spyglass
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_camera_configure.py
More file actions
130 lines (97 loc) · 3.94 KB
/
Copy pathtest_camera_configure.py
File metadata and controls
130 lines (97 loc) · 3.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import sys
from unittest.mock import MagicMock
AF_MODE_ENUM_MANUAL = 3
AF_SPEED_ENUM_NORMAL = 1
mock_libcamera = MagicMock()
mock_picamera2 = MagicMock()
mock_picamera2.encoders._hw_encoder_available = False
mock_picamera2.outputs.Output = MagicMock
sys.modules.update(
{
"libcamera": mock_libcamera,
"picamera2": mock_picamera2,
"picamera2.encoders": mock_picamera2.encoders,
"picamera2.outputs": mock_picamera2.outputs,
}
)
mock_libcamera.controls.AfModeEnum.Manual = AF_MODE_ENUM_MANUAL
mock_libcamera.controls.AfSpeedEnum.Normal = AF_SPEED_ENUM_NORMAL
mock_libcamera.StreamRole.VideoRecording = object()
def _make_picam2(supported_formats=None, enumerate_raises=None):
"""Build a mocked Picamera2 whose libcamera-level
``camera.generate_configuration(...)`` reports the given pixel formats."""
picam2 = MagicMock()
picam2.camera_controls = {}
picam2.create_video_configuration.side_effect = lambda **kw: dict(kw)
if enumerate_raises is not None:
picam2.camera.generate_configuration.side_effect = enumerate_raises
else:
formats = MagicMock()
formats.pixel_formats = [_PixFmt(name) for name in (supported_formats or [])]
stream_cfg = MagicMock()
stream_cfg.formats = formats
libcam_cfg = MagicMock()
libcam_cfg.at.return_value = stream_cfg
picam2.camera.generate_configuration.return_value = libcam_cfg
return picam2
class _PixFmt:
"""Stand-in for a libcamera.PixelFormat — only its ``str()`` matters."""
def __init__(self, name: str):
self._name = name
def __str__(self) -> str:
return self._name
def _run_configure(cam):
cam.configure(
width=1920,
height=1080,
fps=30,
autofocus=AF_MODE_ENUM_MANUAL,
lens_position=0.0,
autofocus_speed=AF_SPEED_ENUM_NORMAL,
)
def test_csi_picks_yuv420_when_supported():
from spyglass.camera.csi import CSI
picam2 = _make_picam2(
supported_formats=["YUV420", "XBGR8888", "BGR888", "NV12", "RGB565"]
)
cam = CSI(picam2)
_run_configure(cam)
main = picam2.create_video_configuration.call_args.kwargs["main"]
assert main == {"size": (1920, 1080), "format": "YUV420"}
picam2.configure.assert_called_once()
def test_csi_falls_through_preference_when_yuv420_missing():
from spyglass.camera.csi import CSI
picam2 = _make_picam2(supported_formats=["XBGR8888", "BGR888", "RGB565"])
cam = CSI(picam2)
_run_configure(cam)
main = picam2.create_video_configuration.call_args.kwargs["main"]
assert main == {"size": (1920, 1080), "format": "BGR888"}
def test_csi_omits_format_when_no_encoder_compatible_supported():
from spyglass.camera.csi import CSI
picam2 = _make_picam2(supported_formats=["NV12", "NV21", "RGB565", "YUYV"])
cam = CSI(picam2)
_run_configure(cam)
main = picam2.create_video_configuration.call_args.kwargs["main"]
assert "format" not in main
assert main == {"size": (1920, 1080)}
def test_csi_omits_format_when_enumeration_fails():
from spyglass.camera.csi import CSI
picam2 = _make_picam2(enumerate_raises=RuntimeError("camera not yet acquired"))
cam = CSI(picam2)
_run_configure(cam)
main = picam2.create_video_configuration.call_args.kwargs["main"]
assert "format" not in main
def test_base_camera_does_not_query_libcamera_formats():
"""Subclasses other than CSI (e.g. USB) should not auto-pick a format."""
from spyglass.camera.camera import Camera
class _StubCamera(Camera):
def start_and_run_server(self, *args, **kwargs):
raise NotImplementedError
def stop(self):
raise NotImplementedError
picam2 = _make_picam2(supported_formats=["YUV420"])
cam = _StubCamera(picam2)
_run_configure(cam)
picam2.camera.generate_configuration.assert_not_called()
main = picam2.create_video_configuration.call_args.kwargs["main"]
assert "format" not in main