diff --git a/.travis.yml b/.travis.yml
index 80541eaab..e41dcb35f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -37,8 +37,16 @@ env:
- SMPFLAGS=-j4 OS=fedora DIST=29 DOCKER_REPO=knnniggett/packpack
- SMPFLAGS=-j4 OS=ubuntu DIST=trusty
- SMPFLAGS=-j4 OS=ubuntu DIST=xenial
+ - SMPFLAGS=-j4 OS=ubuntu DIST=bionic
+ - SMPFLAGS=-j4 OS=ubuntu DIST=disco
+ - SMPFLAGS=-j4 OS=debian DIST=buster
+ - SMPFLAGS=-j4 OS=debian DIST=stretch
- SMPFLAGS=-j4 OS=ubuntu DIST=trusty ARCH=i386
- SMPFLAGS=-j4 OS=ubuntu DIST=xenial ARCH=i386
+ - SMPFLAGS=-j4 OS=ubuntu DIST=bionic ARCH=i386
+ - SMPFLAGS=-j4 OS=ubuntu DIST=disco ARCH=i386
+ - SMPFLAGS=-j4 OS=debian DIST=buster ARCH=i386
+ - SMPFLAGS=-j4 OS=debian DIST=stretch ARCH=i386
- SMPFLAGS=-j4 OS=raspbian DIST=stretch ARCH=armhf DOCKER_REPO=knnniggett/packpack
compiler:
diff --git a/distros/ubuntu1204/control b/distros/ubuntu1204/control
index cc6158334..1a2c6c9e0 100644
--- a/distros/ubuntu1204/control
+++ b/distros/ubuntu1204/control
@@ -7,6 +7,7 @@ Build-Depends: debhelper (>= 9), python-sphinx | python3-sphinx, apache2-dev, dh
,cmake
,libx264-dev, libmp4v2-dev
,libavcodec-dev, libavformat-dev (>= 3:0.svn20090204), libswscale-dev (>= 3:0.svn20090204), libavutil-dev, libavdevice-dev
+ ,libavresample-dev
,libbz2-dev
,libgcrypt-dev
,libcurl4-gnutls-dev
diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Event.pm b/scripts/ZoneMinder/lib/ZoneMinder/Event.pm
index fc19eb7d9..b5a89e601 100644
--- a/scripts/ZoneMinder/lib/ZoneMinder/Event.pm
+++ b/scripts/ZoneMinder/lib/ZoneMinder/Event.pm
@@ -134,7 +134,7 @@ sub Path {
if ( ! $$event{Path} ) {
my $Storage = $event->Storage();
- if ( defined $Storage->Id() ) {
+ if ( (!$$event{StorageId}) or defined $Storage->Id() ) {
$$event{Path} = join('/', $Storage->Path(), $event->RelativePath());
} else {
Error("Storage area for $$event{StorageId} no longer exists in db.");
diff --git a/scripts/zmaudit.pl.in b/scripts/zmaudit.pl.in
index 839b69e0f..57c660342 100644
--- a/scripts/zmaudit.pl.in
+++ b/scripts/zmaudit.pl.in
@@ -282,6 +282,7 @@ MAIN: while( $loop ) {
}
#Event path is hour/minute/sec
my $event_path = readlink($event_link);
+ $event_path = '' if ! defined($event_path);
Debug("Checking link $event_link points to: $event_path");
if ( !($event_path and -e $event_path) ) {
diff --git a/src/zm_config.cpp b/src/zm_config.cpp
index 68c9eae08..7d75042ba 100644
--- a/src/zm_config.cpp
+++ b/src/zm_config.cpp
@@ -29,6 +29,10 @@
#include "zm_utils.h"
+// Note that Error and Debug calls won't actually go anywhere unless you
+// set the relevant ENV vars because the logger gets it's setting from the
+// config.
+
void zmLoadConfig() {
// Process name, value pairs from the main config file first
@@ -40,22 +44,22 @@ void zmLoadConfig() {
DIR* configSubFolder = opendir(ZM_CONFIG_SUBDIR);
if ( configSubFolder ) { // subfolder exists and is readable
char glob_pattern[PATH_MAX] = "";
- snprintf( glob_pattern, sizeof(glob_pattern), "%s/*.conf", ZM_CONFIG_SUBDIR );
+ snprintf(glob_pattern, sizeof(glob_pattern), "%s/*.conf", ZM_CONFIG_SUBDIR);
glob_t pglob;
- int glob_status = glob( glob_pattern, 0, 0, &pglob );
+ int glob_status = glob(glob_pattern, 0, 0, &pglob);
if ( glob_status != 0 ) {
if ( glob_status < 0 ) {
- Error( "Can't glob '%s': %s", glob_pattern, strerror(errno) );
+ Error("Can't glob '%s': %s", glob_pattern, strerror(errno));
} else {
- Debug( 1, "Can't glob '%s': %d", glob_pattern, glob_status );
+ Debug(1, "Can't glob '%s': %d", glob_pattern, glob_status);
}
} else {
for ( unsigned int i = 0; i < pglob.gl_pathc; i++ ) {
process_configfile(pglob.gl_pathv[i]);
}
}
- globfree( &pglob );
+ globfree(&pglob);
closedir(configSubFolder);
}
@@ -64,59 +68,60 @@ void zmLoadConfig() {
config.Assign();
// Populate the server config entries
- if ( ! staticConfig.SERVER_ID ) {
- if ( ! staticConfig.SERVER_NAME.empty() ) {
+ if ( !staticConfig.SERVER_ID ) {
+ if ( !staticConfig.SERVER_NAME.empty() ) {
- Debug( 1, "Fetching ZM_SERVER_ID For Name = %s", staticConfig.SERVER_NAME.c_str() );
- std::string sql = stringtf("SELECT `Id` FROM `Servers` WHERE `Name`='%s'", staticConfig.SERVER_NAME.c_str() );
+ Debug(1, "Fetching ZM_SERVER_ID For Name = %s", staticConfig.SERVER_NAME.c_str());
+ std::string sql = stringtf("SELECT `Id` FROM `Servers` WHERE `Name`='%s'",
+ staticConfig.SERVER_NAME.c_str());
zmDbRow dbrow;
- if ( dbrow.fetch( sql.c_str() ) ) {
+ if ( dbrow.fetch(sql.c_str()) ) {
staticConfig.SERVER_ID = atoi(dbrow[0]);
} else {
- Fatal("Can't get ServerId for Server %s", staticConfig.SERVER_NAME.c_str() );
+ Fatal("Can't get ServerId for Server %s", staticConfig.SERVER_NAME.c_str());
}
} // end if has SERVER_NAME
} else if ( staticConfig.SERVER_NAME.empty() ) {
- Debug( 1, "Fetching ZM_SERVER_NAME For Id = %d", staticConfig.SERVER_ID );
- std::string sql = stringtf("SELECT `Name` FROM `Servers` WHERE `Id`='%d'", staticConfig.SERVER_ID );
+ Debug(1, "Fetching ZM_SERVER_NAME For Id = %d", staticConfig.SERVER_ID);
+ std::string sql = stringtf("SELECT `Name` FROM `Servers` WHERE `Id`='%d'", staticConfig.SERVER_ID);
zmDbRow dbrow;
- if ( dbrow.fetch( sql.c_str() ) ) {
+ if ( dbrow.fetch(sql.c_str()) ) {
staticConfig.SERVER_NAME = std::string(dbrow[0]);
} else {
- Fatal("Can't get ServerName for Server ID %d", staticConfig.SERVER_ID );
+ Fatal("Can't get ServerName for Server ID %d", staticConfig.SERVER_ID);
}
if ( staticConfig.SERVER_ID ) {
- Debug( 3, "Multi-server configuration detected. Server is %d.", staticConfig.SERVER_ID );
+ Debug(3, "Multi-server configuration detected. Server is %d.", staticConfig.SERVER_ID);
} else {
- Debug( 3, "Single server configuration assumed because no Server ID or Name was specified." );
+ Debug(3, "Single server configuration assumed because no Server ID or Name was specified.");
}
}
- snprintf( staticConfig.capture_file_format, sizeof(staticConfig.capture_file_format), "%%s/%%0%dd-capture.jpg", config.event_image_digits );
- snprintf( staticConfig.analyse_file_format, sizeof(staticConfig.analyse_file_format), "%%s/%%0%dd-analyse.jpg", config.event_image_digits );
- snprintf( staticConfig.general_file_format, sizeof(staticConfig.general_file_format), "%%s/%%0%dd-%%s", config.event_image_digits );
- snprintf( staticConfig.video_file_format, sizeof(staticConfig.video_file_format), "%%s/%%s");
+ snprintf(staticConfig.capture_file_format, sizeof(staticConfig.capture_file_format), "%%s/%%0%dd-capture.jpg", config.event_image_digits);
+ snprintf(staticConfig.analyse_file_format, sizeof(staticConfig.analyse_file_format), "%%s/%%0%dd-analyse.jpg", config.event_image_digits);
+ snprintf(staticConfig.general_file_format, sizeof(staticConfig.general_file_format), "%%s/%%0%dd-%%s", config.event_image_digits);
+ snprintf(staticConfig.video_file_format, sizeof(staticConfig.video_file_format), "%%s/%%s");
}
-void process_configfile( char* configFile) {
+void process_configfile(char* configFile) {
FILE *cfg;
char line[512];
- if ( (cfg = fopen( configFile, "r")) == NULL ) {
- Fatal( "Can't open %s: %s", configFile, strerror(errno) );
+ if ( (cfg = fopen(configFile, "r")) == NULL ) {
+ Fatal("Can't open %s: %s", configFile, strerror(errno));
return;
}
- while ( fgets( line, sizeof(line), cfg ) != NULL ) {
+ while ( fgets(line, sizeof(line), cfg) != NULL ) {
char *line_ptr = line;
// Trim off any cr/lf line endings
- int chomp_len = strcspn( line_ptr, "\r\n" );
+ int chomp_len = strcspn(line_ptr, "\r\n");
line_ptr[chomp_len] = '\0';
// Remove leading white space
- int white_len = strspn( line_ptr, " \t" );
+ int white_len = strspn(line_ptr, " \t");
line_ptr += white_len;
// Check for comment or empty line
@@ -131,9 +136,9 @@ void process_configfile( char* configFile) {
}
// Now look for the '=' in the middle of the line
- temp_ptr = strchr( line_ptr, '=' );
+ temp_ptr = strchr(line_ptr, '=');
if ( !temp_ptr ) {
- Warning( "Invalid data in %s: '%s'", configFile, line );
+ Warning("Invalid data in %s: '%s'", configFile, line);
continue;
}
@@ -148,49 +153,49 @@ void process_configfile( char* configFile) {
} while ( *temp_ptr == ' ' || *temp_ptr == '\t' );
// Remove leading white space and leading quotes from the value part
- white_len = strspn( val_ptr, " \t" );
- white_len += strspn( val_ptr, "\'\"" );
+ white_len = strspn(val_ptr, " \t");
+ white_len += strspn(val_ptr, "\'\"");
val_ptr += white_len;
- if ( strcasecmp( name_ptr, "ZM_DB_HOST" ) == 0 )
+ if ( strcasecmp(name_ptr, "ZM_DB_HOST") == 0 )
staticConfig.DB_HOST = std::string(val_ptr);
- else if ( strcasecmp( name_ptr, "ZM_DB_NAME" ) == 0 )
+ else if ( strcasecmp(name_ptr, "ZM_DB_NAME") == 0 )
staticConfig.DB_NAME = std::string(val_ptr);
- else if ( strcasecmp( name_ptr, "ZM_DB_USER" ) == 0 )
+ else if ( strcasecmp(name_ptr, "ZM_DB_USER") == 0 )
staticConfig.DB_USER = std::string(val_ptr);
- else if ( strcasecmp( name_ptr, "ZM_DB_PASS" ) == 0 )
+ else if ( strcasecmp(name_ptr, "ZM_DB_PASS") == 0 )
staticConfig.DB_PASS = std::string(val_ptr);
- else if ( strcasecmp( name_ptr, "ZM_DB_SSL_CA_CERT" ) == 0 )
+ else if ( strcasecmp(name_ptr, "ZM_DB_SSL_CA_CERT") == 0 )
staticConfig.DB_SSL_CA_CERT = std::string(val_ptr);
- else if ( strcasecmp( name_ptr, "ZM_DB_SSL_CLIENT_KEY" ) == 0 )
+ else if ( strcasecmp(name_ptr, "ZM_DB_SSL_CLIENT_KEY") == 0 )
staticConfig.DB_SSL_CLIENT_KEY = std::string(val_ptr);
- else if ( strcasecmp( name_ptr, "ZM_DB_SSL_CLIENT_CERT" ) == 0 )
+ else if ( strcasecmp(name_ptr, "ZM_DB_SSL_CLIENT_CERT") == 0 )
staticConfig.DB_SSL_CLIENT_CERT = std::string(val_ptr);
- else if ( strcasecmp( name_ptr, "ZM_PATH_WEB" ) == 0 )
+ else if ( strcasecmp(name_ptr, "ZM_PATH_WEB") == 0 )
staticConfig.PATH_WEB = std::string(val_ptr);
- else if ( strcasecmp( name_ptr, "ZM_SERVER_HOST" ) == 0 )
+ else if ( strcasecmp(name_ptr, "ZM_SERVER_HOST") == 0 )
staticConfig.SERVER_NAME = std::string(val_ptr);
- else if ( strcasecmp( name_ptr, "ZM_SERVER_NAME" ) == 0 )
+ else if ( strcasecmp(name_ptr, "ZM_SERVER_NAME") == 0 )
staticConfig.SERVER_NAME = std::string(val_ptr);
- else if ( strcasecmp( name_ptr, "ZM_SERVER_ID" ) == 0 )
+ else if ( strcasecmp(name_ptr, "ZM_SERVER_ID") == 0 )
staticConfig.SERVER_ID = atoi(val_ptr);
- else if ( strcasecmp( name_ptr, "ZM_DIR_EVENTS" ) == 0 )
+ else if ( strcasecmp(name_ptr, "ZM_DIR_EVENTS") == 0 )
staticConfig.DIR_EVENTS = std::string(val_ptr);
- else if ( strcasecmp( name_ptr, "ZM_DIR_SOUNDS" ) == 0 )
+ else if ( strcasecmp(name_ptr, "ZM_DIR_SOUNDS") == 0 )
staticConfig.DIR_SOUNDS = std::string(val_ptr);
- else if ( strcasecmp( name_ptr, "ZM_DIR_EXPORTS" ) == 0 )
+ else if ( strcasecmp(name_ptr, "ZM_DIR_EXPORTS") == 0 )
staticConfig.DIR_EXPORTS = std::string(val_ptr);
- else if ( strcasecmp( name_ptr, "ZM_PATH_ZMS" ) == 0 )
+ else if ( strcasecmp(name_ptr, "ZM_PATH_ZMS") == 0 )
staticConfig.PATH_ZMS = std::string(val_ptr);
- else if ( strcasecmp( name_ptr, "ZM_PATH_MAP" ) == 0 )
+ else if ( strcasecmp(name_ptr, "ZM_PATH_MAP") == 0 )
staticConfig.PATH_MAP = std::string(val_ptr);
- else if ( strcasecmp( name_ptr, "ZM_PATH_SOCKS" ) == 0 )
+ else if ( strcasecmp(name_ptr, "ZM_PATH_SOCKS") == 0 )
staticConfig.PATH_SOCKS = std::string(val_ptr);
- else if ( strcasecmp( name_ptr, "ZM_PATH_LOGS" ) == 0 )
+ else if ( strcasecmp(name_ptr, "ZM_PATH_LOGS") == 0 )
staticConfig.PATH_LOGS = std::string(val_ptr);
- else if ( strcasecmp( name_ptr, "ZM_PATH_SWAP" ) == 0 )
+ else if ( strcasecmp(name_ptr, "ZM_PATH_SWAP") == 0 )
staticConfig.PATH_SWAP = std::string(val_ptr);
- else if ( strcasecmp( name_ptr, "ZM_PATH_ARP" ) == 0 )
+ else if ( strcasecmp(name_ptr, "ZM_PATH_ARP") == 0 )
staticConfig.PATH_ARP = std::string(val_ptr);
else {
// We ignore this now as there may be more parameters than the
@@ -198,18 +203,18 @@ void process_configfile( char* configFile) {
// Warning( "Invalid parameter '%s' in %s", name_ptr, ZM_CONFIG );
}
} // end foreach line of the config
- fclose( cfg );
+ fclose(cfg);
}
StaticConfig staticConfig;
-ConfigItem::ConfigItem( const char *p_name, const char *p_value, const char *const p_type ) {
+ConfigItem::ConfigItem(const char *p_name, const char *p_value, const char *const p_type) {
name = new char[strlen(p_name)+1];
- strcpy( name, p_name );
+ strcpy(name, p_name);
value = new char[strlen(p_value)+1];
- strcpy( value, p_value );
+ strcpy(value, p_value);
type = new char[strlen(p_type)+1];
- strcpy( type, p_type );
+ strcpy(type, p_type);
//Info( "Created new config item %s = %s (%s)\n", name, value, type );
@@ -217,28 +222,28 @@ ConfigItem::ConfigItem( const char *p_name, const char *p_value, const char *con
accessed = false;
}
-ConfigItem::ConfigItem( const ConfigItem &item ) {
+ConfigItem::ConfigItem(const ConfigItem &item) {
name = new char[strlen(item.name)+1];
- strcpy( name, item.name );
+ strcpy(name, item.name);
value = new char[strlen(item.value)+1];
- strcpy( value, item.value );
+ strcpy(value, item.value);
type = new char[strlen(item.type)+1];
- strcpy( type, item.type );
+ strcpy(type, item.type);
//Info( "Created new config item %s = %s (%s)\n", name, value, type );
accessed = false;
}
-void ConfigItem::Copy( const ConfigItem &item ) {
+void ConfigItem::Copy(const ConfigItem &item) {
if (name) delete name;
name = new char[strlen(item.name)+1];
- strcpy( name, item.name );
+ strcpy(name, item.name);
if (value) delete value;
value = new char[strlen(item.value)+1];
- strcpy( value, item.value );
+ strcpy(value, item.value);
if (type) delete type;
type = new char[strlen(item.type)+1];
- strcpy( type, item.type );
+ strcpy(type, item.type);
//Info( "Created new config item %s = %s (%s)\n", name, value, type );
accessed = false;
@@ -253,16 +258,16 @@ ConfigItem::~ConfigItem() {
void ConfigItem::ConvertValue() const {
if ( !strcmp( type, "boolean" ) ) {
cfg_type = CFG_BOOLEAN;
- cfg_value.boolean_value = (bool)strtol( value, 0, 0 );
- } else if ( !strcmp( type, "integer" ) ) {
+ cfg_value.boolean_value = (bool)strtol(value, 0, 0);
+ } else if ( !strcmp(type, "integer") ) {
cfg_type = CFG_INTEGER;
- cfg_value.integer_value = strtol( value, 0, 10 );
- } else if ( !strcmp( type, "hexadecimal" ) ) {
+ cfg_value.integer_value = strtol(value, 0, 10);
+ } else if ( !strcmp(type, "hexadecimal") ) {
cfg_type = CFG_INTEGER;
- cfg_value.integer_value = strtol( value, 0, 16 );
- } else if ( !strcmp( type, "decimal" ) ) {
+ cfg_value.integer_value = strtol(value, 0, 16);
+ } else if ( !strcmp(type, "decimal") ) {
cfg_type = CFG_DECIMAL;
- cfg_value.decimal_value = strtod( value, 0 );
+ cfg_value.decimal_value = strtod(value, 0);
} else {
cfg_type = CFG_STRING;
cfg_value.string_value = value;
@@ -275,11 +280,11 @@ bool ConfigItem::BooleanValue() const {
ConvertValue();
if ( cfg_type != CFG_BOOLEAN ) {
- Error( "Attempt to fetch boolean value for %s, actual type is %s. Try running 'zmupdate.pl -f' to reload config.", name, type );
- exit( -1 );
+ Error("Attempt to fetch boolean value for %s, actual type is %s. Try running 'zmupdate.pl -f' to reload config.", name, type);
+ exit(-1);
}
- return( cfg_value.boolean_value );
+ return cfg_value.boolean_value;
}
int ConfigItem::IntegerValue() const {
@@ -287,11 +292,11 @@ int ConfigItem::IntegerValue() const {
ConvertValue();
if ( cfg_type != CFG_INTEGER ) {
- Error( "Attempt to fetch integer value for %s, actual type is %s. Try running 'zmupdate.pl -f' to reload config.", name, type );
- exit( -1 );
+ Error("Attempt to fetch integer value for %s, actual type is %s. Try running 'zmupdate.pl -f' to reload config.", name, type);
+ exit(-1);
}
- return( cfg_value.integer_value );
+ return cfg_value.integer_value;
}
double ConfigItem::DecimalValue() const {
@@ -299,11 +304,11 @@ double ConfigItem::DecimalValue() const {
ConvertValue();
if ( cfg_type != CFG_DECIMAL ) {
- Error( "Attempt to fetch decimal value for %s, actual type is %s. Try running 'zmupdate.pl -f' to reload config.", name, type );
- exit( -1 );
+ Error("Attempt to fetch decimal value for %s, actual type is %s. Try running 'zmupdate.pl -f' to reload config.", name, type);
+ exit(-1);
}
- return( cfg_value.decimal_value );
+ return cfg_value.decimal_value;
}
const char *ConfigItem::StringValue() const {
@@ -311,11 +316,11 @@ const char *ConfigItem::StringValue() const {
ConvertValue();
if ( cfg_type != CFG_STRING ) {
- Error( "Attempt to fetch string value for %s, actual type is %s. Try running 'zmupdate.pl -f' to reload config.", name, type );
- exit( -1 );
+ Error("Attempt to fetch string value for %s, actual type is %s. Try running 'zmupdate.pl -f' to reload config.", name, type);
+ exit(-1);
}
- return( cfg_value.string_value );
+ return cfg_value.string_value;
}
Config::Config() {
@@ -337,54 +342,54 @@ Config::~Config() {
void Config::Load() {
static char sql[ZM_SQL_SML_BUFSIZ];
- strncpy( sql, "select Name, Value, Type from Config order by Id", sizeof(sql) );
- if ( mysql_query( &dbconn, sql ) ) {
- Error( "Can't run query: %s", mysql_error( &dbconn ) );
- exit( mysql_errno( &dbconn ) );
+ strncpy(sql, "SELECT `Name`, `Value`, `Type` FROM `Config` ORDER BY `Id`", sizeof(sql) );
+ if ( mysql_query(&dbconn, sql) ) {
+ Error("Can't run query: %s", mysql_error(&dbconn));
+ exit(mysql_errno(&dbconn));
}
- MYSQL_RES *result = mysql_store_result( &dbconn );
+ MYSQL_RES *result = mysql_store_result(&dbconn);
if ( !result ) {
- Error( "Can't use query result: %s", mysql_error( &dbconn ) );
- exit( mysql_errno( &dbconn ) );
+ Error("Can't use query result: %s", mysql_error(&dbconn));
+ exit(mysql_errno(&dbconn));
}
- n_items = mysql_num_rows( result );
+ n_items = mysql_num_rows(result);
if ( n_items <= ZM_MAX_CFG_ID ) {
- Error( "Config mismatch, expected %d items, read %d. Try running 'zmupdate.pl -f' to reload config.", ZM_MAX_CFG_ID+1, n_items );
- exit( -1 );
+ Error("Config mismatch, expected %d items, read %d. Try running 'zmupdate.pl -f' to reload config.", ZM_MAX_CFG_ID+1, n_items);
+ exit(-1);
}
items = new ConfigItem *[n_items];
- for( int i = 0; MYSQL_ROW dbrow = mysql_fetch_row( result ); i++ ) {
- items[i] = new ConfigItem( dbrow[0], dbrow[1], dbrow[2] );
+ for( int i = 0; MYSQL_ROW dbrow = mysql_fetch_row(result); i++ ) {
+ items[i] = new ConfigItem(dbrow[0], dbrow[1], dbrow[2]);
}
- mysql_free_result( result );
+ mysql_free_result(result);
}
void Config::Assign() {
ZM_CFG_ASSIGN_LIST
}
-const ConfigItem &Config::Item( int id ) {
+const ConfigItem &Config::Item(int id) {
if ( !n_items ) {
Load();
Assign();
}
if ( id < 0 || id > ZM_MAX_CFG_ID ) {
- Error( "Attempt to access invalid config, id = %d. Try running 'zmupdate.pl -f' to reload config.", id );
- exit( -1 );
+ Error("Attempt to access invalid config, id = %d. Try running 'zmupdate.pl -f' to reload config.", id);
+ exit(-1);
}
ConfigItem *item = items[id];
if ( !item ) {
- Error( "Can't find config item %d", id );
- exit( -1 );
+ Error("Can't find config item %d", id);
+ exit(-1);
}
- return( *item );
+ return *item;
}
Config config;
diff --git a/src/zm_db.cpp b/src/zm_db.cpp
index 806ef8e5c..77c149f03 100644
--- a/src/zm_db.cpp
+++ b/src/zm_db.cpp
@@ -32,7 +32,7 @@ bool zmDbConnect() {
// For some reason having these lines causes memory corruption and crashing on newer debian/ubuntu
// But they really need to be here in order to prevent a double open of mysql
if ( zmDbConnected ) {
- Warning("Calling zmDbConnect when already connected");
+ //Warning("Calling zmDbConnect when already connected");
return true;
}
diff --git a/src/zm_event.cpp b/src/zm_event.cpp
index ef39dfa7a..a4117729c 100644
--- a/src/zm_event.cpp
+++ b/src/zm_event.cpp
@@ -294,7 +294,6 @@ bool Event::WriteFrameImage(Image *image, struct timeval timestamp, const char *
int thisquality = ( alarm_frame && (config.jpeg_alarm_file_quality > config.jpeg_file_quality) ) ? config.jpeg_alarm_file_quality : 0 ; // quality to use, zero is default
bool rc;
-Debug(3, "Writing image to %s", event_file);
if ( !config.timestamp_on_capture ) {
// stash the image we plan to use in another pointer regardless if timestamped.
@@ -550,7 +549,7 @@ void Event::AddFrame(Image *image, struct timeval timestamp, int score, Image *a
static char event_file[PATH_MAX];
snprintf(event_file, sizeof(event_file), staticConfig.capture_file_format, path, frames);
Debug(1, "Writing capture frame %d to %s", frames, event_file);
- if ( ! WriteFrameImage(image, timestamp, event_file) ) {
+ if ( !WriteFrameImage(image, timestamp, event_file) ) {
Error("Failed to write frame image");
}
} else {
diff --git a/src/zm_ffmpeg.cpp b/src/zm_ffmpeg.cpp
index bd8643335..339b54c6c 100644
--- a/src/zm_ffmpeg.cpp
+++ b/src/zm_ffmpeg.cpp
@@ -289,9 +289,10 @@ static void zm_log_fps(double d, const char *postfix) {
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
void zm_dump_codecpar ( const AVCodecParameters *par ) {
- Debug(1, "Dumping codecpar codec_type(%d) codec_id(%d) codec_tag(%d) width(%d) height(%d) bit_rate(%d) format(%d = %s)",
+ Debug(1, "Dumping codecpar codec_type(%d) codec_id(%d %s) codec_tag(%d) width(%d) height(%d) bit_rate(%d) format(%d = %s)",
par->codec_type,
par->codec_id,
+ avcodec_get_name(par->codec_id),
par->codec_tag,
par->width,
par->height,
@@ -303,10 +304,11 @@ void zm_dump_codecpar ( const AVCodecParameters *par ) {
#endif
void zm_dump_codec(const AVCodecContext *codec) {
- Debug(1, "Dumping codec_context codec_type(%d) codec_id(%d) width(%d) height(%d) timebase(%d/%d) format(%s)\n"
+ Debug(1, "Dumping codec_context codec_type(%d) codec_id(%d %s) width(%d) height(%d) timebase(%d/%d) format(%s) "
"gop_size %d max_b_frames %d me_cmp %d me_range %d qmin %d qmax %d",
codec->codec_type,
codec->codec_id,
+ avcodec_get_name(codec->codec_id),
codec->width,
codec->height,
codec->time_base.num,
@@ -327,7 +329,6 @@ void zm_dump_codec(const AVCodecContext *codec) {
/* "user interface" functions */
void zm_dump_stream_format(AVFormatContext *ic, int i, int index, int is_output) {
- char buf[256];
Debug(1, "Dumping stream index i(%d) index(%d)", i, index );
int flags = (is_output ? ic->oformat->flags : ic->iformat->flags);
AVStream *st = ic->streams[i];
@@ -350,8 +351,14 @@ void zm_dump_stream_format(AVFormatContext *ic, int i, int index, int is_output)
st->codec_info_nb_frames, codec->frame_size,
st->time_base.num, st->time_base.den
);
+
+#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
+ Debug(1, "codec: %s", avcodec_get_name(st->codecpar->codec_id));
+#else
+ char buf[256];
avcodec_string(buf, sizeof(buf), st->codec, is_output);
Debug(1, "codec: %s", buf);
+#endif
if ( st->sample_aspect_ratio.num && // default
av_cmp_q(st->sample_aspect_ratio, codec->sample_aspect_ratio)
@@ -427,6 +434,35 @@ unsigned int zm_av_packet_ref( AVPacket *dst, AVPacket *src ) {
dst->stream_index = src->stream_index;
return 0;
}
+const char *avcodec_get_name(enum AVCodecID id) {
+ const AVCodecDescriptor *cd;
+ if ( id == AV_CODEC_ID_NONE)
+ return "none";
+ cd = avcodec_descriptor_get(id);
+ if (cd)
+ return cd->name;
+ AVCodec *codec;
+ codec = avcodec_find_decoder(id);
+ if (codec)
+ return codec->name;
+ codec = avcodec_find_encoder(id);
+ if (codec)
+ return codec->name;
+ return "unknown codec";
+}
+
+void av_packet_rescale_ts(
+ AVPacket *pkt,
+ AVRational src_tb,
+ AVRational dst_tb
+ ) {
+ if ( pkt->pts != AV_NOPTS_VALUE)
+ pkt->pts = av_rescale_q(pkt->pts, src_tb, dst_tb);
+ if ( pkt->dts != AV_NOPTS_VALUE)
+ pkt->dts = av_rescale_q(pkt->dts, src_tb, dst_tb);
+ if ( pkt->duration != AV_NOPTS_VALUE)
+ pkt->duration = av_rescale_q(pkt->duration, src_tb, dst_tb);
+}
#endif
bool is_video_stream( AVStream * stream ) {
@@ -477,7 +513,31 @@ bool is_audio_context( AVCodecContext *codec_context ) {
#endif
}
-int zm_receive_frame(AVCodecContext *context, AVFrame *frame, AVPacket &packet) {
+int zm_receive_packet(AVCodecContext *context, AVPacket &packet) {
+#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
+ int ret = avcodec_receive_packet(context, &packet);
+ if ( ret < 0 ) {
+ if ( AVERROR_EOF != ret ) {
+ Error("Error encoding (%d) (%s)", ret,
+ av_err2str(ret));
+ }
+ return 0;
+ }
+ return 1;
+#else
+ int got_packet = 0;
+ int ret = avcodec_encode_audio2(context, &packet, NULL, &got_packet);
+ if ( ret < 0 ) {
+ Error("Error encoding (%d) (%s)", ret, av_err2str(ret));
+ }
+ return got_packet;
+#endif
+} // end int zm_receive_packet(AVCodecContext *context, AVPacket &packet)
+
+int zm_send_packet_receive_frame(
+ AVCodecContext *context,
+ AVFrame *frame,
+ AVPacket &packet) {
int ret;
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
if ( (ret = avcodec_send_packet(context, &packet)) < 0 ) {
@@ -487,8 +547,14 @@ int zm_receive_frame(AVCodecContext *context, AVFrame *frame, AVPacket &packet)
}
if ( (ret = avcodec_receive_frame(context, frame)) < 0 ) {
- Error("Unable to send packet %s, continuing",
- av_make_error_string(ret).c_str());
+ if ( AVERROR(EAGAIN) == ret ) {
+ // The codec may need more samples than it has, perfectly valid
+ Debug(2, "Codec not ready to give us a frame");
+ return 0;
+ } else {
+ Error("Could not recieve frame (error %d = '%s')", ret,
+ av_make_error_string(ret).c_str());
+ }
return ret;
}
# else
@@ -505,29 +571,31 @@ int zm_receive_frame(AVCodecContext *context, AVFrame *frame, AVPacket &packet)
}
} // end while !frameComplete
#endif
- return 0;
-} // end int zm_receive_frame(AVCodecContext *context, AVFrame *frame, AVPacket &packet)
+ return 1;
+} // end int zm_send_packet_receive_frame(AVCodecContext *context, AVFrame *frame, AVPacket &packet)
-int zm_send_frame(AVCodecContext *ctx, AVFrame *frame, AVPacket &packet) {
+/* Returns < 0 on error, 0 if codec not ready, 1 on success
+ */
+int zm_send_frame_receive_packet(AVCodecContext *ctx, AVFrame *frame, AVPacket &packet) {
int ret;
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
if ( (ret = avcodec_send_frame(ctx, frame)) < 0 ) {
Error("Could not send frame (error '%s')",
av_make_error_string(ret).c_str());
- zm_av_packet_unref(&packet);
- return 0;
+ return ret;
}
if ( (ret = avcodec_receive_packet(ctx, &packet)) < 0 ) {
if ( AVERROR(EAGAIN) == ret ) {
// The codec may need more samples than it has, perfectly valid
Debug(2, "Codec not ready to give us a packet");
+ return 0;
} else {
Error("Could not recieve packet (error %d = '%s')", ret,
av_make_error_string(ret).c_str());
}
zm_av_packet_unref(&packet);
- return 0;
+ return ret;
}
#else
int data_present;
@@ -536,7 +604,7 @@ int zm_send_frame(AVCodecContext *ctx, AVFrame *frame, AVPacket &packet) {
Error("Could not encode frame (error '%s')",
av_make_error_string(ret).c_str());
zm_av_packet_unref(&packet);
- return 0;
+ return ret;
}
if ( !data_present ) {
Debug(2, "Not ready to out a frame yet.");
@@ -545,7 +613,7 @@ int zm_send_frame(AVCodecContext *ctx, AVFrame *frame, AVPacket &packet) {
}
#endif
return 1;
-} // wend zm_send_frame
+} // end int zm_send_frame_receive_packet
void dumpPacket(AVStream *stream, AVPacket *pkt, const char *text) {
char b[10240];
@@ -600,3 +668,117 @@ void dumpPacket(AVPacket *pkt, const char *text) {
pkt->duration);
Debug(2, "%s:%d:%s: %s", __FILE__, __LINE__, text, b);
}
+
+void zm_packet_copy_rescale_ts(const AVPacket *ipkt, AVPacket *opkt, const AVRational src_tb, const AVRational dst_tb) {
+ opkt->pts = ipkt->pts;
+ opkt->dts = ipkt->dts;
+ opkt->duration = ipkt->duration;
+ av_packet_rescale_ts(opkt, src_tb, dst_tb);
+}
+
+#if defined(HAVE_LIBSWRESAMPLE) || defined(HAVE_LIBAVRESAMPLE)
+int zm_resample_audio(
+#if defined(HAVE_LIBSWRESAMPLE)
+ SwrContext *resample_ctx,
+#else
+#if defined(HAVE_LIBAVRESAMPLE)
+ AVAudioResampleContext *resample_ctx,
+#endif
+#endif
+ AVFrame *in_frame,
+ AVFrame *out_frame
+ ) {
+#if defined(HAVE_LIBSWRESAMPLE)
+ // Resample the in_frame into the audioSampleBuffer until we process the whole
+ // decoded data. Note: pts does not survive resampling or converting
+ Debug(2, "Converting %d to %d samples using swresample",
+ in_frame->nb_samples, out_frame->nb_samples);
+ int ret = swr_convert_frame(resample_ctx, out_frame, in_frame);
+ if ( ret < 0 ) {
+ Error("Could not resample frame (error '%s')",
+ av_make_error_string(ret).c_str());
+ return 0;
+ }
+ Debug(3,"swr_get_delay %d",
+ swr_get_delay(resample_ctx, out_frame->sample_rate));
+#else
+#if defined(HAVE_LIBAVRESAMPLE)
+ int ret = avresample_convert(resample_ctx, NULL, 0, 0, in_frame->data,
+ 0, in_frame->nb_samples);
+ if ( ret < 0 ) {
+ Error("Could not resample frame (error '%s')",
+ av_make_error_string(ret).c_str());
+ return 0;
+ }
+ int samples_available = avresample_available(resample_ctx);
+ if ( samples_available < out_frame->nb_samples ) {
+ Debug(1, "Not enough samples yet (%d)", samples_available);
+ return 0;
+ }
+
+ // Read a frame audio data from the resample fifo
+ if ( avresample_read(resample_ctx, out_frame->data, out_frame->nb_samples) !=
+ out_frame->nb_samples) {
+ Warning("Error reading resampled audio.");
+ return 0;
+ }
+#endif
+#endif
+ zm_dump_frame(out_frame, "Out frame after resample");
+ return 1;
+}
+
+int zm_resample_get_delay(
+#if defined(HAVE_LIBSWRESAMPLE)
+ SwrContext *resample_ctx,
+#else
+#if defined(HAVE_LIBAVRESAMPLE)
+ AVAudioResampleContext *resample_ctx,
+#endif
+#endif
+ int time_base
+ ) {
+#if defined(HAVE_LIBSWRESAMPLE)
+ return swr_get_delay(resample_ctx, time_base);
+#else
+#if defined(HAVE_LIBAVRESAMPLE)
+ return avresample_available(resample_ctx);
+#endif
+#endif
+}
+#endif
+
+int zm_add_samples_to_fifo(AVAudioFifo *fifo, AVFrame *frame) {
+ int ret = av_audio_fifo_realloc(fifo, av_audio_fifo_size(fifo) + frame->nb_samples);
+ if ( ret < 0 ) {
+ Error("Could not reallocate FIFO to %d samples",
+ av_audio_fifo_size(fifo) + frame->nb_samples);
+ return 0;
+ }
+ /** Store the new samples in the FIFO buffer. */
+ ret = av_audio_fifo_write(fifo, (void **)frame->data, frame->nb_samples);
+ if ( ret < frame->nb_samples ) {
+ Error("Could not write data to FIFO. %d written, expecting %d. Reason %s",
+ ret, frame->nb_samples, av_make_error_string(ret).c_str());
+ return 0;
+ }
+ return 1;
+}
+
+int zm_get_samples_from_fifo(AVAudioFifo *fifo, AVFrame *frame) {
+ // AAC requires 1024 samples per encode. Our input tends to be something else, so need to buffer them.
+ if ( frame->nb_samples > av_audio_fifo_size(fifo) ) {
+ Debug(1, "Not enough samples in fifo for AAC codec frame_size %d > fifo size %d",
+ frame->nb_samples, av_audio_fifo_size(fifo));
+ return 0;
+ }
+
+ if ( av_audio_fifo_read(fifo, (void **)frame->data, frame->nb_samples) < frame->nb_samples ) {
+ Error("Could not read data from FIFO");
+ return 0;
+ }
+//out_frame->nb_samples = frame_size;
+ zm_dump_frame(frame, "Out frame after fifo read");
+ return 1;
+}
+
diff --git a/src/zm_ffmpeg.h b/src/zm_ffmpeg.h
index f6443f797..c65bb38a0 100644
--- a/src/zm_ffmpeg.h
+++ b/src/zm_ffmpeg.h
@@ -24,6 +24,14 @@
extern "C" {
+#ifdef HAVE_LIBSWRESAMPLE
+ #include "libswresample/swresample.h"
+#else
+ #ifdef HAVE_LIBAVRESAMPLE
+ #include "libavresample/avresample.h"
+ #endif
+#endif
+
// AVUTIL
#if HAVE_LIBAVUTIL_AVUTIL_H
#include "libavutil/avassert.h"
@@ -31,6 +39,7 @@ extern "C" {
#include
#include
#include
+#include "libavutil/audio_fifo.h"
/* LIBAVUTIL_VERSION_CHECK checks for the right version of libav and FFmpeg
* The original source is vlc (in modules/codec/avcodec/avcommon_compat.h)
@@ -299,23 +308,6 @@ void zm_dump_codec(const AVCodecContext *codec);
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
void zm_dump_codecpar(const AVCodecParameters *par);
#endif
-#if LIBAVCODEC_VERSION_CHECK(56, 8, 0, 60, 100)
-#define zm_dump_frame(frame, text) Debug(1, "%s: format %d %s sample_rate %" PRIu32 " nb_samples %d channels %d" \
- " duration %" PRId64 \
- " layout %d pts %" PRId64 " pkt_pts %" PRId64 " pkt_dts %" PRId64, \
- text, \
- frame->format, \
- av_get_sample_fmt_name((AVSampleFormat)frame->format), \
- frame->sample_rate, \
- frame->nb_samples, \
- frame->channels, \
- frame->pkt_duration, \
- frame->channel_layout, \
- frame->pts, \
- frame->pkt_pts, \
- frame->pkt_dts \
- );
-#else
#define zm_dump_frame(frame, text) Debug(1, "%s: format %d %s sample_rate %" PRIu32 " nb_samples %d channels %d" \
" duration %" PRId64 \
" layout %d pts %" PRId64, \
@@ -329,8 +321,6 @@ void zm_dump_codecpar(const AVCodecParameters *par);
frame->pts \
);
-#endif
-
#define zm_dump_video_frame(frame,text) Debug(1, "%s: format %d %s %dx%d linesize:%dx%d pts: %" PRId64, \
text, \
frame->format, \
@@ -347,6 +337,9 @@ void zm_dump_codecpar(const AVCodecParameters *par);
#else
unsigned int zm_av_packet_ref( AVPacket *dst, AVPacket *src );
#define zm_av_packet_unref( packet ) av_free_packet( packet )
+ const char *avcodec_get_name(AVCodecID id);
+
+ void av_packet_rescale_ts(AVPacket *pkt, AVRational src_tb, AVRational dst_tb);
#endif
#if LIBAVCODEC_VERSION_CHECK(52, 23, 0, 23, 0)
#define zm_avcodec_decode_video( context, rawFrame, frameComplete, packet ) avcodec_decode_video2( context, rawFrame, frameComplete, packet )
@@ -371,9 +364,42 @@ bool is_audio_stream(AVStream *);
bool is_video_context(AVCodec *);
bool is_audio_context(AVCodec *);
-int zm_receive_frame(AVCodecContext *context, AVFrame *frame, AVPacket &packet);
-int zm_send_frame(AVCodecContext *context, AVFrame *frame, AVPacket &packet);
+int zm_receive_packet(AVCodecContext *context, AVPacket &packet);
+
+int zm_send_packet_receive_frame(AVCodecContext *context, AVFrame *frame, AVPacket &packet);
+int zm_send_frame_receive_packet(AVCodecContext *context, AVFrame *frame, AVPacket &packet);
void dumpPacket(AVStream *, AVPacket *,const char *text="");
void dumpPacket(AVPacket *,const char *text="");
+void zm_packet_copy_rescale_ts(const AVPacket *ipkt, AVPacket *opkt, const AVRational src_tb, const AVRational dst_tb);
+
+#if defined(HAVE_LIBSWRESAMPLE) || defined(HAVE_LIBAVRESAMPLE)
+int zm_resample_audio(
+#if defined(HAVE_LIBSWRESAMPLE)
+ SwrContext *resample_ctx,
+#else
+#if defined(HAVE_LIBAVRESAMPLE)
+ AVAudioResampleContext *resample_ctx,
+#endif
+#endif
+ AVFrame *in_frame,
+ AVFrame *out_frame
+ );
+int zm_resample_get_delay(
+#if defined(HAVE_LIBSWRESAMPLE)
+ SwrContext *resample_ctx,
+#else
+#if defined(HAVE_LIBAVRESAMPLE)
+ AVAudioResampleContext *resample_ctx,
+#endif
+#endif
+ int time_base
+ );
+
+#endif
+
+int zm_add_samples_to_fifo(AVAudioFifo *fifo, AVFrame *frame);
+int zm_get_samples_from_fifo(AVAudioFifo *fifo, AVFrame *frame);
+
+
#endif // ZM_FFMPEG_H
diff --git a/src/zm_ffmpeg_camera.cpp b/src/zm_ffmpeg_camera.cpp
index c9298fe77..cf55a75d4 100644
--- a/src/zm_ffmpeg_camera.cpp
+++ b/src/zm_ffmpeg_camera.cpp
@@ -19,6 +19,7 @@
#include "zm.h"
#include "zm_signal.h"
+#include "zm_utils.h"
#if HAVE_LIBAVFORMAT
@@ -35,11 +36,6 @@ extern "C" {
#define AV_ERROR_MAX_STRING_SIZE 64
#endif
-#ifdef SOLARIS
-#include // for ESRCH
-#include
-#include
-#endif
#include
@@ -260,8 +256,8 @@ int FfmpegCamera::Capture(Image &image) {
&&
(keyframe || have_video_keyframe)
) {
- ret = zm_receive_frame(mVideoCodecContext, mRawFrame, packet);
- if ( ret < 0 ) {
+ ret = zm_send_packet_receive_frame(mVideoCodecContext, mRawFrame, packet);
+ if ( ret <= 0 ) {
Error("Unable to get frame at frame %d: %s, continuing",
frameCount, av_make_error_string(ret).c_str());
zm_av_packet_unref(&packet);
@@ -337,24 +333,27 @@ int FfmpegCamera::OpenFfmpeg() {
}
// Set transport method as specified by method field, rtpUni is default
- const std::string method = Method();
- if ( method == "rtpMulti" ) {
- ret = av_dict_set(&opts, "rtsp_transport", "udp_multicast", 0);
- } else if ( method == "rtpRtsp" ) {
- ret = av_dict_set(&opts, "rtsp_transport", "tcp", 0);
- } else if ( method == "rtpRtspHttp" ) {
- ret = av_dict_set(&opts, "rtsp_transport", "http", 0);
- } else if ( method == "rtpUni" ) {
- ret = av_dict_set(&opts, "rtsp_transport", "udp", 0);
- } else {
- Warning("Unknown method (%s)", method.c_str());
- }
+ std::string protocol = mPath.substr(0, 4);
+ string_toupper(protocol);
+ if ( protocol == "RTSP" ) {
+ const std::string method = Method();
+ if ( method == "rtpMulti" ) {
+ ret = av_dict_set(&opts, "rtsp_transport", "udp_multicast", 0);
+ } else if ( method == "rtpRtsp" ) {
+ ret = av_dict_set(&opts, "rtsp_transport", "tcp", 0);
+ } else if ( method == "rtpRtspHttp" ) {
+ ret = av_dict_set(&opts, "rtsp_transport", "http", 0);
+ } else if ( method == "rtpUni" ) {
+ ret = av_dict_set(&opts, "rtsp_transport", "udp", 0);
+ } else {
+ Warning("Unknown method (%s)", method.c_str());
+ }
+ if ( ret < 0 ) {
+ Warning("Could not set rtsp_transport method '%s'", method.c_str());
+ }
+ } // end if RTSP
// #av_dict_set(&opts, "timeout", "10000000", 0); // in microseconds.
- if ( ret < 0 ) {
- Warning("Could not set rtsp_transport method '%s'", method.c_str());
- }
-
Debug(1, "Calling avformat_open_input for %s", mPath.c_str());
mFormatContext = avformat_alloc_context();
@@ -650,6 +649,9 @@ int FfmpegCamera::OpenFfmpeg() {
) {
Warning("Monitor dimensions are %dx%d but camera is sending %dx%d",
width, height, mVideoCodecContext->width, mVideoCodecContext->height);
+ } else {
+ Warning("Monitor dimensions are %dx%d and camera is sending %dx%d",
+ width, height, mVideoCodecContext->width, mVideoCodecContext->height);
}
mCanCapture = true;
@@ -952,8 +954,8 @@ int FfmpegCamera::CaptureAndRecord(
}
} // end if keyframe or have_video_keyframe
- ret = zm_receive_frame(mVideoCodecContext, mRawFrame, packet);
- if ( ret < 0 ) {
+ ret = zm_send_packet_receive_frame(mVideoCodecContext, mRawFrame, packet);
+ if ( ret <= 0 ) {
Warning("Unable to receive frame %d: %s. error count is %d",
frameCount, av_make_error_string(ret).c_str(), error_count);
error_count += 1;
diff --git a/src/zm_ffmpeg_input.cpp b/src/zm_ffmpeg_input.cpp
index 03d89348d..ab7cbe8d3 100644
--- a/src/zm_ffmpeg_input.cpp
+++ b/src/zm_ffmpeg_input.cpp
@@ -137,8 +137,8 @@ AVFrame *FFmpeg_Input::get_frame(int stream_id) {
} else {
frame = zm_av_frame_alloc();
}
- ret = zm_receive_frame(context, frame, packet);
- if ( ret < 0 ) {
+ ret = zm_send_packet_receive_frame(context, frame, packet);
+ if ( ret <= 0 ) {
Error("Unable to decode frame at frame %d: %s, continuing",
streams[packet.stream_index].frame_count, av_make_error_string(ret).c_str());
zm_av_packet_unref(&packet);
diff --git a/src/zm_file_camera.cpp b/src/zm_file_camera.cpp
index 1bc861b23..a7883c5d5 100644
--- a/src/zm_file_camera.cpp
+++ b/src/zm_file_camera.cpp
@@ -1,31 +1,27 @@
//
// ZoneMinder File Camera Class Implementation, $Date$, $Revision$
// Copyright (C) 2001-2008 Philip Coombes
-//
+//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
-//
+//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
-//
+//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-//
+//
#include
#include
#include
#include
#include
-#include
-#include
-#include
-#include
#include
#include
#include
@@ -45,8 +41,20 @@ FileCamera::FileCamera(
int p_hue,
int p_colour,
bool p_capture,
- bool p_record_audio
- ) : Camera( p_id, FILE_SRC, p_width, p_height, p_colours, ZM_SUBPIX_ORDER_DEFAULT_FOR_COLOUR(p_colours), p_brightness, p_contrast, p_hue, p_colour, p_capture, p_record_audio )
+ bool p_record_audio)
+ : Camera(
+ p_id,
+ FILE_SRC,
+ p_width,
+ p_height,
+ p_colours,
+ ZM_SUBPIX_ORDER_DEFAULT_FOR_COLOUR(p_colours),
+ p_brightness,
+ p_contrast,
+ p_hue,
+ p_colour,
+ p_capture,
+ p_record_audio)
{
strncpy( path, p_path, sizeof(path)-1 );
if ( capture ) {
@@ -62,8 +70,7 @@ FileCamera::~FileCamera() {
void FileCamera::Initialise() {
if ( !path[0] ) {
- Error( "No path specified for file image" );
- exit( -1 );
+ Fatal("No path specified for file image");
}
}
@@ -72,21 +79,25 @@ void FileCamera::Terminate() {
int FileCamera::PreCapture() {
struct stat statbuf;
- if ( stat( path, &statbuf ) < 0 ) {
- Error( "Can't stat %s: %s", path, strerror(errno) );
- return( -1 );
+ if ( stat(path, &statbuf) < 0 ) {
+ Error("Can't stat %s: %s", path, strerror(errno));
+ return -1;
}
+ bytes += statbuf.st_size;
+ // This waits until 1 second has passed since it was modified. Effectively limiting fps to 60.
+ // Which is kinda bogus. If we were writing to this jpg constantly faster than we are monitoring it here
+ // we would never break out of this loop
while ( (time(0) - statbuf.st_mtime) < 1 ) {
- usleep( 100000 );
+ usleep(100000);
}
- return( 0 );
+ return 0;
}
-int FileCamera::Capture( Image &image ) {
- return( image.ReadJpeg( path, colours, subpixelorder )?1:-1 );
+int FileCamera::Capture(Image &image) {
+ return image.ReadJpeg(path, colours, subpixelorder)?1:-1;
}
int FileCamera::PostCapture() {
- return( 0 );
+ return 0;
}
diff --git a/src/zm_image.cpp b/src/zm_image.cpp
index f8ad1ab70..9cf4ada94 100644
--- a/src/zm_image.cpp
+++ b/src/zm_image.cpp
@@ -1,21 +1,21 @@
//
// ZoneMinder Image Class Implementation, $Date$, $Revision$
// Copyright (C) 2001-2008 Philip Coombes
-//
+//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
-//
+//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
-//
+//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-//
+//
#include "zm.h"
#include "zm_font.h"
#include "zm_bigfont.h"
@@ -126,7 +126,7 @@ Image::Image( const char *filename ) {
height = 0;
pixels = 0;
colours = 0;
- subpixelorder = 0;
+ subpixelorder = 0;
size = 0;
allocation = 0;
buffer = 0;
@@ -279,7 +279,7 @@ void Image::Initialise() {
fptr_blend = &std_blend;
Debug(4,"Blend: Using standard blend function");
}
-
+
__attribute__((aligned(64))) uint8_t blend1[128] = {
86,58,54,63,149,62,209,34,148,46,186,176,9,236,193,254,113,146,228,220,123,164,92,98,9,72,67,156,63,118,96,167,
48,224,106,176,201,245,223,219,198,50,100,31,68,77,33,76,166,90,254,128,191,82,84,32,3,171,147,248,14,196,141,179,
@@ -413,7 +413,7 @@ void Image::Initialise() {
}
}
- /*
+ /*
SSSE3 deinterlacing functions were removed because they were usually equal
or slower than the standard code (compiled with -O2 or better)
The function is too complicated to be vectorized efficiently on SSSE3
@@ -528,7 +528,7 @@ uint8_t* Image::WriteBuffer(const unsigned int p_width, const unsigned int p_hei
size = newsize;
} // end if need to re-alloc buffer
- return buffer;
+ return buffer;
}
/* Assign an existing buffer to the image instead of copying from a source buffer. The goal is to reduce the amount of memory copying and increase efficiency and buffer reusing. */
@@ -623,7 +623,7 @@ void Image::Assign(const unsigned int p_width, const unsigned int p_height, cons
return;
}
} else {
- if ( new_size > allocation || !buffer ) {
+ if ( new_size > allocation || !buffer ) {
DumpImgBuffer();
AllocImgBuffer(new_size);
}
@@ -663,7 +663,7 @@ void Image::Assign( const Image &image ) {
return;
}
} else {
- if(new_size > allocation || !buffer) {
+ if(new_size > allocation || !buffer) {
// DumpImgBuffer(); This is also done in AllocImgBuffer
AllocImgBuffer(new_size);
}
@@ -802,25 +802,25 @@ bool Image::ReadRaw( const char *filename ) {
return false;
}
- fclose( infile );
+ fclose(infile);
return true;
}
-bool Image::WriteRaw( const char *filename ) const {
+bool Image::WriteRaw(const char *filename) const {
FILE *outfile;
- if ( (outfile = fopen( filename, "wb" )) == NULL ) {
- Error( "Can't open %s: %s", filename, strerror(errno) );
+ if ( (outfile = fopen(filename, "wb")) == NULL ) {
+ Error("Can't open %s: %s", filename, strerror(errno));
return false;
}
if ( fwrite( buffer, size, 1, outfile ) != 1 ) {
- Error( "Unable to write to '%s': %s", filename, strerror(errno) );
- fclose( outfile );
+ Error("Unable to write to '%s': %s", filename, strerror(errno));
+ fclose(outfile);
return false;
}
- fclose( outfile );
+ fclose(outfile);
return true;
}
@@ -885,13 +885,13 @@ bool Image::ReadJpeg(const char *filename, unsigned int p_colours, unsigned int
{
#ifdef JCS_EXTENSIONS
new_colours = ZM_COLOUR_RGB32;
- if(p_subpixelorder == ZM_SUBPIX_ORDER_BGRA) {
+ if ( p_subpixelorder == ZM_SUBPIX_ORDER_BGRA ) {
cinfo->out_color_space = JCS_EXT_BGRX;
new_subpixelorder = ZM_SUBPIX_ORDER_BGRA;
- } else if(p_subpixelorder == ZM_SUBPIX_ORDER_ARGB) {
+ } else if ( p_subpixelorder == ZM_SUBPIX_ORDER_ARGB ) {
cinfo->out_color_space = JCS_EXT_XRGB;
new_subpixelorder = ZM_SUBPIX_ORDER_ARGB;
- } else if(p_subpixelorder == ZM_SUBPIX_ORDER_ABGR) {
+ } else if ( p_subpixelorder == ZM_SUBPIX_ORDER_ABGR ) {
cinfo->out_color_space = JCS_EXT_XBGR;
new_subpixelorder = ZM_SUBPIX_ORDER_ABGR;
} else {
@@ -899,7 +899,7 @@ bool Image::ReadJpeg(const char *filename, unsigned int p_colours, unsigned int
cinfo->out_color_space = JCS_EXT_RGBX;
new_subpixelorder = ZM_SUBPIX_ORDER_RGBA;
}
- break;
+ break;
#else
Warning("libjpeg-turbo is required for reading a JPEG directly into a RGB32 buffer, reading into a RGB24 buffer instead.");
#endif
@@ -908,13 +908,13 @@ bool Image::ReadJpeg(const char *filename, unsigned int p_colours, unsigned int
default:
{
new_colours = ZM_COLOUR_RGB24;
- if(p_subpixelorder == ZM_SUBPIX_ORDER_BGR) {
-#ifdef JCS_EXTENSIONS
- cinfo->out_color_space = JCS_EXT_BGR;
+ if ( p_subpixelorder == ZM_SUBPIX_ORDER_BGR ) {
+#ifdef JCS_EXTENSIONS
+ cinfo->out_color_space = JCS_EXT_BGR;
new_subpixelorder = ZM_SUBPIX_ORDER_BGR;
#else
- Warning("libjpeg-turbo is required for reading a JPEG directly into a BGR24 buffer, reading into a RGB24 buffer instead.");
- cinfo->out_color_space = JCS_RGB;
+ Warning("libjpeg-turbo is required for reading a JPEG directly into a BGR24 buffer, reading into a RGB24 buffer instead.");
+ cinfo->out_color_space = JCS_RGB;
new_subpixelorder = ZM_SUBPIX_ORDER_RGB;
#endif
} else {
@@ -933,28 +933,27 @@ cinfo->out_color_space = JCS_RGB;
}
}
- if(WriteBuffer(new_width, new_height, new_colours, new_subpixelorder) == NULL) {
+ if ( WriteBuffer(new_width, new_height, new_colours, new_subpixelorder) == NULL ) {
Error("Failed requesting writeable buffer for reading JPEG image.");
- jpeg_abort_decompress( cinfo );
- fclose( infile );
- return( false );
+ jpeg_abort_decompress(cinfo);
+ fclose(infile);
+ return false;
}
- jpeg_start_decompress( cinfo );
+ jpeg_start_decompress(cinfo);
JSAMPROW row_pointer; /* pointer to a single row */
int row_stride = width * colours; /* physical row width in buffer */
- while ( cinfo->output_scanline < cinfo->output_height )
- {
+ while ( cinfo->output_scanline < cinfo->output_height ) {
row_pointer = &buffer[cinfo->output_scanline * row_stride];
- jpeg_read_scanlines( cinfo, &row_pointer, 1 );
+ jpeg_read_scanlines(cinfo, &row_pointer, 1);
}
- jpeg_finish_decompress( cinfo );
+ jpeg_finish_decompress(cinfo);
- fclose( infile );
+ fclose(infile);
- return( true );
+ return true;
}
// Multiple calling formats to permit inclusion (or not) of non blocking, quality_override and timestamp (exif), with suitable defaults.
@@ -977,7 +976,7 @@ bool Image::WriteJpeg(const char *filename, int quality_override, struct timeval
return Image::WriteJpeg(filename, quality_override, timestamp, false);
}
bool Image::WriteJpeg(const char *filename, int quality_override, struct timeval timestamp, bool on_blocking_abort) const {
- if ( config.colour_jpeg_files && colours == ZM_COLOUR_GRAY8 ) {
+ if ( config.colour_jpeg_files && (colours == ZM_COLOUR_GRAY8) ) {
Image temp_image(*this);
temp_image.Colourise(ZM_COLOUR_RGB24, ZM_SUBPIX_ORDER_RGB);
return temp_image.WriteJpeg(filename, quality_override, timestamp, on_blocking_abort);
@@ -985,66 +984,63 @@ bool Image::WriteJpeg(const char *filename, int quality_override, struct timeval
int quality = quality_override?quality_override:config.jpeg_file_quality;
struct jpeg_compress_struct *cinfo = writejpg_ccinfo[quality];
- FILE *outfile =NULL;
+ FILE *outfile = NULL;
static int raw_fd = 0;
bool need_create_comp = false;
raw_fd = 0;
if ( !cinfo ) {
cinfo = writejpg_ccinfo[quality] = new jpeg_compress_struct;
- cinfo->err = jpeg_std_error( &jpg_err.pub );
- jpeg_create_compress( cinfo );
- need_create_comp=true;
+ cinfo->err = jpeg_std_error(&jpg_err.pub);
+ jpeg_create_compress(cinfo);
+ need_create_comp = true;
}
- if (! on_blocking_abort) {
- jpg_err.pub.error_exit = zm_jpeg_error_exit;
- jpg_err.pub.emit_message = zm_jpeg_emit_message;
+ if ( !on_blocking_abort ) {
+ jpg_err.pub.error_exit = zm_jpeg_error_exit;
+ jpg_err.pub.emit_message = zm_jpeg_emit_message;
} else {
jpg_err.pub.error_exit = zm_jpeg_error_silent;
jpg_err.pub.emit_message = zm_jpeg_emit_silence;
- if (setjmp( jpg_err.setjmp_buffer ) ) {
- jpeg_abort_compress( cinfo );
- Debug( 5, "Aborted a write mid-stream and %s and %d", (outfile == NULL) ? "closing file" : "file not opened", raw_fd );
- if (raw_fd)
+ if ( setjmp(jpg_err.setjmp_buffer) ) {
+ jpeg_abort_compress(cinfo);
+ Debug(1, "Aborted a write mid-stream and %s and %d", (outfile == NULL) ? "closing file" : "file not opened", raw_fd);
+ if ( raw_fd )
close(raw_fd);
- if (outfile)
- fclose( outfile );
- return ( false );
+ if ( outfile )
+ fclose(outfile);
+ return false;
}
}
- if (need_create_comp)
- jpeg_create_compress( cinfo );
+ if ( need_create_comp )
+ jpeg_create_compress(cinfo);
- if (! on_blocking_abort) {
+ if ( !on_blocking_abort ) {
if ( (outfile = fopen(filename, "wb")) == NULL ) {
- Error( "Can't open %s for writing: %s", filename, strerror(errno) );
+ Error("Can't open %s for writing: %s", filename, strerror(errno));
return false;
}
} else {
- raw_fd = open(filename,O_WRONLY|O_NONBLOCK|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
- if (raw_fd < 0)
- return ( false );
- outfile = fdopen(raw_fd,"wb");
- if (outfile == NULL) {
+ raw_fd = open(filename, O_WRONLY|O_NONBLOCK|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
+ if ( raw_fd < 0 )
+ return false;
+ outfile = fdopen(raw_fd, "wb");
+ if ( outfile == NULL ) {
close(raw_fd);
- return( false );
+ return false;
}
}
- jpeg_stdio_dest( cinfo, outfile );
+ jpeg_stdio_dest(cinfo, outfile);
cinfo->image_width = width; /* image width and height, in pixels */
cinfo->image_height = height;
- switch(colours) {
+ switch (colours) {
case ZM_COLOUR_GRAY8:
- {
cinfo->input_components = 1;
cinfo->in_color_space = JCS_GRAYSCALE;
break;
- }
case ZM_COLOUR_RGB32:
- {
#ifdef JCS_EXTENSIONS
cinfo->input_components = 4;
if ( subpixelorder == ZM_SUBPIX_ORDER_BGRA ) {
@@ -1056,27 +1052,25 @@ bool Image::WriteJpeg(const char *filename, int quality_override, struct timeval
} else {
/* Assume RGBA */
cinfo->in_color_space = JCS_EXT_RGBX;
- }
+ }
+ break;
#else
Error("libjpeg-turbo is required for JPEG encoding directly from RGB32 source");
- jpeg_abort_compress( cinfo );
+ jpeg_abort_compress(cinfo);
fclose(outfile);
return false;
#endif
- break;
- }
case ZM_COLOUR_RGB24:
default:
- {
cinfo->input_components = 3;
if ( subpixelorder == ZM_SUBPIX_ORDER_BGR) {
-#ifdef JCS_EXTENSIONS
+#ifdef JCS_EXTENSIONS
cinfo->in_color_space = JCS_EXT_BGR;
#else
Error("libjpeg-turbo is required for JPEG encoding directly from BGR24 source");
- jpeg_abort_compress( cinfo );
+ jpeg_abort_compress(cinfo);
fclose(outfile);
- return false;
+ return false;
#endif
} else {
/* Assume RGB */
@@ -1090,16 +1084,15 @@ cinfo->out_color_space = JCS_RGB;
cinfo->in_color_space = JCS_RGB;
}
break;
- }
- }
+ } // end switch(colours)
- jpeg_set_defaults( cinfo );
- jpeg_set_quality( cinfo, quality, FALSE );
+ jpeg_set_defaults(cinfo);
+ jpeg_set_quality(cinfo, quality, FALSE);
cinfo->dct_method = JDCT_FASTEST;
- jpeg_start_compress( cinfo, TRUE );
+ jpeg_start_compress(cinfo, TRUE);
if ( config.add_jpeg_comments && text[0] ) {
- jpeg_write_marker( cinfo, JPEG_COM, (const JOCTET *)text, strlen(text) );
+ jpeg_write_marker(cinfo, JPEG_COM, (const JOCTET *)text, strlen(text));
}
// If we have a non-zero time (meaning a parameter was passed in), then form a simple exif segment with that time as DateTimeOriginal and SubsecTimeOriginal
// No timestamp just leave off the exif section.
@@ -1123,14 +1116,14 @@ cinfo->out_color_space = JCS_RGB;
0xff, 0x00 };
memcpy(&exiftimes[EXIFTIMES_OFFSET], timebuf,EXIFTIMES_LEN);
memcpy(&exiftimes[EXIFTIMES_MS_OFFSET], msbuf, EXIFTIMES_MS_LEN);
- jpeg_write_marker( cinfo, EXIF_CODE, (const JOCTET *)exiftimes, sizeof(exiftimes) );
+ jpeg_write_marker(cinfo, EXIF_CODE, (const JOCTET *)exiftimes, sizeof(exiftimes));
}
JSAMPROW row_pointer; /* pointer to a single row */
int row_stride = cinfo->image_width * colours; /* physical row width in buffer */
while ( cinfo->next_scanline < cinfo->image_height ) {
row_pointer = &buffer[cinfo->next_scanline * row_stride];
- jpeg_write_scanlines( cinfo, &row_pointer, 1 );
+ jpeg_write_scanlines(cinfo, &row_pointer, 1);
}
jpeg_finish_compress(cinfo);
@@ -1140,13 +1133,16 @@ cinfo->out_color_space = JCS_RGB;
return true;
}
-bool Image::DecodeJpeg( const JOCTET *inbuffer, int inbuffer_size, unsigned int p_colours, unsigned int p_subpixelorder)
+bool Image::DecodeJpeg(
+ const JOCTET *inbuffer,
+ int inbuffer_size,
+ unsigned int p_colours,
+ unsigned int p_subpixelorder)
{
unsigned int new_width, new_height, new_colours, new_subpixelorder;
struct jpeg_decompress_struct *cinfo = decodejpg_dcinfo;
- if ( !cinfo )
- {
+ if ( !cinfo ) {
cinfo = decodejpg_dcinfo = new jpeg_decompress_struct;
cinfo->err = jpeg_std_error( &jpg_err.pub );
jpg_err.pub.error_exit = zm_jpeg_error_exit;
@@ -1154,25 +1150,24 @@ bool Image::DecodeJpeg( const JOCTET *inbuffer, int inbuffer_size, unsigned int
jpeg_create_decompress( cinfo );
}
- if ( setjmp( jpg_err.setjmp_buffer ) )
- {
- jpeg_abort_decompress( cinfo );
- return( false );
+ if ( setjmp(jpg_err.setjmp_buffer) ) {
+ jpeg_abort_decompress(cinfo);
+ return false;
}
- zm_jpeg_mem_src( cinfo, inbuffer, inbuffer_size );
+ zm_jpeg_mem_src(cinfo, inbuffer, inbuffer_size);
- jpeg_read_header( cinfo, TRUE );
+ jpeg_read_header(cinfo, TRUE);
- if ( cinfo->num_components != 1 && cinfo->num_components != 3 ) {
- Error( "Unexpected colours when reading jpeg image: %d", colours );
- jpeg_abort_decompress( cinfo );
- return( false );
+ if ( (cinfo->num_components != 1) && (cinfo->num_components != 3) ) {
+ Error("Unexpected colours when reading jpeg image: %d", colours);
+ jpeg_abort_decompress(cinfo);
+ return false;
}
/* Check if the image has at least one huffman table defined. If not, use the standard ones */
/* This is required for the MJPEG capture palette of USB devices */
- if(cinfo->dc_huff_tbl_ptrs[0] == NULL) {
+ if ( cinfo->dc_huff_tbl_ptrs[0] == NULL ) {
zm_use_std_huff_tables(cinfo);
}
@@ -1180,28 +1175,26 @@ bool Image::DecodeJpeg( const JOCTET *inbuffer, int inbuffer_size, unsigned int
new_height = cinfo->image_height;
if ( width != new_width || height != new_height ) {
- Debug(9,"Image dimensions differ. Old: %ux%u New: %ux%u",width,height,new_width,new_height);
+ Debug(9, "Image dimensions differ. Old: %ux%u New: %ux%u",
+ width, height, new_width, new_height);
}
- switch(p_colours) {
+ switch (p_colours) {
case ZM_COLOUR_GRAY8:
- {
cinfo->out_color_space = JCS_GRAYSCALE;
new_colours = ZM_COLOUR_GRAY8;
new_subpixelorder = ZM_SUBPIX_ORDER_NONE;
break;
- }
case ZM_COLOUR_RGB32:
- {
#ifdef JCS_EXTENSIONS
new_colours = ZM_COLOUR_RGB32;
- if(p_subpixelorder == ZM_SUBPIX_ORDER_BGRA) {
+ if ( p_subpixelorder == ZM_SUBPIX_ORDER_BGRA ) {
cinfo->out_color_space = JCS_EXT_BGRX;
new_subpixelorder = ZM_SUBPIX_ORDER_BGRA;
- } else if(p_subpixelorder == ZM_SUBPIX_ORDER_ARGB) {
+ } else if ( p_subpixelorder == ZM_SUBPIX_ORDER_ARGB ) {
cinfo->out_color_space = JCS_EXT_XRGB;
new_subpixelorder = ZM_SUBPIX_ORDER_ARGB;
- } else if(p_subpixelorder == ZM_SUBPIX_ORDER_ABGR) {
+ } else if ( p_subpixelorder == ZM_SUBPIX_ORDER_ABGR ) {
cinfo->out_color_space = JCS_EXT_XBGR;
new_subpixelorder = ZM_SUBPIX_ORDER_ABGR;
} else {
@@ -1209,22 +1202,20 @@ bool Image::DecodeJpeg( const JOCTET *inbuffer, int inbuffer_size, unsigned int
cinfo->out_color_space = JCS_EXT_RGBX;
new_subpixelorder = ZM_SUBPIX_ORDER_RGBA;
}
- break;
+ break;
#else
Warning("libjpeg-turbo is required for reading a JPEG directly into a RGB32 buffer, reading into a RGB24 buffer instead.");
#endif
- }
case ZM_COLOUR_RGB24:
default:
- {
new_colours = ZM_COLOUR_RGB24;
- if(p_subpixelorder == ZM_SUBPIX_ORDER_BGR) {
-#ifdef JCS_EXTENSIONS
- cinfo->out_color_space = JCS_EXT_BGR;
+ if ( p_subpixelorder == ZM_SUBPIX_ORDER_BGR ) {
+#ifdef JCS_EXTENSIONS
+ cinfo->out_color_space = JCS_EXT_BGR;
new_subpixelorder = ZM_SUBPIX_ORDER_BGR;
#else
- Warning("libjpeg-turbo is required for reading a JPEG directly into a BGR24 buffer, reading into a RGB24 buffer instead.");
- cinfo->out_color_space = JCS_RGB;
+ Warning("libjpeg-turbo is required for reading a JPEG directly into a BGR24 buffer, reading into a RGB24 buffer instead.");
+ cinfo->out_color_space = JCS_RGB;
new_subpixelorder = ZM_SUBPIX_ORDER_RGB;
#endif
} else {
@@ -1240,34 +1231,33 @@ cinfo->out_color_space = JCS_RGB;
new_subpixelorder = ZM_SUBPIX_ORDER_RGB;
}
break;
- }
} // end switch
- if(WriteBuffer(new_width, new_height, new_colours, new_subpixelorder) == NULL) {
+ if ( WriteBuffer(new_width, new_height, new_colours, new_subpixelorder) == NULL ) {
Error("Failed requesting writeable buffer for reading JPEG image.");
- jpeg_abort_decompress( cinfo );
- return( false );
+ jpeg_abort_decompress(cinfo);
+ return false;
}
- jpeg_start_decompress( cinfo );
+ jpeg_start_decompress(cinfo);
JSAMPROW row_pointer; /* pointer to a single row */
int row_stride = width * colours; /* physical row width in buffer */
while ( cinfo->output_scanline < cinfo->output_height ) {
row_pointer = &buffer[cinfo->output_scanline * row_stride];
- jpeg_read_scanlines( cinfo, &row_pointer, 1 );
+ jpeg_read_scanlines(cinfo, &row_pointer, 1);
}
- jpeg_finish_decompress( cinfo );
+ jpeg_finish_decompress(cinfo);
return true;
}
-bool Image::EncodeJpeg( JOCTET *outbuffer, int *outbuffer_size, int quality_override ) const {
- if ( config.colour_jpeg_files && colours == ZM_COLOUR_GRAY8 ) {
- Image temp_image( *this );
- temp_image.Colourise(ZM_COLOUR_RGB24, ZM_SUBPIX_ORDER_RGB );
- return( temp_image.EncodeJpeg( outbuffer, outbuffer_size, quality_override ) );
+bool Image::EncodeJpeg(JOCTET *outbuffer, int *outbuffer_size, int quality_override) const {
+ if ( config.colour_jpeg_files && (colours == ZM_COLOUR_GRAY8) ) {
+ Image temp_image(*this);
+ temp_image.Colourise(ZM_COLOUR_RGB24, ZM_SUBPIX_ORDER_RGB);
+ return temp_image.EncodeJpeg(outbuffer, outbuffer_size, quality_override);
}
int quality = quality_override?quality_override:config.jpeg_stream_quality;
@@ -1276,56 +1266,51 @@ bool Image::EncodeJpeg( JOCTET *outbuffer, int *outbuffer_size, int quality_over
if ( !cinfo ) {
cinfo = encodejpg_ccinfo[quality] = new jpeg_compress_struct;
- cinfo->err = jpeg_std_error( &jpg_err.pub );
+ cinfo->err = jpeg_std_error(&jpg_err.pub);
jpg_err.pub.error_exit = zm_jpeg_error_exit;
jpg_err.pub.emit_message = zm_jpeg_emit_message;
- jpeg_create_compress( cinfo );
+ jpeg_create_compress(cinfo);
}
- zm_jpeg_mem_dest( cinfo, outbuffer, outbuffer_size );
+ zm_jpeg_mem_dest(cinfo, outbuffer, outbuffer_size);
cinfo->image_width = width; /* image width and height, in pixels */
cinfo->image_height = height;
- switch(colours) {
+ switch (colours) {
case ZM_COLOUR_GRAY8:
- {
cinfo->input_components = 1;
cinfo->in_color_space = JCS_GRAYSCALE;
break;
- }
case ZM_COLOUR_RGB32:
- {
#ifdef JCS_EXTENSIONS
cinfo->input_components = 4;
- if(subpixelorder == ZM_SUBPIX_ORDER_BGRA) {
+ if ( subpixelorder == ZM_SUBPIX_ORDER_BGRA ) {
cinfo->in_color_space = JCS_EXT_BGRX;
- } else if(subpixelorder == ZM_SUBPIX_ORDER_ARGB) {
+ } else if ( subpixelorder == ZM_SUBPIX_ORDER_ARGB ) {
cinfo->in_color_space = JCS_EXT_XRGB;
- } else if(subpixelorder == ZM_SUBPIX_ORDER_ABGR) {
+ } else if ( subpixelorder == ZM_SUBPIX_ORDER_ABGR ) {
cinfo->in_color_space = JCS_EXT_XBGR;
} else {
/* Assume RGBA */
cinfo->in_color_space = JCS_EXT_RGBX;
- }
+ }
+ break;
#else
Error("libjpeg-turbo is required for JPEG encoding directly from RGB32 source");
- jpeg_abort_compress( cinfo );
- return(false);
+ jpeg_abort_compress(cinfo);
+ return false;
#endif
- break;
- }
case ZM_COLOUR_RGB24:
default:
- {
cinfo->input_components = 3;
- if(subpixelorder == ZM_SUBPIX_ORDER_BGR) {
-#ifdef JCS_EXTENSIONS
+ if ( subpixelorder == ZM_SUBPIX_ORDER_BGR ) {
+#ifdef JCS_EXTENSIONS
cinfo->in_color_space = JCS_EXT_BGR;
#else
Error("libjpeg-turbo is required for JPEG encoding directly from BGR24 source");
- jpeg_abort_compress( cinfo );
- return(false);
+ jpeg_abort_compress(cinfo);
+ return false;
#endif
} else {
/* Assume RGB */
@@ -1339,23 +1324,22 @@ cinfo->out_color_space = JCS_RGB;
cinfo->in_color_space = JCS_RGB;
}
break;
- }
} // end switch
- jpeg_set_defaults( cinfo );
- jpeg_set_quality( cinfo, quality, FALSE );
+ jpeg_set_defaults(cinfo);
+ jpeg_set_quality(cinfo, quality, FALSE);
cinfo->dct_method = JDCT_FASTEST;
- jpeg_start_compress( cinfo, TRUE );
+ jpeg_start_compress(cinfo, TRUE);
JSAMPROW row_pointer; /* pointer to a single row */
int row_stride = cinfo->image_width * colours; /* physical row width in buffer */
while ( cinfo->next_scanline < cinfo->image_height ) {
row_pointer = &buffer[cinfo->next_scanline * row_stride];
- jpeg_write_scanlines( cinfo, &row_pointer, 1 );
+ jpeg_write_scanlines(cinfo, &row_pointer, 1);
}
- jpeg_finish_compress( cinfo );
+ jpeg_finish_compress(cinfo);
return true;
}
@@ -1470,7 +1454,7 @@ void Image::Overlay( const Image &image ) {
Colourise(image.colours, image.subpixelorder);
const Rgb* const max_ptr = (Rgb*)(buffer+size);
- const Rgb* prsrc = (Rgb*)image.buffer;
+ const Rgb* prsrc = (Rgb*)image.buffer;
Rgb* prdest = (Rgb*)buffer;
if ( subpixelorder == ZM_SUBPIX_ORDER_RGBA || subpixelorder == ZM_SUBPIX_ORDER_BGRA ) {
@@ -1521,7 +1505,7 @@ void Image::Overlay( const Image &image ) {
}
pdest += 3;
psrc += 3;
- }
+ }
/* RGB32 ontop of RGB24 - TO BE DONE */
} else if ( colours == ZM_COLOUR_RGB24 && image.colours == ZM_COLOUR_RGB32 ) {
@@ -1561,7 +1545,7 @@ void Image::Overlay( const Image &image ) {
} else if ( colours == ZM_COLOUR_RGB32 && image.colours == ZM_COLOUR_RGB32 ) {
const Rgb* const max_ptr = (Rgb*)(buffer+size);
Rgb* prdest = (Rgb*)buffer;
- const Rgb* prsrc = (Rgb*)image.buffer;
+ const Rgb* prsrc = (Rgb*)image.buffer;
if ( image.subpixelorder == ZM_SUBPIX_ORDER_RGBA || image.subpixelorder == ZM_SUBPIX_ORDER_BGRA ) {
/* RGB\BGR\RGBA\BGRA subpixel order - Alpha byte is last */
@@ -2035,7 +2019,7 @@ void Image::Annotate( const char *p_text, const Coord &coord, const unsigned int
}
}
}
- }
+ }
} else {
Panic("Annotate called with unexpected colours: %d",colours);
@@ -2088,7 +2072,7 @@ void Image::Colourise(const unsigned int p_reqcolours, const unsigned int p_reqs
newpixel = (newpixel<<8) | subpixel;
newpixel = (newpixel<<8) | subpixel;
pdest[i] = (newpixel<<8);
- }
+ }
} else {
/* RGBA\BGRA subpixel order, alpha byte is last (mem+3) */
for ( unsigned int i=0; i < pixels; i++ ) {
@@ -2128,7 +2112,7 @@ void Image::DeColourise() {
size = width * height;
if ( colours == ZM_COLOUR_RGB32 && config.cpu_extensions && sseversion >= 35 ) {
- /* Use SSSE3 functions */
+ /* Use SSSE3 functions */
switch (subpixelorder) {
case ZM_SUBPIX_ORDER_BGRA:
ssse3_convert_bgra_gray8(buffer,buffer,pixels);
@@ -2241,7 +2225,7 @@ void Image::Fill( Rgb colour, const Box *limits ) {
Rgb *p = (Rgb*)&buffer[((y*width)+lo_x)<<2];
for ( unsigned int x = lo_x; x <= (unsigned int)hi_x; x++, p++) {
- /* Fast, copies the entire pixel in a single pass */
+ /* Fast, copies the entire pixel in a single pass */
*p = colour;
}
}
@@ -2294,7 +2278,7 @@ void Image::Fill( Rgb colour, int density, const Box *limits ) {
*p = colour;
}
}
- }
+ }
}
/* RGB32 compatible: complete */
@@ -2469,7 +2453,7 @@ void Image::Fill( Rgb colour, int density, const Polygon &polygon ) {
} else if ( colours == ZM_COLOUR_RGB24 ) {
unsigned char *p = &buffer[colours*((y*width)+lo_x)];
for ( int x = lo_x; x <= hi_x; x++, p += 3) {
- if ( !(x%density) ) {
+ if ( !(x%density) ) {
RED_PTR_RGBA(p) = RED_VAL_RGBA(colour);
GREEN_PTR_RGBA(p) = GREEN_VAL_RGBA(colour);
BLUE_PTR_RGBA(p) = BLUE_VAL_RGBA(colour);
@@ -2675,7 +2659,7 @@ void Image::Flip( bool leftright ) {
}
s_ptr += line_bytes2;
}
- }
+ }
} else {
// Vertical flip, top to bottom
unsigned char *s_ptr = buffer+(height*line_bytes);
@@ -2883,7 +2867,7 @@ void Image::Deinterlace_Linear() {
for (unsigned int x = 0; x < (unsigned int)width; x++) {
*pcurrent++ = *pabove++;
*pcurrent++ = *pabove++;
- *pcurrent++ = *pabove++;
+ *pcurrent++ = *pabove++;
*pcurrent++ = *pabove++;
}
} else {
@@ -3068,7 +3052,7 @@ void Image::Deinterlace_4Field(const Image* next_image, unsigned int threshold)
__attribute__((noinline,__target__("sse2")))
#endif
void sse2_fastblend(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count, double blendpercent) {
-#if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE))
+#if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE))
static uint32_t divider = 0;
static uint32_t clearmask = 0;
static double current_blendpercent = 0.0;
@@ -3361,14 +3345,14 @@ __attribute__((noinline)) void std_blend(const uint8_t* col1, const uint8_t* col
while ( result < max_ptr ) {
*result++ = (*col1++ * opacity) + (*col2++ * divide);
- }
+ }
}
/************************************************* DELTA FUNCTIONS *************************************************/
/* Grayscale */
__attribute__((noinline)) void fast_delta8_gray8(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count) {
- /* Loop unrolling is used to work on 16 bytes (16 grayscale pixels) at a time */
+ /* Loop unrolling is used to work on 16 bytes (16 grayscale pixels) at a time */
const uint8_t* const max_ptr = result + count;
while(result < max_ptr) {
@@ -3392,7 +3376,7 @@ __attribute__((noinline)) void fast_delta8_gray8(const uint8_t* col1, const uint
col1 += 16;
col2 += 16;
result += 16;
- }
+ }
}
__attribute__((noinline)) void std_delta8_gray8(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count) {
@@ -3404,13 +3388,13 @@ __attribute__((noinline)) void std_delta8_gray8(const uint8_t* col1, const uint8
col1 += 1;
col2 += 1;
result += 1;
- }
+ }
}
/* RGB24: RGB */
__attribute__((noinline)) void fast_delta8_rgb(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count) {
/* Loop unrolling is used to work on 12 bytes (4 rgb24 pixels) at a time */
- int r,g,b;
+ int r,g,b;
const uint8_t* const max_ptr = result + count;
while(result < max_ptr) {
@@ -3439,7 +3423,7 @@ __attribute__((noinline)) void fast_delta8_rgb(const uint8_t* col1, const uint8_
__attribute__((noinline)) void std_delta8_rgb(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count) {
/* Loop unrolling is used to work on 12 bytes (4 rgb24 pixels) at a time */
- int r,g,b;
+ int r,g,b;
const uint8_t* const max_ptr = result + count;
while (result < max_ptr) {
@@ -3457,7 +3441,7 @@ __attribute__((noinline)) void std_delta8_rgb(const uint8_t* col1, const uint8_t
/* RGB24: BGR */
__attribute__((noinline)) void fast_delta8_bgr(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count) {
/* Loop unrolling is used to work on 12 bytes (4 rgb24 pixels) at a time */
- int r,g,b;
+ int r,g,b;
const uint8_t* const max_ptr = result + count;
while(result < max_ptr) {
@@ -3486,7 +3470,7 @@ __attribute__((noinline)) void fast_delta8_bgr(const uint8_t* col1, const uint8_
__attribute__((noinline)) void std_delta8_bgr(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count) {
/* Loop unrolling is used to work on 12 bytes (4 rgb24 pixels) at a time */
- int r,g,b;
+ int r,g,b;
const uint8_t* const max_ptr = result + count;
while(result < max_ptr) {
@@ -3504,7 +3488,7 @@ __attribute__((noinline)) void std_delta8_bgr(const uint8_t* col1, const uint8_t
/* RGB32: RGBA */
__attribute__((noinline)) void fast_delta8_rgba(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count) {
/* Loop unrolling is used to work on 16 bytes (4 rgb32 pixels) at a time */
- int r,g,b;
+ int r,g,b;
const uint8_t* const max_ptr = result + count;
while(result < max_ptr) {
@@ -3533,7 +3517,7 @@ __attribute__((noinline)) void fast_delta8_rgba(const uint8_t* col1, const uint8
__attribute__((noinline)) void std_delta8_rgba(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count) {
/* Loop unrolling is used to work on 16 bytes (4 rgb32 pixels) at a time */
- int r,g,b;
+ int r,g,b;
const uint8_t* const max_ptr = result + count;
while(result < max_ptr) {
@@ -3551,7 +3535,7 @@ __attribute__((noinline)) void std_delta8_rgba(const uint8_t* col1, const uint8_
/* RGB32: BGRA */
__attribute__((noinline)) void fast_delta8_bgra(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count) {
/* Loop unrolling is used to work on 16 bytes (4 rgb32 pixels) at a time */
- int r,g,b;
+ int r,g,b;
const uint8_t* const max_ptr = result + count;
while(result < max_ptr) {
@@ -3579,7 +3563,7 @@ __attribute__((noinline)) void fast_delta8_bgra(const uint8_t* col1, const uint8
}
__attribute__((noinline)) void std_delta8_bgra(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count) {
/* Loop unrolling is used to work on 16 bytes (4 rgb32 pixels) at a time */
- int r,g,b;
+ int r,g,b;
const uint8_t* const max_ptr = result + count;
while(result < max_ptr) {
@@ -3597,7 +3581,7 @@ __attribute__((noinline)) void std_delta8_bgra(const uint8_t* col1, const uint8_
/* RGB32: ARGB */
__attribute__((noinline)) void fast_delta8_argb(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count) {
/* Loop unrolling is used to work on 16 bytes (4 rgb32 pixels) at a time */
- int r,g,b;
+ int r,g,b;
const uint8_t* const max_ptr = result + count;
while(result < max_ptr) {
@@ -3625,7 +3609,7 @@ __attribute__((noinline)) void fast_delta8_argb(const uint8_t* col1, const uint8
}
__attribute__((noinline)) void std_delta8_argb(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count) {
/* Loop unrolling is used to work on 16 bytes (4 rgb32 pixels) at a time */
- int r,g,b;
+ int r,g,b;
const uint8_t* const max_ptr = result + count;
while(result < max_ptr) {
@@ -3643,7 +3627,7 @@ __attribute__((noinline)) void std_delta8_argb(const uint8_t* col1, const uint8_
/* RGB32: ABGR */
__attribute__((noinline)) void fast_delta8_abgr(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count) {
/* Loop unrolling is used to work on 16 bytes (4 rgb32 pixels) at a time */
- int r,g,b;
+ int r,g,b;
const uint8_t* const max_ptr = result + count;
while(result < max_ptr) {
@@ -3670,7 +3654,7 @@ __attribute__((noinline)) void fast_delta8_abgr(const uint8_t* col1, const uint8
}
}
__attribute__((noinline)) void std_delta8_abgr(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count) {
- int r,g,b;
+ int r,g,b;
const uint8_t* const max_ptr = result + count;
while(result < max_ptr) {
@@ -3919,7 +3903,7 @@ void neon64_armv8_delta8_abgr(const uint8_t* col1, const uint8_t* col2, uint8_t*
__attribute__((noinline,__target__("sse2")))
#endif
void sse2_delta8_gray8(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count) {
-#if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE))
+#if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE))
__asm__ __volatile__ (
"sub $0x10, %0\n\t"
@@ -3950,7 +3934,7 @@ void sse2_delta8_gray8(const uint8_t* col1, const uint8_t* col2, uint8_t* result
__attribute__((noinline,__target__("sse2")))
#endif
void sse2_delta8_rgba(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count) {
-#if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE))
+#if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE))
__asm__ __volatile__ (
"mov $0x1F1F1F1F, %%eax\n\t"
@@ -4008,7 +3992,7 @@ void sse2_delta8_rgba(const uint8_t* col1, const uint8_t* col2, uint8_t* result,
__attribute__((noinline,__target__("sse2")))
#endif
void sse2_delta8_bgra(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count) {
-#if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE))
+#if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE))
__asm__ __volatile__ (
"mov $0x1F1F1F1F, %%eax\n\t"
@@ -4066,7 +4050,7 @@ void sse2_delta8_bgra(const uint8_t* col1, const uint8_t* col2, uint8_t* result,
__attribute__((noinline,__target__("sse2")))
#endif
void sse2_delta8_argb(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count) {
-#if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE))
+#if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE))
__asm__ __volatile__ (
"mov $0x1F1F1F1F, %%eax\n\t"
@@ -4125,7 +4109,7 @@ void sse2_delta8_argb(const uint8_t* col1, const uint8_t* col2, uint8_t* result,
__attribute__((noinline,__target__("sse2")))
#endif
void sse2_delta8_abgr(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count) {
-#if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE))
+#if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE))
__asm__ __volatile__ (
"mov $0x1F1F1F1F, %%eax\n\t"
@@ -4184,7 +4168,7 @@ void sse2_delta8_abgr(const uint8_t* col1, const uint8_t* col2, uint8_t* result,
__attribute__((noinline,__target__("ssse3")))
#endif
void ssse3_delta8_rgb32(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count, uint32_t multiplier) {
-#if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE))
+#if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE))
/* XMM0 - zero */
/* XMM1 - col1 */
@@ -4253,7 +4237,7 @@ void ssse3_delta8_abgr(const uint8_t* col1, const uint8_t* col2, uint8_t* result
/* RGB24 to grayscale */
__attribute__((noinline)) void fast_convert_rgb_gray8(const uint8_t* col1, uint8_t* result, unsigned long count) {
- unsigned int r,g,b;
+ unsigned int r,g,b;
const uint8_t* const max_ptr = result + count;
while(result < max_ptr) {
@@ -4279,7 +4263,7 @@ __attribute__((noinline)) void fast_convert_rgb_gray8(const uint8_t* col1, uint8
}
}
__attribute__((noinline)) void std_convert_rgb_gray8(const uint8_t* col1, uint8_t* result, unsigned long count) {
- unsigned int r,g,b;
+ unsigned int r,g,b;
const uint8_t* const max_ptr = result + count;
while(result < max_ptr) {
@@ -4295,7 +4279,7 @@ __attribute__((noinline)) void std_convert_rgb_gray8(const uint8_t* col1, uint8_
/* BGR24 to grayscale */
__attribute__((noinline)) void fast_convert_bgr_gray8(const uint8_t* col1, uint8_t* result, unsigned long count) {
- unsigned int r,g,b;
+ unsigned int r,g,b;
const uint8_t* const max_ptr = result + count;
while(result < max_ptr) {
@@ -4321,7 +4305,7 @@ __attribute__((noinline)) void fast_convert_bgr_gray8(const uint8_t* col1, uint8
}
}
__attribute__((noinline)) void std_convert_bgr_gray8(const uint8_t* col1, uint8_t* result, unsigned long count) {
- unsigned int r,g,b;
+ unsigned int r,g,b;
const uint8_t* const max_ptr = result + count;
while(result < max_ptr) {
@@ -4337,7 +4321,7 @@ __attribute__((noinline)) void std_convert_bgr_gray8(const uint8_t* col1, uint8_
/* RGBA to grayscale */
__attribute__((noinline)) void fast_convert_rgba_gray8(const uint8_t* col1, uint8_t* result, unsigned long count) {
- unsigned int r,g,b;
+ unsigned int r,g,b;
const uint8_t* const max_ptr = result + count;
while(result < max_ptr) {
@@ -4363,7 +4347,7 @@ __attribute__((noinline)) void fast_convert_rgba_gray8(const uint8_t* col1, uint
}
}
__attribute__((noinline)) void std_convert_rgba_gray8(const uint8_t* col1, uint8_t* result, unsigned long count) {
- unsigned int r,g,b;
+ unsigned int r,g,b;
const uint8_t* const max_ptr = result + count;
while(result < max_ptr) {
@@ -4379,7 +4363,7 @@ __attribute__((noinline)) void std_convert_rgba_gray8(const uint8_t* col1, uint8
/* BGRA to grayscale */
__attribute__((noinline)) void fast_convert_bgra_gray8(const uint8_t* col1, uint8_t* result, unsigned long count) {
- unsigned int r,g,b;
+ unsigned int r,g,b;
const uint8_t* const max_ptr = result + count;
while(result < max_ptr) {
@@ -4406,7 +4390,7 @@ __attribute__((noinline)) void fast_convert_bgra_gray8(const uint8_t* col1, uint
}
__attribute__((noinline)) void std_convert_bgra_gray8(const uint8_t* col1, uint8_t* result, unsigned long count) {
- unsigned int r,g,b;
+ unsigned int r,g,b;
const uint8_t* const max_ptr = result + count;
while(result < max_ptr) {
@@ -4421,7 +4405,7 @@ __attribute__((noinline)) void std_convert_bgra_gray8(const uint8_t* col1, uint8
}
/* ARGB to grayscale */
__attribute__((noinline)) void fast_convert_argb_gray8(const uint8_t* col1, uint8_t* result, unsigned long count) {
- unsigned int r,g,b;
+ unsigned int r,g,b;
const uint8_t* const max_ptr = result + count;
while(result < max_ptr) {
@@ -4447,7 +4431,7 @@ __attribute__((noinline)) void fast_convert_argb_gray8(const uint8_t* col1, uint
}
}
__attribute__((noinline)) void std_convert_argb_gray8(const uint8_t* col1, uint8_t* result, unsigned long count) {
- unsigned int r,g,b;
+ unsigned int r,g,b;
const uint8_t* const max_ptr = result + count;
while(result < max_ptr) {
@@ -4463,7 +4447,7 @@ __attribute__((noinline)) void std_convert_argb_gray8(const uint8_t* col1, uint8
/* ABGR to grayscale */
__attribute__((noinline)) void fast_convert_abgr_gray8(const uint8_t* col1, uint8_t* result, unsigned long count) {
- unsigned int r,g,b;
+ unsigned int r,g,b;
const uint8_t* const max_ptr = result + count;
while(result < max_ptr) {
@@ -4489,7 +4473,7 @@ __attribute__((noinline)) void fast_convert_abgr_gray8(const uint8_t* col1, uint
}
}
__attribute__((noinline)) void std_convert_abgr_gray8(const uint8_t* col1, uint8_t* result, unsigned long count) {
- unsigned int r,g,b;
+ unsigned int r,g,b;
const uint8_t* const max_ptr = result + count;
while(result < max_ptr) {
@@ -4547,7 +4531,7 @@ __attribute__((noinline)) void std_convert_yuyv_gray8(const uint8_t* col1, uint8
__attribute__((noinline,__target__("ssse3")))
#endif
void ssse3_convert_rgb32_gray8(const uint8_t* col1, uint8_t* result, unsigned long count, uint32_t multiplier) {
-#if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE))
+#if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE))
/* XMM0 - zero */
/* XMM1 - col1 */
@@ -4609,7 +4593,7 @@ void ssse3_convert_abgr_gray8(const uint8_t* col1, uint8_t* result, unsigned lon
__attribute__((noinline,__target__("ssse3")))
#endif
void ssse3_convert_yuyv_gray8(const uint8_t* col1, uint8_t* result, unsigned long count) {
-#if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE))
+#if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE))
unsigned long i = 0;
__attribute__((aligned(16))) static const uint8_t movemask1[16] = {0,2,4,6,8,10,12,14,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
@@ -4712,8 +4696,8 @@ __attribute__((noinline)) void zm_convert_yuyv_rgba(const uint8_t* col1, uint8_t
/* RGB555 to RGB24 - relocated from zm_local_camera.cpp */
__attribute__((noinline)) void zm_convert_rgb555_rgb(const uint8_t* col1, uint8_t* result, unsigned long count) {
- unsigned int r,g,b;
- for(unsigned int i=0; i < count; i++, col1 += 2, result += 3) {
+ unsigned int r,g,b;
+ for(unsigned int i=0; i < count; i++, col1 += 2, result += 3) {
b = ((*col1)<<3)&0xf8;
g = (((*(col1+1))<<6)|((*col1)>>2))&0xf8;
r = ((*(col1+1))<<1)&0xf8;
@@ -4725,8 +4709,8 @@ __attribute__((noinline)) void zm_convert_rgb555_rgb(const uint8_t* col1, uint8_
/* RGB555 to RGBA - modified the one above */
__attribute__((noinline)) void zm_convert_rgb555_rgba(const uint8_t* col1, uint8_t* result, unsigned long count) {
- unsigned int r,g,b;
- for(unsigned int i=0; i < count; i++, col1 += 2, result += 4) {
+ unsigned int r,g,b;
+ for(unsigned int i=0; i < count; i++, col1 += 2, result += 4) {
b = ((*col1)<<3)&0xf8;
g = (((*(col1+1))<<6)|((*col1)>>2))&0xf8;
r = ((*(col1+1))<<1)&0xf8;
@@ -4738,8 +4722,8 @@ __attribute__((noinline)) void zm_convert_rgb555_rgba(const uint8_t* col1, uint8
/* RGB565 to RGB24 - relocated from zm_local_camera.cpp */
__attribute__((noinline)) void zm_convert_rgb565_rgb(const uint8_t* col1, uint8_t* result, unsigned long count) {
- unsigned int r,g,b;
- for(unsigned int i=0; i < count; i++, col1 += 2, result += 3) {
+ unsigned int r,g,b;
+ for(unsigned int i=0; i < count; i++, col1 += 2, result += 3) {
b = ((*col1)<<3)&0xf8;
g = (((*(col1+1))<<5)|((*col1)>>3))&0xfc;
r = (*(col1+1))&0xf8;
@@ -4751,8 +4735,8 @@ __attribute__((noinline)) void zm_convert_rgb565_rgb(const uint8_t* col1, uint8_
/* RGB565 to RGBA - modified the one above */
__attribute__((noinline)) void zm_convert_rgb565_rgba(const uint8_t* col1, uint8_t* result, unsigned long count) {
- unsigned int r,g,b;
- for(unsigned int i=0; i < count; i++, col1 += 2, result += 4) {
+ unsigned int r,g,b;
+ for ( unsigned int i=0; i < count; i++, col1 += 2, result += 4 ) {
b = ((*col1)<<3)&0xf8;
g = (((*(col1+1))<<5)|((*col1)>>3))&0xfc;
r = (*(col1+1))&0xf8;
diff --git a/src/zm_logger.cpp b/src/zm_logger.cpp
index 2089fecc3..1b8afc517 100644
--- a/src/zm_logger.cpp
+++ b/src/zm_logger.cpp
@@ -55,7 +55,7 @@ static void subtractTime( struct timeval * const tp1, struct timeval * const tp2
}
#endif
-void Logger::usrHandler( int sig ) {
+void Logger::usrHandler(int sig) {
Logger *logger = fetch();
if ( sig == SIGUSR1 )
logger->level(logger->level()+1);
@@ -71,9 +71,9 @@ Logger::Logger() :
mFileLevel(NOLOG),
mSyslogLevel(NOLOG),
mEffectiveLevel(NOLOG),
- //mLogPath( staticConfig.PATH_LOGS.c_str() ),
- //mLogFile( mLogPath+"/"+mId+".log" ),
mDbConnected(false),
+ mLogPath(staticConfig.PATH_LOGS.c_str()),
+ //mLogFile( mLogPath+"/"+mId+".log" ),
mLogFileFP(NULL),
mHasTerminal(false),
mFlush(false) {
@@ -106,9 +106,11 @@ Logger::Logger() :
smInitialised = true;
}
- if ( fileno(stderr) && isatty(fileno(stderr)) )
+ if ( fileno(stderr) && isatty(fileno(stderr)) ) {
mHasTerminal = true;
-}
+ mTerminalLevel = WARNING;
+ }
+} // End Logger::Logger
Logger::~Logger() {
terminate();
@@ -138,7 +140,8 @@ void Logger::initialise(const std::string &id, const Options &options) {
} else if ( options.mLogFile.size() ) {
tempLogFile = options.mLogFile;
} else {
- if ( options.mLogPath.size() ) {
+ // options.mLogPath defaults to '.' so only use it if we don't already have a path
+ if ( (!mLogPath.size()) || options.mLogPath != "." ) {
mLogPath = options.mLogPath;
}
tempLogFile = mLogPath+"/"+mId+".log";
@@ -240,7 +243,7 @@ void Logger::initialise(const std::string &id, const Options &options) {
mInitialised = true;
- Debug(1, "LogOpts: level=%s/%s, screen=%s, database=%s, logfile=%s->%s, syslog=%s",
+ Debug(1, "LogOpts: level=%s effective=%s, screen=%s, database=%s, logfile=%s->%s, syslog=%s",
smCodes[mLevel].c_str(),
smCodes[mEffectiveLevel].c_str(),
smCodes[mTerminalLevel].c_str(),
@@ -297,7 +300,7 @@ const std::string &Logger::id(const std::string &id) {
size_t pos;
// Remove whitespace
- while ( (pos = tempId.find_first_of( " \t" )) != std::string::npos ) {
+ while ( (pos = tempId.find_first_of(" \t")) != std::string::npos ) {
tempId.replace(pos, 1, "");
}
// Replace non-alphanum with underscore
@@ -341,7 +344,7 @@ Logger::Level Logger::level(Logger::Level level) {
return mLevel;
}
-Logger::Level Logger::terminalLevel( Logger::Level terminalLevel ) {
+Logger::Level Logger::terminalLevel(Logger::Level terminalLevel) {
if ( terminalLevel > NOOPT ) {
if ( !mHasTerminal )
terminalLevel = NOLOG;
@@ -352,34 +355,35 @@ Logger::Level Logger::terminalLevel( Logger::Level terminalLevel ) {
return mTerminalLevel;
}
-Logger::Level Logger::databaseLevel( Logger::Level databaseLevel ) {
+Logger::Level Logger::databaseLevel(Logger::Level databaseLevel) {
if ( databaseLevel > NOOPT ) {
databaseLevel = limit(databaseLevel);
if ( mDatabaseLevel != databaseLevel ) {
if ( databaseLevel > NOLOG && mDatabaseLevel <= NOLOG ) {
- zmDbConnect();
- } // end if ( databaseLevel > NOLOG && mDatabaseLevel <= NOLOG )
+ if ( !zmDbConnect() ) {
+ databaseLevel = NOLOG;
+ }
+ } // end if ( databaseLevel > NOLOG && mDatabaseLevel <= NOLOG )
mDatabaseLevel = databaseLevel;
- } // end if ( mDatabaseLevel != databaseLevel )
- } // end if ( databaseLevel > NOOPT )
+ } // end if ( mDatabaseLevel != databaseLevel )
+ } // end if ( databaseLevel > NOOPT )
return mDatabaseLevel;
}
-Logger::Level Logger::fileLevel( Logger::Level fileLevel ) {
+Logger::Level Logger::fileLevel(Logger::Level fileLevel) {
if ( fileLevel > NOOPT ) {
fileLevel = limit(fileLevel);
// Always close, because we may have changed file names
if ( mFileLevel > NOLOG )
closeFile();
mFileLevel = fileLevel;
- if ( mFileLevel > NOLOG )
- openFile();
+ // Don't try to open it here because it will create the log file even if we never write to it.
}
return mFileLevel;
}
-Logger::Level Logger::syslogLevel( Logger::Level syslogLevel ) {
+Logger::Level Logger::syslogLevel(Logger::Level syslogLevel) {
if ( syslogLevel > NOOPT ) {
syslogLevel = limit(syslogLevel);
if ( mSyslogLevel != syslogLevel ) {
@@ -393,7 +397,7 @@ Logger::Level Logger::syslogLevel( Logger::Level syslogLevel ) {
return mSyslogLevel;
}
-void Logger::logFile( const std::string &logFile ) {
+void Logger::logFile(const std::string &logFile) {
bool addLogPid = false;
std::string tempLogFile = logFile;
if ( tempLogFile[tempLogFile.length()-1] == '+' ) {
@@ -401,16 +405,16 @@ void Logger::logFile( const std::string &logFile ) {
addLogPid = true;
}
if ( addLogPid )
- mLogFile = stringtf( "%s.%05d", tempLogFile.c_str(), getpid() );
+ mLogFile = stringtf("%s.%05d", tempLogFile.c_str(), getpid());
else
mLogFile = tempLogFile;
}
void Logger::openFile() {
if ( mLogFile.size() ) {
- if ( (mLogFileFP = fopen(mLogFile.c_str() ,"a")) == (FILE *)NULL ) {
+ if ( (mLogFileFP = fopen(mLogFile.c_str(), "a")) == (FILE *)NULL ) {
mFileLevel = NOLOG;
- Fatal( "fopen() for %s, error = %s", mLogFile.c_str(), strerror(errno) );
+ Error("fopen() for %s, error = %s", mLogFile.c_str(), strerror(errno));
}
} else {
puts("Called Logger::openFile() without a filename");
@@ -419,29 +423,33 @@ void Logger::openFile() {
void Logger::closeFile() {
if ( mLogFileFP ) {
- fflush( mLogFileFP );
- if ( fclose( mLogFileFP ) < 0 ) {
- Fatal( "fclose(), error = %s",strerror(errno) );
+ fflush(mLogFileFP);
+ if ( fclose(mLogFileFP) < 0 ) {
+ mLogFileFP = (FILE *)NULL;
+ Error("fclose(), error = %s", strerror(errno));
}
mLogFileFP = (FILE *)NULL;
}
}
void Logger::closeDatabase() {
-
+
}
void Logger::openSyslog() {
- (void) openlog( mId.c_str(), LOG_PID|LOG_NDELAY, LOG_LOCAL1 );
+ (void) openlog(mId.c_str(), LOG_PID|LOG_NDELAY, LOG_LOCAL1);
}
void Logger::closeSyslog() {
(void) closelog();
}
-void Logger::logPrint( bool hex, const char * const filepath, const int line, const int level, const char *fstring, ... ) {
- if ( level > mEffectiveLevel )
+void Logger::logPrint(bool hex, const char * const filepath, const int line, const int level, const char *fstring, ...) {
+
+ if ( level > mEffectiveLevel ) {
return;
+ }
+
log_mutex.lock();
char timeString[64];
char logString[8192];
@@ -479,24 +487,24 @@ void Logger::logPrint( bool hex, const char * const filepath, const int line, co
thr_self(&lwpid);
tid = lwpid;
- if (tid < 0 ) // Thread/Process id
+ if ( tid < 0 ) // Thread/Process id
#else
-#ifdef HAVE_SYSCALL
-#ifdef __FreeBSD_kernel__
+ #ifdef HAVE_SYSCALL
+ #ifdef __FreeBSD_kernel__
if ( (syscall(SYS_thr_self, &tid)) < 0 ) // Thread/Process id
-# else
+ # else
// SOLARIS doesn't have SYS_gettid; don't assume
-#ifdef SYS_gettid
- if ( (tid = syscall(SYS_gettid)) < 0 ) // Thread/Process id
-#endif // SYS_gettid
+ #ifdef SYS_gettid
+ if ( (tid = syscall(SYS_gettid)) < 0 ) // Thread/Process id
+ #endif // SYS_gettid
+ #endif
+ #endif // HAVE_SYSCALL
#endif
-#endif // HAVE_SYSCALL
-#endif
- tid = getpid(); // Process id
+ tid = getpid(); // Process id
char *logPtr = logString;
- logPtr += snprintf( logPtr, sizeof(logString), "%s %s[%d].%s-%s/%d [",
+ logPtr += snprintf(logPtr, sizeof(logString), "%s %s[%d].%s-%s/%d [",
timeString,
mId.c_str(),
tid,
@@ -520,32 +528,39 @@ void Logger::logPrint( bool hex, const char * const filepath, const int line, co
}
va_end(argPtr);
char *syslogEnd = logPtr;
- strncpy( logPtr, "]\n", sizeof(logString)-(logPtr-logString) );
+ strncpy(logPtr, "]\n", sizeof(logString)-(logPtr-logString));
if ( level <= mTerminalLevel ) {
- puts( logString );
- fflush( stdout );
+ puts(logString);
+ fflush(stdout);
}
if ( level <= mFileLevel ) {
+ if ( !mLogFileFP )
+ openFile();
if ( mLogFileFP ) {
- fputs( logString, mLogFileFP );
+ fputs(logString, mLogFileFP);
if ( mFlush )
- fflush( mLogFileFP );
+ fflush(mLogFileFP);
} else {
- puts("Logging to file, but file not open\n");
+ puts("Logging to file, but failed to open it\n");
}
+#if 0
+ } else {
+ printf("Not writing to log file because level %d %s <= mFileLevel %d %s\nstring: %s\n",
+ level, smCodes[level].c_str(), mFileLevel, smCodes[mFileLevel].c_str(), logString);
+#endif
}
*syslogEnd = '\0';
if ( level <= mDatabaseLevel ) {
char sql[ZM_SQL_MED_BUFSIZ];
char escapedString[(strlen(syslogStart)*2)+1];
- if ( ! db_mutex.trylock() ) {
- mysql_real_escape_string( &dbconn, escapedString, syslogStart, strlen(syslogStart) );
+ if ( !db_mutex.trylock() ) {
+ mysql_real_escape_string(&dbconn, escapedString, syslogStart, strlen(syslogStart));
snprintf(sql, sizeof(sql),
- "INSERT INTO Logs "
- "( TimeKey, Component, ServerId, Pid, Level, Code, Message, File, Line )"
+ "INSERT INTO `Logs` "
+ "( `TimeKey`, `Component`, `ServerId`, `Pid`, `Level`, `Code`, `Message`, `File`, `Line` )"
" VALUES "
"( %ld.%06ld, '%s', %d, %d, %d, '%s', '%s', '%s', %d )",
timeVal.tv_sec, timeVal.tv_usec, mId.c_str(), staticConfig.SERVER_ID, tid, level, classString, escapedString, file, line
@@ -567,7 +582,7 @@ void Logger::logPrint( bool hex, const char * const filepath, const int line, co
if ( level <= mSyslogLevel ) {
int priority = smSyslogPriorities[level];
//priority |= LOG_DAEMON;
- syslog( priority, "%s [%s] [%s]", classString, mId.c_str(), syslogStart );
+ syslog(priority, "%s [%s] [%s]", classString, mId.c_str(), syslogStart);
}
free(filecopy);
@@ -580,15 +595,16 @@ void Logger::logPrint( bool hex, const char * const filepath, const int line, co
exit(-1);
}
log_mutex.unlock();
-}
-
+} // end logPrint
void logInit(const char *name, const Logger::Options &options) {
- if ( !Logger::smInstance )
- Logger::smInstance = new Logger();
- Logger::Options tempOptions = options;
- tempOptions.mLogPath = staticConfig.PATH_LOGS;
- Logger::smInstance->initialise(name, tempOptions);
+ if ( Logger::smInstance ) {
+ delete Logger::smInstance;
+ Logger::smInstance = NULL;
+ }
+
+ Logger::smInstance = new Logger();
+ Logger::smInstance->initialise(name, options);
}
void logTerm() {
diff --git a/src/zm_logger.h b/src/zm_logger.h
index f65c5ec31..82144a1c9 100644
--- a/src/zm_logger.h
+++ b/src/zm_logger.h
@@ -36,12 +36,12 @@ class Logger {
public:
enum {
NOOPT=-6,
- NOLOG,
- PANIC,
- FATAL,
- ERROR,
- WARNING,
- INFO,
+ NOLOG, // -5
+ PANIC, // -4
+ FATAL, // -3
+ ERROR, // -2
+ WARNING, // -1
+ INFO, // 0
DEBUG1,
DEBUG2,
DEBUG3,
@@ -68,14 +68,20 @@ public:
std::string mLogPath;
std::string mLogFile;
- public:
- Options( Level terminalLevel=NOOPT, Level databaseLevel=NOOPT, Level fileLevel=NOOPT, Level syslogLevel=NOOPT, const std::string &logPath=".", const std::string &logFile="" ) :
- mTerminalLevel( terminalLevel ),
- mDatabaseLevel( databaseLevel ),
- mFileLevel( fileLevel ),
- mSyslogLevel( syslogLevel ),
- mLogPath( logPath ),
- mLogFile( logFile )
+ Options(
+ Level terminalLevel=NOOPT,
+ Level databaseLevel=NOOPT,
+ Level fileLevel=NOOPT,
+ Level syslogLevel=NOOPT,
+ const std::string &logPath=".",
+ const std::string &logFile=""
+ ) :
+ mTerminalLevel(terminalLevel),
+ mDatabaseLevel(databaseLevel),
+ mFileLevel(fileLevel),
+ mSyslogLevel(syslogLevel),
+ mLogPath(logPath),
+ mLogFile(logFile)
{
}
};
@@ -89,21 +95,21 @@ private:
static StringMap smCodes;
static IntMap smSyslogPriorities;
-private:
bool mInitialised;
std::string mId;
std::string mIdRoot;
std::string mIdArgs;
- Level mLevel; // Level that is currently in operation
+ Level mLevel; // Level that is currently in operation
Level mTerminalLevel; // Maximum level output via terminal
- Level mDatabaseLevel; // Maximum level output via database
- Level mFileLevel; // Maximum level output via file
- Level mSyslogLevel; // Maximum level output via syslog
- Level mEffectiveLevel; // Level optimised to take account of maxima
+ Level mDatabaseLevel; // Maximum level output via database
+ Level mFileLevel; // Maximum level output via file
+ Level mSyslogLevel; // Maximum level output via syslog
+ Level mEffectiveLevel; // Level optimised to take account of maxima
bool mDbConnected;
+
std::string mLogPath;
std::string mLogFile;
FILE *mLogFileFP;
@@ -111,31 +117,10 @@ private:
bool mHasTerminal;
bool mFlush;
-private:
- static void usrHandler(int sig);
-
-public:
- friend void logInit(const char *name, const Options &options);
- friend void logTerm();
-
- static Logger *fetch() {
- if ( !smInstance ) {
- smInstance = new Logger();
- Options options;
- smInstance->initialise( "undef", options );
- }
- return smInstance;
- }
-
private:
Logger();
~Logger();
-public:
- void initialise(const std::string &id, const Options &options);
- void terminate();
-
-private:
int limit(int level) {
if ( level > DEBUG9 )
return DEBUG9;
@@ -150,14 +135,29 @@ private:
char *getTargettedEnv(const std::string &name);
void loadEnv();
+ static void usrHandler(int sig);
public:
+ friend void logInit(const char *name, const Options &options);
+ friend void logTerm();
+
+ static Logger *fetch() {
+ if ( !smInstance ) {
+ smInstance = new Logger();
+ Options options;
+ smInstance->initialise("undef", options);
+ }
+ return smInstance;
+ }
+
+ void initialise(const std::string &id, const Options &options);
+ void terminate();
+
+ const std::string &id(const std::string &id);
const std::string &id() const {
return mId;
}
- const std::string &id(const std::string &id);
-
Level level() const {
return mLevel;
}
diff --git a/src/zm_utils.cpp b/src/zm_utils.cpp
index 49b4d5ffc..d4bb48b73 100644
--- a/src/zm_utils.cpp
+++ b/src/zm_utils.cpp
@@ -22,6 +22,7 @@
#include "zm_utils.h"
#include
+#include
#include
#include
#include /* Definition of AT_* constants */
@@ -416,6 +417,10 @@ Warning("ZM Compiled without LIBCURL. UriDecoding not implemented.");
#endif
}
+void string_toupper( std::string& str) {
+ std::transform(str.begin(), str.end(), str.begin(), ::toupper);
+}
+
void touch(const char *pathname) {
int fd = open(pathname,
O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK,
diff --git a/src/zm_utils.h b/src/zm_utils.h
index d1340cf4b..9a8dd1948 100644
--- a/src/zm_utils.h
+++ b/src/zm_utils.h
@@ -40,6 +40,7 @@ StringVector split( const std::string &string, const std::string &chars, int lim
const std::string join( const StringVector &, const char * );
const std::string base64Encode( const std::string &inString );
+void string_toupper(std::string& str);
int split(const char* string, const char delim, std::vector& items);
int pairsplit(const char* string, const char delim, std::string& name, std::string& value);
diff --git a/src/zm_videostore.cpp b/src/zm_videostore.cpp
index 647920789..c3e19a193 100644
--- a/src/zm_videostore.cpp
+++ b/src/zm_videostore.cpp
@@ -20,13 +20,14 @@
#define __STDC_FORMAT_MACROS 1
-#include
-#include
-#include
#include "zm.h"
#include "zm_videostore.h"
+#include
+#include
+#include
+
extern "C" {
#include "libavutil/time.h"
}
@@ -60,7 +61,7 @@ VideoStore::VideoStore(
Info("Opening video storage stream %s format: %s", filename, format);
- ret = avformat_alloc_output_context2(&oc, NULL, NULL, filename);
+ int ret = avformat_alloc_output_context2(&oc, NULL, NULL, filename);
if ( ret < 0 ) {
Warning(
"Could not create video storage stream %s as no out ctx"
@@ -91,7 +92,7 @@ VideoStore::VideoStore(
oc->metadata = pmetadata;
out_format = oc->oformat;
- out_format->flags |= AVFMT_TS_NONSTRICT; // allow non increasing dts
+ out_format->flags |= AVFMT_TS_NONSTRICT; // allow non increasing dts
video_out_codec = avcodec_find_encoder(video_in_ctx->codec_id);
if ( !video_out_codec ) {
@@ -136,7 +137,7 @@ VideoStore::VideoStore(
video_out_ctx->time_base = video_in_ctx->time_base;
if ( ! (video_out_ctx->time_base.num && video_out_ctx->time_base.den) ) {
Debug(2,"No timebase found in video in context, defaulting to Q");
- video_out_ctx->time_base = AV_TIME_BASE_Q;
+ video_out_ctx->time_base = AV_TIME_BASE_Q;
}
zm_dump_codec(video_out_ctx);
@@ -162,7 +163,7 @@ VideoStore::VideoStore(
if ( !video_out_ctx->codec_tag ) {
Debug(2, "No codec_tag");
- if (
+ if (
!oc->oformat->codec_tag
||
av_codec_get_id(oc->oformat->codec_tag, video_in_ctx->codec_tag) == video_out_ctx->codec_id
@@ -178,32 +179,20 @@ VideoStore::VideoStore(
video_out_stream->time_base = video_in_stream->time_base;
if ( video_in_stream->avg_frame_rate.num ) {
Debug(3,"Copying avg_frame_rate (%d/%d)",
- video_in_stream->avg_frame_rate.num,
- video_in_stream->avg_frame_rate.den
+ video_in_stream->avg_frame_rate.num,
+ video_in_stream->avg_frame_rate.den
);
video_out_stream->avg_frame_rate = video_in_stream->avg_frame_rate;
}
if ( video_in_stream->r_frame_rate.num ) {
Debug(3,"Copying r_frame_rate (%d/%d) to out (%d/%d)",
- video_in_stream->r_frame_rate.num,
+ video_in_stream->r_frame_rate.num,
video_in_stream->r_frame_rate.den ,
- video_out_stream->r_frame_rate.num,
- video_out_stream->r_frame_rate.den
+ video_out_stream->r_frame_rate.num,
+ video_out_stream->r_frame_rate.den
);
video_out_stream->r_frame_rate = video_in_stream->r_frame_rate;
}
-#if LIBAVCODEC_VERSION_CHECK(56, 35, 0, 64, 0)
- ret = avcodec_parameters_from_context(video_out_stream->codecpar, video_out_ctx);
- if ( ret < 0 ) {
- Error("Could not initialize video_out_ctx parameters");
- return;
- } else {
- zm_dump_codec(video_out_ctx);
- }
-
- zm_dump_codecpar(video_in_stream->codecpar);
- zm_dump_codecpar(video_out_stream->codecpar);
-#endif
Debug(3,
"Time bases: VIDEO in stream (%d/%d) in codec: (%d/%d) out "
"stream: (%d/%d) out codec (%d/%d)",
@@ -221,6 +210,10 @@ VideoStore::VideoStore(
}
#if LIBAVCODEC_VERSION_CHECK(56, 35, 0, 64, 0)
+ /* I'm not entirely sure that this is a good idea. We may have to do it someday but really only when transcoding
+ * * think what I was trying to achieve here was to have zm_dump_codecpar output nice info
+ * */
+#if 0
AVDictionary *opts = 0;
if ( (ret = avcodec_open2(video_out_ctx, video_out_codec, &opts)) < 0 ) {
Warning("Can't open video codec (%s) %s",
@@ -234,6 +227,24 @@ VideoStore::VideoStore(
while ( (e = av_dict_get(opts, "", e, AV_DICT_IGNORE_SUFFIX)) != NULL ) {
Warning("Encoder Option %s not recognized by ffmpeg codec", e->key);
}
+ ret = avcodec_parameters_from_context(video_out_stream->codecpar, video_out_ctx);
+ if ( ret < 0 ) {
+ Error("Could not initialize video_out_ctx parameters");
+ return;
+ } else {
+ zm_dump_codec(video_out_ctx);
+ }
+#else
+ ret = avcodec_parameters_from_context(video_out_stream->codecpar, video_in_ctx);
+ if ( ret < 0 ) {
+ Error("Could not initialize video_out_ctx parameters");
+ return;
+ } else {
+ zm_dump_codec(video_out_ctx);
+ }
+#endif
+ zm_dump_codecpar(video_in_stream->codecpar);
+ zm_dump_codecpar(video_out_stream->codecpar);
#endif
Monitor::Orientation orientation = monitor->getOrientation();
@@ -262,9 +273,7 @@ VideoStore::VideoStore(
out_frame = NULL;
#if defined(HAVE_LIBSWRESAMPLE) || defined(HAVE_LIBAVRESAMPLE)
resample_ctx = NULL;
-#if defined(HAVE_LIBSWRESAMPLE)
fifo = NULL;
-#endif
#endif
video_first_pts = 0;
video_first_dts = 0;
@@ -273,6 +282,7 @@ VideoStore::VideoStore(
audio_first_pts = 0;
audio_first_dts = 0;
+ /* When encoding audio, these are used to tell us what the correct pts is, because it gets lost during resampling. */
audio_next_pts = 0;
audio_next_dts = 0;
@@ -301,7 +311,7 @@ VideoStore::VideoStore(
audio_out_stream = NULL;
return;
}
-#else
+#else
audio_out_stream = avformat_new_stream(oc, audio_out_codec);
audio_out_ctx = audio_out_stream->codec;
#endif
@@ -375,6 +385,7 @@ VideoStore::VideoStore(
} // VideoStore::VideoStore
bool VideoStore::open() {
+ int ret;
/* open the out file, if needed */
if ( !(out_format->flags & AVFMT_NOFILE) ) {
ret = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE, NULL, NULL);
@@ -419,6 +430,7 @@ VideoStore::~VideoStore() {
if ( oc->pb ) {
if ( audio_out_codec ) {
+
// The codec queues data. We need to send a flush command and out
// whatever we get. Failures are not fatal.
AVPacket pkt;
@@ -426,105 +438,75 @@ VideoStore::~VideoStore() {
pkt.data = NULL;
pkt.size = 0;
av_init_packet(&pkt);
+
+ int frame_size = audio_out_ctx->frame_size;
+ /*
+ * At the end of the file, we pass the remaining samples to
+ * the encoder. */
+ while ( zm_resample_get_delay(resample_ctx, audio_out_ctx->sample_rate) ) {
+ zm_resample_audio(resample_ctx, out_frame, NULL);
+
+ if ( zm_add_samples_to_fifo(fifo, out_frame) ) {
+ // Should probably set the frame size to what is reported FIXME
+ if ( zm_get_samples_from_fifo(fifo, out_frame) ) {
+ if ( zm_send_frame_receive_packet(audio_out_ctx, out_frame, pkt) ) {
+ pkt.stream_index = audio_out_stream->index;
+
+ av_packet_rescale_ts(&pkt,
+ audio_out_ctx->time_base,
+ audio_out_stream->time_base);
+ write_packet(&pkt, audio_out_stream);
+ }
+ } // end if data returned from fifo
+ }
+
+ } // end if have buffered samples in the resampler
+
+ Debug(2, "av_audio_fifo_size = %d", av_audio_fifo_size(fifo));
+ while ( av_audio_fifo_size(fifo) > 0 ) {
+ /* Take one frame worth of audio samples from the FIFO buffer,
+ * encode it and write it to the output file. */
+
+ Debug(1, "Remaining samples in fifo for AAC codec frame_size %d > fifo size %d",
+ frame_size, av_audio_fifo_size(fifo));
+
+ // SHould probably set the frame size to what is reported FIXME
+ if ( av_audio_fifo_read(fifo, (void **)out_frame->data, frame_size) ) {
+ if ( zm_send_frame_receive_packet(audio_out_ctx, out_frame, pkt) ) {
+ pkt.stream_index = audio_out_stream->index;
+
+ av_packet_rescale_ts(&pkt,
+ audio_out_ctx->time_base,
+ audio_out_stream->time_base);
+ write_packet(&pkt, audio_out_stream);
+ }
+ } // end if data returned from fifo
+ } // end while still data in the fifo
+
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
// Put encoder into flushing mode
avcodec_send_frame(audio_out_ctx, NULL);
#endif
while (1) {
-#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
- ret = avcodec_receive_packet(audio_out_ctx, &pkt);
- if ( ret < 0 ) {
- if ( AVERROR_EOF != ret ) {
- Error("Error encoding audio while flushing (%d) (%s)", ret,
- av_err2str(ret));
- }
+ if ( ! zm_receive_packet(audio_out_ctx, pkt) ) {
+ Debug(1, "No more packets");
break;
}
-#else
- int got_packet = 0;
- ret = avcodec_encode_audio2(audio_out_ctx, &pkt, NULL, &got_packet);
- if ( ret < 0 ) {
- Error("Error encoding audio while flushing (%d) (%s)", ret,
- av_err2str(ret));
- break;
- }
- Debug(1, "Have audio encoder, need to flush it's out");
- if ( !got_packet ) {
- break;
- }
-#endif
dumpPacket(&pkt, "raw from encoder");
- // Need to adjust pts and dts and duration
-
- pkt.stream_index = audio_out_stream->index;
-
- pkt.duration = av_rescale_q(
- pkt.duration,
- audio_out_ctx->time_base,
- audio_out_stream->time_base);
- // Scale the PTS of the outgoing packet to be the correct time base
- if ( pkt.pts != AV_NOPTS_VALUE ) {
-#if 0
- pkt.pts = av_rescale_q(
- pkt.pts,
- audio_out_ctx->time_base,
- audio_in_stream->time_base);
- // audio_first_pts is in audio_in_stream time base
- pkt.pts -= audio_first_pts;
- pkt.pts = av_rescale_q(
- pkt.pts,
- audio_in_stream->time_base,
- audio_out_stream->time_base);
-#else
- pkt.pts = av_rescale_q(
- pkt.pts,
- audio_out_ctx->time_base,
- audio_out_stream->time_base);
-#endif
-
- Debug(2, "audio pkt.pts = %" PRId64 " from first_pts(%" PRId64 ")",
- pkt.pts, audio_first_pts);
- } else {
- Debug(2, "pkt.pts = undef");
- pkt.pts = AV_NOPTS_VALUE;
- }
-
- if ( pkt.dts != AV_NOPTS_VALUE ) {
-#if 0
- pkt.dts = av_rescale_q(
- pkt.dts,
- audio_out_ctx->time_base,
- audio_in_stream->time_base);
- pkt.dts -= audio_first_dts;
- pkt.dts = av_rescale_q(
- pkt.dts,
- audio_in_stream->time_base,
- audio_out_stream->time_base);
-#else
- pkt.dts = av_rescale_q(
- pkt.dts,
- audio_out_ctx->time_base,
- audio_out_stream->time_base);
-#endif
- Debug(2, "pkt.dts = %" PRId64 " - first_dts(%" PRId64 ")",
- pkt.dts, audio_first_dts);
- } else {
- pkt.dts = AV_NOPTS_VALUE;
- }
-
+ av_packet_rescale_ts(&pkt, audio_out_ctx->time_base, audio_out_stream->time_base);
dumpPacket(audio_out_stream, &pkt, "writing flushed packet");
- av_interleaved_write_frame(oc, &pkt);
+ write_packet(&pkt, audio_out_stream);
zm_av_packet_unref(&pkt);
- } // while have buffered frames
- } // end if audio_out_codec
+ } // while have buffered frames
+ } // end if audio_out_codec
// Flush Queues
- Debug(1,"Flushing interleaved queues");
+ Debug(1, "Flushing interleaved queues");
av_interleaved_write_frame(oc, NULL);
- Debug(1,"Writing trailer");
+ Debug(1, "Writing trailer");
/* Write the trailer before close */
if ( int rc = av_write_trailer(oc) ) {
Error("Error writing trailer %s", av_err2str(rc));
@@ -593,11 +575,11 @@ VideoStore::~VideoStore() {
#if defined(HAVE_LIBAVRESAMPLE) || defined(HAVE_LIBSWRESAMPLE)
if ( resample_ctx ) {
- #if defined(HAVE_LIBSWRESAMPLE)
if ( fifo ) {
av_audio_fifo_free(fifo);
fifo = NULL;
}
+ #if defined(HAVE_LIBSWRESAMPLE)
swr_free(&resample_ctx);
#else
#if defined(HAVE_LIBAVRESAMPLE)
@@ -632,6 +614,7 @@ bool VideoStore::setup_resampler() {
"Cannot do audio conversion to AAC");
return false;
#else
+ int ret;
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
// Newer ffmpeg wants to keep everything separate... so have to lookup our own
@@ -650,8 +633,13 @@ bool VideoStore::setup_resampler() {
#else
// codec is already open in ffmpeg_camera
audio_in_ctx = audio_in_stream->codec;
- audio_in_codec = (AVCodec *)audio_in_ctx->codec;
- //audio_in_codec = avcodec_find_decoder(audio_in_stream->codec->codec_id);
+ audio_in_codec = reinterpret_cast(audio_in_ctx->codec);
+ if ( !audio_in_codec ) {
+ audio_in_codec = avcodec_find_decoder(audio_in_stream->codec->codec_id);
+ }
+ if ( !audio_in_codec ) {
+ return false;
+ }
#endif
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
@@ -707,7 +695,7 @@ bool VideoStore::setup_resampler() {
}
}
if ( found ) {
- Debug(3, "Sample rate is good");
+ Debug(3, "Sample rate is good %d", audio_out_ctx->sample_rate);
} else {
audio_out_ctx->sample_rate =
audio_out_codec->supported_samplerates[0];
@@ -739,6 +727,7 @@ bool VideoStore::setup_resampler() {
audio_out_stream = NULL;
return false;
}
+ zm_dump_codec(audio_out_ctx);
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
ret = avcodec_parameters_from_context(
@@ -747,6 +736,7 @@ bool VideoStore::setup_resampler() {
Error("Could not initialize stream parameteres");
return false;
}
+ zm_dump_codecpar(audio_out_stream->codecpar);
#endif
Debug(3,
@@ -783,13 +773,13 @@ bool VideoStore::setup_resampler() {
return false;
}
-#if defined(HAVE_LIBSWRESAMPLE)
if ( !(fifo = av_audio_fifo_alloc(
audio_out_ctx->sample_fmt,
audio_out_ctx->channels, 1)) ) {
Error("Could not allocate FIFO");
return false;
}
+#if defined(HAVE_LIBSWRESAMPLE)
resample_ctx = swr_alloc_set_opts(NULL,
audio_out_ctx->channel_layout,
audio_out_ctx->sample_fmt,
@@ -864,7 +854,7 @@ bool VideoStore::setup_resampler() {
NULL, audio_out_ctx->channels,
audio_out_ctx->frame_size,
audio_out_ctx->sample_fmt, 0);
- converted_in_samples = (uint8_t *)av_malloc(audioSampleBuffer_size);
+ converted_in_samples = reinterpret_cast(av_malloc(audioSampleBuffer_size));
if ( !converted_in_samples ) {
Error("Could not allocate converted in sample pointers");
@@ -890,131 +880,31 @@ bool VideoStore::setup_resampler() {
int VideoStore::writeVideoFramePacket(AVPacket *ipkt) {
av_init_packet(&opkt);
- dumpPacket(video_in_stream, ipkt, "input packet");
+ dumpPacket(video_in_stream, ipkt, "video input packet");
- int64_t duration;
- if ( ipkt->duration != AV_NOPTS_VALUE ) {
- duration = av_rescale_q(
- ipkt->duration,
- video_in_stream->time_base,
- video_out_stream->time_base);
- Debug(1, "duration from ipkt: %" PRId64 ") => (%" PRId64 ") (%d/%d) (%d/%d)",
- ipkt->duration,
- duration,
- video_in_stream->time_base.num,
- video_in_stream->time_base.den,
- video_out_stream->time_base.num,
- video_out_stream->time_base.den
- );
- } else {
- duration = av_rescale_q(
- ipkt->pts - video_last_pts,
- video_in_stream->time_base,
- video_out_stream->time_base);
- Debug(1, "duration calc: pts(%" PRId64 ") - last_pts(%" PRId64 ") = (%" PRId64 ") => (%" PRId64 ")",
- ipkt->pts,
- video_last_pts,
- ipkt->pts - video_last_pts,
- duration
- );
- if ( duration <= 0 ) {
- // Why are we setting the duration to 1?
- duration = ipkt->duration ? ipkt->duration : av_rescale_q(1,video_in_stream->time_base, video_out_stream->time_base);
- }
- }
- opkt.duration = duration;
+ opkt.flags = ipkt->flags;
+ opkt.data = ipkt->data;
+ opkt.size = ipkt->size;
+ opkt.duration = ipkt->duration;
- // Scale the PTS of the outgoing packet to be the correct time base
- if ( ipkt->pts != AV_NOPTS_VALUE ) {
-
- if ( (!video_first_pts) && (ipkt->pts >= 0) ) {
- // This is the first packet.
- opkt.pts = 0;
- Debug(2, "Starting video first_pts will become %" PRId64, ipkt->pts);
- video_first_pts = ipkt->pts;
-#if 1
- if ( audio_in_stream ) {
- // Since audio starts after the start of the video, need to set this here.
- audio_first_pts = av_rescale_q(
- ipkt->pts,
- video_in_stream->time_base,
- audio_in_stream->time_base
- );
- Debug(2, "Starting audio first_pts will become %" PRId64, audio_first_pts);
- }
-#endif
- } else {
- opkt.pts = av_rescale_q(
- ipkt->pts - video_first_pts,
- video_in_stream->time_base,
- video_out_stream->time_base
- );
- }
- Debug(3, "opkt.pts = %" PRId64 " from ipkt->pts(%" PRId64 ") - first_pts(%" PRId64 ")",
- opkt.pts, ipkt->pts, video_first_pts);
- video_last_pts = ipkt->pts;
- } else {
- Debug(3, "opkt.pts = undef");
- opkt.pts = AV_NOPTS_VALUE;
-// can't set 0, it will get rejected
- //AV_NOPTS_VALUE;
- }
// Just because the in stream wraps, doesn't mean the out needs to.
- // Really, if we are limiting ourselves to 10min segments I can't imagine every wrapping in the out.
- // So need to handle in wrap, without causing out wrap.
+ // Really, if we are limiting ourselves to 10min segments I can't imagine every wrapping in the out.
+ // So need to handle in wrap, without causing out wrap.
+ // The cameras that Icon has seem to do EOF instead of wrapping
if ( ipkt->dts != AV_NOPTS_VALUE ) {
if ( !video_first_dts ) {
- // && ( ipkt->dts >= 0 ) ) {
- // This is the first packet.
- opkt.dts = 0;
- Debug(1, "Starting video first_dts will become (%" PRId64 ")", ipkt->dts);
+ Debug(2, "Starting video first_dts will become %" PRId64, ipkt->dts);
video_first_dts = ipkt->dts;
-#if 1
- if ( audio_in_stream ) {
- // Since audio starts after the start of the video, need to set this here.
- audio_first_dts = av_rescale_q(
- ipkt->dts,
- video_in_stream->time_base,
- audio_in_stream->time_base
- );
- Debug(2, "Starting audio first dts will become %" PRId64, audio_first_dts);
- }
-#endif
- } else {
- opkt.dts = av_rescale_q(
- ipkt->dts - video_first_dts,
- video_in_stream->time_base,
- video_out_stream->time_base
- );
- Debug(3, "opkt.dts = %" PRId64 " from ipkt->dts(%" PRId64 ") - first_pts(%" PRId64 ")",
- opkt.dts, ipkt->dts, video_first_dts);
}
- if ( (opkt.pts != AV_NOPTS_VALUE) && (opkt.dts > opkt.pts) ) {
- Debug(1,
- "opkt.dts(%" PRId64 ") must be <= opkt.pts(%" PRId64 "). Decompression must happen "
- "before presentation.",
- opkt.dts, opkt.pts);
- opkt.dts = opkt.pts;
- }
- } else {
- Debug(3, "opkt.dts = undef");
- opkt.dts = video_out_stream->cur_dts;
+ opkt.dts = ipkt->dts - video_first_dts;
}
+ if ( ipkt->pts != AV_NOPTS_VALUE ) {
+ opkt.pts = ipkt->pts - video_first_dts;
+ }
+ av_packet_rescale_ts(&opkt, video_in_stream->time_base, video_out_stream->time_base);
- if ( opkt.dts < video_out_stream->cur_dts ) {
- Debug(1, "Fixing non-monotonic dts/pts dts %" PRId64 " pts %" PRId64 " stream %" PRId64,
- opkt.dts, opkt.pts, video_out_stream->cur_dts);
- opkt.dts = video_out_stream->cur_dts;
- if ( opkt.dts > opkt.pts ) {
- opkt.pts = opkt.dts;
- }
- }
-
- opkt.flags = ipkt->flags;
- opkt.pos = -1;
- opkt.data = ipkt->data;
- opkt.size = ipkt->size;
+ dumpPacket(video_out_stream, &opkt, "after pts adjustment");
write_packet(&opkt, video_out_stream);
zm_av_packet_unref(&opkt);
@@ -1022,6 +912,7 @@ int VideoStore::writeVideoFramePacket(AVPacket *ipkt) {
} // end int VideoStore::writeVideoFramePacket( AVPacket *ipkt )
int VideoStore::writeAudioFramePacket(AVPacket *ipkt) {
+ int ret;
if ( !audio_out_stream ) {
Debug(1, "Called writeAudioFramePacket when no audio_out_stream");
@@ -1030,151 +921,57 @@ int VideoStore::writeAudioFramePacket(AVPacket *ipkt) {
}
dumpPacket(audio_in_stream, ipkt, "input packet");
+ if ( !audio_first_dts ) {
+ audio_first_dts = ipkt->dts;
+ audio_next_pts = audio_out_ctx->frame_size;
+ }
+
+ // Need to adjust pts before feeding to decoder.... should really copy the pkt instead of modifying it
+ ipkt->pts -= audio_first_dts;
+ ipkt->dts -= audio_first_dts;
+ dumpPacket(audio_in_stream, ipkt, "after pts adjustment");
+
if ( audio_out_codec ) {
- if ( ( ret = zm_receive_frame(audio_in_ctx, in_frame, *ipkt) ) < 0 ) {
+ // I wonder if we can get multiple frames per packet? Probably
+ ret = zm_send_packet_receive_frame(audio_in_ctx, in_frame, *ipkt);
+ if ( ret <= 0 ) {
Debug(3, "Not ready to receive frame");
return 0;
}
-
zm_dump_frame(in_frame, "In frame from decode");
- if ( in_frame->pts != AV_NOPTS_VALUE ) {
- if ( !audio_first_pts ) {
- audio_first_pts = in_frame->pts;
- Debug(1, "No audio_first_pts setting to %" PRId64, audio_first_pts);
- in_frame->pts = 0;
- } else {
- // out_frame_pts is in codec->timebase, audio_first_pts is in packet timebase.
- in_frame->pts = in_frame->pts - audio_first_pts;
- zm_dump_frame(in_frame, "in frame after pts adjustment");
- }
- } else {
- // sending AV_NOPTS_VALUE doesn't really work but we seem to get it in ffmpeg 2.8
- in_frame->pts = audio_next_pts;
- }
- if ( !resample_audio() ) {
- //av_frame_unref(in_frame);
- return 0;
- }
+ AVFrame *input_frame = in_frame;
+
+ while ( zm_resample_audio(resample_ctx, input_frame, out_frame) ) {
+ //out_frame->pkt_duration = in_frame->pkt_duration; // resampling doesn't alter duration
+ if ( zm_add_samples_to_fifo(fifo, out_frame) <= 0 )
+ break;
+
+ if ( zm_get_samples_from_fifo(fifo, out_frame) <= 0 )
+ break;
- zm_dump_frame(out_frame, "Out frame after resample");
-#if 0
- // out_frame pts is in the input pkt pts... needs to be adjusted before sending to the encoder
- if ( out_frame->pts != AV_NOPTS_VALUE ) {
- if ( !audio_first_pts ) {
- audio_first_pts = out_frame->pts;
- Debug(1, "No audio_first_pts setting to %" PRId64, audio_first_pts);
- out_frame->pts = 0;
- } else {
- // out_frame_pts is in codec->timebase, audio_first_pts is in packet timebase.
- out_frame->pts = out_frame->pts - audio_first_pts;
- zm_dump_frame(out_frame, "Out frame after pts adjustment");
- }
- //
- } else {
- // sending AV_NOPTS_VALUE doesn't really work but we seem to get it in ffmpeg 2.8
out_frame->pts = audio_next_pts;
- }
- audio_next_pts = out_frame->pts + out_frame->nb_samples;
-#endif
+ audio_next_pts += out_frame->nb_samples;
- av_init_packet(&opkt);
- if ( !zm_send_frame(audio_out_ctx, out_frame, opkt) ) {
- return 0;
- }
+ zm_dump_frame(out_frame, "Out frame after resample");
- dumpPacket(audio_out_stream, &opkt, "raw opkt");
- Debug(1, "Duration before %d in %d/%d", opkt.duration,
- audio_out_ctx->time_base.num,
- audio_out_ctx->time_base.den);
+ av_init_packet(&opkt);
+ if ( zm_send_frame_receive_packet(audio_out_ctx, out_frame, opkt) <= 0 )
+ break;
- opkt.duration = av_rescale_q(
- opkt.duration,
- audio_out_ctx->time_base,
- audio_out_stream->time_base);
- Debug(1, "Duration after %d in %d/%d", opkt.duration,
- audio_out_stream->time_base.num,
- audio_out_stream->time_base.den);
- // Scale the PTS of the outgoing packet to be the correct time base
-#if 0
- if ( ipkt->pts != AV_NOPTS_VALUE ) {
- if ( !audio_first_pts ) {
- opkt.pts = 0;
- audio_first_pts = ipkt->pts;
- Debug(1, "No audio_first_pts");
- } else {
- opkt.pts = av_rescale_q(
- opkt.pts,
- audio_out_ctx->time_base,
- audio_out_stream->time_base);
- opkt.pts -= audio_first_pts;
- Debug(2, "audio opkt.pts = %" PRId64 " from first_pts %" PRId64,
- opkt.pts, audio_first_pts);
- }
- } else {
- Debug(2, "opkt.pts = undef");
- opkt.pts = AV_NOPTS_VALUE;
- }
-
- if ( opkt.dts != AV_NOPTS_VALUE ) {
- if ( !audio_first_dts ) {
- opkt.dts = 0;
- audio_first_dts = opkt.dts;
- } else {
- opkt.dts = av_rescale_q(
- opkt.dts,
- audio_out_ctx->time_base,
- audio_out_stream->time_base);
- opkt.dts -= audio_first_dts;
- Debug(2, "audio opkt.dts = %" PRId64 " from first_dts %" PRId64,
- opkt.dts, audio_first_dts);
- }
- audio_last_dts = opkt.dts;
- } else {
- opkt.dts = AV_NOPTS_VALUE;
- }
-#else
- opkt.pts = av_rescale_q(
- opkt.pts,
- audio_out_ctx->time_base,
- audio_out_stream->time_base);
- opkt.dts = av_rescale_q(
- opkt.dts,
- audio_out_ctx->time_base,
- audio_out_stream->time_base);
-#endif
-
- write_packet(&opkt, audio_out_stream);
- zm_av_packet_unref(&opkt);
-
-#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
- // While the encoder still has packets for us
- while ( !avcodec_receive_packet(audio_out_ctx, &opkt) ) {
- opkt.pts = av_rescale_q(
- opkt.pts,
- audio_out_ctx->time_base,
- audio_out_stream->time_base);
- opkt.dts = av_rescale_q(
- opkt.dts,
+ // Scale the PTS of the outgoing packet to be the correct time base
+ av_packet_rescale_ts(&opkt,
audio_out_ctx->time_base,
audio_out_stream->time_base);
- dumpPacket(audio_out_stream, &opkt, "raw opkt");
- Debug(1, "Duration before %d in %d/%d", opkt.duration,
- audio_out_ctx->time_base.num,
- audio_out_ctx->time_base.den);
-
- opkt.duration = av_rescale_q(
- opkt.duration,
- audio_out_ctx->time_base,
- audio_out_stream->time_base);
- Debug(1, "Duration after %d in %d/%d", opkt.duration,
- audio_out_stream->time_base.num,
- audio_out_stream->time_base.den);
write_packet(&opkt, audio_out_stream);
- }
-#endif
- zm_av_packet_unref(&opkt);
+ zm_av_packet_unref(&opkt);
+
+ if ( zm_resample_get_delay(resample_ctx, out_frame->sample_rate) < out_frame->nb_samples)
+ break;
+ // This will send a null frame, emptying out the resample buffer
+ input_frame = NULL;
+ } // end while there is data in the resampler
} else {
Debug(2,"copying");
@@ -1183,171 +980,50 @@ int VideoStore::writeAudioFramePacket(AVPacket *ipkt) {
opkt.size = ipkt->size;
opkt.flags = ipkt->flags;
- if ( ipkt->duration && (ipkt->duration != AV_NOPTS_VALUE) ) {
- opkt.duration = av_rescale_q(
- ipkt->duration,
- audio_in_stream->time_base,
- audio_out_stream->time_base);
- }
- // Scale the PTS of the outgoing packet to be the correct time base
- if ( ipkt->pts != AV_NOPTS_VALUE ) {
- if ( !audio_first_pts ) {
- opkt.pts = 0;
- audio_first_pts = ipkt->pts;
- Debug(1, "No audio_first_pts");
- } else {
- opkt.pts = av_rescale_q(
- ipkt->pts - audio_first_pts,
- audio_in_stream->time_base,
- audio_out_stream->time_base);
- Debug(2, "audio opkt.pts = %" PRId64 " from ipkt->pts(%" PRId64 ") - first_pts(%" PRId64 ")",
- opkt.pts, ipkt->pts, audio_first_pts);
- }
- } else {
- Debug(2, "opkt.pts = undef");
- opkt.pts = AV_NOPTS_VALUE;
- }
-
- if ( ipkt->dts != AV_NOPTS_VALUE ) {
- if ( !audio_first_dts ) {
- opkt.dts = 0;
- audio_first_dts = ipkt->dts;
- } else {
- opkt.dts = av_rescale_q(
- ipkt->dts - audio_first_dts,
- audio_in_stream->time_base,
- audio_out_stream->time_base);
- Debug(2, "opkt.dts = %" PRId64 " from ipkt.dts(%" PRId64 ") - first_dts(%" PRId64 ")",
- opkt.dts, ipkt->dts, audio_first_dts);
- }
- audio_last_dts = ipkt->dts;
- } else {
- opkt.dts = AV_NOPTS_VALUE;
- }
+ opkt.duration = ipkt->duration;
+ opkt.pts = ipkt->pts;
+ opkt.dts = ipkt->dts;
+ av_packet_rescale_ts(&opkt, audio_in_stream->time_base, audio_out_stream->time_base);
write_packet(&opkt, audio_out_stream);
zm_av_packet_unref(&opkt);
- } // end if encoding or copying
+ } // end if encoding or copying
return 0;
-} // end int VideoStore::writeAudioFramePacket(AVPacket *ipkt)
+} // end int VideoStore::writeAudioFramePacket(AVPacket *ipkt)
int VideoStore::write_packet(AVPacket *pkt, AVStream *stream) {
pkt->pos = -1;
pkt->stream_index = stream->index;
if ( pkt->dts < stream->cur_dts ) {
- Warning("non increasing dts, fixing");
+ Debug(1, "non increasing dts, fixing. our dts %" PRId64 " stream cur_dts %" PRId64, pkt->dts, stream->cur_dts);
pkt->dts = stream->cur_dts;
- if ( pkt->dts > pkt->pts ) {
+ if ( (pkt->pts != AV_NOPTS_VALUE) && (pkt->dts > pkt->pts) ) {
Debug(1,
- "pkt.dts(%" PRId64 ") must be <= pkt.pts(%" PRId64 ")."
+ "pkt.dts %" PRId64 " must be <= pkt.pts %" PRId64 "."
"Decompression must happen before presentation.",
pkt->dts, pkt->pts);
pkt->pts = pkt->dts;
}
- } else if ( pkt->dts > pkt->pts ) {
+ } else if ( (pkt->pts != AV_NOPTS_VALUE) && (pkt->dts > pkt->pts) ) {
Debug(1,
"pkt.dts(%" PRId64 ") must be <= pkt.pts(%" PRId64 ")."
"Decompression must happen before presentation.",
pkt->dts, pkt->pts);
pkt->dts = pkt->pts;
+ } else {
+ Debug(1, "Acceptable pts and dts. cur_dts = %" PRId64, stream->cur_dts);
}
dumpPacket(stream, pkt, "finished pkt");
- ret = av_interleaved_write_frame(oc, pkt);
+ int ret = av_interleaved_write_frame(oc, pkt);
if ( ret != 0 ) {
Error("Error writing packet: %s",
av_make_error_string(ret).c_str());
} else {
Debug(2, "Success writing packet");
}
-} // end int VideoStore::write_packet(AVPacket *pkt, AVStream *stream)
-
-int VideoStore::resample_audio() {
- // Resample the in_frame into the audioSampleBuffer until we process the whole
- // decoded data. Note: pts does not survive resampling or converting
-#if defined(HAVE_LIBSWRESAMPLE) || defined(HAVE_LIBAVRESAMPLE)
-#if defined(HAVE_LIBSWRESAMPLE)
- Debug(2, "Converting %d to %d samples using swresample",
- in_frame->nb_samples, out_frame->nb_samples);
- ret = swr_convert_frame(resample_ctx, out_frame, in_frame);
- if ( ret < 0 ) {
- Error("Could not resample frame (error '%s')",
- av_make_error_string(ret).c_str());
- return 0;
- }
- zm_dump_frame(out_frame, "Out frame after resample");
- out_frame->pkt_duration = in_frame->pkt_duration; // resampling doesn't alter duration
-
- ret = av_audio_fifo_realloc(fifo, av_audio_fifo_size(fifo) + out_frame->nb_samples);
- if ( ret < 0 ) {
- Error("Could not reallocate FIFO");
- return 0;
- }
- /** Store the new samples in the FIFO buffer. */
- ret = av_audio_fifo_write(fifo, (void **)out_frame->data, out_frame->nb_samples);
- if ( ret < out_frame->nb_samples ) {
- Error("Could not write data to FIFO. %d written, expecting %d. Reason %s",
- ret, out_frame->nb_samples, av_make_error_string(ret).c_str());
- return 0;
- }
-
- // Reset frame_size to output_frame_size
- int frame_size = audio_out_ctx->frame_size;
-
- // AAC requires 1024 samples per encode. Our input tends to be something else, so need to buffer them.
- if ( frame_size > av_audio_fifo_size(fifo) ) {
- Debug(1, "Not enough samples in fifo for AAC codec frame_size %d > fifo size %d",
- frame_size, av_audio_fifo_size(fifo));
- return 0;
- }
-
- if ( av_audio_fifo_read(fifo, (void **)out_frame->data, frame_size) < frame_size ) {
- Error("Could not read data from FIFO");
- return 0;
- }
- out_frame->nb_samples = frame_size;
- zm_dump_frame(out_frame, "Out frame after fifo read");
- // resampling changes the duration because the timebase is 1/samples
- // I think we should be dealing in codec timebases not stream
- if ( in_frame->pts != AV_NOPTS_VALUE ) {
- out_frame->pts = av_rescale_q(
- in_frame->pts,
- audio_in_ctx->time_base,
- audio_out_ctx->time_base);
- }
- zm_dump_frame(out_frame, "Out frame after timestamp conversion");
-#else
-#if defined(HAVE_LIBAVRESAMPLE)
- ret = avresample_convert(resample_ctx, NULL, 0, 0, in_frame->data,
- 0, in_frame->nb_samples);
- if ( ret < 0 ) {
- Error("Could not resample frame (error '%s')",
- av_make_error_string(ret).c_str());
- return 0;
- }
-
- int frame_size = audio_out_ctx->frame_size;
-
- int samples_available = avresample_available(resample_ctx);
- if ( samples_available < frame_size ) {
- Debug(1, "Not enough samples yet (%d)", samples_available);
- return 0;
- }
-
- // Read a frame audio data from the resample fifo
- if ( avresample_read(resample_ctx, out_frame->data, frame_size) !=
- frame_size) {
- Warning("Error reading resampled audio.");
- return 0;
- }
-#endif
-#endif
-#else
- Error("Have audio codec but no resampler?!");
- return 0;
-#endif
- return 1;
-} // end int VideoStore::resample_audio
+ return ret;
+} // end int VideoStore::write_packet(AVPacket *pkt, AVStream *stream)
diff --git a/src/zm_videostore.h b/src/zm_videostore.h
index 2940bc2e7..f8a2f2a97 100644
--- a/src/zm_videostore.h
+++ b/src/zm_videostore.h
@@ -5,12 +5,12 @@
extern "C" {
#ifdef HAVE_LIBSWRESAMPLE
#include "libswresample/swresample.h"
- #include "libavutil/audio_fifo.h"
#else
#ifdef HAVE_LIBAVRESAMPLE
#include "libavresample/avresample.h"
#endif
#endif
+#include "libavutil/audio_fifo.h"
}
#if HAVE_LIBAVCODEC
@@ -38,9 +38,8 @@ private:
AVFrame *out_frame;
AVCodecContext *video_in_ctx;
- AVCodec *audio_in_codec;
+ const AVCodec *audio_in_codec;
AVCodecContext *audio_in_ctx;
- int ret;
// The following are used when encoding the audio stream to AAC
AVStream *audio_out_stream;
@@ -48,12 +47,12 @@ private:
AVCodecContext *audio_out_ctx;
#ifdef HAVE_LIBSWRESAMPLE
SwrContext *resample_ctx;
- AVAudioFifo *fifo;
#else
#ifdef HAVE_LIBAVRESAMPLE
AVAudioResampleContext* resample_ctx;
#endif
#endif
+ AVAudioFifo *fifo;
uint8_t *converted_in_samples;
const char *filename;
@@ -77,8 +76,6 @@ private:
int64_t audio_next_dts;
bool setup_resampler();
- int resample_audio();
-
int write_packet(AVPacket *pkt, AVStream *stream);
public:
diff --git a/src/zmc.cpp b/src/zmc.cpp
index bebc0bc7d..65a8d3e12 100644
--- a/src/zmc.cpp
+++ b/src/zmc.cpp
@@ -187,8 +187,8 @@ int main(int argc, char *argv[]) {
snprintf(log_id_string, sizeof(log_id_string), "zmc_m%d", monitor_id);
}
+ logInit(log_id_string);
zmLoadConfig();
-
logInit(log_id_string);
hwcaps_detect();
diff --git a/utils/packpack/startpackpack.sh b/utils/packpack/startpackpack.sh
index fd84a3923..ea1aa0e8b 100755
--- a/utils/packpack/startpackpack.sh
+++ b/utils/packpack/startpackpack.sh
@@ -138,7 +138,7 @@ movecrud () {
# previsouly part of installzm.sh
# install the trusty deb and test zoneminder
-installtrusty () {
+install_deb () {
# Check we've got gdebi installed
type gdebi 2>&1 > /dev/null
@@ -347,8 +347,8 @@ if [ "${TRAVIS_EVENT_TYPE}" == "cron" ] || [ "${TRAVIS}" != "true" ]; then
echo "Starting packpack..."
execpackpack
- if [ "${OS}" == "ubuntu" ] && [ "${DIST}" == "trusty" ] && [ "${ARCH}" == "x86_64" ] && [ "${TRAVIS}" == "true" ]; then
- installtrusty
+ if [ "${TRAVIS}" == "true" ]; then
+ install_deb
fi
fi
@@ -369,7 +369,7 @@ elif [ "${OS}" == "ubuntu" ] && [ "${DIST}" == "trusty" ] && [ "${ARCH}" == "x86
# If we are running inside Travis then attempt to install the deb we just built
if [ "${TRAVIS}" == "true" ]; then
- installtrusty
+ install_deb
fi
fi
diff --git a/web/includes/Event.php b/web/includes/Event.php
index e8b6d15be..02ebf50c0 100644
--- a/web/includes/Event.php
+++ b/web/includes/Event.php
@@ -142,16 +142,14 @@ class Event extends ZM_Object {
# Assumption: All events have a start time
$start_date = date_parse($this->{'StartTime'});
if ( ! $start_date ) {
- Error('Unable to parse start time for event ' . $this->{'Id'} . ' not deleting files.');
- return;
+ throw new Exception('Unable to parse start time for event ' . $this->{'Id'} . ' not deleting files.');
}
$start_date['year'] = $start_date['year'] % 100;
# So this is because ZM creates a link under the day pointing to the time that the event happened.
$link_path = $this->Link_Path();
if ( ! $link_path ) {
- Error('Unable to determine link path for event '.$this->{'Id'}.' not deleting files.');
- return;
+ throw new Exception('Unable to determine link path for event '.$this->{'Id'}.' not deleting files.');
}
$Storage = $this->Storage();
@@ -159,8 +157,7 @@ class Event extends ZM_Object {
if ( $id_files = glob($eventlink_path) ) {
if ( ! $eventPath = readlink($id_files[0]) ) {
- Error("Unable to read link at $id_files[0]");
- return;
+ throw new Exception("Unable to read link at $id_files[0]");
}
# I know we are using arrays here, but really there can only ever be 1 in the array
$eventPath = preg_replace('/\.'.$this->{'Id'}.'$/', $eventPath, $id_files[0]);
@@ -179,8 +176,7 @@ class Event extends ZM_Object {
} else {
$eventPath = $this->Path();
if ( ! $eventPath ) {
- Error('No event Path in Event delete. Not deleting');
- return;
+ throw new Exception('No event Path in Event delete. Not deleting');
}
deletePath($eventPath);
if ( $this->SecondaryStorageId() ) {
@@ -199,6 +195,9 @@ class Event extends ZM_Object {
$dbConn->commit();
} catch (PDOException $e) {
$dbConn->rollback();
+ } catch (Exception $e) {
+ Error($e->getMessage());
+ $dbConn->rollback();
}
} # end Event->delete
@@ -254,7 +253,7 @@ class Event extends ZM_Object {
}
}
- $streamSrc .= '?'.http_build_query($args,'', $querySep);
+ $streamSrc .= '?'.http_build_query($args, '', $querySep);
return $streamSrc;
} // end function getStreamSrc
diff --git a/web/includes/Server.php b/web/includes/Server.php
index 535ea44ed..2f9d038a9 100644
--- a/web/includes/Server.php
+++ b/web/includes/Server.php
@@ -103,6 +103,11 @@ class Server {
}
public function Url( $port = null ) {
+ if ( !$this->Id() ) {
+ # Trying to guess and make up values tends to break proxies. So just return nothing
+ # so that the resulting url will be something like "?view="
+ return '';
+ }
$url = $this->Protocol().'://';
$url .= $this->Hostname();
if ( $port ) {
diff --git a/web/includes/actions/events.php b/web/includes/actions/events.php
index 08782a8a2..abea69b60 100644
--- a/web/includes/actions/events.php
+++ b/web/includes/actions/events.php
@@ -44,11 +44,9 @@ if ( $action == 'archive' ) {
$dbConn->commit();
$refreshParent = true;
} else if ( $action == 'delete' ) {
- $dbConn->beginTransaction();
foreach ( getAffectedIds('eids') as $markEid ) {
deleteEvent($markEid);
}
- $dbConn->commit();
$refreshParent = true;
}
?>
diff --git a/web/includes/actions/user.php b/web/includes/actions/user.php
index a786f78d7..bdbafd176 100644
--- a/web/includes/actions/user.php
+++ b/web/includes/actions/user.php
@@ -37,7 +37,6 @@ if ( $action == 'user' ) {
if ( $_REQUEST['newUser']['Password'] ) {
$changes['Password'] = 'Password = '.$pass_hash;
- ZM\Info('PASS CMD='.$changes['Password']);
} else {
unset($changes['Password']);
}
@@ -47,7 +46,7 @@ if ( $action == 'user' ) {
dbQuery('UPDATE Users SET '.implode(', ', $changes).' WHERE Id = ?', array($_REQUEST['uid']));
# If we are updating the logged in user, then update our session user data.
if ( $user and ( $dbUser['Username'] == $user['Username'] ) )
- userLogin($dbUser['Username'], $dbUser['Password']);
+ generateAuthHash(ZM_AUTH_HASH_IPS);
} else {
dbQuery('INSERT INTO Users SET '.implode(', ', $changes));
}
@@ -71,13 +70,13 @@ if ( $action == 'user' ) {
if ( !empty($_REQUEST['newUser']['Password']) ) {
$changes['Password'] = 'Password = '.$pass_hash;
- }
-
- else
+ } else {
unset($changes['Password']);
+ }
if ( count($changes) ) {
dbQuery('UPDATE Users SET '.implode(', ', $changes).' WHERE Id=?', array($uid));
$refreshParent = true;
+ generateAuthHash(ZM_AUTH_HASH_IPS);
}
$view = 'none';
}
diff --git a/web/includes/database.php b/web/includes/database.php
index d941a01e0..5ec54f163 100644
--- a/web/includes/database.php
+++ b/web/includes/database.php
@@ -56,7 +56,7 @@ function dbConnect() {
$dbConn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbConn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
- } catch(PDOException $ex ) {
+ } catch(PDOException $ex) {
echo 'Unable to connect to ZM db.' . $ex->getMessage();
error_log('Unable to connect to ZM DB ' . $ex->getMessage());
$dbConn = null;
diff --git a/web/includes/functions.php b/web/includes/functions.php
index ff578eff7..7f5e32aaa 100644
--- a/web/includes/functions.php
+++ b/web/includes/functions.php
@@ -120,33 +120,6 @@ function CORSHeaders() {
}
}
-function getStreamSrc( $args, $querySep='&' ) {
- $streamSrc = ZM_BASE_URL.ZM_PATH_ZMS;
-
- if ( ZM_OPT_USE_AUTH ) {
- if ( ZM_AUTH_RELAY == 'hashed' ) {
- $args[] = 'auth='.generateAuthHash( ZM_AUTH_HASH_IPS );
- } elseif ( ZM_AUTH_RELAY == 'plain' ) {
- $args[] = 'user='.$_SESSION['username'];
- $args[] = 'pass='.$_SESSION['password'];
- } elseif ( ZM_AUTH_RELAY == 'none' ) {
- $args[] = 'user='.$_SESSION['username'];
- }
- }
- if ( !in_array( 'mode=single', $args ) && !empty($GLOBALS['connkey']) ) {
- $args[] = 'connkey='.$GLOBALS['connkey'];
- }
- if ( ZM_RAND_STREAM ) {
- $args[] = 'rand='.time();
- }
-
- if ( count($args) ) {
- $streamSrc .= '?'.join( $querySep, $args );
- }
-
- return( $streamSrc );
-}
-
function getMimeType( $file ) {
if ( function_exists('mime_content_type') ) {
return( mime_content_type( $file ) );
@@ -156,7 +129,7 @@ function getMimeType( $file ) {
finfo_close($finfo);
return( $mimeType );
}
- return( trim( exec( 'file -bi '.escapeshellarg( $file ).' 2>/dev/null' ) ) );
+ return trim(exec('file -bi '.escapeshellarg($file).' 2>/dev/null'));
}
function outputVideoStream( $id, $src, $width, $height, $format, $title='' ) {
@@ -169,8 +142,8 @@ function getVideoStreamHTML( $id, $src, $width, $height, $format, $title='' ) {
$height = validInt($height);
$title = validHtmlStr($title);
- if ( file_exists( $src ) ) {
- $mimeType = getMimeType( $src );
+ if ( file_exists($src) ) {
+ $mimeType = getMimeType($src);
} else {
switch( $format ) {
case 'asf' :
@@ -205,7 +178,6 @@ function getVideoStreamHTML( $id, $src, $width, $height, $format, $title='' ) {
case 'video/x-ms-asf' :
case 'video/x-msvideo' :
case 'video/mp4' :
- {
if ( isWindows() ) {
return '';
}
- }
case 'video/quicktime' :
- {
return '';
- }
case 'application/x-shockwave-flash' :
- {
return '';
- }
} # end switch
} # end if use object tags
return '
- 'configureButtons(this)')); ?>
+ 'configureButtons')); ?>
-
-
+
+
-
-
+
+
-
-
+
+