Initial commit for saving events as videos :)
This commit is contained in:
parent
0556187a0f
commit
2b79ff2cbd
|
@ -224,6 +224,40 @@ else(MYSQLCLIENT_LIBRARIES)
|
|||
message(FATAL_ERROR "zm requires mysqlclient but it was not found on your system")
|
||||
endif(MYSQLCLIENT_LIBRARIES)
|
||||
|
||||
# x264 (using find_library and find_path)
|
||||
find_library(X264_LIBRARIES x264)
|
||||
if(X264_LIBRARIES)
|
||||
set(HAVE_LIBX264 1)
|
||||
list(APPEND ZM_BIN_LIBS "${X264_LIBRARIES}")
|
||||
find_path(X264_INCLUDE_DIR x264.h)
|
||||
if(X264_INCLUDE_DIR)
|
||||
include_directories("${X264_INCLUDE_DIR}")
|
||||
set(CMAKE_REQUIRED_INCLUDES "${X264_INCLUDE_DIR}")
|
||||
endif(X264_INCLUDE_DIR)
|
||||
mark_as_advanced(FORCE X264_LIBRARIES X264_INCLUDE_DIR)
|
||||
check_include_files("stdint.h;x264.h" HAVE_X264_H)
|
||||
set(optlibsfound "${optlibsfound} x264")
|
||||
else(X264_LIBRARIES)
|
||||
set(optlibsnotfound "${optlibsnotfound} x264")
|
||||
endif(X264_LIBRARIES)
|
||||
|
||||
# mp4v2 (using find_library and find_path)
|
||||
find_library(MP4V2_LIBRARIES mp4v2)
|
||||
if(MP4V2_LIBRARIES)
|
||||
set(HAVE_LIBMP4V2 1)
|
||||
list(APPEND ZM_BIN_LIBS "${MP4V2_LIBRARIES}")
|
||||
find_path(MP4V2_INCLUDE_DIR mp4.h)
|
||||
if(MP4V2_INCLUDE_DIR)
|
||||
include_directories("${MP4V2_INCLUDE_DIR}")
|
||||
set(CMAKE_REQUIRED_INCLUDES "${MP4V2_INCLUDE_DIR}")
|
||||
endif(MP4V2_INCLUDE_DIR)
|
||||
mark_as_advanced(FORCE MP4V2_LIBRARIES MP4V2_INCLUDE_DIR)
|
||||
check_include_file("mp4.h" HAVE_MP4_H)
|
||||
set(optlibsfound "${optlibsfound} mp4v2")
|
||||
else(MP4V2_LIBRARIES)
|
||||
set(optlibsnotfound "${optlibsnotfound} mp4v2")
|
||||
endif(MP4V2_LIBRARIES)
|
||||
|
||||
set(PATH_FFMPEG "")
|
||||
set(OPT_FFMPEG "no")
|
||||
# Do not check for ffmpeg if ZM_NO_FFMPEG is on
|
||||
|
|
|
@ -266,6 +266,7 @@ fi
|
|||
AC_CHECK_LIB(pcre,pcre_compile,,AC_MSG_WARN(libpcre.a may be required for remote/network camera support))
|
||||
AC_CHECK_LIB(z,zlibVersion)
|
||||
AC_CHECK_LIB(x264,x264_predict_16x16_init)
|
||||
AC_CHECK_LIB(mp4v2,MP4AddH264VideoTrack)
|
||||
AC_CHECK_LIB(avutil,av_malloc,,AC_MSG_WARN(libavutil.a may be required for MPEG streaming))
|
||||
# Don't bother to warn about this one
|
||||
AC_CHECK_LIB(avcore,av_image_copy,,)
|
||||
|
@ -313,6 +314,8 @@ AC_CHECK_HEADERS(sys/ipc.h,,,)
|
|||
AC_CHECK_HEADERS(sys/shm.h,,,)
|
||||
fi
|
||||
AC_CHECK_HEADERS(zlib.h,,,)
|
||||
AC_CHECK_HEADERS(x264.h,,,)
|
||||
AC_CHECK_HEADERS(mp4.h,,,)
|
||||
|
||||
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 <stdlib.h>
|
||||
|
|
|
@ -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.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.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_video.cpp zm_zone.cpp)
|
||||
|
||||
# A fix for cmake recompiling the source files for every target.
|
||||
add_library(zm STATIC ${ZM_BIN_SRC_FILES})
|
||||
|
|
|
@ -1,658 +0,0 @@
|
|||
// The file is autogenerated by zmconfgen.pl
|
||||
// Do not edit this file as any changes will be overwritten
|
||||
|
||||
#define ZM_LANG_DEFAULT 0
|
||||
#define ZM_OPT_USE_AUTH 1
|
||||
#define ZM_AUTH_TYPE 2
|
||||
#define ZM_AUTH_RELAY 3
|
||||
#define ZM_AUTH_HASH_SECRET 4
|
||||
#define ZM_AUTH_HASH_IPS 5
|
||||
#define ZM_AUTH_HASH_LOGINS 6
|
||||
#define ZM_DIR_EVENTS 7
|
||||
#define ZM_USE_DEEP_STORAGE 8
|
||||
#define ZM_DIR_IMAGES 9
|
||||
#define ZM_DIR_SOUNDS 10
|
||||
#define ZM_PATH_ZMS 11
|
||||
#define ZM_COLOUR_JPEG_FILES 12
|
||||
#define ZM_ADD_JPEG_COMMENTS 13
|
||||
#define ZM_JPEG_FILE_QUALITY 14
|
||||
#define ZM_JPEG_ALARM_FILE_QUALITY 15
|
||||
#define ZM_JPEG_IMAGE_QUALITY 16
|
||||
#define ZM_JPEG_STREAM_QUALITY 17
|
||||
#define ZM_MPEG_TIMED_FRAMES 18
|
||||
#define ZM_MPEG_LIVE_FORMAT 19
|
||||
#define ZM_MPEG_REPLAY_FORMAT 20
|
||||
#define ZM_RAND_STREAM 21
|
||||
#define ZM_OPT_CAMBOZOLA 22
|
||||
#define ZM_PATH_CAMBOZOLA 23
|
||||
#define ZM_RELOAD_CAMBOZOLA 24
|
||||
#define ZM_TIMESTAMP_ON_CAPTURE 25
|
||||
#define ZM_CPU_EXTENSIONS 26
|
||||
#define ZM_FAST_IMAGE_BLENDS 27
|
||||
#define ZM_OPT_ADAPTIVE_SKIP 28
|
||||
#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 214
|
||||
|
||||
#define ZM_CFG_DECLARE_LIST \
|
||||
const char *lang_default;\
|
||||
bool opt_use_auth;\
|
||||
const char *auth_type;\
|
||||
const char *auth_relay;\
|
||||
const char *auth_hash_secret;\
|
||||
bool auth_hash_ips;\
|
||||
bool auth_hash_logins;\
|
||||
const char *dir_events;\
|
||||
bool use_deep_storage;\
|
||||
const char *dir_images;\
|
||||
const char *dir_sounds;\
|
||||
const char *path_zms;\
|
||||
bool colour_jpeg_files;\
|
||||
bool add_jpeg_comments;\
|
||||
int jpeg_file_quality;\
|
||||
int jpeg_alarm_file_quality;\
|
||||
int jpeg_image_quality;\
|
||||
int jpeg_stream_quality;\
|
||||
bool mpeg_timed_frames;\
|
||||
const char *mpeg_live_format;\
|
||||
const char *mpeg_replay_format;\
|
||||
bool rand_stream;\
|
||||
bool opt_cambozola;\
|
||||
const char *path_cambozola;\
|
||||
int reload_cambozola;\
|
||||
bool timestamp_on_capture;\
|
||||
bool cpu_extensions;\
|
||||
bool fast_image_blends;\
|
||||
bool opt_adaptive_skip;\
|
||||
int max_suspend_time;\
|
||||
bool opt_remote_cameras;\
|
||||
bool netcam_regexps;\
|
||||
const char *http_version;\
|
||||
const char *http_ua;\
|
||||
int http_timeout;\
|
||||
int min_rtp_port;\
|
||||
int max_rtp_port;\
|
||||
bool opt_ffmpeg;\
|
||||
const char *path_ffmpeg;\
|
||||
const char *ffmpeg_input_options;\
|
||||
const char *ffmpeg_output_options;\
|
||||
const char *ffmpeg_formats;\
|
||||
int log_level_syslog;\
|
||||
int log_level_file;\
|
||||
int log_level_weblog;\
|
||||
int log_level_database;\
|
||||
const char *log_database_limit;\
|
||||
bool log_debug;\
|
||||
const char *log_debug_target;\
|
||||
int log_debug_level;\
|
||||
const char *log_debug_file;\
|
||||
int log_check_period;\
|
||||
int log_alert_war_count;\
|
||||
int log_alert_err_count;\
|
||||
int log_alert_fat_count;\
|
||||
int log_alarm_war_count;\
|
||||
int log_alarm_err_count;\
|
||||
int log_alarm_fat_count;\
|
||||
bool record_event_stats;\
|
||||
bool record_diag_images;\
|
||||
bool dump_cores;\
|
||||
const char *path_map;\
|
||||
const char *path_socks;\
|
||||
const char *path_logs;\
|
||||
const char *path_swap;\
|
||||
const char *web_title_prefix;\
|
||||
bool web_resize_console;\
|
||||
bool web_popup_on_alarm;\
|
||||
bool opt_x10;\
|
||||
const char *x10_device;\
|
||||
const char *x10_house_code;\
|
||||
int x10_db_reload_interval;\
|
||||
bool web_sound_on_alarm;\
|
||||
const char *web_alarm_sound;\
|
||||
bool web_compact_montage;\
|
||||
bool opt_fast_delete;\
|
||||
bool strict_video_config;\
|
||||
int signal_check_points;\
|
||||
bool v4l_multi_buffer;\
|
||||
int captures_per_frame;\
|
||||
int filter_reload_delay;\
|
||||
int filter_execute_interval;\
|
||||
bool opt_upload;\
|
||||
const char *upload_arch_format;\
|
||||
bool upload_arch_compress;\
|
||||
bool upload_arch_analyse;\
|
||||
const char *upload_protocol;\
|
||||
const char *upload_ftp_host;\
|
||||
const char *upload_host;\
|
||||
int upload_port;\
|
||||
const char *upload_ftp_user;\
|
||||
const char *upload_user;\
|
||||
const char *upload_ftp_pass;\
|
||||
const char *upload_pass;\
|
||||
const char *upload_ftp_loc_dir;\
|
||||
const char *upload_loc_dir;\
|
||||
const char *upload_ftp_rem_dir;\
|
||||
const char *upload_rem_dir;\
|
||||
int upload_ftp_timeout;\
|
||||
int upload_timeout;\
|
||||
bool upload_ftp_passive;\
|
||||
bool upload_ftp_debug;\
|
||||
bool upload_debug;\
|
||||
bool opt_email;\
|
||||
const char *email_address;\
|
||||
const char *email_text;\
|
||||
const char *email_subject;\
|
||||
const char *email_body;\
|
||||
bool opt_message;\
|
||||
const char *message_address;\
|
||||
const char *message_text;\
|
||||
const char *message_subject;\
|
||||
const char *message_body;\
|
||||
bool new_mail_modules;\
|
||||
const char *email_host;\
|
||||
const char *from_email;\
|
||||
const char *url;\
|
||||
int max_restart_delay;\
|
||||
int watch_check_interval;\
|
||||
double watch_max_delay;\
|
||||
bool run_audit;\
|
||||
int audit_check_interval;\
|
||||
int forced_alarm_score;\
|
||||
int bulk_frame_interval;\
|
||||
const char *event_close_mode;\
|
||||
bool force_close_events;\
|
||||
bool create_analysis_images;\
|
||||
bool weighted_alarm_centres;\
|
||||
int event_image_digits;\
|
||||
const char *default_aspect_ratio;\
|
||||
bool user_self_edit;\
|
||||
bool opt_frame_server;\
|
||||
int frame_socket_size;\
|
||||
bool opt_control;\
|
||||
bool opt_triggers;\
|
||||
bool check_for_updates;\
|
||||
const char *update_check_proxy;\
|
||||
int shm_key;\
|
||||
const char *web_refresh_method;\
|
||||
const char *web_event_sort_field;\
|
||||
const char *web_event_sort_order;\
|
||||
int web_events_per_page;\
|
||||
bool web_list_thumbs;\
|
||||
int web_list_thumb_width;\
|
||||
int web_list_thumb_height;\
|
||||
bool web_use_object_tags;\
|
||||
int web_h_refresh_main;\
|
||||
int web_h_refresh_cycle;\
|
||||
int web_h_refresh_image;\
|
||||
int web_h_refresh_status;\
|
||||
int web_h_refresh_events;\
|
||||
const char *web_h_can_stream;\
|
||||
const char *web_h_stream_method;\
|
||||
int web_h_default_scale;\
|
||||
int web_h_default_rate;\
|
||||
int web_h_video_bitrate;\
|
||||
int web_h_video_maxfps;\
|
||||
bool web_h_scale_thumbs;\
|
||||
const char *web_h_events_view;\
|
||||
bool web_h_show_progress;\
|
||||
int web_h_ajax_timeout;\
|
||||
int web_m_refresh_main;\
|
||||
int web_m_refresh_cycle;\
|
||||
int web_m_refresh_image;\
|
||||
int web_m_refresh_status;\
|
||||
int web_m_refresh_events;\
|
||||
const char *web_m_can_stream;\
|
||||
const char *web_m_stream_method;\
|
||||
int web_m_default_scale;\
|
||||
int web_m_default_rate;\
|
||||
int web_m_video_bitrate;\
|
||||
int web_m_video_maxfps;\
|
||||
bool web_m_scale_thumbs;\
|
||||
const char *web_m_events_view;\
|
||||
bool web_m_show_progress;\
|
||||
int web_m_ajax_timeout;\
|
||||
int web_l_refresh_main;\
|
||||
int web_l_refresh_cycle;\
|
||||
int web_l_refresh_image;\
|
||||
int web_l_refresh_status;\
|
||||
int web_l_refresh_events;\
|
||||
const char *web_l_can_stream;\
|
||||
const char *web_l_stream_method;\
|
||||
int web_l_default_scale;\
|
||||
int web_l_default_rate;\
|
||||
int web_l_video_bitrate;\
|
||||
int web_l_video_maxfps;\
|
||||
bool web_l_scale_thumbs;\
|
||||
const char *web_l_events_view;\
|
||||
bool web_l_show_progress;\
|
||||
int web_l_ajax_timeout;\
|
||||
const char *web_p_can_stream;\
|
||||
const char *web_p_stream_method;\
|
||||
int web_p_default_scale;\
|
||||
int web_p_default_rate;\
|
||||
int web_p_video_bitrate;\
|
||||
int web_p_video_maxfps;\
|
||||
bool web_p_scale_thumbs;\
|
||||
int web_p_ajax_timeout;\
|
||||
const char *dyn_last_version;\
|
||||
const char *dyn_curr_version;\
|
||||
const char *dyn_db_version;\
|
||||
int dyn_last_check;\
|
||||
const char *dyn_next_reminder;\
|
||||
int dyn_donate_reminder_time;\
|
||||
bool dyn_show_donate_reminder;\
|
||||
bool eyezm_debug;\
|
||||
bool eyezm_log_to_file;\
|
||||
const char *eyezm_log_file;\
|
||||
const char *eyezm_event_vcodec;\
|
||||
const char *eyezm_feed_vcodec;\
|
||||
const char *eyezm_h264_default_br;\
|
||||
const char *eyezm_h264_default_evbr;\
|
||||
const char *eyezm_h264_timeout;\
|
||||
const char *eyezm_seg_duration;\
|
||||
|
||||
|
||||
#define ZM_CFG_ASSIGN_LIST \
|
||||
lang_default = (const char *)config.Item( ZM_LANG_DEFAULT );\
|
||||
opt_use_auth = (bool)config.Item( ZM_OPT_USE_AUTH );\
|
||||
auth_type = (const char *)config.Item( ZM_AUTH_TYPE );\
|
||||
auth_relay = (const char *)config.Item( ZM_AUTH_RELAY );\
|
||||
auth_hash_secret = (const char *)config.Item( ZM_AUTH_HASH_SECRET );\
|
||||
auth_hash_ips = (bool)config.Item( ZM_AUTH_HASH_IPS );\
|
||||
auth_hash_logins = (bool)config.Item( ZM_AUTH_HASH_LOGINS );\
|
||||
dir_events = (const char *)config.Item( ZM_DIR_EVENTS );\
|
||||
use_deep_storage = (bool)config.Item( ZM_USE_DEEP_STORAGE );\
|
||||
dir_images = (const char *)config.Item( ZM_DIR_IMAGES );\
|
||||
dir_sounds = (const char *)config.Item( ZM_DIR_SOUNDS );\
|
||||
path_zms = (const char *)config.Item( ZM_PATH_ZMS );\
|
||||
colour_jpeg_files = (bool)config.Item( ZM_COLOUR_JPEG_FILES );\
|
||||
add_jpeg_comments = (bool)config.Item( ZM_ADD_JPEG_COMMENTS );\
|
||||
jpeg_file_quality = (int)config.Item( ZM_JPEG_FILE_QUALITY );\
|
||||
jpeg_alarm_file_quality = (int)config.Item( ZM_JPEG_ALARM_FILE_QUALITY );\
|
||||
jpeg_image_quality = (int)config.Item( ZM_JPEG_IMAGE_QUALITY );\
|
||||
jpeg_stream_quality = (int)config.Item( ZM_JPEG_STREAM_QUALITY );\
|
||||
mpeg_timed_frames = (bool)config.Item( ZM_MPEG_TIMED_FRAMES );\
|
||||
mpeg_live_format = (const char *)config.Item( ZM_MPEG_LIVE_FORMAT );\
|
||||
mpeg_replay_format = (const char *)config.Item( ZM_MPEG_REPLAY_FORMAT );\
|
||||
rand_stream = (bool)config.Item( ZM_RAND_STREAM );\
|
||||
opt_cambozola = (bool)config.Item( ZM_OPT_CAMBOZOLA );\
|
||||
path_cambozola = (const char *)config.Item( ZM_PATH_CAMBOZOLA );\
|
||||
reload_cambozola = (int)config.Item( ZM_RELOAD_CAMBOZOLA );\
|
||||
timestamp_on_capture = (bool)config.Item( ZM_TIMESTAMP_ON_CAPTURE );\
|
||||
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 );\
|
||||
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 );\
|
||||
http_version = (const char *)config.Item( ZM_HTTP_VERSION );\
|
||||
http_ua = (const char *)config.Item( ZM_HTTP_UA );\
|
||||
http_timeout = (int)config.Item( ZM_HTTP_TIMEOUT );\
|
||||
min_rtp_port = (int)config.Item( ZM_MIN_RTP_PORT );\
|
||||
max_rtp_port = (int)config.Item( ZM_MAX_RTP_PORT );\
|
||||
opt_ffmpeg = (bool)config.Item( ZM_OPT_FFMPEG );\
|
||||
path_ffmpeg = (const char *)config.Item( ZM_PATH_FFMPEG );\
|
||||
ffmpeg_input_options = (const char *)config.Item( ZM_FFMPEG_INPUT_OPTIONS );\
|
||||
ffmpeg_output_options = (const char *)config.Item( ZM_FFMPEG_OUTPUT_OPTIONS );\
|
||||
ffmpeg_formats = (const char *)config.Item( ZM_FFMPEG_FORMATS );\
|
||||
log_level_syslog = (int)config.Item( ZM_LOG_LEVEL_SYSLOG );\
|
||||
log_level_file = (int)config.Item( ZM_LOG_LEVEL_FILE );\
|
||||
log_level_weblog = (int)config.Item( ZM_LOG_LEVEL_WEBLOG );\
|
||||
log_level_database = (int)config.Item( ZM_LOG_LEVEL_DATABASE );\
|
||||
log_database_limit = (const char *)config.Item( ZM_LOG_DATABASE_LIMIT );\
|
||||
log_debug = (bool)config.Item( ZM_LOG_DEBUG );\
|
||||
log_debug_target = (const char *)config.Item( ZM_LOG_DEBUG_TARGET );\
|
||||
log_debug_level = (int)config.Item( ZM_LOG_DEBUG_LEVEL );\
|
||||
log_debug_file = (const char *)config.Item( ZM_LOG_DEBUG_FILE );\
|
||||
log_check_period = (int)config.Item( ZM_LOG_CHECK_PERIOD );\
|
||||
log_alert_war_count = (int)config.Item( ZM_LOG_ALERT_WAR_COUNT );\
|
||||
log_alert_err_count = (int)config.Item( ZM_LOG_ALERT_ERR_COUNT );\
|
||||
log_alert_fat_count = (int)config.Item( ZM_LOG_ALERT_FAT_COUNT );\
|
||||
log_alarm_war_count = (int)config.Item( ZM_LOG_ALARM_WAR_COUNT );\
|
||||
log_alarm_err_count = (int)config.Item( ZM_LOG_ALARM_ERR_COUNT );\
|
||||
log_alarm_fat_count = (int)config.Item( ZM_LOG_ALARM_FAT_COUNT );\
|
||||
record_event_stats = (bool)config.Item( ZM_RECORD_EVENT_STATS );\
|
||||
record_diag_images = (bool)config.Item( ZM_RECORD_DIAG_IMAGES );\
|
||||
dump_cores = (bool)config.Item( ZM_DUMP_CORES );\
|
||||
path_map = (const char *)config.Item( ZM_PATH_MAP );\
|
||||
path_socks = (const char *)config.Item( ZM_PATH_SOCKS );\
|
||||
path_logs = (const char *)config.Item( ZM_PATH_LOGS );\
|
||||
path_swap = (const char *)config.Item( ZM_PATH_SWAP );\
|
||||
web_title_prefix = (const char *)config.Item( ZM_WEB_TITLE_PREFIX );\
|
||||
web_resize_console = (bool)config.Item( ZM_WEB_RESIZE_CONSOLE );\
|
||||
web_popup_on_alarm = (bool)config.Item( ZM_WEB_POPUP_ON_ALARM );\
|
||||
opt_x10 = (bool)config.Item( ZM_OPT_X10 );\
|
||||
x10_device = (const char *)config.Item( ZM_X10_DEVICE );\
|
||||
x10_house_code = (const char *)config.Item( ZM_X10_HOUSE_CODE );\
|
||||
x10_db_reload_interval = (int)config.Item( ZM_X10_DB_RELOAD_INTERVAL );\
|
||||
web_sound_on_alarm = (bool)config.Item( ZM_WEB_SOUND_ON_ALARM );\
|
||||
web_alarm_sound = (const char *)config.Item( ZM_WEB_ALARM_SOUND );\
|
||||
web_compact_montage = (bool)config.Item( ZM_WEB_COMPACT_MONTAGE );\
|
||||
opt_fast_delete = (bool)config.Item( ZM_OPT_FAST_DELETE );\
|
||||
strict_video_config = (bool)config.Item( ZM_STRICT_VIDEO_CONFIG );\
|
||||
signal_check_points = (int)config.Item( ZM_SIGNAL_CHECK_POINTS );\
|
||||
v4l_multi_buffer = (bool)config.Item( ZM_V4L_MULTI_BUFFER );\
|
||||
captures_per_frame = (int)config.Item( ZM_CAPTURES_PER_FRAME );\
|
||||
filter_reload_delay = (int)config.Item( ZM_FILTER_RELOAD_DELAY );\
|
||||
filter_execute_interval = (int)config.Item( ZM_FILTER_EXECUTE_INTERVAL );\
|
||||
opt_upload = (bool)config.Item( ZM_OPT_UPLOAD );\
|
||||
upload_arch_format = (const char *)config.Item( ZM_UPLOAD_ARCH_FORMAT );\
|
||||
upload_arch_compress = (bool)config.Item( ZM_UPLOAD_ARCH_COMPRESS );\
|
||||
upload_arch_analyse = (bool)config.Item( ZM_UPLOAD_ARCH_ANALYSE );\
|
||||
upload_protocol = (const char *)config.Item( ZM_UPLOAD_PROTOCOL );\
|
||||
upload_ftp_host = (const char *)config.Item( ZM_UPLOAD_FTP_HOST );\
|
||||
upload_host = (const char *)config.Item( ZM_UPLOAD_HOST );\
|
||||
upload_port = (int)config.Item( ZM_UPLOAD_PORT );\
|
||||
upload_ftp_user = (const char *)config.Item( ZM_UPLOAD_FTP_USER );\
|
||||
upload_user = (const char *)config.Item( ZM_UPLOAD_USER );\
|
||||
upload_ftp_pass = (const char *)config.Item( ZM_UPLOAD_FTP_PASS );\
|
||||
upload_pass = (const char *)config.Item( ZM_UPLOAD_PASS );\
|
||||
upload_ftp_loc_dir = (const char *)config.Item( ZM_UPLOAD_FTP_LOC_DIR );\
|
||||
upload_loc_dir = (const char *)config.Item( ZM_UPLOAD_LOC_DIR );\
|
||||
upload_ftp_rem_dir = (const char *)config.Item( ZM_UPLOAD_FTP_REM_DIR );\
|
||||
upload_rem_dir = (const char *)config.Item( ZM_UPLOAD_REM_DIR );\
|
||||
upload_ftp_timeout = (int)config.Item( ZM_UPLOAD_FTP_TIMEOUT );\
|
||||
upload_timeout = (int)config.Item( ZM_UPLOAD_TIMEOUT );\
|
||||
upload_ftp_passive = (bool)config.Item( ZM_UPLOAD_FTP_PASSIVE );\
|
||||
upload_ftp_debug = (bool)config.Item( ZM_UPLOAD_FTP_DEBUG );\
|
||||
upload_debug = (bool)config.Item( ZM_UPLOAD_DEBUG );\
|
||||
opt_email = (bool)config.Item( ZM_OPT_EMAIL );\
|
||||
email_address = (const char *)config.Item( ZM_EMAIL_ADDRESS );\
|
||||
email_text = (const char *)config.Item( ZM_EMAIL_TEXT );\
|
||||
email_subject = (const char *)config.Item( ZM_EMAIL_SUBJECT );\
|
||||
email_body = (const char *)config.Item( ZM_EMAIL_BODY );\
|
||||
opt_message = (bool)config.Item( ZM_OPT_MESSAGE );\
|
||||
message_address = (const char *)config.Item( ZM_MESSAGE_ADDRESS );\
|
||||
message_text = (const char *)config.Item( ZM_MESSAGE_TEXT );\
|
||||
message_subject = (const char *)config.Item( ZM_MESSAGE_SUBJECT );\
|
||||
message_body = (const char *)config.Item( ZM_MESSAGE_BODY );\
|
||||
new_mail_modules = (bool)config.Item( ZM_NEW_MAIL_MODULES );\
|
||||
email_host = (const char *)config.Item( ZM_EMAIL_HOST );\
|
||||
from_email = (const char *)config.Item( ZM_FROM_EMAIL );\
|
||||
url = (const char *)config.Item( ZM_URL );\
|
||||
max_restart_delay = (int)config.Item( ZM_MAX_RESTART_DELAY );\
|
||||
watch_check_interval = (int)config.Item( ZM_WATCH_CHECK_INTERVAL );\
|
||||
watch_max_delay = (double) config.Item( ZM_WATCH_MAX_DELAY );\
|
||||
run_audit = (bool)config.Item( ZM_RUN_AUDIT );\
|
||||
audit_check_interval = (int)config.Item( ZM_AUDIT_CHECK_INTERVAL );\
|
||||
forced_alarm_score = (int)config.Item( ZM_FORCED_ALARM_SCORE );\
|
||||
bulk_frame_interval = (int)config.Item( ZM_BULK_FRAME_INTERVAL );\
|
||||
event_close_mode = (const char *)config.Item( ZM_EVENT_CLOSE_MODE );\
|
||||
force_close_events = (bool)config.Item( ZM_FORCE_CLOSE_EVENTS );\
|
||||
create_analysis_images = (bool)config.Item( ZM_CREATE_ANALYSIS_IMAGES );\
|
||||
weighted_alarm_centres = (bool)config.Item( ZM_WEIGHTED_ALARM_CENTRES );\
|
||||
event_image_digits = (int)config.Item( ZM_EVENT_IMAGE_DIGITS );\
|
||||
default_aspect_ratio = (const char *)config.Item( ZM_DEFAULT_ASPECT_RATIO );\
|
||||
user_self_edit = (bool)config.Item( ZM_USER_SELF_EDIT );\
|
||||
opt_frame_server = (bool)config.Item( ZM_OPT_FRAME_SERVER );\
|
||||
frame_socket_size = (int)config.Item( ZM_FRAME_SOCKET_SIZE );\
|
||||
opt_control = (bool)config.Item( ZM_OPT_CONTROL );\
|
||||
opt_triggers = (bool)config.Item( ZM_OPT_TRIGGERS );\
|
||||
check_for_updates = (bool)config.Item( ZM_CHECK_FOR_UPDATES );\
|
||||
update_check_proxy = (const char *)config.Item( ZM_UPDATE_CHECK_PROXY );\
|
||||
shm_key = (int)config.Item( ZM_SHM_KEY );\
|
||||
web_refresh_method = (const char *)config.Item( ZM_WEB_REFRESH_METHOD );\
|
||||
web_event_sort_field = (const char *)config.Item( ZM_WEB_EVENT_SORT_FIELD );\
|
||||
web_event_sort_order = (const char *)config.Item( ZM_WEB_EVENT_SORT_ORDER );\
|
||||
web_events_per_page = (int)config.Item( ZM_WEB_EVENTS_PER_PAGE );\
|
||||
web_list_thumbs = (bool)config.Item( ZM_WEB_LIST_THUMBS );\
|
||||
web_list_thumb_width = (int)config.Item( ZM_WEB_LIST_THUMB_WIDTH );\
|
||||
web_list_thumb_height = (int)config.Item( ZM_WEB_LIST_THUMB_HEIGHT );\
|
||||
web_use_object_tags = (bool)config.Item( ZM_WEB_USE_OBJECT_TAGS );\
|
||||
web_h_refresh_main = (int)config.Item( ZM_WEB_H_REFRESH_MAIN );\
|
||||
web_h_refresh_cycle = (int)config.Item( ZM_WEB_H_REFRESH_CYCLE );\
|
||||
web_h_refresh_image = (int)config.Item( ZM_WEB_H_REFRESH_IMAGE );\
|
||||
web_h_refresh_status = (int)config.Item( ZM_WEB_H_REFRESH_STATUS );\
|
||||
web_h_refresh_events = (int)config.Item( ZM_WEB_H_REFRESH_EVENTS );\
|
||||
web_h_can_stream = (const char *)config.Item( ZM_WEB_H_CAN_STREAM );\
|
||||
web_h_stream_method = (const char *)config.Item( ZM_WEB_H_STREAM_METHOD );\
|
||||
web_h_default_scale = (int)config.Item( ZM_WEB_H_DEFAULT_SCALE );\
|
||||
web_h_default_rate = (int)config.Item( ZM_WEB_H_DEFAULT_RATE );\
|
||||
web_h_video_bitrate = (int)config.Item( ZM_WEB_H_VIDEO_BITRATE );\
|
||||
web_h_video_maxfps = (int)config.Item( ZM_WEB_H_VIDEO_MAXFPS );\
|
||||
web_h_scale_thumbs = (bool)config.Item( ZM_WEB_H_SCALE_THUMBS );\
|
||||
web_h_events_view = (const char *)config.Item( ZM_WEB_H_EVENTS_VIEW );\
|
||||
web_h_show_progress = (bool)config.Item( ZM_WEB_H_SHOW_PROGRESS );\
|
||||
web_h_ajax_timeout = (int)config.Item( ZM_WEB_H_AJAX_TIMEOUT );\
|
||||
web_m_refresh_main = (int)config.Item( ZM_WEB_M_REFRESH_MAIN );\
|
||||
web_m_refresh_cycle = (int)config.Item( ZM_WEB_M_REFRESH_CYCLE );\
|
||||
web_m_refresh_image = (int)config.Item( ZM_WEB_M_REFRESH_IMAGE );\
|
||||
web_m_refresh_status = (int)config.Item( ZM_WEB_M_REFRESH_STATUS );\
|
||||
web_m_refresh_events = (int)config.Item( ZM_WEB_M_REFRESH_EVENTS );\
|
||||
web_m_can_stream = (const char *)config.Item( ZM_WEB_M_CAN_STREAM );\
|
||||
web_m_stream_method = (const char *)config.Item( ZM_WEB_M_STREAM_METHOD );\
|
||||
web_m_default_scale = (int)config.Item( ZM_WEB_M_DEFAULT_SCALE );\
|
||||
web_m_default_rate = (int)config.Item( ZM_WEB_M_DEFAULT_RATE );\
|
||||
web_m_video_bitrate = (int)config.Item( ZM_WEB_M_VIDEO_BITRATE );\
|
||||
web_m_video_maxfps = (int)config.Item( ZM_WEB_M_VIDEO_MAXFPS );\
|
||||
web_m_scale_thumbs = (bool)config.Item( ZM_WEB_M_SCALE_THUMBS );\
|
||||
web_m_events_view = (const char *)config.Item( ZM_WEB_M_EVENTS_VIEW );\
|
||||
web_m_show_progress = (bool)config.Item( ZM_WEB_M_SHOW_PROGRESS );\
|
||||
web_m_ajax_timeout = (int)config.Item( ZM_WEB_M_AJAX_TIMEOUT );\
|
||||
web_l_refresh_main = (int)config.Item( ZM_WEB_L_REFRESH_MAIN );\
|
||||
web_l_refresh_cycle = (int)config.Item( ZM_WEB_L_REFRESH_CYCLE );\
|
||||
web_l_refresh_image = (int)config.Item( ZM_WEB_L_REFRESH_IMAGE );\
|
||||
web_l_refresh_status = (int)config.Item( ZM_WEB_L_REFRESH_STATUS );\
|
||||
web_l_refresh_events = (int)config.Item( ZM_WEB_L_REFRESH_EVENTS );\
|
||||
web_l_can_stream = (const char *)config.Item( ZM_WEB_L_CAN_STREAM );\
|
||||
web_l_stream_method = (const char *)config.Item( ZM_WEB_L_STREAM_METHOD );\
|
||||
web_l_default_scale = (int)config.Item( ZM_WEB_L_DEFAULT_SCALE );\
|
||||
web_l_default_rate = (int)config.Item( ZM_WEB_L_DEFAULT_RATE );\
|
||||
web_l_video_bitrate = (int)config.Item( ZM_WEB_L_VIDEO_BITRATE );\
|
||||
web_l_video_maxfps = (int)config.Item( ZM_WEB_L_VIDEO_MAXFPS );\
|
||||
web_l_scale_thumbs = (bool)config.Item( ZM_WEB_L_SCALE_THUMBS );\
|
||||
web_l_events_view = (const char *)config.Item( ZM_WEB_L_EVENTS_VIEW );\
|
||||
web_l_show_progress = (bool)config.Item( ZM_WEB_L_SHOW_PROGRESS );\
|
||||
web_l_ajax_timeout = (int)config.Item( ZM_WEB_L_AJAX_TIMEOUT );\
|
||||
web_p_can_stream = (const char *)config.Item( ZM_WEB_P_CAN_STREAM );\
|
||||
web_p_stream_method = (const char *)config.Item( ZM_WEB_P_STREAM_METHOD );\
|
||||
web_p_default_scale = (int)config.Item( ZM_WEB_P_DEFAULT_SCALE );\
|
||||
web_p_default_rate = (int)config.Item( ZM_WEB_P_DEFAULT_RATE );\
|
||||
web_p_video_bitrate = (int)config.Item( ZM_WEB_P_VIDEO_BITRATE );\
|
||||
web_p_video_maxfps = (int)config.Item( ZM_WEB_P_VIDEO_MAXFPS );\
|
||||
web_p_scale_thumbs = (bool)config.Item( ZM_WEB_P_SCALE_THUMBS );\
|
||||
web_p_ajax_timeout = (int)config.Item( ZM_WEB_P_AJAX_TIMEOUT );\
|
||||
dyn_last_version = (const char *)config.Item( ZM_DYN_LAST_VERSION );\
|
||||
dyn_curr_version = (const char *)config.Item( ZM_DYN_CURR_VERSION );\
|
||||
dyn_db_version = (const char *)config.Item( ZM_DYN_DB_VERSION );\
|
||||
dyn_last_check = (int)config.Item( ZM_DYN_LAST_CHECK );\
|
||||
dyn_next_reminder = (const char *)config.Item( ZM_DYN_NEXT_REMINDER );\
|
||||
dyn_donate_reminder_time = (int)config.Item( ZM_DYN_DONATE_REMINDER_TIME );\
|
||||
dyn_show_donate_reminder = (bool)config.Item( ZM_DYN_SHOW_DONATE_REMINDER );\
|
||||
eyezm_debug = (bool)config.Item( ZM_EYEZM_DEBUG );\
|
||||
eyezm_log_to_file = (bool)config.Item( ZM_EYEZM_LOG_TO_FILE );\
|
||||
eyezm_log_file = (const char *)config.Item( ZM_EYEZM_LOG_FILE );\
|
||||
eyezm_event_vcodec = (const char *)config.Item( ZM_EYEZM_EVENT_VCODEC );\
|
||||
eyezm_feed_vcodec = (const char *)config.Item( ZM_EYEZM_FEED_VCODEC );\
|
||||
eyezm_h264_default_br = (const char *)config.Item( ZM_EYEZM_H264_DEFAULT_BR );\
|
||||
eyezm_h264_default_evbr = (const char *)config.Item( ZM_EYEZM_H264_DEFAULT_EVBR );\
|
||||
eyezm_h264_timeout = (const char *)config.Item( ZM_EYEZM_H264_TIMEOUT );\
|
||||
eyezm_seg_duration = (const char *)config.Item( ZM_EYEZM_SEG_DURATION );\
|
||||
|
||||
|
115
src/zm_event.cpp
115
src/zm_event.cpp
|
@ -48,6 +48,7 @@ bool Event::initialised = false;
|
|||
char Event::capture_file_format[PATH_MAX];
|
||||
char Event::analyse_file_format[PATH_MAX];
|
||||
char Event::general_file_format[PATH_MAX];
|
||||
char Event::video_file_format[PATH_MAX];
|
||||
|
||||
int Event::pre_alarm_count = 0;
|
||||
Event::PreAlarmData Event::pre_alarm_data[MAX_PRE_ALARM_FRAMES] = { { 0 } };
|
||||
|
@ -161,6 +162,48 @@ Event::Event( Monitor *p_monitor, struct timeval p_start_time, const std::string
|
|||
Fatal( "Can't fopen %s: %s", id_file, strerror(errno));
|
||||
}
|
||||
last_db_frame = 0;
|
||||
|
||||
video_name[0] = 0;
|
||||
|
||||
/* Save as video */
|
||||
if ( monitor->GetOptVideoWriter() != 0 ) {
|
||||
int nRet;
|
||||
snprintf( video_name, sizeof(video_name), "%d-%s", id, "video.mp4" );
|
||||
snprintf( video_file, sizeof(video_file), video_file_format, path, video_name );
|
||||
snprintf( timecodes_name, sizeof(timecodes_name), "%d-%s", id, "video.timecodes" );
|
||||
snprintf( timecodes_file, sizeof(timecodes_file), video_file_format, path, timecodes_name );
|
||||
|
||||
|
||||
/* X264 MP4 video writer */
|
||||
if(monitor->GetOptVideoWriter() == 1) {
|
||||
#if ZM_HAVE_VIDEOWRITER_X264MP4
|
||||
videowriter = new X264MP4Writer(video_file, monitor->Width(), monitor->Height(), monitor->Colours(), monitor->SubpixelOrder(), monitor->GetOptEncoderParams());
|
||||
#else
|
||||
videowriter = NULL;
|
||||
Error("ZoneMinder was not compiled with the X264 MP4 video writer, check dependencies (x264 and mp4v2)");
|
||||
#endif
|
||||
}
|
||||
|
||||
if(videowriter != NULL) {
|
||||
/* Open the video stream */
|
||||
nRet = videowriter->Open();
|
||||
if(nRet != 0) {
|
||||
Error("Failed opening video stream");
|
||||
delete videowriter;
|
||||
videowriter = NULL;
|
||||
}
|
||||
|
||||
/* Create timecodes file */
|
||||
timecodes_fd = fopen(timecodes_file, "wb");
|
||||
if(timecodes_fd == NULL) {
|
||||
Error("Failed creating timecodes file");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* No video object */
|
||||
videowriter = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Event::~Event()
|
||||
|
@ -180,12 +223,28 @@ Event::~Event()
|
|||
}
|
||||
}
|
||||
|
||||
/* Close the video file */
|
||||
if ( videowriter != NULL ) {
|
||||
int nRet;
|
||||
|
||||
nRet = videowriter->Close();
|
||||
if(nRet != 0) {
|
||||
Error("Failed closing video stream");
|
||||
}
|
||||
delete videowriter;
|
||||
videowriter = NULL;
|
||||
|
||||
/* Close the timecodes file */
|
||||
fclose(timecodes_fd);
|
||||
timecodes_fd = NULL;
|
||||
}
|
||||
|
||||
static char sql[ZM_SQL_MED_BUFSIZ];
|
||||
|
||||
struct DeltaTimeval delta_time;
|
||||
DELTA_TIMEVAL( delta_time, end_time, start_time, DT_PREC_2 );
|
||||
|
||||
snprintf( sql, sizeof(sql), "update Events set Name='%s%d', EndTime = from_unixtime( %ld ), Length = %s%ld.%02ld, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d where Id = %d", monitor->EventPrefix(), id, end_time.tv_sec, delta_time.positive?"":"-", delta_time.sec, delta_time.fsec, frames, alarm_frames, tot_score, (int)(alarm_frames?(tot_score/alarm_frames):0), max_score, id );
|
||||
snprintf( sql, sizeof(sql), "update Events set Name='%s%d', EndTime = from_unixtime( %ld ), Length = %s%ld.%02ld, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d, DefaultVideo = '%s' where Id = %d", monitor->EventPrefix(), id, end_time.tv_sec, delta_time.positive?"":"-", delta_time.sec, delta_time.fsec, frames, alarm_frames, tot_score, (int)(alarm_frames?(tot_score/alarm_frames):0), max_score, video_name, id );
|
||||
if ( mysql_query( &dbconn, sql ) )
|
||||
{
|
||||
Error( "Can't update event: %s", mysql_error( &dbconn ) );
|
||||
|
@ -368,6 +427,40 @@ bool Event::WriteFrameImage( Image *image, struct timeval timestamp, const char
|
|||
return( true );
|
||||
}
|
||||
|
||||
bool Event::WriteFrameVideo( const Image *image, const struct timeval timestamp, VideoWriter* videow )
|
||||
{
|
||||
const Image* frameimg = image;
|
||||
Image ts_image;
|
||||
|
||||
/* Checking for invalid parameters */
|
||||
if ( videow == NULL ) {
|
||||
Error("NULL Video object");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If the image does not contain a timestamp, add the timestamp */
|
||||
if (!config.timestamp_on_capture) {
|
||||
ts_image = *image;
|
||||
monitor->TimestampImage( &ts_image, ×tamp );
|
||||
frameimg = &ts_image;
|
||||
}
|
||||
|
||||
/* Calculate delta time */
|
||||
struct DeltaTimeval delta_time3;
|
||||
DELTA_TIMEVAL( delta_time3, timestamp, start_time, DT_PREC_3 );
|
||||
unsigned int timeMS = (delta_time3.sec * delta_time3.prec) + delta_time3.fsec;
|
||||
|
||||
/* Encode and write the frame */
|
||||
if(videowriter->Encode(image, timeMS) != 0) {
|
||||
Error("Failed encoding video frame");
|
||||
}
|
||||
|
||||
/* Add the frame to the timecodes file */
|
||||
fprintf(timecodes_fd, "%u\n", timeMS);
|
||||
|
||||
return( true );
|
||||
}
|
||||
|
||||
void Event::updateNotes( const StringSetMap &newNoteSetMap )
|
||||
{
|
||||
bool update = false;
|
||||
|
@ -514,7 +607,13 @@ void Event::AddFramesInternal( int n_frames, int start_frame, Image **images, st
|
|||
snprintf( event_file, sizeof(event_file), capture_file_format, path, frames );
|
||||
|
||||
Debug( 1, "Writing pre-capture frame %d", frames );
|
||||
WriteFrameImage( images[i], *(timestamps[i]), event_file );
|
||||
if ( monitor->GetOptSaveJPEGs() & 1) {
|
||||
WriteFrameImage( images[i], *(timestamps[i]), event_file );
|
||||
}
|
||||
|
||||
if ( videowriter != NULL ) {
|
||||
WriteFrameVideo( images[i], *(timestamps[i]), videowriter );
|
||||
}
|
||||
|
||||
struct DeltaTimeval delta_time;
|
||||
DELTA_TIMEVAL( delta_time, *(timestamps[i]), start_time, DT_PREC_2 );
|
||||
|
@ -556,7 +655,13 @@ void Event::AddFrame( Image *image, struct timeval timestamp, int score, Image *
|
|||
snprintf( event_file, sizeof(event_file), capture_file_format, path, frames );
|
||||
|
||||
Debug( 1, "Writing capture frame %d", frames );
|
||||
WriteFrameImage( image, timestamp, event_file );
|
||||
if( monitor->GetOptSaveJPEGs() & 1) {
|
||||
WriteFrameImage( image, timestamp, event_file );
|
||||
}
|
||||
|
||||
if ( videowriter != NULL ) {
|
||||
WriteFrameVideo( image, timestamp, videowriter );
|
||||
}
|
||||
|
||||
struct DeltaTimeval delta_time;
|
||||
DELTA_TIMEVAL( delta_time, timestamp, start_time, DT_PREC_2 );
|
||||
|
@ -604,7 +709,9 @@ void Event::AddFrame( Image *image, struct timeval timestamp, int score, Image *
|
|||
snprintf( event_file, sizeof(event_file), analyse_file_format, path, frames );
|
||||
|
||||
Debug( 1, "Writing analysis frame %d", frames );
|
||||
WriteFrameImage( alarm_image, timestamp, event_file, true );
|
||||
if ( monitor->GetOptSaveJPEGs() & 2) {
|
||||
WriteFrameImage( alarm_image, timestamp, event_file, true );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "zm.h"
|
||||
#include "zm_image.h"
|
||||
#include "zm_stream.h"
|
||||
#include "zm_video.h"
|
||||
|
||||
class Zone;
|
||||
class Monitor;
|
||||
|
@ -55,6 +56,7 @@ protected:
|
|||
static char capture_file_format[PATH_MAX];
|
||||
static char analyse_file_format[PATH_MAX];
|
||||
static char general_file_format[PATH_MAX];
|
||||
static char video_file_format[PATH_MAX];
|
||||
|
||||
protected:
|
||||
static int sd;
|
||||
|
@ -89,6 +91,12 @@ protected:
|
|||
unsigned int tot_score;
|
||||
unsigned int max_score;
|
||||
char path[PATH_MAX];
|
||||
VideoWriter* videowriter;
|
||||
FILE* timecodes_fd;
|
||||
char video_name[PATH_MAX];
|
||||
char video_file[PATH_MAX];
|
||||
char timecodes_name[PATH_MAX];
|
||||
char timecodes_file[PATH_MAX];
|
||||
|
||||
protected:
|
||||
int last_db_frame;
|
||||
|
@ -102,6 +110,7 @@ protected:
|
|||
snprintf( capture_file_format, sizeof(capture_file_format), "%%s/%%0%dd-capture.jpg", config.event_image_digits );
|
||||
snprintf( analyse_file_format, sizeof(analyse_file_format), "%%s/%%0%dd-analyse.jpg", config.event_image_digits );
|
||||
snprintf( general_file_format, sizeof(general_file_format), "%%s/%%0%dd-%%s", config.event_image_digits );
|
||||
snprintf( video_file_format, sizeof(video_file_format), "%%s/%%s");
|
||||
|
||||
initialised = true;
|
||||
}
|
||||
|
@ -127,6 +136,7 @@ public:
|
|||
|
||||
bool SendFrameImage( const Image *image, bool alarm_frame=false );
|
||||
bool WriteFrameImage( Image *image, struct timeval timestamp, const char *event_file, bool alarm_frame=false );
|
||||
bool WriteFrameVideo( const Image *image, const struct timeval timestamp, VideoWriter* videow );
|
||||
|
||||
void updateNotes( const StringSetMap &stringSetMap );
|
||||
|
||||
|
|
|
@ -23,6 +23,16 @@
|
|||
|
||||
#if HAVE_LIBAVCODEC || HAVE_LIBAVUTIL || HAVE_LIBSWSCALE
|
||||
|
||||
void FFMPEGInit() {
|
||||
static bool bInit = false;
|
||||
|
||||
if(!bInit) {
|
||||
av_register_all();
|
||||
av_log_set_level(AV_LOG_DEBUG);
|
||||
bInit = true;
|
||||
}
|
||||
}
|
||||
|
||||
#if HAVE_LIBAVUTIL
|
||||
enum PixelFormat GetFFMPEGPixelFormat(unsigned int p_colours, unsigned p_subpixelorder) {
|
||||
enum PixelFormat pf;
|
||||
|
@ -124,10 +134,7 @@ int SWScale::Convert(const uint8_t* in_buffer, const size_t in_buffer_size, uint
|
|||
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;
|
||||
|
@ -154,7 +161,7 @@ int SWScale::Convert(const uint8_t* in_buffer, const size_t in_buffer_size, uint
|
|||
}
|
||||
|
||||
/* Get the context */
|
||||
swscale_ctx = sws_getCachedContext( NULL, width, height, in_pf, width, height, out_pf, 0, NULL, NULL, NULL );
|
||||
swscale_ctx = sws_getCachedContext( NULL, width, height, in_pf, width, height, out_pf, SWS_FAST_BILINEAR, NULL, NULL, NULL );
|
||||
if(swscale_ctx == NULL) {
|
||||
Error("Failed getting swscale context");
|
||||
return -6;
|
||||
|
|
|
@ -97,6 +97,8 @@ extern "C" {
|
|||
#define SWS_CPU_CAPS_SSE2 0x02000000
|
||||
#endif
|
||||
|
||||
/* A single function to initialize ffmpeg, to avoid multiple initializations */
|
||||
void FFMPEGInit();
|
||||
|
||||
#if HAVE_LIBAVUTIL
|
||||
enum PixelFormat GetFFMPEGPixelFormat(unsigned int p_colours, unsigned p_subpixelorder);
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "zm_mpeg.h"
|
||||
#include "zm_signal.h"
|
||||
#include "zm_monitor.h"
|
||||
#include "zm_video.h"
|
||||
#if ZM_HAS_V4L
|
||||
#include "zm_local_camera.h"
|
||||
#endif // ZM_HAS_V4L
|
||||
|
@ -274,6 +275,9 @@ Monitor::Monitor(
|
|||
Camera *p_camera,
|
||||
int p_orientation,
|
||||
unsigned int p_deinterlacing,
|
||||
int p_savejpegs,
|
||||
int p_videowriter,
|
||||
std::string p_encoderparams,
|
||||
const char *p_event_prefix,
|
||||
const char *p_label_format,
|
||||
const Coord &p_label_coord,
|
||||
|
@ -302,6 +306,9 @@ Monitor::Monitor(
|
|||
height( (p_orientation==ROTATE_90||p_orientation==ROTATE_270)?p_camera->Width():p_camera->Height() ),
|
||||
orientation( (Orientation)p_orientation ),
|
||||
deinterlacing( p_deinterlacing ),
|
||||
savejpegspref( p_savejpegs ),
|
||||
videowriterpref( p_videowriter ),
|
||||
encoderparams( p_encoderparams ),
|
||||
label_coord( p_label_coord ),
|
||||
image_buffer_count( p_image_buffer_count ),
|
||||
warmup_count( p_warmup_count ),
|
||||
|
@ -348,6 +355,9 @@ Monitor::Monitor(
|
|||
}
|
||||
}
|
||||
|
||||
/* Parse encoder parameters */
|
||||
ParseEncoderParameters(encoderparams.c_str(), &encoderparamsvec);
|
||||
|
||||
fps = 0.0;
|
||||
event_count = 0;
|
||||
image_count = 0;
|
||||
|
@ -1827,11 +1837,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, AlarmRefBlendPerc, 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, SaveJPEGs, VideoWriter, EncoderParameters, 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, AlarmRefBlendPerc, 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, SaveJPEGs, VideoWriter, EncoderParameters, 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 ) )
|
||||
{
|
||||
|
@ -1870,6 +1880,11 @@ int Monitor::LoadLocalMonitors( const char *device, Monitor **&monitors, Purpose
|
|||
int palette = atoi(dbrow[col]); col++;
|
||||
Orientation orientation = (Orientation)atoi(dbrow[col]); col++;
|
||||
unsigned int deinterlacing = atoi(dbrow[col]); col++;
|
||||
|
||||
int savejpegs = atoi(dbrow[col]); col++;
|
||||
int videowriter = atoi(dbrow[col]); col++;
|
||||
std::string encoderparams = dbrow[col]; col++;
|
||||
|
||||
int brightness = atoi(dbrow[col]); col++;
|
||||
int contrast = atoi(dbrow[col]); col++;
|
||||
int hue = atoi(dbrow[col]); col++;
|
||||
|
@ -1935,6 +1950,9 @@ int Monitor::LoadLocalMonitors( const char *device, Monitor **&monitors, Purpose
|
|||
camera,
|
||||
orientation,
|
||||
deinterlacing,
|
||||
savejpegs,
|
||||
videowriter,
|
||||
encoderparams,
|
||||
event_prefix,
|
||||
label_format,
|
||||
Coord( label_x, label_y ),
|
||||
|
@ -1979,11 +1997,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, AlarmRefBlendPerc, 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, SaveJPEGs, VideoWriter, EncoderParameters, 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, 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 );
|
||||
snprintf( sql, sizeof(sql), "select Id, Name, Function+0, Enabled, LinkedMonitors, Protocol, Method, Host, Port, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, SaveJPEGs, VideoWriter, EncoderParameters, 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 ) )
|
||||
{
|
||||
|
@ -2022,7 +2040,12 @@ int Monitor::LoadRemoteMonitors( const char *protocol, const char *host, const c
|
|||
int colours = atoi(dbrow[col]); col++;
|
||||
/* int palette = atoi(dbrow[col]); */ col++;
|
||||
Orientation orientation = (Orientation)atoi(dbrow[col]); col++;
|
||||
unsigned int deinterlacing = atoi(dbrow[col]); col++;
|
||||
unsigned int deinterlacing = atoi(dbrow[col]); col++;
|
||||
|
||||
int savejpegs = atoi(dbrow[col]); col++;
|
||||
int videowriter = atoi(dbrow[col]); col++;
|
||||
std::string encoderparams = dbrow[col]; col++;
|
||||
|
||||
int brightness = atoi(dbrow[col]); col++;
|
||||
int contrast = atoi(dbrow[col]); col++;
|
||||
int hue = atoi(dbrow[col]); col++;
|
||||
|
@ -2106,6 +2129,9 @@ int Monitor::LoadRemoteMonitors( const char *protocol, const char *host, const c
|
|||
camera,
|
||||
orientation,
|
||||
deinterlacing,
|
||||
savejpegs,
|
||||
videowriter,
|
||||
encoderparams,
|
||||
event_prefix.c_str(),
|
||||
label_format.c_str(),
|
||||
Coord( label_x, label_y ),
|
||||
|
@ -2150,11 +2176,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, AlarmRefBlendPerc, 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, SaveJPEGs, VideoWriter, EncoderParameters, 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, AlarmRefBlendPerc, 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, SaveJPEGs, VideoWriter, EncoderParameters, 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 ) )
|
||||
{
|
||||
|
@ -2190,6 +2216,11 @@ int Monitor::LoadFileMonitors( const char *file, Monitor **&monitors, Purpose pu
|
|||
/* int palette = atoi(dbrow[col]); */ col++;
|
||||
Orientation orientation = (Orientation)atoi(dbrow[col]); col++;
|
||||
unsigned int deinterlacing = atoi(dbrow[col]); col++;
|
||||
|
||||
int savejpegs = atoi(dbrow[col]); col++;
|
||||
int videowriter = atoi(dbrow[col]); col++;
|
||||
std::string encoderparams = dbrow[col]; col++;
|
||||
|
||||
int brightness = atoi(dbrow[col]); col++;
|
||||
int contrast = atoi(dbrow[col]); col++;
|
||||
int hue = atoi(dbrow[col]); col++;
|
||||
|
@ -2241,6 +2272,9 @@ int Monitor::LoadFileMonitors( const char *file, Monitor **&monitors, Purpose pu
|
|||
camera,
|
||||
orientation,
|
||||
deinterlacing,
|
||||
savejpegs,
|
||||
videowriter,
|
||||
encoderparams,
|
||||
event_prefix,
|
||||
label_format,
|
||||
Coord( label_x, label_y ),
|
||||
|
@ -2286,11 +2320,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, AlarmRefBlendPerc, 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, SaveJPEGs, VideoWriter, EncoderParameters, 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, AlarmRefBlendPerc, 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, SaveJPEGs, VideoWriter, EncoderParameters, 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 ) )
|
||||
{
|
||||
|
@ -2326,6 +2360,11 @@ int Monitor::LoadFfmpegMonitors( const char *file, Monitor **&monitors, Purpose
|
|||
/* int palette = atoi(dbrow[col]); */ col++;
|
||||
Orientation orientation = (Orientation)atoi(dbrow[col]); col++;
|
||||
unsigned int deinterlacing = atoi(dbrow[col]); col++;
|
||||
|
||||
int savejpegs = atoi(dbrow[col]); col++;
|
||||
int videowriter = atoi(dbrow[col]); col++;
|
||||
std::string encoderparams = dbrow[col]; col++;
|
||||
|
||||
int brightness = atoi(dbrow[col]); col++;
|
||||
int contrast = atoi(dbrow[col]); col++;
|
||||
int hue = atoi(dbrow[col]); col++;
|
||||
|
@ -2377,6 +2416,9 @@ int Monitor::LoadFfmpegMonitors( const char *file, Monitor **&monitors, Purpose
|
|||
camera,
|
||||
orientation,
|
||||
deinterlacing,
|
||||
savejpegs,
|
||||
videowriter,
|
||||
encoderparams,
|
||||
event_prefix,
|
||||
label_format,
|
||||
Coord( label_x, label_y ),
|
||||
|
@ -2419,7 +2461,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, 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 );
|
||||
snprintf( sql, sizeof(sql), "select Id, Name, Type, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, Protocol, Method, Host, Port, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, SaveJPEGs, VideoWriter, EncoderParameters, 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 ) );
|
||||
|
@ -2462,6 +2504,11 @@ Monitor *Monitor::Load( int id, bool load_zones, Purpose purpose )
|
|||
int palette = atoi(dbrow[col]); col++;
|
||||
Orientation orientation = (Orientation)atoi(dbrow[col]); col++;
|
||||
unsigned int deinterlacing = atoi(dbrow[col]); col++;
|
||||
|
||||
int savejpegs = atoi(dbrow[col]); col++;
|
||||
int videowriter = atoi(dbrow[col]); col++;
|
||||
std::string encoderparams = dbrow[col]; col++;
|
||||
|
||||
int brightness = atoi(dbrow[col]); col++;
|
||||
int contrast = atoi(dbrow[col]); col++;
|
||||
int hue = atoi(dbrow[col]); col++;
|
||||
|
@ -2618,6 +2665,9 @@ Monitor *Monitor::Load( int id, bool load_zones, Purpose purpose )
|
|||
camera,
|
||||
orientation,
|
||||
deinterlacing,
|
||||
savejpegs,
|
||||
videowriter,
|
||||
encoderparams,
|
||||
event_prefix.c_str(),
|
||||
label_format.c_str(),
|
||||
Coord( label_x, label_y ),
|
||||
|
|
|
@ -239,6 +239,11 @@ protected:
|
|||
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
|
||||
|
||||
int savejpegspref;
|
||||
int videowriterpref;
|
||||
std::string encoderparams;
|
||||
std::vector<EncoderParameter_t> encoderparamsvec;
|
||||
|
||||
double fps;
|
||||
Image delta_image;
|
||||
Image ref_image;
|
||||
|
@ -288,7 +293,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, 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( 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, int p_savejpegs, int p_videowriter, std::string p_encoderparams, 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[] );
|
||||
|
@ -337,7 +342,10 @@ public:
|
|||
unsigned int Height() const { return( height ); }
|
||||
unsigned int Colours() const { return( camera->Colours() ); }
|
||||
unsigned int SubpixelOrder() const { return( camera->SubpixelOrder() ); }
|
||||
|
||||
|
||||
int GetOptSaveJPEGs() const { return( savejpegspref ); }
|
||||
int GetOptVideoWriter() const { return( videowriterpref ); }
|
||||
const std::vector<EncoderParameter_t>* GetOptEncoderParams() const { return( &encoderparamsvec ); }
|
||||
|
||||
State GetState() const;
|
||||
int GetImage( int index=-1, int scale=100 ) const;
|
||||
|
|
|
@ -0,0 +1,492 @@
|
|||
// 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_video.h"
|
||||
#include "zm_image.h"
|
||||
#include "zm_utils.h"
|
||||
#include "zm_rgb.h"
|
||||
#include <sstream>
|
||||
|
||||
VideoWriter::VideoWriter(const char* p_container, const char* p_codec, const char* p_path, const unsigned int p_width, const unsigned int p_height, const unsigned int p_colours, const unsigned int p_subpixelorder) :
|
||||
container(p_container), codec(p_codec), path(p_path), width(p_width), height(p_height), colours(p_colours), subpixelorder(p_subpixelorder), frame_count(0) {
|
||||
Debug(7,"Video object created");
|
||||
|
||||
/* Parameter checking */
|
||||
if(path.empty()) {
|
||||
Error("Invalid file path");
|
||||
}
|
||||
if(!width || !height) {
|
||||
Error("Invalid width or height");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
VideoWriter::~VideoWriter() {
|
||||
Debug(7,"Video object destroyed");
|
||||
|
||||
}
|
||||
|
||||
int VideoWriter::Reset() {
|
||||
/* Common variables reset */
|
||||
|
||||
frame_count = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#if ZM_HAVE_VIDEOWRITER_X264MP4
|
||||
X264MP4Writer::X264MP4Writer(const char* p_path, const unsigned int p_width, const unsigned int p_height, const unsigned int p_colours, const unsigned int p_subpixelorder, const std::vector<EncoderParameter_t>* p_user_params) : VideoWriter("mp4", "h264", p_path, p_width, p_height, p_colours, p_subpixelorder), bOpen(false), bGotH264AVCInfo(false), bFirstFrame(true) {
|
||||
|
||||
/* Initialize ffmpeg if it hasn't been initialized yet */
|
||||
FFMPEGInit();
|
||||
|
||||
/* Initialize swscale */
|
||||
zm_pf = GetFFMPEGPixelFormat(colours,subpixelorder);
|
||||
if(zm_pf == 0) {
|
||||
Error("Unable to match ffmpeg pixelformat");
|
||||
}
|
||||
codec_pf = PIX_FMT_YUV420P;
|
||||
|
||||
swscaleobj.SetDefaults(zm_pf, codec_pf, width, height);
|
||||
|
||||
/* Calculate the image sizes. We will need this for parameter checking */
|
||||
zm_imgsize = colours * width * height;
|
||||
codec_imgsize = avpicture_get_size( codec_pf, width, height);
|
||||
if(!codec_imgsize) {
|
||||
Error("Failed calculating codec pixel format image size");
|
||||
}
|
||||
|
||||
/* If supplied with user parameters to the encoder, copy them */
|
||||
if(p_user_params != NULL) {
|
||||
user_params = *p_user_params;
|
||||
}
|
||||
|
||||
/* Setup x264 parameters */
|
||||
if(x264config() < 0) {
|
||||
Error("Failed setting x264 parameters");
|
||||
}
|
||||
|
||||
/* Allocate x264 input picture */
|
||||
x264_picture_alloc(&x264picin, X264_CSP_I420, x264params.i_width, x264params.i_height);
|
||||
|
||||
}
|
||||
|
||||
X264MP4Writer::~X264MP4Writer() {
|
||||
|
||||
/* Free x264 input picture */
|
||||
x264_picture_clean(&x264picin);
|
||||
|
||||
if(bOpen)
|
||||
Close();
|
||||
|
||||
//x264_picture_clean(&x264picout);
|
||||
|
||||
}
|
||||
|
||||
int X264MP4Writer::Open() {
|
||||
|
||||
/* Open the encoder */
|
||||
x264enc = x264_encoder_open(&x264params);
|
||||
if(x264enc == NULL) {
|
||||
Error("Failed opening x264 encoder");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Debug(4,"x264 maximum delayed frames: %d",x264_encoder_maximum_delayed_frames(x264enc));
|
||||
|
||||
x264_nal_t* nals;
|
||||
int i_nals;
|
||||
if(!x264_encoder_headers(x264enc,&nals,&i_nals)) {
|
||||
Error("Failed getting encoder headers");
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* Search SPS NAL for AVC information */
|
||||
for(int i=0;i<i_nals;i++) {
|
||||
if(nals[i].i_type == NAL_SPS) {
|
||||
x264_profleindication = nals[i].p_payload[5];
|
||||
x264_profilecompat = nals[i].p_payload[6];
|
||||
x264_levelindication = nals[i].p_payload[7];
|
||||
bGotH264AVCInfo = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!bGotH264AVCInfo) {
|
||||
Warning("Missing AVC information");
|
||||
}
|
||||
|
||||
/* Create the file */
|
||||
mp4h = MP4Create((path + ".incomplete").c_str());
|
||||
if(mp4h == MP4_INVALID_FILE_HANDLE) {
|
||||
Error("Failed creating mp4 file: %s",path.c_str());
|
||||
return -10;
|
||||
}
|
||||
|
||||
/* Set the global timescale */
|
||||
if(!MP4SetTimeScale(mp4h, 1000)) {
|
||||
Error("Failed setting timescale");
|
||||
return -11;
|
||||
}
|
||||
|
||||
/* Set the global video profile */
|
||||
/* I am a bit confused about this one.
|
||||
I couldn't find what the value should be
|
||||
Some use 0x15 while others use 0x7f. */
|
||||
MP4SetVideoProfileLevel(mp4h, 0x7f);
|
||||
|
||||
/* Add H264 video track */
|
||||
mp4vtid = MP4AddH264VideoTrack(mp4h,1000,MP4_INVALID_DURATION,width,height,x264_profleindication,x264_profilecompat,x264_levelindication,3);
|
||||
if(mp4vtid == MP4_INVALID_TRACK_ID) {
|
||||
Error("Failed adding H264 video track");
|
||||
return -12;
|
||||
}
|
||||
|
||||
bOpen = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int X264MP4Writer::Close() {
|
||||
|
||||
/* Flush all pending frames */
|
||||
for(int i = (x264_encoder_delayed_frames(x264enc) + 1); i > 0; i-- ) {
|
||||
x264encodeloop(true);
|
||||
}
|
||||
|
||||
/* Close the encoder */
|
||||
x264_encoder_close(x264enc);
|
||||
|
||||
/* Close MP4 handle */
|
||||
MP4Close(mp4h);
|
||||
|
||||
/* Required for proper HTTP streaming */
|
||||
MP4Optimize((path + ".incomplete").c_str(), path.c_str());
|
||||
|
||||
/* Delete the temporary file */
|
||||
unlink((path + ".incomplete").c_str());
|
||||
|
||||
bOpen = false;
|
||||
|
||||
Debug(7, "Video closed. Total frames: %d", frame_count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int X264MP4Writer::Reset() {
|
||||
|
||||
VideoWriter::Reset();
|
||||
|
||||
/* Close the encoder and file */
|
||||
if(bOpen)
|
||||
Close();
|
||||
|
||||
/* Reset variables */
|
||||
bFirstFrame = true;
|
||||
bGotH264AVCInfo = false;
|
||||
prevnals.clear();
|
||||
prevpayload.clear();
|
||||
|
||||
/* Reset x264 parameters */
|
||||
x264config();
|
||||
|
||||
/* Open the encoder */
|
||||
Open();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int X264MP4Writer::Encode(const uint8_t* data, const size_t data_size, const unsigned int frame_time) {
|
||||
|
||||
/* Parameter checking */
|
||||
if(data == NULL) {
|
||||
Error("NULL buffer");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(data_size != zm_imgsize) {
|
||||
Error("The data buffer size does not match the expected size. Expected: %d Current: %d", zm_imgsize, data_size);
|
||||
return -2;
|
||||
}
|
||||
|
||||
if(!bOpen) {
|
||||
Warning("The encoder was not initialized, initializing now");
|
||||
Open();
|
||||
}
|
||||
|
||||
/* Convert the image into the x264 input picture */
|
||||
if(swscaleobj.ConvertDefaults(data, data_size, x264picin.img.plane[0], codec_imgsize) < 0) {
|
||||
Error("Image conversion failed");
|
||||
return -3;
|
||||
}
|
||||
|
||||
/* Set PTS */
|
||||
x264picin.i_pts = frame_time;
|
||||
|
||||
/* Do the encoding */
|
||||
x264encodeloop();
|
||||
|
||||
/* Increment frame counter */
|
||||
frame_count++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int X264MP4Writer::Encode(const Image* img, const unsigned int frame_time) {
|
||||
|
||||
if(img->Width() != width) {
|
||||
Error("Source image width differs. Source: %d Output: %d",img->Width(), width);
|
||||
return -12;
|
||||
}
|
||||
|
||||
if(img->Height() != height) {
|
||||
Error("Source image height differs. Source: %d Output: %d",img->Height(), height);
|
||||
return -13;
|
||||
}
|
||||
|
||||
return Encode(img->Buffer(),img->Size(),frame_time);
|
||||
}
|
||||
|
||||
int X264MP4Writer::x264config() {
|
||||
/* Sets up the encoder configuration */
|
||||
|
||||
/* Set the defaults and enable the superfast preset and the stillimage tune */
|
||||
if(x264_param_default_preset(&x264params,"veryfast","stillimage") != 0) {
|
||||
Error("Failed setting x264 preset and tune");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set profile */
|
||||
if(x264_param_apply_profile(&x264params, "main") != 0) {
|
||||
Error("Failed setting x264 profile");
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* Input format */
|
||||
x264params.i_width = width;
|
||||
x264params.i_height = height;
|
||||
x264params.i_csp = X264_CSP_I420;
|
||||
|
||||
/* Quality control */
|
||||
x264params.rc.i_rc_method = X264_RC_CRF;
|
||||
x264params.rc.f_rf_constant = 23.0;
|
||||
|
||||
/* Enable b-frames */
|
||||
x264params.i_bframe = 16;
|
||||
x264params.i_bframe_adaptive = 1;
|
||||
|
||||
/* Timebase */
|
||||
x264params.i_timebase_num = 1;
|
||||
x264params.i_timebase_den = 1000;
|
||||
|
||||
/* Enable variable frame rate */
|
||||
x264params.b_vfr_input = 1;
|
||||
|
||||
/* Disable annex-b (start codes) */
|
||||
x264params.b_annexb = 0;
|
||||
|
||||
/* TODO: Setup error handler */
|
||||
//x264params.i_log_level = X264_LOG_DEBUG;
|
||||
|
||||
/* Process user parameters */
|
||||
x264userparams();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int X264MP4Writer::x264userparams() {
|
||||
/* Passes user parameters (for the encoder) to x264 */
|
||||
int x264ret;
|
||||
|
||||
for(unsigned int i=0; i < user_params.size(); i++) {
|
||||
x264ret = x264_param_parse(&x264params, user_params[i].pname, user_params[i].pvalue);
|
||||
|
||||
/* Error checking */
|
||||
if(x264ret != 0) {
|
||||
if(x264ret == X264_PARAM_BAD_NAME) {
|
||||
Error("Failed parsing x264 user parameter %s=%s : Bad name", user_params[i].pname, user_params[i].pvalue);
|
||||
} else if(x264ret == X264_PARAM_BAD_VALUE) {
|
||||
Error("Failed parsing x264 user parameter %s=%s : Bad value", user_params[i].pname, user_params[i].pvalue);
|
||||
} else {
|
||||
Error("Failed parsing x264 user parameter %s=%s : Unknown error (%d)", user_params[i].pname, user_params[i].pvalue, x264ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void X264MP4Writer::x264encodeloop(bool bFlush) {
|
||||
|
||||
x264_nal_t* nals;
|
||||
int i_nals;
|
||||
int frame_size;
|
||||
|
||||
if(bFlush) {
|
||||
frame_size = x264_encoder_encode(x264enc, &nals, &i_nals, NULL, &x264picout);
|
||||
} else {
|
||||
frame_size = x264_encoder_encode(x264enc, &nals, &i_nals, &x264picin, &x264picout);
|
||||
}
|
||||
|
||||
if (frame_size > 0 || bFlush) {
|
||||
Debug(8, "x264 Frame: %d PTS: %d DTS: %d Size: %d\n",frame_count, x264picout.i_pts, x264picout.i_dts, frame_size);
|
||||
|
||||
/* Handle the previous frame */
|
||||
if(!bFirstFrame) {
|
||||
|
||||
/* Process the NALs for the previous frame */
|
||||
for(unsigned int i=0; i < prevnals.size(); i++) {
|
||||
Debug(9,"Processing NAL: Type %d Size %d",prevnals[i].i_type,prevnals[i].i_payload);
|
||||
|
||||
switch(prevnals[i].i_type) {
|
||||
case NAL_PPS:
|
||||
/* PPS NAL */
|
||||
MP4AddH264PictureParameterSet(mp4h, mp4vtid, prevnals[i].p_payload+4, prevnals[i].i_payload-4);
|
||||
break;
|
||||
case NAL_SPS:
|
||||
/* SPS NAL */
|
||||
MP4AddH264SequenceParameterSet(mp4h, mp4vtid, prevnals[i].p_payload+4, prevnals[i].i_payload-4);
|
||||
break;
|
||||
default:
|
||||
/* Anything else, hopefully frames, so copy it into the sample */
|
||||
buffer.append(prevnals[i].p_payload, prevnals[i].i_payload);
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate frame duration and offset */
|
||||
int duration = x264picout.i_dts - prevDTS;
|
||||
int offset = prevPTS - prevDTS;
|
||||
|
||||
/* Write the sample */
|
||||
if(!buffer.empty()) {
|
||||
if(!MP4WriteSample(mp4h, mp4vtid, buffer.extract(buffer.size()), buffer.size(), duration, offset, prevKeyframe)) {
|
||||
Error("Failed writing sample");
|
||||
}
|
||||
}
|
||||
|
||||
/* Cleanup */
|
||||
prevnals.clear();
|
||||
prevpayload.clear();
|
||||
|
||||
}
|
||||
|
||||
/* Got a frame. Copy this new frame into the previous frame */
|
||||
if(frame_size > 0) {
|
||||
/* Copy the NALs and the payloads */
|
||||
for(int i=0;i<i_nals;i++) {
|
||||
|
||||
prevnals.push_back(nals[i]);
|
||||
prevpayload.append(nals[i].p_payload, nals[i].i_payload);
|
||||
}
|
||||
|
||||
/* Update the payload pointers */
|
||||
/* This is done in a separate loop because the previous loop might reallocate memory when appending,
|
||||
making the pointers invalid */
|
||||
unsigned int payload_head = 0;
|
||||
for(unsigned int i=0;i<prevnals.size();i++) {
|
||||
prevnals[i].p_payload = prevpayload.head() + payload_head;
|
||||
payload_head += nals[i].i_payload;
|
||||
}
|
||||
|
||||
/* We need this for the next frame */
|
||||
prevPTS = x264picout.i_pts;
|
||||
prevDTS = x264picout.i_dts;
|
||||
prevKeyframe = x264picout.b_keyframe;
|
||||
|
||||
bFirstFrame = false;
|
||||
}
|
||||
|
||||
} else if(frame_size == 0) {
|
||||
Debug(7,"x264 encode returned zero. Delayed frames: %d",x264_encoder_delayed_frames(x264enc));
|
||||
} else {
|
||||
Error("x264 encode failed: %d",frame_size);
|
||||
}
|
||||
}
|
||||
#endif // ZM_VIDEOWRITER_X264MP4
|
||||
|
||||
int ParseEncoderParameters(const char* str, std::vector<EncoderParameter_t>* vec) {
|
||||
if(vec == NULL) {
|
||||
Error("NULL Encoder parameters vector pointer");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(str == NULL) {
|
||||
Error("NULL Encoder parameters string");
|
||||
return -2;
|
||||
}
|
||||
|
||||
if(str[0] == 0) {
|
||||
/* Empty */
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string line;
|
||||
std::stringstream ss(str);
|
||||
size_t valueoffset;
|
||||
size_t valuelen;
|
||||
unsigned int lineno = 0;
|
||||
EncoderParameter_t param;
|
||||
|
||||
vec->clear();
|
||||
|
||||
while(std::getline(ss, line) ) {
|
||||
lineno++;
|
||||
|
||||
/* Remove CR if exists */
|
||||
if(line.length() >= 1 && line[line.length()-1] == '\r') {
|
||||
line.erase(line.length()-1);
|
||||
}
|
||||
|
||||
/* Skip comments and empty lines */
|
||||
if(line.empty() || line[0] == '#') {
|
||||
continue;
|
||||
}
|
||||
|
||||
valueoffset = line.find('=');
|
||||
if(valueoffset == std::string::npos || valueoffset+1 >= line.length() || valueoffset == 0) {
|
||||
Warning("Failed parsing encoder parameters line %d: Invalid pair", lineno);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if(valueoffset > (sizeof(param.pname)-1) ) {
|
||||
Warning("Failed parsing encoder parameters line %d: Name too long", lineno);
|
||||
continue;
|
||||
}
|
||||
|
||||
valuelen = line.length() - (valueoffset+1);
|
||||
|
||||
if( valuelen > (sizeof(param.pvalue)-1) ) {
|
||||
Warning("Failed parsing encoder parameters line %d: Value too long", lineno);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Copy and NULL terminate */
|
||||
line.copy(param.pname, valueoffset, 0);
|
||||
line.copy(param.pvalue, valuelen, valueoffset+1);
|
||||
param.pname[valueoffset] = 0;
|
||||
param.pvalue[valuelen] = 0;
|
||||
|
||||
/* Push to the vector */
|
||||
vec->push_back(param);
|
||||
|
||||
Debug(7, "Parsed encoder parameter: %s = %s", param.pname, param.pvalue);
|
||||
}
|
||||
|
||||
Debug(7, "Parsed %d lines", lineno);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,168 @@
|
|||
// 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_VIDEO_H
|
||||
#define ZM_VIDEO_H
|
||||
|
||||
#include "zm.h"
|
||||
#include "zm_rgb.h"
|
||||
#include "zm_utils.h"
|
||||
#include "zm_ffmpeg.h"
|
||||
#include "zm_buffer.h"
|
||||
|
||||
/*
|
||||
#define HAVE_LIBX264 1
|
||||
#define HAVE_LIBMP4V2 1
|
||||
#define HAVE_X264_H 1
|
||||
#define HAVE_MP4_H 1
|
||||
*/
|
||||
|
||||
#if HAVE_MP4_H
|
||||
#include <mp4.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_X264_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <x264.h>
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Structure for user parameters to the encoder */
|
||||
struct EncoderParameter_t {
|
||||
char pname[48];
|
||||
char pvalue[48];
|
||||
|
||||
};
|
||||
int ParseEncoderParameters(const char* str, std::vector<EncoderParameter_t>* vec);
|
||||
|
||||
/* VideoWriter is a generic interface that ZM uses to save events as videos */
|
||||
/* It is relatively simple and the functions are pure virtual, so they must be implemented by the deriving class */
|
||||
|
||||
class VideoWriter {
|
||||
|
||||
protected:
|
||||
std::string container;
|
||||
std::string codec;
|
||||
std::string path;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int colours;
|
||||
unsigned int subpixelorder;
|
||||
|
||||
unsigned int frame_count;
|
||||
|
||||
public:
|
||||
VideoWriter(const char* p_container, const char* p_codec, const char* p_path, const unsigned int p_width, const unsigned int p_height, const unsigned int p_colours, const unsigned int p_subpixelorder);
|
||||
virtual ~VideoWriter();
|
||||
virtual int Encode(const uint8_t* data, const size_t data_size, const unsigned int frame_time) = 0;
|
||||
virtual int Encode(const Image* img, const unsigned int frame_time) = 0;
|
||||
virtual int Open() = 0;
|
||||
virtual int Close() = 0;
|
||||
virtual int Reset();
|
||||
|
||||
const char* GetContainer() const {
|
||||
return container.c_str();
|
||||
}
|
||||
const char* GetCodec() const {
|
||||
return codec.c_str();
|
||||
}
|
||||
const char* GetPath() const {
|
||||
return path.c_str();
|
||||
}
|
||||
unsigned int GetWidth() const {
|
||||
return width;
|
||||
}
|
||||
unsigned int GetHeight() const {
|
||||
return height;
|
||||
}
|
||||
unsigned int GetColours() const {
|
||||
return colours;
|
||||
}
|
||||
unsigned int GetSubpixelorder () const {
|
||||
return subpixelorder;
|
||||
}
|
||||
unsigned int GetFrameCount() const {
|
||||
return frame_count;
|
||||
}
|
||||
};
|
||||
|
||||
#if HAVE_LIBX264 && HAVE_LIBMP4V2 && HAVE_LIBAVUTIL && HAVE_LIBSWSCALE
|
||||
#define ZM_HAVE_VIDEOWRITER_X264MP4 1
|
||||
class X264MP4Writer : public VideoWriter {
|
||||
|
||||
protected:
|
||||
|
||||
bool bOpen;
|
||||
bool bGotH264AVCInfo;
|
||||
bool bFirstFrame;
|
||||
|
||||
/* SWScale */
|
||||
SWScale swscaleobj;
|
||||
enum PixelFormat zm_pf;
|
||||
enum PixelFormat codec_pf;
|
||||
size_t codec_imgsize;
|
||||
size_t zm_imgsize;
|
||||
|
||||
/* User parameters */
|
||||
std::vector<EncoderParameter_t> user_params;
|
||||
|
||||
/* AVC Information */
|
||||
uint8_t x264_profleindication;
|
||||
uint8_t x264_profilecompat;
|
||||
uint8_t x264_levelindication;
|
||||
|
||||
/* NALs */
|
||||
Buffer buffer;
|
||||
|
||||
/* Previous frame */
|
||||
int prevPTS;
|
||||
int prevDTS;
|
||||
bool prevKeyframe;
|
||||
Buffer prevpayload;
|
||||
std::vector<x264_nal_t> prevnals;
|
||||
|
||||
/* Internal functions */
|
||||
int x264config();
|
||||
int x264userparams();
|
||||
void x264encodeloop(bool bFlush = false);
|
||||
|
||||
/* x264 objects */
|
||||
x264_t* x264enc;
|
||||
x264_param_t x264params;
|
||||
x264_picture_t x264picin;
|
||||
x264_picture_t x264picout;
|
||||
|
||||
/* MP4v2 objects */
|
||||
MP4FileHandle mp4h;
|
||||
MP4TrackId mp4vtid;
|
||||
|
||||
|
||||
public:
|
||||
X264MP4Writer(const char* p_path, const unsigned int p_width, const unsigned int p_height, const unsigned int p_colours, const unsigned int p_subpixelorder, const std::vector<EncoderParameter_t>* p_user_params = NULL);
|
||||
~X264MP4Writer();
|
||||
int Encode(const uint8_t* data, const size_t data_size, const unsigned int frame_time);
|
||||
int Encode(const Image* img, const unsigned int frame_time);
|
||||
int Open();
|
||||
int Close();
|
||||
int Reset();
|
||||
|
||||
};
|
||||
#endif // HAVE_LIBX264 && HAVE_LIBMP4V2 && HAVE_LIBAVUTIL && HAVE_LIBSWSCALE
|
||||
|
||||
#endif // ZM_VIDEO_H
|
|
@ -382,31 +382,33 @@ function getNearEvents()
|
|||
else
|
||||
$midSql = '';
|
||||
|
||||
$sql = "select E.Id as Id from Events as E inner join Monitors as M on E.MonitorId = M.Id where ".dbEscape($sortColumn)." ".($sortOrder=='asc'?'<=':'>=')." '".$event[$_REQUEST['sort_field']]."'".$_REQUEST['filter']['sql'].$midSql." order by $sortColumn ".($sortOrder=='asc'?'desc':'asc');
|
||||
$sql = "select E.* as Id from Events as E inner join Monitors as M on E.MonitorId = M.Id where ".dbEscape($sortColumn)." ".($sortOrder=='asc'?'<=':'>=')." '".$event[$_REQUEST['sort_field']]."'".$_REQUEST['filter']['sql'].$midSql." order by $sortColumn ".($sortOrder=='asc'?'desc':'asc');
|
||||
$result = dbQuery( $sql );
|
||||
while ( $id = dbFetchNext( $result, 'Id' ) )
|
||||
{
|
||||
if ( $id == $eventId )
|
||||
{
|
||||
$prevId = dbFetchNext( $result, 'Id' );
|
||||
$prevEvent = dbFetchNext( $result );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$sql = "select E.Id as Id from Events as E inner join Monitors as M on E.MonitorId = M.Id where $sortColumn ".($sortOrder=='asc'?'>=':'<=')." '".$event[$_REQUEST['sort_field']]."'".$_REQUEST['filter']['sql'].$midSql." order by $sortColumn $sortOrder";
|
||||
$sql = "select E.* as Id from Events as E inner join Monitors as M on E.MonitorId = M.Id where $sortColumn ".($sortOrder=='asc'?'>=':'<=')." '".$event[$_REQUEST['sort_field']]."'".$_REQUEST['filter']['sql'].$midSql." order by $sortColumn $sortOrder";
|
||||
$result = dbQuery( $sql );
|
||||
while ( $id = dbFetchNext( $result, 'Id' ) )
|
||||
{
|
||||
if ( $id == $eventId )
|
||||
{
|
||||
$nextId = dbFetchNext( $result, 'Id' );
|
||||
$nextEvent = dbFetchNext( $result );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$result = array( 'EventId'=>$eventId );
|
||||
$result['PrevEventId'] = empty($prevId)?0:$prevId;
|
||||
$result['NextEventId'] = empty($nextId)?0:$nextId;
|
||||
$result['PrevEventId'] = empty($prevEvent)?0:$prevEvent['Id'];
|
||||
$result['NextEventId'] = empty($nextEvent)?0:$nextEvent['Id'];
|
||||
$result['PrevEventDefVideoPath'] = empty($prevEvent)?0:(getEventDefaultVideoPath($prevEvent));
|
||||
$result['NextEventDefVideoPath'] = empty($nextEvent)?0:(getEventDefaultVideoPath($nextEvent));
|
||||
return( $result );
|
||||
}
|
||||
|
||||
|
|
|
@ -497,6 +497,9 @@ function getEventPath( $event )
|
|||
return( $eventPath );
|
||||
}
|
||||
|
||||
function getEventDefaultVideoPath( $event ) {
|
||||
return ZM_DIR_EVENTS . "/" . getEventPath($event) . "/" . $event['DefaultVideo'];
|
||||
}
|
||||
|
||||
function deletePath( $path )
|
||||
{
|
||||
|
|
|
@ -57,6 +57,23 @@
|
|||
text-align: right;
|
||||
}
|
||||
|
||||
#videoBar1 div {
|
||||
text-align: center;
|
||||
float: center;
|
||||
}
|
||||
|
||||
#videoBar1 #prevEvent {
|
||||
float: left;
|
||||
}
|
||||
|
||||
#videoBar1 #dlEvent {
|
||||
float: center;
|
||||
}
|
||||
|
||||
#videoBar1 #nextEvent {
|
||||
float: right;
|
||||
}
|
||||
|
||||
#imageFeed {
|
||||
text-align: center;
|
||||
}
|
||||
|
|
|
@ -125,6 +125,7 @@ if ( canEdit( 'Events' ) )
|
|||
<div id="framesEvent"><a href="#" onclick="showEventFrames()"><?= $SLANG['Frames'] ?></a></div>
|
||||
<div id="streamEvent"<?php if ( $streamMode == 'stream' ) { ?> class="hidden"<?php } ?>><a href="#" onclick="showStream()"><?= $SLANG['Stream'] ?></a></div>
|
||||
<div id="stillsEvent"<?php if ( $streamMode == 'still' ) { ?> class="hidden"<?php } ?>><a href="#" onclick="showStills()"><?= $SLANG['Stills'] ?></a></div>
|
||||
<div id="videoEvent"<?php if ( $streamMode == 'video' ) { ?> class="hidden"<?php } ?>><a href="#" onclick="showVideo()">HTML5Video</a></div>
|
||||
<?php
|
||||
if ( ZM_OPT_FFMPEG )
|
||||
{
|
||||
|
@ -184,6 +185,19 @@ else
|
|||
?>
|
||||
</div>
|
||||
</div>
|
||||
<div id="eventVideo" class="hidden">
|
||||
<div id="videoFeed">
|
||||
<video id="videoobj" width="<?= $event['Width'] ?>" height="<?= $event['Height'] ?>" controls autoplay>
|
||||
<source src="<?= getEventDefaultVideoPath($event) ?>" type="video/mp4">
|
||||
Your browser does not support the video tag.
|
||||
</video>
|
||||
</div>
|
||||
<div id="videoBar1">
|
||||
<div id="prevEvent"><a href="#" onclick="prevEvent()">Previous Event</a></div>
|
||||
<div id="dlEvent"><a id="downloadlink" href="<?= getEventDefaultVideoPath($event) ?>" download>Download Video</a></div>
|
||||
<div id="nextEvent"><a href="#" onclick="nextEvent()">Next Event</a></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="eventStills" class="hidden">
|
||||
<div id="eventThumbsPanel">
|
||||
<div id="eventThumbs">
|
||||
|
|
|
@ -12,12 +12,19 @@ function changeScale()
|
|||
var newWidth = ( baseWidth * scale ) / SCALE_BASE;
|
||||
var newHeight = ( baseHeight * scale ) / SCALE_BASE;
|
||||
|
||||
streamScale( scale );
|
||||
if(streamMode == 'video') {
|
||||
var videoid = document.getElementById('videoobj');
|
||||
|
||||
videoid.style.width = newWidth + "px";
|
||||
videoid.style.height = newHeight + "px";
|
||||
} else {
|
||||
streamScale( scale );
|
||||
|
||||
/*Stream could be an applet so can't use moo tools*/
|
||||
var streamImg = document.getElementById('evtStream');
|
||||
streamImg.style.width = newWidth + "px";
|
||||
streamImg.style.height = newHeight + "px";
|
||||
/*Stream could be an applet so can't use moo tools*/
|
||||
var streamImg = document.getElementById('evtStream');
|
||||
streamImg.style.width = newWidth + "px";
|
||||
streamImg.style.height = newHeight + "px";
|
||||
}
|
||||
}
|
||||
|
||||
function changeReplayMode()
|
||||
|
@ -160,15 +167,35 @@ function streamFastRev( action )
|
|||
function streamPrev( action )
|
||||
{
|
||||
streamPlay( false );
|
||||
if ( action )
|
||||
streamReq.send( streamParms+"&command="+CMD_PREV );
|
||||
if(streamMode == 'video') {
|
||||
var videoid = document.getElementById('videoobj');
|
||||
videoobj.src = PrevEventDefVideoPath;
|
||||
videoobj.load();
|
||||
updatedownloadlink();
|
||||
} else {
|
||||
if ( action )
|
||||
streamReq.send( streamParms+"&command="+CMD_PREV );
|
||||
}
|
||||
}
|
||||
|
||||
function streamNext( action )
|
||||
{
|
||||
streamPlay( false );
|
||||
if ( action )
|
||||
streamReq.send( streamParms+"&command="+CMD_NEXT );
|
||||
if(streamMode == 'video') {
|
||||
var videoid = document.getElementById('videoobj');
|
||||
videoobj.src = NextEventDefVideoPath;
|
||||
videoobj.load();
|
||||
updatedownloadlink();
|
||||
} else {
|
||||
if ( action )
|
||||
streamReq.send( streamParms+"&command="+CMD_NEXT );
|
||||
}
|
||||
}
|
||||
|
||||
function updatedownloadlink() {
|
||||
var videoid = document.getElementById('videoobj');
|
||||
var link = document.getElementById('downloadlink');
|
||||
link.href = videoid.currentSrc;
|
||||
}
|
||||
|
||||
function streamZoomIn( x, y )
|
||||
|
@ -259,6 +286,8 @@ function eventQuery( eventId )
|
|||
|
||||
var prevEventId = 0;
|
||||
var nextEventId = 0;
|
||||
var PrevEventDefVideoPath = "";
|
||||
var NextEventDefVideoPath = "";
|
||||
|
||||
function getNearEventsResponse( respObj, respText )
|
||||
{
|
||||
|
@ -266,6 +295,8 @@ function getNearEventsResponse( respObj, respText )
|
|||
return;
|
||||
prevEventId = respObj.nearevents.PrevEventId;
|
||||
nextEventId = respObj.nearevents.NextEventId;
|
||||
PrevEventDefVideoPath = respObj.nearevents.PrevEventDefVideoPath;
|
||||
NextEventDefVideoPath = respObj.nearevents.NextEventDefVideoPath;
|
||||
|
||||
$('prevEventBtn').disabled = !prevEventId;
|
||||
$('nextEventBtn').disabled = !nextEventId;
|
||||
|
@ -634,18 +665,42 @@ function showStream()
|
|||
{
|
||||
$('eventStills').addClass( 'hidden' );
|
||||
$('eventStream').removeClass( 'hidden' );
|
||||
$('eventVideo').addClass( 'hidden' );
|
||||
|
||||
$('streamEvent').addClass( 'hidden' );
|
||||
$('stillsEvent').removeClass( 'hidden' );
|
||||
$('videoEvent').removeClass( 'hidden' );
|
||||
|
||||
streamMode = 'stream';
|
||||
}
|
||||
|
||||
//$(window).removeEvent( 'resize', updateStillsSizes );
|
||||
function showVideo()
|
||||
{
|
||||
$('eventStills').addClass( 'hidden' );
|
||||
$('eventStream').addClass( 'hidden' );
|
||||
$('eventVideo').removeClass( 'hidden' );
|
||||
|
||||
$('streamEvent').removeClass( 'hidden' );
|
||||
$('stillsEvent').removeClass( 'hidden' );
|
||||
$('videoEvent').addClass( 'hidden' );
|
||||
|
||||
streamMode = 'video';
|
||||
|
||||
var videoid = document.getElementById('videoobj');
|
||||
}
|
||||
|
||||
function showStills()
|
||||
{
|
||||
$('eventStream').addClass( 'hidden' );
|
||||
$('eventStills').removeClass( 'hidden' );
|
||||
$('stillsEvent').addClass( 'hidden' );
|
||||
$('eventStream').addClass( 'hidden' );
|
||||
$('eventVideo').addClass( 'hidden' );
|
||||
|
||||
$('streamEvent').removeClass( 'hidden' );
|
||||
$('stillsEvent').addClass( 'hidden' );
|
||||
$('videoEvent').removeClass( 'hidden' );
|
||||
|
||||
streamMode = 'stills';
|
||||
|
||||
streamPause( true );
|
||||
if ( !scroll )
|
||||
{
|
||||
|
|
|
@ -27,6 +27,7 @@ if ( !canView( 'Monitors' ) )
|
|||
$tabs = array();
|
||||
$tabs["general"] = $SLANG['General'];
|
||||
$tabs["source"] = $SLANG['Source'];
|
||||
$tabs["storage"] = "Storage";
|
||||
$tabs["timestamp"] = $SLANG['Timestamp'];
|
||||
$tabs["buffers"] = $SLANG['Buffers'];
|
||||
if ( ZM_OPT_CONTROL && canView( 'Control' ) )
|
||||
|
@ -70,6 +71,9 @@ else
|
|||
'Height' => "240",
|
||||
'Orientation' => "0",
|
||||
'Deinterlacing' => 0,
|
||||
'SaveJPEGs' => "3",
|
||||
'VideoWriter' => "0",
|
||||
'EncoderParameters' => "# Lines beginning with # are a comment \n# For changing quality, use the crf option\n# 1 is best, 51 is worst quality\n#crf=23\n",
|
||||
'LabelFormat' => '%N - %d/%m/%y %H:%M:%S',
|
||||
'LabelX' => 0,
|
||||
'LabelY' => 0,
|
||||
|
@ -410,6 +414,19 @@ $fastblendopts_alarm = array(
|
|||
"50% (Alarm lasts a moment)" => 50
|
||||
);
|
||||
|
||||
$savejpegopts = array(
|
||||
"Disabled" => 0,
|
||||
"Frames only" => 1,
|
||||
"Analysis images only (if available)" => 2,
|
||||
"Frames + analysis images (if available)" => 3
|
||||
);
|
||||
|
||||
$videowriteropts = array(
|
||||
"Disabled" => 0,
|
||||
"X264 : MP4V2" => 1,
|
||||
"H264 Passthrough : MP4V2 (not implemented)" => 2
|
||||
);
|
||||
|
||||
xhtmlHeaders(__FILE__, $SLANG['Monitor']." - ".validHtmlStr($monitor['Name']) );
|
||||
?>
|
||||
<body>
|
||||
|
@ -518,6 +535,14 @@ if ( $tab != 'source' )
|
|||
<input type="hidden" name="newMonitor[Deinterlacing]" value="<?= validHtmlStr($newMonitor['Deinterlacing']) ?>"/>
|
||||
<?php
|
||||
}
|
||||
if ( $tab != 'storage' )
|
||||
{
|
||||
?>
|
||||
<input type="hidden" name="newMonitor[SaveJPEGs]" value="<?= validHtmlStr($newMonitor['SaveJPEGs']) ?>"/>
|
||||
<input type="hidden" name="newMonitor[VideoWriter]" value="<?= validHtmlStr($newMonitor['VideoWriter']) ?>"/>
|
||||
<input type="hidden" name="newMonitor[EncoderParameters]" value="<?= validHtmlStr($newMonitor['EncoderParameters']) ?>"/>
|
||||
<?php
|
||||
}
|
||||
if ( $tab != 'timestamp' )
|
||||
{
|
||||
?>
|
||||
|
@ -742,6 +767,13 @@ switch ( $tab )
|
|||
<?php
|
||||
break;
|
||||
}
|
||||
case 'storage' :
|
||||
?>
|
||||
<tr><td>Save as JPEGs</td><td><select name="newMonitor[SaveJPEGs]"><?php foreach ( $savejpegopts as $name => $value ) { ?><option value="<?= $value ?>"<?php if ( $value == $newMonitor['SaveJPEGs'] ) { ?> selected="selected"<?php } ?>><?= $name ?></option><?php } ?></select></td></tr>
|
||||
<tr><td>Video writer</td><td><select name="newMonitor[VideoWriter]"><?php foreach ( $videowriteropts as $name => $value ) { ?><option value="<?= $value ?>"<?php if ( $value == $newMonitor['VideoWriter'] ) { ?> selected="selected"<?php } ?>><?= $name ?></option><?php } ?></select></td></tr>
|
||||
<tr><td>Optional encoder parameters</td><td><textarea name="newMonitor[EncoderParameters]" rows="4" cols="36"><?= validHtmlStr($newMonitor['EncoderParameters']) ?></textarea></td></tr>
|
||||
<?php
|
||||
break;
|
||||
case 'timestamp' :
|
||||
{
|
||||
?>
|
||||
|
|
|
@ -37,6 +37,10 @@
|
|||
#cmakedefine HAVE_GNUTLS_GNUTLS_H 1
|
||||
#cmakedefine HAVE_LIBMYSQLCLIENT 1
|
||||
#cmakedefine HAVE_MYSQL_H 1
|
||||
#cmakedefine HAVE_LIBX264 1
|
||||
#cmakedefine HAVE_X264_H 1
|
||||
#cmakedefine HAVE_LIBMP4V2 1
|
||||
#cmakedefine HAVE_MP4_H 1
|
||||
#cmakedefine HAVE_LIBAVFORMAT 1
|
||||
#cmakedefine HAVE_LIBAVFORMAT_AVFORMAT_H 1
|
||||
#cmakedefine HAVE_LIBAVCODEC 1
|
||||
|
|
Loading…
Reference in New Issue