Files
zoneminder/tests/zm_monitor_signal.cpp
Nic BoetandClaude Opus 5.5 68aa214ff7 fix: leave the signal flag to the decoder when it checks SignalCheckPoints
Capture set shared_data->signal to true for every packet while the
decoder set it to CheckSignal() for every decoded frame. With
SignalCheckPoints on and a camera showing its lost-signal picture,
Analyse sometimes read Capture's true between two decoded frames, so the
signal flipped back for one frame: the event was closed for signal loss
and a zero-frame "Signal: Reacquired" event opened, about once a minute.

Capture now writes true only when no decoder measures the signal: no
SignalCheckPoints, Decoding=None, or on-demand decoding with no viewer.
It still writes true for the first packet after connect(), as before, so
Analyse doesn't see a signal loss before the first decoded frame and the
first event keeps its cause. The capture-failure path still writes false.

fixes #5235

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 11:15:52 -05:00

46 lines
1.9 KiB
C++

/*
* This file is part of the ZoneMinder Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "zm_catch2.h"
#include "zm_monitor.h"
TEST_CASE("Monitor::DecoderChecksSignal") {
SECTION("without SignalCheckPoints nothing measures the signal") {
for (auto decoding : {Monitor::DECODING_NONE, Monitor::DECODING_ONDEMAND, Monitor::DECODING_KEYFRAMES,
Monitor::DECODING_KEYFRAMESONDEMAND, Monitor::DECODING_ALWAYS}) {
REQUIRE_FALSE(Monitor::DecoderChecksSignal(decoding, 0, true));
REQUIRE_FALSE(Monitor::DecoderChecksSignal(decoding, 0, false));
}
}
SECTION("a decoder that always runs measures it") {
REQUIRE(Monitor::DecoderChecksSignal(Monitor::DECODING_ALWAYS, 10, false));
REQUIRE(Monitor::DecoderChecksSignal(Monitor::DECODING_KEYFRAMES, 10, false));
REQUIRE(Monitor::DecoderChecksSignal(Monitor::DECODING_KEYFRAMESONDEMAND, 10, false));
}
SECTION("on-demand decoding measures it only while someone watches") {
REQUIRE(Monitor::DecoderChecksSignal(Monitor::DECODING_ONDEMAND, 10, true));
REQUIRE_FALSE(Monitor::DecoderChecksSignal(Monitor::DECODING_ONDEMAND, 10, false));
}
SECTION("no decoding: capture keeps setting it") {
REQUIRE_FALSE(Monitor::DecoderChecksSignal(Monitor::DECODING_NONE, 10, true));
}
}