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>
This commit is contained in:
copilot-swe-agent[bot]
2026-05-17 03:29:41 +00:00
committed by GitHub
parent ea11498dc1
commit 1bce09f4e8
3 changed files with 20 additions and 14 deletions

View File

@@ -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

View File

@@ -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) {

View File

@@ -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),