diff --git a/db/zmalter-1.21.3.sql b/db/zmalter-1.21.3.sql index f5b69bfa9..db76302c4 100644 --- a/db/zmalter-1.21.3.sql +++ b/db/zmalter-1.21.3.sql @@ -7,6 +7,7 @@ alter table Monitors add column Sequence smallint unsigned; alter table Monitors modify column Device tinytext; update Monitors set Device = concat( "/dev/video", Device ); update Monitors set Device = NULL where Type = "Remote"; +alter table Monitors modify column Type enum('Local','Remote','File') NOT NULL default 'Local'; alter table Events add column Height smallint(5) unsigned not null default '0' after EndTime; alter table Events add column Width smallint(5) unsigned not null default '0' after EndTime; -- diff --git a/src/Makefile.am b/src/Makefile.am index cbfc8ac6b..be103b568 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -28,6 +28,7 @@ zm_SOURCES = \ zm_camera.cpp \ zm_local_camera.cpp \ zm_remote_camera.cpp \ + zm_file_camera.cpp \ zm_monitor.cpp \ zm_user.cpp \ zm_mpeg.cpp \ @@ -59,6 +60,7 @@ noinst_HEADERS = \ zm_camera.h \ zm_local_camera.h \ zm_remote_camera.h \ + zm_file_camera.h \ zm_monitor.h \ zm_user.h \ zm_font.h \ diff --git a/src/zm_camera.h b/src/zm_camera.h index 4d89e30c3..da2c9eb92 100644 --- a/src/zm_camera.h +++ b/src/zm_camera.h @@ -33,7 +33,7 @@ class Camera { protected: - typedef enum { LOCAL, REMOTE } SourceType; + typedef enum { LOCAL, REMOTE, FILE } SourceType; SourceType type; unsigned int width; @@ -53,6 +53,7 @@ public: SourceType Type() const { return( type ); } bool IsLocal() const { return( type == LOCAL ); } bool IsRemote() const { return( type == REMOTE ); } + bool IsFile() const { return( type == FILE ); } unsigned int Width() const { return( width ); } unsigned int Height() const { return( height ); } unsigned int Palette() const { return( palette ); } diff --git a/src/zm_file_camera.cpp b/src/zm_file_camera.cpp new file mode 100644 index 000000000..d91a1e2b4 --- /dev/null +++ b/src/zm_file_camera.cpp @@ -0,0 +1,86 @@ +// +// ZoneMinder File Camera Class Implementation, $Date$, $Revision$ +// Copyright (C) 2003, 2004, 2005 Philip Coombes +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "zm.h" +#include "zm_file_camera.h" + +FileCamera::FileCamera( const char *p_path, int p_width, int p_height, int p_palette, int p_brightness, int p_contrast, int p_hue, int p_colour, bool p_capture ) : Camera( FILE, p_width, p_height, p_palette, p_brightness, p_contrast, p_hue, p_colour, p_capture ) +{ + memcpy( path, p_path, sizeof(path) ); + if ( capture ) + { + Initialise(); + } +} + +FileCamera::~FileCamera() +{ + if ( capture ) + { + Terminate(); + } +} + +void FileCamera::Initialise() +{ + if ( !path[0] ) + { + Error(( "No path specified for file image" )); + exit( -1 ); + } +} + +void FileCamera::Terminate() +{ +} + +int FileCamera::PreCapture() +{ + struct stat statbuf; + if ( stat( path, &statbuf ) < 0 ) + { + Error(( "Can't stat %s: %s", path, strerror(errno) )); + return( -1 ); + } + + while ( (time( 0 ) - statbuf.st_mtime) < 1 ) + { + usleep( 100000 ); + } + return( 0 ); +} + +int FileCamera::PostCapture( Image &image ) +{ + return( image.ReadJpeg( path )?0:-1 ); +} diff --git a/src/zm_file_camera.h b/src/zm_file_camera.h new file mode 100644 index 000000000..9b3b2b430 --- /dev/null +++ b/src/zm_file_camera.h @@ -0,0 +1,48 @@ +// +// ZoneMinder File Camera Class Interface, $Date$, $Revision$ +// Copyright (C) 2003, 2004, 2005 Philip Coombes +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// + +#ifndef ZM_FILE_CAMERA_H +#define ZM_FILE_CAMERA_H + +#include "zm_camera.h" +#include "zm_buffer.h" +#include "zm_regexp.h" + +// +// Class representing 'file' cameras, i.e. those which are +// accessed over a network connection. +// +class FileCamera : public Camera +{ +protected: + char path[PATH_MAX]; + +public: + FileCamera( const char *p_path, int p_width, int p_height, int p_palette, int p_brightness, int p_contrast, int p_hue, int p_colour, bool p_capture=true ); + ~FileCamera(); + + const char *Path() const { return( path ); } + + void Initialise(); + void Terminate(); + int PreCapture(); + int PostCapture( Image &image ); +}; + +#endif // ZM_FILE_CAMERA_H diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index 79d2d18bf..65318c910 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -26,22 +26,14 @@ #include "zm_monitor.h" #include "zm_local_camera.h" #include "zm_remote_camera.h" +#include "zm_file_camera.h" Monitor::Monitor( int p_id, char *p_name, int p_function, - const char *p_device, - int p_channel, - int p_format, - int p_width, - int p_height, - int p_palette, + Camera *p_camera, int p_orientation, - int p_brightness, - int p_contrast, - int p_hue, - int p_colour, char *p_event_prefix, char *p_label_format, const Coord &p_label_coord, @@ -61,13 +53,10 @@ Monitor::Monitor( Zone *p_zones[] ) : id( p_id ), function( (Function)p_function ), - width( p_width ), - height( p_height ), + camera( p_camera ), orientation( (Orientation)p_orientation ), - brightness( p_brightness ), - contrast( p_contrast ), - hue( p_hue ), - colour( p_colour ), + width( (p_orientation==ROTATE_90||p_orientation==ROTATE_270)?p_camera->Height():p_camera->Width() ), + height( (p_orientation==ROTATE_90||p_orientation==ROTATE_270)?p_camera->Width():p_camera->Height() ), label_coord( p_label_coord ), image_buffer_count( p_image_buffer_count ), warmup_count( p_warmup_count ), @@ -80,8 +69,8 @@ Monitor::Monitor( fps_report_interval( p_fps_report_interval ), ref_blend_perc( p_ref_blend_perc ), track_motion( p_track_motion ), - image( width, height, (p_palette==VIDEO_PALETTE_GREY?1:3) ), - ref_image( width, height, (p_palette==VIDEO_PALETTE_GREY?1:3) ), + image( width, height, p_camera->Colours() ), + ref_image( width, height, p_camera->Colours() ), purpose( p_purpose ), n_zones( p_n_zones ), zones( p_zones ) @@ -92,82 +81,6 @@ Monitor::Monitor( strncpy( event_prefix, p_event_prefix, sizeof(event_prefix) ); strncpy( label_format, p_label_format, sizeof(label_format) ); - int cam_width = ((orientation==ROTATE_90||orientation==ROTATE_270)?height:width); - int cam_height = ((orientation==ROTATE_90||orientation==ROTATE_270)?width:height); - camera = new LocalCamera( p_device, p_channel, p_format, cam_width, cam_height, p_palette, p_brightness, p_contrast, p_hue, p_colour, purpose==CAPTURE ); - - Setup(); -} - -Monitor::Monitor( - int p_id, - char *p_name, - int p_function, - const char *p_host, - const char *p_port, - const char *p_path, - int p_width, - int p_height, - int p_palette, - int p_orientation, - int p_brightness, - int p_contrast, - int p_hue, - int p_colour, - char *p_event_prefix, - char *p_label_format, - const Coord &p_label_coord, - int p_image_buffer_count, - int p_warmup_count, - int p_pre_event_count, - int p_post_event_count, - int p_alarm_frame_count, - int p_section_length, - int p_frame_skip, - int p_capture_delay, - int p_fps_report_interval, - int p_ref_blend_perc, - bool p_track_motion, - Purpose p_purpose, - int p_n_zones, - Zone *p_zones[] -) : id( p_id ), - function( (Function)p_function ), - width( p_width ), - height( p_height ), - orientation( (Orientation)p_orientation ), - brightness( p_brightness ), - contrast( p_contrast ), - hue( p_hue ), - colour( p_colour ), - label_coord( p_label_coord ), - image_buffer_count( p_image_buffer_count ), - warmup_count( p_warmup_count ), - pre_event_count( p_pre_event_count ), - post_event_count( p_post_event_count ), - alarm_frame_count( p_alarm_frame_count ), - section_length( p_section_length ), - frame_skip( p_frame_skip ), - capture_delay( p_capture_delay ), - fps_report_interval( p_fps_report_interval ), - ref_blend_perc( p_ref_blend_perc ), - track_motion( p_track_motion ), - image( width, height, (p_palette==VIDEO_PALETTE_GREY?1:3) ), - ref_image( width, height, (p_palette==VIDEO_PALETTE_GREY?1:3) ), - purpose( p_purpose ), - n_zones( p_n_zones ), - zones( p_zones ) -{ - name = new char[strlen(p_name)+1]; - strcpy( name, p_name ); - - strncpy( event_prefix, p_event_prefix, sizeof(event_prefix) ); - strncpy( label_format, p_label_format, sizeof(label_format) ); - - int cam_width = ((orientation==ROTATE_90||orientation==ROTATE_270)?height:width); - int cam_height = ((orientation==ROTATE_90||orientation==ROTATE_270)?width:height); - camera = new RemoteCamera( p_host, p_port, p_path, cam_width, cam_height, p_palette, p_brightness, p_contrast, p_hue, p_colour, purpose==CAPTURE ); - Setup(); } @@ -1001,7 +914,7 @@ void Monitor::ReloadZones() DumpZoneImage(); } -int Monitor::Load( const char *device, Monitor **&monitors, Purpose purpose ) +int Monitor::LoadLocalMonitors( const char *device, Monitor **&monitors, Purpose purpose ) { static char sql[BUFSIZ]; if ( !device[0] ) @@ -1030,21 +943,38 @@ int Monitor::Load( const char *device, Monitor **&monitors, Purpose purpose ) monitors = new Monitor *[n_monitors]; for( int i = 0; MYSQL_ROW dbrow = mysql_fetch_row( result ); i++ ) { + int width = atoi(dbrow[6]); + int height = atoi(dbrow[7]); + int palette = atoi(dbrow[8]); + Orientation orientation = (Orientation)atoi(dbrow[9]); + int brightness = atoi(dbrow[10]); + int contrast = atoi(dbrow[11]); + int hue = atoi(dbrow[12]); + int colour = atoi(dbrow[13]); + + int cam_width = ((orientation==ROTATE_90||orientation==ROTATE_270)?height:width); + int cam_height = ((orientation==ROTATE_90||orientation==ROTATE_270)?width:height); + + Camera *camera = new LocalCamera( + dbrow[3], // Device + atoi(dbrow[4]), // Channel + atoi(dbrow[5]), // Format + cam_width, + cam_height, + palette, + brightness, + contrast, + hue, + colour, + purpose==CAPTURE + ); + monitors[i] = new Monitor( atoi(dbrow[0]), // Id dbrow[1], // Name atoi(dbrow[2]), // Function - dbrow[3], // Device - atoi(dbrow[4]), // Channel - atoi(dbrow[5]), // Format - atoi(dbrow[6]), // Width - atoi(dbrow[7]), // Height - atoi(dbrow[8]), // Palette - atoi(dbrow[9]), // Orientation - atoi(dbrow[10]), // Brightness - atoi(dbrow[11]), // Contrast - atoi(dbrow[12]), // Hue - atoi(dbrow[13]), // Colour + camera, + orientation, dbrow[14], // EventPrefix dbrow[15], // LabelFormat Coord( atoi(dbrow[16]), atoi(dbrow[17]) ), // LabelX, LabelY @@ -1077,7 +1007,7 @@ int Monitor::Load( const char *device, Monitor **&monitors, Purpose purpose ) return( n_monitors ); } -int Monitor::Load( const char *host, const char*port, const char *path, Monitor **&monitors, Purpose purpose ) +int Monitor::LoadRemoteMonitors( const char *host, const char*port, const char *path, Monitor **&monitors, Purpose purpose ) { static char sql[BUFSIZ]; if ( !host ) @@ -1106,21 +1036,38 @@ int Monitor::Load( const char *host, const char*port, const char *path, Monitor monitors = new Monitor *[n_monitors]; for( int i = 0; MYSQL_ROW dbrow = mysql_fetch_row( result ); i++ ) { + int width = atoi(dbrow[6]); + int height = atoi(dbrow[7]); + int palette = atoi(dbrow[8]); + Orientation orientation = (Orientation)atoi(dbrow[9]); + int brightness = atoi(dbrow[10]); + int contrast = atoi(dbrow[11]); + int hue = atoi(dbrow[12]); + int colour = atoi(dbrow[13]); + + int cam_width = ((orientation==ROTATE_90||orientation==ROTATE_270)?height:width); + int cam_height = ((orientation==ROTATE_90||orientation==ROTATE_270)?width:height); + + Camera *camera = new RemoteCamera( + dbrow[3], // Host + dbrow[4], // Port + dbrow[5], // Path + cam_width, + cam_height, + palette, + brightness, + contrast, + hue, + colour, + purpose==CAPTURE + ); + monitors[i] = new Monitor( atoi(dbrow[0]), // Id dbrow[1], // Name atoi(dbrow[2]), // Function - dbrow[3], // Host - dbrow[4], // Port - dbrow[5], // Path - atoi(dbrow[6]), // Width - atoi(dbrow[7]), // Height - atoi(dbrow[8]), // Palette + camera, atoi(dbrow[9]), // Orientation - atoi(dbrow[10]), // Brightness - atoi(dbrow[11]), // Contrast - atoi(dbrow[12]), // Hue - atoi(dbrow[13]), // Colour dbrow[14], // EventPrefix dbrow[15], // LabelFormat Coord( atoi(dbrow[16]), atoi(dbrow[17]) ), // LabelX, LabelY @@ -1153,6 +1100,97 @@ int Monitor::Load( const char *host, const char*port, const char *path, Monitor return( n_monitors ); } +int Monitor::LoadFileMonitors( const char *file, Monitor **&monitors, Purpose purpose ) +{ + static char sql[BUFSIZ]; + if ( !file[0] ) + { + strncpy( sql, "select Id, Name, Function+0, Path, Width, Height, Palette, Orientation+0, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, FPSReportInterval, RefBlendPerc, TrackMotion from Monitors where Function != 'None' and Type = 'File'", sizeof(sql) ); + } + else + { + snprintf( sql, sizeof(sql), "select Id, Name, Function+0, Path, Width, Height, Palette, Orientation+0, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, FPSReportInterval, RefBlendPerc, TrackMotion from Monitors where Function != 'None' and Type = 'File' and Path = '%s'", file ); + } + if ( mysql_query( &dbconn, sql ) ) + { + Error(( "Can't run query: %s", mysql_error( &dbconn ) )); + exit( mysql_errno( &dbconn ) ); + } + + MYSQL_RES *result = mysql_store_result( &dbconn ); + if ( !result ) + { + Error(( "Can't use query result: %s", mysql_error( &dbconn ) )); + exit( mysql_errno( &dbconn ) ); + } + int n_monitors = mysql_num_rows( result ); + Debug( 1, ( "Got %d monitors", n_monitors )); + delete[] monitors; + monitors = new Monitor *[n_monitors]; + for( int i = 0; MYSQL_ROW dbrow = mysql_fetch_row( result ); i++ ) + { + int width = atoi(dbrow[4]); + int height = atoi(dbrow[5]); + int palette = atoi(dbrow[6]); + Orientation orientation = (Orientation)atoi(dbrow[7]); + int brightness = atoi(dbrow[8]); + int contrast = atoi(dbrow[9]); + int hue = atoi(dbrow[10]); + int colour = atoi(dbrow[11]); + + int cam_width = ((orientation==ROTATE_90||orientation==ROTATE_270)?height:width); + int cam_height = ((orientation==ROTATE_90||orientation==ROTATE_270)?width:height); + + Camera *camera = new FileCamera( + dbrow[3], // File + cam_width, + cam_height, + palette, + brightness, + contrast, + hue, + colour, + purpose==CAPTURE + ); + + monitors[i] = new Monitor( + atoi(dbrow[0]), // Id + dbrow[1], // Name + atoi(dbrow[2]), // Function + camera, + atoi(dbrow[7]), // Orientation + dbrow[12], // EventPrefix + dbrow[13], // LabelFormat + Coord( atoi(dbrow[14]), atoi(dbrow[15]) ), // LabelX, LabelY + atoi(dbrow[16]), // ImageBufferCount + atoi(dbrow[17]), // WarmupCount + atoi(dbrow[18]), // PreEventCount + atoi(dbrow[19]), // PostEventCount + atoi(dbrow[20]), // AlarmFrameCount + atoi(dbrow[21]), // SectionLength + atoi(dbrow[22]), // FrameSkip + atof(dbrow[23])>0.0?int(DT_PREC_3/atof(dbrow[23])):0, // MaxFPS + atoi(dbrow[24]), // FPSReportInterval + atoi(dbrow[25]), // RefBlendPerc + atoi(dbrow[26]), // TrackMotion + purpose + ); + Zone **zones = 0; + int n_zones = Zone::Load( monitors[i], zones ); + monitors[i]->AddZones( n_zones, zones ); + Debug( 1, ( "Loaded monitor %d(%s), %d zones", atoi(dbrow[0]), dbrow[1], n_zones )); + } + 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_monitors ); +} + Monitor *Monitor::Load( int id, bool load_zones, Purpose purpose ) { static char sql[BUFSIZ]; @@ -1174,74 +1212,93 @@ Monitor *Monitor::Load( int id, bool load_zones, Purpose purpose ) Monitor *monitor = 0; for( int i = 0; MYSQL_ROW dbrow = mysql_fetch_row( result ); i++ ) { + int width = atoi(dbrow[10]); + int height = atoi(dbrow[11]); + int palette = atoi(dbrow[12]); + Orientation orientation = (Orientation)atoi(dbrow[13]); + int brightness = atoi(dbrow[14]); + int contrast = atoi(dbrow[15]); + int hue = atoi(dbrow[16]); + int colour = atoi(dbrow[17]); + + int cam_width = ((orientation==ROTATE_90||orientation==ROTATE_270)?height:width); + int cam_height = ((orientation==ROTATE_90||orientation==ROTATE_270)?width:height); + + Camera *camera = 0; if ( !strcmp( dbrow[2], "Local" ) ) { - monitor = new Monitor( - atoi(dbrow[0]), // Id - dbrow[1], // Name - atoi(dbrow[3]), // Function + camera = new LocalCamera( dbrow[4], // Device atoi(dbrow[5]), // Channel atoi(dbrow[6]), // Format - atoi(dbrow[10]), // Width - atoi(dbrow[11]), // Height - atoi(dbrow[12]), // Palette - atoi(dbrow[13]), // Orientation - atoi(dbrow[14]), // Brightness - atoi(dbrow[15]), // Contrast - atoi(dbrow[16]), // Hue - atoi(dbrow[17]), // Colour - dbrow[18], // EventPrefix - dbrow[19], // LabelFormat - Coord( atoi(dbrow[20]), atoi(dbrow[21]) ), // LabelX, LabelY - atoi(dbrow[22]), // ImageBufferCount - atoi(dbrow[23]), // WarmupCount - atoi(dbrow[24]), // PreEventCount - atoi(dbrow[25]), // PostEventCount - atoi(dbrow[26]), // AlarmFrameCount - atoi(dbrow[27]), // SectionLength - atoi(dbrow[28]), // FrameSkip - atof(dbrow[29])>0.0?int(DT_PREC_3/atof(dbrow[29])):0, // MaxFPS - atoi(dbrow[30]), // FPSReportInterval - atoi(dbrow[31]), // RefBlendPerc - atoi(dbrow[32]), // TrackMotion - purpose + cam_width, + cam_height, + palette, + brightness, + contrast, + hue, + colour, + purpose==CAPTURE + ); + } + else if ( !strcmp( dbrow[2], "Remote" ) ) + { + camera = new RemoteCamera( + dbrow[7], // Host + dbrow[8], // Port + dbrow[9], // Path + cam_width, + cam_height, + palette, + brightness, + contrast, + hue, + colour, + purpose==CAPTURE + ); + } + else if ( !strcmp( dbrow[2], "File" ) ) + { + camera = new FileCamera( + dbrow[9], // Path + cam_width, + cam_height, + palette, + brightness, + contrast, + hue, + colour, + purpose==CAPTURE ); } else { - monitor = new Monitor( - atoi(dbrow[0]), // Id - dbrow[1], // Name - atoi(dbrow[3]), // Function - dbrow[7], // Host - dbrow[8], // Port - dbrow[9], // Path - atoi(dbrow[10]), // Width - atoi(dbrow[11]), // Height - atoi(dbrow[12]), // Palette - atoi(dbrow[13]), // Orientation - atoi(dbrow[14]), // Brightness - atoi(dbrow[15]), // Contrast - atoi(dbrow[16]), // Hue - atoi(dbrow[17]), // Colour - dbrow[18], // EventPrefix - dbrow[19], // LabelFormat - Coord( atoi(dbrow[20]), atoi(dbrow[21]) ), // LabelX, LabelY - atoi(dbrow[22]), // ImageBufferCount - atoi(dbrow[23]), // WarmupCount - atoi(dbrow[24]), // PreEventCount - atoi(dbrow[25]), // PostEventCount - atoi(dbrow[26]), // AlarmFrameCount - atoi(dbrow[27]), // SectionLength - atoi(dbrow[28]), // FrameSkip - atof(dbrow[29])>0.0?int(DT_PREC_3/atof(dbrow[29])):0, // MaxFPS - atoi(dbrow[30]), // FPSReportInterval - atoi(dbrow[31]), // RefBlendPerc - atoi(dbrow[32]), // TrackMotion - purpose - ); + Error(( "Bogus monitor type '%s' for monitor %d", dbrow[2], atoi(dbrow[0]) )); + exit( -1 ); } + monitor = new Monitor( + atoi(dbrow[0]), // Id + dbrow[1], // Name + atoi(dbrow[3]), // Function + camera, + orientation, + dbrow[18], // EventPrefix + dbrow[19], // LabelFormat + Coord( atoi(dbrow[20]), atoi(dbrow[21]) ), // LabelX, LabelY + atoi(dbrow[22]), // ImageBufferCount + atoi(dbrow[23]), // WarmupCount + atoi(dbrow[24]), // PreEventCount + atoi(dbrow[25]), // PostEventCount + atoi(dbrow[26]), // AlarmFrameCount + atoi(dbrow[27]), // SectionLength + atoi(dbrow[28]), // FrameSkip + atof(dbrow[29])>0.0?int(DT_PREC_3/atof(dbrow[29])):0, // MaxFPS + atoi(dbrow[30]), // FPSReportInterval + atoi(dbrow[31]), // RefBlendPerc + atoi(dbrow[32]), // TrackMotion + purpose + ); + int n_zones = 0; if ( load_zones ) { diff --git a/src/zm_monitor.h b/src/zm_monitor.h index d3516bc0d..df63cf8e6 100644 --- a/src/zm_monitor.h +++ b/src/zm_monitor.h @@ -158,8 +158,7 @@ protected: Camera *camera; public: - Monitor( int p_id, char *p_name, int p_function, const char *p_device, int p_channel, int p_format, int p_width, int p_height, int p_palette, int p_orientation, int p_brightness, int p_contrast, int p_hue, int p_colour, char *p_event_prefix, char *p_label_format, const Coord &p_label_coord, int p_image_buffer_count, int p_warmup_count, int p_pre_event_count, int p_post_event_count, int p_alarm_frame_count, int p_section_length, int p_frame_skip, int p_capture_delay, int p_fps_report_interval, int p_ref_blend_perc, bool p_track_motion, Purpose p_purpose=QUERY, int p_n_zones=0, Zone *p_zones[]=0 ); - Monitor( int p_id, char *p_name, int p_function, const char *p_host, const char *p_port, const char *p_path, int p_width, int p_height, int p_palette, int p_orientation, int p_brightness, int p_contrast, int p_hue, int p_colour, char *p_event_prefix, char *p_label_format, const Coord &p_label_coord, int p_image_buffer_count, int p_warmup_count, int p_pre_event_count, int p_post_event_count, int p_alarm_frame_count, int p_section_length, int p_frame_skip, int p_capture_delay, int p_fps_report_interval, int p_ref_blend_perc, bool p_track_motion, Purpose p_purpose=QUERY, int p_n_zones=0, Zone *p_zones[]=0 ); + Monitor( int p_id, char *p_name, int p_function, Camera *p_camera, int p_orientation, char *p_event_prefix, char *p_label_format, const Coord &p_label_coord, int p_image_buffer_count, int p_warmup_count, int p_pre_event_count, int p_post_event_count, int p_alarm_frame_count, int p_section_length, int p_frame_skip, int p_capture_delay, int p_fps_report_interval, int p_ref_blend_perc, bool p_track_motion, Purpose p_purpose=QUERY, int p_n_zones=0, Zone *p_zones[]=0 ); ~Monitor(); void Setup(); @@ -341,8 +340,9 @@ public: unsigned int Compare( const Image &comp_image ); void ReloadZones(); - static int Load( const char *device, Monitor **&monitors, Purpose purpose=QUERY ); - static int Load( const char *host, const char*port, const char*path, Monitor **&monitors, Purpose purpose=QUERY ); + static int LoadLocalMonitors( const char *device, Monitor **&monitors, Purpose purpose=QUERY ); + static int LoadRemoteMonitors( const char *host, const char*port, const char*path, Monitor **&monitors, Purpose purpose=QUERY ); + static int LoadFileMonitors( const char *file, Monitor **&monitors, Purpose purpose=QUERY ); static Monitor *Load( int id, bool load_zones=false, Purpose purpose=QUERY ); void StreamImages( int scale=100, int maxfps=10, time_t ttl=0 ); void SingleImage( int scale=100 ); diff --git a/src/zm_remote_camera.cpp b/src/zm_remote_camera.cpp index 7439062db..c92e6ec33 100644 --- a/src/zm_remote_camera.cpp +++ b/src/zm_remote_camera.cpp @@ -1020,7 +1020,10 @@ int RemoteCamera::PostCapture( Image &image ) Disconnect(); return( -1 ); } - image.DecodeJpeg( buffer.Extract( content_length ), content_length ); + if ( !image.DecodeJpeg( buffer.Extract( content_length ), content_length ) ) + { + return( -1 ); + } return( 0 ); } diff --git a/src/zm_remote_camera.h b/src/zm_remote_camera.h index 41ccedc0b..fe89f8659 100644 --- a/src/zm_remote_camera.h +++ b/src/zm_remote_camera.h @@ -20,22 +20,7 @@ #ifndef ZM_REMOTE_CAMERA_H #define ZM_REMOTE_CAMERA_H -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include #include -//#include -//#include -//#include -//#include #include "zm_camera.h" #include "zm_buffer.h" @@ -47,9 +32,6 @@ // class RemoteCamera : public Camera { -protected: - static bool netcam_regexps; - protected: const char *host; const char *port; diff --git a/src/zmc.cpp b/src/zmc.cpp index bbb2fee09..766fc34db 100644 --- a/src/zmc.cpp +++ b/src/zmc.cpp @@ -35,11 +35,12 @@ void zmc_term_handler( int /* signal */ ) void Usage() { - fprintf( stderr, "zmc -d or -H -P -p or -m \n" ); + fprintf( stderr, "zmc -d or -H -P -p or -f or -m \n" ); fprintf( stderr, "Options:\n" ); fprintf( stderr, " -d, --device : For local cameras, device to access. E.g /dev/video0 etc\n" ); fprintf( stderr, " -H -P -p : For remote cameras\n" ); + fprintf( stderr, " -f, --file : For local images, jpg file to access.\n" ); fprintf( stderr, " -m, --monitor : For sources associated with a single monitor\n" ); fprintf( stderr, " -h, --help : This screen\n" ); exit( 0 ); @@ -51,6 +52,7 @@ int main( int argc, char *argv[] ) const char *host = ""; const char *port = ""; const char *path = ""; + const char *file = ""; int monitor_id = -1; static struct option long_options[] = { @@ -58,6 +60,7 @@ int main( int argc, char *argv[] ) {"host", 1, 0, 'H'}, {"port", 1, 0, 'P'}, {"path", 1, 0, 'p'}, + {"file", 1, 0, 'f'}, {"monitor", 1, 0, 'm'}, {"help", 0, 0, 'h'}, {0, 0, 0, 0} @@ -67,7 +70,7 @@ int main( int argc, char *argv[] ) { int option_index = 0; - int c = getopt_long (argc, argv, "d:H:P:p:m:h", long_options, &option_index); + int c = getopt_long (argc, argv, "d:H:P:p:f:m:h", long_options, &option_index); if (c == -1) { break; @@ -87,6 +90,9 @@ int main( int argc, char *argv[] ) case 'p': path = optarg; break; + case 'f': + file = optarg; + break; case 'm': monitor_id = atoi(optarg); break; @@ -109,18 +115,17 @@ int main( int argc, char *argv[] ) Usage(); } - if (( device[0] && host[0] ) - || ( device[0] && monitor_id > 0 ) - || ( monitor_id > 0 && host[0] )) + int modes = ( device[0]?1:0 + host[0]?1:0 + file[0]?1:0 + (monitor_id>0?1:0) ); + if ( modes > 1 ) { - fprintf( stderr, "Only one of device or host/port/path or monitor id allowed\n" ); + fprintf( stderr, "Only one of device, host/port/path, file or monitor id allowed\n" ); Usage(); exit( 0 ); } - if ( !device[0] && !host[0] && monitor_id <= 0 ) + if ( modes < 1 ) { - fprintf( stderr, "One of device or host/port/path or monitor id must be specified\n" ); + fprintf( stderr, "One of device, host/port/path, file or monitor id must be specified\n" ); Usage(); exit( 0 ); } @@ -135,6 +140,11 @@ int main( int argc, char *argv[] ) { snprintf( dbg_id_string, sizeof(dbg_id_string), "h%s", host ); } + else if ( file[0] ) + { + const char *slash_ptr = strrchr( file, '/' ); + snprintf( dbg_id_string, sizeof(dbg_id_string), "f%s", slash_ptr?slash_ptr+1:file ); + } else { snprintf( dbg_id_string, sizeof(dbg_id_string), "m%d", monitor_id ); @@ -148,13 +158,17 @@ int main( int argc, char *argv[] ) int n_monitors = 0; if ( device[0] ) { - n_monitors = Monitor::Load( device, monitors, Monitor::CAPTURE ); + n_monitors = Monitor::LoadLocalMonitors( device, monitors, Monitor::CAPTURE ); } else if ( host[0] ) { if ( !port ) port = "80"; - n_monitors = Monitor::Load( host, port, path, monitors, Monitor::CAPTURE ); + n_monitors = Monitor::LoadRemoteMonitors( host, port, path, monitors, Monitor::CAPTURE ); + } + else if ( file[0] ) + { + n_monitors = Monitor::LoadFileMonitors( file, monitors, Monitor::CAPTURE ); } else { diff --git a/web/zm_html_view_console.php b/web/zm_html_view_console.php index 1a0a1d1dc..b382d9946 100644 --- a/web/zm_html_view_console.php +++ b/web/zm_html_view_console.php @@ -334,8 +334,12 @@ foreach( $monitors as $monitor ) ".$monitor['Function']."", canEdit( 'Monitors' ) ) ?> ".$monitor['Device']." (".$monitor['Channel'].")", canEdit( 'Monitors' ) ) ?> - + ".preg_replace( '/^.*@/', '', $monitor['Host'] )."", canEdit( 'Monitors' ) ) ?> + +".preg_replace( '/^.*\//', '', $monitor['Path'] )."", canEdit( 'Monitors' ) ) ?> + diff --git a/web/zm_html_view_monitor.php b/web/zm_html_view_monitor.php index ad377a158..74cf0d836 100644 --- a/web/zm_html_view_monitor.php +++ b/web/zm_html_view_monitor.php @@ -105,7 +105,7 @@ if ( !isset( $new_monitor ) ) $new_x10_monitor = isset($x10_monitor)?$x10_monitor:array(); } $local_palettes = array( $zmSlangGrey=>1, "RGB24"=>4, "RGB565"=>3, "RGB555"=>6, "YUV422"=>7, "YUYV"=>8, "YUV422P"=>13, "YUV420P"=>15 ); -$remote_palettes = array( $zmSlang8BitGrey=>1, $zmSlang24BitColour=>4 ); +$remote_palettes = $file_palettes = array( $zmSlang8BitGrey=>1, $zmSlang24BitColour=>4 ); $orientations = array( $zmSlangNormal=>'0', $zmSlangRotateRight=>'90', $zmSlangInverted=>'180', $zmSlangRotateLeft=>'270', $zmSlangFlippedHori=>'hori', $zmSlangFlippedVert=>'vert' ); ?> @@ -398,7 +398,11 @@ switch ( $tab ) $zmSlangLocal, 'Remote'=>$zmSlangRemote ); + $source_types = array( + 'Local'=>$zmSlangLocal, + 'Remote'=>$zmSlangRemote, + 'File'=>$zmSlangFile + ); ?> + + + diff --git a/web/zm_lang_en_gb.php b/web/zm_lang_en_gb.php index 83cf4653b..226eece17 100644 --- a/web/zm_lang_en_gb.php +++ b/web/zm_lang_en_gb.php @@ -248,6 +248,9 @@ $zmSlangExportOptions = 'Export Options'; $zmSlangExportVideoFiles = 'Export Video Files (if present)'; $zmSlangFar = 'Far'; $zmSlangFeed = 'Feed'; +$zmSlangFile = 'File'; +$zmSlangFilePath = 'File Path'; +$zmSlangFileColours = 'File Colours'; $zmSlangFilterPx = 'Filter Px'; $zmSlangFirst = 'First'; $zmSlangFlippedHori = 'Flipped Horizontally';