Merge branch 'master' into storageareas

This commit is contained in:
Isaac Connor 2017-05-23 15:17:46 -04:00
commit a515041e14
16 changed files with 918 additions and 934 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -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
@ -196,7 +196,6 @@ Event::Event( Monitor *p_monitor, struct timeval p_start_time, const std::string
}
if ( videowriter != NULL ) {
/* Open the video stream */
int nRet = videowriter->Open();
if(nRet != 0) {
@ -207,6 +206,7 @@ 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 ) {
@ -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;

View File

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

View File

@ -48,16 +48,14 @@ RemoteCamera::RemoteCamera(
path = '/'+path;
}
RemoteCamera::~RemoteCamera()
{
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) );
}
}

View File

@ -31,8 +31,7 @@
// Class representing 'http' cameras, i.e. those which are
// accessed over a network connection using http
//
class RemoteCameraHttp : public RemoteCamera
{
class RemoteCameraHttp : public RemoteCamera {
protected:
std::string request;
struct timeval timeout;

View File

@ -45,8 +45,7 @@ RemoteCameraRtsp::RemoteCameraRtsp( unsigned int p_monitor_id, const std::string
else
Fatal( "Unrecognised method '%s' when creating RTSP camera %d", p_method.c_str(), monitor_id );
if ( capture )
{
if ( capture ) {
Initialise();
}
@ -76,36 +75,30 @@ RemoteCameraRtsp::RemoteCameraRtsp( unsigned int p_monitor_id, const std::string
} else {
Panic("Unexpected colours: %d",colours);
}
} // end RemoteCameraRtsp::RemoteCameraRtsp(...)
}
RemoteCameraRtsp::~RemoteCameraRtsp()
{
RemoteCameraRtsp::~RemoteCameraRtsp() {
av_frame_free( &mFrame );
av_frame_free( &mRawFrame );
#if HAVE_LIBSWSCALE
if ( mConvertContext )
{
if ( mConvertContext ) {
sws_freeContext( mConvertContext );
mConvertContext = NULL;
}
#endif
if ( mCodecContext )
{
if ( mCodecContext ) {
avcodec_close( mCodecContext );
mCodecContext = NULL; // Freed by avformat_free_context in the destructor of RtspThread class
}
if ( capture )
{
if ( capture ) {
Terminate();
}
}
void RemoteCameraRtsp::Initialise()
{
void RemoteCameraRtsp::Initialise() {
RemoteCamera::Initialise();
int max_size = width*height*colours;
@ -124,13 +117,11 @@ void RemoteCameraRtsp::Initialise()
Connect();
}
void RemoteCameraRtsp::Terminate()
{
void RemoteCameraRtsp::Terminate() {
Disconnect();
}
int RemoteCameraRtsp::Connect()
{
int RemoteCameraRtsp::Connect() {
rtspThread = new RtspThread( monitor_id, method, protocol, host, port, path, auth, rtsp_describe );
rtspThread->start();
@ -138,10 +129,8 @@ int RemoteCameraRtsp::Connect()
return( 0 );
}
int RemoteCameraRtsp::Disconnect()
{
if ( rtspThread )
{
int RemoteCameraRtsp::Disconnect() {
if ( rtspThread ) {
rtspThread->stop();
rtspThread->join();
delete rtspThread;
@ -150,11 +139,9 @@ int RemoteCameraRtsp::Disconnect()
return( 0 );
}
int RemoteCameraRtsp::PrimeCapture()
{
int RemoteCameraRtsp::PrimeCapture() {
Debug( 2, "Waiting for sources" );
for ( int i = 0; i < 100 && !rtspThread->hasSources(); i++ )
{
for ( int i = 0; i < 100 && !rtspThread->hasSources(); i++ ) {
usleep( 100000 );
}
if ( !rtspThread->hasSources() )
@ -265,8 +252,7 @@ int RemoteCameraRtsp::PrimeCapture()
int RemoteCameraRtsp::PreCapture() {
if ( !rtspThread->isRunning() )
return( -1 );
if ( !rtspThread->hasSources() )
{
if ( !rtspThread->hasSources() ) {
Error( "Cannot precapture, no RTP sources" );
return( -1 );
}
@ -303,20 +289,15 @@ int RemoteCameraRtsp::Capture( Image &image ) {
int nalType = (buffer.head()[3] & 0x1f);
// SPS The SPS NAL unit contains parameters that apply to a series of consecutive coded video pictures
if(nalType == 7)
{
if(nalType == 7) {
lastSps = buffer;
continue;
}
} else if(nalType == 8) {
// PPS The PPS NAL unit contains parameters that apply to the decoding of one or more individual pictures inside a coded video sequence
else if(nalType == 8)
{
lastPps = buffer;
continue;
}
} else if(nalType == 5) {
// IDR
else if(nalType == 5)
{
buffer += lastSps;
buffer += lastPps;
}
@ -392,7 +373,6 @@ int RemoteCameraRtsp::CaptureAndRecord(Image &image, timeval recording, char* ev
uint8_t* directbuffer;
int frameComplete = false;
while ( true ) {
// WHY Are we clearing it? Might be something good in it.
@ -450,14 +430,12 @@ int RemoteCameraRtsp::CaptureAndRecord(Image &image, timeval recording, char* ev
if(nalType == 7) {
lastSps = buffer;
continue;
}
} else if(nalType == 8) {
// PPS
else if(nalType == 8) {
lastPps = buffer;
continue;
}
} else if(nalType == 5) {
// IDR
else if(nalType == 5) {
buffer += lastSps;
buffer += lastPps;
}

View File

@ -70,7 +70,11 @@ X264MP4Writer::X264MP4Writer(const char* p_path, const unsigned int p_width, con
/* Calculate the image sizes. We will need this for parameter checking */
zm_imgsize = colours * width * height;
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
codec_imgsize = av_image_get_buffer_size( codec_pf, width, height, 1 );
#else
codec_imgsize = avpicture_get_size( codec_pf, width, height);
#endif
if(!codec_imgsize) {
Error("Failed calculating codec pixel format image size");
}

View File

@ -23,7 +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;
@ -47,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;
@ -89,14 +107,15 @@ void Zone::Setup( Monitor *p_monitor, int p_id, const char *p_label, ZoneType p_
}
}
// 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);
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() {
delete[] label;
@ -112,8 +131,7 @@ void Zone::RecordStats( const Event *event ) {
Error( "Can't insert event stats: %s", mysql_error( &dbconn ) );
exit( mysql_errno( &dbconn ) );
}
}
} // end void Zone::RecordStats( const Event *event )
bool Zone::CheckOverloadCount() {
Info("Overloaded count: %d, Overloaded frames: %d", overload_count, overload_frames);
@ -124,40 +142,40 @@ bool Zone::CheckOverloadCount() {
return( false );
}
return true;
}
} // end bool Zone::CheckOverloadCount()
void Zone::SetScore(unsigned int nScore) {
score = nScore;
}
} // end void Zone::SetScore(unsigned int nScore)
void Zone::SetAlarmImage(const Image* srcImage) {
delete image;
image = new Image(*srcImage);
}
} // end void Zone::SetAlarmImage( const Image* srcImage )
int Zone::GetOverloadCount() {
return overload_count;
}
} // end int Zone::GetOverloadCount()
void Zone::SetOverloadCount(int nOverCount) {
overload_count = nOverCount;
}
} // end void Zone::SetOverloadCount(int nOverCount )
int Zone::GetOverloadFrames() {
return overload_frames;
}
} // end int Zone::GetOverloadFrames
int Zone::GetExtendAlarmCount() {
return extend_alarm_count;
}
} // end int Zone::GetExtendAlarmCount()
void Zone::SetExtendAlarmCount(int nExtendAlarmCount) {
extend_alarm_count = nExtendAlarmCount;
}
} // end void Zone::SetExtendAlarmCount( int nExtendAlarmCount )
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 );
@ -167,7 +185,7 @@ bool Zone::CheckExtendAlarmCount() {
return( true );
}
return false;
}
} // end bool Zone::CheckExtendAlarmCount
bool Zone::CheckAlarms( const Image *delta_image ) {
ResetStats();
@ -204,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 {
@ -217,7 +232,7 @@ bool Zone::CheckAlarms( const 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-%d.jpg", storage->Path(), monitor->Id(), id, 1 );
snprintf( diag_path, sizeof(diag_path), "%s/%s/diag-%d-%d.jpg", config.dir_events, monitor->Name(), id, 1 );
}
diff_image->WriteJpeg( diag_path );
}
@ -299,7 +314,7 @@ bool Zone::CheckAlarms( const 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-%d.jpg", storage->Path(), monitor->Id(), id, 2 );
snprintf( diag_path, sizeof(diag_path), "%s/%d/diag-%d-%d.jpg", config.dir_events, monitor->Id(), id, 2 );
}
diff_image->WriteJpeg( diag_path );
}
@ -509,7 +524,7 @@ bool Zone::CheckAlarms( const 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-%d.jpg", storage->Path(), monitor->Id(), id, 3 );
snprintf( diag_path, sizeof(diag_path), "%s/%d/diag-%d-%d.jpg", config.dir_events, monitor->Id(), id, 3 );
}
diff_image->WriteJpeg( diag_path );
}
@ -556,7 +571,7 @@ bool Zone::CheckAlarms( const 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-%d.jpg", storage->Path(), monitor->Id(), id, 4 );
snprintf( diag_path, sizeof(diag_path), "%s/%d/diag-%d-%d.jpg", config.dir_events, monitor->Id(), id, 4 );
}
diff_image->WriteJpeg( diag_path );
}
@ -585,6 +600,7 @@ 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++ ) {
BlobStats *bs = &blob_stats[i];
if ( bs->count ) {
@ -614,8 +630,8 @@ 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;
}
}
} // 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);
@ -692,7 +708,8 @@ bool Zone::CheckAlarms( const Image *delta_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 );
}
@ -804,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 ) ) {
@ -823,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++;
@ -875,19 +890,17 @@ 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 );
}
@ -906,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 );

View File

@ -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'];
}
}
?>

View File

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