Commit Graph
258 Commits
Author SHA1 Message Date
Claude 89837a6b40 fix: start the monitor stream socket before capture connects
Address monitor-side stream socket review findings:

- zmc starts the stream socket before the first connect attempt, and
  SendStreamHealthEvent records the health state even when the socket is
  not up yet, so connection/prime faults during startup are observable to
  a consumer instead of being lost until the first successful prime.
- PrimeCapture announces audio whenever the camera has a decodable audio
  stream (Capture forwards audio packets unconditionally), and clears a
  previously announced stream when a re-prime no longer sees it.
- Publish the media stream socket path in the monitor shared-memory
  block (reusing the retired video_fifo_path field as stream_socket_path,
  same offset and size) so consumers discover it without hard-coding the
  convention or reading the producer's zm.conf; the PHP Monitor object
  and the ZoneMinder::Memory Perl module expose the renamed field.
- Move the wall-clock microseconds helper out of zm_monitor.cpp into
  zm_time.h as SystemClockMicros(), where time helpers belong.

refs #5143

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T4UcdJLt1bxwdpcigGxZRD
2026-09-19 23:00:14 +00:00
SteveGilvarryandClaude Fable 5.1 0a392802f8 feat: emit capture-fault and state-change events on the monitor stream socket
Wire the monitor lifecycle events into zmc. Monitor::SetState() replaces
the scattered shared_data->state assignments in Analyse() and connect(),
publishing a state_changed event (with previous and new state id and name)
whenever the analysis state actually changes. Monitor::SendStreamHealthEvent()
emits the capture-fault edges and tracks the active fault for the snapshot;
the snapshot is refreshed on every state or health change and after a
successful prime, so a consumer connecting mid-fault learns current status.

zmc's capture loop emits the six health transitions once per edge:
connection failed/restored around connect(), prime_capture failed/restored
around PrimeCapture(), capture_failed on pre/capture/post failure, and a
single capture_resumed once the pipeline recovers. Because the stream
socket survives camera reconnects, these are observable exactly when media
has stopped. A small mutex guards the health fields shared between the
capture thread (health events) and analysis thread (state events).

Documents the EVENT frame in docs/stream_socket.rst and decodes it in
tools/zm_stream_socket_dump.py. Full build and ctest pass (121 tests).

refs #2875

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 05:02:24 +10:00
Isaac ConnorandClaude Opus 5 47379cc083 fix: keep last captured image available while OnDemand capture is paused
Monitor::Pause() reset shared_data->last_write_index to image_buffer_count,
the "nothing written yet" sentinel. Once an OnDemand monitor went to sleep the
last captured image became unreachable, so zms mode=single gave up waiting and
returned "No image available." mode=jpeg worked only because runStream calls
setLastViewed() each iteration, waking capture for a fresh frame.

The zmc OnDemand loop also paused before capturing anything: on a fresh shm
last_viewed is 0, so the first iteration paused a primed camera and no initial
image was ever written for the console thumbnail. The GetLastWriteIndex()
guard that prevented this had been removed because Pause() clobbering the
index made it cycle Pause/Play.

Leave last_write_index alone in Pause() and restore the guard so capture
continues until one image has been written. The index then stays valid, so the
pause is stable and mode=single serves the last captured image.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-11 20:35:35 -04:00
Isaac Connor 5f4304c772 refactor: redesign C++ config to use name-based lookup with compiled-in defaults
Replace numeric ID-based config system with name-based lookup using
std::unordered_map. Config entries now have compiled-in default values,
and only rows where Value != DefaultValue are loaded from the database.
This eliminates the fragile dependency on sequential ID numbers that
required DB regeneration whenever a config entry was added.

The config generator (zmconfgen.pl) now produces three macros:
- ZM_CFG_DECLARE_LIST: declares Config struct members
- ZM_CFG_DEFAULTS_INIT: initializes members to compiled-in defaults
- ZM_CFG_MAP_INIT: registers name-to-member bindings for DB loading

Only daemon-relevant config entries (137 of 245) are included in the
C++ header; web-only settings (WEB_H_*, WEB_M_*, WEB_L_*, skin
defaults, etc.) are excluded.

Also fixes two pre-existing bugs exposed by removing numeric #defines:
- ZM_WATCH_MAX_DELAY was used as Seconds(139) instead of the actual
  config value (the 139 was the config table row ID, not seconds)
- ZM_OPT_USE_AUTH evaluated as if(8) (always true) instead of
  checking the actual auth setting

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
(cherry picked from commit 86d4a8e5f0)
2026-08-29 14:01:25 -04:00
Isaac ConnorandClaude Opus 4.6 7bcdfae0d8 fix: prevent empty events in ONDEMAND mode and fix VideoStore fd/codec leaks
The ONDEMAND capture mode rapidly cycled between Pause() and Play()
because Pause() resets the write index, making the GetLastWriteIndex()
guard false, which fell through to Play(). This created ~2 empty events
per second. Remove the write index guard so monitors stay paused when
nobody is watching.

In VideoStore, fix three resource management issues:
- Free the codec context opened in the PASSTHROUGH+new_extradata path
  immediately after extracting stream parameters, preventing flush_codecs
  from crashing on an encoder that never received frames.
- Clean up video_out_ctx, opts dict, and hw_device_ctx when
  setup_hwaccel() fails, preventing fd accumulation.
- Track whether frames were actually sent to the encoder and skip
  flush_codecs when none were, avoiding segfaults in avcodec_send_frame.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 08:40:26 -04:00
copilot-swe-agent[bot]andconnortechnology d9c9b4087e fix: add HAVE_LIBCURL preprocessor guards to fix ZM_NO_CURL=ON build
Wraps all libcurl usage in #if HAVE_LIBCURL / #endif guards, matching
the existing pattern used for HAVE_LIBVLC and HAVE_LIBVNC.

Files changed:
- src/zm_monitor.h: guard curl include, 4 inner class declarations,
  4 manager member pointers, check_janus() decl, EventPollerHealthy()
- src/zmc.cpp: guard curl_global_init/cleanup calls
- src/zm_monitor.cpp: guard initializer list, instantiation, destructor,
  Poll(), Analyse(), Poller thread condition, and Close() teardown
- src/zm_monitor_amcrest.cpp: wrap implementation in HAVE_LIBCURL guard
- src/zm_monitor_janus.cpp: wrap implementation in HAVE_LIBCURL guard
- src/zm_monitor_rtsp2web.cpp: wrap implementation in HAVE_LIBCURL guard
- src/zm_monitor_go2rtc.cpp: wrap implementation in HAVE_LIBCURL guard

Verified: builds succeed with both ZM_NO_CURL=ON and ZM_NO_CURL=OFF

refs #4967

Co-authored-by: connortechnology <925519+connortechnology@users.noreply.github.com>
2026-03-05 02:13:59 +00:00
Isaac ConnorandClaude Opus 4.6 bc942f194b fix: update heartbeat during camera close and reconnect
avformat_close_input() can block for 75-90s on TCP retransmit timeout
when an RTSP camera becomes unresponsive, and the connect() retry loop
also lacks heartbeat updates. This causes zmwatch to kill zmc with a
stale heartbeat even though the process is actively reconnecting.

Add SetHeartbeatTime() calls before/after Close() and in the connect()
retry loop so zmwatch knows zmc is still alive during reconnection.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 15:38:08 -05:00
Isaac Connor 15e97361b3 Only log a capture failure if we aren't terminated 2026-01-15 16:31:22 -05:00
Mike b56aa9bf85 Fix an uncontrolled FPS scenario leading to OOM.
When the camera exposure time is held longer than the record FPS time and then reduced to under.
2025-07-13 22:09:24 +01:00
Isaac Connor 8e5a9e462c Don't loop forever ignoring sigterm on initial connect 2025-01-16 17:29:10 -05:00
Isaac Connor 36f45fdbc7 Wait until we get a successful shm connect before trying to set StartupTime. fixes crash 2024-12-12 12:21:32 -05:00
Isaac Connor 9f536ccb22 GetLastWriteIndex returns -1 when it is equal to image_buffer_count 2024-10-28 16:06:57 -04:00
Isaac Connor 6cc423bf7a Change logic for going to sleep to just have an image instead of using Ready() which looks for keyframe interval. 2024-10-28 15:51:44 -04:00
Isaac Connor 5eb2a97fce Set fps and bandwidth to 0 on zmc exit. 2024-05-09 09:48:01 -04:00
Isaac Connor 39575343ad Use monitor->Importance when logging about failed captures 2024-05-08 14:45:27 -04: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 92e6a9b5d0 Rough in startup_delay function 2024-03-18 12:54:30 -04:00
Isaac Connor 164e003ab6 Set Heartbeat when not capturing due to ondemand 2023-12-10 09:46:28 -05:00
Isaac Connor c2946f203e Reduce debug logging. Clean up Play/Pause a bit. 2023-12-06 12:25:12 -05:00
Isaac Connor b03838018c When Capturing=ONDEMAND, still PrimeCapture to get an image, and then Pause. 2023-12-06 09:42:26 -05:00
Isaac Connor 9ab31196b5 Don't need to set heartbeat after connect. It willb e set in connect. 2023-11-07 09:15:45 -05:00
Isaac Connor 69891c877e Term log after dbClose, dbClose does a debug log 2023-10-26 16:26:56 -04:00
Isaac Connor 2576c5dfc5 Reset CaptureBandwidth to 0 on startup and after failed connection 2023-08-09 10:25:31 -04:00
Isaac Connor fa266c6578 Reread config files and reread db config when given HUP 2023-07-17 13:46:47 -04:00
Isaac Connor 2ca4756958 Only update fps if capture was successful. Beacuse it now also updates status to say Conected 2022-12-07 20:35:56 -05:00
Isaac Connor b40423d720 Merge branch 'master' of github.com:ZoneMinder/zoneminder 2022-08-02 20:57:48 -04:00
Isaac Connor c40cedc15c Simply code about zm_terminate, replace fixed 60 second max sleep time with ZM_WATCH_MAX_DELAY 2022-08-02 20:45:45 -04:00
Doug Nazar 3c5e44dfe5 Need unistd.h for getpid(). 2022-07-16 10:03:16 +00:00
Isaac Connor 4caffe4674 Include iostream since we use it 2022-07-14 13:42:54 -04:00
Isaac Connor 66f5b9b93d Remove zm_rtsp_server_thread as it isn't used anymore 2022-07-14 12:01:10 -04:00
Isaac Connor e86dd7eb32 move curl init and cleanup into zmc 2022-06-07 18:19:00 -04:00
Isaac Connor 27bc8d9764 Stop the dbQueue before closing logs. Since dbQueue.stop() join's the dbQueue thread, it should not log after we return. 2022-05-18 19:00:40 -04:00
Isaac Connor cf31db0bad Merge branch 'master' into replace_function_concept 2022-02-27 14:05:34 -05:00
Isaac Connor 133553e630 Revert "Merge pull request #3119 from Carbenium/fmt"
This reverts commit 90d930c7c3, reversing
changes made to 0bcb9d276f.
2022-02-27 14:05:14 -05:00
Isaac Connor e33b41745d Merge branch 'master' into replace_function_concept 2022-02-27 14:04:01 -05:00
Isaac Connor cad57df0bb Merge branch 'master' into fmt 2022-02-26 13:56:20 -05:00
Isaac Connor a250567e74 add sleeping when no viewers and in ondemand mode 2022-01-01 17:54:47 -05:00
Isaac Connor 6bd04de5f6 Merge branch 'master' into multistream 2021-12-31 17:53:36 -05:00
Isaac Connor b4511a8fc3 Merge branch 'master' of github.com:ZoneMinder/zoneminder 2021-12-10 16:20:54 -05:00
Isaac Connor c42b75a252 must clear the monitors array before terminating log. 2021-12-10 16:20:44 -05:00
Isaac Connor 1cddac4efd remove remaining signal blocking cruft, add ignoring sigchld so that anything we spawn doesn't become a zombie. 2021-11-29 18:34:19 -05:00
Isaac Connor a2ae63cefe Merge branch 'master' into fmt 2021-11-16 15:10:45 -05:00
Isaac Connor 93055f44e8 Merge UpdateCaptureFPS and UpdateAnalysisFPS into UpdateFPS and call it from zmc after capture. 2021-11-03 17:03:29 -04:00
Isaac Connor 3770306817 Add logic to skip capturing if Capturing()==Ondemand 2021-10-25 16:53:18 -04:00
Peter Keresztes Schmidt 6e96cbe14a Misc: Merge ZM_HAS_V4L with ZM_HAS_V4L2 2021-09-08 00:19:08 +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 f675afc3f2 zmc: Convert internals to std::chrono 2021-06-13 23:22:51 +02:00
Peter Keresztes Schmidt 707975e567 Monitor: Convert API to std::chrono 2021-06-13 23:22:49 +02:00
Peter Keresztes Schmidt 7474294ac3 Time: Remove DELTA_TIMEVAL macro and replace usage with proper std::chrono::duration operations 2021-06-06 16:41:36 +02:00