Fix PrimeCapture on local cams. We need to be able to call it for each monitor

pull/3174/head
Isaac Connor 2021-02-09 20:29:37 -05:00
parent 7ed7ee887b
commit fab7efa003
6 changed files with 42 additions and 33 deletions

View File

@ -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;

View File

@ -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();

View File

@ -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

View File

@ -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

View File

@ -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",

View File

@ -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> &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> &monitor : monitors) {
for (const std::shared_ptr<Monitor> &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;