diff --git a/scripts/zmaudit.pl.in b/scripts/zmaudit.pl.in index 761c07da2..228e7efad 100644 --- a/scripts/zmaudit.pl.in +++ b/scripts/zmaudit.pl.in @@ -620,9 +620,12 @@ FROM Frames WHERE EventId=?'; $res = $selectUnclosedEventsSth->execute() or Fatal( "Can't execute: ".$selectUnclosedEventsSth->errstr() ); while( my $event = $selectUnclosedEventsSth->fetchrow_hashref() ) { - aud_print( "Found open event '$event->{Id}'" ); + aud_print( "Found open event '$event->{Id}' at $$event{StartTime}" ); if ( confirm( 'close', 'closing' ) ) { - $res = $selectFrameDataSth->execute( $event->{Id} ) or Fatal( "Can't execute: ".$selectFrameDataSth->errstr() ); + if ( ! ( $res = $selectFrameDataSth->execute($event->{Id}) ) ) { + Error( "Can't execute: $selectFrameDataSql:".$selectFrameDataSth->errstr() ); + next; + } my $frame = $selectFrameDataSth->fetchrow_hashref(); if ( $frame ) { $res = $updateUnclosedEventsSth->execute( @@ -643,12 +646,13 @@ FROM Frames WHERE EventId=?'; $frame->{MaxScore}, RECOVER_TEXT, $event->{Id} - ) or Fatal( "Can't execute: ".$updateUnclosedEventsSth->errstr() ); + ) or Error( "Can't execute: ".$updateUnclosedEventsSth->errstr() ); } else { Error('SHOULD DELETE'); } # end if has frame data } } # end while unclosed event + Debug("Done closing open events."); # Now delete any old image files if ( my @old_files = grep { -M > $max_image_age } <$image_path/*.{jpg,gif,wbmp}> ) { diff --git a/src/zm_analysis_thread.cpp b/src/zm_analysis_thread.cpp index 400bc8612..a81e44be8 100644 --- a/src/zm_analysis_thread.cpp +++ b/src/zm_analysis_thread.cpp @@ -11,12 +11,11 @@ AnalysisThread::~AnalysisThread() { } int AnalysisThread::run() { - Debug(2, "In run"); useconds_t analysis_rate = monitor->GetAnalysisRate(); - Debug(2, "after getanalysisrate"); + Debug(2, "after getanalysisrate rate is %u", analysis_rate); unsigned int analysis_update_delay = monitor->GetAnalysisUpdateDelay(); - Debug(2, "after getanalysisUpdateDelay"); + Debug(2, "after getanalysisUpdateDelay delay is %u", analysis_update_delay); time_t last_analysis_update_time, cur_time; monitor->UpdateAdaptiveSkip(); Debug(2, "after UpdateAdaptiveSkip"); diff --git a/src/zm_ffmpeg_camera.cpp b/src/zm_ffmpeg_camera.cpp index 67c0b8ab6..e24c20ac4 100644 --- a/src/zm_ffmpeg_camera.cpp +++ b/src/zm_ffmpeg_camera.cpp @@ -108,7 +108,6 @@ FfmpegCamera::FfmpegCamera( int p_id, const std::string &p_path, const std::stri mFrame = NULL; frameCount = 0; mCanCapture = false; - mOpenStart = 0; } // end FFmpegCamera::FFmpegCamera @@ -121,7 +120,7 @@ FfmpegCamera::~FfmpegCamera() { int FfmpegCamera::PrimeCapture() { if ( mCanCapture ) { - Info( "Priming capture from %s", mPath.c_str() ); + Info( "Priming capture from %s, CLosing", mPath.c_str() ); CloseFfmpeg(); } mVideoStreamId = -1; @@ -184,8 +183,6 @@ int FfmpegCamera::OpenFfmpeg() { Debug(2, "OpenFfmpeg called."); int ret; - mOpenStart = time(NULL); - // Open the input, not necessarily a file #if !LIBAVFORMAT_VERSION_CHECK(53, 2, 0, 4, 0) Debug ( 1, "Calling av_open_input_file" ); @@ -224,6 +221,14 @@ int FfmpegCamera::OpenFfmpeg() { #endif { Error("Unable to open input %s due to: %s", mPath.c_str(), strerror(errno)); +#if !LIBAVFORMAT_VERSION_CHECK(53, 17, 0, 25, 0) + av_close_input_file( mFormatContext ); +#else + avformat_close_input( &mFormatContext ); +#endif + mFormatContext = NULL; + av_dict_free(&opts); + return -1; } @@ -231,6 +236,7 @@ int FfmpegCamera::OpenFfmpeg() { while ( (e = av_dict_get(opts, "", e, AV_DICT_IGNORE_SUFFIX)) != NULL ) { Warning( "Option %s not recognized by ffmpeg", e->key); } + av_dict_free(&opts); monitor->GetLastEventId() ; @@ -367,12 +373,15 @@ int FfmpegCamera::OpenFfmpeg() { while ( (e = av_dict_get(opts, "", e, AV_DICT_IGNORE_SUFFIX)) != NULL ) { Warning( "Option %s not recognized by ffmpeg", e->key); } - Fatal( "Unable to open codec for video stream from %s", mPath.c_str() ); + Error( "Unable to open codec for video stream from %s", mPath.c_str() ); + av_dict_free(&opts); + return -1; } else { AVDictionaryEntry *e = NULL; if ( (e = av_dict_get(opts, "", e, AV_DICT_IGNORE_SUFFIX)) != NULL ) { Warning( "Option %s not recognized by ffmpeg", e->key); } + av_dict_free(&opts); } } // end if success opening codec diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index fb6f5b76d..7fb7599be 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -3279,7 +3279,7 @@ void Monitor::get_ref_image() { ( shared_data->last_write_time == 0 ) && ! zm_terminate ) { - Warning( "Waiting for capture daemon lwi(%d) lwt(%d)", shared_data->last_write_index, shared_data->last_write_time ); + Warning( "Waiting for capture daemon lastwriteindex(%d) lastwritetime(%d)", shared_data->last_write_index, shared_data->last_write_time ); usleep( 50000 ); } int last_write_index = shared_data->last_write_index ; diff --git a/src/zm_monitor.h b/src/zm_monitor.h index bdddac4ec..d35d8e30d 100644 --- a/src/zm_monitor.h +++ b/src/zm_monitor.h @@ -430,7 +430,7 @@ public: Error("Should not be calling Ready if the function doesn't include motion detection"); return( false ); } - if ( image_count > ready_count ) { + if ( image_count >= ready_count ) { return true; } Debug(2, "Not ready because image_count(%d) <= ready_count(%d)", image_count, ready_count ); diff --git a/src/zm_thread.cpp b/src/zm_thread.cpp index 430aa55b0..f42ee5041 100644 --- a/src/zm_thread.cpp +++ b/src/zm_thread.cpp @@ -221,8 +221,10 @@ Thread::Thread() : Thread::~Thread() { Debug( 1, "Destroying thread %d", mPid ); - if ( mStarted ) + if ( mStarted ) { + Warning("You should really join the thread before destroying it"); join(); + } } void *Thread::mThreadFunc( void *arg ) { diff --git a/src/zm_user.cpp b/src/zm_user.cpp index 3bf22fadd..1c11aebde 100644 --- a/src/zm_user.cpp +++ b/src/zm_user.cpp @@ -30,6 +30,7 @@ #include "zm_utils.h" User::User() { + id = 0; username[0] = password[0] = 0; enabled = false; stream = events = control = monitors = system = PERM_NONE; @@ -37,6 +38,7 @@ User::User() { User::User( MYSQL_ROW &dbrow ) { int index = 0; + id = atoi( dbrow[index++] ); strncpy( username, dbrow[index++], sizeof(username)-1 ); strncpy( password, dbrow[index++], sizeof(password)-1 ); enabled = (bool)atoi( dbrow[index++] ); @@ -59,6 +61,7 @@ User::~User() { } void User::Copy( const User &u ) { + id=u.id; strncpy( username, u.username, sizeof(username)-1 ); strncpy( password, u.password, sizeof(password)-1 ); enabled = u.enabled; @@ -94,9 +97,9 @@ User *zmLoadUser( const char *username, const char *password ) { if ( password ) { char safer_password[129]; // current db password size is 64 mysql_real_escape_string(&dbconn, safer_password, password, strlen( password ) ); - snprintf( sql, sizeof(sql), "select Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, System+0, MonitorIds from Users where Username = '%s' and Password = password('%s') and Enabled = 1", safer_username, safer_password ); + snprintf( sql, sizeof(sql), "select Id, Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, System+0, MonitorIds from Users where Username = '%s' and Password = password('%s') and Enabled = 1", safer_username, safer_password ); } else { - snprintf( sql, sizeof(sql), "select Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, System+0, MonitorIds from Users where Username = '%s' and Enabled = 1", safer_username ); + snprintf( sql, sizeof(sql), "select Id, Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, System+0, MonitorIds from Users where Username = '%s' and Enabled = 1", safer_username ); } if ( mysql_query( &dbconn, sql ) ) { @@ -124,7 +127,7 @@ User *zmLoadUser( const char *username, const char *password ) { mysql_free_result( result ); - return( user ); + return user; } // Function to validate an authentication string @@ -150,7 +153,7 @@ User *zmLoadAuthUser( const char *auth, bool use_remote_addr ) { Debug( 1, "Attempting to authenticate user from auth string '%s', remote addr(%s)", auth, remote_addr ); char sql[ZM_SQL_SML_BUFSIZ] = ""; - snprintf( sql, sizeof(sql), "SELECT Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, System+0, MonitorIds FROM Users WHERE Enabled = 1" ); + snprintf( sql, sizeof(sql), "SELECT Id, Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, System+0, MonitorIds FROM Users WHERE Enabled = 1" ); if ( mysql_query( &dbconn, sql ) ) { Error( "Can't run query: %s", mysql_error( &dbconn ) ); @@ -182,8 +185,8 @@ User *zmLoadAuthUser( const char *auth, bool use_remote_addr ) { } while( MYSQL_ROW dbrow = mysql_fetch_row( result ) ) { - const char *user = dbrow[0]; - const char *pass = dbrow[1]; + const char *user = dbrow[1]; + const char *pass = dbrow[2]; char auth_key[512] = ""; char auth_md5[32+1] = ""; @@ -232,5 +235,5 @@ User *zmLoadAuthUser( const char *auth, bool use_remote_addr ) { Error( "You need to build with gnutls or openssl installed to use hash based authentication" ); #endif // HAVE_DECL_MD5 Debug(1, "No user found for auth_key %s", auth ); - return( 0 ); + return 0; } diff --git a/src/zm_user.h b/src/zm_user.h index 725acbfa2..2c932dd74 100644 --- a/src/zm_user.h +++ b/src/zm_user.h @@ -42,6 +42,7 @@ public: typedef enum { PERM_NONE=1, PERM_VIEW, PERM_EDIT } Permission; protected: + int id; char username[32+1]; char password[64+1]; bool enabled; @@ -62,6 +63,7 @@ public: Copy(u); return *this; } + const int Id() const { return id; } const char *getUsername() const { return( username ); } const char *getPassword() const { return( password ); } bool isEnabled() const { return( enabled ); } diff --git a/src/zmc.cpp b/src/zmc.cpp index c278a002c..bb67a7bdd 100644 --- a/src/zmc.cpp +++ b/src/zmc.cpp @@ -369,8 +369,10 @@ int main(int argc, char *argv[]) { } } // end foreach monitor delete [] analysis_threads; - sleep(10); + if ( !zm_terminate ) + sleep(10); } // end while ! zm_terminate outer connection loop + Debug(1,"Updating Monitor status"); for ( int i = 0; i < n_monitors; i++ ) { static char sql[ZM_SQL_SML_BUFSIZ]; diff --git a/src/zms.cpp b/src/zms.cpp index b0bc3f9eb..66b3dc683 100644 --- a/src/zms.cpp +++ b/src/zms.cpp @@ -41,7 +41,8 @@ bool ValidateAccess( User *user, int mon_id ) { allowed = false; } if ( !allowed ) { - Error( "Error, insufficient privileges for requested action" ); + Error( "Error, insufficient privileges for requested action user %d %s for monitor %d", + user->Id(), user->getUsername(), mon_id ); exit( -1 ); } return( allowed ); diff --git a/web/skins/classic/views/js/montagereview.js b/web/skins/classic/views/js/montagereview.js index 90a8d71b7..1d1b6fb60 100644 --- a/web/skins/classic/views/js/montagereview.js +++ b/web/skins/classic/views/js/montagereview.js @@ -706,12 +706,26 @@ function showOneMonitor(monId) { createPopup(url, 'zmWatch', 'watch', monitorWidth[monId], monitorHeight[monId] ); } else { for ( var i=0, len=eId.length; i= eStartSecs[i] && currentTimeSecs <= eEndSecs[i] ) { + if ( eMonId[i] != monId ) + continue; + + if ( currentTimeSecs >= eStartSecs[i] && currentTimeSecs <= eEndSecs[i] ) { url="?view=event&eid=" + eId[i] + '&fid=' + parseInt(Math.max(1, Math.min(eventFrames[i], eventFrames[i] * (currentTimeSecs - eStartSecs[i]) / (eEndSecs[i] - eStartSecs[i] + 1) ) )); break; + } else if ( currentTimeSecs <= eStartSecs[i] ) { + if ( i ) { + // Didn't find an exact event, so go with the one before. + url="?view=event&eid=" + eId[i] + '&fid=' + parseInt(Math.max(1, Math.min(eventFrames[i], eventFrames[i] * (currentTimeSecs - eStartSecs[i]) / (eEndSecs[i] - eStartSecs[i] + 1) ) )); + } + break; } } - createPopup(url, 'zmEvent', 'event', monitorWidth[monId], monitorHeight[monId]); + if ( url ) { + createPopup(url, 'zmEvent', 'event', monitorWidth[monId], monitorHeight[monId]); + } else { + url="?view=watch&mid=" + monId.toString(); + createPopup(url, 'zmWatch', 'watch', monitorWidth[monId], monitorHeight[monId] ); + } } } diff --git a/web/skins/classic/views/montagereview.php b/web/skins/classic/views/montagereview.php index 1299473ad..d2d60b8e7 100644 --- a/web/skins/classic/views/montagereview.php +++ b/web/skins/classic/views/montagereview.php @@ -199,6 +199,7 @@ if ( isset($minTime) && isset($maxTime) ) { $frameSql .= " AND TimeStamp > '" . $minTime . "' AND TimeStamp < '" . $maxTime . "'"; } $frameSql .= ' GROUP BY E.Id, E.MonitorId, F.TimeStamp, F.Delta ORDER BY E.MonitorId, F.TimeStamp ASC'; +$eventsSql .= ' ORDER BY E.Id ASC'; $monitors = array(); foreach( $displayMonitors as $row ) {