From f418e885a7a79180fed7d7859e76ff111c4a10ea Mon Sep 17 00:00:00 2001 From: MrDave Date: Sun, 6 Oct 2019 21:52:31 -0600 Subject: [PATCH] Remove rate limit --- src/conf.cpp | 2 +- src/draw.cpp | 24 ++-- src/motion.hpp | 4 - src/motion_loop.cpp | 301 +++++++++++++++++++------------------------- 4 files changed, 143 insertions(+), 188 deletions(-) diff --git a/src/conf.cpp b/src/conf.cpp index 140f9272..1357ddef 100644 --- a/src/conf.cpp +++ b/src/conf.cpp @@ -2235,7 +2235,7 @@ static void conf_defaults(struct ctx_cam **cam_list) { /* Image processing configuration parameters */ cam_list[0]->conf.width = 640; cam_list[0]->conf.height = 480; - cam_list[0]->conf.framerate = 15; + conf_edit_framerate(cam_list[0],"15"); cam_list[0]->conf.rotate = 0; cam_list[0]->conf.flip_axis = "none"; cam_list[0]->conf.locate_motion_mode = "off"; diff --git a/src/draw.cpp b/src/draw.cpp index 921545c5..26272f53 100644 --- a/src/draw.cpp +++ b/src/draw.cpp @@ -1231,7 +1231,7 @@ void draw_init_scale(struct ctx_cam *cam){ /** Draws a box around the movement. */ static void draw_location(struct ctx_coord *cent, struct ctx_images *imgs, int width, unsigned char *new_var, - int style, int mode, int process_thisframe) + int style, int mode) { unsigned char *out = imgs->image_motion.image_norm; int x, y; @@ -1239,7 +1239,7 @@ static void draw_location(struct ctx_coord *cent, struct ctx_images *imgs, int w out = imgs->image_motion.image_norm; /* Debug image always gets a 'normal' box. */ - if ((mode == LOCATE_BOTH) && process_thisframe) { + if (mode == LOCATE_BOTH) { int width_miny = width * cent->miny; int width_maxy = width * cent->maxy; @@ -1296,7 +1296,7 @@ static void draw_location(struct ctx_coord *cent, struct ctx_images *imgs, int w /** Draws a RED box around the movement. */ static void draw_red_location(struct ctx_coord *cent, struct ctx_images *imgs, int width, unsigned char *new_var, - int style, int mode, int process_thisframe) + int style, int mode) { unsigned char *out = imgs->image_motion.image_norm; unsigned char *new_u, *new_v; @@ -1311,7 +1311,7 @@ static void draw_red_location(struct ctx_coord *cent, struct ctx_images *imgs, i new_v = new_var + v; /* Debug image always gets a 'normal' box. */ - if ((mode == LOCATE_BOTH) && process_thisframe) { + if (mode == LOCATE_BOTH) { int width_miny = width * cent->miny; int width_maxy = width * cent->maxy; @@ -1410,16 +1410,16 @@ void draw_locate_preview(struct ctx_cam *cam, struct ctx_image_data *img){ if (cam->locate_motion_style == LOCATE_BOX) { draw_location(&img->location, &cam->imgs, cam->imgs.width, cam->imgs.image_preview.image_norm, - LOCATE_BOX, LOCATE_NORMAL, cam->process_thisframe); + LOCATE_BOX, LOCATE_NORMAL); } else if (cam->locate_motion_style == LOCATE_REDBOX) { draw_red_location(&img->location, &cam->imgs, cam->imgs.width, cam->imgs.image_preview.image_norm, - LOCATE_REDBOX, LOCATE_NORMAL, cam->process_thisframe); + LOCATE_REDBOX, LOCATE_NORMAL); } else if (cam->locate_motion_style == LOCATE_CROSS) { draw_location(&img->location, &cam->imgs, cam->imgs.width, cam->imgs.image_preview.image_norm, - LOCATE_CROSS, LOCATE_NORMAL, cam->process_thisframe); + LOCATE_CROSS, LOCATE_NORMAL); } else if (cam->locate_motion_style == LOCATE_REDCROSS) { draw_red_location(&img->location, &cam->imgs, cam->imgs.width, cam->imgs.image_preview.image_norm, - LOCATE_REDCROSS, LOCATE_NORMAL, cam->process_thisframe); + LOCATE_REDCROSS, LOCATE_NORMAL); } } } @@ -1432,16 +1432,16 @@ void draw_locate(struct ctx_cam *cam, struct ctx_image_data *img){ if (cam->locate_motion_style == LOCATE_BOX) { draw_location(location, imgs, imgs->width, img->image_norm, LOCATE_BOX, - LOCATE_BOTH, cam->process_thisframe); + LOCATE_BOTH); } else if (cam->locate_motion_style == LOCATE_REDBOX) { draw_red_location(location, imgs, imgs->width, img->image_norm, LOCATE_REDBOX, - LOCATE_BOTH, cam->process_thisframe); + LOCATE_BOTH); } else if (cam->locate_motion_style == LOCATE_CROSS) { draw_location(location, imgs, imgs->width, img->image_norm, LOCATE_CROSS, - LOCATE_BOTH, cam->process_thisframe); + LOCATE_BOTH); } else if (cam->locate_motion_style == LOCATE_REDCROSS) { draw_red_location(location, imgs, imgs->width, img->image_norm, LOCATE_REDCROSS, - LOCATE_BOTH, cam->process_thisframe); + LOCATE_BOTH); } } } diff --git a/src/motion.hpp b/src/motion.hpp index eaf4ff6c..e4d48232 100644 --- a/src/motion.hpp +++ b/src/motion.hpp @@ -330,7 +330,6 @@ struct ctx_cam { unsigned int new_img; int locate_motion_mode; int locate_motion_style; - int process_thisframe; int noise; int threshold; int threshold_maximum; @@ -389,11 +388,8 @@ struct ctx_cam { int area_minx[9], area_miny[9], area_maxx[9], area_maxy[9]; int areadetect_eventnbr; - unsigned long long int timenow, timebefore; - unsigned int rate_limit; int minimum_frame_time_downcounter; unsigned int get_image; /* Flag used to signal that we capture new image when we run the loop */ - long int required_frame_time, frame_delay; int olddiffs; //only need this in here for a printf later...do we need that printf? int smartmask_ratio; diff --git a/src/motion_loop.cpp b/src/motion_loop.cpp index cc51b09e..d67a6110 100644 --- a/src/motion_loop.cpp +++ b/src/motion_loop.cpp @@ -517,22 +517,11 @@ static int mlp_init(struct ctx_cam *cam) { track_init(cam); - /* Work out expected frame rate based on config setting */ - if (cam->conf.framerate < 2) - cam->conf.framerate = 2; - /* 2 sec startup delay so FPS is calculated correct */ cam->startup_frames = (cam->conf.framerate * 2) + cam->conf.pre_capture + cam->conf.minimum_motion_frames; - cam->required_frame_time = 1000000L / cam->conf.framerate; - - cam->frame_delay = cam->required_frame_time; - mlp_init_areadetect(cam); - cam->timenow = 0; - cam->timebefore = 0; - cam->rate_limit = 0; cam->lastframetime = 0; cam->minimum_frame_time_downcounter = cam->conf.minimum_frame_time; cam->get_image = 1; @@ -758,23 +747,10 @@ static void mlp_prepare(struct ctx_cam *cam){ cam->watchdog = WATCHDOG_TMO; - cam->timebefore = cam->timenow; - cam->frame_last_ts.tv_sec = cam->frame_curr_ts.tv_sec; cam->frame_last_ts.tv_nsec = cam->frame_curr_ts.tv_nsec; clock_gettime(CLOCK_REALTIME, &cam->frame_curr_ts); - /* - * Calculate detection rate limit. Above 5fps we limit the detection - * rate to 3fps to reduce load at higher framerates. - */ - cam->process_thisframe = 0; - cam->rate_limit++; - if (cam->rate_limit >= (cam->lastrate / 3)) { - cam->rate_limit = 0; - cam->process_thisframe = 1; - } - if (cam->conf.minimum_motion_frames < 1) cam->conf.minimum_motion_frames = 1; @@ -817,8 +793,6 @@ static void mlp_prepare(struct ctx_cam *cam){ static void mlp_resetimages(struct ctx_cam *cam){ - struct ctx_image_data *old_image; - if (cam->conf.minimum_frame_time) { cam->minimum_frame_time_downcounter = cam->conf.minimum_frame_time; cam->get_image = 0; @@ -835,31 +809,18 @@ static void mlp_resetimages(struct ctx_cam *cam){ } /* cam->current_image points to position in ring where to store image, diffs etc. */ - old_image = cam->current_image; cam->current_image = &cam->imgs.image_ring[cam->imgs.ring_in]; - /* Init/clear current_image */ - if (cam->process_thisframe) { - /* set diffs to 0 now, will be written after we calculated diffs in new image */ - cam->current_image->diffs = 0; + /* set diffs to 0 now, will be written after we calculated diffs in new image */ + cam->current_image->diffs = 0; - /* Set flags to 0 */ - cam->current_image->flags = 0; - cam->current_image->cent_dist = 0; + /* Set flags to 0 */ + cam->current_image->flags = 0; + cam->current_image->cent_dist = 0; - /* Clear location data */ - memset(&cam->current_image->location, 0, sizeof(cam->current_image->location)); - cam->current_image->total_labels = 0; - } else if (cam->current_image && old_image) { - /* not processing this frame: save some important values for next image */ - cam->current_image->diffs = old_image->diffs; - cam->current_image->imgts = old_image->imgts; - cam->current_image->shot = old_image->shot; - cam->current_image->cent_dist = old_image->cent_dist; - cam->current_image->flags = old_image->flags & (~IMAGE_SAVED); - cam->current_image->location = old_image->location; - cam->current_image->total_labels = old_image->total_labels; - } + /* Clear location data */ + memset(&cam->current_image->location, 0, sizeof(cam->current_image->location)); + cam->current_image->total_labels = 0; clock_gettime(CLOCK_REALTIME, &cam->current_image->imgts); @@ -1068,86 +1029,85 @@ static int mlp_capture(struct ctx_cam *cam){ static void mlp_detection(struct ctx_cam *cam){ - if (cam->process_thisframe) { - if (cam->threshold && !cam->pause) { - /* - * If we've already detected motion and we want to see if there's - * still motion, don't bother trying the fast one first. IF there's - * motion, the alg_diff will trigger alg_diff_standard - * anyway - */ - if (cam->detecting_motion || cam->conf.setup_mode) - cam->current_image->diffs = alg_diff_standard(cam, cam->imgs.image_vprvcy); - else - cam->current_image->diffs = alg_diff(cam, cam->imgs.image_vprvcy); + if (cam->threshold && !cam->pause) { + /* + * If we've already detected motion and we want to see if there's + * still motion, don't bother trying the fast one first. IF there's + * motion, the alg_diff will trigger alg_diff_standard + * anyway + */ + if (cam->detecting_motion || cam->conf.setup_mode) + cam->current_image->diffs = alg_diff_standard(cam, cam->imgs.image_vprvcy); + else + cam->current_image->diffs = alg_diff(cam, cam->imgs.image_vprvcy); - /* Lightswitch feature - has light intensity changed? - * This can happen due to change of light conditions or due to a sudden change of the camera - * sensitivity. If alg_lightswitch detects lightswitch we suspend motion detection the next - * 'lightswitch_frames' frames to allow the camera to settle. - * Don't check if we have lost connection, we detect "Lost signal" frame as lightswitch - */ - if (cam->conf.lightswitch_percent > 1 && !cam->lost_connection) { - if (alg_lightswitch(cam, cam->current_image->diffs)) { - MOTION_LOG(INF, TYPE_ALL, NO_ERRNO, _("Lightswitch detected")); + /* Lightswitch feature - has light intensity changed? + * This can happen due to change of light conditions or due to a sudden change of the camera + * sensitivity. If alg_lightswitch detects lightswitch we suspend motion detection the next + * 'lightswitch_frames' frames to allow the camera to settle. + * Don't check if we have lost connection, we detect "Lost signal" frame as lightswitch + */ + if (cam->conf.lightswitch_percent > 1 && !cam->lost_connection) { + if (alg_lightswitch(cam, cam->current_image->diffs)) { + MOTION_LOG(INF, TYPE_ALL, NO_ERRNO, _("Lightswitch detected")); - if (cam->conf.lightswitch_frames < 1) - cam->conf.lightswitch_frames = 1; - else if (cam->conf.lightswitch_frames > 1000) - cam->conf.lightswitch_frames = 1000; + if (cam->conf.lightswitch_frames < 1) + cam->conf.lightswitch_frames = 1; + else if (cam->conf.lightswitch_frames > 1000) + cam->conf.lightswitch_frames = 1000; - if (cam->frame_skip < (unsigned int)cam->conf.lightswitch_frames) - cam->frame_skip = (unsigned int)cam->conf.lightswitch_frames; + if (cam->frame_skip < (unsigned int)cam->conf.lightswitch_frames) + cam->frame_skip = (unsigned int)cam->conf.lightswitch_frames; - cam->current_image->diffs = 0; - alg_update_reference_frame(cam, RESET_REF_FRAME); - } + cam->current_image->diffs = 0; + alg_update_reference_frame(cam, RESET_REF_FRAME); } - - /* - * Switchfilter feature tries to detect a change in the video signal - * from one camera to the next. This is normally used in the Round - * Robin feature. The algorithm is not very safe. - * The algorithm takes a little time so we only call it when needed - * ie. when feature is enabled and diffs>threshold. - * We do not suspend motion detection like we did for lightswitch - * because with Round Robin this is controlled by roundrobin_skip. - */ - if (cam->conf.roundrobin_switchfilter && cam->current_image->diffs > cam->threshold) { - cam->current_image->diffs = alg_switchfilter(cam, cam->current_image->diffs, - cam->current_image->image_norm); - - if ((cam->current_image->diffs <= cam->threshold) || - (cam->current_image->diffs > cam->threshold_maximum)) { - - cam->current_image->diffs = 0; - MOTION_LOG(INF, TYPE_ALL, NO_ERRNO, _("Switchfilter detected")); - } - } - - /* - * Despeckle feature - * First we run (as given by the despeckle_filter option iterations - * of erode and dilate algorithms. - * Finally we run the labelling feature. - * All this is done in the alg_despeckle code. - */ - cam->current_image->total_labels = 0; - cam->imgs.largest_label = 0; - cam->olddiffs = 0; - - if (cam->conf.despeckle_filter && cam->current_image->diffs > 0) { - cam->olddiffs = cam->current_image->diffs; - cam->current_image->diffs = alg_despeckle(cam, cam->olddiffs); - } else if (cam->imgs.labelsize_max) { - cam->imgs.labelsize_max = 0; /* Disable labeling if enabled */ - } - - } else if (!cam->conf.setup_mode) { - cam->current_image->diffs = 0; } + + /* + * Switchfilter feature tries to detect a change in the video signal + * from one camera to the next. This is normally used in the Round + * Robin feature. The algorithm is not very safe. + * The algorithm takes a little time so we only call it when needed + * ie. when feature is enabled and diffs>threshold. + * We do not suspend motion detection like we did for lightswitch + * because with Round Robin this is controlled by roundrobin_skip. + */ + if (cam->conf.roundrobin_switchfilter && cam->current_image->diffs > cam->threshold) { + cam->current_image->diffs = alg_switchfilter(cam, cam->current_image->diffs, + cam->current_image->image_norm); + + if ((cam->current_image->diffs <= cam->threshold) || + (cam->current_image->diffs > cam->threshold_maximum)) { + + cam->current_image->diffs = 0; + MOTION_LOG(INF, TYPE_ALL, NO_ERRNO, _("Switchfilter detected")); + } + } + + /* + * Despeckle feature + * First we run (as given by the despeckle_filter option iterations + * of erode and dilate algorithms. + * Finally we run the labelling feature. + * All this is done in the alg_despeckle code. + */ + cam->current_image->total_labels = 0; + cam->imgs.largest_label = 0; + cam->olddiffs = 0; + + if (cam->conf.despeckle_filter && cam->current_image->diffs > 0) { + cam->olddiffs = cam->current_image->diffs; + cam->current_image->diffs = alg_despeckle(cam, cam->olddiffs); + } else if (cam->imgs.labelsize_max) { + cam->imgs.labelsize_max = 0; /* Disable labeling if enabled */ + } + + } else if (!cam->conf.setup_mode) { + cam->current_image->diffs = 0; } + //TODO: This section needs investigation for purpose, cause and effect /* Manipulate smart_mask sensitivity (only every smartmask_ratio seconds) */ if ((cam->smartmask_speed && (cam->event_nr != cam->prev_event)) && @@ -1183,60 +1143,59 @@ static void mlp_tuning(struct ctx_cam *cam){ * If we are not noise tuning lets make sure that remote controlled * changes of noise_level are used. */ - if (cam->process_thisframe) { - /* - * threshold tuning if enabled - * if we are not threshold tuning lets make sure that remote controlled - * changes of threshold are used. - */ - if (cam->conf.threshold_tune){ - alg_threshold_tune(cam, cam->current_image->diffs, cam->detecting_motion); - } - - /* - * If motion is detected (cam->current_image->diffs > cam->threshold) and before we add text to the pictures - * we find the center and size coordinates of the motion to be used for text overlays and later - * for adding the locate rectangle - */ - if ((cam->current_image->diffs > cam->threshold) && - (cam->current_image->diffs < cam->threshold_maximum)){ - - alg_locate_center_size(&cam->imgs - , cam->imgs.width - , cam->imgs.height - , &cam->current_image->location); - } - - /* - * Update reference frame. - * micro-lighswitch: trying to auto-detect lightswitch events. - * frontdoor illumination. Updates are rate-limited to 3 per second at - * framerates above 5fps to save CPU resources and to keep sensitivity - * at a constant level. - */ - - if ((cam->current_image->diffs > cam->threshold) && - (cam->current_image->diffs < cam->threshold_maximum) && - (cam->conf.lightswitch_percent >= 1) && - (cam->lightswitch_framecounter < (cam->lastrate * 2)) && /* two seconds window only */ - /* number of changed pixels almost the same in two consecutive frames and */ - ((abs(cam->previous_diffs - cam->current_image->diffs)) < (cam->previous_diffs / 15)) && - /* center of motion in about the same place ? */ - ((abs(cam->current_image->location.x - cam->previous_location_x)) <= (cam->imgs.width / 150)) && - ((abs(cam->current_image->location.y - cam->previous_location_y)) <= (cam->imgs.height / 150))) { - alg_update_reference_frame(cam, RESET_REF_FRAME); - cam->current_image->diffs = 0; - cam->lightswitch_framecounter = 0; - - MOTION_LOG(INF, TYPE_ALL, NO_ERRNO, _("micro-lightswitch!")); - } else { - alg_update_reference_frame(cam, UPDATE_REF_FRAME); - } - cam->previous_diffs = cam->current_image->diffs; - cam->previous_location_x = cam->current_image->location.x; - cam->previous_location_y = cam->current_image->location.y; + /* + * threshold tuning if enabled + * if we are not threshold tuning lets make sure that remote controlled + * changes of threshold are used. + */ + if (cam->conf.threshold_tune){ + alg_threshold_tune(cam, cam->current_image->diffs, cam->detecting_motion); } + /* + * If motion is detected (cam->current_image->diffs > cam->threshold) and before we add text to the pictures + * we find the center and size coordinates of the motion to be used for text overlays and later + * for adding the locate rectangle + */ + if ((cam->current_image->diffs > cam->threshold) && + (cam->current_image->diffs < cam->threshold_maximum)){ + + alg_locate_center_size(&cam->imgs + , cam->imgs.width + , cam->imgs.height + , &cam->current_image->location); + } + + /* + * Update reference frame. + * micro-lighswitch: trying to auto-detect lightswitch events. + * frontdoor illumination. Updates are rate-limited to 3 per second at + * framerates above 5fps to save CPU resources and to keep sensitivity + * at a constant level. + */ + + if ((cam->current_image->diffs > cam->threshold) && + (cam->current_image->diffs < cam->threshold_maximum) && + (cam->conf.lightswitch_percent >= 1) && + (cam->lightswitch_framecounter < (cam->lastrate * 2)) && /* two seconds window only */ + /* number of changed pixels almost the same in two consecutive frames and */ + ((abs(cam->previous_diffs - cam->current_image->diffs)) < (cam->previous_diffs / 15)) && + /* center of motion in about the same place ? */ + ((abs(cam->current_image->location.x - cam->previous_location_x)) <= (cam->imgs.width / 150)) && + ((abs(cam->current_image->location.y - cam->previous_location_y)) <= (cam->imgs.height / 150))) { + alg_update_reference_frame(cam, RESET_REF_FRAME); + cam->current_image->diffs = 0; + cam->lightswitch_framecounter = 0; + + MOTION_LOG(INF, TYPE_ALL, NO_ERRNO, _("micro-lightswitch!")); + } else { + alg_update_reference_frame(cam, UPDATE_REF_FRAME); + } + cam->previous_diffs = cam->current_image->diffs; + cam->previous_location_x = cam->current_image->location.x; + cam->previous_location_y = cam->current_image->location.y; + + }