mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-02 09:15:22 +03:00
gstreamer improvements
This commit is contained in:
parent
667cfed077
commit
0911b4fd01
@ -1,5 +1,4 @@
|
||||
from __future__ import annotations
|
||||
from email.policy import default
|
||||
|
||||
import json
|
||||
import logging
|
||||
@ -628,7 +627,7 @@ class CameraConfig(FrigateBaseModel):
|
||||
else:
|
||||
for input in self.gstreamer.inputs:
|
||||
gst_cmd = self._get_gstreamer_cmd(self.gstreamer, input)
|
||||
logger.error("gstreamer command[%s] %s", self.name, gst_cmd)
|
||||
logger.info("gstreamer command[%s] %s", self.name, gst_cmd)
|
||||
self._decoder_cmds.append({"roles": input.roles, "cmd": gst_cmd})
|
||||
|
||||
def _get_gstreamer_cmd(
|
||||
|
||||
@ -17,6 +17,7 @@ VIDEO_CODEC_CAP_NAME = "video codec"
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@lru_cache
|
||||
def gst_discover(
|
||||
source: str, cam_name: str, keys: List[str]
|
||||
@ -53,12 +54,12 @@ def gst_discover(
|
||||
),
|
||||
cam_name,
|
||||
)
|
||||
return None
|
||||
return {}
|
||||
except:
|
||||
logger.error(
|
||||
"gst-discoverer-1.0 failed with the message: %s", traceback.format_exc()
|
||||
)
|
||||
return None
|
||||
return {}
|
||||
|
||||
|
||||
@lru_cache
|
||||
@ -81,9 +82,7 @@ def gst_inspect_find_codec(codec: Optional[str]) -> List[str]:
|
||||
for line in data.split("\n")
|
||||
if codec is None or codec in line
|
||||
]
|
||||
return [
|
||||
item[1].strip() for item in data if len(item) > 1
|
||||
]
|
||||
return [item[1].strip() for item in data if len(item) > 1]
|
||||
except:
|
||||
logger.error(
|
||||
"gst-inspect-1.0 failed with the message: %s", traceback.format_exc()
|
||||
@ -228,7 +227,7 @@ class GstreamerBaseBuilder:
|
||||
self.audio_pipeline is not None and len(self.audio_pipeline) > 0
|
||||
)
|
||||
|
||||
split_mux = f"splitmuxsink async-handling=true "
|
||||
split_mux = f"splitmuxsink async-finalize=true send-keyframe-requests=true max-size-bytes=0 "
|
||||
|
||||
if use_audio_pipeline:
|
||||
split_mux = split_mux + "name=mux muxer=mp4mux "
|
||||
@ -283,6 +282,14 @@ class GstreamerBaseBuilder:
|
||||
)
|
||||
depay_element = f"rtp{self.video_format}depay"
|
||||
|
||||
# add rtpjitterbuffer into the input pipeline for reord role if no rtpjitterbuffer has been added already
|
||||
if use_record:
|
||||
has_rtpjitterbuffer = "rtpjitterbuffer" in " ".join(self.input_pipeline)
|
||||
if not has_rtpjitterbuffer:
|
||||
self.input_pipeline.append(
|
||||
"rtpjitterbuffer do-lost=true drop-on-latency=true"
|
||||
)
|
||||
|
||||
pipeline = [*self.input_pipeline, depay_element]
|
||||
# if both detect and record used, split the stream after the depay element
|
||||
# to avoid encoding for recording
|
||||
|
||||
@ -22,7 +22,6 @@ from frigate.const import (
|
||||
CACHE_DIR,
|
||||
RECORD_DIR,
|
||||
GSTREAMER_RECORD_SUFFIX,
|
||||
RECORD_SEGMENT_TIME_SECONDS,
|
||||
)
|
||||
from frigate.models import Event, Recordings
|
||||
from frigate.util import area
|
||||
@ -98,7 +97,7 @@ class RecordingMaintainer(threading.Thread):
|
||||
if camera.endswith(GSTREAMER_RECORD_SUFFIX):
|
||||
camera = camera.split(GSTREAMER_RECORD_SUFFIX)[0]
|
||||
creation_time = (
|
||||
os.path.getmtime(cache_path) - RECORD_SEGMENT_TIME_SECONDS
|
||||
os.path.getctime(cache_path)
|
||||
)
|
||||
start_time = datetime.datetime.utcfromtimestamp(creation_time)
|
||||
else:
|
||||
|
||||
@ -284,6 +284,10 @@ class TestGstreamerNvidia(TestCase):
|
||||
"latency=0",
|
||||
"do-timestamp=true",
|
||||
"!",
|
||||
"rtpjitterbuffer",
|
||||
"do-lost=true",
|
||||
"drop-on-latency=true",
|
||||
"!",
|
||||
"rtph264depay",
|
||||
"!",
|
||||
"tee",
|
||||
@ -308,7 +312,9 @@ class TestGstreamerNvidia(TestCase):
|
||||
"h264parse",
|
||||
"!",
|
||||
"splitmuxsink",
|
||||
"async-handling=true",
|
||||
"async-finalize=true",
|
||||
"send-keyframe-requests=true",
|
||||
"max-size-bytes=0",
|
||||
"location=/tmp/cache/cam_name-gstsplitmuxchunk-%05d.mp4",
|
||||
"max-size-time=10000000000",
|
||||
]
|
||||
@ -332,6 +338,10 @@ class TestGstreamerNvidia(TestCase):
|
||||
"latency=0",
|
||||
"do-timestamp=true",
|
||||
"!",
|
||||
"rtpjitterbuffer",
|
||||
"do-lost=true",
|
||||
"drop-on-latency=true",
|
||||
"!",
|
||||
"rtph264depay",
|
||||
"!",
|
||||
"queue",
|
||||
@ -339,7 +349,9 @@ class TestGstreamerNvidia(TestCase):
|
||||
"h264parse",
|
||||
"!",
|
||||
"splitmuxsink",
|
||||
"async-handling=true",
|
||||
"async-finalize=true",
|
||||
"send-keyframe-requests=true",
|
||||
"max-size-bytes=0",
|
||||
"location=/tmp/cache/cam_name-gstsplitmuxchunk-%05d.mp4",
|
||||
"max-size-time=10000000000",
|
||||
]
|
||||
@ -367,6 +379,10 @@ class TestGstreamerNvidia(TestCase):
|
||||
"latency=0",
|
||||
"do-timestamp=true",
|
||||
"!",
|
||||
"rtpjitterbuffer",
|
||||
"do-lost=true",
|
||||
"drop-on-latency=true",
|
||||
"!",
|
||||
"rtph265depay",
|
||||
"!",
|
||||
"tee",
|
||||
@ -391,7 +407,9 @@ class TestGstreamerNvidia(TestCase):
|
||||
"h265parse",
|
||||
"!",
|
||||
"splitmuxsink",
|
||||
"async-handling=true",
|
||||
"async-finalize=true",
|
||||
"send-keyframe-requests=true",
|
||||
"max-size-bytes=0",
|
||||
"name=mux",
|
||||
"muxer=mp4mux",
|
||||
"location=/tmp/cache/cam_name-gstsplitmuxchunk-%05d.mp4",
|
||||
@ -432,6 +450,10 @@ class TestGstreamerNvidia(TestCase):
|
||||
"latency=0",
|
||||
"do-timestamp=true",
|
||||
"!",
|
||||
"rtpjitterbuffer",
|
||||
"do-lost=true",
|
||||
"drop-on-latency=true",
|
||||
"!",
|
||||
"rtph264depay",
|
||||
"!",
|
||||
"queue",
|
||||
@ -439,7 +461,9 @@ class TestGstreamerNvidia(TestCase):
|
||||
"h264parse",
|
||||
"!",
|
||||
"splitmuxsink",
|
||||
"async-handling=true",
|
||||
"async-finalize=true",
|
||||
"send-keyframe-requests=true",
|
||||
"max-size-bytes=0",
|
||||
"name=mux",
|
||||
"muxer=mp4mux",
|
||||
"location=/tmp/cache/cam_name-gstsplitmuxchunk-%05d.mp4",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user