picamera2 icon indicating copy to clipboard operation
picamera2 copied to clipboard

[BUG] RuntimeError: dictionary changed size during iteration

Open tranhien1612 opened this issue 1 year ago • 1 comments

I have a simple code to switch two video configuration:

import time, os, socket, threading, datetime, pytz, cv2
import numpy as np

from picamera2 import Picamera2, MappedArray
from picamera2.encoders import H264Encoder, MJPEGEncoder, Quality
from picamera2.outputs import FfmpegOutput

from libcamera import controls

class MyCameraPi:
    picam2 = None;
    encoder = H264Encoder(10000000)
    mode = False;
    def __init__(self):
        self.picam2 = Picamera2();
        video_config = self.picam2.create_video_configuration(
                    main   ={"size": (1920, 1080)},
                    lores  ={"size": (1920, 1080)}, 
                    raw    ={"size": (4608, 2592)}, 
                    controls = {"FrameRate": 10.0},
                    buffer_count = 3
                ); 
        self.picam2.configure(video_config);
        self.picam2.set_controls({"AfMode": controls.AfModeEnum.Continuous})
        self.picam2.start();
        self.start_stream_udp("192.168.1.27", 10001);
        
    def switch_mode(self, mode):
        if(mode == False and self.mode != mode):
            print("Mode1")
            self.picam2.stop();
            video_config = self.picam2.create_video_configuration(
                    main   ={"size": (1920, 1080)},
                    lores  ={"size": (1920, 1080)}, 
                    raw    ={"size": (4608, 2592)}, 
                    controls = {"FrameRate": 10.0},
                    buffer_count = 3
                ); 
            self.picam2.configure(video_config);
            self.picam2.set_controls({"AfMode": controls.AfModeEnum.Continuous})
            self.picam2.start();
        elif(mode == True and self.mode != mode):
            print("Mode2")
            self.picam2.stop();
            video_config = self.picam2.create_video_configuration(
                    main   ={"size": (1920, 1080)},
                    lores  ={"size": (1920, 1080)}, 
                    raw    ={"size": (1920, 1080)}, 
                    controls = {"FrameRate": 50.0},
                    buffer_count = 3
                ); 
            self.picam2.configure(video_config);
            self.picam2.set_controls({"AfMode": controls.AfModeEnum.Continuous})
            self.picam2.start();
        
        self.mode = mode;
        
    def start_stream_udp(self, host, port):
        url = "-f rtp udp://{}:{}".format(host, port);
        output=FfmpegOutput(url)
        print(f"Start UDP Stream started on {host}:{port}\n")
        self.picam2.start_recording(H264Encoder(), output, name="main");
        print("output", output)
        
if __name__ == "__main__":        
    myCamera = MyCameraPi();
    while(True):
        myCamera.switch_mode(True);
        time.sleep(2)
        myCamera.switch_mode(False);
        time.sleep(2)

This is the error:

Exception in thread Thread-3 (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
^CTraceback (most recent call last):
  File "/home/raspi/camera/test.py", line 71, in <module>
    time.sleep(2)
KeyboardInterrupt
^CException ignored in atexit callback: <bound method Picamera2.close of <picamera2.picamera2.Picamera2 object at 0x7f87502950>>
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/picamera2/picamera2.py", line 611, in close
    self.camera.release()
KeyboardInterrupt:

I switch with 2 mode (two video configuration) and an error has occurred. pls support me fix it!

tranhien1612 avatar Apr 01 '24 08:04 tranhien1612

Hi, thanks for the report. Could you check your Picamera2 version first, as I think there were some problems in this area a little while ago (you can do apt list python3-picamera2). Thanks. Also can you say what kind of Pi and what OS version (Bullseye, Bookworm...) you are using.

davidplowman avatar Apr 02 '24 08:04 davidplowman