From 181b53a55d5377366ecb99b1d312b286146576b8 Mon Sep 17 00:00:00 2001 From: Sergey Krashevich Date: Mon, 15 May 2023 15:37:34 +0300 Subject: [PATCH 1/5] Fix error in parsing DeepStack response JSON and handle cases where predictions field is missing (#6463) --- frigate/detectors/plugins/deepstack.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frigate/detectors/plugins/deepstack.py b/frigate/detectors/plugins/deepstack.py index 716065903..9d2c69540 100644 --- a/frigate/detectors/plugins/deepstack.py +++ b/frigate/detectors/plugins/deepstack.py @@ -56,8 +56,11 @@ class DeepStack(DetectionApi): ) response_json = response.json() detections = np.zeros((20, 6), np.float32) + if response_json.get("predictions") is None: + logger.debug(f"Error in parsing response json: {response_json}") + return detections - for i, detection in enumerate(response_json["predictions"]): + for i, detection in enumerate(response_json.get("predictions")): logger.debug(f"Response: {detection}") if detection["confidence"] < 0.4: logger.debug(f"Break due to confidence < 0.4") From 5fb96c777a9c4faeac44942f3f5a638e9bee5299 Mon Sep 17 00:00:00 2001 From: Sergey Krashevich Date: Mon, 15 May 2023 15:39:03 +0300 Subject: [PATCH 2/5] Add cmdline information to CPU usage stats in get_cpu_stats() function and display it in the System page's ffmpeg table with a copy-to-clipboard button (#6430) --- frigate/util.py | 4 +++- web/src/routes/System.jsx | 10 +++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/frigate/util.py b/frigate/util.py index d98cee106..a6b4c912a 100755 --- a/frigate/util.py +++ b/frigate/util.py @@ -800,10 +800,11 @@ def get_cpu_stats() -> dict[str, dict]: docker_memlimit = get_docker_memlimit_bytes() / 1024 total_mem = os.sysconf("SC_PAGE_SIZE") * os.sysconf("SC_PHYS_PAGES") / 1024 - for process in psutil.process_iter(["pid", "name", "cpu_percent"]): + for process in psutil.process_iter(["pid", "name", "cpu_percent", "cmdline"]): pid = process.info["pid"] try: cpu_percent = process.info["cpu_percent"] + cmdline = process.info["cmdline"] with open(f"/proc/{pid}/stat", "r") as f: stats = f.readline().split() @@ -837,6 +838,7 @@ def get_cpu_stats() -> dict[str, dict]: "cpu": str(cpu_percent), "cpu_average": str(round(cpu_average_usage, 2)), "mem": f"{mem_pct}", + "cmdline": " ".join(cmdline), } except: continue diff --git a/web/src/routes/System.jsx b/web/src/routes/System.jsx index 7ec238596..b6d78dd54 100644 --- a/web/src/routes/System.jsx +++ b/web/src/routes/System.jsx @@ -347,7 +347,15 @@ export default function System() { - ffmpeg + ffmpeg + + {cameras[camera]['ffmpeg_pid'] || '- '} {cameras[camera]['camera_fps'] || '- '} {cpu_usages[cameras[camera]['ffmpeg_pid']]?.['cpu'] || '- '}% From b4038821cc3e18e21bd3b5ed684a59bce62a258f Mon Sep 17 00:00:00 2001 From: Sergey Krashevich Date: Wed, 17 May 2023 15:40:41 +0300 Subject: [PATCH 3/5] Update DeepStack detector to set width and height from input image size (#6429) --- frigate/detectors/plugins/deepstack.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/frigate/detectors/plugins/deepstack.py b/frigate/detectors/plugins/deepstack.py index 9d2c69540..9f3d323a2 100644 --- a/frigate/detectors/plugins/deepstack.py +++ b/frigate/detectors/plugins/deepstack.py @@ -33,9 +33,6 @@ class DeepStack(DetectionApi): self.api_key = detector_config.api_key self.labels = detector_config.model.merged_labelmap - self.h = detector_config.model.height - self.w = detector_config.model.width - def get_label_index(self, label_value): if label_value.lower() == "truck": label_value = "car" @@ -47,6 +44,7 @@ class DeepStack(DetectionApi): def detect_raw(self, tensor_input): image_data = np.squeeze(tensor_input).astype(np.uint8) image = Image.fromarray(image_data) + self.w, self.h = image.size with io.BytesIO() as output: image.save(output, format="JPEG") image_bytes = output.getvalue() From b568a29fa8eb24e46b9ba623c10016689de7ec20 Mon Sep 17 00:00:00 2001 From: Nicolas Mowen Date: Wed, 17 May 2023 06:42:56 -0600 Subject: [PATCH 4/5] Don't fail if camera does not support presets (#6497) --- frigate/ptz.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frigate/ptz.py b/frigate/ptz.py index e2c21618e..a52006b5c 100644 --- a/frigate/ptz.py +++ b/frigate/ptz.py @@ -79,8 +79,8 @@ class OnvifController: try: presets: list[dict] = ptz.GetPresets({"ProfileToken": profile.token}) except ONVIFError as e: - logger.error(f"Unable to get presets from camera: {camera_name}: {e}") - return False + logger.warning(f"Unable to get presets from camera: {camera_name}: {e}") + presets = [] for preset in presets: self.cams[camera_name]["presets"][preset["Name"].lower()] = preset["token"] From 17e8a46c7d1d164715a5f4e0db18efcd5bd1a8c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Korneliusz=20Jarz=C4=99bski?= Date: Thu, 18 May 2023 03:01:56 +0200 Subject: [PATCH 5/5] add ffmpeg bandwidth stats (#6492) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add ffmpeg bandwidth stats * add ffmpeg bandwidth stats * Change column name Co-authored-by: Nicolas Mowen * fix lint formatting --------- Co-authored-by: Korneliusz Jarzębski Co-authored-by: Nicolas Mowen --- docker/install_deps.sh | 3 ++- frigate/stats.py | 11 ++++++++++- frigate/util.py | 29 +++++++++++++++++++++++++++++ web/src/routes/System.jsx | 5 +++++ 4 files changed, 46 insertions(+), 2 deletions(-) diff --git a/docker/install_deps.sh b/docker/install_deps.sh index 9a0e80dfe..3443329dd 100755 --- a/docker/install_deps.sh +++ b/docker/install_deps.sh @@ -12,7 +12,8 @@ apt-get -qq install --no-install-recommends -y \ unzip locales tzdata libxml2 xz-utils \ python3-pip \ curl \ - jq + jq \ + nethogs mkdir -p -m 600 /root/.gnupg diff --git a/frigate/stats.py b/frigate/stats.py index 4287dab0c..55db809d3 100644 --- a/frigate/stats.py +++ b/frigate/stats.py @@ -16,7 +16,7 @@ from frigate.const import DRIVER_AMD, DRIVER_ENV_VAR, RECORD_DIR, CLIPS_DIR, CAC from frigate.types import StatsTrackingTypes, CameraMetricsTypes from frigate.util import get_amd_gpu_stats, get_intel_gpu_stats, get_nvidia_gpu_stats from frigate.version import VERSION -from frigate.util import get_cpu_stats +from frigate.util import get_cpu_stats, get_bandwidth_stats from frigate.object_detection import ObjectDetectProcess logger = logging.getLogger(__name__) @@ -101,6 +101,7 @@ def get_processing_stats( [ asyncio.create_task(set_gpu_stats(config, stats, hwaccel_errors)), asyncio.create_task(set_cpu_stats(stats)), + asyncio.create_task(set_bandwidth_stats(stats)), ] ) @@ -118,6 +119,14 @@ async def set_cpu_stats(all_stats: dict[str, Any]) -> None: all_stats["cpu_usages"] = cpu_stats +async def set_bandwidth_stats(all_stats: dict[str, Any]) -> None: + """Set bandwidth from nethogs.""" + bandwidth_stats = get_bandwidth_stats() + + if bandwidth_stats: + all_stats["bandwidth_usages"] = bandwidth_stats + + async def set_gpu_stats( config: FrigateConfig, all_stats: dict[str, Any], hwaccel_errors: list[str] ) -> None: diff --git a/frigate/util.py b/frigate/util.py index a6b4c912a..f82476ebc 100755 --- a/frigate/util.py +++ b/frigate/util.py @@ -846,6 +846,35 @@ def get_cpu_stats() -> dict[str, dict]: return usages +def get_bandwidth_stats() -> dict[str, dict]: + """Get bandwidth usages for each ffmpeg process id""" + usages = {} + top_command = ["nethogs", "-t", "-v0", "-c5", "-d1"] + + p = sp.run( + top_command, + encoding="ascii", + capture_output=True, + ) + + if p.returncode != 0: + return usages + else: + lines = p.stdout.split("\n") + for line in lines: + stats = list(filter(lambda a: a != "", line.strip().split("\t"))) + try: + if re.search("^ffmpeg/([0-9]+)/", stats[0]): + process = stats[0].split("/") + usages[process[1]] = { + "bandwidth": round(float(stats[2]), 1), + } + except: + continue + + return usages + + def get_amd_gpu_stats() -> dict[str, str]: """Get stats using radeontop.""" radeontop_command = ["radeontop", "-d", "-", "-l", "1"] diff --git a/web/src/routes/System.jsx b/web/src/routes/System.jsx index b6d78dd54..8d5c4ef80 100644 --- a/web/src/routes/System.jsx +++ b/web/src/routes/System.jsx @@ -27,6 +27,7 @@ export default function System() { const { cpu_usages, gpu_usages, + bandwidth_usages, detectors, service = {}, detection_fps: _, @@ -343,6 +344,7 @@ export default function System() { FPS CPU % Memory % + Network Bandwidth @@ -360,6 +362,7 @@ export default function System() { {cameras[camera]['camera_fps'] || '- '} {cpu_usages[cameras[camera]['ffmpeg_pid']]?.['cpu'] || '- '}% {cpu_usages[cameras[camera]['ffmpeg_pid']]?.['mem'] || '- '}% + {bandwidth_usages[cameras[camera]['ffmpeg_pid']]?.['bandwidth'] || '- '}KB/s Capture @@ -367,6 +370,7 @@ export default function System() { {cameras[camera]['process_fps'] || '- '} {cpu_usages[cameras[camera]['capture_pid']]?.['cpu'] || '- '}% {cpu_usages[cameras[camera]['capture_pid']]?.['mem'] || '- '}% + - Detect @@ -387,6 +391,7 @@ export default function System() { {cpu_usages[cameras[camera]['pid']]?.['cpu'] || '- '}% {cpu_usages[cameras[camera]['pid']]?.['mem'] || '- '}% + -