|
|
|
@ -510,10 +510,17 @@ Monitor::Monitor(
|
|
|
|
|
shared_data->last_write_index, shared_data->last_write_time );
|
|
|
|
|
sleep(1);
|
|
|
|
|
}
|
|
|
|
|
ref_image.Assign( width, height, camera->Colours(), camera->SubpixelOrder(), image_buffer[shared_data->last_write_index].image->Buffer(), camera->ImageSize());
|
|
|
|
|
ref_image.Assign( width, height, camera->Colours(), camera->SubpixelOrder(),
|
|
|
|
|
image_buffer[shared_data->last_write_index].image->Buffer(), camera->ImageSize());
|
|
|
|
|
adaptive_skip = true;
|
|
|
|
|
|
|
|
|
|
ReloadLinkedMonitors(p_linked_monitors);
|
|
|
|
|
|
|
|
|
|
if ( config.record_diag_images ) {
|
|
|
|
|
diag_path_r = stringtf("%s/%d/diag-r.jpg", storage->Path(), id);
|
|
|
|
|
diag_path_d = stringtf("%s/%d/diag-d.jpg", storage->Path(), id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // end if purpose == ANALYSIS
|
|
|
|
|
} // Monitor::Monitor
|
|
|
|
|
|
|
|
|
@ -889,10 +896,10 @@ double Monitor::GetFPS() const {
|
|
|
|
|
useconds_t Monitor::GetAnalysisRate() {
|
|
|
|
|
double capturing_fps = GetFPS();
|
|
|
|
|
if ( !analysis_fps ) {
|
|
|
|
|
return( 0 );
|
|
|
|
|
return 0;
|
|
|
|
|
} else if ( analysis_fps > capturing_fps ) {
|
|
|
|
|
Warning("Analysis fps (%.2f) is greater than capturing fps (%.2f)", analysis_fps, capturing_fps);
|
|
|
|
|
return( 0 );
|
|
|
|
|
return 0;
|
|
|
|
|
} else {
|
|
|
|
|
return ( ( 1000000 / analysis_fps ) - ( 1000000 / capturing_fps ) );
|
|
|
|
|
}
|
|
|
|
@ -975,7 +982,7 @@ int Monitor::actionBrightness( int p_brightness ) {
|
|
|
|
|
usleep(100000);
|
|
|
|
|
} else {
|
|
|
|
|
Warning("Timed out waiting to set brightness");
|
|
|
|
|
return( -1 );
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
@ -986,14 +993,14 @@ int Monitor::actionBrightness( int p_brightness ) {
|
|
|
|
|
usleep(100000);
|
|
|
|
|
} else {
|
|
|
|
|
Warning("Timed out waiting to get brightness");
|
|
|
|
|
return( -1 );
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return( shared_data->brightness );
|
|
|
|
|
}
|
|
|
|
|
return( camera->Brightness( p_brightness ) );
|
|
|
|
|
return shared_data->brightness;
|
|
|
|
|
}
|
|
|
|
|
return camera->Brightness(p_brightness);
|
|
|
|
|
} // end int Monitor::actionBrightness(int p_brightness)
|
|
|
|
|
|
|
|
|
|
int Monitor::actionContrast(int p_contrast) {
|
|
|
|
|
if ( purpose != CAPTURE ) {
|
|
|
|
@ -1006,7 +1013,7 @@ int Monitor::actionContrast( int p_contrast ) {
|
|
|
|
|
usleep(100000);
|
|
|
|
|
} else {
|
|
|
|
|
Warning("Timed out waiting to set contrast");
|
|
|
|
|
return( -1 );
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
@ -1017,14 +1024,14 @@ int Monitor::actionContrast( int p_contrast ) {
|
|
|
|
|
usleep(100000);
|
|
|
|
|
} else {
|
|
|
|
|
Warning("Timed out waiting to get contrast");
|
|
|
|
|
return( -1 );
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return( shared_data->contrast );
|
|
|
|
|
}
|
|
|
|
|
return( camera->Contrast( p_contrast ) );
|
|
|
|
|
return shared_data->contrast;
|
|
|
|
|
}
|
|
|
|
|
return camera->Contrast(p_contrast);
|
|
|
|
|
} // end int Monitor::actionContrast(int p_contrast)
|
|
|
|
|
|
|
|
|
|
int Monitor::actionHue(int p_hue) {
|
|
|
|
|
if ( purpose != CAPTURE ) {
|
|
|
|
@ -1037,7 +1044,7 @@ int Monitor::actionHue( int p_hue ) {
|
|
|
|
|
usleep(100000);
|
|
|
|
|
} else {
|
|
|
|
|
Warning("Timed out waiting to set hue");
|
|
|
|
|
return( -1 );
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
@ -1048,14 +1055,14 @@ int Monitor::actionHue( int p_hue ) {
|
|
|
|
|
usleep(100000);
|
|
|
|
|
} else {
|
|
|
|
|
Warning("Timed out waiting to get hue");
|
|
|
|
|
return( -1 );
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return( shared_data->hue );
|
|
|
|
|
}
|
|
|
|
|
return( camera->Hue( p_hue ) );
|
|
|
|
|
return shared_data->hue;
|
|
|
|
|
}
|
|
|
|
|
return camera->Hue(p_hue);
|
|
|
|
|
} // end int Monitor::actionHue(int p_hue)
|
|
|
|
|
|
|
|
|
|
int Monitor::actionColour(int p_colour) {
|
|
|
|
|
if ( purpose != CAPTURE ) {
|
|
|
|
@ -1068,7 +1075,7 @@ int Monitor::actionColour( int p_colour ) {
|
|
|
|
|
usleep(100000);
|
|
|
|
|
} else {
|
|
|
|
|
Warning("Timed out waiting to set colour");
|
|
|
|
|
return( -1 );
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
@ -1079,14 +1086,14 @@ int Monitor::actionColour( int p_colour ) {
|
|
|
|
|
usleep(100000);
|
|
|
|
|
} else {
|
|
|
|
|
Warning("Timed out waiting to get colour");
|
|
|
|
|
return( -1 );
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return( shared_data->colour );
|
|
|
|
|
}
|
|
|
|
|
return( camera->Colour( p_colour ) );
|
|
|
|
|
return shared_data->colour;
|
|
|
|
|
}
|
|
|
|
|
return camera->Colour(p_colour);
|
|
|
|
|
} // end int Monitor::actionColour(int p_colour)
|
|
|
|
|
|
|
|
|
|
void Monitor::DumpZoneImage(const char *zone_string) {
|
|
|
|
|
int exclude_id = 0;
|
|
|
|
@ -1162,7 +1169,7 @@ void Monitor::DumpZoneImage( const char *zone_string ) {
|
|
|
|
|
snprintf(filename, sizeof(filename), "Zones%d.jpg", id);
|
|
|
|
|
zone_image->WriteJpeg(filename);
|
|
|
|
|
delete zone_image;
|
|
|
|
|
}
|
|
|
|
|
} // end void Monitor::DumpZoneImage(const char *zone_string)
|
|
|
|
|
|
|
|
|
|
void Monitor::DumpImage(Image *dump_image) const {
|
|
|
|
|
if ( image_count && !(image_count%10) ) {
|
|
|
|
@ -1173,7 +1180,7 @@ void Monitor::DumpImage( Image *dump_image ) const {
|
|
|
|
|
if ( dump_image->WriteJpeg(new_filename) )
|
|
|
|
|
rename(new_filename, filename);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} // end void Monitor::DumpImage(Image *dump_image)
|
|
|
|
|
|
|
|
|
|
bool Monitor::CheckSignal(const Image *image) {
|
|
|
|
|
static bool static_undef = true;
|
|
|
|
@ -1245,7 +1252,7 @@ bool Monitor::CheckSignal( const Image *image ) {
|
|
|
|
|
return false;
|
|
|
|
|
} // end if signal_check_points
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
} // end bool Monitor::CheckSignal(const Image *image)
|
|
|
|
|
|
|
|
|
|
bool Monitor::Analyse() {
|
|
|
|
|
if ( shared_data->last_read_index == shared_data->last_write_index ) {
|
|
|
|
@ -1548,7 +1555,7 @@ bool Monitor::Analyse() {
|
|
|
|
|
int pre_event_images = pre_event_count;
|
|
|
|
|
|
|
|
|
|
if ( event ) {
|
|
|
|
|
// SHouldn't be able to happen because
|
|
|
|
|
// Shouldn't be able to happen because
|
|
|
|
|
Error("Creating new event when one exists");
|
|
|
|
|
}
|
|
|
|
|
if ( analysis_fps && pre_event_count ) {
|
|
|
|
@ -1640,17 +1647,20 @@ Error("Creating new event when one exists");
|
|
|
|
|
shared_data->state = state = ALERT;
|
|
|
|
|
} else if ( state == ALERT ) {
|
|
|
|
|
if ( image_count-last_alarm_count > post_event_count ) {
|
|
|
|
|
Info( "%s: %03d - Left alarm state (%" PRIu64 ") - %d(%d) images", name, image_count, event->Id(), event->Frames(), event->AlarmFrames() );
|
|
|
|
|
Info("%s: %03d - Left alarm state (%" PRIu64 ") - %d(%d) images",
|
|
|
|
|
name, image_count, event->Id(), event->Frames(), event->AlarmFrames());
|
|
|
|
|
//if ( function != MOCORD || event_close_mode == CLOSE_ALARM || event->Cause() == SIGNAL_CAUSE )
|
|
|
|
|
if ( function != MOCORD || event_close_mode == CLOSE_ALARM ) {
|
|
|
|
|
shared_data->state = state = IDLE;
|
|
|
|
|
Info( "%s: %03d - Closing event %" PRIu64 ", alarm end%s", name, image_count, event->Id(), (function==MOCORD)?", section truncated":"" );
|
|
|
|
|
Info("%s: %03d - Closing event %" PRIu64 ", alarm end%s",
|
|
|
|
|
name, image_count, event->Id(), (function==MOCORD)?", section truncated":"");
|
|
|
|
|
closeEvent();
|
|
|
|
|
} else {
|
|
|
|
|
shared_data->state = state = TAPE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} // end if ALARM or ALERT
|
|
|
|
|
|
|
|
|
|
if ( state == PREALARM ) {
|
|
|
|
|
if ( function != MOCORD ) {
|
|
|
|
|
shared_data->state = state = IDLE;
|
|
|
|
@ -1676,7 +1686,8 @@ Error("Creating new event when one exists");
|
|
|
|
|
zones[i]->RecordStats(event);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} // end foreach zone
|
|
|
|
|
|
|
|
|
|
if ( got_anal_image ) {
|
|
|
|
|
if ( state == PREALARM )
|
|
|
|
|
Event::AddPreAlarmFrame(snap_image, *timestamp, score, &alarm_image);
|
|
|
|
@ -1770,7 +1781,7 @@ Error("Creating new event when one exists");
|
|
|
|
|
image_count++;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
} // end Monitor::Analyze
|
|
|
|
|
|
|
|
|
|
void Monitor::Reload() {
|
|
|
|
|
Debug(1, "Reloading monitor %s", name);
|
|
|
|
@ -1843,7 +1854,7 @@ void Monitor::Reload() {
|
|
|
|
|
} // end if row
|
|
|
|
|
|
|
|
|
|
ReloadZones();
|
|
|
|
|
}
|
|
|
|
|
} // end void Monitor::Reload()
|
|
|
|
|
|
|
|
|
|
void Monitor::ReloadZones() {
|
|
|
|
|
Debug(1, "Reloading zones for monitor %s", name);
|
|
|
|
@ -1854,7 +1865,7 @@ void Monitor::ReloadZones() {
|
|
|
|
|
zones = 0;
|
|
|
|
|
n_zones = Zone::Load(this, zones);
|
|
|
|
|
//DumpZoneImage();
|
|
|
|
|
}
|
|
|
|
|
} // end void Monitor::ReloadZones()
|
|
|
|
|
|
|
|
|
|
void Monitor::ReloadLinkedMonitors(const char *p_linked_monitors) {
|
|
|
|
|
Debug(1, "Reloading linked monitors for monitor %s, '%s'", name, p_linked_monitors);
|
|
|
|
@ -1968,7 +1979,7 @@ int Monitor::LoadMonitors(std::string sql, Monitor **&monitors, Purpose purpose)
|
|
|
|
|
mysql_free_result(result);
|
|
|
|
|
|
|
|
|
|
return n_monitors;
|
|
|
|
|
}
|
|
|
|
|
} // end int Monitor::LoadMonitors(std::string sql, Monitor **&monitors, Purpose purpose)
|
|
|
|
|
|
|
|
|
|
#if ZM_HAS_V4L
|
|
|
|
|
int Monitor::LoadLocalMonitors(const char *device, Monitor **&monitors, Purpose purpose) {
|
|
|
|
@ -1980,7 +1991,7 @@ int Monitor::LoadLocalMonitors( const char *device, Monitor **&monitors, Purpose
|
|
|
|
|
if ( staticConfig.SERVER_ID )
|
|
|
|
|
sql += stringtf(" AND ServerId=%d", staticConfig.SERVER_ID);
|
|
|
|
|
return LoadMonitors(sql, monitors, purpose);
|
|
|
|
|
}
|
|
|
|
|
} // end int Monitor::LoadLocalMonitors(const char *device, Monitor **&monitors, Purpose purpose)
|
|
|
|
|
#endif // ZM_HAS_V4L
|
|
|
|
|
|
|
|
|
|
int Monitor::LoadRemoteMonitors(const char *protocol, const char *host, const char *port, const char *path, Monitor **&monitors, Purpose purpose) {
|
|
|
|
@ -1991,7 +2002,7 @@ int Monitor::LoadRemoteMonitors( const char *protocol, const char *host, const c
|
|
|
|
|
if ( protocol )
|
|
|
|
|
sql += stringtf(" AND Protocol = '%s' and Host = '%s' and Port = '%s' and Path = '%s'", protocol, host, port, path);
|
|
|
|
|
return LoadMonitors(sql, monitors, purpose);
|
|
|
|
|
}
|
|
|
|
|
} // end int Monitor::LoadRemoteMonitors
|
|
|
|
|
|
|
|
|
|
int Monitor::LoadFileMonitors(const char *file, Monitor **&monitors, Purpose purpose) {
|
|
|
|
|
std::string sql = load_monitor_sql + " WHERE Function != 'None' AND Type = 'File'";
|
|
|
|
@ -2001,7 +2012,7 @@ int Monitor::LoadFileMonitors( const char *file, Monitor **&monitors, Purpose pu
|
|
|
|
|
sql += stringtf(" AND ServerId=%d", staticConfig.SERVER_ID);
|
|
|
|
|
}
|
|
|
|
|
return LoadMonitors(sql, monitors, purpose);
|
|
|
|
|
}
|
|
|
|
|
} // end int Monitor::LoadFileMonitors
|
|
|
|
|
|
|
|
|
|
#if HAVE_LIBAVFORMAT
|
|
|
|
|
int Monitor::LoadFfmpegMonitors(const char *file, Monitor **&monitors, Purpose purpose) {
|
|
|
|
@ -2013,7 +2024,7 @@ int Monitor::LoadFfmpegMonitors(const char *file, Monitor **&monitors, Purpose p
|
|
|
|
|
sql += stringtf(" AND ServerId=%d", staticConfig.SERVER_ID);
|
|
|
|
|
}
|
|
|
|
|
return LoadMonitors(sql, monitors, purpose);
|
|
|
|
|
}
|
|
|
|
|
} // end int Monitor::LoadFfmpegMonitors
|
|
|
|
|
#endif // HAVE_LIBAVFORMAT
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -2333,7 +2344,7 @@ Monitor *Monitor::Load(MYSQL_ROW dbrow, bool load_zones, Purpose purpose) {
|
|
|
|
|
monitor->AddPrivacyBitmask(zones);
|
|
|
|
|
Debug(1, "Loaded monitor %d(%s), %d zones", id, name, n_zones);
|
|
|
|
|
return monitor;
|
|
|
|
|
}
|
|
|
|
|
} // end Monitor *Monitor::Load(MYSQL_ROW dbrow, bool load_zones, Purpose purpose)
|
|
|
|
|
|
|
|
|
|
Monitor *Monitor::Load(unsigned int p_id, bool load_zones, Purpose purpose) {
|
|
|
|
|
std::string sql = load_monitor_sql + stringtf(" WHERE Id=%d", p_id);
|
|
|
|
@ -2397,7 +2408,7 @@ int Monitor::Capture() {
|
|
|
|
|
/* Capture directly into image buffer, avoiding the need to memcpy() */
|
|
|
|
|
captureResult = camera->Capture(*capture_image);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} // end if deinterlacing or not
|
|
|
|
|
|
|
|
|
|
if ( captureResult < 0 ) {
|
|
|
|
|
Info("Return from Capture (%d), signal loss", captureResult);
|
|
|
|
@ -2426,39 +2437,38 @@ int Monitor::Capture() {
|
|
|
|
|
|
|
|
|
|
if ( orientation != ROTATE_0 ) {
|
|
|
|
|
switch ( orientation ) {
|
|
|
|
|
case ROTATE_0 : {
|
|
|
|
|
case ROTATE_0 :
|
|
|
|
|
// No action required
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case ROTATE_90 :
|
|
|
|
|
case ROTATE_180 :
|
|
|
|
|
case ROTATE_270 : {
|
|
|
|
|
case ROTATE_270 :
|
|
|
|
|
capture_image->Rotate((orientation-1)*90);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case FLIP_HORI :
|
|
|
|
|
case FLIP_VERT : {
|
|
|
|
|
case FLIP_VERT :
|
|
|
|
|
capture_image->Flip(orientation==FLIP_HORI);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} // end if have rotation
|
|
|
|
|
|
|
|
|
|
if ( capture_image->Size() > camera->ImageSize() ) {
|
|
|
|
|
Error( "Captured image %d does not match expected size %d check width, height and colour depth",capture_image->Size(),camera->ImageSize() );
|
|
|
|
|
Error("Captured image %d does not match expected size %d check width, height and colour depth",
|
|
|
|
|
capture_image->Size(),camera->ImageSize() );
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( (index == shared_data->last_read_index) && (function > MONITOR) ) {
|
|
|
|
|
Warning( "Buffer overrun at index %d, image %d, slow down capture, speed up analysis or increase ring buffer size", index, image_count );
|
|
|
|
|
Warning("Buffer overrun at index %d, image %d, slow down capture, speed up analysis or increase ring buffer size",
|
|
|
|
|
index, image_count );
|
|
|
|
|
time_t now = time(0);
|
|
|
|
|
double approxFps = double(image_buffer_count)/double(now-image_buffer[index].timestamp->tv_sec);
|
|
|
|
|
time_t last_read_delta = now - shared_data->last_read_time;
|
|
|
|
|
if ( last_read_delta > (image_buffer_count/approxFps) ) {
|
|
|
|
|
Warning( "Last image read from shared memory %ld seconds ago, zma may have gone away", last_read_delta )
|
|
|
|
|
Warning("Last image read from shared memory %ld seconds ago, zma may have gone away", last_read_delta);
|
|
|
|
|
shared_data->last_read_index = image_buffer_count;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} // end if overrun
|
|
|
|
|
|
|
|
|
|
if ( privacy_bitmask )
|
|
|
|
|
capture_image->MaskPrivacy(privacy_bitmask);
|
|
|
|
@ -2486,7 +2496,8 @@ int Monitor::Capture() {
|
|
|
|
|
last_camera_bytes = new_camera_bytes;
|
|
|
|
|
//Info( "%d -> %d -> %d", fps_report_interval, now, last_fps_time );
|
|
|
|
|
//Info( "%d -> %d -> %lf -> %lf", now-last_fps_time, fps_report_interval/(now-last_fps_time), double(fps_report_interval)/(now-last_fps_time), fps );
|
|
|
|
|
Info("%s: images:%d - Capturing at %.2lf fps, capturing bandwidth %ubytes/sec", name, image_count, new_fps, new_capture_bandwidth);
|
|
|
|
|
Info("%s: images:%d - Capturing at %.2lf fps, capturing bandwidth %ubytes/sec",
|
|
|
|
|
name, image_count, new_fps, new_capture_bandwidth);
|
|
|
|
|
last_fps_time = now;
|
|
|
|
|
fps = new_fps;
|
|
|
|
|
db_mutex.lock();
|
|
|
|
@ -2524,10 +2535,12 @@ int Monitor::Capture() {
|
|
|
|
|
shared_data->action &= ~SET_SETTINGS;
|
|
|
|
|
}
|
|
|
|
|
return captureResult;
|
|
|
|
|
}
|
|
|
|
|
} // end int Monitor::Capture
|
|
|
|
|
|
|
|
|
|
void Monitor::TimestampImage(Image *ts_image, const struct timeval *ts_time) const {
|
|
|
|
|
if ( label_format[0] ) {
|
|
|
|
|
if ( !label_format[0] )
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
// Expand the strftime macros first
|
|
|
|
|
char label_time_text[256];
|
|
|
|
|
strftime(label_time_text, sizeof(label_time_text), label_format, localtime(&ts_time->tv_sec));
|
|
|
|
@ -2558,15 +2571,17 @@ void Monitor::TimestampImage( Image *ts_image, const struct timeval *ts_time ) c
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
*d_ptr++ = *s_ptr++;
|
|
|
|
|
}
|
|
|
|
|
} // end while
|
|
|
|
|
*d_ptr = '\0';
|
|
|
|
|
ts_image->Annotate( label_text, label_coord, label_size );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} // end void Monitor::TimestampImage
|
|
|
|
|
|
|
|
|
|
bool Monitor::closeEvent() {
|
|
|
|
|
if ( event ) {
|
|
|
|
|
if ( !event )
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if ( function == RECORD || function == MOCORD ) {
|
|
|
|
|
//FIXME Is this neccessary? ENdTime should be set in the destructor
|
|
|
|
|
gettimeofday(&(event->EndTime()), NULL);
|
|
|
|
|
}
|
|
|
|
|
if ( event_delete_thread ) {
|
|
|
|
@ -2587,34 +2602,19 @@ bool Monitor::closeEvent() {
|
|
|
|
|
#endif
|
|
|
|
|
video_store_data->recording = (struct timeval){0};
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
} // end bool Monitor::closeEvent()
|
|
|
|
|
|
|
|
|
|
unsigned int Monitor::DetectMotion(const Image &comp_image, Event::StringSet &zoneSet) {
|
|
|
|
|
bool alarm = false;
|
|
|
|
|
unsigned int score = 0;
|
|
|
|
|
|
|
|
|
|
if ( n_zones <= 0 ) return( alarm );
|
|
|
|
|
|
|
|
|
|
Storage *storage = this->getStorage();
|
|
|
|
|
|
|
|
|
|
if ( config.record_diag_images ) {
|
|
|
|
|
static char diag_path[PATH_MAX] = "";
|
|
|
|
|
if ( !diag_path[0] ) {
|
|
|
|
|
snprintf( diag_path, sizeof(diag_path), "%s/%d/diag-r.jpg", storage->Path(), id );
|
|
|
|
|
}
|
|
|
|
|
ref_image.WriteJpeg( diag_path );
|
|
|
|
|
}
|
|
|
|
|
if ( n_zones <= 0 ) return alarm;
|
|
|
|
|
|
|
|
|
|
ref_image.Delta(comp_image, &delta_image);
|
|
|
|
|
|
|
|
|
|
if ( config.record_diag_images ) {
|
|
|
|
|
static char diag_path[PATH_MAX] = "";
|
|
|
|
|
if ( !diag_path[0] ) {
|
|
|
|
|
snprintf( diag_path, sizeof(diag_path), "%s/%d/diag-d.jpg", storage->Path(), id );
|
|
|
|
|
}
|
|
|
|
|
delta_image.WriteJpeg( diag_path );
|
|
|
|
|
ref_image.WriteJpeg(diag_path_r.c_str());
|
|
|
|
|
delta_image.WriteJpeg(diag_path_d.c_str());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Blank out all exclusion zones
|
|
|
|
@ -2628,7 +2628,7 @@ unsigned int Monitor::DetectMotion( const Image &comp_image, Event::StringSet &z
|
|
|
|
|
}
|
|
|
|
|
Debug(3, "Blanking inactive zone %s", zone->Label());
|
|
|
|
|
delta_image.Fill(RGB_BLACK, zone->GetPolygon());
|
|
|
|
|
}
|
|
|
|
|
} // end foreach zone
|
|
|
|
|
|
|
|
|
|
// Check preclusive zones first
|
|
|
|
|
for ( int n_zone = 0; n_zone < n_zones; n_zone++ ) {
|
|
|
|
@ -2638,7 +2638,8 @@ unsigned int Monitor::DetectMotion( const Image &comp_image, Event::StringSet &z
|
|
|
|
|
}
|
|
|
|
|
int old_zone_score = zone->Score();
|
|
|
|
|
bool old_zone_alarmed = zone->Alarmed();
|
|
|
|
|
Debug( 3, "Checking preclusive zone %s - old score: %d, state: %s", zone->Label(),old_zone_score, zone->Alarmed()?"alarmed":"quiet" );
|
|
|
|
|
Debug(3, "Checking preclusive zone %s - old score: %d, state: %s",
|
|
|
|
|
zone->Label(),old_zone_score, zone->Alarmed()?"alarmed":"quiet");
|
|
|
|
|
if ( zone->CheckAlarms(&delta_image) ) {
|
|
|
|
|
alarm = true;
|
|
|
|
|
score += zone->Score();
|
|
|
|
@ -2649,7 +2650,8 @@ unsigned int Monitor::DetectMotion( const Image &comp_image, Event::StringSet &z
|
|
|
|
|
} else {
|
|
|
|
|
// check if end of alarm
|
|
|
|
|
if ( old_zone_alarmed ) {
|
|
|
|
|
Debug(3, "Preclusive Zone %s alarm Ends. Previous score: %d", zone->Label(), old_zone_score);
|
|
|
|
|
Debug(3, "Preclusive Zone %s alarm Ends. Previous score: %d",
|
|
|
|
|
zone->Label(), old_zone_score);
|
|
|
|
|
if ( old_zone_score > 0 ) {
|
|
|
|
|
zone->SetExtendAlarmCount(zone->GetExtendAlarmFrames());
|
|
|
|
|
}
|
|
|
|
@ -2660,8 +2662,8 @@ unsigned int Monitor::DetectMotion( const Image &comp_image, Event::StringSet &z
|
|
|
|
|
zone->ClearAlarm();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} // end if CheckAlarms
|
|
|
|
|
} // end foreach zone
|
|
|
|
|
|
|
|
|
|
Coord alarm_centre;
|
|
|
|
|
int top_score = -1;
|
|
|
|
@ -2690,7 +2692,7 @@ unsigned int Monitor::DetectMotion( const Image &comp_image, Event::StringSet &z
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} // end foreach zone
|
|
|
|
|
|
|
|
|
|
if ( alarm ) {
|
|
|
|
|
for ( int n_zone = 0; n_zone < n_zones; n_zone++ ) {
|
|
|
|
@ -2712,8 +2714,8 @@ unsigned int Monitor::DetectMotion( const Image &comp_image, Event::StringSet &z
|
|
|
|
|
alarm_centre = zone->GetAlarmCentre();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} // end if CheckAlarm
|
|
|
|
|
} // end foreach zone
|
|
|
|
|
} else {
|
|
|
|
|
// Find all alarm pixels in exclusive zones
|
|
|
|
|
for ( int n_zone = 0; n_zone < n_zones; n_zone++ ) {
|
|
|
|
@ -2729,22 +2731,23 @@ unsigned int Monitor::DetectMotion( const Image &comp_image, Event::StringSet &z
|
|
|
|
|
Debug(3, "Zone is alarmed, zone score = %d", zone->Score());
|
|
|
|
|
zoneSet.insert(zone->Label());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} // end foreach zone
|
|
|
|
|
} // end if alarm or not
|
|
|
|
|
}
|
|
|
|
|
} // end if alarm
|
|
|
|
|
|
|
|
|
|
if ( top_score > 0 ) {
|
|
|
|
|
shared_data->alarm_x = alarm_centre.X();
|
|
|
|
|
shared_data->alarm_y = alarm_centre.Y();
|
|
|
|
|
|
|
|
|
|
Info( "Got alarm centre at %d,%d, at count %d", shared_data->alarm_x, shared_data->alarm_y, image_count );
|
|
|
|
|
Info("Got alarm centre at %d,%d, at count %d",
|
|
|
|
|
shared_data->alarm_x, shared_data->alarm_y, image_count);
|
|
|
|
|
} else {
|
|
|
|
|
shared_data->alarm_x = shared_data->alarm_y = -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// This is a small and innocent hack to prevent scores of 0 being returned in alarm state
|
|
|
|
|
return( score?score:alarm );
|
|
|
|
|
}
|
|
|
|
|
return score ? score : alarm;
|
|
|
|
|
} // end MotionDetect
|
|
|
|
|
|
|
|
|
|
bool Monitor::DumpSettings(char *output, bool verbose) {
|
|
|
|
|
output[0] = 0;
|
|
|
|
@ -2846,7 +2849,7 @@ std::vector<Group *> Monitor::Groups() {
|
|
|
|
|
mysql_free_result(result);
|
|
|
|
|
}
|
|
|
|
|
return groups;
|
|
|
|
|
}
|
|
|
|
|
} // end Monitor::Groups()
|
|
|
|
|
|
|
|
|
|
StringVector Monitor::GroupNames() {
|
|
|
|
|
StringVector groupnames;
|
|
|
|
@ -2855,5 +2858,4 @@ StringVector Monitor::GroupNames() {
|
|
|
|
|
Debug(1,"Groups: %s", g->Name());
|
|
|
|
|
}
|
|
|
|
|
return groupnames;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // end Monitor::GroupNames()
|
|
|
|
|