qv4l2: fix interval updating, use device_caps, handle conversion errors.
authorHans Verkuil <hans.verkuil@cisco.com>
Sun, 10 Jun 2012 07:31:58 +0000 (09:31 +0200)
committerHans Verkuil <hans.verkuil@cisco.com>
Sun, 10 Jun 2012 07:31:58 +0000 (09:31 +0200)
Choosing a new interval when capturing failed (of course), but the combobox
wasn't put back to the old position.

Now support device_caps for better capability reporting.

If a format can't be converted, then still memcpy it: that's better than a
black window.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
utils/qv4l2/general-tab.cpp
utils/qv4l2/qv4l2.cpp
utils/qv4l2/v4l2-api.h

index 7478b6b..503c113 100644 (file)
@@ -242,7 +242,7 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent)
 
        addLabel("Capture Method");
        m_capMethods = new QComboBox(parent);
-       if (m_querycap.capabilities & V4L2_CAP_STREAMING) {
+       if (caps() & V4L2_CAP_STREAMING) {
                v4l2_requestbuffers reqbuf;
 
                // Yuck. The videobuf framework does not accept a count of 0.
@@ -263,7 +263,7 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent)
                        reqbufs_mmap_cap(reqbuf, 0);
                }
        }
-       if (m_querycap.capabilities & V4L2_CAP_READWRITE) {
+       if (caps() & V4L2_CAP_READWRITE) {
                m_capMethods->addItem("read()", QVariant(methodRead));
        }
        addWidget(m_capMethods);
@@ -422,9 +422,10 @@ void GeneralTab::frameIntervalChanged(int idx)
 
        if (enum_frameintervals(frmival, m_pixelformat, m_width, m_height, idx)
            && frmival.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
-               set_interval(frmival.discrete);
-               m_interval = frmival.discrete;
+               if (set_interval(frmival.discrete))
+                       m_interval = frmival.discrete;
        }
+       updateVidCapFormat();
 }
 
 void GeneralTab::vidOutFormatChanged(int idx)
@@ -702,6 +703,7 @@ void GeneralTab::updateVidCapFormat()
        m_width       = fmt.fmt.pix.width;
        m_height      = fmt.fmt.pix.height;
        updateFrameSize();
+       updateFrameInterval();
        if (enum_fmt_cap(desc, true)) {
                do {
                        if (desc.pixelformat == fmt.fmt.pix.pixelformat)
index 1272a0d..336473c 100644 (file)
@@ -200,8 +200,8 @@ void ApplicationWindow::capFrame()
                        err = v4lconvert_convert(m_convertData, &m_capSrcFormat, &m_capDestFormat,
                                m_frameData, s,
                                m_capImage->bits(), m_capDestFormat.fmt.pix.sizeimage);
-               else
-                       memcpy(m_capImage->bits(), m_frameData, s);
+               if (!m_mustConvert || err)
+                       memcpy(m_capImage->bits(), m_frameData, std::min(s, m_capImage->numBytes()));
                break;
 
        case methodMmap:
@@ -219,10 +219,10 @@ void ApplicationWindow::capFrame()
                                        &m_capSrcFormat, &m_capDestFormat,
                                        (unsigned char *)m_buffers[buf.index].start, buf.bytesused,
                                        m_capImage->bits(), m_capDestFormat.fmt.pix.sizeimage);
-                       else
+                       if (!m_mustConvert || err)
                                memcpy(m_capImage->bits(),
                                       (unsigned char *)m_buffers[buf.index].start,
-                                      buf.bytesused);
+                                      std::min(buf.bytesused, (unsigned)m_capImage->numBytes()));
                }
 
                qbuf(buf);
@@ -243,15 +243,15 @@ void ApplicationWindow::capFrame()
                                        &m_capSrcFormat, &m_capDestFormat,
                                        (unsigned char *)buf.m.userptr, buf.bytesused,
                                        m_capImage->bits(), m_capDestFormat.fmt.pix.sizeimage);
-                       else
+                       if (!m_mustConvert || err)
                                memcpy(m_capImage->bits(), (unsigned char *)buf.m.userptr,
-                                       buf.bytesused);
+                                      std::min(buf.bytesused, (unsigned)m_capImage->numBytes()));
                }
 
                qbuf(buf);
                break;
        }
-       if (err == -1)
+       if (err == -1 && m_frame == 0)
                error(v4lconvert_get_error_message(m_convertData));
 
        QString status;
index b4876bc..4e1e52a 100644 (file)
@@ -45,7 +45,11 @@ public:
 
        inline int fd() const { return m_fd; }
        inline bool useWrapper() const { return m_useWrapper; }
-       inline __u32 caps() const { return m_capability.capabilities; }
+       inline __u32 caps() const {
+               if (m_capability.capabilities & V4L2_CAP_DEVICE_CAPS)
+                       return m_capability.device_caps;
+               return m_capability.capabilities;
+       }
        inline const QString &device() const { return m_device; }
        static QString pixfmt2s(unsigned pixelformat);