Skip to content

Commit ee6669e

Browse files
committed
Fix use of MappedArray with LibcameraAllocator
This was broken by commit c0cc32c ("Always sync buffers as writeable ..."). But of course LibcameraAllocator is only a legacy thing now, so you really shouldn't be using it. Although the code here is now behaving as it did previously, it is rather unoptimised in that every MappedArray will do another mmap which could probably be avoided. But you won't get the LibcameraAllocator by default, and as stated, there is no reason to request one - so it doesn't seem worth the trouble of doing anything about it. Signed-off-by: David Plowman <[email protected]>
1 parent 7aac246 commit ee6669e

File tree

4 files changed

+24
-3
lines changed

4 files changed

+24
-3
lines changed

picamera2/allocators/allocator.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
class Allocator:
22
"""Base class for allocators"""
33

4+
# Most allocators shouldn't need to "sync" buffers every time you access them.
5+
needs_sync = False
6+
47
def __init__(self):
58
self.sync = Sync
69

picamera2/allocators/libcameraallocator.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
class LibcameraAllocator(Allocator):
1111
"""Uses the libcamera FrameBufferAllocator"""
1212

13+
# This legacy allocator does require a sync, but of course you shouldn't be using it.
14+
needs_sync = True
15+
1316
def __init__(self, camera):
1417
super().__init__()
1518
self.camera = camera

picamera2/request.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,25 @@ def __init__(self, request: "CompletedRequest", stream: str, write: bool = True)
3434
assert request.request is not None
3535
self.__fb = request.request.buffers[stream]
3636
self.__allocator = request.picam2.allocator
37+
self.__sync = None
38+
if self.__allocator.needs_sync:
39+
# This is just for legacy LibcameraAllocator, which you shouldn't really use.
40+
self.__sync = self.__allocator.sync(self.__allocator, self.__fb, write)
3741

3842
def __enter__(self) -> Any:
39-
self.__mm = self.__allocator.mapped_buffers.get(self.__fb, None)
43+
if self.__sync:
44+
# For legacy LibcameraAllocator, which you shouldn't be using.
45+
self.__mm = self.__sync.__enter__()
46+
else:
47+
self.__mm = self.__allocator.mapped_buffers.get(self.__fb, None)
4048
if self.__mm is None:
4149
raise RuntimeError("failed to find buffer")
4250
return self.__mm
4351

4452
def __exit__(self, exc_type: Any, exc_value: Any, exc_traceback: Any) -> None:
45-
pass
53+
if self.__sync:
54+
# For legacy LibcameraAllocator, which you shouldn't be using.
55+
self.__sync.__exit__(exc_type, exc_value, exc_traceback)
4656

4757

4858
class MappedArray:

tests/allocator_test.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import time
66

7-
from picamera2 import Picamera2, Preview
7+
from picamera2 import MappedArray, Picamera2, Preview
88
from picamera2.allocators import LibcameraAllocator
99

1010
picam2 = Picamera2()
@@ -17,6 +17,11 @@
1717
picam2.start()
1818
time.sleep(2)
1919

20+
# Check that MappedArray still works!
21+
with picam2.captured_request() as request:
22+
with MappedArray(request, 'main') as m:
23+
pass
24+
2025
size = picam2.sensor_resolution
2126
# GPU won't digest images wider than 4096 on a Pi 4.
2227
if size[0] > 4096:

0 commit comments

Comments
 (0)