From 33f23cbd84c5d8f767ed7abf68a06c5b7610be9e Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 15 Feb 2022 18:51:10 -0500 Subject: [PATCH 01/28] Sync up n_frames, frame_count, curr_frame_id on int instead of a mix of long int, int and unsigned long int --- src/zm_eventstream.cpp | 72 ++++++++++++++++++++++-------------------- src/zm_eventstream.h | 12 +++---- 2 files changed, 44 insertions(+), 40 deletions(-) diff --git a/src/zm_eventstream.cpp b/src/zm_eventstream.cpp index 28a0e50d6..34f693f36 100644 --- a/src/zm_eventstream.cpp +++ b/src/zm_eventstream.cpp @@ -68,17 +68,17 @@ bool EventStream::loadInitialEventData(int monitor_id, SystemTimePoint event_tim curr_frame_id = 1; // curr_frame_id is 1-based if (event_time >= event_data->start_time) { Debug(2, "event time is after event start"); - for (unsigned int i = 0; i < event_data->frame_count; i++) { + for (int i = 0; i < event_data->frame_count; i++) { //Info( "eft %d > et %d", event_data->frames[i].timestamp, event_time ); if (event_data->frames[i].timestamp >= event_time) { curr_frame_id = i + 1; - Debug(3, "Set curr_stream_time: %.2f, curr_frame_id: %ld", + Debug(3, "Set curr_stream_time: %.2f, curr_frame_id: %d", FPSeconds(curr_stream_time.time_since_epoch()).count(), curr_frame_id); break; } } // end foreach frame - Debug(3, "Skipping %ld frames", event_data->frame_count); + Debug(3, "Skipping %d frames", event_data->frame_count); } else { Warning("Requested an event time less than the start of the event. event_time %" PRIi64 " < start_time %" PRIi64, static_cast(std::chrono::duration_cast(event_time.time_since_epoch()).count()), @@ -90,13 +90,13 @@ bool EventStream::loadInitialEventData(int monitor_id, SystemTimePoint event_tim bool EventStream::loadInitialEventData( uint64_t init_event_id, - unsigned int init_frame_id + int init_frame_id ) { loadEventData(init_event_id); if ( init_frame_id ) { if ( init_frame_id >= event_data->frame_count ) { - Error("Invalid frame id specified. %d > %lu", init_frame_id, event_data->frame_count); + Error("Invalid frame id specified. %d > %d", init_frame_id, event_data->frame_count); curr_stream_time = event_data->start_time; curr_frame_id = 1; } else { @@ -225,20 +225,24 @@ bool EventStream::loadEventData(uint64_t event_id) { sql = stringtf("SELECT `FrameId`, unix_timestamp(`TimeStamp`), `Delta` " "FROM `Frames` WHERE `EventId` = %" PRIu64 " ORDER BY `FrameId` ASC", event_id); - result = zmDbFetch(sql); if (!result) { exit(-1); } event_data->n_frames = mysql_num_rows(result); - event_data->frames = new FrameData[event_data->frame_count]; + if (event_data->frame_count < event_data->n_frames) { + event_data->frame_count = event_data->n_frames; + Warning("Event %" PRId64 " has more frames in the Frames table (%d) than in the Event record (%d)", + event_data->event_id, event_data->n_frames, event_data->frame_count); + } + int last_id = 0; SystemTimePoint last_timestamp = event_data->start_time; Microseconds last_delta = Seconds(0); - while ( ( dbrow = mysql_fetch_row(result) ) ) { + while ((dbrow = mysql_fetch_row(result))) { int id = atoi(dbrow[0]); //timestamp = atof(dbrow[1]); Microseconds delta = std::chrono::duration_cast(FPSeconds(atof(dbrow[2]))); @@ -280,7 +284,7 @@ bool EventStream::loadEventData(uint64_t event_id) { // Incomplete events might not have any frame data event_data->last_frame_id = last_id; - if ( mysql_errno(&dbconn) ) { + if (mysql_errno(&dbconn)) { Error("Can't fetch row: %s", mysql_error(&dbconn)); exit(mysql_errno(&dbconn)); } @@ -310,7 +314,7 @@ bool EventStream::loadEventData(uint64_t event_id) { else curr_stream_time = event_data->frames[event_data->last_frame_id-1].timestamp; } - Debug(2, "Event: %" PRIu64 ", Frames: %ld, Last Frame ID (%ld, Duration: %.2f s Frames Duration: %.2f s", + Debug(2, "Event: %" PRIu64 ", Frames: %d, Last Frame ID (%d, Duration: %.2f s Frames Duration: %.2f s", event_data->event_id, event_data->frame_count, event_data->last_frame_id, @@ -342,12 +346,12 @@ void EventStream::processCommand(const CmdMsg *msg) { if ( (mode == MODE_SINGLE || mode == MODE_NONE) && - ((unsigned int)curr_frame_id == event_data->last_frame_id) + (curr_frame_id == event_data->last_frame_id) ) { Debug(1, "Was in single or no replay mode, and at last frame, so jumping to 1st frame"); curr_frame_id = 1; } else { - Debug(1, "mode is %s, current frame is %ld, frame count is %ld, last frame id is %ld", + Debug(1, "mode is %s, current frame is %d, frame count is %d, last frame id is %d", StreamMode_Strings[(int) mode].c_str(), curr_frame_id, event_data->frame_count, @@ -404,9 +408,9 @@ void EventStream::processCommand(const CmdMsg *msg) { paused = true; replay_rate = ZM_RATE_BASE; step = 1; - if ( (unsigned int)curr_frame_id < event_data->last_frame_id ) + if (curr_frame_id < event_data->last_frame_id) curr_frame_id += 1; - Debug(1, "Got SLOWFWD command new frame id %ld", curr_frame_id); + Debug(1, "Got SLOWFWD command new frame id %d", curr_frame_id); break; case CMD_SLOWREV : paused = true; @@ -414,7 +418,7 @@ void EventStream::processCommand(const CmdMsg *msg) { step = -1; curr_frame_id -= 1; if ( curr_frame_id < 1 ) curr_frame_id = 1; - Debug(1, "Got SLOWREV command new frame id %ld", curr_frame_id); + Debug(1, "Got SLOWREV command new frame id %d", curr_frame_id); break; case CMD_FASTREV : Debug(1, "Got FAST REV command"); @@ -538,12 +542,12 @@ void EventStream::processCommand(const CmdMsg *msg) { if ( curr_frame_id < 1 ) { curr_frame_id = 1; - } else if ( (unsigned long)curr_frame_id > event_data->last_frame_id ) { + } else if (curr_frame_id > event_data->last_frame_id) { curr_frame_id = event_data->last_frame_id; } curr_stream_time = event_data->frames[curr_frame_id-1].timestamp; - Debug(1, "Got SEEK command, to %f s (new current frame id: %ld offset %f s)", + Debug(1, "Got SEEK command, to %f s (new current frame id: %d offset %f s)", FPSeconds(offset).count(), curr_frame_id, FPSeconds(event_data->frames[curr_frame_id - 1].offset).count()); @@ -615,11 +619,11 @@ bool EventStream::checkEventLoaded() { sql = stringtf( "SELECT `Id` FROM `Events` WHERE `MonitorId` = %d AND `Id` < %" PRIu64 " ORDER BY `Id` DESC LIMIT 1", event_data->monitor_id, event_data->event_id); - } else if ( (unsigned int)curr_frame_id > event_data->last_frame_id ) { + } else if (curr_frame_id > event_data->last_frame_id) { if (event_data->end_time.time_since_epoch() == Seconds(0)) { // We are viewing an in-process event, so just reload it. loadEventData(event_data->event_id); - if ( (unsigned int)curr_frame_id > event_data->last_frame_id ) + if (curr_frame_id > event_data->last_frame_id) curr_frame_id = event_data->last_frame_id; return false; } @@ -628,7 +632,7 @@ bool EventStream::checkEventLoaded() { event_data->monitor_id, event_data->event_id); } else { // No event change required - Debug(3, "No event change required, as curr frame %ld <=> event frames %lu", + Debug(3, "No event change required, as curr frame %d <=> event frames %d", curr_frame_id, event_data->frame_count); return false; } @@ -662,7 +666,7 @@ bool EventStream::checkEventLoaded() { curr_frame_id = event_data->last_frame_id; else curr_frame_id = 1; - Debug(2, "New frame id = %ld", curr_frame_id); + Debug(2, "New frame id = %d", curr_frame_id); start = std::chrono::steady_clock::now(); return true; } else { @@ -689,13 +693,13 @@ bool EventStream::checkEventLoaded() { Image * EventStream::getImage( ) { std::string path = stringtf(staticConfig.capture_file_format.c_str(), event_data->path.c_str(), curr_frame_id); - Debug(2, "EventStream::getImage path(%s) from %s frame(%ld) ", path.c_str(), event_data->path.c_str(), curr_frame_id); + Debug(2, "EventStream::getImage path(%s) from %s frame(%d) ", path.c_str(), event_data->path.c_str(), curr_frame_id); Image *image = new Image(path.c_str()); return image; } bool EventStream::sendFrame(Microseconds delta_us) { - Debug(2, "Sending frame %ld", curr_frame_id); + Debug(2, "Sending frame %d", curr_frame_id); std::string filepath; struct stat filestat = {}; @@ -881,7 +885,7 @@ void EventStream::runStream() { if ( !paused ) { // Figure out if we should send this frame - Debug(3, "not paused at cur_frame_id (%ld-1) mod frame_mod(%d)", curr_frame_id, frame_mod); + Debug(3, "not paused at cur_frame_id (%d-1) mod frame_mod(%d)", curr_frame_id, frame_mod); // If we are streaming and this frame is due to be sent // frame mod defaults to 1 and if we are going faster than max_fps will get multiplied by 2 // so if it is 2, then we send every other frame, if is it 4 then every fourth frame, etc. @@ -983,7 +987,7 @@ void EventStream::runStream() { if ( (mode == MODE_SINGLE) && ( (curr_frame_id < 1 ) || - ((unsigned int)curr_frame_id >= event_data->frame_count) + (curr_frame_id >= event_data->frame_count) ) ) { Debug(2, "Have mode==MODE_SINGLE and at end of event, looping back to start"); @@ -992,7 +996,7 @@ void EventStream::runStream() { start = now; } - if ((unsigned int)curr_frame_id <= event_data->frame_count) { + if (curr_frame_id <= event_data->frame_count) { frame_data = &event_data->frames[curr_frame_id-1]; // frame_data->delta is the time since last frame as a float in seconds @@ -1032,7 +1036,7 @@ void EventStream::runStream() { } } // end if need to sleep } else { - Debug(1, "invalid curr_frame_id %ld !< %lu", curr_frame_id, event_data->frame_count); + Debug(1, "invalid curr_frame_id %d !< %d", curr_frame_id, event_data->frame_count); } // end if not at end of event } else { // Paused @@ -1110,12 +1114,12 @@ bool EventStream::send_file(const std::string &filepath) { } if (!filestat.st_size) { fclose(fdj); /* Close the file handle */ - Info("File size is zero. Unable to send raw frame %ld: %s", curr_frame_id, strerror(errno)); + Info("File size is zero. Unable to send raw frame %d: %s", curr_frame_id, strerror(errno)); return false; } if (0 > fprintf(stdout, "Content-Length: %d\r\n\r\n", (int)filestat.st_size)) { fclose(fdj); /* Close the file handle */ - Info("Unable to send raw frame %ld: %s", curr_frame_id, strerror(errno)); + Info("Unable to send raw frame %d: %s", curr_frame_id, strerror(errno)); return false; } int rc = zm_sendfile(fileno(stdout), fileno(fdj), 0, (int)filestat.st_size); @@ -1124,7 +1128,7 @@ bool EventStream::send_file(const std::string &filepath) { fclose(fdj); /* Close the file handle */ return true; } - Warning("Unable to send raw frame %ld: %s rc %d != %d", + Warning("Unable to send raw frame %d: %s rc %d != %d", curr_frame_id, strerror(errno), rc, (int)filestat.st_size); #endif @@ -1134,7 +1138,7 @@ bool EventStream::send_file(const std::string &filepath) { int img_buffer_size = fread(img_buffer, 1, sizeof(temp_img_buffer), fdj); fclose(fdj); /* Close the file handle */ if ( !img_buffer_size ) { - Info("Unable to read raw frame %ld: %s", curr_frame_id, strerror(errno)); + Info("Unable to read raw frame %d: %s", curr_frame_id, strerror(errno)); return false; } @@ -1143,13 +1147,13 @@ bool EventStream::send_file(const std::string &filepath) { bool EventStream::send_buffer(uint8_t* buffer, int size) { if ( 0 > fprintf(stdout, "Content-Length: %d\r\n\r\n", size) ) { - Info("Unable to send raw frame %ld: %s", curr_frame_id, strerror(errno)); + Info("Unable to send raw frame %d: %s", curr_frame_id, strerror(errno)); return false; } int rc = fwrite(buffer, size, 1, stdout); if ( 1 != rc ) { - Error("Unable to send raw frame %ld: %s %d", curr_frame_id, strerror(errno), rc); + Error("Unable to send raw frame %d: %s %d", curr_frame_id, strerror(errno), rc); return false; } return true; @@ -1157,7 +1161,7 @@ bool EventStream::send_buffer(uint8_t* buffer, int size) { void EventStream::setStreamStart( uint64_t init_event_id, - unsigned int init_frame_id=0) { + int init_frame_id=0) { loadInitialEventData(init_event_id, init_frame_id); } // end void EventStream::setStreamStart(init_event_id,init_frame_id=0) diff --git a/src/zm_eventstream.h b/src/zm_eventstream.h index 969e6725d..093bcd0eb 100644 --- a/src/zm_eventstream.h +++ b/src/zm_eventstream.h @@ -49,9 +49,9 @@ class EventStream : public StreamBase { struct EventData { uint64_t event_id; unsigned int monitor_id; - unsigned long storage_id; - unsigned long frame_count; // Value of Frames column in Event - unsigned long last_frame_id; // Highest frame id known about. Can be < frame_count in incomplete events + unsigned int storage_id; + int frame_count; // Value of Frames column in Event + int last_frame_id; // Highest frame id known about. Can be < frame_count in incomplete events SystemTimePoint start_time; SystemTimePoint end_time; Microseconds duration; @@ -73,7 +73,7 @@ class EventStream : public StreamBase { StreamMode mode; bool forceEventChange; - long curr_frame_id; + int curr_frame_id; SystemTimePoint curr_stream_time; bool send_frame; TimePoint start; // clock time when started the event @@ -82,7 +82,7 @@ class EventStream : public StreamBase { protected: bool loadEventData(uint64_t event_id); - bool loadInitialEventData(uint64_t init_event_id, unsigned int init_frame_id); + bool loadInitialEventData(uint64_t init_event_id, int init_frame_id); bool loadInitialEventData(int monitor_id, SystemTimePoint event_time); bool checkEventLoaded(); @@ -118,7 +118,7 @@ class EventStream : public StreamBase { ffmpeg_input = nullptr; } } - void setStreamStart(uint64_t init_event_id, unsigned int init_frame_id); + void setStreamStart(uint64_t init_event_id, int init_frame_id); void setStreamStart(int monitor_id, time_t event_time); void setStreamMode(StreamMode p_mode) { mode = p_mode; } void runStream() override; From 8b14885541d6fd9ca464249273a5ca981639c09e Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 15 Feb 2022 18:51:54 -0500 Subject: [PATCH 02/28] Add handling of NOT IN and =\[\] and \!\[\] --- web/includes/FilterTerm.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web/includes/FilterTerm.php b/web/includes/FilterTerm.php index 8a58e2f98..903cce811 100644 --- a/web/includes/FilterTerm.php +++ b/web/includes/FilterTerm.php @@ -174,6 +174,7 @@ class FilterTerm { case 'IN' : return ' IN '; case '![]' : + case 'NOT IN' : return ' NOT IN '; case 'EXISTS' : return ' EXISTS '; @@ -303,7 +304,7 @@ class FilterTerm { } $sql .= $this->sql_operator(); $values = $this->sql_values(); - if ( (count($values) > 1) or ($this->op == 'IN') or ($this->op == 'NOT IN') ) { + if ((count($values) > 1) or ($this->op == 'IN') or ($this->op == 'NOT IN') or ($this->op == '=[]') or ($this->op == '![]')) { $sql .= '('.join(',', $values).')'; } else { $sql .= $values[0]; From b67e7b8111afa3b5691a61ca78abb251f8e878b4 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 15 Feb 2022 18:52:27 -0500 Subject: [PATCH 03/28] serialize form instead of just passing filter id because the modal can now handle unsaved filters --- web/skins/classic/views/js/filter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/skins/classic/views/js/filter.js b/web/skins/classic/views/js/filter.js index 5765a0e76..e7979db15 100644 --- a/web/skins/classic/views/js/filter.js +++ b/web/skins/classic/views/js/filter.js @@ -378,7 +378,7 @@ function delTerm( element ) { } function debugFilter() { - getModal('filterdebug', 'fid='+filterid); + getModal('filterdebug', $j(form).serialize()); } function manageModalBtns(id) { From efc1ec770c6fb5205c75b4379eabfc6154ddac10 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 15 Feb 2022 18:52:40 -0500 Subject: [PATCH 04/28] Debug the contents of REQUEST on every hit. --- web/index.php | 1 + 1 file changed, 1 insertion(+) diff --git a/web/index.php b/web/index.php index 5ace8e9b6..abca33c9f 100644 --- a/web/index.php +++ b/web/index.php @@ -55,6 +55,7 @@ if ( 0 and ZM\Logger::fetch()->debugOn() ) { ZM\Debug(ob_get_contents()); ob_end_clean(); } +ZM\Debug(print_r($_REQUEST, true)); global $Servers; $Servers = ZM\Server::find(); From 59d283095dfcdd8f7314af97a90ac24f4ddde576 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Wed, 16 Feb 2022 07:54:01 -0600 Subject: [PATCH 05/28] bump rpm specfile rtsp commit anytime the rtsp commit is bumped in packpack, it must also be bumped in the rpm specfile --- distros/redhat/zoneminder.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/distros/redhat/zoneminder.spec b/distros/redhat/zoneminder.spec index f15e60326..37920dcf8 100644 --- a/distros/redhat/zoneminder.spec +++ b/distros/redhat/zoneminder.spec @@ -9,7 +9,7 @@ %global ceb_version 1.0-zm # RtspServer is configured as a git submodule -%global rtspserver_commit cd7fd49becad6010a1b8466bfebbd93999a39878 +%global rtspserver_commit eab32851421ffe54fec0229c3efc44c642bc8d46 %global sslcert %{_sysconfdir}/pki/tls/certs/localhost.crt %global sslkey %{_sysconfdir}/pki/tls/private/localhost.key From a2a4a8e74f0c3d8fd4f09aa715c3f8ae4ef77435 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Wed, 16 Feb 2022 08:22:37 -0600 Subject: [PATCH 06/28] include arp-scan polkit files in rpm --- distros/redhat/zoneminder.spec | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/distros/redhat/zoneminder.spec b/distros/redhat/zoneminder.spec index 37920dcf8..042eeb7c3 100644 --- a/distros/redhat/zoneminder.spec +++ b/distros/redhat/zoneminder.spec @@ -352,7 +352,8 @@ ln -sf %{_sysconfdir}/zm/www/zoneminder.nginx.conf %{_sysconfdir}/zm/www/zonemin %config(noreplace) %{_sysconfdir}/logrotate.d/zoneminder %{_unitdir}/zoneminder.service -%{_datadir}/polkit-1/actions/com.zoneminder.systemctl.policy +%{_datadir}/polkit-1/actions/com.zoneminder.* +%{_datadir}/polkit-1/rules.d/com.zoneminder.arp-scan.rules %{_bindir}/zmsystemctl.pl %{_bindir}/zmaudit.pl From 9d400b9f6cf5a04bb490c362696793fe2fdc4dd3 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Wed, 16 Feb 2022 08:33:44 -0600 Subject: [PATCH 07/28] use rockylinux:8 container for ci workflow --- .github/workflows/ci-centos-8.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-centos-8.yml b/.github/workflows/ci-centos-8.yml index f01f9929b..8ad222793 100644 --- a/.github/workflows/ci-centos-8.yml +++ b/.github/workflows/ci-centos-8.yml @@ -19,7 +19,7 @@ jobs: - crypto_backend: gnutls jwt_backend: libjwt runs-on: ubuntu-latest - container: centos:8 + container: rockylinux:8 steps: - name: Enable RPMFusion, EPEL and PowerTools From 93ab345a3a1be5047dffded2ee67f6e8baa9e6c2 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 16 Feb 2022 09:28:21 -0500 Subject: [PATCH 08/28] DefaultCodec is for event view, not live --- web/lang/en_gb.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/lang/en_gb.php b/web/lang/en_gb.php index 623d55571..d8d57d1f3 100644 --- a/web/lang/en_gb.php +++ b/web/lang/en_gb.php @@ -294,10 +294,10 @@ $SLANG = array( 'Debug' => 'Debug', 'DefaultRate' => 'Default Rate', 'DefaultScale' => 'Default Scale', - 'DefaultCodec' => 'Default Method For Live View', + 'DefaultCodec' => 'Default Method For Event View', 'DefaultView' => 'Default View', 'Deinterlacing' => 'Deinterlacing', - 'RTSPDescribe' => 'Use RTSP Response Media URL', + 'RTSPDescribe' => 'Use RTSP Response Media URL', 'Delay' => 'Delay', 'DeleteAndNext' => 'Delete & Next', 'DeleteAndPrev' => 'Delete & Prev', From 055414c77822fcb4f18b0dc793263f56904ce8c3 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 16 Feb 2022 09:28:58 -0500 Subject: [PATCH 09/28] DefaultCodec is for event view, not live --- web/lang/zh_tw.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/lang/zh_tw.php b/web/lang/zh_tw.php index 642b884e2..601d8609a 100644 --- a/web/lang/zh_tw.php +++ b/web/lang/zh_tw.php @@ -278,7 +278,7 @@ $SLANG = array( 'Debug' => '除錯', 'DefaultRate' => '預設 Rate', 'DefaultScale' => '預設 Scale', - 'DefaultCodec' => '預設 Method For Live View', + 'DefaultCodec' => '預設 Method For Event View', 'DefaultView' => '預設 View', 'Deinterlacing' => 'Deinterlacing', 'RTSPDescribe' => 'Use RTSP Response Media URL', From 2d3f99eabbdb3279ae75903ff7056c0dfb6b7582 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 16 Feb 2022 09:59:23 -0500 Subject: [PATCH 10/28] rework zm_sendfile to try again if not all bytes were sent. According to the docs, this is entirely possible. --- src/zm_sendfile.h | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/zm_sendfile.h b/src/zm_sendfile.h index fd72e2e61..3568e2fea 100644 --- a/src/zm_sendfile.h +++ b/src/zm_sendfile.h @@ -3,22 +3,25 @@ #ifdef HAVE_SENDFILE4_SUPPORT #include -int zm_sendfile(int out_fd, int in_fd, off_t *offset, size_t size) { - int err; +ssize_t zm_sendfile(int out_fd, int in_fd, off_t *offset, size_t size) { + size_t remaining = size; + while (remaining) { + ssize_t err = sendfile(out_fd, in_fd, offset, remaining); + if (err < 0) { + return -errno; + } + remaining -= err; + offset += err; + } - err = sendfile(out_fd, in_fd, offset, size); - if ( err < 0 ) - return -errno; - - return err; + return size-remaining; } #elif HAVE_SENDFILE7_SUPPORT #include #include #include -int zm_sendfile(int out_fd, int in_fd, off_t *offset, off_t size) { - int err; - err = sendfile(in_fd, out_fd, *offset, size, nullptr, &size, 0); +ssize_t zm_sendfile(int out_fd, int in_fd, off_t *offset, off_t size) { + ssize_t err = sendfile(in_fd, out_fd, *offset, size, nullptr, &size, 0); if (err && errno != EAGAIN) return -errno; From f3d3cad4192725511f32a4c926487e205104e775 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 16 Feb 2022 09:59:39 -0500 Subject: [PATCH 11/28] Remove non-translations --- web/lang/en_gb.php | 254 +++------------------------------------------ 1 file changed, 14 insertions(+), 240 deletions(-) diff --git a/web/lang/en_gb.php b/web/lang/en_gb.php index d8d57d1f3..c80a37e85 100644 --- a/web/lang/en_gb.php +++ b/web/lang/en_gb.php @@ -78,18 +78,10 @@ define( "STRF_FMT_DATETIME_SHORTER", "%x %H:%M:%S" ); $SLANG = array( 'SystemLog' => 'System Log', 'DateTime' => 'Date/Time', - 'Component' => 'Component', 'Pid' => 'PID', - 'Level' => 'Level', - 'Message' => 'Message', - 'Line' => 'Line', - 'More' => 'More', - 'Clear' => 'Clear', '24BitColour' => '24 bit colour', '32BitColour' => '32 bit colour', '8BitGrey' => '8 bit greyscale', - 'Action' => 'Action', - 'Actual' => 'Actual', 'AddNewControl' => 'Add New Control', 'AddNewMonitor' => 'Add', 'AddMonitorDisabled' => 'Your user is not allowed to add a new monitor', @@ -97,7 +89,6 @@ $SLANG = array( 'AddNewStorage' => 'Add New Storage', 'AddNewUser' => 'Add New User', 'AddNewZone' => 'Add New Zone', - 'Alarm' => 'Alarm', 'AlarmBrFrames' => 'Alarm
Frames', 'AlarmFrame' => 'Alarm Frame', 'AlarmFrameCount' => 'Alarm Frame Count', @@ -106,20 +97,13 @@ $SLANG = array( 'AlarmPx' => 'Alarm Px', 'AlarmRefImageBlendPct' => 'Alarm Reference Image Blend %ge', 'AlarmRGBUnset' => 'You must set an alarm RGB colour', - 'Alert' => 'Alert', - 'All' => 'All', 'AllTokensRevoked' => 'All Tokens Revoked', 'AnalysisFPS' => 'Analysis FPS', 'AnalysisUpdateDelay' => 'Analysis Update Delay', - 'API' => 'API', 'APIEnabled' => 'API Enabled', - 'Apply' => 'Apply', 'ApplyingStateChange' => 'Applying State Change', 'ArchArchived' => 'Archived Only', - 'Archive' => 'Archive', - 'Archived' => 'Archived', 'ArchUnarchived' => 'Unarchived Only', - 'Area' => 'Area', 'AreaUnits' => 'Area (px/%)', 'AttrAlarmFrames' => 'Alarm Frames', 'AttrAlarmedZone' => 'Alarmed Zone', @@ -154,12 +138,8 @@ $SLANG = array( 'AttrTotalScore' => 'Total Score', 'AttrStartWeekday' => 'Start Weekday', 'AttrEndWeekday' => 'End Weekday', - 'Auto' => 'Auto', 'AutoStopTimeout' => 'Auto Stop Timeout', - 'Available' => 'Available', 'AvgBrScore' => 'Avg.
Score', - 'Available' => 'Available', - 'Background' => 'Background', 'BackgroundFilter' => 'Run filter in background', 'BadAlarmFrameCount' => 'Alarm frame count must be an integer of one or more', 'BadAlarmMaxFPS' => 'Alarm Maximum FPS must be a positive integer or floating point value', @@ -197,20 +177,14 @@ $SLANG = array( 'BadWebColour' => 'Web colour must be a valid web colour string', 'BadWebSitePath' => 'Please enter a complete website url, including the http:// or https:// prefix.', 'BadWidth' => 'Width must be set to a valid value', - 'Bandwidth' => 'Bandwidth', 'BandwidthHead' => 'Bandwidth', // This is the end of the bandwidth status on the top of the console, different in many language due to phrasing 'BlobPx' => 'Blob Px', - 'Blobs' => 'Blobs', 'BlobSizes' => 'Blob Sizes', - 'Brightness' => 'Brightness', - 'Buffer' => 'Buffer', - 'Buffers' => 'Buffers', 'CanAutoFocus' => 'Can Auto Focus', 'CanAutoGain' => 'Can Auto Gain', 'CanAutoIris' => 'Can Auto Iris', 'CanAutoWhite' => 'Can Auto White Bal.', 'CanAutoZoom' => 'Can Auto Zoom', - 'Cancel' => 'Cancel', 'CancelForcedAlarm' => 'Cancel Forced Alarm', 'CanFocusAbs' => 'Can Focus Absolute', 'CanFocus' => 'Can Focus', @@ -232,7 +206,7 @@ $SLANG = array( 'CanMoveRel' => 'Can Move Relative', 'CanPan' => 'Can Pan' , 'CanReset' => 'Can Reset', - 'CanReboot' => 'Can Reboot', + 'CanReboot' => 'Can Reboot', 'CanSetPresets' => 'Can Set Presets', 'CanSleep' => 'Can Sleep', 'CanTilt' => 'Can Tilt', @@ -251,7 +225,6 @@ $SLANG = array( 'CaptureResolution' => 'Capture Resolution', 'CapturePalette' => 'Capture Palette', 'CaptureWidth' => 'Capture Width', - 'Cause' => 'Cause', 'CheckMethod' => 'Alarm Check Method', 'ChooseDetectedCamera' => 'Choose Detected Camera', 'ChooseDetectedProfile' => 'Choose Detected Profile', @@ -260,11 +233,7 @@ $SLANG = array( 'ChooseLogSelection' => 'Choose a log selection', 'ChoosePreset' => 'Choose Preset', 'CloneMonitor' => 'Clone', - 'Close' => 'Close', - 'Colour' => 'Colour', - 'Command' => 'Command', 'ConcurrentFilter' => 'Run filter concurrently', - 'Config' => 'Config', 'ConfigOptions' => 'ConfigOptions', 'ConfigType' => 'Config Type', 'ConfiguredFor' => 'Configured for', @@ -276,47 +245,29 @@ $SLANG = array( 'ConfirmPassword' => 'Confirm Password', 'ConjAnd' => 'and', 'ConjOr' => 'or', - 'Console' => 'Console', 'ContactAdmin' => 'Please contact your adminstrator for details.', - 'Continue' => 'Continue', - 'Contrast' => 'Contrast', 'ControlAddress' => 'Control Address', 'ControlCap' => 'Control Capability', 'ControlCaps' => 'Control Capabilities', - 'Control' => 'Control', 'ControlDevice' => 'Control Device', 'Controllable' => 'Controllable', 'ControlType' => 'Control Type', - 'Current' => 'Current', - 'Cycle' => 'Cycle', 'CycleWatch' => 'Cycle Watch', - 'Day' => 'Day', - 'Debug' => 'Debug', 'DefaultRate' => 'Default Rate', 'DefaultScale' => 'Default Scale', 'DefaultCodec' => 'Default Method For Event View', 'DefaultView' => 'Default View', - 'Deinterlacing' => 'Deinterlacing', 'RTSPDescribe' => 'Use RTSP Response Media URL', - 'Delay' => 'Delay', 'DeleteAndNext' => 'Delete & Next', 'DeleteAndPrev' => 'Delete & Prev', - 'Delete' => 'Delete', 'DeleteSavedFilter' => 'Delete saved filter', - 'Description' => 'Description', 'DetectedCameras' => 'Detected Cameras', 'DetectedProfiles' => 'Detected Profiles', 'DeviceChannel' => 'Device Channel', 'DeviceFormat' => 'Device Format', 'DeviceNumber' => 'Device Number', 'DevicePath' => 'Device Path', - 'Device' => 'Device', - 'Devices' => 'Devices', - 'Dimensions' => 'Dimensions', 'DisableAlarms' => 'Disable Alarms', - 'Disk' => 'Disk', - 'Display' => 'Display', - 'Displaying' => 'Displaying', 'DonateAlready' => 'No, I\'ve already donated', 'DonateEnticement' => 'You\'ve been running ZoneMinder for a while now and hopefully are finding it a useful addition to your home or workplace security. Although ZoneMinder is, and will remain, free and open source, it costs money to develop and support. If you would like to help support future development and new features then please consider donating. Donating is, of course, optional but very much appreciated and you can donate as much or as little as you like.

If you would like to donate please select the option below or go to https://zoneminder.com/donate/ in your browser.

Thank you for using ZoneMinder and don\'t forget to visit the forums on ZoneMinder.com for support or suggestions about how to make your ZoneMinder experience even better.', 'Donate' => 'Please Donate', @@ -327,34 +278,23 @@ $SLANG = array( 'DonateRemindWeek' => 'Not yet, remind again in 1 week', 'DonateYes' => 'Yes, I\'d like to donate now', 'DoNativeMotionDetection'=> 'Do Native Motion Detection', - 'Download' => 'Download', 'DuplicateMonitorName' => 'Duplicate Monitor Name', 'DuplicateRTSPStreamName' => 'Duplicate RTSP Stream Name', - 'Duration' => 'Duration', - 'Edit' => 'Edit', 'EditControl' => 'Edit Control', 'EditLayout' => 'Edit Layout', - 'Email' => 'Email', 'EnableAlarms' => 'Enable Alarms', - 'Enabled' => 'Enabled', 'EnterNewFilterName' => 'Enter new filter name', 'ErrorBrackets' => 'Error, please check you have an equal number of opening and closing brackets', - 'Error' => 'Error', 'ErrorValidValue' => 'Error, please check that all terms have a valid value', 'Etc' => 'etc', - 'Event' => 'Event', 'EventFilter' => 'Event Filter', 'EventId' => 'Event Id', 'EventName' => 'Event Name', 'EventPrefix' => 'Event Prefix', - 'Events' => 'Events', - 'Exclude' => 'Exclude', - 'Execute' => 'Execute', 'ExportCompress' => 'Use Compression', 'ExportDetails' => 'Export Event Details', 'ExportMatches' => 'Export Matches', 'Exif' => 'Embed EXIF data into image', - 'Export' => 'Export', 'DownloadVideo' => 'Download Video', 'GenerateDownload' => 'Generate Download', 'ExistsInFileSystem' => 'Exists In File System', @@ -370,11 +310,7 @@ $SLANG = array( 'ExportOptions' => 'Export Options', 'ExportSucceeded' => 'Export Succeeded', 'ExportVideoFiles' => 'Export Video Files (if present)', - 'Far' => 'Far', 'FastForward' => 'Fast Forward', - 'Feed' => 'Feed', - 'Ffmpeg' => 'Ffmpeg', - 'File' => 'File', 'FilterArchiveEvents' => 'Archive all matches', 'FilterUnarchiveEvents' => 'Unarchive all matches', 'FilterUpdateDiskSpace' => 'Update used disk space', @@ -390,13 +326,10 @@ $SLANG = array( 'FilterLog' => 'Filter log', 'FilterMessageEvents' => 'Message details of all matches', 'FilterPx' => 'Filter Px', - 'Filter' => 'Filter', - 'Filters' => 'Filters', 'FilterUnset' => 'You must specify a filter width and height', 'FilterUploadEvents' => 'Upload all matches', 'FilterUser' => 'User to run filter as', 'FilterVideoEvents' => 'Create video for all matches', - 'First' => 'First', 'FlippedHori' => 'Flipped Horizontally', 'FlippedVert' => 'Flipped Vertically', 'FnNone' => 'None', // Added 2013.08.16. @@ -406,29 +339,17 @@ $SLANG = array( 'FnMocord' => 'Mocord', // Added 2013.08.16. 'FnNodect' => 'Nodect', // Added 2013.08.16. 'FnExtdect' => 'Extdect', // Added 2014.12.14. - 'Focus' => 'Focus', 'ForceAlarm' => 'Force Alarm', - 'Format' => 'Format', 'FPS' => 'fps', 'FPSReportInterval' => 'FPS Report Interval', - 'Frame' => 'Frame', 'FrameId' => 'Frame Id', 'FrameRate' => 'Frame Rate', - 'Frames' => 'Frames', 'FrameSkip' => 'Frame Skip', 'MotionFrameSkip' => 'Motion Frame Skip', - 'FTP' => 'FTP', - 'Func' => 'Func', - 'Function' => 'Function', - 'Gain' => 'Gain', - 'General' => 'General', 'GenerateVideo' => 'Generate Video', 'GeneratingVideo' => 'Generating Video', 'GetCurrentLocation' => 'Get Current Location', 'GoToZoneMinder' => 'Go to ZoneMinder.com', - 'Grey' => 'Grey', - 'Group' => 'Group', - 'Groups' => 'Groups', 'HasFocusSpeed' => 'Has Focus Speed', 'HasGainSpeed' => 'Has Gain Speed', 'HasHomePreset' => 'Has Home Preset', @@ -441,49 +362,17 @@ $SLANG = array( 'HasWhiteSpeed' => 'Has White Bal. Speed', 'HasZoomSpeed' => 'Has Zoom Speed', 'HighBW' => 'High B/W', - 'High' => 'High', - 'Home' => 'Home', - 'Hostname' => 'Hostname', - 'Hour' => 'Hour', - 'Hue' => 'Hue', - 'Id' => 'Id', - 'Idle' => 'Idle', - 'Ignore' => 'Ignore', 'ImageBufferSize' => 'Image Buffer Size (frames)', 'MaxImageBufferCount' => 'Maximum Image Buffer Size (frames)', - 'Image' => 'Image', - 'Images' => 'Images', - 'Include' => 'Include', - 'In' => 'In', 'InvalidateTokens' => 'Invalidate all generated tokens', - 'Inverted' => 'Inverted', - 'Iris' => 'Iris', 'KeyString' => 'Key String', - 'Label' => 'Label', - 'Language' => 'Language', - 'Last' => 'Last', - 'Layout' => 'Layout', - 'Libvlc' => 'Libvlc', 'LimitResultsPost' => 'results only', // This is used at the end of the phrase 'Limit to first N results only' 'LimitResultsPre' => 'Limit to first', // This is used at the beginning of the phrase 'Limit to first N results only' 'LinkedMonitors' => 'Linked Monitors', - 'List' => 'List', 'ListMatches' => 'List Matches', - 'Load' => 'Load', - 'Local' => 'Local', - 'Log' => 'Log', - 'Logs' => 'Logs', - 'Logging' => 'Logging', 'LoggedInAs' => 'Logged in as', 'LoggingIn' => 'Logging In', - 'Login' => 'Login', - 'Logout' => 'Logout', 'LowBW' => 'Low B/W', - 'Low' => 'Low', - 'Main' => 'Main', - 'Man' => 'Man', - 'Manual' => 'Manual', - 'Mark' => 'Mark', 'MaxBandwidth' => 'Max Bandwidth', 'MaxBrScore' => 'Max.
Score', 'MaxFocusRange' => 'Max Focus Range', @@ -496,7 +385,6 @@ $SLANG = array( 'MaxIrisRange' => 'Max Iris Range', 'MaxIrisSpeed' => 'Max Iris Speed', 'MaxIrisStep' => 'Max Iris Step', - 'Max' => 'Max', 'MaxPanRange' => 'Max Pan Range', 'MaxPanSpeed' => 'Max Pan Speed', 'MaxPanStep' => 'Max Pan Step', @@ -510,7 +398,6 @@ $SLANG = array( 'MaxZoomSpeed' => 'Max Zoom Speed', 'MaxZoomStep' => 'Max Zoom Step', 'MediumBW' => 'Medium B/W', - 'Medium' => 'Medium', 'MetaConfig' => 'Meta Config', 'MinAlarmAreaLtMax' => 'Minimum alarm area should be less than maximum', 'MinAlarmAreaUnset' => 'You must specify the minimum alarm pixel count', @@ -546,20 +433,13 @@ $SLANG = array( 'MinZoomRange' => 'Min Zoom Range', 'MinZoomSpeed' => 'Min Zoom Speed', 'MinZoomStep' => 'Min Zoom Step', - 'Misc' => 'Misc', - 'Mode' => 'Mode', 'ModectDuringPTZ' => 'Do motion detection during PTZ motion', 'MonitorIds' => 'Monitor Ids', - 'Monitor' => 'Monitor', 'MonitorPresetIntro' => 'Select an appropriate preset from the list below.

Please note that this may overwrite any values you already have configured for the current monitor.

', 'MonitorPreset' => 'Monitor Preset', 'MonitorProbeIntro' => 'The list below shows detected analog and network cameras and whether they are already being used or available for selection.

Select the desired entry from the list below.

Please note that not all cameras may be detected and that choosing a camera here may overwrite any values you already have configured for the current monitor.

', 'MonitorProbe' => 'Monitor Probe', - 'Monitors' => 'Monitors', - 'Montage' => 'Montage', 'MontageReview' => 'Montage Review', - 'Month' => 'Month', - 'Move' => 'Move', 'MtgDefault' => 'Default', // Added 2013.08.15. 'Mtg2widgrd' => '2-wide grid', // Added 2013.08.15. 'Mtg3widgrd' => '3-wide grid', // Added 2013.08.15. @@ -570,35 +450,23 @@ $SLANG = array( 'MustConfirmPassword' => 'You must confirm the password', 'MustSupplyPassword' => 'You must supply a password', 'MustSupplyUsername' => 'You must supply a username', - 'Name' => 'Name', - 'Near' => 'Near', - 'Network' => 'Network', 'NewGroup' => 'New Group', 'NewLabel' => 'New Label', - 'New' => 'New', 'NewPassword' => 'New Password', 'NewState' => 'New State', 'NewUser' => 'New User', - 'Next' => 'Next', 'NextMonitor' => 'Next Monitor', 'NoDetectedCameras' => 'No Detected Cameras', 'NoDetectedProfiles' => 'No Detected Profiles', 'NoFramesRecorded' => 'There are no frames recorded for this event', 'NoGroup' => 'No Group', 'NoneAvailable' => 'None available', - 'None' => 'None', - 'No' => 'No', - 'Normal' => 'Normal', - 'NoSavedFilters' => 'NoSavedFilters', + 'NoSavedFilters' => 'No Saved Filters', 'NoStatisticsRecorded' => 'There are no statistics recorded for this event/frame', - 'Notes' => 'Notes', 'NumPresets' => 'Num Presets', - 'Off' => 'Off', - 'On' => 'On', 'OnvifProbe' => 'ONVIF', 'OnvifProbeIntro' => 'The list below shows detected ONVIF cameras and whether they are already being used or available for selection.

Select the desired entry from the list below.

Please note that not all cameras may be detected and that choosing a camera here may overwrite any values you already have configured for the current monitor.

', 'OnvifCredentialsIntro' => 'Please supply user name and password for the selected camera.
If no user has been created for the camera then the user given here will be created with the given password.

', - 'Open' => 'Open', 'OpEq' => 'equal to', 'OpGtEq' => 'greater than or equal to', 'OpGt' => 'greater than', @@ -619,42 +487,26 @@ $SLANG = array( 'Options' => 'Options', 'Order' => 'Order', 'OrEnterNewName' => 'or enter new name', - 'Orientation' => 'Orientation', - 'Out' => 'Out', 'OverwriteExisting' => 'Overwrite Existing', - 'Paged' => 'Paged', 'PanLeft' => 'Pan Left', - 'Pan' => 'Pan', 'PanRight' => 'Pan Right', 'PanTilt' => 'Pan/Tilt', - 'Parameter' => 'Parameter', 'ParentGroup' => 'Parent Group', - 'Password' => 'Password', 'PasswordsDifferent' => 'The new and confirm passwords are different', 'PathToIndex' => 'Path To Index', 'PathToZMS' => 'Path To ZMS', 'PathToApi' => 'Path To Api', - 'Paths' => 'Paths', - 'Pause' => 'Pause', 'PauseCycle' => 'Pause Cycle', 'PhoneBW' => 'Phone B/W', - 'Phone' => 'Phone', 'PixelDiff' => 'Pixel Diff', 'Pixels' => 'pixels', 'PlayAll' => 'Play All', - 'Play' => 'Play', 'PlayCycle' => 'Play Cycle', - 'Plugins' => 'Plugins', 'PleaseWait' => 'Please Wait', - 'Point' => 'Point', 'PostEventImageBuffer' => 'Post Event Image Count', 'PreEventImageBuffer' => 'Pre Event Image Count', 'PreserveAspect' => 'Preserve Aspect Ratio', - 'Preset' => 'Preset', - 'Presets' => 'Presets', - 'Prev' => 'Prev', 'PreviousMonitor' => 'Previous Monitor', - 'Privacy' => 'Privacy', 'PrivacyAbout' => 'About', 'PrivacyAboutText' => 'Since 2002, ZoneMinder has been the premier free and open-source Video Management System (VMS) solution for Linux platforms. ZoneMinder is supported by the community and is managed by those who choose to volunteer their spare time to the project. The best way to improve ZoneMinder is to get involved.', 'PrivacyContact' => 'Contact', @@ -694,15 +546,9 @@ $SLANG = array( 'Probe' => 'Probe', 'ProfileProbe' => 'Stream Probe', 'ProfileProbeIntro' => 'The list below shows the existing stream profiles of the selected camera .

Select the desired entry from the list below.

Please note that ZoneMinder cannot configure additional profiles and that choosing a camera here may overwrite any values you already have configured for the current monitor.

', - 'Progress' => 'Progress', - 'Protocol' => 'Protocol', - 'Rate' => 'Rate', 'RecaptchaWarning' => 'Your reCaptcha secret key is invalid. Please correct it, or reCaptcha will not work', // added Sep 24 2015 - PP - 'RecordAudio' => 'Whether to store the audio stream when saving an event.', - 'Real' => 'Real', - 'Record' => 'Record', + 'RecordAudio' => 'Whether to store the audio stream when saving an event.', 'RefImageBlendPct' => 'Reference Image Blend %ge', - 'Refresh' => 'Refresh', 'RemoteHostName' => 'Host Name', 'RemoteHostPath' => 'Path', 'RemoteHostSubPath' => 'SubPath', @@ -710,30 +556,22 @@ $SLANG = array( 'RemoteImageColours' => 'Image Colours', 'RemoteMethod' => 'Method', 'RemoteProtocol' => 'Protocol', - 'Remote' => 'Remote', - 'Rename' => 'Rename', 'ReplayAll' => 'All Events', 'ReplayGapless' => 'Gapless Events', - 'Replay' => 'Replay', 'ReplaySingle' => 'Single Event', 'ReportEventAudit' => 'Audit Events Report', 'ResetEventCounts' => 'Reset Event Counts', - 'Reset' => 'Reset', - 'Restarting' => 'Restarting', - 'Restart' => 'Restart', 'RestrictedCameraIds' => 'Restricted Camera Ids', 'RestrictedMonitors' => 'Restricted Monitors', 'ReturnDelay' => 'Return Delay', 'ReturnLocation' => 'Return Location', - 'RevokeAllTokens' => 'Revoke All Tokens', - 'Rewind' => 'Rewind', + 'RevokeAllTokens' => 'Revoke All Tokens', 'RotateLeft' => 'Rotate Left', 'RotateRight' => 'Rotate Right', 'RTSPTransport' => 'RTSP Transport Protocol', 'RunAudit' => 'Run Audit Process', 'RunLocalUpdate' => 'Please run zmupdate.pl to update', 'RunMode' => 'Run Mode', - 'Running' => 'Running', 'RunState' => 'Run State', 'RunStats' => 'Run Stats Process', 'RunTrigger' => 'Run Trigger Process', @@ -741,45 +579,29 @@ $SLANG = array( 'SaveAs' => 'Save as', 'SaveFilter' => 'Save Filter', 'SaveJPEGs' => 'Save JPEGs', - 'Save' => 'Save', - 'Scale' => 'Scale', - 'Score' => 'Score', - 'Secs' => 'Secs', 'Sectionlength' => 'Section length', 'SelectMonitors' => 'Select Monitors', - 'Select' => 'Select', 'SelectFormat' => 'Select Format', 'SelectLog' => 'Select Log', 'SelfIntersecting' => 'Polygon edges must not intersect', 'SetNewBandwidth' => 'Set New Bandwidth', 'SetPreset' => 'Set Preset', - 'Set' => 'Set', - 'Settings' => 'Settings', 'ShowFilterWindow' => 'Show Filter Window', 'ShowTimeline' => 'Show Timeline', - 'Shutdown' => 'Shutdown', 'SignalCheckColour' => 'Signal Check Colour', 'SignalCheckPoints' => 'Signal Check Points', - 'Size' => 'Size', 'SkinDescription' => 'Change the skin for this session', 'CSSDescription' => 'Change the css for this session', - 'Sleep' => 'Sleep', 'SortAsc' => 'Asc', 'SortBy' => 'Sort by', 'SortDesc' => 'Desc', - 'Source' => 'Source', 'SourceColours' => 'Source Colours', 'SourcePath' => 'Source Path', 'SourceType' => 'Source Type', 'SpeedHigh' => 'High Speed', 'SpeedLow' => 'Low Speed', 'SpeedMedium' => 'Medium Speed', - 'Speed' => 'Speed', 'SpeedTurbo' => 'Turbo Speed', - 'Start' => 'Start', - 'State' => 'State', - 'Stats' => 'Stats', - 'Status' => 'Status', 'StatusUnknown' => 'Unknown', 'StatusConnected' => 'Capturing', 'StatusNotRunning' => 'Not Running', @@ -790,23 +612,12 @@ $SLANG = array( 'StepMedium' => 'Medium Step', 'StepNone' => 'No Step', 'StepSmall' => 'Small Step', - 'Step' => 'Step', - 'Stills' => 'Stills', - 'Stopped' => 'Stopped', - 'Stop' => 'Stop', 'StorageArea' => 'Storage Area', 'StorageDoDelete' => 'Do Deletes', 'StorageScheme' => 'Scheme', 'StreamReplayBuffer' => 'Stream Replay Image Buffer', - 'Stream' => 'Stream', - 'Submit' => 'Submit', - 'System' => 'System', 'TargetColorspace' => 'Target colorspace', - 'Tele' => 'Tele', - 'Thumbnail' => 'Thumbnail', - 'Tilt' => 'Tilt', 'TimeDelta' => 'Time Delta', - 'Timeline' => 'Timeline', 'TimelineTip1' => 'Pass your mouse over the graph to view a snapshot image and event details.', // Added 2013.08.15. 'TimelineTip2' => 'Click on the coloured sections of the graph, or the image, to view the event.', // Added 2013.08.15. 'TimelineTip3' => 'Click on the background to zoom in to a smaller time period based around your click.', // Added 2013.08.15. @@ -815,44 +626,25 @@ $SLANG = array( 'TimestampLabelX' => 'Timestamp Label X', 'TimestampLabelY' => 'Timestamp Label Y', 'TimestampLabelSize' => 'Font Size', - 'Timestamp' => 'Timestamp', 'TimeStamp' => 'Time Stamp', - 'Time' => 'Time', - 'Today' => 'Today', - 'Tools' => 'Tools', - 'Total' => 'Total', 'TotalBrScore' => 'Total
Score', 'TrackDelay' => 'Track Delay', 'TrackMotion' => 'Track Motion', - 'Triggers' => 'Triggers', 'TurboPanSpeed' => 'Turbo Pan Speed', 'TurboTiltSpeed' => 'Turbo Tilt Speed', - 'Type' => 'Type', 'TZUnset' => 'Unset - use value in php.ini', - 'Unarchive' => 'Unarchive', - 'Undefined' => 'Undefined', - 'Units' => 'Units', - 'Unknown' => 'Unknown', 'UpdateAvailable' => 'An update to ZoneMinder is available.', 'UpdateNotNecessary' => 'No update is necessary.', - 'Update' => 'Update', - 'Upload' => 'Upload', - 'Updated' => 'Updated', - 'UsedPlugins' => 'Used Plugins', + 'UsedPlugins' => 'Used Plugins', 'UseFilterExprsPost' => ' filter expressions', // This is used at the end of the phrase 'use N filter expressions' 'UseFilterExprsPre' => 'Use ', // This is used at the beginning of the phrase 'use N filter expressions' 'UseFilter' => 'Use Filter', - 'Username' => 'Username', - 'Users' => 'Users', - 'User' => 'User', - 'Value' => 'Value', 'VersionIgnore' => 'Ignore this version', 'VersionRemindDay' => 'Remind again in 1 day', 'VersionRemindHour' => 'Remind again in 1 hour', 'VersionRemindNever' => 'Don\'t remind about new versions', 'VersionRemindWeek' => 'Remind again in 1 week', 'VersionRemindMonth' => 'Remind again in 1 month', - 'Version' => 'Version', 'ViewMatches' => 'View Matches', 'VideoFormat' => 'Video Format', 'VideoGenFailed' => 'Video Generation Failed!', @@ -862,31 +654,19 @@ $SLANG = array( 'VideoGenSucceeded' => 'Video Generation Succeeded!', 'VideoSize' => 'Video Size', 'VideoWriter' => 'Video Writer', - 'Video' => 'Video', 'ViewAll' => 'View All', 'ViewEvent' => 'View Event', 'ViewPaged' => 'View Paged', - 'View' => 'View', - 'V4LCapturesPerFrame' => 'Captures Per Frame', - 'V4LMultiBuffer' => 'Multi Buffering', - 'Wake' => 'Wake', + 'V4LCapturesPerFrame' => 'Captures Per Frame', + 'V4LMultiBuffer' => 'Multi Buffering', 'WarmupFrames' => 'Warmup Frames', - 'Watch' => 'Watch', 'WebColour' => 'Web Colour', - 'Web' => 'Web', 'WebSiteUrl' => 'Website URL', - 'Week' => 'Week', 'WhiteBalance' => 'White Balance', - 'White' => 'White', - 'Wide' => 'Wide', 'X10ActivationString' => 'X10 Activation String', 'X10InputAlarmString' => 'X10 Input Alarm String', 'X10OutputAlarmString' => 'X10 Output Alarm String', - 'X10' => 'X10', - 'X' => 'X', - 'Yes' => 'Yes', 'YouNoPerms' => 'You do not have permissions to access this resource.', - 'Y' => 'Y', 'ZoneAlarmColour' => 'Alarm Colour (Red/Green/Blue)', 'ZoneArea' => 'Zone Area', 'ZoneFilterSize' => 'Filter Width/Height (pixels)', @@ -898,11 +678,8 @@ $SLANG = array( 'ZoneMinMaxPixelThres' => 'Min/Max Pixel Threshold (0-255)', 'ZoneOverloadFrames' => 'Overload Frame Ignore Count', 'ZoneExtendAlarmFrames' => 'Extend Alarm Frame Count', - 'Zones' => 'Zones', - 'Zone' => 'Zone', 'ZoomIn' => 'Zoom In', 'ZoomOut' => 'Zoom Out', - 'Zoom' => 'Zoom', ); // Complex replacements with formatting and/or placements, must be passed through sprintf @@ -960,17 +737,14 @@ $VLANG = array( // // In languages such as English this is fairly simple // Note this still has to be used with printf etc to get the right formatting -function zmVlang( $langVarArray, $count ) -{ - krsort( $langVarArray ); - foreach ( $langVarArray as $key=>$value ) - { - if ( abs($count) >= $key ) - { - return( $value ); - } +function zmVlang($langVarArray, $count) { + krsort($langVarArray); + foreach ($langVarArray as $key=>$value) { + if (abs($count) >= $key) { + return $value; } - die( 'Error, unable to correlate variable language string' ); + } + ZM\Error('Unable to correlate variable language string'); } // This is an version that could be used in the Russian example above From 2336926d90f97646119f41e06f614b23768c6669 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 16 Feb 2022 14:16:01 -0500 Subject: [PATCH 12/28] Rework to remove static temp_img_buffer. Is now a class member. Must be allocated as needed. Use new reworked zm_sendfile and handle if not all bytes are sent. Fixes #3437. --- src/zm_eventstream.cpp | 47 +++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/src/zm_eventstream.cpp b/src/zm_eventstream.cpp index 34f693f36..4521aaf89 100644 --- a/src/zm_eventstream.cpp +++ b/src/zm_eventstream.cpp @@ -799,7 +799,13 @@ bool EventStream::sendFrame(Microseconds delta_us) { } Image *send_image = prepareImage(image); - static unsigned char temp_img_buffer[ZM_MAX_IMAGE_SIZE]; + if (temp_img_buffer_size < send_image->Size()) { + Debug(1, "Resizing image buffer from %zu to %u", + temp_img_buffer_size, send_image->Size()); + delete[] temp_img_buffer; + temp_img_buffer = new uint8_t[send_image->Size()]; + temp_img_buffer_size = send_image->Size(); + } int img_buffer_size = 0; uint8_t *img_buffer = temp_img_buffer; @@ -1098,14 +1104,12 @@ void EventStream::runStream() { } // end void EventStream::runStream() bool EventStream::send_file(const std::string &filepath) { - FILE *fdj = nullptr; - fdj = fopen(filepath.c_str(), "rb"); + FILE *fdj = fopen(filepath.c_str(), "rb"); if (!fdj) { Error("Can't open %s: %s", filepath.c_str(), strerror(errno)); std::string error_message = stringtf("Can't open %s: %s", filepath.c_str(), strerror(errno)); return sendTextFrame(error_message.c_str()); } -#if HAVE_SENDFILE static struct stat filestat; if (fstat(fileno(fdj), &filestat) < 0) { fclose(fdj); /* Close the file handle */ @@ -1117,33 +1121,30 @@ bool EventStream::send_file(const std::string &filepath) { Info("File size is zero. Unable to send raw frame %d: %s", curr_frame_id, strerror(errno)); return false; } - if (0 > fprintf(stdout, "Content-Length: %d\r\n\r\n", (int)filestat.st_size)) { + if (0 > fprintf(stdout, "Content-Length: %jd\r\n\r\n", filestat.st_size)) { fclose(fdj); /* Close the file handle */ Info("Unable to send raw frame %d: %s", curr_frame_id, strerror(errno)); return false; } - int rc = zm_sendfile(fileno(stdout), fileno(fdj), 0, (int)filestat.st_size); - if (rc == (int)filestat.st_size) { + ssize_t remaining = filestat.st_size; + + while (remaining > 0) { + ssize_t rc = zm_sendfile(fileno(stdout), fileno(fdj), nullptr, remaining); + if (rc < 0) break; + if (rc > 0) { + remaining -= rc; + } + } // end while remaining + + if (!remaining) { // Success fclose(fdj); /* Close the file handle */ return true; } - Warning("Unable to send raw frame %d: %s rc %d != %d", - curr_frame_id, strerror(errno), rc, (int)filestat.st_size); -#endif - - static unsigned char temp_img_buffer[ZM_MAX_IMAGE_SIZE]; - - uint8_t *img_buffer = temp_img_buffer; - int img_buffer_size = fread(img_buffer, 1, sizeof(temp_img_buffer), fdj); - fclose(fdj); /* Close the file handle */ - if ( !img_buffer_size ) { - Info("Unable to read raw frame %d: %s", curr_frame_id, strerror(errno)); - return false; - } - - return send_buffer(img_buffer, img_buffer_size); -} + Warning("Unable to send raw frame %d: %s %zu remaining", + curr_frame_id, strerror(errno), remaining); + return false; +} // end bool EventStream::send_file(const std::string &filepath) bool EventStream::send_buffer(uint8_t* buffer, int size) { if ( 0 > fprintf(stdout, "Content-Length: %d\r\n\r\n", size) ) { From 243c780a6a22e1af7aa3a23ee4a3964effed485f Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 16 Feb 2022 14:16:25 -0500 Subject: [PATCH 13/28] cleanup and add fallback to read/write if no sendfile support. --- src/zm_sendfile.h | 51 +++++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/src/zm_sendfile.h b/src/zm_sendfile.h index 3568e2fea..4edabccab 100644 --- a/src/zm_sendfile.h +++ b/src/zm_sendfile.h @@ -3,37 +3,44 @@ #ifdef HAVE_SENDFILE4_SUPPORT #include -ssize_t zm_sendfile(int out_fd, int in_fd, off_t *offset, size_t size) { - size_t remaining = size; - while (remaining) { - ssize_t err = sendfile(out_fd, in_fd, offset, remaining); - if (err < 0) { - return -errno; - } - remaining -= err; - offset += err; - } - - return size-remaining; -} #elif HAVE_SENDFILE7_SUPPORT #include #include #include -ssize_t zm_sendfile(int out_fd, int in_fd, off_t *offset, off_t size) { +#else +#include +#endif + +/* Function to send the contents of a file. Will use sendfile or fall back to reading/writing */ + +ssize_t zm_sendfile(int out_fd, int in_fd, off_t *offset, size_t size) { +#ifdef HAVE_SENDFILE4_SUPPORT + ssize_t err = sendfile(out_fd, in_fd, offset, size); + if (err < 0) { + return -errno; + } + return err; + +#elif HAVE_SENDFILE7_SUPPORT ssize_t err = sendfile(in_fd, out_fd, *offset, size, nullptr, &size, 0); if (err && errno != EAGAIN) return -errno; - - if (size) { - *offset += size; - return size; + return size; +#else + uint8_t buffer[size]; + ssize_t err = read(in_fd, buffer, size); + if (err < 0) { + Error("Unable to read %zu bytes: %s", size, strerror(errno)); + return -errno; } - return -EAGAIN; -} -#else -#error "Your platform does not support sendfile. Sorry." + err = fwrite(out_fd, buffer, size); + if (err < 0) { + Error("Unable to write %zu bytes: %s", size, strerror(errno)); + return -errno; + } + return err; #endif +} #endif // ZM_SENDFILE_H From 67563737c3fdc58e972cbeb298c6316f905bf0a7 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 16 Feb 2022 14:16:46 -0500 Subject: [PATCH 14/28] Rework to remove static temp_img_buffer. Is now a class member. Must be allocated as needed. --- src/zm_stream.cpp | 6 ++---- src/zm_stream.h | 7 ++++++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/zm_stream.cpp b/src/zm_stream.cpp index 084bd6754..b3b3aa120 100644 --- a/src/zm_stream.cpp +++ b/src/zm_stream.cpp @@ -31,10 +31,8 @@ constexpr Seconds StreamBase::MAX_STREAM_DELAY; constexpr Milliseconds StreamBase::MAX_SLEEP; StreamBase::~StreamBase() { - if (vid_stream) { - delete vid_stream; - vid_stream = nullptr; - } + delete vid_stream; + delete temp_img_buffer; closeComms(); } diff --git a/src/zm_stream.h b/src/zm_stream.h index d89d97e7f..de58fcf7b 100644 --- a/src/zm_stream.h +++ b/src/zm_stream.h @@ -144,6 +144,9 @@ protected: CmdMsg msg; + unsigned char *temp_img_buffer; // Used when encoding or sending file data + size_t temp_img_buffer_size; + protected: bool loadMonitor(int monitor_id); bool checkInitialised(); @@ -182,7 +185,9 @@ public: actual_fps(0.0), frame_count(0), last_frame_count(0), - frame_mod(1) + frame_mod(1), + temp_img_buffer(nullptr), + temp_img_buffer_size(0) { memset(&loc_sock_path, 0, sizeof(loc_sock_path)); memset(&loc_addr, 0, sizeof(loc_addr)); From c9de883a7c1d9a61b76ccaaca62677b9e7c6581a Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 16 Feb 2022 14:18:37 -0500 Subject: [PATCH 15/28] Rework to remove static temp_img_buffer. Is now a class member. Must be allocated as needed. --- src/zm_monitorstream.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/zm_monitorstream.cpp b/src/zm_monitorstream.cpp index a6232a23e..2bb82d360 100644 --- a/src/zm_monitorstream.cpp +++ b/src/zm_monitorstream.cpp @@ -422,12 +422,17 @@ bool MonitorStream::sendFrame(Image *image, SystemTimePoint timestamp) { /* double pts = */ vid_stream->EncodeFrame(send_image->Buffer(), send_image->Size(), config.mpeg_timed_frames, delta_time.count()); } else { - static unsigned char temp_img_buffer[ZM_MAX_IMAGE_SIZE]; + if (temp_img_buffer_size < send_image->Size()) { + Debug(1, "Resizing image buffer from %zu to %u", + temp_img_buffer_size, send_image->Size()); + delete[] temp_img_buffer; + temp_img_buffer = new uint8_t[send_image->Size()]; + temp_img_buffer_size = send_image->Size(); + } int img_buffer_size = 0; unsigned char *img_buffer = temp_img_buffer; - switch ( type ) { case STREAM_JPEG : send_image->EncodeJpeg(img_buffer, &img_buffer_size); From b9e6cf803871a758be5a0b408f126e70db541389 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 16 Feb 2022 17:27:12 -0500 Subject: [PATCH 16/28] Spacing, remove dead code, add comments. When implementing CLOSE_ALARM mode, check Alarm Frames against alarm_frame_count instead of 0. --- src/zm_monitor.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index c094aecff..026fad766 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -1747,7 +1747,7 @@ bool Monitor::Analyse() { Event::StringSetMap noteSetMap; #ifdef WITH_GSOAP - if (onvif_event_listener && Event_Poller_Healthy) { + if (onvif_event_listener && Event_Poller_Healthy) { if (Poll_Trigger_State) { score += 9; Debug(1, "Triggered on ONVIF"); @@ -1856,9 +1856,6 @@ bool Monitor::Analyse() { // So... Debug(1, "Waiting for decode"); packet_lock->wait(); - //packetqueue.unlock(packet_lock); // This will delete packet_lock and notify_all - //packetqueue.wait(); - ////packet_lock->lock(); } // end while ! decoded if (zm_terminate or analysis_thread->Stopped()) { delete packet_lock; @@ -1890,7 +1887,7 @@ bool Monitor::Analyse() { Image v_image(snap->in_frame->width, snap->in_frame->height, 1, ZM_SUBPIX_ORDER_NONE, snap->in_frame->data[0], 0); ref_image.Assign(v_image); } else { - Debug(1, "assigning refimage from snap->image"); + Debug(1, "assigning refimage from snap->image"); ref_image.Assign(*(snap->image)); } alarm_image.Assign(*(snap->image)); @@ -1956,7 +1953,7 @@ bool Monitor::Analyse() { if ((state == IDLE) || (state == TAPE) || (state == PREALARM)) { // If we should end then previous continuous event and start a new non-continuous event if (event && event->Frames() - && !event->AlarmFrames() + && (event->AlarmFrames() < alarm_frame_count) && (event_close_mode == CLOSE_ALARM) // FIXME since we won't be including this snap in the event if we close it, we should be looking at event->duration() instead && (event->Duration() >= min_section_length) @@ -2016,7 +2013,7 @@ bool Monitor::Analyse() { if ( ((analysis_image_count - last_alarm_count) > post_event_count) && - (event->Duration() >= min_section_length)) { + (event->Duration() >= min_section_length)) { Info("%s: %03d - Left alarm state (%" PRIu64 ") - %d(%d) images", name.c_str(), analysis_image_count, event->Id(), event->Frames(), event->AlarmFrames()); if ( @@ -2051,6 +2048,7 @@ bool Monitor::Analyse() { Event::EmptyPreAlarmFrames(); } // end if score or not + // At this point, snap ONLY has motion score, so this adds other sources if (score > snap->score) snap->score = score; From 909c0e903f8660ed9ede5e23052156327912a738 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 17 Feb 2022 13:30:01 -0500 Subject: [PATCH 17/28] Include EndDateTimeShort in event ajax response --- web/ajax/status.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/web/ajax/status.php b/web/ajax/status.php index 0d17213a5..b37a3bda6 100644 --- a/web/ajax/status.php +++ b/web/ajax/status.php @@ -113,6 +113,7 @@ $statusData = array( 'StartTimeShort' => array( 'sql' => 'date_format( StartDateTime, \''.MYSQL_FMT_DATETIME_SHORT.'\' )' ), 'StartDateTimeShort' => array( 'sql' => 'date_format( StartDateTime, \''.MYSQL_FMT_DATETIME_SHORT.'\' )' ), 'EndDateTime' => true, + 'EndDateTimeShort' => array( 'sql' => 'date_format( EndDateTime, \''.MYSQL_FMT_DATETIME_SHORT.'\' )' ), 'Width' => true, 'Height' => true, 'Length' => true, @@ -141,6 +142,7 @@ $statusData = array( 'StartTimeShort' => array( 'sql' => 'date_format( StartDateTime, \''.MYSQL_FMT_DATETIME_SHORT.'\' )' ), 'StartDateTimeShort' => array( 'sql' => 'date_format( StartDateTime, \''.MYSQL_FMT_DATETIME_SHORT.'\' )' ), 'EndDateTime' => true, + 'EndDateTimeShort' => array( 'sql' => 'date_format( EndDateTime, \''.MYSQL_FMT_DATETIME_SHORT.'\' )' ), 'Width' => true, 'Height' => true, 'Length' => true, From 8dedac1a216fe5f78c8a170f759b53d14b559c11 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 17 Feb 2022 13:30:50 -0500 Subject: [PATCH 18/28] Handle empty endtime more gracefully. If there is a next event just jump to it. --- web/skins/classic/views/js/event.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/web/skins/classic/views/js/event.js b/web/skins/classic/views/js/event.js index 31363e154..1c7a11954 100644 --- a/web/skins/classic/views/js/event.js +++ b/web/skins/classic/views/js/event.js @@ -52,14 +52,19 @@ function vjsReplay() { var overLaid = $j("#videoobj"); overLaid.append('

No more events

'); } else { - var endTime = (Date.parse(eventData.EndDateTime)).getTime(); + if (!eventData.EndDateTime) { + // No EndTime but have a next event, just go to it. + streamNext(true); + return; + } + var endTime = Date.parse(eventData.EndDateTime).getTime(); var nextStartTime = nextEventStartTime.getTime(); //nextEventStartTime.getTime() is a mootools workaround, highjacks Date.parse if ( nextStartTime <= endTime ) { streamNext(true); return; } - var overLaid = $j("#videoobj"); vid.pause(); + var overLaid = $j("#videoobj"); overLaid.append('

'); var gapDuration = (new Date().getTime()) + (nextStartTime - endTime); var messageP = $j('.vjsMessage'); From adf84133336133915eec031ee8a8009eaac443fb Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 17 Feb 2022 13:31:25 -0500 Subject: [PATCH 19/28] Include EndDateTimeShort in event stats --- web/skins/classic/views/js/event.js.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/web/skins/classic/views/js/event.js.php b/web/skins/classic/views/js/event.js.php index c2b61f395..700558cca 100644 --- a/web/skins/classic/views/js/event.js.php +++ b/web/skins/classic/views/js/event.js.php @@ -52,6 +52,7 @@ var eventData = { StartDateTime: 'StartDateTime() ?>', StartDateTimeShort: 'StartDateTime())) ?>', EndDateTime: 'EndDateTime() ?>', + EndDateTimeShort: 'EndDateTime()? strftime(STRF_FMT_DATETIME_SHORT, strtotime($Event->EndDateTime())) : '' ?>', Frames: 'Frames() ?>', AlarmFrames: 'AlarmFrames() ?>', TotScore: 'TotScore() ?>', @@ -75,6 +76,7 @@ var eventDataStrings = { Cause: '', Notes: '', StartDateTimeShort: '', + EndDateTimeShort: '', Length: '', Frames: '', AlarmFrames: '', From 28f3cb18e4458385e6d67e449bd66bdcc05eca1d Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 18 Feb 2022 15:59:00 -0500 Subject: [PATCH 20/28] Make std function warning into a debug. Warning will happen if they are actually used --- src/zm_image.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/zm_image.cpp b/src/zm_image.cpp index 35efa8774..7a2048102 100644 --- a/src/zm_image.cpp +++ b/src/zm_image.cpp @@ -98,7 +98,7 @@ void Image::update_function_pointers() { delta8_abgr = &std_delta8_abgr; delta8_gray8 = &std_delta8_gray8; blend = &std_blend; - Warning("Using slow std functions because pixels %d mod 4=%d", pixels, pixels%4); + Debug(1, "Using slow std functions because pixels %d mod 4=%d", pixels, pixels%4); } else { // Use either sse or neon, or loop unrolled version delta8_rgb = fptr_delta8_rgb; @@ -1167,7 +1167,7 @@ bool Image::WriteJpeg(const std::string &filename, } else if (subpixelorder == ZM_SUBPIX_ORDER_ABGR) { cinfo->in_color_space = JCS_EXT_XBGR; } else { - Warning("Unknwon subpixelorder %d", subpixelorder); + Warning("Unknown subpixelorder %d", subpixelorder); /* Assume RGBA */ cinfo->in_color_space = JCS_EXT_RGBX; } From 002b2c39aa3f97e5200b82405bb5306dfb24c63d Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 18 Feb 2022 17:08:40 -0500 Subject: [PATCH 21/28] fix button assignments. Don't abort ajax, as it might be important --- web/js/MonitorStream.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/web/js/MonitorStream.js b/web/js/MonitorStream.js index 86b9b97e0..110f1665d 100644 --- a/web/js/MonitorStream.js +++ b/web/js/MonitorStream.js @@ -26,7 +26,7 @@ function MonitorStream(monitorData) { this.buttons = {}; // index by name this.setButton = function(name, element) { - this.buttons.name = element; + this.buttons[name] = element; }; this.element = null; @@ -380,6 +380,8 @@ function MonitorStream(monitorData) { if ('enableAlarmButton' in this.buttons) { this.buttons.enableAlarmButton.addClass('disabled'); this.buttons.enableAlarmButton.prop('title', disableAlarmsStr); + } else { + console.log('enableAlarmButton not found in buttons'); } if ('forceAlarmButton' in this.buttons) { if (streamStatus.forced) { @@ -390,8 +392,11 @@ function MonitorStream(monitorData) { this.buttons.forceAlarmButton.prop('title', forceAlarmStr); } this.buttons.forceAlarmButton.prop('disabled', false); + } else { + console.log('forceAlarmButton not found in buttons'); } } else { + console.log("streamStatus not enabled"); if ('enableAlarmButton' in this.buttons) { this.buttons.enableAlarmButton.removeClass('disabled'); this.buttons.enableAlarmButton.prop('title', enableAlarmsStr); @@ -462,6 +467,8 @@ function MonitorStream(monitorData) { this.alarmCommand = function(command) { if (this.ajaxQueue) { + console.log("Aborting in progress ajax for alarm"); + // Doing this for responsiveness, but we could be aborting something important. Need smarter logic this.ajaxQueue.abort(); } const alarmCmdParms = Object.assign({}, this.streamCmdParms); @@ -485,9 +492,6 @@ function MonitorStream(monitorData) { } this.streamCmdReq = function(streamCmdParms) { - if (this.ajaxQueue) { - this.ajaxQueue.abort(); - } this.ajaxQueue = jQuery.ajaxQueue({url: this.url, data: streamCmdParms, dataType: "json"}) .done(this.getStreamCmdResponse.bind(this)) .fail(this.onFailure.bind(this)); From 1a54a96c0479537411205a6e6c84961409520833 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 18 Feb 2022 17:09:24 -0500 Subject: [PATCH 22/28] Improve title on alarm buttons when we don't have permission. Move onclick from data-on-click to setup in initPage only if permitted --- web/skins/classic/views/js/watch.js | 8 ++++++++ web/skins/classic/views/watch.php | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/web/skins/classic/views/js/watch.js b/web/skins/classic/views/js/watch.js index 21026c3c8..4af160389 100644 --- a/web/skins/classic/views/js/watch.js +++ b/web/skins/classic/views/js/watch.js @@ -833,6 +833,14 @@ function initPage() { monitorStream.setButton('enableAlarmButton', enableAlmBtn); monitorStream.setButton('forceAlarmButton', forceAlmBtn); monitorStream.setButton('zoomOutButton', $j('zoomOutBtn')); + if (canEdit.Monitors) { + // Will be enabled by streamStatus ajax + enableAlmBtn.on('click', cmdAlarm); + forceAlmBtn.on('click', cmdForce); + } else { + forceAlmBtn.prop('title', forceAlmBtn.prop('title') + ': disabled because cannot edit Monitors'); + enableAlmBtn.prop('title', enableAlmBtn.prop('title') + ': disabled because cannot edit Monitors'); + } /* if (streamMode == 'single') { diff --git a/web/skins/classic/views/watch.php b/web/skins/classic/views/watch.php index fdcdae06d..8ceb06ab2 100644 --- a/web/skins/classic/views/watch.php +++ b/web/skins/classic/views/watch.php @@ -159,8 +159,8 @@ xhtmlHeaders(__FILE__, $monitor->Name().' - '.translate('Feed')); - - + +