Revise lost camera processing

This commit is contained in:
Mr-Dave
2024-09-05 12:12:34 -06:00
parent d6f6f6cfd0
commit 52a667ebda
9 changed files with 292 additions and 146 deletions

View File

@@ -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) {

View File

@@ -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);
@@ -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;
@@ -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;
@@ -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;
}
@@ -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;
@@ -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) {
@@ -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)) {
@@ -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 {
@@ -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"));
}
}
}
@@ -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;
@@ -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();
@@ -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) &&
@@ -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;
@@ -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) ||
@@ -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);
@@ -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);
@@ -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) -
@@ -1423,7 +1451,6 @@ void cls_camera::handler()
init();
prepare();
resetimages();
retry();
capture();
detection();
tuning();
@@ -1433,9 +1460,6 @@ void cls_camera::handler()
timelapse();
loopback();
frametiming();
if (device_status == STATUS_CLOSED) {
handler_stop = true;
}
}
cleanup();

View File

@@ -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;

View File

@@ -756,7 +756,7 @@ int cls_libcam::libcam_start()
void cls_libcam::libcam_stop()
{
delete params;
mydelete(params);
if (started_aqr) {
camera->stop();
@@ -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
@@ -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 {
@@ -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"));
@@ -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;
}

View File

@@ -36,6 +36,7 @@
cls_libcam(cls_camera *p_cam);
~cls_libcam();
int next(ctx_image_data *img_data);
void noimage();
private:
cls_camera *cam;
ctx_params *params;
@@ -49,11 +50,11 @@
std::queue<libcamera::Request *> req_queue;
libcamera::ControlList controls;
ctx_imgmap membuf;
bool started_cam;
bool started_mgr;
bool started_aqr;
bool started_req;
bool started_cam;
bool started_mgr;
bool started_aqr;
bool started_req;
int reconnect_count;
void log_orientation();
void log_controls();
void log_draft();
@@ -81,6 +82,9 @@
cls_libcam(cls_camera *p_cam);
~cls_libcam();
int next(ctx_image_data *img_data);
void noimage();
private:
cls_camera *cam;
};
#endif

View File

@@ -1617,10 +1617,6 @@ void cls_netcam::set_parms ()
params = new ctx_params;
pthread_mutex_init(&mutex, nullptr);
pthread_mutex_init(&mutex_pktarray, nullptr);
pthread_mutex_init(&mutex_transfer, nullptr);
context_null();
threadnbr = cam->cfg->device_id;
cfg_width = cam->cfg->width;
@@ -1670,7 +1666,6 @@ void cls_netcam::set_parms ()
pktarray = nullptr;
packet_recv = nullptr;
first_image = true;
reconnect_count = 0;
src_fps = -1; /* Default to neg so we know it has not been set */
pts_adj = false;
capture_rate = -1;
@@ -2017,7 +2012,7 @@ void cls_netcam::handler_wait()
void cls_netcam::handler_reconnect()
{
int retcd;
int retcd, slp_dur;
if (service == "file") {
filelist_load();
@@ -2036,35 +2031,40 @@ void cls_netcam::handler_reconnect()
cam->event_stop = true;
}
/*
* The retry count of 100 is arbritrary.
* We want to try many times quickly to not lose too much information
* before we go into the long wait phase
*/
retcd = connect();
if (retcd < 0) {
if (reconnect_count < 100) {
reconnect_count++;
} else if ((reconnect_count >= 100) && (reconnect_count <= 199)) {
MOTPLS_LOG(NTC, TYPE_NETCAM, NO_ERRNO
,_("%s:Camera did not reconnect.")
, cameratype.c_str());
MOTPLS_LOG(NTC, TYPE_NETCAM, NO_ERRNO
,_("%s:Checking for camera every 10 seconds.")
,cameratype.c_str());
reconnect_count++;
SLEEP(10,0);
} else if (reconnect_count >= 200) {
MOTPLS_LOG(NTC, TYPE_NETCAM, NO_ERRNO
,_("%s:Camera did not reconnect.")
, cameratype.c_str());
MOTPLS_LOG(NTC, TYPE_NETCAM, NO_ERRNO
,_("%s:Checking for camera every 10 minutes.")
,cameratype.c_str());
SLEEP(600,0);
} else {
reconnect_count++;
SLEEP(600,0);
if (reconnect_count >= 500) {
MOTPLS_LOG(NTC, TYPE_NETCAM, NO_ERRNO
,_("%s:Camera did not reconnect.")
, cameratype.c_str());
MOTPLS_LOG(NTC, TYPE_NETCAM, NO_ERRNO
,_("%s:Checking for camera every 2 hours.")
,cameratype.c_str());
slp_dur = 7200;
} else if (reconnect_count >= 200) {
MOTPLS_LOG(NTC, TYPE_NETCAM, NO_ERRNO
,_("%s:Camera did not reconnect.")
, cameratype.c_str());
MOTPLS_LOG(NTC, TYPE_NETCAM, NO_ERRNO
,_("%s:Checking for camera every 10 minutes.")
,cameratype.c_str());
reconnect_count++;
slp_dur = 600;
} else {
MOTPLS_LOG(NTC, TYPE_NETCAM, NO_ERRNO
,_("%s:Camera did not reconnect.")
, cameratype.c_str());
MOTPLS_LOG(NTC, TYPE_NETCAM, NO_ERRNO
,_("%s:Checking for camera every 10 seconds.")
,cameratype.c_str());
reconnect_count++;
slp_dur = 10;
}
cam->watchdog = slp_dur + (cam->cfg->watchdog_tmo * 3);
SLEEP(slp_dur,0);
}
} else {
reconnect_count = 0;
@@ -2082,14 +2082,17 @@ void cls_netcam::handler()
,cameratype.c_str());
while (handler_stop == false) {
if (format_context == nullptr) { /* We must have disconnected. Try to reconnect */
if (format_context == nullptr) {
/* We have disconnected. Try to reconnect */
clock_gettime(CLOCK_MONOTONIC, &frame_prev_tm);
handler_reconnect();
continue;
} else { /* We think we are connected...*/
} else {
/* We think we are connected...*/
clock_gettime(CLOCK_MONOTONIC, &frame_prev_tm);
if (read_image() < 0) {
if (handler_stop == false) { /* Nope. We are not or got bad image. Reconnect*/
/* We are not connected or got bad image.*/
if (handler_stop == false) {
handler_reconnect();
}
continue;
@@ -2208,14 +2211,7 @@ void cls_netcam::handler_shutdown()
img_recv = nullptr;
}
pthread_mutex_destroy(&mutex);
pthread_mutex_destroy(&mutex_pktarray);
pthread_mutex_destroy(&mutex_transfer);
if (params != nullptr) {
delete params;
params = nullptr;
}
mydelete(params);
cam->device_status = STATUS_CLOSED;
status = NETCAM_NOTCONNECTED;
@@ -2225,39 +2221,10 @@ void cls_netcam::handler_shutdown()
}
int cls_netcam::next(ctx_image_data *img_data)
{
if ((status == NETCAM_RECONNECTING) ||
(status == NETCAM_NOTCONNECTED)) {
return CAPTURE_ATTEMPTED;
}
pthread_mutex_lock(&mutex);
pktarray_resize();
if (high_resolution == false) {
memcpy(img_data->image_norm
, img_latest->ptr
, img_latest->used);
img_data->idnbr_norm = idnbr;
} else {
img_data->idnbr_high = idnbr;
if (cam->netcam_high->passthrough == false) {
memcpy(img_data->image_high
, img_latest->ptr
, img_latest->used);
}
}
pthread_mutex_unlock(&mutex);
return CAPTURE_SUCCESS;
}
cls_netcam::cls_netcam(cls_camera *p_cam, bool p_is_high)
void cls_netcam::netcam_start()
{
int retcd;
cam = p_cam;
high_resolution = p_is_high;
handler_finished = true;
handler_stop = false;
@@ -2309,8 +2276,87 @@ cls_netcam::cls_netcam(cls_camera *p_cam, bool p_is_high)
}
cls_netcam::~cls_netcam()
void cls_netcam::netcam_stop()
{
handler_shutdown();
}
void cls_netcam::noimage()
{
int slp_dur;
if (handler_finished == true ) { /* handler is not running */
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);
cam->watchdog = (cam->cfg->watchdog_tmo * 3);
netcam_stop();
netcam_start();
}
}
int cls_netcam::next(ctx_image_data *img_data)
{
if ((status == NETCAM_RECONNECTING) ||
(status == NETCAM_NOTCONNECTED)) {
return CAPTURE_ATTEMPTED;
}
pthread_mutex_lock(&mutex);
pktarray_resize();
if (high_resolution == false) {
memcpy(img_data->image_norm
, img_latest->ptr
, img_latest->used);
img_data->idnbr_norm = idnbr;
} else {
img_data->idnbr_high = idnbr;
if (cam->netcam_high->passthrough == false) {
memcpy(img_data->image_high
, img_latest->ptr
, img_latest->used);
}
}
pthread_mutex_unlock(&mutex);
return CAPTURE_SUCCESS;
}
cls_netcam::cls_netcam(cls_camera *p_cam, bool p_is_high)
{
cam = p_cam;
high_resolution = p_is_high;
reconnect_count = 0;
pthread_mutex_init(&mutex, nullptr);
pthread_mutex_init(&mutex_pktarray, nullptr);
pthread_mutex_init(&mutex_transfer, nullptr);
netcam_start();
}
cls_netcam::~cls_netcam()
{
netcam_stop();
pthread_mutex_destroy(&mutex);
pthread_mutex_destroy(&mutex_pktarray);
pthread_mutex_destroy(&mutex_transfer);
}

View File

@@ -75,6 +75,7 @@ class cls_netcam {
cls_netcam(cls_camera *p_cam, bool p_is_high);
~cls_netcam();
int next(ctx_image_data *img_data);
void noimage();
bool interrupted; /* Boolean for whether interrupt has been tripped */
enum NETCAM_STATUS status; /* Status of whether the camera is connecting, closed, etc*/
@@ -202,6 +203,9 @@ class cls_netcam {
void handler_startup();
void handler_shutdown();
void netcam_start();
void netcam_stop();
};
#endif /* _INCLUDE_NETCAM_HPP_ */

View File

@@ -1105,10 +1105,10 @@ void cls_v4l2cam::stop_cam()
}
if (convert != nullptr) {
delete convert;
mydelete(convert);
}
delete params;
mydelete(params);
}
void cls_v4l2cam::start_cam()
@@ -1138,6 +1138,37 @@ void cls_v4l2cam::start_cam()
#endif /* HAVE_V4L2 */
void cls_v4l2cam::noimage()
{
#ifdef HAVE_V4L2
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);
stop_cam();
start_cam();
}
#endif
}
int cls_v4l2cam::next(ctx_image_data *img_data)
{
#ifdef HAVE_V4L2
@@ -1170,7 +1201,7 @@ cls_v4l2cam::cls_v4l2cam(cls_camera *p_cam)
{
cam = p_cam;
#ifdef HAVE_V4L2
cam->watchdog = cam->cfg->watchdog_tmo;
cam->watchdog = cam->cfg->watchdog_tmo * 3;
start_cam();
#else
cam->device_status = STATUS_CLOSED;

View File

@@ -54,9 +54,8 @@ class cls_v4l2cam {
public:
cls_v4l2cam(cls_camera *p_cam);
~cls_v4l2cam();
int next(ctx_image_data *img_data);
void noimage();
private:
cls_camera *cam;
cls_convert *convert;
@@ -72,7 +71,8 @@ class cls_v4l2cam {
video_buff *buffers;
vec_palette palette;
int pframe;
int pframe;
int reconnect_count;
#ifdef HAVE_V4L2
struct v4l2_capability vidcap;