Initial copy of QtMultimediaKit.
Comes from original repo, with SHA1: 2c82d5611655e5967f5c5095af50c0991c4378b2
This commit is contained in:
29
src/plugins/v4l/radio/radio.pri
Normal file
29
src/plugins/v4l/radio/radio.pri
Normal file
@@ -0,0 +1,29 @@
|
||||
INCLUDEPATH += $$PWD
|
||||
|
||||
maemo5 {
|
||||
QT += dbus
|
||||
|
||||
CONFIG += link_pkgconfig
|
||||
|
||||
PKGCONFIG += gstreamer-0.10
|
||||
|
||||
LIBS += -lasound
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/v4lradiocontrol_maemo5.h \
|
||||
$$PWD/v4lradioservice.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/v4lradiocontrol_maemo5.cpp \
|
||||
$$PWD/v4lradioservice.cpp
|
||||
|
||||
} else {
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/v4lradiocontrol.h \
|
||||
$$PWD/v4lradioservice.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/v4lradiocontrol.cpp \
|
||||
$$PWD/v4lradioservice.cpp
|
||||
}
|
||||
538
src/plugins/v4l/radio/v4lradiocontrol.cpp
Normal file
538
src/plugins/v4l/radio/v4lradiocontrol.cpp
Normal file
@@ -0,0 +1,538 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the Qt Mobility Components.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "v4lradiocontrol.h"
|
||||
#include "v4lradioservice.h"
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include "linux/videodev2.h"
|
||||
|
||||
#include <sys/soundcard.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
V4LRadioControl::V4LRadioControl(QObject *parent)
|
||||
:QRadioTunerControl(parent)
|
||||
{
|
||||
fd = -1;
|
||||
initRadio();
|
||||
muted = false;
|
||||
stereo = false;
|
||||
m_error = false;
|
||||
sig = 0;
|
||||
currentBand = QRadioTuner::FM;
|
||||
step = 100000;
|
||||
scanning = false;
|
||||
playTime.restart();
|
||||
timer = new QTimer(this);
|
||||
timer->setInterval(200);
|
||||
connect(timer,SIGNAL(timeout()),this,SLOT(search()));
|
||||
timer->start();
|
||||
}
|
||||
|
||||
V4LRadioControl::~V4LRadioControl()
|
||||
{
|
||||
timer->stop();
|
||||
|
||||
if(fd > 0)
|
||||
::close(fd);
|
||||
}
|
||||
|
||||
bool V4LRadioControl::isAvailable() const
|
||||
{
|
||||
return available;
|
||||
}
|
||||
|
||||
QtMultimediaKit::AvailabilityError V4LRadioControl::availabilityError() const
|
||||
{
|
||||
if (fd > 0)
|
||||
return QtMultimediaKit::NoError;
|
||||
else
|
||||
return QtMultimediaKit::ResourceError;
|
||||
}
|
||||
|
||||
QRadioTuner::State V4LRadioControl::state() const
|
||||
{
|
||||
return fd > 0 ? QRadioTuner::ActiveState : QRadioTuner::StoppedState;
|
||||
}
|
||||
|
||||
QRadioTuner::Band V4LRadioControl::band() const
|
||||
{
|
||||
return currentBand;
|
||||
}
|
||||
|
||||
bool V4LRadioControl::isBandSupported(QRadioTuner::Band b) const
|
||||
{
|
||||
QRadioTuner::Band bnd = (QRadioTuner::Band)b;
|
||||
switch(bnd) {
|
||||
case QRadioTuner::FM:
|
||||
if(freqMin <= 87500000 && freqMax >= 108000000)
|
||||
return true;
|
||||
break;
|
||||
case QRadioTuner::LW:
|
||||
if(freqMin <= 148500 && freqMax >= 283500)
|
||||
return true;
|
||||
case QRadioTuner::AM:
|
||||
if(freqMin <= 520000 && freqMax >= 1610000)
|
||||
return true;
|
||||
default:
|
||||
if(freqMin <= 1711000 && freqMax >= 30000000)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void V4LRadioControl::setBand(QRadioTuner::Band b)
|
||||
{
|
||||
if(freqMin <= 87500000 && freqMax >= 108000000 && b == QRadioTuner::FM) {
|
||||
// FM 87.5 to 108.0 MHz, except Japan 76-90 MHz
|
||||
currentBand = (QRadioTuner::Band)b;
|
||||
step = 100000; // 100kHz steps
|
||||
emit bandChanged(currentBand);
|
||||
|
||||
} else if(freqMin <= 148500 && freqMax >= 283500 && b == QRadioTuner::LW) {
|
||||
// LW 148.5 to 283.5 kHz, 9kHz channel spacing (Europe, Africa, Asia)
|
||||
currentBand = (QRadioTuner::Band)b;
|
||||
step = 1000; // 1kHz steps
|
||||
emit bandChanged(currentBand);
|
||||
|
||||
} else if(freqMin <= 520000 && freqMax >= 1610000 && b == QRadioTuner::AM) {
|
||||
// AM 520 to 1610 kHz, 9 or 10kHz channel spacing, extended 1610 to 1710 kHz
|
||||
currentBand = (QRadioTuner::Band)b;
|
||||
step = 1000; // 1kHz steps
|
||||
emit bandChanged(currentBand);
|
||||
|
||||
} else if(freqMin <= 1711000 && freqMax >= 30000000 && b == QRadioTuner::SW) {
|
||||
// SW 1.711 to 30.0 MHz, divided into 15 bands. 5kHz channel spacing
|
||||
currentBand = (QRadioTuner::Band)b;
|
||||
step = 500; // 500Hz steps
|
||||
emit bandChanged(currentBand);
|
||||
}
|
||||
playTime.restart();
|
||||
}
|
||||
|
||||
int V4LRadioControl::frequency() const
|
||||
{
|
||||
return currentFreq;
|
||||
}
|
||||
|
||||
int V4LRadioControl::frequencyStep(QRadioTuner::Band b) const
|
||||
{
|
||||
int step = 0;
|
||||
|
||||
if(b == QRadioTuner::FM)
|
||||
step = 100000; // 100kHz steps
|
||||
else if(b == QRadioTuner::LW)
|
||||
step = 1000; // 1kHz steps
|
||||
else if(b == QRadioTuner::AM)
|
||||
step = 1000; // 1kHz steps
|
||||
else if(b == QRadioTuner::SW)
|
||||
step = 500; // 500Hz steps
|
||||
|
||||
return step;
|
||||
}
|
||||
|
||||
QPair<int,int> V4LRadioControl::frequencyRange(QRadioTuner::Band b) const
|
||||
{
|
||||
if(b == QRadioTuner::AM)
|
||||
return qMakePair<int,int>(520000,1710000);
|
||||
else if(b == QRadioTuner::FM)
|
||||
return qMakePair<int,int>(87500000,108000000);
|
||||
else if(b == QRadioTuner::SW)
|
||||
return qMakePair<int,int>(1711111,30000000);
|
||||
else if(b == QRadioTuner::LW)
|
||||
return qMakePair<int,int>(148500,283500);
|
||||
|
||||
return qMakePair<int,int>(0,0);
|
||||
}
|
||||
|
||||
void V4LRadioControl::setFrequency(int frequency)
|
||||
{
|
||||
qint64 f = frequency;
|
||||
|
||||
v4l2_frequency freq;
|
||||
|
||||
if(frequency < freqMin)
|
||||
f = freqMax;
|
||||
if(frequency > freqMax)
|
||||
f = freqMin;
|
||||
|
||||
if(fd > 0) {
|
||||
memset( &freq, 0, sizeof( freq ) );
|
||||
// Use the first tuner
|
||||
freq.tuner = 0;
|
||||
if ( ioctl( fd, VIDIOC_G_FREQUENCY, &freq ) >= 0 ) {
|
||||
if(low) {
|
||||
// For low, freq in units of 62.5Hz, so convert from Hz to units.
|
||||
freq.frequency = (int)(f/62.5);
|
||||
} else {
|
||||
// For high, freq in units of 62.5kHz, so convert from Hz to units.
|
||||
freq.frequency = (int)(f/62500);
|
||||
}
|
||||
ioctl( fd, VIDIOC_S_FREQUENCY, &freq );
|
||||
currentFreq = f;
|
||||
playTime.restart();
|
||||
emit frequencyChanged(currentFreq);
|
||||
}
|
||||
}
|
||||
playTime.restart();
|
||||
}
|
||||
|
||||
bool V4LRadioControl::isStereo() const
|
||||
{
|
||||
return stereo;
|
||||
}
|
||||
|
||||
QRadioTuner::StereoMode V4LRadioControl::stereoMode() const
|
||||
{
|
||||
return QRadioTuner::Auto;
|
||||
}
|
||||
|
||||
void V4LRadioControl::setStereoMode(QRadioTuner::StereoMode mode)
|
||||
{
|
||||
bool stereo = true;
|
||||
|
||||
if(mode == QRadioTuner::ForceMono)
|
||||
stereo = false;
|
||||
|
||||
v4l2_tuner tuner;
|
||||
|
||||
memset( &tuner, 0, sizeof( tuner ) );
|
||||
|
||||
if ( ioctl( fd, VIDIOC_G_TUNER, &tuner ) >= 0 ) {
|
||||
if(stereo)
|
||||
tuner.audmode = V4L2_TUNER_MODE_STEREO;
|
||||
else
|
||||
tuner.audmode = V4L2_TUNER_MODE_MONO;
|
||||
|
||||
if ( ioctl( fd, VIDIOC_S_TUNER, &tuner ) >= 0 ) {
|
||||
emit stereoStatusChanged(stereo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int V4LRadioControl::signalStrength() const
|
||||
{
|
||||
v4l2_tuner tuner;
|
||||
|
||||
// Return the first tuner founds signal strength.
|
||||
for ( int index = 0; index < tuners; ++index ) {
|
||||
memset( &tuner, 0, sizeof( tuner ) );
|
||||
tuner.index = index;
|
||||
if ( ioctl( fd, VIDIOC_G_TUNER, &tuner ) < 0 )
|
||||
continue;
|
||||
if ( tuner.type != V4L2_TUNER_RADIO )
|
||||
continue;
|
||||
// percentage signal strength
|
||||
return tuner.signal*100/65535;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int V4LRadioControl::volume() const
|
||||
{
|
||||
v4l2_queryctrl queryctrl;
|
||||
|
||||
if(fd > 0) {
|
||||
memset( &queryctrl, 0, sizeof( queryctrl ) );
|
||||
queryctrl.id = V4L2_CID_AUDIO_VOLUME;
|
||||
if ( ioctl( fd, VIDIOC_QUERYCTRL, &queryctrl ) >= 0 ) {
|
||||
if(queryctrl.maximum == 0) {
|
||||
return vol;
|
||||
} else {
|
||||
// percentage volume returned
|
||||
return queryctrl.default_value*100/queryctrl.maximum;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void V4LRadioControl::setVolume(int volume)
|
||||
{
|
||||
v4l2_queryctrl queryctrl;
|
||||
|
||||
if(fd > 0) {
|
||||
memset( &queryctrl, 0, sizeof( queryctrl ) );
|
||||
queryctrl.id = V4L2_CID_AUDIO_VOLUME;
|
||||
if ( ioctl( fd, VIDIOC_QUERYCTRL, &queryctrl ) >= 0 ) {
|
||||
v4l2_control control;
|
||||
|
||||
if(queryctrl.maximum > 0) {
|
||||
memset( &control, 0, sizeof( control ) );
|
||||
control.id = V4L2_CID_AUDIO_VOLUME;
|
||||
control.value = volume*queryctrl.maximum/100;
|
||||
ioctl( fd, VIDIOC_S_CTRL, &control );
|
||||
} else {
|
||||
setVol(volume);
|
||||
}
|
||||
emit volumeChanged(volume);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool V4LRadioControl::isMuted() const
|
||||
{
|
||||
return muted;
|
||||
}
|
||||
|
||||
void V4LRadioControl::setMuted(bool muted)
|
||||
{
|
||||
v4l2_queryctrl queryctrl;
|
||||
|
||||
if(fd > 0) {
|
||||
memset( &queryctrl, 0, sizeof( queryctrl ) );
|
||||
queryctrl.id = V4L2_CID_AUDIO_MUTE;
|
||||
if ( ioctl( fd, VIDIOC_QUERYCTRL, &queryctrl ) >= 0 ) {
|
||||
v4l2_control control;
|
||||
memset( &control, 0, sizeof( control ) );
|
||||
control.id = V4L2_CID_AUDIO_MUTE;
|
||||
control.value = (muted ? queryctrl.maximum : queryctrl.minimum );
|
||||
ioctl( fd, VIDIOC_S_CTRL, &control );
|
||||
this->muted = muted;
|
||||
emit mutedChanged(muted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool V4LRadioControl::isSearching() const
|
||||
{
|
||||
return scanning;
|
||||
}
|
||||
|
||||
void V4LRadioControl::cancelSearch()
|
||||
{
|
||||
scanning = false;
|
||||
timer->stop();
|
||||
}
|
||||
|
||||
void V4LRadioControl::searchForward()
|
||||
{
|
||||
// Scan up
|
||||
if(scanning) {
|
||||
cancelSearch();
|
||||
return;
|
||||
}
|
||||
scanning = true;
|
||||
forward = true;
|
||||
timer->start();
|
||||
}
|
||||
|
||||
void V4LRadioControl::searchBackward()
|
||||
{
|
||||
// Scan down
|
||||
if(scanning) {
|
||||
cancelSearch();
|
||||
return;
|
||||
}
|
||||
scanning = true;
|
||||
forward = false;
|
||||
timer->start();
|
||||
}
|
||||
|
||||
void V4LRadioControl::start()
|
||||
{
|
||||
}
|
||||
|
||||
void V4LRadioControl::stop()
|
||||
{
|
||||
}
|
||||
|
||||
QRadioTuner::Error V4LRadioControl::error() const
|
||||
{
|
||||
if(m_error)
|
||||
return QRadioTuner::OpenError;
|
||||
|
||||
return QRadioTuner::NoError;
|
||||
}
|
||||
|
||||
QString V4LRadioControl::errorString() const
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
void V4LRadioControl::search()
|
||||
{
|
||||
int signal = signalStrength();
|
||||
if(sig != signal) {
|
||||
sig = signal;
|
||||
emit signalStrengthChanged(sig);
|
||||
}
|
||||
|
||||
if(!scanning) return;
|
||||
|
||||
if (signal > 25) {
|
||||
cancelSearch();
|
||||
return;
|
||||
}
|
||||
|
||||
if(forward) {
|
||||
setFrequency(currentFreq+step);
|
||||
} else {
|
||||
setFrequency(currentFreq-step);
|
||||
}
|
||||
}
|
||||
|
||||
bool V4LRadioControl::initRadio()
|
||||
{
|
||||
v4l2_tuner tuner;
|
||||
v4l2_input input;
|
||||
v4l2_frequency freq;
|
||||
v4l2_capability cap;
|
||||
|
||||
low = false;
|
||||
available = false;
|
||||
freqMin = freqMax = currentFreq = 0;
|
||||
|
||||
fd = ::open("/dev/radio0", O_RDWR);
|
||||
|
||||
if(fd != -1) {
|
||||
// Capabilities
|
||||
memset( &cap, 0, sizeof( cap ) );
|
||||
if(::ioctl(fd, VIDIOC_QUERYCAP, &cap ) >= 0) {
|
||||
if(((cap.capabilities & V4L2_CAP_RADIO) == 0) && ((cap.capabilities & V4L2_CAP_AUDIO) == 0))
|
||||
available = true;
|
||||
}
|
||||
|
||||
// Tuners
|
||||
memset( &input, 0, sizeof( input ) );
|
||||
tuners = 0;
|
||||
for ( ;; ) {
|
||||
memset( &input, 0, sizeof( input ) );
|
||||
input.index = tuners;
|
||||
if ( ioctl( fd, VIDIOC_ENUMINPUT, &input ) < 0 )
|
||||
break;
|
||||
++tuners;
|
||||
}
|
||||
|
||||
// Freq bands
|
||||
for ( int index = 0; index < tuners; ++index ) {
|
||||
memset( &tuner, 0, sizeof( tuner ) );
|
||||
tuner.index = index;
|
||||
if ( ioctl( fd, VIDIOC_G_TUNER, &tuner ) < 0 )
|
||||
continue;
|
||||
if ( tuner.type != V4L2_TUNER_RADIO )
|
||||
continue;
|
||||
if ( ( tuner.capability & V4L2_TUNER_CAP_LOW ) != 0 ) {
|
||||
// Units are 1/16th of a kHz.
|
||||
low = true;
|
||||
}
|
||||
if(low) {
|
||||
freqMin = tuner.rangelow * 62.5;
|
||||
freqMax = tuner.rangehigh * 62.5;
|
||||
} else {
|
||||
freqMin = tuner.rangelow * 62500;
|
||||
freqMax = tuner.rangehigh * 62500;
|
||||
}
|
||||
}
|
||||
|
||||
// frequency
|
||||
memset( &freq, 0, sizeof( freq ) );
|
||||
if(::ioctl(fd, VIDIOC_G_FREQUENCY, &freq ) >= 0) {
|
||||
if ( ((int)freq.frequency) != -1 ) { // -1 means not set.
|
||||
if(low)
|
||||
currentFreq = freq.frequency * 62.5;
|
||||
else
|
||||
currentFreq = freq.frequency * 62500;
|
||||
}
|
||||
}
|
||||
|
||||
// stereo
|
||||
bool stereo = false;
|
||||
memset( &tuner, 0, sizeof( tuner ) );
|
||||
if ( ioctl( fd, VIDIOC_G_TUNER, &tuner ) >= 0 ) {
|
||||
if((tuner.rxsubchans & V4L2_TUNER_SUB_STEREO) != 0)
|
||||
stereo = true;
|
||||
}
|
||||
|
||||
vol = getVol();
|
||||
|
||||
return true;
|
||||
}
|
||||
m_error = true;
|
||||
emit error();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void V4LRadioControl::setVol(int v)
|
||||
{
|
||||
int fd = ::open( "/dev/mixer", O_RDWR, 0 );
|
||||
if ( fd < 0 )
|
||||
return;
|
||||
int volume = v;
|
||||
if ( volume < 0 )
|
||||
volume = 0;
|
||||
else if ( volume > 100 )
|
||||
volume = 100;
|
||||
vol = volume;
|
||||
volume += volume << 8;
|
||||
::ioctl( fd, MIXER_WRITE(SOUND_MIXER_VOLUME), &volume );
|
||||
::close( fd );
|
||||
}
|
||||
|
||||
int V4LRadioControl::getVol()
|
||||
{
|
||||
int fd = ::open( "/dev/mixer", O_RDWR, 0 );
|
||||
if ( fd >= 0 ) {
|
||||
int volume = 0;
|
||||
::ioctl( fd, MIXER_READ(SOUND_MIXER_VOLUME), &volume );
|
||||
int left = ( volume & 0xFF );
|
||||
int right = ( ( volume >> 8 ) & 0xFF );
|
||||
if ( left > right )
|
||||
vol = left;
|
||||
else
|
||||
vol = right;
|
||||
::close( fd );
|
||||
return vol;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
134
src/plugins/v4l/radio/v4lradiocontrol.h
Normal file
134
src/plugins/v4l/radio/v4lradiocontrol.h
Normal file
@@ -0,0 +1,134 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the Qt Mobility Components.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef V4LRADIOCONTROL_H
|
||||
#define V4LRADIOCONTROL_H
|
||||
|
||||
#include <QtCore/qobject.h>
|
||||
#include <QtCore/qtimer.h>
|
||||
#include <QtCore/qdatetime.h>
|
||||
|
||||
#include <qradiotunercontrol.h>
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/videodev2.h>
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class V4LRadioService;
|
||||
|
||||
class V4LRadioControl : public QRadioTunerControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
V4LRadioControl(QObject *parent = 0);
|
||||
~V4LRadioControl();
|
||||
|
||||
bool isAvailable() const;
|
||||
QtMultimediaKit::AvailabilityError availabilityError() const;
|
||||
|
||||
QRadioTuner::State state() const;
|
||||
|
||||
QRadioTuner::Band band() const;
|
||||
void setBand(QRadioTuner::Band b);
|
||||
bool isBandSupported(QRadioTuner::Band b) const;
|
||||
|
||||
int frequency() const;
|
||||
int frequencyStep(QRadioTuner::Band b) const;
|
||||
QPair<int,int> frequencyRange(QRadioTuner::Band b) const;
|
||||
void setFrequency(int frequency);
|
||||
|
||||
bool isStereo() const;
|
||||
QRadioTuner::StereoMode stereoMode() const;
|
||||
void setStereoMode(QRadioTuner::StereoMode mode);
|
||||
|
||||
int signalStrength() const;
|
||||
|
||||
int volume() const;
|
||||
void setVolume(int volume);
|
||||
|
||||
bool isMuted() const;
|
||||
void setMuted(bool muted);
|
||||
|
||||
bool isSearching() const;
|
||||
void cancelSearch();
|
||||
|
||||
void searchForward();
|
||||
void searchBackward();
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
QRadioTuner::Error error() const;
|
||||
QString errorString() const;
|
||||
|
||||
private slots:
|
||||
void search();
|
||||
|
||||
private:
|
||||
bool initRadio();
|
||||
void setVol(int v);
|
||||
int getVol();
|
||||
|
||||
int fd;
|
||||
|
||||
bool m_error;
|
||||
bool muted;
|
||||
bool stereo;
|
||||
bool low;
|
||||
bool available;
|
||||
int tuners;
|
||||
int step;
|
||||
int vol;
|
||||
int sig;
|
||||
bool scanning;
|
||||
bool forward;
|
||||
QTimer* timer;
|
||||
QRadioTuner::Band currentBand;
|
||||
qint64 freqMin;
|
||||
qint64 freqMax;
|
||||
qint64 currentFreq;
|
||||
QTime playTime;
|
||||
};
|
||||
|
||||
#endif
|
||||
755
src/plugins/v4l/radio/v4lradiocontrol_maemo5.cpp
Normal file
755
src/plugins/v4l/radio/v4lradiocontrol_maemo5.cpp
Normal file
@@ -0,0 +1,755 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the Qt Mobility Components.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "v4lradiocontrol_maemo5.h"
|
||||
#include "v4lradioservice.h"
|
||||
|
||||
#include "linux/videodev2.h"
|
||||
#include <linux/videodev.h>
|
||||
#include <sys/soundcard.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define HEADPHONE_STATE_FILE "/sys/devices/platform/gpio-switch/headphone/state"
|
||||
#define HEADPHONE_CONNECTED_STATE "connected"
|
||||
#define HEADPHONE_DISCONNECTED_STATE "disconnected"
|
||||
|
||||
#define FMRXENABLER_DBUS_SERVICE "de.pycage.FMRXEnabler"
|
||||
#define FMRXENABLER_DBUS_OBJ_PATH "/de/pycage/FMRXEnabler"
|
||||
#define FMRXENABLER_DBUS_IFACE_NAME "de.pycage.FMRXEnabler"
|
||||
|
||||
gboolean
|
||||
state_file_changed(GIOChannel* source, GIOCondition /*condition*/, gpointer data)
|
||||
{
|
||||
V4LRadioControl* radioControl = (V4LRadioControl*)data;
|
||||
gchar* result;
|
||||
|
||||
g_io_channel_seek_position(source, 0, G_SEEK_SET, NULL);
|
||||
g_io_channel_read_line(source, &result, NULL, NULL, NULL);
|
||||
g_strstrip(result);
|
||||
|
||||
if (g_ascii_strcasecmp(result, HEADPHONE_DISCONNECTED_STATE) == 0) {
|
||||
radioControl->enablePipeline(false);
|
||||
} else if (g_ascii_strcasecmp(result, HEADPHONE_CONNECTED_STATE) == 0) {
|
||||
// Wait 400ms until audio is routed again to headphone to prevent sound coming from speakers
|
||||
QTimer::singleShot(400,radioControl,SLOT(enablePipeline()));
|
||||
}
|
||||
|
||||
#ifdef MULTIMEDIA_MAEMO_DEBUG
|
||||
qDebug() << "Headphone is now" << result;
|
||||
#endif
|
||||
|
||||
g_free(result);
|
||||
return true;
|
||||
}
|
||||
|
||||
V4LRadioControl::V4LRadioControl(QObject *parent)
|
||||
: QRadioTunerControl(parent)
|
||||
, fd(1)
|
||||
, m_error(false)
|
||||
, muted(false)
|
||||
, stereo(false)
|
||||
, step(100000)
|
||||
, sig(0)
|
||||
, scanning(false)
|
||||
, currentBand(QRadioTuner::FM)
|
||||
, pipeline(0)
|
||||
{
|
||||
if (QDBusConnection::systemBus().isConnected()) {
|
||||
FMRXEnablerIFace = new QDBusInterface(FMRXENABLER_DBUS_SERVICE,
|
||||
FMRXENABLER_DBUS_OBJ_PATH,
|
||||
FMRXENABLER_DBUS_IFACE_NAME,
|
||||
QDBusConnection::systemBus());
|
||||
}
|
||||
|
||||
createGstPipeline();
|
||||
|
||||
GIOChannel* headphoneStateFile = NULL;
|
||||
headphoneStateFile = g_io_channel_new_file(HEADPHONE_STATE_FILE, "r", NULL);
|
||||
if (headphoneStateFile != NULL) {
|
||||
g_io_add_watch(headphoneStateFile, G_IO_PRI, state_file_changed, this);
|
||||
} else {
|
||||
#ifdef MULTIMEDIA_MAEMO_DEBUG
|
||||
qWarning() << QString("File %1 can't be read!").arg(HEADPHONE_STATE_FILE) ;
|
||||
qWarning() << "Monitoring headphone state isn't possible!";
|
||||
#endif
|
||||
}
|
||||
|
||||
enableFMRX();
|
||||
initRadio();
|
||||
setupHeadPhone();
|
||||
|
||||
setMuted(false);
|
||||
|
||||
timer = new QTimer(this);
|
||||
timer->setInterval(200);
|
||||
connect(timer,SIGNAL(timeout()),this,SLOT(search()));
|
||||
|
||||
tickTimer = new QTimer(this);
|
||||
tickTimer->setInterval(10000);
|
||||
connect(tickTimer,SIGNAL(timeout()),this,SLOT(enableFMRX()));
|
||||
tickTimer->start();
|
||||
}
|
||||
|
||||
V4LRadioControl::~V4LRadioControl()
|
||||
{
|
||||
if (pipeline)
|
||||
{
|
||||
gst_element_set_state (pipeline, GST_STATE_NULL);
|
||||
gst_object_unref (GST_OBJECT (pipeline));
|
||||
}
|
||||
|
||||
if(fd > 0)
|
||||
::close(fd);
|
||||
}
|
||||
|
||||
void V4LRadioControl::enablePipeline(bool enable)
|
||||
{
|
||||
if (enable == true)
|
||||
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
||||
else
|
||||
gst_element_set_state (pipeline, GST_STATE_NULL);
|
||||
}
|
||||
|
||||
void V4LRadioControl::enableFMRX()
|
||||
{
|
||||
if (FMRXEnablerIFace && FMRXEnablerIFace->isValid()) {
|
||||
FMRXEnablerIFace->call("request"); // Return value ignored
|
||||
}
|
||||
}
|
||||
|
||||
// Workaround to capture sound from the PGA line and play it back using gstreamer
|
||||
// because N900 doesn't output sound directly to speakers
|
||||
bool V4LRadioControl::createGstPipeline()
|
||||
{
|
||||
GstElement *source, *sink;
|
||||
|
||||
gst_init (NULL, NULL);
|
||||
pipeline = gst_pipeline_new("my-pipeline");
|
||||
|
||||
source = gst_element_factory_make ("pulsesrc", "source");
|
||||
sink = gst_element_factory_make ("pulsesink", "sink");
|
||||
|
||||
gst_bin_add_many (GST_BIN (pipeline), source, sink, (char *)NULL);
|
||||
|
||||
if (!gst_element_link_many (source, sink, (char *)NULL)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool V4LRadioControl::isAvailable() const
|
||||
{
|
||||
return available;
|
||||
}
|
||||
|
||||
QtMultimediaKit::AvailabilityError V4LRadioControl::availabilityError() const
|
||||
{
|
||||
if (fd > 0)
|
||||
return QtMultimediaKit::NoError;
|
||||
else
|
||||
return QtMultimediaKit::ResourceError;
|
||||
}
|
||||
|
||||
QRadioTuner::State V4LRadioControl::state() const
|
||||
{
|
||||
return fd > 0 ? QRadioTuner::ActiveState : QRadioTuner::StoppedState;
|
||||
}
|
||||
|
||||
QRadioTuner::Band V4LRadioControl::band() const
|
||||
{
|
||||
return currentBand;
|
||||
}
|
||||
|
||||
bool V4LRadioControl::isBandSupported(QRadioTuner::Band b) const
|
||||
{
|
||||
QRadioTuner::Band bnd = (QRadioTuner::Band)b;
|
||||
switch(bnd) {
|
||||
case QRadioTuner::FM:
|
||||
if(freqMin <= 87500000 && freqMax >= 108000000)
|
||||
return true;
|
||||
break;
|
||||
case QRadioTuner::LW:
|
||||
if(freqMin <= 148500 && freqMax >= 283500)
|
||||
return true;
|
||||
case QRadioTuner::AM:
|
||||
if(freqMin <= 520000 && freqMax >= 1610000)
|
||||
return true;
|
||||
default:
|
||||
if(freqMin <= 1711000 && freqMax >= 30000000)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void V4LRadioControl::setBand(QRadioTuner::Band b)
|
||||
{
|
||||
if(freqMin <= 87500000 && freqMax >= 108000000 && b == QRadioTuner::FM) {
|
||||
// FM 87.5 to 108.0 MHz, except Japan 76-90 MHz
|
||||
currentBand = (QRadioTuner::Band)b;
|
||||
step = 100000; // 100kHz steps
|
||||
emit bandChanged(currentBand);
|
||||
|
||||
} else if(freqMin <= 148500 && freqMax >= 283500 && b == QRadioTuner::LW) {
|
||||
// LW 148.5 to 283.5 kHz, 9kHz channel spacing (Europe, Africa, Asia)
|
||||
currentBand = (QRadioTuner::Band)b;
|
||||
step = 1000; // 1kHz steps
|
||||
emit bandChanged(currentBand);
|
||||
|
||||
} else if(freqMin <= 520000 && freqMax >= 1610000 && b == QRadioTuner::AM) {
|
||||
// AM 520 to 1610 kHz, 9 or 10kHz channel spacing, extended 1610 to 1710 kHz
|
||||
currentBand = (QRadioTuner::Band)b;
|
||||
step = 1000; // 1kHz steps
|
||||
emit bandChanged(currentBand);
|
||||
|
||||
} else if(freqMin <= 1711000 && freqMax >= 30000000 && b == QRadioTuner::SW) {
|
||||
// SW 1.711 to 30.0 MHz, divided into 15 bands. 5kHz channel spacing
|
||||
currentBand = (QRadioTuner::Band)b;
|
||||
step = 500; // 500Hz steps
|
||||
emit bandChanged(currentBand);
|
||||
}
|
||||
}
|
||||
|
||||
int V4LRadioControl::frequency() const
|
||||
{
|
||||
return currentFreq;
|
||||
}
|
||||
|
||||
int V4LRadioControl::frequencyStep(QRadioTuner::Band b) const
|
||||
{
|
||||
int step = 0;
|
||||
|
||||
if(b == QRadioTuner::FM)
|
||||
step = 100000; // 100kHz steps
|
||||
else if(b == QRadioTuner::LW)
|
||||
step = 1000; // 1kHz steps
|
||||
else if(b == QRadioTuner::AM)
|
||||
step = 1000; // 1kHz steps
|
||||
else if(b == QRadioTuner::SW)
|
||||
step = 500; // 500Hz steps
|
||||
|
||||
return step;
|
||||
}
|
||||
|
||||
QPair<int,int> V4LRadioControl::frequencyRange(QRadioTuner::Band b) const
|
||||
{
|
||||
if(b == QRadioTuner::AM)
|
||||
return qMakePair<int,int>(520000,1710000);
|
||||
else if(b == QRadioTuner::FM)
|
||||
return qMakePair<int,int>(87500000,108000000);
|
||||
else if(b == QRadioTuner::SW)
|
||||
return qMakePair<int,int>(1711111,30000000);
|
||||
else if(b == QRadioTuner::LW)
|
||||
return qMakePair<int,int>(148500,283500);
|
||||
|
||||
return qMakePair<int,int>(0,0);
|
||||
}
|
||||
|
||||
void V4LRadioControl::setFrequency(int frequency)
|
||||
{
|
||||
qint64 f = frequency;
|
||||
|
||||
v4l2_frequency freq;
|
||||
|
||||
if(frequency < freqMin)
|
||||
f = freqMax;
|
||||
if(frequency > freqMax)
|
||||
f = freqMin;
|
||||
|
||||
if(fd > 0) {
|
||||
memset(&freq, 0, sizeof(freq));
|
||||
// Use the first tuner
|
||||
freq.tuner = 0;
|
||||
if (::ioctl(fd, VIDIOC_G_FREQUENCY, &freq) >= 0) {
|
||||
if(low) {
|
||||
// For low, freq in units of 62.5Hz, so convert from Hz to units.
|
||||
freq.frequency = (int)(f/62.5);
|
||||
} else {
|
||||
// For high, freq in units of 62.5kHz, so convert from Hz to units.
|
||||
freq.frequency = (int)(f/62500);
|
||||
}
|
||||
::ioctl(fd, VIDIOC_S_FREQUENCY, &freq);
|
||||
currentFreq = f;
|
||||
emit frequencyChanged(currentFreq);
|
||||
|
||||
int signal = signalStrength();
|
||||
if(sig != signal) {
|
||||
sig = signal;
|
||||
emit signalStrengthChanged(sig);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool V4LRadioControl::isStereo() const
|
||||
{
|
||||
return stereo;
|
||||
}
|
||||
|
||||
QRadioTuner::StereoMode V4LRadioControl::stereoMode() const
|
||||
{
|
||||
return QRadioTuner::Auto;
|
||||
}
|
||||
|
||||
void V4LRadioControl::setStereoMode(QRadioTuner::StereoMode mode)
|
||||
{
|
||||
bool stereo = true;
|
||||
|
||||
if(mode == QRadioTuner::ForceMono)
|
||||
stereo = false;
|
||||
|
||||
v4l2_tuner tuner;
|
||||
|
||||
memset(&tuner, 0, sizeof(tuner));
|
||||
|
||||
if (ioctl(fd, VIDIOC_G_TUNER, &tuner) >= 0) {
|
||||
if(stereo)
|
||||
tuner.audmode = V4L2_TUNER_MODE_STEREO;
|
||||
else
|
||||
tuner.audmode = V4L2_TUNER_MODE_MONO;
|
||||
|
||||
if (ioctl(fd, VIDIOC_S_TUNER, &tuner) >= 0) {
|
||||
emit stereoStatusChanged(stereo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int V4LRadioControl::signalStrength() const
|
||||
{
|
||||
v4l2_tuner tuner;
|
||||
|
||||
tuner.index = 0;
|
||||
if (ioctl(fd, VIDIOC_G_TUNER, &tuner) < 0 || tuner.type != V4L2_TUNER_RADIO)
|
||||
return 0;
|
||||
return tuner.signal*100/65535;
|
||||
}
|
||||
|
||||
int V4LRadioControl::vol(snd_hctl_elem_t *elem) const
|
||||
{
|
||||
const QString card("hw:0");
|
||||
int err;
|
||||
snd_ctl_elem_id_t *id;
|
||||
snd_ctl_elem_info_t *info;
|
||||
snd_ctl_elem_value_t *control;
|
||||
snd_ctl_elem_id_alloca(&id);
|
||||
snd_ctl_elem_info_alloca(&info);
|
||||
snd_ctl_elem_value_alloca(&control);
|
||||
if ((err = snd_hctl_elem_info(elem, info)) < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
snd_hctl_elem_get_id(elem, id);
|
||||
snd_hctl_elem_read(elem, control);
|
||||
|
||||
return snd_ctl_elem_value_get_integer(control, 0);
|
||||
}
|
||||
|
||||
int V4LRadioControl::volume() const
|
||||
{
|
||||
const QString ctlName("Line DAC Playback Volume");
|
||||
const QString card("hw:0");
|
||||
|
||||
int volume = 0;
|
||||
int err;
|
||||
static snd_ctl_t *handle = NULL;
|
||||
snd_ctl_elem_info_t *info;
|
||||
snd_ctl_elem_id_t *id;
|
||||
snd_ctl_elem_value_t *control;
|
||||
|
||||
snd_ctl_elem_info_alloca(&info);
|
||||
snd_ctl_elem_id_alloca(&id);
|
||||
snd_ctl_elem_value_alloca(&control);
|
||||
snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); /* MIXER */
|
||||
|
||||
snd_ctl_elem_id_set_name(id, ctlName.toAscii());
|
||||
|
||||
if ((err = snd_ctl_open(&handle, card.toAscii(), 0)) < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
snd_ctl_elem_info_set_id(info, id);
|
||||
if ((err = snd_ctl_elem_info(handle, info)) < 0) {
|
||||
snd_ctl_close(handle);
|
||||
handle = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
snd_ctl_elem_info_get_id(info, id); /* FIXME: Remove it when hctl find works ok !!! */
|
||||
snd_ctl_elem_value_set_id(control, id);
|
||||
|
||||
snd_ctl_close(handle);
|
||||
handle = NULL;
|
||||
|
||||
snd_hctl_t *hctl;
|
||||
snd_hctl_elem_t *elem;
|
||||
if ((err = snd_hctl_open(&hctl, card.toAscii(), 0)) < 0) {
|
||||
return 0;
|
||||
}
|
||||
if ((err = snd_hctl_load(hctl)) < 0) {
|
||||
return 0;
|
||||
}
|
||||
elem = snd_hctl_find_elem(hctl, id);
|
||||
if (elem)
|
||||
volume = vol(elem);
|
||||
|
||||
snd_hctl_close(hctl);
|
||||
|
||||
return (volume/118.0) * 100;
|
||||
}
|
||||
|
||||
void V4LRadioControl::setVolume(int volume)
|
||||
{
|
||||
int vol = (volume / 100.0) * 118; // 118 is a headphone max setting
|
||||
callAmixer("Line DAC Playback Volume", QString().setNum(vol)+QString(",")+QString().setNum(vol));
|
||||
}
|
||||
|
||||
bool V4LRadioControl::isMuted() const
|
||||
{
|
||||
return muted;
|
||||
}
|
||||
|
||||
void V4LRadioControl::setMuted(bool muted)
|
||||
{
|
||||
struct v4l2_control vctrl;
|
||||
vctrl.id = V4L2_CID_AUDIO_MUTE;
|
||||
vctrl.value = muted ? 1 : 0;
|
||||
ioctl(fd, VIDIOC_S_CTRL, &vctrl);
|
||||
}
|
||||
|
||||
void V4LRadioControl::setupHeadPhone()
|
||||
{
|
||||
QMap<QString, QString> settings;
|
||||
|
||||
settings["Jack Function"] = "Headset";
|
||||
settings["Left DAC_L1 Mixer HP Switch"] = "off";
|
||||
settings["Right DAC_R1 Mixer HP Switch"] = "off";
|
||||
settings["Line DAC Playback Switch"] = "on";
|
||||
settings["Line DAC Playback Volume"] = "118,118"; // Volume is set to 100%
|
||||
settings["HPCOM DAC Playback Switch"] = "off";
|
||||
settings["Left DAC_L1 Mixer HP Switch"] = "off";
|
||||
settings["Left DAC_L1 Mixer Line Switch"] = "on";
|
||||
settings["Right DAC_R1 Mixer HP Switch"] = "off";
|
||||
settings["Right DAC_R1 Mixer Line Switch"] = "on";
|
||||
settings["Speaker Function"] = "Off";
|
||||
|
||||
settings["Input Select"] = "ADC";
|
||||
settings["Left PGA Mixer Line1L Switch"] = "off";
|
||||
settings["Right PGA Mixer Line1L Switch"] = "off";
|
||||
settings["Right PGA Mixer Line1R Switch"] = "off";
|
||||
settings["PGA Capture Volume"] = "0,0";
|
||||
|
||||
settings["PGA Capture Switch"] = "on";
|
||||
|
||||
settings["Left PGA Mixer Line2L Switch"] = "on";
|
||||
settings["Right PGA Mixer Line2R Switch"] = "on";
|
||||
|
||||
QMapIterator<QString, QString> i(settings);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
callAmixer(i.key(), i.value());
|
||||
}
|
||||
}
|
||||
|
||||
void V4LRadioControl::callAmixer(const QString& target, const QString& value)
|
||||
{
|
||||
int err;
|
||||
long tmp;
|
||||
unsigned int count;
|
||||
static snd_ctl_t *handle = NULL;
|
||||
QString card("hw:0");
|
||||
snd_ctl_elem_info_t *info;
|
||||
snd_ctl_elem_id_t *id;
|
||||
snd_ctl_elem_value_t *control;
|
||||
snd_ctl_elem_type_t type;
|
||||
|
||||
snd_ctl_elem_info_alloca(&info);
|
||||
snd_ctl_elem_id_alloca(&id);
|
||||
snd_ctl_elem_value_alloca(&control);
|
||||
snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); /* MIXER */
|
||||
|
||||
// in amixer parse func
|
||||
// char target[64];
|
||||
// e.g. PGA CAPTure Switch
|
||||
snd_ctl_elem_id_set_name(id, target.toAscii());
|
||||
|
||||
if (handle == NULL && (err = snd_ctl_open(&handle, card.toAscii(), 0)) < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
snd_ctl_elem_info_set_id(info, id);
|
||||
if ((err = snd_ctl_elem_info(handle, info)) < 0)
|
||||
{
|
||||
snd_ctl_close(handle);
|
||||
handle = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
snd_ctl_elem_info_get_id(info, id); /* FIXME: Remove it when hctl find works ok !!! */
|
||||
type = snd_ctl_elem_info_get_type(info);
|
||||
count = snd_ctl_elem_info_get_count(info);
|
||||
|
||||
snd_ctl_elem_value_set_id(control, id);
|
||||
|
||||
tmp = 0;
|
||||
for (uint idx = 0; idx < count && idx < 128; idx++)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case SND_CTL_ELEM_TYPE_BOOLEAN:
|
||||
#ifdef MULTIMEDIA_MAEMO_DEBUG
|
||||
qDebug() << "SND_CTL_ELEM_TYPE_BOOLEAN" << SND_CTL_ELEM_TYPE_BOOLEAN;
|
||||
#endif
|
||||
if ((value == "on") ||(value == "1"))
|
||||
{
|
||||
tmp = 1;
|
||||
}
|
||||
snd_ctl_elem_value_set_boolean(control, idx, tmp);
|
||||
break;
|
||||
case SND_CTL_ELEM_TYPE_ENUMERATED:
|
||||
tmp = getEnumItemIndex(handle, info, value);
|
||||
snd_ctl_elem_value_set_enumerated(control, idx, tmp);
|
||||
break;
|
||||
case SND_CTL_ELEM_TYPE_INTEGER:
|
||||
#ifdef MULTIMEDIA_MAEMO_DEBUG
|
||||
qDebug() << "SND_CTL_ELEM_TYPE_INTEGER" << SND_CTL_ELEM_TYPE_INTEGER;
|
||||
#endif
|
||||
tmp = atoi(value.toAscii());
|
||||
if (tmp < snd_ctl_elem_info_get_min(info))
|
||||
tmp = snd_ctl_elem_info_get_min(info);
|
||||
else if (tmp > snd_ctl_elem_info_get_max(info))
|
||||
tmp = snd_ctl_elem_info_get_max(info);
|
||||
snd_ctl_elem_value_set_integer(control, idx, tmp);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if ((err = snd_ctl_elem_write(handle, control)) < 0) {
|
||||
snd_ctl_close(handle);
|
||||
handle = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
snd_ctl_close(handle);
|
||||
handle = NULL;
|
||||
}
|
||||
|
||||
|
||||
int V4LRadioControl::getEnumItemIndex(snd_ctl_t *handle, snd_ctl_elem_info_t *info,
|
||||
const QString &value)
|
||||
{
|
||||
int items, i;
|
||||
|
||||
items = snd_ctl_elem_info_get_items(info);
|
||||
if (items <= 0)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < items; i++)
|
||||
{
|
||||
snd_ctl_elem_info_set_item(info, i);
|
||||
if (snd_ctl_elem_info(handle, info) < 0)
|
||||
return -1;
|
||||
QString name = snd_ctl_elem_info_get_item_name(info);
|
||||
if(name == value)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool V4LRadioControl::isSearching() const
|
||||
{
|
||||
return scanning;
|
||||
}
|
||||
|
||||
void V4LRadioControl::cancelSearch()
|
||||
{
|
||||
scanning = false;
|
||||
timer->stop();
|
||||
}
|
||||
|
||||
void V4LRadioControl::searchForward()
|
||||
{
|
||||
// Scan up
|
||||
if(scanning) {
|
||||
cancelSearch();
|
||||
return;
|
||||
}
|
||||
scanning = true;
|
||||
forward = true;
|
||||
timer->start();
|
||||
}
|
||||
|
||||
void V4LRadioControl::searchBackward()
|
||||
{
|
||||
// Scan down
|
||||
if(scanning) {
|
||||
cancelSearch();
|
||||
return;
|
||||
}
|
||||
scanning = true;
|
||||
forward = false;
|
||||
timer->start();
|
||||
}
|
||||
|
||||
void V4LRadioControl::start()
|
||||
{
|
||||
}
|
||||
|
||||
void V4LRadioControl::stop()
|
||||
{
|
||||
}
|
||||
|
||||
QRadioTuner::Error V4LRadioControl::error() const
|
||||
{
|
||||
if(m_error)
|
||||
return QRadioTuner::OpenError;
|
||||
|
||||
return QRadioTuner::NoError;
|
||||
}
|
||||
|
||||
QString V4LRadioControl::errorString() const
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
void V4LRadioControl::search()
|
||||
{
|
||||
if(!scanning) return;
|
||||
|
||||
if(forward) {
|
||||
setFrequency(currentFreq+step);
|
||||
} else {
|
||||
setFrequency(currentFreq-step);
|
||||
}
|
||||
|
||||
int signal = signalStrength();
|
||||
if(sig != signal) {
|
||||
sig = signal;
|
||||
emit signalStrengthChanged(sig);
|
||||
}
|
||||
|
||||
if (signal > 25) {
|
||||
cancelSearch();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool V4LRadioControl::initRadio()
|
||||
{
|
||||
v4l2_tuner tuner;
|
||||
v4l2_frequency freq;
|
||||
v4l2_capability cap;
|
||||
|
||||
low = false;
|
||||
available = false;
|
||||
freqMin = freqMax = currentFreq = 0;
|
||||
|
||||
fd = ::open("/dev/radio1", O_RDWR);
|
||||
|
||||
if(fd != -1) {
|
||||
// Capabilities
|
||||
memset(&cap, 0, sizeof(cap));
|
||||
if(::ioctl(fd, VIDIOC_QUERYCAP, &cap ) >= 0) {
|
||||
available = true;
|
||||
}
|
||||
|
||||
tuner.index = 0;
|
||||
|
||||
if (ioctl(fd, VIDIOC_G_TUNER, &tuner) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tuner.type != V4L2_TUNER_RADIO)
|
||||
return false;
|
||||
|
||||
if ((tuner.capability & V4L2_TUNER_CAP_LOW) != 0) {
|
||||
// Units are 1/16th of a kHz.
|
||||
low = true;
|
||||
}
|
||||
|
||||
if(low) {
|
||||
freqMin = tuner.rangelow * 62.5;
|
||||
freqMax = tuner.rangehigh * 62.5;
|
||||
} else {
|
||||
freqMin = tuner.rangelow * 62500;
|
||||
freqMax = tuner.rangehigh * 62500;
|
||||
}
|
||||
|
||||
// frequency
|
||||
memset(&freq, 0, sizeof(freq));
|
||||
|
||||
if(::ioctl(fd, VIDIOC_G_FREQUENCY, &freq) >= 0) {
|
||||
if (((int)freq.frequency) != -1) { // -1 means not set.
|
||||
if(low)
|
||||
currentFreq = freq.frequency * 62.5;
|
||||
else
|
||||
currentFreq = freq.frequency * 62500;
|
||||
}
|
||||
}
|
||||
|
||||
// stereo
|
||||
bool stereo = false;
|
||||
memset(&tuner, 0, sizeof(tuner));
|
||||
if (ioctl(fd, VIDIOC_G_TUNER, &tuner) >= 0) {
|
||||
if((tuner.rxsubchans & V4L2_TUNER_SUB_STEREO) != 0)
|
||||
stereo = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
m_error = true;
|
||||
emit error();
|
||||
|
||||
return false;
|
||||
}
|
||||
144
src/plugins/v4l/radio/v4lradiocontrol_maemo5.h
Normal file
144
src/plugins/v4l/radio/v4lradiocontrol_maemo5.h
Normal file
@@ -0,0 +1,144 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the Qt Mobility Components.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef V4LRADIOCONTROL_H
|
||||
#define V4LRADIOCONTROL_H
|
||||
|
||||
#include <QtCore/qobject.h>
|
||||
#include <QtCore/qtimer.h>
|
||||
|
||||
#include <qradiotunercontrol.h>
|
||||
|
||||
#include <QtDBus/QtDBus>
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include <alsa/asoundlib.h>
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class V4LRadioService;
|
||||
|
||||
class V4LRadioControl : public QRadioTunerControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
V4LRadioControl(QObject *parent = 0);
|
||||
~V4LRadioControl();
|
||||
|
||||
bool isAvailable() const;
|
||||
QtMultimediaKit::AvailabilityError availabilityError() const;
|
||||
|
||||
QRadioTuner::State state() const;
|
||||
|
||||
QRadioTuner::Band band() const;
|
||||
void setBand(QRadioTuner::Band b);
|
||||
bool isBandSupported(QRadioTuner::Band b) const;
|
||||
|
||||
int frequency() const;
|
||||
int frequencyStep(QRadioTuner::Band b) const;
|
||||
QPair<int,int> frequencyRange(QRadioTuner::Band b) const;
|
||||
void setFrequency(int frequency);
|
||||
|
||||
bool isStereo() const;
|
||||
QRadioTuner::StereoMode stereoMode() const;
|
||||
void setStereoMode(QRadioTuner::StereoMode mode);
|
||||
|
||||
int signalStrength() const;
|
||||
|
||||
int volume() const;
|
||||
void setVolume(int volume);
|
||||
|
||||
bool isMuted() const;
|
||||
void setMuted(bool muted);
|
||||
|
||||
bool isSearching() const;
|
||||
void cancelSearch();
|
||||
|
||||
void searchForward();
|
||||
void searchBackward();
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
QRadioTuner::Error error() const;
|
||||
QString errorString() const;
|
||||
|
||||
public slots:
|
||||
void enablePipeline(bool enable = true);
|
||||
|
||||
private slots:
|
||||
void search();
|
||||
void enableFMRX();
|
||||
|
||||
private:
|
||||
bool initRadio();
|
||||
void setupHeadPhone();
|
||||
bool createGstPipeline();
|
||||
void callAmixer(const QString& target, const QString& value);
|
||||
int getEnumItemIndex(snd_ctl_t *handle, snd_ctl_elem_info_t *info, const QString &value);
|
||||
int vol(snd_hctl_elem_t *elem) const;
|
||||
|
||||
private:
|
||||
int fd;
|
||||
|
||||
bool m_error;
|
||||
bool muted;
|
||||
bool stereo;
|
||||
bool low;
|
||||
bool available;
|
||||
int tuners;
|
||||
int step;
|
||||
int sig;
|
||||
bool scanning;
|
||||
bool forward;
|
||||
QTimer* timer;
|
||||
QTimer* tickTimer;
|
||||
QRadioTuner::Band currentBand;
|
||||
qint64 freqMin;
|
||||
qint64 freqMax;
|
||||
qint64 currentFreq;
|
||||
|
||||
GstElement *pipeline;
|
||||
|
||||
QDBusInterface* FMRXEnablerIFace;
|
||||
};
|
||||
|
||||
#endif
|
||||
71
src/plugins/v4l/radio/v4lradioservice.cpp
Normal file
71
src/plugins/v4l/radio/v4lradioservice.cpp
Normal file
@@ -0,0 +1,71 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the Qt Mobility Components.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtCore/qvariant.h>
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtCore/qfile.h>
|
||||
#include <QtGui/qwidget.h>
|
||||
|
||||
#include "v4lradioservice.h"
|
||||
#include "v4lradiocontrol.h"
|
||||
|
||||
V4LRadioService::V4LRadioService(QObject *parent):
|
||||
QMediaService(parent)
|
||||
{
|
||||
m_control = new V4LRadioControl(this);
|
||||
}
|
||||
|
||||
V4LRadioService::~V4LRadioService()
|
||||
{
|
||||
}
|
||||
|
||||
QMediaControl *V4LRadioService::requestControl(const char* name)
|
||||
{
|
||||
if (qstrcmp(name,QRadioTunerControl_iid) == 0)
|
||||
return m_control;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void V4LRadioService::releaseControl(QMediaControl *)
|
||||
{
|
||||
}
|
||||
67
src/plugins/v4l/radio/v4lradioservice.h
Normal file
67
src/plugins/v4l/radio/v4lradioservice.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the Qt Mobility Components.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef V4LRADIOSERVICE_H
|
||||
#define V4LRADIOSERVICE_H
|
||||
|
||||
#include <QtCore/qobject.h>
|
||||
|
||||
#include <qmediaservice.h>
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class V4LRadioControl;
|
||||
|
||||
class V4LRadioService : public QMediaService
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
V4LRadioService(QObject *parent = 0);
|
||||
~V4LRadioService();
|
||||
|
||||
QMediaControl *requestControl(const char* name);
|
||||
void releaseControl(QMediaControl *);
|
||||
|
||||
private:
|
||||
V4LRadioControl *m_control;
|
||||
};
|
||||
|
||||
#endif
|
||||
13
src/plugins/v4l/v4l.pro
Normal file
13
src/plugins/v4l/v4l.pro
Normal file
@@ -0,0 +1,13 @@
|
||||
load(qt_module)
|
||||
|
||||
TARGET = qtmedia_v4lengine
|
||||
QT += multimediakit-private
|
||||
PLUGIN_TYPE = mediaservice
|
||||
|
||||
load(qt_plugin)
|
||||
DESTDIR = $$QT.multimediakit.plugins/$${PLUGIN_TYPE}
|
||||
|
||||
HEADERS += v4lserviceplugin.h
|
||||
SOURCES += v4lserviceplugin.cpp
|
||||
|
||||
include(radio/radio.pri)
|
||||
84
src/plugins/v4l/v4lserviceplugin.cpp
Normal file
84
src/plugins/v4l/v4lserviceplugin.cpp
Normal file
@@ -0,0 +1,84 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the Qt Mobility Components.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtCore/qstring.h>
|
||||
#include <QtCore/qfile.h>
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtCore/qdir.h>
|
||||
|
||||
#include "v4lserviceplugin.h"
|
||||
#include "v4lradioservice.h"
|
||||
|
||||
#include <qmediaserviceprovider.h>
|
||||
|
||||
|
||||
QStringList V4LServicePlugin::keys() const
|
||||
{
|
||||
return QStringList() <<
|
||||
QLatin1String(Q_MEDIASERVICE_RADIO);
|
||||
}
|
||||
|
||||
QMediaService* V4LServicePlugin::create(QString const& key)
|
||||
{
|
||||
if (key == QLatin1String(Q_MEDIASERVICE_RADIO))
|
||||
return new V4LRadioService;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void V4LServicePlugin::release(QMediaService *service)
|
||||
{
|
||||
delete service;
|
||||
}
|
||||
|
||||
QList<QByteArray> V4LServicePlugin::devices(const QByteArray &service) const
|
||||
{
|
||||
return QList<QByteArray>();
|
||||
}
|
||||
|
||||
QString V4LServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device)
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
|
||||
Q_EXPORT_PLUGIN2(qtmedia_v4lengine, V4LServicePlugin);
|
||||
|
||||
63
src/plugins/v4l/v4lserviceplugin.h
Normal file
63
src/plugins/v4l/v4lserviceplugin.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the Qt Mobility Components.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#ifndef V4LSERVICEPLUGIN_H
|
||||
#define V4LSERVICEPLUGIN_H
|
||||
|
||||
#include <qmediaserviceproviderplugin.h>
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class V4LServicePlugin : public QMediaServiceProviderPlugin, public QMediaServiceSupportedDevicesInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
|
||||
public:
|
||||
QStringList keys() const;
|
||||
QMediaService* create(QString const& key);
|
||||
void release(QMediaService *service);
|
||||
|
||||
QList<QByteArray> devices(const QByteArray &service) const;
|
||||
QString deviceDescription(const QByteArray &service, const QByteArray &device);
|
||||
};
|
||||
|
||||
#endif // V4LSERVICEPLUGIN_H
|
||||
Reference in New Issue
Block a user