diff --git a/db/zm_create.sql.in b/db/zm_create.sql.in index 91089ff2d..2685e27d1 100644 --- a/db/zm_create.sql.in +++ b/db/zm_create.sql.in @@ -434,6 +434,19 @@ CREATE TABLE `Monitors` ( `Status` enum('Unknown','NotRunning','Running','NoSignal','Signal') NOT NULL default 'Unknown', `CaptureFPS` DECIMAL(10,2) NOT NULL default 0, `AnalysisFPS` DECIMAL(5,2) NOT NULL default 0, + `TotalEvents` int(10) unsigned, + `TotalEventDiskSpace` bigint unsigned, + `HourEvents` int(10) unsigned, + `HourEventDiskSpace` bigint unsigned, + `DayEvents` int(10) unsigned, + `DayEventDiskSpace` bigint unsigned, + `WeekEvents` int(10) unsigned, + `WeekEventDiskSpace` bigint unsigned, + `MonthEvents` int(10) unsigned, + `MonthEventDiskSpace` bigint unsigned, + `ArchivedEvents` int(10) unsigned, + `ArchivedEventDiskSpace` bigint unsigned, + `ZoneCount` TINYINT NOT NULL DEFAULT 0, PRIMARY KEY (`Id`) ) ENGINE=@ZM_MYSQL_ENGINE@; diff --git a/db/zm_update-1.31.14.sql b/db/zm_update-1.31.14.sql new file mode 100644 index 000000000..29e0f4a42 --- /dev/null +++ b/db/zm_update-1.31.14.sql @@ -0,0 +1,148 @@ + +SET @s = (SELECT IF( + (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE() + AND table_name = 'Monitors' + AND column_name = 'TotalEvents' + ) > 0, +"SELECT 'Column TotalEvents already exists in Monitors'", +"ALTER TABLE `Monitors` ADD `TotalEvents` INT(10) AFTER `AnalysisFPS`" +)); + +PREPARE stmt FROM @s; +EXECUTE stmt; + +SET @s = (SELECT IF( + (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE() + AND table_name = 'Monitors' + AND column_name = 'TotalEventDiskSpace' + ) > 0, +"SELECT 'Column TotalEventDiskSpace already exists in Monitors'", +"ALTER TABLE `Monitors` ADD `TotalEventDiskSpace` BIGINT AFTER `TotalEvents`" +)); + +PREPARE stmt FROM @s; +EXECUTE stmt; + +SET @s = (SELECT IF( + (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE() + AND table_name = 'Monitors' + AND column_name = 'HourEvents' + ) > 0, +"SELECT 'Column HourEvents already exists in Monitors'", +"ALTER TABLE `Monitors` ADD `HourEvents` INT(10) AFTER `TotalEvents`" +)); + + +PREPARE stmt FROM @s; +EXECUTE stmt; + +SET @s = (SELECT IF( + (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE() + AND table_name = 'Monitors' + AND column_name = 'HourEventDiskSpace' + ) > 0, +"SELECT 'Column HourEventDiskSpace already exists in Monitors'", +"ALTER TABLE `Monitors` ADD `HourEventDiskSpace` BIGINT AFTER `HourEvents`" +)); + +PREPARE stmt FROM @s; +EXECUTE stmt; + +SET @s = (SELECT IF( + (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE() + AND table_name = 'Monitors' + AND column_name = 'DayEvents' + ) > 0, +"SELECT 'Column DayEvents already exists in Monitors'", +"ALTER TABLE `Monitors` ADD `DayEvents` INT(10) AFTER `HourEvents`" +)); + + +PREPARE stmt FROM @s; +EXECUTE stmt; + +SET @s = (SELECT IF( + (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE() + AND table_name = 'Monitors' + AND column_name = 'DayEventDiskSpace' + ) > 0, +"SELECT 'Column DayEventDiskSpace already exists in Monitors'", +"ALTER TABLE `Monitors` ADD `DayEventDiskSpace` BIGINT AFTER `DayEvents`" +)); + +PREPARE stmt FROM @s; +EXECUTE stmt; +SET @s = (SELECT IF( + (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE() + AND table_name = 'Monitors' + AND column_name = 'WeekEvents' + ) > 0, +"SELECT 'Column WeekEvents already exists in Monitors'", +"ALTER TABLE `Monitors` ADD `WeekEvents` INT(10) AFTER `DayEvents`" +)); + + +PREPARE stmt FROM @s; +EXECUTE stmt; + +SET @s = (SELECT IF( + (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE() + AND table_name = 'Monitors' + AND column_name = 'WeekEventDiskSpace' + ) > 0, +"SELECT 'Column WeekEventDiskSpace already exists in Monitors'", +"ALTER TABLE `Monitors` ADD `WeekEventDiskSpace` BIGINT AFTER `WeekEvents`" +)); + +PREPARE stmt FROM @s; +EXECUTE stmt; + +SET @s = (SELECT IF( + (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE() + AND table_name = 'Monitors' + AND column_name = 'MonthEvents' + ) > 0, +"SELECT 'Column MonthEvents already exists in Monitors'", +"ALTER TABLE `Monitors` ADD `MonthEvents` INT(10) AFTER `WeekEvents`" +)); + + +PREPARE stmt FROM @s; +EXECUTE stmt; + +SET @s = (SELECT IF( + (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE() + AND table_name = 'Monitors' + AND column_name = 'MonthEventDiskSpace' + ) > 0, +"SELECT 'Column MonthEventDiskSpace already exists in Monitors'", +"ALTER TABLE `Monitors` ADD `MonthEventDiskSpace` BIGINT AFTER `MonthEvents`" +)); + +PREPARE stmt FROM @s; +EXECUTE stmt; + +SET @s = (SELECT IF( + (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE() + AND table_name = 'Monitors' + AND column_name = 'ArchivedEvents' + ) > 0, +"SELECT 'Column ArchivedEvents already exists in Monitors'", +"ALTER TABLE `Monitors` ADD `ArchivedEvents` INT(10) AFTER `MonthEvents`" +)); + + +PREPARE stmt FROM @s; +EXECUTE stmt; + +SET @s = (SELECT IF( + (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE() + AND table_name = 'Monitors' + AND column_name = 'ArchivedEventDiskSpace' + ) > 0, +"SELECT 'Column ArchivedEventDiskSpace already exists in Monitors'", +"ALTER TABLE `Monitors` ADD `ArchivedEventDiskSpace` BIGINT AFTER `ArchivedEvents`" +)); + +PREPARE stmt FROM @s; +EXECUTE stmt; diff --git a/db/zm_update-1.31.15.sql b/db/zm_update-1.31.15.sql new file mode 100644 index 000000000..4c017aa52 --- /dev/null +++ b/db/zm_update-1.31.15.sql @@ -0,0 +1,14 @@ + +SET @s = (SELECT IF( + (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE() + AND table_name = 'Monitors' + AND column_name = 'ZoneCount' + ) > 0, +"SELECT 'Column ZoneCount already exists in Monitors'", +"ALTER TABLE `Monitors` ADD `ZoneCount` TINYINT NOT NULL DEFAULT 0 AFTER `ArchivedEventDiskSpace`" +)); + +PREPARE stmt FROM @s; +EXECUTE stmt; + +UPDATE Monitors SET ZoneCount=(SELECT COUNT(Id) FROM Zones WHERE MonitorId=Monitors.Id); diff --git a/distros/ubuntu1604/zoneminder.postinst b/distros/ubuntu1604/zoneminder.postinst index a17b5b1c0..a703983be 100644 --- a/distros/ubuntu1604/zoneminder.postinst +++ b/distros/ubuntu1604/zoneminder.postinst @@ -17,10 +17,7 @@ if [ "$1" = "configure" ]; then a2enmod cgi fi - if [ "$ZM_DB_HOST" = "localhost" ]; then - # Do this every time the package is installed or upgraded - # Ensure zoneminder is stopped - deb-systemd-invoke stop zoneminder.service || exit $? + if [ "$ZM_DB_HOST" = "localhost" ]; then if [ -e "/etc/init.d/mysql" ]; then # Do this every time the package is installed or upgraded diff --git a/scripts/zmwatch.pl.in b/scripts/zmwatch.pl.in index d513e376a..a902b1498 100644 --- a/scripts/zmwatch.pl.in +++ b/scripts/zmwatch.pl.in @@ -79,24 +79,42 @@ my $sql = $Config{ZM_SERVER_ID} ? 'SELECT * FROM Monitors WHERE ServerId=?' : 'S my $sth = $dbh->prepare_cached( $sql ) or Fatal( "Can't prepare '$sql': ".$dbh->errstr() ); +my $eventcounts_sql = q` +UPDATE Monitors SET + TotalEvents=(SELECT COUNT(Id) FROM Events WHERE MonitorId=Monitors.Id), + TotalEventDiskSpace=(SELECT SUM(DiskSpace) FROM Events WHERE MonitorId=Monitors.Id AND DiskSpace IS NOT NULL), + HourEvents=(SELECT COUNT(Id) FROM Events WHERE MonitorId=Monitors.Id AND StartTime > DATE_SUB( NOW(), INTERVAL 1 hour) ), + HourEventDiskSpace=(SELECT SUM(DiskSpace) FROM Events WHERE MonitorId=Monitors.Id AND StartTime > DATE_SUB(NOW(), INTERVAL 1 hour) AND DiskSpace IS NOT NULL), + DayEvents=(SELECT COUNT(Id) FROM Events WHERE MonitorId=Monitors.Id AND StartTime > DATE_SUB(NOW(), INTERVAL 1 day)), + DayEventDiskSpace=(SELECT SUM(DiskSpace) FROM Events WHERE MonitorId=Monitors.Id AND StartTime > DATE_SUB(NOW(), INTERVAL 1 day) AND DiskSpace IS NOT NULL), + WeekEvents=(SELECT COUNT(Id) FROM Events WHERE MonitorId=Monitors.Id AND StartTime > DATE_SUB(NOW(), INTERVAL 1 week)), + WeekEventDiskSpace=(SELECT SUM(DiskSpace) FROM Events WHERE MonitorId=Monitors.Id AND StartTime > DATE_SUB(NOW(), INTERVAL 1 week) AND DiskSpace IS NOT NULL), + MonthEvents=(SELECT COUNT(Id) FROM Events WHERE MonitorId=Monitors.Id AND StartTime > DATE_SUB( NOW(), INTERVAL 1 month)), + MonthEventDiskSpace=(SELECT SUM(DiskSpace) FROM Events WHERE MonitorId=Monitors.Id AND StartTime > DATE_SUB(NOW(), INTERVAL 1 month) AND DiskSpace IS NOT NULL), + ArchivedEvents=(SELECT COUNT(Id) FROM Events WHERE MonitorId=Monitors.Id AND Archived=1), + ArchivedEventDiskSpace=(SELECT SUM(DiskSpace) FROM Events WHERE MonitorId=Monitors.Id AND Archived=1 AND DiskSpace IS NOT NULL) + WHERE Id=?`; + +my $eventcounts_sth = $dbh->prepare_cached( $eventcounts_sql ); + while( 1 ) { - my $now = time(); my $res = $sth->execute( $Config{ZM_SERVER_ID} ? $Config{ZM_SERVER_ID} : () ) or Fatal( "Can't execute: ".$sth->errstr() ); while( my $monitor = $sth->fetchrow_hashref() ) { + my $now = time(); next if $monitor->{Function} eq 'None'; my $restart = 0; if ( zmMemVerify( $monitor ) ) { # Check we have got an image recently - my $image_time = zmGetLastWriteTime( $monitor ); - if ( !defined($image_time) ) { + my $capture_time = zmGetLastWriteTime( $monitor ); + if ( !defined($capture_time) ) { # Can't read from shared data Debug( "LastWriteTime is not defined." ); zmMemInvalidate( $monitor ); next; } - Debug( "LastWriteTime is = $image_time." ); - if ( !$image_time ) { + Debug( "LastWriteTime is = $capture_time." ); + if ( !$capture_time ) { my $startup_time = zmGetStartupTime( $monitor ); if ( $now - $startup_time > $Config{ZM_WATCH_MAX_DELAY} ) { Info( "Restarting capture daemon for ".$monitor->{Name}.", no image since startup. Startup time was $startup_time - now $now > $Config{ZM_WATCH_MAX_DELAY}\n" ); @@ -104,7 +122,7 @@ while( 1 ) { } else { # We can't get the last capture time so can't be sure it's died, it might just be starting up. zmMemInvalidate( $monitor ); - next; + next; } } if ( ! $restart ) { @@ -114,11 +132,11 @@ while( 1 ) { ) ? (3/$monitor->{MaxFPS}) : $Config{ZM_WATCH_MAX_DELAY} ; - my $image_delay = $now-$image_time; + my $image_delay = $now-$capture_time; Debug( "Monitor $monitor->{Id} last captured $image_delay seconds ago, max is $max_image_delay\n" ); if ( $image_delay > $max_image_delay ) { Info( "Restarting capture daemon for " - .$monitor->{Name}.", time since last capture $image_delay seconds ($now-$image_time)\n" + .$monitor->{Name}.", time since last capture $image_delay seconds ($now-$capture_time)\n" ); $restart = 1; } @@ -148,7 +166,7 @@ while( 1 ) { } elsif ( !$image_time ) { # We can't get the last capture time so can't be sure it's died. $restart = 1; - Error( "Error getting last capture time for $$monitor{Id} $$monitor{Name}\n"); + Error( "Error getting last analyse time for $$monitor{Id} $$monitor{Name}\n"); } else { my $max_image_delay = ( $monitor->{MaxFPS} @@ -175,13 +193,21 @@ while( 1 ) { } # end if check analysis daemon # Prevent open handles building up if we have connect to shared memory zmMemInvalidate( $monitor ); # Close our file handle to the zmc process we are about to end + + + $eventcounts_sth->execute( $$monitor{Id} ) or Error( "Can't execute: ".$eventcounts_sth->errstr() ); + } # end foreach monitor + $eventcounts_sth->finish(); + my $diskspace_sql = 'UPDATE Storage SET DiskSpace =(SELECT SUM(DiskSpace) FROM Events WHERE StorageId=? AND DiskSpace IS NOT NULL)'; - my $diskspace_sth = $dbh->prepare_cached( $sql ) - or Fatal( "Can't prepare '$sql': ".$dbh->errstr() ); + my $diskspace_sth = $dbh->prepare_cached( $diskspace_sql ) + or Fatal( "Can't prepare '$diskspace_sql': ".$dbh->errstr() ); foreach my $Storage ( ZoneMinder::Storage->find() ) { - Error("Updating disk space for $$Storage{Name}"); + Debug("Updating disk space for $$Storage{Name} was $$Storage{DiskSpace}"); $diskspace_sth->execute( $$Storage{Id} ) or Error( "Can't execute: ".$diskspace_sth->errstr() ); + $Storage->load(); + Debug("Updated disk space for $$Storage{Name} to $$Storage{DiskSpace}"); } $diskspace_sth->finish(); sleep( $Config{ZM_WATCH_CHECK_INTERVAL} ); diff --git a/src/zm_ffmpeg.cpp b/src/zm_ffmpeg.cpp index 3c9d969b5..e2abe03f5 100644 --- a/src/zm_ffmpeg.cpp +++ b/src/zm_ffmpeg.cpp @@ -116,7 +116,8 @@ int av_dict_parse_string(AVDictionary **pm, const char *str, flags &= ~(AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL); while (*str) { - if ((int ret = parse_key_value_pair(pm, &str, key_val_sep, pairs_sep, flags)) < 0) + int ret; + if ( (ret = parse_key_value_pair(pm, &str, key_val_sep, pairs_sep, flags)) < 0) return ret; if (*str) diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index 58527271e..7c7b85922 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -583,7 +583,7 @@ Monitor::~Monitor() { } if ( mem_ptr ) { if ( event ) { - Info( "%s: %03d - Closing event %d, shutting down", name, image_count, event->Id() ); + Info( "%s: image_count:%d - Closing event %d, shutting down", name, image_count, event->Id() ); closeEvent(); } @@ -752,13 +752,16 @@ unsigned int Monitor::GetLastEvent() const { return( shared_data->last_event_id ); } +// This function is crap. double Monitor::GetFPS() const { int index1 = shared_data->last_write_index; if ( index1 == image_buffer_count ) { + // last_write_index only has this value on startup before capturing anything. return 0.0; } ZMPacket *snap1 = &image_buffer[index1]; if ( !snap1->timestamp->tv_sec ) { + // This should be impossible return 0.0; } struct timeval time1 = *snap1->timestamp; @@ -766,12 +769,12 @@ double Monitor::GetFPS() const { int image_count = image_buffer_count; int index2 = (index1+1)%image_buffer_count; - if ( index2 == image_buffer_count ) { - return 0.0; - } - ZMPacket *snap2 = &image_buffer[ index2 ]; + ZMPacket *snap2 = &image_buffer[index2]; + // the timestamp pointers are initialized on connection, so that's redundant + // tv_sec is probably only zero during the first loop of capturing, so this basically just counts the unused images. while ( !snap2->timestamp->tv_sec ) { if ( index1 == index2 ) { + // We didn't find any initialized images return 0.0; } index2 = (index2+1)%image_buffer_count; @@ -787,7 +790,7 @@ double Monitor::GetFPS() const { double curr_fps = image_count/time_diff; if ( curr_fps < 0.0 ) { - //Error( "Negative FPS %f, time_diff = %lf (%d:%ld.%ld - %d:%ld.%ld), ibc: %d", curr_fps, time_diff, index2, time2.tv_sec, time2.tv_usec, index1, time1.tv_sec, time1.tv_usec, image_buffer_count ); + Error( "Negative FPS %f, time_diff = %lf (%d:%ld.%ld - %d:%ld.%ld), ibc: %d", curr_fps, time_diff, index2, time2.tv_sec, time2.tv_usec, index1, time1.tv_sec, time1.tv_usec, image_buffer_count ); return 0.0; } return curr_fps; @@ -1224,18 +1227,20 @@ bool Monitor::Analyse() { struct timeval now; gettimeofday( &now, NULL ); - mutex.lock(); // if have event, sent frames until we find a video packet, at which point do analysis. Adaptive skip should only affect which frames we do analysis on. // Keeps minimum video frames. This should be ok, because we SHOULD be staying close to the head of the queue in analysis if ( ! event ) { - if ( packetqueue.video_packet_count > pre_event_count ) + if ( packetqueue.video_packet_count > pre_event_count ) { + mutex.lock(); packetqueue.clearQueue( pre_event_count, video_stream_id ); + mutex.unlock(); + } } // If do have an event, then analysis_it should point to the head of the queue, because we would have emptied it on event creation. - int index = ( shared_data->last_read_index + 1 ) % image_buffer_count; + unsigned int index = ( shared_data->last_read_index + 1 ) % image_buffer_count; // Move to next packet. while ( ( index != shared_data->last_write_index ) && ( analysis_it != packetqueue.pktQueue.end() ) ) { ++analysis_it; @@ -1389,14 +1394,16 @@ bool Monitor::Analyse() { if ( (function != MOCORD && state != ALERT) ) { event = new Event( this, *timestamp, cause, noteSetMap ); shared_data->last_event_id = event->Id(); - ZMPacket *queued_packet = packetqueue.popPacket(); - while( packetqueue.size() && queued_packet != *analysis_it ) { + mutex.lock(); + std::list::iterator it = packetqueue.pktQueue.begin(); + while( packetqueue.size() && it != analysis_it ) { + ZMPacket *queued_packet = packetqueue.popPacket(); event->AddPacket( queued_packet ); if ( queued_packet->image_index == -1 ) { delete queued_packet; } - queued_packet = packetqueue.popPacket(); } + mutex.unlock(); // The analysis packet will be added below. } } else if ( state != PREALARM ) { @@ -1458,7 +1465,9 @@ bool Monitor::Analyse() { } // end foreach zone } // analsys_images or record stats + mutex.lock(); snap = packetqueue.popPacket(); + mutex.unlock(); event->AddPacket( snap, score ); if ( snap->image_index == -1 ) { delete snap; @@ -1469,7 +1478,9 @@ bool Monitor::Analyse() { event->updateNotes( noteSetMap ); } else if ( state == ALERT ) { // Alert means this frame has no motion, but we were alarmed and are still recording. + mutex.lock(); snap = packetqueue.popPacket(); + mutex.unlock(); event->AddPacket( snap, score ); if ( snap->image_index == -1 ) { delete snap; @@ -1479,7 +1490,9 @@ bool Monitor::Analyse() { event->updateNotes( noteSetMap ); } else if ( state == TAPE ) { if ( !(image_count%(frame_skip+1)) ) { + mutex.lock(); snap = packetqueue.popPacket(); + mutex.unlock(); if ( config.bulk_frame_interval > 1 ) { event->AddPacket( snap, (event->Frames()last_read_index = snap->image_index; shared_data->last_read_time = now.tv_sec; } // end while not at end of packetqueue - mutex.unlock(); + //mutex.unlock(); analysis_image_count++; @@ -2728,6 +2741,7 @@ Monitor *Monitor::Load( unsigned int p_id, bool load_zones, Purpose purpose ) { * Returns -1 on failure. */ int Monitor::Capture() { + Debug(2,"Capture::Lock"); mutex.lock(); static int FirstCapture = 1; // Used in de-interlacing to indicate whether this is the even or odd image @@ -2745,7 +2759,7 @@ int Monitor::Capture() { } ZMPacket *packet = &image_buffer[index]; - Debug(2,"Reset"); + Debug(2,"Reset index(%d)", index ); packet->reset(); Image* capture_image = packet->image; int captureResult = 0; @@ -2782,33 +2796,15 @@ int Monitor::Capture() { // Analysis thread will take care of consuming and emptying the packets. - if ( packet->packet.stream_index == video_stream_id ) { - Debug(2, "Have video packet"); - if ( packet->packet.size && ! packet->in_frame ) { - packet->codec_type = camera->get_VideoStream()->codecpar->codec_type; - // Have an av_packet, - if ( packetqueue.video_packet_count || ( packet->packet.flags & AV_PKT_FLAG_KEY ) || event ) { - Debug(2, "Queueing packet"); - packetqueue.queuePacket( packet ); - } - - Debug(2,"About to decode"); - if ( packet->decode( camera->get_VideoCodecContext() ) ) { -Debug(2,"Getimage"); - packet->get_image(); - } - } else { - // If not a AVPacket, then assume video for now. - packet->codec_type = camera->get_VideoStream()->codecpar->codec_type; - Debug(2, "Queueing packet"); - packetqueue.queuePacket( packet ); - } - } else { // probably audio - Debug(2, "Have audio packet (%d) != videostream_id:(%d) ", packet->packet.stream_index, video_stream_id ); + if ( packet->packet.stream_index != video_stream_id ) { + Debug(2, "Have audio packet (%d) != videostream_id:(%d) q.vpktcount(%d) event?(%d) ", + packet->packet.stream_index, video_stream_id, packetqueue.video_packet_count, ( event ? 1 : 0 ) ); // Only queue if we have some video packets in there. if ( packetqueue.video_packet_count || event ) { // Need to copy it into another ZMPacket. + Debug(2, "Copyingg packet"); ZMPacket *audio_packet = new ZMPacket( *packet ); + Debug(2, "Copyingg packet"); audio_packet->codec_type = camera->get_AudioStream()->codecpar->codec_type; //packet->decode( camera->get_AudioCodecContext() ); Debug(2, "Queueing packet"); @@ -2820,6 +2816,22 @@ Debug(2,"Getimage"); return 1; } + Debug(2, "Have video packet"); + packet->codec_type = camera->get_VideoStream()->codecpar->codec_type; + // Have an av_packet, + if ( packetqueue.video_packet_count || ( packet->packet.flags & AV_PKT_FLAG_KEY ) || event ) { + Debug(2, "Queueing packet"); + packetqueue.queuePacket( packet ); + } + + if ( packet->packet.size && ! packet->in_frame ) { + Debug(2,"About to decode"); + if ( packet->decode( camera->get_VideoCodecContext() ) ) { + Debug(2,"Getimage"); + packet->get_image(); + } + } + /* Deinterlacing */ if ( deinterlacing_value ) { if ( deinterlacing_value == 1 ) { @@ -2859,50 +2871,6 @@ Debug(2,"Getimage"); TimestampImage( capture_image, packet->timestamp ); } -#if 0 - //Video recording - if ( video_store_data->recording.tv_sec ) { - - this->SetVideoWriterEventId(shared_data->last_event_id); - - Debug(2, "Clearing packets"); - // Clear all packets that predate the moment when the recording began - } // success opening - } // end if ! was recording - } else { // Not recording - if ( videoStore ) { - Info("Deleting videoStore instance"); - delete videoStore; - videoStore = NULL; - this->SetVideoWriterEventId( 0 ); - } - - // Buffer video packets, since we are not recording. - // All audio packets are keyframes, so only if it's a video keyframe - if ( ( packet->packet.stream_index == video_stream_id ) && ( packet->keyframe ) ) { - packetqueue.clearQueue( this->GetPreEventCount(), video_stream_id ); - } - // The following lines should ensure that the queue always begins with a video keyframe - if ( packet->packet.stream_index == camera->get_AudioStreamId() ) { - //Debug(2, "Have audio packet, reocrd_audio is (%d) and packetqueue.size is (%d)", record_audio, packetqueue.size() ); - if ( record_audio && packetqueue.size() ) { - // if it's audio, and we are doing audio, and there is already something in the queue - packetqueue.queuePacket( packet ); - } - } else if ( packet->packet.stream_index == video_stream_id ) { - if ( packet->keyframe || packetqueue.size() ) // it's a keyframe or we already have something in the queue - } // end if audio or video - } // end if recording or not - - if ( videoStore ) { - //Write the packet to our video store, it will be smart enough to know what to do - int ret = videoStore->writePacket( packet ); - if ( ret < 0 ) { //Less than zero and we skipped a frame - Warning("problem writing packet"); - } - } -#endif - shared_data->signal = CheckSignal(capture_image); shared_data->last_write_index = index; shared_data->last_write_time = image_buffer[index].timestamp->tv_sec; @@ -2931,6 +2899,7 @@ Debug(2,"Getimage"); } // end if result } // end if deinterlacing + Debug(2,"Capture unlock"); mutex.unlock(); // Icon: I'm not sure these should be here. They have nothing to do with capturing diff --git a/src/zm_packetqueue.cpp b/src/zm_packetqueue.cpp index 1073a2f5a..10a66c086 100644 --- a/src/zm_packetqueue.cpp +++ b/src/zm_packetqueue.cpp @@ -70,7 +70,8 @@ unsigned int zm_packetqueue::clearQueue( unsigned int frames_to_keep, int stream ZMPacket *zm_packet = *it; AVPacket *av_packet = &(zm_packet->packet); - Debug(4, "Looking at packet with stream index (%d) with keyframe(%d), frames_to_keep is (%d)", av_packet->stream_index, ( av_packet->flags & AV_PKT_FLAG_KEY ), frames_to_keep ); + Debug(4, "Looking at packet with stream index (%d) with keyframe(%d), frames_to_keep is (%d)", + av_packet->stream_index, ( av_packet->flags & AV_PKT_FLAG_KEY ), frames_to_keep ); // Want frames_to_keep video frames. Otherwise, we may not have enough if ( av_packet->stream_index == stream_id ) { @@ -84,22 +85,25 @@ unsigned int zm_packetqueue::clearQueue( unsigned int frames_to_keep, int stream } else { if ( it != pktQueue.rend() ) { Debug(2, "Not rend"); - } - ZMPacket *zm_packet = *it; - Debug(2, "packet %d", zm_packet); - AVPacket *av_packet = &(zm_packet->packet); - Debug(2, "packet %d", av_packet); - while ( - ( it != pktQueue.rend() ) - && - ( ( av_packet->stream_index != stream_id ) || ! ( av_packet->flags & AV_PKT_FLAG_KEY )) - ) { - ++it; - AVPacket *av_packet = &( (*it)->packet ); + ZMPacket *zm_packet = *it; + Debug(2, "packet %x %d", zm_packet, zm_packet->image_index); + + AVPacket *av_packet = &(zm_packet->packet); + while ( + ( it != pktQueue.rend() ) + && + (( av_packet->stream_index != stream_id ) || ! ( av_packet->flags & AV_PKT_FLAG_KEY )) + ) { + zm_packet = *it; + Debug(2, "packet %x %d", zm_packet, zm_packet->image_index); + ++it; + av_packet = &( (*it)->packet ); + } } } unsigned int delete_count = 0; + Debug(4, "Deleting packets from the front, count is (%d)", delete_count ); while ( it != pktQueue.rend() ) { Debug(4, "Deleting a packet from the front, count is (%d)", delete_count ); @@ -107,7 +111,7 @@ unsigned int zm_packetqueue::clearQueue( unsigned int frames_to_keep, int stream if ( packet->codec_type == AVMEDIA_TYPE_VIDEO ) video_packet_count -= 1; pktQueue.pop_front(); - if ( packet->image_index != -1 ) + if ( packet->image_index == -1 ) delete packet; delete_count += 1; @@ -121,7 +125,8 @@ void zm_packetqueue::clearQueue() { while(!pktQueue.empty()) { packet = pktQueue.front(); pktQueue.pop_front(); - delete packet; + if ( packet->image_index == -1 ) + delete packet; } video_packet_count = 0; } @@ -178,7 +183,8 @@ void zm_packetqueue::clear_unwanted_packets( timeval *recording_started, int mVi //while ( pktQueue.rend() != it ) { packet = pktQueue.front(); pktQueue.pop_front(); - delete packet; + if ( packet->image_index == -1 ) + delete packet; deleted_frames += 1; } diff --git a/src/zm_thread.cpp b/src/zm_thread.cpp index 166c40703..9728796be 100644 --- a/src/zm_thread.cpp +++ b/src/zm_thread.cpp @@ -70,6 +70,7 @@ void Mutex::lock() { if ( pthread_mutex_lock( &mMutex ) < 0 ) throw ThreadException( stringtf( "Unable to lock pthread mutex: %s", strerror(errno) ) ); + Debug(3, "Lock"); } void Mutex::lock( int secs ) @@ -90,6 +91,7 @@ void Mutex::unlock() { if ( pthread_mutex_unlock( &mMutex ) < 0 ) throw ThreadException( stringtf( "Unable to unlock pthread mutex: %s", strerror(errno) ) ); + Debug(3, "unLock"); } bool Mutex::locked() diff --git a/src/zm_videostore.cpp b/src/zm_videostore.cpp index 3baca5ae7..ab7ff5f1e 100644 --- a/src/zm_videostore.cpp +++ b/src/zm_videostore.cpp @@ -326,23 +326,23 @@ Error("Codec not set"); Debug(2, "Success creating video out stream"); } #if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0) - ret = avcodec_parameters_from_context(video_out_stream->codecpar, - video_out_ctx); + ret = avcodec_parameters_from_context(video_out_stream->codecpar, video_out_ctx); if ( ret < 0 ) { Error("Could not initialize stream parameteres"); return; } zm_dump_codecpar(video_out_stream->codecpar); -zm_dump_codec(video_out_ctx); + zm_dump_codec(video_out_ctx); #else -avcodec_copy_context( video_out_stream->codec, video_out_ctx ); -Debug(2, "%dx%d", video_out_stream->codec->width, video_out_stream->codec->height ); -zm_dump_codec(video_out_ctx); -zm_dump_codec(video_out_stream->codec); + avcodec_copy_context(video_out_stream->codec, video_out_ctx); + Debug(2, "%dx%d", video_out_stream->codec->width, video_out_stream->codec->height ); + zm_dump_codec(video_out_ctx); + zm_dump_codec(video_out_stream->codec); #endif + #if 1 -video_out_stream->time_base.num = video_out_ctx->time_base.num; -video_out_stream->time_base.den = video_out_ctx->time_base.den; + video_out_stream->time_base.num = video_out_ctx->time_base.num; + video_out_stream->time_base.den = video_out_ctx->time_base.den; #endif Debug(3, @@ -352,8 +352,6 @@ video_out_stream->time_base.den = video_out_ctx->time_base.den; video_out_ctx->time_base.num, video_out_ctx->time_base.den); - - converted_in_samples = NULL; audio_out_codec = NULL; audio_in_ctx = NULL; @@ -388,7 +386,11 @@ video_out_stream->time_base.den = video_out_ctx->time_base.den; Debug(3, "Got AAC"); audio_out_stream = +#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0) avformat_new_stream(oc, (const AVCodec *)(audio_in_ctx->codec)); +#else + avformat_new_stream(oc, (AVCodec *)audio_in_ctx->codec); +#endif if (!audio_out_stream) { Error("Unable to create audio out stream\n"); audio_out_stream = NULL; diff --git a/version b/version index 45eecfe53..604636091 100644 --- a/version +++ b/version @@ -1 +1 @@ -1.31.13 +1.31.15 diff --git a/web/includes/Monitor.php b/web/includes/Monitor.php index ed1256a52..26b5518a4 100644 --- a/web/includes/Monitor.php +++ b/web/includes/Monitor.php @@ -19,6 +19,7 @@ private $defaults = array( 'OutputContainer' => 'auto', 'AnalysisFPS' => null, 'CaptureFPS' => null, +'ZoneCount' => 0, ); private $control_fields = array( 'Name' => '', diff --git a/web/includes/Storage.php b/web/includes/Storage.php index e3fedad84..448507379 100644 --- a/web/includes/Storage.php +++ b/web/includes/Storage.php @@ -110,7 +110,7 @@ class Storage { } public function disk_used_space() { # This isn't a function like this in php, so we have to add up the space used in each event. - if ( ! array_key_exists( 'disk_used_space', $this ) ) { + if ( ! array_key_exists( 'DiskSpace', $this ) ) { $used = 0; if ( $this->{'Type'} == 's3fs' ) { $used = dbFetchOne('SELECT SUM(DiskSpace) AS DiskSpace FROM Events WHERE StorageId=? AND DiskSpace IS NOT NULL', 'DiskSpace', array($this->Id()) ); @@ -121,13 +121,13 @@ if ( 0 ) { } } } else { - $path = $this->Path(); - $used = disk_total_space( $path ) - disk_free_space( $path );; + $path = $this->Path(); + $used = disk_total_space( $path ) - disk_free_space( $path );; } - $this->{'disk_used_space'} = $used; + $this->{'DiskSpace'} = $used; } - return $this->{'disk_used_space'}; + return $this->{'DiskSpace'}; } } ?> diff --git a/web/includes/actions.php b/web/includes/actions.php index 24184d7db..1a2a13d56 100644 --- a/web/includes/actions.php +++ b/web/includes/actions.php @@ -151,14 +151,16 @@ Warning("Addterm"); if ( ! empty($_REQUEST['Id']) ) { dbQuery( 'DELETE FROM Filters WHERE Id=?', array( $_REQUEST['Id'] ) ); } - } else if ( ( $action == 'save' ) or ( $action == 'execute' ) or ( $action == 'submit' ) ) { + } else if ( ( $action == 'Save' ) or ( $action == 'SaveAs' ) or ( $action == 'execute' ) ) { + # or ( $action == 'submit' ) ) { $sql = ''; $_REQUEST['filter']['Query']['sort_field'] = validStr($_REQUEST['filter']['Query']['sort_field']); $_REQUEST['filter']['Query']['sort_asc'] = validStr($_REQUEST['filter']['Query']['sort_asc']); $_REQUEST['filter']['Query']['limit'] = validInt($_REQUEST['filter']['Query']['limit']); - if ( $action == 'execute' or $action == 'submit' ) { - $sql .= ' Name = \'_TempFilter'.time().'\''; + if ( $action == 'execute' ) { + $tempFilterName = '_TempFilter'.time(); + $sql .= ' Name = \''.$tempFilterName.'\''; } else { $sql .= ' Name = '.dbEscape($_REQUEST['filter']['Name']); } @@ -175,12 +177,15 @@ Warning("Addterm"); $sql .= ', Background = '. ( !empty($_REQUEST['filter']['Background']) ? 1 : 0); $sql .= ', Concurrent = '. ( !empty($_REQUEST['filter']['Concurrent']) ? 1 : 0); - if ( $_REQUEST['Id'] ) { + if ( $_REQUEST['Id'] and ( $action == 'Save' ) ) { dbQuery( 'UPDATE Filters SET ' . $sql. ' WHERE Id=?', array($_REQUEST['Id']) ); } else { dbQuery( 'INSERT INTO Filters SET' . $sql ); $_REQUEST['Id'] = dbInsertId(); } + if ( $action == 'execute' ) { + executeFilter( $tempFilterName ); + } } // end if save or execute } // end if canEdit(Events) @@ -370,6 +375,7 @@ if ( !empty($_REQUEST['mid']) && canEdit( 'Monitors', $_REQUEST['mid'] ) ) { dbQuery( "UPDATE Zones SET ".implode( ", ", $changes )." WHERE MonitorId=? AND Id=?", array( $mid, $zid) ); } else { dbQuery( "INSERT INTO Zones SET MonitorId=?, ".implode( ", ", $changes ), array( $mid ) ); + dbQuery( 'UPDATE Monitors SET ZoneCount=(SELECT COUNT(Id) FROM Zones WHERE MonitorId=Monitors.Id) WHERE Id=?', array($mid)); } //if ( $cookies ) session_write_close(); if ( daemonCheck() ) { @@ -422,6 +428,7 @@ if ( !empty($_REQUEST['mid']) && canEdit( 'Monitors', $_REQUEST['mid'] ) ) { foreach( $_REQUEST['markZids'] as $markZid ) { $zone = dbFetchOne( 'select * from Zones where Id=?', NULL, array($markZid) ); dbQuery( 'delete from Zones WHERE MonitorId=? AND Id=?', array( $mid, $markZid) ); + dbQuery( 'UPDATE Monitors SET ZoneCount=(SELECT COUNT(Id) FROM Zones WHERE MonitorId=Monitors.Id) WHERE Id=?', array($mid)); $deletedZid = 1; } if ( $deletedZid ) { @@ -601,10 +608,10 @@ if ( canEdit( 'Monitors' ) ) { } // end if ZM_OPT_FAST_DELETE // This is the important stuff - dbQuery( 'DELETE FROM Monitors WHERE Id = ?', array($markMid) ); dbQuery( 'DELETE FROM Zones WHERE MonitorId = ?', array($markMid) ); if ( ZM_OPT_X10 ) dbQuery( 'DELETE FROM TriggersX10 WHERE MonitorId=?', array($markMid) ); + dbQuery( 'DELETE FROM Monitors WHERE Id = ?', array($markMid) ); fixSequences(); diff --git a/web/index.php b/web/index.php index 1829f289b..845540327 100644 --- a/web/index.php +++ b/web/index.php @@ -34,7 +34,7 @@ if ( version_compare( phpversion(), '4.1.0', '<') ) { } // Useful debugging lines for mobile devices -if ( true ) { +if ( false ) { ob_start(); phpinfo( INFO_VARIABLES ); $fp = fopen( '/tmp/env.html', 'w' ); diff --git a/web/skins/classic/css/classic/skin.css b/web/skins/classic/css/classic/skin.css index 1d5af9a16..218f42e7a 100644 --- a/web/skins/classic/css/classic/skin.css +++ b/web/skins/classic/css/classic/skin.css @@ -95,9 +95,6 @@ input.noborder { border: 0; } -input[disabled] { - color: #888888; -} img { display: inline-block; @@ -407,11 +404,15 @@ th.table-th-sort-rev span.table-th-sort-span { } */ -#content > input[type=submit], #content > input[type=button], #content > button { +#content > input[type=submit], +#content > input[type=button], +#content > button { margin-top: 8px; } -#content table input[type=submit], #content table input[type=button], #content table button { +#content table input[type=submit], +#content table input[type=button], +#content table button { margin-top: 0; } @@ -420,6 +421,7 @@ th.table-th-sort-rev span.table-th-sort-span { float: right; } +#contentButtons button, #contentButtons input { margin-left: 8px; margin-bottom: 4px; @@ -487,3 +489,36 @@ margin-left: 0px; .nav-pills > li > a { border-radius: 0; } + +button, +input[type=button], +input[type=submit] { + padding: 1px 6px; + /* + background-color: #3498db; + color: #fff; + border-color: #3498db; + font-weight: 200; + padding: 5px 10px; + cursor: pointer; + */ +} + +button:hover, +input[type=button]:hover, +input[type=submit]:hover { + /* + background-color: #34a2ee; + */ +} + +button:disabled, +input[disabled], +input[type=button]:disabled, +input[type=submit]:disabled { + color: #888888; + /* + background-color: #aaaaaa; + */ + border-color: #bbbbbb; +} diff --git a/web/skins/classic/css/classic/views/filter.css b/web/skins/classic/css/classic/views/filter.css index 35bab224d..b392d1573 100644 --- a/web/skins/classic/css/classic/views/filter.css +++ b/web/skins/classic/css/classic/views/filter.css @@ -31,3 +31,7 @@ table.filterTable { width: 300px; text-align: right; } + +input#filter\[Name\] { + width: 400px; +} diff --git a/web/skins/classic/css/dark/skin.css b/web/skins/classic/css/dark/skin.css index 1cef117e2..799a2ba7c 100644 --- a/web/skins/classic/css/dark/skin.css +++ b/web/skins/classic/css/dark/skin.css @@ -108,9 +108,6 @@ input.noborder { border: 0; } -input[disabled] { - color: #777777; -} img { display: inline-block; @@ -449,6 +446,7 @@ th.table-th-sort-rev span.table-th-sort-span { float: right; } +#contentButtons button, #contentButtons input { margin-left: 8px; margin-bottom: 4px; @@ -459,31 +457,34 @@ th.table-th-sort-rev span.table-th-sort-span { margin: 8px auto; } +button, input[type=button], input[type=submit] { - background-color: #3498db; - color: #fff; - border-color: #3498db; - text-transform: uppercase; - font-weight: 200; - padding: 5px 10px; - cursor: pointer; + background-color: #3498db; + color: #fff; + border-color: #3498db; + text-transform: uppercase; + font-weight: 200; + padding: 5px 10px; + cursor: pointer; } +button:hover, input[type=button]:hover, input[type=submit]:hover { - background-color: #34a2ee; - + background-color: #34a2ee; } /* PP - make it easy to identify disabled buttons */ +button:disabled, +input[disabled], input[type=button]:disabled, input[type=submit]:disabled { - background-color: #aaaaaa; - border-color: #bbbbbb; - + color: #ffffff; + background-color: #aaaaaa; + border-color: #bbbbbb; } /* diff --git a/web/skins/classic/css/flat/skin.css b/web/skins/classic/css/flat/skin.css index e60653a41..2752d0056 100644 --- a/web/skins/classic/css/flat/skin.css +++ b/web/skins/classic/css/flat/skin.css @@ -459,6 +459,7 @@ th.table-th-sort-rev span.table-th-sort-span { margin: 8px auto; } +button, input[type=button], input[type=submit] { background-color: #3498db; @@ -470,6 +471,7 @@ input[type=submit] { cursor: pointer; } +button:hover, input[type=button]:hover, input[type=submit]:hover { background-color: #34a2ee; @@ -479,6 +481,7 @@ input[type=submit]:hover { /* PP - make it easy to identify disabled buttons */ +button:disabled, input[type=button]:disabled, input[type=submit]:disabled { background-color: #aaaaaa; diff --git a/web/skins/classic/css/flat/views/console.css b/web/skins/classic/css/flat/views/console.css index fdf1cfb63..db84313d0 100644 --- a/web/skins/classic/css/flat/views/console.css +++ b/web/skins/classic/css/flat/views/console.css @@ -90,7 +90,3 @@ #consoleTable .colLeftButtons { text-align: left; } - -#consoleTable .colLeftButtons input { - margin-right: 24px; -} diff --git a/web/skins/classic/views/_monitor_filters.php b/web/skins/classic/views/_monitor_filters.php index b81634fd4..89ff4e3eb 100644 --- a/web/skins/classic/views/_monitor_filters.php +++ b/web/skins/classic/views/_monitor_filters.php @@ -87,6 +87,7 @@ $groupSql = Group::get_group_sql( $group_id ); $displayMonitors = array(); $monitors_dropdown = array(''=>'All'); + # Check to see if the selected monitor_id is in the results. if ( $monitor_id ) { $found_selected_monitor = false; @@ -94,7 +95,6 @@ $groupSql = Group::get_group_sql( $group_id ); if ( !visibleMonitor( $monitors[$i]['Id'] ) ) { continue; } - $monitors_dropdown[$monitors[$i]['Id']] = $monitors[$i]['Name']; if ( $monitors[$i]['Id'] == $monitor_id ) { $found_selected_monitor = true; } @@ -106,12 +106,19 @@ $groupSql = Group::get_group_sql( $group_id ); for ( $i = 0; $i < count($monitors); $i++ ) { if ( !visibleMonitor( $monitors[$i]['Id'] ) ) { + Warning("Monitor " . $monitors[$i]['Id'] . ' is not visible' ); continue; } + $monitors_dropdown[$monitors[$i]['Id']] = $monitors[$i]['Name']; if ( $monitor_id and ( $monitors[$i]['Id'] != $monitor_id ) ) { continue; } + if ( isset($_SESSION['StatusFilter']) ) { + if ( $monitors[$i]['Status'] != $_SESSION['StatusFilter'] ) { + continue; + } + } $displayMonitors[] = $monitors[$i]; } echo htmlSelect( 'MonitorId', $monitors_dropdown, $monitor_id, array('onchange'=>'changeFilter(this);') ); diff --git a/web/skins/classic/views/_monitor_source_nvsocket.php b/web/skins/classic/views/_monitor_source_nvsocket.php index 2a1567dfe..ebaf93861 100644 --- a/web/skins/classic/views/_monitor_source_nvsocket.php +++ b/web/skins/classic/views/_monitor_source_nvsocket.php @@ -1,13 +1,21 @@ - + - - () - () + + + Colours() ); ?> + + () + + + + () + + Orientation() );?> diff --git a/web/skins/classic/views/console.php b/web/skins/classic/views/console.php index 8aaef178a..584fe6c62 100644 --- a/web/skins/classic/views/console.php +++ b/web/skins/classic/views/console.php @@ -22,16 +22,17 @@ if ( $running == null ) $running = daemonCheck(); $eventCounts = array( - array( + 'Total'=> array( 'title' => translate('Events'), 'filter' => array( 'Query' => array( 'terms' => array() ) ), - 'total' => 0, + 'totalevents' => 0, + 'totaldiskspace' => 0, ), - array( + 'Hour'=>array( 'title' => translate('Hour'), 'filter' => array( 'Query' => array( @@ -40,42 +41,46 @@ $eventCounts = array( ) ) ), - 'total' => 0, + 'totalevents' => 0, + 'totaldiskspace' => 0, ), - array( + 'Day'=>array( 'title' => translate('Day'), 'filter' => array( 'Query' => array( 'terms' => array( - array( 'attr' => 'DateTime', 'op' => '>=', 'val' => '-1 day' ), + array( 'attr' => 'StartDateTime', 'op' => '>=', 'val' => '-1 day' ), ) ) ), - 'total' => 0, + 'totalevents' => 0, + 'totaldiskspace' => 0, ), - array( + 'Week'=>array( 'title' => translate('Week'), 'filter' => array( 'Query' => array( 'terms' => array( - array( 'attr' => 'DateTime', 'op' => '>=', 'val' => '-7 day' ), + array( 'attr' => 'StartDateTime', 'op' => '>=', 'val' => '-7 day' ), ) ) ), - 'total' => 0, + 'totalevents' => 0, + 'totaldiskspace' => 0, ), - array( + 'Month'=>array( 'title' => translate('Month'), 'filter' => array( 'Query' => array( 'terms' => array( - array( 'attr' => 'DateTime', 'op' => '>=', 'val' => '-1 month' ), + array( 'attr' => 'StartDateTime', 'op' => '>=', 'val' => '-1 month' ), ) ) ), - 'total' => 0, + 'totalevents' => 0, + 'totaldiskspace' => 0, ), - array( + 'Archived'=>array( 'title' => translate('Archived'), 'filter' => array( 'Query' => array( @@ -84,7 +89,8 @@ $eventCounts = array( ) ) ), - 'total' => 0, + 'totalevents' => 0, + 'totaldiskspace' => 0, ), ); @@ -109,26 +115,20 @@ for ( $i = 0; $i < count($displayMonitors); $i++ ) { } $monitor['zmc'] = zmcStatus( $monitor ); $monitor['zma'] = zmaStatus( $monitor ); - $monitor['ZoneCount'] = dbFetchOne( 'select count(Id) as ZoneCount from Zones where MonitorId = ?', 'ZoneCount', array($monitor['Id']) ); $zoneCount += $monitor['ZoneCount']; $counts = array(); - for ( $j = 0; $j < count($eventCounts); $j += 1 ) { + foreach ( array_keys( $eventCounts ) as $j ) { $filter = addFilterTerm( $eventCounts[$j]['filter'], count($eventCounts[$j]['filter']['Query']['terms']), array( 'cnj' => 'and', 'attr' => 'MonitorId', 'op' => '=', 'val' => $monitor['Id'] ) ); parseFilter( $filter ); - $counts[] = 'count(if(1'.$filter['sql'].",1,NULL)) AS EventCount$j, SUM(if(1".$filter['sql'].",DiskSpace,NULL)) As DiskSpace$j"; + #$counts[] = 'count(if(1'.$filter['sql'].",1,NULL)) AS EventCount$j, SUM(if(1".$filter['sql'].",DiskSpace,NULL)) As DiskSpace$j"; $monitor['eventCounts'][$j]['filter'] = $filter; - } - $sql = 'SELECT '.join($counts,', ').' FROM Events as E where MonitorId = ?'; - $counts = dbFetchOne( $sql, NULL, array($monitor['Id']) ); - if ( $counts ) - $monitor = array_merge( $monitor, $counts ); - for ( $j = 0; $j < count($eventCounts); $j += 1 ) { - $eventCounts[$j]['total'] += $monitor['EventCount'.$j]; + $eventCounts[$j]['totalevents'] += $monitor[$j.'Events']; + $eventCounts[$j]['totaldiskspace'] += $monitor[$j.'EventDiskSpace']; } unset($monitor); } // end foreach display monitor @@ -168,10 +168,11 @@ xhtmlHeaders( __FILE__, translate('Console') ); - - - - +'. $j .''; + } +?> disabled="disabled"/> @@ -242,10 +243,10 @@ for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) { ' . human_filesize($monitor['DiskSpace'.$i]), canView( 'Events' ) ) ?> + $monitor[$i.'Events'] . '
' . human_filesize($monitor[$i.'EventDiskSpace']), canView( 'Events' ) ) ?> @@ -272,15 +273,17 @@ for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) { - - + +'.human_filesize($eventCounts[$i]['totaldiskspace']), canView( 'Events' ) ) ?> + diff --git a/web/skins/classic/views/event.php b/web/skins/classic/views/event.php index 681e0eab2..41c119967 100644 --- a/web/skins/classic/views/event.php +++ b/web/skins/classic/views/event.php @@ -176,6 +176,7 @@ if ( ZM_WEB_STREAM_METHOD == 'mpeg' && ZM_MPEG_LIVE_FORMAT ) { outputVideoStream( "evtStream", $streamSrc, reScale( $Event->Width(), $scale ), reScale( $Event->Height(), $scale ), ZM_MPEG_LIVE_FORMAT ); } else { $streamSrc = $Event->getStreamSrc( array( 'mode'=>'jpeg', 'frame'=>$fid, 'scale'=>$scale, 'rate'=>$rate, 'maxfps'=>ZM_WEB_VIDEO_MAXFPS, 'replay'=>$replayMode) ); +Warning("Streamsrc: $streamSrc"); if ( canStreamNative() ) { outputImageStream( 'evtStream', $streamSrc, reScale( $Event->Width(), $scale ), reScale( $Event->Height(), $scale ), validHtmlStr($Event->Name()) ); } else { diff --git a/web/skins/classic/views/events.php b/web/skins/classic/views/events.php index d2dfa1f1d..0166fb6b1 100644 --- a/web/skins/classic/views/events.php +++ b/web/skins/classic/views/events.php @@ -25,9 +25,6 @@ if ( !canView( 'Events' ) || (!empty($_REQUEST['execute']) && !canEdit('Events') require_once( 'includes/Event.php' ); -if ( !empty($_REQUEST['execute']) ) { - executeFilter( $tempFilterName ); -} $countSql = 'SELECT count(E.Id) AS EventCount FROM Monitors AS M INNER JOIN Events AS E ON (M.Id = E.MonitorId) WHERE'; $eventsSql = 'SELECT E.*,M.Name AS MonitorName,M.DefaultScale FROM Monitors AS M INNER JOIN Events AS E on (M.Id = E.MonitorId) WHERE'; diff --git a/web/skins/classic/views/filter.php b/web/skins/classic/views/filter.php index cb7e30087..8b8961f8b 100644 --- a/web/skins/classic/views/filter.php +++ b/web/skins/classic/views/filter.php @@ -148,7 +148,7 @@ if ( (null !== $filter->Concurrent()) and $filter->Concurrent() )
-

+

@@ -229,7 +229,7 @@ for ( $i = 0; $i < count($terms); $i++ ) {
- + - + + Id() ) { ?> @@ -415,6 +416,6 @@ if ( canEdit( 'Events' ) ) {
- - + + diff --git a/web/skins/classic/views/js/filter.js b/web/skins/classic/views/js/filter.js index ff93716c5..2a525d1b2 100644 --- a/web/skins/classic/views/js/filter.js +++ b/web/skins/classic/views/js/filter.js @@ -23,6 +23,13 @@ function updateButtons( element ) { canExecute = true; form.elements['executeButton'].disabled = !canExecute; } + if ( form.elements['filter[Name]'].value ) { + form.elements['Save'].disabled = false; + form.elements['SaveAs'].disabled = false; + } else { + form.elements['Save'].disabled = true; + form.elements['SaveAs'].disabled = true; + } } function clearValue( element, line ) { @@ -63,7 +70,7 @@ function saveFilter( element ) { //form.target = 'zmFilter'; form.target = window.name; - form.elements['action'].value = 'save'; + form.elements['action'].value = element.value; form.action = thisUrl + '?view=filter'; form.submit(); } diff --git a/web/skins/classic/views/monitor.php b/web/skins/classic/views/monitor.php index 1ea03c2a5..331e29089 100644 --- a/web/skins/classic/views/monitor.php +++ b/web/skins/classic/views/monitor.php @@ -392,9 +392,9 @@ if ( ZM_HAS_V4L2 ) { } $Colours = array( - translate('8BitGrey') => 1, - translate('24BitColour') => 3, - translate('32BitColour') => 4 + '1' => translate('8BitGrey'), + '3' => translate('24BitColour'), + '4' => translate('32BitColour') ); $orientations = array( @@ -817,7 +817,10 @@ switch ( $tab ) { Method() == 'v4l1' ) { ?> - + + + + Type() != 'NVSocket' ) { ?> - + Colours() ); ?> + () ()