Merge branch 'master' into storageareas
This commit is contained in:
commit
a515041e14
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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) );
|
||||
|
|
|
@ -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) );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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'];
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -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