Merge branch 'release-1.36' of github.com:ZoneMinder/zoneminder into release-1.36

This commit is contained in:
Isaac Connor 2021-10-25 17:06:40 -04:00
commit 8893a29b51
9 changed files with 129 additions and 112 deletions

View File

@ -28,8 +28,8 @@ SET @s = (SELECT IF(
AND table_name = 'Monitors'
AND column_name = 'TotalEvents'
) > 0,
"SELECT 'Column TotalEvents is already removed from Monitors'",
"ALTER TABLE `Monitors` DROP `TotalEvents`"
"ALTER TABLE `Monitors` DROP `TotalEvents`",
"SELECT 'Column TotalEvents is already removed from Monitors'"
));
PREPARE stmt FROM @s;
EXECUTE stmt;
@ -50,8 +50,8 @@ SET @s = (SELECT IF(
AND table_name = 'Monitors'
AND column_name = 'TotalEventDiskSpace'
) > 0,
"SELECT 'Column TotalEventDiskSpace is already removed from Monitors'",
"ALTER TABLE `Monitors` DROP `TotalEventDiskSpace`"
"ALTER TABLE `Monitors` DROP `TotalEventDiskSpace`",
"SELECT 'Column TotalEventDiskSpace is already removed from Monitors'"
));
PREPARE stmt FROM @s;
EXECUTE stmt;

View File

@ -36,7 +36,7 @@
%global _hardened_build 1
Name: zoneminder
Version: 1.36.9
Version: 1.36.10
Release: 1%{?dist}
Summary: A camera monitoring and analysis tool
Group: System Environment/Daemons
@ -430,6 +430,9 @@ ln -sf %{_sysconfdir}/zm/www/zoneminder.nginx.conf %{_sysconfdir}/zm/www/zonemin
%dir %attr(755,nginx,nginx) %{_localstatedir}/log/zoneminder
%changelog
* Mon Oct 25 2021 Andrew Bauer <zonexpertconsulting@outlook.com> - 1.36.10-1
- 1.36.10 release
* Tue Oct 19 2021 Andrew Bauer <zonexpertconsulting@outlook.com> - 1.36.9-1
- 1.36.9 release

View File

@ -756,9 +756,9 @@ sub CopyTo {
} # end sub CopyTo
sub MoveTo {
my ( $self, $NewStorage ) = @_;
my ($self, $NewStorage) = @_;
if ( !$self->canEdit() ) {
if (!$self->canEdit()) {
Warning('No permission to move event.');
return 'No permission to move event.';
}
@ -772,11 +772,9 @@ sub MoveTo {
$$self{StorageId} = $$NewStorage{Id};
$self->Storage($NewStorage);
$error .= $self->save();
if ( $error ) {
$ZoneMinder::Database::dbh->commit();
if ($error) {
return $error;
}
$ZoneMinder::Database::dbh->commit();
$self->delete_files($OldStorage);
return $error;
} # end sub MoveTo

View File

@ -358,25 +358,27 @@ sub checkFilter {
}
} # end if AutoDelete
if ( $filter->{AutoMove} ) {
my $NewStorage = new ZoneMinder::Storage($filter->{AutoMoveTo});
Info("Moving event $Event->{Id} to datastore $filter->{AutoMoveTo}");
$_ = $Event->MoveTo($NewStorage);
Error($_) if $_;
if ($filter->{AutoMove}) {
my $NewStorage = ZoneMinder::Storage->find_one(Id=>$filter->{AutoMoveTo});
if ($NewStorage) {
Info("Moving event $Event->{Id} to datastore $filter->{AutoMoveTo}");
$_ = $Event->MoveTo($NewStorage);
Error($_) if $_;
} else {
Error("No storage area found for move to operation. AutoMoveTo was $$filter{AutoMoveTo}");
}
}
if ( $filter->{AutoCopy} ) {
if ($filter->{AutoCopy}) {
# Copy To is different from MoveTo in that it JUST copies the files
# So we still need to update the Event object with the new SecondaryStorageId
my $NewStorage = ZoneMinder::Storage->find_one(Id=>$filter->{AutoCopyTo});
if ( $NewStorage ) {
Info("Copying event $Event->{Id} to datastore $filter->{AutoCopyTo}");
$_ = $Event->CopyTo($NewStorage);
if ( $_ ) {
$ZoneMinder::Database::dbh->commit();
if ($_) {
Error($_);
} else {
$Event->save({SecondaryStorageId=>$$NewStorage{Id}});
$ZoneMinder::Database::dbh->commit();
}
} else {
Error("No storage area found for copy to operation. AutoCopyTo was $$filter{AutoCopyTo}");

View File

@ -92,6 +92,7 @@ std::string load_monitor_sql =
"`SignalCheckPoints`, `SignalCheckColour`, `Importance`-1 FROM `Monitors`";
std::string CameraType_Strings[] = {
"Unknown",
"Local",
"Remote",
"File",
@ -99,10 +100,21 @@ std::string CameraType_Strings[] = {
"LibVLC",
"NVSOCKET",
"CURL",
"VNC",
"VNC"
};
std::string Function_Strings[] = {
"Unknown",
"None",
"Monitor",
"Modect",
"Record",
"Mocord",
"Nodect"
};
std::string State_Strings[] = {
"Unknown",
"IDLE",
"PREALARM",
"ALARM",
@ -204,7 +216,7 @@ bool Monitor::MonitorLink::connect() {
shared_data = (SharedData *)mem_ptr;
trigger_data = (TriggerData *)((char *)shared_data + sizeof(SharedData));
if ( !shared_data->valid ) {
if (!shared_data->valid) {
Debug(3, "Linked memory not initialised by capture daemon");
disconnect();
return false;
@ -220,23 +232,23 @@ bool Monitor::MonitorLink::connect() {
} // end bool Monitor::MonitorLink::connect()
bool Monitor::MonitorLink::disconnect() {
if ( connected ) {
if (connected) {
connected = false;
#if ZM_MEM_MAPPED
if ( mem_ptr > (void *)0 ) {
msync( mem_ptr, mem_size, MS_ASYNC );
munmap( mem_ptr, mem_size );
if (mem_ptr > (void *)0) {
msync(mem_ptr, mem_size, MS_ASYNC);
munmap(mem_ptr, mem_size);
}
if ( map_fd >= 0 )
close( map_fd );
if (map_fd >= 0)
close(map_fd);
map_fd = -1;
#else // ZM_MEM_MAPPED
struct shmid_ds shm_data;
if ( shmctl( shm_id, IPC_STAT, &shm_data ) < 0 ) {
Debug( 3, "Can't shmctl: %s", strerror(errno) );
return( false );
if (shmctl(shm_id, IPC_STAT, &shm_data) < 0) {
Debug(3, "Can't shmctl: %s", strerror(errno));
return false;
}
shm_id = 0;
@ -252,7 +264,6 @@ bool Monitor::MonitorLink::disconnect() {
Debug(3, "Can't shmdt: %s", strerror(errno));
return false;
}
#endif // ZM_MEM_MAPPED
mem_size = 0;
mem_ptr = nullptr;
@ -484,16 +495,7 @@ void Monitor::Load(MYSQL_ROW dbrow, bool load_zones=true, Purpose p = QUERY) {
function = (Function)atoi(dbrow[col]); col++;
enabled = dbrow[col] ? atoi(dbrow[col]) : false; col++;
decoding_enabled = dbrow[col] ? atoi(dbrow[col]) : false; col++;
decoding_enabled = !(
( function == RECORD or function == NODECT )
and
( savejpegs == 0 )
and
( videowriter == PASSTHROUGH )
and
!decoding_enabled
);
Debug(1, "Decoding enabled: %d", decoding_enabled);
// See below after save_jpegs for a recalculation of decoding_enabled
ReloadLinkedMonitors(dbrow[col]); col++;
@ -556,6 +558,17 @@ void Monitor::Load(MYSQL_ROW dbrow, bool load_zones=true, Purpose p = QUERY) {
videowriter = (VideoWriter)atoi(dbrow[col]); col++;
encoderparams = dbrow[col] ? dbrow[col] : ""; col++;
decoding_enabled = !(
( function == RECORD or function == NODECT )
and
( savejpegs == 0 )
and
( videowriter == PASSTHROUGH )
and
!decoding_enabled
);
Debug(3, "Decoding enabled: %d function %d %s savejpegs %d videowriter %d", decoding_enabled, function, Function_Strings[function].c_str(), savejpegs, videowriter);
/*"`OutputCodec`, `Encoder`, `OutputContainer`, " */
output_codec = dbrow[col] ? atoi(dbrow[col]) : 0; col++;
encoder = dbrow[col] ? dbrow[col] : ""; col++;
@ -898,7 +911,6 @@ std::shared_ptr<Monitor> Monitor::Load(unsigned int p_id, bool load_zones, Purpo
}
bool Monitor::connect() {
if (mem_ptr != nullptr) {
Warning("Already connected. Please call disconnect first.");
}
@ -1040,7 +1052,7 @@ bool Monitor::connect() {
video_store_data->size = sizeof(VideoStoreData);
usedsubpixorder = camera->SubpixelOrder(); // Used in CheckSignal
shared_data->valid = true;
} else if ( !shared_data->valid ) {
} else if (!shared_data->valid) {
Error("Shared data not initialised by capture daemon for monitor %s", name.c_str());
return false;
}

View File

@ -24,7 +24,6 @@
#include "zm_ffmpeg.h"
#include "zm_packet.h"
#include "zm_signal.h"
#include <sys/time.h>
PacketQueue::PacketQueue():
video_stream_id(-1),
@ -87,61 +86,6 @@ bool PacketQueue::queuePacket(std::shared_ptr<ZMPacket> add_packet) {
{
std::unique_lock<std::mutex> lck(mutex);
if (add_packet->packet.stream_index == video_stream_id) {
if ((max_video_packet_count > 0) and (packet_counts[video_stream_id] > max_video_packet_count)) {
Warning("You have set the max video packets in the queue to %u."
" The queue is full. Either Analysis is not keeping up or"
" your camera's keyframe interval is larger than this setting."
" We are dropping packets.", max_video_packet_count);
if (add_packet->keyframe) {
// Have a new keyframe, so delete everything
while ((*pktQueue.begin() != add_packet) and (packet_counts[video_stream_id] > max_video_packet_count)) {
std::shared_ptr <ZMPacket>zm_packet = *pktQueue.begin();
ZMLockedPacket *lp = new ZMLockedPacket(zm_packet);
if (!lp->trylock()) {
Debug(1, "Found locked packet when trying to free up video packets. Can't continue");
delete lp;
break;
}
delete lp;
for (
std::list<packetqueue_iterator *>::iterator iterators_it = iterators.begin();
iterators_it != iterators.end();
++iterators_it
) {
packetqueue_iterator *iterator_it = *iterators_it;
// Have to check each iterator and make sure it doesn't point to the packet we are about to delete
if ( *(*iterator_it) == zm_packet ) {
Debug(1, "Bumping IT because it is at the front that we are deleting");
++(*iterators_it);
}
} // end foreach iterator
pktQueue.pop_front();
packet_counts[zm_packet->packet.stream_index] -= 1;
Debug(1,
"Deleting a packet with stream index:%d image_index:%d with keyframe:%d, video frames in queue:%d max: %d, queuesize:%zu",
zm_packet->packet.stream_index,
zm_packet->image_index,
zm_packet->keyframe,
packet_counts[video_stream_id],
max_video_packet_count,
pktQueue.size());
} // end while
}
} // end if too many video packets
if (max_video_packet_count > 0) {
while (packet_counts[video_stream_id] > max_video_packet_count) {
Error("Unable to free up older packets. Waiting.");
condition.notify_all();
condition.wait(lck);
if (deleting or zm_terminate)
return false;
}
}
} // end if this packet is a video packet
pktQueue.push_back(add_packet);
packet_counts[add_packet->packet.stream_index] += 1;
Debug(2, "packet counts for %d is %d",
@ -149,25 +93,79 @@ bool PacketQueue::queuePacket(std::shared_ptr<ZMPacket> add_packet) {
packet_counts[add_packet->packet.stream_index]);
for (
std::list<packetqueue_iterator *>::iterator iterators_it = iterators.begin();
auto iterators_it = iterators.begin();
iterators_it != iterators.end();
++iterators_it
) {
packetqueue_iterator *iterator_it = *iterators_it;
if (*iterator_it == pktQueue.end()) {
Debug(4, "pointing it %p to back", iterator_it);
--(*iterator_it);
} else {
Debug(4, "it %p not at end", iterator_it);
}
} // end foreach iterator
if (
(add_packet->packet.stream_index == video_stream_id)
and
(max_video_packet_count > 0)
and
(packet_counts[video_stream_id] > max_video_packet_count)
) {
Warning("You have set the max video packets in the queue to %u."
" The queue is full. Either Analysis is not keeping up or"
" your camera's keyframe interval is larger than this setting."
, max_video_packet_count);
for (
auto it = ++pktQueue.begin();
it != pktQueue.end() and *it != add_packet;
) {
std::shared_ptr <ZMPacket>zm_packet = *it;
ZMLockedPacket *lp = new ZMLockedPacket(zm_packet);
if (!lp->trylock()) {
Debug(1, "Found locked packet when trying to free up video packets. Skipping to next one");
delete lp;
++it;
continue;
}
for (
auto iterators_it = iterators.begin();
iterators_it != iterators.end();
++iterators_it
) {
auto iterator_it = *iterators_it;
// Have to check each iterator and make sure it doesn't point to the packet we are about to delete
if ((*iterator_it!=pktQueue.end()) and (*(*iterator_it) == zm_packet)) {
Debug(1, "Bumping IT because it is at the front that we are deleting");
++(*iterator_it);
}
} // end foreach iterator
it = pktQueue.erase(it);
packet_counts[zm_packet->packet.stream_index] -= 1;
Debug(1,
"Deleting a packet with stream index:%d image_index:%d with keyframe:%d, video frames in queue:%d max: %d, queuesize:%zu",
zm_packet->packet.stream_index,
zm_packet->image_index,
zm_packet->keyframe,
packet_counts[video_stream_id],
max_video_packet_count,
pktQueue.size());
delete lp;
if (zm_packet->packet.stream_index == video_stream_id)
break;
} // end while
} // end if not able catch up
} // end lock scope
// We signal on every packet because someday we may analyze sound
Debug(4, "packetqueue queuepacket, unlocked signalling");
condition.notify_all();
return true;
} // end bool PacketQueue::queuePacket(ZMPacket* zm_packet)
} // end bool PacketQueue::queuePacket(ZMPacket* zm_packet)
void PacketQueue::clearPackets(const std::shared_ptr<ZMPacket> &add_packet) {
// Only do queueCleaning if we are adding a video keyframe, so that we guarantee that there is one.
@ -241,8 +239,8 @@ void PacketQueue::clearPackets(const std::shared_ptr<ZMPacket> &add_packet) {
return;
}
packetqueue_iterator it = pktQueue.begin();
packetqueue_iterator next_front = pktQueue.begin();
auto it = pktQueue.begin();
auto next_front = pktQueue.begin();
// First packet is special because we know it is a video keyframe and only need to check for lock
std::shared_ptr<ZMPacket> zm_packet = *it;
@ -250,11 +248,10 @@ void PacketQueue::clearPackets(const std::shared_ptr<ZMPacket> &add_packet) {
return;
}
Debug(1, "trying lock on first packet");
ZMLockedPacket *lp = new ZMLockedPacket(zm_packet);
if (lp->trylock()) {
int video_packets_to_delete = 0; // This is a count of how many packets we will delete so we know when to stop looking
Debug(1, "Have lock on first packet");
Debug(4, "Have lock on first packet");
++it;
delete lp;
@ -269,10 +266,14 @@ void PacketQueue::clearPackets(const std::shared_ptr<ZMPacket> &add_packet) {
}
delete lp;
if (is_there_an_iterator_pointing_to_packet(zm_packet) and (pktQueue.begin() == next_front)) {
Warning("Found iterator at beginning of queue. Some thread isn't keeping up");
#if 0
// There are no threads that follow analysis thread. So there cannot be an it pointing here
if (is_there_an_iterator_pointing_to_packet(zm_packet)) {
if (pktQueue.begin() == next_front)
Warning("Found iterator at beginning of queue. Some thread isn't keeping up");
break;
}
#endif
if (zm_packet->packet.stream_index == video_stream_id) {
if (zm_packet->keyframe) {

View File

@ -1 +1 @@
1.36.9
1.36.10

@ -1 +1 @@
Subproject commit 14292374ccf1328f2d5db20897bd06f99ba4d938
Subproject commit 0bd63fb464957080ead342db58ca9e01532cf1ef

View File

@ -50,6 +50,7 @@ select.chosen {
}
tr td:first-child {
min-width: 300px;
vertical-align: top;
}
.OutputContainer {
display: none;