From 6f45d3c4693529fcb7c4944afdedab62d3dd063d Mon Sep 17 00:00:00 2001 From: MrDave Date: Sun, 20 Oct 2019 13:01:05 -0600 Subject: [PATCH] Add secondary detection to webstream --- src/alg_sec.cpp | 36 ++++++++++++++++++++++++-------- src/alg_sec.hpp | 1 + src/motion.hpp | 23 ++++++++++++--------- src/motion_loop.cpp | 6 ++++++ src/webu.cpp | 9 ++++++++ src/webu.hpp | 1 + src/webu_stream.cpp | 50 +++++++++++++++++++++++++++++++++++++++++---- 7 files changed, 103 insertions(+), 23 deletions(-) diff --git a/src/alg_sec.cpp b/src/alg_sec.cpp index 009067ab..99bff5d0 100644 --- a/src/alg_sec.cpp +++ b/src/alg_sec.cpp @@ -6,15 +6,17 @@ * See also the file 'COPYING'. * */ -#include "motion.hpp" -#include "util.hpp" -#include "logger.hpp" -#include "alg_sec.hpp" + #include #include #include #include +#include "motion.hpp" +#include "util.hpp" +#include "logger.hpp" +#include "alg_sec.hpp" + #ifdef HAVE_OPENCV #include "opencv2/objdetect.hpp" @@ -31,6 +33,8 @@ static void algsec_img_show(ctx_cam *cam, Mat &mat_src std::vector fltr_weights; std::string testdir; std::size_t indx0, indx1; + std::vector buff;//buffer for coding + std::vector param(2); bool isdetected; char wstr[10]; @@ -65,6 +69,13 @@ static void algsec_img_show(ctx_cam *cam, Mat &mat_src putText(mat_src, wstr, Point(r.x,r.y), FONT_HERSHEY_SIMPLEX, 1, 255, 2); } imwrite(testdir + "/detect_" + algmethod + ".jpg", mat_src); + param[0] = cv::IMWRITE_JPEG_QUALITY; + param[1] = 75; + cv::imencode(".jpg", mat_src, buff, param); + pthread_mutex_lock(&cam->algsec->mutex); + std::copy(buff.begin(), buff.end(), cam->imgs.image_secondary); + cam->imgs.size_secondary = (int)buff.size(); + pthread_mutex_unlock(&cam->algsec->mutex); } } @@ -160,6 +171,13 @@ static void algsec_detect_hog(ctx_cam *cam, ctx_algsec_model &algmdl){ ,algmdl.parms_int[0][5] ,false); + MOTION_LOG(INF, TYPE_ALL, NO_ERRNO + , _("HOG Parmeters: winstride %d,%d padding %d,%d scale %.2f theshold %d") + ,Size(algmdl.parms_int[0][2], algmdl.parms_int[0][2]) + ,Size(algmdl.parms_int[0][3], algmdl.parms_int[0][3]) + ,algmdl.parms_float[0][4] + ,algmdl.parms_int[0][5]); + algsec_img_show(cam, mat_dst, detect_pos, detect_weights, "hog" ,algmdl.parms_float[0][1]); @@ -418,11 +436,7 @@ static void *algsec_handler(void *arg) { cam->algsec->closing = false; - if (cam->conf.framerate < 2){ - interval = 1000000L / 2; - } else { - interval = 1000000L / cam->conf.framerate; - } + interval = 1000000L / cam->conf.framerate; while (!cam->algsec->closing){ if (cam->algsec->detecting){ @@ -487,6 +501,8 @@ void algsec_init(ctx_cam *cam){ cam->algsec = new ctx_algsec; + pthread_mutex_init(&cam->algsec->mutex, NULL); + algsec_load_parms(cam); retcd = algsec_load_models(cam); @@ -521,6 +537,8 @@ void algsec_deinit(ctx_cam *cam){ ,_("Graceful shutdown of secondary detector thread failed")); } + pthread_mutex_destroy(&cam->algsec->mutex); + delete cam->algsec; #else diff --git a/src/alg_sec.hpp b/src/alg_sec.hpp index df1d14dc..6053c419 100644 --- a/src/alg_sec.hpp +++ b/src/alg_sec.hpp @@ -46,6 +46,7 @@ struct ctx_algsec { unsigned char *image_norm; int width; int height; + pthread_mutex_t mutex; struct ctx_algsec_model models[3]; }; diff --git a/src/motion.hpp b/src/motion.hpp index 54830478..17daf02e 100644 --- a/src/motion.hpp +++ b/src/motion.hpp @@ -238,12 +238,13 @@ struct ctx_images { unsigned char *smartmask_final; 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_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 */ @@ -267,6 +268,7 @@ struct ctx_images { int labels_above; int labelsize_max; int largest_label; + int size_secondary; /* Size of the jpg put into image_secondary*/ }; @@ -282,10 +284,11 @@ struct ctx_stream { char digest_rand[8]; int finish; - struct ctx_stream_data norm; /* Copy of the image to use for web stream*/ - struct ctx_stream_data sub; /* Copy of the image to use for web stream*/ - struct ctx_stream_data motion; /* Copy of the image to use for web stream*/ - struct ctx_stream_data source; /* Copy of the image to use for web stream*/ + struct ctx_stream_data norm; /* Copy of the image to use for web stream*/ + struct ctx_stream_data sub; /* Copy of the image to use for web stream*/ + struct ctx_stream_data motion; /* Copy of the image to use for web stream*/ + struct ctx_stream_data source; /* Copy of the image to use for web stream*/ + struct ctx_stream_data secondary; /* Copy of the image to use for web stream*/ }; /* diff --git a/src/motion_loop.cpp b/src/motion_loop.cpp index d5a3f562..61208384 100644 --- a/src/motion_loop.cpp +++ b/src/motion_loop.cpp @@ -373,6 +373,7 @@ static void mlp_init_buffers(struct ctx_cam *cam){ cam->imgs.labelsize =(int*) mymalloc((cam->imgs.motionsize/2+1) * sizeof(*cam->imgs.labelsize)); cam->imgs.image_preview.image_norm =(unsigned char*) mymalloc(cam->imgs.size_norm); cam->imgs.common_buffer =(unsigned char*) mymalloc(3 * cam->imgs.width * cam->imgs.height); + cam->imgs.image_secondary =(unsigned char*) mymalloc(3 * cam->imgs.width * cam->imgs.height); if (cam->imgs.size_high > 0){ cam->imgs.image_preview.image_high =(unsigned char*) mymalloc(cam->imgs.size_high); } @@ -399,6 +400,7 @@ static void mlp_init_values(struct ctx_cam *cam) { cam->event_stop = FALSE; cam->passflag = FALSE; //only purpose to flag first frame + /* Make sure to default the high res to zero */ cam->imgs.width_high = 0; cam->imgs.height_high = 0; @@ -568,6 +570,9 @@ void mlp_cleanup(struct ctx_cam *cam) { free(cam->imgs.common_buffer); cam->imgs.common_buffer = NULL; + free(cam->imgs.image_secondary); + cam->imgs.image_secondary = NULL; + free(cam->imgs.image_preview.image_norm); cam->imgs.image_preview.image_norm = NULL; @@ -1084,6 +1089,7 @@ static void mlp_actions_event_stop(struct ctx_cam *cam){ if ((cam->frame_curr_ts.tv_sec - cam->lasttime >= cam->conf.event_gap) && cam->conf.event_gap > 0) { cam->event_stop = TRUE; + MOTION_LOG(NTC, TYPE_ALL, NO_ERRNO, _("222En222dddd of event %d"), cam->event_nr); } if (cam->event_stop) { diff --git a/src/webu.cpp b/src/webu.cpp index 03ff6b99..fc4cb1c7 100644 --- a/src/webu.cpp +++ b/src/webu.cpp @@ -1184,6 +1184,10 @@ static void webu_answer_strm_type(struct webui_ctx *webui) { (mystreq(webui->uri_camid,"source"))){ webui->cnct_type = WEBUI_CNCT_SOURCE; + } else if ((mystreq(webui->uri_cmd1,"secondary")) || + (mystreq(webui->uri_camid,"secondary"))){ + webui->cnct_type = WEBUI_CNCT_SECONDARY; + } else if ((mystreq(webui->uri_cmd1,"current")) || (mystreq(webui->uri_camid,"current"))){ webui->cnct_type = WEBUI_CNCT_STATIC; @@ -1462,6 +1466,11 @@ static void webu_mhd_deinit(void *cls webui->cam->stream.source.cnct_count--; pthread_mutex_unlock(&webui->cam->stream.mutex); + } else if (webui->cnct_type == WEBUI_CNCT_SECONDARY ){ + pthread_mutex_lock(&webui->cam->stream.mutex); + webui->cam->stream.secondary.cnct_count--; + pthread_mutex_unlock(&webui->cam->stream.mutex); + } else if (webui->cnct_type == WEBUI_CNCT_STATIC ){ pthread_mutex_lock(&webui->cam->stream.mutex); webui->cam->stream.norm.cnct_count--; diff --git a/src/webu.hpp b/src/webu.hpp index eb1a101c..e28ef94c 100644 --- a/src/webu.hpp +++ b/src/webu.hpp @@ -24,6 +24,7 @@ WEBUI_CNCT_MOTION = 3, WEBUI_CNCT_SOURCE = 4, WEBUI_CNCT_STATIC = 5, + WEBUI_CNCT_SECONDARY = 6, WEBUI_CNCT_UNKNOWN = 99 }; diff --git a/src/webu_stream.cpp b/src/webu_stream.cpp index 8017628d..6af3e15a 100644 --- a/src/webu_stream.cpp +++ b/src/webu_stream.cpp @@ -19,6 +19,8 @@ #include "picture.hpp" #include "webu.hpp" #include "webu_stream.hpp" +#include "alg_sec.hpp" + static void webu_stream_mjpeg_checkbuffers(struct webui_ctx *webui) { @@ -85,6 +87,9 @@ static void webu_stream_mjpeg_getimg(struct webui_ctx *webui) { } else if (webui->cnct_type == WEBUI_CNCT_SOURCE){ local_stream = &webui->cam->stream.source; + } else if (webui->cnct_type == WEBUI_CNCT_SECONDARY){ + local_stream = &webui->cam->stream.secondary; + } else { return; } @@ -246,6 +251,12 @@ static void webu_stream_cnct_count(struct webui_ctx *webui) { cnct_count = webui->cam->stream.source.cnct_count; pthread_mutex_unlock(&webui->cam->stream.mutex); + } else if (webui->cnct_type == WEBUI_CNCT_SECONDARY) { + pthread_mutex_lock(&webui->cam->stream.mutex); + webui->cam->stream.secondary.cnct_count++; + cnct_count = webui->cam->stream.secondary.cnct_count; + pthread_mutex_unlock(&webui->cam->stream.mutex); + } else { /* Stream, Static */ pthread_mutex_lock(&webui->cam->stream.mutex); @@ -363,6 +374,10 @@ void webu_stream_init(struct ctx_cam *cam){ cam->stream.source.jpeg_data = NULL; cam->stream.source.cnct_count = 0; + cam->stream.secondary.jpeg_size = 0; + cam->stream.secondary.jpeg_data = NULL; + cam->stream.secondary.cnct_count = 0; + } void webu_stream_deinit(struct ctx_cam *cam){ @@ -398,6 +413,12 @@ void webu_stream_deinit(struct ctx_cam *cam){ free(cam->stream.source.jpeg_data); cam->stream.source.jpeg_data = NULL; } + + if (cam->stream.secondary.jpeg_data != NULL){ + free(cam->stream.secondary.jpeg_data); + cam->stream.secondary.jpeg_data = NULL; + } + } static void webu_stream_getimg_norm(struct ctx_cam *cam, struct ctx_image_data *img_data){ @@ -495,14 +516,35 @@ static void webu_stream_getimg_source(struct ctx_cam *cam){ } +static void webu_stream_getimg_secondary(struct ctx_cam *cam){ + /*This is on the motion_loop thread */ + + if (cam->imgs.size_secondary>0) { + pthread_mutex_lock(&cam->algsec->mutex); + if (cam->stream.secondary.jpeg_data == NULL){ + cam->stream.secondary.jpeg_data =(unsigned char*)mymalloc(cam->imgs.size_norm); + } + memcpy(cam->stream.secondary.jpeg_data,cam->imgs.image_secondary,cam->imgs.size_secondary); + cam->stream.secondary.jpeg_size = cam->imgs.size_secondary; + pthread_mutex_unlock(&cam->algsec->mutex); + } else { + if (cam->stream.secondary.jpeg_data != NULL){ + free(cam->stream.secondary.jpeg_data); + cam->stream.secondary.jpeg_data = NULL; + } + } + +} + void webu_stream_getimg(struct ctx_cam *cam, struct ctx_image_data *img_data){ /*This is on the motion_loop thread */ pthread_mutex_lock(&cam->stream.mutex); - if (cam->stream.norm.cnct_count > 0) webu_stream_getimg_norm(cam, img_data); - if (cam->stream.sub.cnct_count > 0) webu_stream_getimg_sub(cam, img_data); - if (cam->stream.motion.cnct_count > 0) webu_stream_getimg_motion(cam); - if (cam->stream.source.cnct_count > 0) webu_stream_getimg_source(cam); + if (cam->stream.norm.cnct_count > 0) webu_stream_getimg_norm(cam, img_data); + if (cam->stream.sub.cnct_count > 0) webu_stream_getimg_sub(cam, img_data); + if (cam->stream.motion.cnct_count > 0) webu_stream_getimg_motion(cam); + if (cam->stream.source.cnct_count > 0) webu_stream_getimg_source(cam); + if (cam->stream.secondary.cnct_count > 0) webu_stream_getimg_secondary(cam); pthread_mutex_unlock(&cam->stream.mutex); }