picamera2
picamera2 copied to clipboard
take pictures during a video recording -errors
I want to take pictures during a video recording (webstream) is in process.
I basically follow the still_during_video.py
example:
Describe the bug
- Reconfigure (to video mode) the camera after picture has been taken failed. (see below)
- With the reconfiguration:
- Several other errors like "MmemoryAllocation" which I will describe later after I am sure that in my code are no bug itsself.
To Reproduce
Because of #887 I have also tested in the next
branch.
#!/usr/bin/python3
from typing import Final
from pathlib import Path
import time
import io
from threading import Condition
from picamera2.encoders import MJPEGEncoder
import libcamera
from picamera2.picamera2 import Picamera2
from picamera2.outputs import FileOutput
class StreamingOutput(io.BufferedIOBase):
def __init__(self):
self.__frame = None
self.__condition = Condition()
@property
def frame(self) -> bytes:
return self.__frame
@frame.setter
def frame(self, frame: bytes) -> None:
self.__frame = frame
@property
def condition(self) -> Condition:
return self.__condition
def write(self, buf):
with self.condition:
self.frame = buf
self.condition.notify_all()
STILL_CONFIGURATION: Final = {
'use_case': 'still',
'transform': libcamera.Transform(hflip=1),
'colour_space': libcamera.ColorSpace.Sycc(),
'buffer_count': 1,
'queue': True,
'main': {'format': 'BGR888', 'size': (1920, 1080)},
'lores': None,
'raw': {'format': 'SRGGB12_CSI2P', 'size': (4056, 3040)},
'controls': {
'NoiseReductionMode': libcamera.controls
.draft.NoiseReductionModeEnum.HighQuality,
'FrameDurationLimits': (100, 1000000000),
'Saturation': 0.0,
'Sharpness': 12.0,
'Brightness': 0.0,
'AnalogueGain': 5,
'ColourGains': (0, 0),
'AeExposureMode': libcamera.controls
.AeExposureModeEnum.Normal,
'AwbEnable': False,
'AeEnable': False,
'ExposureTime': 10000},
'sensor': {'output_size': (4056, 3040)},
'display': None, 'encode': None}
picam2 = Picamera2()
def start_recording() -> None:
encoder = MJPEGEncoder()
picam2.start_recording(
encoder=encoder,
output=FileOutput(StreamingOutput()))
def take_picture():
request = None
if picam2.started:
request = picam2.capture_request()
started = picam2.started
config = picam2.camera_config #config = copy.deepcopy(picam2.camera_config)
picam2.stop()
picam2.configure(STILL_CONFIGURATION)
picam2.start()
img = picam2.capture_image("main")
picam2.stop()
picam2.configure(config)
if request is not None:
request.release()
if started:
picam2.start()
def test_loop():
start_recording()
i = 0
while True:
print("\n \n \n ------------------", i)
take_picture()
time.sleep(1.0)
i += 1
if i > 5:
break
if __name__ == '__main__':
test_loop()
Expected behaviour Picture taking works during video recording running infinity number of times.
Console Output, Screenshots 1.
[10:53:49.657379752] [8609] INFO Camera camera.cpp:1183 configuring streams: (0) 1280x720-XBGR8888 (1) 2028x1080-SBGGR12_CSI2P
[10:53:49.669070213] [8604] INFO RPI vc4.cpp:608 Sensor: /base/soc/i2c0mux/i2c@1/imx477@1a - Selected sensor format: 2028x1080-SBGGR12_1X12 - Selected unicam format: 2028x1080-pBCC
Exception in thread Thread-2 (thread_poll):
Traceback (most recent call last):
File "/usr/lib/python3.11/threading.py", line 1038, in _bootstrap_inner
self.run()
File "/usr/lib/python3.11/threading.py", line 975, in run
self._target(*self._args, **self._kwargs)
File "/usr/lib/python3/dist-packages/picamera2/encoders/v4l2_encoder.py", line 241, in thread_poll
queue_item.release()
File "/usr/lib/python3/dist-packages/picamera2/request.py", line 140, in release
self.picam2.allocator.release(self.request.buffers)
File "/usr/lib/python3/dist-packages/picamera2/allocators/dmaallocator.py", line 78, in release
self.cleanup()
File "/usr/lib/python3/dist-packages/picamera2/allocators/dmaallocator.py", line 81, in cleanup
for k, v in self.mapped_buffers.items():
RuntimeError: dictionary changed size during iteration
G
Traceback (most recent call last):
File "/home/pi/camera_websetter_python/./test_loop.py", line 116, in <module>
test_loop()
File "/home/pi/camera_websetter_python/./test_loop.py", line 105, in test_loop
take_picture()
File "/home/pi/camera_websetter_python/./test_loop.py", line 95, in take_picture
request.release()
File "/usr/lib/python3/dist-packages/picamera2/request.py", line 140, in release
self.picam2.allocator.release(self.request.buffers)
File "/usr/lib/python3/dist-packages/picamera2/allocators/dmaallocator.py", line 78, in release
self.cleanup()
File "/usr/lib/python3/dist-packages/picamera2/allocators/dmaallocator.py", line 83, in cleanup
if not self.mapped_buffers_used[fd] and fd not in self.libcamera_fds:
~~~~~~~~~~~~~~~~~~~~~~~~^^^^
KeyError: 27
Exception ignored in: <function DmaAllocator.__del__ at 0x73016398>
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/picamera2/allocators/dmaallocator.py", line 100, in __del__
self.close()
File "/usr/lib/python3/dist-packages/picamera2/allocators/dmaallocator.py", line 92, in close
self.cleanup()
File "/usr/lib/python3/dist-packages/picamera2/allocators/dmaallocator.py", line 83, in cleanup
if not self.mapped_buffers_used[fd] and fd not in self.libcamera_fds:
INFO:picamera2.picamera2:Camera stopped
DEBUG:picamera2.picamera2:Requesting configuration: {'use_case': 'still', 'transform': <libcamera.Transform 'hvflip'>, 'colour_space': <libcamera.ColorSpace 'sYCC'>, 'buffer_count': 1, 'queue': True, 'main': {'format': 'BGR888', 'size': (1920, 1080), 'stride': 5760, 'framesize': 6220800}, 'lores': None, 'raw': {'format': 'SRGGB12_CSI2P', 'size': (4056, 3040), 'stride': 6112, 'framesize': 18580480}, 'controls': {'NoiseReductionMode': <NoiseReductionModeEnum.HighQuality: 2>, 'FrameDurationLimits': (100, 1000000000), 'Saturation': 0.0, 'Sharpness': 12.0, 'Brightness': 0.1, 'AnalogueGain': 6, 'ColourGains': (0, 0), 'AeExposureMode': <AeExposureModeEnum.Normal: 0>, 'AwbEnable': False, 'AeEnable': False, 'ExposureTime': 10000}, 'sensor': {'bit_depth': 12, 'output_size': (4056, 3040)}, 'display': None, 'encode': None}
[11:24:21.998080685] [9006] INFO Camera camera.cpp:1183 configuring streams: (0) 1920x1080-BGR888 (1) 4056x3040-SRGGB12_CSI2P
[11:24:22.014301048] [8939] INFO RPI vc4.cpp:608 Sensor: /base/soc/i2c0mux/i2c@1/imx477@1a - Selected sensor format: 4056x3040-SRGGB12_1X12 - Selected unicam format: 4056x3040-pRCC
INFO:picamera2.picamera2:Configuration successful!
DEBUG:picamera2.picamera2:Final configuration: {'use_case': 'still', 'transform': <libcamera.Transform 'hvflip'>, 'colour_space': <libcamera.ColorSpace 'sYCC'>, 'buffer_count': 1, 'queue': True, 'main': {'format': 'BGR888', 'size': (1920, 1080), 'stride': 5760, 'framesize': 6220800}, 'lores': None, 'raw': {'format': 'SRGGB12_CSI2P', 'size': (4056, 3040), 'stride': 6112, 'framesize': 18580480}, 'controls': {'NoiseReductionMode': <NoiseReductionModeEnum.HighQuality: 2>, 'FrameDurationLimits': (100, 1000000000), 'Saturation': 0.0, 'Sharpness': 12.0, 'Brightness': 0.1, 'AnalogueGain': 6, 'ColourGains': (0, 0), 'AeExposureMode': <AeExposureModeEnum.Normal: 0>, 'AwbEnable': False, 'AeEnable': False, 'ExposureTime': 10000}, 'sensor': {'bit_depth': 12, 'output_size': (4056, 3040)}, 'display': None, 'encode': None}
DEBUG:picamera2.picamera2:Streams: {'main': <libcamera._libcamera.Stream object at 0x653c10a0>, 'lores': None, 'raw': <libcamera._libcamera.Stream object at 0x653c17e0>}
ERROR:root:34
DEBUG:picamera2.picamera2:Requesting configuration: {'use_case': 'preview', 'buffer_count': 4, 'transform': <libcamera.Transform 'identity'>, 'display': 'main', 'encode': 'main', 'colour_space': <libcamera.ColorSpace 'sYCC'>, 'controls': <Controls: {'NoiseReductionMode': <NoiseReductionModeEnum.Minimal: 3>, 'FrameDurationLimits': (100, 83333)}>, 'main': {'size': (640, 480), 'format': 'XBGR8888', 'stride': 2560, 'framesize': 1228800}, 'lores': None, 'raw': {'size': (2028, 1520), 'format': 'SBGGR12_CSI2P', 'stride': 3072, 'framesize': 4669440}, 'queue': True, 'sensor': {'bit_depth': 12, 'output_size': (2028, 1520)}}
INFO:picamera2.picamera2:Camera configuration has been adjusted!
[11:24:22.035280584] [9006] INFO Camera camera.cpp:1183 configuring streams: (0) 640x480-XBGR8888 (1) 2028x1520-SBGGR12_CSI2P
[11:24:22.036419896] [8939] INFO RPI vc4.cpp:608 Sensor: /base/soc/i2c0mux/i2c@1/imx477@1a - Selected sensor format: 2028x1520-SBGGR12_1X12 - Selected unicam format: 2028x1520-pBCC
INFO:picamera2.picamera2:Configuration successful!
DEBUG:picamera2.picamera2:Final configuration: {'use_case': 'preview', 'buffer_count': 4, 'transform': <libcamera.Transform 'identity'>, 'display': 'main', 'encode': 'main', 'colour_space': <libcamera.ColorSpace 'sYCC'>, 'controls': <Controls: {'NoiseReductionMode': <NoiseReductionModeEnum.Minimal: 3>, 'FrameDurationLimits': (100, 83333)}>, 'main': {'size': (640, 480), 'format': 'XBGR8888', 'stride': 2560, 'framesize': 1228800}, 'lores': None, 'raw': {'size': (2028, 1520), 'format': 'SBGGR12_CSI2P', 'stride': 3072, 'framesize': 4669440}, 'queue': True, 'sensor': {'bit_depth': 12, 'output_size': (2028, 1520)}}
DEBUG:picamera2.picamera2:Streams: {'main': <libcamera._libcamera.Stream object at 0x653c10a0>, 'lores': None, 'raw': <libcamera._libcamera.Stream object at 0x653c17e0>}
DEBUG:picamera2:Allocated 4 buffers for stream 0 with fds [33, 36, 41, 48]
DEBUG:picamera2:Allocated 4 buffers for stream 1 with fds [51, 55, 75, 78]
INFO:picamera2.picamera2:Camera started
DEBUG:picamera2.picamera2:Execute job: <picamera2.job.Job object at 0x624b4810>
ERROR:picamera2.previews.null_preview:Exception during process_requests()
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/picamera2/previews/null_preview.py", line 85, in handle_request
picam2.process_requests(self)
File "/usr/lib/python3/dist-packages/picamera2/picamera2.py", line 1265, in process_requests
encoder.encode(encoder.name, req)
File "/usr/lib/python3/dist-packages/picamera2/encoders/encoder.py", line 210, in encode
self._encode(stream, request)
File "/usr/lib/python3/dist-packages/picamera2/encoders/v4l2_encoder.py", line 279, in _encode
fcntl.ioctl(self.vd, VIDIOC_QBUF, buf)
OSError: [Errno 22] Invalid argument
Exception in thread Thread-4 (thread_func):
Traceback (most recent call last):
File "/usr/lib/python3.11/threading.py", line 1038, in _bootstrap_inner
self.run()
File "/usr/lib/python3.11/threading.py", line 975, in run
self._target(*self._args, **self._kwargs)
File "/usr/lib/python3/dist-packages/picamera2/previews/null_preview.py", line 29, in thread_func
callback(picam2)
File "/usr/lib/python3/dist-packages/picamera2/previews/null_preview.py", line 85, in handle_request
picam2.process_requests(self)
File "/usr/lib/python3/dist-packages/picamera2/picamera2.py", line 1265, in process_requests
encoder.encode(encoder.name, req)
File "/usr/lib/python3/dist-packages/picamera2/encoders/encoder.py", line 210, in encode
self._encode(stream, request)
File "/usr/lib/python3/dist-packages/picamera2/encoders/v4l2_encoder.py", line 279, in _encode
fcntl.ioctl(self.vd, VIDIOC_QBUF, buf)
OSError: [Errno 22] Invalid argument
Hardware :
The problem appear with imx477
and not with imx708
on raspberry 2 and 3 with the latest firmware (rpi-update
).