Open signag opened 5 months ago
Thanks for the report and the code to reproduce it.
It seems to be specific to the FfmpegOutput, where the ffmpeg process isn't cleaning up completely. It seems that adding a gc.collect()
when the FfmpegOutput stops mostly solves the problem, and the thread count never goes above 20, so I'll make that change. (I'm not really clear why this is necessary, though I note that the refcount on the subprocess object is always 2, so I wonder if there's a circular reference going on? Who knows...)
In the meantime, I'd recommend adding
encoder = None
gc.collect()
to your code just after picam2.stop_encoder(encoder)
. You might even want to leave this in once you've got the proposed fix as (for me at least!) it limits the number of threads to 13.
Thanks for the quick response.
I am following your recommendation.
However, I am not sure whether it is the ffmpeg process which does not clean up.
ffmpeg runs in an own process with typically 2 threads which all vanish after encoding was completed.
(I am showing now ffmpeg process information along with main process data in a Camera Info screen)
I also need to correct:
2 threads are started with import of Picamera2 in case of Bookworm, even on a Pi Zero 2W.
For Bullseye, no additional thread is started with import.
In truth, I wouldn't like to claim I fully understand exactly what is happening, and I don't know why Bookworm would be different to Bullseye. But if there's still a problem with these threads, please do report back (preferably with some code I can run - that was very helpful!) and we can investigate some more.
Hello,
Bug Description
I am working on a Flask-based web server for controlling Raspberry Pi cameras with picamera2 (raspi-cam-srv) Among others, this includes motion detection with recording of .mp4 videos.
Users had recognized that the number of threads of the server process is increasing with time.
To analyze the situation, I have written a small test program which monitors the number of threads after specific process steps for different scenarios.
For results, see Console Output, below.
Obviously, already the import of Picamera2 starts 2 threads (only observed on Pi5).
Within the loop, the encoder is started and stopped 5 times, while the camera keeps running.
Each encoder start seems to start 9 threads. However, these threads do not in all cases terminate after the encoder has been stopped.
After the first run, 9 threads are still alive after the camera had been closed and the reference to the camera has been removed.
In the example, all threads seem to have terminated after the second cycle (only the 3 threads from import survive).
However, I have also seen cases where these threads lived for hours.
With other encoders, the behavior was as expected: No additional threads survived after the camera was closed.
To Reproduce
The attached test program can be used to reproduce the described bahavior.
TestPicamera2Threads.zip
Expected Behaviour
I would expect that no additional threads survive after the encoder has been stopped and the camera has been closed.
Console Output, Screenshots
Below is the function for recording .mp4 videos:
For recording .mp4 videos with H264Encoder and FfmpegOutput, the test gives the following output:
Hardware
RPi 5
Attached cameras:
OS: Bookworm
Debian version: 12.5
Additional Context