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