mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-10-12 09:42:47 +03:00
Compare commits
4
Commits
analytics
...
f3656a5043
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f3656a5043 | ||
|
|
9443289112 | ||
|
|
40f8ba1f7f | ||
|
|
397f5253a5 |
@@ -27,7 +27,7 @@ pydantic == 2.10.*
|
|||||||
git+https://github.com/fbcotter/py3nvml#egg=py3nvml
|
git+https://github.com/fbcotter/py3nvml#egg=py3nvml
|
||||||
pytz == 2025.*
|
pytz == 2025.*
|
||||||
pyzmq == 27.1.*
|
pyzmq == 27.1.*
|
||||||
ruamel.yaml == 0.18.*
|
ruamel.yaml == 0.19.*
|
||||||
tzlocal == 5.2
|
tzlocal == 5.2
|
||||||
requests == 2.33.*
|
requests == 2.33.*
|
||||||
types-requests == 2.32.*
|
types-requests == 2.32.*
|
||||||
@@ -43,9 +43,9 @@ opencv-contrib-python == 4.11.0.*
|
|||||||
scipy == 1.16.*
|
scipy == 1.16.*
|
||||||
# OpenVino & ONNX
|
# OpenVino & ONNX
|
||||||
openvino == 2025.4.*
|
openvino == 2025.4.*
|
||||||
onnxruntime == 1.22.*
|
onnxruntime == 1.30.*
|
||||||
# Embeddings
|
# Embeddings
|
||||||
transformers == 4.45.*
|
transformers == 5.17.*
|
||||||
# Generative AI
|
# Generative AI
|
||||||
google-genai == 1.58.*
|
google-genai == 1.58.*
|
||||||
ollama == 0.6.*
|
ollama == 0.6.*
|
||||||
@@ -58,7 +58,7 @@ pyclipper == 1.4.*
|
|||||||
shapely == 2.0.*
|
shapely == 2.0.*
|
||||||
rapidfuzz==3.12.*
|
rapidfuzz==3.12.*
|
||||||
# HailoRT
|
# HailoRT
|
||||||
argcomplete==2.0.*
|
argcomplete==3.7.*
|
||||||
contextlib2==0.6.*
|
contextlib2==0.6.*
|
||||||
future==0.18.*
|
future==0.18.*
|
||||||
netaddr==1.3.*
|
netaddr==1.3.*
|
||||||
|
|||||||
@@ -36,6 +36,31 @@ class TestEventsPerSecond(unittest.TestCase):
|
|||||||
clock[0] += 100.0
|
clock[0] += 100.0
|
||||||
self.assertEqual(eps.eps(), 0.0)
|
self.assertEqual(eps.eps(), 0.0)
|
||||||
|
|
||||||
|
def test_burst_after_start_is_not_divided_by_a_tiny_window(self) -> None:
|
||||||
|
eps = EventsPerSecond(last_n_seconds=10)
|
||||||
|
clock = [1000.0]
|
||||||
|
with patch("frigate.util.builtin.time.monotonic", side_effect=lambda: clock[0]):
|
||||||
|
eps.start()
|
||||||
|
# eleven buffered frames arrive within 100 ms of starting
|
||||||
|
for _ in range(11):
|
||||||
|
clock[0] += 0.01
|
||||||
|
eps.update()
|
||||||
|
# 11 events over less than a second is at most 11 per second
|
||||||
|
self.assertLessEqual(eps.eps(), 11.0)
|
||||||
|
|
||||||
|
def test_subsecond_window_keeps_its_rate(self) -> None:
|
||||||
|
eps = EventsPerSecond(last_n_seconds=0.5)
|
||||||
|
clock = [1000.0]
|
||||||
|
with patch("frigate.util.builtin.time.monotonic", side_effect=lambda: clock[0]):
|
||||||
|
eps.start()
|
||||||
|
# twenty events per second for two seconds
|
||||||
|
for _ in range(40):
|
||||||
|
clock[0] += 0.05
|
||||||
|
eps.update()
|
||||||
|
# read between events, so none sits exactly on the window edge
|
||||||
|
clock[0] += 0.01
|
||||||
|
self.assertAlmostEqual(eps.eps(), 20.0)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|||||||
@@ -56,10 +56,13 @@ class EventsPerSecond:
|
|||||||
self._start = now
|
self._start = now
|
||||||
# compute the (approximate) events in the last n seconds
|
# compute the (approximate) events in the last n seconds
|
||||||
self.expire_timestamps(now)
|
self.expire_timestamps(now)
|
||||||
seconds = min(now - self._start, self._last_n_seconds)
|
# rate over at least one second (or the whole window, if shorter),
|
||||||
# avoid divide by zero
|
# so a burst of events right after start() is not divided by a
|
||||||
if seconds == 0:
|
# tiny window
|
||||||
seconds = 1
|
seconds = max(
|
||||||
|
min(now - self._start, self._last_n_seconds),
|
||||||
|
min(1.0, self._last_n_seconds),
|
||||||
|
)
|
||||||
return len(self._timestamps) / seconds
|
return len(self._timestamps) / seconds
|
||||||
|
|
||||||
# remove aged out timestamps
|
# remove aged out timestamps
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useCallback, useMemo, useRef, useState } from "react";
|
import { useCallback, useMemo, useRef, useState } from "react";
|
||||||
import { LuFolderX } from "react-icons/lu";
|
import { LuFolderX } from "react-icons/lu";
|
||||||
import { isMobileOnly, isSafari } from "react-device-detect";
|
import { isMobileOnly } from "react-device-detect";
|
||||||
import { LuPause, LuPlay } from "react-icons/lu";
|
import { LuPause, LuPlay } from "react-icons/lu";
|
||||||
import {
|
import {
|
||||||
DropdownMenu,
|
DropdownMenu,
|
||||||
@@ -54,7 +54,7 @@ const CONTROLS_DEFAULT: VideoControls = {
|
|||||||
snapshot: false,
|
snapshot: false,
|
||||||
fullscreen: false,
|
fullscreen: false,
|
||||||
};
|
};
|
||||||
const PLAYBACK_RATE_DEFAULT = isSafari ? [0.5, 1, 2] : [0.5, 1, 2, 4, 8, 16];
|
const PLAYBACK_RATE_DEFAULT = [0.5, 1, 2, 4, 8, 16];
|
||||||
const MIN_ITEMS_WRAP = 6;
|
const MIN_ITEMS_WRAP = 6;
|
||||||
|
|
||||||
type VideoControlsProps = {
|
type VideoControlsProps = {
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import {
|
|||||||
useUserPersistence,
|
useUserPersistence,
|
||||||
deleteUserNamespacedKey,
|
deleteUserNamespacedKey,
|
||||||
} from "@/hooks/use-user-persistence";
|
} from "@/hooks/use-user-persistence";
|
||||||
import { isSafari } from "react-device-detect";
|
|
||||||
import {
|
import {
|
||||||
Select,
|
Select,
|
||||||
SelectContent,
|
SelectContent,
|
||||||
@@ -132,7 +131,7 @@ export default function UiSettingsView() {
|
|||||||
const { auth } = useContext(AuthContext);
|
const { auth } = useContext(AuthContext);
|
||||||
const username = auth?.user?.username;
|
const username = auth?.user?.username;
|
||||||
|
|
||||||
const PLAYBACK_RATE_DEFAULT = isSafari ? [0.5, 1, 2] : [0.5, 1, 2, 4, 8, 16];
|
const PLAYBACK_RATE_DEFAULT = [0.5, 1, 2, 4, 8, 16];
|
||||||
|
|
||||||
const clearStoredLayouts = useCallback(() => {
|
const clearStoredLayouts = useCallback(() => {
|
||||||
if (!config) {
|
if (!config) {
|
||||||
|
|||||||
Reference in New Issue
Block a user