diff options
author | Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> | 2022-05-27 17:44:24 +0300 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2022-05-27 22:02:41 +0300 |
commit | 9e4388cca5d9ecd6152c0d5990038b515b5f918c (patch) | |
tree | 433360a1efce3c8a22eef4efeeea590894c7581c /src/py/libcamera | |
parent | 210ce547a42ca559592efaef069648ddfe0d2945 (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/libcamera')
-rw-r--r-- | src/py/libcamera/__init__.py | 80 | ||||
-rw-r--r-- | src/py/libcamera/meson.build | 4 | ||||
-rw-r--r-- | src/py/libcamera/utils/MappedFrameBuffer.py | 74 | ||||
-rw-r--r-- | src/py/libcamera/utils/__init__.py | 4 |
4 files changed, 82 insertions, 80 deletions
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 |