Commit Graph

184 Commits

Author SHA1 Message Date
Isaac Connor
e8b5c4962e Convert warning to debug 2026-02-23 18:16:56 -05:00
Isaac Connor
47edcca6ab fix: fall back to pixel parsing when zone Units=Percent but coords exceed 100
When zones have Units='Percent' in the database but their Coords contain
pixel values (>100), ParsePercentagePolygon treats them as percentages,
causing wild scaling (e.g., 639% * 1920 / 100 = 12269) followed by
clamping to monitor bounds, producing degenerate full-frame zones.

Add a pre-check in Zone::Load that scans coordinate values before calling
ParsePercentagePolygon. If any value exceeds 100, log a warning and use
ParsePolygonString (pixel path) instead. Also add unit tests for both
ParsePolygonString and ParsePercentagePolygon.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 18:16:55 -05:00
Isaac Connor
995b60db80 fix: use int instead of unsigned int for zone pixel coordinates in zm_zone.cpp
The lo_x/lo_y/hi_x/hi_y variables were unsigned int despite being assigned
from signed int32 Vector2 members and compared against signed int dimensions.
This caused scattered (int) and (unsigned int) casts throughout CheckAlarms,
std_alarmedpixels, and Setup. Switching to int eliminates the casts, fixes
the signed/unsigned comparison warnings, and makes the -1 sentinel check in
std_alarmedpixels explicit rather than relying on unsigned wraparound.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 18:16:55 -05:00
Isaac Connor
2013339b1e fix: clamp zone polygon extents to actual frame dimensions in CheckAlarms
When a camera reconnects at a different resolution than the zone polygons
were configured for, the polygon bounding box can exceed the frame
dimensions. This caused a heap buffer overflow in the memset that zeros
the bbox rows of the diff image, confirmed by Valgrind (invalid write
at 0 bytes past a 921600-byte / 1280x720 block).

- Validate delta_image buffer and dimensions at entry
- Clamp hi_y/hi_x to image height/width before memset and pixel loops
- Guard filter, blob, and HighlightEdges loops against empty rows where
  ranges[y].lo_x is -1 (would wrap to UINT_MAX as unsigned)
- Clamp extents in std_alarmedpixels independently for defense in depth

Warning() logs identify which zones need polygon reconfiguration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 18:16:55 -05:00
Isaac Connor
3e067f18b2 feat: store zone coordinates as percentages for resolution independence (src only)
Cherry-picked src/ changes from edge branch commit 17450d122.
Adds ParsePercentagePolygon() to convert percentage-based zone coordinates
to pixel values using monitor dimensions. Zone::Load() now checks the Units
column to dispatch between legacy pixel parsing and percentage-based parsing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 18:06:56 -05:00
Isaac Connor
31aa65bd11 perf: split delta/mask buffers in CheckAlarms to eliminate full-image copy
Instead of copying the entire delta_image into the per-zone mask buffer
every frame (4MB memcpy for 4MP), allocate a persistent grayscale mask
and only zero the polygon bounding-box rows.  alarmedpixels_row now
reads from delta_image (const, read-only) and writes threshold results
to the separate mask buffer.

Key changes:
- alarmedpixels_row takes separate pdelta (read) and pmask (write) pointers
- std_alarmedpixels accepts both delta_image (const) and mask_image
- CheckAlarms allocates mask with explicit linesize == width to match
  filter/blob pointer arithmetic (avoids FFALIGN padding mismatch)
- Full buffer zero on allocation; bbox-only zero on reuse
- No functional change to filter, blob, or HighlightEdges stages

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 17:41:50 -05:00
Isaac Connor
8b3ed97fa4 perf: auto-vectorize alarmedpixels loop for SIMD on all platforms
Restructure std_alarmedpixels inner loop so GCC/Clang can auto-vectorize
it at -O2/-O3. The compiler now emits 16-byte SIMD (SSE2/NEON) processing
16 pixels per iteration instead of 1.

Three changes enable this:
- Extract inner loop into static alarmedpixels_row() with __restrict__
  on function parameters, giving the compiler a strong no-alias guarantee
- Use branchless bitwise AND instead of short-circuit && to avoid
  branches that block vectorization
- Remove per-row Debug(7) call that clobbered memory from the compiler's
  perspective, invalidating pointer analysis

The original hand-written SSE2 ASM (removed in 2011, commit 8e9ccfe1e)
had alignment restrictions and didn't use per-row polygon ranges. This
approach is portable, maintainable, and achieves equivalent throughput.

GCC confirms: "loop vectorized using 16 byte vectors"

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 14:36:13 -05:00
Nic Boet
5fde4e5deb perf: reuse diff image buffer in Zone::CheckAlarms
Replace delete/new Image cycle with lazy-alloc + Assign(). When the
buffer already exists (every frame after the first), Assign() detects
matching dimensions and does a plain memcpy into the existing
allocation, eliminating an aligned malloc+free of ~2 MB per zone per
analyzed frame.

With 4 zones at 15 fps this removes 60 alloc/free cycles per second
from the analysis hot path. The HighlightEdges code path (analysis
images) still allocates a new Image and deletes the old diff buffer,
which is correct — the next Assign() will reallocate once to restore
the single-channel format, then resume reuse.

Behaviorally equivalent: Zone dimensions are constant during zone
lifetime, the destructor already handles cleanup via delete image,
and the only external consumer (Monitor::Analyse → AlarmImage →
Overlay) reads the image without storing pointers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 19:25:58 -06:00
Isaac Connor
a96b776949 fix: apply credentials to secondary URL and fix buffer overflow in DumpSettings
- Apply credentials to secondary stream URL in FFmpegCamera (was causing 401 Unauthorized)
- Add empty check for rtsp_second_path in RTSP2WebManager before applying credentials
- Replace unsafe sprintf pattern in Monitor::DumpSettings with std::string + stringtf
- Refactor Zone::DumpSettings to return std::string instead of writing to char buffer
- Add decimal precision to event duration debug output

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 17:40:26 -05:00
Steve Gilvarry
1b527c1b62 Remove unused row index in zone load loop 2025-12-31 22:18:32 +11:00
Aaron Kling
c4683d90a9 Format code using astyle google format
Commands used:
astyle --style=google --indent=spaces=2 --keep-one-line-blocks src/*.cpp
astyle --style=google --indent=spaces=2 --keep-one-line-blocks src/*.h
2024-03-26 13:43:58 -05:00
Isaac Connor
4993a55b14 Move declaration of zones down to where it is used 2024-02-07 15:56:24 -05:00
Isaac Connor
d0ca677207 Fix %u instead of %d for id which is unsigned. Pass string instead of c_str 2022-07-14 12:07:26 -04:00
Isaac Connor
9093a8694b Fix crashes. Zones should use const for monitor object and not references. 2022-06-07 20:52:39 -04:00
Isaac Connor
07e32025df Just store the linked_monitors string instead of parsing and loading of related objects. Only call ReloadLinkedMonitors if doing analysis. Convert zone id's to unsigned 2022-06-07 18:36:25 -04:00
Isaac Connor
78a87517f6 convert to taking a std::shared_ptr<Monitor> instead of a Monitor *. Implement Name() which just returns the std::string label. 2022-06-07 18:18:24 -04:00
Isaac Connor
e51d3a206f Use auto to get the right type for n_coords 2022-05-18 17:07:06 -04:00
Isaac Connor
b254f990d0 Warn when the number of vertices changes due to clipping 2022-05-17 15:05:25 -04:00
Isaac Connor
3f7b9dfff7 fix cppcheck error about lo_x. Inner scope overwriting it. 2022-01-10 17:36:50 -05:00
Isaac Connor
e8bb095730 include monitor dimensions when logging about zone mismatch 2021-11-24 14:28:31 -05:00
Mike Dussault
d38a6adec4 No behavior change. Added non-const versions of Image::Buffer and fixed a few places that were casting away the constness. 2021-10-12 21:54:49 +00:00
Isaac Connor
b0cf3a4732 Merge pull request #3314 from Carbenium/path-max
Fix Wformat for stringtf and convert path buffers depending on PATH_MAX to std::string
2021-07-07 11:34:03 -04:00
Peter Keresztes Schmidt
80b08a2075 Convert path buffers depending on PATH_MAX to std::string 2021-07-06 10:33:17 +02:00
Peter Keresztes Schmidt
65656de6ce db: Adjust the query methods to accept std::strings 2021-07-06 10:20:46 +02:00
Peter Keresztes Schmidt
c60b577aec Convert more char array buffers to std::string
Remove now unused ZM_SQL_*SIZE defines
2021-07-06 10:20:46 +02:00
Peter Keresztes Schmidt
b1de220958 Polygon: Perform clip operation on existing object instead of returning a new clipped one 2021-05-16 19:42:41 +02:00
Peter Keresztes Schmidt
29488900a1 Box: Make range calculations mathematically correct 2021-05-16 19:41:45 +02:00
Peter Keresztes Schmidt
ef7a083891 Zone: Actually clip the zone if it larger than the image
Until now only the boundary box was manually adjusted without actually clipping the polygon.
2021-05-16 19:41:45 +02:00
Peter Keresztes Schmidt
5af6d6af3d Polygon: Use std::vector to store the vertices 2021-05-16 16:42:58 +02:00
Peter Keresztes Schmidt
8f685b3d66 Box+Poly: Remove direct accessors to {Hi,Lo}{X,Y} 2021-05-16 16:42:58 +02:00
Peter Keresztes Schmidt
e6c159fb70 Vector2: Make coordinate components public
The components were already unconditionally/without side-effects writable. Let's make them public so we don't need the setters.
2021-05-16 16:42:58 +02:00
Peter Keresztes Schmidt
60db1c2eaf Coord: Rename to Vector2
The class is not only used to represent coordinates but also lengths in XY.
Vector2 is a more fitting/general name for this purpose.
2021-05-14 20:14:50 +02:00
Isaac Connor
2cf6ad8089 Switch ZMPacket * to a shared_ptr<ZMPacket>. This is so that in LockedPacket we can unlock and then notify and be confident that packet_ won't have been deleted. Change ZMPacket->timestamp to be a timeval instead of timeval *. This might not have been necessary but I like it. No longer cuse the ZMPacket object to wrap the shared image buffers and timestamps. Use a vector for image_buffers. 2021-05-08 21:14:20 -04:00
Isaac Connor
a91197b47c reset score_ to zero when we return for failing to meet pixel filters 2021-05-07 14:23:36 -04:00
Peter Keresztes Schmidt
4180bc99ac Zone: Sprinkle some const-ness
Keep references in for-loops const if no modifications are preformed on the object.
2021-04-25 22:34:33 +02:00
Peter Keresztes Schmidt
d4458d1216 Monitor: Store zones as vector instead of list
std::vector suits the usage pattern better with no random inserts/deletions
2021-04-25 22:29:18 +02:00
Peter Keresztes Schmidt
ad32a94931 ZoneStats: Rename members according to Google style guide 2021-04-25 17:18:07 +02:00
Isaac Connor
8671e65517 More work on flushing out ZoneStats. Use references to avoid copying 2021-04-21 21:40:39 -04:00
Isaac Connor
be9c5d3f95 Introduce a ZoneStats structure/class and implement a list of them in packet, frame. Store the stats in a list in the packet until it is time to write them to the db in the event. Hence implement batched queuing of stats. 2021-04-21 17:51:43 -04:00
Isaac Connor
c7f06dda0b Improve copy constructor to use initializers 2021-04-20 17:18:57 -04:00
Isaac Connor
e0fc265263 spacing 2021-04-19 13:19:23 -04:00
Isaac Connor
03767236d9 Clean up constructor/Setup functions. Add copy constructor. Change Load to return a std::list<Zone> 2021-04-17 12:50:26 -04:00
Peter Keresztes Schmidt
9e77324de4 Replace raw mysql_query calls with the zmDb* functions
With this we can make sure we have proper locking of our DB connection at all times.
2021-03-06 00:12:18 +01:00
Isaac Connor
8c2e6589ac fifo.h got split into zm_fifo and zm_fifo_debug so update the code in zm_zone 2021-03-01 16:49:27 -05:00
Peter Keresztes Schmidt
76e6c468e8 rgb: Convert some constant defines to constexpr
Using defines interferes with fmt.
Also rename them according to the Google styleguide.
2021-03-01 00:38:21 +01:00
Isaac Connor
8aeb4ab758 Switch db_mutex to a std::mutex. Use modern locking with it. Use zmDbDo or dbQueue.push where appropriate. code cleanup. 2021-02-25 12:26:26 -05:00
Isaac Connor
124d9bf798 Fix logging when holding db lock 2021-02-19 12:09:02 -05:00
Peter Keresztes Schmidt
dd527f0888 Consolidate __STDC_FORMAT_MACROS and __STDC_CONSTANT_MACROS definition
Move the definitions to zm_define.h and include the header at the appropriate locations.
These macros have not been adopted by the C++11 standard.
However glibc 2.17 (CentOS 7) still depends on them to provide the macros which are guarded by these defines.
2021-02-04 19:58:29 +01:00
Peter Keresztes Schmidt
0dbc39ee25 Cleanup and reorganize includes
With this commit a unified structure for includes is introduced.
The general rules:
 * Only include what you need
 * Include wherever possible in the cpp and forward-declare in the header

 The includes are sorted in a local to global fashion. This means for the include order:
  0. If cpp file: The corresponding h file and an empty line
  1. Includes from the project sorted alphabetically
  2. System/library includes sorted alphabetically
  3. Conditional includes
2021-02-04 18:02:01 +01:00
Peter Keresztes Schmidt
e09fa1bebf Remove includes of <cinttypes>
Instead of including <cinttypes> directly, zm_define.h should be used
to get the typedef'ed types as well.
2021-02-02 21:37:26 +01:00