mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-05-09 15:05:26 +03:00
Compare commits
No commits in common. "11bb9fed4c1e7e844c79d670313afe3ca580f532" and "d315e0874a5c236b6cdacb82ee943d61136d7619" have entirely different histories.
11bb9fed4c
...
d315e0874a
@ -171,7 +171,7 @@ When choosing images to include in the face training set it is recommended to al
|
|||||||
- If it is difficult to make out details in a persons face it will not be helpful in training.
|
- If it is difficult to make out details in a persons face it will not be helpful in training.
|
||||||
- Avoid images with extreme under/over-exposure.
|
- Avoid images with extreme under/over-exposure.
|
||||||
- Avoid blurry / pixelated images.
|
- Avoid blurry / pixelated images.
|
||||||
- Avoid training on infrared (gray-scale). The models are trained on color images and will not be able to extract features from gray-scale images.
|
- Avoid training on infrared (gray-scale). The models are trained on color images and will be able to extract features from gray-scale images.
|
||||||
- Using images of people wearing hats / sunglasses may confuse the model.
|
- Using images of people wearing hats / sunglasses may confuse the model.
|
||||||
- Do not upload too many similar images at the same time, it is recommended to train no more than 4-6 similar images for each person to avoid over-fitting.
|
- Do not upload too many similar images at the same time, it is recommended to train no more than 4-6 similar images for each person to avoid over-fitting.
|
||||||
|
|
||||||
|
|||||||
@ -44,7 +44,6 @@ class LlamaCppClient(GenAIClient):
|
|||||||
_supports_tools: bool
|
_supports_tools: bool
|
||||||
_image_token_cache: dict[tuple[int, int], int]
|
_image_token_cache: dict[tuple[int, int], int]
|
||||||
_text_baseline_tokens: int | None
|
_text_baseline_tokens: int | None
|
||||||
_media_marker: str
|
|
||||||
|
|
||||||
def _init_provider(self) -> str | None:
|
def _init_provider(self) -> str | None:
|
||||||
"""Initialize the client and query model metadata from the server."""
|
"""Initialize the client and query model metadata from the server."""
|
||||||
@ -57,7 +56,6 @@ class LlamaCppClient(GenAIClient):
|
|||||||
self._supports_tools = False
|
self._supports_tools = False
|
||||||
self._image_token_cache = {}
|
self._image_token_cache = {}
|
||||||
self._text_baseline_tokens = None
|
self._text_baseline_tokens = None
|
||||||
self._media_marker = "<__media__>"
|
|
||||||
|
|
||||||
base_url = (
|
base_url = (
|
||||||
self.genai_config.base_url.rstrip("/")
|
self.genai_config.base_url.rstrip("/")
|
||||||
@ -143,13 +141,6 @@ class LlamaCppClient(GenAIClient):
|
|||||||
chat_caps = props.get("chat_template_caps", {})
|
chat_caps = props.get("chat_template_caps", {})
|
||||||
self._supports_tools = chat_caps.get("supports_tools", False)
|
self._supports_tools = chat_caps.get("supports_tools", False)
|
||||||
|
|
||||||
# Media marker for multimodal embeddings; the server randomizes this
|
|
||||||
# per startup unless LLAMA_MEDIA_MARKER is set, so we must read it
|
|
||||||
# from /props rather than hardcoding "<__media__>".
|
|
||||||
media_marker = props.get("media_marker")
|
|
||||||
if isinstance(media_marker, str) and media_marker:
|
|
||||||
self._media_marker = media_marker
|
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
"llama.cpp model '%s' initialized — context: %s, vision: %s, audio: %s, tools: %s",
|
"llama.cpp model '%s' initialized — context: %s, vision: %s, audio: %s, tools: %s",
|
||||||
configured_model,
|
configured_model,
|
||||||
@ -474,11 +465,10 @@ class LlamaCppClient(GenAIClient):
|
|||||||
jpeg_bytes = _to_jpeg(img)
|
jpeg_bytes = _to_jpeg(img)
|
||||||
to_encode = jpeg_bytes if jpeg_bytes is not None else img
|
to_encode = jpeg_bytes if jpeg_bytes is not None else img
|
||||||
encoded = base64.b64encode(to_encode).decode("utf-8")
|
encoded = base64.b64encode(to_encode).decode("utf-8")
|
||||||
# prompt_string must contain the server's media marker placeholder.
|
# prompt_string must contain <__media__> placeholder for image tokenization
|
||||||
# The marker is randomized per server startup (read from /props).
|
|
||||||
content.append(
|
content.append(
|
||||||
{
|
{
|
||||||
"prompt_string": f"{self._media_marker}\n",
|
"prompt_string": "<__media__>\n",
|
||||||
"multimodal_data": [encoded], # type: ignore[dict-item]
|
"multimodal_data": [encoded], # type: ignore[dict-item]
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@ -24,7 +24,7 @@ from frigate.config.camera.updater import (
|
|||||||
)
|
)
|
||||||
from frigate.const import PROCESS_PRIORITY_HIGH
|
from frigate.const import PROCESS_PRIORITY_HIGH
|
||||||
from frigate.log import LogPipe
|
from frigate.log import LogPipe
|
||||||
from frigate.util.builtin import EventsPerSecond, get_ffmpeg_arg_list
|
from frigate.util.builtin import EventsPerSecond
|
||||||
from frigate.util.ffmpeg import start_or_restart_ffmpeg, stop_ffmpeg
|
from frigate.util.ffmpeg import start_or_restart_ffmpeg, stop_ffmpeg
|
||||||
from frigate.util.image import (
|
from frigate.util.image import (
|
||||||
FrameManager,
|
FrameManager,
|
||||||
@ -34,23 +34,6 @@ from frigate.util.process import FrigateProcess
|
|||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
# all built-in record presets use this segment_time
|
|
||||||
DEFAULT_RECORD_SEGMENT_TIME = 10
|
|
||||||
|
|
||||||
|
|
||||||
def _get_record_segment_time(config: CameraConfig) -> int:
|
|
||||||
"""Extract -segment_time from the camera's record output args."""
|
|
||||||
record_args = get_ffmpeg_arg_list(config.ffmpeg.output_args.record)
|
|
||||||
|
|
||||||
if record_args and record_args[0].startswith("preset"):
|
|
||||||
return DEFAULT_RECORD_SEGMENT_TIME
|
|
||||||
|
|
||||||
try:
|
|
||||||
idx = record_args.index("-segment_time")
|
|
||||||
return int(record_args[idx + 1])
|
|
||||||
except (ValueError, IndexError):
|
|
||||||
return DEFAULT_RECORD_SEGMENT_TIME
|
|
||||||
|
|
||||||
|
|
||||||
def capture_frames(
|
def capture_frames(
|
||||||
ffmpeg_process: sp.Popen[Any],
|
ffmpeg_process: sp.Popen[Any],
|
||||||
@ -181,12 +164,6 @@ class CameraWatchdog(threading.Thread):
|
|||||||
self.latest_cache_segment_time: float = 0
|
self.latest_cache_segment_time: float = 0
|
||||||
self.record_enable_time: datetime | None = None
|
self.record_enable_time: datetime | None = None
|
||||||
|
|
||||||
# `valid` segments are published with the segment's start time, so the
|
|
||||||
# gap between consecutive publishes can reach 2 * segment_time. Pad the
|
|
||||||
# staleness threshold so it's never tighter than that worst case.
|
|
||||||
segment_time = _get_record_segment_time(self.config)
|
|
||||||
self.record_stale_threshold = max(120, 2 * segment_time + 30)
|
|
||||||
|
|
||||||
# Stall tracking (based on last processed frame)
|
# Stall tracking (based on last processed frame)
|
||||||
self._stall_timestamps: deque[float] = deque()
|
self._stall_timestamps: deque[float] = deque()
|
||||||
self._stall_active: bool = False
|
self._stall_active: bool = False
|
||||||
@ -436,17 +413,16 @@ class CameraWatchdog(threading.Thread):
|
|||||||
|
|
||||||
# ensure segments are still being created and that they have valid video data
|
# ensure segments are still being created and that they have valid video data
|
||||||
# Skip checks during grace period to allow segments to start being created
|
# Skip checks during grace period to allow segments to start being created
|
||||||
stale_window = timedelta(seconds=self.record_stale_threshold)
|
|
||||||
cache_stale = not in_grace_period and now_utc > (
|
cache_stale = not in_grace_period and now_utc > (
|
||||||
latest_cache_dt + stale_window
|
latest_cache_dt + timedelta(seconds=120)
|
||||||
)
|
)
|
||||||
valid_stale = not in_grace_period and now_utc > (
|
valid_stale = not in_grace_period and now_utc > (
|
||||||
latest_valid_dt + stale_window
|
latest_valid_dt + timedelta(seconds=120)
|
||||||
)
|
)
|
||||||
invalid_stale_condition = (
|
invalid_stale_condition = (
|
||||||
self.latest_invalid_segment_time > 0
|
self.latest_invalid_segment_time > 0
|
||||||
and not in_grace_period
|
and not in_grace_period
|
||||||
and now_utc > (latest_invalid_dt + stale_window)
|
and now_utc > (latest_invalid_dt + timedelta(seconds=120))
|
||||||
and self.latest_valid_segment_time
|
and self.latest_valid_segment_time
|
||||||
<= self.latest_invalid_segment_time
|
<= self.latest_invalid_segment_time
|
||||||
)
|
)
|
||||||
@ -463,7 +439,7 @@ class CameraWatchdog(threading.Thread):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.logger.error(
|
self.logger.error(
|
||||||
f"{reason} for {self.config.name} in the last {self.record_stale_threshold}s. Restarting the ffmpeg record process..."
|
f"{reason} for {self.config.name} in the last 120s. Restarting the ffmpeg record process..."
|
||||||
)
|
)
|
||||||
p["process"] = start_or_restart_ffmpeg(
|
p["process"] = start_or_restart_ffmpeg(
|
||||||
p["cmd"],
|
p["cmd"],
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user