diff --git a/src/conf.cpp b/src/conf.cpp index bc0dd843..892a0928 100644 --- a/src/conf.cpp +++ b/src/conf.cpp @@ -3068,6 +3068,7 @@ static void conf_edit_cat05(struct ctx_cam *cam, std::string parm_nm, std::strin static void conf_edit_dflt_app(struct ctx_motapp *motapp) { std::string dflt = ""; + motapp->parms_changed = false; conf_edit_conf_filename(motapp, dflt, PARM_ACT_DFLT); conf_edit_log_file(motapp, dflt, PARM_ACT_DFLT); conf_edit_log_type(motapp, dflt, PARM_ACT_DFLT); @@ -3086,6 +3087,8 @@ static void conf_edit_dflt_cam(struct ctx_cam *cam) { enum PARM_CAT pcat; std::string dflt = ""; + cam->parms_changed = false; + indx = 0; while (config_parms[indx].parm_name != "") { pcat = config_parms[indx].parm_cat; @@ -3117,8 +3120,10 @@ int conf_edit_set_active(struct ctx_motapp *motapp, int threadnbr if (parm_nm == config_parms[indx].parm_name) { pcat = config_parms[indx].parm_cat; if ((pcat == PARM_CAT_00) && (threadnbr == -1)) { + motapp->parms_changed = true; conf_edit_cat00(motapp, parm_nm, parm_val, PARM_ACT_SET); } else if ((config_parms[indx].parm_cat != PARM_CAT_00) && (threadnbr != -1)) { + motapp->cam_list[threadnbr]->parms_changed = true; if (pcat == PARM_CAT_01) { conf_edit_cat01(motapp->cam_list[threadnbr], parm_nm, parm_val, PARM_ACT_SET); } else if (pcat == PARM_CAT_02) { diff --git a/src/motion.hpp b/src/motion.hpp index 4f7655e3..2b34430e 100644 --- a/src/motion.hpp +++ b/src/motion.hpp @@ -363,6 +363,8 @@ struct ctx_cam { int previous_diffs, previous_location_x, previous_location_y; unsigned int passflag; //only purpose is to flag first frame vs all others..... + pthread_mutex_t parms_lock; + int parms_changed; /*bool indicating if the parms have changed */ }; @@ -395,6 +397,7 @@ struct ctx_motapp { struct MHD_Daemon *webcontrol_daemon; char webcontrol_digest_rand[8]; + int parms_changed; /*bool indicating if the parms have changed */ }; diff --git a/src/motion_loop.cpp b/src/motion_loop.cpp index 666553a4..301baeb9 100644 --- a/src/motion_loop.cpp +++ b/src/motion_loop.cpp @@ -1300,7 +1300,7 @@ static void mlp_loopback(struct ctx_cam *cam){ static void mlp_parmsupdate(struct ctx_cam *cam){ /* Check for some config parameter changes but only every second */ - if (cam->shots != 0) return; + if ((cam->shots != 0) || (cam->parms_changed = false)) return; draw_init_scale(cam); /* Initialize and validate text_scale */ @@ -1360,6 +1360,18 @@ static void mlp_parmsupdate(struct ctx_cam *cam){ cam->noise = cam->conf->noise_level; } + if (cam->netcam != NULL){ + pthread_mutex_lock(&cam->netcam->mutex_parms); + cam->netcam->framerate = cam->conf->framerate; + pthread_mutex_unlock(&cam->netcam->mutex_parms); + } + + if (cam->netcam_high != NULL){ + pthread_mutex_lock(&cam->netcam_high->mutex_parms); + cam->netcam_high->framerate = cam->conf->framerate; + pthread_mutex_unlock(&cam->netcam_high->mutex_parms); + } + } static void mlp_frametiming(struct ctx_cam *cam){ diff --git a/src/netcam.cpp b/src/netcam.cpp index c40e0673..53530b36 100644 --- a/src/netcam.cpp +++ b/src/netcam.cpp @@ -1176,45 +1176,49 @@ static void netcam_set_parms (struct ctx_cam *cam, struct ctx_netcam *netcam ) { MOTION_LOG(INF, TYPE_NETCAM, NO_ERRNO ,_("Setting up %s stream."),netcam->cameratype); - mycheck_passthrough(cam); /* In case it was turned on via webcontrol */ - netcam->status = NETCAM_NOTCONNECTED; - netcam->rtsp_uses_tcp =cam->conf->netcam_use_tcp; - netcam->v4l2_palette = cam->conf->v4l2_palette; - netcam->framerate = cam->conf->framerate; - netcam->src_fps = cam->conf->framerate; /* Default to conf fps */ - netcam->motapp = cam->motapp; - netcam->conf = cam->conf; - netcam->img_recv =(netcam_buff_ptr) mymalloc(sizeof(netcam_buff)); - netcam->img_recv->ptr =(char*) mymalloc(NETCAM_BUFFSIZE); - netcam->img_latest =(netcam_buff_ptr) mymalloc(sizeof(netcam_buff)); - netcam->img_latest->ptr =(char*) mymalloc(NETCAM_BUFFSIZE); - netcam->pktarray_size = 0; - netcam->pktarray_index = -1; - netcam->pktarray = NULL; - netcam->handler_finished = TRUE; - netcam->first_image = TRUE; - netcam->reconnect_count = 0; - cam->conf->camera_name.copy(netcam->camera_name,PATH_MAX); + pthread_mutex_lock(&netcam->mutex_parms); - snprintf(netcam->threadname, 15, "%s",_("Unknown")); + mycheck_passthrough(cam); /* In case it was turned on via webcontrol */ + netcam->status = NETCAM_NOTCONNECTED; + netcam->rtsp_uses_tcp =cam->conf->netcam_use_tcp; + netcam->v4l2_palette = cam->conf->v4l2_palette; + netcam->framerate = cam->conf->framerate; + netcam->src_fps = cam->conf->framerate; /* Default to conf fps */ + netcam->motapp = cam->motapp; + netcam->conf = cam->conf; + netcam->img_recv =(netcam_buff_ptr) mymalloc(sizeof(netcam_buff)); + netcam->img_recv->ptr =(char*) mymalloc(NETCAM_BUFFSIZE); + netcam->img_latest =(netcam_buff_ptr) mymalloc(sizeof(netcam_buff)); + netcam->img_latest->ptr =(char*) mymalloc(NETCAM_BUFFSIZE); + netcam->pktarray_size = 0; + netcam->pktarray_index = -1; + netcam->pktarray = NULL; + netcam->handler_finished = TRUE; + netcam->first_image = TRUE; + netcam->reconnect_count = 0; + cam->conf->camera_name.copy(netcam->camera_name,PATH_MAX); - clock_gettime(CLOCK_REALTIME, &netcam->interruptstarttime); - clock_gettime(CLOCK_REALTIME, &netcam->interruptcurrenttime); + snprintf(netcam->threadname, 15, "%s",_("Unknown")); - /* If this is the norm and we have a highres, then disable passthru on the norm */ - if ((!netcam->high_resolution) && - (cam->conf->netcam_highres != "")) { - netcam->passthrough = FALSE; - } else { - netcam->passthrough = mycheck_passthrough(cam); - } - netcam->interruptduration = 5; - netcam->interrupted = FALSE; + clock_gettime(CLOCK_REALTIME, &netcam->interruptstarttime); + clock_gettime(CLOCK_REALTIME, &netcam->interruptcurrenttime); - clock_gettime(CLOCK_REALTIME, &netcam->frame_curr_tm); - clock_gettime(CLOCK_REALTIME, &netcam->frame_prev_tm); + /* If this is the norm and we have a highres, then disable passthru on the norm */ + if ((!netcam->high_resolution) && + (cam->conf->netcam_highres != "")) { + netcam->passthrough = FALSE; + } else { + netcam->passthrough = mycheck_passthrough(cam); + } + netcam->interruptduration = 5; + netcam->interrupted = FALSE; - netcam_set_path(cam, netcam); + clock_gettime(CLOCK_REALTIME, &netcam->frame_curr_tm); + clock_gettime(CLOCK_REALTIME, &netcam->frame_prev_tm); + + netcam_set_path(cam, netcam); + + pthread_mutex_unlock(&netcam->mutex_parms); } @@ -1522,7 +1526,10 @@ static void netcam_handler_wait(struct ctx_netcam *netcam){ int framerate; long usec_maxrate, usec_delay; - framerate = netcam->conf->framerate; + pthread_mutex_lock(&netcam->mutex_parms); + framerate = netcam->framerate; + pthread_mutex_unlock(&netcam->mutex_parms); + if (framerate < 2) framerate = 2; if (mystreq(netcam->service,"file")) { @@ -1639,6 +1646,7 @@ static int netcam_start_handler(struct ctx_netcam *netcam){ pthread_mutex_init(&netcam->mutex, NULL); pthread_mutex_init(&netcam->mutex_pktarray, NULL); pthread_mutex_init(&netcam->mutex_transfer, NULL); + pthread_mutex_init(&netcam->mutex_parms,NULL); pthread_attr_init(&handler_attribute); pthread_attr_setdetachstate(&handler_attribute, PTHREAD_CREATE_DETACHED); @@ -1807,7 +1815,7 @@ void netcam_cleanup(struct ctx_cam *cam, int init_retry_flag){ * If the init_retry_flag is not set this function was * called while retrying the initial connection and there is * no camera-handler started yet and thread_running must - * not be decremented. + * not be decremented. This is called from motion_loop thread */ int wait_counter; int indx_cam, indx_max; @@ -1858,6 +1866,7 @@ void netcam_cleanup(struct ctx_cam *cam, int init_retry_flag){ pthread_mutex_destroy(&netcam->mutex); pthread_mutex_destroy(&netcam->mutex_pktarray); pthread_mutex_destroy(&netcam->mutex_transfer); + pthread_mutex_destroy(&netcam->mutex_parms); free(netcam); netcam = NULL; diff --git a/src/netcam.hpp b/src/netcam.hpp index 28523933..47dbe0d6 100644 --- a/src/netcam.hpp +++ b/src/netcam.hpp @@ -117,6 +117,7 @@ struct ctx_netcam { pthread_mutex_t mutex; /* mutex used with conditional waits */ pthread_mutex_t mutex_transfer; /* mutex used with transferring stream info for pass-through */ pthread_mutex_t mutex_pktarray; /* mutex used with the packet array */ + pthread_mutex_t mutex_parms; /* mutex used with the parms */ };