Merge branch 'master' of github.com:/ZoneMinder/zoneminder
commit
a70b329ce3
|
@ -1,10 +1,10 @@
|
|||
# Configuration for probot-stale - https://github.com/probot/stale
|
||||
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 60
|
||||
daysUntilStale: 180
|
||||
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 7
|
||||
daysUntilClose: 30
|
||||
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
|
|
|
@ -357,6 +357,7 @@ EOF
|
|||
%{_bindir}/zmtelemetry.pl
|
||||
%{_bindir}/zmx10.pl
|
||||
%{_bindir}/zmonvif-probe.pl
|
||||
%{_bindir}/zmonvif-trigger.pl
|
||||
%{_bindir}/zmstats.pl
|
||||
%{_bindir}/zmrecover.pl
|
||||
|
||||
|
|
|
@ -21,8 +21,8 @@ override_dh_auto_configure:
|
|||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DZM_CONFIG_DIR="/etc/zm" \
|
||||
-DZM_CONFIG_SUBDIR="/etc/zm/conf.d" \
|
||||
-DZM_RUNDIR="/var/run/zm" \
|
||||
-DZM_SOCKDIR="/var/run/zm" \
|
||||
-DZM_RUNDIR="/run/zm" \
|
||||
-DZM_SOCKDIR="/run/zm" \
|
||||
-DZM_TMPDIR="/tmp/zm" \
|
||||
-DZM_CGIDIR="/usr/lib/zoneminder/cgi-bin" \
|
||||
-DZM_CACHEDIR="/var/cache/zoneminder/cache" \
|
||||
|
|
|
@ -21,8 +21,8 @@ override_dh_auto_configure:
|
|||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DZM_CONFIG_DIR="/etc/zm" \
|
||||
-DZM_CONFIG_SUBDIR="/etc/zm/conf.d" \
|
||||
-DZM_RUNDIR="/var/run/zm" \
|
||||
-DZM_SOCKDIR="/var/run/zm" \
|
||||
-DZM_RUNDIR="/run/zm" \
|
||||
-DZM_SOCKDIR="/run/zm" \
|
||||
-DZM_TMPDIR="/tmp/zm" \
|
||||
-DZM_CGIDIR="/usr/lib/zoneminder/cgi-bin" \
|
||||
-DZM_CACHEDIR="/var/cache/zoneminder/cache" \
|
||||
|
|
|
@ -3,10 +3,157 @@ Debian
|
|||
|
||||
.. contents::
|
||||
|
||||
Easy Way: Debian Buster
|
||||
------------------------
|
||||
|
||||
This procedure will guide you through the installation of ZoneMinder on Debian 10 (Buster).
|
||||
|
||||
**Step 1:** Make sure your system is up to date
|
||||
|
||||
Open a console and use ``su`` command to become root.
|
||||
|
||||
::
|
||||
|
||||
apt update
|
||||
apt upgrade
|
||||
|
||||
|
||||
**Step 2:** Setup Sudo (optional but recommended)
|
||||
|
||||
By default Debian does not come with sudo, so you have to install it and configure it manually.
|
||||
This step is optional but recommended and the following instructions assume that you have setup sudo.
|
||||
If you prefer to setup ZoneMinder as root, do it at your own risk and adapt the following instructions accordingly.
|
||||
|
||||
::
|
||||
|
||||
apt install sudo
|
||||
usermod -a -G sudo <username>
|
||||
exit
|
||||
|
||||
Now your terminal session is back under your normal user. You can check that
|
||||
you are now part of the sudo group with the command ``groups``, "sudo" should
|
||||
appear in the list. If not, run ``newgrp sudo`` and check again with ``groups``.
|
||||
|
||||
|
||||
**Step 3:** Install Apache and MySQL
|
||||
|
||||
These are not dependencies for the ZoneMinder package as they could be
|
||||
installed elsewhere. If they are not installed yet in your system, you have to
|
||||
trigger their installation manually.
|
||||
|
||||
::
|
||||
|
||||
sudo apt install apache2 mysql-server
|
||||
|
||||
**Step 4:** Add ZoneMinder's Package repository to your apt sources
|
||||
|
||||
ZoneMinder's Debian packages are not included in Debian's official package
|
||||
repositories. To be able to install ZoneMinder with APT, you have to edit the
|
||||
list of apt sources and add ZoneMinder's repository.
|
||||
|
||||
::
|
||||
|
||||
sudo nano /etc/apt/sources.list
|
||||
|
||||
Add the following to the bottom of the file
|
||||
|
||||
::
|
||||
|
||||
# ZoneMinder repository
|
||||
deb https://zmrepo.zoneminder.com/debian/release-1.34 stretch/
|
||||
|
||||
CTRL+o and <Enter> to save
|
||||
CTRL+x to exit
|
||||
|
||||
Because ZoneMinder's package repository provides a secure connection through HTTPS, apt must be enabled for HTTPS.
|
||||
::
|
||||
|
||||
sudo apt install apt-transport-https
|
||||
|
||||
Finally, download the GPG key for ZoneMinder's repository:
|
||||
::
|
||||
|
||||
wget -O - https://zmrepo.zoneminder.com/debian/archive-keyring.gpg | sudo apt-key add -
|
||||
|
||||
|
||||
**Step 5:** Install ZoneMinder
|
||||
|
||||
::
|
||||
|
||||
sudo apt update
|
||||
sudo apt install zoneminder
|
||||
|
||||
**Step 6:** Read the Readme
|
||||
|
||||
The rest of the install process is covered in the README.Debian, so feel free to have
|
||||
a read.
|
||||
|
||||
::
|
||||
|
||||
zcat /usr/share/doc/zoneminder/README.Debian.gz
|
||||
|
||||
|
||||
**Step 7:** Enable ZoneMinder service
|
||||
|
||||
::
|
||||
|
||||
sudo systemctl enable zoneminder.service
|
||||
|
||||
**Step 8:** Configure Apache
|
||||
|
||||
The following commands will setup the default /zm virtual directory and configure
|
||||
required apache modules.
|
||||
|
||||
::
|
||||
|
||||
sudo a2enconf zoneminder
|
||||
sudo a2enmod rewrite
|
||||
sudo a2enmod cgi # this is done automatically when installing the package. Redo this command manually only for troubleshooting.
|
||||
|
||||
|
||||
**Step 9:** Edit Timezone in PHP
|
||||
|
||||
Automated way:
|
||||
::
|
||||
|
||||
sudo sed -i "s/;date.timezone =/date.timezone = $(sed 's/\//\\\//' /etc/timezone)/g" /etc/php/7.0/apache2/php.ini
|
||||
|
||||
Manual way
|
||||
::
|
||||
|
||||
sudo nano /etc/php/7.0/apache2/php.ini
|
||||
|
||||
Search for [Date] (Ctrl + w then type Date and press Enter) and change
|
||||
date.timezone for your time zone. Don't forget to remove the ; from in front
|
||||
of date.timezone.
|
||||
|
||||
::
|
||||
|
||||
[Date]
|
||||
; Defines the default timezone used by the date functions
|
||||
; http://php.net/date.timezone
|
||||
date.timezone = America/New_York
|
||||
|
||||
CTRL+o then [Enter] to save
|
||||
|
||||
CTRL+x to exit
|
||||
|
||||
|
||||
**Step 10:** Start ZoneMinder
|
||||
|
||||
Reload Apache to enable your changes and then start ZoneMinder.
|
||||
|
||||
::
|
||||
|
||||
sudo systemctl reload apache2
|
||||
sudo systemctl start zoneminder
|
||||
|
||||
You are now ready to go with ZoneMinder. Open a browser and type either ``localhost/zm`` one the local machine or ``{IP-OF-ZM-SERVER}/zm`` if you connect from a remote computer.
|
||||
|
||||
Easy Way: Debian Stretch
|
||||
------------------------
|
||||
|
||||
This procedure will guide you through the installation of ZoneMinder on Debian 9 (Stretch). This section has been tested with ZoneMinder 1.32.3 on Debian 9.8.
|
||||
This procedure will guide you through the installation of ZoneMinder on Debian 9 (Stretch). This section has been tested with ZoneMinder 1.34 on Debian 9.8.
|
||||
|
||||
**Step 1:** Make sure your system is up to date
|
||||
|
||||
|
@ -52,7 +199,7 @@ Add the following to the bottom of the file
|
|||
::
|
||||
|
||||
# ZoneMinder repository
|
||||
deb https://zmrepo.zoneminder.com/debian/release stretch/
|
||||
deb https://zmrepo.zoneminder.com/debian/release-1.34 stretch/
|
||||
|
||||
CTRL+o and <Enter> to save
|
||||
CTRL+x to exit
|
||||
|
@ -275,7 +422,6 @@ CTRL+x to exit
|
|||
|
||||
**Step 12:** Please check the configuration
|
||||
|
||||
Zoneminder 1.32.x
|
||||
1. Check path of ZM_PATH in '/etc/zm/conf.d/zmcustom.conf' is ZM_PATH_ZMS=/zm/cgi-bin/nph-zms
|
||||
::
|
||||
cat /etc/zm/conf.d/zmcustom.conf
|
||||
|
@ -309,8 +455,8 @@ Reload Apache to enable your changes and then start ZoneMinder.
|
|||
::
|
||||
|
||||
{
|
||||
"version": "1.29.0",
|
||||
"apiversion": "1.29.0.1"
|
||||
"version": "1.34.0",
|
||||
"apiversion": "1.34.0.1"
|
||||
}
|
||||
|
||||
**Congratulations** Your installation is complete
|
||||
|
|
|
@ -53,7 +53,7 @@ ZoneMinder releases are now being hosted at RPM Fusion. New users should navigat
|
|||
|
||||
Note that RHEL/CentOS 7 users should use yum instead of dnf.
|
||||
|
||||
Once ZoneMinder has been installed, it is critically important that you read the README file under /usr/share/doc/zoneminder. ZoneMinder will not run without completing the steps outlined in the README.
|
||||
Once ZoneMinder has been installed, it is critically important that you read the README file under /usr/share/doc/zoneminder-common. ZoneMinder will not run without completing the steps outlined in the README.
|
||||
|
||||
How to Install Nightly Development Builds
|
||||
-----------------------------------------
|
||||
|
@ -191,7 +191,7 @@ Now clone the ZoneMinder git repository from your home folder:
|
|||
git clone https://github.com/ZoneMinder/zoneminder
|
||||
cd zoneminder
|
||||
|
||||
This will create a sub-folder called ZoneMinder, which will contain the latest development source code.
|
||||
This will create a sub-folder called zoneminder, which will contain the latest development source code.
|
||||
|
||||
If you have previsouly cloned the ZoneMinder git repo and wish to update it to the most recent, then issue these commands instead:
|
||||
|
||||
|
|
|
@ -32,12 +32,10 @@ BULK_FRAME_INTERVAL - Traditionally ZoneMinder writes an entry into the Frames d
|
|||
|
||||
EVENT_CLOSE_MODE - When a monitor is running in a continuous recording mode (Record or Mocord) events are usually closed after a fixed period of time (the section length). However in Mocord mode it is possible that motion detection may occur near the end of a section. This option controls what happens when an alarm occurs in Mocord mode. The 'time' setting means that the event will be closed at the end of the section regardless of alarm activity. The 'idle' setting means that the event will be closed at the end of the section if there is no alarm activity occurring at the time otherwise it will be closed once the alarm is over meaning the event may end up being longer than the normal section length. The 'alarm' setting means that if an alarm occurs during the event, the event will be closed once the alarm is over regardless of when this occurs. This has the effect of limiting the number of alarms to one per event and the events will be shorter than the section length if an alarm has occurred.
|
||||
|
||||
CREATE_ANALYSIS_IMAGES - By default during an alarm ZoneMinder records both the raw captured image and one that has been analysed and had areas where motion was detected outlined. This can be very useful during zone configuration or in analysing why events occurred. However it also incurs some overhead and in a stable system may no longer be necessary. This parameter allows you to switch the generation of these images off.
|
||||
|
||||
WEIGHTED_ALARM_CENTRES - ZoneMinder will always calculate the centre point of an alarm in a zone to give some indication of where on the screen it is. This can be used by the experimental motion tracking feature or your own custom extensions. In the alarmed or filtered pixels mode this is a simple midpoint between the extents of the detected pxiesl. However in the blob method this can instead be calculated using weighted pixel locations to give more accurate positioning for irregularly shaped blobs. This method, while more precise is also slower and so is turned off by default.
|
||||
|
||||
EVENT_IMAGE_DIGITS - As event images are captured they are stored to the filesystem with a numerical index. By default this index has three digits so the numbers start 001, 002 etc. This works works for most scenarios as events with more than 999 frames are rarely captured. However if you have extremely long events and use external applications then you may wish to increase this to ensure correct sorting of images in listings etc. Warning, increasing this value on a live system may render existing events unviewable as the event will have been saved with the previous scheme. Decreasing this value should have no ill effects.
|
||||
|
||||
DEFAULT_ASPECT_RATIO - When specifying the dimensions of monitors you can click a checkbox to ensure that the width stays in the correct ratio to the height, or vice versa. This setting allows you to indicate what the ratio of these settings should be. This should be specified in the format <width value>:<height value> and the default of 4:3 normally be acceptable but 11:9 is another common setting. If the checkbox is not clicked when specifying monitor dimensions this setting has no effect.
|
||||
|
||||
USER_SELF_EDIT - Ordinarily only users with system edit privilege are able to change users details. Switching this option on allows ordinary users to change their passwords and their language settings
|
||||
USER_SELF_EDIT - Ordinarily only users with system edit privilege are able to change users details. Switching this option on allows ordinary users to change their passwords and their language settings
|
||||
|
|
|
@ -252,7 +252,7 @@ our @options = (
|
|||
authentication which passes an independently authentication
|
||||
'remote' user via http. In this case ZoneMinder would use the
|
||||
supplied user without additional authentication provided such a
|
||||
user is configured ion ZoneMinder.
|
||||
user is configured in ZoneMinder.
|
||||
`,
|
||||
requires => [ { name=>'ZM_OPT_USE_AUTH', value=>'yes' } ],
|
||||
type => {
|
||||
|
@ -2635,22 +2635,6 @@ our @options = (
|
|||
type => $types{boolean},
|
||||
category => 'hidden',
|
||||
},
|
||||
{
|
||||
name => 'ZM_CREATE_ANALYSIS_IMAGES',
|
||||
default => 'yes',
|
||||
description => 'Create analysed alarm images with motion outlined',
|
||||
help => q`
|
||||
By default during an alarm ZoneMinder records both the raw
|
||||
captured image and one that has been analysed and had areas
|
||||
where motion was detected outlined. This can be very useful
|
||||
during zone configuration or in analysing why events occurred.
|
||||
However it also incurs some overhead and in a stable system may
|
||||
no longer be necessary. This parameter allows you to switch the
|
||||
generation of these images off.
|
||||
`,
|
||||
type => $types{boolean},
|
||||
category => 'config',
|
||||
},
|
||||
{
|
||||
name => 'ZM_WEIGHTED_ALARM_CENTRES',
|
||||
default => 'no',
|
||||
|
|
|
@ -45,7 +45,7 @@ use ZoneMinder::Config qw(:all);
|
|||
use Time::HiRes qw( usleep );
|
||||
use URI;
|
||||
|
||||
our $ADDRESS;
|
||||
our $uri;
|
||||
|
||||
sub open {
|
||||
my $self = shift;
|
||||
|
@ -55,8 +55,7 @@ sub open {
|
|||
# Has no scheme at the beginning, so won't parse as a URI
|
||||
$self->{Monitor}->{ControlAddress} = 'http://'.$self->{Monitor}->{ControlAddress};
|
||||
}
|
||||
my $uri = URI->new($self->{Monitor}->{ControlAddress});
|
||||
$ADDRESS = $uri->scheme.'://'.$uri->authority().$uri->path().($uri->port()?':'.$uri->port():'');
|
||||
$uri = URI->new($self->{Monitor}->{ControlAddress});
|
||||
|
||||
use LWP::UserAgent;
|
||||
$self->{ua} = LWP::UserAgent->new;
|
||||
|
@ -65,14 +64,21 @@ sub open {
|
|||
$self->{state} = 'closed';
|
||||
|
||||
my ( $username, $password, $host ) = ( $uri->authority() =~ /^([^:]+):([^@]*)@(.+)$/ );
|
||||
|
||||
$uri->userinfo(undef);
|
||||
|
||||
my $realm = $self->{Monitor}->{ControlDevice};
|
||||
|
||||
$self->{ua}->credentials($ADDRESS, $realm, $username, $password);
|
||||
$self->{ua}->credentials($uri->host_port(), $realm, $username, $password);
|
||||
my $url = '/axis-cgi/param.cgi?action=list&group=Properties.PTZ.PTZ';
|
||||
|
||||
# test auth
|
||||
my $res = $self->{ua}->get($ADDRESS.'/cgi/ptdc.cgi');
|
||||
my $res = $self->{ua}->get($uri->canonical().$url);
|
||||
|
||||
if ( $res->is_success ) {
|
||||
if ( $res->content() ne "Properties.PTZ.PTZ=yes\n" ) {
|
||||
Warning('Response suggests that camera doesn\'t support PTZ. Content:('.$res->content().')');
|
||||
}
|
||||
$self->{state} = 'open';
|
||||
return;
|
||||
}
|
||||
|
@ -85,23 +91,18 @@ sub open {
|
|||
}
|
||||
|
||||
if ( $$headers{'www-authenticate'} ) {
|
||||
Debug('Authenticating');
|
||||
my ( $auth, $tokens ) = $$headers{'www-authenticate'} =~ /^(\w+)\s+(.*)$/;
|
||||
if ( $tokens =~ /\w+="([^"]+)"/i ) {
|
||||
if ( $realm ne $1 ) {
|
||||
$realm = $1;
|
||||
Debug("Changing REALM to $realm");
|
||||
$self->{ua}->credentials($host, $realm, $username, $password);
|
||||
$res = $self->{ua}->get($ADDRESS);
|
||||
$self->{ua}->credentials($uri->host_port(), $realm, $username, $password);
|
||||
$res = $self->{ua}->get($uri->canonical().$url);
|
||||
if ( $res->is_success() ) {
|
||||
Info("Auth succeeded after setting realm to $realm. You can set this value in the Control Device field to speed up connections and remove these log entries.");
|
||||
$self->{state} = 'open';
|
||||
return;
|
||||
}
|
||||
Error('Authentication still failed after updating REALM'.$res->status_line);
|
||||
$headers = $res->headers();
|
||||
foreach my $k ( keys %$headers ) {
|
||||
Debug("Initial Header $k => $$headers{$k}");
|
||||
} # end foreach
|
||||
Error('Authentication still failed after updating REALM status: '.$res->status_line);
|
||||
} else {
|
||||
Error('Authentication failed, not a REALM problem');
|
||||
}
|
||||
|
@ -111,6 +112,8 @@ sub open {
|
|||
} else {
|
||||
Debug('No headers line');
|
||||
} # end if headers
|
||||
} else {
|
||||
Warning('Failed to open '.$uri->canonical().$url.' status: '.$res->status_line());
|
||||
} # end if $res->status_line() eq '401 Unauthorized'
|
||||
} # end sub open
|
||||
|
||||
|
@ -120,11 +123,11 @@ sub sendCmd {
|
|||
|
||||
$self->printMsg($cmd, 'Tx');
|
||||
|
||||
my $url = $ADDRESS.$cmd;
|
||||
my $url = $uri->canonical().$cmd;
|
||||
my $res = $self->{ua}->get($url);
|
||||
|
||||
if ( $res->is_success ) {
|
||||
Debug('sndCmd command: ' . $url . ' content: '.$res->content);
|
||||
Debug('sndCmd command: '.$url.' content: '.$res->content);
|
||||
return !undef;
|
||||
}
|
||||
|
||||
|
|
|
@ -143,10 +143,10 @@ sub PutCmd {
|
|||
} else {
|
||||
Info('Missing username and password in Control Address.');
|
||||
}
|
||||
Fatal($res->status_line);
|
||||
Error($res->status_line);
|
||||
}
|
||||
} else {
|
||||
Fatal($res->status_line);
|
||||
Error($res->status_line);
|
||||
}
|
||||
} # end unless res->is_success
|
||||
} # end sub putCmd
|
||||
|
|
|
@ -133,6 +133,7 @@ sub sendCmd {
|
|||
my $result = undef;
|
||||
|
||||
$self->printMsg($cmd, 'Tx');
|
||||
$self->printMsg($msg, 'Tx');
|
||||
|
||||
my $server_endpoint = 'http://'.$address.':'.$port.'/'.$cmd;
|
||||
my $req = HTTP::Request->new(POST => $server_endpoint);
|
||||
|
@ -147,6 +148,7 @@ sub sendCmd {
|
|||
|
||||
if ( $res->is_success ) {
|
||||
$result = !undef;
|
||||
Debug("Result: " . $res->content());
|
||||
} else {
|
||||
Error("After sending PTZ command, camera returned the following error:'".$res->status_line()."'\nMSG:$msg\nResponse:".$res->content);
|
||||
}
|
||||
|
@ -208,12 +210,56 @@ sub reset {
|
|||
$self->sendCmd($cmd, $msg, $content_type);
|
||||
}
|
||||
|
||||
sub moveMap {
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $x = $self->getParam($params,'xcoord');
|
||||
my $y = $self->getParam($params,'ycoord');
|
||||
Debug("Move map to $x x $y");
|
||||
|
||||
my $cmd = 'onvif/PTZ';
|
||||
my $msg ='<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">' . ((%identity) ? authentificationHeader($identity{username}, $identity{password}) : '') . '<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<AbsoluteMove xmlns="http://www.onvif.org/ver20/ptz/wsdl">
|
||||
<ProfileToken>' . $profileToken . '</ProfileToken>
|
||||
<Position><PanTilt x="'.$x.'" y="'.$y.'" xmlns="http://www.onvif.org/ver10/schema"/></Position>
|
||||
<Speed><Zoom x="1" xmlns="http://www.onvif.org/ver10/schema"/></Speed>
|
||||
</AbsoluteMove></s:Body></s:Envelope>';
|
||||
my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/ContinuousMove"';
|
||||
$self->sendCmd($cmd, $msg, $content_type);
|
||||
}
|
||||
|
||||
sub moveRel {
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $x = $self->getParam($params,'xcoord');
|
||||
my $speed = $self->getParam($params,'speed');
|
||||
my $y = $self->getParam($params,'ycoord');
|
||||
Debug("Move rel to $x x $y");
|
||||
|
||||
my $cmd = 'onvif/PTZ';
|
||||
my $msg ='<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">' . ((%identity) ? authentificationHeader($identity{username}, $identity{password}) : '') . '<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<RelativeMove xmlns="http://www.onvif.org/ver20/ptz/wsdl">
|
||||
<ProfileToken>' . $profileToken . '</ProfileToken>
|
||||
<Translation>
|
||||
<PanTilt x="'.$x.'" y="'.$y.'" xmlns="http://www.onvif.org/ver10/schema" space="http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace"/>
|
||||
<Zoom x="1"/>
|
||||
</Translation>
|
||||
<!--<Speed><Zoom x="'.$speed.'" xmlns="http://www.onvif.org/ver10/schema" space="http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace"/></Speed>_-->
|
||||
</RelativeMove></s:Body></s:Envelope>';
|
||||
my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/ContinuousMove"';
|
||||
$self->sendCmd($cmd, $msg, $content_type);
|
||||
}
|
||||
|
||||
#Up Arrow
|
||||
sub moveConUp {
|
||||
Debug('Move Up');
|
||||
my $self = shift;
|
||||
my $cmd = 'onvif/PTZ';
|
||||
my $msg ='<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">' . ((%identity) ? authentificationHeader($identity{username}, $identity{password}) : '') . '<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><ContinuousMove xmlns="http://www.onvif.org/ver20/ptz/wsdl"><ProfileToken>' . $profileToken . '</ProfileToken><Velocity><PanTilt x="0" y="0.5" xmlns="http://www.onvif.org/ver10/schema"/></Velocity></ContinuousMove></s:Body></s:Envelope>';
|
||||
my $msg ='<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">' . ((%identity) ? authentificationHeader($identity{username}, $identity{password}) : '') . '<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<ContinuousMove xmlns="http://www.onvif.org/ver20/ptz/wsdl">
|
||||
<ProfileToken>' . $profileToken . '</ProfileToken>
|
||||
<Velocity><PanTilt x="0" y="0.5" xmlns="http://www.onvif.org/ver10/schema"/></Velocity>
|
||||
</ContinuousMove></s:Body></s:Envelope>';
|
||||
my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/ContinuousMove"';
|
||||
$self->sendCmd($cmd, $msg, $content_type);
|
||||
$self->autoStop($self->{Monitor}->{AutoStopTimeout});
|
||||
|
|
|
@ -146,15 +146,15 @@ sub zmDbGetMonitors {
|
|||
|
||||
if ( $function ) {
|
||||
if ( $function == DB_MON_CAPT ) {
|
||||
$sql .= " where Function >= 'Monitor'";
|
||||
$sql .= " where `Function` >= 'Monitor'";
|
||||
} elsif ( $function == DB_MON_ACTIVE ) {
|
||||
$sql .= " where Function > 'Monitor'";
|
||||
$sql .= " where `Function` > 'Monitor'";
|
||||
} elsif ( $function == DB_MON_MOTION ) {
|
||||
$sql .= " where Function = 'Modect' or Function = 'Mocord'";
|
||||
$sql .= " where `Function` = 'Modect' or Function = 'Mocord'";
|
||||
} elsif ( $function == DB_MON_RECORD ) {
|
||||
$sql .= " where Function = 'Record' or Function = 'Mocord'";
|
||||
$sql .= " where `Function` = 'Record' or Function = 'Mocord'";
|
||||
} elsif ( $function == DB_MON_PASSIVE ) {
|
||||
$sql .= " where Function = 'Nodect'";
|
||||
$sql .= " where `Function` = 'Nodect'";
|
||||
}
|
||||
}
|
||||
my $sth = $dbh->prepare_cached( $sql );
|
||||
|
|
|
@ -368,7 +368,7 @@ sub delete {
|
|||
return;
|
||||
}
|
||||
if ( !($event->Storage()->Path() and -e $event->Storage()->Path()) ) {
|
||||
Warning('Not deleting event because storage path doesn\'t exist');
|
||||
Warning('Not deleting event because storage path ('.$event->Storage()->Path().') doesn\'t exist');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -345,7 +345,7 @@ sub createEvent {
|
|||
." to ".$frame->{capturePath}.": $!"
|
||||
);
|
||||
setFileOwner( $frame->{capturePath} );
|
||||
if ( 0 && $Config{ZM_CREATE_ANALYSIS_IMAGES} ) {
|
||||
if ( $event->{SaveJPEGs} > 1 ) {
|
||||
$frame->{analysePath} = sprintf(
|
||||
"%s/%0".$Config{ZM_EVENT_IMAGE_DIGITS}
|
||||
."d-analyse.jpg"
|
||||
|
|
|
@ -162,6 +162,8 @@ our $mem_data = {
|
|||
imagesize => { type=>'uint32', seq=>$mem_seq++ },
|
||||
epadding1 => { type=>'uint32', seq=>$mem_seq++ },
|
||||
startup_time => { type=>'time_t64', seq=>$mem_seq++ },
|
||||
zmc_heartbeat_time => { type=>'time_t64', seq=>$mem_seq++ },
|
||||
zma_heartbeat_time => { type=>'time_t64', seq=>$mem_seq++ },
|
||||
last_write_time => { type=>'time_t64', seq=>$mem_seq++ },
|
||||
last_read_time => { type=>'time_t64', seq=>$mem_seq++ },
|
||||
control_state => { type=>'uint8[256]', seq=>$mem_seq++ },
|
||||
|
|
|
@ -49,9 +49,9 @@ my %options;
|
|||
GetOptions(
|
||||
'id=i' =>\$id,
|
||||
'command=s' =>\$options{command},
|
||||
'xcoord=i' =>\$options{xcoord},
|
||||
'ycoord=i' =>\$options{ycoord},
|
||||
'speed=i' =>\$options{speed},
|
||||
'xcoord=f' =>\$options{xcoord},
|
||||
'ycoord=f' =>\$options{ycoord},
|
||||
'speed=f' =>\$options{speed},
|
||||
'step=i' =>\$options{step},
|
||||
'panspeed=i' =>\$options{panspeed},
|
||||
'tiltspeed=i' =>\$options{tiltspeed},
|
||||
|
|
|
@ -160,7 +160,7 @@ if ( !$server_up ) {
|
|||
use ZoneMinder::Server qw(CpuLoad);
|
||||
if ( ! defined $dbh->do(q{UPDATE Servers SET Status=?,TotalMem=?,FreeMem=?,TotalSwap=?,FreeSwap=? WHERE Id=?}, undef,
|
||||
'NotRunning', &totalmem, &freemem, &totalswap, &freeswap, $Config{ZM_SERVER_ID} ) ) {
|
||||
Error("Failed Updating status of Server record to Not RUnning for Id=$Config{ZM_SERVER_ID}" . $dbh->errstr());
|
||||
Error('Failed Updating status of Server record to Not Running for Id='.$Config{ZM_SERVER_ID}.': '.$dbh->errstr());
|
||||
}
|
||||
}
|
||||
# Server is not up. Some commands can still be handled
|
||||
|
@ -173,7 +173,7 @@ if ( !$server_up ) {
|
|||
print("stopped\n");
|
||||
exit();
|
||||
} elsif ( $command ne 'startup' ) {
|
||||
print('Unable to connect to server using socket at ' . SOCK_FILE . "\n");
|
||||
print('Unable to connect to server using socket at '.SOCK_FILE."\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
@ -189,10 +189,10 @@ if ( !$server_up ) {
|
|||
|
||||
socket(CLIENT, PF_UNIX, SOCK_STREAM, 0) or Fatal("Can't open socket: $!");
|
||||
my $attempts = 0;
|
||||
while( !connect(CLIENT, $saddr) ) {
|
||||
while ( !connect(CLIENT, $saddr) ) {
|
||||
$attempts++;
|
||||
Debug('Waiting for zmdc.pl server process at '.SOCK_FILE.", attempt $attempts");
|
||||
Fatal("Can't connect: $!") if $attempts > MAX_CONNECT_DELAY;
|
||||
Debug('Waiting for zmdc.pl server process at '.SOCK_FILE.', attempt '.$attempts);
|
||||
Fatal('Can\'t connect to zmdc.pl server process at '.SOCK_FILE.': '.$!) if $attempts > MAX_CONNECT_DELAY;
|
||||
usleep(200000);
|
||||
} # end while
|
||||
} elsif ( defined($cpid) ) {
|
||||
|
@ -255,13 +255,13 @@ sub run {
|
|||
close($PID);
|
||||
} else {
|
||||
# Log not initialized at this point so use die instead
|
||||
die "Can't open pid file at ".ZM_PID."\n";
|
||||
die 'Can\'t open pid file at '.ZM_PID."\n";
|
||||
}
|
||||
|
||||
my $fd = 0;
|
||||
|
||||
# This also closes dbh and CLIENT and SERVER
|
||||
while( $fd < POSIX::sysconf(&POSIX::_SC_OPEN_MAX) ) {
|
||||
while ( $fd < POSIX::sysconf(&POSIX::_SC_OPEN_MAX) ) {
|
||||
POSIX::close($fd++);
|
||||
}
|
||||
|
||||
|
@ -301,13 +301,14 @@ sub run {
|
|||
my $timeout = 1;
|
||||
my $secs_count = 0;
|
||||
|
||||
while( !$zm_terminate ) {
|
||||
while ( !$zm_terminate ) {
|
||||
|
||||
if ( $Config{ZM_SERVER_ID} ) {
|
||||
if ( ! ( $secs_count % 60 ) ) {
|
||||
while ( (!$zm_terminate) and !($dbh and $dbh->ping()) ) {
|
||||
Warning("Not connected to db ($dbh)".($dbh?' ping('.$dbh->ping().')':''). ($DBI::errstr?" errstr($DBI::errstr)":'').' Reconnecting');
|
||||
$dbh = zmDbConnect();
|
||||
sleep 10 if !$dbh;
|
||||
}
|
||||
last if $zm_terminate;
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ $SIG{__DIE__} = \&handler;
|
|||
# =========================================================================
|
||||
# Debug
|
||||
|
||||
use Data::Hexdumper qw(hexdump);
|
||||
#use Data::Hexdumper qw(hexdump);
|
||||
#use Devel::Peek;
|
||||
|
||||
sub dump_mapped {
|
||||
|
@ -116,12 +116,12 @@ sub dump_mapped {
|
|||
printf("Mapped at %x\n", $monitor->{MMapAddr});
|
||||
# Dump($mmap);
|
||||
if ( $mmap && $$mmap ) {
|
||||
print hexdump(
|
||||
data => $$mmap, # what to dump
|
||||
output_format => ' %4a : %S %S %S %S %S %S %S %S : %d',
|
||||
# start_position => 336, # start at this offset ...
|
||||
end_position => 400 # ... and end at this offset
|
||||
);
|
||||
#print hexdump(
|
||||
#data => $$mmap, # what to dump
|
||||
#output_format => ' %4a : %S %S %S %S %S %S %S %S : %d',
|
||||
## start_position => 336, # start at this offset ...
|
||||
#end_position => 400 # ... and end at this offset
|
||||
#);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,49 @@ while( 1 ) {
|
|||
$dbh->do('DELETE FROM Events_Week WHERE StartTime < DATE_SUB(NOW(), INTERVAL 1 week)') or Error($dbh->errstr());
|
||||
$dbh->do('DELETE FROM Events_Month WHERE StartTime < DATE_SUB(NOW(), INTERVAL 1 month)') or Error($dbh->errstr());
|
||||
|
||||
# Prune the Logs table if required
|
||||
if ( $Config{ZM_LOG_DATABASE_LIMIT} ) {
|
||||
if ( $Config{ZM_LOG_DATABASE_LIMIT} =~ /^\d+$/ ) {
|
||||
# Number of rows
|
||||
my $selectLogRowCountSql = 'SELECT count(*) AS `Rows` FROM `Logs`';
|
||||
my $selectLogRowCountSth = $dbh->prepare_cached( $selectLogRowCountSql )
|
||||
or Fatal("Can't prepare '$selectLogRowCountSql': ".$dbh->errstr());
|
||||
my $res = $selectLogRowCountSth->execute()
|
||||
or Fatal("Can't execute: ".$selectLogRowCountSth->errstr());
|
||||
my $row = $selectLogRowCountSth->fetchrow_hashref();
|
||||
my $logRows = $row->{Rows};
|
||||
if ( $logRows > $Config{ZM_LOG_DATABASE_LIMIT} ) {
|
||||
my $deleteLogByRowsSql = 'DELETE low_priority FROM `Logs` ORDER BY `TimeKey` ASC LIMIT ?';
|
||||
my $deleteLogByRowsSth = $dbh->prepare_cached( $deleteLogByRowsSql )
|
||||
or Fatal("Can't prepare '$deleteLogByRowsSql': ".$dbh->errstr());
|
||||
$res = $deleteLogByRowsSth->execute( $logRows - $Config{ZM_LOG_DATABASE_LIMIT} )
|
||||
or Fatal("Can't execute: ".$deleteLogByRowsSth->errstr());
|
||||
if ( $deleteLogByRowsSth->rows() ) {
|
||||
Debug('Deleted '.$deleteLogByRowsSth->rows().' log table entries by count');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
# Time of record
|
||||
|
||||
# 7 days is invalid. We need to remove the s
|
||||
if ( $Config{ZM_LOG_DATABASE_LIMIT} =~ /^(.*)s$/ ) {
|
||||
$Config{ZM_LOG_DATABASE_LIMIT} = $1;
|
||||
}
|
||||
my $deleted_rows;
|
||||
do {
|
||||
my $deleteLogByTimeSql =
|
||||
'DELETE FROM `Logs`
|
||||
WHERE `TimeKey` < unix_timestamp(now() - interval '.$Config{ZM_LOG_DATABASE_LIMIT}.') LIMIT 100';
|
||||
my $deleteLogByTimeSth = $dbh->prepare_cached( $deleteLogByTimeSql )
|
||||
or Fatal("Can't prepare '$deleteLogByTimeSql': ".$dbh->errstr());
|
||||
my $res = $deleteLogByTimeSth->execute()
|
||||
or Fatal("Can't execute: ".$deleteLogByTimeSth->errstr());
|
||||
$deleted_rows = $deleteLogByTimeSth->rows();
|
||||
Debug("Deleted $deleted_rows log table entries by time");
|
||||
} while ( $deleted_rows );
|
||||
}
|
||||
} # end if ZM_LOG_DATABASE_LIMIT
|
||||
|
||||
sleep($Config{ZM_STATS_UPDATE_INTERVAL});
|
||||
} # end while (1)
|
||||
|
||||
|
|
|
@ -119,7 +119,6 @@ if ( !$monitor->{CanMoveMap} ) {
|
|||
}
|
||||
}
|
||||
|
||||
Debug("Found monitor for id '$monitor'");
|
||||
exit(-1) if !zmMemVerify($monitor);
|
||||
|
||||
sub Suspend {
|
||||
|
|
|
@ -48,11 +48,12 @@ Camera::Camera(
|
|||
record_audio(p_record_audio),
|
||||
bytes(0)
|
||||
{
|
||||
linesize = width * colours;
|
||||
pixels = width * height;
|
||||
imagesize = pixels * colours;
|
||||
imagesize = height * linesize;
|
||||
|
||||
Debug(2,"New camera id: %d width: %d height: %d colours: %d subpixelorder: %d capture: %d",
|
||||
monitor_id, width, height, colours, subpixelorder, capture);
|
||||
Debug(2, "New camera id: %d width: %d line size: %d height: %d colours: %d subpixelorder: %d capture: %d",
|
||||
monitor_id, width, linesize, height, colours, subpixelorder, capture);
|
||||
|
||||
monitor = NULL;
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ protected:
|
|||
Monitor * monitor; // Null on instantiation, set as soon as possible.
|
||||
SourceType type;
|
||||
unsigned int width;
|
||||
unsigned int linesize;
|
||||
unsigned int height;
|
||||
unsigned int colours;
|
||||
unsigned int subpixelorder;
|
||||
|
@ -70,6 +71,7 @@ public:
|
|||
bool IscURL() const { return type == CURL_SRC; }
|
||||
bool IsVNC() const { return type == VNC_SRC; }
|
||||
unsigned int Width() const { return width; }
|
||||
unsigned int LineSize() const { return linesize; }
|
||||
unsigned int Height() const { return height; }
|
||||
unsigned int Colours() const { return colours; }
|
||||
unsigned int SubpixelOrder() const { return subpixelorder; }
|
||||
|
|
|
@ -63,31 +63,31 @@ static enum AVPixelFormat get_hw_format(
|
|||
}
|
||||
#if !LIBAVUTIL_VERSION_CHECK(56, 22, 0, 14, 0)
|
||||
static enum AVPixelFormat find_fmt_by_hw_type(const enum AVHWDeviceType type) {
|
||||
enum AVPixelFormat fmt;
|
||||
switch (type) {
|
||||
enum AVPixelFormat fmt;
|
||||
switch (type) {
|
||||
case AV_HWDEVICE_TYPE_VAAPI:
|
||||
fmt = AV_PIX_FMT_VAAPI;
|
||||
break;
|
||||
fmt = AV_PIX_FMT_VAAPI;
|
||||
break;
|
||||
case AV_HWDEVICE_TYPE_DXVA2:
|
||||
fmt = AV_PIX_FMT_DXVA2_VLD;
|
||||
break;
|
||||
fmt = AV_PIX_FMT_DXVA2_VLD;
|
||||
break;
|
||||
case AV_HWDEVICE_TYPE_D3D11VA:
|
||||
fmt = AV_PIX_FMT_D3D11;
|
||||
break;
|
||||
fmt = AV_PIX_FMT_D3D11;
|
||||
break;
|
||||
case AV_HWDEVICE_TYPE_VDPAU:
|
||||
fmt = AV_PIX_FMT_VDPAU;
|
||||
break;
|
||||
fmt = AV_PIX_FMT_VDPAU;
|
||||
break;
|
||||
case AV_HWDEVICE_TYPE_CUDA:
|
||||
fmt = AV_PIX_FMT_CUDA;
|
||||
break;
|
||||
fmt = AV_PIX_FMT_CUDA;
|
||||
break;
|
||||
case AV_HWDEVICE_TYPE_VIDEOTOOLBOX:
|
||||
fmt = AV_PIX_FMT_VIDEOTOOLBOX;
|
||||
break;
|
||||
fmt = AV_PIX_FMT_VIDEOTOOLBOX;
|
||||
break;
|
||||
default:
|
||||
fmt = AV_PIX_FMT_NONE;
|
||||
break;
|
||||
}
|
||||
return fmt;
|
||||
fmt = AV_PIX_FMT_NONE;
|
||||
break;
|
||||
}
|
||||
return fmt;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@ -174,6 +174,20 @@ FfmpegCamera::FfmpegCamera(
|
|||
} else {
|
||||
Panic("Unexpected colours: %d", colours);
|
||||
}
|
||||
|
||||
// sws_scale needs 32bit aligned width and an extra 16 bytes padding, so recalculate imagesize, which was width*height*bytes_per_pixel
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
alignment = 32;
|
||||
imagesize = av_image_get_buffer_size(imagePixFormat, width, height, alignment);
|
||||
// av_image_get_linesize isn't aligned, so we have to do that.
|
||||
linesize = FFALIGN(av_image_get_linesize(imagePixFormat, width, 0), alignment);
|
||||
#else
|
||||
alignment = 1;
|
||||
linesize = FFALIGN(av_image_get_linesize(imagePixFormat, width, 0), alignment);
|
||||
imagesize = avpicture_get_size(imagePixFormat, width, height);
|
||||
#endif
|
||||
|
||||
Debug(1, "ffmpegcamera: width %d height %d linesize %d colours %d imagesize %d", width, height, linesize, colours, imagesize);
|
||||
} // FfmpegCamera::FfmpegCamera
|
||||
|
||||
FfmpegCamera::~FfmpegCamera() {
|
||||
|
@ -194,12 +208,12 @@ void FfmpegCamera::Terminate() {
|
|||
|
||||
int FfmpegCamera::PrimeCapture() {
|
||||
if ( mCanCapture ) {
|
||||
Info("Priming capture from %s, Closing", mPath.c_str());
|
||||
Debug(1, "Priming capture from %s, Closing", mPath.c_str());
|
||||
Close();
|
||||
}
|
||||
mVideoStreamId = -1;
|
||||
mAudioStreamId = -1;
|
||||
Info("Priming capture from %s", mPath.c_str());
|
||||
Debug(1, "Priming capture from %s", mPath.c_str());
|
||||
|
||||
return OpenFfmpeg();
|
||||
}
|
||||
|
@ -608,16 +622,6 @@ int FfmpegCamera::OpenFfmpeg() {
|
|||
mFrame->width = width;
|
||||
mFrame->height = height;
|
||||
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
int pSize = av_image_get_buffer_size(imagePixFormat, width, height, 1);
|
||||
#else
|
||||
int pSize = avpicture_get_size(imagePixFormat, width, height);
|
||||
#endif
|
||||
|
||||
if ( (unsigned int)pSize != imagesize ) {
|
||||
Error("Image size mismatch. Required: %d Available: %d", pSize, imagesize);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if HAVE_LIBSWSCALE
|
||||
if ( !sws_isSupportedInput(mVideoCodecContext->pix_fmt) ) {
|
||||
|
@ -1089,11 +1093,18 @@ int FfmpegCamera::transfer_to_image(
|
|||
int size = av_image_fill_arrays(
|
||||
output_frame->data, output_frame->linesize,
|
||||
directbuffer, imagePixFormat, width, height,
|
||||
(AV_PIX_FMT_RGBA == imagePixFormat ? 32 : 1)
|
||||
alignment
|
||||
);
|
||||
if ( size < 0 ) {
|
||||
Error("Problem setting up data pointers into image %s",
|
||||
av_make_error_string(size).c_str());
|
||||
} else {
|
||||
Debug(4, "av_image_fill_array %dx%d alignment: %d = %d, buffer size is %d",
|
||||
width, height, alignment, size, image.Size());
|
||||
}
|
||||
Debug(1, "ffmpegcamera: width %d height %d linesize %d colours %d imagesize %d", width, height, linesize, colours, imagesize);
|
||||
if ( linesize != (unsigned int)output_frame->linesize[0] ) {
|
||||
Error("Bad linesize expected %d got %d", linesize, output_frame->linesize[0]);
|
||||
}
|
||||
#else
|
||||
avpicture_fill((AVPicture *)output_frame, directbuffer,
|
||||
|
|
|
@ -45,6 +45,8 @@ class FfmpegCamera : public Camera {
|
|||
std::string hwaccel_device;
|
||||
|
||||
int frameCount;
|
||||
|
||||
int alignment; /* ffmpeg wants line sizes to be 32bit aligned. Especially 4.3+ */
|
||||
|
||||
#if HAVE_LIBAVFORMAT
|
||||
AVFormatContext *mFormatContext;
|
||||
|
|
298
src/zm_image.cpp
298
src/zm_image.cpp
|
@ -108,6 +108,7 @@ Image::Image() {
|
|||
if ( !initialised )
|
||||
Initialise();
|
||||
width = 0;
|
||||
linesize = 0;
|
||||
height = 0;
|
||||
pixels = 0;
|
||||
colours = 0;
|
||||
|
@ -125,6 +126,7 @@ Image::Image( const char *filename ) {
|
|||
if ( !initialised )
|
||||
Initialise();
|
||||
width = 0;
|
||||
linesize = 0;
|
||||
height = 0;
|
||||
pixels = 0;
|
||||
colours = 0;
|
||||
|
@ -139,15 +141,42 @@ Image::Image( const char *filename ) {
|
|||
update_function_pointers();
|
||||
}
|
||||
|
||||
Image::Image( int p_width, int p_height, int p_colours, int p_subpixelorder, uint8_t *p_buffer ) {
|
||||
Image::Image( int p_width, int p_height, int p_colours, int p_subpixelorder, uint8_t *p_buffer, unsigned int p_padding) {
|
||||
if ( !initialised )
|
||||
Initialise();
|
||||
width = p_width;
|
||||
height = p_height;
|
||||
pixels = width*height;
|
||||
colours = p_colours;
|
||||
linesize = p_width * p_colours;
|
||||
padding = p_padding;
|
||||
subpixelorder = p_subpixelorder;
|
||||
size = pixels*colours;
|
||||
size = linesize*height + padding;
|
||||
buffer = 0;
|
||||
holdbuffer = 0;
|
||||
if ( p_buffer ) {
|
||||
allocation = size;
|
||||
buffertype = ZM_BUFTYPE_DONTFREE;
|
||||
buffer = p_buffer;
|
||||
} else {
|
||||
AllocImgBuffer(size);
|
||||
}
|
||||
text[0] = '\0';
|
||||
|
||||
update_function_pointers();
|
||||
}
|
||||
|
||||
Image::Image( int p_width, int p_linesize, int p_height, int p_colours, int p_subpixelorder, uint8_t *p_buffer, unsigned int p_padding) {
|
||||
if ( !initialised )
|
||||
Initialise();
|
||||
width = p_width;
|
||||
linesize = p_linesize;
|
||||
height = p_height;
|
||||
pixels = width*height;
|
||||
colours = p_colours;
|
||||
padding = p_padding;
|
||||
subpixelorder = p_subpixelorder;
|
||||
size = linesize*height + padding;
|
||||
buffer = 0;
|
||||
holdbuffer = 0;
|
||||
if ( p_buffer ) {
|
||||
|
@ -167,20 +196,21 @@ Image::Image(const AVFrame *frame) {
|
|||
text[0] = '\0';
|
||||
|
||||
width = frame->width;
|
||||
linesize = frame->linesize[0];
|
||||
height = frame->height;
|
||||
pixels = width*height;
|
||||
|
||||
colours = ZM_COLOUR_RGB32;
|
||||
subpixelorder = ZM_SUBPIX_ORDER_RGBA;
|
||||
|
||||
size = pixels*colours;
|
||||
size = linesize * height;
|
||||
buffer = 0;
|
||||
holdbuffer = 0;
|
||||
AllocImgBuffer(size);
|
||||
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
av_image_fill_arrays(dest_frame->data, dest_frame->linesize,
|
||||
buffer, AV_PIX_FMT_RGBA, width, height, 1);
|
||||
buffer, AV_PIX_FMT_RGBA, width, height, 32);
|
||||
#else
|
||||
avpicture_fill( (AVPicture *)dest_frame, buffer,
|
||||
AV_PIX_FMT_RGBA, width, height);
|
||||
|
@ -212,6 +242,7 @@ Image::Image(const Image &p_image) {
|
|||
if ( !initialised )
|
||||
Initialise();
|
||||
width = p_image.width;
|
||||
linesize = p_image.linesize;
|
||||
height = p_image.height;
|
||||
pixels = p_image.pixels;
|
||||
colours = p_image.colours;
|
||||
|
@ -268,26 +299,26 @@ void Image::Deinitialise() {
|
|||
void Image::Initialise() {
|
||||
/* Assign the blend pointer to function */
|
||||
if ( config.fast_image_blends ) {
|
||||
if ( config.cpu_extensions && sseversion >= 20 ) {
|
||||
if ( config.cpu_extensions && sse_version >= 20 ) {
|
||||
fptr_blend = &sse2_fastblend; /* SSE2 fast blend */
|
||||
Debug(4,"Blend: Using SSE2 fast blend function");
|
||||
Debug(4, "Blend: Using SSE2 fast blend function");
|
||||
} else if ( config.cpu_extensions && neonversion >= 1 ) {
|
||||
#if defined(__aarch64__)
|
||||
fptr_blend = &neon64_armv8_fastblend; /* ARM Neon (AArch64) fast blend */
|
||||
Debug(4,"Blend: Using ARM Neon (AArch64) fast blend function");
|
||||
Debug(4, "Blend: Using ARM Neon (AArch64) fast blend function");
|
||||
#elif defined(__arm__)
|
||||
fptr_blend = &neon32_armv7_fastblend; /* ARM Neon (AArch32) fast blend */
|
||||
Debug(4,"Blend: Using ARM Neon (AArch32) fast blend function");
|
||||
Debug(4, "Blend: Using ARM Neon (AArch32) fast blend function");
|
||||
#else
|
||||
Panic("Bug: Non ARM platform but neon present");
|
||||
#endif
|
||||
} else {
|
||||
fptr_blend = &std_fastblend; /* standard fast blend */
|
||||
Debug(4,"Blend: Using fast blend function");
|
||||
Debug(4, "Blend: Using fast blend function");
|
||||
}
|
||||
} else {
|
||||
fptr_blend = &std_blend;
|
||||
Debug(4,"Blend: Using standard blend function");
|
||||
Debug(4, "Blend: Using standard blend function");
|
||||
}
|
||||
|
||||
__attribute__((aligned(64))) uint8_t blend1[128] = {
|
||||
|
@ -325,22 +356,22 @@ void Image::Initialise() {
|
|||
|
||||
/* Assign the delta functions */
|
||||
if ( config.cpu_extensions ) {
|
||||
if ( sseversion >= 35 ) {
|
||||
if ( sse_version >= 35 ) {
|
||||
/* SSSE3 available */
|
||||
fptr_delta8_rgba = &ssse3_delta8_rgba;
|
||||
fptr_delta8_bgra = &ssse3_delta8_bgra;
|
||||
fptr_delta8_argb = &ssse3_delta8_argb;
|
||||
fptr_delta8_abgr = &ssse3_delta8_abgr;
|
||||
fptr_delta8_gray8 = &sse2_delta8_gray8;
|
||||
Debug(4,"Delta: Using SSSE3 delta functions");
|
||||
} else if ( sseversion >= 20 ) {
|
||||
Debug(4, "Delta: Using SSSE3 delta functions");
|
||||
} else if ( sse_version >= 20 ) {
|
||||
/* SSE2 available */
|
||||
fptr_delta8_rgba = &sse2_delta8_rgba;
|
||||
fptr_delta8_bgra = &sse2_delta8_bgra;
|
||||
fptr_delta8_argb = &sse2_delta8_argb;
|
||||
fptr_delta8_abgr = &sse2_delta8_abgr;
|
||||
fptr_delta8_gray8 = &sse2_delta8_gray8;
|
||||
Debug(4,"Delta: Using SSE2 delta functions");
|
||||
Debug(4, "Delta: Using SSE2 delta functions");
|
||||
} else if ( neonversion >= 1 ) {
|
||||
/* ARM Neon available */
|
||||
#if defined(__aarch64__)
|
||||
|
@ -349,14 +380,14 @@ void Image::Initialise() {
|
|||
fptr_delta8_argb = &neon64_armv8_delta8_argb;
|
||||
fptr_delta8_abgr = &neon64_armv8_delta8_abgr;
|
||||
fptr_delta8_gray8 = &neon64_armv8_delta8_gray8;
|
||||
Debug(4,"Delta: Using ARM Neon (AArch64) delta functions");
|
||||
Debug(4, "Delta: Using ARM Neon (AArch64) delta functions");
|
||||
#elif defined(__arm__)
|
||||
fptr_delta8_rgba = &neon32_armv7_delta8_rgba;
|
||||
fptr_delta8_bgra = &neon32_armv7_delta8_bgra;
|
||||
fptr_delta8_argb = &neon32_armv7_delta8_argb;
|
||||
fptr_delta8_abgr = &neon32_armv7_delta8_abgr;
|
||||
fptr_delta8_gray8 = &neon32_armv7_delta8_gray8;
|
||||
Debug(4,"Delta: Using ARM Neon (AArch32) delta functions");
|
||||
Debug(4, "Delta: Using ARM Neon (AArch32) delta functions");
|
||||
#else
|
||||
Panic("Bug: Non ARM platform but neon present");
|
||||
#endif
|
||||
|
@ -433,68 +464,28 @@ void Image::Initialise() {
|
|||
fptr_deinterlace_4field_argb = &std_deinterlace_4field_argb;
|
||||
fptr_deinterlace_4field_abgr = &std_deinterlace_4field_abgr;
|
||||
fptr_deinterlace_4field_gray8 = &std_deinterlace_4field_gray8;
|
||||
Debug(4,"Deinterlace: Using standard functions");
|
||||
Debug(4, "Deinterlace: Using standard functions");
|
||||
|
||||
#if defined(__i386__) && !defined(__x86_64__)
|
||||
/* Use SSE2 aligned memory copy? */
|
||||
if ( config.cpu_extensions && sseversion >= 20 ) {
|
||||
if ( config.cpu_extensions && sse_version >= 20 ) {
|
||||
fptr_imgbufcpy = &sse2_aligned_memcpy;
|
||||
Debug(4,"Image buffer copy: Using SSE2 aligned memcpy");
|
||||
Debug(4, "Image buffer copy: Using SSE2 aligned memcpy");
|
||||
} else {
|
||||
fptr_imgbufcpy = &memcpy;
|
||||
Debug(4,"Image buffer copy: Using standard memcpy");
|
||||
Debug(4, "Image buffer copy: Using standard memcpy");
|
||||
}
|
||||
#else
|
||||
fptr_imgbufcpy = &memcpy;
|
||||
Debug(4,"Image buffer copy: Using standard memcpy");
|
||||
Debug(4, "Image buffer copy: Using standard memcpy");
|
||||
#endif
|
||||
|
||||
/* Code below relocated from zm_local_camera */
|
||||
Debug( 3, "Setting up static colour tables" );
|
||||
|
||||
y_table = y_table_global;
|
||||
uv_table = uv_table_global;
|
||||
r_v_table = r_v_table_global;
|
||||
g_v_table = g_v_table_global;
|
||||
g_u_table = g_u_table_global;
|
||||
b_u_table = b_u_table_global;
|
||||
/*
|
||||
y_table = new unsigned char[256];
|
||||
for ( int i = 0; i <= 255; i++ )
|
||||
{
|
||||
unsigned char c = i;
|
||||
if ( c <= 16 )
|
||||
y_table[c] = 0;
|
||||
else if ( c >= 235 )
|
||||
y_table[c] = 255;
|
||||
else
|
||||
y_table[c] = (255*(c-16))/219;
|
||||
}
|
||||
|
||||
uv_table = new signed char[256];
|
||||
for ( int i = 0; i <= 255; i++ )
|
||||
{
|
||||
unsigned char c = i;
|
||||
if ( c <= 16 )
|
||||
uv_table[c] = -127;
|
||||
else if ( c >= 240 )
|
||||
uv_table[c] = 127;
|
||||
else
|
||||
uv_table[c] = (127*(c-128))/112;
|
||||
}
|
||||
|
||||
r_v_table = new short[255];
|
||||
g_v_table = new short[255];
|
||||
g_u_table = new short[255];
|
||||
b_u_table = new short[255];
|
||||
for ( int i = 0; i < 255; i++ )
|
||||
{
|
||||
r_v_table[i] = (1402*(i-128))/1000;
|
||||
g_u_table[i] = (344*(i-128))/1000;
|
||||
g_v_table[i] = (714*(i-128))/1000;
|
||||
b_u_table[i] = (1772*(i-128))/1000;
|
||||
}
|
||||
*/
|
||||
|
||||
initialised = true;
|
||||
}
|
||||
|
@ -503,7 +494,7 @@ void Image::Initialise() {
|
|||
uint8_t* Image::WriteBuffer(const unsigned int p_width, const unsigned int p_height, const unsigned int p_colours, const unsigned int p_subpixelorder) {
|
||||
|
||||
if ( p_colours != ZM_COLOUR_GRAY8 && p_colours != ZM_COLOUR_RGB24 && p_colours != ZM_COLOUR_RGB32 ) {
|
||||
Error("WriteBuffer called with unexpected colours: %d",p_colours);
|
||||
Error("WriteBuffer called with unexpected colours: %d", p_colours);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -536,20 +527,30 @@ uint8_t* Image::WriteBuffer(const unsigned int p_width, const unsigned int p_hei
|
|||
subpixelorder = p_subpixelorder;
|
||||
pixels = height*width;
|
||||
size = newsize;
|
||||
} // end if need to re-alloc buffer
|
||||
} // end if need to re-alloc buffer
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/* Assign an existing buffer to the image instead of copying from a source buffer. The goal is to reduce the amount of memory copying and increase efficiency and buffer reusing. */
|
||||
void Image::AssignDirect( const unsigned int p_width, const unsigned int p_height, const unsigned int p_colours, const unsigned int p_subpixelorder, uint8_t *new_buffer, const size_t buffer_size, const int p_buffertype) {
|
||||
/* Assign an existing buffer to the image instead of copying from a source buffer.
|
||||
The goal is to reduce the amount of memory copying and increase efficiency and buffer reusing.
|
||||
*/
|
||||
void Image::AssignDirect(
|
||||
const unsigned int p_width,
|
||||
const unsigned int p_height,
|
||||
const unsigned int p_colours,
|
||||
const unsigned int p_subpixelorder,
|
||||
uint8_t *new_buffer,
|
||||
const size_t buffer_size,
|
||||
const int p_buffertype) {
|
||||
|
||||
if ( new_buffer == NULL ) {
|
||||
Error("Attempt to directly assign buffer from a NULL pointer");
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !p_height || !p_width ) {
|
||||
Error("Attempt to directly assign buffer with invalid width or height: %d %d",p_width,p_height);
|
||||
Error("Attempt to directly assign buffer with invalid width or height: %d %d", p_width, p_height);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -561,7 +562,8 @@ void Image::AssignDirect( const unsigned int p_width, const unsigned int p_heigh
|
|||
unsigned int new_buffer_size = ((p_width*p_height)*p_colours);
|
||||
|
||||
if ( buffer_size < new_buffer_size ) {
|
||||
Error("Attempt to directly assign buffer from an undersized buffer of size: %zu, needed %dx%d*%d colours = %zu",buffer_size, p_width, p_height, p_colours, new_buffer_size );
|
||||
Error("Attempt to directly assign buffer from an undersized buffer of size: %zu, needed %dx%d*%d colours = %zu",
|
||||
buffer_size, p_width, p_height, p_colours, new_buffer_size);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -573,6 +575,7 @@ void Image::AssignDirect( const unsigned int p_width, const unsigned int p_heigh
|
|||
width = p_width;
|
||||
height = p_height;
|
||||
colours = p_colours;
|
||||
linesize = width*colours;
|
||||
subpixelorder = p_subpixelorder;
|
||||
pixels = height*width;
|
||||
size = new_buffer_size; // was pixels*colours, but we already calculated it above as new_buffer_size
|
||||
|
@ -591,6 +594,7 @@ void Image::AssignDirect( const unsigned int p_width, const unsigned int p_heigh
|
|||
width = p_width;
|
||||
height = p_height;
|
||||
colours = p_colours;
|
||||
linesize = width*colours;
|
||||
subpixelorder = p_subpixelorder;
|
||||
pixels = height*width;
|
||||
size = new_buffer_size; // was pixels*colours, but we already calculated it above as new_buffer_size
|
||||
|
@ -599,7 +603,6 @@ void Image::AssignDirect( const unsigned int p_width, const unsigned int p_heigh
|
|||
buffertype = p_buffertype;
|
||||
buffer = new_buffer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Image::Assign(const unsigned int p_width, const unsigned int p_height, const unsigned int p_colours, const unsigned int p_subpixelorder, const uint8_t* new_buffer, const size_t buffer_size) {
|
||||
|
@ -611,17 +614,17 @@ void Image::Assign(const unsigned int p_width, const unsigned int p_height, cons
|
|||
}
|
||||
|
||||
if ( buffer_size < new_size ) {
|
||||
Error("Attempt to assign buffer from an undersized buffer of size: %zu",buffer_size);
|
||||
Error("Attempt to assign buffer from an undersized buffer of size: %zu", buffer_size);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !p_height || !p_width ) {
|
||||
Error("Attempt to assign buffer with invalid width or height: %d %d",p_width,p_height);
|
||||
Error("Attempt to assign buffer with invalid width or height: %d %d", p_width, p_height);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( p_colours != ZM_COLOUR_GRAY8 && p_colours != ZM_COLOUR_RGB24 && p_colours != ZM_COLOUR_RGB32 ) {
|
||||
Error("Attempt to assign buffer with unexpected colours per pixel: %d",p_colours);
|
||||
Error("Attempt to assign buffer with unexpected colours per pixel: %d", p_colours);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -647,9 +650,9 @@ void Image::Assign(const unsigned int p_width, const unsigned int p_height, cons
|
|||
size = new_size;
|
||||
}
|
||||
|
||||
if(new_buffer != buffer)
|
||||
if ( new_buffer != buffer )
|
||||
(*fptr_imgbufcpy)(buffer, new_buffer, size);
|
||||
|
||||
Debug(1,"Assign");
|
||||
}
|
||||
|
||||
void Image::Assign( const Image &image ) {
|
||||
|
@ -688,7 +691,7 @@ void Image::Assign( const Image &image ) {
|
|||
size = new_size;
|
||||
}
|
||||
|
||||
if(image.buffer != buffer)
|
||||
if ( image.buffer != buffer )
|
||||
(*fptr_imgbufcpy)(buffer, image.buffer, size);
|
||||
}
|
||||
|
||||
|
@ -698,7 +701,7 @@ Image *Image::HighlightEdges( Rgb colour, unsigned int p_colours, unsigned int p
|
|||
}
|
||||
|
||||
/* Convert the colour's RGBA subpixel order into the image's subpixel order */
|
||||
colour = rgb_convert(colour,p_subpixelorder);
|
||||
colour = rgb_convert(colour, p_subpixelorder);
|
||||
|
||||
/* Create a new image of the target format */
|
||||
Image *high_image = new Image( width, height, p_colours, p_subpixelorder );
|
||||
|
@ -707,84 +710,67 @@ Image *Image::HighlightEdges( Rgb colour, unsigned int p_colours, unsigned int p
|
|||
/* Set image to all black */
|
||||
high_image->Clear();
|
||||
|
||||
unsigned int lo_x = limits?limits->Lo().X():0;
|
||||
unsigned int lo_y = limits?limits->Lo().Y():0;
|
||||
unsigned int hi_x = limits?limits->Hi().X():width-1;
|
||||
unsigned int hi_y = limits?limits->Hi().Y():height-1;
|
||||
unsigned int lo_x = limits ? limits->Lo().X() : 0;
|
||||
unsigned int lo_y = limits ? limits->Lo().Y() : 0;
|
||||
unsigned int hi_x = limits ? limits->Hi().X() : width-1;
|
||||
unsigned int hi_y = limits ? limits->Hi().Y() : height-1;
|
||||
|
||||
if ( p_colours == ZM_COLOUR_GRAY8 )
|
||||
{
|
||||
for ( unsigned int y = lo_y; y <= hi_y; y++ )
|
||||
{
|
||||
const uint8_t* p = buffer + (y * width) + lo_x;
|
||||
uint8_t* phigh = high_buff + (y * width) + lo_x;
|
||||
for ( unsigned int x = lo_x; x <= hi_x; x++, p++, phigh++ )
|
||||
{
|
||||
if ( p_colours == ZM_COLOUR_GRAY8 ) {
|
||||
for ( unsigned int y = lo_y; y <= hi_y; y++ ) {
|
||||
const uint8_t* p = buffer + (y * linesize) + lo_x;
|
||||
uint8_t* phigh = high_buff + (y * linesize) + lo_x;
|
||||
for ( unsigned int x = lo_x; x <= hi_x; x++, p++, phigh++ ) {
|
||||
bool edge = false;
|
||||
if ( *p )
|
||||
{
|
||||
if ( *p ) {
|
||||
if ( !edge && x > 0 && !*(p-1) ) edge = true;
|
||||
if ( !edge && x < (width-1) && !*(p+1) ) edge = true;
|
||||
if ( !edge && y > 0 && !*(p-width) ) edge = true;
|
||||
if ( !edge && y < (height-1) && !*(p+width) ) edge = true;
|
||||
}
|
||||
if ( edge )
|
||||
{
|
||||
if ( edge ) {
|
||||
*phigh = colour;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( p_colours == ZM_COLOUR_RGB24 )
|
||||
{
|
||||
for ( unsigned int y = lo_y; y <= hi_y; y++ )
|
||||
{
|
||||
const uint8_t* p = buffer + (y * width) + lo_x;
|
||||
uint8_t* phigh = high_buff + (((y * width) + lo_x) * 3);
|
||||
for ( unsigned int x = lo_x; x <= hi_x; x++, p++, phigh += 3 )
|
||||
{
|
||||
} else if ( p_colours == ZM_COLOUR_RGB24 ) {
|
||||
for ( unsigned int y = lo_y; y <= hi_y; y++ ) {
|
||||
const uint8_t* p = buffer + (y * linesize) + lo_x;
|
||||
uint8_t* phigh = high_buff + (((y * linesize) + lo_x) * 3);
|
||||
for ( unsigned int x = lo_x; x <= hi_x; x++, p++, phigh += 3 ) {
|
||||
bool edge = false;
|
||||
if ( *p )
|
||||
{
|
||||
if ( *p ) {
|
||||
if ( !edge && x > 0 && !*(p-1) ) edge = true;
|
||||
if ( !edge && x < (width-1) && !*(p+1) ) edge = true;
|
||||
if ( !edge && y > 0 && !*(p-width) ) edge = true;
|
||||
if ( !edge && y < (height-1) && !*(p+width) ) edge = true;
|
||||
}
|
||||
if ( edge )
|
||||
{
|
||||
if ( edge ) {
|
||||
RED_PTR_RGBA(phigh) = RED_VAL_RGBA(colour);
|
||||
GREEN_PTR_RGBA(phigh) = GREEN_VAL_RGBA(colour);
|
||||
BLUE_PTR_RGBA(phigh) = BLUE_VAL_RGBA(colour);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( p_colours == ZM_COLOUR_RGB32 )
|
||||
{
|
||||
for ( unsigned int y = lo_y; y <= hi_y; y++ )
|
||||
{
|
||||
const uint8_t* p = buffer + (y * width) + lo_x;
|
||||
Rgb* phigh = (Rgb*)(high_buff + (((y * width) + lo_x) * 4));
|
||||
for ( unsigned int x = lo_x; x <= hi_x; x++, p++, phigh++ )
|
||||
{
|
||||
} else if ( p_colours == ZM_COLOUR_RGB32 ) {
|
||||
for ( unsigned int y = lo_y; y <= hi_y; y++ ) {
|
||||
const uint8_t* p = buffer + (y * linesize) + lo_x;
|
||||
Rgb* phigh = (Rgb*)(high_buff + (((y * linesize) + lo_x) * 4));
|
||||
for ( unsigned int x = lo_x; x <= hi_x; x++, p++, phigh++ ) {
|
||||
bool edge = false;
|
||||
if ( *p )
|
||||
{
|
||||
if ( *p ) {
|
||||
if ( !edge && x > 0 && !*(p-1) ) edge = true;
|
||||
if ( !edge && x < (width-1) && !*(p+1) ) edge = true;
|
||||
if ( !edge && y > 0 && !*(p-width) ) edge = true;
|
||||
if ( !edge && y < (height-1) && !*(p+width) ) edge = true;
|
||||
}
|
||||
if ( edge )
|
||||
{
|
||||
if ( edge ) {
|
||||
*phigh = colour;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return( high_image );
|
||||
return high_image;
|
||||
}
|
||||
|
||||
bool Image::ReadRaw( const char *filename ) {
|
||||
|
@ -881,10 +867,10 @@ bool Image::ReadJpeg(const char *filename, unsigned int p_colours, unsigned int
|
|||
new_height = cinfo->image_height;
|
||||
|
||||
if ( width != new_width || height != new_height ) {
|
||||
Debug(9,"Image dimensions differ. Old: %ux%u New: %ux%u",width,height,new_width,new_height);
|
||||
Debug(9, "Image dimensions differ. Old: %ux%u New: %ux%u", width, height, new_width, new_height);
|
||||
}
|
||||
|
||||
switch(p_colours) {
|
||||
switch (p_colours) {
|
||||
case ZM_COLOUR_GRAY8:
|
||||
{
|
||||
cinfo->out_color_space = JCS_GRAYSCALE;
|
||||
|
@ -986,13 +972,14 @@ bool Image::WriteJpeg(const char *filename, struct timeval timestamp) const {
|
|||
bool Image::WriteJpeg(const char *filename, int quality_override, struct timeval timestamp) const {
|
||||
return Image::WriteJpeg(filename, quality_override, timestamp, false);
|
||||
}
|
||||
|
||||
bool Image::WriteJpeg(const char *filename, int quality_override, struct timeval timestamp, bool on_blocking_abort) const {
|
||||
if ( config.colour_jpeg_files && (colours == ZM_COLOUR_GRAY8) ) {
|
||||
Image temp_image(*this);
|
||||
temp_image.Colourise(ZM_COLOUR_RGB24, ZM_SUBPIX_ORDER_RGB);
|
||||
return temp_image.WriteJpeg(filename, quality_override, timestamp, on_blocking_abort);
|
||||
}
|
||||
int quality = quality_override?quality_override:config.jpeg_file_quality;
|
||||
int quality = quality_override ? quality_override : config.jpeg_file_quality;
|
||||
|
||||
struct jpeg_compress_struct *cinfo = writejpg_ccinfo[quality];
|
||||
FILE *outfile = NULL;
|
||||
|
@ -1046,7 +1033,7 @@ bool Image::WriteJpeg(const char *filename, int quality_override, struct timeval
|
|||
cinfo->image_width = width; /* image width and height, in pixels */
|
||||
cinfo->image_height = height;
|
||||
|
||||
switch (colours) {
|
||||
switch ( colours ) {
|
||||
case ZM_COLOUR_GRAY8:
|
||||
cinfo->input_components = 1;
|
||||
cinfo->in_color_space = JCS_GRAYSCALE;
|
||||
|
@ -1131,7 +1118,8 @@ cinfo->out_color_space = JCS_RGB;
|
|||
}
|
||||
|
||||
JSAMPROW row_pointer; /* pointer to a single row */
|
||||
int row_stride = cinfo->image_width * colours; /* physical row width in buffer */
|
||||
int row_stride = linesize;
|
||||
//cinfo->image_width * colours; /* physical row width in buffer */
|
||||
while ( cinfo->next_scanline < cinfo->image_height ) {
|
||||
row_pointer = &buffer[cinfo->next_scanline * row_stride];
|
||||
jpeg_write_scanlines(cinfo, &row_pointer, 1);
|
||||
|
@ -1271,7 +1259,7 @@ bool Image::EncodeJpeg(JOCTET *outbuffer, int *outbuffer_size, int quality_overr
|
|||
return temp_image.EncodeJpeg(outbuffer, outbuffer_size, quality_override);
|
||||
}
|
||||
|
||||
int quality = quality_override?quality_override:config.jpeg_stream_quality;
|
||||
int quality = quality_override ? quality_override : config.jpeg_stream_quality;
|
||||
|
||||
struct jpeg_compress_struct *cinfo = encodejpg_ccinfo[quality];
|
||||
|
||||
|
@ -1344,7 +1332,7 @@ cinfo->out_color_space = JCS_RGB;
|
|||
jpeg_start_compress(cinfo, TRUE);
|
||||
|
||||
JSAMPROW row_pointer; /* pointer to a single row */
|
||||
int row_stride = cinfo->image_width * colours; /* physical row width in buffer */
|
||||
int row_stride = linesize; /* physical row width in buffer */
|
||||
while ( cinfo->next_scanline < cinfo->image_height ) {
|
||||
row_pointer = &buffer[cinfo->next_scanline * row_stride];
|
||||
jpeg_write_scanlines(cinfo, &row_pointer, 1);
|
||||
|
@ -1385,11 +1373,12 @@ bool Image::Crop( unsigned int lo_x, unsigned int lo_y, unsigned int hi_x, unsig
|
|||
unsigned int new_height = (hi_y-lo_y)+1;
|
||||
|
||||
if ( lo_x > hi_x || lo_y > hi_y ) {
|
||||
Error( "Invalid or reversed crop region %d,%d -> %d,%d", lo_x, lo_y, hi_x, hi_y );
|
||||
return( false );
|
||||
Error("Invalid or reversed crop region %d,%d -> %d,%d", lo_x, lo_y, hi_x, hi_y);
|
||||
return false;
|
||||
}
|
||||
if ( hi_x > (width-1) || ( hi_y > (height-1) ) ) {
|
||||
Error( "Attempting to crop outside image, %d,%d -> %d,%d not in %d,%d", lo_x, lo_y, hi_x, hi_y, width-1, height-1 );
|
||||
Error("Attempting to crop outside image, %d,%d -> %d,%d not in %d,%d",
|
||||
lo_x, lo_y, hi_x, hi_y, width-1, height-1);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1400,9 +1389,9 @@ bool Image::Crop( unsigned int lo_x, unsigned int lo_y, unsigned int hi_x, unsig
|
|||
unsigned int new_size = new_width*new_height*colours;
|
||||
uint8_t *new_buffer = AllocBuffer(new_size);
|
||||
|
||||
unsigned int new_stride = new_width*colours;
|
||||
unsigned int new_stride = new_width * colours;
|
||||
for ( unsigned int y = lo_y, ny = 0; y <= hi_y; y++, ny++ ) {
|
||||
unsigned char *pbuf = &buffer[((y*width)+lo_x)*colours];
|
||||
unsigned char *pbuf = &buffer[((y*linesize)+lo_x)];
|
||||
unsigned char *pnbuf = &new_buffer[(ny*new_width)*colours];
|
||||
memcpy( pnbuf, pbuf, new_stride );
|
||||
}
|
||||
|
@ -1412,8 +1401,8 @@ bool Image::Crop( unsigned int lo_x, unsigned int lo_y, unsigned int hi_x, unsig
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Image::Crop( const Box &limits ) {
|
||||
return Crop( limits.LoX(), limits.LoY(), limits.HiX(), limits.HiY() );
|
||||
bool Image::Crop(const Box &limits) {
|
||||
return Crop(limits.LoX(), limits.LoY(), limits.HiX(), limits.HiY());
|
||||
}
|
||||
|
||||
/* Far from complete */
|
||||
|
@ -1434,7 +1423,7 @@ void Image::Overlay( const Image &image ) {
|
|||
const uint8_t* psrc = image.buffer;
|
||||
uint8_t* pdest = buffer;
|
||||
|
||||
while( pdest < max_ptr ) {
|
||||
while ( pdest < max_ptr ) {
|
||||
if ( *psrc ) {
|
||||
*pdest = *psrc;
|
||||
}
|
||||
|
@ -1450,7 +1439,7 @@ void Image::Overlay( const Image &image ) {
|
|||
const uint8_t* psrc = image.buffer;
|
||||
uint8_t* pdest = buffer;
|
||||
|
||||
while( pdest < max_ptr ) {
|
||||
while ( pdest < max_ptr ) {
|
||||
if ( RED_PTR_RGBA(psrc) || GREEN_PTR_RGBA(psrc) || BLUE_PTR_RGBA(psrc) ) {
|
||||
RED_PTR_RGBA(pdest) = RED_PTR_RGBA(psrc);
|
||||
GREEN_PTR_RGBA(pdest) = GREEN_PTR_RGBA(psrc);
|
||||
|
@ -1461,7 +1450,7 @@ void Image::Overlay( const Image &image ) {
|
|||
}
|
||||
|
||||
/* RGB32 ontop of grayscale - convert to same format first - complete */
|
||||
} else if( colours == ZM_COLOUR_GRAY8 && image.colours == ZM_COLOUR_RGB32 ) {
|
||||
} else if ( colours == ZM_COLOUR_GRAY8 && image.colours == ZM_COLOUR_RGB32 ) {
|
||||
Colourise(image.colours, image.subpixelorder);
|
||||
|
||||
const Rgb* const max_ptr = (Rgb*)(buffer+size);
|
||||
|
@ -1470,7 +1459,7 @@ void Image::Overlay( const Image &image ) {
|
|||
|
||||
if ( subpixelorder == ZM_SUBPIX_ORDER_RGBA || subpixelorder == ZM_SUBPIX_ORDER_BGRA ) {
|
||||
/* RGB\BGR\RGBA\BGRA subpixel order - Alpha byte is last */
|
||||
while (prdest < max_ptr) {
|
||||
while ( prdest < max_ptr) {
|
||||
if ( RED_PTR_RGBA(prsrc) || GREEN_PTR_RGBA(prsrc) || BLUE_PTR_RGBA(prsrc) ) {
|
||||
*prdest = *prsrc;
|
||||
}
|
||||
|
@ -1479,7 +1468,7 @@ void Image::Overlay( const Image &image ) {
|
|||
}
|
||||
} else {
|
||||
/* ABGR\ARGB subpixel order - Alpha byte is first */
|
||||
while (prdest < max_ptr) {
|
||||
while ( prdest < max_ptr) {
|
||||
if ( RED_PTR_ABGR(prsrc) || GREEN_PTR_ABGR(prsrc) || BLUE_PTR_ABGR(prsrc) ) {
|
||||
*prdest = *prsrc;
|
||||
}
|
||||
|
@ -1494,7 +1483,7 @@ void Image::Overlay( const Image &image ) {
|
|||
const uint8_t* psrc = image.buffer;
|
||||
uint8_t* pdest = buffer;
|
||||
|
||||
while( pdest < max_ptr ) {
|
||||
while ( pdest < max_ptr ) {
|
||||
if ( *psrc ) {
|
||||
RED_PTR_RGBA(pdest) = GREEN_PTR_RGBA(pdest) = BLUE_PTR_RGBA(pdest) = *psrc;
|
||||
}
|
||||
|
@ -1508,7 +1497,7 @@ void Image::Overlay( const Image &image ) {
|
|||
const uint8_t* psrc = image.buffer;
|
||||
uint8_t* pdest = buffer;
|
||||
|
||||
while( pdest < max_ptr ) {
|
||||
while ( pdest < max_ptr ) {
|
||||
if ( RED_PTR_RGBA(psrc) || GREEN_PTR_RGBA(psrc) || BLUE_PTR_RGBA(psrc) ) {
|
||||
RED_PTR_RGBA(pdest) = RED_PTR_RGBA(psrc);
|
||||
GREEN_PTR_RGBA(pdest) = GREEN_PTR_RGBA(psrc);
|
||||
|
@ -1631,8 +1620,8 @@ void Image::Overlay( const Image &image, unsigned int x, unsigned int y ) {
|
|||
} else {
|
||||
Error("Overlay called with unexpected colours: %d", colours);
|
||||
}
|
||||
|
||||
}
|
||||
Debug(1, "Overlay");
|
||||
} // end void Image::Overlay( const Image &image, unsigned int x, unsigned int y )
|
||||
|
||||
void Image::Blend( const Image &image, int transparency ) {
|
||||
#ifdef ZM_IMAGE_PROFILING
|
||||
|
@ -1794,7 +1783,7 @@ void Image::Delta( const Image &image, Image* targetimage) const {
|
|||
clock_gettime(CLOCK_THREAD_CPUTIME_ID,&start);
|
||||
#endif
|
||||
|
||||
switch (colours) {
|
||||
switch ( colours ) {
|
||||
case ZM_COLOUR_RGB24:
|
||||
if ( subpixelorder == ZM_SUBPIX_ORDER_BGR ) {
|
||||
/* BGR subpixel order */
|
||||
|
@ -1858,7 +1847,7 @@ const Coord Image::centreCoord( const char *text ) const {
|
|||
}
|
||||
int x = (width - (max_line_len * ZM_CHAR_WIDTH) ) / 2;
|
||||
int y = (height - (line_no * LINE_HEIGHT) ) / 2;
|
||||
return( Coord( x, y ) );
|
||||
return Coord(x, y);
|
||||
}
|
||||
|
||||
/* RGB32 compatible: complete */
|
||||
|
@ -2150,7 +2139,7 @@ void Image::DeColourise() {
|
|||
subpixelorder = ZM_SUBPIX_ORDER_NONE;
|
||||
size = width * height;
|
||||
|
||||
if ( colours == ZM_COLOUR_RGB32 && config.cpu_extensions && sseversion >= 35 ) {
|
||||
if ( colours == ZM_COLOUR_RGB32 && config.cpu_extensions && sse_version >= 35 ) {
|
||||
/* Use SSSE3 functions */
|
||||
switch (subpixelorder) {
|
||||
case ZM_SUBPIX_ORDER_BGRA:
|
||||
|
@ -2277,12 +2266,12 @@ void Image::Fill( Rgb colour, int density, const Box *limits ) {
|
|||
if ( density <= 1 )
|
||||
return Fill(colour,limits);
|
||||
|
||||
if ( !(colours == ZM_COLOUR_GRAY8 || colours == ZM_COLOUR_RGB24 || colours == ZM_COLOUR_RGB32 ) ) {
|
||||
if ( !(colours == ZM_COLOUR_GRAY8 || colours == ZM_COLOUR_RGB24 || colours == ZM_COLOUR_RGB32 ) ) {
|
||||
Panic("Attempt to fill image with unexpected colours %d", colours);
|
||||
}
|
||||
|
||||
/* Convert the colour's RGBA subpixel order into the image's subpixel order */
|
||||
colour = rgb_convert(colour,subpixelorder);
|
||||
colour = rgb_convert(colour, subpixelorder);
|
||||
|
||||
unsigned int lo_x = limits?limits->Lo().X():0;
|
||||
unsigned int lo_y = limits?limits->Lo().Y():0;
|
||||
|
@ -2407,20 +2396,20 @@ void Image::Outline( Rgb colour, const Polygon &polygon ) {
|
|||
}
|
||||
|
||||
/* RGB32 compatible: complete */
|
||||
void Image::Fill( Rgb colour, int density, const Polygon &polygon ) {
|
||||
void Image::Fill(Rgb colour, int density, const Polygon &polygon) {
|
||||
if ( !(colours == ZM_COLOUR_GRAY8 || colours == ZM_COLOUR_RGB24 || colours == ZM_COLOUR_RGB32 ) ) {
|
||||
Panic( "Attempt to fill image with unexpected colours %d", colours );
|
||||
Panic("Attempt to fill image with unexpected colours %d", colours);
|
||||
}
|
||||
|
||||
/* Convert the colour's RGBA subpixel order into the image's subpixel order */
|
||||
colour = rgb_convert(colour,subpixelorder);
|
||||
colour = rgb_convert(colour, subpixelorder);
|
||||
|
||||
int n_coords = polygon.getNumCoords();
|
||||
int n_global_edges = 0;
|
||||
Edge global_edges[n_coords];
|
||||
for ( int j = 0, i = n_coords-1; j < n_coords; i = j++ ) {
|
||||
const Coord &p1 = polygon.getCoord( i );
|
||||
const Coord &p2 = polygon.getCoord( j );
|
||||
const Coord &p1 = polygon.getCoord(i);
|
||||
const Coord &p2 = polygon.getCoord(j);
|
||||
|
||||
int x1 = p1.X();
|
||||
int x2 = p2.X();
|
||||
|
@ -2717,7 +2706,7 @@ void Image::Flip( bool leftright ) {
|
|||
|
||||
void Image::Scale( unsigned int factor ) {
|
||||
if ( !factor ) {
|
||||
Error( "Bogus scale factor %d found", factor );
|
||||
Error("Bogus scale factor %d found", factor);
|
||||
return;
|
||||
}
|
||||
if ( factor == ZM_SCALE_BASE ) {
|
||||
|
@ -2727,6 +2716,7 @@ void Image::Scale( unsigned int factor ) {
|
|||
unsigned int new_width = (width*factor)/ZM_SCALE_BASE;
|
||||
unsigned int new_height = (height*factor)/ZM_SCALE_BASE;
|
||||
|
||||
// Why larger than we need?
|
||||
size_t scale_buffer_size = (new_width+1) * (new_height+1) * colours;
|
||||
|
||||
uint8_t* scale_buffer = AllocBuffer(scale_buffer_size);
|
||||
|
@ -2801,10 +2791,8 @@ void Image::Scale( unsigned int factor ) {
|
|||
}
|
||||
new_width = last_w_index;
|
||||
new_height = last_h_index;
|
||||
}
|
||||
|
||||
} // end foreach line
|
||||
AssignDirect( new_width, new_height, colours, subpixelorder, scale_buffer, scale_buffer_size, ZM_BUFTYPE_ZM);
|
||||
|
||||
}
|
||||
|
||||
void Image::Deinterlace_Discard() {
|
||||
|
|
|
@ -152,9 +152,11 @@ protected:
|
|||
static struct zm_error_mgr jpg_err;
|
||||
|
||||
unsigned int width;
|
||||
unsigned int linesize;
|
||||
unsigned int height;
|
||||
unsigned int pixels;
|
||||
unsigned int colours;
|
||||
unsigned int padding;
|
||||
unsigned int size;
|
||||
unsigned int subpixelorder;
|
||||
unsigned long allocation;
|
||||
|
@ -166,14 +168,17 @@ protected:
|
|||
public:
|
||||
Image();
|
||||
explicit Image( const char *filename );
|
||||
Image( int p_width, int p_height, int p_colours, int p_subpixelorder, uint8_t *p_buffer=0);
|
||||
Image(int p_width, int p_height, int p_colours, int p_subpixelorder, uint8_t *p_buffer=0, unsigned int padding=0);
|
||||
Image(int p_width, int p_linesize, int p_height, int p_colours, int p_subpixelorder, uint8_t *p_buffer=0, unsigned int padding=0);
|
||||
explicit Image( const Image &p_image );
|
||||
explicit Image( const AVFrame *frame );
|
||||
|
||||
~Image();
|
||||
static void Initialise();
|
||||
static void Deinitialise();
|
||||
|
||||
inline unsigned int Width() const { return width; }
|
||||
inline unsigned int LineSize() const { return linesize; }
|
||||
inline unsigned int Height() const { return height; }
|
||||
inline unsigned int Pixels() const { return pixels; }
|
||||
inline unsigned int Colours() const { return colours; }
|
||||
|
@ -182,7 +187,7 @@ public:
|
|||
|
||||
/* Internal buffer should not be modified from functions outside of this class */
|
||||
inline const uint8_t* Buffer() const { return buffer; }
|
||||
inline const uint8_t* Buffer( unsigned int x, unsigned int y= 0 ) const { return &buffer[colours*((y*width)+x)]; }
|
||||
inline const uint8_t* Buffer( unsigned int x, unsigned int y= 0 ) const { return &buffer[(y*linesize)+x]; }
|
||||
/* Request writeable buffer */
|
||||
uint8_t* WriteBuffer(const unsigned int p_width, const unsigned int p_height, const unsigned int p_colours, const unsigned int p_subpixelorder);
|
||||
|
||||
|
@ -193,7 +198,7 @@ public:
|
|||
if ( !holdbuffer )
|
||||
DumpImgBuffer();
|
||||
|
||||
width = height = colours = size = pixels = subpixelorder = 0;
|
||||
width = linesize = height = colours = size = pixels = subpixelorder = 0;
|
||||
}
|
||||
|
||||
void Assign( unsigned int p_width, unsigned int p_height, unsigned int p_colours, unsigned int p_subpixelorder, const uint8_t* new_buffer, const size_t buffer_size);
|
||||
|
|
|
@ -198,8 +198,7 @@ void LibvlcCamera::Terminate() {
|
|||
}
|
||||
|
||||
int LibvlcCamera::PrimeCapture() {
|
||||
Info("Priming capture from %s", mPath.c_str());
|
||||
Info("Libvlc Version %s", (*libvlc_get_version_f)());
|
||||
Debug(1, "Priming capture from %s, libvlc version %s", mPath.c_str(), (*libvlc_get_version_f)());
|
||||
|
||||
StringVector opVect = split(Options(), ",");
|
||||
|
||||
|
|
|
@ -148,7 +148,7 @@ void VncCamera::Terminate() {
|
|||
}
|
||||
|
||||
int VncCamera::PrimeCapture() {
|
||||
Info("Priming capture from %s", mHost.c_str());
|
||||
Debug(1, "Priming capture from %s", mHost.c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -504,7 +504,7 @@ LocalCamera::LocalCamera(
|
|||
subpixelorder = ZM_SUBPIX_ORDER_NONE;
|
||||
} else if ( palette == V4L2_PIX_FMT_YUYV && colours == ZM_COLOUR_GRAY8 ) {
|
||||
/* Fast YUYV->Grayscale conversion by extracting the Y channel */
|
||||
if ( config.cpu_extensions && sseversion >= 35 ) {
|
||||
if ( config.cpu_extensions && sse_version >= 35 ) {
|
||||
conversion_fptr = &ssse3_convert_yuyv_gray8;
|
||||
Debug(2,"Using SSSE3 YUYV->grayscale fast conversion");
|
||||
} else {
|
||||
|
@ -616,7 +616,7 @@ LocalCamera::LocalCamera(
|
|||
}
|
||||
} else if ( (palette == VIDEO_PALETTE_YUYV || palette == VIDEO_PALETTE_YUV422) && colours == ZM_COLOUR_GRAY8 ) {
|
||||
/* Fast YUYV->Grayscale conversion by extracting the Y channel */
|
||||
if ( config.cpu_extensions && sseversion >= 35 ) {
|
||||
if ( config.cpu_extensions && sse_version >= 35 ) {
|
||||
conversion_fptr = &ssse3_convert_yuyv_gray8;
|
||||
Debug(2,"Using SSSE3 YUYV->grayscale fast conversion");
|
||||
} else {
|
||||
|
|
|
@ -135,61 +135,61 @@ Monitor::MonitorLink::~MonitorLink() {
|
|||
}
|
||||
|
||||
bool Monitor::MonitorLink::connect() {
|
||||
if ( !last_connect_time || (time( 0 ) - last_connect_time) > 60 ) {
|
||||
last_connect_time = time( 0 );
|
||||
if ( !last_connect_time || (time(0) - last_connect_time) > 60 ) {
|
||||
last_connect_time = time(0);
|
||||
|
||||
mem_size = sizeof(SharedData) + sizeof(TriggerData);
|
||||
|
||||
Debug( 1, "link.mem.size=%d", mem_size );
|
||||
Debug(1, "link.mem.size=%d", mem_size);
|
||||
#if ZM_MEM_MAPPED
|
||||
map_fd = open( mem_file, O_RDWR, (mode_t)0600 );
|
||||
map_fd = open(mem_file, O_RDWR, (mode_t)0600);
|
||||
if ( map_fd < 0 ) {
|
||||
Debug( 3, "Can't open linked memory map file %s: %s", mem_file, strerror(errno) );
|
||||
Debug(3, "Can't open linked memory map file %s: %s", mem_file, strerror(errno));
|
||||
disconnect();
|
||||
return( false );
|
||||
return false;
|
||||
}
|
||||
while ( map_fd <= 2 ) {
|
||||
int new_map_fd = dup(map_fd);
|
||||
Warning( "Got one of the stdio fds for our mmap handle. map_fd was %d, new one is %d", map_fd, new_map_fd );
|
||||
Warning("Got one of the stdio fds for our mmap handle. map_fd was %d, new one is %d", map_fd, new_map_fd);
|
||||
close(map_fd);
|
||||
map_fd = new_map_fd;
|
||||
}
|
||||
|
||||
struct stat map_stat;
|
||||
if ( fstat( map_fd, &map_stat ) < 0 ) {
|
||||
Error( "Can't stat linked memory map file %s: %s", mem_file, strerror(errno) );
|
||||
if ( fstat(map_fd, &map_stat) < 0 ) {
|
||||
Error("Can't stat linked memory map file %s: %s", mem_file, strerror(errno));
|
||||
disconnect();
|
||||
return( false );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( map_stat.st_size == 0 ) {
|
||||
Error( "Linked memory map file %s is empty: %s", mem_file, strerror(errno) );
|
||||
Error("Linked memory map file %s is empty: %s", mem_file, strerror(errno));
|
||||
disconnect();
|
||||
return( false );
|
||||
return false;
|
||||
} else if ( map_stat.st_size < mem_size ) {
|
||||
Error( "Got unexpected memory map file size %ld, expected %d", map_stat.st_size, mem_size );
|
||||
Error("Got unexpected memory map file size %ld, expected %d", map_stat.st_size, mem_size);
|
||||
disconnect();
|
||||
return( false );
|
||||
return false;
|
||||
}
|
||||
|
||||
mem_ptr = (unsigned char *)mmap( NULL, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED, map_fd, 0 );
|
||||
mem_ptr = (unsigned char *)mmap(NULL, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED, map_fd, 0);
|
||||
if ( mem_ptr == MAP_FAILED ) {
|
||||
Error( "Can't map file %s (%d bytes) to memory: %s", mem_file, mem_size, strerror(errno) );
|
||||
Error("Can't map file %s (%d bytes) to memory: %s", mem_file, mem_size, strerror(errno));
|
||||
disconnect();
|
||||
return( false );
|
||||
return false;
|
||||
}
|
||||
#else // ZM_MEM_MAPPED
|
||||
shm_id = shmget( (config.shm_key&0xffff0000)|id, mem_size, 0700 );
|
||||
if ( shm_id < 0 ) {
|
||||
Debug( 3, "Can't shmget link memory: %s", strerror(errno) );
|
||||
Debug(3, "Can't shmget link memory: %s", strerror(errno );
|
||||
connected = false;
|
||||
return( false );
|
||||
return false;
|
||||
}
|
||||
mem_ptr = (unsigned char *)shmat( shm_id, 0, 0 );
|
||||
mem_ptr = (unsigned char *)shmat(shm_id, 0, 0);
|
||||
if ( mem_ptr < (void *)0 ) {
|
||||
Debug( 3, "Can't shmat link memory: %s", strerror(errno) );
|
||||
Debug(3, "Can't shmat link memory: %s", strerror(errno));
|
||||
connected = false;
|
||||
return( false );
|
||||
return false;
|
||||
}
|
||||
#endif // ZM_MEM_MAPPED
|
||||
|
||||
|
@ -197,18 +197,18 @@ bool Monitor::MonitorLink::connect() {
|
|||
trigger_data = (TriggerData *)((char *)shared_data + sizeof(SharedData));
|
||||
|
||||
if ( !shared_data->valid ) {
|
||||
Debug( 3, "Linked memory not initialised by capture daemon" );
|
||||
Debug(3, "Linked memory not initialised by capture daemon");
|
||||
disconnect();
|
||||
return( false );
|
||||
return false;
|
||||
}
|
||||
|
||||
last_state = shared_data->state;
|
||||
last_event = shared_data->last_event;
|
||||
connected = true;
|
||||
|
||||
return( true );
|
||||
return true;
|
||||
}
|
||||
return( false );
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Monitor::MonitorLink::disconnect() {
|
||||
|
@ -529,6 +529,7 @@ Monitor::Monitor(
|
|||
shared_data->last_write_index, shared_data->last_write_time );
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
ref_image.Assign( width, height, camera->Colours(), camera->SubpixelOrder(),
|
||||
image_buffer[shared_data->last_write_index].image->Buffer(), camera->ImageSize());
|
||||
adaptive_skip = true;
|
||||
|
@ -538,7 +539,7 @@ Monitor::Monitor(
|
|||
if ( config.record_diag_images ) {
|
||||
diag_path_r = stringtf(config.record_diag_images_fifo ? "%s/%d/diagpipe-r.jpg" : "%s/%d/diag-r.jpg", storage->Path(), id);
|
||||
diag_path_d = stringtf(config.record_diag_images_fifo ? "%s/%d/diagpipe-d.jpg" : "%s/%d/diag-d.jpg", storage->Path(), id);
|
||||
if (config.record_diag_images_fifo){
|
||||
if ( config.record_diag_images_fifo ) {
|
||||
FifoStream::fifo_create_if_missing(diag_path_r.c_str());
|
||||
FifoStream::fifo_create_if_missing(diag_path_d.c_str());
|
||||
}
|
||||
|
@ -602,7 +603,7 @@ bool Monitor::connect() {
|
|||
if ( mem_ptr == MAP_FAILED )
|
||||
Fatal("Can't map file %s (%d bytes) to memory: %s(%d)", mem_file, mem_size, strerror(errno), errno);
|
||||
if ( mem_ptr == NULL ) {
|
||||
Error("mmap gave a null address:");
|
||||
Error("mmap gave a NULL address:");
|
||||
} else {
|
||||
Debug(3, "mmapped to %p", mem_ptr);
|
||||
}
|
||||
|
@ -631,7 +632,7 @@ bool Monitor::connect() {
|
|||
image_buffer = new Snapshot[image_buffer_count];
|
||||
for ( int i = 0; i < image_buffer_count; i++ ) {
|
||||
image_buffer[i].timestamp = &(shared_timestamps[i]);
|
||||
image_buffer[i].image = new Image( width, height, camera->Colours(), camera->SubpixelOrder(), &(shared_images[i*camera->ImageSize()]) );
|
||||
image_buffer[i].image = new Image( width, camera->LineSize(), height, camera->Colours(), camera->SubpixelOrder(), &(shared_images[i*camera->ImageSize()]) );
|
||||
image_buffer[i].image->HoldBuffer(true); /* Don't release the internal buffer or replace it with another */
|
||||
}
|
||||
if ( (deinterlacing & 0xff) == 4) {
|
||||
|
@ -1403,9 +1404,6 @@ bool Monitor::Analyse() {
|
|||
score += trigger_data->trigger_score;
|
||||
Debug(1, "Triggered on score += %d => %d", trigger_data->trigger_score, score);
|
||||
if ( !event ) {
|
||||
// How could it have a length already?
|
||||
//if ( cause.length() )
|
||||
//cause += ", ";
|
||||
cause += trigger_data->trigger_cause;
|
||||
}
|
||||
Event::StringSet noteSet;
|
||||
|
@ -1485,6 +1483,7 @@ bool Monitor::Analyse() {
|
|||
score += 50;
|
||||
}
|
||||
} else {
|
||||
Debug(1, "Linked monitor %d %d is not connected. Connecting.", i, linked_monitors[i]->Id());
|
||||
linked_monitors[i]->connect();
|
||||
}
|
||||
} // end foreach linked_monit
|
||||
|
@ -1499,7 +1498,7 @@ bool Monitor::Analyse() {
|
|||
|
||||
if ( section_length
|
||||
&& ( ( timestamp->tv_sec - video_store_data->recording.tv_sec ) >= section_length )
|
||||
&& ( (event_close_mode != CLOSE_TIME) || ! ( timestamp->tv_sec % section_length ) )
|
||||
&& ( (function == MOCORD && (event_close_mode != CLOSE_TIME)) || ! ( timestamp->tv_sec % section_length ) )
|
||||
) {
|
||||
Info("%s: %03d - Closing event %" PRIu64 ", section end forced %d - %d = %d >= %d",
|
||||
name, image_count, event->Id(),
|
||||
|
@ -1512,7 +1511,6 @@ bool Monitor::Analyse() {
|
|||
} // end if event
|
||||
|
||||
if ( !event ) {
|
||||
|
||||
// Create event
|
||||
event = new Event(this, *timestamp, "Continuous", noteSetMap, videoRecording);
|
||||
shared_data->last_event = event->Id();
|
||||
|
@ -1526,7 +1524,6 @@ bool Monitor::Analyse() {
|
|||
if ( state == IDLE ) {
|
||||
shared_data->state = state = TAPE;
|
||||
}
|
||||
|
||||
} // end if ! event
|
||||
} // end if function == RECORD || function == MOCORD)
|
||||
} // end if !signal_change && signal
|
||||
|
@ -1539,7 +1536,7 @@ bool Monitor::Analyse() {
|
|||
&& (event_close_mode == CLOSE_ALARM)
|
||||
&& ( ( timestamp->tv_sec - video_store_data->recording.tv_sec ) >= min_section_length )
|
||||
) {
|
||||
Info("%s: %03d - Closing event %" PRIu64 ", continuous end, alarm begins",
|
||||
Info("%s: %03d - Closing event %" PRIu64 ", continuous end, alarm begins",
|
||||
name, image_count, event->Id());
|
||||
closeEvent();
|
||||
} else if ( event ) {
|
||||
|
@ -1550,7 +1547,6 @@ bool Monitor::Analyse() {
|
|||
);
|
||||
}
|
||||
if ( (!pre_event_count) || (Event::PreAlarmCount() >= alarm_frame_count-1) ) {
|
||||
shared_data->state = state = ALARM;
|
||||
// lets construct alarm cause. It will contain cause + names of zones alarmed
|
||||
std::string alarm_cause = "";
|
||||
for ( int i=0; i < n_zones; i++ ) {
|
||||
|
@ -1608,6 +1604,7 @@ bool Monitor::Analyse() {
|
|||
event = new Event(this, *(image_buffer[pre_index].timestamp), cause, noteSetMap);
|
||||
} // end if analysis_fps && pre_event_count
|
||||
|
||||
shared_data->state = state = ALARM;
|
||||
shared_data->last_event = event->Id();
|
||||
//set up video store data
|
||||
snprintf(video_store_data->event_file, sizeof(video_store_data->event_file), "%s", event->getEventFile());
|
||||
|
@ -1680,7 +1677,7 @@ bool Monitor::Analyse() {
|
|||
|
||||
if ( state != IDLE ) {
|
||||
if ( state == PREALARM || state == ALARM ) {
|
||||
if ( config.create_analysis_images ) {
|
||||
if ( savejpegs > 1 ) {
|
||||
bool got_anal_image = false;
|
||||
alarm_image.Assign(*snap_image);
|
||||
for ( int i = 0; i < n_zones; i++ ) {
|
||||
|
@ -1694,17 +1691,10 @@ bool Monitor::Analyse() {
|
|||
} // end if zone is alarmed
|
||||
} // end foreach zone
|
||||
|
||||
if ( got_anal_image ) {
|
||||
if ( state == PREALARM )
|
||||
Event::AddPreAlarmFrame(snap_image, *timestamp, score, &alarm_image);
|
||||
else
|
||||
event->AddFrame(snap_image, *timestamp, score, &alarm_image);
|
||||
} else {
|
||||
if ( state == PREALARM )
|
||||
Event::AddPreAlarmFrame(snap_image, *timestamp, score);
|
||||
else
|
||||
event->AddFrame(snap_image, *timestamp, score);
|
||||
}
|
||||
if ( state == PREALARM )
|
||||
Event::AddPreAlarmFrame(snap_image, *timestamp, score, (got_anal_image?&alarm_image:NULL));
|
||||
else
|
||||
event->AddFrame(snap_image, *timestamp, score, (got_anal_image?&alarm_image:NULL));
|
||||
} else {
|
||||
// Not doing alarm frame storage
|
||||
if ( state == PREALARM ) {
|
||||
|
@ -1718,7 +1708,7 @@ bool Monitor::Analyse() {
|
|||
}
|
||||
} // end if config.record_event_stats
|
||||
}
|
||||
} // end if config.create_analysis_images
|
||||
} // end if savejpegs > 1
|
||||
|
||||
if ( event ) {
|
||||
if ( noteSetMap.size() > 0 )
|
||||
|
@ -1740,7 +1730,6 @@ bool Monitor::Analyse() {
|
|||
//set up video store data
|
||||
snprintf(video_store_data->event_file, sizeof(video_store_data->event_file), "%s", event->getEventFile());
|
||||
video_store_data->recording = event->StartTime();
|
||||
|
||||
}
|
||||
} // end if event
|
||||
|
||||
|
@ -2516,7 +2505,7 @@ int Monitor::Capture() {
|
|||
|
||||
if ( capture_image->Size() > camera->ImageSize() ) {
|
||||
Error("Captured image %d does not match expected size %d check width, height and colour depth",
|
||||
capture_image->Size(),camera->ImageSize() );
|
||||
capture_image->Size(), camera->ImageSize() );
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -138,15 +138,23 @@ protected:
|
|||
time_t startup_time; /* When the zmc process started. zmwatch uses this to see how long the process has been running without getting any images */
|
||||
uint64_t extrapad1;
|
||||
};
|
||||
union { /* +72 */
|
||||
time_t last_write_time;
|
||||
union { /* +72 */
|
||||
time_t zmc_heartbeat_time; /* Constantly updated by zmc. Used to determine if the process is alive or hung or dead */
|
||||
uint64_t extrapad2;
|
||||
};
|
||||
union { /* +80 */
|
||||
time_t last_read_time;
|
||||
union { /* +80 */
|
||||
time_t zma_heartbeat_time; /* Constantly updated by zma. Used to determine if the process is alive or hung or dead */
|
||||
uint64_t extrapad3;
|
||||
};
|
||||
uint8_t control_state[256]; /* +88 */
|
||||
union { /* +88 */
|
||||
time_t last_write_time;
|
||||
uint64_t extrapad4;
|
||||
};
|
||||
union { /* +96 */
|
||||
time_t last_read_time;
|
||||
uint64_t extrapad5;
|
||||
};
|
||||
uint8_t control_state[256]; /* +104 */
|
||||
|
||||
char alarm_cause[256];
|
||||
|
||||
|
@ -210,21 +218,21 @@ protected:
|
|||
uint64_t last_event;
|
||||
|
||||
public:
|
||||
MonitorLink( int p_id, const char *p_name );
|
||||
MonitorLink(int p_id, const char *p_name);
|
||||
~MonitorLink();
|
||||
|
||||
inline int Id() const {
|
||||
return id;
|
||||
}
|
||||
inline const char *Name() const {
|
||||
return( name );
|
||||
return name;
|
||||
}
|
||||
|
||||
inline bool isConnected() const {
|
||||
return( connected );
|
||||
return connected && shared_data->valid;
|
||||
}
|
||||
inline time_t getLastConnectTime() const {
|
||||
return( last_connect_time );
|
||||
return last_connect_time;
|
||||
}
|
||||
|
||||
bool connect();
|
||||
|
@ -415,8 +423,9 @@ public:
|
|||
void AddPrivacyBitmask( Zone *p_zones[] );
|
||||
|
||||
bool connect();
|
||||
|
||||
inline int ShmValid() const {
|
||||
return( shared_data->valid );
|
||||
return shared_data->valid;
|
||||
}
|
||||
|
||||
inline int Id() const {
|
||||
|
|
|
@ -387,6 +387,7 @@ bool MonitorStream::sendFrame(Image *image, struct timeval *timestamp) {
|
|||
struct timeval frameStartTime;
|
||||
gettimeofday(&frameStartTime, NULL);
|
||||
|
||||
fputs("--ZoneMinderFrame\r\n", stdout);
|
||||
switch( type ) {
|
||||
case STREAM_JPEG :
|
||||
send_image->EncodeJpeg(img_buffer, &img_buffer_size);
|
||||
|
|
123
src/zm_utils.cpp
123
src/zm_utils.cpp
|
@ -35,7 +35,7 @@
|
|||
#include <curl/curl.h>
|
||||
#endif
|
||||
|
||||
unsigned int sseversion = 0;
|
||||
unsigned int sse_version = 0;
|
||||
unsigned int neonversion = 0;
|
||||
|
||||
std::string trimSet(std::string str, std::string trimset) {
|
||||
|
@ -44,12 +44,9 @@ std::string trimSet(std::string str, std::string trimset) {
|
|||
size_t endpos = str.find_last_not_of(trimset); // Find the first character position from reverse af
|
||||
|
||||
// if all spaces or empty return an empty string
|
||||
if(( std::string::npos == startpos ) || ( std::string::npos == endpos))
|
||||
{
|
||||
if ( ( std::string::npos == startpos ) || ( std::string::npos == endpos ) )
|
||||
return std::string("");
|
||||
}
|
||||
else
|
||||
return str.substr( startpos, endpos-startpos+1 );
|
||||
return str.substr(startpos, endpos-startpos+1);
|
||||
}
|
||||
|
||||
std::string trimSpaces(const std::string &str) {
|
||||
|
@ -57,48 +54,46 @@ std::string trimSpaces(const std::string &str) {
|
|||
}
|
||||
|
||||
std::string replaceAll(std::string str, std::string from, std::string to) {
|
||||
if(from.empty())
|
||||
if ( from.empty() )
|
||||
return str;
|
||||
size_t start_pos = 0;
|
||||
while((start_pos = str.find(from, start_pos)) != std::string::npos) {
|
||||
while ( (start_pos = str.find(from, start_pos)) != std::string::npos ) {
|
||||
str.replace(start_pos, from.length(), to);
|
||||
start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
const std::string stringtf( const char *format, ... )
|
||||
{
|
||||
const std::string stringtf( const char *format, ... ) {
|
||||
va_list ap;
|
||||
char tempBuffer[8192];
|
||||
std::string tempString;
|
||||
|
||||
va_start(ap, format );
|
||||
vsnprintf( tempBuffer, sizeof(tempBuffer), format , ap );
|
||||
va_start(ap, format);
|
||||
vsnprintf(tempBuffer, sizeof(tempBuffer), format , ap);
|
||||
va_end(ap);
|
||||
|
||||
tempString = tempBuffer;
|
||||
|
||||
return( tempString );
|
||||
return tempString;
|
||||
}
|
||||
|
||||
const std::string stringtf( const std::string format, ... )
|
||||
{
|
||||
const std::string stringtf(const std::string format, ...) {
|
||||
va_list ap;
|
||||
char tempBuffer[8192];
|
||||
std::string tempString;
|
||||
|
||||
va_start(ap, format );
|
||||
vsnprintf( tempBuffer, sizeof(tempBuffer), format.c_str() , ap );
|
||||
va_start(ap, format);
|
||||
vsnprintf(tempBuffer, sizeof(tempBuffer), format.c_str(), ap);
|
||||
va_end(ap);
|
||||
|
||||
tempString = tempBuffer;
|
||||
|
||||
return( tempString );
|
||||
return tempString;
|
||||
}
|
||||
|
||||
bool startsWith(const std::string &haystack, const std::string &needle) {
|
||||
return( haystack.substr(0, needle.length()) == needle );
|
||||
return ( haystack.substr(0, needle.length()) == needle );
|
||||
}
|
||||
|
||||
StringVector split(const std::string &string, const std::string &chars, int limit) {
|
||||
|
@ -145,8 +140,7 @@ const std::string join(const StringVector &v, const char * delim=",") {
|
|||
const std::string base64Encode(const std::string &inString) {
|
||||
static char base64_table[64] = { '\0' };
|
||||
|
||||
if ( !base64_table[0] )
|
||||
{
|
||||
if ( !base64_table[0] ) {
|
||||
int i = 0;
|
||||
for ( char c = 'A'; c <= 'Z'; c++ )
|
||||
base64_table[i++] = c;
|
||||
|
@ -159,59 +153,52 @@ const std::string base64Encode(const std::string &inString) {
|
|||
}
|
||||
|
||||
std::string outString;
|
||||
outString.reserve( 2 * inString.size() );
|
||||
outString.reserve(2 * inString.size());
|
||||
|
||||
const char *inPtr = inString.c_str();
|
||||
while( *inPtr )
|
||||
{
|
||||
while ( *inPtr ) {
|
||||
unsigned char selection = *inPtr >> 2;
|
||||
unsigned char remainder = (*inPtr++ & 0x03) << 4;
|
||||
outString += base64_table[selection];
|
||||
|
||||
if ( *inPtr )
|
||||
{
|
||||
if ( *inPtr ) {
|
||||
selection = remainder | (*inPtr >> 4);
|
||||
remainder = (*inPtr++ & 0x0f) << 2;
|
||||
outString += base64_table[selection];
|
||||
|
||||
if ( *inPtr )
|
||||
{
|
||||
if ( *inPtr ) {
|
||||
selection = remainder | (*inPtr >> 6);
|
||||
outString += base64_table[selection];
|
||||
selection = (*inPtr++ & 0x3f);
|
||||
outString += base64_table[selection];
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
outString += base64_table[remainder];
|
||||
outString += '=';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
outString += base64_table[remainder];
|
||||
outString += '=';
|
||||
outString += '=';
|
||||
}
|
||||
}
|
||||
return( outString );
|
||||
return outString;
|
||||
}
|
||||
|
||||
int split(const char* string, const char delim, std::vector<std::string>& items) {
|
||||
if(string == NULL)
|
||||
if ( string == NULL )
|
||||
return -1;
|
||||
|
||||
if(string[0] == 0)
|
||||
if ( string[0] == 0 )
|
||||
return -2;
|
||||
|
||||
std::string str(string);
|
||||
|
||||
while(true) {
|
||||
while ( true ) {
|
||||
size_t pos = str.find(delim);
|
||||
items.push_back(str.substr(0, pos));
|
||||
str.erase(0, pos+1);
|
||||
|
||||
if(pos == std::string::npos)
|
||||
if ( pos == std::string::npos )
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -219,16 +206,16 @@ int split(const char* string, const char delim, std::vector<std::string>& items)
|
|||
}
|
||||
|
||||
int pairsplit(const char* string, const char delim, std::string& name, std::string& value) {
|
||||
if(string == NULL)
|
||||
if ( string == NULL )
|
||||
return -1;
|
||||
|
||||
if(string[0] == 0)
|
||||
if ( string[0] == 0 )
|
||||
return -2;
|
||||
|
||||
std::string str(string);
|
||||
size_t pos = str.find(delim);
|
||||
|
||||
if(pos == std::string::npos || pos == 0 || pos >= str.length())
|
||||
if ( pos == std::string::npos || pos == 0 || pos >= str.length() )
|
||||
return -3;
|
||||
|
||||
name = str.substr(0, pos);
|
||||
|
@ -240,7 +227,7 @@ int pairsplit(const char* string, const char delim, std::string& name, std::stri
|
|||
/* Detect special hardware features, such as SIMD instruction sets */
|
||||
void hwcaps_detect() {
|
||||
neonversion = 0;
|
||||
sseversion = 0;
|
||||
sse_version = 0;
|
||||
#if (defined(__i386__) || defined(__x86_64__))
|
||||
/* x86 or x86-64 processor */
|
||||
uint32_t r_edx, r_ecx, r_ebx;
|
||||
|
@ -277,33 +264,33 @@ void hwcaps_detect() {
|
|||
);
|
||||
#endif
|
||||
|
||||
if (r_ebx & 0x00000020) {
|
||||
sseversion = 52; /* AVX2 */
|
||||
Debug(1,"Detected a x86\\x86-64 processor with AVX2");
|
||||
} else if (r_ecx & 0x10000000) {
|
||||
sseversion = 51; /* AVX */
|
||||
Debug(1,"Detected a x86\\x86-64 processor with AVX");
|
||||
} else if (r_ecx & 0x00100000) {
|
||||
sseversion = 42; /* SSE4.2 */
|
||||
Debug(1,"Detected a x86\\x86-64 processor with SSE4.2");
|
||||
} else if (r_ecx & 0x00080000) {
|
||||
sseversion = 41; /* SSE4.1 */
|
||||
Debug(1,"Detected a x86\\x86-64 processor with SSE4.1");
|
||||
} else if (r_ecx & 0x00000200) {
|
||||
sseversion = 35; /* SSSE3 */
|
||||
if ( r_ebx & 0x00000020 ) {
|
||||
sse_version = 52; /* AVX2 */
|
||||
Debug(1, "Detected a x86\\x86-64 processor with AVX2");
|
||||
} else if ( r_ecx & 0x10000000 ) {
|
||||
sse_version = 51; /* AVX */
|
||||
Debug(1, "Detected a x86\\x86-64 processor with AVX");
|
||||
} else if ( r_ecx & 0x00100000 ) {
|
||||
sse_version = 42; /* SSE4.2 */
|
||||
Debug(1, "Detected a x86\\x86-64 processor with SSE4.2");
|
||||
} else if ( r_ecx & 0x00080000 ) {
|
||||
sse_version = 41; /* SSE4.1 */
|
||||
Debug(1, "Detected a x86\\x86-64 processor with SSE4.1");
|
||||
} else if ( r_ecx & 0x00000200 ) {
|
||||
sse_version = 35; /* SSSE3 */
|
||||
Debug(1,"Detected a x86\\x86-64 processor with SSSE3");
|
||||
} else if (r_ecx & 0x00000001) {
|
||||
sseversion = 30; /* SSE3 */
|
||||
Debug(1,"Detected a x86\\x86-64 processor with SSE3");
|
||||
} else if (r_edx & 0x04000000) {
|
||||
sseversion = 20; /* SSE2 */
|
||||
Debug(1,"Detected a x86\\x86-64 processor with SSE2");
|
||||
} else if (r_edx & 0x02000000) {
|
||||
sseversion = 10; /* SSE */
|
||||
Debug(1,"Detected a x86\\x86-64 processor with SSE");
|
||||
} else if ( r_ecx & 0x00000001 ) {
|
||||
sse_version = 30; /* SSE3 */
|
||||
Debug(1, "Detected a x86\\x86-64 processor with SSE3");
|
||||
} else if ( r_edx & 0x04000000 ) {
|
||||
sse_version = 20; /* SSE2 */
|
||||
Debug(1, "Detected a x86\\x86-64 processor with SSE2");
|
||||
} else if ( r_edx & 0x02000000 ) {
|
||||
sse_version = 10; /* SSE */
|
||||
Debug(1, "Detected a x86\\x86-64 processor with SSE");
|
||||
} else {
|
||||
sseversion = 0;
|
||||
Debug(1,"Detected a x86\\x86-64 processor");
|
||||
sse_version = 0;
|
||||
Debug(1, "Detected a x86\\x86-64 processor");
|
||||
}
|
||||
#elif defined(__arm__)
|
||||
// ARM processor in 32bit mode
|
||||
|
|
|
@ -59,7 +59,7 @@ void* sse2_aligned_memcpy(void* dest, const void* src, size_t bytes);
|
|||
void timespec_diff(struct timespec *start, struct timespec *end, struct timespec *diff);
|
||||
|
||||
void hwcaps_detect();
|
||||
extern unsigned int sseversion;
|
||||
extern unsigned int sse_version;
|
||||
extern unsigned int neonversion;
|
||||
|
||||
char *timeval_to_string( struct timeval tv );
|
||||
|
|
|
@ -229,7 +229,7 @@ bool Zone::CheckAlarms(const Image *delta_image) {
|
|||
|
||||
Debug(4, "Checking alarms for zone %d/%s in lines %d -> %d", id, label, lo_y, hi_y);
|
||||
|
||||
/* if(config.cpu_extensions && sseversion >= 20) {
|
||||
/* if(config.cpu_extensions && sse_version >= 20) {
|
||||
sse2_alarmedpixels(diff_image, pg_image, &alarm_pixels, &pixel_diff_count);
|
||||
} else {
|
||||
std_alarmedpixels(diff_image, pg_image, &alarm_pixels, &pixel_diff_count);
|
||||
|
@ -505,7 +505,7 @@ bool Zone::CheckAlarms(const Image *delta_image) {
|
|||
||
|
||||
(max_blob_pixels && bs->count > max_blob_pixels)
|
||||
) {
|
||||
if ( config.create_analysis_images || config.record_diag_images ) {
|
||||
if ( ( monitor->GetOptSaveJPEGs() > 1 ) || config.record_diag_images ) {
|
||||
for ( int sy = bs->lo_y; sy <= bs->hi_y; sy++ ) {
|
||||
spdiff = diff_buff + ((diff_width * sy) + bs->lo_x);
|
||||
for ( int sx = bs->lo_x; sx <= bs->hi_x; sx++, spdiff++ ) {
|
||||
|
@ -574,7 +574,7 @@ bool Zone::CheckAlarms(const Image *delta_image) {
|
|||
BlobStats *bs = &blob_stats[i];
|
||||
if ( bs->count ) {
|
||||
if ( (min_blob_pixels && bs->count < min_blob_pixels) || (max_blob_pixels && bs->count > max_blob_pixels) ) {
|
||||
if ( config.create_analysis_images || config.record_diag_images ) {
|
||||
if ( ( monitor->GetOptSaveJPEGs() > 1 ) || config.record_diag_images ) {
|
||||
for ( int sy = bs->lo_y; sy <= bs->hi_y; sy++ ) {
|
||||
spdiff = diff_buff + ((diff_width * sy) + bs->lo_x);
|
||||
for ( int sx = bs->lo_x; sx <= bs->hi_x; sx++, spdiff++ ) {
|
||||
|
@ -702,7 +702,7 @@ bool Zone::CheckAlarms(const Image *delta_image) {
|
|||
alarm_centre = alarm_box.Centre();
|
||||
}
|
||||
|
||||
if ( (type < PRECLUSIVE) && (check_method >= BLOBS) && config.create_analysis_images ) {
|
||||
if ( (type < PRECLUSIVE) && (check_method >= BLOBS) && (monitor->GetOptSaveJPEGs() > 1) ) {
|
||||
|
||||
// First mask out anything we don't want
|
||||
for ( unsigned int y = lo_y; y <= hi_y; y++ ) {
|
||||
|
|
|
@ -259,7 +259,8 @@ int main(int argc, char *argv[]) {
|
|||
Debug(1, "Failed to prime capture of initial monitor");
|
||||
}
|
||||
prime_capture_log_count ++;
|
||||
sleep(10);
|
||||
if ( !zm_terminate )
|
||||
sleep(10);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ echo "Target subfolder set to $targetfolder"
|
|||
echo
|
||||
|
||||
echo "Running \$(rsync -v -e 'ssh -vvv' build/*.{rpm,deb,dsc,tar.xz,buildinfo,changes} zmrepo@zmrepo.zoneminder.com:${targetfolder}/ 2>&1)"
|
||||
rsync -v --ignore-missing-args --exclude 'external-repo.noarch.rpm' -e 'ssh -vvv' build/*.{rpm,deb,dsc,tar.xz,buildinfo,changes} zmrepo@zmrepo.zoneminder.com:${targetfolder}/ 2>&1
|
||||
rsync -v --ignore-missing-args --exclude 'external-repo.noarch.rpm' -e 'ssh -v' build/*.{rpm,deb,dsc,tar.xz,buildinfo,changes} zmrepo@zmrepo.zoneminder.com:${targetfolder}/ 2>&1
|
||||
if [ "$?" -eq 0 ]; then
|
||||
echo
|
||||
echo "Files copied successfully."
|
||||
|
|
|
@ -16,7 +16,7 @@ my @monitors;
|
|||
my $dbh = zmDbConnect();
|
||||
|
||||
my $sql = "SELECT * FROM Monitors
|
||||
WHERE find_in_set( Function, 'Modect,Mocord,Nodect' )".
|
||||
WHERE find_in_set( `Function`, 'Modect,Mocord,Nodect' )".
|
||||
( $Config{ZM_SERVER_ID} ? 'AND ServerId=?' : '' )
|
||||
;
|
||||
|
||||
|
|
|
@ -102,21 +102,21 @@ CakeLog::config('debug', array(
|
|||
'engine' => 'File',
|
||||
'types' => array('notice', 'info', 'debug'),
|
||||
'file' => 'cake_debug',
|
||||
'path' => '@ZM_LOGDIR@/'
|
||||
'path' => '@ZM_LOGDIR@/'
|
||||
));
|
||||
CakeLog::config('error', array(
|
||||
'engine' => 'File',
|
||||
'types' => array('warning', 'error', 'critical', 'alert', 'emergency'),
|
||||
'file' => 'cake_error',
|
||||
'path' => '@ZM_LOGDIR@/'
|
||||
'path' => '@ZM_LOGDIR@/'
|
||||
));
|
||||
CakeLog::config('custom_path', array(
|
||||
'engine' => 'File',
|
||||
'path' => '@ZM_LOGDIR@/'
|
||||
'engine' => 'File',
|
||||
'path' => '@ZM_LOGDIR@/'
|
||||
));
|
||||
|
||||
Configure::write('ZM_CONFIG', '@ZM_CONFIG@');
|
||||
Configure::write('ZM_CONFIG_SUBDIR', '@ZM_CONFIG_SUBDIR@');
|
||||
Configure::write('ZM_CONFIG', '@ZM_CONFIG@');
|
||||
Configure::write('ZM_CONFIG_SUBDIR', '@ZM_CONFIG_SUBDIR@');
|
||||
Configure::write('ZM_VERSION', '@VERSION@');
|
||||
Configure::write('ZM_API_VERSION', '@API_VERSION@');
|
||||
|
||||
|
@ -128,27 +128,3 @@ global $configvals;
|
|||
foreach( $configvals as $key => $value) {
|
||||
Configure::write($key, $value);
|
||||
}
|
||||
if ( 0 ) {
|
||||
// No longer needed, but I want to keep the code for reference
|
||||
//
|
||||
// For Human-readability, use ZM_SERVER_HOST or ZM_SERVER_NAME in zm.conf, and convert it here to a ZM_SERVER_ID
|
||||
if ( ! defined('ZM_SERVER_ID') ) {
|
||||
App::uses('ClassRegistry', 'Utility');
|
||||
$ServerModel = ClassRegistry::init('Server');
|
||||
if ( defined('ZM_SERVER_NAME') and ZM_SERVER_NAME ) {
|
||||
$Server = $ServerModel->find( 'first', array( 'conditions'=>array('Name'=>ZM_SERVER_NAME) ) );
|
||||
if ( ! $Server ) {
|
||||
Error('Invalid Multi-Server configration detected. ZM_SERVER_NAME set to ' . ZM_SERVER_NAME . ' in zm.conf, but no corresponding entry found in Servers table.');
|
||||
} else {
|
||||
define( 'ZM_SERVER_ID', $Server['Server']['Id'] );
|
||||
}
|
||||
} else if ( defined('ZM_SERVER_HOST') and ZM_SERVER_HOST ) {
|
||||
$Server = $ServerModel->find( 'first', array( 'conditions'=>array('Name'=>ZM_SERVER_HOST) ) );
|
||||
if ( ! $Server ) {
|
||||
Error('Invalid Multi-Server configration detected. ZM_SERVER_HOST set to ' . ZM_SERVER_HOST . ' in zm.conf, but no corresponding entry found in Servers table.');
|
||||
} else {
|
||||
define( 'ZM_SERVER_ID', $Server['Server']['Id'] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,12 +36,6 @@ class UsersController extends AppController {
|
|||
* @return void
|
||||
*/
|
||||
public function view($id = null) {
|
||||
$this->loadModel('Config');
|
||||
$configs = $this->Config->find('list', array(
|
||||
'fields' => array('Name', 'Value'),
|
||||
'conditions' => array('Name' => array('ZM_DIR_EVENTS'))
|
||||
));
|
||||
|
||||
$this->User->recursive = 1;
|
||||
if (!$this->User->exists($id)) {
|
||||
throw new NotFoundException(__('Invalid user'));
|
||||
|
@ -86,16 +80,16 @@ class UsersController extends AppController {
|
|||
throw new NotFoundException(__('Invalid user'));
|
||||
}
|
||||
|
||||
if ($this->request->is('post') || $this->request->is('put')) {
|
||||
if ($this->User->save($this->request->data)) {
|
||||
if ( $this->request->is('post') || $this->request->is('put') ) {
|
||||
if ( $this->User->save($this->request->data) ) {
|
||||
$message = 'Saved';
|
||||
} else {
|
||||
$message = 'Error';
|
||||
}
|
||||
} else {
|
||||
$this->request->data = $this->User->read(null, $id);
|
||||
unset($this->request->data['User']['password']);
|
||||
}
|
||||
$this->request->data = $this->User->read(null, $id);
|
||||
unset($this->request->data['User']['password']);
|
||||
}
|
||||
|
||||
$this->set(array(
|
||||
'message' => $message,
|
||||
|
@ -112,11 +106,11 @@ class UsersController extends AppController {
|
|||
*/
|
||||
public function delete($id = null) {
|
||||
$this->User->id = $id;
|
||||
if (!$this->User->exists()) {
|
||||
if ( !$this->User->exists() ) {
|
||||
throw new NotFoundException(__('Invalid user'));
|
||||
}
|
||||
$this->request->allowMethod('post', 'delete');
|
||||
if ($this->User->delete()) {
|
||||
if ( $this->User->delete() ) {
|
||||
$message = 'The user has been deleted.';
|
||||
} else {
|
||||
$message = 'The user could not be deleted. Please, try again.';
|
||||
|
@ -127,29 +121,18 @@ class UsersController extends AppController {
|
|||
));
|
||||
}
|
||||
|
||||
public function beforeFilter() {
|
||||
parent::beforeFilter();
|
||||
public function beforeFilter() {
|
||||
parent::beforeFilter();
|
||||
|
||||
$this->loadModel('Config');
|
||||
$configs = $this->Config->find('list', array(
|
||||
'fields' => array('Name', 'Value'),
|
||||
'conditions' => array('Name' => array('ZM_OPT_USE_AUTH'))
|
||||
));
|
||||
if ( $configs['ZM_OPT_USE_AUTH'] ) {
|
||||
$this->Auth->allow('add','logout');
|
||||
} else {
|
||||
$this->Auth->allow();
|
||||
}
|
||||
if ( ZM_OPT_USE_AUTH ) {
|
||||
$this->Auth->allow('add', 'logout');
|
||||
} else {
|
||||
$this->Auth->allow();
|
||||
}
|
||||
}
|
||||
|
||||
public function login() {
|
||||
$this->loadModel('Config');
|
||||
$configs = $this->Config->find('list', array(
|
||||
'fields' => array('Name', 'Value'),
|
||||
'conditions' => array('Name' => array('ZM_OPT_USE_AUTH'))
|
||||
));
|
||||
|
||||
if ( ! $configs['ZM_OPT_USE_AUTH'] ) {
|
||||
if ( !ZM_OPT_USE_AUTH ) {
|
||||
$this->set(array(
|
||||
'message' => 'Login is not required.',
|
||||
'_serialize' => array('message')
|
||||
|
@ -157,8 +140,8 @@ class UsersController extends AppController {
|
|||
return;
|
||||
}
|
||||
|
||||
if ($this->request->is('post')) {
|
||||
if ($this->Auth->login()) {
|
||||
if ( $this->request->is('post') ) {
|
||||
if ( $this->Auth->login() ) {
|
||||
return $this->redirect($this->Auth->redirectUrl());
|
||||
}
|
||||
$this->Session->setFlash(__('Invalid username or password, try again'));
|
||||
|
@ -168,5 +151,4 @@ class UsersController extends AppController {
|
|||
public function logout() {
|
||||
return $this->redirect($this->Auth->logout());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ class ZonesController extends AppController {
|
|||
'_serialize' => array('zones')
|
||||
));
|
||||
}
|
||||
|
||||
public function index() {
|
||||
$this->Zone->recursive = -1;
|
||||
|
||||
|
@ -63,23 +64,43 @@ class ZonesController extends AppController {
|
|||
* @return void
|
||||
*/
|
||||
public function add() {
|
||||
if ( $this->request->is('post') ) {
|
||||
|
||||
global $user;
|
||||
$canEdit = (!$user) || $user['Monitors'] == 'Edit';
|
||||
if ( !$canEdit ) {
|
||||
throw new UnauthorizedException(__('Insufficient Privileges'));
|
||||
return;
|
||||
}
|
||||
if ( !$this->request->is('post') ) {
|
||||
throw new BadRequestException(__('Invalid method. Should be post'));
|
||||
return;
|
||||
}
|
||||
|
||||
$this->Zone->create();
|
||||
if ( $this->Zone->save($this->request->data) ) {
|
||||
return $this->flash(__('The zone has been saved.'), array('action' => 'index'));
|
||||
global $user;
|
||||
$canEdit = (!$user) || $user['Monitors'] == 'Edit';
|
||||
if ( !$canEdit ) {
|
||||
throw new UnauthorizedException(__('Insufficient Privileges'));
|
||||
return;
|
||||
}
|
||||
|
||||
$zone = null;
|
||||
|
||||
$this->Zone->create();
|
||||
$zone = $this->Zone->save($this->request->data);
|
||||
if ( $zone ) {
|
||||
require_once __DIR__ .'/../../../includes/Monitor.php';
|
||||
$monitor = new ZM\Monitor($zone['Zone']['MonitorId']);
|
||||
$monitor->zmaControl('restart');
|
||||
$message = 'Saved';
|
||||
//$zone = $this->Zone->find('first', array('conditions' => array( array('Zone.' . $this->Zone->primaryKey => $this->Zone),
|
||||
} else {
|
||||
$message = 'Error: ';
|
||||
// if there is a validation message, use it
|
||||
if ( !$this->Zone->validates() ) {
|
||||
$message = $this->Zone->validationErrors;
|
||||
}
|
||||
}
|
||||
$monitors = $this->Zone->Monitor->find('list');
|
||||
$this->set(compact('monitors'));
|
||||
}
|
||||
|
||||
$this->set(array(
|
||||
'message' => $message,
|
||||
'zone' => $zone,
|
||||
'_serialize' => array('message','zone')
|
||||
));
|
||||
} // end function add()
|
||||
|
||||
/**
|
||||
* edit method
|
||||
|
|
|
@ -3,8 +3,6 @@ App::uses('AppModel', 'Model');
|
|||
/**
|
||||
* User Model
|
||||
*
|
||||
* @property Monitor $Monitor
|
||||
* @property Frame $Frame
|
||||
*/
|
||||
class User extends AppModel {
|
||||
|
||||
|
@ -53,14 +51,6 @@ class User extends AppModel {
|
|||
* @var array
|
||||
*/
|
||||
public $belongsTo = array(
|
||||
/*'Monitor' => array(
|
||||
'className' => 'Monitor',
|
||||
'foreignKey' => 'MonitorId',
|
||||
'conditions' => '',
|
||||
'fields' => '',
|
||||
'order' => ''
|
||||
)
|
||||
*/
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -69,21 +59,6 @@ class User extends AppModel {
|
|||
* @var array
|
||||
*/
|
||||
public $hasMany = array(
|
||||
/*
|
||||
'Frame' => array(
|
||||
'className' => 'Frame',
|
||||
'foreignKey' => 'UserId',
|
||||
'dependent' => true,
|
||||
'conditions' => '',
|
||||
'fields' => '',
|
||||
'order' => '',
|
||||
'limit' => '',
|
||||
'offset' => '',
|
||||
'exclusive' => '',
|
||||
'finderQuery' => '',
|
||||
'counterQuery' => ''
|
||||
)
|
||||
*/
|
||||
);
|
||||
|
||||
}
|
||||
|
|
|
@ -30,6 +30,32 @@ class Zone extends AppModel {
|
|||
|
||||
public $recursive = -1;
|
||||
|
||||
/**
|
||||
* Validation rules
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $validate = array(
|
||||
'MonitorId' => array(
|
||||
'rule' => 'checkMonitorId',
|
||||
//array('naturalNumber'),
|
||||
'message' => 'Zones must have a valid MonitorId',
|
||||
'allowEmpty' => false,
|
||||
'required' => true,
|
||||
//'last' => false, // Stop validation after this rule
|
||||
//'on' => 'create', // Limit validation to 'create' or 'update' operations
|
||||
),
|
||||
'Name' => array(
|
||||
'required' => array(
|
||||
//'on' => 'create',
|
||||
'rule' => 'notBlank',
|
||||
'message' => 'Zone Name must be specified for creation',
|
||||
'required' => true,
|
||||
),
|
||||
)
|
||||
|
||||
);
|
||||
|
||||
//The Associations below have been created with all possible keys, those that are not needed can be removed
|
||||
|
||||
/**
|
||||
|
@ -41,9 +67,17 @@ class Zone extends AppModel {
|
|||
'Monitor' => array(
|
||||
'className' => 'Monitor',
|
||||
'foreignKey' => 'MonitorId',
|
||||
'conditions' => '',
|
||||
'fields' => '',
|
||||
'order' => ''
|
||||
//'conditions' => '',
|
||||
//'fields' => '',
|
||||
//'order' => ''
|
||||
)
|
||||
);
|
||||
|
||||
public function checkMonitorId($data) {
|
||||
if ( !$this->Monitor->find('first', array('conditions'=>array('Id'=>$data['MonitorId']))) ) {
|
||||
//$this->invalidate('MonitorId', 'Invalid Monitor Id');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -205,6 +205,11 @@ class Monitor extends ZM_Object {
|
|||
if ( ZM_RAND_STREAM ) {
|
||||
$args['rand'] = time();
|
||||
}
|
||||
foreach ( array('scale','height','width') as $int_arg ) {
|
||||
if ( isset($args[$int_arg]) and (!is_int($args[$int_arg]) or !$args[$int_arg] ) ) {
|
||||
unset($args[$int_arg]);
|
||||
}
|
||||
}
|
||||
|
||||
$streamSrc .= '?'.http_build_query($args, '', $querySep);
|
||||
|
||||
|
@ -297,12 +302,12 @@ class Monitor extends ZM_Object {
|
|||
return;
|
||||
}
|
||||
}
|
||||
Logger::Debug("sending command to $url");
|
||||
Logger::Debug('sending command to '.$url);
|
||||
|
||||
$context = stream_context_create();
|
||||
try {
|
||||
$result = file_get_contents($url, false, $context);
|
||||
if ($result === FALSE) { /* Handle error */
|
||||
if ( $result === FALSE ) { /* Handle error */
|
||||
Error("Error restarting zmc using $url");
|
||||
}
|
||||
} catch ( Exception $e ) {
|
||||
|
@ -314,14 +319,15 @@ class Monitor extends ZM_Object {
|
|||
} // end function zmcControl
|
||||
|
||||
function zmaControl($mode=false) {
|
||||
if ( ! $this->{'Id'} ) {
|
||||
if ( !$this->{'Id'} ) {
|
||||
Warning('Attempt to control a monitor with no Id');
|
||||
return;
|
||||
}
|
||||
|
||||
if ( (!defined('ZM_SERVER_ID')) or ( property_exists($this, 'ServerId') and (ZM_SERVER_ID==$this->{'ServerId'}) ) ) {
|
||||
if ( $this->{'Function'} == 'None' || $this->{'Function'} == 'Monitor' || $mode == 'stop' ) {
|
||||
if ( ZM_OPT_CONTROL ) {
|
||||
if ( ZM_OPT_CONTROL && $this->Controllable() && $this->TrackMotion() &&
|
||||
( $this->{'Function'} == 'Modect' || $this->{'Function'} == 'Mocord' ) ) {
|
||||
daemonControl('stop', 'zmtrack.pl', '-m '.$this->{'Id'});
|
||||
}
|
||||
daemonControl('stop', 'zma', '-m '.$this->{'Id'});
|
||||
|
@ -344,7 +350,7 @@ class Monitor extends ZM_Object {
|
|||
} else if ( $this->ServerId() ) {
|
||||
$Server = $this->Server();
|
||||
|
||||
$url = ZM_BASE_PROTOCOL . '://'.$Server->Hostname().'/zm/api/monitors/daemonControl/'.$this->{'Id'}.'/'.$mode.'/zma.json';
|
||||
$url = $Server->UrlToApi().'/monitors/daemonControl/'.$this->{'Id'}.'/'.$mode.'/zma.json';
|
||||
if ( ZM_OPT_USE_AUTH ) {
|
||||
if ( ZM_AUTH_RELAY == 'hashed' ) {
|
||||
$url .= '?auth='.generateAuthHash(ZM_AUTH_HASH_IPS);
|
||||
|
@ -358,10 +364,10 @@ class Monitor extends ZM_Object {
|
|||
}
|
||||
Logger::Debug("sending command to $url");
|
||||
|
||||
$context = stream_context_create();
|
||||
$context = stream_context_create();
|
||||
try {
|
||||
$result = file_get_contents($url, false, $context);
|
||||
if ($result === FALSE) { /* Handle error */
|
||||
if ( $result === FALSE ) { /* Handle error */
|
||||
Error("Error restarting zma using $url");
|
||||
}
|
||||
} catch ( Exception $e ) {
|
||||
|
@ -497,12 +503,11 @@ class Monitor extends ZM_Object {
|
|||
foreach ( explode(' ', $command) as $option ) {
|
||||
if ( preg_match('/--([^=]+)(?:=(.+))?/', $option, $matches) ) {
|
||||
$options[$matches[1]] = $matches[2]?$matches[2]:1;
|
||||
} else if ( $option != '' and $option != 'quit' ) {
|
||||
} else if ( $option != '' and $option != 'quit' and $option != 'start' and $option != 'stop' ) {
|
||||
Warning("Ignored command for zmcontrol $option in $command");
|
||||
}
|
||||
}
|
||||
if ( !count($options) ) {
|
||||
|
||||
if ( $command == 'quit' or $command == 'start' or $command == 'stop' ) {
|
||||
# These are special as we now run zmcontrol as a daemon through zmdc.
|
||||
$status = daemonStatus('zmcontrol.pl', array('--id', $this->{'Id'}));
|
||||
|
@ -546,7 +551,7 @@ class Monitor extends ZM_Object {
|
|||
} else if ( $this->ServerId() ) {
|
||||
$Server = $this->Server();
|
||||
|
||||
$url = ZM_BASE_PROTOCOL . '://'.$Server->Hostname().'/zm/api/monitors/daemonControl/'.$this->{'Id'}.'/'.$command.'/zmcontrol.pl.json';
|
||||
$url = $Server->UrlToApi().'/monitors/daemonControl/'.$this->{'Id'}.'/'.$command.'/zmcontrol.pl.json';
|
||||
if ( ZM_OPT_USE_AUTH ) {
|
||||
if ( ZM_AUTH_RELAY == 'hashed' ) {
|
||||
$url .= '?auth='.generateAuthHash(ZM_AUTH_HASH_IPS);
|
||||
|
|
|
@ -85,8 +85,6 @@ if ( isset($_REQUEST['object']) and ( $_REQUEST['object'] == 'filter' ) ) {
|
|||
// We update the request id so that the newly saved filter is auto-selected
|
||||
$_REQUEST['Id'] = $filter->Id();
|
||||
}
|
||||
if ( $filter->Background() )
|
||||
$filter->control('start');
|
||||
|
||||
if ( $action == 'execute' ) {
|
||||
$filter->execute();
|
||||
|
@ -94,6 +92,8 @@ if ( isset($_REQUEST['object']) and ( $_REQUEST['object'] == 'filter' ) ) {
|
|||
$filter->delete();
|
||||
|
||||
$view = 'events';
|
||||
} else if ( $filter->Background() ) {
|
||||
$filter->control('start');
|
||||
}
|
||||
|
||||
} else if ( $action == 'control' ) {
|
||||
|
|
|
@ -18,27 +18,36 @@
|
|||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
|
||||
if ( $action == 'user' ) {
|
||||
if ( $action == 'Save' ) {
|
||||
if ( canEdit('System') ) {
|
||||
if ( !empty($_REQUEST['uid']) )
|
||||
if ( !empty($_REQUEST['uid']) ) {
|
||||
$dbUser = dbFetchOne('SELECT * FROM Users WHERE Id=?', NULL, array($_REQUEST['uid']));
|
||||
else
|
||||
} else {
|
||||
$dbUser = array();
|
||||
}
|
||||
|
||||
$types = array();
|
||||
if ( isset($_REQUEST['newUser']['MonitorIds']) and is_array($_REQUEST['newUser']['MonitorIds']) )
|
||||
$_REQUEST['newUser']['MonitorIds'] = implode(',', $_REQUEST['newUser']['MonitorIds']);
|
||||
if ( !$_REQUEST['newUser']['Password'] )
|
||||
unset($_REQUEST['newUser']['Password']);
|
||||
|
||||
$changes = getFormChanges($dbUser, $_REQUEST['newUser'], $types);
|
||||
|
||||
if ( function_exists('password_hash') ) {
|
||||
$pass_hash = '"'.password_hash($_REQUEST['newUser']['Password'], PASSWORD_BCRYPT).'"';
|
||||
} else {
|
||||
$pass_hash = ' PASSWORD('.dbEscape($_REQUEST['newUser']['Password']).') ';
|
||||
ZM\Info('Cannot use bcrypt as you are using PHP < 5.3');
|
||||
}
|
||||
|
||||
if ( $_REQUEST['newUser']['Password'] ) {
|
||||
$changes['Password'] = 'Password = '.$pass_hash;
|
||||
} else {
|
||||
unset($changes['Password']);
|
||||
|
||||
if ( isset($_REQUEST['newUser']['Password']) ) {
|
||||
if ( function_exists('password_hash') ) {
|
||||
$pass_hash = '"'.password_hash($_REQUEST['newUser']['Password'], PASSWORD_BCRYPT).'"';
|
||||
} else {
|
||||
$pass_hash = ' PASSWORD('.dbEscape($_REQUEST['newUser']['Password']).') ';
|
||||
ZM\Info('Cannot use bcrypt as you are using PHP < 5.3');
|
||||
}
|
||||
|
||||
if ( $_REQUEST['newUser']['Password'] ) {
|
||||
$changes['Password'] = 'Password = '.$pass_hash;
|
||||
} else {
|
||||
unset($changes['Password']);
|
||||
}
|
||||
}
|
||||
|
||||
if ( count($changes) ) {
|
||||
|
|
|
@ -2,21 +2,21 @@
|
|||
//
|
||||
// ZoneMinder web function library, $Date$, $Revision$
|
||||
// Copyright (C) 2001-2008 Philip Coombes
|
||||
//
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
//
|
||||
|
||||
// Compatibility functions
|
||||
if ( version_compare(phpversion(), '4.3.0', '<') ) {
|
||||
|
@ -299,7 +299,7 @@ function outputHelperStream($id, $src, $width, $height, $title='') {
|
|||
}
|
||||
function getHelperStream($id, $src, $width, $height, $title='') {
|
||||
return '<object type="application/x-java-applet" id="'.$id.'" code="com.charliemouse.cambozola.Viewer"
|
||||
archive="'. ZM_PATH_CAMBOZOLA .'"
|
||||
archive="'. ZM_PATH_CAMBOZOLA .'"
|
||||
align="middle"
|
||||
width="'. $width .'"
|
||||
height="'. $height .'"
|
||||
|
@ -1244,7 +1244,7 @@ function parseFilter(&$filter, $saveToSession=false, $querySep='&') {
|
|||
if ( !isset($term['val']) ) $term['val'] = '';
|
||||
foreach ( preg_split('/["\'\s]*?,["\'\s]*?/', preg_replace('/^["\']+?(.+)["\']+?$/', '$1', $term['val'])) as $value ) {
|
||||
switch ( $term['attr'] ) {
|
||||
|
||||
|
||||
case 'AlarmedZoneId':
|
||||
$value = '(SELECT * FROM Stats WHERE EventId=E.Id AND ZoneId='.$value.')';
|
||||
break;
|
||||
|
@ -1386,7 +1386,7 @@ function parseFilter(&$filter, $saveToSession=false, $querySep='&') {
|
|||
function addFilterTerm($filter, $position, $term=false) {
|
||||
if ( $position < 0 )
|
||||
$position = 0;
|
||||
|
||||
|
||||
if ( !isset($filter['Query']['terms']) )
|
||||
$filter['Query']['terms'] = array();
|
||||
else if ( $position > count($filter['Query']['terms']) )
|
||||
|
@ -1578,7 +1578,7 @@ function systemStats() {
|
|||
function getcpus() {
|
||||
|
||||
if ( is_readable('/proc/cpuinfo') ) { # Works on Linux
|
||||
preg_match_all('/^processor/m', file_get_contents('/proc/cpuinfo'), $matches);
|
||||
preg_match_all('/^processor/m', file_get_contents('/proc/cpuinfo'), $matches);
|
||||
$num_cpus = count($matches[0]);
|
||||
} else { # Works on BSD
|
||||
$matches = explode(':', shell_exec('sysctl hw.ncpu'));
|
||||
|
@ -1588,8 +1588,8 @@ function getcpus() {
|
|||
return $num_cpus;
|
||||
}
|
||||
|
||||
// Function to fix a problem whereby the built in PHP session handling
|
||||
// features want to put the sid as a hidden field after the form or
|
||||
// Function to fix a problem whereby the built in PHP session handling
|
||||
// features want to put the sid as a hidden field after the form or
|
||||
// fieldset tag, neither of which will work with strict XHTML Basic.
|
||||
function sidField() {
|
||||
if ( SID ) {
|
||||
|
@ -1684,7 +1684,7 @@ function linesIntersect($line1, $line2) {
|
|||
return false;
|
||||
}
|
||||
} elseif ( $b1 == $b2 ) {
|
||||
// Colinear, must overlap due to box check, intersect?
|
||||
// Colinear, must overlap due to box check, intersect?
|
||||
if ( $debug ) echo 'Intersecting, colinear<br>';
|
||||
return true;
|
||||
} else {
|
||||
|
@ -1692,7 +1692,7 @@ function linesIntersect($line1, $line2) {
|
|||
if ( $debug ) echo 'Not intersecting, parallel<br>';
|
||||
return false;
|
||||
}
|
||||
} elseif ( !$dx1 ) { // Line 1 is vertical
|
||||
} elseif ( !$dx1 ) { // Line 1 is vertical
|
||||
$y = ( $m2 * $line1[0]['x'] ) * $b2;
|
||||
if ( $y >= $min_y1 && $y <= $max_y1 ) {
|
||||
if ( $debug ) echo "Intersecting, at y $y<br>";
|
||||
|
@ -1701,7 +1701,7 @@ function linesIntersect($line1, $line2) {
|
|||
if ( $debug ) echo "Not intersecting, out of range at y $y<br>";
|
||||
return false;
|
||||
}
|
||||
} elseif ( !$dx2 ) { // Line 2 is vertical
|
||||
} elseif ( !$dx2 ) { // Line 2 is vertical
|
||||
$y = ( $m1 * $line2[0]['x'] ) * $b1;
|
||||
if ( $y >= $min_y2 && $y <= $max_y2 ) {
|
||||
if ( $debug ) echo "Intersecting, at y $y<br>";
|
||||
|
@ -1712,7 +1712,7 @@ function linesIntersect($line1, $line2) {
|
|||
}
|
||||
} else { // Both lines are vertical
|
||||
if ( $line1[0]['x'] == $line2[0]['x'] ) {
|
||||
// Colinear, must overlap due to box check, intersect?
|
||||
// Colinear, must overlap due to box check, intersect?
|
||||
if ( $debug ) echo 'Intersecting, vertical, colinear<br>';
|
||||
return true;
|
||||
} else {
|
||||
|
@ -2169,7 +2169,7 @@ function jsonDecode($value) {
|
|||
} else if ( $value[$i] == ':' ) {
|
||||
$out .= '=>';
|
||||
} else {
|
||||
$out .= $value[$i];
|
||||
$out .= $value[$i];
|
||||
}
|
||||
} else if ( !$unescape ) {
|
||||
if ( $value[$i] == '\\' )
|
||||
|
@ -2311,7 +2311,8 @@ function validHtmlStr($input) {
|
|||
function getStreamHTML($monitor, $options = array()) {
|
||||
|
||||
if ( isset($options['scale']) ) {
|
||||
if ( $options['scale'] and ( $options['scale'] != 'auto' ) ) {
|
||||
if ( $options['scale'] != 'auto' && $options['scale'] != '0' and $options['scale'] != '' ) {
|
||||
ZM\Logger::Debug("Setting dimensions from scale:".$options['scale']);
|
||||
$options['width'] = reScale($monitor->ViewWidth(), $options['scale']).'px';
|
||||
$options['height'] = reScale($monitor->ViewHeight(), $options['scale']).'px';
|
||||
} else {
|
||||
|
@ -2363,8 +2364,8 @@ function getStreamHTML($monitor, $options = array()) {
|
|||
return getImageStreamHTML( 'liveStream'.$monitor->Id(), $streamSrc, $options['width'], $options['height'], $monitor->Name());
|
||||
elseif ( canStreamApplet() )
|
||||
// Helper, empty widths and heights really don't work.
|
||||
return getHelperStream( 'liveStream'.$monitor->Id(), $streamSrc,
|
||||
$options['width'] ? $options['width'] : $monitor->ViewWidth(),
|
||||
return getHelperStream( 'liveStream'.$monitor->Id(), $streamSrc,
|
||||
$options['width'] ? $options['width'] : $monitor->ViewWidth(),
|
||||
$options['height'] ? $options['height'] : $monitor->ViewHeight(),
|
||||
$monitor->Name());
|
||||
} else {
|
||||
|
@ -2423,8 +2424,8 @@ function check_timezone() {
|
|||
'TIME_FORMAT(TIMEDIFF(NOW(), UTC_TIMESTAMP),\'%H%i\')'
|
||||
));
|
||||
|
||||
#Logger::Debug("System timezone offset determine to be: $sys_tzoffset,\x20
|
||||
#PHP timezone offset determine to be: $php_tzoffset,\x20
|
||||
#Logger::Debug("System timezone offset determine to be: $sys_tzoffset,\x20
|
||||
#PHP timezone offset determine to be: $php_tzoffset,\x20
|
||||
#Mysql timezone offset determine to be: $mysql_tzoffset
|
||||
#");
|
||||
|
||||
|
@ -2439,7 +2440,7 @@ function check_timezone() {
|
|||
|
||||
}
|
||||
|
||||
function unparse_url($parsed_url, $substitutions = array() ) {
|
||||
function unparse_url($parsed_url, $substitutions = array() ) {
|
||||
$fields = array('scheme','host','port','user','pass','path','query','fragment');
|
||||
|
||||
foreach ( $fields as $field ) {
|
||||
|
@ -2447,16 +2448,16 @@ function unparse_url($parsed_url, $substitutions = array() ) {
|
|||
$parsed_url[$field] = $substitutions[$field];
|
||||
}
|
||||
}
|
||||
$scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
|
||||
$host = isset($parsed_url['host']) ? $parsed_url['host'] : '';
|
||||
$port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '';
|
||||
$user = isset($parsed_url['user']) ? $parsed_url['user'] : '';
|
||||
$pass = isset($parsed_url['pass']) ? ':' . $parsed_url['pass'] : '';
|
||||
$pass = ($user || $pass) ? "$pass@" : '';
|
||||
$path = isset($parsed_url['path']) ? $parsed_url['path'] : '';
|
||||
$query = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : '';
|
||||
$fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : '';
|
||||
return "$scheme$user$pass$host$port$path$query$fragment";
|
||||
$scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
|
||||
$host = isset($parsed_url['host']) ? $parsed_url['host'] : '';
|
||||
$port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '';
|
||||
$user = isset($parsed_url['user']) ? $parsed_url['user'] : '';
|
||||
$pass = isset($parsed_url['pass']) ? ':' . $parsed_url['pass'] : '';
|
||||
$pass = ($user || $pass) ? $pass.'@' : '';
|
||||
$path = isset($parsed_url['path']) ? $parsed_url['path'] : '';
|
||||
$query = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : '';
|
||||
$fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : '';
|
||||
return $scheme.$user.$pass.$host.$port.$path.$query.$fragment;
|
||||
}
|
||||
|
||||
// PP - POST request handler for PHP which does not need extensions
|
||||
|
|
|
@ -52,6 +52,14 @@ require_once('includes/Event.php');
|
|||
require_once('includes/Group.php');
|
||||
require_once('includes/Monitor.php');
|
||||
|
||||
// Useful debugging lines for mobile devices
|
||||
if ( ZM\Logger::fetch()->debugOn() ) {
|
||||
ob_start();
|
||||
phpinfo(INFO_VARIABLES);
|
||||
ZM\Logger::Debug(ob_get_contents());
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
global $Servers;
|
||||
$Servers = ZM\Server::find();
|
||||
|
||||
|
|
|
@ -87,6 +87,7 @@ $SLANG = array(
|
|||
'Actual' => 'Actual',
|
||||
'AddNewControl' => 'Add New Control',
|
||||
'AddNewMonitor' => 'Add',
|
||||
'AddMonitorDisabled' => 'Your user is not allowed to add a new monitor',
|
||||
'AddNewServer' => 'Add New Server',
|
||||
'AddNewStorage' => 'Add New Storage',
|
||||
'AddNewUser' => 'Add New User',
|
||||
|
|
|
@ -83,8 +83,8 @@ $SLANG = array(
|
|||
'Actual' => 'Attuale',
|
||||
'AddNewControl' => 'Aggiungi nuovo Controllo',
|
||||
'AddNewMonitor' => 'Aggiungi nuovo Monitor',
|
||||
'AddNewServer' => 'Add New Server', // Added - 2018-08-30
|
||||
'AddNewStorage' => 'Add New Storage', // Added - 2018-08-30
|
||||
'AddNewServer' => 'Aggiungi nuovo Server', // Added - 2018-08-30
|
||||
'AddNewStorage' => 'Aggiungi nuovo Storage', // Added - 2018-08-30
|
||||
'AddNewUser' => 'Aggiungi nuovo Utente',
|
||||
'AddNewZone' => 'Aggiungi nuova Zona',
|
||||
'Alarm' => 'Allarme',
|
||||
|
@ -103,7 +103,7 @@ $SLANG = array(
|
|||
'Apply' => 'Applica',
|
||||
'ApplyingStateChange' => 'Sto applicando le modifiche',
|
||||
'ArchArchived' => 'Archiviato',
|
||||
'ArchUnarchived' => 'Non archiviare',
|
||||
'ArchUnarchived' => 'Non archiviato',
|
||||
'Archive' => 'Archivio',
|
||||
'Archived' => 'Archiviato',
|
||||
'Area' => 'Area',
|
||||
|
@ -142,14 +142,14 @@ $SLANG = array(
|
|||
'AutoStopTimeout' => 'Auto Stop Timeout',
|
||||
'Available' => 'Disponibile', // Added - 2009-03-31
|
||||
'AvgBrScore' => 'Punteggio<br/>medio',
|
||||
'Background' => 'Background',
|
||||
'Background' => 'Sfondo',
|
||||
'BackgroundFilter' => 'Esegui filtro in background',
|
||||
'BadAlarmFrameCount' => 'Il numero di frame di un allarme deve essere un numero intero superiore a uno',
|
||||
'BadAlarmMaxFPS' => 'Il numero massimo di FPS dell\'allarme deve essere un numero intero positivo o un valore in virgola mobile',
|
||||
'BadAnalysisFPS' => 'Analysis FPS must be a positive integer or floating point value', // Added - 2015-07-22
|
||||
'BadAnalysisUpdateDelay'=> 'Analysis update delay must be set to an integer of zero or more', // Added - 2015-07-23
|
||||
'BadAlarmFrameCount' => 'Il numero di immagini per secondo (FPS) di un allarme deve essere un numero intero superiore a uno',
|
||||
'BadAlarmMaxFPS' => 'Il numero massimo di immagini per secondo (FPS) dell\'allarme deve essere un numero intero positivo o un valore in virgola mobile',
|
||||
'BadAnalysisFPS' => 'Il numero di immagini per secondo (FPS) di analisi deve essere un numero intero positivo o un valore in virgola mobile', // Added - 2015-07-22
|
||||
'BadAnalysisUpdateDelay'=> 'Il ritardo di aggiornamento dell\'analisi deve essere impostato su un numero intero pari a zero o superiore', // Added - 2015-07-23
|
||||
'BadChannel' => 'Il canale deve essere settato con un numero intero uguale o maggiore di zero',
|
||||
'BadColours' => 'Target colour must be set to a valid value', // Added - 2011-06-15
|
||||
'BadColours' => 'Il colore target deve essere impostato su un valore valido', // Added - 2011-06-15
|
||||
'BadDevice' => 'Il dispositivo deve essere impostato con un valore valido',
|
||||
'BadFPSReportInterval' => 'L\'intervallo di FPS per i report deve essere un numero intero superiore a 0',
|
||||
'BadFormat' => 'Il formato deve essere impostato con un numero intero come 0 o maggiore',
|
||||
|
@ -160,24 +160,24 @@ $SLANG = array(
|
|||
'BadLabelX' => 'L\'etichetta della coordinata X deve essere un numero intero pari a 0 o maggiore',
|
||||
'BadLabelY' => 'L\'etichetta della coordinata Y deve essere un numero intero pari a 0 o maggiore',
|
||||
'BadMaxFPS' => 'I frame per secondo (FPS) massimi devono essere un numero intero positivo o un valore in virgola mobile',
|
||||
'BadMotionFrameSkip' => 'Motion Frame skip count must be an integer of zero or more',
|
||||
'BadMotionFrameSkip' => 'Il conteggio dei salti di Motion Frame deve essere un numero intero pari a zero o superiore',
|
||||
'BadNameChars' => 'I nomi possono contenere solo caratteri alfanumerici più i caratteri - e _',
|
||||
'BadPalette' => 'La palette dei colori deve essere impostata ad un valore valido', // Added - 2009-03-31
|
||||
'BadPalette' => 'La tavolozza dei colori deve essere impostata ad un valore valido', // Added - 2009-03-31
|
||||
'BadPath' => 'Il percorso deve essere impostato con un valore valido',
|
||||
'BadPort' => 'La porta deve essere settata con un valore valido',
|
||||
'BadPostEventCount' => 'Il buffer d\'immagine successivo ad un evento deve essere un numero maggiore o uguale a zero',
|
||||
'BadPreEventCount' => 'Il buffer d\'immagine antecedente ad un evento deve essere minimo 0 e comunque minore della dimensione del buffer d\'immagine',
|
||||
'BadRefBlendPerc' => 'La percentuale di miscela di riferimento deve essere un intero positivo',
|
||||
'BadSectionLength' => 'La lunghezza della sezione deve essere un numero intero pari a 30 o maggiore',
|
||||
'BadSignalCheckColour' => 'Signal check colour must be a valid RGB colour string',
|
||||
'BadSourceType' => 'Source Type \"Web Site\" requires the Function to be set to \"Monitor\"', // Added - 2018-08-30
|
||||
'BadStreamReplayBuffer'=> 'Stream replay buffer must be an integer of zero or more',
|
||||
'BadSignalCheckColour' => 'Il colore di controllo del segnale deve essere una stringa di colore RGB valida',
|
||||
'BadSourceType' => 'Il tipo di origine \"Sito Web\" richiede che la funzione sia impostata su \"Monitor\"', // Added - 2018-08-30
|
||||
'BadStreamReplayBuffer'=> 'Il buffer di riproduzione dello stream deve essere un numero intero pari a zero o superiore',
|
||||
'BadWarmupCount' => 'Il numero di frame di allarme deve essere un numero intero maggiore o uguale a zero',
|
||||
'BadWebColour' => 'L\'identificativo del colore deve essere una stringa valida',
|
||||
'BadWebSitePath' => 'Please enter a complete website url, including the http:// or https:// prefix.', // Added - 2018-08-30
|
||||
'BadWebSitePath' => 'Inserisci un URL completo del sito Web, incluso il prefisso http: // o https: //.', // Added - 2018-08-30
|
||||
'BadWidth' => 'La larghezza deve essere impostata con un valore valido',
|
||||
'Bandwidth' => 'Banda',
|
||||
'BandwidthHead' => 'Bandwidth', // This is the end of the bandwidth status on the top of the console, different in many language due to phrasing
|
||||
'BandwidthHead' => 'Larghezza di banda', // This is the end of the bandwidth status on the top of the console, different in many language due to phrasing
|
||||
'BlobPx' => 'Blob Px',
|
||||
'BlobSizes' => 'Dimensioni Blob',
|
||||
'Blobs' => 'Blobs',
|
||||
|
@ -228,15 +228,15 @@ $SLANG = array(
|
|||
'CancelForcedAlarm' => 'Annulla Allarme Forzato',
|
||||
'CaptureHeight' => 'Altezza img catturata',
|
||||
'CaptureMethod' => 'Metodo di cattura', // Added - 2009-02-08
|
||||
'CapturePalette' => 'Paletta img Catturata',
|
||||
'CaptureResolution' => 'Capture Resolution', // Added - 2015-04-18
|
||||
'CapturePalette' => 'Paletta img catturata',
|
||||
'CaptureResolution' => 'Risoluzione di cattura', // Added - 2015-04-18
|
||||
'CaptureWidth' => 'Larghezza img Catturata',
|
||||
'Cause' => 'Causa',
|
||||
'CheckMethod' => 'Metodo di Controllo Allarme',
|
||||
'ChooseDetectedCamera' => 'Scegli telecamera rilevata', // Added - 2009-03-31
|
||||
'ChooseFilter' => 'Scegli Filtro',
|
||||
'ChooseLogFormat' => 'Choose a log format', // Added - 2011-06-17
|
||||
'ChooseLogSelection' => 'Choose a log selection', // Added - 2011-06-17
|
||||
'ChooseLogFormat' => 'Scegli un formato di registro', // Added - 2011-06-17
|
||||
'ChooseLogSelection' => 'Scegli una selezione del registro', // Added - 2011-06-17
|
||||
'ChoosePreset' => 'Scegli Preset',
|
||||
'Clear' => 'Clear', // Added - 2011-06-16
|
||||
'CloneMonitor' => 'Clone', // Added - 2018-08-30
|
||||
|
@ -301,12 +301,12 @@ $SLANG = array(
|
|||
'DonateRemindNever' => 'No, io non voglio donare, non lo faro\' mai',
|
||||
'DonateRemindWeek' => 'Non ancora, ricordamelo ancora tra 1 settimana',
|
||||
'DonateYes' => 'Si,mi piacerebbe donare qualcosa ora',
|
||||
'Download' => 'Download',
|
||||
'DownloadVideo' => 'Download Video', // Added - 2018-08-30
|
||||
'DuplicateMonitorName' => 'Il nome del monitor e\' gia\' presente', // Added - 2009-03-31
|
||||
'Download' => 'Scarica',
|
||||
'DownloadVideo' => 'Scarica video', // Added - 2018-08-30
|
||||
'DuplicateMonitorName' => 'Il nome del monitor è già presente', // Added - 2009-03-31
|
||||
'Duration' => 'Durata',
|
||||
'Edit' => 'Modifica',
|
||||
'EditLayout' => 'Edit Layout', // Added - 2018-08-30
|
||||
'EditLayout' => 'Modifica Layout', // Added - 2018-08-30
|
||||
'Email' => 'Email',
|
||||
'EnableAlarms' => 'Abilita Allarmi',
|
||||
'Enabled' => 'Attivo',
|
||||
|
@ -323,7 +323,7 @@ $SLANG = array(
|
|||
'Events' => 'Eventi',
|
||||
'Exclude' => 'Escludi',
|
||||
'Execute' => 'Esegui',
|
||||
'Exif' => 'Embed EXIF data into image', // Added - 2018-08-30
|
||||
'Exif' => 'Includi dati EXIF nell\'immagine', // Added - 2018-08-30
|
||||
'Export' => 'Esporta',
|
||||
'ExportDetails' => 'Esp. dettagli eventi',
|
||||
'ExportFailed' => 'Esp. Fallita ',
|
||||
|
@ -346,17 +346,17 @@ $SLANG = array(
|
|||
'Feed' => 'Feed',
|
||||
'Ffmpeg' => 'Ffmpeg', // Added - 2009-02-08
|
||||
'File' => 'File',
|
||||
'Filter' => 'Filter', // Added - 2015-04-18
|
||||
'Filter' => 'Filtro', // Added - 2015-04-18
|
||||
'FilterArchiveEvents' => 'Archivia gli eventi',
|
||||
'FilterDeleteEvents' => 'Elimina gli eventi',
|
||||
'FilterEmailEvents' => 'Invia dettagli via email',
|
||||
'FilterExecuteEvents' => 'Esegui un comando',
|
||||
'FilterLog' => 'Filter log', // Added - 2015-04-18
|
||||
'FilterMessageEvents' => 'Invia dettagli tramite messaggio',
|
||||
'FilterMoveEvents' => 'Move all matches', // Added - 2018-08-30
|
||||
'FilterMoveEvents' => 'Sposta tutti gli eventi', // Added - 2018-08-30
|
||||
'FilterPx' => 'Px Filtro',
|
||||
'FilterUnset' => 'Devi specificare altezza e larghezza per il filtro',
|
||||
'FilterUpdateDiskSpace'=> 'Update used disk space', // Added - 2018-08-30
|
||||
'FilterUpdateDiskSpace'=> 'Aggiorna spazio disco utilizzato', // Added - 2018-08-30
|
||||
'FilterUploadEvents' => 'Fai upload eventi (FTP)',
|
||||
'FilterVideoEvents' => 'Crea video per tutte le corrispondenze',
|
||||
'Filters' => 'Filtri',
|
||||
|
@ -381,9 +381,9 @@ $SLANG = array(
|
|||
'Function' => 'Funzione',
|
||||
'Gain' => 'Gain',
|
||||
'General' => 'Generale',
|
||||
'GenerateDownload' => 'Generate Download', // Added - 2018-08-30
|
||||
'GenerateVideo' => 'Genera Video',
|
||||
'GeneratingVideo' => 'Sto generando il Video',
|
||||
'GenerateDownload' => 'Genera download', // Added - 2018-08-30
|
||||
'GenerateVideo' => 'Genera video',
|
||||
'GeneratingVideo' => 'Sto generando il video',
|
||||
'GoToZoneMinder' => 'Vai su zoneminder.com',
|
||||
'Grey' => 'Grigio',
|
||||
'Group' => 'Gruppo',
|
||||
|
@ -402,7 +402,7 @@ $SLANG = array(
|
|||
'High' => 'Alta',
|
||||
'HighBW' => 'Banda Alta',
|
||||
'Home' => 'Home',
|
||||
'Hostname' => 'Hostname', // Added - 2018-08-30
|
||||
'Hostname' => 'Nome Host', // Added - 2018-08-30
|
||||
'Hour' => 'Ora',
|
||||
'Hue' => 'Tinta',
|
||||
'Id' => 'Id',
|
||||
|
@ -420,14 +420,14 @@ $SLANG = array(
|
|||
'Language' => 'Linguaggio',
|
||||
'Last' => 'Ultimo',
|
||||
'Layout' => 'Layout', // Added - 2009-02-08
|
||||
'Level' => 'Level', // Added - 2011-06-16
|
||||
'Level' => 'Livello', // Added - 2011-06-16
|
||||
'Libvlc' => 'Libvlc',
|
||||
'LimitResultsPost' => 'risultati;', // This is used at the end of the phrase 'Limit to first N results only'
|
||||
'LimitResultsPre' => 'Limita ai primi', // This is used at the beginning of the phrase 'Limit to first N results only'
|
||||
'Line' => 'Line', // Added - 2011-06-16
|
||||
'LinkedMonitors' => 'Monitor Collegati',
|
||||
'List' => 'Lista',
|
||||
'ListMatches' => 'List Matches', // Added - 2018-08-30
|
||||
'ListMatches' => 'Elenca le corrispondenze', // Added - 2018-08-30
|
||||
'Load' => 'Carico Sistema',
|
||||
'Local' => 'Locale',
|
||||
'Log' => 'Log', // Added - 2011-06-16
|
||||
|
@ -505,12 +505,12 @@ $SLANG = array(
|
|||
'MinZoomSpeed' => 'Velocita\' minima dello zoom',
|
||||
'MinZoomStep' => 'Step minimo dello zoom',
|
||||
'Misc' => 'Altro',
|
||||
'Mode' => 'Mode', // Added - 2015-04-18
|
||||
'Mode' => 'Modalità', // Added - 2015-04-18
|
||||
'Monitor' => 'Monitor',
|
||||
'MonitorIds' => 'Monitor Ids',
|
||||
'MonitorPreset' => 'Monitor Presenti',
|
||||
'MonitorPresetIntro' => 'Selezionare un appropriato pre settaggio dalla lista riportata qui sotto.<br><br>Per favore notare che questo potrebbe sovrascrivere ogni valore che hai già configurato su questo monitor.<br><br>',
|
||||
'MonitorProbe' => 'Monitor Probe', // Added - 2009-03-31
|
||||
'MonitorProbe' => 'Prova Monitor', // Added - 2009-03-31
|
||||
'MonitorProbeIntro' => 'The list below shows detected analog and network cameras and whether they are already being used or available for selection.<br/><br/>Select the desired entry from the list below.<br/><br/>Please note that not all cameras may be detected and that choosing a camera here may overwrite any values you already have configured for the current monitor.<br/><br/>', // Added - 2009-03-31
|
||||
'Monitors' => 'Monitors',
|
||||
'Montage' => 'Montaggio',
|
||||
|
@ -523,7 +523,7 @@ $SLANG = array(
|
|||
'Mtg3widgrd' => '3-wide grid', // Added 2013.08.15.
|
||||
'Mtg3widgrx' => '3-wide grid, scaled, enlarge on alarm', // Added 2013.08.15.
|
||||
'Mtg4widgrd' => '4-wide grid', // Added 2013.08.15.
|
||||
'MtgDefault' => 'Default', // Added 2013.08.15.
|
||||
'MtgDefault' => 'Predefinito', // Added 2013.08.15.
|
||||
'MustBeGe' => 'deve essere superiore a',
|
||||
'MustBeLe' => 'deve essere inferiore o pari a',
|
||||
'MustConfirmPassword' => 'Devi confermare la password',
|
||||
|
@ -541,10 +541,10 @@ $SLANG = array(
|
|||
'Next' => 'Prossimo',
|
||||
'No' => 'No',
|
||||
'NoDetectedCameras' => 'Nessuna telecamera rilevata', // Added - 2009-03-31
|
||||
'NoDetectedProfiles' => 'No Detected Profiles', // Added - 2018-08-30
|
||||
'NoDetectedProfiles' => 'Nessun profilo rilevato', // Added - 2018-08-30
|
||||
'NoFramesRecorded' => 'Non ci sono immagini salvate per questo evento',
|
||||
'NoGroup' => 'Nessun gruppo', // Added - 2009-02-08
|
||||
'NoSavedFilters' => 'NessunFiltroSalvato',
|
||||
'NoSavedFilters' => 'Nessun filtro salvato',
|
||||
'NoStatisticsRecorded' => 'Non ci sono statistiche salvate per questo evento/immagine',
|
||||
'None' => 'Nessuno',
|
||||
'NoneAvailable' => 'Nessuno disponibile',
|
||||
|
@ -553,15 +553,15 @@ $SLANG = array(
|
|||
'NumPresets' => 'Num Presets',
|
||||
'Off' => 'Off',
|
||||
'On' => 'On',
|
||||
'OnvifCredentialsIntro'=> 'Please supply user name and password for the selected camera.<br/>If no user has been created for the camera then the user given here will be created with the given password.<br/><br/>', // Added - 2015-04-18
|
||||
'OnvifCredentialsIntro'=> 'Fornire nome utente e password per la telecamera selezionata.<br/>Se non è stato creato alcun utente per la videocamera, l\'utente qui indicato verrà creato con la password specificata.<br/><br/>', // Added - 2015-04-18
|
||||
'OnvifProbe' => 'ONVIF', // Added - 2015-04-18
|
||||
'OnvifProbeIntro' => 'The list below shows detected ONVIF cameras and whether they are already being used or available for selection.<br/><br/>Select the desired entry from the list below.<br/><br/>Please note that not all cameras may be detected and that choosing a camera here may overwrite any values you already have configured for the current monitor.<br/><br/>', // Added - 2015-04-18
|
||||
'OnvifProbeIntro' => 'L\'elenco seguente mostra le telecamere ONVIF rilevate e se sono già in uso o disponibili per la selezione. Selezionare la voce desiderata dall\'elenco seguente. Si noti che non tutte le telecamere potrebbero essere rilevate e che la scelta di una telecamera qui può sovrascrivere tutti i valori già configurati per il monitor corrente.', // Added - 2015-04-18
|
||||
'OpEq' => 'uguale a',
|
||||
'OpGt' => 'maggiore di',
|
||||
'OpGtEq' => 'maggiore o uguale a',
|
||||
'OpIn' => 'impostato',
|
||||
'OpIs' => 'is', // Added - 2018-08-30
|
||||
'OpIsNot' => 'is not', // Added - 2018-08-30
|
||||
'OpIs' => 'è', // Added - 2018-08-30
|
||||
'OpIsNot' => 'non è', // Added - 2018-08-30
|
||||
'OpLt' => 'minore di',
|
||||
'OpLtEq' => 'minore o uguale a',
|
||||
'OpMatches' => 'corrisponde',
|
||||
|
@ -571,7 +571,7 @@ $SLANG = array(
|
|||
'Open' => 'Apri',
|
||||
'OptionHelp' => 'Opzioni di Aiuto',
|
||||
'OptionRestartWarning' => 'Queste modifiche potrebbero essere attive solo dopo un riavvio del sistema. Riavviare ZoneMinder.',
|
||||
'OptionalEncoderParam' => 'Optional Encoder Parameters', // Added - 2018-08-30
|
||||
'OptionalEncoderParam' => 'Parametri Encoder opzionali', // Added - 2018-08-30
|
||||
'Options' => 'Opzioni',
|
||||
'OrEnterNewName' => 'o inserisci un nuovo nome',
|
||||
'Order' => 'Ordine',
|
||||
|
@ -605,24 +605,24 @@ $SLANG = array(
|
|||
'Presets' => 'Presets',
|
||||
'Prev' => 'Prec',
|
||||
'Probe' => 'Prova la telecamera', // Added - 2009-03-31
|
||||
'ProfileProbe' => 'Stream Probe', // Added - 2015-04-18
|
||||
'ProfileProbeIntro' => 'The list below shows the existing stream profiles of the selected camera .<br/><br/>Select the desired entry from the list below.<br/><br/>Please note that ZoneMinder cannot configure additional profiles and that choosing a camera here may overwrite any values you already have configured for the current monitor.<br/><br/>', // Added - 2015-04-18
|
||||
'Progress' => 'Progress', // Added - 2015-04-18
|
||||
'Protocol' => 'Protocol',
|
||||
'ProfileProbe' => 'Prova lo stream', // Added - 2015-04-18
|
||||
'ProfileProbeIntro' => 'L\'elenco seguente mostra i profili di streaming esistenti della telecamera selezionata.<br/><br/>Selezionare la voce desiderata dall\'elenco seguente.<br/><br/>Si noti che ZoneMinder non è in grado di configurare profili aggiuntivi e che la scelta di una telecamera qui può sovrascrivere qualsiasi valore già configurato per il monitor corrente.<br/><br/>', // Added - 2015-04-18
|
||||
'Progress' => 'Progresso', // Added - 2015-04-18
|
||||
'Protocol' => 'Protocollo',
|
||||
'RTSPDescribe' => 'Use RTSP Response Media URL', // Added - 2018-08-30
|
||||
'RTSPTransport' => 'RTSP Transport Protocol', // Added - 2018-08-30
|
||||
'Rate' => 'Velocita\'',
|
||||
'Rate' => 'Velocità',
|
||||
'Real' => 'Reale',
|
||||
'RecaptchaWarning' => 'Your reCaptcha secret key is invalid. Please correct it, or reCaptcha will not work', // Added - 2018-08-30
|
||||
'RecaptchaWarning' => 'La chiave segreta reCaptcha non è valida. Correggila o reCaptcha non funzionerà', // Added - 2018-08-30
|
||||
'Record' => 'Registra',
|
||||
'RecordAudio' => 'Whether to store the audio stream when saving an event.', // Added - 2018-08-30
|
||||
'RecordAudio' => 'Memorizza flusso audio quando salva un evento.', // Added - 2018-08-30
|
||||
'RefImageBlendPct' => 'Riferimento Miscela Immagine percentuale',
|
||||
'Refresh' => 'Aggiorna',
|
||||
'Remote' => 'Remoto',
|
||||
'RemoteHostName' => 'Nome dell\'Host Remoto',
|
||||
'RemoteHostPath' => 'Percorso dell\'Host Remoto',
|
||||
'RemoteHostPort' => 'Porta dell\'Host Remoto',
|
||||
'RemoteHostSubPath' => 'Remote Host SubPath', // Added - 2009-02-08
|
||||
'RemoteHostSubPath' => 'SubPath host remoto', // Added - 2009-02-08
|
||||
'RemoteImageColours' => 'Colori delle immagini Remote',
|
||||
'RemoteMethod' => 'Metodo Remoto', // Added - 2009-02-08
|
||||
'RemoteProtocol' => 'Protocollo Remoto', // Added - 2009-02-08
|
||||
|
@ -631,7 +631,7 @@ $SLANG = array(
|
|||
'ReplayAll' => 'All Events',
|
||||
'ReplayGapless' => 'Gapless Events',
|
||||
'ReplaySingle' => 'Single Event',
|
||||
'ReportEventAudit' => 'Audit Events Report', // Added - 2018-08-30
|
||||
'ReportEventAudit' => 'Rapporto Eventi di controllo', // Added - 2018-08-30
|
||||
'Reset' => 'Resetta',
|
||||
'ResetEventCounts' => 'Resetta Contatore Eventi',
|
||||
'Restart' => 'Riavvia',
|
||||
|
@ -643,21 +643,21 @@ $SLANG = array(
|
|||
'Rewind' => 'Riavvolgi',
|
||||
'RotateLeft' => 'Ruota a Sinista',
|
||||
'RotateRight' => 'Ruota a Destra',
|
||||
'RunLocalUpdate' => 'Please run zmupdate.pl to update', // Added - 2011-05-25
|
||||
'RunLocalUpdate' => 'Eseguire zmupdate.pl per l\'aggiornamento', // Added - 2011-05-25
|
||||
'RunMode' => 'Modalita\' funzionamento',
|
||||
'RunState' => 'Stato di funzionamento',
|
||||
'Running' => 'Attivo',
|
||||
'Save' => 'Salva',
|
||||
'SaveAs' => 'Salva come',
|
||||
'SaveFilter' => 'salva Filtro',
|
||||
'SaveJPEGs' => 'Save JPEGs', // Added - 2018-08-30
|
||||
'SaveFilter' => 'Salva Filtro',
|
||||
'SaveJPEGs' => 'Salva JPEGs', // Added - 2018-08-30
|
||||
'Scale' => 'Scala',
|
||||
'Score' => 'Punteggio',
|
||||
'Secs' => 'Secs',
|
||||
'Sectionlength' => 'Lunghezza Sezione',
|
||||
'Select' => 'Seleziona',
|
||||
'SelectFormat' => 'Select Format', // Added - 2011-06-17
|
||||
'SelectLog' => 'Select Log', // Added - 2011-06-17
|
||||
'SelectFormat' => 'Seleziona Formato', // Added - 2011-06-17
|
||||
'SelectLog' => 'Seleziona Log', // Added - 2011-06-17
|
||||
'SelectMonitors' => 'Monitor Selezionati',
|
||||
'SelfIntersecting' => 'I vertici del poligono non devono intersecarsi',
|
||||
'Set' => 'Imposta',
|
||||
|
@ -666,10 +666,10 @@ $SLANG = array(
|
|||
'Settings' => 'Impostazioni',
|
||||
'ShowFilterWindow' => 'MostraFinestraFiltri',
|
||||
'ShowTimeline' => 'Mostra linea temporale',
|
||||
'SignalCheckColour' => 'Signal Check Colour',
|
||||
'SignalCheckPoints' => 'Signal Check Points', // Added - 2018-08-30
|
||||
'SignalCheckColour' => 'Colore controllo segnale',
|
||||
'SignalCheckPoints' => 'Punti di controllo segnale', // Added - 2018-08-30
|
||||
'Size' => 'grandezza',
|
||||
'SkinDescription' => 'Change the default skin for this computer', // Added - 2011-01-30
|
||||
'SkinDescription' => 'Cambia la skin predefinita per questo computer', // Added - 2011-01-30
|
||||
'Sleep' => 'Sleep',
|
||||
'SortAsc' => 'Cresc',
|
||||
'SortBy' => 'Ordina per',
|
||||
|
@ -692,8 +692,8 @@ $SLANG = array(
|
|||
'StatusRunning' => 'Not Capturing', // Added - 2018-08-30
|
||||
'StatusUnknown' => 'Unknown', // Added - 2018-08-30
|
||||
'Step' => 'Passo',
|
||||
'StepBack' => 'Step Back',
|
||||
'StepForward' => 'Step Forward',
|
||||
'StepBack' => 'Passo indietro',
|
||||
'StepForward' => 'Passo avanti',
|
||||
'StepLarge' => 'Lungo passo',
|
||||
'StepMedium' => 'Medio passo',
|
||||
'StepNone' => 'No passo',
|
||||
|
@ -701,13 +701,13 @@ $SLANG = array(
|
|||
'Stills' => 'Foto',
|
||||
'Stop' => 'Stop',
|
||||
'Stopped' => 'Inattivo',
|
||||
'StorageArea' => 'Storage Area', // Added - 2018-08-30
|
||||
'StorageArea' => 'Area di salvataggio', // Added - 2018-08-30
|
||||
'StorageScheme' => 'Scheme', // Added - 2018-08-30
|
||||
'Stream' => 'Flusso',
|
||||
'StreamReplayBuffer' => 'Stream Replay Image Buffer',
|
||||
'Submit' => 'Accetta',
|
||||
'System' => 'Sistema',
|
||||
'SystemLog' => 'System Log', // Added - 2011-06-16
|
||||
'SystemLog' => 'Log di sistema', // Added - 2011-06-16
|
||||
'TargetColorspace' => 'Target colorspace', // Added - 2015-04-18
|
||||
'Tele' => 'Tele',
|
||||
'Thumbnail' => 'Anteprima',
|
||||
|
@ -716,18 +716,18 @@ $SLANG = array(
|
|||
'TimeDelta' => 'Tempo di Delta',
|
||||
'TimeStamp' => 'Time Stamp',
|
||||
'Timeline' => 'Linea Temporale',
|
||||
'TimelineTip1' => 'Pass your mouse over the graph to view a snapshot image and event details.', // Added 2013.08.15.
|
||||
'TimelineTip2' => 'Click on the coloured sections of the graph, or the image, to view the event.', // Added 2013.08.15.
|
||||
'TimelineTip3' => 'Click on the background to zoom in to a smaller time period based around your click.', // Added 2013.08.15.
|
||||
'TimelineTip4' => 'Use the controls below to zoom out or navigate back and forward through the time range.', // Added 2013.08.15.
|
||||
'TimelineTip1' => 'Passa il mouse sul grafico per visualizzare un\'immagine dell\'istantanea e i dettagli dell\'evento.', // Added 2013.08.15.
|
||||
'TimelineTip2' => 'Fai clic sulle sezioni colorate del grafico o sull\'immagine per visualizzare l\'evento.', // Added 2013.08.15.
|
||||
'TimelineTip3' => 'Fare clic sullo sfondo per ingrandire un periodo di tempo più piccolo basato sul clic.', // Added 2013.08.15.
|
||||
'TimelineTip4' => 'Utilizzare i controlli seguenti per ridurre o spostarsi avanti e indietro nell\'intervallo di tempo.', // Added 2013.08.15.
|
||||
'Timestamp' => 'Timestamp',
|
||||
'TimestampLabelFormat' => 'Formato etichetta timestamp',
|
||||
'TimestampLabelSize' => 'Font Size', // Added - 2018-08-30
|
||||
'TimestampLabelSize' => 'Dimensione carattere', // Added - 2018-08-30
|
||||
'TimestampLabelX' => 'coordinata X etichetta',
|
||||
'TimestampLabelY' => 'coordinata Y etichetta',
|
||||
'Today' => 'Oggi ',
|
||||
'Tools' => 'Strumenti',
|
||||
'Total' => 'Total', // Added - 2011-06-16
|
||||
'Total' => 'Totale', // Added - 2011-06-16
|
||||
'TotalBrScore' => 'Punteggio<br/>Totale',
|
||||
'TrackDelay' => 'Track Delay',
|
||||
'TrackMotion' => 'Track Motion',
|
||||
|
@ -737,10 +737,10 @@ $SLANG = array(
|
|||
'Type' => 'Tipo',
|
||||
'Unarchive' => 'Togli dall\'archivio',
|
||||
'Undefined' => 'Non specificato', // Added - 2009-02-08
|
||||
'Units' => 'Unità',
|
||||
'Units' => 'Unità',
|
||||
'Unknown' => 'Sconosciuto',
|
||||
'Update' => 'Aggiorna',
|
||||
'UpdateAvailable' => 'Un aggiornamento di ZoneMinder è disponibilie.',
|
||||
'UpdateAvailable' => 'Un aggiornamento di ZoneMinder è disponibilie.',
|
||||
'UpdateNotNecessary' => 'Nessun aggiornamento necessario.',
|
||||
'Updated' => 'Updated', // Added - 2011-06-16
|
||||
'Upload' => 'Upload', // Added - 2011-08-23
|
||||
|
@ -769,8 +769,8 @@ $SLANG = array(
|
|||
'VideoGenParms' => 'Parametri Generazione Video',
|
||||
'VideoGenSucceeded' => 'Successo: Generato Video !',
|
||||
'VideoSize' => 'Dimensioni Video',
|
||||
'VideoWriter' => 'Video Writer', // Added - 2018-08-30
|
||||
'View' => 'vedi',
|
||||
'VideoWriter' => 'Scrittore video', // Added - 2018-08-30
|
||||
'View' => 'Vedi',
|
||||
'ViewAll' => 'Vedi Tutto',
|
||||
'ViewEvent' => 'Vedi Evento',
|
||||
'ViewPaged' => 'Vedi con paginazione',
|
||||
|
@ -819,7 +819,7 @@ $CLANG = array(
|
|||
'MonitorCount' => '%1$s %2$s', // For example '4 Monitors' (from Vlang below)
|
||||
'MonitorFunction' => 'Funzione Monitor %1$s',
|
||||
'RunningRecentVer' => 'Stai usando la versione più aggiornata di ZoneMinder, v%s.',
|
||||
'VersionMismatch' => 'Version mismatch, system is version %1$s, database is %2$s.', // Added - 2011-05-25
|
||||
'VersionMismatch' => 'Versioni non corrispondenti: versione sistema %1$s, versione database %2$s.', // Added - 2011-05-25
|
||||
);
|
||||
|
||||
// The next section allows you to describe a series of word ending and counts used to
|
||||
|
@ -876,7 +876,7 @@ function zmVlang( $langVarArray, $count )
|
|||
return( $value );
|
||||
}
|
||||
}
|
||||
die( 'Errore, sono incapace di correlare le stringhe del file-linguaggio');
|
||||
die( 'Errore, non sono in grado di correlare le stringhe del file-linguaggio');
|
||||
}
|
||||
|
||||
// This is an version that could be used in the Russian example above
|
||||
|
|
|
@ -864,10 +864,6 @@ $OLANG = array(
|
|||
'Prompt' => "Înregistrare imagini intermediare de diagnosticare, foarte lent",
|
||||
'Help' => "Pe lângă faptul că se pot înregistra statisticile evenimentelor se pot deasemenea înregistra imagini intermediare de diagnosticare care afişează rezultatele diferitelor verificări care au loc când se încearcă determinarea unei posibile alarme. Aceste imagini sunt generate pentru fiecare cadru, zonă şi alarmă, deci impactul asupra performanţei va fi foarte mare. Activaţi această opţiune doar pentru depanare sau analiză şi nu uitaţi să o dezactivaţi."
|
||||
),
|
||||
'CREATE_ANALYSIS_IMAGES' => array(
|
||||
'Prompt' => "Crează imagini analizate cu marcaje ale mişcării",
|
||||
'Help' => "Implicit, în cazul unei alarme, ZoneMinder înregistrează atât imaginile neprelucrate cât şi cele ce au fost analizate şi au zone marcate unde a fost detectată mişcare. Acest lucru poate fi foarte folositor la configurarea zonelor sau în analiza evenimentelor. Acest parametru permite oprirea înregistrării imaginilor cu zone de mişcare marcate."
|
||||
),
|
||||
'OPT_CONTROL' => array(
|
||||
'Prompt' => "Suport camere controlabile (rotire/înclinare/zoom)",
|
||||
'Help' => "ZoneMinder include suport limitat pentru camere controlabile. Sunt incluse câteva protocoale mostră şi pot fi adăugate cu uşurinţă şi altele. Dacă vreţi să controlaţi camerele prin intermediul ZoneMinder selectaţi această opţiune."
|
||||
|
|
|
@ -509,7 +509,7 @@ th.table-th-sort-rev span.table-th-sort-span {
|
|||
}
|
||||
|
||||
#content {
|
||||
width: 96%;
|
||||
width: 100%;
|
||||
margin: 0 auto 8px auto;
|
||||
line-height: 130%;
|
||||
text-align: center;
|
||||
|
|
|
@ -15,6 +15,25 @@ input[name="newMonitor[ControlDevice]"],
|
|||
input[name="newMonitor[ControlAddress]"] {
|
||||
width: 100%;
|
||||
}
|
||||
input[name="newMonitor[AnalysisFPSLimit]"],
|
||||
input[name="newMonitor[MaxFPS]"],
|
||||
input[name="newMonitor[AlarmMaxFPS]"],
|
||||
input[name="newMonitor[V4LCapturesPerFrame]"]{
|
||||
width: 60px;
|
||||
}
|
||||
input[name="newMonitor[Port]"],
|
||||
input[name="newMonitor[Refresh]"],
|
||||
input[name="newMonitor[LabelX]"],
|
||||
input[name="newMonitor[LabelY]"],
|
||||
input[name="newMonitor[ImageBufferCount]"],
|
||||
input[name="newMonitor[WarmupCount]"],
|
||||
input[name="newMonitor[PreEventCount]"],
|
||||
input[name="newMonitor[PostEventCount]"],
|
||||
input[name="newMonitor[StreamReplayBuffer]"],
|
||||
input[name="newMonitor[AlarmFrameCount]"],
|
||||
input[name="newMonitor[AutoStopTimeout]"],
|
||||
input[name="newMonitor[TrackDelay]"],
|
||||
input[name="newMonitor[ReturnDelay]"],
|
||||
input[name="newMonitor[Width]"],
|
||||
input[name="newMonitor[Height]"] {
|
||||
width: 80px;
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
}
|
||||
|
||||
#content {
|
||||
/*
|
||||
width: 99%;
|
||||
*/
|
||||
}
|
||||
|
||||
#monitors:after {
|
||||
|
|
|
@ -178,7 +178,7 @@ getBodyTopHTML();
|
|||
|
||||
<div class="container-fluid">
|
||||
<button type="button" name="addBtn" data-on-click-this="addMonitor"
|
||||
<?php echo (canEdit('Monitors') && !$user['MonitorIds']) ? '' : ' disabled="disabled"' ?>
|
||||
<?php echo (canEdit('Monitors') && !$user['MonitorIds']) ? '' : ' disabled="disabled" title="'.translate('AddMonitorDisabled').'"' ?>
|
||||
>
|
||||
<i class="material-icons md-18">add_circle</i>
|
||||
<?php echo translate('AddNewMonitor') ?>
|
||||
|
|
|
@ -58,32 +58,6 @@ $heights = array(
|
|||
'1080px' => '1080px',
|
||||
);
|
||||
|
||||
session_start();
|
||||
|
||||
if ( isset($_REQUEST['scale']) ) {
|
||||
$options['scale'] = validInt($_REQUEST['scale']);
|
||||
} else if ( isset($_COOKIE['zmCycleScale']) ) {
|
||||
$options['scale'] = $_COOKIE['zmCycleScale'];
|
||||
}
|
||||
|
||||
if ( !isset($options['scale']) )
|
||||
$options['scale'] = 100;
|
||||
|
||||
if ( isset($_COOKIE['zmCycleWidth']) and $_COOKIE['zmCycleWidth'] ) {
|
||||
$_SESSION['zmCycleWidth'] = $options['width'] = $_COOKIE['zmCycleWidth'];
|
||||
#} elseif ( isset($_SESSION['zmCycleWidth']) and $_SESSION['zmCycleWidth'] ) {
|
||||
#$options['width'] = $_SESSION['zmCycleWidth'];
|
||||
} else
|
||||
$options['width'] = '';
|
||||
|
||||
if ( isset($_COOKIE['zmCycleHeight']) and $_COOKIE['zmCycleHeight'] )
|
||||
$_SESSION['zmCycleHeight'] = $options['height'] = $_COOKIE['zmCycleHeight'];
|
||||
#else if ( isset($_SESSION['zmCycleHeight']) and $_SESSION['zmCycleHeight'] )
|
||||
#$options['height'] = $_SESSION['zmCycleHeight'];
|
||||
else
|
||||
$options['height'] = '';
|
||||
|
||||
session_write_close();
|
||||
|
||||
$monIdx = 0;
|
||||
$monitors = array();
|
||||
|
@ -104,7 +78,6 @@ foreach( $displayMonitors as &$row ) {
|
|||
$heights[$row['Height'].'px'] = $row['Height'].'px';
|
||||
}
|
||||
|
||||
$row['connKey'] = generateConnKey();
|
||||
$monitors[] = new ZM\Monitor($row);
|
||||
unset($row);
|
||||
} # end foreach Monitor
|
||||
|
@ -113,6 +86,41 @@ if ( $monitors ) {
|
|||
$monitor = $monitors[$monIdx];
|
||||
$nextMid = $monIdx==(count($monitors)-1)?$monitors[0]->Id():$monitors[$monIdx+1]->Id();
|
||||
}
|
||||
if ( !$monitor ) {
|
||||
ZM\Error('There was no monitor to display.');
|
||||
}
|
||||
$options['connkey'] = generateConnKey();
|
||||
|
||||
session_start();
|
||||
|
||||
if ( isset($_REQUEST['scale']) ) {
|
||||
$options['scale'] = validInt($_REQUEST['scale']);
|
||||
} else if ( isset($_COOKIE['zmCycleScale']) ) {
|
||||
$options['scale'] = $_COOKIE['zmCycleScale'];
|
||||
} else if ( $monitor ) {
|
||||
$options['scale'] = $monitor->DefaultScale();
|
||||
}
|
||||
|
||||
if ( !isset($options['scale']) )
|
||||
$options['scale'] = 100;
|
||||
|
||||
if ( isset($_COOKIE['zmCycleWidth']) and $_COOKIE['zmCycleWidth'] ) {
|
||||
$_SESSION['zmCycleWidth'] = $options['width'] = $_COOKIE['zmCycleWidth'];
|
||||
#} elseif ( isset($_SESSION['zmCycleWidth']) and $_SESSION['zmCycleWidth'] ) {
|
||||
#$options['width'] = $_SESSION['zmCycleWidth'];
|
||||
} else {
|
||||
$options['width'] = '';
|
||||
}
|
||||
|
||||
if ( isset($_COOKIE['zmCycleHeight']) and $_COOKIE['zmCycleHeight'] ) {
|
||||
$_SESSION['zmCycleHeight'] = $options['height'] = $_COOKIE['zmCycleHeight'];
|
||||
#else if ( isset($_SESSION['zmCycleHeight']) and $_SESSION['zmCycleHeight'] )
|
||||
#$options['height'] = $_SESSION['zmCycleHeight'];
|
||||
} else {
|
||||
$options['height'] = '';
|
||||
}
|
||||
|
||||
session_write_close();
|
||||
|
||||
ZM\Logger::Debug(print_r($options,true));
|
||||
|
||||
|
@ -151,7 +159,19 @@ xhtmlHeaders(__FILE__, translate('CycleWatch'));
|
|||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<div class="container-fluid">
|
||||
<div class="row" id="content">
|
||||
<div class="col-sm-2 sidebar">
|
||||
<ul class="nav nav-pills nav-stacked">
|
||||
<?php
|
||||
foreach ( $monitors as $m ) {
|
||||
echo '<li'.( $m->Id() == $monitor->Id() ? ' class="active"' : '' ).'><a href="?view=cycle&mid='.$m->Id().'">'.$m->Name().'</a></li>';
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-sm-10 col-sm-offset-2">
|
||||
|
||||
<div id="imageFeed">
|
||||
<?php
|
||||
if ( $monitor ) {
|
||||
|
@ -170,5 +190,6 @@ xhtmlHeaders(__FILE__, translate('CycleWatch'));
|
|||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php xhtmlFooter() ?>
|
||||
|
|
|
@ -35,7 +35,7 @@ xhtmlHeaders(__FILE__, translate('Error') );
|
|||
<?php echo translate('ContactAdmin') ?>
|
||||
</p>
|
||||
<p>
|
||||
<a href="#" data-on-click="closeWindow"><?php echo translate('Close') ?></a>
|
||||
<button type="button" data-on-click="closeWindow"><?php echo translate('Close') ?></button>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -106,7 +106,7 @@ xhtmlHeaders(__FILE__, translate('Events') );
|
|||
<?php
|
||||
if ( $pagination ) {
|
||||
?>
|
||||
<h2 class="pagination"><?php echo $pagination ?></h2>
|
||||
<h2 class="pagination hidden-xs"><?php echo $pagination ?></h2>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
@ -138,6 +138,7 @@ if ( $pages > 1 ) {
|
|||
<input type="hidden" name="sort_field" value="<?php echo validHtmlStr($_REQUEST['sort_field']) ?>"/>
|
||||
<input type="hidden" name="sort_asc" value="<?php echo validHtmlStr($_REQUEST['sort_asc']) ?>"/>
|
||||
<input type="hidden" name="limit" value="<?php echo $limit ?>"/>
|
||||
<div class="table-responsive">
|
||||
<table id="contentTable" class="major">
|
||||
<tbody>
|
||||
<?php
|
||||
|
@ -299,6 +300,7 @@ while ( $event_row = dbFetchNext($results) ) {
|
|||
}
|
||||
?>
|
||||
</table>
|
||||
</div>
|
||||
<?php
|
||||
if ( $pagination ) {
|
||||
?>
|
||||
|
|
|
@ -9,24 +9,27 @@ function cyclePause() {
|
|||
$('pauseBtn').disabled = true;
|
||||
$('playBtn').disabled = false;
|
||||
}
|
||||
|
||||
function cycleStart() {
|
||||
periodical_id = nextCycleView.periodical(cycleRefreshTimeout);
|
||||
$('pauseBtn').disabled = false;
|
||||
$('playBtn').disabled = true;
|
||||
}
|
||||
|
||||
function cycleNext() {
|
||||
monIdx ++;
|
||||
if ( monIdx >= monitorData.length ) {
|
||||
monIdx = 0;
|
||||
}
|
||||
if ( !monitorData[monIdx] ) {
|
||||
console.log("No monitorData for " + monIdx);
|
||||
console.log('No monitorData for ' + monIdx);
|
||||
}
|
||||
|
||||
window.location.replace('?view=cycle&mid='+monitorData[monIdx].id+'&mode='+mode, cycleRefreshTimeout);
|
||||
}
|
||||
|
||||
function cyclePrev() {
|
||||
if (monIdx) {
|
||||
if ( monIdx ) {
|
||||
monIdx -= 1;
|
||||
} else {
|
||||
monIdx = monitorData.length - 1;
|
||||
|
@ -71,7 +74,7 @@ function changeSize() {
|
|||
streamImg.style.width = width ? width : null;
|
||||
streamImg.style.height = height ? height : null;
|
||||
} else {
|
||||
console.log("Did not find liveStream"+monitorData[monIdx].id);
|
||||
console.log('Did not find liveStream'+monitorData[monIdx].id);
|
||||
}
|
||||
$('scale').set('value', '');
|
||||
Cookie.write('zmCycleScale', '', {duration: 10*365});
|
||||
|
@ -96,7 +99,7 @@ function changeScale() {
|
|||
return;
|
||||
}
|
||||
|
||||
if ( scale != '0' ) {
|
||||
if ( scale != '0' && scale != '' && scale != 'auto' ) {
|
||||
if ( newWidth ) {
|
||||
monitor_frame.css('width', newWidth+'px');
|
||||
}
|
||||
|
@ -107,33 +110,36 @@ function changeScale() {
|
|||
monitor_frame.css('width', '100%');
|
||||
monitor_frame.css('height', 'auto');
|
||||
}
|
||||
|
||||
/*Stream could be an applet so can't use moo tools*/
|
||||
var streamImg = $j('#liveStream'+monitorData[monIdx].id)[0];
|
||||
if ( streamImg ) {
|
||||
if ( streamImg.nodeName == 'IMG' ) {
|
||||
var src = streamImg.src;
|
||||
streamImg.src = '';
|
||||
|
||||
//src = src.replace(/rand=\d+/i,'rand='+Math.floor((Math.random() * 1000000) ));
|
||||
src = src.replace(/scale=[\.\d]+/i, 'scale='+scale);
|
||||
if ( scale != '0' ) {
|
||||
src = src.replace(/width=[\.\d]+/i, 'width='+newWidth);
|
||||
src = src.replace(/height=[\.\d]+/i, 'height='+newHeight);
|
||||
} else {
|
||||
src = src.replace(/width=[\.\d]+/i, 'width='+monitorData[monIdx].width);
|
||||
src = src.replace(/height=[\.\d]+/i, 'height='+monitorData[monIdx].height);
|
||||
}
|
||||
streamImg.src = src;
|
||||
}
|
||||
if ( scale != '0' ) {
|
||||
streamImg.style.width = newWidth+'px';
|
||||
streamImg.style.height = newHeight+'px';
|
||||
} else {
|
||||
streamImg.style.width = '100%';
|
||||
streamImg.style.height = 'auto';
|
||||
}
|
||||
} else {
|
||||
if ( !streamImg ) {
|
||||
console.log("Did not find liveStream"+monitorData[monIdx].id);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( streamImg.nodeName == 'IMG' ) {
|
||||
var src = streamImg.src;
|
||||
streamImg.src = '';
|
||||
|
||||
//src = src.replace(/rand=\d+/i,'rand='+Math.floor((Math.random() * 1000000) ));
|
||||
src = src.replace(/scale=[\.\d]+/i, 'scale='+scale);
|
||||
if ( scale != '0' && scale != '' && scale != 'auto' ) {
|
||||
src = src.replace(/width=[\.\d]+/i, 'width='+newWidth);
|
||||
src = src.replace(/height=[\.\d]+/i, 'height='+newHeight);
|
||||
} else {
|
||||
src = src.replace(/width=[\.\d]+/i, 'width='+monitorData[monIdx].width);
|
||||
src = src.replace(/height=[\.\d]+/i, 'height='+monitorData[monIdx].height);
|
||||
}
|
||||
streamImg.src = src;
|
||||
}
|
||||
|
||||
if ( scale != '0' && scale != '' && scale != 'auto' ) {
|
||||
streamImg.style.width = newWidth+'px';
|
||||
streamImg.style.height = newHeight+'px';
|
||||
} else {
|
||||
streamImg.style.width = '100%';
|
||||
streamImg.style.height = 'auto';
|
||||
}
|
||||
} // end function changeScale()
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ foreach ( $monitors as $monitor ) {
|
|||
?>
|
||||
monitorData[monitorData.length] = {
|
||||
'id': <?php echo $monitor->Id() ?>,
|
||||
'connKey': <?php echo $monitor->connKey() ?>,
|
||||
'width': <?php echo $monitor->ViewWidth() ?>,
|
||||
'height':<?php echo $monitor->ViewHeight() ?>,
|
||||
'url': '<?php echo $monitor->UrlToIndex() ?>',
|
||||
|
|
|
@ -285,8 +285,8 @@ function selectLayout(element) {
|
|||
* called when the widthControl|heightControl select elements are changed
|
||||
*/
|
||||
function changeSize() {
|
||||
var width = $('width').get('value');
|
||||
var height = $('height').get('value');
|
||||
var width = parseInt($('width').get('value'));
|
||||
var height = parseInt($('height').get('value'));
|
||||
|
||||
for ( var i = 0, length = monitors.length; i < length; i++ ) {
|
||||
var monitor = monitors[i];
|
||||
|
@ -297,12 +297,8 @@ function changeSize() {
|
|||
console.log("Error finding frame for " + monitor.id);
|
||||
continue;
|
||||
}
|
||||
if ( width ) {
|
||||
monitor_frame.css('width', width);
|
||||
}
|
||||
if ( height ) {
|
||||
monitor_frame.css('height', height);
|
||||
}
|
||||
monitor_frame.css('width', ( width ? width+'px' : 'auto') );
|
||||
monitor_frame.css('height', ( height ? height+'px' : 'auto') );
|
||||
|
||||
/*Stream could be an applet so can't use moo tools*/
|
||||
var streamImg = $('liveStream'+monitor.id);
|
||||
|
@ -315,8 +311,8 @@ function changeSize() {
|
|||
src = src.replace(/rand=\d+/i, 'rand='+Math.floor((Math.random() * 1000000) ));
|
||||
streamImg.src = src;
|
||||
}
|
||||
streamImg.style.width = width ? width : null;
|
||||
streamImg.style.height = height ? height : null;
|
||||
streamImg.style.width = width ? width+'px' : null;
|
||||
streamImg.style.height = height ? height+'px' : null;
|
||||
//streamImg.style.height = '';
|
||||
}
|
||||
}
|
||||
|
@ -383,8 +379,8 @@ function changeScale() {
|
|||
streamImg.src = src;
|
||||
}
|
||||
if ( scale != '0' ) {
|
||||
streamImg.style.width = newWidth + "px";
|
||||
streamImg.style.height = newHeight + "px";
|
||||
streamImg.style.width = newWidth + 'px';
|
||||
streamImg.style.height = newHeight + 'px';
|
||||
} else {
|
||||
streamImg.style.width = '100%';
|
||||
streamImg.style.height = 'auto';
|
||||
|
|
|
@ -12,16 +12,22 @@ function validateForm( form, newUser ) {
|
|||
} else if ( newUser ) {
|
||||
errors[errors.length] = "You must supply a password";
|
||||
}
|
||||
var monitorIds = new Array();
|
||||
for ( var i = 0; i < form.elements['monitorIds'].options.length; i++ ) {
|
||||
if ( form.elements['monitorIds'].options[i].selected ) {
|
||||
monitorIds[monitorIds.length] = form.elements['monitorIds'].options[i].value;
|
||||
}
|
||||
}
|
||||
form.elements['newUser[MonitorIds]'].value = monitorIds.join( ',' );
|
||||
if ( errors.length ) {
|
||||
alert( errors.join( "\n" ) );
|
||||
return ( false );
|
||||
alert(errors.join("\n"));
|
||||
return false;
|
||||
}
|
||||
return ( true );
|
||||
return true;
|
||||
}
|
||||
|
||||
function initPage() {
|
||||
$j('#contentForm').submit(function(event) {
|
||||
if ( validateForm(this) ) {
|
||||
$j('#contentButtons').hide();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
};
|
||||
});
|
||||
} // end function initPage
|
||||
|
||||
window.addEventListener('DOMContentLoaded', initPage);
|
||||
|
|
|
@ -244,12 +244,14 @@ function limitArea(field) {
|
|||
limitRange(field, minValue, maxValue);
|
||||
}
|
||||
|
||||
function highlightOn(index) {
|
||||
function highlightOn(point) {
|
||||
var index = point.getAttribute('data-index');
|
||||
$('row'+index).addClass('highlight');
|
||||
$('point'+index).addClass('highlight');
|
||||
}
|
||||
|
||||
function highlightOff(index) {
|
||||
function highlightOff(point) {
|
||||
var index = point.getAttribute('data-index');
|
||||
$('row'+index).removeClass('highlight');
|
||||
$('point'+index).removeClass('highlight');
|
||||
}
|
||||
|
@ -310,9 +312,11 @@ function updateActivePoint(index) {
|
|||
$('newZone[Points]['+index+'][y]').value = y;
|
||||
zone['Points'][index].x = x;
|
||||
zone['Points'][index].y = y;
|
||||
console.log('hello');
|
||||
var Point = $('zonePoly').points.getItem(index);
|
||||
Point.x =x;
|
||||
Point.y =y;
|
||||
console.log('hello');
|
||||
Point.x = x;
|
||||
Point.y = y;
|
||||
updateArea();
|
||||
}
|
||||
|
||||
|
@ -353,15 +357,17 @@ function updateArea( ) {
|
|||
} else if ( form.elements['newZone[Units]'].value == 'Pixels' ) {
|
||||
form.elements['newZone[TempArea]'].value = area;
|
||||
} else {
|
||||
alert("Unknown units: " + form.elements['newZone[Units]'].value);
|
||||
alert('Unknown units: ' + form.elements['newZone[Units]'].value);
|
||||
}
|
||||
}
|
||||
|
||||
function updateX(index) {
|
||||
limitPointValue($('newZone[Points]['+index+'][x]'), 0, maxX);
|
||||
function updateX(input) {
|
||||
index = input.getAttribute('data-point-index');
|
||||
|
||||
limitPointValue(input, 0, maxX);
|
||||
|
||||
var point = $('point'+index);
|
||||
var x = $('newZone[Points]['+index+'][x]').get('value');
|
||||
var x = input.value;
|
||||
|
||||
point.setStyle('left', x+'px');
|
||||
zone['Points'][index].x = x;
|
||||
|
@ -370,11 +376,12 @@ function updateX(index) {
|
|||
updateArea();
|
||||
}
|
||||
|
||||
function updateY(index) {
|
||||
limitPointValue($('newZone[Points]['+index+'][y]'), 0, maxY);
|
||||
function updateY(input) {
|
||||
index = input.getAttribute('data-point-index');
|
||||
limitPointValue(input, 0, maxY);
|
||||
|
||||
var point = $('point'+index);
|
||||
var y = $('newZone[Points]['+index+'][y]').get('value');
|
||||
var y = input.value;
|
||||
|
||||
point.setStyle('top', y+'px');
|
||||
zone['Points'][index].y = y;
|
||||
|
@ -403,6 +410,7 @@ function drawZonePoints() {
|
|||
for ( var i = 0; i < zone['Points'].length; i++ ) {
|
||||
var div = new Element('div', {
|
||||
'id': 'point'+i,
|
||||
'data-index': i,
|
||||
'class': 'zonePoint',
|
||||
'title': 'Point '+(i+1),
|
||||
'styles': {
|
||||
|
@ -410,7 +418,9 @@ function drawZonePoints() {
|
|||
'top': zone['Points'][i].y
|
||||
}
|
||||
});
|
||||
div.addEvent('mouseover', highlightOn.pass(i));
|
||||
//div.addEvent('mouseover', highlightOn.pass(i));
|
||||
div.onmouseover = window['highlightOn'].bind(div, div);
|
||||
div.onmouseout = window['highlightOff'].bind(div, div);
|
||||
div.addEvent('mouseout', highlightOff.pass(i));
|
||||
div.inject($('imageFrame'));
|
||||
div.makeDraggable( {
|
||||
|
@ -439,9 +449,12 @@ function drawZonePoints() {
|
|||
'id': 'newZone[Points]['+i+'][x]',
|
||||
'name': 'newZone[Points]['+i+'][x]',
|
||||
'value': zone['Points'][i].x,
|
||||
'size': 5
|
||||
'type': 'number',
|
||||
'min': '0',
|
||||
'max': maxX,
|
||||
'data-point-index': i
|
||||
});
|
||||
input.addEvent('input', updateX.pass(i));
|
||||
input.oninput = window['updateX'].bind(input, input);
|
||||
input.inject(cell);
|
||||
cell.inject(row);
|
||||
|
||||
|
@ -450,9 +463,12 @@ function drawZonePoints() {
|
|||
'id': 'newZone[Points]['+i+'][y]',
|
||||
'name': 'newZone[Points]['+i+'][y]',
|
||||
'value': zone['Points'][i].y,
|
||||
'size': 5
|
||||
'type': 'number',
|
||||
'min': '0',
|
||||
'max': maxY,
|
||||
'data-point-index': i
|
||||
} );
|
||||
input.addEvent('input', updateY.pass(i));
|
||||
input.oninput = window['updateY'].bind(input, input);
|
||||
input.inject(cell);
|
||||
cell.inject(row);
|
||||
|
||||
|
@ -499,34 +515,6 @@ function setAlarmState( currentAlarmState ) {
|
|||
} else {
|
||||
$('stateValue').removeProperty('class');
|
||||
}
|
||||
|
||||
var isAlarmed = ( alarmState == STATE_ALARM || alarmState == STATE_ALERT );
|
||||
var wasAlarmed = ( lastAlarmState == STATE_ALARM || lastAlarmState == STATE_ALERT );
|
||||
|
||||
var newAlarm = ( isAlarmed && !wasAlarmed );
|
||||
var oldAlarm = ( !isAlarmed && wasAlarmed );
|
||||
|
||||
if ( newAlarm ) {
|
||||
if ( SOUND_ON_ALARM ) {
|
||||
// Enable the alarm sound
|
||||
if ( !canPlayPauseAudio ) {
|
||||
$('alarmSound').removeClass('hidden');
|
||||
} else {
|
||||
$('MediaPlayer').Play();
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( SOUND_ON_ALARM ) {
|
||||
if ( oldAlarm ) {
|
||||
// Disable alarm sound
|
||||
if ( !canPlayPauseAudio ) {
|
||||
$('alarmSound').addClass('hidden');
|
||||
} else {
|
||||
$('MediaPlayer').Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
lastAlarmState = alarmState;
|
||||
}
|
||||
|
||||
var streamCmdParms = "view=request&request=stream&connkey="+connKey;
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
require_once('includes/Server.php');
|
||||
require_once('includes/Storage.php');
|
||||
|
||||
if ( !canView('Monitors') ) {
|
||||
if ( !canEdit('Monitors', empty($_REQUEST['mid'])?0:$_REQUEST['mid']) ) {
|
||||
$view = 'error';
|
||||
return;
|
||||
}
|
||||
|
@ -171,14 +171,14 @@ unset($httpMethods['jpegTags']);
|
|||
|
||||
if ( ZM_HAS_V4L1 ) {
|
||||
$v4l1DeviceFormats = array(
|
||||
'PAL' => 0,
|
||||
'NTSC' => 1,
|
||||
'SECAM' => 2,
|
||||
'AUTO' => 3,
|
||||
'FMT4' => 4,
|
||||
'FMT5' => 5,
|
||||
'FMT6' => 6,
|
||||
'FMT7' => 7
|
||||
0 => 'PAL',
|
||||
1 => 'NTSC',
|
||||
2 => 'SECAM',
|
||||
3 => 'AUTO',
|
||||
4 => 'FMT4',
|
||||
5 => 'FMT5',
|
||||
6 => 'FMT6',
|
||||
7 => 'FMT7'
|
||||
);
|
||||
|
||||
$v4l1MaxChannels = 15;
|
||||
|
@ -187,48 +187,48 @@ if ( ZM_HAS_V4L1 ) {
|
|||
$v4l1DeviceChannels[$i] = $i;
|
||||
|
||||
$v4l1LocalPalettes = array(
|
||||
translate('Grey') => 1,
|
||||
'BGR32' => 5,
|
||||
'BGR24' => 4,
|
||||
'*YUYV' => 8,
|
||||
'*RGB565' => 3,
|
||||
'*RGB555' => 6,
|
||||
'*YUV422' => 7,
|
||||
'*YUV422P' => 13,
|
||||
'*YUV420P' => 15
|
||||
1 => translate('Grey'),
|
||||
5 => 'BGR32',
|
||||
4 => 'BGR24',
|
||||
8 => '*YUYV',
|
||||
3 => '*RGB565',
|
||||
6 => '*RGB555',
|
||||
7 => '*YUV422',
|
||||
13 => '*YUV422P',
|
||||
15 => '*YUV420P',
|
||||
);
|
||||
}
|
||||
|
||||
if ( ZM_HAS_V4L2 ) {
|
||||
$v4l2DeviceFormats = array(
|
||||
'PAL' => 0x000000ff,
|
||||
'NTSC' => 0x0000b000,
|
||||
'PAL B' => 0x00000001,
|
||||
'PAL B1' => 0x00000002,
|
||||
'PAL G' => 0x00000004,
|
||||
'PAL H' => 0x00000008,
|
||||
'PAL I' => 0x00000010,
|
||||
'PAL D' => 0x00000020,
|
||||
'PAL D1' => 0x00000040,
|
||||
'PAL K' => 0x00000080,
|
||||
'PAL M' => 0x00000100,
|
||||
'PAL N' => 0x00000200,
|
||||
'PAL Nc' => 0x00000400,
|
||||
'PAL 60' => 0x00000800,
|
||||
'NTSC M' => 0x00001000,
|
||||
'NTSC M JP' => 0x00002000,
|
||||
'NTSC 443' => 0x00004000,
|
||||
'NTSC M KR' => 0x00008000,
|
||||
'SECAM B' => 0x00010000,
|
||||
'SECAM D' => 0x00020000,
|
||||
'SECAM G' => 0x00040000,
|
||||
'SECAM H' => 0x00080000,
|
||||
'SECAM K' => 0x00100000,
|
||||
'SECAM K1' => 0x00200000,
|
||||
'SECAM L' => 0x00400000,
|
||||
'SECAM LC' => 0x00800000,
|
||||
'ATSC 8 VSB' => 0x01000000,
|
||||
'ATSC 16 VSB' => 0x02000000,
|
||||
0x000000ff => 'PAL',
|
||||
0x0000b000 => 'NTSC',
|
||||
0x00000001 => 'PAL B',
|
||||
0x00000002 => 'PAL B1',
|
||||
0x00000004 => 'PAL G',
|
||||
0x00000008 => 'PAL H',
|
||||
0x00000010 => 'PAL I',
|
||||
0x00000020 => 'PAL D',
|
||||
0x00000040 => 'PAL D1',
|
||||
0x00000080 => 'PAL K',
|
||||
0x00000100 => 'PAL M',
|
||||
0x00000200 => 'PAL N',
|
||||
0x00000400 => 'PAL Nc',
|
||||
0x00000800 => 'PAL 60',
|
||||
0x00001000 => 'NTSC M',
|
||||
0x00002000 => 'NTSC M JP',
|
||||
0x00004000 => 'NTSC 443',
|
||||
0x00008000 => 'NTSC M KR',
|
||||
0x00010000 => 'SECAM B',
|
||||
0x00020000 => 'SECAM D',
|
||||
0x00040000 => 'SECAM G',
|
||||
0x00080000 => 'SECAM H',
|
||||
0x00100000 => 'SECAM K',
|
||||
0x00200000 => 'SECAM K1',
|
||||
0x00400000 => 'SECAM L',
|
||||
0x00800000 => 'SECAM LC',
|
||||
0x01000000 => 'ATSC 8 VSB',
|
||||
0x02000000 => 'ATSC 16 VSB',
|
||||
);
|
||||
|
||||
$v4l2MaxChannels = 31;
|
||||
|
@ -237,57 +237,58 @@ if ( ZM_HAS_V4L2 ) {
|
|||
$v4l2DeviceChannels[$i] = $i;
|
||||
|
||||
$v4l2LocalPalettes = array(
|
||||
'Auto' => 0, /* Automatic palette selection */
|
||||
0 => 'Auto', /* Automatic palette selection */
|
||||
|
||||
/* Pixel format FOURCC depth Description */
|
||||
translate('Grey') => fourcc('G','R','E','Y'), /* 8 Greyscale */
|
||||
'BGR32' => fourcc('B','G','R','4'), /* 32 BGR-8-8-8-8 */
|
||||
'RGB32' => fourcc('R','G','B','4'), /* 32 RGB-8-8-8-8 */
|
||||
'BGR24' => fourcc('B','G','R','3'), /* 24 BGR-8-8-8 */
|
||||
'RGB24' => fourcc('R','G','B','3'), /* 24 RGB-8-8-8 */
|
||||
'*YUYV' => fourcc('Y','U','Y','V'), /* 16 YUV 4:2:2 */
|
||||
/* FOURCC => Pixel format depth Description */
|
||||
fourcc('G','R','E','Y') => translate('Grey'), /* 8 Greyscale */
|
||||
fourcc('B','G','R','4') => 'BGR32', /* 32 BGR-8-8-8-8 */
|
||||
fourcc('R','G','B','4') => 'RGB32', /* 32 RGB-8-8-8-8 */
|
||||
fourcc('B','G','R','3') => 'BGR24', /* 24 BGR-8-8-8 */
|
||||
fourcc('R','G','B','3') => 'RGB24', /* 24 RGB-8-8-8 */
|
||||
fourcc('Y','U','Y','V') => '*YUYV', /* 16 YUV 4:2:2 */
|
||||
|
||||
/* compressed formats */
|
||||
'*JPEG' => fourcc('J','P','E','G'), /* JFIF JPEG */
|
||||
'*MJPEG' => fourcc('M','J','P','G'), /* Motion-JPEG */
|
||||
//'DV' => fourcc('d','v','s','d'), /* 1394 */
|
||||
//'MPEG' => fourcc('M','P','E','G'), /* MPEG-1/2/4 */
|
||||
fourcc('J','P','E','G') => '*JPEG', /* JFIF JPEG */
|
||||
fourcc('M','J','P','G') => '*MJPEG', /* Motion-JPEG */
|
||||
// fourcc('d','v','s','d') => 'DV', /* 1394 */
|
||||
// fourcc('M','P','E','G') => 'MPEG', /* MPEG-1/2/4 */
|
||||
|
||||
//'RGB332' => fourcc('R','G','B','1'), /* 8 RGB-3-3-2 */
|
||||
'*RGB444' => fourcc('R','4','4','4'), /* 16 xxxxrrrr ggggbbbb */
|
||||
'*RGB555' => fourcc('R','G','B','O'), /* 16 RGB-5-5-5 */
|
||||
'*RGB565' => fourcc('R','G','B','P'), /* 16 RGB-5-6-5 */
|
||||
//'RGB555X' => fourcc('R','G','B','Q'), /* 16 RGB-5-5-5 BE */
|
||||
//'RGB565X' => fourcc('R','G','B','R'), /* 16 RGB-5-6-5 BE */
|
||||
//'Y16' => fourcc('Y','1','6',''), /* 16 Greyscale */
|
||||
//'PAL8' => fourcc('P','A','L','8'), /* 8 8-bit palette */
|
||||
//'YVU410' => fourcc('Y','V','U','9'), /* 9 YVU 4:1:0 */
|
||||
//'YVU420' => fourcc('Y','V','1','2'), /* 12 YVU 4:2:0 */
|
||||
//
|
||||
fourcc('R','G','B','1') => 'RGB332', /* 8 RGB-3-3-2 */
|
||||
fourcc('R','4','4','4') => '*RGB444', /* 16 xxxxrrrr ggggbbbb */
|
||||
fourcc('R','G','B','O') => '*RGB555', /* 16 RGB-5-5-5 */
|
||||
fourcc('R','G','B','P') => '*RGB565', /* 16 RGB-5-6-5 */
|
||||
// fourcc('R','G','B','Q') => 'RGB555X', /* 16 RGB-5-5-5 BE */
|
||||
// fourcc('R','G','B','R') => 'RGB565X', /* 16 RGB-5-6-5 BE */
|
||||
// fourcc('Y','1','6','') => 'Y16', /* 16 Greyscale */
|
||||
// fourcc('P','A','L','8') => 'PAL8', /* 8 8-bit palette */
|
||||
// fourcc('Y','V','U','9') => 'YVU410', /* 9 YVU 4:1:0 */
|
||||
// fourcc('Y','V','1','2') => 'YVU420', /* 12 YVU 4:2:0 */
|
||||
|
||||
'*UYVY' => fourcc('U','Y','V','Y'), /* 16 YUV 4:2:2 */
|
||||
'*YUV422P' => fourcc('4','2','2','P'), /* 16 YVU422 planar */
|
||||
'*YUV411P' => fourcc('4','1','1','P'), /* 16 YVU411 planar */
|
||||
//'Y41P' => fourcc('Y','4','1','P'), /* 12 YUV 4:1:1 */
|
||||
'*YUV444' => fourcc('Y','4','4','4'), /* 16 xxxxyyyy uuuuvvvv */
|
||||
//'YUV555' => fourcc('Y','U','V','O'), /* 16 YUV-5-5-5 */
|
||||
//'YUV565' => fourcc('Y','U','V','P'), /* 16 YUV-5-6-5 */
|
||||
//'YUV32' => fourcc('Y','U','V','4'), /* 32 YUV-8-8-8-8 */
|
||||
fourcc('U','Y','V','Y') => '*UYVY', /* 16 YUV 4:2:2 */
|
||||
fourcc('4','2','2','P') => '*YUV422P', /* 16 YVU422 planar */
|
||||
fourcc('4','1','1','P') => '*YUV411P', /* 16 YVU411 planar */
|
||||
// fourcc('Y','4','1','P') => 'Y41P', /* 12 YUV 4:1:1 */
|
||||
fourcc('Y','4','4','4') => '*YUV444', /* 16 xxxxyyyy uuuuvvvv */
|
||||
// fourcc('Y','U','V','O') => 'YUV555', /* 16 YUV-5-5-5 */
|
||||
// fourcc('Y','U','V','P') => 'YUV565', /* 16 YUV-5-6-5 */
|
||||
// fourcc('Y','U','V','4') => 'YUV32', /* 32 YUV-8-8-8-8 */
|
||||
|
||||
/* two planes -- one Y, one Cr + Cb interleaved */
|
||||
//'NV12' => fourcc('N','V','1','2'), /* 12 Y/CbCr 4:2:0 */
|
||||
//'NV21' => fourcc('N','V','2','1'), /* 12 Y/CrCb 4:2:0 */
|
||||
fourcc('N','V','1','2') => 'NV12', /* 12 Y/CbCr 4:2:0 */
|
||||
// fourcc('N','V','2','1') => 'NV21', /* 12 Y/CrCb 4:2:0 */
|
||||
|
||||
/* The following formats are not defined in the V4L2 specification */
|
||||
'*YUV410' => fourcc('Y','U','V','9'), /* 9 YUV 4:1:0 */
|
||||
'*YUV420' => fourcc('Y','U','1','2'), /* 12 YUV 4:2:0 */
|
||||
//'YYUV' => fourcc('Y','Y','U','V'), /* 16 YUV 4:2:2 */
|
||||
//'HI240' => fourcc('H','I','2','4'), /* 8 8-bit color */
|
||||
//'HM12' => fourcc('H','M','1','2'), /* 8 YUV 4:2:0 16x16 macroblocks */
|
||||
fourcc('Y','U','V','9') => '*YUV410', /* 9 YUV 4:1:0 */
|
||||
fourcc('Y','U','1','2') => '*YUV420', /* 12 YUV 4:2:0 */
|
||||
// fourcc('Y','Y','U','V') => 'YYUV', /* 16 YUV 4:2:2 */
|
||||
// fourcc('H','I','2','4') => 'HI240', /* 8 8-bit color */
|
||||
// fourcc('H','M','1','2') => 'HM12', /* 8 YUV 4:2:0 16x16 macroblocks */
|
||||
|
||||
/* see http://www.siliconimaging.com/RGB%20Bayer.htm */
|
||||
//'SBGGR8' => fourcc('B','A','8','1'), /* 8 BGBG.. GRGR.. */
|
||||
//'SGBRG8' => fourcc('G','B','R','G'), /* 8 GBGB.. RGRG.. */
|
||||
//'SBGGR16' => fourcc('B','Y','R','2'), /* 16 BGBG.. GRGR.. */
|
||||
// fourcc('B','A','8','1') => 'SBGGR8', /* 8 BGBG.. GRGR.. */
|
||||
// fourcc('G','B','R','G') => 'SGBRG8', /* 8 GBGB.. RGRG.. */
|
||||
// fourcc('B','Y','R','2') => 'SBGGR16', /* 16 BGBG.. GRGR.. */
|
||||
|
||||
/* Vendor-specific formats */
|
||||
//'WNVA' => fourcc('W','N','V','A'), /* Winnov hw compress */
|
||||
|
@ -348,23 +349,23 @@ $deinterlaceopts_v4l2 = array(
|
|||
);
|
||||
|
||||
$fastblendopts = array(
|
||||
'No blending' => 0,
|
||||
'1.5625%' => 1,
|
||||
'3.125%' => 3,
|
||||
'6.25% (Indoor)' => 6,
|
||||
'12.5% (Outdoor)' => 12,
|
||||
'25%' => 25,
|
||||
'50%' => 50
|
||||
0 => 'No blending',
|
||||
1 => '1.5625%',
|
||||
3 => '3.125%',
|
||||
6 => '6.25% (Indoor)',
|
||||
12 => '12.5% (Outdoor)',
|
||||
25 => '25%',
|
||||
50 => '50%',
|
||||
);
|
||||
|
||||
$fastblendopts_alarm = array(
|
||||
'No blending (Alarm lasts forever)' => 0,
|
||||
'1.5625%' => 1,
|
||||
'3.125%' => 3,
|
||||
'6.25%' => 6,
|
||||
'12.5%' => 12,
|
||||
'25%' => 25,
|
||||
'50% (Alarm lasts a moment)' => 50
|
||||
0 => 'No blending (Alarm lasts forever)',
|
||||
1 => '1.5625%',
|
||||
3 => '3.125%',
|
||||
6 => '6.25%',
|
||||
12 => '12.5%',
|
||||
25 => '25%',
|
||||
50 => '50% (Alarm lasts a moment)',
|
||||
);
|
||||
|
||||
$label_size = array(
|
||||
|
@ -681,45 +682,50 @@ switch ( $tab ) {
|
|||
echo htmlOptions(ZM\Group::get_dropdown_options(), $monitor->GroupIds());
|
||||
?></select></td>
|
||||
</tr>
|
||||
<tr><td><?php echo translate('AnalysisFPS') ?></td><td><input type="text" name="newMonitor[AnalysisFPSLimit]" value="<?php echo validHtmlStr($monitor->AnalysisFPSLimit()) ?>" size="6"/></td></tr>
|
||||
<tr>
|
||||
<td><?php echo translate('AnalysisFPS') ?></td>
|
||||
<td><input type="number" name="newMonitor[AnalysisFPSLimit]" value="<?php echo validHtmlStr($monitor->AnalysisFPSLimit()) ?>" min="0" step="any"/></td>
|
||||
</tr>
|
||||
<?php
|
||||
if ( $monitor->Type() != 'Local' && $monitor->Type() != 'File' && $monitor->Type() != 'NVSocket' ) {
|
||||
?>
|
||||
<tr>
|
||||
<td><?php echo translate('MaximumFPS') ?> (<?php echo makePopupLink('?view=optionhelp&option=OPTIONS_MAXFPS', 'zmOptionHelp', 'optionhelp', '?' ) ?>)</td>
|
||||
<td>
|
||||
<input type="text" name="newMonitor[MaxFPS]" value="<?php echo validHtmlStr($monitor->MaxFPS()) ?>" size="5"/>
|
||||
<input type="number" name="newMonitor[MaxFPS]" value="<?php echo validHtmlStr($monitor->MaxFPS()) ?>" min="0" step="any"/>
|
||||
<span id="newMonitor[MaxFPS]" style="color:red;<?php echo $monitor->MaxFPS() ? '' : 'display:none;' ?>">CAUTION: See the help text</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('AlarmMaximumFPS') ?> (<?php echo makePopupLink('?view=optionhelp&option=OPTIONS_MAXFPS', 'zmOptionHelp', 'optionhelp', '?' ) ?>)</td>
|
||||
<td>
|
||||
<input type="text" name="newMonitor[AlarmMaxFPS]" value="<?php echo validHtmlStr($monitor->AlarmMaxFPS()) ?>" size="5"/>
|
||||
<input type="number" name="newMonitor[AlarmMaxFPS]" value="<?php echo validHtmlStr($monitor->AlarmMaxFPS()) ?>" min="0" step="any"/>
|
||||
<span id="newMonitor[AlarmMaxFPS]" style="color:red;<?php echo $monitor->AlarmMaxFPS() ? '' : 'display:none;' ?>">CAUTION: See the help text</span>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
} else {
|
||||
?>
|
||||
<tr><td><?php echo translate('MaximumFPS') ?></td><td><input type="text" name="newMonitor[MaxFPS]" value="<?php echo validHtmlStr($monitor->MaxFPS()) ?>" size="5"/></td></tr>
|
||||
<tr><td><?php echo translate('AlarmMaximumFPS') ?></td><td><input type="text" name="newMonitor[AlarmMaxFPS]" value="<?php echo validHtmlStr($monitor->AlarmMaxFPS()) ?>" size="5"/></td></tr>
|
||||
<tr>
|
||||
<td><?php echo translate('MaximumFPS') ?></td>
|
||||
<td><input type="number" name="newMonitor[MaxFPS]" value="<?php echo validHtmlStr($monitor->MaxFPS()) ?>" min="0" step="any"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('AlarmMaximumFPS') ?></td>
|
||||
<td><input type="number" name="newMonitor[AlarmMaxFPS]" value="<?php echo validHtmlStr($monitor->AlarmMaxFPS()) ?>" min="0" step="any"/></td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
if ( ZM_FAST_IMAGE_BLENDS ) {
|
||||
?>
|
||||
<tr>
|
||||
<td><?php echo translate('RefImageBlendPct') ?></td>
|
||||
<td><select name="newMonitor[RefBlendPerc]"><?php foreach ( $fastblendopts as $name => $value ) { ?><option value="<?php echo $value ?>"<?php if ( $value == $monitor->RefBlendPerc() ) { ?> selected="selected"<?php } ?>><?php echo $name ?></option><?php } ?></select></td>
|
||||
<td><?php echo htmlSelect('newMonitor[RefBlendPerc]', $fastblendopts, $monitor->RefBlendPerc()); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('AlarmRefImageBlendPct') ?></td>
|
||||
<td>
|
||||
<select name="newMonitor[AlarmRefBlendPerc]">
|
||||
<?php foreach ( $fastblendopts_alarm as $name => $value ) { ?>
|
||||
<option value="<?php echo $value ?>"<?php if ( $value == $monitor->AlarmRefBlendPerc() ) { ?> selected="selected"<?php } ?>><?php echo $name ?></option>
|
||||
<?php } ?>
|
||||
</select></td></tr>
|
||||
<td><?php echo htmlSelect('newMonitor[AlarmRefBlendPerc]', $fastblendopts_alarm, $monitor->AlarmRefBlendPerc()); ?></td>
|
||||
</tr>
|
||||
<?php
|
||||
} else {
|
||||
?>
|
||||
|
@ -778,17 +784,26 @@ switch ( $tab ) {
|
|||
{
|
||||
if ( ZM_HAS_V4L && $monitor->Type() == 'Local' ) {
|
||||
?>
|
||||
<tr><td><?php echo translate('DevicePath') ?></td><td><input type="text" name="newMonitor[Device]" value="<?php echo validHtmlStr($monitor->Device()) ?>" size="24"/></td></tr>
|
||||
<tr><td><?php echo translate('CaptureMethod') ?></td><td><?php echo htmlSelect( "newMonitor[Method]", $localMethods, $monitor->Method(), "submitTab( '$tab' );" ); ?></td></tr>
|
||||
<tr><td><?php echo translate('DevicePath') ?></td><td><input type="text" name="newMonitor[Device]" value="<?php echo validHtmlStr($monitor->Device()) ?>"/></td></tr>
|
||||
<tr>
|
||||
<td><?php echo translate('CaptureMethod') ?></td>
|
||||
<td><?php echo htmlSelect('newMonitor[Method]', $localMethods, $monitor->Method(), array('onchange'=>'submitTab', 'data-tab-name'=>$tab) ); ?></td>
|
||||
</tr>
|
||||
<?php
|
||||
if ( ZM_HAS_V4L1 && $monitor->Method() == 'v4l1' ) {
|
||||
?>
|
||||
<tr>
|
||||
<td><?php echo translate('DeviceChannel') ?></td>
|
||||
<td><select name="newMonitor[Channel]"><?php foreach ( $v4l1DeviceChannels as $name => $value ) { ?><option value="<?php echo $value ?>"<?php if ( $value == $monitor->Channel()) { ?> selected="selected"<?php } ?>><?php echo $name ?></option><?php } ?></select></td>
|
||||
<td><?php echo htmlSelect('newMonitor[Channel]', $v4l1DeviceChannels, $monitor->Channel()); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('DeviceFormat') ?></td>
|
||||
<td><?php echo htmlSelect('newMonitor[Format]', $v4l1DeviceFormats, $monitor->Format()); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('CapturePalette') ?></td>
|
||||
<td><?php echo htmlSelect('newMonitor[Palette]', $v4l1LocalPalettes, $monitor->Palette()); ?></td>
|
||||
</tr>
|
||||
<tr><td><?php echo translate('DeviceFormat') ?></td><td><select name="newMonitor[Format]"><?php foreach ( $v4l1DeviceFormats as $name => $value ) { ?><option value="<?php echo $value ?>"<?php if ( $value == $monitor->Format()) { ?> selected="selected"<?php } ?>><?php echo $name ?></option><?php } ?></select></td></tr>
|
||||
<tr><td><?php echo translate('CapturePalette') ?></td><td><select name="newMonitor[Palette]"><?php foreach ( $v4l1LocalPalettes as $name => $value ) { ?><option value="<?php echo $value ?>"<?php if ( $value == $monitor->Palette()) { ?> selected="selected"<?php } ?>><?php echo $name ?></option><?php } ?></select></td></tr>
|
||||
<?php
|
||||
} else {
|
||||
?>
|
||||
|
@ -806,7 +821,10 @@ switch ( $tab ) {
|
|||
<input type="radio" name="newMonitor[V4LMultiBuffer]" id="newMonitor[V4LMultiBuffer]" value="" <?php echo ( $monitor->V4LMultiBuffer() == '' ? 'checked="checked"' : '' ) ?>/>
|
||||
<label for="newMonitor[V4LMultiBuffer]">Use Config Value</label>
|
||||
</td></tr>
|
||||
<tr><td><?php echo translate('V4LCapturesPerFrame') ?></td><td><input type="number" name="newMonitor[V4LCapturesPerFrame]" value="<?php echo validHtmlStr($monitor->V4LCapturesPerFrame()); ?>"/></td></tr>
|
||||
<tr>
|
||||
<td><?php echo translate('V4LCapturesPerFrame') ?></td>
|
||||
<td><input type="number" name="newMonitor[V4LCapturesPerFrame]" value="<?php echo validHtmlStr($monitor->V4LCapturesPerFrame()); ?>" min="1"/></td>
|
||||
</tr>
|
||||
<?php
|
||||
|
||||
} else if ( $monitor->Type() == 'NVSocket' ) {
|
||||
|
@ -832,28 +850,29 @@ include('_monitor_source_nvsocket.php');
|
|||
<?php
|
||||
} else if ( $monitor->Type() == 'Remote' ) {
|
||||
?>
|
||||
<tr><td><?php echo translate('RemoteProtocol') ?></td><td><?php echo htmlSelect( "newMonitor[Protocol]", $remoteProtocols, $monitor->Protocol(), "updateMethods( this );if(this.value=='rtsp'){\$('RTSPDescribe').setStyle('display','table-row');}else{\$('RTSPDescribe').hide();}" ); ?></td></tr>
|
||||
<?php
|
||||
?>
|
||||
<tr>
|
||||
<td><?php echo translate('RemoteProtocol') ?></td>
|
||||
<td><?php echo htmlSelect('newMonitor[Protocol]', $remoteProtocols, $monitor->Protocol(), "updateMethods( this );if(this.value=='rtsp'){\$('RTSPDescribe').setStyle('display','table-row');}else{\$('RTSPDescribe').hide();}" ); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('RemoteMethod') ?></td>
|
||||
<td>
|
||||
<?php
|
||||
if ( !$monitor->Protocol() || $monitor->Protocol() == 'http' ) {
|
||||
echo htmlSelect('newMonitor[Method]', $httpMethods, $monitor->Method() );
|
||||
echo htmlSelect('newMonitor[Method]', $httpMethods, $monitor->Method());
|
||||
} else {
|
||||
echo htmlSelect('newMonitor[Method]', $rtspMethods, $monitor->Method() );
|
||||
echo htmlSelect('newMonitor[Method]', $rtspMethods, $monitor->Method());
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><?php echo translate('RemoteHostName') ?></td><td><input type="text" name="newMonitor[Host]" value="<?php echo validHtmlStr($monitor->Host()) ?>"/></td></tr>
|
||||
<tr><td><?php echo translate('RemoteHostPort') ?></td><td><input type="number" name="newMonitor[Port]" value="<?php echo validHtmlStr($monitor->Port()) ?>" size="6"/></td></tr>
|
||||
<tr><td><?php echo translate('RemoteHostPort') ?></td><td><input type="number" name="newMonitor[Port]" value="<?php echo validHtmlStr($monitor->Port()) ?>" min="0" max="65535"/></td></tr>
|
||||
<tr><td><?php echo translate('RemoteHostPath') ?></td><td><input type="text" name="newMonitor[Path]" value="<?php echo validHtmlStr($monitor->Path()) ?>"/></td></tr>
|
||||
<?php
|
||||
} else if ( $monitor->Type() == 'File' ) {
|
||||
?>
|
||||
<tr><td><?php echo translate('SourcePath') ?></td><td><input type="text" name="newMonitor[Path]" value="<?php echo validHtmlStr($monitor->Path()) ?>" size="36"/></td></tr>
|
||||
<tr><td><?php echo translate('SourcePath') ?></td><td><input type="text" name="newMonitor[Path]" value="<?php echo validHtmlStr($monitor->Path()) ?>"/></td></tr>
|
||||
<?php
|
||||
} elseif ( $monitor->Type() == 'cURL' ) {
|
||||
?>
|
||||
|
@ -869,15 +888,15 @@ include('_monitor_source_nvsocket.php');
|
|||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('Width') ?> (<?php echo translate('Pixels') ?>)</td>
|
||||
<td><input type="number" name="newMonitor[Width]" value="<?php echo validHtmlStr($monitor->Width()) ?>" size="4"/></td>
|
||||
<td><input type="number" name="newMonitor[Width]" value="<?php echo validHtmlStr($monitor->Width()) ?>" min="1"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('Height') ?> (<?php echo translate('Pixels') ?>)</td>
|
||||
<td><input type="number" name="newMonitor[Height]" value="<?php echo validHtmlStr($monitor->Height()) ?>" size="4"/></td>
|
||||
<td><input type="number" name="newMonitor[Height]" value="<?php echo validHtmlStr($monitor->Height()) ?>" min="1"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo 'Web Site Refresh (Optional)' ?></td>
|
||||
<td><input type="number" name="newMonitor[Refresh]" value="<?php echo validHtmlStr($monitor->Refresh()) ?>"/></td>
|
||||
<td><input type="number" name="newMonitor[Refresh]" value="<?php echo validHtmlStr($monitor->Refresh()) ?>" min="1"/></td>
|
||||
</tr>
|
||||
<?php
|
||||
} else if ( $monitor->Type() == 'Ffmpeg' || $monitor->Type() == 'Libvlc' ) {
|
||||
|
@ -924,8 +943,8 @@ include('_monitor_source_nvsocket.php');
|
|||
<tr>
|
||||
<td><?php echo translate('CaptureResolution') ?> (<?php echo translate('Pixels') ?>)</td>
|
||||
<td>
|
||||
<input type="number" name="newMonitor[Width]" value="<?php echo validHtmlStr($monitor->Width()) ?>"/>
|
||||
<input type="number" name="newMonitor[Height]" value="<?php echo validHtmlStr($monitor->Height()) ?>"/>
|
||||
<input type="number" name="newMonitor[Width]" value="<?php echo validHtmlStr($monitor->Width()) ?>" min="1"/>
|
||||
<input type="number" name="newMonitor[Height]" value="<?php echo validHtmlStr($monitor->Height()) ?>" min="1"/>
|
||||
<?php echo htmlselect('dimensions_select', array(
|
||||
''=>translate('Custom'),
|
||||
'176x120'=>'176x120 QCIF',
|
||||
|
@ -1054,11 +1073,11 @@ include('_monitor_source_nvsocket.php');
|
|||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('TimestampLabelX') ?></td>
|
||||
<td><input type="number" name="newMonitor[LabelX]" value="<?php echo validHtmlStr($monitor->LabelX()) ?>" size="4"/></td>
|
||||
<td><input type="number" name="newMonitor[LabelX]" value="<?php echo validHtmlStr($monitor->LabelX()) ?>" min="1"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('TimestampLabelY') ?></td>
|
||||
<td><input type="number" name="newMonitor[LabelY]" value="<?php echo validHtmlStr($monitor->LabelY()) ?>" size="4"/></td>
|
||||
<td><input type="number" name="newMonitor[LabelY]" value="<?php echo validHtmlStr($monitor->LabelY()) ?>" min="1"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('TimestampLabelSize') ?></td>
|
||||
|
@ -1072,27 +1091,27 @@ include('_monitor_source_nvsocket.php');
|
|||
?>
|
||||
<tr>
|
||||
<td><?php echo translate('ImageBufferSize') ?></td>
|
||||
<td><input type="number" name="newMonitor[ImageBufferCount]" value="<?php echo validHtmlStr($monitor->ImageBufferCount()) ?>" size="6"/></td>
|
||||
<td><input type="number" name="newMonitor[ImageBufferCount]" value="<?php echo validHtmlStr($monitor->ImageBufferCount()) ?>" min="1"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('WarmupFrames') ?></td>
|
||||
<td><input type="number" name="newMonitor[WarmupCount]" value="<?php echo validHtmlStr($monitor->WarmupCount()) ?>" size="4"/></td>
|
||||
<td><input type="number" name="newMonitor[WarmupCount]" value="<?php echo validHtmlStr($monitor->WarmupCount()) ?>" min="0"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('PreEventImageBuffer') ?></td>
|
||||
<td><input type="number" name="newMonitor[PreEventCount]" value="<?php echo validHtmlStr($monitor->PreEventCount()) ?>" size="4"/></td>
|
||||
<td><input type="number" name="newMonitor[PreEventCount]" value="<?php echo validHtmlStr($monitor->PreEventCount()) ?>" min="0"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('PostEventImageBuffer') ?></td>
|
||||
<td><input type="number" name="newMonitor[PostEventCount]" value="<?php echo validHtmlStr($monitor->PostEventCount()) ?>" size="4"/></td>
|
||||
<td><input type="number" name="newMonitor[PostEventCount]" value="<?php echo validHtmlStr($monitor->PostEventCount()) ?>" min="0"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('StreamReplayBuffer') ?></td>
|
||||
<td><input type="number" name="newMonitor[StreamReplayBuffer]" value="<?php echo validHtmlStr($monitor->StreamReplayBuffer()) ?>" size="6"/></td>
|
||||
<td><input type="number" name="newMonitor[StreamReplayBuffer]" value="<?php echo validHtmlStr($monitor->StreamReplayBuffer()) ?>" min="0"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('AlarmFrameCount') ?></td>
|
||||
<td><input type="number" name="newMonitor[AlarmFrameCount]" value="<?php echo validHtmlStr($monitor->AlarmFrameCount()) ?>" size="4"/></td>
|
||||
<td><input type="number" name="newMonitor[AlarmFrameCount]" value="<?php echo validHtmlStr($monitor->AlarmFrameCount()) ?>" min="1"/></td>
|
||||
</tr>
|
||||
<?php
|
||||
break;
|
||||
|
@ -1122,7 +1141,7 @@ if ( canEdit('Control') ) {
|
|||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('AutoStopTimeout') ?></td>
|
||||
<td><input type="number" name="newMonitor[AutoStopTimeout]" value="<?php echo validHtmlStr($monitor->AutoStopTimeout()) ?>"/></td>
|
||||
<td><input type="number" name="newMonitor[AutoStopTimeout]" value="<?php echo validHtmlStr($monitor->AutoStopTimeout()) ?>" min="0" step="any"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('TrackMotion') ?></td>
|
||||
|
@ -1130,7 +1149,7 @@ if ( canEdit('Control') ) {
|
|||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('TrackDelay') ?></td>
|
||||
<td><input type="number" name="newMonitor[TrackDelay]" value="<?php echo validHtmlStr($monitor->TrackDelay()) ?>"/></td>
|
||||
<td><input type="number" name="newMonitor[TrackDelay]" value="<?php echo validHtmlStr($monitor->TrackDelay()) ?>" min="0" step="any"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('ReturnLocation') ?></td>
|
||||
|
@ -1144,7 +1163,7 @@ echo htmlSelect('newMonitor[ReturnLocation]', $return_options, $monitor->ReturnL
|
|||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('ReturnDelay') ?></td>
|
||||
<td><input type="number" name="newMonitor[ReturnDelay]" value="<?php echo validHtmlStr($monitor->ReturnDelay()) ?>"/></td>
|
||||
<td><input type="number" name="newMonitor[ReturnDelay]" value="<?php echo validHtmlStr($monitor->ReturnDelay()) ?>" min="0" step="any"/></td>
|
||||
</tr>
|
||||
<?php
|
||||
break;
|
||||
|
@ -1168,41 +1187,41 @@ echo htmlSelect('newMonitor[ReturnLocation]', $return_options, $monitor->ReturnL
|
|||
<tr>
|
||||
<td><?php echo translate('Sectionlength') ?></td>
|
||||
<td>
|
||||
<input type="number" name="newMonitor[SectionLength]" value="<?php echo validHtmlStr($monitor->SectionLength()) ?>"/>
|
||||
<input type="number" name="newMonitor[SectionLength]" value="<?php echo validHtmlStr($monitor->SectionLength()) ?>" min="0"/>
|
||||
<?php echo translate('seconds')?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('MinSectionlength') ?></td>
|
||||
<td>
|
||||
<input type="number" name="newMonitor[MinSectionLength]" value="<?php echo validHtmlStr($monitor->MinSectionLength()) ?>"/>
|
||||
<input type="number" name="newMonitor[MinSectionLength]" value="<?php echo validHtmlStr($monitor->MinSectionLength()) ?>" min="0"/>
|
||||
<?php echo translate('seconds')?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('FrameSkip') ?></td>
|
||||
<td>
|
||||
<input type="number" name="newMonitor[FrameSkip]" value="<?php echo validHtmlStr($monitor->FrameSkip()) ?>"/>
|
||||
<input type="number" name="newMonitor[FrameSkip]" value="<?php echo validHtmlStr($monitor->FrameSkip()) ?>" min="0"/>
|
||||
<?php echo translate('frames')?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('MotionFrameSkip') ?></td>
|
||||
<td>
|
||||
<input type="number" name="newMonitor[MotionFrameSkip]" value="<?php echo validHtmlStr($monitor->MotionFrameSkip()) ?>"/>
|
||||
<input type="number" name="newMonitor[MotionFrameSkip]" value="<?php echo validHtmlStr($monitor->MotionFrameSkip()) ?>" min="0"/>
|
||||
<?php echo translate('frames')?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo translate('AnalysisUpdateDelay') ?></td>
|
||||
<td>
|
||||
<input type="number" name="newMonitor[AnalysisUpdateDelay]" value="<?php echo validHtmlStr($monitor->AnalysisUpdateDelay()) ?>"/>
|
||||
<input type="number" name="newMonitor[AnalysisUpdateDelay]" value="<?php echo validHtmlStr($monitor->AnalysisUpdateDelay()) ?>" min="0"/>
|
||||
<?php echo translate('seconds')?>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td><?php echo translate('FPSReportInterval') ?></td>
|
||||
<td>
|
||||
<input type="number" name="newMonitor[FPSReportInterval]" value="<?php echo validHtmlStr($monitor->FPSReportInterval()) ?>"/>
|
||||
<input type="number" name="newMonitor[FPSReportInterval]" value="<?php echo validHtmlStr($monitor->FPSReportInterval()) ?>" min="0"/>
|
||||
<?php echo translate('frames')?>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -1221,7 +1240,7 @@ echo htmlSelect('newMonitor[ReturnLocation]', $return_options, $monitor->ReturnL
|
|||
<tr>
|
||||
<td><?php echo translate('SignalCheckPoints') ?></td>
|
||||
<td>
|
||||
<input type="number" name="newMonitor[SignalCheckPoints]" value="<?php echo validInt($monitor->SignalCheckPoints()) ?>"/>
|
||||
<input type="number" name="newMonitor[SignalCheckPoints]" value="<?php echo validInt($monitor->SignalCheckPoints()) ?>" min="0"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
|
@ -33,20 +33,20 @@ if ( isset($_REQUEST['showZones']) ) {
|
|||
}
|
||||
}
|
||||
$widths = array(
|
||||
'auto' => 'auto',
|
||||
'160px' => '160px',
|
||||
'320px' => '320px',
|
||||
'352px' => '352px',
|
||||
'640px' => '640px',
|
||||
'1280px' => '1280px' );
|
||||
'0' => 'auto',
|
||||
'160' => '160px',
|
||||
'320' => '320px',
|
||||
'352' => '352px',
|
||||
'640' => '640px',
|
||||
'1280' => '1280px' );
|
||||
|
||||
$heights = array(
|
||||
'auto' => 'auto',
|
||||
'240px' => '240px',
|
||||
'320px' => '320px',
|
||||
'480px' => '480px',
|
||||
'720px' => '720px',
|
||||
'1080px' => '1080px',
|
||||
'0' => 'auto',
|
||||
'240' => '240px',
|
||||
'320' => '320px',
|
||||
'480' => '480px',
|
||||
'720' => '720px',
|
||||
'1080' => '1080px',
|
||||
);
|
||||
|
||||
$scale = '100'; # actual
|
||||
|
@ -54,7 +54,7 @@ $scale = '100'; # actual
|
|||
if ( isset($_REQUEST['scale']) ) {
|
||||
$scale = validInt($_REQUEST['scale']);
|
||||
} else if ( isset($_COOKIE['zmMontageScale']) ) {
|
||||
$scale = $_COOKIE['zmMontageScale'];
|
||||
$scale = validInt($_COOKIE['zmMontageScale']);
|
||||
}
|
||||
|
||||
$layouts = ZM\MontageLayout::find(NULL, array('order'=>"lower('Name')"));
|
||||
|
@ -92,19 +92,20 @@ if ( $Layout and ( $Layout->Name() != 'Freeform' ) ) {
|
|||
// Use layout instead of other options
|
||||
}
|
||||
|
||||
if ( isset($_COOKIE['zmMontageWidth']) and $_COOKIE['zmMontageWidth'] ) {
|
||||
$_SESSION['zmMontageWidth'] = $options['width'] = $_COOKIE['zmMontageWidth'];
|
||||
if ( isset($_COOKIE['zmMontageWidth']) ) {
|
||||
$_SESSION['zmMontageWidth'] = $options['width'] = validInt($_COOKIE['zmMontageWidth']);
|
||||
#} elseif ( isset($_SESSION['zmMontageWidth']) and $_SESSION['zmMontageWidth'] ) {
|
||||
#$options['width'] = $_SESSION['zmMontageWidth'];
|
||||
} else
|
||||
$options['width'] = '';
|
||||
$options['width'] = 0;
|
||||
|
||||
if ( isset($_COOKIE['zmMontageHeight']) and $_COOKIE['zmMontageHeight'] )
|
||||
$_SESSION['zmMontageHeight'] = $options['height'] = $_COOKIE['zmMontageHeight'];
|
||||
if ( isset($_COOKIE['zmMontageHeight']) ) {
|
||||
$_SESSION['zmMontageHeight'] = $options['height'] = validInt($_COOKIE['zmMontageHeight']);
|
||||
#else if ( isset($_SESSION['zmMontageHeight']) and $_SESSION['zmMontageHeight'] )
|
||||
#$options['height'] = $_SESSION['zmMontageHeight'];
|
||||
else
|
||||
$options['height'] = '';
|
||||
} else {
|
||||
$options['height'] = 0;
|
||||
}
|
||||
|
||||
#if ( $scale )
|
||||
$options['scale'] = $scale;
|
||||
|
@ -128,10 +129,10 @@ foreach( $displayMonitors as &$row ) {
|
|||
$showControl = true;
|
||||
$row['connKey'] = generateConnKey();
|
||||
if ( ! isset($widths[$row['Width']]) ) {
|
||||
$widths[$row['Width'].'px'] = $row['Width'].'px';
|
||||
$widths[$row['Width']] = $row['Width'].'px';
|
||||
}
|
||||
if ( ! isset($heights[$row['Height']]) ) {
|
||||
$heights[$row['Height'].'px'] = $row['Height'].'px';
|
||||
$heights[$row['Height']] = $row['Height'].'px';
|
||||
}
|
||||
$monitors[] = new ZM\Monitor($row);
|
||||
} # end foreach Monitor
|
||||
|
@ -200,23 +201,28 @@ if ( $showZones ) {
|
|||
<div id="monitors">
|
||||
<?php
|
||||
foreach ( $monitors as $monitor ) {
|
||||
$connkey = $monitor->connKey(); // Minor hack
|
||||
?>
|
||||
<div
|
||||
id="monitorFrame<?php echo $monitor->Id() ?>"
|
||||
class="monitorFrame"
|
||||
title="<?php echo $monitor->Id() . ' ' .$monitor->Name() ?>"
|
||||
style="<?php echo $options['width'] ? 'width:'.$options['width'].';':''?>"
|
||||
style="<?php echo $options['width'] ? 'width:'.$options['width'].'px;':''?>"
|
||||
>
|
||||
<div id="monitor<?php echo $monitor->Id() ?>" class="monitor idle">
|
||||
<div
|
||||
id="imageFeed<?php echo $monitor->Id() ?>"
|
||||
class="imageFeed"
|
||||
data-monitor-id="<?php echo $monitor->Id() ?>"
|
||||
data-width="<?php echo reScale( $monitor->Width(), $monitor->PopupScale() ); ?>"
|
||||
data-height="<?php echo reScale( $monitor->Height(), $monitor->PopupScale() ); ?>">
|
||||
data-width="<?php echo reScale($monitor->ViewWidth(), $monitor->PopupScale()); ?>"
|
||||
data-height="<?php echo reScale($monitor->ViewHeight(), $monitor->PopupScale()); ?>"
|
||||
>
|
||||
<?php
|
||||
$monitor_options = $options;
|
||||
$monitor_options['width'] = $monitor_options['width'].'px';
|
||||
$monitor_options['height'] = $monitor_options['height']?$monitor_options['height'].'px' : null;
|
||||
$monitor_options['connkey'] = $monitor->connKey();
|
||||
|
||||
ZM\Logger::Debug("Options: " . print_r($monitor_options,true));
|
||||
if (0 and $Positions ) {
|
||||
$monitor_options['width'] = '100%';
|
||||
$monitor_options['height'] = '100%';
|
||||
|
@ -235,8 +241,8 @@ foreach ( $monitors as $monitor ) {
|
|||
echo getWebSiteUrl(
|
||||
'liveStream'.$monitor->Id(),
|
||||
$monitor->Path(),
|
||||
(isset($options['width']) ? $options['width'] : reScale($monitor->Width(), $scale).'px' ),
|
||||
( isset($options['height']) ? $options['height'] : reScale($monitor->Height(), $scale).'px' ),
|
||||
(isset($options['width']) ? $options['width'].'px' : reScale($monitor->ViewWidth(), $scale).'px' ),
|
||||
( isset($options['height']) ? $options['height'].'px' : reScale($monitor->ViewHeight(), $scale).'px' ),
|
||||
$monitor->Name()
|
||||
);
|
||||
} else {
|
||||
|
@ -249,17 +255,17 @@ foreach ( $monitors as $monitor ) {
|
|||
$width = $options['width'];
|
||||
if ( !$options['height'] ) {
|
||||
$scale = (int)( 100 * $options['width'] / $monitor->Width() );
|
||||
$height = reScale($monitor->Height(), $scale).'px';
|
||||
$height = reScale($monitor->Height(), $scale);
|
||||
}
|
||||
} else if ( $options['height'] ) {
|
||||
$height = $options['height'];
|
||||
if ( !$options['width'] ) {
|
||||
$scale = (int)( 100 * $options['height'] / $monitor->Height() );
|
||||
$width = reScale($monitor->Width(), $scale).'px';
|
||||
$width = reScale($monitor->Width(), $scale);
|
||||
}
|
||||
} else if ( $scale ) {
|
||||
$width = reScale($monitor->Width(), $scale).'px';
|
||||
$height = reScale($monitor->Height(), $scale).'px';
|
||||
$width = reScale($monitor->Width(), $scale);
|
||||
$height = reScale($monitor->Height(), $scale);
|
||||
}
|
||||
|
||||
$zones = array();
|
||||
|
@ -270,8 +276,8 @@ foreach ( $monitors as $monitor ) {
|
|||
limitPoints($row['Points'], 0, 0, $monitor->Width(), $monitor->Height());
|
||||
} else {
|
||||
limitPoints($row['Points'], 0, 0,
|
||||
( $width ? $width-1 : $monitor->Width()-1 ),
|
||||
( $height ? $height-1 : $monitor->Height()-1 )
|
||||
( $width ? $width-1 : $monitor->ViewWidth()-1 ),
|
||||
( $height ? $height-1 : $monitor->ViewHeight()-1 )
|
||||
);
|
||||
}
|
||||
$row['Coords'] = pointsToCoords($row['Points']);
|
||||
|
@ -280,7 +286,7 @@ foreach ( $monitors as $monitor ) {
|
|||
} // end foreach Zone
|
||||
?>
|
||||
|
||||
<svg class="zones" id="zones<?php echo $monitor->Id() ?>" style="position:absolute; top: 0; left: 0; background: none; width: 100%; height: 100%;" viewBox="0 0 <?php echo $monitor->Width() ?> <?php echo $monitor->Height() ?>" preserveAspectRatio="none">
|
||||
<svg class="zones" id="zones<?php echo $monitor->Id() ?>" style="position:absolute; top: 0; left: 0; background: none; width: 100%; height: 100%;" viewBox="0 0 <?php echo $monitor->ViewWidth() ?> <?php echo $monitor->ViewHeight() ?>" preserveAspectRatio="none">
|
||||
<?php
|
||||
foreach( array_reverse($zones) as $zone ) {
|
||||
echo '<polygon points="'. $zone['AreaCoords'] .'" class="'. $zone['Type'].'" />';
|
||||
|
|
|
@ -139,36 +139,37 @@ foreach ( array_map('basename', glob('skins/'.$skin.'/css/*',GLOB_ONLYDIR)) as $
|
|||
<?php
|
||||
$sql = 'SELECT * FROM Monitors ORDER BY Sequence ASC';
|
||||
$monitors = array();
|
||||
foreach( dbFetchAll($sql) as $monitor ) {
|
||||
foreach ( dbFetchAll($sql) as $monitor ) {
|
||||
$monitors[$monitor['Id']] = $monitor;
|
||||
}
|
||||
|
||||
$sql = 'SELECT * FROM Users ORDER BY Username';
|
||||
foreach( dbFetchAll($sql) as $row ) {
|
||||
foreach ( dbFetchAll($sql) as $user_row ) {
|
||||
$userMonitors = array();
|
||||
if ( !empty($row['MonitorIds']) ) {
|
||||
foreach ( explode(',', $row['MonitorIds']) as $monitorId ) {
|
||||
if ( !empty($user_row['MonitorIds']) ) {
|
||||
foreach ( explode(',', $user_row['MonitorIds']) as $monitorId ) {
|
||||
// A deleted monitor will cause an error since we don't update
|
||||
// the user monitors list on monitor delete
|
||||
if ( ! isset($monitors[$monitorId]) ) continue;
|
||||
if ( !isset($monitors[$monitorId]) ) continue;
|
||||
$userMonitors[] = $monitors[$monitorId]['Name'];
|
||||
}
|
||||
}
|
||||
ZM\Logger::Debug("monitors: ".$user_row['Username'] . ' ' . $user_row['MonitorIds']. ' :' . print_r($userMonitors, true));
|
||||
?>
|
||||
<tr>
|
||||
<td class="colUsername"><?php echo makePopupLink('?view=user&uid='.$row['Id'], 'zmUser', 'user', validHtmlStr($row['Username']).($user['Username']==$row['Username']?"*":""), $canEdit) ?></td>
|
||||
<td class="colLanguage"><?php echo $row['Language']?validHtmlStr($row['Language']):'default' ?></td>
|
||||
<td class="colEnabled"><?php echo $row['Enabled']?translate('Yes'):translate('No') ?></td>
|
||||
<td class="colStream"><?php echo validHtmlStr($row['Stream']) ?></td>
|
||||
<td class="colEvents"><?php echo validHtmlStr($row['Events']) ?></td>
|
||||
<td class="colControl"><?php echo validHtmlStr($row['Control']) ?></td>
|
||||
<td class="colMonitors"><?php echo validHtmlStr($row['Monitors']) ?></td>
|
||||
<td class="colGroups"><?php echo validHtmlStr($row['Groups']) ?></td>
|
||||
<td class="colSystem"><?php echo validHtmlStr($row['System']) ?></td>
|
||||
<td class="colBandwidth"><?php echo $row['MaxBandwidth']?$bandwidth_options[$row['MaxBandwidth']]:' ' ?></td>
|
||||
<td class="colMonitor"><?php echo $row['MonitorIds']?(join( ", ", $userMonitors )):" " ?></td>
|
||||
<?php if ( ZM_OPT_USE_API ) { ?><td class="colAPIEnabled"><?php echo $row['APIEnabled']?translate('Yes'):translate('No') ?></td><?php } ?>
|
||||
<td class="colMark"><input type="checkbox" name="markUids[]" value="<?php echo $row['Id'] ?>" data-on-click-this="configureDeleteButton"<?php if ( !$canEdit ) { ?> disabled="disabled"<?php } ?>/></td>
|
||||
<td class="colUsername"><?php echo makePopupLink('?view=user&uid='.$user_row['Id'], 'zmUser', 'user', validHtmlStr($user_row['Username']).($user['Username']==$user_row['Username']?'*':''), $canEdit) ?></td>
|
||||
<td class="colLanguage"><?php echo $user_row['Language']?validHtmlStr($user_row['Language']):'default' ?></td>
|
||||
<td class="colEnabled"><?php echo translate($user_row['Enabled']?'Yes':'No') ?></td>
|
||||
<td class="colStream"><?php echo validHtmlStr($user_row['Stream']) ?></td>
|
||||
<td class="colEvents"><?php echo validHtmlStr($user_row['Events']) ?></td>
|
||||
<td class="colControl"><?php echo validHtmlStr($user_row['Control']) ?></td>
|
||||
<td class="colMonitors"><?php echo validHtmlStr($user_row['Monitors']) ?></td>
|
||||
<td class="colGroups"><?php echo validHtmlStr($user_row['Groups']) ?></td>
|
||||
<td class="colSystem"><?php echo validHtmlStr($user_row['System']) ?></td>
|
||||
<td class="colBandwidth"><?php echo $user_row['MaxBandwidth']?$bandwidth_options[$user_row['MaxBandwidth']]:' ' ?></td>
|
||||
<td class="colMonitor"><?php echo count($userMonitors)?(join(', ', $userMonitors)):' ' ?></td>
|
||||
<?php if ( ZM_OPT_USE_API ) { ?><td class="colAPIEnabled"><?php echo translate($user_row['APIEnabled']?'Yes':'No') ?></td><?php } ?>
|
||||
<td class="colMark"><input type="checkbox" name="markUids[]" value="<?php echo $user_row['Id'] ?>" data-on-click-this="configureDeleteButton"<?php if ( !$canEdit ) { ?> disabled="disabled"<?php } ?>/></td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
|
@ -351,7 +352,6 @@ foreach ( array_map('basename', glob('skins/'.$skin.'/css/*',GLOB_ONLYDIR)) as $
|
|||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
|
||||
$sql = 'SELECT * FROM Users ORDER BY Username';
|
||||
foreach ( dbFetchAll($sql) as $row ) {
|
||||
?>
|
||||
|
@ -379,7 +379,7 @@ foreach ( array_map('basename', glob('skins/'.$skin.'/css/*',GLOB_ONLYDIR)) as $
|
|||
$result = $dbConn->query('SELECT * FROM `Config` ORDER BY `Id` ASC');
|
||||
if ( !$result )
|
||||
echo mysql_error();
|
||||
while( $row = dbFetchNext($result) ) {
|
||||
while ( $row = dbFetchNext($result) ) {
|
||||
$config[$row['Name']] = $row;
|
||||
if ( !($configCat = &$configCats[$row['Category']]) ) {
|
||||
$configCats[$row['Category']] = array();
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
|
||||
$selfEdit = ZM_USER_SELF_EDIT && $_REQUEST['uid'] == $user['Id'];
|
||||
$selfEdit = ZM_USER_SELF_EDIT && ($_REQUEST['uid'] == $user['Id']);
|
||||
|
||||
if ( !canEdit('System') && !$selfEdit ) {
|
||||
$view = 'error';
|
||||
|
@ -45,10 +45,12 @@ $nve = array( 'None'=>translate('None'), 'View'=>translate('View'), 'Edit'=>tran
|
|||
$bandwidths = array_merge( array( ''=>'' ), $bandwidth_options );
|
||||
$langs = array_merge( array( ''=>'' ), getLanguages() );
|
||||
|
||||
$sql = 'SELECT Id,Name FROM Monitors ORDER BY Sequence ASC';
|
||||
$sql = 'SELECT Id, Name FROM Monitors ORDER BY Sequence ASC';
|
||||
$monitors = array();
|
||||
foreach( dbFetchAll($sql) as $monitor ) {
|
||||
$monitors[] = $monitor;
|
||||
foreach ( dbFetchAll($sql) as $monitor ) {
|
||||
if ( visibleMonitor($monitor['Id']) ) {
|
||||
$monitors[$monitor['Id']] = $monitor;
|
||||
}
|
||||
}
|
||||
|
||||
$focusWindow = true;
|
||||
|
@ -61,11 +63,8 @@ xhtmlHeaders(__FILE__, translate('User').' - '.$newUser['Username']);
|
|||
<h2><?php echo translate('User').' - '.validHtmlStr($newUser['Username']); ?></h2>
|
||||
</div>
|
||||
<div id="content">
|
||||
<form name="contentForm" method="post" action="?" onsubmit="return validateForm( this, <?php echo empty($newUser['Password'])?'true':'false' ?> )">
|
||||
<input type="hidden" name="view" value="<?php echo $view ?>"/>
|
||||
<input type="hidden" name="action" value="user"/>
|
||||
<form id="contentForm" name="contentForm" method="post" action="?view=user">
|
||||
<input type="hidden" name="uid" value="<?php echo validHtmlStr($_REQUEST['uid']) ?>"/>
|
||||
<input type="hidden" name="newUser[MonitorIds]" value="<?php echo validHtmlStr($newUser['MonitorIds']); ?>"/>
|
||||
<table id="contentTable" class="major">
|
||||
<tbody>
|
||||
<?php
|
||||
|
@ -73,7 +72,7 @@ if ( canEdit('System') ) {
|
|||
?>
|
||||
<tr>
|
||||
<th scope="row"><?php echo translate('Username') ?></th>
|
||||
<td><input type="text" name="newUser[Username]" value="<?php echo validHtmlStr($newUser['Username']); ?>"/></td>
|
||||
<td><input type="text" name="newUser[Username]" value="<?php echo validHtmlStr($newUser['Username']); ?>"<?php echo $newUser['Username'] == 'admin' ? ' readonly="readonly"':''?>/></td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
|
@ -88,63 +87,53 @@ if ( canEdit('System') ) {
|
|||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php echo translate('Language') ?></th>
|
||||
<td><?php echo buildSelect( "newUser[Language]", $langs ) ?></td>
|
||||
<td><?php echo htmlSelect('newUser[Language]', $langs, $newUser['Language']) ?></td>
|
||||
</tr>
|
||||
<?php
|
||||
if ( canEdit('System') ) {
|
||||
if ( canEdit('System') and ( $newUser['Username'] != 'admin' ) ) {
|
||||
?>
|
||||
<tr>
|
||||
<th scope="row"><?php echo translate('Enabled') ?></th>
|
||||
<td><?php echo buildSelect( "newUser[Enabled]", $yesno ) ?></td>
|
||||
<td><?php echo htmlSelect('newUser[Enabled]', $yesno, $newUser['Enabled']) ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php echo translate('Stream') ?></th>
|
||||
<td><?php echo buildSelect( "newUser[Stream]", $nv ) ?></td>
|
||||
<td><?php echo htmlSelect('newUser[Stream]', $nv, $newUser['Stream']) ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php echo translate('Events') ?></th>
|
||||
<td><?php echo buildSelect( "newUser[Events]", $nve ) ?></td>
|
||||
<td><?php echo htmlSelect('newUser[Events]', $nve, $newUser['Events']) ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php echo translate('Control') ?></th>
|
||||
<td><?php echo buildSelect( "newUser[Control]", $nve ) ?></td>
|
||||
<td><?php echo htmlSelect('newUser[Control]', $nve, $newUser['Control']) ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php echo translate('Monitors') ?></th>
|
||||
<td><?php echo buildSelect( "newUser[Monitors]", $nve ) ?></td>
|
||||
<td><?php echo htmlSelect('newUser[Monitors]', $nve, $newUser['Monitors']) ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php echo translate('Groups') ?></th>
|
||||
<td><?php echo buildSelect( "newUser[Groups]", $nve ) ?></td>
|
||||
<td><?php echo htmlSelect('newUser[Groups]', $nve, $newUser['Groups']) ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php echo translate('System') ?></th>
|
||||
<td><?php echo buildSelect( "newUser[System]", $nve ) ?></td>
|
||||
<td><?php echo htmlSelect('newUser[System]', $nve, $newUser['System']) ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php echo translate('MaxBandwidth') ?></th>
|
||||
<td><?php echo buildSelect( "newUser[MaxBandwidth]", $bandwidths ) ?></td>
|
||||
<td><?php echo htmlSelect('newUser[MaxBandwidth]', $bandwidths, $newUser['MaxBandwidth']) ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php echo translate('RestrictedMonitors') ?></th>
|
||||
<td>
|
||||
<select name="monitorIds" size="4" multiple="multiple">
|
||||
<?php
|
||||
foreach ( $monitors as $monitor ) {
|
||||
if ( visibleMonitor($monitor['Id']) ) {
|
||||
?>
|
||||
<option value="<?php echo $monitor['Id'] ?>"<?php if ( array_key_exists($monitor['Id'], $monitorIds) ) { ?> selected="selected"<?php } ?>><?php echo htmlentities($monitor['Name']) ?></option>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<?php echo htmlSelect('newUser[MonitorIds][]', $monitors, explode(',', $newUser['MonitorIds']), array('multiple'=>'multiple')); ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php if ( ZM_OPT_USE_API ) { ?>
|
||||
<tr>
|
||||
<th scope="row"><?php echo translate('APIEnabled')?></th>
|
||||
<td><?php echo buildSelect( "newUser[APIEnabled]", $yesno ) ?></td>
|
||||
<td><?php echo htmlSelect('newUser[APIEnabled]', $yesno, $newUser['APIEnabled']) ?></td>
|
||||
</tr>
|
||||
|
||||
<?php
|
||||
|
@ -154,7 +143,7 @@ if ( canEdit('System') ) {
|
|||
</tbody>
|
||||
</table>
|
||||
<div id="contentButtons">
|
||||
<button type="submit" value="Save"><?php echo translate('Save') ?></button>
|
||||
<button type="submit" name="action" value="Save"><?php echo translate('Save') ?></button>
|
||||
<button type="button" data-on-click="closeWindow"><?php echo translate('Cancel') ?></button>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
|
||||
if ( !canView('Monitors') ) {
|
||||
$mid = empty($_REQUEST['mid']) ? 0 : validInt($_REQUEST['mid']);
|
||||
if ( !($mid and canEdit('Monitors', $mid)) ) {
|
||||
$view = 'error';
|
||||
return;
|
||||
}
|
||||
|
||||
$mid = validInt($_REQUEST['mid']);
|
||||
$zid = (!empty($_REQUEST['zid'])) ? validInt($_REQUEST['zid']) : 0;
|
||||
|
||||
$scale = SCALE_BASE;
|
||||
|
@ -212,8 +212,8 @@ xhtmlHeaders(__FILE__, translate('Zone'));
|
|||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php echo translate('ZoneMinMaxPixelThres') ?></th>
|
||||
<td><input type="number" name="newZone[MinPixelThreshold]" value="<?php echo $newZone['MinPixelThreshold'] ?>"/></td>
|
||||
<td><input type="number" name="newZone[MaxPixelThreshold]" value="<?php echo $newZone['MaxPixelThreshold'] ?>"/></td>
|
||||
<td><input type="number" name="newZone[MinPixelThreshold]" value="<?php echo $newZone['MinPixelThreshold'] ?>" min="0" max="255"/></td>
|
||||
<td><input type="number" name="newZone[MaxPixelThreshold]" value="<?php echo $newZone['MaxPixelThreshold'] ?>" min="0" max="255"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php echo translate('ZoneFilterSize') ?></th>
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
|
||||
if ( !canView('Monitors') ) {
|
||||
$mid = empty($_REQUEST['mid']) ? 0 : validInt($_REQUEST['mid']);
|
||||
if ( !($mid and canEdit('Monitors', $mid)) ) {
|
||||
$view = 'error';
|
||||
return;
|
||||
}
|
||||
|
||||
$mid = validInt($_REQUEST['mid']);
|
||||
$monitor = new ZM\Monitor($mid);
|
||||
# ViewWidth() and ViewHeight() are already rotated
|
||||
$minX = 0;
|
||||
|
|
Loading…
Reference in New Issue