Merge branch 'storageareas' of github.com:ConnorTechnology/ZoneMinder into storageareas
This commit is contained in:
commit
d3d0579454
|
@ -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
|
||||||
|
|
|
@ -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;
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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 };
|
||||||
|
|
|
@ -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_level( AV_LOG_QUIET );
|
|
||||||
if ( config.log_ffmpeg )
|
|
||||||
av_log_set_callback(log_libav_callback);
|
av_log_set_callback(log_libav_callback);
|
||||||
else
|
Info("Enabling ffmpeg logs, as LOG_DEBUG+LOG_FFMPEG are enabled in options");
|
||||||
Info("Not enabling ffmpeg logs, as LOG_FFMPEG is disabled 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 );
|
||||||
|
}
|
||||||
#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];
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
@ -333,6 +362,8 @@ 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
|
||||||
|
|
|
@ -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,18 +457,25 @@ 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
|
||||||
|
if ( hw_pix_fmt != AV_PIX_FMT_NONE ) {
|
||||||
Debug(1, "Selected gw_pix_fmt %d %s",
|
Debug(1, "Selected gw_pix_fmt %d %s",
|
||||||
hw_pix_fmt,
|
hw_pix_fmt,
|
||||||
av_get_pix_fmt_name(hw_pix_fmt));
|
av_get_pix_fmt_name(hw_pix_fmt));
|
||||||
|
@ -485,6 +494,9 @@ Debug(1, "Selected gw_pix_fmt %d %s",
|
||||||
mVideoCodecContext->hw_device_ctx = av_buffer_ref(hw_device_ctx);
|
mVideoCodecContext->hw_device_ctx = av_buffer_ref(hw_device_ctx);
|
||||||
hwaccel = true;
|
hwaccel = true;
|
||||||
hwFrame = zm_av_frame_alloc();
|
hwFrame = zm_av_frame_alloc();
|
||||||
|
} else {
|
||||||
|
Debug(1, "Failed to setup hwaccel.");
|
||||||
|
}
|
||||||
#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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
14
src/zms.cpp
14
src/zms.cpp
|
@ -45,7 +45,6 @@ bool ValidateAccess( User *user, int mon_id ) {
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
@ -165,7 +164,6 @@ int main( int argc, const char *argv[] ) {
|
||||||
} 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" ) ) {
|
||||||
|
@ -192,9 +190,7 @@ int main( int argc, const char *argv[] ) {
|
||||||
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,12 +212,18 @@ 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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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'];
|
||||||
|
|
|
@ -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 ) {
|
||||||
|
|
|
@ -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,11 +272,22 @@ 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 {
|
||||||
|
foreach ($row as $k => $v) {
|
||||||
|
$this->{$k} = $v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->{$fn};
|
||||||
} else {
|
} else {
|
||||||
$backTrace = debug_backtrace();
|
$backTrace = debug_backtrace();
|
||||||
$file = $backTrace[1]['file'];
|
$file = $backTrace[1]['file'];
|
||||||
|
@ -283,7 +295,6 @@ private $control_fields = array(
|
||||||
Warning( "Unknown function call Monitor->$fn from $file:$line" );
|
Warning( "Unknown function call Monitor->$fn from $file:$line" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public function getStreamSrc($args, $querySep='&') {
|
public function getStreamSrc($args, $querySep='&') {
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,18 +52,18 @@ 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;
|
||||||
|
@ -95,7 +95,7 @@ function getPopupSize( tag, width, height ) {
|
||||||
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() {
|
||||||
|
@ -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];
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -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&eid='.$event->Id(), 'zmFrames', 'frames', $event->Frames() ) ?></td>
|
<td class="colFrames"><?php echo makePopupLink( '?view=frames&eid='.$event->Id(), 'zmFrames',
|
||||||
<td class="colAlarmFrames"><?php echo makePopupLink( '?view=frames&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&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(
|
||||||
|
|
|
@ -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,16 +75,16 @@ 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;
|
||||||
|
|
|
@ -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 .'&page=1'.$FileMissing_filter['query'].'">'.count($FileMissing).'</a>' : '0' ?>
|
<?php echo count($FileMissing) ? '<a href="?view='.ZM_WEB_EVENTS_VIEW .'&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 .'&page=1'.$ZeroSize_filter['query'].'">'.count($FileMissing).'</a>' : '0' ?>
|
<?php echo count($ZeroSize) ? '<a href="?view='.ZM_WEB_EVENTS_VIEW .'&page=1'.$ZeroSize_filter['query'].'">'.count($ZeroSize).'</a>' : '0' ?>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php
|
<?php
|
||||||
|
|
|
@ -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>';
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
|
Loading…
Reference in New Issue