From 08aefd881ad67e2f2d62eb5fd279d0149abecb94 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 16 Jan 2024 16:47:14 -0500 Subject: [PATCH] Add decoding_image_count, use it in Ready() instead of image_count. Fix hanging processes due to event start/end command failing because it waits writing to db which isn't really open. Stop analysis thread in Pause. --- src/zm_monitor.cpp | 44 +++++++++++++++++++++++++++++--------------- src/zm_monitor.h | 5 +++-- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index 7e80b2cb7..aa15d66a2 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -256,6 +256,7 @@ Monitor::Monitor() image_count(0), last_capture_image_count(0), analysis_image_count(0), + decoding_image_count(0), motion_frame_count(0), last_motion_frame_count(0), ready_count(0), @@ -2909,6 +2910,7 @@ bool Monitor::Decode() { unsigned int index = shared_data->last_write_index; index++; + decoding_image_count++; index = index % image_buffer_count; image_buffer[index]->Assign(*(packet->image)); image_pixelformats[index] = packet->image->AVPixFormat(); @@ -3034,7 +3036,10 @@ Event * Monitor::openEvent( std::to_string(event->Id()).c_str(), std::to_string(event->MonitorId()).c_str(), nullptr); - Error("Error execing %s", event_start_command.c_str()); + Logger *log = Logger::fetch(); + log->databaseLevel(Logger::NOLOG); + Error("Error execing %s: %s", event_start_command.c_str(), strerror(errno)); + exit(0); } } @@ -3077,14 +3082,16 @@ void Monitor::closeEvent() { int monitor_id = e->MonitorId(); delete e; - if (!command.empty()) { if (fork() == 0) { execlp(command.c_str(), command.c_str(), - std::to_string(event_id).c_str(), - std::to_string(monitor_id).c_str(), // monitor id - nullptr); - Error("Error execing %s", command.c_str()); + std::to_string(event_id).c_str(), + std::to_string(monitor_id).c_str(), + nullptr); + Logger *log = Logger::fetch(); + log->databaseLevel(Logger::NOLOG); + Error("Error execing %s: %s", command.c_str(), strerror(errno)); + exit(0); } } }, event, event_end_command); @@ -3396,13 +3403,19 @@ int Monitor::Pause() { Debug(1, "Stopping packetqueue"); // Wake everyone up packetqueue.stop(); - Debug(1, "Stopped packetqueue"); + // Because the stream indexes may change we have to clear out the packetqueue if (decoder) { Debug(1, "Decoder stopping"); decoder->Stop(); Debug(1, "Decoder stopped"); } + + if (analysis_thread) { + analysis_thread->Stop(); + Debug(1, "Analysis stopped"); + } + // Must close event before closing camera because it uses in_streams if (close_event_thread.joinable()) { Debug(1, "Joining event thread"); @@ -3418,8 +3431,11 @@ int Monitor::Pause() { } } if (camera) camera->Close(); + + packetqueue.clear(); return 1; } + int Monitor::Play() { int ret = camera->PrimeCapture(); if (ret <= 0) return ret; @@ -3441,16 +3457,15 @@ int Monitor::Play() { Debug(1, "Restarting decoder thread"); decoder->Start(); } + if (analysing != ANALYSING_NONE) { + Debug(1, "Restarting analysis thread"); + analysis_thread->Start(); + } return 1; } int Monitor::Close() { Pause(); - if (analysis_thread) { - analysis_thread->Stop(); - Debug(1, "Analysis stopped"); - } - //ONVIF Teardown if (Poller) { Poller->Stop(); @@ -3476,13 +3491,13 @@ int Monitor::Close() { soap = nullptr; } //End ONVIF #endif - //RTSP2Web teardown + //RTSP2Web teardown if (RTSP2Web_enabled and (purpose == CAPTURE) and RTSP2Web_Manager) { delete RTSP2Web_Manager; RTSP2Web_Manager = nullptr; } - //Janus Teardown + //Janus Teardown if (janus_enabled and (purpose == CAPTURE) and Janus_Manager) { delete Janus_Manager; Janus_Manager = nullptr; @@ -3499,7 +3514,6 @@ int Monitor::Close() { video_fifo = nullptr; } - packetqueue.clear(); return 1; } diff --git a/src/zm_monitor.h b/src/zm_monitor.h index dc1b679c9..47813120d 100644 --- a/src/zm_monitor.h +++ b/src/zm_monitor.h @@ -516,8 +516,9 @@ protected: int event_count; int image_count; - int last_capture_image_count; // last value of image_count when calculating capture fps + int last_capture_image_count; // last value of image_count when calculating capture fps int analysis_image_count; // How many frames have been processed by analysis thread. + int decoding_image_count; // How many frames have been processed by analysis thread. int motion_frame_count; // How many frames have had motion detection performed on them. int last_motion_frame_count; // last value of motion_frame_count when calculating fps int ready_count; @@ -709,7 +710,7 @@ public: Debug(4, "Have out of order packets, but no keyframe interval."); return false; } - if (image_count >= ready_count) { + if (decoding_image_count >= ready_count) { Debug(4, "Ready because image_count(%d) >= ready_count(%d)", image_count, ready_count); return true; }