pyobs-aravis 2.0.0.dev8__tar.gz → 2.0.0.dev9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyobs_aravis-2.0.0.dev8 → pyobs_aravis-2.0.0.dev9}/PKG-INFO +1 -1
- {pyobs_aravis-2.0.0.dev8 → pyobs_aravis-2.0.0.dev9}/pyobs_aravis/araviscamera.py +41 -4
- {pyobs_aravis-2.0.0.dev8 → pyobs_aravis-2.0.0.dev9}/pyproject.toml +1 -1
- {pyobs_aravis-2.0.0.dev8 → pyobs_aravis-2.0.0.dev9}/uv.lock +1 -1
- {pyobs_aravis-2.0.0.dev8 → pyobs_aravis-2.0.0.dev9}/.github/workflows/pypi.yml +0 -0
- {pyobs_aravis-2.0.0.dev8 → pyobs_aravis-2.0.0.dev9}/.github/workflows/ruff.yml +0 -0
- {pyobs_aravis-2.0.0.dev8 → pyobs_aravis-2.0.0.dev9}/.pre-commit-config.yaml +0 -0
- {pyobs_aravis-2.0.0.dev8 → pyobs_aravis-2.0.0.dev9}/.readthedocs.yml +0 -0
- {pyobs_aravis-2.0.0.dev8 → pyobs_aravis-2.0.0.dev9}/CHANGELOG.rst +0 -0
- {pyobs_aravis-2.0.0.dev8 → pyobs_aravis-2.0.0.dev9}/LICENSE +0 -0
- {pyobs_aravis-2.0.0.dev8 → pyobs_aravis-2.0.0.dev9}/README.md +0 -0
- {pyobs_aravis-2.0.0.dev8 → pyobs_aravis-2.0.0.dev9}/docs/Makefile +0 -0
- {pyobs_aravis-2.0.0.dev8 → pyobs_aravis-2.0.0.dev9}/docs/make.bat +0 -0
- {pyobs_aravis-2.0.0.dev8 → pyobs_aravis-2.0.0.dev9}/docs/requirements.txt +0 -0
- {pyobs_aravis-2.0.0.dev8 → pyobs_aravis-2.0.0.dev9}/docs/source/_static/pyobs.gif +0 -0
- {pyobs_aravis-2.0.0.dev8 → pyobs_aravis-2.0.0.dev9}/docs/source/conf.py +0 -0
- {pyobs_aravis-2.0.0.dev8 → pyobs_aravis-2.0.0.dev9}/docs/source/index.rst +0 -0
- {pyobs_aravis-2.0.0.dev8 → pyobs_aravis-2.0.0.dev9}/pyobs_aravis/__init__.py +0 -0
- {pyobs_aravis-2.0.0.dev8 → pyobs_aravis-2.0.0.dev9}/pyobs_aravis/aravis.py +0 -0
- {pyobs_aravis-2.0.0.dev8 → pyobs_aravis-2.0.0.dev9}/pyobs_aravis/gui.py +0 -0
|
@@ -16,6 +16,11 @@ log = logging.getLogger(__name__)
|
|
|
16
16
|
# rather than let a single dead camera freeze the whole module.
|
|
17
17
|
_SDK_CALL_TIMEOUT = 5.0
|
|
18
18
|
|
|
19
|
+
# pop_frame() is polled from _capture() and is expected to legitimately take a while (up to the
|
|
20
|
+
# camera's own frame interval/exposure time), unlike the other SDK calls above -- a much more
|
|
21
|
+
# generous timeout than _SDK_CALL_TIMEOUT, so normal operation never trips it.
|
|
22
|
+
_FRAME_WAIT_TIMEOUT = 30.0
|
|
23
|
+
|
|
19
24
|
|
|
20
25
|
class AravisCamera(BaseVideo, IExposureTime):
|
|
21
26
|
"""A pyobs module for Aravis cameras."""
|
|
@@ -153,10 +158,10 @@ class AravisCamera(BaseVideo, IExposureTime):
|
|
|
153
158
|
await asyncio.sleep(0.1)
|
|
154
159
|
continue
|
|
155
160
|
|
|
156
|
-
frame
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
161
|
+
frame = await self._wait_for_frame()
|
|
162
|
+
if frame is None:
|
|
163
|
+
# camera went away, or the wait timed out -- back off and retry
|
|
164
|
+
continue
|
|
160
165
|
|
|
161
166
|
if time.time() - last < self._interval:
|
|
162
167
|
await asyncio.sleep(0.01)
|
|
@@ -168,6 +173,38 @@ class AravisCamera(BaseVideo, IExposureTime):
|
|
|
168
173
|
except Exception:
|
|
169
174
|
await asyncio.sleep(1)
|
|
170
175
|
|
|
176
|
+
async def _wait_for_frame(self, timeout: float = _FRAME_WAIT_TIMEOUT) -> npt.NDArray[Any] | None:
|
|
177
|
+
"""Waits for the next frame without blocking the event loop.
|
|
178
|
+
|
|
179
|
+
Polls pop_frame() from a background thread (see _run_blocking) rather than polling it
|
|
180
|
+
directly from the async loop with a sleep in between each attempt -- pop_frame() is
|
|
181
|
+
assumed non-blocking in the common case, but if the underlying aravis/GLib call ever
|
|
182
|
+
doesn't honor that (camera hiccup, network stall for GigE Vision), polling it directly
|
|
183
|
+
would freeze the whole module for as long as that lasts, repeatedly, for the module's
|
|
184
|
+
entire runtime. Runs the whole "poll until ready" loop as a single blocking call instead,
|
|
185
|
+
so only one thread gets spawned per delivered frame rather than one per 10ms poll.
|
|
186
|
+
|
|
187
|
+
Returns:
|
|
188
|
+
The next frame, or None if the camera disappeared mid-wait or the wait timed out.
|
|
189
|
+
"""
|
|
190
|
+
result: list[npt.NDArray[Any]] = []
|
|
191
|
+
|
|
192
|
+
def _poll() -> None:
|
|
193
|
+
camera = self._camera
|
|
194
|
+
while camera is not None:
|
|
195
|
+
frame = camera.pop_frame() # type: ignore[union-attr]
|
|
196
|
+
# pop_frame() can return a non-None array that's empty along axis 0 instead of
|
|
197
|
+
# None -- treat that the same as "not ready yet" rather than a real frame
|
|
198
|
+
if frame is not None and frame.size != 0: # type: ignore[union-attr]
|
|
199
|
+
result.append(frame) # type: ignore[arg-type]
|
|
200
|
+
return
|
|
201
|
+
time.sleep(0.01)
|
|
202
|
+
|
|
203
|
+
if not await self._run_blocking(_poll, timeout=timeout):
|
|
204
|
+
log.error("Timed out waiting for a frame after %.1fs.", timeout)
|
|
205
|
+
return None
|
|
206
|
+
return result[0] if result else None
|
|
207
|
+
|
|
171
208
|
async def set_exposure_time(self, exposure_time: float, **kwargs: Any) -> None:
|
|
172
209
|
"""Set the exposure time in seconds.
|
|
173
210
|
|
|
@@ -1770,7 +1770,7 @@ wheels = [
|
|
|
1770
1770
|
|
|
1771
1771
|
[[package]]
|
|
1772
1772
|
name = "pyobs-aravis"
|
|
1773
|
-
version = "2.0.0.
|
|
1773
|
+
version = "2.0.0.dev9"
|
|
1774
1774
|
source = { editable = "." }
|
|
1775
1775
|
dependencies = [
|
|
1776
1776
|
{ name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" },
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|