diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2018-09-06 16:18:05 +0200 |
---|---|---|
committer | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2018-09-06 16:18:05 +0200 |
commit | 858e9b66e53440317bb8d41d7c342f7d28f13788 (patch) | |
tree | 1e4d8c2835fcecb60540af96a9667aadce35c766 /src/multimedia | |
parent | 72536fa39c71b32f963322a8aa0c1dee320102fc (diff) | |
parent | 871a097d0c6e8203f82b398e21dcfd8151bdae27 (diff) |
Merge remote-tracking branch 'origin/5.12' into dev
Change-Id: I87da2a6655784bcaf76dd73992c8b874853b1fc7
Diffstat (limited to 'src/multimedia')
7 files changed, 431 insertions, 2 deletions
diff --git a/src/multimedia/gsttools_headers/qgstreamerplayercontrol_p.h b/src/multimedia/gsttools_headers/qgstreamerplayercontrol_p.h new file mode 100644 index 000000000..e2252ea52 --- /dev/null +++ b/src/multimedia/gsttools_headers/qgstreamerplayercontrol_p.h @@ -0,0 +1,145 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGSTREAMERPLAYERCONTROL_P_H +#define QGSTREAMERPLAYERCONTROL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qstack.h> +#include <qmediaplayercontrol.h> +#include <private/qgsttools_global_p.h> + +QT_BEGIN_NAMESPACE + +class QMediaPlayerResourceSetInterface; +class QGstreamerPlayerSession; +class Q_GSTTOOLS_EXPORT QGstreamerPlayerControl : public QMediaPlayerControl +{ + Q_OBJECT + +public: + QGstreamerPlayerControl(QGstreamerPlayerSession *session, QObject *parent = 0); + ~QGstreamerPlayerControl(); + + QGstreamerPlayerSession *session() { return m_session; } + + QMediaPlayer::State state() const override; + QMediaPlayer::MediaStatus mediaStatus() const override; + + qint64 position() const override; + qint64 duration() const override; + + int bufferStatus() const override; + + int volume() const override; + bool isMuted() const override; + + bool isAudioAvailable() const override; + bool isVideoAvailable() const override; + void setVideoOutput(QObject *output); + + bool isSeekable() const override; + QMediaTimeRange availablePlaybackRanges() const override; + + qreal playbackRate() const override; + void setPlaybackRate(qreal rate) override; + + QMediaContent media() const override; + const QIODevice *mediaStream() const override; + void setMedia(const QMediaContent&, QIODevice *) override; + + QMediaPlayerResourceSetInterface* resources() const; + +public Q_SLOTS: + void setPosition(qint64 pos) override; + + void play() override; + void pause() override; + void stop() override; + + void setVolume(int volume) override; + void setMuted(bool muted) override; + +private Q_SLOTS: + void updateSessionState(QMediaPlayer::State state); + void updateMediaStatus(); + void processEOS(); + void setBufferProgress(int progress); + + void handleInvalidMedia(); + + void handleResourcesGranted(); + void handleResourcesLost(); + void handleResourcesDenied(); + +private: + void playOrPause(QMediaPlayer::State state); + + void pushState(); + void popAndNotifyState(); + + QGstreamerPlayerSession *m_session; + QMediaPlayer::State m_userRequestedState; + QMediaPlayer::State m_currentState; + QMediaPlayer::MediaStatus m_mediaStatus; + QStack<QMediaPlayer::State> m_stateStack; + QStack<QMediaPlayer::MediaStatus> m_mediaStatusStack; + + int m_bufferProgress; + qint64 m_pendingSeekPosition; + bool m_setMediaPending; + QMediaContent m_currentResource; + QIODevice *m_stream; + + QMediaPlayerResourceSetInterface *m_resources; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/multimedia/gsttools_headers/qgstreamerplayersession_p.h b/src/multimedia/gsttools_headers/qgstreamerplayersession_p.h new file mode 100644 index 000000000..447b9816a --- /dev/null +++ b/src/multimedia/gsttools_headers/qgstreamerplayersession_p.h @@ -0,0 +1,279 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGSTREAMERPLAYERSESSION_P_H +#define QGSTREAMERPLAYERSESSION_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtMultimedia/private/qtmultimediaglobal_p.h> +#include <QObject> +#include <QtCore/qmutex.h> +#include <QtNetwork/qnetworkrequest.h> +#include <private/qgstreamerplayercontrol_p.h> +#include <private/qgstreamerbushelper_p.h> +#include <qmediaplayer.h> +#include <qmediastreamscontrol.h> +#include <qaudioformat.h> + +#if QT_CONFIG(gstreamer_app) +#include <private/qgstappsrc_p.h> +#endif + +#include <gst/gst.h> + +QT_BEGIN_NAMESPACE + +class QGstreamerBusHelper; +class QGstreamerMessage; + +class QGstreamerVideoRendererInterface; +class QGstreamerVideoProbeControl; +class QGstreamerAudioProbeControl; + +typedef enum { + GST_AUTOPLUG_SELECT_TRY, + GST_AUTOPLUG_SELECT_EXPOSE, + GST_AUTOPLUG_SELECT_SKIP +} GstAutoplugSelectResult; + +class Q_GSTTOOLS_EXPORT QGstreamerPlayerSession + : public QObject + , public QGstreamerBusMessageFilter +{ +Q_OBJECT +Q_INTERFACES(QGstreamerBusMessageFilter) + +public: + QGstreamerPlayerSession(QObject *parent); + virtual ~QGstreamerPlayerSession(); + + GstElement *playbin() const; + void setPipeline(GstElement *pipeline); + GstElement *pipeline() const { return m_pipeline; } + QGstreamerBusHelper *bus() const { return m_busHelper; } + + QNetworkRequest request() const; + + QMediaPlayer::State state() const { return m_state; } + QMediaPlayer::State pendingState() const { return m_pendingState; } + + qint64 duration() const; + qint64 position() const; + + int volume() const; + bool isMuted() const; + + bool isAudioAvailable() const; + + void setVideoRenderer(QObject *renderer); + QGstreamerVideoRendererInterface *renderer() const { return m_renderer; } + bool isVideoAvailable() const; + + bool isSeekable() const; + + qreal playbackRate() const; + void setPlaybackRate(qreal rate); + + QMediaTimeRange availablePlaybackRanges() const; + + QMap<QByteArray ,QVariant> tags() const { return m_tags; } + QMap<QString,QVariant> streamProperties(int streamNumber) const { return m_streamProperties[streamNumber]; } + int streamCount() const { return m_streamProperties.count(); } + QMediaStreamsControl::StreamType streamType(int streamNumber) { return m_streamTypes.value(streamNumber, QMediaStreamsControl::UnknownStream); } + + int activeStream(QMediaStreamsControl::StreamType streamType) const; + void setActiveStream(QMediaStreamsControl::StreamType streamType, int streamNumber); + + bool processBusMessage(const QGstreamerMessage &message) override; + +#if QT_CONFIG(gstreamer_app) + QGstAppSrc *appsrc() const { return m_appSrc; } + static void configureAppSrcElement(GObject*, GObject*, GParamSpec*,QGstreamerPlayerSession* _this); +#endif + + bool isLiveSource() const; + + void addProbe(QGstreamerVideoProbeControl* probe); + void removeProbe(QGstreamerVideoProbeControl* probe); + + void addProbe(QGstreamerAudioProbeControl* probe); + void removeProbe(QGstreamerAudioProbeControl* probe); + + void endOfMediaReset(); + +public slots: + void loadFromUri(const QNetworkRequest &url); + void loadFromStream(const QNetworkRequest &url, QIODevice *stream); + bool play(); + bool pause(); + void stop(); + + bool seek(qint64 pos); + + void setVolume(int volume); + void setMuted(bool muted); + + void showPrerollFrames(bool enabled); + +signals: + void durationChanged(qint64 duration); + void positionChanged(qint64 position); + void stateChanged(QMediaPlayer::State state); + void volumeChanged(int volume); + void mutedStateChanged(bool muted); + void audioAvailableChanged(bool audioAvailable); + void videoAvailableChanged(bool videoAvailable); + void bufferingProgressChanged(int percentFilled); + void playbackFinished(); + void tagsChanged(); + void streamsChanged(); + void seekableChanged(bool); + void error(int error, const QString &errorString); + void invalidMedia(); + void playbackRateChanged(qreal); + void rendererChanged(); + +private slots: + void getStreamsInfo(); + void setSeekable(bool); + void finishVideoOutputChange(); + void updateVideoRenderer(); + void updateVideoResolutionTag(); + void updateVolume(); + void updateMuted(); + void updateDuration(); + +private: + static void playbinNotifySource(GObject *o, GParamSpec *p, gpointer d); + static void handleVolumeChange(GObject *o, GParamSpec *p, gpointer d); + static void handleMutedChange(GObject *o, GParamSpec *p, gpointer d); +#if !GST_CHECK_VERSION(1,0,0) + static void insertColorSpaceElement(GstElement *element, gpointer data); +#endif + static void handleElementAdded(GstBin *bin, GstElement *element, QGstreamerPlayerSession *session); + static void handleStreamsChange(GstBin *bin, gpointer user_data); + static GstAutoplugSelectResult handleAutoplugSelect(GstBin *bin, GstPad *pad, GstCaps *caps, GstElementFactory *factory, QGstreamerPlayerSession *session); + + void processInvalidMedia(QMediaPlayer::Error errorCode, const QString& errorString); + + void removeVideoBufferProbe(); + void addVideoBufferProbe(); + void removeAudioBufferProbe(); + void addAudioBufferProbe(); + void flushVideoProbes(); + void resumeVideoProbes(); + + QNetworkRequest m_request; + QMediaPlayer::State m_state; + QMediaPlayer::State m_pendingState; + QGstreamerBusHelper* m_busHelper; + GstElement *m_playbin = nullptr; // Can be null + GstElement *m_pipeline = nullptr; // Never null + + GstElement* m_videoSink; + + GstElement* m_videoOutputBin; + GstElement* m_videoIdentity; +#if !GST_CHECK_VERSION(1,0,0) + GstElement* m_colorSpace; + bool m_usingColorspaceElement; +#endif + GstElement* m_pendingVideoSink; + GstElement* m_nullVideoSink; + + GstElement* m_audioSink; + GstElement* m_volumeElement; + + GstBus* m_bus; + QObject *m_videoOutput; + QGstreamerVideoRendererInterface *m_renderer; + +#if QT_CONFIG(gstreamer_app) + QGstAppSrc *m_appSrc; +#endif + + QMap<QByteArray, QVariant> m_tags; + QList< QMap<QString,QVariant> > m_streamProperties; + QList<QMediaStreamsControl::StreamType> m_streamTypes; + QMap<QMediaStreamsControl::StreamType, int> m_playbin2StreamOffset; + + QGstreamerVideoProbeControl *m_videoProbe; + QGstreamerAudioProbeControl *m_audioProbe; + + int m_volume; + qreal m_playbackRate; + bool m_muted; + bool m_audioAvailable; + bool m_videoAvailable; + bool m_seekable; + + mutable qint64 m_lastPosition; + qint64 m_duration; + int m_durationQueries; + + bool m_displayPrerolledFrame; + + enum SourceType + { + UnknownSrc, + SoupHTTPSrc, + UDPSrc, + MMSSrc, + RTSPSrc, + }; + SourceType m_sourceType; + bool m_everPlayed; + bool m_isLiveSource; + + gulong pad_probe_id; +}; + +QT_END_NAMESPACE + +#endif // QGSTREAMERPLAYERSESSION_H diff --git a/src/multimedia/gsttools_headers/qgstreamervideooverlay_p.h b/src/multimedia/gsttools_headers/qgstreamervideooverlay_p.h index 4228f0fd0..f2ca8a23b 100644 --- a/src/multimedia/gsttools_headers/qgstreamervideooverlay_p.h +++ b/src/multimedia/gsttools_headers/qgstreamervideooverlay_p.h @@ -72,6 +72,7 @@ public: virtual ~QGstreamerVideoOverlay(); GstElement *videoSink() const; + void setVideoSink(GstElement *); QSize nativeVideoSize() const; void setWindowHandle(WId id); diff --git a/src/multimedia/gsttools_headers/qgstreamervideorenderer_p.h b/src/multimedia/gsttools_headers/qgstreamervideorenderer_p.h index 2f0b80d45..d87bfcb8f 100644 --- a/src/multimedia/gsttools_headers/qgstreamervideorenderer_p.h +++ b/src/multimedia/gsttools_headers/qgstreamervideorenderer_p.h @@ -72,6 +72,7 @@ public: void setSurface(QAbstractVideoSurface *surface) override; GstElement *videoSink() override; + void setVideoSink(GstElement *) override; void stopRenderer() override; bool isReady() const override { return m_surface != 0; } @@ -84,7 +85,7 @@ private slots: void handleFormatChange(); private: - QVideoSurfaceGstSink *m_videoSink; + GstElement *m_videoSink = nullptr; QPointer<QAbstractVideoSurface> m_surface; }; diff --git a/src/multimedia/gsttools_headers/qgstreamervideorendererinterface_p.h b/src/multimedia/gsttools_headers/qgstreamervideorendererinterface_p.h index 0d172167b..231c843db 100644 --- a/src/multimedia/gsttools_headers/qgstreamervideorendererinterface_p.h +++ b/src/multimedia/gsttools_headers/qgstreamervideorendererinterface_p.h @@ -62,6 +62,7 @@ class QGstreamerVideoRendererInterface public: virtual ~QGstreamerVideoRendererInterface(); virtual GstElement *videoSink() = 0; + virtual void setVideoSink(GstElement *) {}; //stopRenderer() is called when the renderer element is stopped. //it can be reimplemented when video renderer can't detect diff --git a/src/multimedia/gsttools_headers/qgstreamervideowidget_p.h b/src/multimedia/gsttools_headers/qgstreamervideowidget_p.h index 3e3240725..1ddb738df 100644 --- a/src/multimedia/gsttools_headers/qgstreamervideowidget_p.h +++ b/src/multimedia/gsttools_headers/qgstreamervideowidget_p.h @@ -75,6 +75,7 @@ public: virtual ~QGstreamerVideoWidgetControl(); GstElement *videoSink() override; + void setVideoSink(GstElement *) override; QWidget *videoWidget() override; diff --git a/src/multimedia/gsttools_headers/qgstvideorenderersink_p.h b/src/multimedia/gsttools_headers/qgstvideorenderersink_p.h index 3971c959d..d2417a7c9 100644 --- a/src/multimedia/gsttools_headers/qgstvideorenderersink_p.h +++ b/src/multimedia/gsttools_headers/qgstvideorenderersink_p.h @@ -138,12 +138,13 @@ private: bool m_flush; }; -class QGstVideoRendererSink +class Q_GSTTOOLS_EXPORT QGstVideoRendererSink { public: GstVideoSink parent; static QGstVideoRendererSink *createSink(QAbstractVideoSurface *surface); + static void setSurface(QAbstractVideoSurface *surface); private: static GType get_type(); |