Initial copy of QtMultimediaKit.
Comes from original repo, with SHA1: 2c82d5611655e5967f5c5095af50c0991c4378b2
This commit is contained in:
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
234
src/plugins/gstreamer/camerabin/camerabinsession.h
Normal file
234
src/plugins/gstreamer/camerabin/camerabinsession.h
Normal file
@@ -0,0 +1,234 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 CAMERABINCAPTURESESSION_MAEMO_H
|
||||
#define CAMERABINCAPTURESESSION_MAEMO_H
|
||||
|
||||
#include <qmediarecordercontrol.h>
|
||||
|
||||
#include <QtCore/qurl.h>
|
||||
#include <QtCore/qdir.h>
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/interfaces/photography.h>
|
||||
|
||||
#include "qgstreamerbushelper.h"
|
||||
#include "qcamera.h"
|
||||
|
||||
|
||||
class QGstreamerMessage;
|
||||
class QGstreamerBusHelper;
|
||||
class CameraBinAudioEncoder;
|
||||
class CameraBinVideoEncoder;
|
||||
class CameraBinImageEncoder;
|
||||
class CameraBinRecorder;
|
||||
class CameraBinContainer;
|
||||
class CameraBinExposure;
|
||||
class CameraBinFlash;
|
||||
class CameraBinFocus;
|
||||
class CameraBinImageProcessing;
|
||||
class CameraBinLocks;
|
||||
class CameraBinCaptureDestination;
|
||||
class CameraBinCaptureBufferFormat;
|
||||
class QGstreamerVideoRendererInterface;
|
||||
|
||||
class QGstreamerElementFactory
|
||||
{
|
||||
public:
|
||||
virtual GstElement *buildElement() = 0;
|
||||
};
|
||||
|
||||
class CameraBinSession : public QObject, public QGstreamerSyncEventFilter
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(qint64 duration READ duration NOTIFY durationChanged)
|
||||
public:
|
||||
enum CameraRole {
|
||||
FrontCamera, // Secondary camera
|
||||
BackCamera // Main photo camera
|
||||
};
|
||||
|
||||
CameraBinSession(QObject *parent);
|
||||
~CameraBinSession();
|
||||
|
||||
GstPhotography *photography();
|
||||
GstElement *cameraBin() { return m_pipeline; }
|
||||
|
||||
CameraRole cameraRole() const;
|
||||
|
||||
QList< QPair<int,int> > supportedFrameRates(const QSize &frameSize, bool *continuous) const;
|
||||
QList<QSize> supportedResolutions( QPair<int,int> rate, bool *continuous, QCamera::CaptureMode mode) const;
|
||||
|
||||
QCamera::CaptureMode captureMode() { return m_captureMode; }
|
||||
void setCaptureMode(QCamera::CaptureMode mode);
|
||||
|
||||
QUrl outputLocation() const;
|
||||
bool setOutputLocation(const QUrl& sink);
|
||||
|
||||
QDir defaultDir(QCamera::CaptureMode mode) const;
|
||||
QString generateFileName(const QString &prefix, const QDir &dir, const QString &ext) const;
|
||||
|
||||
CameraBinAudioEncoder *audioEncodeControl() const { return m_audioEncodeControl; }
|
||||
CameraBinVideoEncoder *videoEncodeControl() const { return m_videoEncodeControl; }
|
||||
CameraBinImageEncoder *imageEncodeControl() const { return m_imageEncodeControl; }
|
||||
CameraBinExposure *cameraExposureControl() const { return m_cameraExposureControl; }
|
||||
CameraBinFlash *cameraFlashControl() const { return m_cameraFlashControl; }
|
||||
CameraBinFocus *cameraFocusControl() const { return m_cameraFocusControl; }
|
||||
CameraBinImageProcessing *imageProcessingControl() const { return m_imageProcessingControl; }
|
||||
CameraBinLocks *cameraLocksControl() const { return m_cameraLocksControl; }
|
||||
CameraBinCaptureDestination *captureDestinationControl() const { return m_captureDestinationControl; }
|
||||
CameraBinCaptureBufferFormat *captureBufferFormatControl() const { return m_captureBufferFormatControl; }
|
||||
|
||||
|
||||
CameraBinRecorder *recorderControl() const { return m_recorderControl; }
|
||||
CameraBinContainer *mediaContainerControl() const { return m_mediaContainerControl; }
|
||||
|
||||
QGstreamerElementFactory *audioInput() const { return m_audioInputFactory; }
|
||||
void setAudioInput(QGstreamerElementFactory *audioInput);
|
||||
|
||||
QGstreamerElementFactory *videoInput() const { return m_videoInputFactory; }
|
||||
void setVideoInput(QGstreamerElementFactory *videoInput);
|
||||
bool isReady() const;
|
||||
|
||||
QObject *viewfinder() const { return m_viewfinder; }
|
||||
void setViewfinder(QObject *viewfinder);
|
||||
|
||||
void captureImage(int requestId, const QString &fileName);
|
||||
|
||||
QCamera::State state() const;
|
||||
bool isBusy() const;
|
||||
|
||||
qint64 duration() const;
|
||||
|
||||
void recordVideo();
|
||||
void pauseVideoRecording();
|
||||
void resumeVideoRecording();
|
||||
void stopVideoRecording();
|
||||
|
||||
bool isMuted() const;
|
||||
|
||||
bool processSyncMessage(const QGstreamerMessage &message);
|
||||
|
||||
signals:
|
||||
void stateChanged(QCamera::State state);
|
||||
void durationChanged(qint64 duration);
|
||||
void error(int error, const QString &errorString);
|
||||
void imageExposed(int requestId);
|
||||
void imageCaptured(int requestId, const QImage &img);
|
||||
void mutedChanged(bool);
|
||||
void viewfinderChanged();
|
||||
void readyChanged(bool);
|
||||
void busyChanged(bool);
|
||||
void busMessage(const QGstreamerMessage &message);
|
||||
|
||||
public slots:
|
||||
void setDevice(const QString &device);
|
||||
void setState(QCamera::State);
|
||||
void setCaptureDevice(const QString &deviceName);
|
||||
void setMetaData(const QMap<QByteArray, QVariant>&);
|
||||
void setMuted(bool);
|
||||
|
||||
private slots:
|
||||
void handleBusMessage(const QGstreamerMessage &message);
|
||||
void handleViewfinderChange();
|
||||
|
||||
private:
|
||||
bool setupCameraBin();
|
||||
void setupCaptureResolution();
|
||||
void updateVideoSourceCaps();
|
||||
GstElement *buildVideoSrc();
|
||||
static void updateBusyStatus(GObject *o, GParamSpec *p, gpointer d);
|
||||
|
||||
QUrl m_sink;
|
||||
QUrl m_actualSink;
|
||||
bool m_recordingActive;
|
||||
QString m_captureDevice;
|
||||
QCamera::State m_state;
|
||||
QCamera::State m_pendingState;
|
||||
QString m_inputDevice;
|
||||
bool m_pendingResolutionUpdate;
|
||||
bool m_muted;
|
||||
bool m_busy;
|
||||
|
||||
QCamera::CaptureMode m_captureMode;
|
||||
QMap<QByteArray, QVariant> m_metaData;
|
||||
|
||||
QGstreamerElementFactory *m_audioInputFactory;
|
||||
QGstreamerElementFactory *m_videoInputFactory;
|
||||
QObject *m_viewfinder;
|
||||
QGstreamerVideoRendererInterface *m_viewfinderInterface;
|
||||
|
||||
CameraBinAudioEncoder *m_audioEncodeControl;
|
||||
CameraBinVideoEncoder *m_videoEncodeControl;
|
||||
CameraBinImageEncoder *m_imageEncodeControl;
|
||||
CameraBinRecorder *m_recorderControl;
|
||||
CameraBinContainer *m_mediaContainerControl;
|
||||
CameraBinExposure *m_cameraExposureControl;
|
||||
CameraBinFlash *m_cameraFlashControl;
|
||||
CameraBinFocus *m_cameraFocusControl;
|
||||
CameraBinImageProcessing *m_imageProcessingControl;
|
||||
CameraBinLocks *m_cameraLocksControl;
|
||||
CameraBinCaptureDestination *m_captureDestinationControl;
|
||||
CameraBinCaptureBufferFormat *m_captureBufferFormatControl;
|
||||
|
||||
QGstreamerBusHelper *m_busHelper;
|
||||
GstBus* m_bus;
|
||||
GstElement *m_pipeline;
|
||||
GstElement *m_videoSrc;
|
||||
GstElement *m_viewfinderElement;
|
||||
bool m_viewfinderHasChanged;
|
||||
bool m_videoInputHasChanged;
|
||||
|
||||
GstCaps *m_sourceCaps;
|
||||
|
||||
GstElement *m_audioSrc;
|
||||
GstElement *m_audioConvert;
|
||||
GstElement *m_capsFilter;
|
||||
GstElement *m_fileSink;
|
||||
GstElement *m_audioEncoder;
|
||||
GstElement *m_muxer;
|
||||
|
||||
public:
|
||||
QString m_imageFileName;
|
||||
int m_requestId;
|
||||
};
|
||||
|
||||
#endif // CAMERABINCAPTURESESSION_MAEMO_H
|
||||
346
src/plugins/gstreamer/camerabin/camerabinvideoencoder.cpp
Normal file
346
src/plugins/gstreamer/camerabin/camerabinvideoencoder.cpp
Normal file
@@ -0,0 +1,346 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "camerabinvideoencoder.h"
|
||||
#include "camerabinsession.h"
|
||||
#include "camerabincontainer.h"
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
|
||||
CameraBinVideoEncoder::CameraBinVideoEncoder(CameraBinSession *session)
|
||||
:QVideoEncoderControl(session), m_session(session)
|
||||
{
|
||||
QList<QByteArray> codecCandidates;
|
||||
#if defined(Q_WS_MAEMO_5)
|
||||
codecCandidates << "video/mpeg4" << "video/h264" << "video/h263" << "video/theora"
|
||||
<< "video/mpeg2" << "video/mpeg1" << "video/mjpeg" << "video/VP8" << "video/h261";
|
||||
|
||||
m_elementNames["video/h264"] = "dsph264enc";
|
||||
m_elementNames["video/mpeg4"] = "dspmp4venc";
|
||||
m_elementNames["video/h263"] = "dsph263enc";
|
||||
m_elementNames["video/theora"] = "theoraenc";
|
||||
m_elementNames["video/mpeg2"] = "ffenc_mpeg2video";
|
||||
m_elementNames["video/mpeg1"] = "ffenc_mpeg1video";
|
||||
m_elementNames["video/mjpeg"] = "ffenc_mjpeg";
|
||||
m_elementNames["video/VP8"] = "vp8enc";
|
||||
m_elementNames["video/h261"] = "ffenc_h261";
|
||||
|
||||
m_codecOptions["video/mpeg4"] = QStringList() << "mode" << "keyframe-interval";
|
||||
#elif defined(Q_WS_MAEMO_6)
|
||||
codecCandidates << "video/mpeg4" << "video/h264" << "video/h263";
|
||||
|
||||
m_elementNames["video/h264"] = "dsph264enc";
|
||||
m_elementNames["video/mpeg4"] = "dsphdmp4venc";
|
||||
m_elementNames["video/h263"] = "dsph263enc";
|
||||
|
||||
QStringList options = QStringList() << "mode" << "keyframe-interval" << "max-bitrate" << "intra-refresh";
|
||||
m_codecOptions["video/h264"] = options;
|
||||
m_codecOptions["video/mpeg4"] = options;
|
||||
m_codecOptions["video/h263"] = options;
|
||||
#else
|
||||
codecCandidates << "video/h264" << "video/xvid" << "video/mpeg4"
|
||||
<< "video/mpeg1" << "video/mpeg2" << "video/theora"
|
||||
<< "video/VP8" << "video/h261" << "video/mjpeg";
|
||||
|
||||
m_elementNames["video/h264"] = "x264enc";
|
||||
m_elementNames["video/xvid"] = "xvidenc";
|
||||
m_elementNames["video/mpeg4"] = "ffenc_mpeg4";
|
||||
m_elementNames["video/mpeg1"] = "ffenc_mpeg1video";
|
||||
m_elementNames["video/mpeg2"] = "ffenc_mpeg2video";
|
||||
m_elementNames["video/theora"] = "theoraenc";
|
||||
m_elementNames["video/mjpeg"] = "ffenc_mjpeg";
|
||||
m_elementNames["video/VP8"] = "vp8enc";
|
||||
m_elementNames["video/h261"] = "ffenc_h261";
|
||||
|
||||
m_codecOptions["video/h264"] = QStringList() << "quantizer";
|
||||
m_codecOptions["video/xvid"] = QStringList() << "quantizer" << "profile";
|
||||
m_codecOptions["video/mpeg4"] = QStringList() << "quantizer";
|
||||
m_codecOptions["video/mpeg1"] = QStringList() << "quantizer";
|
||||
m_codecOptions["video/mpeg2"] = QStringList() << "quantizer";
|
||||
m_codecOptions["video/theora"] = 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);
|
||||
m_codecDescriptions.insert(codecName, QString::fromUtf8(descr));
|
||||
|
||||
m_streamTypes.insert(codecName,
|
||||
CameraBinContainer::supportedStreamTypes(factory, GST_PAD_SRC));
|
||||
|
||||
gst_object_unref(GST_OBJECT(factory));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CameraBinVideoEncoder::~CameraBinVideoEncoder()
|
||||
{
|
||||
}
|
||||
|
||||
QList<QSize> CameraBinVideoEncoder::supportedResolutions(const QVideoEncoderSettings &settings, bool *continuous) const
|
||||
{
|
||||
if (continuous)
|
||||
*continuous = false;
|
||||
|
||||
QPair<int,int> rate = rateAsRational(settings.frameRate());
|
||||
|
||||
//select the closest supported rational rate to settings.frameRate()
|
||||
|
||||
return m_session->supportedResolutions(rate, continuous, QCamera::CaptureVideo);
|
||||
}
|
||||
|
||||
QList< qreal > CameraBinVideoEncoder::supportedFrameRates(const QVideoEncoderSettings &settings, bool *continuous) const
|
||||
{
|
||||
if (continuous)
|
||||
*continuous = false;
|
||||
|
||||
QList< qreal > res;
|
||||
QPair<int,int> rate;
|
||||
|
||||
foreach(rate, m_session->supportedFrameRates(settings.resolution(), continuous)) {
|
||||
if (rate.second > 0)
|
||||
res << qreal(rate.first)/rate.second;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
QStringList CameraBinVideoEncoder::supportedVideoCodecs() const
|
||||
{
|
||||
return m_codecs;
|
||||
}
|
||||
|
||||
QString CameraBinVideoEncoder::videoCodecDescription(const QString &codecName) const
|
||||
{
|
||||
return m_codecDescriptions.value(codecName);
|
||||
}
|
||||
|
||||
QStringList CameraBinVideoEncoder::supportedEncodingOptions(const QString &codec) const
|
||||
{
|
||||
return m_codecOptions.value(codec);
|
||||
}
|
||||
|
||||
QVariant CameraBinVideoEncoder::encodingOption(const QString &codec, const QString &name) const
|
||||
{
|
||||
return m_options[codec].value(name);
|
||||
}
|
||||
|
||||
void CameraBinVideoEncoder::setEncodingOption(
|
||||
const QString &codec, const QString &name, const QVariant &value)
|
||||
{
|
||||
m_options[codec][name] = value;
|
||||
}
|
||||
|
||||
QVideoEncoderSettings CameraBinVideoEncoder::videoSettings() const
|
||||
{
|
||||
return m_videoSettings;
|
||||
}
|
||||
|
||||
void CameraBinVideoEncoder::setVideoSettings(const QVideoEncoderSettings &settings)
|
||||
{
|
||||
m_videoSettings = settings;
|
||||
m_userSettings = settings;
|
||||
emit settingsChanged();
|
||||
}
|
||||
|
||||
void CameraBinVideoEncoder::setActualVideoSettings(const QVideoEncoderSettings &settings)
|
||||
{
|
||||
m_videoSettings = settings;
|
||||
}
|
||||
|
||||
void CameraBinVideoEncoder::resetActualSettings()
|
||||
{
|
||||
m_videoSettings = m_userSettings;
|
||||
}
|
||||
|
||||
GstElement *CameraBinVideoEncoder::createEncoder()
|
||||
{
|
||||
QString codec = m_videoSettings.codec();
|
||||
QByteArray elementName = m_elementNames.value(codec);
|
||||
|
||||
GstElement *encoderElement = gst_element_factory_make( elementName.constData(), "video-encoder");
|
||||
|
||||
if (encoderElement) {
|
||||
if (m_videoSettings.encodingMode() == QtMultimediaKit::ConstantQualityEncoding) {
|
||||
QtMultimediaKit::EncodingQuality qualityValue = m_videoSettings.quality();
|
||||
|
||||
if (elementName == "x264enc") {
|
||||
//constant quantizer mode
|
||||
g_object_set(G_OBJECT(encoderElement), "pass", 4, NULL);
|
||||
int qualityTable[] = {
|
||||
50, //VeryLow
|
||||
35, //Low
|
||||
21, //Normal
|
||||
15, //High
|
||||
8 //VeryHigh
|
||||
};
|
||||
g_object_set(G_OBJECT(encoderElement), "quantizer", qualityTable[qualityValue], NULL);
|
||||
} else if (elementName == "xvidenc") {
|
||||
//constant quantizer mode
|
||||
g_object_set(G_OBJECT(encoderElement), "pass", 3, NULL);
|
||||
int qualityTable[] = {
|
||||
32, //VeryLow
|
||||
12, //Low
|
||||
5, //Normal
|
||||
3, //High
|
||||
2 //VeryHigh
|
||||
};
|
||||
int quant = qualityTable[qualityValue];
|
||||
g_object_set(G_OBJECT(encoderElement), "quantizer", quant, NULL);
|
||||
} else if (elementName == "ffenc_mpeg4" ||
|
||||
elementName == "ffenc_mpeg1video" ||
|
||||
elementName == "ffenc_mpeg2video" ) {
|
||||
//constant quantizer mode
|
||||
g_object_set(G_OBJECT(encoderElement), "pass", 2, NULL);
|
||||
//quant from 1 to 30, default ~3
|
||||
double qualityTable[] = {
|
||||
20, //VeryLow
|
||||
8.0, //Low
|
||||
3.0, //Normal
|
||||
2.5, //High
|
||||
2.0 //VeryHigh
|
||||
};
|
||||
double quant = qualityTable[qualityValue];
|
||||
g_object_set(G_OBJECT(encoderElement), "quantizer", quant, NULL);
|
||||
} else if (elementName == "theoraenc") {
|
||||
int qualityTable[] = {
|
||||
8, //VeryLow
|
||||
16, //Low
|
||||
32, //Normal
|
||||
45, //High
|
||||
60 //VeryHigh
|
||||
};
|
||||
//quality from 0 to 63
|
||||
int quality = qualityTable[qualityValue];
|
||||
g_object_set(G_OBJECT(encoderElement), "quality", quality, NULL);
|
||||
} else if (elementName == "dsph264enc" ||
|
||||
elementName == "dspmp4venc" ||
|
||||
elementName == "dsphdmp4venc" ||
|
||||
elementName == "dsph263enc") {
|
||||
//only bitrate parameter is supported
|
||||
int qualityTable[] = {
|
||||
1000000, //VeryLow
|
||||
2000000, //Low
|
||||
4000000, //Normal
|
||||
8000000, //High
|
||||
16000000 //VeryHigh
|
||||
};
|
||||
int bitrate = qualityTable[qualityValue];
|
||||
g_object_set(G_OBJECT(encoderElement), "bitrate", bitrate, NULL);
|
||||
}
|
||||
} else {
|
||||
int bitrate = m_videoSettings.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 encoderElement;
|
||||
}
|
||||
|
||||
QPair<int,int> CameraBinVideoEncoder::rateAsRational(qreal frameRate) const
|
||||
{
|
||||
if (frameRate > 0.001) {
|
||||
//convert to rational number
|
||||
QList<int> denumCandidates;
|
||||
denumCandidates << 1 << 2 << 3 << 5 << 10 << 25 << 30 << 50 << 100 << 1001 << 1000;
|
||||
|
||||
qreal error = 1.0;
|
||||
int num = 1;
|
||||
int denum = 1;
|
||||
|
||||
foreach (int curDenum, denumCandidates) {
|
||||
int curNum = qRound(frameRate*curDenum);
|
||||
qreal curError = qAbs(qreal(curNum)/curDenum - frameRate);
|
||||
|
||||
if (curError < error) {
|
||||
error = curError;
|
||||
num = curNum;
|
||||
denum = curDenum;
|
||||
}
|
||||
|
||||
if (curError < 1e-8)
|
||||
break;
|
||||
}
|
||||
|
||||
return QPair<int,int>(num,denum);
|
||||
}
|
||||
|
||||
return QPair<int,int>();
|
||||
}
|
||||
|
||||
|
||||
QSet<QString> CameraBinVideoEncoder::supportedStreamTypes(const QString &codecName) const
|
||||
{
|
||||
return m_streamTypes.value(codecName);
|
||||
}
|
||||
106
src/plugins/gstreamer/camerabin/camerabinvideoencoder.h
Normal file
106
src/plugins/gstreamer/camerabin/camerabinvideoencoder.h
Normal file
@@ -0,0 +1,106 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 CAMERABINVIDEOENCODE_H
|
||||
#define CAMERABINVIDEOENCODE_H
|
||||
|
||||
#include <qvideoencodercontrol.h>
|
||||
class CameraBinSession;
|
||||
|
||||
#include <QtCore/qstringlist.h>
|
||||
#include <QtCore/qmap.h>
|
||||
#include <QtCore/qset.h>
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class CameraBinVideoEncoder : public QVideoEncoderControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CameraBinVideoEncoder(CameraBinSession *session);
|
||||
virtual ~CameraBinVideoEncoder();
|
||||
|
||||
QList<QSize> supportedResolutions(const QVideoEncoderSettings &settings = QVideoEncoderSettings(),
|
||||
bool *continuous = 0) const;
|
||||
|
||||
QList< qreal > supportedFrameRates(const QVideoEncoderSettings &settings = QVideoEncoderSettings(),
|
||||
bool *continuous = 0) const;
|
||||
|
||||
QPair<int,int> rateAsRational(qreal) const;
|
||||
|
||||
QStringList supportedVideoCodecs() const;
|
||||
QString videoCodecDescription(const QString &codecName) const;
|
||||
|
||||
QVideoEncoderSettings videoSettings() const;
|
||||
void setVideoSettings(const QVideoEncoderSettings &settings);
|
||||
|
||||
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);
|
||||
|
||||
GstElement *createEncoder();
|
||||
|
||||
QSet<QString> supportedStreamTypes(const QString &codecName) const;
|
||||
|
||||
void setActualVideoSettings(const QVideoEncoderSettings&);
|
||||
void resetActualSettings();
|
||||
|
||||
Q_SIGNALS:
|
||||
void settingsChanged();
|
||||
|
||||
private:
|
||||
CameraBinSession *m_session;
|
||||
|
||||
QStringList m_codecs;
|
||||
QMap<QString,QString> m_codecDescriptions;
|
||||
QMap<QString,QByteArray> m_elementNames;
|
||||
QMap<QString,QStringList> m_codecOptions;
|
||||
|
||||
QVideoEncoderSettings m_videoSettings; // backend selected settings, using m_userSettings
|
||||
QVideoEncoderSettings m_userSettings;
|
||||
|
||||
QMap<QString, QMap<QString, QVariant> > m_options;
|
||||
QMap<QString, QSet<QString> > m_streamTypes;
|
||||
};
|
||||
|
||||
#endif
|
||||
121
src/plugins/gstreamer/camerabuttonlistener_maemo.cpp
Normal file
121
src/plugins/gstreamer/camerabuttonlistener_maemo.cpp
Normal file
@@ -0,0 +1,121 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "camerabuttonlistener_maemo.h"
|
||||
|
||||
#include <QtDBus/qdbusconnection.h>
|
||||
#include <QtDBus/qdbusinterface.h>
|
||||
|
||||
#include <QtGui/qapplication.h>
|
||||
#include <QtGui/qevent.h>
|
||||
#include <QtGui/qwidget.h>
|
||||
|
||||
|
||||
CameraButtonListener::CameraButtonListener(QObject *parent) :
|
||||
QObject(parent),
|
||||
m_focusPressed(false),
|
||||
m_shutterPressed(false)
|
||||
{
|
||||
QDBusConnection::systemBus().connect(
|
||||
QString(),
|
||||
"/org/freedesktop/Hal/devices/platform_cam_launch",
|
||||
"org.freedesktop.Hal.Device",
|
||||
"PropertyModified",
|
||||
this,
|
||||
SLOT(updateShuterButtonState()));
|
||||
|
||||
QDBusConnection::systemBus().connect(
|
||||
QString(),
|
||||
"/org/freedesktop/Hal/devices/platform_cam_focus",
|
||||
"org.freedesktop.Hal.Device",
|
||||
"PropertyModified",
|
||||
this,
|
||||
SLOT(updateFocusButtonState()));
|
||||
}
|
||||
|
||||
|
||||
CameraButtonListener::~CameraButtonListener()
|
||||
{
|
||||
}
|
||||
|
||||
void CameraButtonListener::updateFocusButtonState()
|
||||
{
|
||||
QDBusInterface propertyInterface("org.freedesktop.Hal",
|
||||
"/org/freedesktop/Hal/devices/platform_cam_focus",
|
||||
"org.freedesktop.Hal.Device",
|
||||
QDBusConnection::systemBus());
|
||||
|
||||
bool pressed = propertyInterface.call("GetProperty", "button.state.value").arguments().at(0).toBool();
|
||||
|
||||
if (m_focusPressed != pressed) {
|
||||
m_focusPressed = pressed;
|
||||
QWidget *window = QApplication::focusWidget();
|
||||
|
||||
if (window) {
|
||||
QApplication::postEvent(window,
|
||||
new QKeyEvent(pressed ? QEvent::KeyPress : QEvent::KeyRelease,
|
||||
0x01100021, //Qt::Key_CameraFocus since Qt 4.7.0
|
||||
Qt::NoModifier));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CameraButtonListener::updateShuterButtonState()
|
||||
{
|
||||
QDBusInterface propertyInterface("org.freedesktop.Hal",
|
||||
"/org/freedesktop/Hal/devices/platform_cam_launch",
|
||||
"org.freedesktop.Hal.Device",
|
||||
QDBusConnection::systemBus());
|
||||
|
||||
bool pressed = propertyInterface.call("GetProperty", "button.state.value").arguments().at(0).toBool();
|
||||
|
||||
if (m_shutterPressed != pressed) {
|
||||
m_shutterPressed = pressed;
|
||||
QWidget *window = QApplication::focusWidget();
|
||||
|
||||
if (window) {
|
||||
QApplication::postEvent(window,
|
||||
new QKeyEvent(pressed ? QEvent::KeyPress : QEvent::KeyRelease,
|
||||
0x01100020, //Qt::Key_Camera since Qt 4.7.0
|
||||
Qt::NoModifier));
|
||||
}
|
||||
}
|
||||
}
|
||||
64
src/plugins/gstreamer/camerabuttonlistener_maemo.h
Normal file
64
src/plugins/gstreamer/camerabuttonlistener_maemo.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 CAMERABUTTONLISTENER_MAEMO_H
|
||||
#define CAMERABUTTONLISTENER_MAEMO_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class CameraButtonListener : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CameraButtonListener(QObject *parent = 0);
|
||||
virtual ~CameraButtonListener();
|
||||
|
||||
private slots:
|
||||
void updateFocusButtonState();
|
||||
void updateShuterButtonState();
|
||||
|
||||
private:
|
||||
bool m_focusPressed;
|
||||
bool m_shutterPressed;
|
||||
};
|
||||
|
||||
#endif // CAMERABUTTONLISTENER_MAEMO_H
|
||||
92
src/plugins/gstreamer/camerabuttonlistener_meego.cpp
Normal file
92
src/plugins/gstreamer/camerabuttonlistener_meego.cpp
Normal file
@@ -0,0 +1,92 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "camerabuttonlistener_meego.h"
|
||||
|
||||
#include <QtGui/qapplication.h>
|
||||
#include <QtGui/qevent.h>
|
||||
#include <QtGui/qwidget.h>
|
||||
#include <QtCore/qdebug.h>
|
||||
|
||||
CameraButtonListener::CameraButtonListener(QObject *parent) :
|
||||
QObject(parent),
|
||||
m_focusPressed(false),
|
||||
m_shutterPressed(false)
|
||||
{
|
||||
m_keys = new MeeGo::QmKeys(this);
|
||||
connect(m_keys, SIGNAL(keyEvent(MeeGo::QmKeys::Key, MeeGo::QmKeys::State)),
|
||||
this, SLOT(handleQmKeyEvent(MeeGo::QmKeys::Key,MeeGo::QmKeys::State)));
|
||||
}
|
||||
|
||||
CameraButtonListener::~CameraButtonListener()
|
||||
{
|
||||
}
|
||||
|
||||
void CameraButtonListener::handleQmKeyEvent(MeeGo::QmKeys::Key key, MeeGo::QmKeys::State state)
|
||||
{
|
||||
if (key == MeeGo::QmKeys::Camera) {
|
||||
QWidget *window = QApplication::focusWidget();
|
||||
|
||||
bool focusPressed = (state == MeeGo::QmKeys::KeyHalfDown) ||
|
||||
(state == MeeGo::QmKeys::KeyDown);
|
||||
|
||||
if (m_focusPressed != focusPressed) {
|
||||
m_focusPressed = focusPressed;
|
||||
if (window) {
|
||||
QApplication::postEvent(window,
|
||||
new QKeyEvent(focusPressed ? QEvent::KeyPress : QEvent::KeyRelease,
|
||||
Qt::Key_CameraFocus,
|
||||
Qt::NoModifier));
|
||||
}
|
||||
}
|
||||
|
||||
bool shutterPressed = (state == MeeGo::QmKeys::KeyDown);
|
||||
if (m_shutterPressed != shutterPressed) {
|
||||
m_shutterPressed = shutterPressed;
|
||||
if (window) {
|
||||
QApplication::postEvent(window,
|
||||
new QKeyEvent(shutterPressed ? QEvent::KeyPress : QEvent::KeyRelease,
|
||||
Qt::Key_Camera,
|
||||
Qt::NoModifier));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
65
src/plugins/gstreamer/camerabuttonlistener_meego.h
Normal file
65
src/plugins/gstreamer/camerabuttonlistener_meego.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 CAMERABUTTONLISTENER_MEEGO_H
|
||||
#define CAMERABUTTONLISTENER_MEEGO_H
|
||||
|
||||
#include <QtCore/qobject.h>
|
||||
#include <qmsystem2/qmkeys.h>
|
||||
|
||||
class CameraButtonListener : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CameraButtonListener(QObject *parent = 0);
|
||||
~CameraButtonListener();
|
||||
|
||||
private slots:
|
||||
void handleQmKeyEvent(MeeGo::QmKeys::Key key, MeeGo::QmKeys::State state);
|
||||
|
||||
private:
|
||||
MeeGo::QmKeys *m_keys;
|
||||
bool m_focusPressed;
|
||||
bool m_shutterPressed;
|
||||
};
|
||||
|
||||
#endif // CAMERABUTTONLISTENER_MEEGO_H
|
||||
101
src/plugins/gstreamer/gstreamer.pro
Normal file
101
src/plugins/gstreamer/gstreamer.pro
Normal file
@@ -0,0 +1,101 @@
|
||||
|
||||
load(qt_module)
|
||||
|
||||
TARGET = qgstengine
|
||||
QT += multimediakit-private network
|
||||
PLUGIN_TYPE=mediaservice
|
||||
|
||||
load(qt_plugin)
|
||||
DESTDIR = $$QT.multimediakit.plugins/$${PLUGIN_TYPE}
|
||||
|
||||
unix:contains(QT_CONFIG, alsa) {
|
||||
DEFINES += HAVE_ALSA
|
||||
LIBS += \
|
||||
-lasound
|
||||
}
|
||||
|
||||
CONFIG += link_pkgconfig
|
||||
|
||||
PKGCONFIG += \
|
||||
gstreamer-0.10 \
|
||||
gstreamer-base-0.10 \
|
||||
gstreamer-interfaces-0.10 \
|
||||
gstreamer-audio-0.10 \
|
||||
gstreamer-video-0.10
|
||||
|
||||
maemo*:PKGCONFIG +=gstreamer-plugins-bad-0.10
|
||||
contains(gstreamer-appsrc_enabled, yes): PKGCONFIG += gstreamer-app-0.10
|
||||
|
||||
maemo5 {
|
||||
HEADERS += camerabuttonlistener_maemo.h
|
||||
SOURCES += camerabuttonlistener_maemo.cpp
|
||||
|
||||
QT += dbus
|
||||
}
|
||||
|
||||
maemo6 {
|
||||
HEADERS += camerabuttonlistener_meego.h
|
||||
SOURCES += camerabuttonlistener_meego.cpp
|
||||
|
||||
PKGCONFIG += qmsystem2 libresourceqt1
|
||||
|
||||
isEqual(QT_ARCH,armv6) {
|
||||
HEADERS += qgstreamergltexturerenderer.h
|
||||
SOURCES += qgstreamergltexturerenderer.cpp
|
||||
QT += opengl
|
||||
LIBS += -lEGL -lgstmeegointerfaces-0.10
|
||||
}
|
||||
}
|
||||
|
||||
# Input
|
||||
HEADERS += \
|
||||
qgstreamermessage.h \
|
||||
qgstreamerbushelper.h \
|
||||
qgstreamervideorendererinterface.h \
|
||||
qgstreamerserviceplugin.h \
|
||||
qgstreameraudioinputendpointselector.h \
|
||||
qgstreamervideorenderer.h \
|
||||
qgstvideobuffer.h \
|
||||
qvideosurfacegstsink.h \
|
||||
qgstreamervideoinputdevicecontrol.h \
|
||||
gstvideoconnector.h \
|
||||
qabstractgstbufferpool.h \
|
||||
qgstutils.h
|
||||
|
||||
SOURCES += \
|
||||
qgstreamermessage.cpp \
|
||||
qgstreamerbushelper.cpp \
|
||||
qgstreamervideorendererinterface.cpp \
|
||||
qgstreamerserviceplugin.cpp \
|
||||
qgstreameraudioinputendpointselector.cpp \
|
||||
qgstreamervideorenderer.cpp \
|
||||
qgstvideobuffer.cpp \
|
||||
qvideosurfacegstsink.cpp \
|
||||
qgstreamervideoinputdevicecontrol.cpp \
|
||||
gstvideoconnector.c \
|
||||
qgstutils.cpp
|
||||
|
||||
|
||||
!win32:!contains(QT_CONFIG,embedded):!mac:!symbian:!simulator:!contains(QT_CONFIG, qpa) {
|
||||
LIBS += -lXv -lX11 -lXext
|
||||
|
||||
HEADERS += \
|
||||
qgstreamervideooverlay.h \
|
||||
qgstreamervideowindow.h \
|
||||
qgstreamervideowidget.h \
|
||||
qx11videosurface.h \
|
||||
qgstxvimagebuffer.h
|
||||
|
||||
SOURCES += \
|
||||
qgstreamervideooverlay.cpp \
|
||||
qgstreamervideowindow.cpp \
|
||||
qgstreamervideowidget.cpp \
|
||||
qx11videosurface.cpp \
|
||||
qgstxvimagebuffer.cpp
|
||||
}
|
||||
include(mediaplayer/mediaplayer.pri)
|
||||
include(mediacapture/mediacapture.pri)
|
||||
|
||||
contains(gstreamer-photography_enabled, yes) {
|
||||
include(camerabin/camerabin.pri)
|
||||
}
|
||||
421
src/plugins/gstreamer/gstvideoconnector.c
Normal file
421
src/plugins/gstreamer/gstvideoconnector.c
Normal file
@@ -0,0 +1,421 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "gstvideoconnector.h"
|
||||
|
||||
/* signals */
|
||||
enum
|
||||
{
|
||||
SIGNAL_RESEND_NEW_SEGMENT,
|
||||
SIGNAL_CONNECTION_FAILED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
static guint gst_video_connector_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC (video_connector_debug);
|
||||
#define GST_CAT_DEFAULT video_connector_debug
|
||||
|
||||
static GstStaticPadTemplate gst_video_connector_sink_factory =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS_ANY);
|
||||
|
||||
static GstStaticPadTemplate gst_video_connector_src_factory =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS_ANY);
|
||||
|
||||
#define _do_init(bla) \
|
||||
GST_DEBUG_CATEGORY_INIT (video_connector_debug, \
|
||||
"video-connector", 0, "An identity like element for reconnecting video stream");
|
||||
|
||||
GST_BOILERPLATE_FULL (GstVideoConnector, gst_video_connector, GstElement,
|
||||
GST_TYPE_ELEMENT, _do_init);
|
||||
|
||||
static void gst_video_connector_dispose (GObject * object);
|
||||
static GstFlowReturn gst_video_connector_chain (GstPad * pad, GstBuffer * buf);
|
||||
static GstFlowReturn gst_video_connector_buffer_alloc (GstPad * pad,
|
||||
guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf);
|
||||
static GstStateChangeReturn gst_video_connector_change_state (GstElement *
|
||||
element, GstStateChange transition);
|
||||
static gboolean gst_video_connector_handle_sink_event (GstPad * pad,
|
||||
GstEvent * event);
|
||||
static gboolean gst_video_connector_new_buffer_probe(GstObject *pad, GstBuffer *buffer, guint * object);
|
||||
static void gst_video_connector_resend_new_segment(GstElement * element, gboolean emitFailedSignal);
|
||||
static gboolean gst_video_connector_setcaps (GstPad *pad, GstCaps *caps);
|
||||
static GstCaps *gst_video_connector_getcaps (GstPad * pad);
|
||||
static gboolean gst_video_connector_acceptcaps (GstPad * pad, GstCaps * caps);
|
||||
|
||||
static void
|
||||
gst_video_connector_base_init (gpointer g_class)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
|
||||
|
||||
gst_element_class_set_details_simple (element_class, "Video Connector",
|
||||
"Generic",
|
||||
"An identity like element used for reconnecting video stream",
|
||||
"Dmytro Poplavskiy <dmytro.poplavskiy@nokia.com>");
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_video_connector_sink_factory));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_video_connector_src_factory));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_video_connector_class_init (GstVideoConnectorClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
|
||||
gobject_class->dispose = gst_video_connector_dispose;
|
||||
gstelement_class->change_state = gst_video_connector_change_state;
|
||||
klass->resend_new_segment = gst_video_connector_resend_new_segment;
|
||||
|
||||
gst_video_connector_signals[SIGNAL_RESEND_NEW_SEGMENT] =
|
||||
g_signal_new ("resend-new-segment", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
|
||||
G_STRUCT_OFFSET (GstVideoConnectorClass, resend_new_segment), NULL, NULL,
|
||||
g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
|
||||
|
||||
gst_video_connector_signals[SIGNAL_CONNECTION_FAILED] =
|
||||
g_signal_new ("connection-failed", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_video_connector_init (GstVideoConnector *element,
|
||||
GstVideoConnectorClass *g_class)
|
||||
{
|
||||
element->sinkpad =
|
||||
gst_pad_new_from_static_template (&gst_video_connector_sink_factory,
|
||||
"sink");
|
||||
gst_pad_set_chain_function(element->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_video_connector_chain));
|
||||
gst_pad_set_event_function(element->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_video_connector_handle_sink_event));
|
||||
gst_pad_set_bufferalloc_function(element->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_video_connector_buffer_alloc));
|
||||
gst_pad_set_setcaps_function(element->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_video_connector_setcaps));
|
||||
gst_pad_set_getcaps_function(element->sinkpad,
|
||||
GST_DEBUG_FUNCPTR(gst_video_connector_getcaps));
|
||||
gst_pad_set_acceptcaps_function(element->sinkpad,
|
||||
GST_DEBUG_FUNCPTR(gst_video_connector_acceptcaps));
|
||||
|
||||
gst_element_add_pad (GST_ELEMENT (element), element->sinkpad);
|
||||
|
||||
element->srcpad =
|
||||
gst_pad_new_from_static_template (&gst_video_connector_src_factory,
|
||||
"src");
|
||||
gst_pad_add_buffer_probe(element->srcpad,
|
||||
G_CALLBACK(gst_video_connector_new_buffer_probe), element);
|
||||
gst_element_add_pad (GST_ELEMENT (element), element->srcpad);
|
||||
|
||||
element->relinked = FALSE;
|
||||
element->failedSignalEmited = FALSE;
|
||||
gst_segment_init (&element->segment, GST_FORMAT_TIME);
|
||||
element->latest_buffer = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_video_connector_reset (GstVideoConnector * element)
|
||||
{
|
||||
element->relinked = FALSE;
|
||||
element->failedSignalEmited = FALSE;
|
||||
if (element->latest_buffer != NULL) {
|
||||
gst_buffer_unref (element->latest_buffer);
|
||||
element->latest_buffer = NULL;
|
||||
}
|
||||
gst_segment_init (&element->segment, GST_FORMAT_UNDEFINED);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_video_connector_dispose (GObject * object)
|
||||
{
|
||||
GstVideoConnector *element = GST_VIDEO_CONNECTOR (object);
|
||||
|
||||
gst_video_connector_reset (element);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_video_connector_buffer_alloc (GstPad * pad, guint64 offset, guint size,
|
||||
GstCaps * caps, GstBuffer ** buf)
|
||||
{
|
||||
GstVideoConnector *element;
|
||||
GstFlowReturn res = GST_FLOW_OK;
|
||||
element = GST_VIDEO_CONNECTOR (GST_PAD_PARENT (pad));
|
||||
|
||||
if (!buf)
|
||||
return GST_FLOW_ERROR;
|
||||
*buf = NULL;
|
||||
|
||||
GST_OBJECT_LOCK (element);
|
||||
gst_object_ref(element->srcpad);
|
||||
GST_OBJECT_UNLOCK (element);
|
||||
|
||||
res = gst_pad_alloc_buffer(element->srcpad, offset, size, caps, buf);
|
||||
gst_object_unref (element->srcpad);
|
||||
|
||||
GST_DEBUG_OBJECT (element, "buffer alloc finished: %s", gst_flow_get_name (res));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_video_connector_setcaps (GstPad *pad, GstCaps *caps)
|
||||
{
|
||||
GstVideoConnector *element;
|
||||
element = GST_VIDEO_CONNECTOR (GST_PAD_PARENT (pad));
|
||||
|
||||
/* forward-negotiate */
|
||||
gboolean res = gst_pad_set_caps(element->srcpad, caps);
|
||||
|
||||
GST_DEBUG_OBJECT(element, "gst_video_connector_setcaps %s %i", gst_caps_to_string(caps), res);
|
||||
|
||||
if (!res) {
|
||||
//if set_caps failed, emit "connection-failed" signal
|
||||
//so colorspace transformation elemnt can be inserted
|
||||
GST_INFO_OBJECT(element, "gst_video_connector_setcaps failed, emit connection-failed signal");
|
||||
g_signal_emit(G_OBJECT(element), gst_video_connector_signals[SIGNAL_CONNECTION_FAILED], 0);
|
||||
|
||||
return gst_pad_set_caps(element->srcpad, caps);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstCaps *gst_video_connector_getcaps (GstPad * pad)
|
||||
{
|
||||
GstVideoConnector *element;
|
||||
element = GST_VIDEO_CONNECTOR (GST_PAD_PARENT (pad));
|
||||
|
||||
#if (GST_VERSION_MICRO > 25)
|
||||
GstCaps *caps = gst_pad_peer_get_caps_reffed(element->srcpad);
|
||||
#else
|
||||
GstCaps *caps = gst_pad_peer_get_caps(element->srcpad);
|
||||
#endif
|
||||
|
||||
if (!caps)
|
||||
caps = gst_caps_new_any();
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
static gboolean gst_video_connector_acceptcaps (GstPad * pad, GstCaps * caps)
|
||||
{
|
||||
GstVideoConnector *element;
|
||||
element = GST_VIDEO_CONNECTOR (GST_PAD_PARENT (pad));
|
||||
|
||||
return gst_pad_peer_accept_caps(element->srcpad, caps);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_video_connector_resend_new_segment(GstElement * element, gboolean emitFailedSignal)
|
||||
{
|
||||
GST_INFO_OBJECT(element, "New segment requested, failed signal enabled: %i", emitFailedSignal);
|
||||
GstVideoConnector *connector = GST_VIDEO_CONNECTOR(element);
|
||||
connector->relinked = TRUE;
|
||||
if (emitFailedSignal)
|
||||
connector->failedSignalEmited = FALSE;
|
||||
}
|
||||
|
||||
|
||||
static gboolean gst_video_connector_new_buffer_probe(GstObject *pad, GstBuffer *buffer, guint * object)
|
||||
{
|
||||
GstVideoConnector *element = GST_VIDEO_CONNECTOR (object);
|
||||
|
||||
/*
|
||||
If relinking is requested, the current buffer should be rejected and
|
||||
the new segment + previous buffer should be pushed first
|
||||
*/
|
||||
|
||||
if (element->relinked)
|
||||
GST_LOG_OBJECT(element, "rejected buffer because of new segment request");
|
||||
|
||||
return !element->relinked;
|
||||
}
|
||||
|
||||
|
||||
static GstFlowReturn
|
||||
gst_video_connector_chain (GstPad * pad, GstBuffer * buf)
|
||||
{
|
||||
GstFlowReturn res;
|
||||
GstVideoConnector *element;
|
||||
|
||||
element = GST_VIDEO_CONNECTOR (gst_pad_get_parent (pad));
|
||||
|
||||
do {
|
||||
/*
|
||||
Resend the segment message and last buffer to preroll the new sink.
|
||||
Sinks can be changed multiple times while paused,
|
||||
while loop allows to send the segment message and preroll
|
||||
all of them with the same buffer.
|
||||
*/
|
||||
while (element->relinked) {
|
||||
element->relinked = FALSE;
|
||||
|
||||
gint64 pos = element->segment.last_stop;
|
||||
|
||||
if (element->latest_buffer && GST_BUFFER_TIMESTAMP_IS_VALID(element->latest_buffer)) {
|
||||
pos = GST_BUFFER_TIMESTAMP (element->latest_buffer);
|
||||
}
|
||||
|
||||
//push a new segment and last buffer
|
||||
GstEvent *ev = gst_event_new_new_segment (TRUE,
|
||||
element->segment.rate,
|
||||
element->segment.format,
|
||||
pos, //start
|
||||
element->segment.stop,
|
||||
pos);
|
||||
|
||||
GST_DEBUG_OBJECT (element, "Pushing new segment event");
|
||||
if (!gst_pad_push_event (element->srcpad, ev)) {
|
||||
GST_WARNING_OBJECT (element,
|
||||
"Newsegment handling failed in %" GST_PTR_FORMAT,
|
||||
element->srcpad);
|
||||
}
|
||||
|
||||
if (element->latest_buffer) {
|
||||
GST_DEBUG_OBJECT (element, "Pushing latest buffer...");
|
||||
gst_buffer_ref(element->latest_buffer);
|
||||
gst_pad_push(element->srcpad, element->latest_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
gst_buffer_ref(buf);
|
||||
|
||||
//it's possible video sink is changed during gst_pad_push blocked by
|
||||
//pad lock, in this case ( element->relinked == TRUE )
|
||||
//the buffer should be rejected by the buffer probe and
|
||||
//the new segment + prev buffer should be sent before
|
||||
|
||||
GST_LOG_OBJECT (element, "Pushing buffer...");
|
||||
res = gst_pad_push (element->srcpad, buf);
|
||||
GST_LOG_OBJECT (element, "Pushed buffer: %s", gst_flow_get_name (res));
|
||||
|
||||
//if gst_pad_push failed give the service another chance,
|
||||
//it may still work with the colorspace element added
|
||||
if (!element->failedSignalEmited && res == GST_FLOW_NOT_NEGOTIATED) {
|
||||
element->failedSignalEmited = TRUE;
|
||||
GST_INFO_OBJECT(element, "gst_pad_push failed, emit connection-failed signal");
|
||||
g_signal_emit(G_OBJECT(element), gst_video_connector_signals[SIGNAL_CONNECTION_FAILED], 0);
|
||||
}
|
||||
|
||||
} while (element->relinked);
|
||||
|
||||
|
||||
if (element->latest_buffer) {
|
||||
gst_buffer_unref (element->latest_buffer);
|
||||
element->latest_buffer = NULL;
|
||||
}
|
||||
|
||||
//don't save the last video buffer on maemo6 because of buffers shortage
|
||||
//with omapxvsink
|
||||
#ifndef Q_WS_MAEMO_6
|
||||
element->latest_buffer = gst_buffer_ref(buf);
|
||||
#endif
|
||||
|
||||
gst_buffer_unref(buf);
|
||||
gst_object_unref (element);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static GstStateChangeReturn
|
||||
gst_video_connector_change_state (GstElement * element,
|
||||
GstStateChange transition)
|
||||
{
|
||||
GstVideoConnector *connector;
|
||||
GstStateChangeReturn result;
|
||||
|
||||
connector = GST_VIDEO_CONNECTOR(element);
|
||||
result = GST_ELEMENT_CLASS (parent_class)->change_state(element, transition);
|
||||
|
||||
switch (transition) {
|
||||
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
||||
gst_video_connector_reset (connector);
|
||||
break;
|
||||
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
||||
connector->relinked = FALSE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_video_connector_handle_sink_event (GstPad * pad, GstEvent * event)
|
||||
{
|
||||
if (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT) {
|
||||
GstVideoConnector *element = GST_VIDEO_CONNECTOR (gst_pad_get_parent (pad));
|
||||
|
||||
gboolean update;
|
||||
GstFormat format;
|
||||
gdouble rate, arate;
|
||||
gint64 start, stop, time;
|
||||
|
||||
gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
|
||||
&start, &stop, &time);
|
||||
|
||||
GST_LOG_OBJECT (element,
|
||||
"NEWSEGMENT update %d, rate %lf, applied rate %lf, "
|
||||
"format %d, " "%" G_GINT64_FORMAT " -- %" G_GINT64_FORMAT ", time %"
|
||||
G_GINT64_FORMAT, update, rate, arate, format, start, stop, time);
|
||||
|
||||
gst_segment_set_newsegment_full (&element->segment, update,
|
||||
rate, arate, format, start, stop, time);
|
||||
|
||||
gst_object_unref (element);
|
||||
}
|
||||
|
||||
return gst_pad_event_default (pad, event);
|
||||
}
|
||||
87
src/plugins/gstreamer/gstvideoconnector.h
Normal file
87
src/plugins/gstreamer/gstvideoconnector.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 QGSTVIDEOCONNECTOR_H
|
||||
#define QGSTVIDEOCONNECTOR_H
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_VIDEO_CONNECTOR \
|
||||
(gst_video_connector_get_type())
|
||||
#define GST_VIDEO_CONNECTOR(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VIDEO_CONNECTOR, GstVideoConnector))
|
||||
#define GST_VIDEO_CONNECTOR_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VIDEO_CONNECTOR, GstVideoConnectorClass))
|
||||
#define GST_IS_VIDEO_CONNECTOR(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VIDEO_CONNECTOR))
|
||||
#define GST_IS_VIDEO_CONNECTOR_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VIDEO_CONNECTOR))
|
||||
|
||||
typedef struct _GstVideoConnector GstVideoConnector;
|
||||
typedef struct _GstVideoConnectorClass GstVideoConnectorClass;
|
||||
|
||||
struct _GstVideoConnector {
|
||||
GstElement element;
|
||||
|
||||
GstPad *srcpad;
|
||||
GstPad *sinkpad;
|
||||
|
||||
gboolean relinked;
|
||||
gboolean failedSignalEmited;
|
||||
GstSegment segment;
|
||||
GstBuffer *latest_buffer;
|
||||
};
|
||||
|
||||
struct _GstVideoConnectorClass {
|
||||
GstElementClass parent_class;
|
||||
|
||||
/* action signal to resend new segment */
|
||||
void (*resend_new_segment) (GstElement * element, gboolean emitFailedSignal);
|
||||
};
|
||||
|
||||
GType gst_video_connector_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
||||
|
||||
27
src/plugins/gstreamer/mediacapture/mediacapture.pri
Normal file
27
src/plugins/gstreamer/mediacapture/mediacapture.pri
Normal file
@@ -0,0 +1,27 @@
|
||||
INCLUDEPATH += $$PWD
|
||||
|
||||
DEFINES += QMEDIA_GSTREAMER_CAPTURE
|
||||
|
||||
HEADERS += $$PWD/qgstreamercaptureservice.h \
|
||||
$$PWD/qgstreamercapturesession.h \
|
||||
$$PWD/qgstreameraudioencode.h \
|
||||
$$PWD/qgstreamervideoencode.h \
|
||||
$$PWD/qgstreamerrecordercontrol.h \
|
||||
$$PWD/qgstreamermediacontainercontrol.h \
|
||||
$$PWD/qgstreamercameracontrol.h \
|
||||
$$PWD/qgstreamerv4l2input.h \
|
||||
$$PWD/qgstreamercapturemetadatacontrol.h \
|
||||
$$PWD/qgstreamerimagecapturecontrol.h \
|
||||
$$PWD/qgstreamerimageencode.h
|
||||
|
||||
SOURCES += $$PWD/qgstreamercaptureservice.cpp \
|
||||
$$PWD/qgstreamercapturesession.cpp \
|
||||
$$PWD/qgstreameraudioencode.cpp \
|
||||
$$PWD/qgstreamervideoencode.cpp \
|
||||
$$PWD/qgstreamerrecordercontrol.cpp \
|
||||
$$PWD/qgstreamermediacontainercontrol.cpp \
|
||||
$$PWD/qgstreamercameracontrol.cpp \
|
||||
$$PWD/qgstreamerv4l2input.cpp \
|
||||
$$PWD/qgstreamercapturemetadatacontrol.cpp \
|
||||
$$PWD/qgstreamerimagecapturecontrol.cpp \
|
||||
$$PWD/qgstreamerimageencode.cpp
|
||||
292
src/plugins/gstreamer/mediacapture/qgstreameraudioencode.cpp
Normal file
292
src/plugins/gstreamer/mediacapture/qgstreameraudioencode.cpp
Normal file
@@ -0,0 +1,292 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "qgstreameraudioencode.h"
|
||||
#include "qgstreamercapturesession.h"
|
||||
#include "qgstreamermediacontainercontrol.h"
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
QGstreamerAudioEncode::QGstreamerAudioEncode(QObject *parent)
|
||||
:QAudioEncoderControl(parent)
|
||||
{
|
||||
QList<QByteArray> codecCandidates;
|
||||
|
||||
#if defined(Q_WS_MAEMO_5)
|
||||
codecCandidates << "audio/PCM"; //<< "audio/AMR" << "audio/AMR-WB" << "audio/speex";
|
||||
#elif defined(Q_WS_MAEMO_6)
|
||||
codecCandidates << "audio/AAC" << "audio/mpeg" << "audio/vorbis" << "audio/speex" << "audio/GSM"
|
||||
<< "audio/PCM" << "audio/AMR" << "audio/AMR-WB" << "audio/FLAC";
|
||||
#else
|
||||
codecCandidates << "audio/mpeg" << "audio/vorbis" << "audio/speex" << "audio/GSM"
|
||||
<< "audio/PCM" << "audio/AMR" << "audio/AMR-WB" << "audio/FLAC";
|
||||
#endif
|
||||
|
||||
#if defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6)
|
||||
m_elementNames["audio/AMR"] = "nokiaamrnbenc";
|
||||
m_elementNames["audio/AMR-WB"] = "nokiaamrwbenc";
|
||||
m_elementNames["audio/AAC"] = "nokiaaacenc";
|
||||
#else
|
||||
m_elementNames["audio/mpeg"] = "lamemp3enc";
|
||||
m_elementNames["audio/AMR"] = "amrnbenc";
|
||||
m_elementNames["audio/AMR-WB"] = "amrwbenc";
|
||||
#endif
|
||||
|
||||
m_elementNames["audio/vorbis"] = "vorbisenc";
|
||||
m_elementNames["audio/speex"] = "speexenc";
|
||||
m_elementNames["audio/PCM"] = "audioresample";
|
||||
m_elementNames["audio/FLAC"] = "flacenc";
|
||||
m_elementNames["audio/GSM"] = "gsmenc";
|
||||
|
||||
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();
|
||||
|
||||
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,
|
||||
QGstreamerMediaContainerControl::supportedStreamTypes(factory, GST_PAD_SRC));
|
||||
|
||||
gst_object_unref(GST_OBJECT(factory));
|
||||
}
|
||||
}
|
||||
|
||||
//if (!m_codecs.isEmpty())
|
||||
// m_audioSettings.setCodec(m_codecs[0]);
|
||||
}
|
||||
|
||||
QGstreamerAudioEncode::~QGstreamerAudioEncode()
|
||||
{
|
||||
}
|
||||
|
||||
QStringList QGstreamerAudioEncode::supportedAudioCodecs() const
|
||||
{
|
||||
return m_codecs;
|
||||
}
|
||||
|
||||
QString QGstreamerAudioEncode::codecDescription(const QString &codecName) const
|
||||
{
|
||||
return m_codecDescriptions.value(codecName);
|
||||
}
|
||||
|
||||
QStringList QGstreamerAudioEncode::supportedEncodingOptions(const QString &codec) const
|
||||
{
|
||||
return m_codecOptions.value(codec);
|
||||
}
|
||||
|
||||
QVariant QGstreamerAudioEncode::encodingOption(
|
||||
const QString &codec, const QString &name) const
|
||||
{
|
||||
return m_options[codec].value(name);
|
||||
}
|
||||
|
||||
void QGstreamerAudioEncode::setEncodingOption(
|
||||
const QString &codec, const QString &name, const QVariant &value)
|
||||
{
|
||||
m_options[codec][name] = value;
|
||||
}
|
||||
|
||||
QList<int> QGstreamerAudioEncode::supportedSampleRates(const QAudioEncoderSettings &, bool *) const
|
||||
{
|
||||
//TODO check element caps to find actual values
|
||||
|
||||
return QList<int>();
|
||||
}
|
||||
|
||||
QAudioEncoderSettings QGstreamerAudioEncode::audioSettings() const
|
||||
{
|
||||
return m_audioSettings;
|
||||
}
|
||||
|
||||
void QGstreamerAudioEncode::setAudioSettings(const QAudioEncoderSettings &settings)
|
||||
{
|
||||
m_audioSettings = settings;
|
||||
}
|
||||
|
||||
|
||||
GstElement *QGstreamerAudioEncode::createEncoder()
|
||||
{
|
||||
QString codec = m_audioSettings.codec();
|
||||
GstElement *encoderElement = gst_element_factory_make(m_elementNames.value(codec).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);
|
||||
|
||||
//qDebug() << "set caps filter:" << gst_caps_to_string(caps);
|
||||
|
||||
g_object_set(G_OBJECT(capsFilter), "caps", caps, NULL);
|
||||
}
|
||||
|
||||
if (encoderElement) {
|
||||
if (m_audioSettings.encodingMode() == QtMultimediaKit::ConstantQualityEncoding) {
|
||||
QtMultimediaKit::EncodingQuality qualityValue = m_audioSettings.quality();
|
||||
|
||||
if (codec == QLatin1String("audio/vorbis")) {
|
||||
double qualityTable[] = {
|
||||
0.1, //VeryLow
|
||||
0.3, //Low
|
||||
0.5, //Normal
|
||||
0.7, //High
|
||||
1.0 //VeryHigh
|
||||
};
|
||||
g_object_set(G_OBJECT(encoderElement), "quality", qualityTable[qualityValue], NULL);
|
||||
} else if (codec == QLatin1String("audio/mpeg")) {
|
||||
g_object_set(G_OBJECT(encoderElement), "target", 0, NULL); //constant quality mode
|
||||
qreal quality[] = {
|
||||
1, //VeryLow
|
||||
3, //Low
|
||||
5, //Normal
|
||||
7, //High
|
||||
9 //VeryHigh
|
||||
};
|
||||
g_object_set(G_OBJECT(encoderElement), "quality", 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) {
|
||||
if (codec == QLatin1String("audio/mpeg")) {
|
||||
g_object_set(G_OBJECT(encoderElement), "target", 1, NULL); //constant bitrate mode
|
||||
}
|
||||
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> QGstreamerAudioEncode::supportedStreamTypes(const QString &codecName) const
|
||||
{
|
||||
return m_streamTypes.value(codecName);
|
||||
}
|
||||
97
src/plugins/gstreamer/mediacapture/qgstreameraudioencode.h
Normal file
97
src/plugins/gstreamer/mediacapture/qgstreameraudioencode.h
Normal file
@@ -0,0 +1,97 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 QGSTREAMERAUDIOENCODE_H
|
||||
#define QGSTREAMERAUDIOENCODE_H
|
||||
|
||||
#include <qaudioencodercontrol.h>
|
||||
class QGstreamerCaptureSession;
|
||||
|
||||
#include <QtCore/qstringlist.h>
|
||||
#include <QtCore/qmap.h>
|
||||
#include <QtCore/qset.h>
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include <qaudioformat.h>
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class QGstreamerAudioEncode : public QAudioEncoderControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QGstreamerAudioEncode(QObject *parent);
|
||||
virtual ~QGstreamerAudioEncode();
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
#endif
|
||||
185
src/plugins/gstreamer/mediacapture/qgstreamercameracontrol.cpp
Normal file
185
src/plugins/gstreamer/mediacapture/qgstreamercameracontrol.cpp
Normal file
@@ -0,0 +1,185 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "qgstreamercameracontrol.h"
|
||||
#include "qgstreamerimageencode.h"
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtCore/qfile.h>
|
||||
|
||||
|
||||
QGstreamerCameraControl::QGstreamerCameraControl(QGstreamerCaptureSession *session)
|
||||
:QCameraControl(session),
|
||||
m_captureMode(QCamera::CaptureStillImage),
|
||||
m_session(session),
|
||||
m_state(QCamera::UnloadedState),
|
||||
m_status(QCamera::UnloadedStatus),
|
||||
m_reloadPending(false)
|
||||
|
||||
{
|
||||
connect(m_session, SIGNAL(stateChanged(QGstreamerCaptureSession::State)),
|
||||
this, SLOT(updateStatus()));
|
||||
|
||||
connect(m_session->imageEncodeControl(), SIGNAL(settingsChanged()),
|
||||
SLOT(reloadLater()));
|
||||
connect(m_session, SIGNAL(viewfinderChanged()),
|
||||
SLOT(reloadLater()));
|
||||
connect(m_session, SIGNAL(readyChanged(bool)),
|
||||
SLOT(reloadLater()));
|
||||
}
|
||||
|
||||
QGstreamerCameraControl::~QGstreamerCameraControl()
|
||||
{
|
||||
}
|
||||
|
||||
void QGstreamerCameraControl::setCaptureMode(QCamera::CaptureMode mode)
|
||||
{
|
||||
if (m_captureMode == mode)
|
||||
return;
|
||||
|
||||
switch (mode) {
|
||||
case QCamera::CaptureStillImage:
|
||||
m_session->setCaptureMode(QGstreamerCaptureSession::Image);
|
||||
break;
|
||||
case QCamera::CaptureVideo:
|
||||
m_session->setCaptureMode(QGstreamerCaptureSession::AudioAndVideo);
|
||||
break;
|
||||
}
|
||||
|
||||
emit captureModeChanged(mode);
|
||||
updateStatus();
|
||||
reloadLater();
|
||||
}
|
||||
|
||||
void QGstreamerCameraControl::setState(QCamera::State state)
|
||||
{
|
||||
if (m_state == state)
|
||||
return;
|
||||
|
||||
m_state = state;
|
||||
switch (state) {
|
||||
case QCamera::UnloadedState:
|
||||
case QCamera::LoadedState:
|
||||
m_session->setState(QGstreamerCaptureSession::StoppedState);
|
||||
break;
|
||||
case QCamera::ActiveState:
|
||||
//postpone changing to Active if the session is nor ready yet
|
||||
if (m_session->isReady()) {
|
||||
m_session->setState(QGstreamerCaptureSession::PreviewState);
|
||||
} else {
|
||||
#ifdef CAMEABIN_DEBUG
|
||||
qDebug() << "Camera session is not ready yet, postpone activating";
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
default:
|
||||
emit error(QCamera::NotSupportedFeatureError, tr("State not supported."));
|
||||
}
|
||||
|
||||
updateStatus();
|
||||
emit stateChanged(m_state);
|
||||
}
|
||||
|
||||
QCamera::State QGstreamerCameraControl::state() const
|
||||
{
|
||||
return m_state;
|
||||
}
|
||||
|
||||
void QGstreamerCameraControl::updateStatus()
|
||||
{
|
||||
QCamera::Status oldStatus = m_status;
|
||||
|
||||
switch (m_state) {
|
||||
case QCamera::UnloadedState:
|
||||
m_status = QCamera::UnloadedStatus;
|
||||
break;
|
||||
case QCamera::LoadedState:
|
||||
m_status = QCamera::LoadedStatus;
|
||||
break;
|
||||
case QCamera::ActiveState:
|
||||
if (m_session->state() == QGstreamerCaptureSession::StoppedState)
|
||||
m_status = QCamera::StartingStatus;
|
||||
else
|
||||
m_status = QCamera::ActiveStatus;
|
||||
break;
|
||||
}
|
||||
|
||||
if (oldStatus != m_status) {
|
||||
//qDebug() << "Status changed:" << m_status;
|
||||
emit statusChanged(m_status);
|
||||
}
|
||||
}
|
||||
|
||||
void QGstreamerCameraControl::reloadLater()
|
||||
{
|
||||
//qDebug() << "reload pipeline requested";
|
||||
if (!m_reloadPending && m_state == QCamera::ActiveState) {
|
||||
m_reloadPending = true;
|
||||
m_session->setState(QGstreamerCaptureSession::StoppedState);
|
||||
QMetaObject::invokeMethod(this, "reloadPipeline", Qt::QueuedConnection);
|
||||
}
|
||||
}
|
||||
|
||||
void QGstreamerCameraControl::reloadPipeline()
|
||||
{
|
||||
//qDebug() << "reload pipeline";
|
||||
if (m_reloadPending) {
|
||||
m_reloadPending = false;
|
||||
if (m_state == QCamera::ActiveState && m_session->isReady()) {
|
||||
m_session->setState(QGstreamerCaptureSession::PreviewState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool QGstreamerCameraControl::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;
|
||||
}
|
||||
}
|
||||
98
src/plugins/gstreamer/mediacapture/qgstreamercameracontrol.h
Normal file
98
src/plugins/gstreamer/mediacapture/qgstreamercameracontrol.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 QGSTREAMERCAMERACONTROL_H
|
||||
#define QGSTREAMERCAMERACONTROL_H
|
||||
|
||||
#include <QHash>
|
||||
#include <qcameracontrol.h>
|
||||
#include "qgstreamercapturesession.h"
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class QGstreamerCameraControl : public QCameraControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QGstreamerCameraControl( QGstreamerCaptureSession *session );
|
||||
virtual ~QGstreamerCameraControl();
|
||||
|
||||
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 { return m_captureMode; }
|
||||
void setCaptureMode(QCamera::CaptureMode mode);
|
||||
|
||||
bool isCaptureModeSupported(QCamera::CaptureMode mode) const
|
||||
{
|
||||
return mode == QCamera::CaptureStillImage || mode == QCamera::CaptureVideo;
|
||||
}
|
||||
|
||||
QCamera::LockTypes supportedLocks() const
|
||||
{
|
||||
return QCamera::NoLock;
|
||||
}
|
||||
|
||||
bool canChangeProperty(PropertyChangeType changeType, QCamera::Status status) const;
|
||||
|
||||
public slots:
|
||||
void reloadLater();
|
||||
|
||||
private slots:
|
||||
void updateStatus();
|
||||
void reloadPipeline();
|
||||
|
||||
|
||||
private:
|
||||
QCamera::CaptureMode m_captureMode;
|
||||
QGstreamerCaptureSession *m_session;
|
||||
QCamera::State m_state;
|
||||
QCamera::Status m_status;
|
||||
bool m_reloadPending;
|
||||
};
|
||||
|
||||
#endif // QGSTREAMERCAMERACONTROL_H
|
||||
@@ -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 "qgstreamercapturemetadatacontrol.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 }
|
||||
};
|
||||
|
||||
QGstreamerCaptureMetaDataControl::QGstreamerCaptureMetaDataControl(QObject *parent)
|
||||
:QMetaDataWriterControl(parent)
|
||||
{
|
||||
}
|
||||
|
||||
QVariant QGstreamerCaptureMetaDataControl::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 QGstreamerCaptureMetaDataControl::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> QGstreamerCaptureMetaDataControl::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 QGstreamerCaptureMetaDataControl::extendedMetaData(QString const &name) const
|
||||
{
|
||||
return m_values.value(name.toLatin1());
|
||||
}
|
||||
|
||||
void QGstreamerCaptureMetaDataControl::setExtendedMetaData(QString const &name, QVariant const &value)
|
||||
{
|
||||
m_values.insert(name.toLatin1(), value);
|
||||
emit QMetaDataWriterControl::metaDataChanged();
|
||||
emit metaDataChanged(m_values);
|
||||
}
|
||||
|
||||
QStringList QGstreamerCaptureMetaDataControl::availableExtendedMetaData() const
|
||||
{
|
||||
QStringList res;
|
||||
foreach (const QByteArray &key, m_values.keys())
|
||||
res.append(QString(key));
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -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 QGSTREAMERCAPTUREMETADATACONTROL_H
|
||||
#define QGSTREAMERCAPTUREMETADATACONTROL_H
|
||||
|
||||
#include <qmetadatawritercontrol.h>
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class QGstreamerCaptureMetaDataControl : public QMetaDataWriterControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QGstreamerCaptureMetaDataControl(QObject *parent);
|
||||
virtual ~QGstreamerCaptureMetaDataControl() {};
|
||||
|
||||
|
||||
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 // QGSTREAMERCAPTUREMETADATACONTROL_H
|
||||
185
src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp
Normal file
185
src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp
Normal file
@@ -0,0 +1,185 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "qgstreamercaptureservice.h"
|
||||
#include "qgstreamercapturesession.h"
|
||||
#include "qgstreamerrecordercontrol.h"
|
||||
#include "qgstreamermediacontainercontrol.h"
|
||||
#include "qgstreameraudioencode.h"
|
||||
#include "qgstreamervideoencode.h"
|
||||
#include "qgstreamerimageencode.h"
|
||||
#include "qgstreamerbushelper.h"
|
||||
#include "qgstreamercameracontrol.h"
|
||||
#include "qgstreamerv4l2input.h"
|
||||
#include "qgstreamercapturemetadatacontrol.h"
|
||||
|
||||
#include "qgstreameraudioinputendpointselector.h"
|
||||
#include "qgstreamervideoinputdevicecontrol.h"
|
||||
#include "qgstreamerimagecapturecontrol.h"
|
||||
|
||||
#include "qgstreamervideooverlay.h"
|
||||
#include "qgstreamervideorenderer.h"
|
||||
|
||||
#include "qgstreamervideowidget.h"
|
||||
|
||||
#include <qmediaserviceprovider.h>
|
||||
|
||||
|
||||
QGstreamerCaptureService::QGstreamerCaptureService(const QString &service, QObject *parent):
|
||||
QMediaService(parent)
|
||||
{
|
||||
m_captureSession = 0;
|
||||
m_cameraControl = 0;
|
||||
m_metaDataControl = 0;
|
||||
|
||||
m_videoInput = 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_AUDIOSOURCE) {
|
||||
m_captureSession = new QGstreamerCaptureSession(QGstreamerCaptureSession::Audio, this);
|
||||
}
|
||||
|
||||
if (service == Q_MEDIASERVICE_CAMERA) {
|
||||
m_captureSession = new QGstreamerCaptureSession(QGstreamerCaptureSession::AudioAndVideo, this);
|
||||
m_cameraControl = new QGstreamerCameraControl(m_captureSession);
|
||||
m_videoInput = new QGstreamerV4L2Input(this);
|
||||
m_captureSession->setVideoInput(m_videoInput);
|
||||
m_videoInputDevice = new QGstreamerVideoInputDeviceControl(this);
|
||||
|
||||
connect(m_videoInputDevice, SIGNAL(selectedDeviceChanged(QString)),
|
||||
m_videoInput, SLOT(setDevice(QString)));
|
||||
|
||||
if (m_videoInputDevice->deviceCount())
|
||||
m_videoInput->setDevice(m_videoInputDevice->deviceName(m_videoInputDevice->selectedDevice()));
|
||||
|
||||
m_videoRenderer = new QGstreamerVideoRenderer(this);
|
||||
|
||||
#if defined(Q_WS_X11) && !defined(QT_NO_XVIDEO)
|
||||
m_videoWindow = new QGstreamerVideoOverlay(this);
|
||||
m_videoWidgetControl = new QGstreamerVideoWidgetControl(this);
|
||||
#endif
|
||||
m_imageCaptureControl = new QGstreamerImageCaptureControl(m_captureSession);
|
||||
}
|
||||
|
||||
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 QGstreamerCaptureMetaDataControl(this);
|
||||
connect(m_metaDataControl, SIGNAL(metaDataChanged(QMap<QByteArray,QVariant>)),
|
||||
m_captureSession, SLOT(setMetaData(QMap<QByteArray,QVariant>)));
|
||||
}
|
||||
|
||||
QGstreamerCaptureService::~QGstreamerCaptureService()
|
||||
{
|
||||
}
|
||||
|
||||
QMediaControl *QGstreamerCaptureService::requestControl(const char *name)
|
||||
{
|
||||
if (!m_captureSession)
|
||||
return 0;
|
||||
|
||||
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 (!m_videoOutput) {
|
||||
if (qstrcmp(name, QVideoRendererControl_iid) == 0) {
|
||||
m_videoOutput = m_videoRenderer;
|
||||
m_captureSession->setVideoPreview(m_videoRenderer);
|
||||
} else if (qstrcmp(name, QVideoWindowControl_iid) == 0) {
|
||||
m_videoOutput = m_videoWindow;
|
||||
m_captureSession->setVideoPreview(m_videoWindow);
|
||||
} else if (qstrcmp(name, QVideoWidgetControl_iid) == 0) {
|
||||
m_captureSession->setVideoPreview(m_videoWidgetControl);
|
||||
m_videoOutput = m_videoWidgetControl;
|
||||
}
|
||||
|
||||
if (m_videoOutput)
|
||||
return m_videoOutput;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void QGstreamerCaptureService::releaseControl(QMediaControl *control)
|
||||
{
|
||||
if (control && control == m_videoOutput) {
|
||||
m_videoOutput = 0;
|
||||
m_captureSession->setVideoPreview(0);
|
||||
}
|
||||
}
|
||||
@@ -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 QGSTREAMERCAPTURESERVICE_H
|
||||
#define QGSTREAMERCAPTURESERVICE_H
|
||||
|
||||
#include <qmediaservice.h>
|
||||
#include <qmediacontrol.h>
|
||||
|
||||
#include <gst/gst.h>
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QAudioEndpointSelector;
|
||||
class QVideoDeviceControl;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class QGstreamerCaptureSession;
|
||||
class QGstreamerCameraControl;
|
||||
class QGstreamerMessage;
|
||||
class QGstreamerBusHelper;
|
||||
class QGstreamerVideoRenderer;
|
||||
class QGstreamerVideoOverlay;
|
||||
class QGstreamerVideoWidgetControl;
|
||||
class QGstreamerElementFactory;
|
||||
class QGstreamerCaptureMetaDataControl;
|
||||
class QGstreamerImageCaptureControl;
|
||||
class QGstreamerV4L2Input;
|
||||
|
||||
class QGstreamerCaptureService : public QMediaService
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QGstreamerCaptureService(const QString &service, QObject *parent = 0);
|
||||
virtual ~QGstreamerCaptureService();
|
||||
|
||||
QMediaControl *requestControl(const char *name);
|
||||
void releaseControl(QMediaControl *);
|
||||
|
||||
private:
|
||||
void setAudioPreview(GstElement*);
|
||||
|
||||
QGstreamerCaptureSession *m_captureSession;
|
||||
QGstreamerCameraControl *m_cameraControl;
|
||||
QGstreamerV4L2Input *m_videoInput;
|
||||
QGstreamerCaptureMetaDataControl *m_metaDataControl;
|
||||
|
||||
QAudioEndpointSelector *m_audioInputEndpointSelector;
|
||||
QVideoDeviceControl *m_videoInputDevice;
|
||||
|
||||
QMediaControl *m_videoOutput;
|
||||
|
||||
QGstreamerVideoRenderer *m_videoRenderer;
|
||||
QMediaControl *m_videoWindow;
|
||||
QMediaControl *m_videoWidgetControl;
|
||||
QGstreamerImageCaptureControl *m_imageCaptureControl;
|
||||
};
|
||||
|
||||
#endif // QGSTREAMERCAPTURESERVICE_H
|
||||
1051
src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp
Normal file
1051
src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp
Normal file
File diff suppressed because it is too large
Load Diff
211
src/plugins/gstreamer/mediacapture/qgstreamercapturesession.h
Normal file
211
src/plugins/gstreamer/mediacapture/qgstreamercapturesession.h
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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QGSTREAMERCAPTURESESSION_H
|
||||
#define QGSTREAMERCAPTURESESSION_H
|
||||
|
||||
#include <qmediarecordercontrol.h>
|
||||
#include <qmediarecorder.h>
|
||||
|
||||
#include <QtCore/qurl.h>
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "qgstreamerbushelper.h"
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class QGstreamerMessage;
|
||||
class QGstreamerBusHelper;
|
||||
class QGstreamerAudioEncode;
|
||||
class QGstreamerVideoEncode;
|
||||
class QGstreamerImageEncode;
|
||||
class QGstreamerRecorderControl;
|
||||
class QGstreamerMediaContainerControl;
|
||||
class QGstreamerVideoRendererInterface;
|
||||
|
||||
class QGstreamerElementFactory
|
||||
{
|
||||
public:
|
||||
virtual GstElement *buildElement() = 0;
|
||||
virtual void prepareWinId() {}
|
||||
};
|
||||
|
||||
class QGstreamerVideoInput : public QGstreamerElementFactory
|
||||
{
|
||||
public:
|
||||
virtual QList<qreal> supportedFrameRates(const QSize &frameSize = QSize()) const = 0;
|
||||
virtual QList<QSize> supportedResolutions(qreal frameRate = -1) const = 0;
|
||||
};
|
||||
|
||||
class QGstreamerCaptureSession : public QObject, public QGstreamerSyncEventFilter
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(qint64 duration READ duration NOTIFY durationChanged)
|
||||
Q_ENUMS(State)
|
||||
Q_ENUMS(CaptureMode)
|
||||
public:
|
||||
enum CaptureMode { Audio = 1, Video = 2, Image=4, AudioAndVideo = Audio | Video };
|
||||
enum State { StoppedState, PreviewState, PausedState, RecordingState };
|
||||
|
||||
QGstreamerCaptureSession(CaptureMode captureMode, QObject *parent);
|
||||
~QGstreamerCaptureSession();
|
||||
|
||||
CaptureMode captureMode() const { return m_captureMode; }
|
||||
void setCaptureMode(CaptureMode);
|
||||
|
||||
QUrl outputLocation() const;
|
||||
bool setOutputLocation(const QUrl& sink);
|
||||
|
||||
QGstreamerAudioEncode *audioEncodeControl() const { return m_audioEncodeControl; }
|
||||
QGstreamerVideoEncode *videoEncodeControl() const { return m_videoEncodeControl; }
|
||||
QGstreamerImageEncode *imageEncodeControl() const { return m_imageEncodeControl; }
|
||||
|
||||
QGstreamerRecorderControl *recorderControl() const { return m_recorderControl; }
|
||||
QGstreamerMediaContainerControl *mediaContainerControl() const { return m_mediaContainerControl; }
|
||||
|
||||
QGstreamerElementFactory *audioInput() const { return m_audioInputFactory; }
|
||||
void setAudioInput(QGstreamerElementFactory *audioInput);
|
||||
|
||||
QGstreamerElementFactory *audioPreview() const { return m_audioPreviewFactory; }
|
||||
void setAudioPreview(QGstreamerElementFactory *audioPreview);
|
||||
|
||||
QGstreamerVideoInput *videoInput() const { return m_videoInputFactory; }
|
||||
void setVideoInput(QGstreamerVideoInput *videoInput);
|
||||
|
||||
QObject *videoPreview() const { return m_viewfinder; }
|
||||
void setVideoPreview(QObject *viewfinder);
|
||||
|
||||
void captureImage(int requestId, const QString &fileName);
|
||||
|
||||
State state() const;
|
||||
qint64 duration() const;
|
||||
bool isMuted() const { return m_muted; }
|
||||
|
||||
bool isReady() const;
|
||||
|
||||
bool processSyncMessage(const QGstreamerMessage &message);
|
||||
|
||||
signals:
|
||||
void stateChanged(QGstreamerCaptureSession::State state);
|
||||
void durationChanged(qint64 duration);
|
||||
void error(int error, const QString &errorString);
|
||||
void imageExposed(int requestId);
|
||||
void imageCaptured(int requestId, const QImage &img);
|
||||
void imageSaved(int requestId, const QString &path);
|
||||
void mutedChanged(bool);
|
||||
void readyChanged(bool);
|
||||
void viewfinderChanged();
|
||||
|
||||
public slots:
|
||||
void setState(QGstreamerCaptureSession::State);
|
||||
void setCaptureDevice(const QString &deviceName);
|
||||
|
||||
void dumpGraph(const QString &fileName);
|
||||
|
||||
void setMetaData(const QMap<QByteArray, QVariant>&);
|
||||
void setMuted(bool);
|
||||
|
||||
private slots:
|
||||
void busMessage(const QGstreamerMessage &message);
|
||||
|
||||
private:
|
||||
enum PipelineMode { EmptyPipeline, PreviewPipeline, RecordingPipeline, PreviewAndRecordingPipeline };
|
||||
|
||||
GstElement *buildEncodeBin();
|
||||
GstElement *buildAudioSrc();
|
||||
GstElement *buildAudioPreview();
|
||||
GstElement *buildVideoSrc();
|
||||
GstElement *buildVideoPreview();
|
||||
GstElement *buildImageCapture();
|
||||
|
||||
void waitForStopped();
|
||||
bool rebuildGraph(QGstreamerCaptureSession::PipelineMode newMode);
|
||||
|
||||
QUrl m_sink;
|
||||
QString m_captureDevice;
|
||||
State m_state;
|
||||
State m_pendingState;
|
||||
bool m_waitingForEos;
|
||||
PipelineMode m_pipelineMode;
|
||||
QGstreamerCaptureSession::CaptureMode m_captureMode;
|
||||
QMap<QByteArray, QVariant> m_metaData;
|
||||
|
||||
QGstreamerElementFactory *m_audioInputFactory;
|
||||
QGstreamerElementFactory *m_audioPreviewFactory;
|
||||
QGstreamerVideoInput *m_videoInputFactory;
|
||||
QObject *m_viewfinder;
|
||||
QGstreamerVideoRendererInterface *m_viewfinderInterface;
|
||||
|
||||
QGstreamerAudioEncode *m_audioEncodeControl;
|
||||
QGstreamerVideoEncode *m_videoEncodeControl;
|
||||
QGstreamerImageEncode *m_imageEncodeControl;
|
||||
QGstreamerRecorderControl *m_recorderControl;
|
||||
QGstreamerMediaContainerControl *m_mediaContainerControl;
|
||||
|
||||
QGstreamerBusHelper *m_busHelper;
|
||||
GstBus* m_bus;
|
||||
GstElement *m_pipeline;
|
||||
|
||||
GstElement *m_audioSrc;
|
||||
GstElement *m_audioTee;
|
||||
GstElement *m_audioPreviewQueue;
|
||||
GstElement *m_audioPreview;
|
||||
GstElement *m_audioVolume;
|
||||
bool m_muted;
|
||||
|
||||
GstElement *m_videoSrc;
|
||||
GstElement *m_videoTee;
|
||||
GstElement *m_videoPreviewQueue;
|
||||
GstElement *m_videoPreview;
|
||||
|
||||
GstElement *m_imageCaptureBin;
|
||||
|
||||
GstElement *m_encodeBin;
|
||||
|
||||
public:
|
||||
bool m_passImage;
|
||||
bool m_passPrerollImage;
|
||||
QString m_imageFileName;
|
||||
int m_imageRequestId;
|
||||
};
|
||||
|
||||
#endif // QGSTREAMERCAPTURESESSION_H
|
||||
@@ -0,0 +1,98 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "qgstreamerimagecapturecontrol.h"
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QDir>
|
||||
|
||||
QGstreamerImageCaptureControl::QGstreamerImageCaptureControl(QGstreamerCaptureSession *session)
|
||||
:QCameraImageCaptureControl(session), m_session(session), m_ready(false), m_lastId(0)
|
||||
{
|
||||
connect(m_session, SIGNAL(stateChanged(QGstreamerCaptureSession::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(imageSaved(int,QString)), this, SIGNAL(imageSaved(int,QString)));
|
||||
}
|
||||
|
||||
QGstreamerImageCaptureControl::~QGstreamerImageCaptureControl()
|
||||
{
|
||||
}
|
||||
|
||||
bool QGstreamerImageCaptureControl::isReadyForCapture() const
|
||||
{
|
||||
return m_ready;
|
||||
}
|
||||
|
||||
int QGstreamerImageCaptureControl::capture(const QString &fileName)
|
||||
{
|
||||
QString path = fileName;
|
||||
if (path.isEmpty()) {
|
||||
int lastImage = 0;
|
||||
QDir outputDir = QDir::currentPath();
|
||||
foreach(QString fileName, outputDir.entryList(QStringList() << "img_*.jpg")) {
|
||||
int imgNumber = fileName.mid(4, fileName.size()-8).toInt();
|
||||
lastImage = qMax(lastImage, imgNumber);
|
||||
}
|
||||
|
||||
path = QString("img_%1.jpg").arg(lastImage+1,
|
||||
4, //fieldWidth
|
||||
10,
|
||||
QLatin1Char('0'));
|
||||
}
|
||||
m_lastId++;
|
||||
|
||||
m_session->captureImage(m_lastId, path);
|
||||
|
||||
return m_lastId;
|
||||
}
|
||||
|
||||
void QGstreamerImageCaptureControl::cancelCapture()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void QGstreamerImageCaptureControl::updateState()
|
||||
{
|
||||
bool ready = m_session->state() == QGstreamerCaptureSession::PreviewState;
|
||||
if (m_ready != ready) {
|
||||
emit readyForCaptureChanged(m_ready = ready);
|
||||
}
|
||||
}
|
||||
@@ -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 QGSTREAMERIMAGECAPTURECONTROL_H
|
||||
#define QGSTREAMERIMAGECAPTURECONTROL_H
|
||||
|
||||
#include <qcameraimagecapturecontrol.h>
|
||||
#include "qgstreamercapturesession.h"
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class QGstreamerImageCaptureControl : public QCameraImageCaptureControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QGstreamerImageCaptureControl(QGstreamerCaptureSession *session);
|
||||
virtual ~QGstreamerImageCaptureControl();
|
||||
|
||||
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();
|
||||
|
||||
private:
|
||||
QGstreamerCaptureSession *m_session;
|
||||
bool m_ready;
|
||||
int m_lastId;
|
||||
};
|
||||
|
||||
#endif // QGSTREAMERCAPTURECORNTROL_H
|
||||
90
src/plugins/gstreamer/mediacapture/qgstreamerimageencode.cpp
Normal file
90
src/plugins/gstreamer/mediacapture/qgstreamerimageencode.cpp
Normal file
@@ -0,0 +1,90 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "qgstreamerimageencode.h"
|
||||
#include "qgstreamercapturesession.h"
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
QGstreamerImageEncode::QGstreamerImageEncode(QGstreamerCaptureSession *session)
|
||||
:QImageEncoderControl(session), m_session(session)
|
||||
{
|
||||
}
|
||||
|
||||
QGstreamerImageEncode::~QGstreamerImageEncode()
|
||||
{
|
||||
}
|
||||
|
||||
QList<QSize> QGstreamerImageEncode::supportedResolutions(const QImageEncoderSettings &, bool *continuous) const
|
||||
{
|
||||
if (continuous)
|
||||
*continuous = m_session->videoInput() != 0;
|
||||
|
||||
return m_session->videoInput() ? m_session->videoInput()->supportedResolutions() : QList<QSize>();
|
||||
}
|
||||
|
||||
QStringList QGstreamerImageEncode::supportedImageCodecs() const
|
||||
{
|
||||
return QStringList() << "jpeg";
|
||||
}
|
||||
|
||||
QString QGstreamerImageEncode::imageCodecDescription(const QString &codecName) const
|
||||
{
|
||||
if (codecName == "jpeg")
|
||||
return tr("JPEG image encoder");
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
QImageEncoderSettings QGstreamerImageEncode::imageSettings() const
|
||||
{
|
||||
return m_settings;
|
||||
}
|
||||
|
||||
void QGstreamerImageEncode::setImageSettings(const QImageEncoderSettings &settings)
|
||||
{
|
||||
if (m_settings != settings) {
|
||||
m_settings = settings;
|
||||
emit settingsChanged();
|
||||
}
|
||||
}
|
||||
80
src/plugins/gstreamer/mediacapture/qgstreamerimageencode.h
Normal file
80
src/plugins/gstreamer/mediacapture/qgstreamerimageencode.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 QGSTREAMERIMAGEENCODE_H
|
||||
#define QGSTREAMERIMAGEENCODE_H
|
||||
|
||||
class QGstreamerCaptureSession;
|
||||
|
||||
#include <qimageencodercontrol.h>
|
||||
|
||||
#include <QtCore/qstringlist.h>
|
||||
#include <QtCore/qmap.h>
|
||||
|
||||
#include <gst/gst.h>
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class QGstreamerImageEncode : public QImageEncoderControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QGstreamerImageEncode(QGstreamerCaptureSession *session);
|
||||
virtual ~QGstreamerImageEncode();
|
||||
|
||||
QList<QSize> supportedResolutions(const QImageEncoderSettings &settings = QImageEncoderSettings(),
|
||||
bool *continuous = 0) const;
|
||||
|
||||
QStringList supportedImageCodecs() const;
|
||||
QString imageCodecDescription(const QString &codecName) const;
|
||||
|
||||
QImageEncoderSettings imageSettings() const;
|
||||
void setImageSettings(const QImageEncoderSettings &settings);
|
||||
|
||||
Q_SIGNALS:
|
||||
void settingsChanged();
|
||||
|
||||
private:
|
||||
QImageEncoderSettings m_settings;
|
||||
|
||||
QGstreamerCaptureSession *m_session;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,135 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "qgstreamermediacontainercontrol.h"
|
||||
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
|
||||
QGstreamerMediaContainerControl::QGstreamerMediaContainerControl(QObject *parent)
|
||||
:QMediaContainerControl(parent)
|
||||
{
|
||||
QList<QByteArray> formatCandidates;
|
||||
formatCandidates << "matroska" << "ogg" << "mp4" << "wav" << "quicktime" << "avi" << "3gpp";
|
||||
formatCandidates << "flv" << "amr" << "asf" << "dv" << "gif";
|
||||
formatCandidates << "mpeg" << "vob" << "mpegts" << "3g2" << "3gp";
|
||||
formatCandidates << "raw";
|
||||
|
||||
m_elementNames["matroska"] = "matroskamux";
|
||||
m_elementNames["ogg"] = "oggmux";
|
||||
m_elementNames["mp4"] = "ffmux_mp4";
|
||||
m_elementNames["quicktime"] = "ffmux_mov";
|
||||
m_elementNames["avi"] = "avimux";
|
||||
m_elementNames["3gpp"] = "gppmux";
|
||||
m_elementNames["flv"] = "flvmux";
|
||||
m_elementNames["wav"] = "wavenc";
|
||||
m_elementNames["amr"] = "ffmux_amr";
|
||||
m_elementNames["asf"] = "ffmux_asf";
|
||||
m_elementNames["dv"] = "ffmux_dv";
|
||||
m_elementNames["gif"] = "ffmux_gif";
|
||||
m_elementNames["mpeg"] = "ffmux_mpeg";
|
||||
m_elementNames["vob"] = "ffmux_vob";
|
||||
m_elementNames["mpegts"] = "ffmux_mpegts";
|
||||
m_elementNames["3g2"] = "ffmux_3g2";
|
||||
m_elementNames["3gp"] = "ffmux_3gp";
|
||||
m_elementNames["raw"] = "identity";
|
||||
|
||||
m_containerExtensions["matroska"] = "mkv";
|
||||
m_containerExtensions["quicktime"] = "mov";
|
||||
m_containerExtensions["mpegts"] = "m2t";
|
||||
m_containerExtensions["mpeg"] = "mpg";
|
||||
|
||||
QSet<QString> allTypes;
|
||||
|
||||
foreach( const QByteArray& formatName, formatCandidates ) {
|
||||
QByteArray elementName = m_elementNames[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));
|
||||
}
|
||||
}
|
||||
|
||||
//if (!m_supportedContainers.isEmpty())
|
||||
// setContainerMimeType(m_supportedContainers[0]);
|
||||
}
|
||||
|
||||
QSet<QString> QGstreamerMediaContainerControl::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> QGstreamerMediaContainerControl::supportedStreamTypes(const QString &container) const
|
||||
{
|
||||
return m_streamTypes.value(container);
|
||||
}
|
||||
|
||||
QString QGstreamerMediaContainerControl::containerExtension() const
|
||||
{
|
||||
return m_containerExtensions.value(m_format, m_format);
|
||||
}
|
||||
@@ -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 QGSTREAMERMEDIACONTAINERCONTROL_H
|
||||
#define QGSTREAMERMEDIACONTAINERCONTROL_H
|
||||
|
||||
#include <qmediacontainercontrol.h>
|
||||
#include <QtCore/qstringlist.h>
|
||||
#include <QtCore/qset.h>
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class QGstreamerMediaContainerControl : public QMediaContainerControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QGstreamerMediaContainerControl(QObject *parent);
|
||||
virtual ~QGstreamerMediaContainerControl() {};
|
||||
|
||||
virtual QStringList supportedContainers() const { return m_supportedContainers; }
|
||||
virtual QString containerMimeType() const { return m_format; }
|
||||
virtual void setContainerMimeType(const QString &formatMimeType) { m_format = formatMimeType; }
|
||||
|
||||
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);
|
||||
|
||||
QString containerExtension() const;
|
||||
|
||||
private:
|
||||
QString m_format;
|
||||
QStringList m_supportedContainers;
|
||||
QMap<QString,QByteArray> m_elementNames;
|
||||
QMap<QString, QString> m_containerDescriptions;
|
||||
QMap<QString, QString> m_containerExtensions;
|
||||
QMap<QString, QSet<QString> > m_streamTypes;
|
||||
};
|
||||
|
||||
#endif // QGSTREAMERMEDIACONTAINERCONTROL_H
|
||||
289
src/plugins/gstreamer/mediacapture/qgstreamerrecordercontrol.cpp
Normal file
289
src/plugins/gstreamer/mediacapture/qgstreamerrecordercontrol.cpp
Normal file
@@ -0,0 +1,289 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "qgstreamerrecordercontrol.h"
|
||||
#include "qgstreameraudioencode.h"
|
||||
#include "qgstreamervideoencode.h"
|
||||
#include "qgstreamermediacontainercontrol.h"
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
QGstreamerRecorderControl::QGstreamerRecorderControl(QGstreamerCaptureSession *session)
|
||||
:QMediaRecorderControl(session), m_session(session), m_state(QMediaRecorder::StoppedState)
|
||||
{
|
||||
connect(m_session, SIGNAL(stateChanged(QGstreamerCaptureSession::State)), SLOT(updateState()));
|
||||
connect(m_session, SIGNAL(error(int,QString)), SIGNAL(error(int,QString)));
|
||||
connect(m_session, SIGNAL(durationChanged(qint64)), SIGNAL(durationChanged(qint64)));
|
||||
connect(m_session, SIGNAL(mutedChanged(bool)), SIGNAL(mutedChanged(bool)));
|
||||
m_hasPreviewState = m_session->captureMode() != QGstreamerCaptureSession::Audio;
|
||||
}
|
||||
|
||||
QGstreamerRecorderControl::~QGstreamerRecorderControl()
|
||||
{
|
||||
}
|
||||
|
||||
QUrl QGstreamerRecorderControl::outputLocation() const
|
||||
{
|
||||
return m_session->outputLocation();
|
||||
}
|
||||
|
||||
bool QGstreamerRecorderControl::setOutputLocation(const QUrl &sink)
|
||||
{
|
||||
m_outputLocation = sink;
|
||||
m_session->setOutputLocation(sink);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
QMediaRecorder::State QGstreamerRecorderControl::state() const
|
||||
{
|
||||
switch ( m_session->state() ) {
|
||||
case QGstreamerCaptureSession::RecordingState:
|
||||
return QMediaRecorder::RecordingState;
|
||||
case QGstreamerCaptureSession::PausedState:
|
||||
return QMediaRecorder::PausedState;
|
||||
case QGstreamerCaptureSession::PreviewState:
|
||||
case QGstreamerCaptureSession::StoppedState:
|
||||
return QMediaRecorder::StoppedState;
|
||||
}
|
||||
|
||||
return QMediaRecorder::StoppedState;
|
||||
|
||||
}
|
||||
|
||||
void QGstreamerRecorderControl::updateState()
|
||||
{
|
||||
QMediaRecorder::State newState = state();
|
||||
if (m_state != newState) {
|
||||
m_state = newState;
|
||||
emit stateChanged(m_state);
|
||||
}
|
||||
}
|
||||
|
||||
qint64 QGstreamerRecorderControl::duration() const
|
||||
{
|
||||
return m_session->duration();
|
||||
}
|
||||
|
||||
void QGstreamerRecorderControl::record()
|
||||
{
|
||||
if (m_outputLocation.isEmpty()) {
|
||||
QString container = m_session->mediaContainerControl()->containerExtension();
|
||||
if (container.isEmpty())
|
||||
container = "raw";
|
||||
|
||||
m_session->setOutputLocation(QUrl(generateFileName(defaultDir(), container)));
|
||||
}
|
||||
|
||||
m_session->dumpGraph("before-record");
|
||||
if (!m_hasPreviewState || m_session->state() != QGstreamerCaptureSession::StoppedState) {
|
||||
m_session->setState(QGstreamerCaptureSession::RecordingState);
|
||||
} else
|
||||
emit error(QMediaRecorder::ResourceError, tr("Service has not been started"));
|
||||
|
||||
m_session->dumpGraph("after-record");
|
||||
}
|
||||
|
||||
void QGstreamerRecorderControl::pause()
|
||||
{
|
||||
m_session->dumpGraph("before-pause");
|
||||
if (!m_hasPreviewState || m_session->state() != QGstreamerCaptureSession::StoppedState) {
|
||||
m_session->setState(QGstreamerCaptureSession::PausedState);
|
||||
} else
|
||||
emit error(QMediaRecorder::ResourceError, tr("Service has not been started"));
|
||||
}
|
||||
|
||||
void QGstreamerRecorderControl::stop()
|
||||
{
|
||||
if (!m_hasPreviewState) {
|
||||
m_session->setState(QGstreamerCaptureSession::StoppedState);
|
||||
} else {
|
||||
if (m_session->state() != QGstreamerCaptureSession::StoppedState)
|
||||
m_session->setState(QGstreamerCaptureSession::PreviewState);
|
||||
}
|
||||
}
|
||||
|
||||
void QGstreamerRecorderControl::applySettings()
|
||||
{
|
||||
//Check the codecs are compatible with container,
|
||||
//and choose the compatible codecs/container if omitted
|
||||
QGstreamerAudioEncode *audioEncodeControl = m_session->audioEncodeControl();
|
||||
QGstreamerVideoEncode *videoEncodeControl = m_session->videoEncodeControl();
|
||||
QGstreamerMediaContainerControl *mediaContainerControl = m_session->mediaContainerControl();
|
||||
|
||||
bool needAudio = m_session->captureMode() & QGstreamerCaptureSession::Audio;
|
||||
bool needVideo = m_session->captureMode() & QGstreamerCaptureSession::Video;
|
||||
|
||||
QStringList containerCandidates;
|
||||
if (mediaContainerControl->containerMimeType().isEmpty())
|
||||
containerCandidates = mediaContainerControl->supportedContainers();
|
||||
else
|
||||
containerCandidates << mediaContainerControl->containerMimeType();
|
||||
|
||||
|
||||
QStringList audioCandidates;
|
||||
if (needAudio) {
|
||||
QAudioEncoderSettings audioSettings = audioEncodeControl->audioSettings();
|
||||
if (audioSettings.codec().isEmpty())
|
||||
audioCandidates = audioEncodeControl->supportedAudioCodecs();
|
||||
else
|
||||
audioCandidates << audioSettings.codec();
|
||||
}
|
||||
|
||||
QStringList videoCandidates;
|
||||
if (needVideo) {
|
||||
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();
|
||||
|
||||
if (needAudio) {
|
||||
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;
|
||||
}
|
||||
|
||||
if (needVideo) {
|
||||
bool 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()) {
|
||||
emit error(QMediaRecorder::FormatError, tr("Not compatible codecs and container format."));
|
||||
} else {
|
||||
mediaContainerControl->setContainerMimeType(container);
|
||||
|
||||
if (needAudio) {
|
||||
QAudioEncoderSettings audioSettings = audioEncodeControl->audioSettings();
|
||||
audioSettings.setCodec(audioCodec);
|
||||
audioEncodeControl->setAudioSettings(audioSettings);
|
||||
}
|
||||
|
||||
if (needVideo) {
|
||||
QVideoEncoderSettings videoSettings = videoEncodeControl->videoSettings();
|
||||
videoSettings.setCodec(videoCodec);
|
||||
videoEncodeControl->setVideoSettings(videoSettings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool QGstreamerRecorderControl::isMuted() const
|
||||
{
|
||||
return m_session->isMuted();
|
||||
}
|
||||
|
||||
void QGstreamerRecorderControl::setMuted(bool muted)
|
||||
{
|
||||
m_session->setMuted(muted);
|
||||
}
|
||||
|
||||
QDir QGstreamerRecorderControl::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 QGstreamerRecorderControl::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);
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 QGSTREAMERRECORDERCONTROL_H
|
||||
#define QGSTREAMERRECORDERCONTROL_H
|
||||
|
||||
#include <QtCore/QDir>
|
||||
|
||||
#include <qmediarecordercontrol.h>
|
||||
#include "qgstreamercapturesession.h"
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class QGstreamerRecorderControl : public QMediaRecorderControl
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QGstreamerRecorderControl(QGstreamerCaptureSession *session);
|
||||
virtual ~QGstreamerRecorderControl();
|
||||
|
||||
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 slots:
|
||||
void updateState();
|
||||
|
||||
private:
|
||||
QDir defaultDir() const;
|
||||
QString generateFileName(const QDir &dir, const QString &ext) const;
|
||||
|
||||
QUrl m_outputLocation;
|
||||
QGstreamerCaptureSession *m_session;
|
||||
QMediaRecorder::State m_state;
|
||||
bool m_hasPreviewState;
|
||||
};
|
||||
|
||||
#endif // QGSTREAMERCAPTURECORNTROL_H
|
||||
297
src/plugins/gstreamer/mediacapture/qgstreamerv4l2input.cpp
Normal file
297
src/plugins/gstreamer/mediacapture/qgstreamerv4l2input.cpp
Normal file
@@ -0,0 +1,297 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "qgstreamerv4l2input.h"
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtCore/qfile.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>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
static inline uint qHash(const QSize& key) { return uint(key.width()*256+key.height()); }
|
||||
|
||||
static bool operator<(const QSize &s1, const QSize s2)
|
||||
{
|
||||
return s1.width()*s1.height() < s2.width()*s2.height();
|
||||
}
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QGstreamerV4L2Input::QGstreamerV4L2Input(QObject *parent)
|
||||
:QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
QGstreamerV4L2Input::~QGstreamerV4L2Input()
|
||||
{
|
||||
}
|
||||
|
||||
GstElement *QGstreamerV4L2Input::buildElement()
|
||||
{
|
||||
#ifndef Q_WS_MAEMO_5
|
||||
GstElement *camera = gst_element_factory_make("v4l2src", "camera_source");
|
||||
#else
|
||||
GstElement *camera = gst_element_factory_make("v4l2camsrc", "camera_source");
|
||||
#endif
|
||||
if (camera && !m_device.isEmpty() )
|
||||
g_object_set(G_OBJECT(camera), "device", m_device.constData(), NULL);
|
||||
|
||||
return camera;
|
||||
}
|
||||
|
||||
void QGstreamerV4L2Input::setDevice(const QByteArray &newDevice)
|
||||
{
|
||||
if (m_device != newDevice) {
|
||||
m_device = newDevice;
|
||||
updateSupportedResolutions(newDevice);
|
||||
}
|
||||
}
|
||||
|
||||
void QGstreamerV4L2Input::setDevice(const QString &device)
|
||||
{
|
||||
setDevice(QFile::encodeName(device));
|
||||
}
|
||||
|
||||
void QGstreamerV4L2Input::updateSupportedResolutions(const QByteArray &device)
|
||||
{
|
||||
m_frameRates.clear();
|
||||
m_resolutions.clear();
|
||||
m_ratesByResolution.clear();
|
||||
|
||||
QSet<QSize> allResolutions;
|
||||
QSet<int> allFrameRates;
|
||||
|
||||
QFile f(device);
|
||||
|
||||
if (!f.open(QFile::ReadOnly))
|
||||
return;
|
||||
|
||||
int fd = f.handle();
|
||||
|
||||
//get the list of formats:
|
||||
QList<quint32> supportedFormats;
|
||||
|
||||
{
|
||||
v4l2_fmtdesc fmt;
|
||||
memset(&fmt, 0, sizeof(v4l2_fmtdesc));
|
||||
|
||||
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
int sanity = 0;
|
||||
|
||||
for (fmt.index = 0;; fmt.index++) {
|
||||
if (sanity++ > 8)
|
||||
break;
|
||||
if( ::ioctl(fd, VIDIOC_ENUM_FMT, &fmt) == -1) {
|
||||
if(errno == EINVAL)
|
||||
break;
|
||||
}
|
||||
supportedFormats.append(fmt.pixelformat);
|
||||
}
|
||||
}
|
||||
|
||||
QList<QSize> commonSizes;
|
||||
commonSizes << QSize(128, 96)
|
||||
<<QSize(160,120)
|
||||
<<QSize(176, 144)
|
||||
<<QSize(320, 240)
|
||||
<<QSize(352, 288)
|
||||
<<QSize(640, 480)
|
||||
<<QSize(1024, 768)
|
||||
<<QSize(1280, 1024)
|
||||
<<QSize(1600, 1200)
|
||||
<<QSize(1920, 1200)
|
||||
<<QSize(2048, 1536)
|
||||
<<QSize(2560, 1600)
|
||||
<<QSize(2580, 1936);
|
||||
|
||||
QList<int> commonRates;
|
||||
commonRates << 05*1000 << 75*1000 << 10*1000 << 15*1000 << 20*1000
|
||||
<< 24*1000 << 25*1000 << 30*1000 << 50*1000 << 60*1000;
|
||||
|
||||
|
||||
//get the list of resolutions:
|
||||
|
||||
foreach (quint32 format, supportedFormats) {
|
||||
struct v4l2_frmsizeenum formatSize;
|
||||
memset(&formatSize, 0, sizeof(formatSize));
|
||||
formatSize.pixel_format = format;
|
||||
|
||||
QList<QSize> sizeList;
|
||||
|
||||
if (0) {
|
||||
char formatStr[5];
|
||||
memcpy(formatStr, &format, 4);
|
||||
formatStr[4] = 0;
|
||||
//qDebug() << "trying format" << formatStr;
|
||||
}
|
||||
|
||||
for (int i=0;;i++) {
|
||||
formatSize.index = i;
|
||||
if (ioctl (fd, VIDIOC_ENUM_FRAMESIZES, &formatSize) < 0)
|
||||
break;
|
||||
|
||||
if (formatSize.type == V4L2_FRMSIZE_TYPE_DISCRETE) {
|
||||
sizeList.append(QSize(formatSize.discrete.width, formatSize.discrete.height));
|
||||
} else {
|
||||
|
||||
foreach (const QSize& candidate, commonSizes) {
|
||||
if (candidate.width() <= (int)formatSize.stepwise.max_width &&
|
||||
candidate.height() >= (int)formatSize.stepwise.min_width &&
|
||||
candidate.width() % formatSize.stepwise.step_width == 0 &&
|
||||
candidate.height() <= (int)formatSize.stepwise.max_height &&
|
||||
candidate.height() >= (int)formatSize.stepwise.min_height &&
|
||||
candidate.height() % formatSize.stepwise.step_height == 0) {
|
||||
sizeList.append(candidate);
|
||||
}
|
||||
}
|
||||
|
||||
if (!sizeList.contains(QSize(formatSize.stepwise.min_width, formatSize.stepwise.min_height)))
|
||||
sizeList.prepend(QSize(formatSize.stepwise.min_width, formatSize.stepwise.min_height));
|
||||
|
||||
if (!sizeList.contains(QSize(formatSize.stepwise.max_width, formatSize.stepwise.max_height)))
|
||||
sizeList.append(QSize(formatSize.stepwise.max_width, formatSize.stepwise.max_height));
|
||||
|
||||
break; //stepwise values are returned only for index 0
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//and frameRates for each resolution.
|
||||
|
||||
foreach (const QSize &s, sizeList) {
|
||||
allResolutions.insert(s);
|
||||
|
||||
struct v4l2_frmivalenum formatInterval;
|
||||
memset(&formatInterval, 0, sizeof(formatInterval));
|
||||
formatInterval.pixel_format = format;
|
||||
formatInterval.width = s.width();
|
||||
formatInterval.height = s.height();
|
||||
|
||||
QList<int> frameRates; //in 1/1000 of fps
|
||||
|
||||
for (int i=0; ; i++) {
|
||||
formatInterval.index = i;
|
||||
|
||||
if (ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &formatInterval) < 0)
|
||||
break;
|
||||
|
||||
if (formatInterval.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
|
||||
//converts seconds to fps*1000
|
||||
if (formatInterval.discrete.numerator)
|
||||
frameRates.append(qRound(formatInterval.discrete.denominator*1000.0 / formatInterval.discrete.numerator));
|
||||
} else {
|
||||
if (formatInterval.stepwise.min.numerator == 0 ||
|
||||
formatInterval.stepwise.max.numerator == 0) {
|
||||
qWarning() << "received invalid frame interval";
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
int minRate = qRound(formatInterval.stepwise.min.denominator*1000.0 /
|
||||
formatInterval.stepwise.min.numerator);
|
||||
|
||||
int maxRate = qRound(formatInterval.stepwise.max.denominator*1000.0 /
|
||||
formatInterval.stepwise.max.numerator);
|
||||
|
||||
|
||||
foreach (int candidate, commonRates) {
|
||||
if (candidate >= minRate && candidate <= maxRate)
|
||||
frameRates.append(candidate);
|
||||
}
|
||||
|
||||
if (!frameRates.contains(minRate))
|
||||
frameRates.prepend(minRate);
|
||||
|
||||
if (!frameRates.contains(maxRate))
|
||||
frameRates.append(maxRate);
|
||||
|
||||
break; //stepwise values are returned only for index 0
|
||||
}
|
||||
}
|
||||
allFrameRates.unite(frameRates.toSet());
|
||||
m_ratesByResolution[s].unite(frameRates.toSet());
|
||||
}
|
||||
}
|
||||
|
||||
f.close();
|
||||
|
||||
foreach(int rate, allFrameRates) {
|
||||
m_frameRates.append(rate/1000.0);
|
||||
}
|
||||
|
||||
qSort(m_frameRates);
|
||||
|
||||
m_resolutions = allResolutions.toList();
|
||||
qSort(m_resolutions);
|
||||
|
||||
//qDebug() << "frame rates:" << m_frameRates;
|
||||
//qDebug() << "resolutions:" << m_resolutions;
|
||||
}
|
||||
|
||||
|
||||
QList<qreal> QGstreamerV4L2Input::supportedFrameRates(const QSize &frameSize) const
|
||||
{
|
||||
if (frameSize.isEmpty())
|
||||
return m_frameRates;
|
||||
else {
|
||||
QList<qreal> res;
|
||||
foreach(int rate, m_ratesByResolution[frameSize]) {
|
||||
res.append(rate/1000.0);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
QList<QSize> QGstreamerV4L2Input::supportedResolutions(qreal frameRate) const
|
||||
{
|
||||
Q_UNUSED(frameRate);
|
||||
return m_resolutions;
|
||||
}
|
||||
83
src/plugins/gstreamer/mediacapture/qgstreamerv4l2input.h
Normal file
83
src/plugins/gstreamer/mediacapture/qgstreamerv4l2input.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 QGSTREAMERV4L2INPUT_H
|
||||
#define QGSTREAMERV4L2INPUT_H
|
||||
|
||||
#include <QtCore/qhash.h>
|
||||
#include <QtCore/qbytearray.h>
|
||||
#include <QtCore/qlist.h>
|
||||
#include <QtCore/qsize.h>
|
||||
#include "qgstreamercapturesession.h"
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class QGstreamerV4L2Input : public QObject, public QGstreamerVideoInput
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QGstreamerV4L2Input(QObject *parent = 0);
|
||||
virtual ~QGstreamerV4L2Input();
|
||||
|
||||
GstElement *buildElement();
|
||||
|
||||
QList<qreal> supportedFrameRates(const QSize &frameSize = QSize()) const;
|
||||
QList<QSize> supportedResolutions(qreal frameRate = -1) const;
|
||||
|
||||
QByteArray device() const;
|
||||
|
||||
public slots:
|
||||
void setDevice(const QByteArray &device);
|
||||
void setDevice(const QString &device);
|
||||
|
||||
private:
|
||||
void updateSupportedResolutions(const QByteArray &device);
|
||||
|
||||
QList<qreal> m_frameRates;
|
||||
QList<QSize> m_resolutions;
|
||||
|
||||
QHash<QSize, QSet<int> > m_ratesByResolution;
|
||||
|
||||
QByteArray m_device;
|
||||
};
|
||||
|
||||
#endif // QGSTREAMERV4L2INPUT_H
|
||||
331
src/plugins/gstreamer/mediacapture/qgstreamervideoencode.cpp
Normal file
331
src/plugins/gstreamer/mediacapture/qgstreamervideoencode.cpp
Normal file
@@ -0,0 +1,331 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "qgstreamervideoencode.h"
|
||||
#include "qgstreamercapturesession.h"
|
||||
#include "qgstreamermediacontainercontrol.h"
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
QGstreamerVideoEncode::QGstreamerVideoEncode(QGstreamerCaptureSession *session)
|
||||
:QVideoEncoderControl(session), m_session(session)
|
||||
{
|
||||
QList<QByteArray> codecCandidates;
|
||||
codecCandidates << "video/h264" << "video/xvid" << "video/mpeg4" << "video/mpeg1" << "video/mpeg2" << "video/theora";
|
||||
|
||||
m_elementNames["video/h264"] = "x264enc";
|
||||
m_elementNames["video/xvid"] = "xvidenc";
|
||||
m_elementNames["video/mpeg4"] = "ffenc_mpeg4";
|
||||
m_elementNames["video/mpeg1"] = "ffenc_mpeg1video";
|
||||
m_elementNames["video/mpeg2"] = "ffenc_mpeg2video";
|
||||
m_elementNames["video/theora"] = "theoraenc";
|
||||
|
||||
m_codecOptions["video/h264"] = QStringList() << "quantizer";
|
||||
m_codecOptions["video/xvid"] = QStringList() << "quantizer" << "profile";
|
||||
m_codecOptions["video/mpeg4"] = QStringList() << "quantizer";
|
||||
m_codecOptions["video/mpeg1"] = QStringList() << "quantizer";
|
||||
m_codecOptions["video/mpeg2"] = QStringList() << "quantizer";
|
||||
m_codecOptions["video/theora"] = QStringList();
|
||||
|
||||
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);
|
||||
m_codecDescriptions.insert(codecName, QString::fromUtf8(descr));
|
||||
|
||||
m_streamTypes.insert(codecName,
|
||||
QGstreamerMediaContainerControl::supportedStreamTypes(factory, GST_PAD_SRC));
|
||||
|
||||
gst_object_unref(GST_OBJECT(factory));
|
||||
}
|
||||
}
|
||||
|
||||
//if (!m_codecs.isEmpty())
|
||||
// m_videoSettings.setCodec(m_codecs[0]);
|
||||
}
|
||||
|
||||
QGstreamerVideoEncode::~QGstreamerVideoEncode()
|
||||
{
|
||||
}
|
||||
|
||||
QList<QSize> QGstreamerVideoEncode::supportedResolutions(const QVideoEncoderSettings &, bool *continuous) const
|
||||
{
|
||||
if (continuous)
|
||||
*continuous = m_session->videoInput() != 0;
|
||||
|
||||
return m_session->videoInput() ? m_session->videoInput()->supportedResolutions() : QList<QSize>();
|
||||
}
|
||||
|
||||
QList< qreal > QGstreamerVideoEncode::supportedFrameRates(const QVideoEncoderSettings &, bool *continuous) const
|
||||
{
|
||||
if (continuous)
|
||||
*continuous = false;
|
||||
|
||||
return m_session->videoInput() ? m_session->videoInput()->supportedFrameRates() : QList<qreal>();
|
||||
}
|
||||
|
||||
QStringList QGstreamerVideoEncode::supportedVideoCodecs() const
|
||||
{
|
||||
return m_codecs;
|
||||
}
|
||||
|
||||
QString QGstreamerVideoEncode::videoCodecDescription(const QString &codecName) const
|
||||
{
|
||||
return m_codecDescriptions.value(codecName);
|
||||
}
|
||||
|
||||
QStringList QGstreamerVideoEncode::supportedEncodingOptions(const QString &codec) const
|
||||
{
|
||||
return m_codecOptions.value(codec);
|
||||
}
|
||||
|
||||
QVariant QGstreamerVideoEncode::encodingOption(const QString &codec, const QString &name) const
|
||||
{
|
||||
return m_options[codec].value(name);
|
||||
}
|
||||
|
||||
void QGstreamerVideoEncode::setEncodingOption(
|
||||
const QString &codec, const QString &name, const QVariant &value)
|
||||
{
|
||||
m_options[codec][name] = value;
|
||||
}
|
||||
|
||||
QVideoEncoderSettings QGstreamerVideoEncode::videoSettings() const
|
||||
{
|
||||
return m_videoSettings;
|
||||
}
|
||||
|
||||
void QGstreamerVideoEncode::setVideoSettings(const QVideoEncoderSettings &settings)
|
||||
{
|
||||
m_videoSettings = settings;
|
||||
}
|
||||
|
||||
GstElement *QGstreamerVideoEncode::createEncoder()
|
||||
{
|
||||
QString codec = m_videoSettings.codec();
|
||||
//qDebug() << "create encoder for video codec" << codec;
|
||||
GstElement *encoderElement = gst_element_factory_make( m_elementNames.value(codec).constData(), "video-encoder");
|
||||
if (!encoderElement)
|
||||
return 0;
|
||||
|
||||
GstBin *encoderBin = GST_BIN(gst_bin_new("video-encoder-bin"));
|
||||
|
||||
GstElement *capsFilter = gst_element_factory_make("capsfilter", "capsfilter-video");
|
||||
gst_bin_add(encoderBin, capsFilter);
|
||||
|
||||
GstElement *colorspace = gst_element_factory_make("ffmpegcolorspace", NULL);
|
||||
gst_bin_add(encoderBin, colorspace);
|
||||
gst_bin_add(encoderBin, encoderElement);
|
||||
|
||||
gst_element_link_many(capsFilter, colorspace, encoderElement, NULL);
|
||||
|
||||
// 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 (encoderElement) {
|
||||
if (m_videoSettings.encodingMode() == QtMultimediaKit::ConstantQualityEncoding) {
|
||||
QtMultimediaKit::EncodingQuality qualityValue = m_videoSettings.quality();
|
||||
|
||||
if (codec == QLatin1String("video/h264")) {
|
||||
//constant quantizer mode
|
||||
g_object_set(G_OBJECT(encoderElement), "pass", 4, NULL);
|
||||
int qualityTable[] = {
|
||||
50, //VeryLow
|
||||
35, //Low
|
||||
21, //Normal
|
||||
15, //High
|
||||
8 //VeryHigh
|
||||
};
|
||||
g_object_set(G_OBJECT(encoderElement), "quantizer", qualityTable[qualityValue], NULL);
|
||||
} else if (codec == QLatin1String("video/xvid")) {
|
||||
//constant quantizer mode
|
||||
g_object_set(G_OBJECT(encoderElement), "pass", 3, NULL);
|
||||
int qualityTable[] = {
|
||||
32, //VeryLow
|
||||
12, //Low
|
||||
5, //Normal
|
||||
3, //High
|
||||
2 //VeryHigh
|
||||
};
|
||||
int quant = qualityTable[qualityValue];
|
||||
g_object_set(G_OBJECT(encoderElement), "quantizer", quant, NULL);
|
||||
} else if (codec == QLatin1String("video/mpeg4") ||
|
||||
codec == QLatin1String("video/mpeg1") ||
|
||||
codec == QLatin1String("video/mpeg2") ) {
|
||||
//constant quantizer mode
|
||||
g_object_set(G_OBJECT(encoderElement), "pass", 2, NULL);
|
||||
//quant from 1 to 30, default ~3
|
||||
double qualityTable[] = {
|
||||
20, //VeryLow
|
||||
8.0, //Low
|
||||
3.0, //Normal
|
||||
2.5, //High
|
||||
2.0 //VeryHigh
|
||||
};
|
||||
double quant = qualityTable[qualityValue];
|
||||
g_object_set(G_OBJECT(encoderElement), "quantizer", quant, NULL);
|
||||
} else if (codec == QLatin1String("video/theora")) {
|
||||
int qualityTable[] = {
|
||||
8, //VeryLow
|
||||
16, //Low
|
||||
32, //Normal
|
||||
45, //High
|
||||
60 //VeryHigh
|
||||
};
|
||||
//quality from 0 to 63
|
||||
int quality = qualityTable[qualityValue];
|
||||
g_object_set(G_OBJECT(encoderElement), "quality", quality, NULL);
|
||||
}
|
||||
} else {
|
||||
int bitrate = m_videoSettings.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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_videoSettings.resolution().isEmpty() || m_videoSettings.frameRate() > 0.001) {
|
||||
GstCaps *caps = gst_caps_new_empty();
|
||||
QStringList structureTypes;
|
||||
structureTypes << "video/x-raw-yuv" << "video/x-raw-rgb";
|
||||
|
||||
foreach(const QString &structureType, structureTypes) {
|
||||
GstStructure *structure = gst_structure_new(structureType.toAscii().constData(), NULL);
|
||||
|
||||
if (!m_videoSettings.resolution().isEmpty()) {
|
||||
gst_structure_set(structure, "width", G_TYPE_INT, m_videoSettings.resolution().width(), NULL);
|
||||
gst_structure_set(structure, "height", G_TYPE_INT, m_videoSettings.resolution().height(), NULL);
|
||||
}
|
||||
|
||||
if (m_videoSettings.frameRate() > 0.001) {
|
||||
QPair<int,int> rate = rateAsRational();
|
||||
|
||||
//qDebug() << "frame rate:" << num << denum;
|
||||
|
||||
gst_structure_set(structure, "framerate", GST_TYPE_FRACTION, rate.first, rate.second, NULL);
|
||||
}
|
||||
|
||||
gst_caps_append_structure(caps,structure);
|
||||
}
|
||||
|
||||
//qDebug() << "set video caps filter:" << gst_caps_to_string(caps);
|
||||
|
||||
g_object_set(G_OBJECT(capsFilter), "caps", caps, NULL);
|
||||
}
|
||||
|
||||
return GST_ELEMENT(encoderBin);
|
||||
}
|
||||
|
||||
QPair<int,int> QGstreamerVideoEncode::rateAsRational() const
|
||||
{
|
||||
qreal frameRate = m_videoSettings.frameRate();
|
||||
|
||||
if (frameRate > 0.001) {
|
||||
//convert to rational number
|
||||
QList<int> denumCandidates;
|
||||
denumCandidates << 1 << 2 << 3 << 5 << 10 << 1001 << 1000;
|
||||
|
||||
qreal error = 1.0;
|
||||
int num = 1;
|
||||
int denum = 1;
|
||||
|
||||
foreach (int curDenum, denumCandidates) {
|
||||
int curNum = qRound(frameRate*curDenum);
|
||||
qreal curError = qAbs(qreal(curNum)/curDenum - frameRate);
|
||||
|
||||
if (curError < error) {
|
||||
error = curError;
|
||||
num = curNum;
|
||||
denum = curDenum;
|
||||
}
|
||||
|
||||
if (curError < 1e-8)
|
||||
break;
|
||||
}
|
||||
|
||||
return QPair<int,int>(num,denum);
|
||||
}
|
||||
|
||||
return QPair<int,int>();
|
||||
}
|
||||
|
||||
|
||||
QSet<QString> QGstreamerVideoEncode::supportedStreamTypes(const QString &codecName) const
|
||||
{
|
||||
return m_streamTypes.value(codecName);
|
||||
}
|
||||
98
src/plugins/gstreamer/mediacapture/qgstreamervideoencode.h
Normal file
98
src/plugins/gstreamer/mediacapture/qgstreamervideoencode.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 QGSTREAMERVIDEOENCODE_H
|
||||
#define QGSTREAMERVIDEOENCODE_H
|
||||
|
||||
#include <qvideoencodercontrol.h>
|
||||
class QGstreamerCaptureSession;
|
||||
|
||||
#include <QtCore/qstringlist.h>
|
||||
#include <QtCore/qmap.h>
|
||||
#include <QtCore/qset.h>
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class QGstreamerVideoEncode : public QVideoEncoderControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QGstreamerVideoEncode(QGstreamerCaptureSession *session);
|
||||
virtual ~QGstreamerVideoEncode();
|
||||
|
||||
QList<QSize> supportedResolutions(const QVideoEncoderSettings &settings = QVideoEncoderSettings(),
|
||||
bool *continuous = 0) const;
|
||||
|
||||
QList< qreal > supportedFrameRates(const QVideoEncoderSettings &settings = QVideoEncoderSettings(),
|
||||
bool *continuous = 0) const;
|
||||
|
||||
QPair<int,int> rateAsRational() const;
|
||||
|
||||
QStringList supportedVideoCodecs() const;
|
||||
QString videoCodecDescription(const QString &codecName) const;
|
||||
|
||||
QVideoEncoderSettings videoSettings() const;
|
||||
void setVideoSettings(const QVideoEncoderSettings &settings);
|
||||
|
||||
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);
|
||||
|
||||
GstElement *createEncoder();
|
||||
|
||||
QSet<QString> supportedStreamTypes(const QString &codecName) const;
|
||||
|
||||
private:
|
||||
QGstreamerCaptureSession *m_session;
|
||||
|
||||
QStringList m_codecs;
|
||||
QMap<QString,QString> m_codecDescriptions;
|
||||
QMap<QString,QByteArray> m_elementNames;
|
||||
QMap<QString,QStringList> m_codecOptions;
|
||||
|
||||
QVideoEncoderSettings m_videoSettings;
|
||||
QMap<QString, QMap<QString, QVariant> > m_options;
|
||||
QMap<QString, QSet<QString> > m_streamTypes;
|
||||
};
|
||||
|
||||
#endif
|
||||
30
src/plugins/gstreamer/mediaplayer/mediaplayer.pri
Normal file
30
src/plugins/gstreamer/mediaplayer/mediaplayer.pri
Normal file
@@ -0,0 +1,30 @@
|
||||
INCLUDEPATH += $$PWD
|
||||
|
||||
DEFINES += QMEDIA_GSTREAMER_PLAYER
|
||||
|
||||
contains(gstreamer-appsrc_enabled, yes) {
|
||||
HEADERS += $$PWD/qgstappsrc.h
|
||||
SOURCES += $$PWD/qgstappsrc.cpp
|
||||
|
||||
DEFINES += HAVE_GST_APPSRC
|
||||
|
||||
LIBS += -lgstapp-0.10
|
||||
}
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/qgstreamerplayercontrol.h \
|
||||
$$PWD/qgstreamerplayerservice.h \
|
||||
$$PWD/qgstreamerplayersession.h \
|
||||
$$PWD/qgstreamerstreamscontrol.h \
|
||||
$$PWD/qgstreamermetadataprovider.h \
|
||||
$$PWD/playerresourcepolicy.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/qgstreamerplayercontrol.cpp \
|
||||
$$PWD/qgstreamerplayerservice.cpp \
|
||||
$$PWD/qgstreamerplayersession.cpp \
|
||||
$$PWD/qgstreamerstreamscontrol.cpp \
|
||||
$$PWD/qgstreamermetadataprovider.cpp \
|
||||
$$PWD/playerresourcepolicy.cpp
|
||||
|
||||
|
||||
180
src/plugins/gstreamer/mediaplayer/playerresourcepolicy.cpp
Normal file
180
src/plugins/gstreamer/mediaplayer/playerresourcepolicy.cpp
Normal file
@@ -0,0 +1,180 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "playerresourcepolicy.h"
|
||||
|
||||
#ifdef Q_WS_MAEMO_6
|
||||
#define HAVE_RESOURCE_POLICY
|
||||
#endif
|
||||
|
||||
//#define DEBUG_RESOURCE_POLICY
|
||||
#include <QtCore/qdebug.h>
|
||||
|
||||
#ifdef HAVE_RESOURCE_POLICY
|
||||
#include <policy/resource.h>
|
||||
#include <policy/resources.h>
|
||||
#include <policy/resource-set.h>
|
||||
#endif
|
||||
|
||||
PlayerResourcePolicy::PlayerResourcePolicy(QObject *parent) :
|
||||
QObject(parent),
|
||||
m_videoEnabled(true),
|
||||
m_resourceSet(0),
|
||||
m_status(PlayerResourcePolicy::Initial)
|
||||
{
|
||||
#ifdef HAVE_RESOURCE_POLICY
|
||||
m_resourceSet = new ResourcePolicy::ResourceSet("player", this);
|
||||
m_resourceSet->setAlwaysReply();
|
||||
|
||||
ResourcePolicy::AudioResource *audioResource = new ResourcePolicy::AudioResource("player");
|
||||
audioResource->setProcessID(QCoreApplication::applicationPid());
|
||||
audioResource->setStreamTag("media.name", "*");
|
||||
m_resourceSet->addResourceObject(audioResource);
|
||||
|
||||
m_resourceSet->addResource(ResourcePolicy::VideoPlaybackType);
|
||||
m_resourceSet->update();
|
||||
|
||||
connect(m_resourceSet, SIGNAL(resourcesGranted(const QList<ResourcePolicy::ResourceType>)),
|
||||
this, SLOT(handleResourcesGranted()));
|
||||
connect(m_resourceSet, SIGNAL(resourcesDenied()),
|
||||
this, SLOT(handleResourcesDenied()));
|
||||
connect(m_resourceSet, SIGNAL(lostResources()),
|
||||
this, SLOT(handleResourcesLost()));
|
||||
connect(m_resourceSet, SIGNAL(resourcesReleasedByManager()),
|
||||
this, SLOT(handleResourcesLost()));
|
||||
#endif
|
||||
}
|
||||
|
||||
PlayerResourcePolicy::~PlayerResourcePolicy()
|
||||
{
|
||||
}
|
||||
|
||||
bool PlayerResourcePolicy::isVideoEnabled() const
|
||||
{
|
||||
return m_videoEnabled;
|
||||
}
|
||||
|
||||
void PlayerResourcePolicy::setVideoEnabled(bool enabled)
|
||||
{
|
||||
if (m_videoEnabled != enabled) {
|
||||
m_videoEnabled = enabled;
|
||||
|
||||
#ifdef HAVE_RESOURCE_POLICY
|
||||
if (enabled)
|
||||
m_resourceSet->addResource(ResourcePolicy::VideoPlaybackType);
|
||||
else
|
||||
m_resourceSet->deleteResource(ResourcePolicy::VideoPlaybackType);
|
||||
|
||||
m_resourceSet->update();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerResourcePolicy::acquire()
|
||||
{
|
||||
#ifdef HAVE_RESOURCE_POLICY
|
||||
|
||||
#ifdef DEBUG_RESOURCE_POLICY
|
||||
qDebug() << Q_FUNC_INFO << "Acquire resource";
|
||||
#endif
|
||||
m_status = RequestedResource;
|
||||
m_resourceSet->acquire();
|
||||
#else
|
||||
m_status = GrantedResource;
|
||||
#endif
|
||||
}
|
||||
|
||||
void PlayerResourcePolicy::release()
|
||||
{
|
||||
#ifdef HAVE_RESOURCE_POLICY
|
||||
|
||||
#ifdef DEBUG_RESOURCE_POLICY
|
||||
qDebug() << Q_FUNC_INFO << "Release resource";
|
||||
#endif
|
||||
|
||||
m_resourceSet->release();
|
||||
#endif
|
||||
m_status = Initial;
|
||||
|
||||
}
|
||||
|
||||
bool PlayerResourcePolicy::isGranted() const
|
||||
{
|
||||
return m_status == GrantedResource;
|
||||
}
|
||||
|
||||
bool PlayerResourcePolicy::isRequested() const
|
||||
{
|
||||
return m_status == RequestedResource;
|
||||
}
|
||||
|
||||
void PlayerResourcePolicy::handleResourcesGranted()
|
||||
{
|
||||
m_status = GrantedResource;
|
||||
#ifdef DEBUG_RESOURCE_POLICY
|
||||
qDebug() << Q_FUNC_INFO << "Resource granted";
|
||||
#endif
|
||||
emit resourcesGranted();
|
||||
}
|
||||
|
||||
void PlayerResourcePolicy::handleResourcesDenied()
|
||||
{
|
||||
m_status = Initial;
|
||||
#ifdef DEBUG_RESOURCE_POLICY
|
||||
qDebug() << Q_FUNC_INFO << "Resource denied";
|
||||
#endif
|
||||
emit resourcesDenied();
|
||||
}
|
||||
|
||||
void PlayerResourcePolicy::handleResourcesLost()
|
||||
{
|
||||
#ifdef DEBUG_RESOURCE_POLICY
|
||||
qDebug() << Q_FUNC_INFO << "Resource lost";
|
||||
#endif
|
||||
if (m_status != Initial) {
|
||||
m_status = Initial;
|
||||
emit resourcesLost();
|
||||
}
|
||||
|
||||
#ifdef HAVE_RESOURCE_POLICY
|
||||
m_resourceSet->release();
|
||||
#endif
|
||||
}
|
||||
90
src/plugins/gstreamer/mediaplayer/playerresourcepolicy.h
Normal file
90
src/plugins/gstreamer/mediaplayer/playerresourcepolicy.h
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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef PLAYERRESOURCEPOLICY_H
|
||||
#define PLAYERRESOURCEPOLICY_H
|
||||
|
||||
#include <QtCore/qobject.h>
|
||||
|
||||
namespace ResourcePolicy {
|
||||
class ResourceSet;
|
||||
};
|
||||
|
||||
class PlayerResourcePolicy : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PlayerResourcePolicy(QObject *parent = 0);
|
||||
~PlayerResourcePolicy();
|
||||
|
||||
bool isVideoEnabled() const;
|
||||
bool isGranted() const;
|
||||
bool isRequested() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void resourcesDenied();
|
||||
void resourcesGranted();
|
||||
void resourcesLost();
|
||||
|
||||
public Q_SLOTS:
|
||||
void acquire();
|
||||
void release();
|
||||
|
||||
void setVideoEnabled(bool enabled);
|
||||
|
||||
private Q_SLOTS:
|
||||
void handleResourcesGranted();
|
||||
void handleResourcesDenied();
|
||||
void handleResourcesLost();
|
||||
|
||||
private:
|
||||
enum ResourceStatus {
|
||||
Initial = 0,
|
||||
RequestedResource,
|
||||
GrantedResource
|
||||
};
|
||||
|
||||
bool m_videoEnabled;
|
||||
ResourcePolicy::ResourceSet *m_resourceSet;
|
||||
ResourceStatus m_status;
|
||||
};
|
||||
|
||||
#endif
|
||||
224
src/plugins/gstreamer/mediaplayer/qgstappsrc.cpp
Normal file
224
src/plugins/gstreamer/mediaplayer/qgstappsrc.cpp
Normal file
@@ -0,0 +1,224 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 <QDebug>
|
||||
|
||||
#include "qgstappsrc.h"
|
||||
#include <QtNetwork>
|
||||
|
||||
QGstAppSrc::QGstAppSrc(QObject *parent)
|
||||
:QObject(parent)
|
||||
,m_stream(0)
|
||||
,m_appSrc(0)
|
||||
,m_sequential(false)
|
||||
,m_maxBytes(0)
|
||||
,m_setup(false)
|
||||
,m_dataRequestSize(-1)
|
||||
,m_dataRequested(false)
|
||||
,m_enoughData(false)
|
||||
,m_forceData(false)
|
||||
{
|
||||
}
|
||||
|
||||
QGstAppSrc::~QGstAppSrc()
|
||||
{
|
||||
if (m_appSrc)
|
||||
gst_object_unref(G_OBJECT(m_appSrc));
|
||||
}
|
||||
|
||||
bool QGstAppSrc::setup(GstElement* appsrc)
|
||||
{
|
||||
if (m_setup || m_stream == 0 || appsrc == 0)
|
||||
return false;
|
||||
|
||||
m_appSrc = GST_APP_SRC(appsrc);
|
||||
m_callbacks.need_data = &QGstAppSrc::on_need_data;
|
||||
m_callbacks.enough_data = &QGstAppSrc::on_enough_data;
|
||||
m_callbacks.seek_data = &QGstAppSrc::on_seek_data;
|
||||
gst_app_src_set_callbacks(m_appSrc, (GstAppSrcCallbacks*)&m_callbacks, this, (GDestroyNotify)&QGstAppSrc::destroy_notify);
|
||||
|
||||
g_object_get(G_OBJECT(m_appSrc), "max-bytes", &m_maxBytes, NULL);
|
||||
|
||||
if (m_sequential)
|
||||
m_streamType = GST_APP_STREAM_TYPE_STREAM;
|
||||
else
|
||||
m_streamType = GST_APP_STREAM_TYPE_RANDOM_ACCESS;
|
||||
gst_app_src_set_stream_type(m_appSrc, m_streamType);
|
||||
gst_app_src_set_size(m_appSrc, (m_sequential) ? -1 : m_stream->size());
|
||||
|
||||
return m_setup = true;
|
||||
}
|
||||
|
||||
void QGstAppSrc::setStream(QIODevice *stream)
|
||||
{
|
||||
if (stream == 0)
|
||||
return;
|
||||
if (m_stream) {
|
||||
disconnect(m_stream, SIGNAL(readyRead()), this, SLOT(onDataReady()));
|
||||
disconnect(m_stream, SIGNAL(destroyed()), this, SLOT(streamDestroyed()));
|
||||
}
|
||||
if (m_appSrc)
|
||||
gst_object_unref(G_OBJECT(m_appSrc));
|
||||
|
||||
m_dataRequestSize = -1;
|
||||
m_dataRequested = false;
|
||||
m_enoughData = false;
|
||||
m_forceData = false;
|
||||
m_maxBytes = 0;
|
||||
|
||||
m_appSrc = 0;
|
||||
m_stream = stream;
|
||||
connect(m_stream, SIGNAL(destroyed()), SLOT(streamDestroyed()));
|
||||
connect(m_stream, SIGNAL(readyRead()), this, SLOT(onDataReady()));
|
||||
m_sequential = m_stream->isSequential();
|
||||
m_setup = false;
|
||||
}
|
||||
|
||||
QIODevice *QGstAppSrc::stream() const
|
||||
{
|
||||
return m_stream;
|
||||
}
|
||||
|
||||
GstAppSrc *QGstAppSrc::element()
|
||||
{
|
||||
return m_appSrc;
|
||||
}
|
||||
|
||||
void QGstAppSrc::onDataReady()
|
||||
{
|
||||
if (!m_enoughData) {
|
||||
m_dataRequested = true;
|
||||
pushDataToAppSrc();
|
||||
}
|
||||
}
|
||||
|
||||
void QGstAppSrc::streamDestroyed()
|
||||
{
|
||||
if (sender() == m_stream) {
|
||||
m_stream = 0;
|
||||
sendEOS();
|
||||
}
|
||||
}
|
||||
|
||||
void QGstAppSrc::pushDataToAppSrc()
|
||||
{
|
||||
if (!isStreamValid() || !m_setup)
|
||||
return;
|
||||
|
||||
if (m_dataRequested && !m_enoughData) {
|
||||
qint64 size;
|
||||
if (m_dataRequestSize == (unsigned int)-1)
|
||||
size = qMin(m_stream->bytesAvailable(), queueSize());
|
||||
else
|
||||
size = qMin(m_stream->bytesAvailable(), (qint64)m_dataRequestSize);
|
||||
void *data = g_malloc(size);
|
||||
GstBuffer* buffer = gst_app_buffer_new(data, size, g_free, data);
|
||||
buffer->offset = m_stream->pos();
|
||||
qint64 bytesRead = m_stream->read((char*)GST_BUFFER_DATA(buffer), size);
|
||||
buffer->offset_end = buffer->offset + bytesRead - 1;
|
||||
|
||||
if (bytesRead > 0) {
|
||||
m_dataRequested = false;
|
||||
m_enoughData = false;
|
||||
GstFlowReturn ret = gst_app_src_push_buffer (GST_APP_SRC (element()), buffer);
|
||||
if (ret == GST_FLOW_ERROR) {
|
||||
qWarning()<<"appsrc: push buffer error";
|
||||
} else if (ret == GST_FLOW_WRONG_STATE) {
|
||||
qWarning()<<"appsrc: push buffer wrong state";
|
||||
} else if (ret == GST_FLOW_RESEND) {
|
||||
qWarning()<<"appsrc: push buffer resend";
|
||||
}
|
||||
}
|
||||
} else if (m_stream->atEnd()) {
|
||||
sendEOS();
|
||||
}
|
||||
}
|
||||
|
||||
bool QGstAppSrc::doSeek(qint64 value)
|
||||
{
|
||||
if (isStreamValid())
|
||||
return stream()->seek(value);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
gboolean QGstAppSrc::on_seek_data(GstAppSrc *element, guint64 arg0, gpointer userdata)
|
||||
{
|
||||
QGstAppSrc *self = reinterpret_cast<QGstAppSrc*>(userdata);
|
||||
if (self && self->isStreamValid()) {
|
||||
if (!self->stream()->isSequential())
|
||||
QMetaObject::invokeMethod(self, "doSeek", Qt::AutoConnection, Q_ARG(qint64, arg0));
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void QGstAppSrc::on_enough_data(GstAppSrc *element, gpointer userdata)
|
||||
{
|
||||
QGstAppSrc *self = reinterpret_cast<QGstAppSrc*>(userdata);
|
||||
if (self)
|
||||
self->enoughData() = true;
|
||||
}
|
||||
|
||||
void QGstAppSrc::on_need_data(GstAppSrc *element, guint arg0, gpointer userdata)
|
||||
{
|
||||
QGstAppSrc *self = reinterpret_cast<QGstAppSrc*>(userdata);
|
||||
if (self) {
|
||||
self->dataRequested() = true;
|
||||
self->enoughData() = false;
|
||||
self->dataRequestSize()= arg0;
|
||||
QMetaObject::invokeMethod(self, "pushDataToAppSrc", Qt::AutoConnection);
|
||||
}
|
||||
}
|
||||
|
||||
void QGstAppSrc::destroy_notify(gpointer data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
}
|
||||
|
||||
void QGstAppSrc::sendEOS()
|
||||
{
|
||||
gst_app_src_end_of_stream(GST_APP_SRC(m_appSrc));
|
||||
if (isStreamValid() && !stream()->isSequential())
|
||||
stream()->reset();
|
||||
}
|
||||
106
src/plugins/gstreamer/mediaplayer/qgstappsrc.h
Normal file
106
src/plugins/gstreamer/mediaplayer/qgstappsrc.h
Normal file
@@ -0,0 +1,106 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 QGSTAPPSRC_H
|
||||
#define QGSTAPPSRC_H
|
||||
|
||||
#include <QtCore/qobject.h>
|
||||
#include <QtCore/qiodevice.h>
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/app/gstappsrc.h>
|
||||
#include <gst/app/gstappbuffer.h>
|
||||
|
||||
class QGstAppSrc : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QGstAppSrc(QObject *parent = 0);
|
||||
~QGstAppSrc();
|
||||
|
||||
bool setup(GstElement *);
|
||||
bool isReady() const { return m_setup; }
|
||||
|
||||
void setStream(QIODevice *);
|
||||
QIODevice *stream() const;
|
||||
|
||||
GstAppSrc *element();
|
||||
|
||||
qint64 queueSize() const { return m_maxBytes; }
|
||||
|
||||
bool& enoughData() { return m_enoughData; }
|
||||
bool& dataRequested() { return m_dataRequested; }
|
||||
unsigned int& dataRequestSize() { return m_dataRequestSize; }
|
||||
|
||||
bool isStreamValid() const
|
||||
{
|
||||
return m_stream != 0 &&
|
||||
m_stream->isOpen();
|
||||
}
|
||||
|
||||
private slots:
|
||||
void pushDataToAppSrc();
|
||||
bool doSeek(qint64);
|
||||
void onDataReady();
|
||||
|
||||
void streamDestroyed();
|
||||
private:
|
||||
static gboolean on_seek_data(GstAppSrc *element, guint64 arg0, gpointer userdata);
|
||||
static void on_enough_data(GstAppSrc *element, gpointer userdata);
|
||||
static void on_need_data(GstAppSrc *element, uint arg0, gpointer userdata);
|
||||
static void destroy_notify(gpointer data);
|
||||
|
||||
void sendEOS();
|
||||
|
||||
QIODevice *m_stream;
|
||||
GstAppSrc *m_appSrc;
|
||||
bool m_sequential;
|
||||
GstAppStreamType m_streamType;
|
||||
GstAppSrcCallbacks m_callbacks;
|
||||
qint64 m_maxBytes;
|
||||
bool m_setup;
|
||||
unsigned int m_dataRequestSize;
|
||||
bool m_dataRequested;
|
||||
bool m_enoughData;
|
||||
bool m_forceData;
|
||||
};
|
||||
|
||||
#endif
|
||||
192
src/plugins/gstreamer/mediaplayer/qgstreamermetadataprovider.cpp
Normal file
192
src/plugins/gstreamer/mediaplayer/qgstreamermetadataprovider.cpp
Normal file
@@ -0,0 +1,192 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "qgstreamermetadataprovider.h"
|
||||
#include "qgstreamerplayersession.h"
|
||||
#include <QDebug>
|
||||
|
||||
#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, "year" },
|
||||
//{ 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, "resolution" },
|
||||
{ QtMultimediaKit::PixelAspectRatio, "pixel-aspect-ratio" },
|
||||
|
||||
// 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 }
|
||||
};
|
||||
|
||||
QGstreamerMetaDataProvider::QGstreamerMetaDataProvider(QGstreamerPlayerSession *session, QObject *parent)
|
||||
:QMetaDataReaderControl(parent), m_session(session)
|
||||
{
|
||||
connect(m_session, SIGNAL(tagsChanged()), SLOT(updateTags()));
|
||||
}
|
||||
|
||||
QGstreamerMetaDataProvider::~QGstreamerMetaDataProvider()
|
||||
{
|
||||
}
|
||||
|
||||
bool QGstreamerMetaDataProvider::isMetaDataAvailable() const
|
||||
{
|
||||
return !m_session->tags().isEmpty();
|
||||
}
|
||||
|
||||
bool QGstreamerMetaDataProvider::isWritable() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QVariant QGstreamerMetaDataProvider::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) {
|
||||
return m_session->tags().value(QByteArray(qt_gstreamerMetaDataKeys[i].token));
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QList<QtMultimediaKit::MetaData> QGstreamerMetaDataProvider::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_session->tags().keys()) {
|
||||
QtMultimediaKit::MetaData tag = keysMap.value(key, QtMultimediaKit::MetaData(-1));
|
||||
if (tag != -1)
|
||||
res.append(tag);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
QVariant QGstreamerMetaDataProvider::extendedMetaData(const QString &key) const
|
||||
{
|
||||
return m_session->tags().value(key.toLatin1());
|
||||
}
|
||||
|
||||
QStringList QGstreamerMetaDataProvider::availableExtendedMetaData() const
|
||||
{
|
||||
QStringList res;
|
||||
foreach (const QByteArray &key, m_session->tags().keys())
|
||||
res.append(QString(key));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void QGstreamerMetaDataProvider::updateTags()
|
||||
{
|
||||
emit metaDataChanged();
|
||||
}
|
||||
@@ -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 QGSTREAMERMETADATAPROVIDER_H
|
||||
#define QGSTREAMERMETADATAPROVIDER_H
|
||||
|
||||
#include <qmetadatareadercontrol.h>
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class QGstreamerPlayerSession;
|
||||
|
||||
class QGstreamerMetaDataProvider : public QMetaDataReaderControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QGstreamerMetaDataProvider( QGstreamerPlayerSession *session, QObject *parent );
|
||||
virtual ~QGstreamerMetaDataProvider();
|
||||
|
||||
bool isMetaDataAvailable() const;
|
||||
bool isWritable() const;
|
||||
|
||||
QVariant metaData(QtMultimediaKit::MetaData key) const;
|
||||
QList<QtMultimediaKit::MetaData> availableMetaData() const;
|
||||
|
||||
QVariant extendedMetaData(const QString &key) const ;
|
||||
QStringList availableExtendedMetaData() const;
|
||||
|
||||
private slots:
|
||||
void updateTags();
|
||||
|
||||
private:
|
||||
QGstreamerPlayerSession *m_session;
|
||||
};
|
||||
|
||||
#endif // QGSTREAMERMETADATAPROVIDER_H
|
||||
748
src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp
Normal file
748
src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp
Normal file
@@ -0,0 +1,748 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "qgstreamerplayercontrol.h"
|
||||
#include "qgstreamerplayersession.h"
|
||||
#include "playerresourcepolicy.h"
|
||||
|
||||
#include <qmediaplaylistnavigator.h>
|
||||
|
||||
|
||||
#include <QtCore/qdir.h>
|
||||
#include <QtCore/qsocketnotifier.h>
|
||||
#include <QtCore/qurl.h>
|
||||
#include <QtCore/qdebug.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
//#define DEBUG_PLAYBIN
|
||||
|
||||
QGstreamerPlayerControl::QGstreamerPlayerControl(QGstreamerPlayerSession *session, QObject *parent)
|
||||
: QMediaPlayerControl(parent)
|
||||
, m_ownStream(false)
|
||||
, m_session(session)
|
||||
, m_state(QMediaPlayer::StoppedState)
|
||||
, m_mediaStatus(QMediaPlayer::NoMedia)
|
||||
, m_bufferProgress(-1)
|
||||
, m_seekToStartPending(false)
|
||||
, m_pendingSeekPosition(-1)
|
||||
, m_stream(0)
|
||||
, m_fifoNotifier(0)
|
||||
, m_fifoCanWrite(false)
|
||||
, m_bufferSize(0)
|
||||
, m_bufferOffset(0)
|
||||
{
|
||||
m_fifoFd[0] = -1;
|
||||
m_fifoFd[1] = -1;
|
||||
|
||||
m_resources = new PlayerResourcePolicy(this);
|
||||
|
||||
connect(m_session, SIGNAL(positionChanged(qint64)),
|
||||
this, SIGNAL(positionChanged(qint64)));
|
||||
connect(m_session, SIGNAL(durationChanged(qint64)),
|
||||
this, SIGNAL(durationChanged(qint64)));
|
||||
connect(m_session, SIGNAL(mutedStateChanged(bool)),
|
||||
this, SIGNAL(mutedChanged(bool)));
|
||||
connect(m_session, SIGNAL(volumeChanged(int)),
|
||||
this, SIGNAL(volumeChanged(int)));
|
||||
connect(m_session, SIGNAL(stateChanged(QMediaPlayer::State)),
|
||||
this, SLOT(updateSessionState(QMediaPlayer::State)));
|
||||
connect(m_session,SIGNAL(bufferingProgressChanged(int)),
|
||||
this, SLOT(setBufferProgress(int)));
|
||||
connect(m_session, SIGNAL(playbackFinished()),
|
||||
this, SLOT(processEOS()));
|
||||
connect(m_session, SIGNAL(audioAvailableChanged(bool)),
|
||||
this, SIGNAL(audioAvailableChanged(bool)));
|
||||
connect(m_session, SIGNAL(videoAvailableChanged(bool)),
|
||||
this, SIGNAL(videoAvailableChanged(bool)));
|
||||
connect(m_session, SIGNAL(seekableChanged(bool)),
|
||||
this, SIGNAL(seekableChanged(bool)));
|
||||
connect(m_session, SIGNAL(error(int,QString)),
|
||||
this, SIGNAL(error(int,QString)));
|
||||
connect(m_session, SIGNAL(invalidMedia()),
|
||||
this, SLOT(handleInvalidMedia()));
|
||||
connect(m_session, SIGNAL(playbackRateChanged(qreal)),
|
||||
this, SIGNAL(playbackRateChanged(qreal)));
|
||||
connect(m_session, SIGNAL(seekableChanged(bool)),
|
||||
this, SLOT(applyPendingSeek(bool)));
|
||||
|
||||
connect(m_resources, SIGNAL(resourcesGranted()), SLOT(handleResourcesGranted()));
|
||||
connect(m_resources, SIGNAL(resourcesDenied()), SLOT(handleResourcesLost()));
|
||||
connect(m_resources, SIGNAL(resourcesLost()), SLOT(handleResourcesLost()));
|
||||
}
|
||||
|
||||
QGstreamerPlayerControl::~QGstreamerPlayerControl()
|
||||
{
|
||||
if (m_fifoFd[0] >= 0) {
|
||||
::close(m_fifoFd[0]);
|
||||
::close(m_fifoFd[1]);
|
||||
m_fifoFd[0] = -1;
|
||||
m_fifoFd[1] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
qint64 QGstreamerPlayerControl::position() const
|
||||
{
|
||||
return m_seekToStartPending ? 0 : m_session->position();
|
||||
}
|
||||
|
||||
qint64 QGstreamerPlayerControl::duration() const
|
||||
{
|
||||
return m_session->duration();
|
||||
}
|
||||
|
||||
QMediaPlayer::State QGstreamerPlayerControl::state() const
|
||||
{
|
||||
return m_state;
|
||||
}
|
||||
|
||||
QMediaPlayer::MediaStatus QGstreamerPlayerControl::mediaStatus() const
|
||||
{
|
||||
return m_mediaStatus;
|
||||
}
|
||||
|
||||
int QGstreamerPlayerControl::bufferStatus() const
|
||||
{
|
||||
if (m_bufferProgress == -1) {
|
||||
return m_session->state() == QMediaPlayer::StoppedState ? 0 : 100;
|
||||
} else
|
||||
return m_bufferProgress;
|
||||
}
|
||||
|
||||
int QGstreamerPlayerControl::volume() const
|
||||
{
|
||||
return m_session->volume();
|
||||
}
|
||||
|
||||
bool QGstreamerPlayerControl::isMuted() const
|
||||
{
|
||||
return m_session->isMuted();
|
||||
}
|
||||
|
||||
bool QGstreamerPlayerControl::isSeekable() const
|
||||
{
|
||||
return m_session->isSeekable();
|
||||
}
|
||||
|
||||
QMediaTimeRange QGstreamerPlayerControl::availablePlaybackRanges() const
|
||||
{
|
||||
return m_session->availablePlaybackRanges();
|
||||
}
|
||||
|
||||
qreal QGstreamerPlayerControl::playbackRate() const
|
||||
{
|
||||
return m_session->playbackRate();
|
||||
}
|
||||
|
||||
void QGstreamerPlayerControl::setPlaybackRate(qreal rate)
|
||||
{
|
||||
m_session->setPlaybackRate(rate);
|
||||
}
|
||||
|
||||
void QGstreamerPlayerControl::setPosition(qint64 pos)
|
||||
{
|
||||
#ifdef DEBUG_PLAYBIN
|
||||
qDebug() << Q_FUNC_INFO << pos/1000.0;
|
||||
#endif
|
||||
|
||||
pushState();
|
||||
|
||||
if (m_mediaStatus == QMediaPlayer::EndOfMedia) {
|
||||
m_mediaStatus = QMediaPlayer::LoadedMedia;
|
||||
m_seekToStartPending = true;
|
||||
}
|
||||
|
||||
if (m_session->isSeekable() && m_session->seek(pos)) {
|
||||
m_seekToStartPending = false;
|
||||
m_pendingSeekPosition = -1;
|
||||
} else {
|
||||
m_pendingSeekPosition = pos;
|
||||
}
|
||||
|
||||
popAndNotifyState();
|
||||
}
|
||||
|
||||
void QGstreamerPlayerControl::play()
|
||||
{
|
||||
#ifdef DEBUG_PLAYBIN
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
|
||||
playOrPause(QMediaPlayer::PlayingState);
|
||||
}
|
||||
|
||||
void QGstreamerPlayerControl::pause()
|
||||
{
|
||||
#ifdef DEBUG_PLAYBIN
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
|
||||
playOrPause(QMediaPlayer::PausedState);
|
||||
}
|
||||
|
||||
void QGstreamerPlayerControl::playOrPause(QMediaPlayer::State newState)
|
||||
{
|
||||
if (m_mediaStatus == QMediaPlayer::NoMedia)
|
||||
return;
|
||||
|
||||
pushState();
|
||||
#ifdef Q_WS_MAEMO_6
|
||||
//this is a work around for the gstreamer bug,
|
||||
//should be remove once it get fixed
|
||||
if (newState == QMediaPlayer::PlayingState && m_mediaStatus == QMediaPlayer::InvalidMedia) {
|
||||
setMedia(m_currentResource, m_stream);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_mediaStatus == QMediaPlayer::EndOfMedia) {
|
||||
m_mediaStatus = QMediaPlayer::BufferedMedia;
|
||||
m_seekToStartPending = true;
|
||||
}
|
||||
|
||||
if (!m_resources->isGranted() && !m_resources->isRequested())
|
||||
m_resources->acquire();
|
||||
|
||||
if (m_resources->isGranted()) {
|
||||
if (m_seekToStartPending) {
|
||||
m_session->pause();
|
||||
if (!m_session->seek(0)) {
|
||||
m_bufferProgress = -1;
|
||||
m_session->stop();
|
||||
m_mediaStatus = QMediaPlayer::LoadingMedia;
|
||||
}
|
||||
m_seekToStartPending = false;
|
||||
}
|
||||
|
||||
bool ok = false;
|
||||
|
||||
if (newState == QMediaPlayer::PlayingState)
|
||||
ok = m_session->play();
|
||||
else
|
||||
ok = m_session->pause();
|
||||
|
||||
if (!ok)
|
||||
newState = QMediaPlayer::StoppedState;
|
||||
}
|
||||
|
||||
if (m_mediaStatus == QMediaPlayer::InvalidMedia)
|
||||
m_mediaStatus = QMediaPlayer::LoadingMedia;
|
||||
|
||||
m_state = newState;
|
||||
|
||||
if (m_mediaStatus == QMediaPlayer::EndOfMedia || m_mediaStatus == QMediaPlayer::LoadedMedia) {
|
||||
if (m_bufferProgress == -1 || m_bufferProgress == 100)
|
||||
m_mediaStatus = QMediaPlayer::BufferedMedia;
|
||||
else
|
||||
m_mediaStatus = QMediaPlayer::BufferingMedia;
|
||||
}
|
||||
|
||||
popAndNotifyState();
|
||||
|
||||
emit positionChanged(position());
|
||||
}
|
||||
|
||||
void QGstreamerPlayerControl::stop()
|
||||
{
|
||||
#ifdef DEBUG_PLAYBIN
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
|
||||
pushState();
|
||||
|
||||
if (m_state != QMediaPlayer::StoppedState) {
|
||||
m_state = QMediaPlayer::StoppedState;
|
||||
if (m_resources->isGranted())
|
||||
m_session->pause();
|
||||
|
||||
if (m_mediaStatus != QMediaPlayer::EndOfMedia) {
|
||||
m_seekToStartPending = true;
|
||||
emit positionChanged(position());
|
||||
}
|
||||
}
|
||||
|
||||
popAndNotifyState();
|
||||
}
|
||||
|
||||
void QGstreamerPlayerControl::setVolume(int volume)
|
||||
{
|
||||
m_session->setVolume(volume);
|
||||
}
|
||||
|
||||
void QGstreamerPlayerControl::setMuted(bool muted)
|
||||
{
|
||||
m_session->setMuted(muted);
|
||||
}
|
||||
|
||||
QMediaContent QGstreamerPlayerControl::media() const
|
||||
{
|
||||
return m_currentResource;
|
||||
}
|
||||
|
||||
const QIODevice *QGstreamerPlayerControl::mediaStream() const
|
||||
{
|
||||
return m_stream;
|
||||
}
|
||||
|
||||
void QGstreamerPlayerControl::setMedia(const QMediaContent &content, QIODevice *stream)
|
||||
{
|
||||
#ifdef DEBUG_PLAYBIN
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
|
||||
pushState();
|
||||
|
||||
m_state = QMediaPlayer::StoppedState;
|
||||
QMediaContent oldMedia = m_currentResource;
|
||||
m_pendingSeekPosition = -1;
|
||||
|
||||
if (!content.isNull() || stream) {
|
||||
if (!m_resources->isRequested() && !m_resources->isGranted())
|
||||
m_resources->acquire();
|
||||
|
||||
if (!m_resources->isGranted()) {
|
||||
m_currentResource = content;
|
||||
m_stream = stream;
|
||||
|
||||
m_state = QMediaPlayer::StoppedState;
|
||||
m_mediaStatus = QMediaPlayer::LoadingMedia;
|
||||
if (m_currentResource != oldMedia)
|
||||
emit mediaChanged(m_currentResource);
|
||||
popAndNotifyState();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
m_resources->release();
|
||||
}
|
||||
|
||||
m_session->stop();
|
||||
|
||||
bool userStreamValid = false;
|
||||
|
||||
if (m_bufferProgress != -1) {
|
||||
m_bufferProgress = -1;
|
||||
emit bufferStatusChanged(0);
|
||||
}
|
||||
|
||||
if (m_stream) {
|
||||
#if !defined(HAVE_GST_APPSRC)
|
||||
closeFifo();
|
||||
|
||||
disconnect(m_stream, SIGNAL(readyRead()), this, SLOT(writeFifo()));
|
||||
#endif
|
||||
|
||||
if (m_ownStream)
|
||||
delete m_stream;
|
||||
m_stream = 0;
|
||||
m_ownStream = false;
|
||||
}
|
||||
|
||||
// If the canonical URL refers to a Qt resource, open with QFile and use
|
||||
// the stream playback capability to play.
|
||||
if (stream == 0 && content.canonicalUrl().scheme() == QLatin1String("qrc")) {
|
||||
stream = new QFile(QLatin1Char(':') + content.canonicalUrl().path(), this);
|
||||
if (!stream->open(QIODevice::ReadOnly)) {
|
||||
delete stream;
|
||||
m_mediaStatus = QMediaPlayer::InvalidMedia;
|
||||
m_currentResource = content;
|
||||
emit mediaChanged(m_currentResource);
|
||||
emit error(QMediaPlayer::FormatError, tr("Attempting to play invalid Qt resource"));
|
||||
if (m_state != QMediaPlayer::PlayingState)
|
||||
m_resources->release();
|
||||
popAndNotifyState();
|
||||
return;
|
||||
}
|
||||
m_ownStream = true;
|
||||
}
|
||||
|
||||
m_currentResource = content;
|
||||
m_stream = stream;
|
||||
m_seekToStartPending = false;
|
||||
|
||||
QNetworkRequest request;
|
||||
|
||||
if (m_stream) {
|
||||
#if !defined(HAVE_GST_APPSRC)
|
||||
if (m_stream->isReadable() && openFifo()) {
|
||||
request = QNetworkRequest(QUrl(QString(QLatin1String("fd://%1")).arg(m_fifoFd[0])));
|
||||
}
|
||||
#else
|
||||
userStreamValid = stream->isOpen() && m_stream->isReadable();
|
||||
request = content.canonicalRequest();
|
||||
#endif
|
||||
} else if (!content.isNull()) {
|
||||
request = content.canonicalRequest();
|
||||
}
|
||||
|
||||
#if !defined(HAVE_GST_APPSRC)
|
||||
m_session->loadFromUri(request);
|
||||
#else
|
||||
if (m_stream) {
|
||||
if (userStreamValid){
|
||||
m_session->loadFromStream(request, m_stream);
|
||||
} else {
|
||||
m_mediaStatus = QMediaPlayer::InvalidMedia;
|
||||
emit error(QMediaPlayer::FormatError, tr("Attempting to play invalid user stream"));
|
||||
if (m_state != QMediaPlayer::PlayingState)
|
||||
m_resources->release();
|
||||
popAndNotifyState();
|
||||
return;
|
||||
}
|
||||
} else
|
||||
m_session->loadFromUri(request);
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_GST_APPSRC)
|
||||
if (m_fifoFd[1] >= 0) {
|
||||
m_fifoCanWrite = true;
|
||||
|
||||
writeFifo();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_GST_APPSRC)
|
||||
if (!request.url().isEmpty() || userStreamValid) {
|
||||
#else
|
||||
if (!request.url().isEmpty()) {
|
||||
#endif
|
||||
m_mediaStatus = QMediaPlayer::LoadingMedia;
|
||||
m_session->pause();
|
||||
} else {
|
||||
m_mediaStatus = QMediaPlayer::NoMedia;
|
||||
setBufferProgress(0);
|
||||
}
|
||||
|
||||
if (m_currentResource != oldMedia)
|
||||
emit mediaChanged(m_currentResource);
|
||||
|
||||
emit positionChanged(position());
|
||||
|
||||
if (content.isNull() && !stream)
|
||||
m_resources->release();
|
||||
|
||||
popAndNotifyState();
|
||||
}
|
||||
|
||||
void QGstreamerPlayerControl::setVideoOutput(QObject *output)
|
||||
{
|
||||
m_session->setVideoRenderer(output);
|
||||
}
|
||||
|
||||
bool QGstreamerPlayerControl::isAudioAvailable() const
|
||||
{
|
||||
return m_session->isAudioAvailable();
|
||||
}
|
||||
|
||||
bool QGstreamerPlayerControl::isVideoAvailable() const
|
||||
{
|
||||
return m_session->isVideoAvailable();
|
||||
}
|
||||
|
||||
void QGstreamerPlayerControl::updateSessionState(QMediaPlayer::State state)
|
||||
{
|
||||
pushState();
|
||||
|
||||
if (state == QMediaPlayer::StoppedState)
|
||||
m_state = QMediaPlayer::StoppedState;
|
||||
|
||||
updateMediaStatus();
|
||||
|
||||
popAndNotifyState();
|
||||
}
|
||||
|
||||
void QGstreamerPlayerControl::updateMediaStatus()
|
||||
{
|
||||
pushState();
|
||||
QMediaPlayer::MediaStatus oldStatus = m_mediaStatus;
|
||||
|
||||
switch (m_session->state()) {
|
||||
case QMediaPlayer::StoppedState:
|
||||
if (m_currentResource.isNull())
|
||||
m_mediaStatus = QMediaPlayer::NoMedia;
|
||||
else if (oldStatus != QMediaPlayer::InvalidMedia)
|
||||
m_mediaStatus = QMediaPlayer::LoadingMedia;
|
||||
break;
|
||||
|
||||
case QMediaPlayer::PlayingState:
|
||||
case QMediaPlayer::PausedState:
|
||||
if (m_state == QMediaPlayer::StoppedState) {
|
||||
m_mediaStatus = QMediaPlayer::LoadedMedia;
|
||||
} else {
|
||||
if (m_bufferProgress == -1 || m_bufferProgress == 100)
|
||||
m_mediaStatus = QMediaPlayer::BufferedMedia;
|
||||
else
|
||||
m_mediaStatus = QMediaPlayer::StalledMedia;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_state == QMediaPlayer::PlayingState && !m_resources->isGranted())
|
||||
m_mediaStatus = QMediaPlayer::StalledMedia;
|
||||
|
||||
//EndOfMedia status should be kept, until reset by pause, play or setMedia
|
||||
if (oldStatus == QMediaPlayer::EndOfMedia)
|
||||
m_mediaStatus = QMediaPlayer::EndOfMedia;
|
||||
|
||||
popAndNotifyState();
|
||||
}
|
||||
|
||||
void QGstreamerPlayerControl::processEOS()
|
||||
{
|
||||
pushState();
|
||||
m_mediaStatus = QMediaPlayer::EndOfMedia;
|
||||
emit positionChanged(position());
|
||||
stop();
|
||||
popAndNotifyState();
|
||||
}
|
||||
|
||||
void QGstreamerPlayerControl::setBufferProgress(int progress)
|
||||
{
|
||||
if (m_bufferProgress == progress || m_mediaStatus == QMediaPlayer::NoMedia)
|
||||
return;
|
||||
|
||||
#ifdef DEBUG_PLAYBIN
|
||||
qDebug() << Q_FUNC_INFO << progress;
|
||||
#endif
|
||||
m_bufferProgress = progress;
|
||||
|
||||
if (m_resources->isGranted()) {
|
||||
if (m_state == QMediaPlayer::PlayingState &&
|
||||
m_bufferProgress == 100 &&
|
||||
m_session->state() != QMediaPlayer::PlayingState)
|
||||
m_session->play();
|
||||
|
||||
if (m_bufferProgress < 100 &&
|
||||
(m_session->state() == QMediaPlayer::PlayingState ||
|
||||
m_session->pendingState() == QMediaPlayer::PlayingState))
|
||||
m_session->pause();
|
||||
}
|
||||
|
||||
updateMediaStatus();
|
||||
|
||||
emit bufferStatusChanged(m_bufferProgress);
|
||||
}
|
||||
|
||||
void QGstreamerPlayerControl::writeFifo()
|
||||
{
|
||||
if (m_fifoCanWrite) {
|
||||
qint64 bytesToRead = qMin<qint64>(
|
||||
m_stream->bytesAvailable(), PIPE_BUF - m_bufferSize);
|
||||
|
||||
if (bytesToRead > 0) {
|
||||
int bytesRead = m_stream->read(&m_buffer[m_bufferOffset + m_bufferSize], bytesToRead);
|
||||
|
||||
if (bytesRead > 0)
|
||||
m_bufferSize += bytesRead;
|
||||
}
|
||||
|
||||
if (m_bufferSize > 0) {
|
||||
int bytesWritten = ::write(m_fifoFd[1], &m_buffer[m_bufferOffset], size_t(m_bufferSize));
|
||||
|
||||
if (bytesWritten > 0) {
|
||||
m_bufferOffset += bytesWritten;
|
||||
m_bufferSize -= bytesWritten;
|
||||
|
||||
if (m_bufferSize == 0)
|
||||
m_bufferOffset = 0;
|
||||
} else if (errno == EAGAIN) {
|
||||
m_fifoCanWrite = false;
|
||||
} else {
|
||||
closeFifo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_fifoNotifier->setEnabled(m_stream->bytesAvailable() > 0);
|
||||
}
|
||||
|
||||
void QGstreamerPlayerControl::fifoReadyWrite(int socket)
|
||||
{
|
||||
if (socket == m_fifoFd[1]) {
|
||||
m_fifoCanWrite = true;
|
||||
|
||||
writeFifo();
|
||||
}
|
||||
}
|
||||
|
||||
bool QGstreamerPlayerControl::openFifo()
|
||||
{
|
||||
Q_ASSERT(m_fifoFd[0] < 0);
|
||||
Q_ASSERT(m_fifoFd[1] < 0);
|
||||
|
||||
if (::pipe(m_fifoFd) == 0) {
|
||||
int flags = ::fcntl(m_fifoFd[1], F_GETFD);
|
||||
|
||||
if (::fcntl(m_fifoFd[1], F_SETFD, flags | O_NONBLOCK) >= 0) {
|
||||
m_fifoNotifier = new QSocketNotifier(m_fifoFd[1], QSocketNotifier::Write);
|
||||
|
||||
connect(m_fifoNotifier, SIGNAL(activated(int)), this, SLOT(fifoReadyWrite(int)));
|
||||
|
||||
return true;
|
||||
} else {
|
||||
qWarning("Failed to make pipe non blocking %d", errno);
|
||||
|
||||
::close(m_fifoFd[0]);
|
||||
::close(m_fifoFd[1]);
|
||||
|
||||
m_fifoFd[0] = -1;
|
||||
m_fifoFd[1] = -1;
|
||||
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
qWarning("Failed to create pipe %d", errno);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void QGstreamerPlayerControl::closeFifo()
|
||||
{
|
||||
if (m_fifoFd[0] >= 0) {
|
||||
delete m_fifoNotifier;
|
||||
m_fifoNotifier = 0;
|
||||
|
||||
::close(m_fifoFd[0]);
|
||||
::close(m_fifoFd[1]);
|
||||
m_fifoFd[0] = -1;
|
||||
m_fifoFd[1] = -1;
|
||||
|
||||
m_fifoCanWrite = false;
|
||||
|
||||
m_bufferSize = 0;
|
||||
m_bufferOffset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void QGstreamerPlayerControl::applyPendingSeek(bool isSeekable)
|
||||
{
|
||||
if (isSeekable && m_pendingSeekPosition != -1)
|
||||
setPosition(m_pendingSeekPosition);
|
||||
}
|
||||
|
||||
void QGstreamerPlayerControl::handleInvalidMedia()
|
||||
{
|
||||
pushState();
|
||||
m_mediaStatus = QMediaPlayer::InvalidMedia;
|
||||
m_state = QMediaPlayer::StoppedState;
|
||||
popAndNotifyState();
|
||||
}
|
||||
|
||||
void QGstreamerPlayerControl::handleResourcesGranted()
|
||||
{
|
||||
pushState();
|
||||
|
||||
QMediaPlayer::State state = m_state;
|
||||
|
||||
//preserve m_pendingSeekPosition, it's reset on setMedia
|
||||
qint64 pos = m_pendingSeekPosition;
|
||||
setMedia(m_currentResource, m_stream);
|
||||
|
||||
if (pos != -1)
|
||||
setPosition(pos);
|
||||
|
||||
if (state != QMediaPlayer::StoppedState)
|
||||
playOrPause(state);
|
||||
else
|
||||
updateMediaStatus();
|
||||
|
||||
popAndNotifyState();
|
||||
}
|
||||
|
||||
void QGstreamerPlayerControl::handleResourcesLost()
|
||||
{
|
||||
//on resource lost the pipeline should be stopped
|
||||
//player status is changed to paused
|
||||
|
||||
pushState();
|
||||
QMediaPlayer::State oldState = m_state;
|
||||
|
||||
qint64 pos = m_session->position();
|
||||
m_session->stop();
|
||||
m_pendingSeekPosition = pos;
|
||||
|
||||
if (oldState != QMediaPlayer::StoppedState )
|
||||
m_state = QMediaPlayer::PausedState;
|
||||
|
||||
popAndNotifyState();
|
||||
}
|
||||
|
||||
bool QGstreamerPlayerControl::isMediaDownloadEnabled() const
|
||||
{
|
||||
return m_session->property("mediaDownloadEnabled").toBool();
|
||||
}
|
||||
|
||||
void QGstreamerPlayerControl::setMediaDownloadEnabled(bool enabled)
|
||||
{
|
||||
m_session->setProperty("mediaDownloadEnabled", enabled);
|
||||
}
|
||||
|
||||
void QGstreamerPlayerControl::pushState()
|
||||
{
|
||||
m_stateStack.push(m_state);
|
||||
m_mediaStatusStack.push(m_mediaStatus);
|
||||
}
|
||||
|
||||
void QGstreamerPlayerControl::popAndNotifyState()
|
||||
{
|
||||
Q_ASSERT(!m_stateStack.isEmpty());
|
||||
|
||||
QMediaPlayer::State oldState = m_stateStack.pop();
|
||||
QMediaPlayer::MediaStatus oldMediaStatus = m_mediaStatusStack.pop();
|
||||
|
||||
if (m_stateStack.isEmpty()) {
|
||||
if (m_state != oldState) {
|
||||
#ifdef DEBUG_PLAYBIN
|
||||
qDebug() << "State changed:" << m_state;
|
||||
#endif
|
||||
emit stateChanged(m_state);
|
||||
}
|
||||
|
||||
if (m_mediaStatus != oldMediaStatus) {
|
||||
#ifdef DEBUG_PLAYBIN
|
||||
qDebug() << "Media status changed:" << m_mediaStatus;
|
||||
#endif
|
||||
emit mediaStatusChanged(m_mediaStatus);
|
||||
}
|
||||
}
|
||||
}
|
||||
157
src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.h
Normal file
157
src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.h
Normal file
@@ -0,0 +1,157 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 QGSTREAMERPLAYERCONTROL_H
|
||||
#define QGSTREAMERPLAYERCONTROL_H
|
||||
|
||||
#include <QtCore/qobject.h>
|
||||
#include <QtCore/qstack.h>
|
||||
|
||||
#include <qmediaplayercontrol.h>
|
||||
#include <qmediaplayer.h>
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QMediaPlaylist;
|
||||
class QMediaPlaylistNavigator;
|
||||
class QSocketNotifier;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class QGstreamerPlayerSession;
|
||||
class QGstreamerPlayerService;
|
||||
class PlayerResourcePolicy;
|
||||
|
||||
class QGstreamerPlayerControl : public QMediaPlayerControl
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool mediaDownloadEnabled READ isMediaDownloadEnabled WRITE setMediaDownloadEnabled)
|
||||
|
||||
public:
|
||||
QGstreamerPlayerControl(QGstreamerPlayerSession *session, QObject *parent = 0);
|
||||
~QGstreamerPlayerControl();
|
||||
|
||||
QMediaPlayer::State state() const;
|
||||
QMediaPlayer::MediaStatus mediaStatus() const;
|
||||
|
||||
qint64 position() const;
|
||||
qint64 duration() const;
|
||||
|
||||
int bufferStatus() const;
|
||||
|
||||
int volume() const;
|
||||
bool isMuted() const;
|
||||
|
||||
bool isAudioAvailable() const;
|
||||
bool isVideoAvailable() const;
|
||||
void setVideoOutput(QObject *output);
|
||||
|
||||
bool isSeekable() const;
|
||||
QMediaTimeRange availablePlaybackRanges() const;
|
||||
|
||||
qreal playbackRate() const;
|
||||
void setPlaybackRate(qreal rate);
|
||||
|
||||
QMediaContent media() const;
|
||||
const QIODevice *mediaStream() const;
|
||||
void setMedia(const QMediaContent&, QIODevice *);
|
||||
|
||||
bool isMediaDownloadEnabled() const;
|
||||
void setMediaDownloadEnabled(bool enabled);
|
||||
|
||||
public Q_SLOTS:
|
||||
void setPosition(qint64 pos);
|
||||
|
||||
void play();
|
||||
void pause();
|
||||
void stop();
|
||||
|
||||
void setVolume(int volume);
|
||||
void setMuted(bool muted);
|
||||
|
||||
private Q_SLOTS:
|
||||
void writeFifo();
|
||||
void fifoReadyWrite(int socket);
|
||||
|
||||
void updateSessionState(QMediaPlayer::State state);
|
||||
void updateMediaStatus();
|
||||
void processEOS();
|
||||
void setBufferProgress(int progress);
|
||||
void applyPendingSeek(bool isSeekable);
|
||||
|
||||
void handleInvalidMedia();
|
||||
|
||||
void handleResourcesGranted();
|
||||
void handleResourcesLost();
|
||||
|
||||
private:
|
||||
bool openFifo();
|
||||
void closeFifo();
|
||||
void playOrPause(QMediaPlayer::State state);
|
||||
|
||||
void pushState();
|
||||
void popAndNotifyState();
|
||||
|
||||
bool m_ownStream;
|
||||
QGstreamerPlayerSession *m_session;
|
||||
QMediaPlayer::State m_state;
|
||||
QMediaPlayer::MediaStatus m_mediaStatus;
|
||||
QStack<QMediaPlayer::State> m_stateStack;
|
||||
QStack<QMediaPlayer::MediaStatus> m_mediaStatusStack;
|
||||
|
||||
int m_bufferProgress;
|
||||
bool m_seekToStartPending;
|
||||
qint64 m_pendingSeekPosition;
|
||||
QMediaContent m_currentResource;
|
||||
QIODevice *m_stream;
|
||||
QSocketNotifier *m_fifoNotifier;
|
||||
int m_fifoFd[2];
|
||||
bool m_fifoCanWrite;
|
||||
int m_bufferSize;
|
||||
int m_bufferOffset;
|
||||
char m_buffer[PIPE_BUF];
|
||||
|
||||
PlayerResourcePolicy *m_resources;
|
||||
};
|
||||
|
||||
#endif
|
||||
134
src/plugins/gstreamer/mediaplayer/qgstreamerplayerservice.cpp
Normal file
134
src/plugins/gstreamer/mediaplayer/qgstreamerplayerservice.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 <QtCore/qvariant.h>
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtGui/qwidget.h>
|
||||
|
||||
#include "qgstreamerplayerservice.h"
|
||||
#include "qgstreamerplayercontrol.h"
|
||||
#include "qgstreamerplayersession.h"
|
||||
#include "qgstreamermetadataprovider.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 "qgstreamerstreamscontrol.h"
|
||||
|
||||
#include <qmediaplaylistnavigator.h>
|
||||
#include <qmediaplaylist.h>
|
||||
|
||||
QGstreamerPlayerService::QGstreamerPlayerService(QObject *parent):
|
||||
QMediaService(parent),
|
||||
m_videoOutput(0),
|
||||
m_videoRenderer(0),
|
||||
m_videoWindow(0),
|
||||
m_videoWidget(0)
|
||||
{
|
||||
m_session = new QGstreamerPlayerSession(this);
|
||||
m_control = new QGstreamerPlayerControl(m_session, this);
|
||||
m_metaData = new QGstreamerMetaDataProvider(m_session, this);
|
||||
m_streamsControl = new QGstreamerStreamsControl(m_session,this);
|
||||
|
||||
#if defined(Q_WS_MAEMO_6) && defined(__arm__)
|
||||
m_videoRenderer = new QGstreamerGLTextureRenderer(this);
|
||||
#else
|
||||
m_videoRenderer = new QGstreamerVideoRenderer(this);
|
||||
#endif
|
||||
|
||||
#if defined(Q_WS_X11) && !defined(QT_NO_XVIDEO)
|
||||
|
||||
#ifdef Q_WS_MAEMO_6
|
||||
m_videoWindow = new QGstreamerVideoWindow(this, "omapxvsink");
|
||||
#else
|
||||
m_videoWindow = new QGstreamerVideoOverlay(this);
|
||||
#endif
|
||||
|
||||
m_videoWidget = new QGstreamerVideoWidgetControl(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
QGstreamerPlayerService::~QGstreamerPlayerService()
|
||||
{
|
||||
}
|
||||
|
||||
QMediaControl *QGstreamerPlayerService::requestControl(const char *name)
|
||||
{
|
||||
if (qstrcmp(name,QMediaPlayerControl_iid) == 0)
|
||||
return m_control;
|
||||
|
||||
if (qstrcmp(name,QMetaDataReaderControl_iid) == 0)
|
||||
return m_metaData;
|
||||
|
||||
if (qstrcmp(name,QMediaStreamsControl_iid) == 0)
|
||||
return m_streamsControl;
|
||||
|
||||
if (!m_videoOutput) {
|
||||
if (qstrcmp(name, QVideoWidgetControl_iid) == 0)
|
||||
m_videoOutput = m_videoWidget;
|
||||
else if (qstrcmp(name, QVideoRendererControl_iid) == 0)
|
||||
m_videoOutput = m_videoRenderer;
|
||||
else if (qstrcmp(name, QVideoWindowControl_iid) == 0)
|
||||
m_videoOutput = m_videoWindow;
|
||||
|
||||
if (m_videoOutput) {
|
||||
m_control->setVideoOutput(m_videoOutput);
|
||||
return m_videoOutput;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void QGstreamerPlayerService::releaseControl(QMediaControl *control)
|
||||
{
|
||||
if (control == m_videoOutput) {
|
||||
m_videoOutput = 0;
|
||||
m_control->setVideoOutput(0);
|
||||
}
|
||||
}
|
||||
|
||||
90
src/plugins/gstreamer/mediaplayer/qgstreamerplayerservice.h
Normal file
90
src/plugins/gstreamer/mediaplayer/qgstreamerplayerservice.h
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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QGSTREAMERPLAYERSERVICE_H
|
||||
#define QGSTREAMERPLAYERSERVICE_H
|
||||
|
||||
#include <QtCore/qobject.h>
|
||||
#include <QtCore/qiodevice.h>
|
||||
|
||||
#include <qmediaservice.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QMediaMetaData;
|
||||
class QMediaPlayerControl;
|
||||
class QMediaPlaylist;
|
||||
class QMediaPlaylistNavigator;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class QGstreamerMetaData;
|
||||
class QGstreamerPlayerControl;
|
||||
class QGstreamerPlayerSession;
|
||||
class QGstreamerMetaDataProvider;
|
||||
class QGstreamerStreamsControl;
|
||||
class QGstreamerVideoRenderer;
|
||||
class QGstreamerVideoOverlay;
|
||||
class QGstreamerVideoWidgetControl;
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class QGstreamerPlayerService : public QMediaService
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QGstreamerPlayerService(QObject *parent = 0);
|
||||
~QGstreamerPlayerService();
|
||||
|
||||
QMediaControl *requestControl(const char *name);
|
||||
void releaseControl(QMediaControl *control);
|
||||
|
||||
private:
|
||||
QGstreamerPlayerControl *m_control;
|
||||
QGstreamerPlayerSession *m_session;
|
||||
QGstreamerMetaDataProvider *m_metaData;
|
||||
QGstreamerStreamsControl *m_streamsControl;
|
||||
|
||||
QMediaControl *m_videoOutput;
|
||||
QMediaControl *m_videoRenderer;
|
||||
QMediaControl *m_videoWindow;
|
||||
QMediaControl *m_videoWidget;
|
||||
};
|
||||
|
||||
#endif
|
||||
1537
src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp
Normal file
1537
src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp
Normal file
File diff suppressed because it is too large
Load Diff
217
src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h
Normal file
217
src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h
Normal file
@@ -0,0 +1,217 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 QGSTREAMERPLAYERSESSION_H
|
||||
#define QGSTREAMERPLAYERSESSION_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QtNetwork/qnetworkrequest.h>
|
||||
#include "qgstreamerplayercontrol.h"
|
||||
#include "qgstreamerbushelper.h"
|
||||
#include <qmediaplayer.h>
|
||||
#include <qmediastreamscontrol.h>
|
||||
|
||||
#if defined(HAVE_GST_APPSRC)
|
||||
#include "qgstappsrc.h"
|
||||
#endif
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
class QGstreamerBusHelper;
|
||||
class QGstreamerMessage;
|
||||
|
||||
class QGstreamerVideoRendererInterface;
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class QGstreamerPlayerSession : public QObject, public QGstreamerSyncEventFilter
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QGstreamerPlayerSession(QObject *parent);
|
||||
virtual ~QGstreamerPlayerSession();
|
||||
|
||||
QNetworkRequest request() const;
|
||||
|
||||
QMediaPlayer::State state() const { return m_state; }
|
||||
QMediaPlayer::State pendingState() const { return m_pendingState; }
|
||||
|
||||
qint64 duration() const;
|
||||
qint64 position() const;
|
||||
|
||||
bool isBuffering() const;
|
||||
|
||||
int bufferingProgress() const;
|
||||
|
||||
int volume() const;
|
||||
bool isMuted() const;
|
||||
|
||||
bool isAudioAvailable() const;
|
||||
|
||||
void setVideoRenderer(QObject *renderer);
|
||||
bool isVideoAvailable() const;
|
||||
|
||||
bool isSeekable() const;
|
||||
|
||||
qreal playbackRate() const;
|
||||
void setPlaybackRate(qreal rate);
|
||||
|
||||
QMediaTimeRange availablePlaybackRanges() const;
|
||||
|
||||
QMap<QByteArray ,QVariant> tags() const { return m_tags; }
|
||||
QMap<QtMultimediaKit::MetaData,QVariant> streamProperties(int streamNumber) const { return m_streamProperties[streamNumber]; }
|
||||
int streamCount() const { return m_streamProperties.count(); }
|
||||
QMediaStreamsControl::StreamType streamType(int streamNumber) { return m_streamTypes.value(streamNumber, QMediaStreamsControl::UnknownStream); }
|
||||
|
||||
int activeStream(QMediaStreamsControl::StreamType streamType) const;
|
||||
void setActiveStream(QMediaStreamsControl::StreamType streamType, int streamNumber);
|
||||
|
||||
bool processSyncMessage(const QGstreamerMessage &message);
|
||||
|
||||
#if defined(HAVE_GST_APPSRC)
|
||||
QGstAppSrc *appsrc() const { return m_appSrc; }
|
||||
static void configureAppSrcElement(GObject*, GObject*, GParamSpec*,QGstreamerPlayerSession* _this);
|
||||
#endif
|
||||
|
||||
public slots:
|
||||
void loadFromUri(const QNetworkRequest &url);
|
||||
void loadFromStream(const QNetworkRequest &url, QIODevice *stream);
|
||||
bool play();
|
||||
bool pause();
|
||||
void stop();
|
||||
|
||||
bool seek(qint64 pos);
|
||||
|
||||
void setVolume(int volume);
|
||||
void setMuted(bool muted);
|
||||
|
||||
signals:
|
||||
void durationChanged(qint64 duration);
|
||||
void positionChanged(qint64 position);
|
||||
void stateChanged(QMediaPlayer::State state);
|
||||
void volumeChanged(int volume);
|
||||
void mutedStateChanged(bool muted);
|
||||
void audioAvailableChanged(bool audioAvailable);
|
||||
void videoAvailableChanged(bool videoAvailable);
|
||||
void bufferingChanged(bool buffering);
|
||||
void bufferingProgressChanged(int percentFilled);
|
||||
void playbackFinished();
|
||||
void tagsChanged();
|
||||
void streamsChanged();
|
||||
void seekableChanged(bool);
|
||||
void error(int error, const QString &errorString);
|
||||
void invalidMedia();
|
||||
void playbackRateChanged(qreal);
|
||||
|
||||
private slots:
|
||||
void busMessage(const QGstreamerMessage &message);
|
||||
void getStreamsInfo();
|
||||
void setSeekable(bool);
|
||||
void finishVideoOutputChange();
|
||||
void updateVideoRenderer();
|
||||
void updateVideoResolutionTag();
|
||||
void updateVolume();
|
||||
void updateMuted();
|
||||
void updateDuration();
|
||||
|
||||
private:
|
||||
static void playbinNotifySource(GObject *o, GParamSpec *p, gpointer d);
|
||||
static void handleVolumeChange(GObject *o, GParamSpec *p, gpointer d);
|
||||
static void handleMutedChange(GObject *o, GParamSpec *p, gpointer d);
|
||||
static void insertColorSpaceElement(GstElement *element, gpointer data);
|
||||
static void handleElementAdded(GstBin *bin, GstElement *element, QGstreamerPlayerSession *session);
|
||||
void processInvalidMedia(QMediaPlayer::Error errorCode, const QString& errorString);
|
||||
|
||||
QNetworkRequest m_request;
|
||||
QMediaPlayer::State m_state;
|
||||
QMediaPlayer::State m_pendingState;
|
||||
QGstreamerBusHelper* m_busHelper;
|
||||
GstElement* m_playbin;
|
||||
bool m_usePlaybin2;
|
||||
|
||||
GstElement* m_videoOutputBin;
|
||||
GstElement* m_videoIdentity;
|
||||
GstElement* m_colorSpace;
|
||||
bool m_usingColorspaceElement;
|
||||
GstElement* m_videoSink;
|
||||
GstElement* m_pendingVideoSink;
|
||||
GstElement* m_nullVideoSink;
|
||||
|
||||
GstBus* m_bus;
|
||||
QObject *m_videoOutput;
|
||||
QGstreamerVideoRendererInterface *m_renderer;
|
||||
|
||||
bool m_haveQueueElement;
|
||||
|
||||
#if defined(HAVE_GST_APPSRC)
|
||||
QGstAppSrc *m_appSrc;
|
||||
#endif
|
||||
|
||||
QMap<QByteArray, QVariant> m_tags;
|
||||
QList< QMap<QtMultimediaKit::MetaData,QVariant> > m_streamProperties;
|
||||
QList<QMediaStreamsControl::StreamType> m_streamTypes;
|
||||
QMap<QMediaStreamsControl::StreamType, int> m_playbin2StreamOffset;
|
||||
|
||||
|
||||
int m_volume;
|
||||
qreal m_playbackRate;
|
||||
bool m_muted;
|
||||
bool m_audioAvailable;
|
||||
bool m_videoAvailable;
|
||||
bool m_seekable;
|
||||
|
||||
mutable qint64 m_lastPosition;
|
||||
qint64 m_duration;
|
||||
int m_durationQueries;
|
||||
|
||||
enum SourceType
|
||||
{
|
||||
UnknownSrc,
|
||||
SoupHTTPSrc,
|
||||
UDPSrc,
|
||||
MMSSrc
|
||||
};
|
||||
SourceType m_sourceType;
|
||||
bool m_everPlayed;
|
||||
};
|
||||
|
||||
#endif // QGSTREAMERPLAYERSESSION_H
|
||||
@@ -0,0 +1,89 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "qgstreamerstreamscontrol.h"
|
||||
#include "qgstreamerplayersession.h"
|
||||
|
||||
QGstreamerStreamsControl::QGstreamerStreamsControl(QGstreamerPlayerSession *session, QObject *parent)
|
||||
:QMediaStreamsControl(parent), m_session(session)
|
||||
{
|
||||
connect(m_session, SIGNAL(streamsChanged()), SIGNAL(streamsChanged()));
|
||||
}
|
||||
|
||||
QGstreamerStreamsControl::~QGstreamerStreamsControl()
|
||||
{
|
||||
}
|
||||
|
||||
int QGstreamerStreamsControl::streamCount()
|
||||
{
|
||||
return m_session->streamCount();
|
||||
}
|
||||
|
||||
QMediaStreamsControl::StreamType QGstreamerStreamsControl::streamType(int streamNumber)
|
||||
{
|
||||
return m_session->streamType(streamNumber);
|
||||
}
|
||||
|
||||
QVariant QGstreamerStreamsControl::metaData(int streamNumber, QtMultimediaKit::MetaData key)
|
||||
{
|
||||
return m_session->streamProperties(streamNumber).value(key);
|
||||
}
|
||||
|
||||
bool QGstreamerStreamsControl::isActive(int streamNumber)
|
||||
{
|
||||
return streamNumber != -1 && streamNumber == m_session->activeStream(streamType(streamNumber));
|
||||
}
|
||||
|
||||
void QGstreamerStreamsControl::setActive(int streamNumber, bool state)
|
||||
{
|
||||
QMediaStreamsControl::StreamType type = m_session->streamType(streamNumber);
|
||||
if (type == QMediaStreamsControl::UnknownStream)
|
||||
return;
|
||||
|
||||
if (state)
|
||||
m_session->setActiveStream(type, streamNumber);
|
||||
else {
|
||||
//only one active stream of certain type is supported
|
||||
if (m_session->activeStream(type) == streamNumber)
|
||||
m_session->setActiveStream(type, -1);
|
||||
}
|
||||
}
|
||||
|
||||
71
src/plugins/gstreamer/mediaplayer/qgstreamerstreamscontrol.h
Normal file
71
src/plugins/gstreamer/mediaplayer/qgstreamerstreamscontrol.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the Qt Mobility Components.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QGSTREAMERSTREAMSCONTROL_H
|
||||
#define QGSTREAMERSTREAMSCONTROL_H
|
||||
|
||||
#include <qmediastreamscontrol.h>
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class QGstreamerPlayerSession;
|
||||
|
||||
class QGstreamerStreamsControl : public QMediaStreamsControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QGstreamerStreamsControl(QGstreamerPlayerSession *session, QObject *parent);
|
||||
virtual ~QGstreamerStreamsControl();
|
||||
|
||||
virtual int streamCount();
|
||||
virtual StreamType streamType(int streamNumber);
|
||||
|
||||
virtual QVariant metaData(int streamNumber, QtMultimediaKit::MetaData key);
|
||||
|
||||
virtual bool isActive(int streamNumber);
|
||||
virtual void setActive(int streamNumber, bool state);
|
||||
|
||||
private:
|
||||
QGstreamerPlayerSession *m_session;
|
||||
};
|
||||
|
||||
#endif // QGSTREAMERSTREAMSCONTROL_H
|
||||
|
||||
75
src/plugins/gstreamer/qabstractgstbufferpool.h
Normal file
75
src/plugins/gstreamer/qabstractgstbufferpool.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 QGSTBUFFERPOOL_H
|
||||
#define QGSTBUFFERPOOL_H
|
||||
|
||||
#include <qabstractvideobuffer.h>
|
||||
#include <qvideosurfaceformat.h>
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
/*!
|
||||
Abstract interface for video buffers allocation.
|
||||
*/
|
||||
class QAbstractGstBufferPool
|
||||
{
|
||||
public:
|
||||
virtual ~QAbstractGstBufferPool() {}
|
||||
|
||||
virtual bool isFormatSupported(const QVideoSurfaceFormat &format) const = 0;
|
||||
|
||||
virtual GType bufferType() const = 0;
|
||||
virtual GstBuffer *takeBuffer(const QVideoSurfaceFormat &format, GstCaps *caps) = 0;
|
||||
virtual void clear() = 0;
|
||||
|
||||
virtual QAbstractVideoBuffer::HandleType handleType() const = 0;
|
||||
|
||||
/*!
|
||||
Build an QAbstractVideoBuffer instance from compatible (mathcing gst buffer type)
|
||||
GstBuffer.
|
||||
|
||||
This method is called from gstreamer video sink thread.
|
||||
*/
|
||||
virtual QAbstractVideoBuffer *prepareVideoBuffer(GstBuffer *buffer, int bytesPerLine) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
174
src/plugins/gstreamer/qgstreameraudioinputendpointselector.cpp
Normal file
174
src/plugins/gstreamer/qgstreameraudioinputendpointselector.cpp
Normal file
@@ -0,0 +1,174 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "qgstreameraudioinputendpointselector.h"
|
||||
|
||||
#include <QtGui/QIcon>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#ifdef HAVE_ALSA
|
||||
#include <alsa/asoundlib.h>
|
||||
#endif
|
||||
|
||||
QGstreamerAudioInputEndpointSelector::QGstreamerAudioInputEndpointSelector(QObject *parent)
|
||||
:QAudioEndpointSelector(parent)
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
QGstreamerAudioInputEndpointSelector::~QGstreamerAudioInputEndpointSelector()
|
||||
{
|
||||
}
|
||||
|
||||
QList<QString> QGstreamerAudioInputEndpointSelector::availableEndpoints() const
|
||||
{
|
||||
return m_names;
|
||||
}
|
||||
|
||||
QString QGstreamerAudioInputEndpointSelector::endpointDescription(const QString& name) const
|
||||
{
|
||||
QString desc;
|
||||
|
||||
for (int i = 0; i < m_names.size(); i++) {
|
||||
if (m_names.at(i).compare(name) == 0) {
|
||||
desc = m_descriptions.at(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return desc;
|
||||
}
|
||||
|
||||
QString QGstreamerAudioInputEndpointSelector::defaultEndpoint() const
|
||||
{
|
||||
if (m_names.size() > 0)
|
||||
return m_names.at(0);
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString QGstreamerAudioInputEndpointSelector::activeEndpoint() const
|
||||
{
|
||||
return m_audioInput;
|
||||
}
|
||||
|
||||
void QGstreamerAudioInputEndpointSelector::setActiveEndpoint(const QString& name)
|
||||
{
|
||||
if (m_audioInput.compare(name) != 0) {
|
||||
m_audioInput = name;
|
||||
emit activeEndpointChanged(name);
|
||||
}
|
||||
}
|
||||
|
||||
void QGstreamerAudioInputEndpointSelector::update()
|
||||
{
|
||||
m_names.clear();
|
||||
m_descriptions.clear();
|
||||
#ifndef Q_WS_MAEMO_5
|
||||
updateAlsaDevices();
|
||||
updateOssDevices();
|
||||
#endif
|
||||
updatePulseDevices();
|
||||
if (m_names.size() > 0)
|
||||
m_audioInput = m_names.at(0);
|
||||
}
|
||||
|
||||
void QGstreamerAudioInputEndpointSelector::updateAlsaDevices()
|
||||
{
|
||||
#ifdef HAVE_ALSA
|
||||
void **hints, **n;
|
||||
if (snd_device_name_hint(-1, "pcm", &hints) < 0) {
|
||||
qWarning()<<"no alsa devices available";
|
||||
return;
|
||||
}
|
||||
n = hints;
|
||||
|
||||
while (*n != NULL) {
|
||||
char *name = snd_device_name_get_hint(*n, "NAME");
|
||||
char *descr = snd_device_name_get_hint(*n, "DESC");
|
||||
char *io = snd_device_name_get_hint(*n, "IOID");
|
||||
|
||||
if ((name != NULL) && (descr != NULL)) {
|
||||
if ( io == NULL || qstrcmp(io,"Input") == 0 ) {
|
||||
m_names.append(QLatin1String("alsa:")+QString::fromUtf8(name));
|
||||
m_descriptions.append(QString::fromUtf8(descr));
|
||||
}
|
||||
}
|
||||
|
||||
if (name != NULL)
|
||||
free(name);
|
||||
if (descr != NULL)
|
||||
free(descr);
|
||||
if (io != NULL)
|
||||
free(io);
|
||||
n++;
|
||||
}
|
||||
snd_device_name_free_hint(hints);
|
||||
#endif
|
||||
}
|
||||
|
||||
void QGstreamerAudioInputEndpointSelector::updateOssDevices()
|
||||
{
|
||||
QDir devDir("/dev");
|
||||
devDir.setFilter(QDir::System);
|
||||
#ifndef QT_QWS_N810
|
||||
QFileInfoList entries = devDir.entryInfoList(QStringList() << "dsp*");
|
||||
foreach(const QFileInfo& entryInfo, entries) {
|
||||
m_names.append(QLatin1String("oss:")+entryInfo.filePath());
|
||||
m_descriptions.append(QString("OSS device %1").arg(entryInfo.fileName()));
|
||||
}
|
||||
#else
|
||||
m_names.append("dsppcm");
|
||||
m_descriptions.append("PCM audio input");
|
||||
#endif
|
||||
}
|
||||
|
||||
void QGstreamerAudioInputEndpointSelector::updatePulseDevices()
|
||||
{
|
||||
GstElementFactory *factory = gst_element_factory_find("pulsesrc");
|
||||
if (factory) {
|
||||
m_names.append("pulseaudio:");
|
||||
m_descriptions.append("PulseAudio device.");
|
||||
gst_object_unref(GST_OBJECT(factory));
|
||||
}
|
||||
}
|
||||
76
src/plugins/gstreamer/qgstreameraudioinputendpointselector.h
Normal file
76
src/plugins/gstreamer/qgstreameraudioinputendpointselector.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 QGSTREAMERAUDIOINPUTENDPOINTSELECTOR_H
|
||||
#define QGSTREAMERAUDIOINPUTENDPOINTSELECTOR_H
|
||||
|
||||
#include <qaudioendpointselector.h>
|
||||
#include <QtCore/qstringlist.h>
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class QGstreamerAudioInputEndpointSelector : public QAudioEndpointSelector
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QGstreamerAudioInputEndpointSelector(QObject *parent);
|
||||
~QGstreamerAudioInputEndpointSelector();
|
||||
|
||||
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();
|
||||
void updateAlsaDevices();
|
||||
void updateOssDevices();
|
||||
void updatePulseDevices();
|
||||
|
||||
QString m_audioInput;
|
||||
QList<QString> m_names;
|
||||
QList<QString> m_descriptions;
|
||||
};
|
||||
|
||||
#endif // QGSTREAMERAUDIOINPUTENDPOINTSELECTOR_H
|
||||
203
src/plugins/gstreamer/qgstreamerbushelper.cpp
Normal file
203
src/plugins/gstreamer/qgstreamerbushelper.cpp
Normal file
@@ -0,0 +1,203 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 <QMap>
|
||||
#include <QTimer>
|
||||
#include <QMutex>
|
||||
|
||||
#include "qgstreamerbushelper.h"
|
||||
|
||||
|
||||
#ifndef QT_NO_GLIB
|
||||
class QGstreamerBusHelperPrivate : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
void addWatch(GstBus* bus, QGstreamerBusHelper* helper)
|
||||
{
|
||||
setParent(helper);
|
||||
m_tag = gst_bus_add_watch_full(bus, 0, busCallback, this, NULL);
|
||||
m_helper = helper;
|
||||
filter = 0;
|
||||
}
|
||||
|
||||
void removeWatch(QGstreamerBusHelper* helper)
|
||||
{
|
||||
Q_UNUSED(helper);
|
||||
g_source_remove(m_tag);
|
||||
}
|
||||
|
||||
static QGstreamerBusHelperPrivate* instance()
|
||||
{
|
||||
return new QGstreamerBusHelperPrivate;
|
||||
}
|
||||
|
||||
private:
|
||||
void processMessage(GstBus* bus, GstMessage* message)
|
||||
{
|
||||
Q_UNUSED(bus);
|
||||
emit m_helper->message(message);
|
||||
}
|
||||
|
||||
static gboolean busCallback(GstBus *bus, GstMessage *message, gpointer data)
|
||||
{
|
||||
reinterpret_cast<QGstreamerBusHelperPrivate*>(data)->processMessage(bus, message);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
guint m_tag;
|
||||
QGstreamerBusHelper* m_helper;
|
||||
|
||||
public:
|
||||
GstBus* bus;
|
||||
QGstreamerSyncEventFilter *filter;
|
||||
QMutex filterMutex;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
class QGstreamerBusHelperPrivate : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
typedef QMap<QGstreamerBusHelper*, GstBus*> HelperMap;
|
||||
|
||||
public:
|
||||
void addWatch(GstBus* bus, QGstreamerBusHelper* helper)
|
||||
{
|
||||
m_helperMap.insert(helper, bus);
|
||||
|
||||
if (m_helperMap.size() == 1)
|
||||
m_intervalTimer->start();
|
||||
}
|
||||
|
||||
void removeWatch(QGstreamerBusHelper* helper)
|
||||
{
|
||||
m_helperMap.remove(helper);
|
||||
|
||||
if (m_helperMap.size() == 0)
|
||||
m_intervalTimer->stop();
|
||||
}
|
||||
|
||||
static QGstreamerBusHelperPrivate* instance()
|
||||
{
|
||||
static QGstreamerBusHelperPrivate self;
|
||||
|
||||
return &self;
|
||||
}
|
||||
|
||||
private slots:
|
||||
void interval()
|
||||
{
|
||||
for (HelperMap::iterator it = m_helperMap.begin(); it != m_helperMap.end(); ++it) {
|
||||
GstMessage* message;
|
||||
|
||||
while ((message = gst_bus_poll(it.value(), GST_MESSAGE_ANY, 0)) != 0) {
|
||||
emit it.key()->message(message);
|
||||
gst_message_unref(message);
|
||||
}
|
||||
|
||||
emit it.key()->message(QGstreamerMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
QGstreamerBusHelperPrivate()
|
||||
{
|
||||
m_intervalTimer = new QTimer(this);
|
||||
m_intervalTimer->setInterval(250);
|
||||
|
||||
connect(m_intervalTimer, SIGNAL(timeout()), SLOT(interval()));
|
||||
}
|
||||
|
||||
HelperMap m_helperMap;
|
||||
QTimer* m_intervalTimer;
|
||||
|
||||
public:
|
||||
GstBus* bus;
|
||||
QGstreamerSyncEventFilter *filter;
|
||||
QMutex filterMutex;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
static GstBusSyncReply syncGstBusFilter(GstBus* bus, GstMessage* message, QGstreamerBusHelperPrivate *d)
|
||||
{
|
||||
Q_UNUSED(bus);
|
||||
QMutexLocker lock(&d->filterMutex);
|
||||
|
||||
bool res = false;
|
||||
|
||||
if (d->filter)
|
||||
res = d->filter->processSyncMessage(QGstreamerMessage(message));
|
||||
|
||||
return res ? GST_BUS_DROP : GST_BUS_PASS;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\class gstreamer::QGstreamerBusHelper
|
||||
\internal
|
||||
*/
|
||||
|
||||
QGstreamerBusHelper::QGstreamerBusHelper(GstBus* bus, QObject* parent):
|
||||
QObject(parent),
|
||||
d(QGstreamerBusHelperPrivate::instance())
|
||||
{
|
||||
d->bus = bus;
|
||||
d->addWatch(bus, this);
|
||||
|
||||
gst_bus_set_sync_handler(bus, (GstBusSyncHandler)syncGstBusFilter, d);
|
||||
}
|
||||
|
||||
QGstreamerBusHelper::~QGstreamerBusHelper()
|
||||
{
|
||||
d->removeWatch(this);
|
||||
gst_bus_set_sync_handler(d->bus,0,0);
|
||||
}
|
||||
|
||||
void QGstreamerBusHelper::installSyncEventFilter(QGstreamerSyncEventFilter *filter)
|
||||
{
|
||||
QMutexLocker lock(&d->filterMutex);
|
||||
d->filter = filter;
|
||||
}
|
||||
|
||||
#include "qgstreamerbushelper.moc"
|
||||
77
src/plugins/gstreamer/qgstreamerbushelper.h
Normal file
77
src/plugins/gstreamer/qgstreamerbushelper.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 QGSTREAMERBUSHELPER_H
|
||||
#define QGSTREAMERBUSHELPER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include <qgstreamermessage.h>
|
||||
#include <gst/gst.h>
|
||||
|
||||
class QGstreamerSyncEventFilter {
|
||||
public:
|
||||
//returns true if message was processed and should be dropped, false otherwise
|
||||
virtual bool processSyncMessage(const QGstreamerMessage &message) = 0;
|
||||
};
|
||||
|
||||
class QGstreamerBusHelperPrivate;
|
||||
|
||||
class QGstreamerBusHelper : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
friend class QGstreamerBusHelperPrivate;
|
||||
|
||||
public:
|
||||
QGstreamerBusHelper(GstBus* bus, QObject* parent = 0);
|
||||
~QGstreamerBusHelper();
|
||||
|
||||
void installSyncEventFilter(QGstreamerSyncEventFilter *filter);
|
||||
|
||||
signals:
|
||||
void message(QGstreamerMessage const& message);
|
||||
|
||||
|
||||
private:
|
||||
QGstreamerBusHelperPrivate* d;
|
||||
};
|
||||
|
||||
#endif
|
||||
578
src/plugins/gstreamer/qgstreamergltexturerenderer.cpp
Normal file
578
src/plugins/gstreamer/qgstreamergltexturerenderer.cpp
Normal file
@@ -0,0 +1,578 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "qvideosurfacegstsink.h"
|
||||
#include "qabstractvideosurface.h"
|
||||
#include "qgstutils.h"
|
||||
|
||||
#include <QtGui/qevent.h>
|
||||
#include <QtGui/qapplication.h>
|
||||
#include <QtGui/qx11info_x11.h>
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtCore/qthread.h>
|
||||
|
||||
#include <QtOpenGL/qgl.h>
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/interfaces/xoverlay.h>
|
||||
#include <gst/interfaces/propertyprobe.h>
|
||||
#include <gst/interfaces/meegovideotexture.h>
|
||||
#include <gst/interfaces/meegovideorenderswitch.h>
|
||||
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
|
||||
#include "qgstreamergltexturerenderer.h"
|
||||
|
||||
//#define GL_TEXTURE_SINK_DEBUG 1
|
||||
|
||||
//from extdefs.h
|
||||
typedef void *EGLSyncKHR;
|
||||
typedef khronos_utime_nanoseconds_t EGLTimeKHR;
|
||||
|
||||
#define GL_TEXTURE_EXTERNAL_OES 0x8D65
|
||||
#define EGL_SYNC_FENCE_KHR 0x30F9
|
||||
|
||||
typedef EGLSyncKHR (EGLAPIENTRYP _PFNEGLCREATESYNCKHRPROC) (EGLDisplay dpy,
|
||||
EGLenum type, const EGLint * attrib_list);
|
||||
typedef EGLBoolean (EGLAPIENTRYP _PFNEGLDESTROYSYNCKHRPROC) (EGLDisplay dpy,
|
||||
EGLSyncKHR sync);
|
||||
|
||||
|
||||
const QAbstractVideoBuffer::HandleType EGLImageTextureHandle =
|
||||
QAbstractVideoBuffer::HandleType(QAbstractVideoBuffer::UserHandle+3434);
|
||||
|
||||
// EGLSync functions
|
||||
_PFNEGLCREATESYNCKHRPROC eglCreateSyncKHR;
|
||||
_PFNEGLDESTROYSYNCKHRPROC eglDestroySyncKHR;
|
||||
|
||||
class QGStreamerGLTextureBuffer : public QAbstractVideoBuffer
|
||||
{
|
||||
public:
|
||||
QGStreamerGLTextureBuffer(MeegoGstVideoTexture *textureSink, int frameNumber) :
|
||||
QAbstractVideoBuffer(EGLImageTextureHandle),
|
||||
m_textureSink(MEEGO_GST_VIDEO_TEXTURE(textureSink)),
|
||||
m_frameNumber(frameNumber)
|
||||
{
|
||||
}
|
||||
|
||||
~QGStreamerGLTextureBuffer()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MapMode mapMode() const { return NotMapped; }
|
||||
uchar *map(MapMode mode, int *numBytes, int *bytesPerLine)
|
||||
{
|
||||
Q_UNUSED(mode);
|
||||
Q_UNUSED(numBytes);
|
||||
Q_UNUSED(bytesPerLine);
|
||||
|
||||
//acquire_frame should really be called at buffer construction time
|
||||
//but it conflicts with id-less implementation of gst texture sink.
|
||||
#if defined(GL_TEXTURE_SINK_DEBUG) && GL_TEXTURE_SINK_DEBUG > 1
|
||||
qDebug() << "acquire frame" << m_frameNumber;
|
||||
#endif
|
||||
if (!meego_gst_video_texture_acquire_frame(m_textureSink,m_frameNumber))
|
||||
qWarning() << Q_FUNC_INFO << "acquire-frame failed" << m_frameNumber;
|
||||
|
||||
|
||||
#if defined(GL_TEXTURE_SINK_DEBUG) && GL_TEXTURE_SINK_DEBUG > 1
|
||||
qDebug() << "map frame" << m_frameNumber;
|
||||
#endif
|
||||
|
||||
gboolean bind_status = meego_gst_video_texture_bind_frame(m_textureSink, GL_TEXTURE_EXTERNAL_OES, m_frameNumber);
|
||||
if (!bind_status)
|
||||
qWarning() << Q_FUNC_INFO << "bind-frame failed";
|
||||
|
||||
return (uchar*)1;
|
||||
}
|
||||
|
||||
void unmap()
|
||||
{
|
||||
gboolean bind_status = meego_gst_video_texture_bind_frame(m_textureSink, GL_TEXTURE_EXTERNAL_OES, -1);
|
||||
|
||||
#if defined(GL_TEXTURE_SINK_DEBUG) && GL_TEXTURE_SINK_DEBUG > 1
|
||||
qDebug() << "unmap frame" << m_frameNumber;
|
||||
#endif
|
||||
|
||||
if (!bind_status)
|
||||
qWarning() << Q_FUNC_INFO << "unbind-frame failed";
|
||||
|
||||
//release_frame should really be called in destructor
|
||||
//but this conflicts with id-less implementation of gst texture sink.
|
||||
#if defined(GL_TEXTURE_SINK_DEBUG) && GL_TEXTURE_SINK_DEBUG > 1
|
||||
qDebug() << "release frame" << m_frameNumber;
|
||||
#endif
|
||||
EGLSyncKHR sync = eglCreateSyncKHR(eglGetDisplay((EGLNativeDisplayType)QX11Info::display()), EGL_SYNC_FENCE_KHR, NULL);
|
||||
meego_gst_video_texture_release_frame(m_textureSink, m_frameNumber, sync);
|
||||
}
|
||||
|
||||
QVariant handle() const
|
||||
{
|
||||
return m_frameNumber;
|
||||
}
|
||||
|
||||
private:
|
||||
MeegoGstVideoTexture *m_textureSink;
|
||||
int m_frameNumber;
|
||||
};
|
||||
|
||||
|
||||
QGstreamerGLTextureRenderer::QGstreamerGLTextureRenderer(QObject *parent) :
|
||||
QVideoRendererControl(parent),
|
||||
m_videoSink(0),
|
||||
m_surface(0),
|
||||
m_context(0),
|
||||
m_winId(0),
|
||||
m_colorKey(49,0,49),
|
||||
m_overlayEnabled(false),
|
||||
m_bufferProbeId(-1)
|
||||
{
|
||||
eglCreateSyncKHR =
|
||||
(_PFNEGLCREATESYNCKHRPROC)eglGetProcAddress("eglCreateSyncKHR");
|
||||
eglDestroySyncKHR =
|
||||
(_PFNEGLDESTROYSYNCKHRPROC)eglGetProcAddress("eglDestroySyncKHR");
|
||||
}
|
||||
|
||||
QGstreamerGLTextureRenderer::~QGstreamerGLTextureRenderer()
|
||||
{
|
||||
if (m_surface && m_surface->isActive())
|
||||
m_surface->stop();
|
||||
|
||||
if (m_videoSink)
|
||||
gst_object_unref(GST_OBJECT(m_videoSink));
|
||||
}
|
||||
|
||||
GstElement *QGstreamerGLTextureRenderer::videoSink()
|
||||
{
|
||||
if (!m_videoSink && isReady()) {
|
||||
if (m_context && !m_surface->supportedPixelFormats(EGLImageTextureHandle).isEmpty()) {
|
||||
#ifdef GL_TEXTURE_SINK_DEBUG
|
||||
qDebug() << Q_FUNC_INFO << ": using gltexture sink";
|
||||
#endif
|
||||
if (m_context)
|
||||
m_context->makeCurrent();
|
||||
m_videoSink = gst_element_factory_make("gltexturesink", "egl-texture-sink");
|
||||
g_object_set(G_OBJECT(m_videoSink),
|
||||
"x-display", QX11Info::display(),
|
||||
"egl-display", eglGetDisplay((EGLNativeDisplayType)QX11Info::display()),
|
||||
"egl-context", eglGetCurrentContext(),
|
||||
"colorkey", m_colorKey.rgb(),
|
||||
"autopaint-colorkey", false,
|
||||
"use-framebuffer-memory", true,
|
||||
"render-mode", m_overlayEnabled ? VIDEO_RENDERSWITCH_XOVERLAY_MODE
|
||||
: VIDEO_RENDERSWITCH_TEXTURE_STREAMING_MODE,
|
||||
(char*)NULL);
|
||||
|
||||
g_signal_connect(G_OBJECT(m_videoSink), "frame-ready", G_CALLBACK(handleFrameReady), (gpointer)this);
|
||||
} else {
|
||||
qWarning() << Q_FUNC_INFO << ": Fallback to QVideoSurfaceGstSink since EGLImageTextureHandle is not supported";
|
||||
m_videoSink = reinterpret_cast<GstElement*>(QVideoSurfaceGstSink::createSink(m_surface));
|
||||
}
|
||||
|
||||
if (m_videoSink) {
|
||||
gst_object_ref(GST_OBJECT(m_videoSink)); //Take ownership
|
||||
gst_object_sink(GST_OBJECT(m_videoSink));
|
||||
|
||||
GstPad *pad = gst_element_get_static_pad(m_videoSink,"sink");
|
||||
m_bufferProbeId = gst_pad_add_buffer_probe(pad, G_CALLBACK(padBufferProbe), this);
|
||||
}
|
||||
}
|
||||
|
||||
return m_videoSink;
|
||||
}
|
||||
|
||||
QAbstractVideoSurface *QGstreamerGLTextureRenderer::surface() const
|
||||
{
|
||||
return m_surface;
|
||||
}
|
||||
|
||||
void QGstreamerGLTextureRenderer::setSurface(QAbstractVideoSurface *surface)
|
||||
{
|
||||
if (m_surface != surface) {
|
||||
#ifdef GL_TEXTURE_SINK_DEBUG
|
||||
qDebug() << Q_FUNC_INFO << surface;
|
||||
#endif
|
||||
|
||||
bool oldReady = isReady();
|
||||
|
||||
m_context = const_cast<QGLContext*>(QGLContext::currentContext());
|
||||
|
||||
if (m_videoSink)
|
||||
gst_object_unref(GST_OBJECT(m_videoSink));
|
||||
|
||||
m_videoSink = 0;
|
||||
|
||||
if (m_surface) {
|
||||
disconnect(m_surface, SIGNAL(supportedFormatsChanged()),
|
||||
this, SLOT(handleFormatChange()));
|
||||
}
|
||||
|
||||
m_surface = surface;
|
||||
|
||||
if (oldReady != isReady())
|
||||
emit readyChanged(!oldReady);
|
||||
|
||||
if (m_surface) {
|
||||
connect(m_surface, SIGNAL(supportedFormatsChanged()),
|
||||
this, SLOT(handleFormatChange()));
|
||||
}
|
||||
|
||||
emit sinkChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void QGstreamerGLTextureRenderer::handleFormatChange()
|
||||
{
|
||||
if (m_videoSink)
|
||||
gst_object_unref(GST_OBJECT(m_videoSink));
|
||||
|
||||
m_videoSink = 0;
|
||||
emit sinkChanged();
|
||||
}
|
||||
|
||||
void QGstreamerGLTextureRenderer::handleFrameReady(GstElement *sink, gint frame, gpointer data)
|
||||
{
|
||||
Q_UNUSED(sink);
|
||||
QGstreamerGLTextureRenderer* renderer = reinterpret_cast<QGstreamerGLTextureRenderer*>(data);
|
||||
|
||||
QMutexLocker locker(&renderer->m_mutex);
|
||||
QMetaObject::invokeMethod(renderer, "renderGLFrame",
|
||||
Qt::QueuedConnection,
|
||||
Q_ARG(int, frame));
|
||||
|
||||
//we have to wait to ensure the frame is not reused,
|
||||
//timeout is added to avoid deadlocks when the main thread is
|
||||
//waiting for rendering to complete, this is possible for example during state chages.
|
||||
//If frame is not rendered during 60ms (~1-2 frames interval) it's better to unblock and drop it if necessary
|
||||
renderer->m_renderCondition.wait(&renderer->m_mutex, 60);
|
||||
}
|
||||
|
||||
void QGstreamerGLTextureRenderer::renderGLFrame(int frame)
|
||||
{
|
||||
#if defined(GL_TEXTURE_SINK_DEBUG) && GL_TEXTURE_SINK_DEBUG > 1
|
||||
qDebug() << Q_FUNC_INFO << "frame:" << frame << "surface active:" << m_surface->isActive();
|
||||
#endif
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
if (!m_surface) {
|
||||
m_renderCondition.wakeAll();
|
||||
return;
|
||||
}
|
||||
|
||||
MeegoGstVideoTexture *textureSink = MEEGO_GST_VIDEO_TEXTURE(m_videoSink);
|
||||
|
||||
if (m_context)
|
||||
m_context->makeCurrent();
|
||||
|
||||
//don't try to render the frame if state is changed to NULL or READY
|
||||
GstState pendingState = GST_STATE_NULL;
|
||||
GstState newState = GST_STATE_NULL;
|
||||
GstStateChangeReturn res = gst_element_get_state(m_videoSink,
|
||||
&newState,
|
||||
&pendingState,
|
||||
0);//don't block and return immediately
|
||||
|
||||
if (res == GST_STATE_CHANGE_FAILURE ||
|
||||
newState == GST_STATE_NULL ||
|
||||
pendingState == GST_STATE_NULL) {
|
||||
stopRenderer();
|
||||
m_renderCondition.wakeAll();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_surface->isActive()) {
|
||||
//find the native video size
|
||||
GstPad *pad = gst_element_get_static_pad(m_videoSink,"sink");
|
||||
GstCaps *caps = gst_pad_get_negotiated_caps(pad);
|
||||
|
||||
if (caps) {
|
||||
QSize newNativeSize = QGstUtils::capsCorrectedResolution(caps);
|
||||
if (m_nativeSize != newNativeSize) {
|
||||
m_nativeSize = newNativeSize;
|
||||
emit nativeSizeChanged();
|
||||
}
|
||||
gst_caps_unref(caps);
|
||||
}
|
||||
|
||||
//start the surface...
|
||||
QVideoSurfaceFormat format(m_nativeSize, QVideoFrame::Format_RGB32, EGLImageTextureHandle);
|
||||
if (!m_surface->start(format)) {
|
||||
qWarning() << Q_FUNC_INFO << "failed to start video surface" << format;
|
||||
m_renderCondition.wakeAll();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QGStreamerGLTextureBuffer *buffer = new QGStreamerGLTextureBuffer(textureSink, frame);
|
||||
QVideoFrame videoFrame(buffer,
|
||||
m_surface->surfaceFormat().frameSize(),
|
||||
m_surface->surfaceFormat().pixelFormat());
|
||||
m_surface->present(videoFrame);
|
||||
m_renderCondition.wakeAll();
|
||||
}
|
||||
|
||||
bool QGstreamerGLTextureRenderer::isReady() const
|
||||
{
|
||||
if (!m_surface)
|
||||
return false;
|
||||
|
||||
if (m_winId > 0)
|
||||
return true;
|
||||
|
||||
//winId is required only for EGLImageTextureHandle compatible surfaces
|
||||
return m_surface->supportedPixelFormats(EGLImageTextureHandle).isEmpty();
|
||||
}
|
||||
|
||||
void QGstreamerGLTextureRenderer::handleBusMessage(GstMessage* gm)
|
||||
{
|
||||
#ifdef GL_TEXTURE_SINK_DEBUG
|
||||
qDebug() << Q_FUNC_INFO << GST_MESSAGE_TYPE_NAME(gm);
|
||||
#endif
|
||||
|
||||
if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_STATE_CHANGED) {
|
||||
GstState oldState;
|
||||
GstState newState;
|
||||
gst_message_parse_state_changed(gm, &oldState, &newState, 0);
|
||||
|
||||
#ifdef GL_TEXTURE_SINK_DEBUG
|
||||
qDebug() << Q_FUNC_INFO << "State changed:" << oldState << newState;
|
||||
#endif
|
||||
|
||||
if (newState == GST_STATE_READY || newState == GST_STATE_NULL) {
|
||||
stopRenderer();
|
||||
}
|
||||
|
||||
if (oldState == GST_STATE_READY && newState == GST_STATE_PAUSED) {
|
||||
updateNativeVideoSize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QGstreamerGLTextureRenderer::handleSyncMessage(GstMessage* gm)
|
||||
{
|
||||
#ifdef GL_TEXTURE_SINK_DEBUG
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
|
||||
if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT &&
|
||||
gst_structure_has_name(gm->structure, "prepare-xwindow-id"))
|
||||
precessNewStream();
|
||||
}
|
||||
|
||||
void QGstreamerGLTextureRenderer::precessNewStream()
|
||||
{
|
||||
if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) {
|
||||
GstXOverlay *overlay = GST_X_OVERLAY(m_videoSink);
|
||||
|
||||
gst_x_overlay_set_xwindow_id(overlay, m_winId);
|
||||
|
||||
if (!m_displayRect.isEmpty()) {
|
||||
gst_x_overlay_set_render_rectangle(overlay,
|
||||
m_displayRect.x(),
|
||||
m_displayRect.y(),
|
||||
m_displayRect.width(),
|
||||
m_displayRect.height());
|
||||
}
|
||||
|
||||
GstPad *pad = gst_element_get_static_pad(m_videoSink,"sink");
|
||||
m_bufferProbeId = gst_pad_add_buffer_probe(pad, G_CALLBACK(padBufferProbe), this);
|
||||
}
|
||||
}
|
||||
|
||||
void QGstreamerGLTextureRenderer::stopRenderer()
|
||||
{
|
||||
#ifdef GL_TEXTURE_SINK_DEBUG
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
|
||||
if (m_surface && m_surface->isActive())
|
||||
m_surface->stop();
|
||||
|
||||
if (!m_nativeSize.isEmpty()) {
|
||||
m_nativeSize = QSize();
|
||||
emit nativeSizeChanged();
|
||||
}
|
||||
}
|
||||
|
||||
bool QGstreamerGLTextureRenderer::overlayEnabled() const
|
||||
{
|
||||
return m_overlayEnabled;
|
||||
}
|
||||
|
||||
void QGstreamerGLTextureRenderer::setOverlayEnabled(bool enabled)
|
||||
{
|
||||
|
||||
if (m_videoSink && (m_overlayEnabled != enabled)) {
|
||||
qDebug() << Q_FUNC_INFO << enabled;
|
||||
g_object_set(G_OBJECT(m_videoSink),
|
||||
"render-mode",
|
||||
enabled ? VIDEO_RENDERSWITCH_XOVERLAY_MODE : VIDEO_RENDERSWITCH_TEXTURE_STREAMING_MODE,
|
||||
(char *)NULL);
|
||||
}
|
||||
|
||||
m_overlayEnabled = enabled;
|
||||
}
|
||||
|
||||
|
||||
WId QGstreamerGLTextureRenderer::winId() const
|
||||
{
|
||||
return m_winId;
|
||||
}
|
||||
|
||||
void QGstreamerGLTextureRenderer::setWinId(WId id)
|
||||
{
|
||||
#ifdef GL_TEXTURE_SINK_DEBUG
|
||||
qDebug() << Q_FUNC_INFO << id;
|
||||
#endif
|
||||
|
||||
if (m_winId == id)
|
||||
return;
|
||||
|
||||
bool oldReady = isReady();
|
||||
|
||||
m_winId = id;
|
||||
|
||||
if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) {
|
||||
//don't set winId in NULL state,
|
||||
//texture sink opens xvideo port on set_xwindow_id,
|
||||
//this fails if video resource is not granted by resource policy yet.
|
||||
//state is changed to READY/PAUSED/PLAYING only after resource is granted.
|
||||
GstState pendingState = GST_STATE_NULL;
|
||||
GstState newState = GST_STATE_NULL;
|
||||
GstStateChangeReturn res = gst_element_get_state(m_videoSink,
|
||||
&newState,
|
||||
&pendingState,
|
||||
0);//don't block and return immediately
|
||||
|
||||
if (res != GST_STATE_CHANGE_FAILURE &&
|
||||
newState != GST_STATE_NULL &&
|
||||
pendingState != GST_STATE_NULL)
|
||||
gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(m_videoSink), m_winId);
|
||||
}
|
||||
|
||||
if (oldReady != isReady())
|
||||
emit readyChanged(!oldReady);
|
||||
}
|
||||
|
||||
QRect QGstreamerGLTextureRenderer::overlayGeometry() const
|
||||
{
|
||||
return m_displayRect;
|
||||
}
|
||||
|
||||
void QGstreamerGLTextureRenderer::setOverlayGeometry(const QRect &geometry)
|
||||
{
|
||||
if (m_displayRect != geometry) {
|
||||
#ifdef GL_TEXTURE_SINK_DEBUG
|
||||
qDebug() << Q_FUNC_INFO << geometry;
|
||||
#endif
|
||||
m_displayRect = geometry;
|
||||
|
||||
if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) {
|
||||
if (m_displayRect.isEmpty())
|
||||
gst_x_overlay_set_render_rectangle(GST_X_OVERLAY(m_videoSink), -1, -1, -1, -1);
|
||||
else
|
||||
gst_x_overlay_set_render_rectangle(GST_X_OVERLAY(m_videoSink),
|
||||
m_displayRect.x(),
|
||||
m_displayRect.y(),
|
||||
m_displayRect.width(),
|
||||
m_displayRect.height());
|
||||
repaintOverlay();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QColor QGstreamerGLTextureRenderer::colorKey() const
|
||||
{
|
||||
return m_colorKey;
|
||||
}
|
||||
|
||||
void QGstreamerGLTextureRenderer::repaintOverlay()
|
||||
{
|
||||
if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) {
|
||||
//don't call gst_x_overlay_expose if the sink is in null state
|
||||
GstState state = GST_STATE_NULL;
|
||||
GstStateChangeReturn res = gst_element_get_state(m_videoSink, &state, NULL, 1000000);
|
||||
if (res != GST_STATE_CHANGE_FAILURE && state != GST_STATE_NULL) {
|
||||
gst_x_overlay_expose(GST_X_OVERLAY(m_videoSink));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QSize QGstreamerGLTextureRenderer::nativeSize() const
|
||||
{
|
||||
return m_nativeSize;
|
||||
}
|
||||
|
||||
gboolean QGstreamerGLTextureRenderer::padBufferProbe(GstPad *pad, GstBuffer *buffer, gpointer user_data)
|
||||
{
|
||||
QGstreamerGLTextureRenderer *control = reinterpret_cast<QGstreamerGLTextureRenderer*>(user_data);
|
||||
QMetaObject::invokeMethod(control, "updateNativeVideoSize", Qt::QueuedConnection);
|
||||
gst_pad_remove_buffer_probe(pad, control->m_bufferProbeId);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void QGstreamerGLTextureRenderer::updateNativeVideoSize()
|
||||
{
|
||||
const QSize oldSize = m_nativeSize;
|
||||
|
||||
if (m_videoSink) {
|
||||
//find video native size to update video widget size hint
|
||||
GstPad *pad = gst_element_get_static_pad(m_videoSink,"sink");
|
||||
GstCaps *caps = gst_pad_get_negotiated_caps(pad);
|
||||
|
||||
if (caps) {
|
||||
m_nativeSize = QGstUtils::capsCorrectedResolution(caps);
|
||||
gst_caps_unref(caps);
|
||||
}
|
||||
} else {
|
||||
m_nativeSize = QSize();
|
||||
}
|
||||
#ifdef GL_TEXTURE_SINK_DEBUG
|
||||
qDebug() << Q_FUNC_INFO << oldSize << m_nativeSize << m_videoSink;
|
||||
#endif
|
||||
|
||||
if (m_nativeSize != oldSize)
|
||||
emit nativeSizeChanged();
|
||||
}
|
||||
127
src/plugins/gstreamer/qgstreamergltexturerenderer.h
Normal file
127
src/plugins/gstreamer/qgstreamergltexturerenderer.h
Normal file
@@ -0,0 +1,127 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 QGSTREAMERGLTEXTURERENDERER_H
|
||||
#define QGSTREAMERGLTEXTURERENDERER_H
|
||||
|
||||
#include <qvideorenderercontrol.h>
|
||||
#include "qvideosurfacegstsink.h"
|
||||
|
||||
#include "qgstreamervideorendererinterface.h"
|
||||
#include <QtGui/qcolor.h>
|
||||
|
||||
#include <X11/extensions/Xv.h>
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class QGLContext;
|
||||
|
||||
class QGstreamerGLTextureRenderer : public QVideoRendererControl, public QGstreamerVideoRendererInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QGstreamerVideoRendererInterface)
|
||||
|
||||
Q_PROPERTY(bool overlayEnabled READ overlayEnabled WRITE setOverlayEnabled)
|
||||
Q_PROPERTY(qulonglong winId READ winId WRITE setWinId)
|
||||
Q_PROPERTY(QRect overlayGeometry READ overlayGeometry WRITE setOverlayGeometry)
|
||||
Q_PROPERTY(QColor colorKey READ colorKey)
|
||||
Q_PROPERTY(QSize nativeSize READ nativeSize NOTIFY nativeSizeChanged)
|
||||
|
||||
public:
|
||||
QGstreamerGLTextureRenderer(QObject *parent = 0);
|
||||
virtual ~QGstreamerGLTextureRenderer();
|
||||
|
||||
QAbstractVideoSurface *surface() const;
|
||||
void setSurface(QAbstractVideoSurface *surface);
|
||||
|
||||
GstElement *videoSink();
|
||||
|
||||
bool isReady() const;
|
||||
void handleBusMessage(GstMessage* gm);
|
||||
void handleSyncMessage(GstMessage* gm);
|
||||
void precessNewStream();
|
||||
void stopRenderer();
|
||||
|
||||
int framebufferNumber() const;
|
||||
|
||||
bool overlayEnabled() const;
|
||||
WId winId() const;
|
||||
QRect overlayGeometry() const;
|
||||
QColor colorKey() const;
|
||||
QSize nativeSize() const;
|
||||
|
||||
public slots:
|
||||
void renderGLFrame(int);
|
||||
|
||||
void setOverlayEnabled(bool);
|
||||
void setWinId(WId id);
|
||||
void setOverlayGeometry(const QRect &geometry);
|
||||
void repaintOverlay();
|
||||
|
||||
signals:
|
||||
void sinkChanged();
|
||||
void readyChanged(bool);
|
||||
void nativeSizeChanged();
|
||||
|
||||
private slots:
|
||||
void handleFormatChange();
|
||||
void updateNativeVideoSize();
|
||||
|
||||
private:
|
||||
static void handleFrameReady(GstElement *sink, gint frame, gpointer data);
|
||||
static gboolean padBufferProbe(GstPad *pad, GstBuffer *buffer, gpointer user_data);
|
||||
|
||||
GstElement *m_videoSink;
|
||||
QAbstractVideoSurface *m_surface;
|
||||
QGLContext *m_context;
|
||||
QSize m_nativeSize;
|
||||
|
||||
WId m_winId;
|
||||
QColor m_colorKey;
|
||||
QRect m_displayRect;
|
||||
bool m_overlayEnabled;
|
||||
int m_bufferProbeId;
|
||||
|
||||
QMutex m_mutex;
|
||||
QWaitCondition m_renderCondition;
|
||||
};
|
||||
|
||||
#endif // QGSTREAMERVIDEORENDRER_H
|
||||
93
src/plugins/gstreamer/qgstreamermessage.cpp
Normal file
93
src/plugins/gstreamer/qgstreamermessage.cpp
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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "qgstreamermessage.h"
|
||||
|
||||
|
||||
static int wuchi = qRegisterMetaType<QGstreamerMessage>();
|
||||
|
||||
|
||||
/*!
|
||||
\class gstreamer::QGstreamerMessage
|
||||
\internal
|
||||
*/
|
||||
|
||||
QGstreamerMessage::QGstreamerMessage():
|
||||
m_message(0)
|
||||
{
|
||||
}
|
||||
|
||||
QGstreamerMessage::QGstreamerMessage(GstMessage* message):
|
||||
m_message(message)
|
||||
{
|
||||
gst_message_ref(m_message);
|
||||
}
|
||||
|
||||
QGstreamerMessage::QGstreamerMessage(QGstreamerMessage const& m):
|
||||
m_message(m.m_message)
|
||||
{
|
||||
gst_message_ref(m_message);
|
||||
}
|
||||
|
||||
|
||||
QGstreamerMessage::~QGstreamerMessage()
|
||||
{
|
||||
if (m_message != 0)
|
||||
gst_message_unref(m_message);
|
||||
}
|
||||
|
||||
GstMessage* QGstreamerMessage::rawMessage() const
|
||||
{
|
||||
return m_message;
|
||||
}
|
||||
|
||||
QGstreamerMessage& QGstreamerMessage::operator=(QGstreamerMessage const& rhs)
|
||||
{
|
||||
if (m_message != 0)
|
||||
gst_message_unref(m_message);
|
||||
|
||||
if ((m_message = rhs.m_message) != 0)
|
||||
gst_message_ref(m_message);
|
||||
|
||||
return *this;
|
||||
}
|
||||
68
src/plugins/gstreamer/qgstreamermessage.h
Normal file
68
src/plugins/gstreamer/qgstreamermessage.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 QGSTREAMERMESSAGE_H
|
||||
#define QGSTREAMERMESSAGE_H
|
||||
|
||||
#include <QMetaType>
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
|
||||
class QGstreamerMessage
|
||||
{
|
||||
public:
|
||||
QGstreamerMessage();
|
||||
QGstreamerMessage(GstMessage* message);
|
||||
QGstreamerMessage(QGstreamerMessage const& m);
|
||||
~QGstreamerMessage();
|
||||
|
||||
GstMessage* rawMessage() const;
|
||||
|
||||
QGstreamerMessage& operator=(QGstreamerMessage const& rhs);
|
||||
|
||||
private:
|
||||
GstMessage* m_message;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(QGstreamerMessage);
|
||||
|
||||
#endif
|
||||
401
src/plugins/gstreamer/qgstreamerserviceplugin.cpp
Normal file
401
src/plugins/gstreamer/qgstreamerserviceplugin.cpp
Normal file
@@ -0,0 +1,401 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 <QtGui/QIcon>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#include "qgstreamerserviceplugin.h"
|
||||
|
||||
//#define QT_SUPPORTEDMIMETYPES_DEBUG
|
||||
|
||||
#ifdef QMEDIA_GSTREAMER_PLAYER
|
||||
#include "qgstreamerplayerservice.h"
|
||||
#endif
|
||||
|
||||
#if defined(QMEDIA_GSTREAMER_CAPTURE)
|
||||
#include "qgstreamercaptureservice.h"
|
||||
#endif
|
||||
|
||||
#ifdef QMEDIA_GSTREAMER_CAMERABIN
|
||||
#include "camerabinservice.h"
|
||||
#endif
|
||||
|
||||
#include <qmediaserviceprovider.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>
|
||||
|
||||
|
||||
QStringList QGstreamerServicePlugin::keys() const
|
||||
{
|
||||
return QStringList()
|
||||
#ifdef QMEDIA_GSTREAMER_PLAYER
|
||||
<< QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER)
|
||||
#endif
|
||||
|
||||
#ifdef QMEDIA_GSTREAMER_CAPTURE
|
||||
<< QLatin1String(Q_MEDIASERVICE_AUDIOSOURCE)
|
||||
<< QLatin1String(Q_MEDIASERVICE_CAMERA)
|
||||
#elif defined(QMEDIA_GSTREAMER_CAMERABIN)
|
||||
<< QLatin1String(Q_MEDIASERVICE_CAMERA)
|
||||
#endif
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
QMediaService* QGstreamerServicePlugin::create(const QString &key)
|
||||
{
|
||||
static bool initialized = false;
|
||||
if (!initialized) {
|
||||
initialized = true;
|
||||
gst_init(NULL, NULL);
|
||||
}
|
||||
|
||||
#ifdef QMEDIA_GSTREAMER_PLAYER
|
||||
if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER))
|
||||
return new QGstreamerPlayerService;
|
||||
#endif
|
||||
|
||||
#ifdef QMEDIA_GSTREAMER_CAMERABIN
|
||||
if (key == QLatin1String(Q_MEDIASERVICE_CAMERA) && CameraBinService::isCameraBinAvailable())
|
||||
return new CameraBinService(key);
|
||||
#endif
|
||||
|
||||
#ifdef QMEDIA_GSTREAMER_CAPTURE
|
||||
if (key == QLatin1String(Q_MEDIASERVICE_AUDIOSOURCE))
|
||||
return new QGstreamerCaptureService(key);
|
||||
|
||||
if (key == QLatin1String(Q_MEDIASERVICE_CAMERA))
|
||||
return new QGstreamerCaptureService(key);
|
||||
#endif
|
||||
|
||||
qWarning() << "Gstreamer service plugin: unsupported key:" << key;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void QGstreamerServicePlugin::release(QMediaService *service)
|
||||
{
|
||||
delete service;
|
||||
}
|
||||
|
||||
QMediaServiceProviderHint::Features QGstreamerServicePlugin::supportedFeatures(
|
||||
const QByteArray &service) const
|
||||
{
|
||||
if (service == Q_MEDIASERVICE_MEDIAPLAYER)
|
||||
return QMediaServiceProviderHint::StreamPlayback | QMediaServiceProviderHint::VideoSurface;
|
||||
else if (service == Q_MEDIASERVICE_CAMERA)
|
||||
return QMediaServiceProviderHint::VideoSurface;
|
||||
else
|
||||
return QMediaServiceProviderHint::Features();
|
||||
}
|
||||
|
||||
QList<QByteArray> QGstreamerServicePlugin::devices(const QByteArray &service) const
|
||||
{
|
||||
if (service == Q_MEDIASERVICE_CAMERA) {
|
||||
if (m_cameraDevices.isEmpty())
|
||||
updateDevices();
|
||||
|
||||
return m_cameraDevices;
|
||||
}
|
||||
|
||||
return QList<QByteArray>();
|
||||
}
|
||||
|
||||
QString QGstreamerServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device)
|
||||
{
|
||||
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];
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
QVariant QGstreamerServicePlugin::deviceProperty(const QByteArray &service, const QByteArray &device, const QByteArray &property)
|
||||
{
|
||||
Q_UNUSED(service);
|
||||
Q_UNUSED(device);
|
||||
Q_UNUSED(property);
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void QGstreamerServicePlugin::updateDevices() const
|
||||
{
|
||||
m_cameraDevices.clear();
|
||||
m_cameraDescriptions.clear();
|
||||
|
||||
#ifdef Q_WS_MAEMO_5
|
||||
m_cameraDevices << "/dev/video0" << "/dev/video1";
|
||||
m_cameraDescriptions << tr("Main Camera") << tr("Front Camera");
|
||||
return;
|
||||
#endif
|
||||
|
||||
#ifdef Q_WS_MAEMO_6
|
||||
m_cameraDevices << "primary" << "secondary";
|
||||
m_cameraDescriptions << tr("Main camera") << tr("Front camera");
|
||||
return;
|
||||
#endif
|
||||
|
||||
QDir devDir("/dev");
|
||||
devDir.setFilter(QDir::System);
|
||||
|
||||
QFileInfoList entries = devDir.entryInfoList(QStringList() << "video*");
|
||||
|
||||
foreach( const QFileInfo &entryInfo, entries ) {
|
||||
//qDebug() << "Try" << entryInfo.filePath();
|
||||
|
||||
int fd = ::open(entryInfo.filePath().toLatin1().constData(), O_RDWR );
|
||||
if (fd == -1)
|
||||
continue;
|
||||
|
||||
bool isCamera = false;
|
||||
|
||||
v4l2_input input;
|
||||
memset(&input, 0, sizeof(input));
|
||||
for (; ::ioctl(fd, VIDIOC_ENUMINPUT, &input) >= 0; ++input.index) {
|
||||
if(input.type == V4L2_INPUT_TYPE_CAMERA || input.type == 0) {
|
||||
isCamera = ::ioctl(fd, VIDIOC_S_INPUT, input.index) != 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isCamera) {
|
||||
// find out its driver "name"
|
||||
QString name;
|
||||
struct v4l2_capability vcap;
|
||||
memset(&vcap, 0, sizeof(struct v4l2_capability));
|
||||
|
||||
if (ioctl(fd, VIDIOC_QUERYCAP, &vcap) != 0)
|
||||
name = entryInfo.fileName();
|
||||
else
|
||||
name = QString((const char*)vcap.card);
|
||||
//qDebug() << "found camera: " << name;
|
||||
|
||||
m_cameraDevices.append(entryInfo.filePath().toLocal8Bit());
|
||||
m_cameraDescriptions.append(name);
|
||||
}
|
||||
::close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
const char* getCodecAlias(const QString &codec)
|
||||
{
|
||||
if (codec.startsWith("avc1."))
|
||||
return "video/x-h264";
|
||||
|
||||
if (codec.startsWith("mp4a."))
|
||||
return "audio/mpeg4";
|
||||
|
||||
if (codec.startsWith("mp4v.20."))
|
||||
return "video/mpeg4";
|
||||
|
||||
if (codec == "samr")
|
||||
return "audio/amr";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* getMimeTypeAlias(const QString &mimeType)
|
||||
{
|
||||
if (mimeType == "video/mp4")
|
||||
return "video/mpeg4";
|
||||
|
||||
if (mimeType == "audio/mp4")
|
||||
return "audio/mpeg4";
|
||||
|
||||
if (mimeType == "video/ogg"
|
||||
|| mimeType == "audio/ogg")
|
||||
return "application/ogg";
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
QtMultimediaKit::SupportEstimate QGstreamerServicePlugin::hasSupport(const QString &mimeType,
|
||||
const QStringList& codecs) const
|
||||
{
|
||||
if (m_supportedMimeTypeSet.isEmpty())
|
||||
updateSupportedMimeTypes();
|
||||
|
||||
QString mimeTypeLowcase = mimeType.toLower();
|
||||
bool containsMimeType = m_supportedMimeTypeSet.contains(mimeTypeLowcase);
|
||||
if (!containsMimeType) {
|
||||
const char* mimeTypeAlias = getMimeTypeAlias(mimeTypeLowcase);
|
||||
containsMimeType = m_supportedMimeTypeSet.contains(mimeTypeAlias);
|
||||
if (!containsMimeType) {
|
||||
containsMimeType = m_supportedMimeTypeSet.contains("video/" + mimeTypeLowcase)
|
||||
|| m_supportedMimeTypeSet.contains("video/x-" + mimeTypeLowcase)
|
||||
|| m_supportedMimeTypeSet.contains("audio/" + mimeTypeLowcase)
|
||||
|| m_supportedMimeTypeSet.contains("audio/x-" + mimeTypeLowcase);
|
||||
}
|
||||
}
|
||||
|
||||
int supportedCodecCount = 0;
|
||||
foreach(const QString &codec, codecs) {
|
||||
QString codecLowcase = codec.toLower();
|
||||
const char* codecAlias = getCodecAlias(codecLowcase);
|
||||
if (codecAlias) {
|
||||
if (m_supportedMimeTypeSet.contains(codecAlias))
|
||||
supportedCodecCount++;
|
||||
} else if (m_supportedMimeTypeSet.contains("video/" + codecLowcase)
|
||||
|| m_supportedMimeTypeSet.contains("video/x-" + codecLowcase)
|
||||
|| m_supportedMimeTypeSet.contains("audio/" + codecLowcase)
|
||||
|| m_supportedMimeTypeSet.contains("audio/x-" + codecLowcase)) {
|
||||
supportedCodecCount++;
|
||||
}
|
||||
}
|
||||
if (supportedCodecCount > 0 && supportedCodecCount == codecs.size())
|
||||
return QtMultimediaKit::ProbablySupported;
|
||||
|
||||
if (supportedCodecCount == 0 && !containsMimeType)
|
||||
return QtMultimediaKit::NotSupported;
|
||||
|
||||
return QtMultimediaKit::MaybeSupported;
|
||||
}
|
||||
|
||||
void QGstreamerServicePlugin::updateSupportedMimeTypes() const
|
||||
{
|
||||
//enumerate supported mime types
|
||||
gst_init(NULL, NULL);
|
||||
|
||||
GList *plugins, *orig_plugins;
|
||||
orig_plugins = plugins = gst_default_registry_get_plugin_list ();
|
||||
|
||||
while (plugins) {
|
||||
GList *features, *orig_features;
|
||||
|
||||
GstPlugin *plugin = (GstPlugin *) (plugins->data);
|
||||
plugins = g_list_next (plugins);
|
||||
|
||||
if (plugin->flags & (1<<1)) //GST_PLUGIN_FLAG_BLACKLISTED
|
||||
continue;
|
||||
|
||||
orig_features = features = gst_registry_get_feature_list_by_plugin(gst_registry_get_default (),
|
||||
plugin->desc.name);
|
||||
while (features) {
|
||||
if (!G_UNLIKELY(features->data == NULL)) {
|
||||
GstPluginFeature *feature = GST_PLUGIN_FEATURE(features->data);
|
||||
if (GST_IS_ELEMENT_FACTORY (feature)) {
|
||||
GstElementFactory *factory = GST_ELEMENT_FACTORY(gst_plugin_feature_load(feature));
|
||||
if (factory
|
||||
&& factory->numpadtemplates > 0
|
||||
&& (qstrcmp(factory->details.klass, "Codec/Decoder/Audio") == 0
|
||||
|| qstrcmp(factory->details.klass, "Codec/Decoder/Video") == 0
|
||||
|| qstrcmp(factory->details.klass, "Codec/Demux") == 0 )) {
|
||||
const GList *pads = factory->staticpadtemplates;
|
||||
while (pads) {
|
||||
GstStaticPadTemplate *padtemplate = (GstStaticPadTemplate*)(pads->data);
|
||||
pads = g_list_next (pads);
|
||||
if (padtemplate->direction != GST_PAD_SINK)
|
||||
continue;
|
||||
if (padtemplate->static_caps.string) {
|
||||
GstCaps *caps = gst_static_caps_get(&padtemplate->static_caps);
|
||||
if (!gst_caps_is_any (caps) && ! gst_caps_is_empty (caps)) {
|
||||
for (guint i = 0; i < gst_caps_get_size(caps); i++) {
|
||||
GstStructure *structure = gst_caps_get_structure(caps, i);
|
||||
QString nameLowcase = QString(gst_structure_get_name (structure)).toLower();
|
||||
|
||||
m_supportedMimeTypeSet.insert(nameLowcase);
|
||||
if (nameLowcase.contains("mpeg")) {
|
||||
//Because mpeg version number is only included in the detail
|
||||
//description, it is necessary to manually extract this information
|
||||
//in order to match the mime type of mpeg4.
|
||||
const GValue *value = gst_structure_get_value(structure, "mpegversion");
|
||||
if (value) {
|
||||
gchar *str = gst_value_serialize (value);
|
||||
QString versions(str);
|
||||
QStringList elements = versions.split(QRegExp("\\D+"), QString::SkipEmptyParts);
|
||||
foreach(const QString &e, elements)
|
||||
m_supportedMimeTypeSet.insert(nameLowcase + e);
|
||||
g_free (str);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
gst_object_unref (factory);
|
||||
}
|
||||
} else if (GST_IS_TYPE_FIND_FACTORY(feature)) {
|
||||
QString name(gst_plugin_feature_get_name(feature));
|
||||
if (name.contains('/')) //filter out any string without '/' which is obviously not a mime type
|
||||
m_supportedMimeTypeSet.insert(name.toLower());
|
||||
}
|
||||
}
|
||||
features = g_list_next (features);
|
||||
}
|
||||
gst_plugin_feature_list_free (orig_features);
|
||||
}
|
||||
gst_plugin_list_free (orig_plugins);
|
||||
|
||||
#if defined QT_SUPPORTEDMIMETYPES_DEBUG
|
||||
QStringList list = m_supportedMimeTypeSet.toList();
|
||||
list.sort();
|
||||
if (qgetenv("QT_DEBUG_PLUGINS").toInt() > 0) {
|
||||
foreach(const QString &type, list)
|
||||
qDebug() << type;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
QStringList QGstreamerServicePlugin::supportedMimeTypes() const
|
||||
{
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
Q_EXPORT_PLUGIN2(qtmedia_gstengine, QGstreamerServicePlugin);
|
||||
86
src/plugins/gstreamer/qgstreamerserviceplugin.h
Normal file
86
src/plugins/gstreamer/qgstreamerserviceplugin.h
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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#ifndef QGSTREAMERSERVICEPLUGIN_H
|
||||
#define QGSTREAMERSERVICEPLUGIN_H
|
||||
|
||||
#include <qmediaserviceproviderplugin.h>
|
||||
#include <QtCore/qset.h>
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
|
||||
class QGstreamerServicePlugin
|
||||
: public QMediaServiceProviderPlugin
|
||||
, public QMediaServiceSupportedDevicesInterface
|
||||
, public QMediaServiceFeaturesInterface
|
||||
, public QMediaServiceSupportedFormatsInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
|
||||
Q_INTERFACES(QMediaServiceFeaturesInterface)
|
||||
Q_INTERFACES(QMediaServiceSupportedFormatsInterface)
|
||||
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);
|
||||
QVariant deviceProperty(const QByteArray &service, const QByteArray &device, const QByteArray &property);
|
||||
|
||||
QtMultimediaKit::SupportEstimate hasSupport(const QString &mimeType, const QStringList& codecs) const;
|
||||
QStringList supportedMimeTypes() const;
|
||||
|
||||
private:
|
||||
void updateDevices() const;
|
||||
|
||||
mutable QList<QByteArray> m_cameraDevices;
|
||||
mutable QStringList m_cameraDescriptions;
|
||||
mutable QSet<QString> m_supportedMimeTypeSet; //for fast access
|
||||
|
||||
void updateSupportedMimeTypes() const;
|
||||
};
|
||||
|
||||
#endif // QGSTREAMERSERVICEPLUGIN_H
|
||||
162
src/plugins/gstreamer/qgstreamervideoinputdevicecontrol.cpp
Normal file
162
src/plugins/gstreamer/qgstreamervideoinputdevicecontrol.cpp
Normal file
@@ -0,0 +1,162 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "qgstreamervideoinputdevicecontrol.h"
|
||||
|
||||
#include <QtGui/QIcon>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#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>
|
||||
|
||||
QGstreamerVideoInputDeviceControl::QGstreamerVideoInputDeviceControl(QObject *parent)
|
||||
:QVideoDeviceControl(parent), m_selectedDevice(0)
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
QGstreamerVideoInputDeviceControl::~QGstreamerVideoInputDeviceControl()
|
||||
{
|
||||
}
|
||||
|
||||
int QGstreamerVideoInputDeviceControl::deviceCount() const
|
||||
{
|
||||
return m_names.size();
|
||||
}
|
||||
|
||||
QString QGstreamerVideoInputDeviceControl::deviceName(int index) const
|
||||
{
|
||||
return m_names[index];
|
||||
}
|
||||
|
||||
QString QGstreamerVideoInputDeviceControl::deviceDescription(int index) const
|
||||
{
|
||||
return m_descriptions[index];
|
||||
}
|
||||
|
||||
QIcon QGstreamerVideoInputDeviceControl::deviceIcon(int index) const
|
||||
{
|
||||
Q_UNUSED(index);
|
||||
return QIcon();
|
||||
}
|
||||
|
||||
int QGstreamerVideoInputDeviceControl::defaultDevice() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int QGstreamerVideoInputDeviceControl::selectedDevice() const
|
||||
{
|
||||
return m_selectedDevice;
|
||||
}
|
||||
|
||||
|
||||
void QGstreamerVideoInputDeviceControl::setSelectedDevice(int index)
|
||||
{
|
||||
if (index != m_selectedDevice) {
|
||||
m_selectedDevice = index;
|
||||
emit selectedDeviceChanged(index);
|
||||
emit selectedDeviceChanged(deviceName(index));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void QGstreamerVideoInputDeviceControl::update()
|
||||
{
|
||||
m_names.clear();
|
||||
m_descriptions.clear();
|
||||
|
||||
#ifdef Q_WS_MAEMO_6
|
||||
m_names << QLatin1String("primary") << QLatin1String("secondary");
|
||||
m_descriptions << tr("Main camera") << tr("Front camera");
|
||||
#else
|
||||
QDir devDir("/dev");
|
||||
devDir.setFilter(QDir::System);
|
||||
|
||||
QFileInfoList entries = devDir.entryInfoList(QStringList() << "video*");
|
||||
|
||||
foreach( const QFileInfo &entryInfo, entries ) {
|
||||
//qDebug() << "Try" << entryInfo.filePath();
|
||||
|
||||
int fd = ::open(entryInfo.filePath().toLatin1().constData(), O_RDWR );
|
||||
if (fd == -1)
|
||||
continue;
|
||||
|
||||
bool isCamera = false;
|
||||
|
||||
v4l2_input input;
|
||||
memset(&input, 0, sizeof(input));
|
||||
for (; ::ioctl(fd, VIDIOC_ENUMINPUT, &input) >= 0; ++input.index) {
|
||||
if(input.type == V4L2_INPUT_TYPE_CAMERA || input.type == 0) {
|
||||
isCamera = ::ioctl(fd, VIDIOC_S_INPUT, input.index) != 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isCamera) {
|
||||
// find out its driver "name"
|
||||
QString name;
|
||||
struct v4l2_capability vcap;
|
||||
memset(&vcap, 0, sizeof(struct v4l2_capability));
|
||||
|
||||
if (ioctl(fd, VIDIOC_QUERYCAP, &vcap) != 0)
|
||||
name = entryInfo.fileName();
|
||||
else
|
||||
name = QString((const char*)vcap.card);
|
||||
//qDebug() << "found camera: " << name;
|
||||
|
||||
m_names.append(entryInfo.filePath());
|
||||
m_descriptions.append(name);
|
||||
}
|
||||
::close(fd);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
77
src/plugins/gstreamer/qgstreamervideoinputdevicecontrol.h
Normal file
77
src/plugins/gstreamer/qgstreamervideoinputdevicecontrol.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 QGSTREAMERVIDEOINPUTDEVICECONTROL_H
|
||||
#define QGSTREAMERVIDEOINPUTDEVICECONTROL_H
|
||||
|
||||
#include <qvideodevicecontrol.h>
|
||||
#include <QtCore/qstringlist.h>
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class QGstreamerVideoInputDeviceControl : public QVideoDeviceControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QGstreamerVideoInputDeviceControl(QObject *parent);
|
||||
~QGstreamerVideoInputDeviceControl();
|
||||
|
||||
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:
|
||||
void update();
|
||||
|
||||
int m_selectedDevice;
|
||||
QStringList m_names;
|
||||
QStringList m_descriptions;
|
||||
};
|
||||
|
||||
#endif // QGSTREAMERAUDIOINPUTDEVICECONTROL_H
|
||||
232
src/plugins/gstreamer/qgstreamervideooverlay.cpp
Normal file
232
src/plugins/gstreamer/qgstreamervideooverlay.cpp
Normal file
@@ -0,0 +1,232 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "qgstreamervideooverlay.h"
|
||||
#include "qvideosurfacegstsink.h"
|
||||
|
||||
#include <qvideosurfaceformat.h>
|
||||
|
||||
#include "qx11videosurface.h"
|
||||
|
||||
#ifndef QT_NO_XVIDEO
|
||||
|
||||
QGstreamerVideoOverlay::QGstreamerVideoOverlay(QObject *parent)
|
||||
: QVideoWindowControl(parent)
|
||||
, m_surface(new QX11VideoSurface)
|
||||
, m_videoSink(reinterpret_cast<GstElement*>(QVideoSurfaceGstSink::createSink(m_surface)))
|
||||
, m_aspectRatioMode(Qt::KeepAspectRatio)
|
||||
, m_fullScreen(false)
|
||||
{
|
||||
if (m_videoSink) {
|
||||
gst_object_ref(GST_OBJECT(m_videoSink)); //Take ownership
|
||||
gst_object_sink(GST_OBJECT(m_videoSink));
|
||||
}
|
||||
|
||||
connect(m_surface, SIGNAL(surfaceFormatChanged(QVideoSurfaceFormat)),
|
||||
this, SLOT(surfaceFormatChanged()));
|
||||
}
|
||||
|
||||
QGstreamerVideoOverlay::~QGstreamerVideoOverlay()
|
||||
{
|
||||
if (m_videoSink)
|
||||
gst_object_unref(GST_OBJECT(m_videoSink));
|
||||
|
||||
delete m_surface;
|
||||
}
|
||||
|
||||
WId QGstreamerVideoOverlay::winId() const
|
||||
{
|
||||
return m_surface->winId();
|
||||
}
|
||||
|
||||
void QGstreamerVideoOverlay::setWinId(WId id)
|
||||
{
|
||||
bool wasReady = isReady();
|
||||
m_surface->setWinId(id);
|
||||
|
||||
if (isReady() != wasReady)
|
||||
emit readyChanged(!wasReady);
|
||||
}
|
||||
|
||||
QRect QGstreamerVideoOverlay::displayRect() const
|
||||
{
|
||||
return m_displayRect;
|
||||
}
|
||||
|
||||
void QGstreamerVideoOverlay::setDisplayRect(const QRect &rect)
|
||||
{
|
||||
m_displayRect = rect;
|
||||
|
||||
setScaledDisplayRect();
|
||||
}
|
||||
|
||||
Qt::AspectRatioMode QGstreamerVideoOverlay::aspectRatioMode() const
|
||||
{
|
||||
return m_aspectRatioMode;
|
||||
}
|
||||
|
||||
void QGstreamerVideoOverlay::setAspectRatioMode(Qt::AspectRatioMode mode)
|
||||
{
|
||||
m_aspectRatioMode = mode;
|
||||
|
||||
setScaledDisplayRect();
|
||||
}
|
||||
|
||||
void QGstreamerVideoOverlay::repaint()
|
||||
{
|
||||
}
|
||||
|
||||
int QGstreamerVideoOverlay::brightness() const
|
||||
{
|
||||
return m_surface->brightness();
|
||||
}
|
||||
|
||||
void QGstreamerVideoOverlay::setBrightness(int brightness)
|
||||
{
|
||||
m_surface->setBrightness(brightness);
|
||||
|
||||
emit brightnessChanged(m_surface->brightness());
|
||||
}
|
||||
|
||||
int QGstreamerVideoOverlay::contrast() const
|
||||
{
|
||||
return m_surface->contrast();
|
||||
}
|
||||
|
||||
void QGstreamerVideoOverlay::setContrast(int contrast)
|
||||
{
|
||||
m_surface->setContrast(contrast);
|
||||
|
||||
emit contrastChanged(m_surface->contrast());
|
||||
}
|
||||
|
||||
int QGstreamerVideoOverlay::hue() const
|
||||
{
|
||||
return m_surface->hue();
|
||||
}
|
||||
|
||||
void QGstreamerVideoOverlay::setHue(int hue)
|
||||
{
|
||||
m_surface->setHue(hue);
|
||||
|
||||
emit hueChanged(m_surface->hue());
|
||||
}
|
||||
|
||||
int QGstreamerVideoOverlay::saturation() const
|
||||
{
|
||||
return m_surface->saturation();
|
||||
}
|
||||
|
||||
void QGstreamerVideoOverlay::setSaturation(int saturation)
|
||||
{
|
||||
m_surface->setSaturation(saturation);
|
||||
|
||||
emit saturationChanged(m_surface->saturation());
|
||||
}
|
||||
|
||||
bool QGstreamerVideoOverlay::isFullScreen() const
|
||||
{
|
||||
return m_fullScreen;
|
||||
}
|
||||
|
||||
void QGstreamerVideoOverlay::setFullScreen(bool fullScreen)
|
||||
{
|
||||
emit fullScreenChanged(m_fullScreen = fullScreen);
|
||||
}
|
||||
|
||||
QSize QGstreamerVideoOverlay::nativeSize() const
|
||||
{
|
||||
return m_surface->surfaceFormat().sizeHint();
|
||||
}
|
||||
|
||||
QAbstractVideoSurface *QGstreamerVideoOverlay::surface() const
|
||||
{
|
||||
return m_surface;
|
||||
}
|
||||
|
||||
GstElement *QGstreamerVideoOverlay::videoSink()
|
||||
{
|
||||
return m_videoSink;
|
||||
}
|
||||
|
||||
void QGstreamerVideoOverlay::surfaceFormatChanged()
|
||||
{
|
||||
setScaledDisplayRect();
|
||||
|
||||
emit nativeSizeChanged();
|
||||
}
|
||||
|
||||
void QGstreamerVideoOverlay::setScaledDisplayRect()
|
||||
{
|
||||
QRect formatViewport = m_surface->surfaceFormat().viewport();
|
||||
|
||||
switch (m_aspectRatioMode) {
|
||||
case Qt::KeepAspectRatio:
|
||||
{
|
||||
QSize size = m_surface->surfaceFormat().sizeHint();
|
||||
size.scale(m_displayRect.size(), Qt::KeepAspectRatio);
|
||||
|
||||
QRect rect(QPoint(0, 0), size);
|
||||
rect.moveCenter(m_displayRect.center());
|
||||
|
||||
m_surface->setDisplayRect(rect);
|
||||
m_surface->setViewport(formatViewport);
|
||||
}
|
||||
break;
|
||||
case Qt::IgnoreAspectRatio:
|
||||
m_surface->setDisplayRect(m_displayRect);
|
||||
m_surface->setViewport(formatViewport);
|
||||
break;
|
||||
case Qt::KeepAspectRatioByExpanding:
|
||||
{
|
||||
QSize size = m_displayRect.size();
|
||||
size.scale(m_surface->surfaceFormat().sizeHint(), Qt::KeepAspectRatio);
|
||||
|
||||
QRect viewport(QPoint(0, 0), size);
|
||||
viewport.moveCenter(formatViewport.center());
|
||||
m_surface->setDisplayRect(m_displayRect);
|
||||
m_surface->setViewport(viewport);
|
||||
}
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //QT_NO_XVIDEO
|
||||
119
src/plugins/gstreamer/qgstreamervideooverlay.h
Normal file
119
src/plugins/gstreamer/qgstreamervideooverlay.h
Normal file
@@ -0,0 +1,119 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 QGSTREAMERVIDEOOVERLAY_H
|
||||
#define QGSTREAMERVIDEOOVERLAY_H
|
||||
|
||||
#include <qvideowindowcontrol.h>
|
||||
|
||||
#include "qgstreamervideorendererinterface.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QAbstractVideoSurface;
|
||||
QT_END_NAMESPACE
|
||||
class QX11VideoSurface;
|
||||
|
||||
#if defined(Q_WS_X11) && !defined(QT_NO_XVIDEO)
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class QGstreamerVideoOverlay : public QVideoWindowControl, public QGstreamerVideoRendererInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QGstreamerVideoRendererInterface)
|
||||
public:
|
||||
QGstreamerVideoOverlay(QObject *parent = 0);
|
||||
~QGstreamerVideoOverlay();
|
||||
|
||||
WId winId() const;
|
||||
void setWinId(WId id);
|
||||
|
||||
QRect displayRect() const;
|
||||
void setDisplayRect(const QRect &rect);
|
||||
|
||||
bool isFullScreen() const;
|
||||
void setFullScreen(bool fullScreen);
|
||||
|
||||
QSize nativeSize() const;
|
||||
|
||||
Qt::AspectRatioMode aspectRatioMode() const;
|
||||
void setAspectRatioMode(Qt::AspectRatioMode mode);
|
||||
|
||||
void repaint();
|
||||
|
||||
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);
|
||||
|
||||
QAbstractVideoSurface *surface() const;
|
||||
|
||||
GstElement *videoSink();
|
||||
|
||||
bool isReady() const { return winId() != 0; }
|
||||
|
||||
signals:
|
||||
void sinkChanged();
|
||||
void readyChanged(bool);
|
||||
|
||||
private slots:
|
||||
void surfaceFormatChanged();
|
||||
|
||||
private:
|
||||
void setScaledDisplayRect();
|
||||
|
||||
QX11VideoSurface *m_surface;
|
||||
GstElement *m_videoSink;
|
||||
Qt::AspectRatioMode m_aspectRatioMode;
|
||||
QRect m_displayRect;
|
||||
bool m_fullScreen;
|
||||
};
|
||||
|
||||
#endif //QT_NO_XVIDEO
|
||||
|
||||
#endif
|
||||
120
src/plugins/gstreamer/qgstreamervideorenderer.cpp
Normal file
120
src/plugins/gstreamer/qgstreamervideorenderer.cpp
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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qgstreamervideorenderer.h"
|
||||
#include "qvideosurfacegstsink.h"
|
||||
#include "qabstractvideosurface.h"
|
||||
|
||||
#include <QEvent>
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
QGstreamerVideoRenderer::QGstreamerVideoRenderer(QObject *parent)
|
||||
:QVideoRendererControl(parent),m_videoSink(0), m_surface(0)
|
||||
{
|
||||
}
|
||||
|
||||
QGstreamerVideoRenderer::~QGstreamerVideoRenderer()
|
||||
{
|
||||
if (m_videoSink)
|
||||
gst_object_unref(GST_OBJECT(m_videoSink));
|
||||
}
|
||||
|
||||
GstElement *QGstreamerVideoRenderer::videoSink()
|
||||
{
|
||||
if (!m_videoSink && m_surface) {
|
||||
m_videoSink = QVideoSurfaceGstSink::createSink(m_surface);
|
||||
gst_object_ref(GST_OBJECT(m_videoSink)); //Take ownership
|
||||
gst_object_sink(GST_OBJECT(m_videoSink));
|
||||
}
|
||||
|
||||
return reinterpret_cast<GstElement*>(m_videoSink);
|
||||
}
|
||||
|
||||
|
||||
QAbstractVideoSurface *QGstreamerVideoRenderer::surface() const
|
||||
{
|
||||
return m_surface;
|
||||
}
|
||||
|
||||
void QGstreamerVideoRenderer::setSurface(QAbstractVideoSurface *surface)
|
||||
{
|
||||
if (m_surface != surface) {
|
||||
//qDebug() << Q_FUNC_INFO << surface;
|
||||
if (m_videoSink)
|
||||
gst_object_unref(GST_OBJECT(m_videoSink));
|
||||
|
||||
m_videoSink = 0;
|
||||
|
||||
if (m_surface) {
|
||||
disconnect(m_surface, SIGNAL(supportedFormatsChanged()),
|
||||
this, SLOT(handleFormatChange()));
|
||||
}
|
||||
|
||||
m_surface = surface;
|
||||
|
||||
if (surface && !m_surface)
|
||||
emit readyChanged(true);
|
||||
|
||||
if (!surface && m_surface)
|
||||
emit readyChanged(false);
|
||||
|
||||
if (m_surface) {
|
||||
connect(m_surface, SIGNAL(supportedFormatsChanged()),
|
||||
this, SLOT(handleFormatChange()));
|
||||
}
|
||||
|
||||
emit sinkChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void QGstreamerVideoRenderer::handleFormatChange()
|
||||
{
|
||||
//qDebug() << "Supported formats list has changed, reload video output";
|
||||
|
||||
if (m_videoSink)
|
||||
gst_object_unref(GST_OBJECT(m_videoSink));
|
||||
|
||||
m_videoSink = 0;
|
||||
emit sinkChanged();
|
||||
}
|
||||
80
src/plugins/gstreamer/qgstreamervideorenderer.h
Normal file
80
src/plugins/gstreamer/qgstreamervideorenderer.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 QGSTREAMERVIDEORENDERER_H
|
||||
#define QGSTREAMERVIDEORENDERER_H
|
||||
|
||||
#include <qvideorenderercontrol.h>
|
||||
#include "qvideosurfacegstsink.h"
|
||||
|
||||
#include "qgstreamervideorendererinterface.h"
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class QGstreamerVideoRenderer : public QVideoRendererControl, public QGstreamerVideoRendererInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QGstreamerVideoRendererInterface)
|
||||
public:
|
||||
QGstreamerVideoRenderer(QObject *parent = 0);
|
||||
virtual ~QGstreamerVideoRenderer();
|
||||
|
||||
QAbstractVideoSurface *surface() const;
|
||||
void setSurface(QAbstractVideoSurface *surface);
|
||||
|
||||
GstElement *videoSink();
|
||||
void precessNewStream() {}
|
||||
|
||||
bool isReady() const { return m_surface != 0; }
|
||||
|
||||
signals:
|
||||
void sinkChanged();
|
||||
void readyChanged(bool);
|
||||
|
||||
private slots:
|
||||
void handleFormatChange();
|
||||
|
||||
private:
|
||||
QVideoSurfaceGstSink *m_videoSink;
|
||||
QAbstractVideoSurface *m_surface;
|
||||
};
|
||||
|
||||
#endif // QGSTREAMERVIDEORENDRER_H
|
||||
46
src/plugins/gstreamer/qgstreamervideorendererinterface.cpp
Normal file
46
src/plugins/gstreamer/qgstreamervideorendererinterface.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "qgstreamervideorendererinterface.h"
|
||||
|
||||
QGstreamerVideoRendererInterface::~QGstreamerVideoRendererInterface()
|
||||
{
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user