From fab7efa003b9d4588d16bef7fcfc71dbd667edd6 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 9 Feb 2021 20:29:37 -0500 Subject: [PATCH] Fix PrimeCapture on local cams. We need to be able to call it for each monitor --- scripts/zmdc.pl.in | 1 + src/zm_analysis_thread.cpp | 4 +++- src/zm_image.cpp | 4 +++- src/zm_local_camera.cpp | 6 ++++++ src/zm_monitor.cpp | 21 +++++++++----------- src/zmc.cpp | 39 +++++++++++++++++++------------------- 6 files changed, 42 insertions(+), 33 deletions(-) diff --git a/scripts/zmdc.pl.in b/scripts/zmdc.pl.in index 3b4df5648..25cf9c18d 100644 --- a/scripts/zmdc.pl.in +++ b/scripts/zmdc.pl.in @@ -612,6 +612,7 @@ sub restart { # Start will be handled by the reaper... # unless it was already pending in which case send_stop will return () so we should start it if ( !send_stop(0, $process) ) { + dPrint(ZoneMinder::Logger::WARNING, "!send_stop so starting '$command'\n"); start($daemon, @args); } return; diff --git a/src/zm_analysis_thread.cpp b/src/zm_analysis_thread.cpp index 143f970ac..834a57cd4 100644 --- a/src/zm_analysis_thread.cpp +++ b/src/zm_analysis_thread.cpp @@ -15,10 +15,11 @@ AnalysisThread::~AnalysisThread() { } void AnalysisThread::Run() { - Debug(2, "AnalysisThread::Run()"); + Debug(2, "AnalysisThread::Run() for %d", monitor_->Id()); Microseconds analysis_rate = Microseconds(monitor_->GetAnalysisRate()); Seconds analysis_update_delay = Seconds(monitor_->GetAnalysisUpdateDelay()); + Debug(2, "AnalysisThread::Run() have update delay %d", analysis_update_delay); monitor_->UpdateAdaptiveSkip(); @@ -29,6 +30,7 @@ void AnalysisThread::Run() { // Some periodic updates are required for variable capturing framerate if (analysis_update_delay != Seconds::zero()) { cur_time = std::chrono::steady_clock::now(); + Debug(2, "Updating adaptive skip"); if ((cur_time - last_analysis_update_time) > analysis_update_delay) { analysis_rate = Microseconds(monitor_->GetAnalysisRate()); monitor_->UpdateAdaptiveSkip(); diff --git a/src/zm_image.cpp b/src/zm_image.cpp index 8d17cb4ef..77bd14bf1 100644 --- a/src/zm_image.cpp +++ b/src/zm_image.cpp @@ -289,7 +289,9 @@ void Image::Assign(const AVFrame *frame) { if ( sws_scale(sws_convert_context, frame->data, frame->linesize, 0, frame->height, dest_frame->data, dest_frame->linesize) < 0 ) - Fatal("Unable to convert raw format %u to target format %u", frame->format, format); + Fatal("Unable to convert raw format %u %ux%u to target format %u %ux%u", + frame->format, frame->width, frame->height, + format, width, height); #else // HAVE_LIBSWSCALE Fatal("You must compile ffmpeg with the --enable-swscale option to use ffmpeg cameras"); #endif // HAVE_LIBSWSCALE diff --git a/src/zm_local_camera.cpp b/src/zm_local_camera.cpp index 9881b50f6..3a86b4a05 100644 --- a/src/zm_local_camera.cpp +++ b/src/zm_local_camera.cpp @@ -35,6 +35,7 @@ #endif static unsigned int BigEndian; +static bool primed; static int vidioctl(int fd, int request, void *arg) { int result = -1; @@ -676,6 +677,7 @@ LocalCamera::LocalCamera( imgConversionContext = nullptr; } // end if capture and conversion_tye == swscale #endif + get_VideoStream(); } // end LocalCamera::LocalCamera LocalCamera::~LocalCamera() { @@ -1171,6 +1173,7 @@ void LocalCamera::Terminate() { #endif // ZM_HAS_V4L1 close(vid_fd); + primed = false; } // end LocalCamera::Terminate uint32_t LocalCamera::AutoSelectFormat(int p_colours) { @@ -1971,6 +1974,8 @@ int LocalCamera::Contrast( int p_contrast ) { } int LocalCamera::PrimeCapture() { + if ( primed ) return 1; + Initialise(); Debug(2, "Priming capture"); @@ -2014,6 +2019,7 @@ int LocalCamera::PrimeCapture() { } #endif // ZM_HAS_V4L1 mVideoStreamId = 0; + primed = true; return 1; } // end LocalCamera::PrimeCapture diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index 78e1eb278..564e90887 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -1268,18 +1268,22 @@ double Monitor::GetFPS() const { /* I think this returns the # of micro seconds that we should sleep in order to maintain the desired analysis rate */ useconds_t Monitor::GetAnalysisRate() { + Debug(1, "Here"); double capture_fps = get_capture_fps(); + Debug(1, "Here"); if ( !analysis_fps_limit ) { return 0; } else if ( analysis_fps_limit > capture_fps ) { + Debug(1, "Here"); if ( last_fps_time != last_analysis_fps_time ) { // At startup they are equal, should never be equal again Warning("Analysis fps (%.2f) is greater than capturing fps (%.2f)", analysis_fps_limit, capture_fps); } return 0; - } else { + } else if ( capture_fps ) { return( ( 1000000 / analysis_fps_limit ) - ( 1000000 / capture_fps ) ); } + return 0; } void Monitor::UpdateAdaptiveSkip() { @@ -1791,12 +1795,6 @@ bool Monitor::Analyse() { Warning("Shouldn't be doing Analyse when not Enabled"); return false; } -#if 0 - if ( !packetqueue.size() ) { - Debug(1, "Waiting for PrimeCapture"); - return false; - } -#endif if ( !analysis_it ) analysis_it = packetqueue.get_video_it(true); @@ -2916,13 +2914,12 @@ unsigned int Monitor::SubpixelOrder() const { return camera->SubpixelOrder(); } int Monitor::PrimeCapture() { int ret = camera->PrimeCapture(); if ( ret > 0 ) { - //if ( packetqueue ) - //delete packetqueue; video_stream_id = camera->get_VideoStreamId(); - audio_stream_id = camera->get_AudioStreamId(); - //packetqueue = new PacketQueue(image_buffer_count, video_stream_id, audio_stream_id); + packetqueue.addStreamId(video_stream_id); - if ( audio_stream_id ) + + audio_stream_id = camera->get_AudioStreamId(); + if ( audio_stream_id >= 0 ) packetqueue.addStreamId(audio_stream_id); Debug(2, "Video stream id is %d, audio is %d, minimum_packets to keep in buffer %d", diff --git a/src/zmc.cpp b/src/zmc.cpp index 9d0051e78..39d1535d9 100644 --- a/src/zmc.cpp +++ b/src/zmc.cpp @@ -236,6 +236,7 @@ int main(int argc, char *argv[]) { while ( !zm_terminate ) { result = 0; static char sql[ZM_SQL_SML_BUFSIZ]; + for (const std::shared_ptr &monitor : monitors) { if (!monitor->getCamera()) { } @@ -251,28 +252,28 @@ int main(int argc, char *argv[]) { if (mysql_query(&dbconn, sql)) { Error("Can't run query: %s", mysql_error(&dbconn)); } - } // end foreach monitor - - // Outer primary loop, handles connection to camera - if (monitors[0]->PrimeCapture() <= 0) { - if (prime_capture_log_count % 60) { - Error("Failed to prime capture of initial monitor"); - } else { - Debug(1, "Failed to prime capture of initial monitor"); - } - prime_capture_log_count ++; - monitors[0]->disconnect(); - if (!zm_terminate) { - Debug(1, "Sleeping"); - sleep(5); - } - continue; } - for (std::shared_ptr &monitor : monitors) { + for (const std::shared_ptr &monitor : monitors) { + + // Outer primary loop, handles connection to camera + if (monitor->PrimeCapture() <= 0) { + if (prime_capture_log_count % 60) { + Error("Failed to prime capture of initial monitor"); + } else { + Debug(1, "Failed to prime capture of initial monitor"); + } + prime_capture_log_count ++; + monitor->disconnect(); + if (!zm_terminate) { + Debug(1, "Sleeping"); + sleep(5); + } + continue; + } snprintf(sql, sizeof(sql), "INSERT INTO Monitor_Status (MonitorId,Status) VALUES (%d, 'Connected') ON DUPLICATE KEY UPDATE Status='Connected'", - monitor->Id()); + monitor->Id()); if ( mysql_query(&dbconn, sql) ) { Error("Can't run query: %s", mysql_error(&dbconn)); } @@ -314,7 +315,7 @@ int main(int argc, char *argv[]) { rtsp_server_threads[i]->start(); } #endif - } // end foreach monitor + } struct timeval now; struct DeltaTimeval delta_time;