summaryrefslogtreecommitdiff
path: root/src/py
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ideasonboard.com>2022-05-27 17:44:24 +0300
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2022-05-27 22:02:41 +0300
commit9e4388cca5d9ecd6152c0d5990038b515b5f918c (patch)
tree433360a1efce3c8a22eef4efeeea590894c7581c /src/py
parent210ce547a42ca559592efaef069648ddfe0d2945 (diff)
py: Move MappedFrameBuffer to libcamera.utils
Move MappedFrameBuffer to libcamera.utils, instead of extending FrameBuffer class with a new mmap() method. This keeps us more aligned to the C++ API. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'src/py')
-rwxr-xr-xsrc/py/cam/cam.py5
-rw-r--r--src/py/cam/cam_qt.py3
-rw-r--r--src/py/libcamera/__init__.py80
-rw-r--r--src/py/libcamera/meson.build4
-rw-r--r--src/py/libcamera/utils/MappedFrameBuffer.py74
-rw-r--r--src/py/libcamera/utils/__init__.py4
6 files changed, 87 insertions, 83 deletions
diff --git a/src/py/cam/cam.py b/src/py/cam/cam.py
index 66df18bf..64f67e86 100755
--- a/src/py/cam/cam.py
+++ b/src/py/cam/cam.py
@@ -9,6 +9,7 @@
import argparse
import binascii
import libcamera as libcam
+import libcamera.utils
import sys
import traceback
@@ -327,7 +328,7 @@ def request_handler(state, ctx, req):
crcs = []
if ctx['opt-crc']:
- with fb.mmap() as mfb:
+ with libcamera.utils.MappedFrameBuffer(fb) as mfb:
plane_crcs = [binascii.crc32(p) for p in mfb.planes]
crcs.append(plane_crcs)
@@ -345,7 +346,7 @@ def request_handler(state, ctx, req):
print(f'\t{ctrl} = {val}')
if ctx['opt-save-frames']:
- with fb.mmap() as mfb:
+ with libcamera.utils.MappedFrameBuffer(fb) as mfb:
filename = 'frame-{}-{}-{}.data'.format(ctx['id'], stream_name, ctx['reqs-completed'])
with open(filename, 'wb') as f:
for p in mfb.planes:
diff --git a/src/py/cam/cam_qt.py b/src/py/cam/cam_qt.py
index bff1175b..70bdb7bb 100644
--- a/src/py/cam/cam_qt.py
+++ b/src/py/cam/cam_qt.py
@@ -9,6 +9,7 @@ from PIL import Image
from PIL.ImageQt import ImageQt
from PyQt5 import QtCore, QtGui, QtWidgets
import libcamera as libcam
+import libcamera.utils
import numpy as np
import sys
@@ -285,7 +286,7 @@ class MainWindow(QtWidgets.QWidget):
controlsLayout.addStretch()
def buf_to_qpixmap(self, stream, fb):
- with fb.mmap() as mfb:
+ with libcamera.utils.MappedFrameBuffer(fb) as mfb:
cfg = stream.configuration
if cfg.pixel_format == libcam.formats.MJPEG:
diff --git a/src/py/libcamera/__init__.py b/src/py/libcamera/__init__.py
index 0d7da9e2..e234a5e4 100644
--- a/src/py/libcamera/__init__.py
+++ b/src/py/libcamera/__init__.py
@@ -2,83 +2,3 @@
# Copyright (C) 2022, Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
from ._libcamera import *
-
-
-class MappedFrameBuffer:
- def __init__(self, fb):
- self.__fb = fb
-
- def __enter__(self):
- import os
- import mmap
-
- fb = self.__fb
-
- # Collect information about the buffers
-
- bufinfos = {}
-
- for i in range(fb.num_planes):
- fd = fb.fd(i)
-
- if fd not in bufinfos:
- buflen = os.lseek(fd, 0, os.SEEK_END)
- bufinfos[fd] = {'maplen': 0, 'buflen': buflen}
- else:
- buflen = bufinfos[fd]['buflen']
-
- if fb.offset(i) > buflen or fb.offset(i) + fb.length(i) > buflen:
- raise RuntimeError(f'plane is out of buffer: buffer length={buflen}, ' +
- f'plane offset={fb.offset(i)}, plane length={fb.length(i)}')
-
- bufinfos[fd]['maplen'] = max(bufinfos[fd]['maplen'], fb.offset(i) + fb.length(i))
-
- # mmap the buffers
-
- maps = []
-
- for fd, info in bufinfos.items():
- map = mmap.mmap(fd, info['maplen'], mmap.MAP_SHARED, mmap.PROT_READ | mmap.PROT_WRITE)
- info['map'] = map
- maps.append(map)
-
- self.__maps = tuple(maps)
-
- # Create memoryviews for the planes
-
- planes = []
-
- for i in range(fb.num_planes):
- fd = fb.fd(i)
- info = bufinfos[fd]
-
- mv = memoryview(info['map'])
-
- start = fb.offset(i)
- end = fb.offset(i) + fb.length(i)
-
- mv = mv[start:end]
-
- planes.append(mv)
-
- self.__planes = tuple(planes)
-
- return self
-
- def __exit__(self, exc_type, exc_value, exc_traceback):
- for p in self.__planes:
- p.release()
-
- for mm in self.__maps:
- mm.close()
-
- @property
- def planes(self):
- return self.__planes
-
-
-def __FrameBuffer__mmap(self):
- return MappedFrameBuffer(self)
-
-
-FrameBuffer.mmap = __FrameBuffer__mmap
diff --git a/src/py/libcamera/meson.build b/src/py/libcamera/meson.build
index 0a7b65f3..b705ac1f 100644
--- a/src/py/libcamera/meson.build
+++ b/src/py/libcamera/meson.build
@@ -72,6 +72,10 @@ run_command('ln', '-fsT', files('__init__.py'),
meson.current_build_dir() / '__init__.py',
check: true)
+run_command('ln', '-fsT', meson.current_source_dir() / 'utils',
+ meson.current_build_dir() / 'utils',
+ check: true)
+
install_data(['__init__.py'], install_dir : destdir)
# \todo Generate stubs when building. See https://peps.python.org/pep-0484/#stub-files
diff --git a/src/py/libcamera/utils/MappedFrameBuffer.py b/src/py/libcamera/utils/MappedFrameBuffer.py
new file mode 100644
index 00000000..e7dd16ec
--- /dev/null
+++ b/src/py/libcamera/utils/MappedFrameBuffer.py
@@ -0,0 +1,74 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+# Copyright (C) 2022, Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+
+class MappedFrameBuffer:
+ def __init__(self, fb):
+ self.__fb = fb
+
+ def __enter__(self):
+ import os
+ import mmap
+
+ fb = self.__fb
+
+ # Collect information about the buffers
+
+ bufinfos = {}
+
+ for i in range(fb.num_planes):
+ fd = fb.fd(i)
+
+ if fd not in bufinfos:
+ buflen = os.lseek(fd, 0, os.SEEK_END)
+ bufinfos[fd] = {'maplen': 0, 'buflen': buflen}
+ else:
+ buflen = bufinfos[fd]['buflen']
+
+ if fb.offset(i) > buflen or fb.offset(i) + fb.length(i) > buflen:
+ raise RuntimeError(f'plane is out of buffer: buffer length={buflen}, ' +
+ f'plane offset={fb.offset(i)}, plane length={fb.length(i)}')
+
+ bufinfos[fd]['maplen'] = max(bufinfos[fd]['maplen'], fb.offset(i) + fb.length(i))
+
+ # mmap the buffers
+
+ maps = []
+
+ for fd, info in bufinfos.items():
+ map = mmap.mmap(fd, info['maplen'], mmap.MAP_SHARED, mmap.PROT_READ | mmap.PROT_WRITE)
+ info['map'] = map
+ maps.append(map)
+
+ self.__maps = tuple(maps)
+
+ # Create memoryviews for the planes
+
+ planes = []
+
+ for i in range(fb.num_planes):
+ fd = fb.fd(i)
+ info = bufinfos[fd]
+
+ mv = memoryview(info['map'])
+
+ start = fb.offset(i)
+ end = fb.offset(i) + fb.length(i)
+
+ mv = mv[start:end]
+
+ planes.append(mv)
+
+ self.__planes = tuple(planes)
+
+ return self
+
+ def __exit__(self, exc_type, exc_value, exc_traceback):
+ for p in self.__planes:
+ p.release()
+
+ for mm in self.__maps:
+ mm.close()
+
+ @property
+ def planes(self):
+ return self.__planes
diff --git a/src/py/libcamera/utils/__init__.py b/src/py/libcamera/utils/__init__.py
new file mode 100644
index 00000000..4a23ce36
--- /dev/null
+++ b/src/py/libcamera/utils/__init__.py
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+# Copyright (C) 2022, Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+
+from .MappedFrameBuffer import MappedFrameBuffer