[libcamera-devel] [PATCH v2 07/19] py: Move MappedFrameBuffer to libcamera.utils
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Thu May 26 17:31:01 CEST 2022
Hi Tomi,
Thank you for the patch.
On Tue, May 24, 2022 at 02:45:58PM +0300, Tomi Valkeinen wrote:
> Move MappedFrameBuffer to libcamera.utils, instead of extending
> FrameBuffer class with a new mmap() method. This keeps us more aligned
> to the C++ API.
"utils" is a name we use in libcamera/base/utils.h already, for an
entirely different purpose, but I don't think it will create too much
confusion as Python users should not see the C++ utils.h API. We can
always bikeshed this naming question later if needed.
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
> ---
> src/py/cam/cam.py | 5 +-
> src/py/cam/cam_qt.py | 3 +-
> src/py/libcamera/__init__.py | 80 -------------------
> src/py/libcamera/meson.build | 4 +
> .../MappedFrameBuffer.py} | 10 ---
> src/py/libcamera/utils/__init__.py | 4 +
> 6 files changed, 13 insertions(+), 93 deletions(-)
> copy src/py/libcamera/{__init__.py => utils/MappedFrameBuffer.py} (93%)
> create mode 100644 src/py/libcamera/utils/__init__.py
>
> 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 at 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/__init__.py b/src/py/libcamera/utils/MappedFrameBuffer.py
> similarity index 93%
> copy from src/py/libcamera/__init__.py
> copy to src/py/libcamera/utils/MappedFrameBuffer.py
> index 0d7da9e2..e7dd16ec 100644
> --- a/src/py/libcamera/__init__.py
> +++ b/src/py/libcamera/utils/MappedFrameBuffer.py
> @@ -1,9 +1,6 @@
> # SPDX-License-Identifier: LGPL-2.1-or-later
> # Copyright (C) 2022, Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
>
> -from ._libcamera import *
> -
> -
> class MappedFrameBuffer:
> def __init__(self, fb):
> self.__fb = fb
> @@ -75,10 +72,3 @@ class MappedFrameBuffer:
> @property
> def planes(self):
> return self.__planes
> -
> -
> -def __FrameBuffer__mmap(self):
> - return MappedFrameBuffer(self)
> -
> -
> -FrameBuffer.mmap = __FrameBuffer__mmap
> 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 at ideasonboard.com>
> +
> +from .MappedFrameBuffer import MappedFrameBuffer
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list