Skip to content

Commit

Permalink
Revise lost camera processing
Browse files Browse the repository at this point in the history
  • Loading branch information
Mr-Dave committed Sep 5, 2024
1 parent eb823de commit 28e2fbe
Show file tree
Hide file tree
Showing 9 changed files with 292 additions and 146 deletions.
2 changes: 1 addition & 1 deletion src/alg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -883,7 +883,7 @@ void cls_alg::diff_standard()

void cls_alg::lightswitch()
{
if (cam->cfg->lightswitch_percent >= 1 && !cam->lost_connection) {
if (cam->cfg->lightswitch_percent >= 1) {
if (cam->current_image->diffs > (cam->imgs.motionsize * cam->cfg->lightswitch_percent / 100)) {
MOTPLS_LOG(INF, TYPE_ALL, NO_ERRNO, _("Lightswitch detected"));
if (cam->frame_skip < cam->cfg->lightswitch_frames) {
Expand Down
132 changes: 78 additions & 54 deletions src/camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,11 @@ void cls_camera::cam_start()
/* Get next image from camera */
int cls_camera::cam_next(ctx_image_data *img_data)
{
int retcd;
int retcd, imgsz;

if (device_status != STATUS_OPENED) {
return CAPTURE_FAILURE;
}

if (camera_type == CAMERA_TYPE_LIBCAM) {
retcd = libcam->next(img_data);
Expand All @@ -442,7 +446,23 @@ int cls_camera::cam_next(ctx_image_data *img_data)
} else if (camera_type == CAMERA_TYPE_V4L2) {
retcd = v4l2cam->next(img_data);
} else {
retcd = -1;
return CAPTURE_FAILURE;
}

if (retcd == CAPTURE_SUCCESS) {
imgsz = (imgs.width * imgs.height * 3) / 2;
if (imgs.size_norm != imgsz) {
MOTPLS_LOG(NTC, TYPE_ALL, NO_ERRNO,_("Resetting image buffers"));
device_status = STATUS_CLOSED;
restart = true;
return CAPTURE_FAILURE;
}
imgsz = (imgs.width_high * imgs.height_high * 3) / 2;
if (imgs.size_high != imgsz) {
device_status = STATUS_CLOSED;
restart = true;
return CAPTURE_FAILURE;
}
}

return retcd;
Expand Down Expand Up @@ -601,6 +621,8 @@ void cls_camera::init_values()
postcap = 0;
event_stop = false;
text_scale = cfg->text_scale;
connectionlosttime.tv_sec = 0;
connectionlosttime.tv_nsec = 0;
info_reset();

movie_passthrough = cfg->movie_passthrough;
Expand Down Expand Up @@ -731,8 +753,8 @@ void cls_camera::cleanup()
/* initialize everything for the loop */
void cls_camera::init()
{
if ((device_status != STATUS_INIT) &&
(restart != true)) {
if (((device_status != STATUS_INIT) && (restart != true)) ||
(handler_stop == true)) {
return;
}

Expand Down Expand Up @@ -825,6 +847,10 @@ void cls_camera::areadetect()
/* Prepare for the next iteration of loop*/
void cls_camera::prepare()
{
if ((restart == true) || (handler_stop == true)) {
return;
}

watchdog = cfg->watchdog_tmo;

frame_last_ts.tv_sec = frame_curr_ts.tv_sec;
Expand All @@ -846,11 +872,14 @@ void cls_camera::prepare()
}
}

/* reset the images */
void cls_camera::resetimages()
{
int64_t tmpsec;

if ((restart == true) || (handler_stop == true)) {
return;
}

/* ring_buffer_in is pointing to current pos, update before put in a new image */
tmpsec =current_image->imgts.tv_sec;
if (++imgs.ring_in >= imgs.ring_size) {
Expand Down Expand Up @@ -884,56 +913,21 @@ void cls_camera::resetimages()

}

/* Try to reconnect to camera */
void cls_camera::retry()
{
int size_high;

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"));

cam_start();

check_szimg();

if (imgs.width != cfg->width || imgs.height != cfg->height) {
MOTPLS_LOG(NTC, TYPE_ALL, NO_ERRNO,_("Resetting image buffers"));
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 imgs.size_high
* and the cam_start ONLY re-populates the height/width so we can check the size here.
*/
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 */
int cls_camera::capture()
{
const char *tmpin;
char tmpout[80];
int retcd;

if (device_status != STATUS_OPENED) {
retcd = cam_next(current_image);

if ((restart == true) || (handler_stop == true)) {
return 0;
}

retcd = cam_next(current_image);

if (retcd == CAPTURE_SUCCESS) {
watchdog = cfg->watchdog_tmo;
lost_connection = 0;
lost_connection = false;
connectionlosttime.tv_sec = 0;

if (missing_frame_counter >= (cfg->device_tmo * cfg->framerate)) {
Expand Down Expand Up @@ -962,7 +956,7 @@ int cls_camera::capture()
memcpy(current_image->image_norm, imgs.image_vprvcy
, (uint)imgs.size_norm);
} else {
lost_connection = 1;
lost_connection = true;
if (device_status == STATUS_OPENED) {
tmpin = "CONNECTION TO CAMERA LOST\\nSINCE %Y-%m-%d %T";
} else {
Expand All @@ -986,11 +980,14 @@ int cls_camera::capture()
}
}

if ((device_status == STATUS_OPENED) &&
(missing_frame_counter == ((cfg->device_tmo * 4) * cfg->framerate))) {
MOTPLS_LOG(ERR, TYPE_ALL, NO_ERRNO
,_("Video signal still lost - Trying to close video device"));
cam_close();
if (camera_type == CAMERA_TYPE_LIBCAM) {
libcam->noimage();
} else if (camera_type == CAMERA_TYPE_NETCAM) {
netcam->noimage();
} else if (camera_type == CAMERA_TYPE_V4L2) {
v4l2cam->noimage();
} else {
MOTPLS_LOG(ERR, TYPE_VIDEO, NO_ERRNO,_("Unknown camera type"));
}
}
}
Expand All @@ -1001,6 +998,10 @@ int cls_camera::capture()
/* call detection */
void cls_camera::detection()
{
if ((restart == true) || (handler_stop == true)) {
return;
}

if (frame_skip) {
frame_skip--;
current_image->diffs = 0;
Expand All @@ -1019,6 +1020,10 @@ void cls_camera::detection()
/* tune the detection parameters*/
void cls_camera::tuning()
{
if ((restart == true) || (handler_stop == true)) {
return;
}

if ((cfg->noise_tune && shots_mt == 0) &&
(!detecting_motion && (current_image->diffs <= threshold))) {
alg->noise_tune();
Expand Down Expand Up @@ -1051,6 +1056,10 @@ void cls_camera::tuning()
/* apply image overlays */
void cls_camera::overlay()
{
if ((restart == true) || (handler_stop == true)) {
return;
}

char tmp[PATH_MAX];

if ((cfg->smart_mask_speed >0) &&
Expand Down Expand Up @@ -1261,6 +1270,10 @@ void cls_camera::actions_event()

void cls_camera::actions()
{
if ((restart == true) || (handler_stop == true)) {
return;
}

if ((current_image->diffs > threshold) &&
(current_image->diffs < threshold_maximum)) {
current_image->flags |= IMAGE_MOTION;
Expand Down Expand Up @@ -1318,6 +1331,10 @@ void cls_camera::actions()
/* Snapshot interval*/
void cls_camera::snapshot()
{
if ((restart == true) || (handler_stop == true)) {
return;
}

if ((cfg->snapshot_interval > 0 && shots_mt == 0 &&
frame_curr_ts.tv_sec % cfg->snapshot_interval <=
frame_last_ts.tv_sec % cfg->snapshot_interval) ||
Expand All @@ -1332,6 +1349,10 @@ void cls_camera::timelapse()
{
struct tm timestamp_tm;

if ((restart == true) || (handler_stop == true)) {
return;
}

if (cfg->timelapse_interval) {
localtime_r(&current_image->imgts.tv_sec, &timestamp_tm);

Expand Down Expand Up @@ -1383,6 +1404,9 @@ void cls_camera::timelapse()
/* send images to loopback device*/
void cls_camera::loopback()
{
if ((restart == true) || (handler_stop == true)) {
return;
}

vlp_putpipe(this);

Expand All @@ -1398,6 +1422,10 @@ void cls_camera::frametiming()
struct timespec ts2;
int64_t sleeptm;

if ((restart == true) || (handler_stop == true)) {
return;
}

clock_gettime(CLOCK_MONOTONIC, &ts2);

sleeptm = ((1000000L / cfg->framerate) -
Expand All @@ -1423,7 +1451,6 @@ void cls_camera::handler()
init();
prepare();
resetimages();
retry();
capture();
detection();
tuning();
Expand All @@ -1433,9 +1460,6 @@ void cls_camera::handler()
timelapse();
loopback();
frametiming();
if (device_status == STATUS_CLOSED) {
handler_stop = true;
}
}

cleanup();
Expand Down
2 changes: 1 addition & 1 deletion src/camera.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ class cls_camera {
int threshold;
int lastrate;
int frame_skip;
int lost_connection;
bool lost_connection;
int text_scale;
int watchdog;
bool movie_passthrough;
Expand Down
51 changes: 44 additions & 7 deletions src/libcam.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -756,7 +756,7 @@ int cls_libcam::libcam_start()

void cls_libcam::libcam_stop()
{
delete params;
mydelete(params);

if (started_aqr) {
camera->stop();
Expand All @@ -783,11 +783,48 @@ void cls_libcam::libcam_stop()
cam_mgr->stop();
cam_mgr.reset();
}
cam->device_status = STATUS_CLOSED;
MOTPLS_LOG(NTC, TYPE_VIDEO, NO_ERRNO, "Camera stopped.");
}

#endif

void cls_libcam::noimage()
{
#ifdef HAVE_LIBCAM
int slp_dur;

if (reconnect_count < 100) {
reconnect_count++;
} else {
if (reconnect_count >= 500) {
MOTPLS_LOG(NTC, TYPE_NETCAM, NO_ERRNO,_("Camera did not reconnect."));
MOTPLS_LOG(NTC, TYPE_NETCAM, NO_ERRNO,_("Checking for camera every 2 hours."));
slp_dur = 7200;
} else if (reconnect_count >= 200) {
MOTPLS_LOG(NTC, TYPE_NETCAM, NO_ERRNO,_("Camera did not reconnect."));
MOTPLS_LOG(NTC, TYPE_NETCAM, NO_ERRNO,_("Checking for camera every 10 minutes."));
reconnect_count++;
slp_dur = 600;
} else {
MOTPLS_LOG(NTC, TYPE_NETCAM, NO_ERRNO,_("Camera did not reconnect."));
MOTPLS_LOG(NTC, TYPE_NETCAM, NO_ERRNO,_("Checking for camera every 30 seconds."));
reconnect_count++;
slp_dur = 30;
}
cam->watchdog = slp_dur + (cam->cfg->watchdog_tmo * 3);
SLEEP(slp_dur,0);
libcam_stop();
if (libcam_start() < 0) {
MOTPLS_LOG(ERR, TYPE_VIDEO, NO_ERRNO,_("libcam failed to open"));
libcam_stop();
} else {
cam->device_status = STATUS_OPENED;
}
}
#endif
}

int cls_libcam::next(ctx_image_data *img_data)
{
#ifdef HAVE_LIBCAM
Expand Down Expand Up @@ -816,6 +853,8 @@ int cls_libcam::next(ctx_image_data *img_data)
req_add(request);

cam->rotate->process(img_data);
reconnect_count = 0;

return CAPTURE_SUCCESS;

} else {
Expand All @@ -829,10 +868,11 @@ int cls_libcam::next(ctx_image_data *img_data)

cls_libcam::cls_libcam(cls_camera *p_cam)
{
cam = p_cam;
#ifdef HAVE_LIBCAM
MOTPLS_LOG(NTC, TYPE_VIDEO, NO_ERRNO,_("Opening libcam"));
cam = p_cam;
params = nullptr;
reconnect_count = 0;
cam->watchdog = cam->cfg->watchdog_tmo * 3; /* 3 is arbitrary multiplier to give startup more time*/
if (libcam_start() < 0) {
MOTPLS_LOG(ERR, TYPE_VIDEO, NO_ERRNO,_("libcam failed to open"));
Expand All @@ -841,19 +881,16 @@ cls_libcam::cls_libcam(cls_camera *p_cam)
cam->device_status = STATUS_OPENED;
}
#else
(void)p_cam;
MOTPLS_LOG(NTC, TYPE_VIDEO, NO_ERRNO,_("libcam not available"));
p_cam->device_status = STATUS_CLOSED;
cam->device_status = STATUS_CLOSED;
#endif

}

cls_libcam::~cls_libcam()
{
#ifdef HAVE_LIBCAM
libcam_stop();
cam->device_status = STATUS_CLOSED;
#endif

cam->device_status = STATUS_CLOSED;
}

Loading

0 comments on commit 28e2fbe

Please sign in to comment.