Initial copy of QtMultimediaKit.
Comes from original repo, with SHA1: 2c82d5611655e5967f5c5095af50c0991c4378b2
This commit is contained in:
25
src/plugins/audiocapture/audiocapture.pro
Normal file
25
src/plugins/audiocapture/audiocapture.pro
Normal file
@@ -0,0 +1,25 @@
|
||||
load(qt_module)
|
||||
|
||||
TARGET = qtmedia_audioengine
|
||||
QT += multimediakit-private
|
||||
PLUGIN_TYPE=mediaservice
|
||||
|
||||
load(qt_plugin)
|
||||
DESTDIR = $$QT.multimediakit.plugins/$${PLUGIN_TYPE}
|
||||
|
||||
# Input
|
||||
HEADERS += audioencodercontrol.h \
|
||||
audiocontainercontrol.h \
|
||||
audiomediarecordercontrol.h \
|
||||
audioendpointselector.h \
|
||||
audiocaptureservice.h \
|
||||
audiocaptureserviceplugin.h \
|
||||
audiocapturesession.h
|
||||
|
||||
SOURCES += audioencodercontrol.cpp \
|
||||
audiocontainercontrol.cpp \
|
||||
audiomediarecordercontrol.cpp \
|
||||
audioendpointselector.cpp \
|
||||
audiocaptureservice.cpp \
|
||||
audiocaptureserviceplugin.cpp \
|
||||
audiocapturesession.cpp
|
||||
90
src/plugins/audiocapture/audiocaptureservice.cpp
Normal file
90
src/plugins/audiocapture/audiocaptureservice.cpp
Normal file
@@ -0,0 +1,90 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "audiocaptureservice.h"
|
||||
#include "audiocapturesession.h"
|
||||
#include "audioendpointselector.h"
|
||||
#include "audioencodercontrol.h"
|
||||
#include "audiocontainercontrol.h"
|
||||
#include "audiomediarecordercontrol.h"
|
||||
|
||||
AudioCaptureService::AudioCaptureService(QObject *parent):
|
||||
QMediaService(parent)
|
||||
{
|
||||
m_session = new AudioCaptureSession(this);
|
||||
m_encoderControl = new AudioEncoderControl(m_session);
|
||||
m_containerControl = new AudioContainerControl(m_session);
|
||||
m_mediaControl = new AudioMediaRecorderControl(m_session);
|
||||
m_endpointSelector = new AudioEndpointSelector(m_session);
|
||||
}
|
||||
|
||||
AudioCaptureService::~AudioCaptureService()
|
||||
{
|
||||
delete m_encoderControl;
|
||||
delete m_containerControl;
|
||||
delete m_endpointSelector;
|
||||
delete m_mediaControl;
|
||||
delete m_session;
|
||||
}
|
||||
|
||||
QMediaControl *AudioCaptureService::requestControl(const char *name)
|
||||
{
|
||||
if (qstrcmp(name,QMediaRecorderControl_iid) == 0)
|
||||
return m_mediaControl;
|
||||
|
||||
if (qstrcmp(name,QAudioEncoderControl_iid) == 0)
|
||||
return m_encoderControl;
|
||||
|
||||
if (qstrcmp(name,QAudioEndpointSelector_iid) == 0)
|
||||
return m_endpointSelector;
|
||||
|
||||
if (qstrcmp(name,QMediaContainerControl_iid) == 0)
|
||||
return m_containerControl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AudioCaptureService::releaseControl(QMediaControl *control)
|
||||
{
|
||||
Q_UNUSED(control)
|
||||
}
|
||||
|
||||
|
||||
74
src/plugins/audiocapture/audiocaptureservice.h
Normal file
74
src/plugins/audiocapture/audiocaptureservice.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 AUDIOCAPTURESERVICE_H
|
||||
#define AUDIOCAPTURESERVICE_H
|
||||
|
||||
#include <QtCore/qobject.h>
|
||||
|
||||
#include "qmediaservice.h"
|
||||
|
||||
class AudioCaptureSession;
|
||||
class AudioEncoderControl;
|
||||
class AudioContainerControl;
|
||||
class AudioMediaRecorderControl;
|
||||
class AudioEndpointSelector;
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class AudioCaptureService : public QMediaService
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AudioCaptureService(QObject *parent = 0);
|
||||
~AudioCaptureService();
|
||||
|
||||
QMediaControl *requestControl(const char *interface);
|
||||
void releaseControl(QMediaControl *control);
|
||||
private:
|
||||
AudioCaptureSession *m_session;
|
||||
AudioEncoderControl *m_encoderControl;
|
||||
AudioContainerControl *m_containerControl;
|
||||
AudioEndpointSelector *m_endpointSelector;
|
||||
AudioMediaRecorderControl *m_mediaControl;
|
||||
};
|
||||
|
||||
#endif
|
||||
69
src/plugins/audiocapture/audiocaptureserviceplugin.cpp
Normal file
69
src/plugins/audiocapture/audiocaptureserviceplugin.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "audiocaptureserviceplugin.h"
|
||||
#include "audiocaptureservice.h"
|
||||
|
||||
#include "qmediaserviceprovider.h"
|
||||
|
||||
|
||||
QStringList AudioCaptureServicePlugin::keys() const
|
||||
{
|
||||
return QStringList() << QLatin1String(Q_MEDIASERVICE_AUDIOSOURCE);
|
||||
}
|
||||
|
||||
QMediaService* AudioCaptureServicePlugin::create(QString const& key)
|
||||
{
|
||||
if (key == QLatin1String(Q_MEDIASERVICE_AUDIOSOURCE))
|
||||
return new AudioCaptureService;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AudioCaptureServicePlugin::release(QMediaService *service)
|
||||
{
|
||||
delete service;
|
||||
}
|
||||
|
||||
Q_EXPORT_PLUGIN2(qtmedia_audioengine, AudioCaptureServicePlugin);
|
||||
|
||||
60
src/plugins/audiocapture/audiocaptureserviceplugin.h
Normal file
60
src/plugins/audiocapture/audiocaptureserviceplugin.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 AUDIOCAPTURESERVICEPLUGIN_H
|
||||
#define AUDIOCAPTURESERVICEPLUGIN_H
|
||||
|
||||
#include "qmediaserviceproviderplugin.h"
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class AudioCaptureServicePlugin : public QMediaServiceProviderPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QStringList keys() const;
|
||||
QMediaService* create(QString const& key);
|
||||
void release(QMediaService *service);
|
||||
};
|
||||
|
||||
#endif // AUDIOCAPTURESERVICEPLUGIN_H
|
||||
358
src/plugins/audiocapture/audiocapturesession.cpp
Normal file
358
src/plugins/audiocapture/audiocapturesession.cpp
Normal file
@@ -0,0 +1,358 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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/qdebug.h>
|
||||
#include <QtCore/qurl.h>
|
||||
#include <QtCore/qdir.h>
|
||||
#include <qaudiodeviceinfo.h>
|
||||
|
||||
#include "qmediarecorder.h"
|
||||
|
||||
#include "audiocapturesession.h"
|
||||
|
||||
AudioCaptureSession::AudioCaptureSession(QObject *parent):
|
||||
QObject(parent)
|
||||
{
|
||||
m_deviceInfo = new QAudioDeviceInfo(QAudioDeviceInfo::defaultInputDevice());
|
||||
m_audioInput = 0;
|
||||
m_position = 0;
|
||||
m_state = QMediaRecorder::StoppedState;
|
||||
|
||||
m_format.setFrequency(8000);
|
||||
m_format.setChannels(1);
|
||||
m_format.setSampleSize(8);
|
||||
m_format.setSampleType(QAudioFormat::UnSignedInt);
|
||||
m_format.setCodec("audio/pcm");
|
||||
wavFile = true;
|
||||
}
|
||||
|
||||
AudioCaptureSession::~AudioCaptureSession()
|
||||
{
|
||||
stop();
|
||||
|
||||
if(m_audioInput)
|
||||
delete m_audioInput;
|
||||
}
|
||||
|
||||
QAudioDeviceInfo* AudioCaptureSession::deviceInfo() const
|
||||
{
|
||||
return m_deviceInfo;
|
||||
}
|
||||
|
||||
QAudioFormat AudioCaptureSession::format() const
|
||||
{
|
||||
return m_format;
|
||||
}
|
||||
|
||||
bool AudioCaptureSession::isFormatSupported(const QAudioFormat &format) const
|
||||
{
|
||||
if(m_deviceInfo) {
|
||||
if(format.codec().contains(QLatin1String("audio/x-wav"))) {
|
||||
QAudioFormat fmt = format;
|
||||
fmt.setCodec("audio/pcm");
|
||||
return m_deviceInfo->isFormatSupported(fmt);
|
||||
} else
|
||||
return m_deviceInfo->isFormatSupported(format);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AudioCaptureSession::setFormat(const QAudioFormat &format)
|
||||
{
|
||||
if(m_deviceInfo) {
|
||||
|
||||
QAudioFormat fmt = format;
|
||||
|
||||
if(m_deviceInfo->isFormatSupported(fmt)) {
|
||||
m_format = fmt;
|
||||
if(m_audioInput) delete m_audioInput;
|
||||
m_audioInput = 0;
|
||||
QList<QAudioDeviceInfo> devices = QAudioDeviceInfo::availableDevices(QAudio::AudioInput);
|
||||
for(int i=0;i<devices.size();i++) {
|
||||
if(qstrcmp(m_deviceInfo->deviceName().toLocal8Bit().constData(),
|
||||
devices.at(i).deviceName().toLocal8Bit().constData()) == 0) {
|
||||
m_audioInput = new QAudioInput(devices.at(i),m_format);
|
||||
connect(m_audioInput,SIGNAL(stateChanged(QAudio::State)),this,SLOT(stateChanged(QAudio::State)));
|
||||
connect(m_audioInput,SIGNAL(notify()),this,SLOT(notify()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m_format = m_deviceInfo->preferredFormat();
|
||||
qWarning()<<"failed to setFormat using preferred...";
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QStringList AudioCaptureSession::supportedContainers() const
|
||||
{
|
||||
QStringList list;
|
||||
if(m_deviceInfo) {
|
||||
if (m_deviceInfo->supportedCodecs().size() > 0) {
|
||||
list << "audio/x-wav";
|
||||
list << "audio/pcm";
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
QString AudioCaptureSession::containerDescription(const QString &formatMimeType) const
|
||||
{
|
||||
if(m_deviceInfo) {
|
||||
if (formatMimeType.contains(QLatin1String("audio/pcm")))
|
||||
return tr("RAW file format");
|
||||
if (formatMimeType.contains(QLatin1String("audio/x-wav")))
|
||||
return tr("WAV file format");
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
void AudioCaptureSession::setContainerMimeType(const QString &formatMimeType)
|
||||
{
|
||||
if (!formatMimeType.contains(QLatin1String("audio/x-wav")) &&
|
||||
!formatMimeType.contains(QLatin1String("audio/pcm")) &&
|
||||
!formatMimeType.isEmpty())
|
||||
return;
|
||||
|
||||
if(m_deviceInfo) {
|
||||
if (!m_deviceInfo->supportedCodecs().contains(QLatin1String("audio/pcm")))
|
||||
return;
|
||||
|
||||
if (formatMimeType.isEmpty() || formatMimeType.contains(QLatin1String("audio/x-wav"))) {
|
||||
wavFile = true;
|
||||
m_format.setCodec("audio/pcm");
|
||||
} else {
|
||||
wavFile = false;
|
||||
m_format.setCodec(formatMimeType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString AudioCaptureSession::containerMimeType() const
|
||||
{
|
||||
if(wavFile)
|
||||
return QString("audio/x-wav");
|
||||
|
||||
return QString("audio/pcm");
|
||||
}
|
||||
|
||||
QUrl AudioCaptureSession::outputLocation() const
|
||||
{
|
||||
return m_actualSink;
|
||||
}
|
||||
|
||||
bool AudioCaptureSession::setOutputLocation(const QUrl& sink)
|
||||
{
|
||||
m_sink = m_actualSink = sink;
|
||||
return true;
|
||||
}
|
||||
|
||||
qint64 AudioCaptureSession::position() const
|
||||
{
|
||||
return m_position;
|
||||
}
|
||||
|
||||
int AudioCaptureSession::state() const
|
||||
{
|
||||
return int(m_state);
|
||||
}
|
||||
|
||||
QDir AudioCaptureSession::defaultDir() const
|
||||
{
|
||||
QStringList dirCandidates;
|
||||
|
||||
#if defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6)
|
||||
dirCandidates << QLatin1String("/home/user/MyDocs");
|
||||
#endif
|
||||
|
||||
dirCandidates << QDir::home().filePath("Documents");
|
||||
dirCandidates << QDir::home().filePath("My Documents");
|
||||
dirCandidates << QDir::homePath();
|
||||
dirCandidates << QDir::currentPath();
|
||||
dirCandidates << QDir::tempPath();
|
||||
|
||||
foreach (const QString &path, dirCandidates) {
|
||||
QDir dir(path);
|
||||
if (dir.exists() && QFileInfo(path).isWritable())
|
||||
return dir;
|
||||
}
|
||||
|
||||
return QDir();
|
||||
}
|
||||
|
||||
QString AudioCaptureSession::generateFileName(const QDir &dir, const QString &ext) const
|
||||
{
|
||||
|
||||
int lastClip = 0;
|
||||
foreach(QString fileName, dir.entryList(QStringList() << QString("clip_*.%1").arg(ext))) {
|
||||
int imgNumber = fileName.mid(5, fileName.size()-6-ext.length()).toInt();
|
||||
lastClip = qMax(lastClip, imgNumber);
|
||||
}
|
||||
|
||||
QString name = QString("clip_%1.%2").arg(lastClip+1,
|
||||
4, //fieldWidth
|
||||
10,
|
||||
QLatin1Char('0')).arg(ext);
|
||||
|
||||
return dir.absoluteFilePath(name);
|
||||
}
|
||||
|
||||
void AudioCaptureSession::record()
|
||||
{
|
||||
if(!m_audioInput) {
|
||||
setFormat(m_format);
|
||||
}
|
||||
|
||||
m_actualSink = m_sink;
|
||||
|
||||
if (m_actualSink.isEmpty()) {
|
||||
QString ext = wavFile ? QLatin1String("wav") : QLatin1String("raw");
|
||||
m_actualSink = generateFileName(defaultDir(), ext);
|
||||
}
|
||||
|
||||
if(m_actualSink.toLocalFile().length() > 0)
|
||||
file.setFileName(m_actualSink.toLocalFile());
|
||||
else
|
||||
file.setFileName(m_actualSink.toString());
|
||||
|
||||
if(m_audioInput) {
|
||||
if(m_state == QMediaRecorder::StoppedState) {
|
||||
if(file.open(QIODevice::WriteOnly)) {
|
||||
memset(&header,0,sizeof(CombinedHeader));
|
||||
memcpy(header.riff.descriptor.id,"RIFF",4);
|
||||
header.riff.descriptor.size = 0xFFFFFFFF; // This should be updated on stop(), filesize-8
|
||||
memcpy(header.riff.type,"WAVE",4);
|
||||
memcpy(header.wave.descriptor.id,"fmt ",4);
|
||||
header.wave.descriptor.size = 16;
|
||||
header.wave.audioFormat = 1; // for PCM data
|
||||
header.wave.numChannels = m_format.channels();
|
||||
header.wave.sampleRate = m_format.frequency();
|
||||
header.wave.byteRate = m_format.frequency()*m_format.channels()*m_format.sampleSize()/8;
|
||||
header.wave.blockAlign = m_format.channels()*m_format.sampleSize()/8;
|
||||
header.wave.bitsPerSample = m_format.sampleSize();
|
||||
memcpy(header.data.descriptor.id,"data",4);
|
||||
header.data.descriptor.size = 0xFFFFFFFF; // This should be updated on stop(),samples*channels*sampleSize/8
|
||||
if (wavFile)
|
||||
file.write((char*)&header,sizeof(CombinedHeader));
|
||||
|
||||
m_audioInput->start(qobject_cast<QIODevice*>(&file));
|
||||
} else {
|
||||
emit error(1,QString("can't open source, failed"));
|
||||
m_state = QMediaRecorder::StoppedState;
|
||||
emit stateChanged(m_state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_state = QMediaRecorder::RecordingState;
|
||||
}
|
||||
|
||||
void AudioCaptureSession::pause()
|
||||
{
|
||||
if(m_audioInput)
|
||||
m_audioInput->stop();
|
||||
|
||||
m_state = QMediaRecorder::PausedState;
|
||||
}
|
||||
|
||||
void AudioCaptureSession::stop()
|
||||
{
|
||||
if(m_audioInput) {
|
||||
m_audioInput->stop();
|
||||
file.close();
|
||||
if (wavFile) {
|
||||
qint32 fileSize = file.size()-8;
|
||||
file.open(QIODevice::ReadWrite | QIODevice::Unbuffered);
|
||||
file.read((char*)&header,sizeof(CombinedHeader));
|
||||
header.riff.descriptor.size = fileSize; // filesize-8
|
||||
header.data.descriptor.size = fileSize-44; // samples*channels*sampleSize/8
|
||||
file.seek(0);
|
||||
file.write((char*)&header,sizeof(CombinedHeader));
|
||||
file.close();
|
||||
}
|
||||
m_position = 0;
|
||||
}
|
||||
m_state = QMediaRecorder::StoppedState;
|
||||
}
|
||||
|
||||
void AudioCaptureSession::stateChanged(QAudio::State state)
|
||||
{
|
||||
switch(state) {
|
||||
case QAudio::ActiveState:
|
||||
emit stateChanged(QMediaRecorder::RecordingState);
|
||||
break;
|
||||
default:
|
||||
if(!((m_state == QMediaRecorder::PausedState)||(m_state == QMediaRecorder::StoppedState)))
|
||||
m_state = QMediaRecorder::StoppedState;
|
||||
|
||||
emit stateChanged(m_state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void AudioCaptureSession::notify()
|
||||
{
|
||||
m_position += m_audioInput->notifyInterval();
|
||||
emit positionChanged(m_position);
|
||||
}
|
||||
|
||||
void AudioCaptureSession::setCaptureDevice(const QString &deviceName)
|
||||
{
|
||||
m_captureDevice = deviceName;
|
||||
if(m_deviceInfo)
|
||||
delete m_deviceInfo;
|
||||
|
||||
m_deviceInfo = 0;
|
||||
|
||||
QList<QAudioDeviceInfo> devices = QAudioDeviceInfo::availableDevices(QAudio::AudioInput);
|
||||
for(int i = 0; i < devices.size(); i++) {
|
||||
if(qstrcmp(m_captureDevice.toLocal8Bit().constData(),
|
||||
devices.at(i).deviceName().toLocal8Bit().constData())==0){
|
||||
m_deviceInfo = new QAudioDeviceInfo(QAudioDeviceInfo::defaultInputDevice());
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_deviceInfo = new QAudioDeviceInfo(QAudioDeviceInfo::defaultInputDevice());
|
||||
}
|
||||
|
||||
|
||||
|
||||
152
src/plugins/audiocapture/audiocapturesession.h
Normal file
152
src/plugins/audiocapture/audiocapturesession.h
Normal file
@@ -0,0 +1,152 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 AUDIOCAPTURESESSION_H
|
||||
#define AUDIOCAPTURESESSION_H
|
||||
|
||||
#include <QFile>
|
||||
#include <QUrl>
|
||||
#include <QDir>
|
||||
|
||||
#include "audioencodercontrol.h"
|
||||
#include "audioendpointselector.h"
|
||||
#include "audiomediarecordercontrol.h"
|
||||
|
||||
#include <qaudioformat.h>
|
||||
#include <qaudioinput.h>
|
||||
#include <qaudiodeviceinfo.h>
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class AudioCaptureSession : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AudioCaptureSession(QObject *parent = 0);
|
||||
~AudioCaptureSession();
|
||||
|
||||
QAudioFormat format() const;
|
||||
QAudioDeviceInfo* deviceInfo() const;
|
||||
bool isFormatSupported(const QAudioFormat &format) const;
|
||||
bool setFormat(const QAudioFormat &format);
|
||||
QStringList supportedContainers() const;
|
||||
QString containerMimeType() const;
|
||||
void setContainerMimeType(const QString &formatMimeType);
|
||||
QString containerDescription(const QString &formatMimeType) const;
|
||||
|
||||
QUrl outputLocation() const;
|
||||
bool setOutputLocation(const QUrl& sink);
|
||||
qint64 position() const;
|
||||
int state() const;
|
||||
void record();
|
||||
void pause();
|
||||
void stop();
|
||||
|
||||
public slots:
|
||||
void setCaptureDevice(const QString &deviceName);
|
||||
|
||||
signals:
|
||||
void stateChanged(QMediaRecorder::State state);
|
||||
void positionChanged(qint64 position);
|
||||
void error(int error, const QString &errorString);
|
||||
|
||||
private slots:
|
||||
void stateChanged(QAudio::State state);
|
||||
void notify();
|
||||
|
||||
private:
|
||||
QDir defaultDir() const;
|
||||
QString generateFileName(const QDir &dir, const QString &ext) const;
|
||||
|
||||
QFile file;
|
||||
QString m_captureDevice;
|
||||
QUrl m_sink;
|
||||
QUrl m_actualSink;
|
||||
QMediaRecorder::State m_state;
|
||||
QAudioInput *m_audioInput;
|
||||
QAudioDeviceInfo *m_deviceInfo;
|
||||
QAudioFormat m_format;
|
||||
qint64 m_position;
|
||||
bool wavFile;
|
||||
|
||||
// WAV header stuff
|
||||
|
||||
struct chunk
|
||||
{
|
||||
char id[4];
|
||||
quint32 size;
|
||||
};
|
||||
|
||||
struct RIFFHeader
|
||||
{
|
||||
chunk descriptor;
|
||||
char type[4];
|
||||
};
|
||||
|
||||
struct WAVEHeader
|
||||
{
|
||||
chunk descriptor;
|
||||
quint16 audioFormat; // PCM = 1
|
||||
quint16 numChannels;
|
||||
quint32 sampleRate;
|
||||
quint32 byteRate;
|
||||
quint16 blockAlign;
|
||||
quint16 bitsPerSample;
|
||||
};
|
||||
|
||||
struct DATAHeader
|
||||
{
|
||||
chunk descriptor;
|
||||
// quint8 data[];
|
||||
};
|
||||
|
||||
struct CombinedHeader
|
||||
{
|
||||
RIFFHeader riff;
|
||||
WAVEHeader wave;
|
||||
DATAHeader data;
|
||||
};
|
||||
|
||||
CombinedHeader header;
|
||||
};
|
||||
|
||||
#endif
|
||||
74
src/plugins/audiocapture/audiocontainercontrol.cpp
Normal file
74
src/plugins/audiocapture/audiocontainercontrol.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "audiocontainercontrol.h"
|
||||
#include "audiocapturesession.h"
|
||||
|
||||
AudioContainerControl::AudioContainerControl(QObject *parent)
|
||||
:QMediaContainerControl(parent)
|
||||
{
|
||||
m_session = qobject_cast<AudioCaptureSession*>(parent);
|
||||
}
|
||||
|
||||
AudioContainerControl::~AudioContainerControl()
|
||||
{
|
||||
}
|
||||
|
||||
QStringList AudioContainerControl::supportedContainers() const
|
||||
{
|
||||
return m_session->supportedContainers();
|
||||
}
|
||||
|
||||
QString AudioContainerControl::containerMimeType() const
|
||||
{
|
||||
return m_session->containerMimeType();
|
||||
}
|
||||
|
||||
void AudioContainerControl::setContainerMimeType(const QString &formatMimeType)
|
||||
{
|
||||
m_session->setContainerMimeType(formatMimeType);
|
||||
}
|
||||
|
||||
QString AudioContainerControl::containerDescription(const QString &formatMimeType) const
|
||||
{
|
||||
return m_session->containerDescription(formatMimeType);
|
||||
}
|
||||
|
||||
70
src/plugins/audiocapture/audiocontainercontrol.h
Normal file
70
src/plugins/audiocapture/audiocontainercontrol.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 AUDIOCONTAINERCONTROL_H
|
||||
#define AUDIOCONTAINERCONTROL_H
|
||||
|
||||
#include "qmediacontainercontrol.h"
|
||||
|
||||
#include <QtCore/qstringlist.h>
|
||||
#include <QtCore/qmap.h>
|
||||
|
||||
class AudioCaptureSession;
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class AudioContainerControl : public QMediaContainerControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AudioContainerControl(QObject *parent);
|
||||
virtual ~AudioContainerControl();
|
||||
|
||||
QStringList supportedContainers() const;
|
||||
QString containerMimeType() const;
|
||||
void setContainerMimeType(const QString &formatMimeType);
|
||||
QString containerDescription(const QString &formatMimeType) const;
|
||||
|
||||
private:
|
||||
AudioCaptureSession* m_session;
|
||||
};
|
||||
|
||||
#endif
|
||||
168
src/plugins/audiocapture/audioencodercontrol.cpp
Normal file
168
src/plugins/audiocapture/audioencodercontrol.cpp
Normal file
@@ -0,0 +1,168 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "audioencodercontrol.h"
|
||||
#include "audiocapturesession.h"
|
||||
|
||||
#include <qaudioformat.h>
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
|
||||
AudioEncoderControl::AudioEncoderControl(QObject *parent)
|
||||
:QAudioEncoderControl(parent)
|
||||
{
|
||||
m_session = qobject_cast<AudioCaptureSession*>(parent);
|
||||
|
||||
QT_PREPEND_NAMESPACE(QAudioFormat) fmt;
|
||||
fmt.setSampleSize(8);
|
||||
fmt.setChannels(1);
|
||||
fmt.setFrequency(8000);
|
||||
fmt.setSampleType(QT_PREPEND_NAMESPACE(QAudioFormat)::SignedInt);
|
||||
fmt.setCodec("audio/pcm");
|
||||
fmt.setByteOrder(QAudioFormat::LittleEndian);
|
||||
m_session->setFormat(fmt);
|
||||
|
||||
m_settings.setEncodingMode(QtMultimediaKit::ConstantQualityEncoding);
|
||||
m_settings.setCodec("audio/pcm");
|
||||
m_settings.setBitRate(8000);
|
||||
m_settings.setChannelCount(1);
|
||||
m_settings.setSampleRate(8000);
|
||||
m_settings.setQuality(QtMultimediaKit::LowQuality);
|
||||
}
|
||||
|
||||
AudioEncoderControl::~AudioEncoderControl()
|
||||
{
|
||||
}
|
||||
|
||||
QStringList AudioEncoderControl::supportedAudioCodecs() const
|
||||
{
|
||||
QStringList list;
|
||||
if (m_session->supportedContainers().size() > 0)
|
||||
list.append("audio/pcm");
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
QString AudioEncoderControl::codecDescription(const QString &codecName) const
|
||||
{
|
||||
if (codecName.contains(QLatin1String("audio/pcm")))
|
||||
return tr("PCM audio data");
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
QStringList AudioEncoderControl::supportedEncodingOptions(const QString &codec) const
|
||||
{
|
||||
Q_UNUSED(codec)
|
||||
|
||||
QStringList list;
|
||||
return list;
|
||||
}
|
||||
|
||||
QVariant AudioEncoderControl::encodingOption(const QString &codec, const QString &name) const
|
||||
{
|
||||
Q_UNUSED(codec)
|
||||
Q_UNUSED(name)
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void AudioEncoderControl::setEncodingOption(
|
||||
const QString &codec, const QString &name, const QVariant &value)
|
||||
{
|
||||
Q_UNUSED(value)
|
||||
Q_UNUSED(codec)
|
||||
Q_UNUSED(name)
|
||||
}
|
||||
|
||||
QList<int> AudioEncoderControl::supportedSampleRates(const QAudioEncoderSettings &, bool *continuous) const
|
||||
{
|
||||
if (continuous)
|
||||
*continuous = false;
|
||||
|
||||
return m_session->deviceInfo()->supportedFrequencies();
|
||||
}
|
||||
|
||||
QAudioEncoderSettings AudioEncoderControl::audioSettings() const
|
||||
{
|
||||
return m_settings;
|
||||
}
|
||||
|
||||
void AudioEncoderControl::setAudioSettings(const QAudioEncoderSettings &settings)
|
||||
{
|
||||
QAudioFormat fmt = m_session->format();
|
||||
|
||||
if (settings.encodingMode() == QtMultimediaKit::ConstantQualityEncoding) {
|
||||
if (settings.quality() == QtMultimediaKit::LowQuality) {
|
||||
fmt.setSampleSize(8);
|
||||
fmt.setChannels(1);
|
||||
fmt.setFrequency(8000);
|
||||
fmt.setSampleType(QAudioFormat::UnSignedInt);
|
||||
|
||||
} else if (settings.quality() == QtMultimediaKit::NormalQuality) {
|
||||
fmt.setSampleSize(16);
|
||||
fmt.setChannels(1);
|
||||
fmt.setFrequency(22050);
|
||||
fmt.setSampleType(QAudioFormat::SignedInt);
|
||||
|
||||
} else {
|
||||
fmt.setSampleSize(16);
|
||||
fmt.setChannels(1);
|
||||
fmt.setFrequency(44100);
|
||||
fmt.setSampleType(QAudioFormat::SignedInt);
|
||||
}
|
||||
|
||||
} else {
|
||||
fmt.setChannels(settings.channelCount());
|
||||
fmt.setFrequency(settings.sampleRate());
|
||||
if (settings.sampleRate() == 8000 && settings.bitRate() == 8000) {
|
||||
fmt.setSampleType(QAudioFormat::UnSignedInt);
|
||||
fmt.setSampleSize(8);
|
||||
} else {
|
||||
fmt.setSampleSize(16);
|
||||
fmt.setSampleType(QAudioFormat::SignedInt);
|
||||
}
|
||||
}
|
||||
fmt.setCodec("audio/pcm");
|
||||
|
||||
m_session->setFormat(fmt);
|
||||
m_settings = settings;
|
||||
}
|
||||
79
src/plugins/audiocapture/audioencodercontrol.h
Normal file
79
src/plugins/audiocapture/audioencodercontrol.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 AUDIOENCODERCONTROL_H
|
||||
#define AUDIOENCODERCONTROL_H
|
||||
|
||||
#include "qaudioencodercontrol.h"
|
||||
|
||||
#include <QtCore/qstringlist.h>
|
||||
#include <QtCore/qmap.h>
|
||||
|
||||
#include <qaudioformat.h>
|
||||
|
||||
class AudioCaptureSession;
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class AudioEncoderControl : public QAudioEncoderControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AudioEncoderControl(QObject *parent);
|
||||
virtual ~AudioEncoderControl();
|
||||
|
||||
QStringList supportedAudioCodecs() const;
|
||||
QString codecDescription(const QString &codecName) const;
|
||||
QList<int> supportedSampleRates(const QAudioEncoderSettings &, bool *continuous = 0) const;
|
||||
|
||||
QAudioEncoderSettings audioSettings() const;
|
||||
void setAudioSettings(const QAudioEncoderSettings&);
|
||||
|
||||
QStringList supportedEncodingOptions(const QString &codec) const;
|
||||
QVariant encodingOption(const QString &codec, const QString &name) const;
|
||||
void setEncodingOption(const QString &codec, const QString &name, const QVariant &value);
|
||||
|
||||
private:
|
||||
AudioCaptureSession* m_session;
|
||||
QAudioEncoderSettings m_settings;
|
||||
};
|
||||
|
||||
#endif
|
||||
110
src/plugins/audiocapture/audioendpointselector.cpp
Normal file
110
src/plugins/audiocapture/audioendpointselector.cpp
Normal file
@@ -0,0 +1,110 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "audiocapturesession.h"
|
||||
#include "audioendpointselector.h"
|
||||
|
||||
#include <qaudiodeviceinfo.h>
|
||||
|
||||
|
||||
AudioEndpointSelector::AudioEndpointSelector(QObject *parent)
|
||||
:QAudioEndpointSelector(parent)
|
||||
{
|
||||
m_session = qobject_cast<AudioCaptureSession*>(parent);
|
||||
|
||||
update();
|
||||
|
||||
m_audioInput = defaultEndpoint();
|
||||
}
|
||||
|
||||
AudioEndpointSelector::~AudioEndpointSelector()
|
||||
{
|
||||
}
|
||||
|
||||
QList<QString> AudioEndpointSelector::availableEndpoints() const
|
||||
{
|
||||
return m_names;
|
||||
}
|
||||
|
||||
QString AudioEndpointSelector::endpointDescription(const QString& name) const
|
||||
{
|
||||
QString desc;
|
||||
|
||||
for(int i = 0; i < m_names.count(); i++) {
|
||||
if (m_names.at(i).compare(name) == 0) {
|
||||
desc = m_names.at(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return desc;
|
||||
}
|
||||
|
||||
QString AudioEndpointSelector::defaultEndpoint() const
|
||||
{
|
||||
return QAudioDeviceInfo(QAudioDeviceInfo::defaultInputDevice()).deviceName();
|
||||
}
|
||||
|
||||
QString AudioEndpointSelector::activeEndpoint() const
|
||||
{
|
||||
return m_audioInput;
|
||||
}
|
||||
|
||||
void AudioEndpointSelector::setActiveEndpoint(const QString& name)
|
||||
{
|
||||
if (m_audioInput.compare(name) != 0) {
|
||||
m_audioInput = name;
|
||||
m_session->setCaptureDevice(name);
|
||||
emit activeEndpointChanged(name);
|
||||
}
|
||||
}
|
||||
|
||||
void AudioEndpointSelector::update()
|
||||
{
|
||||
m_names.clear();
|
||||
m_descriptions.clear();
|
||||
|
||||
QList<QAudioDeviceInfo> devices;
|
||||
devices = QAudioDeviceInfo::availableDevices(QAudio::AudioInput);
|
||||
for(int i = 0; i < devices.size(); ++i) {
|
||||
m_names.append(devices.at(i).deviceName());
|
||||
m_descriptions.append(devices.at(i).deviceName());
|
||||
}
|
||||
}
|
||||
77
src/plugins/audiocapture/audioendpointselector.h
Normal file
77
src/plugins/audiocapture/audioendpointselector.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 AUDIOENDPOINTSELECTOR_H
|
||||
#define AUDIOENDPOINTSELECTOR_H
|
||||
|
||||
#include <QStringList>
|
||||
|
||||
#include "qaudioendpointselector.h"
|
||||
|
||||
class AudioCaptureSession;
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class AudioEndpointSelector : public QAudioEndpointSelector
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AudioEndpointSelector(QObject *parent);
|
||||
virtual ~AudioEndpointSelector();
|
||||
|
||||
QList<QString> availableEndpoints() const;
|
||||
QString endpointDescription(const QString& name) const;
|
||||
QString defaultEndpoint() const;
|
||||
QString activeEndpoint() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void setActiveEndpoint(const QString& name);
|
||||
|
||||
private:
|
||||
void update();
|
||||
|
||||
QString m_audioInput;
|
||||
QList<QString> m_names;
|
||||
QList<QString> m_descriptions;
|
||||
AudioCaptureSession* m_session;
|
||||
};
|
||||
|
||||
#endif // AUDIOENDPOINTSELECTOR_H
|
||||
102
src/plugins/audiocapture/audiomediarecordercontrol.cpp
Normal file
102
src/plugins/audiocapture/audiomediarecordercontrol.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "audiocapturesession.h"
|
||||
#include "audiomediarecordercontrol.h"
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
|
||||
AudioMediaRecorderControl::AudioMediaRecorderControl(QObject *parent)
|
||||
:QMediaRecorderControl(parent)
|
||||
{
|
||||
m_session = qobject_cast<AudioCaptureSession*>(parent);
|
||||
connect(m_session,SIGNAL(positionChanged(qint64)),this,SIGNAL(durationChanged(qint64)));
|
||||
connect(m_session,SIGNAL(stateChanged(QMediaRecorder::State)),this,SIGNAL(stateChanged(QMediaRecorder::State)));
|
||||
connect(m_session,SIGNAL(error(int,QString)),this,SIGNAL(error(int,QString)));
|
||||
}
|
||||
|
||||
AudioMediaRecorderControl::~AudioMediaRecorderControl()
|
||||
{
|
||||
}
|
||||
|
||||
QUrl AudioMediaRecorderControl::outputLocation() const
|
||||
{
|
||||
return m_session->outputLocation();
|
||||
}
|
||||
|
||||
bool AudioMediaRecorderControl::setOutputLocation(const QUrl& sink)
|
||||
{
|
||||
return m_session->setOutputLocation(sink);
|
||||
}
|
||||
|
||||
QMediaRecorder::State AudioMediaRecorderControl::state() const
|
||||
{
|
||||
return (QMediaRecorder::State)m_session->state();
|
||||
}
|
||||
|
||||
qint64 AudioMediaRecorderControl::duration() const
|
||||
{
|
||||
return m_session->position();
|
||||
}
|
||||
|
||||
void AudioMediaRecorderControl::record()
|
||||
{
|
||||
m_session->record();
|
||||
}
|
||||
|
||||
void AudioMediaRecorderControl::pause()
|
||||
{
|
||||
m_session->stop();
|
||||
}
|
||||
|
||||
void AudioMediaRecorderControl::stop()
|
||||
{
|
||||
m_session->stop();
|
||||
}
|
||||
|
||||
bool AudioMediaRecorderControl::isMuted() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void AudioMediaRecorderControl::setMuted(bool)
|
||||
{
|
||||
}
|
||||
82
src/plugins/audiocapture/audiomediarecordercontrol.h
Normal file
82
src/plugins/audiocapture/audiomediarecordercontrol.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 AUDIOMEDIARECORDERCONTROL_H
|
||||
#define AUDIOMEDIARECORDERCONTROL_H
|
||||
|
||||
#include <QtCore/qobject.h>
|
||||
|
||||
#include "qmediarecorder.h"
|
||||
#include "qmediarecordercontrol.h"
|
||||
|
||||
class AudioCaptureSession;
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class AudioMediaRecorderControl : public QMediaRecorderControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AudioMediaRecorderControl(QObject *parent = 0);
|
||||
~AudioMediaRecorderControl();
|
||||
|
||||
QUrl outputLocation() const;
|
||||
bool setOutputLocation(const QUrl &sink);
|
||||
|
||||
QMediaRecorder::State state() const;
|
||||
|
||||
qint64 duration() const;
|
||||
|
||||
bool isMuted() const;
|
||||
|
||||
void applySettings() {}
|
||||
|
||||
public slots:
|
||||
void record();
|
||||
void pause();
|
||||
void stop();
|
||||
void setMuted(bool);
|
||||
|
||||
private:
|
||||
AudioCaptureSession* m_session;
|
||||
};
|
||||
|
||||
#endif
|
||||
31
src/plugins/directshow/camera/camera.pri
Normal file
31
src/plugins/directshow/camera/camera.pri
Normal file
@@ -0,0 +1,31 @@
|
||||
INCLUDEPATH += $$PWD
|
||||
|
||||
DEFINES += QMEDIA_DIRECTSHOW_CAMERA
|
||||
|
||||
win32-g++: DEFINES += QT_NO_WMSDK
|
||||
|
||||
win32: DEFINES += _CRT_SECURE_NO_WARNINGS
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/dscameraservice.h \
|
||||
$$PWD/dscameracontrol.h \
|
||||
$$PWD/dsvideorenderer.h \
|
||||
$$PWD/dsvideodevicecontrol.h \
|
||||
$$PWD/dsimagecapturecontrol.h \
|
||||
$$PWD/dscamerasession.h \
|
||||
$$PWD/dsvideowidgetcontrol.h \
|
||||
$$PWD/dscameraservice.h \
|
||||
$$PWD/directshowglobal.h
|
||||
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/dscameraservice.cpp \
|
||||
$$PWD/dscameracontrol.cpp \
|
||||
$$PWD/dsvideorenderer.cpp \
|
||||
$$PWD/dsvideodevicecontrol.cpp \
|
||||
$$PWD/dsimagecapturecontrol.cpp \
|
||||
$$PWD/dscamerasession.cpp \
|
||||
$$PWD/dsvideowidgetcontrol.cpp
|
||||
|
||||
INCLUDEPATH += $(DXSDK_DIR)/include
|
||||
LIBS += -lstrmiids -ldmoguids -luuid -lmsdmo -lole32 -loleaut32
|
||||
236
src/plugins/directshow/camera/directshowglobal.h
Normal file
236
src/plugins/directshow/camera/directshowglobal.h
Normal file
@@ -0,0 +1,236 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 DIRECTSHOWGLOBAL_H
|
||||
#define DIRECTSHOWGLOBAL_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#include <dshow.h>
|
||||
|
||||
DEFINE_GUID(MEDIASUBTYPE_I420,
|
||||
0x30323449,0x0000,0x0010,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71);
|
||||
|
||||
extern const GUID MEDIASUBTYPE_RGB24;
|
||||
extern const GUID MEDIASUBTYPE_RGB32;
|
||||
extern const GUID MEDIASUBTYPE_YUY2;
|
||||
extern const GUID MEDIASUBTYPE_MJPG;
|
||||
extern const GUID MEDIASUBTYPE_RGB555;
|
||||
extern const GUID MEDIASUBTYPE_YVU9;
|
||||
extern const GUID MEDIASUBTYPE_UYVY;
|
||||
extern const GUID PIN_CATEGORY_CAPTURE;
|
||||
extern const GUID PIN_CATEGORY_PREVIEW;
|
||||
|
||||
extern const IID IID_IPropertyBag;
|
||||
extern const IID IID_ISampleGrabber;
|
||||
extern const IID IID_ICaptureGraphBuilder2;
|
||||
extern const IID IID_IAMStreamConfig;
|
||||
|
||||
|
||||
extern const CLSID CLSID_CVidCapClassManager;
|
||||
extern const CLSID CLSID_VideoInputDeviceCategory;
|
||||
extern const CLSID CLSID_SampleGrabber;
|
||||
extern const CLSID CLSID_CaptureGraphBuilder2;
|
||||
|
||||
#define SAFE_RELEASE(x) { if(x) x->Release(); x = NULL; }
|
||||
|
||||
typedef struct IFileSinkFilter *LPFILESINKFILTER;
|
||||
typedef struct IAMCopyCaptureFileProgress *LPAMCOPYCAPTUREFILEPROGRESS;
|
||||
|
||||
#ifndef __ICaptureGraphBuilder2_INTERFACE_DEFINED__
|
||||
#define __ICaptureGraphBuilder2_INTERFACE_DEFINED__
|
||||
struct ICaptureGraphBuilder2 : public IUnknown
|
||||
{
|
||||
public:
|
||||
virtual HRESULT STDMETHODCALLTYPE SetFiltergraph(
|
||||
/* [in] */ IGraphBuilder *pfg) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE GetFiltergraph(
|
||||
/* [out] */ IGraphBuilder **ppfg) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE SetOutputFileName(
|
||||
/* [in] */ const GUID *pType,
|
||||
/* [in] */ LPCOLESTR lpstrFile,
|
||||
/* [out] */ IBaseFilter **ppf,
|
||||
/* [out] */ IFileSinkFilter **ppSink) = 0;
|
||||
|
||||
virtual /* [local] */ HRESULT STDMETHODCALLTYPE FindInterface(
|
||||
/* [in] */ const GUID *pCategory,
|
||||
/* [in] */ const GUID *pType,
|
||||
/* [in] */ IBaseFilter *pf,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [out] */ void **ppint) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE RenderStream(
|
||||
/* [in] */ const GUID *pCategory,
|
||||
/* [in] */ const GUID *pType,
|
||||
/* [in] */ IUnknown *pSource,
|
||||
/* [in] */ IBaseFilter *pfCompressor,
|
||||
/* [in] */ IBaseFilter *pfRenderer) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE ControlStream(
|
||||
/* [in] */ const GUID *pCategory,
|
||||
/* [in] */ const GUID *pType,
|
||||
/* [in] */ IBaseFilter *pFilter,
|
||||
/* [in] */ REFERENCE_TIME *pstart,
|
||||
/* [in] */ REFERENCE_TIME *pstop,
|
||||
/* [in] */ WORD wStartCookie,
|
||||
/* [in] */ WORD wStopCookie) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE AllocCapFile(
|
||||
/* [in] */ LPCOLESTR lpstr,
|
||||
/* [in] */ DWORDLONG dwlSize) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE CopyCaptureFile(
|
||||
/* [in] */ LPOLESTR lpwstrOld,
|
||||
/* [in] */ LPOLESTR lpwstrNew,
|
||||
/* [in] */ int fAllowEscAbort,
|
||||
/* [in] */ IAMCopyCaptureFileProgress *pCallback) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE FindPin(
|
||||
/* [in] */ IUnknown *pSource,
|
||||
/* [in] */ PIN_DIRECTION pindir,
|
||||
/* [in] */ const GUID *pCategory,
|
||||
/* [in] */ const GUID *pType,
|
||||
/* [in] */ BOOL fUnconnected,
|
||||
/* [in] */ int num,
|
||||
/* [out] */ IPin **ppPin) = 0;
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef __IAMStreamConfig_INTERFACE_DEFINED__
|
||||
#define __IAMStreamConfig_INTERFACE_DEFINED__
|
||||
struct IAMStreamConfig : public IUnknown
|
||||
{
|
||||
public:
|
||||
virtual HRESULT STDMETHODCALLTYPE SetFormat(
|
||||
/* [in] */ AM_MEDIA_TYPE *pmt) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE GetFormat(
|
||||
/* [out] */ AM_MEDIA_TYPE **ppmt) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE GetNumberOfCapabilities(
|
||||
/* [out] */ int *piCount,
|
||||
/* [out] */ int *piSize) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE GetStreamCaps(
|
||||
/* [in] */ int iIndex,
|
||||
/* [out] */ AM_MEDIA_TYPE **ppmt,
|
||||
/* [out] */ BYTE *pSCC) = 0;
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef __IErrorLog_INTERFACE_DEFINED__
|
||||
#define __IErrorLog_INTERFACE_DEFINED__
|
||||
struct IErrorLog : public IUnknown
|
||||
{
|
||||
public:
|
||||
virtual HRESULT STDMETHODCALLTYPE AddError(
|
||||
/* [in] */ LPCOLESTR pszPropName,
|
||||
/* [in] */ EXCEPINFO *pExcepInfo) = 0;
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef __IPropertyBag_INTERFACE_DEFINED__
|
||||
#define __IPropertyBag_INTERFACE_DEFINED__
|
||||
struct IPropertyBag : public IUnknown
|
||||
{
|
||||
public:
|
||||
virtual /* [local] */ HRESULT STDMETHODCALLTYPE Read(
|
||||
/* [in] */ LPCOLESTR pszPropName,
|
||||
/* [out][in] */ VARIANT *pVar,
|
||||
/* [in] */ IErrorLog *pErrorLog) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE Write(
|
||||
/* [in] */ LPCOLESTR pszPropName,
|
||||
/* [in] */ VARIANT *pVar) = 0;
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef struct IMediaSample *LPMEDIASAMPLE;
|
||||
|
||||
EXTERN_C const IID IID_ISampleGrabberCB;
|
||||
|
||||
#ifndef __ISampleGrabberCB_INTERFACE_DEFINED__
|
||||
#define __ISampleGrabberCB_INTERFACE_DEFINED__
|
||||
|
||||
#undef INTERFACE
|
||||
#define INTERFACE ISampleGrabberCB
|
||||
DECLARE_INTERFACE_(ISampleGrabberCB, IUnknown)
|
||||
{
|
||||
// STDMETHOD(QueryInterface) (THIS_ const GUID *, void **) PURE;
|
||||
STDMETHOD(QueryInterface) (THIS_ REFIID riid, void **) PURE;
|
||||
STDMETHOD_(ULONG, AddRef) (THIS) PURE;
|
||||
STDMETHOD_(ULONG, Release) (THIS) PURE;
|
||||
STDMETHOD_(HRESULT, SampleCB) (THIS_ double, LPMEDIASAMPLE) PURE;
|
||||
STDMETHOD_(HRESULT, BufferCB) (THIS_ double, BYTE *, long) PURE;
|
||||
};
|
||||
#undef INTERFACE
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __ISampleGrabber_INTERFACE_DEFINED__
|
||||
#define __ISampleGrabber_INTERFACE_DEFINED__
|
||||
|
||||
#define INTERFACE ISampleGrabber
|
||||
DECLARE_INTERFACE_(ISampleGrabber,IUnknown)
|
||||
{
|
||||
STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;
|
||||
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
|
||||
STDMETHOD_(ULONG,Release)(THIS) PURE;
|
||||
STDMETHOD(SetOneShot)(THIS_ BOOL) PURE;
|
||||
STDMETHOD(SetMediaType)(THIS_ const AM_MEDIA_TYPE*) PURE;
|
||||
STDMETHOD(GetConnectedMediaType)(THIS_ AM_MEDIA_TYPE*) PURE;
|
||||
STDMETHOD(SetBufferSamples)(THIS_ BOOL) PURE;
|
||||
STDMETHOD(GetCurrentBuffer)(THIS_ long*,long*) PURE;
|
||||
STDMETHOD(GetCurrentSample)(THIS_ IMediaSample**) PURE;
|
||||
STDMETHOD(SetCallback)(THIS_ ISampleGrabberCB *,long) PURE;
|
||||
};
|
||||
#undef INTERFACE
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
103
src/plugins/directshow/camera/dscameracontrol.cpp
Normal file
103
src/plugins/directshow/camera/dscameracontrol.cpp
Normal file
@@ -0,0 +1,103 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2009 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/qdebug.h>
|
||||
|
||||
#include "dscameracontrol.h"
|
||||
#include "dscameraservice.h"
|
||||
#include "dscamerasession.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
DSCameraControl::DSCameraControl(QObject *parent)
|
||||
:QCameraControl(parent), m_captureMode(QCamera::CaptureStillImage)
|
||||
{
|
||||
m_session = qobject_cast<DSCameraSession*>(parent);
|
||||
connect(m_session, SIGNAL(stateChanged(QCamera::State)),this, SIGNAL(stateChanged(QCamera::State)));
|
||||
}
|
||||
|
||||
DSCameraControl::~DSCameraControl()
|
||||
{
|
||||
}
|
||||
|
||||
void DSCameraControl::setState(QCamera::State state)
|
||||
{
|
||||
switch (state) {
|
||||
case QCamera::ActiveState:
|
||||
start();
|
||||
break;
|
||||
case QCamera::UnloadedState: /* fall through */
|
||||
case QCamera::LoadedState:
|
||||
stop();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool DSCameraControl::isCaptureModeSupported(QCamera::CaptureMode mode) const
|
||||
{
|
||||
bool bCaptureSupported = false;
|
||||
switch (mode) {
|
||||
case QCamera::CaptureStillImage:
|
||||
bCaptureSupported = true;
|
||||
break;
|
||||
case QCamera::CaptureVideo:
|
||||
bCaptureSupported = false;
|
||||
break;
|
||||
}
|
||||
return bCaptureSupported;
|
||||
}
|
||||
|
||||
void DSCameraControl::start()
|
||||
{
|
||||
m_session->record();
|
||||
}
|
||||
|
||||
void DSCameraControl::stop()
|
||||
{
|
||||
m_session->stop();
|
||||
}
|
||||
|
||||
QCamera::State DSCameraControl::state() const
|
||||
{
|
||||
return (QCamera::State)m_session->state();
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
94
src/plugins/directshow/camera/dscameracontrol.h
Normal file
94
src/plugins/directshow/camera/dscameracontrol.h
Normal file
@@ -0,0 +1,94 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2009 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 DSCAMERACONTROL_H
|
||||
#define DSCAMERACONTROL_H
|
||||
|
||||
#include <QtCore/qobject.h>
|
||||
#include <qcameracontrol.h>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class DSCameraService;
|
||||
class DSCameraSession;
|
||||
|
||||
|
||||
class DSCameraControl : public QCameraControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DSCameraControl(QObject *parent = 0);
|
||||
~DSCameraControl();
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
QCamera::State state() const;
|
||||
|
||||
QCamera::CaptureMode captureMode() const { return m_captureMode; }
|
||||
void setCaptureMode(QCamera::CaptureMode mode)
|
||||
{
|
||||
if (m_captureMode != mode) {
|
||||
m_captureMode = mode;
|
||||
emit captureModeChanged(mode);
|
||||
}
|
||||
}
|
||||
|
||||
void setState(QCamera::State state);
|
||||
|
||||
QCamera::Status status() const { return QCamera::UnavailableStatus; }
|
||||
bool isCaptureModeSupported(QCamera::CaptureMode mode) const;
|
||||
bool canChangeProperty(PropertyChangeType /* changeType */, QCamera::Status /* status */) const {return false; }
|
||||
|
||||
private:
|
||||
DSCameraSession *m_session;
|
||||
DSCameraService *m_service;
|
||||
QCamera::CaptureMode m_captureMode;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
114
src/plugins/directshow/camera/dscameraservice.cpp
Normal file
114
src/plugins/directshow/camera/dscameraservice.cpp
Normal file
@@ -0,0 +1,114 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2009 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 <QtGui/qwidget.h>
|
||||
#include <QVideoWidgetControl.h>
|
||||
|
||||
|
||||
#include "dscameraservice.h"
|
||||
#include "dscameracontrol.h"
|
||||
#include "dscamerasession.h"
|
||||
#include "dsvideorenderer.h"
|
||||
#include "dsvideodevicecontrol.h"
|
||||
#include "dsimagecapturecontrol.h"
|
||||
#include "dsvideowidgetcontrol.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
DSCameraService::DSCameraService(QObject *parent):
|
||||
QMediaService(parent)
|
||||
{
|
||||
m_session = new DSCameraSession(this);
|
||||
|
||||
m_control = new DSCameraControl(m_session);
|
||||
|
||||
m_videoDevice = new DSVideoDeviceControl(m_session);
|
||||
|
||||
m_videoRenderer = new DSVideoRendererControl(m_session, this);
|
||||
|
||||
m_imageCapture = new DSImageCaptureControl(m_session);
|
||||
|
||||
m_viewFinderWidget = new DSVideoWidgetControl(m_session);
|
||||
|
||||
m_device = QByteArray("default");
|
||||
}
|
||||
|
||||
DSCameraService::~DSCameraService()
|
||||
{
|
||||
delete m_control;
|
||||
delete m_videoDevice;
|
||||
delete m_videoRenderer;
|
||||
delete m_imageCapture;
|
||||
delete m_viewFinderWidget;
|
||||
delete m_session;
|
||||
}
|
||||
|
||||
QMediaControl* DSCameraService::requestControl(const char *name)
|
||||
{
|
||||
if(qstrcmp(name,QCameraControl_iid) == 0)
|
||||
return m_control;
|
||||
|
||||
if (qstrcmp(name, QCameraImageCaptureControl_iid) == 0)
|
||||
return m_imageCapture;
|
||||
|
||||
if (qstrcmp(name, QVideoWidgetControl_iid) == 0) {
|
||||
if (m_viewFinderWidget) {
|
||||
return m_viewFinderWidget;
|
||||
}
|
||||
}
|
||||
|
||||
if(qstrcmp(name,QVideoRendererControl_iid) == 0)
|
||||
return m_videoRenderer;
|
||||
|
||||
if(qstrcmp(name,QVideoDeviceControl_iid) == 0)
|
||||
return m_videoDevice;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DSCameraService::releaseControl(QMediaControl *control)
|
||||
{
|
||||
// Implemented as a singleton, so we do nothing.
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
88
src/plugins/directshow/camera/dscameraservice.h
Normal file
88
src/plugins/directshow/camera/dscameraservice.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2009 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 DSCAMERASERVICE_H
|
||||
#define DSCAMERASERVICE_H
|
||||
|
||||
#include <QtCore/qobject.h>
|
||||
|
||||
#include <qmediaservice.h>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class DSCameraControl;
|
||||
class DSCameraSession;
|
||||
class DSVideoOutputControl;
|
||||
class DSVideoDeviceControl;
|
||||
class DSVideoRendererControl;
|
||||
class DSImageCaptureControl;
|
||||
class DSVideoWidgetControl;
|
||||
|
||||
|
||||
class DSCameraService : public QMediaService
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DSCameraService(QObject *parent = 0);
|
||||
~DSCameraService();
|
||||
|
||||
virtual QMediaControl* requestControl(const char *name);
|
||||
virtual void releaseControl(QMediaControl *control);
|
||||
|
||||
private:
|
||||
DSCameraControl *m_control;
|
||||
DSCameraSession *m_session;
|
||||
DSVideoOutputControl *m_videoOutput;
|
||||
DSVideoWidgetControl *m_viewFinderWidget;
|
||||
DSVideoDeviceControl *m_videoDevice;
|
||||
DSVideoRendererControl *m_videoRenderer;
|
||||
DSImageCaptureControl *m_imageCapture;
|
||||
QByteArray m_device;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif
|
||||
1160
src/plugins/directshow/camera/dscamerasession.cpp
Normal file
1160
src/plugins/directshow/camera/dscamerasession.cpp
Normal file
File diff suppressed because it is too large
Load Diff
208
src/plugins/directshow/camera/dscamerasession.h
Normal file
208
src/plugins/directshow/camera/dscamerasession.h
Normal file
@@ -0,0 +1,208 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2009 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 DSCAMERASESSION_H
|
||||
#define DSCAMERASESSION_H
|
||||
|
||||
#include <QtCore/qobject.h>
|
||||
#include <QTime>
|
||||
#include <QUrl>
|
||||
#include <QMutex>
|
||||
|
||||
#include <qcamera.h>
|
||||
#include <QtMultimedia/qvideoframe.h>
|
||||
#include <QtMultimedia/qabstractvideosurface.h>
|
||||
#include <QtMultimedia/qvideosurfaceformat.h>
|
||||
|
||||
#include <tchar.h>
|
||||
#include <dshow.h>
|
||||
#include <objbase.h>
|
||||
#include <initguid.h>
|
||||
#pragma comment(lib, "strmiids.lib")
|
||||
#pragma comment(lib, "ole32.lib")
|
||||
#include <windows.h>
|
||||
|
||||
#pragma include_alias("dxtrans.h","qedit.h")
|
||||
#define __IDxtCompositor_INTERFACE_DEFINED__
|
||||
#define __IDxtAlphaSetter_INTERFACE_DEFINED__
|
||||
#define __IDxtJpeg_INTERFACE_DEFINED__
|
||||
#define __IDxtKey_INTERFACE_DEFINED__
|
||||
#include <qedit.h>
|
||||
|
||||
struct ICaptureGraphBuilder2;
|
||||
struct ISampleGrabber;
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class DSVideoRenderer;
|
||||
class SampleGrabberCallbackPrivate;
|
||||
|
||||
|
||||
struct video_buffer {
|
||||
unsigned char* buffer;
|
||||
int length;
|
||||
qint64 time;
|
||||
};
|
||||
|
||||
typedef QMap<unsigned int, QList<QSize> > FormatResolutionMap;
|
||||
|
||||
class DSCameraSession : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DSCameraSession(QObject *parent = 0);
|
||||
~DSCameraSession();
|
||||
|
||||
bool deviceReady();
|
||||
bool pictureInProgress();
|
||||
|
||||
// camera controls
|
||||
|
||||
int framerate() const;
|
||||
void setFrameRate(int rate);
|
||||
int brightness() const;
|
||||
void setBrightness(int b);
|
||||
int contrast() const;
|
||||
void setContrast(int c);
|
||||
int saturation() const;
|
||||
void setSaturation(int s);
|
||||
int hue() const;
|
||||
void setHue(int h);
|
||||
int sharpness() const;
|
||||
void setSharpness(int s);
|
||||
int zoom() const;
|
||||
void setZoom(int z);
|
||||
bool backlightCompensation() const;
|
||||
void setBacklightCompensation(bool);
|
||||
int whitelevel() const;
|
||||
void setWhitelevel(int w);
|
||||
int rotation() const;
|
||||
void setRotation(int r);
|
||||
bool flash() const;
|
||||
void setFlash(bool f);
|
||||
bool autofocus() const;
|
||||
void setAutofocus(bool f);
|
||||
|
||||
QSize frameSize() const;
|
||||
void setFrameSize(const QSize& s);
|
||||
void setDevice(const QString &device);
|
||||
QList<QVideoFrame::PixelFormat> supportedPixelFormats();
|
||||
QVideoFrame::PixelFormat pixelFormat() const;
|
||||
void setPixelFormat(QVideoFrame::PixelFormat fmt);
|
||||
QList<QSize> supportedResolutions(QVideoFrame::PixelFormat format);
|
||||
|
||||
// media control
|
||||
|
||||
bool setOutputLocation(const QUrl &sink);
|
||||
QUrl outputLocation() const;
|
||||
qint64 position() const;
|
||||
int state() const;
|
||||
void record();
|
||||
void pause();
|
||||
void stop();
|
||||
|
||||
void setSurface(QAbstractVideoSurface* surface);
|
||||
|
||||
int captureImage(const QString &fileName);
|
||||
|
||||
AM_MEDIA_TYPE StillMediaType;
|
||||
QList<video_buffer*> frames;
|
||||
SampleGrabberCallbackPrivate* StillCapCB;
|
||||
|
||||
QMutex mutex;
|
||||
|
||||
Q_SIGNALS:
|
||||
void stateChanged(QCamera::State);
|
||||
void imageCaptured(int id, const QImage &preview);
|
||||
void imageSaved(int id, const QString &fileName);
|
||||
void readyForCaptureChanged(bool);
|
||||
|
||||
private Q_SLOTS:
|
||||
void captureFrame();
|
||||
|
||||
private:
|
||||
QVideoSurfaceFormat actualFormat;
|
||||
QList<QVideoFrame::PixelFormat> types;
|
||||
|
||||
QTime timeStamp;
|
||||
bool graph;
|
||||
bool active;
|
||||
bool opened;
|
||||
bool available;
|
||||
QCamera::State m_state;
|
||||
QByteArray m_device;
|
||||
QUrl m_sink;
|
||||
DSVideoRenderer* m_output;
|
||||
QAbstractVideoSurface* m_surface;
|
||||
QVideoFrame::PixelFormat pixelF;
|
||||
QSize m_windowSize;
|
||||
FormatResolutionMap resolutions;
|
||||
|
||||
ICaptureGraphBuilder2* pBuild;
|
||||
IGraphBuilder* pGraph;
|
||||
IBaseFilter* pCap;
|
||||
IBaseFilter* pSG_Filter;
|
||||
ISampleGrabber *pSG;
|
||||
|
||||
|
||||
QString m_snapshot;
|
||||
int m_currentImageId;
|
||||
protected:
|
||||
HRESULT getPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir, IPin **ppPin);
|
||||
bool createFilterGraph();
|
||||
void updateProperties();
|
||||
bool setProperties();
|
||||
bool openStream();
|
||||
void closeStream();
|
||||
bool startStream();
|
||||
void stopStream();
|
||||
void suspendStream();
|
||||
void resumeStream();
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
|
||||
#endif
|
||||
83
src/plugins/directshow/camera/dsimagecapturecontrol.cpp
Normal file
83
src/plugins/directshow/camera/dsimagecapturecontrol.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2009 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/QDebug>
|
||||
|
||||
#include "dsimagecapturecontrol.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
DSImageCaptureControl::DSImageCaptureControl(DSCameraSession *session)
|
||||
:QCameraImageCaptureControl(session), m_session(session), m_ready(false)
|
||||
{
|
||||
connect(m_session, SIGNAL(stateChanged(QCamera::State)), SLOT(updateState()));
|
||||
connect(m_session, SIGNAL(imageCaptured(const int, QImage)),
|
||||
this, SIGNAL(imageCaptured(const int, QImage)));
|
||||
connect(m_session, SIGNAL(imageSaved(const int, const QString &)),
|
||||
this, SIGNAL(imageSaved(const int, const QString &)));
|
||||
connect(m_session, SIGNAL(readyForCaptureChanged(bool)),
|
||||
this, SIGNAL(readyForCaptureChanged(bool)));
|
||||
}
|
||||
|
||||
DSImageCaptureControl::~DSImageCaptureControl()
|
||||
{
|
||||
}
|
||||
|
||||
bool DSImageCaptureControl::isReadyForCapture() const
|
||||
{
|
||||
return m_ready;
|
||||
}
|
||||
|
||||
int DSImageCaptureControl::capture(const QString &fileName)
|
||||
{
|
||||
return m_session->captureImage(fileName);
|
||||
}
|
||||
|
||||
void DSImageCaptureControl::updateState()
|
||||
{
|
||||
bool ready = (m_session->state() == QCamera::ActiveState) &&
|
||||
!m_session->pictureInProgress();
|
||||
if(m_ready != ready)
|
||||
emit readyForCaptureChanged(m_ready = ready);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
80
src/plugins/directshow/camera/dsimagecapturecontrol.h
Normal file
80
src/plugins/directshow/camera/dsimagecapturecontrol.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2009 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 DSIMAGECAPTURECONTROL_H
|
||||
#define DSIMAGECAPTURECONTROL_H
|
||||
|
||||
#include <qcameraimagecapturecontrol.h>
|
||||
#include "dscamerasession.h"
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class DSImageCaptureControl : public QCameraImageCaptureControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DSImageCaptureControl(DSCameraSession *session);
|
||||
virtual ~DSImageCaptureControl();
|
||||
|
||||
bool isReadyForCapture() const;
|
||||
int capture(const QString &fileName);
|
||||
|
||||
virtual QCameraImageCapture::DriveMode driveMode() const { return QCameraImageCapture::SingleImageCapture; }
|
||||
virtual void setDriveMode(QCameraImageCapture::DriveMode mode) { }
|
||||
|
||||
virtual void cancelCapture() {}
|
||||
|
||||
private slots:
|
||||
void updateState();
|
||||
|
||||
|
||||
private:
|
||||
DSCameraSession *m_session;
|
||||
bool m_ready;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif // DSCAPTURECONTROL_H
|
||||
168
src/plugins/directshow/camera/dsvideodevicecontrol.cpp
Normal file
168
src/plugins/directshow/camera/dsvideodevicecontrol.cpp
Normal file
@@ -0,0 +1,168 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2009 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 <QDebug>
|
||||
#include <QFile>
|
||||
#include <QtGui/QIcon>
|
||||
|
||||
#include "dsvideodevicecontrol.h"
|
||||
#include "dscamerasession.h"
|
||||
|
||||
#include <tchar.h>
|
||||
#include <dshow.h>
|
||||
#include <objbase.h>
|
||||
#include <initguid.h>
|
||||
#include <Ocidl.h>
|
||||
#include <string.h>
|
||||
|
||||
extern const CLSID CLSID_VideoInputDeviceCategory;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
DSVideoDeviceControl::DSVideoDeviceControl(QObject *parent)
|
||||
: QVideoDeviceControl(parent)
|
||||
{
|
||||
m_session = qobject_cast<DSCameraSession*>(parent);
|
||||
|
||||
devices.clear();
|
||||
descriptions.clear();
|
||||
|
||||
CoInitialize(NULL);
|
||||
ICreateDevEnum* pDevEnum = NULL;
|
||||
IEnumMoniker* pEnum = NULL;
|
||||
// Create the System device enumerator
|
||||
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
|
||||
CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
|
||||
reinterpret_cast<void**>(&pDevEnum));
|
||||
if(SUCCEEDED(hr)) {
|
||||
// Create the enumerator for the video capture category
|
||||
hr = pDevEnum->CreateClassEnumerator(
|
||||
CLSID_VideoInputDeviceCategory, &pEnum, 0);
|
||||
if (S_OK == hr) {
|
||||
pEnum->Reset();
|
||||
// go through and find all video capture devices
|
||||
IMoniker* pMoniker = NULL;
|
||||
while(pEnum->Next(1, &pMoniker, NULL) == S_OK) {
|
||||
IPropertyBag *pPropBag;
|
||||
hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
|
||||
(void**)(&pPropBag));
|
||||
if(FAILED(hr)) {
|
||||
pMoniker->Release();
|
||||
continue; // skip this one
|
||||
}
|
||||
// Find the description
|
||||
WCHAR str[120];
|
||||
VARIANT varName;
|
||||
varName.vt = VT_BSTR;
|
||||
hr = pPropBag->Read(L"FriendlyName", &varName, 0);
|
||||
if(SUCCEEDED(hr)) {
|
||||
wcsncpy(str, varName.bstrVal, sizeof(str)/sizeof(str[0]));
|
||||
QString temp(QString::fromUtf16((unsigned short*)str));
|
||||
devices.append(QString("ds:%1").arg(temp).toLocal8Bit().constData());
|
||||
hr = pPropBag->Read(L"Description", &varName, 0);
|
||||
wcsncpy(str, varName.bstrVal, sizeof(str)/sizeof(str[0]));
|
||||
QString temp2(QString::fromUtf16((unsigned short*)str));
|
||||
descriptions.append(temp2.toLocal8Bit().constData());
|
||||
}
|
||||
pPropBag->Release();
|
||||
pMoniker->Release();
|
||||
}
|
||||
pEnum->Release();
|
||||
}
|
||||
pDevEnum->Release();
|
||||
}
|
||||
CoUninitialize();
|
||||
|
||||
selected = 0;
|
||||
}
|
||||
|
||||
int DSVideoDeviceControl::deviceCount() const
|
||||
{
|
||||
return devices.count();
|
||||
}
|
||||
|
||||
QString DSVideoDeviceControl::deviceName(int index) const
|
||||
{
|
||||
if(index >= 0 && index <= devices.count())
|
||||
return devices.at(index);
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString DSVideoDeviceControl::deviceDescription(int index) const
|
||||
{
|
||||
if(index >= 0 && index <= descriptions.count())
|
||||
return descriptions.at(index);
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
QIcon DSVideoDeviceControl::deviceIcon(int index) const
|
||||
{
|
||||
Q_UNUSED(index)
|
||||
|
||||
return QIcon();
|
||||
}
|
||||
|
||||
int DSVideoDeviceControl::defaultDevice() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DSVideoDeviceControl::selectedDevice() const
|
||||
{
|
||||
return selected;
|
||||
}
|
||||
|
||||
void DSVideoDeviceControl::setSelectedDevice(int index)
|
||||
{
|
||||
if(index >= 0 && index <= devices.count()) {
|
||||
if (m_session) {
|
||||
QString device = devices.at(index);
|
||||
if (device.startsWith("ds:"))
|
||||
device.remove(0,3);
|
||||
m_session->setDevice(device);
|
||||
}
|
||||
selected = index;
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
83
src/plugins/directshow/camera/dsvideodevicecontrol.h
Normal file
83
src/plugins/directshow/camera/dsvideodevicecontrol.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2009 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 DSVIDEODEVICECONTROL_H
|
||||
#define DSVIDEODEVICECONTROL_H
|
||||
|
||||
#include <qvideodevicecontrol.h>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class DSCameraSession;
|
||||
|
||||
//QTM_USE_NAMESPACE
|
||||
|
||||
class DSVideoDeviceControl : public QVideoDeviceControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DSVideoDeviceControl(QObject *parent = 0);
|
||||
|
||||
int deviceCount() const;
|
||||
QString deviceName(int index) const;
|
||||
QString deviceDescription(int index) const;
|
||||
QIcon deviceIcon(int index) const;
|
||||
int defaultDevice() const;
|
||||
int selectedDevice() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void setSelectedDevice(int index);
|
||||
|
||||
private:
|
||||
DSCameraSession* m_session;
|
||||
|
||||
QList<QString> devices;
|
||||
QList<QString> descriptions;
|
||||
|
||||
int selected;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif
|
||||
72
src/plugins/directshow/camera/dsvideorenderer.cpp
Normal file
72
src/plugins/directshow/camera/dsvideorenderer.cpp
Normal file
@@ -0,0 +1,72 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2009 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/qdebug.h>
|
||||
|
||||
#include "dsvideorenderer.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
DSVideoRendererControl::DSVideoRendererControl(DSCameraSession* session, QObject *parent)
|
||||
:QVideoRendererControl(parent),
|
||||
m_surface(0),
|
||||
m_session(session)
|
||||
{
|
||||
}
|
||||
|
||||
DSVideoRendererControl::~DSVideoRendererControl()
|
||||
{
|
||||
}
|
||||
|
||||
QAbstractVideoSurface* DSVideoRendererControl::surface() const
|
||||
{
|
||||
return m_surface;
|
||||
}
|
||||
|
||||
void DSVideoRendererControl::setSurface(QAbstractVideoSurface *surface)
|
||||
{
|
||||
m_surface = surface;
|
||||
if(m_session)
|
||||
m_session->setSurface(m_surface);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
77
src/plugins/directshow/camera/dsvideorenderer.h
Normal file
77
src/plugins/directshow/camera/dsvideorenderer.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2009 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 DSVIDEORENDERER_H
|
||||
#define DSVIDEORENDERER_H
|
||||
|
||||
#include <qvideorenderercontrol.h>
|
||||
#include "dscamerasession.h"
|
||||
|
||||
class CameraFormatConverter;
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
||||
class DSVideoRendererControl : public QVideoRendererControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DSVideoRendererControl(DSCameraSession* session, QObject *parent = 0);
|
||||
~DSVideoRendererControl();
|
||||
|
||||
QAbstractVideoSurface *surface() const;
|
||||
void setSurface(QAbstractVideoSurface *surface);
|
||||
|
||||
void setSession(DSCameraSession* session);
|
||||
|
||||
private:
|
||||
QAbstractVideoSurface* m_surface;
|
||||
DSCameraSession* m_session;
|
||||
CameraFormatConverter* converter;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif // DSVIDEORENDERER_H
|
||||
250
src/plugins/directshow/camera/dsvideowidgetcontrol.cpp
Normal file
250
src/plugins/directshow/camera/dsvideowidgetcontrol.cpp
Normal file
@@ -0,0 +1,250 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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/qcoreevent.h>
|
||||
#include <QtCore/qtimer.h>
|
||||
|
||||
#include "DSVideoWidgetControl.h"
|
||||
#include "dscamerasession.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
DSVideoWidgetSurface::DSVideoWidgetSurface(QLabel *pWidget, QObject *parent)
|
||||
{
|
||||
widget = pWidget;
|
||||
myPixmap = 0;
|
||||
}
|
||||
|
||||
QList<QVideoFrame::PixelFormat> DSVideoWidgetSurface::supportedPixelFormats(
|
||||
QAbstractVideoBuffer::HandleType handleType) const
|
||||
{
|
||||
if (handleType == QAbstractVideoBuffer::NoHandle) {
|
||||
return QList<QVideoFrame::PixelFormat>()
|
||||
<< QVideoFrame::Format_RGB32
|
||||
<< QVideoFrame::Format_RGB24;
|
||||
} else {
|
||||
return QList<QVideoFrame::PixelFormat>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool DSVideoWidgetSurface::present(const QVideoFrame &frame)
|
||||
{
|
||||
QVideoFrame myFrame = frame;
|
||||
myFrame.map(QAbstractVideoBuffer::ReadOnly);
|
||||
QImage image(
|
||||
frame.bits(),
|
||||
frame.width(),
|
||||
frame.height(),
|
||||
frame.bytesPerLine(),
|
||||
imageFormat);
|
||||
if (image.isNull())
|
||||
{
|
||||
// Try to adapt
|
||||
QImage image2(
|
||||
frame.bits(),
|
||||
frame.width(),
|
||||
frame.height(),
|
||||
frame.bytesPerLine(),
|
||||
QImage::Format_RGB888);
|
||||
image = image2;
|
||||
}
|
||||
myFrame.unmap();
|
||||
delete myPixmap;
|
||||
myPixmap = new QPixmap(QPixmap::fromImage(image).scaled(widget->size()));
|
||||
widget->setPixmap(*myPixmap);
|
||||
widget->repaint();
|
||||
return true;
|
||||
}
|
||||
|
||||
void DSVideoWidgetSurface::setImageFormat(QImage::Format fmt)
|
||||
{
|
||||
imageFormat = fmt;
|
||||
}
|
||||
|
||||
void DSVideoWidgetSurface::updateVideoRect()
|
||||
{
|
||||
}
|
||||
|
||||
void DSVideoWidgetSurface::paint(QPainter *painter)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DSVideoWidgetControl::DSVideoWidgetControl(DSCameraSession* session, QObject *parent) :
|
||||
m_session(session), QVideoWidgetControl(parent),
|
||||
m_widget(new QLabel()),
|
||||
m_fullScreen(false)
|
||||
{
|
||||
m_widget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
|
||||
m_widget->setAlignment(Qt::AlignCenter);
|
||||
m_widget->setAttribute(Qt::WA_NoSystemBackground, true);
|
||||
|
||||
surface = new DSVideoWidgetSurface(m_widget);
|
||||
|
||||
QPalette palette;
|
||||
palette.setColor(QPalette::Background, Qt::black);
|
||||
m_widget->setPalette(palette);
|
||||
m_widget->setAutoFillBackground( true );
|
||||
|
||||
// Request QEvents
|
||||
m_widget->installEventFilter(this);
|
||||
m_windowId = m_widget->effectiveWinId();
|
||||
|
||||
surface->setImageFormat(QImage::Format_RGB888);
|
||||
session->setSurface(surface);
|
||||
}
|
||||
|
||||
DSVideoWidgetControl::~DSVideoWidgetControl()
|
||||
{
|
||||
delete m_widget;
|
||||
}
|
||||
|
||||
bool DSVideoWidgetControl::eventFilter(QObject *object, QEvent *e)
|
||||
{
|
||||
if (object == m_widget) {
|
||||
switch (e->type()) {
|
||||
case QEvent::ParentChange:
|
||||
case QEvent::WinIdChange:
|
||||
case QEvent::Show:
|
||||
m_windowId = m_widget->effectiveWinId();
|
||||
emit widgetUpdated();
|
||||
break;
|
||||
case QEvent::Resize:
|
||||
emit widgetResized(m_widget->size());
|
||||
break;
|
||||
case QEvent::PolishRequest:
|
||||
m_widget->ensurePolished();
|
||||
break;
|
||||
|
||||
default:
|
||||
// Do nothing
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QWidget *DSVideoWidgetControl::videoWidget()
|
||||
{
|
||||
return m_widget;
|
||||
}
|
||||
|
||||
Qt::AspectRatioMode DSVideoWidgetControl::aspectRatioMode() const
|
||||
{
|
||||
return m_aspectRatioMode;
|
||||
}
|
||||
|
||||
void DSVideoWidgetControl::setAspectRatioMode(Qt::AspectRatioMode ratio)
|
||||
{
|
||||
if (m_aspectRatioMode==ratio) {
|
||||
return;
|
||||
}
|
||||
m_aspectRatioMode = ratio;
|
||||
|
||||
if (m_aspectRatioMode == Qt::KeepAspectRatio)
|
||||
m_widget->setScaledContents(false);
|
||||
else {
|
||||
m_widget->setScaledContents(true);
|
||||
}
|
||||
}
|
||||
|
||||
bool DSVideoWidgetControl::isFullScreen() const
|
||||
{
|
||||
return m_fullScreen;
|
||||
}
|
||||
|
||||
void DSVideoWidgetControl::setFullScreen(bool fullScreen)
|
||||
{
|
||||
if (m_widget && !fullScreen && m_fullScreen) {
|
||||
m_widget->showNormal();
|
||||
m_fullScreen = false;
|
||||
} else if (m_widget && fullScreen) {
|
||||
m_widget->showFullScreen();
|
||||
m_fullScreen = true;
|
||||
}
|
||||
|
||||
emit fullScreenChanged(fullScreen);
|
||||
}
|
||||
|
||||
int DSVideoWidgetControl::brightness() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DSVideoWidgetControl::setBrightness(int brightness)
|
||||
{
|
||||
Q_UNUSED(brightness);
|
||||
}
|
||||
|
||||
int DSVideoWidgetControl::contrast() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DSVideoWidgetControl::setContrast(int contrast)
|
||||
{
|
||||
Q_UNUSED(contrast);
|
||||
}
|
||||
|
||||
int DSVideoWidgetControl::hue() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DSVideoWidgetControl::setHue(int hue)
|
||||
{
|
||||
Q_UNUSED(hue);
|
||||
}
|
||||
|
||||
int DSVideoWidgetControl::saturation() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DSVideoWidgetControl::setSaturation(int saturation)
|
||||
{
|
||||
Q_UNUSED(saturation);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
// End of file
|
||||
154
src/plugins/directshow/camera/dsvideowidgetcontrol.h
Normal file
154
src/plugins/directshow/camera/dsvideowidgetcontrol.h
Normal file
@@ -0,0 +1,154 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 DSVIDEOWIDGETCONTROL_H
|
||||
#define DSVIDEOWIDGETCONTROL_H
|
||||
|
||||
#include <QtCore/qobject.h>
|
||||
#include <QtGui>
|
||||
#include <QtMultimedia/qvideoframe.h>
|
||||
#include <QtMultimedia/qabstractvideosurface.h>
|
||||
#include <QtMultimedia/qvideosurfaceformat.h>
|
||||
|
||||
#include <qvideowidgetcontrol.h>
|
||||
#include "DsCameraControl.h"
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class DSVideoWidgetSurface : public QAbstractVideoSurface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DSVideoWidgetSurface(QLabel *pWidget, QObject *parent = 0);
|
||||
|
||||
QList<QVideoFrame::PixelFormat> supportedPixelFormats(
|
||||
QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle) const;
|
||||
|
||||
bool present(const QVideoFrame &frame);
|
||||
|
||||
QRect videoRect() const { return targetRect; }
|
||||
void updateVideoRect();
|
||||
|
||||
void paint(QPainter *painter);
|
||||
void setImageFormat(QImage::Format fmt);
|
||||
|
||||
private:
|
||||
QLabel *widget;
|
||||
QImage::Format imageFormat;
|
||||
QRect targetRect;
|
||||
QSize imageSize;
|
||||
QRect sourceRect;
|
||||
QPixmap* myPixmap;
|
||||
};
|
||||
|
||||
class DSVideoWidgetControl : public QVideoWidgetControl
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
DSVideoWidgetSurface* surface;
|
||||
public: // Constructor & Destructor
|
||||
|
||||
DSVideoWidgetControl(DSCameraSession* session, QObject *parent = 0);
|
||||
virtual ~DSVideoWidgetControl();
|
||||
|
||||
public: // QVideoWidgetControl
|
||||
|
||||
QWidget *videoWidget();
|
||||
|
||||
// Aspect Ratio
|
||||
Qt::AspectRatioMode aspectRatioMode() const;
|
||||
void setAspectRatioMode(Qt::AspectRatioMode ratio);
|
||||
|
||||
// Full Screen
|
||||
bool isFullScreen() const;
|
||||
void setFullScreen(bool fullScreen);
|
||||
|
||||
// Brightness
|
||||
int brightness() const;
|
||||
void setBrightness(int brightness);
|
||||
|
||||
// Contrast
|
||||
int contrast() const;
|
||||
void setContrast(int contrast);
|
||||
|
||||
// Hue
|
||||
int hue() const;
|
||||
void setHue(int hue);
|
||||
|
||||
// Saturation
|
||||
int saturation() const;
|
||||
void setSaturation(int saturation);
|
||||
|
||||
public: // Internal
|
||||
|
||||
bool eventFilter(QObject *object, QEvent *event);
|
||||
|
||||
/*
|
||||
Q_SIGNALS: // QVideoWidgetControl
|
||||
|
||||
void fullScreenChanged(bool fullScreen);
|
||||
void brightnessChanged(int brightness);
|
||||
void contrastChanged(int contrast);
|
||||
void hueChanged(int hue);
|
||||
void saturationChanged(int saturation);
|
||||
*/
|
||||
|
||||
Q_SIGNALS: // Internal Signals
|
||||
|
||||
void widgetResized(QSize size);
|
||||
void widgetUpdated();
|
||||
|
||||
private: // Data
|
||||
|
||||
DSCameraSession* m_session;
|
||||
QLabel *m_widget;
|
||||
WId m_windowId;
|
||||
Qt::AspectRatioMode m_aspectRatioMode;
|
||||
bool m_fullScreen;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif // DSVideoWidgetControl_H
|
||||
23
src/plugins/directshow/directshow.pro
Normal file
23
src/plugins/directshow/directshow.pro
Normal file
@@ -0,0 +1,23 @@
|
||||
TEMPLATE = lib
|
||||
|
||||
CONFIG += plugin
|
||||
TARGET = $$qtLibraryTarget(dsengine)
|
||||
|
||||
PLUGIN_TYPE=mediaservice
|
||||
|
||||
include (../../../common.pri)
|
||||
INCLUDEPATH+=../../multimediakit \
|
||||
../../multimediakit/audio \
|
||||
../../multimediakit/video
|
||||
|
||||
qtAddLibrary(QtMultimediaKit)
|
||||
|
||||
DEPENDPATH += .
|
||||
|
||||
HEADERS += dsserviceplugin.h
|
||||
SOURCES += dsserviceplugin.cpp
|
||||
|
||||
!contains(wmsdk_enabled, yes): DEFINES += QT_NO_WMSDK
|
||||
|
||||
include (player/player.pri)
|
||||
include (camera/camera.pri)
|
||||
211
src/plugins/directshow/dsserviceplugin.cpp
Normal file
211
src/plugins/directshow/dsserviceplugin.cpp
Normal file
@@ -0,0 +1,211 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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/qdebug.h>
|
||||
#include <QtCore/QFile>
|
||||
|
||||
#include "dsserviceplugin.h"
|
||||
|
||||
|
||||
#ifdef QMEDIA_DIRECTSHOW_CAMERA
|
||||
#include "dscameraservice.h"
|
||||
#endif
|
||||
|
||||
#ifdef QMEDIA_DIRECTSHOW_PLAYER
|
||||
#include "directshowplayerservice.h"
|
||||
#endif
|
||||
|
||||
#include <qmediaserviceprovider.h>
|
||||
|
||||
|
||||
#ifdef QMEDIA_DIRECTSHOW_CAMERA
|
||||
|
||||
extern const CLSID CLSID_VideoInputDeviceCategory;
|
||||
|
||||
|
||||
#ifndef _STRSAFE_H_INCLUDED_
|
||||
#include <tchar.h>
|
||||
#endif
|
||||
#include <dshow.h>
|
||||
#include <objbase.h>
|
||||
#include <initguid.h>
|
||||
#pragma comment(lib, "strmiids.lib")
|
||||
#pragma comment(lib, "ole32.lib")
|
||||
#include <windows.h>
|
||||
#include <ocidl.h>
|
||||
#endif
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
QStringList DSServicePlugin::keys() const
|
||||
{
|
||||
return QStringList()
|
||||
#ifdef QMEDIA_DIRECTSHOW_CAMERA
|
||||
<< QLatin1String(Q_MEDIASERVICE_CAMERA)
|
||||
#endif
|
||||
#ifdef QMEDIA_DIRECTSHOW_PLAYER
|
||||
<< QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER)
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
QMediaService* DSServicePlugin::create(QString const& key)
|
||||
{
|
||||
#ifdef QMEDIA_DIRECTSHOW_CAMERA
|
||||
if (key == QLatin1String(Q_MEDIASERVICE_CAMERA))
|
||||
return new DSCameraService;
|
||||
#endif
|
||||
#ifdef QMEDIA_DIRECTSHOW_PLAYER
|
||||
if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER))
|
||||
return new DirectShowPlayerService;
|
||||
#endif
|
||||
|
||||
qDebug() << "unsupported key:" << key;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DSServicePlugin::release(QMediaService *service)
|
||||
{
|
||||
delete service;
|
||||
}
|
||||
|
||||
QMediaServiceProviderHint::Features DSServicePlugin::supportedFeatures(
|
||||
const QByteArray &service) const
|
||||
{
|
||||
if (service == Q_MEDIASERVICE_MEDIAPLAYER)
|
||||
return QMediaServiceProviderHint::StreamPlayback | QMediaServiceProviderHint::VideoSurface;
|
||||
else
|
||||
return QMediaServiceProviderHint::Features();
|
||||
}
|
||||
|
||||
QList<QByteArray> DSServicePlugin::devices(const QByteArray &service) const
|
||||
{
|
||||
#ifdef QMEDIA_DIRECTSHOW_CAMERA
|
||||
if (service == Q_MEDIASERVICE_CAMERA) {
|
||||
if (m_cameraDevices.isEmpty())
|
||||
updateDevices();
|
||||
|
||||
return m_cameraDevices;
|
||||
}
|
||||
#endif
|
||||
|
||||
return QList<QByteArray>();
|
||||
}
|
||||
|
||||
QString DSServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device)
|
||||
{
|
||||
#ifdef QMEDIA_DIRECTSHOW_CAMERA
|
||||
if (service == Q_MEDIASERVICE_CAMERA) {
|
||||
if (m_cameraDevices.isEmpty())
|
||||
updateDevices();
|
||||
|
||||
for (int i=0; i<m_cameraDevices.count(); i++)
|
||||
if (m_cameraDevices[i] == device)
|
||||
return m_cameraDescriptions[i];
|
||||
}
|
||||
#endif
|
||||
return QString();
|
||||
}
|
||||
|
||||
#ifdef QMEDIA_DIRECTSHOW_CAMERA
|
||||
|
||||
void DSServicePlugin::updateDevices() const
|
||||
{
|
||||
m_cameraDevices.clear();
|
||||
m_cameraDescriptions.clear();
|
||||
BOOL bFound = TRUE;
|
||||
CoInitialize(NULL);
|
||||
ICreateDevEnum* pDevEnum = NULL;
|
||||
IEnumMoniker* pEnum = NULL;
|
||||
// Create the System device enumerator
|
||||
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
|
||||
CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
|
||||
reinterpret_cast<void**>(&pDevEnum));
|
||||
if(SUCCEEDED(hr)) {
|
||||
// Create the enumerator for the video capture category
|
||||
hr = pDevEnum->CreateClassEnumerator(
|
||||
CLSID_VideoInputDeviceCategory, &pEnum, 0);
|
||||
if (S_OK == hr) {
|
||||
pEnum->Reset();
|
||||
// go through and find all video capture devices
|
||||
IMoniker* pMoniker = NULL;
|
||||
while(pEnum->Next(1, &pMoniker, NULL) == S_OK) {
|
||||
IPropertyBag *pPropBag;
|
||||
hr = pMoniker->BindToStorage(0,0,IID_IPropertyBag,
|
||||
(void**)(&pPropBag));
|
||||
if(FAILED(hr)) {
|
||||
pMoniker->Release();
|
||||
continue; // skip this one
|
||||
}
|
||||
bFound = TRUE;
|
||||
// Find the description
|
||||
WCHAR str[120];
|
||||
VARIANT varName;
|
||||
varName.vt = VT_BSTR;
|
||||
hr = pPropBag->Read(L"FriendlyName", &varName, 0);
|
||||
if(SUCCEEDED(hr)) {
|
||||
wcsncpy(str, varName.bstrVal, sizeof(str)/sizeof(str[0]));
|
||||
QString temp(QString::fromUtf16((unsigned short*)str));
|
||||
m_cameraDevices.append(QString("ds:%1").arg(temp).toLocal8Bit().constData());
|
||||
hr = pPropBag->Read(L"Description", &varName, 0);
|
||||
wcsncpy(str, varName.bstrVal, sizeof(str)/sizeof(str[0]));
|
||||
QString temp2(QString::fromUtf16((unsigned short*)str));
|
||||
m_cameraDescriptions.append(temp2);
|
||||
} else {
|
||||
qWarning() << "No friendly name";
|
||||
}
|
||||
pPropBag->Release();
|
||||
pMoniker->Release();
|
||||
}
|
||||
pEnum->Release();
|
||||
}
|
||||
pDevEnum->Release();
|
||||
}
|
||||
CoUninitialize();
|
||||
if (!bFound) {
|
||||
qWarning() << "No camera devices found";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Q_EXPORT_PLUGIN2(qtmedia_dsengine, DSServicePlugin);
|
||||
|
||||
76
src/plugins/directshow/dsserviceplugin.h
Normal file
76
src/plugins/directshow/dsserviceplugin.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 DSSERVICEPLUGIN_H
|
||||
#define DSSERVICEPLUGIN_H
|
||||
|
||||
#include "qmediaserviceproviderplugin.h"
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class DSServicePlugin
|
||||
: public QMediaServiceProviderPlugin
|
||||
, public QMediaServiceSupportedDevicesInterface
|
||||
, public QMediaServiceFeaturesInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
|
||||
Q_INTERFACES(QMediaServiceFeaturesInterface)
|
||||
public:
|
||||
QStringList keys() const;
|
||||
QMediaService* create(QString const& key);
|
||||
void release(QMediaService *service);
|
||||
|
||||
QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const;
|
||||
|
||||
QList<QByteArray> devices(const QByteArray &service) const;
|
||||
QString deviceDescription(const QByteArray &service, const QByteArray &device);
|
||||
|
||||
private:
|
||||
#ifdef QMEDIA_DIRECTSHOW_CAMERA
|
||||
void updateDevices() const;
|
||||
|
||||
mutable QList<QByteArray> m_cameraDevices;
|
||||
mutable QStringList m_cameraDescriptions;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // DSSERVICEPLUGIN_H
|
||||
161
src/plugins/directshow/player/directshowaudioendpointcontrol.cpp
Normal file
161
src/plugins/directshow/player/directshowaudioendpointcontrol.cpp
Normal file
@@ -0,0 +1,161 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "directshowaudioendpointcontrol.h"
|
||||
|
||||
#include "directshowglobal.h"
|
||||
#include "directshowplayerservice.h"
|
||||
|
||||
DirectShowAudioEndpointControl::DirectShowAudioEndpointControl(
|
||||
DirectShowPlayerService *service, QObject *parent)
|
||||
: QAudioEndpointSelector(parent)
|
||||
, m_service(service)
|
||||
, m_bindContext(0)
|
||||
, m_deviceEnumerator(0)
|
||||
{
|
||||
if (CreateBindCtx(0, &m_bindContext) == S_OK) {
|
||||
m_deviceEnumerator = com_new<ICreateDevEnum>(CLSID_SystemDeviceEnum, IID_ICreateDevEnum);
|
||||
|
||||
updateEndpoints();
|
||||
|
||||
setActiveEndpoint(m_defaultEndpoint);
|
||||
}
|
||||
}
|
||||
|
||||
DirectShowAudioEndpointControl::~DirectShowAudioEndpointControl()
|
||||
{
|
||||
foreach (IMoniker *moniker, m_devices)
|
||||
moniker->Release();
|
||||
|
||||
if (m_bindContext)
|
||||
m_bindContext->Release();
|
||||
|
||||
if (m_deviceEnumerator)
|
||||
m_deviceEnumerator->Release();
|
||||
}
|
||||
|
||||
QList<QString> DirectShowAudioEndpointControl::availableEndpoints() const
|
||||
{
|
||||
return m_devices.keys();
|
||||
}
|
||||
|
||||
QString DirectShowAudioEndpointControl::endpointDescription(const QString &name) const
|
||||
{
|
||||
#ifdef __IPropertyBag_INTERFACE_DEFINED__
|
||||
QString description;
|
||||
|
||||
if (IMoniker *moniker = m_devices.value(name, 0)) {
|
||||
IPropertyBag *propertyBag = 0;
|
||||
if (SUCCEEDED(moniker->BindToStorage(
|
||||
0, 0, IID_IPropertyBag, reinterpret_cast<void **>(&propertyBag)))) {
|
||||
VARIANT name;
|
||||
VariantInit(&name);
|
||||
if (SUCCEEDED(propertyBag->Read(L"FriendlyName", &name, 0)))
|
||||
description = QString::fromWCharArray(name.bstrVal);
|
||||
VariantClear(&name);
|
||||
propertyBag->Release();
|
||||
}
|
||||
}
|
||||
|
||||
return description;
|
||||
#else
|
||||
return name.section(QLatin1Char('\\'), -1);
|
||||
#endif
|
||||
}
|
||||
|
||||
QString DirectShowAudioEndpointControl::defaultEndpoint() const
|
||||
{
|
||||
return m_defaultEndpoint;
|
||||
}
|
||||
|
||||
QString DirectShowAudioEndpointControl::activeEndpoint() const
|
||||
{
|
||||
return m_activeEndpoint;
|
||||
}
|
||||
|
||||
void DirectShowAudioEndpointControl::setActiveEndpoint(const QString &name)
|
||||
{
|
||||
if (m_activeEndpoint == name)
|
||||
return;
|
||||
|
||||
if (IMoniker *moniker = m_devices.value(name, 0)) {
|
||||
IBaseFilter *filter = 0;
|
||||
|
||||
if (moniker->BindToObject(
|
||||
m_bindContext,
|
||||
0,
|
||||
IID_IBaseFilter,
|
||||
reinterpret_cast<void **>(&filter)) == S_OK) {
|
||||
m_service->setAudioOutput(filter);
|
||||
|
||||
filter->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DirectShowAudioEndpointControl::updateEndpoints()
|
||||
{
|
||||
IMalloc *oleMalloc = 0;
|
||||
if (m_deviceEnumerator && CoGetMalloc(1, &oleMalloc) == S_OK) {
|
||||
IEnumMoniker *monikers = 0;
|
||||
|
||||
if (m_deviceEnumerator->CreateClassEnumerator(
|
||||
CLSID_AudioRendererCategory, &monikers, 0) == S_OK) {
|
||||
for (IMoniker *moniker = 0; monikers->Next(1, &moniker, 0) == S_OK; moniker->Release()) {
|
||||
OLECHAR *string = 0;
|
||||
if (moniker->GetDisplayName(m_bindContext, 0, &string) == S_OK) {
|
||||
QString deviceId = QString::fromWCharArray(string);
|
||||
oleMalloc->Free(string);
|
||||
|
||||
moniker->AddRef();
|
||||
m_devices.insert(deviceId, moniker);
|
||||
|
||||
if (m_defaultEndpoint.isEmpty()
|
||||
|| deviceId.endsWith(QLatin1String("Default DirectSound Device"))) {
|
||||
m_defaultEndpoint = deviceId;
|
||||
}
|
||||
}
|
||||
}
|
||||
monikers->Release();
|
||||
}
|
||||
oleMalloc->Release();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 DIRECTSHOWAUDIOENDPOINTCONTROL_H
|
||||
#define DIRECTSHOWAUDIOENDPOINTCONTROL_H
|
||||
|
||||
#include "qaudioendpointselector.h"
|
||||
|
||||
#include <dshow.h>
|
||||
|
||||
class DirectShowPlayerService;
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class DirectShowAudioEndpointControl : public QAudioEndpointSelector
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DirectShowAudioEndpointControl(DirectShowPlayerService *service, QObject *parent = 0);
|
||||
~DirectShowAudioEndpointControl();
|
||||
|
||||
QList<QString> availableEndpoints() const;
|
||||
|
||||
QString endpointDescription(const QString &name) const;
|
||||
|
||||
QString defaultEndpoint() const;
|
||||
QString activeEndpoint() const;
|
||||
|
||||
void setActiveEndpoint(const QString& name);
|
||||
|
||||
private:
|
||||
void updateEndpoints();
|
||||
|
||||
DirectShowPlayerService *m_service;
|
||||
IBindCtx *m_bindContext;
|
||||
ICreateDevEnum *m_deviceEnumerator;
|
||||
|
||||
QMap<QString, IMoniker *> m_devices;
|
||||
QString m_defaultEndpoint;
|
||||
QString m_activeEndpoint;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
150
src/plugins/directshow/player/directshoweventloop.cpp
Normal file
150
src/plugins/directshow/player/directshoweventloop.cpp
Normal file
@@ -0,0 +1,150 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 <directshoweventloop.h>
|
||||
|
||||
#include <QtCore/qcoreapplication.h>
|
||||
#include <QtCore/qcoreevent.h>
|
||||
|
||||
class DirectShowPostedEvent
|
||||
{
|
||||
public:
|
||||
DirectShowPostedEvent(QObject *receiver, QEvent *event)
|
||||
: receiver(receiver)
|
||||
, event(event)
|
||||
, next(0)
|
||||
{
|
||||
}
|
||||
|
||||
~DirectShowPostedEvent()
|
||||
{
|
||||
delete event;
|
||||
}
|
||||
|
||||
QObject *receiver;
|
||||
QEvent *event;
|
||||
DirectShowPostedEvent *next;
|
||||
};
|
||||
|
||||
DirectShowEventLoop::DirectShowEventLoop(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_postsHead(0)
|
||||
, m_postsTail(0)
|
||||
, m_eventHandle(::CreateEvent(0, 0, 0, 0))
|
||||
, m_waitHandle(::CreateEvent(0, 0, 0, 0))
|
||||
{
|
||||
}
|
||||
|
||||
DirectShowEventLoop::~DirectShowEventLoop()
|
||||
{
|
||||
::CloseHandle(m_eventHandle);
|
||||
::CloseHandle(m_waitHandle);
|
||||
|
||||
for (DirectShowPostedEvent *post = m_postsHead; post; post = m_postsHead) {
|
||||
m_postsHead = m_postsHead->next;
|
||||
|
||||
delete post;
|
||||
}
|
||||
}
|
||||
|
||||
void DirectShowEventLoop::wait(QMutex *mutex)
|
||||
{
|
||||
::ResetEvent(m_waitHandle);
|
||||
|
||||
mutex->unlock();
|
||||
|
||||
HANDLE handles[] = { m_eventHandle, m_waitHandle };
|
||||
while (::WaitForMultipleObjects(2, handles, false, INFINITE) == WAIT_OBJECT_0)
|
||||
processEvents();
|
||||
|
||||
mutex->lock();
|
||||
}
|
||||
|
||||
void DirectShowEventLoop::wake()
|
||||
{
|
||||
::SetEvent(m_waitHandle);
|
||||
}
|
||||
|
||||
void DirectShowEventLoop::postEvent(QObject *receiver, QEvent *event)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
DirectShowPostedEvent *post = new DirectShowPostedEvent(receiver, event);
|
||||
|
||||
if (m_postsTail)
|
||||
m_postsTail->next = post;
|
||||
else
|
||||
m_postsHead = post;
|
||||
|
||||
m_postsTail = post;
|
||||
|
||||
QCoreApplication::postEvent(this, new QEvent(QEvent::User));
|
||||
::SetEvent(m_eventHandle);
|
||||
}
|
||||
|
||||
void DirectShowEventLoop::customEvent(QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::User) {
|
||||
processEvents();
|
||||
} else {
|
||||
QObject::customEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
void DirectShowEventLoop::processEvents()
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
::ResetEvent(m_eventHandle);
|
||||
|
||||
while(m_postsHead) {
|
||||
DirectShowPostedEvent *post = m_postsHead;
|
||||
m_postsHead = m_postsHead->next;
|
||||
|
||||
if (!m_postsHead)
|
||||
m_postsTail = 0;
|
||||
|
||||
locker.unlock();
|
||||
QCoreApplication::sendEvent(post->receiver, post->event);
|
||||
delete post;
|
||||
locker.relock();
|
||||
}
|
||||
}
|
||||
78
src/plugins/directshow/player/directshoweventloop.h
Normal file
78
src/plugins/directshow/player/directshoweventloop.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 DIRECTSHOWEVENTLOOP_H
|
||||
#define DIRECTSHOWEVENTLOOP_H
|
||||
|
||||
#include <QtCore/qmutex.h>
|
||||
#include <QtCore/qobject.h>
|
||||
#include <QtCore/qwaitcondition.h>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
class DirectShowPostedEvent;
|
||||
|
||||
class DirectShowEventLoop : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DirectShowEventLoop(QObject *parent = 0);
|
||||
~DirectShowEventLoop();
|
||||
|
||||
void wait(QMutex *mutex);
|
||||
void wake();
|
||||
|
||||
void postEvent(QObject *object, QEvent *event);
|
||||
|
||||
protected:
|
||||
void customEvent(QEvent *event);
|
||||
|
||||
private:
|
||||
void processEvents();
|
||||
|
||||
DirectShowPostedEvent *m_postsHead;
|
||||
DirectShowPostedEvent *m_postsTail;
|
||||
HANDLE m_eventHandle;
|
||||
HANDLE m_waitHandle;
|
||||
QMutex m_mutex;
|
||||
};
|
||||
|
||||
#endif
|
||||
139
src/plugins/directshow/player/directshowglobal.h
Normal file
139
src/plugins/directshow/player/directshowglobal.h
Normal file
@@ -0,0 +1,139 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 DIRECTSHOWGLOBAL_H
|
||||
#define DIRECTSHOWGLOBAL_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#include <dshow.h>
|
||||
|
||||
template <typename T> T *com_cast(IUnknown *unknown, const IID &iid)
|
||||
{
|
||||
T *iface = 0;
|
||||
return unknown && unknown->QueryInterface(iid, reinterpret_cast<void **>(&iface)) == S_OK
|
||||
? iface
|
||||
: 0;
|
||||
}
|
||||
|
||||
template <typename T> T *com_new(const IID &clsid, const IID &iid)
|
||||
{
|
||||
T *object = 0;
|
||||
return CoCreateInstance(
|
||||
clsid,
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
iid,
|
||||
reinterpret_cast<void **>(&object)) == S_OK
|
||||
? object
|
||||
: 0;
|
||||
}
|
||||
|
||||
#ifndef __IFilterGraph2_INTERFACE_DEFINED__
|
||||
#define __IFilterGraph2_INTERFACE_DEFINED__
|
||||
#define INTERFACE IFilterGraph2
|
||||
DECLARE_INTERFACE_(IFilterGraph2 ,IGraphBuilder)
|
||||
{
|
||||
STDMETHOD(AddSourceFilterForMoniker)(THIS_ IMoniker *, IBindCtx *, LPCWSTR,IBaseFilter **) PURE;
|
||||
STDMETHOD(ReconnectEx)(THIS_ IPin *, const AM_MEDIA_TYPE *) PURE;
|
||||
STDMETHOD(RenderEx)(IPin *, DWORD, DWORD *) PURE;
|
||||
};
|
||||
#undef INTERFACE
|
||||
#endif
|
||||
|
||||
#ifndef __IAMFilterMiscFlags_INTERFACE_DEFINED__
|
||||
#define __IAMFilterMiscFlags_INTERFACE_DEFINED__
|
||||
#define INTERFACE IAMFilterMiscFlags
|
||||
DECLARE_INTERFACE_(IAMFilterMiscFlags ,IUnknown)
|
||||
{
|
||||
STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;
|
||||
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
|
||||
STDMETHOD_(ULONG,Release)(THIS) PURE;
|
||||
STDMETHOD_(ULONG,GetMiscFlags)(THIS) PURE;
|
||||
};
|
||||
#undef INTERFACE
|
||||
#endif
|
||||
|
||||
#ifndef __IFileSourceFilter_INTERFACE_DEFINED__
|
||||
#define __IFileSourceFilter_INTERFACE_DEFINED__
|
||||
#define INTERFACE IFileSourceFilter
|
||||
DECLARE_INTERFACE_(IFileSourceFilter ,IUnknown)
|
||||
{
|
||||
STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;
|
||||
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
|
||||
STDMETHOD_(ULONG,Release)(THIS) PURE;
|
||||
STDMETHOD(Load)(THIS_ LPCOLESTR, const AM_MEDIA_TYPE *) PURE;
|
||||
STDMETHOD(GetCurFile)(THIS_ LPOLESTR *ppszFileName, AM_MEDIA_TYPE *) PURE;
|
||||
};
|
||||
#undef INTERFACE
|
||||
#endif
|
||||
|
||||
#ifndef __IAMOpenProgress_INTERFACE_DEFINED__
|
||||
#define __IAMOpenProgress_INTERFACE_DEFINED__
|
||||
#define INTERFACE IAMOpenProgress
|
||||
DECLARE_INTERFACE_(IAMOpenProgress ,IUnknown)
|
||||
{
|
||||
STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;
|
||||
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
|
||||
STDMETHOD_(ULONG,Release)(THIS) PURE;
|
||||
STDMETHOD(QueryProgress)(THIS_ LONGLONG *, LONGLONG *) PURE;
|
||||
STDMETHOD(AbortOperation)(THIS) PURE;
|
||||
};
|
||||
#undef INTERFACE
|
||||
#endif
|
||||
|
||||
#ifndef __IFilterChain_INTERFACE_DEFINED__
|
||||
#define __IFilterChain_INTERFACE_DEFINED__
|
||||
#define INTERFACE IFilterChain
|
||||
DECLARE_INTERFACE_(IFilterChain ,IUnknown)
|
||||
{
|
||||
STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;
|
||||
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
|
||||
STDMETHOD_(ULONG,Release)(THIS) PURE;
|
||||
STDMETHOD(StartChain)(IBaseFilter *, IBaseFilter *) PURE;
|
||||
STDMETHOD(PauseChain)(IBaseFilter *, IBaseFilter *) PURE;
|
||||
STDMETHOD(StopChain)(IBaseFilter *, IBaseFilter *) PURE;
|
||||
STDMETHOD(RemoveChain)(IBaseFilter *, IBaseFilter *) PURE;
|
||||
};
|
||||
#undef INTERFACE
|
||||
#endif
|
||||
|
||||
#endif
|
||||
496
src/plugins/directshow/player/directshowioreader.cpp
Normal file
496
src/plugins/directshow/player/directshowioreader.cpp
Normal file
@@ -0,0 +1,496 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "directshowioreader.h"
|
||||
|
||||
#include "directshoweventloop.h"
|
||||
#include "directshowglobal.h"
|
||||
#include "directshowiosource.h"
|
||||
|
||||
#include <QtCore/qcoreapplication.h>
|
||||
#include <QtCore/qcoreevent.h>
|
||||
#include <QtCore/qiodevice.h>
|
||||
#include <QtCore/qthread.h>
|
||||
|
||||
class DirectShowSampleRequest
|
||||
{
|
||||
public:
|
||||
DirectShowSampleRequest(
|
||||
IMediaSample *sample, DWORD_PTR userData, LONGLONG position, LONG length, BYTE *buffer)
|
||||
: next(0)
|
||||
, sample(sample)
|
||||
, userData(userData)
|
||||
, position(position)
|
||||
, length(length)
|
||||
, buffer(buffer)
|
||||
, result(S_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
DirectShowSampleRequest *remove() { DirectShowSampleRequest *n = next; delete this; return n; }
|
||||
|
||||
DirectShowSampleRequest *next;
|
||||
IMediaSample *sample;
|
||||
DWORD_PTR userData;
|
||||
LONGLONG position;
|
||||
LONG length;
|
||||
BYTE *buffer;
|
||||
HRESULT result;
|
||||
};
|
||||
|
||||
DirectShowIOReader::DirectShowIOReader(
|
||||
QIODevice *device, DirectShowIOSource *source, DirectShowEventLoop *loop)
|
||||
: m_source(source)
|
||||
, m_device(device)
|
||||
, m_loop(loop)
|
||||
, m_pendingHead(0)
|
||||
, m_pendingTail(0)
|
||||
, m_readyHead(0)
|
||||
, m_readyTail(0)
|
||||
, m_synchronousPosition(0)
|
||||
, m_synchronousLength(0)
|
||||
, m_synchronousBytesRead(0)
|
||||
, m_synchronousBuffer(0)
|
||||
, m_synchronousResult(S_OK)
|
||||
, m_totalLength(0)
|
||||
, m_availableLength(0)
|
||||
, m_flushing(false)
|
||||
{
|
||||
moveToThread(device->thread());
|
||||
|
||||
connect(device, SIGNAL(readyRead()), this, SLOT(readyRead()));
|
||||
}
|
||||
|
||||
DirectShowIOReader::~DirectShowIOReader()
|
||||
{
|
||||
flushRequests();
|
||||
}
|
||||
|
||||
HRESULT DirectShowIOReader::QueryInterface(REFIID riid, void **ppvObject)
|
||||
{
|
||||
return m_source->QueryInterface(riid, ppvObject);
|
||||
}
|
||||
|
||||
ULONG DirectShowIOReader::AddRef()
|
||||
{
|
||||
return m_source->AddRef();
|
||||
}
|
||||
|
||||
ULONG DirectShowIOReader::Release()
|
||||
{
|
||||
return m_source->Release();
|
||||
}
|
||||
|
||||
// IAsyncReader
|
||||
HRESULT DirectShowIOReader::RequestAllocator(
|
||||
IMemAllocator *pPreferred, ALLOCATOR_PROPERTIES *pProps, IMemAllocator **ppActual)
|
||||
{
|
||||
if (!ppActual || !pProps) {
|
||||
return E_POINTER;
|
||||
} else {
|
||||
ALLOCATOR_PROPERTIES actualProperties;
|
||||
|
||||
if (pProps->cbAlign == 0)
|
||||
pProps->cbAlign = 1;
|
||||
|
||||
if (pPreferred && pPreferred->SetProperties(pProps, &actualProperties) == S_OK) {
|
||||
pPreferred->AddRef();
|
||||
|
||||
*ppActual = pPreferred;
|
||||
|
||||
m_source->setAllocator(*ppActual);
|
||||
|
||||
return S_OK;
|
||||
} else {
|
||||
*ppActual = com_new<IMemAllocator>(CLSID_MemoryAllocator, IID_IMemAllocator);
|
||||
|
||||
if (*ppActual) {
|
||||
if ((*ppActual)->SetProperties(pProps, &actualProperties) != S_OK) {
|
||||
(*ppActual)->Release();
|
||||
} else {
|
||||
m_source->setAllocator(*ppActual);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
ppActual = 0;
|
||||
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT DirectShowIOReader::Request(IMediaSample *pSample, DWORD_PTR dwUser)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
if (!pSample) {
|
||||
return E_POINTER;
|
||||
} else if (m_flushing) {
|
||||
return VFW_E_WRONG_STATE;
|
||||
} else {
|
||||
REFERENCE_TIME startTime = 0;
|
||||
REFERENCE_TIME endTime = 0;
|
||||
BYTE *buffer;
|
||||
|
||||
if (pSample->GetTime(&startTime, &endTime) != S_OK
|
||||
|| pSample->GetPointer(&buffer) != S_OK) {
|
||||
return VFW_E_SAMPLE_TIME_NOT_SET;
|
||||
} else {
|
||||
LONGLONG position = startTime / 10000000;
|
||||
LONG length = (endTime - startTime) / 10000000;
|
||||
|
||||
DirectShowSampleRequest *request = new DirectShowSampleRequest(
|
||||
pSample, dwUser, position, length, buffer);
|
||||
|
||||
if (m_pendingTail) {
|
||||
m_pendingTail->next = request;
|
||||
} else {
|
||||
m_pendingHead = request;
|
||||
|
||||
m_loop->postEvent(this, new QEvent(QEvent::User));
|
||||
}
|
||||
m_pendingTail = request;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT DirectShowIOReader::WaitForNext(
|
||||
DWORD dwTimeout, IMediaSample **ppSample, DWORD_PTR *pdwUser)
|
||||
{
|
||||
if (!ppSample || !pdwUser)
|
||||
return E_POINTER;
|
||||
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
do {
|
||||
if (m_readyHead) {
|
||||
DirectShowSampleRequest *request = m_readyHead;
|
||||
|
||||
*ppSample = request->sample;
|
||||
*pdwUser = request->userData;
|
||||
|
||||
HRESULT hr = request->result;
|
||||
|
||||
m_readyHead = request->next;
|
||||
|
||||
if (!m_readyHead)
|
||||
m_readyTail = 0;
|
||||
|
||||
delete request;
|
||||
|
||||
return hr;
|
||||
} else if (m_flushing) {
|
||||
*ppSample = 0;
|
||||
*pdwUser = 0;
|
||||
|
||||
return VFW_E_WRONG_STATE;
|
||||
}
|
||||
} while (m_wait.wait(&m_mutex, dwTimeout));
|
||||
|
||||
*ppSample = 0;
|
||||
*pdwUser = 0;
|
||||
|
||||
return VFW_E_TIMEOUT;
|
||||
}
|
||||
|
||||
HRESULT DirectShowIOReader::SyncReadAligned(IMediaSample *pSample)
|
||||
{
|
||||
if (!pSample) {
|
||||
return E_POINTER;
|
||||
} else {
|
||||
REFERENCE_TIME startTime = 0;
|
||||
REFERENCE_TIME endTime = 0;
|
||||
BYTE *buffer;
|
||||
|
||||
if (pSample->GetTime(&startTime, &endTime) != S_OK
|
||||
|| pSample->GetPointer(&buffer) != S_OK) {
|
||||
return VFW_E_SAMPLE_TIME_NOT_SET;
|
||||
} else {
|
||||
LONGLONG position = startTime / 10000000;
|
||||
LONG length = (endTime - startTime) / 10000000;
|
||||
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
if (thread() == QThread::currentThread()) {
|
||||
qint64 bytesRead = 0;
|
||||
|
||||
HRESULT hr = blockingRead(position, length, buffer, &bytesRead);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
pSample->SetActualDataLength(bytesRead);
|
||||
|
||||
return hr;
|
||||
} else {
|
||||
m_synchronousPosition = position;
|
||||
m_synchronousLength = length;
|
||||
m_synchronousBuffer = buffer;
|
||||
|
||||
m_loop->postEvent(this, new QEvent(QEvent::User));
|
||||
|
||||
m_wait.wait(&m_mutex);
|
||||
|
||||
m_synchronousBuffer = 0;
|
||||
|
||||
if (SUCCEEDED(m_synchronousResult))
|
||||
pSample->SetActualDataLength(m_synchronousBytesRead);
|
||||
|
||||
return m_synchronousResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT DirectShowIOReader::SyncRead(LONGLONG llPosition, LONG lLength, BYTE *pBuffer)
|
||||
{
|
||||
if (!pBuffer) {
|
||||
return E_POINTER;
|
||||
} else {
|
||||
if (thread() == QThread::currentThread()) {
|
||||
qint64 bytesRead;
|
||||
|
||||
return blockingRead(llPosition, lLength, pBuffer, &bytesRead);
|
||||
} else {
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
m_synchronousPosition = llPosition;
|
||||
m_synchronousLength = lLength;
|
||||
m_synchronousBuffer = pBuffer;
|
||||
|
||||
m_loop->postEvent(this, new QEvent(QEvent::User));
|
||||
|
||||
m_wait.wait(&m_mutex);
|
||||
|
||||
m_synchronousBuffer = 0;
|
||||
|
||||
return m_synchronousResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT DirectShowIOReader::Length(LONGLONG *pTotal, LONGLONG *pAvailable)
|
||||
{
|
||||
if (!pTotal || !pAvailable) {
|
||||
return E_POINTER;
|
||||
} else {
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
*pTotal = m_totalLength;
|
||||
*pAvailable = m_availableLength;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
HRESULT DirectShowIOReader::BeginFlush()
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
if (m_flushing)
|
||||
return S_FALSE;
|
||||
|
||||
m_flushing = true;
|
||||
|
||||
flushRequests();
|
||||
|
||||
m_wait.wakeAll();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT DirectShowIOReader::EndFlush()
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
if (!m_flushing)
|
||||
return S_FALSE;
|
||||
|
||||
m_flushing = false;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void DirectShowIOReader::customEvent(QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::User) {
|
||||
readyRead();
|
||||
} else {
|
||||
QObject::customEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
void DirectShowIOReader::readyRead()
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
m_availableLength = m_device->bytesAvailable() + m_device->pos();
|
||||
m_totalLength = m_device->size();
|
||||
|
||||
if (m_synchronousBuffer) {
|
||||
if (nonBlockingRead(
|
||||
m_synchronousPosition,
|
||||
m_synchronousLength,
|
||||
m_synchronousBuffer,
|
||||
&m_synchronousBytesRead,
|
||||
&m_synchronousResult)) {
|
||||
m_wait.wakeAll();
|
||||
}
|
||||
} else {
|
||||
qint64 bytesRead = 0;
|
||||
|
||||
while (m_pendingHead && nonBlockingRead(
|
||||
m_pendingHead->position,
|
||||
m_pendingHead->length,
|
||||
m_pendingHead->buffer,
|
||||
&bytesRead,
|
||||
&m_pendingHead->result)) {
|
||||
m_pendingHead->sample->SetActualDataLength(bytesRead);
|
||||
|
||||
if (m_readyTail)
|
||||
m_readyTail->next = m_pendingHead;
|
||||
m_readyTail = m_pendingHead;
|
||||
|
||||
m_pendingHead = m_pendingHead->next;
|
||||
|
||||
m_readyTail->next = 0;
|
||||
|
||||
if (!m_pendingHead)
|
||||
m_pendingTail = 0;
|
||||
|
||||
if (!m_readyHead)
|
||||
m_readyHead = m_readyTail;
|
||||
|
||||
m_wait.wakeAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT DirectShowIOReader::blockingRead(
|
||||
LONGLONG position, LONG length, BYTE *buffer, qint64 *bytesRead)
|
||||
{
|
||||
*bytesRead = 0;
|
||||
|
||||
if (qint64(position) > m_device->size())
|
||||
return S_FALSE;
|
||||
|
||||
const qint64 maxSize = qMin<qint64>(m_device->size(), position + length);
|
||||
|
||||
while (m_device->bytesAvailable() + m_device->pos() < maxSize) {
|
||||
if (!m_device->waitForReadyRead(-1))
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
if (m_device->pos() != position && !m_device->seek(position))
|
||||
return S_FALSE;
|
||||
|
||||
const qint64 maxBytes = qMin<qint64>(length, m_device->bytesAvailable());
|
||||
|
||||
*bytesRead = m_device->read(reinterpret_cast<char *>(buffer), maxBytes);
|
||||
|
||||
if (*bytesRead != length) {
|
||||
qMemSet(buffer + *bytesRead, 0, length - *bytesRead);
|
||||
|
||||
return S_FALSE;
|
||||
} else {
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
bool DirectShowIOReader::nonBlockingRead(
|
||||
LONGLONG position, LONG length, BYTE *buffer, qint64 *bytesRead, HRESULT *result)
|
||||
{
|
||||
const qint64 maxSize = qMin<qint64>(m_device->size(), position + length);
|
||||
|
||||
if (position > m_device->size()) {
|
||||
*bytesRead = 0;
|
||||
*result = S_FALSE;
|
||||
|
||||
return true;
|
||||
} else if (m_device->bytesAvailable() + m_device->pos() >= maxSize) {
|
||||
if (m_device->pos() != position && !m_device->seek(position)) {
|
||||
*bytesRead = 0;
|
||||
*result = S_FALSE;
|
||||
|
||||
return true;
|
||||
} else {
|
||||
const qint64 maxBytes = qMin<qint64>(length, m_device->bytesAvailable());
|
||||
|
||||
*bytesRead = m_device->read(reinterpret_cast<char *>(buffer), maxBytes);
|
||||
|
||||
if (*bytesRead != length) {
|
||||
qMemSet(buffer + *bytesRead, 0, length - *bytesRead);
|
||||
|
||||
*result = S_FALSE;
|
||||
} else {
|
||||
*result = S_OK;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void DirectShowIOReader::flushRequests()
|
||||
{
|
||||
while (m_pendingHead) {
|
||||
m_pendingHead->result = VFW_E_WRONG_STATE;
|
||||
|
||||
if (m_readyTail)
|
||||
m_readyTail->next = m_pendingHead;
|
||||
|
||||
m_readyTail = m_pendingHead;
|
||||
|
||||
m_pendingHead = m_pendingHead->next;
|
||||
|
||||
m_readyTail->next = 0;
|
||||
|
||||
if (!m_pendingHead)
|
||||
m_pendingTail = 0;
|
||||
|
||||
if (!m_readyHead)
|
||||
m_readyHead = m_readyTail;
|
||||
}
|
||||
}
|
||||
120
src/plugins/directshow/player/directshowioreader.h
Normal file
120
src/plugins/directshow/player/directshowioreader.h
Normal file
@@ -0,0 +1,120 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 DIRECTSHOWIOREADER_H
|
||||
#define DIRECTSHOWIOREADER_H
|
||||
|
||||
#include <QtCore/qmutex.h>
|
||||
#include <QtCore/qobject.h>
|
||||
#include <QtCore/qwaitcondition.h>
|
||||
|
||||
#include <dshow.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QIODevice;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class DirectShowEventLoop;
|
||||
class DirectShowIOSource;
|
||||
class DirectShowSampleRequest;
|
||||
|
||||
class DirectShowIOReader : public QObject, public IAsyncReader
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DirectShowIOReader(QIODevice *device, DirectShowIOSource *source, DirectShowEventLoop *loop);
|
||||
~DirectShowIOReader();
|
||||
|
||||
// IUnknown
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject);
|
||||
ULONG STDMETHODCALLTYPE AddRef();
|
||||
ULONG STDMETHODCALLTYPE Release();
|
||||
|
||||
// IAsyncReader
|
||||
HRESULT STDMETHODCALLTYPE RequestAllocator(
|
||||
IMemAllocator *pPreferred, ALLOCATOR_PROPERTIES *pProps, IMemAllocator **ppActual);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE Request(IMediaSample *pSample, DWORD_PTR dwUser);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE WaitForNext(
|
||||
DWORD dwTimeout, IMediaSample **ppSample, DWORD_PTR *pdwUser);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE SyncReadAligned(IMediaSample *pSample);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE SyncRead(LONGLONG llPosition, LONG lLength, BYTE *pBuffer);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE Length(LONGLONG *pTotal, LONGLONG *pAvailable);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE BeginFlush();
|
||||
HRESULT STDMETHODCALLTYPE EndFlush();
|
||||
|
||||
protected:
|
||||
void customEvent(QEvent *event);
|
||||
|
||||
private Q_SLOTS:
|
||||
void readyRead();
|
||||
|
||||
private:
|
||||
HRESULT blockingRead(LONGLONG position, LONG length, BYTE *buffer, qint64 *bytesRead);
|
||||
bool nonBlockingRead(
|
||||
LONGLONG position, LONG length, BYTE *buffer, qint64 *bytesRead, HRESULT *result);
|
||||
void flushRequests();
|
||||
|
||||
DirectShowIOSource *m_source;
|
||||
QIODevice *m_device;
|
||||
DirectShowEventLoop *m_loop;
|
||||
DirectShowSampleRequest *m_pendingHead;
|
||||
DirectShowSampleRequest *m_pendingTail;
|
||||
DirectShowSampleRequest *m_readyHead;
|
||||
DirectShowSampleRequest *m_readyTail;
|
||||
LONGLONG m_synchronousPosition;
|
||||
LONG m_synchronousLength;
|
||||
qint64 m_synchronousBytesRead;
|
||||
BYTE *m_synchronousBuffer;
|
||||
HRESULT m_synchronousResult;
|
||||
LONGLONG m_totalLength;
|
||||
LONGLONG m_availableLength;
|
||||
bool m_flushing;
|
||||
QMutex m_mutex;
|
||||
QWaitCondition m_wait;
|
||||
};
|
||||
|
||||
#endif
|
||||
639
src/plugins/directshow/player/directshowiosource.cpp
Normal file
639
src/plugins/directshow/player/directshowiosource.cpp
Normal file
@@ -0,0 +1,639 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "directshowiosource.h"
|
||||
|
||||
#include "directshowglobal.h"
|
||||
#include "directshowmediatype.h"
|
||||
#include "directshowpinenum.h"
|
||||
|
||||
#include <QtCore/qcoreapplication.h>
|
||||
#include <QtCore/qurl.h>
|
||||
|
||||
static const GUID directshow_subtypes[] =
|
||||
{
|
||||
MEDIASUBTYPE_Avi,
|
||||
MEDIASUBTYPE_WAVE,
|
||||
MEDIASUBTYPE_NULL
|
||||
};
|
||||
|
||||
DirectShowIOSource::DirectShowIOSource(DirectShowEventLoop *loop)
|
||||
: m_ref(1)
|
||||
, m_state(State_Stopped)
|
||||
, m_reader(0)
|
||||
, m_loop(loop)
|
||||
, m_graph(0)
|
||||
, m_clock(0)
|
||||
, m_allocator(0)
|
||||
, m_peerPin(0)
|
||||
, m_pinId(QLatin1String("Data"))
|
||||
{
|
||||
QVector<AM_MEDIA_TYPE> mediaTypes;
|
||||
|
||||
AM_MEDIA_TYPE type =
|
||||
{
|
||||
MEDIATYPE_Stream, // majortype
|
||||
MEDIASUBTYPE_NULL, // subtype
|
||||
TRUE, // bFixedSizeSamples
|
||||
FALSE, // bTemporalCompression
|
||||
1, // lSampleSize
|
||||
GUID_NULL, // formattype
|
||||
0, // pUnk
|
||||
0, // cbFormat
|
||||
0, // pbFormat
|
||||
};
|
||||
|
||||
static const int count = sizeof(directshow_subtypes) / sizeof(GUID);
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
type.subtype = directshow_subtypes[i];
|
||||
mediaTypes.append(type);
|
||||
}
|
||||
|
||||
setMediaTypes(mediaTypes);
|
||||
}
|
||||
|
||||
DirectShowIOSource::~DirectShowIOSource()
|
||||
{
|
||||
Q_ASSERT(m_ref == 0);
|
||||
|
||||
delete m_reader;
|
||||
}
|
||||
|
||||
void DirectShowIOSource::setDevice(QIODevice *device)
|
||||
{
|
||||
Q_ASSERT(!m_reader);
|
||||
|
||||
m_reader = new DirectShowIOReader(device, this, m_loop);
|
||||
}
|
||||
|
||||
void DirectShowIOSource::setAllocator(IMemAllocator *allocator)
|
||||
{
|
||||
if (m_allocator)
|
||||
m_allocator->Release();
|
||||
|
||||
m_allocator = allocator;
|
||||
|
||||
if (m_allocator)
|
||||
m_allocator->AddRef();
|
||||
}
|
||||
|
||||
// IUnknown
|
||||
HRESULT DirectShowIOSource::QueryInterface(REFIID riid, void **ppvObject)
|
||||
{
|
||||
// 2dd74950-a890-11d1-abe8-00a0c905f375
|
||||
static const GUID iid_IAmFilterMiscFlags = {
|
||||
0x2dd74950, 0xa890, 0x11d1, {0xab, 0xe8, 0x00, 0xa0, 0xc9, 0x05, 0xf3, 0x75}};
|
||||
|
||||
if (!ppvObject) {
|
||||
return E_POINTER;
|
||||
} else if (riid == IID_IUnknown
|
||||
|| riid == IID_IPersist
|
||||
|| riid == IID_IMediaFilter
|
||||
|| riid == IID_IBaseFilter) {
|
||||
*ppvObject = static_cast<IBaseFilter *>(this);
|
||||
} else if (riid == iid_IAmFilterMiscFlags) {
|
||||
*ppvObject = static_cast<IAMFilterMiscFlags *>(this);
|
||||
} else if (riid == IID_IPin) {
|
||||
*ppvObject = static_cast<IPin *>(this);
|
||||
} else if (riid == IID_IAsyncReader) {
|
||||
*ppvObject = static_cast<IAsyncReader *>(m_reader);
|
||||
} else {
|
||||
*ppvObject = 0;
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
AddRef();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
ULONG DirectShowIOSource::AddRef()
|
||||
{
|
||||
return InterlockedIncrement(&m_ref);
|
||||
}
|
||||
|
||||
ULONG DirectShowIOSource::Release()
|
||||
{
|
||||
ULONG ref = InterlockedDecrement(&m_ref);
|
||||
|
||||
if (ref == 0) {
|
||||
delete this;
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
// IPersist
|
||||
HRESULT DirectShowIOSource::GetClassID(CLSID *pClassID)
|
||||
{
|
||||
*pClassID = CLSID_NULL;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// IMediaFilter
|
||||
HRESULT DirectShowIOSource::Run(REFERENCE_TIME tStart)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
m_state = State_Running;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT DirectShowIOSource::Pause()
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
m_state = State_Paused;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT DirectShowIOSource::Stop()
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
m_state = State_Stopped;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT DirectShowIOSource::GetState(DWORD dwMilliSecsTimeout, FILTER_STATE *pState)
|
||||
{
|
||||
Q_UNUSED(dwMilliSecsTimeout);
|
||||
|
||||
if (!pState) {
|
||||
return E_POINTER;
|
||||
} else {
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
*pState = m_state;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT DirectShowIOSource::SetSyncSource(IReferenceClock *pClock)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
if (m_clock)
|
||||
m_clock->Release();
|
||||
|
||||
m_clock = pClock;
|
||||
|
||||
if (m_clock)
|
||||
m_clock->AddRef();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT DirectShowIOSource::GetSyncSource(IReferenceClock **ppClock)
|
||||
{
|
||||
if (!ppClock) {
|
||||
return E_POINTER;
|
||||
} else {
|
||||
if (!m_clock) {
|
||||
*ppClock = 0;
|
||||
|
||||
return S_FALSE;
|
||||
} else {
|
||||
m_clock->AddRef();
|
||||
|
||||
*ppClock = m_clock;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IBaseFilter
|
||||
HRESULT DirectShowIOSource::EnumPins(IEnumPins **ppEnum)
|
||||
{
|
||||
if (!ppEnum) {
|
||||
return E_POINTER;
|
||||
} else {
|
||||
*ppEnum = new DirectShowPinEnum(QList<IPin *>() << this);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT DirectShowIOSource::FindPin(LPCWSTR Id, IPin **ppPin)
|
||||
{
|
||||
if (!ppPin || !Id) {
|
||||
return E_POINTER;
|
||||
} else {
|
||||
QMutexLocker locker(&m_mutex);
|
||||
if (QString::fromWCharArray(Id) == m_pinId) {
|
||||
AddRef();
|
||||
|
||||
*ppPin = this;
|
||||
|
||||
return S_OK;
|
||||
} else {
|
||||
*ppPin = 0;
|
||||
|
||||
return VFW_E_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT DirectShowIOSource::JoinFilterGraph(IFilterGraph *pGraph, LPCWSTR pName)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
m_graph = pGraph;
|
||||
m_filterName = QString::fromWCharArray(pName);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT DirectShowIOSource::QueryFilterInfo(FILTER_INFO *pInfo)
|
||||
{
|
||||
if (!pInfo) {
|
||||
return E_POINTER;
|
||||
} else {
|
||||
QString name = m_filterName;
|
||||
|
||||
if (name.length() >= MAX_FILTER_NAME)
|
||||
name.truncate(MAX_FILTER_NAME - 1);
|
||||
|
||||
int length = name.toWCharArray(pInfo->achName);
|
||||
pInfo->achName[length] = '\0';
|
||||
|
||||
if (m_graph)
|
||||
m_graph->AddRef();
|
||||
|
||||
pInfo->pGraph = m_graph;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT DirectShowIOSource::QueryVendorInfo(LPWSTR *pVendorInfo)
|
||||
{
|
||||
Q_UNUSED(pVendorInfo);
|
||||
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
// IAMFilterMiscFlags
|
||||
ULONG DirectShowIOSource::GetMiscFlags()
|
||||
{
|
||||
return AM_FILTER_MISC_FLAGS_IS_SOURCE;
|
||||
}
|
||||
|
||||
// IPin
|
||||
HRESULT DirectShowIOSource::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
if (!pReceivePin) {
|
||||
return E_POINTER;
|
||||
} else if (m_state != State_Stopped) {
|
||||
return VFW_E_NOT_STOPPED;
|
||||
} else if (m_peerPin) {
|
||||
return VFW_E_ALREADY_CONNECTED;
|
||||
} else {
|
||||
HRESULT hr = VFW_E_TYPE_NOT_ACCEPTED;
|
||||
|
||||
m_peerPin = pReceivePin;
|
||||
m_peerPin->AddRef();
|
||||
|
||||
if (!pmt) {
|
||||
IEnumMediaTypes *mediaTypes = 0;
|
||||
if (pReceivePin->EnumMediaTypes(&mediaTypes) == S_OK) {
|
||||
for (AM_MEDIA_TYPE *type = 0;
|
||||
mediaTypes->Next(1, &type, 0) == S_OK;
|
||||
DirectShowMediaType::deleteType(type)) {
|
||||
switch (tryConnect(pReceivePin, type)) {
|
||||
case S_OK:
|
||||
DirectShowMediaType::freeData(type);
|
||||
mediaTypes->Release();
|
||||
return S_OK;
|
||||
case VFW_E_NO_TRANSPORT:
|
||||
hr = VFW_E_NO_TRANSPORT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
mediaTypes->Release();
|
||||
}
|
||||
AM_MEDIA_TYPE type =
|
||||
{
|
||||
MEDIATYPE_Stream, // majortype
|
||||
MEDIASUBTYPE_NULL, // subtype
|
||||
TRUE, // bFixedSizeSamples
|
||||
FALSE, // bTemporalCompression
|
||||
1, // lSampleSize
|
||||
GUID_NULL, // formattype
|
||||
0, // pUnk
|
||||
0, // cbFormat
|
||||
0, // pbFormat
|
||||
};
|
||||
|
||||
static const int count = sizeof(directshow_subtypes) / sizeof(GUID);
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
type.subtype = directshow_subtypes[i];
|
||||
|
||||
switch (tryConnect(pReceivePin, &type)) {
|
||||
case S_OK:
|
||||
return S_OK;
|
||||
case VFW_E_NO_TRANSPORT:
|
||||
hr = VFW_E_NO_TRANSPORT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (pmt->majortype == MEDIATYPE_Stream && (hr = tryConnect(pReceivePin, pmt))) {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
m_peerPin->Release();
|
||||
m_peerPin = 0;
|
||||
|
||||
m_mediaType.clear();
|
||||
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT DirectShowIOSource::tryConnect(IPin *pin, const AM_MEDIA_TYPE *type)
|
||||
{
|
||||
m_mediaType = *type;
|
||||
|
||||
HRESULT hr = pin->ReceiveConnection(this, type);
|
||||
|
||||
if (!SUCCEEDED(hr)) {
|
||||
if (m_allocator) {
|
||||
m_allocator->Release();
|
||||
m_allocator = 0;
|
||||
}
|
||||
} else if (!m_allocator) {
|
||||
hr = VFW_E_NO_TRANSPORT;
|
||||
|
||||
if (IMemInputPin *memPin = com_cast<IMemInputPin>(pin, IID_IMemInputPin)) {
|
||||
if ((m_allocator = com_new<IMemAllocator>(CLSID_MemoryAllocator, IID_IMemAllocator))) {
|
||||
ALLOCATOR_PROPERTIES properties;
|
||||
if (memPin->GetAllocatorRequirements(&properties) == S_OK
|
||||
|| m_allocator->GetProperties(&properties) == S_OK) {
|
||||
if (properties.cbAlign == 0)
|
||||
properties.cbAlign = 1;
|
||||
|
||||
ALLOCATOR_PROPERTIES actualProperties;
|
||||
if (SUCCEEDED(hr = m_allocator->SetProperties(&properties, &actualProperties)))
|
||||
hr = memPin->NotifyAllocator(m_allocator, TRUE);
|
||||
}
|
||||
if (!SUCCEEDED(hr)) {
|
||||
m_allocator->Release();
|
||||
m_allocator = 0;
|
||||
}
|
||||
}
|
||||
memPin->Release();
|
||||
}
|
||||
if (!SUCCEEDED(hr))
|
||||
pin->Disconnect();
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT DirectShowIOSource::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt)
|
||||
{
|
||||
Q_UNUSED(pConnector);
|
||||
Q_UNUSED(pmt);
|
||||
// Output pin.
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT DirectShowIOSource::Disconnect()
|
||||
{
|
||||
if (!m_peerPin) {
|
||||
return S_FALSE;
|
||||
} else if (m_state != State_Stopped) {
|
||||
return VFW_E_NOT_STOPPED;
|
||||
} else {
|
||||
HRESULT hr = m_peerPin->Disconnect();
|
||||
|
||||
if (!SUCCEEDED(hr))
|
||||
return hr;
|
||||
|
||||
if (m_allocator) {
|
||||
m_allocator->Release();
|
||||
m_allocator = 0;
|
||||
}
|
||||
|
||||
m_peerPin->Release();
|
||||
m_peerPin = 0;
|
||||
|
||||
m_mediaType.clear();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT DirectShowIOSource::ConnectedTo(IPin **ppPin)
|
||||
{
|
||||
if (!ppPin) {
|
||||
return E_POINTER;
|
||||
} else {
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
if (!m_peerPin) {
|
||||
*ppPin = 0;
|
||||
|
||||
return VFW_E_NOT_CONNECTED;
|
||||
} else {
|
||||
m_peerPin->AddRef();
|
||||
|
||||
*ppPin = m_peerPin;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT DirectShowIOSource::ConnectionMediaType(AM_MEDIA_TYPE *pmt)
|
||||
{
|
||||
if (!pmt) {
|
||||
return E_POINTER;
|
||||
} else {
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
if (!m_peerPin) {
|
||||
pmt = 0;
|
||||
|
||||
return VFW_E_NOT_CONNECTED;
|
||||
} else {
|
||||
DirectShowMediaType::copy(pmt, m_mediaType);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT DirectShowIOSource::QueryPinInfo(PIN_INFO *pInfo)
|
||||
{
|
||||
if (!pInfo) {
|
||||
return E_POINTER;
|
||||
} else {
|
||||
AddRef();
|
||||
|
||||
pInfo->pFilter = this;
|
||||
pInfo->dir = PINDIR_OUTPUT;
|
||||
|
||||
const int bytes = qMin(MAX_FILTER_NAME, (m_pinId.length() + 1) * 2);
|
||||
|
||||
qMemCopy(pInfo->achName, m_pinId.utf16(), bytes);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT DirectShowIOSource::QueryId(LPWSTR *Id)
|
||||
{
|
||||
if (!Id) {
|
||||
return E_POINTER;
|
||||
} else {
|
||||
const int bytes = (m_pinId.length() + 1) * 2;
|
||||
|
||||
*Id = static_cast<LPWSTR>(::CoTaskMemAlloc(bytes));
|
||||
|
||||
qMemCopy(*Id, m_pinId.utf16(), bytes);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT DirectShowIOSource::QueryAccept(const AM_MEDIA_TYPE *pmt)
|
||||
{
|
||||
if (!pmt) {
|
||||
return E_POINTER;
|
||||
} else if (pmt->majortype == MEDIATYPE_Stream) {
|
||||
return S_OK;
|
||||
} else {
|
||||
return S_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT DirectShowIOSource::EnumMediaTypes(IEnumMediaTypes **ppEnum)
|
||||
{
|
||||
if (!ppEnum) {
|
||||
return E_POINTER;
|
||||
} else {
|
||||
*ppEnum = createMediaTypeEnum();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT DirectShowIOSource::QueryInternalConnections(IPin **apPin, ULONG *nPin)
|
||||
{
|
||||
Q_UNUSED(apPin);
|
||||
Q_UNUSED(nPin);
|
||||
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT DirectShowIOSource::EndOfStream()
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT DirectShowIOSource::BeginFlush()
|
||||
{
|
||||
return m_reader->BeginFlush();
|
||||
}
|
||||
|
||||
HRESULT DirectShowIOSource::EndFlush()
|
||||
{
|
||||
return m_reader->EndFlush();
|
||||
}
|
||||
|
||||
HRESULT DirectShowIOSource::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
|
||||
{
|
||||
Q_UNUSED(tStart);
|
||||
Q_UNUSED(tStop);
|
||||
Q_UNUSED(dRate);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT DirectShowIOSource::QueryDirection(PIN_DIRECTION *pPinDir)
|
||||
{
|
||||
if (!pPinDir) {
|
||||
return E_POINTER;
|
||||
} else {
|
||||
*pPinDir = PINDIR_OUTPUT;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
DirectShowRcSource::DirectShowRcSource(DirectShowEventLoop *loop)
|
||||
: DirectShowIOSource(loop)
|
||||
{
|
||||
}
|
||||
|
||||
bool DirectShowRcSource::open(const QUrl &url)
|
||||
{
|
||||
m_file.moveToThread(QCoreApplication::instance()->thread());
|
||||
|
||||
m_file.setFileName(QLatin1Char(':') + url.path());
|
||||
|
||||
qDebug("qrc file %s", qPrintable(m_file.fileName()));
|
||||
|
||||
if (m_file.open(QIODevice::ReadOnly)) {
|
||||
qDebug("Size %d", m_file.size());
|
||||
qDebug("Sequential %d", int(m_file.isSequential()));
|
||||
|
||||
setDevice(&m_file);
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
149
src/plugins/directshow/player/directshowiosource.h
Normal file
149
src/plugins/directshow/player/directshowiosource.h
Normal file
@@ -0,0 +1,149 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 DIRECTSHOWIOSOURCE_H
|
||||
#define DIRECTSHOWIOSOURCE_H
|
||||
|
||||
#include "directshowglobal.h"
|
||||
#include "directshowioreader.h"
|
||||
#include "directshowmediatype.h"
|
||||
#include "directshowmediatypelist.h"
|
||||
|
||||
#include <QtCore/qfile.h>
|
||||
|
||||
class DirectShowIOSource
|
||||
: public DirectShowMediaTypeList
|
||||
, public IBaseFilter
|
||||
, public IAMFilterMiscFlags
|
||||
, public IPin
|
||||
{
|
||||
public:
|
||||
DirectShowIOSource(DirectShowEventLoop *loop);
|
||||
~DirectShowIOSource();
|
||||
|
||||
void setDevice(QIODevice *device);
|
||||
void setAllocator(IMemAllocator *allocator);
|
||||
|
||||
// IUnknown
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject);
|
||||
ULONG STDMETHODCALLTYPE AddRef();
|
||||
ULONG STDMETHODCALLTYPE Release();
|
||||
|
||||
// IPersist
|
||||
HRESULT STDMETHODCALLTYPE GetClassID(CLSID *pClassID);
|
||||
|
||||
// IMediaFilter
|
||||
HRESULT STDMETHODCALLTYPE Run(REFERENCE_TIME tStart);
|
||||
HRESULT STDMETHODCALLTYPE Pause();
|
||||
HRESULT STDMETHODCALLTYPE Stop();
|
||||
|
||||
HRESULT STDMETHODCALLTYPE GetState(DWORD dwMilliSecsTimeout, FILTER_STATE *pState);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE SetSyncSource(IReferenceClock *pClock);
|
||||
HRESULT STDMETHODCALLTYPE GetSyncSource(IReferenceClock **ppClock);
|
||||
|
||||
// IBaseFilter
|
||||
HRESULT STDMETHODCALLTYPE EnumPins(IEnumPins **ppEnum);
|
||||
HRESULT STDMETHODCALLTYPE FindPin(LPCWSTR Id, IPin **ppPin);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE JoinFilterGraph(IFilterGraph *pGraph, LPCWSTR pName);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE QueryFilterInfo(FILTER_INFO *pInfo);
|
||||
HRESULT STDMETHODCALLTYPE QueryVendorInfo(LPWSTR *pVendorInfo);
|
||||
|
||||
// IAMFilterMiscFlags
|
||||
ULONG STDMETHODCALLTYPE GetMiscFlags();
|
||||
|
||||
// IPin
|
||||
HRESULT STDMETHODCALLTYPE Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt);
|
||||
HRESULT STDMETHODCALLTYPE ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt);
|
||||
HRESULT STDMETHODCALLTYPE Disconnect();
|
||||
HRESULT STDMETHODCALLTYPE ConnectedTo(IPin **ppPin);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE ConnectionMediaType(AM_MEDIA_TYPE *pmt);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE QueryPinInfo(PIN_INFO *pInfo);
|
||||
HRESULT STDMETHODCALLTYPE QueryId(LPWSTR *Id);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE QueryAccept(const AM_MEDIA_TYPE *pmt);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE EnumMediaTypes(IEnumMediaTypes **ppEnum);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE QueryInternalConnections(IPin **apPin, ULONG *nPin);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE EndOfStream();
|
||||
|
||||
HRESULT STDMETHODCALLTYPE BeginFlush();
|
||||
HRESULT STDMETHODCALLTYPE EndFlush();
|
||||
|
||||
HRESULT STDMETHODCALLTYPE NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE QueryDirection(PIN_DIRECTION *pPinDir);
|
||||
|
||||
private:
|
||||
HRESULT tryConnect(IPin *pin, const AM_MEDIA_TYPE *type);
|
||||
|
||||
volatile LONG m_ref;
|
||||
FILTER_STATE m_state;
|
||||
DirectShowIOReader *m_reader;
|
||||
DirectShowEventLoop *m_loop;
|
||||
IFilterGraph *m_graph;
|
||||
IReferenceClock *m_clock;
|
||||
IMemAllocator *m_allocator;
|
||||
IPin *m_peerPin;
|
||||
DirectShowMediaType m_mediaType;
|
||||
QString m_filterName;
|
||||
const QString m_pinId;
|
||||
QMutex m_mutex;
|
||||
};
|
||||
|
||||
class DirectShowRcSource : public DirectShowIOSource
|
||||
{
|
||||
public:
|
||||
DirectShowRcSource(DirectShowEventLoop *loop);
|
||||
|
||||
bool open(const QUrl &url);
|
||||
|
||||
private:
|
||||
QFile m_file;
|
||||
};
|
||||
|
||||
#endif
|
||||
184
src/plugins/directshow/player/directshowmediatype.cpp
Normal file
184
src/plugins/directshow/player/directshowmediatype.cpp
Normal file
@@ -0,0 +1,184 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "directshowmediatype.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct TypeLookup
|
||||
{
|
||||
QVideoFrame::PixelFormat pixelFormat;
|
||||
GUID mediaType;
|
||||
};
|
||||
|
||||
static const TypeLookup qt_typeLookup[] =
|
||||
{
|
||||
{ QVideoFrame::Format_RGB32, /*MEDIASUBTYPE_RGB32*/ {0xe436eb7e, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}} },
|
||||
{ QVideoFrame::Format_BGR24, /*MEDIASUBTYPE_RGB24*/ {0xe436eb7d, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}} },
|
||||
{ QVideoFrame::Format_RGB565, /*MEDIASUBTYPE_RGB565*/ {0xe436eb7b, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}} },
|
||||
{ QVideoFrame::Format_RGB555, /*MEDIASUBTYPE_RGB555*/ {0xe436eb7c, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}} },
|
||||
{ QVideoFrame::Format_AYUV444, /*MEDIASUBTYPE_AYUV*/ {0x56555941, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}} },
|
||||
{ QVideoFrame::Format_YUYV, /*MEDIASUBTYPE_YUY2*/ {0x32595559, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}} },
|
||||
{ QVideoFrame::Format_UYVY, /*MEDIASUBTYPE_UYVY*/ {0x59565955, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}} },
|
||||
{ QVideoFrame::Format_IMC1, /*MEDIASUBTYPE_IMC1*/ {0x31434D49, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}} },
|
||||
{ QVideoFrame::Format_IMC2, /*MEDIASUBTYPE_IMC2*/ {0x32434D49, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}} },
|
||||
{ QVideoFrame::Format_IMC3, /*MEDIASUBTYPE_IMC3*/ {0x33434D49, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}} },
|
||||
{ QVideoFrame::Format_IMC4, /*MEDIASUBTYPE_IMC4*/ {0x34434D49, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}} },
|
||||
{ QVideoFrame::Format_YV12, /*MEDIASUBTYPE_YV12*/ {0x32315659, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}} },
|
||||
{ QVideoFrame::Format_NV12, /*MEDIASUBTYPE_NV12*/ {0x3231564E, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}} },
|
||||
{ QVideoFrame::Format_YUV420P, /*MEDIASUBTYPE_IYUV*/ {0x56555949, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}} }
|
||||
};
|
||||
}
|
||||
|
||||
void DirectShowMediaType::copy(AM_MEDIA_TYPE *target, const AM_MEDIA_TYPE &source)
|
||||
{
|
||||
*target = source;
|
||||
|
||||
if (source.cbFormat > 0) {
|
||||
target->pbFormat = reinterpret_cast<PBYTE>(CoTaskMemAlloc(source.cbFormat));
|
||||
memcpy(target->pbFormat, source.pbFormat, source.cbFormat);
|
||||
}
|
||||
if (target->pUnk)
|
||||
target->pUnk->AddRef();
|
||||
}
|
||||
|
||||
void DirectShowMediaType::deleteType(AM_MEDIA_TYPE *type)
|
||||
{
|
||||
freeData(type);
|
||||
|
||||
CoTaskMemFree(type);
|
||||
}
|
||||
|
||||
void DirectShowMediaType::freeData(AM_MEDIA_TYPE *type)
|
||||
{
|
||||
if (type->cbFormat > 0)
|
||||
CoTaskMemFree(type->pbFormat);
|
||||
|
||||
if (type->pUnk)
|
||||
type->pUnk->Release();
|
||||
}
|
||||
|
||||
|
||||
GUID DirectShowMediaType::convertPixelFormat(QVideoFrame::PixelFormat format)
|
||||
{
|
||||
// MEDIASUBTYPE_None;
|
||||
static const GUID none = {
|
||||
0xe436eb8e, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70} };
|
||||
|
||||
const int count = sizeof(qt_typeLookup) / sizeof(TypeLookup);
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
if (qt_typeLookup[i].pixelFormat == format)
|
||||
return qt_typeLookup[i].mediaType;
|
||||
return none;
|
||||
}
|
||||
|
||||
QVideoSurfaceFormat DirectShowMediaType::formatFromType(const AM_MEDIA_TYPE &type)
|
||||
{
|
||||
const int count = sizeof(qt_typeLookup) / sizeof(TypeLookup);
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
if (IsEqualGUID(qt_typeLookup[i].mediaType, type.subtype) && type.cbFormat > 0) {
|
||||
if (IsEqualGUID(type.formattype, FORMAT_VideoInfo)) {
|
||||
VIDEOINFOHEADER *header = reinterpret_cast<VIDEOINFOHEADER *>(type.pbFormat);
|
||||
|
||||
QVideoSurfaceFormat format(
|
||||
QSize(header->bmiHeader.biWidth, qAbs(header->bmiHeader.biHeight)),
|
||||
qt_typeLookup[i].pixelFormat);
|
||||
|
||||
if (header->AvgTimePerFrame > 0)
|
||||
format.setFrameRate(10000 /header->AvgTimePerFrame);
|
||||
|
||||
format.setScanLineDirection(header->bmiHeader.biHeight < 0
|
||||
? QVideoSurfaceFormat::TopToBottom
|
||||
: QVideoSurfaceFormat::BottomToTop);
|
||||
|
||||
return format;
|
||||
} else if (IsEqualGUID(type.formattype, FORMAT_VideoInfo2)) {
|
||||
VIDEOINFOHEADER2 *header = reinterpret_cast<VIDEOINFOHEADER2 *>(type.pbFormat);
|
||||
|
||||
QVideoSurfaceFormat format(
|
||||
QSize(header->bmiHeader.biWidth, qAbs(header->bmiHeader.biHeight)),
|
||||
qt_typeLookup[i].pixelFormat);
|
||||
|
||||
if (header->AvgTimePerFrame > 0)
|
||||
format.setFrameRate(10000 / header->AvgTimePerFrame);
|
||||
|
||||
format.setScanLineDirection(header->bmiHeader.biHeight < 0
|
||||
? QVideoSurfaceFormat::TopToBottom
|
||||
: QVideoSurfaceFormat::BottomToTop);
|
||||
|
||||
return format;
|
||||
}
|
||||
}
|
||||
}
|
||||
return QVideoSurfaceFormat();
|
||||
}
|
||||
|
||||
int DirectShowMediaType::bytesPerLine(const QVideoSurfaceFormat &format)
|
||||
{
|
||||
switch (format.pixelFormat()) {
|
||||
// 32 bpp packed formats.
|
||||
case QVideoFrame::Format_RGB32:
|
||||
case QVideoFrame::Format_AYUV444:
|
||||
return format.frameWidth() * 4;
|
||||
// 24 bpp packed formats.
|
||||
case QVideoFrame::Format_RGB24:
|
||||
return format.frameWidth() * 3 + 3 - format.frameWidth() % 4;
|
||||
// 16 bpp packed formats.
|
||||
case QVideoFrame::Format_RGB565:
|
||||
case QVideoFrame::Format_RGB555:
|
||||
case QVideoFrame::Format_YUYV:
|
||||
case QVideoFrame::Format_UYVY:
|
||||
return format.frameWidth() * 2 + 3 - format.frameWidth() % 4;
|
||||
// Planar formats.
|
||||
case QVideoFrame::Format_IMC1:
|
||||
case QVideoFrame::Format_IMC2:
|
||||
case QVideoFrame::Format_IMC3:
|
||||
case QVideoFrame::Format_IMC4:
|
||||
case QVideoFrame::Format_YV12:
|
||||
case QVideoFrame::Format_NV12:
|
||||
case QVideoFrame::Format_YUV420P:
|
||||
return format.frameWidth() + 3 - format.frameWidth() % 4;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
74
src/plugins/directshow/player/directshowmediatype.h
Normal file
74
src/plugins/directshow/player/directshowmediatype.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 DIRECTSHOWMEDIATYPE_H
|
||||
#define DIRECTSHOWMEDIATYPE_H
|
||||
|
||||
#include <qvideosurfaceformat.h>
|
||||
|
||||
#include <dshow.h>
|
||||
#include <dvdmedia.h>
|
||||
|
||||
class DirectShowMediaType : public AM_MEDIA_TYPE
|
||||
{
|
||||
public:
|
||||
DirectShowMediaType() { memset(this, 0, sizeof(DirectShowMediaType)); }
|
||||
DirectShowMediaType(const AM_MEDIA_TYPE &type) { copy(this, type); }
|
||||
DirectShowMediaType(const DirectShowMediaType &other) { copy(this, other); }
|
||||
DirectShowMediaType &operator =(const AM_MEDIA_TYPE &type) {
|
||||
freeData(this); copy(this, type); return *this; }
|
||||
DirectShowMediaType &operator =(const DirectShowMediaType &other) {
|
||||
freeData(this); copy(this, other); return *this; }
|
||||
~DirectShowMediaType() { freeData(this); }
|
||||
|
||||
void clear() { freeData(this); memset(this, 0, sizeof(DirectShowMediaType)); }
|
||||
|
||||
static void copy(AM_MEDIA_TYPE *target, const AM_MEDIA_TYPE &source);
|
||||
static void freeData(AM_MEDIA_TYPE *type);
|
||||
static void deleteType(AM_MEDIA_TYPE *type);
|
||||
|
||||
static GUID convertPixelFormat(QVideoFrame::PixelFormat format);
|
||||
static QVideoSurfaceFormat formatFromType(const AM_MEDIA_TYPE &type);
|
||||
|
||||
static int bytesPerLine(const QVideoSurfaceFormat &format);
|
||||
};
|
||||
|
||||
#endif
|
||||
226
src/plugins/directshow/player/directshowmediatypelist.cpp
Normal file
226
src/plugins/directshow/player/directshowmediatypelist.cpp
Normal file
@@ -0,0 +1,226 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "directshowmediatypelist.h"
|
||||
|
||||
#include "directshowmediatype.h"
|
||||
#include "videosurfacefilter.h"
|
||||
|
||||
|
||||
class DirectShowMediaTypeEnum : public IEnumMediaTypes
|
||||
{
|
||||
public:
|
||||
DirectShowMediaTypeEnum(DirectShowMediaTypeList *list, int token, int index = 0);
|
||||
~DirectShowMediaTypeEnum();
|
||||
|
||||
// IUnknown
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject);
|
||||
ULONG STDMETHODCALLTYPE AddRef();
|
||||
ULONG STDMETHODCALLTYPE Release();
|
||||
|
||||
// IEnumMediaTypes
|
||||
HRESULT STDMETHODCALLTYPE Next(
|
||||
ULONG cMediaTypes, AM_MEDIA_TYPE **ppMediaTypes, ULONG *pcFetched);
|
||||
HRESULT STDMETHODCALLTYPE Skip(ULONG cMediaTypes);
|
||||
HRESULT STDMETHODCALLTYPE Reset();
|
||||
|
||||
HRESULT STDMETHODCALLTYPE Clone(IEnumMediaTypes **ppEnum);
|
||||
|
||||
private:
|
||||
LONG m_ref;
|
||||
DirectShowMediaTypeList *m_list;
|
||||
int m_mediaTypeToken;
|
||||
int m_index;
|
||||
};
|
||||
|
||||
|
||||
DirectShowMediaTypeEnum::DirectShowMediaTypeEnum(
|
||||
DirectShowMediaTypeList *list, int token, int index)
|
||||
: m_ref(1)
|
||||
, m_list(list)
|
||||
, m_mediaTypeToken(token)
|
||||
, m_index(index)
|
||||
{
|
||||
m_list->AddRef();
|
||||
}
|
||||
|
||||
DirectShowMediaTypeEnum::~DirectShowMediaTypeEnum()
|
||||
{
|
||||
m_list->Release();
|
||||
}
|
||||
|
||||
HRESULT DirectShowMediaTypeEnum::QueryInterface(REFIID riid, void **ppvObject)
|
||||
{
|
||||
if (!ppvObject) {
|
||||
return E_POINTER;
|
||||
} else if (riid == IID_IUnknown
|
||||
|| riid == IID_IEnumMediaTypes) {
|
||||
*ppvObject = static_cast<IEnumMediaTypes *>(this);
|
||||
} else {
|
||||
*ppvObject = 0;
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
AddRef();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
ULONG DirectShowMediaTypeEnum::AddRef()
|
||||
{
|
||||
return InterlockedIncrement(&m_ref);
|
||||
}
|
||||
|
||||
ULONG DirectShowMediaTypeEnum::Release()
|
||||
{
|
||||
ULONG ref = InterlockedDecrement(&m_ref);
|
||||
|
||||
if (ref == 0) {
|
||||
delete this;
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
HRESULT DirectShowMediaTypeEnum::Next(
|
||||
ULONG cMediaTypes, AM_MEDIA_TYPE **ppMediaTypes, ULONG *pcFetched)
|
||||
{
|
||||
return m_list->nextMediaType(m_mediaTypeToken, &m_index, cMediaTypes, ppMediaTypes, pcFetched);
|
||||
}
|
||||
|
||||
HRESULT DirectShowMediaTypeEnum::Skip(ULONG cMediaTypes)
|
||||
{
|
||||
return m_list->skipMediaType(m_mediaTypeToken, &m_index, cMediaTypes);
|
||||
}
|
||||
|
||||
HRESULT DirectShowMediaTypeEnum::Reset()
|
||||
{
|
||||
m_mediaTypeToken = m_list->currentMediaTypeToken();
|
||||
m_index = 0;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT DirectShowMediaTypeEnum::Clone(IEnumMediaTypes **ppEnum)
|
||||
{
|
||||
return m_list->cloneMediaType(m_mediaTypeToken, m_index, ppEnum);
|
||||
}
|
||||
|
||||
|
||||
DirectShowMediaTypeList::DirectShowMediaTypeList()
|
||||
: m_mediaTypeToken(0)
|
||||
{
|
||||
}
|
||||
|
||||
IEnumMediaTypes *DirectShowMediaTypeList::createMediaTypeEnum()
|
||||
{
|
||||
return new DirectShowMediaTypeEnum(this, m_mediaTypeToken, 0);
|
||||
}
|
||||
|
||||
|
||||
void DirectShowMediaTypeList::setMediaTypes(const QVector<AM_MEDIA_TYPE> &types)
|
||||
{
|
||||
++m_mediaTypeToken;
|
||||
|
||||
m_mediaTypes = types;
|
||||
}
|
||||
|
||||
|
||||
int DirectShowMediaTypeList::currentMediaTypeToken()
|
||||
{
|
||||
return m_mediaTypeToken;
|
||||
}
|
||||
|
||||
HRESULT DirectShowMediaTypeList::nextMediaType(
|
||||
int token, int *index, ULONG count, AM_MEDIA_TYPE **types, ULONG *fetchedCount)
|
||||
{
|
||||
if (!types || (count != 1 && !fetchedCount)) {
|
||||
return E_POINTER;
|
||||
} else if (m_mediaTypeToken != token) {
|
||||
return VFW_E_ENUM_OUT_OF_SYNC;
|
||||
} else {
|
||||
int boundedCount = qBound<int>(0, count, m_mediaTypes.count() - *index);
|
||||
|
||||
for (int i = 0; i < boundedCount; ++i, ++(*index)) {
|
||||
types[i] = reinterpret_cast<AM_MEDIA_TYPE *>(CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE)));
|
||||
|
||||
if (types[i]) {
|
||||
DirectShowMediaType::copy(types[i], m_mediaTypes.at(*index));
|
||||
} else {
|
||||
for (--i; i >= 0; --i)
|
||||
CoTaskMemFree(types[i]);
|
||||
|
||||
if (fetchedCount)
|
||||
*fetchedCount = 0;
|
||||
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
if (fetchedCount)
|
||||
*fetchedCount = boundedCount;
|
||||
|
||||
return boundedCount == count ? S_OK : S_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT DirectShowMediaTypeList::skipMediaType(int token, int *index, ULONG count)
|
||||
{
|
||||
if (m_mediaTypeToken != token) {
|
||||
return VFW_E_ENUM_OUT_OF_SYNC;
|
||||
} else {
|
||||
*index = qMin<int>(*index + count, m_mediaTypes.size());
|
||||
|
||||
return *index < m_mediaTypes.size() ? S_OK : S_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT DirectShowMediaTypeList::cloneMediaType(int token, int index, IEnumMediaTypes **enumeration)
|
||||
{
|
||||
if (m_mediaTypeToken != token) {
|
||||
return VFW_E_ENUM_OUT_OF_SYNC;
|
||||
} else {
|
||||
*enumeration = new DirectShowMediaTypeEnum(this, token, index);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
69
src/plugins/directshow/player/directshowmediatypelist.h
Normal file
69
src/plugins/directshow/player/directshowmediatypelist.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 DIRECTSHOWMEDIATYPELIST_H
|
||||
#define DIRECTSHOWMEDIATYPELIST_H
|
||||
|
||||
#include <QtCore/qvector.h>
|
||||
|
||||
#include <dshow.h>
|
||||
|
||||
class DirectShowMediaTypeList : public IUnknown
|
||||
{
|
||||
public:
|
||||
DirectShowMediaTypeList();
|
||||
|
||||
IEnumMediaTypes *createMediaTypeEnum();
|
||||
|
||||
void setMediaTypes(const QVector<AM_MEDIA_TYPE> &types);
|
||||
|
||||
virtual int currentMediaTypeToken();
|
||||
virtual HRESULT nextMediaType(
|
||||
int token, int *index, ULONG count, AM_MEDIA_TYPE **types, ULONG *fetchedCount);
|
||||
virtual HRESULT skipMediaType(int token, int *index, ULONG count);
|
||||
virtual HRESULT cloneMediaType(int token, int index, IEnumMediaTypes **enumeration);
|
||||
|
||||
private:
|
||||
int m_mediaTypeToken;
|
||||
QVector<AM_MEDIA_TYPE> m_mediaTypes;
|
||||
};
|
||||
|
||||
#endif
|
||||
352
src/plugins/directshow/player/directshowmetadatacontrol.cpp
Normal file
352
src/plugins/directshow/player/directshowmetadatacontrol.cpp
Normal file
@@ -0,0 +1,352 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 <dshow.h>
|
||||
#include <initguid.h>
|
||||
#include <qnetwork.h>
|
||||
|
||||
#include "directshowmetadatacontrol.h"
|
||||
|
||||
#include "directshowplayerservice.h"
|
||||
|
||||
#include <QtCore/qcoreapplication.h>
|
||||
|
||||
#ifndef QT_NO_WMSDK
|
||||
namespace
|
||||
{
|
||||
struct QWMMetaDataKeyLookup
|
||||
{
|
||||
QtMultimediaKit::MetaData key;
|
||||
const wchar_t *token;
|
||||
};
|
||||
}
|
||||
|
||||
static const QWMMetaDataKeyLookup qt_wmMetaDataKeys[] =
|
||||
{
|
||||
{ QtMultimediaKit::Title, L"Title" },
|
||||
{ QtMultimediaKit::SubTitle, L"WM/SubTitle" },
|
||||
{ QtMultimediaKit::Author, L"Author" },
|
||||
{ QtMultimediaKit::Comment, L"Comment" },
|
||||
{ QtMultimediaKit::Description, L"Description" },
|
||||
{ QtMultimediaKit::Category, L"WM/Category" },
|
||||
{ QtMultimediaKit::Genre, L"WM/Genre" },
|
||||
//{ QtMultimediaKit::Date, 0 },
|
||||
{ QtMultimediaKit::Year, L"WM/Year" },
|
||||
{ QtMultimediaKit::UserRating, L"UserRating" },
|
||||
//{ QtMultimediaKit::MetaDatawords, 0 },
|
||||
{ QtMultimediaKit::Language, L"Language" },
|
||||
{ QtMultimediaKit::Publisher, L"WM/Publisher" },
|
||||
{ QtMultimediaKit::Copyright, L"Copyright" },
|
||||
{ QtMultimediaKit::ParentalRating, L"ParentalRating" },
|
||||
{ QtMultimediaKit::RatingOrganisation, L"RatingOrganisation" },
|
||||
|
||||
// Media
|
||||
{ QtMultimediaKit::Size, L"FileSize" },
|
||||
{ QtMultimediaKit::MediaType, L"MediaType" },
|
||||
{ QtMultimediaKit::Duration, L"Duration" },
|
||||
|
||||
// Audio
|
||||
{ QtMultimediaKit::AudioBitRate, L"AudioBitRate" },
|
||||
{ QtMultimediaKit::AudioCodec, L"AudioCodec" },
|
||||
{ QtMultimediaKit::ChannelCount, L"ChannelCount" },
|
||||
{ QtMultimediaKit::SampleRate, L"Frequency" },
|
||||
|
||||
// Music
|
||||
{ QtMultimediaKit::AlbumTitle, L"WM/AlbumTitle" },
|
||||
{ QtMultimediaKit::AlbumArtist, L"WM/AlbumArtist" },
|
||||
{ QtMultimediaKit::ContributingArtist, L"Author" },
|
||||
{ QtMultimediaKit::Composer, L"WM/Composer" },
|
||||
{ QtMultimediaKit::Conductor, L"WM/Conductor" },
|
||||
{ QtMultimediaKit::Lyrics, L"WM/Lyrics" },
|
||||
{ QtMultimediaKit::Mood, L"WM/Mood" },
|
||||
{ QtMultimediaKit::TrackNumber, L"WM/TrackNumber" },
|
||||
//{ QtMultimediaKit::TrackCount, 0 },
|
||||
//{ QtMultimediaKit::CoverArtUriSmall, 0 },
|
||||
//{ QtMultimediaKit::CoverArtUriLarge, 0 },
|
||||
|
||||
// Image/Video
|
||||
//{ QtMultimediaKit::Resolution, 0 },
|
||||
//{ QtMultimediaKit::PixelAspectRatio, 0 },
|
||||
|
||||
// Video
|
||||
//{ QtMultimediaKit::FrameRate, 0 },
|
||||
{ QtMultimediaKit::VideoBitRate, L"VideoBitRate" },
|
||||
{ QtMultimediaKit::VideoCodec, L"VideoCodec" },
|
||||
|
||||
//{ QtMultimediaKit::PosterUri, 0 },
|
||||
|
||||
// Movie
|
||||
{ QtMultimediaKit::ChapterNumber, L"ChapterNumber" },
|
||||
{ QtMultimediaKit::Director, L"WM/Director" },
|
||||
{ QtMultimediaKit::LeadPerformer, L"LeadPerformer" },
|
||||
{ QtMultimediaKit::Writer, L"WM/Writer" },
|
||||
|
||||
// Photos
|
||||
{ QtMultimediaKit::CameraManufacturer, L"CameraManufacturer" },
|
||||
{ QtMultimediaKit::CameraModel, L"CameraModel" },
|
||||
{ QtMultimediaKit::Event, L"Event" },
|
||||
{ QtMultimediaKit::Subject, L"Subject" }
|
||||
};
|
||||
|
||||
static QVariant getValue(IWMHeaderInfo *header, const wchar_t *key)
|
||||
{
|
||||
WORD streamNumber = 0;
|
||||
WMT_ATTR_DATATYPE type = WMT_TYPE_DWORD;
|
||||
WORD size = 0;
|
||||
|
||||
if (header->GetAttributeByName(&streamNumber, key, &type, 0, &size) == S_OK) {
|
||||
switch (type) {
|
||||
case WMT_TYPE_DWORD:
|
||||
if (size == sizeof(DWORD)) {
|
||||
DWORD word;
|
||||
if (header->GetAttributeByName(
|
||||
&streamNumber,
|
||||
key,
|
||||
&type,
|
||||
reinterpret_cast<BYTE *>(&word),
|
||||
&size) == S_OK) {
|
||||
return int(word);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WMT_TYPE_STRING:
|
||||
{
|
||||
QString string;
|
||||
string.resize(size / 2 - 1);
|
||||
|
||||
if (header->GetAttributeByName(
|
||||
&streamNumber,
|
||||
key,
|
||||
&type,
|
||||
reinterpret_cast<BYTE *>(const_cast<ushort *>(string.utf16())),
|
||||
&size) == S_OK) {
|
||||
return string;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WMT_TYPE_BINARY:
|
||||
{
|
||||
QByteArray bytes;
|
||||
bytes.resize(size);
|
||||
if (header->GetAttributeByName(
|
||||
&streamNumber,
|
||||
key,
|
||||
&type,
|
||||
reinterpret_cast<BYTE *>(bytes.data()),
|
||||
&size) == S_OK) {
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WMT_TYPE_BOOL:
|
||||
if (size == sizeof(DWORD)) {
|
||||
DWORD word;
|
||||
if (header->GetAttributeByName(
|
||||
&streamNumber,
|
||||
key,
|
||||
&type,
|
||||
reinterpret_cast<BYTE *>(&word),
|
||||
&size) == S_OK) {
|
||||
return bool(word);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WMT_TYPE_QWORD:
|
||||
if (size == sizeof(QWORD)) {
|
||||
QWORD word;
|
||||
if (header->GetAttributeByName(
|
||||
&streamNumber,
|
||||
key,
|
||||
&type,
|
||||
reinterpret_cast<BYTE *>(&word),
|
||||
&size) == S_OK) {
|
||||
return qint64(word);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WMT_TYPE_WORD:
|
||||
if (size == sizeof(WORD)){
|
||||
WORD word;
|
||||
if (header->GetAttributeByName(
|
||||
&streamNumber,
|
||||
key,
|
||||
&type,
|
||||
reinterpret_cast<BYTE *>(&word),
|
||||
&size) == S_OK) {
|
||||
return short(word);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WMT_TYPE_GUID:
|
||||
if (size == 16) {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
#endif
|
||||
|
||||
DirectShowMetaDataControl::DirectShowMetaDataControl(QObject *parent)
|
||||
: QMetaDataReaderControl(parent)
|
||||
, m_content(0)
|
||||
#ifndef QT_NO_WMSDK
|
||||
, m_headerInfo(0)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
DirectShowMetaDataControl::~DirectShowMetaDataControl()
|
||||
{
|
||||
}
|
||||
|
||||
bool DirectShowMetaDataControl::isMetaDataAvailable() const
|
||||
{
|
||||
#ifndef QT_NO_WMSDK
|
||||
return m_content || m_headerInfo;
|
||||
#else
|
||||
return m_content;
|
||||
#endif
|
||||
}
|
||||
|
||||
QVariant DirectShowMetaDataControl::metaData(QtMultimediaKit::MetaData key) const
|
||||
{
|
||||
QVariant value;
|
||||
|
||||
#ifndef QT_NO_WMSDK
|
||||
if (m_headerInfo) {
|
||||
static const int count = sizeof(qt_wmMetaDataKeys) / sizeof(QWMMetaDataKeyLookup);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
if (qt_wmMetaDataKeys[i].key == key) {
|
||||
value = getValue(m_headerInfo, qt_wmMetaDataKeys[i].token);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (m_content) {
|
||||
#else
|
||||
if (m_content) {
|
||||
#endif
|
||||
BSTR string = 0;
|
||||
|
||||
switch (key) {
|
||||
case QtMultimediaKit::Author:
|
||||
m_content->get_AuthorName(&string);
|
||||
break;
|
||||
case QtMultimediaKit::Title:
|
||||
m_content->get_Title(&string);
|
||||
break;
|
||||
case QtMultimediaKit::ParentalRating:
|
||||
m_content->get_Rating(&string);
|
||||
break;
|
||||
case QtMultimediaKit::Description:
|
||||
m_content->get_Description(&string);
|
||||
break;
|
||||
case QtMultimediaKit::Copyright:
|
||||
m_content->get_Copyright(&string);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (string) {
|
||||
value = QString::fromUtf16(reinterpret_cast<ushort *>(string), ::SysStringLen(string));
|
||||
|
||||
::SysFreeString(string);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
QList<QtMultimediaKit::MetaData> DirectShowMetaDataControl::availableMetaData() const
|
||||
{
|
||||
return QList<QtMultimediaKit::MetaData>();
|
||||
}
|
||||
|
||||
QVariant DirectShowMetaDataControl::extendedMetaData(const QString &) const
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QStringList DirectShowMetaDataControl::availableExtendedMetaData() const
|
||||
{
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
void DirectShowMetaDataControl::updateGraph(IFilterGraph2 *graph, IBaseFilter *source)
|
||||
{
|
||||
if (m_content)
|
||||
m_content->Release();
|
||||
|
||||
if (!graph || graph->QueryInterface(
|
||||
IID_IAMMediaContent, reinterpret_cast<void **>(&m_content)) != S_OK) {
|
||||
m_content = 0;
|
||||
}
|
||||
|
||||
#ifdef QT_NO_WMSDK
|
||||
Q_UNUSED(source);
|
||||
#else
|
||||
if (m_headerInfo)
|
||||
m_headerInfo->Release();
|
||||
|
||||
m_headerInfo = com_cast<IWMHeaderInfo>(source, IID_IWMHeaderInfo);
|
||||
#endif
|
||||
// DirectShowMediaPlayerService holds a lock at this point so defer emitting signals to a later
|
||||
// time.
|
||||
QCoreApplication::postEvent(this, new QEvent(QEvent::Type(MetaDataChanged)));
|
||||
}
|
||||
|
||||
void DirectShowMetaDataControl::customEvent(QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::Type(MetaDataChanged)) {
|
||||
event->accept();
|
||||
|
||||
emit metaDataChanged();
|
||||
#ifndef QT_NO_WMSDK
|
||||
emit metaDataAvailableChanged(m_content || m_headerInfo);
|
||||
#else
|
||||
emit metaDataAvailableChanged(m_content);
|
||||
#endif
|
||||
} else {
|
||||
QMetaDataReaderControl::customEvent(event);
|
||||
}
|
||||
}
|
||||
93
src/plugins/directshow/player/directshowmetadatacontrol.h
Normal file
93
src/plugins/directshow/player/directshowmetadatacontrol.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 DIRECTSHOWMETADATACONTROL_H
|
||||
#define DIRECTSHOWMETADATACONTROL_H
|
||||
|
||||
#include <qmetadatareadercontrol.h>
|
||||
|
||||
#include "directshowglobal.h"
|
||||
|
||||
#include <qnetwork.h>
|
||||
|
||||
#ifndef QT_NO_WMSDK
|
||||
#include <wmsdk.h>
|
||||
#endif
|
||||
|
||||
#include <QtCore/qcoreevent.h>
|
||||
|
||||
class DirectShowPlayerService;
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class DirectShowMetaDataControl : public QMetaDataReaderControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DirectShowMetaDataControl(QObject *parent = 0);
|
||||
~DirectShowMetaDataControl();
|
||||
|
||||
bool isMetaDataAvailable() const;
|
||||
|
||||
QVariant metaData(QtMultimediaKit::MetaData key) const;
|
||||
QList<QtMultimediaKit::MetaData> availableMetaData() const;
|
||||
|
||||
QVariant extendedMetaData(const QString &key) const;
|
||||
QStringList availableExtendedMetaData() const;
|
||||
|
||||
void updateGraph(IFilterGraph2 *graph, IBaseFilter *source);
|
||||
|
||||
protected:
|
||||
void customEvent(QEvent *event);
|
||||
|
||||
private:
|
||||
enum Event
|
||||
{
|
||||
MetaDataChanged = QEvent::User
|
||||
};
|
||||
|
||||
IAMMediaContent *m_content;
|
||||
#ifndef QT_NO_WMSDK
|
||||
IWMHeaderInfo *m_headerInfo;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
134
src/plugins/directshow/player/directshowpinenum.cpp
Normal file
134
src/plugins/directshow/player/directshowpinenum.cpp
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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "directshowpinenum.h"
|
||||
|
||||
|
||||
DirectShowPinEnum::DirectShowPinEnum(const QList<IPin *> &pins)
|
||||
: m_ref(1)
|
||||
, m_pins(pins)
|
||||
, m_index(0)
|
||||
{
|
||||
foreach (IPin *pin, m_pins)
|
||||
pin->AddRef();
|
||||
}
|
||||
|
||||
DirectShowPinEnum::~DirectShowPinEnum()
|
||||
{
|
||||
foreach (IPin *pin, m_pins)
|
||||
pin->Release();
|
||||
}
|
||||
|
||||
HRESULT DirectShowPinEnum::QueryInterface(REFIID riid, void **ppvObject)
|
||||
{
|
||||
if (riid == IID_IUnknown
|
||||
|| riid == IID_IEnumPins) {
|
||||
AddRef();
|
||||
|
||||
*ppvObject = static_cast<IEnumPins *>(this);
|
||||
|
||||
return S_OK;
|
||||
} else {
|
||||
*ppvObject = 0;
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
}
|
||||
|
||||
ULONG DirectShowPinEnum::AddRef()
|
||||
{
|
||||
return InterlockedIncrement(&m_ref);
|
||||
}
|
||||
|
||||
ULONG DirectShowPinEnum::Release()
|
||||
{
|
||||
ULONG ref = InterlockedDecrement(&m_ref);
|
||||
|
||||
if (ref == 0) {
|
||||
delete this;
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
HRESULT DirectShowPinEnum::Next(ULONG cPins, IPin **ppPins, ULONG *pcFetched)
|
||||
{
|
||||
if (ppPins && (pcFetched || cPins == 1)) {
|
||||
ULONG count = qBound<ULONG>(0, cPins, m_pins.count() - m_index);
|
||||
|
||||
for (ULONG i = 0; i < count; ++i, ++m_index) {
|
||||
ppPins[i] = m_pins.at(m_index);
|
||||
ppPins[i]->AddRef();
|
||||
}
|
||||
|
||||
if (pcFetched)
|
||||
*pcFetched = count;
|
||||
|
||||
return count == cPins ? S_OK : S_FALSE;
|
||||
} else {
|
||||
return E_POINTER;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT DirectShowPinEnum::Skip(ULONG cPins)
|
||||
{
|
||||
m_index = qMin(int(m_index + cPins), m_pins.count());
|
||||
|
||||
return m_index < m_pins.count() ? S_OK : S_FALSE;
|
||||
}
|
||||
|
||||
HRESULT DirectShowPinEnum::Reset()
|
||||
{
|
||||
m_index = 0;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT DirectShowPinEnum::Clone(IEnumPins **ppEnum)
|
||||
{
|
||||
if (ppEnum) {
|
||||
*ppEnum = new DirectShowPinEnum(m_pins);
|
||||
|
||||
return S_OK;
|
||||
} else {
|
||||
return E_POINTER;
|
||||
}
|
||||
}
|
||||
72
src/plugins/directshow/player/directshowpinenum.h
Normal file
72
src/plugins/directshow/player/directshowpinenum.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 DIRECTSHOWPINENUM_H
|
||||
#define DIRECTSHOWPINENUM_H
|
||||
|
||||
#include <QtCore/qlist.h>
|
||||
|
||||
#include <dshow.h>
|
||||
|
||||
class DirectShowPinEnum : public IEnumPins
|
||||
{
|
||||
public:
|
||||
DirectShowPinEnum(const QList<IPin *> &pins);
|
||||
~DirectShowPinEnum();
|
||||
|
||||
// IUnknown
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject);
|
||||
ULONG STDMETHODCALLTYPE AddRef();
|
||||
ULONG STDMETHODCALLTYPE Release();
|
||||
|
||||
// IEnumPins
|
||||
HRESULT STDMETHODCALLTYPE Next(ULONG cPins, IPin **ppPins, ULONG *pcFetched);
|
||||
HRESULT STDMETHODCALLTYPE Skip(ULONG cPins);
|
||||
HRESULT STDMETHODCALLTYPE Reset();
|
||||
HRESULT STDMETHODCALLTYPE Clone(IEnumPins **ppEnum);
|
||||
|
||||
private:
|
||||
LONG m_ref;
|
||||
QList<IPin *> m_pins;
|
||||
int m_index;
|
||||
};
|
||||
|
||||
#endif
|
||||
405
src/plugins/directshow/player/directshowplayercontrol.cpp
Normal file
405
src/plugins/directshow/player/directshowplayercontrol.cpp
Normal file
@@ -0,0 +1,405 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "directshowplayercontrol.h"
|
||||
|
||||
#include "directshowplayerservice.h"
|
||||
|
||||
#include <QtCore/qcoreapplication.h>
|
||||
#include <QtCore/qmath.h>
|
||||
|
||||
static int volumeToDecibels(int volume)
|
||||
{
|
||||
if (volume == 0) {
|
||||
return -10000;
|
||||
} else if (volume == 100) {
|
||||
return 0;
|
||||
#ifdef QT_USE_MATH_H_FLOATS
|
||||
} else if (sizeof(qreal) == sizeof(float)) {
|
||||
return qRound(::log10f(float(volume) / 100) * 5000);
|
||||
#endif
|
||||
} else {
|
||||
return qRound(::log10(qreal(volume) / 100) * 5000);
|
||||
}
|
||||
}
|
||||
|
||||
static int decibelsToVolume(int dB)
|
||||
{
|
||||
if (dB == -10000) {
|
||||
return 0;
|
||||
} else if (dB == 0) {
|
||||
return 100;
|
||||
} else {
|
||||
return qRound(100 * qPow(10, qreal(dB) / 5000));
|
||||
}
|
||||
}
|
||||
|
||||
DirectShowPlayerControl::DirectShowPlayerControl(DirectShowPlayerService *service, QObject *parent)
|
||||
: QMediaPlayerControl(parent)
|
||||
, m_service(service)
|
||||
, m_audio(0)
|
||||
, m_updateProperties(0)
|
||||
, m_state(QMediaPlayer::StoppedState)
|
||||
, m_status(QMediaPlayer::NoMedia)
|
||||
, m_error(QMediaPlayer::NoError)
|
||||
, m_streamTypes(0)
|
||||
, m_muteVolume(-1)
|
||||
, m_position(0)
|
||||
, m_duration(0)
|
||||
, m_playbackRate(0)
|
||||
, m_seekable(false)
|
||||
{
|
||||
}
|
||||
|
||||
DirectShowPlayerControl::~DirectShowPlayerControl()
|
||||
{
|
||||
if (m_audio)
|
||||
m_audio->Release();
|
||||
}
|
||||
|
||||
QMediaPlayer::State DirectShowPlayerControl::state() const
|
||||
{
|
||||
return m_state;
|
||||
}
|
||||
|
||||
QMediaPlayer::MediaStatus DirectShowPlayerControl::mediaStatus() const
|
||||
{
|
||||
return m_status;
|
||||
}
|
||||
|
||||
qint64 DirectShowPlayerControl::duration() const
|
||||
{
|
||||
return m_duration;
|
||||
}
|
||||
|
||||
qint64 DirectShowPlayerControl::position() const
|
||||
{
|
||||
return const_cast<qint64 &>(m_position) = m_service->position();
|
||||
}
|
||||
|
||||
void DirectShowPlayerControl::setPosition(qint64 position)
|
||||
{
|
||||
m_service->seek(position);
|
||||
}
|
||||
|
||||
int DirectShowPlayerControl::volume() const
|
||||
{
|
||||
if (m_muteVolume >= 0) {
|
||||
return m_muteVolume;
|
||||
} else if (m_audio) {
|
||||
long dB = 0;
|
||||
|
||||
m_audio->get_Volume(&dB);
|
||||
|
||||
return decibelsToVolume(dB);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void DirectShowPlayerControl::setVolume(int volume)
|
||||
{
|
||||
int boundedVolume = qBound(0, volume, 100);
|
||||
|
||||
if (m_muteVolume >= 0) {
|
||||
m_muteVolume = boundedVolume;
|
||||
|
||||
emit volumeChanged(m_muteVolume);
|
||||
} else if (m_audio) {
|
||||
m_audio->put_Volume(volumeToDecibels(volume));
|
||||
|
||||
emit volumeChanged(boundedVolume);
|
||||
}
|
||||
}
|
||||
|
||||
bool DirectShowPlayerControl::isMuted() const
|
||||
{
|
||||
return m_muteVolume >= 0;
|
||||
}
|
||||
|
||||
void DirectShowPlayerControl::setMuted(bool muted)
|
||||
{
|
||||
if (muted && m_muteVolume < 0) {
|
||||
if (m_audio) {
|
||||
long dB = 0;
|
||||
|
||||
m_audio->get_Volume(&dB);
|
||||
|
||||
m_muteVolume = decibelsToVolume(dB);
|
||||
|
||||
m_audio->put_Volume(-10000);
|
||||
} else {
|
||||
m_muteVolume = 0;
|
||||
}
|
||||
|
||||
emit mutedChanged(muted);
|
||||
} else if (!muted && m_muteVolume >= 0) {
|
||||
if (m_audio) {
|
||||
m_audio->put_Volume(volumeToDecibels(m_muteVolume));
|
||||
}
|
||||
m_muteVolume = -1;
|
||||
|
||||
emit mutedChanged(muted);
|
||||
}
|
||||
}
|
||||
|
||||
int DirectShowPlayerControl::bufferStatus() const
|
||||
{
|
||||
return m_service->bufferStatus();
|
||||
}
|
||||
|
||||
bool DirectShowPlayerControl::isAudioAvailable() const
|
||||
{
|
||||
return m_streamTypes & DirectShowPlayerService::AudioStream;
|
||||
}
|
||||
|
||||
bool DirectShowPlayerControl::isVideoAvailable() const
|
||||
{
|
||||
return m_streamTypes & DirectShowPlayerService::VideoStream;
|
||||
}
|
||||
|
||||
bool DirectShowPlayerControl::isSeekable() const
|
||||
{
|
||||
return m_seekable;
|
||||
}
|
||||
|
||||
QMediaTimeRange DirectShowPlayerControl::availablePlaybackRanges() const
|
||||
{
|
||||
return m_service->availablePlaybackRanges();
|
||||
}
|
||||
|
||||
qreal DirectShowPlayerControl::playbackRate() const
|
||||
{
|
||||
return m_playbackRate;
|
||||
}
|
||||
|
||||
void DirectShowPlayerControl::setPlaybackRate(qreal rate)
|
||||
{
|
||||
if (m_playbackRate != rate) {
|
||||
m_service->setRate(rate);
|
||||
|
||||
emit playbackRateChanged(m_playbackRate = rate);
|
||||
}
|
||||
}
|
||||
|
||||
QMediaContent DirectShowPlayerControl::media() const
|
||||
{
|
||||
return m_media;
|
||||
}
|
||||
|
||||
const QIODevice *DirectShowPlayerControl::mediaStream() const
|
||||
{
|
||||
return m_stream;
|
||||
}
|
||||
|
||||
void DirectShowPlayerControl::setMedia(const QMediaContent &media, QIODevice *stream)
|
||||
{
|
||||
m_media = media;
|
||||
m_stream = stream;
|
||||
|
||||
m_updateProperties &= PlaybackRateProperty;
|
||||
|
||||
m_service->load(media, stream);
|
||||
|
||||
emit mediaChanged(m_media);
|
||||
emitPropertyChanges();
|
||||
}
|
||||
|
||||
void DirectShowPlayerControl::play()
|
||||
{
|
||||
if (m_status == QMediaPlayer::NoMedia)
|
||||
return;
|
||||
if (m_status == QMediaPlayer::InvalidMedia) {
|
||||
setMedia(m_media, m_stream);
|
||||
if (m_error != QMediaPlayer::NoError)
|
||||
return;
|
||||
}
|
||||
m_service->play();
|
||||
emit stateChanged(m_state = QMediaPlayer::PlayingState);
|
||||
}
|
||||
|
||||
void DirectShowPlayerControl::pause()
|
||||
{
|
||||
if (m_status == QMediaPlayer::NoMedia)
|
||||
return;
|
||||
if (m_status == QMediaPlayer::InvalidMedia) {
|
||||
setMedia(m_media, m_stream);
|
||||
if (m_error != QMediaPlayer::NoError)
|
||||
return;
|
||||
}
|
||||
m_service->pause();
|
||||
emit stateChanged(m_state = QMediaPlayer::PausedState);
|
||||
}
|
||||
|
||||
void DirectShowPlayerControl::stop()
|
||||
{
|
||||
m_service->stop();
|
||||
emit stateChanged(m_state = QMediaPlayer::StoppedState);
|
||||
}
|
||||
|
||||
void DirectShowPlayerControl::customEvent(QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::Type(PropertiesChanged)) {
|
||||
emitPropertyChanges();
|
||||
|
||||
event->accept();
|
||||
} else {
|
||||
QMediaPlayerControl::customEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
void DirectShowPlayerControl::emitPropertyChanges()
|
||||
{
|
||||
int properties = m_updateProperties;
|
||||
m_updateProperties = 0;
|
||||
|
||||
if ((properties & ErrorProperty) && m_error != QMediaPlayer::NoError)
|
||||
emit error(m_error, m_errorString);
|
||||
|
||||
if (properties & PlaybackRateProperty)
|
||||
emit playbackRateChanged(m_playbackRate);
|
||||
|
||||
if (properties & StreamTypesProperty) {
|
||||
emit audioAvailableChanged(m_streamTypes & DirectShowPlayerService::AudioStream);
|
||||
emit videoAvailableChanged(m_streamTypes & DirectShowPlayerService::VideoStream);
|
||||
}
|
||||
|
||||
if (properties & PositionProperty)
|
||||
emit positionChanged(m_position);
|
||||
|
||||
if (properties & DurationProperty)
|
||||
emit durationChanged(m_duration);
|
||||
|
||||
if (properties & SeekableProperty)
|
||||
emit seekableChanged(m_seekable);
|
||||
|
||||
if (properties & StatusProperty)
|
||||
emit mediaStatusChanged(m_status);
|
||||
|
||||
if (properties & StateProperty)
|
||||
emit stateChanged(m_state);
|
||||
}
|
||||
|
||||
void DirectShowPlayerControl::scheduleUpdate(int properties)
|
||||
{
|
||||
if (m_updateProperties == 0)
|
||||
QCoreApplication::postEvent(this, new QEvent(QEvent::Type(PropertiesChanged)));
|
||||
|
||||
m_updateProperties |= properties;
|
||||
}
|
||||
|
||||
void DirectShowPlayerControl::updateState(QMediaPlayer::State state)
|
||||
{
|
||||
if (m_state != state) {
|
||||
m_state = state;
|
||||
|
||||
scheduleUpdate(StateProperty);
|
||||
}
|
||||
}
|
||||
|
||||
void DirectShowPlayerControl::updateStatus(QMediaPlayer::MediaStatus status)
|
||||
{
|
||||
if (m_status != status) {
|
||||
m_status = status;
|
||||
|
||||
scheduleUpdate(StatusProperty);
|
||||
}
|
||||
}
|
||||
|
||||
void DirectShowPlayerControl::updateMediaInfo(qint64 duration, int streamTypes, bool seekable)
|
||||
{
|
||||
int properties = 0;
|
||||
|
||||
if (m_duration != duration) {
|
||||
m_duration = duration;
|
||||
|
||||
properties |= DurationProperty;
|
||||
}
|
||||
if (m_streamTypes != streamTypes) {
|
||||
m_streamTypes = streamTypes;
|
||||
|
||||
properties |= StreamTypesProperty;
|
||||
}
|
||||
|
||||
if (m_seekable != seekable) {
|
||||
m_seekable = seekable;
|
||||
|
||||
properties |= SeekableProperty;
|
||||
}
|
||||
|
||||
if (properties != 0)
|
||||
scheduleUpdate(properties);
|
||||
}
|
||||
|
||||
void DirectShowPlayerControl::updatePlaybackRate(qreal rate)
|
||||
{
|
||||
if (m_playbackRate != rate) {
|
||||
m_playbackRate = rate;
|
||||
|
||||
scheduleUpdate(PlaybackRateProperty);
|
||||
}
|
||||
}
|
||||
|
||||
void DirectShowPlayerControl::updateAudioOutput(IBaseFilter *filter)
|
||||
{
|
||||
if (m_audio)
|
||||
m_audio->Release();
|
||||
|
||||
m_audio = com_cast<IBasicAudio>(filter, IID_IBasicAudio);
|
||||
}
|
||||
|
||||
void DirectShowPlayerControl::updateError(QMediaPlayer::Error error, const QString &errorString)
|
||||
{
|
||||
m_error = error;
|
||||
m_errorString = errorString;
|
||||
|
||||
if (m_error != QMediaPlayer::NoError)
|
||||
scheduleUpdate(ErrorProperty);
|
||||
}
|
||||
|
||||
void DirectShowPlayerControl::updatePosition(qint64 position)
|
||||
{
|
||||
if (m_position != position) {
|
||||
m_position = position;
|
||||
|
||||
scheduleUpdate(PositionProperty);
|
||||
}
|
||||
}
|
||||
146
src/plugins/directshow/player/directshowplayercontrol.h
Normal file
146
src/plugins/directshow/player/directshowplayercontrol.h
Normal file
@@ -0,0 +1,146 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 DIRECTSHOWPLAYERCONTROL_H
|
||||
#define DIRECTSHOWPLAYERCONTROL_H
|
||||
|
||||
#include "qmediacontent.h"
|
||||
#include "qmediaplayercontrol.h"
|
||||
|
||||
#include <QtCore/qcoreevent.h>
|
||||
|
||||
#include "directshowplayerservice.h"
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class DirectShowPlayerControl : public QMediaPlayerControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DirectShowPlayerControl(DirectShowPlayerService *service, QObject *parent = 0);
|
||||
~DirectShowPlayerControl();
|
||||
|
||||
QMediaPlayer::State state() const;
|
||||
|
||||
QMediaPlayer::MediaStatus mediaStatus() const;
|
||||
|
||||
qint64 duration() const;
|
||||
|
||||
qint64 position() const;
|
||||
void setPosition(qint64 position);
|
||||
|
||||
int volume() const;
|
||||
void setVolume(int volume);
|
||||
|
||||
bool isMuted() const;
|
||||
void setMuted(bool muted);
|
||||
|
||||
int bufferStatus() const;
|
||||
|
||||
bool isAudioAvailable() const;
|
||||
bool isVideoAvailable() const;
|
||||
|
||||
bool isSeekable() const;
|
||||
|
||||
QMediaTimeRange availablePlaybackRanges() const;
|
||||
|
||||
qreal playbackRate() const;
|
||||
void setPlaybackRate(qreal rate);
|
||||
|
||||
QMediaContent media() const;
|
||||
const QIODevice *mediaStream() const;
|
||||
void setMedia(const QMediaContent &media, QIODevice *stream);
|
||||
|
||||
void play();
|
||||
void pause();
|
||||
void stop();
|
||||
|
||||
void updateState(QMediaPlayer::State state);
|
||||
void updateStatus(QMediaPlayer::MediaStatus status);
|
||||
void updateMediaInfo(qint64 duration, int streamTypes, bool seekable);
|
||||
void updatePlaybackRate(qreal rate);
|
||||
void updateAudioOutput(IBaseFilter *filter);
|
||||
void updateError(QMediaPlayer::Error error, const QString &errorString);
|
||||
void updatePosition(qint64 position);
|
||||
|
||||
protected:
|
||||
void customEvent(QEvent *event);
|
||||
|
||||
private:
|
||||
enum Properties
|
||||
{
|
||||
StateProperty = 0x01,
|
||||
StatusProperty = 0x02,
|
||||
StreamTypesProperty = 0x04,
|
||||
DurationProperty = 0x08,
|
||||
PlaybackRateProperty = 0x10,
|
||||
SeekableProperty = 0x20,
|
||||
ErrorProperty = 0x40,
|
||||
PositionProperty = 0x80
|
||||
};
|
||||
|
||||
enum Event
|
||||
{
|
||||
PropertiesChanged = QEvent::User
|
||||
};
|
||||
|
||||
void scheduleUpdate(int properties);
|
||||
void emitPropertyChanges();
|
||||
|
||||
DirectShowPlayerService *m_service;
|
||||
IBasicAudio *m_audio;
|
||||
QIODevice *m_stream;
|
||||
int m_updateProperties;
|
||||
QMediaPlayer::State m_state;
|
||||
QMediaPlayer::MediaStatus m_status;
|
||||
QMediaPlayer::Error m_error;
|
||||
int m_streamTypes;
|
||||
int m_muteVolume;
|
||||
qint64 m_position;
|
||||
qint64 m_duration;
|
||||
qreal m_playbackRate;
|
||||
bool m_seekable;
|
||||
QMediaContent m_media;
|
||||
QString m_errorString;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
1408
src/plugins/directshow/player/directshowplayerservice.cpp
Normal file
1408
src/plugins/directshow/player/directshowplayerservice.cpp
Normal file
File diff suppressed because it is too large
Load Diff
219
src/plugins/directshow/player/directshowplayerservice.h
Normal file
219
src/plugins/directshow/player/directshowplayerservice.h
Normal file
@@ -0,0 +1,219 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 DIRECTSHOWPLAYERSERVICE_H
|
||||
#define DIRECTSHOWPLAYERSERVICE_H
|
||||
|
||||
#include "qmediaplayer.h"
|
||||
#include "qmediaresource.h"
|
||||
#include "qmediaservice.h"
|
||||
#include "qmediatimerange.h"
|
||||
|
||||
#include "directshoweventloop.h"
|
||||
#include "directshowglobal.h"
|
||||
|
||||
#include <QtCore/qcoreevent.h>
|
||||
#include <QtCore/qmutex.h>
|
||||
#include <QtCore/qurl.h>
|
||||
#include <QtCore/qwaitcondition.h>
|
||||
|
||||
class DirectShowAudioEndpointControl;
|
||||
class DirectShowMetaDataControl;
|
||||
class DirectShowPlayerControl;
|
||||
class DirectShowVideoRendererControl;
|
||||
#ifndef Q_WS_SIMULATOR
|
||||
class Vmr9VideoWindowControl;
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QMediaContent;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class DirectShowPlayerService : public QMediaService
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum StreamType
|
||||
{
|
||||
AudioStream = 0x01,
|
||||
VideoStream = 0x02
|
||||
};
|
||||
|
||||
DirectShowPlayerService(QObject *parent = 0);
|
||||
~DirectShowPlayerService();
|
||||
|
||||
QMediaControl* requestControl(const char *name);
|
||||
void releaseControl(QMediaControl *control);
|
||||
|
||||
void load(const QMediaContent &media, QIODevice *stream);
|
||||
void play();
|
||||
void pause();
|
||||
void stop();
|
||||
|
||||
qint64 position() const;
|
||||
QMediaTimeRange availablePlaybackRanges() const;
|
||||
|
||||
void seek(qint64 position);
|
||||
void setRate(qreal rate);
|
||||
|
||||
int bufferStatus() const;
|
||||
|
||||
void setAudioOutput(IBaseFilter *filter);
|
||||
void setVideoOutput(IBaseFilter *filter);
|
||||
|
||||
protected:
|
||||
void customEvent(QEvent *event);
|
||||
|
||||
private Q_SLOTS:
|
||||
void videoOutputChanged();
|
||||
|
||||
private:
|
||||
void releaseGraph();
|
||||
void updateStatus();
|
||||
|
||||
int findStreamTypes(IBaseFilter *source) const;
|
||||
int findStreamType(IPin *pin) const;
|
||||
|
||||
bool isConnected(IBaseFilter *filter, PIN_DIRECTION direction) const;
|
||||
IBaseFilter *getConnected(IBaseFilter *filter, PIN_DIRECTION direction) const;
|
||||
|
||||
void run();
|
||||
|
||||
void doSetUrlSource(QMutexLocker *locker);
|
||||
void doSetStreamSource(QMutexLocker *locker);
|
||||
void doRender(QMutexLocker *locker);
|
||||
void doFinalizeLoad(QMutexLocker *locker);
|
||||
void doSetRate(QMutexLocker *locker);
|
||||
void doSeek(QMutexLocker *locker);
|
||||
void doPlay(QMutexLocker *locker);
|
||||
void doPause(QMutexLocker *locker);
|
||||
void doStop(QMutexLocker *locker);
|
||||
void doReleaseAudioOutput(QMutexLocker *locker);
|
||||
void doReleaseVideoOutput(QMutexLocker *locker);
|
||||
void doReleaseGraph(QMutexLocker *locker);
|
||||
|
||||
void graphEvent(QMutexLocker *locker);
|
||||
|
||||
enum Task
|
||||
{
|
||||
Shutdown = 0x0001,
|
||||
SetUrlSource = 0x0002,
|
||||
SetStreamSource = 0x0004,
|
||||
SetSource = SetUrlSource | SetStreamSource,
|
||||
SetAudioOutput = 0x0008,
|
||||
SetVideoOutput = 0x0010,
|
||||
SetOutputs = SetAudioOutput | SetVideoOutput,
|
||||
Render = 0x0020,
|
||||
FinalizeLoad = 0x0040,
|
||||
SetRate = 0x0080,
|
||||
Seek = 0x0100,
|
||||
Play = 0x0200,
|
||||
Pause = 0x0400,
|
||||
Stop = 0x0800,
|
||||
ReleaseGraph = 0x1000,
|
||||
ReleaseAudioOutput = 0x2000,
|
||||
ReleaseVideoOutput = 0x4000,
|
||||
ReleaseFilters = ReleaseGraph | ReleaseAudioOutput | ReleaseVideoOutput
|
||||
};
|
||||
|
||||
enum Event
|
||||
{
|
||||
FinalizedLoad = QEvent::User,
|
||||
Error,
|
||||
RateChange,
|
||||
Started,
|
||||
Paused,
|
||||
DurationChange,
|
||||
StatusChange,
|
||||
EndOfMedia,
|
||||
PositionChange
|
||||
};
|
||||
|
||||
enum GraphStatus
|
||||
{
|
||||
NoMedia,
|
||||
Loading,
|
||||
Loaded,
|
||||
InvalidMedia
|
||||
};
|
||||
|
||||
DirectShowPlayerControl *m_playerControl;
|
||||
DirectShowMetaDataControl *m_metaDataControl;
|
||||
DirectShowVideoRendererControl *m_videoRendererControl;
|
||||
#ifndef Q_WS_SIMULATOR
|
||||
Vmr9VideoWindowControl *m_videoWindowControl;
|
||||
#endif
|
||||
DirectShowAudioEndpointControl *m_audioEndpointControl;
|
||||
|
||||
QThread *m_taskThread;
|
||||
DirectShowEventLoop *m_loop;
|
||||
int m_pendingTasks;
|
||||
int m_executingTask;
|
||||
int m_executedTasks;
|
||||
HANDLE m_taskHandle;
|
||||
HANDLE m_eventHandle;
|
||||
GraphStatus m_graphStatus;
|
||||
QMediaPlayer::Error m_error;
|
||||
QIODevice *m_stream;
|
||||
IFilterGraph2 *m_graph;
|
||||
IBaseFilter *m_source;
|
||||
IBaseFilter *m_audioOutput;
|
||||
IBaseFilter *m_videoOutput;
|
||||
int m_streamTypes;
|
||||
qreal m_rate;
|
||||
qint64 m_position;
|
||||
qint64 m_duration;
|
||||
bool m_buffering;
|
||||
bool m_seekable;
|
||||
bool m_atEnd;
|
||||
QMediaTimeRange m_playbackRange;
|
||||
QUrl m_url;
|
||||
QMediaResourceList m_resources;
|
||||
QString m_errorString;
|
||||
QMutex m_mutex;
|
||||
|
||||
friend class DirectShowPlayerServiceThread;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
437
src/plugins/directshow/player/directshowsamplescheduler.cpp
Normal file
437
src/plugins/directshow/player/directshowsamplescheduler.cpp
Normal file
@@ -0,0 +1,437 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "directshowsamplescheduler.h"
|
||||
|
||||
#include <QtCore/qcoreapplication.h>
|
||||
#include <QtCore/qcoreevent.h>
|
||||
|
||||
class DirectShowTimedSample
|
||||
{
|
||||
public:
|
||||
DirectShowTimedSample(IMediaSample *sample)
|
||||
: m_next(0)
|
||||
, m_sample(sample)
|
||||
, m_cookie(0)
|
||||
, m_lastSample(false)
|
||||
{
|
||||
m_sample->AddRef();
|
||||
}
|
||||
|
||||
~DirectShowTimedSample()
|
||||
{
|
||||
m_sample->Release();
|
||||
}
|
||||
|
||||
IMediaSample *sample() const { return m_sample; }
|
||||
|
||||
DirectShowTimedSample *nextSample() const { return m_next; }
|
||||
void setNextSample(DirectShowTimedSample *sample) { Q_ASSERT(!m_next); m_next = sample; }
|
||||
|
||||
DirectShowTimedSample *remove() {
|
||||
DirectShowTimedSample *next = m_next; delete this; return next; }
|
||||
|
||||
bool schedule(IReferenceClock *clock, REFERENCE_TIME startTime, HANDLE handle);
|
||||
void unschedule(IReferenceClock *clock);
|
||||
|
||||
bool isReady(IReferenceClock *clock) const;
|
||||
|
||||
bool isLast() const { return m_lastSample; }
|
||||
void setLast() { m_lastSample = true; }
|
||||
|
||||
private:
|
||||
DirectShowTimedSample *m_next;
|
||||
IMediaSample *m_sample;
|
||||
DWORD_PTR m_cookie;
|
||||
bool m_lastSample;
|
||||
};
|
||||
|
||||
bool DirectShowTimedSample::schedule(
|
||||
IReferenceClock *clock, REFERENCE_TIME startTime, HANDLE handle)
|
||||
{
|
||||
REFERENCE_TIME sampleStartTime;
|
||||
REFERENCE_TIME sampleEndTime;
|
||||
if (m_sample->GetTime(&sampleStartTime, &sampleEndTime) == S_OK) {
|
||||
if (clock->AdviseTime(
|
||||
startTime, sampleStartTime, reinterpret_cast<HEVENT>(handle), &m_cookie) == S_OK) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DirectShowTimedSample::unschedule(IReferenceClock *clock)
|
||||
{
|
||||
clock->Unadvise(m_cookie);
|
||||
}
|
||||
|
||||
bool DirectShowTimedSample::isReady(IReferenceClock *clock) const
|
||||
{
|
||||
REFERENCE_TIME sampleStartTime;
|
||||
REFERENCE_TIME sampleEndTime;
|
||||
REFERENCE_TIME currentTime;
|
||||
if (m_sample->GetTime(&sampleStartTime, &sampleEndTime) == S_OK) {
|
||||
if (clock->GetTime(¤tTime) == S_OK)
|
||||
return currentTime >= sampleStartTime;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
DirectShowSampleScheduler::DirectShowSampleScheduler(IUnknown *pin, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_pin(pin)
|
||||
, m_clock(0)
|
||||
, m_allocator(0)
|
||||
, m_head(0)
|
||||
, m_tail(0)
|
||||
, m_maximumSamples(1)
|
||||
, m_state(Stopped)
|
||||
, m_startTime(0)
|
||||
, m_timeoutEvent(::CreateEvent(0, 0, 0, 0))
|
||||
, m_flushEvent(::CreateEvent(0, 0, 0, 0))
|
||||
{
|
||||
m_semaphore.release(m_maximumSamples);
|
||||
}
|
||||
|
||||
DirectShowSampleScheduler::~DirectShowSampleScheduler()
|
||||
{
|
||||
::CloseHandle(m_timeoutEvent);
|
||||
::CloseHandle(m_flushEvent);
|
||||
|
||||
Q_ASSERT(!m_clock);
|
||||
Q_ASSERT(!m_allocator);
|
||||
}
|
||||
|
||||
HRESULT DirectShowSampleScheduler::QueryInterface(REFIID riid, void **ppvObject)
|
||||
{
|
||||
return m_pin->QueryInterface(riid, ppvObject);
|
||||
}
|
||||
|
||||
ULONG DirectShowSampleScheduler::AddRef()
|
||||
{
|
||||
return m_pin->AddRef();
|
||||
}
|
||||
|
||||
ULONG DirectShowSampleScheduler::Release()
|
||||
{
|
||||
return m_pin->Release();
|
||||
}
|
||||
|
||||
// IMemInputPin
|
||||
HRESULT DirectShowSampleScheduler::GetAllocator(IMemAllocator **ppAllocator)
|
||||
{
|
||||
if (!ppAllocator) {
|
||||
return E_POINTER;
|
||||
} else {
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
if (!m_allocator) {
|
||||
return VFW_E_NO_ALLOCATOR;
|
||||
} else {
|
||||
*ppAllocator = m_allocator;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT DirectShowSampleScheduler::NotifyAllocator(IMemAllocator *pAllocator, BOOL bReadOnly)
|
||||
{
|
||||
Q_UNUSED(bReadOnly);
|
||||
|
||||
HRESULT hr;
|
||||
ALLOCATOR_PROPERTIES properties;
|
||||
|
||||
if (!pAllocator) {
|
||||
if (m_allocator)
|
||||
m_allocator->Release();
|
||||
|
||||
m_allocator = 0;
|
||||
|
||||
return S_OK;
|
||||
} else if ((hr = pAllocator->GetProperties(&properties)) != S_OK) {
|
||||
return hr;
|
||||
} else {
|
||||
if (properties.cBuffers == 1) {
|
||||
ALLOCATOR_PROPERTIES actual;
|
||||
|
||||
properties.cBuffers = 2;
|
||||
if ((hr = pAllocator->SetProperties(&properties, &actual)) != S_OK)
|
||||
return hr;
|
||||
}
|
||||
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
if (m_allocator)
|
||||
m_allocator->Release();
|
||||
|
||||
m_allocator = pAllocator;
|
||||
m_allocator->AddRef();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT DirectShowSampleScheduler::GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps)
|
||||
{
|
||||
if (!pProps)
|
||||
return E_POINTER;
|
||||
|
||||
pProps->cBuffers = 2;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT DirectShowSampleScheduler::Receive(IMediaSample *pSample)
|
||||
{
|
||||
if (!pSample)
|
||||
return E_POINTER;
|
||||
|
||||
m_semaphore.acquire(1);
|
||||
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
if (m_state & Flushing) {
|
||||
m_semaphore.release(1);
|
||||
|
||||
return S_FALSE;
|
||||
} else if (m_state == Stopped) {
|
||||
m_semaphore.release();
|
||||
|
||||
return VFW_E_WRONG_STATE;
|
||||
} else {
|
||||
DirectShowTimedSample *timedSample = new DirectShowTimedSample(pSample);
|
||||
|
||||
if (m_tail)
|
||||
m_tail->setNextSample(timedSample);
|
||||
else
|
||||
m_head = timedSample;
|
||||
|
||||
m_tail = timedSample;
|
||||
|
||||
if (m_state == Running) {
|
||||
if (!timedSample->schedule(m_clock, m_startTime, m_timeoutEvent)) {
|
||||
// Timing information is unavailable, so schedule frames immediately.
|
||||
QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
|
||||
} else {
|
||||
locker.unlock();
|
||||
HANDLE handles[] = { m_flushEvent, m_timeoutEvent };
|
||||
DWORD result = ::WaitForMultipleObjects(2, handles, FALSE, INFINITE);
|
||||
locker.relock();
|
||||
|
||||
if (result == WAIT_OBJECT_0 + 1)
|
||||
QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
|
||||
}
|
||||
} else if (m_tail == m_head) {
|
||||
// If this is the first frame make it available.
|
||||
QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
|
||||
|
||||
if (m_state == Paused) {
|
||||
::ResetEvent(m_timeoutEvent);
|
||||
|
||||
locker.unlock();
|
||||
HANDLE handles[] = { m_flushEvent, m_timeoutEvent };
|
||||
::WaitForMultipleObjects(2, handles, FALSE, INFINITE);
|
||||
locker.relock();
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT DirectShowSampleScheduler::ReceiveMultiple(
|
||||
IMediaSample **pSamples, long nSamples, long *nSamplesProcessed)
|
||||
{
|
||||
if (!pSamples || !nSamplesProcessed)
|
||||
return E_POINTER;
|
||||
|
||||
for (*nSamplesProcessed = 0; *nSamplesProcessed < nSamples; ++(*nSamplesProcessed)) {
|
||||
HRESULT hr = Receive(pSamples[*nSamplesProcessed]);
|
||||
|
||||
if (hr != S_OK)
|
||||
return hr;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT DirectShowSampleScheduler::ReceiveCanBlock()
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void DirectShowSampleScheduler::run(REFERENCE_TIME startTime)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
m_state = (m_state & Flushing) | Running;
|
||||
m_startTime = startTime;
|
||||
|
||||
for (DirectShowTimedSample *sample = m_head; sample; sample = sample->nextSample()) {
|
||||
sample->schedule(m_clock, m_startTime, m_timeoutEvent);
|
||||
}
|
||||
|
||||
if (!(m_state & Flushing))
|
||||
::ResetEvent(m_flushEvent);
|
||||
|
||||
if (!m_head)
|
||||
::SetEvent(m_timeoutEvent);
|
||||
|
||||
}
|
||||
|
||||
void DirectShowSampleScheduler::pause()
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
m_state = (m_state & Flushing) | Paused;
|
||||
|
||||
for (DirectShowTimedSample *sample = m_head; sample; sample = sample->nextSample())
|
||||
sample->unschedule(m_clock);
|
||||
|
||||
if (!(m_state & Flushing))
|
||||
::ResetEvent(m_flushEvent);
|
||||
}
|
||||
|
||||
void DirectShowSampleScheduler::stop()
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
m_state = m_state & Flushing;
|
||||
|
||||
for (DirectShowTimedSample *sample = m_head; sample; sample = sample->remove()) {
|
||||
sample->unschedule(m_clock);
|
||||
|
||||
m_semaphore.release(1);
|
||||
}
|
||||
|
||||
m_head = 0;
|
||||
m_tail = 0;
|
||||
|
||||
::SetEvent(m_flushEvent);
|
||||
}
|
||||
|
||||
void DirectShowSampleScheduler::setFlushing(bool flushing)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
const bool isFlushing = m_state & Flushing;
|
||||
|
||||
if (isFlushing != flushing) {
|
||||
if (flushing) {
|
||||
m_state |= Flushing;
|
||||
|
||||
for (DirectShowTimedSample *sample = m_head; sample; sample = sample->remove()) {
|
||||
sample->unschedule(m_clock);
|
||||
|
||||
m_semaphore.release(1);
|
||||
}
|
||||
m_head = 0;
|
||||
m_tail = 0;
|
||||
|
||||
::SetEvent(m_flushEvent);
|
||||
} else {
|
||||
m_state &= ~Flushing;
|
||||
|
||||
if (m_state != Stopped)
|
||||
::ResetEvent(m_flushEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DirectShowSampleScheduler::setClock(IReferenceClock *clock)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
if (m_clock)
|
||||
m_clock->Release();
|
||||
|
||||
m_clock = clock;
|
||||
|
||||
if (m_clock)
|
||||
m_clock->AddRef();
|
||||
}
|
||||
|
||||
IMediaSample *DirectShowSampleScheduler::takeSample(bool *eos)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
if (m_head && m_head->isReady(m_clock)) {
|
||||
IMediaSample *sample = m_head->sample();
|
||||
sample->AddRef();
|
||||
|
||||
*eos = m_head->isLast();
|
||||
|
||||
m_head = m_head->remove();
|
||||
|
||||
if (!m_head)
|
||||
m_tail = 0;
|
||||
|
||||
m_semaphore.release(1);
|
||||
|
||||
return sample;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool DirectShowSampleScheduler::scheduleEndOfStream()
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
if (m_tail) {
|
||||
m_tail->setLast();
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool DirectShowSampleScheduler::event(QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::UpdateRequest) {
|
||||
emit sampleReady();
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return QObject::event(event);
|
||||
}
|
||||
}
|
||||
117
src/plugins/directshow/player/directshowsamplescheduler.h
Normal file
117
src/plugins/directshow/player/directshowsamplescheduler.h
Normal file
@@ -0,0 +1,117 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 DIRECTSHOWSAMPLESCHEDULER_H
|
||||
#define DIRECTSHOWSAMPLESCHEDULER_H
|
||||
|
||||
#include <QtCore/qmutex.h>
|
||||
#include <QtCore/qobject.h>
|
||||
#include <QtCore/qsemaphore.h>
|
||||
|
||||
#include <dshow.h>
|
||||
|
||||
class DirectShowTimedSample;
|
||||
|
||||
class DirectShowSampleScheduler : public QObject, public IMemInputPin
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
enum State
|
||||
{
|
||||
Stopped = 0x00,
|
||||
Running = 0x01,
|
||||
Paused = 0x02,
|
||||
RunMask = 0x03,
|
||||
Flushing = 0x04
|
||||
};
|
||||
|
||||
DirectShowSampleScheduler(IUnknown *pin, QObject *parent = 0);
|
||||
~DirectShowSampleScheduler();
|
||||
|
||||
// IUnknown
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject);
|
||||
ULONG STDMETHODCALLTYPE AddRef();
|
||||
ULONG STDMETHODCALLTYPE Release();
|
||||
|
||||
// IMemInputPin
|
||||
HRESULT STDMETHODCALLTYPE GetAllocator(IMemAllocator **ppAllocator);
|
||||
HRESULT STDMETHODCALLTYPE NotifyAllocator(IMemAllocator *pAllocator, BOOL bReadOnly);
|
||||
HRESULT STDMETHODCALLTYPE GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE Receive(IMediaSample *pSample);
|
||||
HRESULT STDMETHODCALLTYPE ReceiveMultiple(IMediaSample **pSamples, long nSamples, long *nSamplesProcessed);
|
||||
HRESULT STDMETHODCALLTYPE ReceiveCanBlock();
|
||||
|
||||
void run(REFERENCE_TIME startTime);
|
||||
void pause();
|
||||
void stop();
|
||||
void setFlushing(bool flushing);
|
||||
|
||||
IReferenceClock *clock() const { return m_clock; }
|
||||
void setClock(IReferenceClock *clock);
|
||||
|
||||
bool schedule(IMediaSample *sample);
|
||||
bool scheduleEndOfStream();
|
||||
|
||||
IMediaSample *takeSample(bool *eos);
|
||||
|
||||
bool event(QEvent *event);
|
||||
|
||||
Q_SIGNALS:
|
||||
void sampleReady();
|
||||
|
||||
private:
|
||||
IUnknown *m_pin;
|
||||
IReferenceClock *m_clock;
|
||||
IMemAllocator *m_allocator;
|
||||
DirectShowTimedSample *m_head;
|
||||
DirectShowTimedSample *m_tail;
|
||||
int m_maximumSamples;
|
||||
int m_state;
|
||||
REFERENCE_TIME m_startTime;
|
||||
HANDLE m_timeoutEvent;
|
||||
HANDLE m_flushEvent;
|
||||
QSemaphore m_semaphore;
|
||||
QMutex m_mutex;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,86 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "directshowvideorenderercontrol.h"
|
||||
|
||||
#include "videosurfacefilter.h"
|
||||
|
||||
DirectShowVideoRendererControl::DirectShowVideoRendererControl(DirectShowEventLoop *loop, QObject *parent)
|
||||
: QVideoRendererControl(parent)
|
||||
, m_loop(loop)
|
||||
, m_surface(0)
|
||||
, m_filter(0)
|
||||
{
|
||||
}
|
||||
|
||||
DirectShowVideoRendererControl::~DirectShowVideoRendererControl()
|
||||
{
|
||||
delete m_filter;
|
||||
}
|
||||
|
||||
QAbstractVideoSurface *DirectShowVideoRendererControl::surface() const
|
||||
{
|
||||
return m_surface;
|
||||
}
|
||||
|
||||
void DirectShowVideoRendererControl::setSurface(QAbstractVideoSurface *surface)
|
||||
{
|
||||
if (surface != m_surface) {
|
||||
m_surface = surface;
|
||||
|
||||
VideoSurfaceFilter *existingFilter = m_filter;
|
||||
|
||||
if (surface) {
|
||||
m_filter = new VideoSurfaceFilter(surface, m_loop);
|
||||
} else {
|
||||
m_filter = 0;
|
||||
}
|
||||
|
||||
emit filterChanged();
|
||||
|
||||
delete existingFilter;
|
||||
}
|
||||
}
|
||||
|
||||
IBaseFilter *DirectShowVideoRendererControl::filter()
|
||||
{
|
||||
return m_filter;
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 DIRECTSHOWVIDEORENDERERCONTROL_H
|
||||
#define DIRECTSHOWVIDEORENDERERCONTROL_H
|
||||
|
||||
#include "qvideorenderercontrol.h"
|
||||
|
||||
#include <dshow.h>
|
||||
|
||||
class DirectShowEventLoop;
|
||||
class VideoSurfaceFilter;
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class DirectShowVideoRendererControl : public QVideoRendererControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DirectShowVideoRendererControl(DirectShowEventLoop *loop, QObject *parent = 0);
|
||||
~DirectShowVideoRendererControl();
|
||||
|
||||
QAbstractVideoSurface *surface() const;
|
||||
void setSurface(QAbstractVideoSurface *surface);
|
||||
|
||||
IBaseFilter *filter();
|
||||
|
||||
Q_SIGNALS:
|
||||
void filterChanged();
|
||||
|
||||
private:
|
||||
DirectShowEventLoop *m_loop;
|
||||
QAbstractVideoSurface *m_surface;
|
||||
VideoSurfaceFilter *m_filter;
|
||||
};
|
||||
|
||||
#endif
|
||||
86
src/plugins/directshow/player/mediasamplevideobuffer.cpp
Normal file
86
src/plugins/directshow/player/mediasamplevideobuffer.cpp
Normal file
@@ -0,0 +1,86 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "mediasamplevideobuffer.h"
|
||||
|
||||
MediaSampleVideoBuffer::MediaSampleVideoBuffer(IMediaSample *sample, int bytesPerLine)
|
||||
: QAbstractVideoBuffer(NoHandle)
|
||||
, m_sample(sample)
|
||||
, m_bytesPerLine(bytesPerLine)
|
||||
, m_mapMode(NotMapped)
|
||||
{
|
||||
m_sample->AddRef();
|
||||
}
|
||||
|
||||
MediaSampleVideoBuffer::~MediaSampleVideoBuffer()
|
||||
{
|
||||
m_sample->Release();
|
||||
}
|
||||
|
||||
uchar *MediaSampleVideoBuffer::map(MapMode mode, int *numBytes, int *bytesPerLine)
|
||||
{
|
||||
if (m_mapMode == NotMapped && mode != NotMapped) {
|
||||
if (numBytes)
|
||||
*numBytes = m_sample->GetActualDataLength();
|
||||
|
||||
if (bytesPerLine)
|
||||
*bytesPerLine = m_bytesPerLine;
|
||||
|
||||
BYTE *bytes = 0;
|
||||
|
||||
if (m_sample->GetPointer(&bytes) == S_OK) {
|
||||
m_mapMode = mode;
|
||||
|
||||
return reinterpret_cast<uchar *>(bytes);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MediaSampleVideoBuffer::unmap()
|
||||
{
|
||||
m_mapMode = NotMapped;
|
||||
}
|
||||
|
||||
QAbstractVideoBuffer::MapMode MediaSampleVideoBuffer::mapMode() const
|
||||
{
|
||||
return m_mapMode;
|
||||
}
|
||||
69
src/plugins/directshow/player/mediasamplevideobuffer.h
Normal file
69
src/plugins/directshow/player/mediasamplevideobuffer.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 MEDIASAMPLEVIDEOBUFFER_H
|
||||
#define MEDIASAMPLEVIDEOBUFFER_H
|
||||
|
||||
#include <qabstractvideobuffer.h>
|
||||
|
||||
#include <dshow.h>
|
||||
|
||||
class MediaSampleVideoBuffer : public QAbstractVideoBuffer
|
||||
{
|
||||
public:
|
||||
MediaSampleVideoBuffer(IMediaSample *sample, int bytesPerLine);
|
||||
~MediaSampleVideoBuffer();
|
||||
|
||||
IMediaSample *sample() { return m_sample; }
|
||||
|
||||
uchar *map(MapMode mode, int *numBytes, int *bytesPerLine);
|
||||
void unmap();
|
||||
|
||||
MapMode mapMode() const;
|
||||
|
||||
private:
|
||||
IMediaSample *m_sample;
|
||||
int m_bytesPerLine;
|
||||
MapMode m_mapMode;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
47
src/plugins/directshow/player/player.pri
Normal file
47
src/plugins/directshow/player/player.pri
Normal file
@@ -0,0 +1,47 @@
|
||||
INCLUDEPATH += $$PWD
|
||||
|
||||
DEFINES += QMEDIA_DIRECTSHOW_PLAYER
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/directshowaudioendpointcontrol.h \
|
||||
$$PWD/directshoweventloop.h \
|
||||
$$PWD/directshowglobal.h \
|
||||
$$PWD/directshowioreader.h \
|
||||
$$PWD/directshowiosource.h \
|
||||
$$PWD/directshowmediatype.h \
|
||||
$$PWD/directshowmediatypelist.h \
|
||||
$$PWD/directshowmetadatacontrol.h \
|
||||
$$PWD/directshowpinenum.h \
|
||||
$$PWD/directshowplayercontrol.h \
|
||||
$$PWD/directshowplayerservice.h \
|
||||
$$PWD/directshowsamplescheduler.h \
|
||||
$$PWD/directshowvideorenderercontrol.h \
|
||||
$$PWD/mediasamplevideobuffer.h \
|
||||
$$PWD/videosurfacefilter.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/directshowaudioendpointcontrol.cpp \
|
||||
$$PWD/directshoweventloop.cpp \
|
||||
$$PWD/directshowioreader.cpp \
|
||||
$$PWD/directshowiosource.cpp \
|
||||
$$PWD/directshowmediatype.cpp \
|
||||
$$PWD/directshowmediatypelist.cpp \
|
||||
$$PWD/directshowmetadatacontrol.cpp \
|
||||
$$PWD/directshowpinenum.cpp \
|
||||
$$PWD/directshowplayercontrol.cpp \
|
||||
$$PWD/directshowplayerservice.cpp \
|
||||
$$PWD/directshowsamplescheduler.cpp \
|
||||
$$PWD/directshowvideorenderercontrol.cpp \
|
||||
$$PWD/mediasamplevideobuffer.cpp \
|
||||
$$PWD/videosurfacefilter.cpp
|
||||
|
||||
!simulator {
|
||||
HEADERS += \
|
||||
$$PWD/vmr9videowindowcontrol.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/vmr9videowindowcontrol.cpp
|
||||
}
|
||||
|
||||
LIBS += -lstrmiids -ldmoguids -luuid -lmsdmo -lole32 -loleaut32 -lgdi32
|
||||
|
||||
631
src/plugins/directshow/player/videosurfacefilter.cpp
Normal file
631
src/plugins/directshow/player/videosurfacefilter.cpp
Normal file
@@ -0,0 +1,631 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "videosurfacefilter.h"
|
||||
|
||||
#include "directshoweventloop.h"
|
||||
#include "directshowglobal.h"
|
||||
#include "directshowpinenum.h"
|
||||
#include "mediasamplevideobuffer.h"
|
||||
|
||||
#include <QtCore/qcoreapplication.h>
|
||||
#include <QtCore/qcoreevent.h>
|
||||
#include <QtCore/qthread.h>
|
||||
#include <qabstractvideosurface.h>
|
||||
|
||||
#include <initguid.h>
|
||||
|
||||
// { e23cad72-153d-406c-bf3f-4c4b523d96f2 }
|
||||
DEFINE_GUID(CLSID_VideoSurfaceFilter,
|
||||
0xe23cad72, 0x153d, 0x406c, 0xbf, 0x3f, 0x4c, 0x4b, 0x52, 0x3d, 0x96, 0xf2);
|
||||
|
||||
VideoSurfaceFilter::VideoSurfaceFilter(
|
||||
QAbstractVideoSurface *surface, DirectShowEventLoop *loop, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_ref(1)
|
||||
, m_state(State_Stopped)
|
||||
, m_surface(surface)
|
||||
, m_loop(loop)
|
||||
, m_graph(0)
|
||||
, m_peerPin(0)
|
||||
, m_bytesPerLine(0)
|
||||
, m_startResult(S_OK)
|
||||
, m_pinId(QString::fromLatin1("reference"))
|
||||
, m_sampleScheduler(static_cast<IPin *>(this))
|
||||
{
|
||||
connect(surface, SIGNAL(supportedFormatsChanged()), this, SLOT(supportedFormatsChanged()));
|
||||
connect(&m_sampleScheduler, SIGNAL(sampleReady()), this, SLOT(sampleReady()));
|
||||
}
|
||||
|
||||
VideoSurfaceFilter::~VideoSurfaceFilter()
|
||||
{
|
||||
Q_ASSERT(m_ref == 1);
|
||||
}
|
||||
|
||||
HRESULT VideoSurfaceFilter::QueryInterface(REFIID riid, void **ppvObject)
|
||||
{
|
||||
// 2dd74950-a890-11d1-abe8-00a0c905f375
|
||||
static const GUID iid_IAmFilterMiscFlags = {
|
||||
0x2dd74950, 0xa890, 0x11d1, {0xab, 0xe8, 0x00, 0xa0, 0xc9, 0x05, 0xf3, 0x75} };
|
||||
|
||||
if (!ppvObject) {
|
||||
return E_POINTER;
|
||||
} else if (riid == IID_IUnknown
|
||||
|| riid == IID_IPersist
|
||||
|| riid == IID_IMediaFilter
|
||||
|| riid == IID_IBaseFilter) {
|
||||
*ppvObject = static_cast<IBaseFilter *>(this);
|
||||
} else if (riid == iid_IAmFilterMiscFlags) {
|
||||
*ppvObject = static_cast<IAMFilterMiscFlags *>(this);
|
||||
} else if (riid == IID_IPin) {
|
||||
*ppvObject = static_cast<IPin *>(this);
|
||||
} else if (riid == IID_IMemInputPin) {
|
||||
*ppvObject = static_cast<IMemInputPin *>(&m_sampleScheduler);
|
||||
} else {
|
||||
*ppvObject = 0;
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
AddRef();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
ULONG VideoSurfaceFilter::AddRef()
|
||||
{
|
||||
return InterlockedIncrement(&m_ref);
|
||||
}
|
||||
|
||||
ULONG VideoSurfaceFilter::Release()
|
||||
{
|
||||
ULONG ref = InterlockedDecrement(&m_ref);
|
||||
|
||||
Q_ASSERT(ref != 0);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
HRESULT VideoSurfaceFilter::GetClassID(CLSID *pClassID)
|
||||
{
|
||||
*pClassID = CLSID_VideoSurfaceFilter;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT VideoSurfaceFilter::Run(REFERENCE_TIME tStart)
|
||||
{
|
||||
m_state = State_Running;
|
||||
|
||||
m_sampleScheduler.run(tStart);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT VideoSurfaceFilter::Pause()
|
||||
{
|
||||
m_state = State_Paused;
|
||||
|
||||
m_sampleScheduler.pause();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT VideoSurfaceFilter::Stop()
|
||||
{
|
||||
m_state = State_Stopped;
|
||||
|
||||
m_sampleScheduler.stop();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT VideoSurfaceFilter::GetState(DWORD dwMilliSecsTimeout, FILTER_STATE *pState)
|
||||
{
|
||||
if (!pState)
|
||||
return E_POINTER;
|
||||
|
||||
*pState = m_state;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT VideoSurfaceFilter::SetSyncSource(IReferenceClock *pClock)
|
||||
{
|
||||
|
||||
m_sampleScheduler.setClock(pClock);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT VideoSurfaceFilter::GetSyncSource(IReferenceClock **ppClock)
|
||||
{
|
||||
if (!ppClock) {
|
||||
return E_POINTER;
|
||||
} else {
|
||||
*ppClock = m_sampleScheduler.clock();
|
||||
|
||||
if (*ppClock) {
|
||||
(*ppClock)->AddRef();
|
||||
|
||||
return S_OK;
|
||||
} else {
|
||||
return S_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT VideoSurfaceFilter::EnumPins(IEnumPins **ppEnum)
|
||||
{
|
||||
if (ppEnum) {
|
||||
*ppEnum = new DirectShowPinEnum(QList<IPin *>() << this);
|
||||
|
||||
return S_OK;
|
||||
} else {
|
||||
return E_POINTER;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT VideoSurfaceFilter::FindPin(LPCWSTR pId, IPin **ppPin)
|
||||
{
|
||||
if (!ppPin || !pId) {
|
||||
return E_POINTER;
|
||||
} else if (QString::fromWCharArray(pId) == m_pinId) {
|
||||
AddRef();
|
||||
|
||||
*ppPin = this;
|
||||
|
||||
return S_OK;
|
||||
} else {
|
||||
return VFW_E_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT VideoSurfaceFilter::JoinFilterGraph(IFilterGraph *pGraph, LPCWSTR pName)
|
||||
{
|
||||
m_graph = pGraph;
|
||||
m_name = QString::fromWCharArray(pName);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT VideoSurfaceFilter::QueryFilterInfo(FILTER_INFO *pInfo)
|
||||
{
|
||||
if (pInfo) {
|
||||
QString name = m_name;
|
||||
|
||||
if (name.length() >= MAX_FILTER_NAME)
|
||||
name.truncate(MAX_FILTER_NAME - 1);
|
||||
|
||||
int length = name.toWCharArray(pInfo->achName);
|
||||
pInfo->achName[length] = '\0';
|
||||
|
||||
if (m_graph)
|
||||
m_graph->AddRef();
|
||||
|
||||
pInfo->pGraph = m_graph;
|
||||
|
||||
return S_OK;
|
||||
} else {
|
||||
return E_POINTER;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT VideoSurfaceFilter::QueryVendorInfo(LPWSTR *pVendorInfo)
|
||||
{
|
||||
Q_UNUSED(pVendorInfo);
|
||||
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
ULONG VideoSurfaceFilter::GetMiscFlags()
|
||||
{
|
||||
return AM_FILTER_MISC_FLAGS_IS_RENDERER;
|
||||
}
|
||||
|
||||
|
||||
HRESULT VideoSurfaceFilter::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
|
||||
{
|
||||
// This is an input pin, you shouldn't be calling Connect on it.
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
HRESULT VideoSurfaceFilter::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt)
|
||||
{
|
||||
if (!pConnector) {
|
||||
return E_POINTER;
|
||||
} else if (!pmt) {
|
||||
return E_POINTER;
|
||||
} else {
|
||||
HRESULT hr;
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
if (m_peerPin) {
|
||||
hr = VFW_E_ALREADY_CONNECTED;
|
||||
} else if (pmt->majortype != MEDIATYPE_Video) {
|
||||
hr = VFW_E_TYPE_NOT_ACCEPTED;
|
||||
} else {
|
||||
m_surfaceFormat = DirectShowMediaType::formatFromType(*pmt);
|
||||
m_bytesPerLine = DirectShowMediaType::bytesPerLine(m_surfaceFormat);
|
||||
|
||||
if (thread() == QThread::currentThread()) {
|
||||
hr = start();
|
||||
} else {
|
||||
m_loop->postEvent(this, new QEvent(QEvent::Type(StartSurface)));
|
||||
|
||||
m_wait.wait(&m_mutex);
|
||||
|
||||
hr = m_startResult;
|
||||
}
|
||||
}
|
||||
if (hr == S_OK) {
|
||||
m_peerPin = pConnector;
|
||||
m_peerPin->AddRef();
|
||||
|
||||
DirectShowMediaType::copy(&m_mediaType, *pmt);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT VideoSurfaceFilter::start()
|
||||
{
|
||||
if (!m_surface->isFormatSupported(m_surfaceFormat)) {
|
||||
return VFW_E_TYPE_NOT_ACCEPTED;
|
||||
}
|
||||
if (!m_surface->start(m_surfaceFormat)) {
|
||||
return VFW_E_TYPE_NOT_ACCEPTED;
|
||||
} else {
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT VideoSurfaceFilter::Disconnect()
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
if (!m_peerPin)
|
||||
return S_FALSE;
|
||||
|
||||
if (thread() == QThread::currentThread()) {
|
||||
stop();
|
||||
} else {
|
||||
m_loop->postEvent(this, new QEvent(QEvent::Type(StopSurface)));
|
||||
|
||||
m_wait.wait(&m_mutex);
|
||||
}
|
||||
|
||||
m_mediaType.clear();
|
||||
|
||||
m_sampleScheduler.NotifyAllocator(0, FALSE);
|
||||
|
||||
m_peerPin->Release();
|
||||
m_peerPin = 0;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void VideoSurfaceFilter::stop()
|
||||
{
|
||||
m_surface->stop();
|
||||
}
|
||||
|
||||
HRESULT VideoSurfaceFilter::ConnectedTo(IPin **ppPin)
|
||||
{
|
||||
if (!ppPin) {
|
||||
return E_POINTER;
|
||||
} else {
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
if (!m_peerPin) {
|
||||
return VFW_E_NOT_CONNECTED;
|
||||
} else {
|
||||
m_peerPin->AddRef();
|
||||
|
||||
*ppPin = m_peerPin;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT VideoSurfaceFilter::ConnectionMediaType(AM_MEDIA_TYPE *pmt)
|
||||
{
|
||||
if (!pmt) {
|
||||
return E_POINTER;
|
||||
} else {
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
if (!m_peerPin) {
|
||||
return VFW_E_NOT_CONNECTED;
|
||||
} else {
|
||||
DirectShowMediaType::copy(pmt, m_mediaType);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT VideoSurfaceFilter::QueryPinInfo(PIN_INFO *pInfo)
|
||||
{
|
||||
if (!pInfo) {
|
||||
return E_POINTER;
|
||||
} else {
|
||||
AddRef();
|
||||
|
||||
pInfo->pFilter = this;
|
||||
pInfo->dir = PINDIR_INPUT;
|
||||
|
||||
const int bytes = qMin(MAX_FILTER_NAME, (m_pinId.length() + 1) * 2);
|
||||
|
||||
qMemCopy(pInfo->achName, m_pinId.utf16(), bytes);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT VideoSurfaceFilter::QueryId(LPWSTR *Id)
|
||||
{
|
||||
if (!Id) {
|
||||
return E_POINTER;
|
||||
} else {
|
||||
const int bytes = (m_pinId.length() + 1) * 2;
|
||||
|
||||
*Id = static_cast<LPWSTR>(::CoTaskMemAlloc(bytes));
|
||||
|
||||
qMemCopy(*Id, m_pinId.utf16(), bytes);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT VideoSurfaceFilter::QueryAccept(const AM_MEDIA_TYPE *pmt)
|
||||
{
|
||||
return !m_surface->isFormatSupported(DirectShowMediaType::formatFromType(*pmt))
|
||||
? S_OK
|
||||
: S_FALSE;
|
||||
}
|
||||
|
||||
HRESULT VideoSurfaceFilter::EnumMediaTypes(IEnumMediaTypes **ppEnum)
|
||||
{
|
||||
if (!ppEnum) {
|
||||
return E_POINTER;
|
||||
} else {
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
*ppEnum = createMediaTypeEnum();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT VideoSurfaceFilter::QueryInternalConnections(IPin **apPin, ULONG *nPin)
|
||||
{
|
||||
Q_UNUSED(apPin);
|
||||
Q_UNUSED(nPin);
|
||||
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT VideoSurfaceFilter::EndOfStream()
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
if (!m_sampleScheduler.scheduleEndOfStream()) {
|
||||
if (IMediaEventSink *sink = com_cast<IMediaEventSink>(m_graph, IID_IMediaEventSink)) {
|
||||
sink->Notify(
|
||||
EC_COMPLETE,
|
||||
S_OK,
|
||||
reinterpret_cast<LONG_PTR>(static_cast<IBaseFilter *>(this)));
|
||||
sink->Release();
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT VideoSurfaceFilter::BeginFlush()
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
m_sampleScheduler.setFlushing(true);
|
||||
|
||||
if (thread() == QThread::currentThread()) {
|
||||
flush();
|
||||
} else {
|
||||
m_loop->postEvent(this, new QEvent(QEvent::Type(FlushSurface)));
|
||||
|
||||
m_wait.wait(&m_mutex);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT VideoSurfaceFilter::EndFlush()
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
m_sampleScheduler.setFlushing(false);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void VideoSurfaceFilter::flush()
|
||||
{
|
||||
m_surface->present(QVideoFrame());
|
||||
|
||||
m_wait.wakeAll();
|
||||
}
|
||||
|
||||
HRESULT VideoSurfaceFilter::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
|
||||
{
|
||||
Q_UNUSED(tStart);
|
||||
Q_UNUSED(tStop);
|
||||
Q_UNUSED(dRate);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT VideoSurfaceFilter::QueryDirection(PIN_DIRECTION *pPinDir)
|
||||
{
|
||||
if (!pPinDir) {
|
||||
return E_POINTER;
|
||||
} else {
|
||||
*pPinDir = PINDIR_INPUT;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
int VideoSurfaceFilter::currentMediaTypeToken()
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
return DirectShowMediaTypeList::currentMediaTypeToken();
|
||||
}
|
||||
|
||||
HRESULT VideoSurfaceFilter::nextMediaType(
|
||||
int token, int *index, ULONG count, AM_MEDIA_TYPE **types, ULONG *fetchedCount)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
return DirectShowMediaTypeList::nextMediaType(token, index, count, types, fetchedCount);
|
||||
|
||||
}
|
||||
|
||||
HRESULT VideoSurfaceFilter::skipMediaType(int token, int *index, ULONG count)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
return DirectShowMediaTypeList::skipMediaType(token, index, count);
|
||||
}
|
||||
|
||||
HRESULT VideoSurfaceFilter::cloneMediaType(int token, int index, IEnumMediaTypes **enumeration)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
return DirectShowMediaTypeList::cloneMediaType(token, index, enumeration);
|
||||
}
|
||||
|
||||
void VideoSurfaceFilter::customEvent(QEvent *event)
|
||||
{
|
||||
if (event->type() == StartSurface) {
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
m_startResult = start();
|
||||
|
||||
m_wait.wakeAll();
|
||||
} else if (event->type() == StopSurface) {
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
stop();
|
||||
|
||||
m_wait.wakeAll();
|
||||
} else if (event->type() == FlushSurface) {
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
flush();
|
||||
|
||||
m_wait.wakeAll();
|
||||
} else {
|
||||
QObject::customEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
void VideoSurfaceFilter::supportedFormatsChanged()
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
// MEDIASUBTYPE_None;
|
||||
static const GUID none = {
|
||||
0xe436eb8e, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70} };
|
||||
|
||||
QList<QVideoFrame::PixelFormat> formats = m_surface->supportedPixelFormats();
|
||||
|
||||
QVector<AM_MEDIA_TYPE> mediaTypes;
|
||||
mediaTypes.reserve(formats.count());
|
||||
|
||||
AM_MEDIA_TYPE type;
|
||||
type.majortype = MEDIATYPE_Video;
|
||||
type.bFixedSizeSamples = TRUE;
|
||||
type.bTemporalCompression = FALSE;
|
||||
type.lSampleSize = 0;
|
||||
type.formattype = GUID_NULL;
|
||||
type.pUnk = 0;
|
||||
type.cbFormat = 0;
|
||||
type.pbFormat = 0;
|
||||
|
||||
foreach (QVideoFrame::PixelFormat format, formats) {
|
||||
type.subtype = DirectShowMediaType::convertPixelFormat(format);
|
||||
|
||||
if (type.subtype != none)
|
||||
mediaTypes.append(type);
|
||||
}
|
||||
|
||||
setMediaTypes(mediaTypes);
|
||||
}
|
||||
|
||||
void VideoSurfaceFilter::sampleReady()
|
||||
{
|
||||
bool eos = false;
|
||||
|
||||
IMediaSample *sample = m_sampleScheduler.takeSample(&eos);
|
||||
|
||||
if (sample) {
|
||||
m_surface->present(QVideoFrame(
|
||||
new MediaSampleVideoBuffer(sample, m_bytesPerLine),
|
||||
m_surfaceFormat.frameSize(),
|
||||
m_surfaceFormat.pixelFormat()));
|
||||
|
||||
sample->Release();
|
||||
|
||||
if (eos) {
|
||||
if (IMediaEventSink *sink = com_cast<IMediaEventSink>(m_graph, IID_IMediaEventSink)) {
|
||||
sink->Notify(
|
||||
EC_COMPLETE,
|
||||
S_OK,
|
||||
reinterpret_cast<LONG_PTR>(static_cast<IBaseFilter *>(this)));
|
||||
sink->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
176
src/plugins/directshow/player/videosurfacefilter.h
Normal file
176
src/plugins/directshow/player/videosurfacefilter.h
Normal file
@@ -0,0 +1,176 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 VIDEOSURFACEFILTER_H
|
||||
#define VIDEOSURFACEFILTER_H
|
||||
|
||||
#include "directshowglobal.h"
|
||||
#include "directshowmediatypelist.h"
|
||||
#include "directshowsamplescheduler.h"
|
||||
#include "directshowmediatype.h"
|
||||
|
||||
#include <QtCore/qbasictimer.h>
|
||||
#include <QtCore/qcoreevent.h>
|
||||
#include <QtCore/qmutex.h>
|
||||
#include <QtCore/qsemaphore.h>
|
||||
#include <QtCore/qstring.h>
|
||||
#include <QtCore/qwaitcondition.h>
|
||||
|
||||
#include <dshow.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QAbstractVideoSurface;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class DirectShowEventLoop;
|
||||
|
||||
class VideoSurfaceFilter
|
||||
: public QObject
|
||||
, public DirectShowMediaTypeList
|
||||
, public IBaseFilter
|
||||
, public IAMFilterMiscFlags
|
||||
, public IPin
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
VideoSurfaceFilter(
|
||||
QAbstractVideoSurface *surface, DirectShowEventLoop *loop, QObject *parent = 0);
|
||||
~VideoSurfaceFilter();
|
||||
|
||||
// IUnknown
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject);
|
||||
ULONG STDMETHODCALLTYPE AddRef();
|
||||
ULONG STDMETHODCALLTYPE Release();
|
||||
|
||||
// IPersist
|
||||
HRESULT STDMETHODCALLTYPE GetClassID(CLSID *pClassID);
|
||||
|
||||
// IMediaFilter
|
||||
HRESULT STDMETHODCALLTYPE Run(REFERENCE_TIME tStart);
|
||||
HRESULT STDMETHODCALLTYPE Pause();
|
||||
HRESULT STDMETHODCALLTYPE Stop();
|
||||
|
||||
HRESULT STDMETHODCALLTYPE GetState(DWORD dwMilliSecsTimeout, FILTER_STATE *pState);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE SetSyncSource(IReferenceClock *pClock);
|
||||
HRESULT STDMETHODCALLTYPE GetSyncSource(IReferenceClock **ppClock);
|
||||
|
||||
// IBaseFilter
|
||||
HRESULT STDMETHODCALLTYPE EnumPins(IEnumPins **ppEnum);
|
||||
HRESULT STDMETHODCALLTYPE FindPin(LPCWSTR Id, IPin **ppPin);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE JoinFilterGraph(IFilterGraph *pGraph, LPCWSTR pName);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE QueryFilterInfo(FILTER_INFO *pInfo);
|
||||
HRESULT STDMETHODCALLTYPE QueryVendorInfo(LPWSTR *pVendorInfo);
|
||||
|
||||
// IAMFilterMiscFlags
|
||||
ULONG STDMETHODCALLTYPE GetMiscFlags();
|
||||
|
||||
// IPin
|
||||
HRESULT STDMETHODCALLTYPE Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt);
|
||||
HRESULT STDMETHODCALLTYPE ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt);
|
||||
HRESULT STDMETHODCALLTYPE Disconnect();
|
||||
HRESULT STDMETHODCALLTYPE ConnectedTo(IPin **ppPin);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE ConnectionMediaType(AM_MEDIA_TYPE *pmt);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE QueryPinInfo(PIN_INFO *pInfo);
|
||||
HRESULT STDMETHODCALLTYPE QueryId(LPWSTR *Id);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE QueryAccept(const AM_MEDIA_TYPE *pmt);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE EnumMediaTypes(IEnumMediaTypes **ppEnum);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE QueryInternalConnections(IPin **apPin, ULONG *nPin);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE EndOfStream();
|
||||
|
||||
HRESULT STDMETHODCALLTYPE BeginFlush();
|
||||
HRESULT STDMETHODCALLTYPE EndFlush();
|
||||
|
||||
HRESULT STDMETHODCALLTYPE NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE QueryDirection(PIN_DIRECTION *pPinDir);
|
||||
|
||||
int currentMediaTypeToken();
|
||||
HRESULT nextMediaType(
|
||||
int token, int *index, ULONG count, AM_MEDIA_TYPE **types, ULONG *fetchedCount);
|
||||
HRESULT skipMediaType(int token, int *index, ULONG count);
|
||||
HRESULT cloneMediaType(int token, int index, IEnumMediaTypes **enumeration);
|
||||
|
||||
protected:
|
||||
void customEvent(QEvent *event);
|
||||
|
||||
private Q_SLOTS:
|
||||
void supportedFormatsChanged();
|
||||
void sampleReady();
|
||||
|
||||
private:
|
||||
HRESULT start();
|
||||
void stop();
|
||||
void flush();
|
||||
|
||||
enum
|
||||
{
|
||||
StartSurface = QEvent::User,
|
||||
StopSurface,
|
||||
FlushSurface
|
||||
};
|
||||
|
||||
LONG m_ref;
|
||||
FILTER_STATE m_state;
|
||||
QAbstractVideoSurface *m_surface;
|
||||
DirectShowEventLoop *m_loop;
|
||||
IFilterGraph *m_graph;
|
||||
IPin *m_peerPin;
|
||||
int m_bytesPerLine;
|
||||
HRESULT m_startResult;
|
||||
QString m_name;
|
||||
QString m_pinId;
|
||||
DirectShowMediaType m_mediaType;
|
||||
QVideoSurfaceFormat m_surfaceFormat;
|
||||
QMutex m_mutex;
|
||||
QWaitCondition m_wait;
|
||||
DirectShowSampleScheduler m_sampleScheduler;
|
||||
};
|
||||
|
||||
#endif
|
||||
329
src/plugins/directshow/player/vmr9videowindowcontrol.cpp
Normal file
329
src/plugins/directshow/player/vmr9videowindowcontrol.cpp
Normal file
@@ -0,0 +1,329 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "vmr9videowindowcontrol.h"
|
||||
|
||||
#include "directshowglobal.h"
|
||||
|
||||
Vmr9VideoWindowControl::Vmr9VideoWindowControl(QObject *parent)
|
||||
: QVideoWindowControl(parent)
|
||||
, m_filter(com_new<IBaseFilter>(CLSID_VideoMixingRenderer9, IID_IBaseFilter))
|
||||
, m_windowId(0)
|
||||
, m_dirtyValues(0)
|
||||
, m_aspectRatioMode(Qt::KeepAspectRatio)
|
||||
, m_brightness(0)
|
||||
, m_contrast(0)
|
||||
, m_hue(0)
|
||||
, m_saturation(0)
|
||||
, m_fullScreen(false)
|
||||
{
|
||||
if (IVMRFilterConfig9 *config = com_cast<IVMRFilterConfig9>(m_filter, IID_IVMRFilterConfig9)) {
|
||||
config->SetRenderingMode(VMR9Mode_Windowless);
|
||||
config->SetNumberOfStreams(1);
|
||||
config->Release();
|
||||
}
|
||||
}
|
||||
|
||||
Vmr9VideoWindowControl::~Vmr9VideoWindowControl()
|
||||
{
|
||||
if (m_filter)
|
||||
m_filter->Release();
|
||||
}
|
||||
|
||||
|
||||
WId Vmr9VideoWindowControl::winId() const
|
||||
{
|
||||
return m_windowId;
|
||||
|
||||
}
|
||||
|
||||
void Vmr9VideoWindowControl::setWinId(WId id)
|
||||
{
|
||||
m_windowId = id;
|
||||
|
||||
if (QWidget *widget = QWidget::find(m_windowId)) {
|
||||
const QColor color = widget->palette().color(QPalette::Window);
|
||||
|
||||
m_windowColor = RGB(color.red(), color.green(), color.blue());
|
||||
}
|
||||
|
||||
if (IVMRWindowlessControl9 *control = com_cast<IVMRWindowlessControl9>(
|
||||
m_filter, IID_IVMRWindowlessControl9)) {
|
||||
control->SetVideoClippingWindow(m_windowId);
|
||||
control->SetBorderColor(m_windowColor);
|
||||
control->Release();
|
||||
}
|
||||
}
|
||||
|
||||
QRect Vmr9VideoWindowControl::displayRect() const
|
||||
{
|
||||
return m_displayRect;
|
||||
}
|
||||
|
||||
void Vmr9VideoWindowControl::setDisplayRect(const QRect &rect)
|
||||
{
|
||||
m_displayRect = rect;
|
||||
|
||||
if (IVMRWindowlessControl9 *control = com_cast<IVMRWindowlessControl9>(
|
||||
m_filter, IID_IVMRWindowlessControl9)) {
|
||||
RECT sourceRect = { 0, 0, 0, 0 };
|
||||
RECT displayRect = { rect.left(), rect.top(), rect.right() + 1, rect.bottom() + 1 };
|
||||
|
||||
control->GetNativeVideoSize(&sourceRect.right, &sourceRect.bottom, 0, 0);
|
||||
|
||||
if (m_aspectRatioMode == Qt::KeepAspectRatioByExpanding) {
|
||||
QSize clippedSize = rect.size();
|
||||
clippedSize.scale(sourceRect.right, sourceRect.bottom, Qt::KeepAspectRatio);
|
||||
|
||||
sourceRect.left = (sourceRect.right - clippedSize.width()) / 2;
|
||||
sourceRect.top = (sourceRect.bottom - clippedSize.height()) / 2;
|
||||
sourceRect.right = sourceRect.left + clippedSize.width();
|
||||
sourceRect.bottom = sourceRect.top + clippedSize.height();
|
||||
}
|
||||
|
||||
control->SetVideoPosition(&sourceRect, &displayRect);
|
||||
control->Release();
|
||||
}
|
||||
}
|
||||
|
||||
bool Vmr9VideoWindowControl::isFullScreen() const
|
||||
{
|
||||
return m_fullScreen;
|
||||
}
|
||||
|
||||
void Vmr9VideoWindowControl::setFullScreen(bool fullScreen)
|
||||
{
|
||||
emit fullScreenChanged(m_fullScreen = fullScreen);
|
||||
}
|
||||
|
||||
void Vmr9VideoWindowControl::repaint()
|
||||
{
|
||||
PAINTSTRUCT paint;
|
||||
|
||||
if (HDC dc = ::BeginPaint(m_windowId, &paint)) {
|
||||
HRESULT hr = E_FAIL;
|
||||
|
||||
if (IVMRWindowlessControl9 *control = com_cast<IVMRWindowlessControl9>(
|
||||
m_filter, IID_IVMRWindowlessControl9)) {
|
||||
hr = control->RepaintVideo(m_windowId, dc);
|
||||
control->Release();
|
||||
}
|
||||
|
||||
if (!SUCCEEDED(hr)) {
|
||||
HPEN pen = ::CreatePen(PS_SOLID, 1, m_windowColor);
|
||||
HBRUSH brush = ::CreateSolidBrush(m_windowColor);
|
||||
::SelectObject(dc, pen);
|
||||
::SelectObject(dc, brush);
|
||||
|
||||
::Rectangle(
|
||||
dc,
|
||||
m_displayRect.left(),
|
||||
m_displayRect.top(),
|
||||
m_displayRect.right() + 1,
|
||||
m_displayRect.bottom() + 1);
|
||||
|
||||
::DeleteObject(pen);
|
||||
::DeleteObject(brush);
|
||||
}
|
||||
::EndPaint(m_windowId, &paint);
|
||||
}
|
||||
}
|
||||
|
||||
QSize Vmr9VideoWindowControl::nativeSize() const
|
||||
{
|
||||
QSize size;
|
||||
|
||||
if (IVMRWindowlessControl9 *control = com_cast<IVMRWindowlessControl9>(
|
||||
m_filter, IID_IVMRWindowlessControl9)) {
|
||||
LONG width;
|
||||
LONG height;
|
||||
|
||||
if (control->GetNativeVideoSize(&width, &height, 0, 0) == S_OK)
|
||||
size = QSize(width, height);
|
||||
control->Release();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
Qt::AspectRatioMode Vmr9VideoWindowControl::aspectRatioMode() const
|
||||
{
|
||||
return m_aspectRatioMode;
|
||||
}
|
||||
|
||||
void Vmr9VideoWindowControl::setAspectRatioMode(Qt::AspectRatioMode mode)
|
||||
{
|
||||
m_aspectRatioMode = mode;
|
||||
|
||||
if (IVMRWindowlessControl9 *control = com_cast<IVMRWindowlessControl9>(
|
||||
m_filter, IID_IVMRWindowlessControl9)) {
|
||||
switch (mode) {
|
||||
case Qt::IgnoreAspectRatio:
|
||||
control->SetAspectRatioMode(VMR9ARMode_None);
|
||||
break;
|
||||
case Qt::KeepAspectRatio:
|
||||
control->SetAspectRatioMode(VMR9ARMode_LetterBox);
|
||||
break;
|
||||
case Qt::KeepAspectRatioByExpanding:
|
||||
control->SetAspectRatioMode(VMR9ARMode_LetterBox);
|
||||
setDisplayRect(m_displayRect);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
control->Release();
|
||||
}
|
||||
}
|
||||
|
||||
int Vmr9VideoWindowControl::brightness() const
|
||||
{
|
||||
return m_brightness;
|
||||
}
|
||||
|
||||
void Vmr9VideoWindowControl::setBrightness(int brightness)
|
||||
{
|
||||
m_brightness = brightness;
|
||||
|
||||
m_dirtyValues |= ProcAmpControl9_Brightness;
|
||||
|
||||
setProcAmpValues();
|
||||
|
||||
emit brightnessChanged(brightness);
|
||||
}
|
||||
|
||||
int Vmr9VideoWindowControl::contrast() const
|
||||
{
|
||||
return m_contrast;
|
||||
}
|
||||
|
||||
void Vmr9VideoWindowControl::setContrast(int contrast)
|
||||
{
|
||||
m_contrast = contrast;
|
||||
|
||||
m_dirtyValues |= ProcAmpControl9_Contrast;
|
||||
|
||||
setProcAmpValues();
|
||||
|
||||
emit contrastChanged(contrast);
|
||||
}
|
||||
|
||||
int Vmr9VideoWindowControl::hue() const
|
||||
{
|
||||
return m_hue;
|
||||
}
|
||||
|
||||
void Vmr9VideoWindowControl::setHue(int hue)
|
||||
{
|
||||
m_hue = hue;
|
||||
|
||||
m_dirtyValues |= ProcAmpControl9_Hue;
|
||||
|
||||
setProcAmpValues();
|
||||
|
||||
emit hueChanged(hue);
|
||||
}
|
||||
|
||||
int Vmr9VideoWindowControl::saturation() const
|
||||
{
|
||||
return m_saturation;
|
||||
}
|
||||
|
||||
void Vmr9VideoWindowControl::setSaturation(int saturation)
|
||||
{
|
||||
m_saturation = saturation;
|
||||
|
||||
m_dirtyValues |= ProcAmpControl9_Saturation;
|
||||
|
||||
setProcAmpValues();
|
||||
|
||||
emit saturationChanged(saturation);
|
||||
}
|
||||
|
||||
void Vmr9VideoWindowControl::setProcAmpValues()
|
||||
{
|
||||
if (IVMRMixerControl9 *control = com_cast<IVMRMixerControl9>(m_filter, IID_IVMRMixerControl9)) {
|
||||
VMR9ProcAmpControl procAmp;
|
||||
procAmp.dwSize = sizeof(VMR9ProcAmpControl);
|
||||
procAmp.dwFlags = m_dirtyValues;
|
||||
|
||||
if (m_dirtyValues & ProcAmpControl9_Brightness) {
|
||||
procAmp.Brightness = scaleProcAmpValue(
|
||||
control, ProcAmpControl9_Brightness, m_brightness);
|
||||
}
|
||||
if (m_dirtyValues & ProcAmpControl9_Contrast) {
|
||||
procAmp.Contrast = scaleProcAmpValue(
|
||||
control, ProcAmpControl9_Contrast, m_contrast);
|
||||
}
|
||||
if (m_dirtyValues & ProcAmpControl9_Hue) {
|
||||
procAmp.Hue = scaleProcAmpValue(
|
||||
control, ProcAmpControl9_Hue, m_hue);
|
||||
}
|
||||
if (m_dirtyValues & ProcAmpControl9_Saturation) {
|
||||
procAmp.Saturation = scaleProcAmpValue(
|
||||
control, ProcAmpControl9_Saturation, m_saturation);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(control->SetProcAmpControl(0, &procAmp))) {
|
||||
m_dirtyValues = 0;
|
||||
}
|
||||
|
||||
control->Release();
|
||||
}
|
||||
}
|
||||
|
||||
float Vmr9VideoWindowControl::scaleProcAmpValue(
|
||||
IVMRMixerControl9 *control, VMR9ProcAmpControlFlags property, int value) const
|
||||
{
|
||||
float scaledValue = 0.0;
|
||||
|
||||
VMR9ProcAmpControlRange range;
|
||||
range.dwSize = sizeof(VMR9ProcAmpControlRange);
|
||||
range.dwProperty = property;
|
||||
|
||||
if (SUCCEEDED(control->GetProcAmpControlRange(0, &range))) {
|
||||
scaledValue = range.DefaultValue;
|
||||
if (value > 0)
|
||||
scaledValue += float(value) * (range.MaxValue - range.DefaultValue) / 100;
|
||||
else if (value < 0)
|
||||
scaledValue -= float(value) * (range.MinValue - range.DefaultValue) / 100;
|
||||
}
|
||||
|
||||
return scaledValue;
|
||||
}
|
||||
108
src/plugins/directshow/player/vmr9videowindowcontrol.h
Normal file
108
src/plugins/directshow/player/vmr9videowindowcontrol.h
Normal file
@@ -0,0 +1,108 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 VMR9VIDEOWINDOWCONTROL_H
|
||||
#define VMR9VIDEOWINDOWCONTROL_H
|
||||
|
||||
#include "qvideowindowcontrol.h"
|
||||
|
||||
#include <dshow.h>
|
||||
#include <d3d9.h>
|
||||
#include <vmr9.h>
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class Vmr9VideoWindowControl : public QVideoWindowControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Vmr9VideoWindowControl(QObject *parent = 0);
|
||||
~Vmr9VideoWindowControl();
|
||||
|
||||
IBaseFilter *filter() const { return m_filter; }
|
||||
|
||||
WId winId() const;
|
||||
void setWinId(WId id);
|
||||
|
||||
QRect displayRect() const;
|
||||
void setDisplayRect(const QRect &rect);
|
||||
|
||||
bool isFullScreen() const;
|
||||
void setFullScreen(bool fullScreen);
|
||||
|
||||
void repaint();
|
||||
|
||||
QSize nativeSize() const;
|
||||
|
||||
Qt::AspectRatioMode aspectRatioMode() const;
|
||||
void setAspectRatioMode(Qt::AspectRatioMode mode);
|
||||
|
||||
int brightness() const;
|
||||
void setBrightness(int brightness);
|
||||
|
||||
int contrast() const;
|
||||
void setContrast(int contrast);
|
||||
|
||||
int hue() const;
|
||||
void setHue(int hue);
|
||||
|
||||
int saturation() const;
|
||||
void setSaturation(int saturation);
|
||||
|
||||
private:
|
||||
void setProcAmpValues();
|
||||
float scaleProcAmpValue(
|
||||
IVMRMixerControl9 *control, VMR9ProcAmpControlFlags property, int value) const;
|
||||
|
||||
IBaseFilter *m_filter;
|
||||
WId m_windowId;
|
||||
COLORREF m_windowColor;
|
||||
DWORD m_dirtyValues;
|
||||
Qt::AspectRatioMode m_aspectRatioMode;
|
||||
QRect m_displayRect;
|
||||
int m_brightness;
|
||||
int m_contrast;
|
||||
int m_hue;
|
||||
int m_saturation;
|
||||
bool m_fullScreen;
|
||||
};
|
||||
|
||||
#endif
|
||||
50
src/plugins/gstreamer/camerabin/camerabin.pri
Normal file
50
src/plugins/gstreamer/camerabin/camerabin.pri
Normal file
@@ -0,0 +1,50 @@
|
||||
INCLUDEPATH += $$PWD \
|
||||
$${SOURCE_DIR}/src/multimedia
|
||||
|
||||
INCLUDEPATH += camerabin
|
||||
|
||||
DEFINES += QMEDIA_GSTREAMER_CAMERABIN
|
||||
|
||||
LIBS += -lgstphotography-0.10
|
||||
|
||||
DEFINES += GST_USE_UNSTABLE_API #prevents warnings because of unstable photography API
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/camerabinservice.h \
|
||||
$$PWD/camerabinsession.h \
|
||||
$$PWD/camerabincontrol.h \
|
||||
$$PWD/camerabinaudioencoder.h \
|
||||
$$PWD/camerabinfocus.h \
|
||||
$$PWD/camerabinimageencoder.h \
|
||||
$$PWD/camerabinlocks.h \
|
||||
$$PWD/camerabinrecorder.h \
|
||||
$$PWD/camerabincontainer.h \
|
||||
$$PWD/camerabinexposure.h \
|
||||
$$PWD/camerabinflash.h \
|
||||
$$PWD/camerabinimagecapture.h \
|
||||
$$PWD/camerabinimageprocessing.h \
|
||||
$$PWD/camerabinmetadata.h \
|
||||
$$PWD/camerabinvideoencoder.h \
|
||||
$$PWD/camerabinresourcepolicy.h \
|
||||
$$PWD/camerabincapturedestination.h \
|
||||
$$PWD/camerabincapturebufferformat.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/camerabinservice.cpp \
|
||||
$$PWD/camerabinsession.cpp \
|
||||
$$PWD/camerabincontrol.cpp \
|
||||
$$PWD/camerabinaudioencoder.cpp \
|
||||
$$PWD/camerabincontainer.cpp \
|
||||
$$PWD/camerabinexposure.cpp \
|
||||
$$PWD/camerabinflash.cpp \
|
||||
$$PWD/camerabinfocus.cpp \
|
||||
$$PWD/camerabinimagecapture.cpp \
|
||||
$$PWD/camerabinimageencoder.cpp \
|
||||
$$PWD/camerabinimageprocessing.cpp \
|
||||
$$PWD/camerabinlocks.cpp \
|
||||
$$PWD/camerabinmetadata.cpp \
|
||||
$$PWD/camerabinrecorder.cpp \
|
||||
$$PWD/camerabinvideoencoder.cpp \
|
||||
$$PWD/camerabinresourcepolicy.cpp \
|
||||
$$PWD/camerabincapturedestination.cpp \
|
||||
$$PWD/camerabincapturebufferformat.cpp
|
||||
293
src/plugins/gstreamer/camerabin/camerabinaudioencoder.cpp
Normal file
293
src/plugins/gstreamer/camerabin/camerabinaudioencoder.cpp
Normal file
@@ -0,0 +1,293 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "camerabinaudioencoder.h"
|
||||
#include "camerabincontainer.h"
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
|
||||
CameraBinAudioEncoder::CameraBinAudioEncoder(QObject *parent)
|
||||
:QAudioEncoderControl(parent)
|
||||
{
|
||||
QList<QByteArray> codecCandidates;
|
||||
|
||||
#if defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6)
|
||||
codecCandidates << "audio/AAC" << "audio/PCM" << "audio/AMR" << "audio/AMR-WB" << "audio/speex"
|
||||
<< "audio/ADPCM" << "audio/iLBC" << "audio/vorbis" << "audio/mpeg" << "audio/FLAC";
|
||||
|
||||
m_elementNames["audio/AAC"] = "nokiaaacenc";
|
||||
m_elementNames["audio/speex"] = "speexenc";
|
||||
m_elementNames["audio/PCM"] = "audioresample";
|
||||
m_elementNames["audio/AMR"] = "nokiaamrnbenc";
|
||||
m_elementNames["audio/AMR-WB"] = "nokiaamrwbenc";
|
||||
m_elementNames["audio/ADPCM"] = "nokiaadpcmenc";
|
||||
m_elementNames["audio/iLBC"] = "nokiailbcenc";
|
||||
m_elementNames["audio/vorbis"] = "vorbisenc";
|
||||
m_elementNames["audio/FLAC"] = "flacenc";
|
||||
m_elementNames["audio/mpeg"] = "ffenc_mp2";
|
||||
#else
|
||||
codecCandidates << "audio/mpeg" << "audio/vorbis" << "audio/speex" << "audio/GSM"
|
||||
<< "audio/PCM" << "audio/AMR" << "audio/AMR-WB";
|
||||
|
||||
m_elementNames["audio/mpeg"] = "lamemp3enc";
|
||||
m_elementNames["audio/vorbis"] = "vorbisenc";
|
||||
m_elementNames["audio/speex"] = "speexenc";
|
||||
m_elementNames["audio/GSM"] = "gsmenc";
|
||||
m_elementNames["audio/PCM"] = "audioresample";
|
||||
m_elementNames["audio/AMR"] = "amrnbenc";
|
||||
m_elementNames["audio/AMR-WB"] = "amrwbenc";
|
||||
|
||||
m_codecOptions["audio/vorbis"] = QStringList() << "min-bitrate" << "max-bitrate";
|
||||
m_codecOptions["audio/mpeg"] = QStringList() << "mode";
|
||||
m_codecOptions["audio/speex"] = QStringList() << "mode" << "vbr" << "vad" << "dtx";
|
||||
m_codecOptions["audio/GSM"] = QStringList();
|
||||
m_codecOptions["audio/PCM"] = QStringList();
|
||||
m_codecOptions["audio/AMR"] = QStringList();
|
||||
m_codecOptions["audio/AMR-WB"] = QStringList();
|
||||
#endif
|
||||
|
||||
foreach( const QByteArray& codecName, codecCandidates ) {
|
||||
QByteArray elementName = m_elementNames[codecName];
|
||||
GstElementFactory *factory = gst_element_factory_find(elementName.constData());
|
||||
|
||||
if (factory) {
|
||||
m_codecs.append(codecName);
|
||||
const gchar *descr = gst_element_factory_get_description(factory);
|
||||
|
||||
if (codecName == QByteArray("audio/PCM"))
|
||||
m_codecDescriptions.insert(codecName, tr("Raw PCM audio"));
|
||||
else
|
||||
m_codecDescriptions.insert(codecName, QString::fromUtf8(descr));
|
||||
|
||||
m_streamTypes.insert(codecName,
|
||||
CameraBinContainer::supportedStreamTypes(factory, GST_PAD_SRC));
|
||||
|
||||
gst_object_unref(GST_OBJECT(factory));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CameraBinAudioEncoder::~CameraBinAudioEncoder()
|
||||
{
|
||||
}
|
||||
|
||||
QStringList CameraBinAudioEncoder::supportedAudioCodecs() const
|
||||
{
|
||||
return m_codecs;
|
||||
}
|
||||
|
||||
QString CameraBinAudioEncoder::codecDescription(const QString &codecName) const
|
||||
{
|
||||
return m_codecDescriptions.value(codecName);
|
||||
}
|
||||
|
||||
QStringList CameraBinAudioEncoder::supportedEncodingOptions(const QString &codec) const
|
||||
{
|
||||
return m_codecOptions.value(codec);
|
||||
}
|
||||
|
||||
QVariant CameraBinAudioEncoder::encodingOption(
|
||||
const QString &codec, const QString &name) const
|
||||
{
|
||||
return m_options[codec].value(name);
|
||||
}
|
||||
|
||||
void CameraBinAudioEncoder::setEncodingOption(
|
||||
const QString &codec, const QString &name, const QVariant &value)
|
||||
{
|
||||
m_options[codec][name] = value;
|
||||
}
|
||||
|
||||
QList<int> CameraBinAudioEncoder::supportedSampleRates(const QAudioEncoderSettings &, bool *) const
|
||||
{
|
||||
//TODO check element caps to find actual values
|
||||
|
||||
return QList<int>();
|
||||
}
|
||||
|
||||
QAudioEncoderSettings CameraBinAudioEncoder::audioSettings() const
|
||||
{
|
||||
return m_audioSettings;
|
||||
}
|
||||
|
||||
void CameraBinAudioEncoder::setAudioSettings(const QAudioEncoderSettings &settings)
|
||||
{
|
||||
m_userSettings = settings;
|
||||
m_audioSettings = settings;
|
||||
emit settingsChanged();
|
||||
}
|
||||
|
||||
void CameraBinAudioEncoder::setActualAudioSettings(const QAudioEncoderSettings &settings)
|
||||
{
|
||||
m_audioSettings = settings;
|
||||
}
|
||||
|
||||
void CameraBinAudioEncoder::resetActualSettings()
|
||||
{
|
||||
m_audioSettings = m_userSettings;
|
||||
}
|
||||
|
||||
GstElement *CameraBinAudioEncoder::createEncoder()
|
||||
{
|
||||
QString codec = m_audioSettings.codec();
|
||||
QByteArray encoderElementName = m_elementNames.value(codec);
|
||||
GstElement *encoderElement = gst_element_factory_make(encoderElementName.constData(), NULL);
|
||||
if (!encoderElement)
|
||||
return 0;
|
||||
|
||||
GstBin * encoderBin = GST_BIN(gst_bin_new("audio-encoder-bin"));
|
||||
GstElement *capsFilter = gst_element_factory_make("capsfilter", NULL);
|
||||
|
||||
gst_bin_add(encoderBin, capsFilter);
|
||||
gst_bin_add(encoderBin, encoderElement);
|
||||
gst_element_link(capsFilter, encoderElement);
|
||||
|
||||
// add ghostpads
|
||||
GstPad *pad = gst_element_get_static_pad(capsFilter, "sink");
|
||||
gst_element_add_pad(GST_ELEMENT(encoderBin), gst_ghost_pad_new("sink", pad));
|
||||
gst_object_unref(GST_OBJECT(pad));
|
||||
|
||||
pad = gst_element_get_static_pad(encoderElement, "src");
|
||||
gst_element_add_pad(GST_ELEMENT(encoderBin), gst_ghost_pad_new("src", pad));
|
||||
gst_object_unref(GST_OBJECT(pad));
|
||||
|
||||
if (m_audioSettings.sampleRate() > 0 || m_audioSettings.channelCount() > 0) {
|
||||
GstCaps *caps = gst_caps_new_empty();
|
||||
GstStructure *structure = gst_structure_new("audio/x-raw-int", NULL);
|
||||
|
||||
if (m_audioSettings.sampleRate() > 0)
|
||||
gst_structure_set(structure, "rate", G_TYPE_INT, m_audioSettings.sampleRate(), NULL );
|
||||
|
||||
if (m_audioSettings.channelCount() > 0)
|
||||
gst_structure_set(structure, "channels", G_TYPE_INT, m_audioSettings.channelCount(), NULL );
|
||||
|
||||
gst_caps_append_structure(caps,structure);
|
||||
|
||||
g_object_set(G_OBJECT(capsFilter), "caps", caps, NULL);
|
||||
}
|
||||
|
||||
if (encoderElement) {
|
||||
if (m_audioSettings.encodingMode() == QtMultimediaKit::ConstantQualityEncoding) {
|
||||
QtMultimediaKit::EncodingQuality qualityValue = m_audioSettings.quality();
|
||||
|
||||
if (encoderElementName == "lamemp3enc") {
|
||||
g_object_set(G_OBJECT(encoderElement), "target", 0, NULL); //constant quality mode
|
||||
qreal quality[] = {
|
||||
10.0, //VeryLow
|
||||
6.0, //Low
|
||||
4.0, //Normal
|
||||
2.0, //High
|
||||
0.0 //VeryHigh
|
||||
};
|
||||
g_object_set(G_OBJECT(encoderElement), "quality", quality[qualityValue], NULL);
|
||||
} else if (encoderElementName == "ffenc_mp2") {
|
||||
int quality[] = {
|
||||
8000, //VeryLow
|
||||
64000, //Low
|
||||
128000, //Normal
|
||||
192000, //High
|
||||
320000 //VeryHigh
|
||||
};
|
||||
g_object_set(G_OBJECT(encoderElement), "bitrate", quality[qualityValue], NULL);
|
||||
} else if (codec == QLatin1String("audio/speex")) {
|
||||
//0-10 range with default 8
|
||||
double qualityTable[] = {
|
||||
2, //VeryLow
|
||||
5, //Low
|
||||
8, //Normal
|
||||
9, //High
|
||||
10 //VeryHigh
|
||||
};
|
||||
g_object_set(G_OBJECT(encoderElement), "quality", qualityTable[qualityValue], NULL);
|
||||
} else if (codec.startsWith("audio/AMR")) {
|
||||
int band[] = {
|
||||
0, //VeryLow
|
||||
2, //Low
|
||||
4, //Normal
|
||||
6, //High
|
||||
7 //VeryHigh
|
||||
};
|
||||
|
||||
g_object_set(G_OBJECT(encoderElement), "band-mode", band[qualityValue], NULL);
|
||||
}
|
||||
} else {
|
||||
int bitrate = m_audioSettings.bitRate();
|
||||
if (bitrate > 0) {
|
||||
g_object_set(G_OBJECT(encoderElement), "bitrate", bitrate, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
QMap<QString, QVariant> options = m_options.value(codec);
|
||||
QMapIterator<QString,QVariant> it(options);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
QString option = it.key();
|
||||
QVariant value = it.value();
|
||||
|
||||
switch (value.type()) {
|
||||
case QVariant::Int:
|
||||
g_object_set(G_OBJECT(encoderElement), option.toAscii(), value.toInt(), NULL);
|
||||
break;
|
||||
case QVariant::Bool:
|
||||
g_object_set(G_OBJECT(encoderElement), option.toAscii(), value.toBool(), NULL);
|
||||
break;
|
||||
case QVariant::Double:
|
||||
g_object_set(G_OBJECT(encoderElement), option.toAscii(), value.toDouble(), NULL);
|
||||
break;
|
||||
case QVariant::String:
|
||||
g_object_set(G_OBJECT(encoderElement), option.toAscii(), value.toString().toUtf8().constData(), NULL);
|
||||
break;
|
||||
default:
|
||||
qWarning() << "unsupported option type:" << option << value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return GST_ELEMENT(encoderBin);
|
||||
|
||||
}
|
||||
|
||||
|
||||
QSet<QString> CameraBinAudioEncoder::supportedStreamTypes(const QString &codecName) const
|
||||
{
|
||||
return m_streamTypes.value(codecName);
|
||||
}
|
||||
105
src/plugins/gstreamer/camerabin/camerabinaudioencoder.h
Normal file
105
src/plugins/gstreamer/camerabin/camerabinaudioencoder.h
Normal file
@@ -0,0 +1,105 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 CAMERABINAUDIOENCODE_H
|
||||
#define CAMERABINAUDIOENCODE_H
|
||||
|
||||
#include <qaudioencodercontrol.h>
|
||||
class CameraBinSession;
|
||||
|
||||
#include <QtCore/qstringlist.h>
|
||||
#include <QtCore/qmap.h>
|
||||
#include <QtCore/qset.h>
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include <qaudioformat.h>
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class CameraBinAudioEncoder : public QAudioEncoderControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CameraBinAudioEncoder(QObject *parent);
|
||||
virtual ~CameraBinAudioEncoder();
|
||||
|
||||
QStringList supportedAudioCodecs() const;
|
||||
QString codecDescription(const QString &codecName) const;
|
||||
|
||||
QStringList supportedEncodingOptions(const QString &codec) const;
|
||||
QVariant encodingOption(const QString &codec, const QString &name) const;
|
||||
void setEncodingOption(const QString &codec, const QString &name, const QVariant &value);
|
||||
|
||||
QList<int> supportedSampleRates(const QAudioEncoderSettings &settings = QAudioEncoderSettings(),
|
||||
bool *isContinuous = 0) const;
|
||||
QList<int> supportedChannelCounts(const QAudioEncoderSettings &settings = QAudioEncoderSettings()) const;
|
||||
QList<int> supportedSampleSizes(const QAudioEncoderSettings &settings = QAudioEncoderSettings()) const;
|
||||
|
||||
QAudioEncoderSettings audioSettings() const;
|
||||
void setAudioSettings(const QAudioEncoderSettings&);
|
||||
|
||||
|
||||
GstElement *createEncoder();
|
||||
|
||||
QSet<QString> supportedStreamTypes(const QString &codecName) const;
|
||||
|
||||
void setActualAudioSettings(const QAudioEncoderSettings&);
|
||||
void resetActualSettings();
|
||||
|
||||
Q_SIGNALS:
|
||||
void settingsChanged();
|
||||
|
||||
private:
|
||||
QStringList m_codecs;
|
||||
QMap<QString,QByteArray> m_elementNames;
|
||||
QMap<QString,QString> m_codecDescriptions;
|
||||
QMap<QString,QStringList> m_codecOptions;
|
||||
|
||||
QMap<QString, QMap<QString, QVariant> > m_options;
|
||||
|
||||
QMap<QString, QSet<QString> > m_streamTypes;
|
||||
|
||||
QAudioEncoderSettings m_audioSettings;
|
||||
QAudioEncoderSettings m_userSettings;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,78 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 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 "camerabincapturebufferformat.h"
|
||||
#include "camerabinsession.h"
|
||||
|
||||
CameraBinCaptureBufferFormat::CameraBinCaptureBufferFormat(CameraBinSession *session)
|
||||
:QCameraCaptureBufferFormatControl(session)
|
||||
, m_session(session)
|
||||
, m_format(QVideoFrame::Format_Jpeg)
|
||||
{
|
||||
}
|
||||
|
||||
CameraBinCaptureBufferFormat::~CameraBinCaptureBufferFormat()
|
||||
{
|
||||
}
|
||||
|
||||
QList<QVideoFrame::PixelFormat> CameraBinCaptureBufferFormat::supportedBufferFormats() const
|
||||
{
|
||||
//the exact YUV format is unknown with camerabin until the first capture is requested
|
||||
return QList<QVideoFrame::PixelFormat>()
|
||||
<< QVideoFrame::Format_Jpeg
|
||||
#ifdef Q_WS_MAEMO_6
|
||||
<< QVideoFrame::Format_UYVY
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
QVideoFrame::PixelFormat CameraBinCaptureBufferFormat::bufferFormat() const
|
||||
{
|
||||
return m_format;
|
||||
}
|
||||
|
||||
void CameraBinCaptureBufferFormat::setBufferFormat(QVideoFrame::PixelFormat format)
|
||||
{
|
||||
if (m_format != format) {
|
||||
m_format = format;
|
||||
emit bufferFormatChanged(format);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 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 CAMERABINCAPTUREBUFFERFORMAT_H
|
||||
#define CAMERABINCAPTUREBUFFERFORMAT_H
|
||||
|
||||
#include <qcamera.h>
|
||||
#include <qcameracapturebufferformatcontrol.h>
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <glib.h>
|
||||
|
||||
class CameraBinSession;
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class Q_MULTIMEDIA_EXPORT CameraBinCaptureBufferFormat : public QCameraCaptureBufferFormatControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CameraBinCaptureBufferFormat(CameraBinSession *session);
|
||||
virtual ~CameraBinCaptureBufferFormat();
|
||||
|
||||
QList<QVideoFrame::PixelFormat> supportedBufferFormats() const;
|
||||
|
||||
QVideoFrame::PixelFormat bufferFormat() const;
|
||||
void setBufferFormat(QVideoFrame::PixelFormat format);
|
||||
|
||||
private:
|
||||
CameraBinSession *m_session;
|
||||
QVideoFrame::PixelFormat m_format;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,74 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 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 "camerabincapturedestination.h"
|
||||
#include "camerabinsession.h"
|
||||
|
||||
CameraBinCaptureDestination::CameraBinCaptureDestination(CameraBinSession *session)
|
||||
:QCameraCaptureDestinationControl(session)
|
||||
, m_session(session)
|
||||
, m_destination(QCameraImageCapture::CaptureToFile)
|
||||
{
|
||||
}
|
||||
|
||||
CameraBinCaptureDestination::~CameraBinCaptureDestination()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool CameraBinCaptureDestination::isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const
|
||||
{
|
||||
//capture to buffer, file and both are supported.
|
||||
return destination & (QCameraImageCapture::CaptureToFile | QCameraImageCapture::CaptureToBuffer);
|
||||
}
|
||||
|
||||
QCameraImageCapture::CaptureDestinations CameraBinCaptureDestination::captureDestination() const
|
||||
{
|
||||
return m_destination;
|
||||
}
|
||||
|
||||
void CameraBinCaptureDestination::setCaptureDestination(QCameraImageCapture::CaptureDestinations destination)
|
||||
{
|
||||
if (m_destination != destination) {
|
||||
m_destination = destination;
|
||||
emit captureDestinationChanged(m_destination);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 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 CAMERABINCAPTUREDESTINATION_H
|
||||
#define CAMERABINCAPTUREDESTINATION_H
|
||||
|
||||
#include <qcameraimagecapture.h>
|
||||
#include <qcameracapturedestinationcontrol.h>
|
||||
|
||||
|
||||
class CameraBinSession;
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class Q_MULTIMEDIA_EXPORT CameraBinCaptureDestination : public QCameraCaptureDestinationControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CameraBinCaptureDestination(CameraBinSession *session);
|
||||
virtual ~CameraBinCaptureDestination();
|
||||
|
||||
bool isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const;
|
||||
QCameraImageCapture::CaptureDestinations captureDestination() const;
|
||||
void setCaptureDestination(QCameraImageCapture::CaptureDestinations destination);
|
||||
|
||||
private:
|
||||
CameraBinSession *m_session;
|
||||
QCameraImageCapture::CaptureDestinations m_destination;
|
||||
};
|
||||
|
||||
#endif // CAMERABINFLASHCONTROL_H
|
||||
122
src/plugins/gstreamer/camerabin/camerabincontainer.cpp
Normal file
122
src/plugins/gstreamer/camerabin/camerabincontainer.cpp
Normal file
@@ -0,0 +1,122 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "camerabincontainer.h"
|
||||
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
|
||||
CameraBinContainer::CameraBinContainer(QObject *parent)
|
||||
:QMediaContainerControl(parent)
|
||||
{
|
||||
QList<QByteArray> formatCandidates;
|
||||
formatCandidates << "mp4" << "ogg" << "wav" << "amr" << "mkv"
|
||||
<< "avi" << "3gp" << "3gp2" << "webm" << "mjpeg" << "asf" << "mov";
|
||||
|
||||
QMap<QString,QByteArray> elementNames;
|
||||
|
||||
elementNames.insertMulti("mp4", "ffmux_mp4");
|
||||
elementNames.insertMulti("mp4", "hantromp4mux");
|
||||
elementNames.insertMulti("mp4", "mp4mux");
|
||||
elementNames.insert("ogg", "oggmux");
|
||||
elementNames["wav"] = "wavenc";
|
||||
elementNames["amr"] = "ffmux_amr";
|
||||
elementNames["mkv"] = "matroskamux";
|
||||
elementNames["avi"] = "avimux";
|
||||
elementNames["3gp"] = "ffmux_3gp";
|
||||
elementNames["3gp2"] = "ffmux_3g2";
|
||||
elementNames["webm"] = "webmmux";
|
||||
elementNames["mjpeg"] = "ffmux_mjpeg";
|
||||
elementNames["asf"] = "ffmux_asf";
|
||||
elementNames["mov"] = "qtmux";
|
||||
|
||||
QSet<QString> allTypes;
|
||||
|
||||
foreach(const QByteArray &formatName, formatCandidates) {
|
||||
foreach(const QByteArray &elementName, elementNames.values(formatName)) {
|
||||
GstElementFactory *factory = gst_element_factory_find(elementName.constData());
|
||||
if (factory) {
|
||||
m_supportedContainers.append(formatName);
|
||||
const gchar *descr = gst_element_factory_get_description(factory);
|
||||
m_containerDescriptions.insert(formatName, QString::fromUtf8(descr));
|
||||
|
||||
|
||||
if (formatName == QByteArray("raw")) {
|
||||
m_streamTypes.insert(formatName, allTypes);
|
||||
} else {
|
||||
QSet<QString> types = supportedStreamTypes(factory, GST_PAD_SINK);
|
||||
m_streamTypes.insert(formatName, types);
|
||||
allTypes.unite(types);
|
||||
}
|
||||
|
||||
gst_object_unref(GST_OBJECT(factory));
|
||||
|
||||
m_elementNames.insert(formatName, elementName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QSet<QString> CameraBinContainer::supportedStreamTypes(GstElementFactory *factory, GstPadDirection direction)
|
||||
{
|
||||
QSet<QString> types;
|
||||
const GList *pads = gst_element_factory_get_static_pad_templates(factory);
|
||||
for (const GList *pad = pads; pad; pad = g_list_next(pad)) {
|
||||
GstStaticPadTemplate *templ = (GstStaticPadTemplate*)pad->data;
|
||||
if (templ->direction == direction) {
|
||||
GstCaps *caps = gst_static_caps_get(&templ->static_caps);
|
||||
for (uint i=0; i<gst_caps_get_size(caps); i++) {
|
||||
GstStructure *structure = gst_caps_get_structure(caps, i);
|
||||
types.insert( QString::fromUtf8(gst_structure_get_name(structure)) );
|
||||
}
|
||||
gst_caps_unref(caps);
|
||||
}
|
||||
}
|
||||
|
||||
return types;
|
||||
}
|
||||
|
||||
|
||||
QSet<QString> CameraBinContainer::supportedStreamTypes(const QString &container) const
|
||||
{
|
||||
return m_streamTypes.value(container);
|
||||
}
|
||||
103
src/plugins/gstreamer/camerabin/camerabincontainer.h
Normal file
103
src/plugins/gstreamer/camerabin/camerabincontainer.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 CAMERABINMEDIACONTAINERCONTROL_H
|
||||
#define CAMERABINMEDIACONTAINERCONTROL_H
|
||||
|
||||
#include <qmediacontainercontrol.h>
|
||||
#include <QtCore/qstringlist.h>
|
||||
#include <QtCore/qset.h>
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class CameraBinContainer : public QMediaContainerControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CameraBinContainer(QObject *parent);
|
||||
virtual ~CameraBinContainer() {}
|
||||
|
||||
virtual QStringList supportedContainers() const { return m_supportedContainers; }
|
||||
virtual QString containerMimeType() const { return m_format; }
|
||||
virtual void setContainerMimeType(const QString &formatMimeType)
|
||||
{
|
||||
m_format = formatMimeType;
|
||||
|
||||
if (m_userFormat != formatMimeType) {
|
||||
m_userFormat = formatMimeType;
|
||||
emit settingsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void setActualContainer(const QString &formatMimeType)
|
||||
{
|
||||
m_format = formatMimeType;
|
||||
}
|
||||
|
||||
void resetActualContainer()
|
||||
{
|
||||
m_format = m_userFormat;
|
||||
}
|
||||
|
||||
virtual QString containerDescription(const QString &formatMimeType) const { return m_containerDescriptions.value(formatMimeType); }
|
||||
|
||||
QByteArray formatElementName() const { return m_elementNames.value(containerMimeType()); }
|
||||
|
||||
QSet<QString> supportedStreamTypes(const QString &container) const;
|
||||
|
||||
static QSet<QString> supportedStreamTypes(GstElementFactory *factory, GstPadDirection direction);
|
||||
|
||||
Q_SIGNALS:
|
||||
void settingsChanged();
|
||||
|
||||
private:
|
||||
QString m_format; // backend selected format, using m_userFormat
|
||||
QString m_userFormat;
|
||||
QStringList m_supportedContainers;
|
||||
QMap<QString,QByteArray> m_elementNames;
|
||||
QMap<QString, QString> m_containerDescriptions;
|
||||
QMap<QString, QSet<QString> > m_streamTypes;
|
||||
};
|
||||
|
||||
#endif // CAMERABINMEDIACONTAINERCONTROL_H
|
||||
356
src/plugins/gstreamer/camerabin/camerabincontrol.cpp
Normal file
356
src/plugins/gstreamer/camerabin/camerabincontrol.cpp
Normal file
@@ -0,0 +1,356 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2009 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 "camerabincontrol.h"
|
||||
#include "camerabincontainer.h"
|
||||
#include "camerabinaudioencoder.h"
|
||||
#include "camerabinvideoencoder.h"
|
||||
#include "camerabinimageencoder.h"
|
||||
#include "camerabinresourcepolicy.h"
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtCore/qfile.h>
|
||||
#include <QtCore/qmetaobject.h>
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/poll.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/mman.h>
|
||||
#include <linux/videodev2.h>
|
||||
|
||||
//#define CAMEABIN_DEBUG 1
|
||||
#define ENUM_NAME(c,e,v) (c::staticMetaObject.enumerator(c::staticMetaObject.indexOfEnumerator(e)).valueToKey((v)))
|
||||
|
||||
CameraBinControl::CameraBinControl(CameraBinSession *session)
|
||||
:QCameraControl(session),
|
||||
m_session(session),
|
||||
m_state(QCamera::UnloadedState),
|
||||
m_status(QCamera::UnloadedStatus),
|
||||
m_reloadPending(false)
|
||||
{
|
||||
connect(m_session, SIGNAL(stateChanged(QCamera::State)),
|
||||
this, SLOT(updateStatus()));
|
||||
|
||||
connect(m_session->audioEncodeControl(), SIGNAL(settingsChanged()),
|
||||
SLOT(reloadLater()));
|
||||
connect(m_session->videoEncodeControl(), SIGNAL(settingsChanged()),
|
||||
SLOT(reloadLater()));
|
||||
connect(m_session->mediaContainerControl(), SIGNAL(settingsChanged()),
|
||||
SLOT(reloadLater()));
|
||||
connect(m_session->imageEncodeControl(), SIGNAL(settingsChanged()),
|
||||
SLOT(reloadLater()));
|
||||
connect(m_session, SIGNAL(viewfinderChanged()),
|
||||
SLOT(reloadLater()));
|
||||
connect(m_session, SIGNAL(readyChanged(bool)),
|
||||
SLOT(reloadLater()));
|
||||
connect(m_session, SIGNAL(error(int,QString)),
|
||||
SLOT(handleCameraError(int,QString)));
|
||||
|
||||
m_resourcePolicy = new CamerabinResourcePolicy(this);
|
||||
connect(m_resourcePolicy, SIGNAL(resourcesGranted()),
|
||||
SLOT(handleResourcesGranted()));
|
||||
connect(m_resourcePolicy, SIGNAL(resourcesDenied()),
|
||||
SLOT(handleResourcesLost()));
|
||||
connect(m_resourcePolicy, SIGNAL(resourcesLost()),
|
||||
SLOT(handleResourcesLost()));
|
||||
|
||||
connect(m_session, SIGNAL(busyChanged(bool)),
|
||||
SLOT(handleBusyChanged(bool)));
|
||||
}
|
||||
|
||||
CameraBinControl::~CameraBinControl()
|
||||
{
|
||||
}
|
||||
|
||||
QCamera::CaptureMode CameraBinControl::captureMode() const
|
||||
{
|
||||
return m_session->captureMode();
|
||||
}
|
||||
|
||||
void CameraBinControl::setCaptureMode(QCamera::CaptureMode mode)
|
||||
{
|
||||
if (m_session->captureMode() != mode) {
|
||||
m_session->setCaptureMode(mode);
|
||||
reloadLater();
|
||||
|
||||
if (m_state == QCamera::ActiveState) {
|
||||
m_resourcePolicy->setResourceSet(
|
||||
captureMode() == QCamera::CaptureStillImage ?
|
||||
CamerabinResourcePolicy::ImageCaptureResources :
|
||||
CamerabinResourcePolicy::VideoCaptureResources);
|
||||
}
|
||||
emit captureModeChanged(mode);
|
||||
}
|
||||
}
|
||||
|
||||
bool CameraBinControl::isCaptureModeSupported(QCamera::CaptureMode mode) const
|
||||
{
|
||||
#ifdef Q_WS_MAEMO_5
|
||||
//Front camera on N900 supports only video capture
|
||||
if (m_session->cameraRole() == CameraBinSession::FrontCamera)
|
||||
return mode == QCamera::CaptureVideo;
|
||||
#endif
|
||||
|
||||
return mode == QCamera::CaptureStillImage || mode == QCamera::CaptureVideo;
|
||||
}
|
||||
|
||||
void CameraBinControl::setState(QCamera::State state)
|
||||
{
|
||||
#ifdef CAMEABIN_DEBUG
|
||||
qDebug() << Q_FUNC_INFO << ENUM_NAME(QCamera, "State", state);
|
||||
#endif
|
||||
if (m_state != state) {
|
||||
m_state = state;
|
||||
|
||||
//special case for stopping the camera while it's busy,
|
||||
//it should be delayed until the camera is idle
|
||||
if (state == QCamera::LoadedState &&
|
||||
m_session->state() == QCamera::ActiveState &&
|
||||
m_session->isBusy()) {
|
||||
#ifdef CAMEABIN_DEBUG
|
||||
qDebug() << Q_FUNC_INFO << "Camera is busy, QCamera::stop() is delayed";
|
||||
#endif
|
||||
emit stateChanged(m_state);
|
||||
return;
|
||||
}
|
||||
|
||||
CamerabinResourcePolicy::ResourceSet resourceSet;
|
||||
switch (state) {
|
||||
case QCamera::UnloadedState:
|
||||
resourceSet = CamerabinResourcePolicy::NoResources;
|
||||
break;
|
||||
case QCamera::LoadedState:
|
||||
resourceSet = CamerabinResourcePolicy::LoadedResources;
|
||||
break;
|
||||
case QCamera::ActiveState:
|
||||
resourceSet = captureMode() == QCamera::CaptureStillImage ?
|
||||
CamerabinResourcePolicy::ImageCaptureResources :
|
||||
CamerabinResourcePolicy::VideoCaptureResources;
|
||||
break;
|
||||
}
|
||||
|
||||
m_resourcePolicy->setResourceSet(resourceSet);
|
||||
|
||||
if (m_resourcePolicy->isResourcesGranted()) {
|
||||
//postpone changing to Active if the session is nor ready yet
|
||||
if (state == QCamera::ActiveState) {
|
||||
if (m_session->isReady()) {
|
||||
m_session->setState(state);
|
||||
} else {
|
||||
#ifdef CAMEABIN_DEBUG
|
||||
qDebug() << "Camera session is not ready yet, postpone activating";
|
||||
#endif
|
||||
}
|
||||
} else
|
||||
m_session->setState(state);
|
||||
}
|
||||
|
||||
emit stateChanged(m_state);
|
||||
}
|
||||
}
|
||||
|
||||
QCamera::State CameraBinControl::state() const
|
||||
{
|
||||
return m_state;
|
||||
}
|
||||
|
||||
void CameraBinControl::updateStatus()
|
||||
{
|
||||
QCamera::State sessionState = m_session->state();
|
||||
QCamera::Status oldStatus = m_status;
|
||||
|
||||
switch (m_state) {
|
||||
case QCamera::UnloadedState:
|
||||
m_status = QCamera::UnloadedStatus;
|
||||
break;
|
||||
case QCamera::LoadedState:
|
||||
switch (sessionState) {
|
||||
case QCamera::UnloadedState:
|
||||
m_status = QCamera::LoadingStatus;
|
||||
break;
|
||||
case QCamera::LoadedState:
|
||||
m_status = QCamera::LoadedStatus;
|
||||
break;
|
||||
case QCamera::ActiveState:
|
||||
m_status = QCamera::ActiveStatus;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case QCamera::ActiveState:
|
||||
switch (sessionState) {
|
||||
case QCamera::UnloadedState:
|
||||
m_status = QCamera::LoadingStatus;
|
||||
break;
|
||||
case QCamera::LoadedState:
|
||||
m_status = QCamera::StartingStatus;
|
||||
break;
|
||||
case QCamera::ActiveState:
|
||||
m_status = QCamera::ActiveStatus;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_status != oldStatus) {
|
||||
#ifdef CAMEABIN_DEBUG
|
||||
qDebug() << "Camera status changed" << ENUM_NAME(QCamera, "Status", m_status);
|
||||
#endif
|
||||
emit statusChanged(m_status);
|
||||
}
|
||||
}
|
||||
|
||||
void CameraBinControl::reloadLater()
|
||||
{
|
||||
#ifdef CAMEABIN_DEBUG
|
||||
qDebug() << "CameraBinControl: reload pipeline requested" << ENUM_NAME(QCamera, "State", m_state);
|
||||
#endif
|
||||
if (!m_reloadPending && m_state == QCamera::ActiveState) {
|
||||
m_reloadPending = true;
|
||||
|
||||
if (!m_session->isBusy()) {
|
||||
m_session->setState(QCamera::LoadedState);
|
||||
QMetaObject::invokeMethod(this, "delayedReload", Qt::QueuedConnection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CameraBinControl::handleResourcesLost()
|
||||
{
|
||||
#ifdef CAMEABIN_DEBUG
|
||||
qDebug() << Q_FUNC_INFO << ENUM_NAME(QCamera, "State", m_state);
|
||||
#endif
|
||||
m_session->setState(QCamera::UnloadedState);
|
||||
}
|
||||
|
||||
void CameraBinControl::handleResourcesGranted()
|
||||
{
|
||||
#ifdef CAMEABIN_DEBUG
|
||||
qDebug() << Q_FUNC_INFO << ENUM_NAME(QCamera, "State", m_state);
|
||||
#endif
|
||||
|
||||
//camera will be started soon by delayedReload()
|
||||
if (m_reloadPending && m_state == QCamera::ActiveState)
|
||||
return;
|
||||
|
||||
if (m_state == QCamera::ActiveState && m_session->isReady())
|
||||
m_session->setState(QCamera::ActiveState);
|
||||
else if (m_state == QCamera::LoadedState)
|
||||
m_session->setState(QCamera::LoadedState);
|
||||
}
|
||||
|
||||
void CameraBinControl::handleBusyChanged(bool busy)
|
||||
{
|
||||
if (!busy && m_session->state() == QCamera::ActiveState) {
|
||||
if (m_state == QCamera::LoadedState) {
|
||||
//handle delayed stop() because of busy camera
|
||||
m_resourcePolicy->setResourceSet(CamerabinResourcePolicy::LoadedResources);
|
||||
m_session->setState(QCamera::LoadedState);
|
||||
} else if (m_state == QCamera::ActiveState && m_reloadPending) {
|
||||
//handle delayed reload because of busy camera
|
||||
m_session->setState(QCamera::LoadedState);
|
||||
QMetaObject::invokeMethod(this, "delayedReload", Qt::QueuedConnection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CameraBinControl::handleCameraError(int errorCode, const QString &errorString)
|
||||
{
|
||||
emit error(errorCode, errorString);
|
||||
setState(QCamera::UnloadedState);
|
||||
}
|
||||
|
||||
void CameraBinControl::delayedReload()
|
||||
{
|
||||
#ifdef CAMEABIN_DEBUG
|
||||
qDebug() << "CameraBinControl: reload pipeline";
|
||||
#endif
|
||||
if (m_reloadPending) {
|
||||
m_reloadPending = false;
|
||||
if (m_state == QCamera::ActiveState &&
|
||||
m_session->isReady() &&
|
||||
m_resourcePolicy->isResourcesGranted()) {
|
||||
m_session->setState(QCamera::ActiveState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CameraBinControl::canChangeProperty(PropertyChangeType changeType, QCamera::Status status) const
|
||||
{
|
||||
Q_UNUSED(status);
|
||||
|
||||
switch (changeType) {
|
||||
case QCameraControl::CaptureMode:
|
||||
case QCameraControl::ImageEncodingSettings:
|
||||
case QCameraControl::VideoEncodingSettings:
|
||||
case QCameraControl::Viewfinder:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#define VIEWFINDER_COLORSPACE_CONVERSION 0x00000004
|
||||
|
||||
bool CameraBinControl::viewfinderColorSpaceConversion() const
|
||||
{
|
||||
gint flags = 0;
|
||||
g_object_get(G_OBJECT(m_session->cameraBin()), "flags", &flags, NULL);
|
||||
|
||||
return flags & VIEWFINDER_COLORSPACE_CONVERSION;
|
||||
}
|
||||
|
||||
void CameraBinControl::setViewfinderColorSpaceConversion(bool enabled)
|
||||
{
|
||||
gint flags = 0;
|
||||
g_object_get(G_OBJECT(m_session->cameraBin()), "flags", &flags, NULL);
|
||||
|
||||
if (enabled)
|
||||
flags |= VIEWFINDER_COLORSPACE_CONVERSION;
|
||||
else
|
||||
flags &= ~VIEWFINDER_COLORSPACE_CONVERSION;
|
||||
|
||||
g_object_set(G_OBJECT(m_session->cameraBin()), "flags", flags, NULL);
|
||||
}
|
||||
101
src/plugins/gstreamer/camerabin/camerabincontrol.h
Normal file
101
src/plugins/gstreamer/camerabin/camerabincontrol.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2009 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 CAMERABINCONTROL_H
|
||||
#define CAMERABINCONTROL_H
|
||||
|
||||
#include <QHash>
|
||||
#include <qcameracontrol.h>
|
||||
#include "camerabinsession.h"
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class CamerabinResourcePolicy;
|
||||
|
||||
class CameraBinControl : public QCameraControl
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool viewfinderColorSpaceConversion READ viewfinderColorSpaceConversion WRITE setViewfinderColorSpaceConversion)
|
||||
public:
|
||||
CameraBinControl( CameraBinSession *session );
|
||||
virtual ~CameraBinControl();
|
||||
|
||||
bool isValid() const { return true; }
|
||||
|
||||
QCamera::State state() const;
|
||||
void setState(QCamera::State state);
|
||||
|
||||
QCamera::Status status() const { return m_status; }
|
||||
|
||||
QCamera::CaptureMode captureMode() const;
|
||||
void setCaptureMode(QCamera::CaptureMode mode);
|
||||
|
||||
bool isCaptureModeSupported(QCamera::CaptureMode mode) const;
|
||||
bool canChangeProperty(PropertyChangeType changeType, QCamera::Status status) const;
|
||||
bool viewfinderColorSpaceConversion() const;
|
||||
|
||||
public slots:
|
||||
void reloadLater();
|
||||
void setViewfinderColorSpaceConversion(bool enabled);
|
||||
|
||||
private slots:
|
||||
void updateStatus();
|
||||
void delayedReload();
|
||||
|
||||
void handleResourcesGranted();
|
||||
void handleResourcesLost();
|
||||
|
||||
void handleBusyChanged(bool);
|
||||
void handleCameraError(int error, const QString &errorString);
|
||||
|
||||
private:
|
||||
void updateSupportedResolutions(const QString &device);
|
||||
|
||||
CameraBinSession *m_session;
|
||||
QCamera::State m_state;
|
||||
QCamera::Status m_status;
|
||||
CamerabinResourcePolicy *m_resourcePolicy;
|
||||
|
||||
bool m_reloadPending;
|
||||
};
|
||||
|
||||
#endif // CAMERABINCONTROL_H
|
||||
232
src/plugins/gstreamer/camerabin/camerabinexposure.cpp
Normal file
232
src/plugins/gstreamer/camerabin/camerabinexposure.cpp
Normal file
@@ -0,0 +1,232 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2009 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 "camerabinexposure.h"
|
||||
#include "camerabinsession.h"
|
||||
#include <gst/interfaces/photography.h>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
CameraBinExposure::CameraBinExposure(CameraBinSession *session)
|
||||
:QCameraExposureControl(session),
|
||||
m_session(session)
|
||||
{
|
||||
}
|
||||
|
||||
CameraBinExposure::~CameraBinExposure()
|
||||
{
|
||||
}
|
||||
|
||||
QCameraExposure::ExposureMode CameraBinExposure::exposureMode() const
|
||||
{
|
||||
GstSceneMode sceneMode;
|
||||
gst_photography_get_scene_mode(m_session->photography(), &sceneMode);
|
||||
|
||||
switch (sceneMode) {
|
||||
case GST_PHOTOGRAPHY_SCENE_MODE_PORTRAIT: return QCameraExposure::ExposurePortrait;
|
||||
case GST_PHOTOGRAPHY_SCENE_MODE_SPORT: return QCameraExposure::ExposureSports;
|
||||
case GST_PHOTOGRAPHY_SCENE_MODE_NIGHT: return QCameraExposure::ExposureNight;
|
||||
case GST_PHOTOGRAPHY_SCENE_MODE_MANUAL: return QCameraExposure::ExposureManual;
|
||||
case GST_PHOTOGRAPHY_SCENE_MODE_CLOSEUP: //no direct mapping available so mapping to auto mode
|
||||
case GST_PHOTOGRAPHY_SCENE_MODE_LANDSCAPE: //no direct mapping available so mapping to auto mode
|
||||
case GST_PHOTOGRAPHY_SCENE_MODE_AUTO:
|
||||
default:
|
||||
return QCameraExposure::ExposureAuto;
|
||||
}
|
||||
}
|
||||
|
||||
void CameraBinExposure::setExposureMode(QCameraExposure::ExposureMode mode)
|
||||
{
|
||||
GstSceneMode sceneMode;
|
||||
gst_photography_get_scene_mode(m_session->photography(), &sceneMode);
|
||||
|
||||
switch (mode) {
|
||||
case QCameraExposure::ExposureManual: sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_MANUAL; break;
|
||||
case QCameraExposure::ExposurePortrait: sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_PORTRAIT; break;
|
||||
case QCameraExposure::ExposureSports: sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_SPORT; break;
|
||||
case QCameraExposure::ExposureNight: sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_NIGHT; break;
|
||||
case QCameraExposure::ExposureAuto: sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_AUTO; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
gst_photography_set_scene_mode(m_session->photography(), sceneMode);
|
||||
}
|
||||
|
||||
bool CameraBinExposure::isExposureModeSupported(QCameraExposure::ExposureMode mode) const
|
||||
{
|
||||
//Similar mode names can be found in gst as GstSceneMode
|
||||
return mode == QCameraExposure::ExposureAuto ||
|
||||
mode == QCameraExposure::ExposurePortrait ||
|
||||
mode == QCameraExposure::ExposureSports ||
|
||||
mode == QCameraExposure::ExposureNight;
|
||||
|
||||
//No direct mapping available for GST_PHOTOGRAPHY_SCENE_MODE_CLOSEUP and
|
||||
//GST_PHOTOGRAPHY_SCENE_MODE_LANDSCAPE
|
||||
}
|
||||
|
||||
QCameraExposure::MeteringMode CameraBinExposure::meteringMode() const
|
||||
{
|
||||
return QCameraExposure::MeteringMatrix;
|
||||
}
|
||||
|
||||
void CameraBinExposure::setMeteringMode(QCameraExposure::MeteringMode mode)
|
||||
{
|
||||
Q_UNUSED(mode);
|
||||
}
|
||||
|
||||
bool CameraBinExposure::isMeteringModeSupported(QCameraExposure::MeteringMode mode) const
|
||||
{
|
||||
return mode == QCameraExposure::MeteringMatrix;
|
||||
}
|
||||
|
||||
bool CameraBinExposure::isParameterSupported(ExposureParameter parameter) const
|
||||
{
|
||||
switch (parameter) {
|
||||
case QCameraExposureControl::ExposureCompensation:
|
||||
case QCameraExposureControl::ISO:
|
||||
case QCameraExposureControl::Aperture:
|
||||
case QCameraExposureControl::ShutterSpeed:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
QVariant CameraBinExposure::exposureParameter(ExposureParameter parameter) const
|
||||
{
|
||||
switch (parameter) {
|
||||
case QCameraExposureControl::ExposureCompensation:
|
||||
{
|
||||
gfloat ev;
|
||||
gst_photography_get_ev_compensation(m_session->photography(), &ev);
|
||||
return QVariant(ev);
|
||||
}
|
||||
case QCameraExposureControl::ISO:
|
||||
{
|
||||
guint isoSpeed = 0;
|
||||
gst_photography_get_iso_speed(m_session->photography(), &isoSpeed);
|
||||
return QVariant(isoSpeed);
|
||||
}
|
||||
case QCameraExposureControl::Aperture:
|
||||
return QVariant(2.8);
|
||||
case QCameraExposureControl::ShutterSpeed:
|
||||
{
|
||||
guint32 shutterSpeed = 0;
|
||||
gst_photography_get_exposure(m_session->photography(), &shutterSpeed);
|
||||
|
||||
return QVariant(shutterSpeed/1000000.0);
|
||||
}
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
QCameraExposureControl::ParameterFlags CameraBinExposure::exposureParameterFlags(ExposureParameter parameter) const
|
||||
{
|
||||
QCameraExposureControl::ParameterFlags flags = 0;
|
||||
|
||||
switch (parameter) {
|
||||
case QCameraExposureControl::ExposureCompensation:
|
||||
flags |= ContinuousRange;
|
||||
break;
|
||||
case QCameraExposureControl::Aperture:
|
||||
flags |= ReadOnly;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
QVariantList CameraBinExposure::supportedParameterRange(ExposureParameter parameter) const
|
||||
{
|
||||
QVariantList res;
|
||||
switch (parameter) {
|
||||
case QCameraExposureControl::ExposureCompensation:
|
||||
res << -2.0 << 2.0;
|
||||
break;
|
||||
case QCameraExposureControl::ISO:
|
||||
res << 100 << 200 << 400;
|
||||
break;
|
||||
case QCameraExposureControl::Aperture:
|
||||
res << 2.8;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool CameraBinExposure::setExposureParameter(ExposureParameter parameter, const QVariant& value)
|
||||
{
|
||||
QVariant oldValue = exposureParameter(parameter);
|
||||
|
||||
switch (parameter) {
|
||||
case QCameraExposureControl::ExposureCompensation:
|
||||
gst_photography_set_ev_compensation(m_session->photography(), value.toReal());
|
||||
break;
|
||||
case QCameraExposureControl::ISO:
|
||||
gst_photography_set_iso_speed(m_session->photography(), value.toInt());
|
||||
break;
|
||||
case QCameraExposureControl::Aperture:
|
||||
gst_photography_set_aperture(m_session->photography(), guint(value.toReal()*1000000));
|
||||
break;
|
||||
case QCameraExposureControl::ShutterSpeed:
|
||||
gst_photography_set_exposure(m_session->photography(), guint(value.toReal()*1000000));
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
QVariant newValue = exposureParameter(parameter);
|
||||
if (!qFuzzyCompare(oldValue.toReal(), newValue.toReal()))
|
||||
emit exposureParameterChanged(parameter);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QString CameraBinExposure::extendedParameterName(ExposureParameter)
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
83
src/plugins/gstreamer/camerabin/camerabinexposure.h
Normal file
83
src/plugins/gstreamer/camerabin/camerabinexposure.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2009 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 CAMERABINEXPOSURECONTROL_MAEMO_H
|
||||
#define CAMERABINEXPOSURECONTROL_MAEMO_H
|
||||
|
||||
#include <qcamera.h>
|
||||
#include <qcameraexposurecontrol.h>
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <glib.h>
|
||||
|
||||
class CameraBinSession;
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class Q_MULTIMEDIA_EXPORT CameraBinExposure : public QCameraExposureControl
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CameraBinExposure(CameraBinSession *session);
|
||||
virtual ~CameraBinExposure();
|
||||
|
||||
QCameraExposure::ExposureMode exposureMode() const;
|
||||
void setExposureMode(QCameraExposure::ExposureMode mode);
|
||||
bool isExposureModeSupported(QCameraExposure::ExposureMode mode) const;
|
||||
|
||||
QCameraExposure::MeteringMode meteringMode() const;
|
||||
void setMeteringMode(QCameraExposure::MeteringMode mode);
|
||||
bool isMeteringModeSupported(QCameraExposure::MeteringMode mode) const;
|
||||
|
||||
bool isParameterSupported(ExposureParameter parameter) const;
|
||||
QVariant exposureParameter(ExposureParameter parameter) const;
|
||||
ParameterFlags exposureParameterFlags(ExposureParameter parameter) const;
|
||||
QVariantList supportedParameterRange(ExposureParameter parameter) const;
|
||||
bool setExposureParameter(ExposureParameter parameter, const QVariant& value);
|
||||
|
||||
QString extendedParameterName(ExposureParameter parameter);
|
||||
|
||||
private:
|
||||
CameraBinSession *m_session;
|
||||
};
|
||||
|
||||
#endif // CAMERABINEXPOSURECONTROL_MAEMO_H
|
||||
104
src/plugins/gstreamer/camerabin/camerabinflash.cpp
Normal file
104
src/plugins/gstreamer/camerabin/camerabinflash.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2009 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 "camerabinflash.h"
|
||||
#include "camerabinsession.h"
|
||||
#include <gst/interfaces/photography.h>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
CameraBinFlash::CameraBinFlash(CameraBinSession *session)
|
||||
:QCameraFlashControl(session),
|
||||
m_session(session)
|
||||
{
|
||||
}
|
||||
|
||||
CameraBinFlash::~CameraBinFlash()
|
||||
{
|
||||
}
|
||||
|
||||
QCameraExposure::FlashModes CameraBinFlash::flashMode() const
|
||||
{
|
||||
GstFlashMode flashMode;
|
||||
gst_photography_get_flash_mode(m_session->photography(), &flashMode);
|
||||
|
||||
QCameraExposure::FlashModes modes;
|
||||
switch (flashMode) {
|
||||
case GST_PHOTOGRAPHY_FLASH_MODE_AUTO: modes |= QCameraExposure::FlashAuto; break;
|
||||
case GST_PHOTOGRAPHY_FLASH_MODE_OFF: modes |= QCameraExposure::FlashOff; break;
|
||||
case GST_PHOTOGRAPHY_FLASH_MODE_ON: modes |= QCameraExposure::FlashOn; break;
|
||||
case GST_PHOTOGRAPHY_FLASH_MODE_FILL_IN: modes |= QCameraExposure::FlashFill; break;
|
||||
case GST_PHOTOGRAPHY_FLASH_MODE_RED_EYE: modes |= QCameraExposure::FlashRedEyeReduction; break;
|
||||
default:
|
||||
modes |= QCameraExposure::FlashAuto;
|
||||
break;
|
||||
}
|
||||
return modes;
|
||||
}
|
||||
|
||||
void CameraBinFlash::setFlashMode(QCameraExposure::FlashModes mode)
|
||||
{
|
||||
GstFlashMode flashMode;
|
||||
gst_photography_get_flash_mode(m_session->photography(), &flashMode);
|
||||
|
||||
if (mode.testFlag(QCameraExposure::FlashAuto)) flashMode = GST_PHOTOGRAPHY_FLASH_MODE_AUTO;
|
||||
else if (mode.testFlag(QCameraExposure::FlashOff)) flashMode = GST_PHOTOGRAPHY_FLASH_MODE_OFF;
|
||||
else if (mode.testFlag(QCameraExposure::FlashOn)) flashMode = GST_PHOTOGRAPHY_FLASH_MODE_ON;
|
||||
else if (mode.testFlag(QCameraExposure::FlashFill)) flashMode = GST_PHOTOGRAPHY_FLASH_MODE_FILL_IN;
|
||||
else if (mode.testFlag(QCameraExposure::FlashRedEyeReduction)) flashMode = GST_PHOTOGRAPHY_FLASH_MODE_RED_EYE;
|
||||
|
||||
gst_photography_set_flash_mode(m_session->photography(), flashMode);
|
||||
}
|
||||
|
||||
bool CameraBinFlash::isFlashModeSupported(QCameraExposure::FlashModes mode) const
|
||||
{
|
||||
return mode == QCameraExposure::FlashOff ||
|
||||
mode == QCameraExposure::FlashOn ||
|
||||
mode == QCameraExposure::FlashAuto ||
|
||||
mode == QCameraExposure::FlashRedEyeReduction ||
|
||||
mode == QCameraExposure::FlashFill;
|
||||
}
|
||||
|
||||
bool CameraBinFlash::isFlashReady() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
73
src/plugins/gstreamer/camerabin/camerabinflash.h
Normal file
73
src/plugins/gstreamer/camerabin/camerabinflash.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2009 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 CAMERABINFLASHCONTROL_H
|
||||
#define CAMERABINFLASHCONTROL_H
|
||||
|
||||
#include <qcamera.h>
|
||||
#include <qcameraflashcontrol.h>
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <glib.h>
|
||||
|
||||
class CameraBinSession;
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class Q_MULTIMEDIA_EXPORT CameraBinFlash : public QCameraFlashControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CameraBinFlash(CameraBinSession *session);
|
||||
virtual ~CameraBinFlash();
|
||||
|
||||
QCameraExposure::FlashModes flashMode() const;
|
||||
void setFlashMode(QCameraExposure::FlashModes mode);
|
||||
bool isFlashModeSupported(QCameraExposure::FlashModes mode) const;
|
||||
|
||||
bool isFlashReady() const;
|
||||
|
||||
private:
|
||||
CameraBinSession *m_session;
|
||||
};
|
||||
|
||||
#endif // CAMERABINFLASHCONTROL_H
|
||||
|
||||
245
src/plugins/gstreamer/camerabin/camerabinfocus.cpp
Normal file
245
src/plugins/gstreamer/camerabin/camerabinfocus.cpp
Normal file
@@ -0,0 +1,245 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2009 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 "camerabinfocus.h"
|
||||
#include "camerabinsession.h"
|
||||
|
||||
#include <gst/interfaces/photography.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QtCore/qmetaobject.h>
|
||||
|
||||
//#define CAMERABIN_DEBUG 1
|
||||
#define ENUM_NAME(c,e,v) (c::staticMetaObject.enumerator(c::staticMetaObject.indexOfEnumerator(e)).valueToKey((v)))
|
||||
|
||||
CameraBinFocus::CameraBinFocus(CameraBinSession *session)
|
||||
:QCameraFocusControl(session),
|
||||
m_session(session),
|
||||
m_focusMode(QCameraFocus::AutoFocus),
|
||||
m_focusStatus(QCamera::Unlocked),
|
||||
m_focusZoneStatus(QCameraFocusZone::Selected)
|
||||
{
|
||||
connect(m_session, SIGNAL(stateChanged(QCamera::State)),
|
||||
this, SLOT(_q_handleCameraStateChange(QCamera::State)));
|
||||
connect(m_session, SIGNAL(imageCaptured(int,QImage)),
|
||||
this, SLOT(_q_handleCapturedImage()));
|
||||
}
|
||||
|
||||
CameraBinFocus::~CameraBinFocus()
|
||||
{
|
||||
}
|
||||
|
||||
QCameraFocus::FocusMode CameraBinFocus::focusMode() const
|
||||
{
|
||||
return m_focusMode;
|
||||
}
|
||||
|
||||
void CameraBinFocus::setFocusMode(QCameraFocus::FocusMode mode)
|
||||
{
|
||||
if (isFocusModeSupported(mode)) {
|
||||
m_focusMode = mode;
|
||||
}
|
||||
}
|
||||
|
||||
bool CameraBinFocus::isFocusModeSupported(QCameraFocus::FocusMode mode) const
|
||||
{
|
||||
return mode & QCameraFocus::AutoFocus;
|
||||
}
|
||||
|
||||
qreal CameraBinFocus::maximumOpticalZoom() const
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
qreal CameraBinFocus::maximumDigitalZoom() const
|
||||
{
|
||||
return 10;
|
||||
}
|
||||
|
||||
qreal CameraBinFocus::opticalZoom() const
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
qreal CameraBinFocus::digitalZoom() const
|
||||
{
|
||||
#ifdef Q_WS_MAEMO_5
|
||||
gint zoomFactor = 0;
|
||||
g_object_get(GST_BIN(m_session->cameraBin()), "zoom", &zoomFactor, NULL);
|
||||
return zoomFactor/100.0;
|
||||
#else
|
||||
gfloat zoomFactor = 1.0;
|
||||
g_object_get(GST_BIN(m_session->cameraBin()), "zoom", &zoomFactor, NULL);
|
||||
return zoomFactor;
|
||||
#endif
|
||||
}
|
||||
|
||||
void CameraBinFocus::zoomTo(qreal optical, qreal digital)
|
||||
{
|
||||
Q_UNUSED(optical);
|
||||
digital = qBound(qreal(1.0), digital, qreal(10.0));
|
||||
#ifdef Q_WS_MAEMO_5
|
||||
g_object_set(GST_BIN(m_session->cameraBin()), "zoom", qRound(digital*100.0), NULL);
|
||||
#else
|
||||
g_object_set(GST_BIN(m_session->cameraBin()), "zoom", digital, NULL);
|
||||
#endif
|
||||
emit digitalZoomChanged(digital);
|
||||
}
|
||||
|
||||
QCameraFocus::FocusPointMode CameraBinFocus::focusPointMode() const
|
||||
{
|
||||
return QCameraFocus::FocusPointAuto;
|
||||
}
|
||||
|
||||
void CameraBinFocus::setFocusPointMode(QCameraFocus::FocusPointMode mode)
|
||||
{
|
||||
Q_UNUSED(mode);
|
||||
}
|
||||
|
||||
bool CameraBinFocus::isFocusPointModeSupported(QCameraFocus::FocusPointMode mode) const
|
||||
{
|
||||
return mode == QCameraFocus::FocusPointAuto;
|
||||
}
|
||||
|
||||
QPointF CameraBinFocus::customFocusPoint() const
|
||||
{
|
||||
return QPointF(0.5, 0.5);
|
||||
}
|
||||
|
||||
void CameraBinFocus::setCustomFocusPoint(const QPointF &point)
|
||||
{
|
||||
Q_UNUSED(point);
|
||||
}
|
||||
|
||||
QCameraFocusZoneList CameraBinFocus::focusZones() const
|
||||
{
|
||||
return QCameraFocusZoneList() << QCameraFocusZone(QRectF(0.35, 0.35, 0.3, 0.3), m_focusZoneStatus);
|
||||
}
|
||||
|
||||
|
||||
void CameraBinFocus::handleFocusMessage(GstMessage *gm)
|
||||
{
|
||||
//it's a sync message, so it's called from non main thread
|
||||
if (gst_structure_has_name(gm->structure, GST_PHOTOGRAPHY_AUTOFOCUS_DONE)) {
|
||||
gint status = GST_PHOTOGRAPHY_FOCUS_STATUS_NONE;
|
||||
gst_structure_get_int (gm->structure, "status", &status);
|
||||
QCamera::LockStatus focusStatus = m_focusStatus;
|
||||
QCamera::LockChangeReason reason = QCamera::UserRequest;
|
||||
|
||||
switch (status) {
|
||||
case GST_PHOTOGRAPHY_FOCUS_STATUS_FAIL:
|
||||
focusStatus = QCamera::Unlocked;
|
||||
reason = QCamera::LockFailed;
|
||||
break;
|
||||
case GST_PHOTOGRAPHY_FOCUS_STATUS_SUCCESS:
|
||||
focusStatus = QCamera::Locked;
|
||||
break;
|
||||
case GST_PHOTOGRAPHY_FOCUS_STATUS_NONE:
|
||||
break;
|
||||
case GST_PHOTOGRAPHY_FOCUS_STATUS_RUNNING:
|
||||
focusStatus = QCamera::Searching;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
static int signalIndex = metaObject()->indexOfSlot(
|
||||
"_q_setFocusStatus(QCamera::LockStatus,QCamera::LockChangeReason)");
|
||||
metaObject()->method(signalIndex).invoke(this,
|
||||
Qt::QueuedConnection,
|
||||
Q_ARG(QCamera::LockStatus,focusStatus),
|
||||
Q_ARG(QCamera::LockChangeReason,reason));
|
||||
}
|
||||
}
|
||||
|
||||
void CameraBinFocus::_q_setFocusStatus(QCamera::LockStatus status, QCamera::LockChangeReason reason)
|
||||
{
|
||||
#ifdef CAMERABIN_DEBUG
|
||||
qDebug() << Q_FUNC_INFO << "Current:"
|
||||
<< ENUM_NAME(QCamera, "LockStatus", m_focusStatus)
|
||||
<< "New:"
|
||||
<< ENUM_NAME(QCamera, "LockStatus", status) << ENUM_NAME(QCamera, "LockChangeReason", reason);
|
||||
#endif
|
||||
|
||||
if (m_focusStatus != status) {
|
||||
m_focusStatus = status;
|
||||
|
||||
QCameraFocusZone::FocusZoneStatus zonesStatus =
|
||||
m_focusStatus == QCamera::Locked ?
|
||||
QCameraFocusZone::Focused : QCameraFocusZone::Selected;
|
||||
|
||||
if (m_focusZoneStatus != zonesStatus) {
|
||||
m_focusZoneStatus = zonesStatus;
|
||||
emit focusZonesChanged();
|
||||
}
|
||||
|
||||
emit _q_focusStatusChanged(m_focusStatus, reason);
|
||||
}
|
||||
}
|
||||
|
||||
void CameraBinFocus::_q_handleCameraStateChange(QCamera::State state)
|
||||
{
|
||||
if (state != QCamera::ActiveState)
|
||||
_q_setFocusStatus(QCamera::Unlocked, QCamera::LockLost);
|
||||
}
|
||||
|
||||
void CameraBinFocus::_q_handleCapturedImage()
|
||||
{
|
||||
#ifdef Q_WS_MAEMO_5
|
||||
//N900 lost focus after image capture
|
||||
if (m_focusStatus != QCamera::Unlocked) {
|
||||
m_focusStatus = QCamera::Unlocked;
|
||||
emit _q_focusStatusChanged(QCamera::Unlocked, QCamera::LockLost);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void CameraBinFocus::_q_startFocusing()
|
||||
{
|
||||
_q_setFocusStatus(QCamera::Searching, QCamera::UserRequest);
|
||||
gst_photography_set_autofocus(m_session->photography(), TRUE);
|
||||
}
|
||||
|
||||
void CameraBinFocus::_q_stopFocusing()
|
||||
{
|
||||
gst_photography_set_autofocus(m_session->photography(), FALSE);
|
||||
_q_setFocusStatus(QCamera::Unlocked, QCamera::UserRequest);
|
||||
}
|
||||
104
src/plugins/gstreamer/camerabin/camerabinfocus.h
Normal file
104
src/plugins/gstreamer/camerabin/camerabinfocus.h
Normal file
@@ -0,0 +1,104 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2009 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 CAMERABINFOCUSCONTROL_H
|
||||
#define CAMERABINFOCUSCONTROL_H
|
||||
|
||||
#include <qcamera.h>
|
||||
#include <qcamerafocuscontrol.h>
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <glib.h>
|
||||
|
||||
class CameraBinSession;
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class CameraBinFocus : public QCameraFocusControl
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CameraBinFocus(CameraBinSession *session);
|
||||
virtual ~CameraBinFocus();
|
||||
|
||||
QCameraFocus::FocusMode focusMode() const;
|
||||
void setFocusMode(QCameraFocus::FocusMode mode);
|
||||
bool isFocusModeSupported(QCameraFocus::FocusMode mode) const;
|
||||
|
||||
qreal maximumOpticalZoom() const;
|
||||
qreal maximumDigitalZoom() const;
|
||||
qreal opticalZoom() const;
|
||||
qreal digitalZoom() const;
|
||||
|
||||
void zoomTo(qreal optical, qreal digital) ;
|
||||
|
||||
QCameraFocus::FocusPointMode focusPointMode() const;
|
||||
void setFocusPointMode(QCameraFocus::FocusPointMode mode) ;
|
||||
bool isFocusPointModeSupported(QCameraFocus::FocusPointMode) const;
|
||||
QPointF customFocusPoint() const;
|
||||
void setCustomFocusPoint(const QPointF &point);
|
||||
|
||||
QCameraFocusZoneList focusZones() const;
|
||||
|
||||
void handleFocusMessage(GstMessage*);
|
||||
QCamera::LockStatus focusStatus() const { return m_focusStatus; }
|
||||
|
||||
Q_SIGNALS:
|
||||
void _q_focusStatusChanged(QCamera::LockStatus status, QCamera::LockChangeReason reason);
|
||||
|
||||
public Q_SLOTS:
|
||||
void _q_startFocusing();
|
||||
void _q_stopFocusing();
|
||||
|
||||
private Q_SLOTS:
|
||||
void _q_setFocusStatus(QCamera::LockStatus status, QCamera::LockChangeReason reason);
|
||||
void _q_handleCameraStateChange(QCamera::State state);
|
||||
void _q_handleCapturedImage();
|
||||
|
||||
private:
|
||||
CameraBinSession *m_session;
|
||||
QCameraFocus::FocusMode m_focusMode;
|
||||
QCamera::LockStatus m_focusStatus;
|
||||
QCameraFocusZone::FocusZoneStatus m_focusZoneStatus;
|
||||
};
|
||||
|
||||
#endif // CAMERABINFOCUSCONTROL_H
|
||||
347
src/plugins/gstreamer/camerabin/camerabinimagecapture.cpp
Normal file
347
src/plugins/gstreamer/camerabin/camerabinimagecapture.cpp
Normal file
@@ -0,0 +1,347 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2009 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 "camerabinimagecapture.h"
|
||||
#include "camerabincapturedestination.h"
|
||||
#include "camerabincapturebufferformat.h"
|
||||
#include "camerabinsession.h"
|
||||
#include "qgstvideobuffer.h"
|
||||
#include "qvideosurfacegstsink.h"
|
||||
#include "qgstutils.h"
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtCore/qbuffer.h>
|
||||
#include <QtGui/qimagereader.h>
|
||||
|
||||
//#define DEBUG_CAPTURE
|
||||
|
||||
#ifdef Q_WS_MAEMO_5
|
||||
#define IMAGE_DONE_SIGNAL "img-done"
|
||||
#else
|
||||
#define IMAGE_DONE_SIGNAL "image-done"
|
||||
#endif
|
||||
|
||||
|
||||
Q_DECLARE_METATYPE(QVideoFrame)
|
||||
Q_DECLARE_METATYPE(QtMultimediaKit::MetaData)
|
||||
|
||||
namespace
|
||||
{
|
||||
class CameraRegisterMetaTypes
|
||||
{
|
||||
public:
|
||||
CameraRegisterMetaTypes()
|
||||
{
|
||||
qRegisterMetaType<QVideoFrame>("QVideoFrame");
|
||||
qRegisterMetaType<QtMultimediaKit::MetaData>("QtMultimediaKit::MetaData");
|
||||
}
|
||||
} _registerCameraMetaTypes;
|
||||
}
|
||||
|
||||
|
||||
CameraBinImageCapture::CameraBinImageCapture(CameraBinSession *session)
|
||||
:QCameraImageCaptureControl(session)
|
||||
, m_session(session)
|
||||
, m_ready(false)
|
||||
, m_requestId(0)
|
||||
, m_jpegEncoderElement(0)
|
||||
, m_metadataMuxerElement(0)
|
||||
{
|
||||
connect(m_session, SIGNAL(stateChanged(QCamera::State)), SLOT(updateState()));
|
||||
connect(m_session, SIGNAL(imageExposed(int)), this, SIGNAL(imageExposed(int)));
|
||||
connect(m_session, SIGNAL(imageCaptured(int,QImage)), this, SIGNAL(imageCaptured(int,QImage)));
|
||||
connect(m_session, SIGNAL(busMessage(QGstreamerMessage)), SLOT(handleBusMessage(QGstreamerMessage)));
|
||||
|
||||
g_signal_connect(G_OBJECT(m_session->cameraBin()), IMAGE_DONE_SIGNAL, G_CALLBACK(handleImageSaved), this);
|
||||
}
|
||||
|
||||
CameraBinImageCapture::~CameraBinImageCapture()
|
||||
{
|
||||
}
|
||||
|
||||
bool CameraBinImageCapture::isReadyForCapture() const
|
||||
{
|
||||
return m_ready;
|
||||
}
|
||||
|
||||
int CameraBinImageCapture::capture(const QString &fileName)
|
||||
{
|
||||
m_requestId++;
|
||||
|
||||
if (!m_ready) {
|
||||
emit error(m_requestId, QCameraImageCapture::NotReadyError, tr("Camera not ready"));
|
||||
return m_requestId;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CAPTURE
|
||||
qDebug() << Q_FUNC_INFO << m_requestId << fileName;
|
||||
#endif
|
||||
m_session->captureImage(m_requestId, fileName);
|
||||
return m_requestId;
|
||||
}
|
||||
|
||||
void CameraBinImageCapture::cancelCapture()
|
||||
{
|
||||
}
|
||||
|
||||
void CameraBinImageCapture::updateState()
|
||||
{
|
||||
bool ready = m_session->state() == QCamera::ActiveState;
|
||||
if (m_ready != ready) {
|
||||
#ifdef DEBUG_CAPTURE
|
||||
qDebug() << "readyForCaptureChanged" << ready;
|
||||
#endif
|
||||
emit readyForCaptureChanged(m_ready = ready);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean CameraBinImageCapture::handleImageSaved(GstElement *camera,
|
||||
const gchar *filename,
|
||||
CameraBinImageCapture *self)
|
||||
{
|
||||
#ifdef DEBUG_CAPTURE
|
||||
qDebug() << "Image saved" << filename;
|
||||
#endif
|
||||
|
||||
Q_UNUSED(camera);
|
||||
|
||||
if (self->m_session->captureDestinationControl()->captureDestination() & QCameraImageCapture::CaptureToFile) {
|
||||
QMetaObject::invokeMethod(self, "imageSaved",
|
||||
Qt::QueuedConnection,
|
||||
Q_ARG(int, self->m_requestId),
|
||||
Q_ARG(QString, QString::fromUtf8(filename)));
|
||||
} else {
|
||||
#ifdef DEBUG_CAPTURE
|
||||
qDebug() << Q_FUNC_INFO << "Dropped saving file" << filename;
|
||||
#endif
|
||||
//camerabin creates an empty file when captured buffer is dropped,
|
||||
//let's remove it
|
||||
QFileInfo info(QString::fromUtf8(filename));
|
||||
if (info.isFile() &&
|
||||
info.filePath().startsWith("/home") &&
|
||||
info.size() == 0) {
|
||||
QFile(info.absoluteFilePath()).remove();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
gboolean CameraBinImageCapture::metadataEventProbe(GstPad *pad, GstEvent *event, CameraBinImageCapture *self)
|
||||
{
|
||||
|
||||
if (GST_EVENT_TYPE(event) == GST_EVENT_TAG) {
|
||||
GstTagList *gstTags;
|
||||
gst_event_parse_tag(event, &gstTags);
|
||||
QMap<QByteArray, QVariant> extendedTags = QGstUtils::gstTagListToMap(gstTags);
|
||||
|
||||
#ifdef DEBUG_CAPTURE
|
||||
qDebug() << QString(gst_structure_to_string(gst_event_get_structure(event))).right(768);
|
||||
qDebug() << "Capture event probe" << extendedTags;
|
||||
#endif
|
||||
|
||||
QMap<QtMultimediaKit::MetaData, QVariant> tags;
|
||||
tags[QtMultimediaKit::ISOSpeedRatings] = extendedTags.value("capturing-iso-speed");
|
||||
tags[QtMultimediaKit::DigitalZoomRatio] = extendedTags.value("capturing-digital-zoom-ratio");
|
||||
tags[QtMultimediaKit::ExposureTime] = extendedTags.value("capturing-shutter-speed");
|
||||
tags[QtMultimediaKit::WhiteBalance] = extendedTags.value("capturing-white-balance");
|
||||
tags[QtMultimediaKit::Flash] = extendedTags.value("capturing-flash-fired");
|
||||
tags[QtMultimediaKit::FocalLengthIn35mmFilm] = extendedTags.value("capturing-focal-length");
|
||||
tags[QtMultimediaKit::MeteringMode] = extendedTags.value("capturing-metering-mode");
|
||||
tags[QtMultimediaKit::ExposureMode] = extendedTags.value("capturing-exposure-mode");
|
||||
tags[QtMultimediaKit::FNumber] = extendedTags.value("capturing-focal-ratio");
|
||||
tags[QtMultimediaKit::ExposureMode] = extendedTags.value("capturing-exposure-mode");
|
||||
|
||||
QMapIterator<QtMultimediaKit::MetaData, QVariant> i(tags);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
if (i.value().isValid()) {
|
||||
QMetaObject::invokeMethod(self, "imageMetadataAvailable",
|
||||
Qt::QueuedConnection,
|
||||
Q_ARG(int, self->m_requestId),
|
||||
Q_ARG(QtMultimediaKit::MetaData, i.key()),
|
||||
Q_ARG(QVariant, i.value()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
gboolean CameraBinImageCapture::uncompressedBufferProbe(GstPad *pad, GstBuffer *buffer, CameraBinImageCapture *self)
|
||||
{
|
||||
Q_UNUSED(pad);
|
||||
CameraBinSession *session = self->m_session;
|
||||
|
||||
#ifdef DEBUG_CAPTURE
|
||||
qDebug() << "Uncompressed buffer probe" << gst_caps_to_string(GST_BUFFER_CAPS(buffer));
|
||||
#endif
|
||||
|
||||
QCameraImageCapture::CaptureDestinations destination =
|
||||
session->captureDestinationControl()->captureDestination();
|
||||
QVideoFrame::PixelFormat format = session->captureBufferFormatControl()->bufferFormat();
|
||||
|
||||
if (destination & QCameraImageCapture::CaptureToBuffer) {
|
||||
if (format != QVideoFrame::Format_Jpeg) {
|
||||
GstCaps *caps = GST_BUFFER_CAPS(buffer);
|
||||
int bytesPerLine = -1;
|
||||
QVideoSurfaceFormat format = QVideoSurfaceGstSink::formatForCaps(caps, &bytesPerLine);
|
||||
#ifdef DEBUG_CAPTURE
|
||||
qDebug() << "imageAvailable(uncompressed):" << format;
|
||||
#endif
|
||||
QGstVideoBuffer *videoBuffer = new QGstVideoBuffer(buffer, bytesPerLine);
|
||||
|
||||
QVideoFrame frame(videoBuffer,
|
||||
format.frameSize(),
|
||||
format.pixelFormat());
|
||||
|
||||
QMetaObject::invokeMethod(self, "imageAvailable",
|
||||
Qt::QueuedConnection,
|
||||
Q_ARG(int, self->m_requestId),
|
||||
Q_ARG(QVideoFrame, frame));
|
||||
}
|
||||
}
|
||||
|
||||
//keep the buffer if capture to file or jpeg buffer capture was reuqsted
|
||||
bool keepBuffer = (destination & QCameraImageCapture::CaptureToFile) ||
|
||||
((destination & QCameraImageCapture::CaptureToBuffer) &&
|
||||
format == QVideoFrame::Format_Jpeg);
|
||||
|
||||
return keepBuffer;
|
||||
}
|
||||
|
||||
gboolean CameraBinImageCapture::jpegBufferProbe(GstPad *pad, GstBuffer *buffer, CameraBinImageCapture *self)
|
||||
{
|
||||
Q_UNUSED(pad);
|
||||
CameraBinSession *session = self->m_session;
|
||||
|
||||
#ifdef DEBUG_CAPTURE
|
||||
qDebug() << "Jpeg buffer probe" << gst_caps_to_string(GST_BUFFER_CAPS(buffer));
|
||||
#endif
|
||||
|
||||
QCameraImageCapture::CaptureDestinations destination =
|
||||
session->captureDestinationControl()->captureDestination();
|
||||
|
||||
if ((destination & QCameraImageCapture::CaptureToBuffer) &&
|
||||
session->captureBufferFormatControl()->bufferFormat() == QVideoFrame::Format_Jpeg) {
|
||||
QGstVideoBuffer *videoBuffer = new QGstVideoBuffer(buffer,
|
||||
-1); //bytesPerLine is not available for jpegs
|
||||
|
||||
QSize resolution = QGstUtils::capsCorrectedResolution(GST_BUFFER_CAPS(buffer));
|
||||
//if resolution is not presented in caps, try to find it from encoded jpeg data:
|
||||
if (resolution.isEmpty()) {
|
||||
QBuffer data;
|
||||
data.setData(reinterpret_cast<const char*>(GST_BUFFER_DATA(buffer)), GST_BUFFER_SIZE(buffer));
|
||||
QImageReader reader(&data, "JPEG");
|
||||
resolution = reader.size();
|
||||
}
|
||||
|
||||
QVideoFrame frame(videoBuffer,
|
||||
resolution,
|
||||
QVideoFrame::Format_Jpeg);
|
||||
|
||||
QMetaObject::invokeMethod(self, "imageAvailable",
|
||||
Qt::QueuedConnection,
|
||||
Q_ARG(int, self->m_requestId),
|
||||
Q_ARG(QVideoFrame, frame));
|
||||
}
|
||||
|
||||
//drop the buffer if capture to file was disabled
|
||||
return destination & QCameraImageCapture::CaptureToFile;
|
||||
}
|
||||
|
||||
void CameraBinImageCapture::handleBusMessage(const QGstreamerMessage &message)
|
||||
{
|
||||
//Install metadata event and buffer probes
|
||||
|
||||
//The image capture pipiline is built dynamically,
|
||||
//it's necessary to wait until jpeg encoder is added to pipeline
|
||||
|
||||
GstMessage *gm = message.rawMessage();
|
||||
if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_STATE_CHANGED) {
|
||||
GstState oldState;
|
||||
GstState newState;
|
||||
GstState pending;
|
||||
gst_message_parse_state_changed(gm, &oldState, &newState, &pending);
|
||||
|
||||
if (newState == GST_STATE_READY) {
|
||||
GstElement *element = GST_ELEMENT(GST_MESSAGE_SRC(gm));
|
||||
if (!element)
|
||||
return;
|
||||
|
||||
QString elementName = QString::fromLatin1(gst_element_get_name(element));
|
||||
if (elementName.contains("jpegenc") && element != m_jpegEncoderElement) {
|
||||
m_jpegEncoderElement = element;
|
||||
GstPad *sinkpad = gst_element_get_static_pad(element, "sink");
|
||||
|
||||
//metadata event probe is installed before jpeg encoder
|
||||
//to emit metadata available signal as soon as possible.
|
||||
#ifdef DEBUG_CAPTURE
|
||||
qDebug() << "install metadata probe";
|
||||
#endif
|
||||
gst_pad_add_event_probe(sinkpad,
|
||||
G_CALLBACK(CameraBinImageCapture::metadataEventProbe),
|
||||
this);
|
||||
|
||||
#ifdef DEBUG_CAPTURE
|
||||
qDebug() << "install uncompressed buffer probe";
|
||||
#endif
|
||||
gst_pad_add_buffer_probe(sinkpad,
|
||||
G_CALLBACK(CameraBinImageCapture::uncompressedBufferProbe),
|
||||
this);
|
||||
|
||||
gst_object_unref(sinkpad);
|
||||
} else if ((elementName.contains("jifmux") || elementName.startsWith("metadatamux"))
|
||||
&& element != m_metadataMuxerElement) {
|
||||
//Jpeg encoded buffer probe is added after jifmux/metadatamux
|
||||
//element to ensure the resulting jpeg buffer contains capture metadata
|
||||
m_metadataMuxerElement = element;
|
||||
|
||||
GstPad *srcpad = gst_element_get_static_pad(element, "src");
|
||||
#ifdef DEBUG_CAPTURE
|
||||
qDebug() << "install jpeg buffer probe";
|
||||
#endif
|
||||
gst_pad_add_buffer_probe(srcpad,
|
||||
G_CALLBACK(CameraBinImageCapture::jpegBufferProbe),
|
||||
this);
|
||||
gst_object_unref(srcpad);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
82
src/plugins/gstreamer/camerabin/camerabinimagecapture.h
Normal file
82
src/plugins/gstreamer/camerabin/camerabinimagecapture.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2009 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 CAMERABINIMAGECAPTURECONTROL_H
|
||||
#define CAMERABINIMAGECAPTURECONTROL_H
|
||||
|
||||
#include <qcameraimagecapturecontrol.h>
|
||||
#include "camerabinsession.h"
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class CameraBinImageCapture : public QCameraImageCaptureControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CameraBinImageCapture(CameraBinSession *session);
|
||||
virtual ~CameraBinImageCapture();
|
||||
|
||||
QCameraImageCapture::DriveMode driveMode() const { return QCameraImageCapture::SingleImageCapture; }
|
||||
void setDriveMode(QCameraImageCapture::DriveMode) {}
|
||||
|
||||
bool isReadyForCapture() const;
|
||||
int capture(const QString &fileName);
|
||||
void cancelCapture();
|
||||
|
||||
private slots:
|
||||
void updateState();
|
||||
void handleBusMessage(const QGstreamerMessage &message);
|
||||
|
||||
private:
|
||||
static gboolean metadataEventProbe(GstPad *pad, GstEvent *event, CameraBinImageCapture *);
|
||||
static gboolean uncompressedBufferProbe(GstPad *pad, GstBuffer *buffer, CameraBinImageCapture *);
|
||||
static gboolean jpegBufferProbe(GstPad *pad, GstBuffer *buffer, CameraBinImageCapture *);
|
||||
static gboolean handleImageSaved(GstElement *camera, const gchar *filename, CameraBinImageCapture *);
|
||||
|
||||
CameraBinSession *m_session;
|
||||
bool m_ready;
|
||||
int m_requestId;
|
||||
GstElement *m_jpegEncoderElement;
|
||||
GstElement *m_metadataMuxerElement;
|
||||
};
|
||||
|
||||
#endif // CAMERABINCAPTURECORNTROL_H
|
||||
87
src/plugins/gstreamer/camerabin/camerabinimageencoder.cpp
Normal file
87
src/plugins/gstreamer/camerabin/camerabinimageencoder.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2009 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 "camerabinimageencoder.h"
|
||||
#include "camerabinsession.h"
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
|
||||
CameraBinImageEncoder::CameraBinImageEncoder(CameraBinSession *session)
|
||||
:QImageEncoderControl(session), m_session(session)
|
||||
{
|
||||
}
|
||||
|
||||
CameraBinImageEncoder::~CameraBinImageEncoder()
|
||||
{
|
||||
}
|
||||
|
||||
QList<QSize> CameraBinImageEncoder::supportedResolutions(const QImageEncoderSettings &, bool *continuous) const
|
||||
{
|
||||
qDebug() << "CameraBinImageEncoder::supportedResolutions()";
|
||||
if (continuous)
|
||||
*continuous = false;
|
||||
|
||||
return m_session->supportedResolutions(qMakePair<int,int>(0,0), continuous, QCamera::CaptureStillImage);
|
||||
}
|
||||
|
||||
QStringList CameraBinImageEncoder::supportedImageCodecs() const
|
||||
{
|
||||
return QStringList() << "jpeg";
|
||||
}
|
||||
|
||||
QString CameraBinImageEncoder::imageCodecDescription(const QString &codecName) const
|
||||
{
|
||||
if (codecName == "jpeg")
|
||||
return tr("JPEG image");
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
QImageEncoderSettings CameraBinImageEncoder::imageSettings() const
|
||||
{
|
||||
return m_settings;
|
||||
}
|
||||
|
||||
void CameraBinImageEncoder::setImageSettings(const QImageEncoderSettings &settings)
|
||||
{
|
||||
m_settings = settings;
|
||||
emit settingsChanged();
|
||||
}
|
||||
86
src/plugins/gstreamer/camerabin/camerabinimageencoder.h
Normal file
86
src/plugins/gstreamer/camerabin/camerabinimageencoder.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2009 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 CAMERABINIMAGEENCODE_H
|
||||
#define CAMERABINIMAGEENCODE_H
|
||||
|
||||
class CameraBinSession;
|
||||
|
||||
#include <qimageencodercontrol.h>
|
||||
|
||||
#include <QtCore/qstringlist.h>
|
||||
#include <QtCore/qmap.h>
|
||||
|
||||
#include <gst/gst.h>
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class CameraBinImageEncoder : public QImageEncoderControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CameraBinImageEncoder(CameraBinSession *session);
|
||||
virtual ~CameraBinImageEncoder();
|
||||
|
||||
QList<QSize> supportedResolutions(const QImageEncoderSettings &settings = QImageEncoderSettings(),
|
||||
bool *continuous = 0) const;
|
||||
|
||||
QStringList supportedImageCodecs() const;
|
||||
QString imageCodecDescription(const QString &formatName) const;
|
||||
|
||||
QImageEncoderSettings imageSettings() const;
|
||||
void setImageSettings(const QImageEncoderSettings &settings);
|
||||
|
||||
Q_SIGNALS:
|
||||
void settingsChanged();
|
||||
|
||||
private:
|
||||
QImageEncoderSettings m_settings;
|
||||
|
||||
CameraBinSession *m_session;
|
||||
|
||||
// Added
|
||||
QStringList m_codecs;
|
||||
QMap<QString,QByteArray> m_elementNames;
|
||||
QMap<QString,QString> m_codecDescriptions;
|
||||
QMap<QString,QStringList> m_codecOptions;
|
||||
};
|
||||
|
||||
#endif
|
||||
171
src/plugins/gstreamer/camerabin/camerabinimageprocessing.cpp
Normal file
171
src/plugins/gstreamer/camerabin/camerabinimageprocessing.cpp
Normal file
@@ -0,0 +1,171 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2009 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 "camerabinimageprocessing.h"
|
||||
#include "camerabinsession.h"
|
||||
|
||||
CameraBinImageProcessing::CameraBinImageProcessing(CameraBinSession *session)
|
||||
:QCameraImageProcessingControl(session),
|
||||
m_session(session)
|
||||
{
|
||||
m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_AUTO] = QCameraImageProcessing::WhiteBalanceAuto;
|
||||
m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_DAYLIGHT] = QCameraImageProcessing::WhiteBalanceSunlight;
|
||||
m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_CLOUDY] = QCameraImageProcessing::WhiteBalanceCloudy;
|
||||
m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_SUNSET] = QCameraImageProcessing::WhiteBalanceSunset;
|
||||
m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_TUNGSTEN] = QCameraImageProcessing::WhiteBalanceTungsten;
|
||||
m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_FLUORESCENT] = QCameraImageProcessing::WhiteBalanceFluorescent;
|
||||
|
||||
updateColorBalanceValues();
|
||||
}
|
||||
|
||||
CameraBinImageProcessing::~CameraBinImageProcessing()
|
||||
{
|
||||
}
|
||||
|
||||
void CameraBinImageProcessing::updateColorBalanceValues()
|
||||
{
|
||||
if (!GST_IS_COLOR_BALANCE(m_session->cameraBin())) {
|
||||
// Camerabin doesn't implement gstcolorbalance interface
|
||||
return;
|
||||
}
|
||||
|
||||
GstColorBalance *balance = GST_COLOR_BALANCE(m_session->cameraBin());
|
||||
const GList *controls = gst_color_balance_list_channels(balance);
|
||||
|
||||
const GList *item;
|
||||
GstColorBalanceChannel *channel;
|
||||
gint cur_value;
|
||||
|
||||
for (item = controls; item; item = g_list_next (item)) {
|
||||
channel = (GstColorBalanceChannel *)item->data;
|
||||
cur_value = gst_color_balance_get_value (balance, channel);
|
||||
|
||||
if (!g_ascii_strcasecmp (channel->label, "brightness")) {
|
||||
m_values[QCameraImageProcessingControl::Brightness] = cur_value;
|
||||
} else if (!g_ascii_strcasecmp (channel->label, "contrast")) {
|
||||
m_values[QCameraImageProcessingControl::Contrast] = cur_value;
|
||||
} else if (!g_ascii_strcasecmp (channel->label, "saturation")) {
|
||||
m_values[QCameraImageProcessingControl::Saturation] = cur_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CameraBinImageProcessing::setColorBalanceValue(const QString& channel, int value)
|
||||
{
|
||||
|
||||
if (!GST_IS_COLOR_BALANCE(m_session->cameraBin())) {
|
||||
// Camerabin doesn't implement gstcolorbalance interface
|
||||
return false;
|
||||
}
|
||||
|
||||
GstColorBalance *balance = GST_COLOR_BALANCE(m_session->cameraBin());
|
||||
const GList *controls = gst_color_balance_list_channels(balance);
|
||||
|
||||
const GList *item;
|
||||
GstColorBalanceChannel *colorBalanceChannel;
|
||||
|
||||
for (item = controls; item; item = g_list_next (item)) {
|
||||
colorBalanceChannel = (GstColorBalanceChannel *)item->data;
|
||||
|
||||
if (!g_ascii_strcasecmp (colorBalanceChannel->label, channel.toAscii())) {
|
||||
gst_color_balance_set_value (balance, colorBalanceChannel, value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QCameraImageProcessing::WhiteBalanceMode CameraBinImageProcessing::whiteBalanceMode() const
|
||||
{
|
||||
GstWhiteBalanceMode wbMode;
|
||||
gst_photography_get_white_balance_mode(m_session->photography(), &wbMode);
|
||||
return m_mappedWbValues[wbMode];
|
||||
}
|
||||
|
||||
void CameraBinImageProcessing::setWhiteBalanceMode(QCameraImageProcessing::WhiteBalanceMode mode)
|
||||
{
|
||||
if (isWhiteBalanceModeSupported(mode))
|
||||
gst_photography_set_white_balance_mode(m_session->photography(), m_mappedWbValues.key(mode));
|
||||
}
|
||||
|
||||
bool CameraBinImageProcessing::isWhiteBalanceModeSupported(QCameraImageProcessing::WhiteBalanceMode mode) const
|
||||
{
|
||||
return m_mappedWbValues.values().contains(mode);
|
||||
}
|
||||
|
||||
bool CameraBinImageProcessing::isProcessingParameterSupported(QCameraImageProcessingControl::ProcessingParameter parameter) const
|
||||
{
|
||||
return parameter == QCameraImageProcessingControl::Contrast
|
||||
|| parameter == QCameraImageProcessingControl::Brightness
|
||||
|| parameter == QCameraImageProcessingControl::Saturation;
|
||||
}
|
||||
|
||||
QVariant CameraBinImageProcessing::processingParameter(
|
||||
QCameraImageProcessingControl::ProcessingParameter parameter) const
|
||||
{
|
||||
if (m_values.contains(parameter))
|
||||
return m_values.value(parameter);
|
||||
else
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void CameraBinImageProcessing::setProcessingParameter(
|
||||
QCameraImageProcessingControl::ProcessingParameter parameter,
|
||||
QVariant value)
|
||||
{
|
||||
switch (parameter) {
|
||||
case Contrast:
|
||||
setColorBalanceValue("contrast", value.toInt());
|
||||
break;
|
||||
case Brightness:
|
||||
setColorBalanceValue("brightness", value.toInt());
|
||||
break;
|
||||
case Saturation:
|
||||
setColorBalanceValue("saturation", value.toInt());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
updateColorBalanceValues();
|
||||
}
|
||||
|
||||
84
src/plugins/gstreamer/camerabin/camerabinimageprocessing.h
Normal file
84
src/plugins/gstreamer/camerabin/camerabinimageprocessing.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2009 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 CAMERABINIMAGEPROCESSINGCONTROL_H
|
||||
#define CAMERABINIMAGEPROCESSINGCONTROL_H
|
||||
|
||||
#include <qcamera.h>
|
||||
#include <qcameraimageprocessingcontrol.h>
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include <gst/interfaces/photography.h>
|
||||
#include <gst/interfaces/colorbalance.h>
|
||||
|
||||
class CameraBinSession;
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class CameraBinImageProcessing : public QCameraImageProcessingControl
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CameraBinImageProcessing(CameraBinSession *session);
|
||||
virtual ~CameraBinImageProcessing();
|
||||
|
||||
QCameraImageProcessing::WhiteBalanceMode whiteBalanceMode() const;
|
||||
void setWhiteBalanceMode(QCameraImageProcessing::WhiteBalanceMode mode);
|
||||
bool isWhiteBalanceModeSupported(QCameraImageProcessing::WhiteBalanceMode mode) const;
|
||||
|
||||
bool isProcessingParameterSupported(ProcessingParameter) const;
|
||||
QVariant processingParameter(ProcessingParameter parameter) const;
|
||||
void setProcessingParameter(ProcessingParameter parameter, QVariant value);
|
||||
|
||||
private:
|
||||
bool setColorBalanceValue(const QString& channel, int value);
|
||||
void updateColorBalanceValues();
|
||||
|
||||
private:
|
||||
CameraBinSession *m_session;
|
||||
QMap<QCameraImageProcessingControl::ProcessingParameter, int> m_values;
|
||||
QMap<GstWhiteBalanceMode, QCameraImageProcessing::WhiteBalanceMode> m_mappedWbValues;
|
||||
};
|
||||
|
||||
#endif // CAMERABINIMAGEPROCESSINGCONTROL_H
|
||||
88
src/plugins/gstreamer/camerabin/camerabinlocks.cpp
Normal file
88
src/plugins/gstreamer/camerabin/camerabinlocks.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2009 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 "camerabinlocks.h"
|
||||
#include "camerabinsession.h"
|
||||
#include "camerabinfocus.h"
|
||||
|
||||
#include <gst/interfaces/photography.h>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
CameraBinLocks::CameraBinLocks(CameraBinSession *session)
|
||||
:QCameraLocksControl(session),
|
||||
m_session(session),
|
||||
m_focus(m_session->cameraFocusControl())
|
||||
{
|
||||
connect(m_focus, SIGNAL(_q_focusStatusChanged(QCamera::LockStatus, QCamera::LockChangeReason)),
|
||||
this, SLOT(updateFocusStatus(QCamera::LockStatus, QCamera::LockChangeReason)));
|
||||
}
|
||||
|
||||
CameraBinLocks::~CameraBinLocks()
|
||||
{
|
||||
}
|
||||
|
||||
QCamera::LockTypes CameraBinLocks::supportedLocks() const
|
||||
{
|
||||
return QCamera::LockFocus;
|
||||
}
|
||||
|
||||
QCamera::LockStatus CameraBinLocks::lockStatus(QCamera::LockType lock) const
|
||||
{
|
||||
return lock == QCamera::LockFocus ? m_focus->focusStatus() : QCamera::Unlocked;
|
||||
}
|
||||
|
||||
void CameraBinLocks::searchAndLock(QCamera::LockTypes locks)
|
||||
{
|
||||
if (locks & QCamera::LockFocus)
|
||||
m_focus->_q_startFocusing();
|
||||
}
|
||||
|
||||
void CameraBinLocks::unlock(QCamera::LockTypes locks)
|
||||
{
|
||||
if (locks & QCamera::LockFocus)
|
||||
m_focus->_q_stopFocusing();
|
||||
}
|
||||
|
||||
void CameraBinLocks::updateFocusStatus(QCamera::LockStatus status, QCamera::LockChangeReason reason)
|
||||
{
|
||||
emit lockStatusChanged(QCamera::LockFocus, status, reason);
|
||||
}
|
||||
79
src/plugins/gstreamer/camerabin/camerabinlocks.h
Normal file
79
src/plugins/gstreamer/camerabin/camerabinlocks.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2009 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 CAMERABINLOCKSCONTROL_H
|
||||
#define CAMERABINLOCKSCONTROL_H
|
||||
|
||||
#include <qcamera.h>
|
||||
#include <qcameralockscontrol.h>
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <glib.h>
|
||||
|
||||
class CameraBinSession;
|
||||
class CameraBinFocus;
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class CameraBinLocks : public QCameraLocksControl
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CameraBinLocks(CameraBinSession *session);
|
||||
virtual ~CameraBinLocks();
|
||||
|
||||
QCamera::LockTypes supportedLocks() const;
|
||||
|
||||
QCamera::LockStatus lockStatus(QCamera::LockType lock) const;
|
||||
|
||||
void searchAndLock(QCamera::LockTypes locks);
|
||||
void unlock(QCamera::LockTypes locks);
|
||||
|
||||
private slots:
|
||||
void updateFocusStatus(QCamera::LockStatus status, QCamera::LockChangeReason reason);
|
||||
|
||||
private:
|
||||
CameraBinSession *m_session;
|
||||
CameraBinFocus *m_focus;
|
||||
};
|
||||
|
||||
#endif
|
||||
198
src/plugins/gstreamer/camerabin/camerabinmetadata.cpp
Normal file
198
src/plugins/gstreamer/camerabin/camerabinmetadata.cpp
Normal file
@@ -0,0 +1,198 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "camerabinmetadata.h"
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/gstversion.h>
|
||||
|
||||
struct QGstreamerMetaDataKeyLookup
|
||||
{
|
||||
QtMultimediaKit::MetaData key;
|
||||
const char *token;
|
||||
};
|
||||
|
||||
static const QGstreamerMetaDataKeyLookup qt_gstreamerMetaDataKeys[] =
|
||||
{
|
||||
{ QtMultimediaKit::Title, GST_TAG_TITLE },
|
||||
//{ QtMultimediaKit::SubTitle, 0 },
|
||||
//{ QtMultimediaKit::Author, 0 },
|
||||
{ QtMultimediaKit::Comment, GST_TAG_COMMENT },
|
||||
{ QtMultimediaKit::Description, GST_TAG_DESCRIPTION },
|
||||
//{ QtMultimediaKit::Category, 0 },
|
||||
{ QtMultimediaKit::Genre, GST_TAG_GENRE },
|
||||
//{ QtMultimediaKit::Year, 0 },
|
||||
//{ QtMultimediaKit::UserRating, 0 },
|
||||
|
||||
{ QtMultimediaKit::Language, GST_TAG_LANGUAGE_CODE },
|
||||
|
||||
{ QtMultimediaKit::Publisher, GST_TAG_ORGANIZATION },
|
||||
{ QtMultimediaKit::Copyright, GST_TAG_COPYRIGHT },
|
||||
//{ QtMultimediaKit::ParentalRating, 0 },
|
||||
//{ QtMultimediaKit::RatingOrganisation, 0 },
|
||||
|
||||
// Media
|
||||
//{ QtMultimediaKit::Size, 0 },
|
||||
//{ QtMultimediaKit::MediaType, 0 },
|
||||
{ QtMultimediaKit::Duration, GST_TAG_DURATION },
|
||||
|
||||
// Audio
|
||||
{ QtMultimediaKit::AudioBitRate, GST_TAG_BITRATE },
|
||||
{ QtMultimediaKit::AudioCodec, GST_TAG_AUDIO_CODEC },
|
||||
//{ QtMultimediaKit::ChannelCount, 0 },
|
||||
//{ QtMultimediaKit::SampleRate, 0 },
|
||||
|
||||
// Music
|
||||
{ QtMultimediaKit::AlbumTitle, GST_TAG_ALBUM },
|
||||
{ QtMultimediaKit::AlbumArtist, GST_TAG_ARTIST},
|
||||
{ QtMultimediaKit::ContributingArtist, GST_TAG_PERFORMER },
|
||||
#if (GST_VERSION_MAJOR >= 0) && (GST_VERSION_MINOR >= 10) && (GST_VERSION_MICRO >= 19)
|
||||
{ QtMultimediaKit::Composer, GST_TAG_COMPOSER },
|
||||
#endif
|
||||
//{ QtMultimediaKit::Conductor, 0 },
|
||||
//{ QtMultimediaKit::Lyrics, 0 },
|
||||
//{ QtMultimediaKit::Mood, 0 },
|
||||
{ QtMultimediaKit::TrackNumber, GST_TAG_TRACK_NUMBER },
|
||||
|
||||
//{ QtMultimediaKit::CoverArtUrlSmall, 0 },
|
||||
//{ QtMultimediaKit::CoverArtUrlLarge, 0 },
|
||||
|
||||
// Image/Video
|
||||
//{ QtMultimediaKit::Resolution, 0 },
|
||||
//{ QtMultimediaKit::PixelAspectRatio, 0 },
|
||||
|
||||
// Video
|
||||
//{ QtMultimediaKit::VideoFrameRate, 0 },
|
||||
//{ QtMultimediaKit::VideoBitRate, 0 },
|
||||
{ QtMultimediaKit::VideoCodec, GST_TAG_VIDEO_CODEC },
|
||||
|
||||
//{ QtMultimediaKit::PosterUrl, 0 },
|
||||
|
||||
// Movie
|
||||
//{ QtMultimediaKit::ChapterNumber, 0 },
|
||||
//{ QtMultimediaKit::Director, 0 },
|
||||
{ QtMultimediaKit::LeadPerformer, GST_TAG_PERFORMER },
|
||||
//{ QtMultimediaKit::Writer, 0 },
|
||||
|
||||
// Photos
|
||||
//{ QtMultimediaKit::CameraManufacturer, 0 },
|
||||
//{ QtMultimediaKit::CameraModel, 0 },
|
||||
//{ QtMultimediaKit::Event, 0 },
|
||||
//{ QtMultimediaKit::Subject, 0 }
|
||||
};
|
||||
|
||||
CameraBinMetaData::CameraBinMetaData(QObject *parent)
|
||||
:QMetaDataWriterControl(parent)
|
||||
{
|
||||
}
|
||||
|
||||
QVariant CameraBinMetaData::metaData(QtMultimediaKit::MetaData key) const
|
||||
{
|
||||
static const int count = sizeof(qt_gstreamerMetaDataKeys) / sizeof(QGstreamerMetaDataKeyLookup);
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
if (qt_gstreamerMetaDataKeys[i].key == key) {
|
||||
const char *name = qt_gstreamerMetaDataKeys[i].token;
|
||||
|
||||
return m_values.value(QByteArray::fromRawData(name, qstrlen(name)));
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void CameraBinMetaData::setMetaData(QtMultimediaKit::MetaData key, const QVariant &value)
|
||||
{
|
||||
static const int count = sizeof(qt_gstreamerMetaDataKeys) / sizeof(QGstreamerMetaDataKeyLookup);
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
if (qt_gstreamerMetaDataKeys[i].key == key) {
|
||||
const char *name = qt_gstreamerMetaDataKeys[i].token;
|
||||
|
||||
m_values.insert(QByteArray::fromRawData(name, qstrlen(name)), value);
|
||||
|
||||
emit QMetaDataWriterControl::metaDataChanged();
|
||||
emit metaDataChanged(m_values);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QList<QtMultimediaKit::MetaData> CameraBinMetaData::availableMetaData() const
|
||||
{
|
||||
static QMap<QByteArray, QtMultimediaKit::MetaData> keysMap;
|
||||
if (keysMap.isEmpty()) {
|
||||
const int count = sizeof(qt_gstreamerMetaDataKeys) / sizeof(QGstreamerMetaDataKeyLookup);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
keysMap[QByteArray(qt_gstreamerMetaDataKeys[i].token)] = qt_gstreamerMetaDataKeys[i].key;
|
||||
}
|
||||
}
|
||||
|
||||
QList<QtMultimediaKit::MetaData> res;
|
||||
foreach (const QByteArray &key, m_values.keys()) {
|
||||
QtMultimediaKit::MetaData tag = keysMap.value(key, QtMultimediaKit::MetaData(-1));
|
||||
if (tag != -1)
|
||||
res.append(tag);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
QVariant CameraBinMetaData::extendedMetaData(QString const &name) const
|
||||
{
|
||||
return m_values.value(name.toLatin1());
|
||||
}
|
||||
|
||||
void CameraBinMetaData::setExtendedMetaData(QString const &name, QVariant const &value)
|
||||
{
|
||||
m_values.insert(name.toLatin1(), value);
|
||||
emit QMetaDataWriterControl::metaDataChanged();
|
||||
emit metaDataChanged(m_values);
|
||||
}
|
||||
|
||||
QStringList CameraBinMetaData::availableExtendedMetaData() const
|
||||
{
|
||||
QStringList res;
|
||||
foreach (const QByteArray &key, m_values.keys())
|
||||
res.append(QString(key));
|
||||
|
||||
return res;
|
||||
}
|
||||
75
src/plugins/gstreamer/camerabin/camerabinmetadata.h
Normal file
75
src/plugins/gstreamer/camerabin/camerabinmetadata.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 CAMERABINCAPTUREMETADATACONTROL_H
|
||||
#define CAMERABINCAPTUREMETADATACONTROL_H
|
||||
|
||||
#include <qmetadatawritercontrol.h>
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class CameraBinMetaData : public QMetaDataWriterControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CameraBinMetaData(QObject *parent);
|
||||
virtual ~CameraBinMetaData() {}
|
||||
|
||||
|
||||
bool isMetaDataAvailable() const { return true; }
|
||||
bool isWritable() const { return true; }
|
||||
|
||||
QVariant metaData(QtMultimediaKit::MetaData key) const;
|
||||
void setMetaData(QtMultimediaKit::MetaData key, const QVariant &value);
|
||||
QList<QtMultimediaKit::MetaData> availableMetaData() const;
|
||||
|
||||
QVariant extendedMetaData(QString const &name) const;
|
||||
void setExtendedMetaData(QString const &name, QVariant const &value);
|
||||
QStringList availableExtendedMetaData() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void metaDataChanged(const QMap<QByteArray, QVariant>&);
|
||||
|
||||
private:
|
||||
QMap<QByteArray, QVariant> m_values;
|
||||
};
|
||||
|
||||
#endif // CAMERABINCAPTUREMETADATACONTROL_H
|
||||
225
src/plugins/gstreamer/camerabin/camerabinrecorder.cpp
Normal file
225
src/plugins/gstreamer/camerabin/camerabinrecorder.cpp
Normal file
@@ -0,0 +1,225 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "camerabinrecorder.h"
|
||||
#include "camerabinaudioencoder.h"
|
||||
#include "camerabinvideoencoder.h"
|
||||
#include "camerabincontainer.h"
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
CameraBinRecorder::CameraBinRecorder(CameraBinSession *session)
|
||||
:QMediaRecorderControl(session),
|
||||
m_session(session),
|
||||
m_state(QMediaRecorder::StoppedState)
|
||||
{
|
||||
connect(m_session, SIGNAL(stateChanged(QCamera::State)), SLOT(updateState()));
|
||||
connect(m_session, SIGNAL(durationChanged(qint64)), SIGNAL(durationChanged(qint64)));
|
||||
connect(m_session, SIGNAL(mutedChanged(bool)), this, SIGNAL(mutedChanged(bool)));
|
||||
}
|
||||
|
||||
CameraBinRecorder::~CameraBinRecorder()
|
||||
{
|
||||
}
|
||||
|
||||
QUrl CameraBinRecorder::outputLocation() const
|
||||
{
|
||||
return m_session->outputLocation();
|
||||
}
|
||||
|
||||
bool CameraBinRecorder::setOutputLocation(const QUrl &sink)
|
||||
{
|
||||
m_session->setOutputLocation(sink);
|
||||
return true;
|
||||
}
|
||||
|
||||
QMediaRecorder::State CameraBinRecorder::state() const
|
||||
{
|
||||
return m_state;
|
||||
}
|
||||
|
||||
void CameraBinRecorder::updateState()
|
||||
{
|
||||
if (m_session->state() != QCamera::ActiveState &&
|
||||
m_state != QMediaRecorder::StoppedState) {
|
||||
m_session->stopVideoRecording();
|
||||
emit stateChanged(m_state = QMediaRecorder::StoppedState);
|
||||
}
|
||||
}
|
||||
|
||||
qint64 CameraBinRecorder::duration() const
|
||||
{
|
||||
return m_session->duration();
|
||||
}
|
||||
|
||||
void CameraBinRecorder::record()
|
||||
{
|
||||
if (m_session->state() == QCamera::ActiveState) {
|
||||
if (m_state == QMediaRecorder::PausedState)
|
||||
m_session->resumeVideoRecording();
|
||||
else
|
||||
m_session->recordVideo();
|
||||
emit stateChanged(m_state = QMediaRecorder::RecordingState);
|
||||
} else
|
||||
emit error(QMediaRecorder::ResourceError, tr("Service has not been started"));
|
||||
}
|
||||
|
||||
void CameraBinRecorder::pause()
|
||||
{
|
||||
if (m_session->state() == QCamera::ActiveState) {
|
||||
m_session->pauseVideoRecording();
|
||||
emit stateChanged(m_state = QMediaRecorder::PausedState);
|
||||
} else
|
||||
emit error(QMediaRecorder::ResourceError, tr("Service has not been started"));
|
||||
}
|
||||
|
||||
void CameraBinRecorder::stop()
|
||||
{
|
||||
if (m_session->state() == QCamera::ActiveState) {
|
||||
m_session->stopVideoRecording();
|
||||
emit stateChanged(m_state = QMediaRecorder::StoppedState);
|
||||
}
|
||||
}
|
||||
|
||||
bool CameraBinRecorder::findCodecs()
|
||||
{
|
||||
//Check the codecs are compatible with container,
|
||||
//and choose the compatible codecs/container if omitted
|
||||
CameraBinAudioEncoder *audioEncodeControl = m_session->audioEncodeControl();
|
||||
CameraBinVideoEncoder *videoEncodeControl = m_session->videoEncodeControl();
|
||||
CameraBinContainer *mediaContainerControl = m_session->mediaContainerControl();
|
||||
|
||||
audioEncodeControl->resetActualSettings();
|
||||
videoEncodeControl->resetActualSettings();
|
||||
mediaContainerControl->resetActualContainer();
|
||||
|
||||
QStringList containerCandidates;
|
||||
if (mediaContainerControl->containerMimeType().isEmpty())
|
||||
containerCandidates = mediaContainerControl->supportedContainers();
|
||||
else
|
||||
containerCandidates << mediaContainerControl->containerMimeType();
|
||||
|
||||
|
||||
QStringList audioCandidates;
|
||||
QAudioEncoderSettings audioSettings = audioEncodeControl->audioSettings();
|
||||
if (audioSettings.codec().isEmpty())
|
||||
audioCandidates = audioEncodeControl->supportedAudioCodecs();
|
||||
else
|
||||
audioCandidates << audioSettings.codec();
|
||||
|
||||
QStringList videoCandidates;
|
||||
QVideoEncoderSettings videoSettings = videoEncodeControl->videoSettings();
|
||||
if (videoSettings.codec().isEmpty())
|
||||
videoCandidates = videoEncodeControl->supportedVideoCodecs();
|
||||
else
|
||||
videoCandidates << videoSettings.codec();
|
||||
|
||||
QString container;
|
||||
QString audioCodec;
|
||||
QString videoCodec;
|
||||
|
||||
foreach (const QString &containerCandidate, containerCandidates) {
|
||||
QSet<QString> supportedTypes = mediaContainerControl->supportedStreamTypes(containerCandidate);
|
||||
|
||||
audioCodec.clear();
|
||||
videoCodec.clear();
|
||||
|
||||
bool found = false;
|
||||
foreach (const QString &audioCandidate, audioCandidates) {
|
||||
QSet<QString> audioTypes = audioEncodeControl->supportedStreamTypes(audioCandidate);
|
||||
if (!audioTypes.intersect(supportedTypes).isEmpty()) {
|
||||
found = true;
|
||||
audioCodec = audioCandidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
continue;
|
||||
|
||||
found = false;
|
||||
foreach (const QString &videoCandidate, videoCandidates) {
|
||||
QSet<QString> videoTypes = videoEncodeControl->supportedStreamTypes(videoCandidate);
|
||||
if (!videoTypes.intersect(supportedTypes).isEmpty()) {
|
||||
found = true;
|
||||
videoCodec = videoCandidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
continue;
|
||||
|
||||
|
||||
container = containerCandidate;
|
||||
break;
|
||||
}
|
||||
|
||||
if (container.isEmpty()) {
|
||||
qWarning() << "Camera error: Not compatible codecs and container format.";
|
||||
emit error(QMediaRecorder::FormatError, tr("Not compatible codecs and container format."));
|
||||
return false;
|
||||
} else {
|
||||
mediaContainerControl->setActualContainer(container);
|
||||
|
||||
QAudioEncoderSettings audioSettings = audioEncodeControl->audioSettings();
|
||||
audioSettings.setCodec(audioCodec);
|
||||
audioEncodeControl->setActualAudioSettings(audioSettings);
|
||||
|
||||
QVideoEncoderSettings videoSettings = videoEncodeControl->videoSettings();
|
||||
videoSettings.setCodec(videoCodec);
|
||||
videoEncodeControl->setActualVideoSettings(videoSettings);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CameraBinRecorder::applySettings()
|
||||
{
|
||||
findCodecs();
|
||||
}
|
||||
|
||||
bool CameraBinRecorder::isMuted() const
|
||||
{
|
||||
return m_session->isMuted();
|
||||
}
|
||||
|
||||
void CameraBinRecorder::setMuted(bool muted)
|
||||
{
|
||||
m_session->setMuted(muted);
|
||||
}
|
||||
85
src/plugins/gstreamer/camerabin/camerabinrecorder.h
Normal file
85
src/plugins/gstreamer/camerabin/camerabinrecorder.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 CAMERABINRECORDERCONTROL_H
|
||||
#define CAMERABINRECORDERCONTROL_H
|
||||
|
||||
#include <qmediarecordercontrol.h>
|
||||
#include "camerabinsession.h"
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class CameraBinRecorder : public QMediaRecorderControl
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CameraBinRecorder(CameraBinSession *session);
|
||||
virtual ~CameraBinRecorder();
|
||||
|
||||
QUrl outputLocation() const;
|
||||
bool setOutputLocation(const QUrl &sink);
|
||||
|
||||
QMediaRecorder::State state() const;
|
||||
|
||||
qint64 duration() const;
|
||||
|
||||
bool isMuted() const;
|
||||
|
||||
bool findCodecs();
|
||||
|
||||
void applySettings();
|
||||
|
||||
public slots:
|
||||
void record();
|
||||
void pause();
|
||||
void stop();
|
||||
void setMuted(bool);
|
||||
|
||||
private slots:
|
||||
void updateState();
|
||||
|
||||
private:
|
||||
CameraBinSession *m_session;
|
||||
QMediaRecorder::State m_state;
|
||||
};
|
||||
|
||||
#endif // CAMERABINCAPTURECORNTROL_H
|
||||
188
src/plugins/gstreamer/camerabin/camerabinresourcepolicy.cpp
Normal file
188
src/plugins/gstreamer/camerabin/camerabinresourcepolicy.cpp
Normal file
@@ -0,0 +1,188 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "camerabinresourcepolicy.h"
|
||||
|
||||
#ifdef Q_WS_MAEMO_6
|
||||
#define HAVE_RESOURCE_POLICY
|
||||
#endif
|
||||
|
||||
//#define DEBUG_RESOURCE_POLICY
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtCore/qset.h>
|
||||
|
||||
#ifdef HAVE_RESOURCE_POLICY
|
||||
#include <policy/resource.h>
|
||||
#include <policy/resources.h>
|
||||
#include <policy/resource-set.h>
|
||||
#endif
|
||||
|
||||
CamerabinResourcePolicy::CamerabinResourcePolicy(QObject *parent) :
|
||||
QObject(parent),
|
||||
m_resourceSet(NoResources),
|
||||
m_releasingResources(false)
|
||||
{
|
||||
#ifdef HAVE_RESOURCE_POLICY
|
||||
//loaded resource set is also kept requested for image and video capture sets
|
||||
m_resource = new ResourcePolicy::ResourceSet("camera");
|
||||
m_resource->setAlwaysReply();
|
||||
m_resource->initAndConnect();
|
||||
|
||||
connect(m_resource, SIGNAL(resourcesGranted(const QList<ResourcePolicy::ResourceType>)),
|
||||
SIGNAL(resourcesGranted()));
|
||||
connect(m_resource, SIGNAL(resourcesDenied()), SIGNAL(resourcesDenied()));
|
||||
connect(m_resource, SIGNAL(lostResources()), SIGNAL(resourcesLost()));
|
||||
connect(m_resource, SIGNAL(resourcesReleased()), SLOT(handleResourcesReleased()));
|
||||
#endif
|
||||
}
|
||||
|
||||
CamerabinResourcePolicy::~CamerabinResourcePolicy()
|
||||
{
|
||||
#ifdef HAVE_RESOURCE_POLICY
|
||||
//ensure the resources are released
|
||||
if (m_resourceSet != NoResources)
|
||||
setResourceSet(NoResources);
|
||||
|
||||
//don't delete the resource set until resources are released
|
||||
if (m_releasingResources) {
|
||||
m_resource->connect(m_resource, SIGNAL(resourcesReleased()),
|
||||
SLOT(deleteLater()));
|
||||
} else {
|
||||
delete m_resource;
|
||||
m_resource = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
CamerabinResourcePolicy::ResourceSet CamerabinResourcePolicy::resourceSet() const
|
||||
{
|
||||
return m_resourceSet;
|
||||
}
|
||||
|
||||
void CamerabinResourcePolicy::setResourceSet(CamerabinResourcePolicy::ResourceSet set)
|
||||
{
|
||||
CamerabinResourcePolicy::ResourceSet oldSet = m_resourceSet;
|
||||
m_resourceSet = set;
|
||||
|
||||
#ifdef DEBUG_RESOURCE_POLICY
|
||||
qDebug() << Q_FUNC_INFO << set;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_RESOURCE_POLICY
|
||||
QSet<ResourcePolicy::ResourceType> requestedTypes;
|
||||
|
||||
switch (set) {
|
||||
case NoResources:
|
||||
break;
|
||||
case LoadedResources:
|
||||
requestedTypes << ResourcePolicy::LensCoverType //to detect lens cover is opened/closed
|
||||
<< ResourcePolicy::VideoRecorderType //to open camera device
|
||||
<< ResourcePolicy::SnapButtonType; //to detect capture button events
|
||||
break;
|
||||
case ImageCaptureResources:
|
||||
requestedTypes << ResourcePolicy::LensCoverType
|
||||
<< ResourcePolicy::VideoPlaybackType
|
||||
<< ResourcePolicy::VideoRecorderType
|
||||
<< ResourcePolicy::AudioPlaybackType
|
||||
<< ResourcePolicy::ScaleButtonType
|
||||
<< ResourcePolicy::LedsType
|
||||
<< ResourcePolicy::SnapButtonType;
|
||||
break;
|
||||
case VideoCaptureResources:
|
||||
requestedTypes << ResourcePolicy::LensCoverType
|
||||
<< ResourcePolicy::VideoPlaybackType
|
||||
<< ResourcePolicy::VideoRecorderType
|
||||
<< ResourcePolicy::AudioPlaybackType
|
||||
<< ResourcePolicy::AudioRecorderType
|
||||
<< ResourcePolicy::ScaleButtonType
|
||||
<< ResourcePolicy::LedsType
|
||||
<< ResourcePolicy::SnapButtonType;
|
||||
break;
|
||||
}
|
||||
|
||||
QSet<ResourcePolicy::ResourceType> currentTypes;
|
||||
foreach (ResourcePolicy::Resource *resource, m_resource->resources())
|
||||
currentTypes << resource->type();
|
||||
|
||||
foreach (ResourcePolicy::ResourceType resourceType, currentTypes - requestedTypes)
|
||||
m_resource->deleteResource(resourceType);
|
||||
|
||||
foreach (ResourcePolicy::ResourceType resourceType, requestedTypes - currentTypes) {
|
||||
if (resourceType == ResourcePolicy::LensCoverType) {
|
||||
ResourcePolicy::LensCoverResource *lensCoverResource = new ResourcePolicy::LensCoverResource;
|
||||
lensCoverResource->setOptional(true);
|
||||
m_resource->addResourceObject(lensCoverResource);
|
||||
} else {
|
||||
m_resource->addResource(resourceType);
|
||||
}
|
||||
}
|
||||
|
||||
m_resource->update();
|
||||
if (set != NoResources) {
|
||||
m_resource->acquire();
|
||||
} else {
|
||||
if (oldSet != NoResources) {
|
||||
m_releasingResources = true;
|
||||
m_resource->release();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CamerabinResourcePolicy::isResourcesGranted() const
|
||||
{
|
||||
#ifdef HAVE_RESOURCE_POLICY
|
||||
foreach (ResourcePolicy::Resource *resource, m_resource->resources())
|
||||
if (!resource->isOptional() && !resource->isGranted())
|
||||
return false;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
void CamerabinResourcePolicy::handleResourcesReleased()
|
||||
{
|
||||
#ifdef HAVE_RESOURCE_POLICY
|
||||
#ifdef DEBUG_RESOURCE_POLICY
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
m_releasingResources = false;
|
||||
#endif
|
||||
}
|
||||
84
src/plugins/gstreamer/camerabin/camerabinresourcepolicy.h
Normal file
84
src/plugins/gstreamer/camerabin/camerabinresourcepolicy.h
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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CAMERARESOURCEPOLICY_H
|
||||
#define CAMERARESOURCEPOLICY_H
|
||||
|
||||
#include <QtCore/qobject.h>
|
||||
|
||||
namespace ResourcePolicy {
|
||||
class ResourceSet;
|
||||
};
|
||||
|
||||
class CamerabinResourcePolicy : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum ResourceSet {
|
||||
NoResources,
|
||||
LoadedResources,
|
||||
ImageCaptureResources,
|
||||
VideoCaptureResources
|
||||
};
|
||||
|
||||
CamerabinResourcePolicy(QObject *parent);
|
||||
~CamerabinResourcePolicy();
|
||||
|
||||
ResourceSet resourceSet() const;
|
||||
void setResourceSet(ResourceSet set);
|
||||
|
||||
bool isResourcesGranted() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void resourcesDenied();
|
||||
void resourcesGranted();
|
||||
void resourcesLost();
|
||||
|
||||
private Q_SLOTS:
|
||||
void handleResourcesReleased();
|
||||
|
||||
private:
|
||||
ResourceSet m_resourceSet;
|
||||
ResourcePolicy::ResourceSet *m_resource;
|
||||
bool m_releasingResources;
|
||||
};
|
||||
|
||||
#endif
|
||||
261
src/plugins/gstreamer/camerabin/camerabinservice.cpp
Normal file
261
src/plugins/gstreamer/camerabin/camerabinservice.cpp
Normal file
@@ -0,0 +1,261 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "camerabinservice.h"
|
||||
#include "camerabinsession.h"
|
||||
#include "camerabinrecorder.h"
|
||||
#include "camerabincontainer.h"
|
||||
#include "camerabinaudioencoder.h"
|
||||
#include "camerabinvideoencoder.h"
|
||||
#include "camerabinimageencoder.h"
|
||||
#include "qgstreamerbushelper.h"
|
||||
#include "camerabincontrol.h"
|
||||
#include "camerabinlocks.h"
|
||||
#include "camerabinmetadata.h"
|
||||
#include "camerabinexposure.h"
|
||||
#include "camerabinflash.h"
|
||||
#include "camerabinfocus.h"
|
||||
#include "camerabinimagecapture.h"
|
||||
#include "camerabinimageprocessing.h"
|
||||
#include "camerabincapturebufferformat.h"
|
||||
#include "camerabincapturedestination.h"
|
||||
|
||||
#include "qgstreameraudioinputendpointselector.h"
|
||||
#include "qgstreamervideoinputdevicecontrol.h"
|
||||
|
||||
#include "qgstreamervideooverlay.h"
|
||||
#include "qgstreamervideowindow.h"
|
||||
#include "qgstreamervideorenderer.h"
|
||||
|
||||
#if defined(Q_WS_MAEMO_6) && defined(__arm__)
|
||||
#include "qgstreamergltexturerenderer.h"
|
||||
#endif
|
||||
|
||||
#include "qgstreamervideowidget.h"
|
||||
|
||||
#include <qmediaserviceprovider.h>
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtCore/qprocess.h>
|
||||
|
||||
#if defined(Q_WS_MAEMO_5)
|
||||
#include "camerabuttonlistener_maemo.h"
|
||||
#endif
|
||||
|
||||
#if defined(Q_WS_MAEMO_6)
|
||||
#include "camerabuttonlistener_meego.h"
|
||||
#endif
|
||||
|
||||
CameraBinService::CameraBinService(const QString &service, QObject *parent):
|
||||
QMediaService(parent)
|
||||
{
|
||||
m_captureSession = 0;
|
||||
m_cameraControl = 0;
|
||||
m_metaDataControl = 0;
|
||||
|
||||
m_audioInputEndpointSelector = 0;
|
||||
m_videoInputDevice = 0;
|
||||
|
||||
m_videoOutput = 0;
|
||||
m_videoRenderer = 0;
|
||||
m_videoWindow = 0;
|
||||
m_videoWidgetControl = 0;
|
||||
m_imageCaptureControl = 0;
|
||||
|
||||
if (service == Q_MEDIASERVICE_CAMERA) {
|
||||
m_captureSession = new CameraBinSession(this);
|
||||
m_cameraControl = new CameraBinControl(m_captureSession);
|
||||
m_videoInputDevice = new QGstreamerVideoInputDeviceControl(m_captureSession);
|
||||
m_imageCaptureControl = new CameraBinImageCapture(m_captureSession);
|
||||
|
||||
connect(m_videoInputDevice, SIGNAL(selectedDeviceChanged(QString)),
|
||||
m_captureSession, SLOT(setDevice(QString)));
|
||||
|
||||
if (m_videoInputDevice->deviceCount())
|
||||
m_captureSession->setDevice(m_videoInputDevice->deviceName(m_videoInputDevice->selectedDevice()));
|
||||
|
||||
#if defined(Q_WS_MAEMO_6) && defined(__arm__)
|
||||
m_videoRenderer = new QGstreamerGLTextureRenderer(this);
|
||||
#else
|
||||
m_videoRenderer = new QGstreamerVideoRenderer(this);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef Q_WS_MAEMO_6
|
||||
m_videoWindow = new QGstreamerVideoWindow(this, "omapxvsink");
|
||||
//m_videoWindow = new QGstreamerVideoWindow(this);
|
||||
#else
|
||||
m_videoWindow = new QGstreamerVideoOverlay(this);
|
||||
#endif
|
||||
|
||||
m_videoWidgetControl = new QGstreamerVideoWidgetControl(this);
|
||||
|
||||
}
|
||||
|
||||
if (!m_captureSession) {
|
||||
qWarning() << Q_FUNC_INFO << "Service type is not supported:" << service;
|
||||
return;
|
||||
}
|
||||
|
||||
m_audioInputEndpointSelector = new QGstreamerAudioInputEndpointSelector(this);
|
||||
connect(m_audioInputEndpointSelector, SIGNAL(activeEndpointChanged(QString)), m_captureSession, SLOT(setCaptureDevice(QString)));
|
||||
|
||||
if (m_captureSession && m_audioInputEndpointSelector->availableEndpoints().size() > 0)
|
||||
m_captureSession->setCaptureDevice(m_audioInputEndpointSelector->defaultEndpoint());
|
||||
|
||||
m_metaDataControl = new CameraBinMetaData(this);
|
||||
connect(m_metaDataControl, SIGNAL(metaDataChanged(QMap<QByteArray,QVariant>)),
|
||||
m_captureSession, SLOT(setMetaData(QMap<QByteArray,QVariant>)));
|
||||
|
||||
#if defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6)
|
||||
new CameraButtonListener(this);
|
||||
#endif
|
||||
|
||||
#if defined(Q_WS_MAEMO_5)
|
||||
//disable the system camera application
|
||||
QProcess::execute("/usr/sbin/dsmetool -k /usr/bin/camera-ui");
|
||||
#endif
|
||||
}
|
||||
|
||||
CameraBinService::~CameraBinService()
|
||||
{
|
||||
#if defined(Q_WS_MAEMO_5)
|
||||
//restore the system camera application
|
||||
QProcess::execute("/usr/sbin/dsmetool -U user -o /usr/bin/camera-ui");
|
||||
#endif
|
||||
}
|
||||
|
||||
QMediaControl *CameraBinService::requestControl(const char *name)
|
||||
{
|
||||
if (!m_captureSession)
|
||||
return 0;
|
||||
|
||||
//qDebug() << "Request control" << name;
|
||||
|
||||
if (!m_videoOutput) {
|
||||
if (qstrcmp(name, QVideoRendererControl_iid) == 0) {
|
||||
m_videoOutput = m_videoRenderer;
|
||||
m_captureSession->setViewfinder(m_videoRenderer);
|
||||
} else if (qstrcmp(name, QVideoWindowControl_iid) == 0) {
|
||||
m_videoOutput = m_videoWindow;
|
||||
m_captureSession->setViewfinder(m_videoWindow);
|
||||
} else if (qstrcmp(name, QVideoWidgetControl_iid) == 0) {
|
||||
m_captureSession->setViewfinder(m_videoWidgetControl);
|
||||
m_videoOutput = m_videoWidgetControl;
|
||||
}
|
||||
|
||||
if (m_videoOutput)
|
||||
return m_videoOutput;
|
||||
}
|
||||
|
||||
if (qstrcmp(name,QAudioEndpointSelector_iid) == 0)
|
||||
return m_audioInputEndpointSelector;
|
||||
|
||||
if (qstrcmp(name,QVideoDeviceControl_iid) == 0)
|
||||
return m_videoInputDevice;
|
||||
|
||||
if (qstrcmp(name,QMediaRecorderControl_iid) == 0)
|
||||
return m_captureSession->recorderControl();
|
||||
|
||||
if (qstrcmp(name,QAudioEncoderControl_iid) == 0)
|
||||
return m_captureSession->audioEncodeControl();
|
||||
|
||||
if (qstrcmp(name,QVideoEncoderControl_iid) == 0)
|
||||
return m_captureSession->videoEncodeControl();
|
||||
|
||||
if (qstrcmp(name,QImageEncoderControl_iid) == 0)
|
||||
return m_captureSession->imageEncodeControl();
|
||||
|
||||
|
||||
if (qstrcmp(name,QMediaContainerControl_iid) == 0)
|
||||
return m_captureSession->mediaContainerControl();
|
||||
|
||||
if (qstrcmp(name,QCameraControl_iid) == 0)
|
||||
return m_cameraControl;
|
||||
|
||||
if (qstrcmp(name,QMetaDataWriterControl_iid) == 0)
|
||||
return m_metaDataControl;
|
||||
|
||||
if (qstrcmp(name, QCameraImageCaptureControl_iid) == 0)
|
||||
return m_imageCaptureControl;
|
||||
|
||||
if (qstrcmp(name, QCameraExposureControl_iid) == 0)
|
||||
return m_captureSession->cameraExposureControl();
|
||||
|
||||
if (qstrcmp(name, QCameraFlashControl_iid) == 0)
|
||||
return m_captureSession->cameraFlashControl();
|
||||
|
||||
if (qstrcmp(name, QCameraFocusControl_iid) == 0)
|
||||
return m_captureSession->cameraFocusControl();
|
||||
|
||||
if (qstrcmp(name, QCameraImageProcessingControl_iid) == 0)
|
||||
return m_captureSession->imageProcessingControl();
|
||||
|
||||
if (qstrcmp(name, QCameraLocksControl_iid) == 0)
|
||||
return m_captureSession->cameraLocksControl();
|
||||
|
||||
if (qstrcmp(name, QCameraCaptureDestinationControl_iid) == 0)
|
||||
return m_captureSession->captureDestinationControl();
|
||||
|
||||
if (qstrcmp(name, QCameraCaptureBufferFormatControl_iid) == 0)
|
||||
return m_captureSession->captureBufferFormatControl();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CameraBinService::releaseControl(QMediaControl *control)
|
||||
{
|
||||
if (control && control == m_videoOutput) {
|
||||
m_videoOutput = 0;
|
||||
m_captureSession->setViewfinder(0);
|
||||
}
|
||||
}
|
||||
|
||||
bool CameraBinService::isCameraBinAvailable()
|
||||
{
|
||||
GstElementFactory *factory = gst_element_factory_find("camerabin");
|
||||
if (factory) {
|
||||
gst_object_unref(GST_OBJECT(factory));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
96
src/plugins/gstreamer/camerabin/camerabinservice.h
Normal file
96
src/plugins/gstreamer/camerabin/camerabinservice.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 CAMERABINCAPTURESERVICE_H
|
||||
#define CAMERABINCAPTURESERVICE_H
|
||||
|
||||
#include <qmediaservice.h>
|
||||
|
||||
#include <gst/gst.h>
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QAudioEndpointSelector;
|
||||
class QVideoDeviceControl;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class CameraBinSession;
|
||||
class CameraBinControl;
|
||||
class QGstreamerMessage;
|
||||
class QGstreamerBusHelper;
|
||||
class QGstreamerVideoRenderer;
|
||||
class QGstreamerVideoOverlay;
|
||||
class QGstreamerVideoWidgetControl;
|
||||
class QGstreamerElementFactory;
|
||||
class CameraBinMetaData;
|
||||
class CameraBinImageCapture;
|
||||
class CameraBinMetaData;
|
||||
|
||||
class CameraBinService : public QMediaService
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CameraBinService(const QString &service, QObject *parent = 0);
|
||||
virtual ~CameraBinService();
|
||||
|
||||
QMediaControl *requestControl(const char *name);
|
||||
void releaseControl(QMediaControl *);
|
||||
|
||||
static bool isCameraBinAvailable();
|
||||
|
||||
private:
|
||||
void setAudioPreview(GstElement*);
|
||||
|
||||
CameraBinSession *m_captureSession;
|
||||
CameraBinControl *m_cameraControl;
|
||||
CameraBinMetaData *m_metaDataControl;
|
||||
|
||||
QAudioEndpointSelector *m_audioInputEndpointSelector;
|
||||
QVideoDeviceControl *m_videoInputDevice;
|
||||
|
||||
QMediaControl *m_videoOutput;
|
||||
|
||||
QMediaControl *m_videoRenderer;
|
||||
QMediaControl *m_videoWindow;
|
||||
QGstreamerVideoWidgetControl *m_videoWidgetControl;
|
||||
CameraBinImageCapture *m_imageCaptureControl;
|
||||
};
|
||||
|
||||
#endif // CAMERABINCAPTURESERVICE_H
|
||||
1267
src/plugins/gstreamer/camerabin/camerabinsession.cpp
Normal file
1267
src/plugins/gstreamer/camerabin/camerabinsession.cpp
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user