mirror of
https://github.com/opencv/opencv.git
synced 2025-06-07 17:44:04 +08:00
Merge pull request #15973 from VadimLevin:dev/vlevin/video_capture_inf_loop
* Fix infinite loop when trying to change state of the busy camera - Add finite number of attempts in tryIoctl functions 10 by default. * Introduced new flag for ioctl call to handle EBUSY
This commit is contained in:
parent
50ac880335
commit
373160ce00
@ -353,7 +353,7 @@ struct CvCaptureCAM_V4L CV_FINAL : public CvCapture
|
||||
bool initCapture();
|
||||
bool streaming(bool startStream);
|
||||
bool setFps(int value);
|
||||
bool tryIoctl(unsigned long ioctlCode, void *parameter) const;
|
||||
bool tryIoctl(unsigned long ioctlCode, void *parameter, bool failIfBusy = true, int attempts = 10) const;
|
||||
bool controlInfo(int property_id, __u32 &v4l2id, cv::Range &range) const;
|
||||
bool icvControl(__u32 v4l2id, int &value, bool isSet) const;
|
||||
|
||||
@ -406,10 +406,10 @@ bool CvCaptureCAM_V4L::try_palette_v4l2()
|
||||
form.fmt.pix.field = V4L2_FIELD_ANY;
|
||||
form.fmt.pix.width = width;
|
||||
form.fmt.pix.height = height;
|
||||
|
||||
if (!tryIoctl(VIDIOC_S_FMT, &form))
|
||||
{
|
||||
return false;
|
||||
|
||||
}
|
||||
return palette == form.fmt.pix.pixelformat;
|
||||
}
|
||||
|
||||
@ -481,6 +481,8 @@ bool CvCaptureCAM_V4L::autosetup_capture_mode_v4l2()
|
||||
//in case palette is already set and works, no need to setup.
|
||||
if (palette != 0 && try_palette_v4l2()) {
|
||||
return true;
|
||||
} else if (errno == EBUSY) {
|
||||
return false;
|
||||
}
|
||||
__u32 try_order[] = {
|
||||
V4L2_PIX_FMT_BGR24,
|
||||
@ -637,7 +639,9 @@ bool CvCaptureCAM_V4L::initCapture()
|
||||
}
|
||||
|
||||
if (!autosetup_capture_mode_v4l2()) {
|
||||
fprintf(stderr, "VIDEOIO ERROR: V4L2: Pixel format of incoming image is unsupported by OpenCV\n");
|
||||
if (errno != EBUSY) {
|
||||
fprintf(stderr, "VIDEOIO ERROR: V4L2: Pixel format of incoming image is unsupported by OpenCV\n");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -857,10 +861,21 @@ bool CvCaptureCAM_V4L::read_frame_v4l2()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CvCaptureCAM_V4L::tryIoctl(unsigned long ioctlCode, void *parameter) const
|
||||
bool CvCaptureCAM_V4L::tryIoctl(unsigned long ioctlCode, void *parameter, bool failIfBusy, int attempts) const
|
||||
{
|
||||
if (attempts == 0) {
|
||||
return false;
|
||||
}
|
||||
while (-1 == ioctl(deviceHandle, ioctlCode, parameter)) {
|
||||
if (!(errno == EBUSY || errno == EAGAIN))
|
||||
const bool isBusy = (errno == EBUSY);
|
||||
if (isBusy & failIfBusy) {
|
||||
return false;
|
||||
}
|
||||
if ((attempts > 0) && (--attempts == 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(isBusy || errno == EAGAIN))
|
||||
return false;
|
||||
|
||||
fd_set fds;
|
||||
@ -1969,8 +1984,9 @@ CvCapture* cvCreateCameraCapture_V4L( int index )
|
||||
{
|
||||
cv::CvCaptureCAM_V4L* capture = new cv::CvCaptureCAM_V4L();
|
||||
|
||||
if(capture->open(index))
|
||||
if(capture->open(index)) {
|
||||
return capture;
|
||||
}
|
||||
|
||||
delete capture;
|
||||
return NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user