Merge branch 'storageareas' of github.com:connortechnology/ZoneMinder into storageareas
commit
8b8bcbd1e2
|
@ -439,7 +439,8 @@ sub start {
|
|||
sigprocmask(SIG_BLOCK, $blockset, $sigset) or Fatal("Can't block SIGCHLD: $!");
|
||||
Debug("forking");
|
||||
if ( my $cpid = fork() ) {
|
||||
#logReinit();
|
||||
# This logReinit is required. Not sure why.
|
||||
logReinit();
|
||||
|
||||
$process->{pid} = $cpid;
|
||||
$process->{started} = time();
|
||||
|
@ -503,6 +504,10 @@ sub start {
|
|||
sub send_stop {
|
||||
my ( $final, $process ) = @_;
|
||||
|
||||
my $sigset = POSIX::SigSet->new;
|
||||
my $blockset = POSIX::SigSet->new(SIGCHLD);
|
||||
sigprocmask(SIG_BLOCK, $blockset, $sigset) or die "dying at block...\n";
|
||||
|
||||
my $command = $process->{command};
|
||||
if ( $process->{pending} ) {
|
||||
|
||||
|
@ -511,12 +516,19 @@ sub send_stop {
|
|||
.strftime('%y/%m/%d %H:%M:%S', localtime())
|
||||
."\n"
|
||||
);
|
||||
sigprocmask(SIG_UNBLOCK, $blockset) or die "dying at unblock...\n";
|
||||
return();
|
||||
}
|
||||
|
||||
my $pid = $process->{pid};
|
||||
if ( !$pid ) {
|
||||
dPrint(ZoneMinder::Logger::ERROR, "No process with command of '$command' is running\n");
|
||||
sigprocmask(SIG_UNBLOCK, $blockset) or die "dying at unblock...\n";
|
||||
return();
|
||||
}
|
||||
if ( !$pid_hash{$pid} ) {
|
||||
dPrint(ZoneMinder::Logger::ERROR, "No process with command of '$command' pid $pid is running\n");
|
||||
sigprocmask(SIG_UNBLOCK, $blockset) or die "dying at unblock...\n";
|
||||
return();
|
||||
}
|
||||
|
||||
|
@ -525,11 +537,12 @@ sub send_stop {
|
|||
."\n"
|
||||
);
|
||||
$process->{keepalive} = !$final;
|
||||
$process->{term_sent_at} = time;
|
||||
$process->{term_sent_at} = time if ! $process->{term_sent_at};
|
||||
$process->{pending} = 0;
|
||||
$terminating_processes{$command} = $process;
|
||||
|
||||
kill('TERM', $pid);
|
||||
sigprocmask(SIG_UNBLOCK, $blockset) or die "dying at unblock...\n";
|
||||
return $pid;
|
||||
} # end sub send_stop
|
||||
|
||||
|
@ -540,6 +553,16 @@ sub check_for_processes_to_kill {
|
|||
sigprocmask(SIG_BLOCK, $blockset, $sigset) or die "dying at block...\n";
|
||||
foreach my $command ( keys %terminating_processes ) {
|
||||
my $process = $cmd_hash{$command};
|
||||
if ( ! $process ) {
|
||||
Debug("No process found for $command");
|
||||
delete $terminating_processes{$command};
|
||||
next;
|
||||
}
|
||||
if ( ! $$process{pid} ) {
|
||||
Warning("Have no pid for $command.");
|
||||
delete $terminating_processes{$command};
|
||||
next;
|
||||
}
|
||||
my $now = time;
|
||||
Debug("Have process $command at pid $$process{pid} $now - $$process{term_sent_at} = " . ( $now - $$process{term_sent_at} ));
|
||||
if ( $$process{term_sent_at} and ( $now - $$process{term_sent_at} > KILL_DELAY ) ) {
|
||||
|
@ -685,7 +708,7 @@ sub reaper {
|
|||
} # end while waitpid
|
||||
$SIG{CHLD} = \&reaper;
|
||||
$! = $saved_status;
|
||||
Debug("Leaving reaper");
|
||||
Debug("Leaving reaper");
|
||||
}
|
||||
|
||||
sub restartPending {
|
||||
|
@ -697,7 +720,7 @@ sub restartPending {
|
|||
start($process->{daemon}, @{$process->{args}});
|
||||
}
|
||||
}
|
||||
dPrint(ZoneMinder::Logger::INFO, "done restartPending");
|
||||
Debug("done restartPending");
|
||||
}
|
||||
|
||||
sub shutdownAll {
|
||||
|
@ -706,29 +729,17 @@ sub shutdownAll {
|
|||
next if ! $pid_hash{$pid};
|
||||
send_stop(1, $pid_hash{$pid});
|
||||
}
|
||||
my $count = KILL_DELAY;
|
||||
while ( (keys %terminating_processes) and $count) {
|
||||
while ( keys %terminating_processes ) {
|
||||
check_for_processes_to_kill();
|
||||
if ( %terminating_processes ) {
|
||||
Debug("Still " . %terminating_processes . ' to die. count is: ' . $count . ' sleeping');
|
||||
Debug("Still " . %terminating_processes . ' to die. sleeping');
|
||||
sleep(1);
|
||||
$count --;
|
||||
}
|
||||
}
|
||||
foreach my $command ( keys %terminating_processes ) {
|
||||
my $process = $cmd_hash{$command};
|
||||
|
||||
dPrint(ZoneMinder::Logger::WARNING, "'$$process{command}' has not stopped at "
|
||||
.strftime('%y/%m/%d %H:%M:%S', localtime())
|
||||
.' after ' . KILL_DELAY . ' seconds.'
|
||||
." Sending KILL to pid $$process{pid}\n"
|
||||
);
|
||||
kill('KILL', $$process{pid});
|
||||
dPrint(ZoneMinder::Logger::INFO, "Server shutdown at "
|
||||
.strftime('%y/%m/%d %H:%M:%S', localtime())
|
||||
."\n"
|
||||
);
|
||||
}
|
||||
dPrint(ZoneMinder::Logger::INFO, 'Server shutdown at '
|
||||
.strftime('%y/%m/%d %H:%M:%S', localtime())
|
||||
."\n"
|
||||
);
|
||||
unlink(main::SOCK_FILE) or Error("Unable to unlink " . main::SOCK_FILE .". Error message was: $!") if ( -e main::SOCK_FILE );
|
||||
unlink(ZM_PID) or Error("Unable to unlink " . ZM_PID .". Error message was: $!") if ( -e ZM_PID );
|
||||
close(CLIENT);
|
||||
|
|
|
@ -1,51 +1,66 @@
|
|||
//
|
||||
// ZoneMinder Camera Class Implementation, $Date$, $Revision$
|
||||
// Copyright (C) 2001-2008 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
//
|
||||
|
||||
#include "zm.h"
|
||||
#include "zm_camera.h"
|
||||
|
||||
Camera::Camera( unsigned int p_monitor_id, SourceType p_type, unsigned int p_width, unsigned int p_height, int p_colours, int p_subpixelorder, int p_brightness, int p_contrast, int p_hue, int p_colour, bool p_capture, bool p_record_audio ) :
|
||||
monitor_id( p_monitor_id ),
|
||||
type( p_type ),
|
||||
width( p_width),
|
||||
height( p_height ),
|
||||
colours( p_colours ),
|
||||
subpixelorder( p_subpixelorder ),
|
||||
brightness( p_brightness ),
|
||||
hue( p_hue ),
|
||||
colour( p_colour ),
|
||||
contrast( p_contrast ),
|
||||
capture( p_capture ),
|
||||
record_audio( p_record_audio )
|
||||
Camera::Camera(
|
||||
unsigned int p_monitor_id,
|
||||
SourceType p_type,
|
||||
unsigned int p_width,
|
||||
unsigned int p_height,
|
||||
int p_colours,
|
||||
int p_subpixelorder,
|
||||
int p_brightness,
|
||||
int p_contrast,
|
||||
int p_hue,
|
||||
int p_colour,
|
||||
bool p_capture,
|
||||
bool p_record_audio
|
||||
) :
|
||||
monitor_id(p_monitor_id),
|
||||
type(p_type),
|
||||
width(p_width),
|
||||
height(p_height),
|
||||
colours(p_colours),
|
||||
subpixelorder(p_subpixelorder),
|
||||
brightness(p_brightness),
|
||||
hue(p_hue),
|
||||
colour(p_colour),
|
||||
contrast(p_contrast),
|
||||
capture(p_capture),
|
||||
record_audio(p_record_audio),
|
||||
bytes(0)
|
||||
{
|
||||
pixels = width * height;
|
||||
imagesize = pixels * colours;
|
||||
|
||||
Debug(2,"New camera id: %d width: %d height: %d colours: %d subpixelorder: %d capture: %d",monitor_id,width,height,colours,subpixelorder,capture);
|
||||
|
||||
|
||||
Debug(2,"New camera id: %d width: %d height: %d colours: %d subpixelorder: %d capture: %d",
|
||||
monitor_id,width,height,colours,subpixelorder,capture);
|
||||
|
||||
/* Because many loops are unrolled and work on 16 colours/time or 4 pixels/time, we have to meet requirements */
|
||||
if((colours == ZM_COLOUR_GRAY8 || colours == ZM_COLOUR_RGB32) && (imagesize % 64) != 0) {
|
||||
if ( (colours == ZM_COLOUR_GRAY8 || colours == ZM_COLOUR_RGB32) && (imagesize % 64) != 0 ) {
|
||||
Fatal("Image size is not multiples of 64");
|
||||
} else if(colours == ZM_COLOUR_RGB24 && ((imagesize % 64) != 0 || (imagesize % 12) != 0)) {
|
||||
} else if ( colours == ZM_COLOUR_RGB24 && ((imagesize % 64) != 0 || (imagesize % 12) != 0) ) {
|
||||
Fatal("Image size is not multiples of 12 and 64");
|
||||
}
|
||||
monitor = NULL;
|
||||
monitor = NULL;
|
||||
}
|
||||
|
||||
Camera::~Camera() {
|
||||
|
@ -53,11 +68,11 @@ Camera::~Camera() {
|
|||
|
||||
Monitor *Camera::getMonitor() {
|
||||
if ( ! monitor )
|
||||
monitor = Monitor::Load( monitor_id, false, Monitor::QUERY );
|
||||
monitor = Monitor::Load(monitor_id, false, Monitor::QUERY);
|
||||
return monitor;
|
||||
}
|
||||
}
|
||||
|
||||
void Camera::setMonitor( Monitor *p_monitor ) {
|
||||
void Camera::setMonitor(Monitor *p_monitor) {
|
||||
monitor = p_monitor;
|
||||
monitor_id = monitor->Id();
|
||||
}
|
||||
|
|
|
@ -341,11 +341,13 @@ int FfmpegCamera::OpenFfmpeg() {
|
|||
|
||||
Debug(1, "Calling avformat_open_input for %s", mPath.c_str());
|
||||
|
||||
//mFormatContext = avformat_alloc_context( );
|
||||
mFormatContext = avformat_alloc_context( );
|
||||
// Speed up find_stream_info
|
||||
//FIXME can speed up initial analysis but need sensible parameters...
|
||||
//mFormatContext->probesize = 32;
|
||||
//mFormatContext->max_analyze_duration = 32;
|
||||
mFormatContext->interrupt_callback.callback = FfmpegInterruptCallback;
|
||||
mFormatContext->interrupt_callback.opaque = this;
|
||||
|
||||
if ( avformat_open_input(&mFormatContext, mPath.c_str(), NULL, &opts) != 0 )
|
||||
#endif
|
||||
|
@ -691,7 +693,7 @@ int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event
|
|||
|
||||
int frameComplete = false;
|
||||
while ( ! frameComplete ) {
|
||||
av_init_packet( &packet );
|
||||
av_init_packet(&packet);
|
||||
|
||||
ret = av_read_frame(mFormatContext, &packet);
|
||||
if ( ret < 0 ) {
|
||||
|
@ -739,11 +741,11 @@ int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event
|
|||
videoStore = NULL;
|
||||
have_video_keyframe = false;
|
||||
|
||||
monitor->SetVideoWriterEventId( 0 );
|
||||
monitor->SetVideoWriterEventId(0);
|
||||
} // end if videoStore
|
||||
} // end if end of recording
|
||||
|
||||
if ( last_event_id and ! videoStore ) {
|
||||
if ( last_event_id and !videoStore ) {
|
||||
//Instantiate the video storage module
|
||||
|
||||
if ( record_audio ) {
|
||||
|
@ -820,7 +822,7 @@ int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event
|
|||
delete videoStore;
|
||||
videoStore = NULL;
|
||||
have_video_keyframe = false;
|
||||
monitor->SetVideoWriterEventId( 0 );
|
||||
monitor->SetVideoWriterEventId(0);
|
||||
}
|
||||
|
||||
// Buffer video packets, since we are not recording.
|
||||
|
@ -828,18 +830,18 @@ int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event
|
|||
if ( packet.stream_index == mVideoStreamId ) {
|
||||
if ( keyframe ) {
|
||||
Debug(3, "Clearing queue");
|
||||
packetqueue.clearQueue( monitor->GetPreEventCount(), mVideoStreamId );
|
||||
packetqueue.queuePacket( &packet );
|
||||
packetqueue.clearQueue(monitor->GetPreEventCount(), mVideoStreamId);
|
||||
packetqueue.queuePacket(&packet);
|
||||
} else if ( packetqueue.size() ) {
|
||||
// it's a keyframe or we already have something in the queue
|
||||
packetqueue.queuePacket( &packet );
|
||||
packetqueue.queuePacket(&packet);
|
||||
}
|
||||
} else if ( packet.stream_index == mAudioStreamId ) {
|
||||
// The following lines should ensure that the queue always begins with a video keyframe
|
||||
//Debug(2, "Have audio packet, reocrd_audio is (%d) and packetqueue.size is (%d)", record_audio, packetqueue.size() );
|
||||
if ( record_audio && packetqueue.size() ) {
|
||||
// if it's audio, and we are doing audio, and there is already something in the queue
|
||||
packetqueue.queuePacket( &packet );
|
||||
packetqueue.queuePacket(&packet);
|
||||
}
|
||||
}
|
||||
} // end if recording or not
|
||||
|
@ -851,25 +853,25 @@ int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event
|
|||
if ( videoStore ) {
|
||||
|
||||
//Write the packet to our video store
|
||||
int ret = videoStore->writeVideoFramePacket( &packet );
|
||||
int ret = videoStore->writeVideoFramePacket(&packet);
|
||||
if ( ret < 0 ) { //Less than zero and we skipped a frame
|
||||
zm_av_packet_unref( &packet );
|
||||
zm_av_packet_unref(&packet);
|
||||
return 0;
|
||||
}
|
||||
have_video_keyframe = true;
|
||||
}
|
||||
} // end if keyframe or have_video_keyframe
|
||||
|
||||
Debug(4, "about to decode video" );
|
||||
Debug(4, "about to decode video");
|
||||
|
||||
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
||||
ret = avcodec_send_packet( mVideoCodecContext, &packet );
|
||||
if ( ret < 0 ) {
|
||||
av_strerror( ret, errbuf, AV_ERROR_MAX_STRING_SIZE );
|
||||
Error( "Unable to send packet at frame %d: %s, continuing", frameCount, errbuf );
|
||||
zm_av_packet_unref( &packet );
|
||||
continue;
|
||||
}
|
||||
ret = avcodec_send_packet(mVideoCodecContext, &packet);
|
||||
if ( ret < 0 ) {
|
||||
av_strerror(ret, errbuf, AV_ERROR_MAX_STRING_SIZE);
|
||||
Error("Unable to send packet at frame %d: %s, continuing", frameCount, errbuf);
|
||||
zm_av_packet_unref(&packet);
|
||||
continue;
|
||||
}
|
||||
#if HAVE_AVUTIL_HWCONTEXT_H
|
||||
if ( hwaccel ) {
|
||||
ret = avcodec_receive_frame( mVideoCodecContext, hwFrame );
|
||||
|
@ -888,11 +890,11 @@ int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event
|
|||
}
|
||||
} else {
|
||||
#endif
|
||||
ret = avcodec_receive_frame( mVideoCodecContext, mRawFrame );
|
||||
ret = avcodec_receive_frame(mVideoCodecContext, mRawFrame);
|
||||
if ( ret < 0 ) {
|
||||
av_strerror( ret, errbuf, AV_ERROR_MAX_STRING_SIZE );
|
||||
Warning( "Unable to receive frame %d: %s, continuing", frameCount, errbuf );
|
||||
zm_av_packet_unref( &packet );
|
||||
av_strerror(ret, errbuf, AV_ERROR_MAX_STRING_SIZE);
|
||||
Warning("Unable to receive frame %d: %s, continuing", frameCount, errbuf);
|
||||
zm_av_packet_unref(&packet);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -902,10 +904,10 @@ int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event
|
|||
|
||||
frameComplete = 1;
|
||||
# else
|
||||
ret = zm_avcodec_decode_video( mVideoCodecContext, mRawFrame, &frameComplete, &packet );
|
||||
ret = zm_avcodec_decode_video(mVideoCodecContext, mRawFrame, &frameComplete, &packet);
|
||||
if ( ret < 0 ) {
|
||||
av_strerror( ret, errbuf, AV_ERROR_MAX_STRING_SIZE );
|
||||
Error( "Unable to decode frame at frame %d: %s, continuing", frameCount, errbuf );
|
||||
av_strerror(ret, errbuf, AV_ERROR_MAX_STRING_SIZE);
|
||||
Error("Unable to decode frame at frame %d: %s, continuing", frameCount, errbuf);
|
||||
zm_av_packet_unref( &packet );
|
||||
continue;
|
||||
}
|
||||
|
@ -921,15 +923,13 @@ int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event
|
|||
if ( directbuffer == NULL ) {
|
||||
Error("Failed requesting writeable buffer for the captured image.");
|
||||
zm_av_packet_unref( &packet );
|
||||
return (-1);
|
||||
return -1;
|
||||
}
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
av_image_fill_arrays(mFrame->data, mFrame->linesize, directbuffer, imagePixFormat, width, height, 1);
|
||||
#else
|
||||
avpicture_fill( (AVPicture *)mFrame, directbuffer, imagePixFormat, width, height);
|
||||
#endif
|
||||
|
||||
|
||||
if (sws_scale(mConvertContext, mRawFrame->data, mRawFrame->linesize,
|
||||
0, mVideoCodecContext->height, mFrame->data, mFrame->linesize) < 0) {
|
||||
Error("Unable to convert raw format %u to target format %u at frame %d",
|
||||
|
@ -980,6 +980,10 @@ int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event
|
|||
return frameCount;
|
||||
} // end FfmpegCamera::CaptureAndRecord
|
||||
|
||||
int FfmpegCamera::FfmpegInterruptCallback(void *ctx) {
|
||||
//FfmpegCamera* camera = reinterpret_cast<FfmpegCamera*>(ctx);
|
||||
|
||||
return zm_terminate;
|
||||
}
|
||||
|
||||
#endif // HAVE_LIBAVFORMAT
|
||||
|
|
|
@ -99,11 +99,12 @@ class FfmpegCamera : public Camera {
|
|||
void Initialise();
|
||||
void Terminate();
|
||||
|
||||
static int FfmpegInterruptCallback(void*ctx);
|
||||
|
||||
int PrimeCapture();
|
||||
int PreCapture();
|
||||
int Capture( Image &image );
|
||||
int CaptureAndRecord( Image &image, timeval recording, char* event_directory );
|
||||
int PostCapture();
|
||||
};
|
||||
|
||||
#endif // ZM_FFMPEG_CAMERA_H
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
|
||||
#include "zm.h"
|
||||
#include "zm_signal.h"
|
||||
#include "zm_libvlc_camera.h"
|
||||
|
||||
#if HAVE_LIBVLC
|
||||
|
@ -39,7 +40,7 @@ void LibvlcUnlockBuffer(void* opaque, void* picture, void *const *planes) {
|
|||
LibvlcPrivateData* data = reinterpret_cast<LibvlcPrivateData*>(opaque);
|
||||
|
||||
bool newFrame = false;
|
||||
for( uint32_t i = 0; i < data->bufferSize; i++ ) {
|
||||
for( unsigned int i=0; i < data->bufferSize; i++ ) {
|
||||
if ( data->buffer[i] != data->prevBuffer[i] ) {
|
||||
newFrame = true;
|
||||
break;
|
||||
|
@ -56,11 +57,38 @@ void LibvlcUnlockBuffer(void* opaque, void* picture, void *const *planes) {
|
|||
}
|
||||
}
|
||||
|
||||
LibvlcCamera::LibvlcCamera( int p_id, const std::string &p_path, const std::string &p_method, const std::string &p_options, int p_width, int p_height, int p_colours, int p_brightness, int p_contrast, int p_hue, int p_colour, bool p_capture, bool p_record_audio ) :
|
||||
Camera( p_id, LIBVLC_SRC, p_width, p_height, p_colours, ZM_SUBPIX_ORDER_DEFAULT_FOR_COLOUR(p_colours), p_brightness, p_contrast, p_hue, p_colour, p_capture, p_record_audio ),
|
||||
mPath( p_path ),
|
||||
mMethod( p_method ),
|
||||
mOptions( p_options )
|
||||
LibvlcCamera::LibvlcCamera(
|
||||
int p_id,
|
||||
const std::string &p_path,
|
||||
const std::string &p_method,
|
||||
const std::string &p_options,
|
||||
int p_width,
|
||||
int p_height,
|
||||
int p_colours,
|
||||
int p_brightness,
|
||||
int p_contrast,
|
||||
int p_hue,
|
||||
int p_colour,
|
||||
bool p_capture,
|
||||
bool p_record_audio
|
||||
) :
|
||||
Camera(
|
||||
p_id,
|
||||
LIBVLC_SRC,
|
||||
p_width,
|
||||
p_height,
|
||||
p_colours,
|
||||
ZM_SUBPIX_ORDER_DEFAULT_FOR_COLOUR(p_colours),
|
||||
p_brightness,
|
||||
p_contrast,
|
||||
p_hue,
|
||||
p_colour,
|
||||
p_capture,
|
||||
p_record_audio
|
||||
),
|
||||
mPath(p_path),
|
||||
mMethod(p_method),
|
||||
mOptions(p_options)
|
||||
{
|
||||
mLibvlcInstance = NULL;
|
||||
mLibvlcMedia = NULL;
|
||||
|
@ -70,15 +98,15 @@ LibvlcCamera::LibvlcCamera( int p_id, const std::string &p_path, const std::stri
|
|||
mOptArgV = NULL;
|
||||
|
||||
/* Has to be located inside the constructor so other components such as zma will receive correct colours and subpixel order */
|
||||
if(colours == ZM_COLOUR_RGB32) {
|
||||
if ( colours == ZM_COLOUR_RGB32 ) {
|
||||
subpixelorder = ZM_SUBPIX_ORDER_BGRA;
|
||||
mTargetChroma = "RV32";
|
||||
mBpp = 4;
|
||||
} else if(colours == ZM_COLOUR_RGB24) {
|
||||
} else if ( colours == ZM_COLOUR_RGB24 ) {
|
||||
subpixelorder = ZM_SUBPIX_ORDER_BGR;
|
||||
mTargetChroma = "RV24";
|
||||
mBpp = 3;
|
||||
} else if(colours == ZM_COLOUR_GRAY8) {
|
||||
} else if ( colours == ZM_COLOUR_GRAY8 ) {
|
||||
subpixelorder = ZM_SUBPIX_ORDER_NONE;
|
||||
mTargetChroma = "GREY";
|
||||
mBpp = 1;
|
||||
|
@ -118,11 +146,13 @@ void LibvlcCamera::Initialise() {
|
|||
|
||||
void LibvlcCamera::Terminate() {
|
||||
libvlc_media_player_stop(mLibvlcMediaPlayer);
|
||||
if(mLibvlcData.buffer != NULL) {
|
||||
if ( mLibvlcData.buffer ) {
|
||||
zm_freealigned(mLibvlcData.buffer);
|
||||
mLibvlcData.buffer = NULL;
|
||||
}
|
||||
if(mLibvlcData.prevBuffer != NULL) {
|
||||
if ( mLibvlcData.prevBuffer ) {
|
||||
zm_freealigned(mLibvlcData.prevBuffer);
|
||||
mLibvlcData.prevBuffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -139,6 +169,8 @@ int LibvlcCamera::PrimeCapture() {
|
|||
else if ( Method() == "rtpRtspHttp" )
|
||||
opVect.push_back("--rtsp-http");
|
||||
|
||||
opVect.push_back("--no-audio");
|
||||
|
||||
if ( opVect.size() > 0 ) {
|
||||
mOptArgV = new char*[opVect.size()];
|
||||
Debug(2, "Number of Options: %d",opVect.size());
|
||||
|
@ -149,17 +181,23 @@ int LibvlcCamera::PrimeCapture() {
|
|||
}
|
||||
}
|
||||
|
||||
mLibvlcInstance = libvlc_new (opVect.size(), (const char* const*)mOptArgV);
|
||||
if ( mLibvlcInstance == NULL )
|
||||
Fatal("Unable to create libvlc instance due to: %s", libvlc_errmsg());
|
||||
mLibvlcInstance = libvlc_new(opVect.size(), (const char* const*)mOptArgV);
|
||||
if ( mLibvlcInstance == NULL ) {
|
||||
Error("Unable to create libvlc instance due to: %s", libvlc_errmsg());
|
||||
return -1;
|
||||
}
|
||||
|
||||
mLibvlcMedia = libvlc_media_new_location(mLibvlcInstance, mPath.c_str());
|
||||
if(mLibvlcMedia == NULL)
|
||||
Fatal("Unable to open input %s due to: %s", mPath.c_str(), libvlc_errmsg());
|
||||
if ( mLibvlcMedia == NULL ) {
|
||||
Error("Unable to open input %s due to: %s", mPath.c_str(), libvlc_errmsg());
|
||||
return -1;
|
||||
}
|
||||
|
||||
mLibvlcMediaPlayer = libvlc_media_player_new_from_media(mLibvlcMedia);
|
||||
if(mLibvlcMediaPlayer == NULL)
|
||||
Fatal("Unable to create player for %s due to: %s", mPath.c_str(), libvlc_errmsg());
|
||||
if ( mLibvlcMediaPlayer == NULL ) {
|
||||
Error("Unable to create player for %s due to: %s", mPath.c_str(), libvlc_errmsg());
|
||||
return -1;
|
||||
}
|
||||
|
||||
libvlc_video_set_format(mLibvlcMediaPlayer, mTargetChroma.c_str(), width, height, width * mBpp);
|
||||
libvlc_video_set_callbacks(mLibvlcMediaPlayer, &LibvlcLockBuffer, &LibvlcUnlockBuffer, NULL, &mLibvlcData);
|
||||
|
@ -177,13 +215,18 @@ int LibvlcCamera::PrimeCapture() {
|
|||
}
|
||||
|
||||
int LibvlcCamera::PreCapture() {
|
||||
return(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Should not return -1 as cancels capture. Always wait for image if available.
|
||||
int LibvlcCamera::Capture( Image &image ) {
|
||||
while(!mLibvlcData.newImage.getValueImmediate())
|
||||
int LibvlcCamera::Capture(Image &image) {
|
||||
|
||||
// newImage is a mutex/condition based flag to tell us when there is an image available
|
||||
while( !mLibvlcData.newImage.getValueImmediate() ) {
|
||||
if (zm_terminate)
|
||||
return 0;
|
||||
mLibvlcData.newImage.getUpdatedValue(1);
|
||||
}
|
||||
|
||||
mLibvlcData.mutex.lock();
|
||||
image.Assign(width, height, colours, subpixelorder, mLibvlcData.buffer, width * height * mBpp);
|
||||
|
@ -193,13 +236,12 @@ int LibvlcCamera::Capture( Image &image ) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
// Should not return -1 as cancels capture. Always wait for image if available.
|
||||
int LibvlcCamera::CaptureAndRecord(Image &image, timeval recording, char* event_directory) {
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LibvlcCamera::PostCapture() {
|
||||
return(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // HAVE_LIBVLC
|
||||
|
|
|
@ -41,8 +41,7 @@ struct LibvlcPrivateData
|
|||
ThreadData<bool> newImage;
|
||||
};
|
||||
|
||||
class LibvlcCamera : public Camera
|
||||
{
|
||||
class LibvlcCamera : public Camera {
|
||||
protected:
|
||||
std::string mPath;
|
||||
std::string mMethod;
|
||||
|
|
|
@ -330,7 +330,7 @@ bool MonitorStream::sendFrame(const char *filepath, struct timeval *timestamp) {
|
|||
fprintf(stdout, "Content-Length: %d\r\n", img_buffer_size);
|
||||
if ( fwrite(img_buffer, img_buffer_size, 1, stdout) != 1 ) {
|
||||
if ( ! zm_terminate )
|
||||
Error("Unable to send stream frame: %s", strerror(errno));
|
||||
Warning("Unable to send stream frame: %s", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
fputs("\r\n\r\n", stdout);
|
||||
|
@ -407,7 +407,7 @@ bool MonitorStream::sendFrame(Image *image, struct timeval *timestamp) {
|
|||
if ( fwrite(img_buffer, img_buffer_size, 1, stdout) != 1 ) {
|
||||
if ( !zm_terminate ){
|
||||
// If the pipe was closed, we will get signalled SIGPIPE to exit, which will set zm_terminate
|
||||
Error("Unable to send stream frame: %s", strerror(errno));
|
||||
Warning("Unable to send stream frame: %s", strerror(errno));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -142,31 +142,29 @@ template <class T> const T ThreadData<T>::getValue() const {
|
|||
mMutex.lock();
|
||||
const T valueCopy = mValue;
|
||||
mMutex.unlock();
|
||||
return( valueCopy );
|
||||
return valueCopy;
|
||||
}
|
||||
|
||||
template <class T> T ThreadData<T>::setValue( const T value ) {
|
||||
template <class T> T ThreadData<T>::setValue(const T value) {
|
||||
mMutex.lock();
|
||||
const T valueCopy = mValue = value;
|
||||
mMutex.unlock();
|
||||
return( valueCopy );
|
||||
return valueCopy;
|
||||
}
|
||||
|
||||
template <class T> const T ThreadData<T>::getUpdatedValue() const {
|
||||
Debug( 8, "Waiting for value update, %p", this );
|
||||
Debug(8, "Waiting for value update, %p", this);
|
||||
mMutex.lock();
|
||||
mChanged = false;
|
||||
//do {
|
||||
mCondition.wait();
|
||||
//} while ( !mChanged );
|
||||
mCondition.wait();
|
||||
const T valueCopy = mValue;
|
||||
mMutex.unlock();
|
||||
Debug( 9, "Got value update, %p", this );
|
||||
return( valueCopy );
|
||||
Debug(9, "Got value update, %p", this);
|
||||
return valueCopy;
|
||||
}
|
||||
|
||||
template <class T> const T ThreadData<T>::getUpdatedValue( double secs ) const {
|
||||
Debug( 8, "Waiting for value update, %.2f secs, %p", secs, this );
|
||||
template <class T> const T ThreadData<T>::getUpdatedValue(double secs) const {
|
||||
Debug(8, "Waiting for value update, %.2f secs, %p", secs, this);
|
||||
mMutex.lock();
|
||||
mChanged = false;
|
||||
//do {
|
||||
|
@ -174,41 +172,41 @@ template <class T> const T ThreadData<T>::getUpdatedValue( double secs ) const {
|
|||
//} while ( !mChanged );
|
||||
const T valueCopy = mValue;
|
||||
mMutex.unlock();
|
||||
Debug( 9, "Got value update, %p", this );
|
||||
return( valueCopy );
|
||||
Debug(9, "Got value update, %p", this );
|
||||
return valueCopy;
|
||||
}
|
||||
|
||||
template <class T> const T ThreadData<T>::getUpdatedValue( int secs ) const {
|
||||
Debug( 8, "Waiting for value update, %d secs, %p", secs, this );
|
||||
template <class T> const T ThreadData<T>::getUpdatedValue(int secs) const {
|
||||
Debug(8, "Waiting for value update, %d secs, %p", secs, this);
|
||||
mMutex.lock();
|
||||
mChanged = false;
|
||||
//do {
|
||||
mCondition.wait( secs );
|
||||
mCondition.wait(secs);
|
||||
//} while ( !mChanged );
|
||||
const T valueCopy = mValue;
|
||||
mMutex.unlock();
|
||||
Debug( 9, "Got value update, %p", this );
|
||||
return( valueCopy );
|
||||
Debug(9, "Got value update, %p", this);
|
||||
return valueCopy;
|
||||
}
|
||||
|
||||
template <class T> void ThreadData<T>::updateValueSignal( const T value ) {
|
||||
Debug( 8, "Updating value with signal, %p", this );
|
||||
template <class T> void ThreadData<T>::updateValueSignal(const T value) {
|
||||
Debug(8, "Updating value with signal, %p", this);
|
||||
mMutex.lock();
|
||||
mValue = value;
|
||||
mChanged = true;
|
||||
mCondition.signal();
|
||||
mMutex.unlock();
|
||||
Debug( 9, "Updated value, %p", this );
|
||||
Debug(9, "Updated value, %p", this);
|
||||
}
|
||||
|
||||
template <class T> void ThreadData<T>::updateValueBroadcast( const T value ) {
|
||||
Debug( 8, "Updating value with broadcast, %p", this );
|
||||
Debug(8, "Updating value with broadcast, %p", this);
|
||||
mMutex.lock();
|
||||
mValue = value;
|
||||
mChanged = true;
|
||||
mCondition.broadcast();
|
||||
mMutex.unlock();
|
||||
Debug( 9, "Updated value, %p", this );
|
||||
Debug(9, "Updated value, %p", this);
|
||||
}
|
||||
|
||||
Thread::Thread() :
|
||||
|
|
|
@ -125,6 +125,9 @@ class EventsController extends AppController {
|
|||
$event['Event']['Next'] = $event_neighbors['next']['Event']['Id'];
|
||||
$event['Event']['Prev'] = $event_neighbors['prev']['Event']['Id'];
|
||||
|
||||
$event['Event']['fileExists'] = $this->Event->fileExists($event['Event']);
|
||||
$event['Event']['fileSize'] = $this->Event->fileSize($event['Event']);
|
||||
|
||||
# Also get the previous and next events for the same monitor
|
||||
$event_monitor_neighbors = $this->Event->find('neighbors', array(
|
||||
'conditions'=>array('Event.MonitorId'=>$event['Event']['MonitorId'])
|
||||
|
|
|
@ -30,20 +30,37 @@ class HostController extends AppController {
|
|||
));
|
||||
}
|
||||
|
||||
function getAuthHash() {
|
||||
if ( $zmOptAuth == '1' ) {
|
||||
require_once '../../../includes/auth.php';
|
||||
$this->set(array(
|
||||
'auth_hash' => generateAuthHash(ZM_AUTH_HASH_IPS),
|
||||
'_serialize' => array('auth_hash')
|
||||
) );
|
||||
} else {
|
||||
$this->set(array(
|
||||
'auth_hash' => '',
|
||||
'_serialize' => array('auth_hash')
|
||||
) );
|
||||
function getCredentials() {
|
||||
// ignore debug warnings from other functions
|
||||
$this->view='Json';
|
||||
$credentials = "";
|
||||
$appendPassword = 0;
|
||||
|
||||
$this->loadModel('Config');
|
||||
$isZmAuth = $this->Config->find('first',array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_OPT_USE_AUTH')))['Config']['Value'];
|
||||
|
||||
if ($isZmAuth) {
|
||||
$zmAuthRelay = $this->Config->find('first',array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_AUTH_RELAY')))['Config']['Value'];
|
||||
if ($zmAuthRelay == 'hashed') {
|
||||
$zmAuthHashIps= $this->Config->find('first',array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_AUTH_HASH_IPS')))['Config']['Value'];
|
||||
$credentials = 'auth='.generateAuthHash($zmAuthHashIps);
|
||||
}
|
||||
elseif ($zmAuthRelay == 'plain') {
|
||||
// user will need to append the store password here
|
||||
$credentials = "user=".$this->Session->read('user.Username')."&pass=";
|
||||
$appendPassword = 1;
|
||||
}
|
||||
elseif ($zmAuthRelay == 'none') {
|
||||
$credentials = "user=".$this->Session->read('user.Username');
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->set(array(
|
||||
'credentials'=> $credentials,
|
||||
'append_password'=>$appendPassword,
|
||||
'_serialize' => array('credentials', 'append_password')
|
||||
) );
|
||||
}
|
||||
|
||||
|
||||
// If $mid is set, only return disk usage for that monitor
|
||||
// Else, return an array of total disk usage, and per-monitor
|
||||
|
|
|
@ -44,7 +44,15 @@ class Event extends AppModel {
|
|||
'conditions' => '',
|
||||
'fields' => '',
|
||||
'order' => ''
|
||||
)
|
||||
),
|
||||
'Storage' => array(
|
||||
'className' => 'Storage',
|
||||
'joinTable' => 'Storage',
|
||||
'foreignKey' => 'StorageId',
|
||||
'conditions' => '',
|
||||
'fields' => '',
|
||||
'order' => ''
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -92,4 +100,40 @@ class Event extends AppModel {
|
|||
),
|
||||
);
|
||||
|
||||
public function Relative_Path($event) {
|
||||
$event_path = '';
|
||||
|
||||
if ( $event['Scheme'] == 'Deep' ) {
|
||||
$event_path = $event['MonitorId'] .'/'.strftime('%y/%m/%d/%H/%M/%S', strtotime($event['StartTime']));
|
||||
} else if ( $event['Scheme'] == 'Medium' ) {
|
||||
$event_path = $event['MonitorId'] .'/'.strftime('%Y-%m-%d', strtotime($event['StartTime'])) . '/'.$event['Id'];
|
||||
} else {
|
||||
$event_path = $event['MonitorId'] .'/'.$event['Id'];
|
||||
}
|
||||
|
||||
return $event_path;
|
||||
} // end function Relative_Path()
|
||||
|
||||
|
||||
public function fileExists($event) {
|
||||
//$data = $this->findById($id);
|
||||
//return $data['Event']['dataset_filename'];
|
||||
$storage = $this->Storage->findById($event['StorageId']);
|
||||
|
||||
if ( $event['DefaultVideo'] ) {
|
||||
if ( file_exists($storage['Storage']['Path'].'/'.$this->Relative_Path($event).'/'.$event['DefaultVideo']) ) {
|
||||
return 1;
|
||||
} else {
|
||||
Logger::Debug("FIle does not exist at " . $storage['Storage']['Path'].'/'.$this->Relative_Path($event).'/'.$event['DefaultVideo'] );
|
||||
}
|
||||
} else {
|
||||
Logger::Debug("No DefaultVideo in Event" . $this->Event);
|
||||
return 0;
|
||||
}
|
||||
} // end function fileExists($event)
|
||||
|
||||
public function fileSize($event) {
|
||||
$storage = $this->Storage->findById($event['StorageId']);
|
||||
return filesize($storage['Storage']['Path'].'/'.$this->Relative_Path($event).'/'.$event['DefaultVideo']);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
App::uses('AppModel', 'Model');
|
||||
/**
|
||||
* Storage Model
|
||||
*
|
||||
* @property Event $Event
|
||||
* @property Zone $Zone
|
||||
*/
|
||||
class Storage extends AppModel {
|
||||
|
||||
/**
|
||||
* Use table
|
||||
*
|
||||
* @var mixed False or table name
|
||||
*/
|
||||
public $useTable = 'Storage';
|
||||
|
||||
/**
|
||||
* Primary key field
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $primaryKey = 'Id';
|
||||
|
||||
/**
|
||||
* Display field
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $displayField = 'Name';
|
||||
|
||||
public $recursive = -1;
|
||||
|
||||
/**
|
||||
* Validation rules
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $validate = array(
|
||||
'Id' => array(
|
||||
'numeric' => array(
|
||||
'rule' => array('numeric'),
|
||||
//'message' => 'Your custom message here',
|
||||
//'allowEmpty' => false,
|
||||
//'required' => false,
|
||||
//'last' => false, // Stop validation after this rule
|
||||
//'on' => 'create', // Limit validation to 'create' or 'update' operations
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
//The Associations below have been created with all possible keys, those that are not needed can be removed
|
||||
|
||||
/**
|
||||
* hasMany associations
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $belongsTo = array(
|
||||
'Server' => array(
|
||||
'className' => 'Server',
|
||||
'foreignKey' => 'ServerId',
|
||||
'dependent' => false,
|
||||
'conditions' => '',
|
||||
'fields' => '',
|
||||
'order' => '',
|
||||
)
|
||||
);
|
||||
}
|
|
@ -1 +1 @@
|
|||
Subproject commit c3976f1478c681b0bbc132ec3a3e82c3984eeed5
|
||||
Subproject commit 0bd63fb464957080ead342db58ca9e01532cf1ef
|
|
@ -522,6 +522,94 @@ class Event {
|
|||
return '<a href="?view=event&eid='. $this->{'Id'}.'">'.$text.'</a>';
|
||||
}
|
||||
|
||||
public function file_exists() {
|
||||
if ( file_exists( $this->Path().'/'.$this->DefaultVideo() ) ) {
|
||||
return true;
|
||||
}
|
||||
$Storage= $this->Storage();
|
||||
$Server = $Storage->ServerId() ? $Storage->Server() : $this->Monitor()->Server();
|
||||
if ( $Server->Id() != ZM_SERVER_ID ) {
|
||||
|
||||
$url = $Server->Url() . '/zm/api/events/'.$this->{'Id'}.'.json';
|
||||
if ( ZM_OPT_USE_AUTH ) {
|
||||
if ( ZM_AUTH_RELAY == 'hashed' ) {
|
||||
$url .= '?auth='.generateAuthHash( ZM_AUTH_HASH_IPS );
|
||||
} elseif ( ZM_AUTH_RELAY == 'plain' ) {
|
||||
$url = '?user='.$_SESSION['username'];
|
||||
$url = '?pass='.$_SESSION['password'];
|
||||
} elseif ( ZM_AUTH_RELAY == 'none' ) {
|
||||
$url = '?user='.$_SESSION['username'];
|
||||
}
|
||||
}
|
||||
Logger::Debug("sending command to $url");
|
||||
// use key 'http' even if you send the request to https://...
|
||||
$options = array(
|
||||
'http' => array(
|
||||
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
|
||||
'method' => 'GET',
|
||||
'content' => ''
|
||||
)
|
||||
);
|
||||
$context = stream_context_create($options);
|
||||
try {
|
||||
$result = file_get_contents($url, false, $context);
|
||||
if ($result === FALSE) { /* Handle error */
|
||||
Error("Error restarting zmc using $url");
|
||||
}
|
||||
$event_data = json_decode($result,true);
|
||||
Logger::Debug(print_r($event_data['event']['Event'],1));
|
||||
return $event_data['event']['Event']['fileExists'];
|
||||
} catch ( Exception $e ) {
|
||||
Error("Except $e thrown trying to get event data");
|
||||
}
|
||||
} # end if not local
|
||||
return false;
|
||||
} # end public function file_exists()
|
||||
|
||||
public function file_size() {
|
||||
if ( file_exists($this->Path().'/'.$this->DefaultVideo()) ) {
|
||||
return filesize($this->Path().'/'.$this->DefaultVideo());
|
||||
}
|
||||
$Storage= $this->Storage();
|
||||
$Server = $Storage->ServerId() ? $Storage->Server() : $this->Monitor()->Server();
|
||||
if ( $Server->Id() != ZM_SERVER_ID ) {
|
||||
|
||||
$url = $Server->Url() . '/zm/api/events/'.$this->{'Id'}.'.json';
|
||||
if ( ZM_OPT_USE_AUTH ) {
|
||||
if ( ZM_AUTH_RELAY == 'hashed' ) {
|
||||
$url .= '?auth='.generateAuthHash( ZM_AUTH_HASH_IPS );
|
||||
} elseif ( ZM_AUTH_RELAY == 'plain' ) {
|
||||
$url = '?user='.$_SESSION['username'];
|
||||
$url = '?pass='.$_SESSION['password'];
|
||||
} elseif ( ZM_AUTH_RELAY == 'none' ) {
|
||||
$url = '?user='.$_SESSION['username'];
|
||||
}
|
||||
}
|
||||
Logger::Debug("sending command to $url");
|
||||
// use key 'http' even if you send the request to https://...
|
||||
$options = array(
|
||||
'http' => array(
|
||||
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
|
||||
'method' => 'GET',
|
||||
'content' => ''
|
||||
)
|
||||
);
|
||||
$context = stream_context_create($options);
|
||||
try {
|
||||
$result = file_get_contents($url, false, $context);
|
||||
if ($result === FALSE) { /* Handle error */
|
||||
Error("Error restarting zmc using $url");
|
||||
}
|
||||
$event_data = json_decode($result,true);
|
||||
Logger::Debug(print_r($event_data['event']['Event'],1));
|
||||
return $event_data['event']['Event']['fileSize'];
|
||||
} catch ( Exception $e ) {
|
||||
Error("Except $e thrown trying to get event data");
|
||||
}
|
||||
} # end if not local
|
||||
return 0;
|
||||
} # end public function file_size()
|
||||
|
||||
} # end class
|
||||
|
||||
?>
|
||||
|
|
|
@ -172,6 +172,7 @@ class Storage {
|
|||
}
|
||||
return $this->{'DiskSpace'};
|
||||
} // end function event_disk_space
|
||||
|
||||
public function Server() {
|
||||
if ( ! array_key_exists('Server',$this) ) {
|
||||
$this->{'Server'}= new Server( $this->{'ServerId'} );
|
||||
|
|
|
@ -195,16 +195,15 @@ $html .= htmlSelect( 'Status[]', $status_options,
|
|||
$Monitor = new Monitor($monitors[$i]);
|
||||
ini_set('track_errors', 'on');
|
||||
$php_errormsg = '';
|
||||
@preg_match($_SESSION['MonitorName'], '');
|
||||
if ( !$php_errormsg ) {
|
||||
# regexp is valid
|
||||
if ( !preg_match($_SESSION['MonitorName'], $Monitor->Name()) ) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if ( ! strstr($Monitor->Name(), $_SESSION['MonitorName']) ) {
|
||||
continue;
|
||||
}
|
||||
$regexp = $_SESSION['MonitorName'];
|
||||
|
||||
@preg_match($regexp, '');
|
||||
if ( $php_errormsg ) {
|
||||
$regexp = '/'.preg_quote($regexp,'/').'/i';
|
||||
}
|
||||
|
||||
if ( !preg_match($regexp, $Monitor->Name()) ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -212,16 +211,14 @@ $html .= htmlSelect( 'Status[]', $status_options,
|
|||
$Monitor = new Monitor($monitors[$i]);
|
||||
ini_set('track_errors', 'on');
|
||||
$php_errormsg = '';
|
||||
@preg_match($_SESSION['Source'], '');
|
||||
if ( !$php_errormsg ) {
|
||||
# regexp is valid
|
||||
if ( !preg_match($_SESSION['Source'], $Monitor->Source()) ) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if ( ! strstr($Monitor->Source(), $_SESSION['Source']) ) {
|
||||
continue;
|
||||
}
|
||||
$regexp = $_SESSION['Source'];
|
||||
|
||||
@preg_match($regexp, '');
|
||||
if ( $php_errormsg ) {
|
||||
$regexp = '/'.preg_quote($regexp,'/').'/i';
|
||||
}
|
||||
if ( !preg_match($regexp, $Monitor->Source()) ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,14 +27,15 @@ ob_end_clean();
|
|||
noCacheHeaders();
|
||||
xhtmlHeaders( __FILE__, translate('Console') );
|
||||
|
||||
if ( !isset($_REQUEST['minTime']) && !isset($_REQUEST['maxTime']) ) {
|
||||
$time = time();
|
||||
$maxTime = strftime('%FT%T',$time - 3600);
|
||||
$minTime = strftime('%FT%T',$time - (2*3600) );
|
||||
} else if ( isset($_REQUEST['minTime']) ) {
|
||||
if ( isset($_REQUEST['minTime']) ) {
|
||||
$minTime = validHtmlStr($_REQUEST['minTime']);
|
||||
} else if ( isset($_REQUEST['maxTime']) ) {
|
||||
} else {
|
||||
$minTime = strftime('%FT%T',time() - (2*3600) );
|
||||
}
|
||||
if ( isset($_REQUEST['maxTime']) ) {
|
||||
$maxTime = validHtmlStr($_REQUEST['maxTime']);
|
||||
} else {
|
||||
$maxTime = strftime('%FT%T',time() - 3600);
|
||||
}
|
||||
|
||||
$filter = array(
|
||||
|
@ -63,8 +64,6 @@ parseFilter($filter);
|
|||
$filterQuery = $filter['query'];
|
||||
Logger::Debug($filterQuery);
|
||||
|
||||
|
||||
|
||||
$eventsSql = 'SELECT *,
|
||||
UNIX_TIMESTAMP(E.StartTime) AS StartTimeSecs,
|
||||
UNIX_TIMESTAMP(EndTime) AS EndTimeSecs
|
||||
|
@ -91,7 +90,7 @@ $EventsByMonitor = array();
|
|||
while( $event = $result->fetch(PDO::FETCH_ASSOC) ) {
|
||||
$Event = new Event($event);
|
||||
if ( ! isset($EventsByMonitor[$event['MonitorId']]) )
|
||||
$EventsByMonitor[$event['MonitorId']] = array( 'Events'=>array(), 'MinGap'=>0, 'MaxGap'=>0, 'FileMissing'=>0, 'ZeroSize'=>array() );
|
||||
$EventsByMonitor[$event['MonitorId']] = array( 'Events'=>array(), 'MinGap'=>0, 'MaxGap'=>0, 'FileMissing'=>array(), 'ZeroSize'=>array() );
|
||||
|
||||
if ( count($EventsByMonitor[$event['MonitorId']]['Events']) ) {
|
||||
$last_event = end($EventsByMonitor[$event['MonitorId']]['Events']);
|
||||
|
@ -104,9 +103,9 @@ while( $event = $result->fetch(PDO::FETCH_ASSOC) ) {
|
|||
$EventsByMonitor[$event['MonitorId']]['MaxGap'] = $gap;
|
||||
|
||||
} # end if has previous events
|
||||
if ( ! file_exists( $Event->Path().'/'.$Event->DefaultVideo() ) ) {
|
||||
$EventsByMonitor[$event['MonitorId']]['FileMissing'] += 1;
|
||||
} else if ( ! filesize( $Event->Path().'/'.$Event->DefaultVideo() ) ) {
|
||||
if ( ! $Event->file_exists() ) {
|
||||
$EventsByMonitor[$event['MonitorId']]['FileMissing'][] = $Event;
|
||||
} else if ( ! $Event->file_size() ) {
|
||||
$EventsByMonitor[$event['MonitorId']]['ZeroSize'][] = $Event;
|
||||
}
|
||||
$EventsByMonitor[$event['MonitorId']]['Events'][] = $Event;
|
||||
|
@ -169,12 +168,33 @@ for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) {
|
|||
} else {
|
||||
$MinGap = 0;
|
||||
$MaxGap = 0;
|
||||
$FileMissing = 0;
|
||||
$ZeroSize = 0;
|
||||
$FileMissing = array();
|
||||
$ZeroSize = array();
|
||||
$FirstEvent = 0;
|
||||
$LastEvent = 0;
|
||||
}
|
||||
|
||||
if ( count($FileMissing) ) {
|
||||
$FileMissing_filter = array(
|
||||
'Query' => array(
|
||||
'terms' => array(
|
||||
array('attr'=>'Id','op'=>'IN', 'val'=>implode(',',array_map(function($Event){return $Event->Id();},$FileMissing)))
|
||||
)
|
||||
)
|
||||
);
|
||||
parseFilter($FileMissing_filter);
|
||||
}
|
||||
if ( count($ZeroSize) ) {
|
||||
$ZeroSize_filter = array(
|
||||
'Query' => array(
|
||||
'terms' => array(
|
||||
array('attr'=>'Id','op'=>'IN', 'val'=>implode(',',array_map(function($Event){return $Event->Id();},$ZeroSize)))
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
<tr id="<?php echo 'monitor_id-'.$monitor['Id'] ?>" title="<?php echo $monitor['Id'] ?>">
|
||||
<td class="colId"><a href="<?php echo $montagereview_link ?>"><?php echo $monitor['Id'] ?></a></td>
|
||||
|
@ -195,8 +215,12 @@ for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) {
|
|||
<td class="colLastEvent"><?php echo $LastEvent ? $LastEvent->link_to($LastEvent->Id().' at ' . $LastEvent->StartTime()) : 'none'?></td>
|
||||
<td class="colMinGap"><?php echo $MinGap ?></td>
|
||||
<td class="colMaxGap"><?php echo $MaxGap ?></td>
|
||||
<td class="colFileMissing<?php echo $FileMissing ? ' errorText' : ''?>"><?php echo $FileMissing ?></td>
|
||||
<td class="colZeroSize<?php echo count($ZeroSize) ? ' errorText' : ''?>"><?php echo count($ZeroSize) ?></td>
|
||||
<td class="colFileMissing<?php echo count($FileMissing) ? ' errorText' : ''?>">
|
||||
<?php echo count($FileMissing) ? '<a href="?view='.ZM_WEB_EVENTS_VIEW .'&page=1'.$FileMissing_filter['query'].'">'.count($FileMissing).'</a>' : '0' ?>
|
||||
</td>
|
||||
<td class="colZeroSize<?php echo count($ZeroSize) ? ' errorText' : ''?>">
|
||||
<?php echo count($ZeroSize) ? '<a href="?view='.ZM_WEB_EVENTS_VIEW .'&page=1'.$ZeroSize_filter['query'].'">'.count($FileMissing).'</a>' : '0' ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
} # end for each monitor
|
||||
|
|
Loading…
Reference in New Issue