From c718ae960452e67dff8b95ba8b682a748d5750f1 Mon Sep 17 00:00:00 2001 From: Mr-Dave Date: Mon, 13 Dec 2021 19:00:01 -0700 Subject: [PATCH] Fix and cleanup movie event processing --- src/event.cpp | 181 +++++++++++++++++++++----------------------- src/event.hpp | 12 +-- src/motion_loop.cpp | 52 +++++++------ src/motionplus.hpp | 5 +- src/netcam.cpp | 18 ++++- 5 files changed, 142 insertions(+), 126 deletions(-) diff --git a/src/event.cpp b/src/event.cpp index a2b619e0..543df06d 100644 --- a/src/event.cpp +++ b/src/event.cpp @@ -35,11 +35,11 @@ const char *eventList[] = { "NULL", "EVENT_FILECREATE", "EVENT_MOTION", - "EVENT_FIRSTMOTION", - "EVENT_ENDMOTION", + "EVENT_START", + "EVENT_END", "EVENT_STOP", - "EVENT_TIMELAPSE", - "EVENT_TIMELAPSEEND", + "EVENT_TLAPSE_START", + "EVENT_TLAPSE_END", "EVENT_STREAM", "EVENT_IMAGE_DETECTED", "EVENT_IMAGEM_DETECTED", @@ -48,8 +48,6 @@ const char *eventList[] = { "EVENT_IMAGEM", "EVENT_IMAGE_PREVIEW", "EVENT_FILECLOSE", - "EVENT_DEBUG", - "EVENT_CRITICAL", "EVENT_AREA_DETECTED", "EVENT_CAMERA_LOST", "EVENT_CAMERA_FOUND", @@ -519,7 +517,7 @@ static void event_extpipe_end(struct ctx_cam *cam, motion_event evnt } } -static void event_create_extpipe(struct ctx_cam *cam, motion_event evnt +static void event_extpipe_start(struct ctx_cam *cam, motion_event evnt ,struct ctx_image_data *img_data, char *fname, void *ftype, struct timespec *ts1) { @@ -626,32 +624,9 @@ static void event_extpipe_put(struct ctx_cam *cam, motion_event evnt } } -static void event_new_video(struct ctx_cam *cam, motion_event evnt +static void event_movie_start(struct ctx_cam *cam, motion_event evnt ,struct ctx_image_data *img_data, char *fname, void *ftype, struct timespec *ts1) { - - (void)evnt; - (void)img_data; - (void)fname; - (void)ftype; - (void)ts1; - - cam->movie_last_shot = -1; - - cam->movie_fps = cam->lastrate; - - MOTION_LOG(INF, TYPE_EVENTS, NO_ERRNO, _("Source FPS %d"), cam->movie_fps); - - if (cam->movie_fps < 2) { - cam->movie_fps = 2; - } - -} - -static void event_movie_newfile(struct ctx_cam *cam, motion_event evnt - ,struct ctx_image_data *img_data, char *fname, void *ftype, struct timespec *ts1) -{ - int retcd; (void)evnt; @@ -659,8 +634,14 @@ static void event_movie_newfile(struct ctx_cam *cam, motion_event evnt (void)fname; (void)ftype; - if (!cam->conf->movie_output && !cam->conf->movie_output_motion) { - return; + /* This will cascade to extpipe_start*/ + cam->movie_start_time = cam->frame_curr_ts.tv_sec; + + cam->movie_last_shot = -1; + if (cam->lastrate < 2) { + cam->movie_fps = 2; + } else { + cam->movie_fps = cam->lastrate; } if (cam->conf->movie_output) { @@ -691,37 +672,6 @@ static void event_movie_newfile(struct ctx_cam *cam, motion_event evnt } } -static void event_movie_timelapse(struct ctx_cam *cam, motion_event evnt - ,struct ctx_image_data *img_data, char *fname, void *ftype, struct timespec *ts1) -{ - - int retcd; - - (void)evnt; - (void)fname; - (void)ftype; - - if (!cam->movie_timelapse) { - retcd = movie_init_timelapse(cam, ts1); - if (retcd < 0) { - MOTION_LOG(ERR, TYPE_EVENTS, NO_ERRNO - ,_("Error creating timelapse file [%s]"), cam->movie_timelapse->filename); - if (cam->movie_timelapse != NULL) { - free(cam->movie_timelapse); - } - cam->movie_timelapse = NULL; - return; - } - event(cam, EVENT_FILECREATE, NULL, cam->movie_timelapse->filename - , (void *)FTYPE_MPEG_TIMELAPSE, ts1); - } - - if (movie_put_image(cam->movie_timelapse, img_data, ts1) == -1) { - MOTION_LOG(ERR, TYPE_EVENTS, NO_ERRNO, _("Error encoding image")); - } - -} - static void event_movie_put(struct ctx_cam *cam, motion_event evnt ,struct ctx_image_data *img_data, char *fname, void *ftype, struct timespec *ts1) { @@ -742,7 +692,7 @@ static void event_movie_put(struct ctx_cam *cam, motion_event evnt } } -static void event_movie_closefile(struct ctx_cam *cam, motion_event evnt +static void event_movie_end(struct ctx_cam *cam, motion_event evnt ,struct ctx_image_data *img_data, char *fname, void *ftype, struct timespec *ts1) { @@ -798,7 +748,38 @@ static void event_movie_closefile(struct ctx_cam *cam, motion_event evnt } -static void event_movie_timelapseend(struct ctx_cam *cam, motion_event evnt +static void event_tlapse_start(struct ctx_cam *cam, motion_event evnt + ,struct ctx_image_data *img_data, char *fname, void *ftype, struct timespec *ts1) +{ + + int retcd; + + (void)evnt; + (void)fname; + (void)ftype; + + if (!cam->movie_timelapse) { + retcd = movie_init_timelapse(cam, ts1); + if (retcd < 0) { + MOTION_LOG(ERR, TYPE_EVENTS, NO_ERRNO + ,_("Error creating timelapse file [%s]"), cam->movie_timelapse->filename); + if (cam->movie_timelapse != NULL) { + free(cam->movie_timelapse); + } + cam->movie_timelapse = NULL; + return; + } + event(cam, EVENT_FILECREATE, NULL, cam->movie_timelapse->filename + , (void *)FTYPE_MPEG_TIMELAPSE, ts1); + } + + if (movie_put_image(cam->movie_timelapse, img_data, ts1) == -1) { + MOTION_LOG(ERR, TYPE_EVENTS, NO_ERRNO, _("Error encoding image")); + } + +} + +static void event_tlapse_end(struct ctx_cam *cam, motion_event evnt ,struct ctx_image_data *img_data, char *fname, void *ftype, struct timespec *ts1) { @@ -844,22 +825,46 @@ struct event_handlers event_handlers[] = { on_area_command }, { - EVENT_FIRSTMOTION, + EVENT_START, event_sqlfirstmotion }, { - EVENT_FIRSTMOTION, + EVENT_START, on_event_start_command }, { - EVENT_ENDMOTION, + EVENT_START, + event_movie_start + }, + { + EVENT_START, + event_extpipe_start + }, + { + EVENT_END, on_event_end_command }, { + EVENT_END, + event_movie_end + }, + { + EVENT_END, + event_extpipe_end + }, + { EVENT_IMAGE_DETECTED, event_image_detect }, { + EVENT_IMAGE_DETECTED, + event_movie_put + }, + { + EVENT_IMAGE_DETECTED, + event_extpipe_put + }, + { EVENT_IMAGEM_DETECTED, event_imagem_detect }, @@ -884,32 +889,20 @@ struct event_handlers event_handlers[] = { event_stream_put }, { - EVENT_FIRSTMOTION, - event_new_video - }, - { - EVENT_FIRSTMOTION, - event_movie_newfile - }, - { - EVENT_IMAGE_DETECTED, - event_movie_put - }, - { EVENT_MOVIE_PUT, event_movie_put }, { - EVENT_ENDMOTION, - event_movie_closefile + EVENT_MOVIE_PUT, + event_extpipe_put }, { - EVENT_TIMELAPSE, - event_movie_timelapse + EVENT_TLAPSE_START, + event_tlapse_start }, { - EVENT_TIMELAPSEEND, - event_movie_timelapseend + EVENT_TLAPSE_END, + event_tlapse_end }, { EVENT_FILECLOSE, @@ -920,19 +913,19 @@ struct event_handlers event_handlers[] = { on_movie_end_command }, { - EVENT_FIRSTMOTION, - event_create_extpipe + EVENT_MOVIE_START, + event_movie_start }, { - EVENT_IMAGE_DETECTED, - event_extpipe_put + EVENT_MOVIE_START, + event_extpipe_start }, { - EVENT_MOVIE_PUT, - event_extpipe_put + EVENT_MOVIE_END, + event_movie_end }, { - EVENT_ENDMOTION, + EVENT_END, event_extpipe_end }, { diff --git a/src/event.hpp b/src/event.hpp index a8bb9749..0196a794 100644 --- a/src/event.hpp +++ b/src/event.hpp @@ -22,10 +22,10 @@ typedef enum { EVENT_FILECREATE = 1, EVENT_MOTION, - EVENT_FIRSTMOTION, - EVENT_ENDMOTION, - EVENT_TIMELAPSE, - EVENT_TIMELAPSEEND, + EVENT_START, + EVENT_END, + EVENT_TLAPSE_START, + EVENT_TLAPSE_END, EVENT_STREAM, EVENT_IMAGE_DETECTED, EVENT_IMAGEM_DETECTED, @@ -34,12 +34,12 @@ typedef enum { EVENT_IMAGEM, EVENT_IMAGE_PREVIEW, EVENT_FILECLOSE, - EVENT_DEBUG, - EVENT_CRITICAL, EVENT_AREA_DETECTED, EVENT_CAMERA_LOST, EVENT_CAMERA_FOUND, EVENT_MOVIE_PUT, + EVENT_MOVIE_START, + EVENT_MOVIE_END, EVENT_SECDETECT, EVENT_LAST, } motion_event; diff --git a/src/motion_loop.cpp b/src/motion_loop.cpp index 41f4203c..fb44e39b 100644 --- a/src/motion_loop.cpp +++ b/src/motion_loop.cpp @@ -202,21 +202,20 @@ static void mlp_detected_trigger(struct ctx_cam *cam, struct ctx_image_data *img if (cam->event_nr != cam->prev_event) { cam->prev_event = cam->event_nr; - cam->eventtime = img->imgts.tv_sec; if (cam->algsec_inuse) { cam->algsec->isdetected = false; } + MOTION_LOG(NTC, TYPE_ALL, NO_ERRNO, _("Motion detected - starting event %d"), + cam->event_nr); + mystrftime(cam, cam->text_event_string, sizeof(cam->text_event_string), cam->conf->text_event.c_str(), &img->imgts, NULL, 0); - event(cam, EVENT_FIRSTMOTION, img, NULL, NULL, + event(cam, EVENT_START, img, NULL, NULL, &cam->imgs.image_ring[cam->imgs.ring_out].imgts); - MOTION_LOG(NTC, TYPE_ALL, NO_ERRNO, _("Motion detected - starting event %d"), - cam->event_nr); - if (cam->new_img & (NEWIMG_FIRST | NEWIMG_BEST | NEWIMG_CENTER)) { pic_save_preview(cam, img); } @@ -732,7 +731,7 @@ static int mlp_init(struct ctx_cam *cam) void mlp_cleanup(struct ctx_cam *cam) { - event(cam, EVENT_TIMELAPSEEND, NULL, NULL, NULL, NULL); + event(cam, EVENT_TLAPSE_END, NULL, NULL, NULL, NULL); /*if (cam->event_nr == cam->prev_event) { mlp_ring_process(cam); @@ -741,7 +740,7 @@ void mlp_cleanup(struct ctx_cam *cam) cam->imgs.image_preview.diffs = 0; } */ - event(cam, EVENT_ENDMOTION, NULL, NULL, NULL, &cam->current_image->imgts); + event(cam, EVENT_END, NULL, NULL, NULL, &cam->current_image->imgts); /* } */ webu_stream_deinit(cam); @@ -964,6 +963,7 @@ static void mlp_resetimages(struct ctx_cam *cam) cam->current_image->total_labels = 0; clock_gettime(CLOCK_REALTIME, &cam->current_image->imgts); + clock_gettime(CLOCK_MONOTONIC, &cam->current_image->monots); /* Store shot number with pre_captured image */ cam->current_image->shot = cam->shots; @@ -1302,13 +1302,9 @@ static void mlp_actions_motion(struct ctx_cam *cam) static void mlp_actions_event(struct ctx_cam *cam) { - if ((cam->conf->movie_max_time > 0) && - (cam->event_nr == cam->prev_event) && - ((cam->frame_curr_ts.tv_sec - cam->eventtime) >= cam->conf->movie_max_time)) { - cam->event_stop = true; - } + /* Other functions may also set the event_stop */ if ((cam->conf->event_gap > 0) && - ((cam->frame_curr_ts.tv_sec - cam->lasttime) >= cam->conf->event_gap)) { + ((cam->frame_curr_ts.tv_sec - cam->lasttime ) >= cam->conf->event_gap)) { cam->event_stop = true; } @@ -1321,7 +1317,7 @@ static void mlp_actions_event(struct ctx_cam *cam) event(cam, EVENT_IMAGE_PREVIEW, NULL, NULL, NULL, &cam->current_image->imgts); cam->imgs.image_preview.diffs = 0; } - event(cam, EVENT_ENDMOTION, NULL, NULL, NULL, &cam->current_image->imgts); + event(cam, EVENT_END, NULL, NULL, NULL, &cam->current_image->imgts); mlp_track_center(cam); @@ -1341,11 +1337,21 @@ static void mlp_actions_event(struct ctx_cam *cam) cam->event_stop = false; cam->event_user = false; } + + if ((cam->conf->movie_max_time > 0) && + (cam->event_nr == cam->prev_event) && + ((cam->frame_curr_ts.tv_sec - cam->movie_start_time) >= + cam->conf->movie_max_time) && + ( !(cam->current_image->flags & IMAGE_POSTCAP)) && + ( !(cam->current_image->flags & IMAGE_PRECAP))) { + event(cam, EVENT_MOVIE_END, NULL, NULL, NULL, &cam->current_image->imgts); + event(cam, EVENT_MOVIE_START, NULL, NULL, NULL, &cam->current_image->imgts); + } + } static void mlp_actions(struct ctx_cam *cam) { - if ((cam->current_image->diffs > cam->threshold) && (cam->current_image->diffs < cam->threshold_maximum)) { cam->current_image->flags |= IMAGE_MOTION; @@ -1367,7 +1373,7 @@ static void mlp_actions(struct ctx_cam *cam) } if (cam->current_image->flags & IMAGE_SAVE) { - cam->lasttime = cam->current_image->imgts.tv_sec; + cam->lasttime = cam->current_image->monots.tv_sec; } if (cam->detecting_motion) { @@ -1444,21 +1450,21 @@ static void mlp_timelapse(struct ctx_cam *cam) if (cam->conf->timelapse_mode == "daily") { if (timestamp_tm.tm_hour == 0) { - event(cam, EVENT_TIMELAPSEEND, NULL, NULL, NULL, &cam->current_image->imgts); + event(cam, EVENT_TLAPSE_END, NULL, NULL, NULL, &cam->current_image->imgts); } } else if (cam->conf->timelapse_mode == "hourly") { - event(cam, EVENT_TIMELAPSEEND, NULL, NULL, NULL, &cam->current_image->imgts); + event(cam, EVENT_TLAPSE_END, NULL, NULL, NULL, &cam->current_image->imgts); } else if (cam->conf->timelapse_mode == "weekly-sunday") { if (timestamp_tm.tm_wday == 0 && timestamp_tm.tm_hour == 0) { - event(cam, EVENT_TIMELAPSEEND, NULL, NULL, NULL, &cam->current_image->imgts); + event(cam, EVENT_TLAPSE_END, NULL, NULL, NULL, &cam->current_image->imgts); } } else if (cam->conf->timelapse_mode == "weekly-monday") { if (timestamp_tm.tm_wday == 1 && timestamp_tm.tm_hour == 0) { - event(cam, EVENT_TIMELAPSEEND, NULL, NULL, NULL, &cam->current_image->imgts); + event(cam, EVENT_TLAPSE_END, NULL, NULL, NULL, &cam->current_image->imgts); } } else if (cam->conf->timelapse_mode == "monthly") { if (timestamp_tm.tm_mday == 1 && timestamp_tm.tm_hour == 0) { - event(cam, EVENT_TIMELAPSEEND, NULL, NULL, NULL, &cam->current_image->imgts); + event(cam, EVENT_TLAPSE_END, NULL, NULL, NULL, &cam->current_image->imgts); } } } @@ -1466,7 +1472,7 @@ static void mlp_timelapse(struct ctx_cam *cam) if (cam->shots == 0 && cam->frame_curr_ts.tv_sec % cam->conf->timelapse_interval <= cam->frame_last_ts.tv_sec % cam->conf->timelapse_interval) { - event(cam, EVENT_TIMELAPSE, cam->current_image, NULL + event(cam, EVENT_TLAPSE_START, cam->current_image, NULL , NULL, &cam->current_image->imgts); } @@ -1476,7 +1482,7 @@ static void mlp_timelapse(struct ctx_cam *cam) * This is an important feature that allows manual roll-over of timelapse file using the http * remote control via a cron job. */ - event(cam, EVENT_TIMELAPSEEND, NULL, NULL, NULL, &cam->current_image->imgts); + event(cam, EVENT_TLAPSE_END, NULL, NULL, NULL, &cam->current_image->imgts); } } diff --git a/src/motionplus.hpp b/src/motionplus.hpp index 91c8b35a..3a1932a6 100644 --- a/src/motionplus.hpp +++ b/src/motionplus.hpp @@ -206,7 +206,8 @@ struct ctx_image_data { int diffs_ratio; int64_t idnbr_norm; int64_t idnbr_high; - struct timespec imgts; + struct timespec imgts; /* Realtime for display */ + struct timespec monots; /* Montonic clock for timing */ int shot; /* Sub second timestamp count */ unsigned long cent_dist; /* Movement center to img center distance * Note: Dist is calculated distX*distX + distY*distY */ unsigned int flags; /* See IMAGE_* defines */ @@ -343,7 +344,7 @@ struct ctx_cam { struct timespec frame_last_ts; time_t lasttime; - time_t eventtime; + time_t movie_start_time; time_t connectionlosttime; /* timestamp from connection lost */ unsigned int lastrate; unsigned int startup_frames; diff --git a/src/netcam.cpp b/src/netcam.cpp index ff4f5350..a24104d8 100644 --- a/src/netcam.cpp +++ b/src/netcam.cpp @@ -1953,7 +1953,7 @@ static void netcam_handler_wait(struct ctx_netcam *netcam) static void netcam_handler_reconnect(struct ctx_netcam *netcam) { - int retcd; + int retcd, indx; if ((netcam->status == NETCAM_CONNECTED) || (netcam->status == NETCAM_READINGIMAGE)) { @@ -1962,6 +1962,22 @@ static void netcam_handler_reconnect(struct ctx_netcam *netcam) } netcam->status = NETCAM_RECONNECTING; + /* When doing passthrough movies, any movies in progress + * must end and start again because the cache'd packets and timing + * on them gets all messed up. So we loop through the list of cameras + * and find the pointer that matches our passed in netcam. + */ + if (netcam->passthrough == true) { + indx = 1; + while (netcam->motapp->cam_list[indx] != NULL) { + if ((netcam->motapp->cam_list[indx]->netcam == netcam) || + (netcam->motapp->cam_list[indx]->netcam_high == netcam)) { + netcam->motapp->cam_list[indx]->event_stop = true; + } + indx++; + } + } + /* * The retry count of 100 is arbritrary. * We want to try many times quickly to not lose too much information