Replies: 1 comment 5 replies
-
|
Thanks for the discussion. Motion boxes in Frigate aren't a simple on/off gate for inference. They seed the detection regions that get cropped and scaled to the detector, so box tightness directly sets the effective resolution for small/distant objects. A 22×18 cell grid is roughly an order of magnitude coarser than the per-pixel contours our internal detector produces on the (already cheap) downscaled motion frame, and it's not tunable. The common fallback paths like binary-only cameras, no metadata track on the substream, and discovery/decode failure, all collapse to a full-frame box, which is the worst case for region seeding. The bigger issue though is alignment. The ONVIF state and cells arrive out-of-band from a separate stream at a different time than the detect frame they'd be used to crop. Internal motion is computed from the exact frame at And I'm not sure the CPU argument holds, detection and inference are the expensive parts of Frigate's pipeline. Internal motion (frame-diff on a ~100px frame) is the cheap part you'd be replacing, while adding a third RTSP/ffmpeg subprocess per camera plus per-frame IPC list marshalling. Curious if the other maintainers have thoughts. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
1. Gap this addresses
onvif:camera block is bound exclusively to PTZ services (media / ptz / imaging infrigate/ptz/onvif.py)._init_onvifshort-circuits at theget_definition("ptz")check (around line 198), so any camera without PTZ effectively cannot use theonvif:block at all — including all the analytics services the rest of the ONVIF Profile-M spec defines.ImprovedMotionDetectorruns on the decoded RTSP stream even when the camera already has hardware motion detection it would happily expose via ONVIF.2. Why this matters
Many modern IP cameras have internal hardware IP blocks, which can efficiently detect motion between frames and help pipelining heavy GPU-based analytics (no motion in frame, no GPU inference is needed).
3. Standards stance
VideoSource/MotionAlarm).tns1:RuleEngine/CellMotionDetector/MotionIsMotion=true|false; also accept the legacytns1:VideoSource/MotionAlarmState=true|falsesince many devices publish both).application/vnd.onvif.metadata) for per-frame cell coordinates (tt:MotionInCells, ONVIF Analytics Spec Annex B — base64 + PackBits, bit-packed row-major bitmap).AnalyticsService.GetAnalyticsModulesusing the token returned byMedia.GetVideoAnalyticsConfigurations— token format is implementation-defined per the WSDL, so it's looked up not assumed.4. Design choices that deserve maintainer input
Each is presented as "chose X over Y because Z — open to redirection".
4.1 Module placement
frigate/ptz/onvif.py— reuses the existing dedicated asyncio loop thread,ONVIFCameraclient lifecycle, dynamic config-reload subscriber.frigate/onvif/package separating non-PTZ ONVIF surface.4.2 Analytics metadata stream consumption
ffmpegsubprocess per enabled camera,-rtsp_transport tcp -map 0:d:0 -c copy -f data pipe:1, parse XML chunks from stdout.aiortsp).application/vnd.onvif.metadatacleanly.4.3 IPC main → camera subprocess
manager.Value("b", 0)+manager.list()fields on existingCameraMetrics. Subscriber (main proc) writes;CameraTracker.process_framesreads.CameraMetricsalready follows this SyncManager-backed shared-state pattern for fps/pid counters; no new IPC surface.4.4 Event delivery model
NotificationConsumer).4.5 Motion-source switch
motion.source: internal | onvifenum onMotionConfig.onvif.events.enabled.onvif.events.enabled=truewhenmotion.source=onvif.4.6 WSSE authentication scheme
OnvifConfig.tls_insecure: false(default) maps topython-onvif-zeep-async'sencrypt=True, which sends WSSE PasswordDigest. A meaningful number of Profile-M devices reject Digest and only accept PasswordText (or HTTP Basic), and the only existing workaround is settingtls_insecure: true— conflating TLS verification with the WSSE auth scheme.PullMessagescall is authenticated.onvif.auth_mode: digest | textfield, or accept thetls_insecureoverload for v1?4.7 Cell-bitmap decoder
cv2.connectedComponentsWithStats.4.8 Topic filter on subscription
IsMotion/StateSimpleItems.Filter.TopicExpressionnarrowing the subscription totns1:RuleEngine/CellMotionDetector/Motion.4.9 Configuration discovery flow
Media.GetVideoAnalyticsConfigurations()→ first config'stoken→Analytics.GetAnalyticsModules({"ConfigurationToken": <token>})→ findtt:CellMotionEnginemodule → extractCellLayout(Columns, Rows, Transformation).4.10 Graceful degradation
vnd.onvif.metadatatrack in the SDP → PullPoint binary state with full-frame motion box.update_xaddrsfinds no analytics service → no events init, internal motion path unchanged.4.11 Lifecycle & backward compatibility
OnvifController.__init__takescamera_metrics: dict[str, CameraMetrics] | None = None. DefaultNonepreserves all existing call sites.stop_event.set()+task.cancel()+asyncio.wait_for(task, 5.0). Bounded so dynamic config reload stays responsive.CameraConfigUpdateEnum.onvifalready exists; the new tasks are torn down + respawned via the existing_close_camera→_init_single_camerachain.5. Known limitations
VideoAnalyticsConfigurationper camera assumed (first discovered is used).CellMotionDetectorrule but their detector implementation never firesIsMotion=true— the integration correctly reflects this as "no motion" rather than working around camera-side bugs.6. Reference implementation
7. Asks for maintainer input
motion.sourceenum onMotionConfigvs deriving fromonvif.events.enabled: 4.5tls_insecureoverload for v1: 4.6P.S. I apologize for the delay, but it’s better late than never.
Beta Was this translation helpful? Give feedback.
All reactions