Commit a995cec
committed
onvif: Major overhaul of ONVIF support
Makes the ONVIF driver usable end-to-end against real-world cameras
(including budget Xiongmai/XM-chipset firmwares that are loose with the
spec), and adds WS-Discovery as a first-class entry path so users no
longer have to type host/port by hand.
Bug fixes
---------
- absoluteMove() / relativeMove() declared pan/tilt/zoom as int,
truncating the normalized doubles to 0 or 1 and breaking every
absolute/relative move.
- Drop the Basic auth Authorization header on every SOAP request. The
WS-UsernameToken in the envelope already authenticates and some
firmwares rejected the duplicate as ambiguous.
- Default port changed from 8899 to 80 (more common ONVIF default).
- sendRequest() bails out early on an empty URL instead of letting Qt
emit `Protocol "" is unknown` once per command when an operation
fires before GetCapabilities has populated the per-service XAddrs.
- Per-request transfer timeout (10s) so failures surface in seconds
instead of waiting the OS TCP timeout (~2 min).
- Sanitize unescaped `&` inside SOAP body text before parsing. ONVIF
cameras commonly emit `&protocol=` / `&channel=` etc. in stream URIs,
which Python's lenient parser tolerates but Qt's QDomDocument
rejects, dropping the whole document.
Preset save
-----------
SetPreset's response carries the camera-assigned PresetToken; the old
code ignored it, so memory_recall() never had a valid token to send
back. We now remember which slot triggered the SetPreset and apply the
new token to that slot when the response arrives. memory_reset() also
clears the stale local token after RemovePreset.
Clock-skew handling
-------------------
connectCamera() now starts with GetSystemDateAndTime (an
unauthenticated call per spec), computes the offset between camera and
host clocks, and adjusts every WS-Security `Created` timestamp by it.
Cameras with bad NTP no longer reject our calls as out-of-window.
ensureCapabilitiesRequested() makes GetCapabilities still happen if the
time probe errors out, so the device doesn't stay un-initialized.
Stale XAddr host rewrites
-------------------------
Some firmwares advertise their static/DHCP IP in WS-Discovery XAddrs
and in GetCapabilities responses even when reached via a different
address (NAT, multi-homed, IP changed since boot, etc.). We now
override the host of any XAddr that doesn't match the
responder/configured host with the address we know works — both in the
WS-Discovery parse and in handleGetCapabilitiesResponse.
Connection status + auto-reconnect
----------------------------------
PTZOnvif now calls setConnected() on every success/failure, so the
dock's red/green dot reflects reality. After 3 consecutive failures
(~15s), the device is marked disconnected and the next status-timer
tick restarts the full connect chain from GetSystemDateAndTime — so a
camera reboot or a network blip recovers without user intervention.
GetStatus polling
-----------------
A 5s timer polls GetStatus while connected, keeping cached pan/tilt/
zoom position in sync with the camera. The same timer drives the
reconnect retry when disconnected.
WS-Discovery + selection dialog
-------------------------------
Adding an ONVIF device now pops a dialog that:
- Sends a SOAP-over-UDP Probe to 239.255.255.250:3702 from every
suitable interface (so multi-homed hosts find cameras on every LAN).
- Lists discovered cameras with host/port/manufacturer/model parsed
from the response Scopes.
- Provides a manual-add row for cameras the multicast probe can't
reach (different subnet, multicast-blocked LAN, etc.).
- Fetches per-profile RTSP stream URIs via GetCapabilities →
GetProfiles → GetStreamUri, with the same clock-skew handling as the
runtime driver and a SOAP-fault surface so auth/credential failures
produce a readable error.
- Supports anonymous probing for cameras that don't require auth
(empty password ⇒ skip WS-Security header entirely).
- Has a stream selector for which profile's URL to use when
auto-creating a Media Source.
- Optionally auto-creates an OBS Media Source from the picked stream
URI, with the user's credentials embedded as Basic auth so it
survives token expiry.
Other new features
------------------
- Media profile combo in the device settings; persists across reloads.
- Imaging service: continuous focus moves + AutoFocusMode toggle, and
WhiteBalance mode (AUTO/MANUAL). Focus is wired through PTZDevice's
focus_changed and only fires on cameras that advertise an Imaging
XAddr.
- Per-device speed multiplier slider (0.1..10.0) for cameras that
accept ONVIF velocities above the spec maximum.
- SetHomePosition via right-click on the dock's Home button. Gated by
a new virtual supportsSetHome() (default false), so VISCA/Pelco/USB
devices show no menu and behavior there is unchanged.
Signed-off-by: Jonatã Bolzan Loss <jonata@jonata.org>1 parent 97980d2 commit a995cec
10 files changed
Lines changed: 1702 additions & 26 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
125 | 125 | | |
126 | 126 | | |
127 | 127 | | |
128 | | - | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
129 | 136 | | |
130 | 137 | | |
131 | 138 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
39 | 39 | | |
40 | 40 | | |
41 | 41 | | |
| 42 | + | |
42 | 43 | | |
43 | 44 | | |
44 | 45 | | |
| |||
75 | 76 | | |
76 | 77 | | |
77 | 78 | | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
78 | 104 | | |
79 | 105 | | |
80 | 106 | | |
| |||
0 commit comments