2003-03-26 19:57:29 +08:00
//
2003-04-22 22:15:01 +08:00
// ZoneMinder Event Class Implementation, $Date$, $Revision$
2003-03-26 19:57:29 +08:00
// Copyright (C) 2003 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.
//
2003-04-22 22:15:01 +08:00
# include <fcntl.h>
# include <sys/socket.h>
# include <sys/un.h>
# include <sys/uio.h>
# include <getopt.h>
2004-01-28 01:03:45 +08:00
# include <glob.h>
2003-04-22 22:15:01 +08:00
2003-03-26 19:57:29 +08:00
# include "zm.h"
# include "zm_db.h"
2004-03-04 23:05:54 +08:00
# include "zm_mpeg.h"
2003-03-26 19:57:29 +08:00
# include "zm_event.h"
# include "zm_monitor.h"
2003-04-22 22:15:01 +08:00
# include "zmf.h"
2004-02-16 04:07:16 +08:00
bool Event : : initialised = false ;
bool Event : : timestamp_on_capture ;
2003-03-26 19:57:29 +08:00
Event : : Event ( Monitor * p_monitor , struct timeval p_start_time ) : monitor ( p_monitor ) , start_time ( p_start_time )
{
2004-02-16 04:07:16 +08:00
if ( ! initialised )
Initialise ( ) ;
2003-07-04 04:39:47 +08:00
static char sql [ BUFSIZ ] ;
2003-03-26 19:57:29 +08:00
static char start_time_str [ 32 ] ;
strftime ( start_time_str , sizeof ( start_time_str ) , " %Y-%m-%d %H:%M:%S " , localtime ( & start_time . tv_sec ) ) ;
2003-10-08 20:54:35 +08:00
sprintf ( sql , " insert into Events ( MonitorId, Name, StartTime ) values ( %d, 'New Event', '%s' ) " , monitor - > Id ( ) , start_time_str ) ;
2003-03-26 19:57:29 +08:00
if ( mysql_query ( & dbconn , sql ) )
{
2003-04-15 17:04:38 +08:00
Error ( ( " Can't insert event: %s " , mysql_error ( & dbconn ) ) ) ;
2003-03-26 19:57:29 +08:00
exit ( mysql_errno ( & dbconn ) ) ;
}
id = mysql_insert_id ( & dbconn ) ;
2003-09-23 17:52:45 +08:00
end_time . tv_sec = 0 ;
2003-03-26 19:57:29 +08:00
frames = 0 ;
alarm_frames = 0 ;
tot_score = 0 ;
max_score = 0 ;
2003-07-04 20:31:36 +08:00
sprintf ( path , " %s/%s/%d " , ( const char * ) config . Item ( ZM_DIR_EVENTS ) , monitor - > Name ( ) , id ) ;
2003-03-26 19:57:29 +08:00
struct stat statbuf ;
errno = 0 ;
stat ( path , & statbuf ) ;
if ( errno = = ENOENT | | errno = = ENOTDIR )
{
if ( mkdir ( path , 0755 ) )
{
2003-04-15 17:04:38 +08:00
Error ( ( " Can't make %s: %s " , path , strerror ( errno ) ) ) ;
2003-03-26 19:57:29 +08:00
}
}
}
Event : : ~ Event ( )
{
2003-07-04 04:39:47 +08:00
static char sql [ BUFSIZ ] ;
2003-03-26 19:57:29 +08:00
static char end_time_str [ 32 ] ;
struct DeltaTimeval delta_time ;
2003-05-16 18:17:05 +08:00
DELTA_TIMEVAL ( delta_time , end_time , start_time , DT_PREC_2 ) ;
2003-03-26 19:57:29 +08:00
strftime ( end_time_str , sizeof ( end_time_str ) , " %Y-%m-%d %H:%M:%S " , localtime ( & end_time . tv_sec ) ) ;
2003-09-23 17:52:45 +08:00
sprintf ( sql , " update Events set Name='Event-%d', EndTime = '%s', Length = %s%ld.%02ld, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d where Id = %d " , id , end_time_str , delta_time . positive ? " " : " - " , delta_time . sec , delta_time . fsec , frames , alarm_frames , tot_score , ( int ) ( alarm_frames ? ( tot_score / alarm_frames ) : 0 ) , max_score , id ) ;
2003-03-26 19:57:29 +08:00
if ( mysql_query ( & dbconn , sql ) )
{
2003-04-15 17:04:38 +08:00
Error ( ( " Can't update event: %s " , mysql_error ( & dbconn ) ) ) ;
2003-03-26 19:57:29 +08:00
exit ( mysql_errno ( & dbconn ) ) ;
}
}
2003-04-22 22:15:01 +08:00
int Event : : sd = - 1 ;
bool Event : : OpenFrameSocket ( int monitor_id )
{
if ( sd > 0 )
{
close ( sd ) ;
}
sd = socket ( AF_UNIX , SOCK_STREAM , 0 ) ;
if ( sd < 0 )
{
Error ( ( " Can't create socket: %s " , strerror ( errno ) ) ) ;
return ( false ) ;
}
2004-03-04 20:50:42 +08:00
int socket_buffer_size = ( int ) config . Item ( ZM_FRAME_SOCKET_SIZE ) ;
if ( socket_buffer_size > 0 )
{
if ( setsockopt ( sd , SOL_SOCKET , SO_SNDBUF , & socket_buffer_size , sizeof ( socket_buffer_size ) ) < 0 )
{
Error ( ( " Can't get socket buffer size to %d, error = %s " , socket_buffer_size , strerror ( errno ) ) ) ;
close ( sd ) ;
sd = - 1 ;
return ( false ) ;
}
}
2003-04-22 22:15:01 +08:00
int flags ;
if ( ( flags = fcntl ( sd , F_GETFL ) ) < 0 )
{
Error ( ( " Can't get socket flags, error = %s " , strerror ( errno ) ) ) ;
close ( sd ) ;
sd = - 1 ;
return ( false ) ;
}
flags | = O_NONBLOCK ;
if ( fcntl ( sd , F_SETFL , flags ) < 0 )
{
Error ( ( " Can't set socket flags, error = %s " , strerror ( errno ) ) ) ;
close ( sd ) ;
sd = - 1 ;
return ( false ) ;
}
char sock_path [ PATH_MAX ] = " " ;
2003-07-04 20:31:36 +08:00
sprintf ( sock_path , " %s/zmf-%d.sock " , ( const char * ) config . Item ( ZM_PATH_SOCKS ) , monitor_id ) ;
2003-04-22 22:15:01 +08:00
struct sockaddr_un addr ;
strcpy ( addr . sun_path , sock_path ) ;
addr . sun_family = AF_UNIX ;
if ( connect ( sd , ( struct sockaddr * ) & addr , strlen ( addr . sun_path ) + sizeof ( addr . sun_family ) ) < 0 )
{
Warning ( ( " Can't connect: %s " , strerror ( errno ) ) ) ;
close ( sd ) ;
sd = - 1 ;
return ( false ) ;
}
Info ( ( " Opened connection to frame server " ) ) ;
return ( true ) ;
}
bool Event : : ValidateFrameSocket ( int monitor_id )
{
if ( sd < 0 )
{
return ( OpenFrameSocket ( monitor_id ) ) ;
}
return ( true ) ;
}
bool Event : : SendFrameImage ( const Image * image , bool alarm_frame )
{
if ( ! ValidateFrameSocket ( monitor - > Id ( ) ) )
{
return ( false ) ;
}
static int jpg_buffer_size = 0 ;
2003-05-02 23:03:16 +08:00
static unsigned char jpg_buffer [ ZM_MAX_IMAGE_SIZE ] ;
2003-04-22 22:15:01 +08:00
image - > EncodeJpeg ( jpg_buffer , & jpg_buffer_size ) ;
static FrameHeader frame_header ;
frame_header . event_id = id ;
frame_header . frame_id = frames ;
frame_header . alarm_frame = alarm_frame ;
frame_header . image_length = jpg_buffer_size ;
struct iovec iovecs [ 2 ] ;
iovecs [ 0 ] . iov_base = & frame_header ;
iovecs [ 0 ] . iov_len = sizeof ( frame_header ) ;
iovecs [ 1 ] . iov_base = jpg_buffer ;
iovecs [ 1 ] . iov_len = jpg_buffer_size ;
2004-01-15 05:26:47 +08:00
ssize_t writev_size = sizeof ( frame_header ) + jpg_buffer_size ;
ssize_t writev_result = writev ( sd , iovecs , sizeof ( iovecs ) / sizeof ( * iovecs ) ) ;
if ( writev_result ! = writev_size )
2003-04-22 22:15:01 +08:00
{
2004-01-15 05:26:47 +08:00
if ( writev_result < 0 )
2003-04-22 22:15:01 +08:00
{
2004-01-15 05:26:47 +08:00
if ( errno = = EAGAIN )
{
Warning ( ( " Blocking write detected " ) ) ;
}
else
{
Error ( ( " Can't write frame: %s " , strerror ( errno ) ) ) ;
close ( sd ) ;
sd = - 1 ;
}
2003-04-22 22:15:01 +08:00
}
else
{
2004-01-15 05:26:47 +08:00
Error ( ( " Incomplete frame write: %d of %d bytes written " , writev_result , writev_size ) ) ;
2003-04-22 22:15:01 +08:00
close ( sd ) ;
sd = - 1 ;
}
return ( false ) ;
}
2003-10-19 17:48:10 +08:00
Debug ( 1 , ( " Wrote frame image, %d bytes " , jpg_buffer_size ) ) ;
2003-04-22 22:15:01 +08:00
return ( true ) ;
}
2004-02-16 04:07:16 +08:00
bool Event : : WriteFrameImage ( Image * image , struct timeval timestamp , const char * event_file , bool alarm_frame )
2003-04-22 22:15:01 +08:00
{
2004-02-16 19:12:28 +08:00
if ( timestamp_on_capture )
2004-02-16 04:07:16 +08:00
{
2004-02-16 19:12:28 +08:00
if ( ! ( bool ) config . Item ( ZM_OPT_FRAME_SERVER ) | | ! SendFrameImage ( image , alarm_frame ) )
{
image - > WriteJpeg ( event_file ) ;
}
2004-02-16 04:07:16 +08:00
}
2004-02-16 19:12:28 +08:00
else
2003-04-22 22:15:01 +08:00
{
2004-02-16 19:12:28 +08:00
Image ts_image ( * image ) ;
monitor - > TimestampImage ( & ts_image , timestamp . tv_sec ) ;
2004-02-19 23:51:02 +08:00
if ( ! ( bool ) config . Item ( ZM_OPT_FRAME_SERVER ) | | ! SendFrameImage ( & ts_image , alarm_frame ) )
2004-02-16 19:12:28 +08:00
{
ts_image . WriteJpeg ( event_file ) ;
}
2003-04-22 22:15:01 +08:00
}
return ( true ) ;
}
2004-02-16 04:07:16 +08:00
void Event : : AddFrames ( int n_frames , Image * * images , struct timeval * * timestamps )
2003-04-17 23:38:21 +08:00
{
2003-11-05 22:49:55 +08:00
static char sql [ BUFSIZ ] ;
2004-01-28 01:03:45 +08:00
strcpy ( sql , " insert into Frames ( EventId, FrameId, Delta ) values " ) ;
2003-04-17 23:38:21 +08:00
for ( int i = 0 ; i < n_frames ; i + + )
{
frames + + ;
2003-04-22 22:15:01 +08:00
2003-04-17 23:38:21 +08:00
static char event_file [ PATH_MAX ] ;
2004-01-28 01:03:45 +08:00
sprintf ( event_file , " %s/%03d-capture.jpg " , path , frames ) ;
2003-04-22 22:15:01 +08:00
Debug ( 1 , ( " Writing pre-capture frame %d " , frames ) ) ;
2004-02-16 04:07:16 +08:00
WriteFrameImage ( images [ i ] , * ( timestamps [ i ] ) , event_file ) ;
2003-04-17 23:38:21 +08:00
struct DeltaTimeval delta_time ;
2003-05-16 18:17:05 +08:00
DELTA_TIMEVAL ( delta_time , * ( timestamps [ i ] ) , start_time , DT_PREC_2 ) ;
2003-04-17 23:38:21 +08:00
2004-01-28 01:03:45 +08:00
sprintf ( sql + strlen ( sql ) , " ( %d, %d, %s%ld.%02ld ), " , id , frames , delta_time . positive ? " " : " - " , delta_time . sec , delta_time . fsec ) ;
2003-04-17 23:38:21 +08:00
}
Debug ( 1 , ( " Adding %d frames to DB " , n_frames ) ) ;
* ( sql + strlen ( sql ) - 2 ) = ' \0 ' ;
if ( mysql_query ( & dbconn , sql ) )
{
Error ( ( " Can't insert frames: %s " , mysql_error ( & dbconn ) ) ) ;
exit ( mysql_errno ( & dbconn ) ) ;
}
}
2004-02-16 04:07:16 +08:00
void Event : : AddFrame ( Image * image , struct timeval timestamp , unsigned int score , Image * alarm_image )
2003-03-26 19:57:29 +08:00
{
frames + + ;
static char event_file [ PATH_MAX ] ;
2004-01-28 01:03:45 +08:00
sprintf ( event_file , " %s/%03d-capture.jpg " , path , frames ) ;
2003-04-22 22:15:01 +08:00
Debug ( 1 , ( " Writing capture frame %d " , frames ) ) ;
2004-02-16 04:07:16 +08:00
WriteFrameImage ( image , timestamp , event_file ) ;
2003-03-26 19:57:29 +08:00
struct DeltaTimeval delta_time ;
2003-05-16 18:17:05 +08:00
DELTA_TIMEVAL ( delta_time , timestamp , start_time , DT_PREC_2 ) ;
2003-03-26 19:57:29 +08:00
2003-04-17 23:38:21 +08:00
Debug ( 1 , ( " Adding frame %d to DB " , frames ) ) ;
2003-07-04 04:39:47 +08:00
static char sql [ BUFSIZ ] ;
2004-01-28 01:03:45 +08:00
sprintf ( sql , " insert into Frames ( EventId, FrameId, AlarmFrame, Delta, Score ) values ( %d, %d, %d, %s%ld.%02ld, %d ) " , id , frames , score > 0 , delta_time . positive ? " " : " - " , delta_time . sec , delta_time . fsec , score ) ;
2003-03-26 19:57:29 +08:00
if ( mysql_query ( & dbconn , sql ) )
{
2003-04-15 17:04:38 +08:00
Error ( ( " Can't insert frame: %s " , mysql_error ( & dbconn ) ) ) ;
2003-03-26 19:57:29 +08:00
exit ( mysql_errno ( & dbconn ) ) ;
}
2003-11-21 18:38:41 +08:00
if ( score )
2003-03-26 19:57:29 +08:00
{
end_time = timestamp ;
alarm_frames + + ;
2003-04-22 22:15:01 +08:00
2003-03-26 19:57:29 +08:00
tot_score + = score ;
if ( score > max_score )
max_score = score ;
2003-11-21 18:38:41 +08:00
if ( alarm_image )
{
2004-01-28 01:03:45 +08:00
sprintf ( event_file , " %s/%03d-analyse.jpg " , path , frames ) ;
2003-11-21 18:38:41 +08:00
Debug ( 1 , ( " Writing analysis frame %d " , frames ) ) ;
2004-02-16 04:07:16 +08:00
WriteFrameImage ( alarm_image , timestamp , event_file , true ) ;
2003-11-21 18:38:41 +08:00
}
2003-03-26 19:57:29 +08:00
}
2004-01-28 01:03:45 +08:00
2004-01-28 01:07:20 +08:00
if ( ( bool ) config . Item ( ZM_RECORD_DIAG_IMAGES ) )
2004-01-28 01:03:45 +08:00
{
char diag_glob [ PATH_MAX ] = " " ;
sprintf ( diag_glob , " %s/%s/diag-*.jpg " , ( const char * ) config . Item ( ZM_DIR_EVENTS ) , monitor - > Name ( ) ) ;
glob_t pglob ;
int glob_status = glob ( diag_glob , 0 , 0 , & pglob ) ;
if ( glob_status ! = 0 )
{
if ( glob_status < 0 )
{
Error ( ( " Can't glob '%s': %s " , diag_glob , strerror ( errno ) ) ) ;
}
else
{
Info ( ( " Can't glob '%s': %s " , diag_glob , glob_status ) ) ;
}
}
else
{
char new_diag_path [ PATH_MAX ] = " " ;
for ( int i = 0 ; i < pglob . gl_pathc ; i + + )
{
char * diag_path = pglob . gl_pathv [ i ] ;
char * diag_file = strstr ( diag_path , " diag- " ) ;
if ( diag_file )
{
sprintf ( new_diag_path , " %s/%03d-%s " , path , frames , diag_file ) ;
if ( rename ( diag_path , new_diag_path ) < 0 )
{
Error ( ( " Can't rename '%s' to '%s': %s " , diag_path , new_diag_path , strerror ( errno ) ) ) ;
}
}
}
}
globfree ( & pglob ) ;
}
2003-03-26 19:57:29 +08:00
}
2004-03-04 23:05:54 +08:00
void Event : : StreamEvent ( int event_id , int rate , int scale )
2003-03-26 19:57:29 +08:00
{
2003-07-04 04:39:47 +08:00
static char sql [ BUFSIZ ] ;
2004-02-06 05:58:44 +08:00
static char eventpath [ PATH_MAX ] ;
2004-01-28 01:03:45 +08:00
2004-02-06 05:58:44 +08:00
sprintf ( sql , " select M.Id, M.Name from Events as E inner join Monitors as M on E.MonitorId = M.Id where E.Id = %d " , event_id ) ;
2003-03-26 19:57:29 +08:00
if ( mysql_query ( & dbconn , sql ) )
{
2003-04-15 17:04:38 +08:00
Error ( ( " Can't run query: %s " , mysql_error ( & dbconn ) ) ) ;
2003-03-26 19:57:29 +08:00
exit ( mysql_errno ( & dbconn ) ) ;
}
MYSQL_RES * result = mysql_store_result ( & dbconn ) ;
if ( ! result )
{
2003-04-15 17:04:38 +08:00
Error ( ( " Can't use query result: %s " , mysql_error ( & dbconn ) ) ) ;
2003-03-26 19:57:29 +08:00
exit ( mysql_errno ( & dbconn ) ) ;
}
2004-02-06 05:58:44 +08:00
MYSQL_ROW dbrow = mysql_fetch_row ( result ) ;
if ( mysql_errno ( & dbconn ) )
{
Error ( ( " Can't fetch row: %s " , mysql_error ( & dbconn ) ) ) ;
exit ( mysql_errno ( & dbconn ) ) ;
}
sprintf ( eventpath , " %s/%s/%s/%d " , ZM_PATH_WEB , ( const char * ) config . Item ( ZM_DIR_EVENTS ) , dbrow [ 1 ] , event_id ) ;
mysql_free_result ( result ) ;
sprintf ( sql , " select FrameId, EventId, Delta from Frames where EventId = %d order by FrameId " , event_id ) ;
if ( mysql_query ( & dbconn , sql ) )
{
Error ( ( " Can't run query: %s " , mysql_error ( & dbconn ) ) ) ;
exit ( mysql_errno ( & dbconn ) ) ;
}
result = mysql_store_result ( & dbconn ) ;
if ( ! result )
{
Error ( ( " Can't use query result: %s " , mysql_error ( & dbconn ) ) ) ;
exit ( mysql_errno ( & dbconn ) ) ;
}
2003-03-26 19:57:29 +08:00
2004-03-04 23:05:54 +08:00
fprintf ( stdout , " Content-Type: multipart/x-mixed-replace;boundary=ZoneMinderFrame \r \n \r \n " ) ;
fprintf ( stdout , " --ZoneMinderFrame \n " ) ;
2003-03-26 19:57:29 +08:00
2003-10-19 17:48:10 +08:00
//int n_frames = mysql_num_rows( result );
//Info(( "Got %d frames, at rate %d, scale %d", n_frames, rate, scale ));
2003-03-26 19:57:29 +08:00
FILE * fdj = NULL ;
int n_bytes = 0 ;
2003-10-16 17:00:53 +08:00
static unsigned char buffer [ ZM_MAX_IMAGE_SIZE ] ;
2003-05-27 16:59:11 +08:00
double last_delta = 0 ;
2003-10-16 17:00:53 +08:00
struct timeval now , last_now ;
struct DeltaTimeval delta_time ;
gettimeofday ( & now , & dummy_tz ) ;
2004-02-06 05:58:44 +08:00
for ( int i = 0 ; dbrow = mysql_fetch_row ( result ) ; i + + )
2003-03-26 19:57:29 +08:00
{
2003-10-10 18:38:30 +08:00
if ( rate )
2003-05-23 00:34:22 +08:00
{
2004-02-06 17:21:57 +08:00
double this_delta = atof ( dbrow [ 2 ] ) ;
2003-05-27 16:59:11 +08:00
if ( i )
2003-05-23 00:34:22 +08:00
{
2003-10-16 17:00:53 +08:00
gettimeofday ( & now , & dummy_tz ) ;
2004-02-06 17:21:57 +08:00
double frame_delta = this_delta - last_delta ;
2003-10-16 17:00:53 +08:00
DELTA_TIMEVAL ( delta_time , now , last_now , DT_PREC_6 ) ;
int delay = ( int ) ( ( DT_GRAN_1000000 * frame_delta ) ) - delta_time . delta ;
2004-02-16 03:47:23 +08:00
delay = ( delay * ZM_RATE_SCALE ) / rate ;
2003-10-16 17:00:53 +08:00
//Info(( "FD:%lf, DDT:%d, D:%d, N:%d.%d, LN:%d.%d", frame_delta, delta_time.delta, delay, now.tv_sec, now.tv_usec, last_now.tv_sec, last_now.tv_usec ));
if ( delay > 0 )
usleep ( delay ) ;
2003-05-23 00:34:22 +08:00
}
2004-02-06 17:21:57 +08:00
last_delta = this_delta ;
2003-10-16 17:00:53 +08:00
gettimeofday ( & last_now , & dummy_tz ) ;
2003-05-23 00:34:22 +08:00
}
2003-10-16 17:00:53 +08:00
static char filepath [ PATH_MAX ] ;
2004-02-06 05:58:44 +08:00
sprintf ( filepath , " %s/%03d-capture.jpg " , eventpath , atoi ( dbrow [ 0 ] ) ) ;
2003-10-16 17:00:53 +08:00
2004-03-04 23:05:54 +08:00
fprintf ( stdout , " Content-type: image/jpeg \n \n " ) ;
if ( scale = = 100 )
2003-03-26 19:57:29 +08:00
{
2003-10-16 17:00:53 +08:00
if ( ( fdj = fopen ( filepath , " r " ) ) )
{
while ( ( n_bytes = fread ( buffer , 1 , sizeof ( buffer ) , fdj ) ) )
{
2004-03-04 23:05:54 +08:00
write ( fileno ( stdout ) , buffer , n_bytes ) ;
2003-10-16 17:00:53 +08:00
}
fclose ( fdj ) ;
}
else
2003-03-26 19:57:29 +08:00
{
2003-10-16 17:00:53 +08:00
Error ( ( " Can't open %s: %s " , filepath , strerror ( errno ) ) ) ;
2003-03-26 19:57:29 +08:00
}
}
else
{
2003-10-16 17:00:53 +08:00
Image image ( filepath ) ;
image . Scale ( scale ) ;
image . EncodeJpeg ( buffer , & n_bytes ) ;
2004-03-04 23:05:54 +08:00
write ( fileno ( stdout ) , buffer , n_bytes ) ;
}
fprintf ( stdout , " \n --ZoneMinderFrame \n " ) ;
fflush ( stdout ) ;
}
if ( mysql_errno ( & dbconn ) )
{
Error ( ( " Can't fetch row: %s " , mysql_error ( & dbconn ) ) ) ;
exit ( mysql_errno ( & dbconn ) ) ;
}
// Yadda yadda
mysql_free_result ( result ) ;
}
# if HAVE_LIBAVCODEC
void Event : : StreamMpeg ( int event_id , const char * format , int bit_rate , int rate , int scale )
{
static char sql [ BUFSIZ ] ;
static char eventpath [ PATH_MAX ] ;
sprintf ( sql , " select M.Id, M.Name,max(F.Delta)-min(F.Delta) as Duration, count(F.Id) as Frames from Events as E inner join Monitors as M on E.MonitorId = M.Id inner join Frames as F on F.EventId = E.Id where E.Id = %d group by F.EventId " , event_id ) ;
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 ) ) ;
}
MYSQL_ROW dbrow = mysql_fetch_row ( result ) ;
if ( mysql_errno ( & dbconn ) )
{
Error ( ( " Can't fetch row: %s " , mysql_error ( & dbconn ) ) ) ;
exit ( mysql_errno ( & dbconn ) ) ;
}
sprintf ( eventpath , " %s/%s/%s/%d " , ZM_PATH_WEB , ( const char * ) config . Item ( ZM_DIR_EVENTS ) , dbrow [ 1 ] , event_id ) ;
int fps = ( ( atoi ( dbrow [ 3 ] ) / atoi ( dbrow [ 2 ] ) ) * rate ) / ZM_RATE_SCALE ;
if ( rate )
{
if ( fps < = 0 )
fps = 1 ;
else if ( fps > 30 )
fps = 30 ;
}
else
{
fps = 30 ;
}
Info ( ( " Duration:%d, Frames:%d, FPS:%d " , atoi ( dbrow [ 2 ] ) , atoi ( dbrow [ 3 ] ) , fps ) ) ;
mysql_free_result ( result ) ;
sprintf ( sql , " select FrameId, EventId, Delta from Frames where EventId = %d order by FrameId " , event_id ) ;
if ( mysql_query ( & dbconn , sql ) )
{
Error ( ( " Can't run query: %s " , mysql_error ( & dbconn ) ) ) ;
exit ( mysql_errno ( & dbconn ) ) ;
}
result = mysql_store_result ( & dbconn ) ;
if ( ! result )
{
Error ( ( " Can't use query result: %s " , mysql_error ( & dbconn ) ) ) ;
exit ( mysql_errno ( & dbconn ) ) ;
}
fprintf ( stdout , " Content-type: video/x-ms-asf \r \n \r \n " ) ;
VideoStream * vid_stream = 0 ;
for ( int i = 0 ; dbrow = mysql_fetch_row ( result ) ; i + + )
{
static char filepath [ PATH_MAX ] ;
sprintf ( filepath , " %s/%03d-capture.jpg " , eventpath , atoi ( dbrow [ 0 ] ) ) ;
Image image ( filepath ) ;
if ( ! vid_stream )
{
vid_stream = new VideoStream ( " pipe: " , format , bit_rate , fps , image . Colours ( ) , ( image . Width ( ) * scale ) / ZM_SCALE_SCALE , ( image . Height ( ) * scale ) / ZM_SCALE_SCALE ) ;
2003-03-26 19:57:29 +08:00
}
2004-03-04 23:05:54 +08:00
if ( scale ! = 100 )
{
image . Scale ( scale ) ;
}
double pts = vid_stream - > EncodeFrame ( image . Buffer ( ) , image . Size ( ) ) ;
2003-03-26 19:57:29 +08:00
}
if ( mysql_errno ( & dbconn ) )
{
2003-04-15 17:04:38 +08:00
Error ( ( " Can't fetch row: %s " , mysql_error ( & dbconn ) ) ) ;
2003-03-26 19:57:29 +08:00
exit ( mysql_errno ( & dbconn ) ) ;
}
// Yadda yadda
mysql_free_result ( result ) ;
2004-03-04 23:05:54 +08:00
delete vid_stream ;
2003-03-26 19:57:29 +08:00
}
2004-03-04 23:05:54 +08:00
# endif // HAVE_LIBAVCODEC