From e94547c8592f9f1fb2618b8b5a175ded9a16a69c Mon Sep 17 00:00:00 2001 From: Naushir Patuck Date: Mon, 12 Aug 2024 15:25:09 +0100 Subject: [PATCH] devices: imx708: Add a new IMX708 helper class This class provides a convenient helper function set enable/disable sensor HDR mode without relying on external tools. Usage example: ----- from picamera2.devices.imx708 import IMX708 from picamera2 import Picamera2 camera_num = 0 c = IMX708(camera_num) c.set_sensor_hdr_mode(True) picam2 = Picamera2(camera_num) ----- Note that after calling IMX708.set_hdr_mode(), you must re-initialise the Picamera2 instance. Signed-off-by: Naushir Patuck --- picamera2/devices/imx708/__init__.py | 1 + picamera2/devices/imx708/imx708.py | 46 ++++++++++++++++++++++++++++ setup.py | 3 +- 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 picamera2/devices/imx708/__init__.py create mode 100644 picamera2/devices/imx708/imx708.py diff --git a/picamera2/devices/imx708/__init__.py b/picamera2/devices/imx708/__init__.py new file mode 100644 index 00000000..6157cbb4 --- /dev/null +++ b/picamera2/devices/imx708/__init__.py @@ -0,0 +1 @@ +from .imx708 import IMX708 diff --git a/picamera2/devices/imx708/imx708.py b/picamera2/devices/imx708/imx708.py new file mode 100644 index 00000000..11f469a8 --- /dev/null +++ b/picamera2/devices/imx708/imx708.py @@ -0,0 +1,46 @@ +import fcntl +import os + +from picamera2 import Picamera2 +from v4l2 import * + +HDR_CTRL_ID = 0x009a0915 + + +class IMX708: + def __init__(self, camera_num: int): + self.device_fd = None + + camera_id = next((c['Id'] for c in Picamera2.global_camera_info() if c['Num'] == camera_num), None) + if camera_id is None: + raise RuntimeError(f'IMX708: Requested camera number {camera_num} cound not be found') + + for i in range(16): + test_dir = f'/sys/class/video4linux/v4l-subdev{i}/device' + module_dir = f'{test_dir}/driver/module' + id_dir = f'{test_dir}/of_node' + if os.path.exists(module_dir) and os.path.islink(module_dir) and 'imx708' in os.readlink(module_dir): + if os.path.islink(id_dir) and camera_id in os.readlink(id_dir): + self.device_fd = open(f'/dev/v4l-subdev{i}', 'rb+', buffering=0) + break + + if self.device_fd is None: + raise RuntimeError('IMX708: Requested camera device node not found') + + def __del__(self): + if self.device_fd: + self.device_fd.close() + + def set_sensor_hdr_mode(self, enable: bool): + """ + Set the sensor HDR mode (True/False) on the IMX708 device. Note that after changing the HDR mode, you must + re-initialise the Picamera2 object to cache the updated sensor modes. + """ + ctrl = v4l2_control() + ctrl.id = HDR_CTRL_ID + ctrl.value = int(enable) + + try: + fcntl.ioctl(self.device_fd, VIDIOC_S_CTRL, ctrl) + except OSError as err: + print(f'IMX708: Unable to set HDR control in the device node: {err}') diff --git a/setup.py b/setup.py index 423fccf8..5aa44fa1 100644 --- a/setup.py +++ b/setup.py @@ -30,7 +30,8 @@ "Programming Language :: Python :: 3.9", "Topic :: Multimedia :: Graphics :: Capture :: Digital Camera", ], - packages=['picamera2', 'picamera2.encoders', 'picamera2.outputs', 'picamera2.previews', 'picamera2.allocators'], + packages=['picamera2', 'picamera2.devices.imx708', 'picamera2.encoders', 'picamera2.outputs', 'picamera2.previews', + 'picamera2.allocators'], python_requires='>=3.9', licence='BSD 2-Clause License', install_requires=['numpy', 'PiDNG', 'piexif', 'pillow', 'simplejpeg', 'v4l2-python3', 'python-prctl', 'av'],