This is an automatic generated email to let you know that the following patch 
were queued at the 
http://git.linuxtv.org/v4l-utils.git tree:

Subject: qv4l2: add support for sliced VBI.
Author:  Hans Verkuil <[email protected]>
Date:    Fri Jul 20 15:03:10 2012 +0200

Signed-off-by: Hans Verkuil <[email protected]>
(cherry picked from commit bd1648985f6ee275c5095e0847b5ede017dc57c1)

Signed-off-by: Gregor Jasny <[email protected]>

 utils/qv4l2/general-tab.cpp |   31 +++++++++++++++---
 utils/qv4l2/general-tab.h   |    3 ++
 utils/qv4l2/qv4l2.cpp       |   53 ++++++++++++++++++++++++-------
 utils/qv4l2/v4l2-api.cpp    |    7 ++++
 utils/qv4l2/v4l2-api.h      |    1 +
 utils/qv4l2/vbi-tab.cpp     |   74 +++++++++++++++++++++++++++++++++----------
 utils/qv4l2/vbi-tab.h       |    7 +++-
 7 files changed, 141 insertions(+), 35 deletions(-)

---

http://git.linuxtv.org/v4l-utils.git?a=commitdiff;h=1b09582e41b6714f644fd5cf9e282c87123a6d77

diff --git a/utils/qv4l2/general-tab.cpp b/utils/qv4l2/general-tab.cpp
index 2e1b224..88d54fb 100644
--- a/utils/qv4l2/general-tab.cpp
+++ b/utils/qv4l2/general-tab.cpp
@@ -49,7 +49,8 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int 
n, QWidget *parent)
        m_freq(NULL),
        m_vidCapFormats(NULL),
        m_frameSize(NULL),
-       m_vidOutFormats(NULL)
+       m_vidOutFormats(NULL),
+       m_vbiMethods(NULL)
 {
        setSpacing(3);
 
@@ -82,7 +83,7 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int 
n, QWidget *parent)
        if (m_modulator.capability && m_modulator.capability & 
V4L2_TUNER_CAP_LOW)
                m_isRadio = true;
        if (m_querycap.capabilities & V4L2_CAP_DEVICE_CAPS)
-               m_isVbi = caps() & V4L2_CAP_VBI_CAPTURE;
+               m_isVbi = caps() & (V4L2_CAP_VBI_CAPTURE | 
V4L2_CAP_SLICED_VBI_CAPTURE);
 
        if (!isRadio() && enum_input(vin, true)) {
                addLabel("Input");
@@ -280,8 +281,17 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, 
int n, QWidget *parent)
        if (isRadio())
                goto done;
 
-       if (isVbi())
+       if (isVbi()) {
+               addLabel("VBI Capture Method");
+               m_vbiMethods = new QComboBox(parent);
+               if (caps() & V4L2_CAP_VBI_CAPTURE)
+                       m_vbiMethods->addItem("Raw");
+               if (caps() & V4L2_CAP_SLICED_VBI_CAPTURE)
+                       m_vbiMethods->addItem("Sliced");
+               addWidget(m_vbiMethods);
+               connect(m_vbiMethods, SIGNAL(activated(int)), 
SLOT(vbiMethodsChanged(int)));
                goto capture_method;
+       }
 
        v4l2_fmtdesc fmt;
        addLabel("Capture Image Formats");
@@ -340,8 +350,8 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int 
n, QWidget *parent)
 capture_method:
        addLabel("Capture Method");
        m_capMethods = new QComboBox(parent);
-       m_buftype = isVbi() ? V4L2_BUF_TYPE_VBI_CAPTURE :
-               V4L2_BUF_TYPE_VIDEO_CAPTURE;
+       m_buftype = isSlicedVbi() ? V4L2_BUF_TYPE_SLICED_VBI_CAPTURE :
+               (isVbi() ? V4L2_BUF_TYPE_VBI_CAPTURE : 
V4L2_BUF_TYPE_VIDEO_CAPTURE);
        if (caps() & V4L2_CAP_STREAMING) {
                v4l2_requestbuffers reqbuf;
 
@@ -383,6 +393,11 @@ void GeneralTab::addWidget(QWidget *w, Qt::Alignment align)
        }
 }
 
+bool GeneralTab::isSlicedVbi() const
+{
+       return m_vbiMethods && m_vbiMethods->currentText() == "Sliced";
+}
+
 CapMethod GeneralTab::capMethod()
 {
        return 
(CapMethod)m_capMethods->itemData(m_capMethods->currentIndex()).toInt();
@@ -599,6 +614,12 @@ void GeneralTab::vidOutFormatChanged(int idx)
        updateVidOutFormat();
 }
 
+void GeneralTab::vbiMethodsChanged(int idx)
+{
+       m_buftype = isSlicedVbi() ? V4L2_BUF_TYPE_SLICED_VBI_CAPTURE :
+               (isVbi() ? V4L2_BUF_TYPE_VBI_CAPTURE : 
V4L2_BUF_TYPE_VIDEO_CAPTURE);
+}
+
 void GeneralTab::updateVideoInput()
 {
        int input;
diff --git a/utils/qv4l2/general-tab.h b/utils/qv4l2/general-tab.h
index e2681f4..85871ee 100644
--- a/utils/qv4l2/general-tab.h
+++ b/utils/qv4l2/general-tab.h
@@ -46,6 +46,7 @@ public:
        int height() const { return m_height; }
        bool isRadio() const { return m_isRadio; }
        bool isVbi() const { return m_isVbi; }
+       bool isSlicedVbi() const;
        __u32 bufType() const { return m_buftype; }
        inline bool reqbufs_mmap(v4l2_requestbuffers &reqbuf, int count = 0) {
                return v4l2::reqbufs_mmap(reqbuf, m_buftype, count);
@@ -92,6 +93,7 @@ private slots:
        void frameSizeChanged(int);
        void frameIntervalChanged(int);
        void vidOutFormatChanged(int);
+       void vbiMethodsChanged(int);
 
 private:
        void updateVideoInput();
@@ -166,6 +168,7 @@ private:
        QComboBox *m_frameInterval;
        QComboBox *m_vidOutFormats;
        QComboBox *m_capMethods;
+       QComboBox *m_vbiMethods;
 };
 
 #endif
diff --git a/utils/qv4l2/qv4l2.cpp b/utils/qv4l2/qv4l2.cpp
index 087f782..55eddb0 100644
--- a/utils/qv4l2/qv4l2.cpp
+++ b/utils/qv4l2/qv4l2.cpp
@@ -227,7 +227,7 @@ void ApplicationWindow::capVbiFrame()
                s = buf.bytesused;
                break;
        }
-       if (s != m_vbiSize) {
+       if (buftype == V4L2_BUF_TYPE_VBI_CAPTURE && s != m_vbiSize) {
                error("incorrect vbi size");
                m_capStartAct->setChecked(false);
                return;
@@ -247,13 +247,20 @@ void ApplicationWindow::capVbiFrame()
 
        struct v4l2_sliced_vbi_format sfmt;
        struct v4l2_sliced_vbi_data sdata[m_vbiHandle.count[0] + 
m_vbiHandle.count[1]];
-
-       vbi_parse(&m_vbiHandle, data, &sfmt, sdata);
+       struct v4l2_sliced_vbi_data *p;
+
+       if (buftype == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
+               p = (struct v4l2_sliced_vbi_data *)data;
+       } else {
+               vbi_parse(&m_vbiHandle, data, &sfmt, sdata);
+               s = sizeof(sdata);
+               p = sdata;
+       }
 
        if (m_capMethod != methodRead)
                qbuf(buf);
 
-       m_vbiTab->slicedData(sdata);
+       m_vbiTab->slicedData(p, s / sizeof(p[0]));
 
        QString status, curStatus;
        struct timeval tv, res;
@@ -583,6 +590,26 @@ void ApplicationWindow::capStart(bool start)
        m_frame = m_lastFrame = m_fps = 0;
        m_capMethod = m_genTab->capMethod();
 
+       if (m_genTab->isSlicedVbi()) {
+               v4l2_format fmt;
+               v4l2_std_id std;
+
+               m_showFrames = false;
+               g_fmt_sliced_vbi(fmt);
+               g_std(std);
+               fmt.fmt.sliced.service_set = (std & V4L2_STD_625_50) ?
+                       V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
+               s_fmt(fmt);
+               memset(&m_vbiHandle, 0, sizeof(m_vbiHandle));
+               m_vbiTab->slicedFormat(fmt.fmt.sliced);
+               m_vbiSize = fmt.fmt.sliced.io_size;
+               m_frameData = new unsigned char[m_vbiSize];
+               if (startCapture(m_vbiSize)) {
+                       m_capNotifier = new QSocketNotifier(fd(), 
QSocketNotifier::Read, m_tabs);
+                       connect(m_capNotifier, SIGNAL(activated(int)), this, 
SLOT(capVbiFrame()));
+               }
+               return;
+       }
        if (m_genTab->isVbi()) {
                v4l2_format fmt;
                v4l2_std_id std;
@@ -592,6 +619,7 @@ void ApplicationWindow::capStart(bool start)
                        error("non-grey pixelformat not supported for VBI\n");
                        return;
                }
+               s_fmt(fmt);
                g_std(std);
                if (!vbi_prepare(&m_vbiHandle, &fmt.fmt.vbi, std)) {
                        error("no services possible\n");
@@ -604,13 +632,14 @@ void ApplicationWindow::capStart(bool start)
                else
                        m_vbiHeight = fmt.fmt.vbi.count[0] + 
fmt.fmt.vbi.count[1];
                m_vbiSize = m_vbiWidth * m_vbiHeight;
-               if (m_showFrames)
-                       m_frameData = new unsigned char[m_vbiSize];
-               m_capture->setMinimumSize(m_vbiWidth, m_vbiHeight);
-               m_capImage = new QImage(m_vbiWidth, m_vbiHeight, dstFmt);
-               m_capImage->fill(0);
-               m_capture->setImage(*m_capImage, "No frame");
-               m_capture->show();
+               m_frameData = new unsigned char[m_vbiSize];
+               if (m_showFrames) {
+                       m_capture->setMinimumSize(m_vbiWidth, m_vbiHeight);
+                       m_capImage = new QImage(m_vbiWidth, m_vbiHeight, 
dstFmt);
+                       m_capImage->fill(0);
+                       m_capture->setImage(*m_capImage, "No frame");
+                       m_capture->show();
+               }
                statusBar()->showMessage("No frame");
                if (startCapture(m_vbiSize)) {
                        m_capNotifier = new QSocketNotifier(fd(), 
QSocketNotifier::Read, m_tabs);
@@ -625,8 +654,8 @@ void ApplicationWindow::capStart(bool start)
                set_interval(interval);
 
        m_mustConvert = m_showFrames;
+       m_frameData = new unsigned char[srcPix.sizeimage];
        if (m_showFrames) {
-               m_frameData = new unsigned char[srcPix.sizeimage];
                m_capDestFormat = m_capSrcFormat;
                dstPix.pixelformat = V4L2_PIX_FMT_RGB24;
 
diff --git a/utils/qv4l2/v4l2-api.cpp b/utils/qv4l2/v4l2-api.cpp
index fbdd9e4..86cf388 100644
--- a/utils/qv4l2/v4l2-api.cpp
+++ b/utils/qv4l2/v4l2-api.cpp
@@ -310,6 +310,13 @@ bool v4l2::g_fmt_vbi(v4l2_format &fmt)
        return ioctl(VIDIOC_G_FMT, &fmt) >= 0;
 }
 
+bool v4l2::g_fmt_sliced_vbi(v4l2_format &fmt)
+{
+       memset(&fmt, 0, sizeof(fmt));
+       fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
+       return ioctl(VIDIOC_G_FMT, &fmt) >= 0;
+}
+
 bool v4l2::try_fmt(v4l2_format &fmt)
 {
        fmt.fmt.pix.field = V4L2_FIELD_ANY;
diff --git a/utils/qv4l2/v4l2-api.h b/utils/qv4l2/v4l2-api.h
index 8067354..4c10466 100644
--- a/utils/qv4l2/v4l2-api.h
+++ b/utils/qv4l2/v4l2-api.h
@@ -85,6 +85,7 @@ public:
        bool g_fmt_cap(v4l2_format &fmt);
        bool g_fmt_out(v4l2_format &fmt);
        bool g_fmt_vbi(v4l2_format &fmt);
+       bool g_fmt_sliced_vbi(v4l2_format &fmt);
        bool try_fmt(v4l2_format &fmt);
        bool s_fmt(v4l2_format &fmt);
        bool enum_input(v4l2_input &in, bool init = false, int index = 0);
diff --git a/utils/qv4l2/vbi-tab.cpp b/utils/qv4l2/vbi-tab.cpp
index 92d0703..d40c65b 100644
--- a/utils/qv4l2/vbi-tab.cpp
+++ b/utils/qv4l2/vbi-tab.cpp
@@ -45,31 +45,53 @@ VbiTab::VbiTab(QWidget *parent) :
        addWidget(m_tableF2, 0, 1);
 }
 
-void VbiTab::rawFormat(const v4l2_vbi_format &fmt)
+void VbiTab::tableFormat()
 {
        QTableWidgetItem *item;
        QStringList q;
        unsigned i;
 
-       m_tableF1->setRowCount(fmt.count[0]);
-       m_tableF2->setRowCount(fmt.count[1]);
-       for (i = 0; i < fmt.count[0]; i++) {
+       m_tableF1->setRowCount(m_countF1);
+       m_tableF2->setRowCount(m_countF2);
+       for (i = 0; i < m_countF1; i++) {
                item = new QTableWidgetItem();
                item->setFlags(Qt::ItemIsEnabled);
                m_tableF1->setItem(i, 0, item);
-               q.append("Line " + QString::number(i + fmt.start[0]));
+               q.append("Line " + QString::number(i + m_startF1));
        }
        m_tableF1->setVerticalHeaderLabels(q);
        q.clear();
-       for (i = 0; i < fmt.count[1]; i++) {
+       for (i = 0; i < m_countF2; i++) {
                item = new QTableWidgetItem();
                item->setFlags(Qt::ItemIsEnabled);
                m_tableF2->setItem(i, 0, item);
-               q.append("Line " + QString::number(i + fmt.start[1]));
+               q.append("Line " + QString::number(i + m_startF2));
        }
        m_tableF2->setVerticalHeaderLabels(q);
 }
 
+void VbiTab::rawFormat(const v4l2_vbi_format &fmt)
+{
+
+       m_countF1 = fmt.count[0];
+       m_countF2 = fmt.count[1];
+       m_startF1 = fmt.start[0];
+       m_startF2 = fmt.start[1];
+       m_offsetF2 = m_startF2 >= 313 ? 313 : 263;
+       tableFormat();
+}
+
+void VbiTab::slicedFormat(const v4l2_sliced_vbi_format &fmt)
+{
+       bool is_625 = fmt.service_set & V4L2_SLICED_VBI_625;
+
+       m_startF1 = is_625 ? 6 : 10;
+       m_startF2 = is_625 ? 319 : 273;
+       m_offsetF2 = is_625 ? 313 : 263;
+       m_countF1 = m_countF2 = is_625 ? 18 : 12;
+       tableFormat();
+}
+
 static const char *formats[] = {
        "Full format 4:3, 576 lines",
        "Letterbox 14:9 centre, 504 lines",
@@ -350,18 +372,36 @@ static void setItem(QTableWidgetItem *item, const 
v4l2_sliced_vbi_data *data)
        }
 }
 
-void VbiTab::slicedData(const v4l2_sliced_vbi_data *data)
+void VbiTab::slicedData(const v4l2_sliced_vbi_data *data, unsigned elems)
 {
-       int i;
-
-       for (i = 0; i < m_tableF1->rowCount(); i++) {
-               QTableWidgetItem *item = m_tableF1->item(i, 0);
-
+       char found[m_countF1 + m_countF2];
+
+       memset(found, 0, m_countF1 + m_countF2);
+       for (unsigned i = 0; i < elems; i++) {
+               QTableWidgetItem *item;
+               
+               if (data[i].id == 0)
+                       continue;
+               if (data[i].field == 0) {
+                       if (data[i].line < m_startF1 ||
+                           data[i].line >= m_startF1 + m_countF1)
+                               continue;
+                       item = m_tableF1->item(data[i].line - m_startF1, 0);
+                       found[data[i].line - m_startF1] = 1;
+               } else {
+                       if (data[i].line + m_offsetF2 < m_startF2 ||
+                           data[i].line + m_offsetF2 >= m_startF2 + m_countF2)
+                               continue;
+                       item = m_tableF2->item(data[i].line + m_offsetF2 - 
m_startF2, 0);
+                       found[data[i].line + m_offsetF2 - m_startF2 + 
m_countF1] = 1;
+               }
                setItem(item, data + i);
        }
-       for (i = 0; i < m_tableF2->rowCount(); i++) {
-               QTableWidgetItem *item = m_tableF2->item(i, 0);
-
-               setItem(item, data + i + m_tableF1->rowCount());
+       for (unsigned i = 0; i < m_countF1 + m_countF2; i++) {
+               if (found[i])
+                       continue;
+               QTableWidgetItem *item = (i < m_countF1) ?
+                       m_tableF1->item(i, 0) : m_tableF2->item(i - m_countF1, 
0);
+               item->setText("");
        }
 }
diff --git a/utils/qv4l2/vbi-tab.h b/utils/qv4l2/vbi-tab.h
index 7950e0d..4ad730f 100644
--- a/utils/qv4l2/vbi-tab.h
+++ b/utils/qv4l2/vbi-tab.h
@@ -35,7 +35,8 @@ public:
        virtual ~VbiTab() {}
 
        void rawFormat(const v4l2_vbi_format &fmt);
-       void slicedData(const v4l2_sliced_vbi_data *data);
+       void slicedFormat(const v4l2_sliced_vbi_format &fmt);
+       void slicedData(const v4l2_sliced_vbi_data *data, unsigned elems);
 
 private:
        void info(const QString &info)
@@ -46,9 +47,13 @@ private:
        {
                g_mw->error(error);
        }
+       void tableFormat();
 
        QTableWidget *m_tableF1;
        QTableWidget *m_tableF2;
+       unsigned m_startF1, m_startF2;
+       unsigned m_countF1, m_countF2;
+       unsigned m_offsetF2;
 };
 
 #endif

_______________________________________________
linuxtv-commits mailing list
[email protected]
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits

Reply via email to