Merge branch 'multi-server' of github.com:ZoneMinder/ZoneMinder into multi-server
This commit is contained in:
commit
df4c881b4a
|
@ -4,7 +4,7 @@
|
||||||
#
|
#
|
||||||
cmake_minimum_required (VERSION 2.6)
|
cmake_minimum_required (VERSION 2.6)
|
||||||
project (zoneminder)
|
project (zoneminder)
|
||||||
set(zoneminder_VERSION "1.28.105")
|
set(zoneminder_VERSION "1.28.107")
|
||||||
# make API version a minor of ZM version
|
# make API version a minor of ZM version
|
||||||
set(zoneminder_API_VERSION "${zoneminder_VERSION}.1")
|
set(zoneminder_API_VERSION "${zoneminder_VERSION}.1")
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# For instructions on building with cmake, please see INSTALL
|
# For instructions on building with cmake, please see INSTALL
|
||||||
#
|
#
|
||||||
AC_PREREQ(2.59)
|
AC_PREREQ(2.59)
|
||||||
AC_INIT(zm,1.28.105,[http://www.zoneminder.com/forums/ - Please check FAQ first],zoneminder,http://www.zoneminder.com/downloads.html)
|
AC_INIT(zm,1.28.107,[http://www.zoneminder.com/forums/ - Please check FAQ first],zoneminder,http://www.zoneminder.com/downloads.html)
|
||||||
AM_INIT_AUTOMAKE
|
AM_INIT_AUTOMAKE
|
||||||
AC_CONFIG_SRCDIR(src/zm.h)
|
AC_CONFIG_SRCDIR(src/zm.h)
|
||||||
AC_CONFIG_HEADERS(config.h)
|
AC_CONFIG_HEADERS(config.h)
|
||||||
|
|
|
@ -341,6 +341,7 @@ CREATE TABLE `Monitors` (
|
||||||
`Palette` int(10) unsigned NOT NULL default '0',
|
`Palette` int(10) unsigned NOT NULL default '0',
|
||||||
`Orientation` enum('0','90','180','270','hori','vert') NOT NULL default '0',
|
`Orientation` enum('0','90','180','270','hori','vert') NOT NULL default '0',
|
||||||
`Deinterlacing` int(10) unsigned NOT NULL default '0',
|
`Deinterlacing` int(10) unsigned NOT NULL default '0',
|
||||||
|
`RTSPDescribe` tinyint(1) unsigned NOT NULL default '0',
|
||||||
`Brightness` mediumint(7) NOT NULL default '-1',
|
`Brightness` mediumint(7) NOT NULL default '-1',
|
||||||
`Contrast` mediumint(7) NOT NULL default '-1',
|
`Contrast` mediumint(7) NOT NULL default '-1',
|
||||||
`Hue` mediumint(7) NOT NULL default '-1',
|
`Hue` mediumint(7) NOT NULL default '-1',
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
--
|
||||||
|
-- This updates a 1.28.105 database to 1.28.106
|
||||||
|
--
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Add Monitor RTSPDescribe field
|
||||||
|
-- Used to enable or disable processing of the remote camera RTSP DESCRIBE response header
|
||||||
|
--
|
||||||
|
SET @s = (SELECT IF(
|
||||||
|
(SELECT COUNT(*)
|
||||||
|
FROM INFORMATION_SCHEMA.COLUMNS
|
||||||
|
WHERE table_name = 'Monitors'
|
||||||
|
AND table_schema = DATABASE()
|
||||||
|
AND column_name = 'RTSPDescribe'
|
||||||
|
) > 0,
|
||||||
|
"SELECT 'Column RTSPDescribe already exists in Monitors'",
|
||||||
|
"ALTER TABLE `Monitors` ADD `RTSPDescribe` tinyint(1) unsigned NOT NULL default '0' AFTER `Deinterlacing`"
|
||||||
|
));
|
||||||
|
|
||||||
|
PREPARE stmt FROM @s;
|
||||||
|
EXECUTE stmt;
|
|
@ -25,6 +25,7 @@ install(DIRECTORY events images temp DESTINATION /var/lib/zoneminder DIRECTORY_P
|
||||||
install(CODE "execute_process(COMMAND ln -sf ../../../../var/lib/zoneminder/events \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/events\")")
|
install(CODE "execute_process(COMMAND ln -sf ../../../../var/lib/zoneminder/events \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/events\")")
|
||||||
install(CODE "execute_process(COMMAND ln -sf ../../../../var/lib/zoneminder/images \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/images\")")
|
install(CODE "execute_process(COMMAND ln -sf ../../../../var/lib/zoneminder/images \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/images\")")
|
||||||
install(CODE "execute_process(COMMAND ln -sf ../../../../var/lib/zoneminder/temp \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/temp\")")
|
install(CODE "execute_process(COMMAND ln -sf ../../../../var/lib/zoneminder/temp \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/temp\")")
|
||||||
|
install(CODE "execute_process(COMMAND ln -sf ../../../../../../var/lib/zoneminder/temp \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/api/app/tmp\")")
|
||||||
|
|
||||||
# Fedora requires cambozola as a separate package so just link to it
|
# Fedora requires cambozola as a separate package so just link to it
|
||||||
install(CODE "execute_process(COMMAND ln -sf ../../java/cambozola.jar \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/cambozola.jar\")")
|
install(CODE "execute_process(COMMAND ln -sf ../../java/cambozola.jar \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/cambozola.jar\")")
|
||||||
|
|
|
@ -25,8 +25,8 @@ New installs
|
||||||
introduce an obvious security issue. The following should set this up:
|
introduce an obvious security issue. The following should set this up:
|
||||||
|
|
||||||
mysql -u root -p
|
mysql -u root -p
|
||||||
grant select,insert,update,delete,lock tables,alter on zm.* to
|
grant select,insert,update,delete,lock tables,alter,create
|
||||||
'zmuser'@localhost identified by 'zmpass';
|
on zm.* to 'zmuser'@localhost identified by 'zmpass';
|
||||||
|
|
||||||
Obviously, change at least zmpass to an actual, secure password or
|
Obviously, change at least zmpass to an actual, secure password or
|
||||||
passphrase. You can change zmuser as well if you like.
|
passphrase. You can change zmuser as well if you like.
|
||||||
|
@ -95,7 +95,7 @@ Upgrades
|
||||||
2. Add additional permissions to the zmuser account:
|
2. Add additional permissions to the zmuser account:
|
||||||
|
|
||||||
mysql -u root -p
|
mysql -u root -p
|
||||||
grant lock tables,alter on zm.* to
|
grant lock tables,alter,create on zm.* to
|
||||||
'zmuser'@localhost identified by 'zmpass';
|
'zmuser'@localhost identified by 'zmpass';
|
||||||
|
|
||||||
Since this is an upgrade, the assumption is that the zmuser account already
|
Since this is an upgrade, the assumption is that the zmuser account already
|
||||||
|
|
|
@ -51,6 +51,7 @@ install(DIRECTORY events images temp DESTINATION /var/lib/zoneminder DIRECTORY_P
|
||||||
install(CODE "execute_process(COMMAND ln -sf ../../../../var/lib/zoneminder/events \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/events\")")
|
install(CODE "execute_process(COMMAND ln -sf ../../../../var/lib/zoneminder/events \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/events\")")
|
||||||
install(CODE "execute_process(COMMAND ln -sf ../../../../var/lib/zoneminder/images \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/images\")")
|
install(CODE "execute_process(COMMAND ln -sf ../../../../var/lib/zoneminder/images \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/images\")")
|
||||||
install(CODE "execute_process(COMMAND ln -sf ../../../../var/lib/zoneminder/temp \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/temp\")")
|
install(CODE "execute_process(COMMAND ln -sf ../../../../var/lib/zoneminder/temp \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/temp\")")
|
||||||
|
install(CODE "execute_process(COMMAND ln -sf ../../../../../../var/lib/zoneminder/temp \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/api/app/tmp\")")
|
||||||
|
|
||||||
# Install auxillary files required to run zoneminder on CentOS
|
# Install auxillary files required to run zoneminder on CentOS
|
||||||
install(FILES redalert.wav DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/sounds PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
install(FILES redalert.wav DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/sounds PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
||||||
|
|
|
@ -15,8 +15,8 @@
|
||||||
|
|
||||||
mysql -uroot -p
|
mysql -uroot -p
|
||||||
mysql> create database zm;
|
mysql> create database zm;
|
||||||
mysql> grant select,insert,update,delete,lock tables,alter on zm.* to
|
mysql> grant select,insert,update,delete,lock tables,alter,create
|
||||||
'zmuser'@localhost identified by 'zmpass';
|
on zm.* to 'zmuser'@localhost identified by 'zmpass';
|
||||||
mysql> exit;
|
mysql> exit;
|
||||||
mysql -uroot -p < /usr/share/zoneminder/db/zm_create.sql
|
mysql -uroot -p < /usr/share/zoneminder/db/zm_create.sql
|
||||||
mysqladmin -uroot -p reload
|
mysqladmin -uroot -p reload
|
||||||
|
@ -69,7 +69,7 @@
|
||||||
1. Add additional permissions to the zmuser account:
|
1. Add additional permissions to the zmuser account:
|
||||||
|
|
||||||
mysql -u root -p
|
mysql -u root -p
|
||||||
grant lock tables,alter on zm.* to
|
grant lock tables,alter,create on zm.* to
|
||||||
'zmuser'@localhost identified by 'zmpass';
|
'zmuser'@localhost identified by 'zmpass';
|
||||||
|
|
||||||
Since this is an upgrade, the assumption is that the zmuser account exists
|
Since this is an upgrade, the assumption is that the zmuser account exists
|
||||||
|
|
|
@ -36,8 +36,8 @@ New installs
|
||||||
|
|
||||||
mysql -u root -p < /usr/share/zoneminder/db/zm_create.sql
|
mysql -u root -p < /usr/share/zoneminder/db/zm_create.sql
|
||||||
mysql -u root -p
|
mysql -u root -p
|
||||||
mysql> grant select,insert,update,delete,lock tables,alter on zm.* to
|
mysql> grant select,insert,update,delete,lock tables,alter, create
|
||||||
'zmuser'@localhost identified by 'zmpass';
|
on zm.* to 'zmuser'@localhost identified by 'zmpass';
|
||||||
mysql> exit;
|
mysql> exit;
|
||||||
mysqladmin -u root -p reload
|
mysqladmin -u root -p reload
|
||||||
|
|
||||||
|
@ -101,8 +101,8 @@ Upgrades
|
||||||
|
|
||||||
Overtime, the database account permissions required for normal operation
|
Overtime, the database account permissions required for normal operation
|
||||||
have changed. Verify the zmuser database account has been granted select,
|
have changed. Verify the zmuser database account has been granted select,
|
||||||
insert, update, delete, lock tables, and alter permission to the ZoneMinder
|
insert, update, delete, lock tables, alter, and create permission to the
|
||||||
database:
|
ZoneMinder database:
|
||||||
|
|
||||||
mysql -u root -p
|
mysql -u root -p
|
||||||
mysql> show grants for zmuser@localhost;
|
mysql> show grants for zmuser@localhost;
|
||||||
|
|
|
@ -146,7 +146,7 @@ rm -rf %{_docdir}/%{name}-%{version}
|
||||||
#%{_bindir}/zmonvif-probe.pl
|
#%{_bindir}/zmonvif-probe.pl
|
||||||
|
|
||||||
%{perl_vendorlib}/ZoneMinder*
|
%{perl_vendorlib}/ZoneMinder*
|
||||||
%{perl_vendorlib}/%{_arch}-linux-thread-multi/auto/ZoneMinder*
|
%{perl_vendorarch}/auto/ZoneMinder/.packlist
|
||||||
#%{perl_vendorlib}/ONVIF*
|
#%{perl_vendorlib}/ONVIF*
|
||||||
#%{perl_vendorlib}/WSDiscovery*
|
#%{perl_vendorlib}/WSDiscovery*
|
||||||
#%{perl_vendorlib}/WSSecurity*
|
#%{perl_vendorlib}/WSSecurity*
|
||||||
|
|
|
@ -17,7 +17,7 @@ Name
|
||||||
Each Zone can be named for reference purposes. It is used for logging and debugging. Choose a name that helps you identify your zones.
|
Each Zone can be named for reference purposes. It is used for logging and debugging. Choose a name that helps you identify your zones.
|
||||||
|
|
||||||
Type
|
Type
|
||||||
This is one of the more important concepts in ZoneMinder and there are five to choose from.
|
This is one of the more important concepts in ZoneMinder and there are six to choose from.
|
||||||
|
|
||||||
* Active
|
* Active
|
||||||
Triggers an alarm when motion is detected within it. This is the zone type you'll use most often, and which will be set for your default zone. Only Active and Exclusive zones can trigger an alarm.
|
Triggers an alarm when motion is detected within it. This is the zone type you'll use most often, and which will be set for your default zone. Only Active and Exclusive zones can trigger an alarm.
|
||||||
|
@ -32,7 +32,10 @@ Type
|
||||||
This zone type is relatively recent. It is called a Preclusive zone because if it is triggered it actually precludes an alarm being generated for that image frame. So motion or other changes that occur in a Preclusive zone will have the effect of ensuring that no alarm occurs at all. The application for this zone type is primarily as a shortcut for detecting general large-scale lighting or other changes. Generally this may be achieved by limiting the maximum number of alarm pixels or other measure in an Active zone. However in some cases that zone may cover an area where the area of variable illumination occurs in different places as the sun and/or shadows move and it thus may be difficult to come up with general values. Additionally, if the sun comes out rapidly then although the initial change may be ignored in this way as the reference image catches up an alarm may ultimately be triggered as the image becomes less different. Using one or more Preclusive zones offers a different approach. Preclusive zones are designed to be fairly small, even just a few pixels across, with quite low alarm thresholds. They should be situated in areas of the image that are less likely to have motion occur such as high on a wall or in a corner. Should a general illumination change occur they would be triggered at least as early as any Active zones and prevent any other zones from generating an alarm. Obviously careful placement is required to ensure that they do not cancel any genuine alarms or that they are not so close together that any motion just hops from one Preclusive zone to another. Preclusive zones may also be used to reduce processing time by situating one over an Active zone. The Preclusive zone is processed first; if it is small, and is triggered, the rest of the zone/image will not be processed.
|
This zone type is relatively recent. It is called a Preclusive zone because if it is triggered it actually precludes an alarm being generated for that image frame. So motion or other changes that occur in a Preclusive zone will have the effect of ensuring that no alarm occurs at all. The application for this zone type is primarily as a shortcut for detecting general large-scale lighting or other changes. Generally this may be achieved by limiting the maximum number of alarm pixels or other measure in an Active zone. However in some cases that zone may cover an area where the area of variable illumination occurs in different places as the sun and/or shadows move and it thus may be difficult to come up with general values. Additionally, if the sun comes out rapidly then although the initial change may be ignored in this way as the reference image catches up an alarm may ultimately be triggered as the image becomes less different. Using one or more Preclusive zones offers a different approach. Preclusive zones are designed to be fairly small, even just a few pixels across, with quite low alarm thresholds. They should be situated in areas of the image that are less likely to have motion occur such as high on a wall or in a corner. Should a general illumination change occur they would be triggered at least as early as any Active zones and prevent any other zones from generating an alarm. Obviously careful placement is required to ensure that they do not cancel any genuine alarms or that they are not so close together that any motion just hops from one Preclusive zone to another. Preclusive zones may also be used to reduce processing time by situating one over an Active zone. The Preclusive zone is processed first; if it is small, and is triggered, the rest of the zone/image will not be processed.
|
||||||
|
|
||||||
* Inactive
|
* Inactive
|
||||||
Suppresses the detection of motion within it. This can be layered on top of any other zone type, preventing motion within the Inactive zone from being effective for any other zone type. Use inactive zones to cover areas in which nothing notable will ever happen or where you get false alarms that don't relate to what you are trying to monitor. Inactive zones may be overlaid on other zones to blank out areas, and are processed first. As a general practice, you should try and make zones abut each other instead of overlapping to avoid repeated duplicate processing of the same area.
|
Suppresses the detection of motion within it. This can be layered on top of any other zone type, preventing motion within the Inactive zone from being effective for any other zone type. Use inactive zones to cover areas in which nothing notable will ever happen or where you get false alarms that don't relate to what you are trying to monitor. Inactive zones may be overlaid on other zones to blank out areas, and are processed first (with the exception of Privacy zones, see below). As a general practice, you should try and make zones abut each other instead of overlapping to avoid repeated duplicate processing of the same area.
|
||||||
|
|
||||||
|
* Privacy
|
||||||
|
Blackens the pixels within it. This can be used if you want to hide some regions in the image if the situation does not allow an other solution. This zone type is different to all the others in that it gets processed as soon as possible during capture (even before the timestamp gets into the image) and not in the analyzing process. So if you add, change or delete a Privacy zone, you don't see the changes in the image until the capture process gets restarted. This will be done automatically, but needs a few seconds.
|
||||||
|
|
||||||
Preset
|
Preset
|
||||||
The preset chooser sets sensible default values based on computational needs (fast v. best) and sensitivity (low, medium, high.) It is not required that you select a preset, and you can alter any of the parameters after choosing a preset. For a small number of monitors with ZoneMinder running on modern equipment, Best, high sensitivity can be chosen as a good starting point.
|
The preset chooser sets sensible default values based on computational needs (fast v. best) and sensitivity (low, medium, high.) It is not required that you select a preset, and you can alter any of the parameters after choosing a preset. For a small number of monitors with ZoneMinder running on modern equipment, Best, high sensitivity can be chosen as a good starting point.
|
||||||
|
|
|
@ -184,3 +184,4 @@ If your filter is not working, here are some useful tips:
|
||||||
* Run ``sudo zmfilter.pl -f <yourfiltername>`` from command line and see the log output
|
* Run ``sudo zmfilter.pl -f <yourfiltername>`` from command line and see the log output
|
||||||
* Check how long your action is taking - zmfilter.pl will wait for the action to complete before it checks again
|
* Check how long your action is taking - zmfilter.pl will wait for the action to complete before it checks again
|
||||||
* If you are using relative times like 'now' or '1 year ago' etc. remember that zmfilter converts that relative time to an absolute date only when it reloads filters, which is dictated by the FILTER_RELOAD_DELAY duration. So, for example, if you are wondering why your events are not being detected before intervals of 5 minutes and you have used such a relative condition, this is why
|
* If you are using relative times like 'now' or '1 year ago' etc. remember that zmfilter converts that relative time to an absolute date only when it reloads filters, which is dictated by the FILTER_RELOAD_DELAY duration. So, for example, if you are wondering why your events are not being detected before intervals of 5 minutes and you have used such a relative condition, this is why
|
||||||
|
* In the event that you see your new filter is working great when you try it out from the Web Console (using the Submit or Execute button) but does not seem to work when its running in background mode, you might have just chanced upon a compatibility issue between how Perl and PHP translate free form text to dates/times. When you test it via the "Submit" or "Execute" button, you are invoking a PHP function for time conversion. When the filter runs in background mode, zmfilter.pl calls a perl equivalent function. In some cases, depending on the version of Perl and PHP you have, the results may vary. If you face this situation, the best thing to do is to run ``sudo zmfilter.pl -f <yourfiltername>`` from a terminal to make sure the filter actually works in Perl as well.
|
||||||
|
|
|
@ -2222,7 +2222,7 @@ Debug( 1, "Got %d for v4l_captures_per_frame", v4l_captures_per_frame );
|
||||||
|
|
||||||
int Monitor::LoadRemoteMonitors( const char *protocol, const char *host, const char *port, const char *path, Monitor **&monitors, Purpose purpose )
|
int Monitor::LoadRemoteMonitors( const char *protocol, const char *host, const char *port, const char *path, Monitor **&monitors, Purpose purpose )
|
||||||
{
|
{
|
||||||
std::string sql = "select Id, Name, ServerId, Function+0, Enabled, LinkedMonitors, Protocol, Method, Host, Port, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, Exif from Monitors where Function != 'None' and Type = 'Remote'";
|
std::string sql = "select Id, Name, ServerId, Function+0, Enabled, LinkedMonitors, Protocol, Method, Host, Port, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, RTSPDescribe, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, Exif from Monitors where Function != 'None' and Type = 'Remote'";
|
||||||
if ( staticConfig.SERVER_ID ) {
|
if ( staticConfig.SERVER_ID ) {
|
||||||
sql += " AND ServerId='";
|
sql += " AND ServerId='";
|
||||||
sql += staticConfig.SERVER_ID;
|
sql += staticConfig.SERVER_ID;
|
||||||
|
@ -2265,6 +2265,7 @@ int Monitor::LoadRemoteMonitors( const char *protocol, const char *host, const c
|
||||||
/* int palette = atoi(dbrow[col]); */ col++;
|
/* int palette = atoi(dbrow[col]); */ col++;
|
||||||
Orientation orientation = (Orientation)atoi(dbrow[col]); col++;
|
Orientation orientation = (Orientation)atoi(dbrow[col]); col++;
|
||||||
unsigned int deinterlacing = atoi(dbrow[col]); col++;
|
unsigned int deinterlacing = atoi(dbrow[col]); col++;
|
||||||
|
bool rtsp_describe = (*dbrow[col] != '0'); col++;
|
||||||
int brightness = atoi(dbrow[col]); col++;
|
int brightness = atoi(dbrow[col]); col++;
|
||||||
int contrast = atoi(dbrow[col]); col++;
|
int contrast = atoi(dbrow[col]); col++;
|
||||||
int hue = atoi(dbrow[col]); col++;
|
int hue = atoi(dbrow[col]); col++;
|
||||||
|
@ -2329,6 +2330,7 @@ int Monitor::LoadRemoteMonitors( const char *protocol, const char *host, const c
|
||||||
path, // Path
|
path, // Path
|
||||||
cam_width,
|
cam_width,
|
||||||
cam_height,
|
cam_height,
|
||||||
|
rtsp_describe,
|
||||||
colours,
|
colours,
|
||||||
brightness,
|
brightness,
|
||||||
contrast,
|
contrast,
|
||||||
|
@ -2692,7 +2694,7 @@ int Monitor::LoadFfmpegMonitors( const char *file, Monitor **&monitors, Purpose
|
||||||
|
|
||||||
Monitor *Monitor::Load( unsigned int p_id, bool load_zones, Purpose purpose )
|
Monitor *Monitor::Load( unsigned int p_id, bool load_zones, Purpose purpose )
|
||||||
{
|
{
|
||||||
std::string sql = stringtf( "select Id, Name, ServerId, Type, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, V4LMultiBuffer, V4LCapturesPerFrame, Protocol, Method, Host, Port, Path, Options, User, Pass, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour, Exif from Monitors where Id = %d", p_id );
|
std::string sql = stringtf( "select Id, Name, ServerId, Type, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, V4LMultiBuffer, V4LCapturesPerFrame, Protocol, Method, Host, Port, Path, Options, User, Pass, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, RTSPDescribe, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour, Exif from Monitors where Id = %d", p_id );
|
||||||
|
|
||||||
MYSQL_ROW dbrow = zmDbFetchOne( sql.c_str() );
|
MYSQL_ROW dbrow = zmDbFetchOne( sql.c_str() );
|
||||||
if ( ! dbrow ) {
|
if ( ! dbrow ) {
|
||||||
|
@ -2750,6 +2752,7 @@ Debug( 1, "Got %d for v4l_captures_per_frame", v4l_captures_per_frame );
|
||||||
int palette = atoi(dbrow[col]); col++;
|
int palette = atoi(dbrow[col]); col++;
|
||||||
Orientation orientation = (Orientation)atoi(dbrow[col]); col++;
|
Orientation orientation = (Orientation)atoi(dbrow[col]); col++;
|
||||||
unsigned int deinterlacing = atoi(dbrow[col]); col++;
|
unsigned int deinterlacing = atoi(dbrow[col]); col++;
|
||||||
|
bool rtsp_describe = (*dbrow[col] != '0'); col++;
|
||||||
int brightness = atoi(dbrow[col]); col++;
|
int brightness = atoi(dbrow[col]); col++;
|
||||||
int contrast = atoi(dbrow[col]); col++;
|
int contrast = atoi(dbrow[col]); col++;
|
||||||
int hue = atoi(dbrow[col]); col++;
|
int hue = atoi(dbrow[col]); col++;
|
||||||
|
@ -2850,6 +2853,7 @@ Debug( 1, "Got %d for v4l_captures_per_frame", v4l_captures_per_frame );
|
||||||
path.c_str(),
|
path.c_str(),
|
||||||
cam_width,
|
cam_width,
|
||||||
cam_height,
|
cam_height,
|
||||||
|
rtsp_describe,
|
||||||
colours,
|
colours,
|
||||||
brightness,
|
brightness,
|
||||||
contrast,
|
contrast,
|
||||||
|
|
|
@ -28,9 +28,10 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
|
||||||
RemoteCameraRtsp::RemoteCameraRtsp( int p_id, const std::string &p_method, const std::string &p_host, const std::string &p_port, const std::string &p_path, int p_width, int p_height, int p_colours, int p_brightness, int p_contrast, int p_hue, int p_colour, bool p_capture ) :
|
RemoteCameraRtsp::RemoteCameraRtsp( int p_id, const std::string &p_method, const std::string &p_host, const std::string &p_port, const std::string &p_path, int p_width, int p_height, bool p_rtsp_describe, int p_colours, int p_brightness, int p_contrast, int p_hue, int p_colour, bool p_capture ) :
|
||||||
RemoteCamera( p_id, "rtsp", p_host, p_port, p_path, p_width, p_height, p_colours, p_brightness, p_contrast, p_hue, p_colour, p_capture ),
|
RemoteCamera( p_id, "rtsp", p_host, p_port, p_path, p_width, p_height, p_colours, p_brightness, p_contrast, p_hue, p_colour, p_capture ),
|
||||||
rtspThread( 0 )
|
rtspThread( 0 ),
|
||||||
|
rtsp_describe( p_rtsp_describe )
|
||||||
{
|
{
|
||||||
if ( p_method == "rtpUni" )
|
if ( p_method == "rtpUni" )
|
||||||
method = RtspThread::RTP_UNICAST;
|
method = RtspThread::RTP_UNICAST;
|
||||||
|
@ -125,7 +126,7 @@ void RemoteCameraRtsp::Terminate()
|
||||||
|
|
||||||
int RemoteCameraRtsp::Connect()
|
int RemoteCameraRtsp::Connect()
|
||||||
{
|
{
|
||||||
rtspThread = new RtspThread( id, method, protocol, host, port, path, auth );
|
rtspThread = new RtspThread( id, method, protocol, host, port, path, auth, rtsp_describe );
|
||||||
|
|
||||||
rtspThread->start();
|
rtspThread->start();
|
||||||
|
|
||||||
|
|
|
@ -40,10 +40,11 @@ protected:
|
||||||
int rtsp_sd;
|
int rtsp_sd;
|
||||||
int rtp_sd;
|
int rtp_sd;
|
||||||
int rtcp_sd;
|
int rtcp_sd;
|
||||||
|
bool rtsp_describe;
|
||||||
|
|
||||||
Buffer buffer;
|
Buffer buffer;
|
||||||
Buffer lastSps;
|
Buffer lastSps;
|
||||||
Buffer lastPps;
|
Buffer lastPps;
|
||||||
|
|
||||||
RtspThread::RtspMethod method;
|
RtspThread::RtspMethod method;
|
||||||
|
|
||||||
|
@ -66,18 +67,19 @@ protected:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RemoteCameraRtsp( int p_id, const std::string &method, const std::string &host, const std::string &port, const std::string &path, int p_width, int p_height, int p_colours, int p_brightness, int p_contrast, int p_hue, int p_colour, bool p_capture );
|
RemoteCameraRtsp( int p_id, const std::string &method, const std::string &host, const std::string &port, const std::string &path, int p_width, int p_height, bool p_rtsp_describe, int p_colours, int p_brightness, int p_contrast, int p_hue, int p_colour, bool p_capture );
|
||||||
~RemoteCameraRtsp();
|
~RemoteCameraRtsp();
|
||||||
|
|
||||||
void Initialise();
|
void Initialise();
|
||||||
void Terminate();
|
void Terminate();
|
||||||
int Connect();
|
int Connect();
|
||||||
int Disconnect();
|
int Disconnect();
|
||||||
|
|
||||||
int PrimeCapture();
|
int PrimeCapture();
|
||||||
int PreCapture();
|
int PreCapture();
|
||||||
int Capture( Image &image );
|
int Capture( Image &image );
|
||||||
int PostCapture();
|
int PostCapture();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ZM_REMOTE_CAMERA_RTSP_H
|
#endif // ZM_REMOTE_CAMERA_RTSP_H
|
||||||
|
|
|
@ -167,13 +167,14 @@ void RtspThread::releasePorts( int port )
|
||||||
smAssignedPorts.erase( port );
|
smAssignedPorts.erase( port );
|
||||||
}
|
}
|
||||||
|
|
||||||
RtspThread::RtspThread( int id, RtspMethod method, const std::string &protocol, const std::string &host, const std::string &port, const std::string &path, const std::string &auth) :
|
RtspThread::RtspThread( int id, RtspMethod method, const std::string &protocol, const std::string &host, const std::string &port, const std::string &path, const std::string &auth, bool rtsp_describe) :
|
||||||
mId( id ),
|
mId( id ),
|
||||||
mMethod( method ),
|
mMethod( method ),
|
||||||
mProtocol( protocol ),
|
mProtocol( protocol ),
|
||||||
mHost( host ),
|
mHost( host ),
|
||||||
mPort( port ),
|
mPort( port ),
|
||||||
mPath( path ),
|
mPath( path ),
|
||||||
|
mRtspDescribe( rtsp_describe ),
|
||||||
mSessDesc( 0 ),
|
mSessDesc( 0 ),
|
||||||
mFormatContext( 0 ),
|
mFormatContext( 0 ),
|
||||||
mSeq( 0 ),
|
mSeq( 0 ),
|
||||||
|
@ -382,20 +383,23 @@ int RtspThread::run()
|
||||||
if( sdpStart == std::string::npos )
|
if( sdpStart == std::string::npos )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
std::string DescHeader = response.substr( 0,sdpStart );
|
if ( mRtspDescribe )
|
||||||
Debug( 1, "Processing DESCRIBE response header '%s'", DescHeader.c_str() );
|
{
|
||||||
|
std::string DescHeader = response.substr( 0,sdpStart );
|
||||||
|
Debug( 1, "Processing DESCRIBE response header '%s'", DescHeader.c_str() );
|
||||||
|
|
||||||
lines = split( DescHeader, "\r\n" );
|
lines = split( DescHeader, "\r\n" );
|
||||||
for ( size_t i = 0; i < lines.size(); i++ )
|
for ( size_t i = 0; i < lines.size(); i++ )
|
||||||
{
|
{
|
||||||
// If the device sends us a url value for Content-Base in the response header, we should use that instead
|
// If the device sends us a url value for Content-Base in the response header, we should use that instead
|
||||||
if ( ( lines[i].size() > 13 ) && ( lines[i].substr( 0, 13 ) == "Content-Base:" ) )
|
if ( ( lines[i].size() > 13 ) && ( lines[i].substr( 0, 13 ) == "Content-Base:" ) )
|
||||||
{
|
{
|
||||||
mUrl = trimSpaces( lines[i].substr( 13 ) );
|
mUrl = trimSpaces( lines[i].substr( 13 ) );
|
||||||
Info("Received new Content-Base in DESCRIBE response header. Updated device Url to: '%s'", mUrl.c_str() );
|
Info("Received new Content-Base in DESCRIBE response header. Updated device Url to: '%s'", mUrl.c_str() );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sdpStart += endOfHeaders.length();
|
sdpStart += endOfHeaders.length();
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,7 @@ private:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int mId;
|
int mId;
|
||||||
|
bool mRtspDescribe;
|
||||||
RtspMethod mMethod;
|
RtspMethod mMethod;
|
||||||
std::string mProtocol;
|
std::string mProtocol;
|
||||||
std::string mHost;
|
std::string mHost;
|
||||||
|
@ -95,7 +96,7 @@ private:
|
||||||
void checkAuthResponse(std::string &response);
|
void checkAuthResponse(std::string &response);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RtspThread( int id, RtspMethod method, const std::string &protocol, const std::string &host, const std::string &port, const std::string &path, const std::string &auth);
|
RtspThread( int id, RtspMethod method, const std::string &protocol, const std::string &host, const std::string &port, const std::string &path, const std::string &auth, bool rtsp_describe );
|
||||||
~RtspThread();
|
~RtspThread();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -445,7 +445,8 @@ if ( !empty($action) )
|
||||||
'TrackMotion' => 'toggle',
|
'TrackMotion' => 'toggle',
|
||||||
'Enabled' => 'toggle',
|
'Enabled' => 'toggle',
|
||||||
'DoNativeMotDet' => 'toggle',
|
'DoNativeMotDet' => 'toggle',
|
||||||
'Exif' => 'toggle'
|
'Exif' => 'toggle',
|
||||||
|
'RTSPDescribe' => 'toggle',
|
||||||
);
|
);
|
||||||
|
|
||||||
$columns = getTableColumns( 'Monitors' );
|
$columns = getTableColumns( 'Monitors' );
|
||||||
|
|
|
@ -256,6 +256,7 @@ $SLANG = array(
|
||||||
'DefaultScale' => 'Default Scale',
|
'DefaultScale' => 'Default Scale',
|
||||||
'DefaultView' => 'Default View',
|
'DefaultView' => 'Default View',
|
||||||
'Deinterlacing' => 'Deinterlacing',
|
'Deinterlacing' => 'Deinterlacing',
|
||||||
|
'RTSPDescribe' => 'Use RTSP Response Media URL',
|
||||||
'Delay' => 'Delay',
|
'Delay' => 'Delay',
|
||||||
'DeleteAndNext' => 'Delete & Next',
|
'DeleteAndNext' => 'Delete & Next',
|
||||||
'DeleteAndPrev' => 'Delete & Prev',
|
'DeleteAndPrev' => 'Delete & Prev',
|
||||||
|
@ -903,7 +904,13 @@ $OLANG = array(
|
||||||
'OPTIONS_EXIF' => array(
|
'OPTIONS_EXIF' => array(
|
||||||
'Help' => "Enable this option to embed EXIF data into each jpeg frame."
|
'Help' => "Enable this option to embed EXIF data into each jpeg frame."
|
||||||
),
|
),
|
||||||
|
'OPTIONS_RTSPDESCRIBE' => array(
|
||||||
|
'Help' => "Sometimes, during the intial 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~~~~".
|
||||||
|
"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"
|
||||||
|
),
|
||||||
|
|
||||||
// 'LANG_DEFAULT' => array(
|
// 'LANG_DEFAULT' => array(
|
||||||
// 'Prompt' => "This is a new prompt for this option",
|
// 'Prompt' => "This is a new prompt for this option",
|
||||||
|
|
|
@ -78,6 +78,7 @@ if ( ! empty($_REQUEST['mid']) ) {
|
||||||
'Height' => "240",
|
'Height' => "240",
|
||||||
'Orientation' => "0",
|
'Orientation' => "0",
|
||||||
'Deinterlacing' => 0,
|
'Deinterlacing' => 0,
|
||||||
|
'RTSPDescribe' => 0,
|
||||||
'LabelFormat' => '%N - %d/%m/%y %H:%M:%S',
|
'LabelFormat' => '%N - %d/%m/%y %H:%M:%S',
|
||||||
'LabelX' => 0,
|
'LabelX' => 0,
|
||||||
'LabelY' => 0,
|
'LabelY' => 0,
|
||||||
|
@ -563,6 +564,12 @@ if ( $tab != 'source' )
|
||||||
<input type="hidden" name="newMonitor[Deinterlacing]" value="<?php echo validHtmlStr($newMonitor['Deinterlacing']) ?>"/>
|
<input type="hidden" name="newMonitor[Deinterlacing]" value="<?php echo validHtmlStr($newMonitor['Deinterlacing']) ?>"/>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
|
if ( $tab != 'source' || ($newMonitor['Type'] != 'Remote' && $newMonitor['Protocol'] != 'RTSP'))
|
||||||
|
{
|
||||||
|
?>
|
||||||
|
<input type="hidden" name="newMonitor[RTSPDescribe]" value="<?php echo validHtmlStr($newMonitor['RTSPDescribe']) ?>"/>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
if ( $tab != 'timestamp' )
|
if ( $tab != 'timestamp' )
|
||||||
{
|
{
|
||||||
?>
|
?>
|
||||||
|
@ -823,6 +830,14 @@ switch ( $tab )
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
<?php
|
||||||
|
if ( $newMonitor['Type'] == "Remote" )
|
||||||
|
{
|
||||||
|
?>
|
||||||
|
<tr><td><?php echo translate('RTSPDescribe') ?> (<?php echo makePopupLink( '?view=optionhelp&option=OPTIONS_RTSPDESCRIBE', 'zmOptionHelp', 'optionhelp', '?' ) ?>) </td><td><input type="checkbox" name="newMonitor[RTSPDescribe]" value="1"<?php if ( !empty($newMonitor['RTSPDescribe']) ) { ?> checked="checked"<?php } ?>/></td></tr>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
<?php
|
<?php
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue