merged fifo changes
commit
915e9f05a9
|
@ -33,7 +33,6 @@ install:
|
|||
|
||||
env:
|
||||
- SMPFLAGS=-j4 OS=el DIST=7
|
||||
- SMPFLAGS=-j4 OS=fedora DIST=27 DOCKER_REPO=knnniggett/packpack
|
||||
- SMPFLAGS=-j4 OS=fedora DIST=28 DOCKER_REPO=knnniggett/packpack
|
||||
- SMPFLAGS=-j4 OS=fedora DIST=29 DOCKER_REPO=knnniggett/packpack
|
||||
- SMPFLAGS=-j4 OS=ubuntu DIST=trusty
|
||||
|
|
|
@ -791,7 +791,7 @@ INSERT INTO `Controls` VALUES (NULL,'IOS Camera','Ffmpeg','IPCAMIOS',0,0,0,0,0,0
|
|||
INSERT INTO `Controls` VALUES (NULL,'Dericam P2','Ffmpeg','DericamP2',0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,10,0,1,1,1,0,0,0,1,1,0,0,0,0,1,1,45,0,0,1,0,0,0,0,1,1,45,0,0,0,0);
|
||||
INSERT INTO `Controls` VALUES (NULL,'Trendnet','Remote','Trendnet',1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0);
|
||||
INSERT INTO `Controls` VALUES (NULL,'PSIA','Remote','PSIA',0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,20,0,1,1,1,0,0,1,0,1,0,0,0,0,1,-100,100,0,0,1,0,0,0,0,1,-100,100,0,0,0,0);
|
||||
INSERT INTO `Controls` VALUES (NULL,'Dahua','Ffmpeg','Dahua',0,0,1,1,1,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,20,1,1,1,1,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0);
|
||||
INSERT INTO `Controls` VALUES (NULL,'Dahua','Ffmpeg','Dahua',0,0,1,1,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,20,1,1,1,1,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0);
|
||||
INSERT INTO `Controls` VALUES (NULL,'FOSCAMR2C','Libvlc','FOSCAMR2C',1,1,1,0,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,1,12,0,1,1,1,0,0,0,1,1,NULL,NULL,NULL,NULL,1,0,4,0,NULL,1,NULL,NULL,NULL,NULL,1,0,4,0,NULL,0,0);
|
||||
INSERT INTO `Controls` VALUES (NULL,'Amcrest HTTP API','Ffmpeg','Amcrest_HTTP',0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,5,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,5);
|
||||
|
||||
|
|
|
@ -73,6 +73,7 @@ BuildRequires: libcurl-devel
|
|||
BuildRequires: libv4l-devel
|
||||
BuildRequires: desktop-file-utils
|
||||
BuildRequires: gzip
|
||||
BuildRequires: zlib-devel
|
||||
|
||||
# ZoneMinder looks for and records the location of the ffmpeg binary during build
|
||||
BuildRequires: ffmpeg
|
||||
|
|
|
@ -197,8 +197,8 @@ our @options = (
|
|||
name => 'ZM_BANDWIDTH_DEFAULT',
|
||||
default => 'high',
|
||||
description => 'Default setting for bandwidth profile used by web interface',
|
||||
help => q`The classic skin for ZoneMinder has different
|
||||
profiles to use for low medium or high bandwidth connections.
|
||||
help => q`The classic skin for ZoneMinder has different
|
||||
profiles to use for low, medium, or high bandwidth connections.
|
||||
`,
|
||||
type => $types{string},
|
||||
category => 'system',
|
||||
|
@ -558,7 +558,7 @@ our @options = (
|
|||
higher quality setting than the ordinary file setting. If set
|
||||
to a lower value then it is ignored. Thus leaving it at the
|
||||
default of 0 effectively means to use the regular file quality
|
||||
setting for all saved images. This is to prevent acccidentally
|
||||
setting for all saved images. This is to prevent accidentally
|
||||
saving important images at a worse quality setting.
|
||||
`,
|
||||
type => $types{integer},
|
||||
|
@ -682,7 +682,7 @@ our @options = (
|
|||
Internet Explorer that don't natively support this format. If
|
||||
you use this browser it is highly recommended to install this
|
||||
from the [cambozola project site](http://www.charliemouse.com/code/cambozola/).
|
||||
However, if it is not installed still images at a lower refresh rate can
|
||||
However, if it is not installed still images at a lower refresh rate can
|
||||
still be viewed.
|
||||
`,
|
||||
type => $types{boolean},
|
||||
|
@ -937,10 +937,10 @@ our @options = (
|
|||
help => q`
|
||||
Due to browsers only wanting to open 6 connections, if you have more
|
||||
than 6 monitors, you can have trouble viewing more than 6. This setting
|
||||
specified the beginning of a port range that will be used to contact ZM
|
||||
specified the beginning of a port range that will be used to contact ZM
|
||||
on. Each monitor will use this value plus the Monitor Id to stream
|
||||
content. So a value of 2000 here will cause a stream for Monitor 1 to
|
||||
hit port 2001. Please ensure that you configure apache appropriately
|
||||
content. So a value of 2000 here will cause a stream for Monitor 1 to
|
||||
hit port 2001. Please ensure that you configure apache appropriately
|
||||
to respond on these ports.`,
|
||||
type => $types{integer},
|
||||
category => 'network',
|
||||
|
@ -1076,12 +1076,12 @@ our @options = (
|
|||
default => '0',
|
||||
description => 'Save logging output to the system log',
|
||||
help => q`
|
||||
ZoneMinder logging is now more more integrated between
|
||||
ZoneMinder logging is now more integrated between
|
||||
components and allows you to specify the destination for
|
||||
logging output and the individual levels for each. This option
|
||||
lets you control the level of logging output that goes to the
|
||||
system log. ZoneMinder binaries have always logged to the
|
||||
system log but now scripts and web logging is also included. To
|
||||
system log but script and web logging is now included. To
|
||||
preserve the previous behaviour you should ensure this value is
|
||||
set to Info or Warning. This option controls the maximum level
|
||||
of logging that will be written, so Info includes Warnings and
|
||||
|
@ -1103,7 +1103,7 @@ our @options = (
|
|||
default => '-5',
|
||||
description => 'Save logging output to component files',
|
||||
help => q`
|
||||
ZoneMinder logging is now more more integrated between
|
||||
ZoneMinder logging is now more integrated between
|
||||
components and allows you to specify the destination for
|
||||
logging output and the individual levels for each. This option
|
||||
lets you control the level of logging output that goes to
|
||||
|
@ -1133,7 +1133,7 @@ our @options = (
|
|||
default => '-5',
|
||||
description => 'Save logging output to the weblog',
|
||||
help => q`
|
||||
ZoneMinder logging is now more more integrated between
|
||||
ZoneMinder logging is now more integrated between
|
||||
components and allows you to specify the destination for
|
||||
logging output and the individual levels for each. This option
|
||||
lets you control the level of logging output from the web
|
||||
|
@ -1160,7 +1160,7 @@ our @options = (
|
|||
default => '0',
|
||||
description => 'Save logging output to the database',
|
||||
help => q`
|
||||
ZoneMinder logging is now more more integrated between
|
||||
ZoneMinder logging is now more integrated between
|
||||
components and allows you to specify the destination for
|
||||
logging output and the individual levels for each. This option
|
||||
lets you control the level of logging output that is written to
|
||||
|
@ -1215,7 +1215,7 @@ our @options = (
|
|||
help => q`
|
||||
When enabled (default is on), this option will log FFMPEG messages.
|
||||
FFMPEG messages can be useful when debugging streaming issues. However,
|
||||
depending on your distro and FFMPEG version, this may also result in
|
||||
depending on your distro and FFMPEG version, this may also result in
|
||||
more logs than you'd typically like to see. If all your streams are working
|
||||
well, you may choose to turn this off.
|
||||
`,
|
||||
|
@ -1230,7 +1230,7 @@ our @options = (
|
|||
ZoneMinder components usually support debug logging available
|
||||
to help with diagnosing problems. Binary components have
|
||||
several levels of debug whereas more other components have only
|
||||
one. Normally this is disabled to minimise performance
|
||||
one. Normally this is disabled to minimize performance
|
||||
penalties and avoid filling logs too quickly. This option lets
|
||||
you switch on other options that allow you to configure
|
||||
additional debug information to be output. Components will pick
|
||||
|
@ -1491,8 +1491,8 @@ our @options = (
|
|||
default => 'ZoneMinder',
|
||||
description => 'The title displayed wherever the site references itself.',
|
||||
help => q`
|
||||
If you want the site to identify as something other than ZoneMinder, change this here.
|
||||
It can be used to more accurately identify this installation from others.
|
||||
If you want the site to identify as something other than ZoneMinder, change this here.
|
||||
It can be used to more accurately identify this installation from others.
|
||||
`,
|
||||
type => $types{string},
|
||||
category => 'web',
|
||||
|
@ -1515,8 +1515,8 @@ our @options = (
|
|||
default => 'http://zoneminder.com',
|
||||
description => 'The url used in the home/logo area of the navigation bar.',
|
||||
help => q`
|
||||
By default this takes you to the zoneminder.com website,
|
||||
but perhaps you would prefer it to take you somewhere else.
|
||||
By default this takes you to the zoneminder.com website,
|
||||
but perhaps you would prefer it to take you somewhere else.
|
||||
`,
|
||||
type => $types{string},
|
||||
category => 'web',
|
||||
|
@ -1526,7 +1526,7 @@ our @options = (
|
|||
default => 'ZoneMinder',
|
||||
description => 'The content of the home button.',
|
||||
help => q`
|
||||
You may wish to set this to empty if you are using css to put a background image on it.
|
||||
You may wish to set this to empty if you are using css to put a background image on it.
|
||||
`,
|
||||
type => $types{string},
|
||||
category => 'web',
|
||||
|
@ -1549,7 +1549,8 @@ our @options = (
|
|||
name => 'ZM_WEB_EVENT_DISK_SPACE',
|
||||
default => 'no',
|
||||
description => 'Whether to show disk space used by each event.',
|
||||
help => q`Adds another column to the listing of events
|
||||
help => q`
|
||||
Adds another column to the listing of events
|
||||
showing the disk space used by the event. This will impart a small
|
||||
overhead as it will call du on the event directory. In practice
|
||||
this overhead is fairly small but may be noticeable on IO-constrained
|
||||
|
@ -1566,7 +1567,7 @@ our @options = (
|
|||
Traditionally the main ZoneMinder web console window has
|
||||
resized itself to shrink to a size small enough to list only
|
||||
the monitors that are actually present. This is intended to
|
||||
make the window more unobtrusize but may not be to everyones
|
||||
make the window more unobtrusize but may not be to everyone's
|
||||
tastes, especially if opened in a tab in browsers which support
|
||||
this kind if layout. Switch this option off to have the console
|
||||
window size left to the users preference
|
||||
|
@ -2116,7 +2117,7 @@ our @options = (
|
|||
a remote ftp server. This option indicates that ftp transfers
|
||||
should be done in passive mode. This uses a single connection
|
||||
for all ftp activity and, whilst slower than active transfers,
|
||||
is more robust and likely to work from behind filewalls. This
|
||||
is more robust and likely to work from behind firewalls. This
|
||||
option is ignored for SFTP transfers.
|
||||
`,
|
||||
requires => [ { name => 'ZM_OPT_UPLOAD', value => 'yes' } ],
|
||||
|
@ -2642,7 +2643,7 @@ our @options = (
|
|||
help => q`
|
||||
As event images are captured they are stored to the filesystem
|
||||
with a numerical index. By default this index has three digits
|
||||
so the numbers start 001, 002 etc. This works works for most
|
||||
so the numbers start 001, 002 etc. This works for most
|
||||
scenarios as events with more than 999 frames are rarely
|
||||
captured. However if you have extremely long events and use
|
||||
external applications then you may wish to increase this to
|
||||
|
@ -2739,7 +2740,7 @@ our @options = (
|
|||
it to the ZoneMinder development team. This data will be used to
|
||||
determine things like who and where our customers are, how big their
|
||||
systems are, the underlying hardware and operating system, etc.
|
||||
This is being done for the sole purpoase of creating a better
|
||||
This is being done for the sole purpose of creating a better
|
||||
product for our target audience. This script is intended to be
|
||||
completely transparent to the end user, and can be disabled from
|
||||
the web console under Options. For more details on what information
|
||||
|
@ -2763,7 +2764,7 @@ our @options = (
|
|||
{
|
||||
name => 'ZM_TELEMETRY_LAST_UPLOAD',
|
||||
default => '',
|
||||
description => 'When the last ZoneMinder telemetry upload ocurred',
|
||||
description => 'When the last ZoneMinder telemetry upload occurred',
|
||||
help => '',
|
||||
type => $types{integer},
|
||||
readonly => 1,
|
||||
|
@ -2821,7 +2822,7 @@ our @options = (
|
|||
default => 'javascript',
|
||||
description => 'What method windows should use to refresh themselves',
|
||||
help => q`
|
||||
Many windows in Javascript need to refresh themselves to keep
|
||||
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
|
||||
|
@ -2955,7 +2956,7 @@ our @options = (
|
|||
some indication of the type of content. However this is not a
|
||||
standard part of HTML. The official method is to use OBJECT
|
||||
tags which are able to give more information allowing the
|
||||
correct media viewers etc to be loaded. However these are less
|
||||
correct media viewers etc. to be loaded. However these are less
|
||||
widely supported and content may be specifically tailored to a
|
||||
particular platform or player. This option controls whether
|
||||
media content is enclosed in EMBED tags only or whether, where
|
||||
|
@ -2979,7 +2980,7 @@ our @options = (
|
|||
browsers. When this condition occurs, ZoneMinder will write a
|
||||
warning to the log file. To get around this, one can install a browser
|
||||
plugin or extension to ignore X-Frame headers, and then the page will
|
||||
display properly. Once the plugin or extenstion has ben installed,
|
||||
display properly. Once the plugin or extension has ben installed,
|
||||
the end user may choose to turn this warning off.
|
||||
`,
|
||||
type => $types{boolean},
|
||||
|
@ -3093,7 +3094,7 @@ our @options = (
|
|||
description => 'How often (in seconds) the event listing is refreshed in the watch window',
|
||||
help => q`
|
||||
The monitor window is actually made from several frames. The
|
||||
lower framme contains a listing of the last few events for easy
|
||||
lower frame contains a listing of the last few events for easy
|
||||
access. This option determines how often this is refreshed.
|
||||
`,
|
||||
type => $types{integer},
|
||||
|
@ -3223,12 +3224,12 @@ our @options = (
|
|||
{
|
||||
name => 'ZM_WEB_H_SCALE_THUMBS',
|
||||
default => 'no',
|
||||
description => 'Scale thumbnails in events, bandwidth versus cpu in rescaling',
|
||||
description => 'Scale thumbnails in events, bandwidth versus CPU in rescaling',
|
||||
help => q`
|
||||
If unset, this option sends the whole image to the browser
|
||||
which resizes it in the window. If set the image is scaled down
|
||||
on the server before sending a reduced size image to the
|
||||
browser to conserve bandwidth at the cost of cpu on the server.
|
||||
browser to conserve bandwidth at the cost of CPU on the server.
|
||||
Note that ZM can only perform the resizing if the appropriate
|
||||
PHP graphics functionality is installed. This is usually
|
||||
available in the php-gd package.
|
||||
|
@ -3262,7 +3263,7 @@ our @options = (
|
|||
help => q`
|
||||
When viewing events an event navigation panel and progress bar
|
||||
is shown below the event itself. This allows you to jump to
|
||||
specific points in the event, but can can also dynamically
|
||||
specific points in the event, but can also dynamically
|
||||
update to display the current progress of the event replay
|
||||
itself. This progress is calculated from the actual event
|
||||
duration and is not directly linked to the replay itself, so on
|
||||
|
@ -3366,7 +3367,7 @@ our @options = (
|
|||
description => 'How often (in seconds) the event listing is refreshed in the watch window',
|
||||
help => q`
|
||||
The monitor window is actually made from several frames. The
|
||||
lower framme contains a listing of the last few events for easy
|
||||
lower frame contains a listing of the last few events for easy
|
||||
access. This option determines how often this is refreshed.
|
||||
`,
|
||||
type => $types{integer},
|
||||
|
@ -3496,12 +3497,12 @@ our @options = (
|
|||
{
|
||||
name => 'ZM_WEB_M_SCALE_THUMBS',
|
||||
default => 'yes',
|
||||
description => 'Scale thumbnails in events, bandwidth versus cpu in rescaling',
|
||||
description => 'Scale thumbnails in events, bandwidth versus CPU in rescaling',
|
||||
help => q`
|
||||
If unset, this option sends the whole image to the browser
|
||||
which resizes it in the window. If set the image is scaled down
|
||||
on the server before sending a reduced size image to the
|
||||
browser to conserve bandwidth at the cost of cpu on the server.
|
||||
browser to conserve bandwidth at the cost of CPU on the server.
|
||||
Note that ZM can only perform the resizing if the appropriate
|
||||
PHP graphics functionality is installed. This is usually
|
||||
available in the php-gd package.
|
||||
|
@ -3535,7 +3536,7 @@ our @options = (
|
|||
help => q`
|
||||
When viewing events an event navigation panel and progress bar
|
||||
is shown below the event itself. This allows you to jump to
|
||||
specific points in the event, but can can also dynamically
|
||||
specific points in the event, but can also dynamically
|
||||
update to display the current progress of the event replay
|
||||
itself. This progress is calculated from the actual event
|
||||
duration and is not directly linked to the replay itself, so on
|
||||
|
@ -3639,7 +3640,7 @@ our @options = (
|
|||
description => 'How often (in seconds) the event listing is refreshed in the watch window',
|
||||
help => q`
|
||||
The monitor window is actually made from several frames. The
|
||||
lower framme contains a listing of the last few events for easy
|
||||
lower frame contains a listing of the last few events for easy
|
||||
access. This option determines how often this is refreshed.
|
||||
`,
|
||||
type => $types{integer},
|
||||
|
@ -3768,12 +3769,12 @@ our @options = (
|
|||
{
|
||||
name => 'ZM_WEB_L_SCALE_THUMBS',
|
||||
default => 'yes',
|
||||
description => 'Scale thumbnails in events, bandwidth versus cpu in rescaling',
|
||||
description => 'Scale thumbnails in events, bandwidth versus CPU in rescaling',
|
||||
help => q`
|
||||
If unset, this option sends the whole image to the browser
|
||||
which resizes it in the window. If set the image is scaled down
|
||||
on the server before sending a reduced size image to the
|
||||
browser to conserve bandwidth at the cost of cpu on the server.
|
||||
browser to conserve bandwidth at the cost of CPU on the server.
|
||||
Note that ZM can only perform the resizing if the appropriate
|
||||
PHP graphics functionality is installed. This is usually
|
||||
available in the php-gd package.
|
||||
|
@ -3807,7 +3808,7 @@ our @options = (
|
|||
help => q`
|
||||
When viewing events an event navigation panel and progress bar
|
||||
is shown below the event itself. This allows you to jump to
|
||||
specific points in the event, but can can also dynamically
|
||||
specific points in the event, but can also dynamically
|
||||
update to display the current progress of the event replay
|
||||
itself. This progress is calculated from the actual event
|
||||
duration and is not directly linked to the replay itself, so on
|
||||
|
@ -3955,7 +3956,15 @@ our @options = (
|
|||
help => q`This will affect how long a session will be valid for since the last request. Keeping this short helps prevent session hijacking. Keeping it long allows you to stay logged in longer without refreshing the view.`,
|
||||
type => $types{integer},
|
||||
category => 'system',
|
||||
}
|
||||
},
|
||||
{
|
||||
name => 'ZM_RECORD_DIAG_IMAGES_FIFO',
|
||||
default => 'no',
|
||||
description => ' Recording intermediate alarm diagnostic use fifo instead of files (faster)',
|
||||
help => 'This tries to lessen the load of recording diag images by sending them to a memory FIFO pipe instead of creating each file.',
|
||||
type => $types{boolean},
|
||||
category => 'logging',
|
||||
},
|
||||
);
|
||||
|
||||
our %options_hash = map { ( $_->{name}, $_ ) } @options;
|
||||
|
@ -3999,7 +4008,7 @@ saveConfigToDB();
|
|||
|
||||
The ZoneMinder:ConfigData module contains the master definition of the
|
||||
ZoneMinder configuration options as well as helper methods. This module is
|
||||
intended for specialist confguration management and would not normally be
|
||||
intended for specialist configuration management and would not normally be
|
||||
used by end users.
|
||||
|
||||
The configuration held in this module, which was previously in zmconfig.pl,
|
||||
|
|
|
@ -189,7 +189,7 @@ sub moveAbs ## Up, Down, Left, Right, etc. ??? Doesn't make sense here...
|
|||
my $tilt_degrees = shift || 0;
|
||||
my $speed = shift || 1;
|
||||
Debug( "Move ABS" );
|
||||
$self->sendCmd( 'cgi-bin/ptz.cgi?action=start&code=PositionABS&channel=0&arg1='.$pan_degress.'&arg2='.$tilt_degrees.'&arg3=0&arg4='.$speed );
|
||||
$self->sendCmd( 'cgi-bin/ptz.cgi?action=start&code=PositionABS&channel=0&arg1='.$pan_degrees.'&arg2='.$tilt_degrees.'&arg3=0&arg4='.$speed );
|
||||
}
|
||||
|
||||
sub moveConUp
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
configure_file(zm_config.h.in "${CMAKE_CURRENT_BINARY_DIR}/zm_config.h" @ONLY)
|
||||
|
||||
# Group together all the source files that are used by all the binaries (zmc, zma, zmu, zms etc)
|
||||
set(ZM_BIN_SRC_FILES zm_box.cpp zm_buffer.cpp zm_camera.cpp zm_comms.cpp zm_config.cpp zm_coord.cpp zm_curl_camera.cpp zm.cpp zm_db.cpp zm_logger.cpp zm_event.cpp zm_frame.cpp zm_eventstream.cpp zm_exception.cpp zm_file_camera.cpp zm_ffmpeg_input.cpp zm_ffmpeg_camera.cpp zm_group.cpp zm_image.cpp zm_jpeg.cpp zm_libvlc_camera.cpp zm_local_camera.cpp zm_monitor.cpp zm_monitorstream.cpp zm_ffmpeg.cpp zm_mpeg.cpp zm_packet.cpp zm_packetqueue.cpp zm_poly.cpp zm_regexp.cpp zm_remote_camera.cpp zm_remote_camera_http.cpp zm_remote_camera_nvsocket.cpp zm_remote_camera_rtsp.cpp zm_rtp.cpp zm_rtp_ctrl.cpp zm_rtp_data.cpp zm_rtp_source.cpp zm_rtsp.cpp zm_rtsp_auth.cpp zm_sdp.cpp zm_signal.cpp zm_stream.cpp zm_swscale.cpp zm_thread.cpp zm_time.cpp zm_timer.cpp zm_user.cpp zm_utils.cpp zm_video.cpp zm_videostore.cpp zm_zone.cpp zm_storage.cpp zm_crypt.cpp)
|
||||
|
||||
<<<<<<< HEAD
|
||||
set(ZM_BIN_SRC_FILES zm_box.cpp zm_buffer.cpp zm_camera.cpp zm_comms.cpp zm_config.cpp zm_coord.cpp zm_curl_camera.cpp zm.cpp zm_db.cpp zm_logger.cpp zm_event.cpp zm_frame.cpp zm_eventstream.cpp zm_exception.cpp zm_file_camera.cpp zm_ffmpeg_input.cpp zm_ffmpeg_camera.cpp zm_group.cpp zm_image.cpp zm_jpeg.cpp zm_libvlc_camera.cpp zm_local_camera.cpp zm_monitor.cpp zm_monitorstream.cpp zm_ffmpeg.cpp zm_mpeg.cpp zm_packet.cpp zm_packetqueue.cpp zm_poly.cpp zm_regexp.cpp zm_remote_camera.cpp zm_remote_camera_http.cpp zm_remote_camera_nvsocket.cpp zm_remote_camera_rtsp.cpp zm_rtp.cpp zm_rtp_ctrl.cpp zm_rtp_data.cpp zm_rtp_source.cpp zm_rtsp.cpp zm_rtsp_auth.cpp zm_sdp.cpp zm_signal.cpp zm_stream.cpp zm_swscale.cpp zm_thread.cpp zm_time.cpp zm_timer.cpp zm_user.cpp zm_utils.cpp zm_video.cpp zm_videostore.cpp zm_zone.cpp zm_storage.cpp zm_fifo.cpp zm_crypt.cpp)
|
||||
|
||||
|
||||
# A fix for cmake recompiling the source files for every target.
|
||||
|
|
|
@ -0,0 +1,247 @@
|
|||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
#include <sys/file.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "zm.h"
|
||||
#include "zm_db.h"
|
||||
#include "zm_time.h"
|
||||
#include "zm_mpeg.h"
|
||||
#include "zm_signal.h"
|
||||
#include "zm_monitor.h"
|
||||
#include "zm_fifo.h"
|
||||
#define RAW_BUFFER 512
|
||||
static bool zm_fifodbg_inited = false;
|
||||
FILE *zm_fifodbg_log_fd = 0;
|
||||
char zm_fifodbg_log[PATH_MAX] = "";
|
||||
|
||||
static bool zmFifoDbgOpen(){
|
||||
if (zm_fifodbg_log_fd)
|
||||
fclose(zm_fifodbg_log_fd);
|
||||
zm_fifodbg_log_fd = NULL;
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
FifoStream::fifo_create_if_missing(zm_fifodbg_log);
|
||||
int fd = open(zm_fifodbg_log,O_WRONLY|O_NONBLOCK|O_TRUNC);
|
||||
if (fd < 0)
|
||||
return ( false );
|
||||
int res = flock(fd,LOCK_EX | LOCK_NB);
|
||||
if (res < 0)
|
||||
{
|
||||
close(fd);
|
||||
return ( false );
|
||||
}
|
||||
zm_fifodbg_log_fd = fdopen(fd,"wb");
|
||||
if (zm_fifodbg_log_fd == NULL)
|
||||
{
|
||||
close(fd);
|
||||
return ( false );
|
||||
}
|
||||
return ( true );
|
||||
}
|
||||
int zmFifoDbgInit(Monitor *monitor){
|
||||
zm_fifodbg_inited = true;
|
||||
snprintf( zm_fifodbg_log, sizeof(zm_fifodbg_log), "%s/%d/dbgpipe.log", monitor->getStorage()->Path(), monitor->Id() );
|
||||
zmFifoDbgOpen();
|
||||
return 1;
|
||||
}
|
||||
void zmFifoDbgOutput( int hex, const char * const file, const int line, const int level, const char *fstring, ... ){
|
||||
char dbg_string[8192];
|
||||
va_list arg_ptr;
|
||||
if (! zm_fifodbg_inited)
|
||||
return;
|
||||
if (! zm_fifodbg_log_fd && ! zmFifoDbgOpen())
|
||||
return;
|
||||
|
||||
char *dbg_ptr = dbg_string;
|
||||
va_start( arg_ptr, fstring );
|
||||
if ( hex )
|
||||
{
|
||||
unsigned char *data = va_arg( arg_ptr, unsigned char * );
|
||||
int len = va_arg( arg_ptr, int );
|
||||
int i;
|
||||
dbg_ptr += snprintf( dbg_ptr, sizeof(dbg_string)-(dbg_ptr-dbg_string), "%d:", len );
|
||||
for ( i = 0; i < len; i++ )
|
||||
{
|
||||
dbg_ptr += snprintf( dbg_ptr, sizeof(dbg_string)-(dbg_ptr-dbg_string), " %02x", data[i] );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dbg_ptr += vsnprintf( dbg_ptr, sizeof(dbg_string)-(dbg_ptr-dbg_string), fstring, arg_ptr );
|
||||
}
|
||||
va_end(arg_ptr);
|
||||
strncpy( dbg_ptr++, "\n", 1);
|
||||
int res = fwrite( dbg_string, dbg_ptr-dbg_string, 1, zm_fifodbg_log_fd );
|
||||
if (res != 1){
|
||||
fclose(zm_fifodbg_log_fd);
|
||||
zm_fifodbg_log_fd = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
fflush(zm_fifodbg_log_fd);
|
||||
}
|
||||
}
|
||||
bool FifoStream::sendRAWFrames(){
|
||||
static unsigned char buffer[RAW_BUFFER];
|
||||
int fd = open(stream_path,O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
Error( "Can't open %s: %s", stream_path, strerror(errno));
|
||||
return( false );
|
||||
}
|
||||
while( (bytes_read = read(fd,buffer,RAW_BUFFER)) )
|
||||
{
|
||||
if (bytes_read == 0)
|
||||
continue;
|
||||
if (bytes_read < 0)
|
||||
{
|
||||
Error( "Problem during reading: %s", strerror(errno));
|
||||
close(fd);
|
||||
return( false );
|
||||
}
|
||||
if ( fwrite( buffer, bytes_read, 1, stdout ) != 1){
|
||||
Error( "Problem during writing: %s", strerror(errno));
|
||||
close(fd);
|
||||
return( false );
|
||||
}
|
||||
fflush( stdout );
|
||||
}
|
||||
close(fd);
|
||||
return ( true );
|
||||
}
|
||||
|
||||
void FifoStream::file_create_if_missing(const char * path, bool is_fifo,bool delete_fake_fifo){
|
||||
static struct stat st;
|
||||
if(stat(path,&st) == 0){
|
||||
|
||||
if (! is_fifo || S_ISFIFO(st.st_mode) || ! delete_fake_fifo)
|
||||
return;
|
||||
Debug(5, "Supposed to be a fifo pipe but isn't, unlinking: %s", path);
|
||||
unlink(path);
|
||||
}
|
||||
int fd;
|
||||
if (! is_fifo){
|
||||
Debug(5, "Creating non fifo file as requested: %s", path);
|
||||
fd = open(path,O_CREAT|O_WRONLY,S_IRUSR|S_IWUSR);
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
Debug(5, "Making fifo file of: %s", path);
|
||||
mkfifo(path,S_IRUSR|S_IWUSR);
|
||||
}
|
||||
void FifoStream::fifo_create_if_missing(const char * path, bool delete_fake_fifo){
|
||||
file_create_if_missing(path,true,delete_fake_fifo);
|
||||
}
|
||||
bool FifoStream::sendMJEGFrames(){
|
||||
static unsigned char buffer[ZM_MAX_IMAGE_SIZE];
|
||||
int fd = open(stream_path,O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
Error( "Can't open %s: %s", stream_path, strerror(errno));
|
||||
return( false );
|
||||
}
|
||||
total_read = 0;
|
||||
while( (bytes_read = read(fd,buffer+total_read,ZM_MAX_IMAGE_SIZE-total_read)) )
|
||||
{
|
||||
if (bytes_read < 0)
|
||||
{
|
||||
Error( "Problem during reading: %s", strerror(errno));
|
||||
close(fd);
|
||||
return( false );
|
||||
}
|
||||
total_read+=bytes_read;
|
||||
}
|
||||
close(fd);
|
||||
if (total_read == 0)
|
||||
return( true );
|
||||
if (frame_count%frame_mod != 0)
|
||||
return (true );
|
||||
if (fprintf( stdout, "--ZoneMinderFrame\r\n" ) < 0 )
|
||||
{
|
||||
Error( "Problem during writing: %s", strerror(errno));
|
||||
return( false );
|
||||
}
|
||||
|
||||
fprintf( stdout, "Content-Type: image/jpeg\r\n" );
|
||||
fprintf( stdout, "Content-Length: %d\r\n\r\n", total_read );
|
||||
if ( fwrite( buffer, total_read, 1, stdout ) != 1){
|
||||
Error( "Problem during reading: %s", strerror(errno));
|
||||
return( false );
|
||||
}
|
||||
fprintf( stdout, "\r\n\r\n" );
|
||||
fflush( stdout);
|
||||
last_frame_sent = TV_2_FLOAT( now );
|
||||
frame_count++;
|
||||
return( true );
|
||||
}
|
||||
|
||||
void FifoStream::setStreamStart( const char * path ){
|
||||
stream_path = strdup(path);
|
||||
}
|
||||
void FifoStream::setStreamStart( int monitor_id, const char * format ){
|
||||
char diag_path[PATH_MAX];
|
||||
const char * filename;
|
||||
Monitor * monitor = Monitor::Load(monitor_id, false, Monitor::QUERY);
|
||||
|
||||
if (! strcmp(format,"reference") )
|
||||
{
|
||||
stream_type = MJPEG;
|
||||
filename = "diagpipe-r.jpg";
|
||||
}
|
||||
else if (! strcmp(format,"delta"))
|
||||
{
|
||||
filename = "diagpipe-d.jpg";
|
||||
stream_type = MJPEG;
|
||||
}
|
||||
else
|
||||
{
|
||||
stream_type = RAW;
|
||||
filename = "dbgpipe.log";
|
||||
}
|
||||
|
||||
snprintf( diag_path, sizeof(diag_path), "%s/%d/%s", monitor->getStorage()->Path(), monitor->Id(), filename );
|
||||
setStreamStart(diag_path);
|
||||
}
|
||||
void FifoStream::runStream(){
|
||||
if (stream_type == MJPEG)
|
||||
fprintf( stdout, "Content-Type: multipart/x-mixed-replace;boundary=ZoneMinderFrame\r\n\r\n" );
|
||||
else
|
||||
fprintf( stdout, "Content-Type: text/html\r\n\r\n" );
|
||||
|
||||
char lock_file[PATH_MAX];
|
||||
strcpy(lock_file,stream_path);
|
||||
strcat(lock_file,".rlock");
|
||||
file_create_if_missing(lock_file,false);
|
||||
int fd_lock = open(lock_file,O_RDONLY);
|
||||
if (fd_lock < 0)
|
||||
{
|
||||
Error( "Can't open %s: %s", lock_file, strerror(errno));
|
||||
return;
|
||||
}
|
||||
int res = flock(fd_lock,LOCK_EX | LOCK_NB);
|
||||
if (res < 0)
|
||||
{
|
||||
Error( "Flocking problem on %s: - %s", lock_file, strerror(errno) );
|
||||
close(fd_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
while( !zm_terminate )
|
||||
{
|
||||
gettimeofday( &now, NULL );
|
||||
checkCommandQueue();
|
||||
if (stream_type == MJPEG)
|
||||
{
|
||||
if (! sendMJEGFrames())
|
||||
zm_terminate = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (! sendRAWFrames())
|
||||
zm_terminate = true;
|
||||
}
|
||||
}
|
||||
close(fd_lock);
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
#ifndef ZM_FIFO_H
|
||||
#define ZM_FIFO_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "zm.h"
|
||||
#include "zm_image.h"
|
||||
#include "zm_monitor.h"
|
||||
#include "zm_stream.h"
|
||||
|
||||
|
||||
#define zmFifoDbgPrintf(level,params...) {\
|
||||
zmFifoDbgOutput( 0, __FILE__, __LINE__, level, ##params );\
|
||||
}
|
||||
|
||||
#ifndef ZM_DBG_OFF
|
||||
#define FifoDebug(level,params...) zmFifoDbgPrintf(level,##params)
|
||||
#else
|
||||
#define FifoDebug(level,params...)
|
||||
#endif
|
||||
void zmFifoDbgOutput( int hex, const char * const file, const int line, const int level, const char *fstring, ... ) __attribute__ ((format(printf, 5, 6)));
|
||||
int zmFifoDbgInit(Monitor * monitor);
|
||||
|
||||
class FifoStream : public StreamBase
|
||||
{
|
||||
|
||||
private:
|
||||
char * stream_path;
|
||||
int fd;
|
||||
int total_read;
|
||||
int bytes_read;
|
||||
unsigned int frame_count;
|
||||
static void file_create_if_missing(const char * path, bool is_fifo, bool delete_fake_fifo=true);
|
||||
|
||||
protected:
|
||||
typedef enum { MJPEG, RAW } StreamType;
|
||||
StreamType stream_type;
|
||||
bool sendMJEGFrames( );
|
||||
bool sendRAWFrames( );
|
||||
void processCommand( const CmdMsg *msg ) {};
|
||||
|
||||
public:
|
||||
FifoStream(){
|
||||
|
||||
|
||||
}
|
||||
static void fifo_create_if_missing(const char * path,bool delete_fake_fifo=true);
|
||||
void setStreamStart( const char * path );
|
||||
void setStreamStart( int monitor_id, const char * format );
|
||||
|
||||
void runStream();
|
||||
};
|
||||
#endif
|
|
@ -24,6 +24,7 @@
|
|||
#include "zm_rgb.h"
|
||||
#include "zm_ffmpeg.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
@ -957,7 +958,7 @@ cinfo->out_color_space = JCS_RGB;
|
|||
return( true );
|
||||
}
|
||||
|
||||
// Multiple calling formats to permit inclusion (or not) of both quality_override and timestamp (exif), with suitable defaults.
|
||||
// Multiple calling formats to permit inclusion (or not) of non blocking, quality_override and timestamp (exif), with suitable defaults.
|
||||
// Note quality=zero means default
|
||||
|
||||
bool Image::WriteJpeg(const char *filename, int quality_override) const {
|
||||
|
@ -966,33 +967,71 @@ bool Image::WriteJpeg(const char *filename, int quality_override) const {
|
|||
bool Image::WriteJpeg(const char *filename) const {
|
||||
return Image::WriteJpeg(filename, 0, (timeval){0,0});
|
||||
}
|
||||
bool Image::WriteJpeg(const char *filename, bool on_blocking_abort) const {
|
||||
return Image::WriteJpeg(filename, 0, (timeval){0,0}, on_blocking_abort);
|
||||
}
|
||||
bool Image::WriteJpeg(const char *filename, struct timeval timestamp) const {
|
||||
return Image::WriteJpeg(filename, 0, timestamp);
|
||||
}
|
||||
|
||||
bool Image::WriteJpeg(const char *filename, int quality_override, struct timeval timestamp) const {
|
||||
return Image::WriteJpeg(filename, quality_override, timestamp, false);
|
||||
}
|
||||
bool Image::WriteJpeg(const char *filename, int quality_override, struct timeval timestamp, bool on_blocking_abort) const {
|
||||
if ( config.colour_jpeg_files && colours == ZM_COLOUR_GRAY8 ) {
|
||||
Image temp_image(*this);
|
||||
temp_image.Colourise(ZM_COLOUR_RGB24, ZM_SUBPIX_ORDER_RGB);
|
||||
return temp_image.WriteJpeg(filename, quality_override, timestamp);
|
||||
return temp_image.WriteJpeg(filename, quality_override, timestamp, on_blocking_abort);
|
||||
}
|
||||
int quality = quality_override?quality_override:config.jpeg_file_quality;
|
||||
|
||||
struct jpeg_compress_struct *cinfo = writejpg_ccinfo[quality];
|
||||
FILE *outfile =NULL;
|
||||
static int raw_fd = 0;
|
||||
bool need_create_comp = false;
|
||||
raw_fd = 0;
|
||||
|
||||
if ( !cinfo ) {
|
||||
cinfo = writejpg_ccinfo[quality] = new jpeg_compress_struct;
|
||||
cinfo->err = jpeg_std_error( &jpg_err.pub );
|
||||
jpg_err.pub.error_exit = zm_jpeg_error_exit;
|
||||
jpg_err.pub.emit_message = zm_jpeg_emit_message;
|
||||
jpeg_create_compress( cinfo );
|
||||
need_create_comp=true;
|
||||
}
|
||||
if (! on_blocking_abort) {
|
||||
jpg_err.pub.error_exit = zm_jpeg_error_exit;
|
||||
jpg_err.pub.emit_message = zm_jpeg_emit_message;
|
||||
} else {
|
||||
jpg_err.pub.error_exit = zm_jpeg_error_silent;
|
||||
jpg_err.pub.emit_message = zm_jpeg_emit_silence;
|
||||
if (setjmp( jpg_err.setjmp_buffer ) ) {
|
||||
jpeg_abort_compress( cinfo );
|
||||
Debug( 5, "Aborted a write mid-stream and %s and %d", (outfile == NULL) ? "closing file" : "file not opened", raw_fd );
|
||||
if (raw_fd)
|
||||
close(raw_fd);
|
||||
if (outfile)
|
||||
fclose( outfile );
|
||||
return ( false );
|
||||
}
|
||||
}
|
||||
if (need_create_comp)
|
||||
jpeg_create_compress( cinfo );
|
||||
|
||||
if (! on_blocking_abort) {
|
||||
if ( (outfile = fopen(filename, "wb")) == NULL ) {
|
||||
Error( "Can't open %s for writing: %s", filename, strerror(errno) );
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
raw_fd = open(filename,O_WRONLY|O_NONBLOCK|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
|
||||
if (raw_fd < 0)
|
||||
return ( false );
|
||||
outfile = fdopen(raw_fd,"wb");
|
||||
if (outfile == NULL) {
|
||||
close(raw_fd);
|
||||
return( false );
|
||||
}
|
||||
}
|
||||
|
||||
FILE *outfile;
|
||||
if ( (outfile = fopen(filename, "wb")) == NULL ) {
|
||||
Error("Can't open %s: %s", filename, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
jpeg_stdio_dest( cinfo, outfile );
|
||||
|
||||
cinfo->image_width = width; /* image width and height, in pixels */
|
||||
|
|
|
@ -218,9 +218,12 @@ public:
|
|||
bool ReadJpeg( const char *filename, unsigned int p_colours, unsigned int p_subpixelorder);
|
||||
|
||||
bool WriteJpeg ( const char *filename) const;
|
||||
bool WriteJpeg ( const char *filename, bool on_blocking_abort) const;
|
||||
bool WriteJpeg ( const char *filename, int quality_override ) const;
|
||||
bool WriteJpeg ( const char *filename, struct timeval timestamp ) const;
|
||||
bool WriteJpeg ( const char *filename, int quality_override, struct timeval timestamp ) const;
|
||||
bool WriteJpeg ( const char *filename, int quality_override, struct timeval timestamp, bool on_blocking_abort ) const;
|
||||
|
||||
|
||||
bool DecodeJpeg( const JOCTET *inbuffer, int inbuffer_size, unsigned int p_colours, unsigned int p_subpixelorder);
|
||||
bool EncodeJpeg( JOCTET *outbuffer, int *outbuffer_size, int quality_override=0 ) const;
|
||||
|
|
|
@ -30,6 +30,13 @@ extern "C"
|
|||
|
||||
static int jpeg_err_count = 0;
|
||||
|
||||
void zm_jpeg_error_silent( j_common_ptr cinfo ){
|
||||
zm_error_ptr zmerr = (zm_error_ptr)cinfo->err;
|
||||
longjmp( zmerr->setjmp_buffer, 1 );
|
||||
}
|
||||
void zm_jpeg_emit_silence( j_common_ptr cinfo, int msg_level ){
|
||||
}
|
||||
|
||||
void zm_jpeg_error_exit( j_common_ptr cinfo )
|
||||
{
|
||||
static char buffer[JMSG_LENGTH_MAX];
|
||||
|
|
|
@ -38,6 +38,8 @@ struct zm_error_mgr
|
|||
|
||||
typedef struct zm_error_mgr *zm_error_ptr;
|
||||
|
||||
void zm_jpeg_error_silent( j_common_ptr cinfo );
|
||||
void zm_jpeg_emit_silence( j_common_ptr cinfo, int msg_level );
|
||||
void zm_jpeg_error_exit( j_common_ptr cinfo );
|
||||
void zm_jpeg_emit_message( j_common_ptr cinfo, int msg_level );
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#if HAVE_LIBAVFORMAT
|
||||
#include "zm_ffmpeg_camera.h"
|
||||
#endif // HAVE_LIBAVFORMAT
|
||||
#include "zm_fifo.h"
|
||||
#if HAVE_LIBVLC
|
||||
#include "zm_libvlc_camera.h"
|
||||
#endif // HAVE_LIBVLC
|
||||
|
@ -517,8 +518,12 @@ Monitor::Monitor(
|
|||
ReloadLinkedMonitors(p_linked_monitors);
|
||||
|
||||
if ( config.record_diag_images ) {
|
||||
diag_path_r = stringtf("%s/%d/diag-r.jpg", storage->Path(), id);
|
||||
diag_path_d = stringtf("%s/%d/diag-d.jpg", storage->Path(), id);
|
||||
diag_path_r = stringtf(config.record_diag_images_fifo ? "%s/%d/diagpipe-r.jpg" : "%s/%d/diag-r.jpg", storage->Path(), id);
|
||||
diag_path_d = stringtf(config.record_diag_images_fifo ? "%s/%d/diagpipe-d.jpg" : "%s/%d/diag-d.jpg", storage->Path(), id);
|
||||
if (config.record_diag_images_fifo){
|
||||
FifoStream::fifo_create_if_missing(diag_path_r.c_str());
|
||||
FifoStream::fifo_create_if_missing(diag_path_d.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
} // end if purpose == ANALYSIS
|
||||
|
@ -2614,8 +2619,8 @@ unsigned int Monitor::DetectMotion(const Image &comp_image, Event::StringSet &zo
|
|||
ref_image.Delta(comp_image, &delta_image);
|
||||
|
||||
if ( config.record_diag_images ) {
|
||||
ref_image.WriteJpeg(diag_path_r.c_str());
|
||||
delta_image.WriteJpeg(diag_path_d.c_str());
|
||||
ref_image.WriteJpeg(diag_path_r.c_str(), config.record_diag_images_fifo);
|
||||
delta_image.WriteJpeg(diag_path_d.c_str(), config.record_diag_images_fifo);
|
||||
}
|
||||
|
||||
// Blank out all exclusion zones
|
||||
|
|
|
@ -394,10 +394,15 @@ bool MonitorStream::sendFrame(Image *image, struct timeval *timestamp) {
|
|||
img_buffer_size = send_image->Size();
|
||||
break;
|
||||
case STREAM_ZIP :
|
||||
#if HAVE_ZLIB_H
|
||||
fputs("Content-Type: image/x-rgbz\r\n",stdout);
|
||||
unsigned long zip_buffer_size;
|
||||
send_image->Zip(img_buffer, &zip_buffer_size);
|
||||
img_buffer_size = zip_buffer_size;
|
||||
#else
|
||||
Error("zlib is required for zipped images. Falling back to raw image");
|
||||
type = STREAM_RAW;
|
||||
#endif // HAVE_ZLIB_H
|
||||
break;
|
||||
default :
|
||||
Error("Unexpected frame type %d", type);
|
||||
|
@ -794,6 +799,8 @@ void MonitorStream::SingleImageRaw( int scale ) {
|
|||
fwrite( snap_image->Buffer(), snap_image->Size(), 1, stdout );
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_ZLIB_H
|
||||
void MonitorStream::SingleImageZip( int scale ) {
|
||||
unsigned long img_buffer_size = 0;
|
||||
static Bytef img_buffer[ZM_MAX_IMAGE_SIZE];
|
||||
|
@ -816,3 +823,4 @@ void MonitorStream::SingleImageZip( int scale ) {
|
|||
fprintf( stdout, "Content-Type: image/x-rgbz\r\n\r\n" );
|
||||
fwrite( img_buffer, img_buffer_size, 1, stdout );
|
||||
}
|
||||
#endif // HAVE_ZLIB_H
|
||||
|
|
|
@ -55,7 +55,9 @@ class MonitorStream : public StreamBase {
|
|||
void processCommand( const CmdMsg *msg );
|
||||
void SingleImage( int scale=100 );
|
||||
void SingleImageRaw( int scale=100 );
|
||||
#ifdef HAVE_ZLIB_H
|
||||
void SingleImageZip( int scale=100 );
|
||||
#endif
|
||||
|
||||
public:
|
||||
MonitorStream() :
|
||||
|
|
|
@ -1011,7 +1011,6 @@ int VideoStore::writeAudioFramePacket(AVPacket *ipkt) {
|
|||
}
|
||||
zm_dump_frame(out_frame, "Out frame after resample");
|
||||
|
||||
out_frame->pts = in_frame->pts;
|
||||
// out_frame pts is in the input pkt pts... needs to be adjusted before sending to the encoder
|
||||
if ( out_frame->pts != AV_NOPTS_VALUE ) {
|
||||
if ( !audio_first_pts ) {
|
||||
|
@ -1065,6 +1064,8 @@ int VideoStore::writeAudioFramePacket(AVPacket *ipkt) {
|
|||
return 0;
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
// These should be set by encoder. They may not directly relate to ipkt due to buffering in codec.
|
||||
opkt.duration = av_rescale_q(opkt.duration,
|
||||
audio_in_stream->time_base,
|
||||
audio_out_stream->time_base);
|
||||
|
@ -1074,6 +1075,7 @@ int VideoStore::writeAudioFramePacket(AVPacket *ipkt) {
|
|||
opkt.dts = av_rescale_q(opkt.dts,
|
||||
audio_in_stream->time_base,
|
||||
audio_out_stream->time_base);
|
||||
#endif
|
||||
dumpPacket(audio_out_stream, &opkt, "raw opkt");
|
||||
|
||||
} else {
|
||||
|
@ -1179,13 +1181,32 @@ int VideoStore::resample_audio() {
|
|||
Debug(2, "Converting %d to %d samples using swresample",
|
||||
in_frame->nb_samples, out_frame->nb_samples);
|
||||
ret = swr_convert_frame(resample_ctx, out_frame, in_frame);
|
||||
zm_dump_frame(out_frame, "Out frame after convert");
|
||||
|
||||
if ( ret < 0 ) {
|
||||
Error("Could not resample frame (error '%s')",
|
||||
av_make_error_string(ret).c_str());
|
||||
return 0;
|
||||
}
|
||||
zm_dump_frame(out_frame, "Out frame after convert");
|
||||
|
||||
|
||||
#if 0
|
||||
// out_frame pts is in the input pkt pts... needs to be adjusted before sending to the encoder
|
||||
if ( out_frame->pts != AV_NOPTS_VALUE ) {
|
||||
if ( !audio_first_pts ) {
|
||||
audio_first_pts = out_frame->pts;
|
||||
Debug(1, "No audio_first_pts setting to %" PRId64, audio_first_pts);
|
||||
out_frame->pts = 0;
|
||||
} else {
|
||||
out_frame->pts = out_frame->pts - audio_first_pts;
|
||||
}
|
||||
//
|
||||
} else {
|
||||
// sending AV_NOPTS_VALUE doesn't really work but we seem to get it in ffmpeg 2.8
|
||||
out_frame->pts = audio_next_pts;
|
||||
}
|
||||
audio_next_pts = out_frame->pts + out_frame->nb_samples;
|
||||
#endif
|
||||
|
||||
if ((ret = av_audio_fifo_realloc(fifo, av_audio_fifo_size(fifo) + out_frame->nb_samples)) < 0) {
|
||||
Error("Could not reallocate FIFO");
|
||||
return 0;
|
||||
|
@ -1193,7 +1214,8 @@ int VideoStore::resample_audio() {
|
|||
/** Store the new samples in the FIFO buffer. */
|
||||
ret = av_audio_fifo_write(fifo, (void **)out_frame->data, out_frame->nb_samples);
|
||||
if ( ret < out_frame->nb_samples ) {
|
||||
Error("Could not write data to FIFO on %d written, expecting %d", ret, out_frame->nb_samples);
|
||||
Error("Could not write data to FIFO. %d written, expecting %d. Reason %s",
|
||||
ret, out_frame->nb_samples, av_make_error_string(ret).c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1210,6 +1232,17 @@ int VideoStore::resample_audio() {
|
|||
return 0;
|
||||
}
|
||||
out_frame->nb_samples = frame_size;
|
||||
// resampling changes the duration because the timebase is 1/samples
|
||||
if ( in_frame->pts != AV_NOPTS_VALUE ) {
|
||||
out_frame->pkt_duration = av_rescale_q(
|
||||
in_frame->pkt_duration,
|
||||
audio_in_stream->time_base,
|
||||
audio_out_stream->time_base);
|
||||
out_frame->pts = av_rescale_q(
|
||||
in_frame->pts,
|
||||
audio_in_stream->time_base,
|
||||
audio_out_stream->time_base);
|
||||
}
|
||||
#else
|
||||
#if defined(HAVE_LIBAVRESAMPLE)
|
||||
ret = avresample_convert(resample_ctx, NULL, 0, 0, in_frame->data,
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "zm_zone.h"
|
||||
#include "zm_image.h"
|
||||
#include "zm_monitor.h"
|
||||
#include "zm_fifo.h"
|
||||
|
||||
|
||||
void Zone::Setup(
|
||||
|
@ -112,8 +113,10 @@ void Zone::Setup(
|
|||
}
|
||||
|
||||
if ( config.record_diag_images ) {
|
||||
snprintf(diag_path, sizeof(diag_path), "%s/diag-%d-poly.jpg", monitor->getStorage()->Path(), id);
|
||||
pg_image->WriteJpeg(diag_path);
|
||||
snprintf(diag_path, sizeof(diag_path), config.record_diag_images_fifo ? "%s/diagpipe-%d-poly.jpg" : "%s/diag-%d-poly.jpg", monitor->getStorage()->Path(), id);
|
||||
if (config.record_diag_images_fifo)
|
||||
FifoStream::fifo_create_if_missing(diag_path);
|
||||
pg_image->WriteJpeg(diag_path, config.record_diag_images_fifo);
|
||||
} else {
|
||||
diag_path[0] = 0;
|
||||
}
|
||||
|
@ -232,7 +235,7 @@ bool Zone::CheckAlarms(const Image *delta_image) {
|
|||
std_alarmedpixels(diff_image, pg_image, &alarm_pixels, &pixel_diff_count);
|
||||
|
||||
if ( config.record_diag_images )
|
||||
diff_image->WriteJpeg(diag_path);
|
||||
diff_image->WriteJpeg(diag_path, config.record_diag_images_fifo);
|
||||
|
||||
if ( pixel_diff_count && alarm_pixels )
|
||||
pixel_diff = pixel_diff_count/alarm_pixels;
|
||||
|
@ -240,6 +243,10 @@ bool Zone::CheckAlarms(const Image *delta_image) {
|
|||
Debug(5, "Got %d alarmed pixels, need %d -> %d, avg pixel diff %d",
|
||||
alarm_pixels, min_alarm_pixels, max_alarm_pixels, pixel_diff);
|
||||
|
||||
if (config.record_diag_images_fifo)
|
||||
FifoDebug( 5, "{\"zone\":%d,\"type\":\"ALRM\",\"pixels\":%d,\"avg_diff\":%d}", id,alarm_pixels, pixel_diff );
|
||||
|
||||
|
||||
if ( alarm_pixels ) {
|
||||
if ( min_alarm_pixels && (alarm_pixels < (unsigned int)min_alarm_pixels) ) {
|
||||
/* Not enough pixels alarmed */
|
||||
|
@ -316,11 +323,14 @@ bool Zone::CheckAlarms(const Image *delta_image) {
|
|||
}
|
||||
|
||||
if ( config.record_diag_images )
|
||||
diff_image->WriteJpeg(diag_path);
|
||||
diff_image->WriteJpeg(diag_path, config.record_diag_images_fifo);
|
||||
|
||||
Debug(5, "Got %d filtered pixels, need %d -> %d",
|
||||
alarm_filter_pixels, min_filter_pixels, max_filter_pixels);
|
||||
|
||||
if (config.record_diag_images_fifo)
|
||||
FifoDebug( 5, "{\"zone\":%d,\"type\":\"FILT\",\"pixels\":%d}", id, alarm_filter_pixels );
|
||||
|
||||
if ( alarm_filter_pixels ) {
|
||||
if ( min_filter_pixels && (alarm_filter_pixels < min_filter_pixels) ) {
|
||||
/* Not enough pixels alarmed */
|
||||
|
@ -542,7 +552,7 @@ bool Zone::CheckAlarms(const Image *delta_image) {
|
|||
}
|
||||
}
|
||||
if ( config.record_diag_images )
|
||||
diff_image->WriteJpeg(diag_path);
|
||||
diff_image->WriteJpeg(diag_path, config.record_diag_images_fifo);
|
||||
|
||||
if ( !alarm_blobs ) {
|
||||
return false;
|
||||
|
@ -551,6 +561,9 @@ bool Zone::CheckAlarms(const Image *delta_image) {
|
|||
Debug(5, "Got %d raw blob pixels, %d raw blobs, need %d -> %d, %d -> %d",
|
||||
alarm_blob_pixels, alarm_blobs, min_blob_pixels, max_blob_pixels, min_blobs, max_blobs);
|
||||
|
||||
if (config.record_diag_images_fifo)
|
||||
FifoDebug( 5, "{\"zone\":%d,\"type\":\"RBLB\",\"pixels\":%d,\"blobs\":%d}", id, alarm_blob_pixels, alarm_blobs );
|
||||
|
||||
// Now eliminate blobs under the threshold
|
||||
for ( int i = 1; i < WHITE; i++ ) {
|
||||
BlobStats *bs = &blob_stats[i];
|
||||
|
@ -587,10 +600,12 @@ bool Zone::CheckAlarms(const Image *delta_image) {
|
|||
} // end if bs_count
|
||||
} // end for i < WHITE
|
||||
if ( config.record_diag_images )
|
||||
diff_image->WriteJpeg(diag_path);
|
||||
diff_image->WriteJpeg(diag_path, config.record_diag_images_fifo);
|
||||
|
||||
Debug(5, "Got %d blob pixels, %d blobs, need %d -> %d, %d -> %d",
|
||||
alarm_blob_pixels, alarm_blobs, min_blob_pixels, max_blob_pixels, min_blobs, max_blobs);
|
||||
if (config.record_diag_images_fifo)
|
||||
FifoDebug( 5, "{\"zone\":%d,\"type\":\"FBLB\",\"pixels\":%d,\"blobs\":%d}", id, alarm_blob_pixels, alarm_blobs );
|
||||
|
||||
if ( alarm_blobs ) {
|
||||
if ( min_blobs && (alarm_blobs < min_blobs) ) {
|
||||
|
|
|
@ -56,6 +56,7 @@ behind.
|
|||
#include "zm_db.h"
|
||||
#include "zm_signal.h"
|
||||
#include "zm_monitor.h"
|
||||
#include "zm_fifo.h"
|
||||
|
||||
void Usage() {
|
||||
fprintf(stderr, "zma -m <monitor_id>\n");
|
||||
|
@ -129,6 +130,7 @@ int main( int argc, char *argv[] ) {
|
|||
hwcaps_detect();
|
||||
|
||||
Monitor *monitor = Monitor::Load(id, true, Monitor::ANALYSIS);
|
||||
zmFifoDbgInit( monitor );
|
||||
|
||||
if ( monitor ) {
|
||||
Info("In mode %d/%d, warming up", monitor->GetFunction(), monitor->Enabled());
|
||||
|
|
10
src/zms.cpp
10
src/zms.cpp
|
@ -28,6 +28,7 @@
|
|||
#include "zm_monitor.h"
|
||||
#include "zm_monitorstream.h"
|
||||
#include "zm_eventstream.h"
|
||||
#include "zm_fifo.h"
|
||||
|
||||
bool ValidateAccess( User *user, int mon_id ) {
|
||||
bool allowed = true;
|
||||
|
@ -54,7 +55,7 @@ int main( int argc, const char *argv[] ) {
|
|||
|
||||
srand( getpid() * time( 0 ) );
|
||||
|
||||
enum { ZMS_UNKNOWN, ZMS_MONITOR, ZMS_EVENT } source = ZMS_UNKNOWN;
|
||||
enum { ZMS_UNKNOWN, ZMS_MONITOR, ZMS_EVENT, ZMS_FIFO } source = ZMS_UNKNOWN;
|
||||
enum { ZMS_JPEG, ZMS_MPEG, ZMS_RAW, ZMS_ZIP, ZMS_SINGLE } mode = ZMS_JPEG;
|
||||
char format[32] = "";
|
||||
int monitor_id = 0;
|
||||
|
@ -111,6 +112,8 @@ int main( int argc, const char *argv[] ) {
|
|||
value = (char *)"";
|
||||
if ( !strcmp(name, "source") ) {
|
||||
source = !strcmp(value, "event")?ZMS_EVENT:ZMS_MONITOR;
|
||||
if (! strcmp( value,"fifo") )
|
||||
source = ZMS_FIFO;
|
||||
} else if ( !strcmp(name, "mode") ) {
|
||||
mode = !strcmp(value, "jpeg")?ZMS_JPEG:ZMS_MPEG;
|
||||
mode = !strcmp(value, "raw")?ZMS_RAW:mode;
|
||||
|
@ -284,6 +287,11 @@ int main( int argc, const char *argv[] ) {
|
|||
#endif // HAVE_LIBAVCODEC
|
||||
}
|
||||
stream.runStream();
|
||||
} else if (source == ZMS_FIFO ) {
|
||||
FifoStream stream;
|
||||
stream.setStreamMaxFPS( maxfps );
|
||||
stream.setStreamStart( monitor_id, format );
|
||||
stream.runStream();
|
||||
} else if ( source == ZMS_EVENT ) {
|
||||
if ( ! event_id ) {
|
||||
Fatal( "Can't view an event without specifying an event_id." );
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
// a formatting string. If the dynamic element is a number you will usually need to use a variable
|
||||
// replacement also as described below.
|
||||
// c) Variable replacements are used in conjunction with complex replacements and involve the generation
|
||||
// of a singular or plural noun depending on the number passed into the zmVlang function. See the
|
||||
// of a singular or plural noun depending on the number passed into the zmVlang function. See the
|
||||
// the zmVlang section below for a further description of this.
|
||||
// d) Optional strings which can be used to replace the prompts and/or help text for the Options section
|
||||
// of the web interface. These are not listed below as they are quite large and held in the database
|
||||
|
@ -40,7 +40,7 @@
|
|||
// quite easily from the Config table in the database if necessary.
|
||||
// 3. The tokens listed below are not used to build up phrases or sentences from single words. Therefore
|
||||
// you can safely assume that a single word token will only be used in that context.
|
||||
// 4. In new language files, or if you are changing only a few words or phrases it makes sense from a
|
||||
// 4. In new language files, or if you are changing only a few words or phrases it makes sense from a
|
||||
// maintenance point of view to include the original language file and override the old definitions rather
|
||||
// than copy all the language tokens across. To do this change the line below to whatever your base language
|
||||
// is and uncomment it.
|
||||
|
@ -57,10 +57,10 @@
|
|||
// If you do need to change your locale, be aware that the format of this function
|
||||
// is subtlely different in versions of PHP before and after 4.3.0, see
|
||||
// http://uk2.php.net/manual/en/function.setlocale.php for details.
|
||||
// Also be aware that changing the whole locale may affect some floating point or decimal
|
||||
// Also be aware that changing the whole locale may affect some floating point or decimal
|
||||
// arithmetic in the database, if this is the case change only the individual locale areas
|
||||
// that don't affect this rather than all at once. See the examples below.
|
||||
// Finally, depending on your setup, PHP may not enjoy have multiple locales in a shared
|
||||
// Finally, depending on your setup, PHP may not enjoy have multiple locales in a shared
|
||||
// threaded environment, if you get funny errors it may be this.
|
||||
//
|
||||
// Examples
|
||||
|
@ -771,7 +771,7 @@ $SLANG = array(
|
|||
'Update' => 'Update',
|
||||
'Upload' => 'Upload',
|
||||
'Updated' => 'Updated',
|
||||
'UsedPlugins' => 'Used Plugins',
|
||||
'UsedPlugins' => 'Used Plugins',
|
||||
'UseFilterExprsPost' => ' filter expressions', // This is used at the end of the phrase 'use N filter expressions'
|
||||
'UseFilterExprsPre' => 'Use ', // This is used at the beginning of the phrase 'use N filter expressions'
|
||||
'UseFilter' => 'Use Filter',
|
||||
|
@ -850,7 +850,7 @@ $CLANG = array(
|
|||
'VersionMismatch' => 'Version mismatch, system is version %1$s, database is %2$s.',
|
||||
);
|
||||
|
||||
// The next section allows you to describe a series of word ending and counts used to
|
||||
// The next section allows you to describe a series of word ending and counts used to
|
||||
// generate the correctly conjugated forms of words depending on a count that is associated
|
||||
// with that word.
|
||||
// This intended to allow phrases such a '0 potatoes', '1 potato', '2 potatoes' etc to
|
||||
|
@ -891,7 +891,7 @@ $VLANG = array(
|
|||
// with variable counts. This is used to conjugate the Vlang arrays above with a number passed
|
||||
// in to generate the correct noun form.
|
||||
//
|
||||
// In languages such as English this is fairly simple
|
||||
// In languages such as English this is fairly simple
|
||||
// Note this still has to be used with printf etc to get the right formatting
|
||||
function zmVlang( $langVarArray, $count )
|
||||
{
|
||||
|
@ -909,9 +909,9 @@ function zmVlang( $langVarArray, $count )
|
|||
// This is an version that could be used in the Russian example above
|
||||
// The rules are that the first word form is used if the count ends in
|
||||
// 0, 5-9 or 11-19. The second form is used then the count ends in 1
|
||||
// (not including 11 as above) and the third form is used when the
|
||||
// (not including 11 as above) and the third form is used when the
|
||||
// count ends in 2-4, again excluding any values ending in 12-14.
|
||||
//
|
||||
//
|
||||
// function zmVlang( $langVarArray, $count )
|
||||
// {
|
||||
// $secondlastdigit = substr( $count, -2, 1 );
|
||||
|
@ -919,7 +919,7 @@ function zmVlang( $langVarArray, $count )
|
|||
// // or
|
||||
// // $secondlastdigit = ($count/10)%10;
|
||||
// // $lastdigit = $count%10;
|
||||
//
|
||||
//
|
||||
// // Get rid of the special cases first, the teens
|
||||
// if ( $secondlastdigit == 1 && $lastdigit != 0 )
|
||||
// {
|
||||
|
@ -953,7 +953,7 @@ function zmVlang( $langVarArray, $count )
|
|||
// die( 'Error, unable to correlate variable language string' );
|
||||
// }
|
||||
|
||||
// This is an example of how the function is used in the code which you can uncomment and
|
||||
// This is an example of how the function is used in the code which you can uncomment and
|
||||
// use to test your custom function.
|
||||
//$monitors = array();
|
||||
//$monitors[] = 1; // Choose any number
|
||||
|
@ -970,17 +970,17 @@ $OLANG = array(
|
|||
"\"reorder_queue_size=nnn\" Set number of packets to buffer for handling of reordered packets~~~~".
|
||||
"\"loglevel=debug\" Set verbosity of FFmpeg (quiet, panic, fatal, error, warning, info, verbose, debug)"
|
||||
),
|
||||
'OPTIONS_RTSPTrans' => array(
|
||||
'OPTIONS_RTSPTrans' => array(
|
||||
'Help' => "This sets the RTSP Transport Protocol for FFmpeg.~~ ".
|
||||
"TCP - Use TCP (interleaving within the RTSP control channel) as transport protocol.~~".
|
||||
"UDP - Use UDP as transport protocol. Higher resolution cameras have experienced some 'smearing' while using UDP, if so try TCP~~".
|
||||
"UDP Multicast - Use UDP Multicast as transport protocol~~".
|
||||
"HTTP - Use HTTP tunneling as transport protocol, which is useful for passing proxies.~~"
|
||||
"TCP - Use TCP (interleaving within the RTSP control channel) as transport protocol.~~".
|
||||
"UDP - Use UDP as transport protocol. Higher resolution cameras have experienced some 'smearing' while using UDP, if so try TCP~~".
|
||||
"UDP Multicast - Use UDP Multicast as transport protocol~~".
|
||||
"HTTP - Use HTTP tunneling as transport protocol, which is useful for passing proxies.~~"
|
||||
),
|
||||
'OPTIONS_LIBVLC' => array(
|
||||
'Help' => "Parameters in this field are passed on to libVLC. Multiple parameters can be separated by ,~~ ".
|
||||
"Examples (do not enter quotes)~~~~".
|
||||
"\"--rtp-client-port=nnn\" Set local port to use for rtp data~~~~".
|
||||
"\"--rtp-client-port=nnn\" Set local port to use for rtp data~~~~".
|
||||
"\"--verbose=2\" Set verbosity of libVLC"
|
||||
),
|
||||
'OPTIONS_EXIF' => array(
|
||||
|
@ -989,7 +989,7 @@ $OLANG = array(
|
|||
'OPTIONS_RTSPDESCRIBE' => array(
|
||||
'Help' => "Sometimes, during the initial RTSP handshake, the camera will send an updated media URL. ".
|
||||
"Enable this option to tell ZoneMinder to use this URL. Disable this option to ignore the ".
|
||||
"value from the camera and use the value as entered in the monitor configuration~~~~".
|
||||
"value from the camera and use the value as entered in the monitor configuration~~~~".
|
||||
"Generally this should be enabled. However, there are cases where the camera can get its".
|
||||
"own URL incorrect, such as when the camera is streaming through a firewall"),
|
||||
'OPTIONS_MAXFPS' => array(
|
||||
|
@ -997,12 +997,12 @@ $OLANG = array(
|
|||
"Failure to adhere to these limitations will cause a delay in live video, irregular frame skipping, ".
|
||||
"and missed events~~".
|
||||
"For streaming IP cameras, do not use this field to reduce the frame rate. Set the frame rate in the".
|
||||
" camera, instead. You can, however, use a value that is slightly higher than the frame rate in the camera. ".
|
||||
"In this case, this helps keep the cpu from being overtaxed in the event of a network problem.~~".
|
||||
" camera, instead. You can, however, use a value that is slightly higher than the frame rate in the camera. ".
|
||||
"In this case, this helps keep the cpu from being overtaxed in the event of a network problem.~~".
|
||||
"Some, mostly older, IP cameras support snapshot mode. In this case ZoneMinder is actively polling the camera ".
|
||||
"for new images. In this case, it is safe to use the field."
|
||||
),
|
||||
|
||||
|
||||
// 'LANG_DEFAULT' => array(
|
||||
// 'Prompt' => "This is a new prompt for this option",
|
||||
// 'Help' => "This is some new help for this option which will be displayed in the popup window when the ? is clicked"
|
||||
|
|
|
@ -233,7 +233,12 @@ function getNavBarHTML($reload = null) {
|
|||
ob_start();
|
||||
if ( $running == null )
|
||||
$running = daemonCheck();
|
||||
$status = $running?translate('Running'):translate('Stopped');
|
||||
if ( $running ) {
|
||||
$state = dbFetchOne('SELECT Name FROM States WHERE isActive=1', 'Name');
|
||||
if ( $state == 'default' )
|
||||
$state = '';
|
||||
}
|
||||
$status = $running ? ($state ? $state : translate('Running')) : translate('Stopped');
|
||||
?>
|
||||
<div class="navbar navbar-inverse navbar-static-top">
|
||||
<div class="container-fluid">
|
||||
|
@ -244,7 +249,9 @@ function getNavBarHTML($reload = null) {
|
|||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<div class="navbar-brand"><a href="<?php echo validHtmlStr(ZM_HOME_URL); ?>" target="<?php echo validHtmlStr(ZM_WEB_TITLE); ?>"><?php echo ZM_HOME_CONTENT ?></a></div>
|
||||
<div class="navbar-brand">
|
||||
<a href="<?php echo validHtmlStr(ZM_HOME_URL); ?>" target="<?php echo validHtmlStr(ZM_WEB_TITLE); ?>"><?php echo ZM_HOME_CONTENT ?></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="collapse navbar-collapse" id="main-header-nav">
|
||||
|
@ -326,7 +333,7 @@ if (isset($_REQUEST['filter']['Query']['terms']['attr'])) {
|
|||
<button type="button" class="btn btn-default navbar-btn" data-toggle="modal" data-target="#modalState"><?php echo $status ?></button>
|
||||
|
||||
<?php } else if ( canView('System') ) { ?>
|
||||
<p class="navbar-text"> <?php echo $status ?></p>
|
||||
<p class="navbar-text"><?php echo $status ?></p>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<?php } # end if !$user or $user['Id'] meaning logged in ?>
|
||||
|
|
|
@ -39,7 +39,7 @@ if ( ! empty($_REQUEST['mid']) ) {
|
|||
$monitor = new ZM\Monitor( $_REQUEST['mid'] );
|
||||
if ( $monitor and ZM_OPT_X10 )
|
||||
$x10Monitor = dbFetchOne('SELECT * FROM TriggersX10 WHERE MonitorId = ?', NULL, array($_REQUEST['mid']));
|
||||
}
|
||||
}
|
||||
if ( ! $monitor ) {
|
||||
|
||||
$nextId = getTableAutoInc('Monitors');
|
||||
|
@ -132,9 +132,9 @@ if ( ! $monitor ) {
|
|||
|
||||
if ( ZM_OPT_X10 && empty($x10Monitor) ) {
|
||||
$x10Monitor = array(
|
||||
'Activation' => '',
|
||||
'AlarmInput' => '',
|
||||
'AlarmOutput' => '',
|
||||
'Activation' => '',
|
||||
'AlarmInput' => '',
|
||||
'AlarmOutput' => '',
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -166,7 +166,7 @@ if ( $monitor->AlarmMaxFPS() == '0.00' )
|
|||
if ( !empty($_REQUEST['preset']) ) {
|
||||
$preset = dbFetchOne( 'SELECT Type, Device, Channel, Format, Protocol, Method, Host, Port, Path, Width, Height, Palette, MaxFPS, Controllable, ControlId, ControlDevice, ControlAddress, DefaultRate, DefaultScale FROM MonitorPresets WHERE Id = ?', NULL, array($_REQUEST['preset']) );
|
||||
foreach ( $preset as $name=>$value ) {
|
||||
# Does isset handle NULL's? I don't think this code is correct.
|
||||
# Does isset handle NULL's? I don't think this code is correct.
|
||||
if ( isset($value) ) {
|
||||
$monitor->$name = $value;
|
||||
}
|
||||
|
@ -176,7 +176,7 @@ if ( !empty($_REQUEST['probe']) ) {
|
|||
$probe = json_decode(base64_decode($_REQUEST['probe']));
|
||||
foreach ( $probe as $name=>$value ) {
|
||||
if ( isset($value) ) {
|
||||
# Does isset handle NULL's? I don't think this code is correct.
|
||||
# Does isset handle NULL's? I don't think this code is correct.
|
||||
$monitor->$name = urldecode($value);
|
||||
}
|
||||
}
|
||||
|
@ -389,7 +389,7 @@ $orientations = array(
|
|||
'90' => translate('RotateRight'),
|
||||
'180' => translate('Inverted'),
|
||||
'270' => translate('RotateLeft'),
|
||||
'horz' => translate('FlippedHori'),
|
||||
'hori' => translate('FlippedHori'),
|
||||
'vert' => translate('FlippedVert')
|
||||
);
|
||||
|
||||
|
@ -683,7 +683,7 @@ switch ( $tab ) {
|
|||
?>
|
||||
<tr class="Name"><td><?php echo translate('Name') ?></td><td><input type="text" name="newMonitor[Name]" value="<?php echo validHtmlStr($monitor->Name()) ?>" /></td></tr>
|
||||
<tr><td><?php echo translate('Server') ?></td><td>
|
||||
<?php
|
||||
<?php
|
||||
$servers = array(''=>'None','auto'=>'Auto');
|
||||
foreach ( ZM\Server::find(NULL, array('order'=>'lower(Name)')) as $Server ) {
|
||||
$servers[$Server->Id()] = $Server->Name();
|
||||
|
@ -763,7 +763,7 @@ echo htmlOptions(ZM\Group::get_dropdown_options( ), $monitor->GroupIds() );
|
|||
<td><?php echo translate('RefImageBlendPct') ?></td>
|
||||
<td><select name="newMonitor[RefBlendPerc]"><?php foreach ( $fastblendopts as $name => $value ) { ?><option value="<?php echo $value ?>"<?php if ( $value == $monitor->RefBlendPerc() ) { ?> selected="selected"<?php } ?>><?php echo $name ?></option><?php } ?></select></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<tr>
|
||||
<td><?php echo translate('AlarmRefImageBlendPct') ?></td>
|
||||
<td>
|
||||
<select name="newMonitor[AlarmRefBlendPerc]">
|
||||
|
@ -840,7 +840,7 @@ echo htmlOptions(ZM\Group::get_dropdown_options( ), $monitor->GroupIds() );
|
|||
</td></tr>
|
||||
<tr><td><?php echo translate('V4LCapturesPerFrame') ?></td><td><input type="number" name="newMonitor[V4LCapturesPerFrame]" value="<?php echo validHtmlStr($monitor->V4LCapturesPerFrame()); ?>"/></td></tr>
|
||||
<?php
|
||||
|
||||
|
||||
} else if ( $monitor->Type() == 'NVSocket' ) {
|
||||
include('_monitor_source_nvsocket.php');
|
||||
} else if ( $monitor->Type() == 'Remote' ) {
|
||||
|
@ -894,10 +894,10 @@ if ( $monitor->Type() != 'NVSocket' && $monitor->Type() != 'WebSite' ) {
|
|||
</td></tr>
|
||||
<tr><td><?php echo translate('CaptureWidth') ?> (<?php echo translate('Pixels') ?>)</td><td><input type="text" name="newMonitor[Width]" value="<?php echo validHtmlStr($monitor->Width()) ?>" size="4" onkeyup="updateMonitorDimensions(this);"/></td></tr>
|
||||
<tr><td><?php echo translate('CaptureHeight') ?> (<?php echo translate('Pixels') ?>)</td><td><input type="text" name="newMonitor[Height]" value="<?php echo validHtmlStr($monitor->Height()) ?>" size="4" onkeyup="updateMonitorDimensions(this);"/></td></tr>
|
||||
<tr><td><?php echo translate('PreserveAspect') ?></td><td><input type="checkbox" name="preserveAspectRatio" value="1"/></td></tr>
|
||||
<tr><td><?php echo translate('PreserveAspect') ?></td><td><input type="checkbox" name="preserveAspectRatio" value="1"/></td></tr>
|
||||
<tr><td><?php echo translate('Orientation') ?></td><td><?php echo htmlselect( 'newMonitor[Orientation]', $orientations, $monitor->Orientation() );?></td></tr>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
if ( $monitor->Type() == 'Local' ) {
|
||||
?>
|
||||
<tr><td><?php echo translate('Deinterlacing') ?></td><td><select name="newMonitor[Deinterlacing]"><?php foreach ( $deinterlaceopts_v4l2 as $name => $value ) { ?><option value="<?php echo validHtmlStr($value); ?>"<?php if ( $value == $monitor->Deinterlacing()) { ?> selected="selected"<?php } ?>><?php echo validHtmlStr($name); ?></option><?php } ?></select></td></tr>
|
||||
|
@ -920,7 +920,7 @@ if ( $monitor->Type() == 'Local' ) {
|
|||
?>
|
||||
<tr><td><?php echo translate('SaveJPEGs') ?></td><td><select name="newMonitor[SaveJPEGs]"><?php foreach ( $savejpegopts as $name => $value ) { ?><option value="<?php echo validHtmlStr($value); ?>"<?php if ( $value == $monitor->SaveJPEGs() ) { ?> selected="selected"<?php } ?>><?php echo validHtmlStr($name); ?></option><?php } ?></select></td></tr>
|
||||
<tr><td><?php echo translate('VideoWriter') ?></td><td>
|
||||
<?php
|
||||
<?php
|
||||
$videowriteropts = array(
|
||||
0 => 'Disabled',
|
||||
);
|
||||
|
|
|
@ -54,7 +54,9 @@ if ( $running ) {
|
|||
$states = dbFetchAll('SELECT * FROM States');
|
||||
foreach ( $states as $state ) {
|
||||
?>
|
||||
<option value="<?php echo validHtmlStr($state['Name']) ?>"><?php echo validHtmlStr($state['Name']); ?></option>
|
||||
<option value="<?php echo validHtmlStr($state['Name']) ?>" <?php echo $state['IsActive'] ? 'selected="selected"' : '' ?>>
|
||||
<?php echo validHtmlStr($state['Name']); ?>
|
||||
</option>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
|
Loading…
Reference in New Issue