qv4l2: improve frequency and radio support.
authorHans Verkuil <hans.verkuil@cisco.com>
Sun, 10 Jun 2012 08:17:13 +0000 (10:17 +0200)
committerHans Verkuil <hans.verkuil@cisco.com>
Sun, 10 Jun 2012 08:17:13 +0000 (10:17 +0200)
Enter frequency in MHz (TV) or kHz (radio) rather than the v4l2_frequency value.

Disable/remove all video related items when a radio device is selected.

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

index 503c113..1541be0 100644 (file)
@@ -24,6 +24,8 @@
 #include <QSpinBox>
 #include <QComboBox>
 #include <QPushButton>
+#include <QLineEdit>
+#include <QDoubleValidator>
 
 #include <stdio.h>
 #include <errno.h>
@@ -34,6 +36,7 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent)
        m_row(0),
        m_col(0),
        m_cols(n),
+       m_isRadio(false),
        m_audioInput(NULL),
        m_tvStandard(NULL),
        m_qryStandard(NULL),
@@ -71,7 +74,10 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent)
        bool needsPreset = false;
        bool needsTimings = false;
 
-       if (enum_input(vin, true)) {
+       if (m_tuner.type && m_tuner.capability & V4L2_TUNER_CAP_LOW)
+               m_isRadio = true;
+
+       if (!isRadio() && enum_input(vin, true)) {
                addLabel("Input");
                m_videoInput = new QComboBox(parent);
                do {
@@ -88,7 +94,7 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent)
        }
 
        v4l2_output vout;
-       if (enum_output(vout, true)) {
+       if (!isRadio() && enum_output(vout, true)) {
                addLabel("Output");
                m_videoOutput = new QComboBox(parent);
                do {
@@ -100,7 +106,7 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent)
        }
 
        v4l2_audio vaudio;
-       if (enum_audio(vaudio, true)) {
+       if (!isRadio() && enum_audio(vaudio, true)) {
                addLabel("Input Audio");
                m_audioInput = new QComboBox(parent);
                do {
@@ -112,7 +118,7 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent)
        }
 
        v4l2_audioout vaudout;
-       if (enum_audout(vaudout, true)) {
+       if (!isRadio() && enum_audout(vaudout, true)) {
                addLabel("Output Audio");
                m_audioOutput = new QComboBox(parent);
                do {
@@ -160,32 +166,44 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent)
        }
 
        if (m_tuner.type) {
-               m_freq = new QSpinBox(parent);
-               m_freq->setMinimum(m_tuner.rangelow);
-               m_freq->setMaximum(m_tuner.rangehigh);
+               QDoubleValidator *val;
+               double factor = (m_tuner.capability & V4L2_TUNER_CAP_LOW) ? 16 : 16000;
+
+               val = new QDoubleValidator(m_tuner.rangelow / factor, m_tuner.rangehigh / factor, 3, parent);
+               m_freq = new QLineEdit(parent);
+               m_freq->setValidator(val);
                m_freq->setWhatsThis(QString("Frequency\nLow: %1\nHigh: %2")
-                               .arg(m_tuner.rangelow).arg(m_tuner.rangehigh));
-               connect(m_freq, SIGNAL(valueChanged(int)), SLOT(freqChanged(int)));
+                               .arg(m_tuner.rangelow / factor).arg(m_tuner.rangehigh / factor));
+               connect(m_freq, SIGNAL(lostFocus()), SLOT(freqChanged()));
+               connect(m_freq, SIGNAL(returnPressed()), SLOT(freqChanged()));
                updateFreq();
-               addLabel("Frequency");
+               if (m_tuner.capability & V4L2_TUNER_CAP_LOW)
+                       addLabel("Frequency (kHz)");
+               else
+                       addLabel("Frequency (MHz)");
                addWidget(m_freq);
 
-               addLabel("Frequency Table");
-               m_freqTable = new QComboBox(parent);
-               for (int i = 0; v4l2_channel_lists[i].name; i++) {
-                       m_freqTable->addItem(v4l2_channel_lists[i].name);
+               if (!m_tuner.capability & V4L2_TUNER_CAP_LOW) {
+                       addLabel("Frequency Table");
+                       m_freqTable = new QComboBox(parent);
+                       for (int i = 0; v4l2_channel_lists[i].name; i++) {
+                               m_freqTable->addItem(v4l2_channel_lists[i].name);
+                       }
+                       addWidget(m_freqTable);
+                       connect(m_freqTable, SIGNAL(activated(int)), SLOT(freqTableChanged(int)));
+
+                       addLabel("Channels");
+                       m_freqChannel = new QComboBox(parent);
+                       m_freqChannel->setSizeAdjustPolicy(QComboBox::AdjustToContents);
+                       addWidget(m_freqChannel);
+                       connect(m_freqChannel, SIGNAL(activated(int)), SLOT(freqChannelChanged(int)));
+                       updateFreqChannel();
                }
-               addWidget(m_freqTable);
-               connect(m_freqTable, SIGNAL(activated(int)), SLOT(freqTableChanged(int)));
-
-               addLabel("Channels");
-               m_freqChannel = new QComboBox(parent);
-               m_freqChannel->setSizeAdjustPolicy(QComboBox::AdjustToContents);
-               addWidget(m_freqChannel);
-               connect(m_freqChannel, SIGNAL(activated(int)), SLOT(freqChannelChanged(int)));
-               updateFreqChannel();
        }
 
+       if (isRadio())
+               goto done;
+
        v4l2_fmtdesc fmt;
        addLabel("Capture Image Formats");
        m_vidCapFormats = new QComboBox(parent);
@@ -268,6 +286,7 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent)
        }
        addWidget(m_capMethods);
 
+done:
        QGridLayout::addWidget(new QWidget(parent), rowCount(), 0, 1, n);
        setRowStretch(rowCount() - 1, 1);
 }
@@ -350,12 +369,17 @@ void GeneralTab::freqTableChanged(int)
 
 void GeneralTab::freqChannelChanged(int idx)
 {
-       m_freq->setValue((int)(v4l2_channel_lists[m_freqTable->currentIndex()].list[idx].freq / 62.5));
+       double f = v4l2_channel_lists[m_freqTable->currentIndex()].list[idx].freq;
+
+       m_freq->setText(QString::number(f / 1000.0));
+       freqChanged();
 }
 
-void GeneralTab::freqChanged(int val)
+void GeneralTab::freqChanged()
 {
-       s_frequency(val);
+       double f = m_freq->text().toDouble();
+
+       s_frequency(f * 16, m_tuner.capability & V4L2_TUNER_CAP_LOW);
 }
 
 void GeneralTab::vidCapFormatChanged(int idx)
@@ -680,7 +704,7 @@ void GeneralTab::updateFreq()
        g_frequency(f);
        /* m_freq listens to valueChanged block it to avoid recursion */
        m_freq->blockSignals(true);
-       m_freq->setValue(f.frequency);
+       m_freq->setText(QString::number(f.frequency / 16.0));
        m_freq->blockSignals(false);
 }
 
index d483d8f..e71c38a 100644 (file)
@@ -43,6 +43,7 @@ public:
        bool get_interval(struct v4l2_fract &interval);
        int width() const { return m_width; }
        int height() const { return m_height; }
+       bool isRadio() const { return m_isRadio; }
 
 private slots:
        void inputChanged(int);
@@ -57,7 +58,7 @@ private slots:
        void qryTimingsClicked();
        void freqTableChanged(int);
        void freqChannelChanged(int);
-       void freqChanged(int);
+       void freqChanged();
        void vidCapFormatChanged(int);
        void frameWidthChanged();
        void frameHeightChanged();
@@ -100,6 +101,7 @@ private:
        int m_row;
        int m_col;
        int m_cols;
+       bool m_isRadio;
        struct v4l2_tuner m_tuner;
        struct v4l2_capability m_querycap;
        __u32 m_pixelformat;
@@ -118,7 +120,7 @@ private:
        QPushButton *m_qryPreset;
        QComboBox *m_videoTimings;
        QPushButton *m_qryTimings;
-       QSpinBox  *m_freq;
+       QLineEdit *m_freq;
        QComboBox *m_freqTable;
        QComboBox *m_freqChannel;
        QComboBox *m_vidCapFormats;
index 336473c..059b03f 100644 (file)
@@ -154,7 +154,7 @@ void ApplicationWindow::setDevice(const QString &device, bool rawOpen)
        m_tabs->setFocus();
        m_convertData = v4lconvert_create(fd(), NULL,
                                          &libv4l2_default_dev_ops);
-       m_capStartAct->setEnabled(fd() >= 0);
+       m_capStartAct->setEnabled(fd() >= 0 && !m_genTab->isRadio());
 }
 
 void ApplicationWindow::opendev()
index 2252f60..04742b4 100644 (file)
@@ -263,12 +263,12 @@ bool v4l2::s_frequency(v4l2_frequency &freq)
        return ioctl("Set Frequency", VIDIOC_S_FREQUENCY, &freq);
 }
 
-bool v4l2::s_frequency(int val)
+bool v4l2::s_frequency(int val, bool low)
 {
        v4l2_frequency f;
 
        memset(&f, 0, sizeof(f));
-       f.type = V4L2_TUNER_ANALOG_TV;
+       f.type = low ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
        f.frequency = val;
        return s_frequency(f);
 }
index 4e1e52a..5376897 100644 (file)
@@ -78,7 +78,7 @@ public:
        bool query_dv_timings(v4l2_dv_timings &timings);
        bool g_frequency(v4l2_frequency &freq);
        bool s_frequency(v4l2_frequency &freq);
-       bool s_frequency(int freq);
+       bool s_frequency(int freq, bool low = false);
        bool g_fmt_cap(v4l2_format &fmt);
        bool g_fmt_out(v4l2_format &fmt);
        bool try_fmt(v4l2_format &fmt);