Merge branch 'storageareas' of github.com:ConnorTechnology/ZoneMinder into storageareas
This commit is contained in:
commit
2e673e49c8
19
README.md
19
README.md
|
@ -1,20 +1,7 @@
|
|||
ZoneMinder H264 Patch
|
||||
ZoneMinder
|
||||
==========
|
||||
|
||||
[![Build Status](https://travis-ci.org/ZoneMinder/ZoneMinder.png?branch=feature-h264-videostorage)](https://travis-ci.org/ZoneMinder/ZoneMinder) [![Bountysource](https://api.bountysource.com/badge/team?team_id=204&style=bounties_received)](https://www.bountysource.com/teams/zoneminder/issues?utm_source=ZoneMinder&utm_medium=shield&utm_campaign=bounties_received)
|
||||
|
||||
##Feature-h264-videostorage Branch Details
|
||||
This branch supports direct recording of h264 cameras into MP4 format uisng the h264 Passthrough option, but only with FFMPEG Monitors currently. It also provides h264 encoding for any other monitor type. If you encounter any issues, please open an issue on GitHub and attach it to the h264 milestone. But do remember this is bleeding edge so it will have problems.
|
||||
Thanks to @chriswiggins and @mastertheknife for their work, @SteveGilvarry is now maintaining this branch and welcomes any assistance.
|
||||
|
||||
**The following SQL changes are required, these will be merged to zmupdate once we are ready to merge this branch to master.**
|
||||
```
|
||||
ALTER TABLE `Monitors` ADD `SaveJPEGs` TINYINT NOT NULL DEFAULT '3' AFTER `Deinterlacing` ,
|
||||
ADD `VideoWriter` TINYINT NOT NULL DEFAULT '0' AFTER `SaveJPEGs` ,
|
||||
ADD `EncoderParameters` TEXT NOT NULL AFTER `VideoWriter` ,
|
||||
ADD `RecordAudio` TINYINT NOT NULL DEFAULT '0' AFTER `EncoderParameters` ;
|
||||
|
||||
ALTER TABLE `Events` ADD `DefaultVideo` VARCHAR( 64 ) NOT NULL AFTER `AlarmFrames` ;
|
||||
```
|
||||
[![Build Status](https://travis-ci.org/ZoneMinder/ZoneMinder.png)](https://travis-ci.org/ZoneMinder/ZoneMinder) [![Bountysource](https://api.bountysource.com/badge/team?team_id=204&style=bounties_received)](https://www.bountysource.com/teams/zoneminder/issues?utm_source=ZoneMinder&utm_medium=shield&utm_campaign=bounties_received)
|
||||
|
||||
All documentation for ZoneMinder is now online at https://zoneminder.readthedocs.org
|
||||
|
||||
|
|
|
@ -354,7 +354,7 @@ CREATE TABLE `Monitors` (
|
|||
`Deinterlacing` int(10) unsigned NOT NULL default '0',
|
||||
`SaveJPEGs` TINYINT NOT NULL DEFAULT '3' ,
|
||||
`VideoWriter` TINYINT NOT NULL DEFAULT '0',
|
||||
`EncoderParameters` TEXT NOT NULL,
|
||||
`EncoderParameters` TEXT,
|
||||
`RecordAudio` TINYINT NOT NULL DEFAULT '0',
|
||||
`RTSPDescribe` tinyint(1) unsigned,
|
||||
`Brightness` mediumint(7) NOT NULL default '-1',
|
||||
|
|
|
@ -71,3 +71,27 @@ SET @s = (SELECT IF(
|
|||
|
||||
PREPARE stmt FROM @s;
|
||||
EXECUTE stmt;
|
||||
|
||||
--
|
||||
-- The following alters various columns to allow NULLs
|
||||
--
|
||||
|
||||
ALTER TABLE Monitors MODIFY Host varchar(64);
|
||||
ALTER TABLE Monitors MODIFY LabelFormat varchar(64);
|
||||
ALTER TABLE Monitors MODIFY LinkedMonitors varchar(255);
|
||||
ALTER TABLE Monitors MODIFY Options varchar(255);
|
||||
ALTER TABLE Monitors MODIFY Protocol varchar(16);
|
||||
ALTER TABLE Monitors MODIFY User varchar(64);
|
||||
ALTER TABLE Monitors MODIFY Pass varchar(64);
|
||||
ALTER TABLE Monitors MODIFY RTSPDescribe tinyint(1) unsigned;
|
||||
ALTER TABLE Monitors MODIFY ControlId int(10) unsigned;
|
||||
ALTER TABLE Monitors MODIFY TrackDelay smallint(5) unsigned;
|
||||
ALTER TABLE Monitors MODIFY ReturnDelay smallint(5) unsigned;
|
||||
ALTER TABLE Monitors MODIFY EncoderParameters TEXT;
|
||||
ALTER TABLE Monitors MODIFY Path varchar(255);
|
||||
ALTER TABLE Monitors MODIFY V4LMultiBuffer tinyint(1) unsigned;
|
||||
|
||||
ALTER TABLE Users MODIFY MonitorIds tinytext;
|
||||
ALTER TABLE Users MODIFY Language varchar(8);
|
||||
ALTER TABLE Users MODIFY MaxBandwidth varchar(16);
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ Build-Depends: debhelper (>= 9), cmake
|
|||
, libphp-serialization-perl
|
||||
, libgnutls28-dev | libgnutls-dev
|
||||
, libmysqlclient-dev | libmariadbclient-dev
|
||||
, libjpeg-dev
|
||||
, libjpeg8-dev | libjpeg-dev
|
||||
, libpcre3-dev
|
||||
, libavcodec-dev, libavformat-dev (>= 3:0.svn20090204), libswscale-dev (>= 3:0.svn20090204), libavutil-dev
|
||||
, libavdevice-dev
|
||||
|
|
|
@ -5,10 +5,19 @@ Maintainer: Dmitry Smirnov <onlyjob@debian.org>
|
|||
Uploaders: Vagrant Cascadian <vagrant@debian.org>
|
||||
Build-Depends: debhelper (>= 9), dh-systemd, python-sphinx | python3-sphinx, apache2-dev, dh-linktree
|
||||
,cmake
|
||||
<<<<<<< HEAD
|
||||
,libx264-dev, libmp4v2-dev
|
||||
,libavcodec-dev, libavformat-dev, libswscale-dev
|
||||
,libavutil-dev, libavdevice-dev, libavresample-dev
|
||||
,libboost-dev
|
||||
=======
|
||||
,libboost-dev
|
||||
,libavdevice-dev (>= 6:10~)
|
||||
,libavcodec-dev (>= 6:10~)
|
||||
,libavformat-dev (>= 6:10~)
|
||||
,libavutil-dev (>= 6:10~)
|
||||
,libswscale-dev (>= 6:10~)
|
||||
>>>>>>> dragndrop_monitor_sorting
|
||||
,libbz2-dev
|
||||
,libgcrypt-dev
|
||||
,libcurl4-gnutls-dev
|
||||
|
|
|
@ -1,83 +0,0 @@
|
|||
AUTOMAKE_OPTIONS = gnu
|
||||
|
||||
# Ack! Nasty hack to get modules Makefile regenerated if wiped with make clean
|
||||
all-local: ZoneMinder/Makefile
|
||||
|
||||
ZoneMinder/Makefile: ZoneMinder/Makefile.PL
|
||||
( cd ZoneMinder; perl Makefile.PL )
|
||||
|
||||
bin_SCRIPTS = \
|
||||
zmdc.pl \
|
||||
zmaudit.pl \
|
||||
zmfilter.pl \
|
||||
zmtrigger.pl \
|
||||
zmx10.pl \
|
||||
zmwatch.pl \
|
||||
zmpkg.pl \
|
||||
zmupdate.pl \
|
||||
zmvideo.pl \
|
||||
zmcontrol.pl \
|
||||
zmtrack.pl \
|
||||
zmcamtool.pl \
|
||||
zmsystemctl.pl \
|
||||
zmtelemetry.pl
|
||||
|
||||
SUBDIRS = \
|
||||
. \
|
||||
ZoneMinder
|
||||
|
||||
EXTRA_DIST = \
|
||||
zmdc.pl.in \
|
||||
zmaudit.pl.in \
|
||||
zmfilter.pl.in \
|
||||
zmtrigger.pl.in \
|
||||
zmx10.pl.in \
|
||||
zmwatch.pl.in \
|
||||
zmpkg.pl.in \
|
||||
zmupdate.pl.in \
|
||||
zmvideo.pl.in \
|
||||
zmcontrol.pl.in \
|
||||
zmtrack.pl.in \
|
||||
zmcamtool.pl.in \
|
||||
zmsystemctl.pl.in \
|
||||
zmtelemtry.pl.in \
|
||||
ZoneMinder/Makefile.PL \
|
||||
ZoneMinder/README \
|
||||
ZoneMinder/Changes \
|
||||
ZoneMinder/META.yml \
|
||||
ZoneMinder/MANIFEST \
|
||||
ZoneMinder/t/ZoneMinder.t \
|
||||
ZoneMinder/lib/ZoneMinder.pm \
|
||||
ZoneMinder/lib/ZoneMinder/Base.pm.in \
|
||||
ZoneMinder/lib/ZoneMinder/Config.pm.in \
|
||||
ZoneMinder/lib/ZoneMinder/Event.pm \
|
||||
ZoneMinder/lib/ZoneMinder/Filter.pm \
|
||||
ZoneMinder/lib/ZoneMinder/Monitor.pm \
|
||||
ZoneMinder/lib/ZoneMinder/Object.pm \
|
||||
ZoneMinder/lib/ZoneMinder/Server.pm \
|
||||
ZoneMinder/lib/ZoneMinder/Storage.pm \
|
||||
ZoneMinder/lib/ZoneMinder/Logger.pm \
|
||||
ZoneMinder/lib/ZoneMinder/General.pm \
|
||||
ZoneMinder/lib/ZoneMinder/Database.pm \
|
||||
ZoneMinder/lib/ZoneMinder/Memory.pm.in \
|
||||
ZoneMinder/lib/ZoneMinder/Memory/Shared.pm \
|
||||
ZoneMinder/lib/ZoneMinder/Memory/Mapped.pm \
|
||||
ZoneMinder/lib/ZoneMinder/ConfigAdmin.pm \
|
||||
ZoneMinder/lib/ZoneMinder/ConfigData.pm.in \
|
||||
ZoneMinder/lib/ZoneMinder/Control.pm \
|
||||
ZoneMinder/lib/ZoneMinder/Control \
|
||||
ZoneMinder/lib/ZoneMinder/Trigger/Channel.pm \
|
||||
ZoneMinder/lib/ZoneMinder/Trigger/Channel/Handle.pm \
|
||||
ZoneMinder/lib/ZoneMinder/Trigger/Channel/Spawning.pm \
|
||||
ZoneMinder/lib/ZoneMinder/Trigger/Channel/Inet.pm \
|
||||
ZoneMinder/lib/ZoneMinder/Trigger/Channel/Unix.pm \
|
||||
ZoneMinder/lib/ZoneMinder/Trigger/Channel/File.pm \
|
||||
ZoneMinder/lib/ZoneMinder/Trigger/Channel/Serial.pm \
|
||||
ZoneMinder/lib/ZoneMinder/Trigger/Connection.pm \
|
||||
ZoneMinder/lib/ZoneMinder/Trigger/Connection/Example.pm \
|
||||
zm.in \
|
||||
zmdbbackup.in \
|
||||
zmdbrestore.in \
|
||||
zmeventdump.in \
|
||||
zmlogrotate.conf.in
|
||||
|
|
@ -187,7 +187,7 @@ Event::Event( Monitor *p_monitor, struct timeval p_start_time, const std::string
|
|||
snprintf( video_file, sizeof(video_file), video_file_format, path, video_name );
|
||||
|
||||
/* X264 MP4 video writer */
|
||||
if(monitor->GetOptVideoWriter() == 1) {
|
||||
if ( monitor->GetOptVideoWriter() == Monitor::X264ENCODE ) {
|
||||
#if ZM_HAVE_VIDEOWRITER_X264MP4
|
||||
videowriter = new X264MP4Writer(video_file, monitor->Width(), monitor->Height(), monitor->Colours(), monitor->SubpixelOrder(), monitor->GetOptEncoderParams());
|
||||
#else
|
||||
|
@ -195,8 +195,7 @@ Event::Event( Monitor *p_monitor, struct timeval p_start_time, const std::string
|
|||
#endif
|
||||
}
|
||||
|
||||
if(videowriter != NULL) {
|
||||
|
||||
if ( videowriter != NULL ) {
|
||||
/* Open the video stream */
|
||||
int nRet = videowriter->Open();
|
||||
if(nRet != 0) {
|
||||
|
@ -207,9 +206,10 @@ Event::Event( Monitor *p_monitor, struct timeval p_start_time, const std::string
|
|||
|
||||
snprintf( timecodes_name, sizeof(timecodes_name), "%d-%s", id, "video.timecodes" );
|
||||
snprintf( timecodes_file, sizeof(timecodes_file), video_file_format, path, timecodes_name );
|
||||
|
||||
/* Create timecodes file */
|
||||
timecodes_fd = fopen(timecodes_file, "wb");
|
||||
if(timecodes_fd == NULL) {
|
||||
if ( timecodes_fd == NULL ) {
|
||||
Error("Failed creating timecodes file");
|
||||
}
|
||||
}
|
||||
|
@ -353,12 +353,12 @@ void Event::updateNotes( const StringSetMap &newNoteSetMap ) {
|
|||
noteSet.insert( newNote );
|
||||
update = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // end for
|
||||
} // end if ( noteSetMap.size() == 0
|
||||
} // end if newNoteSetupMap.size() > 0
|
||||
} // end foreach newNoteSetMap
|
||||
} // end if have old notes
|
||||
} // end if have new notes
|
||||
|
||||
if ( update ) {
|
||||
std::string notes;
|
||||
|
|
|
@ -61,7 +61,6 @@
|
|||
#define MAP_LOCKED 0
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
std::vector<std::string> split(const std::string &s, char delim) {
|
||||
std::vector<std::string> elems;
|
||||
std::stringstream ss(s);
|
||||
|
@ -71,7 +70,6 @@ std::vector<std::string> split(const std::string &s, char delim) {
|
|||
}
|
||||
return elems;
|
||||
}
|
||||
//=============================================================================
|
||||
|
||||
Monitor::MonitorLink::MonitorLink( int p_id, const char *p_name ) : id( p_id ) {
|
||||
strncpy( name, p_name, sizeof(name) );
|
||||
|
@ -1228,7 +1226,7 @@ bool Monitor::Analyse() {
|
|||
}
|
||||
shared_data->action &= ~RESUME;
|
||||
}
|
||||
} // end ifshared_data->action
|
||||
} // end if shared_data->action
|
||||
|
||||
if ( auto_resume_time && (now.tv_sec >= auto_resume_time) ) {
|
||||
Info( "Auto resuming at count %d", image_count );
|
||||
|
|
|
@ -48,16 +48,14 @@ RemoteCamera::RemoteCamera(
|
|||
path = '/'+path;
|
||||
}
|
||||
|
||||
RemoteCamera::~RemoteCamera()
|
||||
{
|
||||
if(hp != NULL) {
|
||||
RemoteCamera::~RemoteCamera() {
|
||||
if ( hp != NULL ) {
|
||||
freeaddrinfo(hp);
|
||||
hp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteCamera::Initialise()
|
||||
{
|
||||
void RemoteCamera::Initialise() {
|
||||
if( protocol.empty() )
|
||||
Fatal( "No protocol specified for remote camera" );
|
||||
|
||||
|
@ -73,8 +71,7 @@ void RemoteCamera::Initialise()
|
|||
// Cache as much as we can to speed things up
|
||||
std::string::size_type authIndex = host.rfind( '@' );
|
||||
|
||||
if ( authIndex != std::string::npos )
|
||||
{
|
||||
if ( authIndex != std::string::npos ) {
|
||||
auth = host.substr( 0, authIndex );
|
||||
host.erase( 0, authIndex+1 );
|
||||
auth64 = base64Encode( auth );
|
||||
|
@ -82,7 +79,6 @@ void RemoteCamera::Initialise()
|
|||
authIndex = auth.rfind( ':' );
|
||||
username = auth.substr(0,authIndex);
|
||||
password = auth.substr( authIndex+1, auth.length() );
|
||||
|
||||
}
|
||||
|
||||
mNeedAuth = false;
|
||||
|
@ -94,9 +90,7 @@ void RemoteCamera::Initialise()
|
|||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
int ret = getaddrinfo(host.c_str(), port.c_str(), &hints, &hp);
|
||||
if ( ret != 0 )
|
||||
{
|
||||
if ( ret != 0 ) {
|
||||
Fatal( "Can't getaddrinfo(%s port %s): %s", host.c_str(), port.c_str(), gai_strerror(ret) );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
489
src/zm_zone.cpp
489
src/zm_zone.cpp
|
@ -23,8 +23,28 @@
|
|||
#include "zm_image.h"
|
||||
#include "zm_monitor.h"
|
||||
|
||||
void Zone::Setup( Monitor *p_monitor, int p_id, const char *p_label, ZoneType p_type, const Polygon &p_polygon, const Rgb p_alarm_rgb, CheckMethod p_check_method, int p_min_pixel_threshold, int p_max_pixel_threshold, int p_min_alarm_pixels, int p_max_alarm_pixels, const Coord &p_filter_box, int p_min_filter_pixels, int p_max_filter_pixels, int p_min_blob_pixels, int p_max_blob_pixels, int p_min_blobs, int p_max_blobs, int p_overload_frames, int p_extend_alarm_frames )
|
||||
{
|
||||
void Zone::Setup(
|
||||
Monitor *p_monitor,
|
||||
int p_id,
|
||||
const char *p_label,
|
||||
ZoneType p_type,
|
||||
const Polygon &p_polygon,
|
||||
const Rgb p_alarm_rgb,
|
||||
CheckMethod p_check_method,
|
||||
int p_min_pixel_threshold,
|
||||
int p_max_pixel_threshold,
|
||||
int p_min_alarm_pixels,
|
||||
int p_max_alarm_pixels,
|
||||
const Coord &p_filter_box,
|
||||
int p_min_filter_pixels,
|
||||
int p_max_filter_pixels,
|
||||
int p_min_blob_pixels,
|
||||
int p_max_blob_pixels,
|
||||
int p_min_blobs,
|
||||
int p_max_blobs,
|
||||
int p_overload_frames,
|
||||
int p_extend_alarm_frames
|
||||
) {
|
||||
monitor = p_monitor;
|
||||
|
||||
id = p_id;
|
||||
|
@ -48,10 +68,7 @@ void Zone::Setup( Monitor *p_monitor, int p_id, const char *p_label, ZoneType p_
|
|||
overload_frames = p_overload_frames;
|
||||
extend_alarm_frames = p_extend_alarm_frames;
|
||||
|
||||
//Debug( 1, "Initialised zone %d/%s - %d - %dx%d - Rgb:%06x, CM:%d, MnAT:%d, MxAT:%d, MnAP:%d, MxAP:%d, FB:%dx%d, MnFP:%d, MxFP:%d, MnBS:%d, MxBS:%d, MnB:%d, MxB:%d, OF: %d, AF: %d", id, label, type, polygon.Width(), polygon.Height(), alarm_rgb, check_method, min_pixel_threshold, max_pixel_threshold, min_alarm_pixels, max_alarm_pixels, filter_box.X(), filter_box.Y(), min_filter_pixels, max_filter_pixels, min_blob_pixels, max_blob_pixels, min_blobs, max_blobs, overload_frames, extend_alarm_frames );
|
||||
//Debug( 1, "Initialised zone %d/%s - %d - %dx%d - Rgb:%06x, CM:%d, MnAT:%d, MxAT:%d, MnAP:%d, MxAP:%d, FB:%dx%d, MnFP:%d, MxFP:%d, MnBS:%d, MxBS:%d, MnB:%d, MxB:%d, OF: %d", id, label, type, polygon.Width(), polygon.Height(), alarm_rgb, check_method, min_pixel_threshold, max_pixel_threshold, min_alarm_pixels, max_alarm_pixels, filter_box.X(), filter_box.Y(), min_filter_pixels, max_filter_pixels, min_blob_pixels, max_blob_pixels, min_blobs, max_blobs, overload_frames );
|
||||
//Debug( 1, "Initialised zone %d/%s - %d - %dx%d - Rgb:%06x, CM:%d", id, label, type, polygon.Width(), polygon.Height(), alarm_rgb, check_method );
|
||||
Debug( 1, "Initialised zone %d/%s - %d - %dx%d", id, label, type, polygon.Width(), polygon.Height() );
|
||||
Debug( 1, "Initialised zone %d/%s - %d - %dx%d - Rgb:%06x, CM:%d, MnAT:%d, MxAT:%d, MnAP:%d, MxAP:%d, FB:%dx%d, MnFP:%d, MxFP:%d, MnBS:%d, MxBS:%d, MnB:%d, MxB:%d, OF: %d, AF: %d", id, label, type, polygon.Width(), polygon.Height(), alarm_rgb, check_method, min_pixel_threshold, max_pixel_threshold, min_alarm_pixels, max_alarm_pixels, filter_box.X(), filter_box.Y(), min_filter_pixels, max_filter_pixels, min_blob_pixels, max_blob_pixels, min_blobs, max_blobs, overload_frames, extend_alarm_frames );
|
||||
|
||||
alarmed = false;
|
||||
pixel_diff = 0;
|
||||
|
@ -67,144 +84,113 @@ void Zone::Setup( Monitor *p_monitor, int p_id, const char *p_label, ZoneType p_
|
|||
overload_count = 0;
|
||||
extend_alarm_count = 0;
|
||||
|
||||
pg_image = new Image( monitor->Width(), monitor->Height(), 1, ZM_SUBPIX_ORDER_NONE);
|
||||
pg_image = new Image( monitor->Width(), monitor->Height(), 1, ZM_SUBPIX_ORDER_NONE );
|
||||
pg_image->Clear();
|
||||
pg_image->Fill( 0xff, polygon );
|
||||
pg_image->Outline( 0xff, polygon );
|
||||
|
||||
ranges = new Range[monitor->Height()];
|
||||
for ( unsigned int y = 0; y < monitor->Height(); y++)
|
||||
{
|
||||
for ( unsigned int y = 0; y < monitor->Height(); y++ ) {
|
||||
ranges[y].lo_x = -1;
|
||||
ranges[y].hi_x = 0;
|
||||
ranges[y].off_x = 0;
|
||||
const uint8_t *ppoly = pg_image->Buffer( 0, y );
|
||||
for ( unsigned int x = 0; x < monitor->Width(); x++, ppoly++ )
|
||||
{
|
||||
if ( *ppoly )
|
||||
{
|
||||
if ( ranges[y].lo_x == -1 )
|
||||
{
|
||||
for ( unsigned int x = 0; x < monitor->Width(); x++, ppoly++ ) {
|
||||
if ( *ppoly ) {
|
||||
if ( ranges[y].lo_x == -1 ) {
|
||||
ranges[y].lo_x = x;
|
||||
}
|
||||
if ( (unsigned int)ranges[y].hi_x < x )
|
||||
{
|
||||
if ( (unsigned int)ranges[y].hi_x < x ) {
|
||||
ranges[y].hi_x = x;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( config.record_diag_images )
|
||||
{
|
||||
// FIXME: Is this not a problem? If you had two zones for a monitor.. then these would conflict. You would only get 1 dump file
|
||||
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-poly.jpg", monitor->getStorage()->Path(), monitor->Id(), id);
|
||||
if ( ! diag_path[0] ) {
|
||||
snprintf( diag_path, sizeof(diag_path), "%s/%s/diag-%d-poly.jpg", config.dir_events, monitor->Name(), id);
|
||||
}
|
||||
pg_image->WriteJpeg( diag_path );
|
||||
}
|
||||
}
|
||||
} // end Zone::Setup
|
||||
|
||||
Zone::~Zone()
|
||||
{
|
||||
Zone::~Zone() {
|
||||
delete[] label;
|
||||
delete image;
|
||||
delete pg_image;
|
||||
delete[] ranges;
|
||||
}
|
||||
|
||||
void Zone::RecordStats( const Event *event )
|
||||
{
|
||||
void Zone::RecordStats( const Event *event ) {
|
||||
static char sql[ZM_SQL_MED_BUFSIZ];
|
||||
snprintf( sql, sizeof(sql), "insert into Stats set MonitorId=%d, ZoneId=%d, EventId=%d, FrameId=%d, PixelDiff=%d, AlarmPixels=%d, FilterPixels=%d, BlobPixels=%d, Blobs=%d, MinBlobSize=%d, MaxBlobSize=%d, MinX=%d, MinY=%d, MaxX=%d, MaxY=%d, Score=%d", monitor->Id(), id, event->Id(), event->Frames()+1, pixel_diff, alarm_pixels, alarm_filter_pixels, alarm_blob_pixels, alarm_blobs, min_blob_size, max_blob_size, alarm_box.LoX(), alarm_box.LoY(), alarm_box.HiX(), alarm_box.HiY(), score );
|
||||
if ( mysql_query( &dbconn, sql ) )
|
||||
{
|
||||
if ( mysql_query( &dbconn, sql ) ) {
|
||||
Error( "Can't insert event stats: %s", mysql_error( &dbconn ) );
|
||||
exit( mysql_errno( &dbconn ) );
|
||||
}
|
||||
}
|
||||
} // end void Zone::RecordStats( const Event *event )
|
||||
|
||||
|
||||
//=============================================================================
|
||||
bool Zone::CheckOverloadCount()
|
||||
{
|
||||
bool Zone::CheckOverloadCount() {
|
||||
Info("Overloaded count: %d, Overloaded frames: %d", overload_count, overload_frames);
|
||||
if ( overload_count )
|
||||
{
|
||||
if ( overload_count ) {
|
||||
Info( "In overload mode, %d frames of %d remaining", overload_count, overload_frames );
|
||||
Debug( 4, "In overload mode, %d frames of %d remaining", overload_count, overload_frames );
|
||||
overload_count--;
|
||||
return( false );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // end bool Zone::CheckOverloadCount()
|
||||
|
||||
void Zone::SetScore(unsigned int nScore)
|
||||
{
|
||||
void Zone::SetScore(unsigned int nScore) {
|
||||
score = nScore;
|
||||
}
|
||||
} // end void Zone::SetScore(unsigned int nScore)
|
||||
|
||||
|
||||
void Zone::SetAlarmImage(const Image* srcImage)
|
||||
{
|
||||
void Zone::SetAlarmImage(const Image* srcImage) {
|
||||
delete image;
|
||||
image = new Image(*srcImage);
|
||||
}
|
||||
} // end void Zone::SetAlarmImage( const Image* srcImage )
|
||||
|
||||
int Zone::GetOverloadCount()
|
||||
{
|
||||
int Zone::GetOverloadCount() {
|
||||
return overload_count;
|
||||
}
|
||||
} // end int Zone::GetOverloadCount()
|
||||
|
||||
void Zone::SetOverloadCount(int nOverCount)
|
||||
{
|
||||
void Zone::SetOverloadCount(int nOverCount) {
|
||||
overload_count = nOverCount;
|
||||
}
|
||||
} // end void Zone::SetOverloadCount(int nOverCount )
|
||||
|
||||
int Zone::GetOverloadFrames()
|
||||
{
|
||||
int Zone::GetOverloadFrames() {
|
||||
return overload_frames;
|
||||
}
|
||||
} // end int Zone::GetOverloadFrames
|
||||
|
||||
int Zone::GetExtendAlarmCount()
|
||||
{
|
||||
int Zone::GetExtendAlarmCount() {
|
||||
return extend_alarm_count;
|
||||
}
|
||||
} // end int Zone::GetExtendAlarmCount()
|
||||
|
||||
void Zone::SetExtendAlarmCount(int nExtendAlarmCount)
|
||||
{
|
||||
void Zone::SetExtendAlarmCount(int nExtendAlarmCount) {
|
||||
extend_alarm_count = nExtendAlarmCount;
|
||||
}
|
||||
} // end void Zone::SetExtendAlarmCount( int nExtendAlarmCount )
|
||||
|
||||
int Zone::GetExtendAlarmFrames()
|
||||
{
|
||||
int Zone::GetExtendAlarmFrames() {
|
||||
return extend_alarm_frames;
|
||||
}
|
||||
} // end int Zone::GetExtendAlarmFrames()
|
||||
|
||||
bool Zone::CheckExtendAlarmCount()
|
||||
{
|
||||
Info("ExtendAlarm count: %d, ExtendAlarm frames: %d", extend_alarm_count, extend_alarm_frames);
|
||||
if ( extend_alarm_count )
|
||||
{
|
||||
bool Zone::CheckExtendAlarmCount() {
|
||||
Info( "ExtendAlarm count: %d, ExtendAlarm frames: %d", extend_alarm_count, extend_alarm_frames );
|
||||
if ( extend_alarm_count ) {
|
||||
Debug( 3, "In extend mode, %d frames of %d remaining", extend_alarm_count, extend_alarm_frames );
|
||||
extend_alarm_count--;
|
||||
return( true );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} // end bool Zone::CheckExtendAlarmCount
|
||||
|
||||
|
||||
//===========================================================================
|
||||
|
||||
|
||||
|
||||
bool Zone::CheckAlarms( const Image *delta_image )
|
||||
{
|
||||
bool Zone::CheckAlarms( const Image *delta_image ) {
|
||||
ResetStats();
|
||||
|
||||
if ( overload_count )
|
||||
{
|
||||
if ( overload_count ) {
|
||||
Info( "In overload mode, %d frames of %d remaining", overload_count, overload_frames );
|
||||
Debug( 4, "In overload mode, %d frames of %d remaining", overload_count, overload_frames );
|
||||
overload_count--;
|
||||
|
@ -236,9 +222,6 @@ bool Zone::CheckAlarms( const Image *delta_image )
|
|||
|
||||
Debug( 4, "Checking alarms for zone %d/%s in lines %d -> %d", id, label, lo_y, hi_y );
|
||||
|
||||
Storage *storage = monitor->getStorage();
|
||||
|
||||
Debug( 5, "Checking for alarmed pixels" );
|
||||
/* if(config.cpu_extensions && sseversion >= 20) {
|
||||
sse2_alarmedpixels(diff_image, pg_image, &alarm_pixels, &pixel_diff_count);
|
||||
} else {
|
||||
|
@ -246,12 +229,10 @@ bool Zone::CheckAlarms( const Image *delta_image )
|
|||
} */
|
||||
std_alarmedpixels(diff_image, pg_image, &alarm_pixels, &pixel_diff_count);
|
||||
|
||||
if ( config.record_diag_images )
|
||||
{
|
||||
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-%d.jpg", storage->Path(), monitor->Id(), id, 1 );
|
||||
if ( ! diag_path[0] ) {
|
||||
snprintf( diag_path, sizeof(diag_path), "%s/%s/diag-%d-%d.jpg", config.dir_events, monitor->Name(), id, 1 );
|
||||
}
|
||||
diff_image->WriteJpeg( diag_path );
|
||||
}
|
||||
|
@ -275,61 +256,50 @@ bool Zone::CheckAlarms( const Image *delta_image )
|
|||
}
|
||||
|
||||
score = (100*alarm_pixels)/polygon.Area();
|
||||
if(score < 1)
|
||||
if ( score < 1 )
|
||||
score = 1; /* Fix for score of 0 when frame meets thresholds but alarmed area is not big enough */
|
||||
Debug( 5, "Current score is %d", score );
|
||||
|
||||
if ( check_method >= FILTERED_PIXELS )
|
||||
{
|
||||
if ( check_method >= FILTERED_PIXELS ) {
|
||||
int bx = filter_box.X();
|
||||
int by = filter_box.Y();
|
||||
int bx1 = bx-1;
|
||||
int by1 = by-1;
|
||||
|
||||
Debug( 5, "Checking for filtered pixels" );
|
||||
if ( bx > 1 || by > 1 )
|
||||
{
|
||||
if ( bx > 1 || by > 1 ) {
|
||||
// Now remove any pixels smaller than our filter size
|
||||
unsigned char *cpdiff;
|
||||
int ldx, hdx, ldy, hdy;
|
||||
bool block;
|
||||
for ( unsigned int y = lo_y; y <= hi_y; y++ )
|
||||
{
|
||||
for ( unsigned int y = lo_y; y <= hi_y; y++ ) {
|
||||
int lo_x = ranges[y].lo_x;
|
||||
int hi_x = ranges[y].hi_x;
|
||||
|
||||
pdiff = (uint8_t*)diff_image->Buffer( lo_x, y );
|
||||
|
||||
for ( int x = lo_x; x <= hi_x; x++, pdiff++ )
|
||||
{
|
||||
if ( *pdiff == WHITE )
|
||||
{
|
||||
for ( int x = lo_x; x <= hi_x; x++, pdiff++ ) {
|
||||
if ( *pdiff == WHITE ) {
|
||||
// Check participation in an X block
|
||||
ldx = (x>=(lo_x+bx1))?-bx1:lo_x-x;
|
||||
hdx = (x<=(hi_x-bx1))?0:((hi_x-x)-bx1);
|
||||
ldy = (y>=(lo_y+by1))?-by1:lo_y-y;
|
||||
hdy = (y<=(hi_y-by1))?0:((hi_y-y)-by1);
|
||||
block = false;
|
||||
for ( int dy = ldy; !block && dy <= hdy; dy++ )
|
||||
{
|
||||
for ( int dx = ldx; !block && dx <= hdx; dx++ )
|
||||
{
|
||||
for ( int dy = ldy; !block && dy <= hdy; dy++ ) {
|
||||
for ( int dx = ldx; !block && dx <= hdx; dx++ ) {
|
||||
block = true;
|
||||
for ( int dy2 = 0; block && dy2 < by; dy2++ )
|
||||
{
|
||||
for ( int dx2 = 0; block && dx2 < bx; dx2++ )
|
||||
{
|
||||
for ( int dy2 = 0; block && dy2 < by; dy2++ ) {
|
||||
for ( int dx2 = 0; block && dx2 < bx; dx2++ ) {
|
||||
cpdiff = diff_buff + (((y+dy+dy2)*diff_width) + (x+dx+dx2));
|
||||
if ( !*cpdiff )
|
||||
{
|
||||
if ( !*cpdiff ) {
|
||||
block = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( !block )
|
||||
{
|
||||
if ( !block ) {
|
||||
*pdiff = BLACK;
|
||||
continue;
|
||||
}
|
||||
|
@ -337,18 +307,14 @@ bool Zone::CheckAlarms( const Image *delta_image )
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
alarm_filter_pixels = alarm_pixels;
|
||||
}
|
||||
|
||||
if ( config.record_diag_images )
|
||||
{
|
||||
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-%d.jpg", storage->Path(), monitor->Id(), id, 2 );
|
||||
if ( !diag_path[0] ) {
|
||||
snprintf( diag_path, sizeof(diag_path), "%s/%d/diag-%d-%d.jpg", config.dir_events, monitor->Id(), id, 2 );
|
||||
}
|
||||
diff_image->WriteJpeg( diag_path );
|
||||
}
|
||||
|
@ -370,12 +336,11 @@ bool Zone::CheckAlarms( const Image *delta_image )
|
|||
}
|
||||
|
||||
score = (100*alarm_filter_pixels)/(polygon.Area());
|
||||
if(score < 1)
|
||||
if ( score < 1 )
|
||||
score = 1; /* Fix for score of 0 when frame meets thresholds but alarmed area is not big enough */
|
||||
Debug( 5, "Current score is %d", score );
|
||||
|
||||
if ( check_method >= BLOBS )
|
||||
{
|
||||
if ( check_method >= BLOBS ) {
|
||||
Debug( 5, "Checking for blob pixels" );
|
||||
typedef struct { unsigned char tag; int count; int lo_x; int hi_x; int lo_y; int hi_y; } BlobStats;
|
||||
BlobStats blob_stats[256];
|
||||
|
@ -384,16 +349,13 @@ bool Zone::CheckAlarms( const Image *delta_image )
|
|||
uint8_t last_x, last_y;
|
||||
BlobStats *bsx, *bsy;
|
||||
BlobStats *bsm, *bss;
|
||||
for ( unsigned int y = lo_y; y <= hi_y; y++ )
|
||||
{
|
||||
for ( unsigned int y = lo_y; y <= hi_y; y++ ) {
|
||||
int lo_x = ranges[y].lo_x;
|
||||
int hi_x = ranges[y].hi_x;
|
||||
|
||||
pdiff = (uint8_t*)diff_image->Buffer( lo_x, y );
|
||||
for ( int x = lo_x; x <= hi_x; x++, pdiff++ )
|
||||
{
|
||||
if ( *pdiff == WHITE )
|
||||
{
|
||||
for ( int x = lo_x; x <= hi_x; x++, pdiff++ ) {
|
||||
if ( *pdiff == WHITE ) {
|
||||
Debug( 9, "Got white pixel at %d,%d (%p)", x, y, pdiff );
|
||||
//last_x = (x>lo_x)?*(pdiff-1):0;
|
||||
//last_y = (y>lo_y&&x>=last_lo_x&&x<=last_hi_x)?*(pdiff-diff_width):0;
|
||||
|
@ -412,16 +374,13 @@ bool Zone::CheckAlarms( const Image *delta_image )
|
|||
}
|
||||
}
|
||||
|
||||
if ( last_x )
|
||||
{
|
||||
if ( last_x ) {
|
||||
Debug( 9, "Left neighbour is %d", last_x );
|
||||
bsx = &blob_stats[last_x];
|
||||
if ( last_y )
|
||||
{
|
||||
if ( last_y ) {
|
||||
Debug( 9, "Top neighbour is %d", last_y );
|
||||
bsy = &blob_stats[last_y];
|
||||
if ( last_x == last_y )
|
||||
{
|
||||
if ( last_x == last_y ) {
|
||||
Debug( 9, "Matching neighbours, setting to %d", last_x );
|
||||
// Add to the blob from the x side (either side really)
|
||||
*pdiff = last_x;
|
||||
|
@ -429,9 +388,7 @@ bool Zone::CheckAlarms( const Image *delta_image )
|
|||
bsx->count++;
|
||||
if ( x > bsx->hi_x ) bsx->hi_x = x;
|
||||
if ( (int)y > bsx->hi_y ) bsx->hi_y = y;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Aggregate blobs
|
||||
bsm = bsx->count>=bsy->count?bsx:bsy;
|
||||
bss = bsm==bsx?bsy:bsx;
|
||||
|
@ -441,19 +398,16 @@ bool Zone::CheckAlarms( const Image *delta_image )
|
|||
Debug( 9, "Slave blob t:%d, c:%d, lx:%d, hx:%d, ly:%d, hy:%d", bss->tag, bss->count, bss->lo_x, bss->hi_x, bss->lo_y, bss->hi_y );
|
||||
// Now change all those pixels to the other setting
|
||||
int changed = 0;
|
||||
for ( int sy = bss->lo_y; sy <= bss->hi_y; sy++)
|
||||
{
|
||||
for ( int sy = bss->lo_y; sy <= bss->hi_y; sy++) {
|
||||
int lo_sx = bss->lo_x>=ranges[sy].lo_x?bss->lo_x:ranges[sy].lo_x;
|
||||
int hi_sx = bss->hi_x<=ranges[sy].hi_x?bss->hi_x:ranges[sy].hi_x;
|
||||
|
||||
Debug( 9, "Changing %d, %d->%d", sy, lo_sx, hi_sx );
|
||||
Debug( 9, "Range %d, %d->%d", sy, ranges[sy].lo_x, ranges[sy].hi_x );
|
||||
spdiff = diff_buff + ((diff_width * sy) + lo_sx);
|
||||
for ( int sx = lo_sx; sx <= hi_sx; sx++, spdiff++ )
|
||||
{
|
||||
for ( int sx = lo_sx; sx <= hi_sx; sx++, spdiff++ ) {
|
||||
Debug( 9, "Pixel at %d,%d (%p) is %d", sx, sy, spdiff, *spdiff );
|
||||
if ( *spdiff == bss->tag )
|
||||
{
|
||||
if ( *spdiff == bss->tag ) {
|
||||
Debug( 9, "Setting pixel" );
|
||||
*spdiff = bsm->tag;
|
||||
changed++;
|
||||
|
@ -462,8 +416,7 @@ bool Zone::CheckAlarms( const Image *delta_image )
|
|||
}
|
||||
*pdiff = bsm->tag;
|
||||
alarm_blob_pixels++;
|
||||
if ( !changed )
|
||||
{
|
||||
if ( !changed ) {
|
||||
Info( "Master blob t:%d, c:%d, lx:%d, hx:%d, ly:%d, hy:%d", bsm->tag, bsm->count, bsm->lo_x, bsm->hi_x, bsm->lo_y, bsm->hi_y );
|
||||
Info( "Slave blob t:%d, c:%d, lx:%d, hx:%d, ly:%d, hy:%d", bss->tag, bss->count, bss->lo_x, bss->hi_x, bss->lo_y, bss->hi_y );
|
||||
Error( "No pixels changed, exiting" );
|
||||
|
@ -491,9 +444,7 @@ bool Zone::CheckAlarms( const Image *delta_image )
|
|||
bss->hi_x = 0;
|
||||
bss->hi_y = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Debug( 9, "Setting to left neighbour %d", last_x );
|
||||
// Add to the blob from the x side
|
||||
*pdiff = last_x;
|
||||
|
@ -502,11 +453,8 @@ bool Zone::CheckAlarms( const Image *delta_image )
|
|||
if ( x > bsx->hi_x ) bsx->hi_x = x;
|
||||
if ( (int)y > bsx->hi_y ) bsx->hi_y = y;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( last_y )
|
||||
{
|
||||
} else {
|
||||
if ( last_y ) {
|
||||
Debug( 9, "Top neighbour is %d", last_y );
|
||||
Debug( 9, "Setting to top neighbour %d", last_y );
|
||||
|
||||
|
@ -518,28 +466,19 @@ bool Zone::CheckAlarms( const Image *delta_image )
|
|||
bsy->count++;
|
||||
if ( x > bsy->hi_x ) bsy->hi_x = x;
|
||||
if ( (int)y > bsy->hi_y ) bsy->hi_y = y;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Create a new blob
|
||||
int i;
|
||||
for ( i = (WHITE-1); i > 0; i-- )
|
||||
{
|
||||
for ( i = (WHITE-1); i > 0; i-- ) {
|
||||
BlobStats *bs = &blob_stats[i];
|
||||
// See if we can recycle one first, only if it's at least two rows up
|
||||
if ( bs->count && bs->hi_y < (int)(y-1) )
|
||||
{
|
||||
if ( (min_blob_pixels && bs->count < min_blob_pixels) || (max_blob_pixels && bs->count > max_blob_pixels) )
|
||||
{
|
||||
if ( config.create_analysis_images || config.record_diag_images )
|
||||
{
|
||||
for ( int sy = bs->lo_y; sy <= bs->hi_y; sy++ )
|
||||
{
|
||||
if ( bs->count && bs->hi_y < (int)(y-1) ) {
|
||||
if ( (min_blob_pixels && bs->count < min_blob_pixels) || (max_blob_pixels && bs->count > max_blob_pixels) ) {
|
||||
if ( config.create_analysis_images || config.record_diag_images ) {
|
||||
for ( int sy = bs->lo_y; sy <= bs->hi_y; sy++ ) {
|
||||
spdiff = diff_buff + ((diff_width * sy) + bs->lo_x);
|
||||
for ( int sx = bs->lo_x; sx <= bs->hi_x; sx++, spdiff++ )
|
||||
{
|
||||
if ( *spdiff == bs->tag )
|
||||
{
|
||||
for ( int sx = bs->lo_x; sx <= bs->hi_x; sx++, spdiff++ ) {
|
||||
if ( *spdiff == bs->tag ) {
|
||||
*spdiff = BLACK;
|
||||
}
|
||||
}
|
||||
|
@ -558,8 +497,7 @@ bool Zone::CheckAlarms( const Image *delta_image )
|
|||
bs->hi_y = 0;
|
||||
}
|
||||
}
|
||||
if ( !bs->count )
|
||||
{
|
||||
if ( !bs->count ) {
|
||||
Debug( 9, "Creating new blob %d", i );
|
||||
*pdiff = i;
|
||||
alarm_blob_pixels++;
|
||||
|
@ -573,8 +511,7 @@ bool Zone::CheckAlarms( const Image *delta_image )
|
|||
break;
|
||||
}
|
||||
}
|
||||
if ( i == 0 )
|
||||
{
|
||||
if ( i == 0 ) {
|
||||
Warning( "Max blob count reached. Unable to allocate new blobs so terminating. Zone settings may be too sensitive." );
|
||||
x = hi_x+1;
|
||||
y = hi_y+1;
|
||||
|
@ -584,40 +521,30 @@ bool Zone::CheckAlarms( const Image *delta_image )
|
|||
}
|
||||
}
|
||||
}
|
||||
if ( config.record_diag_images )
|
||||
{
|
||||
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-%d.jpg", storage->Path(), monitor->Id(), id, 3 );
|
||||
if ( !diag_path[0] ) {
|
||||
snprintf( diag_path, sizeof(diag_path), "%s/%d/diag-%d-%d.jpg", config.dir_events, monitor->Id(), id, 3 );
|
||||
}
|
||||
diff_image->WriteJpeg( diag_path );
|
||||
}
|
||||
|
||||
if ( !alarm_blobs )
|
||||
{
|
||||
if ( !alarm_blobs ) {
|
||||
return( false );
|
||||
}
|
||||
|
||||
Debug( 5, "Got %d raw blob pixels, %d raw blobs, need %d -> %d, %d -> %d", alarm_blob_pixels, alarm_blobs, min_blob_pixels, max_blob_pixels, min_blobs, max_blobs );
|
||||
|
||||
// Now eliminate blobs under the threshold
|
||||
for ( int i = 1; i < WHITE; i++ )
|
||||
{
|
||||
for ( int i = 1; i < WHITE; i++ ) {
|
||||
BlobStats *bs = &blob_stats[i];
|
||||
if ( bs->count )
|
||||
{
|
||||
if ( (min_blob_pixels && bs->count < min_blob_pixels) || (max_blob_pixels && bs->count > max_blob_pixels) )
|
||||
{
|
||||
if ( config.create_analysis_images || config.record_diag_images )
|
||||
{
|
||||
for ( int sy = bs->lo_y; sy <= bs->hi_y; sy++ )
|
||||
{
|
||||
if ( bs->count ) {
|
||||
if ( (min_blob_pixels && bs->count < min_blob_pixels) || (max_blob_pixels && bs->count > max_blob_pixels) ) {
|
||||
if ( config.create_analysis_images || config.record_diag_images ) {
|
||||
for ( int sy = bs->lo_y; sy <= bs->hi_y; sy++ ) {
|
||||
spdiff = diff_buff + ((diff_width * sy) + bs->lo_x);
|
||||
for ( int sx = bs->lo_x; sx <= bs->hi_x; sx++, spdiff++ )
|
||||
{
|
||||
if ( *spdiff == bs->tag )
|
||||
{
|
||||
for ( int sx = bs->lo_x; sx <= bs->hi_x; sx++, spdiff++ ) {
|
||||
if ( *spdiff == bs->tag ) {
|
||||
*spdiff = BLACK;
|
||||
}
|
||||
}
|
||||
|
@ -634,21 +561,17 @@ bool Zone::CheckAlarms( const Image *delta_image )
|
|||
bs->lo_y = 0;
|
||||
bs->hi_x = 0;
|
||||
bs->hi_y = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Debug( 6, "Preserved blob %d, %d pixels (%d,%d - %d,%d), %d current blobs", i, bs->count, bs->lo_x, bs->lo_y, bs->hi_x, bs->hi_y, alarm_blobs );
|
||||
if ( !min_blob_size || bs->count < min_blob_size ) min_blob_size = bs->count;
|
||||
if ( !max_blob_size || bs->count > max_blob_size ) max_blob_size = bs->count;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( config.record_diag_images )
|
||||
{
|
||||
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-%d.jpg", storage->Path(), monitor->Id(), id, 4 );
|
||||
if ( !diag_path[0] ) {
|
||||
snprintf( diag_path, sizeof(diag_path), "%s/%d/diag-%d-%d.jpg", config.dir_events, monitor->Id(), id, 4 );
|
||||
}
|
||||
diff_image->WriteJpeg( diag_path );
|
||||
}
|
||||
|
@ -669,7 +592,7 @@ bool Zone::CheckAlarms( const Image *delta_image )
|
|||
}
|
||||
|
||||
score = (100*alarm_blob_pixels)/(polygon.Area());
|
||||
if(score < 1)
|
||||
if ( score < 1 )
|
||||
score = 1; /* Fix for score of 0 when frame meets thresholds but alarmed area is not big enough */
|
||||
Debug( 5, "Current score is %d", score );
|
||||
|
||||
|
@ -677,25 +600,19 @@ bool Zone::CheckAlarms( const Image *delta_image )
|
|||
alarm_hi_x = polygon.LoX()-1;
|
||||
alarm_lo_y = polygon.HiY()+1;
|
||||
alarm_hi_y = polygon.LoY()-1;
|
||||
for ( int i = 1; i < WHITE; i++ )
|
||||
{
|
||||
|
||||
for ( int i = 1; i < WHITE; i++ ) {
|
||||
BlobStats *bs = &blob_stats[i];
|
||||
if ( bs->count )
|
||||
{
|
||||
if ( bs->count == max_blob_size )
|
||||
{
|
||||
if ( config.weighted_alarm_centres )
|
||||
{
|
||||
if ( bs->count ) {
|
||||
if ( bs->count == max_blob_size ) {
|
||||
if ( config.weighted_alarm_centres ) {
|
||||
unsigned long x_total = 0;
|
||||
unsigned long y_total = 0;
|
||||
|
||||
for ( int sy = bs->lo_y; sy <= bs->hi_y; sy++ )
|
||||
{
|
||||
for ( int sy = bs->lo_y; sy <= bs->hi_y; sy++ ) {
|
||||
spdiff = diff_buff + ((diff_width * sy) + bs->lo_x);
|
||||
for ( int sx = bs->lo_x; sx <= bs->hi_x; sx++, spdiff++ )
|
||||
{
|
||||
if ( *spdiff == bs->tag )
|
||||
{
|
||||
for ( int sx = bs->lo_x; sx <= bs->hi_x; sx++, spdiff++ ) {
|
||||
if ( *spdiff == bs->tag ) {
|
||||
x_total += sx;
|
||||
y_total += sy;
|
||||
}
|
||||
|
@ -703,9 +620,7 @@ bool Zone::CheckAlarms( const Image *delta_image )
|
|||
}
|
||||
alarm_mid_x = int(round(x_total/bs->count));
|
||||
alarm_mid_y = int(round(y_total/bs->count));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
alarm_mid_x = int((bs->hi_x+bs->lo_x+1)/2);
|
||||
alarm_mid_y = int((bs->hi_y+bs->lo_y+1)/2);
|
||||
}
|
||||
|
@ -715,94 +630,72 @@ bool Zone::CheckAlarms( const Image *delta_image )
|
|||
if ( alarm_lo_y > bs->lo_y ) alarm_lo_y = bs->lo_y;
|
||||
if ( alarm_hi_x < bs->hi_x ) alarm_hi_x = bs->hi_x;
|
||||
if ( alarm_hi_y < bs->hi_y ) alarm_hi_y = bs->hi_y;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} // end if bs->count
|
||||
} // end for i < WHITE
|
||||
} else {
|
||||
alarm_mid_x = int((alarm_hi_x+alarm_lo_x+1)/2);
|
||||
alarm_mid_y = int((alarm_hi_y+alarm_lo_y+1)/2);
|
||||
}
|
||||
}
|
||||
|
||||
if ( type == INCLUSIVE )
|
||||
{
|
||||
if ( type == INCLUSIVE ) {
|
||||
// score >>= 1;
|
||||
score /= 2;
|
||||
}
|
||||
else if ( type == EXCLUSIVE )
|
||||
{
|
||||
} else if ( type == EXCLUSIVE ) {
|
||||
// score <<= 1;
|
||||
score *= 2;
|
||||
|
||||
}
|
||||
|
||||
Debug( 5, "Adjusted score is %d", score );
|
||||
|
||||
// Now outline the changed region
|
||||
if ( score )
|
||||
{
|
||||
if ( score ) {
|
||||
alarm_box = Box( Coord( alarm_lo_x, alarm_lo_y ), Coord( alarm_hi_x, alarm_hi_y ) );
|
||||
|
||||
//if ( monitor->followMotion() )
|
||||
if ( true )
|
||||
{
|
||||
if ( true ) {
|
||||
alarm_centre = Coord( alarm_mid_x, alarm_mid_y );
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
alarm_centre = alarm_box.Centre();
|
||||
}
|
||||
|
||||
if ( (type < PRECLUSIVE) && check_method >= BLOBS && config.create_analysis_images )
|
||||
{
|
||||
if ( (type < PRECLUSIVE) && check_method >= BLOBS && config.create_analysis_images ) {
|
||||
|
||||
// First mask out anything we don't want
|
||||
for ( unsigned int y = lo_y; y <= hi_y; y++ )
|
||||
{
|
||||
for ( unsigned int y = lo_y; y <= hi_y; y++ ) {
|
||||
pdiff = diff_buff + ((diff_width * y) + lo_x);
|
||||
|
||||
int lo_x2 = ranges[y].lo_x;
|
||||
int hi_x2 = ranges[y].hi_x;
|
||||
|
||||
int lo_gap = lo_x2-lo_x;
|
||||
if ( lo_gap > 0 )
|
||||
{
|
||||
if ( lo_gap == 1 )
|
||||
{
|
||||
if ( lo_gap > 0 ) {
|
||||
if ( lo_gap == 1 ) {
|
||||
*pdiff++ = BLACK;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
memset( pdiff, BLACK, lo_gap );
|
||||
pdiff += lo_gap;
|
||||
}
|
||||
}
|
||||
|
||||
ppoly = pg_image->Buffer( lo_x2, y );
|
||||
for ( int x = lo_x2; x <= hi_x2; x++, pdiff++, ppoly++ )
|
||||
{
|
||||
if ( !*ppoly )
|
||||
{
|
||||
for ( int x = lo_x2; x <= hi_x2; x++, pdiff++, ppoly++ ) {
|
||||
if ( !*ppoly ) {
|
||||
*pdiff = BLACK;
|
||||
}
|
||||
}
|
||||
|
||||
int hi_gap = hi_x-hi_x2;
|
||||
if ( hi_gap > 0 )
|
||||
{
|
||||
if ( hi_gap == 1 )
|
||||
{
|
||||
if ( hi_gap > 0 ) {
|
||||
if ( hi_gap == 1 ) {
|
||||
*pdiff = BLACK;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
memset( pdiff, BLACK, hi_gap );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( monitor->Colours() == ZM_COLOUR_GRAY8 ) {
|
||||
if ( monitor->Colours() == ZM_COLOUR_GRAY8 ) {
|
||||
image = diff_image->HighlightEdges( alarm_rgb, ZM_COLOUR_RGB24, ZM_SUBPIX_ORDER_RGB, &polygon.Extent() );
|
||||
} else {
|
||||
image = diff_image->HighlightEdges( alarm_rgb, monitor->Colours(), monitor->SubpixelOrder(), &polygon.Extent() );
|
||||
|
@ -810,20 +703,18 @@ bool Zone::CheckAlarms( const Image *delta_image )
|
|||
|
||||
// Only need to delete this when 'image' becomes detached and points somewhere else
|
||||
delete diff_image;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
delete image;
|
||||
image = 0;
|
||||
}
|
||||
|
||||
Debug( 3, "%s: Pixel Diff: %d, Alarm Pixels: %d, Filter Pixels: %d, Blob Pixels: %d, Blobs: %d, Score: %d", Label(), pixel_diff, alarm_pixels, alarm_filter_pixels, alarm_blob_pixels, alarm_blobs, score );
|
||||
Debug( 1, "%s: Pixel Diff: %d, Alarm Pixels: %d, Filter Pixels: %d, Blob Pixels: %d, Blobs: %d, Score: %d",
|
||||
Label(), pixel_diff, alarm_pixels, alarm_filter_pixels, alarm_blob_pixels, alarm_blobs, score );
|
||||
}
|
||||
return( true );
|
||||
}
|
||||
|
||||
bool Zone::ParsePolygonString( const char *poly_string, Polygon &polygon )
|
||||
{
|
||||
bool Zone::ParsePolygonString( const char *poly_string, Polygon &polygon ) {
|
||||
Debug( 3, "Parsing polygon string '%s'", poly_string );
|
||||
|
||||
char *str_ptr = new char[strlen(poly_string)+1];
|
||||
|
@ -834,27 +725,21 @@ bool Zone::ParsePolygonString( const char *poly_string, Polygon &polygon )
|
|||
int n_coords = 0;
|
||||
int max_n_coords = strlen(str)/4;
|
||||
Coord *coords = new Coord[max_n_coords];
|
||||
while( true )
|
||||
{
|
||||
if ( *str == '\0' )
|
||||
{
|
||||
while( true ) {
|
||||
if ( *str == '\0' ) {
|
||||
break;
|
||||
}
|
||||
ws = strchr( str, ' ' );
|
||||
if ( ws )
|
||||
{
|
||||
if ( ws ) {
|
||||
*ws = '\0';
|
||||
}
|
||||
char *cp = strchr( str, ',' );
|
||||
if ( !cp )
|
||||
{
|
||||
if ( !cp ) {
|
||||
Error( "Bogus coordinate %s found in polygon string", str );
|
||||
delete[] coords;
|
||||
delete[] str_ptr;
|
||||
return( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
*cp = '\0';
|
||||
char *xp = str;
|
||||
char *yp = cp+1;
|
||||
|
@ -892,8 +777,7 @@ bool Zone::ParsePolygonString( const char *poly_string, Polygon &polygon )
|
|||
return( true );
|
||||
}
|
||||
|
||||
bool Zone::ParseZoneString( const char *zone_string, int &zone_id, int &colour, Polygon &polygon )
|
||||
{
|
||||
bool Zone::ParseZoneString( const char *zone_string, int &zone_id, int &colour, Polygon &polygon ) {
|
||||
Debug( 3, "Parsing zone string '%s'", zone_string );
|
||||
|
||||
char *str_ptr = new char[strlen(zone_string)+1];
|
||||
|
@ -901,14 +785,12 @@ bool Zone::ParseZoneString( const char *zone_string, int &zone_id, int &colour,
|
|||
strcpy( str, zone_string );
|
||||
|
||||
char *ws = strchr( str, ' ' );
|
||||
if ( !ws )
|
||||
{
|
||||
if ( !ws ) {
|
||||
Debug( 3, "No initial whitespace found in zone string '%s', finishing", str );
|
||||
}
|
||||
zone_id = strtol( str, 0, 10 );
|
||||
Debug( 3, "Got zone %d from zone string", zone_id );
|
||||
if ( !ws )
|
||||
{
|
||||
if ( !ws ) {
|
||||
delete str_ptr;
|
||||
return( true );
|
||||
}
|
||||
|
@ -917,14 +799,12 @@ bool Zone::ParseZoneString( const char *zone_string, int &zone_id, int &colour,
|
|||
str = ws+1;
|
||||
|
||||
ws = strchr( str, ' ' );
|
||||
if ( !ws )
|
||||
{
|
||||
if ( !ws ) {
|
||||
Debug( 3, "No secondary whitespace found in zone string '%s', finishing", zone_string );
|
||||
}
|
||||
colour = strtol( str, 0, 16 );
|
||||
Debug( 3, "Got colour %06x from zone string", colour );
|
||||
if ( !ws )
|
||||
{
|
||||
if ( !ws ) {
|
||||
delete str_ptr;
|
||||
return( true );
|
||||
}
|
||||
|
@ -941,8 +821,7 @@ bool Zone::ParseZoneString( const char *zone_string, int &zone_id, int &colour,
|
|||
return( result );
|
||||
}
|
||||
|
||||
int Zone::Load( Monitor *monitor, Zone **&zones )
|
||||
{
|
||||
int Zone::Load( Monitor *monitor, Zone **&zones ) {
|
||||
static char sql[ZM_SQL_MED_BUFSIZ];
|
||||
snprintf( sql, sizeof(sql), "select Id,Name,Type+0,Units,Coords,AlarmRGB,CheckMethod+0,MinPixelThreshold,MaxPixelThreshold,MinAlarmPixels,MaxAlarmPixels,FilterX,FilterY,MinFilterPixels,MaxFilterPixels,MinBlobPixels,MaxBlobPixels,MinBlobs,MaxBlobs,OverloadFrames,ExtendAlarmFrames from Zones where MonitorId = %d order by Type, Id", monitor->Id() );
|
||||
if ( mysql_query( &dbconn, sql ) ) {
|
||||
|
@ -960,12 +839,11 @@ int Zone::Load( Monitor *monitor, Zone **&zones )
|
|||
delete[] zones;
|
||||
zones = new Zone *[n_zones];
|
||||
for( int i = 0; MYSQL_ROW dbrow = mysql_fetch_row( result ); i++ ) {
|
||||
zones[i] = NULL;
|
||||
int col = 0;
|
||||
|
||||
int Id = atoi(dbrow[col++]);
|
||||
const char *Name = dbrow[col++];
|
||||
ZoneType Type = (ZoneType) atoi(dbrow[col++]);
|
||||
int Type = atoi(dbrow[col++]);
|
||||
const char *Units = dbrow[col++];
|
||||
const char *Coords = dbrow[col++];
|
||||
int AlarmRGB = dbrow[col]?atoi(dbrow[col]):0; col++;
|
||||
|
@ -1012,25 +890,22 @@ int Zone::Load( Monitor *monitor, Zone **&zones )
|
|||
MaxBlobPixels = (MaxBlobPixels*polygon.Area())/100;
|
||||
}
|
||||
|
||||
if ( Type == INACTIVE ) {
|
||||
if ( atoi(dbrow[2]) == Zone::INACTIVE ) {
|
||||
zones[i] = new Zone( monitor, Id, Name, polygon );
|
||||
} else if ( Type == PRIVACY ) {
|
||||
zones[i] = new Zone( monitor, Id, Name, Type, polygon );
|
||||
} else {
|
||||
zones[i] = new Zone( monitor, Id, Name, Type, polygon, AlarmRGB, (Zone::CheckMethod)CheckMethod, MinPixelThreshold, MaxPixelThreshold, MinAlarmPixels, MaxAlarmPixels, Coord( FilterX, FilterY ), MinFilterPixels, MaxFilterPixels, MinBlobPixels, MaxBlobPixels, MinBlobs, MaxBlobs, OverloadFrames, ExtendAlarmFrames );
|
||||
} else if ( atoi(dbrow[2]) == Zone::PRIVACY ) {
|
||||
zones[i] = new Zone( monitor, Id, Name, (Zone::ZoneType)Type, polygon );
|
||||
}
|
||||
zones[i] = new Zone( monitor, Id, Name, (Zone::ZoneType)Type, polygon, AlarmRGB, (Zone::CheckMethod)CheckMethod, MinPixelThreshold, MaxPixelThreshold, MinAlarmPixels, MaxAlarmPixels, Coord( FilterX, FilterY ), MinFilterPixels, MaxFilterPixels, MinBlobPixels, MaxBlobPixels, MinBlobs, MaxBlobs, OverloadFrames, ExtendAlarmFrames );
|
||||
}
|
||||
} // end foreach row in zones table
|
||||
if ( mysql_errno( &dbconn ) ) {
|
||||
Error( "Can't fetch row: %s", mysql_error( &dbconn ) );
|
||||
exit( mysql_errno( &dbconn ) );
|
||||
}
|
||||
// Yadda yadda
|
||||
mysql_free_result( result );
|
||||
return( n_zones );
|
||||
}
|
||||
|
||||
bool Zone::DumpSettings( char *output, bool /*verbose*/ )
|
||||
{
|
||||
bool Zone::DumpSettings( char *output, bool /*verbose*/ ) {
|
||||
output[0] = 0;
|
||||
|
||||
sprintf( output+strlen(output), " Id : %d\n", id );
|
||||
|
@ -1044,8 +919,7 @@ bool Zone::DumpSettings( char *output, bool /*verbose*/ )
|
|||
type==PRIVACY?"Privacy":"Unknown"
|
||||
))))));
|
||||
sprintf( output+strlen(output), " Shape : %d points\n", polygon.getNumCoords() );
|
||||
for ( int i = 0; i < polygon.getNumCoords(); i++ )
|
||||
{
|
||||
for ( int i = 0; i < polygon.getNumCoords(); i++ ) {
|
||||
sprintf( output+strlen(output), " %i: %d,%d\n", i, polygon.getCoord( i ).X(), polygon.getCoord( i ).Y() );
|
||||
}
|
||||
sprintf( output+strlen(output), " Alarm RGB : %06x\n", alarm_rgb );
|
||||
|
@ -1084,8 +958,7 @@ void Zone::std_alarmedpixels(Image* pdiff_image, const Image* ppoly_image, unsig
|
|||
|
||||
lo_y = polygon.LoY();
|
||||
hi_y = polygon.HiY();
|
||||
for ( unsigned int y = lo_y; y <= hi_y; y++ )
|
||||
{
|
||||
for ( unsigned int y = lo_y; y <= hi_y; y++ ) {
|
||||
lo_x = ranges[y].lo_x;
|
||||
hi_x = ranges[y].hi_x;
|
||||
|
||||
|
@ -1093,16 +966,12 @@ void Zone::std_alarmedpixels(Image* pdiff_image, const Image* ppoly_image, unsig
|
|||
pdiff = (uint8_t*)pdiff_image->Buffer( lo_x, y );
|
||||
ppoly = ppoly_image->Buffer( lo_x, y );
|
||||
|
||||
for ( unsigned int x = lo_x; x <= hi_x; x++, pdiff++, ppoly++ )
|
||||
{
|
||||
if ( *ppoly && (*pdiff > min_pixel_threshold) && (*pdiff <= calc_max_pixel_threshold) )
|
||||
{
|
||||
for ( unsigned int x = lo_x; x <= hi_x; x++, pdiff++, ppoly++ ) {
|
||||
if ( *ppoly && (*pdiff > min_pixel_threshold) && (*pdiff <= calc_max_pixel_threshold) ) {
|
||||
pixelsalarmed++;
|
||||
pixelsdifference += *pdiff;
|
||||
*pdiff = WHITE;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
*pdiff = BLACK;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,7 +94,10 @@ class ImageComponent extends Component {
|
|||
// Take the StartTime of an Event and return
|
||||
// the path to its location on the filesystem
|
||||
public function getEventPath( $event ) {
|
||||
if ( $config['ZM_USE_DEEP_STORAGE'] == 1 )
|
||||
return $event['Event']['MonitorId'].'/'.strftime( "%y/%m/%d/%H/%M/%S", strtotime($event['Event']['StartTime']) );
|
||||
else
|
||||
return $event['Event']['MonitorId'].'/'.$event['Event']['Id'];
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
AUTOMAKE_OPTIONS = gnu
|
||||
|
||||
webdir = @WEB_PREFIX@/css
|
||||
|
||||
dist_web_DATA = \
|
||||
bootstrap.min.css \
|
||||
reset.css \
|
||||
spinner.css \
|
||||
overlay.css
|
|
@ -61,12 +61,8 @@
|
|||
text-align: left;
|
||||
}
|
||||
|
||||
#consoleTable .colOrder {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#consoleTable .colMark {
|
||||
width: 32px;
|
||||
width: 62px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
@ -85,13 +81,3 @@
|
|||
#consoleTable .colLeftButtons input {
|
||||
margin-right: 24px;
|
||||
}
|
||||
|
||||
#consoleTable .colRightButtons {
|
||||
text-align: right;
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
#consoleTable .colRightButtons input {
|
||||
margin: 0 8px;
|
||||
}
|
||||
|
||||
|
|
|
@ -61,12 +61,8 @@
|
|||
text-align: left;
|
||||
}
|
||||
|
||||
#consoleTable .colOrder {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#consoleTable .colMark {
|
||||
width: 32px;
|
||||
width: 62px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
@ -85,13 +81,3 @@
|
|||
#consoleTable .colLeftButtons input {
|
||||
margin-right: 24px;
|
||||
}
|
||||
|
||||
#consoleTable .colRightButtons {
|
||||
text-align: right;
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
#consoleTable .colRightButtons input {
|
||||
margin: 0 8px;
|
||||
}
|
||||
|
||||
|
|
|
@ -61,12 +61,8 @@
|
|||
text-align: left;
|
||||
}
|
||||
|
||||
#consoleTable .colOrder {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#consoleTable .colMark {
|
||||
width: 32px;
|
||||
width: 62px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
@ -85,12 +81,3 @@
|
|||
#consoleTable .colLeftButtons input {
|
||||
margin-right: 24px;
|
||||
}
|
||||
|
||||
#consoleTable .colRightButtons {
|
||||
text-align: right;
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
#consoleTable .colRightButtons input {
|
||||
margin: 0 8px;
|
||||
}
|
||||
|
|
|
@ -74,8 +74,6 @@ function xhtmlHeaders( $file, $title ) {
|
|||
<script type="text/javascript" src="tools/mootools/mootools-core.js"></script>
|
||||
<script type="text/javascript" src="tools/mootools/mootools-more.js"></script>
|
||||
<script type="text/javascript" src="js/mootools.ext.js"></script>
|
||||
<?php if ( !in_array($basename, $bad_views) ) { ?>
|
||||
<!--<script type="text/javascript" src="js/overlay.js"></script>-->
|
||||
<script type="text/javascript" src="skins/<?php echo $skin; ?>/js/jquery-1.11.3.js"></script>
|
||||
<script type="text/javascript" src="skins/<?php echo $skin; ?>/js/jquery-ui-1.11.3.js"></script>
|
||||
<script type="text/javascript" src="skins/<?php echo $skin; ?>/js/bootstrap.min.js"></script>
|
||||
|
@ -90,7 +88,6 @@ var $j = jQuery.noConflict();
|
|||
//]]>
|
||||
</script>
|
||||
<script type="text/javascript" src="skins/<?php echo $skin; ?>/views/js/state.js"></script>
|
||||
<?php } ?>
|
||||
<?php if ( $title == 'Login' && (defined('ZM_OPT_USE_GOOG_RECAPTCHA') && ZM_OPT_USE_GOOG_RECAPTCHA) ) { ?>
|
||||
<script src='https://www.google.com/recaptcha/api.js'></script>
|
||||
<?php } else if ( $title == 'Event' ) {
|
||||
|
|
|
@ -83,6 +83,7 @@ $eventCounts = array(
|
|||
|
||||
$displayMonitors = NULL;
|
||||
|
||||
<<<<<<< HEAD
|
||||
# Also populates displayMonitors
|
||||
$navbar = getNavBarHTML();
|
||||
$zoneCount = 0;
|
||||
|
@ -107,12 +108,76 @@ for( $i = 0; $i < count($displayMonitors); $i += 1 ) {
|
|||
$eventCounts[$j]['total'] += $monitor['EventCount'.$j];
|
||||
}
|
||||
$zoneCount += $monitor['ZoneCount'];
|
||||
=======
|
||||
$group = NULL;
|
||||
if ( ! empty($_COOKIE['zmGroup']) ) {
|
||||
if ( $group = dbFetchOne( 'select * from Groups where Id = ?', NULL, array($_COOKIE['zmGroup'])) )
|
||||
$groupIds = array_flip(explode( ',', $group['MonitorIds'] ));
|
||||
}
|
||||
|
||||
noCacheHeaders();
|
||||
|
||||
$maxWidth = 0;
|
||||
$maxHeight = 0;
|
||||
$cycleCount = 0;
|
||||
$minSequence = 0;
|
||||
$maxSequence = 1;
|
||||
$monitors = dbFetchAll( "select * from Monitors order by Sequence asc" );
|
||||
$displayMonitors = array();
|
||||
for ( $i = 0; $i < count($monitors); $i++ ) {
|
||||
if ( !visibleMonitor( $monitors[$i]['Id'] ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( $group && !empty($groupIds) && !array_key_exists( $monitors[$i]['Id'], $groupIds ) ) {
|
||||
continue;
|
||||
}
|
||||
$monitors[$i]['Show'] = true;
|
||||
$monitors[$i]['zmc'] = zmcStatus( $monitors[$i] );
|
||||
$monitors[$i]['zma'] = zmaStatus( $monitors[$i] );
|
||||
$monitors[$i]['ZoneCount'] = dbFetchOne( 'select count(Id) as ZoneCount from Zones where MonitorId = ?', 'ZoneCount', array($monitors[$i]['Id']) );
|
||||
$counts = array();
|
||||
for ( $j = 0; $j < count($eventCounts); $j++ ) {
|
||||
$filter = addFilterTerm( $eventCounts[$j]['filter'], count($eventCounts[$j]['filter']['terms']), array( "cnj" => "and", "attr" => "MonitorId", "op" => "=", "val" => $monitors[$i]['Id'] ) );
|
||||
parseFilter( $filter );
|
||||
$counts[] = "count(if(1".$filter['sql'].",1,NULL)) as EventCount$j";
|
||||
$monitors[$i]['eventCounts'][$j]['filter'] = $filter;
|
||||
}
|
||||
$sql = "select ".join($counts,", ")." from Events as E where MonitorId = ?";
|
||||
$counts = dbFetchOne( $sql, NULL, array($monitors[$i]['Id']) );
|
||||
if ( $monitors[$i]['Function'] != 'None' ) {
|
||||
$cycleCount++;
|
||||
$scaleWidth = reScale( $monitors[$i]['Width'], $monitors[$i]['DefaultScale'], ZM_WEB_DEFAULT_SCALE );
|
||||
$scaleHeight = reScale( $monitors[$i]['Height'], $monitors[$i]['DefaultScale'], ZM_WEB_DEFAULT_SCALE );
|
||||
if ( $maxWidth < $scaleWidth ) $maxWidth = $scaleWidth;
|
||||
if ( $maxHeight < $scaleHeight ) $maxHeight = $scaleHeight;
|
||||
}
|
||||
if ( $counts ) $monitors[$i] = array_merge( $monitors[$i], $counts );
|
||||
$displayMonitors[] = $monitors[$i];
|
||||
>>>>>>> dragndrop_monitor_sorting
|
||||
}
|
||||
|
||||
noCacheHeaders();
|
||||
|
||||
$eventsView = ZM_WEB_EVENTS_VIEW;
|
||||
$eventsWindow = 'zm'.ucfirst(ZM_WEB_EVENTS_VIEW);
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
|
||||
$eventCount = 0;
|
||||
for ( $i = 0; $i < count($eventCounts); $i++ ) {
|
||||
$eventCounts[$i]['total'] = 0;
|
||||
}
|
||||
$zoneCount = 0;
|
||||
foreach( $displayMonitors as $monitor ) {
|
||||
for ( $i = 0; $i < count($eventCounts); $i++ ) {
|
||||
$eventCounts[$i]['total'] += $monitor['EventCount'.$i];
|
||||
}
|
||||
$zoneCount += $monitor['ZoneCount'];
|
||||
}
|
||||
|
||||
$versionClass = (ZM_DYN_DB_VERSION&&(ZM_DYN_DB_VERSION!=ZM_VERSION))?'errorText':'';
|
||||
|
||||
>>>>>>> dragndrop_monitor_sorting
|
||||
$left_columns = 3;
|
||||
if ( count($servers) ) $left_columns += 1;
|
||||
if ( ZM_WEB_ID_ON_CONSOLE ) $left_columns += 1;
|
||||
|
@ -124,11 +189,56 @@ xhtmlHeaders( __FILE__, translate('Console') );
|
|||
<form name="monitorForm" method="get" action="<?php echo $_SERVER['PHP_SELF'] ?>">
|
||||
<input type="hidden" name="view" value="<?php echo $view ?>"/>
|
||||
<input type="hidden" name="action" value=""/>
|
||||
<<<<<<< HEAD
|
||||
|
||||
<?php echo $navbar ?>
|
||||
|
||||
<div class="container-fluid">
|
||||
<table class="table table-striped table-hover table-condensed">
|
||||
=======
|
||||
<div id="header">
|
||||
<h3 id="systemTime"><?php echo preg_match( '/%/', DATE_FMT_CONSOLE_LONG )?strftime( DATE_FMT_CONSOLE_LONG ):date( DATE_FMT_CONSOLE_LONG ) ?></h3>
|
||||
<h3 id="systemStats"><?php echo translate('Load') ?>: <?php echo getLoad() ?> - <?php echo translate('Disk') ?>: <?php echo getDiskPercent() ?>% - <?php echo ZM_PATH_MAP ?>: <?php echo getDiskPercent(ZM_PATH_MAP) ?>%</h3>
|
||||
<h2 id="title"><a href="http://www.zoneminder.com" target="ZoneMinder">ZoneMinder</a> <?php echo translate('Console') ?> - <?php echo makePopupLink( '?view=state', 'zmState', 'state', $status, canEdit( 'System' ) ) ?> - <?php echo $run_state ?> <?php echo makePopupLink( '?view=version', 'zmVersion', 'version', '<span class="'.$versionClass.'">v'.ZM_VERSION.'</span>', canEdit( 'System' ) ) ?></h2>
|
||||
<div class="clear"></div>
|
||||
<h3 id="development"><center><?php echo ZM_WEB_CONSOLE_BANNER ?></center></h3>
|
||||
<div id="monitorSummary"><?php echo makePopupLink( '?view=groups', 'zmGroups', 'groups', sprintf( $CLANG['MonitorCount'], count($displayMonitors), zmVlang( $VLANG['Monitor'], count($displayMonitors) ) ).($group?' ('.$group['Name'].')':''), canView( 'Groups' ) ); ?></div>
|
||||
<?php
|
||||
if ( ZM_OPT_X10 && canView( 'Devices' ) ) {
|
||||
?>
|
||||
<div id="devices"><?php echo makePopupLink( '?view=devices', 'zmDevices', 'devices', translate('Devices') ) ?></div>
|
||||
<?php
|
||||
}
|
||||
if ( canView( 'System' ) ) {
|
||||
?>
|
||||
<div id="options"><?php echo makePopupLink( '?view=options', 'zmOptions', 'options', translate('Options') ) ?><?php if ( logToDatabase() > Logger::NOLOG ) { ?> / <?php echo makePopupLink( '?view=log', 'zmLog', 'log', '<span class="'.logState().'">'.translate('Log').'</span>' ) ?><?php } ?></div>
|
||||
<?php
|
||||
}
|
||||
if ( canView( 'Stream' ) && $cycleCount > 1 ) {
|
||||
$cycleGroup = isset($_COOKIE['zmGroup'])?$_COOKIE['zmGroup']:0;
|
||||
?>
|
||||
<div id="cycleMontage">
|
||||
<?php echo makePopupLink( '?view=cycle&group='.$cycleGroup, 'zmCycle'.$cycleGroup, array( 'cycle', $cycleWidth, $cycleHeight ), translate('Cycle'), $running ) ?> /
|
||||
<?php echo makePopupLink( '?view=montage&group='.$cycleGroup, 'zmMontage'.$cycleGroup, 'montage', translate('Montage'), $running ) ?> /
|
||||
<?php echo makePopupLink( '?view=montagereview&group='.$cycleGroup, 'zmMontage'.$cycleGroup, 'montagereview', translate('Montage Review'), $running ) ?>
|
||||
</div>
|
||||
<?php
|
||||
} else {
|
||||
?>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<h3 id="loginBandwidth"><?php
|
||||
if ( ZM_OPT_USE_AUTH ) {
|
||||
?><?php echo translate('LoggedInAs') ?> <?php echo makePopupLink( '?view=logout', 'zmLogout', 'logout', $user['Username'], (ZM_AUTH_TYPE == "builtin") ) ?>, <?php echo strtolower( translate('ConfiguredFor') ) ?><?php
|
||||
} else {
|
||||
?><?php echo translate('ConfiguredFor') ?><?php
|
||||
}
|
||||
?> <?php echo makePopupLink( '?view=bandwidth', 'zmBandwidth', 'bandwidth', $bwArray[$_COOKIE['zmBandwidth']], ($user && $user['MaxBandwidth'] != 'low' ) ) ?> <?php echo translate('BandwidthHead') ?></h3>
|
||||
</div>
|
||||
<div id="content">
|
||||
<table id="consoleTable" cellspacing="0">
|
||||
>>>>>>> dragndrop_monitor_sorting
|
||||
<thead>
|
||||
<tr>
|
||||
<?php if ( ZM_WEB_ID_ON_CONSOLE ) { ?>
|
||||
|
@ -140,6 +250,7 @@ xhtmlHeaders( __FILE__, translate('Console') );
|
|||
<th class="colServer"><?php echo translate('Server') ?></th>
|
||||
<?php } ?>
|
||||
<th class="colSource"><?php echo translate('Source') ?></th>
|
||||
<<<<<<< HEAD
|
||||
<?php if ( $show_storage_areas ) { ?>
|
||||
<th class="colStorage"><?php echo translate('Storage') ?></th>
|
||||
<?php } ?>
|
||||
|
@ -148,6 +259,16 @@ xhtmlHeaders( __FILE__, translate('Console') );
|
|||
<?php } ?>
|
||||
<th class="colZones"><a href="<?php echo $_SERVER['PHP_SELF'] ?>?view=zones_overview"><?php echo translate('Zones') ?></a></th>
|
||||
<?php if ( canEdit('Monitors') ) { ?>
|
||||
=======
|
||||
<?php
|
||||
for ( $i = 0; $i < count($eventCounts); $i++ ) {
|
||||
?>
|
||||
<th class="colEvents"><?php echo $eventCounts[$i]['title'] ?></th>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<th class="colZones"><?php echo translate('Zones') ?></th>
|
||||
>>>>>>> dragndrop_monitor_sorting
|
||||
<th class="colMark"><?php echo translate('Mark') ?></th>
|
||||
<?php } ?>
|
||||
</tr>
|
||||
|
@ -155,6 +276,7 @@ xhtmlHeaders( __FILE__, translate('Console') );
|
|||
<tfoot>
|
||||
<tr>
|
||||
<td class="colLeftButtons" colspan="<?php echo $left_columns ?>">
|
||||
<<<<<<< HEAD
|
||||
<input type="button" class="btn btn-primary" value="<?php echo translate('Refresh') ?>" onclick="location.reload(true);"/>
|
||||
<input type="button" class="btn btn-primary" name="addBtn" value="<?php echo translate('AddNewMonitor') ?>" onclick="addMonitor( this )"/>
|
||||
<!-- <?php echo makePopupButton( '?view=monitor', 'zmMonitor0', 'monitor', translate('AddNewMonitor'), (canEdit( 'Monitors' ) && !$user['MonitorIds']) ) ?> -->
|
||||
|
@ -164,28 +286,49 @@ xhtmlHeaders( __FILE__, translate('Console') );
|
|||
</td>
|
||||
<?php for ( $i = 0; $i < count($eventCounts); $i++ ) {
|
||||
parseFilter( $eventCounts[$i]['filter'] );
|
||||
=======
|
||||
<input type="button" value="<?php echo translate('Refresh') ?>" onclick="location.reload(true);"/>
|
||||
<input type="button" name="addBtn" value="<?php echo translate('AddNewMonitor') ?>" onclick="addMonitor( this )"/>
|
||||
<!-- <?php echo makePopupButton( '?view=monitor', 'zmMonitor0', 'monitor', translate('AddNewMonitor'), (canEdit( 'Monitors' ) && !$user['MonitorIds']) ) ?> -->
|
||||
<?php echo makePopupButton( '?view=filter&filter[terms][0][attr]=DateTime&filter[terms][0][op]=%3c&filter[terms][0][val]=now', 'zmFilter', 'filter', translate('Filters'), canView( 'Events' ) ) ?>
|
||||
<input type="button" name="editBtn" value="<?php echo translate('Edit') ?>" onclick="editMonitor( this )" disabled="disabled"/>
|
||||
<input type="button" name="deleteBtn" value="<?php echo translate('Delete') ?>" onclick="deleteMonitor( this )" disabled="disabled"/>
|
||||
</td>
|
||||
<?php
|
||||
for ( $i = 0; $i < count($eventCounts); $i++ ) {
|
||||
parseFilter( $eventCounts[$i]['filter'] );
|
||||
>>>>>>> dragndrop_monitor_sorting
|
||||
?>
|
||||
<td class="colEvents"><?php echo makePopupLink( '?view='.$eventsView.'&page=1'.$eventCounts[$i]['filter']['query'], $eventsWindow, $eventsView, $eventCounts[$i]['total'], canView( 'Events' ) ) ?></td>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<td class="colZones"><?php echo $zoneCount ?></td>
|
||||
<<<<<<< HEAD
|
||||
<?php if ( canEdit('Monitors') ) { ?>
|
||||
<td class="colMark"></td>
|
||||
<?php } ?>
|
||||
=======
|
||||
<td class="colMark"></td>
|
||||
>>>>>>> dragndrop_monitor_sorting
|
||||
</tr>
|
||||
</tfoot>
|
||||
<tbody id="consoleTableBody">
|
||||
<?php
|
||||
<<<<<<< HEAD
|
||||
for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) {
|
||||
$monitor = $displayMonitors[$monitor_i];
|
||||
?>
|
||||
<tr id="<?php echo 'monitor_id-'.$monitor['Id'] ?>" title="<?php echo $monitor['Id'] ?>">
|
||||
=======
|
||||
foreach( $displayMonitors as $monitor ) {
|
||||
?>
|
||||
<tr id="<?php echo 'monitor_id-'.$monitor['Id'] ?>">
|
||||
>>>>>>> dragndrop_monitor_sorting
|
||||
<?php
|
||||
if ( !$monitor['zmc'] )
|
||||
if ( !$monitor['zmc'] ) {
|
||||
$dclass = "errorText";
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// https://github.com/ZoneMinder/ZoneMinder/issues/1082
|
||||
if ( !$monitor['zma'] && $monitor['Function']!='Monitor' )
|
||||
$dclass = "warnText";
|
||||
|
@ -262,13 +405,4 @@ if ( canEdit('System') ) {
|
|||
}
|
||||
?>
|
||||
</body>
|
||||
<script>
|
||||
$j( function() {
|
||||
$j( "#consoleTableBody" ).sortable({
|
||||
handle: ".glyphicon-sort",
|
||||
update: applySort,
|
||||
axis:'Y' } );
|
||||
$j( "#consoleTableBody" ).disableSelection();
|
||||
} );
|
||||
</script>
|
||||
</html>
|
||||
|
|
|
@ -74,6 +74,15 @@ function initPage() {
|
|||
createPopup( '?view=version', 'zmVersion', 'version' );
|
||||
if ( showDonatePopup )
|
||||
createPopup( '?view=donate', 'zmDonate', 'donate' );
|
||||
|
||||
// Makes table sortable
|
||||
$j( function() {
|
||||
$j( "#consoleTableBody" ).sortable({
|
||||
handle: ".glyphicon-sort",
|
||||
update: applySort,
|
||||
axis:'Y' } );
|
||||
$j( "#consoleTableBody" ).disableSelection();
|
||||
} );
|
||||
}
|
||||
|
||||
function applySort(event, ui) {
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
//
|
||||
|
||||
require_once( 'includes/Server.php');
|
||||
require_once( 'includes/Storage.php');
|
||||
|
||||
if ( !canView( 'Monitors' ) ) {
|
||||
$view = "error";
|
||||
|
@ -29,7 +28,6 @@ if ( !canView( 'Monitors' ) ) {
|
|||
$tabs = array();
|
||||
$tabs["general"] = translate('General');
|
||||
$tabs["source"] = translate('Source');
|
||||
$tabs["storage"] = translate('Storage');
|
||||
$tabs["timestamp"] = translate('Timestamp');
|
||||
$tabs["buffers"] = translate('Buffers');
|
||||
if ( ZM_OPT_CONTROL && canView( 'Control' ) )
|
||||
|
@ -137,7 +135,6 @@ if ( ! empty($_REQUEST['mid']) ) {
|
|||
'V4LMultiBuffer' => '',
|
||||
'V4LCapturesPerFrame' => 1,
|
||||
'ServerId' => $Server['Id'],
|
||||
'StorageId' => '0',
|
||||
) );
|
||||
} # end if $_REQUEST['dupID']
|
||||
} # end if $_REQUEST['mid']
|
||||
|
@ -519,7 +516,6 @@ if ( $tab != 'general' ) {
|
|||
?>
|
||||
<input type="hidden" name="newMonitor[Name]" value="<?php echo validHtmlStr($monitor->Name) ?>"/>
|
||||
<input type="hidden" name="newMonitor[ServerId]" value="<?php echo validHtmlStr($monitor->ServerId() ) ?>"/>
|
||||
<input type="hidden" name="newMonitor[StorageId]" value="<?= validHtmlStr($monitor->StorageId() ) ?>"/>
|
||||
<input type="hidden" name="newMonitor[Type]" value="<?php echo validHtmlStr($monitor->Type) ?>"/>
|
||||
<input type="hidden" name="newMonitor[Function]" value="<?php echo validHtmlStr($monitor->Function) ?>"/>
|
||||
<input type="hidden" name="newMonitor[Enabled]" value="<?php echo validHtmlStr($monitor->Enabled) ?>"/>
|
||||
|
@ -682,17 +678,6 @@ switch ( $tab )
|
|||
$servers[$server_obj->Id()] = $server_obj->Name();
|
||||
}
|
||||
echo htmlSelect( "newMonitor[ServerId]", $servers, $monitor->ServerId() );
|
||||
?>
|
||||
</td></tr>
|
||||
<tr><td><?php echo translate('StorageArea') ?></td><td>
|
||||
<?php
|
||||
$storage_areas = array(0=>'Default');
|
||||
$result = dbQuery( 'SELECT * FROM Storage ORDER BY Name');
|
||||
$results = $result->fetchALL(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'Storage' );
|
||||
foreach ( $results as $row => $storage_obj ) {
|
||||
$storage_areas[$storage_obj->Id] = $storage_obj->Name();
|
||||
}
|
||||
echo htmlSelect( "newMonitor[StorageId]", $storage_areas, $monitor->StorageId() );
|
||||
?>
|
||||
</td></tr>
|
||||
<tr><td><?php echo translate('SourceType') ?></td><td><?php echo htmlSelect( "newMonitor[Type]", $sourceTypes, $monitor->Type() ); ?></td></tr>
|
||||
|
|
Loading…
Reference in New Issue