diff options
Diffstat (limited to 'src/plugins/gstreamer')
52 files changed, 641 insertions, 5142 deletions
diff --git a/src/plugins/gstreamer/audiodecoder/audiodecoder.json b/src/plugins/gstreamer/audiodecoder/audiodecoder.json new file mode 100644 index 000000000..3cc81dc72 --- /dev/null +++ b/src/plugins/gstreamer/audiodecoder/audiodecoder.json @@ -0,0 +1,3 @@ +{ + "Keys": ["org.qt-project.qt.audiodecode"] +} diff --git a/src/plugins/gstreamer/audiodecoder/audiodecoder.pri b/src/plugins/gstreamer/audiodecoder/audiodecoder.pri deleted file mode 100644 index d2711e017..000000000 --- a/src/plugins/gstreamer/audiodecoder/audiodecoder.pri +++ /dev/null @@ -1,15 +0,0 @@ -INCLUDEPATH += $$PWD - -DEFINES += QMEDIA_GSTREAMER_AUDIO_DECODER - -HEADERS += \ - $$PWD/qgstreameraudiodecodercontrol.h \ - $$PWD/qgstreameraudiodecoderservice.h \ - $$PWD/qgstreameraudiodecodersession.h - -SOURCES += \ - $$PWD/qgstreameraudiodecodercontrol.cpp \ - $$PWD/qgstreameraudiodecoderservice.cpp \ - $$PWD/qgstreameraudiodecodersession.cpp - - diff --git a/src/plugins/gstreamer/audiodecoder/audiodecoder.pro b/src/plugins/gstreamer/audiodecoder/audiodecoder.pro new file mode 100644 index 000000000..a0dfcafec --- /dev/null +++ b/src/plugins/gstreamer/audiodecoder/audiodecoder.pro @@ -0,0 +1,30 @@ +load(qt_module) + +TARGET = gstaudiodecoder +PLUGIN_TYPE = mediaservice + +load(qt_plugin) +DESTDIR = $$QT.multimedia.plugins/$${PLUGIN_TYPE} + +include(../common.pri) + +INCLUDEPATH += $$PWD + +HEADERS += \ + $$PWD/qgstreameraudiodecodercontrol.h \ + $$PWD/qgstreameraudiodecoderservice.h \ + $$PWD/qgstreameraudiodecodersession.h \ + $$PWD/qgstreameraudiodecoderserviceplugin.h + +SOURCES += \ + $$PWD/qgstreameraudiodecodercontrol.cpp \ + $$PWD/qgstreameraudiodecoderservice.cpp \ + $$PWD/qgstreameraudiodecodersession.cpp \ + $$PWD/qgstreameraudiodecoderserviceplugin.cpp + +target.path += $$[QT_INSTALL_PLUGINS]/$${PLUGIN_TYPE} +INSTALLS += target + +OTHER_FILES += \ + audiodecoder.json + diff --git a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderserviceplugin.cpp b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderserviceplugin.cpp new file mode 100644 index 000000000..c52aee3a5 --- /dev/null +++ b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderserviceplugin.cpp @@ -0,0 +1,180 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgstreameraudiodecoderserviceplugin.h" + +#include "qgstreameraudiodecoderservice.h" +#include <private/qgstutils_p.h> + +#include <QtCore/qstring.h> +#include <QtCore/qdebug.h> +#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> +#include <gst/gst.h> + +// #define QT_SUPPORTEDMIMETYPES_DEBUG + +QMediaService* QGstreamerAudioDecoderServicePlugin::create(const QString &key) +{ + QGstUtils::initializeGst(); + + if (key == QLatin1String(Q_MEDIASERVICE_AUDIODECODER)) + return new QGstreamerAudioDecoderService; + + qWarning() << "Gstreamer audio decoder service plugin: unsupported key:" << key; + return 0; +} + +void QGstreamerAudioDecoderServicePlugin::release(QMediaService *service) +{ + delete service; +} + +QtMultimedia::SupportEstimate QGstreamerAudioDecoderServicePlugin::hasSupport(const QString &mimeType, + const QStringList &codecs) const +{ + if (m_supportedMimeTypeSet.isEmpty()) + updateSupportedMimeTypes(); + + return QGstUtils::hasSupport(mimeType, codecs, m_supportedMimeTypeSet); +} + +void QGstreamerAudioDecoderServicePlugin::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/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 QGstreamerAudioDecoderServicePlugin::supportedMimeTypes() const +{ + return QStringList(); +} + diff --git a/src/plugins/gstreamer/qgstreamervideoprobecontrol.h b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderserviceplugin.h index 499983bf0..d30adff55 100644 --- a/src/plugins/gstreamer/qgstreamervideoprobecontrol.h +++ b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderserviceplugin.h @@ -39,37 +39,36 @@ ** ****************************************************************************/ -#ifndef QGSTREAMERVIDEOPROBECONTROL_H -#define QGSTREAMERVIDEOPROBECONTROL_H +#ifndef QGSTREAMERAUDIODECODERSERVICEPLUGIN_H +#define QGSTREAMERAUDIODECODERSERVICEPLUGIN_H -#include <gst/gst.h> -#include <qmediavideoprobecontrol.h> -#include <QtCore/qmutex.h> -#include "qvideoframe.h" +#include <qmediaserviceproviderplugin.h> +#include <QtCore/qset.h> +#include <QtCore/QObject> QT_BEGIN_NAMESPACE -class QGstreamerVideoProbeControl : public QMediaVideoProbeControl +class QGstreamerAudioDecoderServicePlugin + : public QMediaServiceProviderPlugin + , public QMediaServiceSupportedFormatsInterface { Q_OBJECT -public: - explicit QGstreamerVideoProbeControl(QObject *parent); - virtual ~QGstreamerVideoProbeControl(); + Q_INTERFACES(QMediaServiceSupportedFormatsInterface) + Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "audiodecoder.json") - void bufferProbed(GstBuffer* buffer); - void startFlushing(); - void stopFlushing(); +public: + QMediaService* create(QString const& key); + void release(QMediaService *service); -private slots: - void frameProbed(); + QtMultimedia::SupportEstimate hasSupport(const QString &mimeType, const QStringList& codecs) const; + QStringList supportedMimeTypes() const; private: - bool m_flushing; - bool m_frameProbed; // true if at least one frame was probed - QVideoFrame m_pendingFrame; - QMutex m_frameMutex; + void updateSupportedMimeTypes() const; + + mutable QSet<QString> m_supportedMimeTypeSet; }; QT_END_NAMESPACE -#endif // QGSTREAMERVIDEOPROBECONTROL_H +#endif // QGSTREAMERAUDIODECODERSERVICEPLUGIN_H diff --git a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodersession.h b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodersession.h index 301123d13..9eec77bfd 100644 --- a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodersession.h +++ b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodersession.h @@ -49,7 +49,7 @@ #include "qaudiodecoder.h" #if defined(HAVE_GST_APPSRC) -#include "qgstappsrc.h" +#include <private/qgstappsrc_p.h> #endif #include <gst/gst.h> diff --git a/src/plugins/gstreamer/camerabin/camerabin.pri b/src/plugins/gstreamer/camerabin/camerabin.pro index 5c266e784..f79c625cd 100644 --- a/src/plugins/gstreamer/camerabin/camerabin.pri +++ b/src/plugins/gstreamer/camerabin/camerabin.pro @@ -1,10 +1,18 @@ +load(qt_module) + +TARGET = gstcamerabin +PLUGIN_TYPE = mediaservice + +load(qt_plugin) +DESTDIR = $$QT.multimedia.plugins/$${PLUGIN_TYPE} + +include(../common.pri) + 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 @@ -48,3 +56,15 @@ SOURCES += \ $$PWD/camerabinresourcepolicy.cpp \ $$PWD/camerabincapturedestination.cpp \ $$PWD/camerabincapturebufferformat.cpp + +maemo6 { + HEADERS += \ + $$PWD/camerabuttonlistener_meego.h + + SOURCES += \ + $$PWD/camerabuttonlistener_meego.cpp +} + +target.path += $$[QT_INSTALL_PLUGINS]/$${PLUGIN_TYPE} +INSTALLS += target + diff --git a/src/plugins/gstreamer/camerabuttonlistener_meego.cpp b/src/plugins/gstreamer/camerabin/camerabuttonlistener_meego.cpp index 026f49bc5..026f49bc5 100644 --- a/src/plugins/gstreamer/camerabuttonlistener_meego.cpp +++ b/src/plugins/gstreamer/camerabin/camerabuttonlistener_meego.cpp diff --git a/src/plugins/gstreamer/camerabuttonlistener_meego.h b/src/plugins/gstreamer/camerabin/camerabuttonlistener_meego.h index 01cc3894b..01cc3894b 100644 --- a/src/plugins/gstreamer/camerabuttonlistener_meego.h +++ b/src/plugins/gstreamer/camerabin/camerabuttonlistener_meego.h diff --git a/src/plugins/gstreamer/common.pri b/src/plugins/gstreamer/common.pri new file mode 100644 index 000000000..582b79a6c --- /dev/null +++ b/src/plugins/gstreamer/common.pri @@ -0,0 +1,39 @@ + +QT += multimedia-private network +CONFIG += no_private_qt_headers_warning + +!isEmpty(QT.widgets.name) { + QT += widgets multimediawidgets-private + DEFINES += HAVE_WIDGETS +} + +LIBS += -lqgsttools_p + +CONFIG += link_pkgconfig + +PKGCONFIG += \ + gstreamer-0.10 \ + gstreamer-base-0.10 \ + gstreamer-interfaces-0.10 \ + gstreamer-audio-0.10 \ + gstreamer-video-0.10 \ + gstreamer-pbutils-0.10 + +maemo*:PKGCONFIG +=gstreamer-plugins-bad-0.10 + +contains(config_test_resourcepolicy, yes) { + DEFINES += HAVE_RESOURCE_POLICY + PKGCONFIG += libresourceqt1 +} + +contains(config_test_xvideo, yes):!isEmpty(QT.widgets.name): { + DEFINES += HAVE_XVIDEO + LIBS += -lXv -lX11 -lXext +} + +contains(config_test_gstreamer_appsrc, yes) { + PKGCONFIG += gstreamer-app-0.10 + DEFINES += HAVE_GST_APPSRC + LIBS += -lgstapp-0.10 +} + diff --git a/src/plugins/gstreamer/gstreamer.pro b/src/plugins/gstreamer/gstreamer.pro index 073ef43ca..17f9e65e0 100644 --- a/src/plugins/gstreamer/gstreamer.pro +++ b/src/plugins/gstreamer/gstreamer.pro @@ -1,119 +1,14 @@ +TEMPLATE = subdirs -load(qt_module) +SUBDIRS += \ + audiodecoder \ + mediacapture \ + mediaplayer -TARGET = qgstengine -QT += multimedia-private network -CONFIG += no_private_qt_headers_warning - -!isEmpty(QT.widgets.name) { - QT += widgets multimediawidgets-private - DEFINES += HAVE_WIDGETS -} - -PLUGIN_TYPE=mediaservice - -load(qt_plugin) -DESTDIR = $$QT.multimedia.plugins/$${PLUGIN_TYPE} - -LIBS += -lqgsttools_p - -unix:!maemo*: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 \ - gstreamer-pbutils-0.10 - -maemo*:PKGCONFIG +=gstreamer-plugins-bad-0.10 - -contains(config_test_resourcepolicy, yes) { - DEFINES += HAVE_RESOURCE_POLICY - PKGCONFIG += libresourceqt1 -} - -maemo6 { - HEADERS += camerabuttonlistener_meego.h - SOURCES += camerabuttonlistener_meego.cpp - - PKGCONFIG += qmsystem2 - - contains(QT_CONFIG, opengles2):!isEmpty(QT.widgets.name) { - HEADERS += qgstreamergltexturerenderer.h - SOURCES += qgstreamergltexturerenderer.cpp - QT += opengl - LIBS += -lEGL -lgstmeegointerfaces-0.10 +# Camerabin2 based camera backend is untested and currently disabled +disabled { + contains(config_test_gstreamer_photography, yes) { + SUBDIRS += camerabin } } -HEADERS += \ - qgstreamervideorendererinterface.h \ - qgstreamerserviceplugin.h \ - qgstreameraudioinputendpointselector.h \ - qgstreamervideorenderer.h \ - qgstreamervideoinputdevicecontrol.h \ - gstvideoconnector.h \ - qgstcodecsinfo.h \ - qgstreamervideoprobecontrol.h \ - qgstreameraudioprobecontrol.h \ - -SOURCES += \ - qgstreamervideorendererinterface.cpp \ - qgstreamerserviceplugin.cpp \ - qgstreameraudioinputendpointselector.cpp \ - qgstreamervideorenderer.cpp \ - qgstreamervideoinputdevicecontrol.cpp \ - qgstcodecsinfo.cpp \ - gstvideoconnector.c \ - qgstreamervideoprobecontrol.cpp \ - qgstreameraudioprobecontrol.cpp \ - - -contains(config_test_xvideo, yes):!isEmpty(QT.widgets.name): { - DEFINES += HAVE_XVIDEO - - LIBS += -lXv -lX11 -lXext - - HEADERS += \ - qgstreamervideooverlay.h \ - qgstreamervideowindow.h \ - qgstreamervideowidget.h \ - qx11videosurface.h \ - - SOURCES += \ - qgstreamervideooverlay.cpp \ - qgstreamervideowindow.cpp \ - qgstreamervideowidget.cpp \ - qx11videosurface.cpp \ -} -include(mediaplayer/mediaplayer.pri) -include(mediacapture/mediacapture.pri) -include(audiodecoder/audiodecoder.pri) - -contains(config_test_gstreamer_appsrc, yes) { - PKGCONFIG += gstreamer-app-0.10 - HEADERS += $$PWD/qgstappsrc.h - SOURCES += $$PWD/qgstappsrc.cpp - - DEFINES += HAVE_GST_APPSRC - - LIBS += -lgstapp-0.10 -} - -OTHER_FILES += gstreamer.json - - -#Camerabin2 based camera backend is untested and currently disabled -#contains(config_test_gstreamer_photography, yes) { -# include(camerabin/camerabin.pri) -#} - -target.path += $$[QT_INSTALL_PLUGINS]/$${PLUGIN_TYPE} -INSTALLS += target diff --git a/src/plugins/gstreamer/gstvideoconnector.c b/src/plugins/gstreamer/gstvideoconnector.c deleted file mode 100644 index 9c8d1da7e..000000000 --- a/src/plugins/gstreamer/gstvideoconnector.c +++ /dev/null @@ -1,474 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "gstvideoconnector.h" -#include <unistd.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) -{ - (void) 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); -} - -// "When this function returns anything else than GST_FLOW_OK, -// the buffer allocation failed and buf does not contain valid data." -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; - - gboolean isFailed = FALSE; - while (1) { - GST_OBJECT_LOCK (element); - gst_object_ref(element->srcpad); - GST_OBJECT_UNLOCK (element); - - // Check if downstream element is in NULL state - // and wait for up to 1 second for it to switch. - GstPad *peerPad = gst_pad_get_peer(element->srcpad); - if (peerPad) { - GstElement *parent = gst_pad_get_parent_element(peerPad); - gst_object_unref (peerPad); - if (parent) { - GstState state; - GstState pending; - int totalTimeout = 0; - // This seems to sleep for about 10ms usually. - while (totalTimeout < 1000000) { - gst_element_get_state(parent, &state, &pending, 0); - if (state != GST_STATE_NULL) - break; - usleep(5000); - totalTimeout += 5000; - } - - gst_object_unref (parent); - if (state == GST_STATE_NULL) { - GST_DEBUG_OBJECT (element, "Downstream element is in NULL state"); - // Downstream filter seems to be in the wrong state - return GST_FLOW_UNEXPECTED; - } - } - } - - 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)); - - if (res == GST_FLOW_WRONG_STATE) { - // Just in case downstream filter is still somehow in the wrong state. - // Pipeline stalls if we report GST_FLOW_WRONG_STATE. - return GST_FLOW_UNEXPECTED; - } - - if (res >= GST_FLOW_OK || isFailed == TRUE) - break; - - //if gst_pad_alloc_buffer failed, emit "connection-failed" signal - //so colorspace transformation element can be inserted - GST_INFO_OBJECT(element, "gst_video_connector_buffer_alloc failed, emit connection-failed signal"); - g_signal_emit(G_OBJECT(element), gst_video_connector_signals[SIGNAL_CONNECTION_FAILED], 0); - isFailed = TRUE; - } - - 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 element 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) -{ - (void) pad; - (void) buffer; - - 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); -} diff --git a/src/plugins/gstreamer/gstvideoconnector.h b/src/plugins/gstreamer/gstvideoconnector.h deleted file mode 100644 index 1ac973f43..000000000 --- a/src/plugins/gstreamer/gstvideoconnector.h +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $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 - diff --git a/src/plugins/gstreamer/mediacapture/mediacapture.json b/src/plugins/gstreamer/mediacapture/mediacapture.json new file mode 100644 index 000000000..d963a2e3e --- /dev/null +++ b/src/plugins/gstreamer/mediacapture/mediacapture.json @@ -0,0 +1,3 @@ +{ + "Keys": ["org.qt-project.qt.audiosource"] +} diff --git a/src/plugins/gstreamer/mediacapture/mediacapture.pri b/src/plugins/gstreamer/mediacapture/mediacapture.pro index b7f7794f9..f0e984f46 100644 --- a/src/plugins/gstreamer/mediacapture/mediacapture.pri +++ b/src/plugins/gstreamer/mediacapture/mediacapture.pro @@ -1,6 +1,14 @@ -INCLUDEPATH += $$PWD +load(qt_module) + +TARGET = gstmediacapture +PLUGIN_TYPE = mediaservice + +load(qt_plugin) +DESTDIR = $$QT.multimedia.plugins/$${PLUGIN_TYPE} -DEFINES += QMEDIA_GSTREAMER_CAPTURE +include(../common.pri) + +INCLUDEPATH += $$PWD HEADERS += $$PWD/qgstreamercaptureservice.h \ $$PWD/qgstreamercapturesession.h \ @@ -12,7 +20,8 @@ HEADERS += $$PWD/qgstreamercaptureservice.h \ $$PWD/qgstreamerv4l2input.h \ $$PWD/qgstreamercapturemetadatacontrol.h \ $$PWD/qgstreamerimagecapturecontrol.h \ - $$PWD/qgstreamerimageencode.h + $$PWD/qgstreamerimageencode.h \ + $$PWD/qgstreamercaptureserviceplugin.h SOURCES += $$PWD/qgstreamercaptureservice.cpp \ $$PWD/qgstreamercapturesession.cpp \ @@ -24,4 +33,22 @@ SOURCES += $$PWD/qgstreamercaptureservice.cpp \ $$PWD/qgstreamerv4l2input.cpp \ $$PWD/qgstreamercapturemetadatacontrol.cpp \ $$PWD/qgstreamerimagecapturecontrol.cpp \ - $$PWD/qgstreamerimageencode.cpp + $$PWD/qgstreamerimageencode.cpp \ + $$PWD/qgstreamercaptureserviceplugin.cpp + +target.path += $$[QT_INSTALL_PLUGINS]/$${PLUGIN_TYPE} +INSTALLS += target + +# Camera usage with gstreamer needs to have +#CONFIG += use_gstreamer_camera + +use_gstreamer_camera { +DEFINES += USE_GSTREAMER_CAMERA + +OTHER_FILES += \ + mediacapturecamera.json +} else { +OTHER_FILES += \ + mediacapture.json +} + diff --git a/src/plugins/gstreamer/mediacapture/mediacapturecamera.json b/src/plugins/gstreamer/mediacapture/mediacapturecamera.json new file mode 100644 index 000000000..b31238363 --- /dev/null +++ b/src/plugins/gstreamer/mediacapture/mediacapturecamera.json @@ -0,0 +1,3 @@ +{ + "Keys": ["org.qt-project.qt.audiosource", "org.qt-project.qt.camera"] +} diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp b/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp index 405cc5778..bacc9c9ca 100644 --- a/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp +++ b/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp @@ -51,16 +51,16 @@ #include "qgstreamerv4l2input.h" #include "qgstreamercapturemetadatacontrol.h" -#include "qgstreameraudioinputendpointselector.h" -#include "qgstreamervideoinputdevicecontrol.h" #include "qgstreamerimagecapturecontrol.h" -#include "qgstreameraudioprobecontrol.h" +#include <private/qgstreameraudioinputendpointselector_p.h> +#include <private/qgstreamervideoinputdevicecontrol_p.h> +#include <private/qgstreameraudioprobecontrol_p.h> -#include "qgstreamervideorenderer.h" +#include <private/qgstreamervideorenderer_p.h> #if defined(HAVE_WIDGETS) -#include "qgstreamervideooverlay.h" -#include "qgstreamervideowidget.h" +#include <private/qgstreamervideooverlay_p.h> +#include <private/qgstreamervideowidget_p.h> #endif #include <qmediaserviceproviderplugin.h> diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.h b/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.h index 036d19ecb..80445e452 100644 --- a/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.h +++ b/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.h @@ -46,6 +46,7 @@ #include <qmediacontrol.h> #include <gst/gst.h> + QT_BEGIN_NAMESPACE class QAudioEndpointSelector; class QVideoDeviceControl; @@ -74,7 +75,7 @@ public: void releaseControl(QMediaControl *); private: - void setAudioPreview(GstElement*); + void setAudioPreview(GstElement *); QGstreamerCaptureSession *m_captureSession; QGstreamerCameraControl *m_cameraControl; diff --git a/src/plugins/gstreamer/qgstreamerserviceplugin.cpp b/src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.cpp index d9811d651..1dc2c4b33 100644 --- a/src/plugins/gstreamer/qgstreamerserviceplugin.cpp +++ b/src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.cpp @@ -44,27 +44,12 @@ #include <QtCore/QDir> #include <QtCore/QDebug> -#include "qgstreamerserviceplugin.h" +#include "qgstreamercaptureserviceplugin.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 - -#ifdef QMEDIA_GSTREAMER_AUDIO_DECODER -#include "qgstreameraudiodecoderservice.h" -#endif - -#include <qmediaserviceproviderplugin.h> +#include <private/qgstutils_p.h> #include <linux/types.h> #include <sys/time.h> @@ -77,60 +62,40 @@ #include <stdlib.h> #include <sys/mman.h> #include <linux/videodev2.h> +#include <gst/gst.h> - -QMediaService* QGstreamerServicePlugin::create(const QString &key) +QMediaService* QGstreamerCaptureServicePlugin::create(const QString &key) { - static bool initialized = false; - if (!initialized) { - initialized = true; - gst_init(NULL, NULL); - } + QGstUtils::initializeGst(); -#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_AUDIO_DECODER - if (key == QLatin1String(Q_MEDIASERVICE_AUDIODECODER)) - return new QGstreamerAudioDecoderService; -#endif - -#ifdef QMEDIA_GSTREAMER_CAPTURE if (key == QLatin1String(Q_MEDIASERVICE_AUDIOSOURCE)) return new QGstreamerCaptureService(key); +#if defined(USE_GSTREAMER_CAMERA) if (key == QLatin1String(Q_MEDIASERVICE_CAMERA)) return new QGstreamerCaptureService(key); #endif - qWarning() << "Gstreamer service plugin: unsupported key:" << key; + qWarning() << "Gstreamer capture service plugin: unsupported key:" << key; return 0; } -void QGstreamerServicePlugin::release(QMediaService *service) +void QGstreamerCaptureServicePlugin::release(QMediaService *service) { delete service; } -QMediaServiceProviderHint::Features QGstreamerServicePlugin::supportedFeatures( +#if defined(USE_GSTREAMER_CAMERA) +QMediaServiceProviderHint::Features QGstreamerCaptureServicePlugin::supportedFeatures( const QByteArray &service) const { - if (service == Q_MEDIASERVICE_MEDIAPLAYER) - return QMediaServiceProviderHint::StreamPlayback | QMediaServiceProviderHint::VideoSurface; - else if (service == Q_MEDIASERVICE_CAMERA) + if (service == Q_MEDIASERVICE_CAMERA) return QMediaServiceProviderHint::VideoSurface; - else - return QMediaServiceProviderHint::Features(); + + return QMediaServiceProviderHint::Features(); } -QList<QByteArray> QGstreamerServicePlugin::devices(const QByteArray &service) const +QList<QByteArray> QGstreamerCaptureServicePlugin::devices(const QByteArray &service) const { if (service == Q_MEDIASERVICE_CAMERA) { if (m_cameraDevices.isEmpty()) @@ -142,7 +107,7 @@ QList<QByteArray> QGstreamerServicePlugin::devices(const QByteArray &service) co return QList<QByteArray>(); } -QString QGstreamerServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device) +QString QGstreamerCaptureServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device) { if (service == Q_MEDIASERVICE_CAMERA) { if (m_cameraDevices.isEmpty()) @@ -156,7 +121,7 @@ QString QGstreamerServicePlugin::deviceDescription(const QByteArray &service, co return QString(); } -QVariant QGstreamerServicePlugin::deviceProperty(const QByteArray &service, const QByteArray &device, const QByteArray &property) +QVariant QGstreamerCaptureServicePlugin::deviceProperty(const QByteArray &service, const QByteArray &device, const QByteArray &property) { Q_UNUSED(service); Q_UNUSED(device); @@ -164,17 +129,11 @@ QVariant QGstreamerServicePlugin::deviceProperty(const QByteArray &service, cons return QVariant(); } -void QGstreamerServicePlugin::updateDevices() const +void QGstreamerCaptureServicePlugin::updateDevices() const { m_cameraDevices.clear(); m_cameraDescriptions.clear(); -#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); @@ -216,84 +175,18 @@ void QGstreamerServicePlugin::updateDevices() const ::close(fd); } } +#endif -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; - } -} - -QtMultimedia::SupportEstimate QGstreamerServicePlugin::hasSupport(const QString &mimeType, +QtMultimedia::SupportEstimate QGstreamerCaptureServicePlugin::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 QtMultimedia::ProbablySupported; - - if (supportedCodecCount == 0 && !containsMimeType) - return QtMultimedia::NotSupported; - - return QtMultimedia::MaybeSupported; + return QGstUtils::hasSupport(mimeType, codecs, m_supportedMimeTypeSet); } -void QGstreamerServicePlugin::updateSupportedMimeTypes() const +void QGstreamerCaptureServicePlugin::updateSupportedMimeTypes() const { //enumerate supported mime types gst_init(NULL, NULL); @@ -345,7 +238,7 @@ void QGstreamerServicePlugin::updateSupportedMimeTypes() const gchar *str = gst_value_serialize (value); QString versions(str); QStringList elements = versions.split(QRegExp("\\D+"), QString::SkipEmptyParts); - foreach(const QString &e, elements) + foreach (const QString &e, elements) m_supportedMimeTypeSet.insert(nameLowcase + e); g_free (str); } @@ -372,13 +265,13 @@ void QGstreamerServicePlugin::updateSupportedMimeTypes() const QStringList list = m_supportedMimeTypeSet.toList(); list.sort(); if (qgetenv("QT_DEBUG_PLUGINS").toInt() > 0) { - foreach(const QString &type, list) + foreach (const QString &type, list) qDebug() << type; } #endif } -QStringList QGstreamerServicePlugin::supportedMimeTypes() const +QStringList QGstreamerCaptureServicePlugin::supportedMimeTypes() const { return QStringList(); } diff --git a/src/plugins/gstreamer/qgstreamerserviceplugin.h b/src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.h index 96239a6da..8837e2e06 100644 --- a/src/plugins/gstreamer/qgstreamerserviceplugin.h +++ b/src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.h @@ -40,8 +40,8 @@ ****************************************************************************/ -#ifndef QGSTREAMERSERVICEPLUGIN_H -#define QGSTREAMERSERVICEPLUGIN_H +#ifndef QGSTREAMERCAPTURESERVICEPLUGIN_H +#define QGSTREAMERCAPTURESERVICEPLUGIN_H #include <qmediaserviceproviderplugin.h> #include <QtCore/qset.h> @@ -49,41 +49,52 @@ QT_BEGIN_NAMESPACE - -class QGstreamerServicePlugin +class QGstreamerCaptureServicePlugin : public QMediaServiceProviderPlugin +#if defined(USE_GSTREAMER_CAMERA) , public QMediaServiceSupportedDevicesInterface , public QMediaServiceFeaturesInterface +#endif , public QMediaServiceSupportedFormatsInterface { Q_OBJECT +#if defined(USE_GSTREAMER_CAMERA) Q_INTERFACES(QMediaServiceSupportedDevicesInterface) Q_INTERFACES(QMediaServiceFeaturesInterface) +#endif Q_INTERFACES(QMediaServiceSupportedFormatsInterface) - Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "gstreamer.json") +#if defined(USE_GSTREAMER_CAMERA) + Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "mediacapturecamera.json") +#else + Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "mediacapture.json") +#endif public: QMediaService* create(QString const& key); void release(QMediaService *service); +#if defined(USE_GSTREAMER_CAMERA) 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); +#endif QtMultimedia::SupportEstimate hasSupport(const QString &mimeType, const QStringList& codecs) const; QStringList supportedMimeTypes() const; private: +#if defined(USE_GSTREAMER_CAMERA) void updateDevices() const; mutable QList<QByteArray> m_cameraDevices; mutable QStringList m_cameraDescriptions; - mutable QSet<QString> m_supportedMimeTypeSet; //for fast access - +#endif void updateSupportedMimeTypes() const; + + mutable QSet<QString> m_supportedMimeTypeSet; //for fast access }; QT_END_NAMESPACE -#endif // QGSTREAMERSERVICEPLUGIN_H +#endif // QGSTREAMERCAPTURESERVICEPLUGIN_H diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp b/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp index 60cda07bc..56174c4c0 100644 --- a/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp +++ b/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp @@ -42,12 +42,12 @@ #include "qgstreamercapturesession.h" #include "qgstreamerrecordercontrol.h" #include "qgstreamermediacontainercontrol.h" -#include "qgstreamervideorendererinterface.h" #include "qgstreameraudioencode.h" #include "qgstreamervideoencode.h" #include "qgstreamerimageencode.h" -#include "qgstreameraudioprobecontrol.h" #include <qmediarecorder.h> +#include <private/qgstreamervideorendererinterface_p.h> +#include <private/qgstreameraudioprobecontrol_p.h> #include <private/qgstreamerbushelper_p.h> #include <gst/gsttagsetter.h> diff --git a/src/plugins/gstreamer/mediaplayer/mediaplayer.json b/src/plugins/gstreamer/mediaplayer/mediaplayer.json new file mode 100644 index 000000000..c4a27ea01 --- /dev/null +++ b/src/plugins/gstreamer/mediaplayer/mediaplayer.json @@ -0,0 +1,3 @@ +{ + "Keys": ["org.qt-project.qt.mediaplayer"] +} diff --git a/src/plugins/gstreamer/mediaplayer/mediaplayer.pri b/src/plugins/gstreamer/mediaplayer/mediaplayer.pro index 02551f731..82980b397 100644 --- a/src/plugins/gstreamer/mediaplayer/mediaplayer.pri +++ b/src/plugins/gstreamer/mediaplayer/mediaplayer.pro @@ -1,6 +1,14 @@ -INCLUDEPATH += $$PWD +load(qt_module) + +TARGET = gstmediaplayer +PLUGIN_TYPE = mediaservice + +load(qt_plugin) +DESTDIR = $$QT.multimedia.plugins/$${PLUGIN_TYPE} -DEFINES += QMEDIA_GSTREAMER_PLAYER +include(../common.pri) + +INCLUDEPATH += $$PWD HEADERS += \ $$PWD/qgstreamerplayercontrol.h \ @@ -8,7 +16,8 @@ HEADERS += \ $$PWD/qgstreamerplayersession.h \ $$PWD/qgstreamerstreamscontrol.h \ $$PWD/qgstreamermetadataprovider.h \ - $$PWD/qgstreameravailabilitycontrol.h + $$PWD/qgstreameravailabilitycontrol.h \ + $$PWD/qgstreamerplayerserviceplugin.h SOURCES += \ $$PWD/qgstreamerplayercontrol.cpp \ @@ -16,6 +25,12 @@ SOURCES += \ $$PWD/qgstreamerplayersession.cpp \ $$PWD/qgstreamerstreamscontrol.cpp \ $$PWD/qgstreamermetadataprovider.cpp \ - $$PWD/qgstreameravailabilitycontrol.cpp + $$PWD/qgstreameravailabilitycontrol.cpp \ + $$PWD/qgstreamerplayerserviceplugin.cpp + +target.path += $$[QT_INSTALL_PLUGINS]/$${PLUGIN_TYPE} +INSTALLS += target +OTHER_FILES += \ + mediaplayer.json diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayerservice.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamerplayerservice.cpp index 9a6b4b44b..fbd059fe1 100644 --- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayerservice.cpp +++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayerservice.cpp @@ -53,20 +53,20 @@ #include "qgstreameravailabilitycontrol.h" #if defined(HAVE_WIDGETS) -#include "qgstreamervideooverlay.h" -#include "qgstreamervideowindow.h" -#include "qgstreamervideowidget.h" +#include <private/qgstreamervideooverlay_p.h> +#include <private/qgstreamervideowindow_p.h> +#include <private/qgstreamervideowidget_p.h> #endif -#include "qgstreamervideorenderer.h" +#include <private/qgstreamervideorenderer_p.h> #if defined(Q_WS_MAEMO_6) && defined(__arm__) #include "qgstreamergltexturerenderer.h" #endif #include "qgstreamerstreamscontrol.h" -#include "qgstreameraudioprobecontrol.h" -#include "qgstreamervideoprobecontrol.h" +#include <private/qgstreameraudioprobecontrol_p.h> +#include <private/qgstreamervideoprobecontrol_p.h> #include <private/qmediaplaylistnavigator_p.h> #include <qmediaplaylist.h> diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayerserviceplugin.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamerplayerserviceplugin.cpp new file mode 100644 index 000000000..59a039f8d --- /dev/null +++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayerserviceplugin.cpp @@ -0,0 +1,191 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/qstring.h> +#include <QtCore/qdebug.h> +#include <QtCore/QDir> +#include <QtCore/QDebug> + +#include "qgstreamerplayerserviceplugin.h" + +//#define QT_SUPPORTEDMIMETYPES_DEBUG + +#include "qgstreamerplayerservice.h" +#include <private/qgstutils_p.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> +#include <gst/gst.h> + + +QMediaService* QGstreamerPlayerServicePlugin::create(const QString &key) +{ + QGstUtils::initializeGst(); + + if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER)) + return new QGstreamerPlayerService; + + qWarning() << "Gstreamer service plugin: unsupported key:" << key; + return 0; +} + +void QGstreamerPlayerServicePlugin::release(QMediaService *service) +{ + delete service; +} + +QMediaServiceProviderHint::Features QGstreamerPlayerServicePlugin::supportedFeatures( + const QByteArray &service) const +{ + if (service == Q_MEDIASERVICE_MEDIAPLAYER) + return QMediaServiceProviderHint::StreamPlayback | QMediaServiceProviderHint::VideoSurface; + else + return QMediaServiceProviderHint::Features(); +} + +QtMultimedia::SupportEstimate QGstreamerPlayerServicePlugin::hasSupport(const QString &mimeType, + const QStringList &codecs) const +{ + if (m_supportedMimeTypeSet.isEmpty()) + updateSupportedMimeTypes(); + + return QGstUtils::hasSupport(mimeType, codecs, m_supportedMimeTypeSet); +} + +void QGstreamerPlayerServicePlugin::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 QGstreamerPlayerServicePlugin::supportedMimeTypes() const +{ + return QStringList(); +} + diff --git a/src/plugins/gstreamer/qgstreameraudioprobecontrol.h b/src/plugins/gstreamer/mediaplayer/qgstreamerplayerserviceplugin.h index 90fc5840d..e19f31cda 100644 --- a/src/plugins/gstreamer/qgstreameraudioprobecontrol.h +++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayerserviceplugin.h @@ -39,33 +39,42 @@ ** ****************************************************************************/ -#ifndef QGSTREAMERAUDIOPROBECONTROL_H -#define QGSTREAMERAUDIOPROBECONTROL_H -#include <gst/gst.h> -#include <qmediaaudioprobecontrol.h> -#include <QtCore/qmutex.h> -#include "qaudiobuffer.h" +#ifndef QGSTREAMERPLAYERSERVICEPLUGIN_H +#define QGSTREAMERPLAYERSERVICEPLUGIN_H + +#include <qmediaserviceproviderplugin.h> +#include <QtCore/qset.h> +#include <QtCore/QObject> QT_BEGIN_NAMESPACE -class QGstreamerAudioProbeControl : public QMediaAudioProbeControl + +class QGstreamerPlayerServicePlugin + : public QMediaServiceProviderPlugin + , public QMediaServiceFeaturesInterface + , public QMediaServiceSupportedFormatsInterface { Q_OBJECT + Q_INTERFACES(QMediaServiceFeaturesInterface) + Q_INTERFACES(QMediaServiceSupportedFormatsInterface) + Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "mediaplayer.json") public: - explicit QGstreamerAudioProbeControl(QObject *parent); - virtual ~QGstreamerAudioProbeControl(); + QMediaService* create(QString const& key); + void release(QMediaService *service); - void bufferProbed(GstBuffer* buffer); + QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const; -private slots: - void bufferProbed(); + QtMultimedia::SupportEstimate hasSupport(const QString &mimeType, const QStringList& codecs) const; + QStringList supportedMimeTypes() const; private: - QAudioBuffer m_pendingBuffer; - QMutex m_bufferMutex; + void updateSupportedMimeTypes() const; + + mutable QSet<QString> m_supportedMimeTypeSet; //for fast access }; QT_END_NAMESPACE -#endif // QGSTREAMERAUDIOPROBECONTROL_H +#endif // QGSTREAMERPLAYERSERVICEPLUGIN_H + diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp index 7f48738cb..bd4d57d12 100644 --- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp +++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp @@ -42,10 +42,10 @@ #include "qgstreamerplayersession.h" #include <private/qgstreamerbushelper_p.h> -#include "qgstreameraudioprobecontrol.h" -#include "qgstreamervideoprobecontrol.h" -#include "qgstreamervideorendererinterface.h" -#include "gstvideoconnector.h" +#include <private/qgstreameraudioprobecontrol_p.h> +#include <private/qgstreamervideoprobecontrol_p.h> +#include <private/qgstreamervideorendererinterface_p.h> +#include <private/gstvideoconnector_p.h> #include <private/qgstutils_p.h> #include <private/playlistfileparser_p.h> diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h index 4bda52d85..c43be0bd7 100644 --- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h +++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h @@ -52,7 +52,7 @@ #include <qaudioformat.h> #if defined(HAVE_GST_APPSRC) -#include "qgstappsrc.h" +#include <private/qgstappsrc_p.h> #endif #include <gst/gst.h> diff --git a/src/plugins/gstreamer/qgstappsrc.cpp b/src/plugins/gstreamer/qgstappsrc.cpp deleted file mode 100644 index 7dfe95792..000000000 --- a/src/plugins/gstreamer/qgstappsrc.cpp +++ /dev/null @@ -1,231 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $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) -{ - m_callbacks.need_data = &QGstAppSrc::on_need_data; - m_callbacks.enough_data = &QGstAppSrc::on_enough_data; - m_callbacks.seek_data = &QGstAppSrc::on_seek_data; -} - -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); - 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"; - } - } - - // After reading we might be all done - if (m_stream->atEnd()) - sendEOS(); - } 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) -{ - Q_UNUSED(element); - 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) -{ - Q_UNUSED(element); - QGstAppSrc *self = reinterpret_cast<QGstAppSrc*>(userdata); - if (self) - self->enoughData() = true; -} - -void QGstAppSrc::on_need_data(GstAppSrc *element, guint arg0, gpointer userdata) -{ - Q_UNUSED(element); - 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(); -} diff --git a/src/plugins/gstreamer/qgstappsrc.h b/src/plugins/gstreamer/qgstappsrc.h deleted file mode 100644 index dc817e8f0..000000000 --- a/src/plugins/gstreamer/qgstappsrc.h +++ /dev/null @@ -1,106 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $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 diff --git a/src/plugins/gstreamer/qgstcodecsinfo.cpp b/src/plugins/gstreamer/qgstcodecsinfo.cpp deleted file mode 100644 index cf8ae2954..000000000 --- a/src/plugins/gstreamer/qgstcodecsinfo.cpp +++ /dev/null @@ -1,183 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgstcodecsinfo.h" - -#include <QtCore/qset.h> - -#ifdef QMEDIA_GSTREAMER_CAMERABIN -#include <gst/pbutils/pbutils.h> -#include <gst/pbutils/encoding-profile.h> -#endif - - -QGstCodecsInfo::QGstCodecsInfo(QGstCodecsInfo::ElementType elementType) -{ - -#if GST_CHECK_VERSION(0,10,31) - - GstElementFactoryListType gstElementType = 0; - switch (elementType) { - case AudioEncoder: - gstElementType = GST_ELEMENT_FACTORY_TYPE_AUDIO_ENCODER; - break; - case VideoEncoder: - gstElementType = GST_ELEMENT_FACTORY_TYPE_VIDEO_ENCODER; - break; - case Muxer: - gstElementType = GST_ELEMENT_FACTORY_TYPE_MUXER; - break; - } - - GstCaps *allCaps = supportedElementCaps(gstElementType); - GstCaps *caps = gst_caps_new_empty(); - - uint codecsCount = gst_caps_get_size(allCaps); - for (uint i=0; i<codecsCount; i++) { - gst_caps_append_structure(caps, gst_caps_steal_structure(allCaps, 0)); - gchar * capsString = gst_caps_to_string(caps); - - QString codec = QLatin1String(capsString); - m_codecs.append(codec); - -#ifdef QMEDIA_GSTREAMER_CAMERABIN - gchar *description = gst_pb_utils_get_codec_description(caps); - m_codecDescriptions.insert(codec, QString::fromUtf8(description)); - - if (description) - g_free(description); -#else - m_codecDescriptions.insert(codec, codec); -#endif - - if (capsString) - g_free(capsString); - - gst_caps_remove_structure(caps, 0); - } -#else - Q_UNUSED(elementType); -#endif // GST_CHECK_VERSION(0,10,31) -} - -QStringList QGstCodecsInfo::supportedCodecs() const -{ - return m_codecs; -} - -QString QGstCodecsInfo::codecDescription(const QString &codec) const -{ - return m_codecDescriptions.value(codec); -} - -#if GST_CHECK_VERSION(0,10,31) - -/*! - List all supported caps for all installed elements of type \a elementType. - - Caps are simplified to mime type and a few field necessary to distinguish - different codecs like mpegversion or layer. - */ -GstCaps* QGstCodecsInfo::supportedElementCaps(GstElementFactoryListType elementType, - GstRank minimumRank, - GstPadDirection padDirection) -{ - GList *elements = gst_element_factory_list_get_elements(elementType, minimumRank); - GstCaps *res = gst_caps_new_empty(); - - QSet<QByteArray> fakeEncoderMimeTypes; - fakeEncoderMimeTypes << "unknown/unknown" - << "audio/x-raw-int" << "audio/x-raw-float" - << "video/x-raw-yuv" << "video/x-raw-rgb"; - - QSet<QByteArray> fieldsToAdd; - fieldsToAdd << "mpegversion" << "layer" << "layout" << "raversion" - << "wmaversion" << "wmvversion" << "variant"; - - GList *element = elements; - while (element) { - GstElementFactory *factory = (GstElementFactory *)element->data; - element = element->next; - - const GList *padTemplates = gst_element_factory_get_static_pad_templates(factory); - while (padTemplates) { - GstStaticPadTemplate *padTemplate = (GstStaticPadTemplate *)padTemplates->data; - padTemplates = padTemplates->next; - - if (padTemplate->direction == padDirection) { - const GstCaps *caps = gst_static_caps_get(&padTemplate->static_caps); - for (uint i=0; i<gst_caps_get_size(caps); i++) { - const GstStructure *structure = gst_caps_get_structure(caps, i); - - //skip "fake" encoders - if (fakeEncoderMimeTypes.contains(gst_structure_get_name(structure))) - continue; - - GstStructure *newStructure = gst_structure_new(gst_structure_get_name(structure), NULL); - - //add structure fields to distinguish between formats with similar mime types, - //like audio/mpeg - for (int j=0; j<gst_structure_n_fields(structure); j++) { - const gchar* fieldName = gst_structure_nth_field_name(structure, j); - if (fieldsToAdd.contains(fieldName)) { - const GValue *value = gst_structure_get_value(structure, fieldName); - GType valueType = G_VALUE_TYPE(value); - - //don't add values of range type, - //gst_pb_utils_get_codec_description complains about not fixed caps - - if (valueType != GST_TYPE_INT_RANGE && valueType != GST_TYPE_DOUBLE_RANGE && - valueType != GST_TYPE_FRACTION_RANGE && valueType != GST_TYPE_LIST && - valueType != GST_TYPE_ARRAY) - gst_structure_set_value(newStructure, fieldName, value); - } - } - - gst_caps_merge_structure(res, newStructure); - } - } - } - } - gst_plugin_feature_list_free(elements); - - return res; -} -#endif //GST_CHECK_VERSION(0,10,31) diff --git a/src/plugins/gstreamer/qgstcodecsinfo.h b/src/plugins/gstreamer/qgstcodecsinfo.h deleted file mode 100644 index 58e843bcf..000000000 --- a/src/plugins/gstreamer/qgstcodecsinfo.h +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGSTCODECSINFO_H -#define QGSTCODECSINFO_H - -#include <QtCore/qmap.h> -#include <QtCore/qstringlist.h> - -#include <gst/gst.h> - -class QGstCodecsInfo -{ -public: - enum ElementType { AudioEncoder, VideoEncoder, Muxer }; - - QGstCodecsInfo(ElementType elementType); - - QStringList supportedCodecs() const; - QString codecDescription(const QString &codec) const; - -#if GST_CHECK_VERSION(0,10,31) - static GstCaps* supportedElementCaps(GstElementFactoryListType elementType, - GstRank minimumRank = GST_RANK_MARGINAL, - GstPadDirection padDirection = GST_PAD_SRC); -#endif - -private: - QStringList m_codecs; - QMap<QString,QString> m_codecDescriptions; -}; - - -#endif diff --git a/src/plugins/gstreamer/qgstreameraudioinputendpointselector.cpp b/src/plugins/gstreamer/qgstreameraudioinputendpointselector.cpp deleted file mode 100644 index cad931b3e..000000000 --- a/src/plugins/gstreamer/qgstreameraudioinputendpointselector.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgstreameraudioinputendpointselector.h" - -#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(); - updateAlsaDevices(); - updateOssDevices(); - 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); - 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())); - } -} - -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)); - } -} diff --git a/src/plugins/gstreamer/qgstreameraudioinputendpointselector.h b/src/plugins/gstreamer/qgstreameraudioinputendpointselector.h deleted file mode 100644 index 5d5bc715d..000000000 --- a/src/plugins/gstreamer/qgstreameraudioinputendpointselector.h +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGSTREAMERAUDIOINPUTENDPOINTSELECTOR_H -#define QGSTREAMERAUDIOINPUTENDPOINTSELECTOR_H - -#include <qaudioendpointselector.h> -#include <QtCore/qstringlist.h> - -QT_BEGIN_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; -}; - -QT_END_NAMESPACE - -#endif // QGSTREAMERAUDIOINPUTENDPOINTSELECTOR_H diff --git a/src/plugins/gstreamer/qgstreameraudioprobecontrol.cpp b/src/plugins/gstreamer/qgstreameraudioprobecontrol.cpp deleted file mode 100644 index d1f15d843..000000000 --- a/src/plugins/gstreamer/qgstreameraudioprobecontrol.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgstreameraudioprobecontrol.h" -#include <private/qgstutils_p.h> - -QGstreamerAudioProbeControl::QGstreamerAudioProbeControl(QObject *parent) - : QMediaAudioProbeControl(parent) -{ - -} - -QGstreamerAudioProbeControl::~QGstreamerAudioProbeControl() -{ - -} - -void QGstreamerAudioProbeControl::bufferProbed(GstBuffer* buffer) -{ - GstCaps* caps = gst_buffer_get_caps(buffer); - if (!caps) - return; - - QAudioFormat format = QGstUtils::audioFormatForCaps(caps); - gst_caps_unref(caps); - if (!format.isValid()) - return; - - QAudioBuffer audioBuffer = QAudioBuffer(QByteArray((const char*)buffer->data, buffer->size), format); - - { - QMutexLocker locker(&m_bufferMutex); - m_pendingBuffer = audioBuffer; - QMetaObject::invokeMethod(this, "bufferProbed", Qt::QueuedConnection); - } -} - -void QGstreamerAudioProbeControl::bufferProbed() -{ - QAudioBuffer audioBuffer; - { - QMutexLocker locker(&m_bufferMutex); - if (!m_pendingBuffer.isValid()) - return; - audioBuffer = m_pendingBuffer; - } - emit audioBufferProbed(audioBuffer); -} diff --git a/src/plugins/gstreamer/qgstreamergltexturerenderer.cpp b/src/plugins/gstreamer/qgstreamergltexturerenderer.cpp deleted file mode 100644 index be3c68b49..000000000 --- a/src/plugins/gstreamer/qgstreamergltexturerenderer.cpp +++ /dev/null @@ -1,583 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <private/qvideosurfacegstsink_p.h> -#include <qabstractvideosurface.h> -#include <private/qgstutils_p.h> - -#include <QtGui/qevent.h> -#include <QtWidgets/qapplication.h> -#include <QtWidgets/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(); -} - -bool QGstreamerGLTextureRenderer::processBusMessage(const QGstreamerMessage &message) -{ - GstMessage* gm = message.rawMessage(); - -#ifdef GL_TEXTURE_SINK_DEBUG - qDebug() << Q_FUNC_INFO << GST_MESSAGE_TYPE_NAME(gm); -#endif - - if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_STATE_CHANGED && - GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_videoSink)) { - 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(); - } - } - - return false; -} - -bool QGstreamerGLTextureRenderer::processSyncMessage(const QGstreamerMessage &message) -{ - GstMessage* gm = message.rawMessage(); - - if ((GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) && - gst_structure_has_name(gm->structure, "prepare-xwindow-id") && - m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) { -#ifdef GL_TEXTURE_SINK_DEBUG - qDebug() << Q_FUNC_INFO; -#endif - 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); - - return true; - } - - return false; -} - -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(); -} diff --git a/src/plugins/gstreamer/qgstreamergltexturerenderer.h b/src/plugins/gstreamer/qgstreamergltexturerenderer.h deleted file mode 100644 index b35964dfd..000000000 --- a/src/plugins/gstreamer/qgstreamergltexturerenderer.h +++ /dev/null @@ -1,132 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGSTREAMERGLTEXTURERENDERER_H -#define QGSTREAMERGLTEXTURERENDERER_H - -#include <qvideorenderercontrol.h> -#include <private/qvideosurfacegstsink_p.h> -#include <private/qgstreamerbushelper_p.h> - -#include "qgstreamervideorendererinterface.h" -#include <QtGui/qcolor.h> - -#include <X11/extensions/Xv.h> - -QT_BEGIN_NAMESPACE - -class QGLContext; - -class QGstreamerGLTextureRenderer : public QVideoRendererControl, - public QGstreamerVideoRendererInterface, - public QGstreamerSyncMessageFilter, - public QGstreamerBusMessageFilter -{ - Q_OBJECT - Q_INTERFACES(QGstreamerVideoRendererInterface QGstreamerSyncMessageFilter QGstreamerBusMessageFilter) - - 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; - bool processBusMessage(const QGstreamerMessage &message); - bool processSyncMessage(const QGstreamerMessage &message); - 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; -}; - -QT_END_NAMESPACE - -#endif // QGSTREAMERVIDEORENDRER_H diff --git a/src/plugins/gstreamer/qgstreamervideoinputdevicecontrol.cpp b/src/plugins/gstreamer/qgstreamervideoinputdevicecontrol.cpp deleted file mode 100644 index 3ffe728aa..000000000 --- a/src/plugins/gstreamer/qgstreamervideoinputdevicecontrol.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgstreamervideoinputdevicecontrol.h" - -#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]; -} - -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 -} diff --git a/src/plugins/gstreamer/qgstreamervideoinputdevicecontrol.h b/src/plugins/gstreamer/qgstreamervideoinputdevicecontrol.h deleted file mode 100644 index f51a9c82f..000000000 --- a/src/plugins/gstreamer/qgstreamervideoinputdevicecontrol.h +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGSTREAMERVIDEOINPUTDEVICECONTROL_H -#define QGSTREAMERVIDEOINPUTDEVICECONTROL_H - -#include <qvideodevicecontrol.h> -#include <QtCore/qstringlist.h> - -QT_BEGIN_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; - - 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; -}; - -QT_END_NAMESPACE - -#endif // QGSTREAMERAUDIOINPUTDEVICECONTROL_H diff --git a/src/plugins/gstreamer/qgstreamervideooverlay.cpp b/src/plugins/gstreamer/qgstreamervideooverlay.cpp deleted file mode 100644 index 8c3a4bfc9..000000000 --- a/src/plugins/gstreamer/qgstreamervideooverlay.cpp +++ /dev/null @@ -1,228 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgstreamervideooverlay.h" -#include <private/qvideosurfacegstsink_p.h> - -#include <qvideosurfaceformat.h> - -#include <qx11videosurface.h> - -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; - }; -} diff --git a/src/plugins/gstreamer/qgstreamervideooverlay.h b/src/plugins/gstreamer/qgstreamervideooverlay.h deleted file mode 100644 index 9e0fc40d4..000000000 --- a/src/plugins/gstreamer/qgstreamervideooverlay.h +++ /dev/null @@ -1,117 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $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; - -QT_BEGIN_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; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/gstreamer/qgstreamervideoprobecontrol.cpp b/src/plugins/gstreamer/qgstreamervideoprobecontrol.cpp deleted file mode 100644 index 6d586c4a4..000000000 --- a/src/plugins/gstreamer/qgstreamervideoprobecontrol.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgstreamervideoprobecontrol.h" -#include <private/qvideosurfacegstsink_p.h> -#include <private/qgstvideobuffer_p.h> - -QGstreamerVideoProbeControl::QGstreamerVideoProbeControl(QObject *parent) - : QMediaVideoProbeControl(parent) - , m_flushing(false) - , m_frameProbed(false) -{ - -} - -QGstreamerVideoProbeControl::~QGstreamerVideoProbeControl() -{ - -} - -void QGstreamerVideoProbeControl::startFlushing() -{ - m_flushing = true; - - { - QMutexLocker locker(&m_frameMutex); - m_pendingFrame = QVideoFrame(); - } - - // only emit flush if at least one frame was probed - if (m_frameProbed) - emit flush(); -} - -void QGstreamerVideoProbeControl::stopFlushing() -{ - m_flushing = false; -} - -void QGstreamerVideoProbeControl::bufferProbed(GstBuffer* buffer) -{ - if (m_flushing) - return; - - GstCaps* caps = gst_buffer_get_caps(buffer); - if (!caps) - return; - - int bytesPerLine = 0; - QVideoSurfaceFormat format = QVideoSurfaceGstSink::formatForCaps(caps, &bytesPerLine); - gst_caps_unref(caps); - if (!format.isValid() || !bytesPerLine) - return; - - QVideoFrame frame = QVideoFrame(new QGstVideoBuffer(buffer, bytesPerLine), - format.frameSize(), format.pixelFormat()); - - QVideoSurfaceGstSink::setFrameTimeStamps(&frame, buffer); - - m_frameProbed = true; - - { - QMutexLocker locker(&m_frameMutex); - m_pendingFrame = frame; - QMetaObject::invokeMethod(this, "frameProbed", Qt::QueuedConnection); - } -} - -void QGstreamerVideoProbeControl::frameProbed() -{ - QVideoFrame frame; - { - QMutexLocker locker(&m_frameMutex); - if (!m_pendingFrame.isValid()) - return; - frame = m_pendingFrame; - } - emit videoFrameProbed(frame); -} diff --git a/src/plugins/gstreamer/qgstreamervideorenderer.cpp b/src/plugins/gstreamer/qgstreamervideorenderer.cpp deleted file mode 100644 index d5ee93df4..000000000 --- a/src/plugins/gstreamer/qgstreamervideorenderer.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgstreamervideorenderer.h" -#include <private/qvideosurfacegstsink_p.h> -#include <qabstractvideosurface.h> - -#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())); - } - - bool wasReady = isReady(); - - m_surface = surface; - - if (m_surface) { - connect(m_surface, SIGNAL(supportedFormatsChanged()), - this, SLOT(handleFormatChange())); - } - - if (wasReady != isReady()) - emit readyChanged(isReady()); - - 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(); -} diff --git a/src/plugins/gstreamer/qgstreamervideorenderer.h b/src/plugins/gstreamer/qgstreamervideorenderer.h deleted file mode 100644 index b50139fd4..000000000 --- a/src/plugins/gstreamer/qgstreamervideorenderer.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGSTREAMERVIDEORENDERER_H -#define QGSTREAMERVIDEORENDERER_H - -#include <qvideorenderercontrol.h> -#include <private/qvideosurfacegstsink_p.h> - -#include "qgstreamervideorendererinterface.h" - -QT_BEGIN_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(); - - bool isReady() const { return m_surface != 0; } - -signals: - void sinkChanged(); - void readyChanged(bool); - -private slots: - void handleFormatChange(); - -private: - QVideoSurfaceGstSink *m_videoSink; - QAbstractVideoSurface *m_surface; -}; - -QT_END_NAMESPACE - -#endif // QGSTREAMERVIDEORENDRER_H diff --git a/src/plugins/gstreamer/qgstreamervideorendererinterface.cpp b/src/plugins/gstreamer/qgstreamervideorendererinterface.cpp deleted file mode 100644 index de3cd5bf8..000000000 --- a/src/plugins/gstreamer/qgstreamervideorendererinterface.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgstreamervideorendererinterface.h" - -QGstreamerVideoRendererInterface::~QGstreamerVideoRendererInterface() -{ -} diff --git a/src/plugins/gstreamer/qgstreamervideorendererinterface.h b/src/plugins/gstreamer/qgstreamervideorendererinterface.h deleted file mode 100644 index 42f6d5d5a..000000000 --- a/src/plugins/gstreamer/qgstreamervideorendererinterface.h +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGSTREAMERVIDEOOUTPUTCONTROL_H -#define QGSTREAMERVIDEOOUTPUTCONTROL_H - -#include <gst/gst.h> - -#include <QtCore/qobject.h> - -QT_BEGIN_NAMESPACE - -class QGstreamerVideoRendererInterface -{ -public: - virtual ~QGstreamerVideoRendererInterface(); - virtual GstElement *videoSink() = 0; - - //stopRenderer() is called when the renderer element is stopped. - //it can be reimplemented when video renderer can't detect - //changes to NULL state but has to free video resources. - virtual void stopRenderer() {} - - //the video output is configured, usually after the first paint event - //(winId is known, - virtual bool isReady() const { return true; } - - //signals: - //void sinkChanged(); - //void readyChanged(bool); -}; - -#define QGstreamerVideoRendererInterface_iid "org.qt-project.qt.gstreamervideorenderer/5.0" -Q_DECLARE_INTERFACE(QGstreamerVideoRendererInterface, QGstreamerVideoRendererInterface_iid) -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/gstreamer/qgstreamervideowidget.cpp b/src/plugins/gstreamer/qgstreamervideowidget.cpp deleted file mode 100644 index 118265102..000000000 --- a/src/plugins/gstreamer/qgstreamervideowidget.cpp +++ /dev/null @@ -1,352 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgstreamervideowidget.h" -#include <private/qgstutils_p.h> - -#include <QtCore/qcoreevent.h> -#include <QtCore/qdebug.h> -#include <QtWidgets/qapplication.h> -#include <QtGui/qpainter.h> - -#ifdef Q_WS_X11 -# include <X11/Xlib.h> -#endif -#include <gst/gst.h> -#include <gst/interfaces/xoverlay.h> -#include <gst/interfaces/propertyprobe.h> - -class QGstreamerVideoWidget : public QWidget -{ -public: - QGstreamerVideoWidget(QWidget *parent = 0) - :QWidget(parent) - { - setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - QPalette palette; - palette.setColor(QPalette::Background, Qt::black); - setPalette(palette); - } - - virtual ~QGstreamerVideoWidget() {} - - QSize sizeHint() const - { - return m_nativeSize; - } - - void setNativeSize( const QSize &size) - { - if (size != m_nativeSize) { - m_nativeSize = size; - if (size.isEmpty()) - setMinimumSize(0,0); - else - setMinimumSize(160,120); - - updateGeometry(); - } - } - -protected: - void paintEvent(QPaintEvent *) - { - QPainter painter(this); - painter.fillRect(rect(), palette().background()); - } - - QSize m_nativeSize; -}; - -QGstreamerVideoWidgetControl::QGstreamerVideoWidgetControl(QObject *parent) - : QVideoWidgetControl(parent) - , m_videoSink(0) - , m_widget(0) - , m_fullScreen(false) -{ -} - -QGstreamerVideoWidgetControl::~QGstreamerVideoWidgetControl() -{ - if (m_videoSink) - gst_object_unref(GST_OBJECT(m_videoSink)); - - delete m_widget; -} - -void QGstreamerVideoWidgetControl::createVideoWidget() -{ - if (m_widget) - return; - - m_widget = new QGstreamerVideoWidget; - - m_widget->installEventFilter(this); - m_windowId = m_widget->winId(); - - m_videoSink = gst_element_factory_make ("xvimagesink", NULL); - if (m_videoSink) { - // Check if the xv sink is usable - if (gst_element_set_state(m_videoSink, GST_STATE_READY) != GST_STATE_CHANGE_SUCCESS) { - gst_object_unref(GST_OBJECT(m_videoSink)); - m_videoSink = 0; - } else { - gst_element_set_state(m_videoSink, GST_STATE_NULL); - - g_object_set(G_OBJECT(m_videoSink), "force-aspect-ratio", 1, (const char*)NULL); - } - } - - if (!m_videoSink) - m_videoSink = gst_element_factory_make ("ximagesink", NULL); - - gst_object_ref (GST_OBJECT (m_videoSink)); //Take ownership - gst_object_sink (GST_OBJECT (m_videoSink)); - - -} - -GstElement *QGstreamerVideoWidgetControl::videoSink() -{ - createVideoWidget(); - return m_videoSink; -} - -bool QGstreamerVideoWidgetControl::eventFilter(QObject *object, QEvent *e) -{ - if (m_widget && object == m_widget) { - if (e->type() == QEvent::ParentChange || e->type() == QEvent::Show) { - WId newWId = m_widget->winId(); - if (newWId != m_windowId) { - m_windowId = newWId; - // Even if we have created a winId at this point, other X applications - // need to be aware of it. - QApplication::syncX(); - setOverlay(); - } - } - - if (e->type() == QEvent::Show) { - // Setting these values ensures smooth resizing since it - // will prevent the system from clearing the background - m_widget->setAttribute(Qt::WA_NoSystemBackground, true); - m_widget->setAttribute(Qt::WA_PaintOnScreen, true); - } else if (e->type() == QEvent::Resize) { - // This is a workaround for missing background repaints - // when reducing window size - windowExposed(); - } - } - - return false; -} - -bool QGstreamerVideoWidgetControl::processSyncMessage(const QGstreamerMessage &message) -{ - GstMessage* gm = message.rawMessage(); - - if (gm && (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) && - gst_structure_has_name(gm->structure, "prepare-xwindow-id")) { - - setOverlay(); - QMetaObject::invokeMethod(this, "updateNativeVideoSize", Qt::QueuedConnection); - return true; - } - - return false; -} - -bool QGstreamerVideoWidgetControl::processBusMessage(const QGstreamerMessage &message) -{ - GstMessage* gm = message.rawMessage(); - - if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_STATE_CHANGED && - GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_videoSink)) { - GstState oldState; - GstState newState; - gst_message_parse_state_changed(gm, &oldState, &newState, 0); - - if (oldState == GST_STATE_READY && newState == GST_STATE_PAUSED) - updateNativeVideoSize(); - } - - return false; -} - -void QGstreamerVideoWidgetControl::setOverlay() -{ - if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) { - gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(m_videoSink), m_windowId); - } -} - -void QGstreamerVideoWidgetControl::updateNativeVideoSize() -{ - 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_widget->setNativeSize(QGstUtils::capsCorrectedResolution(caps)); - gst_caps_unref(caps); - } - } else { - if (m_widget) - m_widget->setNativeSize(QSize()); - } -} - - -void QGstreamerVideoWidgetControl::windowExposed() -{ - if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) - gst_x_overlay_expose(GST_X_OVERLAY(m_videoSink)); -} - -QWidget *QGstreamerVideoWidgetControl::videoWidget() -{ - createVideoWidget(); - return m_widget; -} - -Qt::AspectRatioMode QGstreamerVideoWidgetControl::aspectRatioMode() const -{ - return m_aspectRatioMode; -} - -void QGstreamerVideoWidgetControl::setAspectRatioMode(Qt::AspectRatioMode mode) -{ - if (m_videoSink) { - g_object_set(G_OBJECT(m_videoSink), - "force-aspect-ratio", - (mode == Qt::KeepAspectRatio), - (const char*)NULL); - } - - m_aspectRatioMode = mode; -} - -bool QGstreamerVideoWidgetControl::isFullScreen() const -{ - return m_fullScreen; -} - -void QGstreamerVideoWidgetControl::setFullScreen(bool fullScreen) -{ - emit fullScreenChanged(m_fullScreen = fullScreen); -} - -int QGstreamerVideoWidgetControl::brightness() const -{ - int brightness = 0; - - if (m_videoSink && g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "brightness")) - g_object_get(G_OBJECT(m_videoSink), "brightness", &brightness, NULL); - - return brightness / 10; -} - -void QGstreamerVideoWidgetControl::setBrightness(int brightness) -{ - if (m_videoSink && g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "brightness")) { - g_object_set(G_OBJECT(m_videoSink), "brightness", brightness * 10, NULL); - - emit brightnessChanged(brightness); - } -} - -int QGstreamerVideoWidgetControl::contrast() const -{ - int contrast = 0; - - if (m_videoSink && g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "contrast")) - g_object_get(G_OBJECT(m_videoSink), "contrast", &contrast, NULL); - - return contrast / 10; -} - -void QGstreamerVideoWidgetControl::setContrast(int contrast) -{ - if (m_videoSink && g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "contrast")) { - g_object_set(G_OBJECT(m_videoSink), "contrast", contrast * 10, NULL); - - emit contrastChanged(contrast); - } -} - -int QGstreamerVideoWidgetControl::hue() const -{ - int hue = 0; - - if (m_videoSink && g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "hue")) - g_object_get(G_OBJECT(m_videoSink), "hue", &hue, NULL); - - return hue / 10; -} - -void QGstreamerVideoWidgetControl::setHue(int hue) -{ - if (m_videoSink && g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "hue")) { - g_object_set(G_OBJECT(m_videoSink), "hue", hue * 10, NULL); - - emit hueChanged(hue); - } -} - -int QGstreamerVideoWidgetControl::saturation() const -{ - int saturation = 0; - - if (m_videoSink && g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "saturation")) - g_object_get(G_OBJECT(m_videoSink), "saturation", &saturation, NULL); - - return saturation / 10; -} - -void QGstreamerVideoWidgetControl::setSaturation(int saturation) -{ - if (m_videoSink && g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "saturation")) { - g_object_set(G_OBJECT(m_videoSink), "saturation", saturation * 10, NULL); - - emit saturationChanged(saturation); - } -} diff --git a/src/plugins/gstreamer/qgstreamervideowidget.h b/src/plugins/gstreamer/qgstreamervideowidget.h deleted file mode 100644 index 59d69eb3b..000000000 --- a/src/plugins/gstreamer/qgstreamervideowidget.h +++ /dev/null @@ -1,114 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGSTREAMERVIDEOWIDGET_H -#define QGSTREAMERVIDEOWIDGET_H - -#include <qvideowidgetcontrol.h> - -#include "qgstreamervideorendererinterface.h" -#include <private/qgstreamerbushelper_p.h> - -QT_BEGIN_NAMESPACE - -class QGstreamerVideoWidget; - -class QGstreamerVideoWidgetControl - : public QVideoWidgetControl - , public QGstreamerVideoRendererInterface - , public QGstreamerSyncMessageFilter - , public QGstreamerBusMessageFilter -{ - Q_OBJECT - Q_INTERFACES(QGstreamerVideoRendererInterface QGstreamerSyncMessageFilter QGstreamerBusMessageFilter) -public: - QGstreamerVideoWidgetControl(QObject *parent = 0); - virtual ~QGstreamerVideoWidgetControl(); - - GstElement *videoSink(); - - QWidget *videoWidget(); - - Qt::AspectRatioMode aspectRatioMode() const; - void setAspectRatioMode(Qt::AspectRatioMode mode); - - bool isFullScreen() const; - void setFullScreen(bool fullScreen); - - 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); - - void setOverlay(); - - bool eventFilter(QObject *object, QEvent *event); - bool processSyncMessage(const QGstreamerMessage &message); - bool processBusMessage(const QGstreamerMessage &message); - -public slots: - void updateNativeVideoSize(); - -signals: - void sinkChanged(); - void readyChanged(bool); - -private: - void createVideoWidget(); - void windowExposed(); - - GstElement *m_videoSink; - QGstreamerVideoWidget *m_widget; - WId m_windowId; - Qt::AspectRatioMode m_aspectRatioMode; - bool m_fullScreen; -}; - -QT_END_NAMESPACE - -#endif // QGSTREAMERVIDEOWIDGET_H diff --git a/src/plugins/gstreamer/qgstreamervideowindow.cpp b/src/plugins/gstreamer/qgstreamervideowindow.cpp deleted file mode 100644 index 4891ea899..000000000 --- a/src/plugins/gstreamer/qgstreamervideowindow.cpp +++ /dev/null @@ -1,346 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgstreamervideowindow.h" -#include <private/qgstutils_p.h> - -#include <QtCore/qdebug.h> - -#include <gst/gst.h> -#include <gst/interfaces/xoverlay.h> -#include <gst/interfaces/propertyprobe.h> - -/* - QGstreamerVideoWindow is similar to QGstreamerVideoOverlay, - but uses xvimagesink like gstreamer element instead of QX11VideoSurface. - - This allows to use the accelerated elements if available on the target platform, - but requires at least 0.10.29 gstreamer version - with gst_x_overlay_set_render_rectangle to set display rect. -*/ - -QGstreamerVideoWindow::QGstreamerVideoWindow(QObject *parent, const char *elementName) - : QVideoWindowControl(parent) - , m_videoSink(0) - , m_windowId(0) - , m_aspectRatioMode(Qt::KeepAspectRatio) - , m_fullScreen(false) - , m_colorKey(QColor::Invalid) -{ - if (elementName) - m_videoSink = gst_element_factory_make(elementName, NULL); - else - m_videoSink = gst_element_factory_make("xvimagesink", NULL); - - 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); - } -} - -QGstreamerVideoWindow::~QGstreamerVideoWindow() -{ - if (m_videoSink) - gst_object_unref(GST_OBJECT(m_videoSink)); -} - -WId QGstreamerVideoWindow::winId() const -{ - return m_windowId; -} - -void QGstreamerVideoWindow::setWinId(WId id) -{ - if (m_windowId == id) - return; - - qDebug() << Q_FUNC_INFO << id; - - WId oldId = m_windowId; - - m_windowId = id; - - if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) { - gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(m_videoSink), m_windowId); - } - - if (!oldId) - emit readyChanged(true); - - if (!id) - emit readyChanged(false); -} - -bool QGstreamerVideoWindow::processSyncMessage(const QGstreamerMessage &message) -{ - GstMessage* gm = message.rawMessage(); - - if ((GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) && - gst_structure_has_name(gm->structure, "prepare-xwindow-id") && - m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) { - - gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(m_videoSink), m_windowId); - - GstPad *pad = gst_element_get_static_pad(m_videoSink,"sink"); - m_bufferProbeId = gst_pad_add_buffer_probe(pad, G_CALLBACK(padBufferProbe), this); - - return true; - } - - return false; -} - -QRect QGstreamerVideoWindow::displayRect() const -{ - return m_displayRect; -} - -void QGstreamerVideoWindow::setDisplayRect(const QRect &rect) -{ - m_displayRect = rect; - - if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) { -#if GST_VERSION_MICRO >= 29 - 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()); - repaint(); -#endif - } -} - -Qt::AspectRatioMode QGstreamerVideoWindow::aspectRatioMode() const -{ - return m_aspectRatioMode; -} - -void QGstreamerVideoWindow::setAspectRatioMode(Qt::AspectRatioMode mode) -{ - m_aspectRatioMode = mode; - - if (m_videoSink) { - g_object_set(G_OBJECT(m_videoSink), - "force-aspect-ratio", - (m_aspectRatioMode == Qt::KeepAspectRatio), - (const char*)NULL); - } -} - -void QGstreamerVideoWindow::repaint() -{ - 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)); - } - } -} - -QColor QGstreamerVideoWindow::colorKey() const -{ - if (!m_colorKey.isValid()) { - gint colorkey = 0; - if (m_videoSink && g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "colorkey")) - g_object_get(G_OBJECT(m_videoSink), "colorkey", &colorkey, NULL); - - if (colorkey > 0) - m_colorKey.setRgb(colorkey); - } - - return m_colorKey; -} - -void QGstreamerVideoWindow::setColorKey(const QColor &color) -{ - m_colorKey = color; - - if (m_videoSink && g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "colorkey")) - g_object_set(G_OBJECT(m_videoSink), "colorkey", color.rgba(), NULL); -} - -bool QGstreamerVideoWindow::autopaintColorKey() const -{ - bool enabled = true; - - if (m_videoSink && g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "autopaint-colorkey")) - g_object_get(G_OBJECT(m_videoSink), "autopaint-colorkey", &enabled, NULL); - - return enabled; -} - -void QGstreamerVideoWindow::setAutopaintColorKey(bool enabled) -{ - if (m_videoSink && g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "autopaint-colorkey")) - g_object_set(G_OBJECT(m_videoSink), "autopaint-colorkey", enabled, NULL); -} - -int QGstreamerVideoWindow::brightness() const -{ - int brightness = 0; - - if (m_videoSink && g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "brightness")) - g_object_get(G_OBJECT(m_videoSink), "brightness", &brightness, NULL); - - return brightness / 10; -} - -void QGstreamerVideoWindow::setBrightness(int brightness) -{ - if (m_videoSink && g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "brightness")) { - g_object_set(G_OBJECT(m_videoSink), "brightness", brightness * 10, NULL); - - emit brightnessChanged(brightness); - } -} - -int QGstreamerVideoWindow::contrast() const -{ - int contrast = 0; - - if (m_videoSink && g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "contrast")) - g_object_get(G_OBJECT(m_videoSink), "contrast", &contrast, NULL); - - return contrast / 10; -} - -void QGstreamerVideoWindow::setContrast(int contrast) -{ - if (m_videoSink && g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "contrast")) { - g_object_set(G_OBJECT(m_videoSink), "contrast", contrast * 10, NULL); - - emit contrastChanged(contrast); - } -} - -int QGstreamerVideoWindow::hue() const -{ - int hue = 0; - - if (m_videoSink && g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "hue")) - g_object_get(G_OBJECT(m_videoSink), "hue", &hue, NULL); - - return hue / 10; -} - -void QGstreamerVideoWindow::setHue(int hue) -{ - if (m_videoSink && g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "hue")) { - g_object_set(G_OBJECT(m_videoSink), "hue", hue * 10, NULL); - - emit hueChanged(hue); - } -} - -int QGstreamerVideoWindow::saturation() const -{ - int saturation = 0; - - if (m_videoSink && g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "saturation")) - g_object_get(G_OBJECT(m_videoSink), "saturation", &saturation, NULL); - - return saturation / 10; -} - -void QGstreamerVideoWindow::setSaturation(int saturation) -{ - if (m_videoSink && g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "saturation")) { - g_object_set(G_OBJECT(m_videoSink), "saturation", saturation * 10, NULL); - - emit saturationChanged(saturation); - } -} - -bool QGstreamerVideoWindow::isFullScreen() const -{ - return m_fullScreen; -} - -void QGstreamerVideoWindow::setFullScreen(bool fullScreen) -{ - emit fullScreenChanged(m_fullScreen = fullScreen); -} - -QSize QGstreamerVideoWindow::nativeSize() const -{ - return m_nativeSize; -} - -void QGstreamerVideoWindow::padBufferProbe(GstPad *pad, GstBuffer * /* buffer */, gpointer user_data) -{ - QGstreamerVideoWindow *control = reinterpret_cast<QGstreamerVideoWindow*>(user_data); - QMetaObject::invokeMethod(control, "updateNativeVideoSize", Qt::QueuedConnection); - gst_pad_remove_buffer_probe(pad, control->m_bufferProbeId); -} - -void QGstreamerVideoWindow::updateNativeVideoSize() -{ - const QSize oldSize = m_nativeSize; - m_nativeSize = QSize(); - - 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); - } - } - - if (m_nativeSize != oldSize) - emit nativeSizeChanged(); -} - -GstElement *QGstreamerVideoWindow::videoSink() -{ - return m_videoSink; -} diff --git a/src/plugins/gstreamer/qgstreamervideowindow.h b/src/plugins/gstreamer/qgstreamervideowindow.h deleted file mode 100644 index 8c962defa..000000000 --- a/src/plugins/gstreamer/qgstreamervideowindow.h +++ /dev/null @@ -1,133 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGSTREAMERVIDEOWINDOW_H -#define QGSTREAMERVIDEOWINDOW_H - -#include <qvideowindowcontrol.h> - -#include "qgstreamervideorendererinterface.h" -#include <private/qgstreamerbushelper_p.h> -#include <QtGui/qcolor.h> - -QT_BEGIN_NAMESPACE -class QAbstractVideoSurface; -QT_END_NAMESPACE -class QX11VideoSurface; - -QT_BEGIN_NAMESPACE - -class QGstreamerVideoWindow : public QVideoWindowControl, - public QGstreamerVideoRendererInterface, - public QGstreamerSyncMessageFilter -{ - Q_OBJECT - Q_INTERFACES(QGstreamerVideoRendererInterface QGstreamerSyncMessageFilter) - Q_PROPERTY(QColor colorKey READ colorKey WRITE setColorKey) - Q_PROPERTY(bool autopaintColorKey READ autopaintColorKey WRITE setAutopaintColorKey) -public: - QGstreamerVideoWindow(QObject *parent = 0, const char *elementName = 0); - ~QGstreamerVideoWindow(); - - 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); - - QColor colorKey() const; - void setColorKey(const QColor &); - - bool autopaintColorKey() const; - void setAutopaintColorKey(bool); - - 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 processSyncMessage(const QGstreamerMessage &message); - bool isReady() const { return m_windowId != 0; } - -signals: - void sinkChanged(); - void readyChanged(bool); - -private slots: - void updateNativeVideoSize(); - -private: - static void padBufferProbe(GstPad *pad, GstBuffer *buffer, gpointer user_data); - - GstElement *m_videoSink; - WId m_windowId; - Qt::AspectRatioMode m_aspectRatioMode; - QRect m_displayRect; - bool m_fullScreen; - QSize m_nativeSize; - mutable QColor m_colorKey; - int m_bufferProbeId; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/gstreamer/qx11videosurface.cpp b/src/plugins/gstreamer/qx11videosurface.cpp deleted file mode 100644 index c4d01a826..000000000 --- a/src/plugins/gstreamer/qx11videosurface.cpp +++ /dev/null @@ -1,534 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtCore/qvariant.h> -#include <QtCore/qdebug.h> -#include <QtGui/qguiapplication.h> -#include <QtGui/qplatformnativeinterface_qpa.h> -#include <qvideosurfaceformat.h> - -#include "qx11videosurface.h" - -Q_DECLARE_METATYPE(XvImage*); - -struct XvFormatRgb -{ - QVideoFrame::PixelFormat pixelFormat; - int bits_per_pixel; - int format; - int num_planes; - - int depth; - unsigned int red_mask; - unsigned int green_mask; - unsigned int blue_mask; - -}; - -bool operator ==(const XvImageFormatValues &format, const XvFormatRgb &rgb) -{ - return format.type == XvRGB - && format.bits_per_pixel == rgb.bits_per_pixel - && format.format == rgb.format - && format.num_planes == rgb.num_planes - && format.depth == rgb.depth - && format.red_mask == rgb.red_mask - && format.blue_mask == rgb.blue_mask; -} - -static const XvFormatRgb qt_xvRgbLookup[] = -{ - { QVideoFrame::Format_ARGB32, 32, XvPacked, 1, 32, 0x00FF0000, 0x0000FF00, 0x000000FF }, - { QVideoFrame::Format_RGB32 , 32, XvPacked, 1, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, - { QVideoFrame::Format_RGB24 , 24, XvPacked, 1, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, - { QVideoFrame::Format_RGB565, 16, XvPacked, 1, 16, 0x0000F800, 0x000007E0, 0x0000001F }, - { QVideoFrame::Format_BGRA32, 32, XvPacked, 1, 32, 0xFF000000, 0x00FF0000, 0x0000FF00 }, - { QVideoFrame::Format_BGR32 , 32, XvPacked, 1, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, - { QVideoFrame::Format_BGR24 , 24, XvPacked, 1, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, - { QVideoFrame::Format_BGR565, 16, XvPacked, 1, 16, 0x0000F800, 0x000007E0, 0x0000001F } -}; - -struct XvFormatYuv -{ - QVideoFrame::PixelFormat pixelFormat; - int bits_per_pixel; - int format; - int num_planes; - - unsigned int y_sample_bits; - unsigned int u_sample_bits; - unsigned int v_sample_bits; - unsigned int horz_y_period; - unsigned int horz_u_period; - unsigned int horz_v_period; - unsigned int vert_y_period; - unsigned int vert_u_period; - unsigned int vert_v_period; - char component_order[32]; -}; - -bool operator ==(const XvImageFormatValues &format, const XvFormatYuv &yuv) -{ - return format.type == XvYUV - && format.bits_per_pixel == yuv.bits_per_pixel - && format.format == yuv.format - && format.num_planes == yuv.num_planes - && format.y_sample_bits == yuv.y_sample_bits - && format.u_sample_bits == yuv.u_sample_bits - && format.v_sample_bits == yuv.v_sample_bits - && format.horz_y_period == yuv.horz_y_period - && format.horz_u_period == yuv.horz_u_period - && format.horz_v_period == yuv.horz_v_period - && format.horz_y_period == yuv.vert_y_period - && format.vert_u_period == yuv.vert_u_period - && format.vert_v_period == yuv.vert_v_period - && qstrncmp(format.component_order, yuv.component_order, 32) == 0; -} - -static const XvFormatYuv qt_xvYuvLookup[] = -{ - { QVideoFrame::Format_YUV444 , 24, XvPacked, 1, 8, 8, 8, 1, 1, 1, 1, 1, 1, "YUV" }, - { QVideoFrame::Format_YUV420P, 12, XvPlanar, 3, 8, 8, 8, 1, 2, 2, 1, 2, 2, "YUV" }, - { QVideoFrame::Format_YV12 , 12, XvPlanar, 3, 8, 8, 8, 1, 2, 2, 1, 2, 2, "YVU" }, - { QVideoFrame::Format_UYVY , 16, XvPacked, 1, 8, 8, 8, 1, 2, 2, 1, 1, 1, "UYVY" }, - { QVideoFrame::Format_YUYV , 16, XvPacked, 1, 8, 8, 8, 1, 2, 2, 1, 1, 1, "YUY2" }, - { QVideoFrame::Format_YUYV , 16, XvPacked, 1, 8, 8, 8, 1, 2, 2, 1, 1, 1, "YUYV" }, - { QVideoFrame::Format_NV12 , 12, XvPlanar, 2, 8, 8, 8, 1, 2, 2, 1, 2, 2, "YUV" }, - { QVideoFrame::Format_NV12 , 12, XvPlanar, 2, 8, 8, 8, 1, 2, 2, 1, 2, 2, "YVU" }, - { QVideoFrame::Format_Y8 , 8 , XvPlanar, 1, 8, 0, 0, 1, 0, 0, 1, 0, 0, "Y" } -}; - -QX11VideoSurface::QX11VideoSurface(QObject *parent) - : QAbstractVideoSurface(parent) - , m_winId(0) - , m_portId(0) - , m_gc(0) - , m_image(0) -{ -} - -QX11VideoSurface::~QX11VideoSurface() -{ - if (m_gc) - XFreeGC(display(), m_gc); - - if (m_portId != 0) - XvUngrabPort(display(), m_portId, 0); -} - -WId QX11VideoSurface::winId() const -{ - return m_winId; -} - -void QX11VideoSurface::setWinId(WId id) -{ - //qDebug() << "setWinID:" << id; - - if (id == m_winId) - return; - - if (m_image) - XFree(m_image); - - if (m_gc) { - XFreeGC(display(), m_gc); - m_gc = 0; - } - - if (m_portId != 0) - XvUngrabPort(display(), m_portId, 0); - - m_supportedPixelFormats.clear(); - m_formatIds.clear(); - - m_winId = id; - - if (m_winId && findPort()) { - querySupportedFormats(); - - m_gc = XCreateGC(display(), m_winId, 0, 0); - - if (m_image) { - m_image = 0; - - if (!start(surfaceFormat())) { - QAbstractVideoSurface::stop(); - qWarning() << "Failed to start video surface with format" << surfaceFormat(); - } - } - } else { - qWarning() << "Failed to find XVideo port"; - if (m_image) { - m_image = 0; - - QAbstractVideoSurface::stop(); - } - } - - emit supportedFormatsChanged(); -} - -QRect QX11VideoSurface::displayRect() const -{ - return m_displayRect; -} - -void QX11VideoSurface::setDisplayRect(const QRect &rect) -{ - m_displayRect = rect; -} - -QRect QX11VideoSurface::viewport() const -{ - return m_viewport; -} - -void QX11VideoSurface::setViewport(const QRect &rect) -{ - m_viewport = rect; -} - -int QX11VideoSurface::brightness() const -{ - return getAttribute("XV_BRIGHTNESS", m_brightnessRange.first, m_brightnessRange.second); -} - -void QX11VideoSurface::setBrightness(int brightness) -{ - setAttribute("XV_BRIGHTNESS", brightness, m_brightnessRange.first, m_brightnessRange.second); -} - -int QX11VideoSurface::contrast() const -{ - return getAttribute("XV_CONTRAST", m_contrastRange.first, m_contrastRange.second); -} - -void QX11VideoSurface::setContrast(int contrast) -{ - setAttribute("XV_CONTRAST", contrast, m_contrastRange.first, m_contrastRange.second); -} - -int QX11VideoSurface::hue() const -{ - return getAttribute("XV_HUE", m_hueRange.first, m_hueRange.second); -} - -void QX11VideoSurface::setHue(int hue) -{ - setAttribute("XV_HUE", hue, m_hueRange.first, m_hueRange.second); -} - -int QX11VideoSurface::saturation() const -{ - return getAttribute("XV_SATURATION", m_saturationRange.first, m_saturationRange.second); -} - -void QX11VideoSurface::setSaturation(int saturation) -{ - setAttribute("XV_SATURATION", saturation, m_saturationRange.first, m_saturationRange.second); -} - -int QX11VideoSurface::getAttribute(const char *attribute, int minimum, int maximum) const -{ - if (m_portId != 0) { - Display *disp = display(); - - Atom atom = XInternAtom(disp, attribute, True); - - int value = 0; - - XvGetPortAttribute(disp, m_portId, atom, &value); - - return redistribute(value, minimum, maximum, -100, 100); - } else { - return 0; - } -} - -void QX11VideoSurface::setAttribute(const char *attribute, int value, int minimum, int maximum) -{ - if (m_portId != 0) { - Display *disp = display(); - - Atom atom = XInternAtom(disp, attribute, True); - - XvSetPortAttribute( - disp, m_portId, atom, redistribute(value, -100, 100, minimum, maximum)); - } -} - -int QX11VideoSurface::redistribute( - int value, int fromLower, int fromUpper, int toLower, int toUpper) -{ - return fromUpper != fromLower - ? ((value - fromLower) * (toUpper - toLower) / (fromUpper - fromLower)) + toLower - : 0; -} - -QList<QVideoFrame::PixelFormat> QX11VideoSurface::supportedPixelFormats( - QAbstractVideoBuffer::HandleType handleType) const -{ - return handleType == QAbstractVideoBuffer::NoHandle || handleType == QAbstractVideoBuffer::XvShmImageHandle - ? m_supportedPixelFormats - : QList<QVideoFrame::PixelFormat>(); -} - -bool QX11VideoSurface::start(const QVideoSurfaceFormat &format) -{ - if (m_image) - XFree(m_image); - - int xvFormatId = 0; - for (int i = 0; i < m_supportedPixelFormats.count(); ++i) { - if (m_supportedPixelFormats.at(i) == format.pixelFormat()) { - xvFormatId = m_formatIds.at(i); - break; - } - } - - if (xvFormatId == 0) { - setError(UnsupportedFormatError); - } else { - XvImage *image = XvCreateImage( - display(), - m_portId, - xvFormatId, - 0, - format.frameWidth(), - format.frameHeight()); - - if (!image) { - setError(ResourceError); - } else { - m_viewport = format.viewport(); - m_image = image; - - QVideoSurfaceFormat newFormat = format; - newFormat.setProperty("portId", QVariant(quint64(m_portId))); - newFormat.setProperty("xvFormatId", xvFormatId); - newFormat.setProperty("dataSize", image->data_size); - - return QAbstractVideoSurface::start(newFormat); - } - } - - if (m_image) { - m_image = 0; - - QAbstractVideoSurface::stop(); - } - - return false; -} - -void QX11VideoSurface::stop() -{ - if (m_image) { - XFree(m_image); - m_image = 0; - - QAbstractVideoSurface::stop(); - } -} - -bool QX11VideoSurface::present(const QVideoFrame &frame) -{ - if (!m_image) { - setError(StoppedError); - return false; - } else if (m_image->width != frame.width() || m_image->height != frame.height()) { - setError(IncorrectFormatError); - return false; - } else { - QVideoFrame frameCopy(frame); - - if (!frameCopy.map(QAbstractVideoBuffer::ReadOnly)) { - setError(IncorrectFormatError); - return false; - } else { - bool presented = false; - - if (frame.handleType() != QAbstractVideoBuffer::XvShmImageHandle && - m_image->data_size > frame.mappedBytes()) { - qWarning("Insufficient frame buffer size"); - setError(IncorrectFormatError); - } else if (frame.handleType() != QAbstractVideoBuffer::XvShmImageHandle && - m_image->num_planes > 0 && - m_image->pitches[0] != frame.bytesPerLine()) { - qWarning("Incompatible frame pitches"); - setError(IncorrectFormatError); - } else { - if (frame.handleType() != QAbstractVideoBuffer::XvShmImageHandle) { - m_image->data = reinterpret_cast<char *>(frameCopy.bits()); - - //qDebug() << "copy frame"; - XvPutImage( - display(), - m_portId, - m_winId, - m_gc, - m_image, - m_viewport.x(), - m_viewport.y(), - m_viewport.width(), - m_viewport.height(), - m_displayRect.x(), - m_displayRect.y(), - m_displayRect.width(), - m_displayRect.height()); - - m_image->data = 0; - } else { - XvImage *img = frame.handle().value<XvImage*>(); - - //qDebug() << "render directly"; - if (img) - XvShmPutImage( - display(), - m_portId, - m_winId, - m_gc, - img, - m_viewport.x(), - m_viewport.y(), - m_viewport.width(), - m_viewport.height(), - m_displayRect.x(), - m_displayRect.y(), - m_displayRect.width(), - m_displayRect.height(), - false); - } - - presented = true; - } - - frameCopy.unmap(); - - return presented; - } - } -} - -Display *QX11VideoSurface::display() const -{ - QWindow *window = QGuiApplication::focusWindow(); - Display *display = (Display *)QGuiApplication::platformNativeInterface()->nativeResourceForWindow("Display", window); - - return display; -} - -bool QX11VideoSurface::findPort() -{ - unsigned int count = 0; - XvAdaptorInfo *adaptors = 0; - bool portFound = false; - - if (XvQueryAdaptors(display(), m_winId, &count, &adaptors) == Success) { - for (unsigned int i = 0; i < count && !portFound; ++i) { - if (adaptors[i].type & XvImageMask) { - m_portId = adaptors[i].base_id; - - for (unsigned int j = 0; j < adaptors[i].num_ports && !portFound; ++j, ++m_portId) - portFound = XvGrabPort(display(), m_portId, 0) == Success; - } - } - XvFreeAdaptorInfo(adaptors); - } - - return portFound; -} - -void QX11VideoSurface::querySupportedFormats() -{ - int count = 0; - if (XvImageFormatValues *imageFormats = XvListImageFormats( - display(), m_portId, &count)) { - const int rgbCount = sizeof(qt_xvRgbLookup) / sizeof(XvFormatRgb); - const int yuvCount = sizeof(qt_xvYuvLookup) / sizeof(XvFormatYuv); - - for (int i = 0; i < count; ++i) { - switch (imageFormats[i].type) { - case XvRGB: - for (int j = 0; j < rgbCount; ++j) { - if (imageFormats[i] == qt_xvRgbLookup[j]) { - m_supportedPixelFormats.append(qt_xvRgbLookup[j].pixelFormat); - m_formatIds.append(imageFormats[i].id); - break; - } - } - break; - case XvYUV: - for (int j = 0; j < yuvCount; ++j) { - if (imageFormats[i] == qt_xvYuvLookup[j]) { - m_supportedPixelFormats.append(qt_xvYuvLookup[j].pixelFormat); - m_formatIds.append(imageFormats[i].id); - break; - } - } - break; - } - } - XFree(imageFormats); - } - - m_brightnessRange = qMakePair(0, 0); - m_contrastRange = qMakePair(0, 0); - m_hueRange = qMakePair(0, 0); - m_saturationRange = qMakePair(0, 0); - - if (XvAttribute *attributes = XvQueryPortAttributes(display(), m_portId, &count)) { - for (int i = 0; i < count; ++i) { - if (qstrcmp(attributes[i].name, "XV_BRIGHTNESS") == 0) - m_brightnessRange = qMakePair(attributes[i].min_value, attributes[i].max_value); - else if (qstrcmp(attributes[i].name, "XV_CONTRAST") == 0) - m_contrastRange = qMakePair(attributes[i].min_value, attributes[i].max_value); - else if (qstrcmp(attributes[i].name, "XV_HUE") == 0) - m_hueRange = qMakePair(attributes[i].min_value, attributes[i].max_value); - else if (qstrcmp(attributes[i].name, "XV_SATURATION") == 0) - m_saturationRange = qMakePair(attributes[i].min_value, attributes[i].max_value); - } - - XFree(attributes); - } -} - diff --git a/src/plugins/gstreamer/qx11videosurface.h b/src/plugins/gstreamer/qx11videosurface.h deleted file mode 100644 index 243c06907..000000000 --- a/src/plugins/gstreamer/qx11videosurface.h +++ /dev/null @@ -1,117 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QX11VIDEOSURFACE_H -#define QX11VIDEOSURFACE_H - -#include <QtWidgets/qwidget.h> -#include <qabstractvideosurface.h> - -#include <X11/Xlib.h> -#include <X11/extensions/Xv.h> -#include <X11/extensions/Xvlib.h> - -QT_BEGIN_NAMESPACE - -class QX11VideoSurface : public QAbstractVideoSurface -{ - Q_OBJECT -public: - QX11VideoSurface(QObject *parent = 0); - ~QX11VideoSurface(); - - WId winId() const; - void setWinId(WId id); - - QRect displayRect() const; - void setDisplayRect(const QRect &rect); - - QRect viewport() const; - void setViewport(const QRect &rect); - - 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); - - QList<QVideoFrame::PixelFormat> supportedPixelFormats( - QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle) const; - - bool start(const QVideoSurfaceFormat &format); - void stop(); - - bool present(const QVideoFrame &frame); - -private: - Display *display() const; - - WId m_winId; - XvPortID m_portId; - GC m_gc; - XvImage *m_image; - QList<QVideoFrame::PixelFormat> m_supportedPixelFormats; - QVector<int> m_formatIds; - QRect m_viewport; - QRect m_displayRect; - QPair<int, int> m_brightnessRange; - QPair<int, int> m_contrastRange; - QPair<int, int> m_hueRange; - QPair<int, int> m_saturationRange; - - bool findPort(); - void querySupportedFormats(); - - int getAttribute(const char *attribute, int minimum, int maximum) const; - void setAttribute(const char *attribute, int value, int minimum, int maximum); - - static int redistribute(int value, int fromLower, int fromUpper, int toLower, int toUpper); -}; - -QT_END_NAMESPACE - -#endif |