From a7ff96a0d2d01c949237ec85a6120bbb0401654e Mon Sep 17 00:00:00 2001 From: Mr-Dave Date: Thu, 15 Aug 2024 17:31:20 -0600 Subject: [PATCH] Revise from ctx_dev to cls_camera --- src/alg.cpp | 5 +- src/alg.hpp | 4 +- src/alg_sec.cpp | 11 +- src/alg_sec.hpp | 4 +- src/camera.cpp | 1535 +++++++++++++++++++++------------------- src/camera.hpp | 235 +++++- src/conf.cpp | 159 ++--- src/conf.hpp | 8 +- src/dbse.cpp | 5 +- src/dbse.hpp | 4 +- src/draw.cpp | 4 +- src/draw.hpp | 4 +- src/jpegutils.cpp | 11 +- src/jpegutils.hpp | 6 +- src/libcam.cpp | 14 +- src/libcam.hpp | 6 +- src/logger.cpp | 3 +- src/motionplus.cpp | 610 +++++----------- src/motionplus.hpp | 225 +----- src/movie.cpp | 3 +- src/movie.hpp | 4 +- src/netcam.cpp | 20 +- src/netcam.hpp | 4 +- src/picture.cpp | 42 +- src/picture.hpp | 4 +- src/rotate.cpp | 3 +- src/rotate.hpp | 4 +- src/sound.cpp | 12 +- src/util.cpp | 15 +- src/util.hpp | 6 +- src/video_convert.cpp | 3 +- src/video_convert.hpp | 4 +- src/video_loopback.cpp | 5 +- src/video_loopback.hpp | 4 +- src/video_v4l2.cpp | 6 +- src/video_v4l2.hpp | 5 +- src/webu.cpp | 1 + src/webu_ans.cpp | 10 +- src/webu_ans.hpp | 2 +- src/webu_common.cpp | 11 +- src/webu_common.hpp | 4 +- src/webu_file.cpp | 1 + src/webu_getimg.cpp | 19 +- src/webu_getimg.hpp | 6 +- src/webu_html.cpp | 1 + src/webu_json.cpp | 5 +- src/webu_mpegts.cpp | 1 + src/webu_post.cpp | 23 +- src/webu_stream.cpp | 5 +- 49 files changed, 1461 insertions(+), 1625 deletions(-) diff --git a/src/alg.cpp b/src/alg.cpp index 31247d13..e133babe 100644 --- a/src/alg.cpp +++ b/src/alg.cpp @@ -18,9 +18,10 @@ #include "motionplus.hpp" #include "conf.hpp" #include "util.hpp" -#include "alg.hpp" +#include "camera.hpp" #include "draw.hpp" #include "logger.hpp" +#include "alg.hpp" #define MAX2(x, y) ((x) > (y) ? (x) : (y)) #define MAX3(x, y, z) ((x) > (y) ? ((x) > (z) ? (x) : (z)) : ((y) > (z) ? (y) : (z))) @@ -1225,7 +1226,7 @@ void cls_alg::init_conf() cfg_smart_mask_speed = cam->conf->smart_mask_speed; } -cls_alg::cls_alg(ctx_dev *p_cam) +cls_alg::cls_alg(cls_camera *p_cam) { int i; diff --git a/src/alg.hpp b/src/alg.hpp index da555e78..c904c15e 100644 --- a/src/alg.hpp +++ b/src/alg.hpp @@ -22,7 +22,7 @@ class cls_alg { public: - cls_alg(ctx_dev *p_cam); + cls_alg(cls_camera *p_cam); ~cls_alg(); void diff(); void noise_tune(); @@ -34,7 +34,7 @@ void location(); u_char *smartmask_final; private: - ctx_dev *cam; + cls_camera *cam; int smartmask_count; u_char *smartmask; int *smartmask_buffer; diff --git a/src/alg_sec.cpp b/src/alg_sec.cpp index 96b87605..0586c6b8 100644 --- a/src/alg_sec.cpp +++ b/src/alg_sec.cpp @@ -17,6 +17,7 @@ */ #include "motionplus.hpp" +#include "camera.hpp" #include "conf.hpp" #include "util.hpp" #include "logger.hpp" @@ -547,7 +548,6 @@ void cls_algsec::handler() MOTPLS_LOG(INF, TYPE_ALL, NO_ERRNO,_("Secondary detection starting.")); handler_finished = false; - cam->motapp->threads_running++; handler_stop = false; interval = 1000000L / cfg_framerate; @@ -612,9 +612,6 @@ void cls_algsec::deinit() MOTPLS_LOG(ERR, TYPE_ALL, NO_ERRNO ,_("Shutdown of secondary detector failed")); pthread_kill(handler_thread.native_handle(), SIGVTALRM); - pthread_mutex_lock(&cam->motapp->global_lock); - cam->motapp->threads_running--; - pthread_mutex_unlock(&cam->motapp->global_lock); } } @@ -671,14 +668,14 @@ void cls_algsec::detect() #endif } -cls_algsec::cls_algsec(ctx_dev *p_cam) +cls_algsec::cls_algsec(cls_camera *p_cam) { #ifdef HAVE_OPENCV cam = p_cam; - mythreadname_set("cv",cam->threadnr,cam->conf->device_name.c_str()); + mythreadname_set("cv",cam->device_id, cam->conf->device_name.c_str()); load_params(); start_model(); - mythreadname_set("ml",cam->threadnr,cam->conf->device_name.c_str()); + mythreadname_set("cl",cam->device_id, cam->conf->device_name.c_str()); #else (void)p_cam; #endif diff --git a/src/alg_sec.hpp b/src/alg_sec.hpp index 7d2e20ac..35cbb2ef 100644 --- a/src/alg_sec.hpp +++ b/src/alg_sec.hpp @@ -32,7 +32,7 @@ class cls_algsec { public: - cls_algsec(ctx_dev *p_cam); + cls_algsec(cls_camera *p_cam); ~cls_algsec(); void detect(); bool detected; @@ -41,7 +41,7 @@ class cls_algsec { private: #ifdef HAVE_OPENCV - ctx_dev *cam; + cls_camera *cam; std::thread handler_thread; bool handler_finished; bool handler_stop; diff --git a/src/camera.cpp b/src/camera.cpp index d8948751..8a2c9a85 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -36,13 +36,19 @@ #include "draw.hpp" #include "webu_getimg.hpp" +static void *camera_handler(void *arg) +{ + ((cls_camera *)arg)->handler(); + return nullptr; +} + /* Resize the image ring */ -static void mlp_ring_resize(ctx_dev *cam) +void cls_camera::ring_resize() { int i, new_size; ctx_image_data *tmp; - new_size = cam->conf->pre_capture + cam->conf->minimum_motion_frames; + new_size = conf->pre_capture + conf->minimum_motion_frames; if (new_size < 1) { new_size = 1; } @@ -53,260 +59,260 @@ static void mlp_ring_resize(ctx_dev *cam) tmp =(ctx_image_data*) mymalloc((uint)new_size * sizeof(ctx_image_data)); for(i = 0; i < new_size; i++) { - tmp[i].image_norm =(unsigned char*) mymalloc((uint)cam->imgs.size_norm); - memset(tmp[i].image_norm, 0x80, (uint)cam->imgs.size_norm); - if (cam->imgs.size_high > 0) { - tmp[i].image_high =(unsigned char*) mymalloc((uint)cam->imgs.size_high); - memset(tmp[i].image_high, 0x80, (uint)cam->imgs.size_high); + tmp[i].image_norm =(u_char*) mymalloc((uint)imgs.size_norm); + memset(tmp[i].image_norm, 0x80, (uint)imgs.size_norm); + if (imgs.size_high > 0) { + tmp[i].image_high =(u_char*) mymalloc((uint)imgs.size_high); + memset(tmp[i].image_high, 0x80, (uint)imgs.size_high); } } - cam->imgs.image_ring = tmp; - cam->current_image = NULL; - cam->imgs.ring_size = new_size; - cam->imgs.ring_in = 0; - cam->imgs.ring_out = 0; + imgs.image_ring = tmp; + current_image = NULL; + imgs.ring_size = new_size; + imgs.ring_in = 0; + imgs.ring_out = 0; } /* Clean image ring */ -static void mlp_ring_destroy(ctx_dev *cam) +void cls_camera::ring_destroy() { int i; - if (cam->imgs.image_ring == NULL) { + if (imgs.image_ring == NULL) { return; } - for (i = 0; i < cam->imgs.ring_size; i++) { - myfree(cam->imgs.image_ring[i].image_norm); - myfree(cam->imgs.image_ring[i].image_high); + for (i = 0; i < imgs.ring_size; i++) { + myfree(imgs.image_ring[i].image_norm); + myfree(imgs.image_ring[i].image_high); } - myfree(cam->imgs.image_ring); + myfree(imgs.image_ring); /* * current_image is an alias from the pointers above which have * already been freed so we just set it equal to NULL here */ - cam->current_image = NULL; + current_image = NULL; - cam->imgs.ring_size = 0; + imgs.ring_size = 0; } /* Add debug messsage to image */ -static void mlp_ring_process_debug(ctx_dev *cam) +void cls_camera::ring_process_debug() { char tmp[32]; const char *t; - if (cam->current_image->flags & IMAGE_TRIGGER) { + if (current_image->flags & IMAGE_TRIGGER) { t = "Trigger"; - } else if (cam->current_image->flags & IMAGE_MOTION) { + } else if (current_image->flags & IMAGE_MOTION) { t = "Motion"; - } else if (cam->current_image->flags & IMAGE_PRECAP) { + } else if (current_image->flags & IMAGE_PRECAP) { t = "Precap"; - } else if (cam->current_image->flags & IMAGE_POSTCAP) { + } else if (current_image->flags & IMAGE_POSTCAP) { t = "Postcap"; } else { t = "Other"; } - mystrftime(cam, tmp, sizeof(tmp), "%H%M%S-%q", NULL); - cam->draw->text(cam->imgs.image_ring[cam->imgs.ring_out].image_norm - , cam->imgs.width, cam->imgs.height - , 10, 20, tmp, cam->text_scale); - cam->draw->text(cam->imgs.image_ring[cam->imgs.ring_out].image_norm - , cam->imgs.width, cam->imgs.height - , 10, 30, t, cam->text_scale); + mystrftime(this, tmp, sizeof(tmp), "%H%M%S-%q", NULL); + draw->text(imgs.image_ring[imgs.ring_out].image_norm + , imgs.width, imgs.height + , 10, 20, tmp, text_scale); + draw->text(imgs.image_ring[imgs.ring_out].image_norm + , imgs.width, imgs.height + , 10, 30, t, text_scale); } -static void mlp_ring_process_image(ctx_dev *cam) +void cls_camera::ring_process_image() { - cam->picture->process_norm(); - if (cam->movie_norm->put_image(cam->current_image - , &cam->current_image->imgts) == -1) { + picture->process_norm(); + if (movie_norm->put_image(current_image + , ¤t_image->imgts) == -1) { MOTPLS_LOG(ERR, TYPE_EVENTS, NO_ERRNO, _("Error encoding image")); } - if (cam->movie_motion->put_image(&cam->imgs.image_motion - , &cam->imgs.image_motion.imgts) == -1) { + if (movie_motion->put_image(&imgs.image_motion + , &imgs.image_motion.imgts) == -1) { MOTPLS_LOG(ERR, TYPE_EVENTS, NO_ERRNO, _("Error encoding image")); } - if (cam->movie_extpipe->put_image(cam->current_image - , &cam->current_image->imgts) == -1) { + if (movie_extpipe->put_image(current_image + , ¤t_image->imgts) == -1) { MOTPLS_LOG(ERR, TYPE_EVENTS, NO_ERRNO, _("Error encoding image")); } } /* Process the entire image ring */ -static void mlp_ring_process(ctx_dev *cam) +void cls_camera::ring_process() { - ctx_image_data *saved_current_image = cam->current_image; + ctx_image_data *saved_current_image = current_image; do { - if ((cam->imgs.image_ring[cam->imgs.ring_out].flags & (IMAGE_SAVE | IMAGE_SAVED)) != IMAGE_SAVE) { + if ((imgs.image_ring[imgs.ring_out].flags & (IMAGE_SAVE | IMAGE_SAVED)) != IMAGE_SAVE) { break; } - cam->current_image = &cam->imgs.image_ring[cam->imgs.ring_out]; + current_image = &imgs.image_ring[imgs.ring_out]; - if (cam->current_image->shot <= cam->conf->framerate) { - if (cam->motapp->conf->log_level >= DBG) { - mlp_ring_process_debug(cam); + if (current_image->shot <= conf->framerate) { + if (motapp->conf->log_level >= DBG) { + ring_process_debug(); } - mlp_ring_process_image(cam); + ring_process_image(); } - cam->current_image->flags |= IMAGE_SAVED; + current_image->flags |= IMAGE_SAVED; - if (cam->current_image->flags & IMAGE_MOTION) { - if (cam->conf->picture_output == "best") { - if (cam->current_image->diffs > cam->imgs.image_preview.diffs) { - cam->picture->save_preview(); + if (current_image->flags & IMAGE_MOTION) { + if (conf->picture_output == "best") { + if (current_image->diffs > imgs.image_preview.diffs) { + picture->save_preview(); } } - if (cam->conf->picture_output == "center") { - if (cam->current_image->cent_dist < cam->imgs.image_preview.cent_dist) { - cam->picture->save_preview(); + if (conf->picture_output == "center") { + if (current_image->cent_dist < imgs.image_preview.cent_dist) { + picture->save_preview(); } } } - if (++cam->imgs.ring_out >= cam->imgs.ring_size) { - cam->imgs.ring_out = 0; + if (++imgs.ring_out >= imgs.ring_size) { + imgs.ring_out = 0; } - } while (cam->imgs.ring_out != cam->imgs.ring_in); + } while (imgs.ring_out != imgs.ring_in); - cam->current_image = saved_current_image; + current_image = saved_current_image; } /* Reset the image info variables*/ -static void mlp_info_reset(ctx_dev *cam) +void cls_camera::info_reset() { - cam->info_diff_cnt = 0; - cam->info_diff_tot = 0; - cam->info_sdev_min = 99999999; - cam->info_sdev_max = 0; - cam->info_sdev_tot = 0; + info_diff_cnt = 0; + info_diff_tot = 0; + info_sdev_min = 99999999; + info_sdev_max = 0; + info_sdev_tot = 0; } -static void mlp_movie_start(ctx_dev *cam) +void cls_camera::movie_start() { - cam->movie_start_time = cam->frame_curr_ts.tv_sec; - if (cam->lastrate < 2) { - cam->movie_fps = 2; + movie_start_time = frame_curr_ts.tv_sec; + if (lastrate < 2) { + movie_fps = 2; } else { - cam->movie_fps = cam->lastrate; + movie_fps = lastrate; } - cam->movie_norm->start(); - cam->movie_motion->start(); - cam->movie_extpipe->start(); + movie_norm->start(); + movie_motion->start(); + movie_extpipe->start(); } -static void mlp_movie_end(ctx_dev *cam) +void cls_camera::movie_end() { - cam->movie_norm->stop(); - cam->movie_motion->stop(); - cam->movie_extpipe->stop(); + movie_norm->stop(); + movie_motion->stop(); + movie_extpipe->stop(); } /* Process the motion detected items*/ -static void mlp_detected_trigger(ctx_dev *cam) +void cls_camera::detected_trigger() { time_t raw_time; struct tm evt_tm; - if (cam->current_image->flags & IMAGE_TRIGGER) { - if (cam->event_curr_nbr != cam->event_prev_nbr) { - mlp_info_reset(cam); - cam->event_prev_nbr = cam->event_curr_nbr; + if (current_image->flags & IMAGE_TRIGGER) { + if (event_curr_nbr != event_prev_nbr) { + info_reset(); + event_prev_nbr = event_curr_nbr; - cam->algsec->detected = false; + algsec->detected = false; time(&raw_time); localtime_r(&raw_time, &evt_tm); - sprintf(cam->eventid, "%05d", cam->device_id); - strftime(cam->eventid+5, 15, "%Y%m%d%H%M%S", &evt_tm); + sprintf(eventid, "%05d", device_id); + strftime(eventid+5, 15, "%Y%m%d%H%M%S", &evt_tm); MOTPLS_LOG(NTC, TYPE_ALL, NO_ERRNO, _("Motion detected - starting event %d"), - cam->event_curr_nbr); + event_curr_nbr); - mystrftime(cam, cam->text_event_string - , sizeof(cam->text_event_string) - , cam->conf->text_event.c_str(), NULL); + mystrftime(this, text_event_string + , sizeof(text_event_string) + , conf->text_event.c_str(), NULL); - if (cam->conf->on_event_start != "") { - util_exec_command(cam, cam->conf->on_event_start.c_str(), NULL); + if (conf->on_event_start != "") { + util_exec_command(this, conf->on_event_start.c_str(), NULL); } - mlp_movie_start(cam); - cam->motapp->dbse->exec(cam, "", "event_start"); + movie_start(); + motapp->dbse->exec(this, "", "event_start"); - if ((cam->conf->picture_output == "first") || - (cam->conf->picture_output == "best") || - (cam->conf->picture_output == "center")) { - cam->picture->save_preview(); + if ((conf->picture_output == "first") || + (conf->picture_output == "best") || + (conf->picture_output == "center")) { + picture->save_preview(); } } - if (cam->conf->on_motion_detected != "") { - util_exec_command(cam, cam->conf->on_motion_detected.c_str(), NULL); + if (conf->on_motion_detected != "") { + util_exec_command(this, conf->on_motion_detected.c_str(), NULL); } } } /* call ptz camera center */ -static void mlp_track_center(ctx_dev *cam) +void cls_camera::track_center() { - if ((cam->conf->ptz_auto_track) && (cam->conf->ptz_move_track != "")) { - cam->track_posx = 0; - cam->track_posy = 0; - util_exec_command(cam, cam->conf->ptz_move_track.c_str(), NULL); - cam->frame_skip = cam->conf->ptz_wait; + if ((conf->ptz_auto_track) && (conf->ptz_move_track != "")) { + track_posx = 0; + track_posy = 0; + util_exec_command(this, conf->ptz_move_track.c_str(), NULL); + frame_skip = conf->ptz_wait; } } /* call ptz camera move */ -static void mlp_track_move(ctx_dev *cam) +void cls_camera::track_move() { - if ((cam->conf->ptz_auto_track) && (cam->conf->ptz_move_track != "")) { - cam->track_posx += cam->current_image->location.x; - cam->track_posy += cam->current_image->location.y; - util_exec_command(cam, cam->conf->ptz_move_track.c_str(), NULL); - cam->frame_skip = cam->conf->ptz_wait; + if ((conf->ptz_auto_track) && (conf->ptz_move_track != "")) { + track_posx += current_image->location.x; + track_posy += current_image->location.y; + util_exec_command(this, conf->ptz_move_track.c_str(), NULL); + frame_skip = conf->ptz_wait; } } /* motion detected */ -static void mlp_detected(ctx_dev *cam) +void cls_camera::detected() { unsigned int distX, distY; - cam->draw->locate(); + draw->locate(); /* Calculate how centric motion is if configured preview center*/ - if (cam->conf->picture_output == "center") { - distX = (uint)abs((cam->imgs.width / 2) - cam->current_image->location.x ); - distY = (uint)abs((cam->imgs.height / 2) - cam->current_image->location.y); - cam->current_image->cent_dist = distX * distX + distY * distY; + if (conf->picture_output == "center") { + distX = (uint)abs((imgs.width / 2) - current_image->location.x ); + distY = (uint)abs((imgs.height / 2) - current_image->location.y); + current_image->cent_dist = distX * distX + distY * distY; } - mlp_detected_trigger(cam); + detected_trigger(); - if (cam->current_image->shot <= cam->conf->framerate) { - if ((cam->conf->stream_motion == true) && - (cam->current_image->shot != 1)) { - webu_getimg_main(cam); + if (current_image->shot <= conf->framerate) { + if ((conf->stream_motion == true) && + (current_image->shot != 1)) { + webu_getimg_main(this); } - cam->picture->process_motion(); + picture->process_motion(); } - mlp_track_move(cam); + track_move(); } /* Apply the privacy mask to image*/ -static void mlp_mask_privacy(ctx_dev *cam) +void cls_camera::mask_privacy() { - if (cam->imgs.mask_privacy == NULL) { + if (imgs.mask_privacy == NULL) { return; } @@ -315,9 +321,9 @@ static void mlp_mask_privacy(ctx_dev *cam) * bytes at a time, providing a significant boost in performance. * Then a trailer loop takes care of any remaining bytes. */ - unsigned char *image; - const unsigned char *mask; - const unsigned char *maskuv; + u_char *image; + const u_char *mask; + const u_char *maskuv; int index_y; int index_crcb; @@ -326,7 +332,7 @@ static void mlp_mask_privacy(ctx_dev *cam) int indx_max; /* 1 if we are only doing norm, 2 if we are doing both norm and high */ indx_img = 1; - if (cam->imgs.size_high > 0) { + if (imgs.size_high > 0) { indx_max = 2; } else { indx_max = 1; @@ -336,18 +342,18 @@ static void mlp_mask_privacy(ctx_dev *cam) while (indx_img <= indx_max) { if (indx_img == 1) { /* Normal Resolution */ - index_y = cam->imgs.height * cam->imgs.width; - image = cam->current_image->image_norm; - mask = cam->imgs.mask_privacy; - index_crcb = cam->imgs.size_norm - index_y; - maskuv = cam->imgs.mask_privacy_uv; + index_y = imgs.height * imgs.width; + image = current_image->image_norm; + mask = imgs.mask_privacy; + index_crcb = imgs.size_norm - index_y; + maskuv = imgs.mask_privacy_uv; } else { /* High Resolution */ - index_y = cam->imgs.height_high * cam->imgs.width_high; - image = cam->current_image->image_high; - mask = cam->imgs.mask_privacy_high; - index_crcb = cam->imgs.size_high - index_y; - maskuv = cam->imgs.mask_privacy_high_uv; + index_y = imgs.height_high * imgs.width_high; + image = current_image->image_high; + mask = imgs.mask_privacy_high; + index_crcb = imgs.size_high - index_y; + maskuv = imgs.mask_privacy_high_uv; } while (index_y >= increment) { @@ -388,49 +394,52 @@ static void mlp_mask_privacy(ctx_dev *cam) } /* Close and clean up camera*/ -void mlp_cam_close(ctx_dev *cam) +void cls_camera::cam_close() { - mydelete(cam->libcam); - mydelete(cam->v4l2cam); - mydelete(cam->netcam); - mydelete(cam->netcam_high); + mydelete(libcam); + mydelete(v4l2cam); + mydelete(netcam); + mydelete(netcam_high); } /* Start camera */ -void mlp_cam_start(ctx_dev *cam) +void cls_camera::cam_start() { - if (cam->camera_type == CAMERA_TYPE_LIBCAM) { - cam->libcam = new cls_libcam(cam); - } else if (cam->camera_type == CAMERA_TYPE_NETCAM) { - cam->netcam = new cls_netcam(cam, false); - if (cam->conf->netcam_high_url != "") { - cam->netcam_high = new cls_netcam(cam, true); + watchdog = conf->watchdog_tmo; + if (camera_type == CAMERA_TYPE_LIBCAM) { + libcam = new cls_libcam(this); + } else if (camera_type == CAMERA_TYPE_NETCAM) { + netcam = new cls_netcam(this, false); + if (conf->netcam_high_url != "") { + watchdog = conf->watchdog_tmo; + netcam_high = new cls_netcam(this, true); } - } else if (cam->camera_type == CAMERA_TYPE_V4L2) { - cam->v4l2cam = new cls_v4l2cam(cam); + } else if (camera_type == CAMERA_TYPE_V4L2) { + v4l2cam = new cls_v4l2cam(this); } else { MOTPLS_LOG(ERR, TYPE_VIDEO, NO_ERRNO ,_("No Camera device specified")); - cam->device_status = STATUS_CLOSED; + device_status = STATUS_CLOSED; } + watchdog = conf->watchdog_tmo; } /* Get next image from camera */ -int mlp_cam_next(ctx_dev *cam, ctx_image_data *img_data) +int cls_camera::cam_next(ctx_image_data *img_data) { int retcd; - if (cam->camera_type == CAMERA_TYPE_LIBCAM) { - retcd = cam->libcam->next(img_data); - } else if (cam->camera_type == CAMERA_TYPE_NETCAM) { - retcd = cam->netcam->next(img_data); + if (camera_type == CAMERA_TYPE_LIBCAM) { + retcd = libcam->next(img_data); + } else if (camera_type == CAMERA_TYPE_NETCAM) { + retcd = netcam->next(img_data); if ((retcd == CAPTURE_SUCCESS) && - (cam->netcam_high != nullptr)) { - retcd = cam->netcam_high->next(img_data); + (netcam_high != nullptr)) { + retcd = netcam_high->next(img_data); } - cam->rotate->process(img_data); - } else if (cam->camera_type == CAMERA_TYPE_V4L2) { - retcd = cam->v4l2cam->next(img_data); + rotate->process(img_data); + } else if (camera_type == CAMERA_TYPE_V4L2) { + retcd = v4l2cam->next(img_data); } else { retcd = -1; } @@ -440,33 +449,33 @@ int mlp_cam_next(ctx_dev *cam, ctx_image_data *img_data) } /* Assign the camera type */ -static void mlp_init_camera_type(ctx_dev *cam) +void cls_camera::init_camera_type() { - if (cam->conf->libcam_device != "") { - cam->camera_type = CAMERA_TYPE_LIBCAM; - } else if (cam->conf->netcam_url != "") { - cam->camera_type = CAMERA_TYPE_NETCAM; - } else if (cam->conf->v4l2_device != "") { - cam->camera_type = CAMERA_TYPE_V4L2; + if (conf->libcam_device != "") { + camera_type = CAMERA_TYPE_LIBCAM; + } else if (conf->netcam_url != "") { + camera_type = CAMERA_TYPE_NETCAM; + } else if (conf->v4l2_device != "") { + camera_type = CAMERA_TYPE_V4L2; } else { MOTPLS_LOG(ERR, TYPE_ALL, NO_ERRNO , _("Unable to determine camera type")); - cam->camera_type = CAMERA_TYPE_UNKNOWN; - cam->finish_dev = true; - cam->restart_dev = false; + camera_type = CAMERA_TYPE_UNKNOWN; + handler_stop = true; + restart = false; } } /** Get first images from camera at startup */ -static void mlp_init_firstimage(ctx_dev *cam) +void cls_camera::init_firstimage() { int indx; const char *msg; - cam->current_image = &cam->imgs.image_ring[cam->imgs.ring_in]; - if (cam->device_status == STATUS_OPENED) { + current_image = &imgs.image_ring[imgs.ring_in]; + if (device_status == STATUS_OPENED) { for (indx = 0; indx < 5; indx++) { - if (mlp_cam_next(cam, cam->current_image) == CAPTURE_SUCCESS) { + if (cam_next(current_image) == CAPTURE_SUCCESS) { break; } SLEEP(2, 0); @@ -475,50 +484,50 @@ static void mlp_init_firstimage(ctx_dev *cam) indx = 0; } - if ((indx >= 5) || (cam->device_status != STATUS_OPENED)) { - if (cam->device_status != STATUS_OPENED) { + if ((indx >= 5) || (device_status != STATUS_OPENED)) { + if (device_status != STATUS_OPENED) { msg = "Unable to open camera"; } else { msg = "Error capturing first image"; } MOTPLS_LOG(ERR, TYPE_ALL, NO_ERRNO, "%s", msg); - for (indx = 0; indximgs.ring_size; indx++) { - memset(cam->imgs.image_ring[indx].image_norm - , 0x80, (uint)cam->imgs.size_norm); - cam->draw->text(cam->imgs.image_ring[indx].image_norm - , cam->imgs.width, cam->imgs.height - , 10, 20 * cam->text_scale - , msg, cam->text_scale); + for (indx = 0; indxtext(imgs.image_ring[indx].image_norm + , imgs.width, imgs.height + , 10, 20 * text_scale + , msg, text_scale); } } - cam->noise = cam->conf->noise_level; - cam->threshold = cam->conf->threshold; - if (cam->conf->threshold_maximum > cam->conf->threshold ) { - cam->threshold_maximum = cam->conf->threshold_maximum; + noise = conf->noise_level; + threshold = conf->threshold; + if (conf->threshold_maximum > conf->threshold ) { + threshold_maximum = conf->threshold_maximum; } else { - cam->threshold_maximum = (cam->imgs.height * cam->imgs.width * 3) / 2; + threshold_maximum = (imgs.height * imgs.width * 3) / 2; } } /** Check the image size to determine if modulo 8 and over 64 */ -static void mlp_check_szimg(ctx_dev *cam) +void cls_camera::check_szimg() { - if ((cam->imgs.width % 8) || (cam->imgs.height % 8)) { + if ((imgs.width % 8) || (imgs.height % 8)) { MOTPLS_LOG(ERR, TYPE_NETCAM, NO_ERRNO ,_("Image width (%d) or height(%d) requested is not modulo 8.") - ,cam->imgs.width, cam->imgs.height); - cam->device_status = STATUS_RESET; + ,imgs.width, imgs.height); + device_status = STATUS_CLOSED; } - if ((cam->imgs.width < 64) || (cam->imgs.height < 64)) { + if ((imgs.width < 64) || (imgs.height < 64)) { MOTPLS_LOG(ERR, TYPE_ALL, NO_ERRNO ,_("Motion only supports width and height greater than or equal to 64 %dx%d") - ,cam->imgs.width, cam->imgs.height); - cam->device_status = STATUS_RESET; + ,imgs.width, imgs.height); + device_status = STATUS_CLOSED; } /* Substream size notification*/ - if ((cam->imgs.width % 16) || (cam->imgs.height % 16)) { + if ((imgs.width % 16) || (imgs.height % 16)) { MOTPLS_LOG(NTC, TYPE_NETCAM, NO_ERRNO ,_("Substream not available. Image sizes not modulo 16.")); } @@ -526,270 +535,286 @@ static void mlp_check_szimg(ctx_dev *cam) } /** Set the items required for the area detect */ -static void mlp_init_areadetect(ctx_dev *cam) +void cls_camera::init_areadetect() { - cam->area_minx[0] = cam->area_minx[3] = cam->area_minx[6] = 0; - cam->area_miny[0] = cam->area_miny[1] = cam->area_miny[2] = 0; + area_minx[0] = area_minx[3] = area_minx[6] = 0; + area_miny[0] = area_miny[1] = area_miny[2] = 0; - cam->area_minx[1] = cam->area_minx[4] = cam->area_minx[7] = cam->imgs.width / 3; - cam->area_maxx[0] = cam->area_maxx[3] = cam->area_maxx[6] = cam->imgs.width / 3; + area_minx[1] = area_minx[4] = area_minx[7] = imgs.width / 3; + area_maxx[0] = area_maxx[3] = area_maxx[6] = imgs.width / 3; - cam->area_minx[2] = cam->area_minx[5] = cam->area_minx[8] = cam->imgs.width / 3 * 2; - cam->area_maxx[1] = cam->area_maxx[4] = cam->area_maxx[7] = cam->imgs.width / 3 * 2; + area_minx[2] = area_minx[5] = area_minx[8] = imgs.width / 3 * 2; + area_maxx[1] = area_maxx[4] = area_maxx[7] = imgs.width / 3 * 2; - cam->area_miny[3] = cam->area_miny[4] = cam->area_miny[5] = cam->imgs.height / 3; - cam->area_maxy[0] = cam->area_maxy[1] = cam->area_maxy[2] = cam->imgs.height / 3; + area_miny[3] = area_miny[4] = area_miny[5] = imgs.height / 3; + area_maxy[0] = area_maxy[1] = area_maxy[2] = imgs.height / 3; - cam->area_miny[6] = cam->area_miny[7] = cam->area_miny[8] = cam->imgs.height / 3 * 2; - cam->area_maxy[3] = cam->area_maxy[4] = cam->area_maxy[5] = cam->imgs.height / 3 * 2; + area_miny[6] = area_miny[7] = area_miny[8] = imgs.height / 3 * 2; + area_maxy[3] = area_maxy[4] = area_maxy[5] = imgs.height / 3 * 2; - cam->area_maxx[2] = cam->area_maxx[5] = cam->area_maxx[8] = cam->imgs.width; - cam->area_maxy[6] = cam->area_maxy[7] = cam->area_maxy[8] = cam->imgs.height; + area_maxx[2] = area_maxx[5] = area_maxx[8] = imgs.width; + area_maxy[6] = area_maxy[7] = area_maxy[8] = imgs.height; - cam->areadetect_eventnbr = 0; + areadetect_eventnbr = 0; } /** Allocate the required buffers */ -static void mlp_init_buffers(ctx_dev *cam) +void cls_camera::init_buffers() { - cam->imgs.ref =(unsigned char*) mymalloc((uint)cam->imgs.size_norm); - cam->imgs.image_motion.image_norm = (unsigned char*)mymalloc((uint)cam->imgs.size_norm); - cam->imgs.ref_dyn =(int*) mymalloc((uint)cam->imgs.motionsize * sizeof(*cam->imgs.ref_dyn)); - cam->imgs.image_virgin =(unsigned char*) mymalloc((uint)cam->imgs.size_norm); - cam->imgs.image_vprvcy = (unsigned char*)mymalloc((uint)cam->imgs.size_norm); - cam->imgs.labels =(int*)mymalloc((uint)cam->imgs.motionsize * sizeof(*cam->imgs.labels)); - cam->imgs.labelsize =(int*) mymalloc((uint)(cam->imgs.motionsize/2+1) * sizeof(*cam->imgs.labelsize)); - cam->imgs.image_preview.image_norm =(unsigned char*) mymalloc((uint)cam->imgs.size_norm); - cam->imgs.common_buffer =(unsigned char*) mymalloc((uint)(3 * cam->imgs.width * cam->imgs.height)); - cam->imgs.image_secondary =(unsigned char*) mymalloc((uint)(3 * cam->imgs.width * cam->imgs.height)); - if (cam->imgs.size_high > 0) { - cam->imgs.image_preview.image_high =(unsigned char*) mymalloc((uint)cam->imgs.size_high); + imgs.ref =(u_char*) mymalloc((uint)imgs.size_norm); + imgs.image_motion.image_norm = (u_char*)mymalloc((uint)imgs.size_norm); + imgs.ref_dyn =(int*) mymalloc((uint)imgs.motionsize * sizeof(*imgs.ref_dyn)); + imgs.image_virgin =(u_char*) mymalloc((uint)imgs.size_norm); + imgs.image_vprvcy = (u_char*)mymalloc((uint)imgs.size_norm); + imgs.labels =(int*)mymalloc((uint)imgs.motionsize * sizeof(*imgs.labels)); + imgs.labelsize =(int*) mymalloc((uint)(imgs.motionsize/2+1) * sizeof(*imgs.labelsize)); + imgs.image_preview.image_norm =(u_char*) mymalloc((uint)imgs.size_norm); + imgs.common_buffer =(u_char*) mymalloc((uint)(3 * imgs.width * imgs.height)); + imgs.image_secondary =(u_char*) mymalloc((uint)(3 * imgs.width * imgs.height)); + if (imgs.size_high > 0) { + imgs.image_preview.image_high =(u_char*) mymalloc((uint)imgs.size_high); } else { - cam->imgs.image_preview.image_high = NULL; + imgs.image_preview.image_high = NULL; } } /* Initialize loop values */ -static void mlp_init_values(ctx_dev *cam) +void cls_camera::init_values() { - cam->event_curr_nbr = 1; - cam->event_prev_nbr = 0; + int indx; - cam->watchdog = cam->conf->watchdog_tmo; + event_curr_nbr = 1; + event_prev_nbr = 0; - clock_gettime(CLOCK_MONOTONIC, &cam->frame_curr_ts); - clock_gettime(CLOCK_MONOTONIC, &cam->frame_last_ts); + watchdog = conf->watchdog_tmo; - cam->noise = cam->conf->noise_level; - cam->passflag = false; - cam->motapp->all_sizes->reset= true; - cam->threshold = cam->conf->threshold; - cam->device_status = STATUS_CLOSED; - cam->startup_frames = (cam->conf->framerate * 2) + cam->conf->pre_capture + cam->conf->minimum_motion_frames; + clock_gettime(CLOCK_MONOTONIC, &frame_curr_ts); + clock_gettime(CLOCK_MONOTONIC, &frame_last_ts); - cam->movie_passthrough = cam->conf->movie_passthrough; - if ((cam->camera_type != CAMERA_TYPE_NETCAM) && - (cam->movie_passthrough)) { + noise = conf->noise_level; + passflag = false; + motapp->all_sizes->reset= true; + threshold = conf->threshold; + device_status = STATUS_CLOSED; + startup_frames = (conf->framerate * 2) + conf->pre_capture + conf->minimum_motion_frames; + missing_frame_counter = 0; + frame_skip = 0; + detecting_motion = false; + shots_mt = 0; + lastrate = conf->framerate; + event_user = false; + lasttime = frame_curr_ts.tv_sec; + postcap = 0; + + movie_passthrough = conf->movie_passthrough; + if ((camera_type != CAMERA_TYPE_NETCAM) && + (movie_passthrough)) { MOTPLS_LOG(WRN, TYPE_ALL, NO_ERRNO,_("Pass-through processing disabled.")); - cam->movie_passthrough = false; + movie_passthrough = false; } - if (cam->motapp->pause) { - cam->pause = true; + if (motapp->pause) { + pause = true; } else { - cam->pause = cam->conf->pause; + pause = conf->pause; } - cam->v4l2cam = nullptr; - cam->netcam = nullptr; - cam->netcam_high = nullptr; - cam->rotate = nullptr; - cam->picture = nullptr; - cam->movie_norm = nullptr; - cam->movie_norm = nullptr; - cam->movie_motion = nullptr; - cam->movie_timelapse = nullptr; - cam->movie_extpipe = nullptr; - cam->draw = nullptr; + v4l2cam = nullptr; + netcam = nullptr; + netcam_high = nullptr; + libcam = nullptr; + rotate = nullptr; + picture = nullptr; + movie_norm = nullptr; + movie_norm = nullptr; + movie_motion = nullptr; + movie_timelapse = nullptr; + movie_extpipe = nullptr; + draw = nullptr; - gethostname (cam->hostname, PATH_MAX); - cam->hostname[PATH_MAX-1] = '\0'; + gethostname (hostname, PATH_MAX); + hostname[PATH_MAX-1] = '\0'; + + for (indx=0; indxdevice_status == STATUS_CLOSED) { + if (device_status == STATUS_CLOSED) { MOTPLS_LOG(ERR, TYPE_ALL, NO_ERRNO,_("Failed to start camera.")); - cam->imgs.width = cam->conf->width; - cam->imgs.height = cam->conf->height; + imgs.width = conf->width; + imgs.height = conf->height; } - cam->imgs.motionsize = (cam->imgs.width * cam->imgs.height); - cam->imgs.size_norm = (cam->imgs.width * cam->imgs.height * 3) / 2; - cam->imgs.size_high = (cam->imgs.width_high * cam->imgs.height_high * 3) / 2; - + imgs.motionsize = (imgs.width * imgs.height); + imgs.size_norm = (imgs.width * imgs.height * 3) / 2; + imgs.size_high = (imgs.width_high * imgs.height_high * 3) / 2; + imgs.labelsize_max = 0; + imgs.largest_label = 0; } /* initialize reference images*/ -static void mlp_init_ref(ctx_dev *cam) +void cls_camera::init_ref() { - memcpy(cam->imgs.image_virgin, cam->current_image->image_norm - , (uint)cam->imgs.size_norm); + memcpy(imgs.image_virgin, current_image->image_norm + , (uint)imgs.size_norm); - mlp_mask_privacy(cam); + mask_privacy(); - memcpy(cam->imgs.image_vprvcy, cam->current_image->image_norm - , (uint)cam->imgs.size_norm); + memcpy(imgs.image_vprvcy, current_image->image_norm + , (uint)imgs.size_norm); - cam->alg->ref_frame_reset(); + alg->ref_frame_reset(); } /** clean up all memory etc. from motion init */ -void mlp_cleanup(ctx_dev *cam) +void cls_camera::cleanup() { - cam->movie_timelapse->stop(); - if (cam->event_curr_nbr == cam->event_prev_nbr) { - mlp_ring_process(cam); - if (cam->imgs.image_preview.diffs) { - cam->picture->process_preview(); - cam->imgs.image_preview.diffs = 0; + movie_timelapse->stop(); + if (event_curr_nbr == event_prev_nbr) { + ring_process(); + if (imgs.image_preview.diffs) { + picture->process_preview(); + imgs.image_preview.diffs = 0; } - if (cam->conf->on_event_end != "") { - util_exec_command(cam, cam->conf->on_event_end.c_str(), NULL); + if (conf->on_event_end != "") { + util_exec_command(this, conf->on_event_end.c_str(), NULL); } - mlp_movie_end(cam); - cam->motapp->dbse->exec(cam, "", "event_end"); + movie_end(); + motapp->dbse->exec(this, "", "event_end"); } - webu_getimg_deinit(cam); + webu_getimg_deinit(this); - if (cam->device_status == STATUS_OPENED) { - mlp_cam_close(cam); + if (device_status == STATUS_OPENED) { + cam_close(); } - myfree(cam->imgs.image_motion.image_norm); - myfree(cam->imgs.ref); - myfree(cam->imgs.ref_dyn); - myfree(cam->imgs.image_virgin); - myfree(cam->imgs.image_vprvcy); - myfree(cam->imgs.labels); - myfree(cam->imgs.labelsize); - myfree(cam->imgs.mask); - myfree(cam->imgs.mask_privacy); - myfree(cam->imgs.mask_privacy_uv); - myfree(cam->imgs.mask_privacy_high); - myfree(cam->imgs.mask_privacy_high_uv); - myfree(cam->imgs.common_buffer); - myfree(cam->imgs.image_secondary); - myfree(cam->imgs.image_preview.image_norm); - myfree(cam->imgs.image_preview.image_high); + myfree(imgs.image_motion.image_norm); + myfree(imgs.ref); + myfree(imgs.ref_dyn); + myfree(imgs.image_virgin); + myfree(imgs.image_vprvcy); + myfree(imgs.labels); + myfree(imgs.labelsize); + myfree(imgs.mask); + myfree(imgs.mask_privacy); + myfree(imgs.mask_privacy_uv); + myfree(imgs.mask_privacy_high); + myfree(imgs.mask_privacy_high_uv); + myfree(imgs.common_buffer); + myfree(imgs.image_secondary); + myfree(imgs.image_preview.image_norm); + myfree(imgs.image_preview.image_high); - mlp_ring_destroy(cam); /* Cleanup the precapture ring buffer */ + ring_destroy(); /* Cleanup the precapture ring buffer */ - mydelete(cam->alg); - mydelete(cam->algsec); - mydelete(cam->rotate); - mydelete(cam->picture); - mydelete(cam->movie_norm); - mydelete(cam->movie_motion); - mydelete(cam->movie_timelapse); - mydelete(cam->movie_extpipe); - mydelete(cam->draw); + mydelete(alg); + mydelete(algsec); + mydelete(rotate); + mydelete(picture); + mydelete(movie_norm); + mydelete(movie_motion); + mydelete(movie_timelapse); + mydelete(movie_extpipe); + mydelete(draw); - if (cam->pipe != -1) { - close(cam->pipe); - cam->pipe = -1; + if (pipe != -1) { + close(pipe); + pipe = -1; } - if (cam->mpipe != -1) { - close(cam->mpipe); - cam->mpipe = -1; + if (mpipe != -1) { + close(mpipe); + mpipe = -1; } } /* initialize everything for the loop */ -static void mlp_init(ctx_dev *cam) +void cls_camera::init() { - if ((cam->device_status != STATUS_INIT) && - (cam->device_status != STATUS_RESET)) { + if ((device_status != STATUS_INIT) && + (restart != true)) { return; } - if (cam->device_status == STATUS_RESET) { - mlp_cleanup(cam); + if (restart == true) { + cleanup(); } + restart = false; - MOTPLS_LOG(INF, TYPE_ALL, NO_ERRNO,_("Initialize")); + MOTPLS_LOG(INF, TYPE_ALL, NO_ERRNO,_("Initialize Camera")); - mlp_init_camera_type(cam); + init_camera_type(); - mlp_init_values(cam); + init_values(); - mlp_init_cam_start(cam); + init_cam_start(); - mlp_check_szimg(cam); + check_szimg(); - mlp_ring_resize(cam); + ring_resize(); - mlp_init_buffers(cam); + init_buffers(); - webu_getimg_init(cam); + webu_getimg_init(this); - cam->rotate = new cls_rotate(cam); + rotate = new cls_rotate(this); - mlp_init_firstimage(cam); + init_firstimage(); - vlp_init(cam); - cam->alg = new cls_alg(cam); - cam->algsec = new cls_algsec(cam); - cam->picture = new cls_picture(cam); - cam->draw = new cls_draw(cam); - cam->movie_norm = new cls_movie(cam, "norm"); - cam->movie_motion = new cls_movie(cam, "motion"); - cam->movie_timelapse = new cls_movie(cam, "timelapse"); - cam->movie_extpipe = new cls_movie(cam, "extpipe"); + vlp_init(this); + alg = new cls_alg(this); + algsec = new cls_algsec(this); + picture = new cls_picture(this); + draw = new cls_draw(this); + movie_norm = new cls_movie(this, "norm"); + movie_motion = new cls_movie(this, "motion"); + movie_timelapse = new cls_movie(this, "timelapse"); + movie_extpipe = new cls_movie(this, "extpipe"); - mlp_init_areadetect(cam); + init_areadetect(); - mlp_init_ref(cam); + init_ref(); - if (cam->device_status == STATUS_OPENED) { + if (device_status == STATUS_OPENED) { MOTPLS_LOG(NTC, TYPE_ALL, NO_ERRNO ,_("Camera %d started: motion detection %s"), - cam->device_id, cam->pause ? _("Disabled"):_("Enabled")); + device_id, pause ? _("Disabled"):_("Enabled")); - if (cam->conf->emulate_motion) { + if (conf->emulate_motion) { MOTPLS_LOG(INF, TYPE_ALL, NO_ERRNO, _("Emulating motion")); } } + } - - /* check the area detect */ -static void mlp_areadetect(ctx_dev *cam) +void cls_camera::areadetect() { int i, j, z = 0; - if ((cam->conf->area_detect != "" ) && - (cam->event_curr_nbr != cam->areadetect_eventnbr) && - (cam->current_image->flags & IMAGE_TRIGGER)) { - j = (int)cam->conf->area_detect.length(); + if ((conf->area_detect != "" ) && + (event_curr_nbr != areadetect_eventnbr) && + (current_image->flags & IMAGE_TRIGGER)) { + j = (int)conf->area_detect.length(); for (i = 0; i < j; i++) { - z = cam->conf->area_detect[(uint)i] - 49; /* characters are stored as ascii 48-57 (0-9) */ + z = conf->area_detect[(uint)i] - 49; /* characters are stored as ascii 48-57 (0-9) */ if ((z >= 0) && (z < 9)) { - if (cam->current_image->location.x > cam->area_minx[z] && - cam->current_image->location.x < cam->area_maxx[z] && - cam->current_image->location.y > cam->area_miny[z] && - cam->current_image->location.y < cam->area_maxy[z]) { - if (cam->conf->on_area_detected != "") { - util_exec_command(cam, cam->conf->on_area_detected.c_str(), NULL); + if (current_image->location.x > area_minx[z] && + current_image->location.x < area_maxx[z] && + current_image->location.y > area_miny[z] && + current_image->location.y < area_maxy[z]) { + if (conf->on_area_detected != "") { + util_exec_command(this, conf->on_area_detected.c_str(), NULL); } - cam->areadetect_eventnbr = cam->event_curr_nbr; /* Fire script only once per event */ + areadetect_eventnbr = event_curr_nbr; /* Fire script only once per event */ MOTPLS_LOG(DBG, TYPE_ALL, NO_ERRNO ,_("Motion in area %d detected."), z + 1); break; @@ -800,171 +825,173 @@ static void mlp_areadetect(ctx_dev *cam) } /* Prepare for the next iteration of loop*/ -static void mlp_prepare(ctx_dev *cam) +void cls_camera::prepare() { - cam->watchdog = cam->conf->watchdog_tmo; + watchdog = conf->watchdog_tmo; - 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_MONOTONIC, &cam->frame_curr_ts); + frame_last_ts.tv_sec = frame_curr_ts.tv_sec; + frame_last_ts.tv_nsec = frame_curr_ts.tv_nsec; + clock_gettime(CLOCK_MONOTONIC, &frame_curr_ts); - if (cam->frame_last_ts.tv_sec != cam->frame_curr_ts.tv_sec) { - cam->lastrate = cam->shots_mt + 1; - cam->shots_mt = -1; + if (frame_last_ts.tv_sec != frame_curr_ts.tv_sec) { + lastrate = shots_mt + 1; + shots_mt = -1; } - cam->shots_mt++; + shots_mt++; - if (cam->conf->pre_capture < 0) { - cam->conf->pre_capture = 0; + if (conf->pre_capture < 0) { + conf->pre_capture = 0; } - if (cam->startup_frames > 0) { - cam->startup_frames--; + if (startup_frames > 0) { + startup_frames--; } } /* reset the images */ -static void mlp_resetimages(ctx_dev *cam) +void cls_camera::resetimages() { int64_t tmpsec; /* ring_buffer_in is pointing to current pos, update before put in a new image */ - tmpsec =cam->current_image->imgts.tv_sec; - if (++cam->imgs.ring_in >= cam->imgs.ring_size) { - cam->imgs.ring_in = 0; + tmpsec =current_image->imgts.tv_sec; + if (++imgs.ring_in >= imgs.ring_size) { + imgs.ring_in = 0; } /* Check if we have filled the ring buffer, throw away last image */ - if (cam->imgs.ring_in == cam->imgs.ring_out) { - if (++cam->imgs.ring_out >= cam->imgs.ring_size) { - cam->imgs.ring_out = 0; + if (imgs.ring_in == imgs.ring_out) { + if (++imgs.ring_out >= imgs.ring_size) { + imgs.ring_out = 0; } } - cam->current_image = &cam->imgs.image_ring[cam->imgs.ring_in]; - cam->current_image->diffs = 0; - cam->current_image->flags = 0; - cam->current_image->cent_dist = 0; - memset(&cam->current_image->location, 0, sizeof(cam->current_image->location)); - cam->current_image->total_labels = 0; + current_image = &imgs.image_ring[imgs.ring_in]; + current_image->diffs = 0; + current_image->flags = 0; + current_image->cent_dist = 0; + memset(¤t_image->location, 0, sizeof(current_image->location)); + current_image->total_labels = 0; - clock_gettime(CLOCK_REALTIME, &cam->current_image->imgts); - clock_gettime(CLOCK_MONOTONIC, &cam->current_image->monots); + clock_gettime(CLOCK_REALTIME, ¤t_image->imgts); + clock_gettime(CLOCK_MONOTONIC, ¤t_image->monots); - if (tmpsec != cam->current_image->imgts.tv_sec) { - cam->shots_rt = 1; + if (tmpsec != current_image->imgts.tv_sec) { + shots_rt = 1; } else { - cam->shots_rt++; + shots_rt++; } /* Store shot number with pre_captured image */ - cam->current_image->shot = cam->shots_rt; + current_image->shot = shots_rt; } /* Try to reconnect to camera */ -static void mlp_retry(ctx_dev *cam) +void cls_camera::retry() { int size_high; - if ((cam->device_status == STATUS_CLOSED) && - (cam->frame_curr_ts.tv_sec % 10 == 0) && - (cam->shots_mt == 0)) { + if ((device_status == STATUS_CLOSED) && + (frame_curr_ts.tv_sec % 10 == 0) && + (shots_mt == 0)) { MOTPLS_LOG(NTC, TYPE_ALL, NO_ERRNO ,_("Retrying until successful connection with camera")); - mlp_cam_start(cam); + cam_start(); - mlp_check_szimg(cam); + check_szimg(); - if (cam->imgs.width != cam->conf->width || cam->imgs.height != cam->conf->height) { + if (imgs.width != conf->width || imgs.height != conf->height) { MOTPLS_LOG(NTC, TYPE_ALL, NO_ERRNO,_("Resetting image buffers")); - cam->device_status = STATUS_RESET; + device_status = STATUS_CLOSED; + restart = true; } /* * For high res, we check the size of buffer to determine whether to break out - * the init_motion function allocated the buffer for high using the cam->imgs.size_high - * and the mlp_cam_start ONLY re-populates the height/width so we can check the size here. + * the init_motion function allocated the buffer for high using the imgs.size_high + * and the cam_start ONLY re-populates the height/width so we can check the size here. */ - size_high = (cam->imgs.width_high * cam->imgs.height_high * 3) / 2; - if (cam->imgs.size_high != size_high) { - cam->device_status = STATUS_RESET; + size_high = (imgs.width_high * imgs.height_high * 3) / 2; + if (imgs.size_high != size_high) { + device_status = STATUS_CLOSED; + restart = true; } } } /* Get next image from camera */ -static int mlp_capture(ctx_dev *cam) +int cls_camera::capture() { const char *tmpin; char tmpout[80]; int retcd; - if (cam->device_status != STATUS_OPENED) { + if (device_status != STATUS_OPENED) { return 0; } - retcd = mlp_cam_next(cam, cam->current_image); + retcd = cam_next(current_image); if (retcd == CAPTURE_SUCCESS) { - cam->lost_connection = 0; - cam->connectionlosttime.tv_sec = 0; + lost_connection = 0; + connectionlosttime.tv_sec = 0; - if (cam->missing_frame_counter >= (cam->conf->device_tmo * cam->conf->framerate)) { + if (missing_frame_counter >= (conf->device_tmo * conf->framerate)) { MOTPLS_LOG(NTC, TYPE_ALL, NO_ERRNO, _("Video signal re-acquired")); - if (cam->conf->on_camera_found != "") { - util_exec_command(cam, cam->conf->on_camera_found.c_str(), NULL); + if (conf->on_camera_found != "") { + util_exec_command(this, conf->on_camera_found.c_str(), NULL); } } - cam->missing_frame_counter = 0; - memcpy(cam->imgs.image_virgin, cam->current_image->image_norm - , (uint)cam->imgs.size_norm); - mlp_mask_privacy(cam); - memcpy(cam->imgs.image_vprvcy, cam->current_image->image_norm - , (uint)cam->imgs.size_norm); + missing_frame_counter = 0; + memcpy(imgs.image_virgin, current_image->image_norm + , (uint)imgs.size_norm); + mask_privacy(); + memcpy(imgs.image_vprvcy, current_image->image_norm + , (uint)imgs.size_norm); } else { - if (cam->connectionlosttime.tv_sec == 0) { - clock_gettime(CLOCK_REALTIME, &cam->connectionlosttime); + if (connectionlosttime.tv_sec == 0) { + clock_gettime(CLOCK_REALTIME, &connectionlosttime); } - cam->missing_frame_counter++; + missing_frame_counter++; - if ((cam->device_status == STATUS_OPENED) && - (cam->missing_frame_counter < - (cam->conf->device_tmo * cam->conf->framerate))) { - memcpy(cam->current_image->image_norm, cam->imgs.image_vprvcy - , (uint)cam->imgs.size_norm); + if ((device_status == STATUS_OPENED) && + (missing_frame_counter < + (conf->device_tmo * conf->framerate))) { + memcpy(current_image->image_norm, imgs.image_vprvcy + , (uint)imgs.size_norm); } else { - cam->lost_connection = 1; - if (cam->device_status == STATUS_OPENED) { + lost_connection = 1; + if (device_status == STATUS_OPENED) { tmpin = "CONNECTION TO CAMERA LOST\\nSINCE %Y-%m-%d %T"; } else { tmpin = "UNABLE TO OPEN VIDEO DEVICE\\nSINCE %Y-%m-%d %T"; } - memset(cam->current_image->image_norm, 0x80, (uint)cam->imgs.size_norm); - cam->current_image->imgts =cam->connectionlosttime; - mystrftime(cam, tmpout, sizeof(tmpout), tmpin, NULL); - cam->draw->text(cam->current_image->image_norm - , cam->imgs.width, cam->imgs.height - , 10, 20 * cam->text_scale - , tmpout, cam->text_scale); + memset(current_image->image_norm, 0x80, (uint)imgs.size_norm); + current_image->imgts =connectionlosttime; + mystrftime(this, tmpout, sizeof(tmpout), tmpin, NULL); + draw->text(current_image->image_norm + , imgs.width, imgs.height + , 10, 20 * text_scale + , tmpout, text_scale); /* Write error message only once */ - if (cam->missing_frame_counter == (cam->conf->device_tmo * cam->conf->framerate)) { + if (missing_frame_counter == (conf->device_tmo * conf->framerate)) { MOTPLS_LOG(NTC, TYPE_ALL, NO_ERRNO ,_("Video signal lost - Adding grey image")); - if (cam->conf->on_camera_lost != "") { - util_exec_command(cam, cam->conf->on_camera_lost.c_str(), NULL); + if (conf->on_camera_lost != "") { + util_exec_command(this, conf->on_camera_lost.c_str(), NULL); } } - if ((cam->device_status == STATUS_OPENED) && - (cam->missing_frame_counter == ((cam->conf->device_tmo * 4) * cam->conf->framerate))) { + if ((device_status == STATUS_OPENED) && + (missing_frame_counter == ((conf->device_tmo * 4) * conf->framerate))) { MOTPLS_LOG(ERR, TYPE_ALL, NO_ERRNO ,_("Video signal still lost - Trying to close video device")); - mlp_cam_close(cam); + cam_close(); } } } @@ -973,486 +1000,542 @@ static int mlp_capture(ctx_dev *cam) } /* call detection */ -static void mlp_detection(ctx_dev *cam) +void cls_camera::detection() { - if (cam->frame_skip) { - cam->frame_skip--; - cam->current_image->diffs = 0; + if (frame_skip) { + frame_skip--; + current_image->diffs = 0; return; } - if (cam->pause == false) { - cam->alg->diff(); + if (pause == false) { + alg->diff(); } else { - cam->current_image->diffs = 0; - cam->current_image->diffs_raw = 0; - cam->current_image->diffs_ratio = 100; + current_image->diffs = 0; + current_image->diffs_raw = 0; + current_image->diffs_ratio = 100; } } /* tune the detection parameters*/ -static void mlp_tuning(ctx_dev *cam) +void cls_camera::tuning() { - if ((cam->conf->noise_tune && cam->shots_mt == 0) && - (!cam->detecting_motion && (cam->current_image->diffs <= cam->threshold))) { - cam->alg->noise_tune(); + if ((conf->noise_tune && shots_mt == 0) && + (!detecting_motion && (current_image->diffs <= threshold))) { + alg->noise_tune(); } - if (cam->conf->threshold_tune) { - cam->alg->threshold_tune(); + if (conf->threshold_tune) { + alg->threshold_tune(); } - if ((cam->current_image->diffs > cam->threshold) && - (cam->current_image->diffs < cam->threshold_maximum)) { - cam->alg->location(); - cam->alg->stddev(); + if ((current_image->diffs > threshold) && + (current_image->diffs < threshold_maximum)) { + alg->location(); + alg->stddev(); } - if (cam->current_image->diffs_ratio < cam->conf->threshold_ratio) { - cam->current_image->diffs = 0; + if (current_image->diffs_ratio < conf->threshold_ratio) { + current_image->diffs = 0; } - cam->alg->tune_smartmask(); + alg->tune_smartmask(); - cam->alg->ref_frame_update(); + alg->ref_frame_update(); - 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; + previous_diffs = current_image->diffs; + previous_location_x = current_image->location.x; + previous_location_y = current_image->location.y; } /* apply image overlays */ -static void mlp_overlay(ctx_dev *cam) +void cls_camera::overlay() { char tmp[PATH_MAX]; - if ((cam->conf->smart_mask_speed >0) && - ((cam->conf->picture_output_motion != "off") || - cam->conf->movie_output_motion || - (cam->stream.motion.jpg_cnct > 0) || - (cam->stream.motion.ts_cnct > 0))) { - cam->draw->smartmask(); + if ((conf->smart_mask_speed >0) && + ((conf->picture_output_motion != "off") || + conf->movie_output_motion || + (stream.motion.jpg_cnct > 0) || + (stream.motion.ts_cnct > 0))) { + draw->smartmask(); } - if (cam->imgs.largest_label && - ((cam->conf->picture_output_motion != "off") || - cam->conf->movie_output_motion || - (cam->stream.motion.jpg_cnct > 0) || - (cam->stream.motion.ts_cnct > 0))) { - cam->draw->largest_label(); + if (imgs.largest_label && + ((conf->picture_output_motion != "off") || + conf->movie_output_motion || + (stream.motion.jpg_cnct > 0) || + (stream.motion.ts_cnct > 0))) { + draw->largest_label(); } - if (cam->imgs.mask && - ((cam->conf->picture_output_motion != "off") || - cam->conf->movie_output_motion || - (cam->stream.motion.jpg_cnct > 0) || - (cam->stream.motion.ts_cnct > 0))) { - cam->draw->fixed_mask(); + if (imgs.mask && + ((conf->picture_output_motion != "off") || + conf->movie_output_motion || + (stream.motion.jpg_cnct > 0) || + (stream.motion.ts_cnct > 0))) { + draw->fixed_mask(); } - if (cam->conf->text_changes) { - if (cam->pause == false) { - sprintf(tmp, "%d", cam->current_image->diffs); + if (conf->text_changes) { + if (pause == false) { + sprintf(tmp, "%d", current_image->diffs); } else { sprintf(tmp, "-"); } - cam->draw->text(cam->current_image->image_norm - , cam->imgs.width, cam->imgs.height - , cam->imgs.width - 10, 10 - , tmp, cam->text_scale); + draw->text(current_image->image_norm + , imgs.width, imgs.height + , imgs.width - 10, 10 + , tmp, text_scale); } - if ((cam->stream.motion.jpg_cnct > 0) || - (cam->stream.motion.ts_cnct > 0)) { - sprintf(tmp, "D:%5d L:%3d N:%3d", cam->current_image->diffs, - cam->current_image->total_labels, cam->noise); - cam->draw->text(cam->imgs.image_motion.image_norm - , cam->imgs.width, cam->imgs.height - , cam->imgs.width - 10 - , cam->imgs.height - (30 * cam->text_scale) - , tmp, cam->text_scale); - sprintf(tmp, "THREAD %d SETUP", cam->threadnr); - cam->draw->text(cam->imgs.image_motion.image_norm - , cam->imgs.width, cam->imgs.height - , cam->imgs.width - 10 - , cam->imgs.height - (10 * cam->text_scale) - , tmp, cam->text_scale); + if ((stream.motion.jpg_cnct > 0) || + (stream.motion.ts_cnct > 0)) { + sprintf(tmp, "D:%5d L:%3d N:%3d", current_image->diffs, + current_image->total_labels, noise); + draw->text(imgs.image_motion.image_norm + , imgs.width, imgs.height + , imgs.width - 10 + , imgs.height - (30 * text_scale) + , tmp, text_scale); + sprintf(tmp, "THREAD %d SETUP", threadnr); + draw->text(imgs.image_motion.image_norm + , imgs.width, imgs.height + , imgs.width - 10 + , imgs.height - (10 * text_scale) + , tmp, text_scale); } /* Add text in lower left corner of the pictures */ - if (cam->conf->text_left != "") { - mystrftime(cam, tmp, sizeof(tmp), cam->conf->text_left.c_str(), NULL); - cam->draw->text(cam->current_image->image_norm - , cam->imgs.width, cam->imgs.height - , 10, cam->imgs.height - (10 * cam->text_scale) - , tmp, cam->text_scale); + if (conf->text_left != "") { + mystrftime(this, tmp, sizeof(tmp), conf->text_left.c_str(), NULL); + draw->text(current_image->image_norm + , imgs.width, imgs.height + , 10, imgs.height - (10 * text_scale) + , tmp, text_scale); } /* Add text in lower right corner of the pictures */ - if (cam->conf->text_right != "") { - mystrftime(cam, tmp, sizeof(tmp), cam->conf->text_right.c_str(), NULL); - cam->draw->text(cam->current_image->image_norm - , cam->imgs.width, cam->imgs.height - , cam->imgs.width - 10, cam->imgs.height - (10 * cam->text_scale) - , tmp, cam->text_scale); + if (conf->text_right != "") { + mystrftime(this, tmp, sizeof(tmp), conf->text_right.c_str(), NULL); + draw->text(current_image->image_norm + , imgs.width, imgs.height + , imgs.width - 10, imgs.height - (10 * text_scale) + , tmp, text_scale); } } /* emulate motion */ -static void mlp_actions_emulate(ctx_dev *cam) +void cls_camera::actions_emulate() { int indx; - if ((cam->detecting_motion == false) && - (cam->movie_norm->is_running == true)) { - cam->movie_norm->reset_start_time(&cam->current_image->imgts); + if ((detecting_motion == false) && + (movie_norm->is_running == true)) { + movie_norm->reset_start_time(¤t_image->imgts); } - if ((cam->detecting_motion == false) && - (cam->movie_motion->is_running == true)) { - cam->movie_motion->reset_start_time(&cam->imgs.image_motion.imgts); + if ((detecting_motion == false) && + (movie_motion->is_running == true)) { + movie_motion->reset_start_time(&imgs.image_motion.imgts); } - cam->detecting_motion = true; - if (cam->conf->post_capture > 0) { - cam->postcap = cam->conf->post_capture; + detecting_motion = true; + if (conf->post_capture > 0) { + postcap = conf->post_capture; } - cam->current_image->flags |= (IMAGE_TRIGGER | IMAGE_SAVE); + current_image->flags |= (IMAGE_TRIGGER | IMAGE_SAVE); /* Mark all images in image_ring to be saved */ - for (indx = 0; indx < cam->imgs.ring_size; indx++) { - cam->imgs.image_ring[indx].flags |= IMAGE_SAVE; + for (indx = 0; indx < imgs.ring_size; indx++) { + imgs.image_ring[indx].flags |= IMAGE_SAVE; } - mlp_detected(cam); + detected(); } /* call the actions */ -static void mlp_actions_motion(ctx_dev *cam) +void cls_camera::actions_motion() { int indx, frame_count = 0; - int pos = cam->imgs.ring_in; + int pos = imgs.ring_in; - for (indx = 0; indx < cam->conf->minimum_motion_frames; indx++) { - if (cam->imgs.image_ring[pos].flags & IMAGE_MOTION) { + for (indx = 0; indx < conf->minimum_motion_frames; indx++) { + if (imgs.image_ring[pos].flags & IMAGE_MOTION) { frame_count++; } if (pos == 0) { - pos = cam->imgs.ring_size-1; + pos = imgs.ring_size-1; } else { pos--; } } - if (frame_count >= cam->conf->minimum_motion_frames) { + if (frame_count >= conf->minimum_motion_frames) { - cam->current_image->flags |= (IMAGE_TRIGGER | IMAGE_SAVE); + current_image->flags |= (IMAGE_TRIGGER | IMAGE_SAVE); - if ((cam->detecting_motion == false) && - (cam->movie_norm->is_running == true)) { - cam->movie_norm->reset_start_time(&cam->current_image->imgts); + if ((detecting_motion == false) && + (movie_norm->is_running == true)) { + movie_norm->reset_start_time(¤t_image->imgts); } - if ((cam->detecting_motion == false) && - (cam->movie_motion->is_running == true)) { - cam->movie_motion->reset_start_time(&cam->imgs.image_motion.imgts); + if ((detecting_motion == false) && + (movie_motion->is_running == true)) { + movie_motion->reset_start_time(&imgs.image_motion.imgts); } - cam->detecting_motion = true; - cam->postcap = cam->conf->post_capture; + detecting_motion = true; + postcap = conf->post_capture; - for (indx = 0; indx < cam->imgs.ring_size; indx++) { - cam->imgs.image_ring[indx].flags |= IMAGE_SAVE; + for (indx = 0; indx < imgs.ring_size; indx++) { + imgs.image_ring[indx].flags |= IMAGE_SAVE; } - } else if (cam->postcap > 0) { + } else if (postcap > 0) { /* we have motion in this frame, but not enough frames for trigger. Check postcap */ - cam->current_image->flags |= (IMAGE_POSTCAP | IMAGE_SAVE); - cam->postcap--; + current_image->flags |= (IMAGE_POSTCAP | IMAGE_SAVE); + postcap--; } else { - cam->current_image->flags |= IMAGE_PRECAP; + current_image->flags |= IMAGE_PRECAP; } - mlp_detected(cam); + detected(); } /* call the event actions*/ -static void mlp_actions_event(ctx_dev *cam) +void cls_camera::actions_event() { - if ((cam->conf->event_gap > 0) && - ((cam->frame_curr_ts.tv_sec - cam->lasttime ) >= cam->conf->event_gap)) { - cam->event_stop = true; + if ((conf->event_gap > 0) && + ((frame_curr_ts.tv_sec - lasttime ) >= conf->event_gap)) { + event_stop = true; } - if (cam->event_stop) { - if (cam->event_curr_nbr == cam->event_prev_nbr) { + if (event_stop) { + if (event_curr_nbr == event_prev_nbr) { - mlp_ring_process(cam); + ring_process(); - if (cam->imgs.image_preview.diffs) { - cam->picture->process_preview(); - cam->imgs.image_preview.diffs = 0; + if (imgs.image_preview.diffs) { + picture->process_preview(); + imgs.image_preview.diffs = 0; } - if (cam->conf->on_event_end != "") { - util_exec_command(cam, cam->conf->on_event_end.c_str(), NULL); + if (conf->on_event_end != "") { + util_exec_command(this, conf->on_event_end.c_str(), NULL); } - mlp_movie_end(cam); - cam->motapp->dbse->exec(cam, "", "event_end"); + movie_end(); + motapp->dbse->exec(this, "", "event_end"); - mlp_track_center(cam); + track_center(); - if (cam->algsec->detected) { + if (algsec->detected) { MOTPLS_LOG(NTC, TYPE_EVENTS , NO_ERRNO, _("Secondary detect")); - if (cam->conf->on_secondary_detect != "") { - util_exec_command(cam - , cam->conf->on_secondary_detect.c_str() + if (conf->on_secondary_detect != "") { + util_exec_command(this + , conf->on_secondary_detect.c_str() , NULL); } } - cam->algsec->detected = false; + algsec->detected = false; - MOTPLS_LOG(NTC, TYPE_ALL, NO_ERRNO, _("End of event %d"), cam->event_curr_nbr); + MOTPLS_LOG(NTC, TYPE_ALL, NO_ERRNO, _("End of event %d"), event_curr_nbr); - cam->postcap = 0; - cam->event_curr_nbr++; - cam->text_event_string[0] = '\0'; + postcap = 0; + event_curr_nbr++; + text_event_string[0] = '\0'; } - cam->event_stop = false; - cam->event_user = false; + event_stop = false; + event_user = false; } - if ((cam->conf->movie_max_time > 0) && - (cam->event_curr_nbr == cam->event_prev_nbr) && - ((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))) { - mlp_movie_end(cam); - mlp_movie_start(cam); + if ((conf->movie_max_time > 0) && + (event_curr_nbr == event_prev_nbr) && + ((frame_curr_ts.tv_sec - movie_start_time) >= + conf->movie_max_time) && + ( !(current_image->flags & IMAGE_POSTCAP)) && + ( !(current_image->flags & IMAGE_PRECAP))) { + movie_end(); + movie_start(); } } -static void mlp_actions(ctx_dev *cam) +void cls_camera::actions() { - if ((cam->current_image->diffs > cam->threshold) && - (cam->current_image->diffs < cam->threshold_maximum)) { - cam->current_image->flags |= IMAGE_MOTION; - cam->info_diff_cnt++; - cam->info_diff_tot += (uint)cam->current_image->diffs; - cam->info_sdev_tot += (uint)cam->current_image->location.stddev_xy; - if (cam->info_sdev_min > cam->current_image->location.stddev_xy ) { - cam->info_sdev_min = cam->current_image->location.stddev_xy; + if ((current_image->diffs > threshold) && + (current_image->diffs < threshold_maximum)) { + current_image->flags |= IMAGE_MOTION; + info_diff_cnt++; + info_diff_tot += (uint)current_image->diffs; + info_sdev_tot += (uint)current_image->location.stddev_xy; + if (info_sdev_min > current_image->location.stddev_xy ) { + info_sdev_min = current_image->location.stddev_xy; } - if (cam->info_sdev_max < cam->current_image->location.stddev_xy ) { - cam->info_sdev_max = cam->current_image->location.stddev_xy; + if (info_sdev_max < current_image->location.stddev_xy ) { + info_sdev_max = current_image->location.stddev_xy; } /* MOTPLS_LOG(DBG, TYPE_ALL, NO_ERRNO , "dev_x %d dev_y %d dev_xy %d, diff %d ratio %d" - , cam->current_image->location.stddev_x - , cam->current_image->location.stddev_y - , cam->current_image->location.stddev_xy - , cam->current_image->diffs - , cam->current_image->diffs_ratio); + , current_image->location.stddev_x + , current_image->location.stddev_y + , current_image->location.stddev_xy + , current_image->diffs + , current_image->diffs_ratio); */ } - if ((cam->conf->emulate_motion || cam->event_user) && (cam->startup_frames == 0)) { - mlp_actions_emulate(cam); - } else if ((cam->current_image->flags & IMAGE_MOTION) && (cam->startup_frames == 0)) { - mlp_actions_motion(cam); - } else if (cam->postcap > 0) { - cam->current_image->flags |= (IMAGE_POSTCAP | IMAGE_SAVE); - cam->postcap--; + if ((conf->emulate_motion || event_user) && (startup_frames == 0)) { + actions_emulate(); + } else if ((current_image->flags & IMAGE_MOTION) && (startup_frames == 0)) { + actions_motion(); + } else if (postcap > 0) { + current_image->flags |= (IMAGE_POSTCAP | IMAGE_SAVE); + postcap--; } else { - cam->current_image->flags |= IMAGE_PRECAP; - if ((cam->conf->event_gap == 0) && cam->detecting_motion) { - cam->event_stop = true; + current_image->flags |= IMAGE_PRECAP; + if ((conf->event_gap == 0) && detecting_motion) { + event_stop = true; } - cam->detecting_motion = false; + detecting_motion = false; } - if (cam->current_image->flags & IMAGE_SAVE) { - cam->lasttime = cam->current_image->monots.tv_sec; + if (current_image->flags & IMAGE_SAVE) { + lasttime = current_image->monots.tv_sec; } - if (cam->detecting_motion) { - cam->algsec->detect(); + if (detecting_motion) { + algsec->detect(); } - mlp_areadetect(cam); + areadetect(); - mlp_ring_process(cam); + ring_process(); - mlp_actions_event(cam); + actions_event(); } /* Snapshot interval*/ -static void mlp_snapshot(ctx_dev *cam) +void cls_camera::snapshot() { - if ((cam->conf->snapshot_interval > 0 && cam->shots_mt == 0 && - cam->frame_curr_ts.tv_sec % cam->conf->snapshot_interval <= - cam->frame_last_ts.tv_sec % cam->conf->snapshot_interval) || - cam->snapshot) { - cam->picture->process_snapshot(); - cam->snapshot = 0; + if ((conf->snapshot_interval > 0 && shots_mt == 0 && + frame_curr_ts.tv_sec % conf->snapshot_interval <= + frame_last_ts.tv_sec % conf->snapshot_interval) || + action_snapshot) { + picture->process_snapshot(); + action_snapshot = false; } } /* Create timelapse video*/ -static void mlp_timelapse(ctx_dev *cam) +void cls_camera::timelapse() { struct tm timestamp_tm; - if (cam->conf->timelapse_interval) { - localtime_r(&cam->current_image->imgts.tv_sec, ×tamp_tm); + if (conf->timelapse_interval) { + localtime_r(¤t_image->imgts.tv_sec, ×tamp_tm); if (timestamp_tm.tm_min == 0 && - (cam->frame_curr_ts.tv_sec % 60 < cam->frame_last_ts.tv_sec % 60) && - cam->shots_mt == 0) { + (frame_curr_ts.tv_sec % 60 < frame_last_ts.tv_sec % 60) && + shots_mt == 0) { - if (cam->conf->timelapse_mode == "daily") { + if (conf->timelapse_mode == "daily") { if (timestamp_tm.tm_hour == 0) { - cam->movie_timelapse->stop(); + movie_timelapse->stop(); } - } else if (cam->conf->timelapse_mode == "hourly") { - cam->movie_timelapse->stop(); - } else if (cam->conf->timelapse_mode == "weekly-sunday") { + } else if (conf->timelapse_mode == "hourly") { + movie_timelapse->stop(); + } else if (conf->timelapse_mode == "weekly-sunday") { if (timestamp_tm.tm_wday == 0 && timestamp_tm.tm_hour == 0) { - cam->movie_timelapse->stop(); + movie_timelapse->stop(); } - } else if (cam->conf->timelapse_mode == "weekly-monday") { + } else if (conf->timelapse_mode == "weekly-monday") { if (timestamp_tm.tm_wday == 1 && timestamp_tm.tm_hour == 0) { - cam->movie_timelapse->stop(); + movie_timelapse->stop(); } - } else if (cam->conf->timelapse_mode == "monthly") { + } else if (conf->timelapse_mode == "monthly") { if (timestamp_tm.tm_mday == 1 && timestamp_tm.tm_hour == 0) { - cam->movie_timelapse->stop(); + movie_timelapse->stop(); } } } - if (cam->shots_mt == 0 && - cam->frame_curr_ts.tv_sec % cam->conf->timelapse_interval <= - cam->frame_last_ts.tv_sec % cam->conf->timelapse_interval) { - cam->movie_timelapse->start(); - if (cam->movie_timelapse->put_image( - cam->current_image, &cam->current_image->imgts) == -1) { + if (shots_mt == 0 && + frame_curr_ts.tv_sec % conf->timelapse_interval <= + frame_last_ts.tv_sec % conf->timelapse_interval) { + movie_timelapse->start(); + if (movie_timelapse->put_image( + current_image, ¤t_image->imgts) == -1) { MOTPLS_LOG(ERR, TYPE_EVENTS, NO_ERRNO, _("Error encoding image")); } } - } else if (cam->movie_timelapse->is_running) { + } else if (movie_timelapse->is_running) { /* * If timelapse movie is in progress but conf.timelapse_interval is zero then close timelapse file * This is an important feature that allows manual roll-over of timelapse file using the http * remote control via a cron job. */ - cam->movie_timelapse->stop(); + movie_timelapse->stop(); } } /* send images to loopback device*/ -static void mlp_loopback(ctx_dev *cam) +void cls_camera::loopback() { - vlp_putpipe(cam); + vlp_putpipe(this); - if (!cam->conf->stream_motion || cam->shots_mt == 0) { - webu_getimg_main(cam); + if (!conf->stream_motion || shots_mt == 0) { + webu_getimg_main(this); } } /* sleep the loop to get framerate requested */ -static void mlp_frametiming(ctx_dev *cam) +void cls_camera::frametiming() { int indx; struct timespec ts2; int64_t avgtime; /* Shuffle the last wait times*/ - for (indx=0; indxframe_wait[indx]=cam->frame_wait[indx+1]; + for (indx=0; indxconf->framerate) { - cam->frame_wait[AVGCNT-1] = 1000000L / cam->conf->framerate; + if (conf->framerate) { + frame_wait[AVGCNT-1] = 1000000L / conf->framerate; } else { - cam->frame_wait[AVGCNT-1] = 0; + frame_wait[AVGCNT-1] = 0; } clock_gettime(CLOCK_MONOTONIC, &ts2); - cam->frame_wait[AVGCNT-1] = cam->frame_wait[AVGCNT-1] - - (1000000L * (ts2.tv_sec - cam->frame_curr_ts.tv_sec)) - - ((ts2.tv_nsec - cam->frame_curr_ts.tv_nsec)/1000); + frame_wait[AVGCNT-1] = frame_wait[AVGCNT-1] - + (1000000L * (ts2.tv_sec - frame_curr_ts.tv_sec)) - + ((ts2.tv_nsec - frame_curr_ts.tv_nsec)/1000); avgtime = 0; for (indx=0; indxframe_wait[indx]; + avgtime += frame_wait[indx]; } - avgtime = (avgtime/AVGCNT); + avgtime = (int64_t)((avgtime / AVGCNT) * 1000); - if (avgtime > 0) { - avgtime = avgtime * 1000; - /* If over 1 second, just do one*/ - if (avgtime > 999999999) { - SLEEP(1, 0); - } else { - SLEEP(0, avgtime); - } + /* If over 1 second, just do one*/ + if (avgtime > 999999999L) { + SLEEP(1, 0); + } else if (avgtime > 0) { + SLEEP(0, avgtime); } - cam->passflag = true; + + passflag = true; } -/** main processing loop for each camera */ -void *mlp_main(void *arg) +void cls_camera::handler() { - ctx_dev *cam =(ctx_dev *) arg; + mythreadname_set("cl", conf->device_id, conf->device_name.c_str()); + device_status = STATUS_INIT; - cam->running_dev = true; - - pthread_mutex_lock(&cam->motapp->global_lock); - cam->motapp->threads_running++; - pthread_mutex_unlock(&cam->motapp->global_lock); - - mythreadname_set("ml",cam->threadnr,cam->conf->device_name.c_str()); - pthread_setspecific(tls_key_threadnr, (void *)((unsigned long)cam->threadnr)); - - cam->finish_dev = false; - cam->restart_dev = false; - cam->device_status = STATUS_INIT; - - while (cam->finish_dev == false) { - mlp_init(cam); - mlp_prepare(cam); - mlp_resetimages(cam); - mlp_retry(cam); - mlp_capture(cam); - mlp_detection(cam); - mlp_tuning(cam); - mlp_overlay(cam); - mlp_actions(cam); - mlp_snapshot(cam); - mlp_timelapse(cam); - mlp_loopback(cam); - mlp_frametiming(cam); + while (handler_stop == false) { + init(); + prepare(); + resetimages(); + retry(); + capture(); + detection(); + tuning(); + overlay(); + actions(); + snapshot(); + timelapse(); + loopback(); + frametiming(); + if (device_status == STATUS_CLOSED) { + handler_stop = true; + } } - MOTPLS_LOG(NTC, TYPE_ALL, NO_ERRNO, _("Exiting")); + cleanup(); - mlp_cleanup(cam); - - pthread_mutex_lock(&cam->motapp->global_lock); - cam->motapp->threads_running--; - pthread_mutex_unlock(&cam->motapp->global_lock); - - cam->finish_dev = true; - cam->running_dev = false; + MOTPLS_LOG(NTC, TYPE_ALL, NO_ERRNO, _("Camera closed")); + handler_finished = true; pthread_exit(NULL); } +void cls_camera::start() +{ + int retcd; + pthread_attr_t thread_attr; + + if (handler_finished == true) { + handler_finished = false; + handler_stop = false; + pthread_attr_init(&thread_attr); + pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); + retcd = pthread_create(&handler_thread, &thread_attr, &camera_handler, this); + if (retcd != 0) { + MOTPLS_LOG(WRN, TYPE_ALL, NO_ERRNO,_("Unable to start camera thread.")); + } + pthread_attr_destroy(&thread_attr); + } +} + +void cls_camera::stop() +{ + int waitcnt; + + if (handler_finished == false) { + handler_stop = true; + waitcnt = 0; + while ((handler_finished == false) && (waitcnt < conf->watchdog_tmo)){ + SLEEP(1,0) + waitcnt++; + } + if (waitcnt == conf->watchdog_tmo) { + MOTPLS_LOG(ERR, TYPE_ALL, NO_ERRNO + , _("Normal shutdown of camera failed")); + if (conf->watchdog_kill > 0) { + MOTPLS_LOG(ERR, TYPE_ALL, NO_ERRNO + ,_("Waiting additional %d seconds (watchdog_kill).") + ,conf->watchdog_kill); + waitcnt = 0; + while ((handler_finished == false) && (waitcnt < conf->watchdog_kill)){ + SLEEP(1,0) + waitcnt++; + } + if (waitcnt == conf->watchdog_kill) { + MOTPLS_LOG(ERR, TYPE_ALL, NO_ERRNO + , _("No response to shutdown. Killing it.")); + MOTPLS_LOG(ERR, TYPE_ALL, NO_ERRNO + , _("Memory leaks will occur.")); + pthread_kill(handler_thread, SIGVTALRM); + } + } else { + MOTPLS_LOG(ERR, TYPE_ALL, NO_ERRNO + , _("watchdog_kill set to terminate application.")); + exit(1); + } + } + handler_finished = true; + watchdog = conf->watchdog_tmo; + } + +} + +cls_camera::cls_camera(ctx_motapp *p_motapp) +{ + motapp = p_motapp; + handler_finished = true; + handler_stop = true; + restart = false; + action_snapshot = false; + watchdog = 30; +} + +cls_camera::~cls_camera() +{ + mydelete(conf); +} diff --git a/src/camera.hpp b/src/camera.hpp index 8115fe22..609a57ea 100644 --- a/src/camera.hpp +++ b/src/camera.hpp @@ -21,7 +21,236 @@ #ifndef _INCLUDE_CAMERA_HPP_ #define _INCLUDE_CAMERA_HPP_ -void *mlp_main(void *arg); -void mlp_cleanup(ctx_dev *cam); +struct ctx_coord { + int x; + int y; + int width; + int height; + int minx; + int maxx; + int miny; + int maxy; + int stddev_x; + int stddev_y; + int stddev_xy; +}; -#endif /* _INCLUDE_MOTION_LOOP_HPP_ */ \ No newline at end of file +struct ctx_image_data { + u_char *image_norm; + u_char *image_high; + int diffs; + int diffs_raw; + int diffs_ratio; + int64_t idnbr_norm; + int64_t idnbr_high; + 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 */ + ctx_coord location; /* coordinates for center and size of last motion detection*/ + int total_labels; +}; + +struct ctx_images { + ctx_image_data *image_ring; /* The base address of the image ring buffer */ + ctx_image_data image_motion; /* Picture buffer for motion images */ + ctx_image_data image_preview; /* Picture buffer for best image when enables */ + + u_char *ref; /* The reference frame */ + u_char *ref_next; /* The reference frame */ + u_char *mask; /* Buffer for the mask file */ + u_char *common_buffer; + u_char *image_substream; + u_char *image_virgin; /* Last picture frame with no text or locate overlay */ + u_char *image_vprvcy; /* Virgin image with the privacy mask applied */ + u_char *mask_privacy; /* Buffer for the privacy mask values */ + u_char *mask_privacy_uv; /* Buffer for the privacy U&V values */ + u_char *mask_privacy_high; /* Buffer for the privacy mask values */ + u_char *mask_privacy_high_uv; /* Buffer for the privacy U&V values */ + u_char *image_secondary; /* Buffer for JPG from alg_sec methods */ + + int ring_size; + int ring_in; /* Index in image ring buffer we last added a image into */ + int ring_out; /* Index in image ring buffer we want to process next time */ + + int *ref_dyn; /* Dynamic objects to be excluded from reference frame */ + int *labels; + int *labelsize; + + int width; + int height; + int size_norm; /* Number of bytes for normal size image */ + + int width_high; + int height_high; + int size_high; /* Number of bytes for high resolution image */ + + int motionsize; + int labelgroup_max; + int labels_above; + int labelsize_max; + int largest_label; + int size_secondary; /* Size of the jpg put into image_secondary*/ + +}; + +struct ctx_stream_data { + u_char *jpg_data; /* Image compressed as JPG */ + int jpg_sz; /* The number of bytes for jpg */ + int consumed; /* Bool for whether the jpeg data was consumed*/ + u_char *img_data; /* The base data used for image */ + int jpg_cnct; /* Counter of the number of jpg connections*/ + int ts_cnct; /* Counter of the number of mpegts connections */ + int all_cnct; /* Counter of the number of all camera connections */ +}; + +struct ctx_stream { + pthread_mutex_t mutex; + ctx_stream_data norm; /* Copy of the image to use for web stream*/ + ctx_stream_data sub; /* Copy of the image to use for web stream*/ + ctx_stream_data motion; /* Copy of the image to use for web stream*/ + ctx_stream_data source; /* Copy of the image to use for web stream*/ + ctx_stream_data secondary; /* Copy of the image to use for web stream*/ +}; + +class cls_camera { + public: + cls_camera(ctx_motapp *p_motapp); + ~cls_camera(); + void start(); + void stop(); + + ctx_motapp *motapp; + cls_config *conf; + ctx_images imgs; + ctx_stream stream; + ctx_image_data *current_image; + cls_alg *alg; + cls_algsec *algsec; + cls_rotate *rotate; + cls_netcam *netcam; + cls_netcam *netcam_high; + ctx_all_loc all_loc; + cls_draw *draw; + cls_picture *picture; + + int device_id; + bool restart; + + bool handler_stop; + bool handler_finished; + pthread_t handler_thread; + void handler(); + + int threadnr; + int noise; + bool detecting_motion; + int event_curr_nbr; + int event_prev_nbr; + int threshold; + int lastrate; + int frame_skip; + int lost_connection; + int text_scale; + int watchdog; + bool movie_passthrough; + int filetype; + char eventid[20]; + char text_event_string[PATH_MAX]; + char hostname[PATH_MAX]; + char action_user[40]; + int movie_fps; + bool passflag; + int pipe; + int mpipe; + bool pause; + int missing_frame_counter; + + uint64_t info_diff_tot; + uint64_t info_diff_cnt; + int info_sdev_min; + int info_sdev_max; + uint64_t info_sdev_tot; + + bool action_snapshot; /* Make a snapshot */ + bool event_stop; /* Boolean for whether to stop a event */ + bool event_user; /* Boolean for whether to user triggered an event */ + + enum DEVICE_STATUS device_status; + enum CAMERA_TYPE camera_type; + struct timespec connectionlosttime; + + private: + cls_movie *movie_norm; + cls_movie *movie_motion; + cls_movie *movie_timelapse; + cls_movie *movie_extpipe; + cls_v4l2cam *v4l2cam; + cls_libcam *libcam; + + pthread_t thread_id; + int track_posx; + int track_posy; + int threshold_maximum; + + int postcap; /* downcounter, frames left to to send post event */ + int shots_mt; /* Monotonic clock shots count*/ + int shots_rt; /* Realtime clock shots count*/ + long frame_wait[30]; /* Last wait times through motion loop*/ + struct timespec frame_curr_ts; + struct timespec frame_last_ts; + time_t lasttime; + time_t movie_start_time; + int startup_frames; + int area_minx[9], area_miny[9], area_maxx[9], area_maxy[9]; + int areadetect_eventnbr; + int previous_diffs, previous_location_x, previous_location_y; + + void ring_resize(); + void ring_destroy(); + void ring_process_debug(); + void ring_process_image(); + void ring_process(); + void info_reset(); + void movie_start(); + void movie_end(); + void detected_trigger(); + void track_center(); + void track_move(); + void detected(); + void mask_privacy(); + void cam_close(); + void cam_start(); + int cam_next(ctx_image_data *img_data); + void init_camera_type(); + void init_firstimage(); + void check_szimg(); + void init_areadetect(); + void init_buffers(); + void init_values(); + void init_cam_start(); + void init_ref(); + void cleanup(); + void init(); + void areadetect(); + void prepare(); + void resetimages(); + void retry(); + int capture(); + void detection(); + void tuning(); + void overlay(); + void actions_emulate(); + void actions_motion(); + void actions_event(); + void actions(); + void snapshot(); + void timelapse(); + void loopback(); + void frametiming(); + + +}; + +#endif /* _INCLUDE_CAMERA_HPP_ */ diff --git a/src/conf.cpp b/src/conf.cpp index 9d6392f9..c4120df5 100644 --- a/src/conf.cpp +++ b/src/conf.cpp @@ -19,8 +19,9 @@ #include "motionplus.hpp" #include "util.hpp" #include "logger.hpp" -#include "conf.hpp" +#include "camera.hpp" #include "sound.hpp" +#include "conf.hpp" /*Configuration parameters */ ctx_parm config_parms[] = { @@ -697,7 +698,7 @@ void cls_config::edit_watchdog_tmo(std::string &parm, enum PARM_ACT pact) { int parm_in; if (pact == PARM_ACT_DFLT) { - watchdog_tmo = 30; + watchdog_tmo = 5; } else if (pact == PARM_ACT_SET) { parm_in = atoi(parm.c_str()); if (parm_in < 1) { @@ -716,10 +717,10 @@ void cls_config::edit_watchdog_kill(std::string &parm, enum PARM_ACT pact) { int parm_in; if (pact == PARM_ACT_DFLT) { - watchdog_kill = 10; + watchdog_kill = 0; } else if (pact == PARM_ACT_SET) { parm_in = atoi(parm.c_str()); - if (parm_in < 1) { + if (parm_in < 0) { MOTPLS_LOG(NTC, TYPE_ALL, NO_ERRNO, _("Invalid watchdog kill timeout %d"),parm_in); } else { watchdog_kill = parm_in; @@ -3589,10 +3590,6 @@ void cls_config::camera_filenm(ctx_motapp *motapp) struct stat statbuf; size_t lstpos; - if (motapp->cam_list[motapp->cam_cnt-1]->conf->conf_filename != "") { - return; - } - lstpos = motapp->conf->conf_filename.find_last_of("/"); if (lstpos != std::string::npos) { lstpos++; @@ -3603,8 +3600,8 @@ void cls_config::camera_filenm(ctx_motapp *motapp) fullnm = ""; while (fullnm == "") { fullnm = dirnm + "camera" + std::to_string(indx_cam) + ".conf"; - for (indx=0;indxcam_cnt;indx++) { - if (fullnm == motapp->cam_list[indx_cam]->conf->conf_filename) { + for (indx = 0; indxcam_cnt; indx++) { + if (fullnm == motapp->cam_list[indx]->conf->conf_filename) { fullnm = ""; } } @@ -3618,63 +3615,79 @@ void cls_config::camera_filenm(ctx_motapp *motapp) } } - motapp->cam_list[motapp->cam_cnt-1]->conf->conf_filename = fullnm; + conf_filename = fullnm; +} + +int cls_config::get_next_devid(ctx_motapp *motapp) +{ + int indx, dev_id; + bool chkid; + + dev_id = 0; + chkid = true; + while (chkid) { + dev_id++; + chkid = false; + for (indx = 0; indxcam_cnt;indx++) { + if ((motapp->cam_list[indx]->conf->device_id == dev_id) || + (motapp->cam_list[indx]->device_id == dev_id)) { + chkid = true; + } + } + for (indx = 0; indxsnd_cnt;indx++) { + if ((motapp->snd_list[indx]->conf->device_id == dev_id) || + (motapp->snd_list[indx]->device_id == dev_id)) { + chkid = true; + } + } + } + + return dev_id; } -void cls_config::camera_add(ctx_motapp *motapp) +void cls_config::camera_add(ctx_motapp *motapp, std::string fname, bool srcdir) { + struct stat statbuf; int indx; - std::string parm_val; + std::string parm_val, parm_nm; + cls_camera *cam_cls; - motapp->cam_cnt++; - motapp->cam_list = (ctx_dev **)myrealloc( - motapp->cam_list - , sizeof(ctx_dev *) * (uint)(motapp->cam_cnt + 1) - , "config_camera"); - - motapp->cam_list[motapp->cam_cnt-1] = new ctx_dev; - memset(motapp->cam_list[motapp->cam_cnt-1],0,sizeof(ctx_dev)); - motapp->cam_list[motapp->cam_cnt-1]->conf = new cls_config; - - motapp->cam_list[motapp->cam_cnt] = nullptr; - motapp->cam_list[motapp->cam_cnt-1]->motapp = motapp; + cam_cls = new cls_camera(motapp); + cam_cls->conf = new cls_config; indx = 0; while (config_parms[indx].parm_name != "") { - if (mystrne(config_parms[indx].parm_name.c_str(),"device_id")) { - motapp->conf->edit_get(config_parms[indx].parm_name - , parm_val, config_parms[indx].parm_cat); - motapp->cam_list[motapp->cam_cnt-1]->conf->edit_set( - config_parms[indx].parm_name, parm_val); + parm_nm =config_parms[indx].parm_name; + if (parm_nm != "device_id") { + motapp->conf->edit_get(parm_nm, parm_val, config_parms[indx].parm_cat); + cam_cls->conf->edit_set(parm_nm, parm_val); } indx++; } - camera_filenm(motapp); + cam_cls->conf->from_conf_dir = srcdir; + cam_cls->conf->conf_filename = fname; + cam_cls->conf->device_id = get_next_devid(motapp); + cam_cls->device_id = cam_cls->conf->device_id; -} - -void cls_config::camera_parm(ctx_motapp *motapp, std::string filename) -{ - struct stat statbuf; - - if (stat(filename.c_str(), &statbuf) != 0) { + if (fname == "") { + cam_cls->conf->camera_filenm(motapp); + } else if (stat(fname.c_str(), &statbuf) != 0) { MOTPLS_LOG(ALR, TYPE_ALL, SHOW_ERRNO - ,_("Camera config file %s not found"), filename.c_str()); - return; + ,_("Camera config file %s not found"), fname.c_str()); + } else { + cam_cls->conf->process(motapp); } - camera_add(motapp); - motapp->cam_list[motapp->cam_cnt-1]->conf->conf_filename = filename; - motapp->cam_list[motapp->cam_cnt-1]->conf->process(motapp); - + motapp->cam_list.push_back(cam_cls); + motapp->cam_cnt = (int)motapp->cam_list.size(); } /* Create default configuration file name*/ void cls_config::sound_filenm(ctx_motapp *motapp) { - uint indx_snd, indx; + int indx_snd, indx; std::string dirnm, fullnm; struct stat statbuf; size_t lstpos; @@ -3689,7 +3702,7 @@ void cls_config::sound_filenm(ctx_motapp *motapp) fullnm = ""; while (fullnm == "") { fullnm = dirnm + "sound" + std::to_string(indx_snd) + ".conf"; - for (indx = 0; indxsnd_list.size(); indx++) { + for (indx = 0; indxsnd_cnt; indx++) { if (fullnm == motapp->snd_list[indx]->conf->conf_filename) { fullnm = ""; } @@ -3729,6 +3742,8 @@ void cls_config::sound_add(ctx_motapp *motapp, std::string fname, bool srcdir) snd_cls->conf->from_conf_dir = srcdir; snd_cls->conf->conf_filename = fname; + snd_cls->conf->device_id = get_next_devid(motapp); + snd_cls->device_id = snd_cls->conf->device_id; if (fname == "") { snd_cls->conf->sound_filenm(motapp); @@ -3740,7 +3755,7 @@ void cls_config::sound_add(ctx_motapp *motapp, std::string fname, bool srcdir) } motapp->snd_list.push_back(snd_cls); - + motapp->snd_cnt = (int)motapp->snd_list.size(); } void cls_config::config_dir_parm(ctx_motapp *motapp, std::string confdir) @@ -3760,8 +3775,7 @@ void cls_config::config_dir_parm(ctx_motapp *motapp, std::string confdir) MOTPLS_LOG(NTC, TYPE_ALL, NO_ERRNO ,_("Processing as camera config file %s") , file.c_str() ); - camera_parm(motapp, file); - motapp->cam_list[motapp->cam_cnt-1]->conf->from_conf_dir = true; + camera_add(motapp, file, true); } else { file = confdir + "/" + file; MOTPLS_LOG(NTC, TYPE_ALL, NO_ERRNO @@ -3818,7 +3832,7 @@ void cls_config::process(ctx_motapp *motapp) myunquote(parm_nm); myunquote(parm_vl); if ((parm_nm == "camera") && (motapp->conf == this)) { - camera_parm(motapp, parm_vl); + camera_add(motapp, parm_vl, false); } else if ((parm_nm == "sound") && (motapp->conf == this)) { sound_add(motapp, parm_vl, false); } else if ((parm_nm == "config_dir") && (motapp->conf == this)){ @@ -3867,7 +3881,7 @@ void cls_config::parms_log_parm(std::string parm_nm, std::string parm_vl) void cls_config::parms_log(ctx_motapp *motapp) { - uint i, indx; + int i, indx; std::string parm_vl, parm_main, parm_nm; std::list parm_array; std::list::iterator it; @@ -3901,7 +3915,7 @@ void cls_config::parms_log(ctx_motapp *motapp) i++; } - for (indx=0; indx<(uint)motapp->cam_cnt; indx++) { + for (indx=0; indxcam_cnt; indx++) { MOTPLS_SHT(INF, TYPE_ALL, NO_ERRNO , _("Camera config file: %s") , motapp->cam_list[indx]->conf->conf_filename.c_str()); @@ -3928,7 +3942,7 @@ void cls_config::parms_log(ctx_motapp *motapp) } } - for (indx=0; indxsnd_list.size(); indx++) { + for (indx=0; indxsnd_cnt; indx++) { MOTPLS_SHT(INF, TYPE_ALL, NO_ERRNO , _("Sound config file: %s") , motapp->snd_list[indx]->conf->conf_filename.c_str()); @@ -3982,7 +3996,7 @@ void cls_config::parms_write_parms(FILE *conffile, std::string parm_nm void cls_config::parms_write_app(ctx_motapp *motapp) { - uint i, indx; + int i, indx; std::string parm_vl, parm_main, parm_nm; std::list parm_array; std::list::iterator it; @@ -4029,7 +4043,7 @@ void cls_config::parms_write_app(ctx_motapp *motapp) i++; } - for (indx=0; indx<(uint)motapp->cam_cnt; indx++) { + for (indx=0; indxcam_cnt; indx++) { if (motapp->cam_list[indx]->conf->from_conf_dir == false) { parms_write_parms(conffile, "camera" , motapp->cam_list[indx]->conf->conf_filename @@ -4037,7 +4051,7 @@ void cls_config::parms_write_app(ctx_motapp *motapp) } } - for (indx=0; indxsnd_list.size(); indx++) { + for (indx=0; indxsnd_cnt; indx++) { if (motapp->snd_list[indx]->conf->from_conf_dir == false) { parms_write_parms(conffile, "sound" , motapp->snd_list[indx]->conf->conf_filename @@ -4121,7 +4135,7 @@ void cls_config::parms_write_cam(ctx_motapp *motapp) void cls_config::parms_write_snd(ctx_motapp *motapp) { - uint i, indx; + int i, indx; std::string parm_vl, parm_main, parm_nm; std::list parm_array; std::list::iterator it; @@ -4133,7 +4147,7 @@ void cls_config::parms_write_snd(ctx_motapp *motapp) time_t now = time(0); strftime(timestamp, 32, "%Y-%m-%dT%H:%M:%S", localtime(&now)); - for (indx=0; indxsnd_list.size(); indx++) { + for (indx=0; indxsnd_cnt; indx++) { conffile = myfopen(motapp->snd_list[indx]->conf->conf_filename.c_str(), "we"); if (conffile == NULL) { MOTPLS_LOG(NTC, TYPE_ALL, NO_ERRNO @@ -4191,7 +4205,7 @@ void cls_config::init(ctx_motapp *motapp) std::string filename; char path[PATH_MAX]; struct stat statbuf; - uint indx; + int indx; defaults(); @@ -4242,34 +4256,13 @@ void cls_config::init(ctx_motapp *motapp) cmdline(motapp); - for (indx=0; indx<(uint)motapp->cam_cnt; indx++) { - motapp->cam_list[indx]->threadnr = (int)indx; - } - - for (indx=0; indxsnd_list.size(); indx++) { - motapp->snd_list[indx]->threadnr = (int)indx + motapp->cam_cnt; - } - -} - -void cls_config::deinit(ctx_motapp *motapp) -{ - int indx; - for (indx=0; indxcam_cnt; indx++) { - delete motapp->cam_list[indx]->conf; - delete motapp->cam_list[indx]; + motapp->cam_list[indx]->threadnr = indx; } - myfree(motapp->cam_list); - motapp->cam_cnt = 0; -/* + for (indx=0; indxsnd_cnt; indx++) { - delete motapp->snd_list[indx]->conf; - delete motapp->snd_list[indx]; + motapp->snd_list[indx]->threadnr = (indx + motapp->cam_cnt); } - myfree(motapp->snd_list); - motapp->snd_cnt = 0; -*/ } diff --git a/src/conf.hpp b/src/conf.hpp index 9ec2d2bd..fed44082 100644 --- a/src/conf.hpp +++ b/src/conf.hpp @@ -274,8 +274,9 @@ std::string snd_window; bool snd_show; - void camera_add(ctx_motapp *motapp); + void camera_add(ctx_motapp *motapp, std::string fname, bool srcdir); void sound_add(ctx_motapp *motapp, std::string fname, bool srcdir); + void camera_filenm(ctx_motapp *motapp); void sound_filenm(ctx_motapp *motapp); void process(ctx_motapp *motapp); @@ -288,16 +289,13 @@ std::string cat_desc(enum PARM_CAT pcat, bool shrt); void usage(); void init(ctx_motapp *motapp); - void deinit(ctx_motapp *motapp); void parms_log(ctx_motapp *motapp); void parms_write(ctx_motapp *motapp); private: void cmdline(ctx_motapp *motapp); void defaults(); - - void camera_filenm(ctx_motapp *motapp); - void camera_parm(ctx_motapp *motapp, std::string filename); + int get_next_devid(ctx_motapp *motapp); void config_dir_parm(ctx_motapp *motapp, std::string confdir); void parms_log_parm(std::string parm_nm, std::string parm_vl); diff --git a/src/dbse.cpp b/src/dbse.cpp index 734041a5..e2e70e68 100644 --- a/src/dbse.cpp +++ b/src/dbse.cpp @@ -17,6 +17,7 @@ */ #include "motionplus.hpp" +#include "camera.hpp" #include "conf.hpp" #include "util.hpp" #include "logger.hpp" @@ -948,7 +949,7 @@ void cls_dbse::exec_sql(std::string sql) } -void cls_dbse::exec(ctx_dev *cam, std::string fname, std::string cmd) +void cls_dbse::exec(cls_camera *cam, std::string fname, std::string cmd) { std::string sql; @@ -979,7 +980,7 @@ void cls_dbse::exec(ctx_dev *cam, std::string fname, std::string cmd) } /* Add a record to motionplus table */ -void cls_dbse::movielist_add(ctx_dev *cam, cls_movie *movie, timespec *ts1) +void cls_dbse::movielist_add(cls_camera *cam, cls_movie *movie, timespec *ts1) { std::string sqlquery; struct stat statbuf; diff --git a/src/dbse.hpp b/src/dbse.hpp index 1136e7d9..dcd31235 100644 --- a/src/dbse.hpp +++ b/src/dbse.hpp @@ -57,8 +57,8 @@ ~cls_dbse(); void sqlite3db_cb (int arg_nb, char **arg_val, char **col_nm); pthread_mutex_t mutex_dbse; - void exec(ctx_dev *cam, std::string filename, std::string cmd); - void movielist_add(ctx_dev *cam, cls_movie *movie, timespec *ts1); + void exec(cls_camera *cam, std::string filename, std::string cmd); + void movielist_add(cls_camera *cam, cls_movie *movie, timespec *ts1); void movielist_get(int p_device_id, lst_movies *p_movielist); private: #ifdef HAVE_SQLITE3DB diff --git a/src/draw.cpp b/src/draw.cpp index e4853047..aa14d9b7 100644 --- a/src/draw.cpp +++ b/src/draw.cpp @@ -16,8 +16,8 @@ * */ -#include #include "motionplus.hpp" +#include "camera.hpp" #include "conf.hpp" #include "util.hpp" #include "logger.hpp" @@ -1558,7 +1558,7 @@ void cls_draw::largest_label() } } -cls_draw::cls_draw(ctx_dev *p_cam) +cls_draw::cls_draw(cls_camera *p_cam) { cam = p_cam; cfg_text_scale = cam->conf->text_scale; diff --git a/src/draw.hpp b/src/draw.hpp index 3d46fed4..0f4b9121 100644 --- a/src/draw.hpp +++ b/src/draw.hpp @@ -23,7 +23,7 @@ class cls_draw { public: - cls_draw(ctx_dev *p_cam); + cls_draw(cls_camera *p_cam); ~cls_draw(); int text(u_char *image , int width, int height, int startx, int starty @@ -34,7 +34,7 @@ void largest_label(); private: - ctx_dev *cam; + cls_camera *cam; u_char *char_arr_ptr[ASCII_MAX]; diff --git a/src/jpegutils.cpp b/src/jpegutils.cpp index a7e030fe..490cebcb 100644 --- a/src/jpegutils.cpp +++ b/src/jpegutils.cpp @@ -18,6 +18,7 @@ */ #include "motionplus.hpp" +#include "camera.hpp" #include "conf.hpp" #include "logger.hpp" #include "util.hpp" @@ -163,7 +164,7 @@ static void put_subjectarea(struct tiff_writing *into, ctx_coord *box) } struct ctx_exif_info { - ctx_dev *cam; + cls_camera *cam; timespec *ts_in1; ctx_coord *box; struct tm timestamp_tm; @@ -331,7 +332,7 @@ void jpgutl_exif_writeifd1(ctx_exif_info *exif_info) } -uint jpgutl_exif(u_char **exif, ctx_dev *cam, timespec *ts_in1, ctx_coord *box) +uint jpgutl_exif(u_char **exif, cls_camera *cam, timespec *ts_in1, ctx_coord *box) { struct ctx_exif_info *exif_info; uint buffer_size; @@ -716,7 +717,7 @@ static GLOBAL(int) _jpeg_mem_size(j_compress_ptr cinfo) * It must be called after jpeg_start_compress() but before * any image data is written by jpeg_write_scanlines(). */ -static void put_jpeg_exif(j_compress_ptr cinfo, ctx_dev *cam, +static void put_jpeg_exif(j_compress_ptr cinfo, cls_camera *cam, timespec *ts1, ctx_coord *box) { u_char *exif = NULL; @@ -846,7 +847,7 @@ int jpgutl_decode_jpeg (u_char *jpeg_data_in, int jpeg_data_len, int jpgutl_put_yuv420p(u_char *dest_image, int image_size, u_char *input_image, int width, int height, int quality, - ctx_dev *cam, timespec *ts1, ctx_coord *box) + cls_camera *cam, timespec *ts1, ctx_coord *box) { int i, j, jpeg_image_size; @@ -936,7 +937,7 @@ int jpgutl_put_yuv420p(u_char *dest_image, int image_size, int jpgutl_put_grey(u_char *dest_image, int image_size, u_char *input_image, int width, int height, int quality, - ctx_dev *cam, timespec *ts1, ctx_coord *box) + cls_camera *cam, timespec *ts1, ctx_coord *box) { int y, dest_image_size; JSAMPROW row_ptr[1]; diff --git a/src/jpegutils.hpp b/src/jpegutils.hpp index a91d2d46..732668e8 100644 --- a/src/jpegutils.hpp +++ b/src/jpegutils.hpp @@ -25,11 +25,11 @@ unsigned int width, unsigned int height, unsigned char *volatile img_out); int jpgutl_put_yuv420p(unsigned char *dest_image, int image_size, unsigned char *input_image, int width, int height, int quality, - ctx_dev *cam, timespec *ts1, ctx_coord *box); + cls_camera *cam, timespec *ts1, ctx_coord *box); int jpgutl_put_grey(unsigned char *dest_image, int image_size, unsigned char *input_image, int width, int height, int quality, - ctx_dev *cam, timespec *ts1, ctx_coord *box); - uint jpgutl_exif(u_char **exif, ctx_dev *cam + cls_camera *cam, timespec *ts1, ctx_coord *box); + uint jpgutl_exif(u_char **exif, cls_camera *cam , timespec *ts_in1, ctx_coord *box); #endif /* _INCLUDE_JPEGUTILS_HPP_ */ diff --git a/src/libcam.cpp b/src/libcam.cpp index a9be6128..6c79c278 100644 --- a/src/libcam.cpp +++ b/src/libcam.cpp @@ -17,17 +17,8 @@ * */ -/* TODO: - * Determine if we need to have multiple requests or buffers. - * (The current logic is just a single request and buffer but - * this may need to change to allow for multiple requests or buffers - * so as to reduce latency. As of now, it is kept simple with - * a single request and buffer.) - * Need to determine flags for designating start up, shutdown - * etc. and possibly add mutex locking. Startup currently has - * a SLEEP to allow for initialization but this should change - */ #include "motionplus.hpp" +#include "camera.hpp" #include "conf.hpp" #include "logger.hpp" #include "util.hpp" @@ -833,11 +824,12 @@ int cls_libcam::next(ctx_image_data *img_data) #endif } -cls_libcam::cls_libcam(ctx_dev *p_cam) +cls_libcam::cls_libcam(cls_camera *p_cam) { #ifdef HAVE_LIBCAM MOTPLS_LOG(NTC, TYPE_VIDEO, NO_ERRNO,_("Opening libcam")); cam = p_cam; + params = nullptr; conf_libcam_params = cam->conf->libcam_params; conf_libcam_device = cam->conf->libcam_device; conf_width = cam->conf->width; diff --git a/src/libcam.hpp b/src/libcam.hpp index d5057722..df1d35ae 100644 --- a/src/libcam.hpp +++ b/src/libcam.hpp @@ -33,11 +33,11 @@ class cls_libcam { public: - cls_libcam(ctx_dev *p_cam); + cls_libcam(cls_camera *p_cam); ~cls_libcam(); int next(ctx_image_data *img_data); private: - ctx_dev *cam; + cls_camera *cam; ctx_params *params; std::unique_ptr cam_mgr; @@ -83,7 +83,7 @@ #define LIBCAMVER 0 class cls_libcam { public: - cls_libcam(ctx_dev *p_cam); + cls_libcam(cls_camera *p_cam); ~cls_libcam(); int next(ctx_image_data *img_data); }; diff --git a/src/logger.cpp b/src/logger.cpp index aeffcced..f5ca8897 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -53,7 +53,7 @@ void ff_log(void *var1, int errnbr, const char *fmt, va_list vlist) fflvl = ((motlog->log_fflevel -2) * 8); - if (errnbr < fflvl) { + if (errnbr <= fflvl ) { MOTPLS_LOG(INF, TYPE_ALL, NO_ERRNO,"%s",buff ); } } @@ -256,6 +256,7 @@ cls_log::cls_log(ctx_motapp *p_motapp) c_motapp = p_motapp; log_mode = LOGMODE_NONE; log_level = LEVEL_DEFAULT; + log_fflevel = 4; log_file_ptr = nullptr; log_file_name = ""; flood_cnt = 0; diff --git a/src/motionplus.cpp b/src/motionplus.cpp index b44797fd..5bb8bd43 100644 --- a/src/motionplus.cpp +++ b/src/motionplus.cpp @@ -28,55 +28,44 @@ #include "movie.hpp" #include "netcam.hpp" -pthread_key_t tls_key_threadnr; volatile enum MOTPLS_SIGNAL motsignal; /** Process signals sent */ static void motpls_signal_process(ctx_motapp *motapp) { - uint indx; + int indx; switch(motsignal){ case MOTPLS_SIGNAL_ALARM: /* Trigger snapshot */ - if (motapp->cam_list != NULL) { - for (indx=0; indx<(uint)motapp->cam_cnt; indx++) { - if (motapp->cam_list[indx]->conf->snapshot_interval) { - motapp->cam_list[indx]->snapshot = true; - } - } + for (indx=0; indxcam_cnt; indx++) { + motapp->cam_list[indx]->action_snapshot = true; } break; case MOTPLS_SIGNAL_USR1: /* Trigger the end of a event */ - if (motapp->cam_list != NULL) { - for (indx=0; indx<(uint)motapp->cam_cnt; indx++) { - motapp->cam_list[indx]->event_stop = true; - } + for (indx=0; indxcam_cnt; indx++) { + motapp->cam_list[indx]->event_stop = true; } break; case MOTPLS_SIGNAL_SIGHUP: /* Reload the parameters and restart*/ motapp->reload_all = true; motapp->webu->wb_finish = true; - for (indx=0; indx<(uint)motapp->cam_cnt; indx++) { + for (indx=0; indxcam_cnt; indx++) { motapp->cam_list[indx]->event_stop = true; - motapp->cam_list[indx]->finish_dev = true; - motapp->cam_list[indx]->restart_dev = false; + motapp->cam_list[indx]->stop(); } - for (indx=0; indxsnd_list.size(); indx++) { - motapp->snd_list[indx]->handler_stop = true; + for (indx=0; indxsnd_cnt; indx++) { + motapp->snd_list[indx]->stop(); } break; case MOTPLS_SIGNAL_SIGTERM: /* Quit application */ - motapp->webu->wb_finish = true; - for (indx=0; indx<(uint)motapp->cam_cnt; indx++) { + for (indx=0; indxcam_cnt; indx++) { motapp->cam_list[indx]->event_stop = true; - motapp->cam_list[indx]->finish_dev = true; - motapp->cam_list[indx]->restart_dev = false; + motapp->cam_list[indx]->stop(); } - for (indx=0; indxsnd_list.size(); indx++) { - motapp->snd_list[indx]->handler_stop = true; + for (indx=0; indxsnd_cnt; indx++) { + motapp->snd_list[indx]->stop(); } - motapp->finish_all = true; default: break; } @@ -86,7 +75,6 @@ static void motpls_signal_process(ctx_motapp *motapp) /** Handle signals sent */ static void sig_handler(int signo) { - /*The FALLTHROUGH is a special comment required by compiler. Do not edit it*/ switch(signo) { case SIGALRM: @@ -108,7 +96,6 @@ static void sig_handler(int signo) case SIGSEGV: exit(0); case SIGVTALRM: - printf("SIGVTALRM went off\n"); pthread_exit(NULL); break; } @@ -118,12 +105,9 @@ static void sig_handler(int signo) static void sigchild_handler(int signo) { (void)signo; - #ifdef WNOHANG while (waitpid(-1, NULL, WNOHANG) > 0) {}; #endif /* WNOHANG */ - - return; } /** Attach handlers to a number of signals that MotionPlus need to catch. */ @@ -184,24 +168,24 @@ static void motpls_pid_write(ctx_motapp *motapp) , motapp->conf->pid_file.c_str()); } } + + MOTPLS_LOG(NTC, TYPE_ALL, NO_ERRNO,_("Motionplus pid: %d"), getpid()); + } /** Remove the process id file ( pid file ) before MotionPlus exit. */ static void motpls_pid_remove(ctx_motapp *motapp) { - if ((motapp->conf->pid_file != "") && - (motapp->restart_all == false)) { + (motapp->reload_all == false)) { if (!unlink(motapp->conf->pid_file.c_str())) { MOTPLS_LOG(NTC, TYPE_ALL, NO_ERRNO, _("Removed process id file (pid file).")); } else{ MOTPLS_LOG(ERR, TYPE_ALL, SHOW_ERRNO, _("Error removing pid file")); } } - } -/** Turn MotionPlus into a daemon through forking. */ static void motpls_daemon() { int fd; @@ -260,37 +244,6 @@ static void motpls_daemon() sigaction(SIGTSTP, &sig_ign_action, NULL); } -void motpls_av_log(void *ignoreme, int errno_flag, const char *fmt, va_list vl) -{ - char buf[1024]; - char *end; - int retcd; - - (void)ignoreme; - - /* Valgrind occasionally reports use of uninitialized values in here when we interrupt - * some rtsp functions. The offending value is either fmt or vl and seems to be from a - * debug level of av functions. To address it we flatten the message after we know - * the log level. Now we put the avcodec messages to INF level since their error - * are not necessarily our errors. - */ - - if (errno_flag <= AV_LOG_WARNING) { - retcd = vsnprintf(buf, sizeof(buf), fmt, vl); - if (retcd >=1024) { - MOTPLS_LOG(DBG, TYPE_ENCODER, NO_ERRNO, "av message truncated %d bytes",(retcd - 1024)); - } - end = buf + strlen(buf); - if (end > buf && end[-1] == '\n') { - *--end = 0; - } - if (strstr(buf, "Will reconnect at") == NULL) { - MOTPLS_LOG(INF, TYPE_ENCODER, NO_ERRNO, "%s", buf); - } - } - -} - void motpls_av_init(void) { MOTPLS_LOG(NTC, TYPE_ENCODER, NO_ERRNO, _("libavcodec version %d.%d.%d") @@ -305,8 +258,6 @@ void motpls_av_init(void) avformat_network_init(); avdevice_register_all(); - av_log_set_callback(motpls_av_log); - } void motpls_av_deinit(void) @@ -317,7 +268,8 @@ void motpls_av_deinit(void) /* Validate or set the position on the all cameras image*/ static void motpls_allcams_init(ctx_motapp *motapp) { - int indx, indx1, row, col, mx_row, mx_col, col_chk; + int indx, indx1; + int row, col, mx_row, mx_col, col_chk; bool cfg_valid, chk; std::string cfg_row, cfg_col; ctx_params *params_loc; @@ -482,58 +434,43 @@ static void motpls_allcams_init(ctx_motapp *motapp) } -static void motpls_shutdown(ctx_motapp *motapp) -{ - motpls_pid_remove(motapp); - - mydelete(motapp->webu); - mydelete(motapp->dbse); - mydelete(motapp->conf); - mydelete(motapp->all_sizes); - mydelete(motlog); - -} - static void motpls_device_ids(ctx_motapp *motapp) { - uint indx, indx2, sndmx, cammx; + int indx, indx2; int invalid_ids; - sndmx = (uint)motapp->snd_list.size(); - cammx = (uint)motapp->cam_cnt; - - /* Defaults */ - for (indx=0; indxcam_cnt; indx++) { if (motapp->cam_list[indx]->conf->device_id != 0) { motapp->cam_list[indx]->device_id = motapp->cam_list[indx]->conf->device_id; } else { motapp->cam_list[indx]->device_id = (int)indx + 1; } } - for (indx=0; indxsnd_cnt; indx++) { if (motapp->snd_list[indx]->conf->device_id != 0) { motapp->snd_list[indx]->device_id = motapp->snd_list[indx]->conf->device_id; } else { - motapp->snd_list[indx]->device_id = motapp->cam_cnt + (int)indx + 1; + motapp->snd_list[indx]->device_id = (int)(motapp->cam_cnt + indx + 1); } } /*Check for unique values*/ invalid_ids = false; - for (indx=0; indxcam_cnt; indx++) { + for (indx2=indx+1; indx2cam_cnt; indx2++) { if (motapp->cam_list[indx]->device_id == motapp->cam_list[indx2]->device_id) { invalid_ids = true; } } - for (indx2=0; indx2snd_cnt; indx2++) { if (motapp->cam_list[indx]->device_id == motapp->snd_list[indx2]->device_id) { invalid_ids = true; } } } - for (indx=0; indxsnd_cnt; indx++) { + for (indx2=indx+1; indx2snd_cnt; indx2++) { if (motapp->snd_list[indx]->device_id == motapp->snd_list[indx2]->device_id) { invalid_ids = true; } @@ -543,11 +480,11 @@ static void motpls_device_ids(ctx_motapp *motapp) if (invalid_ids) { MOTPLS_LOG(WRN, TYPE_ALL, NO_ERRNO,_("Device IDs are not unique.")); MOTPLS_LOG(WRN, TYPE_ALL, NO_ERRNO,_("Falling back to sequence numbers")); - for (indx=0; indxcam_list[indx]->device_id = (int)indx + 1; + for (indx=0; indxcam_cnt; indx++) { + motapp->cam_list[indx]->device_id = indx + 1; } - for (indx=0; indxsnd_list[indx]->device_id = motapp->cam_cnt + (int)indx + 1; + for (indx=0; indxsnd_cnt; indx++) { + motapp->snd_list[indx]->device_id = motapp->cam_cnt+ indx + 1; } } @@ -618,13 +555,117 @@ static void motpls_ntc(void) } -/** Initialize upon start up or restart */ -static void motpls_startup(ctx_motapp *motapp, int daemonize) +/* Check for whether any cams are locked */ +static void motpls_watchdog(ctx_motapp *motapp, uint camindx) { + int indx; + + if (motapp->cam_list[camindx]->handler_finished == true) { + return; + } + + motapp->cam_list[camindx]->watchdog--; + if (motapp->cam_list[camindx]->watchdog > 0) { + return; + } + + MOTPLS_LOG(ERR, TYPE_ALL, NO_ERRNO + , _("Camera %d - Watchdog timeout.") + , motapp->cam_list[camindx]->device_id); + + /* Shut down all the cameras */ + for (indx=0; indxcam_cnt; indx++) { + motapp->cam_list[indx]->event_stop = true; + pthread_mutex_unlock(&motapp->mutex_camlst); + pthread_mutex_unlock(&motapp->mutex_parms); + pthread_mutex_unlock(&motapp->mutex_post); + pthread_mutex_unlock(&motapp->dbse->mutex_dbse); + pthread_mutex_unlock(&motapp->global_lock); + pthread_mutex_unlock(&motapp->cam_list[indx]->stream.mutex); + + if ((motapp->cam_list[indx]->camera_type == CAMERA_TYPE_NETCAM) && + (motapp->cam_list[indx]->netcam != nullptr)) { + pthread_mutex_unlock(&motapp->cam_list[indx]->netcam->mutex); + pthread_mutex_unlock(&motapp->cam_list[indx]->netcam->mutex_pktarray); + pthread_mutex_unlock(&motapp->cam_list[indx]->netcam->mutex_transfer); + motapp->cam_list[indx]->netcam->finish = true; + } + if ((motapp->cam_list[indx]->camera_type == CAMERA_TYPE_NETCAM) && + (motapp->cam_list[indx]->netcam_high != nullptr)) { + pthread_mutex_unlock(&motapp->cam_list[indx]->netcam_high->mutex); + pthread_mutex_unlock(&motapp->cam_list[indx]->netcam_high->mutex_pktarray); + pthread_mutex_unlock(&motapp->cam_list[indx]->netcam_high->mutex_transfer); + motapp->cam_list[indx]->netcam_high->finish = true; + } + + motapp->cam_list[indx]->stop(); + if (motsignal != MOTPLS_SIGNAL_SIGTERM) { + motapp->cam_list[indx]->handler_stop = false; /*Trigger a restart*/ + } + } + +} + +static bool motpls_check_devices(ctx_motapp *motapp) +{ + int indx; + bool retcd; + + for (indx=0; indxcam_cnt; indx++) { + motpls_watchdog(motapp, indx); + } + + retcd = false; + for (indx=0; indxcam_cnt; indx++) { + if (motapp->cam_list[indx]->handler_finished == false) { + retcd = true; + } else if (motapp->cam_list[indx]->handler_stop == false) { + motapp->cam_list[indx]->start(); + retcd = true; + } + } + for (indx=0; indxsnd_cnt; indx++) { + if (motapp->snd_list[indx]->handler_finished == false) { + retcd = true; + } else if (motapp->snd_list[indx]->handler_stop == false) { + motapp->snd_list[indx]->start(); + retcd = true; + } + } + + if ((motapp->webu->wb_finish == false) && + (motapp->webu->wb_daemon != NULL)) { + retcd = true; + } + + return retcd; + +} + +static void motpls_init(ctx_motapp *motapp, int argc, char *argv[]) +{ + int indx; + + motapp->argc = argc; + motapp->argv = argv; + + motapp->reload_all = false; + motapp->parms_changed = false; + motapp->pause = false; + motapp->cam_add = false; + motapp->cam_delete = -1; + motapp->cam_cnt = 0; + motapp->snd_cnt = 0; + motapp->conf = nullptr; + motapp->dbse = nullptr; + motapp->webu = nullptr; + + pthread_mutex_init(&motapp->global_lock, NULL); + pthread_mutex_init(&motapp->mutex_parms, NULL); + pthread_mutex_init(&motapp->mutex_camlst, NULL); + pthread_mutex_init(&motapp->mutex_post, NULL); + motapp->conf = new cls_config; - - motlog = new cls_log(motapp); - motapp->conf->init(motapp); motlog->log_level = motapp->conf->log_level; @@ -635,11 +676,9 @@ static void motpls_startup(ctx_motapp *motapp, int daemonize) mytranslate_text("",motapp->conf->native_language); - if (daemonize) { - if (motapp->conf->daemon) { - motpls_daemon(); - MOTPLS_LOG(NTC, TYPE_ALL, NO_ERRNO, _("MotionPlus running as daemon process")); - } + if (motapp->conf->daemon) { + motpls_daemon(); + MOTPLS_LOG(NTC, TYPE_ALL, NO_ERRNO, _("MotionPlus running as daemon process")); } motapp->conf->parms_log(motapp); @@ -655,219 +694,44 @@ static void motpls_startup(ctx_motapp *motapp, int daemonize) motpls_allcams_init(motapp); -} - -/** Start a camera thread */ -static void motpls_start_thread_cam(ctx_dev *cam) -{ - int retcd; - pthread_attr_t thread_attr; - - pthread_attr_init(&thread_attr); - pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); - - cam->restart_dev = true; - retcd = pthread_create(&cam->thread_id, &thread_attr, &mlp_main, cam); - if (retcd != 0) { - MOTPLS_LOG(WRN, TYPE_ALL, NO_ERRNO,_("Unable to start camera thread.")); - } - pthread_attr_destroy(&thread_attr); - -} - -static void motpls_restart(ctx_motapp *motapp) -{ - - MOTPLS_LOG(WRN, TYPE_ALL, NO_ERRNO,_("Restarting MotionPlus.")); - - motpls_shutdown(motapp); - - SLEEP(2, 0); - - motpls_startup(motapp, false); - - MOTPLS_LOG(WRN, TYPE_ALL, NO_ERRNO,_("MotionPlus restarted")); - - motapp->restart_all = false; - -} - -/* Check for whether any cams are locked */ -static void motpls_watchdog(ctx_motapp *motapp, uint camindx) -{ - int indx; - - if (motapp->cam_list[camindx]->running_dev == false) { - return; - } - - motapp->cam_list[camindx]->watchdog--; - if (motapp->cam_list[camindx]->watchdog > 0) { - return; - } - - MOTPLS_LOG(ERR, TYPE_ALL, NO_ERRNO - , _("Camera %d - Watchdog timeout.") - , motapp->cam_list[camindx]->device_id); - - /* Shut down all the cameras */ - for (indx=0; indxcam_cnt; indx++) { - pthread_mutex_unlock(&motapp->mutex_camlst); - pthread_mutex_unlock(&motapp->mutex_parms); - pthread_mutex_unlock(&motapp->mutex_camlst); - pthread_mutex_unlock(&motapp->mutex_post); - if (motapp->dbse != NULL) { - pthread_mutex_unlock(&motapp->dbse->mutex_dbse); - } - pthread_mutex_unlock(&motapp->global_lock); - pthread_mutex_unlock(&motapp->cam_list[indx]->stream.mutex); - pthread_mutex_unlock(&motapp->cam_list[indx]->parms_lock); - - if ((motapp->cam_list[indx]->camera_type == CAMERA_TYPE_NETCAM) && - (motapp->cam_list[indx]->netcam != NULL)) { - pthread_mutex_unlock(&motapp->cam_list[indx]->netcam->mutex); - pthread_mutex_unlock(&motapp->cam_list[indx]->netcam->mutex_pktarray); - pthread_mutex_unlock(&motapp->cam_list[indx]->netcam->mutex_transfer); - motapp->cam_list[indx]->netcam->finish = true; - } - if ((motapp->cam_list[indx]->camera_type == CAMERA_TYPE_NETCAM) && - (motapp->cam_list[indx]->netcam_high != NULL)) { - pthread_mutex_unlock(&motapp->cam_list[indx]->netcam_high->mutex); - pthread_mutex_unlock(&motapp->cam_list[indx]->netcam_high->mutex_pktarray); - pthread_mutex_unlock(&motapp->cam_list[indx]->netcam_high->mutex_transfer); - motapp->cam_list[indx]->netcam_high->finish = true; - } - motapp->cam_list[indx]->event_stop = true; - motapp->cam_list[indx]->finish_dev = true; - } - - SLEEP(motapp->cam_list[camindx]->conf->watchdog_kill, 0); - - /* When in a watchdog timeout and we get to a kill situation, - * we WILL have to leak memory because the freeing/deinit - * processes could lock this thread which would stop everything. - */ - for (indx=0; indxcam_cnt; indx++) { - if (motapp->cam_list[indx]->netcam != NULL) { - if (motapp->cam_list[indx]->netcam->handler_finished == false) { - MOTPLS_LOG(ERR, TYPE_ALL, NO_ERRNO - , _("Camera %d - Watchdog netcam kill.") - , motapp->cam_list[indx]->device_id); - pthread_kill(motapp->cam_list[indx]->netcam->net_thread.native_handle(), SIGVTALRM); - } - } - if (motapp->cam_list[indx]->netcam_high != NULL) { - if (motapp->cam_list[indx]->netcam_high->handler_finished == false) { - MOTPLS_LOG(ERR, TYPE_ALL, NO_ERRNO - , _("Camera %d - Watchdog netcam_high kill.") - , motapp->cam_list[indx]->device_id); - pthread_kill(motapp->cam_list[indx]->netcam_high->net_thread.native_handle(), SIGVTALRM); - } - } - if (motapp->cam_list[indx]->running_dev == true) { - MOTPLS_LOG(ERR, TYPE_ALL, NO_ERRNO - , _("Camera %d - Watchdog kill.") - , motapp->cam_list[indx]->device_id); - pthread_kill(motapp->cam_list[indx]->thread_id, SIGVTALRM); - }; - motapp->cam_list[indx]->running_dev = false; - motapp->cam_list[indx]->restart_dev = false; - } - motapp->restart_all = true; - motapp->finish_all = true; - motapp->webu->wb_finish = true; - motapp->threads_running = 0; - -} - -static int motpls_check_threadcount(ctx_motapp *motapp) -{ - uint thrdcnt, indx; - - thrdcnt = 0; - - for (indx=0; indx<(uint)motapp->cam_cnt; indx++) { - if (motapp->cam_list[indx]->running_dev || motapp->cam_list[indx]->restart_dev) { - thrdcnt++; - } - } - for (indx=0; indxsnd_list.size(); indx++) { - if (motapp->snd_list[indx]->handler_finished == false) { - thrdcnt++; - } - } - - if ((motapp->webu->wb_finish == false) && - (motapp->webu->wb_daemon != NULL)) { - thrdcnt++; - } - - if (((thrdcnt == 0) && motapp->finish_all) || - ((thrdcnt == 0) && (motapp->threads_running == 0))) { - return 1; - } else { - return 0; - } - -} - -static void motpls_init(ctx_motapp *motapp, int argc, char *argv[]) -{ - motapp->argc = argc; - motapp->argv = argv; - - motapp->cam_list = (ctx_dev **)mymalloc(sizeof(ctx_dev *)); - motapp->cam_list[0] = nullptr; - - motapp->threads_running = 0; - motapp->finish_all = false; - motapp->restart_all = false; - motapp->reload_all = false; - motapp->parms_changed = false; - motapp->pause = false; - motapp->cam_add = false; - motapp->cam_delete = -1; - motapp->cam_cnt = 0; - - motapp->conf = nullptr; - motapp->dbse = nullptr; - motapp->webu = nullptr; - - pthread_key_create(&tls_key_threadnr, NULL); - pthread_setspecific(tls_key_threadnr, (void *)(0)); - - pthread_mutex_init(&motapp->global_lock, NULL); - pthread_mutex_init(&motapp->mutex_parms, NULL); - pthread_mutex_init(&motapp->mutex_camlst, NULL); - pthread_mutex_init(&motapp->mutex_post, NULL); - - motpls_startup(motapp, true); - motpls_av_init(); + if ((motapp->cam_cnt > 0) || (motapp->snd_cnt > 0)) { + for (indx=0; indxcam_cnt; indx++) { + motapp->cam_list[indx]->start(); + } + for (indx=0; indxsnd_cnt; indx++) { + motapp->snd_list[indx]->start(); + } + } else { + MOTPLS_LOG(NTC, TYPE_ALL, NO_ERRNO + , _("No camera or sound configuration files specified.")); + MOTPLS_LOG(NTC, TYPE_ALL, NO_ERRNO + , _("Waiting for camera or sound configuration to be added via web control.")); + } + } static void motpls_deinit(ctx_motapp *motapp) { - uint indx; + int indx; motpls_av_deinit(); + motpls_pid_remove(motapp); - motpls_shutdown(motapp); + mydelete(motapp->webu); + mydelete(motapp->dbse); + mydelete(motapp->conf); + mydelete(motapp->all_sizes); - indx = 0; - while (motapp->cam_list[indx] != nullptr) { - mydelete(motapp->cam_list[indx]->conf); + for (indx = 0; indx < motapp->cam_cnt;indx++) { mydelete(motapp->cam_list[indx]); - indx++; } - myfree(motapp->cam_list); - for (indx = 0; indx < motapp->snd_list.size();indx++) { + for (indx = 0; indx < motapp->snd_cnt;indx++) { mydelete(motapp->snd_list[indx]); } - pthread_key_delete(tls_key_threadnr); pthread_mutex_destroy(&motapp->global_lock); pthread_mutex_destroy(&motapp->mutex_parms); pthread_mutex_destroy(&motapp->mutex_camlst); @@ -877,44 +741,29 @@ static void motpls_deinit(ctx_motapp *motapp) /* Check for whether to add a new cam */ static void motpls_cam_add(ctx_motapp *motapp) { - int indx_cam, indx; - if (motapp->cam_add == false) { return; } pthread_mutex_lock(&motapp->mutex_camlst); - motapp->conf->camera_add(motapp); + motapp->conf->camera_add(motapp, "", false); pthread_mutex_unlock(&motapp->mutex_camlst); - indx = 1; - for (indx_cam=0; indx_camcam_cnt; indx_cam++) { - if (indx < motapp->cam_list[indx_cam]->device_id) { - indx = motapp->cam_list[indx_cam]->device_id; - } - } - indx++; - - motapp->cam_list[motapp->cam_cnt-1]->device_id = indx; - motapp->cam_list[motapp->cam_cnt-1]->conf->device_id = indx; - motapp->cam_list[motapp->cam_cnt-1]->conf->webcontrol_port = 0; - motapp->cam_add = false; } - /* Check for whether to delete a new cam */ static void motpls_cam_delete(ctx_motapp *motapp) { - int indx1, indx2, maxcnt; - ctx_dev **tmp, *cam; + cls_camera *cam; - if ((motapp->cam_delete == -1) || (motapp->cam_cnt == 0)) { + if ((motapp->cam_delete == -1) || + (motapp->cam_cnt == 0)) { motapp->cam_delete = -1; return; } - if (motapp->cam_delete >= motapp->cam_cnt) { + if (motapp->cam_delete >= (int)motapp->cam_cnt) { MOTPLS_LOG(NTC, TYPE_ALL, NO_ERRNO , _("Invalid camera specified for deletion. %d"), motapp->cam_delete); motapp->cam_delete = -1; @@ -925,39 +774,19 @@ static void motpls_cam_delete(ctx_motapp *motapp) MOTPLS_LOG(NTC, TYPE_STREAM, NO_ERRNO, _("Stopping %s device_id %d") , cam->conf->device_name.c_str(), cam->device_id); - cam->restart_dev = false; - cam->finish_dev = true; - maxcnt = 100; - indx1 = 0; - while ((cam->running_dev) && (indx1 < maxcnt)) { - SLEEP(0, 50000000) - indx1++; - } - if (indx1 == maxcnt) { + cam->stop(); + + if (cam->handler_finished == false) { MOTPLS_LOG(ERR, TYPE_ALL, NO_ERRNO, "Error stopping camera. Timed out shutting down"); motapp->cam_delete = -1; return; } MOTPLS_LOG(NTC, TYPE_ALL, NO_ERRNO, "Camera stopped"); - tmp = (ctx_dev **)mymalloc(sizeof(ctx_dev *) * (uint)(motapp->cam_cnt)); - tmp[motapp->cam_cnt-1] = NULL; - - indx2 = 0; - for (indx1=0; indx1cam_cnt; indx1++) { - if (indx1 != motapp->cam_delete) { - tmp[indx2] = motapp->cam_list[indx1]; - indx2++; - } - } - pthread_mutex_lock(&motapp->mutex_camlst); - delete motapp->cam_list[motapp->cam_delete]->conf; - delete motapp->cam_list[motapp->cam_delete]; - myfree(motapp->cam_list); - motapp->cam_cnt--; - motapp->cam_list = tmp; + mydelete(motapp->cam_list[motapp->cam_delete]); + motapp->cam_list.erase(motapp->cam_list.begin() + motapp->cam_delete); pthread_mutex_unlock(&motapp->mutex_camlst); motapp->cam_delete = -1; @@ -967,104 +796,39 @@ static void motpls_cam_delete(ctx_motapp *motapp) /** Main entry point of MotionPlus. */ int main (int argc, char **argv) { - uint indx; ctx_motapp *motapp; motapp = new ctx_motapp; + motlog = new cls_log(motapp); setup_signals(); - - motpls_init(motapp, argc, argv); - - MOTPLS_LOG(NTC, TYPE_ALL, NO_ERRNO - ,_("Motionplus pid: %d"), getpid()); - + mythreadname_set("mp",0,""); while (true) { - if (motapp->restart_all) { - motpls_restart(motapp); - } - - for (indx=0; indx<(uint)motapp->cam_cnt; indx++) { - motpls_start_thread_cam(motapp->cam_list[indx]); - } - for (indx=0; indxsnd_list.size(); indx++) { - motapp->snd_list[indx]->start(); - } - - if ((motapp->cam_cnt == 0) && - (motapp->snd_list.size() ==0)) { - MOTPLS_LOG(NTC, TYPE_ALL, NO_ERRNO - , _("No camera or sound configuration files specified.")); - MOTPLS_LOG(NTC, TYPE_ALL, NO_ERRNO - , _("Waiting for camera or sound configuration to be added via web control.")); - } - - while (true) { + motpls_init(motapp, argc, argv); + while (motpls_check_devices(motapp)) { SLEEP(1, 0); - - if (motpls_check_threadcount(motapp)) { - break; - } - - for (indx=0; indx<(uint)motapp->cam_cnt; indx++) { - /* Check if threads wants to be restarted */ - if ((motapp->cam_list[indx]->running_dev == false) && - (motapp->cam_list[indx]->restart_dev == true)) { - MOTPLS_LOG(NTC, TYPE_ALL, NO_ERRNO - ,_("MotionPlus camera %d restart") - , motapp->cam_list[indx]->device_id); - motpls_start_thread_cam(motapp->cam_list[indx]); - } - motpls_watchdog(motapp, indx); - } - for (indx=0; indxsnd_list.size(); indx++) { - if ((motapp->snd_list[indx]->handler_finished == true) && - (motapp->snd_list[indx]->restart == true)) { - MOTPLS_LOG(NTC, TYPE_ALL, NO_ERRNO - ,_("MotionPlus sound %d restart") - , motapp->snd_list[indx]->device_id); - motapp->snd_list[indx]->start(); - } - if ((motapp->snd_list[indx]->handler_finished == false) && - (motapp->snd_list[indx]->handler_stop == true)) { - MOTPLS_LOG(NTC, TYPE_ALL, NO_ERRNO - ,_("MotionPlus stop sound %d") - , motapp->snd_list[indx]->device_id); - motapp->snd_list[indx]->stop(); - } - } - if (motsignal != MOTPLS_SIGNAL_NONE) { motpls_signal_process(motapp); } - motpls_cam_add(motapp); motpls_cam_delete(motapp); - } - - /* If there are no cameras running, this allows for adding */ - motpls_cam_add(motapp); - - motapp->finish_all = false; - MOTPLS_LOG(NTC, TYPE_ALL, NO_ERRNO, _("Motionplus devices finished")); - - if (motapp->restart_all) { - SLEEP(1, 0); /* Rest before restarting */ - } else if (motapp->reload_all) { + if (motapp->reload_all) { motpls_deinit(motapp); - motpls_init(motapp, argc, argv); + motapp->reload_all = false; } else { break; } } - MOTPLS_LOG(NTC, TYPE_ALL, NO_ERRNO, _("MotionPlus terminating")); motpls_deinit(motapp); - delete motapp; + MOTPLS_LOG(NTC, TYPE_ALL, NO_ERRNO, _("MotionPlus terminating")); + + mydelete(motlog); + mydelete(motapp); return 0; } diff --git a/src/motionplus.hpp b/src/motionplus.hpp index e59c5825..3ce91217 100644 --- a/src/motionplus.hpp +++ b/src/motionplus.hpp @@ -60,7 +60,6 @@ #include #include - #if defined(HAVE_PTHREAD_NP_H) #include #endif @@ -117,6 +116,7 @@ struct ctx_motapp; struct ctx_images; struct ctx_image_data; +class cls_camera; class cls_sound; class cls_algsec; class cls_alg; @@ -202,7 +202,6 @@ enum CAPTURE_RESULT { enum DEVICE_STATUS { STATUS_CLOSED, /* Device is closed */ STATUS_INIT, /* First time initialize */ - STATUS_RESET, /* Clean up and re-initialize */ STATUS_OPENED /* Successfully started the device */ }; @@ -269,80 +268,6 @@ struct ctx_col_item { typedef std::list lst_cols; typedef lst_cols::iterator it_cols; -struct ctx_coord { - int x; - int y; - int width; - int height; - int minx; - int maxx; - int miny; - int maxy; - int stddev_x; - int stddev_y; - int stddev_xy; -}; - -struct ctx_image_data { - unsigned char *image_norm; - unsigned char *image_high; - int diffs; - int diffs_raw; - int diffs_ratio; - int64_t idnbr_norm; - int64_t idnbr_high; - 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 */ - ctx_coord location; /* coordinates for center and size of last motion detection*/ - int total_labels; -}; - -struct ctx_images { - ctx_image_data *image_ring; /* The base address of the image ring buffer */ - ctx_image_data image_motion; /* Picture buffer for motion images */ - ctx_image_data image_preview; /* Picture buffer for best image when enables */ - - unsigned char *ref; /* The reference frame */ - unsigned char *ref_next; /* The reference frame */ - unsigned char *mask; /* Buffer for the mask file */ - unsigned char *common_buffer; - unsigned char *image_substream; - unsigned char *image_virgin; /* Last picture frame with no text or locate overlay */ - unsigned char *image_vprvcy; /* Virgin image with the privacy mask applied */ - unsigned char *mask_privacy; /* Buffer for the privacy mask values */ - unsigned char *mask_privacy_uv; /* Buffer for the privacy U&V values */ - unsigned char *mask_privacy_high; /* Buffer for the privacy mask values */ - unsigned char *mask_privacy_high_uv; /* Buffer for the privacy U&V values */ - unsigned char *image_secondary; /* Buffer for JPG from alg_sec methods */ - - int ring_size; - int ring_in; /* Index in image ring buffer we last added a image into */ - int ring_out; /* Index in image ring buffer we want to process next time */ - - int *ref_dyn; /* Dynamic objects to be excluded from reference frame */ - int *labels; - int *labelsize; - - int width; - int height; - int size_norm; /* Number of bytes for normal size image */ - - int width_high; - int height_high; - int size_high; /* Number of bytes for high resolution image */ - - int motionsize; - int labelgroup_max; - int labels_above; - int labelsize_max; - int largest_label; - int size_secondary; /* Size of the jpg put into image_secondary*/ - -}; - struct ctx_all_loc { int row; int col; @@ -360,160 +285,34 @@ struct ctx_all_sizes { bool reset; }; - -struct ctx_stream_data { - unsigned char *jpg_data; /* Image compressed as JPG */ - int jpg_sz; /* The number of bytes for jpg */ - int consumed; /* Bool for whether the jpeg data was consumed*/ - unsigned char *img_data; /* The base data used for image */ - int jpg_cnct; /* Counter of the number of jpg connections*/ - int ts_cnct; /* Counter of the number of mpegts connections */ - int all_cnct; /* Counter of the number of all camera connections */ -}; - -struct ctx_stream { - pthread_mutex_t mutex; - ctx_stream_data norm; /* Copy of the image to use for web stream*/ - ctx_stream_data sub; /* Copy of the image to use for web stream*/ - ctx_stream_data motion; /* Copy of the image to use for web stream*/ - ctx_stream_data source; /* Copy of the image to use for web stream*/ - ctx_stream_data secondary; /* Copy of the image to use for web stream*/ -}; - - -struct ctx_dev { - ctx_motapp *motapp; - int threadnr; - pthread_t thread_id; - - cls_config *conf; - ctx_images imgs; - - ctx_image_data *current_image; - - cls_alg *alg; - cls_algsec *algsec; - cls_movie *movie_norm; - cls_movie *movie_motion; - cls_movie *movie_timelapse; - cls_movie *movie_extpipe; - - ctx_stream stream; - - cls_draw *draw; - cls_netcam *netcam; - cls_netcam *netcam_high; - cls_picture *picture; - cls_rotate *rotate; - cls_v4l2cam *v4l2cam; - cls_libcam *libcam; - - int track_posx; - int track_posy; - int device_id; - enum CAMERA_TYPE camera_type; - enum DEVICE_STATUS device_status; - int noise; - int threshold; - int threshold_maximum; - - volatile bool snapshot; /* Make a snapshot */ - volatile bool event_stop; /* Boolean for whether to stop a event */ - volatile bool event_user; /* Boolean for whether to user triggered an event */ - volatile bool finish_dev; /* End the device thread */ - volatile bool restart_dev; /* Restart the device thread when it ends */ - bool running_dev; /* Device thread is running*/ - volatile int watchdog; - - int event_curr_nbr; - int event_prev_nbr; - char eventid[20]; /* Cam ID + Date/Time 99999yyyymmddhhmmss */ - char text_event_string[PATH_MAX]; /* The text for conv. spec. %C - */ - int text_scale; - - int postcap; /* downcounter, frames left to to send post event */ - int shots_mt; /* Monotonic clock shots count*/ - int shots_rt; /* Realtime clock shots count*/ - bool detecting_motion; - long frame_wait[AVGCNT]; /* Last wait times through motion loop*/ - - struct timespec frame_curr_ts; - struct timespec frame_last_ts; - - time_t lasttime; - time_t movie_start_time; - struct timespec connectionlosttime; /* timestamp from connection lost */ - int lastrate; - int startup_frames; - int frame_skip; - volatile bool pause; - int missing_frame_counter; /* counts failed attempts to fetch picture frame from camera */ - int lost_connection; - - int pipe; - int mpipe; - - char hostname[PATH_MAX]; - char action_user[40]; - - int movie_fps; - bool movie_passthrough; - - int filetype; - - int area_minx[9], area_miny[9], area_maxx[9], area_maxy[9]; - int areadetect_eventnbr; - - int previous_diffs, previous_location_x, previous_location_y; - bool passflag; //flag first frame vs all others. - - ctx_all_loc all_loc; /* position on all camera image */ - - pthread_mutex_t parms_lock; - bool parms_changed; /*bool indicating if the parms have changed */ - - uint64_t info_diff_tot; - uint64_t info_diff_cnt; - int info_sdev_min; - int info_sdev_max; - uint64_t info_sdev_tot; - -}; - +typedef std::vector vec_cam; typedef std::vector vec_snd; -typedef vec_snd::iterator it_snd; struct ctx_motapp { - ctx_dev **cam_list; + vec_cam cam_list; vec_snd snd_list; - pthread_mutex_t global_lock; + bool reload_all; + bool cam_add; + int cam_delete; /* 0 for no action, other numbers specify camera to remove */ + int cam_cnt; + int snd_cnt; + int argc; + char **argv; + bool pause; - volatile int threads_running; - volatile bool finish_all; - volatile bool restart_all; - volatile bool reload_all; - volatile bool cam_add; /* Bool for whether to add a camera to the list */ - volatile int cam_delete; /* 0 for no action, other numbers specify camera to remove */ - - int argc; - char **argv; - bool pause; cls_config *conf; - int cam_cnt; ctx_all_sizes *all_sizes; cls_webu *webu; cls_dbse *dbse; bool parms_changed; /*bool indicating if the parms have changed */ + pthread_mutex_t global_lock; pthread_mutex_t mutex_parms; /* mutex used to lock when changing parms */ pthread_mutex_t mutex_camlst; /* Lock the list of cams while adding/removing */ pthread_mutex_t mutex_post; /* mutex to allow for processing of post actions*/ - }; -extern pthread_key_t tls_key_threadnr; /* key for thread number */ - #endif /* _INCLUDE_MOTIONPLUS_HPP_ */ diff --git a/src/movie.cpp b/src/movie.cpp index 5311cee7..0ff67257 100644 --- a/src/movie.cpp +++ b/src/movie.cpp @@ -17,6 +17,7 @@ */ #include "motionplus.hpp" +#include "camera.hpp" #include "conf.hpp" #include "logger.hpp" #include "util.hpp" @@ -1747,7 +1748,7 @@ void cls_movie::init_vars() } -cls_movie::cls_movie(ctx_dev *p_cam, std::string pmovie_type) +cls_movie::cls_movie(cls_camera *p_cam, std::string pmovie_type) { cam = p_cam; diff --git a/src/movie.hpp b/src/movie.hpp index 7a8e4631..978296fe 100644 --- a/src/movie.hpp +++ b/src/movie.hpp @@ -22,7 +22,7 @@ class cls_movie { public: - cls_movie(ctx_dev *p_cam, std::string pmovie_type); + cls_movie(cls_camera *p_cam, std::string pmovie_type); ~cls_movie(); void start(); void stop(); @@ -38,7 +38,7 @@ class cls_movie { bool is_running; private: - ctx_dev *cam; + cls_camera *cam; void free_pkt(); void free_nal(); diff --git a/src/netcam.cpp b/src/netcam.cpp index 4fad17ec..433fb078 100644 --- a/src/netcam.cpp +++ b/src/netcam.cpp @@ -18,6 +18,7 @@ */ #include "motionplus.hpp" +#include "camera.hpp" #include "conf.hpp" #include "logger.hpp" #include "util.hpp" @@ -1617,11 +1618,8 @@ void cls_netcam::set_parms () pthread_mutex_init(&mutex_pktarray, nullptr); pthread_mutex_init(&mutex_transfer, nullptr); - pthread_mutex_lock(&motapp->global_lock); - threadnbr = ++motapp->threads_running; - pthread_mutex_unlock(&motapp->global_lock); - context_null(); + threadnbr = cam->device_id; cfg_width = cam->conf->width; cfg_height = cam->conf->height; cfg_framerate = cam->conf->framerate; @@ -1901,6 +1899,7 @@ int cls_netcam::open_context() int cls_netcam::connect() { + if (open_context() < 0) { return -1; } @@ -2069,8 +2068,6 @@ void cls_netcam::handler() mythreadname_set("nc", threadnbr, camera_name.c_str()); - pthread_setspecific(tls_key_threadnr, (void *)((unsigned long)threadnbr)); - MOTPLS_LOG(NTC, TYPE_NETCAM, NO_ERRNO ,_("%s:Camera handler started") ,cameratype.c_str()); @@ -2097,11 +2094,6 @@ void cls_netcam::handler() MOTPLS_LOG(INF, TYPE_NETCAM, NO_ERRNO ,_("%s:Loop finished."),cameratype.c_str()); - /* Our thread is finished - decrement app's thread count. */ - pthread_mutex_lock(&motapp->global_lock); - motapp->threads_running--; - pthread_mutex_unlock(&motapp->global_lock); - MOTPLS_LOG(INF, TYPE_NETCAM, NO_ERRNO ,_("%s:Exiting"),cameratype.c_str()); handler_finished = true; @@ -2123,6 +2115,7 @@ void cls_netcam::start_handler() */ wait_counter = 60; while (wait_counter > 0) { + pthread_mutex_lock(&mutex); if (img_latest->ptr != nullptr ) { wait_counter = -1; @@ -2160,9 +2153,6 @@ void cls_netcam::shutdown() ,_("%s:No response from handler thread.") ,cameratype.c_str()); pthread_kill(net_thread.native_handle(), SIGVTALRM); - pthread_mutex_lock(&motapp->global_lock); - motapp->threads_running--; - pthread_mutex_unlock(&motapp->global_lock); } context_close(); @@ -2223,7 +2213,7 @@ int cls_netcam::next(ctx_image_data *img_data) return CAPTURE_SUCCESS; } -cls_netcam::cls_netcam(ctx_dev *p_cam, bool p_is_high) +cls_netcam::cls_netcam(cls_camera *p_cam, bool p_is_high) { int retcd; diff --git a/src/netcam.hpp b/src/netcam.hpp index 3b73743f..74c971f7 100644 --- a/src/netcam.hpp +++ b/src/netcam.hpp @@ -72,7 +72,7 @@ struct ctx_filelist_item { class cls_netcam { public: - cls_netcam(ctx_dev *p_cam, bool p_is_high); + cls_netcam(cls_camera *p_cam, bool p_is_high); ~cls_netcam(); int next(ctx_image_data *img_data); @@ -100,7 +100,7 @@ class cls_netcam { private: - ctx_dev *cam; + cls_camera *cam; AVFormatContext *format_context; /* Main format context for the camera */ AVCodecContext *codec_context; /* Codec being sent from the camera */ diff --git a/src/picture.cpp b/src/picture.cpp index e4d3c052..7b2319c0 100644 --- a/src/picture.cpp +++ b/src/picture.cpp @@ -16,6 +16,7 @@ * */ #include "motionplus.hpp" +#include "camera.hpp" #include "conf.hpp" #include "logger.hpp" #include "util.hpp" @@ -62,9 +63,9 @@ void cls_picture::process_norm() , cfg_picture_type); cam->filetype = FTYPE_IMAGE; if ((cam->imgs.size_high > 0) && (cam->movie_passthrough == false)) { - cam->picture->save_norm(filename, cam->current_image->image_high); + save_norm(filename, cam->current_image->image_high); } else { - cam->picture->save_norm(filename,cam->current_image->image_norm); + save_norm(filename,cam->current_image->image_norm); } on_picture_save_command(filename); cam->motapp->dbse->exec(cam, filename, "pic_save"); @@ -78,14 +79,14 @@ void cls_picture::process_motion() if (cfg_picture_output_motion == "on") { picname(filename,"%s/%sm.%s", cfg_picture_filename, cfg_picture_type); cam->filetype = FTYPE_IMAGE_MOTION; - cam->picture->save_norm(filename, cam->imgs.image_motion.image_norm); + save_norm(filename, cam->imgs.image_motion.image_norm); on_picture_save_command(filename); cam->motapp->dbse->exec(cam, filename, "pic_save"); } else if (cfg_picture_output_motion == "roi") { picname(filename,"%s/%sr.%s", cfg_picture_filename, cfg_picture_type); cam->filetype = FTYPE_IMAGE_ROI; - cam->picture->save_roi(filename, cam->current_image->image_norm); + save_roi(filename, cam->current_image->image_norm); on_picture_save_command(filename); cam->motapp->dbse->exec(cam, filename, "pic_save"); } @@ -108,9 +109,9 @@ void cls_picture::process_snapshot() , cfg_picture_type); cam->filetype = FTYPE_IMAGE_SNAPSHOT; if ((cam->imgs.size_high > 0) && (cam->movie_passthrough == false)) { - cam->picture->save_norm(filename, cam->current_image->image_high); + save_norm(filename, cam->current_image->image_high); } else { - cam->picture->save_norm(filename, cam->current_image->image_norm); + save_norm(filename, cam->current_image->image_norm); } on_picture_save_command(filename); cam->motapp->dbse->exec(cam, filename, "pic_save"); @@ -132,15 +133,15 @@ void cls_picture::process_snapshot() remove(filename); cam->filetype = FTYPE_IMAGE_SNAPSHOT; if ((cam->imgs.size_high > 0) && (cam->movie_passthrough == false)) { - cam->picture->save_norm(filename, cam->current_image->image_high); + save_norm(filename, cam->current_image->image_high); } else { - cam->picture->save_norm(filename, cam->current_image->image_norm); + save_norm(filename, cam->current_image->image_norm); } on_picture_save_command(filename); cam->motapp->dbse->exec(cam, filename, "pic_save"); } - cam->snapshot = 0; + cam->action_snapshot = false; } void cls_picture::process_preview() @@ -161,9 +162,9 @@ void cls_picture::process_preview() cam->filetype = FTYPE_IMAGE; if ((cam->imgs.size_high > 0) && (cam->movie_passthrough == false)) { - cam->picture->save_norm(filename, cam->imgs.image_preview.image_high); + save_norm(filename, cam->imgs.image_preview.image_high); } else { - cam->picture->save_norm(filename, cam->imgs.image_preview.image_norm); + save_norm(filename, cam->imgs.image_preview.image_norm); } on_picture_save_command(filename); cam->motapp->dbse->exec(cam, filename, "pic_save"); @@ -439,20 +440,9 @@ void cls_picture::save_norm(char *file, u_char *image) picture = myfopen(file, "wbe"); if (!picture) { - /* Report to syslog - suggest solution if the problem is access rights to target dir. */ - if (errno == EACCES) { - MOTPLS_LOG(ERR, TYPE_ALL, SHOW_ERRNO - ,_("Can't write picture to file %s - check access rights to target directory\n" - "Thread is going to finish due to this fatal error"), file); - cam->finish_dev = true; - cam->restart_dev = false; - return; - } else { - /* If target dir is temporarily unavailable we may survive. */ - MOTPLS_LOG(ERR, TYPE_ALL, SHOW_ERRNO - ,_("Can't write picture to file %s"), file); - return; - } + MOTPLS_LOG(ERR, TYPE_ALL, SHOW_ERRNO + ,_("Can't write picture to file %s"), file); + return; } pic_write(picture, image); @@ -854,7 +844,7 @@ void cls_picture::init_cfg() cfg_picture_output = cam->conf->picture_output; } -cls_picture::cls_picture(ctx_dev *p_cam) +cls_picture::cls_picture(cls_camera *p_cam) { cam = p_cam; init_cfg(); diff --git a/src/picture.hpp b/src/picture.hpp index b54451c2..334ad0b8 100644 --- a/src/picture.hpp +++ b/src/picture.hpp @@ -26,7 +26,7 @@ class cls_picture { public: - cls_picture(ctx_dev *p_cam); + cls_picture(cls_camera *p_cam); ~cls_picture(); int put_memory(u_char* img_dst @@ -39,7 +39,7 @@ class cls_picture { void process_preview(); private: - ctx_dev *cam; + cls_camera *cam; int cfg_w; int cfg_h; diff --git a/src/rotate.cpp b/src/rotate.cpp index 94bd615b..843371f3 100644 --- a/src/rotate.cpp +++ b/src/rotate.cpp @@ -16,6 +16,7 @@ * */ #include "motionplus.hpp" +#include "camera.hpp" #include "conf.hpp" #include "logger.hpp" #include "util.hpp" @@ -213,7 +214,7 @@ void cls_rotate::process(ctx_image_data *img_data) return; } -cls_rotate::cls_rotate(ctx_dev *p_cam) +cls_rotate::cls_rotate(cls_camera *p_cam) { cam = p_cam; int size_norm, size_high; diff --git a/src/rotate.hpp b/src/rotate.hpp index 63c910a1..c90f38d0 100644 --- a/src/rotate.hpp +++ b/src/rotate.hpp @@ -20,13 +20,13 @@ class cls_rotate { public: - cls_rotate(ctx_dev *p_cam); + cls_rotate(cls_camera *p_cam); ~cls_rotate(); void process(ctx_image_data *img_data); private: - ctx_dev *cam; + cls_camera *cam; u_char *buffer_norm; /* Temp low res buffer for 90 and 270 degrees rotation */ u_char *buffer_high; /* Temp high res buffer for 90 and 270 degrees rotation */ diff --git a/src/sound.cpp b/src/sound.cpp index 7541a1a8..4ff8533b 100644 --- a/src/sound.cpp +++ b/src/sound.cpp @@ -860,10 +860,6 @@ void cls_sound::check_levels() void cls_sound::handler() { - pthread_mutex_lock(&motapp->global_lock); - motapp->threads_running++; - pthread_mutex_unlock(&motapp->global_lock); - device_status = STATUS_INIT; handler_finished = false; handler_stop = false; @@ -879,10 +875,6 @@ void cls_sound::handler() cleanup(); - pthread_mutex_lock(&motapp->global_lock); - motapp->threads_running--; - pthread_mutex_unlock(&motapp->global_lock); - MOTPLS_LOG(NTC, TYPE_ALL, NO_ERRNO, _("Sound exiting")); handler_finished = true; @@ -916,9 +908,6 @@ void cls_sound::stop() MOTPLS_LOG(ERR, TYPE_ALL, NO_ERRNO ,_("Shutdown of sound frequency detection failed")); pthread_kill(handler_thread.native_handle(), SIGVTALRM); - pthread_mutex_lock(&motapp->global_lock); - motapp->threads_running--; - pthread_mutex_unlock(&motapp->global_lock); } } @@ -928,6 +917,7 @@ cls_sound::cls_sound(ctx_motapp *p_motapp) { motapp = p_motapp; handler_finished = true; + handler_stop = true; restart = false; } diff --git a/src/util.cpp b/src/util.cpp index 24371ac5..29a2783a 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -18,6 +18,7 @@ */ #include "motionplus.hpp" +#include "camera.hpp" #include "conf.hpp" #include "util.hpp" #include "logger.hpp" @@ -239,7 +240,7 @@ int myfclose(FILE* fh) return rval; } -static void mystrftime_long (const ctx_dev *cam, +static void mystrftime_long (const cls_camera *cam, int width, const char *word, int l, char *out) { @@ -353,7 +354,7 @@ void mystrftime(cls_sound *snd, std::string &dst, std::string fmt) dst.assign(tmp); } -size_t mystrftime_base(ctx_dev *cam, char *s, size_t max +size_t mystrftime_base(cls_camera *cam, char *s, size_t max , const char *userformat, const char *filename) { char formatstring[PATH_MAX] = ""; @@ -528,13 +529,13 @@ size_t mystrftime_base(ctx_dev *cam, char *s, size_t max return strftime(s, max, format, ×tamp_tm); } -void mystrftime(ctx_dev *cam, char *s, size_t mx_sz +void mystrftime(cls_camera *cam, char *s, size_t mx_sz , const char *usrfmt, const char *fname) { mystrftime_base(cam, s, mx_sz, usrfmt,fname); } -void mystrftime(ctx_dev *cam, std::string &rslt +void mystrftime(cls_camera *cam, std::string &rslt , std::string usrfmt, std::string fname) { char tmp[PATH_MAX] = ""; @@ -575,7 +576,7 @@ void mythreadname_set(const char *abbr, int threadnbr, const char *threadname) void mythreadname_get(std::string &threadname) { #if ((!defined(BSD) && HAVE_PTHREAD_GETNAME_NP) || defined(__APPLE__)) - char currname[16]; + char currname[32]; pthread_getname_np(pthread_self(), currname, sizeof(currname)); threadname = currname; #else @@ -586,7 +587,7 @@ void mythreadname_get(std::string &threadname) void mythreadname_get(char *threadname) { #if ((!defined(BSD) && HAVE_PTHREAD_GETNAME_NP) || defined(__APPLE__)) - char currname[16]; + char currname[32]; pthread_getname_np(pthread_self(), currname, sizeof(currname)); snprintf(threadname, sizeof(currname), "%s",currname); #else @@ -710,7 +711,7 @@ AVPacket *mypacket_alloc(AVPacket *pkt) } -void util_exec_command(ctx_dev *cam, const char *command, const char *filename) +void util_exec_command(cls_camera *cam, const char *command, const char *filename) { char stamp[PATH_MAX]; int pid; diff --git a/src/util.hpp b/src/util.hpp index d0ebda33..a57cb93a 100644 --- a/src/util.hpp +++ b/src/util.hpp @@ -83,12 +83,12 @@ int mycreate_path(const char *path); FILE *myfopen(const char *path, const char *mode); int myfclose(FILE *fh); - void mystrftime(ctx_dev *cam, char *s, size_t mx_sz + void mystrftime(cls_camera *cam, char *s, size_t mx_sz , const char *usrfmt, const char *fname); - void mystrftime(ctx_dev *cam, std::string &rslt + void mystrftime(cls_camera *cam, std::string &rslt , std::string usrfmt, std::string fname); void mystrftime(cls_sound *snd, std::string &dst, std::string fmt); - void util_exec_command(ctx_dev *cam, const char *command, const char *filename); + void util_exec_command(cls_camera *cam, const char *command, const char *filename); void util_exec_command(cls_sound *snd, std::string cmd); void mythreadname_set(const char *abbr, int threadnbr, const char *threadname); diff --git a/src/video_convert.cpp b/src/video_convert.cpp index 3907c0d6..bee0203c 100644 --- a/src/video_convert.cpp +++ b/src/video_convert.cpp @@ -17,6 +17,7 @@ */ #include "motionplus.hpp" +#include "camera.hpp" #include "logger.hpp" #include "util.hpp" #include "jpegutils.hpp" @@ -595,7 +596,7 @@ int cls_convert::process(u_char *img_dst, u_char *img_src, int clen) } -cls_convert::cls_convert(ctx_dev *p_cam, int p_pix, int p_w, int p_h) +cls_convert::cls_convert(cls_camera *p_cam, int p_pix, int p_w, int p_h) { cam = p_cam; width = p_w; diff --git a/src/video_convert.hpp b/src/video_convert.hpp index e57dde37..506787d1 100644 --- a/src/video_convert.hpp +++ b/src/video_convert.hpp @@ -27,12 +27,12 @@ typedef struct { class cls_convert { public: - cls_convert(ctx_dev *p_cam, int p_pix, int p_w, int p_h); + cls_convert(cls_camera *p_cam, int p_pix, int p_w, int p_h); ~cls_convert(); int process(u_char *img_dest, u_char *img_src, int clen); private: - ctx_dev *cam; + cls_camera *cam; int width; int height; diff --git a/src/video_loopback.cpp b/src/video_loopback.cpp index f7e46975..9c580f99 100644 --- a/src/video_loopback.cpp +++ b/src/video_loopback.cpp @@ -16,6 +16,7 @@ * */ #include "motionplus.hpp" +#include "camera.hpp" #include "conf.hpp" #include "logger.hpp" #include "util.hpp" @@ -227,7 +228,7 @@ int vlp_startpipe(const char *dev_name, int width, int height) #endif /* HAVE_V4L2 && !BSD */ -void vlp_putpipe(ctx_dev *cam) +void vlp_putpipe(cls_camera *cam) { #if (defined(HAVE_V4L2)) && (!defined(BSD)) ssize_t retcd; @@ -255,7 +256,7 @@ void vlp_putpipe(ctx_dev *cam) #endif } -void vlp_init(ctx_dev *cam) +void vlp_init(cls_camera *cam) { #if defined(HAVE_V4L2) && !defined(BSD) /* open video loopback devices if enabled */ diff --git a/src/video_loopback.hpp b/src/video_loopback.hpp index 40ebe7fa..01d93aeb 100644 --- a/src/video_loopback.hpp +++ b/src/video_loopback.hpp @@ -17,6 +17,6 @@ */ #ifndef _INCLUDE_VIDEO_LOOPBACK_HPP_ #define _INCLUDE_VIDEO_LOOPBACK_HPP_ - void vlp_putpipe(ctx_dev *cam); - void vlp_init(ctx_dev *cam); + void vlp_putpipe(cls_camera *cam); + void vlp_init(cls_camera *cam); #endif /* _INCLUDE_VIDEO_LOOPBACK_HPP_ */ diff --git a/src/video_v4l2.cpp b/src/video_v4l2.cpp index 14677f11..78d5867f 100644 --- a/src/video_v4l2.cpp +++ b/src/video_v4l2.cpp @@ -17,6 +17,7 @@ */ #include "motionplus.hpp" +#include "camera.hpp" #include "conf.hpp" #include "logger.hpp" #include "util.hpp" @@ -82,7 +83,7 @@ int cls_v4l2cam::xioctl(unsigned long request, void *arg) do { retcd = ioctl(fd_device, request, arg); - } while (-1 == retcd && EINTR == errno && !finish); + } while (-1 == retcd && EINTR == errno); return retcd; } @@ -895,7 +896,6 @@ void cls_v4l2cam::init_vars() { buffer_count= 0; pframe = -1; - finish = cam->finish_dev; buffers = nullptr; convert = nullptr; @@ -1173,7 +1173,7 @@ int cls_v4l2cam::next(ctx_image_data *img_data) #endif // HAVE_V4L2 } -cls_v4l2cam::cls_v4l2cam(ctx_dev *p_cam) +cls_v4l2cam::cls_v4l2cam(cls_camera *p_cam) { cam = p_cam; #ifdef HAVE_V4L2 diff --git a/src/video_v4l2.hpp b/src/video_v4l2.hpp index 496a2917..eb0a0b91 100644 --- a/src/video_v4l2.hpp +++ b/src/video_v4l2.hpp @@ -52,13 +52,13 @@ typedef vec_palette::iterator it_palette; class cls_v4l2cam { public: - cls_v4l2cam(ctx_dev *p_cam); + cls_v4l2cam(cls_camera *p_cam); ~cls_v4l2cam(); int next(ctx_image_data *img_data); private: - ctx_dev *cam; + cls_camera *cam; cls_convert *convert; /* Isolated variables from user config*/ @@ -80,7 +80,6 @@ class cls_v4l2cam { vec_palette palette; int pframe; - volatile bool finish; #ifdef HAVE_V4L2 struct v4l2_capability vidcap; diff --git a/src/webu.cpp b/src/webu.cpp index fa1bbec6..e0525a7f 100644 --- a/src/webu.cpp +++ b/src/webu.cpp @@ -17,6 +17,7 @@ */ #include "motionplus.hpp" +#include "camera.hpp" #include "conf.hpp" #include "logger.hpp" #include "util.hpp" diff --git a/src/webu_ans.cpp b/src/webu_ans.cpp index 34bf92c2..cd3e1a86 100644 --- a/src/webu_ans.cpp +++ b/src/webu_ans.cpp @@ -17,6 +17,7 @@ */ #include "motionplus.hpp" +#include "camera.hpp" #include "conf.hpp" #include "logger.hpp" #include "util.hpp" @@ -651,13 +652,8 @@ mhdrslt cls_webu_ans::answer_main(struct MHD_Connection *p_connection return MHD_YES; } - if (app->finish_all) { - MOTPLS_LOG(NTC, TYPE_STREAM, NO_ERRNO ,_("Shutting down camera")); - return MHD_NO; - } - if (cam != NULL) { - if (cam->finish_dev) { + if (cam->handler_stop) { MOTPLS_LOG(NTC, TYPE_STREAM, NO_ERRNO ,_("Shutting down camera")); return MHD_NO; } @@ -762,7 +758,7 @@ cls_webu_ans::cls_webu_ans(ctx_motapp *p_motapp, const char *uri) void cls_webu_ans::deinit_counter() { ctx_stream_data *strm; - ctx_dev *p_cam; + cls_camera *p_cam; int indx, cam_max, cam_min; if (cnct_type < WEBUI_CNCT_JPG_MIN) { diff --git a/src/webu_ans.hpp b/src/webu_ans.hpp index fb4f8260..f2001a7a 100644 --- a/src/webu_ans.hpp +++ b/src/webu_ans.hpp @@ -31,7 +31,7 @@ ctx_motapp *app; cls_webu *webu; - ctx_dev *cam; + cls_camera *cam; struct MHD_Connection *connection; diff --git a/src/webu_common.cpp b/src/webu_common.cpp index 7ea60bde..86ff576d 100644 --- a/src/webu_common.cpp +++ b/src/webu_common.cpp @@ -17,6 +17,7 @@ */ #include "motionplus.hpp" +#include "camera.hpp" #include "conf.hpp" #include "logger.hpp" #include "util.hpp" @@ -39,7 +40,7 @@ bool cls_webu_common::check_finish() return true; } if (webua->cam != NULL) { - if ((webua->cam->finish_dev == true) || + if ((webua->cam->handler_stop == true) || (webua->cam->passflag == false)) { resp_used = 0; return true; @@ -94,7 +95,7 @@ void cls_webu_common::delay() clock_gettime(CLOCK_MONOTONIC, &time_last); } -void cls_webu_common::img_sizes(ctx_dev *p_cam, int &img_w, int &img_h) +void cls_webu_common::img_sizes(cls_camera *p_cam, int &img_w, int &img_h) { if (((webua->cnct_type == WEBUI_CNCT_JPG_SUB) || (webua->cnct_type == WEBUI_CNCT_TS_SUB)) && @@ -124,7 +125,7 @@ void cls_webu_common::img_sizes(ctx_dev *p_cam, int &img_w, int &img_h) } } -void cls_webu_common::img_resize(ctx_dev *p_cam +void cls_webu_common::img_resize(cls_camera *p_cam , uint8_t *src, uint8_t *dst, int dst_w, int dst_h) { int retcd, img_sz, src_h, src_w; @@ -242,7 +243,7 @@ void cls_webu_common::all_getimg() unsigned char *dst_img, *src_img; ctx_stream_data *strm; ctx_all_sizes *all_sz; - ctx_dev *p_cam; + cls_camera *p_cam; memset(resp_image, '\0', resp_size); @@ -367,7 +368,7 @@ void cls_webu_common::all_sizes() int chk_sz, chk_w, mx_col, mx_row; int mx_h, mx_w, img_h, img_w; bool dflt_scale; - ctx_dev *p_cam; + cls_camera *p_cam; if (app->all_sizes->reset == false) { return; diff --git a/src/webu_common.hpp b/src/webu_common.hpp index b46db21a..e49b5062 100644 --- a/src/webu_common.hpp +++ b/src/webu_common.hpp @@ -43,8 +43,8 @@ cls_webu *webu; cls_webu_ans *webua; - void img_sizes(ctx_dev *cam, int &img_w, int &img_h); - void img_resize(ctx_dev *cam + void img_sizes(cls_camera *cam, int &img_w, int &img_h); + void img_resize(cls_camera *cam , uint8_t *src, uint8_t *dst, int dst_w, int dst_h); }; diff --git a/src/webu_file.cpp b/src/webu_file.cpp index 193ce7c1..d29aebd5 100644 --- a/src/webu_file.cpp +++ b/src/webu_file.cpp @@ -17,6 +17,7 @@ */ #include "motionplus.hpp" +#include "camera.hpp" #include "conf.hpp" #include "logger.hpp" #include "util.hpp" diff --git a/src/webu_getimg.cpp b/src/webu_getimg.cpp index fc002014..467647f4 100644 --- a/src/webu_getimg.cpp +++ b/src/webu_getimg.cpp @@ -20,14 +20,15 @@ #include "conf.hpp" #include "logger.hpp" #include "util.hpp" +#include "camera.hpp" #include "picture.hpp" -#include "webu_getimg.hpp" #include "alg_sec.hpp" +#include "webu_getimg.hpp" /* NOTE: These run on the camera thread. */ /* Initial the stream context items for the camera */ -void webu_getimg_init(ctx_dev *cam) +void webu_getimg_init(cls_camera *cam) { pthread_mutex_init(&cam->stream.mutex, NULL); @@ -76,7 +77,7 @@ void webu_getimg_init(ctx_dev *cam) } /* Free the stream buffers and mutex for shutdown */ -void webu_getimg_deinit(ctx_dev *cam) +void webu_getimg_deinit(cls_camera *cam) { /* NOTE: This runs on the camera thread. */ myfree(cam->imgs.image_substream); @@ -100,7 +101,7 @@ void webu_getimg_deinit(ctx_dev *cam) } /* Get a normal image from the motion loop and compress it*/ -static void webu_getimg_norm(ctx_dev *cam) +static void webu_getimg_norm(cls_camera *cam) { if ((cam->stream.norm.jpg_cnct == 0) && (cam->stream.norm.ts_cnct == 0) && @@ -135,7 +136,7 @@ static void webu_getimg_norm(ctx_dev *cam) } /* Get a substream image from the motion loop and compress it*/ -static void webu_getimg_sub(ctx_dev *cam) +static void webu_getimg_sub(cls_camera *cam) { int subsize; @@ -209,7 +210,7 @@ static void webu_getimg_sub(ctx_dev *cam) } /* Get a motion image from the motion loop and compress it*/ -static void webu_getimg_motion(ctx_dev *cam) +static void webu_getimg_motion(cls_camera *cam) { if ((cam->stream.motion.jpg_cnct == 0) && (cam->stream.motion.ts_cnct == 0) && @@ -243,7 +244,7 @@ static void webu_getimg_motion(ctx_dev *cam) } /* Get a source image from the motion loop and compress it*/ -static void webu_getimg_source(ctx_dev *cam) +static void webu_getimg_source(cls_camera *cam) { if ((cam->stream.source.jpg_cnct == 0) && (cam->stream.source.ts_cnct == 0) && @@ -277,7 +278,7 @@ static void webu_getimg_source(ctx_dev *cam) } /* Get a secondary image from the motion loop and compress it*/ -static void webu_getimg_secondary(ctx_dev *cam) +static void webu_getimg_secondary(cls_camera *cam) { if ((cam->stream.secondary.jpg_cnct == 0) && (cam->stream.secondary.ts_cnct == 0) && @@ -314,7 +315,7 @@ static void webu_getimg_secondary(ctx_dev *cam) } /* Get image from the motion loop and compress it*/ -void webu_getimg_main(ctx_dev *cam) +void webu_getimg_main(cls_camera *cam) { /*This is on the camera thread */ pthread_mutex_lock(&cam->stream.mutex); diff --git a/src/webu_getimg.hpp b/src/webu_getimg.hpp index b1777c5a..b0fbca1c 100644 --- a/src/webu_getimg.hpp +++ b/src/webu_getimg.hpp @@ -19,8 +19,8 @@ #ifndef _INCLUDE_WEBU_GETIMG_HPP_ #define _INCLUDE_WEBU_GETIMG_HPP_ - void webu_getimg_init(ctx_dev *cam); - void webu_getimg_deinit(ctx_dev *cam); - void webu_getimg_main(ctx_dev *cam); + void webu_getimg_init(cls_camera *cam); + void webu_getimg_deinit(cls_camera *cam); + void webu_getimg_main(cls_camera *cam); #endif diff --git a/src/webu_html.cpp b/src/webu_html.cpp index 0a65047d..0323db5c 100644 --- a/src/webu_html.cpp +++ b/src/webu_html.cpp @@ -17,6 +17,7 @@ */ #include "motionplus.hpp" +#include "camera.hpp" #include "conf.hpp" #include "logger.hpp" #include "util.hpp" diff --git a/src/webu_json.cpp b/src/webu_json.cpp index 5a0b6630..ab0e608d 100644 --- a/src/webu_json.cpp +++ b/src/webu_json.cpp @@ -17,6 +17,7 @@ */ #include "motionplus.hpp" +#include "camera.hpp" #include "conf.hpp" #include "logger.hpp" #include "util.hpp" @@ -173,7 +174,7 @@ void cls_webu_json::cameras_list() int indx_cam; std::string response; std::string strid; - ctx_dev *cam; + cls_camera *cam; webua->resp_page += "{\"count\" : " + std::to_string(app->cam_cnt); @@ -351,7 +352,7 @@ void cls_webu_json::status_vars(int indx_cam) char buf[32]; struct tm timestamp_tm; struct timespec curr_ts; - ctx_dev *cam; + cls_camera *cam; cam = app->cam_list[indx_cam]; diff --git a/src/webu_mpegts.cpp b/src/webu_mpegts.cpp index 48ef4d13..09a4da40 100644 --- a/src/webu_mpegts.cpp +++ b/src/webu_mpegts.cpp @@ -17,6 +17,7 @@ */ #include "motionplus.hpp" +#include "camera.hpp" #include "conf.hpp" #include "logger.hpp" #include "util.hpp" diff --git a/src/webu_post.cpp b/src/webu_post.cpp index 4f1d60b8..bfa53346 100644 --- a/src/webu_post.cpp +++ b/src/webu_post.cpp @@ -17,6 +17,7 @@ */ #include "motionplus.hpp" +#include "camera.hpp" #include "conf.hpp" #include "logger.hpp" #include "util.hpp" @@ -243,10 +244,10 @@ void cls_webu_post::action_snapshot() if (webua->device_id == 0) { for (indx=0; indxcam_cnt; indx++) { - app->cam_list[indx]->snapshot = true; + app->cam_list[indx]->action_snapshot = true; } } else { - app->cam_list[webua->camindx]->snapshot = true; + app->cam_list[webua->camindx]->action_snapshot = true; } } @@ -327,15 +328,13 @@ void cls_webu_post::action_restart() if (webua->device_id == 0) { MOTPLS_LOG(NTC, TYPE_STREAM, NO_ERRNO, _("Restarting all cameras")); for (indx=0; indxcam_cnt; indx++) { - app->cam_list[indx]->restart_dev = true; - app->cam_list[indx]->finish_dev = true; + app->cam_list[indx]->restart = true; } } else { MOTPLS_LOG(NTC, TYPE_STREAM, NO_ERRNO , _("Restarting camera %d") , app->cam_list[webua->camindx]->device_id); - app->cam_list[webua->camindx]->restart_dev = true; - app->cam_list[webua->camindx]->finish_dev = true; + app->cam_list[webua->camindx]->restart = true; } } @@ -361,19 +360,19 @@ void cls_webu_post::action_stop() MOTPLS_LOG(NTC, TYPE_STREAM, NO_ERRNO , _("Stopping cam %d") , app->cam_list[indx]->device_id); - app->cam_list[indx]->restart_dev = false; + app->cam_list[indx]->restart = false; app->cam_list[indx]->event_stop = true; app->cam_list[indx]->event_user = false; - app->cam_list[indx]->finish_dev = true; + app->cam_list[indx]->handler_stop = true; } } else { MOTPLS_LOG(NTC, TYPE_STREAM, NO_ERRNO , _("Stopping cam %d") , app->cam_list[webua->camindx]->device_id); - app->cam_list[webua->camindx]->restart_dev = false; + app->cam_list[webua->camindx]->restart = false; app->cam_list[webua->camindx]->event_stop = true; app->cam_list[webua->camindx]->event_user = false; - app->cam_list[webua->camindx]->finish_dev = true; + app->cam_list[webua->camindx]->handler_stop = true; } } @@ -382,7 +381,7 @@ void cls_webu_post::action_stop() void cls_webu_post::action_user() { int indx, indx2; - ctx_dev *cam; + cls_camera *cam; std::string tmp; p_lst *lst = &webu->wb_actions->params_array; p_it it; @@ -538,7 +537,7 @@ void cls_webu_post::config() /* Process the ptz action */ void cls_webu_post::ptz() { - ctx_dev *cam; + cls_camera *cam; p_lst *lst = &webu->wb_actions->params_array; p_it it; diff --git a/src/webu_stream.cpp b/src/webu_stream.cpp index 0d03857f..b12529f9 100644 --- a/src/webu_stream.cpp +++ b/src/webu_stream.cpp @@ -17,6 +17,7 @@ */ #include "motionplus.hpp" +#include "camera.hpp" #include "conf.hpp" #include "logger.hpp" #include "util.hpp" @@ -39,7 +40,7 @@ static ssize_t webu_mjpeg_response (void *cls, uint64_t pos, char *buf, size_t m bool cls_webu_stream::all_ready() { int indx, indx1; - ctx_dev *p_cam; + cls_camera *p_cam; for (indx=0; indxcam_cnt; indx++) { p_cam = app->cam_list[indx]; @@ -511,7 +512,7 @@ mhdrslt cls_webu_stream::main() } if (webua->cam != NULL) { - if ((webua->cam->passflag == false) || (webua->cam->finish_dev)) { + if ((webua->cam->passflag == false) || (webua->cam->handler_stop)) { return MHD_NO; } }