From cd16f3f8e4a2539f374d0b1f8066a358c1634d55 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 28 May 2021 14:00:36 -0400 Subject: [PATCH 01/43] Bump version for 1.36.2 --- distros/redhat/zoneminder.spec | 5 ++++- version | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/distros/redhat/zoneminder.spec b/distros/redhat/zoneminder.spec index d8ce4a742..0432a3a2c 100644 --- a/distros/redhat/zoneminder.spec +++ b/distros/redhat/zoneminder.spec @@ -31,7 +31,7 @@ %global _hardened_build 1 Name: zoneminder -Version: 1.36.1 +Version: 1.36.2 Release: 1%{?dist} Summary: A camera monitoring and analysis tool Group: System Environment/Daemons @@ -425,6 +425,9 @@ ln -sf %{_sysconfdir}/zm/www/zoneminder.nginx.conf %{_sysconfdir}/zm/www/zonemin %dir %attr(755,nginx,nginx) %{_localstatedir}/log/zoneminder %changelog +* Fri May 28 2021 Andrew Bauer - 1.36.2-1 +- 1.36.2 release + * Fri May 21 2021 Andrew Bauer - 1.36.1-1 - 1.36.1 release - add rtspserver submodule diff --git a/version b/version index f107550c2..c6a567b8e 100644 --- a/version +++ b/version @@ -1 +1 @@ -1.36.1 +1.36.2 From 1219bd8d1e5e691b2328885a206a565d2f0f6b6b Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Sun, 30 May 2021 10:54:23 -0400 Subject: [PATCH 02/43] the filename is incorrect so the tmpfiles.d configuration is not being included --- distros/ubuntu2004/{zoneminder.tmpfiles => zoneminder.tmpfile} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename distros/ubuntu2004/{zoneminder.tmpfiles => zoneminder.tmpfile} (100%) diff --git a/distros/ubuntu2004/zoneminder.tmpfiles b/distros/ubuntu2004/zoneminder.tmpfile similarity index 100% rename from distros/ubuntu2004/zoneminder.tmpfiles rename to distros/ubuntu2004/zoneminder.tmpfile From cd36bd9bf512815e3e167d2974ac3f74ea4d3646 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Sat, 29 May 2021 15:05:19 -0400 Subject: [PATCH 03/43] Merge pull request #3266 from Carbenium/fill-out-of-bounds Image: Remove std::vector out-of-bounds access when filling polygons --- cmake/compiler/gcc/settings.cmake | 1 + src/zm_image.cpp | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/cmake/compiler/gcc/settings.cmake b/cmake/compiler/gcc/settings.cmake index ce84dcc1a..2eb3baaed 100644 --- a/cmake/compiler/gcc/settings.cmake +++ b/cmake/compiler/gcc/settings.cmake @@ -19,6 +19,7 @@ endif() if(ASAN) target_compile_options(zm-compile-option-interface INTERFACE + -D_GLIBCXX_SANITIZE_VECTOR=1 -fno-omit-frame-pointer -fsanitize=address -fsanitize-recover=address diff --git a/src/zm_image.cpp b/src/zm_image.cpp index 1acb49e03..60b1dcc02 100644 --- a/src/zm_image.cpp +++ b/src/zm_image.cpp @@ -2513,10 +2513,16 @@ void Image::Fill(Rgb colour, int density, const Polygon &polygon) { ++it; } } + + // Not enough edges to perform the fill operation. + // Continue to next line. + if (active_edges.size() < 2) { + continue; + } std::sort(active_edges.begin(), active_edges.end(), PolygonFill::Edge::CompareX); if (!(scan_line % density)) { - for (auto it = active_edges.begin(); it != active_edges.end(); ++it) { + for (auto it = active_edges.begin(); it < active_edges.end() - 1; ++it) { int32 lo_x = static_cast(it->min_x); int32 hi_x = static_cast(std::next(it)->min_x); if (colours == ZM_COLOUR_GRAY8) { From f723b39cf6584271d871e8a8c3fd93313b048e40 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Sun, 30 May 2021 18:31:26 -0400 Subject: [PATCH 04/43] Apply height css to limit height of logout modal and apply overflow:auto to add a scrollbar if needed so that we don't have to scroll to logout. --- web/skins/classic/css/base/skin.css | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/web/skins/classic/css/base/skin.css b/web/skins/classic/css/base/skin.css index 0920ac2c3..a3ef3b2ce 100644 --- a/web/skins/classic/css/base/skin.css +++ b/web/skins/classic/css/base/skin.css @@ -736,3 +736,13 @@ a.flip { #objdetectModal .modal-content { width: fit-content; } + +#modalLogout .modal-dialog { + height: 100%; +} +#modalLogout .modal-content { + height: 90%; +} +#modalLogout .modal-body { + overflow:auto; +} From 5bdbb25efb760a059b6e89fb7643bbcb58eb4130 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Sun, 30 May 2021 18:31:57 -0400 Subject: [PATCH 05/43] Don't print out buffer since it isn't zero terminated --- src/zm_rtsp_server_fifo_source.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zm_rtsp_server_fifo_source.cpp b/src/zm_rtsp_server_fifo_source.cpp index d83096717..025a15b66 100644 --- a/src/zm_rtsp_server_fifo_source.cpp +++ b/src/zm_rtsp_server_fifo_source.cpp @@ -209,7 +209,7 @@ int ZoneMinderFifoSource::getNextFrame() { Debug(4, "ZM Packet %s header_size %d packet size %u pts %s %" PRId64, header, header_size, data_size, pts_ptr, pts); delete[] header; } else { - Debug(1, "ZM header not found in %d of buffer:%s.", m_buffer.size(), m_buffer.head()); + Debug(1, "ZM header not found in %u of buffer.", m_buffer.size()); m_buffer.clear(); return 0; } From 0e598f67c9a6b8df3a447992183fd317b96244e2 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Sun, 30 May 2021 18:49:09 -0400 Subject: [PATCH 06/43] Bump version to 1.36.3 for release --- distros/redhat/zoneminder.spec | 5 ++++- version | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/distros/redhat/zoneminder.spec b/distros/redhat/zoneminder.spec index 0432a3a2c..64a4dd9f5 100644 --- a/distros/redhat/zoneminder.spec +++ b/distros/redhat/zoneminder.spec @@ -31,7 +31,7 @@ %global _hardened_build 1 Name: zoneminder -Version: 1.36.2 +Version: 1.36.3 Release: 1%{?dist} Summary: A camera monitoring and analysis tool Group: System Environment/Daemons @@ -425,6 +425,9 @@ ln -sf %{_sysconfdir}/zm/www/zoneminder.nginx.conf %{_sysconfdir}/zm/www/zonemin %dir %attr(755,nginx,nginx) %{_localstatedir}/log/zoneminder %changelog +* Sun May 30 2021 Andrew Bauer - 1.36.3-1 +- 1.36.3 release + * Fri May 28 2021 Andrew Bauer - 1.36.2-1 - 1.36.2 release diff --git a/version b/version index c6a567b8e..663224e46 100644 --- a/version +++ b/version @@ -1 +1 @@ -1.36.2 +1.36.3 From 9f6eec792c12fe9d431ddb307270f9e4bcf9d6b1 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 8 Jun 2021 13:01:09 -0400 Subject: [PATCH 07/43] Fix Crud fork --- web/api/app/Plugin/Crud | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/api/app/Plugin/Crud b/web/api/app/Plugin/Crud index 0bd63fb46..14292374c 160000 --- a/web/api/app/Plugin/Crud +++ b/web/api/app/Plugin/Crud @@ -1 +1 @@ -Subproject commit 0bd63fb464957080ead342db58ca9e01532cf1ef +Subproject commit 14292374ccf1328f2d5db20897bd06f99ba4d938 From be5c6371bb68548711bfc440cad8f9a945493713 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 8 Jun 2021 12:50:50 -0400 Subject: [PATCH 08/43] zmstats.pl: add use warnings. Fix log deletion only ever deleting 100 when it should delete more in a loop. Add deleting more than 100 sessions. Fix loop not terminating on Ctrl-C --- scripts/zmstats.pl.in | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/scripts/zmstats.pl.in b/scripts/zmstats.pl.in index 3c86aada6..a03f68ada 100644 --- a/scripts/zmstats.pl.in +++ b/scripts/zmstats.pl.in @@ -1,5 +1,6 @@ #!@PERL_EXECUTABLE@ -wT use strict; +use warnings; use bytes; # ========================================================================== @@ -79,14 +80,18 @@ while (!$zm_terminate) { } my $rows; do { - my $rows = zmDbDo('DELETE FROM `Logs` WHERE `TimeKey` < unix_timestamp(now() - interval '.$Config{ZM_LOG_DATABASE_LIMIT}.') LIMIT 100'); - Debug("Deleted $rows log table entries by time") if defined $rows; - } while ($rows); + $rows = zmDbDo('DELETE FROM `Logs` WHERE `TimeKey` < unix_timestamp(now() - interval '.$Config{ZM_LOG_DATABASE_LIMIT}.') LIMIT 100'); + Debug("Deleted $rows log table entries by time") if $rows; + } while ($rows and ($rows == 100) and !$zm_terminate); } } # end if ZM_LOG_DATABASE_LIMIT - # Delete any sessions that are more ethan a week old. Limiting to 100 because mysql sucks - zmDbDo('DELETE FROM Sessions WHERE access < ? LIMIT 100', time - (60*60*24*7)); + my $rows; + do { + # Delete any sessions that are more than a week old. Limiting to 100 because mysql sucks + $rows = zmDbDo('DELETE FROM Sessions WHERE access < ? LIMIT 100', time - (60*60*24*7)); + Debug("Deleted $rows sessions") if $rows; + } while ($rows and ($rows == 100) and !$zm_terminate); sleep($Config{ZM_STATS_UPDATE_INTERVAL}); } # end while (!$zm_terminate) From f85efc17b4f63a49cedf60ae776d9d737c7229b3 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 25 May 2021 11:20:52 -0400 Subject: [PATCH 09/43] Add samesite when setting cookie for skin and css --- web/index.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/web/index.php b/web/index.php index 5026bb016..ce3d68647 100644 --- a/web/index.php +++ b/web/index.php @@ -139,6 +139,14 @@ $skinBase[] = $skin; zm_session_start(); +$cookie_options = array( + 'expires'=>time()+3600*24*30*12*10, +); +if ( version_compare(phpversion(), '7.3.0', '>=') ) { + # samesite was introduced in 7.3.0 + $cookie_options['samesite'] = 'Strict'; +} + if ( !isset($_SESSION['skin']) || isset($_REQUEST['skin']) || @@ -146,7 +154,7 @@ if ( ($_COOKIE['zmSkin'] != $skin) ) { $_SESSION['skin'] = $skin; - setcookie('zmSkin', $skin, time()+3600*24*30*12*10); + setcookie('zmSkin', $skin, $cookie_options); } if ( @@ -156,7 +164,7 @@ if ( ($_COOKIE['zmCSS'] != $css) ) { $_SESSION['css'] = $css; - setcookie('zmCSS', $css, time()+3600*24*30*12*10); + setcookie('zmCSS', $css, $cookie_options); } # Running is global but only do the daemonCheck if it is actually needed From 74b48c9f21bba4f05c8d8c4070707612bc7cb90e Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 2 Jun 2021 14:59:13 -0400 Subject: [PATCH 10/43] Fix samsite support for php <= 7.2 --- web/index.php | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/web/index.php b/web/index.php index ce3d68647..d003fadb6 100644 --- a/web/index.php +++ b/web/index.php @@ -141,11 +141,8 @@ zm_session_start(); $cookie_options = array( 'expires'=>time()+3600*24*30*12*10, + 'samesite' => 'Strict', ); -if ( version_compare(phpversion(), '7.3.0', '>=') ) { - # samesite was introduced in 7.3.0 - $cookie_options['samesite'] = 'Strict'; -} if ( !isset($_SESSION['skin']) || @@ -154,7 +151,11 @@ if ( ($_COOKIE['zmSkin'] != $skin) ) { $_SESSION['skin'] = $skin; - setcookie('zmSkin', $skin, $cookie_options); + if (version_compare(phpversion(), '7.3.0', '>=')) { + setcookie('zmSkin', $skin, $cookie_options); + } else { + setcookie('zmSkin', $skin, $cookie_options['expires'], '/; samesite=strict'); + } } if ( @@ -164,7 +165,11 @@ if ( ($_COOKIE['zmCSS'] != $css) ) { $_SESSION['css'] = $css; - setcookie('zmCSS', $css, $cookie_options); + if (version_compare(phpversion(), '7.3.0', '>=')) { + setcookie('zmCSS', $css, $cookie_options); + } else { + setcookie('zmCSS', $css, $cookie_options['expires'], '/; samesite=strict'); + } } # Running is global but only do the daemonCheck if it is actually needed From 959107f318b8221ba67383351f3fd75bd8c31d29 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 2 Jun 2021 18:34:26 -0400 Subject: [PATCH 11/43] Default to UTC when no timezone set so that montagereview continues working. Fixes #3274 --- web/skins/classic/views/js/montagereview.js.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/web/skins/classic/views/js/montagereview.js.php b/web/skins/classic/views/js/montagereview.js.php index 291bb99e8..5d43364e7 100644 --- a/web/skins/classic/views/js/montagereview.js.php +++ b/web/skins/classic/views/js/montagereview.js.php @@ -1,6 +1,12 @@ var server_utc_offset = System->Timezone or in php.ini'); +} + +$TimeZone = new DateTimeZone($tz); $now = new DateTime('now', $TimeZone); $offset = $TimeZone->getOffset($now); echo $offset.'; // '.floor($offset / 3600).' hours '; From 4f3552a3e9f9efd9c5055d20ea483c13fbd5feff Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 2 Jun 2021 18:35:08 -0400 Subject: [PATCH 12/43] fix missing namespace on warning --- web/skins/classic/views/js/montagereview.js.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/skins/classic/views/js/montagereview.js.php b/web/skins/classic/views/js/montagereview.js.php index 5d43364e7..d82f103ed 100644 --- a/web/skins/classic/views/js/montagereview.js.php +++ b/web/skins/classic/views/js/montagereview.js.php @@ -3,7 +3,7 @@ var server_utc_offset = System->Timezone or in php.ini'); + ZM\Warning('Timezone has not been set. Either select it in Options->System->Timezone or in php.ini'); } $TimeZone = new DateTimeZone($tz); From a5341beaa50299148c3498a98f051625963c350c Mon Sep 17 00:00:00 2001 From: Xulunix Date: Thu, 3 Jun 2021 02:26:24 +0200 Subject: [PATCH 13/43] Fixed bug in onvifprobe The arguments for "/usr/bin/zmonvif-probe.pl" was always `probe 1.1,1.2 1` with the last argument always being `1` instead of the network interface name selected in the menu. This change fixes this issue by using the selected interface name instead of the boolean return value of the `isset()` function. --- web/skins/classic/views/onvifprobe.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/skins/classic/views/onvifprobe.php b/web/skins/classic/views/onvifprobe.php index 70ad8ead9..754bb50ef 100644 --- a/web/skins/classic/views/onvifprobe.php +++ b/web/skins/classic/views/onvifprobe.php @@ -50,7 +50,7 @@ function execONVIF($cmd) { function probeCameras($localIp) { $cameras = array(); - $lines = @execONVIF('probe 1.1,1.2'.(isset($_REQUEST['interface']) ? ' '.isset($_REQUEST['interface']) : '' )); + $lines = @execONVIF('probe 1.1,1.2'.(isset($_REQUEST['interface']) ? ' '.$_REQUEST['interface'] : '' )); if ( $lines ) { foreach ( $lines as $line ) { $line = rtrim($line); From 13da1aca1438839d414eb09f70b39a66bcc630ac Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 8 Jun 2021 13:37:40 -0400 Subject: [PATCH 14/43] Remove 25x and options. Browsers do not support them. Add 16x which is the max. Fixes #3284 --- web/skins/classic/includes/config.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/web/skins/classic/includes/config.php b/web/skins/classic/includes/config.php index 663fa7fb6..9bed867ed 100644 --- a/web/skins/classic/includes/config.php +++ b/web/skins/classic/includes/config.php @@ -19,8 +19,7 @@ // $rates = array( - -5000 => '-50x', - -2500 => '-25x', + -1600 => '-16x', -1000 => '-10x', -500 => '-5x', -200 => '-2x', @@ -34,8 +33,7 @@ $rates = array( 200 => '2x', 500 => '5x', 1000 => '10x', - 2500 => '25x', - 5000 => '50x' + 1600 => '16x', // Max that Chrome will support ); $scales = array( From eda96d24e093509f665b40b0f02df4e14cf52237 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 31 May 2021 16:02:42 -0400 Subject: [PATCH 15/43] fix crash when in alert state with no event --- src/zm_monitor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index 795cd3e94..fb728ef3d 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -2231,7 +2231,7 @@ bool Monitor::Analyse() { } } else if ( state == ALERT ) { // Alert means this frame has no motion, but we were alarmed and are still recording. - if ( noteSetMap.size() > 0 ) + if ((noteSetMap.size() > 0) and event) event->updateNotes(noteSetMap); } else if ( state == TAPE ) { // bulk frame code moved to event. From a676f7c407893903692b1abc2d25d024cc98c424 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 31 May 2021 15:59:36 -0400 Subject: [PATCH 16/43] SHould reset state as well as shared_data->state --- src/zm_monitor.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index fb728ef3d..60474c541 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -1009,7 +1009,7 @@ bool Monitor::connect() { shared_data->signal = false; shared_data->capture_fps = 0.0; shared_data->analysis_fps = 0.0; - shared_data->state = IDLE; + shared_data->state = state = IDLE; shared_data->last_write_index = image_buffer_count; shared_data->last_read_index = image_buffer_count; shared_data->last_write_time = 0; @@ -2206,8 +2206,8 @@ bool Monitor::Analyse() { snap->analysis_image = new Image(*(snap->image)); snap->analysis_image->Overlay(*(zone.AlarmImage())); } - } // end if zone is alarmed - } // end foreach zone + } // end if zone is alarmed + } // end foreach zone if (event) { if (noteSetMap.size() > 0) event->updateNotes(noteSetMap); @@ -2253,7 +2253,7 @@ bool Monitor::Analyse() { shared_data->last_frame_score = score; } else { Debug(3, "trigger == off"); - if ( event ) { + if (event) { Info("%s: %03d - Closing event %" PRIu64 ", trigger off", name.c_str(), analysis_image_count, event->Id()); closeEvent(); } @@ -2277,7 +2277,7 @@ bool Monitor::Analyse() { // Only do these if it's a video packet. shared_data->last_read_index = snap->image_index; analysis_image_count++; - if ( function == MODECT or function == MOCORD ) + if (function == MODECT or function == MOCORD) UpdateAnalysisFPS(); } packetqueue.unlock(packet_lock); From 61de5eaae5b508fe61e26a772194d11cbc191f89 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 4 Jun 2021 15:03:08 -0400 Subject: [PATCH 17/43] More debugging around clearQueue. return early if deleting --- src/zm_packetqueue.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/zm_packetqueue.cpp b/src/zm_packetqueue.cpp index f73ade20d..394713267 100644 --- a/src/zm_packetqueue.cpp +++ b/src/zm_packetqueue.cpp @@ -174,6 +174,8 @@ void PacketQueue::clearPackets(const std::shared_ptr &add_packet) { // // So start at the beginning, counting video packets until the next keyframe. // Then if deleting those packets doesn't break 1 and 2, then go ahead and delete them. + if (deleting) return; + if (keep_keyframes and ! ( add_packet->packet.stream_index == video_stream_id and @@ -327,10 +329,19 @@ void PacketQueue::clear() { // Someone might have this packet, but not for very long and since we have locked the queue they won't be able to get another one ZMLockedPacket *lp = new ZMLockedPacket(packet); lp->lock(); + Debug(1, + "Deleting a packet with stream index:%d image_index:%d with keyframe:%d, video frames in queue:%d max: %d, queuesize:%zu", + packet->packet.stream_index, + packet->image_index, + packet->keyframe, + packet_counts[video_stream_id], + pre_event_video_packet_count, + pktQueue.size()); pktQueue.pop_front(); delete lp; //delete packet; } + Debug(1, "Packetqueue is clear, deleting iterators"); for ( std::list::iterator iterators_it = iterators.begin(); @@ -345,6 +356,7 @@ void PacketQueue::clear() { packet_counts = nullptr; max_stream_id = -1; + Debug(1, "Packetqueue is clear, notifying"); condition.notify_all(); } From a903ab5d0993f517d22db70554236b8ba0e3ce60 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 3 Jun 2021 18:21:46 -0400 Subject: [PATCH 18/43] Introduce get_packet_and_increase_it just so we can lose an extra grab lock and function calls, etc. In queuePacket, if the queue is full, WAIT instead of failing to queue. --- src/zm_packetqueue.cpp | 63 ++++++++++++++++++++++++++++++++++++++---- src/zm_packetqueue.h | 1 + 2 files changed, 58 insertions(+), 6 deletions(-) diff --git a/src/zm_packetqueue.cpp b/src/zm_packetqueue.cpp index 394713267..9662e4958 100644 --- a/src/zm_packetqueue.cpp +++ b/src/zm_packetqueue.cpp @@ -131,9 +131,13 @@ bool PacketQueue::queuePacket(std::shared_ptr add_packet) { } // end while } } // end if too many video packets - if ((max_video_packet_count > 0) and (packet_counts[video_stream_id] > max_video_packet_count)) { - Error("Unable to free up older packets. Not queueing this video packet."); - return false; + if (max_video_packet_count > 0) { + while (packet_counts[video_stream_id] > max_video_packet_count) { + Error("Unable to free up older packets. Waiting."); + condition.wait(lck); + if (deleting or zm_terminate) + return false; + } } } // end if this packet is a video packet @@ -385,7 +389,7 @@ ZMLockedPacket *PacketQueue::get_packet(packetqueue_iterator *it) { std::unique_lock lck(mutex); Debug(4, "Have Lock in get_packet"); while (!lp) { - while (*it == pktQueue.end() and !(deleting or zm_terminate)) { + while ((*it == pktQueue.end()) and !(deleting or zm_terminate)) { Debug(2, "waiting. Queue size %zu it == end? %d", pktQueue.size(), (*it == pktQueue.end())); condition.wait(lck); } @@ -418,6 +422,53 @@ ZMLockedPacket *PacketQueue::get_packet(packetqueue_iterator *it) { return lp; } // end ZMLockedPacket *PacketQueue::get_packet(it) +// Returns a packet. Packet will be locked +ZMLockedPacket *PacketQueue::get_packet_and_increment_it(packetqueue_iterator *it) { + if (deleting or zm_terminate) + return nullptr; + + Debug(4, "Locking in get_packet using it %p queue end? %d", + std::addressof(*it), (*it == pktQueue.end())); + + ZMLockedPacket *lp = nullptr; + { // scope for lock + std::unique_lock lck(mutex); + Debug(4, "Have Lock in get_packet"); + while (!lp) { + while ((*it == pktQueue.end()) and !(deleting or zm_terminate)) { + Debug(2, "waiting. Queue size %zu it == end? %d", pktQueue.size(), (*it == pktQueue.end())); + condition.wait(lck); + } + if (deleting or zm_terminate) break; + + std::shared_ptr p = *(*it); + if (!p) { + Error("Null p?!"); + return nullptr; + } + Debug(3, "get_packet using it %p locking index %d", + std::addressof(*it), p->image_index); + + lp = new ZMLockedPacket(p); + if (lp->trylock()) { + Debug(2, "Locked packet %d, unlocking packetqueue mutex, incrementing it", p->image_index); + ++(*it); + return lp; + } + delete lp; + lp = nullptr; + Debug(2, "waiting. Queue size %zu it == end? %d", pktQueue.size(), (*it == pktQueue.end())); + condition.wait(lck); + } // end while !lp + } // end scope for lock + + if (!lp) { + Debug(1, "terminated, leaving"); + condition.notify_all(); + } + return lp; +} // end ZMLockedPacket *PacketQueue::get_packet_and_increment_it(it) + void PacketQueue::unlock(ZMLockedPacket *lp) { delete lp; condition.notify_all(); @@ -425,7 +476,7 @@ void PacketQueue::unlock(ZMLockedPacket *lp) { bool PacketQueue::increment_it(packetqueue_iterator *it) { Debug(2, "Incrementing %p, queue size %zu, end? %d", it, pktQueue.size(), ((*it) == pktQueue.end())); - if ((*it) == pktQueue.end() or deleting) { + if (((*it) == pktQueue.end()) or deleting) { return false; } std::unique_lock lck(mutex); @@ -441,7 +492,7 @@ bool PacketQueue::increment_it(packetqueue_iterator *it) { // Increment it only considering packets for a given stream bool PacketQueue::increment_it(packetqueue_iterator *it, int stream_id) { Debug(2, "Incrementing %p, queue size %zu, end? %d", it, pktQueue.size(), (*it == pktQueue.end())); - if ( *it == pktQueue.end() ) { + if (*it == pktQueue.end()) { return false; } diff --git a/src/zm_packetqueue.h b/src/zm_packetqueue.h index a2f57dcfe..7e2f367fc 100644 --- a/src/zm_packetqueue.h +++ b/src/zm_packetqueue.h @@ -70,6 +70,7 @@ class PacketQueue { bool increment_it(packetqueue_iterator *it); bool increment_it(packetqueue_iterator *it, int stream_id); ZMLockedPacket *get_packet(packetqueue_iterator *); + ZMLockedPacket *get_packet_and_increment_it(packetqueue_iterator *); packetqueue_iterator *get_video_it(bool wait); packetqueue_iterator *get_stream_it(int stream_id); void free_it(packetqueue_iterator *); From 85b35cf82c6a3fb03aaea59363d407b775304583 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 3 Jun 2021 18:22:12 -0400 Subject: [PATCH 19/43] Use new get_packet_and_increment_it in decoder. Adjust some debugging levels --- src/zm_monitor.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index 60474c541..2f3f33f79 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -2591,10 +2591,9 @@ int Monitor::Capture() { } // end Monitor::Capture bool Monitor::Decode() { - ZMLockedPacket *packet_lock = packetqueue.get_packet(decoder_it); + ZMLockedPacket *packet_lock = packetqueue.get_packet_and_increment_it(decoder_it); if (!packet_lock) return false; std::shared_ptr packet = packet_lock->packet_; - packetqueue.increment_it(decoder_it); if (packet->codec_type != AVMEDIA_TYPE_VIDEO) { Debug(4, "Not video"); packetqueue.unlock(packet_lock); @@ -2644,13 +2643,16 @@ bool Monitor::Decode() { delete packet->image; packet->image = nullptr; } + Debug(1, "Done assigning about to unref"); av_frame_unref(dest_frame); + Debug(1, "Done assigning onde to unref"); } // end if have convert_context } // end if need transfer to image } else { Debug(1, "No packet.size(%d) or packet->in_frame(%p). Not decoding", packet->packet.size, packet->in_frame); } } // end if need_decoding + Image* capture_image = nullptr; unsigned int index = image_count % image_buffer_count; @@ -2690,7 +2692,7 @@ bool Monitor::Decode() { } if (orientation != ROTATE_0) { - Debug(2, "Doing rotation"); + Debug(3, "Doing rotation"); switch (orientation) { case ROTATE_0 : // No action required @@ -2713,7 +2715,7 @@ bool Monitor::Decode() { } if (config.timestamp_on_capture) { - Debug(3, "Timestampprivacy"); + Debug(3, "Timestamping"); TimestampImage(packet->image, packet->timestamp); } @@ -2721,7 +2723,7 @@ bool Monitor::Decode() { shared_timestamps[index] = packet->timestamp; } // end if have image packet->decoded = true; - shared_data->signal = ( capture_image and signal_check_points ) ? CheckSignal(capture_image) : true; + shared_data->signal = (capture_image and signal_check_points) ? CheckSignal(capture_image) : true; shared_data->last_write_index = index; shared_data->last_write_time = packet->timestamp.tv_sec; packetqueue.unlock(packet_lock); From 25bce3b8cab1242e6fac590bb4e9a4d3bbd8bc56 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 8 Jun 2021 12:51:29 -0400 Subject: [PATCH 20/43] Adjust debug logging --- src/zm_monitor.cpp | 2 -- src/zm_packet.cpp | 18 +++++++++--------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index 2f3f33f79..8118be19f 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -2643,9 +2643,7 @@ bool Monitor::Decode() { delete packet->image; packet->image = nullptr; } - Debug(1, "Done assigning about to unref"); av_frame_unref(dest_frame); - Debug(1, "Done assigning onde to unref"); } // end if have convert_context } // end if need transfer to image } else { diff --git a/src/zm_packet.cpp b/src/zm_packet.cpp index b50ce275f..57bbaebc5 100644 --- a/src/zm_packet.cpp +++ b/src/zm_packet.cpp @@ -132,8 +132,8 @@ int ZMPacket::decode(AVCodecContext *ctx) { #if HAVE_LIBAVUTIL_HWCONTEXT_H #if LIBAVCODEC_VERSION_CHECK(57, 89, 0, 89, 0) - if ( fix_deprecated_pix_fmt(ctx->sw_pix_fmt) != fix_deprecated_pix_fmt(static_cast(in_frame->format)) ) { - Debug(1, "Have different format ctx->pix_fmt %s ?= ctx->sw_pix_fmt %s in_frame->format %s.", + if (fix_deprecated_pix_fmt(ctx->sw_pix_fmt) != fix_deprecated_pix_fmt(static_cast(in_frame->format))) { + Debug(3, "Have different format ctx->pix_fmt %s ?= ctx->sw_pix_fmt %s in_frame->format %s.", av_get_pix_fmt_name(ctx->pix_fmt), av_get_pix_fmt_name(ctx->sw_pix_fmt), av_get_pix_fmt_name(static_cast(in_frame->format)) @@ -180,7 +180,7 @@ int ZMPacket::decode(AVCodecContext *ctx) { /* retrieve data from GPU to CPU */ zm_dump_video_frame(in_frame, "Before hwtransfer"); ret = av_hwframe_transfer_data(new_frame, in_frame, 0); - if ( ret < 0 ) { + if (ret < 0) { Error("Unable to transfer frame: %s, continuing", av_make_error_string(ret).c_str()); av_frame_free(&in_frame); @@ -188,7 +188,7 @@ int ZMPacket::decode(AVCodecContext *ctx) { return 0; } ret = av_frame_copy_props(new_frame, in_frame); - if ( ret < 0 ) { + if (ret < 0) { Error("Unable to copy props: %s, continuing", av_make_error_string(ret).c_str()); } @@ -205,7 +205,7 @@ int ZMPacket::decode(AVCodecContext *ctx) { } else #endif #endif - Debug(2, "Same pix format %s so not hwtransferring. sw_pix_fmt is %s", + Debug(3, "Same pix format %s so not hwtransferring. sw_pix_fmt is %s", av_get_pix_fmt_name(ctx->pix_fmt), av_get_pix_fmt_name(ctx->sw_pix_fmt) ); @@ -219,12 +219,12 @@ int ZMPacket::decode(AVCodecContext *ctx) { } // end ZMPacket::decode Image *ZMPacket::get_image(Image *i) { - if ( !in_frame ) { + if (!in_frame) { Error("Can't get image without frame.. maybe need to decode first"); return nullptr; } - if ( !image ) { - if ( !i ) { + if (!image) { + if (!i) { Error("Need a pre-allocated image buffer"); return nullptr; } @@ -240,7 +240,7 @@ Image *ZMPacket::set_image(Image *i) { } AVPacket *ZMPacket::set_packet(AVPacket *p) { - if ( zm_av_packet_ref(&packet, p) < 0 ) { + if (zm_av_packet_ref(&packet, p) < 0) { Error("error refing packet"); } //ZM_DUMP_PACKET(packet, "zmpacket:"); From 1a6dc18a09d9545e57520e058ad9fbd82baca5be Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 28 May 2021 11:38:48 -0400 Subject: [PATCH 21/43] simplify test for being decoded. timestamping needs to be done as well --- src/zm_monitor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index 8118be19f..c1fadd6e1 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -1855,7 +1855,7 @@ bool Monitor::Analyse() { /* try to stay behind the decoder. */ if (decoding_enabled) { - while ((!snap->image or deinterlacing_value) and !snap->decoded and !zm_terminate and !analysis_thread->Stopped()) { + while (!snap->decoded and !zm_terminate and !analysis_thread->Stopped()) { // Need to wait for the decoder thread. Debug(1, "Waiting for decode"); packet_lock->wait(); From 9dd960beaccf2ab49d6bc9eafc46d4fc98f8febd Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 28 May 2021 13:54:20 -0400 Subject: [PATCH 22/43] Actually close the camera in localcamera::Close --- src/zm_local_camera.cpp | 6 ++++++ src/zm_local_camera.h | 3 +-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/zm_local_camera.cpp b/src/zm_local_camera.cpp index 3ff3608c0..0679a5c5e 100644 --- a/src/zm_local_camera.cpp +++ b/src/zm_local_camera.cpp @@ -705,6 +705,12 @@ LocalCamera::~LocalCamera() { } // end LocalCamera::~LocalCamera +int LocalCamera::Close() { + if (device_prime && capture) + Terminate(); + return 0; +}; + void LocalCamera::Initialise() { Debug(3, "Opening video device %s", device.c_str()); //if ( (vid_fd = open( device.c_str(), O_RDWR|O_NONBLOCK, 0 )) < 0 ) diff --git a/src/zm_local_camera.h b/src/zm_local_camera.h index 6c64e39d6..7bbb285ac 100644 --- a/src/zm_local_camera.h +++ b/src/zm_local_camera.h @@ -153,8 +153,7 @@ public: int PreCapture() override; int Capture(std::shared_ptr &p) override; int PostCapture() override; - int Close() override { return 0; }; - + int Close() override; static bool GetCurrentSettings(const char *device, char *output, int version, bool verbose); }; From 16295598dc97af5789a22fef301e7a9de054fb38 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 8 Jun 2021 15:53:35 -0400 Subject: [PATCH 23/43] spacing --- web/ajax/modals/eventrename.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/web/ajax/modals/eventrename.php b/web/ajax/modals/eventrename.php index c877d57b4..f556a09b0 100644 --- a/web/ajax/modals/eventrename.php +++ b/web/ajax/modals/eventrename.php @@ -1,10 +1,9 @@