Merge branch 'storageareas' of github.com:/ConnorTechnology/ZoneMinder into storageareas
This commit is contained in:
commit
93ecf69381
|
@ -6,3 +6,4 @@ usr/share/perl5/ZoneMinder.pm
|
||||||
usr/share/zoneminder/db
|
usr/share/zoneminder/db
|
||||||
usr/share/zoneminder/www
|
usr/share/zoneminder/www
|
||||||
etc/zm
|
etc/zm
|
||||||
|
etc/zm/conf.d/*
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
etc/zm/zm.conf
|
etc/zm/zm.conf
|
||||||
|
etc/zm/conf.d/*
|
||||||
usr/bin
|
usr/bin
|
||||||
usr/lib/zoneminder
|
usr/lib/zoneminder
|
||||||
usr/share/polkit-1
|
usr/share/polkit-1
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
etc/zm
|
etc/zm
|
||||||
|
etc/zm/conf.d/*
|
||||||
usr/bin
|
usr/bin
|
||||||
usr/share/polkit-1/actions
|
usr/share/polkit-1/actions
|
||||||
usr/share/polkit-1/rules.d
|
usr/share/polkit-1/rules.d
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
etc/zm/zm.conf
|
etc/zm/zm.conf
|
||||||
|
etc/zm/conf.d/*
|
||||||
usr/bin
|
usr/bin
|
||||||
usr/lib/zoneminder
|
usr/lib/zoneminder
|
||||||
usr/share/polkit-1
|
usr/share/polkit-1
|
||||||
|
|
|
@ -33,8 +33,11 @@ FOREACH(PERLSCRIPT ${perlscripts})
|
||||||
ENDFOREACH(PERLSCRIPT ${perlscripts})
|
ENDFOREACH(PERLSCRIPT ${perlscripts})
|
||||||
|
|
||||||
# Install the perl scripts
|
# Install the perl scripts
|
||||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/zmaudit.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmcontrol.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmdc.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmfilter.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmpkg.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmtrack.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmtrigger.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmupdate.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmvideo.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmwatch.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmcamtool.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmsystemctl.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmtelemetry.pl" DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}" PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/zmaudit.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmcontrol.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmdc.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmfilter.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmpkg.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmtrack.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmtrigger.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmupdate.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmvideo.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmwatch.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmcamtool.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmtelemetry.pl" DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}" PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
||||||
if(NOT ZM_NO_X10)
|
if(NOT ZM_NO_X10)
|
||||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/zmx10.pl" DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}" PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/zmx10.pl" DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}" PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
||||||
endif(NOT ZM_NO_X10)
|
endif(NOT ZM_NO_X10)
|
||||||
|
|
||||||
|
if(WITH_SYSTEMD)
|
||||||
|
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/zmsystemctl.pl" DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}" PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
||||||
|
endif(WITH_SYSTEMD)
|
||||||
|
|
|
@ -41,7 +41,7 @@ our @ISA = qw(Exporter ZoneMinder::Base);
|
||||||
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
|
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
|
||||||
# will save memory.
|
# will save memory.
|
||||||
our %EXPORT_TAGS = (
|
our %EXPORT_TAGS = (
|
||||||
'constants' => [ qw(
|
constants => [ qw(
|
||||||
DEBUG
|
DEBUG
|
||||||
INFO
|
INFO
|
||||||
WARNING
|
WARNING
|
||||||
|
@ -50,7 +50,7 @@ our %EXPORT_TAGS = (
|
||||||
PANIC
|
PANIC
|
||||||
NOLOG
|
NOLOG
|
||||||
) ],
|
) ],
|
||||||
'functions' => [ qw(
|
functions => [ qw(
|
||||||
logInit
|
logInit
|
||||||
logReinit
|
logReinit
|
||||||
logTerm
|
logTerm
|
||||||
|
@ -72,13 +72,14 @@ our %EXPORT_TAGS = (
|
||||||
Panic
|
Panic
|
||||||
) ]
|
) ]
|
||||||
);
|
);
|
||||||
push( @{$EXPORT_TAGS{all}}, @{$EXPORT_TAGS{$_}} ) foreach keys %EXPORT_TAGS;
|
|
||||||
|
|
||||||
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
|
push( @{$EXPORT_TAGS{all}}, @{$EXPORT_TAGS{$_}} ) foreach keys %EXPORT_TAGS;
|
||||||
|
|
||||||
our @EXPORT = qw();
|
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
|
||||||
|
|
||||||
our $VERSION = $ZoneMinder::Base::VERSION;
|
our @EXPORT = qw();
|
||||||
|
|
||||||
|
our $VERSION = $ZoneMinder::Base::VERSION;
|
||||||
|
|
||||||
# ==========================================================================
|
# ==========================================================================
|
||||||
#
|
#
|
||||||
|
@ -86,43 +87,43 @@ our %EXPORT_TAGS = (
|
||||||
#
|
#
|
||||||
# ==========================================================================
|
# ==========================================================================
|
||||||
|
|
||||||
use ZoneMinder::Config qw(:all);
|
use ZoneMinder::Config qw(:all);
|
||||||
|
|
||||||
use DBI;
|
use DBI;
|
||||||
use Carp;
|
use Carp;
|
||||||
use POSIX;
|
use POSIX;
|
||||||
use IO::Handle;
|
use IO::Handle;
|
||||||
use Data::Dumper;
|
use Data::Dumper;
|
||||||
use Time::HiRes qw/gettimeofday/;
|
use Time::HiRes qw/gettimeofday/;
|
||||||
use Sys::Syslog;
|
use Sys::Syslog;
|
||||||
|
|
||||||
use constant {
|
use constant {
|
||||||
DEBUG => 1,
|
DEBUG => 1,
|
||||||
INFO => 0,
|
INFO => 0,
|
||||||
WARNING => -1,
|
WARNING => -1,
|
||||||
ERROR => -2,
|
ERROR => -2,
|
||||||
FATAL => -3,
|
FATAL => -3,
|
||||||
PANIC => -4,
|
PANIC => -4,
|
||||||
NOLOG => -5
|
NOLOG => -5
|
||||||
};
|
};
|
||||||
|
|
||||||
our %codes = (
|
our %codes = (
|
||||||
&DEBUG => "DBG",
|
&DEBUG => 'DBG',
|
||||||
&INFO => "INF",
|
&INFO => 'INF',
|
||||||
&WARNING => "WAR",
|
&WARNING => 'WAR',
|
||||||
&ERROR => "ERR",
|
&ERROR => 'ERR',
|
||||||
&FATAL => "FAT",
|
&FATAL => 'FAT',
|
||||||
&PANIC => "PNC",
|
&PANIC => 'PNC',
|
||||||
&NOLOG => "OFF"
|
&NOLOG => 'OFF'
|
||||||
);
|
);
|
||||||
|
|
||||||
our %priorities = (
|
our %priorities = (
|
||||||
&DEBUG => "debug",
|
&DEBUG => 'debug',
|
||||||
&INFO => "info",
|
&INFO => 'info',
|
||||||
&WARNING => "warning",
|
&WARNING => 'warning',
|
||||||
&ERROR => "err",
|
&ERROR => 'err',
|
||||||
&FATAL => "err",
|
&FATAL => 'err',
|
||||||
&PANIC => "err"
|
&PANIC => 'err'
|
||||||
);
|
);
|
||||||
|
|
||||||
our $logger;
|
our $logger;
|
||||||
|
@ -134,10 +135,10 @@ sub new {
|
||||||
|
|
||||||
$this->{initialised} = undef;
|
$this->{initialised} = undef;
|
||||||
|
|
||||||
#$this->{id} = "zmundef";
|
#$this->{id} = 'zmundef';
|
||||||
( $this->{id} ) = $0 =~ m|^(?:.*/)?([^/]+?)(?:\.[^/.]+)?$|;
|
( $this->{id} ) = $0 =~ m|^(?:.*/)?([^/]+?)(?:\.[^/.]+)?$|;
|
||||||
$this->{idRoot} = $this->{id};
|
$this->{idRoot} = $this->{id};
|
||||||
$this->{idArgs} = "";
|
$this->{idArgs} = '';
|
||||||
|
|
||||||
$this->{level} = INFO;
|
$this->{level} = INFO;
|
||||||
if (-t STDIN) {
|
if (-t STDIN) {
|
||||||
|
@ -155,7 +156,7 @@ if (-t STDIN) {
|
||||||
|
|
||||||
( $this->{fileName} = $0 ) =~ s|^.*/||;
|
( $this->{fileName} = $0 ) =~ s|^.*/||;
|
||||||
$this->{logPath} = $Config{ZM_PATH_LOGS};
|
$this->{logPath} = $Config{ZM_PATH_LOGS};
|
||||||
$this->{logFile} = $this->{logPath}."/".$this->{id}.".log";
|
$this->{logFile} = $this->{logPath}.'/'.$this->{id}.".log";
|
||||||
|
|
||||||
$this->{trace} = 0;
|
$this->{trace} = 0;
|
||||||
|
|
||||||
|
@ -200,7 +201,7 @@ sub initialise( @ ) {
|
||||||
$this->{logPath} = $options{logPath} if ( defined($options{logPath}) );
|
$this->{logPath} = $options{logPath} if ( defined($options{logPath}) );
|
||||||
|
|
||||||
my $tempLogFile;
|
my $tempLogFile;
|
||||||
$tempLogFile = $this->{logPath}."/".$this->{id}.".log";
|
$tempLogFile = $this->{logPath}.'/'.$this->{id}.".log";
|
||||||
$tempLogFile = $options{logFile} if ( defined($options{logFile}) );
|
$tempLogFile = $options{logFile} if ( defined($options{logFile}) );
|
||||||
if ( my $logFile = $this->getTargettedEnv('LOG_FILE') ) {
|
if ( my $logFile = $this->getTargettedEnv('LOG_FILE') ) {
|
||||||
$tempLogFile = $logFile;
|
$tempLogFile = $logFile;
|
||||||
|
@ -235,7 +236,6 @@ sub initialise( @ ) {
|
||||||
|
|
||||||
my $level;
|
my $level;
|
||||||
$tempLevel = $level if ( defined($level = $this->getTargettedEnv('LOG_LEVEL')) );
|
$tempLevel = $level if ( defined($level = $this->getTargettedEnv('LOG_LEVEL')) );
|
||||||
|
|
||||||
$tempTermLevel = $level if ( defined($level = $this->getTargettedEnv('LOG_LEVEL_TERM')) );
|
$tempTermLevel = $level if ( defined($level = $this->getTargettedEnv('LOG_LEVEL_TERM')) );
|
||||||
$tempDatabaseLevel = $level if ( defined($level = $this->getTargettedEnv('LOG_LEVEL_DATABASE')) );
|
$tempDatabaseLevel = $level if ( defined($level = $this->getTargettedEnv('LOG_LEVEL_DATABASE')) );
|
||||||
$tempFileLevel = $level if ( defined($level = $this->getTargettedEnv('LOG_LEVEL_FILE')) );
|
$tempFileLevel = $level if ( defined($level = $this->getTargettedEnv('LOG_LEVEL_FILE')) );
|
||||||
|
@ -244,9 +244,9 @@ sub initialise( @ ) {
|
||||||
if ( $Config{ZM_LOG_DEBUG} ) {
|
if ( $Config{ZM_LOG_DEBUG} ) {
|
||||||
foreach my $target ( split( /\|/, $Config{ZM_LOG_DEBUG_TARGET} ) ) {
|
foreach my $target ( split( /\|/, $Config{ZM_LOG_DEBUG_TARGET} ) ) {
|
||||||
if ( $target eq $this->{id}
|
if ( $target eq $this->{id}
|
||||||
|| $target eq "_".$this->{id}
|
|| $target eq '_'.$this->{id}
|
||||||
|| $target eq $this->{idRoot}
|
|| $target eq $this->{idRoot}
|
||||||
|| $target eq "_".$this->{idRoot}
|
|| $target eq '_'.$this->{idRoot}
|
||||||
|| $target eq ""
|
|| $target eq ""
|
||||||
) {
|
) {
|
||||||
if ( $Config{ZM_LOG_DEBUG_LEVEL} > NOLOG ) {
|
if ( $Config{ZM_LOG_DEBUG_LEVEL} > NOLOG ) {
|
||||||
|
@ -275,13 +275,13 @@ sub initialise( @ ) {
|
||||||
|
|
||||||
$this->{initialised} = !undef;
|
$this->{initialised} = !undef;
|
||||||
|
|
||||||
Debug( "LogOpts: level=".$codes{$this->{level}}
|
Debug( 'LogOpts: level='.$codes{$this->{level}}
|
||||||
."/".$codes{$this->{effectiveLevel}}
|
.'/'.$codes{$this->{effectiveLevel}}
|
||||||
.", screen=".$codes{$this->{termLevel}}
|
.', screen='.$codes{$this->{termLevel}}
|
||||||
.", database=".$codes{$this->{databaseLevel}}
|
.', database='.$codes{$this->{databaseLevel}}
|
||||||
.", logfile=".$codes{$this->{fileLevel}}
|
.', logfile='.$codes{$this->{fileLevel}}
|
||||||
."->".$this->{logFile}
|
.'->'.$this->{logFile}
|
||||||
.", syslog=".$codes{$this->{syslogLevel}}
|
.', syslog='.$codes{$this->{syslogLevel}}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,11 +326,11 @@ sub limit {
|
||||||
sub getTargettedEnv {
|
sub getTargettedEnv {
|
||||||
my $this = shift;
|
my $this = shift;
|
||||||
my $name = shift;
|
my $name = shift;
|
||||||
my $envName = $name."_".$this->{id};
|
my $envName = $name.'_'.$this->{id};
|
||||||
my $value;
|
my $value;
|
||||||
$value = $ENV{$envName} if ( defined($ENV{$envName}) );
|
$value = $ENV{$envName} if ( defined($ENV{$envName}) );
|
||||||
if ( !defined($value) && $this->{id} ne $this->{idRoot} ) {
|
if ( !defined($value) && $this->{id} ne $this->{idRoot} ) {
|
||||||
$envName = $name."_".$this->{idRoot};
|
$envName = $name.'_'.$this->{idRoot};
|
||||||
$value = $ENV{$envName} if ( defined($ENV{$envName}) );
|
$value = $ENV{$envName} if ( defined($ENV{$envName}) );
|
||||||
}
|
}
|
||||||
if ( !defined($value) ) {
|
if ( !defined($value) ) {
|
||||||
|
@ -494,7 +494,7 @@ sub syslogLevel {
|
||||||
|
|
||||||
sub openSyslog {
|
sub openSyslog {
|
||||||
my $this = shift;
|
my $this = shift;
|
||||||
openlog( $this->{id}, "pid", "local1" );
|
openlog( $this->{id}, 'pid', "local1" );
|
||||||
}
|
}
|
||||||
|
|
||||||
sub closeSyslog {
|
sub closeSyslog {
|
||||||
|
@ -527,6 +527,7 @@ sub openFile {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$this->fileLevel( NOLOG );
|
$this->fileLevel( NOLOG );
|
||||||
|
$this->termLevel( INFO );
|
||||||
Error( "Can't open log file '".$this->{logFile}."': $!" );
|
Error( "Can't open log file '".$this->{logFile}."': $!" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -548,10 +549,8 @@ sub logPrint {
|
||||||
|
|
||||||
my ($seconds, $microseconds) = gettimeofday();
|
my ($seconds, $microseconds) = gettimeofday();
|
||||||
my $message = sprintf(
|
my $message = sprintf(
|
||||||
"%s.%06d %s[%d].%s [%s]"
|
'%s.%06d %s[%d].%s [%s]'
|
||||||
, strftime( "%x %H:%M:%S"
|
, strftime( '%x %H:%M:%S' ,localtime( $seconds ) )
|
||||||
,localtime( $seconds )
|
|
||||||
)
|
|
||||||
, $microseconds
|
, $microseconds
|
||||||
, $this->{id}
|
, $this->{id}
|
||||||
, $$
|
, $$
|
||||||
|
@ -568,7 +567,7 @@ sub logPrint {
|
||||||
}
|
}
|
||||||
print( $LOGFILE $message ) if ( $level <= $this->{fileLevel} );
|
print( $LOGFILE $message ) if ( $level <= $this->{fileLevel} );
|
||||||
if ( $level <= $this->{databaseLevel} ) {
|
if ( $level <= $this->{databaseLevel} ) {
|
||||||
my $sql = "insert into Logs ( TimeKey, Component, Pid, Level, Code, Message, File, Line ) values ( ?, ?, ?, ?, ?, ?, ?, NULL )";
|
my $sql = 'insert into Logs ( TimeKey, Component, Pid, Level, Code, Message, File, Line ) values ( ?, ?, ?, ?, ?, ?, ?, NULL )';
|
||||||
$this->{sth} = $this->{dbh}->prepare_cached( $sql );
|
$this->{sth} = $this->{dbh}->prepare_cached( $sql );
|
||||||
if ( !$this->{sth} ) {
|
if ( !$this->{sth} ) {
|
||||||
$this->{databaseLevel} = NOLOG;
|
$this->{databaseLevel} = NOLOG;
|
||||||
|
@ -593,7 +592,7 @@ sub logPrint {
|
||||||
|
|
||||||
sub logInit( ;@ ) {
|
sub logInit( ;@ ) {
|
||||||
my %options = @_ ? @_ : ();
|
my %options = @_ ? @_ : ();
|
||||||
$logger = ZoneMinder::Logger->new() if ( !$logger );
|
$logger = ZoneMinder::Logger->new() if !$logger;
|
||||||
$logger->initialise( %options );
|
$logger->initialise( %options );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -650,14 +649,14 @@ sub logSyslogLevel {
|
||||||
sub Mark {
|
sub Mark {
|
||||||
my $level = shift;
|
my $level = shift;
|
||||||
$level = DEBUG unless( defined($level) );
|
$level = DEBUG unless( defined($level) );
|
||||||
my $tag = "Mark";
|
my $tag = 'Mark';
|
||||||
fetch()->logPrint( $level, $tag );
|
fetch()->logPrint( $level, $tag );
|
||||||
}
|
}
|
||||||
|
|
||||||
sub Dump {
|
sub Dump {
|
||||||
my $var = shift;
|
my $var = shift;
|
||||||
my $label = shift;
|
my $label = shift;
|
||||||
$label = "VAR" unless( defined($label) );
|
$label = 'VAR' unless( defined($label) );
|
||||||
fetch()->logPrint( DEBUG, Data::Dumper->Dump( [ $var ], [ $label ] ) );
|
fetch()->logPrint( DEBUG, Data::Dumper->Dump( [ $var ], [ $label ] ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -699,10 +698,10 @@ ZoneMinder::Logger - ZoneMinder Logger module
|
||||||
use ZoneMinder::Logger;
|
use ZoneMinder::Logger;
|
||||||
use ZoneMinder::Logger qw(:all);
|
use ZoneMinder::Logger qw(:all);
|
||||||
|
|
||||||
logInit( "myproc", DEBUG );
|
logInit( 'myproc', DEBUG );
|
||||||
|
|
||||||
Debug( "This is what is happening" );
|
Debug( 'This is what is happening' );
|
||||||
Info( "Something interesting is happening" );
|
Info( 'Something interesting is happening' );
|
||||||
Warning( "Something might be going wrong." );
|
Warning( "Something might be going wrong." );
|
||||||
Error( "Something has gone wrong!!" );
|
Error( "Something has gone wrong!!" );
|
||||||
Fatal( "Something has gone badly wrong, gotta stop!!" );
|
Fatal( "Something has gone badly wrong, gotta stop!!" );
|
||||||
|
|
|
@ -96,20 +96,11 @@ my $size = '';
|
||||||
my $overwrite = 0;
|
my $overwrite = 0;
|
||||||
my $version = 0;
|
my $version = 0;
|
||||||
|
|
||||||
my @formats = split( /\s+/, $Config{ZM_FFMPEG_FORMATS} );
|
|
||||||
for ( my $i = 0; $i < @formats; $i++ )
|
|
||||||
{
|
|
||||||
if ( $i =~ /^(.+)\*$/ )
|
|
||||||
{
|
|
||||||
$format = $formats[$i] = $1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GetOptions(
|
GetOptions(
|
||||||
'concat|c:s' =>\$concat_name,
|
'concat|c:s' =>\$concat_name,
|
||||||
'event|e=i' =>\$event_id,
|
'event|e=i' =>\$event_id,
|
||||||
'filter_name=s' =>\$filter_name,
|
'filter_name=s' =>\$filter_name,
|
||||||
'filter_id=i' =>\$filter_id,
|
'filter_id=i' =>\$filter_id,
|
||||||
'format|f=s' =>\$format,
|
'format|f=s' =>\$format,
|
||||||
'rate|r=f' =>\$rate,
|
'rate|r=f' =>\$rate,
|
||||||
'scale|s=f' =>\$scale,
|
'scale|s=f' =>\$scale,
|
||||||
|
@ -117,51 +108,51 @@ GetOptions(
|
||||||
'size|S=s' =>\$size,
|
'size|S=s' =>\$size,
|
||||||
'overwrite' =>\$overwrite,
|
'overwrite' =>\$overwrite,
|
||||||
'version' =>\$version
|
'version' =>\$version
|
||||||
) or pod2usage(-exitstatus => -1);
|
) or pod2usage(-exitstatus => -1);
|
||||||
|
|
||||||
if ( $version ) {
|
if ( $version ) {
|
||||||
print ZoneMinder::Base::ZM_VERSION . "\n";
|
print ZoneMinder::Base::ZM_VERSION . "\n";
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !( $filter_id or $filter_name or $event_id ) || $event_id < 0 )
|
if ( !( $filter_id or $filter_name or $event_id ) || ($event_id and ( $event_id < 0 ) ) ) {
|
||||||
{
|
print( STDERR "Please give a valid event id or filter name\n" );
|
||||||
print( STDERR "Please give a valid event id or filter name\n" );
|
pod2usage(-exitstatus => -1);
|
||||||
pod2usage(-exitstatus => -1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! $Config{ZM_OPT_FFMPEG} )
|
if ( ! $Config{ZM_OPT_FFMPEG} ) {
|
||||||
{
|
print( STDERR "Mpeg encoding is not currently enabled\n" );
|
||||||
print( STDERR "Mpeg encoding is not currently enabled\n" );
|
exit(-1);
|
||||||
exit(-1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !$rate && !$fps )
|
my @formats = split( /\s+/, $Config{ZM_FFMPEG_FORMATS} );
|
||||||
{
|
for ( my $i = 0; $i < @formats; $i++ ) {
|
||||||
$rate = 1;
|
if ( $i =~ /^(.+)\*$/ ) {
|
||||||
|
$format = $formats[$i] = $1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !$scale && !$size )
|
if ( !$rate && !$fps ) {
|
||||||
{
|
$rate = 1;
|
||||||
$scale = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $rate && ($rate < 0.25 || $rate > 100) )
|
if ( !$scale && !$size ) {
|
||||||
{
|
$scale = 1;
|
||||||
print( STDERR "Rate is out of range, 0.25 >= rate <= 100\n" );
|
|
||||||
pod2usage(-exitstatus => -1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $scale && ($scale < 0.25 || $scale > 4) )
|
if ( $rate && ($rate < 0.25 || $rate > 100) ) {
|
||||||
{
|
print( STDERR "Rate is out of range, 0.25 >= rate <= 100\n" );
|
||||||
print( STDERR "Scale is out of range, 0.25 >= scale <= 4\n" );
|
pod2usage(-exitstatus => -1);
|
||||||
pod2usage(-exitstatus => -1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $fps && ($fps > 30) )
|
if ( $scale && ($scale < 0.25 || $scale > 4) ) {
|
||||||
{
|
print( STDERR "Scale is out of range, 0.25 >= scale <= 4\n" );
|
||||||
print( STDERR "FPS is out of range, <= 30\n" );
|
pod2usage(-exitstatus => -1);
|
||||||
pod2usage(-exitstatus => -1);
|
}
|
||||||
|
|
||||||
|
if ( $fps && ($fps > 30) ) {
|
||||||
|
print( STDERR "FPS is out of range, <= 30\n" );
|
||||||
|
pod2usage(-exitstatus => -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
my ( $detaint_format ) = $format =~ /^(\w+)$/;
|
my ( $detaint_format ) = $format =~ /^(\w+)$/;
|
||||||
|
@ -183,24 +174,25 @@ my $cwd = getcwd;
|
||||||
my $video_name;
|
my $video_name;
|
||||||
my @event_ids;
|
my @event_ids;
|
||||||
if ( $event_id ) {
|
if ( $event_id ) {
|
||||||
Debug("Making a video of event $event_id");
|
|
||||||
@event_ids = ( $event_id );
|
@event_ids = ( $event_id );
|
||||||
|
|
||||||
} elsif ( $filter_name or $filter_id ) {
|
} elsif ( $filter_name or $filter_id ) {
|
||||||
Debug("Loading filter " .join('',
|
|
||||||
($filter_name ? "Name => $filter_name" : '' ),
|
|
||||||
($filter_id ? "Id => $filter_id " : '' ),
|
|
||||||
) );
|
|
||||||
my $Filter = ZoneMinder::Filter->find_one(
|
my $Filter = ZoneMinder::Filter->find_one(
|
||||||
($filter_name ? ( Name => $filter_name ) : () ),
|
($filter_name ? ( Name => $filter_name ) : () ),
|
||||||
($filter_id ? ( Id => $filter_id ) : () ),
|
($filter_id ? ( Id => $filter_name ) : () ),
|
||||||
);
|
);
|
||||||
if ( ! $Filter ) {
|
if ( ! $Filter ) {
|
||||||
Fatal("Filter $filter_name $filter_id not found.");
|
Fatal("Filter $filter_name $filter_id not found.");
|
||||||
}
|
}
|
||||||
@event_ids = map { $_->{Id} }$Filter->Execute();
|
@event_ids = map { $_->{Id} } $Filter->Execute();
|
||||||
Fatal( "No events found for $filter_name") if ! @event_ids;
|
if ( ! @event_ids ) {
|
||||||
$concat_name = $filter_name if $concat_name eq '';
|
Fatal( "No events found for $filter_name")
|
||||||
|
} else {
|
||||||
|
Debug(@event_ids . " events found for $filter_name");
|
||||||
|
}
|
||||||
|
$concat_name = $filter_name if ! $concat_name;
|
||||||
|
} else {
|
||||||
|
Warning("Nothing to do");
|
||||||
}
|
}
|
||||||
|
|
||||||
my $sql = " SELECT (SELECT max(Delta) FROM Frames WHERE EventId=Events.Id)-(SELECT min(Delta) FROM Frames WHERE EventId=Events.Id) as FullLength,
|
my $sql = " SELECT (SELECT max(Delta) FROM Frames WHERE EventId=Events.Id)-(SELECT min(Delta) FROM Frames WHERE EventId=Events.Id) as FullLength,
|
||||||
|
@ -219,7 +211,6 @@ Debug($sql);
|
||||||
|
|
||||||
my @video_files;
|
my @video_files;
|
||||||
foreach my $event_id ( @event_ids ) {
|
foreach my $event_id ( @event_ids ) {
|
||||||
|
|
||||||
my $res = $sth->execute( $event_id )
|
my $res = $sth->execute( $event_id )
|
||||||
or Fatal( "Can't execute: ".$sth->errstr() );
|
or Fatal( "Can't execute: ".$sth->errstr() );
|
||||||
my $event = $sth->fetchrow_hashref();
|
my $event = $sth->fetchrow_hashref();
|
||||||
|
@ -227,9 +218,10 @@ foreach my $event_id ( @event_ids ) {
|
||||||
my $Event = new ZoneMinder::Event( $$event{Id}, $event );
|
my $Event = new ZoneMinder::Event( $$event{Id}, $event );
|
||||||
my $video_file = $Event->GenerateVideo( $rate, $fps, $scale, $size, $overwrite, $format );
|
my $video_file = $Event->GenerateVideo( $rate, $fps, $scale, $size, $overwrite, $format );
|
||||||
if ( $video_file ) {
|
if ( $video_file ) {
|
||||||
Debug("Generated $video_file");
|
|
||||||
push @video_files, $video_file;
|
push @video_files, $video_file;
|
||||||
print( STDOUT $video_file."\n" );
|
print( STDOUT $video_file."\n" );
|
||||||
|
} else {
|
||||||
|
Warning("No video file generated for event $event_id");
|
||||||
}
|
}
|
||||||
} # end foreach event_id
|
} # end foreach event_id
|
||||||
|
|
||||||
|
@ -248,7 +240,7 @@ if ( $concat_name ) {
|
||||||
close $fd;
|
close $fd;
|
||||||
my $command = $Config{ZM_PATH_FFMPEG}
|
my $command = $Config{ZM_PATH_FFMPEG}
|
||||||
. " -f concat -i $concat_list_file -c copy "
|
. " -f concat -i $concat_list_file -c copy "
|
||||||
.$Config{ZM_FFMPEG_OUTPUT_OPTIONS}
|
.$Config{ZM_FFMPEG_OUTPUT_OPTIONS}
|
||||||
." '$video_file' > $Config{ZM_PATH_LOGS}/ffmpeg_${concat_name}.log 2>&1"
|
." '$video_file' > $Config{ZM_PATH_LOGS}/ffmpeg_${concat_name}.log 2>&1"
|
||||||
;
|
;
|
||||||
Debug( $command."\n" );
|
Debug( $command."\n" );
|
||||||
|
@ -264,3 +256,5 @@ if ( $concat_name ) {
|
||||||
print( STDOUT $video_file."\n" );
|
print( STDOUT $video_file."\n" );
|
||||||
}
|
}
|
||||||
exit( 0 );
|
exit( 0 );
|
||||||
|
|
||||||
|
__END__
|
||||||
|
|
|
@ -32,8 +32,8 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
/* Workaround for GNU/kFreeBSD */
|
/* Workaround for GNU/kFreeBSD and FreeBSD */
|
||||||
#if defined(__FreeBSD_kernel__)
|
#if defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
|
||||||
#ifndef ENODATA
|
#ifndef ENODATA
|
||||||
#define ENODATA ENOATTR
|
#define ENODATA ENOATTR
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -24,6 +24,10 @@ extern "C" {
|
||||||
#include <libavformat/avformat.h>
|
#include <libavformat/avformat.h>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
#include <sys/time.h>
|
||||||
|
#endif // __FreeBSD__
|
||||||
|
|
||||||
class ZMPacket {
|
class ZMPacket {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -63,13 +63,13 @@ RETSIGTYPE zm_die_handler(int signal)
|
||||||
ucontext_t *uc = (ucontext_t *) context;
|
ucontext_t *uc = (ucontext_t *) context;
|
||||||
cr2 = info->si_addr;
|
cr2 = info->si_addr;
|
||||||
#if defined(__x86_64__)
|
#if defined(__x86_64__)
|
||||||
#ifdef __FreeBSD_kernel__
|
#if defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
|
||||||
ip = (void *)(uc->uc_mcontext.mc_rip);
|
ip = (void *)(uc->uc_mcontext.mc_rip);
|
||||||
#else
|
#else
|
||||||
ip = (void *)(uc->uc_mcontext.gregs[REG_RIP]);
|
ip = (void *)(uc->uc_mcontext.gregs[REG_RIP]);
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#ifdef __FreeBSD_kernel__
|
#if defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
|
||||||
ip = (void *)(uc->uc_mcontext.mc_eip);
|
ip = (void *)(uc->uc_mcontext.mc_eip);
|
||||||
#else
|
#else
|
||||||
ip = (void *)(uc->uc_mcontext.gregs[REG_EIP]);
|
ip = (void *)(uc->uc_mcontext.gregs[REG_EIP]);
|
||||||
|
|
803
src/zm_video.cpp
803
src/zm_video.cpp
|
@ -1,3 +1,4 @@
|
||||||
|
// Copyright (C) 2001-2017 ZoneMinder LLC
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License
|
// modify it under the terms of the GNU General Public License
|
||||||
// as published by the Free Software Foundation; either version 2
|
// as published by the Free Software Foundation; either version 2
|
||||||
|
@ -18,505 +19,559 @@
|
||||||
#include "zm_utils.h"
|
#include "zm_utils.h"
|
||||||
#include "zm_rgb.h"
|
#include "zm_rgb.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
VideoWriter::VideoWriter(const char* p_container, const char* p_codec, const char* p_path, const unsigned int p_width, const unsigned int p_height, const unsigned int p_colours, const unsigned int p_subpixelorder) :
|
VideoWriter::VideoWriter(
|
||||||
container(p_container), codec(p_codec), path(p_path), width(p_width), height(p_height), colours(p_colours), subpixelorder(p_subpixelorder), frame_count(0) {
|
const char* p_container,
|
||||||
Debug(7,"Video object created");
|
const char* p_codec,
|
||||||
|
const char* p_path,
|
||||||
/* Parameter checking */
|
const unsigned int p_width,
|
||||||
if(path.empty()) {
|
const unsigned int p_height,
|
||||||
Error("Invalid file path");
|
const unsigned int p_colours,
|
||||||
}
|
const unsigned int p_subpixelorder) :
|
||||||
if(!width || !height) {
|
container(p_container),
|
||||||
Error("Invalid width or height");
|
codec(p_codec),
|
||||||
}
|
path(p_path),
|
||||||
|
width(p_width),
|
||||||
|
height(p_height),
|
||||||
|
colours(p_colours),
|
||||||
|
subpixelorder(p_subpixelorder),
|
||||||
|
frame_count(0) {
|
||||||
|
Debug(7, "Video object created");
|
||||||
|
|
||||||
|
/* Parameter checking */
|
||||||
|
if ( path.empty() ) {
|
||||||
|
Error("Invalid file path");
|
||||||
|
}
|
||||||
|
if ( !width || !height ) {
|
||||||
|
Error("Invalid width or height");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoWriter::~VideoWriter() {
|
VideoWriter::~VideoWriter() {
|
||||||
Debug(7,"Video object destroyed");
|
Debug(7, "Video object destroyed");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int VideoWriter::Reset(const char* new_path) {
|
int VideoWriter::Reset(const char* new_path) {
|
||||||
/* Common variables reset */
|
/* Common variables reset */
|
||||||
|
|
||||||
/* If there is a new path, use it */
|
/* If there is a new path, use it */
|
||||||
if(new_path != NULL) {
|
if ( new_path != NULL ) {
|
||||||
path = new_path;
|
path = new_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reset frame counter */
|
/* Reset frame counter */
|
||||||
frame_count = 0;
|
frame_count = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if ZM_HAVE_VIDEOWRITER_X264MP4
|
#if ZM_HAVE_VIDEOWRITER_X264MP4
|
||||||
X264MP4Writer::X264MP4Writer(const char* p_path, const unsigned int p_width, const unsigned int p_height, const unsigned int p_colours, const unsigned int p_subpixelorder, const std::vector<EncoderParameter_t>* p_user_params) : VideoWriter("mp4", "h264", p_path, p_width, p_height, p_colours, p_subpixelorder), bOpen(false), bGotH264AVCInfo(false), bFirstFrame(true) {
|
X264MP4Writer::X264MP4Writer(
|
||||||
|
const char* p_path,
|
||||||
|
const unsigned int p_width,
|
||||||
|
const unsigned int p_height,
|
||||||
|
const unsigned int p_colours,
|
||||||
|
const unsigned int p_subpixelorder,
|
||||||
|
const std::vector<EncoderParameter_t>* p_user_params) :
|
||||||
|
VideoWriter(
|
||||||
|
"mp4",
|
||||||
|
"h264",
|
||||||
|
p_path,
|
||||||
|
p_width,
|
||||||
|
p_height,
|
||||||
|
p_colours,
|
||||||
|
p_subpixelorder),
|
||||||
|
bOpen(false),
|
||||||
|
bGotH264AVCInfo(false),
|
||||||
|
bFirstFrame(true) {
|
||||||
|
/* Initialize ffmpeg if it hasn't been initialized yet */
|
||||||
|
FFMPEGInit();
|
||||||
|
|
||||||
/* Initialize ffmpeg if it hasn't been initialized yet */
|
/* Initialize swscale */
|
||||||
FFMPEGInit();
|
zm_pf = GetFFMPEGPixelFormat(colours, subpixelorder);
|
||||||
|
if ( zm_pf == 0 ) {
|
||||||
|
Error("Unable to match ffmpeg pixelformat");
|
||||||
|
}
|
||||||
|
codec_pf = AV_PIX_FMT_YUV420P;
|
||||||
|
|
||||||
/* Initialize swscale */
|
swscaleobj.SetDefaults(zm_pf, codec_pf, width, height);
|
||||||
zm_pf = GetFFMPEGPixelFormat(colours,subpixelorder);
|
|
||||||
if(zm_pf == 0) {
|
|
||||||
Error("Unable to match ffmpeg pixelformat");
|
|
||||||
}
|
|
||||||
codec_pf = AV_PIX_FMT_YUV420P;
|
|
||||||
|
|
||||||
swscaleobj.SetDefaults(zm_pf, codec_pf, width, height);
|
/* Calculate the image sizes. We will need this for parameter checking */
|
||||||
|
zm_imgsize = colours * width * height;
|
||||||
/* Calculate the image sizes. We will need this for parameter checking */
|
|
||||||
zm_imgsize = colours * width * height;
|
|
||||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||||
codec_imgsize = av_image_get_buffer_size( codec_pf, width, height, 1 );
|
codec_imgsize = av_image_get_buffer_size(codec_pf, width, height, 1);
|
||||||
#else
|
#else
|
||||||
codec_imgsize = avpicture_get_size( codec_pf, width, height);
|
codec_imgsize = avpicture_get_size(codec_pf, width, height);
|
||||||
#endif
|
#endif
|
||||||
if(!codec_imgsize) {
|
if ( !codec_imgsize ) {
|
||||||
Error("Failed calculating codec pixel format image size");
|
Error("Failed calculating codec pixel format image size");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If supplied with user parameters to the encoder, copy them */
|
/* If supplied with user parameters to the encoder, copy them */
|
||||||
if(p_user_params != NULL) {
|
if ( p_user_params != NULL ) {
|
||||||
user_params = *p_user_params;
|
user_params = *p_user_params;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup x264 parameters */
|
/* Setup x264 parameters */
|
||||||
if(x264config() < 0) {
|
if ( x264config() < 0 ) {
|
||||||
Error("Failed setting x264 parameters");
|
Error("Failed setting x264 parameters");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate x264 input picture */
|
|
||||||
x264_picture_alloc(&x264picin, X264_CSP_I420, x264params.i_width, x264params.i_height);
|
|
||||||
|
|
||||||
|
/* Allocate x264 input picture */
|
||||||
|
x264_picture_alloc(
|
||||||
|
&x264picin,
|
||||||
|
X264_CSP_I420,
|
||||||
|
x264params.i_width,
|
||||||
|
x264params.i_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
X264MP4Writer::~X264MP4Writer() {
|
X264MP4Writer::~X264MP4Writer() {
|
||||||
|
/* Free x264 input picture */
|
||||||
|
x264_picture_clean(&x264picin);
|
||||||
|
|
||||||
/* Free x264 input picture */
|
if ( bOpen )
|
||||||
x264_picture_clean(&x264picin);
|
Close();
|
||||||
|
|
||||||
if(bOpen)
|
|
||||||
Close();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int X264MP4Writer::Open() {
|
int X264MP4Writer::Open() {
|
||||||
|
/* Open the encoder */
|
||||||
|
x264enc = x264_encoder_open(&x264params);
|
||||||
|
if ( x264enc == NULL ) {
|
||||||
|
Error("Failed opening x264 encoder");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Open the encoder */
|
// Debug(4,"x264 maximum delayed frames: %d",
|
||||||
x264enc = x264_encoder_open(&x264params);
|
// x264_encoder_maximum_delayed_frames(x264enc));
|
||||||
if(x264enc == NULL) {
|
|
||||||
Error("Failed opening x264 encoder");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Debug(4,"x264 maximum delayed frames: %d",x264_encoder_maximum_delayed_frames(x264enc));
|
x264_nal_t* nals;
|
||||||
|
int i_nals;
|
||||||
|
if ( !x264_encoder_headers(x264enc, &nals, &i_nals) ) {
|
||||||
|
Error("Failed getting encoder headers");
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
x264_nal_t* nals;
|
/* Search SPS NAL for AVC information */
|
||||||
int i_nals;
|
for ( unsigned int i = 0; i < i_nals; i++ ) {
|
||||||
if(!x264_encoder_headers(x264enc,&nals,&i_nals)) {
|
if ( nals[i].i_type == NAL_SPS ) {
|
||||||
Error("Failed getting encoder headers");
|
x264_profleindication = nals[i].p_payload[5];
|
||||||
return -2;
|
x264_profilecompat = nals[i].p_payload[6];
|
||||||
}
|
x264_levelindication = nals[i].p_payload[7];
|
||||||
|
bGotH264AVCInfo = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( !bGotH264AVCInfo ) {
|
||||||
|
Warning("Missing AVC information");
|
||||||
|
}
|
||||||
|
|
||||||
/* Search SPS NAL for AVC information */
|
/* Create the file */
|
||||||
for(int i=0;i<i_nals;i++) {
|
mp4h = MP4Create((path + ".incomplete").c_str());
|
||||||
if(nals[i].i_type == NAL_SPS) {
|
if ( mp4h == MP4_INVALID_FILE_HANDLE ) {
|
||||||
x264_profleindication = nals[i].p_payload[5];
|
Error("Failed creating mp4 file: %s", path.c_str());
|
||||||
x264_profilecompat = nals[i].p_payload[6];
|
return -10;
|
||||||
x264_levelindication = nals[i].p_payload[7];
|
}
|
||||||
bGotH264AVCInfo = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!bGotH264AVCInfo) {
|
|
||||||
Warning("Missing AVC information");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create the file */
|
/* Set the global timescale */
|
||||||
mp4h = MP4Create((path + ".incomplete").c_str());
|
if ( !MP4SetTimeScale(mp4h, 1000) ) {
|
||||||
if(mp4h == MP4_INVALID_FILE_HANDLE) {
|
Error("Failed setting timescale");
|
||||||
Error("Failed creating mp4 file: %s",path.c_str());
|
return -11;
|
||||||
return -10;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the global timescale */
|
/* Set the global video profile */
|
||||||
if(!MP4SetTimeScale(mp4h, 1000)) {
|
/* I am a bit confused about this one.
|
||||||
Error("Failed setting timescale");
|
I couldn't find what the value should be
|
||||||
return -11;
|
Some use 0x15 while others use 0x7f. */
|
||||||
}
|
MP4SetVideoProfileLevel(mp4h, 0x7f);
|
||||||
|
|
||||||
/* Set the global video profile */
|
/* Add H264 video track */
|
||||||
/* I am a bit confused about this one.
|
mp4vtid = MP4AddH264VideoTrack(
|
||||||
I couldn't find what the value should be
|
mp4h,
|
||||||
Some use 0x15 while others use 0x7f. */
|
1000,
|
||||||
MP4SetVideoProfileLevel(mp4h, 0x7f);
|
MP4_INVALID_DURATION,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
x264_profleindication,
|
||||||
|
x264_profilecompat,
|
||||||
|
x264_levelindication,
|
||||||
|
3);
|
||||||
|
if ( mp4vtid == MP4_INVALID_TRACK_ID ) {
|
||||||
|
Error("Failed adding H264 video track");
|
||||||
|
return -12;
|
||||||
|
}
|
||||||
|
|
||||||
/* Add H264 video track */
|
bOpen = true;
|
||||||
mp4vtid = MP4AddH264VideoTrack(mp4h,1000,MP4_INVALID_DURATION,width,height,x264_profleindication,x264_profilecompat,x264_levelindication,3);
|
|
||||||
if(mp4vtid == MP4_INVALID_TRACK_ID) {
|
|
||||||
Error("Failed adding H264 video track");
|
|
||||||
return -12;
|
|
||||||
}
|
|
||||||
|
|
||||||
bOpen = true;
|
return 0;
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int X264MP4Writer::Close() {
|
int X264MP4Writer::Close() {
|
||||||
|
/* Flush all pending frames */
|
||||||
|
for ( int i = (x264_encoder_delayed_frames(x264enc) + 1); i > 0; i-- ) {
|
||||||
|
x264encodeloop(true);
|
||||||
|
}
|
||||||
|
|
||||||
/* Flush all pending frames */
|
/* Close the encoder */
|
||||||
for(int i = (x264_encoder_delayed_frames(x264enc) + 1); i > 0; i-- ) {
|
x264_encoder_close(x264enc);
|
||||||
x264encodeloop(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Close the encoder */
|
/* Close MP4 handle */
|
||||||
x264_encoder_close(x264enc);
|
MP4Close(mp4h);
|
||||||
|
|
||||||
/* Close MP4 handle */
|
/* Required for proper HTTP streaming */
|
||||||
MP4Close(mp4h);
|
MP4Optimize((path + ".incomplete").c_str(), path.c_str());
|
||||||
|
|
||||||
/* Required for proper HTTP streaming */
|
/* Delete the temporary file */
|
||||||
MP4Optimize((path + ".incomplete").c_str(), path.c_str());
|
unlink((path + ".incomplete").c_str());
|
||||||
|
|
||||||
/* Delete the temporary file */
|
bOpen = false;
|
||||||
unlink((path + ".incomplete").c_str());
|
|
||||||
|
|
||||||
bOpen = false;
|
Debug(7, "Video closed. Total frames: %d", frame_count);
|
||||||
|
|
||||||
Debug(7, "Video closed. Total frames: %d", frame_count);
|
return 0;
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int X264MP4Writer::Reset(const char* new_path) {
|
int X264MP4Writer::Reset(const char* new_path) {
|
||||||
|
/* Close the encoder and file */
|
||||||
|
if ( bOpen )
|
||||||
|
Close();
|
||||||
|
|
||||||
/* Close the encoder and file */
|
/* Reset common variables */
|
||||||
if(bOpen)
|
VideoWriter::Reset(new_path);
|
||||||
Close();
|
|
||||||
|
|
||||||
/* Reset common variables */
|
/* Reset local variables */
|
||||||
VideoWriter::Reset(new_path);
|
bFirstFrame = true;
|
||||||
|
bGotH264AVCInfo = false;
|
||||||
|
prevnals.clear();
|
||||||
|
prevpayload.clear();
|
||||||
|
|
||||||
/* Reset local variables */
|
/* Reset x264 parameters */
|
||||||
bFirstFrame = true;
|
x264config();
|
||||||
bGotH264AVCInfo = false;
|
|
||||||
prevnals.clear();
|
|
||||||
prevpayload.clear();
|
|
||||||
|
|
||||||
/* Reset x264 parameters */
|
/* Open the encoder */
|
||||||
x264config();
|
Open();
|
||||||
|
|
||||||
/* Open the encoder */
|
return 0;
|
||||||
Open();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int X264MP4Writer::Encode(const uint8_t* data, const size_t data_size, const unsigned int frame_time) {
|
int X264MP4Writer::Encode(
|
||||||
|
const uint8_t* data,
|
||||||
|
const size_t data_size,
|
||||||
|
const unsigned int frame_time) {
|
||||||
|
/* Parameter checking */
|
||||||
|
if ( data == NULL ) {
|
||||||
|
Error("NULL buffer");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Parameter checking */
|
if ( data_size != zm_imgsize ) {
|
||||||
if(data == NULL) {
|
Error("The data buffer size (%d) != expected (%d)", data_size, zm_imgsize);
|
||||||
Error("NULL buffer");
|
return -2;
|
||||||
return -1;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(data_size != zm_imgsize) {
|
if ( !bOpen ) {
|
||||||
Error("The data buffer size does not match the expected size. Expected: %d Current: %d", zm_imgsize, data_size);
|
Warning("The encoder was not initialized, initializing now");
|
||||||
return -2;
|
Open();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!bOpen) {
|
/* Convert the image into the x264 input picture */
|
||||||
Warning("The encoder was not initialized, initializing now");
|
if ( swscaleobj.ConvertDefaults(data, data_size, x264picin.img.plane[0], codec_imgsize) < 0 ) {
|
||||||
Open();
|
Error("Image conversion failed");
|
||||||
}
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
/* Convert the image into the x264 input picture */
|
/* Set PTS */
|
||||||
if(swscaleobj.ConvertDefaults(data, data_size, x264picin.img.plane[0], codec_imgsize) < 0) {
|
x264picin.i_pts = frame_time;
|
||||||
Error("Image conversion failed");
|
|
||||||
return -3;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set PTS */
|
/* Do the encoding */
|
||||||
x264picin.i_pts = frame_time;
|
x264encodeloop();
|
||||||
|
|
||||||
/* Do the encoding */
|
/* Increment frame counter */
|
||||||
x264encodeloop();
|
frame_count++;
|
||||||
|
|
||||||
/* Increment frame counter */
|
return 0;
|
||||||
frame_count++;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int X264MP4Writer::Encode(const Image* img, const unsigned int frame_time) {
|
int X264MP4Writer::Encode(const Image* img, const unsigned int frame_time) {
|
||||||
|
if ( img->Width() != width ) {
|
||||||
|
Error("Source image width differs. Source: %d Output: %d", img->Width(), width);
|
||||||
|
return -12;
|
||||||
|
}
|
||||||
|
|
||||||
if(img->Width() != width) {
|
if ( img->Height() != height ) {
|
||||||
Error("Source image width differs. Source: %d Output: %d",img->Width(), width);
|
Error("Source image height differs. Source: %d Output: %d", img->Height(), height);
|
||||||
return -12;
|
return -13;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(img->Height() != height) {
|
return Encode(img->Buffer(), img->Size(), frame_time);
|
||||||
Error("Source image height differs. Source: %d Output: %d",img->Height(), height);
|
|
||||||
return -13;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Encode(img->Buffer(),img->Size(),frame_time);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int X264MP4Writer::x264config() {
|
int X264MP4Writer::x264config() {
|
||||||
/* Sets up the encoder configuration */
|
/* Sets up the encoder configuration */
|
||||||
|
|
||||||
int x264ret;
|
int x264ret;
|
||||||
|
|
||||||
/* Defaults */
|
/* Defaults */
|
||||||
const char* preset = "veryfast";
|
const char* preset = "veryfast";
|
||||||
const char* tune = "stillimage";
|
const char* tune = "stillimage";
|
||||||
const char* profile = "main";
|
const char* profile = "main";
|
||||||
|
|
||||||
/* Search the user parameters for preset, tune and profile */
|
/* Search the user parameters for preset, tune and profile */
|
||||||
for(unsigned int i=0; i < user_params.size(); i++) {
|
for ( unsigned int i = 0; i < user_params.size(); i++ ) {
|
||||||
if(strcmp(user_params[i].pname, "preset") == 0) {
|
if ( strcmp(user_params[i].pname, "preset") == 0 ) {
|
||||||
/* Got preset */
|
/* Got preset */
|
||||||
preset = user_params[i].pvalue;
|
preset = user_params[i].pvalue;
|
||||||
} else if(strcmp(user_params[i].pname, "tune") == 0) {
|
} else if ( strcmp(user_params[i].pname, "tune") == 0 ) {
|
||||||
/* Got tune */
|
/* Got tune */
|
||||||
tune = user_params[i].pvalue;
|
tune = user_params[i].pvalue;
|
||||||
} else if(strcmp(user_params[i].pname, "profile") == 0) {
|
} else if ( strcmp(user_params[i].pname, "profile") == 0 ) {
|
||||||
/* Got profile */
|
/* Got profile */
|
||||||
profile = user_params[i].pvalue;
|
profile = user_params[i].pvalue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the defaults and preset and tune */
|
/* Set the defaults and preset and tune */
|
||||||
x264ret = x264_param_default_preset(&x264params, preset, tune);
|
x264ret = x264_param_default_preset(&x264params, preset, tune);
|
||||||
if(x264ret != 0) {
|
if ( x264ret != 0 ) {
|
||||||
Error("Failed setting x264 preset %s and tune %s : %d",preset,tune,x264ret);
|
Error("Failed setting x264 preset %s and tune %s : %d", preset, tune, x264ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the profile */
|
/* Set the profile */
|
||||||
x264ret = x264_param_apply_profile(&x264params, profile);
|
x264ret = x264_param_apply_profile(&x264params, profile);
|
||||||
if(x264ret != 0) {
|
if ( x264ret != 0 ) {
|
||||||
Error("Failed setting x264 profile %s : %d",profile,x264ret);
|
Error("Failed setting x264 profile %s : %d", profile, x264ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Input format */
|
/* Input format */
|
||||||
x264params.i_width = width;
|
x264params.i_width = width;
|
||||||
x264params.i_height = height;
|
x264params.i_height = height;
|
||||||
x264params.i_csp = X264_CSP_I420;
|
x264params.i_csp = X264_CSP_I420;
|
||||||
|
|
||||||
/* Quality control */
|
/* Quality control */
|
||||||
x264params.rc.i_rc_method = X264_RC_CRF;
|
x264params.rc.i_rc_method = X264_RC_CRF;
|
||||||
x264params.rc.f_rf_constant = 23.0;
|
x264params.rc.f_rf_constant = 23.0;
|
||||||
|
|
||||||
/* Enable b-frames */
|
/* Enable b-frames */
|
||||||
x264params.i_bframe = 16;
|
x264params.i_bframe = 16;
|
||||||
x264params.i_bframe_adaptive = 1;
|
x264params.i_bframe_adaptive = 1;
|
||||||
|
|
||||||
/* Timebase */
|
/* Timebase */
|
||||||
x264params.i_timebase_num = 1;
|
x264params.i_timebase_num = 1;
|
||||||
x264params.i_timebase_den = 1000;
|
x264params.i_timebase_den = 1000;
|
||||||
|
|
||||||
/* Enable variable frame rate */
|
/* Enable variable frame rate */
|
||||||
x264params.b_vfr_input = 1;
|
x264params.b_vfr_input = 1;
|
||||||
|
|
||||||
/* Disable annex-b (start codes) */
|
/* Disable annex-b (start codes) */
|
||||||
x264params.b_annexb = 0;
|
x264params.b_annexb = 0;
|
||||||
|
|
||||||
/* TODO: Setup error handler */
|
/* TODO: Setup error handler */
|
||||||
//x264params.i_log_level = X264_LOG_DEBUG;
|
// x264params.i_log_level = X264_LOG_DEBUG;
|
||||||
|
|
||||||
/* Process user parameters (excluding preset, tune and profile) */
|
/* Process user parameters (excluding preset, tune and profile) */
|
||||||
for(unsigned int i=0; i < user_params.size(); i++) {
|
for ( unsigned int i = 0; i < user_params.size(); i++ ) {
|
||||||
/* Skip preset, tune and profile */
|
/* Skip preset, tune and profile */
|
||||||
if( (strcmp(user_params[i].pname, "preset") == 0) || (strcmp(user_params[i].pname, "tune") == 0) || (strcmp(user_params[i].pname, "profile") == 0) ) {
|
if (
|
||||||
continue;
|
(strcmp(user_params[i].pname, "preset") == 0) ||
|
||||||
}
|
(strcmp(user_params[i].pname, "tune") == 0) ||
|
||||||
|
(strcmp(user_params[i].pname, "profile") == 0) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* Pass the name and value to x264 */
|
/* Pass the name and value to x264 */
|
||||||
x264ret = x264_param_parse(&x264params, user_params[i].pname, user_params[i].pvalue);
|
x264ret = x264_param_parse(&x264params, user_params[i].pname, user_params[i].pvalue);
|
||||||
|
|
||||||
/* Error checking */
|
/* Error checking */
|
||||||
if(x264ret != 0) {
|
if ( x264ret != 0 ) {
|
||||||
if(x264ret == X264_PARAM_BAD_NAME) {
|
if ( x264ret == X264_PARAM_BAD_NAME ) {
|
||||||
Error("Failed processing x264 user parameter %s=%s : Bad name", user_params[i].pname, user_params[i].pvalue);
|
Error("Failed processing x264 user parameter %s=%s : Bad name",
|
||||||
} else if(x264ret == X264_PARAM_BAD_VALUE) {
|
user_params[i].pname, user_params[i].pvalue);
|
||||||
Error("Failed processing x264 user parameter %s=%s : Bad value", user_params[i].pname, user_params[i].pvalue);
|
} else if ( x264ret == X264_PARAM_BAD_VALUE ) {
|
||||||
} else {
|
Error("Failed processing x264 user parameter %s=%s : Bad value",
|
||||||
Error("Failed processing x264 user parameter %s=%s : Unknown error (%d)", user_params[i].pname, user_params[i].pvalue, x264ret);
|
user_params[i].pname, user_params[i].pvalue);
|
||||||
}
|
} else {
|
||||||
}
|
Error("Failed processing x264 user parameter %s=%s : Unknown error (%d)",
|
||||||
}
|
user_params[i].pname, user_params[i].pvalue, x264ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void X264MP4Writer::x264encodeloop(bool bFlush) {
|
void X264MP4Writer::x264encodeloop(bool bFlush) {
|
||||||
|
x264_nal_t* nals;
|
||||||
|
int i_nals;
|
||||||
|
int frame_size;
|
||||||
|
|
||||||
x264_nal_t* nals;
|
if ( bFlush ) {
|
||||||
int i_nals;
|
frame_size = x264_encoder_encode(x264enc, &nals, &i_nals, NULL, &x264picout);
|
||||||
int frame_size;
|
} else {
|
||||||
|
frame_size = x264_encoder_encode(x264enc, &nals, &i_nals, &x264picin, &x264picout);
|
||||||
|
}
|
||||||
|
|
||||||
if(bFlush) {
|
if ( frame_size > 0 || bFlush ) {
|
||||||
frame_size = x264_encoder_encode(x264enc, &nals, &i_nals, NULL, &x264picout);
|
Debug(8, "x264 Frame: %d PTS: %d DTS: %d Size: %d\n",
|
||||||
} else {
|
frame_count, x264picout.i_pts, x264picout.i_dts, frame_size);
|
||||||
frame_size = x264_encoder_encode(x264enc, &nals, &i_nals, &x264picin, &x264picout);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (frame_size > 0 || bFlush) {
|
/* Handle the previous frame */
|
||||||
Debug(8, "x264 Frame: %d PTS: %d DTS: %d Size: %d\n",frame_count, x264picout.i_pts, x264picout.i_dts, frame_size);
|
if ( !bFirstFrame ) {
|
||||||
|
buffer.clear();
|
||||||
|
|
||||||
/* Handle the previous frame */
|
/* Process the NALs for the previous frame */
|
||||||
if(!bFirstFrame) {
|
for ( unsigned int i = 0; i < prevnals.size(); i++ ) {
|
||||||
|
Debug(9, "Processing NAL: Type %d Size %d",
|
||||||
|
prevnals[i].i_type,
|
||||||
|
prevnals[i].i_payload);
|
||||||
|
|
||||||
buffer.clear();
|
switch ( prevnals[i].i_type ) {
|
||||||
|
case NAL_PPS:
|
||||||
|
/* PPS NAL */
|
||||||
|
MP4AddH264PictureParameterSet(mp4h, mp4vtid, prevnals[i].p_payload+4, prevnals[i].i_payload-4);
|
||||||
|
break;
|
||||||
|
case NAL_SPS:
|
||||||
|
/* SPS NAL */
|
||||||
|
MP4AddH264SequenceParameterSet(mp4h, mp4vtid, prevnals[i].p_payload+4, prevnals[i].i_payload-4);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Anything else, hopefully frames, so copy it into the sample */
|
||||||
|
buffer.append(prevnals[i].p_payload, prevnals[i].i_payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Process the NALs for the previous frame */
|
/* Calculate frame duration and offset */
|
||||||
for(unsigned int i=0; i < prevnals.size(); i++) {
|
int duration = x264picout.i_dts - prevDTS;
|
||||||
Debug(9,"Processing NAL: Type %d Size %d",prevnals[i].i_type,prevnals[i].i_payload);
|
int offset = prevPTS - prevDTS;
|
||||||
|
|
||||||
switch(prevnals[i].i_type) {
|
/* Write the sample */
|
||||||
case NAL_PPS:
|
if ( !buffer.empty() ) {
|
||||||
/* PPS NAL */
|
if ( !MP4WriteSample(
|
||||||
MP4AddH264PictureParameterSet(mp4h, mp4vtid, prevnals[i].p_payload+4, prevnals[i].i_payload-4);
|
mp4h,
|
||||||
break;
|
mp4vtid,
|
||||||
case NAL_SPS:
|
buffer.extract(buffer.size()),
|
||||||
/* SPS NAL */
|
buffer.size(),
|
||||||
MP4AddH264SequenceParameterSet(mp4h, mp4vtid, prevnals[i].p_payload+4, prevnals[i].i_payload-4);
|
duration,
|
||||||
break;
|
offset,
|
||||||
default:
|
prevKeyframe) ) {
|
||||||
/* Anything else, hopefully frames, so copy it into the sample */
|
Error("Failed writing sample");
|
||||||
buffer.append(prevnals[i].p_payload, prevnals[i].i_payload);
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Calculate frame duration and offset */
|
/* Cleanup */
|
||||||
int duration = x264picout.i_dts - prevDTS;
|
prevnals.clear();
|
||||||
int offset = prevPTS - prevDTS;
|
prevpayload.clear();
|
||||||
|
}
|
||||||
|
|
||||||
/* Write the sample */
|
/* Got a frame. Copy this new frame into the previous frame */
|
||||||
if(!buffer.empty()) {
|
if ( frame_size > 0 ) {
|
||||||
if(!MP4WriteSample(mp4h, mp4vtid, buffer.extract(buffer.size()), buffer.size(), duration, offset, prevKeyframe)) {
|
/* Copy the NALs and the payloads */
|
||||||
Error("Failed writing sample");
|
for ( unsigned int i = 0; i < i_nals; i++ ) {
|
||||||
}
|
prevnals.push_back(nals[i]);
|
||||||
}
|
prevpayload.append(nals[i].p_payload, nals[i].i_payload);
|
||||||
|
}
|
||||||
|
|
||||||
/* Cleanup */
|
/* Update the payload pointers */
|
||||||
prevnals.clear();
|
/* This is done in a separate loop because the previous loop might reallocate memory when appending,
|
||||||
prevpayload.clear();
|
making the pointers invalid */
|
||||||
|
unsigned int payload_offset = 0;
|
||||||
|
for ( unsigned int i = 0; i < prevnals.size(); i++ ) {
|
||||||
|
prevnals[i].p_payload = prevpayload.head() + payload_offset;
|
||||||
|
payload_offset += nals[i].i_payload;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
/* We need this for the next frame */
|
||||||
|
prevPTS = x264picout.i_pts;
|
||||||
|
prevDTS = x264picout.i_dts;
|
||||||
|
prevKeyframe = x264picout.b_keyframe;
|
||||||
|
|
||||||
/* Got a frame. Copy this new frame into the previous frame */
|
bFirstFrame = false;
|
||||||
if(frame_size > 0) {
|
}
|
||||||
/* Copy the NALs and the payloads */
|
|
||||||
for(int i=0;i<i_nals;i++) {
|
|
||||||
|
|
||||||
prevnals.push_back(nals[i]);
|
} else if ( frame_size == 0 ) {
|
||||||
prevpayload.append(nals[i].p_payload, nals[i].i_payload);
|
Debug(7, "x264 encode returned zero. Delayed frames: %d",
|
||||||
}
|
x264_encoder_delayed_frames(x264enc));
|
||||||
|
} else {
|
||||||
/* Update the payload pointers */
|
Error("x264 encode failed: %d", frame_size);
|
||||||
/* This is done in a separate loop because the previous loop might reallocate memory when appending,
|
}
|
||||||
making the pointers invalid */
|
|
||||||
unsigned int payload_offset = 0;
|
|
||||||
for(unsigned int i=0;i<prevnals.size();i++) {
|
|
||||||
prevnals[i].p_payload = prevpayload.head() + payload_offset;
|
|
||||||
payload_offset += nals[i].i_payload;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We need this for the next frame */
|
|
||||||
prevPTS = x264picout.i_pts;
|
|
||||||
prevDTS = x264picout.i_dts;
|
|
||||||
prevKeyframe = x264picout.b_keyframe;
|
|
||||||
|
|
||||||
bFirstFrame = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if(frame_size == 0) {
|
|
||||||
Debug(7,"x264 encode returned zero. Delayed frames: %d",x264_encoder_delayed_frames(x264enc));
|
|
||||||
} else {
|
|
||||||
Error("x264 encode failed: %d",frame_size);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif // ZM_VIDEOWRITER_X264MP4
|
#endif // ZM_VIDEOWRITER_X264MP4
|
||||||
|
|
||||||
int ParseEncoderParameters(const char* str, std::vector<EncoderParameter_t>* vec) {
|
int ParseEncoderParameters(
|
||||||
if(vec == NULL) {
|
const char* str,
|
||||||
Error("NULL Encoder parameters vector pointer");
|
std::vector<EncoderParameter_t>* vec
|
||||||
return -1;
|
) {
|
||||||
}
|
if ( vec == NULL ) {
|
||||||
|
Error("NULL Encoder parameters vector pointer");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if(str == NULL) {
|
if ( str == NULL ) {
|
||||||
Error("NULL Encoder parameters string");
|
Error("NULL Encoder parameters string");
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec->clear();
|
vec->clear();
|
||||||
|
|
||||||
if(str[0] == 0) {
|
if ( str[0] == 0 ) {
|
||||||
/* Empty */
|
/* Empty */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string line;
|
std::string line;
|
||||||
std::stringstream ss(str);
|
std::stringstream ss(str);
|
||||||
size_t valueoffset;
|
size_t valueoffset;
|
||||||
size_t valuelen;
|
size_t valuelen;
|
||||||
unsigned int lineno = 0;
|
unsigned int lineno = 0;
|
||||||
EncoderParameter_t param;
|
EncoderParameter_t param;
|
||||||
|
|
||||||
while(std::getline(ss, line) ) {
|
while ( std::getline(ss, line) ) {
|
||||||
lineno++;
|
lineno++;
|
||||||
|
|
||||||
/* Remove CR if exists */
|
/* Remove CR if exists */
|
||||||
if(line.length() >= 1 && line[line.length()-1] == '\r') {
|
if ( line.length() >= 1 && line[line.length()-1] == '\r' ) {
|
||||||
line.erase(line.length()-1);
|
line.erase(line.length() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Skip comments and empty lines */
|
/* Skip comments and empty lines */
|
||||||
if(line.empty() || line[0] == '#') {
|
if ( line.empty() || line[0] == '#' ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
valueoffset = line.find('=');
|
valueoffset = line.find('=');
|
||||||
if(valueoffset == std::string::npos || valueoffset+1 >= line.length() || valueoffset == 0) {
|
if ( valueoffset == std::string::npos || valueoffset+1 >= line.length() || valueoffset == 0 ) {
|
||||||
Warning("Failed parsing encoder parameters line %d: Invalid pair", lineno);
|
Warning("Failed parsing encoder parameters line %d: Invalid pair", lineno);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( valueoffset > (sizeof(param.pname) - 1 ) ) {
|
||||||
|
Warning("Failed parsing encoder parameters line %d: Name too long", lineno);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if(valueoffset > (sizeof(param.pname)-1) ) {
|
valuelen = line.length() - (valueoffset+1);
|
||||||
Warning("Failed parsing encoder parameters line %d: Name too long", lineno);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
valuelen = line.length() - (valueoffset+1);
|
if ( valuelen > (sizeof(param.pvalue) - 1 ) ) {
|
||||||
|
Warning("Failed parsing encoder parameters line %d: Value too long", lineno);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if( valuelen > (sizeof(param.pvalue)-1) ) {
|
/* Copy and NULL terminate */
|
||||||
Warning("Failed parsing encoder parameters line %d: Value too long", lineno);
|
line.copy(param.pname, valueoffset, 0);
|
||||||
continue;
|
line.copy(param.pvalue, valuelen, valueoffset+1);
|
||||||
}
|
param.pname[valueoffset] = 0;
|
||||||
|
param.pvalue[valuelen] = 0;
|
||||||
|
|
||||||
/* Copy and NULL terminate */
|
/* Push to the vector */
|
||||||
line.copy(param.pname, valueoffset, 0);
|
vec->push_back(param);
|
||||||
line.copy(param.pvalue, valuelen, valueoffset+1);
|
|
||||||
param.pname[valueoffset] = 0;
|
|
||||||
param.pvalue[valuelen] = 0;
|
|
||||||
|
|
||||||
/* Push to the vector */
|
Debug(7, "Parsed encoder parameter: %s = %s", param.pname, param.pvalue);
|
||||||
vec->push_back(param);
|
}
|
||||||
|
|
||||||
Debug(7, "Parsed encoder parameter: %s = %s", param.pname, param.pvalue);
|
Debug(7, "Parsed %d lines", lineno);
|
||||||
}
|
|
||||||
|
|
||||||
Debug(7, "Parsed %d lines", lineno);
|
return 0;
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ if [ "${TRAVIS_EVENT_TYPE}" == "cron" ]; then
|
||||||
|
|
||||||
# Don't keep packages older than 5 days
|
# Don't keep packages older than 5 days
|
||||||
find ./zmrepo/$targetfolder/ -maxdepth 1 -type f -mtime +5 -delete
|
find ./zmrepo/$targetfolder/ -maxdepth 1 -type f -mtime +5 -delete
|
||||||
rsync -vzh --ignore-errors build/* zmrepo/$targetfolder/
|
rsync -vzlh --ignore-errors build/* zmrepo/$targetfolder/
|
||||||
fusermount -zu zmrepo
|
fusermount -zu zmrepo
|
||||||
else
|
else
|
||||||
echo
|
echo
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
class Filter {
|
class Filter {
|
||||||
|
|
||||||
public $defaults = array(
|
public $defaults = array(
|
||||||
'Id' => null,
|
'Id' => null,
|
||||||
'Name' => '',
|
'Name' => '',
|
||||||
'AutoExecute' => 0,
|
'AutoExecute' => 0,
|
||||||
'AutoExecuteCmd' => 0,
|
'AutoExecuteCmd' => 0,
|
||||||
'AutoEmail' => 0,
|
'AutoEmail' => 0,
|
||||||
|
@ -15,7 +15,7 @@ public $defaults = array(
|
||||||
'Background' => 0,
|
'Background' => 0,
|
||||||
'Concurrent' => 0,
|
'Concurrent' => 0,
|
||||||
'limit' => 100,
|
'limit' => 100,
|
||||||
'terms' => array(),
|
'Query' => array(),
|
||||||
'sort_field' => ZM_WEB_EVENT_SORT_FIELD,
|
'sort_field' => ZM_WEB_EVENT_SORT_FIELD,
|
||||||
'sort_asc' => (ZM_WEB_EVENT_SORT_ORDER == 'asc'),
|
'sort_asc' => (ZM_WEB_EVENT_SORT_ORDER == 'asc'),
|
||||||
);
|
);
|
||||||
|
@ -44,6 +44,11 @@ public $defaults = array(
|
||||||
foreach ($row as $k => $v) {
|
foreach ($row as $k => $v) {
|
||||||
$this->{$k} = $v;
|
$this->{$k} = $v;
|
||||||
}
|
}
|
||||||
|
if ( array_key_exists( 'Query', $this ) and $this->{'Query'} ) {
|
||||||
|
$this->{'Query'} = jsonDecode( $this->{'Query'} );
|
||||||
|
} else {
|
||||||
|
$this->{'Query'} = array();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} // end function __construct
|
} // end function __construct
|
||||||
|
|
||||||
|
@ -62,21 +67,33 @@ public $defaults = array(
|
||||||
$line = $backTrace[1]['line'];
|
$line = $backTrace[1]['line'];
|
||||||
Warning( "Unknown function call Filter->$fn from $file:$line" );
|
Warning( "Unknown function call Filter->$fn from $file:$line" );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function terms( ) {
|
public function terms( ) {
|
||||||
if ( func_num_args( ) ) {
|
if ( func_num_args( ) ) {
|
||||||
$this->{'terms'} = func_get_arg(0);
|
$this->{'Query'}['terms'] = func_get_arg(0);
|
||||||
}
|
}
|
||||||
if ( ! isset( $this->{'terms'} ) ) {
|
return $this->{'Query'}['terms'];
|
||||||
if ( array_key_exists( 'Query', $this ) and $this->{'Query'} ) {
|
}
|
||||||
$this->{'terms'} = jsonDecode( $this->{'Query'} );
|
|
||||||
} else {
|
// The following three fields are actually stored in the Query
|
||||||
$this->{'terms'} = array();
|
public function sort_field( ) {
|
||||||
}
|
if ( func_num_args( ) ) {
|
||||||
|
$this->{'Query'}['sort_field'] = func_get_arg(0);
|
||||||
}
|
}
|
||||||
return $this->{'terms'};
|
return $this->{'Query'}['sort_field'];
|
||||||
|
}
|
||||||
|
public function sort_asc( ) {
|
||||||
|
if ( func_num_args( ) ) {
|
||||||
|
$this->{'Query'}['sort_asc'] = func_get_arg(0);
|
||||||
|
}
|
||||||
|
return $this->{'Query'}['sort_asc'];
|
||||||
|
}
|
||||||
|
public function limit( ) {
|
||||||
|
if ( func_num_args( ) ) {
|
||||||
|
$this->{'Query'}['limit'] = func_get_arg(0);
|
||||||
|
}
|
||||||
|
return $this->{'Query'}['limit'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function find_all() {
|
public static function find_all() {
|
||||||
|
|
|
@ -119,6 +119,7 @@ if ( !empty($action) ) {
|
||||||
|
|
||||||
if ( isset( $_REQUEST['object'] ) and ( $_REQUEST['object'] == 'filter' ) ) {
|
if ( isset( $_REQUEST['object'] ) and ( $_REQUEST['object'] == 'filter' ) ) {
|
||||||
if ( $action == 'addterm' ) {
|
if ( $action == 'addterm' ) {
|
||||||
|
Warning("Addterm");
|
||||||
$_REQUEST['filter'] = addFilterTerm( $_REQUEST['filter'], $_REQUEST['line'] );
|
$_REQUEST['filter'] = addFilterTerm( $_REQUEST['filter'], $_REQUEST['line'] );
|
||||||
} elseif ( $action == 'delterm' ) {
|
} elseif ( $action == 'delterm' ) {
|
||||||
$_REQUEST['filter'] = delFilterTerm( $_REQUEST['filter'], $_REQUEST['line'] );
|
$_REQUEST['filter'] = delFilterTerm( $_REQUEST['filter'], $_REQUEST['line'] );
|
||||||
|
@ -130,15 +131,15 @@ if ( !empty($action) ) {
|
||||||
} else if ( ( $action == 'save' ) or ( $action == 'execute' ) or ( $action == 'submit' ) ) {
|
} else if ( ( $action == 'save' ) or ( $action == 'execute' ) or ( $action == 'submit' ) ) {
|
||||||
|
|
||||||
$sql = '';
|
$sql = '';
|
||||||
$_REQUEST['filter']['sort_field'] = validStr($_REQUEST['filter']['sort_field']);
|
$_REQUEST['filter']['Query']['sort_field'] = validStr($_REQUEST['filter']['Query']['sort_field']);
|
||||||
$_REQUEST['filter']['sort_asc'] = validStr($_REQUEST['filter']['sort_asc']);
|
$_REQUEST['filter']['Query']['sort_asc'] = validStr($_REQUEST['filter']['Query']['sort_asc']);
|
||||||
$_REQUEST['filter']['limit'] = validInt($_REQUEST['filter']['limit']);
|
$_REQUEST['filter']['Query']['limit'] = validInt($_REQUEST['filter']['Query']['limit']);
|
||||||
if ( $action == 'execute' or $action == 'submit' ) {
|
if ( $action == 'execute' or $action == 'submit' ) {
|
||||||
$sql .= ' Name = \'_TempFilter'.time().'\'';
|
$sql .= ' Name = \'_TempFilter'.time().'\'';
|
||||||
} else {
|
} else {
|
||||||
$sql .= ' Name = '.dbEscape($_REQUEST['filter']['Name']);
|
$sql .= ' Name = '.dbEscape($_REQUEST['filter']['Name']);
|
||||||
}
|
}
|
||||||
$sql .= ', Query = '.dbEscape(jsonEncode($_REQUEST['filter']['terms']));
|
$sql .= ', Query = '.dbEscape(jsonEncode($_REQUEST['filter']['Query']));
|
||||||
$sql .= ', AutoArchive = '.(!empty($_REQUEST['filter']['AutoArchive']) ? 1 : 0);
|
$sql .= ', AutoArchive = '.(!empty($_REQUEST['filter']['AutoArchive']) ? 1 : 0);
|
||||||
$sql .= ', AutoVideo = '. ( !empty($_REQUEST['filter']['AutoVideo']) ? 1 : 0);
|
$sql .= ', AutoVideo = '. ( !empty($_REQUEST['filter']['AutoVideo']) ? 1 : 0);
|
||||||
$sql .= ', AutoUpload = '. ( !empty($_REQUEST['filter']['AutoUpload']) ? 1 : 0);
|
$sql .= ', AutoUpload = '. ( !empty($_REQUEST['filter']['AutoUpload']) ? 1 : 0);
|
||||||
|
@ -176,6 +177,7 @@ if ( !empty($action) ) {
|
||||||
dbQuery( 'UPDATE Events SET Cause=?, Notes=? WHERE Id=?', array( $_REQUEST['newEvent']['Cause'], $_REQUEST['newEvent']['Notes'], $markEid ) );
|
dbQuery( 'UPDATE Events SET Cause=?, Notes=? WHERE Id=?', array( $_REQUEST['newEvent']['Cause'], $_REQUEST['newEvent']['Notes'], $markEid ) );
|
||||||
$refreshParent = true;
|
$refreshParent = true;
|
||||||
}
|
}
|
||||||
|
$refreshParent = '/index.php?view=filter&Id='.$_REQUEST['Id'];
|
||||||
}
|
}
|
||||||
} elseif ( $action == 'archive' || $action == 'unarchive' ) {
|
} elseif ( $action == 'archive' || $action == 'unarchive' ) {
|
||||||
$archiveVal = ($action == 'archive')?1:0;
|
$archiveVal = ($action == 'archive')?1:0;
|
||||||
|
|
|
@ -379,7 +379,7 @@ function outputHelperStream( $id, $src, $width, $height, $title='' ) {
|
||||||
echo getHelperStream( $id, $src, $width, $height, $title );
|
echo getHelperStream( $id, $src, $width, $height, $title );
|
||||||
}
|
}
|
||||||
function getHelperStream( $id, $src, $width, $height, $title='' ) {
|
function getHelperStream( $id, $src, $width, $height, $title='' ) {
|
||||||
return '<applet id="'.$id.'" code="com.charliemouse.cambozola.Viewer"
|
return '<object type="application/x-java-applet" id="'.$id.'" code="com.charliemouse.cambozola.Viewer"
|
||||||
archive="'. ZM_PATH_CAMBOZOLA .'"
|
archive="'. ZM_PATH_CAMBOZOLA .'"
|
||||||
align="middle"
|
align="middle"
|
||||||
width="'. $width .'"
|
width="'. $width .'"
|
||||||
|
@ -387,14 +387,14 @@ function getHelperStream( $id, $src, $width, $height, $title='' ) {
|
||||||
title="'. $title .'">
|
title="'. $title .'">
|
||||||
<param name="accessories" value="none"/>
|
<param name="accessories" value="none"/>
|
||||||
<param name="url" value="'. $src .'"/>
|
<param name="url" value="'. $src .'"/>
|
||||||
</applet>';
|
</object>';
|
||||||
}
|
}
|
||||||
|
|
||||||
function outputImageStill( $id, $src, $width, $height, $title='' ) {
|
function outputImageStill( $id, $src, $width, $height, $title='' ) {
|
||||||
echo getImageStill( $id, $src, $width, $height, $title='' );
|
echo getImageStill( $id, $src, $width, $height, $title='' );
|
||||||
}
|
}
|
||||||
function getImageStill( $id, $src, $width, $height, $title='' ) {
|
function getImageStill( $id, $src, $width, $height, $title='' ) {
|
||||||
return '<img id="'.$id.'" src="'.$src.'" alt="'.$title.'" width="'.$width.'" height="'.$height.'"/>';
|
return '<img id="'.$id.'" src="'.$src.'" alt="'.$title.'"'.(validInt($width)?' width="'.$width.'"':'').(validInt($height)?' height="'.$height.'"':'').'/>';
|
||||||
}
|
}
|
||||||
|
|
||||||
function outputControlStill( $src, $width, $height, $monitor, $scale, $target ) {
|
function outputControlStill( $src, $width, $height, $monitor, $scale, $target ) {
|
||||||
|
@ -1306,14 +1306,14 @@ function addFilterTerm( $filter, $position, $term=false ) {
|
||||||
if ( $position < 0 )
|
if ( $position < 0 )
|
||||||
$position = 0;
|
$position = 0;
|
||||||
|
|
||||||
if ( ! isset( $filter['terms'] ) )
|
if ( ! isset( $filter['Query']['terms'] ) )
|
||||||
$filter['terms'] = array();
|
$filter['Query']['terms'] = array();
|
||||||
|
|
||||||
elseif( $position > count($filter['terms']) )
|
elseif( $position > count($filter['Query']['terms']) )
|
||||||
$position = count($filter['terms']);
|
$position = count($filter['Query']['terms']);
|
||||||
if ( $term && $position == 0 )
|
if ( $term && $position == 0 )
|
||||||
unset( $term['cnj'] );
|
unset( $term['cnj'] );
|
||||||
array_splice( $filter['terms'], $position, 0, array( $term?$term:array() ) );
|
array_splice( $filter['Query']['terms'], $position, 0, array( $term?$term:array() ) );
|
||||||
|
|
||||||
return( $filter );
|
return( $filter );
|
||||||
}
|
}
|
||||||
|
@ -1321,9 +1321,9 @@ function addFilterTerm( $filter, $position, $term=false ) {
|
||||||
function delFilterTerm( $filter, $position ) {
|
function delFilterTerm( $filter, $position ) {
|
||||||
if ( $position < 0 )
|
if ( $position < 0 )
|
||||||
$position = 0;
|
$position = 0;
|
||||||
elseif( $position >= count($filter['terms']) )
|
elseif( $position >= count($filter['Query']['terms']) )
|
||||||
$position = count($filter['terms']);
|
$position = count($filter['Query']['terms']);
|
||||||
array_splice( $filter['terms'], $position, 1 );
|
array_splice( $filter['Query']['terms'], $position, 1 );
|
||||||
|
|
||||||
return( $filter );
|
return( $filter );
|
||||||
}
|
}
|
||||||
|
@ -2126,9 +2126,24 @@ function validHtmlStr( $input ) {
|
||||||
|
|
||||||
function getStreamHTML( $monitor, $options = array() ) {
|
function getStreamHTML( $monitor, $options = array() ) {
|
||||||
|
|
||||||
if ( isset($options['scale']) and $options['scale'] ) {
|
if ( isset($options['scale']) and $options['scale'] and ( $options['scale'] != 100 ) ) {
|
||||||
$options['width'] = reScale( $monitor->Width(), $options['scale'] );
|
$options['width'] = reScale( $monitor->Width(), $options['scale'] );
|
||||||
$options['height'] = reScale( $monitor->Height(), $options['scale'] );
|
$options['height'] = reScale( $monitor->Height(), $options['scale'] );
|
||||||
|
} else {
|
||||||
|
if ( ! isset( $options['width'] ) ) {
|
||||||
|
if ( $options['width'] == 100 ) {
|
||||||
|
$options['width'] = $monitor->Width();
|
||||||
|
} else {
|
||||||
|
$options['width'] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( ! isset( $options['height'] ) ) {
|
||||||
|
if ( $options['height'] == 100 ) {
|
||||||
|
$options['height'] = $monitor->Height();
|
||||||
|
} else {
|
||||||
|
$options['height'] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ( ! isset($options['mode'] ) ) {
|
if ( ! isset($options['mode'] ) ) {
|
||||||
$options['mode'] = 'stream';
|
$options['mode'] = 'stream';
|
||||||
|
@ -2146,27 +2161,20 @@ function getStreamHTML( $monitor, $options = array() ) {
|
||||||
$streamSrc = $monitor->getStreamSrc( $options );
|
$streamSrc = $monitor->getStreamSrc( $options );
|
||||||
|
|
||||||
if ( canStreamNative() )
|
if ( canStreamNative() )
|
||||||
return getImageStream( 'liveStream'.$monitor->Id(), $streamSrc,
|
return getImageStream( 'liveStream'.$monitor->Id(), $streamSrc, $options['width'], $options['height'], $monitor->Name());
|
||||||
( isset($options['width']) ? $options['width'] : NULL ),
|
|
||||||
( isset($options['height']) ? $options['height'] : NULL ),
|
|
||||||
$monitor->Name()
|
|
||||||
);
|
|
||||||
elseif ( canStreamApplet() )
|
elseif ( canStreamApplet() )
|
||||||
|
// Helper, empty widths and heights really don't work.
|
||||||
return getHelperStream( 'liveStream'.$monitor->Id(), $streamSrc,
|
return getHelperStream( 'liveStream'.$monitor->Id(), $streamSrc,
|
||||||
( isset($options['width']) ? $options['width'] : NULL ),
|
$options['width'] ? $options['width'] : $monitor->Width(),
|
||||||
( isset($options['height']) ? $options['height'] : NULL ),
|
$options['height'] ? $options['height'] : $monitor->Height(),
|
||||||
$monitor->Name()
|
$monitor->Name());
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
$streamSrc = $monitor->getStreamSrc( $options );
|
if ( $options['mode'] == 'stream' ) {
|
||||||
if ( $mode == 'stream' ) {
|
|
||||||
Info( 'The system has fallen back to single jpeg mode for streaming. Consider enabling Cambozola or upgrading the client browser.' );
|
Info( 'The system has fallen back to single jpeg mode for streaming. Consider enabling Cambozola or upgrading the client browser.' );
|
||||||
}
|
}
|
||||||
return getImageStill( 'liveStream'.$monitor->Id(), $streamSrc,
|
$options['mode'] = 'single';
|
||||||
( isset($options['width']) ? $options['width'] : NULL ),
|
$streamSrc = $monitor->getStreamSrc( $options );
|
||||||
( isset($options['height']) ? $options['height'] : NULL ),
|
return getImageStill( 'liveStream'.$monitor->Id(), $streamSrc, $options['width'], $options['height'], $monitor->Name());
|
||||||
$monitor->Name()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} // end function getStreamHTML
|
} // end function getStreamHTML
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,8 @@ $rates = array(
|
||||||
'400' => '4x',
|
'400' => '4x',
|
||||||
'200' => '2x',
|
'200' => '2x',
|
||||||
'100' => translate('Real'),
|
'100' => translate('Real'),
|
||||||
'50' => "1/2x",
|
'50' => '1/2x',
|
||||||
'25' => "1/4x",
|
'25' => '1/4x',
|
||||||
);
|
);
|
||||||
|
|
||||||
$scales = array(
|
$scales = array(
|
||||||
|
@ -35,13 +35,13 @@ $scales = array(
|
||||||
'400' => '4x',
|
'400' => '4x',
|
||||||
'300' => '3x',
|
'300' => '3x',
|
||||||
'200' => '2x',
|
'200' => '2x',
|
||||||
'150' => "1.5x",
|
'150' => '1.5x',
|
||||||
'100' => translate('Actual'),
|
'100' => translate('Actual'),
|
||||||
'75' => "3/4x",
|
'75' => '3/4x',
|
||||||
'50' => "1/2x",
|
'50' => '1/2x',
|
||||||
'33' => "1/3x",
|
'33' => '1/3x',
|
||||||
'25' => "1/4x",
|
'25' => '1/4x',
|
||||||
"12.5" => "1/8x",
|
'12.5' => '1/8x',
|
||||||
);
|
);
|
||||||
|
|
||||||
$bwArray = array(
|
$bwArray = array(
|
||||||
|
|
|
@ -106,27 +106,6 @@ $archiveTypes = array(
|
||||||
'1' => translate('ArchArchived')
|
'1' => translate('ArchArchived')
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
$sort_fields = array(
|
|
||||||
'Id' => translate('AttrId'),
|
|
||||||
'Name' => translate('AttrName'),
|
|
||||||
'Cause' => translate('AttrCause'),
|
|
||||||
'Notes' => translate('AttrNotes'),
|
|
||||||
'MonitorName' => translate('AttrMonitorName'),
|
|
||||||
'DateTime' => translate('AttrDateTime'),
|
|
||||||
'Length' => translate('AttrDuration'),
|
|
||||||
'Frames' => translate('AttrFrames'),
|
|
||||||
'AlarmFrames' => translate('AttrAlarmFrames'),
|
|
||||||
'TotScore' => translate('AttrTotalScore'),
|
|
||||||
'AvgScore' => translate('AttrAvgScore'),
|
|
||||||
'MaxScore' => translate('AttrMaxScore'),
|
|
||||||
);
|
|
||||||
|
|
||||||
$sort_dirns = array(
|
|
||||||
'1' => translate('SortAsc'),
|
|
||||||
'0' => translate('SortDesc')
|
|
||||||
);
|
|
||||||
|
|
||||||
$hasCal = file_exists( 'tools/jscalendar/calendar.js' );
|
$hasCal = file_exists( 'tools/jscalendar/calendar.js' );
|
||||||
|
|
||||||
$focusWindow = true;
|
$focusWindow = true;
|
||||||
|
@ -191,36 +170,36 @@ for ( $i = 0; $i < count($terms); $i++ ) {
|
||||||
<?php
|
<?php
|
||||||
} else {
|
} else {
|
||||||
?>
|
?>
|
||||||
<td><?php echo htmlSelect( "filter[terms][$i][cnj]", $conjunctionTypes, $term['cnj'] ); ?></td>
|
<td><?php echo htmlSelect( "filter[Query][terms][$i][cnj]", $conjunctionTypes, $term['cnj'] ); ?></td>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<td><?php if ( count($terms) > 2 ) { echo htmlSelect( "filter[terms][$i][obr]", $obracketTypes, $term['obr'] ); } else { ?> <?php } ?></td>
|
<td><?php if ( count($terms) > 2 ) { echo htmlSelect( "filter[Query][terms][$i][obr]", $obracketTypes, $term['obr'] ); } else { ?> <?php } ?></td>
|
||||||
<td><?php echo htmlSelect( "filter[terms][$i][attr]", $attrTypes, $term['attr'], "clearValue( this, $i ); this.form.submit();" ); ?></td>
|
<td><?php echo htmlSelect( "filter[Query][terms][$i][attr]", $attrTypes, $term['attr'], "clearValue( this, $i ); this.form.submit();" ); ?></td>
|
||||||
<?php
|
<?php
|
||||||
if ( isset($term['attr']) ) {
|
if ( isset($term['attr']) ) {
|
||||||
if ( $term['attr'] == 'Archived' ) {
|
if ( $term['attr'] == 'Archived' ) {
|
||||||
?>
|
?>
|
||||||
<td><?php echo translate('OpEq') ?><input type="hidden" name="filter[terms][<?php echo $i ?>][op]" value="="/></td>
|
<td><?php echo translate('OpEq') ?><input type="hidden" name="filter[Query][terms][<?php echo $i ?>][op]" value="="/></td>
|
||||||
<td><?php echo htmlSelect( "filter[terms][$i][val]", $archiveTypes, $term['val'] ); ?></td>
|
<td><?php echo htmlSelect( "filter[Query][terms][$i][val]", $archiveTypes, $term['val'] ); ?></td>
|
||||||
<?php
|
<?php
|
||||||
} elseif ( $term['attr'] == 'DateTime' ) {
|
} elseif ( $term['attr'] == 'DateTime' ) {
|
||||||
?>
|
?>
|
||||||
<td><?php echo htmlSelect( "filter[terms][$i][op]", $opTypes, $term['op'] ); ?></td>
|
<td><?php echo htmlSelect( "filter[Query][terms][$i][op]", $opTypes, $term['op'] ); ?></td>
|
||||||
<td>
|
<td>
|
||||||
<input name="filter[terms][<?php echo $i ?>][val]" id="filter[terms][<?php echo $i ?>][val]" value="<?php echo isset($term['val'])?validHtmlStr($term['val']):'' ?>"/>
|
<input name="filter[Query][terms][<?php echo $i ?>][val]" id="filter[Query][terms][<?php echo $i ?>][val]" value="<?php echo isset($term['val'])?validHtmlStr($term['val']):'' ?>"/>
|
||||||
<?php if ( $hasCal ) { ?>
|
<?php if ( $hasCal ) { ?>
|
||||||
<script type="text/javascript">Calendar.setup( { inputField: "filter[terms][<?php echo $i ?>][val]", ifFormat: "%Y-%m-%d %H:%M", showsTime: true, timeFormat: "24", showOthers: true, weekNumbers: false });</script>
|
<script type="text/javascript">Calendar.setup( { inputField: "filter[Query][terms][<?php echo $i ?>][val]", ifFormat: "%Y-%m-%d %H:%M", showsTime: true, timeFormat: "24", showOthers: true, weekNumbers: false });</script>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
</td>
|
</td>
|
||||||
<?php
|
<?php
|
||||||
} elseif ( $term['attr'] == 'Date' ) {
|
} elseif ( $term['attr'] == 'Date' ) {
|
||||||
?>
|
?>
|
||||||
<td><?php echo htmlSelect( "filter[terms][$i][op]", $opTypes, $term['op'] ); ?></td>
|
<td><?php echo htmlSelect( "filter[Query][terms][$i][op]", $opTypes, $term['op'] ); ?></td>
|
||||||
<td>
|
<td>
|
||||||
<input name="filter[terms][<?php echo $i ?>][val]" id="filter[terms][<?php echo $i ?>][val]" value="<?php echo isset($term['val'])?validHtmlStr($term['val']):'' ?>"/>
|
<input name="filter[Query][terms][<?php echo $i ?>][val]" id="filter[Query][terms][<?php echo $i ?>][val]" value="<?php echo isset($term['val'])?validHtmlStr($term['val']):'' ?>"/>
|
||||||
<?php if ( $hasCal ) { ?>
|
<?php if ( $hasCal ) { ?>
|
||||||
<script type="text/javascript">Calendar.setup( { inputField: "filter[terms][<?php echo $i ?>][val]", ifFormat: "%Y-%m-%d", showOthers: true, weekNumbers: false });</script>
|
<script type="text/javascript">Calendar.setup( { inputField: "filter[Query][terms][<?php echo $i ?>][val]", ifFormat: "%Y-%m-%d", showOthers: true, weekNumbers: false });</script>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
</td>
|
</td>
|
||||||
<?php
|
<?php
|
||||||
|
@ -230,8 +209,8 @@ for ( $i = 0; $i < count($terms); $i++ ) {
|
||||||
$states[$state_row['Id']] = $state_row['Name'];
|
$states[$state_row['Id']] = $state_row['Name'];
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<td><?php echo htmlSelect( "filter[terms][$i][op]", $opTypes, $term['op'] ); ?></td>
|
<td><?php echo htmlSelect( "filter[Query][terms][$i][op]", $opTypes, $term['op'] ); ?></td>
|
||||||
<td><?php echo htmlSelect( "filter[terms][$i][val]", $states, $term['val'] ); ?></td>
|
<td><?php echo htmlSelect( "filter[Query][terms][$i][val]", $states, $term['val'] ); ?></td>
|
||||||
<?php
|
<?php
|
||||||
} elseif ( $term['attr'] == 'Weekday' ) {
|
} elseif ( $term['attr'] == 'Weekday' ) {
|
||||||
$weekdays = array();
|
$weekdays = array();
|
||||||
|
@ -239,8 +218,8 @@ for ( $i = 0; $i < count($terms); $i++ ) {
|
||||||
$weekdays[$i] = strftime( '%A', mktime( 12, 0, 0, 1, $i+1, 2001 ) );
|
$weekdays[$i] = strftime( '%A', mktime( 12, 0, 0, 1, $i+1, 2001 ) );
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<td><?php echo htmlSelect( "filter[terms][$i][op]", $opTypes, $term['op'] ); ?></td>
|
<td><?php echo htmlSelect( "filter[Query][terms][$i][op]", $opTypes, $term['op'] ); ?></td>
|
||||||
<td><?php echo htmlSelect( "filter[terms][$i][val]", $weekdays, $term['val'] ); ?></td>
|
<td><?php echo htmlSelect( "filter[Query][terms][$i][val]", $weekdays, $term['val'] ); ?></td>
|
||||||
<?php
|
<?php
|
||||||
} elseif ( false && $term['attr'] == 'MonitorName' ) {
|
} elseif ( false && $term['attr'] == 'MonitorName' ) {
|
||||||
$monitors = array();
|
$monitors = array();
|
||||||
|
@ -250,8 +229,8 @@ for ( $i = 0; $i < count($terms); $i++ ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<td><?php echo htmlSelect( "filter[terms][$i][op]", $opTypes, $term['op'] ); ?></td>
|
<td><?php echo htmlSelect( "filter[Query][terms][$i][op]", $opTypes, $term['op'] ); ?></td>
|
||||||
<td><?php echo htmlSelect( "filter[terms][$i][val]", $monitors, $term['val'] ); ?></td>
|
<td><?php echo htmlSelect( "filter[Query][terms][$i][val]", $monitors, $term['val'] ); ?></td>
|
||||||
<?php
|
<?php
|
||||||
} elseif ( $term['attr'] == 'ServerId' ) {
|
} elseif ( $term['attr'] == 'ServerId' ) {
|
||||||
$servers = array();
|
$servers = array();
|
||||||
|
@ -260,8 +239,8 @@ for ( $i = 0; $i < count($terms); $i++ ) {
|
||||||
$servers[$server['Id']] = $server['Name'];
|
$servers[$server['Id']] = $server['Name'];
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<td><?php echo htmlSelect( "filter[terms][$i][op]", $opTypes, $term['op'] ); ?></td>
|
<td><?php echo htmlSelect( "filter[Query][terms][$i][op]", $opTypes, $term['op'] ); ?></td>
|
||||||
<td><?php echo htmlSelect( "filter[terms][$i][val]", $servers, $term['val'] ); ?></td>
|
<td><?php echo htmlSelect( "filter[Query][terms][$i][val]", $servers, $term['val'] ); ?></td>
|
||||||
<?php
|
<?php
|
||||||
} elseif ( $term['attr'] == 'StorageId' ) {
|
} elseif ( $term['attr'] == 'StorageId' ) {
|
||||||
$storageareas = array();
|
$storageareas = array();
|
||||||
|
@ -270,23 +249,23 @@ for ( $i = 0; $i < count($terms); $i++ ) {
|
||||||
$storageareas[$storage['Id']] = $storage['Name'];
|
$storageareas[$storage['Id']] = $storage['Name'];
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<td><?php echo htmlSelect( "filter[terms][$i][op]", $opTypes, $term['op'] ); ?></td>
|
<td><?php echo htmlSelect( "filter[Query][terms][$i][op]", $opTypes, $term['op'] ); ?></td>
|
||||||
<td><?php echo htmlSelect( "filter[terms][$i][val]", $storageareas, $term['val'] ); ?></td>
|
<td><?php echo htmlSelect( "filter[Query][terms][$i][val]", $storageareas, $term['val'] ); ?></td>
|
||||||
<?php
|
<?php
|
||||||
} else {
|
} else {
|
||||||
?>
|
?>
|
||||||
<td><?php echo htmlSelect( "filter[terms][$i][op]", $opTypes, $term['op'] ); ?></td>
|
<td><?php echo htmlSelect( "filter[Query][terms][$i][op]", $opTypes, $term['op'] ); ?></td>
|
||||||
<td><input name="filter[terms][<?php echo $i ?>][val]" value="<?php echo $term['val'] ?>"/></td>
|
<td><input name="filter[Query][terms][<?php echo $i ?>][val]" value="<?php echo $term['val'] ?>"/></td>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
?>
|
?>
|
||||||
<td><?php echo htmlSelect( "filter[terms][$i][op]", $opTypes, $term['op'] ); ?></td>
|
<td><?php echo htmlSelect( "filter[Query][terms][$i][op]", $opTypes, $term['op'] ); ?></td>
|
||||||
<td><input name="filter[terms][<?php echo $i ?>][val]" value="<?php echo isset($term['val'])?$term['val']:'' ?>"/></td>
|
<td><input name="filter[Query][terms][<?php echo $i ?>][val]" value="<?php echo isset($term['val'])?$term['val']:'' ?>"/></td>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<td><?php if ( count($terms) > 2 ) { echo htmlSelect( "filter[terms][$i][cbr]", $cbracketTypes, $term['cbr'] ); } else { ?> <?php } ?></td>
|
<td><?php if ( count($terms) > 2 ) { echo htmlSelect( "filter[Query][terms][$i][cbr]", $cbracketTypes, $term['cbr'] ); } else { ?> <?php } ?></td>
|
||||||
<td>
|
<td>
|
||||||
<input type="button" onclick="addTerm( this, <?php echo $i+1 ?> )" value="+"/>
|
<input type="button" onclick="addTerm( this, <?php echo $i+1 ?> )" value="+"/>
|
||||||
<?php
|
<?php
|
||||||
|
@ -314,13 +293,33 @@ if ( count($terms) == 0 ) {
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<label for="filter[sort_field]"><?php echo translate('SortBy') ?></label>
|
<label for="filter[Query][sort_field]"><?php echo translate('SortBy') ?></label>
|
||||||
<?php echo htmlSelect( 'filter[sort_field]', $sort_fields, $filter->sort_field() ); ?>
|
<?php
|
||||||
<?php echo htmlSelect( 'filter[sort_asc]', $sort_dirns, $filter->sort_asc() ); ?>
|
$sort_fields = array(
|
||||||
|
'Id' => translate('AttrId'),
|
||||||
|
'Name' => translate('AttrName'),
|
||||||
|
'Cause' => translate('AttrCause'),
|
||||||
|
'Notes' => translate('AttrNotes'),
|
||||||
|
'MonitorName' => translate('AttrMonitorName'),
|
||||||
|
'DateTime' => translate('AttrDateTime'),
|
||||||
|
'Length' => translate('AttrDuration'),
|
||||||
|
'Frames' => translate('AttrFrames'),
|
||||||
|
'AlarmFrames' => translate('AttrAlarmFrames'),
|
||||||
|
'TotScore' => translate('AttrTotalScore'),
|
||||||
|
'AvgScore' => translate('AttrAvgScore'),
|
||||||
|
'MaxScore' => translate('AttrMaxScore'),
|
||||||
|
);
|
||||||
|
echo htmlSelect( 'filter[Query][sort_field]', $sort_fields, $filter->sort_field() );
|
||||||
|
$sort_dirns = array(
|
||||||
|
'1' => translate('SortAsc'),
|
||||||
|
'0' => translate('SortDesc')
|
||||||
|
);
|
||||||
|
echo htmlSelect( 'filter[Query][sort_asc]', $sort_dirns, $filter->sort_asc() );
|
||||||
|
?>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<label for="filter[limit]"><?php echo translate('LimitResultsPre') ?></label>
|
<label for="filter[Query][limit]"><?php echo translate('LimitResultsPre') ?></label>
|
||||||
<input type="text" id="filter[limit]" name="filter[limit]" value="<?php echo (null !== $filter->limit())?validInt($filter->limit()):'' ?>"/><?php echo translate('LimitResultsPost') ?>
|
<input type="text" id="filter[Query][limit]" name="filter[Query][limit]" value="<?php echo (null !== $filter->limit())?validInt($filter->limit()):'' ?>"/><?php echo translate('LimitResultsPost') ?>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
|
@ -25,7 +25,7 @@ function updateButtons( element ) {
|
||||||
|
|
||||||
function clearValue( element, line ) {
|
function clearValue( element, line ) {
|
||||||
var form = element.form;
|
var form = element.form;
|
||||||
var val = form.elements['filter[terms]['+line+'][val]'];
|
var val = form.elements['filter[Query][terms]['+line+'][val]'];
|
||||||
val.value = '';
|
val.value = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ function executeFilter( element ) {
|
||||||
function saveFilter( element ) {
|
function saveFilter( element ) {
|
||||||
var form = element.form;
|
var form = element.form;
|
||||||
|
|
||||||
form.target = 'zmFilter';
|
//form.target = 'zmFilter';
|
||||||
form.elements['action'].value = 'save';
|
form.elements['action'].value = 'save';
|
||||||
form.action = thisUrl + '?view=filter';
|
form.action = thisUrl + '?view=filter';
|
||||||
form.submit();
|
form.submit();
|
||||||
|
|
|
@ -106,31 +106,38 @@ function Monitor( monitorData ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectLayout( element ) {
|
function selectLayout( element ) {
|
||||||
var cssFile = skinPath+'/css/'+Cookie.read('zmCSS')+'/views/'+$(element).get('value');
|
layout = $(element).get('value')
|
||||||
|
var cssFile = skinPath+'/css/'+Cookie.read('zmCSS')+'/views/'+layout;
|
||||||
if ( $('dynamicStyles') )
|
if ( $('dynamicStyles') )
|
||||||
$('dynamicStyles').destroy();
|
$('dynamicStyles').destroy();
|
||||||
new Asset.css( cssFile, { id: 'dynamicStyles' } );
|
new Asset.css( cssFile, { id: 'dynamicStyles' } );
|
||||||
Cookie.write( 'zmMontageLayout', $(element).get('value'), { duration: 10*365 } );
|
Cookie.write( 'zmMontageLayout', layout, { duration: 10*365 } );
|
||||||
Cookie.write( 'zmMontageScale', '', { duration: 10*365 } );
|
if ( layout != 'montage_freeform.css' ) {
|
||||||
$('scale').set('value', '' );
|
Cookie.write( 'zmMontageScale', '', { duration: 10*365 } );
|
||||||
$('width').set('value', '');
|
$('scale').set('value', '' );
|
||||||
|
$('width').set('value', '');
|
||||||
|
|
||||||
for ( var x = 0; x < monitors.length; x++ ) {
|
for ( var x = 0; x < monitors.length; x++ ) {
|
||||||
var monitor = monitors[x];
|
var monitor = monitors[x];
|
||||||
var streamImg = document.getElementById( 'liveStream'+monitor.id );
|
var streamImg = $( 'liveStream'+monitor.id );
|
||||||
if ( streamImg ) {
|
if ( streamImg ) {
|
||||||
var src = streamImg.src;
|
if ( streamImg.nodeName == 'IMG' ) {
|
||||||
streamImg.src='';
|
var src = streamImg.src;
|
||||||
src = src.replace(/width=[\.\d]+/i,'width=0' );
|
streamImg.src='';
|
||||||
src = src.replace(/rand=\d+/i,'rand='+Math.floor((Math.random() * 1000000) ));
|
src = src.replace(/width=[\.\d]+/i,'width=0' );
|
||||||
streamImg.src = src;
|
src = src.replace(/rand=\d+/i,'rand='+Math.floor((Math.random() * 1000000) ));
|
||||||
streamImg.style.width = '';
|
streamImg.src = src;
|
||||||
}
|
} else if ( streamImg.nodeName == 'APPLET' || streamImg.nodeName == 'OBJECT' ) {
|
||||||
var zonesSVG = $('zones'+monitor.id);
|
// APPLET's and OBJECTS need to be re-initialized
|
||||||
if ( zonesSVG ) {
|
}
|
||||||
zonesSVG.style.width = '';
|
streamImg.style.width = '';
|
||||||
}
|
}
|
||||||
} // end foreach monitor
|
var zonesSVG = $('zones'+monitor.id);
|
||||||
|
if ( zonesSVG ) {
|
||||||
|
zonesSVG.style.width = '';
|
||||||
|
}
|
||||||
|
} // end foreach monitor
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeWidth() {
|
function changeWidth() {
|
||||||
|
@ -139,20 +146,23 @@ function changeWidth() {
|
||||||
for ( var x = 0; x < monitors.length; x++ ) {
|
for ( var x = 0; x < monitors.length; x++ ) {
|
||||||
var monitor = monitors[x];
|
var monitor = monitors[x];
|
||||||
/*Stream could be an applet so can't use moo tools*/
|
/*Stream could be an applet so can't use moo tools*/
|
||||||
var streamImg = document.getElementById( 'liveStream'+monitor.id );
|
var streamImg = $( 'liveStream'+monitor.id );
|
||||||
if ( streamImg ) {
|
if ( streamImg ) {
|
||||||
var src = streamImg.src;
|
if ( streamImg.nodeName == 'IMG' ) {
|
||||||
streamImg.src='';
|
var src = streamImg.src;
|
||||||
src = src.replace(/width=[\.\d]+/i,'width='+width );
|
streamImg.src='';
|
||||||
src = src.replace(/rand=\d+/i,'rand='+Math.floor((Math.random() * 1000000) ));
|
src = src.replace(/width=[\.\d]+/i,'width='+width );
|
||||||
streamImg.src = src;
|
src = src.replace(/rand=\d+/i,'rand='+Math.floor((Math.random() * 1000000) ));
|
||||||
|
streamImg.src = src;
|
||||||
|
|
||||||
streamImg.style.width = width + "px";
|
}
|
||||||
streamImg.style.height = '';
|
streamImg.style.width = width? width + "px" : null;
|
||||||
|
//streamImg.style.height = '';
|
||||||
}
|
}
|
||||||
var zonesSVG = $('zones'+monitor.id);
|
var zonesSVG = $('zones'+monitor.id);
|
||||||
if ( zonesSVG ) {
|
if ( zonesSVG ) {
|
||||||
zonesSVG.style.width = newWidth + "px";
|
|
||||||
|
zonesSVG.style.width = width ? width + "px" : '100%';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$('scale').set('value', '' );
|
$('scale').set('value', '' );
|
||||||
|
@ -166,18 +176,20 @@ function changeHeight() {
|
||||||
for ( var x = 0; x < monitors.length; x++ ) {
|
for ( var x = 0; x < monitors.length; x++ ) {
|
||||||
var monitor = monitors[x];
|
var monitor = monitors[x];
|
||||||
/*Stream could be an applet so can't use moo tools*/
|
/*Stream could be an applet so can't use moo tools*/
|
||||||
var streamImg = document.getElementById( 'liveStream'+monitor.id );
|
var streamImg = $( 'liveStream'+monitor.id );
|
||||||
if ( streamImg ) {
|
if ( streamImg ) {
|
||||||
var src = streamImg.src;
|
if ( streamImg.nodeName == 'IMG' ) {
|
||||||
streamImg.src='';
|
var src = streamImg.src;
|
||||||
src = src.replace(/height=[\.\d]+/i,'height='+height );
|
streamImg.src='';
|
||||||
src = src.replace(/rand=\d+/i,'rand='+Math.floor((Math.random() * 1000000) ));
|
src = src.replace(/height=[\.\d]+/i,'height='+height );
|
||||||
streamImg.src = src;
|
src = src.replace(/rand=\d+/i,'rand='+Math.floor((Math.random() * 1000000) ));
|
||||||
streamImg.style.height = height + "px";
|
streamImg.src = src;
|
||||||
|
streamImg.style.height = height ? height + "px" : null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var zonesSVG = $('zones'+monitor.id);
|
var zonesSVG = $('zones'+monitor.id);
|
||||||
if ( zonesSVG ) {
|
if ( zonesSVG ) {
|
||||||
zonesSVG.style.height = newHeight + "px";
|
zonesSVG.style.height = height + "px";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$('scale').set('value', '' );
|
$('scale').set('value', '' );
|
||||||
|
@ -195,16 +207,18 @@ function changeScale() {
|
||||||
/*Stream could be an applet so can't use moo tools*/
|
/*Stream could be an applet so can't use moo tools*/
|
||||||
var streamImg = document.getElementById( 'liveStream'+monitor.id );
|
var streamImg = document.getElementById( 'liveStream'+monitor.id );
|
||||||
if ( streamImg ) {
|
if ( streamImg ) {
|
||||||
var src = streamImg.src;
|
if ( streamImg.nodeName == 'IMG' ) {
|
||||||
streamImg.src='';
|
var src = streamImg.src;
|
||||||
|
streamImg.src='';
|
||||||
|
|
||||||
|
//src = src.replace(/rand=\d+/i,'rand='+Math.floor((Math.random() * 1000000) ));
|
||||||
|
src = src.replace(/scale=[\.\d]+/i,'scale='+ scale );
|
||||||
|
src = src.replace(/width=[\.\d]+/i,'width='+newWidth );
|
||||||
|
src = src.replace(/height=[\.\d]+/i,'height='+newHeight );
|
||||||
|
streamImg.src = src;
|
||||||
|
}
|
||||||
streamImg.style.width = newWidth + "px";
|
streamImg.style.width = newWidth + "px";
|
||||||
streamImg.style.height = newHeight + "px";
|
streamImg.style.height = newHeight + "px";
|
||||||
//src = src.replace(/rand=\d+/i,'rand='+Math.floor((Math.random() * 1000000) ));
|
|
||||||
src = src.replace(/scale=[\.\d]+/i,'scale='+ scale );
|
|
||||||
src = src.replace(/width=[\.\d]+/i,'width='+newWidth );
|
|
||||||
src = src.replace(/height=[\.\d]+/i,'height='+newHeight );
|
|
||||||
streamImg.src = src;
|
|
||||||
}
|
}
|
||||||
var zonesSVG = $('zones'+monitor.id);
|
var zonesSVG = $('zones'+monitor.id);
|
||||||
if ( zonesSVG ) {
|
if ( zonesSVG ) {
|
||||||
|
@ -227,7 +241,7 @@ function initPage() {
|
||||||
var delay = Math.round( (Math.random()+0.5)*statusRefreshTimeout );
|
var delay = Math.round( (Math.random()+0.5)*statusRefreshTimeout );
|
||||||
monitors[i].start( delay );
|
monitors[i].start( delay );
|
||||||
}
|
}
|
||||||
selectLayout( $('layout') );
|
selectLayout($('layout'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Kick everything off
|
// Kick everything off
|
||||||
|
|
|
@ -55,12 +55,17 @@ $heights = array(
|
||||||
480 => 480,
|
480 => 480,
|
||||||
);
|
);
|
||||||
|
|
||||||
$width_scale = $height_scale = $scale = null;
|
$scale = '100'; # actual
|
||||||
|
|
||||||
if ( isset( $_REQUEST['scale'] ) )
|
if ( isset( $_REQUEST['scale'] ) ) {
|
||||||
$scale = validInt($_REQUEST['scale']);
|
$scale = validInt($_REQUEST['scale']);
|
||||||
else if ( isset( $_COOKIE['zmMontageScale'] ) )
|
Logger::Debug("Setting scale from request to $scale");
|
||||||
|
} else if ( isset( $_COOKIE['zmMontageScale'] ) ) {
|
||||||
$scale = $_COOKIE['zmMontageScale'];
|
$scale = $_COOKIE['zmMontageScale'];
|
||||||
|
Logger::Debug("Setting scale from cookie to $scale");
|
||||||
|
} else {
|
||||||
|
Logger::Debug("scale is $scale");
|
||||||
|
}
|
||||||
|
|
||||||
foreach( dbFetchAll( $sql ) as $row ) {
|
foreach( dbFetchAll( $sql ) as $row ) {
|
||||||
if ( !visibleMonitor( $row['Id'] ) ) {
|
if ( !visibleMonitor( $row['Id'] ) ) {
|
||||||
|
@ -92,6 +97,7 @@ $layouts = array(
|
||||||
'montage_3wide50enlarge.css' => translate('Mtg3widgrx'),
|
'montage_3wide50enlarge.css' => translate('Mtg3widgrx'),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$layout = '';
|
||||||
if ( isset($_COOKIE['zmMontageLayout']) )
|
if ( isset($_COOKIE['zmMontageLayout']) )
|
||||||
$layout = $_COOKIE['zmMontageLayout'];
|
$layout = $_COOKIE['zmMontageLayout'];
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue