Merge branch 'master' of github.com:/ZoneMinder/zoneminder
This commit is contained in:
commit
b060e0835c
|
@ -282,6 +282,7 @@ DROP TABLE IF EXISTS `Filters`;
|
||||||
CREATE TABLE `Filters` (
|
CREATE TABLE `Filters` (
|
||||||
`Id` int(10) unsigned NOT NULL auto_increment,
|
`Id` int(10) unsigned NOT NULL auto_increment,
|
||||||
`Name` varchar(64) NOT NULL default '',
|
`Name` varchar(64) NOT NULL default '',
|
||||||
|
`UserId` int(10) unsigned,
|
||||||
`Query_json` text NOT NULL,
|
`Query_json` text NOT NULL,
|
||||||
`AutoArchive` tinyint(3) unsigned NOT NULL default '0',
|
`AutoArchive` tinyint(3) unsigned NOT NULL default '0',
|
||||||
`AutoVideo` tinyint(3) unsigned NOT NULL default '0',
|
`AutoVideo` tinyint(3) unsigned NOT NULL default '0',
|
||||||
|
@ -787,6 +788,7 @@ INSERT INTO `Filters`
|
||||||
`AutoCopy`,
|
`AutoCopy`,
|
||||||
`AutoCopyTo`,
|
`AutoCopyTo`,
|
||||||
`UpdateDiskSpace`,
|
`UpdateDiskSpace`,
|
||||||
|
`UserId`,
|
||||||
`Background`,
|
`Background`,
|
||||||
`Concurrent`
|
`Concurrent`
|
||||||
)
|
)
|
||||||
|
@ -807,6 +809,7 @@ INSERT INTO `Filters`
|
||||||
0/*AutoMove*/,0/*MoveTo*/,
|
0/*AutoMove*/,0/*MoveTo*/,
|
||||||
0/*AutoCopy*/,0/*CopyTo*/,
|
0/*AutoCopy*/,0/*CopyTo*/,
|
||||||
0/*UpdateDiskSpace*/,
|
0/*UpdateDiskSpace*/,
|
||||||
|
1/*UserId = admin*/,
|
||||||
1/*Background*/,
|
1/*Background*/,
|
||||||
0/*Concurrent*/
|
0/*Concurrent*/
|
||||||
);
|
);
|
||||||
|
@ -830,6 +833,7 @@ INSERT INTO `Filters`
|
||||||
`AutoCopy`,
|
`AutoCopy`,
|
||||||
`AutoCopyTo`,
|
`AutoCopyTo`,
|
||||||
`UpdateDiskSpace`,
|
`UpdateDiskSpace`,
|
||||||
|
`UserId`,
|
||||||
`Background`,
|
`Background`,
|
||||||
`Concurrent`
|
`Concurrent`
|
||||||
)
|
)
|
||||||
|
@ -849,6 +853,7 @@ VALUES (
|
||||||
0/*AutoMove*/,0/*MoveTo*/,
|
0/*AutoMove*/,0/*MoveTo*/,
|
||||||
0/*AutoCopy*/,0/*CopyTo*/,
|
0/*AutoCopy*/,0/*CopyTo*/,
|
||||||
1/*UpdateDiskSpace*/,
|
1/*UpdateDiskSpace*/,
|
||||||
|
1/*UserId=admin*/,
|
||||||
1/*Background*/,
|
1/*Background*/,
|
||||||
0/*Concurrent*/
|
0/*Concurrent*/
|
||||||
);
|
);
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
SET @s = (SELECT IF(
|
||||||
|
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
|
||||||
|
AND table_name = 'Filters'
|
||||||
|
AND column_name = 'UserId'
|
||||||
|
) > 0,
|
||||||
|
"SELECT 'Column UserId already exists in Filters'",
|
||||||
|
"ALTER TABLE `Filters` ADD `UserId` int(10) unsigned AFTER `Name`"
|
||||||
|
));
|
||||||
|
|
||||||
|
PREPARE stmt FROM @s;
|
||||||
|
EXECUTE stmt;
|
|
@ -28,7 +28,7 @@
|
||||||
%global _hardened_build 1
|
%global _hardened_build 1
|
||||||
|
|
||||||
Name: zoneminder
|
Name: zoneminder
|
||||||
Version: 1.35.4
|
Version: 1.35.5
|
||||||
Release: 1%{?dist}
|
Release: 1%{?dist}
|
||||||
Summary: A camera monitoring and analysis tool
|
Summary: A camera monitoring and analysis tool
|
||||||
Group: System Environment/Daemons
|
Group: System Environment/Daemons
|
||||||
|
|
|
@ -83,7 +83,7 @@ Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}
|
||||||
,libssl | libssl1.0.0 | libssl1.1
|
,libssl | libssl1.0.0 | libssl1.1
|
||||||
,libcrypt-eksblowfish-perl
|
,libcrypt-eksblowfish-perl
|
||||||
,libdata-entropy-perl
|
,libdata-entropy-perl
|
||||||
,libvncclient1
|
,libvncclient1|libvncclient0
|
||||||
Recommends: ${misc:Recommends}
|
Recommends: ${misc:Recommends}
|
||||||
,libapache2-mod-php5 | libapache2-mod-php | php5-fpm | php-fpm
|
,libapache2-mod-php5 | libapache2-mod-php | php5-fpm | php-fpm
|
||||||
,mysql-server | mariadb-server | virtual-mysql-server
|
,mysql-server | mariadb-server | virtual-mysql-server
|
||||||
|
|
|
@ -352,6 +352,11 @@ sub GenerateVideo {
|
||||||
sub delete {
|
sub delete {
|
||||||
my $event = $_[0];
|
my $event = $_[0];
|
||||||
|
|
||||||
|
if ( !$event->canEdit() ) {
|
||||||
|
Warning('No permission to delete event.');
|
||||||
|
return 'No permission to delete event.';
|
||||||
|
}
|
||||||
|
|
||||||
my $in_zmaudit = ( $0 =~ 'zmaudit.pl$');
|
my $in_zmaudit = ( $0 =~ 'zmaudit.pl$');
|
||||||
|
|
||||||
if ( ! $in_zmaudit ) {
|
if ( ! $in_zmaudit ) {
|
||||||
|
@ -402,6 +407,11 @@ sub delete {
|
||||||
sub delete_files {
|
sub delete_files {
|
||||||
my $event = shift;
|
my $event = shift;
|
||||||
|
|
||||||
|
if ( !$event->canEdit() ) {
|
||||||
|
Warning('No permission to delete event.');
|
||||||
|
return 'No permission to delete event.';
|
||||||
|
}
|
||||||
|
|
||||||
foreach my $Storage (
|
foreach my $Storage (
|
||||||
@_ ? ($_[0]) : (
|
@_ ? ($_[0]) : (
|
||||||
new ZoneMinder::Storage($$event{StorageId}),
|
new ZoneMinder::Storage($$event{StorageId}),
|
||||||
|
@ -570,6 +580,11 @@ sub DiskSpace {
|
||||||
sub CopyTo {
|
sub CopyTo {
|
||||||
my ( $self, $NewStorage ) = @_;
|
my ( $self, $NewStorage ) = @_;
|
||||||
|
|
||||||
|
if ( !$self->canEdit() ) {
|
||||||
|
Warning('No permission to copy event.');
|
||||||
|
return 'No permission to copy event.';
|
||||||
|
}
|
||||||
|
|
||||||
my $OldStorage = $self->Storage(undef);
|
my $OldStorage = $self->Storage(undef);
|
||||||
my ( $OldPath ) = ( $self->Path() =~ /^(.*)$/ ); # De-taint
|
my ( $OldPath ) = ( $self->Path() =~ /^(.*)$/ ); # De-taint
|
||||||
if ( ! -e $OldPath ) {
|
if ( ! -e $OldPath ) {
|
||||||
|
@ -734,8 +749,13 @@ sub CopyTo {
|
||||||
} # end sub CopyTo
|
} # end sub CopyTo
|
||||||
|
|
||||||
sub MoveTo {
|
sub MoveTo {
|
||||||
|
|
||||||
my ( $self, $NewStorage ) = @_;
|
my ( $self, $NewStorage ) = @_;
|
||||||
|
|
||||||
|
if ( !$self->canEdit() ) {
|
||||||
|
Warning('No permission to move event.');
|
||||||
|
return 'No permission to move event.';
|
||||||
|
}
|
||||||
|
|
||||||
my $OldStorage = $self->Storage(undef);
|
my $OldStorage = $self->Storage(undef);
|
||||||
|
|
||||||
my $error = $self->CopyTo($NewStorage);
|
my $error = $self->CopyTo($NewStorage);
|
||||||
|
@ -857,16 +877,32 @@ sub files {
|
||||||
|
|
||||||
sub has_capture_jpegs {
|
sub has_capture_jpegs {
|
||||||
@{$_[0]{capture_jpegs}} = grep(/^\d+\-capture\.jpg$/, $_[0]->files());
|
@{$_[0]{capture_jpegs}} = grep(/^\d+\-capture\.jpg$/, $_[0]->files());
|
||||||
Debug("have " . @{$_[0]{capture_jpegs}} . " capture jpegs");
|
Debug('have ' . @{$_[0]{capture_jpegs}} . ' capture jpegs');
|
||||||
return @{$_[0]{capture_jpegs}} ? 1 : 0;
|
return @{$_[0]{capture_jpegs}} ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub has_analyse_jpegs {
|
sub has_analyse_jpegs {
|
||||||
@{$_[0]{analyse_jpegs}} = grep(/^\d+\-analyse\.jpg$/, $_[0]->files());
|
@{$_[0]{analyse_jpegs}} = grep(/^\d+\-analyse\.jpg$/, $_[0]->files());
|
||||||
Debug("have " . @{$_[0]{analyse_jpegs}} . " analyse jpegs");
|
Debug('have ' . @{$_[0]{analyse_jpegs}} . ' analyse jpegs');
|
||||||
return @{$_[0]{analyse_jpegs}} ? 1 : 0;
|
return @{$_[0]{analyse_jpegs}} ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub canEdit {
|
||||||
|
my $self = shift;
|
||||||
|
if ( !$ZoneMinder::user ) {
|
||||||
|
# No user loaded... assume running as system
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if ( !$$ZoneMinder::user{MonitorIds} ) {
|
||||||
|
# User has no monitor limitations
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if ( $$ZoneMinder::user{Events} eq 'Edit' ) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
} # end sub canEdit
|
||||||
|
|
||||||
1;
|
1;
|
||||||
__END__
|
__END__
|
||||||
|
|
||||||
|
|
|
@ -49,49 +49,34 @@ use ZoneMinder::Database qw(:all);
|
||||||
require ZoneMinder::Storage;
|
require ZoneMinder::Storage;
|
||||||
require ZoneMinder::Server;
|
require ZoneMinder::Server;
|
||||||
|
|
||||||
sub Name {
|
use vars qw/ $table $primary_key %fields /;
|
||||||
if ( @_ > 1 ) {
|
$table = 'Users';
|
||||||
$_[0]{Name} = $_[1];
|
$primary_key = 'Id';
|
||||||
}
|
|
||||||
return $_[0]{Name};
|
|
||||||
} # end sub Path
|
|
||||||
|
|
||||||
sub find {
|
%fields = map { $_ => $_ } qw(
|
||||||
shift if $_[0] eq 'ZoneMinder::Filter';
|
Id
|
||||||
my %sql_filters = @_;
|
Name
|
||||||
|
Query_json
|
||||||
my $sql = 'SELECT * FROM Filters';
|
AutoArchive
|
||||||
my @sql_filters;
|
AutoVideo
|
||||||
my @sql_values;
|
AutoUpload
|
||||||
|
AutoEmail
|
||||||
if ( exists $sql_filters{Name} ) {
|
EmailTo
|
||||||
push @sql_filters , ' Name = ? ';
|
EmailSubject
|
||||||
push @sql_values, $sql_filters{Name};
|
EmailBody
|
||||||
}
|
AutoMessage
|
||||||
|
AutoExecute
|
||||||
$sql .= ' WHERE ' . join(' AND ', @sql_filters ) if @sql_filters;
|
AutoExecuteCmd
|
||||||
$sql .= ' LIMIT ' . $sql_filters{limit} if $sql_filters{limit};
|
AutoDelete
|
||||||
|
AutoMove
|
||||||
my $sth = $ZoneMinder::Database::dbh->prepare_cached($sql)
|
AutoMoveTo
|
||||||
or Fatal("Can't prepare '$sql': ".$ZoneMinder::Database::dbh->errstr());
|
AutoCopy
|
||||||
my $res = $sth->execute(@sql_values)
|
AutoCopyTo
|
||||||
or Fatal("Can't execute '$sql': ".$sth->errstr());
|
UpdateDiskSpace
|
||||||
|
UserId
|
||||||
my @results;
|
Background
|
||||||
|
Concurrent
|
||||||
while( my $db_filter = $sth->fetchrow_hashref() ) {
|
);
|
||||||
my $filter = new ZoneMinder::Filter($$db_filter{Id}, $db_filter);
|
|
||||||
push @results, $filter;
|
|
||||||
} # end while
|
|
||||||
$sth->finish();
|
|
||||||
|
|
||||||
return @results;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub find_one {
|
|
||||||
my @results = find(@_);
|
|
||||||
return $results[0] if @results;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub Execute {
|
sub Execute {
|
||||||
my $self = $_[0];
|
my $self = $_[0];
|
||||||
|
@ -324,14 +309,9 @@ sub Sql {
|
||||||
} # end if terms
|
} # end if terms
|
||||||
|
|
||||||
if ( $self->{Sql} ) {
|
if ( $self->{Sql} ) {
|
||||||
if ( $self->{AutoMessage} ) {
|
|
||||||
# Include all events, including events that are still ongoing
|
# Include all events, including events that are still ongoing
|
||||||
# and have no EndTime yet
|
# and have no EndTime yet
|
||||||
$sql .= ' WHERE ( '.$self->{Sql}.' )';
|
$sql .= ' WHERE ( '.$self->{Sql}.' )';
|
||||||
} else {
|
|
||||||
# Only include closed events (events with valid EndTime)
|
|
||||||
$sql .= ' WHERE (E.EndTime IS NOT NULL) AND ( '.$self->{Sql}.' )';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
my @auto_terms;
|
my @auto_terms;
|
||||||
if ( $self->{AutoArchive} ) {
|
if ( $self->{AutoArchive} ) {
|
||||||
|
@ -458,6 +438,15 @@ sub DateTimeToSQL {
|
||||||
return POSIX::strftime('%Y-%m-%d %H:%M:%S', localtime($dt_val));
|
return POSIX::strftime('%Y-%m-%d %H:%M:%S', localtime($dt_val));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub User {
|
||||||
|
my $self = shift;
|
||||||
|
$$self{User} = shift if @_;
|
||||||
|
if ( ! $$self{User} and $$self{UserId} ) {
|
||||||
|
$$self{User} = ZoneMinder::User->find_one(Id=>$$self{UserId});
|
||||||
|
}
|
||||||
|
return $$self{User};
|
||||||
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
__END__
|
__END__
|
||||||
# Below is stub documentation for your module. You'd better edit it!
|
# Below is stub documentation for your module. You'd better edit it!
|
||||||
|
|
|
@ -28,6 +28,9 @@ our %EXPORT_TAGS = (
|
||||||
makePath
|
makePath
|
||||||
jsonEncode
|
jsonEncode
|
||||||
jsonDecode
|
jsonDecode
|
||||||
|
systemStatus
|
||||||
|
packageControl
|
||||||
|
daemonControl
|
||||||
) ]
|
) ]
|
||||||
);
|
);
|
||||||
push( @{$EXPORT_TAGS{all}}, @{$EXPORT_TAGS{$_}} ) foreach keys %EXPORT_TAGS;
|
push( @{$EXPORT_TAGS{all}}, @{$EXPORT_TAGS{$_}} ) foreach keys %EXPORT_TAGS;
|
||||||
|
@ -531,6 +534,38 @@ sub jsonDecode {
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub packageControl {
|
||||||
|
my $command = shift;
|
||||||
|
my $string = $Config{ZM_PATH_BIN}.'/zmpkg.pl '.$command;
|
||||||
|
$string .= ' 2>/dev/null >&- <&- >/dev/null';
|
||||||
|
executeShellCommand($string);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub daemonControl {
|
||||||
|
my ($command, $daemon, $args) = @_;
|
||||||
|
my $string = $Config{ZM_PATH_BIN}.'/zmdc.pl '.$command;
|
||||||
|
if ( $daemon ) {
|
||||||
|
$string .= ' ' . $daemon;
|
||||||
|
if ( $args ) {
|
||||||
|
$string .= ' ' . $args;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#$string .= ' 2>/dev/null >&- <&- >/dev/null';
|
||||||
|
executeShellCommand($string);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub systemStatus {
|
||||||
|
my $command = $Config{ZM_PATH_BIN}.'/zmdc.pl check';
|
||||||
|
my $output = qx($command);
|
||||||
|
my $status = $? >> 8;
|
||||||
|
if ( $status || logDebugging() ) {
|
||||||
|
$output = '' if !defined($output);
|
||||||
|
chomp($output);
|
||||||
|
Debug("Command: $command Output: $output");
|
||||||
|
}
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
__END__
|
__END__
|
||||||
# Below is stub documentation for your module. You'd better edit it!
|
# Below is stub documentation for your module. You'd better edit it!
|
||||||
|
@ -542,7 +577,6 @@ ZoneMinder::General - Utility Functions for ZoneMinder
|
||||||
=head1 SYNOPSIS
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
use ZoneMinder::General;
|
use ZoneMinder::General;
|
||||||
blah blah blah
|
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
|
@ -561,6 +595,9 @@ of the ZoneMinder scripts
|
||||||
makePath
|
makePath
|
||||||
jsonEncode
|
jsonEncode
|
||||||
jsonDecode
|
jsonDecode
|
||||||
|
packageControl
|
||||||
|
daemonControl
|
||||||
|
systemStatus
|
||||||
) ]
|
) ]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
# ==========================================================================
|
||||||
|
#
|
||||||
|
# ZoneMinder User Module
|
||||||
|
# Copyright (C) 2020 ZoneMinder LLC
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
#
|
||||||
|
# ==========================================================================
|
||||||
|
|
||||||
|
package ZoneMinder::Frame;
|
||||||
|
|
||||||
|
use 5.006;
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
require ZoneMinder::Base;
|
||||||
|
require ZoneMinder::Object;
|
||||||
|
|
||||||
|
use parent qw(ZoneMinder::Object);
|
||||||
|
|
||||||
|
use vars qw/ $table $primary_key %fields /;
|
||||||
|
$table = 'Users';
|
||||||
|
$primary_key = 'Id';
|
||||||
|
|
||||||
|
%fields = map { $_ => $_ } qw(
|
||||||
|
Id
|
||||||
|
Username
|
||||||
|
Password
|
||||||
|
Language
|
||||||
|
Enabled
|
||||||
|
Stream
|
||||||
|
Events
|
||||||
|
Control
|
||||||
|
Monitors
|
||||||
|
Groups
|
||||||
|
Devices
|
||||||
|
System
|
||||||
|
MaxBandwidth
|
||||||
|
MonitorIds
|
||||||
|
TokenMinExpiry
|
||||||
|
APIEnabled
|
||||||
|
);
|
||||||
|
|
||||||
|
1;
|
||||||
|
__END__
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
ZoneMinder::User - Perl Class for Users
|
||||||
|
|
||||||
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
|
use ZoneMinder::User;
|
||||||
|
|
||||||
|
=head1 AUTHOR
|
||||||
|
|
||||||
|
Isaac Connor, E<lt>isaac@zoneminder.comE<gt>
|
||||||
|
|
||||||
|
=head1 COPYRIGHT AND LICENSE
|
||||||
|
|
||||||
|
Copyright (C) 2001-2017 ZoneMinder LLC
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify
|
||||||
|
it under the same terms as Perl itself, either Perl version 5.8.3 or,
|
||||||
|
at your option, any later version of Perl 5 you may have available.
|
||||||
|
|
||||||
|
|
||||||
|
=cut
|
|
@ -119,8 +119,13 @@ GetOptions(
|
||||||
) or pod2usage(-exitstatus => -1);
|
) or pod2usage(-exitstatus => -1);
|
||||||
|
|
||||||
my $dbh = zmDbConnect(undef, { mysql_multi_statements=>1 } );
|
my $dbh = zmDbConnect(undef, { mysql_multi_statements=>1 } );
|
||||||
|
if ( !$dbh ) {
|
||||||
|
die "Unable to connect to db\n";
|
||||||
|
}
|
||||||
$Config{ZM_DB_USER} = $dbUser;
|
$Config{ZM_DB_USER} = $dbUser;
|
||||||
$Config{ZM_DB_PASS} = $dbPass;
|
$Config{ZM_DB_PASS} = $dbPass;
|
||||||
|
# we escape dbpass with single quotes so that $ in the password has no effect, but dbpass could have a ' in it.
|
||||||
|
$dbPass =~ s/'/\\'/g;
|
||||||
|
|
||||||
if ( ! ($check || $freshen || $rename || $zoneFix || $migrateEvents || $version) ) {
|
if ( ! ($check || $freshen || $rename || $zoneFix || $migrateEvents || $version) ) {
|
||||||
if ( $Config{ZM_DYN_DB_VERSION} ) {
|
if ( $Config{ZM_DYN_DB_VERSION} ) {
|
||||||
|
@ -137,7 +142,7 @@ if ( ($check + $freshen + $rename + $zoneFix + $migrateEvents + ($version?1:0))
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $check && $Config{ZM_CHECK_FOR_UPDATES} ) {
|
if ( $check && $Config{ZM_CHECK_FOR_UPDATES} ) {
|
||||||
print( "Update agent starting at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" );
|
print('Update agent starting at '.strftime('%y/%m/%d %H:%M:%S', localtime() )."\n");
|
||||||
|
|
||||||
my $currVersion = $Config{ZM_DYN_CURR_VERSION};
|
my $currVersion = $Config{ZM_DYN_CURR_VERSION};
|
||||||
my $lastVersion = $Config{ZM_DYN_LAST_VERSION};
|
my $lastVersion = $Config{ZM_DYN_LAST_VERSION};
|
||||||
|
@ -148,18 +153,18 @@ if ( $check && $Config{ZM_CHECK_FOR_UPDATES} ) {
|
||||||
|
|
||||||
my $sql = "update Config set Value = ? where Name = 'ZM_DYN_CURR_VERSION'";
|
my $sql = "update Config set Value = ? where Name = 'ZM_DYN_CURR_VERSION'";
|
||||||
my $sth = $dbh->prepare_cached($sql) or die("Can't prepare '$sql': ".$dbh->errstr());
|
my $sth = $dbh->prepare_cached($sql) or die("Can't prepare '$sql': ".$dbh->errstr());
|
||||||
my $res = $sth->execute( "$currVersion" ) or die( "Can't execute: ".$sth->errstr() );
|
my $res = $sth->execute($currVersion) or die("Can't execute: ".$sth->errstr());
|
||||||
$sth->finish();
|
$sth->finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
while ( 1 ) {
|
while ( 1 ) {
|
||||||
my $now = time();
|
my $now = time();
|
||||||
if ( !$lastVersion || !$lastCheck || (($now-$lastCheck) > CHECK_INTERVAL) ) {
|
if ( !$lastVersion || !$lastCheck || (($now-$lastCheck) > CHECK_INTERVAL) ) {
|
||||||
Info( "Checking for updates\n" );
|
Info('Checking for updates');
|
||||||
|
|
||||||
use LWP::UserAgent;
|
use LWP::UserAgent;
|
||||||
my $ua = LWP::UserAgent->new;
|
my $ua = LWP::UserAgent->new;
|
||||||
$ua->agent( "ZoneMinder Update Agent/".ZM_VERSION );
|
$ua->agent('ZoneMinder Update Agent/'.ZM_VERSION);
|
||||||
if ( $Config{ZM_UPDATE_CHECK_PROXY} ) {
|
if ( $Config{ZM_UPDATE_CHECK_PROXY} ) {
|
||||||
$ua->proxy('http', $Config{ZM_UPDATE_CHECK_PROXY});
|
$ua->proxy('http', $Config{ZM_UPDATE_CHECK_PROXY});
|
||||||
}
|
}
|
||||||
|
@ -171,24 +176,24 @@ if ( $check && $Config{ZM_CHECK_FOR_UPDATES} ) {
|
||||||
chomp($lastVersion);
|
chomp($lastVersion);
|
||||||
$lastCheck = $now;
|
$lastCheck = $now;
|
||||||
|
|
||||||
Info( "Got version: '".$lastVersion."'\n" );
|
Info('Got version: '.$lastVersion);
|
||||||
|
|
||||||
my $lv_sql = "update Config set Value = ? where Name = 'ZM_DYN_LAST_VERSION'";
|
my $lv_sql = 'UPDATE Config SET Value = ? WHERE Name = \'ZM_DYN_LAST_VERSION\'';
|
||||||
my $lv_sth = $dbh->prepare_cached($lv_sql) or die("Can't prepare '$lv_sql': ".$dbh->errstr());
|
my $lv_sth = $dbh->prepare_cached($lv_sql) or die("Can't prepare '$lv_sql': ".$dbh->errstr());
|
||||||
my $lv_res = $lv_sth->execute($lastVersion) or die("Can't execute: ".$lv_sth->errstr());
|
my $lv_res = $lv_sth->execute($lastVersion) or die("Can't execute: ".$lv_sth->errstr());
|
||||||
$lv_sth->finish();
|
$lv_sth->finish();
|
||||||
|
|
||||||
my $lc_sql = "update Config set Value = ? where Name = 'ZM_DYN_LAST_CHECK'";
|
my $lc_sql = 'UPDATE Config SET Value = ? WHERE Name = \'ZM_DYN_LAST_CHECK\'';
|
||||||
my $lc_sth = $dbh->prepare_cached($lc_sql) or die("Can't prepare '$lc_sql': ".$dbh->errstr());
|
my $lc_sth = $dbh->prepare_cached($lc_sql) or die("Can't prepare '$lc_sql': ".$dbh->errstr());
|
||||||
my $lc_res = $lc_sth->execute($lastCheck) or die("Can't execute: ".$lc_sth->errstr());
|
my $lc_res = $lc_sth->execute($lastCheck) or die("Can't execute: ".$lc_sth->errstr());
|
||||||
$lc_sth->finish();
|
$lc_sth->finish();
|
||||||
} else {
|
} else {
|
||||||
Error( "Error check failed: '".$res->status_line()."'\n" );
|
Error('Error check failed: \''.$res->status_line().'\'');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sleep(3600);
|
sleep(3600);
|
||||||
}
|
}
|
||||||
print( "Update agent exiting at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" );
|
print('Update agent exiting at '.strftime('%y/%m/%d %H:%M:%S', localtime())."\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $rename ) {
|
if ( $rename ) {
|
||||||
|
@ -207,17 +212,17 @@ if ( $rename ) {
|
||||||
if ( $file !~ /(capture|analyse)-(\d+)(\.jpg)/ ) {
|
if ( $file !~ /(capture|analyse)-(\d+)(\.jpg)/ ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
my $newFile = "$2-$1$3";
|
my $newFile = $2.'-'.$1.$3;
|
||||||
|
|
||||||
print("Renaming '$file' to '$newFile'\n");
|
print("Renaming '$file' to '$newFile'\n");
|
||||||
rename($file, $newFile) or warn("Can't rename '$file' to '$newFile'");
|
rename($file, $newFile) or warn("Can't rename '$file' to '$newFile'");
|
||||||
}
|
}
|
||||||
|
|
||||||
File::Find::find(\&renameImage, '.');
|
File::Find::find(\&renameImage, '.');
|
||||||
}
|
} # end if rename
|
||||||
if ( $zoneFix ) {
|
|
||||||
|
|
||||||
my $sql = "select Z.*, M.Width as MonitorWidth, M.Height as MonitorHeight from Zones as Z inner join Monitors as M on Z.MonitorId = M.Id where Z.Units = 'Percent'";
|
if ( $zoneFix ) {
|
||||||
|
my $sql = "SELECT Z.*, M.Width AS MonitorWidth, M.Height AS MonitorHeight FROM Zones AS Z INNER JOIN Monitors AS M ON Z.MonitorId = M.Id WHERE Z.Units = 'Percent'";
|
||||||
my $sth = $dbh->prepare_cached($sql) or die("Can't prepare '$sql': ".$dbh->errstr());
|
my $sth = $dbh->prepare_cached($sql) or die("Can't prepare '$sql': ".$dbh->errstr());
|
||||||
my $res = $sth->execute() or die("Can't execute: ".$sth->errstr());
|
my $res = $sth->execute() or die("Can't execute: ".$sth->errstr());
|
||||||
my @zones;
|
my @zones;
|
||||||
|
@ -226,7 +231,7 @@ if ( $zoneFix ) {
|
||||||
}
|
}
|
||||||
$sth->finish();
|
$sth->finish();
|
||||||
|
|
||||||
$sql = 'update Zones set MinAlarmPixels = ?, MaxAlarmPixels = ?, MinFilterPixels = ?, MaxFilterPixels = ?, MinBlobPixels = ?, MaxBlobPixels = ? where Id = ?';
|
$sql = 'UPDATE Zones SET MinAlarmPixels = ?, MaxAlarmPixels = ?, MinFilterPixels = ?, MaxFilterPixels = ?, MinBlobPixels = ?, MaxBlobPixels = ? WHERE Id = ?';
|
||||||
$sth = $dbh->prepare_cached($sql) or die("Can't prepare '$sql': ".$dbh->errstr());
|
$sth = $dbh->prepare_cached($sql) or die("Can't prepare '$sql': ".$dbh->errstr());
|
||||||
foreach my $zone ( @zones ) {
|
foreach my $zone ( @zones ) {
|
||||||
my $zone_width = (($zone->{HiX}*$zone->{MonitorWidth})-($zone->{LoX}*$zone->{MonitorWidth}))/100;
|
my $zone_width = (($zone->{HiX}*$zone->{MonitorWidth})-($zone->{LoX}*$zone->{MonitorWidth}))/100;
|
||||||
|
@ -244,7 +249,8 @@ if ( $zoneFix ) {
|
||||||
) or die("Can't execute: ".$sth->errstr());
|
) or die("Can't execute: ".$sth->errstr());
|
||||||
}
|
}
|
||||||
$sth->finish();
|
$sth->finish();
|
||||||
}
|
} # end if zoneFix
|
||||||
|
|
||||||
if ( $migrateEvents ) {
|
if ( $migrateEvents ) {
|
||||||
my $webUid = (getpwnam($Config{ZM_WEB_USER}))[2];
|
my $webUid = (getpwnam($Config{ZM_WEB_USER}))[2];
|
||||||
my $webGid = (getgrnam($Config{ZM_WEB_USER}))[2];
|
my $webGid = (getgrnam($Config{ZM_WEB_USER}))[2];
|
||||||
|
@ -260,7 +266,11 @@ if ( $migrateEvents ) {
|
||||||
$< = $webUid;
|
$< = $webUid;
|
||||||
$> = $webUid;
|
$> = $webUid;
|
||||||
|
|
||||||
print( "\nAbout to convert saved events to deep storage, please ensure that ZoneMinder is fully stopped before proceeding.\nThis process is not easily reversible. Are you sure you wish to proceed?\n\nPress 'y' to continue or 'n' to abort : " );
|
print('
|
||||||
|
About to convert saved events to deep storage, please ensure that ZoneMinder is fully stopped before proceeding.
|
||||||
|
This process is not easily reversible. Are you sure you wish to proceed?
|
||||||
|
|
||||||
|
Press \'y\' to continue or \'n\' to abort : ');
|
||||||
my $response = <STDIN>;
|
my $response = <STDIN>;
|
||||||
chomp($response);
|
chomp($response);
|
||||||
while ( $response !~ /^[yYnN]$/ ) {
|
while ( $response !~ /^[yYnN]$/ ) {
|
||||||
|
@ -273,7 +283,7 @@ if ( $migrateEvents ) {
|
||||||
print("Converting all events to deep storage.\n");
|
print("Converting all events to deep storage.\n");
|
||||||
|
|
||||||
chdir($Config{ZM_PATH_WEB});
|
chdir($Config{ZM_PATH_WEB});
|
||||||
my $sql = "select *, unix_timestamp(StartTime) as UnixStartTime from Events";
|
my $sql = 'SELECT *, unix_timestamp(StartTime) AS UnixStartTime FROM Events';
|
||||||
my $sth = $dbh->prepare_cached($sql) or Fatal("Can't prepare '$sql': ".$dbh->errstr());
|
my $sth = $dbh->prepare_cached($sql) or Fatal("Can't prepare '$sql': ".$dbh->errstr());
|
||||||
my $res = $sth->execute();
|
my $res = $sth->execute();
|
||||||
if ( !$res ) {
|
if ( !$res ) {
|
||||||
|
@ -288,9 +298,9 @@ if ( $migrateEvents ) {
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
|
||||||
print( "Converting event ".$event->{Id}."\n" );
|
print('Converting event '.$event->{Id}."\n");
|
||||||
my $newDatePath = $Config{ZM_DIR_EVENTS}.'/'.$event->{MonitorId}.'/'.strftime( "%y/%m/%d", localtime($event->{UnixStartTime}) );
|
my $newDatePath = $Config{ZM_DIR_EVENTS}.'/'.$event->{MonitorId}.'/'.strftime('%y/%m/%d', localtime($event->{UnixStartTime}));
|
||||||
my $newTimePath = strftime( "%H/%M/%S", localtime($event->{UnixStartTime}) );
|
my $newTimePath = strftime('%H/%M/%S', localtime($event->{UnixStartTime}));
|
||||||
my $newEventPath = $newDatePath.'/'.$newTimePath;
|
my $newEventPath = $newDatePath.'/'.$newTimePath;
|
||||||
( my $truncEventPath = $newEventPath ) =~ s|/\d+$||;
|
( my $truncEventPath = $newEventPath ) =~ s|/\d+$||;
|
||||||
makePath($truncEventPath, $Config{ZM_PATH_WEB});
|
makePath($truncEventPath, $Config{ZM_PATH_WEB});
|
||||||
|
@ -311,6 +321,7 @@ if ( $migrateEvents ) {
|
||||||
print("Aborting event conversion.\n\n");
|
print("Aborting event conversion.\n\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $freshen ) {
|
if ( $freshen ) {
|
||||||
print("\nFreshening configuration in database\n");
|
print("\nFreshening configuration in database\n");
|
||||||
migratePaths();
|
migratePaths();
|
||||||
|
@ -333,8 +344,13 @@ if ( $interactive ) {
|
||||||
$sth->finish();
|
$sth->finish();
|
||||||
|
|
||||||
if ( @MyISAM_Tables ) {
|
if ( @MyISAM_Tables ) {
|
||||||
print( "\nPrevious versions of ZoneMinder used the MyISAM database engine.\nHowever, the recommended database engine is InnoDB.\n");
|
print('
|
||||||
print( "\nHint: InnoDB tables are much less likely to be corrupted during an unclean shutdown.\n\nPress 'y' to convert your tables to InnoDB or 'n' to skip : ");
|
Previous versions of ZoneMinder used the MyISAM database engine.
|
||||||
|
However, the recommended database engine is InnoDB.
|
||||||
|
|
||||||
|
Hint: InnoDB tables are much less likely to be corrupted during an unclean shutdown.
|
||||||
|
|
||||||
|
Press \'y\' to convert your tables to InnoDB or \'n\' to skip : ');
|
||||||
my $response = <STDIN>;
|
my $response = <STDIN>;
|
||||||
chomp( $response );
|
chomp( $response );
|
||||||
if ( $response =~ /^[yY]$/ ) {
|
if ( $response =~ /^[yY]$/ ) {
|
||||||
|
@ -360,18 +376,26 @@ if ( $version ) {
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my $start_zm = 0;
|
||||||
print("\nInitiating database upgrade to version ".ZM_VERSION." from version $version\n");
|
print("\nInitiating database upgrade to version ".ZM_VERSION." from version $version\n");
|
||||||
if ( $interactive ) {
|
if ( $interactive ) {
|
||||||
if ( $Config{ZM_DYN_DB_VERSION} && $Config{ZM_DYN_DB_VERSION} ne $version ) {
|
if ( $Config{ZM_DYN_DB_VERSION} && ($Config{ZM_DYN_DB_VERSION} ne $version) ) {
|
||||||
print( "\nWARNING - You have specified an upgrade from version $version but the database version found is ".$Config{ZM_DYN_DB_VERSION}.". Is this correct?\nPress enter to continue or ctrl-C to abort : " );
|
print("\nWARNING - You have specified an upgrade from version $version but the database version found is $Config{ZM_DYN_DB_VERSION}. Is this correct?\nPress enter to continue or ctrl-C to abort : ");
|
||||||
my $response = <STDIN>;
|
my $response = <STDIN>;
|
||||||
}
|
}
|
||||||
|
|
||||||
print( "\nPlease ensure that ZoneMinder is stopped on your system prior to upgrading the database.\nPress enter to continue or ctrl-C to stop : " );
|
if ( systemStatus() eq 'running' ) {
|
||||||
|
print"\nZoneMinder system appears to be running. While not strictly required, it is advised to stop ZM during the update process. Would you like to stop ZM now? [Yn]:";
|
||||||
my $response = <STDIN>;
|
my $response = <STDIN>;
|
||||||
|
chomp($response);
|
||||||
|
if ( $response !~ /Yy/ ) {
|
||||||
|
packageControl('stop');
|
||||||
|
$start_zm = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
print("\nDo you wish to take a backup of your database prior to upgrading?\nThis may result in a large file in @ZM_TMPDIR@ if you have a lot of events.\nPress 'y' for a backup or 'n' to continue : ");
|
print("\nDo you wish to take a backup of your database prior to upgrading?\nThis may result in a large file in @ZM_TMPDIR@ if you have a lot of events.\nPress 'y' for a backup or 'n' to continue : ");
|
||||||
$response = <STDIN>;
|
my $response = <STDIN>;
|
||||||
chomp($response);
|
chomp($response);
|
||||||
while ( $response !~ /^[yYnN]$/ ) {
|
while ( $response !~ /^[yYnN]$/ ) {
|
||||||
print("Please press 'y' for a backup or 'n' to continue only : ");
|
print("Please press 'y' for a backup or 'n' to continue only : ");
|
||||||
|
@ -384,21 +408,22 @@ if ( $version ) {
|
||||||
my $command = 'mysqldump';
|
my $command = 'mysqldump';
|
||||||
if ( defined($portOrSocket) ) {
|
if ( defined($portOrSocket) ) {
|
||||||
if ( $portOrSocket =~ /^\// ) {
|
if ( $portOrSocket =~ /^\// ) {
|
||||||
$command .= " -S".$portOrSocket;
|
$command .= ' -S'.$portOrSocket;
|
||||||
} else {
|
} else {
|
||||||
$command .= " -h".$host." -P".$portOrSocket;
|
$command .= ' -h'.$host.' -P'.$portOrSocket;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$command .= " -h".$host;
|
$command .= ' -h'.$host;
|
||||||
}
|
}
|
||||||
if ( $dbUser ) {
|
if ( $dbUser ) {
|
||||||
$command .= ' -u'.$dbUser;
|
$command .= ' -u'.$dbUser;
|
||||||
$command .= ' -p"'.$dbPass.'"' if $dbPass;
|
$command .= ' -p\''.$dbPass.'\'' if $dbPass;
|
||||||
}
|
}
|
||||||
my $backup = "@ZM_TMPDIR@/".$Config{ZM_DB_NAME}."-".$version.".dump";
|
my $backup = '@ZM_TMPDIR@/'.$Config{ZM_DB_NAME}.'-'.$version.'.dump';
|
||||||
$command .= " --add-drop-table --databases ".$Config{ZM_DB_NAME}." > ".$backup;
|
$command .= ' --add-drop-table --databases '.$Config{ZM_DB_NAME}.' > '.$backup;
|
||||||
print("Creating backup to $backup. This may take several minutes.\n");
|
print("Creating backup to $backup. This may take several minutes.\n");
|
||||||
print( "Executing '$command'\n" ) if ( logDebugging() );
|
($command) = $command =~ /(.*)/; # detaint
|
||||||
|
print("Executing '$command'\n") if logDebugging();
|
||||||
my $output = qx($command);
|
my $output = qx($command);
|
||||||
my $status = $? >> 8;
|
my $status = $? >> 8;
|
||||||
if ( $status || logDebugging() ) {
|
if ( $status || logDebugging() ) {
|
||||||
|
@ -933,7 +958,12 @@ if ( $version ) {
|
||||||
#my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
|
#my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
|
||||||
#my $res = $sth->execute( ) or die( "Can't execute: ".$sth->errstr() );
|
#my $res = $sth->execute( ) or die( "Can't execute: ".$sth->errstr() );
|
||||||
#$sth->finish();
|
#$sth->finish();
|
||||||
|
|
||||||
print("\nDatabase upgrade to version ".ZM_VERSION." successful.\n\n");
|
print("\nDatabase upgrade to version ".ZM_VERSION." successful.\n\n");
|
||||||
|
if ( $start_zm ) {
|
||||||
|
print("Starting ZM since we stopped it for the update\n");
|
||||||
|
packageControl('start');
|
||||||
|
}
|
||||||
} # end if version
|
} # end if version
|
||||||
|
|
||||||
zmDbDisconnect();
|
zmDbDisconnect();
|
||||||
|
@ -969,7 +999,7 @@ sub patchDB {
|
||||||
my $dbh = shift;
|
my $dbh = shift;
|
||||||
my $version = shift;
|
my $version = shift;
|
||||||
|
|
||||||
my ( $host, $portOrSocket ) = ( $Config{ZM_DB_HOST} =~ /^([^:]+)(?::(.+))?$/ );
|
my ( $host, $portOrSocket ) = ( $Config{ZM_DB_HOST} =~ /^([^:]+)(?::(.+))?$/ ) if $Config{ZM_DB_HOST};
|
||||||
my $command = 'mysql';
|
my $command = 'mysql';
|
||||||
if ( defined($portOrSocket) ) {
|
if ( defined($portOrSocket) ) {
|
||||||
if ( $portOrSocket =~ /^\// ) {
|
if ( $portOrSocket =~ /^\// ) {
|
||||||
|
@ -977,12 +1007,12 @@ sub patchDB {
|
||||||
} else {
|
} else {
|
||||||
$command .= ' -h'.$host.' -P'.$portOrSocket;
|
$command .= ' -h'.$host.' -P'.$portOrSocket;
|
||||||
}
|
}
|
||||||
} else {
|
} elsif ( $host ) {
|
||||||
$command .= ' -h'.$host;
|
$command .= ' -h'.$host;
|
||||||
}
|
}
|
||||||
if ( $dbUser ) {
|
if ( $dbUser ) {
|
||||||
$command .= ' -u'.$dbUser;
|
$command .= ' -u'.$dbUser;
|
||||||
$command .= ' -p"'.$dbPass.'"' if $dbPass;
|
$command .= ' -p\''.$dbPass.'\'' if $dbPass;
|
||||||
}
|
}
|
||||||
$command .= ' '.$Config{ZM_DB_NAME}.' < ';
|
$command .= ' '.$Config{ZM_DB_NAME}.' < ';
|
||||||
if ( $updateDir ) {
|
if ( $updateDir ) {
|
||||||
|
@ -993,6 +1023,7 @@ sub patchDB {
|
||||||
$command .= '/zm_update-'.$version.'.sql';
|
$command .= '/zm_update-'.$version.'.sql';
|
||||||
|
|
||||||
print("Executing '$command'\n") if logDebugging();
|
print("Executing '$command'\n") if logDebugging();
|
||||||
|
($command) = $command =~ /(.*)/; # detaint
|
||||||
my $output = qx($command);
|
my $output = qx($command);
|
||||||
my $status = $? >> 8;
|
my $status = $? >> 8;
|
||||||
if ( $status || logDebugging() ) {
|
if ( $status || logDebugging() ) {
|
||||||
|
|
|
@ -976,10 +976,12 @@ int FfmpegCamera::CaptureAndRecord(
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#if HAVE_LIBAVUTIL_HWCONTEXT_H
|
#if HAVE_LIBAVUTIL_HWCONTEXT_H
|
||||||
|
#if LIBAVCODEC_VERSION_CHECK(57, 89, 0, 89, 0)
|
||||||
if ( (ret == AVERROR_INVALIDDATA ) && (hw_pix_fmt != AV_PIX_FMT_NONE) ) {
|
if ( (ret == AVERROR_INVALIDDATA ) && (hw_pix_fmt != AV_PIX_FMT_NONE) ) {
|
||||||
use_hwaccel = false;
|
use_hwaccel = false;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
zm_av_packet_unref(&packet);
|
zm_av_packet_unref(&packet);
|
||||||
|
|
|
@ -1967,10 +1967,19 @@ void Image::Annotate( const char *p_text, const Coord &coord, const unsigned int
|
||||||
unsigned char *temp_ptr = ptr;
|
unsigned char *temp_ptr = ptr;
|
||||||
for ( unsigned int x = lo_line_x, c = 0; x < hi_line_x && c < line_len; c++ ) {
|
for ( unsigned int x = lo_line_x, c = 0; x < hi_line_x && c < line_len; c++ ) {
|
||||||
int f;
|
int f;
|
||||||
if (size == 2)
|
if ( size == 2 ) {
|
||||||
|
if ( (line[c] * ZM_CHAR_HEIGHT * size) + r > sizeof(bigfontdata) ) {
|
||||||
|
Warning("Unsupported character %c in %s", line[c], line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
f = bigfontdata[(line[c] * ZM_CHAR_HEIGHT * size) + r];
|
f = bigfontdata[(line[c] * ZM_CHAR_HEIGHT * size) + r];
|
||||||
else
|
} else {
|
||||||
|
if ( (line[c] * ZM_CHAR_HEIGHT) + r > sizeof(fontdata) ) {
|
||||||
|
Warning("Unsupported character %c in %s", line[c], line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
f = fontdata[(line[c] * ZM_CHAR_HEIGHT) + r];
|
f = fontdata[(line[c] * ZM_CHAR_HEIGHT) + r];
|
||||||
|
}
|
||||||
for ( unsigned int i = 0; i < (ZM_CHAR_WIDTH * size) && x < hi_line_x; i++, x++, temp_ptr++ ) {
|
for ( unsigned int i = 0; i < (ZM_CHAR_WIDTH * size) && x < hi_line_x; i++, x++, temp_ptr++ ) {
|
||||||
if ( f & (zm_text_bitmask >> i) ) {
|
if ( f & (zm_text_bitmask >> i) ) {
|
||||||
if ( !fg_trans )
|
if ( !fg_trans )
|
||||||
|
@ -1989,10 +1998,19 @@ void Image::Annotate( const char *p_text, const Coord &coord, const unsigned int
|
||||||
unsigned char *temp_ptr = ptr;
|
unsigned char *temp_ptr = ptr;
|
||||||
for ( unsigned int x = lo_line_x, c = 0; x < hi_line_x && c < line_len; c++ ) {
|
for ( unsigned int x = lo_line_x, c = 0; x < hi_line_x && c < line_len; c++ ) {
|
||||||
int f;
|
int f;
|
||||||
if (size == 2)
|
if ( size == 2 ) {
|
||||||
|
if ( (line[c] * ZM_CHAR_HEIGHT * size) + r > sizeof(bigfontdata) ) {
|
||||||
|
Warning("Unsupported character %c in %s", line[c], line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
f = bigfontdata[(line[c] * ZM_CHAR_HEIGHT * size) + r];
|
f = bigfontdata[(line[c] * ZM_CHAR_HEIGHT * size) + r];
|
||||||
else
|
} else {
|
||||||
|
if ( (line[c] * ZM_CHAR_HEIGHT) + r > sizeof(fontdata) ) {
|
||||||
|
Warning("Unsupported character %c in %s", line[c], line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
f = fontdata[(line[c] * ZM_CHAR_HEIGHT) + r];
|
f = fontdata[(line[c] * ZM_CHAR_HEIGHT) + r];
|
||||||
|
}
|
||||||
for ( unsigned int i = 0; i < (ZM_CHAR_WIDTH * size) && x < hi_line_x; i++, x++, temp_ptr += colours ) {
|
for ( unsigned int i = 0; i < (ZM_CHAR_WIDTH * size) && x < hi_line_x; i++, x++, temp_ptr += colours ) {
|
||||||
if ( f & (zm_text_bitmask >> i) ) {
|
if ( f & (zm_text_bitmask >> i) ) {
|
||||||
if ( !fg_trans ) {
|
if ( !fg_trans ) {
|
||||||
|
@ -2016,10 +2034,19 @@ void Image::Annotate( const char *p_text, const Coord &coord, const unsigned int
|
||||||
Rgb* temp_ptr = (Rgb*)ptr;
|
Rgb* temp_ptr = (Rgb*)ptr;
|
||||||
for ( unsigned int x = lo_line_x, c = 0; x < hi_line_x && c < line_len; c++ ) {
|
for ( unsigned int x = lo_line_x, c = 0; x < hi_line_x && c < line_len; c++ ) {
|
||||||
int f;
|
int f;
|
||||||
if (size == 2)
|
if ( size == 2 ) {
|
||||||
|
if ( (line[c] * ZM_CHAR_HEIGHT * size) + r > sizeof(bigfontdata) ) {
|
||||||
|
Warning("Unsupported character %c in %s", line[c], line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
f = bigfontdata[(line[c] * ZM_CHAR_HEIGHT * size) + r];
|
f = bigfontdata[(line[c] * ZM_CHAR_HEIGHT * size) + r];
|
||||||
else
|
} else {
|
||||||
|
if ( (line[c] * ZM_CHAR_HEIGHT) + r > sizeof(fontdata) ) {
|
||||||
|
Warning("Unsupported character %c in %s", line[c], line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
f = fontdata[(line[c] * ZM_CHAR_HEIGHT) + r];
|
f = fontdata[(line[c] * ZM_CHAR_HEIGHT) + r];
|
||||||
|
}
|
||||||
for ( unsigned int i = 0; i < (ZM_CHAR_WIDTH * size) && x < hi_line_x; i++, x++, temp_ptr++ ) {
|
for ( unsigned int i = 0; i < (ZM_CHAR_WIDTH * size) && x < hi_line_x; i++, x++, temp_ptr++ ) {
|
||||||
if ( f & (zm_text_bitmask >> i) ) {
|
if ( f & (zm_text_bitmask >> i) ) {
|
||||||
if ( !fg_trans ) {
|
if ( !fg_trans ) {
|
||||||
|
|
|
@ -1276,54 +1276,60 @@ uint32_t LocalCamera::AutoSelectFormat(int p_colours) {
|
||||||
|
|
||||||
bool LocalCamera::GetCurrentSettings(const char *device, char *output, int version, bool verbose) {
|
bool LocalCamera::GetCurrentSettings(const char *device, char *output, int version, bool verbose) {
|
||||||
output[0] = 0;
|
output[0] = 0;
|
||||||
|
char *output_ptr = output;
|
||||||
|
|
||||||
char queryDevice[PATH_MAX] = "";
|
char queryDevice[PATH_MAX] = "";
|
||||||
int devIndex = 0;
|
int devIndex = 0;
|
||||||
do {
|
do {
|
||||||
if ( device )
|
if ( device ) {
|
||||||
strncpy(queryDevice, device, sizeof(queryDevice)-1);
|
strncpy(queryDevice, device, sizeof(queryDevice)-1);
|
||||||
else
|
} else {
|
||||||
sprintf(queryDevice, "/dev/video%d", devIndex);
|
sprintf(queryDevice, "/dev/video%d", devIndex);
|
||||||
|
}
|
||||||
|
|
||||||
if ( (vid_fd = open(queryDevice, O_RDWR)) <= 0 ) {
|
if ( (vid_fd = open(queryDevice, O_RDWR)) <= 0 ) {
|
||||||
if ( device ) {
|
if ( device ) {
|
||||||
Error("Failed to open video device %s: %s", queryDevice, strerror(errno));
|
Error("Failed to open video device %s: %s", queryDevice, strerror(errno));
|
||||||
if ( verbose )
|
if ( verbose )
|
||||||
sprintf(output+strlen(output), "Error, failed to open video device %s: %s\n",
|
output_ptr += sprintf(output_ptr, "Error, failed to open video device %s: %s\n",
|
||||||
queryDevice, strerror(errno));
|
queryDevice, strerror(errno));
|
||||||
else
|
else
|
||||||
sprintf(output+strlen(output), "error%d\n", errno);
|
output_ptr += sprintf(output_ptr, "error%d\n", errno);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( verbose )
|
if ( verbose ) {
|
||||||
sprintf(output+strlen(output), "Video Device: %s\n", queryDevice);
|
output_ptr += sprintf(output_ptr, "Video Device: %s\n", queryDevice);
|
||||||
else
|
} else {
|
||||||
sprintf(output+strlen(output), "d:%s|", queryDevice);
|
output_ptr += sprintf(output_ptr, "d:%s|", queryDevice);
|
||||||
|
}
|
||||||
|
|
||||||
#if ZM_HAS_V4L2
|
#if ZM_HAS_V4L2
|
||||||
if ( version == 2 ) {
|
if ( version == 2 ) {
|
||||||
struct v4l2_capability vid_cap;
|
struct v4l2_capability vid_cap;
|
||||||
if ( vidioctl(vid_fd, VIDIOC_QUERYCAP, &vid_cap) < 0 ) {
|
if ( vidioctl(vid_fd, VIDIOC_QUERYCAP, &vid_cap) < 0 ) {
|
||||||
Error("Failed to query video device: %s", strerror(errno));
|
Error("Failed to query video device: %s", strerror(errno));
|
||||||
if ( verbose )
|
if ( verbose ) {
|
||||||
sprintf(output, "Error, failed to query video capabilities %s: %s\n",
|
output_ptr += sprintf(output_ptr, "Error, failed to query video capabilities %s: %s\n",
|
||||||
queryDevice, strerror(errno));
|
queryDevice, strerror(errno));
|
||||||
else
|
} else {
|
||||||
sprintf(output, "error%d\n", errno);
|
output_ptr += sprintf(output_ptr, "error%d\n", errno);
|
||||||
|
}
|
||||||
|
if ( device )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( verbose ) {
|
if ( verbose ) {
|
||||||
sprintf(output+strlen(output), "General Capabilities\n");
|
output_ptr += sprintf(output_ptr, "General Capabilities\n"
|
||||||
sprintf(output+strlen(output), " Driver: %s\n", vid_cap.driver);
|
" Driver: %s\n"
|
||||||
sprintf(output+strlen(output), " Card: %s\n", vid_cap.card);
|
" Card: %s\n"
|
||||||
sprintf(output+strlen(output), " Bus: %s\n", vid_cap.bus_info);
|
" Bus: %s\n"
|
||||||
sprintf(output+strlen(output), " Version: %u.%u.%u\n",
|
" Version: %u.%u.%u\n"
|
||||||
(vid_cap.version>>16)&0xff, (vid_cap.version>>8)&0xff, vid_cap.version&0xff);
|
" Type: 0x%x\n%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
|
||||||
sprintf(output+strlen(output), " Type: 0x%x\n%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
|
vid_cap.driver, vid_cap.card, vid_cap.bus_info,
|
||||||
|
(vid_cap.version>>16)&0xff, (vid_cap.version>>8)&0xff, vid_cap.version&0xff,
|
||||||
vid_cap.capabilities,
|
vid_cap.capabilities,
|
||||||
capString(vid_cap.capabilities&V4L2_CAP_VIDEO_CAPTURE, " ", "Supports", "Does not support", "video capture (X)"),
|
capString(vid_cap.capabilities&V4L2_CAP_VIDEO_CAPTURE, " ", "Supports", "Does not support", "video capture (X)"),
|
||||||
capString(vid_cap.capabilities&V4L2_CAP_VIDEO_OUTPUT, " ", "Supports", "Does not support", "video output"),
|
capString(vid_cap.capabilities&V4L2_CAP_VIDEO_OUTPUT, " ", "Supports", "Does not support", "video output"),
|
||||||
|
@ -1345,17 +1351,16 @@ bool LocalCamera::GetCurrentSettings( const char *device, char *output, int vers
|
||||||
capString(vid_cap.capabilities&V4L2_CAP_STREAMING, " ", "Supports", "Does not support", "streaming i/o (X)")
|
capString(vid_cap.capabilities&V4L2_CAP_STREAMING, " ", "Supports", "Does not support", "streaming i/o (X)")
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
sprintf(output+strlen(output), "D:%s|", vid_cap.driver);
|
output_ptr += sprintf(output_ptr, "D:%s|C:%s|B:%s|V:%u.%u.%u|T:0x%x|"
|
||||||
sprintf(output+strlen(output), "C:%s|", vid_cap.card);
|
, vid_cap.driver
|
||||||
sprintf(output+strlen(output), "B:%s|", vid_cap.bus_info);
|
, vid_cap.card
|
||||||
sprintf(output+strlen(output), "V:%u.%u.%u|", (vid_cap.version>>16)&0xff, (vid_cap.version>>8)&0xff, vid_cap.version&0xff);
|
, vid_cap.bus_info
|
||||||
sprintf(output+strlen(output), "T:0x%x|", vid_cap.capabilities);
|
, (vid_cap.version>>16)&0xff, (vid_cap.version>>8)&0xff, vid_cap.version&0xff
|
||||||
|
, vid_cap.capabilities);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( verbose )
|
output_ptr += sprintf(output_ptr, verbose ? " Standards:\n" : "S:");
|
||||||
sprintf(output+strlen(output), " Standards:\n");
|
|
||||||
else
|
|
||||||
sprintf(output+strlen(output), "S:");
|
|
||||||
struct v4l2_standard standard;
|
struct v4l2_standard standard;
|
||||||
int standardIndex = 0;
|
int standardIndex = 0;
|
||||||
do {
|
do {
|
||||||
|
@ -1370,25 +1375,20 @@ bool LocalCamera::GetCurrentSettings( const char *device, char *output, int vers
|
||||||
} else {
|
} else {
|
||||||
Error("Failed to enumerate standard %d: %d %s", standard.index, errno, strerror(errno));
|
Error("Failed to enumerate standard %d: %d %s", standard.index, errno, strerror(errno));
|
||||||
if ( verbose )
|
if ( verbose )
|
||||||
sprintf(output, "Error, failed to enumerate standard %d: %d %s\n", standard.index, errno, strerror(errno));
|
output_ptr += sprintf(output_ptr, "Error, failed to enumerate standard %d: %d %s\n", standard.index, errno, strerror(errno));
|
||||||
else
|
else
|
||||||
sprintf(output, "error%d\n", errno);
|
output_ptr += sprintf(output_ptr, "error%d\n", errno);
|
||||||
|
// Why return? Why not continue trying other things?
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( verbose )
|
output_ptr += sprintf(output_ptr, (verbose ? " %s\n" : "%s/"), standard.name);
|
||||||
sprintf(output+strlen(output), " %s\n", standard.name);
|
} while ( standardIndex++ >= 0 );
|
||||||
else
|
|
||||||
sprintf(output+strlen(output), "%s/", standard.name);
|
|
||||||
}
|
|
||||||
while ( standardIndex++ >= 0 );
|
|
||||||
if ( !verbose && output[strlen(output)-1] == '/')
|
|
||||||
output[strlen(output)-1] = '|';
|
|
||||||
|
|
||||||
if ( verbose )
|
if ( !verbose && (*(output_ptr-1) == '/') )
|
||||||
sprintf(output+strlen(output), " Formats:\n");
|
*(output_ptr-1) = '|';
|
||||||
else
|
|
||||||
sprintf(output+strlen(output), "F:");
|
output_ptr += sprintf(output_ptr, verbose ? " Formats:\n" : "F:");
|
||||||
struct v4l2_fmtdesc format;
|
struct v4l2_fmtdesc format;
|
||||||
int formatIndex = 0;
|
int formatIndex = 0;
|
||||||
do {
|
do {
|
||||||
|
@ -1403,15 +1403,15 @@ bool LocalCamera::GetCurrentSettings( const char *device, char *output, int vers
|
||||||
} else {
|
} else {
|
||||||
Error("Failed to enumerate format %d: %s", format.index, strerror(errno));
|
Error("Failed to enumerate format %d: %s", format.index, strerror(errno));
|
||||||
if ( verbose )
|
if ( verbose )
|
||||||
sprintf(output, "Error, failed to enumerate format %d: %s\n", format.index, strerror(errno));
|
output_ptr += sprintf(output_ptr, "Error, failed to enumerate format %d: %s\n", format.index, strerror(errno));
|
||||||
else
|
else
|
||||||
sprintf(output, "error%d\n", errno);
|
output_ptr += sprintf(output_ptr, "error%d\n", errno);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( verbose )
|
if ( verbose )
|
||||||
sprintf(
|
output_ptr += sprintf(
|
||||||
output+strlen(output),
|
output_ptr,
|
||||||
" %s (0x%02hhx%02hhx%02hhx%02hhx)\n",
|
" %s (0x%02hhx%02hhx%02hhx%02hhx)\n",
|
||||||
format.description,
|
format.description,
|
||||||
(format.pixelformat>>24)&0xff,
|
(format.pixelformat>>24)&0xff,
|
||||||
|
@ -1419,18 +1419,19 @@ bool LocalCamera::GetCurrentSettings( const char *device, char *output, int vers
|
||||||
(format.pixelformat>>8)&0xff,
|
(format.pixelformat>>8)&0xff,
|
||||||
format.pixelformat&0xff);
|
format.pixelformat&0xff);
|
||||||
else
|
else
|
||||||
sprintf(
|
output_ptr += sprintf(
|
||||||
output+strlen(output),
|
output_ptr,
|
||||||
"0x%02hhx%02hhx%02hhx%02hhx/",
|
"0x%02hhx%02hhx%02hhx%02hhx/",
|
||||||
(format.pixelformat>>24)&0xff,
|
(format.pixelformat>>24)&0xff,
|
||||||
(format.pixelformat>>16)&0xff,
|
(format.pixelformat>>16)&0xff,
|
||||||
(format.pixelformat>>8)&0xff,
|
(format.pixelformat>>8)&0xff,
|
||||||
(format.pixelformat)&0xff);
|
(format.pixelformat)&0xff);
|
||||||
} while ( formatIndex++ >= 0 );
|
} while ( formatIndex++ >= 0 );
|
||||||
|
|
||||||
if ( !verbose )
|
if ( !verbose )
|
||||||
output[strlen(output)-1] = '|';
|
*(output_ptr-1) = '|';
|
||||||
else
|
else
|
||||||
sprintf(output+strlen(output), "Crop Capabilities\n");
|
output_ptr += sprintf(output_ptr, "Crop Capabilities\n");
|
||||||
|
|
||||||
struct v4l2_cropcap cropcap;
|
struct v4l2_cropcap cropcap;
|
||||||
memset(&cropcap, 0, sizeof(cropcap));
|
memset(&cropcap, 0, sizeof(cropcap));
|
||||||
|
@ -1442,10 +1443,10 @@ bool LocalCamera::GetCurrentSettings( const char *device, char *output, int vers
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( verbose ) {
|
if ( verbose ) {
|
||||||
sprintf(output+strlen(output), " Cropping is not supported\n");
|
output_ptr += sprintf(output_ptr, " Cropping is not supported\n");
|
||||||
} else {
|
} else {
|
||||||
/* Send fake crop bounds to not confuse things parsing this, such as monitor probe */
|
/* Send fake crop bounds to not confuse things parsing this, such as monitor probe */
|
||||||
sprintf(output+strlen(output), "B:%dx%d|",0,0);
|
output_ptr += sprintf(output_ptr, "B:%dx%d|", 0, 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
struct v4l2_crop crop;
|
struct v4l2_crop crop;
|
||||||
|
@ -1459,19 +1460,23 @@ bool LocalCamera::GetCurrentSettings( const char *device, char *output, int vers
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( verbose ) {
|
if ( verbose ) {
|
||||||
sprintf(output+strlen(output), " Cropping is not supported\n");
|
output_ptr += sprintf(output_ptr, " Cropping is not supported\n");
|
||||||
} else {
|
} else {
|
||||||
/* Send fake crop bounds to not confuse things parsing this, such as monitor probe */
|
/* Send fake crop bounds to not confuse things parsing this, such as monitor probe */
|
||||||
sprintf(output+strlen(output), "B:%dx%d|",0,0);
|
output_ptr += sprintf(output_ptr, "B:%dx%d|",0,0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Cropping supported */
|
/* Cropping supported */
|
||||||
if ( verbose ) {
|
if ( verbose ) {
|
||||||
sprintf(output+strlen(output), " Bounds: %d x %d\n", cropcap.bounds.width, cropcap.bounds.height);
|
output_ptr += sprintf(output_ptr,
|
||||||
sprintf(output+strlen(output), " Default: %d x %d\n", cropcap.defrect.width, cropcap.defrect.height);
|
" Bounds: %d x %d\n"
|
||||||
sprintf(output+strlen(output), " Current: %d x %d\n", crop.c.width, crop.c.height);
|
" Default: %d x %d\n"
|
||||||
|
" Current: %d x %d\n"
|
||||||
|
, cropcap.bounds.width, cropcap.bounds.height
|
||||||
|
, cropcap.defrect.width, cropcap.defrect.height
|
||||||
|
, crop.c.width, crop.c.height);
|
||||||
} else {
|
} else {
|
||||||
sprintf(output+strlen(output), "B:%dx%d|", cropcap.bounds.width, cropcap.bounds.height);
|
output_ptr += sprintf(output_ptr, "B:%dx%d|", cropcap.bounds.width, cropcap.bounds.height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} /* Crop code */
|
} /* Crop code */
|
||||||
|
@ -1488,17 +1493,14 @@ bool LocalCamera::GetCurrentSettings( const char *device, char *output, int vers
|
||||||
}
|
}
|
||||||
Error("Failed to enumerate input %d: %s", input.index, strerror(errno));
|
Error("Failed to enumerate input %d: %s", input.index, strerror(errno));
|
||||||
if ( verbose )
|
if ( verbose )
|
||||||
sprintf(output, "Error, failed to enumerate input %d: %s\n", input.index, strerror(errno));
|
output_ptr += sprintf(output_ptr, "Error, failed to enumerate input %d: %s\n", input.index, strerror(errno));
|
||||||
else
|
else
|
||||||
sprintf(output, "error%d\n", errno);
|
output_ptr += sprintf(output_ptr, "error%d\n", errno);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} while ( inputIndex++ >= 0 );
|
} while ( inputIndex++ >= 0 );
|
||||||
|
|
||||||
if ( verbose )
|
output_ptr += sprintf(output_ptr, verbose?"Inputs: %d\n":"I:%d|", inputIndex);
|
||||||
sprintf(output+strlen(output), "Inputs: %d\n", inputIndex);
|
|
||||||
else
|
|
||||||
sprintf(output+strlen(output), "I:%d|", inputIndex);
|
|
||||||
|
|
||||||
inputIndex = 0;
|
inputIndex = 0;
|
||||||
do {
|
do {
|
||||||
|
@ -1512,47 +1514,56 @@ bool LocalCamera::GetCurrentSettings( const char *device, char *output, int vers
|
||||||
}
|
}
|
||||||
Error("Failed to enumerate input %d: %s", input.index, strerror(errno));
|
Error("Failed to enumerate input %d: %s", input.index, strerror(errno));
|
||||||
if ( verbose )
|
if ( verbose )
|
||||||
sprintf(output, "Error, failed to enumerate input %d: %s\n", input.index, strerror(errno));
|
output_ptr += sprintf(output_ptr, "Error, failed to enumerate input %d: %s\n", input.index, strerror(errno));
|
||||||
else
|
else
|
||||||
sprintf(output, "error%d\n", errno);
|
output_ptr += sprintf(output_ptr, "error%d\n", errno);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( vidioctl(vid_fd, VIDIOC_S_INPUT, &input.index) < 0 ) {
|
if ( vidioctl(vid_fd, VIDIOC_S_INPUT, &input.index) < 0 ) {
|
||||||
Error("Failed to set video input %d: %s", input.index, strerror(errno));
|
Error("Failed to set video input %d: %s", input.index, strerror(errno));
|
||||||
if ( verbose )
|
if ( verbose )
|
||||||
sprintf(output, "Error, failed to switch to input %d: %s\n", input.index, strerror(errno));
|
output_ptr += sprintf(output_ptr, "Error, failed to switch to input %d: %s\n", input.index, strerror(errno));
|
||||||
else
|
else
|
||||||
sprintf(output, "error%d\n", errno);
|
output_ptr += sprintf(output_ptr, "error%d\n", errno);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( verbose ) {
|
if ( verbose ) {
|
||||||
sprintf( output+strlen(output), " Input %d\n", input.index );
|
output_ptr += sprintf( output,
|
||||||
sprintf( output+strlen(output), " Name: %s\n", input.name );
|
" Input %d\n"
|
||||||
sprintf( output+strlen(output), " Type: %s\n", input.type==V4L2_INPUT_TYPE_TUNER?"Tuner":(input.type==V4L2_INPUT_TYPE_CAMERA?"Camera":"Unknown") );
|
" Name: %s\n"
|
||||||
sprintf( output+strlen(output), " Audioset: %08x\n", input.audioset );
|
" Type: %s\n"
|
||||||
sprintf( output+strlen(output), " Standards: 0x%llx\n", input.std );
|
" Audioset: %08x\n"
|
||||||
|
" Standards: 0x%llx\n"
|
||||||
|
, input.index
|
||||||
|
, input.name
|
||||||
|
, input.type==V4L2_INPUT_TYPE_TUNER?"Tuner":(input.type==V4L2_INPUT_TYPE_CAMERA?"Camera":"Unknown")
|
||||||
|
, input.audioset
|
||||||
|
, input.std );
|
||||||
} else {
|
} else {
|
||||||
sprintf( output+strlen(output), "i%d:%s|", input.index, input.name );
|
output_ptr += sprintf( output_ptr, "i%d:%s|i%dT:%s|i%dS:%llx|"
|
||||||
sprintf( output+strlen(output), "i%dT:%s|", input.index, input.type==V4L2_INPUT_TYPE_TUNER?"Tuner":(input.type==V4L2_INPUT_TYPE_CAMERA?"Camera":"Unknown") );
|
, input.index, input.name
|
||||||
sprintf( output+strlen(output), "i%dS:%llx|", input.index, input.std );
|
, input.index, input.type==V4L2_INPUT_TYPE_TUNER?"Tuner":(input.type==V4L2_INPUT_TYPE_CAMERA?"Camera":"Unknown")
|
||||||
|
, input.index, input.std);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( verbose ) {
|
if ( verbose ) {
|
||||||
sprintf( output+strlen(output), " %s", capString( input.status&V4L2_IN_ST_NO_POWER, "Power ", "off", "on", " (X)" ) );
|
output_ptr += sprintf( output_ptr, " %s %s %s %s"
|
||||||
sprintf( output+strlen(output), " %s", capString( input.status&V4L2_IN_ST_NO_SIGNAL, "Signal ", "not detected", "detected", " (X)" ) );
|
, capString(input.status&V4L2_IN_ST_NO_POWER, "Power ", "off", "on", " (X)")
|
||||||
sprintf( output+strlen(output), " %s", capString( input.status&V4L2_IN_ST_NO_COLOR, "Colour Signal ", "not detected", "detected", "" ) );
|
, capString(input.status&V4L2_IN_ST_NO_SIGNAL, "Signal ", "not detected", "detected", " (X)")
|
||||||
sprintf( output+strlen(output), " %s", capString( input.status&V4L2_IN_ST_NO_H_LOCK, "Horizontal Lock ", "not detected", "detected", "" ) );
|
, capString(input.status&V4L2_IN_ST_NO_COLOR, "Colour Signal ", "not detected", "detected", "")
|
||||||
|
, capString(input.status&V4L2_IN_ST_NO_H_LOCK, "Horizontal Lock ", "not detected", "detected", ""));
|
||||||
} else {
|
} else {
|
||||||
sprintf( output+strlen(output), "i%dSP:%d|", input.index, (input.status&V4L2_IN_ST_NO_POWER)?0:1 );
|
output_ptr += sprintf( output_ptr, "i%dSP:%d|i%dSS:%d|i%dSC:%d|i%dHP:%d|"
|
||||||
sprintf( output+strlen(output), "i%dSS:%d|", input.index, (input.status&V4L2_IN_ST_NO_SIGNAL)?0:1 );
|
, input.index, (input.status&V4L2_IN_ST_NO_POWER)?0:1
|
||||||
sprintf( output+strlen(output), "i%dSC:%d|", input.index, (input.status&V4L2_IN_ST_NO_COLOR)?0:1 );
|
, input.index, (input.status&V4L2_IN_ST_NO_SIGNAL)?0:1
|
||||||
sprintf( output+strlen(output), "i%dHP:%d|", input.index, (input.status&V4L2_IN_ST_NO_H_LOCK)?0:1 );
|
, input.index, (input.status&V4L2_IN_ST_NO_COLOR)?0:1
|
||||||
|
, input.index, (input.status&V4L2_IN_ST_NO_H_LOCK)?0:1 );
|
||||||
}
|
}
|
||||||
} while ( inputIndex++ >= 0 );
|
} while ( inputIndex++ >= 0 );
|
||||||
if ( !verbose )
|
if ( !verbose )
|
||||||
output[strlen(output)-1] = '\n';
|
*(output_ptr-1) = '\n';
|
||||||
}
|
}
|
||||||
#endif // ZM_HAS_V4L2
|
#endif // ZM_HAS_V4L2
|
||||||
#if ZM_HAS_V4L1
|
#if ZM_HAS_V4L1
|
||||||
|
@ -1562,15 +1573,25 @@ bool LocalCamera::GetCurrentSettings( const char *device, char *output, int vers
|
||||||
if ( ioctl(vid_fd, VIDIOCGCAP, &vid_cap) < 0 ) {
|
if ( ioctl(vid_fd, VIDIOCGCAP, &vid_cap) < 0 ) {
|
||||||
Error("Failed to get video capabilities: %s", strerror(errno));
|
Error("Failed to get video capabilities: %s", strerror(errno));
|
||||||
if ( verbose )
|
if ( verbose )
|
||||||
sprintf( output, "Error, failed to get video capabilities %s: %s\n", queryDevice, strerror(errno) );
|
output_ptr += sprintf(output_ptr,
|
||||||
|
"Error, failed to get video capabilities %s: %s\n",
|
||||||
|
queryDevice, strerror(errno));
|
||||||
else
|
else
|
||||||
sprintf( output, "error%d\n", errno );
|
output_ptr += sprintf(output_ptr, "error%d\n", errno);
|
||||||
return( false );
|
return false;
|
||||||
}
|
}
|
||||||
if ( verbose ) {
|
if ( verbose ) {
|
||||||
sprintf( output+strlen(output), "Video Capabilities\n" );
|
output_ptr += sprintf( output_ptr, "Video Capabilities\n"
|
||||||
sprintf( output+strlen(output), " Name: %s\n", vid_cap.name );
|
" Name: %s\n"
|
||||||
sprintf( output+strlen(output), " Type: %d\n%s%s%s%s%s%s%s%s%s%s%s%s%s%s", vid_cap.type,
|
" Type: %d\n%s%s%s%s%s%s%s%s%s%s%s%s%s%s"
|
||||||
|
" Video Channels: %d\n"
|
||||||
|
" Audio Channels: %d\n"
|
||||||
|
" Maximum Width: %d\n"
|
||||||
|
" Maximum Height: %d\n"
|
||||||
|
" Minimum Width: %d\n"
|
||||||
|
" Minimum Height: %d\n",
|
||||||
|
vid_cap.name,
|
||||||
|
vid_cap.type,
|
||||||
(vid_cap.type&VID_TYPE_CAPTURE)?" Can capture\n":"",
|
(vid_cap.type&VID_TYPE_CAPTURE)?" Can capture\n":"",
|
||||||
(vid_cap.type&VID_TYPE_TUNER)?" Can tune\n":"",
|
(vid_cap.type&VID_TYPE_TUNER)?" Can tune\n":"",
|
||||||
(vid_cap.type&VID_TYPE_TELETEXT)?" Does teletext\n":"",
|
(vid_cap.type&VID_TYPE_TELETEXT)?" Does teletext\n":"",
|
||||||
|
@ -1584,25 +1605,23 @@ bool LocalCamera::GetCurrentSettings( const char *device, char *output, int vers
|
||||||
(vid_cap.type&VID_TYPE_MPEG_DECODER)?" Can decode MPEG streams\n":"",
|
(vid_cap.type&VID_TYPE_MPEG_DECODER)?" Can decode MPEG streams\n":"",
|
||||||
(vid_cap.type&VID_TYPE_MPEG_ENCODER)?" Can encode MPEG streams\n":"",
|
(vid_cap.type&VID_TYPE_MPEG_ENCODER)?" Can encode MPEG streams\n":"",
|
||||||
(vid_cap.type&VID_TYPE_MJPEG_DECODER)?" Can decode MJPEG streams\n":"",
|
(vid_cap.type&VID_TYPE_MJPEG_DECODER)?" Can decode MJPEG streams\n":"",
|
||||||
(vid_cap.type&VID_TYPE_MJPEG_ENCODER)?" Can encode MJPEG streams\n":""
|
(vid_cap.type&VID_TYPE_MJPEG_ENCODER)?" Can encode MJPEG streams\n":"",
|
||||||
);
|
vid_cap.channels,
|
||||||
sprintf( output+strlen(output), " Video Channels: %d\n", vid_cap.channels );
|
vid_cap.audios,
|
||||||
sprintf( output+strlen(output), " Audio Channels: %d\n", vid_cap.audios );
|
vid_cap.maxwidth,
|
||||||
sprintf( output+strlen(output), " Maximum Width: %d\n", vid_cap.maxwidth );
|
vid_cap.maxheight,
|
||||||
sprintf( output+strlen(output), " Maximum Height: %d\n", vid_cap.maxheight );
|
vid_cap.minwidth,
|
||||||
sprintf( output+strlen(output), " Minimum Width: %d\n", vid_cap.minwidth );
|
vid_cap.minheight );
|
||||||
sprintf( output+strlen(output), " Minimum Height: %d\n", vid_cap.minheight );
|
} else {
|
||||||
}
|
output_ptr += sprintf(output_ptr, "N:%s|T:%d|nC:%d|nA:%d|mxW:%d|mxH:%d|mnW:%d|mnH:%d|"
|
||||||
else
|
, vid_cap.name
|
||||||
{
|
, vid_cap.type
|
||||||
sprintf( output+strlen(output), "N:%s|", vid_cap.name );
|
, vid_cap.channels
|
||||||
sprintf( output+strlen(output), "T:%d|", vid_cap.type );
|
, vid_cap.audios
|
||||||
sprintf( output+strlen(output), "nC:%d|", vid_cap.channels );
|
, vid_cap.maxwidth
|
||||||
sprintf( output+strlen(output), "nA:%d|", vid_cap.audios );
|
, vid_cap.maxheight
|
||||||
sprintf( output+strlen(output), "mxW:%d|", vid_cap.maxwidth );
|
, vid_cap.minwidth
|
||||||
sprintf( output+strlen(output), "mxH:%d|", vid_cap.maxheight );
|
, vid_cap.minheight);
|
||||||
sprintf( output+strlen(output), "mnW:%d|", vid_cap.minwidth );
|
|
||||||
sprintf( output+strlen(output), "mnH:%d|", vid_cap.minheight );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct video_window vid_win;
|
struct video_window vid_win;
|
||||||
|
@ -1610,22 +1629,25 @@ bool LocalCamera::GetCurrentSettings( const char *device, char *output, int vers
|
||||||
if ( ioctl(vid_fd, VIDIOCGWIN, &vid_win) < 0 ) {
|
if ( ioctl(vid_fd, VIDIOCGWIN, &vid_win) < 0 ) {
|
||||||
Error("Failed to get window attributes: %s", strerror(errno));
|
Error("Failed to get window attributes: %s", strerror(errno));
|
||||||
if ( verbose )
|
if ( verbose )
|
||||||
sprintf( output, "Error, failed to get window attributes: %s\n", strerror(errno) );
|
output_ptr += sprintf(output_ptr, "Error, failed to get window attributes: %s\n", strerror(errno));
|
||||||
else
|
else
|
||||||
sprintf( output, "error%d\n", errno );
|
output_ptr += sprintf(output_ptr, "error%d\n", errno);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ( verbose ) {
|
if ( verbose ) {
|
||||||
sprintf( output+strlen(output), "Window Attributes\n" );
|
output_ptr += sprintf(output_ptr,
|
||||||
sprintf( output+strlen(output), " X Offset: %d\n", vid_win.x );
|
"Window Attributes\n"
|
||||||
sprintf( output+strlen(output), " Y Offset: %d\n", vid_win.y );
|
" X Offset: %d\n"
|
||||||
sprintf( output+strlen(output), " Width: %d\n", vid_win.width );
|
" Y Offset: %d\n"
|
||||||
sprintf( output+strlen(output), " Height: %d\n", vid_win.height );
|
" Width: %d\n"
|
||||||
|
" Height: %d\n"
|
||||||
|
, vid_win.x
|
||||||
|
, vid_win.y
|
||||||
|
, vid_win.width
|
||||||
|
, vid_win.height );
|
||||||
} else {
|
} else {
|
||||||
sprintf( output+strlen(output), "X:%d|", vid_win.x );
|
output_ptr += sprintf(output_ptr, "X:%d|Y:%d|W:%d|H:%d|",
|
||||||
sprintf( output+strlen(output), "Y:%d|", vid_win.y );
|
vid_win.height, vid_win.x, vid_win.y, vid_win.width);
|
||||||
sprintf( output+strlen(output), "W:%d|", vid_win.width );
|
|
||||||
sprintf( output+strlen(output), "H:%d|", vid_win.height );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct video_picture vid_pic;
|
struct video_picture vid_pic;
|
||||||
|
@ -1633,14 +1655,22 @@ bool LocalCamera::GetCurrentSettings( const char *device, char *output, int vers
|
||||||
if ( ioctl(vid_fd, VIDIOCGPICT, &vid_pic) < 0 ) {
|
if ( ioctl(vid_fd, VIDIOCGPICT, &vid_pic) < 0 ) {
|
||||||
Error("Failed to get picture attributes: %s", strerror(errno));
|
Error("Failed to get picture attributes: %s", strerror(errno));
|
||||||
if ( verbose )
|
if ( verbose )
|
||||||
sprintf( output, "Error, failed to get picture attributes: %s\n", strerror(errno) );
|
output_ptr += sprintf(output_ptr, "Error, failed to get picture attributes: %s\n", strerror(errno));
|
||||||
else
|
else
|
||||||
sprintf( output, "error%d\n", errno );
|
output_ptr += sprintf(output_ptr, "error%d\n", errno);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ( verbose ) {
|
if ( verbose ) {
|
||||||
sprintf( output+strlen(output), "Picture Attributes\n" );
|
output_ptr += sprintf(output_ptr,
|
||||||
sprintf( output+strlen(output), " Palette: %d - %s\n", vid_pic.palette,
|
"Picture Attributes\n"
|
||||||
|
" Palette: %d - %s\n"
|
||||||
|
" Colour Depth: %d\n"
|
||||||
|
" Brightness: %d\n"
|
||||||
|
" Hue: %d\n"
|
||||||
|
" Colour :%d\n"
|
||||||
|
" Contrast: %d\n"
|
||||||
|
" Whiteness: %d\n"
|
||||||
|
, vid_pic.palette,
|
||||||
vid_pic.palette==VIDEO_PALETTE_GREY?"Linear greyscale":(
|
vid_pic.palette==VIDEO_PALETTE_GREY?"Linear greyscale":(
|
||||||
vid_pic.palette==VIDEO_PALETTE_HI240?"High 240 cube (BT848)":(
|
vid_pic.palette==VIDEO_PALETTE_HI240?"High 240 cube (BT848)":(
|
||||||
vid_pic.palette==VIDEO_PALETTE_RGB565?"565 16 bit RGB":(
|
vid_pic.palette==VIDEO_PALETTE_RGB565?"565 16 bit RGB":(
|
||||||
|
@ -1659,21 +1689,24 @@ bool LocalCamera::GetCurrentSettings( const char *device, char *output, int vers
|
||||||
vid_pic.palette==VIDEO_PALETTE_YUV411P?"YUV 4:1:1 Planar":(
|
vid_pic.palette==VIDEO_PALETTE_YUV411P?"YUV 4:1:1 Planar":(
|
||||||
vid_pic.palette==VIDEO_PALETTE_YUV420P?"YUV 4:2:0 Planar":(
|
vid_pic.palette==VIDEO_PALETTE_YUV420P?"YUV 4:2:0 Planar":(
|
||||||
vid_pic.palette==VIDEO_PALETTE_YUV410P?"YUV 4:1:0 Planar":"Unknown"
|
vid_pic.palette==VIDEO_PALETTE_YUV410P?"YUV 4:1:0 Planar":"Unknown"
|
||||||
))))))))))))))))));
|
))))))))))))))))),
|
||||||
sprintf( output+strlen(output), " Colour Depth: %d\n", vid_pic.depth );
|
vid_pic.depth,
|
||||||
sprintf( output+strlen(output), " Brightness: %d\n", vid_pic.brightness );
|
vid_pic.brightness,
|
||||||
sprintf( output+strlen(output), " Hue: %d\n", vid_pic.hue );
|
vid_pic.hue,
|
||||||
sprintf( output+strlen(output), " Colour :%d\n", vid_pic.colour );
|
vid_pic.colour,
|
||||||
sprintf( output+strlen(output), " Contrast: %d\n", vid_pic.contrast );
|
vid_pic.contrast,
|
||||||
sprintf( output+strlen(output), " Whiteness: %d\n", vid_pic.whiteness );
|
vid_pic.whiteness
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
sprintf( output+strlen(output), "P:%d|", vid_pic.palette );
|
output_ptr += sprintf(output_ptr, "P:%d|D:%d|B:%d|h:%d|Cl:%d|Cn:%d|w:%d|",
|
||||||
sprintf( output+strlen(output), "D:%d|", vid_pic.depth );
|
vid_pic.palette,
|
||||||
sprintf( output+strlen(output), "B:%d|", vid_pic.brightness );
|
vid_pic.depth,
|
||||||
sprintf( output+strlen(output), "h:%d|", vid_pic.hue );
|
vid_pic.brightness,
|
||||||
sprintf( output+strlen(output), "Cl:%d|", vid_pic.colour );
|
vid_pic.hue,
|
||||||
sprintf( output+strlen(output), "Cn:%d|", vid_pic.contrast );
|
vid_pic.colour,
|
||||||
sprintf( output+strlen(output), "w:%d|", vid_pic.whiteness );
|
vid_pic.contrast,
|
||||||
|
vid_pic.whiteness
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( int chan = 0; chan < vid_cap.channels; chan++ ) {
|
for ( int chan = 0; chan < vid_cap.channels; chan++ ) {
|
||||||
|
@ -1683,39 +1716,47 @@ bool LocalCamera::GetCurrentSettings( const char *device, char *output, int vers
|
||||||
if ( ioctl(vid_fd, VIDIOCGCHAN, &vid_src) < 0 ) {
|
if ( ioctl(vid_fd, VIDIOCGCHAN, &vid_src) < 0 ) {
|
||||||
Error("Failed to get channel %d attributes: %s", chan, strerror(errno));
|
Error("Failed to get channel %d attributes: %s", chan, strerror(errno));
|
||||||
if ( verbose )
|
if ( verbose )
|
||||||
sprintf( output, "Error, failed to get channel %d attributes: %s\n", chan, strerror(errno) );
|
output_ptr += sprintf(output_ptr, "Error, failed to get channel %d attributes: %s\n", chan, strerror(errno));
|
||||||
else
|
else
|
||||||
sprintf( output, "error%d\n", errno );
|
output_ptr += sprintf(output_ptr, "error%d\n", errno);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ( verbose ) {
|
if ( verbose ) {
|
||||||
sprintf( output+strlen(output), "Channel %d Attributes\n", chan );
|
output_ptr += sprintf(output_ptr,
|
||||||
sprintf( output+strlen(output), " Name: %s\n", vid_src.name );
|
"Channel %d Attributes\n"
|
||||||
sprintf( output+strlen(output), " Channel: %d\n", vid_src.channel );
|
" Name: %s\n"
|
||||||
sprintf( output+strlen(output), " Flags: %d\n%s%s", vid_src.flags,
|
" Channel: %d\n"
|
||||||
(vid_src.flags&VIDEO_VC_TUNER)?" Channel has a tuner\n":"",
|
" Flags: %d\n%s%s"
|
||||||
(vid_src.flags&VIDEO_VC_AUDIO)?" Channel has audio\n":""
|
" Type: %d - %s\n"
|
||||||
);
|
" Format: %d - %s\n"
|
||||||
sprintf( output+strlen(output), " Type: %d - %s\n", vid_src.type,
|
, chan
|
||||||
|
, vid_src.name
|
||||||
|
, vid_src.channel
|
||||||
|
, vid_src.flags
|
||||||
|
, (vid_src.flags&VIDEO_VC_TUNER)?" Channel has a tuner\n":""
|
||||||
|
, (vid_src.flags&VIDEO_VC_AUDIO)?" Channel has audio\n":""
|
||||||
|
, vid_src.type,
|
||||||
vid_src.type==VIDEO_TYPE_TV?"TV":(
|
vid_src.type==VIDEO_TYPE_TV?"TV":(
|
||||||
vid_src.type==VIDEO_TYPE_CAMERA?"Camera":"Unknown"
|
vid_src.type==VIDEO_TYPE_CAMERA?"Camera":"Unknown"
|
||||||
));
|
)
|
||||||
sprintf( output+strlen(output), " Format: %d - %s\n", vid_src.norm,
|
, vid_src.norm,
|
||||||
vid_src.norm==VIDEO_MODE_PAL?"PAL":(
|
vid_src.norm==VIDEO_MODE_PAL?"PAL":(
|
||||||
vid_src.norm==VIDEO_MODE_NTSC?"NTSC":(
|
vid_src.norm==VIDEO_MODE_NTSC?"NTSC":(
|
||||||
vid_src.norm==VIDEO_MODE_SECAM?"SECAM":(
|
vid_src.norm==VIDEO_MODE_SECAM?"SECAM":(
|
||||||
vid_src.norm==VIDEO_MODE_AUTO?"AUTO":"Unknown"
|
vid_src.norm==VIDEO_MODE_AUTO?"AUTO":"Unknown"
|
||||||
))));
|
))));
|
||||||
} else {
|
} else {
|
||||||
sprintf( output+strlen(output), "n%d:%s|", chan, vid_src.name );
|
output_ptr += sprintf(output_ptr, "n%d:%s|C%d:%d|Fl%d:%x|T%d:%d|F%d:%d%s|"
|
||||||
sprintf( output+strlen(output), "C%d:%d|", chan, vid_src.channel );
|
, chan, vid_src.name
|
||||||
sprintf( output+strlen(output), "Fl%d:%x|", chan, vid_src.flags );
|
, chan, vid_src.channel
|
||||||
sprintf( output+strlen(output), "T%d:%d|", chan, vid_src.type );
|
, chan, vid_src.flags
|
||||||
sprintf( output+strlen(output), "F%d:%d%s|", chan, vid_src.norm, chan==(vid_cap.channels-1)?"":"," );
|
, chan, vid_src.type
|
||||||
|
, chan, vid_src.norm, chan==(vid_cap.channels-1)?"":","
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( !verbose )
|
if ( !verbose )
|
||||||
output[strlen(output)-1] = '\n';
|
*output_ptr = '\n';
|
||||||
}
|
}
|
||||||
#endif // ZM_HAS_V4L1
|
#endif // ZM_HAS_V4L1
|
||||||
close(vid_fd);
|
close(vid_fd);
|
||||||
|
|
|
@ -24,6 +24,7 @@ class Filter extends ZM_Object {
|
||||||
'AutoCopy' => 0,
|
'AutoCopy' => 0,
|
||||||
'AutoCopyTo' => 0,
|
'AutoCopyTo' => 0,
|
||||||
'UpdateDiskSpace' => 0,
|
'UpdateDiskSpace' => 0,
|
||||||
|
'UserId' => 0,
|
||||||
'Background' => 0,
|
'Background' => 0,
|
||||||
'Concurrent' => 0,
|
'Concurrent' => 0,
|
||||||
'Query_json' => '',
|
'Query_json' => '',
|
||||||
|
|
|
@ -19,9 +19,9 @@ class Group extends ZM_Object {
|
||||||
|
|
||||||
public function delete() {
|
public function delete() {
|
||||||
if ( property_exists($this, 'Id') ) {
|
if ( property_exists($this, 'Id') ) {
|
||||||
dbQuery('DELETE FROM Groups_Monitors WHERE GroupId=?', array($this->{'Id'}));
|
dbQuery('DELETE FROM `Groups_Monitors` WHERE `GroupId`=?', array($this->{'Id'}));
|
||||||
dbQuery('UPDATE Groups SET ParentId=NULL WHERE ParentId=?', array($this->{'Id'}));
|
dbQuery('UPDATE `Groups` SET `ParentId`=NULL WHERE `ParentId`=?', array($this->{'Id'}));
|
||||||
dbQuery('DELETE FROM Groups WHERE Id=?', array($this->{'Id'}));
|
dbQuery('DELETE FROM `Groups` WHERE Id=?', array($this->{'Id'}));
|
||||||
if ( isset($_COOKIE['zmGroup']) ) {
|
if ( isset($_COOKIE['zmGroup']) ) {
|
||||||
if ( $this->{'Id'} == $_COOKIE['zmGroup'] ) {
|
if ( $this->{'Id'} == $_COOKIE['zmGroup'] ) {
|
||||||
unset($_COOKIE['zmGroup']);
|
unset($_COOKIE['zmGroup']);
|
||||||
|
@ -47,7 +47,7 @@ class Group extends ZM_Object {
|
||||||
|
|
||||||
public function MonitorIds( ) {
|
public function MonitorIds( ) {
|
||||||
if ( ! property_exists($this, 'MonitorIds') ) {
|
if ( ! property_exists($this, 'MonitorIds') ) {
|
||||||
$this->{'MonitorIds'} = dbFetchAll('SELECT MonitorId FROM Groups_Monitors WHERE GroupId=?', 'MonitorId', array($this->{'Id'}));
|
$this->{'MonitorIds'} = dbFetchAll('SELECT `MonitorId` FROM `Groups_Monitors` WHERE `GroupId`=?', 'MonitorId', array($this->{'Id'}));
|
||||||
}
|
}
|
||||||
return $this->{'MonitorIds'};
|
return $this->{'MonitorIds'};
|
||||||
}
|
}
|
||||||
|
|
|
@ -306,7 +306,7 @@ class ZM_Object {
|
||||||
$fields = array_keys($fields);
|
$fields = array_keys($fields);
|
||||||
|
|
||||||
if ( $this->Id() ) {
|
if ( $this->Id() ) {
|
||||||
$sql = 'UPDATE '.$table.' SET '.implode(', ', array_map(function($field) {return '`'.$field.'`=?';}, $fields)).' WHERE Id=?';
|
$sql = 'UPDATE `'.$table.'` SET '.implode(', ', array_map(function($field) {return '`'.$field.'`=?';}, $fields)).' WHERE Id=?';
|
||||||
$values = array_map(function($field){ return $this->{$field};}, $fields);
|
$values = array_map(function($field){ return $this->{$field};}, $fields);
|
||||||
$values[] = $this->{'Id'};
|
$values[] = $this->{'Id'};
|
||||||
if ( dbQuery($sql, $values) )
|
if ( dbQuery($sql, $values) )
|
||||||
|
@ -314,8 +314,8 @@ class ZM_Object {
|
||||||
} else {
|
} else {
|
||||||
unset($fields['Id']);
|
unset($fields['Id']);
|
||||||
|
|
||||||
$sql = 'INSERT INTO '.$table.
|
$sql = 'INSERT INTO `'.$table.
|
||||||
' ('.implode(', ', array_map(function($field) {return '`'.$field.'`';}, $fields)).
|
'` ('.implode(', ', array_map(function($field) {return '`'.$field.'`';}, $fields)).
|
||||||
') VALUES ('.
|
') VALUES ('.
|
||||||
implode(', ', array_map(function($field){return '?';}, $fields)).')';
|
implode(', ', array_map(function($field){return '?';}, $fields)).')';
|
||||||
|
|
||||||
|
@ -331,7 +331,7 @@ class ZM_Object {
|
||||||
public function delete() {
|
public function delete() {
|
||||||
$class = get_class($this);
|
$class = get_class($this);
|
||||||
$table = $class::$table;
|
$table = $class::$table;
|
||||||
dbQuery("DELETE FROM $table WHERE Id=?", array($this->{'Id'}));
|
dbQuery("DELETE FROM `$table` WHERE Id=?", array($this->{'Id'}));
|
||||||
if ( isset($object_cache[$class]) and isset($object_cache[$class][$this->{'Id'}]) )
|
if ( isset($object_cache[$class]) and isset($object_cache[$class][$this->{'Id'}]) )
|
||||||
unset($object_cache[$class][$this->{'Id'}]);
|
unset($object_cache[$class][$this->{'Id'}]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
<?php
|
||||||
|
namespace ZM;
|
||||||
|
require_once('database.php');
|
||||||
|
require_once('Object.php');
|
||||||
|
|
||||||
|
|
||||||
|
class User extends ZM_Object {
|
||||||
|
protected static $table = 'Users';
|
||||||
|
|
||||||
|
protected $defaults = array(
|
||||||
|
'Id' => null,
|
||||||
|
'Username' => '',
|
||||||
|
'Password' => '',
|
||||||
|
'Language' => '',
|
||||||
|
'Enabled' => 1,
|
||||||
|
'Stream' => 'None',
|
||||||
|
'Events' => 'None',
|
||||||
|
'Control' => 'None',
|
||||||
|
'Monitors' => 'None',
|
||||||
|
'Groups' => 'None',
|
||||||
|
'Devices' => 'None',
|
||||||
|
'System'=> 'None',
|
||||||
|
'MaxBandwidth' =>'',
|
||||||
|
'MonitorIds' =>'',
|
||||||
|
'TokenMinExpiry' => 0,
|
||||||
|
'APIEnabled'=> 1,
|
||||||
|
);
|
||||||
|
|
||||||
|
public static function find( $parameters = array(), $options = array() ) {
|
||||||
|
return ZM_Object::_find(get_class(), $parameters, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function find_one( $parameters = array(), $options = array() ) {
|
||||||
|
return ZM_Object::_find_one(get_class(), $parameters, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Name( ) {
|
||||||
|
return $this->{'Username'};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function Indexed_By_Id() {
|
||||||
|
$results = array();
|
||||||
|
foreach ( ZM_Object::_find('ZM\User', null, array('order'=>'lower(Username)')) as $Object ) {
|
||||||
|
$results[$Object->Id()] = $Object;
|
||||||
|
}
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
|
||||||
|
} # end class User
|
||||||
|
?>
|
|
@ -25,21 +25,28 @@ define('DB_LOG_DEBUG', 2);
|
||||||
$GLOBALS['dbLogLevel'] = DB_LOG_OFF;
|
$GLOBALS['dbLogLevel'] = DB_LOG_OFF;
|
||||||
|
|
||||||
$GLOBALS['dbConn'] = false;
|
$GLOBALS['dbConn'] = false;
|
||||||
|
require_once('logger.php');
|
||||||
|
|
||||||
function dbConnect() {
|
function dbConnect() {
|
||||||
global $dbConn;
|
global $dbConn;
|
||||||
|
|
||||||
|
$dsn = ZM_DB_TYPE;
|
||||||
|
if ( ZM_DB_HOST ) {
|
||||||
if ( strpos(ZM_DB_HOST, ':') ) {
|
if ( strpos(ZM_DB_HOST, ':') ) {
|
||||||
// Host variable may carry a port or socket.
|
// Host variable may carry a port or socket.
|
||||||
list($host, $portOrSocket) = explode(':', ZM_DB_HOST, 2);
|
list($host, $portOrSocket) = explode(':', ZM_DB_HOST, 2);
|
||||||
if ( ctype_digit($portOrSocket) ) {
|
if ( ctype_digit($portOrSocket) ) {
|
||||||
$socket = ':host='.$host . ';port='.$portOrSocket;
|
$dsn .= ':host='.$host.';port='.$portOrSocket.';';
|
||||||
} else {
|
} else {
|
||||||
$socket = ':unix_socket='.$portOrSocket;
|
$dsn .= ':unix_socket='.$portOrSocket.';';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$socket = ':host='.ZM_DB_HOST;
|
$dsn .= ':host='.ZM_DB_HOST.';';
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
$dsn .= ':host=localhost;';
|
||||||
|
}
|
||||||
|
$dsn .= 'dbname='.ZM_DB_NAME;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$dbOptions = null;
|
$dbOptions = null;
|
||||||
|
@ -49,21 +56,24 @@ function dbConnect() {
|
||||||
PDO::MYSQL_ATTR_SSL_KEY => ZM_DB_SSL_CLIENT_KEY,
|
PDO::MYSQL_ATTR_SSL_KEY => ZM_DB_SSL_CLIENT_KEY,
|
||||||
PDO::MYSQL_ATTR_SSL_CERT => ZM_DB_SSL_CLIENT_CERT,
|
PDO::MYSQL_ATTR_SSL_CERT => ZM_DB_SSL_CLIENT_CERT,
|
||||||
);
|
);
|
||||||
$dbConn = new PDO(ZM_DB_TYPE . $socket . ';dbname='.ZM_DB_NAME, ZM_DB_USER, ZM_DB_PASS, $dbOptions);
|
$dbConn = new PDO($dsn, ZM_DB_USER, ZM_DB_PASS, $dbOptions);
|
||||||
} else {
|
} else {
|
||||||
$dbConn = new PDO(ZM_DB_TYPE . $socket . ';dbname='.ZM_DB_NAME, ZM_DB_USER, ZM_DB_PASS);
|
$dbConn = new PDO($dsn, ZM_DB_USER, ZM_DB_PASS);
|
||||||
}
|
}
|
||||||
|
|
||||||
$dbConn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
|
$dbConn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
|
||||||
$dbConn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
$dbConn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||||
} catch(PDOException $ex) {
|
} catch(PDOException $ex) {
|
||||||
echo 'Unable to connect to ZM db.' . $ex->getMessage();
|
echo "Unable to connect to ZM db using dsn $dsn host".ZM_DB_HOST.' user: ('.ZM_DB_USER.') password ('.ZM_DB_PASS.': '.$ex->getMessage();
|
||||||
error_log('Unable to connect to ZM DB ' . $ex->getMessage());
|
error_log('Unable to connect to ZM DB ' . $ex->getMessage());
|
||||||
$dbConn = null;
|
$dbConn = null;
|
||||||
}
|
}
|
||||||
}
|
return $dbConn;
|
||||||
|
} // end function dbConnect
|
||||||
|
|
||||||
dbConnect();
|
if ( !dbConnect() ) {
|
||||||
|
ZM\Fatal('Failed db connection');
|
||||||
|
}
|
||||||
|
|
||||||
function dbDisconnect() {
|
function dbDisconnect() {
|
||||||
global $dbConn;
|
global $dbConn;
|
||||||
|
|
|
@ -1505,15 +1505,15 @@ function getLoad() {
|
||||||
function getDiskPercent($path = ZM_DIR_EVENTS) {
|
function getDiskPercent($path = ZM_DIR_EVENTS) {
|
||||||
$total = disk_total_space($path);
|
$total = disk_total_space($path);
|
||||||
if ( $total === false ) {
|
if ( $total === false ) {
|
||||||
Error('disk_total_space returned false. Verify the web account user has access to ' . $path);
|
ZM\Error('disk_total_space returned false. Verify the web account user has access to ' . $path);
|
||||||
return 0;
|
return 0;
|
||||||
} elseif ( $total == 0 ) {
|
} elseif ( $total == 0 ) {
|
||||||
Error('disk_total_space indicates the following path has a filesystem size of zero bytes ' . $path);
|
ZM\Error('disk_total_space indicates the following path has a filesystem size of zero bytes ' . $path);
|
||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
$free = disk_free_space($path);
|
$free = disk_free_space($path);
|
||||||
if ( $free === false ) {
|
if ( $free === false ) {
|
||||||
Error('disk_free_space returned false. Verify the web account user has access to ' . $path);
|
ZM\Error('disk_free_space returned false. Verify the web account user has access to ' . $path);
|
||||||
}
|
}
|
||||||
$space = round((($total - $free) / $total) * 100);
|
$space = round((($total - $free) / $total) * 100);
|
||||||
return $space;
|
return $space;
|
||||||
|
@ -2069,7 +2069,7 @@ function logState() {
|
||||||
if ( $count['Level'] <= ZM\Logger::PANIC )
|
if ( $count['Level'] <= ZM\Logger::PANIC )
|
||||||
$count['Level'] = ZM\Logger::FATAL;
|
$count['Level'] = ZM\Logger::FATAL;
|
||||||
if ( !($levelCount = $levelCounts[$count['Level']]) ) {
|
if ( !($levelCount = $levelCounts[$count['Level']]) ) {
|
||||||
Error('Unexpected Log level '.$count['Level']);
|
ZM\Error('Unexpected Log level '.$count['Level']);
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
if ( $levelCount[1] && $count['LevelCount'] >= $levelCount[1] ) {
|
if ( $levelCount[1] && $count['LevelCount'] >= $levelCount[1] ) {
|
||||||
|
|
|
@ -100,14 +100,17 @@ class Logger {
|
||||||
$tempDatabaseLevel = $options['databaseLevel'];
|
$tempDatabaseLevel = $options['databaseLevel'];
|
||||||
else
|
else
|
||||||
$tempDatabaseLevel = ZM_LOG_LEVEL_DATABASE;
|
$tempDatabaseLevel = ZM_LOG_LEVEL_DATABASE;
|
||||||
|
|
||||||
if ( isset($options['fileLevel']) )
|
if ( isset($options['fileLevel']) )
|
||||||
$tempFileLevel = $options['fileLevel'];
|
$tempFileLevel = $options['fileLevel'];
|
||||||
else
|
else
|
||||||
$tempFileLevel = ZM_LOG_LEVEL_FILE;
|
$tempFileLevel = ZM_LOG_LEVEL_FILE;
|
||||||
|
|
||||||
if ( isset($options['weblogLevel']) )
|
if ( isset($options['weblogLevel']) )
|
||||||
$tempWeblogLevel = $options['weblogLevel'];
|
$tempWeblogLevel = $options['weblogLevel'];
|
||||||
else
|
else
|
||||||
$tempWeblogLevel = ZM_LOG_LEVEL_WEBLOG;
|
$tempWeblogLevel = ZM_LOG_LEVEL_WEBLOG;
|
||||||
|
|
||||||
if ( isset($options['syslogLevel']) )
|
if ( isset($options['syslogLevel']) )
|
||||||
$tempSyslogLevel = $options['syslogLevel'];
|
$tempSyslogLevel = $options['syslogLevel'];
|
||||||
else
|
else
|
||||||
|
|
|
@ -376,6 +376,7 @@ $SLANG = array(
|
||||||
'Filters' => 'Filters',
|
'Filters' => 'Filters',
|
||||||
'FilterUnset' => 'You must specify a filter width and height',
|
'FilterUnset' => 'You must specify a filter width and height',
|
||||||
'FilterUploadEvents' => 'Upload all matches',
|
'FilterUploadEvents' => 'Upload all matches',
|
||||||
|
'FilterUser' => 'User to run filter as',
|
||||||
'FilterVideoEvents' => 'Create video for all matches',
|
'FilterVideoEvents' => 'Create video for all matches',
|
||||||
'First' => 'First',
|
'First' => 'First',
|
||||||
'FlippedHori' => 'Flipped Horizontally',
|
'FlippedHori' => 'Flipped Horizontally',
|
||||||
|
|
|
@ -205,6 +205,7 @@ getBodyTopHTML();
|
||||||
<?php
|
<?php
|
||||||
ob_start();
|
ob_start();
|
||||||
?>
|
?>
|
||||||
|
<div class="table-responsive">
|
||||||
<table class="table table-striped table-hover table-condensed consoleTable">
|
<table class="table table-striped table-hover table-condensed consoleTable">
|
||||||
<thead class="thead-highlight">
|
<thead class="thead-highlight">
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -394,5 +395,6 @@ for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) {
|
||||||
</tfoot>
|
</tfoot>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<?php xhtmlFooter() ?>
|
<?php xhtmlFooter() ?>
|
||||||
|
|
|
@ -27,6 +27,7 @@ require_once('includes/Storage.php');
|
||||||
require_once('includes/Filter.php');
|
require_once('includes/Filter.php');
|
||||||
require_once('includes/Monitor.php');
|
require_once('includes/Monitor.php');
|
||||||
require_once('includes/Zone.php');
|
require_once('includes/Zone.php');
|
||||||
|
require_once('includes/User.php');
|
||||||
parseSort();
|
parseSort();
|
||||||
|
|
||||||
$filterNames = array(''=>translate('ChooseFilter'));
|
$filterNames = array(''=>translate('ChooseFilter'));
|
||||||
|
@ -200,6 +201,18 @@ if ( (null !== $filter->Concurrent()) and $filter->Concurrent() )
|
||||||
<label for="filter[Name]"><?php echo translate('Name') ?></label>
|
<label for="filter[Name]"><?php echo translate('Name') ?></label>
|
||||||
<input type="text" id="filter[Name]" name="filter[Name]" value="<?php echo validHtmlStr($filter->Name()) ?>" data-on-input-this="updateButtons"/>
|
<input type="text" id="filter[Name]" name="filter[Name]" value="<?php echo validHtmlStr($filter->Name()) ?>" data-on-input-this="updateButtons"/>
|
||||||
</p>
|
</p>
|
||||||
|
<?php if ( ZM_OPT_USE_AUTH ) { ?>
|
||||||
|
<p><label><?php echo translate('FilterUser') ?></label>
|
||||||
|
<?php
|
||||||
|
global $user;
|
||||||
|
echo htmlSelect('filter[UserId]',
|
||||||
|
ZM\User::Indexed_By_Id(),
|
||||||
|
//ZM\User::find(),
|
||||||
|
$filter->UserId() ? $filter->UserId() : $user['Id']
|
||||||
|
); ?>
|
||||||
|
</p>
|
||||||
|
<?php } ?>
|
||||||
|
<p>
|
||||||
<table id="fieldsTable" class="filterTable">
|
<table id="fieldsTable" class="filterTable">
|
||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
|
|
|
@ -747,9 +747,11 @@ function fetchImage( streamImage ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleClick( event ) {
|
function handleClick( event ) {
|
||||||
var target = event.target;
|
var $target = $(event.target);
|
||||||
var x = event.page.x - $(target).getLeft();
|
var scaleX = parseInt(monitorWidth / $target.getWidth());
|
||||||
var y = event.page.y - $(target).getTop();
|
var scaleY = parseInt(monitorHeight / $target.getHeight());
|
||||||
|
var x = (event.page.x - $target.getLeft()) * scaleX;
|
||||||
|
var y = (event.page.y - $target.getTop()) * scaleY;
|
||||||
|
|
||||||
if ( showMode == 'events' || !imageControlMode ) {
|
if ( showMode == 'events' || !imageControlMode ) {
|
||||||
if ( event.shift ) {
|
if ( event.shift ) {
|
||||||
|
@ -848,7 +850,7 @@ function initPage() {
|
||||||
if ( refreshApplet && appletRefreshTime ) {
|
if ( refreshApplet && appletRefreshTime ) {
|
||||||
appletRefresh.delay(appletRefreshTime*1000);
|
appletRefresh.delay(appletRefreshTime*1000);
|
||||||
}
|
}
|
||||||
if ( scale == 'auto' ) changeScale();
|
if ( scale == '0' || scale == 'auto' ) changeScale();
|
||||||
if ( window.history.length == 1 ) {
|
if ( window.history.length == 1 ) {
|
||||||
$j('#closeControl').html('');
|
$j('#closeControl').html('');
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,12 +179,16 @@ function toPixels(field, maxValue) {
|
||||||
if ( field.value != '' ) {
|
if ( field.value != '' ) {
|
||||||
field.value = Math.round((field.value*maxValue)/100);
|
field.value = Math.round((field.value*maxValue)/100);
|
||||||
}
|
}
|
||||||
|
field.setAttribute('step', 1);
|
||||||
|
field.setAttribute('max', monitorArea);
|
||||||
}
|
}
|
||||||
|
|
||||||
function toPercent(field, maxValue) {
|
function toPercent(field, maxValue) {
|
||||||
if ( field.value != '' ) {
|
if ( field.value != '' ) {
|
||||||
field.value = Math.round((100*100*field.value)/maxValue)/100;
|
field.value = Math.round((100*100*field.value)/maxValue)/100;
|
||||||
}
|
}
|
||||||
|
field.setAttribute('step', 0.01);
|
||||||
|
field.setAttribute('max', 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyZoneUnits() {
|
function applyZoneUnits() {
|
||||||
|
|
|
@ -151,11 +151,11 @@ if ( $showControl ) {
|
||||||
}
|
}
|
||||||
if ( $showZones ) {
|
if ( $showZones ) {
|
||||||
?>
|
?>
|
||||||
<a id="ShowZones" href="?view=montage&showZones=0">Hide Zones</a>
|
<a id="HideZones" href="?view=montage&showZones=0"><?php echo translate('Hide Zones')?></a>
|
||||||
<?php
|
<?php
|
||||||
} else {
|
} else {
|
||||||
?>
|
?>
|
||||||
<a id="ShowZones" href="?view=montage&showZones=1">Show Zones</a>
|
<a id="ShowZones" href="?view=montage&showZones=1"><?php echo translate('Show Zones')?></a>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -96,12 +96,14 @@ function probeProfiles($device_ep, $soapversion, $username, $password) {
|
||||||
if ( $lines = @execONVIF("profiles $device_ep $soapversion $username $password") ) {
|
if ( $lines = @execONVIF("profiles $device_ep $soapversion $username $password") ) {
|
||||||
foreach ( $lines as $line ) {
|
foreach ( $lines as $line ) {
|
||||||
$line = rtrim( $line );
|
$line = rtrim( $line );
|
||||||
if ( preg_match('|^(.+),\s*(.+),\s*(.+),\s*(.+),\s*(.+),\s*(.+),\s*(.+)\s*$|', $line, $matches) ) {
|
|
||||||
$stream_uri = $matches[7];
|
if ( preg_match('|^([^,]+),\s*([^,]+),\s*([^,]+),\s*(\d+),\s*(\d+),\s*(\d+),\s*([^,]+),\s*(.+)\s*$|', $line, $matches) ) {
|
||||||
|
$stream_uri = $matches[8];
|
||||||
// add user@pass to URI
|
// add user@pass to URI
|
||||||
if ( preg_match('|^(\S+://)(.+)$|', $stream_uri, $tokens) ) {
|
if ( preg_match('|^(\S+://)(.+)$|', $stream_uri, $tokens) ) {
|
||||||
$stream_uri = $tokens[1].$username.':'.$password.'@'.$tokens[2];
|
$stream_uri = $tokens[1].$username.':'.$password.'@'.$tokens[2];
|
||||||
}
|
}
|
||||||
|
ZM\Warning(print_r($matches,1));
|
||||||
|
|
||||||
$profile = array( # 'monitor' part of camera
|
$profile = array( # 'monitor' part of camera
|
||||||
'Type' => 'Ffmpeg',
|
'Type' => 'Ffmpeg',
|
||||||
|
@ -113,6 +115,7 @@ function probeProfiles($device_ep, $soapversion, $username, $password) {
|
||||||
'Profile' => $matches[1],
|
'Profile' => $matches[1],
|
||||||
'Name' => $matches[2],
|
'Name' => $matches[2],
|
||||||
'Encoding' => $matches[3],
|
'Encoding' => $matches[3],
|
||||||
|
'Transport' => $matches[7],
|
||||||
);
|
);
|
||||||
$profiles[] = $profile;
|
$profiles[] = $profile;
|
||||||
} else {
|
} else {
|
||||||
|
@ -261,10 +264,17 @@ if ( !isset($_REQUEST['step']) || ($_REQUEST['step'] == '1') ) {
|
||||||
$monitor = $camera['monitor'];
|
$monitor = $camera['monitor'];
|
||||||
|
|
||||||
$sourceString = "${profile['Name']} : ${profile['Encoding']}" .
|
$sourceString = "${profile['Name']} : ${profile['Encoding']}" .
|
||||||
" (${profile['Width']}x${profile['Height']} @ ${profile['MaxFPS']}fps)";
|
" (${profile['Width']}x${profile['Height']} @ ${profile['MaxFPS']}fps ${profile['Transport']})";
|
||||||
// copy technical details
|
// copy technical details
|
||||||
$monitor['Width'] = $profile['Width'];
|
$monitor['Width'] = $profile['Width'];
|
||||||
$monitor['Height'] = $profile['Height'];
|
$monitor['Height'] = $profile['Height'];
|
||||||
|
if ( $profile['Transport'] == 'RTP-Multicast' ) {
|
||||||
|
$monitor['Method'] = 'rtpMulti';
|
||||||
|
} else if ( $profile['Transport'] == 'RTP-Unicast' ) {
|
||||||
|
$monitor['Method'] = 'rtpUni';
|
||||||
|
} else {
|
||||||
|
$monitor['Method'] = 'rtpRtsp';
|
||||||
|
}
|
||||||
// The maxfps fields do not work for ip streams. Can re-enable if that is fixed.
|
// The maxfps fields do not work for ip streams. Can re-enable if that is fixed.
|
||||||
// $monitor['MaxFPS'] = $profile['MaxFPS'];
|
// $monitor['MaxFPS'] = $profile['MaxFPS'];
|
||||||
// $monitor['AlarmMaxFPS'] = $profile['AlarmMaxFPS'];
|
// $monitor['AlarmMaxFPS'] = $profile['AlarmMaxFPS'];
|
||||||
|
|
|
@ -174,29 +174,36 @@ xhtmlHeaders(__FILE__, translate('Zone'));
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row"><?php echo translate('Type') ?></th>
|
<th scope="row"><?php echo translate('Type') ?></th>
|
||||||
<td colspan="2"><?php echo htmlSelect('newZone[Type]', $optTypes, $newZone['Type'],
|
<td colspan="2"><?php echo htmlSelect('newZone[Type]', $optTypes, $newZone['Type'],
|
||||||
array('onchange'=>'applyZoneType()')); ?></td>
|
array('data-on-change'=>'applyZoneType')); ?></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row"><?php echo translate('Preset') ?></th>
|
<th scope="row"><?php echo translate('Preset') ?></th>
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
<?php echo htmlSelect('presetSelector', $presetNames,
|
<?php echo htmlSelect('presetSelector', $presetNames,
|
||||||
( isset($_REQUEST['presetSelector']) ? $_REQUEST['presetSelector'] : null),
|
( isset($_REQUEST['presetSelector']) ? $_REQUEST['presetSelector'] : null),
|
||||||
array('onchange'=>'applyPreset()', 'onblur'=>'this.selectedIndex=0') )
|
array('data-on-change'=>'applyPreset', 'onblur'=>'this.selectedIndex=0') )
|
||||||
?></td>
|
?></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row"><?php echo translate('Units') ?></th>
|
<th scope="row"><?php echo translate('Units') ?></th>
|
||||||
<td colspan="2"><?php echo htmlSelect('newZone[Units]', $optUnits, $newZone['Units'],
|
<td colspan="2">
|
||||||
array('onchange'=>'applyZoneUnits()') ) ?></td>
|
<?php
|
||||||
|
echo htmlSelect('newZone[Units]', $optUnits, $newZone['Units'],
|
||||||
|
array('data-on-change'=>'applyZoneUnits')
|
||||||
|
);
|
||||||
|
# Used later for number inputs
|
||||||
|
$step = $newZone['Units'] == 'Percent' ? ' step="0.01" max="100"' : '';
|
||||||
|
?>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row"><?php echo translate('ZoneAlarmColour') ?></th>
|
<th scope="row"><?php echo translate('ZoneAlarmColour') ?></th>
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
<input type="number" name="newAlarmRgbR" value="<?php echo ($newZone['AlarmRGB']>>16)&0xff ?>" size="3"/>
|
<input type="number" name="newAlarmRgbR" value="<?php echo ($newZone['AlarmRGB']>>16)&0xff ?>" min="0" max="255"/>
|
||||||
/
|
/
|
||||||
<input type="number" name="newAlarmRgbG" value="<?php echo ($newZone['AlarmRGB']>>8)&0xff ?>" size="3"/>
|
<input type="number" name="newAlarmRgbG" value="<?php echo ($newZone['AlarmRGB']>>8)&0xff ?>" min="0" max="255"/>
|
||||||
/
|
/
|
||||||
<input type="number" name="newAlarmRgbB" value="<?php echo $newZone['AlarmRGB']&0xff ?>" size="3"/>
|
<input type="number" name="newAlarmRgbB" value="<?php echo $newZone['AlarmRGB']&0xff ?>" min="0" max="255"/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -205,45 +212,45 @@ xhtmlHeaders(__FILE__, translate('Zone'));
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row"><?php echo translate('ZoneMinMaxPixelThres') ?></th>
|
<th scope="row"><?php echo translate('ZoneMinMaxPixelThres') ?></th>
|
||||||
<td><input type="number" name="newZone[MinPixelThreshold]" value="<?php echo $newZone['MinPixelThreshold'] ?>" size="4"/></td>
|
<td><input type="number" name="newZone[MinPixelThreshold]" value="<?php echo $newZone['MinPixelThreshold'] ?>"/></td>
|
||||||
<td><input type="number" name="newZone[MaxPixelThreshold]" value="<?php echo $newZone['MaxPixelThreshold'] ?>" size="4"/></td>
|
<td><input type="number" name="newZone[MaxPixelThreshold]" value="<?php echo $newZone['MaxPixelThreshold'] ?>"/></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row"><?php echo translate('ZoneFilterSize') ?></th>
|
<th scope="row"><?php echo translate('ZoneFilterSize') ?></th>
|
||||||
<td><input type="number" name="newZone[FilterX]" value="<?php echo $newZone['FilterX'] ?>" size="4"/></td>
|
<td><input type="number" name="newZone[FilterX]" value="<?php echo $newZone['FilterX'] ?>"/></td>
|
||||||
<td><input type="number" name="newZone[FilterY]" value="<?php echo $newZone['FilterY'] ?>" size="4"/></td>
|
<td><input type="number" name="newZone[FilterY]" value="<?php echo $newZone['FilterY'] ?>"/></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row"><?php echo translate('ZoneArea') ?></th>
|
<th scope="row"><?php echo translate('ZoneArea') ?></th>
|
||||||
<td colspan="2"><input type="number" name="newZone[TempArea]" value="<?php echo $newZone['Area'] ?>" size="7" disabled="disabled"/></td>
|
<td colspan="2"><input type="number" name="newZone[TempArea]" value="<?php echo $newZone['Area'] ?>" disabled="disabled"/></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row"><?php echo translate('ZoneMinMaxAlarmArea') ?></th>
|
<th scope="row"><?php echo translate('ZoneMinMaxAlarmArea') ?></th>
|
||||||
<td><input type="number" name="newZone[MinAlarmPixels]" value="<?php echo $newZone['MinAlarmPixels'] ?>" size="6"/></td>
|
<td><input type="number" name="newZone[MinAlarmPixels]" value="<?php echo $newZone['MinAlarmPixels'] ?>"<?php echo $step ?> min="0"/></td>
|
||||||
<td><input type="number" name="newZone[MaxAlarmPixels]" value="<?php echo $newZone['MaxAlarmPixels'] ?>" size="6"/></td>
|
<td><input type="number" name="newZone[MaxAlarmPixels]" value="<?php echo $newZone['MaxAlarmPixels'] ?>"<?php echo $step ?> min="0"/></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row"><?php echo translate('ZoneMinMaxFiltArea') ?></th>
|
<th scope="row"><?php echo translate('ZoneMinMaxFiltArea') ?></th>
|
||||||
<td><input type="number" name="newZone[MinFilterPixels]" value="<?php echo $newZone['MinFilterPixels'] ?>" size="6"/></td>
|
<td><input type="number" name="newZone[MinFilterPixels]" value="<?php echo $newZone['MinFilterPixels'] ?>"<?php echo $step ?> min="0"/></td>
|
||||||
<td><input type="number" name="newZone[MaxFilterPixels]" value="<?php echo $newZone['MaxFilterPixels'] ?>" size="6"/></td>
|
<td><input type="number" name="newZone[MaxFilterPixels]" value="<?php echo $newZone['MaxFilterPixels'] ?>"<?php echo $step ?> min="0"/></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row"><?php echo translate('ZoneMinMaxBlobArea') ?></th>
|
<th scope="row"><?php echo translate('ZoneMinMaxBlobArea') ?></th>
|
||||||
<td><input type="number" name="newZone[MinBlobPixels]" value="<?php echo $newZone['MinBlobPixels'] ?>" size="6"/></td>
|
<td><input type="number" name="newZone[MinBlobPixels]" value="<?php echo $newZone['MinBlobPixels'] ?>"<?php echo $step ?> min="0"/></td>
|
||||||
<td><input type="number" name="newZone[MaxBlobPixels]" value="<?php echo $newZone['MaxBlobPixels'] ?>" size="6"/></td>
|
<td><input type="number" name="newZone[MaxBlobPixels]" value="<?php echo $newZone['MaxBlobPixels'] ?>"<?php echo $step ?> min="0"/></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row"><?php echo translate('ZoneMinMaxBlobs') ?></th>
|
<th scope="row"><?php echo translate('ZoneMinMaxBlobs') ?></th>
|
||||||
<td><input type="number" name="newZone[MinBlobs]" value="<?php echo $newZone['MinBlobs'] ?>" size="4"/></td>
|
<td><input type="number" name="newZone[MinBlobs]" value="<?php echo $newZone['MinBlobs'] ?>" min="0"/></td>
|
||||||
<td><input type="number" name="newZone[MaxBlobs]" value="<?php echo $newZone['MaxBlobs'] ?>" size="4"/></td>
|
<td><input type="number" name="newZone[MaxBlobs]" value="<?php echo $newZone['MaxBlobs'] ?>" min="0"/></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row"><?php echo translate('ZoneOverloadFrames') ?></th>
|
<th scope="row"><?php echo translate('ZoneOverloadFrames') ?></th>
|
||||||
<td colspan="2"><input type="number" name="newZone[OverloadFrames]" value="<?php echo $newZone['OverloadFrames'] ?>" size="4"/></td>
|
<td colspan="2"><input type="number" name="newZone[OverloadFrames]" value="<?php echo $newZone['OverloadFrames'] ?>" min="0"/></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row"><?php echo translate('ZoneExtendAlarmFrames') ?></th>
|
<th scope="row"><?php echo translate('ZoneExtendAlarmFrames') ?></th>
|
||||||
<td colspan="2"><input type="number" name="newZone[ExtendAlarmFrames]" value="<?php echo $newZone['ExtendAlarmFrames'] ?>" size="4"/></td>
|
<td colspan="2"><input type="number" name="newZone[ExtendAlarmFrames]" value="<?php echo $newZone['ExtendAlarmFrames'] ?>" min="0"/></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
Loading…
Reference in New Issue