From 35617a6cf7963cc8e37d9e9509d4d062997a0b5a Mon Sep 17 00:00:00 2001 From: dreaddy Date: Mon, 2 Nov 2015 22:16:10 -0500 Subject: [PATCH 01/31] #1128 - Added option to enable send email by ssmtp mail. Option for custom ssmtp path. Conditional checks for new options in filter --- .../lib/ZoneMinder/ConfigData.pm.in | 28 +++++++++++++++++++ scripts/zmfilter.pl.in | 20 +++++++++++-- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in b/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in index 7fff3d62e..d5da2eb9d 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in +++ b/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in @@ -4045,6 +4045,34 @@ body = "ZM alarm detected - %EL% secs, %EF%/%EFA% frames, t%EST%/m%ESM%/a%ESA% s type => $types{string}, category => "eyeZm", }, + { + name => "ZM_SSMTP_MAIL", + default => "no", + description => "Use a SSMTP mail server if available. NEW_MAIL_MODULES must be enabled", + requires => [ + { name => "ZM_OPT_EMAIL", value => "yes" }, + { name => "ZM_OPT_MESSAGE", value => "yes" }, + { name => "ZM_NEW_MAIL_MODULES", value => "yes" } + ], + help => qqq(" + Please visit the following wiki page for more information on setting up ssmtp: http://www.zoneminder.com/wiki/index.php/How_to_get_ssmtp_working_with_Zoneminder. + "), + type => $types{boolean}, + category => "mail", + }, + { + name => "ZM_SSMTP_PATH", + default => "", + description => "SSMTP path custom location", + requires => [ + { name => "ZM_SSMTP_MAIL", value => "yes" } + ], + help => qqq(" + Please visit the following wiki page for more information on setting up ssmtp: http://www.zoneminder.com/wiki/index.php/How_to_get_ssmtp_working_with_Zoneminder. + "), + type => $types{string}, + category => "mail", + }, ); our %options_hash = map { ( $_->{name}, $_ ) } @options; diff --git a/scripts/zmfilter.pl.in b/scripts/zmfilter.pl.in index 54f372262..d038488b4 100755 --- a/scripts/zmfilter.pl.in +++ b/scripts/zmfilter.pl.in @@ -1165,9 +1165,25 @@ sub sendEmail Disposition => "attachment" ); } + if ( $Config{ZM_SSMTP_MAIL} ){ + + my $ssmtp_location = qx('which ssmtp'); + + if( $Config{ZM_SSMTP_PATH} ){ + + $ssmtp_location = $Config{ZM_SSMTP_PATH} + } + + $mail->send( 'sendmail', $ssmtp_location, $Config{ZM_EMAIL_ADDRESS} ); + + }else{ + + MIME::Lite->send( "smtp", $Config{ZM_EMAIL_HOST}, Timeout=>60 ); + $mail->send(); + } ### Send the Message - MIME::Lite->send( "smtp", $Config{ZM_EMAIL_HOST}, Timeout=>60 ); - $mail->send(); + #MIME::Lite->send( "smtp", $Config{ZM_EMAIL_HOST}, Timeout=>60 ); + #$mail->send(); } else { From ced0240fc3817a5dd724875d5327501db877a77e Mon Sep 17 00:00:00 2001 From: dreaddy Date: Fri, 6 Nov 2015 10:43:30 -0500 Subject: [PATCH 02/31] Use the ssmtp path set in options first. shell command if ssmtp path empty. display debug suggesting set ssmtp path in option. --- scripts/zmfilter.pl.in | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/scripts/zmfilter.pl.in b/scripts/zmfilter.pl.in index d038488b4..7e335a30f 100755 --- a/scripts/zmfilter.pl.in +++ b/scripts/zmfilter.pl.in @@ -1167,11 +1167,17 @@ sub sendEmail } if ( $Config{ZM_SSMTP_MAIL} ){ - my $ssmtp_location = qx('which ssmtp'); + my $ssmtp_location = $Config{ZM_SSMTP_PATH} - if( $Config{ZM_SSMTP_PATH} ){ + if( ! $ssmtp_location ){ + + $ssmtp_location = qx('which ssmtp'); + + if ( logDebugging() ) + { + Debug( "which ssmtp: $ssmtp_location - set ssmtp path in options to suppress this message\n" ); + } - $ssmtp_location = $Config{ZM_SSMTP_PATH} } $mail->send( 'sendmail', $ssmtp_location, $Config{ZM_EMAIL_ADDRESS} ); From 92401193a76d7b45d8a4aeacb4236ddf9f47d547 Mon Sep 17 00:00:00 2001 From: dreaddy Date: Fri, 6 Nov 2015 11:19:12 -0500 Subject: [PATCH 03/31] Add missing semicolon --- scripts/zmfilter.pl.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/zmfilter.pl.in b/scripts/zmfilter.pl.in index 7e335a30f..042539907 100755 --- a/scripts/zmfilter.pl.in +++ b/scripts/zmfilter.pl.in @@ -1167,7 +1167,7 @@ sub sendEmail } if ( $Config{ZM_SSMTP_MAIL} ){ - my $ssmtp_location = $Config{ZM_SSMTP_PATH} + my $ssmtp_location = $Config{ZM_SSMTP_PATH}; if( ! $ssmtp_location ){ From 3479af78bd84c7ead3dc18b29fae12c65abf3ca2 Mon Sep 17 00:00:00 2001 From: dreaddy Date: Fri, 6 Nov 2015 13:36:29 -0500 Subject: [PATCH 04/31] Add more verbose help --- scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in b/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in index d5da2eb9d..49fa87f8b 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in +++ b/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in @@ -4055,7 +4055,9 @@ body = "ZM alarm detected - %EL% secs, %EF%/%EFA% frames, t%EST%/m%ESM%/a%ESA% s { name => "ZM_NEW_MAIL_MODULES", value => "yes" } ], help => qqq(" - Please visit the following wiki page for more information on setting up ssmtp: http://www.zoneminder.com/wiki/index.php/How_to_get_ssmtp_working_with_Zoneminder. + +SSMTP is a lightweight and efficient method to send email. The SSMTP application is not installed by default. NEW_MAIL_MODULES must also be enabled Please visit: http://www.zoneminder.com/wiki/index.php/How_to_get_ssmtp_working_with_Zoneminder setup and configuration help. + "), type => $types{boolean}, category => "mail", @@ -4063,12 +4065,12 @@ body = "ZM alarm detected - %EL% secs, %EF%/%EFA% frames, t%EST%/m%ESM%/a%ESA% s { name => "ZM_SSMTP_PATH", default => "", - description => "SSMTP path custom location", + description => "SSMTP executable path", requires => [ { name => "ZM_SSMTP_MAIL", value => "yes" } ], help => qqq(" - Please visit the following wiki page for more information on setting up ssmtp: http://www.zoneminder.com/wiki/index.php/How_to_get_ssmtp_working_with_Zoneminder. +Recommend setting the path to the SSMTP application. If path is not defined. Zoneminder will try to determined the path via shell command. Example path: /usr/sbin/ssmtp. "), type => $types{string}, category => "mail", From e70d037895975c1bf711f02b943116ad8d11a1cd Mon Sep 17 00:00:00 2001 From: SteveGilvarry Date: Sat, 27 Feb 2016 01:23:20 +1100 Subject: [PATCH 05/31] Start avpicture deprecation --- src/zm_ffmpeg_camera.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/zm_ffmpeg_camera.cpp b/src/zm_ffmpeg_camera.cpp index 9e3a2960c..062d819d9 100644 --- a/src/zm_ffmpeg_camera.cpp +++ b/src/zm_ffmpeg_camera.cpp @@ -182,8 +182,8 @@ int FfmpegCamera::Capture( Image &image ) if ( frameComplete ) { Debug( 3, "Got frame %d", frameCount ); - - avpicture_fill( (AVPicture *)mFrame, directbuffer, imagePixFormat, width, height); + av_image_fill_arrays(mFrame->data, mFrame->linesize, directbuffer, imagePixFormat, width, height, 1); + //avpicture_fill( (AVPicture *)mFrame, directbuffer, imagePixFormat, width, height); #if HAVE_LIBSWSCALE if(mConvertContext == NULL) { From 2122d6e443bd468972f2def40b4b0450c57130b3 Mon Sep 17 00:00:00 2001 From: SteveGilvarry Date: Thu, 3 Mar 2016 01:03:55 +1100 Subject: [PATCH 06/31] Fix all the av_picture related deprecations --- src/zm_ffmpeg.cpp | 41 ++++++++++++++++++++++++++++------- src/zm_ffmpeg.h | 6 +++++ src/zm_ffmpeg_camera.cpp | 14 ++++++++++-- src/zm_local_camera.cpp | 39 +++++++++++++++++++++++++++++---- src/zm_mpeg.cpp | 28 ++++++++++++++++++++++-- src/zm_remote_camera_rtsp.cpp | 16 ++++++++++++-- 6 files changed, 126 insertions(+), 18 deletions(-) diff --git a/src/zm_ffmpeg.cpp b/src/zm_ffmpeg.cpp index 86817c223..1e54ad9e8 100644 --- a/src/zm_ffmpeg.cpp +++ b/src/zm_ffmpeg.cpp @@ -160,12 +160,21 @@ int SWScale::Convert(const uint8_t* in_buffer, const size_t in_buffer_size, uint #endif /* Check the buffer sizes */ - size_t insize = avpicture_get_size(in_pf, width, height); +#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) + size_t insize = av_image_get_buffer_size(in_pf, width, height,1); +#else + size_t insize = avpicture_get_size(in_pf, width, height); +#endif if(insize != in_buffer_size) { Error("The input buffer size does not match the expected size for the input format. Required: %d Available: %d", insize, in_buffer_size); return -4; } - size_t outsize = avpicture_get_size(out_pf, width, height); +#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) + size_t outsize = av_image_get_buffer_size(out_pf, width, height,1); +#else + size_t outsize = avpicture_get_size(out_pf, width, height); +#endif + if(outsize < out_buffer_size) { Error("The output buffer is undersized for the output format. Required: %d Available: %d", outsize, out_buffer_size); return -5; @@ -179,13 +188,29 @@ int SWScale::Convert(const uint8_t* in_buffer, const size_t in_buffer_size, uint } /* Fill in the buffers */ - if(!avpicture_fill( (AVPicture*)input_avframe, (uint8_t*)in_buffer, in_pf, width, height ) ) { - Error("Failed filling input frame with input buffer"); - return -7; +#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) + if(av_image_fill_arrays(input_avframe->data, input_avframe->linesize, + (uint8_t*)in_buffer, in_pf, width, height, 1) <= 0) + { +#else + if(avpicture_fill( (AVPicture*)input_avframe, (uint8_t*)in_buffer, + in_pf, width, height ) <= 0) + { +#endif + Error("Failed filling input frame with input buffer"); + return -7; } - if(!avpicture_fill( (AVPicture*)output_avframe, out_buffer, out_pf, width, height ) ) { - Error("Failed filling output frame with output buffer"); - return -8; +#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) + if(av_image_fill_arrays(output_avframe->data, output_avframe->linesize, + out_buffer, out_pf, width, height, 1) <= 0) + { +#else + if(avpicture_fill( (AVPicture*)output_avframe, out_buffer, + out_pf, width, height ) <= 0) + { +#endif + Error("Failed filling output frame with output buffer"); + return -8; } /* Do the conversion */ diff --git a/src/zm_ffmpeg.h b/src/zm_ffmpeg.h index 031a10671..7806682c7 100644 --- a/src/zm_ffmpeg.h +++ b/src/zm_ffmpeg.h @@ -47,6 +47,12 @@ extern "C" { #else #include #endif + +#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) +#include +#else +#include +#endif #elif HAVE_FFMPEG_AVUTIL_H #include #include diff --git a/src/zm_ffmpeg_camera.cpp b/src/zm_ffmpeg_camera.cpp index 062d819d9..cbb3e7eff 100644 --- a/src/zm_ffmpeg_camera.cpp +++ b/src/zm_ffmpeg_camera.cpp @@ -182,8 +182,13 @@ int FfmpegCamera::Capture( Image &image ) if ( frameComplete ) { Debug( 3, "Got frame %d", frameCount ); - av_image_fill_arrays(mFrame->data, mFrame->linesize, directbuffer, imagePixFormat, width, height, 1); - //avpicture_fill( (AVPicture *)mFrame, directbuffer, imagePixFormat, width, height); +#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) + av_image_fill_arrays(mFrame->data, mFrame->linesize, + directbuffer, imagePixFormat, width, height, 1); +#else + avpicture_fill( (AVPicture *)mFrame, directbuffer, + imagePixFormat, width, height); +#endif #if HAVE_LIBSWSCALE if(mConvertContext == NULL) { @@ -345,7 +350,12 @@ int FfmpegCamera::OpenFfmpeg() { Debug ( 1, "Allocated frames" ); +#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) + int pSize = av_image_get_buffer_size( imagePixFormat, width, height,1 ); +#else int pSize = avpicture_get_size( imagePixFormat, width, height ); +#endif + if( (unsigned int)pSize != imagesize) { Fatal("Image size mismatch. Required: %d Available: %d",pSize,imagesize); } diff --git a/src/zm_local_camera.cpp b/src/zm_local_camera.cpp index 022f35dbe..e1dadeb74 100644 --- a/src/zm_local_camera.cpp +++ b/src/zm_local_camera.cpp @@ -626,7 +626,11 @@ LocalCamera::LocalCamera( int p_id, const std::string &p_device, int p_channel, if ( !tmpPicture ) Fatal( "Could not allocate temporary picture" ); - int pSize = avpicture_get_size( imagePixFormat, width, height ); +#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) + int pSize = av_image_get_buffer_size( imagePixFormat, width, height,1 ); +#else + int pSize = avpicture_get_size( imagePixFormat, width, height ); +#endif if( (unsigned int)pSize != imagesize) { Fatal("Image size mismatch. Required: %d Available: %d",pSize,imagesize); } @@ -859,7 +863,18 @@ void LocalCamera::Initialise() #endif if ( !capturePictures[i] ) Fatal( "Could not allocate picture" ); - avpicture_fill( (AVPicture *)capturePictures[i], (uint8_t*)v4l2_data.buffers[i].start, capturePixFormat, v4l2_data.fmt.fmt.pix.width, v4l2_data.fmt.fmt.pix.height ); +#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) + av_image_fill_arrays(capturePictures[i]->data, + capturePictures[i]->linesize, + (uint8_t*)v4l2_data.buffers[i].start,capturePixFormat, + v4l2_data.fmt.fmt.pix.width, + v4l2_data.fmt.fmt.pix.height, 1); +#else + avpicture_fill( (AVPicture *)capturePictures[i], + (uint8_t*)v4l2_data.buffers[i].start, capturePixFormat, + v4l2_data.fmt.fmt.pix.width, + v4l2_data.fmt.fmt.pix.height ); +#endif #endif // HAVE_LIBSWSCALE } @@ -1017,7 +1032,16 @@ void LocalCamera::Initialise() #endif if ( !capturePictures[i] ) Fatal( "Could not allocate picture" ); - avpicture_fill( (AVPicture *)capturePictures[i], (unsigned char *)v4l1_data.bufptr+v4l1_data.frames.offsets[i], capturePixFormat, width, height ); +#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) + av_image_fill_arrays(capturePictures[i]->data, + capturePictures[i]->linesize, + (unsigned char *)v4l1_data.bufptr+v4l1_data.frames.offsets[i], + capturePixFormat, width, height, 1); +#else + avpicture_fill( (AVPicture *)capturePictures[i], + (unsigned char *)v4l1_data.bufptr+v4l1_data.frames.offsets[i], + capturePixFormat, width, height ); +#endif } #endif // HAVE_LIBSWSCALE @@ -2113,7 +2137,14 @@ int LocalCamera::Capture( Image &image ) Debug( 9, "Calling sws_scale to perform the conversion" ); /* Use swscale to convert the image directly into the shared memory */ - avpicture_fill( (AVPicture *)tmpPicture, directbuffer, imagePixFormat, width, height ); +#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) + av_image_fill_arrays(tmpPicture->data, + tmpPicture->linesize, directbuffer, + imagePixFormat, width, height, 1); +#else + avpicture_fill( (AVPicture *)tmpPicture, directbuffer, + imagePixFormat, width, height ); +#endif sws_scale( imgConversionContext, capturePictures[capture_frame]->data, capturePictures[capture_frame]->linesize, 0, height, tmpPicture->data, tmpPicture->linesize ); } #endif diff --git a/src/zm_mpeg.cpp b/src/zm_mpeg.cpp index 01f9006b8..77a80eb37 100644 --- a/src/zm_mpeg.cpp +++ b/src/zm_mpeg.cpp @@ -333,7 +333,13 @@ void VideoStream::OpenStream( ) Panic( "Could not allocate opicture" ); } +#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) + int size = av_image_get_buffer_size( c->pix_fmt, c->width, + c->height, 1 ); +#else int size = avpicture_get_size( c->pix_fmt, c->width, c->height ); +#endif + uint8_t *opicture_buf = (uint8_t *)av_malloc( size ); if ( !opicture_buf ) { @@ -344,7 +350,13 @@ void VideoStream::OpenStream( ) #endif Panic( "Could not allocate opicture_buf" ); } - avpicture_fill( (AVPicture *)opicture, opicture_buf, c->pix_fmt, c->width, c->height ); +#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) + av_image_fill_arrays(opicture->data, opicture->linesize, + opicture_buf, c->pix_fmt, c->width, c->height, 1); +#else + avpicture_fill( (AVPicture *)opicture, opicture_buf, c->pix_fmt, + c->width, c->height ); +#endif /* if the output format is not identical to the input format, then a temporary picture is needed too. It is then converted to the required @@ -361,7 +373,12 @@ void VideoStream::OpenStream( ) { Panic( "Could not allocate tmp_opicture" ); } +#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) + int size = av_image_get_buffer_size( pf, c->width, + c->height,1 ); +#else int size = avpicture_get_size( pf, c->width, c->height ); +#endif uint8_t *tmp_opicture_buf = (uint8_t *)av_malloc( size ); if ( !tmp_opicture_buf ) { @@ -372,7 +389,14 @@ void VideoStream::OpenStream( ) #endif Panic( "Could not allocate tmp_opicture_buf" ); } - avpicture_fill( (AVPicture *)tmp_opicture, tmp_opicture_buf, pf, c->width, c->height ); +#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) + av_image_fill_arrays(tmp_opicture->data, + tmp_opicture->linesize, tmp_opicture_buf, pf, + c->width, c->height, 1); +#else + avpicture_fill( (AVPicture *)tmp_opicture, + tmp_opicture_buf, pf, c->width, c->height ); +#endif } } diff --git a/src/zm_remote_camera_rtsp.cpp b/src/zm_remote_camera_rtsp.cpp index a07d97a8e..9bbe458bf 100644 --- a/src/zm_remote_camera_rtsp.cpp +++ b/src/zm_remote_camera_rtsp.cpp @@ -214,7 +214,12 @@ int RemoteCameraRtsp::PrimeCapture() if(mRawFrame == NULL || mFrame == NULL) Fatal( "Unable to allocate frame(s)"); - int pSize = avpicture_get_size( imagePixFormat, width, height ); +#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) + int pSize = av_image_get_buffer_size( imagePixFormat, width, height, 1 ); +#else + int pSize = avpicture_get_size( imagePixFormat, width, height ); +#endif + if( (unsigned int)pSize != imagesize) { Fatal("Image size mismatch. Required: %d Available: %d",pSize,imagesize); } @@ -330,7 +335,14 @@ int RemoteCameraRtsp::Capture( Image &image ) Debug( 3, "Got frame %d", frameCount ); - avpicture_fill( (AVPicture *)mFrame, directbuffer, imagePixFormat, width, height); +#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) + av_image_fill_arrays(mFrame->data, mFrame->linesize, + directbuffer, imagePixFormat, width, height, 1); +#else + avpicture_fill( (AVPicture *)mFrame, directbuffer, + imagePixFormat, width, height); +#endif + #if HAVE_LIBSWSCALE if(mConvertContext == NULL) { From 5f4441878e116baff4c0f23ba7145f40f461a3f6 Mon Sep 17 00:00:00 2001 From: SteveGilvarry Date: Thu, 3 Mar 2016 17:16:06 +1100 Subject: [PATCH 07/31] Coded_Frame deprecation all examples were no lomger setting AV_PKT_FLAG_KEY, is it on the packet already. --- src/zm_mpeg.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/zm_mpeg.cpp b/src/zm_mpeg.cpp index 77a80eb37..1cdf73057 100644 --- a/src/zm_mpeg.cpp +++ b/src/zm_mpeg.cpp @@ -702,14 +702,14 @@ double VideoStream::ActuallyEncodeFrame( const uint8_t *buffer, int buffer_size, #endif if ( got_packet ) { - if ( c->coded_frame->key_frame ) - { -#if LIBAVCODEC_VERSION_CHECK(52, 30, 2, 30, 2) - pkt->flags |= AV_PKT_FLAG_KEY; -#else - pkt->flags |= PKT_FLAG_KEY; -#endif - } +// if ( c->coded_frame->key_frame ) +// { +//#if LIBAVCODEC_VERSION_CHECK(52, 30, 2, 30, 2) +// pkt->flags |= AV_PKT_FLAG_KEY; +//#else +// pkt->flags |= PKT_FLAG_KEY; +//#endif +// } if ( pkt->pts != (int64_t)AV_NOPTS_VALUE ) { From 804ac1de8177fe2233f69c71382dbf2daca0ff08 Mon Sep 17 00:00:00 2001 From: arjunrc Date: Thu, 14 Apr 2016 13:53:10 -0400 Subject: [PATCH 08/31] Clone feature added --- web/lang/en_gb.php | 1 + web/skins/classic/views/console.php | 20 +- web/skins/classic/views/js/console.js | 32 +++ web/skins/classic/views/js/console.js.php | 4 +- web/skins/classic/views/monitor.php | 232 ++++++++++++---------- 5 files changed, 178 insertions(+), 111 deletions(-) diff --git a/web/lang/en_gb.php b/web/lang/en_gb.php index e2c2aac7c..d559a567a 100644 --- a/web/lang/en_gb.php +++ b/web/lang/en_gb.php @@ -230,6 +230,7 @@ $SLANG = array( 'ChooseLogFormat' => 'Choose a log format', 'ChooseLogSelection' => 'Choose a log selection', 'ChoosePreset' => 'Choose Preset', + 'CloneMonitor' => 'Clone Monitor', 'Close' => 'Close', 'Colour' => 'Colour', 'Command' => 'Command', diff --git a/web/skins/classic/views/console.php b/web/skins/classic/views/console.php index 070c85b59..dbf0ea2f4 100644 --- a/web/skins/classic/views/console.php +++ b/web/skins/classic/views/console.php @@ -77,8 +77,8 @@ $run_state = dbFetchOne('select Name from States where IsActive = 1', 'Name' ); $group = NULL; if ( ! empty($_COOKIE['zmGroup']) ) { - if ( $group = dbFetchOne( 'select * from Groups where Id = ?', NULL, array($_COOKIE['zmGroup'])) ) - $groupIds = array_flip(explode( ',', $group['MonitorIds'] )); + if ( $group = dbFetchOne( 'select * from Groups where Id = ?', NULL, array($_COOKIE['zmGroup'])) ) + $groupIds = array_flip(explode( ',', $group['MonitorIds'] )); } noCacheHeaders(); @@ -182,6 +182,7 @@ $seqDownFile = getSkinFile( 'graphics/seq-d.gif' ); $versionClass = (ZM_DYN_DB_VERSION&&(ZM_DYN_DB_VERSION!=ZM_VERSION))?'errorText':''; + xhtmlHeaders( __FILE__, translate('Console') ); ?> @@ -243,7 +244,7 @@ else - + - + + '.translate('Fn'.$monitor['Function']).( empty($monitor['Enabled']) ? ', disabled' : '' ) .'', canEdit( 'Monitors' ) ) ?> - Name(); ?> @@ -330,9 +332,9 @@ echo $Server->Name(); '.$shortpath.'', canEdit( 'Monitors' ) ) ?> diff --git a/web/skins/classic/views/js/console.js b/web/skins/classic/views/js/console.js index 5182a5fd5..99f175c23 100644 --- a/web/skins/classic/views/js/console.js +++ b/web/skins/classic/views/js/console.js @@ -1,3 +1,6 @@ +var jsTranslatedAddText; +var jsTranslatedCloneText; + function setButtonStates( element ) { var form = element.form; @@ -15,9 +18,36 @@ function setButtonStates( element ) } $(element).getParent( 'tr' ).toggleClass( 'highlight' ); form.editBtn.disabled = (checked!=1); + form.addBtn.value = (checked==1) ? jsTranslatedCloneText:jsTranslatedAddText; + form.deleteBtn.disabled = (checked==0); } +function addMonitor( element) +{ + + var form = element.form; + var dupParam; + var monitorId=-1; + if (form.addBtn.value == jsTranslatedCloneText) + { + // get the value of the first checkbox + for ( var i = 0; i < form.elements.length; i++ ) + { + if ( form.elements[i].type == "checkbox" ) + { + if ( form.elements[i].checked ) + { + monitorId = form.elements[i].value; + break; + } + } + } + } + dupParam = (monitorId == -1 ) ? '': '&dupId='+monitorId; + createPopup( '?view=monitor'+dupParam, 'zmMonitor0','monitor' ); +} + function editMonitor( element ) { var form = element.form; @@ -55,6 +85,8 @@ function reloadWindow() function initPage() { + jsTranslatedAddText = translatedAddText; + jsTranslatedCloneText = translatedCloneText; reloadWindow.periodical( consoleRefreshTimeout ); if ( showVersionPopup ) createPopup( '?view=version', 'zmVersion', 'version' ); diff --git a/web/skins/classic/views/js/console.js.php b/web/skins/classic/views/js/console.js.php index 93cf0cdb7..98417a985 100644 --- a/web/skins/classic/views/js/console.js.php +++ b/web/skins/classic/views/js/console.js.php @@ -26,7 +26,7 @@ elseif ( ZM_DYN_SHOW_DONATE_REMINDER ) ?> var showVersionPopup = ; var showDonatePopup = ; - - +var translatedAddText = ""; +var translatedCloneText = ""; diff --git a/web/skins/classic/views/monitor.php b/web/skins/classic/views/monitor.php index c55d77187..9f4375eae 100644 --- a/web/skins/classic/views/monitor.php +++ b/web/skins/classic/views/monitor.php @@ -42,11 +42,11 @@ if ( isset($_REQUEST['tab']) ) else $tab = "general"; - $Server = null; + $Server = null; if ( defined( 'ZM_SERVER_ID' ) ) { $Server = dbFetchOne( 'SELECT * FROM Servers WHERE Id=?', NULL, array( ZM_SERVER_ID ) ); - } - if ( ! $Server ) { + } + if ( ! $Server ) { $Server = array( 'Id' => '' ); } @@ -56,74 +56,11 @@ if ( ! empty($_REQUEST['mid']) ) { $x10Monitor = dbFetchOne( 'SELECT * FROM TriggersX10 WHERE MonitorId = ?', NULL, array($_REQUEST['mid']) ); } else { - $nextId = getTableAutoInc( 'Monitors' ); - $monitor = array( - 'Id' => 0, - 'Name' => translate('Monitor').'-'.$nextId, - 'Function' => "Monitor", - 'Enabled' => true, - 'LinkedMonitors' => "", - 'Type' => "", - 'Device' => "/dev/video0", - 'Channel' => "0", - 'Format' => 0x000000ff, - 'Protocol' => "", - 'Method' => "", - 'Host' => "", - 'Path' => "", - 'Options' => "", - 'Port' => "80", - 'User' => "", - 'Pass' => "", - 'Colours' => 3, - 'Palette' => 0, - 'Width' => "320", - 'Height' => "240", - 'Orientation' => "0", - 'Deinterlacing' => 0, - 'RTSPDescribe' => 0, - 'LabelFormat' => '%N - %d/%m/%y %H:%M:%S', - 'LabelX' => 0, - 'LabelY' => 0, - 'LabelSize' => 1, - 'ImageBufferCount' => 50, - 'WarmupCount' => 25, - 'PreEventCount' => 25, - 'PostEventCount' => 25, - 'StreamReplayBuffer' => 1000, - 'AlarmFrameCount' => 1, - 'Controllable' => 0, - 'ControlId' => "", - 'ControlType' => 0, - 'ControlDevice' => "", - 'ControlAddress' => "", - 'AutoStopTimeout' => "", - 'TrackMotion' => 0, - 'TrackDelay' => "", - 'ReturnLocation' => -1, - 'ReturnDelay' => "", - 'SectionLength' => 600, - 'FrameSkip' => 0, - 'MotionFrameSkip' => 0, - 'EventPrefix' => 'Event-', - 'AnalysisFPS' => "", - 'AnalysisUpdateDelay' => 0, - 'MaxFPS' => "", - 'AlarmMaxFPS' => "", - 'FPSReportInterval' => 1000, - 'RefBlendPerc' => 6, - 'AlarmRefBlendPerc' => 6, - 'DefaultView' => 'Events', - 'DefaultRate' => '100', - 'DefaultScale' => '100', - 'SignalCheckColour' => '#0000c0', - 'WebColour' => 'red', - 'Exif' => '0', - 'Triggers' => "", - 'V4LMultiBuffer' => '', - 'V4LCapturesPerFrame' => 1, - 'ServerId' => $Server['Id'], - ); + $nextId = getTableAutoInc( 'Monitors' ); + $monitor = getMonitorObject($_REQUEST['dupId']); + $clonedName = $monitor['Name']; + $monitor['Name'] = translate('Monitor').'-'.$nextId; + $monitor['Id']='0'; } if ( ZM_OPT_X10 && empty($x10Monitor) ) @@ -135,6 +72,85 @@ if ( ZM_OPT_X10 && empty($x10Monitor) ) ); } +function getMonitorObject( $mid = null) +{ + if ($mid !== null) + { + $monitor = dbFetchMonitor($mid); + } + else + { + $monitor = array( + 'Id' => 0, + 'Name' => "willbereplaced", + 'Function' => "Monitor", + 'Enabled' => true, + 'LinkedMonitors' => "", + 'Type' => "", + 'Device' => "/dev/video0", + 'Channel' => "0", + 'Format' => 0x000000ff, + 'Protocol' => "", + 'Method' => "", + 'Host' => "", + 'Path' => "", + 'Options' => "", + 'Port' => "80", + 'User' => "", + 'Pass' => "", + 'Colours' => 3, + 'Palette' => 0, + 'Width' => "320", + 'Height' => "240", + 'Orientation' => "0", + 'Deinterlacing' => 0, + 'RTSPDescribe' => 0, + 'LabelFormat' => '%N - %d/%m/%y %H:%M:%S', + 'LabelX' => 0, + 'LabelY' => 0, + 'LabelSize' => 1, + 'ImageBufferCount' => 50, + 'WarmupCount' => 25, + 'PreEventCount' => 25, + 'PostEventCount' => 25, + 'StreamReplayBuffer' => 1000, + 'AlarmFrameCount' => 1, + 'Controllable' => 0, + 'ControlId' => "", + 'ControlType' => 0, + 'ControlDevice' => "", + 'ControlAddress' => "", + 'AutoStopTimeout' => "", + 'TrackMotion' => 0, + 'TrackDelay' => "", + 'ReturnLocation' => -1, + 'ReturnDelay' => "", + 'SectionLength' => 600, + 'FrameSkip' => 0, + 'MotionFrameSkip' => 0, + 'EventPrefix' => 'Event-', + 'AnalysisFPS' => "", + 'AnalysisUpdateDelay' => 0, + 'MaxFPS' => "", + 'AlarmMaxFPS' => "", + 'FPSReportInterval' => 1000, + 'RefBlendPerc' => 6, + 'AlarmRefBlendPerc' => 6, + 'DefaultView' => 'Events', + 'DefaultRate' => '100', + 'DefaultScale' => '100', + 'SignalCheckColour' => '#0000c0', + 'WebColour' => 'red', + 'Exif' => '0', + 'Triggers' => "", + 'V4LMultiBuffer' => '', + 'V4LCapturesPerFrame' => 1, + 'ServerId' => $Server['Id'], + ); + } + return ($monitor); +} + function fourcc( $a, $b, $c, $d ) { return( ord($a) | (ord($b) << 8) | (ord($c) << 16) | (ord($d) << 24) ); @@ -450,16 +466,31 @@ xhtmlHeaders(__FILE__, translate('Monitor')." - ".validHtmlStr($monitor['Name']) if ( canEdit( 'Monitors' ) ) { ?> + + + +
+ Configuration cloned from Monitor: +
+ + +
- - - + + +
'None'); - $result = dbQuery( 'SELECT * FROM Servers ORDER BY Name'); - $results = $result->fetchALL(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'Server' ); - foreach ( $results as $row => $server_obj ) { - $servers[$server_obj->Id] = $server_obj->Name(); - } + $servers = array(''=>'None'); + $result = dbQuery( 'SELECT * FROM Servers ORDER BY Name'); + $results = $result->fetchALL(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'Server' ); + foreach ( $results as $row => $server_obj ) { + $servers[$server_obj->Id] = $server_obj->Name(); + } ?> - + @@ -775,15 +806,15 @@ switch ( $tab ) - - /> - - /> - - /> - - - + + /> + + /> + + /> + + + - + -  () +  () @@ -956,8 +987,9 @@ switch ( $tab )
disabled="disabled"/>
+ - + From 7058b0862acd7b6a5f1a415514fce8d5087fcfec Mon Sep 17 00:00:00 2001 From: abi Date: Sat, 16 Apr 2016 16:39:58 +0300 Subject: [PATCH 09/31] suppressed warnings of killall for FreeBSD --- scripts/zmdc.pl.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/zmdc.pl.in b/scripts/zmdc.pl.in index b068b9a49..36d5e922a 100644 --- a/scripts/zmdc.pl.in +++ b/scripts/zmdc.pl.in @@ -862,7 +862,7 @@ sub killAll my $killall; if ( '@HOST_OS@' eq 'BSD' ) { - $killall = 'killall -'; + $killall = 'killall -q -'; } elsif ( '@HOST_OS@' eq 'solaris' ) { $killall = 'pkill -'; } else { From d9646d6ceb99d8f567619db426e2d0e63c9ed9ae Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 19 Apr 2016 15:19:37 -0400 Subject: [PATCH 10/31] Populate a Monitors hash with the Monitors data so we don't have to use in JOINs later --- scripts/zmaudit.pl.in | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/zmaudit.pl.in b/scripts/zmaudit.pl.in index c95f65441..7f7fc4257 100644 --- a/scripts/zmaudit.pl.in +++ b/scripts/zmaudit.pl.in @@ -155,10 +155,12 @@ MAIN: while( $loop ) { Fatal("ZM_AUDIT_MIN_AGE is not set in config."); } + my %Monitors; my $db_monitors; - my $monitorSelectSql = "select Id from Monitors order by Id"; + my $monitorSelectSql = "select * from Monitors order by Id"; my $monitorSelectSth = $dbh->prepare_cached( $monitorSelectSql ) or Fatal( "Can't prepare '$monitorSelectSql': ".$dbh->errstr() ); + my $eventSelectSql = "SELECT Id, (unix_timestamp() - unix_timestamp(StartTime)) as Age FROM Events WHERE MonitorId = ? ORDER BY Id"; my $eventSelectSth = $dbh->prepare_cached( $eventSelectSql ) @@ -169,6 +171,8 @@ MAIN: while( $loop ) { or Fatal( "Can't execute: ".$monitorSelectSth->errstr() ); while( my $monitor = $monitorSelectSth->fetchrow_hashref() ) { + $Monitors{$$monitor{Id}} = $monitor; + Debug( "Found database monitor '$monitor->{Id}'" ); my $db_events = $db_monitors->{$monitor->{Id}} = {}; my $res = $eventSelectSth->execute( $monitor->{Id} ) From 588dbc0c3c3a71dfea1653bddce0af3551560204 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 19 Apr 2016 15:22:46 -0400 Subject: [PATCH 11/31] Don't JOIN MOnitors to get event prefix. Use {->MonitorID} instead --- scripts/zmaudit.pl.in | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/scripts/zmaudit.pl.in b/scripts/zmaudit.pl.in index 7f7fc4257..d3f5eadd2 100644 --- a/scripts/zmaudit.pl.in +++ b/scripts/zmaudit.pl.in @@ -471,16 +471,14 @@ MAIN: while( $loop ) { # New audit to close any events that were left open for longer than MIN_AGE seconds my $selectUnclosedEventsSql = - "SELECT E.Id, + "SELECT E.Id, E.MonitorId, max(F.TimeStamp) as EndTime, unix_timestamp(max(F.TimeStamp)) - unix_timestamp(E.StartTime) as Length, max(F.FrameId) as Frames, count(if(F.Score>0,1,NULL)) as AlarmFrames, sum(F.Score) as TotScore, - max(F.Score) as MaxScore, - M.EventPrefix as Prefix + max(F.Score) as MaxScore FROM Events as E - LEFT JOIN Monitors as M on E.MonitorId = M.Id INNER JOIN Frames as F on E.Id = F.EventId WHERE isnull(E.Frames) or isnull(E.EndTime) GROUP BY E.Id HAVING EndTime < (now() - interval ".$Config{ZM_AUDIT_MIN_AGE}." second)" @@ -512,7 +510,7 @@ MAIN: while( $loop ) { $res = $updateUnclosedEventsSth->execute ( sprintf("%s%d%s", - $event->{Prefix}, + $Monitors{$event->{MonitorId}->{Prefix}, $event->{Id}, RECOVER_TAG ), From bb15915ce58681c3dcccf9c44f633379eb20d1f6 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 19 Apr 2016 15:23:36 -0400 Subject: [PATCH 12/31] Use EventPrefix, not Prefix --- scripts/zmaudit.pl.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/zmaudit.pl.in b/scripts/zmaudit.pl.in index d3f5eadd2..b1e54cd17 100644 --- a/scripts/zmaudit.pl.in +++ b/scripts/zmaudit.pl.in @@ -510,7 +510,7 @@ MAIN: while( $loop ) { $res = $updateUnclosedEventsSth->execute ( sprintf("%s%d%s", - $Monitors{$event->{MonitorId}->{Prefix}, + $Monitors{$event->{MonitorId}->{EventPrefix}, $event->{Id}, RECOVER_TAG ), From d2870f06928b0975fca082c58649c5260ba45394 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 20 Apr 2016 09:44:11 -0400 Subject: [PATCH 13/31] move the mysql_free_result, looks like we can't free it until we free the row --- src/zm_db.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/zm_db.cpp b/src/zm_db.cpp index a342ca14b..bc15d9ec6 100644 --- a/src/zm_db.cpp +++ b/src/zm_db.cpp @@ -100,12 +100,13 @@ MYSQL_ROW zmDbFetchOne( const char *query ) { int n_rows = mysql_num_rows( result ); if ( n_rows != 1 ) { Error( "Bogus number of lines return from query, %d returned for query %s.", n_rows, query ); + mysql_free_result( result ); return NULL; } MYSQL_ROW dbrow = mysql_fetch_row( result ); - mysql_free_result( result ); if ( ! dbrow ) { + mysql_free_result( result ); Error("Error getting row from query %s. Error is %s", query, mysql_error( &dbconn ) ); return NULL; } From e52e88055367fa3eb60981f687f931207ef626eb Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 20 Apr 2016 10:00:13 -0400 Subject: [PATCH 14/31] rework open event check to not use group by --- scripts/zmaudit.pl.in | 76 ++++++++++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 29 deletions(-) diff --git a/scripts/zmaudit.pl.in b/scripts/zmaudit.pl.in index b1e54cd17..a8cebde89 100644 --- a/scripts/zmaudit.pl.in +++ b/scripts/zmaudit.pl.in @@ -471,18 +471,30 @@ MAIN: while( $loop ) { # New audit to close any events that were left open for longer than MIN_AGE seconds my $selectUnclosedEventsSql = - "SELECT E.Id, E.MonitorId, - max(F.TimeStamp) as EndTime, - unix_timestamp(max(F.TimeStamp)) - unix_timestamp(E.StartTime) as Length, - max(F.FrameId) as Frames, + #"SELECT E.Id, ANY_VALUE(E.MonitorId), +# + #max(F.TimeStamp) as EndTime, + #unix_timestamp(max(F.TimeStamp)) - unix_timestamp(E.StartTime) as Length, + #max(F.FrameId) as Frames, + #count(if(F.Score>0,1,NULL)) as AlarmFrames, + #sum(F.Score) as TotScore, + #max(F.Score) as MaxScore + #FROM Events as E + #INNER JOIN Frames as F on E.Id = F.EventId + #WHERE isnull(E.Frames) or isnull(E.EndTime) + #GROUP BY E.Id HAVING EndTime < (now() - interval ".$Config{ZM_AUDIT_MIN_AGE}." second)" + #; + "SELECT *, unix_timestamp(StartTime) AS TimeStamp FROM Events WHERE EndTime IS NULL AND StartTime < (now() - interval ".$Config{ZM_AUDIT_MIN_AGE}." second)"; + + my $selectFrameDataSql = "SELECT max(TimeStamp) as EndTime, unix_timestamp(max(TimeStamp)) AS EndTimeStamp, max(FrameId) as Frames, count(if(F.Score>0,1,NULL)) as AlarmFrames, sum(F.Score) as TotScore, max(F.Score) as MaxScore - FROM Events as E - INNER JOIN Frames as F on E.Id = F.EventId - WHERE isnull(E.Frames) or isnull(E.EndTime) - GROUP BY E.Id HAVING EndTime < (now() - interval ".$Config{ZM_AUDIT_MIN_AGE}." second)" - ; + FROM Frames WHERE EventId=?"; + my $selectFrameDataSth = $dbh->prepare_cached($selectFrameDataSql) + or Fatal( "Can't prepare '$selectFrameDataSql': ".$dbh->errstr() ); + + my $selectUnclosedEventsSth = $dbh->prepare_cached( $selectUnclosedEventsSql ) or Fatal( "Can't prepare '$selectUnclosedEventsSql': ".$dbh->errstr() ); my $updateUnclosedEventsSql = @@ -507,26 +519,32 @@ MAIN: while( $loop ) { aud_print( "Found open event '$event->{Id}'" ); if ( confirm( 'close', 'closing' ) ) { - $res = $updateUnclosedEventsSth->execute - ( - sprintf("%s%d%s", - $Monitors{$event->{MonitorId}->{EventPrefix}, - $event->{Id}, - RECOVER_TAG - ), - $event->{EndTime}, - $event->{Length}, - $event->{Frames}, - $event->{AlarmFrames}, - $event->{TotScore}, - $event->{AlarmFrames} - ? int($event->{TotScore} / $event->{AlarmFrames}) - : 0 - , - $event->{MaxScore}, - RECOVER_TEXT, - $event->{Id} - ) or Fatal( "Can't execute: ".$updateUnclosedEventsSth->errstr() ); + $res = $selectFrameDataSth->execute( $event->{Id} ); + my $frame = $selectFrameDataSth->fetchrow_hashref(); + if ( $frame ) { + $res = $updateUnclosedEventsSth->execute + ( + sprintf("%s%d%s", + $Monitors{$event->{MonitorId}}->{EventPrefix}, + $event->{Id}, + RECOVER_TAG + ), + $frame->{EndTime}, + $frame->{EndTimeStamp} - $event->{TimeStamp}, + $frame->{Frames}, + $frame->{AlarmFrames}, + $frame->{TotScore}, + $frame->{AlarmFrames} + ? int($frame->{TotScore} / $frame->{AlarmFrames}) + : 0 + , + $frame->{MaxScore}, + RECOVER_TEXT, + $event->{Id} + ) or Fatal( "Can't execute: ".$updateUnclosedEventsSth->errstr() ); + } else { + Error("SHOULD DELETE"); + } # end if has frame data } } From 44f32f46b7620a63e2a43a9a41f4ae8e4bd2ea89 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 20 Apr 2016 11:56:58 -0400 Subject: [PATCH 15/31] deprecate zmdbFetchOne in favor of zmDbRow --- src/zm_config.cpp | 6 +++-- src/zm_db.cpp | 50 +++++++++++++++++++++++++++------------- src/zm_db.h | 17 +++++++++++++- src/zm_ffmpeg_camera.cpp | 4 ++-- src/zm_monitor.cpp | 8 +++---- src/zm_storage.cpp | 4 ++-- 6 files changed, 62 insertions(+), 27 deletions(-) diff --git a/src/zm_config.cpp b/src/zm_config.cpp index 5a7454a7b..1a5c65840 100644 --- a/src/zm_config.cpp +++ b/src/zm_config.cpp @@ -117,7 +117,8 @@ void zmLoadConfig() Debug( 1, "Fetching ZM_SERVER_ID For Name = %s", staticConfig.SERVER_NAME.c_str() ); std::string sql = stringtf("SELECT Id FROM Servers WHERE Name='%s'", staticConfig.SERVER_NAME.c_str() ); - if ( MYSQL_ROW dbrow = zmDbFetchOne( sql.c_str() ) ) { + zmDbRow dbrow; + if ( dbrow.fetch( sql.c_str() ) ) { staticConfig.SERVER_ID = atoi(dbrow[0]); } else { Fatal("Can't get ServerId for Server %s", staticConfig.SERVER_NAME.c_str() ); @@ -128,7 +129,8 @@ void zmLoadConfig() Debug( 1, "Fetching ZM_SERVER_NAME For Id = %d", staticConfig.SERVER_ID ); std::string sql = stringtf("SELECT Name FROM Servers WHERE Id='%d'", staticConfig.SERVER_ID ); - if ( MYSQL_ROW dbrow = zmDbFetchOne( sql.c_str() ) ) { + zmDbRow dbrow; + if ( dbrow.fetch( sql.c_str() ) ) { staticConfig.SERVER_NAME = std::string(dbrow[0]); } else { Fatal("Can't get ServerName for Server ID %d", staticConfig.SERVER_ID ); diff --git a/src/zm_db.cpp b/src/zm_db.cpp index bc15d9ec6..7d418abf9 100644 --- a/src/zm_db.cpp +++ b/src/zm_db.cpp @@ -95,20 +95,38 @@ MYSQL_RES * zmDbFetch( const char * query ) { return result; } // end MYSQL_RES * zmDbFetch( const char * query ); -MYSQL_ROW zmDbFetchOne( const char *query ) { - MYSQL_RES *result = zmDbFetch( query ); - int n_rows = mysql_num_rows( result ); - if ( n_rows != 1 ) { - Error( "Bogus number of lines return from query, %d returned for query %s.", n_rows, query ); - mysql_free_result( result ); - return NULL; - } - - MYSQL_ROW dbrow = mysql_fetch_row( result ); - if ( ! dbrow ) { - mysql_free_result( result ); - Error("Error getting row from query %s. Error is %s", query, mysql_error( &dbconn ) ); - return NULL; - } - return dbrow; +zmDbRow *zmDbFetchOne( const char *query ) { + zmDbRow *row = new zmDbRow(); + if ( row->fetch( query ) ) { + return row; + } + delete row; + return NULL; +} + +MYSQL_RES *zmDbRow::fetch( const char *query ) { + result_set = zmDbFetch( query ); + if ( ! result_set ) return result_set; + + int n_rows = mysql_num_rows( result_set ); + if ( n_rows != 1 ) { + Error( "Bogus number of lines return from query, %d returned for query %s.", n_rows, query ); + mysql_free_result( result_set ); + result_set = NULL; + return result_set; + } + + row = mysql_fetch_row( result_set ); + if ( ! row ) { + mysql_free_result( result_set ); + result_set = NULL; + Error("Error getting row from query %s. Error is %s", query, mysql_error( &dbconn ) ); + } else { + Debug(3, "Succes"); + } + return result_set; +} +zmDbRow::~zmDbRow() { + if ( result_set ) + mysql_free_result( result_set ); } diff --git a/src/zm_db.h b/src/zm_db.h index 6ec1b5e4e..50ae2974f 100644 --- a/src/zm_db.h +++ b/src/zm_db.h @@ -22,6 +22,21 @@ #include +class zmDbRow { + private: + MYSQL_RES *result_set; + MYSQL_ROW row; + public: + zmDbRow() { result_set = NULL; row = NULL; }; + MYSQL_RES *fetch( const char *query ); + zmDbRow( MYSQL_RES *, MYSQL_ROW *row ); + ~zmDbRow(); + + char *operator[](unsigned int index) const { + return row[index]; + } +}; + #ifdef __cplusplus extern "C" { #endif @@ -33,7 +48,7 @@ void zmDbConnect(); void zmDbClose(); MYSQL_RES * zmDbFetch( const char *query ); -MYSQL_ROW zmDbFetchOne( const char *query ); +zmDbRow *zmDbFetchOne( const char *query ); #ifdef __cplusplus } /* extern "C" */ diff --git a/src/zm_ffmpeg_camera.cpp b/src/zm_ffmpeg_camera.cpp index 7e1813896..88a2a43c5 100644 --- a/src/zm_ffmpeg_camera.cpp +++ b/src/zm_ffmpeg_camera.cpp @@ -594,8 +594,8 @@ int FfmpegCamera::CaptureAndRecord( Image &image, bool recording, char* event_fi //Keep the last keyframe so we can establish immediate video if(packet.flags & AV_PKT_FLAG_KEY) { - Debug(4, "Have keyframe"); - av_copy_packet(&lastKeyframePkt, &packet); + //Debug(4, "Have keyframe"); + //av_copy_packet(&lastKeyframePkt, &packet); //TODO I think we need to store the key frame location for seeking as part of the event } diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index b747934d2..b90820362 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -1119,8 +1119,8 @@ void Monitor::DumpZoneImage( const char *zone_string ) { Debug(3, "Trying to load from event"); // Grab the most revent event image std::string sql = stringtf( "SELECT MAX(Id) FROM Events WHERE MonitorId=%d AND Frames > 0", id ); - MYSQL_ROW eventid_row = zmDbFetchOne(sql.c_str() ); - if ( eventid_row ) { + zmDbRow eventid_row; + if ( eventid_row.fetch( sql.c_str() ) ) { int event_id = atoi( eventid_row[0] ); Debug( 3, "Got event %d", event_id ); @@ -2770,8 +2770,8 @@ int Monitor::LoadFfmpegMonitors( const char *file, Monitor **&monitors, Purpose Monitor *Monitor::Load( unsigned int p_id, bool load_zones, Purpose purpose ) { std::string sql = stringtf( "select Id, Name, ServerId, StorageId, Type, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, V4LMultiBuffer, V4LCapturesPerFrame, Protocol, Method, Host, Port, Path, Options, User, Pass, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, RTSPDescribe, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour, Exif from Monitors where Id = %d", p_id ); - MYSQL_ROW dbrow = zmDbFetchOne( sql.c_str() ); - if ( ! dbrow ) { + zmDbRow dbrow; + if ( ! dbrow.fetch( sql.c_str() ) ) { Error( "Can't use query result: %s", mysql_error( &dbconn ) ); exit( mysql_errno( &dbconn ) ); } diff --git a/src/zm_storage.cpp b/src/zm_storage.cpp index 14a6cfc01..ff2bce5a9 100644 --- a/src/zm_storage.cpp +++ b/src/zm_storage.cpp @@ -50,8 +50,8 @@ Storage::Storage( unsigned int p_id ) { char sql[ZM_SQL_SML_BUFSIZ]; snprintf( sql, sizeof(sql), "SELECT Id, Name, Path from Storage WHERE Id=%d", p_id ); Debug(1,"Loading Storage for %d using %s", p_id, sql ); - MYSQL_ROW dbrow = zmDbFetchOne( sql ); - if ( ! dbrow ) { + zmDbRow dbrow; + if ( ! dbrow.fetch( sql ) ) { Error( "Unable to load storage area for id %d: %s", p_id, mysql_error( &dbconn ) ); } else { unsigned int index = 0; From c7fee31c85fe8c7d362af9e2c3fb4477b0fa04aa Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 20 Apr 2016 14:21:37 -0400 Subject: [PATCH 16/31] use --filter instead of -f because -f is ambiguous --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 183d22e57..3dbe1e066 100644 --- a/.travis.yml +++ b/.travis.yml @@ -45,4 +45,4 @@ script: - mysql -uzmuser -pzmpass < db/zm_create.sql - mysql -uzmuser -pzmpass zm < db/test.monitor.sql - sudo zmpkg.pl start - - sudo zmfilter.pl -f purgewhenfull + - sudo zmfilter.pl --filter purgewhenfull From 02a56b811bbaa01f54540fef1c971c807d424002 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 20 Apr 2016 14:38:51 -0400 Subject: [PATCH 17/31] Don't be recursive when chowning /var/cache/zoneminder --- distros/debian/postinst | 2 +- distros/ubuntu1204/zoneminder.postinst | 2 +- distros/ubuntu1504/zoneminder.postinst | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/distros/debian/postinst b/distros/debian/postinst index 8bb4d23eb..39e3dfc32 100644 --- a/distros/debian/postinst +++ b/distros/debian/postinst @@ -10,7 +10,7 @@ if [ "$1" = "configure" ]; then chown www-data:root /var/log/zm chown www-data:www-data /var/lib/zm if [ -z "$2" ]; then - chown www-data:www-data -R /var/cache/zoneminder + chown www-data:www-data /var/cache/zoneminder /var/cache/zoneminder/* fi # Do this every time the package is installed or upgraded diff --git a/distros/ubuntu1204/zoneminder.postinst b/distros/ubuntu1204/zoneminder.postinst index 1bfd41d42..7c01cdde4 100644 --- a/distros/ubuntu1204/zoneminder.postinst +++ b/distros/ubuntu1204/zoneminder.postinst @@ -10,7 +10,7 @@ if [ "$1" = "configure" ]; then chown www-data:root /var/log/zm chown www-data:www-data /var/lib/zm if [ -z "$2" ]; then - chown www-data:www-data -R /var/cache/zoneminder + chown www-data:www-data /var/cache/zoneminder /var/cache/zoneminder/* fi # Do this every time the package is installed or upgraded diff --git a/distros/ubuntu1504/zoneminder.postinst b/distros/ubuntu1504/zoneminder.postinst index c45474e1d..64699d1ca 100644 --- a/distros/ubuntu1504/zoneminder.postinst +++ b/distros/ubuntu1504/zoneminder.postinst @@ -10,7 +10,7 @@ if [ "$1" = "configure" ]; then chown www-data:root /var/log/zm chown www-data:www-data /var/lib/zm if [ -z "$2" ]; then - chown www-data:www-data -R /var/cache/zoneminder + chown www-data:www-data /var/cache/zoneminder /var/cache/zoneminder/* fi # Do this every time the package is installed or upgraded From e218e91e243495d5366170ef72c19411fff9f684 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 20 Apr 2016 14:58:18 -0400 Subject: [PATCH 18/31] add php7 versions for 1604 --- distros/ubuntu1504/control | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/distros/ubuntu1504/control b/distros/ubuntu1504/control index c1b7d958f..1165b6210 100644 --- a/distros/ubuntu1504/control +++ b/distros/ubuntu1504/control @@ -57,12 +57,12 @@ Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends} ,libsys-cpu-perl, libsys-meminfo-perl ,mysql-client | virtual-mysql-client ,perl-modules - ,php5-mysql, php5-gd + ,php5-mysql | php7-mysql, php5-gd | php-gd ,policykit-1 ,rsyslog | system-log-daemon ,zip Recommends: ${misc:Recommends} - ,libapache2-mod-php5 | php5-fpm + ,libapache2-mod-php5 | libapache2-mod-php7 | php5-fpm ,mysql-server | virtual-mysql-server ,zoneminder-doc (>= ${source:Version}) Suggests: fcgiwrap, logrotate From 8b96872efe5fb8cdf9da4f632770675f84ea0433 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 20 Apr 2016 15:04:50 -0400 Subject: [PATCH 19/31] shoudl be php-mysql for php7 --- distros/ubuntu1504/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/distros/ubuntu1504/control b/distros/ubuntu1504/control index 1165b6210..b71a35e88 100644 --- a/distros/ubuntu1504/control +++ b/distros/ubuntu1504/control @@ -57,7 +57,7 @@ Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends} ,libsys-cpu-perl, libsys-meminfo-perl ,mysql-client | virtual-mysql-client ,perl-modules - ,php5-mysql | php7-mysql, php5-gd | php-gd + ,php5-mysql | php-mysql, php5-gd | php-gd ,policykit-1 ,rsyslog | system-log-daemon ,zip From 1072327dd13d5f8d0a63a3d5ba2b2dc14468f7e8 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Thu, 21 Apr 2016 08:01:13 -0500 Subject: [PATCH 20/31] remove extra quote --- scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in b/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in index d4bb9bd38..fc4143d8a 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in +++ b/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in @@ -3830,7 +3830,7 @@ body = "ZM alarm detected - %EL% secs, %EF%/%EFA% frames, t%EST%/m%ESM%/a%ESA% s default => "no", description => qqq(" Use a SSMTP mail server if available. - NEW_MAIL_MODULES must be enabled" + NEW_MAIL_MODULES must be enabled "), requires => [ { name => "ZM_OPT_EMAIL", value => "yes" }, From 6a319667818198c3e5e3850eb266cf4d60c59291 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 22 Apr 2016 13:35:20 -0400 Subject: [PATCH 21/31] shift to match debian --- distros/ubuntu1504/control | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/distros/ubuntu1504/control b/distros/ubuntu1504/control index b71a35e88..0b32a37ac 100644 --- a/distros/ubuntu1504/control +++ b/distros/ubuntu1504/control @@ -6,6 +6,7 @@ Uploaders: Vagrant Cascadian Build-Depends: debhelper (>= 9), dh-systemd, python-sphinx | python3-sphinx, apache2-dev, dh-linktree ,cmake ,libavcodec-ffmpeg-dev, libavformat-ffmpeg-dev, libswscale-ffmpeg-dev, libavutil-ffmpeg-dev, libavdevice-ffmpeg-dev + ,libx264-dev, libmp4v2-dev, ,libbz2-dev ,libgcrypt-dev ,libcurl4-gnutls-dev @@ -34,10 +35,8 @@ Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends} ,javascript-common ,libav-tools - ,libdate-manip-perl + ,libdate-manip-perl, libmime-lite-perl, libmime-tools-perl ,libdbd-mysql-perl - ,libmime-lite-perl - ,libmime-tools-perl ,libphp-serialization-perl ,libmodule-load-conditional-perl ,libnet-sftp-foreign-perl From 30b746c603f0aad8b1480b6c710ae790da1fe102 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 22 Apr 2016 13:35:40 -0400 Subject: [PATCH 22/31] Add missing ()'s --- .../classic/includes/control_functions.php | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/web/skins/classic/includes/control_functions.php b/web/skins/classic/includes/control_functions.php index cc99cacbc..d1212aec3 100644 --- a/web/skins/classic/includes/control_functions.php +++ b/web/skins/classic/includes/control_functions.php @@ -30,7 +30,7 @@ function getControlCommands( $monitor ) $cmds['PresetGoto'] = "presetGoto"; $cmds['PresetHome'] = "presetHome"; - if ( !empty($monitor->CanZoom) ) + if ( !empty($monitor->CanZoom()) ) { if ( $monitor->CanZoomCon() ) $cmds['ZoomRoot'] = "zoomCon"; @@ -45,7 +45,7 @@ function getControlCommands( $monitor ) $cmds['ZoomMan'] = "zoomMan"; } - if ( !empty($monitor->CanFocus) ) + if ( !empty($monitor->CanFocus()) ) { if ( $monitor->CanFocusCon() ) $cmds['FocusRoot'] = "focusCon"; @@ -60,7 +60,7 @@ function getControlCommands( $monitor ) $cmds['FocusMan'] = "focusMan"; } - if ( !empty($monitor->CanIris) ) + if ( !empty($monitor->CanIris()) ) { if ( $monitor->CanIrisCon() ) $cmds['IrisRoot'] = "irisCon"; @@ -75,7 +75,7 @@ function getControlCommands( $monitor ) $cmds['IrisMan'] = "irisMan"; } - if ( !empty($monitor->CanWhite) ) + if ( !empty($monitor->CanWhite()) ) { if ( $monitor->CanWhiteCon() ) $cmds['WhiteRoot'] = "whiteCon"; @@ -89,7 +89,7 @@ function getControlCommands( $monitor ) $cmds['WhiteMan'] = "whiteMan"; } - if ( !empty($monitor->CanGain) ) + if ( !empty($monitor->CanGain()) ) { if ( $monitor->CanGainCon() ) $cmds['GainRoot'] = "gainCon"; @@ -103,7 +103,7 @@ function getControlCommands( $monitor ) $cmds['GainMan'] = "gainMan"; } - if ( !empty($monitor->CanMove) ) + if ( !empty($monitor->CanMove()) ) { if ( $monitor->CanMoveCon() ) { @@ -246,9 +246,9 @@ function controlPanTilt( $monitor, $cmds )
CanPan; - $hasTilt = $monitor->CanTilt; - $hasDiag = $hasPan && $hasTilt && $monitor->CanMoveDiag; + $hasPan = $monitor->CanPan(); + $hasTilt = $monitor->CanTilt(); + $hasDiag = $hasPan && $hasTilt && $monitor->CanMoveDiag(); ?>
@@ -278,7 +278,7 @@ function controlPresets( $monitor, $cmds ) $labels[$row['Preset']] = $row['Label']; } - $presetBreak = (int)(($monitor->NumPresets+1)/((int)(($monitor->NumPresets-1)/MAX_PRESETS)+1)); + $presetBreak = (int)(($monitor->NumPresets()+1)/((int)(($monitor->NumPresets()-1)/MAX_PRESETS)+1)); ob_start(); ?> @@ -286,7 +286,7 @@ function controlPresets( $monitor, $cmds )
NumPresets; $i++ ) + for ( $i = 1; $i <= $monitor->NumPresets(); $i++ ) { ?>" value="" onclick="controlCmd('');"/> Date: Fri, 22 Apr 2016 13:36:12 -0400 Subject: [PATCH 23/31] remove unneeded global --- web/skins/classic/includes/export_functions.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/web/skins/classic/includes/export_functions.php b/web/skins/classic/includes/export_functions.php index e604536e8..686d0174e 100644 --- a/web/skins/classic/includes/export_functions.php +++ b/web/skins/classic/includes/export_functions.php @@ -589,7 +589,6 @@ else if (document.layers) window.onload=start_slider; function exportEventImagesMaster( $eids ) { - global $SLANG; ob_start(); exportHeader( translate('Images').' Master' ); ?> @@ -599,9 +598,9 @@ function exportEventImagesMaster( $eids ) foreach ($eids as $eid) { //get monitor id and event id $sql = 'SELECT E.MonitorId, E.StartTime, E.Id - FROM Monitors AS M INNER JOIN Events AS E ON (M.Id = E.MonitorId) - WHERE E.Id = ? - '; + FROM Monitors AS M INNER JOIN Events AS E ON (M.Id = E.MonitorId) + WHERE E.Id = ? + '; $event = dbFetchOne( $sql, NULL, array( $eid ) ); $eventMonitorId[$eid] = $event['MonitorId']; $eventPath[$eid] = mygetEventPath( $event ); From 26a45d5fa9ccac2964177e24d409ade66de95bde Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 25 Apr 2016 13:55:28 -0400 Subject: [PATCH 24/31] Don't rotate dimensions when constructing the monitor because they are already rotated --- src/zm_monitor.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index e96997ebc..e66256dea 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -306,8 +306,12 @@ Monitor::Monitor( server_id( p_server_id ), function( (Function)p_function ), enabled( p_enabled ), - width( (p_orientation==ROTATE_90||p_orientation==ROTATE_270)?p_camera->Height():p_camera->Width() ), - height( (p_orientation==ROTATE_90||p_orientation==ROTATE_270)?p_camera->Width():p_camera->Height() ), + // When we instantiate the camera, the dimensions are rotated. So if we rotate them again here, we undo the rotation. + // With this change, calls to Monitor->Width and Height will give the rotated dimesions.So this will trickle down + width( p_camera->Width() ), + height( p_camera->Height() ), + //width( (p_orientation==ROTATE_90||p_orientation==ROTATE_270)?p_camera->Height():p_camera->Width() ), + //height( (p_orientation==ROTATE_90||p_orientation==ROTATE_270)?p_camera->Width():p_camera->Height() ), orientation( (Orientation)p_orientation ), deinterlacing( p_deinterlacing ), label_coord( p_label_coord ), From 85798932ee3f9bb69b357c7825369a88e084d99b Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 25 Apr 2016 14:10:26 -0400 Subject: [PATCH 25/31] Use Event Width and Height, not the Monitor Width and Height. THe Monitor dimensions are not rotated --- web/skins/classic/views/event.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/skins/classic/views/event.php b/web/skins/classic/views/event.php index a0b97e35e..d3a185f33 100644 --- a/web/skins/classic/views/event.php +++ b/web/skins/classic/views/event.php @@ -27,7 +27,7 @@ if ( !canView( 'Events' ) ) $eid = validInt( $_REQUEST['eid'] ); $fid = !empty($_REQUEST['fid'])?validInt($_REQUEST['fid']):1; -$sql = 'SELECT E.*,M.Name AS MonitorName,M.Width,M.Height,M.DefaultRate,M.DefaultScale FROM Events AS E INNER JOIN Monitors AS M ON E.MonitorId = M.Id WHERE E.Id = ?'; +$sql = 'SELECT E.*,M.Name AS MonitorName,E.Width,E.Height,M.DefaultRate,M.DefaultScale FROM Events AS E INNER JOIN Monitors AS M ON E.MonitorId = M.Id WHERE E.Id = ?'; $sql_values = array( $eid ); if ( $user['MonitorIds'] ) { From b50172fc2e9e24d2da05a87d645c6299e2141697 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 25 Apr 2016 14:59:55 -0400 Subject: [PATCH 26/31] introduce a Frame object. Alter the image view to take just an fid, in which case it is the unique primary key Id of the Frame. --- web/skins/classic/views/frame.php | 33 +++++++++++++++++-------------- web/views/image.php | 7 +++++++ 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/web/skins/classic/views/frame.php b/web/skins/classic/views/frame.php index 582ecb55f..9aa544fb8 100644 --- a/web/skins/classic/views/frame.php +++ b/web/skins/classic/views/frame.php @@ -23,6 +23,7 @@ if ( !canView( 'Events' ) ) $view = "error"; return; } +require_once('includes/Frame.php'); $eid = validInt($_REQUEST['eid']); if ( !empty($_REQUEST['fid']) ) @@ -38,58 +39,60 @@ if ( !empty($fid) ) { } else { $frame = dbFetchOne( 'SELECT * FROM Frames WHERE EventId = ? AND Score = ?', NULL, array( $eid, $event['MaxScore'] ) ); } +$frame = new Frame( $frame ); $maxFid = $event['Frames']; $firstFid = 1; -$prevFid = $frame['FrameId']-1; -$nextFid = $frame['FrameId']+1; +$prevFid = $frame->FrameId()-1; +$nextFid = $frame->FrameId()+1; $lastFid = $maxFid; -$alarmFrame = $frame['Type']=='Alarm'; +$alarmFrame = $frame->Type()=='Alarm'; if ( isset( $_REQUEST['scale'] ) ) $scale = validInt($_REQUEST['scale']); else $scale = max( reScale( SCALE_BASE, $event['DefaultScale'], ZM_WEB_DEFAULT_SCALE ), SCALE_BASE ); -$imageData = getImageSrc( $event, $frame, $scale, (isset($_REQUEST['show']) && $_REQUEST['show']=="capt") ); +$imageData = getImageSrc( $event, $frame->FrameId(), $scale, (isset($_REQUEST['show']) && $_REQUEST['show']=="capt") ); $imagePath = $imageData['thumbPath']; $eventPath = $imageData['eventPath']; -$dImagePath = sprintf( "%s/%0".ZM_EVENT_IMAGE_DIGITS."d-diag-d.jpg", $eventPath, $frame['FrameId'] ); -$rImagePath = sprintf( "%s/%0".ZM_EVENT_IMAGE_DIGITS."d-diag-r.jpg", $eventPath, $frame['FrameId'] ); +$dImagePath = sprintf( "%s/%0".ZM_EVENT_IMAGE_DIGITS."d-diag-d.jpg", $eventPath, $frame->FrameId() ); +$rImagePath = sprintf( "%s/%0".ZM_EVENT_IMAGE_DIGITS."d-diag-r.jpg", $eventPath, $frame->FrameId() ); $focusWindow = true; -xhtmlHeaders(__FILE__, translate('Frame')." - ".$event['Id']." - ".$frame['FrameId'] ); +xhtmlHeaders(__FILE__, translate('Frame')." - ".$event['Id']." - ".$frame->FrameId() ); ?>

- + "><?php echo $frame['EventId']." class=""/> +if ( $imageData['hasAnalImage'] ) { ?>"> +<?php echo $frame->EventId().FrameId() ?>" class=""/>

- 1 ) { ?> +FrameId() > 1 ) { ?> - 1 ) { ?> +FrameId() > 1 ) { ?> - +FrameId() < $maxFid ) { ?> - +FrameId() < $maxFid ) { ?>

diff --git a/web/views/image.php b/web/views/image.php index 28843f96d..8fe5ab558 100644 --- a/web/views/image.php +++ b/web/views/image.php @@ -40,6 +40,7 @@ if ( !canView( 'Events' ) ) require_once('includes/Storage.php'); require_once('includes/Event.php'); +require_once('includes/Frame.php'); header( 'Content-type: image/jpeg' ); @@ -67,6 +68,12 @@ if ( empty($_REQUEST['path']) ) $Event = new Event( $_REQUEST['eid'] ); $Storage = $Event->Storage(); $path = $Event->Relative_Path().'/'.sprintf("%'.0".ZM_EVENT_IMAGE_DIGITS.'d',$_REQUEST['fid']).'-capture.jpg'; + } else { + # If we are only specifying fid, then the fid must be the primary key into the frames table. But when the event is specified, then it is the frame # + $Frame = new Frame( $_REQUEST['fid'] ); + $Event = new Event( $Frame->EventId() ); + $Storage = $Event->Storage(); + $path = $Event->Relative_Path().'/'.sprintf("%'.0".ZM_EVENT_IMAGE_DIGITS.'d',$Frame->FrameId()).'-capture.jpg'; } } else { $errorText = "No image path"; From 59db5d42e70dcb43685266d8190795aa234ffdc7 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 25 Apr 2016 15:00:27 -0400 Subject: [PATCH 27/31] include Frame.php --- web/includes/Frame.php | 76 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 web/includes/Frame.php diff --git a/web/includes/Frame.php b/web/includes/Frame.php new file mode 100644 index 000000000..b7add3b0e --- /dev/null +++ b/web/includes/Frame.php @@ -0,0 +1,76 @@ + $v) { + $this->{$k} = $v; + } + } else { + Error("No row for Frame " . $IdOrRow ); + } + } // end function __construct + public function Storage() { + return $this->Event()->Storage(); + } + public function Event() { + return new Event( $this->{'EventId'} ); + } + public function __call( $fn, array $args){ + if(isset($this->{$fn})){ + return $this->{$fn}; +#array_unshift($args, $this); +#call_user_func_array( $this->{$fn}, $args); + } + } + + public function Path() { + $Storage = $this->Storage(); + return $Storage->Path().'/'.$this->Relative_Path(); + } + public function Relative_Path() { + $event_path = ""; + + if ( ZM_USE_DEEP_STORAGE ) + { + $event_path = + $this->{'MonitorId'} + .'/'.strftime( "%y/%m/%d/%H/%M/%S", + $this->Time() + ) + ; + } + else + { + $event_path = + $this->{'MonitorId'} + .'/'.$this->{'Id'} + ; + } + + return( $event_path ); + + } + + public function getImageSrc( ) { + return ZM_BASE_URL.'/index.php?view=image&fid='.$this->{'Id'}; + } // end function getImageSrc +} # end class +?> From 8c53925fdc75c47d894eeda1cd4156ee9ffeabb1 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 25 Apr 2016 16:00:34 -0400 Subject: [PATCH 28/31] redo rotation fix. cameras have to be given the width and height that the camera will be sending. The monitor will report rotated dimensions. --- src/zm_monitor.cpp | 67 +++++++++++++++++----------------------------- src/zm_monitor.h | 4 +-- 2 files changed, 26 insertions(+), 45 deletions(-) diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index e66256dea..4fe59b5e8 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -306,12 +306,8 @@ Monitor::Monitor( server_id( p_server_id ), function( (Function)p_function ), enabled( p_enabled ), - // When we instantiate the camera, the dimensions are rotated. So if we rotate them again here, we undo the rotation. - // With this change, calls to Monitor->Width and Height will give the rotated dimesions.So this will trickle down width( p_camera->Width() ), height( p_camera->Height() ), - //width( (p_orientation==ROTATE_90||p_orientation==ROTATE_270)?p_camera->Height():p_camera->Width() ), - //height( (p_orientation==ROTATE_90||p_orientation==ROTATE_270)?p_camera->Width():p_camera->Height() ), orientation( (Orientation)p_orientation ), deinterlacing( p_deinterlacing ), label_coord( p_label_coord ), @@ -2150,9 +2146,6 @@ Debug( 1, "Got %d for v4l_captures_per_frame", v4l_captures_per_frame ); col++; bool embed_exif = (*dbrow[col] != '0'); col++; - int cam_width = ((orientation==ROTATE_90||orientation==ROTATE_270)?height:width); - int cam_height = ((orientation==ROTATE_90||orientation==ROTATE_270)?width:height); - int extras = (deinterlacing>>24)&0xff; Camera *camera = new LocalCamera( @@ -2163,8 +2156,8 @@ Debug( 1, "Got %d for v4l_captures_per_frame", v4l_captures_per_frame ); v4l_multi_buffer, v4l_captures_per_frame, method, - cam_width, - cam_height, + width, + height, colours, palette, brightness, @@ -2306,9 +2299,6 @@ int Monitor::LoadRemoteMonitors( const char *protocol, const char *host, const c int track_motion = atoi(dbrow[col]); col++; bool embed_exif = (*dbrow[col] != '0'); col++; - int cam_width = ((orientation==ROTATE_90||orientation==ROTATE_270)?height:width); - int cam_height = ((orientation==ROTATE_90||orientation==ROTATE_270)?width:height); - Camera *camera = 0; if ( protocol == "http" ) { @@ -2318,8 +2308,8 @@ int Monitor::LoadRemoteMonitors( const char *protocol, const char *host, const c host, // Host port, // Port path, // Path - cam_width, - cam_height, + width, + height, colours, brightness, contrast, @@ -2337,8 +2327,8 @@ int Monitor::LoadRemoteMonitors( const char *protocol, const char *host, const c host, // Host port, // Port path, // Path - cam_width, - cam_height, + width, + height, rtsp_describe, colours, brightness, @@ -2481,14 +2471,11 @@ int Monitor::LoadFileMonitors( const char *file, Monitor **&monitors, Purpose pu int track_motion = atoi(dbrow[col]); col++; bool embed_exif = (*dbrow[col] != '0'); col++; - int cam_width = ((orientation==ROTATE_90||orientation==ROTATE_270)?height:width); - int cam_height = ((orientation==ROTATE_90||orientation==ROTATE_270)?width:height); - Camera *camera = new FileCamera( id, path, // File - cam_width, - cam_height, + width, + height, colours, brightness, contrast, @@ -2626,16 +2613,13 @@ int Monitor::LoadFfmpegMonitors( const char *file, Monitor **&monitors, Purpose int track_motion = atoi(dbrow[col]); col++; bool embed_exif = (*dbrow[col] != '0'); col++; - int cam_width = ((orientation==ROTATE_90||orientation==ROTATE_270)?height:width); - int cam_height = ((orientation==ROTATE_90||orientation==ROTATE_270)?width:height); - Camera *camera = new FfmpegCamera( id, path, // File method, options, - cam_width, - cam_height, + width, + height, colours, brightness, contrast, @@ -2796,9 +2780,6 @@ Debug( 1, "Got %d for v4l_captures_per_frame", v4l_captures_per_frame ); col++; bool embed_exif = (*dbrow[col] != '0'); col++; - int cam_width = ((orientation==ROTATE_90||orientation==ROTATE_270)?height:width); - int cam_height = ((orientation==ROTATE_90||orientation==ROTATE_270)?width:height); - int extras = (deinterlacing>>24)&0xff; Camera *camera = 0; @@ -2813,8 +2794,8 @@ Debug( 1, "Got %d for v4l_captures_per_frame", v4l_captures_per_frame ); v4l_multi_buffer, v4l_captures_per_frame, method, - cam_width, - cam_height, + width, + height, colours, palette, brightness, @@ -2838,8 +2819,8 @@ Debug( 1, "Got %d for v4l_captures_per_frame", v4l_captures_per_frame ); host.c_str(), port.c_str(), path.c_str(), - cam_width, - cam_height, + width, + height, colours, brightness, contrast, @@ -2857,8 +2838,8 @@ Debug( 1, "Got %d for v4l_captures_per_frame", v4l_captures_per_frame ); host.c_str(), port.c_str(), path.c_str(), - cam_width, - cam_height, + width, + height, rtsp_describe, colours, brightness, @@ -2881,8 +2862,8 @@ Debug( 1, "Got %d for v4l_captures_per_frame", v4l_captures_per_frame ); camera = new FileCamera( id, path.c_str(), - cam_width, - cam_height, + width, + height, colours, brightness, contrast, @@ -2899,8 +2880,8 @@ Debug( 1, "Got %d for v4l_captures_per_frame", v4l_captures_per_frame ); path.c_str(), method, options, - cam_width, - cam_height, + width, + height, colours, brightness, contrast, @@ -2920,8 +2901,8 @@ Debug( 1, "Got %d for v4l_captures_per_frame", v4l_captures_per_frame ); path.c_str(), method, options, - cam_width, - cam_height, + width, + height, colours, brightness, contrast, @@ -2941,8 +2922,8 @@ Debug( 1, "Got %d for v4l_captures_per_frame", v4l_captures_per_frame ); path.c_str(), user.c_str(), pass.c_str(), - cam_width, - cam_height, + width, + height, colours, brightness, contrast, diff --git a/src/zm_monitor.h b/src/zm_monitor.h index a9cd05674..d1a619a4c 100644 --- a/src/zm_monitor.h +++ b/src/zm_monitor.h @@ -358,8 +358,8 @@ public: return( embed_exif ); } - unsigned int Width() const { return( width ); } - unsigned int Height() const { return( height ); } + unsigned int Width() const { return( (p_orientation==ROTATE_90||p_orientation==ROTATE_270)?p_camera->Height():p_camera->Width() ); } + unsigned int Height() const { return( (p_orientation==ROTATE_90||p_orientation==ROTATE_270)?p_camera->Width():p_camera->Height() ); } unsigned int Colours() const { return( camera->Colours() ); } unsigned int SubpixelOrder() const { return( camera->SubpixelOrder() ); } From d936312207d6de5ac1f90e0b8035e6b83cc12621 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 25 Apr 2016 16:46:23 -0400 Subject: [PATCH 29/31] revert --- src/zm_monitor.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/zm_monitor.h b/src/zm_monitor.h index 8cd237abf..70f77ca4c 100644 --- a/src/zm_monitor.h +++ b/src/zm_monitor.h @@ -417,8 +417,8 @@ public: return( embed_exif ); } - unsigned int Width() const { return ((orientation==ROTATE_90||orientation==ROTATE_270)?height:width); } - unsigned int Height() const { return ((orientation==ROTATE_90||orientation==ROTATE_270)?width:height); } + unsigned int Width() const { return width; } + unsigned int Height() const { return height; } unsigned int Colours() const { return( camera->Colours() ); } unsigned int SubpixelOrder() const { return( camera->SubpixelOrder() ); } From 2d8c484792a9518a0c308c6d8d2e6ade06959b6b Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 25 Apr 2016 16:48:26 -0400 Subject: [PATCH 30/31] rotate dimensions when instantiating the Monitor object --- src/zm_monitor.cpp | 4 ++-- src/zm_monitor.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index 4fe59b5e8..e9998c181 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -306,8 +306,8 @@ Monitor::Monitor( server_id( p_server_id ), function( (Function)p_function ), enabled( p_enabled ), - width( p_camera->Width() ), - height( p_camera->Height() ), + width( (p_orientation==ROTATE_90||p_orientation==ROTATE_270)?p_camera->Height():p_camera->Width() ), + height( (p_orientation==ROTATE_90||p_orientation==ROTATE_270)?p_camera->Width():p_camera->Height() ), orientation( (Orientation)p_orientation ), deinterlacing( p_deinterlacing ), label_coord( p_label_coord ), diff --git a/src/zm_monitor.h b/src/zm_monitor.h index d1a619a4c..a9cd05674 100644 --- a/src/zm_monitor.h +++ b/src/zm_monitor.h @@ -358,8 +358,8 @@ public: return( embed_exif ); } - unsigned int Width() const { return( (p_orientation==ROTATE_90||p_orientation==ROTATE_270)?p_camera->Height():p_camera->Width() ); } - unsigned int Height() const { return( (p_orientation==ROTATE_90||p_orientation==ROTATE_270)?p_camera->Width():p_camera->Height() ); } + unsigned int Width() const { return( width ); } + unsigned int Height() const { return( height ); } unsigned int Colours() const { return( camera->Colours() ); } unsigned int SubpixelOrder() const { return( camera->SubpixelOrder() ); } From 010f748016d8cfdd5ca8f660e2a08d309311353d Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 26 Apr 2016 15:02:34 -0400 Subject: [PATCH 31/31] fix clone merge --- web/skins/classic/views/console.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/web/skins/classic/views/console.php b/web/skins/classic/views/console.php index a9b3c673c..467b5d642 100644 --- a/web/skins/classic/views/console.php +++ b/web/skins/classic/views/console.php @@ -54,7 +54,9 @@ if ( canEdit('Monitors') ) if ( $show_storage_areas ) { $columns += 1; } echo $columns; ?>"> - + + +