Skip to content

Commit 2d3924f

Browse files
committed
Improve FfmpegOutput shutdown if there's an error in the Ffmpeg process
Set a flag to stop us continually re-trying when it's already failed, but leave the tidying up proper to the stop() method. This stops us seeing a few mildly disconcerting errors (unless we want to, of course). Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
1 parent 83c8bd7 commit 2d3924f

1 file changed

Lines changed: 9 additions & 3 deletions

File tree

picamera2/outputs/ffmpegoutput.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ def __init__(self, output_filename, audio=False, audio_device="default", audio_s
3737
audio_samplerate=48000, audio_codec="aac", audio_bitrate=128000, audio_filter=None, pts=None):
3838
super().__init__(pts=pts)
3939
self.ffmpeg = None
40+
self.output_broken = False
4041
self.output_filename = output_filename
4142
self.audio = audio
4243
self.audio_device = audio_device
@@ -86,7 +87,10 @@ def start(self):
8687
def stop(self):
8788
super().stop()
8889
if self.ffmpeg is not None:
89-
self.ffmpeg.stdin.close() # FFmpeg needs this to shut down tidily
90+
try:
91+
self.ffmpeg.stdin.close() # FFmpeg needs this to shut down tidily
92+
except Exception:
93+
pass
9094
try:
9195
# Give it a moment to flush out video frames, but after that make sure we terminate it.
9296
self.ffmpeg.wait(timeout=self.timeout)
@@ -103,13 +107,15 @@ def stop(self):
103107
def outputframe(self, frame, keyframe=True, timestamp=None, packet=None, audio=False):
104108
if audio:
105109
raise RuntimeError("FfmpegOutput does not support audio packets from Picamera2")
106-
if self.recording and self.ffmpeg:
110+
if self.recording and not self.output_broken:
107111
# Handle the case where the FFmpeg prcoess has gone away for reasons of its own.
108112
try:
109113
self.ffmpeg.stdin.write(frame)
110114
self.ffmpeg.stdin.flush() # forces every frame to get timestamped individually
111115
except Exception as e: # presumably a BrokenPipeError? should we check explicitly?
112-
self.ffmpeg = None
116+
# Don't clear up the ffmpeg process here, that's what stop() is for. But
117+
# set a flag so that we don't keep coming back and re-trying to no avail...
118+
self.output_broken = True
113119
if self.error_callback:
114120
self.error_callback(e)
115121
else:

0 commit comments

Comments
 (0)