From 407d14106a7877402f67744e0a623308b075e38b Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 10 Jun 2012 11:44:59 +0200 Subject: [PATCH] qv4l2: add support for radio modulators. Signed-off-by: Hans Verkuil --- utils/qv4l2/general-tab.cpp | 65 +++++++++++++++++++++++++++++++++++++++++++-- utils/qv4l2/general-tab.h | 6 +++++ utils/qv4l2/v4l2-api.cpp | 11 ++++++++ utils/qv4l2/v4l2-api.h | 2 ++ 4 files changed, 82 insertions(+), 2 deletions(-) diff --git a/utils/qv4l2/general-tab.cpp b/utils/qv4l2/general-tab.cpp index 784d19c..346a1ee 100644 --- a/utils/qv4l2/general-tab.cpp +++ b/utils/qv4l2/general-tab.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -68,13 +69,16 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent) } g_tuner(m_tuner); + g_modulator(m_modulator); v4l2_input vin; bool needsStd = false; bool needsPreset = false; bool needsTimings = false; - if (m_tuner.type && m_tuner.capability & V4L2_TUNER_CAP_LOW) + if (m_tuner.capability && m_tuner.capability & V4L2_TUNER_CAP_LOW) + m_isRadio = true; + if (m_modulator.capability && m_modulator.capability & V4L2_TUNER_CAP_LOW) m_isRadio = true; if (!isRadio() && enum_input(vin, true)) { @@ -165,7 +169,7 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent) connect(m_qryTimings, SIGNAL(clicked()), SLOT(qryTimingsClicked())); } - if (m_tuner.type) { + if (m_tuner.capability) { QDoubleValidator *val; double factor = (m_tuner.capability & V4L2_TUNER_CAP_LOW) ? 16 : 16000; @@ -235,6 +239,41 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent) detectSubchansClicked(); } + if (m_modulator.capability) { + QDoubleValidator *val; + double factor = (m_modulator.capability & V4L2_TUNER_CAP_LOW) ? 16 : 16000; + + val = new QDoubleValidator(m_modulator.rangelow / factor, m_modulator.rangehigh / factor, 3, parent); + m_freq = new QLineEdit(parent); + m_freq->setValidator(val); + m_freq->setWhatsThis(QString("Frequency\nLow: %1\nHigh: %2") + .arg(m_modulator.rangelow / factor).arg(m_modulator.rangehigh / factor)); + connect(m_freq, SIGNAL(lostFocus()), SLOT(freqChanged())); + connect(m_freq, SIGNAL(returnPressed()), SLOT(freqChanged())); + updateFreq(); + if (m_modulator.capability & V4L2_TUNER_CAP_LOW) + addLabel("Frequency (kHz)"); + else + addLabel("Frequency (MHz)"); + addWidget(m_freq); + if (m_modulator.capability & V4L2_TUNER_CAP_STEREO) { + addLabel("Stereo"); + m_stereoMode = new QCheckBox(parent); + m_stereoMode->setCheckState((m_modulator.txsubchans & V4L2_TUNER_SUB_STEREO) ? + Qt::Checked : Qt::Unchecked); + addWidget(m_stereoMode); + connect(m_stereoMode, SIGNAL(clicked()), SLOT(stereoModeChanged())); + } + if (m_modulator.capability & V4L2_TUNER_CAP_RDS) { + addLabel("RDS"); + m_rdsMode = new QCheckBox(parent); + m_rdsMode->setCheckState((m_modulator.txsubchans & V4L2_TUNER_SUB_RDS) ? + Qt::Checked : Qt::Unchecked); + addWidget(m_rdsMode); + connect(m_rdsMode, SIGNAL(clicked()), SLOT(rdsModeChanged())); + } + } + if (isRadio()) goto done; @@ -446,6 +485,28 @@ void GeneralTab::detectSubchansClicked() m_subchannels->setText(chans); } +void GeneralTab::stereoModeChanged() +{ + v4l2_modulator mod; + bool val = m_stereoMode->checkState() == Qt::Checked; + + g_modulator(mod); + mod.txsubchans &= ~(V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO); + mod.txsubchans |= val ? V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO; + s_modulator(mod); +} + +void GeneralTab::rdsModeChanged() +{ + v4l2_modulator mod; + bool val = m_rdsMode->checkState() == Qt::Checked; + + g_modulator(mod); + mod.txsubchans &= ~V4L2_TUNER_SUB_RDS; + mod.txsubchans |= val ? V4L2_TUNER_SUB_RDS : 0; + s_modulator(mod); +} + void GeneralTab::vidCapFormatChanged(int idx) { v4l2_fmtdesc desc; diff --git a/utils/qv4l2/general-tab.h b/utils/qv4l2/general-tab.h index 8805ed7..2d5ffa6 100644 --- a/utils/qv4l2/general-tab.h +++ b/utils/qv4l2/general-tab.h @@ -28,6 +28,7 @@ #include "v4l2-api.h" class QComboBox; +class QCheckBox; class QSpinBox; class QPushButton; @@ -61,6 +62,8 @@ private slots: void freqChanged(); void audioModeChanged(int); void detectSubchansClicked(); + void stereoModeChanged(); + void rdsModeChanged(); void vidCapFormatChanged(int); void frameWidthChanged(); void frameHeightChanged(); @@ -106,6 +109,7 @@ private: bool m_isRadio; __u32 m_audioModes[5]; struct v4l2_tuner m_tuner; + struct v4l2_modulator m_modulator; struct v4l2_capability m_querycap; __u32 m_pixelformat; __u32 m_width, m_height; @@ -128,6 +132,8 @@ private: QComboBox *m_freqChannel; QComboBox *m_audioMode; QLabel *m_subchannels; + QCheckBox *m_stereoMode; + QCheckBox *m_rdsMode; QPushButton *m_detectSubchans; QComboBox *m_vidCapFormats; QComboBox *m_frameSize; diff --git a/utils/qv4l2/v4l2-api.cpp b/utils/qv4l2/v4l2-api.cpp index 7df54e8..cf88eb5 100644 --- a/utils/qv4l2/v4l2-api.cpp +++ b/utils/qv4l2/v4l2-api.cpp @@ -149,6 +149,17 @@ bool v4l2::s_tuner(v4l2_tuner &tuner) return ioctl("Set Tuner", VIDIOC_S_TUNER, &tuner); } +bool v4l2::g_modulator(v4l2_modulator &modulator) +{ + memset(&modulator, 0, sizeof(modulator)); + return ioctl(VIDIOC_G_MODULATOR, &modulator) >= 0; +} + +bool v4l2::s_modulator(v4l2_modulator &modulator) +{ + return ioctl("Set Modulator", VIDIOC_S_MODULATOR, &modulator); +} + bool v4l2::g_input(int &input) { return ioctl(VIDIOC_G_INPUT, &input) >= 0; diff --git a/utils/qv4l2/v4l2-api.h b/utils/qv4l2/v4l2-api.h index d015909..a451268 100644 --- a/utils/qv4l2/v4l2-api.h +++ b/utils/qv4l2/v4l2-api.h @@ -60,6 +60,8 @@ public: bool querymenu(v4l2_querymenu &qm); bool g_tuner(v4l2_tuner &tuner); bool s_tuner(v4l2_tuner &tuner); + bool g_modulator(v4l2_modulator &modulator); + bool s_modulator(v4l2_modulator &modulator); bool g_input(int &input); bool s_input(int input); bool g_output(int &output); -- 2.7.4