From 1bce09f4e84615e03e083480ec92ed87fe44fff7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 17 May 2026 03:29:41 +0000 Subject: [PATCH] fix: address review feedback - endian decode, send_twice init, setLastViewed, curr_frame_id gating Agent-Logs-Url: https://github.com/ZoneMinder/zoneminder/sessions/b457dcf6-616f-4df9-bc28-76640bf5dd39 Co-authored-by: connortechnology <925519+connortechnology@users.noreply.github.com> --- src/zm_eventstream.cpp | 8 +++++--- src/zm_monitorstream.cpp | 12 ++++++------ src/zm_stream.h | 14 +++++++++----- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/zm_eventstream.cpp b/src/zm_eventstream.cpp index cf08b81d4..ea7d5ace0 100644 --- a/src/zm_eventstream.cpp +++ b/src/zm_eventstream.cpp @@ -480,7 +480,7 @@ void EventStream::processCommand(const CmdMsg *msg) { Debug(1, "Got VARPLAY command"); stopped = false; paused = false; - replay_rate = ntohs(((unsigned char)msg->msg_data[2]<<8)|(unsigned char)msg->msg_data[1])-32768; + replay_rate = (((unsigned char)msg->msg_data[1]<<8)|(unsigned char)msg->msg_data[2])-VARPLAY_RATE_OFFSET; if (replay_rate > 50 * ZM_RATE_BASE) { Warning("requested replay rate (%d) is too high. We only support up to 50x", replay_rate); replay_rate = 50 * ZM_RATE_BASE; @@ -494,6 +494,8 @@ void EventStream::processCommand(const CmdMsg *msg) { Debug(1, "Got STOP command"); stopped = true; paused = false; + step = 0; + send_twice = false; break; case CMD_FASTFWD : { Debug(1, "Got FAST FWD command"); @@ -1198,10 +1200,10 @@ void EventStream::runStream() { // Paused or stopped delta = MAX_SLEEP; - // We are paused, so might be stepping + // We are paused, so might be stepping (not when fully stopped) //if ( step != 0 )// Adding 0 is cheaper than an if 0 // curr_frame_id starts at 1 though, so we might skip the first frame? - curr_frame_id += step; + if (!stopped) curr_frame_id += step; } // end if !paused && !stopped } // end scope for mutex lock diff --git a/src/zm_monitorstream.cpp b/src/zm_monitorstream.cpp index 6cb7f625e..4dd4f6a91 100644 --- a/src/zm_monitorstream.cpp +++ b/src/zm_monitorstream.cpp @@ -113,7 +113,7 @@ void MonitorStream::processCommand(const CmdMsg *msg) { paused = false; delayed = true; } - replay_rate = ntohs(((unsigned char)msg->msg_data[2]<<8)|(unsigned char)msg->msg_data[1])-32768; + replay_rate = (((unsigned char)msg->msg_data[1]<<8)|(unsigned char)msg->msg_data[2])-VARPLAY_RATE_OFFSET; break; case CMD_STOP : Debug(1, "Got STOP command"); @@ -646,15 +646,15 @@ void MonitorStream::runStream() { std::this_thread::sleep_for(MAX_SLEEP); continue; } - monitor->setLastViewed(); - if (frame_type == FRAME_ANALYSIS) - monitor->setLastAnalysisViewed(); - if (stopped) { - // In stopped state, do nothing except wait for a new command + // In stopped state, do nothing except wait for a new command. + // Don't call setLastViewed() so we don't keep capture/decoding active unnecessarily. std::this_thread::sleep_for(MAX_SLEEP); continue; } + monitor->setLastViewed(); + if (frame_type == FRAME_ANALYSIS) + monitor->setLastAnalysisViewed(); if (paused) { if (!was_paused) { diff --git a/src/zm_stream.h b/src/zm_stream.h index f729cc504..8c794ca00 100644 --- a/src/zm_stream.h +++ b/src/zm_stream.h @@ -54,6 +54,9 @@ class StreamBase { enum { DEFAULT_ZOOM=ZM_SCALE_BASE }; enum { DEFAULT_MAXFPS=10 }; enum { DEFAULT_BITRATE=100000 }; + // Offset applied when encoding a signed replay rate as a uint16 for CMD_VARPLAY. + // On the wire: uint16 = rate + VARPLAY_RATE_OFFSET. Receiver subtracts the same offset. + static const int VARPLAY_RATE_OFFSET = 32768; protected: typedef struct { @@ -93,12 +96,12 @@ class StreamBase { CMD_NEXT, CMD_SEEK, // CMD_VARPLAY resumes or starts playback at a caller-specified rate. - // The desired rate is packed as a big-endian uint16 offset by +32768 so that the range - // [-32768, +32767] maps to [0, 65535]. ZM_RATE_BASE (100) represents 1x speed, so: - // 32868 (= 32768 + 100) encodes 1x forward playback, - // 32668 (= 32768 - 100) encodes 1x reverse playback. + // The desired rate is packed as a big-endian uint16 offset by +VARPLAY_RATE_OFFSET so that + // the range [-32768, +32767] maps to [0, 65535]. ZM_RATE_BASE (100) represents 1x speed, so: + // 32868 (= VARPLAY_RATE_OFFSET + 100) encodes 1x forward playback, + // 32668 (= VARPLAY_RATE_OFFSET - 100) encodes 1x reverse playback. // Negative rates play in reverse; rates > ZM_RATE_BASE play faster than real-time. - // MSG payload: msg_data[1..2] = (rate + 32768) as network-byte-order uint16. + // MSG payload: msg_data[1..2] = (rate + VARPLAY_RATE_OFFSET) as network-byte-order uint16. CMD_VARPLAY, CMD_GET_IMAGE, CMD_QUIT, @@ -202,6 +205,7 @@ class StreamBase { paused(false), stopped(false), step(0), + send_twice(false), maxfps(DEFAULT_MAXFPS), base_fps(0.0), effective_fps(0.0),