Merge branch 'master' of github.com:ZoneMinder/ZoneMinder

This commit is contained in:
Isaac Connor 2019-04-16 11:42:54 -04:00
commit 56537893da
5 changed files with 318 additions and 305 deletions

View File

@ -252,8 +252,6 @@ void Logger::initialise(const std::string &id, const Options &options) {
}
void Logger::terminate() {
Debug(1, "Terminating Logger");
if ( mFileLevel > NOLOG )
closeFile();

View File

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

View File

@ -298,6 +298,8 @@ protected:
Image ref_image;
Image alarm_image; // Used in creating analysis images, will be initialized in Analysis
Image write_image; // Used when creating snapshot images
std::string diag_path_r;
std::string diag_path_d;
Purpose purpose; // What this monitor has been created to do
int event_count;

View File

@ -1135,11 +1135,22 @@ int VideoStore::writeAudioFramePacket(AVPacket *ipkt) {
}
} // end if encoding or copying
opkt.pos = -1;
opkt.stream_index = audio_out_stream->index;
opkt.flags = ipkt->flags;
if ( opkt.dts < audio_out_stream->cur_dts ) {
Warning("non increasing dts, fixing");
opkt.dts = audio_out_stream->cur_dts;
if ( opkt.dts > opkt.pts ) {
Debug(1,
"opkt.dts(%" PRId64 ") must be <= opkt.pts(%" PRId64 ")."
"Decompression must happen before presentation.",
opkt.dts, opkt.pts);
opkt.pts = opkt.dts;
}
} else if ( opkt.dts > opkt.pts ) {
Debug(1,
"opkt.dts(%" PRId64 ") must be <= opkt.pts(%" PRId64 ")."
"Decompression must happen before presentation.",

View File

@ -115,7 +115,7 @@
}
.ptzControls .controlsPanel .pantiltPanel .pantiltControls .centerBtn {
background: url("../skins/classic/graphics/graphics/center.png") no-repeat 0 0;
background: url("../skins/classic/graphics/center.png") no-repeat 0 0;
}
.ptzControls .controlsPanel .pantiltPanel .pantiltControls .rightBtn {