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
