Merge branch 'master' of github.com:ZoneMinder/zoneminder

This commit is contained in:
Isaac Connor 2021-11-24 13:44:59 -05:00
commit 6037cdc2a3
12 changed files with 98 additions and 65 deletions

View File

@ -167,6 +167,8 @@ set(ZM_NO_X10 "OFF" CACHE BOOL
set(ZM_ONVIF "ON" CACHE BOOL set(ZM_ONVIF "ON" CACHE BOOL
"Set to ON to enable basic ONVIF support. This is EXPERIMENTAL and may not "Set to ON to enable basic ONVIF support. This is EXPERIMENTAL and may not
work with all cameras claiming to be ONVIF compliant. default: ON") work with all cameras claiming to be ONVIF compliant. default: ON")
set(ZM_NO_PCRE "OFF" CACHE BOOL
"Set to ON to skip libpcre3 checks and force building ZM without libpcre3. default: OFF")
set(ZM_NO_RTSPSERVER "OFF" CACHE BOOL set(ZM_NO_RTSPSERVER "OFF" CACHE BOOL
"Set to ON to skip building ZM with rtsp server support. default: OFF") "Set to ON to skip building ZM with rtsp server support. default: OFF")
set(ZM_PERL_MM_PARMS INSTALLDIRS=vendor NO_PACKLIST=1 NO_PERLLOCAL=1 CACHE STRING set(ZM_PERL_MM_PARMS INSTALLDIRS=vendor NO_PACKLIST=1 NO_PERLLOCAL=1 CACHE STRING
@ -407,21 +409,24 @@ else()
message(FATAL_ERROR "ZoneMinder requires pthread but it was not found on your system") message(FATAL_ERROR "ZoneMinder requires pthread but it was not found on your system")
endif() endif()
# pcre (using find_library and find_path) # Do not check for cURL if ZM_NO_CURL is on
find_library(PCRE_LIBRARIES pcre) if(NOT ZM_NO_PRCE)
if(PCRE_LIBRARIES) # pcre (using find_library and find_path)
set(HAVE_LIBPCRE 1) find_library(PCRE_LIBRARIES pcre)
list(APPEND ZM_BIN_LIBS "${PCRE_LIBRARIES}") if(PCRE_LIBRARIES)
find_path(PCRE_INCLUDE_DIR pcre.h) set(HAVE_LIBPCRE 1)
if(PCRE_INCLUDE_DIR) list(APPEND ZM_BIN_LIBS "${PCRE_LIBRARIES}")
include_directories("${PCRE_INCLUDE_DIR}") find_path(PCRE_INCLUDE_DIR pcre.h)
set(CMAKE_REQUIRED_INCLUDES "${PCRE_INCLUDE_DIR}") if(PCRE_INCLUDE_DIR)
include_directories("${PCRE_INCLUDE_DIR}")
set(CMAKE_REQUIRED_INCLUDES "${PCRE_INCLUDE_DIR}")
endif()
mark_as_advanced(FORCE PCRE_LIBRARIES PCRE_INCLUDE_DIR)
check_include_file("pcre.h" HAVE_PCRE_H)
set(optlibsfound "${optlibsfound} PCRE")
else()
set(optlibsnotfound "${optlibsnotfound} PCRE")
endif() endif()
mark_as_advanced(FORCE PCRE_LIBRARIES PCRE_INCLUDE_DIR)
check_include_file("pcre.h" HAVE_PCRE_H)
set(optlibsfound "${optlibsfound} PCRE")
else()
set(optlibsnotfound "${optlibsnotfound} PCRE")
endif() endif()
# mysqlclient (using find_library and find_path) # mysqlclient (using find_library and find_path)
@ -540,6 +545,7 @@ set(ZM_PCRE 0)
if(HAVE_LIBPCRE AND HAVE_PCRE_H) if(HAVE_LIBPCRE AND HAVE_PCRE_H)
set(ZM_PCRE 1) set(ZM_PCRE 1)
endif() endif()
# Check for mmap and enable in all components # Check for mmap and enable in all components
set(ZM_MEM_MAPPED 0) set(ZM_MEM_MAPPED 0)
set(ENABLE_MMAP no) set(ENABLE_MMAP no)

View File

@ -16,7 +16,6 @@ Build-Depends: debhelper (>= 11), sphinx-doc, python3-sphinx, dh-linktree, dh-ap
,libjpeg-turbo8-dev | libjpeg62-turbo-dev | libjpeg8-dev | libjpeg9-dev ,libjpeg-turbo8-dev | libjpeg62-turbo-dev | libjpeg8-dev | libjpeg9-dev
,libturbojpeg0-dev ,libturbojpeg0-dev
,default-libmysqlclient-dev | libmysqlclient-dev | libmariadbclient-dev-compat ,default-libmysqlclient-dev | libmysqlclient-dev | libmariadbclient-dev-compat
,libpcre3-dev
,libpolkit-gobject-1-dev ,libpolkit-gobject-1-dev
,libv4l-dev [!hurd-any] ,libv4l-dev [!hurd-any]
,libvlc-dev ,libvlc-dev
@ -70,7 +69,6 @@ Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}
,policykit-1 ,policykit-1
,rsyslog | system-log-daemon ,rsyslog | system-log-daemon
,zip ,zip
,libpcre3
,libcrypt-eksblowfish-perl ,libcrypt-eksblowfish-perl
,libdata-entropy-perl ,libdata-entropy-perl
,libvncclient1|libvncclient0 ,libvncclient1|libvncclient0

View File

@ -19,6 +19,7 @@ override_dh_auto_configure:
-DCMAKE_VERBOSE_MAKEFILE=ON \ -DCMAKE_VERBOSE_MAKEFILE=ON \
-DCMAKE_BUILD_TYPE=Release \ -DCMAKE_BUILD_TYPE=Release \
-DBUILD_MAN=0 \ -DBUILD_MAN=0 \
-DZM_NO_PCRE=ON \
-DZM_CONFIG_DIR="/etc/zm" \ -DZM_CONFIG_DIR="/etc/zm" \
-DZM_CONFIG_SUBDIR="/etc/zm/conf.d" \ -DZM_CONFIG_SUBDIR="/etc/zm/conf.d" \
-DZM_RUNDIR="/run/zm" \ -DZM_RUNDIR="/run/zm" \

View File

@ -326,18 +326,30 @@ sub resumeMotionDetection {
sub Control { sub Control {
my $self = shift; my $self = shift;
if ( ! exists $$self{Control}) { if (!exists $$self{Control}) {
require ZoneMinder::Control; if ($$self{ControlId}) {
my $Control = ZoneMinder::Control->find_one(Id=>$$self{ControlId}); require ZoneMinder::Control;
if ($Control) { my $Control = ZoneMinder::Control->find_one(Id=>$$self{ControlId});
require Module::Load::Conditional; if ($Control) {
if (!Module::Load::Conditional::can_load(modules => {'ZoneMinder::Control::'.$$Control{Protocol} => undef})) { my $Protocol = $$Control{Protocol};
Error("Can't load ZoneMinder::Control::$$Control{Protocol}\n$Module::Load::Conditional::ERROR");
return undef; if (!$Protocol) {
Error("No protocol set in control $$Control{Id}, trying Name $$Control{Name}");
$Protocol = $$Control{Name};
}
require Module::Load::Conditional;
if (!Module::Load::Conditional::can_load(modules => {'ZoneMinder::Control::'.$Protocol => undef})) {
Error("Can't load ZoneMinder::Control::$Protocol\n$Module::Load::Conditional::ERROR");
return undef;
}
bless $Control, 'ZoneMinder::Control::'.$Protocol;
$$Control{MonitorId} = $$self{Id};
$$self{Control} = $Control;
} else {
Error("Unable to load control for control $$self{ControlId} for monitor $$self{Id}");
} }
bless $Control, 'ZoneMinder::Control::'.$$Control{Protocol}; } else {
$$Control{MonitorId} = $$self{Id}; Info("No ControlId set in monitor $$self{Id}")
$$self{Control} = $Control;
} }
} }
return $$self{Control}; return $$self{Control};

View File

@ -429,10 +429,20 @@ sub start {
# It's not running, or at least it's not been started by us # It's not running, or at least it's not been started by us
$process = { daemon=>$daemon, args=>\@args, command=>$command, keepalive=>!undef }; $process = { daemon=>$daemon, args=>\@args, command=>$command, keepalive=>!undef };
} elsif ( $process->{pid} && $pid_hash{$process->{pid}} ) { } elsif ( $process->{pid} && $pid_hash{$process->{pid}} ) {
dPrint(ZoneMinder::Logger::INFO, "'$process->{command}' already running at " if ($process->{term_sent_at}) {
dPrint(ZoneMinder::Logger::INFO, "'$process->{command}' was told to term at "
.strftime('%y/%m/%d %H:%M:%S', localtime($process->{term_sent_at}))
.", pid = $process->{pid}\n"
);
$process->{keepalive} = !undef;
$process->{delay} = 0;
delete $terminating_processes{$command};
} else {
dPrint(ZoneMinder::Logger::INFO, "'$process->{command}' already running at "
.strftime('%y/%m/%d %H:%M:%S', localtime($process->{started})) .strftime('%y/%m/%d %H:%M:%S', localtime($process->{started}))
.", pid = $process->{pid}\n" .", pid = $process->{pid}\n"
); );
}
return; return;
} }
@ -523,7 +533,7 @@ sub send_stop {
."\n" ."\n"
); );
sigprocmask(SIG_UNBLOCK, $blockset) or die "dying at unblock...\n"; sigprocmask(SIG_UNBLOCK, $blockset) or die "dying at unblock...\n";
return(); return ();
} }
my $pid = $process->{pid}; my $pid = $process->{pid};
@ -586,7 +596,7 @@ sub check_for_processes_to_kill {
sub stop { sub stop {
my ( $daemon, @args ) = @_; my ( $daemon, @args ) = @_;
my $command = join(' ', $daemon, @args ); my $command = join(' ', $daemon, @args);
my $process = $cmd_hash{$command}; my $process = $cmd_hash{$command};
if ( !$process ) { if ( !$process ) {
dPrint(ZoneMinder::Logger::WARNING, "Can't find process with command of '$command'"); dPrint(ZoneMinder::Logger::WARNING, "Can't find process with command of '$command'");

View File

@ -251,11 +251,11 @@ void zmDbQueue::process() {
mCondition.wait(lock); mCondition.wait(lock);
} }
while (!mQueue.empty()) { while (!mQueue.empty()) {
if (mQueue.size() > 10) { if (mQueue.size() > 20) {
Logger *log = Logger::fetch(); Logger *log = Logger::fetch();
Logger::Level db_level = log->databaseLevel(); Logger::Level db_level = log->databaseLevel();
log->databaseLevel(Logger::NOLOG); log->databaseLevel(Logger::NOLOG);
Warning("db queue size has grown larger %zu than 10 entries", mQueue.size()); Warning("db queue size has grown larger %zu than 20 entries", mQueue.size());
log->databaseLevel(db_level); log->databaseLevel(db_level);
} }
std::string sql = mQueue.front(); std::string sql = mQueue.front();
@ -271,8 +271,10 @@ void zmDbQueue::process() {
void zmDbQueue::push(std::string &&sql) { void zmDbQueue::push(std::string &&sql) {
if (mTerminate) return; if (mTerminate) return;
std::unique_lock<std::mutex> lock(mMutex); {
mQueue.push(std::move(sql)); std::unique_lock<std::mutex> lock(mMutex);
mQueue.push(std::move(sql));
}
mCondition.notify_all(); mCondition.notify_all();
} }

View File

@ -377,10 +377,10 @@ bool MonitorStream::sendFrame(const std::string &filepath, SystemTimePoint times
} }
bool MonitorStream::sendFrame(Image *image, SystemTimePoint timestamp) { bool MonitorStream::sendFrame(Image *image, SystemTimePoint timestamp) {
Image *send_image = prepareImage(image);
if (!config.timestamp_on_capture) { if (!config.timestamp_on_capture) {
monitor->TimestampImage(send_image, timestamp); monitor->TimestampImage(image, timestamp);
} }
Image *send_image = prepareImage(image);
fputs("--" BOUNDARY "\r\n", stdout); fputs("--" BOUNDARY "\r\n", stdout);
if ( type == STREAM_MPEG ) { if ( type == STREAM_MPEG ) {
@ -854,16 +854,16 @@ void MonitorStream::SingleImage(int scale) {
int index = monitor->shared_data->last_write_index % monitor->image_buffer_count; int index = monitor->shared_data->last_write_index % monitor->image_buffer_count;
Debug(1, "write index: %d %d", monitor->shared_data->last_write_index, index); Debug(1, "write index: %d %d", monitor->shared_data->last_write_index, index);
Image *snap_image = monitor->image_buffer[index]; Image *snap_image = monitor->image_buffer[index];
if (!config.timestamp_on_capture) {
monitor->TimestampImage(snap_image,
SystemTimePoint(zm::chrono::duration_cast<Microseconds>(monitor->shared_timestamps[index])));
}
if ( scale != ZM_SCALE_BASE ) { if ( scale != ZM_SCALE_BASE ) {
scaled_image.Assign(*snap_image); scaled_image.Assign(*snap_image);
scaled_image.Scale(scale); scaled_image.Scale(scale);
snap_image = &scaled_image; snap_image = &scaled_image;
} }
if (!config.timestamp_on_capture) {
monitor->TimestampImage(snap_image,
SystemTimePoint(zm::chrono::duration_cast<Microseconds>(monitor->shared_timestamps[index])));
}
snap_image->EncodeJpeg(img_buffer, &img_buffer_size); snap_image->EncodeJpeg(img_buffer, &img_buffer_size);
fprintf(stdout, fprintf(stdout,

View File

@ -116,14 +116,15 @@ bool PacketQueue::queuePacket(std::shared_ptr<ZMPacket> add_packet) {
, max_video_packet_count); , max_video_packet_count);
for ( for (
auto it = ++pktQueue.begin(); auto it = ++pktQueue.begin();
it != pktQueue.end() and *it != add_packet; it != pktQueue.end() and *it != add_packet;
// iterator is incremented by erase
) { ) {
std::shared_ptr <ZMPacket>zm_packet = *it; std::shared_ptr <ZMPacket>zm_packet = *it;
ZMLockedPacket *lp = new ZMLockedPacket(zm_packet); ZMLockedPacket *lp = new ZMLockedPacket(zm_packet);
if (!lp->trylock()) { if (!lp->trylock()) {
Debug(1, "Found locked packet when trying to free up video packets. Skipping to next one"); Warning("Found locked packet when trying to free up video packets. This basically means that decoding is not keeping up.");
delete lp; delete lp;
++it; ++it;
continue; continue;
@ -312,7 +313,6 @@ void PacketQueue::clearPackets(const std::shared_ptr<ZMPacket> &add_packet) {
pktQueue.size()); pktQueue.size());
pktQueue.pop_front(); pktQueue.pop_front();
packet_counts[zm_packet->packet.stream_index] -= 1; packet_counts[zm_packet->packet.stream_index] -= 1;
//delete zm_packet;
} }
} // end if have at least max_video_packet_count video packets remaining } // end if have at least max_video_packet_count video packets remaining
// We signal on every packet because someday we may analyze sound // We signal on every packet because someday we may analyze sound

View File

@ -63,13 +63,13 @@ function processRows(rows) {
row.Id = '<a href="?view=event&amp;eid=' + eid + filterQuery + sortQuery + '&amp;page=1">' + eid + '</a>'; row.Id = '<a href="?view=event&amp;eid=' + eid + filterQuery + sortQuery + '&amp;page=1">' + eid + '</a>';
row.Name = '<a href="?view=event&amp;eid=' + eid + filterQuery + sortQuery + '&amp;page=1">' + row.Name + '</a>' + row.Name = '<a href="?view=event&amp;eid=' + eid + filterQuery + sortQuery + '&amp;page=1">' + row.Name + '</a>' +
'<br/><div class="small text-nowrap text-muted">' + archived + emailed + '</div>'; '<br/><div class="small text-muted">' + archived + emailed + '</div>';
if ( canEdit.Monitors ) row.Monitor = '<a href="?view=event&amp;eid=' + eid + '">' + row.Monitor + '</a>'; if ( canEdit.Monitors ) row.Monitor = '<a href="?view=event&amp;eid=' + eid + '">' + row.Monitor + '</a>';
if ( canEdit.Events ) row.Cause = '<a href="#" title="' + row.Notes + '" class="eDetailLink" data-eid="' + eid + '">' + row.Cause + '</a>'; if ( canEdit.Events ) row.Cause = '<a href="#" title="' + row.Notes + '" class="eDetailLink" data-eid="' + eid + '">' + row.Cause + '</a>';
if ( row.Notes.indexOf('detected:') >= 0 ) { if ( row.Notes.indexOf('detected:') >= 0 ) {
row.Cause = row.Cause + '<a href="#" class="objDetectLink" data-eid=' +eid+ '><div class="small text-nowrap text-muted"><u>' + row.Notes + '</u></div></div></a>'; row.Cause = row.Cause + '<a href="#" class="objDetectLink" data-eid=' +eid+ '><div class="small text-muted"><u>' + row.Notes + '</u></div></div></a>';
} else if ( row.Notes != 'Forced Web: ' ) { } else if ( row.Notes != 'Forced Web: ' ) {
row.Cause = row.Cause + '<br/><div class="small text-nowrap text-muted">' + row.Notes + '</div>'; row.Cause = row.Cause + '<br/><div class="small text-muted">' + row.Notes + '</div>';
} }
row.Frames = '<a href="?view=frames&amp;eid=' + eid + '">' + row.Frames + '</a>'; row.Frames = '<a href="?view=frames&amp;eid=' + eid + '">' + row.Frames + '</a>';
row.AlarmFrames = '<a href="?view=frames&amp;eid=' + eid + '">' + row.AlarmFrames + '</a>'; row.AlarmFrames = '<a href="?view=frames&amp;eid=' + eid + '">' + row.AlarmFrames + '</a>';

View File

@ -57,7 +57,7 @@ function getFrame(monId, time, last_Frame) {
var events_for_monitor = events_by_monitor_id[monId]; var events_for_monitor = events_by_monitor_id[monId];
if ( !events_for_monitor ) { if ( !events_for_monitor ) {
console.log("No events for monitor " + monId); //console.log("No events for monitor " + monId);
return; return;
} }
@ -648,8 +648,11 @@ function setSpeed(speed_index) {
} }
function setLive(value) { function setLive(value) {
// When we submit the context etc goes away but we may still be trying to update
// So kill the timer.
clearInterval(timerObj);
liveMode = value; liveMode = value;
var form = $j('#montagereview_form')[0]; var form = document.getElementById('montagereview_form');
form.elements['live'].value = value; form.elements['live'].value = value;
form.submit(); form.submit();
return false; return false;
@ -985,6 +988,19 @@ function initPage() {
}); });
}); });
if ( !liveMode ) {
canvas = document.getElementById('timeline');
canvas.addEventListener('mousemove', mmove, false);
canvas.addEventListener('touchmove', tmove, false);
canvas.addEventListener('mousedown', mdown, false);
canvas.addEventListener('mouseup', mup, false);
canvas.addEventListener('mouseout', mout, false);
ctx = canvas.getContext('2d');
drawGraph();
}
for ( var i = 0, len = monitorPtr.length; i < len; i += 1 ) { for ( var i = 0, len = monitorPtr.length; i < len; i += 1 ) {
var monId = monitorPtr[i]; var monId = monitorPtr[i];
if ( !monId ) continue; if ( !monId ) continue;
@ -1006,18 +1022,6 @@ function initPage() {
} }
} // end foreach monitor } // end foreach monitor
if ( !liveMode ) {
canvas = document.getElementById('timeline');
canvas.addEventListener('mousemove', mmove, false);
canvas.addEventListener('touchmove', tmove, false);
canvas.addEventListener('mousedown', mdown, false);
canvas.addEventListener('mouseup', mup, false);
canvas.addEventListener('mouseout', mout, false);
ctx = canvas.getContext('2d');
drawGraph();
}
setSpeed(speedIndex); setSpeed(speedIndex);
//setFit(fitMode); // will redraw //setFit(fitMode); // will redraw
//setLive(liveMode); // will redraw //setLive(liveMode); // will redraw

View File

@ -239,6 +239,6 @@ echo "];\n";
var cWidth; // save canvas width var cWidth; // save canvas width
var cHeight; // save canvas height var cHeight; // save canvas height
var canvas; // global canvas definition so we don't have to keep looking it up var canvas; // global canvas definition so we don't have to keep looking it up
var ctx; var ctx = null;
var underSlider; // use this to hold what is hidden by the slider var underSlider; // use this to hold what is hidden by the slider
var underSliderX; // Where the above was taken from (left side, Y is zero) var underSliderX; // Where the above was taken from (left side, Y is zero)

View File

@ -453,7 +453,7 @@ foreach ( $tabs as $name=>$value ) {
switch ( $name ) { switch ( $name ) {
case 'general' : case 'general' :
{ {
if (!$monitor->Id()) { if (!$monitor->Id() and count($monitors)) {
$monitor_ids = array(); $monitor_ids = array();
foreach ($monitors as $m) { $monitor_ids[] = $m['Id']; } foreach ($monitors as $m) { $monitor_ids[] = $m['Id']; }
$available_monitor_ids = array_diff(range(min($monitor_ids),max($monitor_ids)), $monitor_ids); $available_monitor_ids = array_diff(range(min($monitor_ids),max($monitor_ids)), $monitor_ids);
@ -470,7 +470,7 @@ if (count($available_monitor_ids)) {
</tr> </tr>
<?php <?php
} # end if ! $monitor->Id() } # end if ! $monitor->Id() and count($monitors)
?> ?>
<tr class="Name"> <tr class="Name">
<td class="text-right pr-3"><?php echo translate('Name') ?></td> <td class="text-right pr-3"><?php echo translate('Name') ?></td>