From d710b7dfd24c48fee9352311e91b3bbc85380b49 Mon Sep 17 00:00:00 2001 From: Nick Mowen Date: Thu, 29 Dec 2022 13:36:43 -0700 Subject: [PATCH] Write to pipe instead of encoding mpeg1 --- frigate/output.py | 104 ++++++++++++++++++++------------------------ frigate/restream.py | 2 +- 2 files changed, 48 insertions(+), 58 deletions(-) diff --git a/frigate/output.py b/frigate/output.py index e987c7080..bdc188674 100644 --- a/frigate/output.py +++ b/frigate/output.py @@ -3,6 +3,7 @@ import glob import logging import math import multiprocessing as mp +import os import queue import signal import subprocess as sp @@ -28,6 +29,9 @@ logger = logging.getLogger(__name__) class FFMpegConverter: + + BIRDSEYE_PIPE = "/tmp/birdseye" + def __init__( self, in_width: int, @@ -38,63 +42,39 @@ class FFMpegConverter: birdseye_rtsp: bool = False, ): if birdseye_rtsp: - ffmpeg_cmd = [ - "ffmpeg", - "-f", - "rawvideo", - "-pix_fmt", - "yuv420p", - "-video_size", - f"{in_width}x{in_height}", - "-i", - "pipe:", - "-an", - "-f", - "rtp_mpegts", - "-s", - f"{out_width}x{out_height}", - "-codec:v", - "mpeg1video", - "-q", - f"{quality}", - "-bf", - "0", - "rtp://127.0.0.1:1998", - "-f", - "mpegts", - "-s", - f"{out_width}x{out_height}", - "-codec:v", - "mpeg1video", - "-q", - f"{quality}", - "-bf", - "0", - "pipe:", - ] + try: + os.mkfifo(self.BIRDSEYE_PIPE, mode=0o777) + stdin = os.open(self.BIRDSEYE_PIPE, os.O_RDONLY | os.O_NONBLOCK) + self.bd_pipe = os.open(self.BIRDSEYE_PIPE, os.O_WRONLY) + os.close(stdin) + except Exception as e: + print(f"The exception is {e}") + self.bd_pipe = None else: - ffmpeg_cmd = [ - "ffmpeg", - "-f", - "rawvideo", - "-pix_fmt", - "yuv420p", - "-video_size", - f"{in_width}x{in_height}", - "-i", - "pipe:", - "-f", - "mpegts", - "-s", - f"{out_width}x{out_height}", - "-codec:v", - "mpeg1video", - "-q", - f"{quality}", - "-bf", - "0", - "pipe:", - ] + self.bd_pipe = None + + ffmpeg_cmd = [ + "ffmpeg", + "-f", + "rawvideo", + "-pix_fmt", + "yuv420p", + "-video_size", + f"{in_width}x{in_height}", + "-i", + "pipe:", + "-f", + "mpegts", + "-s", + f"{out_width}x{out_height}", + "-codec:v", + "mpeg1video", + "-q", + f"{quality}", + "-bf", + "0", + "pipe:", + ] self.process = sp.Popen( ffmpeg_cmd, @@ -104,9 +84,16 @@ class FFMpegConverter: start_new_session=True, ) - def write(self, b): + def write(self, b) -> None: self.process.stdin.write(b) + if self.bd_pipe: + try: + os.write(self.bd_pipe, b) + except BrokenPipeError: + # catch error when no one is listening + return + def read(self, length): try: return self.process.stdout.read1(length) @@ -114,6 +101,9 @@ class FFMpegConverter: return False def exit(self): + if self.bd_pipe: + os.close(self.bd_pipe) + self.process.terminate() try: self.process.communicate(timeout=30) diff --git a/frigate/restream.py b/frigate/restream.py index e7b1add7f..e84b83746 100644 --- a/frigate/restream.py +++ b/frigate/restream.py @@ -45,7 +45,7 @@ class RestreamApi: if self.config.restream.birdseye: self.relays[ "birdseye" - ] = "ffmpeg:rtp://127.0.0.1:1998#video=h264#audio=none" + ] = f"exec:ffmpeg -hide_banner -f rawvideo -pix_fmt yuv420p -s {self.config.birdseye.width}x{self.config.birdseye.height} -i /tmp/birdseye -tune zerolatency -preset ultrafast -c:v libx264 -rtsp_transport tcp -f rtsp {{output}}" for name, path in self.relays.items(): params = {"src": path, "name": name}