Merge branch 'master' into zma_to_thread
This commit is contained in:
commit
a39a656373
|
@ -1,3 +1,5 @@
|
||||||
|
<!--
|
||||||
|
|
||||||
**THIS FORUM IS FOR BUG REPORTS ONLY**
|
**THIS FORUM IS FOR BUG REPORTS ONLY**
|
||||||
|
|
||||||
Do not post feature or enhancement requests, general discussions, or support questions here.
|
Do not post feature or enhancement requests, general discussions, or support questions here.
|
||||||
|
@ -12,35 +14,46 @@ Docker related issues should be posted here: https://github.com/ZoneMinder/zmdoc
|
||||||
In order to submit a bug report, please populate the fields below this line. This is required.
|
In order to submit a bug report, please populate the fields below this line. This is required.
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------------------------
|
||||||
|
-->
|
||||||
**Describe Your Environment**
|
**Describe Your Environment**
|
||||||
|
<!--
|
||||||
- Version of ZoneMinder [release version, development version, or commit]
|
- Version of ZoneMinder [release version, development version, or commit]
|
||||||
- How you installed ZoneMinder [e.g. PPA, RPMFusion, from-source, etc]
|
- How you installed ZoneMinder [e.g. PPA, RPMFusion, from-source, etc]
|
||||||
- Full name and version of OS
|
- Full name and version of OS
|
||||||
- Browser name and version (if this is an issue with the web interface)
|
- Browser name and version (if this is an issue with the web interface)
|
||||||
|
-->
|
||||||
|
|
||||||
**If the issue concerns a camera**
|
**If the issue concerns a camera**
|
||||||
|
<!--
|
||||||
- Make and Model
|
- Make and Model
|
||||||
- Frame rate
|
- Frame rate
|
||||||
- Resolution
|
- Resolution
|
||||||
- ZoneMinder Source Type:
|
- ZoneMinder Source Type:
|
||||||
|
-->
|
||||||
|
|
||||||
**Describe the bug**
|
**Describe the bug**
|
||||||
|
<!--
|
||||||
A clear and concise description of what the bug is.
|
A clear and concise description of what the bug is.
|
||||||
|
-->
|
||||||
**To Reproduce**
|
**To Reproduce**
|
||||||
|
<!--
|
||||||
Steps to reproduce the behavior:
|
Steps to reproduce the behavior:
|
||||||
1. Go to '...'
|
1. Go to '...'
|
||||||
2. Click on '....'
|
2. Click on '....'
|
||||||
3. Scroll down to '....'
|
3. Scroll down to '....'
|
||||||
4. See error
|
4. See error
|
||||||
|
-->
|
||||||
|
|
||||||
**Expected behavior**
|
**Expected behavior**
|
||||||
|
<!--
|
||||||
A clear and concise description of what you expected to happen.
|
A clear and concise description of what you expected to happen.
|
||||||
|
-->
|
||||||
|
|
||||||
**Debug Logs**
|
**Debug Logs**
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<!--
|
||||||
<insert debug logs here, please make sure they are within the ``` quotes so they are formatted properly>
|
<insert debug logs here, please make sure they are within the ``` quotes so they are formatted properly>
|
||||||
|
-->
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -120,7 +120,7 @@ src/CMakeFiles/
|
||||||
src/cmake_install.cmake
|
src/cmake_install.cmake
|
||||||
src/libzm.a
|
src/libzm.a
|
||||||
src/nph-zms
|
src/nph-zms
|
||||||
src/zm_config.h
|
src/zm_config_data.h
|
||||||
src/zm_config_defines.h
|
src/zm_config_defines.h
|
||||||
src/zma
|
src/zma
|
||||||
src/zmc
|
src/zmc
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
language: cpp
|
language: cpp
|
||||||
sudo: required
|
sudo: required
|
||||||
dist: xenial
|
dist: bionic
|
||||||
git:
|
git:
|
||||||
depth: 9999999
|
depth: 9999999
|
||||||
notifications:
|
notifications:
|
||||||
|
@ -32,20 +32,17 @@ install:
|
||||||
- update-binfmts --enable qemu-arm
|
- update-binfmts --enable qemu-arm
|
||||||
|
|
||||||
env:
|
env:
|
||||||
|
- SMPFLAGS=-j4 OS=eslint DIST=eslint
|
||||||
- SMPFLAGS=-j4 OS=el DIST=7 DOCKER_REPO=knnniggett/packpack
|
- SMPFLAGS=-j4 OS=el DIST=7 DOCKER_REPO=knnniggett/packpack
|
||||||
- SMPFLAGS=-j4 OS=el DIST=8 DOCKER_REPO=knnniggett/packpack
|
- SMPFLAGS=-j4 OS=el DIST=8 DOCKER_REPO=knnniggett/packpack
|
||||||
- SMPFLAGS=-j4 OS=fedora DIST=31 DOCKER_REPO=knnniggett/packpack
|
- SMPFLAGS=-j4 OS=fedora DIST=31 DOCKER_REPO=knnniggett/packpack
|
||||||
- SMPFLAGS=-j4 OS=fedora DIST=32 DOCKER_REPO=knnniggett/packpack
|
- SMPFLAGS=-j4 OS=fedora DIST=32 DOCKER_REPO=knnniggett/packpack
|
||||||
- SMPFLAGS=-j4 OS=ubuntu DIST=trusty DOCKER_REPO=iconzm/packpack
|
- SMPFLAGS=-j4 OS=fedora DIST=33 DOCKER_REPO=knnniggett/packpack
|
||||||
- SMPFLAGS=-j4 OS=ubuntu DIST=xenial DOCKER_REPO=iconzm/packpack
|
- SMPFLAGS=-j4 OS=ubuntu DIST=xenial DOCKER_REPO=iconzm/packpack
|
||||||
- SMPFLAGS=-j4 OS=ubuntu DIST=bionic DOCKER_REPO=iconzm/packpack
|
- SMPFLAGS=-j4 OS=ubuntu DIST=bionic DOCKER_REPO=iconzm/packpack
|
||||||
- SMPFLAGS=-j4 OS=ubuntu DIST=disco DOCKER_REPO=iconzm/packpack
|
|
||||||
- SMPFLAGS=-j4 OS=ubuntu DIST=eoan DOCKER_REPO=iconzm/packpack
|
|
||||||
- SMPFLAGS=-j4 OS=ubuntu DIST=focal DOCKER_REPO=iconzm/packpack
|
- SMPFLAGS=-j4 OS=ubuntu DIST=focal DOCKER_REPO=iconzm/packpack
|
||||||
- SMPFLAGS=-j4 OS=debian DIST=jessie DOCKER_REPO=iconzm/packpack
|
|
||||||
- SMPFLAGS=-j4 OS=debian DIST=stretch DOCKER_REPO=iconzm/packpack
|
- SMPFLAGS=-j4 OS=debian DIST=stretch DOCKER_REPO=iconzm/packpack
|
||||||
- SMPFLAGS=-j4 OS=debian DIST=buster DOCKER_REPO=iconzm/packpack
|
- SMPFLAGS=-j4 OS=debian DIST=buster DOCKER_REPO=iconzm/packpack
|
||||||
- SMPFLAGS=-j4 OS=eslint DIST=eslint
|
|
||||||
|
|
||||||
compiler:
|
compiler:
|
||||||
- gcc
|
- gcc
|
||||||
|
|
|
@ -73,15 +73,16 @@ properly and are documented.
|
||||||
## Contribution Model and Development
|
## Contribution Model and Development
|
||||||
|
|
||||||
* Source hosted at [GitHub](https://github.com/ZoneMinder/ZoneMinder/)
|
* Source hosted at [GitHub](https://github.com/ZoneMinder/ZoneMinder/)
|
||||||
* Report issues/questions/feature requests on [GitHub Issues](https://github.com/ZoneMinder/ZoneMinder/issues)
|
* Report issues at [GitHub Issues](https://github.com/ZoneMinder/ZoneMinder/issues)
|
||||||
|
* Questions/feature requests in [Slack](https://zoneminder-chat.slack.com/) or [forums](https://forums.zoneminder.com)
|
||||||
|
|
||||||
Pull requests are very welcome! If you would like to contribute, please follow
|
Pull requests are very welcome! If you would like to contribute, please follow
|
||||||
the following steps. While step 3 is optional, it is preferred.
|
the following steps. While step 3 is optional, it is preferred.
|
||||||
|
|
||||||
1. Fork the repo
|
1. Fork the repo
|
||||||
2. Open an issue at our [GitHub Issues Tracker](https://github.com/ZoneMinder/ZoneMinder/issues).
|
2. Open an issue at our [GitHub Issues Tracker](https://github.com/ZoneMinder/ZoneMinder/issues).
|
||||||
Describe the bug that you've found, or the feature which you're asking for.
|
Follow the issue template to describe the bug or security issue you found. Please note feature
|
||||||
Jot down the issue number (e.g. 456)
|
requests or questions should be posted in our user forum or Slack channel.
|
||||||
3. Create your feature branch (`git checkout -b 456-my-new-feature`)
|
3. Create your feature branch (`git checkout -b 456-my-new-feature`)
|
||||||
4. Commit your changes (`git commit -am 'Added some feature'`)
|
4. Commit your changes (`git commit -am 'Added some feature'`)
|
||||||
It is preferred that you 'commit early and often' instead of bunching all
|
It is preferred that you 'commit early and often' instead of bunching all
|
||||||
|
|
|
@ -46,3 +46,6 @@ ZM_PATH_SWAP=@ZM_TMPDIR@
|
||||||
# Full path to optional arp binary
|
# Full path to optional arp binary
|
||||||
# ZoneMinder will find the arp binary automatically on most systems
|
# ZoneMinder will find the arp binary automatically on most systems
|
||||||
ZM_PATH_ARP="@ZM_PATH_ARP@"
|
ZM_PATH_ARP="@ZM_PATH_ARP@"
|
||||||
|
|
||||||
|
#Full path to shutdown binary
|
||||||
|
ZM_PATH_SHUTDOWN="@ZM_PATH_SHUTDOWN@"
|
||||||
|
|
|
@ -485,7 +485,7 @@ CREATE TABLE `Monitors` (
|
||||||
`Hue` mediumint(7) NOT NULL default '-1',
|
`Hue` mediumint(7) NOT NULL default '-1',
|
||||||
`Colour` mediumint(7) NOT NULL default '-1',
|
`Colour` mediumint(7) NOT NULL default '-1',
|
||||||
`EventPrefix` varchar(32) NOT NULL default 'Event-',
|
`EventPrefix` varchar(32) NOT NULL default 'Event-',
|
||||||
`LabelFormat` varchar(64) default '%N - %y/%m/%d %H:%M:%S',
|
`LabelFormat` varchar(64),
|
||||||
`LabelX` smallint(5) unsigned NOT NULL default '0',
|
`LabelX` smallint(5) unsigned NOT NULL default '0',
|
||||||
`LabelY` smallint(5) unsigned NOT NULL default '0',
|
`LabelY` smallint(5) unsigned NOT NULL default '0',
|
||||||
`LabelSize` smallint(5) unsigned NOT NULL DEFAULT '1',
|
`LabelSize` smallint(5) unsigned NOT NULL DEFAULT '1',
|
||||||
|
|
|
@ -13,6 +13,8 @@ SET @s = (SELECT IF(
|
||||||
PREPARE stmt FROM @s;
|
PREPARE stmt FROM @s;
|
||||||
EXECUTE stmt;
|
EXECUTE stmt;
|
||||||
|
|
||||||
|
UPDATE `Events` SET `SaveJPEGs`=(SELECT `SaveJPEGs` FROM `Monitors` WHERE Monitors.Id = MonitorId) WHERE `SaveJPEGs` IS NULL;
|
||||||
|
|
||||||
SET @s = (SELECT IF(
|
SET @s = (SELECT IF(
|
||||||
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
|
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
|
||||||
AND table_name = 'Storage'
|
AND table_name = 'Storage'
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
/* This was done in 1.31.0 but zm_create.sql.in wasn't updated to match. */
|
||||||
|
ALTER TABLE Monitors MODIFY LinkedMonitors varchar(255);
|
|
@ -0,0 +1,2 @@
|
||||||
|
/* This was done in 1.31.0 but zm_create.sql.in wasn't updated to match. */
|
||||||
|
ALTER TABLE Monitors MODIFY LinkedMonitors varchar(255);
|
|
@ -0,0 +1,10 @@
|
||||||
|
zoneminder (1.28.1-1) unstable; urgency=low
|
||||||
|
|
||||||
|
This version is no longer automatically initialize or upgrade database.
|
||||||
|
See README.Debian for details.
|
||||||
|
|
||||||
|
Changed installation paths (please correct your web server configuration):
|
||||||
|
/usr/share/zoneminder --> /usr/share/zoneminder/www
|
||||||
|
/usr/lib/cgi-bin --> /usr/lib/zoneminder/cgi-bin
|
||||||
|
|
||||||
|
-- Dmitry Smirnov <onlyjob@debian.org> Tue, 31 Mar 2015 15:12:17 +1100
|
|
@ -0,0 +1,130 @@
|
||||||
|
Zoneminder for Debian
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
Initializing database
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
pv /usr/share/zoneminder/db/zm_create.sql | sudo mysql --defaults-file=/etc/mysql/debian.cnf
|
||||||
|
OR
|
||||||
|
cat /usr/share/zoneminder/db/zm_create.sql | sudo mysql --defaults-file=/etc/mysql/debian.cnf
|
||||||
|
|
||||||
|
echo 'grant lock tables,alter,create,index,select,insert,update,delete on zm.* to 'zmuser'@localhost identified by "zmpass";'\
|
||||||
|
| sudo mysql --defaults-file=/etc/mysql/debian.cnf mysql
|
||||||
|
|
||||||
|
Hint: generate secure password with `pwgen` and update "/etc/zm/zm.conf"
|
||||||
|
accordingly.
|
||||||
|
|
||||||
|
The following command can help to ensure that zoneminder can read its
|
||||||
|
configuration file:
|
||||||
|
|
||||||
|
chgrp -c www-data /etc/zm/zm.conf
|
||||||
|
|
||||||
|
|
||||||
|
Upgrading database
|
||||||
|
------------------
|
||||||
|
|
||||||
|
The database is updated automatically on installation. You should not need to take this step.
|
||||||
|
|
||||||
|
Assuming that database is on "localhost" then the following command can be
|
||||||
|
used to upgrade "zm" database:
|
||||||
|
|
||||||
|
zmupdate.pl
|
||||||
|
|
||||||
|
Additional permissions may be required to perform upgrade:
|
||||||
|
|
||||||
|
echo 'grant lock tables, create, alter on zm.* to 'zmuser'@localhost identified by "zmpass";'\
|
||||||
|
| sudo mysql --defaults-file=/etc/mysql/debian.cnf mysql
|
||||||
|
|
||||||
|
The following command prints the current version of zoneminder database:
|
||||||
|
|
||||||
|
echo 'select Value from Config where Name = "ZM_DYN_CURR_VERSION";' \
|
||||||
|
| sudo mysql --defaults-file=/etc/mysql/debian.cnf --skip-column-names zm
|
||||||
|
|
||||||
|
|
||||||
|
Enabling service
|
||||||
|
----------------
|
||||||
|
|
||||||
|
By default Zoneminder service is not automatically started and needs to be
|
||||||
|
manually enabled once database is configured:
|
||||||
|
|
||||||
|
sudo systemctl enable zoneminder.service
|
||||||
|
|
||||||
|
|
||||||
|
Web server set-up
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
There are few manual steps to get the web interface working:
|
||||||
|
|
||||||
|
## Apache2
|
||||||
|
|
||||||
|
Apache can be configured as folder "/zm" using sample .conf:
|
||||||
|
|
||||||
|
sudo a2enconf zoneminder
|
||||||
|
|
||||||
|
Alternatively Apache web site configuration template can be used to setup
|
||||||
|
zoneminder as "http://zoneminder":
|
||||||
|
|
||||||
|
sudo cp -v /usr/share/doc/zoneminder/examples/apache.conf /etc/apache2/sites-available/
|
||||||
|
sudo a2ensite zoneminder.conf
|
||||||
|
|
||||||
|
Common configuration steps for Apache2:
|
||||||
|
|
||||||
|
sudo a2enmod cgi
|
||||||
|
sudo service apache2 reload
|
||||||
|
|
||||||
|
|
||||||
|
## nginx / fcgiwrap
|
||||||
|
|
||||||
|
Nginx needs "php-fpm" package to support PHP and "fcgiwrap" package
|
||||||
|
for binary "cgi-bin" applications:
|
||||||
|
|
||||||
|
sudo apt-get install php-fpm fcgiwrap
|
||||||
|
|
||||||
|
To enable a URL alias that makes Zoneminder available from
|
||||||
|
|
||||||
|
http://yourserver/zm
|
||||||
|
|
||||||
|
the following line is to be added to "server" section of a web site
|
||||||
|
configuration:
|
||||||
|
|
||||||
|
include /usr/share/doc/zoneminder/examples/nginx.conf;
|
||||||
|
|
||||||
|
For "default" web site it would be sufficient to include the above
|
||||||
|
statement to the file
|
||||||
|
|
||||||
|
/etc/nginx/sites-enabled/default
|
||||||
|
|
||||||
|
To avoid problems with feeds from multiple cameras "fcgiwrap" should be
|
||||||
|
configured to start at least as many processes as there are cameras.
|
||||||
|
It can be done by adjusting DAEMON_OPTS in "/etc/default/fcgiwrap".
|
||||||
|
Systemd users may be affected by the following bug:
|
||||||
|
|
||||||
|
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=792705
|
||||||
|
|
||||||
|
|
||||||
|
## Note:
|
||||||
|
|
||||||
|
When Zoneminder web site is running it may be necessary to set
|
||||||
|
Options/Paths/PATH_ZMS to "/zm/cgi-bin/nph-zms" or according to chosen web
|
||||||
|
site configuration.
|
||||||
|
|
||||||
|
|
||||||
|
Changing the location for images and events
|
||||||
|
-------------------------------------------
|
||||||
|
|
||||||
|
ZoneMinder is now able to be configured to use an alternative location for storing
|
||||||
|
events and images at compile time. This package makes use of that, so symlinks in
|
||||||
|
/usr/share/zoneminder/www are no longer necessary.
|
||||||
|
|
||||||
|
Access to /dev/video*
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
For cameras which require access to /dev/video*, zoneminder may need the
|
||||||
|
www-data user added to the video group in order to see those cameras:
|
||||||
|
|
||||||
|
adduser www-data video
|
||||||
|
|
||||||
|
Note that all web applications running on the zoneminder server will then have
|
||||||
|
access to all video devices on the system.
|
||||||
|
|
||||||
|
-- Vagrant Cascadian <vagrant@debian.org> Sun, 27 Mar 2011 13:06:56 -0700
|
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
## Separate substantial /usr/share into its own arch-all package.
|
||||||
|
|
||||||
|
## Decide how to handle database updates.
|
||||||
|
|
||||||
|
* Consider possibility that database may be on another machine (#469239).
|
||||||
|
* Consider dbconfig-common? Probably not (what if database is not on localhost?).
|
||||||
|
|
||||||
|
### Run `zmupdate.pl` from service control scripts (init.d, service) on start?
|
||||||
|
|
||||||
|
Automatic upgrade will break "one DB, many zoneminders" setup (unimportant?).
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
zoneminder (1.31.39~20180223.27-stretch-1) unstable; urgency=low
|
||||||
|
*
|
||||||
|
-- Isaac Connor <iconnor@connortechnology.com> Fri, 23 Feb 2018 14:15:59 -0500
|
|
@ -0,0 +1,3 @@
|
||||||
|
.gitattributes
|
||||||
|
web/api/.gitattributes
|
||||||
|
web/api/.gitignore
|
|
@ -0,0 +1 @@
|
||||||
|
9
|
|
@ -0,0 +1,57 @@
|
||||||
|
# Remember to enable cgi mod (i.e. "a2enmod cgi").
|
||||||
|
ScriptAlias /zm/cgi-bin "/usr/lib/zoneminder/cgi-bin"
|
||||||
|
<Directory "/usr/lib/zoneminder/cgi-bin">
|
||||||
|
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
|
||||||
|
AllowOverride All
|
||||||
|
Require all granted
|
||||||
|
</Directory>
|
||||||
|
|
||||||
|
|
||||||
|
# Order matters. This alias must come first.
|
||||||
|
Alias /zm/cache /var/cache/zoneminder/cache
|
||||||
|
<Directory /var/cache/zoneminder/cache>
|
||||||
|
Options -Indexes +FollowSymLinks
|
||||||
|
AllowOverride None
|
||||||
|
<IfModule mod_authz_core.c>
|
||||||
|
# Apache 2.4
|
||||||
|
Require all granted
|
||||||
|
</IfModule>
|
||||||
|
<IfModule !mod_authz_core.c>
|
||||||
|
# Apache 2.2
|
||||||
|
Order deny,allow
|
||||||
|
Allow from all
|
||||||
|
</IfModule>
|
||||||
|
</Directory>
|
||||||
|
|
||||||
|
Alias /zm /usr/share/zoneminder/www
|
||||||
|
<Directory /usr/share/zoneminder/www>
|
||||||
|
Options -Indexes +FollowSymLinks
|
||||||
|
<IfModule mod_dir.c>
|
||||||
|
DirectoryIndex index.php
|
||||||
|
</IfModule>
|
||||||
|
</Directory>
|
||||||
|
|
||||||
|
# For better visibility, the following directives have been migrated from the
|
||||||
|
# default .htaccess files included with the CakePHP project.
|
||||||
|
# Parameters not set here are inherited from the parent directive above.
|
||||||
|
<Directory "/usr/share/zoneminder/www/api">
|
||||||
|
RewriteEngine on
|
||||||
|
RewriteRule ^$ app/webroot/ [L]
|
||||||
|
RewriteRule (.*) app/webroot/$1 [L]
|
||||||
|
RewriteBase /zm/api
|
||||||
|
</Directory>
|
||||||
|
|
||||||
|
<Directory "/usr/share/zoneminder/www/api/app">
|
||||||
|
RewriteEngine on
|
||||||
|
RewriteRule ^$ webroot/ [L]
|
||||||
|
RewriteRule (.*) webroot/$1 [L]
|
||||||
|
RewriteBase /zm/api
|
||||||
|
</Directory>
|
||||||
|
|
||||||
|
<Directory "/usr/share/zoneminder/www/api/app/webroot">
|
||||||
|
RewriteEngine On
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-d
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-f
|
||||||
|
RewriteRule ^ index.php [L]
|
||||||
|
RewriteBase /zm/api
|
||||||
|
</Directory>
|
|
@ -0,0 +1,166 @@
|
||||||
|
Source: zoneminder
|
||||||
|
Section: net
|
||||||
|
Priority: optional
|
||||||
|
Maintainer: Isaac Connor <isaac@zoneminder.com>
|
||||||
|
Uploaders: Isaac Connor <isaac@zoneminder.com>
|
||||||
|
Build-Depends: debhelper, sphinx-doc, dh-linktree, dh-apache2
|
||||||
|
,cmake
|
||||||
|
,libx264-dev, libmp4v2-dev
|
||||||
|
,libavdevice-dev
|
||||||
|
,libavcodec-dev
|
||||||
|
,libavformat-dev
|
||||||
|
,libavutil-dev
|
||||||
|
,libswresample-dev
|
||||||
|
,libswscale-dev
|
||||||
|
,ffmpeg
|
||||||
|
,net-tools
|
||||||
|
,libbz2-dev
|
||||||
|
,libgcrypt20-dev
|
||||||
|
,libcurl4-gnutls-dev
|
||||||
|
,libturbojpeg0-dev
|
||||||
|
,default-libmysqlclient-dev | libmysqlclient-dev | libmariadbclient-dev-compat
|
||||||
|
,libpcre3-dev
|
||||||
|
,libpolkit-gobject-1-dev
|
||||||
|
,libv4l-dev [!hurd-any]
|
||||||
|
,libvlc-dev
|
||||||
|
,libdate-manip-perl
|
||||||
|
,libdbd-mysql-perl
|
||||||
|
,libphp-serialization-perl
|
||||||
|
,libsys-mmap-perl [!hurd-any]
|
||||||
|
,libwww-perl
|
||||||
|
,libdata-uuid-perl
|
||||||
|
,libssl-dev
|
||||||
|
,libcrypt-eksblowfish-perl
|
||||||
|
,libdata-entropy-perl
|
||||||
|
# Unbundled (dh_linktree):
|
||||||
|
,libjs-jquery
|
||||||
|
,libjs-mootools
|
||||||
|
Standards-Version: 3.9.8
|
||||||
|
Homepage: http://www.zoneminder.com/
|
||||||
|
Vcs-Browser: http://anonscm.debian.org/cgit/collab-maint/zoneminder.git
|
||||||
|
Vcs-Git: git://anonscm.debian.org/collab-maint/zoneminder.git
|
||||||
|
|
||||||
|
Package: zoneminder
|
||||||
|
Architecture: any
|
||||||
|
Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}
|
||||||
|
,javascript-common
|
||||||
|
,libmp4v2-2, libx264-155
|
||||||
|
,libswscale5
|
||||||
|
,libswresample3
|
||||||
|
,ffmpeg
|
||||||
|
,libdate-manip-perl, libmime-lite-perl, libmime-tools-perl
|
||||||
|
,libdbd-mysql-perl
|
||||||
|
,libphp-serialization-perl
|
||||||
|
,libmodule-load-conditional-perl
|
||||||
|
,libnet-sftp-foreign-perl
|
||||||
|
,libarchive-zip-perl
|
||||||
|
,libdbd-mysql-perl
|
||||||
|
,libdevice-serialport-perl
|
||||||
|
,libimage-info-perl
|
||||||
|
,libjson-maybexs-perl
|
||||||
|
,libsys-mmap-perl [!hurd-any]
|
||||||
|
,liburi-encode-perl
|
||||||
|
,libwww-perl, liburi-perl
|
||||||
|
,libdata-dump-perl
|
||||||
|
,libdatetime-perl
|
||||||
|
,libclass-std-fast-perl
|
||||||
|
,libsoap-wsdl-perl
|
||||||
|
,libio-socket-multicast-perl
|
||||||
|
,libdigest-sha-perl
|
||||||
|
,libsys-cpu-perl, libsys-meminfo-perl
|
||||||
|
,libdata-uuid-perl
|
||||||
|
,libnumber-bytes-human-perl
|
||||||
|
,libfile-slurp-perl
|
||||||
|
,mysql-client | mariadb-client | virtual-mysql-client
|
||||||
|
,perl-modules
|
||||||
|
,php-mysql, php-gd, php-apcu, php-apc | php-apcu-bc, php-json
|
||||||
|
,policykit-1
|
||||||
|
,rsyslog | system-log-daemon
|
||||||
|
,zip
|
||||||
|
,libpcre3
|
||||||
|
,libcrypt-eksblowfish-perl
|
||||||
|
,libdata-entropy-perl
|
||||||
|
Recommends: ${misc:Recommends}
|
||||||
|
,libapache2-mod-php | php-fpm
|
||||||
|
,mysql-server | mariadb-server | virtual-mysql-server
|
||||||
|
,zoneminder-doc (>= ${source:Version})
|
||||||
|
,ffmpeg
|
||||||
|
Suggests: fcgiwrap, logrotate
|
||||||
|
Description: video camera security and surveillance solution
|
||||||
|
ZoneMinder is intended for use in single or multi-camera video security
|
||||||
|
applications, including commercial or home CCTV, theft prevention and child
|
||||||
|
or family member or home monitoring and other care scenarios. It
|
||||||
|
supports capture, analysis, recording, and monitoring of video data coming
|
||||||
|
from one or more video or network cameras attached to a Linux system.
|
||||||
|
ZoneMinder also support web and semi-automatic control of Pan/Tilt/Zoom
|
||||||
|
cameras using a variety of protocols. It is suitable for use as a home
|
||||||
|
video security system and for commercial or professional video security
|
||||||
|
and surveillance. It can also be integrated into a home automation system
|
||||||
|
via X.10 or other protocols.
|
||||||
|
|
||||||
|
#Package: libzoneminder-perl
|
||||||
|
#Section: perl
|
||||||
|
#Architecture: all
|
||||||
|
#Multi-Arch: foreign
|
||||||
|
#Depends: ${misc:Depends}, ${perl:Depends}
|
||||||
|
# ,libarchive-zip-perl
|
||||||
|
# ,libdbd-mysql-perl
|
||||||
|
# ,libdevice-serialport-perl
|
||||||
|
# ,libimage-info-perl
|
||||||
|
# ,libjson-maybexs-perl
|
||||||
|
# ,libsys-mmap-perl [!hurd-any]
|
||||||
|
# ,liburi-encode-perl
|
||||||
|
# ,libwww-perl
|
||||||
|
#Description: ZoneMinder Perl libraries
|
||||||
|
# ZoneMinder is intended for use in single or multi-camera video security
|
||||||
|
# applications, including commercial or home CCTV, theft prevention and child
|
||||||
|
# or family member or home monitoring and other care scenarios. It
|
||||||
|
# supports capture, analysis, recording, and monitoring of video data coming
|
||||||
|
# from one or more video or network cameras attached to a Linux system.
|
||||||
|
# ZoneMinder also support web and semi-automatic control of Pan/Tilt/Zoom
|
||||||
|
# cameras using a variety of protocols. It is suitable for use as a home
|
||||||
|
# video security system and for commercial or professional video security
|
||||||
|
# and surveillance. It can also be integrated into a home automation system
|
||||||
|
# via X.10 or other protocols.
|
||||||
|
# .
|
||||||
|
# This package provides ZoneMinder Perl libraries; it can be used to
|
||||||
|
# write custom interfaces as well.
|
||||||
|
|
||||||
|
Package: zoneminder-doc
|
||||||
|
Section: doc
|
||||||
|
Architecture: all
|
||||||
|
Multi-Arch: foreign
|
||||||
|
Depends: ${misc:Depends}, ${sphinxdoc:Depends}, python-sphinx-rtd-theme | python3-sphinx-rtd-theme
|
||||||
|
Suggests: www-browser
|
||||||
|
Description: ZoneMinder documentation
|
||||||
|
ZoneMinder is intended for use in single or multi-camera video security
|
||||||
|
applications, including commercial or home CCTV, theft prevention and child
|
||||||
|
or family member or home monitoring and other care scenarios. It
|
||||||
|
supports capture, analysis, recording, and monitoring of video data coming
|
||||||
|
from one or more video or network cameras attached to a Linux system.
|
||||||
|
ZoneMinder also support web and semi-automatic control of Pan/Tilt/Zoom
|
||||||
|
cameras using a variety of protocols. It is suitable for use as a home
|
||||||
|
video security system and for commercial or professional video security
|
||||||
|
and surveillance. It can also be integrated into a home automation system
|
||||||
|
via X.10 or other protocols.
|
||||||
|
.
|
||||||
|
This package provides ZoneMinder documentation in HTML format.
|
||||||
|
|
||||||
|
Package: zoneminder-dbg
|
||||||
|
Section: debug
|
||||||
|
Priority: extra
|
||||||
|
Architecture: any
|
||||||
|
Depends: zoneminder (= ${binary:Version}), ${misc:Depends}
|
||||||
|
Description: Zoneminder -- debugging symbols
|
||||||
|
ZoneMinder is intended for use in single or multi-camera video security
|
||||||
|
applications, including commercial or home CCTV, theft prevention and child
|
||||||
|
or family member or home monitoring and other care scenarios. It
|
||||||
|
supports capture, analysis, recording, and monitoring of video data coming
|
||||||
|
from one or more video or network cameras attached to a Linux system.
|
||||||
|
ZoneMinder also support web and semi-automatic control of Pan/Tilt/Zoom
|
||||||
|
cameras using a variety of protocols. It is suitable for use as a home
|
||||||
|
video security system and for commercial or professional video security
|
||||||
|
and surveillance. It can also be integrated into a home automation system
|
||||||
|
via X.10 or other protocols.
|
||||||
|
.
|
||||||
|
This package provides debugging symbols
|
|
@ -0,0 +1,174 @@
|
||||||
|
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||||
|
Upstream-Name: ZoneMinder
|
||||||
|
Upstream-Contact: Philip Coombes <philip.coombes@zoneminder.com>
|
||||||
|
Source: https://github.com/ZoneMinder/ZoneMinder
|
||||||
|
Comment:
|
||||||
|
This package was originally debianized by matrix <matrix@cecilia>
|
||||||
|
on Mon, 7 Mar 2005 02:07:57 -0500.
|
||||||
|
It was re-done for submission to the Debian project by Peter Howard
|
||||||
|
<pjh@northern-ridge.com.au> on Fri, 8 Dec 2006 10:19:43 +1100
|
||||||
|
Files-Excluded:
|
||||||
|
web/skins/*/js/jquery-*
|
||||||
|
web/tools/mootools/*-yc.js
|
||||||
|
|
||||||
|
Files: *
|
||||||
|
Copyright: 2001-2014 Philip Coombes <philip.coombes@zoneminder.com>
|
||||||
|
2008 Brian Rudy <brudyNO@SPAMpraecogito.com>
|
||||||
|
2014 Vincent Giovannone
|
||||||
|
2013 Tim Craig <timcraigNO@SPAMsonic.net>
|
||||||
|
2003-2008 Corey DeLasaux
|
||||||
|
2001-2010 Chris Kistner
|
||||||
|
License: GPL-2+
|
||||||
|
|
||||||
|
Files: distros/*
|
||||||
|
Copyright: 2001-2008 Philip Coombes <philip.coombes@zoneminder.com>
|
||||||
|
2014 Isaac Connor <iconnor@connortechnology.com>
|
||||||
|
2005 Serg Oskin
|
||||||
|
License: GPL-2+
|
||||||
|
|
||||||
|
Files: web/skins/*/js/jquery-*
|
||||||
|
Copyright: 2010 John Resig
|
||||||
|
2010 The Dojo Foundation
|
||||||
|
License: GPL-2 or Expat
|
||||||
|
Comment:
|
||||||
|
Dual licensed under the MIT or GPL Version 2 licenses.
|
||||||
|
http://jquery.org/license
|
||||||
|
.
|
||||||
|
Includes Sizzle.js http://sizzlejs.com/
|
||||||
|
Released under the MIT, BSD, and GPL Licenses.
|
||||||
|
|
||||||
|
Files: web/tools/mootools/*.js
|
||||||
|
Copyright: 2009 Marcelo Jorge Vieira (metal) <metal@alucinados.com>
|
||||||
|
2006-2010 Valerio Proietti (http://mad4milk.net/)
|
||||||
|
License: Expat
|
||||||
|
|
||||||
|
Files: web/api/*
|
||||||
|
Copyright: 2005-2013 Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||||
|
License: Expat
|
||||||
|
|
||||||
|
Files:
|
||||||
|
cmake/Modules/CheckPrototypeDefinition*.cmake
|
||||||
|
cmake/Modules/FindGLIB2.cmake
|
||||||
|
cmake/Modules/FindPolkit.cmake
|
||||||
|
cmake/Modules/GNUInstallDirs.cmake
|
||||||
|
Copyright:
|
||||||
|
2005-2011 Kitware, Inc.
|
||||||
|
2010-2011 Andreas Schneider <asn@cryptomilk.org>
|
||||||
|
2009 Dario Freddi <drf@kde.org>
|
||||||
|
2008 Laurent Montel, <montel@kde.org>
|
||||||
|
2011 Nikita Krupen'ko <krnekit@gmail.com>
|
||||||
|
License: BSD-3-clause
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
.
|
||||||
|
* Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
.
|
||||||
|
* The names of Kitware, Inc., the Insight Consortium, or the names of
|
||||||
|
any consortium members, or of any contributors, may not be used to
|
||||||
|
endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
.
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
Files: cmake/Modules/FindPerlModules.cmake
|
||||||
|
Copyright: 2012 Iowa State University
|
||||||
|
License: Boost-1.0
|
||||||
|
Boost Software License - Version 1.0 - August 17th, 2003
|
||||||
|
.
|
||||||
|
Permission is hereby granted, free of charge, to any person or organization
|
||||||
|
obtaining a copy of the software and accompanying documentation covered by
|
||||||
|
this license (the "Software") to use, reproduce, display, distribute,
|
||||||
|
execute, and transmit the Software, and to prepare derivative works of the
|
||||||
|
Software, and to permit third-parties to whom the Software is furnished to
|
||||||
|
do so, all subject to the following:
|
||||||
|
.
|
||||||
|
The copyright notices in the Software and this entire statement, including
|
||||||
|
the above license grant, this restriction and the following disclaimer,
|
||||||
|
must be included in all copies of the Software, in whole or in part, and
|
||||||
|
all derivative works of the Software, unless such copies or derivative
|
||||||
|
works are solely in the form of machine-executable object code generated by
|
||||||
|
a source language processor.
|
||||||
|
.
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||||
|
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||||
|
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
Files: debian/*
|
||||||
|
Copyright: 2015 Dmitry Smirnov <onlyjob@debian.org>
|
||||||
|
2007-2014 Peter Howard <pjh@northern-ridge.com.au>
|
||||||
|
2010-2012 Vagrant Cascadian <vagrant@debian.org>
|
||||||
|
2001-2008 Philip Coombes <philip.coombes@zoneminder.com>
|
||||||
|
License: GPL-2+
|
||||||
|
|
||||||
|
License: Expat
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
.
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
.
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
License: GPL-2+
|
||||||
|
This package 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 package 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 package; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
.
|
||||||
|
The complete text of the GNU General Public License version 2
|
||||||
|
can be found in "/usr/share/common-licenses/GPL-2".
|
||||||
|
|
||||||
|
License: GPL-2
|
||||||
|
This package 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; version 2 of the License.
|
||||||
|
.
|
||||||
|
This package 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 package; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
.
|
||||||
|
The complete text of the GNU General Public License version 2
|
||||||
|
can be found in "/usr/share/common-licenses/GPL-2".
|
|
@ -0,0 +1,32 @@
|
||||||
|
location /zm/cgi-bin {
|
||||||
|
gzip off;
|
||||||
|
alias /usr/lib/zoneminder/cgi-bin;
|
||||||
|
|
||||||
|
include /etc/nginx/fastcgi_params;
|
||||||
|
fastcgi_param SCRIPT_FILENAME $request_filename;
|
||||||
|
fastcgi_pass unix:/var/run/fcgiwrap.socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /zm {
|
||||||
|
# if ($scheme ~ ^http:){
|
||||||
|
# rewrite ^(.*)$ https://$host$1 permanent;
|
||||||
|
# }
|
||||||
|
|
||||||
|
gzip off;
|
||||||
|
alias /usr/share/zoneminder/www;
|
||||||
|
index index.php;
|
||||||
|
|
||||||
|
location ~ \.php$ {
|
||||||
|
if (!-f $request_filename) { return 404; }
|
||||||
|
expires epoch;
|
||||||
|
include /etc/nginx/fastcgi_params;
|
||||||
|
fastcgi_param SCRIPT_FILENAME $request_filename;
|
||||||
|
fastcgi_index index.php;
|
||||||
|
fastcgi_pass unix:/var/run/php5-fpm.sock;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ \.(jpg|jpeg|gif|png|ico)$ {
|
||||||
|
access_log off;
|
||||||
|
expires 33d;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
[dch]
|
||||||
|
id-length = 0
|
||||||
|
|
||||||
|
[import-orig]
|
||||||
|
pristine-tar = False
|
||||||
|
merge = False
|
|
@ -0,0 +1,2 @@
|
||||||
|
usr/share/man/man3
|
||||||
|
usr/share/perl5
|
|
@ -0,0 +1,87 @@
|
||||||
|
#!/usr/bin/make -f
|
||||||
|
# -*- makefile -*-
|
||||||
|
|
||||||
|
# Uncomment this to turn on verbose mode.
|
||||||
|
#export DH_VERBOSE=1
|
||||||
|
|
||||||
|
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
|
||||||
|
export DEB_LDFLAGS_MAINT_APPEND += -Wl,--as-needed
|
||||||
|
|
||||||
|
ifeq ($(DEB_BUILD_ARCH_OS),hurd)
|
||||||
|
ARGS:= -DZM_NO_MMAP=ON
|
||||||
|
endif
|
||||||
|
|
||||||
|
%:
|
||||||
|
dh $@ --parallel --buildsystem=cmake --builddirectory=dbuild \
|
||||||
|
--with sphinxdoc,apache2,linktree
|
||||||
|
|
||||||
|
override_dh_auto_configure:
|
||||||
|
dh_auto_configure -- $(ARGS) \
|
||||||
|
-DCMAKE_VERBOSE_MAKEFILE=ON \
|
||||||
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
|
-DZM_CONFIG_DIR="/etc/zm" \
|
||||||
|
-DZM_CONFIG_SUBDIR="/etc/zm/conf.d" \
|
||||||
|
-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" \
|
||||||
|
-DZM_DIR_EVENTS="/var/cache/zoneminder/events" \
|
||||||
|
-DZM_PATH_SHUTDOWN="/sbin/shutdown" \
|
||||||
|
-DZM_PATH_ZMS="/zm/cgi-bin/nph-zms"
|
||||||
|
|
||||||
|
override_dh_clean:
|
||||||
|
dh_clean $(MANPAGES1)
|
||||||
|
$(RM) -r docs/_build
|
||||||
|
|
||||||
|
build-indep:
|
||||||
|
#$(MAKE) -C docs text
|
||||||
|
$(MAKE) -C docs html
|
||||||
|
|
||||||
|
MANPAGES1 = dbuild/scripts/zmupdate.pl.1
|
||||||
|
$(MANPAGES1):
|
||||||
|
# generate man page(s):
|
||||||
|
pod2man -s1 --stderr --utf8 $(patsubst %.1, %, $@) $@
|
||||||
|
|
||||||
|
## reproducible build:
|
||||||
|
LAST_CHANGE=$(shell dpkg-parsechangelog -S Date)
|
||||||
|
BUILD_DATE=$(shell LC_ALL=C date -u "+%B %d, %Y" -d "$(LAST_CHANGE)")
|
||||||
|
override_dh_installman: $(MANPAGES1)
|
||||||
|
$(MAKE) -C docs man SPHINXOPTS="-D today=\"$(BUILD_DATE)\""
|
||||||
|
dh_installman --language=C $(MANPAGES1)
|
||||||
|
|
||||||
|
override_dh_auto_install:
|
||||||
|
dh_auto_install --destdir=$(CURDIR)/debian/tmp
|
||||||
|
# remove worthless files:
|
||||||
|
$(RM) -v $(CURDIR)/debian/tmp/usr/share/perl5/*/*/*/.packlist
|
||||||
|
$(RM) -v $(CURDIR)/debian/tmp/usr/share/perl5/*/*.in
|
||||||
|
# remove empty directories:
|
||||||
|
find $(CURDIR)/debian/tmp/usr -type d -empty -delete -printf 'removed %p\n'
|
||||||
|
# remove extra-license-file:
|
||||||
|
$(RM) -v $(CURDIR)/debian/tmp/usr/share/zoneminder/www/api/lib/Cake/LICENSE.txt
|
||||||
|
|
||||||
|
override_dh_fixperms:
|
||||||
|
dh_fixperms
|
||||||
|
#
|
||||||
|
# As requested by the Debian Webapps Policy Manual §3.2.1
|
||||||
|
chown root:www-data $(CURDIR)/debian/zoneminder/etc/zm/zm.conf
|
||||||
|
chmod 640 $(CURDIR)/debian/zoneminder/etc/zm/zm.conf
|
||||||
|
|
||||||
|
override_dh_strip:
|
||||||
|
[ -d "$(CURDIR)/debian/zoneminder-dbg" ] \
|
||||||
|
&& dh_strip --dbg-package=zoneminder-dbg \
|
||||||
|
|| dh_strip
|
||||||
|
|
||||||
|
#%:
|
||||||
|
# dh $@ --parallel --buildsystem=autoconf --with autoreconf
|
||||||
|
#
|
||||||
|
#override_dh_auto_configure:
|
||||||
|
# dh_auto_configure -- \
|
||||||
|
# --sysconfdir=/etc/zm \
|
||||||
|
# --with-mysql=/usr \
|
||||||
|
# --with-webdir=/usr/share/zoneminder \
|
||||||
|
# --with-ffmpeg=/usr \
|
||||||
|
# --with-cgidir=/usr/lib/cgi-bin \
|
||||||
|
# --with-webuser=www-data \
|
||||||
|
# --with-webgroup=www-data \
|
||||||
|
# --enable-mmap=yes
|
|
@ -0,0 +1 @@
|
||||||
|
3.0 (quilt)
|
|
@ -0,0 +1,9 @@
|
||||||
|
## Actually sources are there: "*-nc.js".
|
||||||
|
source-is-missing web/tools/mootools/mootools-*-yc.js
|
||||||
|
|
||||||
|
## We're using "libjs-jquery" instead.
|
||||||
|
source-is-missing web/skins/*/js/jquery-1.4.2.min.js
|
||||||
|
|
||||||
|
## Acknowledged, will repack eventually.
|
||||||
|
source-contains-prebuilt-javascript-object web/tools/mootools/mootools-*-yc.js
|
||||||
|
source-contains-prebuilt-javascript-object web/skins/*/js/jquery-1.4.2.min.js
|
|
@ -0,0 +1,8 @@
|
||||||
|
Document: zoneminder-doc
|
||||||
|
Title: Zoneminder documentation
|
||||||
|
Abstract: This document describes how to use Zoneminder.
|
||||||
|
Section: System/Administration
|
||||||
|
|
||||||
|
Format: HTML
|
||||||
|
Index: /usr/share/doc/zoneminder-doc/html/index.html
|
||||||
|
Files: /usr/share/doc/zoneminder-doc/html/*
|
|
@ -0,0 +1 @@
|
||||||
|
docs/_build/html usr/share/doc/zoneminder-doc/
|
|
@ -0,0 +1,2 @@
|
||||||
|
## Convenience symlink:
|
||||||
|
/usr/share/doc/zoneminder-doc/html /usr/share/doc/zoneminder/html
|
|
@ -0,0 +1 @@
|
||||||
|
conf debian/conf/apache2/zoneminder.conf nginx
|
|
@ -0,0 +1,5 @@
|
||||||
|
Unless bug is specific to Debian please consider reporting it directly to
|
||||||
|
upstream developer(s):
|
||||||
|
|
||||||
|
https://github.com/ZoneMinder/ZoneMinder/issues
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
var/log/zm
|
||||||
|
var/lib/zm
|
||||||
|
var/cache/zoneminder/events
|
||||||
|
var/cache/zoneminder/images
|
||||||
|
var/cache/zoneminder/temp
|
||||||
|
var/cache/zoneminder/cache
|
||||||
|
usr/share/zoneminder/db
|
||||||
|
etc/zm/
|
||||||
|
etc/zm/conf.d
|
|
@ -0,0 +1 @@
|
||||||
|
README.md
|
|
@ -0,0 +1,2 @@
|
||||||
|
debian/examples/*
|
||||||
|
dbuild/misc/apache.conf
|
|
@ -0,0 +1,91 @@
|
||||||
|
#!/bin/sh
|
||||||
|
### BEGIN INIT INFO
|
||||||
|
# Provides: zoneminder
|
||||||
|
# Required-Start: $network $remote_fs $syslog
|
||||||
|
# Required-Stop: $network $remote_fs $syslog
|
||||||
|
# Should-Start: mysql
|
||||||
|
# Should-Stop: mysql
|
||||||
|
# Default-Start: 2 3 4 5
|
||||||
|
# Default-Stop: 0 1 6
|
||||||
|
# Short-Description: Control ZoneMinder as a Service
|
||||||
|
# Description: ZoneMinder CCTV recording and surveillance system
|
||||||
|
### END INIT INFO
|
||||||
|
# chkconfig: 2345 20 20
|
||||||
|
|
||||||
|
# Source function library.
|
||||||
|
. /lib/lsb/init-functions
|
||||||
|
|
||||||
|
prog=ZoneMinder
|
||||||
|
ZM_PATH_BIN="/usr/bin"
|
||||||
|
RUNDIR="/run/zm"
|
||||||
|
TMPDIR="/tmp/zm"
|
||||||
|
command="$ZM_PATH_BIN/zmpkg.pl"
|
||||||
|
|
||||||
|
start() {
|
||||||
|
echo -n "Starting $prog: "
|
||||||
|
export TZ=:/etc/localtime
|
||||||
|
mkdir -p "$RUNDIR" && chown www-data:www-data "$RUNDIR"
|
||||||
|
mkdir -p "$TMPDIR" && chown www-data:www-data "$TMPDIR"
|
||||||
|
$command start
|
||||||
|
RETVAL=$?
|
||||||
|
[ $RETVAL = 0 ] && echo success
|
||||||
|
[ $RETVAL != 0 ] && echo failure
|
||||||
|
echo
|
||||||
|
[ $RETVAL = 0 ] && touch /var/lock/zm
|
||||||
|
return $RETVAL
|
||||||
|
}
|
||||||
|
stop() {
|
||||||
|
echo -n "Stopping $prog: "
|
||||||
|
#
|
||||||
|
# Why is this status check being done?
|
||||||
|
# as $command stop returns 1 if zoneminder
|
||||||
|
# is stopped, which will result in
|
||||||
|
# this returning 1, which will stuff
|
||||||
|
# dpkg when it tries to stop zoneminder before
|
||||||
|
# uninstalling . . .
|
||||||
|
#
|
||||||
|
result=`$command status`
|
||||||
|
if [ ! "$result" = "running" ]; then
|
||||||
|
echo "Zoneminder already stopped"
|
||||||
|
echo
|
||||||
|
RETVAL=0
|
||||||
|
else
|
||||||
|
$command stop
|
||||||
|
RETVAL=$?
|
||||||
|
[ $RETVAL = 0 ] && echo success
|
||||||
|
[ $RETVAL != 0 ] && echo failure
|
||||||
|
echo
|
||||||
|
[ $RETVAL = 0 ] && rm -f /var/lock/zm
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
status() {
|
||||||
|
result=`$command status`
|
||||||
|
if [ "$result" = "running" ]; then
|
||||||
|
echo "ZoneMinder is running"
|
||||||
|
RETVAL=0
|
||||||
|
else
|
||||||
|
echo "ZoneMinder is stopped"
|
||||||
|
RETVAL=1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
'start')
|
||||||
|
start
|
||||||
|
;;
|
||||||
|
'stop')
|
||||||
|
stop
|
||||||
|
;;
|
||||||
|
'restart' | 'force-reload')
|
||||||
|
stop
|
||||||
|
start
|
||||||
|
;;
|
||||||
|
'status')
|
||||||
|
status
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Usage: $0 { start | stop | restart | status }"
|
||||||
|
RETVAL=1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
exit $RETVAL
|
|
@ -0,0 +1,11 @@
|
||||||
|
etc/zm/zm.conf
|
||||||
|
etc/zm/conf.d/*
|
||||||
|
usr/bin
|
||||||
|
usr/lib/zoneminder
|
||||||
|
usr/share/polkit-1
|
||||||
|
usr/share/zoneminder/db
|
||||||
|
usr/share/zoneminder/www
|
||||||
|
|
||||||
|
# libzoneminder-perl files:
|
||||||
|
usr/share/man/man3
|
||||||
|
usr/share/perl5
|
|
@ -0,0 +1 @@
|
||||||
|
/var/tmp /usr/share/zoneminder/www/api/app/tmp
|
|
@ -0,0 +1,14 @@
|
||||||
|
## cakephp
|
||||||
|
#replace /usr/share/php/Cake /usr/share/zoneminder/www/api/lib/Cake
|
||||||
|
|
||||||
|
## libjs-mootools
|
||||||
|
replace /usr/share/javascript/mootools/mootools.js /usr/share/zoneminder/www/tools/mootools/mootools-core.js
|
||||||
|
replace /usr/share/javascript/mootools/mootools.js /usr/share/zoneminder/www/tools/mootools/mootools-core-1.3.2-nc.js
|
||||||
|
replace /usr/share/javascript/mootools/mootools.js /usr/share/zoneminder/www/tools/mootools/mootools-core-1.3.2-yc.js
|
||||||
|
replace /usr/share/javascript/mootools/mootools-more.js /usr/share/zoneminder/www/tools/mootools/mootools-more.js
|
||||||
|
replace /usr/share/javascript/mootools/mootools-more.js /usr/share/zoneminder/www/tools/mootools/mootools-more-1.3.2.1-nc.js
|
||||||
|
replace /usr/share/javascript/mootools/mootools-more.js /usr/share/zoneminder/www/tools/mootools/mootools-more-1.3.2.1-yc.js
|
||||||
|
|
||||||
|
## libjs-jquery
|
||||||
|
replace /usr/share/javascript/jquery/jquery.min.js /usr/share/zoneminder/www/skins/classic/js/jquery-1.4.2.min.js
|
||||||
|
replace /usr/share/javascript/jquery/jquery.min.js /usr/share/zoneminder/www/skins/flat/js/jquery-1.4.2.min.js
|
|
@ -0,0 +1,14 @@
|
||||||
|
# Depends: policykit-1
|
||||||
|
unusual-interpreter usr/bin/zmsystemctl.pl #!/usr/bin/pkexec
|
||||||
|
|
||||||
|
# Intentionally not others-readable, #637685.
|
||||||
|
non-standard-file-perm etc/zm/zm.conf 0640 != 0644
|
||||||
|
|
||||||
|
# Bundled Cake PHP framework, not intended for direct execution:
|
||||||
|
script-not-executable usr/share/zoneminder/www/api/*
|
||||||
|
|
||||||
|
# Annoying but seems to be too much troubles to fix; should be fixed upstream:
|
||||||
|
script-with-language-extension usr/bin/*.pl
|
||||||
|
|
||||||
|
# dh-linktree:
|
||||||
|
package-contains-broken-symlink usr/share/zoneminder/www/api/lib/Cake/*
|
|
@ -0,0 +1,13 @@
|
||||||
|
/var/log/zm/*.log {
|
||||||
|
missingok
|
||||||
|
notifempty
|
||||||
|
sharedscripts
|
||||||
|
delaycompress
|
||||||
|
compress
|
||||||
|
postrotate
|
||||||
|
/usr/bin/zmpkg.pl logrot >>/dev/null 2>&1 || :
|
||||||
|
endscript
|
||||||
|
daily
|
||||||
|
rotate 7
|
||||||
|
maxage 7
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
rm_conffile /etc/zm/apache.conf 1.28.1-5~
|
|
@ -0,0 +1 @@
|
||||||
|
docs/_build/man/*.1
|
|
@ -0,0 +1,66 @@
|
||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [ "$1" = "configure" ]; then
|
||||||
|
|
||||||
|
. /etc/zm/zm.conf
|
||||||
|
for i in /etc/zm/conf.d/*.conf; do
|
||||||
|
. $i
|
||||||
|
done;
|
||||||
|
|
||||||
|
|
||||||
|
# The logs can contain passwords, etc... so by setting group root, only www-data can read them, not people in the www-data group
|
||||||
|
chown www-data:root /var/log/zm
|
||||||
|
chown www-data:www-data /var/lib/zm
|
||||||
|
if [ -z "$2" ]; then
|
||||||
|
chown www-data:www-data /var/cache/zoneminder /var/cache/zoneminder/*
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Do this every time the package is installed or upgraded
|
||||||
|
# Ensure zoneminder is stopped
|
||||||
|
invoke-rc.d zoneminder stop || true
|
||||||
|
|
||||||
|
if [ "$ZM_DB_HOST" = "localhost" ]; then
|
||||||
|
if [ -e "/etc/init.d/mysql" ]; then
|
||||||
|
#
|
||||||
|
# Get mysql started if it isn't
|
||||||
|
#
|
||||||
|
if ! $(/etc/init.d/mysql status >/dev/null 2>&1); then
|
||||||
|
invoke-rc.d mysql start
|
||||||
|
fi
|
||||||
|
if $(/etc/init.d/mysql status >/dev/null 2>&1); then
|
||||||
|
mysqladmin --defaults-file=/etc/mysql/debian.cnf -f reload
|
||||||
|
# test if database if already present...
|
||||||
|
if ! $(echo quit | mysql --defaults-file=/etc/mysql/debian.cnf zm > /dev/null 2> /dev/null) ; then
|
||||||
|
cat /usr/share/zoneminder/db/zm_create.sql | mysql --defaults-file=/etc/mysql/debian.cnf
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Error creating db."
|
||||||
|
exit 1;
|
||||||
|
fi
|
||||||
|
# This creates the user.
|
||||||
|
echo "grant lock tables, alter,drop,select,insert,update,delete,create,index,alter routine,create routine, trigger,execute on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost identified by \"${ZM_DB_PASS}\";" | mysql --defaults-file=/etc/mysql/debian.cnf mysql
|
||||||
|
else
|
||||||
|
echo "grant lock tables, alter,drop,select,insert,update,delete,create,index,alter routine,create routine, trigger,execute on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost;" | mysql --defaults-file=/etc/mysql/debian.cnf mysql
|
||||||
|
fi
|
||||||
|
|
||||||
|
zmupdate.pl --nointeractive
|
||||||
|
zmupdate.pl --nointeractive -f
|
||||||
|
|
||||||
|
# Add any new PTZ control configurations to the database (will not overwrite)
|
||||||
|
zmcamtool.pl --import >/dev/null 2>&1
|
||||||
|
|
||||||
|
else
|
||||||
|
echo 'NOTE: mysql not running, please start mysql and run dpkg-reconfigure zoneminder when it is running.'
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo 'mysql not found, assuming remote server.'
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Not doing database upgrade due to remote db server ($ZM_DB_HOST)"
|
||||||
|
fi
|
||||||
|
echo "Done Updating, starting ZoneMinder"
|
||||||
|
invoke-rc.d zoneminder start || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
#DEBHELPER#
|
|
@ -0,0 +1,14 @@
|
||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [ "$1" = "purge" ]; then
|
||||||
|
echo "
|
||||||
|
Reminder: to completely remove \"zoneminder\" it may be necessary
|
||||||
|
* to delete database using the following sample command:
|
||||||
|
sudo mysqladmin --defaults-file=/etc/mysql/debian.cnf -f drop zm
|
||||||
|
* to delete remaining data files in "/var/cache/zoneminder".
|
||||||
|
"
|
||||||
|
fi
|
||||||
|
|
||||||
|
#DEBHELPER#
|
|
@ -0,0 +1,11 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
## Remove obsolete symlink which is in the way of dh_apache2:
|
||||||
|
ol="/etc/apache2/conf-available/zoneminder.conf"
|
||||||
|
if [ -h "${ol}" ]; then
|
||||||
|
[ "$(readlink ${ol})" = "/etc/zm/apache.conf" ] && rm -f "${ol}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
#DEBHELPER#
|
|
@ -0,0 +1,4 @@
|
||||||
|
d /run/zm 0755 www-data www-data
|
||||||
|
d /tmp/zm 0755 www-data www-data
|
||||||
|
d /var/tmp/zm 0755 www-data www-data
|
||||||
|
d /var/cache/zoneminder/cache 0755 www-data www-data
|
|
@ -21,7 +21,7 @@ endif(ZM_TARGET_DISTRO MATCHES "^el")
|
||||||
# Configure the common zoneminder files
|
# Configure the common zoneminder files
|
||||||
configure_file(common/zoneminder.logrotate.in ${CMAKE_CURRENT_SOURCE_DIR}/zoneminder.logrotate @ONLY)
|
configure_file(common/zoneminder.logrotate.in ${CMAKE_CURRENT_SOURCE_DIR}/zoneminder.logrotate @ONLY)
|
||||||
configure_file(common/zoneminder.service.in ${CMAKE_CURRENT_SOURCE_DIR}/zoneminder.service @ONLY)
|
configure_file(common/zoneminder.service.in ${CMAKE_CURRENT_SOURCE_DIR}/zoneminder.service @ONLY)
|
||||||
file(MAKE_DIRECTORY sock swap zoneminder zoneminder-upload events temp)
|
file(MAKE_DIRECTORY sock swap zoneminder events temp)
|
||||||
|
|
||||||
# Configure the Apache zoneminder files
|
# Configure the Apache zoneminder files
|
||||||
configure_file(httpd/zm-httpd.conf.in ${CMAKE_CURRENT_SOURCE_DIR}/zm-httpd.conf @ONLY)
|
configure_file(httpd/zm-httpd.conf.in ${CMAKE_CURRENT_SOURCE_DIR}/zm-httpd.conf @ONLY)
|
||||||
|
@ -51,7 +51,6 @@ install(DIRECTORY sock swap DESTINATION /var/lib/zoneminder DIRECTORY_PERMISSION
|
||||||
install(DIRECTORY zoneminder DESTINATION /var/log DIRECTORY_PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
install(DIRECTORY zoneminder DESTINATION /var/log DIRECTORY_PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
||||||
install(DIRECTORY zoneminder DESTINATION /var/run DIRECTORY_PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
install(DIRECTORY zoneminder DESTINATION /var/run DIRECTORY_PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
||||||
install(DIRECTORY zoneminder DESTINATION /var/cache DIRECTORY_PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
install(DIRECTORY zoneminder DESTINATION /var/cache DIRECTORY_PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
||||||
install(DIRECTORY zoneminder-upload DESTINATION /var/spool DIRECTORY_PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
|
||||||
install(DIRECTORY events temp DESTINATION /var/lib/zoneminder DIRECTORY_PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
install(DIRECTORY events temp DESTINATION /var/lib/zoneminder DIRECTORY_PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
||||||
|
|
||||||
# Install the Apache zoneminder files
|
# Install the Apache zoneminder files
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
Description=ZoneMinder CCTV recording and security system
|
Description=ZoneMinder CCTV recording and security system
|
||||||
After=network.target mariadb.service
|
After=network.target mariadb.service
|
||||||
Requires=mariadb.service
|
Requires=mariadb.service
|
||||||
|
BindsTo=mariadb.service
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=forking
|
Type=forking
|
||||||
|
|
|
@ -28,14 +28,18 @@
|
||||||
%global _hardened_build 1
|
%global _hardened_build 1
|
||||||
|
|
||||||
Name: zoneminder
|
Name: zoneminder
|
||||||
Version: 1.35.5
|
Version: 1.35.6
|
||||||
Release: 1%{?dist}
|
Release: 1%{?dist}
|
||||||
Summary: A camera monitoring and analysis tool
|
Summary: A camera monitoring and analysis tool
|
||||||
Group: System Environment/Daemons
|
Group: System Environment/Daemons
|
||||||
# Mootools is inder the MIT license: http://mootools.net/
|
# Mootools is under the MIT license: http://mootools.net/
|
||||||
|
# jQuery is under the MIT license: https://jquery.org/license/
|
||||||
# CakePHP is under the MIT license: https://github.com/cakephp/cakephp
|
# CakePHP is under the MIT license: https://github.com/cakephp/cakephp
|
||||||
# Crud is under the MIT license: https://github.com/FriendsOfCake/crud
|
# Crud is under the MIT license: https://github.com/FriendsOfCake/crud
|
||||||
# CakePHP-Enum-Behavior is under the MIT license: https://github.com/asper/CakePHP-Enum-Behavior
|
# CakePHP-Enum-Behavior is under the MIT license: https://github.com/asper/CakePHP-Enum-Behavior
|
||||||
|
# Bootstrap is under the MIT license: https://getbootstrap.com/docs/4.5/about/license/
|
||||||
|
# Bootstrap-table is under the MIT license: https://bootstrap-table.com/docs/about/license/
|
||||||
|
# font-awesome is under CC-BY license: https://fontawesome.com/license/free
|
||||||
License: GPLv2+ and LGPLv2+ and MIT
|
License: GPLv2+ and LGPLv2+ and MIT
|
||||||
URL: http://www.zoneminder.com/
|
URL: http://www.zoneminder.com/
|
||||||
|
|
||||||
|
@ -200,11 +204,8 @@ mv -f CakePHP-Enum-Behavior-%{ceb_version} ./web/api/app/Plugin/CakePHP-Enum-Beh
|
||||||
|
|
||||||
# Change the following default values
|
# Change the following default values
|
||||||
./utils/zmeditconfigdata.sh ZM_OPT_CAMBOZOLA yes
|
./utils/zmeditconfigdata.sh ZM_OPT_CAMBOZOLA yes
|
||||||
./utils/zmeditconfigdata.sh ZM_UPLOAD_FTP_LOC_DIR %{_localstatedir}/spool/zoneminder-upload
|
|
||||||
./utils/zmeditconfigdata.sh ZM_OPT_CONTROL yes
|
./utils/zmeditconfigdata.sh ZM_OPT_CONTROL yes
|
||||||
./utils/zmeditconfigdata.sh ZM_CHECK_FOR_UPDATES no
|
./utils/zmeditconfigdata.sh ZM_CHECK_FOR_UPDATES no
|
||||||
./utils/zmeditconfigdata.sh ZM_DYN_SHOW_DONATE_REMINDER no
|
|
||||||
./utils/zmeditconfigdata.sh ZM_OPT_FAST_DELETE no
|
|
||||||
|
|
||||||
%build
|
%build
|
||||||
# Disable LTO due to top level asm
|
# Disable LTO due to top level asm
|
||||||
|
@ -395,7 +396,6 @@ EOF
|
||||||
%dir %attr(755,%{zmuid_final},%{zmgid_final}) %{_sharedstatedir}/zoneminder/temp
|
%dir %attr(755,%{zmuid_final},%{zmgid_final}) %{_sharedstatedir}/zoneminder/temp
|
||||||
%dir %attr(755,%{zmuid_final},%{zmgid_final}) %{_localstatedir}/cache/zoneminder
|
%dir %attr(755,%{zmuid_final},%{zmgid_final}) %{_localstatedir}/cache/zoneminder
|
||||||
%dir %attr(755,%{zmuid_final},%{zmgid_final}) %{_localstatedir}/log/zoneminder
|
%dir %attr(755,%{zmuid_final},%{zmgid_final}) %{_localstatedir}/log/zoneminder
|
||||||
%dir %attr(755,%{zmuid_final},%{zmgid_final}) %{_localstatedir}/spool/zoneminder-upload
|
|
||||||
|
|
||||||
%files nginx
|
%files nginx
|
||||||
%config(noreplace) %attr(640,root,nginx) %{_sysconfdir}/zm/zm.conf
|
%config(noreplace) %attr(640,root,nginx) %{_sysconfdir}/zm/zm.conf
|
||||||
|
@ -419,7 +419,6 @@ EOF
|
||||||
%dir %attr(755,nginx,nginx) %{_sharedstatedir}/zoneminder/temp
|
%dir %attr(755,nginx,nginx) %{_sharedstatedir}/zoneminder/temp
|
||||||
%dir %attr(755,nginx,nginx) %{_localstatedir}/cache/zoneminder
|
%dir %attr(755,nginx,nginx) %{_localstatedir}/cache/zoneminder
|
||||||
%dir %attr(755,nginx,nginx) %{_localstatedir}/log/zoneminder
|
%dir %attr(755,nginx,nginx) %{_localstatedir}/log/zoneminder
|
||||||
%dir %attr(755,nginx,nginx) %{_localstatedir}/spool/zoneminder-upload
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
* Tue Feb 04 2020 Andrew Bauer <zonexpertconsulting@outlook.com> - 1.34.2-1
|
* Tue Feb 04 2020 Andrew Bauer <zonexpertconsulting@outlook.com> - 1.34.2-1
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
zoneminder (1.31.39~20180223.27-stretch-1) unstable; urgency=low
|
zoneminder (1.35.6~20200825.27-xenial) xenial; urgency=low
|
||||||
*
|
*
|
||||||
-- Isaac Connor <iconnor@connortechnology.com> Fri, 23 Feb 2018 14:15:59 -0500
|
-- Isaac Connor <isaac@zoneminder.com> Tue, 25 Aug 2020 09:28:18 -0400
|
||||||
|
|
|
@ -3,7 +3,7 @@ Section: net
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Maintainer: Isaac Connor <isaac@zoneminder.com>
|
Maintainer: Isaac Connor <isaac@zoneminder.com>
|
||||||
Uploaders: Isaac Connor <isaac@zoneminder.com>
|
Uploaders: Isaac Connor <isaac@zoneminder.com>
|
||||||
Build-Depends: debhelper, dh-systemd, sphinx-doc, dh-linktree, dh-systemd, dh-apache2
|
Build-Depends: debhelper, dh-systemd, sphinx-doc, python3-sphinx, dh-linktree, dh-systemd, dh-apache2
|
||||||
,cmake
|
,cmake
|
||||||
,libx264-dev, libmp4v2-dev
|
,libx264-dev, libmp4v2-dev
|
||||||
,libavdevice-dev
|
,libavdevice-dev
|
||||||
|
|
|
@ -23,7 +23,7 @@ override_dh_auto_configure:
|
||||||
-DZM_CONFIG_SUBDIR="/etc/zm/conf.d" \
|
-DZM_CONFIG_SUBDIR="/etc/zm/conf.d" \
|
||||||
-DZM_RUNDIR="/run/zm" \
|
-DZM_RUNDIR="/run/zm" \
|
||||||
-DZM_SOCKDIR="/run/zm" \
|
-DZM_SOCKDIR="/run/zm" \
|
||||||
-DZM_TMPDIR="/tmp/zm" \
|
-DZM_TMPDIR="/var/tmp/zm" \
|
||||||
-DZM_CGIDIR="/usr/lib/zoneminder/cgi-bin" \
|
-DZM_CGIDIR="/usr/lib/zoneminder/cgi-bin" \
|
||||||
-DZM_CACHEDIR="/var/cache/zoneminder/cache" \
|
-DZM_CACHEDIR="/var/cache/zoneminder/cache" \
|
||||||
-DZM_DIR_EVENTS="/var/cache/zoneminder/events" \
|
-DZM_DIR_EVENTS="/var/cache/zoneminder/events" \
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
#!/bin/sh
|
||||||
|
### BEGIN INIT INFO
|
||||||
|
# Provides: zoneminder
|
||||||
|
# Required-Start: $network $remote_fs $syslog
|
||||||
|
# Required-Stop: $network $remote_fs $syslog
|
||||||
|
# Should-Start: mysql
|
||||||
|
# Should-Stop: mysql
|
||||||
|
# Default-Start: 2 3 4 5
|
||||||
|
# Default-Stop: 0 1 6
|
||||||
|
# Short-Description: Control ZoneMinder as a Service
|
||||||
|
# Description: ZoneMinder CCTV recording and surveillance system
|
||||||
|
### END INIT INFO
|
||||||
|
# chkconfig: 2345 20 20
|
||||||
|
|
||||||
|
# Source function library.
|
||||||
|
. /lib/lsb/init-functions
|
||||||
|
|
||||||
|
prog=ZoneMinder
|
||||||
|
ZM_PATH_BIN="/usr/bin"
|
||||||
|
RUNDIR="/run/zm"
|
||||||
|
TMPDIR="/tmp/zm"
|
||||||
|
command="$ZM_PATH_BIN/zmpkg.pl"
|
||||||
|
|
||||||
|
start() {
|
||||||
|
echo -n "Starting $prog: "
|
||||||
|
export TZ=:/etc/localtime
|
||||||
|
mkdir -p "$RUNDIR" && chown www-data:www-data "$RUNDIR"
|
||||||
|
mkdir -p "$TMPDIR" && chown www-data:www-data "$TMPDIR"
|
||||||
|
$command start
|
||||||
|
RETVAL=$?
|
||||||
|
[ $RETVAL = 0 ] && echo success
|
||||||
|
[ $RETVAL != 0 ] && echo failure
|
||||||
|
echo
|
||||||
|
[ $RETVAL = 0 ] && touch /var/lock/zm
|
||||||
|
return $RETVAL
|
||||||
|
}
|
||||||
|
stop() {
|
||||||
|
echo -n "Stopping $prog: "
|
||||||
|
#
|
||||||
|
# Why is this status check being done?
|
||||||
|
# as $command stop returns 1 if zoneminder
|
||||||
|
# is stopped, which will result in
|
||||||
|
# this returning 1, which will stuff
|
||||||
|
# dpkg when it tries to stop zoneminder before
|
||||||
|
# uninstalling . . .
|
||||||
|
#
|
||||||
|
result=`$command status`
|
||||||
|
if [ ! "$result" = "running" ]; then
|
||||||
|
echo "Zoneminder already stopped"
|
||||||
|
echo
|
||||||
|
RETVAL=0
|
||||||
|
else
|
||||||
|
$command stop
|
||||||
|
RETVAL=$?
|
||||||
|
[ $RETVAL = 0 ] && echo success
|
||||||
|
[ $RETVAL != 0 ] && echo failure
|
||||||
|
echo
|
||||||
|
[ $RETVAL = 0 ] && rm -f /var/lock/zm
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
status() {
|
||||||
|
result=`$command status`
|
||||||
|
if [ "$result" = "running" ]; then
|
||||||
|
echo "ZoneMinder is running"
|
||||||
|
RETVAL=0
|
||||||
|
else
|
||||||
|
echo "ZoneMinder is stopped"
|
||||||
|
RETVAL=1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
'start')
|
||||||
|
start
|
||||||
|
;;
|
||||||
|
'stop')
|
||||||
|
stop
|
||||||
|
;;
|
||||||
|
'restart' | 'force-reload')
|
||||||
|
stop
|
||||||
|
start
|
||||||
|
;;
|
||||||
|
'status')
|
||||||
|
status
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Usage: $0 { start | stop | restart | status }"
|
||||||
|
RETVAL=1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
exit $RETVAL
|
|
@ -2,6 +2,40 @@
|
||||||
|
|
||||||
set +e
|
set +e
|
||||||
|
|
||||||
|
create_db () {
|
||||||
|
echo "Checking for db"
|
||||||
|
mysqladmin --defaults-file=/etc/mysql/debian.cnf -f reload
|
||||||
|
# test if database if already present...
|
||||||
|
if ! $(echo quit | mysql --defaults-file=/etc/mysql/debian.cnf zm > /dev/null 2> /dev/null) ; then
|
||||||
|
echo "Creating zm db"
|
||||||
|
cat /usr/share/zoneminder/db/zm_create.sql | mysql --defaults-file=/etc/mysql/debian.cnf
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Error creating db."
|
||||||
|
exit 1;
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Db exists."
|
||||||
|
fi
|
||||||
|
USER_EXISTS="$(mysql --defaults-file=/etc/mysql/debian.cnf -sse "SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = '$ZM_DB_USER')")"
|
||||||
|
if [ $USER_EXISTS -ne 1 ]; then
|
||||||
|
echo "Creating zm user $ZM_DB_USER"
|
||||||
|
# This creates the user.
|
||||||
|
echo "CREATE USER '${ZM_DB_USER}'@${ZM_DB_HOST} IDENTIFIED BY '${ZM_DB_PASS}';" | mysql --defaults-file=/etc/mysql/debian.cnf mysql
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
update_db () {
|
||||||
|
echo "Updating permissions"
|
||||||
|
echo "GRANT LOCK tables,alter,drop,select,insert,update,delete,create,index,alter routine,create routine,trigger,execute ON ${ZM_DB_NAME}.* TO '${ZM_DB_USER}'@${ZM_DB_HOST};" | mysql --defaults-file=/etc/mysql/debian.cnf mysql
|
||||||
|
|
||||||
|
zmupdate.pl --nointeractive
|
||||||
|
zmupdate.pl --nointeractive -f
|
||||||
|
|
||||||
|
# Add any new PTZ control configurations to the database (will not overwrite)
|
||||||
|
zmcamtool.pl --import >/dev/null 2>&1
|
||||||
|
echo "Done Updating"
|
||||||
|
}
|
||||||
|
|
||||||
if [ "$1" = "configure" ]; then
|
if [ "$1" = "configure" ]; then
|
||||||
|
|
||||||
. /etc/zm/zm.conf
|
. /etc/zm/zm.conf
|
||||||
|
@ -20,12 +54,20 @@ if [ "$1" = "configure" ]; then
|
||||||
a2enmod cgi
|
a2enmod cgi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$ZM_DB_HOST" = "localhost" ]; then
|
SYSTEMD=0
|
||||||
|
if [ -e "/run/systemd/system" ]; then
|
||||||
if [ -e "/lib/systemd/system/mysql.service" ] || [ -e "/lib/systemd/system/mariadb.service" ] || [ -e "/etc/init.d/mysql" ]; then
|
SYSTEMD=1
|
||||||
|
echo "detected systemd"
|
||||||
# Ensure zoneminder is stopped
|
# Ensure zoneminder is stopped
|
||||||
deb-systemd-invoke stop zoneminder.service || exit $?
|
deb-systemd-invoke stop zoneminder.service || exit $?
|
||||||
|
else
|
||||||
|
# Ensure zoneminder is stopped
|
||||||
|
invoke-rc.d zoneminder stop || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$ZM_DB_HOST" = "localhost" ]; then
|
||||||
|
|
||||||
|
if [ $SYSTEMD -eq 1 ] && ([ -e "/lib/systemd/system/mysql.service" ] || [ -e "/lib/systemd/system/mariadb.service" ]); then
|
||||||
#
|
#
|
||||||
# Get mysql started if it isn't running
|
# Get mysql started if it isn't running
|
||||||
#
|
#
|
||||||
|
@ -51,39 +93,39 @@ if [ "$1" = "configure" ]; then
|
||||||
|
|
||||||
# Make sure systemctl status exit code is 0; i.e. the DB is running
|
# Make sure systemctl status exit code is 0; i.e. the DB is running
|
||||||
if systemctl is-active --quiet "$DBSERVICE"; then
|
if systemctl is-active --quiet "$DBSERVICE"; then
|
||||||
mysqladmin --defaults-file=/etc/mysql/debian.cnf -f reload
|
create_db
|
||||||
# test if database if already present...
|
update_db
|
||||||
if ! $(echo quit | mysql --defaults-file=/etc/mysql/debian.cnf zm > /dev/null 2> /dev/null) ; then
|
|
||||||
echo "Creating zm db"
|
|
||||||
cat /usr/share/zoneminder/db/zm_create.sql | mysql --defaults-file=/etc/mysql/debian.cnf
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "Error creating db."
|
|
||||||
exit 1;
|
|
||||||
fi
|
|
||||||
# This creates the user.
|
|
||||||
echo "CREATE USER '${ZM_DB_USER}'@localhost IDENTIFIED BY '${ZM_DB_PASS}';" | mysql --defaults-file=/etc/mysql/debian.cnf mysql
|
|
||||||
fi
|
|
||||||
echo "Updating permissions"
|
|
||||||
echo "grant lock tables,alter,drop,select,insert,update,delete,create,index,alter routine,create routine, trigger,execute on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost;" | mysql --defaults-file=/etc/mysql/debian.cnf mysql
|
|
||||||
|
|
||||||
zmupdate.pl --nointeractive
|
|
||||||
zmupdate.pl --nointeractive -f
|
|
||||||
|
|
||||||
# Add any new PTZ control configurations to the database (will not overwrite)
|
|
||||||
zmcamtool.pl --import >/dev/null 2>&1
|
|
||||||
echo "Done Updating; starting ZoneMinder."
|
|
||||||
else
|
else
|
||||||
echo 'NOTE: MySQL/MariaDB not running; please start mysql and run dpkg-reconfigure zoneminder when it is running.'
|
echo 'NOTE: MySQL/MariaDB not running; please start mysql and run dpkg-reconfigure zoneminder when it is running.'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
elif [ -e "/etc/init.d/mysql" ]; then
|
||||||
|
#
|
||||||
|
# Get mysql started if it isn't
|
||||||
|
#
|
||||||
|
if ! $(/etc/init.d/mysql status >/dev/null 2>&1); then
|
||||||
|
service mysql start
|
||||||
|
fi
|
||||||
|
if $(/etc/init.d/mysql status >/dev/null 2>&1); then
|
||||||
|
create_db
|
||||||
|
update_db
|
||||||
|
else
|
||||||
|
echo 'NOTE: MySQL/MariaDB not running; please start mysql and run dpkg-reconfigure zoneminder when it is running.'
|
||||||
|
fi
|
||||||
|
|
||||||
else
|
else
|
||||||
echo 'MySQL/MariaDB not found; assuming remote server.'
|
echo 'MySQL/MariaDB not found; assuming remote server.'
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
else
|
else
|
||||||
echo "Not doing database upgrade due to remote db server ($ZM_DB_HOST)."
|
echo "Not doing database upgrade due to remote db server ($ZM_DB_HOST)."
|
||||||
fi
|
fi
|
||||||
deb-systemd-invoke restart zoneminder.service
|
|
||||||
|
|
||||||
|
if [ $SYSTEMD -eq 1 ]; then
|
||||||
|
deb-systemd-invoke restart zoneminder.service
|
||||||
|
#else
|
||||||
|
#service zoneminder start || true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#DEBHELPER#
|
#DEBHELPER#
|
||||||
|
|
|
@ -43,7 +43,7 @@ trigger their installation manually.
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
sudo apt install apache2 mysql-server
|
sudo apt install apache2 default-mysql-server
|
||||||
|
|
||||||
**Step 4:** Add ZoneMinder's Package repository to your apt sources
|
**Step 4:** Add ZoneMinder's Package repository to your apt sources
|
||||||
|
|
||||||
|
@ -51,25 +51,29 @@ 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
|
repositories. To be able to install ZoneMinder with APT, you have to edit the
|
||||||
list of apt sources and add ZoneMinder's repository.
|
list of apt sources and add ZoneMinder's repository.
|
||||||
|
|
||||||
::
|
Add the following to the /etc/apt/sources.list.d/zoneminder.list file
|
||||||
|
|
||||||
sudo nano /etc/apt/sources.list
|
|
||||||
|
|
||||||
Add the following to the bottom of the file
|
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
# ZoneMinder repository
|
# ZoneMinder repository
|
||||||
deb https://zmrepo.zoneminder.com/debian/release-1.34 buster/
|
deb https://zmrepo.zoneminder.com/debian/release-1.34 buster/
|
||||||
|
|
||||||
CTRL+o and <Enter> to save
|
You can do this using:
|
||||||
CTRL+x to exit
|
|
||||||
|
::
|
||||||
|
echo "deb https://zmrepo.zoneminder.com/debian/release-1.34 buster/" | sudo tee /etc/apt/sources.list.d/zoneminder.list
|
||||||
|
|
||||||
Because ZoneMinder's package repository provides a secure connection through HTTPS, apt must be enabled for HTTPS.
|
Because ZoneMinder's package repository provides a secure connection through HTTPS, apt must be enabled for HTTPS.
|
||||||
::
|
::
|
||||||
|
|
||||||
sudo apt install apt-transport-https
|
sudo apt install apt-transport-https
|
||||||
|
|
||||||
|
Ensure you have gnupg installed before importing the apt key in the following step.
|
||||||
|
::
|
||||||
|
|
||||||
|
sudo apt install gnupg
|
||||||
|
|
||||||
|
|
||||||
Finally, download the GPG key for ZoneMinder's repository:
|
Finally, download the GPG key for ZoneMinder's repository:
|
||||||
::
|
::
|
||||||
|
|
||||||
|
@ -107,7 +111,7 @@ required apache modules.
|
||||||
::
|
::
|
||||||
|
|
||||||
sudo a2enconf zoneminder
|
sudo a2enconf zoneminder
|
||||||
sudo a2enmod rewrite
|
sudo a2enmod rewrite # this is enabled by default
|
||||||
sudo a2enmod cgi # this is done automatically when installing the package. Redo this command manually only for troubleshooting.
|
sudo a2enmod cgi # this is done automatically when installing the package. Redo this command manually only for troubleshooting.
|
||||||
|
|
||||||
|
|
||||||
|
@ -116,12 +120,12 @@ required apache modules.
|
||||||
Automated way:
|
Automated way:
|
||||||
::
|
::
|
||||||
|
|
||||||
sudo sed -i "s/;date.timezone =/date.timezone = $(sed 's/\//\\\//' /etc/timezone)/g" /etc/php/7.0/apache2/php.ini
|
sudo sed -i "s/;date.timezone =/date.timezone = $(sed 's/\//\\\//' /etc/timezone)/g" /etc/php/7.*/apache2/php.ini
|
||||||
|
|
||||||
Manual way
|
Manual way
|
||||||
::
|
::
|
||||||
|
|
||||||
sudo nano /etc/php/7.0/apache2/php.ini
|
sudo nano /etc/php/7.*/apache2/php.ini
|
||||||
|
|
||||||
Search for [Date] (Ctrl + w then type Date and press Enter) and change
|
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
|
date.timezone for your time zone. Don't forget to remove the ; from in front
|
||||||
|
|
|
@ -51,7 +51,7 @@ This screen is called the "console" screen in ZoneMinder and shows a summary of
|
||||||
|
|
||||||
* **A**: The options menu lets you configure many aspects of ZoneMinder. Refer to :doc:`options`.
|
* **A**: The options menu lets you configure many aspects of ZoneMinder. Refer to :doc:`options`.
|
||||||
* **B**: This brings up a color coded log window that shows various system and component level logs. This window is useful if you are trying to diagnose issues. Refer to :doc:`logging`.
|
* **B**: This brings up a color coded log window that shows various system and component level logs. This window is useful if you are trying to diagnose issues. Refer to :doc:`logging`.
|
||||||
* **C**: ZoneMinder allows you to group monitors gor logical separation. This option lets you create new groups, associate monitors to them and edit/delete existing groups.
|
* **C**: ZoneMinder allows you to group monitors for logical separation. This option lets you create new groups, associate monitors to them and edit/delete existing groups.
|
||||||
* **D**: Filters are a powerful mechanism to perform actions when certain conditions are met. ZoneMinder comes with some preset filters that keep a tab of disk space and others. Many users create their own filters for more advanced actions like sending emails when certain events occur and more. Refer to :doc:`filterevents`.
|
* **D**: Filters are a powerful mechanism to perform actions when certain conditions are met. ZoneMinder comes with some preset filters that keep a tab of disk space and others. Many users create their own filters for more advanced actions like sending emails when certain events occur and more. Refer to :doc:`filterevents`.
|
||||||
* **E**: The Cycle option allows you to rotate between live views of each cofigured monitor.
|
* **E**: The Cycle option allows you to rotate between live views of each cofigured monitor.
|
||||||
* **F**: The Montage option shows a collage of your monitors. You can customize them including moving them around.
|
* **F**: The Montage option shows a collage of your monitors. You can customize them including moving them around.
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
{
|
|
||||||
"abstract" : "unknown",
|
|
||||||
"author" : [
|
|
||||||
"Jan Hochstein"
|
|
||||||
],
|
|
||||||
"dynamic_config" : 0,
|
|
||||||
"generated_by" : "ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010",
|
|
||||||
"license" : [
|
|
||||||
"unknown"
|
|
||||||
],
|
|
||||||
"meta-spec" : {
|
|
||||||
"url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
|
|
||||||
"version" : 2
|
|
||||||
},
|
|
||||||
"name" : "ONVIF",
|
|
||||||
"no_index" : {
|
|
||||||
"directory" : [
|
|
||||||
"t",
|
|
||||||
"inc"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"prereqs" : {
|
|
||||||
"build" : {
|
|
||||||
"requires" : {
|
|
||||||
"ExtUtils::MakeMaker" : "0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"configure" : {
|
|
||||||
"requires" : {
|
|
||||||
"ExtUtils::MakeMaker" : "0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"runtime" : {
|
|
||||||
"requires" : {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"release_status" : "stable",
|
|
||||||
"version" : "",
|
|
||||||
"x_serialization_backend" : "JSON::PP version 4.02"
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
---
|
|
||||||
abstract: unknown
|
|
||||||
author:
|
|
||||||
- 'Jan Hochstein'
|
|
||||||
build_requires:
|
|
||||||
ExtUtils::MakeMaker: '0'
|
|
||||||
configure_requires:
|
|
||||||
ExtUtils::MakeMaker: '0'
|
|
||||||
dynamic_config: 0
|
|
||||||
generated_by: 'ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010'
|
|
||||||
license: unknown
|
|
||||||
meta-spec:
|
|
||||||
url: http://module-build.sourceforge.net/META-spec-v1.4.html
|
|
||||||
version: '1.4'
|
|
||||||
name: ONVIF
|
|
||||||
no_index:
|
|
||||||
directory:
|
|
||||||
- t
|
|
||||||
- inc
|
|
||||||
requires: {}
|
|
||||||
version: ''
|
|
||||||
x_serialization_backend: 'CPAN::Meta::YAML version 0.018'
|
|
|
@ -1,40 +0,0 @@
|
||||||
{
|
|
||||||
"abstract" : "unknown",
|
|
||||||
"author" : [
|
|
||||||
"Jan Hochstein"
|
|
||||||
],
|
|
||||||
"dynamic_config" : 0,
|
|
||||||
"generated_by" : "ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010",
|
|
||||||
"license" : [
|
|
||||||
"unknown"
|
|
||||||
],
|
|
||||||
"meta-spec" : {
|
|
||||||
"url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
|
|
||||||
"version" : 2
|
|
||||||
},
|
|
||||||
"name" : "ONVIF",
|
|
||||||
"no_index" : {
|
|
||||||
"directory" : [
|
|
||||||
"t",
|
|
||||||
"inc"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"prereqs" : {
|
|
||||||
"build" : {
|
|
||||||
"requires" : {
|
|
||||||
"ExtUtils::MakeMaker" : "0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"configure" : {
|
|
||||||
"requires" : {
|
|
||||||
"ExtUtils::MakeMaker" : "0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"runtime" : {
|
|
||||||
"requires" : {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"release_status" : "stable",
|
|
||||||
"version" : "",
|
|
||||||
"x_serialization_backend" : "JSON::PP version 4.02"
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
---
|
|
||||||
abstract: unknown
|
|
||||||
author:
|
|
||||||
- 'Jan Hochstein'
|
|
||||||
build_requires:
|
|
||||||
ExtUtils::MakeMaker: '0'
|
|
||||||
configure_requires:
|
|
||||||
ExtUtils::MakeMaker: '0'
|
|
||||||
dynamic_config: 0
|
|
||||||
generated_by: 'ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010'
|
|
||||||
license: unknown
|
|
||||||
meta-spec:
|
|
||||||
url: http://module-build.sourceforge.net/META-spec-v1.4.html
|
|
||||||
version: '1.4'
|
|
||||||
name: ONVIF
|
|
||||||
no_index:
|
|
||||||
directory:
|
|
||||||
- t
|
|
||||||
- inc
|
|
||||||
requires: {}
|
|
||||||
version: ''
|
|
||||||
x_serialization_backend: 'CPAN::Meta::YAML version 0.018'
|
|
|
@ -76,8 +76,7 @@ BEGIN {
|
||||||
require ZoneMinder::Database;
|
require ZoneMinder::Database;
|
||||||
|
|
||||||
# Process name, value pairs from the main config file first
|
# Process name, value pairs from the main config file first
|
||||||
my $config_file = ZM_CONFIG;
|
process_configfile(ZM_CONFIG);
|
||||||
process_configfile($config_file);
|
|
||||||
|
|
||||||
# Search for user created config files. If one or more are found then
|
# Search for user created config files. If one or more are found then
|
||||||
# update the Config hash with those values
|
# update the Config hash with those values
|
||||||
|
@ -92,10 +91,14 @@ require ZoneMinder::Database;
|
||||||
}
|
}
|
||||||
|
|
||||||
my $dbh = ZoneMinder::Database::zmDbConnect();
|
my $dbh = ZoneMinder::Database::zmDbConnect();
|
||||||
|
die "Unable to connect to DB. ZM Cannot continue.\n" if !$dbh;
|
||||||
|
|
||||||
my $sql = 'SELECT Name,Value FROM Config';
|
my $sql = 'SELECT Name,Value FROM Config';
|
||||||
my $sth = $dbh->prepare_cached($sql) or croak("Can't prepare '$sql': ".$dbh->errstr());
|
my $sth = $dbh->prepare_cached($sql) or croak("Can't prepare '$sql': ".$dbh->errstr());
|
||||||
my $res = $sth->execute() or croak("Can't execute: ".$sth->errstr());
|
my $res = $sth->execute() or croak("Can't execute: ".$sth->errstr());
|
||||||
while ( my $config = $sth->fetchrow_hashref() ) {
|
while ( my $config = $sth->fetchrow_hashref() ) {
|
||||||
|
# If already defined skip it because we want the values in /etc/zm.conf to override the values in Config Table
|
||||||
|
next if exists $Config{$config->{Name}};
|
||||||
$Config{$config->{Name}} = $config->{Value};
|
$Config{$config->{Name}} = $config->{Value};
|
||||||
}
|
}
|
||||||
$sth->finish();
|
$sth->finish();
|
||||||
|
@ -133,7 +136,7 @@ require ZoneMinder::Database;
|
||||||
print(STDERR "Warning, bad line in $config_file: $str\n");
|
print(STDERR "Warning, bad line in $config_file: $str\n");
|
||||||
next;
|
next;
|
||||||
} # end if
|
} # end if
|
||||||
$name =~ tr/a-z/A-Z/;
|
$name = uc $name;
|
||||||
#if ( !$ZoneMinder::ConfigData::options_hash{$name} ) {
|
#if ( !$ZoneMinder::ConfigData::options_hash{$name} ) {
|
||||||
#print(STDERR "Warning, unknown config option name $name in $config_file\n");
|
#print(STDERR "Warning, unknown config option name $name in $config_file\n");
|
||||||
#} else {
|
#} else {
|
||||||
|
|
|
@ -582,26 +582,6 @@ our @options = (
|
||||||
type => $types{integer},
|
type => $types{integer},
|
||||||
category => 'images',
|
category => 'images',
|
||||||
},
|
},
|
||||||
# Deprecated, now stream quality
|
|
||||||
{
|
|
||||||
name => 'ZM_JPEG_IMAGE_QUALITY',
|
|
||||||
default => '70',
|
|
||||||
description => q`Set the JPEG quality setting for the streamed 'live' images (1-100)`,
|
|
||||||
help => q`
|
|
||||||
When viewing a 'live' stream for a monitor ZoneMinder will grab
|
|
||||||
an image from the buffer and encode it into JPEG format before
|
|
||||||
sending it. This option specifies what image quality should be
|
|
||||||
used to encode these images. A higher number means better
|
|
||||||
quality but less compression so will take longer to view over a
|
|
||||||
slow connection. By contrast a low number means quicker to view
|
|
||||||
images but at the price of lower quality images. This option
|
|
||||||
does not apply when viewing events or still images as these are
|
|
||||||
usually just read from disk and so will be encoded at the
|
|
||||||
quality specified by the previous options.
|
|
||||||
`,
|
|
||||||
type => $types{integer},
|
|
||||||
category => 'hidden',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name => 'ZM_JPEG_STREAM_QUALITY',
|
name => 'ZM_JPEG_STREAM_QUALITY',
|
||||||
default => '70',
|
default => '70',
|
||||||
|
@ -877,38 +857,6 @@ our @options = (
|
||||||
type => $types{integer},
|
type => $types{integer},
|
||||||
category => 'config',
|
category => 'config',
|
||||||
},
|
},
|
||||||
# Deprecated, really no longer necessary
|
|
||||||
{
|
|
||||||
name => 'ZM_OPT_REMOTE_CAMERAS',
|
|
||||||
default => 'no',
|
|
||||||
description => 'Are you going to use remote/networked cameras',
|
|
||||||
help => q`
|
|
||||||
ZoneMinder can work with both local cameras, ie. those attached
|
|
||||||
physically to your computer and remote or network cameras. If
|
|
||||||
you will be using networked cameras select this option.
|
|
||||||
`,
|
|
||||||
type => $types{boolean},
|
|
||||||
category => 'hidden',
|
|
||||||
},
|
|
||||||
# Deprecated, now set on a per monitor basis using the Method field
|
|
||||||
{
|
|
||||||
name => 'ZM_NETCAM_REGEXPS',
|
|
||||||
default => 'yes',
|
|
||||||
description => 'Use regular expression matching with network cameras',
|
|
||||||
help => q`
|
|
||||||
Traditionally ZoneMinder has used complex regular regular
|
|
||||||
expressions to handle the multitude of formats that network
|
|
||||||
cameras produce. In versions from 1.21.1 the default is to use
|
|
||||||
a simpler and faster built in pattern matching methodology.
|
|
||||||
This works well with most networks cameras but if you have
|
|
||||||
problems you can try the older, but more flexible, regular
|
|
||||||
expression based method by selecting this option. Note, to use
|
|
||||||
this method you must have libpcre installed on your system.
|
|
||||||
`,
|
|
||||||
requires => [ { name => 'ZM_OPT_REMOTE_CAMERAS', value => 'yes' } ],
|
|
||||||
type => $types{boolean},
|
|
||||||
category => 'hidden',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name => 'ZM_HTTP_VERSION',
|
name => 'ZM_HTTP_VERSION',
|
||||||
default => '1.0',
|
default => '1.0',
|
||||||
|
@ -1974,19 +1922,6 @@ our @options = (
|
||||||
},
|
},
|
||||||
category => 'upload',
|
category => 'upload',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name => 'ZM_UPLOAD_FTP_HOST',
|
|
||||||
default => '',
|
|
||||||
description => 'The remote server to upload to',
|
|
||||||
help => q`
|
|
||||||
You can use filters to instruct ZoneMinder to upload events to
|
|
||||||
a remote ftp server. This option indicates the name, or ip
|
|
||||||
address, of the server to use.
|
|
||||||
`,
|
|
||||||
requires => [ { name => 'ZM_OPT_UPLOAD', value => 'yes' } ],
|
|
||||||
type => $types{hostname},
|
|
||||||
category => 'hidden',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name => 'ZM_UPLOAD_HOST',
|
name => 'ZM_UPLOAD_HOST',
|
||||||
default => '',
|
default => '',
|
||||||
|
@ -2015,19 +1950,6 @@ our @options = (
|
||||||
type => $types{integer},
|
type => $types{integer},
|
||||||
category => 'upload',
|
category => 'upload',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name => 'ZM_UPLOAD_FTP_USER',
|
|
||||||
default => '',
|
|
||||||
description => 'Your ftp username',
|
|
||||||
help => q`
|
|
||||||
You can use filters to instruct ZoneMinder to upload events to
|
|
||||||
a remote ftp server. This option indicates the username that
|
|
||||||
ZoneMinder should use to log in for ftp transfer.
|
|
||||||
`,
|
|
||||||
requires => [ { name => 'ZM_OPT_UPLOAD', value => 'yes' } ],
|
|
||||||
type => $types{alphanum},
|
|
||||||
category => 'hidden',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name => 'ZM_UPLOAD_USER',
|
name => 'ZM_UPLOAD_USER',
|
||||||
default => '',
|
default => '',
|
||||||
|
@ -2041,19 +1963,6 @@ our @options = (
|
||||||
type => $types{alphanum},
|
type => $types{alphanum},
|
||||||
category => 'upload',
|
category => 'upload',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name => 'ZM_UPLOAD_FTP_PASS',
|
|
||||||
default => '',
|
|
||||||
description => 'Your ftp password',
|
|
||||||
help => q`
|
|
||||||
You can use filters to instruct ZoneMinder to upload events to
|
|
||||||
a remote ftp server. This option indicates the password that
|
|
||||||
ZoneMinder should use to log in for ftp transfer.
|
|
||||||
`,
|
|
||||||
requires => [ { name => 'ZM_OPT_UPLOAD', value => 'yes' } ],
|
|
||||||
type => $types{string},
|
|
||||||
category => 'hidden',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name => 'ZM_UPLOAD_PASS',
|
name => 'ZM_UPLOAD_PASS',
|
||||||
default => '',
|
default => '',
|
||||||
|
@ -2069,21 +1978,6 @@ our @options = (
|
||||||
type => $types{string},
|
type => $types{string},
|
||||||
category => 'upload',
|
category => 'upload',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name => 'ZM_UPLOAD_FTP_LOC_DIR',
|
|
||||||
default => '@ZM_TMPDIR@',
|
|
||||||
description => 'The local directory in which to create upload files',
|
|
||||||
help => q`
|
|
||||||
You can use filters to instruct ZoneMinder to upload events to
|
|
||||||
a remote ftp server. This option indicates the local directory
|
|
||||||
that ZoneMinder should use for temporary upload files. These
|
|
||||||
are files that are created from events, uploaded and then
|
|
||||||
deleted.
|
|
||||||
`,
|
|
||||||
requires => [ { name => 'ZM_OPT_UPLOAD', value => 'yes' } ],
|
|
||||||
type => $types{abs_path},
|
|
||||||
category => 'hidden',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name => 'ZM_UPLOAD_LOC_DIR',
|
name => 'ZM_UPLOAD_LOC_DIR',
|
||||||
default => '@ZM_TMPDIR@',
|
default => '@ZM_TMPDIR@',
|
||||||
|
@ -2098,19 +1992,6 @@ our @options = (
|
||||||
type => $types{abs_path},
|
type => $types{abs_path},
|
||||||
category => 'upload',
|
category => 'upload',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name => 'ZM_UPLOAD_FTP_REM_DIR',
|
|
||||||
default => '',
|
|
||||||
description => 'The remote directory to upload to',
|
|
||||||
help => q`
|
|
||||||
You can use filters to instruct ZoneMinder to upload events to
|
|
||||||
a remote ftp server. This option indicates the remote directory
|
|
||||||
that ZoneMinder should use to upload event files to.
|
|
||||||
`,
|
|
||||||
requires => [ { name => 'ZM_OPT_UPLOAD', value => 'yes' } ],
|
|
||||||
type => $types{rel_path},
|
|
||||||
category => 'hidden',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name => 'ZM_UPLOAD_REM_DIR',
|
name => 'ZM_UPLOAD_REM_DIR',
|
||||||
default => '',
|
default => '',
|
||||||
|
@ -2124,21 +2005,6 @@ our @options = (
|
||||||
type => $types{rel_path},
|
type => $types{rel_path},
|
||||||
category => 'upload',
|
category => 'upload',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name => 'ZM_UPLOAD_FTP_TIMEOUT',
|
|
||||||
default => '120',
|
|
||||||
description => 'How long to allow the transfer to take for each file',
|
|
||||||
help => q`
|
|
||||||
You can use filters to instruct ZoneMinder to upload events to
|
|
||||||
a remote ftp server. This option indicates the maximum ftp
|
|
||||||
inactivity timeout (in seconds) that should be tolerated before
|
|
||||||
ZoneMinder determines that the transfer has failed and closes
|
|
||||||
down the connection.
|
|
||||||
`,
|
|
||||||
requires => [ { name => 'ZM_OPT_UPLOAD', value => 'yes' } ],
|
|
||||||
type => $types{integer},
|
|
||||||
category => 'hidden',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name => 'ZM_UPLOAD_TIMEOUT',
|
name => 'ZM_UPLOAD_TIMEOUT',
|
||||||
default => '120',
|
default => '120',
|
||||||
|
@ -2191,20 +2057,6 @@ our @options = (
|
||||||
type => $types{boolean},
|
type => $types{boolean},
|
||||||
category => 'upload',
|
category => 'upload',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name => 'ZM_UPLOAD_FTP_DEBUG',
|
|
||||||
default => 'no',
|
|
||||||
description => 'Switch ftp debugging on',
|
|
||||||
help => q`
|
|
||||||
You can use filters to instruct ZoneMinder to upload events to
|
|
||||||
a remote ftp server. If you are having (or expecting) troubles
|
|
||||||
with uploading events then setting this to 'yes' permits
|
|
||||||
additional information to be included in the zmfilter log file.
|
|
||||||
`,
|
|
||||||
requires => [ { name => 'ZM_OPT_UPLOAD', value => 'yes' } ],
|
|
||||||
type => $types{boolean},
|
|
||||||
category => 'hidden',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name => 'ZM_UPLOAD_DEBUG',
|
name => 'ZM_UPLOAD_DEBUG',
|
||||||
default => 'no',
|
default => 'no',
|
||||||
|
@ -2237,85 +2089,6 @@ our @options = (
|
||||||
type => $types{boolean},
|
type => $types{boolean},
|
||||||
category => 'mail',
|
category => 'mail',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name => 'ZM_EMAIL_ADDRESS',
|
|
||||||
default => '',
|
|
||||||
description => 'The email address to send matching event details to',
|
|
||||||
requires => [ { name => 'ZM_OPT_EMAIL', value => 'yes' } ],
|
|
||||||
help => q`
|
|
||||||
This option is used to define the email address that any events
|
|
||||||
that match the appropriate filters will be sent to.
|
|
||||||
`,
|
|
||||||
type => $types{email},
|
|
||||||
category => 'hidden',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name => 'ZM_EMAIL_TEXT',
|
|
||||||
default => 'subject = "ZoneMinder: Alarm - %MN%-%EI% (%ESM% - %ESA% %EFA%)"
|
|
||||||
body = "
|
|
||||||
Hello,
|
|
||||||
|
|
||||||
An alarm has been detected on your installation of the ZoneMinder.
|
|
||||||
|
|
||||||
The details are as follows :-
|
|
||||||
|
|
||||||
Monitor : %MN%
|
|
||||||
Event Id : %EI%
|
|
||||||
Length : %EL%
|
|
||||||
Frames : %EF% (%EFA%)
|
|
||||||
Scores : t%EST% m%ESM% a%ESA%
|
|
||||||
|
|
||||||
This alarm was matched by the %FN% filter and can be viewed at %EPS%
|
|
||||||
|
|
||||||
ZoneMinder"',
|
|
||||||
description => 'The text of the email used to send matching event details',
|
|
||||||
requires => [ { name => 'ZM_OPT_EMAIL', value => 'yes' } ],
|
|
||||||
help => q`
|
|
||||||
This option is used to define the content of the email that is
|
|
||||||
sent for any events that match the appropriate filters.
|
|
||||||
`,
|
|
||||||
type => $types{text},
|
|
||||||
category => 'hidden',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name => 'ZM_EMAIL_SUBJECT',
|
|
||||||
default => 'ZoneMinder: Alarm - %MN%-%EI% (%ESM% - %ESA% %EFA%)',
|
|
||||||
description => 'The subject of the email used to send matching event details',
|
|
||||||
requires => [ { name => 'ZM_OPT_EMAIL', value => 'yes' } ],
|
|
||||||
help => q`
|
|
||||||
This option is used to define the subject of the email that is
|
|
||||||
sent for any events that match the appropriate filters.
|
|
||||||
`,
|
|
||||||
type => $types{string},
|
|
||||||
category => 'hidden',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name => 'ZM_EMAIL_BODY',
|
|
||||||
default => '
|
|
||||||
Hello,
|
|
||||||
|
|
||||||
An alarm has been detected on your installation of the ZoneMinder.
|
|
||||||
|
|
||||||
The details are as follows :-
|
|
||||||
|
|
||||||
Monitor : %MN%
|
|
||||||
Event Id : %EI%
|
|
||||||
Length : %EL%
|
|
||||||
Frames : %EF% (%EFA%)
|
|
||||||
Scores : t%EST% m%ESM% a%ESA%
|
|
||||||
|
|
||||||
This alarm was matched by the %FN% filter and can be viewed at %EPS%
|
|
||||||
|
|
||||||
ZoneMinder',
|
|
||||||
description => 'The body of the email used to send matching event details',
|
|
||||||
requires => [ { name => 'ZM_OPT_EMAIL', value => 'yes' } ],
|
|
||||||
help => q`
|
|
||||||
This option is used to define the content of the email that is
|
|
||||||
sent for any events that match the appropriate filters.
|
|
||||||
`,
|
|
||||||
type => $types{text},
|
|
||||||
category => 'hidden',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name => 'ZM_OPT_MESSAGE',
|
name => 'ZM_OPT_MESSAGE',
|
||||||
default => 'no',
|
default => 'no',
|
||||||
|
@ -2347,19 +2120,6 @@ our @options = (
|
||||||
type => $types{email},
|
type => $types{email},
|
||||||
category => 'mail',
|
category => 'mail',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name => 'ZM_MESSAGE_TEXT',
|
|
||||||
default => 'subject = "ZoneMinder: Alarm - %MN%-%EI%"
|
|
||||||
body = "ZM alarm detected - %EL% secs, %EF%/%EFA% frames, t%EST%/m%ESM%/a%ESA% score."',
|
|
||||||
description => 'The text of the message used to send matching event details',
|
|
||||||
requires => [ { name => 'ZM_OPT_MESSAGE', value => 'yes' } ],
|
|
||||||
help => q`
|
|
||||||
This option is used to define the content of the message that
|
|
||||||
is sent for any events that match the appropriate filters.
|
|
||||||
`,
|
|
||||||
type => $types{text},
|
|
||||||
category => 'hidden',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name => 'ZM_MESSAGE_SUBJECT',
|
name => 'ZM_MESSAGE_SUBJECT',
|
||||||
default => 'ZoneMinder: Alarm - %MN%-%EI%',
|
default => 'ZoneMinder: Alarm - %MN%-%EI%',
|
||||||
|
@ -2652,23 +2412,6 @@ our @options = (
|
||||||
category => 'config',
|
category => 'config',
|
||||||
},
|
},
|
||||||
# Deprecated, superseded by event close mode
|
# Deprecated, superseded by event close mode
|
||||||
{
|
|
||||||
name => 'ZM_FORCE_CLOSE_EVENTS',
|
|
||||||
default => 'no',
|
|
||||||
description => 'Close events at section ends.',
|
|
||||||
help => q`
|
|
||||||
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 and ordinarily this will prevent the event being closed
|
|
||||||
until the motion has ceased. Switching this option on will
|
|
||||||
force the event closed at the specified time regardless of any
|
|
||||||
motion activity.
|
|
||||||
`,
|
|
||||||
type => $types{boolean},
|
|
||||||
category => 'hidden',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name => 'ZM_WEIGHTED_ALARM_CENTRES',
|
name => 'ZM_WEIGHTED_ALARM_CENTRES',
|
||||||
default => 'no',
|
default => 'no',
|
||||||
|
@ -2876,37 +2619,9 @@ our @options = (
|
||||||
type => $types{hexadecimal},
|
type => $types{hexadecimal},
|
||||||
category => 'system',
|
category => 'system',
|
||||||
},
|
},
|
||||||
# Deprecated, really no longer necessary
|
|
||||||
{
|
|
||||||
name => 'ZM_WEB_REFRESH_METHOD',
|
|
||||||
default => 'javascript',
|
|
||||||
description => 'What method windows should use to refresh themselves',
|
|
||||||
help => q`
|
|
||||||
Many windows in ZoneMinder need to refresh themselves to keep
|
|
||||||
their information current. This option determines what method
|
|
||||||
they should use to do this. Choosing 'javascript' means that
|
|
||||||
each window will have a short JavaScript statement in with a
|
|
||||||
timer to prompt the refresh. This is the most compatible
|
|
||||||
method. Choosing 'http' means the refresh instruction is put in
|
|
||||||
the HTTP header. This is a cleaner method but refreshes are
|
|
||||||
interrupted or cancelled when a link in the window is clicked
|
|
||||||
meaning that the window will no longer refresh and this would
|
|
||||||
have to be done manually.
|
|
||||||
`,
|
|
||||||
type => {
|
|
||||||
db_type =>'string',
|
|
||||||
hint =>'javascript|http',
|
|
||||||
pattern =>qr|^([jh])|i,
|
|
||||||
format =>q( $1 =~ /^j/
|
|
||||||
? 'javascript'
|
|
||||||
: 'http'
|
|
||||||
)
|
|
||||||
},
|
|
||||||
category => 'hidden',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name => 'ZM_WEB_EVENT_SORT_FIELD',
|
name => 'ZM_WEB_EVENT_SORT_FIELD',
|
||||||
default => 'DateTime',
|
default => 'StartDateTime',
|
||||||
description => 'Default field the event lists are sorted by',
|
description => 'Default field the event lists are sorted by',
|
||||||
help => q`
|
help => q`
|
||||||
Events in lists can be initially ordered in any way you want.
|
Events in lists can be initially ordered in any way you want.
|
||||||
|
@ -2918,7 +2633,7 @@ our @options = (
|
||||||
`,
|
`,
|
||||||
type => {
|
type => {
|
||||||
db_type =>'string',
|
db_type =>'string',
|
||||||
hint =>'Id|Name|Cause|MonitorName|DateTime|Length|Frames|AlarmFrames|TotScore|AvgScore|MaxScore',
|
hint =>'Id|Name|Cause|DiskSpace|MonitorName|StartDateTime|Length|Frames|AlarmFrames|TotScore|AvgScore|MaxScore',
|
||||||
pattern =>qr|.|,
|
pattern =>qr|.|,
|
||||||
format =>q( $1 )
|
format =>q( $1 )
|
||||||
},
|
},
|
||||||
|
@ -4043,7 +3758,6 @@ sub initialiseConfig {
|
||||||
} else {
|
} else {
|
||||||
$option->{value} = '';
|
$option->{value} = '';
|
||||||
}
|
}
|
||||||
#next if ( $option->{category} eq 'hidden' );
|
|
||||||
$option->{id} = $option_id++;
|
$option->{id} = $option_id++;
|
||||||
}
|
}
|
||||||
$configInitialised = 1;
|
$configInitialised = 1;
|
||||||
|
|
|
@ -113,7 +113,7 @@ sub open {
|
||||||
Debug('No headers line');
|
Debug('No headers line');
|
||||||
} # end if headers
|
} # end if headers
|
||||||
} else {
|
} else {
|
||||||
Warning('Failed to open '.$uri->canonical().$url.' status: '.$res->status_line());
|
Debug('Failed to open '.$uri->canonical().$url.' status: '.$res->status_line());
|
||||||
} # end if $res->status_line() eq '401 Unauthorized'
|
} # end if $res->status_line() eq '401 Unauthorized'
|
||||||
} # end sub open
|
} # end sub open
|
||||||
|
|
||||||
|
|
|
@ -146,15 +146,15 @@ sub zmDbGetMonitors {
|
||||||
|
|
||||||
if ( $function ) {
|
if ( $function ) {
|
||||||
if ( $function == DB_MON_CAPT ) {
|
if ( $function == DB_MON_CAPT ) {
|
||||||
$sql .= " where `Function` >= 'Monitor'";
|
$sql .= " WHERE `Function` >= 'Monitor'";
|
||||||
} elsif ( $function == DB_MON_ACTIVE ) {
|
} elsif ( $function == DB_MON_ACTIVE ) {
|
||||||
$sql .= " where `Function` > 'Monitor'";
|
$sql .= " WHERE `Function` > 'Monitor'";
|
||||||
} elsif ( $function == DB_MON_MOTION ) {
|
} elsif ( $function == DB_MON_MOTION ) {
|
||||||
$sql .= " where `Function` = 'Modect' or Function = 'Mocord'";
|
$sql .= " WHERE `Function` = 'Modect' OR `Function` = 'Mocord'";
|
||||||
} elsif ( $function == DB_MON_RECORD ) {
|
} elsif ( $function == DB_MON_RECORD ) {
|
||||||
$sql .= " where `Function` = 'Record' or Function = 'Mocord'";
|
$sql .= " WHERE `Function` = 'Record' OR `Function` = 'Mocord'";
|
||||||
} elsif ( $function == DB_MON_PASSIVE ) {
|
} elsif ( $function == DB_MON_PASSIVE ) {
|
||||||
$sql .= " where `Function` = 'Nodect'";
|
$sql .= " WHERE `Function` = 'Nodect'";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
my $sth = $dbh->prepare_cached( $sql );
|
my $sth = $dbh->prepare_cached( $sql );
|
||||||
|
|
|
@ -82,6 +82,13 @@ sub Execute {
|
||||||
my $self = $_[0];
|
my $self = $_[0];
|
||||||
my $sql = $self->Sql(undef);
|
my $sql = $self->Sql(undef);
|
||||||
|
|
||||||
|
if ( $$self{PreSQLConditions} and @{$$self{PreSQLConditions}} ) {
|
||||||
|
foreach my $term ( @{$$self{PreSQLConditions}} ) {
|
||||||
|
if ( $$term{attr} eq 'DiskPercent' ) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( $self->{HasDiskPercent} ) {
|
if ( $self->{HasDiskPercent} ) {
|
||||||
my $disk_percent = getDiskPercent($$self{Storage} ? $$self{Storage}->Path() : ());
|
my $disk_percent = getDiskPercent($$self{Storage} ? $$self{Storage}->Path() : ());
|
||||||
$sql =~ s/zmDiskPercent/$disk_percent/g;
|
$sql =~ s/zmDiskPercent/$disk_percent/g;
|
||||||
|
@ -104,14 +111,27 @@ sub Execute {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
my @results;
|
my @results;
|
||||||
|
|
||||||
while ( my $event = $sth->fetchrow_hashref() ) {
|
while ( my $event = $sth->fetchrow_hashref() ) {
|
||||||
push @results, $event;
|
push @results, $event;
|
||||||
}
|
}
|
||||||
$sth->finish();
|
$sth->finish();
|
||||||
Debug('Loaded ' . @results . " events for filter $_[0]{Name} using query ($sql)");
|
Debug('Loaded ' . @results . ' events for filter '.$$self{Name}.' using query ('.$sql.')"');
|
||||||
return @results;
|
if ( $self->{PostSQLConditions} ) {
|
||||||
|
my @filtered_events;
|
||||||
|
foreach my $term ( @{$$self{PostSQLConditions}} ) {
|
||||||
|
if ( $$term{attr} eq 'ExistsInFileSystem' ) {
|
||||||
|
foreach my $row ( @results ) {
|
||||||
|
my $event = new ZoneMinder::Event($row);
|
||||||
|
if ( -e $event->Path() ) {
|
||||||
|
push @filtered_events, $row;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} # end foreach term
|
||||||
|
@results = @filtered_events;
|
||||||
|
} # end if has PostSQLConditions
|
||||||
|
return @results;
|
||||||
|
} # end sub Execute
|
||||||
|
|
||||||
sub Sql {
|
sub Sql {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
@ -183,18 +203,22 @@ sub Sql {
|
||||||
$self->{Sql} .= "weekday( E.EndTime )";
|
$self->{Sql} .= "weekday( E.EndTime )";
|
||||||
|
|
||||||
#
|
#
|
||||||
|
} elsif ( $term->{attr} eq 'ExistsInFileSystem' ) {
|
||||||
|
push @{$self->{PostSQLConditions}}, $term;
|
||||||
} elsif ( $term->{attr} eq 'DiskSpace' ) {
|
} elsif ( $term->{attr} eq 'DiskSpace' ) {
|
||||||
$self->{Sql} .= 'E.DiskSpace';
|
$self->{Sql} .= 'E.DiskSpace';
|
||||||
$self->{HasDiskPercent} = !undef;
|
|
||||||
} elsif ( $term->{attr} eq 'DiskPercent' ) {
|
} elsif ( $term->{attr} eq 'DiskPercent' ) {
|
||||||
$self->{Sql} .= 'zmDiskPercent';
|
$self->{Sql} .= 'zmDiskPercent';
|
||||||
$self->{HasDiskPercent} = !undef;
|
$self->{HasDiskPercent} = !undef;
|
||||||
|
$self->{HasPreCondition} = !undef;
|
||||||
} elsif ( $term->{attr} eq 'DiskBlocks' ) {
|
} elsif ( $term->{attr} eq 'DiskBlocks' ) {
|
||||||
$self->{Sql} .= 'zmDiskBlocks';
|
$self->{Sql} .= 'zmDiskBlocks';
|
||||||
$self->{HasDiskBlocks} = !undef;
|
$self->{HasDiskBlocks} = !undef;
|
||||||
|
$self->{HasPreCondition} = !undef;
|
||||||
} elsif ( $term->{attr} eq 'SystemLoad' ) {
|
} elsif ( $term->{attr} eq 'SystemLoad' ) {
|
||||||
$self->{Sql} .= 'zmSystemLoad';
|
$self->{Sql} .= 'zmSystemLoad';
|
||||||
$self->{HasSystemLoad} = !undef;
|
$self->{HasSystemLoad} = !undef;
|
||||||
|
$self->{HasPreCondition} = !undef;
|
||||||
} else {
|
} else {
|
||||||
$self->{Sql} .= 'E.'.$term->{attr};
|
$self->{Sql} .= 'E.'.$term->{attr};
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ if ( $options{command} ) {
|
||||||
my $server_up;
|
my $server_up;
|
||||||
while ( $tries and ! ( $server_up = connect(CLIENT, $saddr) ) ) {
|
while ( $tries and ! ( $server_up = connect(CLIENT, $saddr) ) ) {
|
||||||
Debug("Failed to connect to zmcontrol server at $sock_file");
|
Debug("Failed to connect to zmcontrol server at $sock_file");
|
||||||
runCommand("zmdc.pl start zmcontrol.pl --id=$id");
|
runCommand("zmdc.pl start zmcontrol.pl --id $id");
|
||||||
sleep 1;
|
sleep 1;
|
||||||
$tries -= 1;
|
$tries -= 1;
|
||||||
}
|
}
|
||||||
|
@ -142,9 +142,9 @@ if ( $options{command} ) {
|
||||||
.strftime('%y/%m/%d %H:%M:%S', localtime())
|
.strftime('%y/%m/%d %H:%M:%S', localtime())
|
||||||
);
|
);
|
||||||
|
|
||||||
$0 = $0." --id=$id";
|
$0 = $0.' --id '.$id;
|
||||||
|
|
||||||
my $control = "ZoneMinder::Control::$protocol"->new($id);
|
my $control = ('ZoneMinder::Control::'.$protocol)->new($id);
|
||||||
my $control_key = $control->getKey();
|
my $control_key = $control->getKey();
|
||||||
$control->loadMonitor();
|
$control->loadMonitor();
|
||||||
|
|
||||||
|
|
|
@ -691,6 +691,7 @@ sub substituteTags {
|
||||||
$text =~ s/%EC%/$Event->{Cause}/g;
|
$text =~ s/%EC%/$Event->{Cause}/g;
|
||||||
$text =~ s/%ED%/$Event->{Notes}/g;
|
$text =~ s/%ED%/$Event->{Notes}/g;
|
||||||
$text =~ s/%ET%/$Event->{StartTime}/g;
|
$text =~ s/%ET%/$Event->{StartTime}/g;
|
||||||
|
$text =~ s/%EVF%/$$Event{DefaultVideo}/g; # Event video filename
|
||||||
$text =~ s/%EL%/$Event->{Length}/g;
|
$text =~ s/%EL%/$Event->{Length}/g;
|
||||||
$text =~ s/%EF%/$Event->{Frames}/g;
|
$text =~ s/%EF%/$Event->{Frames}/g;
|
||||||
$text =~ s/%EFA%/$Event->{AlarmFrames}/g;
|
$text =~ s/%EFA%/$Event->{AlarmFrames}/g;
|
||||||
|
@ -1017,8 +1018,7 @@ sub executeCommand {
|
||||||
|
|
||||||
my $event_path = $Event->Path();
|
my $event_path = $Event->Path();
|
||||||
|
|
||||||
my $command = $filter->{AutoExecuteCmd};
|
my $command = $filter->{AutoExecuteCmd}.' '.$event_path;
|
||||||
$command .= " $event_path";
|
|
||||||
$command = substituteTags($command, $filter, $Event);
|
$command = substituteTags($command, $filter, $Event);
|
||||||
|
|
||||||
Info("Executing '$command'");
|
Info("Executing '$command'");
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# CMakeLists.txt for the ZoneMinder binaries
|
# CMakeLists.txt for the ZoneMinder binaries
|
||||||
|
|
||||||
# Create files from the .in files
|
# Create files from the .in files
|
||||||
configure_file(zm_config.h.in "${CMAKE_CURRENT_BINARY_DIR}/zm_config.h" @ONLY)
|
configure_file(zm_config_data.h.in "${CMAKE_CURRENT_BINARY_DIR}/zm_config_data.h" @ONLY)
|
||||||
|
|
||||||
# Group together all the source files that are used by all the binaries (zmc, zmu, zms etc)
|
# Group together all the source files that are used by all the binaries (zmc, zmu, zms etc)
|
||||||
set(ZM_BIN_SRC_FILES
|
set(ZM_BIN_SRC_FILES
|
||||||
|
|
|
@ -20,4 +20,4 @@
|
||||||
#include "zm.h"
|
#include "zm.h"
|
||||||
|
|
||||||
/* This is our argv[0], we need it for backtrace */
|
/* This is our argv[0], we need it for backtrace */
|
||||||
const char* self = 0;
|
const char* self = nullptr;
|
||||||
|
|
|
@ -34,7 +34,7 @@ protected:
|
||||||
unsigned char *mTail;
|
unsigned char *mTail;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Buffer() : mStorage( 0 ), mAllocation( 0 ), mSize( 0 ), mHead( 0 ), mTail( 0 ) {
|
Buffer() : mStorage( nullptr ), mAllocation( 0 ), mSize( 0 ), mHead( nullptr ), mTail( nullptr ) {
|
||||||
}
|
}
|
||||||
explicit Buffer( unsigned int pSize ) : mAllocation( pSize ), mSize( 0 ) {
|
explicit Buffer( unsigned int pSize ) : mAllocation( pSize ), mSize( 0 ) {
|
||||||
mHead = mStorage = new unsigned char[mAllocation];
|
mHead = mStorage = new unsigned char[mAllocation];
|
||||||
|
|
|
@ -60,7 +60,7 @@ Camera::Camera(
|
||||||
Debug(2, "New camera id: %d width: %d line size: %d height: %d colours: %d subpixelorder: %d capture: %d",
|
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_id, width, linesize, height, colours, subpixelorder, capture);
|
||||||
|
|
||||||
monitor = NULL;
|
monitor = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Camera::~Camera() {
|
Camera::~Camera() {
|
||||||
|
|
|
@ -142,13 +142,13 @@ SockAddr *SockAddr::newSockAddr( const struct sockaddr &addr, socklen_t len )
|
||||||
return( new SockAddrUnix( (const struct sockaddr_un *)&addr ) );
|
return( new SockAddrUnix( (const struct sockaddr_un *)&addr ) );
|
||||||
}
|
}
|
||||||
Error( "Unable to create new SockAddr from addr family %d with size %d", addr.sa_family, len );
|
Error( "Unable to create new SockAddr from addr family %d with size %d", addr.sa_family, len );
|
||||||
return( 0 );
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
SockAddr *SockAddr::newSockAddr( const SockAddr *addr )
|
SockAddr *SockAddr::newSockAddr( const SockAddr *addr )
|
||||||
{
|
{
|
||||||
if ( !addr )
|
if ( !addr )
|
||||||
return( 0 );
|
return nullptr;
|
||||||
|
|
||||||
if ( addr->getDomain() == AF_INET )
|
if ( addr->getDomain() == AF_INET )
|
||||||
{
|
{
|
||||||
|
@ -159,7 +159,7 @@ SockAddr *SockAddr::newSockAddr( const SockAddr *addr )
|
||||||
return( new SockAddrUnix( *(SockAddrUnix *)addr ) );
|
return( new SockAddrUnix( *(SockAddrUnix *)addr ) );
|
||||||
}
|
}
|
||||||
Error( "Unable to create new SockAddr from addr family %d", addr->getDomain() );
|
Error( "Unable to create new SockAddr from addr family %d", addr->getDomain() );
|
||||||
return( 0 );
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
SockAddrInet::SockAddrInet() : SockAddr( (struct sockaddr *)&mAddrIn )
|
SockAddrInet::SockAddrInet() : SockAddr( (struct sockaddr *)&mAddrIn )
|
||||||
|
@ -170,14 +170,14 @@ bool SockAddrInet::resolve( const char *host, const char *serv, const char *prot
|
||||||
{
|
{
|
||||||
memset( &mAddrIn, 0, sizeof(mAddrIn) );
|
memset( &mAddrIn, 0, sizeof(mAddrIn) );
|
||||||
|
|
||||||
struct hostent *hostent=0;
|
struct hostent *hostent=nullptr;
|
||||||
if ( !(hostent = ::gethostbyname( host ) ) )
|
if ( !(hostent = ::gethostbyname( host ) ) )
|
||||||
{
|
{
|
||||||
Error( "gethostbyname( %s ), h_errno = %d", host, h_errno );
|
Error( "gethostbyname( %s ), h_errno = %d", host, h_errno );
|
||||||
return( false );
|
return( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
struct servent *servent=0;
|
struct servent *servent=nullptr;
|
||||||
if ( !(servent = ::getservbyname( serv, proto ) ) )
|
if ( !(servent = ::getservbyname( serv, proto ) ) )
|
||||||
{
|
{
|
||||||
Error( "getservbyname( %s ), errno = %d, error = %s", serv, errno, strerror(errno) );
|
Error( "getservbyname( %s ), errno = %d, error = %s", serv, errno, strerror(errno) );
|
||||||
|
@ -195,7 +195,7 @@ bool SockAddrInet::resolve( const char *host, int port, const char *proto )
|
||||||
{
|
{
|
||||||
memset( &mAddrIn, 0, sizeof(mAddrIn) );
|
memset( &mAddrIn, 0, sizeof(mAddrIn) );
|
||||||
|
|
||||||
struct hostent *hostent=0;
|
struct hostent *hostent=nullptr;
|
||||||
if ( !(hostent = ::gethostbyname( host ) ) )
|
if ( !(hostent = ::gethostbyname( host ) ) )
|
||||||
{
|
{
|
||||||
Error( "gethostbyname( %s ), h_errno = %d", host, h_errno );
|
Error( "gethostbyname( %s ), h_errno = %d", host, h_errno );
|
||||||
|
@ -212,7 +212,7 @@ bool SockAddrInet::resolve( const char *serv, const char *proto )
|
||||||
{
|
{
|
||||||
memset( &mAddrIn, 0, sizeof(mAddrIn) );
|
memset( &mAddrIn, 0, sizeof(mAddrIn) );
|
||||||
|
|
||||||
struct servent *servent=0;
|
struct servent *servent=nullptr;
|
||||||
if ( !(servent = ::getservbyname( serv, proto ) ) )
|
if ( !(servent = ::getservbyname( serv, proto ) ) )
|
||||||
{
|
{
|
||||||
Error( "getservbyname( %s ), errno = %d, error = %s", serv, errno, strerror(errno) );
|
Error( "getservbyname( %s ), errno = %d, error = %s", serv, errno, strerror(errno) );
|
||||||
|
@ -541,7 +541,7 @@ bool InetSocket::connect( const char *host, const char *serv )
|
||||||
* If socket(2) (or connect(2)) fails, we (close the socket
|
* If socket(2) (or connect(2)) fails, we (close the socket
|
||||||
* and) try the next address. */
|
* and) try the next address. */
|
||||||
|
|
||||||
for (rp = result; rp != NULL; rp = rp->ai_next) {
|
for (rp = result; rp != nullptr; rp = rp->ai_next) {
|
||||||
if (mSd != -1) {
|
if (mSd != -1) {
|
||||||
if (::connect(mSd, rp->ai_addr, rp->ai_addrlen) != -1)
|
if (::connect(mSd, rp->ai_addr, rp->ai_addrlen) != -1)
|
||||||
break; /* Success */
|
break; /* Success */
|
||||||
|
@ -576,7 +576,7 @@ bool InetSocket::connect( const char *host, const char *serv )
|
||||||
|
|
||||||
freeaddrinfo(result); /* No longer needed */
|
freeaddrinfo(result); /* No longer needed */
|
||||||
|
|
||||||
if (rp == NULL) { /* No address succeeded */
|
if (rp == nullptr) { /* No address succeeded */
|
||||||
Error( "connect(), Could not connect" );
|
Error( "connect(), Could not connect" );
|
||||||
mAddressFamily = AF_UNSPEC;
|
mAddressFamily = AF_UNSPEC;
|
||||||
return( false );
|
return( false );
|
||||||
|
@ -607,9 +607,9 @@ bool InetSocket::bind( const char * host, const char * serv )
|
||||||
hints.ai_socktype = getType();
|
hints.ai_socktype = getType();
|
||||||
hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */
|
hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */
|
||||||
hints.ai_protocol = 0; /* Any protocol */
|
hints.ai_protocol = 0; /* Any protocol */
|
||||||
hints.ai_canonname = NULL;
|
hints.ai_canonname = nullptr;
|
||||||
hints.ai_addr = NULL;
|
hints.ai_addr = nullptr;
|
||||||
hints.ai_next = NULL;
|
hints.ai_next = nullptr;
|
||||||
|
|
||||||
s = getaddrinfo(host, serv, &hints, &result);
|
s = getaddrinfo(host, serv, &hints, &result);
|
||||||
if (s != 0) {
|
if (s != 0) {
|
||||||
|
@ -621,7 +621,7 @@ bool InetSocket::bind( const char * host, const char * serv )
|
||||||
* Try each address until we successfully bind(2).
|
* Try each address until we successfully bind(2).
|
||||||
* If socket(2) (or bind(2)) fails, we (close the socket
|
* If socket(2) (or bind(2)) fails, we (close the socket
|
||||||
* and) try the next address. */
|
* and) try the next address. */
|
||||||
for (rp = result; rp != NULL; rp = rp->ai_next) {
|
for (rp = result; rp != nullptr; rp = rp->ai_next) {
|
||||||
memset(&buf, 0, sizeof(buf));
|
memset(&buf, 0, sizeof(buf));
|
||||||
if (rp->ai_family == AF_INET) {
|
if (rp->ai_family == AF_INET) {
|
||||||
inet_ntop(AF_INET, &((struct sockaddr_in *)rp->ai_addr)->sin_addr, buf, sizeof(buf)-1);
|
inet_ntop(AF_INET, &((struct sockaddr_in *)rp->ai_addr)->sin_addr, buf, sizeof(buf)-1);
|
||||||
|
@ -645,7 +645,7 @@ bool InetSocket::bind( const char * host, const char * serv )
|
||||||
mSd = -1;
|
mSd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rp == NULL) { /* No address succeeded */
|
if (rp == nullptr) { /* No address succeeded */
|
||||||
Error( "bind(), Could not bind" );
|
Error( "bind(), Could not bind" );
|
||||||
return( false );
|
return( false );
|
||||||
}
|
}
|
||||||
|
@ -657,7 +657,7 @@ bool InetSocket::bind( const char * host, const char * serv )
|
||||||
|
|
||||||
bool InetSocket::bind( const char * serv )
|
bool InetSocket::bind( const char * serv )
|
||||||
{
|
{
|
||||||
return bind( NULL, serv);
|
return bind( nullptr, serv);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InetSocket::bind( const char * host, int port )
|
bool InetSocket::bind( const char * host, int port )
|
||||||
|
@ -673,7 +673,7 @@ bool InetSocket::bind( int port )
|
||||||
char serv[8];
|
char serv[8];
|
||||||
snprintf(serv, sizeof(serv), "%d", port);
|
snprintf(serv, sizeof(serv), "%d", port);
|
||||||
|
|
||||||
return bind( NULL, serv );
|
return bind( nullptr, serv );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TcpInetServer::listen()
|
bool TcpInetServer::listen()
|
||||||
|
@ -689,7 +689,7 @@ bool TcpInetServer::accept()
|
||||||
bool TcpInetServer::accept( TcpInetSocket *&newSocket )
|
bool TcpInetServer::accept( TcpInetSocket *&newSocket )
|
||||||
{
|
{
|
||||||
int newSd = -1;
|
int newSd = -1;
|
||||||
newSocket = 0;
|
newSocket = nullptr;
|
||||||
|
|
||||||
if ( !Socket::accept( newSd ) )
|
if ( !Socket::accept( newSd ) )
|
||||||
return( false );
|
return( false );
|
||||||
|
@ -702,7 +702,7 @@ bool TcpInetServer::accept( TcpInetSocket *&newSocket )
|
||||||
bool TcpUnixServer::accept( TcpUnixSocket *&newSocket )
|
bool TcpUnixServer::accept( TcpUnixSocket *&newSocket )
|
||||||
{
|
{
|
||||||
int newSd = -1;
|
int newSd = -1;
|
||||||
newSocket = 0;
|
newSocket = nullptr;
|
||||||
|
|
||||||
if ( !Socket::accept( newSd ) )
|
if ( !Socket::accept( newSd ) )
|
||||||
return( false );
|
return( false );
|
||||||
|
@ -830,7 +830,7 @@ void Select::clearWriters()
|
||||||
int Select::wait()
|
int Select::wait()
|
||||||
{
|
{
|
||||||
struct timeval tempTimeout = mTimeout;
|
struct timeval tempTimeout = mTimeout;
|
||||||
struct timeval *selectTimeout = mHasTimeout?&tempTimeout:NULL;
|
struct timeval *selectTimeout = mHasTimeout?&tempTimeout:nullptr;
|
||||||
|
|
||||||
fd_set rfds;
|
fd_set rfds;
|
||||||
fd_set wfds;
|
fd_set wfds;
|
||||||
|
@ -845,7 +845,7 @@ int Select::wait()
|
||||||
for ( CommsSet::iterator iter = mWriters.begin(); iter != mWriters.end(); ++iter )
|
for ( CommsSet::iterator iter = mWriters.begin(); iter != mWriters.end(); ++iter )
|
||||||
FD_SET((*iter)->getWriteDesc(),&wfds);
|
FD_SET((*iter)->getWriteDesc(),&wfds);
|
||||||
|
|
||||||
int nFound = select( mMaxFd+1, &rfds, &wfds, NULL, selectTimeout );
|
int nFound = select( mMaxFd+1, &rfds, &wfds, nullptr, selectTimeout );
|
||||||
if( nFound == 0 )
|
if( nFound == 0 )
|
||||||
{
|
{
|
||||||
Debug( 1, "Select timed out" );
|
Debug( 1, "Select timed out" );
|
||||||
|
|
|
@ -416,8 +416,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual int sendto( const void *msg, int len, const SockAddr *addr=0 ) const {
|
virtual int sendto( const void *msg, int len, const SockAddr *addr=nullptr ) const {
|
||||||
ssize_t nBytes = ::sendto( mSd, msg, len, 0, addr?addr->getAddr():NULL, addr?addr->getAddrSize():0 );
|
ssize_t nBytes = ::sendto( mSd, msg, len, 0, addr?addr->getAddr():nullptr, addr?addr->getAddrSize():0 );
|
||||||
if ( nBytes < 0 )
|
if ( nBytes < 0 )
|
||||||
Debug( 1, "Sendto of %d bytes on sd %d failed: %s", len, mSd, strerror(errno) );
|
Debug( 1, "Sendto of %d bytes on sd %d failed: %s", len, mSd, strerror(errno) );
|
||||||
return( nBytes );
|
return( nBytes );
|
||||||
|
@ -432,7 +432,7 @@ public:
|
||||||
Debug( 1, "Recvfrom of %d bytes max on sd %d (with address) failed: %s", len, mSd, strerror(errno) );
|
Debug( 1, "Recvfrom of %d bytes max on sd %d (with address) failed: %s", len, mSd, strerror(errno) );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
nBytes = ::recvfrom( mSd, msg, len, 0, NULL, 0 );
|
nBytes = ::recvfrom( mSd, msg, len, 0, nullptr, 0 );
|
||||||
if ( nBytes < 0 )
|
if ( nBytes < 0 )
|
||||||
Debug( 1, "Recvfrom of %d bytes max on sd %d (no address) failed: %s", len, mSd, strerror(errno) );
|
Debug( 1, "Recvfrom of %d bytes max on sd %d (no address) failed: %s", len, mSd, strerror(errno) );
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,8 +37,7 @@
|
||||||
void zmLoadConfig() {
|
void zmLoadConfig() {
|
||||||
|
|
||||||
// Process name, value pairs from the main config file first
|
// Process name, value pairs from the main config file first
|
||||||
char configFile[PATH_MAX] = ZM_CONFIG;
|
process_configfile(ZM_CONFIG);
|
||||||
process_configfile(configFile);
|
|
||||||
|
|
||||||
// Search for user created config files. If one or more are found then
|
// Search for user created config files. If one or more are found then
|
||||||
// update the Config hash with those values
|
// update the Config hash with those values
|
||||||
|
@ -109,14 +108,14 @@ void zmLoadConfig() {
|
||||||
snprintf(staticConfig.video_file_format, sizeof(staticConfig.video_file_format), "%%s/%%s");
|
snprintf(staticConfig.video_file_format, sizeof(staticConfig.video_file_format), "%%s/%%s");
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_configfile(char* configFile) {
|
void process_configfile(char const *configFile) {
|
||||||
FILE *cfg;
|
FILE *cfg;
|
||||||
char line[512];
|
char line[512];
|
||||||
if ( (cfg = fopen(configFile, "r")) == NULL ) {
|
if ( (cfg = fopen(configFile, "r")) == nullptr ) {
|
||||||
Fatal("Can't open %s: %s", configFile, strerror(errno));
|
Fatal("Can't open %s: %s", configFile, strerror(errno));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while ( fgets(line, sizeof(line), cfg) != NULL ) {
|
while ( fgets(line, sizeof(line), cfg) != nullptr ) {
|
||||||
char *line_ptr = line;
|
char *line_ptr = line;
|
||||||
|
|
||||||
// Trim off any cr/lf line endings
|
// Trim off any cr/lf line endings
|
||||||
|
@ -261,16 +260,16 @@ ConfigItem::~ConfigItem() {
|
||||||
void ConfigItem::ConvertValue() const {
|
void ConfigItem::ConvertValue() const {
|
||||||
if ( !strcmp( type, "boolean" ) ) {
|
if ( !strcmp( type, "boolean" ) ) {
|
||||||
cfg_type = CFG_BOOLEAN;
|
cfg_type = CFG_BOOLEAN;
|
||||||
cfg_value.boolean_value = (bool)strtol(value, 0, 0);
|
cfg_value.boolean_value = (bool)strtol(value, nullptr, 0);
|
||||||
} else if ( !strcmp(type, "integer") ) {
|
} else if ( !strcmp(type, "integer") ) {
|
||||||
cfg_type = CFG_INTEGER;
|
cfg_type = CFG_INTEGER;
|
||||||
cfg_value.integer_value = strtol(value, 0, 10);
|
cfg_value.integer_value = strtol(value, nullptr, 10);
|
||||||
} else if ( !strcmp(type, "hexadecimal") ) {
|
} else if ( !strcmp(type, "hexadecimal") ) {
|
||||||
cfg_type = CFG_INTEGER;
|
cfg_type = CFG_INTEGER;
|
||||||
cfg_value.integer_value = strtol(value, 0, 16);
|
cfg_value.integer_value = strtol(value, nullptr, 16);
|
||||||
} else if ( !strcmp(type, "decimal") ) {
|
} else if ( !strcmp(type, "decimal") ) {
|
||||||
cfg_type = CFG_DECIMAL;
|
cfg_type = CFG_DECIMAL;
|
||||||
cfg_value.decimal_value = strtod(value, 0);
|
cfg_value.decimal_value = strtod(value, nullptr);
|
||||||
} else {
|
} else {
|
||||||
cfg_type = CFG_STRING;
|
cfg_type = CFG_STRING;
|
||||||
cfg_value.string_value = value;
|
cfg_value.string_value = value;
|
||||||
|
@ -335,10 +334,10 @@ Config::~Config() {
|
||||||
if ( items ) {
|
if ( items ) {
|
||||||
for ( int i = 0; i < n_items; i++ ) {
|
for ( int i = 0; i < n_items; i++ ) {
|
||||||
delete items[i];
|
delete items[i];
|
||||||
items[i] = NULL;
|
items[i] = nullptr;
|
||||||
}
|
}
|
||||||
delete[] items;
|
delete[] items;
|
||||||
items = NULL;
|
items = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,19 +23,13 @@
|
||||||
#if !defined(PATH_MAX)
|
#if !defined(PATH_MAX)
|
||||||
#define PATH_MAX 1024
|
#define PATH_MAX 1024
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "zm_config_defines.h"
|
#include "zm_config_defines.h"
|
||||||
|
#include "zm_config_data.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#define ZM_CONFIG "@ZM_CONFIG@" // Path to config file
|
|
||||||
#define ZM_CONFIG_SUBDIR "@ZM_CONFIG_SUBDIR@" // Path to the ZoneMinder config subfolder
|
|
||||||
#define ZM_VERSION "@VERSION@" // ZoneMinder Version
|
|
||||||
|
|
||||||
#define ZM_HAS_V4L1 @ZM_HAS_V4L1@
|
|
||||||
#define ZM_HAS_V4L2 @ZM_HAS_V4L2@
|
|
||||||
#define ZM_HAS_V4L @ZM_HAS_V4L@
|
|
||||||
|
|
||||||
#ifdef HAVE_LIBAVFORMAT
|
#ifdef HAVE_LIBAVFORMAT
|
||||||
#define ZM_HAS_FFMPEG 1
|
#define ZM_HAS_FFMPEG 1
|
||||||
#endif // HAVE_LIBAVFORMAT
|
#endif // HAVE_LIBAVFORMAT
|
||||||
|
@ -62,7 +56,7 @@
|
||||||
|
|
||||||
extern void zmLoadConfig();
|
extern void zmLoadConfig();
|
||||||
|
|
||||||
extern void process_configfile( char* configFile );
|
extern void process_configfile(char const *configFile);
|
||||||
|
|
||||||
struct StaticConfig {
|
struct StaticConfig {
|
||||||
std::string DB_HOST;
|
std::string DB_HOST;
|
|
@ -0,0 +1,31 @@
|
||||||
|
//
|
||||||
|
// ZoneMinder Configuration, $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.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef ZM_CONFIG_DATA_H
|
||||||
|
#define ZM_CONFIG_DATA_H
|
||||||
|
|
||||||
|
#define ZM_CONFIG "@ZM_CONFIG@" // Path to config file
|
||||||
|
#define ZM_CONFIG_SUBDIR "@ZM_CONFIG_SUBDIR@" // Path to the ZoneMinder config subfolder
|
||||||
|
#define ZM_VERSION "@VERSION@" // ZoneMinder Version
|
||||||
|
|
||||||
|
#define ZM_HAS_V4L1 @ZM_HAS_V4L1@
|
||||||
|
#define ZM_HAS_V4L2 @ZM_HAS_V4L2@
|
||||||
|
#define ZM_HAS_V4L @ZM_HAS_V4L@
|
||||||
|
|
||||||
|
#endif // ZM_CONFIG_DATA_H
|
|
@ -106,26 +106,26 @@ void cURLCamera::Initialise() {
|
||||||
Debug(2,"libcurl version: %s", (*curl_version_f)());
|
Debug(2,"libcurl version: %s", (*curl_version_f)());
|
||||||
|
|
||||||
/* Create the shared data mutex */
|
/* Create the shared data mutex */
|
||||||
int nRet = pthread_mutex_init(&shareddata_mutex, NULL);
|
int nRet = pthread_mutex_init(&shareddata_mutex, nullptr);
|
||||||
if(nRet != 0) {
|
if(nRet != 0) {
|
||||||
Error("Shared data mutex creation failed: %s",strerror(nRet));
|
Error("Shared data mutex creation failed: %s",strerror(nRet));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Create the data available condition variable */
|
/* Create the data available condition variable */
|
||||||
nRet = pthread_cond_init(&data_available_cond, NULL);
|
nRet = pthread_cond_init(&data_available_cond, nullptr);
|
||||||
if(nRet != 0) {
|
if(nRet != 0) {
|
||||||
Error("Data available condition variable creation failed: %s",strerror(nRet));
|
Error("Data available condition variable creation failed: %s",strerror(nRet));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Create the request complete condition variable */
|
/* Create the request complete condition variable */
|
||||||
nRet = pthread_cond_init(&request_complete_cond, NULL);
|
nRet = pthread_cond_init(&request_complete_cond, nullptr);
|
||||||
if(nRet != 0) {
|
if(nRet != 0) {
|
||||||
Error("Request complete condition variable creation failed: %s",strerror(nRet));
|
Error("Request complete condition variable creation failed: %s",strerror(nRet));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create the thread */
|
/* Create the thread */
|
||||||
nRet = pthread_create(&thread, NULL, thread_func_dispatcher, this);
|
nRet = pthread_create(&thread, nullptr, thread_func_dispatcher, this);
|
||||||
if(nRet != 0) {
|
if(nRet != 0) {
|
||||||
Error("Thread creation failed: %s",strerror(nRet));
|
Error("Thread creation failed: %s",strerror(nRet));
|
||||||
return;
|
return;
|
||||||
|
@ -137,7 +137,7 @@ void cURLCamera::Terminate() {
|
||||||
bTerminate = true;
|
bTerminate = true;
|
||||||
|
|
||||||
/* Wait for thread termination */
|
/* Wait for thread termination */
|
||||||
pthread_join(thread, NULL);
|
pthread_join(thread, nullptr);
|
||||||
|
|
||||||
/* Destroy condition variables */
|
/* Destroy condition variables */
|
||||||
pthread_cond_destroy(&request_complete_cond);
|
pthread_cond_destroy(&request_complete_cond);
|
||||||
|
@ -419,7 +419,7 @@ void* cURLCamera::thread_func() {
|
||||||
double dSize;
|
double dSize;
|
||||||
|
|
||||||
c = (*curl_easy_init_f)();
|
c = (*curl_easy_init_f)();
|
||||||
if(c == NULL) {
|
if(c == nullptr) {
|
||||||
dlclose(curl_lib);
|
dlclose(curl_lib);
|
||||||
Error("Failed getting easy handle from libcurl");
|
Error("Failed getting easy handle from libcurl");
|
||||||
tRet = -51;
|
tRet = -51;
|
||||||
|
@ -566,7 +566,7 @@ void* cURLCamera::thread_func() {
|
||||||
|
|
||||||
/* Cleanup */
|
/* Cleanup */
|
||||||
(*curl_easy_cleanup_f)(c);
|
(*curl_easy_cleanup_f)(c);
|
||||||
c = NULL;
|
c = nullptr;
|
||||||
|
|
||||||
return (void*)tRet;
|
return (void*)tRet;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,10 +48,10 @@ bool zmDbConnect() {
|
||||||
staticConfig.DB_SSL_CLIENT_KEY.c_str(),
|
staticConfig.DB_SSL_CLIENT_KEY.c_str(),
|
||||||
staticConfig.DB_SSL_CLIENT_CERT.c_str(),
|
staticConfig.DB_SSL_CLIENT_CERT.c_str(),
|
||||||
staticConfig.DB_SSL_CA_CERT.c_str(),
|
staticConfig.DB_SSL_CA_CERT.c_str(),
|
||||||
NULL, NULL);
|
nullptr, nullptr);
|
||||||
std::string::size_type colonIndex = staticConfig.DB_HOST.find(":");
|
std::string::size_type colonIndex = staticConfig.DB_HOST.find(":");
|
||||||
if ( colonIndex == std::string::npos ) {
|
if ( colonIndex == std::string::npos ) {
|
||||||
if ( !mysql_real_connect(&dbconn, staticConfig.DB_HOST.c_str(), staticConfig.DB_USER.c_str(), staticConfig.DB_PASS.c_str(), NULL, 0, NULL, 0) ) {
|
if ( !mysql_real_connect(&dbconn, staticConfig.DB_HOST.c_str(), staticConfig.DB_USER.c_str(), staticConfig.DB_PASS.c_str(), nullptr, 0, nullptr, 0) ) {
|
||||||
Error( "Can't connect to server: %s", mysql_error(&dbconn));
|
Error( "Can't connect to server: %s", mysql_error(&dbconn));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -59,12 +59,12 @@ bool zmDbConnect() {
|
||||||
std::string dbHost = staticConfig.DB_HOST.substr( 0, colonIndex );
|
std::string dbHost = staticConfig.DB_HOST.substr( 0, colonIndex );
|
||||||
std::string dbPortOrSocket = staticConfig.DB_HOST.substr( colonIndex+1 );
|
std::string dbPortOrSocket = staticConfig.DB_HOST.substr( colonIndex+1 );
|
||||||
if ( dbPortOrSocket[0] == '/' ) {
|
if ( dbPortOrSocket[0] == '/' ) {
|
||||||
if ( !mysql_real_connect(&dbconn, NULL, staticConfig.DB_USER.c_str(), staticConfig.DB_PASS.c_str(), NULL, 0, dbPortOrSocket.c_str(), 0) ) {
|
if ( !mysql_real_connect(&dbconn, nullptr, staticConfig.DB_USER.c_str(), staticConfig.DB_PASS.c_str(), nullptr, 0, dbPortOrSocket.c_str(), 0) ) {
|
||||||
Error("Can't connect to server: %s", mysql_error(&dbconn));
|
Error("Can't connect to server: %s", mysql_error(&dbconn));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ( !mysql_real_connect( &dbconn, dbHost.c_str(), staticConfig.DB_USER.c_str(), staticConfig.DB_PASS.c_str(), NULL, atoi(dbPortOrSocket.c_str()), NULL, 0 ) ) {
|
if ( !mysql_real_connect( &dbconn, dbHost.c_str(), staticConfig.DB_USER.c_str(), staticConfig.DB_PASS.c_str(), nullptr, atoi(dbPortOrSocket.c_str()), nullptr, 0 ) ) {
|
||||||
Error( "Can't connect to server: %s", mysql_error( &dbconn ) );
|
Error( "Can't connect to server: %s", mysql_error( &dbconn ) );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -94,20 +94,20 @@ void zmDbClose() {
|
||||||
MYSQL_RES * zmDbFetch(const char * query) {
|
MYSQL_RES * zmDbFetch(const char * query) {
|
||||||
if ( !zmDbConnected ) {
|
if ( !zmDbConnected ) {
|
||||||
Error("Not connected.");
|
Error("Not connected.");
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
db_mutex.lock();
|
db_mutex.lock();
|
||||||
// Might have been disconnected while we waited for the lock
|
// Might have been disconnected while we waited for the lock
|
||||||
if ( !zmDbConnected ) {
|
if ( !zmDbConnected ) {
|
||||||
db_mutex.unlock();
|
db_mutex.unlock();
|
||||||
Error("Not connected.");
|
Error("Not connected.");
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( mysql_query(&dbconn, query) ) {
|
if ( mysql_query(&dbconn, query) ) {
|
||||||
db_mutex.unlock();
|
db_mutex.unlock();
|
||||||
Error("Can't run query: %s", mysql_error(&dbconn));
|
Error("Can't run query: %s", mysql_error(&dbconn));
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
Debug(4, "Success running query: %s", query);
|
Debug(4, "Success running query: %s", query);
|
||||||
MYSQL_RES *result = mysql_store_result(&dbconn);
|
MYSQL_RES *result = mysql_store_result(&dbconn);
|
||||||
|
@ -124,7 +124,7 @@ zmDbRow *zmDbFetchOne(const char *query) {
|
||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
delete row;
|
delete row;
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
MYSQL_RES *zmDbRow::fetch(const char *query) {
|
MYSQL_RES *zmDbRow::fetch(const char *query) {
|
||||||
|
@ -135,14 +135,14 @@ MYSQL_RES *zmDbRow::fetch(const char *query) {
|
||||||
if ( n_rows != 1 ) {
|
if ( n_rows != 1 ) {
|
||||||
Error("Bogus number of lines return from query, %d returned for query %s.", n_rows, query);
|
Error("Bogus number of lines return from query, %d returned for query %s.", n_rows, query);
|
||||||
mysql_free_result(result_set);
|
mysql_free_result(result_set);
|
||||||
result_set = NULL;
|
result_set = nullptr;
|
||||||
return result_set;
|
return result_set;
|
||||||
}
|
}
|
||||||
|
|
||||||
row = mysql_fetch_row(result_set);
|
row = mysql_fetch_row(result_set);
|
||||||
if ( ! row ) {
|
if ( ! row ) {
|
||||||
mysql_free_result(result_set);
|
mysql_free_result(result_set);
|
||||||
result_set = NULL;
|
result_set = nullptr;
|
||||||
Error("Error getting row from query %s. Error is %s", query, mysql_error(&dbconn));
|
Error("Error getting row from query %s. Error is %s", query, mysql_error(&dbconn));
|
||||||
} else {
|
} else {
|
||||||
Debug(5, "Success");
|
Debug(5, "Success");
|
||||||
|
@ -153,6 +153,6 @@ MYSQL_RES *zmDbRow::fetch(const char *query) {
|
||||||
zmDbRow::~zmDbRow() {
|
zmDbRow::~zmDbRow() {
|
||||||
if ( result_set ) {
|
if ( result_set ) {
|
||||||
mysql_free_result(result_set);
|
mysql_free_result(result_set);
|
||||||
result_set = NULL;
|
result_set = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ class zmDbRow {
|
||||||
MYSQL_RES *result_set;
|
MYSQL_RES *result_set;
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
public:
|
public:
|
||||||
zmDbRow() { result_set = NULL; row = NULL; };
|
zmDbRow() { result_set = nullptr; row = nullptr; };
|
||||||
MYSQL_RES *fetch( const char *query );
|
MYSQL_RES *fetch( const char *query );
|
||||||
zmDbRow( MYSQL_RES *, MYSQL_ROW *row );
|
zmDbRow( MYSQL_RES *, MYSQL_ROW *row );
|
||||||
~zmDbRow();
|
~zmDbRow();
|
||||||
|
|
|
@ -230,12 +230,12 @@ Event::Event(
|
||||||
video_file.c_str(),
|
video_file.c_str(),
|
||||||
container.c_str(),
|
container.c_str(),
|
||||||
camera->get_VideoStream(),
|
camera->get_VideoStream(),
|
||||||
( monitor->RecordAudio() ? camera->get_AudioStream() : NULL ),
|
( monitor->RecordAudio() ? camera->get_AudioStream() : nullptr ),
|
||||||
monitor );
|
monitor );
|
||||||
|
|
||||||
if ( !videoStore->open() ) {
|
if ( !videoStore->open() ) {
|
||||||
delete videoStore;
|
delete videoStore;
|
||||||
videoStore = NULL;
|
videoStore = nullptr;
|
||||||
save_jpegs |= 1; // Turn on jpeg storage
|
save_jpegs |= 1; // Turn on jpeg storage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -245,10 +245,10 @@ Event::~Event() {
|
||||||
// We close the videowriter first, because if we finish the event, we might try to view the file, but we aren't done writing it yet.
|
// We close the videowriter first, because if we finish the event, we might try to view the file, but we aren't done writing it yet.
|
||||||
|
|
||||||
/* Close the video file */
|
/* Close the video file */
|
||||||
if ( videoStore ) {
|
if ( videoStore != nullptr ) {
|
||||||
Debug(2, "Deleting video store");
|
Debug(2, "Deleting video store");
|
||||||
delete videoStore;
|
delete videoStore;
|
||||||
videoStore = NULL;
|
videoStore = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DeltaTimeval delta_time;
|
struct DeltaTimeval delta_time;
|
||||||
|
@ -281,7 +281,7 @@ Event::~Event() {
|
||||||
// Should not be static because we might be multi-threaded
|
// Should not be static because we might be multi-threaded
|
||||||
char sql[ZM_SQL_LGE_BUFSIZ];
|
char sql[ZM_SQL_LGE_BUFSIZ];
|
||||||
snprintf(sql, sizeof(sql),
|
snprintf(sql, sizeof(sql),
|
||||||
"UPDATE Events SET Name='%s %" PRIu64 "', EndTime = from_unixtime(%ld), Length = %s%ld.%02ld, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d WHERE Id = %" PRIu64,
|
"UPDATE Events SET Name='%s%" PRIu64 "', EndTime = from_unixtime(%ld), Length = %s%ld.%02ld, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d WHERE Id = %" PRIu64 " AND Name='New Event'",
|
||||||
monitor->EventPrefix(), id, end_time.tv_sec,
|
monitor->EventPrefix(), id, end_time.tv_sec,
|
||||||
delta_time.positive?"":"-", delta_time.sec, delta_time.fsec,
|
delta_time.positive?"":"-", delta_time.sec, delta_time.fsec,
|
||||||
frames, alarm_frames,
|
frames, alarm_frames,
|
||||||
|
@ -294,6 +294,22 @@ Event::~Event() {
|
||||||
sleep(1);
|
sleep(1);
|
||||||
db_mutex.lock();
|
db_mutex.lock();
|
||||||
}
|
}
|
||||||
|
if ( !mysql_affected_rows(&dbconn) ) {
|
||||||
|
// Name might have been changed during recording, so just do the update without changing the name.
|
||||||
|
snprintf(sql, sizeof(sql),
|
||||||
|
"UPDATE Events SET EndTime = from_unixtime(%ld), Length = %s%ld.%02ld, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d WHERE Id = %" PRIu64,
|
||||||
|
end_time.tv_sec,
|
||||||
|
delta_time.positive?"":"-", delta_time.sec, delta_time.fsec,
|
||||||
|
frames, alarm_frames,
|
||||||
|
tot_score, (int)(alarm_frames?(tot_score/alarm_frames):0), max_score,
|
||||||
|
id);
|
||||||
|
while ( mysql_query(&dbconn, sql) && !zm_terminate ) {
|
||||||
|
db_mutex.unlock();
|
||||||
|
Error("Can't update event: %s reason: %s", sql, mysql_error(&dbconn));
|
||||||
|
sleep(1);
|
||||||
|
db_mutex.lock();
|
||||||
|
}
|
||||||
|
} // end if no changed rows due to Name change during recording
|
||||||
db_mutex.unlock();
|
db_mutex.unlock();
|
||||||
} // Event::~Event()
|
} // Event::~Event()
|
||||||
|
|
||||||
|
|
|
@ -128,8 +128,8 @@ class Event {
|
||||||
void updateNotes( const StringSetMap &stringSetMap );
|
void updateNotes( const StringSetMap &stringSetMap );
|
||||||
|
|
||||||
void AddFrames( int n_frames, Image **images, struct timeval **timestamps );
|
void AddFrames( int n_frames, Image **images, struct timeval **timestamps );
|
||||||
void AddFrame( Image *image, struct timeval timestamp, int score=0, Image *alarm_frame=NULL );
|
void AddFrame( Image *image, struct timeval timestamp, int score=0, Image *alarm_frame=nullptr );
|
||||||
void AddPacket( ZMPacket *p, int score=0, Image *alarm_frame=NULL );
|
void AddPacket( ZMPacket *p, int score=0, Image *alarm_frame=nullptr );
|
||||||
bool WritePacket( ZMPacket &p );
|
bool WritePacket( ZMPacket &p );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -159,16 +159,16 @@ class Event {
|
||||||
while ( pre_alarm_count > 0 ) {
|
while ( pre_alarm_count > 0 ) {
|
||||||
int i = pre_alarm_count - 1;
|
int i = pre_alarm_count - 1;
|
||||||
delete pre_alarm_data[i].image;
|
delete pre_alarm_data[i].image;
|
||||||
pre_alarm_data[i].image = NULL;
|
pre_alarm_data[i].image = nullptr;
|
||||||
if ( pre_alarm_data[i].alarm_frame ) {
|
if ( pre_alarm_data[i].alarm_frame ) {
|
||||||
delete pre_alarm_data[i].alarm_frame;
|
delete pre_alarm_data[i].alarm_frame;
|
||||||
pre_alarm_data[i].alarm_frame = NULL;
|
pre_alarm_data[i].alarm_frame = nullptr;
|
||||||
}
|
}
|
||||||
pre_alarm_count--;
|
pre_alarm_count--;
|
||||||
}
|
}
|
||||||
pre_alarm_count = 0;
|
pre_alarm_count = 0;
|
||||||
}
|
}
|
||||||
static void AddPreAlarmFrame(Image *image, struct timeval timestamp, int score=0, Image *alarm_frame=NULL) {
|
static void AddPreAlarmFrame(Image *image, struct timeval timestamp, int score=0, Image *alarm_frame=nullptr) {
|
||||||
pre_alarm_data[pre_alarm_count].image = new Image(*image);
|
pre_alarm_data[pre_alarm_count].image = new Image(*image);
|
||||||
pre_alarm_data[pre_alarm_count].timestamp = timestamp;
|
pre_alarm_data[pre_alarm_count].timestamp = timestamp;
|
||||||
pre_alarm_data[pre_alarm_count].score = score;
|
pre_alarm_data[pre_alarm_count].score = score;
|
||||||
|
|
|
@ -148,7 +148,7 @@ bool EventStream::loadEventData(uint64_t event_id) {
|
||||||
|
|
||||||
event_data->monitor_id = atoi(dbrow[0]);
|
event_data->monitor_id = atoi(dbrow[0]);
|
||||||
event_data->storage_id = dbrow[1] ? atoi(dbrow[1]) : 0;
|
event_data->storage_id = dbrow[1] ? atoi(dbrow[1]) : 0;
|
||||||
event_data->frame_count = dbrow[2] == NULL ? 0 : atoi(dbrow[2]);
|
event_data->frame_count = dbrow[2] == nullptr ? 0 : atoi(dbrow[2]);
|
||||||
event_data->start_time = atoi(dbrow[3]);
|
event_data->start_time = atoi(dbrow[3]);
|
||||||
event_data->duration = dbrow[4] ? atof(dbrow[4]) : 0.0;
|
event_data->duration = dbrow[4] ? atof(dbrow[4]) : 0.0;
|
||||||
strncpy(event_data->video_file, dbrow[5], sizeof(event_data->video_file)-1);
|
strncpy(event_data->video_file, dbrow[5], sizeof(event_data->video_file)-1);
|
||||||
|
@ -160,8 +160,8 @@ bool EventStream::loadEventData(uint64_t event_id) {
|
||||||
} else {
|
} else {
|
||||||
event_data->scheme = Storage::SHALLOW;
|
event_data->scheme = Storage::SHALLOW;
|
||||||
}
|
}
|
||||||
event_data->SaveJPEGs = dbrow[7] == NULL ? 0 : atoi(dbrow[7]);
|
event_data->SaveJPEGs = dbrow[7] == nullptr ? 0 : atoi(dbrow[7]);
|
||||||
event_data->Orientation = (Monitor::Orientation)(dbrow[8] == NULL ? 0 : atoi(dbrow[8]));
|
event_data->Orientation = (Monitor::Orientation)(dbrow[8] == nullptr ? 0 : atoi(dbrow[8]));
|
||||||
mysql_free_result(result);
|
mysql_free_result(result);
|
||||||
|
|
||||||
if ( !monitor ) {
|
if ( !monitor ) {
|
||||||
|
@ -303,7 +303,7 @@ bool EventStream::loadEventData(uint64_t event_id) {
|
||||||
if ( 0 > ffmpeg_input->Open(filepath.c_str()) ) {
|
if ( 0 > ffmpeg_input->Open(filepath.c_str()) ) {
|
||||||
Warning("Unable to open ffmpeg_input %s", filepath.c_str());
|
Warning("Unable to open ffmpeg_input %s", filepath.c_str());
|
||||||
delete ffmpeg_input;
|
delete ffmpeg_input;
|
||||||
ffmpeg_input = NULL;
|
ffmpeg_input = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -646,7 +646,6 @@ bool EventStream::sendFrame(int delta_us) {
|
||||||
|
|
||||||
static char filepath[PATH_MAX];
|
static char filepath[PATH_MAX];
|
||||||
static struct stat filestat;
|
static struct stat filestat;
|
||||||
FILE *fdj = NULL;
|
|
||||||
|
|
||||||
// This needs to be abstracted. If we are saving jpgs, then load the capture file.
|
// This needs to be abstracted. If we are saving jpgs, then load the capture file.
|
||||||
// If we are only saving analysis frames, then send that.
|
// If we are only saving analysis frames, then send that.
|
||||||
|
@ -662,7 +661,6 @@ bool EventStream::sendFrame(int delta_us) {
|
||||||
filepath[0] = 0;
|
filepath[0] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if ( !ffmpeg_input ) {
|
} else if ( !ffmpeg_input ) {
|
||||||
Fatal("JPEGS not saved. zms is not capable of streaming jpegs from mp4 yet");
|
Fatal("JPEGS not saved. zms is not capable of streaming jpegs from mp4 yet");
|
||||||
return false;
|
return false;
|
||||||
|
@ -684,34 +682,22 @@ bool EventStream::sendFrame(int delta_us) {
|
||||||
} else
|
} else
|
||||||
#endif // HAVE_LIBAVCODEC
|
#endif // HAVE_LIBAVCODEC
|
||||||
{
|
{
|
||||||
static unsigned char temp_img_buffer[ZM_MAX_IMAGE_SIZE];
|
|
||||||
|
|
||||||
|
static unsigned char temp_img_buffer[ZM_MAX_IMAGE_SIZE];
|
||||||
int img_buffer_size = 0;
|
int img_buffer_size = 0;
|
||||||
uint8_t *img_buffer = temp_img_buffer;
|
uint8_t *img_buffer = temp_img_buffer;
|
||||||
|
|
||||||
bool send_raw = ((scale>=ZM_SCALE_BASE)&&(zoom==ZM_SCALE_BASE)) && filepath[0];
|
bool send_raw = (type == STREAM_JPEG) && ((scale>=ZM_SCALE_BASE)&&(zoom==ZM_SCALE_BASE)) && filepath[0];
|
||||||
|
|
||||||
fprintf(stdout, "--ZoneMinderFrame\r\n");
|
fprintf(stdout, "--" BOUNDARY "\r\n");
|
||||||
|
|
||||||
if ( (type != STREAM_JPEG) || (!filepath[0]) )
|
|
||||||
send_raw = false;
|
|
||||||
|
|
||||||
if ( send_raw ) {
|
if ( send_raw ) {
|
||||||
fdj = fopen(filepath, "rb");
|
if ( !send_file(filepath) ) {
|
||||||
if ( !fdj ) {
|
Error("Can't send %s: %s", filepath, strerror(errno));
|
||||||
Error("Can't open %s: %s", filepath, strerror(errno));
|
|
||||||
return true; // returning false will cause us to terminate.
|
|
||||||
}
|
|
||||||
#if HAVE_SENDFILE
|
|
||||||
if ( fstat(fileno(fdj),&filestat) < 0 ) {
|
|
||||||
Error("Failed getting information about file %s: %s", filepath, strerror(errno));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
img_buffer_size = fread(img_buffer, 1, sizeof(temp_img_buffer), fdj);
|
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
Image *image = NULL;
|
Image *image = nullptr;
|
||||||
|
|
||||||
if ( filepath[0] ) {
|
if ( filepath[0] ) {
|
||||||
image = new Image(filepath);
|
image = new Image(filepath);
|
||||||
|
@ -765,91 +751,33 @@ bool EventStream::sendFrame(int delta_us) {
|
||||||
|
|
||||||
switch ( type ) {
|
switch ( type ) {
|
||||||
case STREAM_JPEG :
|
case STREAM_JPEG :
|
||||||
if ( send_image->EncodeJpeg(img_buffer, &img_buffer_size) ) {
|
send_image->EncodeJpeg(img_buffer, &img_buffer_size);
|
||||||
Debug(1, "encoded JPEG");
|
fputs("Content-Type: image/jpeg\r\n", stdout);
|
||||||
} else {
|
|
||||||
// Failed
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case STREAM_ZIP :
|
case STREAM_ZIP :
|
||||||
#if HAVE_ZLIB_H
|
|
||||||
unsigned long zip_buffer_size;
|
unsigned long zip_buffer_size;
|
||||||
send_image->Zip(img_buffer, &zip_buffer_size);
|
send_image->Zip(img_buffer, &zip_buffer_size);
|
||||||
img_buffer_size = zip_buffer_size;
|
img_buffer_size = zip_buffer_size;
|
||||||
|
fputs("Content-Type: image/x-rgbz\r\n", stdout);
|
||||||
break;
|
break;
|
||||||
#else
|
|
||||||
Error("zlib is required for zipped images. Falling back to raw image");
|
|
||||||
type = STREAM_RAW;
|
|
||||||
#endif // HAVE_ZLIB_H
|
|
||||||
case STREAM_RAW :
|
case STREAM_RAW :
|
||||||
img_buffer = (uint8_t*)(send_image->Buffer());
|
img_buffer = (uint8_t*)(send_image->Buffer());
|
||||||
img_buffer_size = send_image->Size();
|
img_buffer_size = send_image->Size();
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Fatal("Unexpected frame type %d", type);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
delete image;
|
|
||||||
image = NULL;
|
|
||||||
} // end if send_raw or not
|
|
||||||
|
|
||||||
switch ( type ) {
|
|
||||||
case STREAM_JPEG :
|
|
||||||
fputs("Content-Type: image/jpeg\r\n", stdout);
|
|
||||||
break;
|
|
||||||
case STREAM_RAW :
|
|
||||||
fputs("Content-Type: image/x-rgb\r\n", stdout);
|
fputs("Content-Type: image/x-rgb\r\n", stdout);
|
||||||
break;
|
break;
|
||||||
case STREAM_ZIP :
|
|
||||||
fputs("Content-Type: image/x-rgbz\r\n", stdout);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
Fatal("Unexpected frame type %d", type);
|
Fatal("Unexpected frame type %d", type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
send_buffer(img_buffer, img_buffer_size);
|
||||||
if ( send_raw ) {
|
delete image;
|
||||||
#if HAVE_SENDFILE
|
image = nullptr;
|
||||||
if ( 0 > fprintf(stdout, "Content-Length: %d\r\n\r\n", (int)filestat.st_size) ) {
|
|
||||||
fclose(fdj); /* Close the file handle */
|
|
||||||
Info("Unable to send raw frame %u: %s", curr_frame_id, strerror(errno));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if ( zm_sendfile(fileno(stdout), fileno(fdj), 0, (int)filestat.st_size) != (int)filestat.st_size ) {
|
|
||||||
/* sendfile() failed, use standard way instead */
|
|
||||||
img_buffer_size = fread(img_buffer, 1, sizeof(temp_img_buffer), fdj);
|
|
||||||
if ( fwrite(img_buffer, img_buffer_size, 1, stdout) != 1 ) {
|
|
||||||
fclose(fdj); /* Close the file handle */
|
|
||||||
Info("Unable to send raw frame %u: %s", curr_frame_id, strerror(errno));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (
|
|
||||||
(0 > fprintf(stdout, "Content-Length: %d\r\n\r\n", img_buffer_size) )
|
|
||||||
||
|
|
||||||
( fwrite(img_buffer, img_buffer_size, 1, stdout) != 1 )
|
|
||||||
) {
|
|
||||||
fclose(fdj); /* Close the file handle */
|
|
||||||
Info("Unable to send raw frame %u: %s", curr_frame_id, strerror(errno));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
fclose(fdj); /* Close the file handle */
|
|
||||||
} else {
|
|
||||||
Debug(3, "Content length: %d", img_buffer_size);
|
|
||||||
if (
|
|
||||||
(0 > fprintf(stdout, "Content-Length: %d\r\n\r\n", img_buffer_size) )
|
|
||||||
||
|
|
||||||
( fwrite(img_buffer, img_buffer_size, 1, stdout) != 1 ) ) {
|
|
||||||
Error("Unable to send stream frame: %s", strerror(errno));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} // end if send_raw or not
|
} // end if send_raw or not
|
||||||
|
|
||||||
|
} // end if stream MPEG or other
|
||||||
|
|
||||||
fputs("\r\n\r\n", stdout);
|
fputs("\r\n\r\n", stdout);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
} // end if stream MPEG or other
|
|
||||||
last_frame_sent = TV_2_FLOAT(now);
|
last_frame_sent = TV_2_FLOAT(now);
|
||||||
return true;
|
return true;
|
||||||
} // bool EventStream::sendFrame( int delta_us )
|
} // bool EventStream::sendFrame( int delta_us )
|
||||||
|
@ -860,7 +788,7 @@ void EventStream::runStream() {
|
||||||
checkInitialised();
|
checkInitialised();
|
||||||
|
|
||||||
if ( type == STREAM_JPEG )
|
if ( type == STREAM_JPEG )
|
||||||
fputs("Content-Type: multipart/x-mixed-replace;boundary=ZoneMinderFrame\r\n\r\n", stdout);
|
fputs("Content-Type: multipart/x-mixed-replace;boundary=" BOUNDARY "\r\n\r\n", stdout);
|
||||||
|
|
||||||
if ( !event_data ) {
|
if ( !event_data ) {
|
||||||
sendTextFrame("No event data found");
|
sendTextFrame("No event data found");
|
||||||
|
@ -869,7 +797,7 @@ void EventStream::runStream() {
|
||||||
|
|
||||||
Debug(3, "frame rate is: (%f)", (double)event_data->frame_count/event_data->duration);
|
Debug(3, "frame rate is: (%f)", (double)event_data->frame_count/event_data->duration);
|
||||||
updateFrameRate((double)event_data->frame_count/event_data->duration);
|
updateFrameRate((double)event_data->frame_count/event_data->duration);
|
||||||
gettimeofday(&start, NULL);
|
gettimeofday(&start, nullptr);
|
||||||
uint64_t start_usec = start.tv_sec * 1000000 + start.tv_usec;
|
uint64_t start_usec = start.tv_sec * 1000000 + start.tv_usec;
|
||||||
uint64_t last_frame_offset = 0;
|
uint64_t last_frame_offset = 0;
|
||||||
|
|
||||||
|
@ -877,7 +805,7 @@ void EventStream::runStream() {
|
||||||
double time_to_event = 0;
|
double time_to_event = 0;
|
||||||
|
|
||||||
while ( !zm_terminate ) {
|
while ( !zm_terminate ) {
|
||||||
gettimeofday(&now, NULL);
|
gettimeofday(&now, nullptr);
|
||||||
|
|
||||||
int delta_us = 0;
|
int delta_us = 0;
|
||||||
send_frame = false;
|
send_frame = false;
|
||||||
|
@ -981,7 +909,7 @@ void EventStream::runStream() {
|
||||||
// +/- 1? What if we are skipping frames?
|
// +/- 1? What if we are skipping frames?
|
||||||
curr_frame_id += (replay_rate>0) ? frame_mod : -1*frame_mod;
|
curr_frame_id += (replay_rate>0) ? frame_mod : -1*frame_mod;
|
||||||
// sending the frame may have taken some time, so reload now
|
// sending the frame may have taken some time, so reload now
|
||||||
gettimeofday(&now, NULL);
|
gettimeofday(&now, nullptr);
|
||||||
uint64_t now_usec = (now.tv_sec * 1000000 + now.tv_usec);
|
uint64_t now_usec = (now.tv_sec * 1000000 + now.tv_usec);
|
||||||
|
|
||||||
// we incremented by replay_rate, so might have jumped past frame_count
|
// we incremented by replay_rate, so might have jumped past frame_count
|
||||||
|
@ -1078,7 +1006,65 @@ void EventStream::runStream() {
|
||||||
#endif // HAVE_LIBAVCODEC
|
#endif // HAVE_LIBAVCODEC
|
||||||
|
|
||||||
closeComms();
|
closeComms();
|
||||||
} // void EventStream::runStream()
|
} // end void EventStream::runStream()
|
||||||
|
|
||||||
|
bool EventStream::send_file(const char * filepath) {
|
||||||
|
static unsigned char temp_img_buffer[ZM_MAX_IMAGE_SIZE];
|
||||||
|
|
||||||
|
int img_buffer_size = 0;
|
||||||
|
uint8_t *img_buffer = temp_img_buffer;
|
||||||
|
|
||||||
|
FILE *fdj = NULL;
|
||||||
|
fdj = fopen(filepath, "rb");
|
||||||
|
if ( !fdj ) {
|
||||||
|
Error("Can't open %s: %s", filepath, strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool size_sent = false;
|
||||||
|
|
||||||
|
#if HAVE_SENDFILE
|
||||||
|
static struct stat filestat;
|
||||||
|
if ( fstat(fileno(fdj), &filestat) < 0 ) {
|
||||||
|
Error("Failed getting information about file %s: %s", filepath, strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( 0 > fprintf(stdout, "Content-Length: %d\r\n\r\n", (int)filestat.st_size) ) {
|
||||||
|
fclose(fdj); /* Close the file handle */
|
||||||
|
Info("Unable to send raw frame %u: %s", curr_frame_id, strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
size_sent = true;
|
||||||
|
|
||||||
|
if ( zm_sendfile(fileno(stdout), fileno(fdj), 0, (int)filestat.st_size) != (int)filestat.st_size ) {
|
||||||
|
fclose(fdj); /* Close the file handle */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
img_buffer_size = fread(img_buffer, 1, sizeof(temp_img_buffer), fdj);
|
||||||
|
if ( !size_sent ) {
|
||||||
|
if ( 0 > fprintf(stdout, "Content-Length: %d\r\n\r\n", img_buffer_size) ) {
|
||||||
|
fclose(fdj); /* Close the file handle */
|
||||||
|
Info("Unable to send raw frame %u: %s", curr_frame_id, strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( fwrite(img_buffer, img_buffer_size, 1, stdout) != 1 ) {
|
||||||
|
Error("Unable to send raw frame %u: %s", curr_frame_id, strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fdj); /* Close the file handle */
|
||||||
|
return true;
|
||||||
|
} // end bool EventStream::send_file(const char * filepath)
|
||||||
|
|
||||||
|
bool EventStream::send_buffer(uint8_t* buffer, int size) {
|
||||||
|
fprintf(stdout, "Content-Length: %d\r\n\r\n", size);
|
||||||
|
if ( fwrite(buffer, size, 1, stdout) != 1 ) {
|
||||||
|
Error("Unable to send raw frame %u: %s", curr_frame_id, strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} // end bool EventStream::send_buffer(uint8_t* buffer, int size)
|
||||||
|
|
||||||
void EventStream::setStreamStart(
|
void EventStream::setStreamStart(
|
||||||
uint64_t init_event_id,
|
uint64_t init_event_id,
|
||||||
|
|
|
@ -97,33 +97,33 @@ class EventStream : public StreamBase {
|
||||||
curr_frame_id(0),
|
curr_frame_id(0),
|
||||||
curr_stream_time(0.0),
|
curr_stream_time(0.0),
|
||||||
send_frame(false),
|
send_frame(false),
|
||||||
event_data(0),
|
event_data(nullptr),
|
||||||
storage(NULL),
|
storage(nullptr),
|
||||||
ffmpeg_input(NULL),
|
ffmpeg_input(nullptr),
|
||||||
// Used when loading frames from an mp4
|
// Used when loading frames from an mp4
|
||||||
input_codec_context(0),
|
input_codec_context(nullptr),
|
||||||
input_codec(0)
|
input_codec(nullptr)
|
||||||
{}
|
{}
|
||||||
~EventStream() {
|
~EventStream() {
|
||||||
if ( event_data ) {
|
if ( event_data ) {
|
||||||
if ( event_data->frames ) {
|
if ( event_data->frames ) {
|
||||||
delete[] event_data->frames;
|
delete[] event_data->frames;
|
||||||
event_data->frames = NULL;
|
event_data->frames = nullptr;
|
||||||
}
|
}
|
||||||
delete event_data;
|
delete event_data;
|
||||||
event_data = NULL;
|
event_data = nullptr;
|
||||||
}
|
}
|
||||||
if ( monitor ) {
|
if ( monitor ) {
|
||||||
delete monitor;
|
delete monitor;
|
||||||
monitor = NULL;
|
monitor = nullptr;
|
||||||
}
|
}
|
||||||
if ( storage ) {
|
if ( storage ) {
|
||||||
delete storage;
|
delete storage;
|
||||||
storage = NULL;
|
storage = nullptr;
|
||||||
}
|
}
|
||||||
if ( ffmpeg_input ) {
|
if ( ffmpeg_input ) {
|
||||||
delete ffmpeg_input;
|
delete ffmpeg_input;
|
||||||
ffmpeg_input = NULL;
|
ffmpeg_input = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void setStreamStart( uint64_t init_event_id, unsigned int init_frame_id );
|
void setStreamStart( uint64_t init_event_id, unsigned int init_frame_id );
|
||||||
|
@ -134,6 +134,8 @@ class EventStream : public StreamBase {
|
||||||
void runStream();
|
void runStream();
|
||||||
Image *getImage();
|
Image *getImage();
|
||||||
private:
|
private:
|
||||||
|
bool send_file( const char *file_path );
|
||||||
|
bool send_buffer( uint8_t * buffer, int size );
|
||||||
Storage *storage;
|
Storage *storage;
|
||||||
FFmpeg_Input *ffmpeg_input;
|
FFmpeg_Input *ffmpeg_input;
|
||||||
AVCodecContext *input_codec_context;
|
AVCodecContext *input_codec_context;
|
||||||
|
|
|
@ -81,7 +81,7 @@ void FFMPEGInit() {
|
||||||
av_log_set_callback(log_libav_callback);
|
av_log_set_callback(log_libav_callback);
|
||||||
Info("Enabling ffmpeg logs, as LOG_DEBUG+LOG_FFMPEG are enabled in options");
|
Info("Enabling ffmpeg logs, as LOG_DEBUG+LOG_FFMPEG are enabled in options");
|
||||||
} else {
|
} else {
|
||||||
Info("Not enabling ffmpeg logs, as LOG_FFMPEG and/or LOG_DEBUG is disabled in options, or this monitor is not part of your debug targets");
|
Debug(1,"Not enabling ffmpeg logs, as LOG_FFMPEG and/or LOG_DEBUG is disabled in options, or this monitor is not part of your debug targets");
|
||||||
av_log_set_level(AV_LOG_QUIET);
|
av_log_set_level(AV_LOG_QUIET);
|
||||||
}
|
}
|
||||||
#if !LIBAVFORMAT_VERSION_CHECK(58, 9, 0, 64, 0)
|
#if !LIBAVFORMAT_VERSION_CHECK(58, 9, 0, 64, 0)
|
||||||
|
@ -151,7 +151,7 @@ static int parse_key_value_pair(AVDictionary **pm, const char **buf,
|
||||||
int flags)
|
int flags)
|
||||||
{
|
{
|
||||||
char *key = av_get_token(buf, key_val_sep);
|
char *key = av_get_token(buf, key_val_sep);
|
||||||
char *val = NULL;
|
char *val = nullptr;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (key && *key && strspn(*buf, key_val_sep)) {
|
if (key && *key && strspn(*buf, key_val_sep)) {
|
||||||
|
@ -225,7 +225,7 @@ int hacked_up_context2_for_older_ffmpeg(AVFormatContext **avctx, AVOutputFormat
|
||||||
AVFormatContext *s = avformat_alloc_context();
|
AVFormatContext *s = avformat_alloc_context();
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
*avctx = NULL;
|
*avctx = nullptr;
|
||||||
if (!s) {
|
if (!s) {
|
||||||
av_log(s, AV_LOG_ERROR, "Out of memory\n");
|
av_log(s, AV_LOG_ERROR, "Out of memory\n");
|
||||||
ret = AVERROR(ENOMEM);
|
ret = AVERROR(ENOMEM);
|
||||||
|
@ -234,13 +234,13 @@ int hacked_up_context2_for_older_ffmpeg(AVFormatContext **avctx, AVOutputFormat
|
||||||
|
|
||||||
if (!oformat) {
|
if (!oformat) {
|
||||||
if (format) {
|
if (format) {
|
||||||
oformat = av_guess_format(format, NULL, NULL);
|
oformat = av_guess_format(format, nullptr, nullptr);
|
||||||
if (!oformat) {
|
if (!oformat) {
|
||||||
av_log(s, AV_LOG_ERROR, "Requested output format '%s' is not a suitable output format\n", format);
|
av_log(s, AV_LOG_ERROR, "Requested output format '%s' is not a suitable output format\n", format);
|
||||||
ret = AVERROR(EINVAL);
|
ret = AVERROR(EINVAL);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
oformat = av_guess_format(NULL, filename, NULL);
|
oformat = av_guess_format(nullptr, filename, nullptr);
|
||||||
if (!oformat) {
|
if (!oformat) {
|
||||||
ret = AVERROR(EINVAL);
|
ret = AVERROR(EINVAL);
|
||||||
av_log(s, AV_LOG_ERROR, "Unable to find a suitable output format for '%s'\n", filename);
|
av_log(s, AV_LOG_ERROR, "Unable to find a suitable output format for '%s'\n", filename);
|
||||||
|
@ -267,7 +267,7 @@ int hacked_up_context2_for_older_ffmpeg(AVFormatContext **avctx, AVOutputFormat
|
||||||
ret = AVERROR(ENOMEM);
|
ret = AVERROR(ENOMEM);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
s->priv_data = NULL;
|
s->priv_data = nullptr;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -335,7 +335,7 @@ void zm_dump_stream_format(AVFormatContext *ic, int i, int index, int is_output)
|
||||||
Debug(1, "Dumping stream index i(%d) index(%d)", i, index );
|
Debug(1, "Dumping stream index i(%d) index(%d)", i, index );
|
||||||
int flags = (is_output ? ic->oformat->flags : ic->iformat->flags);
|
int flags = (is_output ? ic->oformat->flags : ic->iformat->flags);
|
||||||
AVStream *st = ic->streams[i];
|
AVStream *st = ic->streams[i];
|
||||||
AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0);
|
AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", nullptr, 0);
|
||||||
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
||||||
AVCodecParameters *codec = st->codecpar;
|
AVCodecParameters *codec = st->codecpar;
|
||||||
#else
|
#else
|
||||||
|
@ -533,7 +533,7 @@ int zm_receive_packet(AVCodecContext *context, AVPacket &packet) {
|
||||||
return 1;
|
return 1;
|
||||||
#else
|
#else
|
||||||
int got_packet = 0;
|
int got_packet = 0;
|
||||||
int ret = avcodec_encode_audio2(context, &packet, NULL, &got_packet);
|
int ret = avcodec_encode_audio2(context, &packet, nullptr, &got_packet);
|
||||||
if ( ret < 0 ) {
|
if ( ret < 0 ) {
|
||||||
Error("Error encoding (%d) (%s)", ret, av_err2str(ret));
|
Error("Error encoding (%d) (%s)", ret, av_err2str(ret));
|
||||||
}
|
}
|
||||||
|
@ -730,7 +730,7 @@ int zm_resample_audio(
|
||||||
Error("Flushing resampler not supported by AVRESAMPLE");
|
Error("Flushing resampler not supported by AVRESAMPLE");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int ret = avresample_convert(resample_ctx, NULL, 0, 0, in_frame->data,
|
int ret = avresample_convert(resample_ctx, nullptr, 0, 0, in_frame->data,
|
||||||
0, in_frame->nb_samples);
|
0, in_frame->nb_samples);
|
||||||
if ( ret < 0 ) {
|
if ( ret < 0 ) {
|
||||||
Error("Could not resample frame (error '%s')",
|
Error("Could not resample frame (error '%s')",
|
||||||
|
|
|
@ -40,6 +40,7 @@ extern "C" {
|
||||||
#include <libavutil/mathematics.h>
|
#include <libavutil/mathematics.h>
|
||||||
#include <libavutil/avstring.h>
|
#include <libavutil/avstring.h>
|
||||||
#include "libavutil/audio_fifo.h"
|
#include "libavutil/audio_fifo.h"
|
||||||
|
#include "libavutil/imgutils.h"
|
||||||
|
|
||||||
/* LIBAVUTIL_VERSION_CHECK checks for the right version of libav and FFmpeg
|
/* LIBAVUTIL_VERSION_CHECK checks for the right version of libav and FFmpeg
|
||||||
* The original source is vlc (in modules/codec/avcodec/avcommon_compat.h)
|
* The original source is vlc (in modules/codec/avcodec/avcommon_compat.h)
|
||||||
|
|
|
@ -132,29 +132,29 @@ FfmpegCamera::FfmpegCamera(
|
||||||
FFMPEGInit();
|
FFMPEGInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
mFormatContext = NULL;
|
mFormatContext = nullptr;
|
||||||
mVideoStreamId = -1;
|
mVideoStreamId = -1;
|
||||||
mAudioStreamId = -1;
|
mAudioStreamId = -1;
|
||||||
mVideoCodecContext = NULL;
|
mVideoCodecContext = nullptr;
|
||||||
mAudioCodecContext = NULL;
|
mAudioCodecContext = nullptr;
|
||||||
mVideoCodec = NULL;
|
mVideoCodec = nullptr;
|
||||||
mAudioCodec = NULL;
|
mAudioCodec = nullptr;
|
||||||
mRawFrame = NULL;
|
mRawFrame = nullptr;
|
||||||
mFrame = NULL;
|
mFrame = nullptr;
|
||||||
frameCount = 0;
|
frameCount = 0;
|
||||||
mCanCapture = false;
|
mCanCapture = false;
|
||||||
error_count = 0;
|
error_count = 0;
|
||||||
use_hwaccel = true;
|
use_hwaccel = true;
|
||||||
#if HAVE_LIBAVUTIL_HWCONTEXT_H
|
#if HAVE_LIBAVUTIL_HWCONTEXT_H
|
||||||
hwFrame = NULL;
|
hwFrame = nullptr;
|
||||||
hw_device_ctx = NULL;
|
hw_device_ctx = nullptr;
|
||||||
#if LIBAVCODEC_VERSION_CHECK(57, 89, 0, 89, 0)
|
#if LIBAVCODEC_VERSION_CHECK(57, 89, 0, 89, 0)
|
||||||
hw_pix_fmt = AV_PIX_FMT_NONE;
|
hw_pix_fmt = AV_PIX_FMT_NONE;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_LIBSWSCALE
|
#if HAVE_LIBSWSCALE
|
||||||
mConvertContext = NULL;
|
mConvertContext = nullptr;
|
||||||
#endif
|
#endif
|
||||||
/* Has to be located inside the constructor so other components such as zma
|
/* Has to be located inside the constructor so other components such as zma
|
||||||
* will receive correct colours and subpixel order */
|
* will receive correct colours and subpixel order */
|
||||||
|
@ -171,7 +171,7 @@ FfmpegCamera::FfmpegCamera(
|
||||||
Panic("Unexpected colours: %d", colours);
|
Panic("Unexpected colours: %d", colours);
|
||||||
}
|
}
|
||||||
|
|
||||||
frame_buffer = NULL;
|
frame_buffer = nullptr;
|
||||||
// sws_scale needs 32bit aligned width and an extra 16 bytes padding, so recalculate imagesize, which was width*height*bytes_per_pixel
|
// 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)
|
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||||
alignment = 32;
|
alignment = 32;
|
||||||
|
@ -255,10 +255,10 @@ int FfmpegCamera::OpenFfmpeg() {
|
||||||
|
|
||||||
// Open the input, not necessarily a file
|
// Open the input, not necessarily a file
|
||||||
#if !LIBAVFORMAT_VERSION_CHECK(53, 2, 0, 4, 0)
|
#if !LIBAVFORMAT_VERSION_CHECK(53, 2, 0, 4, 0)
|
||||||
if ( av_open_input_file(&mFormatContext, mPath.c_str(), NULL, 0, NULL) != 0 )
|
if ( av_open_input_file(&mFormatContext, mPath.c_str(), nullptr, 0, nullptr) != 0 )
|
||||||
#else
|
#else
|
||||||
// Handle options
|
// Handle options
|
||||||
AVDictionary *opts = NULL;
|
AVDictionary *opts = nullptr;
|
||||||
ret = av_dict_parse_string(&opts, Options().c_str(), "=", ",", 0);
|
ret = av_dict_parse_string(&opts, Options().c_str(), "=", ",", 0);
|
||||||
if ( ret < 0 ) {
|
if ( ret < 0 ) {
|
||||||
Warning("Could not parse ffmpeg input options '%s'", Options().c_str());
|
Warning("Could not parse ffmpeg input options '%s'", Options().c_str());
|
||||||
|
@ -296,8 +296,7 @@ int FfmpegCamera::OpenFfmpeg() {
|
||||||
mFormatContext->interrupt_callback.callback = FfmpegInterruptCallback;
|
mFormatContext->interrupt_callback.callback = FfmpegInterruptCallback;
|
||||||
mFormatContext->interrupt_callback.opaque = this;
|
mFormatContext->interrupt_callback.opaque = this;
|
||||||
|
|
||||||
ret = avformat_open_input(&mFormatContext, mPath.c_str(), NULL, &opts);
|
ret = avformat_open_input(&mFormatContext, mPath.c_str(), nullptr, &opts);
|
||||||
Debug(1, "Have %d from open_input", ret);
|
|
||||||
if ( ret != 0 )
|
if ( ret != 0 )
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
@ -308,15 +307,15 @@ int FfmpegCamera::OpenFfmpeg() {
|
||||||
#else
|
#else
|
||||||
if ( mFormatContext ) {
|
if ( mFormatContext ) {
|
||||||
avformat_close_input(&mFormatContext);
|
avformat_close_input(&mFormatContext);
|
||||||
mFormatContext = NULL;
|
mFormatContext = nullptr;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
av_dict_free(&opts);
|
av_dict_free(&opts);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
AVDictionaryEntry *e = NULL;
|
AVDictionaryEntry *e = nullptr;
|
||||||
while ( (e = av_dict_get(opts, "", e, AV_DICT_IGNORE_SUFFIX)) != NULL ) {
|
while ( (e = av_dict_get(opts, "", e, AV_DICT_IGNORE_SUFFIX)) != nullptr ) {
|
||||||
Warning("Option %s not recognized by ffmpeg", e->key);
|
Warning("Option %s not recognized by ffmpeg", e->key);
|
||||||
}
|
}
|
||||||
av_dict_free(&opts);
|
av_dict_free(&opts);
|
||||||
|
@ -325,7 +324,7 @@ int FfmpegCamera::OpenFfmpeg() {
|
||||||
#if !LIBAVFORMAT_VERSION_CHECK(53, 6, 0, 6, 0)
|
#if !LIBAVFORMAT_VERSION_CHECK(53, 6, 0, 6, 0)
|
||||||
ret = av_find_stream_info(mFormatContext);
|
ret = av_find_stream_info(mFormatContext);
|
||||||
#else
|
#else
|
||||||
ret = avformat_find_stream_info(mFormatContext, 0);
|
ret = avformat_find_stream_info(mFormatContext, nullptr);
|
||||||
#endif
|
#endif
|
||||||
if ( ret < 0 ) {
|
if ( ret < 0 ) {
|
||||||
Error("Unable to find stream info from %s due to: %s",
|
Error("Unable to find stream info from %s due to: %s",
|
||||||
|
@ -355,6 +354,7 @@ int FfmpegCamera::OpenFfmpeg() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // end foreach stream
|
} // end foreach stream
|
||||||
|
|
||||||
if ( mVideoStreamId == -1 ) {
|
if ( mVideoStreamId == -1 ) {
|
||||||
Error("Unable to locate video stream in %s", mPath.c_str());
|
Error("Unable to locate video stream in %s", mPath.c_str());
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -378,7 +378,7 @@ int FfmpegCamera::OpenFfmpeg() {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ( mVideoCodecContext->codec_id == AV_CODEC_ID_H264 ) {
|
if ( mVideoCodecContext->codec_id == AV_CODEC_ID_H264 ) {
|
||||||
if ( (mVideoCodec = avcodec_find_decoder_by_name("h264_mmal")) == NULL ) {
|
if ( (mVideoCodec = avcodec_find_decoder_by_name("h264_mmal")) == nullptr ) {
|
||||||
Debug(1, "Failed to find decoder (h264_mmal)");
|
Debug(1, "Failed to find decoder (h264_mmal)");
|
||||||
} else {
|
} else {
|
||||||
Debug(1, "Success finding decoder (h264_mmal)");
|
Debug(1, "Success finding decoder (h264_mmal)");
|
||||||
|
@ -444,7 +444,7 @@ int FfmpegCamera::OpenFfmpeg() {
|
||||||
hw_pix_fmt, av_get_pix_fmt_name(hw_pix_fmt));
|
hw_pix_fmt, av_get_pix_fmt_name(hw_pix_fmt));
|
||||||
|
|
||||||
ret = av_hwdevice_ctx_create(&hw_device_ctx, type,
|
ret = av_hwdevice_ctx_create(&hw_device_ctx, type,
|
||||||
(hwaccel_device != "" ? hwaccel_device.c_str(): NULL), NULL, 0);
|
(hwaccel_device != "" ? hwaccel_device.c_str(): nullptr), nullptr, 0);
|
||||||
if ( ret < 0 ) {
|
if ( ret < 0 ) {
|
||||||
Error("Failed to create hwaccel device. %s",av_make_error_string(ret).c_str());
|
Error("Failed to create hwaccel device. %s",av_make_error_string(ret).c_str());
|
||||||
hw_pix_fmt = AV_PIX_FMT_NONE;
|
hw_pix_fmt = AV_PIX_FMT_NONE;
|
||||||
|
@ -470,8 +470,8 @@ int FfmpegCamera::OpenFfmpeg() {
|
||||||
#else
|
#else
|
||||||
ret = avcodec_open2(mVideoCodecContext, mVideoCodec, &opts);
|
ret = avcodec_open2(mVideoCodecContext, mVideoCodec, &opts);
|
||||||
#endif
|
#endif
|
||||||
e = NULL;
|
e = nullptr;
|
||||||
while ( (e = av_dict_get(opts, "", e, AV_DICT_IGNORE_SUFFIX)) != NULL ) {
|
while ( (e = av_dict_get(opts, "", e, AV_DICT_IGNORE_SUFFIX)) != nullptr ) {
|
||||||
Warning("Option %s not recognized by ffmpeg", e->key);
|
Warning("Option %s not recognized by ffmpeg", e->key);
|
||||||
}
|
}
|
||||||
if ( ret < 0 ) {
|
if ( ret < 0 ) {
|
||||||
|
@ -490,7 +490,7 @@ int FfmpegCamera::OpenFfmpeg() {
|
||||||
#else
|
#else
|
||||||
mFormatContext->streams[mAudioStreamId]->codec->codec_id
|
mFormatContext->streams[mAudioStreamId]->codec->codec_id
|
||||||
#endif
|
#endif
|
||||||
)) == NULL ) {
|
)) == nullptr ) {
|
||||||
Debug(1, "Can't find codec for audio stream from %s", mPath.c_str());
|
Debug(1, "Can't find codec for audio stream from %s", mPath.c_str());
|
||||||
} else {
|
} else {
|
||||||
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
||||||
|
@ -509,7 +509,7 @@ int FfmpegCamera::OpenFfmpeg() {
|
||||||
#if !LIBAVFORMAT_VERSION_CHECK(53, 8, 0, 8, 0)
|
#if !LIBAVFORMAT_VERSION_CHECK(53, 8, 0, 8, 0)
|
||||||
if ( avcodec_open(mAudioCodecContext, mAudioCodec) < 0 )
|
if ( avcodec_open(mAudioCodecContext, mAudioCodec) < 0 )
|
||||||
#else
|
#else
|
||||||
if ( avcodec_open2(mAudioCodecContext, mAudioCodec, 0) < 0 )
|
if ( avcodec_open2(mAudioCodecContext, mAudioCodec, nullptr) < 0 )
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
Error("Unable to open codec for audio stream from %s", mPath.c_str());
|
Error("Unable to open codec for audio stream from %s", mPath.c_str());
|
||||||
|
@ -537,16 +537,16 @@ int FfmpegCamera::Close() {
|
||||||
|
|
||||||
if ( mFrame ) {
|
if ( mFrame ) {
|
||||||
av_frame_free(&mFrame);
|
av_frame_free(&mFrame);
|
||||||
mFrame = NULL;
|
mFrame = nullptr;
|
||||||
}
|
}
|
||||||
if ( mRawFrame ) {
|
if ( mRawFrame ) {
|
||||||
av_frame_free(&mRawFrame);
|
av_frame_free(&mRawFrame);
|
||||||
mRawFrame = NULL;
|
mRawFrame = nullptr;
|
||||||
}
|
}
|
||||||
#if HAVE_LIBAVUTIL_HWCONTEXT_H
|
#if HAVE_LIBAVUTIL_HWCONTEXT_H
|
||||||
if ( hwFrame ) {
|
if ( hwFrame ) {
|
||||||
av_frame_free(&hwFrame);
|
av_frame_free(&hwFrame);
|
||||||
hwFrame = NULL;
|
hwFrame = nullptr;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -555,14 +555,14 @@ int FfmpegCamera::Close() {
|
||||||
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
||||||
// avcodec_free_context(&mVideoCodecContext);
|
// avcodec_free_context(&mVideoCodecContext);
|
||||||
#endif
|
#endif
|
||||||
mVideoCodecContext = NULL; // Freed by av_close_input_file
|
mVideoCodecContext = nullptr; // Freed by av_close_input_file
|
||||||
}
|
}
|
||||||
if ( mAudioCodecContext ) {
|
if ( mAudioCodecContext ) {
|
||||||
avcodec_close(mAudioCodecContext);
|
avcodec_close(mAudioCodecContext);
|
||||||
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
||||||
avcodec_free_context(&mAudioCodecContext);
|
avcodec_free_context(&mAudioCodecContext);
|
||||||
#endif
|
#endif
|
||||||
mAudioCodecContext = NULL; // Freed by av_close_input_file
|
mAudioCodecContext = nullptr; // Freed by av_close_input_file
|
||||||
}
|
}
|
||||||
|
|
||||||
#if HAVE_LIBAVUTIL_HWCONTEXT_H
|
#if HAVE_LIBAVUTIL_HWCONTEXT_H
|
||||||
|
@ -577,7 +577,7 @@ int FfmpegCamera::Close() {
|
||||||
#else
|
#else
|
||||||
avformat_close_input(&mFormatContext);
|
avformat_close_input(&mFormatContext);
|
||||||
#endif
|
#endif
|
||||||
mFormatContext = NULL;
|
mFormatContext = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -593,7 +593,7 @@ int FfmpegCamera::transfer_to_image(
|
||||||
|
|
||||||
/* Request a writeable buffer of the target image */
|
/* Request a writeable buffer of the target image */
|
||||||
image_buffer = image.WriteBuffer(width, height, colours, subpixelorder);
|
image_buffer = image.WriteBuffer(width, height, colours, subpixelorder);
|
||||||
if ( image_buffer == NULL ) {
|
if ( image_buffer == nullptr ) {
|
||||||
Error("Failed requesting writeable buffer for the captured image.");
|
Error("Failed requesting writeable buffer for the captured image.");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -630,9 +630,9 @@ int FfmpegCamera::transfer_to_image(
|
||||||
input_frame->height,
|
input_frame->height,
|
||||||
(AVPixelFormat)input_frame->format,
|
(AVPixelFormat)input_frame->format,
|
||||||
width, height,
|
width, height,
|
||||||
imagePixFormat, SWS_BICUBIC, NULL,
|
imagePixFormat, SWS_BICUBIC, nullptr,
|
||||||
NULL, NULL);
|
nullptr, nullptr);
|
||||||
if ( mConvertContext == NULL ) {
|
if ( mConvertContext == nullptr ) {
|
||||||
Error("Unable to create conversion context for %s from %s to %s",
|
Error("Unable to create conversion context for %s from %s to %s",
|
||||||
mPath.c_str(),
|
mPath.c_str(),
|
||||||
av_get_pix_fmt_name((AVPixelFormat)input_frame->format),
|
av_get_pix_fmt_name((AVPixelFormat)input_frame->format),
|
||||||
|
|
|
@ -62,7 +62,7 @@ class FfmpegCamera : public Camera {
|
||||||
AVFrame *hwFrame; // Will also be used to indicate if hwaccel is in use
|
AVFrame *hwFrame; // Will also be used to indicate if hwaccel is in use
|
||||||
bool use_hwaccel; //will default to on if hwaccel specified, will get turned off if there is a failure
|
bool use_hwaccel; //will default to on if hwaccel specified, will get turned off if there is a failure
|
||||||
#if HAVE_LIBAVUTIL_HWCONTEXT_H
|
#if HAVE_LIBAVUTIL_HWCONTEXT_H
|
||||||
AVBufferRef *hw_device_ctx = NULL;
|
AVBufferRef *hw_device_ctx = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Used to store the incoming packet, it will get copied when queued.
|
// Used to store the incoming packet, it will get copied when queued.
|
||||||
|
|
|
@ -4,12 +4,12 @@
|
||||||
#include "zm_ffmpeg.h"
|
#include "zm_ffmpeg.h"
|
||||||
|
|
||||||
FFmpeg_Input::FFmpeg_Input() {
|
FFmpeg_Input::FFmpeg_Input() {
|
||||||
input_format_context = NULL;
|
input_format_context = nullptr;
|
||||||
video_stream_id = -1;
|
video_stream_id = -1;
|
||||||
audio_stream_id = -1;
|
audio_stream_id = -1;
|
||||||
FFMPEGInit();
|
FFMPEGInit();
|
||||||
streams = NULL;
|
streams = nullptr;
|
||||||
frame = NULL;
|
frame = nullptr;
|
||||||
last_seek_request = -1;
|
last_seek_request = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,14 +20,14 @@ FFmpeg_Input::~FFmpeg_Input() {
|
||||||
if ( streams ) {
|
if ( streams ) {
|
||||||
for ( unsigned int i = 0; i < input_format_context->nb_streams; i += 1 ) {
|
for ( unsigned int i = 0; i < input_format_context->nb_streams; i += 1 ) {
|
||||||
avcodec_close(streams[i].context);
|
avcodec_close(streams[i].context);
|
||||||
streams[i].context = NULL;
|
streams[i].context = nullptr;
|
||||||
}
|
}
|
||||||
delete[] streams;
|
delete[] streams;
|
||||||
streams = NULL;
|
streams = nullptr;
|
||||||
}
|
}
|
||||||
if ( frame ) {
|
if ( frame ) {
|
||||||
av_frame_free(&frame);
|
av_frame_free(&frame);
|
||||||
frame = NULL;
|
frame = nullptr;
|
||||||
}
|
}
|
||||||
if ( input_format_context ) {
|
if ( input_format_context ) {
|
||||||
#if !LIBAVFORMAT_VERSION_CHECK(53, 17, 0, 25, 0)
|
#if !LIBAVFORMAT_VERSION_CHECK(53, 17, 0, 25, 0)
|
||||||
|
@ -35,7 +35,7 @@ FFmpeg_Input::~FFmpeg_Input() {
|
||||||
#else
|
#else
|
||||||
avformat_close_input(&input_format_context);
|
avformat_close_input(&input_format_context);
|
||||||
#endif
|
#endif
|
||||||
input_format_context = NULL;
|
input_format_context = nullptr;
|
||||||
}
|
}
|
||||||
} // end ~FFmpeg_Input()
|
} // end ~FFmpeg_Input()
|
||||||
|
|
||||||
|
@ -58,16 +58,16 @@ int FFmpeg_Input::Open(const char *filepath) {
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
/** Open the input file to read from it. */
|
/** Open the input file to read from it. */
|
||||||
error = avformat_open_input(&input_format_context, filepath, NULL, NULL);
|
error = avformat_open_input(&input_format_context, filepath, nullptr, nullptr);
|
||||||
if ( error < 0 ) {
|
if ( error < 0 ) {
|
||||||
Error("Could not open input file '%s' (error '%s')",
|
Error("Could not open input file '%s' (error '%s')",
|
||||||
filepath, av_make_error_string(error).c_str());
|
filepath, av_make_error_string(error).c_str());
|
||||||
input_format_context = NULL;
|
input_format_context = nullptr;
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get information on the input file (number of streams etc.). */
|
/** Get information on the input file (number of streams etc.). */
|
||||||
if ( (error = avformat_find_stream_info(input_format_context, NULL)) < 0 ) {
|
if ( (error = avformat_find_stream_info(input_format_context, nullptr)) < 0 ) {
|
||||||
Error(
|
Error(
|
||||||
"Could not open find stream info (error '%s')",
|
"Could not open find stream info (error '%s')",
|
||||||
av_make_error_string(error).c_str()
|
av_make_error_string(error).c_str()
|
||||||
|
@ -101,7 +101,7 @@ int FFmpeg_Input::Open(const char *filepath) {
|
||||||
|
|
||||||
streams[i].frame_count = 0;
|
streams[i].frame_count = 0;
|
||||||
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
||||||
streams[i].context = avcodec_alloc_context3(NULL);
|
streams[i].context = avcodec_alloc_context3(nullptr);
|
||||||
avcodec_parameters_to_context(streams[i].context, input_format_context->streams[i]->codecpar);
|
avcodec_parameters_to_context(streams[i].context, input_format_context->streams[i]->codecpar);
|
||||||
#else
|
#else
|
||||||
streams[i].context = input_format_context->streams[i]->codec;
|
streams[i].context = input_format_context->streams[i]->codec;
|
||||||
|
@ -115,7 +115,7 @@ int FFmpeg_Input::Open(const char *filepath) {
|
||||||
Debug(1, "Using codec (%s) for stream %d", streams[i].codec->name, i);
|
Debug(1, "Using codec (%s) for stream %d", streams[i].codec->name, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
error = avcodec_open2(streams[i].context, streams[i].codec, NULL);
|
error = avcodec_open2(streams[i].context, streams[i].codec, nullptr);
|
||||||
if ( error < 0 ) {
|
if ( error < 0 ) {
|
||||||
Error("Could not open input codec (error '%s')",
|
Error("Could not open input codec (error '%s')",
|
||||||
av_make_error_string(error).c_str());
|
av_make_error_string(error).c_str());
|
||||||
|
@ -123,7 +123,7 @@ int FFmpeg_Input::Open(const char *filepath) {
|
||||||
avcodec_free_context(&streams[i].context);
|
avcodec_free_context(&streams[i].context);
|
||||||
#endif
|
#endif
|
||||||
avformat_close_input(&input_format_context);
|
avformat_close_input(&input_format_context);
|
||||||
input_format_context = NULL;
|
input_format_context = nullptr;
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
} // end foreach stream
|
} // end foreach stream
|
||||||
|
@ -174,11 +174,11 @@ AVFrame *FFmpeg_Input::get_frame(int stream_id) {
|
||||||
(ret == -110)
|
(ret == -110)
|
||||||
) {
|
) {
|
||||||
Info("av_read_frame returned %s.", av_make_error_string(ret).c_str());
|
Info("av_read_frame returned %s.", av_make_error_string(ret).c_str());
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
Error("Unable to read packet from stream %d: error %d \"%s\".",
|
Error("Unable to read packet from stream %d: error %d \"%s\".",
|
||||||
packet.stream_index, ret, av_make_error_string(ret).c_str());
|
packet.stream_index, ret, av_make_error_string(ret).c_str());
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
dumpPacket(input_format_context->streams[packet.stream_index], &packet, "Received packet");
|
dumpPacket(input_format_context->streams[packet.stream_index], &packet, "Received packet");
|
||||||
|
|
||||||
|
@ -233,7 +233,7 @@ AVFrame *FFmpeg_Input::get_frame(int stream_id, double at) {
|
||||||
ret = av_seek_frame(input_format_context, stream_id, seek_target, AVSEEK_FLAG_FRAME);
|
ret = av_seek_frame(input_format_context, stream_id, seek_target, AVSEEK_FLAG_FRAME);
|
||||||
if ( ret < 0 ) {
|
if ( ret < 0 ) {
|
||||||
Error("Unable to seek in stream");
|
Error("Unable to seek in stream");
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
// Have to grab a frame to update our current frame to know where we are
|
// Have to grab a frame to update our current frame to know where we are
|
||||||
get_frame(stream_id);
|
get_frame(stream_id);
|
||||||
|
@ -241,7 +241,7 @@ AVFrame *FFmpeg_Input::get_frame(int stream_id, double at) {
|
||||||
|
|
||||||
if ( !frame ) {
|
if ( !frame ) {
|
||||||
Warning("Unable to get frame.");
|
Warning("Unable to get frame.");
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
@ -257,7 +257,7 @@ AVFrame *FFmpeg_Input::get_frame(int stream_id, double at) {
|
||||||
AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_FRAME
|
AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_FRAME
|
||||||
) < 0 ) ) {
|
) < 0 ) ) {
|
||||||
Error("Unable to seek in stream");
|
Error("Unable to seek in stream");
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
// Have to grab a frame to update our current frame to know where we are
|
// Have to grab a frame to update our current frame to know where we are
|
||||||
get_frame(stream_id);
|
get_frame(stream_id);
|
||||||
|
|
|
@ -30,13 +30,13 @@
|
||||||
#include "zm_fifo.h"
|
#include "zm_fifo.h"
|
||||||
#define RAW_BUFFER 512
|
#define RAW_BUFFER 512
|
||||||
static bool zm_fifodbg_inited = false;
|
static bool zm_fifodbg_inited = false;
|
||||||
FILE *zm_fifodbg_log_fd = 0;
|
FILE *zm_fifodbg_log_fd = nullptr;
|
||||||
char zm_fifodbg_log[PATH_MAX] = "";
|
char zm_fifodbg_log[PATH_MAX] = "";
|
||||||
|
|
||||||
static bool zmFifoDbgOpen() {
|
static bool zmFifoDbgOpen() {
|
||||||
if ( zm_fifodbg_log_fd )
|
if ( zm_fifodbg_log_fd )
|
||||||
fclose(zm_fifodbg_log_fd);
|
fclose(zm_fifodbg_log_fd);
|
||||||
zm_fifodbg_log_fd = NULL;
|
zm_fifodbg_log_fd = nullptr;
|
||||||
signal(SIGPIPE, SIG_IGN);
|
signal(SIGPIPE, SIG_IGN);
|
||||||
FifoStream::fifo_create_if_missing(zm_fifodbg_log);
|
FifoStream::fifo_create_if_missing(zm_fifodbg_log);
|
||||||
int fd = open(zm_fifodbg_log, O_WRONLY|O_NONBLOCK|O_TRUNC);
|
int fd = open(zm_fifodbg_log, O_WRONLY|O_NONBLOCK|O_TRUNC);
|
||||||
|
@ -48,7 +48,7 @@ static bool zmFifoDbgOpen() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
zm_fifodbg_log_fd = fdopen(fd, "wb");
|
zm_fifodbg_log_fd = fdopen(fd, "wb");
|
||||||
if ( zm_fifodbg_log_fd == NULL ) {
|
if ( zm_fifodbg_log_fd == nullptr ) {
|
||||||
close(fd);
|
close(fd);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ void zmFifoDbgOutput(
|
||||||
int res = fwrite(dbg_string, dbg_ptr-dbg_string, 1, zm_fifodbg_log_fd);
|
int res = fwrite(dbg_string, dbg_ptr-dbg_string, 1, zm_fifodbg_log_fd);
|
||||||
if ( res != 1 ) {
|
if ( res != 1 ) {
|
||||||
fclose(zm_fifodbg_log_fd);
|
fclose(zm_fifodbg_log_fd);
|
||||||
zm_fifodbg_log_fd = NULL;
|
zm_fifodbg_log_fd = nullptr;
|
||||||
} else {
|
} else {
|
||||||
fflush(zm_fifodbg_log_fd);
|
fflush(zm_fifodbg_log_fd);
|
||||||
}
|
}
|
||||||
|
@ -249,7 +249,7 @@ void FifoStream::runStream() {
|
||||||
}
|
}
|
||||||
|
|
||||||
while ( !zm_terminate ) {
|
while ( !zm_terminate ) {
|
||||||
gettimeofday(&now, NULL);
|
gettimeofday(&now, nullptr);
|
||||||
checkCommandQueue();
|
checkCommandQueue();
|
||||||
if ( stream_type == MJPEG ) {
|
if ( stream_type == MJPEG ) {
|
||||||
if ( !sendMJEGFrames() )
|
if ( !sendMJEGFrames() )
|
||||||
|
|
|
@ -88,7 +88,7 @@ int FileCamera::PreCapture() {
|
||||||
// This waits until 1 second has passed since it was modified. Effectively limiting fps to 60.
|
// This waits until 1 second has passed since it was modified. Effectively limiting fps to 60.
|
||||||
// Which is kinda bogus. If we were writing to this jpg constantly faster than we are monitoring it here
|
// Which is kinda bogus. If we were writing to this jpg constantly faster than we are monitoring it here
|
||||||
// we would never break out of this loop
|
// we would never break out of this loop
|
||||||
while ( (time(0) - statbuf.st_mtime) < 1 ) {
|
while ( (time(nullptr) - statbuf.st_mtime) < 1 ) {
|
||||||
usleep(100000);
|
usleep(100000);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -48,12 +48,12 @@ static short *g_v_table;
|
||||||
static short *g_u_table;
|
static short *g_u_table;
|
||||||
static short *b_u_table;
|
static short *b_u_table;
|
||||||
|
|
||||||
struct SwsContext *sws_convert_context = NULL;
|
struct SwsContext *sws_convert_context = nullptr;
|
||||||
|
|
||||||
jpeg_compress_struct *Image::writejpg_ccinfo[101] = { 0 };
|
jpeg_compress_struct *Image::writejpg_ccinfo[101] = { };
|
||||||
jpeg_compress_struct *Image::encodejpg_ccinfo[101] = { 0 };
|
jpeg_compress_struct *Image::encodejpg_ccinfo[101] = { };
|
||||||
jpeg_decompress_struct *Image::readjpg_dcinfo = 0;
|
jpeg_decompress_struct *Image::readjpg_dcinfo = nullptr;
|
||||||
jpeg_decompress_struct *Image::decodejpg_dcinfo = 0;
|
jpeg_decompress_struct *Image::decodejpg_dcinfo = nullptr;
|
||||||
struct zm_error_mgr Image::jpg_err;
|
struct zm_error_mgr Image::jpg_err;
|
||||||
|
|
||||||
/* Pointer to blend function. */
|
/* Pointer to blend function. */
|
||||||
|
@ -152,7 +152,7 @@ Image::Image(int p_width, int p_height, int p_colours, int p_subpixelorder, uint
|
||||||
padding = p_padding;
|
padding = p_padding;
|
||||||
subpixelorder = p_subpixelorder;
|
subpixelorder = p_subpixelorder;
|
||||||
size = linesize*height + padding;
|
size = linesize*height + padding;
|
||||||
buffer = 0;
|
buffer = nullptr;
|
||||||
holdbuffer = 0;
|
holdbuffer = 0;
|
||||||
if ( p_buffer ) {
|
if ( p_buffer ) {
|
||||||
allocation = size;
|
allocation = size;
|
||||||
|
@ -177,7 +177,7 @@ Image::Image(int p_width, int p_linesize, int p_height, int p_colours, int p_sub
|
||||||
padding = p_padding;
|
padding = p_padding;
|
||||||
subpixelorder = p_subpixelorder;
|
subpixelorder = p_subpixelorder;
|
||||||
size = linesize*height + padding;
|
size = linesize*height + padding;
|
||||||
buffer = 0;
|
buffer = nullptr;
|
||||||
holdbuffer = 0;
|
holdbuffer = 0;
|
||||||
if ( p_buffer ) {
|
if ( p_buffer ) {
|
||||||
allocation = size;
|
allocation = size;
|
||||||
|
@ -210,7 +210,7 @@ Image::Image(const AVFrame *frame) {
|
||||||
size = avpicture_get_size(AV_PIX_FMT_RGBA, width, height);
|
size = avpicture_get_size(AV_PIX_FMT_RGBA, width, height);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
buffer = 0;
|
buffer = nullptr;
|
||||||
holdbuffer = 0;
|
holdbuffer = 0;
|
||||||
AllocImgBuffer(size);
|
AllocImgBuffer(size);
|
||||||
this->Assign(frame);
|
this->Assign(frame);
|
||||||
|
@ -237,9 +237,9 @@ void Image::Assign(const AVFrame *frame) {
|
||||||
height,
|
height,
|
||||||
(AVPixelFormat)frame->format,
|
(AVPixelFormat)frame->format,
|
||||||
width, height,
|
width, height,
|
||||||
format, SWS_BICUBIC, NULL,
|
format, SWS_BICUBIC, nullptr,
|
||||||
NULL, NULL);
|
nullptr, nullptr);
|
||||||
if ( sws_convert_context == NULL )
|
if ( sws_convert_context == nullptr )
|
||||||
Fatal("Unable to create conversion context");
|
Fatal("Unable to create conversion context");
|
||||||
|
|
||||||
if ( sws_scale(sws_convert_context, frame->data, frame->linesize, 0, frame->height,
|
if ( sws_scale(sws_convert_context, frame->data, frame->linesize, 0, frame->height,
|
||||||
|
@ -262,7 +262,7 @@ Image::Image(const Image &p_image) {
|
||||||
colours = p_image.colours;
|
colours = p_image.colours;
|
||||||
subpixelorder = p_image.subpixelorder;
|
subpixelorder = p_image.subpixelorder;
|
||||||
size = p_image.size; // allocation is set in AllocImgBuffer
|
size = p_image.size; // allocation is set in AllocImgBuffer
|
||||||
buffer = 0;
|
buffer = nullptr;
|
||||||
holdbuffer = 0;
|
holdbuffer = 0;
|
||||||
AllocImgBuffer(size);
|
AllocImgBuffer(size);
|
||||||
(*fptr_imgbufcpy)(buffer, p_image.buffer, size);
|
(*fptr_imgbufcpy)(buffer, p_image.buffer, size);
|
||||||
|
@ -281,24 +281,24 @@ void Image::Deinitialise() {
|
||||||
if ( readjpg_dcinfo ) {
|
if ( readjpg_dcinfo ) {
|
||||||
jpeg_destroy_decompress(readjpg_dcinfo);
|
jpeg_destroy_decompress(readjpg_dcinfo);
|
||||||
delete readjpg_dcinfo;
|
delete readjpg_dcinfo;
|
||||||
readjpg_dcinfo = NULL;
|
readjpg_dcinfo = nullptr;
|
||||||
}
|
}
|
||||||
if ( decodejpg_dcinfo ) {
|
if ( decodejpg_dcinfo ) {
|
||||||
jpeg_destroy_decompress(decodejpg_dcinfo);
|
jpeg_destroy_decompress(decodejpg_dcinfo);
|
||||||
delete decodejpg_dcinfo;
|
delete decodejpg_dcinfo;
|
||||||
decodejpg_dcinfo = NULL;
|
decodejpg_dcinfo = nullptr;
|
||||||
}
|
}
|
||||||
for ( unsigned int quality=0; quality <= 100; quality += 1 ) {
|
for ( unsigned int quality=0; quality <= 100; quality += 1 ) {
|
||||||
if ( writejpg_ccinfo[quality] ) {
|
if ( writejpg_ccinfo[quality] ) {
|
||||||
jpeg_destroy_compress(writejpg_ccinfo[quality]);
|
jpeg_destroy_compress(writejpg_ccinfo[quality]);
|
||||||
delete writejpg_ccinfo[quality];
|
delete writejpg_ccinfo[quality];
|
||||||
writejpg_ccinfo[quality] = NULL;
|
writejpg_ccinfo[quality] = nullptr;
|
||||||
}
|
}
|
||||||
} // end foreach quality
|
} // end foreach quality
|
||||||
|
|
||||||
if ( sws_convert_context ) {
|
if ( sws_convert_context ) {
|
||||||
sws_freeContext(sws_convert_context);
|
sws_freeContext(sws_convert_context);
|
||||||
sws_convert_context = NULL;
|
sws_convert_context = nullptr;
|
||||||
}
|
}
|
||||||
} // end void Image::Deinitialise()
|
} // end void Image::Deinitialise()
|
||||||
|
|
||||||
|
@ -509,25 +509,25 @@ uint8_t* Image::WriteBuffer(
|
||||||
&&
|
&&
|
||||||
p_colours != ZM_COLOUR_RGB32 ) {
|
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;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! ( p_height > 0 && p_width > 0 ) ) {
|
if ( ! ( p_height > 0 && p_width > 0 ) ) {
|
||||||
Error("WriteBuffer called with invalid width or height: %d %d", p_width, p_height);
|
Error("WriteBuffer called with invalid width or height: %d %d", p_width, p_height);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( p_width != width || p_height != height || p_colours != colours || p_subpixelorder != subpixelorder ) {
|
if ( p_width != width || p_height != height || p_colours != colours || p_subpixelorder != subpixelorder ) {
|
||||||
|
|
||||||
unsigned int newsize = (p_width * p_height) * p_colours;
|
unsigned int newsize = (p_width * p_height) * p_colours;
|
||||||
|
|
||||||
if ( buffer == NULL ) {
|
if ( buffer == nullptr ) {
|
||||||
AllocImgBuffer(newsize);
|
AllocImgBuffer(newsize);
|
||||||
} else {
|
} else {
|
||||||
if ( allocation < newsize ) {
|
if ( allocation < newsize ) {
|
||||||
if ( holdbuffer ) {
|
if ( holdbuffer ) {
|
||||||
Error("Held buffer is undersized for requested buffer");
|
Error("Held buffer is undersized for requested buffer");
|
||||||
return NULL;
|
return nullptr;
|
||||||
} else {
|
} else {
|
||||||
/* Replace buffer with a bigger one */
|
/* Replace buffer with a bigger one */
|
||||||
//DumpImgBuffer(); // Done in AllocImgBuffer too
|
//DumpImgBuffer(); // Done in AllocImgBuffer too
|
||||||
|
@ -560,7 +560,7 @@ void Image::AssignDirect(
|
||||||
const size_t buffer_size,
|
const size_t buffer_size,
|
||||||
const int p_buffertype) {
|
const int p_buffertype) {
|
||||||
|
|
||||||
if ( new_buffer == NULL ) {
|
if ( new_buffer == nullptr ) {
|
||||||
Error("Attempt to directly assign buffer from a NULL pointer");
|
Error("Attempt to directly assign buffer from a NULL pointer");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -631,7 +631,7 @@ void Image::Assign(
|
||||||
const size_t buffer_size) {
|
const size_t buffer_size) {
|
||||||
unsigned int new_size = (p_width * p_height) * p_colours;
|
unsigned int new_size = (p_width * p_height) * p_colours;
|
||||||
|
|
||||||
if ( new_buffer == NULL ) {
|
if ( new_buffer == nullptr ) {
|
||||||
Error("Attempt to assign buffer from a NULL pointer");
|
Error("Attempt to assign buffer from a NULL pointer");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -681,7 +681,7 @@ void Image::Assign(
|
||||||
void Image::Assign(const Image &image) {
|
void Image::Assign(const Image &image) {
|
||||||
unsigned int new_size = image.height * image.linesize;
|
unsigned int new_size = image.height * image.linesize;
|
||||||
|
|
||||||
if ( image.buffer == NULL ) {
|
if ( image.buffer == nullptr ) {
|
||||||
Error("Attempt to assign image with an empty buffer");
|
Error("Attempt to assign image with an empty buffer");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -820,7 +820,7 @@ Image *Image::HighlightEdges(
|
||||||
|
|
||||||
bool Image::ReadRaw(const char *filename) {
|
bool Image::ReadRaw(const char *filename) {
|
||||||
FILE *infile;
|
FILE *infile;
|
||||||
if ( (infile = fopen(filename, "rb")) == NULL ) {
|
if ( (infile = fopen(filename, "rb")) == nullptr ) {
|
||||||
Error("Can't open %s: %s", filename, strerror(errno));
|
Error("Can't open %s: %s", filename, strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -851,7 +851,7 @@ bool Image::ReadRaw(const char *filename) {
|
||||||
|
|
||||||
bool Image::WriteRaw(const char *filename) const {
|
bool Image::WriteRaw(const char *filename) const {
|
||||||
FILE *outfile;
|
FILE *outfile;
|
||||||
if ( (outfile = fopen(filename, "wb")) == NULL ) {
|
if ( (outfile = fopen(filename, "wb")) == nullptr ) {
|
||||||
Error("Can't open %s: %s", filename, strerror(errno));
|
Error("Can't open %s: %s", filename, strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -880,7 +880,7 @@ bool Image::ReadJpeg(const char *filename, unsigned int p_colours, unsigned int
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *infile;
|
FILE *infile;
|
||||||
if ( (infile = fopen(filename, "rb")) == NULL ) {
|
if ( (infile = fopen(filename, "rb")) == nullptr ) {
|
||||||
Error("Can't open %s: %s", filename, strerror(errno));
|
Error("Can't open %s: %s", filename, strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -904,7 +904,7 @@ bool Image::ReadJpeg(const char *filename, unsigned int p_colours, unsigned int
|
||||||
|
|
||||||
/* Check if the image has at least one huffman table defined. If not, use the standard ones */
|
/* Check if the image has at least one huffman table defined. If not, use the standard ones */
|
||||||
/* This is required for the MJPEG capture palette of USB devices */
|
/* This is required for the MJPEG capture palette of USB devices */
|
||||||
if ( cinfo->dc_huff_tbl_ptrs[0] == NULL ) {
|
if ( cinfo->dc_huff_tbl_ptrs[0] == nullptr ) {
|
||||||
zm_use_std_huff_tables(cinfo);
|
zm_use_std_huff_tables(cinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -969,7 +969,7 @@ cinfo->out_color_space = JCS_RGB;
|
||||||
break;
|
break;
|
||||||
} // end switch p_colours
|
} // end switch p_colours
|
||||||
|
|
||||||
if ( WriteBuffer(new_width, new_height, new_colours, new_subpixelorder) == NULL ) {
|
if ( WriteBuffer(new_width, new_height, new_colours, new_subpixelorder) == nullptr ) {
|
||||||
Error("Failed requesting writeable buffer for reading JPEG image.");
|
Error("Failed requesting writeable buffer for reading JPEG image.");
|
||||||
jpeg_abort_decompress(cinfo);
|
jpeg_abort_decompress(cinfo);
|
||||||
fclose(infile);
|
fclose(infile);
|
||||||
|
@ -1020,7 +1020,7 @@ bool Image::WriteJpeg(const char *filename, int quality_override, struct timeval
|
||||||
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];
|
struct jpeg_compress_struct *cinfo = writejpg_ccinfo[quality];
|
||||||
FILE *outfile = NULL;
|
FILE *outfile = nullptr;
|
||||||
static int raw_fd = 0;
|
static int raw_fd = 0;
|
||||||
raw_fd = 0;
|
raw_fd = 0;
|
||||||
|
|
||||||
|
@ -1037,7 +1037,7 @@ bool Image::WriteJpeg(const char *filename, int quality_override, struct timeval
|
||||||
jpg_err.pub.emit_message = zm_jpeg_emit_silence;
|
jpg_err.pub.emit_message = zm_jpeg_emit_silence;
|
||||||
if ( setjmp(jpg_err.setjmp_buffer) ) {
|
if ( setjmp(jpg_err.setjmp_buffer) ) {
|
||||||
jpeg_abort_compress(cinfo);
|
jpeg_abort_compress(cinfo);
|
||||||
Debug(1, "Aborted a write mid-stream and %s and %d", (outfile == NULL) ? "closing file" : "file not opened", raw_fd);
|
Debug(1, "Aborted a write mid-stream and %s and %d", (outfile == nullptr) ? "closing file" : "file not opened", raw_fd);
|
||||||
if ( raw_fd )
|
if ( raw_fd )
|
||||||
close(raw_fd);
|
close(raw_fd);
|
||||||
if ( outfile )
|
if ( outfile )
|
||||||
|
@ -1047,7 +1047,7 @@ bool Image::WriteJpeg(const char *filename, int quality_override, struct timeval
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !on_blocking_abort ) {
|
if ( !on_blocking_abort ) {
|
||||||
if ( (outfile = fopen(filename, "wb")) == NULL ) {
|
if ( (outfile = fopen(filename, "wb")) == nullptr ) {
|
||||||
Error("Can't open %s for writing: %s", filename, strerror(errno));
|
Error("Can't open %s for writing: %s", filename, strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1056,7 +1056,7 @@ bool Image::WriteJpeg(const char *filename, int quality_override, struct timeval
|
||||||
if ( raw_fd < 0 )
|
if ( raw_fd < 0 )
|
||||||
return false;
|
return false;
|
||||||
outfile = fdopen(raw_fd, "wb");
|
outfile = fdopen(raw_fd, "wb");
|
||||||
if ( outfile == NULL ) {
|
if ( outfile == nullptr ) {
|
||||||
close(raw_fd);
|
close(raw_fd);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1199,7 +1199,7 @@ bool Image::DecodeJpeg(
|
||||||
|
|
||||||
/* Check if the image has at least one huffman table defined. If not, use the standard ones */
|
/* Check if the image has at least one huffman table defined. If not, use the standard ones */
|
||||||
/* This is required for the MJPEG capture palette of USB devices */
|
/* This is required for the MJPEG capture palette of USB devices */
|
||||||
if ( cinfo->dc_huff_tbl_ptrs[0] == NULL ) {
|
if ( cinfo->dc_huff_tbl_ptrs[0] == nullptr ) {
|
||||||
zm_use_std_huff_tables(cinfo);
|
zm_use_std_huff_tables(cinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1265,7 +1265,7 @@ cinfo->out_color_space = JCS_RGB;
|
||||||
break;
|
break;
|
||||||
} // end switch
|
} // end switch
|
||||||
|
|
||||||
if ( WriteBuffer(new_width, new_height, new_colours, new_subpixelorder) == NULL ) {
|
if ( WriteBuffer(new_width, new_height, new_colours, new_subpixelorder) == nullptr ) {
|
||||||
Error("Failed requesting writeable buffer for reading JPEG image.");
|
Error("Failed requesting writeable buffer for reading JPEG image.");
|
||||||
jpeg_abort_decompress(cinfo);
|
jpeg_abort_decompress(cinfo);
|
||||||
return false;
|
return false;
|
||||||
|
@ -1808,7 +1808,7 @@ void Image::Delta(const Image &image, Image* targetimage) const {
|
||||||
|
|
||||||
uint8_t *pdiff = targetimage->WriteBuffer(width, height, ZM_COLOUR_GRAY8, ZM_SUBPIX_ORDER_NONE);
|
uint8_t *pdiff = targetimage->WriteBuffer(width, height, ZM_COLOUR_GRAY8, ZM_SUBPIX_ORDER_NONE);
|
||||||
|
|
||||||
if ( pdiff == NULL ) {
|
if ( pdiff == nullptr ) {
|
||||||
Panic("Failed requesting writeable buffer for storing the delta image");
|
Panic("Failed requesting writeable buffer for storing the delta image");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ extern imgbufcpy_fptr_t fptr_imgbufcpy;
|
||||||
/* Should be called from Image class functions */
|
/* Should be called from Image class functions */
|
||||||
inline static uint8_t* AllocBuffer(size_t p_bufsize) {
|
inline static uint8_t* AllocBuffer(size_t p_bufsize) {
|
||||||
uint8_t* buffer = (uint8_t*)zm_mallocaligned(64, p_bufsize);
|
uint8_t* buffer = (uint8_t*)zm_mallocaligned(64, p_bufsize);
|
||||||
if ( buffer == NULL )
|
if ( buffer == nullptr )
|
||||||
Fatal("Memory allocation failed: %s", strerror(errno));
|
Fatal("Memory allocation failed: %s", strerror(errno));
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
|
@ -123,7 +123,7 @@ protected:
|
||||||
|
|
||||||
inline void DumpImgBuffer() {
|
inline void DumpImgBuffer() {
|
||||||
DumpBuffer(buffer, buffertype);
|
DumpBuffer(buffer, buffertype);
|
||||||
buffer = NULL;
|
buffer = nullptr;
|
||||||
allocation = 0;
|
allocation = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -192,7 +192,7 @@ void zm_jpeg_mem_dest (j_compress_ptr cinfo, JOCTET *outbuffer, int *outbuffer_s
|
||||||
* manager serially with the same JPEG object, because their private object
|
* manager serially with the same JPEG object, because their private object
|
||||||
* sizes may be different. Caveat programmer.
|
* sizes may be different. Caveat programmer.
|
||||||
*/
|
*/
|
||||||
if ( cinfo->dest == NULL )
|
if ( cinfo->dest == nullptr )
|
||||||
{
|
{
|
||||||
/* first time for this JPEG object? */
|
/* first time for this JPEG object? */
|
||||||
cinfo->dest = (struct jpeg_destination_mgr *)(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, SIZEOF(mem_destination_mgr));
|
cinfo->dest = (struct jpeg_destination_mgr *)(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, SIZEOF(mem_destination_mgr));
|
||||||
|
@ -369,7 +369,7 @@ void zm_jpeg_mem_src( j_decompress_ptr cinfo, const JOCTET *inbuffer, int inbuff
|
||||||
* This makes it unsafe to use this manager and a different source
|
* This makes it unsafe to use this manager and a different source
|
||||||
* manager serially with the same JPEG object. Caveat programmer.
|
* manager serially with the same JPEG object. Caveat programmer.
|
||||||
*/
|
*/
|
||||||
if ( cinfo->src == NULL )
|
if ( cinfo->src == nullptr )
|
||||||
{
|
{
|
||||||
/* first time for this JPEG object? */
|
/* first time for this JPEG object? */
|
||||||
cinfo->src = (struct jpeg_source_mgr *)(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, SIZEOF(mem_source_mgr));
|
cinfo->src = (struct jpeg_source_mgr *)(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, SIZEOF(mem_source_mgr));
|
||||||
|
@ -396,7 +396,7 @@ void zm_jpeg_mem_src( j_decompress_ptr cinfo, const JOCTET *inbuffer, int inbuff
|
||||||
src->inbuffer = (JOCTET *)inbuffer;
|
src->inbuffer = (JOCTET *)inbuffer;
|
||||||
src->inbuffer_size = inbuffer_size;
|
src->inbuffer_size = inbuffer_size;
|
||||||
src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
|
src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
|
||||||
src->pub.next_input_byte = NULL; /* until buffer loaded */
|
src->pub.next_input_byte = nullptr; /* until buffer loaded */
|
||||||
}
|
}
|
||||||
|
|
||||||
void zm_use_std_huff_tables( j_decompress_ptr cinfo ) {
|
void zm_use_std_huff_tables( j_decompress_ptr cinfo ) {
|
||||||
|
|
|
@ -72,7 +72,7 @@ void* LibvlcLockBuffer(void* opaque, void** planes) {
|
||||||
data->prevBuffer = buffer;
|
data->prevBuffer = buffer;
|
||||||
|
|
||||||
*planes = data->buffer;
|
*planes = data->buffer;
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LibvlcUnlockBuffer(void* opaque, void* picture, void *const *planes) {
|
void LibvlcUnlockBuffer(void* opaque, void* picture, void *const *planes) {
|
||||||
|
@ -129,12 +129,12 @@ LibvlcCamera::LibvlcCamera(
|
||||||
mMethod(p_method),
|
mMethod(p_method),
|
||||||
mOptions(p_options)
|
mOptions(p_options)
|
||||||
{
|
{
|
||||||
mLibvlcInstance = NULL;
|
mLibvlcInstance = nullptr;
|
||||||
mLibvlcMedia = NULL;
|
mLibvlcMedia = nullptr;
|
||||||
mLibvlcMediaPlayer = NULL;
|
mLibvlcMediaPlayer = nullptr;
|
||||||
mLibvlcData.buffer = NULL;
|
mLibvlcData.buffer = nullptr;
|
||||||
mLibvlcData.prevBuffer = NULL;
|
mLibvlcData.prevBuffer = nullptr;
|
||||||
mOptArgV = NULL;
|
mOptArgV = nullptr;
|
||||||
|
|
||||||
/* Has to be located inside the constructor so other components such as zma will receive correct colours and subpixel order */
|
/* Has to be located inside the constructor so other components such as zma will receive correct colours and subpixel order */
|
||||||
if ( colours == ZM_COLOUR_RGB32 ) {
|
if ( colours == ZM_COLOUR_RGB32 ) {
|
||||||
|
@ -163,19 +163,19 @@ LibvlcCamera::~LibvlcCamera() {
|
||||||
if ( capture ) {
|
if ( capture ) {
|
||||||
Terminate();
|
Terminate();
|
||||||
}
|
}
|
||||||
if ( mLibvlcMediaPlayer != NULL ) {
|
if ( mLibvlcMediaPlayer != nullptr ) {
|
||||||
(*libvlc_media_player_release_f)(mLibvlcMediaPlayer);
|
(*libvlc_media_player_release_f)(mLibvlcMediaPlayer);
|
||||||
mLibvlcMediaPlayer = NULL;
|
mLibvlcMediaPlayer = nullptr;
|
||||||
}
|
}
|
||||||
if ( mLibvlcMedia != NULL ) {
|
if ( mLibvlcMedia != nullptr ) {
|
||||||
(*libvlc_media_release_f)(mLibvlcMedia);
|
(*libvlc_media_release_f)(mLibvlcMedia);
|
||||||
mLibvlcMedia = NULL;
|
mLibvlcMedia = nullptr;
|
||||||
}
|
}
|
||||||
if ( mLibvlcInstance != NULL ) {
|
if ( mLibvlcInstance != nullptr ) {
|
||||||
(*libvlc_release_f)(mLibvlcInstance);
|
(*libvlc_release_f)(mLibvlcInstance);
|
||||||
mLibvlcInstance = NULL;
|
mLibvlcInstance = nullptr;
|
||||||
}
|
}
|
||||||
if ( mOptArgV != NULL ) {
|
if ( mOptArgV != nullptr ) {
|
||||||
delete[] mOptArgV;
|
delete[] mOptArgV;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -188,12 +188,12 @@ void LibvlcCamera::Terminate() {
|
||||||
(*libvlc_media_player_stop_f)(mLibvlcMediaPlayer);
|
(*libvlc_media_player_stop_f)(mLibvlcMediaPlayer);
|
||||||
if ( mLibvlcData.buffer ) {
|
if ( mLibvlcData.buffer ) {
|
||||||
zm_freealigned(mLibvlcData.buffer);
|
zm_freealigned(mLibvlcData.buffer);
|
||||||
mLibvlcData.buffer = NULL;
|
mLibvlcData.buffer = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( mLibvlcData.prevBuffer ) {
|
if ( mLibvlcData.prevBuffer ) {
|
||||||
zm_freealigned(mLibvlcData.prevBuffer);
|
zm_freealigned(mLibvlcData.prevBuffer);
|
||||||
mLibvlcData.prevBuffer = NULL;
|
mLibvlcData.prevBuffer = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,27 +223,27 @@ int LibvlcCamera::PrimeCapture() {
|
||||||
}
|
}
|
||||||
|
|
||||||
mLibvlcInstance = (*libvlc_new_f)(opVect.size(), (const char* const*)mOptArgV);
|
mLibvlcInstance = (*libvlc_new_f)(opVect.size(), (const char* const*)mOptArgV);
|
||||||
if ( mLibvlcInstance == NULL ) {
|
if ( mLibvlcInstance == nullptr ) {
|
||||||
Error("Unable to create libvlc instance due to: %s", (*libvlc_errmsg_f)());
|
Error("Unable to create libvlc instance due to: %s", (*libvlc_errmsg_f)());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
(*libvlc_log_set_f)(mLibvlcInstance, LibvlcCamera::log_callback, NULL);
|
(*libvlc_log_set_f)(mLibvlcInstance, LibvlcCamera::log_callback, nullptr);
|
||||||
|
|
||||||
|
|
||||||
mLibvlcMedia = (*libvlc_media_new_location_f)(mLibvlcInstance, mPath.c_str());
|
mLibvlcMedia = (*libvlc_media_new_location_f)(mLibvlcInstance, mPath.c_str());
|
||||||
if ( mLibvlcMedia == NULL ) {
|
if ( mLibvlcMedia == nullptr ) {
|
||||||
Error("Unable to open input %s due to: %s", mPath.c_str(), (*libvlc_errmsg_f)());
|
Error("Unable to open input %s due to: %s", mPath.c_str(), (*libvlc_errmsg_f)());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
mLibvlcMediaPlayer = (*libvlc_media_player_new_from_media_f)(mLibvlcMedia);
|
mLibvlcMediaPlayer = (*libvlc_media_player_new_from_media_f)(mLibvlcMedia);
|
||||||
if ( mLibvlcMediaPlayer == NULL ) {
|
if ( mLibvlcMediaPlayer == nullptr ) {
|
||||||
Error("Unable to create player for %s due to: %s", mPath.c_str(), (*libvlc_errmsg_f)());
|
Error("Unable to create player for %s due to: %s", mPath.c_str(), (*libvlc_errmsg_f)());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*libvlc_video_set_format_f)(mLibvlcMediaPlayer, mTargetChroma.c_str(), width, height, width * mBpp);
|
(*libvlc_video_set_format_f)(mLibvlcMediaPlayer, mTargetChroma.c_str(), width, height, width * mBpp);
|
||||||
(*libvlc_video_set_callbacks_f)(mLibvlcMediaPlayer, &LibvlcLockBuffer, &LibvlcUnlockBuffer, NULL, &mLibvlcData);
|
(*libvlc_video_set_callbacks_f)(mLibvlcMediaPlayer, &LibvlcLockBuffer, &LibvlcUnlockBuffer, nullptr, &mLibvlcData);
|
||||||
|
|
||||||
mLibvlcData.bufferSize = width * height * mBpp;
|
mLibvlcData.bufferSize = width * height * mBpp;
|
||||||
// Libvlc wants 32 byte alignment for images (should in theory do this for all image lines)
|
// Libvlc wants 32 byte alignment for images (should in theory do this for all image lines)
|
||||||
|
|
|
@ -24,7 +24,7 @@ void bind_libvnc_symbols() {
|
||||||
|
|
||||||
libvnc_lib = dlopen("libvncclient.so", RTLD_LAZY | RTLD_GLOBAL);
|
libvnc_lib = dlopen("libvncclient.so", RTLD_LAZY | RTLD_GLOBAL);
|
||||||
if ( !libvnc_lib ) {
|
if ( !libvnc_lib ) {
|
||||||
Error("Error loading libvlc: %s", dlerror());
|
Error("Error loading libvncclient: %s", dlerror());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ static rfbCredential* GetCredentialsCallback(rfbClient* cl, int credentialType){
|
||||||
rfbCredential *c = (rfbCredential *)malloc(sizeof(rfbCredential));
|
rfbCredential *c = (rfbCredential *)malloc(sizeof(rfbCredential));
|
||||||
if ( credentialType != rfbCredentialTypeUser ) {
|
if ( credentialType != rfbCredentialTypeUser ) {
|
||||||
free(c);
|
free(c);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
c->userCredential.password = strdup((const char *)(*rfbClientGetClientData_f)(cl, &TAG_1));
|
c->userCredential.password = strdup((const char *)(*rfbClientGetClientData_f)(cl, &TAG_1));
|
||||||
|
@ -136,7 +136,6 @@ void VncCamera::Initialise() {
|
||||||
mRfb->programName = "Zoneminder VNC Monitor";
|
mRfb->programName = "Zoneminder VNC Monitor";
|
||||||
mRfb->serverHost = strdup(mHost.c_str());
|
mRfb->serverHost = strdup(mHost.c_str());
|
||||||
mRfb->serverPort = atoi(mPort.c_str());
|
mRfb->serverPort = atoi(mPort.c_str());
|
||||||
(*rfbInitClient_f)(mRfb, 0, nullptr);
|
|
||||||
scale.init();
|
scale.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,12 +148,20 @@ void VncCamera::Terminate() {
|
||||||
|
|
||||||
int VncCamera::PrimeCapture() {
|
int VncCamera::PrimeCapture() {
|
||||||
Debug(1, "Priming capture from %s", mHost.c_str());
|
Debug(1, "Priming capture from %s", mHost.c_str());
|
||||||
|
if ( ! (*rfbInitClient_f)(mRfb, 0, nullptr) ) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int VncCamera::PreCapture() {
|
int VncCamera::PreCapture() {
|
||||||
Debug(2, "PreCapture");
|
Debug(2, "PreCapture");
|
||||||
(*WaitForMessage_f)(mRfb, 500);
|
int rc = (*WaitForMessage_f)(mRfb, 500);
|
||||||
|
if ( rc < 0 ) {
|
||||||
|
return -1;
|
||||||
|
} else if ( !rc ) {
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
rfbBool res = (*HandleRFBServerMessage_f)(mRfb);
|
rfbBool res = (*HandleRFBServerMessage_f)(mRfb);
|
||||||
return res == TRUE ? 1 : -1;
|
return res == TRUE ? 1 : -1;
|
||||||
}
|
}
|
||||||
|
@ -162,7 +169,17 @@ int VncCamera::PreCapture() {
|
||||||
int VncCamera::Capture(Image &image) {
|
int VncCamera::Capture(Image &image) {
|
||||||
Debug(2, "Capturing");
|
Debug(2, "Capturing");
|
||||||
uint8_t *directbuffer = image.WriteBuffer(width, height, colours, subpixelorder);
|
uint8_t *directbuffer = image.WriteBuffer(width, height, colours, subpixelorder);
|
||||||
scale.Convert(mVncData.buffer, mRfb->si.framebufferHeight * mRfb->si.framebufferWidth * 4, directbuffer, width * height * mBpp, AV_PIX_FMT_RGBA, mImgPixFmt, mRfb->si.framebufferWidth, mRfb->si.framebufferHeight, width, height);
|
scale.Convert(
|
||||||
|
mVncData.buffer,
|
||||||
|
mRfb->si.framebufferHeight * mRfb->si.framebufferWidth * 4,
|
||||||
|
directbuffer,
|
||||||
|
width * height * mBpp,
|
||||||
|
AV_PIX_FMT_RGBA,
|
||||||
|
mImgPixFmt,
|
||||||
|
mRfb->si.framebufferWidth,
|
||||||
|
mRfb->si.framebufferHeight,
|
||||||
|
width,
|
||||||
|
height);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -301,10 +301,10 @@ LocalCamera::V4L1Data LocalCamera::v4l1_data;
|
||||||
#endif // ZM_HAS_V4L1
|
#endif // ZM_HAS_V4L1
|
||||||
|
|
||||||
#if HAVE_LIBSWSCALE
|
#if HAVE_LIBSWSCALE
|
||||||
AVFrame **LocalCamera::capturePictures = 0;
|
AVFrame **LocalCamera::capturePictures = nullptr;
|
||||||
#endif // HAVE_LIBSWSCALE
|
#endif // HAVE_LIBSWSCALE
|
||||||
|
|
||||||
LocalCamera *LocalCamera::last_camera = NULL;
|
LocalCamera *LocalCamera::last_camera = nullptr;
|
||||||
|
|
||||||
LocalCamera::LocalCamera(
|
LocalCamera::LocalCamera(
|
||||||
int p_id,
|
int p_id,
|
||||||
|
@ -668,14 +668,14 @@ LocalCamera::LocalCamera(
|
||||||
Fatal("Image size mismatch. Required: %d Available: %u", pSize, imagesize);
|
Fatal("Image size mismatch. Required: %d Available: %u", pSize, imagesize);
|
||||||
}
|
}
|
||||||
|
|
||||||
imgConversionContext = sws_getContext(width, height, capturePixFormat, width, height, imagePixFormat, SWS_BICUBIC, NULL, NULL, NULL);
|
imgConversionContext = sws_getContext(width, height, capturePixFormat, width, height, imagePixFormat, SWS_BICUBIC, nullptr, nullptr, nullptr);
|
||||||
|
|
||||||
if ( !imgConversionContext ) {
|
if ( !imgConversionContext ) {
|
||||||
Fatal("Unable to initialise image scaling context");
|
Fatal("Unable to initialise image scaling context");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tmpPicture = NULL;
|
tmpPicture = nullptr;
|
||||||
imgConversionContext = NULL;
|
imgConversionContext = nullptr;
|
||||||
} // end if capture and conversion_tye == swscale
|
} // end if capture and conversion_tye == swscale
|
||||||
#endif
|
#endif
|
||||||
mVideoStreamId = 0;
|
mVideoStreamId = 0;
|
||||||
|
@ -691,7 +691,7 @@ LocalCamera::~LocalCamera() {
|
||||||
/* Clean up swscale stuff */
|
/* Clean up swscale stuff */
|
||||||
if ( capture && conversion_type == 1 ) {
|
if ( capture && conversion_type == 1 ) {
|
||||||
sws_freeContext(imgConversionContext);
|
sws_freeContext(imgConversionContext);
|
||||||
imgConversionContext = NULL;
|
imgConversionContext = nullptr;
|
||||||
|
|
||||||
av_frame_free(&tmpPicture);
|
av_frame_free(&tmpPicture);
|
||||||
}
|
}
|
||||||
|
@ -903,7 +903,7 @@ void LocalCamera::Initialise() {
|
||||||
Fatal("Unable to query video buffer: %s", strerror(errno));
|
Fatal("Unable to query video buffer: %s", strerror(errno));
|
||||||
|
|
||||||
v4l2_data.buffers[i].length = vid_buf.length;
|
v4l2_data.buffers[i].length = vid_buf.length;
|
||||||
v4l2_data.buffers[i].start = mmap(NULL, vid_buf.length, PROT_READ|PROT_WRITE, MAP_SHARED, vid_fd, vid_buf.m.offset);
|
v4l2_data.buffers[i].start = mmap(nullptr, vid_buf.length, PROT_READ|PROT_WRITE, MAP_SHARED, vid_fd, vid_buf.m.offset);
|
||||||
|
|
||||||
if ( v4l2_data.buffers[i].start == MAP_FAILED )
|
if ( v4l2_data.buffers[i].start == MAP_FAILED )
|
||||||
Fatal("Can't map video buffer %u (%u bytes) to memory: %s(%d)",
|
Fatal("Can't map video buffer %u (%u bytes) to memory: %s(%d)",
|
||||||
|
@ -1998,7 +1998,7 @@ int LocalCamera::PrimeCapture() {
|
||||||
if ( vidioctl(vid_fd, VIDIOC_QBUF, &vid_buf) < 0 )
|
if ( vidioctl(vid_fd, VIDIOC_QBUF, &vid_buf) < 0 )
|
||||||
Fatal("Failed to queue buffer %d: %s", frame, strerror(errno));
|
Fatal("Failed to queue buffer %d: %s", frame, strerror(errno));
|
||||||
}
|
}
|
||||||
v4l2_data.bufptr = NULL;
|
v4l2_data.bufptr = nullptr;
|
||||||
|
|
||||||
Debug(3, "Starting video stream");
|
Debug(3, "Starting video stream");
|
||||||
//enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
//enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||||
|
@ -2030,9 +2030,8 @@ int LocalCamera::PreCapture() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int LocalCamera::Capture(ZMPacket &zm_packet) {
|
int LocalCamera::Capture(ZMPacket &zm_packet) {
|
||||||
|
|
||||||
// We assume that the avpacket is allocated, and just needs to be filled
|
// We assume that the avpacket is allocated, and just needs to be filled
|
||||||
static uint8_t* buffer = NULL;
|
static uint8_t* buffer = nullptr;
|
||||||
int buffer_bytesused = 0;
|
int buffer_bytesused = 0;
|
||||||
int capture_frame = -1;
|
int capture_frame = -1;
|
||||||
|
|
||||||
|
@ -2134,7 +2133,7 @@ int LocalCamera::Capture( ZMPacket &zm_packet ) {
|
||||||
|
|
||||||
/* Request a writeable buffer of the target image */
|
/* Request a writeable buffer of the target image */
|
||||||
uint8_t *directbuffer = zm_packet.image->WriteBuffer(width, height, colours, subpixelorder);
|
uint8_t *directbuffer = zm_packet.image->WriteBuffer(width, height, colours, subpixelorder);
|
||||||
if ( directbuffer == NULL ) {
|
if ( directbuffer == nullptr ) {
|
||||||
Error("Failed requesting writeable buffer for the captured image.");
|
Error("Failed requesting writeable buffer for the captured image.");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
|
|
||||||
bool Logger::smInitialised = false;
|
bool Logger::smInitialised = false;
|
||||||
Logger *Logger::smInstance = NULL;
|
Logger *Logger::smInstance = nullptr;
|
||||||
|
|
||||||
Logger::StringMap Logger::smCodes;
|
Logger::StringMap Logger::smCodes;
|
||||||
Logger::IntMap Logger::smSyslogPriorities;
|
Logger::IntMap Logger::smSyslogPriorities;
|
||||||
|
@ -75,7 +75,7 @@ Logger::Logger() :
|
||||||
mDbConnected(false),
|
mDbConnected(false),
|
||||||
mLogPath(staticConfig.PATH_LOGS.c_str()),
|
mLogPath(staticConfig.PATH_LOGS.c_str()),
|
||||||
//mLogFile( mLogPath+"/"+mId+".log" ),
|
//mLogFile( mLogPath+"/"+mId+".log" ),
|
||||||
mLogFileFP(NULL),
|
mLogFileFP(nullptr),
|
||||||
mHasTerminal(false),
|
mHasTerminal(false),
|
||||||
mFlush(false) {
|
mFlush(false) {
|
||||||
|
|
||||||
|
@ -412,7 +412,7 @@ void Logger::logFile(const std::string &logFile) {
|
||||||
|
|
||||||
void Logger::openFile() {
|
void Logger::openFile() {
|
||||||
if ( mLogFile.size() ) {
|
if ( mLogFile.size() ) {
|
||||||
if ( (mLogFileFP = fopen(mLogFile.c_str(), "a")) == (FILE *)NULL ) {
|
if ( (mLogFileFP = fopen(mLogFile.c_str(), "a")) == nullptr ) {
|
||||||
mFileLevel = NOLOG;
|
mFileLevel = NOLOG;
|
||||||
Error("fopen() for %s, error = %s", mLogFile.c_str(), strerror(errno));
|
Error("fopen() for %s, error = %s", mLogFile.c_str(), strerror(errno));
|
||||||
}
|
}
|
||||||
|
@ -425,10 +425,10 @@ void Logger::closeFile() {
|
||||||
if ( mLogFileFP ) {
|
if ( mLogFileFP ) {
|
||||||
fflush(mLogFileFP);
|
fflush(mLogFileFP);
|
||||||
if ( fclose(mLogFileFP) < 0 ) {
|
if ( fclose(mLogFileFP) < 0 ) {
|
||||||
mLogFileFP = (FILE *)NULL;
|
mLogFileFP = nullptr;
|
||||||
Error("fclose(), error = %s", strerror(errno));
|
Error("fclose(), error = %s", strerror(errno));
|
||||||
}
|
}
|
||||||
mLogFileFP = (FILE *)NULL;
|
mLogFileFP = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -463,7 +463,7 @@ void Logger::logPrint(bool hex, const char * const filepath, const int line, con
|
||||||
if ( level < PANIC || level > DEBUG9 )
|
if ( level < PANIC || level > DEBUG9 )
|
||||||
Panic("Invalid logger level %d", level);
|
Panic("Invalid logger level %d", level);
|
||||||
|
|
||||||
gettimeofday(&timeVal, NULL);
|
gettimeofday(&timeVal, nullptr);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if ( logRuntime ) {
|
if ( logRuntime ) {
|
||||||
|
@ -610,7 +610,7 @@ void Logger::logPrint(bool hex, const char * const filepath, const int line, con
|
||||||
void logInit(const char *name, const Logger::Options &options) {
|
void logInit(const char *name, const Logger::Options &options) {
|
||||||
if ( Logger::smInstance ) {
|
if ( Logger::smInstance ) {
|
||||||
delete Logger::smInstance;
|
delete Logger::smInstance;
|
||||||
Logger::smInstance = NULL;
|
Logger::smInstance = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::smInstance = new Logger();
|
Logger::smInstance = new Logger();
|
||||||
|
@ -620,6 +620,6 @@ void logInit(const char *name, const Logger::Options &options) {
|
||||||
void logTerm() {
|
void logTerm() {
|
||||||
if ( Logger::smInstance ) {
|
if ( Logger::smInstance ) {
|
||||||
delete Logger::smInstance;
|
delete Logger::smInstance;
|
||||||
Logger::smInstance = NULL;
|
Logger::smInstance = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,15 +27,15 @@ inline void* zm_mallocaligned(unsigned int reqalignment, size_t reqsize) {
|
||||||
uint8_t* retptr;
|
uint8_t* retptr;
|
||||||
#if HAVE_POSIX_MEMALIGN
|
#if HAVE_POSIX_MEMALIGN
|
||||||
if ( posix_memalign((void**)&retptr,reqalignment,reqsize) != 0 )
|
if ( posix_memalign((void**)&retptr,reqalignment,reqsize) != 0 )
|
||||||
return NULL;
|
return nullptr;
|
||||||
|
|
||||||
return retptr;
|
return retptr;
|
||||||
#else
|
#else
|
||||||
uint8_t* alloc;
|
uint8_t* alloc;
|
||||||
retptr = (uint8_t*)malloc(reqsize+reqalignment+sizeof(void*));
|
retptr = (uint8_t*)malloc(reqsize+reqalignment+sizeof(void*));
|
||||||
|
|
||||||
if ( retptr == NULL )
|
if ( retptr == nullptr )
|
||||||
return NULL;
|
return nullptr;
|
||||||
|
|
||||||
alloc = retptr + sizeof(void*);
|
alloc = retptr + sizeof(void*);
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ inline void zm_freealigned(void* ptr) {
|
||||||
|
|
||||||
inline char *mempbrk(const char *s, const char *accept, size_t limit) {
|
inline char *mempbrk(const char *s, const char *accept, size_t limit) {
|
||||||
if ( limit == 0 || !s || !accept || !*accept )
|
if ( limit == 0 || !s || !accept || !*accept )
|
||||||
return 0;
|
return nullptr;
|
||||||
|
|
||||||
unsigned int i,j;
|
unsigned int i,j;
|
||||||
size_t acc_len = strlen(accept);
|
size_t acc_len = strlen(accept);
|
||||||
|
@ -72,12 +72,12 @@ inline char *mempbrk(const char *s, const char *accept, size_t limit) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline char *memstr(const char *s, const char *n, size_t limit) {
|
inline char *memstr(const char *s, const char *n, size_t limit) {
|
||||||
if ( limit == 0 || !s || !n )
|
if ( limit == 0 || !s || !n )
|
||||||
return 0;
|
return nullptr;
|
||||||
|
|
||||||
if ( !*n )
|
if ( !*n )
|
||||||
return (char *)s;
|
return (char *)s;
|
||||||
|
@ -97,7 +97,7 @@ inline char *memstr(const char *s, const char *n, size_t limit) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t memspn(const char *s, const char *accept, size_t limit) {
|
inline size_t memspn(const char *s, const char *accept, size_t limit) {
|
||||||
|
|
|
@ -98,9 +98,9 @@ std::string CameraType_Strings[] = {
|
||||||
|
|
||||||
Monitor::MonitorLink::MonitorLink(unsigned int p_id, const char *p_name) :
|
Monitor::MonitorLink::MonitorLink(unsigned int p_id, const char *p_name) :
|
||||||
id(p_id),
|
id(p_id),
|
||||||
shared_data(NULL),
|
shared_data(nullptr),
|
||||||
trigger_data(NULL),
|
trigger_data(nullptr),
|
||||||
video_store_data(NULL)
|
video_store_data(nullptr)
|
||||||
{
|
{
|
||||||
strncpy(name, p_name, sizeof(name)-1);
|
strncpy(name, p_name, sizeof(name)-1);
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ Monitor::MonitorLink::MonitorLink(unsigned int p_id, const char *p_name) :
|
||||||
shm_id = 0;
|
shm_id = 0;
|
||||||
#endif // ZM_MEM_MAPPED
|
#endif // ZM_MEM_MAPPED
|
||||||
mem_size = 0;
|
mem_size = 0;
|
||||||
mem_ptr = 0;
|
mem_ptr = nullptr;
|
||||||
|
|
||||||
last_event_id = 0;
|
last_event_id = 0;
|
||||||
last_state = IDLE;
|
last_state = IDLE;
|
||||||
|
@ -125,8 +125,8 @@ Monitor::MonitorLink::~MonitorLink() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Monitor::MonitorLink::connect() {
|
bool Monitor::MonitorLink::connect() {
|
||||||
if ( !last_connect_time || (time(0) - last_connect_time) > 60 ) {
|
if ( !last_connect_time || (time(nullptr) - last_connect_time) > 60 ) {
|
||||||
last_connect_time = time(0);
|
last_connect_time = time(nullptr);
|
||||||
|
|
||||||
mem_size = sizeof(SharedData) + sizeof(TriggerData);
|
mem_size = sizeof(SharedData) + sizeof(TriggerData);
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ bool Monitor::MonitorLink::connect() {
|
||||||
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(nullptr, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED, map_fd, 0);
|
||||||
if ( mem_ptr == MAP_FAILED ) {
|
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();
|
disconnect();
|
||||||
|
@ -237,7 +237,7 @@ bool Monitor::MonitorLink::disconnect() {
|
||||||
|
|
||||||
#endif // ZM_MEM_MAPPED
|
#endif // ZM_MEM_MAPPED
|
||||||
mem_size = 0;
|
mem_size = 0;
|
||||||
mem_ptr = 0;
|
mem_ptr = nullptr;
|
||||||
}
|
}
|
||||||
return( true );
|
return( true );
|
||||||
}
|
}
|
||||||
|
@ -334,13 +334,13 @@ Monitor::Monitor()
|
||||||
last_motion_score(0),
|
last_motion_score(0),
|
||||||
camera(0),
|
camera(0),
|
||||||
n_zones(0),
|
n_zones(0),
|
||||||
zones(NULL),
|
zones(nullptr),
|
||||||
timestamps(0),
|
timestamps(0),
|
||||||
images(0),
|
images(0),
|
||||||
privacy_bitmask( NULL ),
|
privacy_bitmask( nullptr ),
|
||||||
event_delete_thread(NULL),
|
event_delete_thread(nullptr),
|
||||||
n_linked_monitors(0),
|
n_linked_monitors(0),
|
||||||
linked_monitors(NULL)
|
linked_monitors(nullptr)
|
||||||
{
|
{
|
||||||
|
|
||||||
if ( strcmp(config.event_close_mode, "time") == 0 )
|
if ( strcmp(config.event_close_mode, "time") == 0 )
|
||||||
|
@ -356,7 +356,7 @@ Monitor::Monitor()
|
||||||
|
|
||||||
adaptive_skip = true;
|
adaptive_skip = true;
|
||||||
|
|
||||||
videoStore = NULL;
|
videoStore = nullptr;
|
||||||
} // Monitor::Monitor
|
} // Monitor::Monitor
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -581,7 +581,7 @@ void Monitor::Load(MYSQL_ROW dbrow, bool load_zones=true, Purpose p = QUERY) {
|
||||||
(image_buffer_count*sizeof(struct timeval)),
|
(image_buffer_count*sizeof(struct timeval)),
|
||||||
image_buffer_count, image_size, (image_buffer_count*image_size),
|
image_buffer_count, image_size, (image_buffer_count*image_size),
|
||||||
mem_size);
|
mem_size);
|
||||||
mem_ptr = NULL;
|
mem_ptr = nullptr;
|
||||||
|
|
||||||
Zone **zones = 0;
|
Zone **zones = 0;
|
||||||
int n_zones = Zone::Load(this, zones);
|
int n_zones = Zone::Load(this, zones);
|
||||||
|
@ -851,12 +851,12 @@ bool Monitor::connect() {
|
||||||
|
|
||||||
Debug(3, "MMap file size is %ld", map_stat.st_size);
|
Debug(3, "MMap file size is %ld", map_stat.st_size);
|
||||||
#ifdef MAP_LOCKED
|
#ifdef MAP_LOCKED
|
||||||
mem_ptr = (unsigned char *)mmap(NULL, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_LOCKED, map_fd, 0);
|
mem_ptr = (unsigned char *)mmap(nullptr, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_LOCKED, map_fd, 0);
|
||||||
if ( mem_ptr == MAP_FAILED ) {
|
if ( mem_ptr == MAP_FAILED ) {
|
||||||
if ( errno == EAGAIN ) {
|
if ( errno == EAGAIN ) {
|
||||||
Debug(1, "Unable to map file %s (%d bytes) to locked memory, trying unlocked", mem_file, mem_size);
|
Debug(1, "Unable to map file %s (%d bytes) to locked memory, trying unlocked", mem_file, mem_size);
|
||||||
#endif
|
#endif
|
||||||
mem_ptr = (unsigned char *)mmap(NULL, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED, map_fd, 0);
|
mem_ptr = (unsigned char *)mmap(nullptr, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED, map_fd, 0);
|
||||||
Debug(1, "Mapped file %s (%d bytes) to unlocked memory", mem_file, mem_size);
|
Debug(1, "Mapped file %s (%d bytes) to unlocked memory", mem_file, mem_size);
|
||||||
#ifdef MAP_LOCKED
|
#ifdef MAP_LOCKED
|
||||||
} else {
|
} else {
|
||||||
|
@ -866,7 +866,7 @@ bool Monitor::connect() {
|
||||||
#endif
|
#endif
|
||||||
if ( mem_ptr == MAP_FAILED )
|
if ( mem_ptr == MAP_FAILED )
|
||||||
Fatal("Can't map file %s (%d bytes) to memory: %s(%d)", mem_file, mem_size, strerror(errno), errno);
|
Fatal("Can't map file %s (%d bytes) to memory: %s(%d)", mem_file, mem_size, strerror(errno), errno);
|
||||||
if ( mem_ptr == NULL ) {
|
if ( mem_ptr == nullptr ) {
|
||||||
Error("mmap gave a NULL address:");
|
Error("mmap gave a NULL address:");
|
||||||
} else {
|
} else {
|
||||||
Debug(3, "mmapped to %p", mem_ptr);
|
Debug(3, "mmapped to %p", mem_ptr);
|
||||||
|
@ -976,13 +976,13 @@ Monitor::~Monitor() {
|
||||||
if ( event_delete_thread ) {
|
if ( event_delete_thread ) {
|
||||||
event_delete_thread->join();
|
event_delete_thread->join();
|
||||||
delete event_delete_thread;
|
delete event_delete_thread;
|
||||||
event_delete_thread = NULL;
|
event_delete_thread = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( event_delete_thread ) {
|
if ( event_delete_thread ) {
|
||||||
event_delete_thread->join();
|
event_delete_thread->join();
|
||||||
delete event_delete_thread;
|
delete event_delete_thread;
|
||||||
event_delete_thread = NULL;
|
event_delete_thread = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( deinterlacing_value == 4 ) {
|
if ( deinterlacing_value == 4 ) {
|
||||||
|
@ -1083,9 +1083,9 @@ void Monitor::AddZones(int p_n_zones, Zone *p_zones[]) {
|
||||||
void Monitor::AddPrivacyBitmask(Zone *p_zones[]) {
|
void Monitor::AddPrivacyBitmask(Zone *p_zones[]) {
|
||||||
if ( privacy_bitmask ) {
|
if ( privacy_bitmask ) {
|
||||||
delete[] privacy_bitmask;
|
delete[] privacy_bitmask;
|
||||||
privacy_bitmask = NULL;
|
privacy_bitmask = nullptr;
|
||||||
}
|
}
|
||||||
Image *privacy_image = NULL;
|
Image *privacy_image = nullptr;
|
||||||
|
|
||||||
for ( int i=0; i < n_zones; i++ ) {
|
for ( int i=0; i < n_zones; i++ ) {
|
||||||
if ( p_zones[i]->IsPrivacy() ) {
|
if ( p_zones[i]->IsPrivacy() ) {
|
||||||
|
@ -1444,7 +1444,7 @@ void Monitor::DumpZoneImage(const char *zone_string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Image *zone_image = NULL;
|
Image *zone_image = nullptr;
|
||||||
if ( ( (!staticConfig.SERVER_ID) || ( staticConfig.SERVER_ID == server_id ) ) && mem_ptr ) {
|
if ( ( (!staticConfig.SERVER_ID) || ( staticConfig.SERVER_ID == server_id ) ) && mem_ptr ) {
|
||||||
Debug(3, "Trying to load from local zmc");
|
Debug(3, "Trying to load from local zmc");
|
||||||
int index = shared_data->last_write_index;
|
int index = shared_data->last_write_index;
|
||||||
|
@ -1463,7 +1463,7 @@ void Monitor::DumpZoneImage(const char *zone_string) {
|
||||||
stream->setStreamStart(event_id, (unsigned int)1);
|
stream->setStreamStart(event_id, (unsigned int)1);
|
||||||
zone_image = stream->getImage();
|
zone_image = stream->getImage();
|
||||||
delete stream;
|
delete stream;
|
||||||
stream = NULL;
|
stream = nullptr;
|
||||||
} else {
|
} else {
|
||||||
Error("Unable to load an event for monitor %d", id);
|
Error("Unable to load an event for monitor %d", id);
|
||||||
return;
|
return;
|
||||||
|
@ -1594,7 +1594,8 @@ bool Monitor::CheckSignal(const Image *image) {
|
||||||
|
|
||||||
void Monitor::CheckAction() {
|
void Monitor::CheckAction() {
|
||||||
struct timeval now;
|
struct timeval now;
|
||||||
gettimeofday(&now, NULL);
|
gettimeofday(&now, nullptr);
|
||||||
|
|
||||||
if ( shared_data->action ) {
|
if ( shared_data->action ) {
|
||||||
// Can there be more than 1 bit set in the action? Shouldn't these be elseifs?
|
// Can there be more than 1 bit set in the action? Shouldn't these be elseifs?
|
||||||
if ( shared_data->action & RELOAD ) {
|
if ( shared_data->action & RELOAD ) {
|
||||||
|
@ -2096,7 +2097,7 @@ void Monitor::ReloadZones() {
|
||||||
delete zones[i];
|
delete zones[i];
|
||||||
}
|
}
|
||||||
delete[] zones;
|
delete[] zones;
|
||||||
zones = 0;
|
zones = nullptr;
|
||||||
n_zones = Zone::Load(this, zones);
|
n_zones = Zone::Load(this, zones);
|
||||||
//DumpZoneImage();
|
//DumpZoneImage();
|
||||||
} // end void Monitor::ReloadZones()
|
} // end void Monitor::ReloadZones()
|
||||||
|
@ -2108,7 +2109,7 @@ void Monitor::ReloadLinkedMonitors(const char *p_linked_monitors) {
|
||||||
delete linked_monitors[i];
|
delete linked_monitors[i];
|
||||||
}
|
}
|
||||||
delete[] linked_monitors;
|
delete[] linked_monitors;
|
||||||
linked_monitors = 0;
|
linked_monitors = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
n_linked_monitors = 0;
|
n_linked_monitors = 0;
|
||||||
|
@ -2538,13 +2539,13 @@ bool Monitor::closeEvent() {
|
||||||
}
|
}
|
||||||
event_delete_thread = new std::thread([](Event *event) {
|
event_delete_thread = new std::thread([](Event *event) {
|
||||||
Event * e = event;
|
Event * e = event;
|
||||||
event = NULL;
|
event = nullptr;
|
||||||
delete e;
|
delete e;
|
||||||
e = NULL;
|
e = nullptr;
|
||||||
}, event);
|
}, event);
|
||||||
#else
|
#else
|
||||||
delete event;
|
delete event;
|
||||||
event = NULL;
|
event = nullptr;
|
||||||
#endif
|
#endif
|
||||||
video_store_data->recording = (struct timeval){0};
|
video_store_data->recording = (struct timeval){0};
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -93,6 +93,7 @@ public:
|
||||||
} Orientation;
|
} Orientation;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
UNKNOWN=-1,
|
||||||
IDLE,
|
IDLE,
|
||||||
PREALARM,
|
PREALARM,
|
||||||
ALARM,
|
ALARM,
|
||||||
|
@ -403,7 +404,7 @@ public:
|
||||||
bool connect();
|
bool connect();
|
||||||
|
|
||||||
inline int ShmValid() const {
|
inline int ShmValid() const {
|
||||||
return shared_data->valid;
|
return shared_data && shared_data->valid;
|
||||||
}
|
}
|
||||||
Camera *getCamera();
|
Camera *getCamera();
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue