From 3b17af0c6711f328bf586b3c9749666e73e45664 Mon Sep 17 00:00:00 2001 From: MPR Date: Sat, 8 Nov 2014 18:13:19 +0000 Subject: [PATCH] add method to update format & buffersize --- inc/V4l2Capture.h | 5 ++++- src/V4l2Capture.cpp | 43 ++++++++++++++++++++++++++++++++----------- 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/inc/V4l2Capture.h b/inc/V4l2Capture.h index 6c9a2b8..45867bc 100644 --- a/inc/V4l2Capture.h +++ b/inc/V4l2Capture.h @@ -45,8 +45,10 @@ class V4l2Capture virtual ~V4l2Capture(); public: - int getBufferSize() { return m_bufferSize; }; int getFd() { return m_fd; }; + int getBufferSize() { return m_bufferSize; }; + int getFormat() { return m_format; } ; + void queryFormat(); protected: bool init(unsigned int mandatoryCapabilities); @@ -68,6 +70,7 @@ class V4l2Capture V4L2DeviceParameters m_params; int m_fd; int m_bufferSize; + int m_format; }; #endif diff --git a/src/V4l2Capture.cpp b/src/V4l2Capture.cpp index 560398a..ee1e31a 100644 --- a/src/V4l2Capture.cpp +++ b/src/V4l2Capture.cpp @@ -14,6 +14,7 @@ #include #include #include +#include // libv4l2 #include @@ -23,7 +24,7 @@ #include "V4l2Capture.h" // Constructor -V4l2Capture::V4l2Capture(V4L2DeviceParameters params) : m_params(params), m_fd(-1), m_bufferSize(0) +V4l2Capture::V4l2Capture(V4L2DeviceParameters params) : m_params(params), m_fd(-1), m_bufferSize(0), m_format(0) { } @@ -33,20 +34,21 @@ V4l2Capture::~V4l2Capture() if (m_fd !=-1) v4l2_close(m_fd); } -// intialize the source +// intialize the V4L2 connection bool V4l2Capture::init(unsigned int mandatoryCapabilities) { if (initdevice(m_params.m_devName.c_str(), mandatoryCapabilities) == -1) { - fprintf(stderr, "Init device:%s failure\n", m_params.m_devName.c_str()); + fprintf(stderr, "[%s] Init device:%s failure\n", __FILE__, m_params.m_devName.c_str()); } return (m_fd!=-1); } +// close the V4L2 connection void V4l2Capture::close() { - if (m_fd !=-1) v4l2_close(m_fd); + if (m_fd != -1) v4l2_close(m_fd); m_fd = -1; } @@ -86,14 +88,14 @@ int V4l2Capture::checkCapabilities(int fd, unsigned int mandatoryCapabilities) memset(&(cap), 0, sizeof(cap)); if (-1 == xioctl(fd, VIDIOC_QUERYCAP, &cap)) { - fprintf(stderr, "xioctl cannot get capabilities error %d, %s\n", errno, strerror(errno)); + fprintf(stderr, "[%s] xioctl cannot get capabilities error %d, %s\n", __FILE__, errno, strerror(errno)); return -1; } fprintf(stderr, "driver:%s capabilities;%X\n", cap.driver, cap.capabilities); if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { - fprintf(stderr, "%s is no video capture device\n", m_params.m_devName.c_str()); + fprintf(stderr, "[%s] the device '%s' doesnot support capture\n", __FILE__, m_params.m_devName.c_str()); return -1; } @@ -115,7 +117,7 @@ int V4l2Capture::configureFormat(int fd) { struct v4l2_format fmt; memset(&(fmt), 0, sizeof(fmt)); - fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmt.fmt.pix.width = m_params.m_width; fmt.fmt.pix.height = m_params.m_height; fmt.fmt.pix.pixelformat = m_params.m_format; @@ -123,12 +125,12 @@ int V4l2Capture::configureFormat(int fd) if (xioctl(fd, VIDIOC_S_FMT, &fmt) == -1) { - fprintf(stderr, "xioctl cannot set format error %d, %s\n", errno, strerror(errno)); + fprintf(stderr, "Cannot set format error %d, %s\n", errno, strerror(errno)); return -1; } if (fmt.fmt.pix.pixelformat != m_params.m_format) { - printf("Libv4l didn't accept format (%d). Can't proceed.\n", m_params.m_format); + printf("Error: format (%d) refused.\n", m_params.m_format); return -1; } if ((fmt.fmt.pix.width != m_params.m_width) || (fmt.fmt.pix.height != m_params.m_height)) @@ -136,7 +138,11 @@ int V4l2Capture::configureFormat(int fd) printf("Warning: driver is sending image at %dx%d\n", fmt.fmt.pix.width, fmt.fmt.pix.width); } - m_bufferSize = fmt.fmt.pix.sizeimage; + m_format = fmt.fmt.pix.pixelformat; + m_bufferSize = fmt.fmt.pix.sizeimage; + + fprintf(stderr, "[%s] bufferSize:%d\n", __FILE__, m_bufferSize); + return 0; } @@ -160,14 +166,29 @@ int V4l2Capture::configureParam(int fd) return 0; } + +// query current format +void V4l2Capture::queryFormat() +{ + struct v4l2_format fmt; + memset(&fmt,0,sizeof(fmt)); + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + if (0 == ioctl(m_fd,VIDIOC_G_FMT,&fmt)) // don't understand why xioctl give a different result + { + m_format = fmt.fmt.pix.pixelformat; + m_bufferSize = fmt.fmt.pix.sizeimage; + } +} + // ioctl encapsulation int V4l2Capture::xioctl(int fd, int request, void *arg) { int ret = -1; + errno=0; do { ret = v4l2_ioctl(fd, request, arg); - } while (ret == -1 && ((errno == EINTR) || (errno == EAGAIN))); + } while ((ret == -1) && ((errno == EINTR) || (errno == EAGAIN))); return ret; }