Ensure birdseye restream is not left with partially read frames (#5504)

* Ensure birdseye pipe does not get corrupted

* Fix conditionals

* Change log

* Formatting
This commit is contained in:
Nicolas Mowen 2023-02-16 06:49:31 -07:00 committed by GitHub
parent c9cd810c9f
commit 7b26935462
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -38,17 +38,11 @@ class FFMpegConverter:
quality: int, quality: int,
birdseye_rtsp: bool = False, birdseye_rtsp: bool = False,
): ):
if birdseye_rtsp:
if os.path.exists(BIRDSEYE_PIPE):
os.remove(BIRDSEYE_PIPE)
os.mkfifo(BIRDSEYE_PIPE, mode=0o777)
stdin = os.open(BIRDSEYE_PIPE, os.O_RDONLY | os.O_NONBLOCK)
self.bd_pipe = os.open(BIRDSEYE_PIPE, os.O_WRONLY)
os.close(stdin)
else:
self.bd_pipe = None self.bd_pipe = None
if birdseye_rtsp:
self.recreate_birdseye_pipe()
ffmpeg_cmd = [ ffmpeg_cmd = [
"ffmpeg", "ffmpeg",
"-f", "-f",
@ -80,14 +74,36 @@ class FFMpegConverter:
start_new_session=True, start_new_session=True,
) )
def recreate_birdseye_pipe(self) -> None:
if self.bd_pipe:
os.close(self.bd_pipe)
if os.path.exists(BIRDSEYE_PIPE):
os.remove(BIRDSEYE_PIPE)
os.mkfifo(BIRDSEYE_PIPE, mode=0o777)
stdin = os.open(BIRDSEYE_PIPE, os.O_RDONLY | os.O_NONBLOCK)
self.bd_pipe = os.open(BIRDSEYE_PIPE, os.O_WRONLY)
os.close(stdin)
self.reading_birdseye = False
def write(self, b) -> None: def write(self, b) -> None:
self.process.stdin.write(b) self.process.stdin.write(b)
if self.bd_pipe: if self.bd_pipe:
try: try:
os.write(self.bd_pipe, b) os.write(self.bd_pipe, b)
self.reading_birdseye = True
except BrokenPipeError: except BrokenPipeError:
# catch error when no one is listening if self.reading_birdseye:
# we know the pipe was being read from and now it is not
# so we should recreate the pipe to ensure no partially-read
# frames exist
logger.debug(
"Recreating the birdseye pipe because it was read from and now is not"
)
self.recreate_birdseye_pipe()
return return
def read(self, length): def read(self, length):