1 /* motion.h 2 * 3 * Include file for motion.c 4 * Copyright 2000 by Jeroen Vreeken (pe1rxq@amsat.org) 5 * This software is distributed under the GNU public license version 2 6 * See also the file 'COPYING'. 7 * 8 */ 9 10 #ifndef _INCLUDE_MOTION_H 11 #define _INCLUDE_MOTION_H 12 13 /* Forward declarations, used in functional definitions of headers */ 14 struct images; 15 struct image_data; 16 17 #include "config.h" 18 19 /* Includes */ 20 #if defined(HAVE_MYSQL) || defined(HAVE_MARIADB) 21 #include <mysql.h> 22 #endif 23 24 #ifdef HAVE_SQLITE3 25 #include <sqlite3.h> 26 #endif 27 28 #ifdef HAVE_PGSQL 29 #include <libpq-fe.h> 30 #endif 31 32 33 #include <stdio.h> 34 #include <stdlib.h> 35 #ifndef __USE_GNU 36 #define __USE_GNU 37 #endif 38 #include <string.h> 39 #include <unistd.h> 40 #include <fcntl.h> 41 #include <time.h> 42 #include <signal.h> 43 #include <limits.h> 44 #include <errno.h> 45 #include <assert.h> 46 #include <sys/time.h> 47 #include <sys/stat.h> 48 #include <sys/types.h> 49 #include <sys/wait.h> 50 #include <sys/ioctl.h> 51 #include <sys/param.h> 52 #include <stdint.h> 53 #include <pthread.h> 54 #include <microhttpd.h> 55 56 #if defined(HAVE_PTHREAD_NP_H) 57 #include <pthread_np.h> 58 #endif 59 60 #include "logger.h" 61 #include "conf.h" 62 #include "stream.h" 63 64 #include "track.h" 65 #include "netcam.h" 66 #include "netcam_rtsp.h" 67 #include "ffmpeg.h" 68 69 #ifdef HAVE_MMAL 70 #include "mmalcam.h" 71 #endif 72 73 74 /** 75 * ATTRIBUTE_UNUSED: 76 * 77 * Macro used to signal to GCC unused function parameters 78 */ 79 #ifdef __GNUC__ 80 #ifdef HAVE_ANSIDECL_H 81 #include <ansidecl.h> 82 #endif 83 #ifndef ATTRIBUTE_UNUSED 84 #define ATTRIBUTE_UNUSED __attribute__((unused)) 85 #endif 86 #else 87 #define ATTRIBUTE_UNUSED 88 #endif 89 90 /* 91 * The macro below defines a version of sleep using nanosleep 92 * If a signal such as SIG_CHLD interrupts the sleep we just continue sleeping 93 */ 94 #define SLEEP(seconds, nanoseconds) { \ 95 struct timespec tv; \ 96 tv.tv_sec = (seconds); \ 97 tv.tv_nsec = (nanoseconds); \ 98 while (nanosleep(&tv, &tv) == -1); \ 99 } 100 101 #define DEF_PALETTE 17 102 103 /* Default picture settings */ 104 #define DEF_WIDTH 640 105 #define DEF_HEIGHT 480 106 #define DEF_QUALITY 75 107 #define DEF_CHANGES 1500 108 109 #define DEF_MAXFRAMERATE 15 110 #define DEF_NOISELEVEL 32 111 112 /* Minimum time between two 'actions' (email, sms, external) */ 113 #define DEF_EVENT_GAP 60 /* 1 minutes */ 114 115 #define DEF_INPUT -1 116 #define DEF_VIDEO_DEVICE "/dev/video0" 117 118 #define THRESHOLD_TUNE_LENGTH 256 119 120 #define MISSING_FRAMES_TIMEOUT 30 /* When failing to get picture frame from camera 121 we reuse the previous frame until 122 MISSING_FRAMES_TIMEOUT seconds has passed 123 and then we show a grey image instead 124 */ 125 126 #define WATCHDOG_TMO 30 /* 30 sec max motion_loop interval */ 127 #define WATCHDOG_KILL -10 /* 10 sec grace period before calling thread cancel */ 128 129 #define CONNECTION_KO "Lost connection" 130 #define CONNECTION_OK "Connection OK" 131 132 #define DEF_MAXSTREAMS 10 /* Maximum number of stream clients per camera */ 133 #define DEF_MAXWEBQUEUE 10 /* Maximum number of stream client in queue */ 134 135 #define DEF_TIMESTAMP "%Y-%m-%d\\n%T" 136 #define DEF_EVENTSTAMP "%Y%m%d%H%M%S" 137 138 #define DEF_SNAPPATH "%v-%Y%m%d%H%M%S-snapshot" 139 #define DEF_IMAGEPATH "%v-%Y%m%d%H%M%S-%q" 140 #define DEF_MOVIEPATH "%v-%Y%m%d%H%M%S" 141 #define DEF_TIMEPATH "%Y%m%d-timelapse" 142 143 #define DEF_TIMELAPSE_MODE "daily" 144 145 /* OUTPUT Image types */ 146 #define IMAGE_TYPE_JPEG 0 147 #define IMAGE_TYPE_PPM 1 148 #define IMAGE_TYPE_WEBP 2 149 150 /* Filetype defines */ 151 #define FTYPE_IMAGE 1 152 #define FTYPE_IMAGE_SNAPSHOT 2 153 #define FTYPE_IMAGE_MOTION 4 154 #define FTYPE_MPEG 8 155 #define FTYPE_MPEG_MOTION 16 156 #define FTYPE_MPEG_TIMELAPSE 32 157 158 #define FTYPE_MPEG_ANY (FTYPE_MPEG | FTYPE_MPEG_MOTION | FTYPE_MPEG_TIMELAPSE) 159 #define FTYPE_IMAGE_ANY (FTYPE_IMAGE | FTYPE_IMAGE_SNAPSHOT | FTYPE_IMAGE_MOTION) 160 161 /* What types of images files do we want to have */ 162 #define NEWIMG_OFF 0 163 #define NEWIMG_ON 1 164 #define NEWIMG_FIRST 2 165 #define NEWIMG_BEST 4 166 #define NEWIMG_CENTER 8 167 168 #define LOCATE_OFF 0 169 #define LOCATE_ON 1 170 #define LOCATE_PREVIEW 2 171 #define LOCATE_BOX 1 172 #define LOCATE_REDBOX 2 173 #define LOCATE_CROSS 4 174 #define LOCATE_REDCROSS 8 175 176 #define LOCATE_NORMAL 1 177 #define LOCATE_BOTH 2 178 179 #define UPDATE_REF_FRAME 1 180 #define RESET_REF_FRAME 2 181 182 183 /* 184 * Structure to hold images information 185 * The idea is that this should have all information about a picture e.g. diffs, timestamp etc. 186 * The exception is the label information, it uses a lot of memory 187 * When the image is stored all texts motion marks etc. is written to the image 188 * so we only have to send it out when/if we want. 189 */ 190 191 /* A image can have detected motion in it, but dosn't trigger an event, if we use minimum_motion_frames */ 192 #define IMAGE_MOTION 1 193 #define IMAGE_TRIGGER 2 194 #define IMAGE_SAVE 4 195 #define IMAGE_SAVED 8 196 #define IMAGE_PRECAP 16 197 #define IMAGE_POSTCAP 32 198 199 enum CAMERA_TYPE { 200 CAMERA_TYPE_UNKNOWN, 201 CAMERA_TYPE_V4L2, 202 CAMERA_TYPE_BKTR, 203 CAMERA_TYPE_MMAL, 204 CAMERA_TYPE_RTSP, 205 CAMERA_TYPE_NETCAM 206 }; 207 208 enum WEBUI_LEVEL{ 209 WEBUI_LEVEL_ALWAYS = 0, 210 WEBUI_LEVEL_LIMITED = 1, 211 WEBUI_LEVEL_ADVANCED = 2, 212 WEBUI_LEVEL_RESTRICTED = 3, 213 WEBUI_LEVEL_NEVER = 99 214 }; 215 216 struct vdev_usrctrl_ctx { 217 char *ctrl_name; /* The name or description of the ID as requested by user*/ 218 int ctrl_value; /* The value that the user wants the control set to*/ 219 }; 220 221 struct vdev_context { 222 /* As v4l2 and bktr get rewritten, put thread specific items here 223 * Rather than use conf options directly, copy from conf to here 224 * to handle cross thread webui changes which could cause problems 225 */ 226 struct vdev_usrctrl_ctx *usrctrl_array; /*Array of the controls the user specified*/ 227 int usrctrl_count; /*Count of the controls the user specified*/ 228 int update_parms; /*Bool for whether to update the parameters on the device*/ 229 }; 230 231 232 struct image_data { 233 unsigned char *image_norm; 234 unsigned char *image_high; 235 int diffs; 236 int64_t idnbr_norm; 237 int64_t idnbr_high; 238 struct timeval timestamp_tv; 239 int shot; /* Sub second timestamp count */ 240 241 /* 242 * Movement center to img center distance 243 * Note: Dist is calculated distX*distX + distY*distY 244 */ 245 unsigned long cent_dist; 246 247 unsigned int flags; /* Se IMAGE_* defines */ 248 249 struct coord location; /* coordinates for center and size of last motion detection*/ 250 251 int total_labels; 252 253 }; 254 255 struct stream_data { 256 unsigned char *jpeg_data; /* Image compressed as JPG */ 257 long jpeg_size; /* The number of bytes for jpg */ 258 int cnct_count; /* Counter of the number of connections */ 259 }; 260 261 /* 262 * DIFFERENCES BETWEEN imgs.width, conf.width AND rotate_data.cap_width 263 * (and the corresponding height values, of course) 264 * =========================================================================== 265 * Location Purpose 266 * 267 * conf The values in conf reflect width and height set in the 268 * configuration file. These can be set via http remote control, 269 * but they are not used internally by Motion, so it won't break 270 * anything. These values are transferred to imgs in vid_start. 271 * 272 * imgs The values in imgs are the actual output dimensions. Normally 273 * the output dimensions are the same as the capture dimensions, 274 * but for 90 or 270 degrees rotation, they are not. E.g., if 275 * you capture at 320x240, and rotate 90 degrees, the output 276 * dimensions are 240x320. 277 * These values are set from the conf values in vid_start, or 278 * from the first JPEG image in netcam_start. For 90 or 270 279 * degrees rotation, they are swapped in rotate_init. 280 * 281 * rotate_data The values in rotate_data are named cap_width and cap_height, 282 * and contain the capture dimensions. The difference between 283 * capture and output dimensions is explained above. 284 * These values are set in rotate_init. 285 */ 286 287 /* date/time drawing, draw.c */ 288 int draw_text(unsigned char *image, 289 int width, int height, 290 int startx, int starty, 291 const char *text, int factor); 292 int initialize_chars(void); 293 294 struct images { 295 struct image_data *image_ring; /* The base address of the image ring buffer */ 296 int image_ring_size; 297 int image_ring_in; /* Index in image ring buffer we last added a image into */ 298 int image_ring_out; /* Index in image ring buffer we want to process next time */ 299 300 unsigned char *ref; /* The reference frame */ 301 struct image_data img_motion; /* Picture buffer for motion images */ 302 int *ref_dyn; /* Dynamic objects to be excluded from reference frame */ 303 struct image_data image_virgin; /* Last picture frame with no text or locate overlay */ 304 struct image_data image_vprvcy; /* Virgin image with the privacy mask applied */ 305 struct image_data preview_image; /* Picture buffer for best image when enables */ 306 unsigned char *mask; /* Buffer for the mask file */ 307 unsigned char *smartmask; 308 unsigned char *smartmask_final; 309 unsigned char *common_buffer; 310 unsigned char *substream_image; 311 312 unsigned char *mask_privacy; /* Buffer for the privacy mask values */ 313 unsigned char *mask_privacy_uv; /* Buffer for the privacy U&V values */ 314 315 unsigned char *mask_privacy_high; /* Buffer for the privacy mask values */ 316 unsigned char *mask_privacy_high_uv; /* Buffer for the privacy U&V values */ 317 318 int *smartmask_buffer; 319 int *labels; 320 int *labelsize; 321 int width; 322 int height; 323 int type; 324 int picture_type; /* Output picture type IMAGE_JPEG, IMAGE_PPM */ 325 int size_norm; /* Number of bytes for normal size image */ 326 327 int width_high; 328 int height_high; 329 int size_high; /* Number of bytes for high resolution image */ 330 331 int motionsize; 332 int labelgroup_max; 333 int labels_above; 334 int labelsize_max; 335 int largest_label; 336 }; 337 338 enum FLIP_TYPE { 339 FLIP_TYPE_NONE, 340 FLIP_TYPE_HORIZONTAL, 341 FLIP_TYPE_VERTICAL 342 }; 343 344 /* Contains data for image rotation, see rotate.c. */ 345 struct rotdata { 346 347 unsigned char *buffer_norm; /* Temporary buffer for 90 and 270 degrees rotation of normal resolution image. */ 348 unsigned char *buffer_high; /* Temporary buffer for 90 and 270 degrees rotation of high resolution image. */ 349 int degrees; /* Degrees to rotate; copied from conf.rotate_deg. */ 350 enum FLIP_TYPE axis; /* Rotate image over the Horizontal or Vertical axis. */ 351 352 int capture_width_norm; /* Capture width of normal resolution image */ 353 int capture_height_norm; /* Capture height of normal resolution image */ 354 355 int capture_width_high; /* Capture width of high resolution image */ 356 int capture_height_high; /* Capture height of high resolution image */ 357 358 }; 359 360 /* 361 * These used to be global variables but now each thread will have its 362 * own context 363 */ 364 struct context { 365 FILE *extpipe; 366 int extpipe_open; 367 char conf_filename[PATH_MAX]; 368 int from_conf_dir; 369 int threadnr; 370 unsigned int daemon; 371 char pid_file[PATH_MAX]; 372 char log_file[PATH_MAX]; 373 char log_type_str[6]; 374 int log_level; 375 unsigned int log_type; 376 377 struct config conf; 378 struct images imgs; 379 struct trackoptions track; 380 int track_posx; 381 int track_posy; 382 383 enum CAMERA_TYPE camera_type; 384 struct netcam_context *netcam; 385 #ifdef HAVE_MMAL 386 struct mmalcam_context *mmalcam; 387 #endif 388 struct rtsp_context *rtsp; /* this structure contains the context for normal RTSP connection */ 389 struct rtsp_context *rtsp_high; /* this structure contains the context for high resolution RTSP connection */ 390 391 struct vdev_context *vdev; /* Structure for v4l2 and bktr device information */ 392 393 struct image_data *current_image; /* Pointer to a structure where the image, diffs etc is stored */ 394 unsigned int new_img; 395 396 int locate_motion_mode; 397 int locate_motion_style; 398 int process_thisframe; 399 struct rotdata rotate_data; /* rotation data is thread-specific */ 400 401 int noise; 402 int threshold; 403 int threshold_maximum; 404 int diffs_last[THRESHOLD_TUNE_LENGTH]; 405 int smartmask_speed; 406 407 408 /* Commands to the motion thread */ 409 volatile unsigned int snapshot; /* Make a snapshot */ 410 volatile unsigned int event_stop; /* Boolean for whether to stop a event */ 411 volatile unsigned int event_user; /* Boolean for whether to user triggered an event */ 412 volatile unsigned int finish; /* End the thread */ 413 volatile unsigned int restart; /* Restart the thread when it ends */ 414 /* Is the motion thread running */ 415 volatile unsigned int running; 416 /* Is the web control thread running */ 417 volatile unsigned int webcontrol_running; 418 volatile unsigned int webcontrol_finish; /* End the thread */ 419 volatile int watchdog; 420 421 pthread_t thread_id; 422 423 int event_nr; 424 int prev_event; 425 unsigned long long database_event_id; 426 unsigned int lightswitch_framecounter; 427 char text_event_string[PATH_MAX]; /* The text for conv. spec. %C - */ 428 int text_scale; 429 430 int postcap; /* downcounter, frames left to to send post event */ 431 int shots; 432 unsigned int detecting_motion; 433 struct tm *currenttime_tm; 434 struct tm *eventtime_tm; 435 436 time_t currenttime; 437 time_t lasttime; 438 time_t eventtime; 439 time_t connectionlosttime; /* timestamp from connection lost */ 440 441 unsigned int lastrate; 442 unsigned int startup_frames; 443 unsigned int moved; 444 unsigned int pause; 445 int missing_frame_counter; /* counts failed attempts to fetch picture frame from camera */ 446 unsigned int lost_connection; 447 448 int video_dev; 449 int pipe; 450 int mpipe; 451 452 struct stream stream; 453 int stream_count; 454 455 char hostname[PATH_MAX]; 456 char *netcam_decoder; 457 458 int sql_mask; 459 460 #ifdef HAVE_SQLITE3 461 sqlite3 *database_sqlite3; 462 #endif 463 464 #if defined(HAVE_MYSQL) || defined(HAVE_MARIADB) 465 MYSQL *database; 466 #endif 467 468 #ifdef HAVE_PGSQL 469 PGconn *database_pg; 470 #endif 471 472 int movie_fps; 473 char newfilename[PATH_MAX]; 474 char extpipefilename[PATH_MAX]; 475 char extpipecmdline[PATH_MAX]; 476 int movie_last_shot; 477 478 struct ffmpeg *ffmpeg_output; 479 struct ffmpeg *ffmpeg_output_motion; 480 struct ffmpeg *ffmpeg_timelapse; 481 int movie_passthrough; 482 483 char timelapsefilename[PATH_MAX]; 484 char motionfilename[PATH_MAX]; 485 486 int area_minx[9], area_miny[9], area_maxx[9], area_maxy[9]; 487 int areadetect_eventnbr; 488 /* ToDo Determine why we need these...just put it all into prepare? */ 489 unsigned long long int timenow, timebefore; 490 491 unsigned int rate_limit; 492 time_t lastframetime; 493 int minimum_frame_time_downcounter; 494 unsigned int get_image; /* Flag used to signal that we capture new image when we run the loop */ 495 496 long int required_frame_time, frame_delay; 497 498 long int rolling_average_limit; 499 long int *rolling_average_data; 500 unsigned long int rolling_average; 501 502 int olddiffs; //only need this in here for a printf later...do we need that printf? 503 int smartmask_ratio; 504 int smartmask_count; 505 506 int previous_diffs, previous_location_x, previous_location_y; 507 unsigned long int time_last_frame, time_current_frame; 508 509 unsigned int smartmask_lastrate; 510 511 unsigned int passflag; //only purpose is to flag first frame vs all others..... 512 int rolling_frame; 513 514 struct MHD_Daemon *webcontrol_daemon; 515 struct MHD_Daemon *webstream_daemon; 516 char webcontrol_digest_rand[8]; 517 char webstream_digest_rand[8]; 518 int camera_id; 519 520 pthread_mutex_t mutex_stream; 521 522 struct stream_data stream_norm; /* Copy of the image to use for web stream*/ 523 struct stream_data stream_sub; /* Copy of the image to use for web stream*/ 524 struct stream_data stream_motion; /* Copy of the image to use for web stream*/ 525 struct stream_data stream_source; /* Copy of the image to use for web stream*/ 526 527 528 }; 529 530 extern pthread_mutex_t global_lock; 531 extern volatile int threads_running; 532 extern FILE *ptr_logfile; 533 534 /* TLS keys below */ 535 extern pthread_key_t tls_key_threadnr; /* key for thread number */ 536 537 int http_bindsock(int, int, int); 538 void * mymalloc(size_t); 539 void * myrealloc(void *, size_t, const char *); 540 FILE * myfopen(const char *, const char *); 541 int myfclose(FILE *); 542 size_t mystrftime(const struct context *, char *, size_t, const char *, const struct timeval *, const char *, int); 543 int create_path(const char *); 544 545 void util_threadname_set(const char *abbr, int threadnbr, const char *threadname); 546 void util_threadname_get(char *threadname); 547 int util_check_passthrough(struct context *cnt); 548 549 #endif /* _INCLUDE_MOTION_H */ 550