Merge branch 'storageareas' of github.com:ConnorTechnology/ZoneMinder into storageareas

This commit is contained in:
Isaac Connor 2019-07-23 10:14:34 -04:00
commit d3d0579454
22 changed files with 368 additions and 193 deletions

View File

@ -351,6 +351,7 @@ CREATE INDEX `Groups_Monitors_MonitorId_idx` ON `Groups_Monitors` (`MonitorId`);
DROP TABLE IF EXISTS `Logs`; DROP TABLE IF EXISTS `Logs`;
CREATE TABLE `Logs` ( CREATE TABLE `Logs` (
`Id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`TimeKey` decimal(16,6) NOT NULL, `TimeKey` decimal(16,6) NOT NULL,
`Component` varchar(32) NOT NULL, `Component` varchar(32) NOT NULL,
`ServerId` int(10) unsigned, `ServerId` int(10) unsigned,
@ -360,6 +361,7 @@ CREATE TABLE `Logs` (
`Message` text NOT NULL, `Message` text NOT NULL,
`File` varchar(255) DEFAULT NULL, `File` varchar(255) DEFAULT NULL,
`Line` smallint(5) unsigned DEFAULT NULL, `Line` smallint(5) unsigned DEFAULT NULL,
PRIMARY KEY (`Id`),
KEY `TimeKey` (`TimeKey`) KEY `TimeKey` (`TimeKey`)
) ENGINE=@ZM_MYSQL_ENGINE@; ) ENGINE=@ZM_MYSQL_ENGINE@;
@ -589,6 +591,7 @@ CREATE INDEX `Servers_Name_idx` ON `Servers` (`Name`);
DROP TABLE IF EXISTS `Stats`; DROP TABLE IF EXISTS `Stats`;
CREATE TABLE `Stats` ( CREATE TABLE `Stats` (
`Id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`MonitorId` int(10) unsigned NOT NULL default '0', `MonitorId` int(10) unsigned NOT NULL default '0',
`ZoneId` int(10) unsigned NOT NULL default '0', `ZoneId` int(10) unsigned NOT NULL default '0',
`EventId` BIGINT UNSIGNED NOT NULL, `EventId` BIGINT UNSIGNED NOT NULL,
@ -605,6 +608,7 @@ CREATE TABLE `Stats` (
`MinY` smallint(5) unsigned NOT NULL default '0', `MinY` smallint(5) unsigned NOT NULL default '0',
`MaxY` smallint(5) unsigned NOT NULL default '0', `MaxY` smallint(5) unsigned NOT NULL default '0',
`Score` smallint(5) unsigned NOT NULL default '0', `Score` smallint(5) unsigned NOT NULL default '0',
PRIMARY KEY (`Id`),
KEY `EventId` (`EventId`), KEY `EventId` (`EventId`),
KEY `MonitorId` (`MonitorId`), KEY `MonitorId` (`MonitorId`),
KEY `ZoneId` (`ZoneId`) KEY `ZoneId` (`ZoneId`)
@ -745,7 +749,7 @@ insert into Storage VALUES (NULL, '@ZM_DIR_EVENTS@', 'Default', 'local', NULL, N
-- --
-- Create a default admin user. -- Create a default admin user.
-- --
insert into Users VALUES (NULL,'admin',password('admin'),'',1,'View','Edit','Edit','Edit','Edit','Edit','Edit','','',0,1); insert into Users VALUES (NULL,'admin','$2b$12$NHZsm6AM2f2LQVROriz79ul3D6DnmFiZC.ZK5eqbF.ZWfwH9bqUJ6','',1,'View','Edit','Edit','Edit','Edit','Edit','Edit','','',0,1);
-- --
-- Add a sample filter to purge the oldest 100 events when the disk is 95% full -- Add a sample filter to purge the oldest 100 events when the disk is 95% full

27
db/zm_update-1.33.12.sql Normal file
View File

@ -0,0 +1,27 @@
--
-- Add primary keys for Logs and Stats tables
--
SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Logs'
AND column_name = 'Id'
) > 0,
"SELECT 'Column Id already exists in Logs'",
"ALTER TABLE `Logs` ADD COLUMN `Id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY (`Id`)"
));
PREPARE stmt FROM @s;
EXECUTE stmt;
SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Stats'
AND column_name = 'Id'
) > 0,
"SELECT 'Column Id already exists in Stats'",
"ALTER TABLE `Stats` ADD COLUMN `Id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY (`Id`)"
));
PREPARE stmt FROM @s;
EXECUTE stmt;

View File

@ -23,7 +23,7 @@
%global _hardened_build 1 %global _hardened_build 1
Name: zoneminder Name: zoneminder
Version: 1.33.9 Version: 1.33.12
Release: 1%{?dist} Release: 1%{?dist}
Summary: A camera monitoring and analysis tool Summary: A camera monitoring and analysis tool
Group: System Environment/Daemons Group: System Environment/Daemons
@ -411,6 +411,9 @@ EOF
%dir %attr(755,nginx,nginx) %{_localstatedir}/spool/zoneminder-upload %dir %attr(755,nginx,nginx) %{_localstatedir}/spool/zoneminder-upload
%changelog %changelog
* Sun Jul 07 2019 Andrew Bauer <zonexpertconsulting@outlook.com> - 1.33.12-1
- Bump to 1.33.12 Development
* Sun Jun 23 2019 Andrew Bauer <zonexpertconsulting@outlook.com> - 1.33.9-1 * Sun Jun 23 2019 Andrew Bauer <zonexpertconsulting@outlook.com> - 1.33.9-1
- Bump to 1.33.9 Development - Bump to 1.33.9 Development

View File

@ -728,6 +728,7 @@ sub substituteTags {
} }
if ( $text =~ s/%EIMOD%//g ) { if ( $text =~ s/%EIMOD%//g ) {
$text =~ s/%EIMOD%/$url?view=frame&mid=$Event->{MonitorId}&eid=$Event->{Id}&fid=objdetect/g;
my $path = $Event->Path().'/objdetect.jpg'; my $path = $Event->Path().'/objdetect.jpg';
if ( -e $path ) { if ( -e $path ) {
push @$attachments_ref, { type=>'image/jpeg', path=>$path }; push @$attachments_ref, { type=>'image/jpeg', path=>$path };

View File

@ -21,6 +21,9 @@
#include "zm_ffmpeg.h" #include "zm_ffmpeg.h"
#include "zm_image.h" #include "zm_image.h"
#include "zm_rgb.h" #include "zm_rgb.h"
extern "C" {
#include "libavutil/pixdesc.h"
}
#if HAVE_LIBAVCODEC || HAVE_LIBAVUTIL || HAVE_LIBSWSCALE #if HAVE_LIBAVCODEC || HAVE_LIBAVUTIL || HAVE_LIBSWSCALE
@ -70,14 +73,14 @@ static bool bInit = false;
void FFMPEGInit() { void FFMPEGInit() {
if ( !bInit ) { if ( !bInit ) {
if ( logDebugging() ) if ( logDebugging() && config.log_ffmpeg ) {
av_log_set_level( AV_LOG_DEBUG ); av_log_set_level( AV_LOG_DEBUG );
else av_log_set_callback(log_libav_callback);
Info("Enabling ffmpeg logs, as LOG_DEBUG+LOG_FFMPEG are enabled in options");
} else {
Info("Not enabling ffmpeg logs, as LOG_FFMPEG and/or LOG_DEBUG is disabled in options, or this monitor not part of your debug targets");
av_log_set_level( AV_LOG_QUIET ); av_log_set_level( AV_LOG_QUIET );
if ( config.log_ffmpeg ) }
av_log_set_callback(log_libav_callback);
else
Info("Not enabling ffmpeg logs, as LOG_FFMPEG is disabled in options");
#if LIBAVFORMAT_VERSION_CHECK(58, 9, 0, 64, 0) #if LIBAVFORMAT_VERSION_CHECK(58, 9, 0, 64, 0)
#else #else
av_register_all(); av_register_all();
@ -295,25 +298,6 @@ void zm_dump_video_frame(const AVFrame *frame, const char *text) {
frame->pts frame->pts
); );
} }
void zm_dump_frame(const AVFrame *frame,const char *text) {
Debug(1, "%s: format %d %s sample_rate %" PRIu32 " nb_samples %d channels %d"
" duration %" PRId64
" layout %d pts %" PRId64,
text,
frame->format,
av_get_sample_fmt_name((AVSampleFormat)frame->format),
frame->sample_rate,
frame->nb_samples,
#if LIBAVCODEC_VERSION_CHECK(56, 8, 0, 60, 100)
frame->channels,
frame->pkt_duration,
#else
0, 0,
#endif
frame->channel_layout,
frame->pts
);
}
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0) #if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
void zm_dump_codecpar ( const AVCodecParameters *par ) { void zm_dump_codecpar ( const AVCodecParameters *par ) {
@ -536,6 +520,45 @@ int zm_receive_frame(AVCodecContext *context, AVFrame *frame, AVPacket &packet)
return 0; return 0;
} // end int zm_receive_frame(AVCodecContext *context, AVFrame *frame, AVPacket &packet) } // end int zm_receive_frame(AVCodecContext *context, AVFrame *frame, AVPacket &packet)
int zm_send_frame(AVCodecContext *ctx, AVFrame *frame, AVPacket &packet) {
int ret;
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
if ( (ret = avcodec_send_frame(ctx, frame)) < 0 ) {
Error("Could not send frame (error '%s')",
av_make_error_string(ret).c_str());
zm_av_packet_unref(&packet);
return 0;
}
if ( (ret = avcodec_receive_packet(ctx, &packet)) < 0 ) {
if ( AVERROR(EAGAIN) == ret ) {
// The codec may need more samples than it has, perfectly valid
Debug(2, "Codec not ready to give us a packet");
} else {
Error("Could not recieve packet (error %d = '%s')", ret,
av_make_error_string(ret).c_str());
}
zm_av_packet_unref(&packet);
return 0;
}
#else
int data_present;
if ( (ret = avcodec_encode_audio2(
ctx, &packet, frame, &data_present)) < 0 ) {
Error("Could not encode frame (error '%s')",
av_make_error_string(ret).c_str());
zm_av_packet_unref(&packet);
return 0;
}
if ( !data_present ) {
Debug(2, "Not ready to out a frame yet.");
zm_av_packet_unref(&packet);
return 0;
}
#endif
return 1;
} // wend zm_send_frame
void dumpPacket(AVStream *stream, AVPacket *pkt, const char *text) { void dumpPacket(AVStream *stream, AVPacket *pkt, const char *text) {
char b[10240]; char b[10240];

View File

@ -299,7 +299,36 @@ void zm_dump_codec(const AVCodecContext *codec);
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0) #if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
void zm_dump_codecpar(const AVCodecParameters *par); void zm_dump_codecpar(const AVCodecParameters *par);
#endif #endif
void zm_dump_frame(const AVFrame *frame, const char *text="Frame"); #if LIBAVCODEC_VERSION_CHECK(56, 8, 0, 60, 100)
#define zm_dump_frame(frame, text) Debug(1, "%s: format %d %s sample_rate %" PRIu32 " nb_samples %d channels %d" \
" duration %" PRId64 \
" layout %d pts %" PRId64,\
text, \
frame->format, \
av_get_sample_fmt_name((AVSampleFormat)frame->format), \
frame->sample_rate, \
frame->nb_samples, \
frame->channels, \
frame->pkt_duration, \
frame->channel_layout, \
frame->pts \
);
#else
#define zm_dump_frame(frame, text) Debug(1, "%s: format %d %s sample_rate %" PRIu32 " nb_samples %d channels %d" \
" duration %" PRId64 \
" layout %d pts %" PRId64, \
text, \
frame->format, \
av_get_sample_fmt_name((AVSampleFormat)frame->format), \
frame->sample_rate, \
frame->nb_samples, \
0, 0, \
frame->channel_layout, \
frame->pts \
);
#endif
void zm_dump_video_frame(const AVFrame *frame, const char *text="Frame"); void zm_dump_video_frame(const AVFrame *frame, const char *text="Frame");
#if LIBAVCODEC_VERSION_CHECK(56, 8, 0, 60, 100) #if LIBAVCODEC_VERSION_CHECK(56, 8, 0, 60, 100)
@ -332,7 +361,9 @@ bool is_audio_stream(AVStream *);
bool is_video_context(AVCodec *); bool is_video_context(AVCodec *);
bool is_audio_context(AVCodec *); bool is_audio_context(AVCodec *);
int zm_receive_frame( AVCodecContext *context, AVFrame *frame, AVPacket &packet ); int zm_receive_frame(AVCodecContext *context, AVFrame *frame, AVPacket &packet);
int zm_send_frame(AVCodecContext *context, AVFrame *frame, AVPacket &packet);
void dumpPacket(AVStream *, AVPacket *,const char *text=""); void dumpPacket(AVStream *, AVPacket *,const char *text="");
void dumpPacket(AVPacket *,const char *text=""); void dumpPacket(AVPacket *,const char *text="");
#endif // ZM_FFMPEG_H #endif // ZM_FFMPEG_H

View File

@ -29,6 +29,7 @@ extern "C" {
#if HAVE_LIBAVUTIL_HWCONTEXT_H #if HAVE_LIBAVUTIL_HWCONTEXT_H
#include "libavutil/hwcontext.h" #include "libavutil/hwcontext.h"
#endif #endif
#include "libavutil/pixdesc.h"
} }
#ifndef AV_ERROR_MAX_STRING_SIZE #ifndef AV_ERROR_MAX_STRING_SIZE
#define AV_ERROR_MAX_STRING_SIZE 64 #define AV_ERROR_MAX_STRING_SIZE 64
@ -135,7 +136,6 @@ FfmpegCamera::FfmpegCamera(
} }
hwaccel = false; hwaccel = false;
hwFrame = NULL;
mFormatContext = NULL; mFormatContext = NULL;
mVideoStreamId = -1; mVideoStreamId = -1;
@ -153,6 +153,8 @@ FfmpegCamera::FfmpegCamera(
packetqueue = NULL; packetqueue = NULL;
error_count = 0; error_count = 0;
#if HAVE_LIBAVUTIL_HWCONTEXT_H #if HAVE_LIBAVUTIL_HWCONTEXT_H
hwFrame = NULL;
hw_device_ctx = NULL;
hw_pix_fmt = AV_PIX_FMT_NONE; hw_pix_fmt = AV_PIX_FMT_NONE;
#endif #endif
@ -455,36 +457,46 @@ int FfmpegCamera::OpenFfmpeg() {
if ( !config ) { if ( !config ) {
Debug(1, "Decoder %s does not support device type %s.", Debug(1, "Decoder %s does not support device type %s.",
mVideoCodec->name, av_hwdevice_get_type_name(type)); mVideoCodec->name, av_hwdevice_get_type_name(type));
return -1; break;
} }
if ( (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX) if ( (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX)
&& (config->device_type == type) && (config->device_type == type)
) { ) {
hw_pix_fmt = config->pix_fmt; hw_pix_fmt = config->pix_fmt;
break; break;
} else {
Debug(1, "decoder %s hwConfig doesn't match our type: %s, pix_fmt %s.",
mVideoCodec->name,
av_hwdevice_get_type_name(config->device_type),
av_get_pix_fmt_name(config->pix_fmt)
);
} }
} // end foreach hwconfig } // end foreach hwconfig
#else #else
hw_pix_fmt = find_fmt_by_hw_type(type); hw_pix_fmt = find_fmt_by_hw_type(type);
#endif #endif
Debug(1, "Selected gw_pix_fmt %d %s", if ( hw_pix_fmt != AV_PIX_FMT_NONE ) {
hw_pix_fmt, Debug(1, "Selected gw_pix_fmt %d %s",
av_get_pix_fmt_name(hw_pix_fmt)); hw_pix_fmt,
av_get_pix_fmt_name(hw_pix_fmt));
mVideoCodecContext->get_format = get_hw_format; mVideoCodecContext->get_format = get_hw_format;
Debug(1, "Creating hwdevice for %s", Debug(1, "Creating hwdevice for %s",
(hwaccel_device != "" ? hwaccel_device.c_str() : "")); (hwaccel_device != "" ? hwaccel_device.c_str() : ""));
ret = av_hwdevice_ctx_create(&hw_device_ctx, type, ret = av_hwdevice_ctx_create(&hw_device_ctx, type,
(hwaccel_device != "" ? hwaccel_device.c_str(): NULL), NULL, 0); (hwaccel_device != "" ? hwaccel_device.c_str(): NULL), NULL, 0);
if ( ret < 0 ) { if ( ret < 0 ) {
Error("Failed to create specified HW device."); Error("Failed to create specified HW device.");
return -1; return -1;
}
Debug(1, "Created hwdevice");
mVideoCodecContext->hw_device_ctx = av_buffer_ref(hw_device_ctx);
hwaccel = true;
hwFrame = zm_av_frame_alloc();
} else {
Debug(1, "Failed to setup hwaccel.");
} }
Debug(1, "Created hwdevice");
mVideoCodecContext->hw_device_ctx = av_buffer_ref(hw_device_ctx);
hwaccel = true;
hwFrame = zm_av_frame_alloc();
#else #else
Warning("HWAccel support not compiled in."); Warning("HWAccel support not compiled in.");
#endif #endif
@ -637,6 +649,12 @@ int FfmpegCamera::Close() {
av_frame_free(&mRawFrame); av_frame_free(&mRawFrame);
mRawFrame = NULL; mRawFrame = NULL;
} }
#if HAVE_LIBAVUTIL_HWCONTEXT_H
if ( hwFrame ) {
av_frame_free(&hwFrame);
hwFrame = NULL;
}
#endif
#if HAVE_LIBSWSCALE #if HAVE_LIBSWSCALE
if ( mConvertContext ) { if ( mConvertContext ) {
@ -665,6 +683,12 @@ int FfmpegCamera::Close() {
mAudioCodecContext = NULL; // Freed by av_close_input_file mAudioCodecContext = NULL; // Freed by av_close_input_file
} }
#if HAVE_LIBAVUTIL_HWCONTEXT_H
if ( hw_device_ctx ) {
av_buffer_unref(&hw_device_ctx);
}
#endif
if ( mFormatContext ) { if ( mFormatContext ) {
#if !LIBAVFORMAT_VERSION_CHECK(53, 17, 0, 25, 0) #if !LIBAVFORMAT_VERSION_CHECK(53, 17, 0, 25, 0)
av_close_input_file(mFormatContext); av_close_input_file(mFormatContext);

View File

@ -7,8 +7,7 @@ FFmpeg_Input::FFmpeg_Input() {
input_format_context = NULL; input_format_context = NULL;
video_stream_id = -1; video_stream_id = -1;
audio_stream_id = -1; audio_stream_id = -1;
av_register_all(); FFMPEGInit();
avcodec_register_all();
streams = NULL; streams = NULL;
frame = NULL; frame = NULL;
} }

View File

@ -157,6 +157,7 @@ User *zmLoadTokenUser (std::string jwt_token_str, bool use_remote_addr ) {
std::pair<std::string, unsigned int> ans = verifyToken(jwt_token_str, key); std::pair<std::string, unsigned int> ans = verifyToken(jwt_token_str, key);
std::string username = ans.first; std::string username = ans.first;
unsigned int iat = ans.second; unsigned int iat = ans.second;
Debug (1,"retrieved user '%s' from token", username.c_str());
if (username != "") { if (username != "") {
char sql[ZM_SQL_MED_BUFSIZ] = ""; char sql[ZM_SQL_MED_BUFSIZ] = "";
@ -178,7 +179,7 @@ User *zmLoadTokenUser (std::string jwt_token_str, bool use_remote_addr ) {
if ( n_users != 1 ) { if ( n_users != 1 ) {
mysql_free_result(result); mysql_free_result(result);
Error("Unable to authenticate user %s", username.c_str()); Error("Unable to authenticate user '%s'", username.c_str());
return NULL; return NULL;
} }
@ -188,12 +189,12 @@ User *zmLoadTokenUser (std::string jwt_token_str, bool use_remote_addr ) {
if (stored_iat > iat ) { // admin revoked tokens if (stored_iat > iat ) { // admin revoked tokens
mysql_free_result(result); mysql_free_result(result);
Error("Token was revoked for %s", username.c_str()); Error("Token was revoked for '%s'", username.c_str());
return NULL; return NULL;
} }
Debug (1,"Got stored expiry time of %u",stored_iat); Debug (1,"Got stored expiry time of %u",stored_iat);
Info ("Authenticated user '%s' via token", username.c_str()); Debug (1,"Authenticated user '%s' via token", username.c_str());
mysql_free_result(result); mysql_free_result(result);
return user; return user;

View File

@ -308,7 +308,6 @@ VideoStore::VideoStore(
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0) #if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
audio_out_stream = avformat_new_stream(oc, NULL); audio_out_stream = avformat_new_stream(oc, NULL);
audio_out_stream->time_base = audio_in_stream->time_base;
audio_out_ctx = avcodec_alloc_context3(audio_out_codec); audio_out_ctx = avcodec_alloc_context3(audio_out_codec);
if ( !audio_out_ctx ) { if ( !audio_out_ctx ) {
Error("could not allocate codec ctx for AAC"); Error("could not allocate codec ctx for AAC");
@ -476,7 +475,51 @@ VideoStore::~VideoStore() {
break; break;
} }
#endif #endif
// Need to adjust pts and dts and duration
pkt.stream_index = audio_out_stream->index; pkt.stream_index = audio_out_stream->index;
pkt.duration = av_rescale_q(
pkt.duration,
audio_out_ctx->time_base,
audio_out_stream->time_base);
// Scale the PTS of the outgoing packet to be the correct time base
if ( pkt.pts != AV_NOPTS_VALUE ) {
pkt.pts = av_rescale_q(
pkt.pts,
audio_out_ctx->time_base,
audio_in_stream->time_base);
// audio_first_pts is in audio_in_stream time base
pkt.pts -= audio_first_pts;
pkt.pts = av_rescale_q(
pkt.pts,
audio_in_stream->time_base,
audio_out_stream->time_base);
Debug(2, "audio pkt.pts = %" PRId64 " from first_pts(%" PRId64 ")",
pkt.pts, audio_first_pts);
} else {
Debug(2, "pkt.pts = undef");
pkt.pts = AV_NOPTS_VALUE;
}
if ( pkt.dts != AV_NOPTS_VALUE ) {
pkt.dts = av_rescale_q(
pkt.dts,
audio_out_ctx->time_base,
audio_in_stream->time_base);
pkt.dts -= audio_first_dts;
pkt.dts = av_rescale_q(
pkt.dts,
audio_in_ctx->time_base,
audio_out_stream->time_base);
Debug(2, "pkt.dts = %" PRId64 " - first_dts(%" PRId64 ")",
pkt.dts, audio_first_dts);
} else {
pkt.dts = AV_NOPTS_VALUE;
}
dumpPacket(audio_out_stream, &pkt, "writing flushed packet"); dumpPacket(audio_out_stream, &pkt, "writing flushed packet");
av_interleaved_write_frame(oc, &pkt); av_interleaved_write_frame(oc, &pkt);
zm_av_packet_unref(&pkt); zm_av_packet_unref(&pkt);
@ -1017,8 +1060,8 @@ int VideoStore::writeAudioFramePacket(AVPacket *ipkt) {
dumpPacket(audio_in_stream, ipkt, "input packet"); dumpPacket(audio_in_stream, ipkt, "input packet");
if ( audio_out_codec ) { if ( audio_out_codec ) {
Debug(2, "Have output codec");
if ( ( ret = zm_receive_frame(audio_in_ctx, in_frame, *ipkt) ) < 0 ) { if ( ( ret = zm_receive_frame(audio_in_ctx, in_frame, *ipkt) ) < 0 ) {
Debug(3, "Not ready to receive frame");
return 0; return 0;
} }
@ -1030,13 +1073,15 @@ int VideoStore::writeAudioFramePacket(AVPacket *ipkt) {
} }
zm_dump_frame(out_frame, "Out frame after resample"); zm_dump_frame(out_frame, "Out frame after resample");
#if 0
// out_frame pts is in the input pkt pts... needs to be adjusted before sending to the encoder // out_frame pts is in the input pkt pts... needs to be adjusted before sending to the encoder
if ( out_frame->pts != AV_NOPTS_VALUE ) { if ( out_frame->pts != AV_NOPTS_VALUE ) {
if ( !audio_first_pts ) { if ( !audio_first_pts ) {
audio_first_pts = out_frame->pts; audio_first_pts = out_frame->pts;
Debug(1, "No video_first_pts setting to %" PRId64, audio_first_pts); Debug(1, "No audio_first_pts setting to %" PRId64, audio_first_pts);
out_frame->pts = 0; out_frame->pts = 0;
} else { } else {
// out_frame_pts is in codec->timebase, audio_first_pts is in packet timebase.
out_frame->pts = out_frame->pts - audio_first_pts; out_frame->pts = out_frame->pts - audio_first_pts;
zm_dump_frame(out_frame, "Out frame after pts adjustment"); zm_dump_frame(out_frame, "Out frame after pts adjustment");
} }
@ -1046,56 +1091,57 @@ int VideoStore::writeAudioFramePacket(AVPacket *ipkt) {
out_frame->pts = audio_next_pts; out_frame->pts = audio_next_pts;
} }
audio_next_pts = out_frame->pts + out_frame->nb_samples; audio_next_pts = out_frame->pts + out_frame->nb_samples;
#endif
av_init_packet(&opkt); av_init_packet(&opkt);
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0) if ( !zm_send_frame(audio_out_ctx, out_frame, opkt) ) {
if ( (ret = avcodec_send_frame(audio_out_ctx, out_frame)) < 0 ) {
Error("Could not send frame (error '%s')",
av_make_error_string(ret).c_str());
zm_av_packet_unref(&opkt);
return 0; return 0;
} }
if ( (ret = avcodec_receive_packet(audio_out_ctx, &opkt)) < 0 ) {
if ( AVERROR(EAGAIN) == ret ) {
// The codec may need more samples than it has, perfectly valid
Debug(2, "Codec not ready to give us a packet");
} else {
Error("Could not recieve packet (error %d = '%s')", ret,
av_make_error_string(ret).c_str());
}
zm_av_packet_unref(&opkt);
return 0;
}
#else
int data_present;
if ( (ret = avcodec_encode_audio2(
audio_out_ctx, &opkt, out_frame, &data_present)) < 0 ) {
Error("Could not encode frame (error '%s')",
av_make_error_string(ret).c_str());
zm_av_packet_unref(&opkt);
return 0;
}
if ( !data_present ) {
Debug(2, "Not ready to out a frame yet.");
zm_av_packet_unref(&opkt);
return 0;
}
#endif
#if 0
// These should be set by encoder. They may not directly relate to ipkt due to buffering in codec.
opkt.duration = av_rescale_q(opkt.duration,
audio_in_stream->time_base,
audio_out_stream->time_base);
opkt.pts = av_rescale_q(opkt.pts,
audio_in_stream->time_base,
audio_out_stream->time_base);
opkt.dts = av_rescale_q(opkt.dts,
audio_in_stream->time_base,
audio_out_stream->time_base);
#endif
dumpPacket(audio_out_stream, &opkt, "raw opkt"); dumpPacket(audio_out_stream, &opkt, "raw opkt");
opkt.duration = av_rescale_q(
opkt.duration,
audio_out_ctx->time_base,
audio_out_stream->time_base);
// Scale the PTS of the outgoing packet to be the correct time base
if ( ipkt->pts != AV_NOPTS_VALUE ) {
if ( !audio_first_pts ) {
opkt.pts = 0;
audio_first_pts = ipkt->pts;
Debug(1, "No audio_first_pts");
} else {
opkt.pts = av_rescale_q(
opkt.pts,
audio_out_ctx->time_base,
audio_out_stream->time_base);
opkt.pts -= audio_first_pts;
Debug(2, "audio opkt.pts = %" PRId64 " from first_pts %" PRId64,
opkt.pts, audio_first_pts);
}
} else {
Debug(2, "opkt.pts = undef");
opkt.pts = AV_NOPTS_VALUE;
}
if ( opkt.dts != AV_NOPTS_VALUE ) {
if ( !audio_first_dts ) {
opkt.dts = 0;
audio_first_dts = opkt.dts;
} else {
opkt.dts = av_rescale_q(
opkt.dts,
audio_out_ctx->time_base,
audio_out_stream->time_base);
opkt.dts -= audio_first_dts;
Debug(2, "opkt.dts = %" PRId64 " from first_dts %" PRId64,
opkt.dts, audio_first_dts);
}
audio_last_dts = opkt.dts;
} else {
opkt.dts = AV_NOPTS_VALUE;
}
} else { } else {
Debug(2,"copying"); Debug(2,"copying");
av_init_packet(&opkt); av_init_packet(&opkt);
@ -1128,16 +1174,6 @@ int VideoStore::writeAudioFramePacket(AVPacket *ipkt) {
} }
if ( ipkt->dts != AV_NOPTS_VALUE ) { if ( ipkt->dts != AV_NOPTS_VALUE ) {
// So if the in has no dts assigned... still need an out dts... so we use cur_dts?
#if 0
if ( audio_last_dts >= audio_in_stream->cur_dts ) {
Debug(1, "Resetting audio_last_dts from (%d) to cur_dts (%d)", audio_last_dts, audio_in_stream->cur_dts);
opkt.dts = audio_next_dts + av_rescale_q( audio_in_stream->cur_dts, AV_TIME_BASE_Q, audio_out_stream->time_base);
} else {
opkt.dts = audio_next_dts + av_rescale_q( audio_in_stream->cur_dts - audio_last_dts, AV_TIME_BASE_Q, audio_out_stream->time_base);
}
#endif
if ( !audio_first_dts ) { if ( !audio_first_dts ) {
opkt.dts = 0; opkt.dts = 0;
audio_first_dts = ipkt->dts; audio_first_dts = ipkt->dts;
@ -1204,28 +1240,9 @@ int VideoStore::resample_audio() {
av_make_error_string(ret).c_str()); av_make_error_string(ret).c_str());
return 0; return 0;
} }
zm_dump_frame(out_frame, "Out frame after convert");
ret = av_audio_fifo_realloc(fifo, av_audio_fifo_size(fifo) + out_frame->nb_samples);
#if 0 if ( ret < 0 ) {
// out_frame pts is in the input pkt pts... needs to be adjusted before sending to the encoder
if ( out_frame->pts != AV_NOPTS_VALUE ) {
if ( !video_first_pts ) {
video_first_pts = out_frame->pts;
Debug(1, "No video_first_pts setting to %" PRId64, video_first_pts);
out_frame->pts = 0;
} else {
out_frame->pts = out_frame->pts - video_first_pts;
}
//
} else {
// sending AV_NOPTS_VALUE doesn't really work but we seem to get it in ffmpeg 2.8
out_frame->pts = audio_next_pts;
}
audio_next_pts = out_frame->pts + out_frame->nb_samples;
#endif
if ((ret = av_audio_fifo_realloc(fifo, av_audio_fifo_size(fifo) + out_frame->nb_samples)) < 0) {
Error("Could not reallocate FIFO"); Error("Could not reallocate FIFO");
return 0; return 0;
} }
@ -1240,7 +1257,7 @@ int VideoStore::resample_audio() {
// Reset frame_size to output_frame_size // Reset frame_size to output_frame_size
int frame_size = audio_out_ctx->frame_size; int frame_size = audio_out_ctx->frame_size;
// AAC requires 1024 samples per encode. Our input tends to be 160, so need to buffer them. // AAC requires 1024 samples per encode. Our input tends to be something else, so need to buffer them.
if ( frame_size > av_audio_fifo_size(fifo) ) { if ( frame_size > av_audio_fifo_size(fifo) ) {
return 0; return 0;
} }
@ -1251,16 +1268,14 @@ int VideoStore::resample_audio() {
} }
out_frame->nb_samples = frame_size; out_frame->nb_samples = frame_size;
// resampling changes the duration because the timebase is 1/samples // resampling changes the duration because the timebase is 1/samples
// I think we should be dealing in codec timebases not stream
if ( in_frame->pts != AV_NOPTS_VALUE ) { if ( in_frame->pts != AV_NOPTS_VALUE ) {
out_frame->pkt_duration = av_rescale_q(
in_frame->pkt_duration,
audio_in_stream->time_base,
audio_out_stream->time_base);
out_frame->pts = av_rescale_q( out_frame->pts = av_rescale_q(
in_frame->pts, in_frame->pts,
audio_in_stream->time_base, audio_in_ctx->time_base,
audio_out_stream->time_base); audio_out_ctx->time_base);
} }
zm_dump_frame(out_frame, "Out frame after timestamp conversion");
#else #else
#if defined(HAVE_LIBAVRESAMPLE) #if defined(HAVE_LIBAVRESAMPLE)
ret = avresample_convert(resample_ctx, NULL, 0, 0, in_frame->data, ret = avresample_convert(resample_ctx, NULL, 0, 0, in_frame->data,

View File

@ -43,9 +43,8 @@ bool ValidateAccess( User *user, int mon_id ) {
allowed = false; allowed = false;
} }
if ( !allowed ) { if ( !allowed ) {
Error( "Error, insufficient privileges for requested action user %d %s for monitor %d", Error("Error, insufficient privileges for requested action user %d %s for monitor %d",
user->Id(), user->getUsername(), mon_id ); user->Id(), user->getUsername(), mon_id);
exit( -1 );
} }
return allowed; return allowed;
} }
@ -164,8 +163,7 @@ int main( int argc, const char *argv[] ) {
strncpy( auth, value, sizeof(auth)-1 ); strncpy( auth, value, sizeof(auth)-1 );
} else if ( !strcmp( name, "token" ) ) { } else if ( !strcmp( name, "token" ) ) {
jwt_token_str = value; jwt_token_str = value;
Debug(1,"ZMS: JWT token found: %s", jwt_token_str.c_str()); Debug(1, "ZMS: JWT token found: %s", jwt_token_str.c_str());
} else if ( !strcmp( name, "user" ) ) { } else if ( !strcmp( name, "user" ) ) {
username = UriDecode( value ); username = UriDecode( value );
} else if ( !strcmp( name, "pass" ) ) { } else if ( !strcmp( name, "pass" ) ) {
@ -184,17 +182,15 @@ int main( int argc, const char *argv[] ) {
} else { } else {
snprintf(log_id_string, sizeof(log_id_string), "zms_e%" PRIu64, event_id); snprintf(log_id_string, sizeof(log_id_string), "zms_e%" PRIu64, event_id);
} }
logInit( log_id_string ); logInit(log_id_string);
if ( config.opt_use_auth ) { if ( config.opt_use_auth ) {
User *user = 0; User *user = 0;
if (jwt_token_str != "") { if ( jwt_token_str != "" ) {
//user = zmLoadTokenUser(jwt_token_str, config.auth_hash_ips); //user = zmLoadTokenUser(jwt_token_str, config.auth_hash_ips);
user = zmLoadTokenUser(jwt_token_str, false); user = zmLoadTokenUser(jwt_token_str, false);
} else if ( strcmp(config.auth_relay, "none") == 0 ) {
}
else if ( strcmp(config.auth_relay, "none") == 0 ) {
if ( checkUser(username.c_str()) ) { if ( checkUser(username.c_str()) ) {
user = zmLoadUser(username.c_str()); user = zmLoadUser(username.c_str());
} else { } else {
@ -216,21 +212,27 @@ int main( int argc, const char *argv[] ) {
} }
} }
if ( !user ) { if ( !user ) {
fprintf(stdout, "HTTP/1.0 401 Unauthorized\r\n");
Error("Unable to authenticate user"); Error("Unable to authenticate user");
logTerm(); logTerm();
zmDbClose(); zmDbClose();
return -1; return -1;
} }
ValidateAccess(user, monitor_id); if ( !ValidateAccess(user, monitor_id) ) {
fprintf(stdout, "HTTP/1.0 403 Forbidden\r\n");
logTerm();
zmDbClose();
return -1;
}
} // end if config.opt_use_auth } // end if config.opt_use_auth
hwcaps_detect(); hwcaps_detect();
zmSetDefaultTermHandler(); zmSetDefaultTermHandler();
zmSetDefaultDieHandler(); zmSetDefaultDieHandler();
setbuf( stdout, 0 ); setbuf(stdout, 0);
if ( nph ) { if ( nph ) {
fprintf( stdout, "HTTP/1.0 200 OK\r\n" ); fprintf(stdout, "HTTP/1.0 200 OK\r\n");
} }
fprintf( stdout, "Server: ZoneMinder Video Server/%s\r\n", ZM_VERSION ); fprintf( stdout, "Server: ZoneMinder Video Server/%s\r\n", ZM_VERSION );

View File

@ -333,7 +333,7 @@ EOF
fi; fi;
else else
echo "dputting to $PPA"; echo "dputting to $PPA";
dput $PPA $SC dput $PPA $SC
fi; fi;
fi; fi;
done; # foreach distro done; # foreach distro
@ -345,5 +345,3 @@ if [ "$INTERACTIVE" != "no" ]; then
else else
rm -fr "$DIRECTORY.orig"; echo "The checked out copy has been deleted"; rm -fr "$DIRECTORY.orig"; echo "The checked out copy has been deleted";
fi fi

View File

@ -1 +1 @@
1.33.11 1.33.12

View File

@ -254,6 +254,7 @@ class MonitorsController extends AppController {
throw new BadRequestException(__('Invalid command')); throw new BadRequestException(__('Invalid command'));
} }
$zm_path_bin = Configure::read('ZM_PATH_BIN'); $zm_path_bin = Configure::read('ZM_PATH_BIN');
$mToken = $this->request->query('token') ? $this->request->query('token') : null;
switch ($cmd) { switch ($cmd) {
case 'on': case 'on':
@ -281,8 +282,12 @@ class MonitorsController extends AppController {
$zmAuthRelay = $config['Config']['Value']; $zmAuthRelay = $config['Config']['Value'];
$auth = ''; $auth = '';
if ( $zmOptAuth ) { if ( $zmOptAuth ) {
if ( $zmAuthRelay == 'hashed' ) { if ($mToken) {
$auth = ' -T '.$mToken;
}
elseif ( $zmAuthRelay == 'hashed' ) {
$options = array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_AUTH_HASH_SECRET')); $options = array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_AUTH_HASH_SECRET'));
$config = $this->Config->find('first', $options); $config = $this->Config->find('first', $options);
$zmAuthHashSecret = $config['Config']['Value']; $zmAuthHashSecret = $config['Config']['Value'];

View File

@ -580,6 +580,9 @@ class Event {
if ( file_exists( $this->Path().'/'.$this->DefaultVideo() ) ) { if ( file_exists( $this->Path().'/'.$this->DefaultVideo() ) ) {
return true; return true;
} }
if ( !defined('ZM_SERVER_ID') ) {
return false;
}
$Storage= $this->Storage(); $Storage= $this->Storage();
$Server = $Storage->ServerId() ? $Storage->Server() : $this->Monitor()->Server(); $Server = $Storage->ServerId() ? $Storage->Server() : $this->Monitor()->Server();
if ( $Server->Id() != ZM_SERVER_ID ) { if ( $Server->Id() != ZM_SERVER_ID ) {
@ -624,6 +627,9 @@ class Event {
if ( file_exists($this->Path().'/'.$this->DefaultVideo()) ) { if ( file_exists($this->Path().'/'.$this->DefaultVideo()) ) {
return filesize($this->Path().'/'.$this->DefaultVideo()); return filesize($this->Path().'/'.$this->DefaultVideo());
} }
if ( !defined('ZM_SERVER_ID') ) {
return false;
}
$Storage= $this->Storage(); $Storage= $this->Storage();
$Server = $Storage->ServerId() ? $Storage->Server() : $this->Monitor()->Server(); $Server = $Storage->ServerId() ? $Storage->Server() : $this->Monitor()->Server();
if ( $Server->Id() != ZM_SERVER_ID ) { if ( $Server->Id() != ZM_SERVER_ID ) {

View File

@ -105,6 +105,7 @@ private $defaults = array(
'DefaultCodec' => 'auto', 'DefaultCodec' => 'auto',
); );
private $status_fields = array( private $status_fields = array(
'Status' => null,
'AnalysisFPS' => null, 'AnalysisFPS' => null,
'CaptureFPS' => null, 'CaptureFPS' => null,
'CaptureBandwidth' => null, 'CaptureBandwidth' => null,
@ -271,17 +272,27 @@ private $control_fields = array(
return $this->{$fn}; return $this->{$fn};
#array_unshift($args, $this); #array_unshift($args, $this);
#call_user_func_array( $this->{$fn}, $args); #call_user_func_array( $this->{$fn}, $args);
} else { } else if ( array_key_exists($fn, $this->control_fields) ) {
if ( array_key_exists($fn, $this->control_fields) ) {
return $this->control_fields{$fn}; return $this->control_fields{$fn};
} else if ( array_key_exists( $fn, $this->defaults ) ) { } else if ( array_key_exists( $fn, $this->defaults ) ) {
return $this->defaults{$fn}; return $this->defaults{$fn};
} else if ( array_key_exists( $fn, $this->status_fields) ) {
$sql = 'SELECT Status,CaptureFPS,AnalysisFPS,CaptureBandwidth
FROM Monitor_Status WHERE MonitorId=?';
$row = dbFetchOne($sql, NULL, array($this->{'Id'}));
if ( !$row ) {
Error("Unable to load Monitor record for Id=" . $this->{'Id'});
} else { } else {
$backTrace = debug_backtrace(); foreach ($row as $k => $v) {
$file = $backTrace[1]['file']; $this->{$k} = $v;
$line = $backTrace[1]['line']; }
Warning( "Unknown function call Monitor->$fn from $file:$line" );
} }
return $this->{$fn};
} else {
$backTrace = debug_backtrace();
$file = $backTrace[1]['file'];
$line = $backTrace[1]['line'];
Warning( "Unknown function call Monitor->$fn from $file:$line" );
} }
} }

View File

@ -2459,11 +2459,13 @@ function do_post_request($url, $data, $optional_headers = null) {
$ctx = stream_context_create($params); $ctx = stream_context_create($params);
$fp = @fopen($url, 'rb', false, $ctx); $fp = @fopen($url, 'rb', false, $ctx);
if ( !$fp ) { if ( !$fp ) {
throw new Exception("Problem with $url, $php_errormsg"); throw new Exception("Problem with $url, "
.print_r(error_get_last(),true));
} }
$response = @stream_get_contents($fp); $response = @stream_get_contents($fp);
if ( $response === false ) { if ( $response === false ) {
throw new Exception("Problem reading data from $url, $php_errormsg"); throw new Exception("Problem reading data from $url, data: ".print_r($params,true)
.print_r(error_get_last(),true));
} }
return $response; return $response;
} }

View File

@ -51,51 +51,51 @@ function newWindow( url, name, width, height ) {
function getPopupSize( tag, width, height ) { function getPopupSize( tag, width, height ) {
if ( typeof popupSizes == 'undefined' ) { if ( typeof popupSizes == 'undefined' ) {
Error( "Can't find any window sizes" ); Error("Can't find any window sizes");
return ( {'width': 0, 'height': 0} ); return {'width': 0, 'height': 0};
} }
var popupSize = Object.clone( popupSizes[tag] ); var popupSize = Object.clone(popupSizes[tag]);
if ( !popupSize ) { if ( !popupSize ) {
Error( "Can't find window size for tag '"+tag+"'" ); Error("Can't find window size for tag '"+tag+"'");
return ( {'width': 0, 'height': 0} ); return {'width': 0, 'height': 0};
} }
if ( popupSize.width && popupSize.height ) { if ( popupSize.width && popupSize.height ) {
if ( width || height ) { if ( width || height ) {
Warning( "Ignoring passed dimensions "+width+"x"+height+" when getting popup size for tag '"+tag+"'" ); Warning("Ignoring passed dimensions "+width+"x"+height+" when getting popup size for tag '"+tag+"'");
} }
return ( popupSize ); return popupSize;
} }
if ( popupSize.addWidth ) { if ( popupSize.addWidth ) {
popupSize.width = popupSize.addWidth; popupSize.width = popupSize.addWidth;
if ( !width ) { if ( !width ) {
Error( "Got addWidth but no passed width when getting popup size for tag '"+tag+"'" ); Error("Got addWidth but no passed width when getting popup size for tag '"+tag+"'");
} else { } else {
popupSize.width += parseInt(width); popupSize.width += parseInt(width);
} }
} else if ( width ) { } else if ( width ) {
popupSize.width = width; popupSize.width = width;
Error( "Got passed width but no addWidth when getting popup size for tag '"+tag+"'" ); Error("Got passed width but no addWidth when getting popup size for tag '"+tag+"'");
} }
if ( popupSize.minWidth && popupSize.width < popupSize.minWidth ) { if ( popupSize.minWidth && popupSize.width < popupSize.minWidth ) {
Warning( "Adjusting to minimum width when getting popup size for tag '"+tag+"'" ); Warning("Adjusting to minimum width when getting popup size for tag '"+tag+"'");
popupSize.width = popupSize.minWidth; popupSize.width = popupSize.minWidth;
} }
if ( popupSize.addHeight ) { if ( popupSize.addHeight ) {
popupSize.height = popupSize.addHeight; popupSize.height = popupSize.addHeight;
if ( !height ) { if ( !height ) {
Error( "Got addHeight but no passed height when getting popup size for tag '"+tag+"'" ); Error("Got addHeight but no passed height when getting popup size for tag '"+tag+"'");
} else { } else {
popupSize.height += parseInt(height); popupSize.height += parseInt(height);
} }
} else if ( height ) { } else if ( height ) {
popupSize.height = height; popupSize.height = height;
Error( "Got passed height but no addHeight when getting popup size for tag '"+tag+"'" ); Error("Got passed height but no addHeight when getting popup size for tag '"+tag+"'");
} }
if ( popupSize.minHeight && ( popupSize.height < popupSize.minHeight ) ) { if ( popupSize.minHeight && ( popupSize.height < popupSize.minHeight ) ) {
Warning( "Adjusting to minimum height ("+popupSize.minHeight+") when getting popup size for tag '"+tag+"' because calculated height is " + popupSize.height ); Warning("Adjusting to minimum height ("+popupSize.minHeight+") when getting popup size for tag '"+tag+"' because calculated height is " + popupSize.height);
popupSize.height = popupSize.minHeight; popupSize.height = popupSize.minHeight;
} }
return ( popupSize ); return popupSize;
} }
function zmWindow() { function zmWindow() {
@ -144,7 +144,7 @@ window.addEventListener("DOMContentLoaded", function onSkinDCL() {
el.addEventListener("click", function onClick(evt) { el.addEventListener("click", function onClick(evt) {
var el = this; var el = this;
var url; var url;
if (el.hasAttribute("href")) { if ( el.hasAttribute("href") ) {
// <a> // <a>
url = el.getAttribute("href"); url = el.getAttribute("href");
} else { } else {
@ -167,12 +167,20 @@ window.addEventListener("DOMContentLoaded", function onSkinDCL() {
// 'data-on-click-this' calls the global function in the attribute value with the element when a click happens. // 'data-on-click-this' calls the global function in the attribute value with the element when a click happens.
document.querySelectorAll("a[data-on-click-this], button[data-on-click-this], input[data-on-click-this]").forEach(function attachOnClick(el) { document.querySelectorAll("a[data-on-click-this], button[data-on-click-this], input[data-on-click-this]").forEach(function attachOnClick(el) {
var fnName = el.getAttribute("data-on-click-this"); var fnName = el.getAttribute("data-on-click-this");
if ( !window[fnName] ) {
console.error("Nothing found to bind to " + fnName);
return;
}
el.onclick = window[fnName].bind(el, el); el.onclick = window[fnName].bind(el, el);
}); });
// 'data-on-click' calls the global function in the attribute value with no arguments when a click happens. // 'data-on-click' calls the global function in the attribute value with no arguments when a click happens.
document.querySelectorAll("a[data-on-click], button[data-on-click], input[data-on-click]").forEach(function attachOnClick(el) { document.querySelectorAll("a[data-on-click], button[data-on-click], input[data-on-click]").forEach(function attachOnClick(el) {
var fnName = el.getAttribute("data-on-click"); var fnName = el.getAttribute("data-on-click");
if ( !window[fnName] ) {
console.error("Nothing found to bind to " + fnName);
return;
}
el.onclick = function() { el.onclick = function() {
window[fnName](); window[fnName]();
}; };
@ -181,6 +189,10 @@ window.addEventListener("DOMContentLoaded", function onSkinDCL() {
// 'data-on-click-true' calls the global function in the attribute value with no arguments when a click happens. // 'data-on-click-true' calls the global function in the attribute value with no arguments when a click happens.
document.querySelectorAll("a[data-on-click-true], button[data-on-click-true], input[data-on-click-true]").forEach(function attachOnClick(el) { document.querySelectorAll("a[data-on-click-true], button[data-on-click-true], input[data-on-click-true]").forEach(function attachOnClick(el) {
var fnName = el.getAttribute("data-on-click-true"); var fnName = el.getAttribute("data-on-click-true");
if ( !window[fnName] ) {
console.error("Nothing found to bind to " + fnName);
return;
}
el.onclick = function() { el.onclick = function() {
window[fnName](true); window[fnName](true);
}; };
@ -189,12 +201,20 @@ window.addEventListener("DOMContentLoaded", function onSkinDCL() {
// 'data-on-change-this' calls the global function in the attribute value with the element when a change happens. // 'data-on-change-this' calls the global function in the attribute value with the element when a change happens.
document.querySelectorAll("select[data-on-change-this], input[data-on-change-this]").forEach(function attachOnChangeThis(el) { document.querySelectorAll("select[data-on-change-this], input[data-on-change-this]").forEach(function attachOnChangeThis(el) {
var fnName = el.getAttribute("data-on-change-this"); var fnName = el.getAttribute("data-on-change-this");
if ( !window[fnName] ) {
console.error("Nothing found to bind to " + fnName);
return;
}
el.onchange = window[fnName].bind(el, el); el.onchange = window[fnName].bind(el, el);
}); });
// 'data-on-change' adds an event listener for the global function in the attribute value when a change happens. // 'data-on-change' adds an event listener for the global function in the attribute value when a change happens.
document.querySelectorAll("select[data-on-change], input[data-on-change]").forEach(function attachOnChange(el) { document.querySelectorAll("select[data-on-change], input[data-on-change]").forEach(function attachOnChange(el) {
var fnName = el.getAttribute("data-on-change"); var fnName = el.getAttribute("data-on-change");
if ( !window[fnName] ) {
console.error("Nothing found to bind to " + fnName);
return;
}
el.onchange = window[fnName]; el.onchange = window[fnName];
}); });
}); });

View File

@ -215,8 +215,12 @@ while ( $event_row = dbFetchNext($results) ) {
( $event->EndTime() ? ' until ' . strftime(STRF_FMT_DATETIME_SHORTER, strtotime($event->EndTime()) ) : '' ) ?> ( $event->EndTime() ? ' until ' . strftime(STRF_FMT_DATETIME_SHORTER, strtotime($event->EndTime()) ) : '' ) ?>
</td> </td>
<td class="colDuration"><?php echo gmdate("H:i:s", $event->Length() ) ?></td> <td class="colDuration"><?php echo gmdate("H:i:s", $event->Length() ) ?></td>
<td class="colFrames"><?php echo makePopupLink( '?view=frames&amp;eid='.$event->Id(), 'zmFrames', 'frames', $event->Frames() ) ?></td> <td class="colFrames"><?php echo makePopupLink( '?view=frames&amp;eid='.$event->Id(), 'zmFrames',
<td class="colAlarmFrames"><?php echo makePopupLink( '?view=frames&amp;eid='.$event->Id(), 'zmFrames', 'frames', $event->AlarmFrames() ) ?></td> ( ZM_WEB_LIST_THUMBS ? array('frames', ZM_WEB_LIST_THUMB_WIDTH, ZM_WEB_LIST_THUMB_HEIGHT) : 'frames'),
$event->Frames() ) ?></td>
<td class="colAlarmFrames"><?php echo makePopupLink( '?view=frames&amp;eid='.$event->Id(), 'zmFrames',
( ZM_WEB_LIST_THUMBS ? array('frames', ZM_WEB_LIST_THUMB_WIDTH, ZM_WEB_LIST_THUMB_HEIGHT) : 'frames'),
$event->AlarmFrames() ) ?></td>
<td class="colTotScore"><?php echo $event->TotScore() ?></td> <td class="colTotScore"><?php echo $event->TotScore() ?></td>
<td class="colAvgScore"><?php echo $event->AvgScore() ?></td> <td class="colAvgScore"><?php echo $event->AvgScore() ?></td>
<td class="colMaxScore"><?php echo makePopupLink( <td class="colMaxScore"><?php echo makePopupLink(

View File

@ -24,11 +24,13 @@ if ( !canView('Events') ) {
} }
require_once('includes/Frame.php'); require_once('includes/Frame.php');
$eid = validInt($_REQUEST['eid']);
$Event = new ZM\Event($eid);
$Monitor = $Event->Monitor();
$countSql = 'SELECT COUNT(*) AS FrameCount FROM Frames AS F WHERE 1 '; $countSql = 'SELECT COUNT(*) AS FrameCount FROM Frames AS F WHERE 1 ';
$frameSql = 'SELECT *, unix_timestamp( TimeStamp ) AS UnixTimeStamp FROM Frames AS F WHERE 1 '; $frameSql = 'SELECT *, unix_timestamp( TimeStamp ) AS UnixTimeStamp FROM Frames AS F WHERE 1 ';
$eid = $_REQUEST['eid'];
// override the sort_field handling in parseSort for frames // override the sort_field handling in parseSort for frames
if ( empty($_REQUEST['sort_field']) ) if ( empty($_REQUEST['sort_field']) )
@ -59,8 +61,6 @@ if ( $_REQUEST['filter']['sql'] ) {
$frameSql .= " ORDER BY $sortColumn $sortOrder,Id $sortOrder"; $frameSql .= " ORDER BY $sortColumn $sortOrder,Id $sortOrder";
$Event = new ZM\Event($eid);
$Monitor = $Event->Monitor();
if ( isset( $_REQUEST['scale'] ) ) { if ( isset( $_REQUEST['scale'] ) ) {
$scale = validNum($_REQUEST['scale']); $scale = validNum($_REQUEST['scale']);
@ -75,22 +75,22 @@ if ( isset( $_REQUEST['scale'] ) ) {
$page = isset($_REQUEST['page']) ? validInt($_REQUEST['page']) : 1; $page = isset($_REQUEST['page']) ? validInt($_REQUEST['page']) : 1;
$limit = isset($_REQUEST['limit']) ? validInt($_REQUEST['limit']) : 0; $limit = isset($_REQUEST['limit']) ? validInt($_REQUEST['limit']) : 0;
$nEvents = dbFetchOne($countSql, 'FrameCount' ); $nFrames = dbFetchOne($countSql, 'FrameCount' );
if ( !empty($limit) && $nEvents > $limit ) { if ( !empty($limit) && ($nFrames > $limit) ) {
$nEvents = $limit; $nFrames = $limit;
} }
$pages = (int)ceil($nEvents/ZM_WEB_EVENTS_PER_PAGE); $pages = (int)ceil($nFrames/ZM_WEB_EVENTS_PER_PAGE);
if ( !empty($page) ) { if ( !empty($page) ) {
if ( $page < 0 ) if ( $page <= 0 )
$page = 1; $page = 1;
else if ( $pages and ( $page > $pages ) ) else if ( $pages and ( $page > $pages ) )
$page = $pages; $page = $pages;
$limitStart = (($page-1)*ZM_WEB_EVENTS_PER_PAGE); $limitStart = (($page-1)*ZM_WEB_EVENTS_PER_PAGE);
if ( empty( $limit ) ) { if ( empty($limit) ) {
$limitAmount = ZM_WEB_EVENTS_PER_PAGE; $limitAmount = ZM_WEB_EVENTS_PER_PAGE;
} else { } else {
$limitLeft = $limit - $limitStart; $limitLeft = $limit - $limitStart;
@ -104,7 +104,7 @@ if ( !empty($page) ) {
$maxShortcuts = 5; $maxShortcuts = 5;
$pagination = getPagination($pages, $page, $maxShortcuts, $sortQuery.'&eid='.$eid.$limitQuery.$filterQuery); $pagination = getPagination($pages, $page, $maxShortcuts, $sortQuery.'&eid='.$eid.$limitQuery.$filterQuery);
$frames = dbFetchAll( $frameSql ); $frames = dbFetchAll($frameSql);
$focusWindow = true; $focusWindow = true;

View File

@ -192,9 +192,8 @@ for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) {
) )
) )
); );
parseFilter($ZeroSize_filter);
} }
?> ?>
<tr id="<?php echo 'monitor_id-'.$monitor['Id'] ?>" title="<?php echo $monitor['Id'] ?>"> <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> <td class="colId"><a href="<?php echo $montagereview_link ?>"><?php echo $monitor['Id'] ?></a></td>
@ -219,7 +218,7 @@ for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) {
<?php echo count($FileMissing) ? '<a href="?view='.ZM_WEB_EVENTS_VIEW .'&amp;page=1'.$FileMissing_filter['query'].'">'.count($FileMissing).'</a>' : '0' ?> <?php echo count($FileMissing) ? '<a href="?view='.ZM_WEB_EVENTS_VIEW .'&amp;page=1'.$FileMissing_filter['query'].'">'.count($FileMissing).'</a>' : '0' ?>
</td> </td>
<td class="colZeroSize<?php echo count($ZeroSize) ? ' errorText' : ''?>"> <td class="colZeroSize<?php echo count($ZeroSize) ? ' errorText' : ''?>">
<?php echo count($ZeroSize) ? '<a href="?view='.ZM_WEB_EVENTS_VIEW .'&amp;page=1'.$ZeroSize_filter['query'].'">'.count($FileMissing).'</a>' : '0' ?> <?php echo count($ZeroSize) ? '<a href="?view='.ZM_WEB_EVENTS_VIEW .'&amp;page=1'.$ZeroSize_filter['query'].'">'.count($ZeroSize).'</a>' : '0' ?>
</td> </td>
</tr> </tr>
<?php <?php

View File

@ -78,7 +78,7 @@ if ( canView('Control') && $monitor->Type() == 'Local' ) {
<div id="closeControl"><a href="#" onclick="<?php echo $popup ? 'window.close()' : 'history.go(-1);return false;' ?>"><?php echo $popup ? translate('Close') : translate('Back') ?></a></div> <div id="closeControl"><a href="#" onclick="<?php echo $popup ? 'window.close()' : 'history.go(-1);return false;' ?>"><?php echo $popup ? translate('Close') : translate('Back') ?></a></div>
</div> </div>
<?php <?php
if ( $monitor->Status() != 'Capturing' ) { if ( $monitor->Status() != 'Connected' ) {
echo '<div class="warning">Monitor is not capturing. We will be unable to provide an image</div>'; echo '<div class="warning">Monitor is not capturing. We will be unable to provide an image</div>';
} }
?> ?>