diff -p a/conf.c b/conf.c *** a/conf.c 2007-11-05 11:19:06.000000000 +0100 --- b/conf.c 2007-11-05 11:19:06.000000000 +0100 *************** struct config conf_template = { *** 113,118 **** --- 113,119 ---- mysql_user: NULL, mysql_password: NULL, on_picture_save: NULL, + on_area_detected: NULL, on_motion_detected: NULL, on_movie_start: NULL, on_movie_end: NULL, *************** struct config conf_template = { *** 131,136 **** --- 132,138 ---- text_event: DEF_EVENTSTAMP, text_double: 0, despeckle: NULL, + area_detect: NULL, minimum_motion_frames: 1, pid_file: NULL, // debug_parameter: 0 *************** config_param config_params[] = { *** 406,411 **** --- 408,423 ---- print_string }, { + "area_detect", + "# Detect motion in predefined areas (1 - 9). Areas are numbered like that: 1 2 3\n" + "# A script (on_area_detected) is started immediately when motion is 4 5 6\n" + "# detected in one of the given areas, but only once during an event. 7 8 9\n" + "# One or more areas can be specified with this option. (Default: not defined)", + CONF_OFFSET(area_detect), + copy_string, + print_string + }, + { "mask_file", "# PGM file to use as a sensitivity mask.\n" "# Full path name to. (Default: not defined)", *************** config_param config_params[] = { *** 991,996 **** --- 1003,1016 ---- copy_string, print_string }, + { + "on_area_detected", + "# Command to be executed when motion in a predefined area is detected\n" + "# Check option 'area_detect'. (default: none)", + CONF_OFFSET(on_area_detected), + copy_string, + print_string + }, #ifdef HAVE_FFMPEG { "on_movie_start", diff -p a/conf.h b/conf.h *** a/conf.h 2007-11-05 11:19:06.000000000 +0100 --- b/conf.h 2007-11-05 11:19:06.000000000 +0100 *************** struct config { *** 97,102 **** --- 97,103 ---- const char *mysql_user; const char *mysql_password; char *on_picture_save; + char *on_area_detected; char *on_motion_detected; char *on_movie_start; char *on_movie_end; *************** struct config { *** 115,120 **** --- 116,122 ---- const char *text_event; int text_double; const char *despeckle; + const char *area_detect; int minimum_motion_frames; char *pid_file; // int debug_parameter; diff -p a/event.c b/event.c *** a/event.c 2007-11-05 11:19:06.000000000 +0100 --- b/event.c 2007-11-05 11:19:06.000000000 +0100 *************** static void event_sqlnewfile(struct cont *** 170,175 **** --- 170,183 ---- #endif /* defined HAVE_MYSQL || defined HAVE_PGSQL */ + static void on_area_command(struct context *cnt, int type ATTRIBUTE_UNUSED, + unsigned char *dummy1 ATTRIBUTE_UNUSED, + char *dummy2 ATTRIBUTE_UNUSED, void *dummy3 ATTRIBUTE_UNUSED, + struct tm *tm ATTRIBUTE_UNUSED) + { + if (cnt->conf.on_area_detected) + exec_command(cnt, cnt->conf.on_area_detected, NULL, 0); + } static void on_event_start_command(struct context *cnt, int type ATTRIBUTE_UNUSED, unsigned char *dummy1 ATTRIBUTE_UNUSED, *************** struct event_handlers event_handlers[] = *** 590,595 **** --- 598,607 ---- on_motion_detected_command }, { + EVENT_AREA_DETECTED, + on_area_command + }, + { EVENT_FIRSTMOTION, on_event_start_command }, diff -p a/event.h b/event.h *** a/event.h 2007-11-05 11:19:06.000000000 +0100 --- b/event.h 2007-11-05 11:19:06.000000000 +0100 *************** *** 27,32 **** --- 27,33 ---- #define EVENT_FILECLOSE 16384 #define EVENT_DEBUG 65536 #define EVENT_CRITICAL 131072 + #define EVENT_AREA_DETECTED 262144 # typedef void(* event_handler)(struct context *, int, unsigned char *, char *, void *, struct tm *); diff -p a/motion.c b/motion.c *** a/motion.c 2007-11-05 11:19:06.000000000 +0100 --- b/motion.c 2007-11-05 11:19:06.000000000 +0100 *************** static void motion_init(struct context * *** 823,831 **** static void *motion_loop(void *arg) { struct context *cnt = arg; ! int i, j = 0; time_t lastframetime = 0; int frame_buffer_size; int smartmask_ratio = 0; int smartmask_count = 20; int smartmask_lastrate = 0; --- 823,833 ---- static void *motion_loop(void *arg) { struct context *cnt = arg; ! int i, j, z = 0; time_t lastframetime = 0; int frame_buffer_size; + int area_once = 0; + int area_minx[9], area_miny[9], area_maxx[9], area_maxy[9]; int smartmask_ratio = 0; int smartmask_count = 20; int smartmask_lastrate = 0; *************** static void *motion_loop(void *arg) *** 857,862 **** --- 859,873 ---- else text_size_factor = 1; + /* Initialize area detection */ + area_minx[0] = area_minx[3] = area_minx[6] = area_miny[0] = area_miny[1] = area_miny[2] = 0; + area_minx[1] = area_minx[4] = area_minx[7] = area_maxx[0] = area_maxx[3] = area_maxx[6] = cnt->imgs.width / 3; + area_minx[2] = area_minx[5] = area_minx[8] = area_maxx[1] = area_maxx[4] = area_maxx[7] = cnt->imgs.width / 3 * 2; + area_miny[3] = area_miny[4] = area_miny[5] = area_maxy[0] = area_maxy[1] = area_maxy[2] = cnt->imgs.height / 3; + area_miny[6] = area_miny[7] = area_miny[8] = area_maxy[3] = area_maxy[4] = area_maxy[5] = cnt->imgs.height / 3 * 2; + area_maxx[2] = area_maxx[5] = area_maxx[8] = cnt->imgs.width; + area_maxy[6] = area_maxy[7] = area_maxy[8] = cnt->imgs.height; + /* Work out expected frame rate based on config setting */ if (cnt->conf.frame_limit < 2) cnt->conf.frame_limit = 2; *************** static void *motion_loop(void *arg) *** 1391,1396 **** --- 1402,1429 ---- cnt->lasttime = cnt->current_image->timestamp; } + /* Simple hack to recognize motion in a specific area */ + /* Do we need a new coversion specifier as well?? */ + if ((cnt->conf.area_detect) && (cnt->event_nr != area_once) && (cnt->detecting_motion)) { + j = strlen(cnt->conf.area_detect); + for (i = 0; i < j; i++) { + z = cnt->conf.area_detect[i] - 49; /* 1 becomes 0 */ + if ((z >= 0) && (z < 9)) { + if (cnt->current_image->location.x > area_minx[z] && + cnt->current_image->location.x < area_maxx[z] && + cnt->current_image->location.y > area_miny[z] && + cnt->current_image->location.y < area_maxy[z]) { + event(cnt, EVENT_AREA_DETECTED, NULL, NULL, + NULL, cnt->currenttime_tm); + area_once = cnt->event_nr; /* Fire script only once per event */ + if (cnt->conf.setup_mode) + motion_log(-1, 0, "Motion in area %d detected.\n", z+1); + break; + } + } + } + } + /* Is the mpeg movie to long? Then make movies * First test for max mpegtime */