Initial revision

git-svn-id: http://svn.zoneminder.com/svn/zm/trunk@2 e3e1d417-86f3-4887-817a-d78f3d33393f
This commit is contained in:
stan 2002-09-16 09:19:24 +00:00
parent fbc71c9f56
commit 945b535fca
14 changed files with 8039 additions and 0 deletions

39
Makefile Normal file
View File

@ -0,0 +1,39 @@
all: zmc zma zms zmu
FLAGS=-g -I/usr/local/include
FLAGS=-O3 -I/usr/local/include
XLIBS= -L. -lmpatrol -lbfd -liberty
XLIBS=
zmdbg.o: zmdbg.c zmdbg.h
gcc -c $(FLAGS) $<
jmemdst.o: jmemdst.c
gcc -c $(FLAGS) $<
zm.o: zm.cpp zm.h zmcfg.h zmdbg.h
g++ -c $(FLAGS) $<
zmc.o: zmc.cpp zm.h zmcfg.h zmdbg.h
g++ -c $(FLAGS) $<
zma.o: zma.cpp zm.h zmcfg.h zmdbg.h
g++ -c $(FLAGS) $<
zms.o: zms.cpp zm.h zmcfg.h zmdbg.h
g++ -c $(FLAGS) $<
zmu.o: zmu.cpp zm.h zmcfg.h zmdbg.h
g++ -c $(FLAGS) $<
zmc: zmc.o zm.o zmdbg.o jmemdst.o
g++ $(FLAGS) -Wall -o zmc zmc.o zm.o zmdbg.o jmemdst.o -L/usr/lib/mysql -lmysqlclient -lpthread -ljpeg -ldl -lz -Wl,-E $(XLIBS)
zma: zma.o zm.o zmdbg.o jmemdst.o
g++ $(FLAGS) -Wall -o zma zma.o zm.o zmdbg.o jmemdst.o -L/usr/lib/mysql -lmysqlclient -lpthread -ljpeg -ldl -lz -Wl,-E $(XLIBS)
zms: zms.o zm.o zmdbg.o jmemdst.o
g++ $(FLAGS) -Wall -o zms zms.o zm.o zmdbg.o jmemdst.o -L/usr/lib/mysql -lmysqlclient -lpthread -ljpeg -ldl -lz -Wl,-E $(XLIBS)
zmu: zmu.o zm.o zmdbg.o jmemdst.o
g++ $(FLAGS) -Wall -o zmu zmu.o zm.o zmdbg.o jmemdst.o -L/usr/lib/mysql -lmysqlclient -lpthread -ljpeg -ldl -lz -Wl,-E $(XLIBS)

3337
src/font_6x11.h Normal file

File diff suppressed because it is too large Load Diff

91
src/jinclude.h Normal file
View File

@ -0,0 +1,91 @@
/*
* jinclude.h
*
* Copyright (C) 1991-1994, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file exists to provide a single place to fix any problems with
* including the wrong system include files. (Common problems are taken
* care of by the standard jconfig symbols, but on really weird systems
* you may have to edit this file.)
*
* NOTE: this file is NOT intended to be included by applications using the
* JPEG library. Most applications need only include jpeglib.h.
*/
/* Include auto-config file to find out which system include files we need. */
#include "jconfig.h" /* auto configuration options */
#define JCONFIG_INCLUDED /* so that jpeglib.h doesn't do it again */
/*
* We need the NULL macro and size_t typedef.
* On an ANSI-conforming system it is sufficient to include <stddef.h>.
* Otherwise, we get them from <stdlib.h> or <stdio.h>; we may have to
* pull in <sys/types.h> as well.
* Note that the core JPEG library does not require <stdio.h>;
* only the default error handler and data source/destination modules do.
* But we must pull it in because of the references to FILE in jpeglib.h.
* You can remove those references if you want to compile without <stdio.h>.
*/
#ifdef HAVE_STDDEF_H
#include <stddef.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef NEED_SYS_TYPES_H
#include <sys/types.h>
#endif
#include <stdio.h>
/*
* We need memory copying and zeroing functions, plus strncpy().
* ANSI and System V implementations declare these in <string.h>.
* BSD doesn't have the mem() functions, but it does have bcopy()/bzero().
* Some systems may declare memset and memcpy in <memory.h>.
*
* NOTE: we assume the size parameters to these functions are of type size_t.
* Change the casts in these macros if not!
*/
#ifdef NEED_BSD_STRINGS
#include <strings.h>
#define MEMZERO(target,size) bzero((void *)(target), (size_t)(size))
#define MEMCOPY(dest,src,size) bcopy((const void *)(src), (void *)(dest), (size_t)(size))
#else /* not BSD, assume ANSI/SysV string lib */
#include <string.h>
#define MEMZERO(target,size) memset((void *)(target), 0, (size_t)(size))
#define MEMCOPY(dest,src,size) memcpy((void *)(dest), (const void *)(src), (size_t)(size))
#endif
/*
* In ANSI C, and indeed any rational implementation, size_t is also the
* type returned by sizeof(). However, it seems there are some irrational
* implementations out there, in which sizeof() returns an int even though
* size_t is defined as long or unsigned long. To ensure consistent results
* we always use this SIZEOF() macro in place of using sizeof() directly.
*/
#define SIZEOF(object) ((size_t) sizeof(object))
/*
* The modules that use fread() and fwrite() always invoke them through
* these macros. On some systems you may need to twiddle the argument casts.
* CAUTION: argument order is different from underlying functions!
*/
#define JFREAD(file,buf,sizeofbuf) \
((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))
#define JFWRITE(file,buf,sizeofbuf) \
((size_t) fwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))

133
src/jmemdst.c Normal file
View File

@ -0,0 +1,133 @@
/* this is not a core library module, so it doesn't define JPEG_INTERNALS */
#include "jinclude.h"
#include "jpeglib.h"
#include "jerror.h"
/* Expanded data destination object for memory */
typedef struct {
struct jpeg_destination_mgr pub; /* public fields */
JOCTET *outbuffer; /* target buffer */
int *outbuffer_size;
JOCTET *buffer; /* start of buffer */
} mem_destination_mgr;
typedef mem_destination_mgr * mem_dest_ptr;
#define OUTPUT_BUF_SIZE 4096 /* choose an efficiently fwrite'able size */
/*
* Initialize destination --- called by jpeg_start_compress
* before any data is actually written.
*/
static void
init_destination (j_compress_ptr cinfo)
{
mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
/* Allocate the output buffer --- it will be released when done with image */
dest->buffer = (JOCTET *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
OUTPUT_BUF_SIZE * SIZEOF(JOCTET));
dest->pub.next_output_byte = dest->buffer;
dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
*(dest->outbuffer_size) = 0;
}
/*
* Empty the output buffer --- called whenever buffer fills up.
*
* In typical applications, this should write the entire output buffer
* (ignoring the current state of next_output_byte & free_in_buffer),
* reset the pointer & count to the start of the buffer, and return TRUE
* indicating that the buffer has been dumped.
*
* In applications that need to be able to suspend compression due to output
* overrun, a FALSE return indicates that the buffer cannot be emptied now.
* In this situation, the compressor will return to its caller (possibly with
* an indication that it has not accepted all the supplied scanlines). The
* application should resume compression after it has made more room in the
* output buffer. Note that there are substantial restrictions on the use of
* suspension --- see the documentation.
*
* When suspending, the compressor will back up to a convenient restart point
* (typically the start of the current MCU). next_output_byte & free_in_buffer
* indicate where the restart point will be if the current call returns FALSE.
* Data beyond this point will be regenerated after resumption, so do not
* write it out when emptying the buffer externally.
*/
static boolean
empty_output_buffer (j_compress_ptr cinfo)
{
mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
memcpy( dest->outbuffer+*(dest->outbuffer_size), dest->buffer, OUTPUT_BUF_SIZE );
*(dest->outbuffer_size) += OUTPUT_BUF_SIZE;
dest->pub.next_output_byte = dest->buffer;
dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
return TRUE;
}
/*
* Terminate destination --- called by jpeg_finish_compress
* after all data has been written. Usually needs to flush buffer.
*
* NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
* application must deal with any cleanup that should happen even
* for error exit.
*/
static void
term_destination (j_compress_ptr cinfo)
{
mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;
if (datacount > 0) {
memcpy( dest->outbuffer+*(dest->outbuffer_size), dest->buffer, datacount );
*(dest->outbuffer_size) += datacount;
}
}
/*
* Prepare for output to a stdio stream.
* The caller must have already opened the stream, and is responsible
* for closing it after finishing compression.
*/
void
jpeg_mem_dest (j_compress_ptr cinfo, JOCTET *outbuffer, int *outbuffer_size )
{
mem_dest_ptr dest;
/* The destination object is made permanent so that multiple JPEG images
* can be written to the same file without re-executing jpeg_stdio_dest.
* This makes it dangerous to use this manager and a different destination
* manager serially with the same JPEG object, because their private object
* sizes may be different. Caveat programmer.
*/
if (cinfo->dest == NULL) { /* first time for this JPEG object? */
cinfo->dest = (struct jpeg_destination_mgr *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
SIZEOF(mem_destination_mgr));
}
dest = (mem_dest_ptr) cinfo->dest;
dest->pub.init_destination = init_destination;
dest->pub.empty_output_buffer = empty_output_buffer;
dest->pub.term_destination = term_destination;
dest->outbuffer = outbuffer;
dest->outbuffer_size = outbuffer_size;
}

1891
src/zm.cpp Normal file

File diff suppressed because it is too large Load Diff

623
src/zm.h Normal file
View File

@ -0,0 +1,623 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <math.h>
#include <time.h>
#include <signal.h>
#include <assert.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/shm.h>
#include <linux/videodev.h>
#include <mysql/mysql.h>
#include "font_6x11.h"
extern "C"
{
#include <jpeglib.h>
double round(double);
void jpeg_mem_dest(j_compress_ptr cinfo, JOCTET *outbuffer, int *outbuffer_size );
}
extern "C"
{
#include "zmcfg.h"
#include "zmdbg.h"
}
typedef unsigned int Rgb;
#define RED(byte) (*(byte))
#define GREEN(byte) (*(byte+1))
#define BLUE(byte) (*(byte+2))
#define WHITE 0xff
#define WHITE_R 0xff
#define WHITE_G 0xff
#define WHITE_B 0xff
#define BLACK 0x00
#define BLACK_R 0x00
#define BLACK_G 0x00
#define BLACK_B 0x00
#define RGB_WHITE (0x00ffffff)
#define RGB_BLACK (0x00000000)
#define RGB_RED (0x00ff0000)
#define RGB_GREEN (0x0000ff00)
#define RGB_BLUE (0x000000ff)
#define RGB_VAL(v,c) (((v)>>(16-((c)*8)))&0xff)
#define RGB_RED_VAL(v) (((v)>>16)&0xff)
#define RGB_GREEN_VAL(v) (((v)>>8)&0xff)
#define RGB_BLUE_VAL(v) ((v)&0xff)
extern MYSQL dbconn;
class Coord
{
private:
int x, y;
public:
inline Coord() : x(0), y(0)
{
}
inline Coord( int p_x, int p_y ) : x(p_x), y(p_y)
{
}
inline Coord( const Coord &p_coord ) : x(p_coord.x), y(p_coord.y)
{
}
inline int &X() { return( x ); }
inline const int &X() const { return( x ); }
inline int &Y() { return( y ); }
inline const int &Y() const { return( y ); }
inline static Coord Range( const Coord &coord1, const Coord &coord2 )
{
Coord result( (coord1.x-coord2.x)+1, (coord1.y-coord2.y)+1 );
return( result );
}
inline bool operator==( const Coord &coord )
{
return( x == coord.x && y == coord.y );
}
inline bool operator!=( const Coord &coord )
{
return( x != coord.x || y != coord.y );
}
inline bool operator>( const Coord &coord )
{
return( x > coord.x && y > coord.y );
}
inline bool operator>=( const Coord &coord )
{
return( !(operator<(coord)) );
}
inline bool operator<( const Coord &coord )
{
return( x < coord.x && y < coord.y );
}
inline bool operator<=( const Coord &coord )
{
return( !(operator>(coord)) );
}
inline Coord &operator+=( const Coord &coord )
{
x += coord.x;
y += coord.y;
return( *this );
}
inline Coord &operator-=( const Coord &coord )
{
x -= coord.x;
y -= coord.y;
return( *this );
}
inline friend Coord operator+( const Coord &coord1, const Coord &coord2 )
{
Coord result( coord1 );
result += coord2;
return( result );
}
inline friend Coord operator-( const Coord &coord1, const Coord &coord2 )
{
Coord result( coord1 );
result -= coord2;
return( result );
}
};
class Box
{
private:
Coord lo, hi;
Coord size;
public:
inline Box()
{
}
inline Box( int p_size ) : lo( 0, 0 ), hi ( p_size-1, p_size-1 ), size( Coord::Range( hi, lo ) )
{
}
inline Box( int p_x_size, int p_y_size ) : lo( 0, 0 ), hi ( p_x_size-1, p_y_size-1 ), size( Coord::Range( hi, lo ) )
{
}
inline Box( int lo_x, int lo_y, int hi_x, int hi_y ) : lo( lo_x, lo_y ), hi( hi_x, hi_y ), size( Coord::Range( hi, lo ) )
{
}
inline Box( const Coord &p_lo, const Coord &p_hi ) : lo( p_lo ), hi( p_hi ), size( Coord::Range( hi, lo ) )
{
}
inline const Coord &Lo() const { return( lo ); }
inline const Coord &Hi() const { return( hi ); }
inline const Coord &Size() const { return( size ); }
inline int Width() const
{
return( size.X() );
}
inline int Height() const
{
return( size.Y() );
}
inline bool Inside( const Coord &coord ) const
{
return( coord.X() >= lo.X() && coord.X() <= hi.X() && coord.Y() >= lo.Y() && coord.Y() <= hi.Y() );
}
};
class Zone
{
friend class Image;
public:
typedef enum { ACTIVE=1, INCLUSIVE, EXCLUSIVE, INACTIVE } ZoneType;
protected:
// Inputs
int id;
char *label;
ZoneType type;
Box limits;
Rgb alarm_rgb;
int alarm_threshold;
int min_alarm_pixels;
int max_alarm_pixels;
Coord filter_box;
int min_filter_pixels;
int max_filter_pixels;
int min_blob_pixels;
int max_blob_pixels;
int min_blobs;
int max_blobs;
// Outputs
bool alarmed;
int alarm_pixels;
int alarm_filter_pixels;
int alarm_blobs;
Box alarm_box;
unsigned int score;
Image *image;
protected:
void Setup( int p_id, const char *p_label, ZoneType p_type, const Box &p_limits, const Rgb p_alarm_rgb, int p_alarm_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 );
public:
Zone( int p_id, const char *p_label, ZoneType p_type, const Box &p_limits, const Rgb p_alarm_rgb, int p_alarm_threshold=15, int p_min_alarm_pixels=50, int p_max_alarm_pixels=75000, const Coord &p_filter_box=Coord( 3, 3 ), int p_min_filter_pixels=50, int p_max_filter_pixels=50000, int p_min_blob_pixels=10, int p_max_blob_pixels=0, int p_min_blobs=0, int p_max_blobs=0 )
{
Setup( p_id, p_label, p_type, p_limits, p_alarm_rgb, p_alarm_threshold, p_min_alarm_pixels, p_max_alarm_pixels, p_filter_box, p_min_filter_pixels, p_max_filter_pixels, p_min_blob_pixels, p_max_blob_pixels, p_min_blobs, p_max_blobs );
}
Zone( int p_id, const char *p_label, const Box &p_limits, const Rgb p_alarm_rgb, int p_alarm_threshold=15, int p_min_alarm_pixels=50, int p_max_alarm_pixels=75000, const Coord &p_filter_box=Coord( 3, 3 ), int p_min_filter_pixels=50, int p_max_filter_pixels=50000, int p_min_blob_pixels=10, int p_max_blob_pixels=0, int p_min_blobs=0, int p_max_blobs=0 )
{
Setup( p_id, p_label, Zone::ACTIVE, p_limits, p_alarm_rgb, p_alarm_threshold, p_min_alarm_pixels, p_max_alarm_pixels, p_filter_box, p_min_filter_pixels, p_max_filter_pixels, p_min_blob_pixels, p_max_blob_pixels, p_min_blobs, p_max_blobs );
}
Zone( int p_id, const char *p_label, const Box &p_limits )
{
Setup( p_id, p_label, Zone::INACTIVE, p_limits, RGB_BLACK, 0, 0, 0, Coord( 0, 0 ), 0, 0, 0, 0, 0, 0 );
}
public:
~Zone();
inline const char *Label() const
{
return( label );
}
inline ZoneType Type() const
{
return( type );
}
inline Image &AlarmImage() const
{
return( *image );
}
inline const Box &Limits() const { return( limits ); }
inline bool Alarmed() const
{
return( alarmed );
}
static int Load( int monitor_id, int width, int height, Zone **&zones );
};
class Camera;
class Monitor;
class Image
{
friend class Camera;
friend class Monitor;
protected:
enum { CHAR_HEIGHT=11, CHAR_WIDTH=6, CHAR_START=4 };
protected:
int width;
int height;
int colours;
int size;
JSAMPLE *buffer;
bool our_buffer;
public:
Image( const char *filename )
{
ReadJpeg( filename );
our_buffer = true;
}
Image( int p_width, int p_height, int p_colours, JSAMPLE *p_buffer=0 )
{
width = p_width;
height = p_height;
colours = p_colours;
size = width*height*colours;
if ( !p_buffer )
{
our_buffer = true;
buffer = new JSAMPLE[size];
memset( buffer, 0, size );
}
else
{
our_buffer = false;
buffer = p_buffer;
}
}
Image( const Image &p_image )
{
width = p_image.width;
height = p_image.height;
colours = p_image.colours;
size = p_image.size;
buffer = new JSAMPLE[size];
memcpy( buffer, p_image.buffer, size );
our_buffer = true;
}
~Image()
{
if ( our_buffer )
{
delete[] buffer;
}
}
inline void Assign( int p_width, int p_height, int p_colours, unsigned char *new_buffer )
{
if ( p_width != width || p_height != height || p_colours != colours )
{
width = p_width;
height = p_height;
colours = p_colours;
size = width*height*colours;
delete[] buffer;
buffer = new JSAMPLE[size];
memset( buffer, 0, size );
}
if ( colours == 1 )
{
memcpy( buffer, new_buffer, size );
}
else
{
for ( int i = 0; i < size; i += 3 )
{
buffer[i] = new_buffer[i+2];
buffer[i+1] = new_buffer[i+1];
buffer[i+2] = new_buffer[i];
}
}
}
inline Image &operator=( const unsigned char *new_buffer )
{
memcpy( buffer, new_buffer, size );
return( *this );
}
inline int Width() { return( width ); }
inline int Height() { return( height ); }
void ReadJpeg( const char *filename );
void WriteJpeg( const char *filename ) const;
void EncodeJpeg( JOCTET *outbuffer, int *outbuffer_size ) const;
void Overlay( const Image &image );
void Blend( const Image &image, double transparency=0.1 ) const;
void Blend( const Image &image, int transparency=10 ) const;
static Image *Merge( int n_images, Image *images[] );
static Image *Merge( int n_images, Image *images[], double weight );
static Image *Highlight( int n_images, Image *images[], const Rgb threshold=RGB_BLACK, const Rgb ref_colour=RGB_RED );
Image *Delta( const Image &image, bool absolute=true ) const;
unsigned int CheckAlarms( Zone *zone, const Image *delta_image ) const;
unsigned int Compare( const Image &image, int n_zones, Zone *zones[] ) const;
void Annotate( const char *text, const Coord &coord, const Rgb colour );
void Annotate( const char *text, const Coord &coord );
void Timestamp( const char *label, time_t when, const Coord &coord );
void Colourise();
void DeColourise();
};
class Camera
{
friend class Image;
protected:
int id;
char *name;
int device;
int channel;
int format;
int width;
int height;
int colours;
bool capture;
protected:
static int m_cap_frame;
static int m_sync_frame;
static video_mbuf m_vmb;
static video_mmap *m_vmm;
static int m_videohandle;
static unsigned char *m_buffer;
static int camera_count;
public:
Camera( int p_id, char *p_name, int p_device, int p_channel, int p_format, int p_width, int p_height, int p_colours, bool p_capture=true );
~Camera();
inline int Id() const
{
return( id );
}
inline char *Name() const
{
return( name );
}
static void Initialise( int device, int channel, int format, int width, int height, int colours );
void Terminate();
inline void PreCapture()
{
//Info(( "%s: Capturing image\n", id ));
if ( camera_count > 1 )
{
//Info(( "Switching\n" ));
struct video_channel vs;
vs.channel = channel;
//vs.norm = VIDEO_MODE_AUTO;
vs.norm = format;
vs.flags = 0;
vs.type = VIDEO_TYPE_CAMERA;
if(ioctl(m_videohandle, VIDIOCSCHAN, &vs))
{
Error(( "Failed to set camera source %d: %s\n", channel, strerror(errno) ));
}
}
//Info(( "MC:%d\n", m_videohandle ));
if ( ioctl(m_videohandle, VIDIOCMCAPTURE, &m_vmm[m_cap_frame]) )
{
Error(( "Capture failure for frame %d: %s\n", m_cap_frame, strerror(errno)));
}
m_cap_frame = (m_cap_frame+1)%m_vmb.frames;
}
inline unsigned char *PostCapture()
{
//Info(( "%s: Capturing image\n", id ));
if ( ioctl(m_videohandle, VIDIOCSYNC, &m_sync_frame) )
{
Error(( "Sync failure for frame %d: %s\n", m_sync_frame, strerror(errno)));
}
unsigned char *buffer = m_buffer+(m_sync_frame*m_vmb.size/m_vmb.frames);
m_sync_frame = (m_sync_frame+1)%m_vmb.frames;
return( buffer );
}
inline void PostCapture( Image &image )
{
//Info(( "%s: Capturing image\n", id ));
if ( ioctl(m_videohandle, VIDIOCSYNC, &m_sync_frame) )
{
Error(( "Sync failure for frame %d: %s\n", m_sync_frame, strerror(errno)));
}
unsigned char *buffer = m_buffer+(m_sync_frame*m_vmb.size/m_vmb.frames);
m_sync_frame = (m_sync_frame+1)%m_vmb.frames;
image.Assign( width, height, colours, buffer );
}
inline unsigned char *Capture()
{
PreCapture();
return( PostCapture() );
}
inline void Capture( Image &image )
{
PreCapture();
return( PostCapture( image ) );
}
};
class Event
{
friend class Monitor;
protected:
int id;
Monitor *monitor;
time_t start_time;
time_t end_time;
int start_frame_id;
int end_frame_id;
int frames;
int alarm_frames;
char path[256];
public:
Event( Monitor *p_monitor, time_t p_start_time );
~Event();
void AddFrame( time_t timestamp, const Image *image, const Image *alarm_frame=NULL, unsigned int score=0 );
static void StreamEvent( const char *path, int event_id, unsigned long refresh=100, FILE *fd=stdout );
};
class Monitor : public Camera
{
protected:
typedef enum
{
WARMUP_COUNT=25,
PRE_EVENT_COUNT=10,
POST_EVENT_COUNT=10,
IMAGE_BUFFER_COUNT=100,
FPS_REPORT_INTERVAL=200,
};
typedef enum
{
NONE=1,
PASSIVE,
ACTIVE
} Function;
Function function;
double fps;
Image image;
Image ref_image;
int event_count;
int image_count;
int first_alarm_count;
int last_alarm_count;
int buffer_count;
typedef enum { IDLE, ALARM, ALERT } State;
State state;
int n_zones;
Zone **zones;
Event *event;
time_t start_time;
time_t last_fps_time;
typedef struct Snapshot
{
time_t *timestamp;
Image *image;
};
Snapshot *image_buffer;
typedef struct
{
State state;
int last_write_index;
int last_read_index;
time_t *timestamps;
unsigned char *images;
} SharedImages;
SharedImages *shared_images;
public:
Monitor( int p_id, char *p_name, int p_function, int p_device, int p_channel, int p_format, int p_width, int p_height, int p_colours, bool p_capture=true, int p_n_zones=0, Zone *p_zones[]=0 );
~Monitor();
State GetState() const;
int GetImage( int index=-1 ) const;
time_t GetTimestamp( int index=-1 ) const;
unsigned int GetLastReadIndex() const;
unsigned int GetLastWriteIndex() const;
double GetFPS() const;
void CheckFunction();
void DumpZoneImage();
inline void Capture()
{
PreCapture();
PostCapture();
}
inline void PostCapture()
{
Camera::PostCapture( image );
time_t now = time( 0 );
image.Timestamp( name, now, Coord( 0, 280 ) );
int index = image_count%IMAGE_BUFFER_COUNT;
if ( index == shared_images->last_read_index )
{
Error(( "Error, buffer overrun at index %d\n", index ));
}
*(image_buffer[index].timestamp) = now;
memcpy( image_buffer[index].image->buffer, image.buffer, image.size );
//Info(( "%d: %x - %x", index, image_buffer[index].image, image_buffer[index].image->buffer ));
shared_images->last_write_index = index;
image_count++;
if ( image_count && !(image_count%FPS_REPORT_INTERVAL) )
{
fps = double(FPS_REPORT_INTERVAL)/(now-last_fps_time);
Info(( "%s: %d - Capturing at %.2f fps\n", name, image_count, fps ));
last_fps_time = now;
}
}
inline bool Ready()
{
return( function == ACTIVE && image_count > WARMUP_COUNT );
}
char *GetTimestampPath( time_t now );
void DumpImage( Image *image ) const;
void Analyse();
void Adjust( double ratio )
{
ref_image.Blend( image, 0.1 );
}
void ReloadZones();
static int Load( int device, Monitor **&monitors, bool capture=true );
static Monitor *Load( int id, bool load_zones=false );
void StreamImages( unsigned long idle=5000, unsigned long refresh=50, FILE *fd=stdout );
};

69
src/zma.cpp Normal file
View File

@ -0,0 +1,69 @@
#include "zm.h"
bool reload = false;
void hup_handler( int signal )
{
reload = true;
}
void main( int argc, const char *argv[] )
{
int device = argv[1]?atoi( argv[1] ):0;
char dbg_name_string[16];
sprintf( dbg_name_string, "zma-%d", device );
dbg_name = dbg_name_string;
DbgInit();
//umask( 0 );
if ( !mysql_init( &dbconn ) )
{
fprintf( stderr, "Can't initialise structure: %s\n", mysql_error( &dbconn ) );
exit( mysql_errno( &dbconn ) );
}
if ( !mysql_connect( &dbconn, "", ZM_DB_USERA, ZM_DB_PASSA ) )
{
fprintf( stderr, "Can't connect to server: %s\n", mysql_error( &dbconn ) );
exit( mysql_errno( &dbconn ) );
}
if ( mysql_select_db( &dbconn, ZM_DATABASE ) )
{
fprintf( stderr, "Can't select database: %s\n", mysql_error( &dbconn ) );
exit( mysql_errno( &dbconn ) );
}
Monitor **monitors = 0;
int n_monitors = Monitor::Load( device, monitors, false );
Info(( "Warming up" ));
sigset_t block_set;
sigemptyset( &block_set );
struct sigaction action, old_action;
action.sa_handler = hup_handler;
action.sa_mask = block_set;
action.sa_flags = 0;
sigaction( SIGHUP, &action, &old_action );
sigaddset( &block_set, SIGHUP );
while( 1 )
{
// Process the next image
sigprocmask( SIG_BLOCK, &block_set, 0 );
for ( int i = 0; i < n_monitors; i++ )
{
monitors[i]->Analyse();
}
sigprocmask( SIG_UNBLOCK, &block_set, 0 );
if ( reload )
{
for ( int i = 0; i < n_monitors; i++ )
{
monitors[i]->ReloadZones();
monitors[i]->CheckFunction();
}
reload = false;
}
}
}

71
src/zmc.cpp Normal file
View File

@ -0,0 +1,71 @@
#include "zm.h"
bool reload = false;
void hup_handler( int signal )
{
reload = true;
}
void main( int argc, const char *argv[] )
{
int device = argv[1]?atoi( argv[1] ):0;
char dbg_name_string[16];
sprintf( dbg_name_string, "zmc-%d", device );
dbg_name = dbg_name_string;
DbgInit();
if ( !mysql_init( &dbconn ) )
{
fprintf( stderr, "Can't initialise structure: %s\n", mysql_error( &dbconn ) );
exit( mysql_errno( &dbconn ) );
}
if ( !mysql_connect( &dbconn, "", ZM_DB_USERA, ZM_DB_PASSA ) )
{
fprintf( stderr, "Can't connect to server: %s\n", mysql_error( &dbconn ) );
exit( mysql_errno( &dbconn ) );
}
if ( mysql_select_db( &dbconn, ZM_DATABASE ) )
{
fprintf( stderr, "Can't select database: %s\n", mysql_error( &dbconn ) );
exit( mysql_errno( &dbconn ) );
}
Monitor **monitors = 0;
int n_monitors = Monitor::Load( device, monitors );
Info(( "Starting Capture" ));
sigset_t block_set;
sigemptyset( &block_set );
struct sigaction action, old_action;
action.sa_handler = hup_handler;
action.sa_mask = block_set;
action.sa_flags = 0;
sigaction( SIGHUP, &action, &old_action );
sigaddset( &block_set, SIGHUP );
if ( n_monitors == 1 )
{
monitors[0]->PreCapture();
}
while( 1 )
{
/* grab a new one */
sigprocmask( SIG_BLOCK, &block_set, 0 );
for ( int i = 0; i < n_monitors; i++ )
{
monitors[i]->PreCapture();
monitors[i]->PostCapture();
}
sigprocmask( SIG_UNBLOCK, &block_set, 0 );
if ( reload )
{
for ( int i = 0; i < n_monitors; i++ )
{
monitors[i]->CheckFunction();
}
reload = false;
}
}
}

5
src/zmcfg.h.z Normal file
View File

@ -0,0 +1,5 @@
#define ZM_DATABASE "polycam"
#define ZM_DB_USERA "zmadmin"
#define ZM_DB_PASSA "zmadminzm"
#define ZM_DB_USERB "zmuser"
#define ZM_DB_PASSB "zmuserzm"

568
src/zmdbg.c Normal file
View File

@ -0,0 +1,568 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#include <syslog.h>
#include <signal.h>
#include <stdarg.h>
#include <errno.h>
#include "zmdbg.h"
#define PRESERVE_ATTEMPTS 3
static unsigned int DbgArchive_ext = 1;
static unsigned int DbgArchive_time = 0;
static unsigned int DbgArchive_size = 0;
static unsigned long DbgArchive_sec = 0;
static unsigned long DbgArchive_cnt = 0;
static char string[4096];
static char dbg_string[4096+512];
static const char *dbg_file;
static int dbg_line;
static int dbg_code;
static char dbg_class[4];
const char *dbg_name = "";
int dbg_pid = -1;
static int dbg_switched_on = FALSE;
int dbg_level = 0;
char dbg_log[128] = "";
FILE *dbg_log_fd = (FILE *)NULL;
int dbg_print = FALSE;
int dbg_flush = FALSE;
int dbg_runtime = FALSE;
int dbg_add_log_id = FALSE;
struct timeval dbg_start;
/* support for automatic reopening of debug files on failure to open */
static int dbg_running = FALSE;
static int dbg_reopen_cnt = 10;
static time_t dbg_log_closed = 0;
static int dbg_trig_arc = FALSE;
void UsrHandler( int sig )
{
if( sig == SIGUSR1)
{
dbg_switched_on = TRUE;
if ( dbg_level < 9 )
{
dbg_level++;
}
#if 0
if ( SIGNAL( SIGUSR1,UsrHandler ) < 0 )
{
Error(( "%s(), error = %s", dbg_policy_nm[dbg_sig_policy], strerror(errno) ));
}
#endif
}
else if ( sig == SIGUSR2 )
{
if( dbg_level > -3 )
{
dbg_level--;
}
#if 0
if ( SIGNAL( SIGUSR2,UsrHandler ) < 0 )
{
Error(( "%s(), error = %s", dbg_policy_nm[dbg_sig_policy], strerror(errno) ));
}
#endif
}
Info(( "Debug Level Changed to %d", dbg_level ));
}
int GetDebugEnv( const char * const command )
{
char buffer[128];
char *env_ptr;
/* dbg_level = 0; */
/* dbg_log[0] = '\0'; */
env_ptr = getenv( "DB_PRINT" );
if ( env_ptr == (char *)NULL )
{
dbg_print = FALSE;
}
else
{
dbg_print = atoi( env_ptr );
}
env_ptr = getenv( "DB_FLUSH" );
if ( env_ptr == (char *)NULL )
{
dbg_flush = FALSE;
}
else
{
dbg_flush = atoi( env_ptr );
}
env_ptr = getenv( "DB_RUNTIME" );
if ( env_ptr == (char *)NULL )
{
dbg_runtime = FALSE;
}
else
{
dbg_runtime = atoi( env_ptr );
}
sprintf(buffer,"DLVL_%s",command);
env_ptr = getenv(buffer);
if( env_ptr != (char *)NULL )
{
dbg_level = atoi(env_ptr);
}
sprintf( buffer, "DLOG_%s", command );
env_ptr = getenv( buffer );
if ( env_ptr != (char *)NULL )
{
/* If we do not want to add a pid to the debug logs
* which is the default, and original method
*/
if ( env_ptr[strlen(env_ptr)-1] == '+' )
{
/* remove the + character from the string */
env_ptr[strlen(env_ptr)-1] = '\0';
dbg_add_log_id = TRUE;
}
if ( dbg_add_log_id == FALSE )
{
strcpy( dbg_log, env_ptr );
}
else
{
sprintf( dbg_log, "%s.%05d", env_ptr, getpid() );
}
}
env_ptr = getenv( "DB_REOPEN_TRY" );
if ( env_ptr != (char *) NULL )
{
/* This counts the number of times the DbgOutput function
* has been called when the debug logs have been closed
* before a reopen is attempted
*/
dbg_reopen_cnt = atoi(env_ptr);
if (dbg_reopen_cnt < 1)
{
dbg_reopen_cnt = 1;
}
}
return(0);
}
char *move_debug_file ( void )
{
int i;
static char new_dbg_log[200];
for ( i=0; i<PRESERVE_ATTEMPTS; i++ )
{
FILE *fd = (FILE *)NULL;
sprintf ( new_dbg_log, "%s.%d", dbg_log, DbgArchive_ext );
DbgArchive_ext ++;
if ( ( fd = fopen ( new_dbg_log, "r" ) ) == NULL )
{
fclose ( fd );
rename ( dbg_log, new_dbg_log );
return ( new_dbg_log );
}
}
return ( NULL );
}
int InitialiseDebug()
{
char *prev_file = (char*)NULL;
FILE *tmp_fp;
int status;
struct timezone tzp;
gettimeofday( &dbg_start, &tzp );
Debug(1,("Initialising Debug"));
/* Now set up the syslog stuff */
(void) openlog( dbg_name, LOG_PID|LOG_NDELAY, LOG_LOCAL1 );
string[0] = '\0';
dbg_class[0] = '\0';
dbg_pid = getpid();
dbg_log_fd = (FILE *)NULL;
if( (status = GetDebugEnv(dbg_name) ) < 0)
{
Error(("Debug Environment Error, status = %d",status));
return(DBG_ERROR);
}
/* If we have purposely set the last character in the log name to a
* tilda, rename it .....old and get ready for new debug file.
*/
if ( ( dbg_add_log_id == FALSE && dbg_log[0] ) && ( dbg_log[strlen(dbg_log)-1] == '~' ) )
{
dbg_log[strlen(dbg_log)-1] = '\0';
if ( (tmp_fp = fopen(dbg_log, "r")) != NULL )
{
char old_pth[256];
sprintf(old_pth, "%s.old", dbg_log);
rename(dbg_log, old_pth);
fclose(tmp_fp); /* should maybe fclose() before rename() ? */
}
}
if ( DbgArchive_time || DbgArchive_size )
{
/* if either of the archive parameters are set then try to archive an
* existing log file
*/
DbgArchive_sec = dbg_start.tv_sec; /* time of last archive is set to now */
DbgArchive_cnt = 0; /* running file size is set to zero */
if ( ( tmp_fp = fopen ( dbg_log, "r" ) ) != NULL )
{
fclose ( tmp_fp );
prev_file = move_debug_file ( );
}
}
if( dbg_log[0] && (dbg_log_fd = fopen(dbg_log,"w")) == (FILE *)NULL )
{
Error(("fopen() for %s, error = %s",dbg_log,strerror(errno)));
return(DBG_ERROR);
}
Info(("Debug Level = %d, Debug Log = %s",dbg_level,dbg_log));
{
struct sigaction action, old_action;
action.sa_handler = UsrHandler;
action.sa_flags = SA_RESTART;
if ( sigaction( SIGUSR1, &action, &old_action ) < 0 )
{
Error(("%s(), error = %s",sigaction,strerror(errno)));
return(DBG_ERROR);
}
if ( sigaction( SIGUSR2, &action, &old_action ) < 0)
{
Error(("%s(), error = %s",sigaction,strerror(errno)));
return(DBG_ERROR);
}
}
dbg_running = TRUE;
return(DBG_OK);
}
int DbgInit()
{
return((InitialiseDebug() == DBG_OK ? 0 : 1));
}
int TerminateDebug()
{
Debug(1,("Terminating Debug"));
fflush(dbg_log_fd);
if((fclose(dbg_log_fd)) == -1)
{
Error(("fclose(), error = %s",strerror(errno)));
return(DBG_ERROR);
}
dbg_log_fd = (FILE *)NULL;
(void) closelog();
dbg_running = FALSE;
return(DBG_OK);
}
int DbgTerm()
{
return((TerminateDebug() == DBG_OK ? 0 : 1));
}
void DbgSubtractTime( struct timeval * const tp1, struct timeval * const tp2 )
{
tp1->tv_sec -= tp2->tv_sec;
if ( tp1->tv_usec <= tp2->tv_usec )
{
tp1->tv_sec--;
tp1->tv_usec = 1000000 - (tp2->tv_usec - tp1->tv_usec);
}
else
{
tp1->tv_usec = tp1->tv_usec - tp2->tv_usec;
}
}
static int DbgArchiveNowLocal( const unsigned long secs )
{
DbgArchive_sec = secs;
DbgArchive_cnt = 0;
fflush ( dbg_log_fd );
if ( dbg_log_fd != NULL && ( fclose ( dbg_log_fd ) ) == -1 )
{
Error ( ( "Failed to archive: fclose(), error = %s", strerror ( errno ) ) );
/* clearing dbg_log_fd to make sure that we don't confused about
* this debug file */
if (dbg_log_closed == 0)
{
dbg_log_closed = time(NULL);
}
dbg_log_fd = NULL;
}
else
{
char *prev_file;
dbg_log_fd = (FILE *)NULL;
prev_file = move_debug_file ( );
if ( prev_file == (char*)NULL )
{
if ( ( dbg_log_fd = fopen ( dbg_log, "a" ) ) == (FILE *)NULL )
{
if (dbg_log_closed == 0)
{
dbg_log_closed = time(NULL);
}
return ( DBG_ERROR );
}
Error ( ( "Debug Log archive failed" ) );
}
else
{
if ( ( dbg_log_fd = fopen ( dbg_log, "w" ) ) == (FILE *)NULL )
{
if (dbg_log_closed == 0)
{
dbg_log_closed = time(NULL);
}
return ( DBG_ERROR );
}
}
Info(("Debug Level = %d, Debug Log = %s",dbg_level,dbg_log));
}
return ( DBG_OK );
}
int DbgArchiveNow ( void )
{
struct timeval tp;
struct timezone tzp;
int rtn;
gettimeofday( &tp, &tzp );
rtn = DbgArchiveNowLocal ( tp.tv_sec );
Info(("Reopening of debug logs under applications control"));
return ( rtn );
}
int DbgPrepare( const char * const file, const int line, const int code )
{
dbg_file = file;
dbg_line = line;
dbg_code = code;
switch(code)
{
case DBG_INF:
strcpy(dbg_class,"INF");
break;
case DBG_WAR:
strcpy(dbg_class,"WAR");
break;
case DBG_ERR:
strcpy(dbg_class,"ERR");
break;
case DBG_FAT:
strcpy(dbg_class,"FAT");
break;
default:
if(code > 0 && code <= 9)
{
sprintf(dbg_class,"DB%d",code);
}
else
{
Error(("Unknown Error Code %d",code));
}
break;
}
return(code);
}
int DbgOutput( const char *fstring, ... )
{
char time_string[64];
va_list arg_ptr;
int log_code;
struct timeval tp;
struct timezone tzp;
static int count = 0;
string[0] = '\0';
va_start(arg_ptr,fstring);
vsprintf(string,fstring,arg_ptr);
gettimeofday( &tp, &tzp );
/* Archive processing */
#if 0
if ( ( DbgArchive_time && ( ( tp.tv_sec - DbgArchive_sec ) > DbgArchive_time ) ) ||
( DbgArchive_size && ( DbgArchive_cnt > DbgArchive_size ) ) )
{
int rtn;
if ( ( rtn = DbgArchiveNowLocal ( tp.tv_sec ) ) != DBG_OK )
{
return ( rtn );
}
Info(("Reopening of debug triggered by debug library (MaxOpenTime=%d,MaxSize=%d", DbgArchive_time, DbgArchive_size));
}
#endif
if ( dbg_runtime )
{
DbgSubtractTime( &tp, &dbg_start );
sprintf( time_string, "%d.%03ld", tp.tv_sec, tp.tv_usec/1000 );
}
else
{
time_t the_time;
the_time = tp.tv_sec;
strftime(time_string,63,"%x %H:%M:%S",localtime(&the_time));
sprintf(&(time_string[strlen(time_string)]), ".%06ld", tp.tv_usec);
}
sprintf(dbg_string,"%s %s[%d].%s-%s/%d [%s]\n",
time_string,dbg_name,dbg_pid,
dbg_class,dbg_file,dbg_line,string);
if ( dbg_print )
{
printf("%s", dbg_string);
fflush(stdout);
}
if ( dbg_log_fd != (FILE *)NULL )
{
int cnt;
/*
* Attempt to seek to the end of the file.
* This will add about 2 micro seconds to every
* debug call. This is not considerd significant.
* Note that if it fails it fails and we don't care
* it's only to be nice to fstidy.
*/
lseek(fileno(dbg_log_fd), 0, 2);
if ( ( cnt = fprintf ( dbg_log_fd, "%s", dbg_string ) ) > 0 )
{
DbgArchive_cnt += cnt;
}
if ( dbg_flush )
{
fflush(dbg_log_fd);
}
}
else if (dbg_log_fd == NULL && dbg_running == TRUE)
{
/* in this section, debug is on because dbg_running (i.e.
* InitialiseDebug has been called and TerminateDebug has not),
* dbg_log_fd is NULL, probably from a failed close, so
* what we do is increment the count of times into DbgOutput
* function. Once this is greater than the dbg_reopen_cnt
* we try to archive (this should hopefully tidy things up a
* little, but even if it doesn't it should try reopening
* the debug log. Once it is reopened we spit out an
* extra message for information indicating the time the
* debug log got lost. Note that if we can't archive (say
* filesystem is still full) we just return as we would have
* done earlier. Also note that in the case where we've
* entered this function greater than dbg_reopen_cnt we
* reset the counter.
*/
#if 0
count++;
if (count > dbg_reopen_cnt)
{
int rtn;
count = 0;
if ( ( rtn = DbgArchiveNowLocal ( tp.tv_sec ) ) != DBG_OK )
{
return ( rtn );
}
Info(("Warning debug log closed since UTC=%d", dbg_log_closed));
dbg_log_closed = 0;
}
#endif
}
/* For Info, Warning, Errors etc we want to log them */
if ( dbg_code <= DBG_INF )
{
if ( !dbg_flush )
{
fflush(dbg_log_fd);
}
switch(dbg_code)
{
case DBG_INF:
log_code = LOG_INFO;
break;
case DBG_WAR:
log_code = LOG_WARNING;
break;
case DBG_ERR:
log_code = LOG_ERR;
break;
case DBG_FAT:
log_code = LOG_CRIT;
break;
default:
log_code = LOG_CRIT;
break;
}
log_code |= LOG_LOCAL1;
syslog( log_code, "%s [%s]", dbg_class, string );
}
va_end(arg_ptr);
if ( dbg_code == DBG_FAT )
{
exit(-1);
}
return( strlen( string ) );
}
void DbgArchive ( const unsigned int ArchiveTime, const unsigned int ArchiveSize )
{
DbgArchive_time = ArchiveTime;
DbgArchive_size = ArchiveSize;
}

128
src/zmdbg.h Normal file
View File

@ -0,0 +1,128 @@
#include <sys/types.h>
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
/* Leve 0 and below */
#define DBG_OK 0
#define DBG_SUCCESS 0
#define DBG_INFO 1
#define DBG_WARNING -1
#define DBG_ERROR -2
#define DBG_FATAL -3
#define DBG_INF 0
#define DBG_WAR -1
#define DBG_ERR -2
#define DBG_FAT -3
#ifndef DEBUG_OFF
#define DbgPrintf(code,params) {\
if (code <= dbg_level)\
{\
(void) DbgPrepare(__FILE__,__LINE__,code);\
(void) DbgOutput params;\
}\
}
#define Null(params)
#define Debug(level,params) DbgPrintf(level,params)
#define Info(params) DbgPrintf(0, params)
#define Warning(params) DbgPrintf(DBG_WAR,params)
#define Error(params) DbgPrintf(DBG_ERR,params)
#define Fatal(params) DbgPrintf(DBG_FAT,params)
#define Entrypoint(params) DbgPrintf(9,params);
#define Exitpoint(params) DbgPrintf(9,params);
#define Mark() Info(("Mark"))
#define Log() Info(("Log"))
#ifdef __GNUC__
#define Enter(level) DbgPrintf(level,("Entering %s",__PRETTY_FUNCTION__))
#define Exit(level) DbgPrintf(level,("Exiting %s",__PRETTY_FUNCTION__))
#else
#if 0
#define Enter(level) DbgPrintf(level,("Entering <unknown>"))
#define Exit(level) DbgPrintf(level,("Exiting <unknown>"))
#endif
#define Enter(level)
#define Exit(level)
#endif
#define HexDump(t,n) {if(dbg_level == 9) \
{ \
int _i; \
int _len; \
char *_s; \
_s = (t); \
_len = (n); \
for(_i = 0; _i < _len; _i++,_s++) \
{ \
if(!(_i % 16)) \
{ \
fprintf(dbg_log_fd,"\n"); \
} \
fprintf(dbg_log_fd,"0x%02x ", \
((int)*_s)&0xff); \
} \
fprintf(dbg_log_fd,"\n"); \
}}
#ifdef __cplusplus
extern "C" {
#endif
#if defined(__STDC__) || defined(__cplusplus)
int DbgInit(void);
int DbgTerm(void);
int DbgPrepare(const char * const file,const int line, const int code);
int DbgArchiveNow ( void );
void DbgArchive ( const unsigned int ArchiveTime, const unsigned int ArchiveSize );
int DbgOutput(const char *fstring, ... ) __attribute__ ((format(printf, 1, 2)));
#else
int DbgInit();
int DbgTerm();
int DbgPrepare();
DbgArchiveNow();
DbgArchive();
int DbgOutput();
#endif
extern int dbg_level;
extern int dbg_pid;
extern char dbg_log[];
#ifndef _STDIO_INCLUDED
#include <stdio.h>
#endif
extern FILE *dbg_log_fd;
extern const char *dbg_name;
extern int dbg_print;
extern int dbg_flush;
extern int dbg_add_log_id;
#ifdef __cplusplus
} //extern "C"
#endif
#else
#define InitialiseDebug(params) DBG_OK
#define TerminateDebug(params) DBG_OK
#define Debug(lvl,params)
#define Info(params)
#define Warning(params)
#define Error(params)
#define Fatal(params)
#define Mark()
#define Log()
#define Enter()
#define Exit()
#define DbgInit()
#define DbgTerm()
#endif /* DEBUG_ON */

73
src/zms.cpp Normal file
View File

@ -0,0 +1,73 @@
#include "zm.h"
void main( int argc, const char *argv[] )
{
int id = 1;
unsigned long idle = 5000;
unsigned long refresh = 50;
int event = 0;
char *path = ".";
const char *query = getenv( "QUERY_STRING" );
if ( query )
{
char temp_query[256];
strcpy( temp_query, query );
char *q_ptr = temp_query;
char *parms[8]; // Shouldn't be more than this
int parm_no = 0;
while( parms[parm_no] = strtok( q_ptr, "&" ) )
{
parm_no++;
q_ptr = NULL;
}
for ( int p = 0; p < parm_no; p++ )
{
char *name = strtok( parms[p], "=" );
char *value = strtok( NULL, "=" );
if ( !strcmp( name, "refresh" ) )
refresh = atol( value );
else if ( !strcmp( name, "idle" ) )
idle = atol( value );
else if ( !strcmp( name, "monitor" ) )
id = atoi( value );
else if ( !strcmp( name, "event" ) )
event = atoi( value );
else if ( !strcmp( name, "path" ) )
path = value;
}
}
dbg_name = "zms";
DbgInit();
if ( !mysql_init( &dbconn ) )
{
fprintf( stderr, "Can't initialise structure: %s\n", mysql_error( &dbconn ) );
exit( mysql_errno( &dbconn ) );
}
if ( !mysql_connect( &dbconn, "", "zmuser", "zmuserzm" ) )
{
fprintf( stderr, "Can't connect to server: %s\n", mysql_error( &dbconn ) );
exit( mysql_errno( &dbconn ) );
}
if ( mysql_select_db( &dbconn, "polycam" ) )
{
fprintf( stderr, "Can't select database: %s\n", mysql_error( &dbconn ) );
exit( mysql_errno( &dbconn ) );
}
if ( !event )
{
Monitor *monitor = Monitor::Load( id );
if ( monitor )
monitor->StreamImages( idle, refresh, stdout );
}
else
{
Event::StreamEvent( path, event, refresh, stdout );
}
}

138
src/zmu.cpp Normal file
View File

@ -0,0 +1,138 @@
#include <getopt.h>
#include "zm.h"
void main( int argc, char *argv[] )
{
static struct option long_options[] = {
{"monitor", 1, 0, 'm'},
{"image", 2, 0, 'i'},
{"timestamp", 2, 0, 't'},
{"state", 0, 0, 's'},
{"read_index", 0, 0, 'r'},
{"write_index", 0, 0, 'w'},
{"fps", 0, 0, 'f'},
{"zones", 0, 0, 'z'},
{0, 0, 0, 0}
};
int id = 1;
enum { STATE, IMAGE, TIME, READ_IDX, WRITE_IDX, FPS, ZONES } function = STATE;
int image_idx = -1;
while (1)
{
int this_option_optind = optind ? optind : 1;
int option_index = 0;
int c = getopt_long (argc, argv, "m:srwi::t::fz", long_options, &option_index);
if (c == -1)
break;
switch (c)
{
case 'm':
id = atoi(optarg);
break;
case 's':
function = STATE;
break;
case 'i':
function = IMAGE;
if ( optarg )
{
image_idx = atoi( optarg );
}
break;
case 't':
function = TIME;
if ( optarg )
{
image_idx = atoi( optarg );
}
break;
case 'r':
function = READ_IDX;
break;
case 'w':
function = WRITE_IDX;
break;
case 'f':
function = FPS;
break;
case 'z':
function = ZONES;
break;
case '?':
//fprintf( stderr, "What?\n" );
break;
default:
//fprintf( stderr, "?? getopt returned character code 0%o ??\n", c );
break;
}
}
#if 0
if (optind < argc)
{
printf ("non-option ARGV-elements: ");
while (optind < argc)
printf ("%s ", argv[optind++]);
printf ("\n");
}
#endif
//printf( "Monitor %d, Function %d, ImageIdx %d\n", id, function, image_idx );
dbg_name = "zmu";
DbgInit();
if ( !mysql_init( &dbconn ) )
{
fprintf( stderr, "Can't initialise structure: %s\n", mysql_error( &dbconn ) );
exit( mysql_errno( &dbconn ) );
}
if ( !mysql_connect( &dbconn, "", "zmuser", "zmuserzm" ) )
{
fprintf( stderr, "Can't connect to server: %s\n", mysql_error( &dbconn ) );
exit( mysql_errno( &dbconn ) );
}
if ( mysql_select_db( &dbconn, "polycam" ) )
{
fprintf( stderr, "Can't select database: %s\n", mysql_error( &dbconn ) );
exit( mysql_errno( &dbconn ) );
}
Monitor *monitor = Monitor::Load( id );
if ( monitor )
{
if ( function == STATE )
{
printf( "%d\n", monitor->GetState() );
}
else if ( function == IMAGE )
{
monitor->GetImage( image_idx );
}
else if ( function == TIME )
{
printf( "%d\n", monitor->GetTimestamp( image_idx ) );
}
else if ( function == READ_IDX )
{
printf( "%d\n", monitor->GetLastReadIndex() );
}
else if ( function == WRITE_IDX )
{
printf( "%d\n", monitor->GetLastWriteIndex() );
}
else if ( function == FPS )
{
printf( "%.2f\n", monitor->GetFPS() );
}
else if ( function == ZONES )
{
monitor->ReloadZones();
}
}
}

873
web/zm.php Normal file
View File

@ -0,0 +1,873 @@
<?php
include_once( 'browser.php' );
import_request_variables( "GPC" );
$DB_SERVER = "localhost"; // Database Server machine
$DB_LOGIN = "root"; // Database login
$DB_PASSWORD = ""; // Database password
$DB = "polycam"; // Database containing the tables
define( "MAX_EVENTS", 12 );
define( "THISFILE", "THIS_FILE" );
if ( !$bandwidth )
{
$new_bandwidth = "low";
}
if ( $new_bandwidth )
{
$bandwidth = $new_bandwidth;
setcookie( "bandwidth", $new_bandwidth, time()+3600*24*30*12*10 );
}
if ( $bandwidth == "high" )
{
define( "REFRESH_MAIN", 300 );
define( "REFRESH_CYCLE", 5 );
define( "REFRESH_IMAGE", 5 );
define( "REFRESH_STATUS", 3 );
define( "REFRESH_EVENTS", 30 );
define( "REFRESH_EVENTS_ALL", 120 );
define( "STREAM_IDLE_DELAY", 1000 );
define( "STREAM_FRAME_DELAY", 50 );
define( "STREAM_EVENT_DELAY", 200 );
define( "IMAGE_SCALING", 1 );
}
elseif ( $bandwidth == "medium" )
{
define( "REFRESH_MAIN", 300 );
define( "REFRESH_CYCLE", 10 );
define( "REFRESH_IMAGE", 15 );
define( "REFRESH_STATUS", 5 );
define( "REFRESH_EVENTS", 60 );
define( "REFRESH_EVENTS_ALL", 300 );
define( "STREAM_IDLE_DELAY", 5000 );
define( "STREAM_FRAME_DELAY", 100 );
define( "STREAM_EVENT_DELAY", 50 );
define( "IMAGE_SCALING", 2 );
}
else
{
define( "REFRESH_MAIN", 300 );
define( "REFRESH_CYCLE", 30 );
define( "REFRESH_IMAGE", 30 );
define( "REFRESH_STATUS", 10 );
define( "REFRESH_EVENTS", 180 );
define( "REFRESH_EVENTS_ALL", 600 );
define( "STREAM_IDLE_DELAY", 10000 );
define( "STREAM_FRAME_DELAY", 250 );
define( "STREAM_EVENT_DELAY", 10 );
define( "IMAGE_SCALING", 4 );
}
$conn = mysql_connect("$DB_SERVER", "$DB_LOGIN", "$DB_PASSWORD") or die("Could not connect to DB: ".mysql_error());
mysql_select_db("$DB", $conn) or die("Could not select DB: ".mysql_error());
if ( $action )
{
if ( $action == "rename" && $event_name && $eid )
{
$result = mysql_query( "update Events set Name = '$event_name' where Id = '$eid'" );
if ( !$result )
die( mysql_error() );
}
elseif ( $action == "archive" && $eid )
{
$result = mysql_query( "update Events set Archived = 1 where Id = '$eid'" );
if ( !$result )
die( mysql_error() );
}
elseif ( $action == "delete" && $delete_eids )
{
foreach( $delete_eids as $delete_eid )
{
$result = mysql_query( "delete from Frames where EventId = '$delete_eid'" );
if ( !$result )
die( mysql_error() );
$result = mysql_query( "delete from Events where Id = '$delete_eid'" );
if ( !$result )
die( mysql_error() );
if ( $delete_eid )
system( escapeshellcmd( "rm -rf events/*/".sprintf( "%04d", $delete_eid ) ) );
}
}
}
if ( !$view )
{
$view = "console";
}
if ( $view == "console" )
{
header("Refresh: ".REFRESH_MAIN."; URL='index.php" );
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); // always modified
header("Cache-Control: no-store, no-cache, must-revalidate"); // HTTP/1.1
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache"); // HTTP/1.0
//$result = mysql_query( "select M.*, count(E.Id) as EventCount, count(if(E.Archived,1,NULL)) as ArchEventCount, count(if(E.StartTime>NOW() - INTERVAL 1 HOUR && E.Archived = 0,1,NULL)) as HourEventCount, count(if(E.StartTime>NOW() - INTERVAL 1 DAY && E.Archived = 0,1,NULL)) as DayEventCount, count(if(E.StartTime>NOW() - INTERVAL 7 DAY && E.Archived = 0,1,NULL)) as WeekEventCount, count(if(E.StartTime>NOW() - INTERVAL 1 MONTH && E.Archived = 0,1,NULL)) as MonthEventCount, count(Z.MonitorId) as ZoneCount from Monitors as M inner join Zones as Z on Z.MonitorId = M.Id left join Events as E on E.MonitorId = M.Id group by E.MonitorId,Z.MonitorId order by Id" );
$sql = "select M.*, count(E.Id) as EventCount, count(if(E.Archived,1,NULL)) as ArchEventCount, count(if(E.StartTime>NOW() - INTERVAL 1 HOUR && E.Archived = 0,1,NULL)) as HourEventCount, count(if(E.StartTime>NOW() - INTERVAL 1 DAY && E.Archived = 0,1,NULL)) as DayEventCount, count(if(E.StartTime>NOW() - INTERVAL 7 DAY && E.Archived = 0,1,NULL)) as WeekEventCount, count(if(E.StartTime>NOW() - INTERVAL 1 MONTH && E.Archived = 0,1,NULL)) as MonthEventCount from Monitors as M left join Events as E on E.MonitorId = M.Id group by E.MonitorId order by Id";
$result = mysql_query( $sql );
if ( !$result )
echo mysql_error();
$monitors = array();
$max_width = 0;
$max_height = 0;
while( $row = mysql_fetch_assoc( $result ) )
{
if ( $max_width < $row[Width] ) $max_width = $row[Width];
if ( $max_height < $row[Height] ) $max_height = $row[Height];
$sql = "select count(Id) as ZoneCount, count(if(Type='Active',1,NULL)) as ActZoneCount, count(if(Type='Inclusive',1,NULL)) as IncZoneCount, count(if(Type='Exclusive',1,NULL)) as ExcZoneCount, count(if(Type='Inactive',1,NULL)) as InactZoneCount from Zones where MonitorId = '$row[Id]'";
$result2 = mysql_query( $sql );
if ( !$result2 )
echo mysql_error();
$row2 = mysql_fetch_assoc( $result2 );
$monitors[] = array_merge( $row, $row2 );
}
//echo phpinfo();
?>
<html>
<head>
<title>ZM - Console</title>
<link rel="stylesheet" href="zm_styles.css" type="text/css">
<script language="JavaScript">
window.resizeTo(800,400)
function newWindow(Url,Name,Width,Height) {
var Name = window.open(Url,Name,"resizable,scrollbars,width="+Width+",height="+Height);
}
</script>
</head>
<body>
<p class="head" align="center"><strong>Zone Monitor Console</strong></p>
<table align="center" border="0" cellspacing="2" cellpadding="2" width="96%">
<tr>
<td class="smallhead" align="left"><?php echo count($monitors) ?> Monitors</td>
<td class="smallhead" align="center">Currently configured for <strong><?php echo $bandwidth ?></strong> bandwidth (change to
<?php if ( $bandwidth != "high" ) { ?> <a href="index.php?new_bandwidth=high">high</a><?php } ?>
<?php if ( $bandwidth != "medium" ) { ?> <a href="index.php?new_bandwidth=medium">medium</a><?php } ?>
<?php if ( $bandwidth != "low" ) { ?> <a href="index.php?new_bandwidth=low">low</a><?php } ?> )</td>
<td class="smallhead" align="right"><a href="javascript: newWindow( 'index.php?view=cycle', 'zmCycle', <?php echo $max_width+36 ?>, <?php echo $max_height+72 ?> );">Monitor All</a></td>
</tr>
</table>
<table align="center" border="0" cellspacing="2" cellpadding="2" width="96%">
<form name="event_form" method="post" action="index.php">
<input type="hidden" name="view" value="<?php echo $view ?>">
<input type="hidden" name="action" value="delete">
<tr><td align="left" class="smallhead">Id</td>
<td align="left" class="smallhead">Name</td>
<td align="left" class="smallhead">Device/Channel</td>
<td align="left" class="smallhead">Function</td>
<td align="left" class="smallhead">Dimensions</td>
<td align="right" class="smallhead">Events</td>
<td align="right" class="smallhead">Hour</td>
<td align="right" class="smallhead">Day</td>
<td align="right" class="smallhead">Week</td>
<td align="right" class="smallhead">Month</td>
<td align="right" class="smallhead">Archive</td>
<td align="right" class="smallhead">Zones</td>
<td align="center" class="smallhead">Delete</td>
</tr>
<?php
$event_count = 0;
$hour_event_count = 0;
$day_event_count = 0;
$week_event_count = 0;
$month_event_count = 0;
$arch_event_count = 0;
$zone_count = 0;
foreach( $monitors as $monitor )
{
$event_count += $monitor[EventCount];
$hour_event_count += $monitor[HourEventCount];
$day_event_count += $monitor[DayEventCount];
$week_event_count += $monitor[WeekEventCount];
$month_event_count += $monitor[MonthEventCount];
$arch_event_count += $monitor[ArchEventCount];
$zone_count += $monitor[ZoneCount];
?>
<tr>
<td align="left" class="text"><a href="javascript: newWindow( 'index.php?view=monitor&mid=<?php echo $monitor[Id] ?>', 'zm<?php echo $monitor[Name] ?>', <?php echo $monitor[Width]+72 ?>, <?php echo $monitor[Height]+360 ?> );"><?php echo $monitor[Id] ?>.</a></td>
<td align="left" class="text"><a href="javascript: newWindow( 'index.php?view=monitor&mid=<?php echo $monitor[Id] ?>', 'zm<?php echo $monitor[Name] ?>', <?php echo $monitor[Width]+72 ?>, <?php echo $monitor[Height]+360 ?> );"><?php echo $monitor[Name] ?></a></td>
<td align="left" class="text">/dev/video<?php echo $monitor[Device] ?> (<?php echo $monitor[Channel] ?>)</td>
<td align="left" class="text"><?php echo $monitor['Function'] ?></td>
<td align="left" class="text"><?php echo $monitor[Width] ?>x<?php echo $monitor[Height] ?>x<?php echo $monitor[Colours]*8 ?></td>
<td align="right" class="text"><?php echo $monitor[EventCount] ?></td>
<td align="right" class="text"><?php echo $monitor[HourEventCount] ?></td>
<td align="right" class="text"><?php echo $monitor[DayEventCount] ?></td>
<td align="right" class="text"><?php echo $monitor[WeekEventCount] ?></td>
<td align="right" class="text"><?php echo $monitor[MonthEventCount] ?></td>
<td align="right" class="text"><?php echo $monitor[ArchEventCount] ?></td>
<td align="right" class="text"><a href="javascript: newWindow( 'index.php?view=zones&mid=<?php echo $monitor[Id] ?>', 'zmZones', <?php echo $monitor[Width]+36 ?>, <?php echo $monitor[Height]+72 ?> );"><?php echo $monitor[ZoneCount] ?></a></td>
<td align="center" class="text"><input type="checkbox" name="delete_mids[]" value="<?php echo $zone[Id] ?>"></td>
</tr>
<?php
}
?>
<tr><td align="left" class="text">&nbsp;</td>
<td align="left" class="text">&nbsp;</td>
<td colspan="3" align="center"><input type="submit" value="Add New Monitor" class="form"></td>
<td align="right" class="text"><?php echo $event_count ?></td>
<td align="right" class="text"><?php echo $hour_event_count ?></td>
<td align="right" class="text"><?php echo $day_event_count ?></td>
<td align="right" class="text"><?php echo $week_event_count ?></td>
<td align="right" class="text"><?php echo $month_event_count ?></td>
<td align="right" class="text"><?php echo $arch_event_count ?></td>
<td align="right" class="text"><?php echo $zone_count ?></td>
<td align="center"><input type="submit" value="Delete" class="form"></td>
</tr>
</form>
</table>
</body>
</html>
<?php
}
elseif ( $view == "cycle" )
{
$result = mysql_query( "select * from Monitors where Function != 'None' order by Id" );
$monitors = array();
$mon_idx = 0;
while( $row = mysql_fetch_assoc( $result ) )
{
if ( $mid && $row[Id] == $mid )
$mon_idx = count($monitors);
$monitors[] = $row;
}
$monitor = $monitors[$mon_idx];
$next_mid = $mon_idx==(count($monitors)-1)?$monitors[0][Id]:$monitors[$mon_idx+1][Id];
header("Refresh: ".REFRESH_CYCLE."; URL='index.php?view=cycle&mid=$next_mid'" );
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); // always modified
header("Cache-Control: no-store, no-cache, must-revalidate"); // HTTP/1.1
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache"); // HTTP/1.0
?>
<html>
<head>
<title>ZM - Cycle Watch</title>
<link rel="stylesheet" href="zm_styles.css" type="text/css">
<script language="JavaScript">
function newWindow(Url,Name,Width,Height) {
var Name = window.open(Url,Name,"resizable,scrollbars,width="+Width+",height="+Height);
}
</script>
</head>
<body>
<p class="head" align="center"><?php echo $monitor[Name] ?></p>
<a href="javascript: newWindow( 'index.php?view=monitor&mid=<?php echo $monitor[Id] ?>', 'zm<?php echo $monitor[Name] ?>', <?php echo $monitor[Width]+72 ?>, <?php echo $monitor[Height]+360 ?> );"><img src='<?php echo $monitor[Name] ?>.jpg' border="0"></a>
</body>
</html>
<?php
}
elseif ( $view == "monitor" )
{
$result = mysql_query( "select * from Monitors where Id = '$mid'" );
if ( !$result )
die( mysql_error() );
$monitor = mysql_fetch_assoc( $result );
?>
<html>
<head>
<title>ZM - <?php echo $monitor[Name] ?> - Monitor</title>
<link rel="stylesheet" href="zm_styles.css" type="text/css">
<script language="JavaScript">
opener.location.reload();
window.focus();
</script>
</head>
<frameset rows="<?php echo $monitor[Height]+32 ?>,16,*" border="1" frameborder="no" framespacing="0">
<frame src="index.php?view=watch&mode=stream&mid=<?php echo $monitor[Id] ?>" marginwidth="0" marginheight="0" name="MonitorStream" scrolling="no">
<frame src="index.php?view=status&mid=<?php echo $monitor[Id] ?>" marginwidth="0" marginheight="0" name="MonitorStatus" scrolling="no">
<frame src="index.php?view=events&max_events=<?php echo MAX_EVENTS ?>&mid=<?php echo $monitor[Id] ?>" marginwidth="0" marginheight="0" name="MonitorEvents" scrolling="auto">
</frameset>
<?php
}
elseif( $view == "watch" )
{
if ( !$mode )
$mode = "stream";
$result = mysql_query( "select * from Monitors where Id = '$mid'" );
if ( !$result )
die( mysql_error() );
$monitor = mysql_fetch_assoc( $result );
if ( $mode != "stream" )
{
header("Refresh: ".REFRESH_IMAGE."; URL='index.php?view=watch&mid=$mid&mode=still'" );
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); // always modified
header("Cache-Control: no-store, no-cache, must-revalidate"); // HTTP/1.1
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache"); // HTTP/1.0
}
?>
<html>
<head>
<link rel="stylesheet" href="zm_styles.css" type="text/css">
<script language="JavaScript">
function closeWindow() {
top.window.close();
}
</script>
</head>
<body>
<table width="96%" align="center" border="0" cellspacing="0" cellpadding="4">
<tr>
<td width="33%" align="left" class="text"><b><?php echo $monitor[Name] ?> Stream</b></td>
<?php if ( $mode == "stream" ) { ?>
<td width="34%" align="center" class="text"><a href="index.php?view=watch&mode=stills&mid=<?php echo $mid ?>">Stills</a></td>
<?php } else { ?>
<td width="34%" align="center" class="text"><a href="index.php?view=watch&mode=stream&mid=<?php echo $mid ?>">Stream</a></td>
<?php } ?>
<td width="33%" align="right" class="text"><a href="javascript: closeWindow();">Close</a></td>
</tr>
<?php if ( $mode == "stream" )
{
$stream_src = "/cgi-bin/zms?monitor=$monitor[Id]&idle=".STREAM_IDLE_DELAY."&refresh=".STREAM_FRAME_DELAY;
if ( browser_is_netscape() )
{
?>
<tr><td colspan="3" align="center"><img src="<?php echo $stream_src ?>" border="0" width="<?php echo $monitor[Width] ?>" height="<?php echo $monitor[Height] ?>"></td></tr>
<?php
}
else
{
?>
<tr><td colspan="3" align="center"><applet code="com.charliemouse.cambozola.Viewer" archive="cambozola.jar" align="middle" width="<?php echo $monitor[Width] ?>" height="<?php echo $monitor[Height] ?>"><param name="url" value="<?php echo $stream_src ?>"></applet></td></tr>
<?php
}
}
else
{
?>
<tr><td colspan="3" align="center"><img src="<?php echo $monitor[Name] ?>.jpg" border="0" width="<?php echo $monitor[Width] ?>" height="<?php echo $monitor[Height] ?>"></td></tr>
<?php
}
?>
</table>
</body>
</html>
<?php
}
elseif ( $view == "status" )
{
$status = exec( escapeshellcmd( "./zmu -m $mid -s" ) );
$status_string = "Unknown";
$class = "text";
if ( $status == 0 )
{
$status_string = "Idle";
}
elseif ( $status == 1 )
{
$status_string = "Alarm";
$class = "redtext";
}
elseif ( $status == 2 )
{
$status_string = "Alert";
$class = "ambtext";
}
header("Refresh: ".REFRESH_STATUS."; URL='index.php?view=status&mid=$mid&last_status=$status'" );
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); // always modified
header("Cache-Control: no-store, no-cache, must-revalidate"); // HTTP/1.1
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache"); // HTTP/1.0
?>
<html>
<head>
<link rel="stylesheet" href="zm_styles.css" type="text/css">
<script language="JavaScript">
<?php
if ( $status > 0 && $last_status == 0 )
{
?>
top.window.focus();
<?php
//document.write( "\a" );
}
?>
</script>
</head>
<body>
<table width="100%" align="center" border="0" cellpadding="0" cellspacing="0"><tr><td class="<?php echo $class ?>" align="center" valign="middle">Status: <?php echo $status_string ?></td></tr></table>
</body>
</html>
<?php
}
elseif ( $view == "events" )
{
if ( !$archived )
{
if ( $max_events )
{
header("Refresh: ".REFRESH_EVENTS."; URL='index.php?view=events&mid=$mid&max_events=$max_events'" );
}
else
{
header("Refresh: ".REFRESH_EVENTS_ALL."; URL='index.php?view=events&mid=$mid'" );
}
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); // always modified
header("Cache-Control: no-store, no-cache, must-revalidate"); // HTTP/1.1
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache"); // HTTP/1.0
}
?>
<html>
<head>
<title>ZM - <?php echo $monitor ?> - Events <?php if ( $archived ) { ?>Archive<?php } ?></title>
<link rel="stylesheet" href="zm_styles.css" type="text/css">
<script language="JavaScript">
function newWindow(Url,Name) {
var Name = window.open(Url,Name,"resizable,scrollbars,width=400,height=500");
}
function closeWindow() {
top.window.close();
}
function checkAll(form,name){
for (var i = 0; i < form.elements.length; i++)
if (form.elements[i].name.indexOf(name) == 0)
form.elements[i].checked = 1;
}
</script>
</head>
<body>
<form name="event_form" method="post" action="index.php">
<input type="hidden" name="view" value="<?php echo $view ?>">
<input type="hidden" name="action" value="delete">
<input type="hidden" name="mid" value="<?php echo $mid ?>">
<?php if ( $max_events ) { ?>
<input type="hidden" name="max_events" value="<?php echo $max_events ?>">
<?php } ?>
<?php if ( $archived ) { ?>
<input type="hidden" name="archived" value="<?php echo $archived ?>">
<?php } ?>
<table width="96%" align="center" border="0" cellspacing="1" cellpadding="1">
<tr>
<td valign="top"><table border="0" cellspacing="0" cellpadding="0" width="100%">
<?php
$sql = "select E.Id, E.Name,unix_timestamp(E.StartTime) as Time,E.Length,E.Frames,E.AlarmFrames from Monitors as M, Events as E where M.Id = '$mid' and M.Id = E.MonitorId and E.Archived = ".($archived?"1":"0")." order by E.Id desc";
if ( $max_events )
$sql .= " limit 0,$max_events";
$result = mysql_query( $sql );
if ( !$result )
{
die( mysql_error() );
}
$n_rows = mysql_num_rows( $result );
?>
<tr>
<td class="text"><b><?php if ( $max_events ) {?>Last <?php } ?><?php echo $n_rows ?> events</b></td>
<?php if ( !$max_events ) { ?>
<td align="center" class="text"><a href="index.php?view=events&mid=<?php echo $mid ?>&max_events=<?php echo MAX_EVENTS ?>">Recent</a></td>
<?php } ?>
<?php if ( $archived || $max_events ) { ?>
<td align="center" class="text"><a href="index.php?view=events&mid=<?php echo $mid ?>">All</a></td>
<?php } ?>
<?php if ( !$archived ) { ?>
<td align="center" class="text"><a href="index.php?view=events&mid=<?php echo $mid ?>&archived=1">Archive</a></td>
<?php } ?>
<td align="right" class="text"><a href="javascript: checkAll( event_form, 'delete_eids' );">Check All</a></td>
</tr>
<tr><td colspan="4" class="text">&nbsp;</td></tr>
<tr><td colspan="4"><table border="0" cellspacing="0" cellpadding="0" width="100%">
<tr align="center"><td width="4%" class="text">Id</td><td width="24%" class="text">Name</td><td class="text">Time</td><td class="text">Length</td><td class="text">Frames</td><td class="text">Delete</td></tr>
<?php
while( $row = mysql_fetch_assoc( $result ) )
{
?>
<tr>
<td align="center" class="text"><a href="javascript: newWindow( 'index.php?view=event&eid=<?php echo $row[Id] ?>', 'zmEvent' );"><?php echo $row[Id] ?></a></td>
<td align="center" class="text"><a href="javascript: newWindow( 'index.php?view=event&eid=<?php echo $row[Id] ?>', 'zmEvent' );"><?php echo $row[Name] ?></a></td>
<td align="center" class="text"><?php echo strftime( "%m/%d %H:%M:%S", $row[Time] ) ?></td>
<td align="center" class="text"><?php echo $row[Length] ?></td>
<td align="center" class="text"><?php echo $row[Frames] ?> (<?php echo $row[AlarmFrames] ?>)</td>
<td align="center" class="text"><input type="checkbox" name="delete_eids[]" value="<?php echo $row[Id] ?>"></td>
</tr>
<?php
}
?>
</table></td></tr>
</table></td>
</tr>
<tr><td align="right"><input type="submit" value="Delete" class="form"></td></tr>
</table>
</form>
</body>
</html>
<?php
}
elseif ( $view == "images" )
{
$result = mysql_query( "select E.*,M.Name as MonitorName, M.Width, M.Height from Events as E, Monitors as M where E.Id = '$eid' and E.MonitorId = M.Id" );
if ( !$result )
die( mysql_error() );
$event = mysql_fetch_assoc( $result );
?>
<html>
<head>
<title>ZM - Images - <?php echo $event[Name] ?> - Images</title>
<link rel="stylesheet" href="zm_styles.css" type="text/css">
<script language="JavaScript">
window.focus();
function newWindow(Url,Name,Width,Height) {
var Name = window.open(Url,Name,"resizable,scrollbars,width="+Width+",height="+Height);
}
function closeWindow() {
window.close();
}
</script>
</head>
<body>
<table border="0" cellspacing="0" cellpadding="0" align="center" width="100%">
<?php
$result = mysql_query( "select * from Frames where EventID = '$eid' order by Id" );
if ( !$result )
die( mysql_error() );
?>
<tr><td colspan="4"><table border="0" cellpadding="0" cellspacing="2" align="center">
<tr>
<?php
$count = 0;
$scale = IMAGE_SCALING;
$fraction = sprintf( "%.2f", 1/$scale );
$thumb_width = $event[Width]/4;
$thumb_height = $event[Height]/4;
while( $row = mysql_fetch_assoc( $result ) )
{
$frame_id = $row[FrameId];
$image_path = $row[ImagePath];
if ( $scale == 1 )
{
$capt_image = $image_path;
$anal_image = preg_replace( "/capture/", "analyse", $image_path );
if ( file_exists($anal_image) && filesize( $anal_image ) )
{
$thumb_image = $anal_image;
}
else
{
$thumb_image = $capt_image;
}
}
else
{
$thumb_image = preg_replace( "/capture/", "thumb", $image_path );
if ( !file_exists($thumb_image) || !filesize( $thumb_image ) )
{
$anal_image = preg_replace( "/capture/", "analyse", $image );
if ( file_exists( $anal_image ) )
$command = "jpegtopnm -dct fast $anal_image | pnmscalefixed $fraction | ppmtojpeg --dct=fast > $thumb_image";
else
$command = "jpegtopnm -dct fast $image | pnmscalefixed $fraction | ppmtojpeg --dct=fast > $thumb_image";
#exec( escapeshellcmd( $command ) );
exec( $command );
}
}
?>
<td align="center" width="88"><a href="javascript: newWindow( 'index.php?view=image&eid=<?php echo $eid ?>&fid=<?php echo $frame_id ?>', 'zmImage', <?php echo $event[Width]+48 ?>, <?php echo $event[Height]+72 ?> );"><img src="<?php echo $thumb_image ?>" width="<?php echo $thumb_width ?>" height="<? echo $thumb_height ?>" border="0" alt="<?php echo $frame_id ?>/<?php echo $row[Score] ?>"></a></td>
<?php
flush();
if ( !(++$count % 4) )
{
?>
</tr>
<tr>
<?php
}
}
?>
</tr>
</table></td></tr>
</table>
</body>
</html>
<?php
}
elseif( $view == "image" )
{
$result = mysql_query( "select * from Frames where EventID = '$eid' and FrameId = '$fid'" );
if ( !$result )
die( mysql_error() );
$frame = mysql_fetch_assoc( $result );
$result = mysql_query( "select count(*) as FrameCount from Frames where EventID = '$eid'" );
if ( !$result )
die( mysql_error() );
$row = mysql_fetch_assoc( $result );
$max_fid = $row[FrameCount];
$first_fid = 1;
$prev_fid = $fid-1;
$next_fid = $fid+1;
$last_fid = $max_fid;
$image_path = $frame[ImagePath];
$anal_image = preg_replace( "/capture/", "analyse", $image_path );
if ( file_exists( $anal_image ) )
{
$image_path = $anal_image;
}
?>
<html>
<head>
<title>ZM - Image <?php echo $eid."-".$fid ?></title>
<link rel="stylesheet" href="zm_styles.css" type="text/css">
<script language="JavaScript">
window.focus();
function newWindow(Url,Name,Width,Height) {
var Name = window.open(Url,Name,"resizable,scrollbars,width="+Width+",height="+Height);
}
function closeWindow() {
window.close();
}
function deleteImage() {
opener.location.href = "index.php?view=delete&eid=<?php echo $eid ?>";
window.close();
}
</script>
</head>
<body>
<table border="0">
<tr><td colspan="2" class="text"><b>Image <?php echo $eid."-".$fid ?></b></td>
<td align="center" class="text"><a href="javascript: deleteImage();">Delete</a></td>
<td align="right" class="text"><a href="javascript: closeWindow();">Close</a></td>
</tr>
<tr><td colspan="4"><img src="<?php echo $image_path ?>" width="352" height="288" border="0"></td></tr>
<tr>
<?php if ( $fid > 1 ) { ?>
<td width="25%" class="text"><a href="index.php?view=image&eid=<?php echo $eid ?>&fid=<?php echo $first_fid ?>">First</a></td>
<?php } else { ?>
<td width="25%" class="text">&nbsp;</td>
<?php } if ( $fid > 1 ) { ?>
<td width="25%" class="text"><a href="index.php?view=image&eid=<?php echo $eid ?>&fid=<?php echo $prev_fid ?>">Prev</a></td>
<?php } else { ?>
<td width="25%" class="text">&nbsp;</td>
<?php } if ( $fid < $max_fid ) { ?>
<td width="25%" class="text"><a href="index.php?view=image&eid=<?php echo $eid ?>&fid=<?php echo $next_fid ?>">Next</a></td>
<?php } else { ?>
<td width="25%" class="text">&nbsp;</td>
<?php } if ( $fid < $max_fid ) { ?>
<td width="25%" class="text"><a href="index.php?view=image&eid=<?php echo $eid ?>&fid=<?php echo $last_fid ?>">Last</a></td>
<?php } else { ?>
<td width="25%" class="text">&nbsp;</td>
<?php } ?>
</tr>
</table>
</body>
</html>
<?php
}
elseif( $view == "event" )
{
$result = mysql_query( "select E.*,M.Name as MonitorName,M.Width,M.Height from Events as E, Monitors as M where E.Id = '$eid' and E.MonitorId = M.Id" );
if ( !$result )
die( mysql_error() );
$event = mysql_fetch_assoc( $result );
?>
<html>
<head>
<title>ZM - Event - <?php echo $event[Name] ?></title>
<link rel="stylesheet" href="zm_styles.css" type="text/css">
<script language="JavaScript">
opener.location.reload();
window.focus();
function refreshWindow() {
window.location.reload();
}
function closeWindow() {
window.close();
}
function newWindow(Url,Name,Width,Height) {
var Name = window.open(Url,Name,"resizable,scrollbars,width="+Width+",height="+Height);
}
</script>
</head>
<body>
<table border="0" cellspacing="0" cellpadding="4" width="100%">
<tr>
<td colspan="6" align="left" class="text">
<form action="index.php">
<input type="hidden" name="view" value="<?php echo $view ?>">
<input type="hidden" name="action" value="rename">
<input type="hidden" name="eid" value="$eid">
<input type="text" size="16" name="event_name" value="<?php echo $event[Name] ?>" class="form">
<input type="submit" value="Rename" class="form"></td>
</tr>
<tr>
<td width="20%" align="center" class="text"><a href="javascript: refreshWindow();">Refresh</a></td>
<td width="20%" align="center" class="text"><a href="index.php?view=delete&eid=<?php echo $eid ?>">Delete</a></td>
<td width="20%" align="center" class="text"><a href="index.php?view=<?php echo $view ?>&action=archive&mid=<?php echo $event[MonitorName] ?>&eid=<?php echo $eid ?>">Archive</a></td>
<td width="20%" align="center" class="text"><a href="javascript: newWindow( 'index.php?view=images&eid=<?php echo $eid ?>', 'zmImages', <?php echo $event[Width]+72 ?>, <?php echo $event[Height]+360 ?> );">Images</a></td>
<td width="20%" align="center" class="text"><a href="javascript: newWindow( 'index.php?view=video&eid=<?php echo $eid ?>', 'zmVideo', 100, 80 );">Video</a></td>
<td width="20%" align="right" class="text"><a href="javascript: closeWindow();">Close</a></td>
</tr>
<?php
$stream_src = "/cgi-bin/zms?path=/data&event=$eid&refresh=".STREAM_EVENT_DELAY;
if ( browser_is_netscape() )
{
?>
<tr><td colspan="6" align="center"><img src="<?php echo $stream_src ?>" border="0" width="<?php echo $event[Width] ?>" height="<?php echo $event[Height] ?>"></td></tr>
<?php
}
else
{
?>
<tr><td colspan="6" align="center"><applet code="com.charliemouse.cambozola.Viewer" archive="cambozola.jar" align="middle" width="<?php echo $event[Width] ?>" height="<?php echo $event[Height] ?>"><param name="url" value="<?php echo $stream_src ?>"></applet></td></tr>
<?php
}
?>
</table>
</body>
</html>
<?php
}
elseif( $view == "zones" )
{
$result = mysql_query( "select * from Monitors where Id = '$mid'" );
if ( !$result )
die( mysql_error() );
$monitor = mysql_fetch_assoc( $result );
$result = mysql_query( "select * from Zones where MonitorId = '$mid'" );
if ( !$result )
die( mysql_error() );
$zones = array();
while( $row = mysql_fetch_assoc( $result ) )
{
$zones[] = $row;
}
$image = $monitor[Name]."-Zones.jpg";
?>
<html>
<head>
<title>ZM - <?php echo $monitor[Name] ?> - Zones</title>
<link rel="stylesheet" href="zm_styles.css" type="text/css">
</head>
<body>
<map name="zonemap">
<?php
foreach( $zones as $zone )
{
?>
<area shape="rect" coords="<?php echo "$zone[LoX],$zone[LoY],$zone[HiX],$zone[HiY]" ?>" href="index.php?view=zone&zid=<?php echo $zone[Id] ?>">
<?php
}
?>
<area shape="default" nohref>
</map>
<p class="head" align="center"><strong><?php echo $monitor[Name] ?> Zones</strong></p>
<table align="center" border="0" cellspacing="2" cellpadding="2" width="96%">
<tr><td align="center"><img src="<?php echo $image ?>" usemap="#zonemap" width="352" height="288" border="0"></td></tr>
</table>
<table align="center" border="0" cellspacing="0" cellpadding="0" width="96%">
<form name="event_form" method="post" action="index.php">
<input type="hidden" name="view" value="<?php echo $zones ?>">
<input type="hidden" name="action" value="delete">
<input type="hidden" name="mid" value="<?php echo $mid ?>">
<tr><td align="center" class="smallhead">Id</td>
<td align="center" class="smallhead">Name</td>
<td align="center" class="smallhead">Type</td>
<td align="center" class="smallhead">Units</td>
<td align="center" class="smallhead">Dimensions</td>
<td align="center" class="smallhead">Delete</td>
</tr>
<?php
foreach( $zones as $zone )
{
?>
<tr>
<td align="center" class="text"><a href="javascript: newWindow( 'index.php?view=zone&mid=<?php echo $zone[Id] ?>', 'zmZone', <?php echo $zone[Width]+72 ?>, <?php echo $zone[Height]+360 ?> );"><?php echo $zone[Id] ?>.</a></td>
<td align="center" class="text"><a href="javascript: newWindow( 'index.php?view=zone&mid=<?php echo $zone[Id] ?>', 'zmZone', <?php echo $zone[Width]+72 ?>, <?php echo $zone[Height]+360 ?> );"><?php echo $zone[Name] ?></a></td>
<td align="center" class="text"><?php echo $zone['Type'] ?></td>
<td align="center" class="text"><?php echo $zone[Units] ?></td>
<td align="center" class="text"><?php echo $zone[LoX] ?>,<?php echo $zone[LoY] ?>-<?php echo $zone[HiX] ?>,<?php echo $zone[HiY]?></td>
<td align="center" class="text"><input type="checkbox" name="delete_zids[]" value="<?php echo $zone[Id] ?>"></td>
</tr>
<?php
}
?>
<tr>
<td align="center" class="text">&nbsp;</td>
<td colspan="4" align="center"><input type="submit" value="Add New Zone" class="form"></td>
<td align="center"><input type="submit" value="Delete" class="form"></td>
</tr>
</form>
</table>
</body>
</html>
<?php
}
elseif( $view == "video" )
{
$result = mysql_query( "select E.*,M.Name as MonitorName, M.Colours from Events as E, Monitors as M where E.Id = '$eid' and E.MonitorId = M.Id" );
if ( !$result )
die( mysql_error() );
$event = mysql_fetch_assoc( $result );
$event_dir = "events/$event[MonitorName]/".sprintf( "%04d", $eid );
$param_file = $event_dir."/mpeg.param";
$video_name = preg_replace( "/\\s/", "_", $event[Name] ).".mpeg";
$video_file = $event_dir."/".$video_name;
if ( !file_exists( $video_file ) )
{
$fp = fopen( $param_file, "w" );
fputs( $fp, "PATTERN IBBPBBPBBPBBPBB\n" );
fputs( $fp, "OUTPUT $video_file\n" );
fputs( $fp, "BASE_FILE_FORMAT JPEG\n" );
fputs( $fp, "GOP_SIZE 30\n" );
fputs( $fp, "SLICES_PER_FRAME 1\n" );
fputs( $fp, "PIXEL HALF\n" );
fputs( $fp, "RANGE 10\n" );
fputs( $fp, "PSEARCH_ALG LOGARITHMIC\n" );
fputs( $fp, "BSEARCH_ALG CROSS2\n" );
fputs( $fp, "IQSCALE 8\n" );
fputs( $fp, "PQSCALE 10\n" );
fputs( $fp, "BQSCALE 25\n" );
fputs( $fp, "REFERENCE_FRAME ORIGINAL\n" );
fputs( $fp, "FRAME_RATE 24\n" );
if ( $event[Colours] == 1 )
fputs( $fp, "INPUT_CONVERT jpegtopnm * | pgmtoppm white | ppmtojpeg\n" );
else
fputs( $fp, "INPUT_CONVERT *\n" );
fputs( $fp, "INPUT_DIR $event_dir\n" );
fputs( $fp, "INPUT\n" );
for ( $i = 1; $i < $event[Frames]; $i++ )
{
fputs( $fp, "capture-".sprintf( "%03d", $i ).".jpg\n" );
fputs( $fp, "capture-".sprintf( "%03d", $i ).".jpg\n" );
}
fputs( $fp, "END_INPUT\n" );
fclose( $fp );
exec( escapeshellcmd( "./mpeg_encode $param_file >$event_dir/mpeg.log" ) );
}
//chdir( $event_dir );
//header("Content-type: video/mpeg");
//header("Content-Disposition: inline; filename=$video_name");
header("Location: $video_file" );
}