mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-10-01 20:36:51 +03:00
Tweaks (#24067)
* improve keyframes messages * don't pad the labelmap with unknown `load_labels()` prefilled 91 `unknown` entries before reading the label file, so any model with fewer than 91 classes kept that padding in `merged_labelmap` and `unknown` showed up as a selectable object type in the objects settings UI. The padding only existed so `RemoteObjectDetector.detect` could index the labelmap without a KeyError, and it didn't even cover the empty-file case or Frigate+, which never had a prefill. Both lookups now skip class ids the labelmap doesn't name and warn once per id.
This commit is contained in:
committed by
Nicolas Mowen
parent
853840dfd4
commit
396a2156b2
@@ -152,12 +152,19 @@ def get_record_segment_time(config: "CameraConfig") -> int:
|
||||
|
||||
|
||||
def load_labels(
|
||||
path: str | None, encoding="utf-8", prefill=91, indexed: bool | None = None
|
||||
path: str | None, encoding="utf-8", prefill=0, indexed: bool | None = None
|
||||
):
|
||||
"""Loads labels from file (with or without index numbers).
|
||||
|
||||
Only the indices the file defines are returned, so the result describes
|
||||
exactly the classes a model can name. Callers must treat a missing index
|
||||
as an unnamed class rather than assuming a contiguous range.
|
||||
|
||||
Args:
|
||||
path: path to label file.
|
||||
encoding: label file encoding.
|
||||
prefill: pad indices below this with "unknown" before reading the file.
|
||||
indexed: whether lines start with an index; auto-detected when None.
|
||||
Returns:
|
||||
Dictionary mapping indices to labels.
|
||||
"""
|
||||
|
||||
@@ -1061,6 +1061,7 @@ def ffprobe_stream(ffmpeg, path: str, detailed: bool = False) -> sp.CompletedPro
|
||||
|
||||
KEYFRAME_PROBE_WINDOW_SECONDS = 20
|
||||
KEYFRAME_GAP_WARNING_SECONDS = 4.0
|
||||
KEYFRAME_GAP_JITTER_SECONDS = 0.5
|
||||
|
||||
|
||||
def parse_keyframe_packets(output: str) -> tuple[list[float], float | None]:
|
||||
@@ -1100,6 +1101,10 @@ def classify_keyframe_gaps(
|
||||
- "error" when the longest gap exceeds the record segment length
|
||||
- "warning" when the longest gap exceeds the warning threshold
|
||||
- "ok" otherwise
|
||||
|
||||
The "pattern" key separates the two causes so callers can give accurate
|
||||
advice: "fixed" is a regular GOP that is simply too long, "variable" is
|
||||
the irregular spacing a smart/+ codec produces.
|
||||
"""
|
||||
thresholds = {
|
||||
"warning": KEYFRAME_GAP_WARNING_SECONDS,
|
||||
@@ -1112,6 +1117,7 @@ def classify_keyframe_gaps(
|
||||
"max_gap": None,
|
||||
"mean_gap": None,
|
||||
"min_gap": None,
|
||||
"pattern": None,
|
||||
"segment_time": segment_time,
|
||||
"severity": "unknown",
|
||||
"thresholds": thresholds,
|
||||
@@ -1119,6 +1125,7 @@ def classify_keyframe_gaps(
|
||||
|
||||
gaps = [b - a for a, b in zip(keyframe_pts, keyframe_pts[1:])]
|
||||
max_gap = max(gaps)
|
||||
min_gap = min(gaps)
|
||||
|
||||
if max_gap > segment_time:
|
||||
severity = "error"
|
||||
@@ -1127,11 +1134,16 @@ def classify_keyframe_gaps(
|
||||
else:
|
||||
severity = "ok"
|
||||
|
||||
# allow for encoder jitter and probe rounding before calling a GOP variable
|
||||
tolerance = max(KEYFRAME_GAP_JITTER_SECONDS, min_gap * 0.25)
|
||||
pattern = "variable" if (max_gap - min_gap) > tolerance else "fixed"
|
||||
|
||||
return {
|
||||
"keyframe_count": len(keyframe_pts),
|
||||
"max_gap": round(max_gap, 2),
|
||||
"mean_gap": round(sum(gaps) / len(gaps), 2),
|
||||
"min_gap": round(min(gaps), 2),
|
||||
"min_gap": round(min_gap, 2),
|
||||
"pattern": pattern,
|
||||
"segment_time": segment_time,
|
||||
"severity": severity,
|
||||
"thresholds": thresholds,
|
||||
|
||||
Reference in New Issue
Block a user