videoio(v4l2): use logging, update handling of EBUSY, device closing

- DEBUG logging compilation is enabled for all videoio backends
- eliminate output through perror(), stderr
This commit is contained in:
Alexander Alekhin 2019-11-22 21:03:52 +00:00
parent 373160ce00
commit 501ff7f056
2 changed files with 214 additions and 79 deletions

View File

@ -278,6 +278,32 @@ make & enjoy!
namespace cv {
static const char* decode_ioctl_code(unsigned long ioctlCode)
{
switch (ioctlCode)
{
#define CV_ADD_IOCTL_CODE(id) case id: return #id
CV_ADD_IOCTL_CODE(VIDIOC_G_FMT);
CV_ADD_IOCTL_CODE(VIDIOC_S_FMT);
CV_ADD_IOCTL_CODE(VIDIOC_REQBUFS);
CV_ADD_IOCTL_CODE(VIDIOC_DQBUF);
CV_ADD_IOCTL_CODE(VIDIOC_QUERYCAP);
CV_ADD_IOCTL_CODE(VIDIOC_S_PARM);
CV_ADD_IOCTL_CODE(VIDIOC_G_PARM);
CV_ADD_IOCTL_CODE(VIDIOC_QUERYBUF);
CV_ADD_IOCTL_CODE(VIDIOC_QBUF);
CV_ADD_IOCTL_CODE(VIDIOC_STREAMON);
CV_ADD_IOCTL_CODE(VIDIOC_STREAMOFF);
CV_ADD_IOCTL_CODE(VIDIOC_ENUMINPUT);
CV_ADD_IOCTL_CODE(VIDIOC_G_INPUT);
CV_ADD_IOCTL_CODE(VIDIOC_S_INPUT);
CV_ADD_IOCTL_CODE(VIDIOC_G_CTRL);
CV_ADD_IOCTL_CODE(VIDIOC_S_CTRL);
#undef CV_ADD_IOCTL_CODE
}
return "unknown";
}
/* Device Capture Objects */
/* V4L2 structure */
struct Buffer
@ -299,6 +325,9 @@ struct CvCaptureCAM_V4L CV_FINAL : public CvCapture
int getCaptureDomain() /*const*/ CV_OVERRIDE { return cv::CAP_V4L; }
int deviceHandle;
bool v4l_buffersRequested;
bool v4l_streamStarted;
int bufferIndex;
bool FirstCapture;
String deviceName;
@ -339,6 +368,8 @@ struct CvCaptureCAM_V4L CV_FINAL : public CvCapture
bool open(const char* deviceName);
bool isOpened() const;
void closeDevice();
virtual double getProperty(int) const CV_OVERRIDE;
virtual bool setProperty(int, double) CV_OVERRIDE;
virtual bool grabFrame() CV_OVERRIDE;
@ -373,7 +404,10 @@ struct CvCaptureCAM_V4L CV_FINAL : public CvCapture
/*********************** Implementations ***************************************/
CvCaptureCAM_V4L::CvCaptureCAM_V4L() :
deviceHandle(-1), bufferIndex(-1),
deviceHandle(-1),
v4l_buffersRequested(false),
v4l_streamStarted(false),
bufferIndex(-1),
FirstCapture(true),
palette(0),
width(0), height(0), width_set(0), height_set(0),
@ -386,11 +420,32 @@ CvCaptureCAM_V4L::CvCaptureCAM_V4L() :
memset(&timestamp, 0, sizeof(timestamp));
}
CvCaptureCAM_V4L::~CvCaptureCAM_V4L() {
streaming(false);
releaseBuffers();
CvCaptureCAM_V4L::~CvCaptureCAM_V4L()
{
try
{
closeDevice();
}
catch (...)
{
CV_LOG_WARNING(NULL, "VIDEOIO(V4L2): unable properly close device: " << deviceName);
if (deviceHandle != -1)
close(deviceHandle);
}
}
void CvCaptureCAM_V4L::closeDevice()
{
if (v4l_streamStarted)
streaming(false);
if (v4l_buffersRequested)
releaseBuffers();
if(deviceHandle != -1)
{
CV_LOG_DEBUG(NULL, "VIDEOIO(V4L2:" << deviceName << "): close(" << deviceHandle << ")");
close(deviceHandle);
}
deviceHandle = -1;
}
bool CvCaptureCAM_V4L::isOpened() const
@ -406,7 +461,7 @@ 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))
if (!tryIoctl(VIDIOC_S_FMT, &form, true))
{
return false;
}
@ -451,9 +506,7 @@ bool CvCaptureCAM_V4L::try_init_v4l2()
// The cv::CAP_PROP_MODE used for set the video input channel number
if (!setVideoInputChannel())
{
#ifndef NDEBUG
fprintf(stderr, "(DEBUG) V4L2: Unable to set Video Input Channel.");
#endif
CV_LOG_DEBUG(NULL, "VIDEOIO(V4L2:" << deviceName << "): Unable to set Video Input Channel");
return false;
}
@ -461,16 +514,14 @@ bool CvCaptureCAM_V4L::try_init_v4l2()
capability = v4l2_capability();
if (!tryIoctl(VIDIOC_QUERYCAP, &capability))
{
#ifndef NDEBUG
fprintf(stderr, "(DEBUG) V4L2: Unable to query capability.");
#endif
CV_LOG_DEBUG(NULL, "VIDEOIO(V4L2:" << deviceName << "): Unable to query capability");
return false;
}
if ((capability.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0)
{
/* Nope. */
fprintf(stderr, "VIDEOIO ERROR: V4L2: Unable to capture video memory.");
CV_LOG_INFO(NULL, "VIDEOIO(V4L2:" << deviceName << "): not supported - device is unable to capture video (missing V4L2_CAP_VIDEO_CAPTURE)");
return false;
}
return true;
@ -479,10 +530,18 @@ bool CvCaptureCAM_V4L::try_init_v4l2()
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;
if (palette != 0)
{
if (try_palette_v4l2())
{
return true;
}
else if (errno == EBUSY)
{
CV_LOG_INFO(NULL, "VIDEOIO(V4L2:" << deviceName << "): device is busy");
closeDevice();
return false;
}
}
__u32 try_order[] = {
V4L2_PIX_FMT_BGR24,
@ -510,6 +569,10 @@ bool CvCaptureCAM_V4L::autosetup_capture_mode_v4l2()
palette = try_order[i];
if (try_palette_v4l2()) {
return true;
} else if (errno == EBUSY) {
CV_LOG_INFO(NULL, "VIDEOIO(V4L2:" << deviceName << "): device is busy");
closeDevice();
return false;
}
}
return false;
@ -525,9 +588,15 @@ bool CvCaptureCAM_V4L::setFps(int value)
streamparm.parm.capture.timeperframe.numerator = 1;
streamparm.parm.capture.timeperframe.denominator = __u32(value);
if (!tryIoctl(VIDIOC_S_PARM, &streamparm) || !tryIoctl(VIDIOC_G_PARM, &streamparm))
{
CV_LOG_INFO(NULL, "VIDEOIO(V4L2:" << deviceName << "): can't set FPS: " << value);
return false;
}
fps = streamparm.parm.capture.timeperframe.denominator;
CV_LOG_DEBUG(NULL, "VIDEOIO(V4L2:" << deviceName << "): FPS="
<< streamparm.parm.capture.timeperframe.denominator << "/"
<< streamparm.parm.capture.timeperframe.numerator);
fps = streamparm.parm.capture.timeperframe.denominator; // TODO use numerator
return true;
}
@ -622,10 +691,9 @@ bool CvCaptureCAM_V4L::initCapture()
if (!isOpened())
return false;
if (!try_init_v4l2()) {
#ifndef NDEBUG
fprintf(stderr, " try_init_v4l2 open \"%s\": %s\n", deviceName.c_str(), strerror(errno));
#endif
if (!try_init_v4l2())
{
CV_LOG_DEBUG(NULL, "VIDEOIO(V4L2:" << deviceName << "): init failed: errno=" << errno << " (" << strerror(errno) << ")");
return false;
}
@ -633,14 +701,17 @@ bool CvCaptureCAM_V4L::initCapture()
form = v4l2_format();
form.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (!tryIoctl(VIDIOC_G_FMT, &form)) {
fprintf( stderr, "VIDEOIO ERROR: V4L2: Could not obtain specifics of capture window.\n");
if (!tryIoctl(VIDIOC_G_FMT, &form))
{
CV_LOG_DEBUG(NULL, "VIDEOIO(V4L2:" << deviceName << "): Could not obtain specifics of capture window (VIDIOC_G_FMT): errno=" << errno << " (" << strerror(errno) << ")");
return false;
}
if (!autosetup_capture_mode_v4l2()) {
if (errno != EBUSY) {
fprintf(stderr, "VIDEOIO ERROR: V4L2: Pixel format of incoming image is unsupported by OpenCV\n");
if (!autosetup_capture_mode_v4l2())
{
if (errno != EBUSY)
{
CV_LOG_INFO(NULL, "VIDEOIO(V4L2:" << deviceName << "): Pixel format of incoming image is unsupported by OpenCV");
}
return false;
}
@ -682,16 +753,16 @@ bool CvCaptureCAM_V4L::requestBuffers()
{
unsigned int buffer_number = bufferSize;
while (buffer_number > 0) {
if (!requestBuffers(buffer_number))
return false;
if (req.count >= buffer_number)
if (requestBuffers(buffer_number) && req.count >= buffer_number)
{
break;
}
buffer_number--;
fprintf(stderr, "Insufficient buffer memory on %s -- decreasing buffers\n", deviceName.c_str());
CV_LOG_DEBUG(NULL, "VIDEOIO(V4L2:" << deviceName << "): Insufficient buffer memory -- decreasing buffers: " << buffer_number);
}
if (buffer_number < 1) {
fprintf(stderr, "Insufficient buffer memory on %s\n", deviceName.c_str());
CV_LOG_WARNING(NULL, "VIDEOIO(V4L2:" << deviceName << "): Insufficient buffer memory");
return false;
}
bufferSize = req.count;
@ -709,13 +780,18 @@ bool CvCaptureCAM_V4L::requestBuffers(unsigned int buffer_number)
req.memory = V4L2_MEMORY_MMAP;
if (!tryIoctl(VIDIOC_REQBUFS, &req)) {
if (EINVAL == errno) {
fprintf(stderr, "%s does not support memory mapping\n", deviceName.c_str());
} else {
perror("VIDIOC_REQBUFS");
int err = errno;
if (EINVAL == err)
{
CV_LOG_WARNING(NULL, "VIDEOIO(V4L2:" << deviceName << "): no support for memory mapping");
}
else
{
CV_LOG_WARNING(NULL, "VIDEOIO(V4L2:" << deviceName << "): failed VIDIOC_REQBUFS: errno=" << err << " (" << strerror(err) << ")");
}
return false;
}
v4l_buffersRequested = true;
return true;
}
@ -729,7 +805,7 @@ bool CvCaptureCAM_V4L::createBuffers()
buf.index = n_buffers;
if (!tryIoctl(VIDIOC_QUERYBUF, &buf)) {
perror("VIDIOC_QUERYBUF");
CV_LOG_WARNING(NULL, "VIDEOIO(V4L2:" << deviceName << "): failed VIDIOC_QUERYBUF: errno=" << errno << " (" << strerror(errno) << ")");
return false;
}
@ -742,7 +818,7 @@ bool CvCaptureCAM_V4L::createBuffers()
deviceHandle, buf.m.offset);
if (MAP_FAILED == buffers[n_buffers].start) {
perror("mmap");
CV_LOG_WARNING(NULL, "VIDEOIO(V4L2:" << deviceName << "): failed mmap(" << buf.length << "): errno=" << errno << " (" << strerror(errno) << ")");
return false;
}
maxLength = maxLength > buf.length ? maxLength : buf.length;
@ -786,7 +862,7 @@ bool CvCaptureCAM_V4L::open(int _index)
}
if (_index < 0)
{
fprintf(stderr, "VIDEOIO ERROR: V4L: can't find camera device\n");
CV_LOG_WARNING(NULL, "VIDEOIO(V4L2): can't find camera device");
name.clear();
return false;
}
@ -799,16 +875,15 @@ bool CvCaptureCAM_V4L::open(int _index)
bool res = open(name.c_str());
if (!res)
{
CV_LOG_WARNING(NULL, cv::format("VIDEOIO ERROR: V4L: can't open camera by index %d", _index));
CV_LOG_WARNING(NULL, "VIDEOIO(V4L2:" << deviceName << "): can't open camera by index");
}
return res;
}
bool CvCaptureCAM_V4L::open(const char* _deviceName)
{
#ifndef NDEBUG
fprintf(stderr, "(DEBUG) V4L: opening %s\n", _deviceName);
#endif
CV_Assert(_deviceName);
CV_LOG_DEBUG(NULL, "VIDEOIO(V4L2:" << _deviceName << "): opening...");
FirstCapture = true;
width = DEFAULT_V4L_WIDTH;
height = DEFAULT_V4L_HEIGHT;
@ -824,6 +899,7 @@ bool CvCaptureCAM_V4L::open(const char* _deviceName)
bufferIndex = -1;
deviceHandle = ::open(deviceName.c_str(), O_RDWR /* required */ | O_NONBLOCK, 0);
CV_LOG_DEBUG(NULL, "VIDEOIO(V4L2:" << _deviceName << "): deviceHandle=" << deviceHandle);
if (deviceHandle == -1)
return false;
@ -837,7 +913,8 @@ bool CvCaptureCAM_V4L::read_frame_v4l2()
buf.memory = V4L2_MEMORY_MMAP;
while (!tryIoctl(VIDIOC_DQBUF, &buf)) {
if (errno == EIO && !(buf.flags & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE))) {
int err = errno;
if (err == EIO && !(buf.flags & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE))) {
// Maybe buffer not in the queue? Try to put there
if (!tryIoctl(VIDIOC_QBUF, &buf))
return false;
@ -845,7 +922,7 @@ bool CvCaptureCAM_V4L::read_frame_v4l2()
}
/* display the error and stop processing */
returnFrame = false;
perror("VIDIOC_DQBUF");
CV_LOG_DEBUG(NULL, "VIDEOIO(V4L2:" << deviceName << "): can't read frame (VIDIOC_DQBUF): errno=" << err << " (" << strerror(err) << ")");
return false;
}
@ -863,37 +940,64 @@ bool CvCaptureCAM_V4L::read_frame_v4l2()
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)) {
const bool isBusy = (errno == EBUSY);
if (isBusy & failIfBusy) {
return false;
}
if ((attempts > 0) && (--attempts == 0)) {
return false;
}
CV_Assert(attempts > 0);
CV_LOG_DEBUG(NULL, "VIDEOIO(V4L2:" << deviceName << "): tryIoctl(" << deviceHandle << ", "
<< decode_ioctl_code(ioctlCode) << "(" << ioctlCode << "), failIfBusy=" << failIfBusy << ")"
);
while (true)
{
errno = 0;
int result = ioctl(deviceHandle, ioctlCode, parameter);
int err = errno;
CV_LOG_DEBUG(NULL, "VIDEOIO(V4L2:" << deviceName << "): call ioctl(" << deviceHandle << ", "
<< decode_ioctl_code(ioctlCode) << "(" << ioctlCode << "), ...) => "
<< result << " errno=" << err << " (" << strerror(err) << ")"
);
if (result != -1)
return true; // success
const bool isBusy = (err == EBUSY);
if (isBusy && failIfBusy)
{
CV_LOG_INFO(NULL, "VIDEOIO(V4L2:" << deviceName << "): ioctl returns with errno=EBUSY");
return false;
}
if (!(isBusy || errno == EAGAIN))
return false;
if (--attempts == 0) {
return false;
}
fd_set fds;
FD_ZERO(&fds);
FD_SET(deviceHandle, &fds);
/* Timeout. */
static int param_v4l_select_timeout = (int)utils::getConfigurationParameterSizeT("OPENCV_VIDEOIO_V4L_SELECT_TIMEOUT", 10);
struct timeval tv;
tv.tv_sec = 10;
tv.tv_sec = param_v4l_select_timeout;
tv.tv_usec = 0;
int result = select(deviceHandle + 1, &fds, NULL, NULL, &tv);
if (0 == result) {
fprintf(stderr, "select timeout\n");
errno = 0;
result = select(deviceHandle + 1, &fds, NULL, NULL, &tv);
err = errno;
if (0 == result)
{
CV_LOG_WARNING(NULL, "VIDEOIO(V4L2:" << deviceName << "): select() timeout.");
return false;
}
CV_LOG_DEBUG(NULL, "VIDEOIO(V4L2:" << deviceName << "): select(" << deviceHandle << ") => "
<< result << " errno = " << err << " (" << strerror(err) << ")"
);
if (EINTR == err) // don't loop if signal occurred, like Ctrl+C
{
return false;
}
if (-1 == result && EINTR != errno)
perror("select");
}
return true;
}
@ -914,14 +1018,12 @@ bool CvCaptureCAM_V4L::grabFrame()
buf.index = index;
if (!tryIoctl(VIDIOC_QBUF, &buf)) {
perror("VIDIOC_QBUF");
CV_LOG_DEBUG(NULL, "VIDEOIO(V4L2:" << deviceName << "): failed VIDIOC_QBUF (buffer=" << index << "): errno=" << errno << " (" << strerror(errno) << ")");
return false;
}
}
if(!streaming(true)) {
/* error enabling the stream */
perror("VIDIOC_STREAMON");
if (!streaming(true)) {
return false;
}
@ -936,9 +1038,12 @@ bool CvCaptureCAM_V4L::grabFrame()
FirstCapture = false;
}
// In the case that the grab frame was without retrieveFrame
if (bufferIndex >= 0) {
if (bufferIndex >= 0)
{
if (!tryIoctl(VIDIOC_QBUF, &buffers[bufferIndex].buffer))
perror("VIDIOC_QBUF");
{
CV_LOG_DEBUG(NULL, "VIDEOIO(V4L2:" << deviceName << "): failed VIDIOC_QBUF (buffer=" << bufferIndex << "): errno=" << errno << " (" << strerror(errno) << ")");
}
}
return read_frame_v4l2();
}
@ -1453,6 +1558,7 @@ void CvCaptureCAM_V4L::convertToRgb(const Buffer &currentBuffer)
#ifdef HAVE_JPEG
case V4L2_PIX_FMT_MJPEG:
case V4L2_PIX_FMT_JPEG:
CV_LOG_DEBUG(NULL, "VIDEOIO(V4L2:" << deviceName << "): decoding JPEG frame: size=" << currentBuffer.buffer.bytesused);
cv::imdecode(Mat(1, currentBuffer.buffer.bytesused, CV_8U, currentBuffer.start), IMREAD_COLOR, &destination);
return;
#endif
@ -1695,7 +1801,7 @@ bool CvCaptureCAM_V4L::controlInfo(int property_id, __u32 &_v4l2id, cv::Range &r
v4l2_queryctrl queryctrl = v4l2_queryctrl();
queryctrl.id = __u32(v4l2id);
if (v4l2id == -1 || !tryIoctl(VIDIOC_QUERYCTRL, &queryctrl)) {
fprintf(stderr, "VIDEOIO ERROR: V4L2: property %s is not supported\n", capPropertyName(property_id).c_str());
CV_LOG_INFO(NULL, "VIDEOIO(V4L2:" << deviceName << "): property " << capPropertyName(property_id) << " is not supported");
return false;
}
_v4l2id = __u32(v4l2id);
@ -1726,7 +1832,9 @@ bool CvCaptureCAM_V4L::icvControl(__u32 v4l2id, int &value, bool isSet) const
/* The driver may clamp the value or return ERANGE, ignored here */
if (!tryIoctl(isSet ? VIDIOC_S_CTRL : VIDIOC_G_CTRL, &control)) {
switch (errno) {
int err = errno;
CV_LOG_DEBUG(NULL, "VIDEOIO(V4L2:" << deviceName << "): failed " << (isSet ? "VIDIOC_S_CTRL" : "VIDIOC_G_CTRL") << ": errno=" << err << " (" << strerror(err) << ")");
switch (err) {
#ifndef NDEBUG
case EINVAL:
fprintf(stderr,
@ -1741,7 +1849,6 @@ bool CvCaptureCAM_V4L::icvControl(__u32 v4l2id, int &value, bool isSet) const
break;
#endif
default:
perror(isSet ? "VIDIOC_S_CTRL" : "VIDIOC_G_CTRL");
break;
}
return false;
@ -1775,7 +1882,7 @@ double CvCaptureCAM_V4L::getProperty(int property_id) const
v4l2_streamparm sp = v4l2_streamparm();
sp.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (!tryIoctl(VIDIOC_G_PARM, &sp)) {
fprintf(stderr, "VIDEOIO ERROR: V4L: Unable to get camera FPS\n");
CV_LOG_WARNING(NULL, "VIDEOIO(V4L2:" << deviceName << "): Unable to get camera FPS");
return -1;
}
return sp.parm.capture.timeperframe.denominator / (double)sp.parm.capture.timeperframe.numerator;
@ -1865,7 +1972,7 @@ bool CvCaptureCAM_V4L::setProperty( int property_id, double _value )
return true;
if (value > MAX_V4L_BUFFERS || value < 1) {
fprintf(stderr, "V4L: Bad buffer size %d, buffer size must be from 1 to %d\n", value, MAX_V4L_BUFFERS);
CV_LOG_WARNING(NULL, "VIDEOIO(V4L2:" << deviceName << "): Bad buffer size " << value << ", buffer size must be from 1 to " << MAX_V4L_BUFFERS);
return false;
}
bufferSize = value;
@ -1921,13 +2028,15 @@ void CvCaptureCAM_V4L::releaseBuffers()
bufferIndex = -1;
FirstCapture = true;
if (!isOpened())
if (!v4l_buffersRequested)
return;
v4l_buffersRequested = false;
for (unsigned int n_buffers = 0; n_buffers < MAX_V4L_BUFFERS; ++n_buffers) {
if (buffers[n_buffers].start) {
if (-1 == munmap(buffers[n_buffers].start, buffers[n_buffers].length)) {
perror("munmap");
CV_LOG_DEBUG(NULL, "VIDEOIO(V4L2:" << deviceName << "): failed munmap(): errno=" << errno << " (" << strerror(errno) << ")");
} else {
buffers[n_buffers].start = 0;
}
@ -1941,11 +2050,28 @@ void CvCaptureCAM_V4L::releaseBuffers()
bool CvCaptureCAM_V4L::streaming(bool startStream)
{
if (!isOpened())
return !startStream;
if (startStream != v4l_streamStarted)
{
if (!isOpened())
{
CV_Assert(v4l_streamStarted == false);
return !startStream;
}
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
return tryIoctl(startStream ? VIDIOC_STREAMON : VIDIOC_STREAMOFF, &type);
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
bool result = tryIoctl(startStream ? VIDIOC_STREAMON : VIDIOC_STREAMOFF, &type);
if (result)
{
v4l_streamStarted = startStream;
return true;
}
if (startStream)
{
CV_LOG_DEBUG(NULL, "VIDEOIO(V4L2:" << deviceName << "): failed VIDIOC_STREAMON: errno=" << errno << " (" << strerror(errno) << ")");
}
return false;
}
return startStream;
}
IplImage *CvCaptureCAM_V4L::retrieveFrame(int)
@ -1963,6 +2089,7 @@ IplImage *CvCaptureCAM_V4L::retrieveFrame(int)
} else {
// for mjpeg streams the size might change in between, so we have to change the header
// We didn't allocate memory when not convert_rgb, but we have to recreate the header
CV_LOG_DEBUG(NULL, "VIDEOIO(V4L2:" << deviceName << "): buffer input size=" << currentBuffer.buffer.bytesused);
if (frame.imageSize != (int)currentBuffer.buffer.bytesused)
v4l2_create_frame();
@ -1972,7 +2099,9 @@ IplImage *CvCaptureCAM_V4L::retrieveFrame(int)
}
//Revert buffer to the queue
if (!tryIoctl(VIDIOC_QBUF, &buffers[bufferIndex].buffer))
perror("VIDIOC_QBUF");
{
CV_LOG_DEBUG(NULL, "VIDEOIO(V4L2:" << deviceName << "): failed VIDIOC_QBUF: errno=" << errno << " (" << strerror(errno) << ")");
}
bufferIndex = -1;
return &frame;

View File

@ -48,6 +48,12 @@
#include "opencv2/core/private.hpp"
#include <opencv2/core/utils/configuration.private.hpp>
#include <opencv2/core/utils/logger.defines.hpp>
#ifdef NDEBUG
#define CV_LOG_STRIP_LEVEL CV_LOG_LEVEL_DEBUG + 1
#else
#define CV_LOG_STRIP_LEVEL CV_LOG_LEVEL_VERBOSE + 1
#endif
#include <opencv2/core/utils/logger.hpp>
#include "opencv2/imgcodecs.hpp"