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.

pull/3805/head
Isaac Connor 2024-01-16 16:47:14 -05:00
parent 219af38127
commit 08aefd881a
2 changed files with 32 additions and 17 deletions

View File

@ -256,6 +256,7 @@ Monitor::Monitor()
image_count(0), image_count(0),
last_capture_image_count(0), last_capture_image_count(0),
analysis_image_count(0), analysis_image_count(0),
decoding_image_count(0),
motion_frame_count(0), motion_frame_count(0),
last_motion_frame_count(0), last_motion_frame_count(0),
ready_count(0), ready_count(0),
@ -2909,6 +2910,7 @@ bool Monitor::Decode() {
unsigned int index = shared_data->last_write_index; unsigned int index = shared_data->last_write_index;
index++; index++;
decoding_image_count++;
index = index % image_buffer_count; index = index % image_buffer_count;
image_buffer[index]->Assign(*(packet->image)); image_buffer[index]->Assign(*(packet->image));
image_pixelformats[index] = packet->image->AVPixFormat(); image_pixelformats[index] = packet->image->AVPixFormat();
@ -3034,7 +3036,10 @@ Event * Monitor::openEvent(
std::to_string(event->Id()).c_str(), std::to_string(event->Id()).c_str(),
std::to_string(event->MonitorId()).c_str(), std::to_string(event->MonitorId()).c_str(),
nullptr); 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(); int monitor_id = e->MonitorId();
delete e; delete e;
if (!command.empty()) { if (!command.empty()) {
if (fork() == 0) { if (fork() == 0) {
execlp(command.c_str(), command.c_str(), execlp(command.c_str(), command.c_str(),
std::to_string(event_id).c_str(), std::to_string(event_id).c_str(),
std::to_string(monitor_id).c_str(), // monitor id std::to_string(monitor_id).c_str(),
nullptr); nullptr);
Error("Error execing %s", command.c_str()); Logger *log = Logger::fetch();
log->databaseLevel(Logger::NOLOG);
Error("Error execing %s: %s", command.c_str(), strerror(errno));
exit(0);
} }
} }
}, event, event_end_command); }, event, event_end_command);
@ -3396,13 +3403,19 @@ int Monitor::Pause() {
Debug(1, "Stopping packetqueue"); Debug(1, "Stopping packetqueue");
// Wake everyone up // Wake everyone up
packetqueue.stop(); packetqueue.stop();
Debug(1, "Stopped packetqueue");
// Because the stream indexes may change we have to clear out the packetqueue // Because the stream indexes may change we have to clear out the packetqueue
if (decoder) { if (decoder) {
Debug(1, "Decoder stopping"); Debug(1, "Decoder stopping");
decoder->Stop(); decoder->Stop();
Debug(1, "Decoder stopped"); 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 // Must close event before closing camera because it uses in_streams
if (close_event_thread.joinable()) { if (close_event_thread.joinable()) {
Debug(1, "Joining event thread"); Debug(1, "Joining event thread");
@ -3418,8 +3431,11 @@ int Monitor::Pause() {
} }
} }
if (camera) camera->Close(); if (camera) camera->Close();
packetqueue.clear();
return 1; return 1;
} }
int Monitor::Play() { int Monitor::Play() {
int ret = camera->PrimeCapture(); int ret = camera->PrimeCapture();
if (ret <= 0) return ret; if (ret <= 0) return ret;
@ -3441,16 +3457,15 @@ int Monitor::Play() {
Debug(1, "Restarting decoder thread"); Debug(1, "Restarting decoder thread");
decoder->Start(); decoder->Start();
} }
if (analysing != ANALYSING_NONE) {
Debug(1, "Restarting analysis thread");
analysis_thread->Start();
}
return 1; return 1;
} }
int Monitor::Close() { int Monitor::Close() {
Pause(); Pause();
if (analysis_thread) {
analysis_thread->Stop();
Debug(1, "Analysis stopped");
}
//ONVIF Teardown //ONVIF Teardown
if (Poller) { if (Poller) {
Poller->Stop(); Poller->Stop();
@ -3476,13 +3491,13 @@ int Monitor::Close() {
soap = nullptr; soap = nullptr;
} //End ONVIF } //End ONVIF
#endif #endif
//RTSP2Web teardown //RTSP2Web teardown
if (RTSP2Web_enabled and (purpose == CAPTURE) and RTSP2Web_Manager) { if (RTSP2Web_enabled and (purpose == CAPTURE) and RTSP2Web_Manager) {
delete RTSP2Web_Manager; delete RTSP2Web_Manager;
RTSP2Web_Manager = nullptr; RTSP2Web_Manager = nullptr;
} }
//Janus Teardown //Janus Teardown
if (janus_enabled and (purpose == CAPTURE) and Janus_Manager) { if (janus_enabled and (purpose == CAPTURE) and Janus_Manager) {
delete Janus_Manager; delete Janus_Manager;
Janus_Manager = nullptr; Janus_Manager = nullptr;
@ -3499,7 +3514,6 @@ int Monitor::Close() {
video_fifo = nullptr; video_fifo = nullptr;
} }
packetqueue.clear();
return 1; return 1;
} }

View File

@ -516,8 +516,9 @@ protected:
int event_count; int event_count;
int image_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 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 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 last_motion_frame_count; // last value of motion_frame_count when calculating fps
int ready_count; int ready_count;
@ -709,7 +710,7 @@ public:
Debug(4, "Have out of order packets, but no keyframe interval."); Debug(4, "Have out of order packets, but no keyframe interval.");
return false; 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); Debug(4, "Ready because image_count(%d) >= ready_count(%d)", image_count, ready_count);
return true; return true;
} }