diff --git a/CMakeLists.txt b/CMakeLists.txt index 87010afd7..3cea30c87 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ # cmake_minimum_required (VERSION 2.6) project (zoneminder) -set(zoneminder_VERSION "1.26.4") +set(zoneminder_VERSION "1.26.5") # CMake does not allow out-of-source build if CMakeCache.exists in the source folder. Abort and notify the user to save him from headache why it doesn't work. if((NOT (CMAKE_BINARY_DIR STREQUAL CMAKE_SOURCE_DIR)) AND (EXISTS "${CMAKE_SOURCE_DIR}/CMakeCache.txt")) @@ -62,12 +62,11 @@ set(ZM_EXTRA_LIBS "" CACHE STRING "A list of optional libraries, separated by se set(ZM_MYSQL_ENGINE "InnoDB" CACHE STRING "MySQL engine to use with database, default: InnoDB") set(ZM_NO_MMAP "OFF" CACHE BOOL "Set to ON to not use mmap shared memory. Shouldn't be enabled unless you experience problems with the shared memory. default: OFF") set(ZM_NO_FFMPEG "OFF" CACHE BOOL "Set to ON to skip ffmpeg checks and force building ZM without ffmpeg. default: OFF") +set(ZM_NO_LIBVLC "OFF" CACHE BOOL "Set to ON to skip libvlc checks and force building ZM without libvlc. default: OFF") set(ZM_NO_X10 "OFF" CACHE BOOL "Set to ON to build ZoneMinder without X10 support. default: OFF") -set(ZM_PERL_SUBPREFIX "${CMAKE_INSTALL_LIBDIR}/perl5" CACHE PATH "Use a different directory for the zm perl modules. NOTE: This is a subprefix, e.g. lib will be turned into /lib, default: ${CMAKE_INSTALL_LIBDIR}/perl5") +set(ZM_PERL_SUBPREFIX "${CMAKE_INSTALL_LIBDIR}/perl5" CACHE PATH "Use a different directory for the zm perl modules. NOTE: This is a subprefix, e.g. lib will be turned into /lib, default: /perl5") set(ZM_PERL_USE_PATH "${CMAKE_INSTALL_PREFIX}/${ZM_PERL_SUBPREFIX}" CACHE PATH "Override the include path for zm perl modules. Useful if you are moving the perl modules without using the ZM_PERL_SUBPREFIX option. default: /") set(ZM_TARGET_DISTRO "" CACHE STRING "Build ZoneMinder for a specific distribution. Currently, valid names are: f19, el6") -# Only required for cmakecacheimport: -set(CMAKE_INSTALL_FULL_BINDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}" CACHE PATH "Override default binary directory") # Required for certain checks to work set(CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES} stdio.h stdlib.h math.h signal.h) @@ -88,7 +87,6 @@ check_function_exists("sendfile" HAVE_SENDFILE) check_function_exists("backtrace" HAVE_DECL_BACKTRACE) check_function_exists("backtrace_symbols" HAVE_DECL_BACKTRACE_SYMBOLS) check_function_exists("posix_memalign" HAVE_POSIX_MEMALIGN) -check_prototype_definition("round" "double round (double x)" "0.0" "math.h" HAVE_DECL_ROUND) check_type_size("siginfo_t" HAVE_SIGINFO_T) check_type_size("ucontext_t" HAVE_UCONTEXT_T) @@ -98,9 +96,9 @@ check_type_size("ucontext_t" HAVE_UCONTEXT_T) find_package(ZLIB) if(ZLIB_FOUND) set(HAVE_LIBZLIB 1) - list(APPEND ZM_BIN_LIBS ${ZLIB_LIBRARIES}) - include_directories(${ZLIB_INCLUDE_DIRS}) - set(CMAKE_REQUIRED_INCLUDES ${ZLIB_INCLUDE_DIRS}) + list(APPEND ZM_BIN_LIBS "${ZLIB_LIBRARIES}") + include_directories("${ZLIB_INCLUDE_DIR}") + set(CMAKE_REQUIRED_INCLUDES "${ZLIB_INCLUDE_DIR}") check_include_file("zlib.h" HAVE_ZLIB_H) set(optlibsfound "${optlibsfound} zlib") else(ZLIB_FOUND) @@ -124,10 +122,10 @@ endif(CURL_FOUND) find_package(JPEG) if(JPEG_FOUND) set(HAVE_LIBJPEG 1) - list(APPEND ZM_BIN_LIBS ${JPEG_LIBRARIES}) + list(APPEND ZM_BIN_LIBS "${JPEG_LIBRARIES}") #link_directories(${JPEG_LIBRARY}) - include_directories(${JPEG_INCLUDE_DIR}) - set(CMAKE_REQUIRED_INCLUDES ${JPEG_INCLUDE_DIR}) + include_directories("${JPEG_INCLUDE_DIR}") + set(CMAKE_REQUIRED_INCLUDES "${JPEG_INCLUDE_DIR}") check_include_files("stdio.h;jpeglib.h" HAVE_JPEGLIB_H) if(NOT HAVE_JPEGLIB_H) message(FATAL_ERROR " zm requires libjpeg headers - check that libjpeg development packages are installed") @@ -141,9 +139,9 @@ find_package(OpenSSL) if(OPENSSL_FOUND) set(HAVE_LIBOPENSSL 1) set(HAVE_LIBCRYPTO 1) - list(APPEND ZM_BIN_LIBS ${OPENSSL_LIBRARIES}) - include_directories(${OPENSSL_INCLUDE_DIR}) - set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR}) + list(APPEND ZM_BIN_LIBS "${OPENSSL_LIBRARIES}") + include_directories("${OPENSSL_INCLUDE_DIR}") + set(CMAKE_REQUIRED_INCLUDES "${OPENSSL_INCLUDE_DIR}") check_include_file("openssl/md5.h" HAVE_OPENSSL_MD5_H) set(optlibsfound "${optlibsfound} OpenSSL") else(OPENSSL_FOUND) @@ -154,11 +152,11 @@ endif(OPENSSL_FOUND) find_library(PTHREAD_LIBRARIES pthread) if(PTHREAD_LIBRARIES) set(HAVE_LIBPTHREAD 1) - list(APPEND ZM_BIN_LIBS ${PTHREAD_LIBRARIES}) + list(APPEND ZM_BIN_LIBS "${PTHREAD_LIBRARIES}") find_path(PTHREAD_INCLUDE_DIR pthread.h) if(PTHREAD_INCLUDE_DIR) - include_directories(${PTHREAD_INCLUDE_DIR}) - set(CMAKE_REQUIRED_INCLUDES ${PTHREAD_INCLUDE_DIR}) + include_directories("${PTHREAD_INCLUDE_DIR}") + set(CMAKE_REQUIRED_INCLUDES "${PTHREAD_INCLUDE_DIR}") endif(PTHREAD_INCLUDE_DIR) mark_as_advanced(FORCE PTHREAD_LIBRARIES PTHREAD_INCLUDE_DIR) check_include_file("pthread.h" HAVE_PTHREAD_H) @@ -173,11 +171,11 @@ endif(PTHREAD_LIBRARIES) find_library(PCRE_LIBRARIES pcre) if(PCRE_LIBRARIES) set(HAVE_LIBPCRE 1) - list(APPEND ZM_BIN_LIBS ${PCRE_LIBRARIES}) + list(APPEND ZM_BIN_LIBS "${PCRE_LIBRARIES}") find_path(PCRE_INCLUDE_DIR pcre.h) if(PCRE_INCLUDE_DIR) - include_directories(${PCRE_INCLUDE_DIR}) - set(CMAKE_REQUIRED_INCLUDES ${PCRE_INCLUDE_DIR}) + include_directories("${PCRE_INCLUDE_DIR}") + set(CMAKE_REQUIRED_INCLUDES "${PCRE_INCLUDE_DIR}") endif(PCRE_INCLUDE_DIR) mark_as_advanced(FORCE PCRE_LIBRARIES PCRE_INCLUDE_DIR) check_include_file("pcre.h" HAVE_PCRE_H) @@ -190,11 +188,11 @@ endif(PCRE_LIBRARIES) find_library(GCRYPT_LIBRARIES gcrypt) if(GCRYPT_LIBRARIES) set(HAVE_LIBGCRYPT 1) - list(APPEND ZM_BIN_LIBS ${GCRYPT_LIBRARIES}) + list(APPEND ZM_BIN_LIBS "${GCRYPT_LIBRARIES}") find_path(GCRYPT_INCLUDE_DIR gcrypt.h) if(GCRYPT_INCLUDE_DIR) - include_directories(${GCRYPT_INCLUDE_DIR}) - set(CMAKE_REQUIRED_INCLUDES ${GCRYPT_INCLUDE_DIR}) + include_directories("${GCRYPT_INCLUDE_DIR}") + set(CMAKE_REQUIRED_INCLUDES "${GCRYPT_INCLUDE_DIR}") endif(GCRYPT_INCLUDE_DIR) mark_as_advanced(FORCE GCRYPT_LIBRARIES GCRYPT_INCLUDE_DIR) check_include_file("gcrypt.h" HAVE_GCRYPT_H) @@ -207,11 +205,11 @@ endif(GCRYPT_LIBRARIES) find_library(GNUTLS_LIBRARIES gnutls) if(GNUTLS_LIBRARIES) set(HAVE_LIBGNUTLS 1) - list(APPEND ZM_BIN_LIBS ${GNUTLS_LIBRARIES}) + list(APPEND ZM_BIN_LIBS "${GNUTLS_LIBRARIES}") find_path(GNUTLS_INCLUDE_DIR gnutls/gnutls.h) if(GNUTLS_INCLUDE_DIR) - include_directories(${GNUTLS_INCLUDE_DIR}) - set(CMAKE_REQUIRED_INCLUDES ${GNUTLS_INCLUDE_DIR}) + include_directories("${GNUTLS_INCLUDE_DIR}") + set(CMAKE_REQUIRED_INCLUDES "${GNUTLS_INCLUDE_DIR}") endif(GNUTLS_INCLUDE_DIR) mark_as_advanced(FORCE GNUTLS_LIBRARIES GNUTLS_INCLUDE_DIR) check_include_file("gnutls/openssl.h" HAVE_GNUTLS_OPENSSL_H) @@ -225,11 +223,11 @@ endif(GNUTLS_LIBRARIES) find_library(MYSQLCLIENT_LIBRARIES mysqlclient PATH_SUFFIXES mysql) if(MYSQLCLIENT_LIBRARIES) set(HAVE_LIBMYSQLCLIENT 1) - list(APPEND ZM_BIN_LIBS ${MYSQLCLIENT_LIBRARIES}) + list(APPEND ZM_BIN_LIBS "${MYSQLCLIENT_LIBRARIES}") find_path(MYSQLCLIENT_INCLUDE_DIR mysql/mysql.h) if(MYSQLCLIENT_INCLUDE_DIR) - include_directories(${MYSQLCLIENT_INCLUDE_DIR}) - set(CMAKE_REQUIRED_INCLUDES ${MYSQLCLIENT_INCLUDE_DIR}) + include_directories("${MYSQLCLIENT_INCLUDE_DIR}") + set(CMAKE_REQUIRED_INCLUDES "${MYSQLCLIENT_INCLUDE_DIR}") endif(MYSQLCLIENT_INCLUDE_DIR) mark_as_advanced(FORCE MYSQLCLIENT_LIBRARIES MYSQLCLIENT_INCLUDE_DIR) check_include_file("mysql/mysql.h" HAVE_MYSQL_H) @@ -240,17 +238,19 @@ else(MYSQLCLIENT_LIBRARIES) message(FATAL_ERROR "zm requires mysqlclient but it was not found on your system") endif(MYSQLCLIENT_LIBRARIES) +set(PATH_FFMPEG "") +set(OPT_FFMPEG "no") # Do not check for ffmpeg if ZM_NO_FFMPEG is on if(NOT ZM_NO_FFMPEG) # avformat (using find_library and find_path) find_library(AVFORMAT_LIBRARIES avformat) if(AVFORMAT_LIBRARIES) set(HAVE_LIBAVFORMAT 1) - list(APPEND ZM_BIN_LIBS ${AVFORMAT_LIBRARIES}) + list(APPEND ZM_BIN_LIBS "${AVFORMAT_LIBRARIES}") find_path(AVFORMAT_INCLUDE_DIR "libavformat/avformat.h") if(AVFORMAT_INCLUDE_DIR) - include_directories(${AVFORMAT_INCLUDE_DIR}) - set(CMAKE_REQUIRED_INCLUDES ${AVFORMAT_INCLUDE_DIR}) + include_directories("${AVFORMAT_INCLUDE_DIR}") + set(CMAKE_REQUIRED_INCLUDES "${AVFORMAT_INCLUDE_DIR}") endif(AVFORMAT_INCLUDE_DIR) mark_as_advanced(FORCE AVFORMAT_LIBRARIES AVFORMAT_INCLUDE_DIR) check_include_file("libavformat/avformat.h" HAVE_LIBAVFORMAT_AVFORMAT_H) @@ -263,11 +263,11 @@ if(NOT ZM_NO_FFMPEG) find_library(AVCODEC_LIBRARIES avcodec) if(AVCODEC_LIBRARIES) set(HAVE_LIBAVCODEC 1) - list(APPEND ZM_BIN_LIBS ${AVCODEC_LIBRARIES}) + list(APPEND ZM_BIN_LIBS "${AVCODEC_LIBRARIES}") find_path(AVCODEC_INCLUDE_DIR "libavcodec/avcodec.h") if(AVCODEC_INCLUDE_DIR) - include_directories(${AVCODEC_INCLUDE_DIR}) - set(CMAKE_REQUIRED_INCLUDES ${AVCODEC_INCLUDE_DIR}) + include_directories("${AVCODEC_INCLUDE_DIR}") + set(CMAKE_REQUIRED_INCLUDES "${AVCODEC_INCLUDE_DIR}") endif(AVCODEC_INCLUDE_DIR) mark_as_advanced(FORCE AVCODEC_LIBRARIES AVCODEC_INCLUDE_DIR) check_include_file("libavcodec/avcodec.h" HAVE_LIBAVCODEC_AVCODEC_H) @@ -280,11 +280,11 @@ if(NOT ZM_NO_FFMPEG) find_library(AVDEVICE_LIBRARIES avdevice) if(AVDEVICE_LIBRARIES) set(HAVE_LIBAVDEVICE 1) - list(APPEND ZM_BIN_LIBS ${AVDEVICE_LIBRARIES}) + list(APPEND ZM_BIN_LIBS "${AVDEVICE_LIBRARIES}") find_path(AVDEVICE_INCLUDE_DIR "libavdevice/avdevice.h") if(AVDEVICE_INCLUDE_DIR) - include_directories(${AVDEVICE_INCLUDE_DIR}) - set(CMAKE_REQUIRED_INCLUDES ${AVDEVICE_INCLUDE_DIR}) + include_directories("${AVDEVICE_INCLUDE_DIR}") + set(CMAKE_REQUIRED_INCLUDES "${AVDEVICE_INCLUDE_DIR}") endif(AVDEVICE_INCLUDE_DIR) mark_as_advanced(FORCE AVDEVICE_LIBRARIES AVDEVICE_INCLUDE_DIR) check_include_file("libavdevice/avdevice.h" HAVE_LIBAVDEVICE_AVDEVICE_H) @@ -297,11 +297,11 @@ if(NOT ZM_NO_FFMPEG) find_library(AVUTIL_LIBRARIES avutil) if(AVUTIL_LIBRARIES) set(HAVE_LIBAVUTIL 1) - list(APPEND ZM_BIN_LIBS ${AVUTIL_LIBRARIES}) + list(APPEND ZM_BIN_LIBS "${AVUTIL_LIBRARIES}") find_path(AVUTIL_INCLUDE_DIR "libavutil/avutil.h") if(AVUTIL_INCLUDE_DIR) - include_directories(${AVUTIL_INCLUDE_DIR}) - set(CMAKE_REQUIRED_INCLUDES ${AVUTIL_INCLUDE_DIR}) + include_directories("${AVUTIL_INCLUDE_DIR}") + set(CMAKE_REQUIRED_INCLUDES "${AVUTIL_INCLUDE_DIR}") endif(AVUTIL_INCLUDE_DIR) mark_as_advanced(FORCE AVUTIL_LIBRARIES AVUTIL_INCLUDE_DIR) check_include_file("libavutil/avutil.h" HAVE_LIBAVUTIL_AVUTIL_H) @@ -315,11 +315,11 @@ if(NOT ZM_NO_FFMPEG) find_library(SWSCALE_LIBRARIES swscale) if(SWSCALE_LIBRARIES) set(HAVE_LIBSWSCALE 1) - list(APPEND ZM_BIN_LIBS ${SWSCALE_LIBRARIES}) + list(APPEND ZM_BIN_LIBS "${SWSCALE_LIBRARIES}") find_path(SWSCALE_INCLUDE_DIR "libswscale/swscale.h") if(SWSCALE_INCLUDE_DIR) - include_directories(${SWSCALE_INCLUDE_DIR}) - set(CMAKE_REQUIRED_INCLUDES ${SWSCALE_INCLUDE_DIR}) + include_directories("${SWSCALE_INCLUDE_DIR}") + set(CMAKE_REQUIRED_INCLUDES "${SWSCALE_INCLUDE_DIR}") endif(SWSCALE_INCLUDE_DIR) mark_as_advanced(FORCE SWSCALE_LIBRARIES SWSCALE_INCLUDE_DIR) check_include_file("libswscale/swscale.h" HAVE_LIBSWSCALE_SWSCALE_H) @@ -327,8 +327,37 @@ if(NOT ZM_NO_FFMPEG) else(SWSCALE_LIBRARIES) set(optlibsnotfound "${optlibsnotfound} SWScale") endif(SWSCALE_LIBRARIES) + + # Find the path to the ffmpeg executable + find_program(FFMPEG_EXECUTABLE ffmpeg PATH_SUFFIXES ffmpeg) + if(FFMPEG_EXECUTABLE) + set(PATH_FFMPEG "${FFMPEG_EXECUTABLE}") + set(OPT_FFMPEG "yes") + mark_as_advanced(FFMPEG_EXECUTABLE) + endif(FFMPEG_EXECUTABLE) + endif(NOT ZM_NO_FFMPEG) +# Do not check for libvlc if ZM_NO_LIBVLC is on +if(NOT ZM_NO_LIBVLC) + # libvlc (using find_library and find_path) + find_library(LIBVLC_LIBRARIES vlc) + if(LIBVLC_LIBRARIES) + set(HAVE_LIBVLC 1) + list(APPEND ZM_BIN_LIBS "${LIBVLC_LIBRARIES}") + find_path(LIBVLC_INCLUDE_DIR "vlc/vlc.h") + if(LIBVLC_INCLUDE_DIR) + include_directories("${LIBVLC_INCLUDE_DIR}") + set(CMAKE_REQUIRED_INCLUDES "${LIBVLC_INCLUDE_DIR}") + endif(LIBVLC_INCLUDE_DIR) + mark_as_advanced(FORCE LIBVLC_LIBRARIES LIBVLC_INCLUDE_DIR) + check_include_file("vlc/vlc.h" HAVE_VLC_VLC_H) + set(optlibsfound "${optlibsfound} libVLC") + else(LIBVLC_LIBRARIES) + set(optlibsnotfound "${optlibsnotfound} libVLC") + endif(LIBVLC_LIBRARIES) +endif(NOT ZM_NO_LIBVLC) + # *** END OF LIBRARY CHECKS *** # Check for gnutls or crypto @@ -368,18 +397,18 @@ endif(NOT ZM_NO_MMAP) # Check for authenication functions if(HAVE_OPENSSL_MD5_H) - set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES}) - set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR}) + set(CMAKE_REQUIRED_LIBRARIES "${OPENSSL_LIBRARIES}") + set(CMAKE_REQUIRED_INCLUDES "${OPENSSL_INCLUDE_DIR}") check_prototype_definition(MD5 "unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md)" "NULL" "openssl/md5.h" HAVE_MD5_OPENSSL) endif(HAVE_OPENSSL_MD5_H) if(HAVE_GNUTLS_OPENSSL_H) - set(CMAKE_REQUIRED_LIBRARIES ${GNUTLS_LIBRARIES}) - set(CMAKE_REQUIRED_INCLUDES ${GNUTLS_INCLUDE_DIR}) + set(CMAKE_REQUIRED_LIBRARIES "${GNUTLS_LIBRARIES}") + set(CMAKE_REQUIRED_INCLUDES "${GNUTLS_INCLUDE_DIR}") check_prototype_definition(MD5 "unsigned char *MD5 (const unsigned char *buf, unsigned long len, unsigned char *md)" "NULL" "gnutls/openssl.h" HAVE_MD5_GNUTLS) endif(HAVE_GNUTLS_OPENSSL_H) if(HAVE_GNUTLS_GNUTLS_H) - set(CMAKE_REQUIRED_LIBRARIES ${GNUTLS_LIBRARIES}) - set(CMAKE_REQUIRED_INCLUDES ${GNUTLS_INCLUDE_DIR}) + set(CMAKE_REQUIRED_LIBRARIES "${GNUTLS_LIBRARIES}") + set(CMAKE_REQUIRED_INCLUDES "${GNUTLS_INCLUDE_DIR}") check_prototype_definition(gnutls_fingerprint "int gnutls_fingerprint (gnutls_digest_algorithm_t algo, const gnutls_datum_t * data, void *result, size_t * result_size)" "0" "stdlib.h;gnutls/gnutls.h" HAVE_DECL_GNUTLS_FINGERPRINT) endif(HAVE_GNUTLS_GNUTLS_H) if(HAVE_MD5_OPENSSL OR HAVE_MD5_GNUTLS) @@ -431,9 +460,7 @@ message(STATUS "Using web group: ${ZM_WEB_GROUP}") set(ZM_PID "${ZM_RUNDIR}/zm.pid") set(ZM_CONFIG "/${CMAKE_INSTALL_SYSCONFDIR}/zm.conf") set(VERSION "${zoneminder_VERSION}") -set(PATH_BUILD "${PROJECT_SOURCE_DIR}") set(PKGDATADIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/zoneminder") -set(TIME_BUILD "1000000") # Don't have a solution for this one yet set(BINDIR "${CMAKE_INSTALL_FULL_BINDIR}") set(LIBDIR "${CMAKE_INSTALL_FULL_LIBDIR}") set(SYSCONFDIR "/${CMAKE_INSTALL_SYSCONFDIR}") @@ -441,6 +468,7 @@ set(WEB_PREFIX "${ZM_WEBDIR}") set(CGI_PREFIX "${ZM_CGIDIR}") set(WEB_USER "${ZM_WEB_USER}") set(WEB_GROUP "${ZM_WEB_GROUP}") +set(ZM_DB_TYPE "mysql") set(EXTRA_PERL_LIB "use lib '${ZM_PERL_USE_PATH}';") # Reassign some variables if a target distro has been specified diff --git a/README.md b/README.md index 1b5b62f13..17d7d53e8 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ root@host:~# aptitude install -y apache2 mysql-server php5 php5-mysql build-esse root@host:~# git clone https://github.com/ZoneMinder/ZoneMinder.git zoneminder; root@host:~# cd zoneminder; -root@host:~# ln -s distros/ubuntu1204; +root@host:~# ln -s distros/ubuntu1204 debian; root@host:~# dpkg-checkbuilddeps; root@host:~# dpkg-buildpackage; ``` diff --git a/cmakecacheimport.sh b/cmakecacheimport.sh index 4ae5fa49c..79253f6ad 100755 --- a/cmakecacheimport.sh +++ b/cmakecacheimport.sh @@ -44,7 +44,7 @@ if [ "$?" != "0" ]; then fi # Print some information -echo "Executables directory : $ZM_PATH_BIN" +#echo "Executables directory : $ZM_PATH_BIN" #echo "Libraries directory : $ZM_PATH_LIB" #echo "System config directory : $ZM_PATH_CONF" echo "Web directory : $ZM_PATH_WEB" @@ -60,8 +60,8 @@ echo "Database password : Not shown" CMPATH="CACHE PATH \"Imported by cmakecacheimport.sh\" FORCE" CMSTRING="CACHE STRING \"Imported by cmakecacheimport.sh\" FORCE" # Write -echo "# Generated by cmakecacheimport.sh">zm_conf.cmake -echo "set(CMAKE_INSTALL_FULL_BINDIR \"$ZM_PATH_BIN\" $CMPATH)">>zm_conf.cmake +echo "# This file was generated by cmakecacheimport.sh">zm_conf.cmake +#echo "set(CMAKE_INSTALL_FULL_BINDIR \"$ZM_PATH_BIN\" $CMPATH)">>zm_conf.cmake #echo "set(CMAKE_INSTALL_FULL_LIBDIR \"$ZM_PATH_LIB\" $CMPATH)">>zm_conf.cmake #echo "set(CMAKE_INSTALL_FULL_SYSCONFDIR \"$ZM_PATH_CONF\" $CMPATH)">>zm_conf.cmake echo "set(ZM_WEBDIR \"$ZM_PATH_WEB\" $CMPATH)">>zm_conf.cmake diff --git a/configure.ac b/configure.ac index 7ce0942a7..6e7451426 100644 --- a/configure.ac +++ b/configure.ac @@ -1,15 +1,12 @@ AC_PREREQ(2.59) -AC_INIT(zm,1.26.4,[http://www.zoneminder.com/forums/ - Please check FAQ first],zoneminder,http://www.zoneminder.com/downloads.html) +AC_INIT(zm,1.26.5,[http://www.zoneminder.com/forums/ - Please check FAQ first],zoneminder,http://www.zoneminder.com/downloads.html) AM_INIT_AUTOMAKE AC_CONFIG_SRCDIR(src/zm.h) AC_CONFIG_HEADERS(config.h) AC_SUBST([AM_CXXFLAGS], [-D__STDC_CONSTANT_MACROS]) -PATH_BUILD=`pwd` -AC_SUBST(PATH_BUILD) -TIME_BUILD=`date +'%s'` -AC_SUBST(TIME_BUILD) +AC_SUBST(VERSION) AC_ARG_VAR(ZM_DB_HOST,[Hostname where ZoneMinder database located, default localhost]) AC_ARG_VAR(ZM_DB_NAME,[Name of ZoneMinder database, default zm]) @@ -21,6 +18,9 @@ AC_ARG_VAR(ZM_RUNDIR,[Location of transient process files, default /var/run/zm]) AC_ARG_VAR(ZM_TMPDIR,[Location of temporary files, default /tmp/zm]) AC_ARG_VAR(ZM_LOGDIR,[Location of generated log files, default /var/log/zm]) +if test "$ZM_DB_TYPE" == ""; then + AC_SUBST(ZM_DB_TYPE,[mysql]) +fi if test "$ZM_DB_HOST" == ""; then AC_SUBST(ZM_DB_HOST,[localhost]) fi @@ -177,22 +177,6 @@ if test "$ENABLE_DEBUG" != "yes"; then AC_DEFINE(ZM_DBG_OFF,1,"Whether debug is switched off and compiled out") fi -ENABLE_CRASHTRACE=yes -AC_ARG_ENABLE(crashtrace, - [ --enable-crashtrace= enable or disabled crash tracing, default enabled], - [ENABLE_CRASHTRACE=$enable_crashtrace], - AC_MSG_WARN([You can call configure with the --enable-crashtrace= or --disable-crashtrace option. - This tells configure whether to compile ZoneMinder with crash tracing included. This allows a - dump of the stack trace when a ZoneMinder binary crashes or is killed by an unexpected signal. - Although this should work on most systems it does rely on un(or loosely) documented features and - so should be regarded as experimental. If you experience problems compiling zm_signal.cpp or - ZoneMinder binaries fail to shut down correctly then you should probably disable this feature. - e.g. --enable-crashtrace=yes or --disable-crashtrace]) -) -if test "$ENABLE_CRASHTRACE" != "yes"; then - AC_DEFINE(ZM_NO_CRASHTRACE,1,"Whether crash tracing is switched off and compiled out") -fi - ENABLE_MMAP=yes AC_ARG_ENABLE(mmap, [ --enable-mmap= enable or disabled mapped memory versus shared memory, default mapped], @@ -291,6 +275,7 @@ AC_CHECK_LIB(avformat,avformat_version,,AC_MSG_WARN(libavformat.a is required fo #AC_CHECK_LIB(avformat,av_new_stream,,AC_MSG_WARN(libavformat.a is required for MPEG streaming)) AC_CHECK_LIB(avdevice,avdevice_register_all,,AC_MSG_WARN(libavdevice.a may be required for MPEG streaming)) AC_CHECK_LIB(swscale,sws_scale,,,-lswscale) +AC_CHECK_LIB(vlc,libvlc_new,,AC_MSG_WARN(libvlc.a may be required for streaming)) AC_CHECK_LIB(bz2,BZ2_bzCompress,,AC_MSG_WARN(zm requires libbz2.a for recent versions of ffmpeg)) AC_CHECK_LIB(z,compress,,) @@ -329,8 +314,8 @@ AC_CHECK_HEADERS(sys/ipc.h,,,) AC_CHECK_HEADERS(sys/shm.h,,,) fi AC_CHECK_HEADERS(zlib.h,,,) +AC_CHECK_HEADERS(vlc/vlc.h,,,) -AC_CHECK_DECLS(round,,,[#include ]) if test "$ZM_SSL_LIB" == "openssl"; then AC_CHECK_DECLS(MD5,,AC_MSG_ERROR([zm requires openssl/md5.h - use ZM_SSL_LIB option to select gnutls instead]),[#include #include ]) diff --git a/db/Makefile.am b/db/Makefile.am index b6da2b5d4..9cb4e197c 100644 --- a/db/Makefile.am +++ b/db/Makefile.am @@ -1,4 +1,4 @@ -AUTOMAKE_OPTIONS = gnu +AUTOMAKE_OPTIONS = foreign zmdbdatadir = $(pkgdatadir)/db @@ -10,48 +10,5 @@ dist_zmdbdata_DATA = \ zm_create.sql \ $(dbupgrade_scripts) -dbupgrade_scripts = \ - zm_update-0.0.1.sql \ - zm_update-0.9.7.sql \ - zm_update-0.9.8.sql \ - zm_update-0.9.9.sql \ - zm_update-0.9.10.sql \ - zm_update-0.9.11.sql \ - zm_update-0.9.12.sql \ - zm_update-0.9.13.sql \ - zm_update-0.9.15.sql \ - zm_update-0.9.16.sql \ - zm_update-1.17.1.sql \ - zm_update-1.17.2.sql \ - zm_update-1.18.0.sql \ - zm_update-1.18.1.sql \ - zm_update-1.19.0.sql \ - zm_update-1.19.1.sql \ - zm_update-1.19.2.sql \ - zm_update-1.19.3.sql \ - zm_update-1.19.4.sql \ - zm_update-1.19.5.sql \ - zm_update-1.20.0.sql \ - zm_update-1.20.1.sql \ - zm_update-1.21.0.sql \ - zm_update-1.21.1.sql \ - zm_update-1.21.2.sql \ - zm_update-1.21.3.sql \ - zm_update-1.21.4.sql \ - zm_update-1.22.0.sql \ - zm_update-1.22.1.sql \ - zm_update-1.22.2.sql \ - zm_update-1.22.3.sql \ - zm_update-1.23.0.sql \ - zm_update-1.23.1.sql \ - zm_update-1.23.2.sql \ - zm_update-1.23.3.sql \ - zm_update-1.24.0.sql \ - zm_update-1.24.1.sql \ - zm_update-1.24.2.sql \ - zm_update-1.24.3.sql \ - zm_update-1.24.4.sql \ - zm_update-1.26.0.sql \ - zm_update-1.26.1.sql \ - zm_update-1.26.2.sql \ - zm_update-1.26.3.sql +dbupgrade_scripts = $(wildcard zm_update-*.sql) + diff --git a/db/zm_create.sql.in b/db/zm_create.sql.in index d9fcab3ce..e94a589e5 100644 --- a/db/zm_create.sql.in +++ b/db/zm_create.sql.in @@ -63,7 +63,7 @@ DROP TABLE IF EXISTS `Controls`; CREATE TABLE `Controls` ( `Id` int(10) unsigned NOT NULL auto_increment, `Name` varchar(64) NOT NULL default '', - `Type` enum('Local','Remote','Ffmpeg') NOT NULL default 'Local', + `Type` enum('Local','Remote','Ffmpeg','Libvlc') NOT NULL default 'Local', `Protocol` varchar(64) default NULL, `CanWake` tinyint(3) unsigned NOT NULL default '0', `CanSleep` tinyint(3) unsigned NOT NULL default '0', @@ -282,7 +282,7 @@ DROP TABLE IF EXISTS `MonitorPresets`; CREATE TABLE `MonitorPresets` ( `Id` int(10) unsigned NOT NULL auto_increment, `Name` varchar(64) NOT NULL default '', - `Type` enum('Local','Remote','File','Ffmpeg') NOT NULL default 'Local', + `Type` enum('Local','Remote','File','Ffmpeg','Libvlc') NOT NULL default 'Local', `Device` tinytext, `Channel` tinytext, `Format` int(10) unsigned default NULL, @@ -313,7 +313,7 @@ DROP TABLE IF EXISTS `Monitors`; CREATE TABLE `Monitors` ( `Id` int(10) unsigned NOT NULL auto_increment, `Name` varchar(64) NOT NULL default '', - `Type` enum('Local','Remote','File','Ffmpeg') NOT NULL default 'Local', + `Type` enum('Local','Remote','File','Ffmpeg','Libvlc') NOT NULL default 'Local', `Function` enum('None','Monitor','Modect','Record','Mocord','Nodect') NOT NULL default 'Monitor', `Enabled` tinyint(3) unsigned NOT NULL default '1', `LinkedMonitors` varchar(255) NOT NULL default '', @@ -354,7 +354,8 @@ CREATE TABLE `Monitors` ( `MaxFPS` decimal(5,2) default NULL, `AlarmMaxFPS` decimal(5,2) default NULL, `FPSReportInterval` smallint(5) unsigned NOT NULL default '250', - `RefBlendPerc` tinyint(3) unsigned NOT NULL default '10', + `RefBlendPerc` tinyint(3) unsigned NOT NULL default '6', + `AlarmRefBlendPerc` tinyint(3) unsigned NOT NULL default '3', `Controllable` tinyint(3) unsigned NOT NULL default '0', `ControlId` int(10) unsigned NOT NULL default '0', `ControlDevice` varchar(255) default NULL, diff --git a/db/zm_update-1.26.5.sql b/db/zm_update-1.26.5.sql new file mode 100644 index 000000000..01308aae4 --- /dev/null +++ b/db/zm_update-1.26.5.sql @@ -0,0 +1,9 @@ +-- +-- This updates a 1.26.4 database to 1.26.5 +-- + +-- +-- Add AlarmRefBlendPerc field for controlling the reference image blend percent during alarm (see pull request #241) +-- +ALTER TABLE `Monitors` ADD `AlarmRefBlendPerc` TINYINT(3) UNSIGNED NOT NULL DEFAULT '3' AFTER `RefBlendPerc`; + diff --git a/db/zm_update-1.26.6.sql b/db/zm_update-1.26.6.sql new file mode 100644 index 000000000..4b667d8a8 --- /dev/null +++ b/db/zm_update-1.26.6.sql @@ -0,0 +1,11 @@ +-- +-- This updates a 1.26.5 database to 1.26.6 +-- + +-- +-- Add Libvlc monitor type +-- + +ALTER TABLE Controls modify column Type enum('Local','Remote','Ffmpeg','Libvlc') NOT NULL default 'Local'; +ALTER TABLE MonitorPresets modify column Type enum('Local','Remote','File','Ffmpeg','Libvlc') NOT NULL default 'Local'; +ALTER TABLE Monitors modify column Type enum('Local','Remote','File','Ffmpeg','Libvlc') NOT NULL default 'Local'; diff --git a/distros/debian/changelog b/distros/debian/changelog index fbdacd988..af8df8eeb 100644 --- a/distros/debian/changelog +++ b/distros/debian/changelog @@ -1,4 +1,4 @@ -zoneminder (1.26.4-1) unstable; urgency=low +zoneminder (1.26.5-1) unstable; urgency=low * improvements to zmupdate.pl, cleanups diff --git a/distros/debian/control b/distros/debian/control index 06bc6801e..d774fb45f 100644 --- a/distros/debian/control +++ b/distros/debian/control @@ -2,13 +2,32 @@ Source: zoneminder Section: net Priority: optional Maintainer: Isaac Connor -Build-Depends: debhelper (>= 5), autoconf, automake, dpatch, libphp-serialization-perl, libgnutls-dev, libmysqlclient-dev, libdbd-mysql-perl, libdate-manip-perl, libwww-perl, libjpeg8-dev, libpcre3-dev, libavcodec-dev, libavformat-dev (>= 3:0.svn20090204), libswscale-dev (>= 3:0.svn20090204), libavutil-dev, libv4l-dev (>= 0.8.3), libbz2-dev, libtool, libsys-mmap-perl, ffmpeg, libnetpbm10-dev, libavdevice-dev, libdevice-serialport-perl, libpcre3, libarchive-zip-perl, libmime-lite-perl, libjpeg8, dh-autoreconf +Build-Depends: debhelper (>= 7.0.50), autoconf, automake, dpatch, libphp-serialization-perl, libgnutls-dev, libmysqlclient-dev, libdbd-mysql-perl, libdate-manip-perl, libwww-perl, libjpeg8-dev, libpcre3-dev, libavcodec-dev, libavformat-dev (>= 3:0.svn20090204), libswscale-dev (>= 3:0.svn20090204), libavutil-dev, libv4l-dev (>= 0.8.3), libbz2-dev, libtool, libsys-mmap-perl, ffmpeg, libnetpbm10-dev, libavdevice-dev, libdevice-serialport-perl, libpcre3, libarchive-zip-perl, libmime-lite-perl, libjpeg8, dh-autoreconf Standards-Version: 3.9.2 Package: zoneminder Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}, apache2, libapache2-mod-php5, php5, php5-mysql, libphp-serialization-perl, libdate-manip-perl, libmime-lite-perl, libmime-lite-perl, mysql-client, libwww-perl, libarchive-tar-perl, libarchive-zip-perl, libdevice-serialport-perl, libpcre3, ffmpeg, rsyslog | system-log-daemon, libmodule-load-perl, libsys-mmap-perl, libjson-any-perl, netpbm, libavdevice53, libjpeg8, zip, libnet-sftp-foreign-perl -Description: Linux video camera security and surveillance solution +Recommends: mysql-server +Description: A video camera security and surveillance solution + ZoneMinder is intended for use in single or multi-camera video security + applications, including commercial or home CCTV, theft prevention and child + or family member or home monitoring and other care scenarios. It + supports capture, analysis, recording, and monitoring of video data coming + from one or more video or network cameras attached to a Linux system. + ZoneMinder also support web and semi-automatic control of Pan/Tilt/Zoom + cameras using a variety of protocols. It is suitable for use as a home + video security system and for commercial or professional video security + and surveillance. It can also be integrated into a home automation system + via X.10 or other protocols. + +Package: zoneminder-dbg +Architecture: any +Depends: + zoneminder (= ${binary:Version}), + ${misc:Depends} +Description: debugging syumbols for zoneminder. + ZoneMinder is a video camera security and surveillance solution. ZoneMinder is intended for use in single or multi-camera video security applications, including commercial or home CCTV, theft prevention and child or family member or home monitoring and other care scenarios. It diff --git a/distros/debian/init.d b/distros/debian/init.d index 757003132..d3354c1d8 100644 --- a/distros/debian/init.d +++ b/distros/debian/init.d @@ -25,7 +25,6 @@ start() { echo -n "Starting $prog: " mkdir -p $RUNDIR && chown www-data:www-data $RUNDIR mkdir -p $TMPDIR && chown www-data:www-data $TMPDIR - zmfix -a $command start RETVAL=$? [ $RETVAL = 0 ] && echo success diff --git a/distros/debian/rules b/distros/debian/rules index 601dcf62a..3dea63174 100755 --- a/distros/debian/rules +++ b/distros/debian/rules @@ -71,3 +71,7 @@ override_dh_fixperms: override_dh_auto_test: # do not run tests... + +.PHONY: override_dh_strip +override_dh_strip: + dh_strip --dbg-package=zoneminder-dbg diff --git a/distros/fedora/README.Fedora b/distros/fedora/README.Fedora index 55c2d029a..035c9365f 100644 --- a/distros/fedora/README.Fedora +++ b/distros/fedora/README.Fedora @@ -25,7 +25,7 @@ New installs introduce an obvious security issue. The following should set this up: mysql -u root -p - grant select,insert,update,delete,alter on zm.* to + grant select,insert,update,delete,lock tables,alter on zm.* to 'zmuser'@localhost identified by 'zmpass'; Obviously, change at least zmpass to an actual, secure password or diff --git a/distros/fedora/zoneminder.cmake.f19.spec b/distros/fedora/zoneminder.cmake.f19.spec index 19056a361..2b8a6756f 100644 --- a/distros/fedora/zoneminder.cmake.f19.spec +++ b/distros/fedora/zoneminder.cmake.f19.spec @@ -4,7 +4,7 @@ %define zmgid_final apache Name: zoneminder -Version: 1.26.4 +Version: 1.26.5 Release: 1%{?dist} Summary: A camera monitoring and analysis tool Group: System Environment/Daemons @@ -126,7 +126,6 @@ fi %{_bindir}/zmdc.pl %{_bindir}/zmf %{_bindir}/zmfilter.pl -%attr(4755,root,root) %{_bindir}/zmfix %{_bindir}/zmpkg.pl %{_bindir}/zmstreamer %{_bindir}/zmtrack.pl @@ -139,7 +138,7 @@ fi #%{_bindir}/zmx10.pl %{perl_vendorlib}/ZoneMinder* -%{perl_vendorlib}/x86_64-linux-thread-multi/auto/ZoneMinder* +%{perl_vendorlib}/%{_arch}-linux-thread-multi/auto/ZoneMinder* #%{perl_archlib}/ZoneMinder* %{_mandir}/man*/* %dir %{_libexecdir}/zoneminder @@ -160,6 +159,10 @@ fi %changelog +* Mon Dec 16 2013 Andrew Bauer - 1.26.5 +- This is a bug fixe release +- RTSP fixes, cmake enhancements, couple other misc fixes + * Mon Oct 07 2013 Andrew Bauer - 1.26.4 - Initial cmake build. diff --git a/distros/fedora/zoneminder.f19.spec b/distros/fedora/zoneminder.f19.spec index 906646568..1f0eac54b 100644 --- a/distros/fedora/zoneminder.f19.spec +++ b/distros/fedora/zoneminder.f19.spec @@ -8,7 +8,7 @@ %define zmgid_final apache Name: zoneminder -Version: 1.26.4 +Version: 1.26.5 Release: 1%{?dist} Summary: A camera monitoring and analysis tool Group: System Environment/Daemons @@ -228,7 +228,6 @@ fi %{_bindir}/zmdc.pl %{_bindir}/zmf %{_bindir}/zmfilter.pl -%attr(4755,root,root) %{_bindir}/zmfix %{_bindir}/zmpkg.pl %{_bindir}/zmstreamer %{_bindir}/zmtrack.pl @@ -259,6 +258,10 @@ fi %changelog +* Mon Dec 16 2013 Andrew Bauer - 1.26.5 +- This is a bug fixe release +- RTSP fixes, cmake enhancements, couple other misc fixes + * Sat Oct 05 2013 Andrew Bauer - 1.26.4 - Fedora specific path changes have been moved to zoneminder-1.26.0-defaults.patch - All files are now part of the zoneminder source tree. Update specfile accordingly. diff --git a/distros/fedora/zoneminder.service b/distros/fedora/zoneminder.service index d59fc6796..fdd9b3af2 100644 --- a/distros/fedora/zoneminder.service +++ b/distros/fedora/zoneminder.service @@ -1,5 +1,6 @@ [Unit] Description=Video security and surveillance system +After=mysqld.service [Service] Type=forking diff --git a/distros/redhat/README.CentOS b/distros/redhat/README.CentOS index a837faf15..5929a6ad0 100644 --- a/distros/redhat/README.CentOS +++ b/distros/redhat/README.CentOS @@ -15,7 +15,7 @@ mysql -uroot -p mysql> create database zm; - mysql> grant select,insert,update,delete,alter on zm.* to + mysql> grant select,insert,update,delete,lock tables,alter on zm.* to 'zmuser'@localhost identified by 'zmpass'; mysql> exit; mysql -uroot -p < /usr/share/zoneminder/db/zm_create.sql diff --git a/distros/redhat/zoneminder.cmake.el6.spec b/distros/redhat/zoneminder.cmake.el6.spec index 73d5bf682..d732c6af5 100644 --- a/distros/redhat/zoneminder.cmake.el6.spec +++ b/distros/redhat/zoneminder.cmake.el6.spec @@ -4,7 +4,7 @@ %define zmgid_final apache Name: zoneminder -Version: 1.26.4 +Version: 1.26.5 Release: 1%{?dist} Summary: A camera monitoring and analysis tool Group: System Environment/Daemons @@ -124,7 +124,6 @@ rm -rf %{_docdir}/%{name}-%{version} %{_bindir}/zmdc.pl %{_bindir}/zmf %{_bindir}/zmfilter.pl -%attr(4755,root,root) %{_bindir}/zmfix %{_bindir}/zmpkg.pl %{_bindir}/zmstreamer %{_bindir}/zmtrack.pl @@ -136,7 +135,7 @@ rm -rf %{_docdir}/%{name}-%{version} %{_bindir}/zmx10.pl %{perl_vendorlib}/ZoneMinder* -%{perl_vendorlib}/x86_64-linux-thread-multi/auto/ZoneMinder* +%{perl_vendorlib}/%{_arch}-linux-thread-multi/auto/ZoneMinder* %{_mandir}/man*/* %dir %{_libexecdir}/%{name} %{_libexecdir}/%{name}/cgi-bin @@ -155,6 +154,10 @@ rm -rf %{_docdir}/%{name}-%{version} %changelog +* Mon Dec 16 2013 Andrew Bauer - 1.26.5 +- This is a bug fixe release +- RTSP fixes, cmake enhancements, couple other misc fixes + * Sat Oct 19 2013 Andrew Bauer - 1.26.4 - Streamline the cmake build. Move much code into cmakelist.txt file. diff --git a/distros/redhat/zoneminder.el6.spec b/distros/redhat/zoneminder.el6.spec index 72449cb1d..d47d66f65 100644 --- a/distros/redhat/zoneminder.el6.spec +++ b/distros/redhat/zoneminder.el6.spec @@ -8,7 +8,7 @@ %define zmgid_final apache Name: zoneminder -Version: 1.26.4 +Version: 1.26.5 Release: 1%{?dist} Summary: A camera monitoring and analysis tool Group: System Environment/Daemons @@ -233,7 +233,6 @@ fi %{_bindir}/zmdc.pl %{_bindir}/zmf %{_bindir}/zmfilter.pl -%attr(4755,root,root) %{_bindir}/zmfix %{_bindir}/zmpkg.pl %{_bindir}/zmstreamer %{_bindir}/zmtrack.pl @@ -263,6 +262,10 @@ fi %changelog +* Mon Dec 16 2013 Andrew Bauer - 1.26.5 +- This is a bug fixe release +- RTSP fixes, cmake enhancements, couple other misc fixes + * Sun Oct 06 2013 Andrew Bauer - 1.26.4 - All files are now part of the zoneminder source tree. Update specfile accordingly. diff --git a/distros/redhat/zoneminder.in b/distros/redhat/zoneminder.in index 6fb4fef6b..f1c6c47c6 100755 --- a/distros/redhat/zoneminder.in +++ b/distros/redhat/zoneminder.in @@ -26,7 +26,8 @@ command="$ZM_PATH_BIN/zmpkg.pl" start() { - zmupdate || return $? +# Commenting out as it is not needed. Leaving as a placeholder for future use. +# zmupdate || return $? loadconf || return $? #Make sure the directory for our PID folder exists or create one. [ ! -d $pidfile ] \ diff --git a/distros/ubuntu1204/changelog b/distros/ubuntu1204/changelog index 567177bc3..4ebc39de8 100644 --- a/distros/ubuntu1204/changelog +++ b/distros/ubuntu1204/changelog @@ -1,4 +1,4 @@ -zoneminder (1.26.4-2) precise; urgency=high +zoneminder (1.26.5-1) precise; urgency=high * improvements to zmupdate.pl, cleanups diff --git a/distros/ubuntu1204/control b/distros/ubuntu1204/control index 06bc6801e..49be18df6 100644 --- a/distros/ubuntu1204/control +++ b/distros/ubuntu1204/control @@ -2,13 +2,32 @@ Source: zoneminder Section: net Priority: optional Maintainer: Isaac Connor -Build-Depends: debhelper (>= 5), autoconf, automake, dpatch, libphp-serialization-perl, libgnutls-dev, libmysqlclient-dev, libdbd-mysql-perl, libdate-manip-perl, libwww-perl, libjpeg8-dev, libpcre3-dev, libavcodec-dev, libavformat-dev (>= 3:0.svn20090204), libswscale-dev (>= 3:0.svn20090204), libavutil-dev, libv4l-dev (>= 0.8.3), libbz2-dev, libtool, libsys-mmap-perl, ffmpeg, libnetpbm10-dev, libavdevice-dev, libdevice-serialport-perl, libpcre3, libarchive-zip-perl, libmime-lite-perl, libjpeg8, dh-autoreconf +Build-Depends: debhelper (>= 7.0.50), autoconf, automake, dpatch, libphp-serialization-perl, libgnutls-dev, libmysqlclient-dev, libdbd-mysql-perl, libdate-manip-perl, libwww-perl, libjpeg8-dev, libpcre3-dev, libavcodec-dev, libavformat-dev (>= 3:0.svn20090204), libswscale-dev (>= 3:0.svn20090204), libavutil-dev, libv4l-dev (>= 0.8.3), libbz2-dev, libtool, libsys-mmap-perl, ffmpeg, libnetpbm10-dev, libavdevice-dev, libdevice-serialport-perl, libpcre3, libarchive-zip-perl, libmime-lite-perl, libjpeg8, dh-autoreconf Standards-Version: 3.9.2 Package: zoneminder Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}, apache2, libapache2-mod-php5, php5, php5-mysql, libphp-serialization-perl, libdate-manip-perl, libmime-lite-perl, libmime-lite-perl, mysql-client, libwww-perl, libarchive-tar-perl, libarchive-zip-perl, libdevice-serialport-perl, libpcre3, ffmpeg, rsyslog | system-log-daemon, libmodule-load-perl, libsys-mmap-perl, libjson-any-perl, netpbm, libavdevice53, libjpeg8, zip, libnet-sftp-foreign-perl -Description: Linux video camera security and surveillance solution +SUggests: mysql-server +Description: A video camera security and surveillance solution + ZoneMinder is intended for use in single or multi-camera video security + applications, including commercial or home CCTV, theft prevention and child + or family member or home monitoring and other care scenarios. It + supports capture, analysis, recording, and monitoring of video data coming + from one or more video or network cameras attached to a Linux system. + ZoneMinder also support web and semi-automatic control of Pan/Tilt/Zoom + cameras using a variety of protocols. It is suitable for use as a home + video security system and for commercial or professional video security + and surveillance. It can also be integrated into a home automation system + via X.10 or other protocols. + +Package: zoneminder-dbg +Architecture: any +Depends: + zoneminder (= ${binary:Version}), + ${misc:Depends} +Description: debugging syumbols for zoneminder. + ZoneMinder is a video camera security and surveillance solution. ZoneMinder is intended for use in single or multi-camera video security applications, including commercial or home CCTV, theft prevention and child or family member or home monitoring and other care scenarios. It diff --git a/distros/ubuntu1204/init.d b/distros/ubuntu1204/init.d index 757003132..d3354c1d8 100644 --- a/distros/ubuntu1204/init.d +++ b/distros/ubuntu1204/init.d @@ -25,7 +25,6 @@ start() { echo -n "Starting $prog: " mkdir -p $RUNDIR && chown www-data:www-data $RUNDIR mkdir -p $TMPDIR && chown www-data:www-data $TMPDIR - zmfix -a $command start RETVAL=$? [ $RETVAL = 0 ] && echo success diff --git a/distros/ubuntu1204/postinst b/distros/ubuntu1204/postinst index 716c475e6..d06f9c641 100644 --- a/distros/ubuntu1204/postinst +++ b/distros/ubuntu1204/postinst @@ -2,44 +2,36 @@ set -e -VERSION=1.26.4 - if [ "$1" = "configure" ]; then - # - # Get mysql started if it isn't - # - if ! $(/etc/init.d/mysql status >/dev/null 2>&1); then - invoke-rc.d mysql start - fi - if $(/etc/init.d/mysql status >/dev/null 2>&1); then - mysqladmin --defaults-file=/etc/mysql/debian.cnf -f reload - # test if database if already present... - if ! $(echo quit | mysql --defaults-file=/etc/mysql/debian.cnf zm > /dev/null 2> /dev/null) ; then - cat /usr/share/zoneminder/db/zm_create.sql | mysql --defaults-file=/etc/mysql/debian.cnf - echo 'grant lock tables, alter,select,insert,update,delete on zm.* to 'zmuser'@localhost identified by "zmpass";' | mysql --defaults-file=/etc/mysql/debian.cnf mysql - fi + if [ -e "/etc/init.d/mysql" ]; then + # + # Get mysql started if it isn't + # + if ! $(/etc/init.d/mysql status >/dev/null 2>&1); then + invoke-rc.d mysql start + fi + if $(/etc/init.d/mysql status >/dev/null 2>&1); then + mysqladmin --defaults-file=/etc/mysql/debian.cnf -f reload + # test if database if already present... + if ! $(echo quit | mysql --defaults-file=/etc/mysql/debian.cnf zm > /dev/null 2> /dev/null) ; then + cat /usr/share/zoneminder/db/zm_create.sql | mysql --defaults-file=/etc/mysql/debian.cnf + echo 'grant lock tables, alter,select,insert,update,delete on zm.* to 'zmuser'@localhost identified by "zmpass";' | mysql --defaults-file=/etc/mysql/debian.cnf mysql + fi - # get old version from upgrade... - OLD_ZM_VERSION=${2%-*} - if [ -z "$OLD_ZM_VERSION" ]; then - # fall back to getting version from database itself, which may not necessarily be accurate? - OLD_ZM_VERSION=$(echo 'select Value from Config where Name = "ZM_DYN_CURR_VERSION";' | mysql --defaults-file=/etc/mysql/debian.cnf --skip-column-names zm ) - fi - if [ -n "$OLD_ZM_VERSION" ] && [ "$OLD_ZM_VERSION" != "$VERSION" ] ; then - echo 'grant lock tables, create, alter on zm.* to 'zmuser'@localhost identified by "zmpass";' | mysql --defaults-file=/etc/mysql/debian.cnf mysql - # stop zoneminder before performing database upgrade. - invoke-rc.d zoneminder stop || true - zmupdate.pl --nointeractive --version $OLD_ZM_VERSION - fi + invoke-rc.d zoneminder stop || true + zmupdate.pl --nointeractive - else - echo 'NOTE: mysql not running, please start mysql and run dpkg-reconfigure zoneminder when it is running.' - fi - chown www-data:www-data /var/log/zm - chown www-data:www-data /var/lib/zm/ - if [ -z "$2" ]; then - chown www-data:www-data -R /var/cache/zoneminder - fi + else + echo 'NOTE: mysql not running, please start mysql and run dpkg-reconfigure zoneminder when it is running.' + fi + else + echo 'mysql not found, assuming remote server.' + fi + chown www-data:www-data /var/log/zm + chown www-data:www-data /var/lib/zm/ + if [ -z "$2" ]; then + chown www-data:www-data -R /var/cache/zoneminder + fi fi # Ensure zoneminder is stopped... if [ -x "/etc/init.d/zoneminder" ]; then @@ -55,10 +47,7 @@ if [ "$1" = "configure" ]; then chown www-data:www-data -R /var/cache/zoneminder else chown www-data:www-data /var/log/zm - OLD_ZM_VERSION=${2%-*} - if [ "$OLD_ZM_VERSION" != "$VERSION" ] ; then - zmupdate.pl --version $OLD_ZM_VERSION - fi + zmupdate.pl fi fi #DEBHELPER# diff --git a/distros/ubuntu1204/rules b/distros/ubuntu1204/rules index 601dcf62a..89c1ff393 100755 --- a/distros/ubuntu1204/rules +++ b/distros/ubuntu1204/rules @@ -9,9 +9,6 @@ # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 -UPSTREAM_VERSION := $(shell dpkg-parsechangelog | egrep '^Version:' | cut -f 2 -d ' ' | cut -d - -f 1) -POSTINST_VERSION := $(shell egrep ^VERSION= debian/postinst | cut -d = -f 2) - # These are used for cross-compiling and for saving the configure script # from having to guess our platform (since we know it already) DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) @@ -34,9 +31,6 @@ override_dh_auto_configure: CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" ./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --sysconfdir=/etc/zm --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info --with-mysql=/usr --with-webdir=/usr/share/zoneminder --with-ffmpeg=/usr --with-cgidir=/usr/lib/cgi-bin --with-webuser=www-data --with-webgroup=www-data --enable-crashtrace=no --enable-mmap=yes override_dh_clean: - # check to make sure that postinst contains the correct upstream version - [ $(UPSTREAM_VERSION) = $(POSTINST_VERSION) ] - # Add here commands to clean up after the build process. [ ! -f Makefile ] || $(MAKE) distclean dh_clean @@ -71,3 +65,7 @@ override_dh_fixperms: override_dh_auto_test: # do not run tests... + +.PHONY: override_dh_strip +override_dh_strip: + dh_strip --dbg-package=zoneminder-dbg diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Base.pm.in b/scripts/ZoneMinder/lib/ZoneMinder/Base.pm.in index 37119f725..3f10e9137 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Base.pm.in +++ b/scripts/ZoneMinder/lib/ZoneMinder/Base.pm.in @@ -32,6 +32,8 @@ require Exporter; our @ISA = qw(Exporter); +use constant ZM_VERSION => "@VERSION@"; + # Items to export into callers namespace by default. Note: do not export # names by default without a very good reason. Use EXPORT_OK instead. # Do not simply export all your public functions/methods/constants. @@ -39,7 +41,7 @@ our @ISA = qw(Exporter); # This allows declaration use ZoneMinder ':all'; # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK # will save memory. -our %EXPORT_TAGS = ( 'all' => [ qw() ] ); +our %EXPORT_TAGS = ( 'all' => [ qw(ZM_VERSION) ] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Config.pm.in b/scripts/ZoneMinder/lib/ZoneMinder/Config.pm.in index fbd9ea374..21f7a2d50 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Config.pm.in +++ b/scripts/ZoneMinder/lib/ZoneMinder/Config.pm.in @@ -33,6 +33,7 @@ require ZoneMinder::Base; our @ISA = qw(Exporter ZoneMinder::Base); +use vars qw( %Config ); # Items to export into callers namespace by default. Note: do not export # names by default without a very good reason. Use EXPORT_OK instead. # Do not simply export all your public functions/methods/constants. @@ -40,7 +41,7 @@ our @ISA = qw(Exporter ZoneMinder::Base); # This allows declaration use ZoneMinder ':all'; # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK # will save memory. -our @EXPORT_CONFIG; # Get populated by BEGIN +our @EXPORT_CONFIG = qw( %Config ); # Get populated by BEGIN our %EXPORT_TAGS = ( 'constants' => [ qw( @@ -64,11 +65,9 @@ use Carp; # Load the config from the database into the symbol table BEGIN { - no strict 'refs'; - my $config_file = ZM_CONFIG; ( my $local_config_file = $config_file ) =~ s|^.*/|./|; - if ( -s $local_config_file && -r $local_config_file ) + if ( -s $local_config_file and -r $local_config_file ) { print( STDERR "Warning, overriding installed $local_config_file file with local copy\n" ); $config_file = $local_config_file; @@ -78,25 +77,26 @@ BEGIN { next if ( $str =~ /^\s*$/ ); next if ( $str =~ /^\s*#/ ); - my ( $name, $value ) = $str =~ /^\s*([^=\s]+)\s*=\s*(.+?)\s*$/; + my ( $name, $value ) = $str =~ /^\s*([^=\s]+)\s*=\s*(.*?)\s*$/; + if ( ! $name ) { + print( STDERR "Warning, bad line in $config_file: $str\n" ); + next; + } # end if $name =~ tr/a-z/A-Z/; - *{$name} = sub { $value }; - push( @EXPORT_CONFIG, $name ); + $Config{$name} = $value; } close( CONFIG ); use DBI; - my $dbh = DBI->connect( "DBI:mysql:database=".&ZM_DB_NAME.";host=".&ZM_DB_HOST, &ZM_DB_USER, &ZM_DB_PASS ); - my $sql = "select * from Config"; + my $dbh = DBI->connect( "DBI:mysql:database=".$Config{ZM_DB_NAME}.";host=".$Config{ZM_DB_HOST}, $Config{ZM_DB_USER}, $Config{ZM_DB_PASS} ) or croak( "Can't connect to db" ); + my $sql = 'select * from Config'; my $sth = $dbh->prepare_cached( $sql ) or croak( "Can't prepare '$sql': ".$dbh->errstr() ); my $res = $sth->execute() or croak( "Can't execute: ".$sth->errstr() ); - while( my $config = $sth->fetchrow_hashref() ) - { - *{$config->{Name}} = sub { $config->{Value} }; - push( @EXPORT_CONFIG, $config->{Name} ); + while( my $config = $sth->fetchrow_hashref() ) { + $Config{$config->{Name}} = $config->{Value}; } $sth->finish(); - $dbh->disconnect(); + #$dbh->disconnect(); } 1; @@ -116,7 +116,7 @@ The ZoneMinder::Config module is used to import the ZoneMinder configuration fro Once the configuration has been imported then configuration variables are defined as constants and can be accessed directory by name, e.g. - $lang = ZM_LANG_DEFAULT; + $lang = $Config{ZM_LANG_DEFAULT}; =head2 EXPORT diff --git a/scripts/ZoneMinder/lib/ZoneMinder/ConfigAdmin.pm b/scripts/ZoneMinder/lib/ZoneMinder/ConfigAdmin.pm index 8ee1ec82b..673e13c98 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/ConfigAdmin.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/ConfigAdmin.pm @@ -68,7 +68,7 @@ use Carp; sub loadConfigFromDB { print( "Loading config from DB\n" ); - my $dbh = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".ZM_DB_HOST, ZM_DB_USER, ZM_DB_PASS ); + my $dbh = DBI->connect( "DBI:mysql:database=".$Config{ZM_DB_NAME}.";host=".$Config{ZM_DB_HOST}, $Config{ZM_DB_USER}, $Config{ZM_DB_PASS} ); if ( !$dbh ) { @@ -111,13 +111,19 @@ sub loadConfigFromDB sub saveConfigToDB { print( "Saving config to DB\n" ); - my $dbh = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".ZM_DB_HOST, ZM_DB_USER, ZM_DB_PASS ); + my $dbh = DBI->connect( "DBI:mysql:database=".$Config{ZM_DB_NAME}.";host=".$Config{ZM_DB_HOST}, $Config{ZM_DB_USER}, $Config{ZM_DB_PASS} ); if ( !$dbh ) { print( "Error: unable to save options to database: $DBI::errstr\n" ); return( 0 ); } + + my $ac = $dbh->{AutoCommit}; + $dbh->{AutoCommit} = 0; + + $dbh->do('LOCK TABLE Config WRITE') or croak( "Can't lock Config table: " . $dbh->errstr() ); + my $sql = "delete from Config"; my $res = $dbh->do( $sql ) or croak( "Can't do '$sql': ".$dbh->errstr() ); @@ -149,6 +155,10 @@ sub saveConfigToDB my $res = $sth->execute( $option->{id}, $option->{name}, $option->{db_value}, $option->{db_type}, $option->{default}, $option->{db_hint}, $option->{db_pattern}, $option->{db_format}, $option->{description}, $option->{help}, $option->{category}, $option->{readonly}?1:0, $option->{db_requires} ) or croak( "Can't execute: ".$sth->errstr() ); } $sth->finish(); + + $dbh->do('UNLOCK TABLES'); + $dbh->{AutoCommit} = $ac; + $dbh->disconnect(); } diff --git a/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in b/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in index 0b75a4d9a..51a5a9555 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in +++ b/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in @@ -331,14 +331,6 @@ our @options = type => $types{boolean}, category => "config", }, - { - name => "ZM_BLEND_ALARMED_IMAGES", - default => "yes", - description => "Blend alarmed images to update the reference image", - help => "To detect alarms ZoneMinder compares an image with a reference image which is formed from a composite of the previous images. This option determines whether images that cause events are included in this process. Doing so may increase the precision of the alarmed region but can cause problems if wholescale lighting changes cause alarms as this would not get fed back into the image and an alarm may persist indefinately. A better way to achive the same effect in most cases is to lower substantially the reference blend percentage in specific monitors.", - type => $types{boolean}, - category => "config", - }, { name => "ZM_MAX_SUSPEND_TIME", default => "30", @@ -370,7 +362,7 @@ our @options = name => "ZM_HTTP_VERSION", default => "1.0", description => "The version of HTTP that ZoneMinder will use to connect", - help => "ZoneMinder can communicate with network cameras using either of the HTTP/1.1 or HTTP/1.0 standard. A server will normally fall back to the version it supports iwht no problem so this should usually by left at the default. However it can be changed to HTTP/1.0 if necessary to resolve particular issues.", + help => "ZoneMinder can communicate with network cameras using either of the HTTP/1.1 or HTTP/1.0 standard. A server will normally fall back to the version it supports with no problem so this should usually by left at the default. However it can be changed to HTTP/1.0 if necessary to resolve particular issues.", type => { db_type=>"string", hint=>"1.1|1.0", pattern=>qr|^(1\.[01])$|, format=>q( $1?$1:"" ) }, category => "network", }, diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Control/FI8608W_Y2k.pm b/scripts/ZoneMinder/lib/ZoneMinder/Control/FI8608W_Y2k.pm index ef4f5ad9e..7ffbf248a 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Control/FI8608W_Y2k.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Control/FI8608W_Y2k.pm @@ -37,7 +37,6 @@ require ZoneMinder::Base; require ZoneMinder::Control; our @ISA = qw(ZoneMinder::Control); -our $VERSION = $ZoneMinder::Base::VERSION; # =================================================================================================================================== # # FI8608W FOSCAM PT H264 Control Protocol @@ -111,7 +110,7 @@ sub open $self->loadMonitor(); use LWP::UserAgent; $self->{ua} = LWP::UserAgent->new; - $self->{ua}->agent( "ZoneMinder Control Agent/".ZM_VERSION ); + $self->{ua}->agent( "ZoneMinder Control Agent/".ZoneMinder::Base::ZM_VERSION ); $self->{state} = 'open'; } diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Control/FI8620_Y2k.pm b/scripts/ZoneMinder/lib/ZoneMinder/Control/FI8620_Y2k.pm index bc8bd8c48..7d9cd261d 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Control/FI8620_Y2k.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Control/FI8620_Y2k.pm @@ -41,7 +41,6 @@ require ZoneMinder::Base; require ZoneMinder::Control; our @ISA = qw(ZoneMinder::Control); -our $VERSION = $ZoneMinder::Base::VERSION; # =================================================================================================================================== # # FI8620 FOSCAM Dome PTZ H264 Control Protocol @@ -117,7 +116,7 @@ sub open $self->loadMonitor(); use LWP::UserAgent; $self->{ua} = LWP::UserAgent->new; - $self->{ua}->agent( "ZoneMinder Control Agent/".ZM_VERSION ); + $self->{ua}->agent( "ZoneMinder Control Agent/".ZoneMinder::Base::ZM_VERSION ); $self->{state} = 'open'; } diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Control/FI9821W_Y2k.pm b/scripts/ZoneMinder/lib/ZoneMinder/Control/FI9821W_Y2k.pm index e3b1a6d22..d363ca247 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Control/FI9821W_Y2k.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Control/FI9821W_Y2k.pm @@ -36,7 +36,6 @@ require ZoneMinder::Base; require ZoneMinder::Control; our @ISA = qw(ZoneMinder::Control); -our $VERSION = $ZoneMinder::Base::VERSION; # =================================================================================================================================== # # FI9821 FOSCAM PT H264 Control Protocol @@ -91,7 +90,7 @@ sub open $self->loadMonitor(); use LWP::UserAgent; $self->{ua} = LWP::UserAgent->new; - $self->{ua}->agent( "ZoneMinder Control Agent/".ZM_VERSION ); + $self->{ua}->agent( "ZoneMinder Control Agent/".ZoneMinder::Base::ZM_VERSION ); $self->{state} = 'open'; } diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Control/LoftekSentinel.pm b/scripts/ZoneMinder/lib/ZoneMinder/Control/LoftekSentinel.pm index c6a9582c6..610b8d78c 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Control/LoftekSentinel.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Control/LoftekSentinel.pm @@ -36,8 +36,6 @@ require ZoneMinder::Control; our @ISA = qw(ZoneMinder::Control); -our $VERSION = $ZoneMinder::Base::VERSION; - our %CamParams = (); # ========================================================================== @@ -91,7 +89,7 @@ sub open use LWP::UserAgent; $self->{ua} = LWP::UserAgent->new; - $self->{ua}->agent( "ZoneMinder Control Agent/".ZM_VERSION ); + $self->{ua}->agent( "ZoneMinder Control Agent/".ZoneMinder::Base::ZM_VERSION ); $self->{state} = 'open'; } diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Control/Ncs370.pm b/scripts/ZoneMinder/lib/ZoneMinder/Control/Ncs370.pm index 358aecb2b..c69b4f29d 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Control/Ncs370.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Control/Ncs370.pm @@ -33,8 +33,6 @@ require ZoneMinder::Control; our @ISA = qw(ZoneMinder::Control); -our $VERSION = $ZoneMinder::Base::VERSION; - # ========================================================================== # # Ncs370 IP Control Protocol @@ -79,7 +77,7 @@ sub open use LWP::UserAgent; $self->{ua} = LWP::UserAgent->new; - $self->{ua}->agent( "ZoneMinder Control Agent/".ZM_VERSION ); + $self->{ua}->agent( "ZoneMinder Control Agent/".ZoneMinder::Base::ZM_VERSION ); $self->{state} = 'open'; } diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Control/PanasonicIP.pm b/scripts/ZoneMinder/lib/ZoneMinder/Control/PanasonicIP.pm index 643765e9f..d3e19e3aa 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Control/PanasonicIP.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Control/PanasonicIP.pm @@ -33,8 +33,6 @@ require ZoneMinder::Control; our @ISA = qw(ZoneMinder::Control); -our $VERSION = $ZoneMinder::Base::VERSION; - # ========================================================================== # # Panasonic IP Control Protocol @@ -79,7 +77,7 @@ sub open use LWP::UserAgent; $self->{ua} = LWP::UserAgent->new; - $self->{ua}->agent( "ZoneMinder Control Agent/".ZM_VERSION ); + $self->{ua}->agent( "ZoneMinder Control Agent/".ZoneMinder::Base::ZM_VERSION ); $self->{state} = 'open'; } diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Control/PelcoD.pm b/scripts/ZoneMinder/lib/ZoneMinder/Control/PelcoD.pm index 6c507bd1a..8e5d07f74 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Control/PelcoD.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Control/PelcoD.pm @@ -33,8 +33,6 @@ require ZoneMinder::Control; our @ISA = qw(ZoneMinder::Control); -our $VERSION = $ZoneMinder::Base::VERSION; - # ========================================================================== # # Pelco-D Control Protocol diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Control/PelcoP.pm b/scripts/ZoneMinder/lib/ZoneMinder/Control/PelcoP.pm index c743f2b51..c9d9d907d 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Control/PelcoP.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Control/PelcoP.pm @@ -33,8 +33,6 @@ require ZoneMinder::Control; our @ISA = qw(ZoneMinder::Control); -our $VERSION = $ZoneMinder::Base::VERSION; - # ========================================================================== # # Pelco-P Control Protocol diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Control/SkyIPCam7xx.pm b/scripts/ZoneMinder/lib/ZoneMinder/Control/SkyIPCam7xx.pm index 89108ed41..fd97c5a49 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Control/SkyIPCam7xx.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Control/SkyIPCam7xx.pm @@ -34,8 +34,6 @@ require ZoneMinder::Control; our @ISA = qw(ZoneMinder::Control); -our $VERSION = $ZoneMinder::Base::VERSION; - # ========================================================================== # # Airlink SkyIPCam AICN747/AICN747W Control Protocol @@ -80,7 +78,7 @@ sub open use LWP::UserAgent; $self->{ua} = LWP::UserAgent->new; - $self->{ua}->agent( "ZoneMinder Control Agent/".ZM_VERSION ); + $self->{ua}->agent( "ZoneMinder Control Agent/".ZoneMinder::Base::ZM_VERSION ); $self->{state} = 'open'; } diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Control/Visca.pm b/scripts/ZoneMinder/lib/ZoneMinder/Control/Visca.pm index 37f30dc09..749beae21 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Control/Visca.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Control/Visca.pm @@ -33,8 +33,6 @@ require ZoneMinder::Control; our @ISA = qw(ZoneMinder::Control); -our $VERSION = $ZoneMinder::Base::VERSION; - # ========================================================================== # # Visca Control Protocol diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Control/mjpgStreamer.pm b/scripts/ZoneMinder/lib/ZoneMinder/Control/mjpgStreamer.pm index 33a15cba1..255dac056 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Control/mjpgStreamer.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Control/mjpgStreamer.pm @@ -33,8 +33,6 @@ require ZoneMinder::Control; our @ISA = qw(ZoneMinder::Control); -our $VERSION = $ZoneMinder::Base::VERSION; - # ========================================================================== # # mjpgSTreamer Control Protocol @@ -81,7 +79,7 @@ sub open Debug( "Camera open" ); use LWP::UserAgent; $self->{ua} = LWP::UserAgent->new; - $self->{ua}->agent( "ZoneMinder Control Agent/".ZM_VERSION ); + $self->{ua}->agent( "ZoneMinder Control Agent/".ZoneMinder::Base::ZM_VERSION ); $self->{state} = 'open'; } diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Database.pm b/scripts/ZoneMinder/lib/ZoneMinder/Database.pm index d0bae5dde..29b3c8b2a 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Database.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Database.pm @@ -79,15 +79,15 @@ sub zmDbConnect( ;$ ) } if ( !defined( $dbh ) ) { - my ( $host, $port ) = ( ZM_DB_HOST =~ /^([^:]+)(?::(.+))?$/ ); + my ( $host, $port ) = ( $Config{ZM_DB_HOST} =~ /^([^:]+)(?::(.+))?$/ ); if ( defined($port) ) { - $dbh = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".$host.";port=".$port, ZM_DB_USER, ZM_DB_PASS ); + $dbh = DBI->connect( "DBI:mysql:database=".$Config{ZM_DB_NAME}.";host=".$host.";port=".$port, $Config{ZM_DB_USER}, $Config{ZM_DB_PASS} ); } else { - $dbh = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".ZM_DB_HOST, ZM_DB_USER, ZM_DB_PASS ); + $dbh = DBI->connect( "DBI:mysql:database=".$Config{ZM_DB_NAME}.";host=".$Config{ZM_DB_HOST}, $Config{ZM_DB_USER}, $Config{ZM_DB_PASS} ); } $dbh->trace( 0 ); } diff --git a/scripts/ZoneMinder/lib/ZoneMinder/General.pm b/scripts/ZoneMinder/lib/ZoneMinder/General.pm index 5af7150a8..4d60852a7 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/General.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/General.pm @@ -95,7 +95,7 @@ sub getCmdFormat() Debug( "Testing valid shell syntax\n" ); my ( $name ) = getpwuid( $> ); - if ( $name eq ZM_WEB_USER ) + if ( $name eq $Config{ZM_WEB_USER} ) { Debug( "Running as '$name', su commands not needed\n" ); return( "" ); @@ -103,7 +103,7 @@ sub getCmdFormat() my $null_command = "true"; - my $prefix = "sudo -u ".ZM_WEB_USER." "; + my $prefix = "sudo -u ".$Config{ZM_WEB_USER}." "; my $suffix = ""; my $command = $prefix.$null_command.$suffix; Debug( "Testing \"$command\"\n" ); @@ -120,7 +120,7 @@ sub getCmdFormat() chomp( $output ); Debug( "Test failed, '$output'\n" ); - $prefix = "su ".ZM_WEB_USER." --shell=/bin/sh --command='"; + $prefix = "su ".$Config{ZM_WEB_USER}." --shell=/bin/sh --command='"; $suffix = "'"; $command = $prefix.$null_command.$suffix; Debug( "Testing \"$command\"\n" ); @@ -136,7 +136,7 @@ sub getCmdFormat() chomp( $output ); Debug( "Test failed, '$output'\n" ); - $prefix = "su ".ZM_WEB_USER." -c '"; + $prefix = "su ".$Config{ZM_WEB_USER}." -c '"; $suffix = "'"; $command = $prefix.$null_command.$suffix; Debug( "Testing \"$command\"\n" ); @@ -172,7 +172,7 @@ sub runCommand( $ ) } my $command = shift; - $command = ZM_PATH_BIN."/".$command; + $command = $Config{ZM_PATH_BIN}."/".$command; if ( $cmdPrefix ) { $command = $cmdPrefix.$command.$cmdSuffix; @@ -201,15 +201,15 @@ sub getEventPath( $ ) my $event = shift; my $event_path = ""; - if ( ZM_USE_DEEP_STORAGE ) + if ( $Config{ZM_USE_DEEP_STORAGE} ) { - $event_path = ZM_DIR_EVENTS.'/'.$event->{MonitorId}.'/'.strftime( "%y/%m/%d/%H/%M/%S", localtime($event->{Time}) ); + $event_path = $Config{ZM_DIR_EVENTS}.'/'.$event->{MonitorId}.'/'.strftime( "%y/%m/%d/%H/%M/%S", localtime($event->{Time}) ); } else { - $event_path = ZM_DIR_EVENTS.'/'.$event->{MonitorId}.'/'.$event->{Id}; + $event_path = $Config{ZM_DIR_EVENTS}.'/'.$event->{MonitorId}.'/'.$event->{Id}; } - $event_path = ZM_PATH_WEB.'/'.$event_path if ( index(ZM_DIR_EVENTS,'/') != 0 ); + $event_path = $Config{ZM_PATH_WEB}.'/'.$event_path if ( index($Config{ZM_DIR_EVENTS},'/') != 0 ); return( $event_path ); } @@ -219,10 +219,10 @@ sub createEventPath( $ ) # WARNING assumes running from events directory # my $event = shift; - my $eventRootPath = (ZM_DIR_EVENTS=~m|/|)?ZM_DIR_EVENTS:(ZM_PATH_WEB.'/'.ZM_DIR_EVENTS); + my $eventRootPath = ($Config{ZM_DIR_EVENTS}=~m|/|)?$Config{ZM_DIR_EVENTS}:($Config{ZM_PATH_WEB}.'/'.$Config{ZM_DIR_EVENTS}); my $eventPath = $eventRootPath.'/'.$event->{MonitorId}; - if ( ZM_USE_DEEP_STORAGE ) + if ( $Config{ZM_USE_DEEP_STORAGE} ) { my @startTime = localtime( $event->{StartTime} ); @@ -277,10 +277,10 @@ sub _checkProcessOwner() if ( !defined($_setFileOwner) ) { my ( $processOwner ) = getpwuid( $> ); - if ( $processOwner ne ZM_WEB_USER ) + if ( $processOwner ne $Config{ZM_WEB_USER} ) { # Not running as web user, so should be root in whch case chown the temporary directory - ( my $ownerName, my $ownerPass, $_ownerUid, $_ownerGid ) = getpwnam( ZM_WEB_USER ) or Fatal( "Can't get user details for web user '".ZM_WEB_USER."': $!" ); + ( my $ownerName, my $ownerPass, $_ownerUid, $_ownerGid ) = getpwnam( $Config{ZM_WEB_USER} ) or Fatal( "Can't get user details for web user '".$Config{ZM_WEB_USER}."': $!" ); $_setFileOwner = 1; } else @@ -297,7 +297,7 @@ sub setFileOwner( $ ) if ( _checkProcessOwner() ) { - chown( $_ownerUid, $_ownerGid, $file ) or Fatal( "Can't change ownership of file '$file' to '".ZM_WEB_USER.":".ZM_WEB_GROUP."': $!" ); + chown( $_ownerUid, $_ownerGid, $file ) or Fatal( "Can't change ownership of file '$file' to '".$Config{ZM_WEB_USER}.":".$Config{ZM_WEB_GROUP}."': $!" ); } } @@ -434,12 +434,12 @@ sub createEvent( $;$ ) #$frame->{FrameId} = $dbh->{mysql_insertid}; if ( $frame->{imagePath} ) { - $frame->{capturePath} = sprintf( "%s/%0".ZM_EVENT_IMAGE_DIGITS."d-capture.jpg", $eventPath, $frame->{FrameId} ); + $frame->{capturePath} = sprintf( "%s/%0".$Config{ZM_EVENT_IMAGE_DIGITS}."d-capture.jpg", $eventPath, $frame->{FrameId} ); rename( $frame->{imagePath}, $frame->{capturePath} ) or Fatal( "Can't copy ".$frame->{imagePath}." to ".$frame->{capturePath}.": $!" ); setFileOwner( $frame->{capturePath} ); - if ( 0 && ZM_CREATE_ANALYSIS_IMAGES ) + if ( 0 && $Config{ZM_CREATE_ANALYSIS_IMAGES} ) { - $frame->{analysePath} = sprintf( "%s/%0".ZM_EVENT_IMAGE_DIGITS."d-analyse.jpg", $eventPath, $frame->{FrameId} ); + $frame->{analysePath} = sprintf( "%s/%0".$Config{ZM_EVENT_IMAGE_DIGITS}."d-analyse.jpg", $eventPath, $frame->{FrameId} ); link( $frame->{capturePath}, $frame->{analysePath} ) or Fatal( "Can't link ".$frame->{capturePath}." to ".$frame->{analysePath}.": $!" ); setFileOwner( $frame->{analysePath} ); } @@ -497,7 +497,7 @@ sub deleteEventFiles( $;$ ) my $monitor_id = shift; $monitor_id = '*' if ( !defined($monitor_id) ); - if ( ZM_USE_DEEP_STORAGE ) + if ( $Config{ZM_USE_DEEP_STORAGE} ) { my $link_path = $monitor_id."/*/*/*/.".$event_id; #Debug( "LP1:$link_path" ); diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Logger.pm b/scripts/ZoneMinder/lib/ZoneMinder/Logger.pm index 46095be2e..5b4438c72 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Logger.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Logger.pm @@ -150,7 +150,7 @@ sub new $this->{hasTerm} = -t STDERR; ( $this->{fileName} = $0 ) =~ s|^.*/||; - $this->{logPath} = ZM_PATH_LOGS; + $this->{logPath} = $Config{ZM_PATH_LOGS}; $this->{logFile} = $this->{logPath}."/".$this->{id}.".log"; $this->{trace} = 0; @@ -163,7 +163,7 @@ sub BEGIN { # Fake the config variables that are used in case they are not defined yet # Only really necessary to support upgrade from previous version - if ( !eval('defined(ZM_LOG_DEBUG)') ) + if ( !eval('defined($Config{ZM_LOG_DEBUG})') ) { no strict 'subs'; no strict 'refs'; @@ -221,7 +221,7 @@ sub initialise( @ ) } else { - $tempDatabaseLevel = ZM_LOG_LEVEL_DATABASE; + $tempDatabaseLevel = $Config{ZM_LOG_LEVEL_DATABASE}; } if ( defined($options{fileLevel}) ) { @@ -229,7 +229,7 @@ sub initialise( @ ) } else { - $tempFileLevel = ZM_LOG_LEVEL_FILE; + $tempFileLevel = $Config{ZM_LOG_LEVEL_FILE}; } if ( defined($options{syslogLevel}) ) { @@ -237,7 +237,7 @@ sub initialise( @ ) } else { - $tempSyslogLevel = ZM_LOG_LEVEL_SYSLOG; + $tempSyslogLevel = $Config{ZM_LOG_LEVEL_SYSLOG}; } if ( defined($ENV{'LOG_PRINT'}) ) @@ -253,18 +253,18 @@ sub initialise( @ ) $tempFileLevel = $level if ( defined($level = $this->getTargettedEnv('LOG_LEVEL_FILE')) ); $tempSyslogLevel = $level if ( defined($level = $this->getTargettedEnv('LOG_LEVEL_SYSLOG')) ); - if ( ZM_LOG_DEBUG ) + if ( $Config{ZM_LOG_DEBUG} ) { - foreach my $target ( split( /\|/, ZM_LOG_DEBUG_TARGET ) ) + foreach my $target ( split( /\|/, $Config{ZM_LOG_DEBUG_TARGET} ) ) { if ( $target eq $this->{id} || $target eq "_".$this->{id} || $target eq $this->{idRoot} || $target eq "_".$this->{idRoot} || $target eq "" ) { - if ( ZM_LOG_DEBUG_LEVEL > NOLOG ) + if ( $Config{ZM_LOG_DEBUG_LEVEL} > NOLOG ) { - $tempLevel = $this->limit( ZM_LOG_DEBUG_LEVEL ); - if ( ZM_LOG_DEBUG_FILE ne "" ) + $tempLevel = $this->limit( $Config{ZM_LOG_DEBUG_LEVEL} ); + if ( $Config{ZM_LOG_DEBUG_FILE} ne "" ) { - $tempLogFile = ZM_LOG_DEBUG_FILE; + $tempLogFile = $Config{ZM_LOG_DEBUG_FILE}; $tempFileLevel = $tempLevel; } } @@ -447,20 +447,20 @@ sub databaseLevel( ;$ ) { if ( !$this->{dbh} ) { - my ( $host, $port ) = ( ZM_DB_HOST =~ /^([^:]+)(?::(.+))?$/ ); + my ( $host, $port ) = ( $Config{ZM_DB_HOST} =~ /^([^:]+)(?::(.+))?$/ ); if ( defined($port) ) { - $this->{dbh} = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".$host.";port=".$port, ZM_DB_USER, ZM_DB_PASS ); + $this->{dbh} = DBI->connect( "DBI:mysql:database=".$Config{ZM_DB_NAME}.";host=".$host.";port=".$port, $Config{ZM_DB_USER}, $Config{ZM_DB_PASS} ); } else { - $this->{dbh} = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".ZM_DB_HOST, ZM_DB_USER, ZM_DB_PASS ); + $this->{dbh} = DBI->connect( "DBI:mysql:database=".$Config{ZM_DB_NAME}.";host=".$Config{ZM_DB_HOST}, $Config{ZM_DB_USER}, $Config{ZM_DB_PASS} ); } if ( !$this->{dbh} ) { $databaseLevel = NOLOG; - Error( "Unable to write log entries to DB, can't connect to database '".ZM_DB_NAME."' on host '".ZM_DB_HOST."'" ); + Error( "Unable to write log entries to DB, can't connect to database '".$Config{ZM_DB_NAME}."' on host '".$Config{ZM_DB_HOST}."'" ); } else { @@ -553,8 +553,8 @@ sub openFile() { LOGFILE->autoflush() if ( $this->{autoFlush} ); - my $webUid = (getpwnam( ZM_WEB_USER ))[2]; - my $webGid = (getgrnam( ZM_WEB_GROUP ))[2]; + my $webUid = (getpwnam( $Config{ZM_WEB_USER} ))[2]; + my $webGid = (getgrnam( $Config{ZM_WEB_GROUP} ))[2]; if ( $> == 0 ) { chown( $webUid, $webGid, $this->{logFile} ) or Fatal( "Can't change permissions on log file '".$this->{logFile}."': $!" ) diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Memory/Mapped.pm b/scripts/ZoneMinder/lib/ZoneMinder/Memory/Mapped.pm index 2c68c7209..7c472591d 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Memory/Mapped.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Memory/Mapped.pm @@ -80,7 +80,7 @@ sub zmMemAttach( $$ ) my $size = shift; if ( !defined($monitor->{MMapAddr}) ) { - my $mmap_file = ZM_PATH_MAP."/zm.mmap.".$monitor->{Id}; + my $mmap_file = $Config{ZM_PATH_MAP}."/zm.mmap.".$monitor->{Id}; if ( -s $mmap_file < $size ) { Error( sprintf( "Memory map file '%s' should have been %d but was instead %d", $mmap_file, $size, -s $mmap_file ) ); return ( undef ); @@ -160,7 +160,7 @@ sub zmMemPut( $$$$ ) sub zmMemClean { Debug( "Removing memory map files\n" ); - my $mapPath = ZM_PATH_MAP."/zm.mmap.*"; + my $mapPath = $Config{ZM_PATH_MAP}."/zm.mmap.*"; foreach my $mapFile( glob( $mapPath ) ) { ( $mapFile ) = $mapFile =~ /^(.+)$/; diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Memory/Shared.pm b/scripts/ZoneMinder/lib/ZoneMinder/Memory/Shared.pm index c04e4f413..59dc399f1 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Memory/Shared.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Memory/Shared.pm @@ -33,6 +33,8 @@ require ZoneMinder::Base; our @ISA = qw(Exporter ZoneMinder::Base); +eval 'sub IPC_CREAT {0001000}' unless defined &IPC_CREAT; + # Items to export into callers namespace by default. Note: do not export # names by default without a very good reason. Use EXPORT_OK instead. # Do not simply export all your public functions/methods/constants. @@ -79,8 +81,8 @@ sub zmMemAttach( $$ ) my $size = shift; if ( !defined($monitor->{ShmId}) ) { - my $shm_key = (hex(ZM_SHM_KEY)&0xffff0000)|$monitor->{Id}; - my $shm_id = shmget( $shm_key, $size, 0 ); + my $shm_key = (hex($Config{ZM_SHM_KEY})&0xffff0000)|$monitor->{Id}; + my $shm_id = shmget( $shm_key, $size, &IPC_CREAT | 0777 ); if ( !defined($shm_id) ) { Error( sprintf( "Can't get shared memory id '%x', %d: $!\n", $shm_key, $monitor->{Id} ) ); @@ -139,7 +141,7 @@ sub zmMemClean { Debug( "Removing shared memory\n" ); # Find ZoneMinder shared memory - my $command = "ipcs -m | grep '^".substr( sprintf( "0x%x", hex(ZM_SHM_KEY) ), 0, -2 )."'"; + my $command = "ipcs -m | grep '^".substr( sprintf( "0x%x", hex($Config{ZM_SHM_KEY}) ), 0, -2 )."'"; Debug( "Checking for shared memory with '$command'\n" ); open( CMD, "$command |" ) or Fatal( "Can't execute '$command': $!" ); while( ) diff --git a/scripts/zm.in b/scripts/zm.in index c46d4b164..a46a89280 100755 --- a/scripts/zm.in +++ b/scripts/zm.in @@ -26,7 +26,8 @@ command="$ZM_PATH_BIN/zmpkg.pl" start() { - zmupdate || return $? +# Commenting out as it is not needed. Leaving as a placeholder for future use. +# zmupdate || return $? loadconf || return $? #Make sure the directory for our PID folder exists or create one. [ ! -d $pidfile ] \ diff --git a/scripts/zmaudit.pl.in b/scripts/zmaudit.pl.in index 955198c9f..64a992196 100644 --- a/scripts/zmaudit.pl.in +++ b/scripts/zmaudit.pl.in @@ -57,8 +57,8 @@ use File::Find; use Time::HiRes qw/gettimeofday/; use Getopt::Long; -use constant IMAGE_PATH => ZM_PATH_WEB.'/'.ZM_DIR_IMAGES; -use constant EVENT_PATH => (ZM_DIR_EVENTS=~m|/|)?ZM_DIR_EVENTS:(ZM_PATH_WEB.'/'.ZM_DIR_EVENTS); +use constant IMAGE_PATH => $Config{ZM_PATH_WEB}.'/'.$Config{ZM_DIR_IMAGES}; +use constant EVENT_PATH => ($Config{ZM_DIR_EVENTS}=~m|/|)?$Config{ZM_DIR_EVENTS}:($Config{ZM_PATH_WEB}.'/'.$Config{ZM_DIR_EVENTS}); $| = 1; @@ -107,7 +107,7 @@ chdir( EVENT_PATH ); my $max_image_age = 6/24; # 6 hours my $max_swap_age = 24/24; # 24 hours my $image_path = IMAGE_PATH; -my $swap_image_path = ZM_PATH_SWAP; +my $swap_image_path = $Config{ZM_PATH_SWAP}; my $loop = 1; my $cleaned = 0; @@ -142,7 +142,7 @@ MAIN: while( $loop ) my $fs_events = $fs_monitors->{$monitor} = {}; ( my $monitor_dir ) = ( $monitor =~ /^(.*)$/ ); # De-taint - if ( ZM_USE_DEEP_STORAGE ) + if ( $Config{ZM_USE_DEEP_STORAGE} ) { foreach my $day_dir ( <$monitor_dir/*/*/*> ) { @@ -399,9 +399,9 @@ MAIN: while( $loop ) File::Find::find( { wanted=>\&deleteSwapImage, untaint=>1 }, $swap_image_root ); # Prune the Logs table if required - if ( ZM_LOG_DATABASE_LIMIT ) + if ( $Config{ZM_LOG_DATABASE_LIMIT} ) { - if ( ZM_LOG_DATABASE_LIMIT =~ /^\d+$/ ) + if ( $Config{ZM_LOG_DATABASE_LIMIT} =~ /^\d+$/ ) { # Number of rows my $selectLogRowCountSql = "select count(*) as Rows from Logs"; @@ -410,18 +410,18 @@ MAIN: while( $loop ) my $row = $selectLogRowCountSth->fetchrow_hashref(); my $logRows = $row->{Rows}; $selectLogRowCountSth->finish(); - if ( $logRows > ZM_LOG_DATABASE_LIMIT ) + if ( $logRows > $Config{ZM_LOG_DATABASE_LIMIT} ) { my $deleteLogByRowsSql = "delete low_priority from Logs order by TimeKey asc limit ?"; my $deleteLogByRowsSth = $dbh->prepare_cached( $deleteLogByRowsSql ) or Fatal( "Can't prepare '$deleteLogByRowsSql': ".$dbh->errstr() ); - $res = $deleteLogByRowsSth->execute( $logRows - ZM_LOG_DATABASE_LIMIT ) or Fatal( "Can't execute: ".$deleteLogByRowsSth->errstr() ); + $res = $deleteLogByRowsSth->execute( $logRows - $Config{ZM_LOG_DATABASE_LIMIT} ) or Fatal( "Can't execute: ".$deleteLogByRowsSth->errstr() ); aud_print( "Deleted ".$deleteLogByRowsSth->rows()." log table entries by count\n" ) if ( $deleteLogByRowsSth->rows() ); } } else { # Time of record - my $deleteLogByTimeSql = "delete low_priority from Logs where TimeKey < unix_timestamp(now() - interval ".ZM_LOG_DATABASE_LIMIT.")"; + my $deleteLogByTimeSql = "delete low_priority from Logs where TimeKey < unix_timestamp(now() - interval ".$Config{ZM_LOG_DATABASE_LIMIT}.")"; my $deleteLogByTimeSth = $dbh->prepare_cached( $deleteLogByTimeSql ) or Fatal( "Can't prepare '$deleteLogByTimeSql': ".$dbh->errstr() ); $res = $deleteLogByTimeSth->execute() or Fatal( "Can't execute: ".$deleteLogByTimeSth->errstr() ); aud_print( "Deleted ".$deleteLogByTimeSth->rows()." log table entries by time\n" ) if ( $deleteLogByTimeSth->rows() ); @@ -429,7 +429,7 @@ MAIN: while( $loop ) } $loop = $continuous; - sleep( ZM_AUDIT_CHECK_INTERVAL ) if ( $continuous ); + sleep( $Config{ZM_AUDIT_CHECK_INTERVAL} ) if $continuous; }; exit( 0 ); diff --git a/scripts/zmcontrol.pl.in b/scripts/zmcontrol.pl.in index aba203614..77283acc9 100644 --- a/scripts/zmcontrol.pl.in +++ b/scripts/zmcontrol.pl.in @@ -88,7 +88,7 @@ if ( !$id || !$options{command} ) Debug( $arg_string ); -my $sock_file = ZM_PATH_SOCKS.'/zmcontrol-'.$id.'.sock'; +my $sock_file = $Config{ZM_PATH_SOCKS}.'/zmcontrol-'.$id.'.sock'; socket( CLIENT, PF_UNIX, SOCK_STREAM, 0 ) or Fatal( "Can't open socket: $!" ); diff --git a/scripts/zmdbbackup.in b/scripts/zmdbbackup.in index 303cf86be..37879b5f1 100644 --- a/scripts/zmdbbackup.in +++ b/scripts/zmdbbackup.in @@ -20,6 +20,8 @@ # Edit these to suit your configuration ZM_CONFIG=@ZM_CONFIG@ source $ZM_CONFIG +# ZM_VERSION in the config is now deprecated but will likely still exist in people's config files. This will override it. +ZM_VERSION=@VERSION@ MYSQLDUMP=/usr/bin/mysqldump BACKUP_PATH=/var/lib/zm diff --git a/scripts/zmdc.pl.in b/scripts/zmdc.pl.in index 47e50cc39..c891553d5 100644 --- a/scripts/zmdc.pl.in +++ b/scripts/zmdc.pl.in @@ -51,7 +51,7 @@ use Socket; use IO::Handle; use Data::Dumper; -use constant SOCK_FILE => ZM_PATH_SOCKS.'/zmdc.sock'; +use constant SOCK_FILE => $Config{ZM_PATH_SOCKS}.'/zmdc.sock'; $| = 1; @@ -437,7 +437,7 @@ sub start if ( $daemon =~ /^${daemon_patt}$/ ) { - $daemon = ZM_PATH_BIN.'/'.$1; + $daemon = $Config{ZM_PATH_BIN}.'/'.$1; } else { @@ -645,7 +645,7 @@ sub reaper if ( $process->{keepalive} ) { - if ( !$process->{delay} || ($process->{runtime} > ZM_MAX_RESTART_DELAY) ) + if ( !$process->{delay} || ($process->{runtime} > $Config{ZM_MAX_RESTART_DELAY} ) ) { #start( $process->{daemon}, @{$process->{args}} ); # Schedule for immediate restart @@ -659,9 +659,9 @@ sub reaper $process->{pending} = $process->{stopped}+$process->{delay}; $process->{delay} *= 2; # Limit the start delay to 15 minutes max - if ( $process->{delay} > ZM_MAX_RESTART_DELAY ) + if ( $process->{delay} > $Config{ZM_MAX_RESTART_DELAY} ) { - $process->{delay} = ZM_MAX_RESTART_DELAY; + $process->{delay} = $Config{ZM_MAX_RESTART_DELAY}; } } } diff --git a/scripts/zmeventdump.in b/scripts/zmeventdump.in index 342b665b0..fad82db37 100644 --- a/scripts/zmeventdump.in +++ b/scripts/zmeventdump.in @@ -23,6 +23,8 @@ # Edit these to suit your configuration ZM_CONFIG=@ZM_CONFIG@ +# ZM_VERSION in the config is now deprecated but will likely still exist in people's config files. This will override it. +ZM_VERSION=@VERSION@ MYSQLDUMP=/usr/bin/mysqldump # The rest should not need editing diff --git a/scripts/zmfilter.pl.in b/scripts/zmfilter.pl.in index 19e7a8977..1e9f1bbce 100644 --- a/scripts/zmfilter.pl.in +++ b/scripts/zmfilter.pl.in @@ -51,16 +51,16 @@ use Date::Manip; use Getopt::Long; use Data::Dumper; -use constant EVENT_PATH => (ZM_DIR_EVENTS=~m|/|)?ZM_DIR_EVENTS:(ZM_PATH_WEB.'/'.ZM_DIR_EVENTS); +use constant EVENT_PATH => ($Config{ZM_DIR_EVENTS}=~m|/|)?$Config{ZM_DIR_EVENTS}:($Config{ZM_PATH_WEB}.'/'.$Config{ZM_DIR_EVENTS}); logInit(); logSetSignal(); -if ( ZM_OPT_UPLOAD ) +if ( $Config{ZM_OPT_UPLOAD} ) { # Comment these out if you don't have them and don't want to upload # or don't want to use that format - if ( ZM_UPLOAD_ARCH_FORMAT eq "zip" ) + if ( $Config{ZM_UPLOAD_ARCH_FORMAT} eq "zip" ) { require Archive::Zip; import Archive::Zip qw( :ERROR_CODES :CONSTANTS ); @@ -69,7 +69,7 @@ if ( ZM_OPT_UPLOAD ) { require Archive::Tar; } - if ( ZM_UPLOAD_PROTOCOL eq "ftp" ) + if ( $Config{ZM_UPLOAD_PROTOCOL} eq "ftp" ) { require Net::FTP; } @@ -79,9 +79,9 @@ if ( ZM_OPT_UPLOAD ) } } -if ( ZM_OPT_EMAIL ) +if ( $Config{ZM_OPT_EMAIL} ) { - if ( ZM_NEW_MAIL_MODULES ) + if ( $Config{ZM_NEW_MAIL_MODULES} ) { require MIME::Lite; require Net::SMTP; @@ -92,9 +92,9 @@ if ( ZM_OPT_EMAIL ) } } -if ( ZM_OPT_MESSAGE ) +if ( $Config{ZM_OPT_MESSAGE} ) { - if ( ZM_NEW_MAIL_MODULES ) + if ( $Config{ZM_NEW_MAIL_MODULES} ) { require MIME::Lite; require Net::SMTP; @@ -112,7 +112,7 @@ $ENV{PATH} = '/bin:/usr/bin'; $ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL}; delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; -my $delay = ZM_FILTER_EXECUTE_INTERVAL; +my $delay = $Config{ZM_FILTER_EXECUTE_INTERVAL}; my $event_id = 0; my $filter_parm = ""; @@ -163,6 +163,11 @@ if ( !GetOptions( 'filter=s'=>\$filter_parm ) ) Usage(); } +if ( ! EVENT_PATH ) { + Error( "No event path defined. Config was $Config{ZM_DIR_EVENTS}\n" ); + die; +} + chdir( EVENT_PATH ); my $dbh = zmDbConnect(); @@ -186,7 +191,7 @@ my $last_action = 0; while( 1 ) { - if ( (time() - $last_action) > ZM_FILTER_RELOAD_DELAY ) + if ( (time() - $last_action) > $Config{ZM_FILTER_RELOAD_DELAY} ) { Debug( "Reloading filters\n" ); $last_action = time(); @@ -573,28 +578,28 @@ sub checkFilter my $sth = $dbh->prepare_cached( $sql ) or Fatal( "Can't prepare '$sql': ".$dbh->errstr() ); my $res = $sth->execute( $event->{Id} ) or Fatal( "Can't execute '$sql': ".$sth->errstr() ); } - if ( ZM_OPT_FFMPEG && $filter->{AutoVideo} ) + if ( $Config{ZM_OPT_FFMPEG} && $filter->{AutoVideo} ) { if ( !$event->{Videoed} ) { $delete_ok = undef if ( !generateVideo( $filter, $event ) ); } } - if ( ZM_OPT_EMAIL && $filter->{AutoEmail} ) + if ( $Config{ZM_OPT_EMAIL} && $filter->{AutoEmail} ) { if ( !$event->{Emailed} ) { $delete_ok = undef if ( !sendEmail( $filter, $event ) ); } } - if ( ZM_OPT_MESSAGE && $filter->{AutoMessage} ) + if ( $Config{ZM_OPT_MESSAGE} && $filter->{AutoMessage} ) { if ( !$event->{Messaged} ) { $delete_ok = undef if ( !sendMessage( $filter, $event ) ); } } - if ( ZM_OPT_UPLOAD && $filter->{AutoUpload} ) + if ( $Config{ZM_OPT_UPLOAD} && $filter->{AutoUpload} ) { if ( !$event->{Uploaded} ) { @@ -618,7 +623,7 @@ sub checkFilter my $sth = $dbh->prepare_cached( $sql ) or Fatal( "Can't prepare '$sql': ".$dbh->errstr() ); my $res = $sth->execute( $event->{Id} ) or Fatal( "Can't execute '$sql': ".$sth->errstr() ); - if ( !ZM_OPT_FAST_DELETE ) + if ( ! $Config{ZM_OPT_FAST_DELETE} ) { my $sql = "delete from Frames where EventId = ?"; my $sth = $dbh->prepare_cached( $sql ) or Fatal( "Can't prepare '$sql': ".$dbh->errstr() ); @@ -650,7 +655,7 @@ sub generateVideo my $scale = $event->{DefaultScale}/100; my $format; - my @ffmpeg_formats = split( /\s+/, ZM_FFMPEG_FORMATS ); + my @ffmpeg_formats = split( /\s+/, $Config{ZM_FFMPEG_FORMATS} ); my $default_video_format; my $default_phone_format; foreach my $ffmpeg_format( @ffmpeg_formats ) @@ -678,7 +683,7 @@ sub generateVideo $format = $ffmpeg_formats[0]; } - my $command = ZM_PATH_BIN."/zmvideo.pl -e ".$event->{Id}." -r ".$rate." -s ".$scale." -f ".$format; + my $command = $Config{ZM_PATH_BIN}."/zmvideo.pl -e ".$event->{Id}." -r ".$rate." -s ".$scale." -f ".$format; my $output = qx($command); chomp( $output ); my $status = $? >> 8; @@ -713,22 +718,22 @@ sub uploadArchFile my $filter = shift; my $event = shift; - if ( !ZM_UPLOAD_HOST ) + if ( ! $Config{ZM_UPLOAD_HOST} ) { Error( "Cannot upload archive as no upload host defined" ); return( 0 ); } my $archFile = $event->{MonitorName}.'-'.$event->{Id}; - my $archImagePath = getEventPath( $event )."/".((ZM_UPLOAD_ARCH_ANALYSE)?'{*analyse,*capture}':'*capture').".jpg"; + my $archImagePath = getEventPath( $event )."/".(( $Config{ZM_UPLOAD_ARCH_ANALYSE} )?'{*analyse,*capture}':'*capture').".jpg"; my @archImageFiles = glob($archImagePath); my $archLocPath; my $archError = 0; - if ( ZM_UPLOAD_ARCH_FORMAT eq "zip" ) + if ( $Config{ZM_UPLOAD_ARCH_FORMAT} eq "zip" ) { $archFile .= '.zip'; - $archLocPath = ZM_UPLOAD_LOC_DIR.'/'.$archFile; + $archLocPath = $Config{ZM_UPLOAD_LOC_DIR}.'/'.$archFile; my $zip = Archive::Zip->new(); Info( "Creating upload file '$archLocPath', ".int(@archImageFiles)." files\n" ); @@ -743,7 +748,7 @@ sub uploadArchFile $archError = 1; last; } - $member->desiredCompressionMethod( (ZM_UPLOAD_ARCH_COMPRESS)?&COMPRESSION_DEFLATED:&COMPRESSION_STORED ); + $member->desiredCompressionMethod( $Config{ZM_UPLOAD_ARCH_COMPRESS} ? &COMPRESSION_DEFLATED : &COMPRESSION_STORED ); } if ( !$archError ) { @@ -759,9 +764,9 @@ sub uploadArchFile Error( "Error adding images to zip archive $archLocPath, not writing" ); } } - elsif ( ZM_UPLOAD_ARCH_FORMAT eq "tar" ) + elsif ( $Config{ZM_UPLOAD_ARCH_FORMAT} eq "tar" ) { - if ( ZM_UPLOAD_ARCH_COMPRESS ) + if ( $Config{ZM_UPLOAD_ARCH_COMPRESS} ) { $archFile .= '.tar.gz'; } @@ -769,10 +774,10 @@ sub uploadArchFile { $archFile .= '.tar'; } - $archLocPath = ZM_UPLOAD_LOC_DIR.'/'.$archFile; + $archLocPath = $Config{ZM_UPLOAD_LOC_DIR}.'/'.$archFile; Info( "Creating upload file '$archLocPath', ".int(@archImageFiles)." files\n" ); - if ( $archError = !Archive::Tar->create_archive( $archLocPath, ZM_UPLOAD_ARCH_COMPRESS, @archImageFiles ) ) + if ( $archError = !Archive::Tar->create_archive( $archLocPath, $Config{ZM_UPLOAD_ARCH_COMPRESS}, @archImageFiles ) ) { Error( "Tar error: ".Archive::Tar->error()."\n " ); } @@ -784,39 +789,39 @@ sub uploadArchFile } else { - if ( ZM_UPLOAD_PROTOCOL eq "ftp" ) + if ( $Config{ZM_UPLOAD_PROTOCOL} eq "ftp" ) { - Info( "Uploading to ".ZM_UPLOAD_HOST." using FTP\n" ); - my $ftp = Net::FTP->new( ZM_UPLOAD_HOST, Timeout=>ZM_UPLOAD_TIMEOUT, Passive=>ZM_UPLOAD_FTP_PASSIVE, Debug=>ZM_UPLOAD_DEBUG ); + Info( "Uploading to ".$Config{ZM_UPLOAD_HOST}." using FTP\n" ); + my $ftp = Net::FTP->new( $Config{ZM_UPLOAD_HOST}, Timeout=>$Config{ZM_UPLOAD_TIMEOUT}, Passive=>$Config{ZM_UPLOAD_FTP_PASSIVE}, Debug=>$Config{ZM_UPLOAD_DEBUG} ); if ( !$ftp ) { Error( "Can't create FTP connection: $@" ); return( 0 ); } - $ftp->login( ZM_UPLOAD_USER, ZM_UPLOAD_PASS ) or Error( "FTP - Can't login" ); + $ftp->login( $Config{ZM_UPLOAD_USER}, $Config{ZM_UPLOAD_PASS} ) or Error( "FTP - Can't login" ); $ftp->binary() or Error( "FTP - Can't go binary" ); - $ftp->cwd( ZM_UPLOAD_REM_DIR ) or Error( "FTP - Can't cwd" ) if ( ZM_UPLOAD_REM_DIR ); + $ftp->cwd( $Config{ZM_UPLOAD_REM_DIR} ) or Error( "FTP - Can't cwd" ) if ( $Config{ZM_UPLOAD_REM_DIR} ); $ftp->put( $archLocPath ) or Error( "FTP - Can't upload '$archLocPath'" ); $ftp->quit() or Error( "FTP - Can't quit" ); } else { - my $host = ZM_UPLOAD_HOST; - $host .= ":".ZM_UPLOAD_PORT if ( ZM_UPLOAD_PORT ); + my $host = $Config{ZM_UPLOAD_HOST}; + $host .= ":".$Config{ZM_UPLOAD_PORT} if $Config{ZM_UPLOAD_PORT}; Info( "Uploading to ".$host." using SFTP\n" ); - my %sftpOptions = ( host=>ZM_UPLOAD_HOST, user=>ZM_UPLOAD_USER ); - $sftpOptions{password} = ZM_UPLOAD_PASS if ( ZM_UPLOAD_PASS ); - $sftpOptions{port} = ZM_UPLOAD_PORT if ( ZM_UPLOAD_PORT ); - $sftpOptions{timeout} = ZM_UPLOAD_TIMEOUT if ( ZM_UPLOAD_TIMEOUT ); + my %sftpOptions = ( host=>$Config{ZM_UPLOAD_HOST}, user=>$Config{ZM_UPLOAD_USER} ); + $sftpOptions{password} = $Config{ZM_UPLOAD_PASS} if $Config{ZM_UPLOAD_PASS}; + $sftpOptions{port} = $Config{ZM_UPLOAD_PORT} if $Config{ZM_UPLOAD_PORT}; + $sftpOptions{timeout} = $Config{ZM_UPLOAD_TIMEOUT} if $Config{ZM_UPLOAD_TIMEOUT}; $sftpOptions{more} = [ '-o'=>'StrictHostKeyChecking=no' ]; - $Net::SFTP::Foreign::debug = -1 if ( ZM_UPLOAD_DEBUG ); - my $sftp = Net::SFTP::Foreign->new( ZM_UPLOAD_HOST, %sftpOptions ); + $Net::SFTP::Foreign::debug = -1 if $Config{ZM_UPLOAD_DEBUG}; + my $sftp = Net::SFTP::Foreign->new( $Config{ZM_UPLOAD_HOST}, %sftpOptions ); if ( $sftp->error ) { Error( "Can't create SFTP connection: ".$sftp->error ); return( 0 ); } - $sftp->setcwd( ZM_UPLOAD_REM_DIR ) or Error( "SFTP - Can't setcwd: ".$sftp->error ) if ( ZM_UPLOAD_REM_DIR ); + $sftp->setcwd( $Config{ZM_UPLOAD_REM_DIR} ) or Error( "SFTP - Can't setcwd: ".$sftp->error ) if $Config{ZM_UPLOAD_REM_DIR}; $sftp->put( $archLocPath, $archFile ) or Error( "SFTP - Can't upload '$archLocPath': ".$sftp->error ); } unlink( $archLocPath ); @@ -876,7 +881,7 @@ sub substituteTags $sth->finish(); } - my $url = ZM_URL; + my $url = $Config{ZM_URL}; $text =~ s/%ZP%/$url/g; $text =~ s/%MN%/$event->{MonitorName}/g; $text =~ s/%MET%/$monitor->{EventCount}/g; @@ -908,18 +913,18 @@ sub substituteTags $text =~ s/%EPIM%/$url?view=frame&mid=$event->{MonitorId}&eid=$event->{Id}&fid=$max_alarm_frame->{FrameId}/g; if ( $attachments_ref && $text =~ s/%EI1%//g ) { - push( @$attachments_ref, { type=>"image/jpeg", path=>sprintf( "%s/%0".ZM_EVENT_IMAGE_DIGITS."d-capture.jpg", getEventPath( $event ), $first_alarm_frame->{FrameId} ) } ); + push( @$attachments_ref, { type=>"image/jpeg", path=>sprintf( "%s/%0".$Config{ZM_EVENT_IMAGE_DIGITS}."d-capture.jpg", getEventPath( $event ), $first_alarm_frame->{FrameId} ) } ); } if ( $attachments_ref && $text =~ s/%EIM%//g ) { # Don't attach the same image twice if ( !@$attachments_ref || ($first_alarm_frame->{FrameId} != $max_alarm_frame->{FrameId} ) ) { - push( @$attachments_ref, { type=>"image/jpeg", path=>sprintf( "%s/%0".ZM_EVENT_IMAGE_DIGITS."d-capture.jpg", getEventPath( $event ), $max_alarm_frame->{FrameId} ) } ); + push( @$attachments_ref, { type=>"image/jpeg", path=>sprintf( "%s/%0".$Config{ZM_EVENT_IMAGE_DIGITS}."d-capture.jpg", getEventPath( $event ), $max_alarm_frame->{FrameId} ) } ); } } } - if ( $attachments_ref && ZM_OPT_FFMPEG ) + if ( $attachments_ref && $Config{ZM_OPT_FFMPEG} ) { if ( $text =~ s/%EV%//g ) { @@ -952,12 +957,12 @@ sub sendEmail my $filter = shift; my $event = shift; - if ( !ZM_FROM_EMAIL ) + if ( ! $Config{ZM_FROM_EMAIL} ) { Error( "No 'from' email address defined, not sending email" ); return( 0 ); } - if ( !ZM_EMAIL_ADDRESS ) + if ( ! $Config{ZM_EMAIL_ADDRESS} ) { Error( "No email address defined, not sending email" ); return( 0 ); @@ -965,22 +970,22 @@ sub sendEmail Info( "Creating notification email\n" ); - my $subject = substituteTags( ZM_EMAIL_SUBJECT, $filter, $event ); + my $subject = substituteTags( $Config{ZM_EMAIL_SUBJECT}, $filter, $event ); return( 0 ) if ( !$subject ); my @attachments; - my $body = substituteTags( ZM_EMAIL_BODY, $filter, $event, \@attachments ); + my $body = substituteTags( $Config{ZM_EMAIL_BODY}, $filter, $event, \@attachments ); return( 0 ) if ( !$body ); Info( "Sending notification email '$subject'\n" ); eval { - if ( ZM_NEW_MAIL_MODULES ) + if ( $Config{ZM_NEW_MAIL_MODULES} ) { ### Create the multipart container my $mail = MIME::Lite->new ( - From => ZM_FROM_EMAIL, - To => ZM_EMAIL_ADDRESS, + From => $Config{ZM_FROM_EMAIL}, + To => $Config{ZM_EMAIL_ADDRESS}, Subject => $subject, Type => "multipart/mixed" ); @@ -1000,14 +1005,14 @@ sub sendEmail ); } ### Send the Message - MIME::Lite->send( "smtp", ZM_EMAIL_HOST, Timeout=>60 ); + MIME::Lite->send( "smtp", $Config{ZM_EMAIL_HOST}, Timeout=>60 ); $mail->send(); } else { my $mail = MIME::Entity->build( - From => ZM_FROM_EMAIL, - To => ZM_EMAIL_ADDRESS, + From => $Config{ZM_FROM_EMAIL}, + To => $Config{ZM_EMAIL_ADDRESS}, Subject => $subject, Type => (($body=~//)?'text/html':'text/plain'), Data => $body @@ -1022,7 +1027,7 @@ sub sendEmail Encoding => "base64" ); } - $mail->smtpsend( Host => ZM_EMAIL_HOST, MailFrom => ZM_FROM_EMAIL ); + $mail->smtpsend( Host => $Config{ZM_EMAIL_HOST}, MailFrom => $Config{ZM_FROM_EMAIL} ); } }; if ( $@ ) @@ -1046,12 +1051,12 @@ sub sendMessage my $filter = shift; my $event = shift; - if ( !ZM_FROM_EMAIL ) + if ( ! $Config{ZM_FROM_EMAIL} ) { Error( "No 'from' email address defined, not sending message" ); return( 0 ); } - if ( !ZM_MESSAGE_ADDRESS ) + if ( ! $Config{ZM_MESSAGE_ADDRESS} ) { Error( "No message address defined, not sending message" ); return( 0 ); @@ -1059,22 +1064,22 @@ sub sendMessage Info( "Creating notification message\n" ); - my $subject = substituteTags( ZM_MESSAGE_SUBJECT, $filter, $event ); + my $subject = substituteTags( $Config{ZM_MESSAGE_SUBJECT}, $filter, $event ); return( 0 ) if ( !$subject ); my @attachments; - my $body = substituteTags( ZM_MESSAGE_BODY, $filter, $event, \@attachments ); + my $body = substituteTags( $Config{ZM_MESSAGE_BODY}, $filter, $event, \@attachments ); return( 0 ) if ( !$body ); Info( "Sending notification message '$subject'\n" ); eval { - if ( ZM_NEW_MAIL_MODULES ) + if ( $Config{ZM_NEW_MAIL_MODULES} ) { ### Create the multipart container my $mail = MIME::Lite->new ( - From => ZM_FROM_EMAIL, - To => ZM_MESSAGE_ADDRESS, + From => $Config{ZM_FROM_EMAIL}, + To => $Config{ZM_MESSAGE_ADDRESS}, Subject => $subject, Type => "multipart/mixed" ); @@ -1094,14 +1099,14 @@ sub sendMessage ); } ### Send the Message - MIME::Lite->send( "smtp", ZM_EMAIL_HOST, Timeout=>60 ); + MIME::Lite->send( "smtp", $Config{ZM_EMAIL_HOST}, Timeout=>60 ); $mail->send(); } else { my $mail = MIME::Entity->build( - From => ZM_FROM_EMAIL, - To => ZM_MESSAGE_ADDRESS, + From => $Config{ZM_FROM_EMAIL}, + To => $Config{ZM_MESSAGE_ADDRESS}, Subject => $subject, Type => (($body=~//)?'text/html':'text/plain'), Data => $body @@ -1116,7 +1121,7 @@ sub sendMessage Encoding => "base64" ); } - $mail->smtpsend( Host => ZM_EMAIL_HOST, MailFrom => ZM_FROM_EMAIL ); + $mail->smtpsend( Host => $Config{ZM_EMAIL_HOST}, MailFrom => $Config{ZM_FROM_EMAIL} ); } }; if ( $@ ) diff --git a/scripts/zmpkg.pl.in b/scripts/zmpkg.pl.in index 1158a1a29..b69c78b71 100644 --- a/scripts/zmpkg.pl.in +++ b/scripts/zmpkg.pl.in @@ -57,9 +57,9 @@ if ( !$command || $command !~ /^(?:start|stop|restart|status|logrot)$/ ) if ( $command ) { # Check to see if it's a valid run state - my $sql = "select * from States where Name = '$command'"; + my $sql = 'select * from States where Name = ?'; my $sth = $dbh->prepare_cached( $sql ) or Fatal( "Can't prepare '$sql': ".$dbh->errstr() ); - my $res = $sth->execute() or Fatal( "Can't execute: ".$sth->errstr() ); + my $res = $sth->execute( $command ) or Fatal( "Can't execute: ".$sth->errstr() ); if ( $state = $sth->fetchrow_hashref() ) { $state->{Name} = $command; @@ -84,7 +84,7 @@ if ( !$command || $command !~ /^(?:start|stop|restart|status|logrot)$/ ) } # Move to the right place -chdir( ZM_PATH_WEB ) or Fatal( "Can't chdir to '".ZM_PATH_WEB."': $!" ); +chdir( $Config{ZM_PATH_WEB} ) or Fatal( "Can't chdir to '".$Config{ZM_PATH_WEB}."': $!" ); my $dbg_id = ""; @@ -138,7 +138,7 @@ if ( $command =~ /^(?:stop|restart)$/ ) } } -runCommand( "zmupdate.pl -f" ); +#runCommand( "zmupdate.pl -f" ); if ( $command =~ /^(?:start|restart)$/ ) { @@ -146,9 +146,9 @@ if ( $command =~ /^(?:start|restart)$/ ) if ( $status eq "stopped" ) { - if ( ZM_DYN_DB_VERSION && ZM_DYN_DB_VERSION ne ZM_VERSION ) + if ( $Config{ZM_DYN_DB_VERSION} and ( $Config{ZM_DYN_DB_VERSION} ne ZM_VERSION ) ) { - Fatal( "Version mismatch, system is version ".ZM_VERSION.", database is ".ZM_DYN_DB_VERSION.", please run zmupdate.pl to update." ); + Fatal( "Version mismatch, system is version ".ZM_VERSION.", database is ".$Config{ZM_DYN_DB_VERSION}.", please run zmupdate.pl to update." ); exit( -1 ); } @@ -158,15 +158,14 @@ if ( $command =~ /^(?:start|restart)$/ ) Debug( "Recreating temporary directory '@ZM_TMPDIR@'" ); mkdir( "@ZM_TMPDIR@", 0700 ) or Fatal( "Can't create missing temporary directory '@ZM_TMPDIR@': $!" ); my ( $runName ) = getpwuid( $> ); - if ( $runName ne ZM_WEB_USER ) + if ( $runName ne $Config{ZM_WEB_USER} ) { # Not running as web user, so should be root in whch case chown the temporary directory - my ( $webName, $webPass, $webUid, $webGid ) = getpwnam( ZM_WEB_USER ) or Fatal( "Can't get user details for web user '".ZM_WEB_USER."': $!" ); - chown( $webUid, $webGid, "@ZM_TMPDIR@" ) or Fatal( "Can't change ownership of temporary directory '@ZM_TMPDIR@' to '".ZM_WEB_USER.":".ZM_WEB_GROUP."': $!" ); + my ( $webName, $webPass, $webUid, $webGid ) = getpwnam( $Config{ZM_WEB_USER} ) or Fatal( "Can't get user details for web user '".$Config{ZM_WEB_USER}."': $!" ); + chown( $webUid, $webGid, "@ZM_TMPDIR@" ) or Fatal( "Can't change ownership of temporary directory '@ZM_TMPDIR@' to '".$Config{ZM_WEB_USER}.":".$Config{ZM_WEB_GROUP}."': $!" ); } } zmMemTidy(); - runCommand( "zmfix" ); runCommand( "zmdc.pl startup" ); my $sql = "select * from Monitors"; @@ -186,13 +185,13 @@ if ( $command =~ /^(?:start|restart)$/ ) } if ( $monitor->{Function} ne 'Monitor' ) { - if ( ZM_OPT_FRAME_SERVER ) + if ( $Config{ZM_OPT_FRAME_SERVER} ) { runCommand( "zmdc.pl start zmf -m $monitor->{Id}" ); } runCommand( "zmdc.pl start zma -m $monitor->{Id}" ); } - if ( ZM_OPT_CONTROL ) + if ( $Config{ZM_OPT_CONTROL} ) { if ( $monitor->{Function} eq 'Modect' || $monitor->{Function} eq 'Mocord' ) { @@ -208,20 +207,20 @@ if ( $command =~ /^(?:start|restart)$/ ) # This is now started unconditionally runCommand( "zmdc.pl start zmfilter.pl" ); - if ( ZM_RUN_AUDIT ) + if ( $Config{ZM_RUN_AUDIT} ) { runCommand( "zmdc.pl start zmaudit.pl -c" ); } - if ( ZM_OPT_TRIGGERS ) + if ( $Config{ZM_OPT_TRIGGERS} ) { runCommand( "zmdc.pl start zmtrigger.pl" ); } - if ( ZM_OPT_X10 ) + if ( $Config{ZM_OPT_X10} ) { runCommand( "zmdc.pl start zmx10.pl -c start" ); } runCommand( "zmdc.pl start zmwatch.pl" ); - if ( ZM_CHECK_FOR_UPDATES ) + if ( $Config{ZM_CHECK_FOR_UPDATES} ) { runCommand( "zmdc.pl start zmupdate.pl -c" ); } @@ -245,3 +244,5 @@ if ( $command eq "logrot" ) } exit( $retval ); + +__END__ diff --git a/scripts/zmupdate.pl.in b/scripts/zmupdate.pl.in index d80209885..cc2e93467 100644 --- a/scripts/zmupdate.pl.in +++ b/scripts/zmupdate.pl.in @@ -54,7 +54,7 @@ use DBI; use Getopt::Long; use Data::Dumper; -use constant EVENT_PATH => (ZM_DIR_EVENTS=~m|/|)?ZM_DIR_EVENTS:(ZM_PATH_WEB.'/'.ZM_DIR_EVENTS); +use constant EVENT_PATH => ($Config{ZM_DIR_EVENTS}=~m|/|)?$Config{ZM_DIR_EVENTS}:($Config{ZM_PATH_WEB}.'/'.$Config{ZM_DIR_EVENTS}); $| = 1; @@ -62,7 +62,7 @@ $ENV{PATH} = '/bin:/usr/bin:/usr/local/bin'; $ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL}; delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; -my $web_uid = (getpwnam( ZM_WEB_USER ))[2]; +my $web_uid = (getpwnam( $Config{ZM_WEB_USER} ))[2]; my $use_log = (($> == 0) || ($> == $web_uid)); logInit( toFile=>$use_log?DEBUG:NOLOG ); @@ -75,8 +75,8 @@ my $rename = 0; my $zoneFix = 0; my $migrateEvents = 0; my $version = ''; -my $dbUser = ZM_DB_USER; -my $dbPass = ZM_DB_PASS; +my $dbUser = $Config{ZM_DB_USER}; +my $dbPass = $Config{ZM_DB_PASS}; my $updateDir = ''; sub Usage { @@ -99,15 +99,14 @@ if ( !GetOptions( 'check'=>\$check, 'freshen'=>\$freshen, 'rename'=>\$rename, 'z } my $dbh = zmDbConnect(); -*ZoneMinder::Database::ZM_DB_USER = sub { $dbUser } if ZoneMinder::Database::ZM_DB_USER ne $dbUser; -*ZoneMinder::Database::ZM_DB_PASS = sub { $dbPass } if ZoneMinder::Database::ZM_DB_PASS ne $dbPass; -zmDbDisconnect(); +$Config{ZM_DB_USER} = $dbUser; +$Config{ZM_DB_PASS} = $dbPass; if ( ! ($check || $freshen || $rename || $zoneFix || $migrateEvents || $version) ) { - if ( ZM_DYN_DB_VERSION ) + if ( $Config{ZM_DYN_DB_VERSION} ) { - $version = ZM_DYN_DB_VERSION; + $version = $Config{ZM_DYN_DB_VERSION}; } else { @@ -122,46 +121,35 @@ if ( ($check + $freshen + $rename + $zoneFix + $migrateEvents + ($version?1:0)) Usage(); } -if ( $check && ZM_CHECK_FOR_UPDATES ) +if ( $check && $Config{ZM_CHECK_FOR_UPDATES} ) { print( "Update agent starting at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" ); - my $dbh = zmDbConnect(); - - my $currVersion = ZM_DYN_CURR_VERSION; - my $lastVersion = ZM_DYN_LAST_VERSION; - my $lastCheck = ZM_DYN_LAST_CHECK; + my $currVersion = $Config{ZM_DYN_CURR_VERSION}; + my $lastVersion = $Config{ZM_DYN_LAST_VERSION}; + my $lastCheck = $Config{ZM_DYN_LAST_CHECK}; if ( !$currVersion ) { - $currVersion = ZM_VERSION; + $currVersion = $Config{ZM_VERSION}; my $sql = "update Config set Value = ? where Name = 'ZM_DYN_CURR_VERSION'"; my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); my $res = $sth->execute( "$currVersion" ) or die( "Can't execute: ".$sth->errstr() ); } - zmDbDisconnect(); while( 1 ) { my $now = time(); if ( !$lastVersion || !$lastCheck || (($now-$lastCheck) > CHECK_INTERVAL) ) { - $dbh = zmDbConnect(); - Info( "Checking for updates\n" ); use LWP::UserAgent; my $ua = LWP::UserAgent->new; $ua->agent( "ZoneMinder Update Agent/".ZM_VERSION ); - if ( eval('defined(ZM_UPDATE_CHECK_PROXY)') ) - { - no strict 'subs'; - if ( ZM_UPDATE_CHECK_PROXY ) - { - $ua->proxy( "http", ZM_UPDATE_CHECK_PROXY ); - } - use strict 'subs'; + if ( $Config{ZM_UPDATE_CHECK_PROXY} ) { + $ua->proxy( "http", $Config{ZM_UPDATE_CHECK_PROXY} ); } my $req = HTTP::Request->new( GET=>'http://zoneminder.github.io/ZoneMinder/version.txt' ); my $res = $ua->request($req); @@ -186,7 +174,6 @@ if ( $check && ZM_CHECK_FOR_UPDATES ) { Error( "Error check failed: '".$res->status_line()."'\n" ); } - zmDbDisconnect(); } sleep( 3600 ); } @@ -222,9 +209,6 @@ if ( $rename ) } if ( $zoneFix ) { - require DBI; - - my $dbh = zmDbConnect(); my $sql = "select Z.*, M.Width as MonitorWidth, M.Height as MonitorHeight from Zones as Z inner join Monitors as M on Z.MonitorId = M.Id where Z.Units = 'Percent'"; my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); @@ -257,12 +241,12 @@ if ( $zoneFix ) } if ( $migrateEvents ) { - my $webUid = (getpwnam( ZM_WEB_USER ))[2]; - my $webGid = (getgrnam( ZM_WEB_USER ))[2]; + my $webUid = (getpwnam( $Config{ZM_WEB_USER} ))[2]; + my $webGid = (getgrnam( $Config{ZM_WEB_USER} ))[2]; if ( !(($> == 0) || ($> == $webUid)) ) { - print( "Error, migrating events can only be done as user root or ".ZM_WEB_USER.".\n" ); + print( "Error, migrating events can only be done as user root or ".$Config{ZM_WEB_USER}.".\n" ); exit( -1 ); } @@ -286,8 +270,7 @@ if ( $migrateEvents ) { print( "Converting all events to deep storage.\n" ); - chdir( ZM_PATH_WEB ); - my $dbh = zmDbConnect(); + chdir( $Config{ZM_PATH_WEB} ); my $sql = "select *, unix_timestamp(StartTime) as UnixStartTime from Events"; my $sth = $dbh->prepare_cached( $sql ) or Fatal( "Can't prepare '$sql': ".$dbh->errstr() ); my $res = $sth->execute(); @@ -298,7 +281,7 @@ if ( $migrateEvents ) while( my $event = $sth->fetchrow_hashref() ) { - my $oldEventPath = ZM_DIR_EVENTS.'/'.$event->{MonitorId}.'/'.$event->{Id}; + my $oldEventPath = $Config{ZM_DIR_EVENTS}.'/'.$event->{MonitorId}.'/'.$event->{Id}; if ( !-d $oldEventPath ) { @@ -307,11 +290,11 @@ if ( $migrateEvents ) } print( "Converting event ".$event->{Id}."\n" ); - my $newDatePath = ZM_DIR_EVENTS.'/'.$event->{MonitorId}.'/'.strftime( "%y/%m/%d", localtime($event->{UnixStartTime}) ); + my $newDatePath = $Config{ZM_DIR_EVENTS}.'/'.$event->{MonitorId}.'/'.strftime( "%y/%m/%d", localtime($event->{UnixStartTime}) ); my $newTimePath = strftime( "%H/%M/%S", localtime($event->{UnixStartTime}) ); my $newEventPath = $newDatePath.'/'.$newTimePath; ( my $truncEventPath = $newEventPath ) =~ s|/\d+$||; - makePath( $truncEventPath, ZM_PATH_WEB ); + makePath( $truncEventPath, $Config{ZM_PATH_WEB} ); my $idLink = $newDatePath.'/.'.$event->{Id}; symlink( $newTimePath, $idLink ) or die( "Can't symlink $newTimePath -> $idLink: $!" ); rename( $oldEventPath, $newEventPath ) or die( "Can't move $oldEventPath -> $newEventPath: $!" ); @@ -335,6 +318,34 @@ if ( $freshen ) loadConfigFromDB(); saveConfigToDB(); } + +# Now check for MyISAM Tables +my @MyISAM_Tables; +my $sql = "SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='zm' AND engine = 'MyISAM'"; +my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); +my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() ); + +while( my $dbTable = $sth->fetchrow() ) { + push @MyISAM_Tables, $dbTable; +} +$sth->finish(); + +if ( @MyISAM_Tables ) { + print( "\nPrevious versions of ZoneMinder used the MyISAM database engine.\nHowever, the recommended database engine is InnoDB.\n"); + print( "\nHint: InnoDB tables are much less likely to be corrupted during an unclean shutdown.\n\nPress 'y' to convert your tables to InnoDB or 'n' to skip : "); + my $response = ; + chomp( $response ); + if ( $response =~ /^[yY]$/ ) { + print "\nConverting MyISAM tables to InnoDB. Please wait.\n"; + foreach (@MyISAM_Tables) { + my $sql = "ALTER TABLE $_ ENGINE = InnoDB"; + my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); + my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() ); + $sth->finish(); + } + } +} + if ( $version ) { my ( $detaint_version ) = $version =~ /^([\w.]+)$/; @@ -343,15 +354,15 @@ if ( $version ) if ( ZM_VERSION eq $version ) { print( "\nDatabase already at version $version, update aborted.\n\n" ); - exit( -1 ); + exit( 0 ); } print( "\nInitiating database upgrade to version ".ZM_VERSION." from version $version\n" ); if ( $interactive ) { - if ( ZM_DYN_DB_VERSION && ZM_DYN_DB_VERSION ne $version ) + if ( $Config{ZM_DYN_DB_VERSION} && $Config{ZM_DYN_DB_VERSION} ne $version ) { - print( "\nWARNING - You have specified an upgrade from version $version but the database version found is ".ZM_DYN_DB_VERSION.". Is this correct?\nPress enter to continue or ctrl-C to abort : " ); + print( "\nWARNING - You have specified an upgrade from version $version but the database version found is ".$Config{ZM_DYN_DB_VERSION}.". Is this correct?\nPress enter to continue or ctrl-C to abort : " ); my $response = ; } @@ -370,7 +381,7 @@ if ( $version ) if ( $response =~ /^[yY]$/ ) { - my ( $host, $port ) = ( ZM_DB_HOST =~ /^([^:]+)(?::(.+))?$/ ); + my ( $host, $port ) = ( $Config{ZM_DB_HOST} =~ /^([^:]+)(?::(.+))?$/ ); my $command = "mysqldump -h".$host; $command .= " -P".$port if defined($port); if ( $dbUser ) @@ -381,8 +392,8 @@ if ( $version ) $command .= " -p".$dbPass; } } - my $backup = "@ZM_TMPDIR@/".ZM_DB_NAME."-".$version.".dump"; - $command .= " --add-drop-table --databases ".ZM_DB_NAME." > ".$backup; + my $backup = "@ZM_TMPDIR@/".$Config{ZM_DB_NAME}."-".$version.".dump"; + $command .= " --add-drop-table --databases ".$Config{ZM_DB_NAME}." > ".$backup; print( "Creating backup to $backup. This may take several minutes.\n" ); print( "Executing '$command'\n" ) if ( logDebugging() ); my $output = qx($command); @@ -411,7 +422,7 @@ if ( $version ) my $dbh = shift; my $version = shift; - my ( $host, $port ) = ( ZM_DB_HOST =~ /^([^:]+)(?::(.+))?$/ ); + my ( $host, $port ) = ( $Config{ZM_DB_HOST} =~ /^([^:]+)(?::(.+))?$/ ); my $command = "mysql -h".$host; $command .= " -P".$port if defined($port); if ( $dbUser ) @@ -422,14 +433,14 @@ if ( $version ) $command .= " -p".$dbPass; } } - $command .= " ".ZM_DB_NAME." < "; + $command .= " ".$Config{ZM_DB_NAME}." < "; if ( $updateDir ) { $command .= $updateDir; } else { - $command .= ZM_PATH_DATA."/db"; + $command .= $Config{ZM_PATH_DATA}."/db"; } $command .= "/zm_update-".$version.".sql"; @@ -454,34 +465,6 @@ if ( $version ) } } - sub toInnoDB - { - my $dbh = shift; - my $sql = "SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='zm' AND engine = 'MyISAM'"; - my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); - my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() ); - - my @dbTables; - while( my $dbTable = $sth->fetchrow() ) - { - push( @dbTables, $dbTable ); - } - $sth->finish(); - - if (@dbTables) - { - print "\nConverting MyISAM tables to InnoDB. Please wait.\n"; - foreach (@dbTables) - { - my $sql = "ALTER TABLE $_ ENGINE = InnoDB"; - my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); - my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() ); - } - $sth->finish(); - } else { - print "\nNo MyISAM tables found. Skipping...\n"; - } - } print( "\nUpgrading database to version ".ZM_VERSION."\n" ); @@ -489,8 +472,6 @@ if ( $version ) loadConfigFromDB(); saveConfigToDB(); - my $dbh = zmDbConnect(); - my $cascade = undef; if ( $cascade || $version eq "1.19.0" ) { @@ -518,8 +499,6 @@ if ( $version ) } if ( $cascade || $version eq "1.19.4" ) { - require DBI; - # Rename the event directories and create a new symlink for the names chdir( EVENT_PATH ); @@ -742,7 +721,7 @@ if ( $version ) my ( $sql, $sth, $res ); if ( defined(&ZM_EMAIL_TEXT) && &ZM_EMAIL_TEXT ) { - my ( $email_subject, $email_body ) = ZM_EMAIL_TEXT =~ /subject\s*=\s*"([^\n]*)".*body\s*=\s*"(.*)"?$/ms; + my ( $email_subject, $email_body ) = $Config{ZM_EMAIL_TEXT} =~ /subject\s*=\s*"([^\n]*)".*body\s*=\s*"(.*)"?$/ms; $sql = "replace into Config set Id = 0, Name = 'ZM_EMAIL_SUBJECT', Value = '".$email_subject."', Type = 'string', DefaultValue = 'ZoneMinder: Alarm - %MN%-%EI% (%ESM% - %ESA% %EFA%)', Hint = 'string', Pattern = '(?-xism:^(.+)\$)', Format = ' \$1 ', Prompt = 'The subject of the email used to send matching event details', Help = 'This option is used to define the subject of the email that is sent for any events that match the appropriate filters.', Category = 'mail', Readonly = '0', Requires = 'ZM_OPT_EMAIL=1'"; $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() ); @@ -752,7 +731,7 @@ if ( $version ) } if ( defined(&ZM_MESSAGE_TEXT) && &ZM_MESSAGE_TEXT ) { - my ( $message_subject, $message_body ) = ZM_MESSAGE_TEXT =~ /subject\s*=\s*"([^\n]*)".*body\s*=\s*"(.*)"?$/ms; + my ( $message_subject, $message_body ) = $Config{ZM_MESSAGE_TEXT} =~ /subject\s*=\s*"([^\n]*)".*body\s*=\s*"(.*)"?$/ms; $sql = "replace into Config set Id = 0, Name = 'ZM_MESSAGE_SUBJECT', Value = '".$message_subject."', Type = 'string', DefaultValue = 'ZoneMinder: Alarm - %MN%-%EI%', Hint = 'string', Pattern = '(?-xism:^(.+)\$)', Format = ' \$1 ', Prompt = 'The subject of the message used to send matching event details', Help = 'This option is used to define the subject of the message that is sent for any events that match the appropriate filters.', Category = 'mail', Readonly = '0', Requires = 'ZM_OPT_MESSAGE=1'"; $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() ); @@ -886,7 +865,7 @@ if ( $version ) my $sql = "update Config set Value = ? where Name = 'ZM_JPEG_STREAM_QUALITY'"; my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); - my $res = $sth->execute( ZM_JPEG_IMAGE_QUALITY ) or die( "Can't execute: ".$sth->errstr() ); + my $res = $sth->execute( $Config{ZM_JPEG_IMAGE_QUALITY} ) or die( "Can't execute: ".$sth->errstr() ); } $cascade = !undef; } @@ -1014,14 +993,6 @@ if ( $version ) } # end if $sth->finish(); - print( "\nPrevious versions of ZoneMinder used the MyISAM database engine.\nHowever, the recommended database engine is InnoDB.\n"); - print( "\nHint: InnoDB tables are much less likely to be corrupted during an unclean shutdown.\n\nPress 'y' to convert your tables to InnoDB or 'n' to skip : "); - my $response = ; - chomp( $response ); - if ( $response =~ /^[yY]$/ ) - { - toInnoDB($dbh); - } $cascade = !undef; $version = '1.26.0'; @@ -1030,7 +1001,7 @@ if ( $version ) if ( $version ge '1.26.0' ) { my @files; - $updateDir = ZM_PATH_DATA."/db" if ! $updateDir; + $updateDir = $Config{ZM_PATH_DATA}."/db" if ! $updateDir; opendir( my $dh, $updateDir ) || die "Can't open updateDir $!"; @files = sort grep { (!/^\./) && /^zm_update\-[\d\.]+\.sql$/ && -f "$updateDir/$_" } readdir($dh); closedir $dh; @@ -1061,13 +1032,13 @@ if ( $version ) my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); my $res = $sth->execute( "$installed_version", "ZM_DYN_DB_VERSION" ) or die( "Can't execute: ".$sth->errstr() ); $res = $sth->execute( "$installed_version", "ZM_DYN_CURR_VERSION" ) or die( "Can't execute: ".$sth->errstr() ); - $dbh->disconnect(); } else { - $dbh->disconnect(); + zmDbDisconnect(); die( "Can't find upgrade from version '$version'" ); } print( "\nDatabase upgrade to version ".ZM_VERSION." successful.\n\n" ); } +zmDbDisconnect(); exit( 0 ); diff --git a/scripts/zmvideo.pl.in b/scripts/zmvideo.pl.in index 236e5d20c..46cf83998 100644 --- a/scripts/zmvideo.pl.in +++ b/scripts/zmvideo.pl.in @@ -56,7 +56,7 @@ my $fps = ''; my $size = ''; my $overwrite = 0; -my @formats = split( /\s+/, ZM_FFMPEG_FORMATS ); +my @formats = split( /\s+/, $Config{ZM_FFMPEG_FORMATS} ); for ( my $i = 0; $i < @formats; $i++ ) { if ( $i =~ /^(.+)\*$/ ) @@ -92,7 +92,7 @@ if ( !$event_id || $event_id < 0 ) Usage(); } -if ( !ZM_OPT_FFMPEG ) +if ( ! $Config{ZM_OPT_FFMPEG} ) { print( STDERR "Mpeg encoding is not currently enabled\n" ); exit(-1); @@ -221,7 +221,7 @@ if ( $overwrite || !-s $video_file ) $video_size = $size; } - my $command = ZM_PATH_FFMPEG." -y -r $frame_rate ".ZM_FFMPEG_INPUT_OPTIONS." -i %0".ZM_EVENT_IMAGE_DIGITS."d-capture.jpg -s $video_size ".ZM_FFMPEG_OUTPUT_OPTIONS." '$video_file' > ffmpeg.log 2>&1"; + my $command = $Config{ZM_PATH_FFMPEG}." -y -r $frame_rate ".$Config{ZM_FFMPEG_INPUT_OPTIONS}." -i %0".$Config{ZM_EVENT_IMAGE_DIGITS}."d-capture.jpg -s $video_size ".$Config{ZM_FFMPEG_OUTPUT_OPTIONS}." '$video_file' > ffmpeg.log 2>&1"; Debug( $command."\n" ); my $output = qx($command); diff --git a/scripts/zmwatch.pl.in b/scripts/zmwatch.pl.in index 4d50f0496..bfa8b54bd 100644 --- a/scripts/zmwatch.pl.in +++ b/scripts/zmwatch.pl.in @@ -90,7 +90,7 @@ while( 1 ) next if ( !defined($image_time) ); # Can't read from shared data next if ( !$image_time ); # We can't get the last capture time so can't be sure it's died. - my $max_image_delay = ($monitor->{MaxFPS}&&($monitor->{MaxFPS}>0)&&($monitor->{MaxFPS}<1))?(3/$monitor->{MaxFPS}):ZM_WATCH_MAX_DELAY; + my $max_image_delay = ($monitor->{MaxFPS}&&($monitor->{MaxFPS}>0)&&($monitor->{MaxFPS}<1))?(3/$monitor->{MaxFPS}):$Config{ZM_WATCH_MAX_DELAY}; my $image_delay = $now-$image_time; Debug( "Monitor $monitor->{Id} last captured $image_delay seconds ago, max is $max_image_delay\n" ); if ( $image_delay > $max_image_delay ) @@ -127,7 +127,7 @@ while( 1 ) next if ( !defined($image_time) ); # Can't read from shared data next if ( !$image_time ); # We can't get the last capture time so can't be sure it's died. - my $max_image_delay = ($monitor->{MaxFPS}&&($monitor->{MaxFPS}>0)&&($monitor->{MaxFPS}<1))?(3/$monitor->{MaxFPS}):ZM_WATCH_MAX_DELAY; + my $max_image_delay = ($monitor->{MaxFPS}&&($monitor->{MaxFPS}>0)&&($monitor->{MaxFPS}<1))?(3/$monitor->{MaxFPS}):$Config{ZM_WATCH_MAX_DELAY}; my $image_delay = $now-$image_time; Debug( "Monitor $monitor->{Id} last analysed $image_delay seconds ago, max is $max_image_delay\n" ); if ( $image_delay > $max_image_delay ) @@ -142,7 +142,7 @@ while( 1 ) # Prevent open handles building up if we have connect to shared memory zmMemInvalidate( $monitor ); } - sleep( ZM_WATCH_CHECK_INTERVAL ); + sleep( $Config{ZM_WATCH_CHECK_INTERVAL} ); } Info( "Watchdog exiting\n" ); exit(); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dce028e03..28a07a87d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,7 +4,7 @@ configure_file(zm_config.h.in "${CMAKE_CURRENT_BINARY_DIR}/zm_config.h" @ONLY) # Group together all the source files that are used by all the binaries (zmc, zma, zmu, zms etc) -set(ZM_BIN_SRC_FILES zm_box.cpp zm_buffer.cpp zm_camera.cpp zm_comms.cpp zm_config.cpp zm_coord.cpp zm_curl_camera.cpp zm.cpp zm_db.cpp zm_logger.cpp zm_event.cpp zm_exception.cpp zm_file_camera.cpp zm_ffmpeg_camera.cpp zm_image.cpp zm_jpeg.cpp zm_local_camera.cpp zm_monitor.cpp zm_ffmpeg.cpp zm_mpeg.cpp zm_poly.cpp zm_regexp.cpp zm_remote_camera.cpp zm_remote_camera_http.cpp zm_remote_camera_rtsp.cpp zm_rtp.cpp zm_rtp_ctrl.cpp zm_rtp_data.cpp zm_rtp_source.cpp zm_rtsp.cpp zm_sdp.cpp zm_signal.cpp zm_stream.cpp zm_thread.cpp zm_time.cpp zm_timer.cpp zm_user.cpp zm_utils.cpp zm_zone.cpp) +set(ZM_BIN_SRC_FILES zm_box.cpp zm_buffer.cpp zm_camera.cpp zm_comms.cpp zm_config.cpp zm_coord.cpp zm_curl_camera.cpp zm.cpp zm_db.cpp zm_logger.cpp zm_event.cpp zm_exception.cpp zm_file_camera.cpp zm_ffmpeg_camera.cpp zm_image.cpp zm_jpeg.cpp zm_libvlc_camera.cpp zm_local_camera.cpp zm_monitor.cpp zm_ffmpeg.cpp zm_mpeg.cpp zm_poly.cpp zm_regexp.cpp zm_remote_camera.cpp zm_remote_camera_http.cpp zm_remote_camera_rtsp.cpp zm_rtp.cpp zm_rtp_ctrl.cpp zm_rtp_data.cpp zm_rtp_source.cpp zm_rtsp.cpp zm_sdp.cpp zm_signal.cpp zm_stream.cpp zm_thread.cpp zm_time.cpp zm_timer.cpp zm_user.cpp zm_utils.cpp zm_zone.cpp) # A fix for cmake recompiling the source files for every target. add_library(zm STATIC ${ZM_BIN_SRC_FILES}) @@ -16,7 +16,6 @@ add_executable(zmf zmf.cpp) add_executable(zms zms.cpp) add_executable(nph-zms zms.cpp) add_executable(zmstreamer zmstreamer.cpp) -add_executable(zmfix zmfix.cpp zm_config.cpp zm_regexp.cpp zm_logger.cpp zm_utils.cpp zm_db.cpp zm.cpp) target_link_libraries(zmc zm ${ZM_EXTRA_LIBS} ${ZM_BIN_LIBS}) target_link_libraries(zma zm ${ZM_EXTRA_LIBS} ${ZM_BIN_LIBS}) @@ -25,9 +24,8 @@ target_link_libraries(zmf zm ${ZM_EXTRA_LIBS} ${ZM_BIN_LIBS}) target_link_libraries(zms zm ${ZM_EXTRA_LIBS} ${ZM_BIN_LIBS}) target_link_libraries(nph-zms zm ${ZM_EXTRA_LIBS} ${ZM_BIN_LIBS}) target_link_libraries(zmstreamer zm ${ZM_EXTRA_LIBS} ${ZM_BIN_LIBS}) -target_link_libraries(zmfix ${ZM_EXTRA_LIBS} ${ZM_BIN_LIBS}) -install(TARGETS zmc zma zmu zmf zmstreamer zmfix RUNTIME DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}" PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) +install(TARGETS zmc zma zmu zmf zmstreamer RUNTIME DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}" PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) install(TARGETS zms nph-zms RUNTIME DESTINATION "${ZM_CGIDIR}" PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) diff --git a/src/Makefile.am b/src/Makefile.am index 9f111bfe3..64c9163cb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -17,8 +17,7 @@ bin_PROGRAMS = \ zmu \ zms \ zmf \ - zmstreamer \ - zmfix + zmstreamer zm_SOURCES = \ zm_box.cpp \ @@ -36,6 +35,7 @@ zm_SOURCES = \ zm_ffmpeg_camera.cpp \ zm_image.cpp \ zm_jpeg.cpp \ + zm_libvlc_camera.cpp \ zm_local_camera.cpp \ zm_monitor.cpp \ zm_ffmpeg.cpp \ @@ -66,7 +66,6 @@ zms_SOURCES = zms.cpp $(zm_SOURCES) zmu_SOURCES = zmu.cpp $(zm_SOURCES) zmf_SOURCES = zmf.cpp $(zm_SOURCES) zmstreamer_SOURCES = zmstreamer.cpp $(zm_SOURCES) -zmfix_SOURCES = zmfix.cpp zm_config.cpp zm_regexp.cpp zm_logger.cpp zm_utils.cpp zm_db.cpp zm.cpp noinst_HEADERS = \ jinclude.h \ @@ -89,6 +88,7 @@ noinst_HEADERS = \ zm.h \ zm_image.h \ zm_jpeg.h \ + zm_libvlc_camera.h \ zm_local_camera.h \ zm_mem_utils.h \ zm_monitor.h \ @@ -126,7 +126,6 @@ dist-hook: install-exec-hook: ( cd $(DESTDIR)@bindir@; mkdir -p $(DESTDIR)$(cgidir); mv zms $(DESTDIR)$(cgidir) ) ( cd $(DESTDIR)$(cgidir); chown $(webuser):$(webgroup) zms; ln -f zms nph-zms ) - ( cd $(DESTDIR)@bindir@; chmod u+s zmfix ) uninstall-hook: ( cd $(DESTDIR)$(cgidir); rm -f zms nph-zms ) diff --git a/src/zm.h b/src/zm.h index 4a25936aa..9e4f47b5d 100644 --- a/src/zm.h +++ b/src/zm.h @@ -23,13 +23,6 @@ #include "zm_config.h" #include "zm_logger.h" -extern "C" -{ -#if !HAVE_DECL_ROUND -double round(double); -#endif -} - #include extern const char* self; diff --git a/src/zm_camera.h b/src/zm_camera.h index 48748b59e..d7af79b25 100644 --- a/src/zm_camera.h +++ b/src/zm_camera.h @@ -32,7 +32,7 @@ class Camera { protected: - typedef enum { LOCAL_SRC, REMOTE_SRC, FILE_SRC, FFMPEG_SRC, CURL_SRC } SourceType; + typedef enum { LOCAL_SRC, REMOTE_SRC, FILE_SRC, FFMPEG_SRC, LIBVLC_SRC, CURL_SRC } SourceType; int id; SourceType type; @@ -58,6 +58,7 @@ public: bool IsRemote() const { return( type == REMOTE_SRC ); } bool IsFile() const { return( type == FILE_SRC ); } bool IsFfmpeg() const { return( type == FFMPEG_SRC ); } + bool IsLibvlc() const { return( type == LIBVLC_SRC ); } unsigned int Width() const { return( width ); } unsigned int Height() const { return( height ); } unsigned int Colours() const { return( colours ); } diff --git a/src/zm_config_defines.h b/src/zm_config_defines.h index 572ee589f..4d3b9085a 100644 --- a/src/zm_config_defines.h +++ b/src/zm_config_defines.h @@ -30,196 +30,195 @@ #define ZM_CPU_EXTENSIONS 26 #define ZM_FAST_IMAGE_BLENDS 27 #define ZM_OPT_ADAPTIVE_SKIP 28 -#define ZM_BLEND_ALARMED_IMAGES 29 -#define ZM_MAX_SUSPEND_TIME 30 -#define ZM_OPT_REMOTE_CAMERAS 31 -#define ZM_NETCAM_REGEXPS 32 -#define ZM_HTTP_VERSION 33 -#define ZM_HTTP_UA 34 -#define ZM_HTTP_TIMEOUT 35 -#define ZM_MIN_RTP_PORT 36 -#define ZM_MAX_RTP_PORT 37 -#define ZM_OPT_FFMPEG 38 -#define ZM_PATH_FFMPEG 39 -#define ZM_FFMPEG_INPUT_OPTIONS 40 -#define ZM_FFMPEG_OUTPUT_OPTIONS 41 -#define ZM_FFMPEG_FORMATS 42 -#define ZM_LOG_LEVEL_SYSLOG 43 -#define ZM_LOG_LEVEL_FILE 44 -#define ZM_LOG_LEVEL_WEBLOG 45 -#define ZM_LOG_LEVEL_DATABASE 46 -#define ZM_LOG_DATABASE_LIMIT 47 -#define ZM_LOG_DEBUG 48 -#define ZM_LOG_DEBUG_TARGET 49 -#define ZM_LOG_DEBUG_LEVEL 50 -#define ZM_LOG_DEBUG_FILE 51 -#define ZM_LOG_CHECK_PERIOD 52 -#define ZM_LOG_ALERT_WAR_COUNT 53 -#define ZM_LOG_ALERT_ERR_COUNT 54 -#define ZM_LOG_ALERT_FAT_COUNT 55 -#define ZM_LOG_ALARM_WAR_COUNT 56 -#define ZM_LOG_ALARM_ERR_COUNT 57 -#define ZM_LOG_ALARM_FAT_COUNT 58 -#define ZM_RECORD_EVENT_STATS 59 -#define ZM_RECORD_DIAG_IMAGES 60 -#define ZM_DUMP_CORES 61 -#define ZM_PATH_MAP 62 -#define ZM_PATH_SOCKS 63 -#define ZM_PATH_LOGS 64 -#define ZM_PATH_SWAP 65 -#define ZM_WEB_TITLE_PREFIX 66 -#define ZM_WEB_RESIZE_CONSOLE 67 -#define ZM_WEB_POPUP_ON_ALARM 68 -#define ZM_OPT_X10 69 -#define ZM_X10_DEVICE 70 -#define ZM_X10_HOUSE_CODE 71 -#define ZM_X10_DB_RELOAD_INTERVAL 72 -#define ZM_WEB_SOUND_ON_ALARM 73 -#define ZM_WEB_ALARM_SOUND 74 -#define ZM_WEB_COMPACT_MONTAGE 75 -#define ZM_OPT_FAST_DELETE 76 -#define ZM_STRICT_VIDEO_CONFIG 77 -#define ZM_SIGNAL_CHECK_POINTS 78 -#define ZM_V4L_MULTI_BUFFER 79 -#define ZM_CAPTURES_PER_FRAME 80 -#define ZM_FILTER_RELOAD_DELAY 81 -#define ZM_FILTER_EXECUTE_INTERVAL 82 -#define ZM_OPT_UPLOAD 83 -#define ZM_UPLOAD_ARCH_FORMAT 84 -#define ZM_UPLOAD_ARCH_COMPRESS 85 -#define ZM_UPLOAD_ARCH_ANALYSE 86 -#define ZM_UPLOAD_PROTOCOL 87 -#define ZM_UPLOAD_FTP_HOST 88 -#define ZM_UPLOAD_HOST 89 -#define ZM_UPLOAD_PORT 90 -#define ZM_UPLOAD_FTP_USER 91 -#define ZM_UPLOAD_USER 92 -#define ZM_UPLOAD_FTP_PASS 93 -#define ZM_UPLOAD_PASS 94 -#define ZM_UPLOAD_FTP_LOC_DIR 95 -#define ZM_UPLOAD_LOC_DIR 96 -#define ZM_UPLOAD_FTP_REM_DIR 97 -#define ZM_UPLOAD_REM_DIR 98 -#define ZM_UPLOAD_FTP_TIMEOUT 99 -#define ZM_UPLOAD_TIMEOUT 100 -#define ZM_UPLOAD_FTP_PASSIVE 101 -#define ZM_UPLOAD_FTP_DEBUG 102 -#define ZM_UPLOAD_DEBUG 103 -#define ZM_OPT_EMAIL 104 -#define ZM_EMAIL_ADDRESS 105 -#define ZM_EMAIL_TEXT 106 -#define ZM_EMAIL_SUBJECT 107 -#define ZM_EMAIL_BODY 108 -#define ZM_OPT_MESSAGE 109 -#define ZM_MESSAGE_ADDRESS 110 -#define ZM_MESSAGE_TEXT 111 -#define ZM_MESSAGE_SUBJECT 112 -#define ZM_MESSAGE_BODY 113 -#define ZM_NEW_MAIL_MODULES 114 -#define ZM_EMAIL_HOST 115 -#define ZM_FROM_EMAIL 116 -#define ZM_URL 117 -#define ZM_MAX_RESTART_DELAY 118 -#define ZM_WATCH_CHECK_INTERVAL 119 -#define ZM_WATCH_MAX_DELAY 120 -#define ZM_RUN_AUDIT 121 -#define ZM_AUDIT_CHECK_INTERVAL 122 -#define ZM_FORCED_ALARM_SCORE 123 -#define ZM_BULK_FRAME_INTERVAL 124 -#define ZM_EVENT_CLOSE_MODE 125 -#define ZM_FORCE_CLOSE_EVENTS 126 -#define ZM_CREATE_ANALYSIS_IMAGES 127 -#define ZM_WEIGHTED_ALARM_CENTRES 128 -#define ZM_EVENT_IMAGE_DIGITS 129 -#define ZM_DEFAULT_ASPECT_RATIO 130 -#define ZM_USER_SELF_EDIT 131 -#define ZM_OPT_FRAME_SERVER 132 -#define ZM_FRAME_SOCKET_SIZE 133 -#define ZM_OPT_CONTROL 134 -#define ZM_OPT_TRIGGERS 135 -#define ZM_CHECK_FOR_UPDATES 136 -#define ZM_UPDATE_CHECK_PROXY 137 -#define ZM_SHM_KEY 138 -#define ZM_WEB_REFRESH_METHOD 139 -#define ZM_WEB_EVENT_SORT_FIELD 140 -#define ZM_WEB_EVENT_SORT_ORDER 141 -#define ZM_WEB_EVENTS_PER_PAGE 142 -#define ZM_WEB_LIST_THUMBS 143 -#define ZM_WEB_LIST_THUMB_WIDTH 144 -#define ZM_WEB_LIST_THUMB_HEIGHT 145 -#define ZM_WEB_USE_OBJECT_TAGS 146 -#define ZM_WEB_H_REFRESH_MAIN 147 -#define ZM_WEB_H_REFRESH_CYCLE 148 -#define ZM_WEB_H_REFRESH_IMAGE 149 -#define ZM_WEB_H_REFRESH_STATUS 150 -#define ZM_WEB_H_REFRESH_EVENTS 151 -#define ZM_WEB_H_CAN_STREAM 152 -#define ZM_WEB_H_STREAM_METHOD 153 -#define ZM_WEB_H_DEFAULT_SCALE 154 -#define ZM_WEB_H_DEFAULT_RATE 155 -#define ZM_WEB_H_VIDEO_BITRATE 156 -#define ZM_WEB_H_VIDEO_MAXFPS 157 -#define ZM_WEB_H_SCALE_THUMBS 158 -#define ZM_WEB_H_EVENTS_VIEW 159 -#define ZM_WEB_H_SHOW_PROGRESS 160 -#define ZM_WEB_H_AJAX_TIMEOUT 161 -#define ZM_WEB_M_REFRESH_MAIN 162 -#define ZM_WEB_M_REFRESH_CYCLE 163 -#define ZM_WEB_M_REFRESH_IMAGE 164 -#define ZM_WEB_M_REFRESH_STATUS 165 -#define ZM_WEB_M_REFRESH_EVENTS 166 -#define ZM_WEB_M_CAN_STREAM 167 -#define ZM_WEB_M_STREAM_METHOD 168 -#define ZM_WEB_M_DEFAULT_SCALE 169 -#define ZM_WEB_M_DEFAULT_RATE 170 -#define ZM_WEB_M_VIDEO_BITRATE 171 -#define ZM_WEB_M_VIDEO_MAXFPS 172 -#define ZM_WEB_M_SCALE_THUMBS 173 -#define ZM_WEB_M_EVENTS_VIEW 174 -#define ZM_WEB_M_SHOW_PROGRESS 175 -#define ZM_WEB_M_AJAX_TIMEOUT 176 -#define ZM_WEB_L_REFRESH_MAIN 177 -#define ZM_WEB_L_REFRESH_CYCLE 178 -#define ZM_WEB_L_REFRESH_IMAGE 179 -#define ZM_WEB_L_REFRESH_STATUS 180 -#define ZM_WEB_L_REFRESH_EVENTS 181 -#define ZM_WEB_L_CAN_STREAM 182 -#define ZM_WEB_L_STREAM_METHOD 183 -#define ZM_WEB_L_DEFAULT_SCALE 184 -#define ZM_WEB_L_DEFAULT_RATE 185 -#define ZM_WEB_L_VIDEO_BITRATE 186 -#define ZM_WEB_L_VIDEO_MAXFPS 187 -#define ZM_WEB_L_SCALE_THUMBS 188 -#define ZM_WEB_L_EVENTS_VIEW 189 -#define ZM_WEB_L_SHOW_PROGRESS 190 -#define ZM_WEB_L_AJAX_TIMEOUT 191 -#define ZM_WEB_P_CAN_STREAM 192 -#define ZM_WEB_P_STREAM_METHOD 193 -#define ZM_WEB_P_DEFAULT_SCALE 194 -#define ZM_WEB_P_DEFAULT_RATE 195 -#define ZM_WEB_P_VIDEO_BITRATE 196 -#define ZM_WEB_P_VIDEO_MAXFPS 197 -#define ZM_WEB_P_SCALE_THUMBS 198 -#define ZM_WEB_P_AJAX_TIMEOUT 199 -#define ZM_DYN_LAST_VERSION 200 -#define ZM_DYN_CURR_VERSION 201 -#define ZM_DYN_DB_VERSION 202 -#define ZM_DYN_LAST_CHECK 203 -#define ZM_DYN_NEXT_REMINDER 204 -#define ZM_DYN_DONATE_REMINDER_TIME 205 -#define ZM_DYN_SHOW_DONATE_REMINDER 206 -#define ZM_EYEZM_DEBUG 207 -#define ZM_EYEZM_LOG_TO_FILE 208 -#define ZM_EYEZM_LOG_FILE 209 -#define ZM_EYEZM_EVENT_VCODEC 210 -#define ZM_EYEZM_FEED_VCODEC 211 -#define ZM_EYEZM_H264_DEFAULT_BR 212 -#define ZM_EYEZM_H264_DEFAULT_EVBR 213 -#define ZM_EYEZM_H264_TIMEOUT 214 -#define ZM_EYEZM_SEG_DURATION 215 +#define ZM_MAX_SUSPEND_TIME 29 +#define ZM_OPT_REMOTE_CAMERAS 30 +#define ZM_NETCAM_REGEXPS 31 +#define ZM_HTTP_VERSION 32 +#define ZM_HTTP_UA 33 +#define ZM_HTTP_TIMEOUT 34 +#define ZM_MIN_RTP_PORT 35 +#define ZM_MAX_RTP_PORT 36 +#define ZM_OPT_FFMPEG 37 +#define ZM_PATH_FFMPEG 38 +#define ZM_FFMPEG_INPUT_OPTIONS 39 +#define ZM_FFMPEG_OUTPUT_OPTIONS 40 +#define ZM_FFMPEG_FORMATS 41 +#define ZM_LOG_LEVEL_SYSLOG 42 +#define ZM_LOG_LEVEL_FILE 43 +#define ZM_LOG_LEVEL_WEBLOG 44 +#define ZM_LOG_LEVEL_DATABASE 45 +#define ZM_LOG_DATABASE_LIMIT 46 +#define ZM_LOG_DEBUG 47 +#define ZM_LOG_DEBUG_TARGET 48 +#define ZM_LOG_DEBUG_LEVEL 49 +#define ZM_LOG_DEBUG_FILE 50 +#define ZM_LOG_CHECK_PERIOD 51 +#define ZM_LOG_ALERT_WAR_COUNT 52 +#define ZM_LOG_ALERT_ERR_COUNT 53 +#define ZM_LOG_ALERT_FAT_COUNT 54 +#define ZM_LOG_ALARM_WAR_COUNT 55 +#define ZM_LOG_ALARM_ERR_COUNT 56 +#define ZM_LOG_ALARM_FAT_COUNT 57 +#define ZM_RECORD_EVENT_STATS 58 +#define ZM_RECORD_DIAG_IMAGES 59 +#define ZM_DUMP_CORES 60 +#define ZM_PATH_MAP 61 +#define ZM_PATH_SOCKS 62 +#define ZM_PATH_LOGS 63 +#define ZM_PATH_SWAP 64 +#define ZM_WEB_TITLE_PREFIX 65 +#define ZM_WEB_RESIZE_CONSOLE 66 +#define ZM_WEB_POPUP_ON_ALARM 67 +#define ZM_OPT_X10 68 +#define ZM_X10_DEVICE 69 +#define ZM_X10_HOUSE_CODE 70 +#define ZM_X10_DB_RELOAD_INTERVAL 71 +#define ZM_WEB_SOUND_ON_ALARM 72 +#define ZM_WEB_ALARM_SOUND 73 +#define ZM_WEB_COMPACT_MONTAGE 74 +#define ZM_OPT_FAST_DELETE 75 +#define ZM_STRICT_VIDEO_CONFIG 76 +#define ZM_SIGNAL_CHECK_POINTS 77 +#define ZM_V4L_MULTI_BUFFER 78 +#define ZM_CAPTURES_PER_FRAME 79 +#define ZM_FILTER_RELOAD_DELAY 80 +#define ZM_FILTER_EXECUTE_INTERVAL 81 +#define ZM_OPT_UPLOAD 82 +#define ZM_UPLOAD_ARCH_FORMAT 83 +#define ZM_UPLOAD_ARCH_COMPRESS 84 +#define ZM_UPLOAD_ARCH_ANALYSE 85 +#define ZM_UPLOAD_PROTOCOL 86 +#define ZM_UPLOAD_FTP_HOST 87 +#define ZM_UPLOAD_HOST 88 +#define ZM_UPLOAD_PORT 89 +#define ZM_UPLOAD_FTP_USER 90 +#define ZM_UPLOAD_USER 91 +#define ZM_UPLOAD_FTP_PASS 92 +#define ZM_UPLOAD_PASS 93 +#define ZM_UPLOAD_FTP_LOC_DIR 94 +#define ZM_UPLOAD_LOC_DIR 95 +#define ZM_UPLOAD_FTP_REM_DIR 96 +#define ZM_UPLOAD_REM_DIR 97 +#define ZM_UPLOAD_FTP_TIMEOUT 98 +#define ZM_UPLOAD_TIMEOUT 99 +#define ZM_UPLOAD_FTP_PASSIVE 100 +#define ZM_UPLOAD_FTP_DEBUG 101 +#define ZM_UPLOAD_DEBUG 102 +#define ZM_OPT_EMAIL 103 +#define ZM_EMAIL_ADDRESS 104 +#define ZM_EMAIL_TEXT 105 +#define ZM_EMAIL_SUBJECT 106 +#define ZM_EMAIL_BODY 107 +#define ZM_OPT_MESSAGE 108 +#define ZM_MESSAGE_ADDRESS 109 +#define ZM_MESSAGE_TEXT 110 +#define ZM_MESSAGE_SUBJECT 111 +#define ZM_MESSAGE_BODY 112 +#define ZM_NEW_MAIL_MODULES 113 +#define ZM_EMAIL_HOST 114 +#define ZM_FROM_EMAIL 115 +#define ZM_URL 116 +#define ZM_MAX_RESTART_DELAY 117 +#define ZM_WATCH_CHECK_INTERVAL 118 +#define ZM_WATCH_MAX_DELAY 119 +#define ZM_RUN_AUDIT 120 +#define ZM_AUDIT_CHECK_INTERVAL 121 +#define ZM_FORCED_ALARM_SCORE 122 +#define ZM_BULK_FRAME_INTERVAL 123 +#define ZM_EVENT_CLOSE_MODE 124 +#define ZM_FORCE_CLOSE_EVENTS 125 +#define ZM_CREATE_ANALYSIS_IMAGES 126 +#define ZM_WEIGHTED_ALARM_CENTRES 127 +#define ZM_EVENT_IMAGE_DIGITS 128 +#define ZM_DEFAULT_ASPECT_RATIO 129 +#define ZM_USER_SELF_EDIT 130 +#define ZM_OPT_FRAME_SERVER 131 +#define ZM_FRAME_SOCKET_SIZE 132 +#define ZM_OPT_CONTROL 133 +#define ZM_OPT_TRIGGERS 134 +#define ZM_CHECK_FOR_UPDATES 135 +#define ZM_UPDATE_CHECK_PROXY 136 +#define ZM_SHM_KEY 137 +#define ZM_WEB_REFRESH_METHOD 138 +#define ZM_WEB_EVENT_SORT_FIELD 139 +#define ZM_WEB_EVENT_SORT_ORDER 140 +#define ZM_WEB_EVENTS_PER_PAGE 141 +#define ZM_WEB_LIST_THUMBS 142 +#define ZM_WEB_LIST_THUMB_WIDTH 143 +#define ZM_WEB_LIST_THUMB_HEIGHT 144 +#define ZM_WEB_USE_OBJECT_TAGS 145 +#define ZM_WEB_H_REFRESH_MAIN 146 +#define ZM_WEB_H_REFRESH_CYCLE 147 +#define ZM_WEB_H_REFRESH_IMAGE 148 +#define ZM_WEB_H_REFRESH_STATUS 149 +#define ZM_WEB_H_REFRESH_EVENTS 150 +#define ZM_WEB_H_CAN_STREAM 151 +#define ZM_WEB_H_STREAM_METHOD 152 +#define ZM_WEB_H_DEFAULT_SCALE 153 +#define ZM_WEB_H_DEFAULT_RATE 154 +#define ZM_WEB_H_VIDEO_BITRATE 155 +#define ZM_WEB_H_VIDEO_MAXFPS 156 +#define ZM_WEB_H_SCALE_THUMBS 157 +#define ZM_WEB_H_EVENTS_VIEW 158 +#define ZM_WEB_H_SHOW_PROGRESS 159 +#define ZM_WEB_H_AJAX_TIMEOUT 160 +#define ZM_WEB_M_REFRESH_MAIN 161 +#define ZM_WEB_M_REFRESH_CYCLE 162 +#define ZM_WEB_M_REFRESH_IMAGE 163 +#define ZM_WEB_M_REFRESH_STATUS 164 +#define ZM_WEB_M_REFRESH_EVENTS 165 +#define ZM_WEB_M_CAN_STREAM 166 +#define ZM_WEB_M_STREAM_METHOD 167 +#define ZM_WEB_M_DEFAULT_SCALE 168 +#define ZM_WEB_M_DEFAULT_RATE 169 +#define ZM_WEB_M_VIDEO_BITRATE 170 +#define ZM_WEB_M_VIDEO_MAXFPS 171 +#define ZM_WEB_M_SCALE_THUMBS 172 +#define ZM_WEB_M_EVENTS_VIEW 173 +#define ZM_WEB_M_SHOW_PROGRESS 174 +#define ZM_WEB_M_AJAX_TIMEOUT 175 +#define ZM_WEB_L_REFRESH_MAIN 176 +#define ZM_WEB_L_REFRESH_CYCLE 177 +#define ZM_WEB_L_REFRESH_IMAGE 178 +#define ZM_WEB_L_REFRESH_STATUS 179 +#define ZM_WEB_L_REFRESH_EVENTS 180 +#define ZM_WEB_L_CAN_STREAM 181 +#define ZM_WEB_L_STREAM_METHOD 182 +#define ZM_WEB_L_DEFAULT_SCALE 183 +#define ZM_WEB_L_DEFAULT_RATE 184 +#define ZM_WEB_L_VIDEO_BITRATE 185 +#define ZM_WEB_L_VIDEO_MAXFPS 186 +#define ZM_WEB_L_SCALE_THUMBS 187 +#define ZM_WEB_L_EVENTS_VIEW 188 +#define ZM_WEB_L_SHOW_PROGRESS 189 +#define ZM_WEB_L_AJAX_TIMEOUT 190 +#define ZM_WEB_P_CAN_STREAM 191 +#define ZM_WEB_P_STREAM_METHOD 192 +#define ZM_WEB_P_DEFAULT_SCALE 193 +#define ZM_WEB_P_DEFAULT_RATE 194 +#define ZM_WEB_P_VIDEO_BITRATE 195 +#define ZM_WEB_P_VIDEO_MAXFPS 196 +#define ZM_WEB_P_SCALE_THUMBS 197 +#define ZM_WEB_P_AJAX_TIMEOUT 198 +#define ZM_DYN_LAST_VERSION 199 +#define ZM_DYN_CURR_VERSION 200 +#define ZM_DYN_DB_VERSION 201 +#define ZM_DYN_LAST_CHECK 202 +#define ZM_DYN_NEXT_REMINDER 203 +#define ZM_DYN_DONATE_REMINDER_TIME 204 +#define ZM_DYN_SHOW_DONATE_REMINDER 205 +#define ZM_EYEZM_DEBUG 206 +#define ZM_EYEZM_LOG_TO_FILE 207 +#define ZM_EYEZM_LOG_FILE 208 +#define ZM_EYEZM_EVENT_VCODEC 209 +#define ZM_EYEZM_FEED_VCODEC 210 +#define ZM_EYEZM_H264_DEFAULT_BR 211 +#define ZM_EYEZM_H264_DEFAULT_EVBR 212 +#define ZM_EYEZM_H264_TIMEOUT 213 +#define ZM_EYEZM_SEG_DURATION 214 -#define ZM_MAX_CFG_ID 215 +#define ZM_MAX_CFG_ID 214 #define ZM_CFG_DECLARE_LIST \ const char *lang_default;\ @@ -251,7 +250,6 @@ bool cpu_extensions;\ bool fast_image_blends;\ bool opt_adaptive_skip;\ - bool blend_alarmed_images;\ int max_suspend_time;\ bool opt_remote_cameras;\ bool netcam_regexps;\ @@ -470,7 +468,6 @@ cpu_extensions = (bool)config.Item( ZM_CPU_EXTENSIONS );\ fast_image_blends = (bool)config.Item( ZM_FAST_IMAGE_BLENDS );\ opt_adaptive_skip = (bool)config.Item( ZM_OPT_ADAPTIVE_SKIP );\ - blend_alarmed_images = (bool)config.Item( ZM_BLEND_ALARMED_IMAGES );\ max_suspend_time = (int)config.Item( ZM_MAX_SUSPEND_TIME );\ opt_remote_cameras = (bool)config.Item( ZM_OPT_REMOTE_CAMERAS );\ netcam_regexps = (bool)config.Item( ZM_NETCAM_REGEXPS );\ diff --git a/src/zm_ffmpeg.cpp b/src/zm_ffmpeg.cpp index 577a188ca..2369cc745 100644 --- a/src/zm_ffmpeg.cpp +++ b/src/zm_ffmpeg.cpp @@ -17,8 +17,201 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#if HAVE_LIBAVCODEC - #include "zm_ffmpeg.h" +#include "zm_image.h" +#include "zm_rgb.h" -#endif // HAVE_LIBAVCODEC +#if HAVE_LIBAVCODEC || HAVE_LIBAVUTIL || HAVE_LIBSWSCALE + +#if HAVE_LIBAVUTIL +enum PixelFormat GetFFMPEGPixelFormat(unsigned int p_colours, unsigned p_subpixelorder) { + enum PixelFormat pf; + + Debug(8,"Colours: %d SubpixelOrder: %d",p_colours,p_subpixelorder); + + switch(p_colours) { + case ZM_COLOUR_RGB24: + { + if(p_subpixelorder == ZM_SUBPIX_ORDER_BGR) { + /* BGR subpixel order */ + pf = PIX_FMT_BGR24; + } else { + /* Assume RGB subpixel order */ + pf = PIX_FMT_RGB24; + } + break; + } + case ZM_COLOUR_RGB32: + { + if(p_subpixelorder == ZM_SUBPIX_ORDER_ARGB) { + /* ARGB subpixel order */ + pf = PIX_FMT_ARGB; + } else if(p_subpixelorder == ZM_SUBPIX_ORDER_ABGR) { + /* ABGR subpixel order */ + pf = PIX_FMT_ABGR; + } else if(p_subpixelorder == ZM_SUBPIX_ORDER_BGRA) { + /* BGRA subpixel order */ + pf = PIX_FMT_BGRA; + } else { + /* Assume RGBA subpixel order */ + pf = PIX_FMT_RGBA; + } + break; + } + case ZM_COLOUR_GRAY8: + pf = PIX_FMT_GRAY8; + break; + default: + Panic("Unexpected colours: %d",p_colours); + pf = PIX_FMT_GRAY8; /* Just to shush gcc variable may be unused warning */ + break; + } + + return pf; +} +#endif // HAVE_LIBAVUTIL + +#if HAVE_LIBSWSCALE && HAVE_LIBAVUTIL +SWScale::SWScale() : gotdefaults(false), swscale_ctx(NULL), input_avframe(NULL), output_avframe(NULL) { + Debug(4,"SWScale object created"); + + /* Allocate AVFrame for the input */ + input_avframe = avcodec_alloc_frame(); + if(input_avframe == NULL) { + Fatal("Failed allocating AVFrame for the input"); + } + + /* Allocate AVFrame for the output */ + output_avframe = avcodec_alloc_frame(); + if(output_avframe == NULL) { + Fatal("Failed allocating AVFrame for the output"); + } +} + +SWScale::~SWScale() { + + /* Free up everything */ + av_free(input_avframe); + input_avframe = NULL; + + av_free(output_avframe); + output_avframe = NULL; + + if(swscale_ctx) { + sws_freeContext(swscale_ctx); + swscale_ctx = NULL; + } + + Debug(4,"SWScale object destroyed"); +} + +int SWScale::SetDefaults(enum PixelFormat in_pf, enum PixelFormat out_pf, unsigned int width, unsigned int height) { + + /* Assign the defaults */ + default_input_pf = in_pf; + default_output_pf = out_pf; + default_width = width; + default_height = height; + + gotdefaults = true; + + return 0; +} + +int SWScale::Convert(const uint8_t* in_buffer, const size_t in_buffer_size, uint8_t* out_buffer, const size_t out_buffer_size, enum PixelFormat in_pf, enum PixelFormat out_pf, unsigned int width, unsigned int height) { + /* Parameter checking */ + if(in_buffer == NULL || out_buffer == NULL) { + Error("NULL Input or output buffer"); + return -1; + } + if(in_pf == 0 || out_pf == 0) { + Error("Invalid input or output pixel formats"); + return -2; + } + if(!width || !height) { + Error("Invalid width or height"); + return -3; + } + + /* Warn if the input or output pixelformat is not supported */ + if(!sws_isSupportedInput(in_pf)) { + Warning("swscale does not support the input format: %c%c%c%c",(in_pf)&0xff,((in_pf)&0xff),((in_pf>>16)&0xff),((in_pf>>24)&0xff)); + } + if(!sws_isSupportedOutput(out_pf)) { + Warning("swscale does not support the output format: %c%c%c%c",(out_pf)&0xff,((out_pf>>8)&0xff),((out_pf>>16)&0xff),((out_pf>>24)&0xff)); + } + + /* Check the buffer sizes */ + size_t insize = avpicture_get_size(in_pf, width, height); + if(insize != in_buffer_size) { + Error("The input buffer size does not match the expected size for the input format. Required: %d Available: %d", insize, in_buffer_size); + return -4; + } + size_t outsize = avpicture_get_size(out_pf, width, height); + if(outsize < out_buffer_size) { + Error("The output buffer is undersized for the output format. Required: %d Available: %d", outsize, out_buffer_size); + return -5; + } + + /* Get the context */ + swscale_ctx = sws_getCachedContext( NULL, width, height, in_pf, width, height, out_pf, 0, NULL, NULL, NULL ); + if(swscale_ctx == NULL) { + Error("Failed getting swscale context"); + return -6; + } + + /* Fill in the buffers */ + if(!avpicture_fill( (AVPicture*)input_avframe, (uint8_t*)in_buffer, in_pf, width, height ) ) { + Error("Failed filling input frame with input buffer"); + return -7; + } + if(!avpicture_fill( (AVPicture*)output_avframe, out_buffer, out_pf, width, height ) ) { + Error("Failed filling output frame with output buffer"); + return -8; + } + + /* Do the conversion */ + if(!sws_scale(swscale_ctx, input_avframe->data, input_avframe->linesize, 0, height, output_avframe->data, output_avframe->linesize ) ) { + Error("swscale conversion failed"); + return -10; + } + + return 0; +} + +int SWScale::Convert(const Image* img, uint8_t* out_buffer, const size_t out_buffer_size, enum PixelFormat in_pf, enum PixelFormat out_pf, unsigned int width, unsigned int height) { + if(img->Width() != width) { + Error("Source image width differs. Source: %d Output: %d",img->Width(), width); + return -12; + } + + if(img->Height() != height) { + Error("Source image height differs. Source: %d Output: %d",img->Height(), height); + return -13; + } + + return Convert(img->Buffer(),img->Size(),out_buffer,out_buffer_size,in_pf,out_pf,width,height); +} + +int SWScale::ConvertDefaults(const Image* img, uint8_t* out_buffer, const size_t out_buffer_size) { + + if(!gotdefaults) { + Error("Defaults are not set"); + return -24; + } + + return Convert(img,out_buffer,out_buffer_size,default_input_pf,default_output_pf,default_width,default_height); +} + +int SWScale::ConvertDefaults(const uint8_t* in_buffer, const size_t in_buffer_size, uint8_t* out_buffer, const size_t out_buffer_size) { + + if(!gotdefaults) { + Error("Defaults are not set"); + return -24; + } + + return Convert(in_buffer,in_buffer_size,out_buffer,out_buffer_size,default_input_pf,default_output_pf,default_width,default_height); +} +#endif // HAVE_LIBSWSCALE && HAVE_LIBAVUTIL + +#endif // HAVE_LIBAVCODEC || HAVE_LIBAVUTIL || HAVE_LIBSWSCALE diff --git a/src/zm_ffmpeg.h b/src/zm_ffmpeg.h index 5fd3fe5b6..0a4837d67 100644 --- a/src/zm_ffmpeg.h +++ b/src/zm_ffmpeg.h @@ -20,6 +20,8 @@ #ifndef ZM_FFMPEG_H #define ZM_FFMPEG_H #include +#include "zm.h" +#include "zm_image.h" #ifdef __cplusplus extern "C" { @@ -94,7 +96,38 @@ extern "C" { #ifndef SWS_CPU_CAPS_SSE2 #define SWS_CPU_CAPS_SSE2 0x02000000 #endif - + + +#if HAVE_LIBAVUTIL +enum PixelFormat GetFFMPEGPixelFormat(unsigned int p_colours, unsigned p_subpixelorder); +#endif // HAVE_LIBAVUTIL + + +/* SWScale wrapper class to make our life easier and reduce code reuse */ +#if HAVE_LIBSWSCALE && HAVE_LIBAVUTIL +class SWScale { +public: + SWScale(); + ~SWScale(); + int SetDefaults(enum PixelFormat in_pf, enum PixelFormat out_pf, unsigned int width, unsigned int height); + int ConvertDefaults(const Image* img, uint8_t* out_buffer, const size_t out_buffer_size); + int ConvertDefaults(const uint8_t* in_buffer, const size_t in_buffer_size, uint8_t* out_buffer, const size_t out_buffer_size); + int Convert(const Image* img, uint8_t* out_buffer, const size_t out_buffer_size, enum PixelFormat in_pf, enum PixelFormat out_pf, unsigned int width, unsigned int height); + int Convert(const uint8_t* in_buffer, const size_t in_buffer_size, uint8_t* out_buffer, const size_t out_buffer_size, enum PixelFormat in_pf, enum PixelFormat out_pf, unsigned int width, unsigned int height); + +protected: + bool gotdefaults; + struct SwsContext* swscale_ctx; + AVFrame* input_avframe; + AVFrame* output_avframe; + enum PixelFormat default_input_pf; + enum PixelFormat default_output_pf; + unsigned int default_width; + unsigned int default_height; +}; +#endif // HAVE_LIBSWSCALE && HAVE_LIBAVUTIL + + #endif // ( HAVE_LIBAVUTIL_AVUTIL_H || HAVE_LIBAVCODEC_AVCODEC_H || HAVE_LIBAVFORMAT_AVFORMAT_H || HAVE_LIBAVDEVICE_AVDEVICE_H ) #endif // ZM_FFMPEG_H diff --git a/src/zm_image.cpp b/src/zm_image.cpp index 18b93c57b..f60d6e9d0 100644 --- a/src/zm_image.cpp +++ b/src/zm_image.cpp @@ -3000,23 +3000,23 @@ __attribute__((noinline,__target__("sse2"))) void sse2_fastblend(const uint8_t* // 1.5625% blending divider = 6; clearmask = 0x03030303; - } else if(blendpercent >= 2.34375 && blendpercent < 4.6875) { + } else if(blendpercent < 4.6875) { // 3.125% blending divider = 5; clearmask = 0x07070707; - } else if(blendpercent >= 4.6875 && blendpercent < 9.375) { + } else if(blendpercent < 9.375) { // 6.25% blending divider = 4; clearmask = 0x0F0F0F0F; - } else if(blendpercent >= 9.375 && blendpercent < 18.75) { + } else if(blendpercent < 18.75) { // 12.5% blending divider = 3; clearmask = 0x1F1F1F1F; - } else if(blendpercent >= 18.75 && blendpercent < 37.5) { + } else if(blendpercent < 37.5) { // 25% blending divider = 2; clearmask = 0x3F3F3F3F; - } else if(blendpercent >= 37.5) { + } else { // 50% blending divider = 1; clearmask = 0x7F7F7F7F; @@ -3063,19 +3063,19 @@ __attribute__((noinline)) void std_fastblend(const uint8_t* col1, const uint8_t* if(blendpercent < 2.34375) { // 1.5625% blending divider = 6; - } else if(blendpercent >= 2.34375 && blendpercent < 4.6875) { + } else if(blendpercent < 4.6875) { // 3.125% blending divider = 5; - } else if(blendpercent >= 4.6875 && blendpercent < 9.375) { + } else if(blendpercent < 9.375) { // 6.25% blending divider = 4; - } else if(blendpercent >= 9.375 && blendpercent < 18.75) { + } else if(blendpercent < 18.75) { // 12.5% blending divider = 3; - } else if(blendpercent >= 18.75 && blendpercent < 37.5) { + } else if(blendpercent < 37.5) { // 25% blending divider = 2; - } else if(blendpercent >= 37.5) { + } else { // 50% blending divider = 1; } diff --git a/src/zm_libvlc_camera.cpp b/src/zm_libvlc_camera.cpp new file mode 100644 index 000000000..8c56a5346 --- /dev/null +++ b/src/zm_libvlc_camera.cpp @@ -0,0 +1,192 @@ +/* + * ZoneMinder Libvlc 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "zm.h" +#include "zm_libvlc_camera.h" + +#if HAVE_LIBVLC + +// Do all the buffer checking work here to avoid unnecessary locking +void* LibvlcLockBuffer(void* opaque, void** planes) +{ + LibvlcPrivateData* data = (LibvlcPrivateData*)opaque; + data->mutex.lock(); + + uint8_t* buffer = data->buffer; + data->buffer = data->prevBuffer; + data->prevBuffer = buffer; + + *planes = data->buffer; + return NULL; +} + +void LibvlcUnlockBuffer(void* opaque, void* picture, void *const *planes) +{ + LibvlcPrivateData* data = (LibvlcPrivateData*)opaque; + + bool newFrame = false; + for(uint32_t i = 0; i < data->bufferSize; i++) + { + if(data->buffer[i] != data->prevBuffer[i]) + { + newFrame = true; + break; + } + } + data->mutex.unlock(); + + time_t now; + time(&now); + // Return frames slightly faster than 1fps (if time() supports greater than one second resolution) + if(newFrame || difftime(now, data->prevTime) >= 0.8) + { + data->prevTime = now; + data->newImage.updateValueSignal(true); + } +} + +LibvlcCamera::LibvlcCamera( int p_id, const std::string &p_path, int p_width, int p_height, int p_colours, int p_brightness, int p_contrast, int p_hue, int p_colour, bool p_capture ) : + Camera( p_id, LIBVLC_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 ), + mPath( p_path ) +{ + mLibvlcInstance = NULL; + mLibvlcMedia = NULL; + mLibvlcMediaPlayer = NULL; + mLibvlcData.buffer = NULL; + mLibvlcData.prevBuffer = NULL; + + /* Has to be located inside the constructor so other components such as zma will receive correct colours and subpixel order */ + if(colours == ZM_COLOUR_RGB32) { + subpixelorder = ZM_SUBPIX_ORDER_BGRA; + mTargetChroma = "RV32"; + mBpp = 4; + } else if(colours == ZM_COLOUR_RGB24) { + subpixelorder = ZM_SUBPIX_ORDER_BGR; + mTargetChroma = "RV24"; + mBpp = 3; + } else if(colours == ZM_COLOUR_GRAY8) { + subpixelorder = ZM_SUBPIX_ORDER_NONE; + mTargetChroma = "GREY"; + mBpp = 1; + } else { + Panic("Unexpected colours: %d",colours); + } + + if ( capture ) + { + Initialise(); + } +} + +LibvlcCamera::~LibvlcCamera() +{ + if ( capture ) + { + Terminate(); + } + if(mLibvlcMediaPlayer != NULL) + { + libvlc_media_player_release(mLibvlcMediaPlayer); + mLibvlcMediaPlayer = NULL; + } + if(mLibvlcMedia != NULL) + { + libvlc_media_release(mLibvlcMedia); + mLibvlcMedia = NULL; + } + if(mLibvlcInstance != NULL) + { + libvlc_release(mLibvlcInstance); + mLibvlcInstance = NULL; + } +} + +void LibvlcCamera::Initialise() +{ +} + +void LibvlcCamera::Terminate() +{ + libvlc_media_player_stop(mLibvlcMediaPlayer); + if(mLibvlcData.buffer != NULL) + { + zm_freealigned(mLibvlcData.buffer); + } + if(mLibvlcData.prevBuffer != NULL) + { + zm_freealigned(mLibvlcData.prevBuffer); + } +} + +int LibvlcCamera::PrimeCapture() +{ + Info("Priming capture from %s", mPath.c_str()); + + mLibvlcInstance = libvlc_new (0, NULL); + if(mLibvlcInstance == NULL) + Fatal("Unable to create libvlc instance due to: %s", libvlc_errmsg()); + + mLibvlcMedia = libvlc_media_new_location(mLibvlcInstance, mPath.c_str()); + if(mLibvlcMedia == NULL) + Fatal("Unable to open input %s due to: %s", mPath.c_str(), libvlc_errmsg()); + + mLibvlcMediaPlayer = libvlc_media_player_new_from_media(mLibvlcMedia); + if(mLibvlcMediaPlayer == NULL) + Fatal("Unable to create player for %s due to: %s", mPath.c_str(), libvlc_errmsg()); + + libvlc_video_set_format(mLibvlcMediaPlayer, mTargetChroma.c_str(), width, height, width * mBpp); + libvlc_video_set_callbacks(mLibvlcMediaPlayer, &LibvlcLockBuffer, &LibvlcUnlockBuffer, NULL, &mLibvlcData); + + mLibvlcData.bufferSize = width * height * mBpp; + // Libvlc wants 32 byte alignment for images (should in theory do this for all image lines) + mLibvlcData.buffer = (uint8_t*)zm_mallocaligned(32, mLibvlcData.bufferSize); + mLibvlcData.prevBuffer = (uint8_t*)zm_mallocaligned(32, mLibvlcData.bufferSize); + + mLibvlcData.newImage.setValueImmediate(false); + + libvlc_media_player_play(mLibvlcMediaPlayer); + + return(0); +} + +int LibvlcCamera::PreCapture() +{ + return(0); +} + +// Should not return -1 as cancels capture. Always wait for image if available. +int LibvlcCamera::Capture( Image &image ) +{ + while(!mLibvlcData.newImage.getValueImmediate()) + mLibvlcData.newImage.getUpdatedValue(1); + + mLibvlcData.mutex.lock(); + image.Assign(width, height, colours, subpixelorder, mLibvlcData.buffer, width * height * mBpp); + mLibvlcData.newImage.setValueImmediate(false); + mLibvlcData.mutex.unlock(); + + return (0); +} + +int LibvlcCamera::PostCapture() +{ + return(0); +} + +#endif // HAVE_LIBVLC diff --git a/src/zm_libvlc_camera.h b/src/zm_libvlc_camera.h new file mode 100644 index 000000000..0e5d94821 --- /dev/null +++ b/src/zm_libvlc_camera.h @@ -0,0 +1,73 @@ +/* + * ZoneMinder Libvlc Camera Class Interface, $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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef ZM_LIBVLC_CAMERA_H +#define ZM_LIBVLC_CAMERA_H + +#include "zm_buffer.h" +#include "zm_camera.h" +#include "zm_thread.h" + +#if HAVE_LIBVLC + +#if HAVE_VLC_VLC_H +#include "vlc/vlc.h" +#endif + +// Used by libvlc callbacks +struct LibvlcPrivateData +{ + uint8_t* buffer; + uint8_t* prevBuffer; + time_t prevTime; + uint32_t bufferSize; + Mutex mutex; + ThreadData newImage; +}; + +class LibvlcCamera : public Camera +{ +protected: + std::string mPath; + + LibvlcPrivateData mLibvlcData; + std::string mTargetChroma; + uint8_t mBpp; + + libvlc_instance_t *mLibvlcInstance; + libvlc_media_t *mLibvlcMedia; + libvlc_media_player_t *mLibvlcMediaPlayer; + +public: + LibvlcCamera( int p_id, const std::string &path, int p_width, int p_height, int p_colours, int p_brightness, int p_contrast, int p_hue, int p_colour, bool p_capture ); + ~LibvlcCamera(); + + const std::string &Path() const { return( mPath ); } + + void Initialise(); + void Terminate(); + + int PrimeCapture(); + int PreCapture(); + int Capture( Image &image ); + int PostCapture(); +}; + +#endif // HAVE_LIBVLC +#endif // ZM_LIBVLC_CAMERA_H diff --git a/src/zm_local_camera.cpp b/src/zm_local_camera.cpp index 110db6828..1d5eb195b 100644 --- a/src/zm_local_camera.cpp +++ b/src/zm_local_camera.cpp @@ -104,9 +104,11 @@ static PixelFormat getFfPixFormatFromV4lPalette( int v4l_version, int palette ) case V4L2_PIX_FMT_MJPEG : pixFormat = PIX_FMT_YUVJ444P; break; + case V4L2_PIX_FMT_UYVY : + pixFormat = PIX_FMT_UYVY422; + break; // These don't seem to have ffmpeg equivalents // See if you can match any of the ones in the default clause below!? - case V4L2_PIX_FMT_UYVY : case V4L2_PIX_FMT_RGB332 : case V4L2_PIX_FMT_RGB555X : case V4L2_PIX_FMT_RGB565X : diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index 6bf8180aa..02bc2b8cd 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -40,6 +40,9 @@ #if HAVE_LIBAVFORMAT #include "zm_ffmpeg_camera.h" #endif // HAVE_LIBAVFORMAT +#if HAVE_LIBVLC +#include "zm_libvlc_camera.h" +#endif // HAVE_LIBVLC #if HAVE_LIBCURL #include "zm_curl_camera.h" #endif // HAVE_LIBCURL @@ -292,6 +295,7 @@ Monitor::Monitor( int p_alarm_capture_delay, int p_fps_report_interval, int p_ref_blend_perc, + int p_alarm_ref_blend_perc, bool p_track_motion, Rgb p_signal_check_colour, Purpose p_purpose, @@ -317,6 +321,7 @@ Monitor::Monitor( alarm_frame_count( p_alarm_frame_count ), fps_report_interval( p_fps_report_interval ), ref_blend_perc( p_ref_blend_perc ), + alarm_ref_blend_perc( p_alarm_ref_blend_perc ), track_motion( p_track_motion ), signal_check_colour( p_signal_check_colour ), delta_image( width, height, ZM_COLOUR_GRAY8, ZM_SUBPIX_ORDER_NONE ), @@ -512,7 +517,7 @@ Monitor::Monitor( Debug( 1, "Monitor %s has function %d", name, function ); Debug( 1, "Monitor %s LBF = '%s', LBX = %d, LBY = %d", name, label_format, label_coord.X(), label_coord.Y() ); - Debug( 1, "Monitor %s IBC = %d, WUC = %d, pEC = %d, PEC = %d, EAF = %d, FRI = %d, RBP = %d, FM = %d", name, image_buffer_count, warmup_count, pre_event_count, post_event_count, alarm_frame_count, fps_report_interval, ref_blend_perc, track_motion ); + Debug( 1, "Monitor %s IBC = %d, WUC = %d, pEC = %d, PEC = %d, EAF = %d, FRI = %d, RBP = %d, ARBP = %d, FM = %d", name, image_buffer_count, warmup_count, pre_event_count, post_event_count, alarm_frame_count, fps_report_interval, ref_blend_perc, alarm_ref_blend_perc, track_motion ); if ( purpose == ANALYSIS ) { @@ -1608,9 +1613,13 @@ bool Monitor::Analyse() shared_data->state = state = IDLE; last_section_mod = 0; } - if ( (!signal_change && signal) && (function == MODECT || function == MOCORD) && (config.blend_alarmed_images || state != ALARM) ) + if ( (!signal_change && signal) && (function == MODECT || function == MOCORD) ) { - ref_image.Blend( *snap_image, ref_blend_perc ); + if ( state == ALARM ) { + ref_image.Blend( *snap_image, alarm_ref_blend_perc ); + } else { + ref_image.Blend( *snap_image, ref_blend_perc ); + } } last_signal = signal; } @@ -1633,7 +1642,7 @@ void Monitor::Reload() closeEvent(); static char sql[ZM_SQL_MED_BUFSIZ]; - snprintf( sql, sizeof(sql), "select Function+0, Enabled, LinkedMonitors, EventPrefix, LabelFormat, LabelX, LabelY, WarmupCount, PreEventCount, PostEventCount, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, TrackMotion, SignalCheckColour from Monitors where Id = '%d'", id ); + snprintf( sql, sizeof(sql), "select Function+0, Enabled, LinkedMonitors, EventPrefix, LabelFormat, LabelX, LabelY, WarmupCount, PreEventCount, PostEventCount, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour from Monitors where Id = '%d'", id ); if ( mysql_query( &dbconn, sql ) ) { @@ -1673,6 +1682,7 @@ void Monitor::Reload() alarm_capture_delay = (dbrow[index]&&atof(dbrow[index])>0.0)?int(DT_PREC_3/atof(dbrow[index])):0; index++; fps_report_interval = atoi(dbrow[index++]); ref_blend_perc = atoi(dbrow[index++]); + alarm_ref_blend_perc = atoi(dbrow[index++]); track_motion = atoi(dbrow[index++]); @@ -1823,11 +1833,11 @@ int Monitor::LoadLocalMonitors( const char *device, Monitor **&monitors, Purpose static char sql[ZM_SQL_MED_BUFSIZ]; if ( !device[0] ) { - strncpy( sql, "select Id, Name, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, Method, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, TrackMotion, SignalCheckColour from Monitors where Function != 'None' and Type = 'Local' order by Device, Channel", sizeof(sql) ); + strncpy( sql, "select Id, Name, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, Method, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour from Monitors where Function != 'None' and Type = 'Local' order by Device, Channel", sizeof(sql) ); } else { - snprintf( sql, sizeof(sql), "select Id, Name, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, Method, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, TrackMotion, SignalCheckColour from Monitors where Function != 'None' and Type = 'Local' and Device = '%s' order by Channel", device ); + snprintf( sql, sizeof(sql), "select Id, Name, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, Method, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour from Monitors where Function != 'None' and Type = 'Local' and Device = '%s' order by Channel", device ); } if ( mysql_query( &dbconn, sql ) ) { @@ -1889,6 +1899,7 @@ int Monitor::LoadLocalMonitors( const char *device, Monitor **&monitors, Purpose int alarm_capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++; int fps_report_interval = atoi(dbrow[col]); col++; int ref_blend_perc = atoi(dbrow[col]); col++; + int alarm_ref_blend_perc = atoi(dbrow[col]); col++; int track_motion = atoi(dbrow[col]); col++; int signal_check_colour; @@ -1945,6 +1956,7 @@ int Monitor::LoadLocalMonitors( const char *device, Monitor **&monitors, Purpose alarm_capture_delay, fps_report_interval, ref_blend_perc, + alarm_ref_blend_perc, track_motion, signal_check_colour, purpose, @@ -1973,11 +1985,11 @@ int Monitor::LoadRemoteMonitors( const char *protocol, const char *host, const c static char sql[ZM_SQL_MED_BUFSIZ]; if ( !protocol ) { - strncpy( sql, "select Id, Name, Function+0, Enabled, LinkedMonitors, Protocol, Method, Host, Port, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, TrackMotion from Monitors where Function != 'None' and Type = 'Remote'", sizeof(sql) ); + strncpy( sql, "select Id, Name, Function+0, Enabled, LinkedMonitors, Protocol, Method, Host, Port, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion from Monitors where Function != 'None' and Type = 'Remote'", sizeof(sql) ); } else { - snprintf( sql, sizeof(sql), "select Id, Name, Function+0, Enabled, LinkedMonitors, Protocol, Method, Host, Port, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, TrackMotion from Monitors where Function != 'None' and Type = 'Remote' and Protocol = '%s' and Host = '%s' and Port = '%s' and Path = '%s'", protocol, host, port, path ); + snprintf( sql, sizeof(sql), "select Id, Name, Function+0, Enabled, LinkedMonitors, Protocol, Method, Host, Port, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion from Monitors where Function != 'None' and Type = 'Remote' and Protocol = '%s' and Host = '%s' and Port = '%s' and Path = '%s'", protocol, host, port, path ); } if ( mysql_query( &dbconn, sql ) ) { @@ -2040,6 +2052,7 @@ int Monitor::LoadRemoteMonitors( const char *protocol, const char *host, const c int alarm_capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++; int fps_report_interval = atoi(dbrow[col]); col++; int ref_blend_perc = atoi(dbrow[col]); col++; + int alarm_ref_blend_perc = atoi(dbrow[col]); col++; int track_motion = atoi(dbrow[col]); col++; @@ -2114,6 +2127,7 @@ int Monitor::LoadRemoteMonitors( const char *protocol, const char *host, const c alarm_capture_delay, fps_report_interval, ref_blend_perc, + alarm_ref_blend_perc, track_motion, RGB_WHITE, purpose, @@ -2142,11 +2156,11 @@ int Monitor::LoadFileMonitors( const char *file, Monitor **&monitors, Purpose pu static char sql[ZM_SQL_MED_BUFSIZ]; if ( !file[0] ) { - strncpy( sql, "select Id, Name, Function+0, Enabled, LinkedMonitors, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, TrackMotion from Monitors where Function != 'None' and Type = 'File'", sizeof(sql) ); + strncpy( sql, "select Id, Name, Function+0, Enabled, LinkedMonitors, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion from Monitors where Function != 'None' and Type = 'File'", sizeof(sql) ); } else { - snprintf( sql, sizeof(sql), "select Id, Name, Function+0, Enabled, LinkedMonitors, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, TrackMotion from Monitors where Function != 'None' and Type = 'File' and Path = '%s'", file ); + snprintf( sql, sizeof(sql), "select Id, Name, Function+0, Enabled, LinkedMonitors, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion from Monitors where Function != 'None' and Type = 'File' and Path = '%s'", file ); } if ( mysql_query( &dbconn, sql ) ) { @@ -2205,6 +2219,7 @@ int Monitor::LoadFileMonitors( const char *file, Monitor **&monitors, Purpose pu int alarm_capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++; int fps_report_interval = atoi(dbrow[col]); col++; int ref_blend_perc = atoi(dbrow[col]); col++; + int alarm_ref_blend_perc = atoi(dbrow[col]); col++; int track_motion = atoi(dbrow[col]); col++; int cam_width = ((orientation==ROTATE_90||orientation==ROTATE_270)?height:width); @@ -2247,6 +2262,7 @@ int Monitor::LoadFileMonitors( const char *file, Monitor **&monitors, Purpose pu alarm_capture_delay, fps_report_interval, ref_blend_perc, + alarm_ref_blend_perc, track_motion, RGB_WHITE, purpose, @@ -2276,11 +2292,11 @@ int Monitor::LoadFfmpegMonitors( const char *file, Monitor **&monitors, Purpose static char sql[ZM_SQL_MED_BUFSIZ]; if ( !file[0] ) { - strncpy( sql, "select Id, Name, Function+0, Enabled, LinkedMonitors, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, TrackMotion from Monitors where Function != 'None' and Type = 'Ffmpeg'", sizeof(sql) ); + strncpy( sql, "select Id, Name, Function+0, Enabled, LinkedMonitors, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion from Monitors where Function != 'None' and Type = 'Ffmpeg'", sizeof(sql) ); } else { - snprintf( sql, sizeof(sql), "select Id, Name, Function+0, Enabled, LinkedMonitors, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, TrackMotion from Monitors where Function != 'None' and Type = 'Ffmpeg' and Path = '%s'", file ); + snprintf( sql, sizeof(sql), "select Id, Name, Function+0, Enabled, LinkedMonitors, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion from Monitors where Function != 'None' and Type = 'Ffmpeg' and Path = '%s'", file ); } if ( mysql_query( &dbconn, sql ) ) { @@ -2339,6 +2355,7 @@ int Monitor::LoadFfmpegMonitors( const char *file, Monitor **&monitors, Purpose int alarm_capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++; int fps_report_interval = atoi(dbrow[col]); col++; int ref_blend_perc = atoi(dbrow[col]); col++; + int alarm_ref_blend_perc = atoi(dbrow[col]); col++; int track_motion = atoi(dbrow[col]); col++; int cam_width = ((orientation==ROTATE_90||orientation==ROTATE_270)?height:width); @@ -2381,6 +2398,7 @@ int Monitor::LoadFfmpegMonitors( const char *file, Monitor **&monitors, Purpose alarm_capture_delay, fps_report_interval, ref_blend_perc, + alarm_ref_blend_perc, track_motion, RGB_WHITE, purpose, @@ -2407,7 +2425,7 @@ int Monitor::LoadFfmpegMonitors( const char *file, Monitor **&monitors, Purpose Monitor *Monitor::Load( int id, bool load_zones, Purpose purpose ) { static char sql[ZM_SQL_MED_BUFSIZ]; - snprintf( sql, sizeof(sql), "select Id, Name, Type, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, Protocol, Method, Host, Port, Path, User, Pass, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, TrackMotion, SignalCheckColour from Monitors where Id = %d", id ); + snprintf( sql, sizeof(sql), "select Id, Name, Type, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, Protocol, Method, Host, Port, Path, User, Pass, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour from Monitors where Id = %d", id ); if ( mysql_query( &dbconn, sql ) ) { Error( "Can't run query: %s", mysql_error( &dbconn ) ); @@ -2475,6 +2493,7 @@ Monitor *Monitor::Load( int id, bool load_zones, Purpose purpose ) int alarm_capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++; int fps_report_interval = atoi(dbrow[col]); col++; int ref_blend_perc = atoi(dbrow[col]); col++; + int alarm_ref_blend_perc = atoi(dbrow[col]); col++; int track_motion = atoi(dbrow[col]); col++; int signal_check_colour; @@ -2593,6 +2612,25 @@ Monitor *Monitor::Load( int id, bool load_zones, Purpose purpose ) #else // HAVE_LIBAVFORMAT Fatal( "You must have ffmpeg libraries installed to use ffmpeg cameras for monitor %d", id ); #endif // HAVE_LIBAVFORMAT + } + else if (type == "Libvlc") + { +#if HAVE_LIBVLC + camera = new LibvlcCamera( + id, + path.c_str(), + cam_width, + cam_height, + colours, + brightness, + contrast, + hue, + colour, + purpose==CAPTURE + ); +#else // HAVE_LIBVLC + Fatal( "You must have vlc libraries installed to use vlc cameras for monitor %d", id ); +#endif // HAVE_LIBVLC } else if ( type == "cURL" ) { @@ -2643,6 +2681,7 @@ Monitor *Monitor::Load( int id, bool load_zones, Purpose purpose ) alarm_capture_delay, fps_report_interval, ref_blend_perc, + alarm_ref_blend_perc, track_motion, signal_check_colour, purpose, @@ -3280,6 +3319,7 @@ bool Monitor::DumpSettings( char *output, bool verbose ) sprintf( output+strlen(output), "Maximum FPS : %.2f\n", capture_delay?DT_PREC_3/capture_delay:0.0 ); sprintf( output+strlen(output), "Alarm Maximum FPS : %.2f\n", alarm_capture_delay?DT_PREC_3/alarm_capture_delay:0.0 ); sprintf( output+strlen(output), "Reference Blend %%ge : %d\n", ref_blend_perc ); + sprintf( output+strlen(output), "Alarm Reference Blend %%ge : %d\n", alarm_ref_blend_perc ); sprintf( output+strlen(output), "Track Motion : %d\n", track_motion ); sprintf( output+strlen(output), "Function: %d - %s\n", function, function==NONE?"None":( diff --git a/src/zm_monitor.h b/src/zm_monitor.h index 496ce96b1..c8aea5a07 100644 --- a/src/zm_monitor.h +++ b/src/zm_monitor.h @@ -235,6 +235,7 @@ protected: int alarm_frame_count; // How many alarm frames are required before an event is triggered int fps_report_interval; // How many images should be captured/processed between reporting the current FPS int ref_blend_perc; // Percentage of new image going into reference image. + int alarm_ref_blend_perc; // Percentage of new image going into reference image during alarm. bool track_motion; // Whether this monitor tries to track detected motion Rgb signal_check_colour; // The colour that the camera will emit when no video signal detected @@ -287,7 +288,7 @@ protected: public: // OurCheckAlarms seems to be unused. Check it on zm_monitor.cpp for more info. //bool OurCheckAlarms( Zone *zone, const Image *pImage ); - Monitor( int p_id, const char *p_name, int p_function, bool p_enabled, const char *p_linked_monitors, Camera *p_camera, int p_orientation, unsigned int p_deinterlacing, const char *p_event_prefix, const char *p_label_format, const Coord &p_label_coord, int p_image_buffer_count, int p_warmup_count, int p_pre_event_count, int p_post_event_count, int p_stream_replay_buffer, int p_alarm_frame_count, int p_section_length, int p_frame_skip, int p_capture_delay, int p_alarm_capture_delay, int p_fps_report_interval, int p_ref_blend_perc, bool p_track_motion, Rgb p_signal_check_colour, Purpose p_purpose, int p_n_zones=0, Zone *p_zones[]=0 ); + Monitor( int p_id, const char *p_name, int p_function, bool p_enabled, const char *p_linked_monitors, Camera *p_camera, int p_orientation, unsigned int p_deinterlacing, const char *p_event_prefix, const char *p_label_format, const Coord &p_label_coord, int p_image_buffer_count, int p_warmup_count, int p_pre_event_count, int p_post_event_count, int p_stream_replay_buffer, int p_alarm_frame_count, int p_section_length, int p_frame_skip, int p_capture_delay, int p_alarm_capture_delay, int p_fps_report_interval, int p_ref_blend_perc, int p_alarm_ref_blend_perc, bool p_track_motion, Rgb p_signal_check_colour, Purpose p_purpose, int p_n_zones=0, Zone *p_zones[]=0 ); ~Monitor(); void AddZones( int p_n_zones, Zone *p_zones[] ); diff --git a/src/zm_remote_camera.cpp b/src/zm_remote_camera.cpp index 8c54c0ad7..4ede09e69 100644 --- a/src/zm_remote_camera.cpp +++ b/src/zm_remote_camera.cpp @@ -35,6 +35,10 @@ RemoteCamera::RemoteCamera( int p_id, const std::string &p_protocol, const std:: RemoteCamera::~RemoteCamera() { + if(hp != NULL) { + freeaddrinfo(hp); + hp = NULL; + } } void RemoteCamera::Initialise() @@ -61,15 +65,15 @@ void RemoteCamera::Initialise() auth64 = base64Encode( auth ); } - if ( !hp ) + struct addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + int ret = getaddrinfo(host.c_str(), port.c_str(), &hints, &hp); + if ( ret != 0 ) { - if ( !(hp = gethostbyname(host.c_str())) ) - { - Fatal( "Can't gethostbyname(%s): %s", host.c_str(), strerror(h_errno) ); - } - memcpy((char *)&sa.sin_addr, (char *)hp->h_addr, hp->h_length); - sa.sin_family = hp->h_addrtype; - sa.sin_port = htons(atoi(port.c_str())); + Fatal( "Can't getaddrinfo(%s port %s): %s", host.c_str(), port.c_str(), gai_strerror(ret) ); } } diff --git a/src/zm_remote_camera.h b/src/zm_remote_camera.h index 32a331136..2738e4a5d 100644 --- a/src/zm_remote_camera.h +++ b/src/zm_remote_camera.h @@ -23,6 +23,8 @@ #include "zm_camera.h" #include +#include +#include #include // @@ -40,8 +42,7 @@ protected: std::string auth64; protected: - struct hostent *hp; - struct sockaddr_in sa; + struct addrinfo *hp; public: RemoteCamera( int p_id, const std::string &p_proto, const std::string &p_host, const std::string &p_port, const std::string &p_path, int p_width, int p_height, int p_colours, int p_brightness, int p_contrast, int p_hue, int p_colour, bool p_capture ); diff --git a/src/zm_remote_camera_http.cpp b/src/zm_remote_camera_http.cpp index 59c6f53e0..07d0e6a41 100644 --- a/src/zm_remote_camera_http.cpp +++ b/src/zm_remote_camera_http.cpp @@ -24,6 +24,7 @@ #include #include #include +#include RemoteCameraHttp::RemoteCameraHttp( int p_id, const std::string &p_method, const std::string &p_host, const std::string &p_port, const std::string &p_path, int p_width, int p_height, int p_colours, int p_brightness, int p_contrast, int p_hue, int p_colour, bool p_capture ) : RemoteCamera( p_id, "http", p_host, p_port, p_path, p_width, p_height, p_colours, p_brightness, p_contrast, p_hue, p_colour, p_capture ) @@ -87,22 +88,34 @@ void RemoteCameraHttp::Initialise() int RemoteCameraHttp::Connect() { - if ( sd < 0 ) + struct addrinfo *p; + + for(p = hp; p != NULL; p = p->ai_next) { - sd = socket( hp->h_addrtype, SOCK_STREAM, 0 ); + sd = socket( p->ai_family, p->ai_socktype, p->ai_protocol ); if ( sd < 0 ) { - Error( "Can't create socket: %s", strerror(errno) ); - return( -1 ); + Warning("Can't create socket: %s", strerror(errno) ); + continue; } - if ( connect( sd, (struct sockaddr *)&sa, sizeof(sa) ) < 0 ) + if ( connect( sd, p->ai_addr, p->ai_addrlen ) < 0 ) { - Error( "Can't connect to remote camera: %s", strerror(errno) ); - Disconnect(); - return( -1 ); + close(sd); + sd = -1; + Warning("Can't connect to remote camera: %s", strerror(errno) ); + continue; } + + /* If we got here, we must have connected successfully */ + break; } + + if(p == NULL) { + Error("Unable to connect to the remote camera, aborting"); + return( -1 ); + } + Debug( 3, "Connected to host, socket = %d", sd ); return( sd ); } @@ -428,7 +441,7 @@ int RemoteCameraHttp::GetResponse() if ( content_length ) { - while ( buffer.size() < (unsigned int)content_length ) + while ( (long)buffer.size() < content_length ) { int buffer_len = ReadData( buffer ); if ( buffer_len == 0 ) @@ -960,7 +973,7 @@ int RemoteCameraHttp::GetResponse() if ( content_length ) { - while ( buffer.size() < (unsigned int)content_length ) + while ( (long)buffer.size() < content_length ) { //int buffer_len = ReadData( buffer, content_length-buffer.size() ); int buffer_len = ReadData( buffer ); @@ -1086,7 +1099,7 @@ int RemoteCameraHttp::PreCapture() int RemoteCameraHttp::Capture( Image &image ) { - unsigned int content_length = GetResponse(); + int content_length = GetResponse(); if ( content_length == 0 ) { Warning( "Unable to capture image, retrying" ); @@ -1112,7 +1125,7 @@ int RemoteCameraHttp::Capture( Image &image ) } case X_RGB : { - if ( content_length != image.Size() ) + if ( content_length != (long)image.Size() ) { Error( "Image length mismatch, expected %d bytes, content length was %d", image.Size(), content_length ); Disconnect(); diff --git a/src/zm_remote_camera_rtsp.cpp b/src/zm_remote_camera_rtsp.cpp index cffb91cce..8a1c78f8e 100644 --- a/src/zm_remote_camera_rtsp.cpp +++ b/src/zm_remote_camera_rtsp.cpp @@ -261,6 +261,31 @@ int RemoteCameraRtsp::Capture( Image &image ) if ( !buffer.size() ) return( -1 ); + if(mCodecContext->codec_id == CODEC_ID_H264) + { + // SPS and PPS frames should be saved and appended to IDR frames + int nalType = (buffer.head()[3] & 0x1f); + + // SPS + if(nalType == 7) + { + lastSps = buffer; + continue; + } + // PPS + else if(nalType == 8) + { + lastPps = buffer; + continue; + } + // IDR + else if(nalType == 5) + { + buffer += lastSps; + buffer += lastPps; + } + } + av_init_packet( &packet ); while ( !frameComplete && buffer.size() > 0 ) diff --git a/src/zm_remote_camera_rtsp.h b/src/zm_remote_camera_rtsp.h index 3295c9363..359fea9f4 100644 --- a/src/zm_remote_camera_rtsp.h +++ b/src/zm_remote_camera_rtsp.h @@ -41,6 +41,8 @@ protected: int rtcp_sd; Buffer buffer; + Buffer lastSps; + Buffer lastPps; RtspThread::RtspMethod method; diff --git a/src/zm_rtp_ctrl.cpp b/src/zm_rtp_ctrl.cpp index 1d88482d4..01a0b535a 100644 --- a/src/zm_rtp_ctrl.cpp +++ b/src/zm_rtp_ctrl.cpp @@ -143,8 +143,13 @@ int RtpCtrlThread::recvPacket( const unsigned char *packet, ssize_t packetLen ) mStop = true; break; } - case RTCP_RR : case RTCP_APP : + { + // Ignoring as per RFC 3550 + Debug( 5, "Received RTCP_APP packet, ignoring."); + break; + } + case RTCP_RR : default : { Error( "Received unexpected packet type %d, ignoring", pt ); diff --git a/src/zm_rtp_source.cpp b/src/zm_rtp_source.cpp index 92c4f3d34..0aecd0332 100644 --- a/src/zm_rtp_source.cpp +++ b/src/zm_rtp_source.cpp @@ -24,12 +24,19 @@ #include -RtpSource::RtpSource( int id, const std::string &localHost, int localPortBase, const std::string &remoteHost, int remotePortBase, uint32_t ssrc, uint16_t seq, uint32_t rtpClock, uint32_t rtpTime ) : +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54,25,0) + #define _AVCODECID AVCodecID +#else + #define _AVCODECID CodecID +#endif + +RtpSource::RtpSource( int id, const std::string &localHost, int localPortBase, const std::string &remoteHost, int remotePortBase, uint32_t ssrc, uint16_t seq, uint32_t rtpClock, uint32_t rtpTime, _AVCODECID codecId ) : mId( id ), mSsrc( ssrc ), mLocalHost( localHost ), mRemoteHost( remoteHost ), mRtpClock( rtpClock ), + mCodecId( codecId ), mFrame( 65536 ), mFrameCount( 0 ), mFrameGood( true ), @@ -61,6 +68,9 @@ RtpSource::RtpSource( int id, const std::string &localHost, int localPortBase, c mLastSrTimeReal = tvZero(); mLastSrTimeNtp = tvZero(); mLastSrTimeRtp = 0; + + if(mCodecId != CODEC_ID_H264 && mCodecId != CODEC_ID_MPEG4) + Warning( "The device is using a codec that may not be supported. Do not be surprised if things don't work." ); } void RtpSource::init( uint16_t seq ) @@ -253,57 +263,63 @@ bool RtpSource::handlePacket( const unsigned char *packet, size_t packetLen ) { const RtpDataHeader *rtpHeader; rtpHeader = (RtpDataHeader *)packet; - bool fragmentEnd = false; - - // Each RTP packet delivers only one NAL. It can be either the Single NAL - // ( in that case it must be in one packet ) or the Fragmentation NALs - // that delivers large single NAL... + int rtpHeaderSize = 12 + rtpHeader->cc * 4; + // No need to check for nal type as non fragmented packets already have 001 start sequence appended + bool h264FragmentEnd = (mCodecId == CODEC_ID_H264) && (packet[rtpHeaderSize+1] & 0x40); + bool thisM = rtpHeader->m || h264FragmentEnd; if ( updateSeq( ntohs(rtpHeader->seqN) ) ) { - Hexdump( 4, packet+sizeof(RtpDataHeader), 16 ); - if ( ((packet[sizeof(RtpDataHeader)] & 0x1f) == 28 && - (packet[sizeof(RtpDataHeader)+1] & 0x80)) || - ((packet[sizeof(RtpDataHeader)] & 0x1f) != 28 && - prevM && rtpHeader->m) ) - mFrameGood = true; // This means that if packet is in sequence - // and is single NAL with mark set (and prev packet - // was NAL with mark set or it is Fragmentation NAL with - // Start bit set then we assume that sequence - // was restored and we can handle packet + Hexdump( 4, packet+rtpHeaderSize, 16 ); + if ( mFrameGood ) { - // check if there fragmentation NAL - if ( (packet[sizeof(RtpDataHeader)] & 0x1f) == 28 ) - { - // is this NAL the first NAL in fragmentation sequence - if ( packet[sizeof(RtpDataHeader)+1] & 0x80 ) - { - // if there is any data in frame then we must - // discard it because that frame was incomplete - if ( mFrame.size() ) - mFrame.clear(); - // Now we will form new header of frame - mFrame.append("\x0\x0\x1\x0",4); - *(mFrame+3) = (packet[sizeof(RtpDataHeader)+1] & 0x1f) | - (packet[sizeof(RtpDataHeader)] & 0x60); - } - else - if ( packet[sizeof(RtpDataHeader)+1] & 0x40 ) - fragmentEnd = true; - mFrame.append(packet+sizeof(RtpDataHeader)+2, packetLen-sizeof(RtpDataHeader)-2); - } - else - { -// mframe.clear(); - if ( !mFrame.size() ) - mFrame.append("\x0\x0\x1",3); - mFrame.append( packet+sizeof(RtpDataHeader), packetLen-sizeof(RtpDataHeader) ); - } + int extraHeader = 0; + + if( mCodecId == CODEC_ID_H264 ) + { + int nalType = (packet[rtpHeaderSize] & 0x1f); + + switch (nalType) + { + case 24: + { + extraHeader = 2; + break; + } + case 25: case 26: case 27: + { + extraHeader = 3; + break; + } + // FU-A and FU-B + case 28: case 29: + { + // Is this NAL the first NAL in fragmentation sequence + if ( packet[rtpHeaderSize+1] & 0x80 ) + { + // Now we will form new header of frame + mFrame.append( "\x0\x0\x1\x0", 4 ); + // Reconstruct NAL header from FU headers + *(mFrame+3) = (packet[rtpHeaderSize+1] & 0x1f) | + (packet[rtpHeaderSize] & 0xe0); + } + + extraHeader = 2; + break; + } + } + + // Append NAL frame start code + if ( !mFrame.size() ) + mFrame.append( "\x0\x0\x1", 3 ); + } + mFrame.append( packet+rtpHeaderSize+extraHeader, packetLen-rtpHeaderSize-extraHeader ); } + Hexdump( 4, mFrame.head(), 16 ); - if ( rtpHeader->m || fragmentEnd ) + if ( thisM ) { if ( mFrameGood ) { @@ -339,7 +355,7 @@ bool RtpSource::handlePacket( const unsigned char *packet, size_t packetLen ) mFrameGood = false; mFrame.clear(); } - if ( rtpHeader->m || fragmentEnd ) + if ( thisM ) { mFrameGood = true; prevM = true; @@ -368,3 +384,5 @@ bool RtpSource::getFrame( Buffer &buffer ) Debug( 3, "Copied %d bytes", buffer.size() ); return( true ); } + +#undef _AVCODECID \ No newline at end of file diff --git a/src/zm_rtp_source.h b/src/zm_rtp_source.h index 4ffd6e101..8d1f7da4f 100644 --- a/src/zm_rtp_source.h +++ b/src/zm_rtp_source.h @@ -21,12 +21,19 @@ #define ZM_RTP_SOURCE_H #include "zm_buffer.h" +#include "zm_ffmpeg.h" #include "zm_thread.h" #include #include #include +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54,25,0) + #define _AVCODECID AVCodecID +#else + #define _AVCODECID CodecID +#endif + struct RtpDataHeader; class RtpSource @@ -81,6 +88,8 @@ private: uint32_t mLostPackets; uint8_t mLostFraction; + _AVCODECID mCodecId; + Buffer mFrame; int mFrameCount; bool mFrameGood; @@ -92,7 +101,8 @@ private: void init( uint16_t seq ); public: - RtpSource( int id, const std::string &localHost, int localPortBase, const std::string &remoteHost, int remotePortBase, uint32_t ssrc, uint16_t seq, uint32_t rtpClock, uint32_t rtpTime ); + RtpSource( int id, const std::string &localHost, int localPortBase, const std::string &remoteHost, int remotePortBase, uint32_t ssrc, uint16_t seq, uint32_t rtpClock, uint32_t rtpTime, _AVCODECID codecId ); + bool updateSeq( uint16_t seq ); void updateJitter( const RtpDataHeader *header ); void updateRtcpData( uint32_t ntpTimeSecs, uint32_t ntpTimeFrac, uint32_t rtpTime ); @@ -177,4 +187,6 @@ public: } }; +#undef _AVCODECID + #endif // ZM_RTP_SOURCE_H diff --git a/src/zm_rtsp.cpp b/src/zm_rtsp.cpp index 3d82e7f35..e349dcf9f 100644 --- a/src/zm_rtsp.cpp +++ b/src/zm_rtsp.cpp @@ -330,6 +330,13 @@ int RtspThread::run() uint32_t rtpClock = 0; std::string trackUrl = mUrl; + + #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54,25,0) + enum AVCodecID codecId; + #else + enum CodecID codecId; + #endif + if ( mFormatContext->nb_streams >= 1 ) { for ( unsigned int i = 0; i < mFormatContext->nb_streams; i++ ) @@ -343,6 +350,7 @@ int RtspThread::run() { trackUrl += "/"+mediaDesc->getControlUrl(); rtpClock = mediaDesc->getClock(); + codecId = mFormatContext->streams[i]->codec->codec_id; // Hackery pokery //rtpClock = mFormatContext->streams[i]->codec->sample_rate; break; @@ -500,7 +508,7 @@ int RtspThread::run() { case RTP_UNICAST : { - RtpSource *source = new RtpSource( mId, "", localPorts[0], mHost, remotePorts[0], ssrc, seq, rtpClock, rtpTime ); + RtpSource *source = new RtpSource( mId, "", localPorts[0], mHost, remotePorts[0], ssrc, seq, rtpClock, rtpTime, codecId ); mSources[ssrc] = source; RtpDataThread rtpDataThread( *this, *source ); RtpCtrlThread rtpCtrlThread( *this, *source ); @@ -545,7 +553,7 @@ int RtspThread::run() case RTP_RTSP : case RTP_RTSP_HTTP : { - RtpSource *source = new RtpSource( mId, "", remoteChannels[0], mHost, remoteChannels[0], ssrc, seq, rtpClock, rtpTime ); + RtpSource *source = new RtpSource( mId, "", remoteChannels[0], mHost, remoteChannels[0], ssrc, seq, rtpClock, rtpTime, codecId ); mSources[ssrc] = source; // These never actually run RtpDataThread rtpDataThread( *this, *source ); @@ -673,7 +681,7 @@ int RtspThread::run() } case RTP_MULTICAST : { - RtpSource *source = new RtpSource( mId, localHost, localPorts[0], mHost, remotePorts[0], ssrc, seq, rtpClock, rtpTime ); + RtpSource *source = new RtpSource( mId, localHost, localPorts[0], mHost, remotePorts[0], ssrc, seq, rtpClock, rtpTime, codecId ); mSources[ssrc] = source; RtpDataThread rtpDataThread( *this, *source ); RtpCtrlThread rtpCtrlThread( *this, *source ); diff --git a/src/zmfix.cpp b/src/zmfix.cpp deleted file mode 100644 index a9254844b..000000000 --- a/src/zmfix.cpp +++ /dev/null @@ -1,207 +0,0 @@ -// -// ZoneMinder Video Device Fixer, $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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "zm.h" -#include "zm_db.h" - -// Determine if we are a member of the group -int inGroup( gid_t gid ) -{ - // Get how many groups we are in - int n_gids = getgroups( 0, NULL ); - if ( n_gids < 0 ) - { - Error( "getgroups:%s", strerror(errno) ); - return( -1 ); - } - - // Not in any groups - if ( !n_gids ) - { - return( 0 ); - } - - // Allocate space to hold groups - gid_t *gids = new gid_t[n_gids * sizeof(gid_t)]; - if ( !gids ) - { - Error( "Unable to allocate groups: %s", strerror(errno) ); - return( -1 ); - } - - // Get list of groups - if ( getgroups( n_gids, gids ) != n_gids ) - { - Error( "getgroups:%s", strerror(errno) ); - delete[] gids; - return( -1 ); - } - - // See if gid in list of groups we belong to - int in_gid = 0; - for ( int i = 0; i < n_gids; i++ ) - { - if ( gids[i] == gid ) - { - in_gid = 1; - } - } - delete[] gids; - return( in_gid ); -} - -bool fixDevice( const char *device_path ) -{ - struct stat stat_buf; - - if ( stat( device_path, &stat_buf ) < 0 ) - { - Error( "Can't stat %s: %s", device_path, strerror(errno)); - return( false ); - } - - uid_t uid = getuid(); - gid_t gid = getgid(); - - int in_gid; - if ( (in_gid = inGroup( stat_buf.st_gid )) < 0 ) - { - return( false ); - } - - mode_t mask = 0; - if ( uid == stat_buf.st_uid ) - { - // If we are the owner - mask = 00600; - } - else if ( gid == stat_buf.st_gid || in_gid ) - { - // If we are in the owner group - mask = 00060; - } - else - { - // We are neither the owner nor in the group - mask = 00006; - } - - mode_t mode = stat_buf.st_mode; - if ( (mode & mask) == mask ) - { - Debug( 1, "Permissions on %s are ok at %o", device_path, mode ); - return( true ); - } - mode |= mask; - - Info( "Resetting permissions on %s to %o", device_path, mode ); - if ( chmod( device_path, mode ) < 0 ) - { - Error( "Can't chmod %s to %o: %s", device_path, mode, strerror(errno)); - return( false ); - } - return( true ); -} - -int main( int argc, char *argv[] ) -{ - self = argv[0]; - - zmLoadConfig(); - - logInit( "zmfix" ); - logCapLevel( Logger::ERROR ); - - // Only do registered devices - static char sql[ZM_SQL_SML_BUFSIZ]; - snprintf( sql, sizeof(sql), "select distinct Device from Monitors where not isnull(Device) and Type = 'Local'" ); - 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 ); - if ( !result ) - { - Error( "Can't use query result: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } - - for( int i = 0; MYSQL_ROW dbrow = mysql_fetch_row( result ); i++ ) - { - fixDevice( dbrow[0] ); - } - - if ( mysql_errno( &dbconn ) ) - { - Error( "Can't fetch row: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } - // Yadda yadda - mysql_free_result( result ); - - snprintf( sql, sizeof(sql), "select distinct ControlDevice from Monitors where not isEmpty(ControlDevice)" ); - if ( mysql_query( &dbconn, sql ) ) - { - Error( "Can't run query: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } - - result = mysql_store_result( &dbconn ); - if ( !result ) - { - Error( "Can't use query result: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } - - for( int i = 0; MYSQL_ROW dbrow = mysql_fetch_row( result ); i++ ) - { - fixDevice( dbrow[0] ); - } - - if ( mysql_errno( &dbconn ) ) - { - Error( "Can't fetch row: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } - // Yadda yadda - mysql_free_result( result ); - - if ( config.opt_x10 ) - { - if ( config.x10_device ) - { - fixDevice( config.x10_device ); - } - } - - return( 0 ); -} diff --git a/version b/version index ea0928ced..8fe00a57f 100644 --- a/version +++ b/version @@ -1 +1 @@ -1.26.4 +1.26.5 diff --git a/web/CMakeLists.txt b/web/CMakeLists.txt index b122bea4e..b4d865c19 100644 --- a/web/CMakeLists.txt +++ b/web/CMakeLists.txt @@ -7,6 +7,12 @@ add_subdirectory(tools/mootools) configure_file(includes/config.php.in "${CMAKE_CURRENT_BINARY_DIR}/includes/config.php" @ONLY) # Install the web files -install(DIRECTORY ajax css graphics includes js lang skins tools views DESTINATION "${ZM_WEBDIR}" PATTERN "*.in" EXCLUDE PATTERN "*Make*" EXCLUDE PATTERN "*cmake*" EXCLUDE REGEX "includes/config.php$" EXCLUDE) -install(FILES index.php README.md DESTINATION "${ZM_WEBDIR}") +install(DIRECTORY ajax css graphics includes js lang skins tools views DESTINATION "${ZM_WEBDIR}" PATTERN "*.in" EXCLUDE PATTERN "*Make*" EXCLUDE PATTERN "*cmake*" EXCLUDE) +install(FILES index.php DESTINATION "${ZM_WEBDIR}") install(FILES "${CMAKE_CURRENT_BINARY_DIR}/includes/config.php" DESTINATION "${ZM_WEBDIR}/includes") + +# Install the mootools symlinks (if its not in the source directory) +if(NOT (CMAKE_BINARY_DIR STREQUAL CMAKE_SOURCE_DIR)) + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/tools/mootools/mootools-core.js" DESTINATION "${ZM_WEBDIR}/tools/mootools") + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/tools/mootools/mootools-more.js" DESTINATION "${ZM_WEBDIR}/tools/mootools") +endif(NOT (CMAKE_BINARY_DIR STREQUAL CMAKE_SOURCE_DIR)) diff --git a/web/includes/actions.php b/web/includes/actions.php index 6eadb97ae..643bf82a5 100644 --- a/web/includes/actions.php +++ b/web/includes/actions.php @@ -554,7 +554,6 @@ if ( !empty($action) ) if ( $restart ) { $monitor = dbFetchOne( "select * from Monitors where Id = '".dbEscape($mid)."'" ); - fixDevices(); //if ( $cookies ) //session_write_close(); if ( daemonCheck() ) diff --git a/web/includes/config.php.in b/web/includes/config.php.in index 91612cbdf..a592e41bc 100644 --- a/web/includes/config.php.in +++ b/web/includes/config.php.in @@ -22,6 +22,8 @@ // This section contains options substituted by the zmconfig.pl utility, do not edit these directly // define( "ZM_CONFIG", "@ZM_CONFIG@" ); // Path to config file +// Define, and override any given in config file +define( "ZM_VERSION", "@VERSION@" ); // Version $configFile = ZM_CONFIG; $localConfigFile = basename($configFile); diff --git a/web/includes/functions.php b/web/includes/functions.php index 30ef63281..49abecde2 100644 --- a/web/includes/functions.php +++ b/web/includes/functions.php @@ -256,9 +256,9 @@ classid="CLSID:22D6F312-B0F6-11D0-94AB-0080C74C7E95" codebase="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,0,02,902" standby="Loading Microsoft Windows Media Player components..." type=""> - - - + + + classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" codebase="http://www.apple.com/qtactivex/qtplugin.cab" type=""> - - - + + + "> - - - + + + /dev/null >&- <&- >/dev/null"; - exec( $string ); -} - function packageControl( $command ) { $string = ZM_PATH_BIN.'/zmpkg.pl '.escapeshellarg( $command ); @@ -2225,10 +2218,11 @@ function isVector ( &$array ) return( true ); } -function checkJsonError() +function checkJsonError($value) { if ( function_exists('json_last_error') ) { + $value = var_export($value,true); switch( json_last_error() ) { case JSON_ERROR_DEPTH : @@ -2252,7 +2246,7 @@ function jsonEncode( &$value ) if ( function_exists('json_encode') ) { $string = json_encode( $value ); - checkJsonError(); + checkJsonError($value); return( $string ); } @@ -2293,7 +2287,7 @@ function jsonDecode( $value ) if ( function_exists('json_decode') ) { $object = json_decode( $value, true ); - checkJsonError(); + checkJsonError($value); return( $object ); } diff --git a/web/lang/en_gb.php b/web/lang/en_gb.php index cf889520d..cbf85c0b1 100644 --- a/web/lang/en_gb.php +++ b/web/lang/en_gb.php @@ -376,6 +376,7 @@ $SLANG = array( 'Language' => 'Language', 'Last' => 'Last', 'Layout' => 'Layout', + 'Libvlc' => 'Libvlc', 'LimitResultsPost' => 'results only', // This is used at the end of the phrase 'Limit to first N results only' 'LimitResultsPre' => 'Limit to first', // This is used at the beginning of the phrase 'Limit to first N results only' 'LinkedMonitors' => 'Linked Monitors', diff --git a/web/skins/classic/includes/export_functions.php b/web/skins/classic/includes/export_functions.php index 7123cbf6f..1c77ca9bb 100644 --- a/web/skins/classic/includes/export_functions.php +++ b/web/skins/classic/includes/export_functions.php @@ -71,163 +71,8 @@ html ul.tabs li.active, html ul.tabs li.active a:hover { } --> +