Merge branch 'release-1.36' of github.com:ZoneMinder/zoneminder into release-1.36
This commit is contained in:
commit
8893a29b51
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -358,25 +358,27 @@ sub checkFilter {
|
|||
}
|
||||
} # end if AutoDelete
|
||||
|
||||
if ( $filter->{AutoMove} ) {
|
||||
my $NewStorage = new ZoneMinder::Storage($filter->{AutoMoveTo});
|
||||
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}");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,38 +86,63 @@ 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;
|
||||
pktQueue.push_back(add_packet);
|
||||
packet_counts[add_packet->packet.stream_index] += 1;
|
||||
Debug(2, "packet counts for %d is %d",
|
||||
add_packet->packet.stream_index,
|
||||
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;
|
||||
// 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);
|
||||
if (*iterator_it == pktQueue.end()) {
|
||||
--(*iterator_it);
|
||||
}
|
||||
} // end foreach iterator
|
||||
|
||||
pktQueue.pop_front();
|
||||
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",
|
||||
|
@ -128,39 +152,13 @@ bool PacketQueue::queuePacket(std::shared_ptr<ZMPacket> add_packet) {
|
|||
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 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",
|
||||
add_packet->packet.stream_index,
|
||||
packet_counts[add_packet->packet.stream_index]);
|
||||
|
||||
for (
|
||||
std::list<packetqueue_iterator *>::iterator 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
|
||||
} // 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");
|
||||
|
@ -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)) {
|
||||
#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) {
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 14292374ccf1328f2d5db20897bd06f99ba4d938
|
||||
Subproject commit 0bd63fb464957080ead342db58ca9e01532cf1ef
|
|
@ -50,6 +50,7 @@ select.chosen {
|
|||
}
|
||||
tr td:first-child {
|
||||
min-width: 300px;
|
||||
vertical-align: top;
|
||||
}
|
||||
.OutputContainer {
|
||||
display: none;
|
||||
|
|
Loading…
Reference in New Issue