summaryrefslogtreecommitdiffstats
path: root/src/gsttools
diff options
context:
space:
mode:
Diffstat (limited to 'src/gsttools')
-rw-r--r--src/gsttools/gsttools.pro104
-rw-r--r--src/gsttools/gstvideoconnector.c471
-rw-r--r--src/gsttools/gstvideoconnector_p.h98
-rw-r--r--src/gsttools/qgstappsrc.cpp253
-rw-r--r--src/gsttools/qgstappsrc_p.h121
-rw-r--r--src/gsttools/qgstbufferpoolinterface.cpp51
-rw-r--r--src/gsttools/qgstbufferpoolinterface_p.h117
-rw-r--r--src/gsttools/qgstcodecsinfo.cpp300
-rw-r--r--src/gsttools/qgstcodecsinfo_p.h96
-rw-r--r--src/gsttools/qgstreameraudioinputselector.cpp167
-rw-r--r--src/gsttools/qgstreameraudioinputselector_p.h88
-rw-r--r--src/gsttools/qgstreameraudioprobecontrol.cpp101
-rw-r--r--src/gsttools/qgstreameraudioprobecontrol_p.h90
-rw-r--r--src/gsttools/qgstreamerbufferprobe.cpp166
-rw-r--r--src/gsttools/qgstreamerbufferprobe_p.h97
-rw-r--r--src/gsttools/qgstreamerbushelper.cpp216
-rw-r--r--src/gsttools/qgstreamerbushelper_p.h104
-rw-r--r--src/gsttools/qgstreamermessage.cpp93
-rw-r--r--src/gsttools/qgstreamermessage_p.h84
-rw-r--r--src/gsttools/qgstreamerplayercontrol.cpp613
-rw-r--r--src/gsttools/qgstreamerplayercontrol_p.h145
-rw-r--r--src/gsttools/qgstreamerplayersession.cpp2016
-rw-r--r--src/gsttools/qgstreamerplayersession_p.h284
-rw-r--r--src/gsttools/qgstreamervideoinputdevicecontrol.cpp98
-rw-r--r--src/gsttools/qgstreamervideoinputdevicecontrol_p.h93
-rw-r--r--src/gsttools/qgstreamervideooverlay.cpp639
-rw-r--r--src/gsttools/qgstreamervideooverlay_p.h127
-rw-r--r--src/gsttools/qgstreamervideoprobecontrol.cpp129
-rw-r--r--src/gsttools/qgstreamervideoprobecontrol_p.h100
-rw-r--r--src/gsttools/qgstreamervideorenderer.cpp128
-rw-r--r--src/gsttools/qgstreamervideorenderer_p.h94
-rw-r--r--src/gsttools/qgstreamervideorendererinterface.cpp44
-rw-r--r--src/gsttools/qgstreamervideorendererinterface_p.h85
-rw-r--r--src/gsttools/qgstreamervideowidget.cpp280
-rw-r--r--src/gsttools/qgstreamervideowidget_p.h128
-rw-r--r--src/gsttools/qgstreamervideowindow.cpp179
-rw-r--r--src/gsttools/qgstreamervideowindow_p.h127
-rw-r--r--src/gsttools/qgsttools_global_p.h70
-rw-r--r--src/gsttools/qgstutils.cpp1746
-rw-r--r--src/gsttools/qgstutils_p.h176
-rw-r--r--src/gsttools/qgstvideobuffer.cpp159
-rw-r--r--src/gsttools/qgstvideobuffer_p.h107
-rw-r--r--src/gsttools/qgstvideorendererplugin.cpp51
-rw-r--r--src/gsttools/qgstvideorendererplugin_p.h110
-rw-r--r--src/gsttools/qgstvideorenderersink.cpp810
-rw-r--r--src/gsttools/qgstvideorenderersink_p.h199
-rw-r--r--src/gsttools/qvideosurfacegstsink.cpp712
-rw-r--r--src/gsttools/qvideosurfacegstsink_p.h192
48 files changed, 0 insertions, 12458 deletions
diff --git a/src/gsttools/gsttools.pro b/src/gsttools/gsttools.pro
deleted file mode 100644
index 0127cbe92..000000000
--- a/src/gsttools/gsttools.pro
+++ /dev/null
@@ -1,104 +0,0 @@
-TARGET = QtMultimediaGstTools
-MODULE = multimediagsttools
-CONFIG += internal_module
-
-QT = core-private multimedia-private gui-private
-
-!static:DEFINES += QT_MAKEDLL
-DEFINES += GLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_26
-
-qtConfig(alsa): \
- QMAKE_USE += alsa
-
-QMAKE_USE += gstreamer
-
-qtConfig(resourcepolicy): \
- QMAKE_USE += libresourceqt5
-
-PRIVATE_HEADERS += \
- qgstreamerbushelper_p.h \
- qgstreamermessage_p.h \
- qgstutils_p.h \
- qgstvideobuffer_p.h \
- qgstreamerbufferprobe_p.h \
- qgstreamervideorendererinterface_p.h \
- qgstreameraudioinputselector_p.h \
- qgstreamervideorenderer_p.h \
- qgstreamervideoinputdevicecontrol_p.h \
- qgstcodecsinfo_p.h \
- qgstreamervideoprobecontrol_p.h \
- qgstreameraudioprobecontrol_p.h \
- qgstreamervideowindow_p.h \
- qgstreamervideooverlay_p.h \
- qgsttools_global_p.h \
- qgstreamerplayersession_p.h \
- qgstreamerplayercontrol_p.h
-
-SOURCES += \
- qgstreamerbushelper.cpp \
- qgstreamermessage.cpp \
- qgstutils.cpp \
- qgstvideobuffer.cpp \
- qgstreamerbufferprobe.cpp \
- qgstreamervideorendererinterface.cpp \
- qgstreameraudioinputselector.cpp \
- qgstreamervideorenderer.cpp \
- qgstreamervideoinputdevicecontrol.cpp \
- qgstcodecsinfo.cpp \
- qgstreamervideoprobecontrol.cpp \
- qgstreameraudioprobecontrol.cpp \
- qgstreamervideowindow.cpp \
- qgstreamervideooverlay.cpp \
- qgstreamerplayersession.cpp \
- qgstreamerplayercontrol.cpp
-
-qtHaveModule(widgets) {
- QT += multimediawidgets
-
- PRIVATE_HEADERS += \
- qgstreamervideowidget_p.h
-
- SOURCES += \
- qgstreamervideowidget.cpp
-}
-
-qtConfig(gstreamer_0_10) {
- PRIVATE_HEADERS += \
- qgstbufferpoolinterface_p.h \
- qvideosurfacegstsink_p.h \
- gstvideoconnector_p.h
-
- SOURCES += \
- qgstbufferpoolinterface.cpp \
- qvideosurfacegstsink.cpp \
- gstvideoconnector.c
-} else {
- PRIVATE_HEADERS += \
- qgstvideorendererplugin_p.h \
- qgstvideorenderersink_p.h
-
- SOURCES += \
- qgstvideorendererplugin.cpp \
- qgstvideorenderersink.cpp
-}
-
-qtConfig(gstreamer_gl): QMAKE_USE += gstreamer_gl
-
-qtConfig(gstreamer_app) {
- QMAKE_USE += gstreamer_app
- PRIVATE_HEADERS += qgstappsrc_p.h
- SOURCES += qgstappsrc.cpp
-}
-
-android {
- LIBS_PRIVATE += \
- -L$$(GSTREAMER_ROOT_ANDROID)/armv7/lib \
- -Wl,--whole-archive \
- -lgstapp-1.0 -lgstreamer-1.0 -lgstaudio-1.0 -lgsttag-1.0 -lgstvideo-1.0 -lgstbase-1.0 -lgstpbutils-1.0 \
- -lgobject-2.0 -lgmodule-2.0 -lglib-2.0 -lffi -lintl -liconv -lorc-0.4 \
- -Wl,--no-whole-archive
-}
-
-HEADERS += $$PRIVATE_HEADERS
-
-load(qt_module)
diff --git a/src/gsttools/gstvideoconnector.c b/src/gsttools/gstvideoconnector.c
deleted file mode 100644
index b85f5bdbe..000000000
--- a/src/gsttools/gstvideoconnector.c
+++ /dev/null
@@ -1,471 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#include "gstvideoconnector_p.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);
-
- gchar * debugmsg = NULL;
- GST_DEBUG_OBJECT(element, "gst_video_connector_setcaps %s %i", debugmsg = gst_caps_to_string(caps), res);
- if (debugmsg)
- g_free(debugmsg);
-
- 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;
- }
-
- element->latest_buffer = gst_buffer_ref(buf);
-
- 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/gsttools/gstvideoconnector_p.h b/src/gsttools/gstvideoconnector_p.h
deleted file mode 100644
index a38ca2e65..000000000
--- a/src/gsttools/gstvideoconnector_p.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/****************************************************************************
-**
-** 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 QGSTVIDEOCONNECTOR_H
-#define QGSTVIDEOCONNECTOR_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 <private/qgsttools_global_p.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 Q_GSTTOOLS_EXPORT _GstVideoConnector {
- GstElement element;
-
- GstPad *srcpad;
- GstPad *sinkpad;
-
- gboolean relinked;
- gboolean failedSignalEmited;
- GstSegment segment;
- GstBuffer *latest_buffer;
-};
-
-struct Q_GSTTOOLS_EXPORT _GstVideoConnectorClass {
- GstElementClass parent_class;
-
- /* action signal to resend new segment */
- void (*resend_new_segment) (GstElement * element, gboolean emitFailedSignal);
-};
-
-GType Q_GSTTOOLS_EXPORT gst_video_connector_get_type (void);
-
-G_END_DECLS
-
-#endif
-
diff --git a/src/gsttools/qgstappsrc.cpp b/src/gsttools/qgstappsrc.cpp
deleted file mode 100644
index f6ecd48be..000000000
--- a/src/gsttools/qgstappsrc.cpp
+++ /dev/null
@@ -1,253 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#include <QDebug>
-
-#include "qgstappsrc_p.h"
-
-QGstAppSrc::QGstAppSrc(QObject *parent)
- : QObject(parent)
-{
- 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_appSrc) {
- gst_object_unref(G_OBJECT(m_appSrc));
- m_appSrc = 0;
- }
-
- if (!appsrc || !m_stream)
- return false;
-
- m_appSrc = GST_APP_SRC(appsrc);
- gst_object_ref(G_OBJECT(m_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, nullptr);
-
- 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 true;
-}
-
-void QGstAppSrc::setStream(QIODevice *stream)
-{
- if (m_stream) {
- disconnect(m_stream, SIGNAL(readyRead()), this, SLOT(onDataReady()));
- disconnect(m_stream, SIGNAL(destroyed()), this, SLOT(streamDestroyed()));
- m_stream = 0;
- }
-
- if (m_appSrc) {
- gst_object_unref(G_OBJECT(m_appSrc));
- m_appSrc = 0;
- }
-
- m_dataRequestSize = ~0;
- m_dataRequested = false;
- m_enoughData = false;
- m_forceData = false;
- m_sequential = false;
- m_maxBytes = 0;
-
- if (stream) {
- m_stream = stream;
- connect(m_stream, SIGNAL(destroyed()), SLOT(streamDestroyed()));
- connect(m_stream, SIGNAL(readyRead()), this, SLOT(onDataReady()));
- m_sequential = m_stream->isSequential();
- }
-}
-
-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_appSrc)
- return;
-
- if (m_dataRequested && !m_enoughData) {
- qint64 size;
- if (m_dataRequestSize == ~0u)
- size = qMin(m_stream->bytesAvailable(), queueSize());
- else
- size = qMin(m_stream->bytesAvailable(), (qint64)m_dataRequestSize);
-
- if (size) {
- GstBuffer* buffer = gst_buffer_new_and_alloc(size);
-
-#if GST_CHECK_VERSION(1,0,0)
- GstMapInfo mapInfo;
- gst_buffer_map(buffer, &mapInfo, GST_MAP_WRITE);
- void* bufferData = mapInfo.data;
-#else
- void* bufferData = GST_BUFFER_DATA(buffer);
-#endif
-
- buffer->offset = m_stream->pos();
- qint64 bytesRead = m_stream->read((char*)bufferData, size);
- buffer->offset_end = buffer->offset + bytesRead - 1;
-
-#if GST_CHECK_VERSION(1,0,0)
- gst_buffer_unmap(buffer, &mapInfo);
-#endif
-
- 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";
-#if GST_CHECK_VERSION(1,0,0)
- } else if (ret == GST_FLOW_FLUSHING) {
- qWarning()<<"appsrc: push buffer wrong state";
- }
-#else
- } else if (ret == GST_FLOW_WRONG_STATE) {
- qWarning()<<"appsrc: push buffer wrong state";
- }
-#endif
-#if GST_VERSION_MAJOR < 1
- else if (ret == GST_FLOW_RESEND) {
- qWarning()<<"appsrc: push buffer resend";
- }
-#endif
- }
- } else if (!m_sequential) {
- sendEOS();
- }
- } else if (m_stream->atEnd() && !m_sequential) {
- 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()
-{
- if (!m_appSrc)
- return;
-
- gst_app_src_end_of_stream(GST_APP_SRC(m_appSrc));
- if (isStreamValid() && !stream()->isSequential())
- stream()->reset();
-}
diff --git a/src/gsttools/qgstappsrc_p.h b/src/gsttools/qgstappsrc_p.h
deleted file mode 100644
index c1c8cdabe..000000000
--- a/src/gsttools/qgstappsrc_p.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/****************************************************************************
-**
-** 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 QGSTAPPSRC_H
-#define QGSTAPPSRC_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 <private/qgsttools_global_p.h>
-#include <QtCore/qobject.h>
-#include <QtCore/qiodevice.h>
-
-#include <gst/gst.h>
-#include <gst/app/gstappsrc.h>
-
-#if GST_VERSION_MAJOR < 1
-#include <gst/app/gstappbuffer.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class Q_GSTTOOLS_EXPORT QGstAppSrc : public QObject
-{
- Q_OBJECT
-public:
- QGstAppSrc(QObject *parent = 0);
- ~QGstAppSrc();
-
- bool setup(GstElement *);
-
- 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 = nullptr;
- GstAppSrc *m_appSrc = nullptr;
- bool m_sequential = false;
- GstAppStreamType m_streamType = GST_APP_STREAM_TYPE_RANDOM_ACCESS;
- GstAppSrcCallbacks m_callbacks;
- qint64 m_maxBytes = 0;
- unsigned int m_dataRequestSize = ~0;
- bool m_dataRequested = false;
- bool m_enoughData = false;
- bool m_forceData = false;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/gsttools/qgstbufferpoolinterface.cpp b/src/gsttools/qgstbufferpoolinterface.cpp
deleted file mode 100644
index be8a2e116..000000000
--- a/src/gsttools/qgstbufferpoolinterface.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#include "qgstbufferpoolinterface_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QGstBufferPoolPlugin::QGstBufferPoolPlugin(QObject *parent) :
- QObject(parent)
-{
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qgstbufferpoolinterface_p.cpp"
diff --git a/src/gsttools/qgstbufferpoolinterface_p.h b/src/gsttools/qgstbufferpoolinterface_p.h
deleted file mode 100644
index f5cbc35aa..000000000
--- a/src/gsttools/qgstbufferpoolinterface_p.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/****************************************************************************
-**
-** 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 QGSTBUFFERPOOLINTERFACE_P_H
-#define QGSTBUFFERPOOLINTERFACE_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 <private/qgsttools_global_p.h>
-#include <qabstractvideobuffer.h>
-#include <qvideosurfaceformat.h>
-#include <QtCore/qobject.h>
-#include <QtCore/qplugin.h>
-
-#include <gst/gst.h>
-
-QT_BEGIN_NAMESPACE
-
-const QLatin1String QGstBufferPoolPluginKey("bufferpool");
-
-/*!
- Abstract interface for video buffers allocation.
-*/
-class Q_GSTTOOLS_EXPORT QGstBufferPoolInterface
-{
-public:
- virtual ~QGstBufferPoolInterface() {}
-
- virtual bool isFormatSupported(const QVideoSurfaceFormat &format) const = 0;
- virtual GstBuffer *takeBuffer(const QVideoSurfaceFormat &format, GstCaps *caps) = 0;
- virtual void clear() = 0;
-
- virtual QAbstractVideoBuffer::HandleType handleType() const = 0;
-
- /*!
- Build an QAbstractVideoBuffer instance from GstBuffer.
- Returns nullptr if GstBuffer is not compatible with this buffer pool.
-
- This method is called from gstreamer video sink thread.
- */
- virtual QAbstractVideoBuffer *prepareVideoBuffer(GstBuffer *buffer, int bytesPerLine) = 0;
-};
-
-#define QGstBufferPoolInterface_iid "org.qt-project.qt.gstbufferpool/5.0"
-Q_DECLARE_INTERFACE(QGstBufferPoolInterface, QGstBufferPoolInterface_iid)
-
-class QGstBufferPoolPlugin : public QObject, public QGstBufferPoolInterface
-{
- Q_OBJECT
- Q_INTERFACES(QGstBufferPoolInterface)
-public:
- explicit QGstBufferPoolPlugin(QObject *parent = 0);
- virtual ~QGstBufferPoolPlugin() {}
-
- bool isFormatSupported(const QVideoSurfaceFormat &format) const override = 0;
- GstBuffer *takeBuffer(const QVideoSurfaceFormat &format, GstCaps *caps) override = 0;
- void clear() override = 0;
-
- QAbstractVideoBuffer::HandleType handleType() const override = 0;
-
- /*!
- Build an QAbstractVideoBuffer instance from compatible GstBuffer.
- Returns nullptr if GstBuffer is not compatible with this buffer pool.
-
- This method is called from gstreamer video sink thread.
- */
- QAbstractVideoBuffer *prepareVideoBuffer(GstBuffer *buffer, int bytesPerLine) override = 0;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/gsttools/qgstcodecsinfo.cpp b/src/gsttools/qgstcodecsinfo.cpp
deleted file mode 100644
index 2522ee19c..000000000
--- a/src/gsttools/qgstcodecsinfo.cpp
+++ /dev/null
@@ -1,300 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#include "qgstcodecsinfo_p.h"
-#include "qgstutils_p.h"
-#include <QtCore/qset.h>
-
-#include <gst/pbutils/pbutils.h>
-
-static QSet<QString> streamTypes(GstElementFactory *factory, GstPadDirection direction)
-{
- QSet<QString> types;
- const GList *pads = gst_element_factory_get_static_pad_templates(factory);
- for (const GList *pad = pads; pad; pad = g_list_next(pad)) {
- GstStaticPadTemplate *templ = reinterpret_cast<GstStaticPadTemplate *>(pad->data);
- if (templ->direction == direction) {
- GstCaps *caps = gst_static_caps_get(&templ->static_caps);
- for (uint i = 0; i < gst_caps_get_size(caps); ++i) {
- GstStructure *structure = gst_caps_get_structure(caps, i);
- types.insert(QString::fromUtf8(gst_structure_get_name(structure)));
- }
- gst_caps_unref(caps);
- }
- }
-
- return types;
-}
-
-QGstCodecsInfo::QGstCodecsInfo(QGstCodecsInfo::ElementType elementType)
-{
- updateCodecs(elementType);
- for (auto &codec : supportedCodecs()) {
- GstElementFactory *factory = gst_element_factory_find(codecElement(codec).constData());
- if (factory) {
- GstPadDirection direction = elementType == Muxer ? GST_PAD_SINK : GST_PAD_SRC;
- m_streamTypes.insert(codec, streamTypes(factory, direction));
- gst_object_unref(GST_OBJECT(factory));
- }
- }
-}
-
-QStringList QGstCodecsInfo::supportedCodecs() const
-{
- return m_codecs;
-}
-
-QString QGstCodecsInfo::codecDescription(const QString &codec) const
-{
- return m_codecInfo.value(codec).description;
-}
-
-QByteArray QGstCodecsInfo::codecElement(const QString &codec) const
-
-{
- return m_codecInfo.value(codec).elementName;
-}
-
-QStringList QGstCodecsInfo::codecOptions(const QString &codec) const
-{
- QStringList options;
-
- QByteArray elementName = m_codecInfo.value(codec).elementName;
- if (elementName.isEmpty())
- return options;
-
- GstElement *element = gst_element_factory_make(elementName, nullptr);
- if (element) {
- guint numProperties;
- GParamSpec **properties = g_object_class_list_properties(G_OBJECT_GET_CLASS(element),
- &numProperties);
- for (guint j = 0; j < numProperties; ++j) {
- GParamSpec *property = properties[j];
- // ignore some properties
- if (strcmp(property->name, "name") == 0 || strcmp(property->name, "parent") == 0)
- continue;
-
- options.append(QLatin1String(property->name));
- }
- g_free(properties);
- gst_object_unref(element);
- }
-
- return options;
-}
-
-void QGstCodecsInfo::updateCodecs(ElementType elementType)
-{
- m_codecs.clear();
- m_codecInfo.clear();
-
- GList *elements = elementFactories(elementType);
-
- 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" << "systemstream";
-
- 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 == GST_PAD_SRC) {
- 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 = qt_gst_structure_new_empty(gst_structure_get_name(structure));
-
- //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);
- }
- }
-
- GstCaps *newCaps = gst_caps_new_full(newStructure, nullptr);
-
- gchar *capsString = gst_caps_to_string(newCaps);
- QString codec = QLatin1String(capsString);
- if (capsString)
- g_free(capsString);
- GstRank rank = GstRank(gst_plugin_feature_get_rank(GST_PLUGIN_FEATURE(factory)));
-
- // If two elements provide the same codec, use the highest ranked one
- QMap<QString, CodecInfo>::const_iterator it = m_codecInfo.constFind(codec);
- if (it == m_codecInfo.constEnd() || it->rank < rank) {
- if (it == m_codecInfo.constEnd())
- m_codecs.append(codec);
-
- CodecInfo info;
- info.elementName = gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(factory));
-
- gchar *description = gst_pb_utils_get_codec_description(newCaps);
- info.description = QString::fromUtf8(description);
- if (description)
- g_free(description);
-
- info.rank = rank;
-
- m_codecInfo.insert(codec, info);
- }
-
- gst_caps_unref(newCaps);
- }
- gst_caps_unref(caps);
- }
- }
- }
-
- gst_plugin_feature_list_free(elements);
-}
-
-#if !GST_CHECK_VERSION(0, 10, 31)
-static gboolean element_filter(GstPluginFeature *feature, gpointer user_data)
-{
- if (Q_UNLIKELY(!GST_IS_ELEMENT_FACTORY(feature)))
- return FALSE;
-
- const QGstCodecsInfo::ElementType type = *reinterpret_cast<QGstCodecsInfo::ElementType *>(user_data);
-
- const gchar *klass = gst_element_factory_get_klass(GST_ELEMENT_FACTORY(feature));
- if (type == QGstCodecsInfo::AudioEncoder && !(strstr(klass, "Encoder") && strstr(klass, "Audio")))
- return FALSE;
- if (type == QGstCodecsInfo::VideoEncoder && !(strstr(klass, "Encoder") && strstr(klass, "Video")))
- return FALSE;
- if (type == QGstCodecsInfo::Muxer && !strstr(klass, "Muxer"))
- return FALSE;
-
- guint rank = gst_plugin_feature_get_rank(feature);
- if (rank < GST_RANK_MARGINAL)
- return FALSE;
-
- return TRUE;
-}
-
-static gint compare_plugin_func(const void *item1, const void *item2)
-{
- GstPluginFeature *f1 = reinterpret_cast<GstPluginFeature *>(const_cast<void *>(item1));
- GstPluginFeature *f2 = reinterpret_cast<GstPluginFeature *>(const_cast<void *>(item2));
-
- gint diff = gst_plugin_feature_get_rank(f2) - gst_plugin_feature_get_rank(f1);
- if (diff != 0)
- return diff;
-
- return strcmp(gst_plugin_feature_get_name(f1), gst_plugin_feature_get_name (f2));
-}
-#endif
-
-GList *QGstCodecsInfo::elementFactories(ElementType elementType) const
-{
-#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;
- }
-
- GList *list = gst_element_factory_list_get_elements(gstElementType, GST_RANK_MARGINAL);
- if (elementType == AudioEncoder) {
- // Manually add "audioconvert" to the list
- // to allow linking with various containers.
- auto factory = gst_element_factory_find("audioconvert");
- if (factory)
- list = g_list_prepend(list, factory);
- }
-
- return list;
-#else
- GList *result = gst_registry_feature_filter(gst_registry_get_default(),
- element_filter,
- FALSE, &elementType);
- result = g_list_sort(result, compare_plugin_func);
- return result;
-#endif
-}
-
-QSet<QString> QGstCodecsInfo::supportedStreamTypes(const QString &codec) const
-{
- return m_streamTypes.value(codec);
-}
-
-QStringList QGstCodecsInfo::supportedCodecs(const QSet<QString> &types) const
-{
- QStringList result;
- for (auto &candidate : supportedCodecs()) {
- auto candidateTypes = supportedStreamTypes(candidate);
- if (candidateTypes.intersects(types))
- result << candidate;
- }
-
- return result;
-}
diff --git a/src/gsttools/qgstcodecsinfo_p.h b/src/gsttools/qgstcodecsinfo_p.h
deleted file mode 100644
index d7aadef21..000000000
--- a/src/gsttools/qgstcodecsinfo_p.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/****************************************************************************
-**
-** 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 QGSTCODECSINFO_H
-#define QGSTCODECSINFO_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 <private/qgsttools_global_p.h>
-#include <QtCore/qmap.h>
-#include <QtCore/qstringlist.h>
-#include <QSet>
-
-#include <gst/gst.h>
-
-QT_BEGIN_NAMESPACE
-
-class Q_GSTTOOLS_EXPORT QGstCodecsInfo
-{
-public:
- enum ElementType { AudioEncoder, VideoEncoder, Muxer };
-
- struct CodecInfo {
- QString description;
- QByteArray elementName;
- GstRank rank;
- };
-
- QGstCodecsInfo(ElementType elementType);
-
- QStringList supportedCodecs() const;
- QString codecDescription(const QString &codec) const;
- QByteArray codecElement(const QString &codec) const;
- QStringList codecOptions(const QString &codec) const;
- QSet<QString> supportedStreamTypes(const QString &codec) const;
- QStringList supportedCodecs(const QSet<QString> &types) const;
-
-private:
- void updateCodecs(ElementType elementType);
- GList *elementFactories(ElementType elementType) const;
-
- QStringList m_codecs;
- QMap<QString, CodecInfo> m_codecInfo;
- QMap<QString, QSet<QString>> m_streamTypes;
-};
-
-Q_DECLARE_TYPEINFO(QGstCodecsInfo::CodecInfo, Q_MOVABLE_TYPE);
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/gsttools/qgstreameraudioinputselector.cpp b/src/gsttools/qgstreameraudioinputselector.cpp
deleted file mode 100644
index 3bf5538c2..000000000
--- a/src/gsttools/qgstreameraudioinputselector.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#include <QtMultimedia/private/qtmultimediaglobal_p.h>
-#include "qgstreameraudioinputselector_p.h"
-
-#include <QtCore/QDir>
-#include <QtCore/QDebug>
-
-#include <gst/gst.h>
-
-#if QT_CONFIG(alsa)
-#include <alsa/asoundlib.h>
-#endif
-
-QGstreamerAudioInputSelector::QGstreamerAudioInputSelector(QObject *parent)
- :QAudioInputSelectorControl(parent)
-{
- update();
-}
-
-QGstreamerAudioInputSelector::~QGstreamerAudioInputSelector()
-{
-}
-
-QList<QString> QGstreamerAudioInputSelector::availableInputs() const
-{
- return m_names;
-}
-
-QString QGstreamerAudioInputSelector::inputDescription(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 QGstreamerAudioInputSelector::defaultInput() const
-{
- if (m_names.size() > 0)
- return m_names.at(0);
-
- return QString();
-}
-
-QString QGstreamerAudioInputSelector::activeInput() const
-{
- return m_audioInput;
-}
-
-void QGstreamerAudioInputSelector::setActiveInput(const QString& name)
-{
- if (m_audioInput.compare(name) != 0) {
- m_audioInput = name;
- emit activeInputChanged(name);
- }
-}
-
-void QGstreamerAudioInputSelector::update()
-{
- m_names.clear();
- m_descriptions.clear();
-
- //use autoaudiosrc as the first default device
- m_names.append(QLatin1String("default:"));
- m_descriptions.append(tr("System default device"));
-
- updatePulseDevices();
- updateAlsaDevices();
- updateOssDevices();
- if (m_names.size() > 0)
- m_audioInput = m_names.at(0);
-}
-
-void QGstreamerAudioInputSelector::updateAlsaDevices()
-{
-#if QT_CONFIG(alsa)
- void **hints, **n;
- if (snd_device_name_hint(-1, "pcm", &hints) < 0) {
- qWarning()<<"no alsa devices available";
- return;
- }
- n = hints;
-
- while (*n != nullptr) {
- 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 != nullptr) && (descr != nullptr)) {
- if (io == nullptr || qstrcmp(io, "Input") == 0) {
- m_names.append(QLatin1String("alsa:")+QString::fromUtf8(name));
- m_descriptions.append(QString::fromUtf8(descr));
- }
- }
-
- free(name);
- free(descr);
- free(io);
- n++;
- }
- snd_device_name_free_hint(hints);
-#endif
-}
-
-void QGstreamerAudioInputSelector::updateOssDevices()
-{
- QDir devDir(QStringLiteral("/dev"));
- devDir.setFilter(QDir::System);
- const QFileInfoList entries = devDir.entryInfoList(QStringList() << QLatin1String("dsp*"));
- for (const QFileInfo& entryInfo : entries) {
- m_names.append(QLatin1String("oss:")+entryInfo.filePath());
- m_descriptions.append(QString::fromLatin1("OSS device %1").arg(entryInfo.fileName()));
- }
-}
-
-void QGstreamerAudioInputSelector::updatePulseDevices()
-{
- GstElementFactory *factory = gst_element_factory_find("pulsesrc");
- if (factory) {
- m_names.append(QLatin1String("pulseaudio:"));
- m_descriptions.append(QLatin1String("PulseAudio device."));
- gst_object_unref(GST_OBJECT(factory));
- }
-}
diff --git a/src/gsttools/qgstreameraudioinputselector_p.h b/src/gsttools/qgstreameraudioinputselector_p.h
deleted file mode 100644
index 0c193fda9..000000000
--- a/src/gsttools/qgstreameraudioinputselector_p.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/****************************************************************************
-**
-** 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 QGSTREAMERAUDIOINPUTSELECTOR_H
-#define QGSTREAMERAUDIOINPUTSELECTOR_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 <private/qgsttools_global_p.h>
-#include <qaudioinputselectorcontrol.h>
-#include <QtCore/qstringlist.h>
-
-QT_BEGIN_NAMESPACE
-
-class Q_GSTTOOLS_EXPORT QGstreamerAudioInputSelector : public QAudioInputSelectorControl
-{
-Q_OBJECT
-public:
- QGstreamerAudioInputSelector(QObject *parent);
- ~QGstreamerAudioInputSelector();
-
- QList<QString> availableInputs() const override;
- QString inputDescription(const QString &name) const override;
- QString defaultInput() const override;
- QString activeInput() const override;
-
-public Q_SLOTS:
- void setActiveInput(const QString &name) override;
-
-private:
- void update();
- void updateAlsaDevices();
- void updateOssDevices();
- void updatePulseDevices();
-
- QString m_audioInput;
- QList<QString> m_names;
- QList<QString> m_descriptions;
-};
-
-QT_END_NAMESPACE
-
-#endif // QGSTREAMERAUDIOINPUTSELECTOR_H
diff --git a/src/gsttools/qgstreameraudioprobecontrol.cpp b/src/gsttools/qgstreameraudioprobecontrol.cpp
deleted file mode 100644
index d40b39939..000000000
--- a/src/gsttools/qgstreameraudioprobecontrol.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#include "qgstreameraudioprobecontrol_p.h"
-#include <private/qgstutils_p.h>
-
-QGstreamerAudioProbeControl::QGstreamerAudioProbeControl(QObject *parent)
- : QMediaAudioProbeControl(parent)
-{
-}
-
-QGstreamerAudioProbeControl::~QGstreamerAudioProbeControl()
-{
-}
-
-void QGstreamerAudioProbeControl::probeCaps(GstCaps *caps)
-{
- QAudioFormat format = QGstUtils::audioFormatForCaps(caps);
-
- QMutexLocker locker(&m_bufferMutex);
- m_format = format;
-}
-
-bool QGstreamerAudioProbeControl::probeBuffer(GstBuffer *buffer)
-{
- qint64 position = GST_BUFFER_TIMESTAMP(buffer);
- position = position >= 0
- ? position / G_GINT64_CONSTANT(1000) // microseconds
- : -1;
-
- QByteArray data;
-#if GST_CHECK_VERSION(1,0,0)
- GstMapInfo info;
- if (gst_buffer_map(buffer, &info, GST_MAP_READ)) {
- data = QByteArray(reinterpret_cast<const char *>(info.data), info.size);
- gst_buffer_unmap(buffer, &info);
- } else {
- return true;
- }
-#else
- data = QByteArray(reinterpret_cast<const char *>(buffer->data), buffer->size);
-#endif
-
- QMutexLocker locker(&m_bufferMutex);
- if (m_format.isValid()) {
- if (!m_pendingBuffer.isValid())
- QMetaObject::invokeMethod(this, "bufferProbed", Qt::QueuedConnection);
- m_pendingBuffer = QAudioBuffer(data, m_format, position);
- }
-
- return true;
-}
-
-void QGstreamerAudioProbeControl::bufferProbed()
-{
- QAudioBuffer audioBuffer;
- {
- QMutexLocker locker(&m_bufferMutex);
- if (!m_pendingBuffer.isValid())
- return;
- audioBuffer = m_pendingBuffer;
- m_pendingBuffer = QAudioBuffer();
- }
- emit audioBufferProbed(audioBuffer);
-}
diff --git a/src/gsttools/qgstreameraudioprobecontrol_p.h b/src/gsttools/qgstreameraudioprobecontrol_p.h
deleted file mode 100644
index 4fc5c7704..000000000
--- a/src/gsttools/qgstreameraudioprobecontrol_p.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/****************************************************************************
-**
-** 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 QGSTREAMERAUDIOPROBECONTROL_H
-#define QGSTREAMERAUDIOPROBECONTROL_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 <private/qgsttools_global_p.h>
-#include <gst/gst.h>
-#include <qmediaaudioprobecontrol.h>
-#include <QtCore/qmutex.h>
-#include <qaudiobuffer.h>
-#include <qshareddata.h>
-
-#include <private/qgstreamerbufferprobe_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class Q_GSTTOOLS_EXPORT QGstreamerAudioProbeControl
- : public QMediaAudioProbeControl
- , public QGstreamerBufferProbe
- , public QSharedData
-{
- Q_OBJECT
-public:
- explicit QGstreamerAudioProbeControl(QObject *parent);
- virtual ~QGstreamerAudioProbeControl();
-
-protected:
- void probeCaps(GstCaps *caps) override;
- bool probeBuffer(GstBuffer *buffer) override;
-
-private slots:
- void bufferProbed();
-
-private:
- QAudioBuffer m_pendingBuffer;
- QAudioFormat m_format;
- QMutex m_bufferMutex;
-};
-
-QT_END_NAMESPACE
-
-#endif // QGSTREAMERAUDIOPROBECONTROL_H
diff --git a/src/gsttools/qgstreamerbufferprobe.cpp b/src/gsttools/qgstreamerbufferprobe.cpp
deleted file mode 100644
index e2956eadd..000000000
--- a/src/gsttools/qgstreamerbufferprobe.cpp
+++ /dev/null
@@ -1,166 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Jolla 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$
-**
-****************************************************************************/
-
-#include "qgstreamerbufferprobe_p.h"
-#include "qgstutils_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QGstreamerBufferProbe::QGstreamerBufferProbe(Flags flags)
- : m_flags(flags)
-{
-}
-
-QGstreamerBufferProbe::~QGstreamerBufferProbe()
-{
-#if !GST_CHECK_VERSION(1,0,0)
- if (m_caps)
- gst_caps_unref(m_caps);
-#endif
-}
-
-void QGstreamerBufferProbe::addProbeToPad(GstPad *pad, bool downstream)
-{
- if (GstCaps *caps = qt_gst_pad_get_current_caps(pad)) {
- probeCaps(caps);
- gst_caps_unref(caps);
- }
-#if GST_CHECK_VERSION(1,0,0)
- if (m_flags & ProbeCaps) {
- m_capsProbeId = gst_pad_add_probe(
- pad,
- downstream
- ? GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM
- : GST_PAD_PROBE_TYPE_EVENT_UPSTREAM,
- capsProbe,
- this,
- nullptr);
- }
- if (m_flags & ProbeBuffers) {
- m_bufferProbeId = gst_pad_add_probe(
- pad, GST_PAD_PROBE_TYPE_BUFFER, bufferProbe, this, nullptr);
- }
-#else
- Q_UNUSED(downstream);
-
- m_bufferProbeId = gst_pad_add_buffer_probe(pad, G_CALLBACK(bufferProbe), this);
-#endif
-}
-
-void QGstreamerBufferProbe::removeProbeFromPad(GstPad *pad)
-{
-#if GST_CHECK_VERSION(1,0,0)
- if (m_capsProbeId != -1) {
- gst_pad_remove_probe(pad, m_capsProbeId);
- m_capsProbeId = -1;
- }
- if (m_bufferProbeId != -1) {
- gst_pad_remove_probe(pad, m_bufferProbeId);
- m_bufferProbeId = -1;
- }
-#else
- if (m_bufferProbeId != -1) {
- gst_pad_remove_buffer_probe(pad, m_bufferProbeId);
- m_bufferProbeId = -1;
- if (m_caps) {
- gst_caps_unref(m_caps);
- m_caps = 0;
- }
- }
-#endif
-}
-
-void QGstreamerBufferProbe::probeCaps(GstCaps *)
-{
-}
-
-bool QGstreamerBufferProbe::probeBuffer(GstBuffer *)
-{
- return true;
-}
-
-#if GST_CHECK_VERSION(1,0,0)
-GstPadProbeReturn QGstreamerBufferProbe::capsProbe(
- GstPad *, GstPadProbeInfo *info, gpointer user_data)
-{
- QGstreamerBufferProbe * const control = static_cast<QGstreamerBufferProbe *>(user_data);
-
- if (GstEvent * const event = gst_pad_probe_info_get_event(info)) {
- if (GST_EVENT_TYPE(event) == GST_EVENT_CAPS) {
- GstCaps *caps;
- gst_event_parse_caps(event, &caps);
-
- control->probeCaps(caps);
- }
- }
- return GST_PAD_PROBE_OK;
-}
-
-GstPadProbeReturn QGstreamerBufferProbe::bufferProbe(
- GstPad *, GstPadProbeInfo *info, gpointer user_data)
-{
- QGstreamerBufferProbe * const control = static_cast<QGstreamerBufferProbe *>(user_data);
- if (GstBuffer * const buffer = gst_pad_probe_info_get_buffer(info))
- return control->probeBuffer(buffer) ? GST_PAD_PROBE_OK : GST_PAD_PROBE_DROP;
- return GST_PAD_PROBE_OK;
-}
-#else
-gboolean QGstreamerBufferProbe::bufferProbe(GstElement *, GstBuffer *buffer, gpointer user_data)
-{
- QGstreamerBufferProbe * const control = static_cast<QGstreamerBufferProbe *>(user_data);
-
- if (control->m_flags & ProbeCaps) {
- GstCaps *caps = gst_buffer_get_caps(buffer);
- if (caps && (!control->m_caps || !gst_caps_is_equal(control->m_caps, caps))) {
- qSwap(caps, control->m_caps);
- control->probeCaps(control->m_caps);
- }
- if (caps)
- gst_caps_unref(caps);
- }
-
- if (control->m_flags & ProbeBuffers) {
- return control->probeBuffer(buffer) ? TRUE : FALSE;
- } else {
- return TRUE;
- }
-}
-#endif
-
-QT_END_NAMESPACE
diff --git a/src/gsttools/qgstreamerbufferprobe_p.h b/src/gsttools/qgstreamerbufferprobe_p.h
deleted file mode 100644
index 2dda73e40..000000000
--- a/src/gsttools/qgstreamerbufferprobe_p.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Jolla 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 QGSTREAMERBUFFERPROBE_H
-#define QGSTREAMERBUFFERPROBE_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 <private/qgsttools_global_p.h>
-#include <gst/gst.h>
-
-#include <QtCore/qglobal.h>
-
-
-QT_BEGIN_NAMESPACE
-
-class Q_GSTTOOLS_EXPORT QGstreamerBufferProbe
-{
-public:
- enum Flags
- {
- ProbeCaps = 0x01,
- ProbeBuffers = 0x02,
- ProbeAll = ProbeCaps | ProbeBuffers
- };
-
- explicit QGstreamerBufferProbe(Flags flags = ProbeAll);
- virtual ~QGstreamerBufferProbe();
-
- void addProbeToPad(GstPad *pad, bool downstream = true);
- void removeProbeFromPad(GstPad *pad);
-
-protected:
- virtual void probeCaps(GstCaps *caps);
- virtual bool probeBuffer(GstBuffer *buffer);
-
-private:
-#if GST_CHECK_VERSION(1,0,0)
- static GstPadProbeReturn capsProbe(GstPad *pad, GstPadProbeInfo *info, gpointer user_data);
- static GstPadProbeReturn bufferProbe(GstPad *pad, GstPadProbeInfo *info, gpointer user_data);
- int m_capsProbeId = -1;
-#else
- static gboolean bufferProbe(GstElement *element, GstBuffer *buffer, gpointer user_data);
- GstCaps *m_caps = nullptr;
-#endif
- int m_bufferProbeId = -1;
- const Flags m_flags;
-};
-
-QT_END_NAMESPACE
-
-#endif // QGSTREAMERAUDIOPROBECONTROL_H
diff --git a/src/gsttools/qgstreamerbushelper.cpp b/src/gsttools/qgstreamerbushelper.cpp
deleted file mode 100644
index 1a4034eee..000000000
--- a/src/gsttools/qgstreamerbushelper.cpp
+++ /dev/null
@@ -1,216 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#include <QtCore/qmap.h>
-#include <QtCore/qtimer.h>
-#include <QtCore/qmutex.h>
-#include <QtCore/qlist.h>
-#include <QtCore/qabstracteventdispatcher.h>
-#include <QtCore/qcoreapplication.h>
-
-#include "qgstreamerbushelper_p.h"
-
-QT_BEGIN_NAMESPACE
-
-
-class QGstreamerBusHelperPrivate : public QObject
-{
- Q_OBJECT
-public:
- QGstreamerBusHelperPrivate(QGstreamerBusHelper *parent, GstBus* bus) :
- QObject(parent),
- m_tag(0),
- m_bus(bus),
- m_helper(parent),
- m_intervalTimer(nullptr)
- {
- // glib event loop can be disabled either by env variable or QT_NO_GLIB define, so check the dispacher
- QAbstractEventDispatcher *dispatcher = QCoreApplication::eventDispatcher();
- const bool hasGlib = dispatcher && dispatcher->inherits("QEventDispatcherGlib");
- if (!hasGlib) {
- m_intervalTimer = new QTimer(this);
- m_intervalTimer->setInterval(250);
- connect(m_intervalTimer, SIGNAL(timeout()), SLOT(interval()));
- m_intervalTimer->start();
- } else {
- m_tag = gst_bus_add_watch_full(bus, G_PRIORITY_DEFAULT, busCallback, this, nullptr);
- }
- }
-
- ~QGstreamerBusHelperPrivate()
- {
- m_helper = 0;
- delete m_intervalTimer;
-
- if (m_tag)
-#if GST_CHECK_VERSION(1, 6, 0)
- gst_bus_remove_watch(m_bus);
-#else
- g_source_remove(m_tag);
-#endif
- }
-
- GstBus* bus() const { return m_bus; }
-
-private slots:
- void interval()
- {
- GstMessage* message;
- while ((message = gst_bus_poll(m_bus, GST_MESSAGE_ANY, 0)) != 0) {
- processMessage(message);
- gst_message_unref(message);
- }
- }
-
-private:
- void processMessage(GstMessage* message)
- {
- QGstreamerMessage msg(message);
- doProcessMessage(msg);
- }
-
- void queueMessage(GstMessage* message)
- {
- QGstreamerMessage msg(message);
- QMetaObject::invokeMethod(this, "doProcessMessage", Qt::QueuedConnection,
- Q_ARG(QGstreamerMessage, msg));
- }
-
- static gboolean busCallback(GstBus *bus, GstMessage *message, gpointer data)
- {
- Q_UNUSED(bus);
- reinterpret_cast<QGstreamerBusHelperPrivate*>(data)->queueMessage(message);
- return TRUE;
- }
-
- guint m_tag;
- GstBus* m_bus;
- QGstreamerBusHelper* m_helper;
- QTimer* m_intervalTimer;
-
-private slots:
- void doProcessMessage(const QGstreamerMessage& msg)
- {
- for (QGstreamerBusMessageFilter *filter : qAsConst(busFilters)) {
- if (filter->processBusMessage(msg))
- break;
- }
- emit m_helper->message(msg);
- }
-
-public:
- QMutex filterMutex;
- QList<QGstreamerSyncMessageFilter*> syncFilters;
- QList<QGstreamerBusMessageFilter*> busFilters;
-};
-
-
-static GstBusSyncReply syncGstBusFilter(GstBus* bus, GstMessage* message, QGstreamerBusHelperPrivate *d)
-{
- Q_UNUSED(bus);
- QMutexLocker lock(&d->filterMutex);
-
- for (QGstreamerSyncMessageFilter *filter : qAsConst(d->syncFilters)) {
- if (filter->processSyncMessage(QGstreamerMessage(message))) {
- gst_message_unref(message);
- return GST_BUS_DROP;
- }
- }
-
- return GST_BUS_PASS;
-}
-
-
-/*!
- \class QGstreamerBusHelper
- \internal
-*/
-
-QGstreamerBusHelper::QGstreamerBusHelper(GstBus* bus, QObject* parent):
- QObject(parent)
-{
- d = new QGstreamerBusHelperPrivate(this, bus);
-#if GST_CHECK_VERSION(1,0,0)
- gst_bus_set_sync_handler(bus, (GstBusSyncHandler)syncGstBusFilter, d, 0);
-#else
- gst_bus_set_sync_handler(bus, (GstBusSyncHandler)syncGstBusFilter, d);
-#endif
- gst_object_ref(GST_OBJECT(bus));
-}
-
-QGstreamerBusHelper::~QGstreamerBusHelper()
-{
-#if GST_CHECK_VERSION(1,0,0)
- gst_bus_set_sync_handler(d->bus(), 0, 0, 0);
-#else
- gst_bus_set_sync_handler(d->bus(),0,0);
-#endif
- gst_object_unref(GST_OBJECT(d->bus()));
-}
-
-void QGstreamerBusHelper::installMessageFilter(QObject *filter)
-{
- auto syncFilter = qobject_cast<QGstreamerSyncMessageFilter*>(filter);
- if (syncFilter) {
- QMutexLocker lock(&d->filterMutex);
- if (!d->syncFilters.contains(syncFilter))
- d->syncFilters.append(syncFilter);
- }
-
- auto busFilter = qobject_cast<QGstreamerBusMessageFilter*>(filter);
- if (busFilter && !d->busFilters.contains(busFilter))
- d->busFilters.append(busFilter);
-}
-
-void QGstreamerBusHelper::removeMessageFilter(QObject *filter)
-{
- auto syncFilter = qobject_cast<QGstreamerSyncMessageFilter*>(filter);
- if (syncFilter) {
- QMutexLocker lock(&d->filterMutex);
- d->syncFilters.removeAll(syncFilter);
- }
-
- auto busFilter = qobject_cast<QGstreamerBusMessageFilter*>(filter);
- if (busFilter)
- d->busFilters.removeAll(busFilter);
-}
-
-QT_END_NAMESPACE
-
-#include "qgstreamerbushelper.moc"
diff --git a/src/gsttools/qgstreamerbushelper_p.h b/src/gsttools/qgstreamerbushelper_p.h
deleted file mode 100644
index e784f6e41..000000000
--- a/src/gsttools/qgstreamerbushelper_p.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/****************************************************************************
-**
-** 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 QGSTREAMERBUSHELPER_P_H
-#define QGSTREAMERBUSHELPER_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 <private/qgsttools_global_p.h>
-#include <QObject>
-
-#include "qgstreamermessage_p.h"
-
-#include <gst/gst.h>
-
-QT_BEGIN_NAMESPACE
-
-class QGstreamerSyncMessageFilter {
-public:
- //returns true if message was processed and should be dropped, false otherwise
- virtual bool processSyncMessage(const QGstreamerMessage &message) = 0;
-};
-#define QGstreamerSyncMessageFilter_iid "org.qt-project.qt.gstreamersyncmessagefilter/5.0"
-Q_DECLARE_INTERFACE(QGstreamerSyncMessageFilter, QGstreamerSyncMessageFilter_iid)
-
-
-class QGstreamerBusMessageFilter {
-public:
- //returns true if message was processed and should be dropped, false otherwise
- virtual bool processBusMessage(const QGstreamerMessage &message) = 0;
-};
-#define QGstreamerBusMessageFilter_iid "org.qt-project.qt.gstreamerbusmessagefilter/5.0"
-Q_DECLARE_INTERFACE(QGstreamerBusMessageFilter, QGstreamerBusMessageFilter_iid)
-
-
-class QGstreamerBusHelperPrivate;
-
-class Q_GSTTOOLS_EXPORT QGstreamerBusHelper : public QObject
-{
- Q_OBJECT
- friend class QGstreamerBusHelperPrivate;
-
-public:
- QGstreamerBusHelper(GstBus* bus, QObject* parent = 0);
- ~QGstreamerBusHelper();
-
- void installMessageFilter(QObject *filter);
- void removeMessageFilter(QObject *filter);
-
-signals:
- void message(QGstreamerMessage const& message);
-
-private:
- QGstreamerBusHelperPrivate *d = nullptr;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/gsttools/qgstreamermessage.cpp b/src/gsttools/qgstreamermessage.cpp
deleted file mode 100644
index 7191565e1..000000000
--- a/src/gsttools/qgstreamermessage.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#include <gst/gst.h>
-
-#include "qgstreamermessage_p.h"
-
-QT_BEGIN_NAMESPACE
-
-static int wuchi = qRegisterMetaType<QGstreamerMessage>();
-
-
-/*!
- \class QGstreamerMessage
- \internal
-*/
-
-QGstreamerMessage::QGstreamerMessage(GstMessage* message):
- m_message(message)
-{
- gst_message_ref(m_message);
-}
-
-QGstreamerMessage::QGstreamerMessage(QGstreamerMessage const& m):
- m_message(m.m_message)
-{
- gst_message_ref(m_message);
-}
-
-
-QGstreamerMessage::~QGstreamerMessage()
-{
- if (m_message != 0)
- gst_message_unref(m_message);
-}
-
-GstMessage* QGstreamerMessage::rawMessage() const
-{
- return m_message;
-}
-
-QGstreamerMessage& QGstreamerMessage::operator=(QGstreamerMessage const& rhs)
-{
- if (rhs.m_message != m_message) {
- if (rhs.m_message != 0)
- gst_message_ref(rhs.m_message);
-
- if (m_message != 0)
- gst_message_unref(m_message);
-
- m_message = rhs.m_message;
- }
-
- return *this;
-}
-
-QT_END_NAMESPACE
diff --git a/src/gsttools/qgstreamermessage_p.h b/src/gsttools/qgstreamermessage_p.h
deleted file mode 100644
index baeecc360..000000000
--- a/src/gsttools/qgstreamermessage_p.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/****************************************************************************
-**
-** 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 QGSTREAMERMESSAGE_P_H
-#define QGSTREAMERMESSAGE_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 <private/qgsttools_global_p.h>
-#include <QMetaType>
-
-#include <gst/gst.h>
-
-QT_BEGIN_NAMESPACE
-
-// Required for QDoc workaround
-class QString;
-
-class Q_GSTTOOLS_EXPORT QGstreamerMessage
-{
-public:
- QGstreamerMessage() = default;
- QGstreamerMessage(GstMessage* message);
- QGstreamerMessage(QGstreamerMessage const& m);
- ~QGstreamerMessage();
-
- GstMessage* rawMessage() const;
-
- QGstreamerMessage& operator=(QGstreamerMessage const& rhs);
-
-private:
- GstMessage* m_message = nullptr;
-};
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(QGstreamerMessage);
-
-#endif
diff --git a/src/gsttools/qgstreamerplayercontrol.cpp b/src/gsttools/qgstreamerplayercontrol.cpp
deleted file mode 100644
index 689467db8..000000000
--- a/src/gsttools/qgstreamerplayercontrol.cpp
+++ /dev/null
@@ -1,613 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#include <private/qgstreamerplayercontrol_p.h>
-#include <private/qgstreamerplayersession_p.h>
-
-#include <private/qmediaplaylistnavigator_p.h>
-#include <private/qmediaresourcepolicy_p.h>
-#include <private/qmediaresourceset_p.h>
-
-#include <QtCore/qdir.h>
-#include <QtCore/qsocketnotifier.h>
-#include <QtCore/qurl.h>
-#include <QtCore/qdebug.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-//#define DEBUG_PLAYBIN
-
-QT_BEGIN_NAMESPACE
-
-QGstreamerPlayerControl::QGstreamerPlayerControl(QGstreamerPlayerSession *session, QObject *parent)
- : QMediaPlayerControl(parent)
- , m_session(session)
-{
- m_resources = QMediaResourcePolicy::createResourceSet<QMediaPlayerResourceSetInterface>();
- Q_ASSERT(m_resources);
-
- connect(m_session, &QGstreamerPlayerSession::positionChanged, this, &QGstreamerPlayerControl::positionChanged);
- connect(m_session, &QGstreamerPlayerSession::durationChanged, this, &QGstreamerPlayerControl::durationChanged);
- connect(m_session, &QGstreamerPlayerSession::mutedStateChanged, this, &QGstreamerPlayerControl::mutedChanged);
- connect(m_session, &QGstreamerPlayerSession::volumeChanged, this, &QGstreamerPlayerControl::volumeChanged);
- connect(m_session, &QGstreamerPlayerSession::stateChanged, this, &QGstreamerPlayerControl::updateSessionState);
- connect(m_session, &QGstreamerPlayerSession::bufferingProgressChanged, this, &QGstreamerPlayerControl::setBufferProgress);
- connect(m_session, &QGstreamerPlayerSession::playbackFinished, this, &QGstreamerPlayerControl::processEOS);
- connect(m_session, &QGstreamerPlayerSession::audioAvailableChanged, this, &QGstreamerPlayerControl::audioAvailableChanged);
- connect(m_session, &QGstreamerPlayerSession::videoAvailableChanged, this, &QGstreamerPlayerControl::videoAvailableChanged);
- connect(m_session, &QGstreamerPlayerSession::seekableChanged, this, &QGstreamerPlayerControl::seekableChanged);
- connect(m_session, &QGstreamerPlayerSession::error, this, &QGstreamerPlayerControl::error);
- connect(m_session, &QGstreamerPlayerSession::invalidMedia, this, &QGstreamerPlayerControl::handleInvalidMedia);
- connect(m_session, &QGstreamerPlayerSession::playbackRateChanged, this, &QGstreamerPlayerControl::playbackRateChanged);
-
- connect(m_resources, &QMediaPlayerResourceSetInterface::resourcesGranted, this, &QGstreamerPlayerControl::handleResourcesGranted);
- //denied signal should be queued to have correct state update process,
- //since in playOrPause, when acquire is call on resource set, it may trigger a resourcesDenied signal immediately,
- //so handleResourcesDenied should be processed later, otherwise it will be overwritten by state update later in playOrPause.
- connect(m_resources, &QMediaPlayerResourceSetInterface::resourcesDenied,
- this, &QGstreamerPlayerControl::handleResourcesDenied, Qt::QueuedConnection);
- connect(m_resources, &QMediaPlayerResourceSetInterface::resourcesLost, this, &QGstreamerPlayerControl::handleResourcesLost);
-}
-
-QGstreamerPlayerControl::~QGstreamerPlayerControl()
-{
- QMediaResourcePolicy::destroyResourceSet(m_resources);
-}
-
-QMediaPlayerResourceSetInterface* QGstreamerPlayerControl::resources() const
-{
- return m_resources;
-}
-
-qint64 QGstreamerPlayerControl::position() const
-{
- if (m_mediaStatus == QMediaPlayer::EndOfMedia)
- return m_session->duration();
-
- return m_pendingSeekPosition != -1 ? m_pendingSeekPosition : m_session->position();
-}
-
-qint64 QGstreamerPlayerControl::duration() const
-{
- return m_session->duration();
-}
-
-QMediaPlayer::State QGstreamerPlayerControl::state() const
-{
- return m_currentState;
-}
-
-QMediaPlayer::MediaStatus QGstreamerPlayerControl::mediaStatus() const
-{
- return m_mediaStatus;
-}
-
-int QGstreamerPlayerControl::bufferStatus() const
-{
- if (m_bufferProgress == -1) {
- return m_session->state() == QMediaPlayer::StoppedState ? 0 : 100;
- } else
- return m_bufferProgress;
-}
-
-int QGstreamerPlayerControl::volume() const
-{
- return m_session->volume();
-}
-
-bool QGstreamerPlayerControl::isMuted() const
-{
- return m_session->isMuted();
-}
-
-bool QGstreamerPlayerControl::isSeekable() const
-{
- return m_session->isSeekable();
-}
-
-QMediaTimeRange QGstreamerPlayerControl::availablePlaybackRanges() const
-{
- return m_session->availablePlaybackRanges();
-}
-
-qreal QGstreamerPlayerControl::playbackRate() const
-{
- return m_session->playbackRate();
-}
-
-void QGstreamerPlayerControl::setPlaybackRate(qreal rate)
-{
- m_session->setPlaybackRate(rate);
-}
-
-void QGstreamerPlayerControl::setPosition(qint64 pos)
-{
-#ifdef DEBUG_PLAYBIN
- qDebug() << Q_FUNC_INFO << pos/1000.0;
-#endif
-
- pushState();
-
- if (m_mediaStatus == QMediaPlayer::EndOfMedia) {
- m_mediaStatus = QMediaPlayer::LoadedMedia;
- }
-
- if (m_currentState == QMediaPlayer::StoppedState) {
- m_pendingSeekPosition = pos;
- emit positionChanged(m_pendingSeekPosition);
- } else if (m_session->isSeekable()) {
- m_session->showPrerollFrames(true);
- m_session->seek(pos);
- m_pendingSeekPosition = -1;
- } else if (m_session->state() == QMediaPlayer::StoppedState) {
- m_pendingSeekPosition = pos;
- emit positionChanged(m_pendingSeekPosition);
- } else if (m_pendingSeekPosition != -1) {
- m_pendingSeekPosition = -1;
- emit positionChanged(m_pendingSeekPosition);
- }
-
- popAndNotifyState();
-}
-
-void QGstreamerPlayerControl::play()
-{
-#ifdef DEBUG_PLAYBIN
- qDebug() << Q_FUNC_INFO;
-#endif
- //m_userRequestedState is needed to know that we need to resume playback when resource-policy
- //regranted the resources after lost, since m_currentState will become paused when resources are
- //lost.
- m_userRequestedState = QMediaPlayer::PlayingState;
- playOrPause(QMediaPlayer::PlayingState);
-}
-
-void QGstreamerPlayerControl::pause()
-{
-#ifdef DEBUG_PLAYBIN
- qDebug() << Q_FUNC_INFO;
-#endif
- m_userRequestedState = QMediaPlayer::PausedState;
- // If the playback has not been started yet but pause is requested.
- // Seek to the beginning to show first frame.
- if (m_pendingSeekPosition == -1 && m_session->position() == 0)
- m_pendingSeekPosition = 0;
-
- playOrPause(QMediaPlayer::PausedState);
-}
-
-void QGstreamerPlayerControl::playOrPause(QMediaPlayer::State newState)
-{
- if (m_mediaStatus == QMediaPlayer::NoMedia)
- return;
-
- pushState();
-
- if (m_setMediaPending) {
- m_mediaStatus = QMediaPlayer::LoadingMedia;
- setMedia(m_currentResource, m_stream);
- }
-
- if (m_mediaStatus == QMediaPlayer::EndOfMedia && m_pendingSeekPosition == -1) {
- m_pendingSeekPosition = 0;
- }
-
- if (!m_resources->isGranted())
- m_resources->acquire();
-
- if (m_resources->isGranted()) {
- // show prerolled frame if switching from stopped state
- if (m_pendingSeekPosition == -1) {
- m_session->showPrerollFrames(true);
- } else if (m_session->state() == QMediaPlayer::StoppedState) {
- // Don't evaluate the next two conditions.
- } else if (m_session->isSeekable()) {
- m_session->pause();
- m_session->showPrerollFrames(true);
- m_session->seek(m_pendingSeekPosition);
- m_pendingSeekPosition = -1;
- } else {
- m_pendingSeekPosition = -1;
- }
-
- bool ok = false;
-
- //To prevent displaying the first video frame when playback is resumed
- //the pipeline is paused instead of playing, seeked to requested position,
- //and after seeking is finished (position updated) playback is restarted
- //with show-preroll-frame enabled.
- if (newState == QMediaPlayer::PlayingState && m_pendingSeekPosition == -1)
- ok = m_session->play();
- else
- ok = m_session->pause();
-
- if (!ok)
- newState = QMediaPlayer::StoppedState;
- }
-
- if (m_mediaStatus == QMediaPlayer::InvalidMedia)
- m_mediaStatus = QMediaPlayer::LoadingMedia;
-
- m_currentState = newState;
-
- if (m_mediaStatus == QMediaPlayer::EndOfMedia || m_mediaStatus == QMediaPlayer::LoadedMedia) {
- if (m_bufferProgress == -1 || m_bufferProgress == 100)
- m_mediaStatus = QMediaPlayer::BufferedMedia;
- else
- m_mediaStatus = QMediaPlayer::BufferingMedia;
- }
-
- popAndNotifyState();
-
- emit positionChanged(position());
-}
-
-void QGstreamerPlayerControl::stop()
-{
-#ifdef DEBUG_PLAYBIN
- qDebug() << Q_FUNC_INFO;
-#endif
- m_userRequestedState = QMediaPlayer::StoppedState;
-
- pushState();
-
- if (m_currentState != QMediaPlayer::StoppedState) {
- m_currentState = QMediaPlayer::StoppedState;
- m_session->showPrerollFrames(false); // stop showing prerolled frames in stop state
- // Since gst is not going to send GST_STATE_PAUSED
- // when pipeline is already paused,
- // needs to update media status directly.
- if (m_session->state() == QMediaPlayer::PausedState)
- updateMediaStatus();
- else if (m_resources->isGranted())
- m_session->pause();
-
- if (m_mediaStatus != QMediaPlayer::EndOfMedia) {
- m_pendingSeekPosition = 0;
- emit positionChanged(position());
- }
- }
-
- popAndNotifyState();
-}
-
-void QGstreamerPlayerControl::setVolume(int volume)
-{
- m_session->setVolume(volume);
-}
-
-void QGstreamerPlayerControl::setMuted(bool muted)
-{
- m_session->setMuted(muted);
-}
-
-QMediaContent QGstreamerPlayerControl::media() const
-{
- return m_currentResource;
-}
-
-const QIODevice *QGstreamerPlayerControl::mediaStream() const
-{
- return m_stream;
-}
-
-void QGstreamerPlayerControl::setMedia(const QMediaContent &content, QIODevice *stream)
-{
-#ifdef DEBUG_PLAYBIN
- qDebug() << Q_FUNC_INFO;
-#endif
-
- pushState();
-
- m_currentState = QMediaPlayer::StoppedState;
- QMediaContent oldMedia = m_currentResource;
- m_pendingSeekPosition = -1;
- m_session->showPrerollFrames(false); // do not show prerolled frames until pause() or play() explicitly called
- m_setMediaPending = false;
-
- if (!content.isNull() || stream) {
- if (!m_resources->isGranted())
- m_resources->acquire();
- } else {
- m_resources->release();
- }
-
- m_session->stop();
-
- bool userStreamValid = false;
-
- if (m_bufferProgress != -1) {
- m_bufferProgress = -1;
- emit bufferStatusChanged(0);
- }
-
- m_currentResource = content;
- m_stream = stream;
-
- QNetworkRequest request = content.request();
-
- if (m_stream)
- userStreamValid = stream->isOpen() && m_stream->isReadable();
-
-#if !QT_CONFIG(gstreamer_app)
- m_session->loadFromUri(request);
-#else
- if (m_stream) {
- if (userStreamValid){
- m_session->loadFromStream(request, m_stream);
- } else {
- m_mediaStatus = QMediaPlayer::InvalidMedia;
- emit error(QMediaPlayer::FormatError, tr("Attempting to play invalid user stream"));
- if (m_currentState != QMediaPlayer::PlayingState)
- m_resources->release();
- popAndNotifyState();
- return;
- }
- } else
- m_session->loadFromUri(request);
-#endif
-
-#if QT_CONFIG(gstreamer_app)
- if (!request.url().isEmpty() || userStreamValid) {
-#else
- if (!request.url().isEmpty()) {
-#endif
- m_mediaStatus = QMediaPlayer::LoadingMedia;
- m_session->pause();
- } else {
- m_mediaStatus = QMediaPlayer::NoMedia;
- setBufferProgress(0);
- }
-
- if (m_currentResource != oldMedia)
- emit mediaChanged(m_currentResource);
-
- emit positionChanged(position());
-
- if (content.isNull() && !stream)
- m_resources->release();
-
- popAndNotifyState();
-}
-
-void QGstreamerPlayerControl::setVideoOutput(QObject *output)
-{
- m_session->setVideoRenderer(output);
-}
-
-bool QGstreamerPlayerControl::isAudioAvailable() const
-{
- return m_session->isAudioAvailable();
-}
-
-bool QGstreamerPlayerControl::isVideoAvailable() const
-{
- return m_session->isVideoAvailable();
-}
-
-void QGstreamerPlayerControl::updateSessionState(QMediaPlayer::State state)
-{
- pushState();
-
- if (state == QMediaPlayer::StoppedState) {
- m_session->showPrerollFrames(false);
- m_currentState = QMediaPlayer::StoppedState;
- }
-
- if (state == QMediaPlayer::PausedState && m_currentState != QMediaPlayer::StoppedState) {
- if (m_pendingSeekPosition != -1 && m_session->isSeekable()) {
- m_session->showPrerollFrames(true);
- m_session->seek(m_pendingSeekPosition);
- }
- m_pendingSeekPosition = -1;
-
- if (m_currentState == QMediaPlayer::PlayingState) {
- if (m_bufferProgress == -1 || m_bufferProgress == 100)
- m_session->play();
- }
- }
-
- updateMediaStatus();
-
- popAndNotifyState();
-}
-
-void QGstreamerPlayerControl::updateMediaStatus()
-{
- //EndOfMedia status should be kept, until reset by pause, play or setMedia
- if (m_mediaStatus == QMediaPlayer::EndOfMedia)
- return;
-
- pushState();
- QMediaPlayer::MediaStatus oldStatus = m_mediaStatus;
-
- switch (m_session->state()) {
- case QMediaPlayer::StoppedState:
- if (m_currentResource.isNull())
- m_mediaStatus = QMediaPlayer::NoMedia;
- else if (oldStatus != QMediaPlayer::InvalidMedia)
- m_mediaStatus = QMediaPlayer::LoadingMedia;
- break;
-
- case QMediaPlayer::PlayingState:
- case QMediaPlayer::PausedState:
- if (m_currentState == QMediaPlayer::StoppedState) {
- m_mediaStatus = QMediaPlayer::LoadedMedia;
- } else {
- if (m_bufferProgress == -1 || m_bufferProgress == 100)
- m_mediaStatus = QMediaPlayer::BufferedMedia;
- else
- m_mediaStatus = QMediaPlayer::StalledMedia;
- }
- break;
- }
-
- if (m_currentState == QMediaPlayer::PlayingState && !m_resources->isGranted())
- m_mediaStatus = QMediaPlayer::StalledMedia;
-
- popAndNotifyState();
-}
-
-void QGstreamerPlayerControl::processEOS()
-{
- pushState();
- m_mediaStatus = QMediaPlayer::EndOfMedia;
- emit positionChanged(position());
- m_session->endOfMediaReset();
-
- if (m_currentState != QMediaPlayer::StoppedState) {
- m_currentState = QMediaPlayer::StoppedState;
- m_session->showPrerollFrames(false); // stop showing prerolled frames in stop state
- }
-
- popAndNotifyState();
-}
-
-void QGstreamerPlayerControl::setBufferProgress(int progress)
-{
- if (m_bufferProgress == progress || m_mediaStatus == QMediaPlayer::NoMedia)
- return;
-
-#ifdef DEBUG_PLAYBIN
- qDebug() << Q_FUNC_INFO << progress;
-#endif
- m_bufferProgress = progress;
-
- if (m_resources->isGranted()) {
- if (m_currentState == QMediaPlayer::PlayingState &&
- m_bufferProgress == 100 &&
- m_session->state() != QMediaPlayer::PlayingState)
- m_session->play();
-
- if (!m_session->isLiveSource() && m_bufferProgress < 100 &&
- (m_session->state() == QMediaPlayer::PlayingState ||
- m_session->pendingState() == QMediaPlayer::PlayingState))
- m_session->pause();
- }
-
- updateMediaStatus();
-
- emit bufferStatusChanged(m_bufferProgress);
-}
-
-void QGstreamerPlayerControl::handleInvalidMedia()
-{
- pushState();
- m_mediaStatus = QMediaPlayer::InvalidMedia;
- m_currentState = QMediaPlayer::StoppedState;
- m_setMediaPending = true;
- popAndNotifyState();
-}
-
-void QGstreamerPlayerControl::handleResourcesGranted()
-{
- pushState();
-
- //This may be triggered when there is an auto resume
- //from resource-policy, we need to take action according to m_userRequestedState
- //rather than m_currentState
- m_currentState = m_userRequestedState;
- if (m_currentState != QMediaPlayer::StoppedState)
- playOrPause(m_currentState);
- else
- updateMediaStatus();
-
- popAndNotifyState();
-}
-
-void QGstreamerPlayerControl::handleResourcesLost()
-{
- //on resource lost the pipeline should be paused
- //player status is changed to paused
- pushState();
- QMediaPlayer::State oldState = m_currentState;
-
- m_session->pause();
-
- if (oldState != QMediaPlayer::StoppedState )
- m_currentState = QMediaPlayer::PausedState;
-
- popAndNotifyState();
-}
-
-void QGstreamerPlayerControl::handleResourcesDenied()
-{
- //on resource denied the pipeline should stay paused
- //player status is changed to paused
- pushState();
-
- if (m_currentState != QMediaPlayer::StoppedState )
- m_currentState = QMediaPlayer::PausedState;
-
- popAndNotifyState();
-}
-
-void QGstreamerPlayerControl::pushState()
-{
- m_stateStack.push(m_currentState);
- m_mediaStatusStack.push(m_mediaStatus);
-}
-
-void QGstreamerPlayerControl::popAndNotifyState()
-{
- Q_ASSERT(!m_stateStack.isEmpty());
-
- QMediaPlayer::State oldState = m_stateStack.pop();
- QMediaPlayer::MediaStatus oldMediaStatus = m_mediaStatusStack.pop();
-
- if (m_stateStack.isEmpty()) {
- if (m_mediaStatus != oldMediaStatus) {
-#ifdef DEBUG_PLAYBIN
- qDebug() << "Media status changed:" << m_mediaStatus;
-#endif
- emit mediaStatusChanged(m_mediaStatus);
- }
-
- if (m_currentState != oldState) {
-#ifdef DEBUG_PLAYBIN
- qDebug() << "State changed:" << m_currentState;
-#endif
- emit stateChanged(m_currentState);
- }
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/gsttools/qgstreamerplayercontrol_p.h b/src/gsttools/qgstreamerplayercontrol_p.h
deleted file mode 100644
index ef94df925..000000000
--- a/src/gsttools/qgstreamerplayercontrol_p.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/****************************************************************************
-**
-** 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 = nullptr;
- QMediaPlayer::State m_userRequestedState = QMediaPlayer::StoppedState;
- QMediaPlayer::State m_currentState = QMediaPlayer::StoppedState;
- QMediaPlayer::MediaStatus m_mediaStatus = QMediaPlayer::NoMedia;
- QStack<QMediaPlayer::State> m_stateStack;
- QStack<QMediaPlayer::MediaStatus> m_mediaStatusStack;
-
- int m_bufferProgress = -1;
- qint64 m_pendingSeekPosition = -1;
- bool m_setMediaPending = false;
- QMediaContent m_currentResource;
- QIODevice *m_stream = nullptr;
-
- QMediaPlayerResourceSetInterface *m_resources = nullptr;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/gsttools/qgstreamerplayersession.cpp b/src/gsttools/qgstreamerplayersession.cpp
deleted file mode 100644
index adf11b022..000000000
--- a/src/gsttools/qgstreamerplayersession.cpp
+++ /dev/null
@@ -1,2016 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#include <private/qgstreamerplayersession_p.h>
-#include <private/qgstreamerbushelper_p.h>
-
-#include <private/qgstreameraudioprobecontrol_p.h>
-#include <private/qgstreamervideoprobecontrol_p.h>
-#include <private/qgstreamervideorendererinterface_p.h>
-#if !GST_CHECK_VERSION(1,0,0)
-#include <private/gstvideoconnector_p.h>
-#endif
-#include <private/qgstutils_p.h>
-#include <private/qvideosurfacegstsink_p.h>
-
-#include <gst/gstvalue.h>
-#include <gst/base/gstbasesrc.h>
-
-#include <QtMultimedia/qmediametadata.h>
-#include <QtCore/qdatetime.h>
-#include <QtCore/qdebug.h>
-#include <QtCore/qsize.h>
-#include <QtCore/qtimer.h>
-#include <QtCore/qdebug.h>
-#include <QtCore/qdir.h>
-#include <QtCore/qstandardpaths.h>
-#include <qvideorenderercontrol.h>
-#include <QUrlQuery>
-
-//#define DEBUG_PLAYBIN
-
-QT_BEGIN_NAMESPACE
-
-static bool usePlaybinVolume()
-{
- static enum { Yes, No, Unknown } status = Unknown;
- if (status == Unknown) {
- QByteArray v = qgetenv("QT_GSTREAMER_USE_PLAYBIN_VOLUME");
- bool value = !v.isEmpty() && v != "0" && v != "false";
- if (value)
- status = Yes;
- else
- status = No;
- }
- return status == Yes;
-}
-
-typedef enum {
- GST_PLAY_FLAG_VIDEO = 0x00000001,
- GST_PLAY_FLAG_AUDIO = 0x00000002,
- GST_PLAY_FLAG_TEXT = 0x00000004,
- GST_PLAY_FLAG_VIS = 0x00000008,
- GST_PLAY_FLAG_SOFT_VOLUME = 0x00000010,
- GST_PLAY_FLAG_NATIVE_AUDIO = 0x00000020,
- GST_PLAY_FLAG_NATIVE_VIDEO = 0x00000040,
- GST_PLAY_FLAG_DOWNLOAD = 0x00000080,
- GST_PLAY_FLAG_BUFFERING = 0x000000100
-} GstPlayFlags;
-
-#if !GST_CHECK_VERSION(1,0,0)
-#define DEFAULT_RAW_CAPS \
- "video/x-raw-yuv; " \
- "video/x-raw-rgb; " \
- "video/x-raw-gray; " \
- "video/x-surface; " \
- "video/x-android-buffer; " \
- "audio/x-raw-int; " \
- "audio/x-raw-float; " \
- "text/plain; " \
- "text/x-pango-markup; " \
- "video/x-dvd-subpicture; " \
- "subpicture/x-pgs"
-
-static GstStaticCaps static_RawCaps = GST_STATIC_CAPS(DEFAULT_RAW_CAPS);
-#endif
-
-QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent)
- : QObject(parent)
-{
- initPlaybin();
-}
-
-void QGstreamerPlayerSession::initPlaybin()
-{
- m_playbin = gst_element_factory_make(QT_GSTREAMER_PLAYBIN_ELEMENT_NAME, nullptr);
- if (m_playbin) {
- //GST_PLAY_FLAG_NATIVE_VIDEO omits configuration of ffmpegcolorspace and videoscale,
- //since those elements are included in the video output bin when necessary.
- int flags = GST_PLAY_FLAG_VIDEO | GST_PLAY_FLAG_AUDIO;
- QByteArray envFlags = qgetenv("QT_GSTREAMER_PLAYBIN_FLAGS");
- if (!envFlags.isEmpty()) {
- flags |= envFlags.toInt();
-#if !GST_CHECK_VERSION(1,0,0)
- } else {
- flags |= GST_PLAY_FLAG_NATIVE_VIDEO;
-#endif
- }
- g_object_set(G_OBJECT(m_playbin), "flags", flags, nullptr);
-
- const QByteArray envAudioSink = qgetenv("QT_GSTREAMER_PLAYBIN_AUDIOSINK");
- GstElement *audioSink = gst_element_factory_make(envAudioSink.isEmpty() ? "autoaudiosink" : envAudioSink, "audiosink");
- if (audioSink) {
- if (usePlaybinVolume()) {
- m_audioSink = audioSink;
- m_volumeElement = m_playbin;
- } else {
- m_volumeElement = gst_element_factory_make("volume", "volumeelement");
- if (m_volumeElement) {
- m_audioSink = gst_bin_new("audio-output-bin");
-
- gst_bin_add_many(GST_BIN(m_audioSink), m_volumeElement, audioSink, nullptr);
- gst_element_link(m_volumeElement, audioSink);
-
- GstPad *pad = gst_element_get_static_pad(m_volumeElement, "sink");
- gst_element_add_pad(GST_ELEMENT(m_audioSink), gst_ghost_pad_new("sink", pad));
- gst_object_unref(GST_OBJECT(pad));
- } else {
- m_audioSink = audioSink;
- m_volumeElement = m_playbin;
- }
- }
-
- g_object_set(G_OBJECT(m_playbin), "audio-sink", m_audioSink, nullptr);
- addAudioBufferProbe();
- }
- }
-
-#if GST_CHECK_VERSION(1,0,0)
- static const auto convDesc = qEnvironmentVariable("QT_GSTREAMER_PLAYBIN_CONVERT");
- GError *err = nullptr;
- auto convPipeline = !convDesc.isEmpty() ? convDesc.toLatin1().constData() : "identity";
- auto convElement = gst_parse_launch(convPipeline, &err);
- if (err) {
- qWarning() << "Error:" << convDesc << ":" << QLatin1String(err->message);
- g_clear_error(&err);
- }
- m_videoIdentity = convElement;
-#else
- m_videoIdentity = GST_ELEMENT(g_object_new(gst_video_connector_get_type(), 0)); // floating ref
- g_signal_connect(G_OBJECT(m_videoIdentity), "connection-failed", G_CALLBACK(insertColorSpaceElement), (gpointer)this);
- m_colorSpace = gst_element_factory_make(QT_GSTREAMER_COLORCONVERSION_ELEMENT_NAME, "ffmpegcolorspace-vo");
-
- // might not get a parent, take ownership to avoid leak
- qt_gst_object_ref_sink(GST_OBJECT(m_colorSpace));
-#endif
-
- m_nullVideoSink = gst_element_factory_make("fakesink", nullptr);
- g_object_set(G_OBJECT(m_nullVideoSink), "sync", true, nullptr);
- gst_object_ref(GST_OBJECT(m_nullVideoSink));
-
- m_videoOutputBin = gst_bin_new("video-output-bin");
- // might not get a parent, take ownership to avoid leak
- qt_gst_object_ref_sink(GST_OBJECT(m_videoOutputBin));
-
- GstElement *videoOutputSink = m_videoIdentity;
-#if QT_CONFIG(gstreamer_gl)
- if (QGstUtils::useOpenGL()) {
- videoOutputSink = gst_element_factory_make("glupload", nullptr);
- GstElement *colorConvert = gst_element_factory_make("glcolorconvert", nullptr);
- gst_bin_add_many(GST_BIN(m_videoOutputBin), videoOutputSink, colorConvert, m_videoIdentity, m_nullVideoSink, nullptr);
- gst_element_link_many(videoOutputSink, colorConvert, m_videoIdentity, nullptr);
- } else {
- gst_bin_add_many(GST_BIN(m_videoOutputBin), m_videoIdentity, m_nullVideoSink, nullptr);
- }
-#else
- gst_bin_add_many(GST_BIN(m_videoOutputBin), m_videoIdentity, m_nullVideoSink, nullptr);
-#endif
- gst_element_link(m_videoIdentity, m_nullVideoSink);
-
- m_videoSink = m_nullVideoSink;
-
- // add ghostpads
- GstPad *pad = gst_element_get_static_pad(videoOutputSink, "sink");
- gst_element_add_pad(GST_ELEMENT(m_videoOutputBin), gst_ghost_pad_new("sink", pad));
- gst_object_unref(GST_OBJECT(pad));
-
- if (m_playbin != 0) {
- // Sort out messages
- setBus(gst_element_get_bus(m_playbin));
-
- g_object_set(G_OBJECT(m_playbin), "video-sink", m_videoOutputBin, nullptr);
-
- g_signal_connect(G_OBJECT(m_playbin), "notify::source", G_CALLBACK(playbinNotifySource), this);
- g_signal_connect(G_OBJECT(m_playbin), "element-added", G_CALLBACK(handleElementAdded), this);
-
- if (usePlaybinVolume()) {
- updateVolume();
- updateMuted();
- g_signal_connect(G_OBJECT(m_playbin), "notify::volume", G_CALLBACK(handleVolumeChange), this);
- g_signal_connect(G_OBJECT(m_playbin), "notify::mute", G_CALLBACK(handleMutedChange), this);
- }
-
- g_signal_connect(G_OBJECT(m_playbin), "video-changed", G_CALLBACK(handleStreamsChange), this);
- g_signal_connect(G_OBJECT(m_playbin), "audio-changed", G_CALLBACK(handleStreamsChange), this);
- g_signal_connect(G_OBJECT(m_playbin), "text-changed", G_CALLBACK(handleStreamsChange), this);
-
-#if QT_CONFIG(gstreamer_app)
- g_signal_connect(G_OBJECT(m_playbin), "deep-notify::source", G_CALLBACK(configureAppSrcElement), this);
-#endif
-
- m_pipeline = m_playbin;
- gst_object_ref(GST_OBJECT(m_pipeline));
- }
-}
-
-QGstreamerPlayerSession::~QGstreamerPlayerSession()
-{
- if (m_pipeline) {
- stop();
-
- removeVideoBufferProbe();
- removeAudioBufferProbe();
-
- delete m_busHelper;
- m_busHelper = nullptr;
- resetElements();
- }
-}
-
-template <class T>
-static inline void resetGstObject(T *&obj, T *v = nullptr)
-{
- if (obj)
- gst_object_unref(GST_OBJECT(obj));
-
- obj = v;
-}
-
-void QGstreamerPlayerSession::resetElements()
-{
- setBus(nullptr);
- resetGstObject(m_playbin);
- resetGstObject(m_pipeline);
-#if !GST_CHECK_VERSION(1,0,0)
- resetGstObject(m_colorSpace);
-#endif
- resetGstObject(m_nullVideoSink);
- resetGstObject(m_videoOutputBin);
-
- m_audioSink = nullptr;
- m_volumeElement = nullptr;
- m_videoIdentity = nullptr;
- m_pendingVideoSink = nullptr;
- m_videoSink = nullptr;
-}
-
-GstElement *QGstreamerPlayerSession::playbin() const
-{
- return m_playbin;
-}
-
-#if QT_CONFIG(gstreamer_app)
-void QGstreamerPlayerSession::configureAppSrcElement(GObject* object, GObject *orig, GParamSpec *pspec, QGstreamerPlayerSession* self)
-{
- Q_UNUSED(object);
- Q_UNUSED(pspec);
-
- if (!self->appsrc())
- return;
-
- GstElement *appsrc;
- g_object_get(orig, "source", &appsrc, nullptr);
-
- if (!self->appsrc()->setup(appsrc))
- qWarning()<<"Could not setup appsrc element";
-
- g_object_unref(G_OBJECT(appsrc));
-}
-#endif
-
-void QGstreamerPlayerSession::loadFromStream(const QNetworkRequest &request, QIODevice *appSrcStream)
-{
-#if QT_CONFIG(gstreamer_app)
-#ifdef DEBUG_PLAYBIN
- qDebug() << Q_FUNC_INFO;
-#endif
- m_request = request;
- m_duration = 0;
- m_lastPosition = 0;
-
- if (!m_appSrc)
- m_appSrc = new QGstAppSrc(this);
- m_appSrc->setStream(appSrcStream);
-
- if (!parsePipeline() && m_playbin) {
- m_tags.clear();
- emit tagsChanged();
-
- g_object_set(G_OBJECT(m_playbin), "uri", "appsrc://", nullptr);
-
- if (!m_streamTypes.isEmpty()) {
- m_streamProperties.clear();
- m_streamTypes.clear();
-
- emit streamsChanged();
- }
- }
-#endif
-}
-
-void QGstreamerPlayerSession::loadFromUri(const QNetworkRequest &request)
-{
-#ifdef DEBUG_PLAYBIN
- qDebug() << Q_FUNC_INFO << request.url();
-#endif
- m_request = request;
- m_duration = 0;
- m_lastPosition = 0;
-
-#if QT_CONFIG(gstreamer_app)
- if (m_appSrc) {
- m_appSrc->deleteLater();
- m_appSrc = 0;
- }
-#endif
-
- if (!parsePipeline() && m_playbin) {
- m_tags.clear();
- emit tagsChanged();
-
- g_object_set(G_OBJECT(m_playbin), "uri", m_request.url().toEncoded().constData(), nullptr);
-
- if (!m_streamTypes.isEmpty()) {
- m_streamProperties.clear();
- m_streamTypes.clear();
-
- emit streamsChanged();
- }
- }
-}
-
-bool QGstreamerPlayerSession::parsePipeline()
-{
- if (m_request.url().scheme() != QLatin1String("gst-pipeline")) {
- if (!m_playbin) {
- resetElements();
- initPlaybin();
- updateVideoRenderer();
- }
- return false;
- }
-
- // Set current surface to video sink before creating a pipeline.
- auto renderer = qobject_cast<QVideoRendererControl *>(m_videoOutput);
- if (renderer)
- QVideoSurfaceGstSink::setSurface(renderer->surface());
-
- QString url = m_request.url().toString(QUrl::RemoveScheme);
- QString desc = QUrl::fromPercentEncoding(url.toLatin1().constData());
- GError *err = nullptr;
- GstElement *pipeline = gst_parse_launch(desc.toLatin1().constData(), &err);
- if (err) {
- auto errstr = QLatin1String(err->message);
- qWarning() << "Error:" << desc << ":" << errstr;
- emit error(QMediaPlayer::FormatError, errstr);
- g_clear_error(&err);
- }
-
- return setPipeline(pipeline);
-}
-
-static void gst_foreach(GstIterator *it, const std::function<bool(GstElement *)> &cmp)
-{
-#if GST_CHECK_VERSION(1,0,0)
- GValue value = G_VALUE_INIT;
- while (gst_iterator_next (it, &value) == GST_ITERATOR_OK) {
- auto child = static_cast<GstElement*>(g_value_get_object(&value));
-#else
- GstElement *child = nullptr;
- while (gst_iterator_next(it, reinterpret_cast<gpointer *>(&child)) == GST_ITERATOR_OK) {
-#endif
- if (cmp(child))
- break;
- }
-
- gst_iterator_free(it);
-#if GST_CHECK_VERSION(1,0,0)
- g_value_unset(&value);
-#endif
-}
-
-bool QGstreamerPlayerSession::setPipeline(GstElement *pipeline)
-{
- GstBus *bus = pipeline ? gst_element_get_bus(pipeline) : nullptr;
- if (!bus)
- return false;
-
- if (m_playbin)
- gst_element_set_state(m_playbin, GST_STATE_NULL);
-
- resetElements();
- setBus(bus);
- m_pipeline = pipeline;
-
- if (m_renderer) {
- gst_foreach(gst_bin_iterate_sinks(GST_BIN(pipeline)),
- [this](GstElement *child) {
- if (qstrcmp(GST_OBJECT_NAME(child), "qtvideosink") == 0) {
- m_renderer->setVideoSink(child);
- return true;
- }
- return false;
- });
- }
-
-#if QT_CONFIG(gstreamer_app)
- if (m_appSrc) {
- gst_foreach(gst_bin_iterate_sources(GST_BIN(pipeline)),
- [this](GstElement *child) {
- if (qstrcmp(qt_gst_element_get_factory_name(child), "appsrc") == 0) {
- m_appSrc->setup(child);
- return true;
- }
- return false;
- });
- }
-#endif
-
- emit pipelineChanged();
- return true;
-}
-
-void QGstreamerPlayerSession::setBus(GstBus *bus)
-{
- resetGstObject(m_bus, bus);
-
- // It might still accept gst messages.
- if (m_busHelper)
- m_busHelper->deleteLater();
- m_busHelper = nullptr;
-
- if (!m_bus)
- return;
-
- m_busHelper = new QGstreamerBusHelper(m_bus, this);
- m_busHelper->installMessageFilter(this);
-
- if (m_videoOutput)
- m_busHelper->installMessageFilter(m_videoOutput);
-}
-
-qint64 QGstreamerPlayerSession::duration() const
-{
- return m_duration;
-}
-
-qint64 QGstreamerPlayerSession::position() const
-{
- gint64 position = 0;
-
- if (m_pipeline && qt_gst_element_query_position(m_pipeline, GST_FORMAT_TIME, &position))
- m_lastPosition = position / 1000000;
- return m_lastPosition;
-}
-
-qreal QGstreamerPlayerSession::playbackRate() const
-{
- return m_playbackRate;
-}
-
-void QGstreamerPlayerSession::setPlaybackRate(qreal rate)
-{
-#ifdef DEBUG_PLAYBIN
- qDebug() << Q_FUNC_INFO << rate;
-#endif
- if (!qFuzzyCompare(m_playbackRate, rate)) {
- m_playbackRate = rate;
- if (m_pipeline && m_seekable) {
- qint64 from = rate > 0 ? position() : 0;
- qint64 to = rate > 0 ? duration() : position();
- gst_element_seek(m_pipeline, rate, GST_FORMAT_TIME,
- GstSeekFlags(GST_SEEK_FLAG_FLUSH),
- GST_SEEK_TYPE_SET, from * 1000000,
- GST_SEEK_TYPE_SET, to * 1000000);
- }
- emit playbackRateChanged(m_playbackRate);
- }
-}
-
-QMediaTimeRange QGstreamerPlayerSession::availablePlaybackRanges() const
-{
- QMediaTimeRange ranges;
-
- if (duration() <= 0)
- return ranges;
-
-#if GST_CHECK_VERSION(0, 10, 31)
- //GST_FORMAT_TIME would be more appropriate, but unfortunately it's not supported.
- //with GST_FORMAT_PERCENT media is treated as encoded with constant bitrate.
- GstQuery* query = gst_query_new_buffering(GST_FORMAT_PERCENT);
-
- if (!gst_element_query(m_pipeline, query)) {
- gst_query_unref(query);
- return ranges;
- }
-
- gint64 rangeStart = 0;
- gint64 rangeStop = 0;
- for (guint index = 0; index < gst_query_get_n_buffering_ranges(query); index++) {
- if (gst_query_parse_nth_buffering_range(query, index, &rangeStart, &rangeStop))
- ranges.addInterval(rangeStart * duration() / 100,
- rangeStop * duration() / 100);
- }
-
- gst_query_unref(query);
-#endif
-
- if (ranges.isEmpty() && !isLiveSource() && isSeekable())
- ranges.addInterval(0, duration());
-
-#ifdef DEBUG_PLAYBIN
- qDebug() << ranges;
-#endif
-
- return ranges;
-}
-
-int QGstreamerPlayerSession::activeStream(QMediaStreamsControl::StreamType streamType) const
-{
- int streamNumber = -1;
- if (m_playbin) {
- switch (streamType) {
- case QMediaStreamsControl::AudioStream:
- g_object_get(G_OBJECT(m_playbin), "current-audio", &streamNumber, nullptr);
- break;
- case QMediaStreamsControl::VideoStream:
- g_object_get(G_OBJECT(m_playbin), "current-video", &streamNumber, nullptr);
- break;
- case QMediaStreamsControl::SubPictureStream:
- g_object_get(G_OBJECT(m_playbin), "current-text", &streamNumber, nullptr);
- break;
- default:
- break;
- }
- }
-
- if (streamNumber >= 0)
- streamNumber += m_playbin2StreamOffset.value(streamType,0);
-
- return streamNumber;
-}
-
-void QGstreamerPlayerSession::setActiveStream(QMediaStreamsControl::StreamType streamType, int streamNumber)
-{
-#ifdef DEBUG_PLAYBIN
- qDebug() << Q_FUNC_INFO << streamType << streamNumber;
-#endif
-
- if (streamNumber >= 0)
- streamNumber -= m_playbin2StreamOffset.value(streamType,0);
-
- if (m_playbin) {
- switch (streamType) {
- case QMediaStreamsControl::AudioStream:
- g_object_set(G_OBJECT(m_playbin), "current-audio", streamNumber, nullptr);
- break;
- case QMediaStreamsControl::VideoStream:
- g_object_set(G_OBJECT(m_playbin), "current-video", streamNumber, nullptr);
- break;
- case QMediaStreamsControl::SubPictureStream:
- g_object_set(G_OBJECT(m_playbin), "current-text", streamNumber, nullptr);
- break;
- default:
- break;
- }
- }
-}
-
-int QGstreamerPlayerSession::volume() const
-{
- return m_volume;
-}
-
-bool QGstreamerPlayerSession::isMuted() const
-{
- return m_muted;
-}
-
-bool QGstreamerPlayerSession::isAudioAvailable() const
-{
- return m_audioAvailable;
-}
-
-#if GST_CHECK_VERSION(1,0,0)
-static GstPadProbeReturn block_pad_cb(GstPad *pad, GstPadProbeInfo *info, gpointer user_data)
-#else
-static void block_pad_cb(GstPad *pad, gboolean blocked, gpointer user_data)
-#endif
-{
- Q_UNUSED(pad);
-#if GST_CHECK_VERSION(1,0,0)
- Q_UNUSED(info);
- Q_UNUSED(user_data);
- return GST_PAD_PROBE_OK;
-#else
-#ifdef DEBUG_PLAYBIN
- qDebug() << "block_pad_cb, blocked:" << blocked;
-#endif
- if (blocked && user_data) {
- QGstreamerPlayerSession *session = reinterpret_cast<QGstreamerPlayerSession*>(user_data);
- QMetaObject::invokeMethod(session, "finishVideoOutputChange", Qt::QueuedConnection);
- }
-#endif
-}
-
-void QGstreamerPlayerSession::updateVideoRenderer()
-{
-#ifdef DEBUG_PLAYBIN
- qDebug() << "Video sink has chaged, reload video output";
-#endif
-
- if (m_videoOutput)
- setVideoRenderer(m_videoOutput);
-}
-
-void QGstreamerPlayerSession::setVideoRenderer(QObject *videoOutput)
-{
-#ifdef DEBUG_PLAYBIN
- qDebug() << Q_FUNC_INFO;
-#endif
- if (m_videoOutput != videoOutput) {
- if (m_videoOutput) {
- disconnect(m_videoOutput, SIGNAL(sinkChanged()),
- this, SLOT(updateVideoRenderer()));
- disconnect(m_videoOutput, SIGNAL(readyChanged(bool)),
- this, SLOT(updateVideoRenderer()));
-
- m_busHelper->removeMessageFilter(m_videoOutput);
- }
-
- m_videoOutput = videoOutput;
-
- if (m_videoOutput) {
- connect(m_videoOutput, SIGNAL(sinkChanged()),
- this, SLOT(updateVideoRenderer()));
- connect(m_videoOutput, SIGNAL(readyChanged(bool)),
- this, SLOT(updateVideoRenderer()));
-
- m_busHelper->installMessageFilter(m_videoOutput);
- }
- }
-
- m_renderer = qobject_cast<QGstreamerVideoRendererInterface*>(videoOutput);
- emit rendererChanged();
-
- // No sense to continue if custom pipeline requested.
- if (!m_playbin)
- return;
-
- GstElement *videoSink = 0;
- if (m_renderer && m_renderer->isReady())
- videoSink = m_renderer->videoSink();
-
- if (!videoSink)
- videoSink = m_nullVideoSink;
-
-#ifdef DEBUG_PLAYBIN
- qDebug() << "Set video output:" << videoOutput;
- qDebug() << "Current sink:" << (m_videoSink ? GST_ELEMENT_NAME(m_videoSink) : "") << m_videoSink
- << "pending:" << (m_pendingVideoSink ? GST_ELEMENT_NAME(m_pendingVideoSink) : "") << m_pendingVideoSink
- << "new sink:" << (videoSink ? GST_ELEMENT_NAME(videoSink) : "") << videoSink;
-#endif
-
- if (m_pendingVideoSink == videoSink ||
- (m_pendingVideoSink == 0 && m_videoSink == videoSink)) {
-#ifdef DEBUG_PLAYBIN
- qDebug() << "Video sink has not changed, skip video output reconfiguration";
-#endif
- return;
- }
-
-#ifdef DEBUG_PLAYBIN
- qDebug() << "Reconfigure video output";
-#endif
-
- if (m_state == QMediaPlayer::StoppedState) {
-#ifdef DEBUG_PLAYBIN
- qDebug() << "The pipeline has not started yet, pending state:" << m_pendingState;
-#endif
- //the pipeline has not started yet
- flushVideoProbes();
- m_pendingVideoSink = 0;
- gst_element_set_state(m_videoSink, GST_STATE_NULL);
- gst_element_set_state(m_playbin, GST_STATE_NULL);
-
-#if !GST_CHECK_VERSION(1,0,0)
- if (m_usingColorspaceElement) {
- gst_element_unlink(m_colorSpace, m_videoSink);
- gst_bin_remove(GST_BIN(m_videoOutputBin), m_colorSpace);
- } else {
- gst_element_unlink(m_videoIdentity, m_videoSink);
- }
-#endif
-
- removeVideoBufferProbe();
-
- gst_bin_remove(GST_BIN(m_videoOutputBin), m_videoSink);
-
- m_videoSink = videoSink;
-
- gst_bin_add(GST_BIN(m_videoOutputBin), m_videoSink);
-
- bool linked = gst_element_link(m_videoIdentity, m_videoSink);
-#if !GST_CHECK_VERSION(1,0,0)
- m_usingColorspaceElement = false;
- if (!linked) {
- m_usingColorspaceElement = true;
-#ifdef DEBUG_PLAYBIN
- qDebug() << "Failed to connect video output, inserting the colorspace element.";
-#endif
- gst_bin_add(GST_BIN(m_videoOutputBin), m_colorSpace);
- linked = gst_element_link_many(m_videoIdentity, m_colorSpace, m_videoSink, nullptr);
- }
-#endif
-
- if (!linked)
- qWarning() << "Linking video output element failed";
-
- if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "show-preroll-frame") != 0) {
- gboolean value = m_displayPrerolledFrame;
- g_object_set(G_OBJECT(m_videoSink), "show-preroll-frame", value, nullptr);
- }
-
- addVideoBufferProbe();
-
- switch (m_pendingState) {
- case QMediaPlayer::PausedState:
- gst_element_set_state(m_playbin, GST_STATE_PAUSED);
- break;
- case QMediaPlayer::PlayingState:
- gst_element_set_state(m_playbin, GST_STATE_PLAYING);
- break;
- default:
- break;
- }
-
- resumeVideoProbes();
-
- } else {
- if (m_pendingVideoSink) {
-#ifdef DEBUG_PLAYBIN
- qDebug() << "already waiting for pad to be blocked, just change the pending sink";
-#endif
- m_pendingVideoSink = videoSink;
- return;
- }
-
- m_pendingVideoSink = videoSink;
-
-#ifdef DEBUG_PLAYBIN
- qDebug() << "Blocking the video output pad...";
-#endif
-
- //block pads, async to avoid locking in paused state
- GstPad *srcPad = gst_element_get_static_pad(m_videoIdentity, "src");
-#if GST_CHECK_VERSION(1,0,0)
- this->pad_probe_id = gst_pad_add_probe(srcPad, (GstPadProbeType)(GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_BLOCKING), block_pad_cb, this, nullptr);
-#else
- gst_pad_set_blocked_async(srcPad, true, &block_pad_cb, this);
-#endif
- gst_object_unref(GST_OBJECT(srcPad));
-
- //Unpause the sink to avoid waiting until the buffer is processed
- //while the sink is paused. The pad will be blocked as soon as the current
- //buffer is processed.
- if (m_state == QMediaPlayer::PausedState) {
-#ifdef DEBUG_PLAYBIN
- qDebug() << "Starting video output to avoid blocking in paused state...";
-#endif
- gst_element_set_state(m_videoSink, GST_STATE_PLAYING);
- }
- }
-}
-
-void QGstreamerPlayerSession::finishVideoOutputChange()
-{
- if (!m_playbin || !m_pendingVideoSink)
- return;
-
-#ifdef DEBUG_PLAYBIN
- qDebug() << "finishVideoOutputChange" << m_pendingVideoSink;
-#endif
-
- GstPad *srcPad = gst_element_get_static_pad(m_videoIdentity, "src");
-
- if (!gst_pad_is_blocked(srcPad)) {
- //pad is not blocked, it's possible to swap outputs only in the null state
- qWarning() << "Pad is not blocked yet, could not switch video sink";
- GstState identityElementState = GST_STATE_NULL;
- gst_element_get_state(m_videoIdentity, &identityElementState, nullptr, GST_CLOCK_TIME_NONE);
- if (identityElementState != GST_STATE_NULL) {
- gst_object_unref(GST_OBJECT(srcPad));
- return; //can't change vo yet, received async call from the previous change
- }
- }
-
- if (m_pendingVideoSink == m_videoSink) {
- qDebug() << "Abort, no change";
- //video output was change back to the current one,
- //no need to torment the pipeline, just unblock the pad
- if (gst_pad_is_blocked(srcPad))
-#if GST_CHECK_VERSION(1,0,0)
- gst_pad_remove_probe(srcPad, this->pad_probe_id);
-#else
- gst_pad_set_blocked_async(srcPad, false, &block_pad_cb, 0);
-#endif
-
- m_pendingVideoSink = 0;
- gst_object_unref(GST_OBJECT(srcPad));
- return;
- }
-
-#if !GST_CHECK_VERSION(1,0,0)
- if (m_usingColorspaceElement) {
- gst_element_set_state(m_colorSpace, GST_STATE_NULL);
- gst_element_set_state(m_videoSink, GST_STATE_NULL);
-
- gst_element_unlink(m_colorSpace, m_videoSink);
- gst_bin_remove(GST_BIN(m_videoOutputBin), m_colorSpace);
- } else {
-#else
- {
-#endif
- gst_element_set_state(m_videoSink, GST_STATE_NULL);
- gst_element_unlink(m_videoIdentity, m_videoSink);
- }
-
- removeVideoBufferProbe();
-
- gst_bin_remove(GST_BIN(m_videoOutputBin), m_videoSink);
-
- m_videoSink = m_pendingVideoSink;
- m_pendingVideoSink = 0;
-
- gst_bin_add(GST_BIN(m_videoOutputBin), m_videoSink);
-
- addVideoBufferProbe();
-
- bool linked = gst_element_link(m_videoIdentity, m_videoSink);
-#if !GST_CHECK_VERSION(1,0,0)
- m_usingColorspaceElement = false;
- if (!linked) {
- m_usingColorspaceElement = true;
-#ifdef DEBUG_PLAYBIN
- qDebug() << "Failed to connect video output, inserting the colorspace element.";
-#endif
- gst_bin_add(GST_BIN(m_videoOutputBin), m_colorSpace);
- linked = gst_element_link_many(m_videoIdentity, m_colorSpace, m_videoSink, nullptr);
- }
-#endif
-
- if (!linked)
- qWarning() << "Linking video output element failed";
-
-#ifdef DEBUG_PLAYBIN
- qDebug() << "notify the video connector it has to emit a new segment message...";
-#endif
-
-#if !GST_CHECK_VERSION(1,0,0)
- //it's necessary to send a new segment event just before
- //the first buffer pushed to the new sink
- g_signal_emit_by_name(m_videoIdentity,
- "resend-new-segment",
- true //emit connection-failed signal
- //to have a chance to insert colorspace element
- );
-#endif
-
- GstState state = GST_STATE_VOID_PENDING;
-
- switch (m_pendingState) {
- case QMediaPlayer::StoppedState:
- state = GST_STATE_NULL;
- break;
- case QMediaPlayer::PausedState:
- state = GST_STATE_PAUSED;
- break;
- case QMediaPlayer::PlayingState:
- state = GST_STATE_PLAYING;
- break;
- }
-
-#if !GST_CHECK_VERSION(1,0,0)
- if (m_usingColorspaceElement)
- gst_element_set_state(m_colorSpace, state);
-#endif
-
- gst_element_set_state(m_videoSink, state);
-
- if (state == GST_STATE_NULL)
- flushVideoProbes();
-
- // Set state change that was deferred due the video output
- // change being pending
- gst_element_set_state(m_playbin, state);
-
- if (state != GST_STATE_NULL)
- resumeVideoProbes();
-
- //don't have to wait here, it will unblock eventually
- if (gst_pad_is_blocked(srcPad))
-#if GST_CHECK_VERSION(1,0,0)
- gst_pad_remove_probe(srcPad, this->pad_probe_id);
-#else
- gst_pad_set_blocked_async(srcPad, false, &block_pad_cb, 0);
-#endif
-
- gst_object_unref(GST_OBJECT(srcPad));
-
-}
-
-#if !GST_CHECK_VERSION(1,0,0)
-
-void QGstreamerPlayerSession::insertColorSpaceElement(GstElement *element, gpointer data)
-{
-#ifdef DEBUG_PLAYBIN
- qDebug() << Q_FUNC_INFO;
-#endif
- Q_UNUSED(element);
- QGstreamerPlayerSession* session = reinterpret_cast<QGstreamerPlayerSession*>(data);
-
- if (session->m_usingColorspaceElement)
- return;
- session->m_usingColorspaceElement = true;
-
-#ifdef DEBUG_PLAYBIN
- qDebug() << "Failed to connect video output, inserting the colorspace elemnt.";
- qDebug() << "notify the video connector it has to emit a new segment message...";
-#endif
- //it's necessary to send a new segment event just before
- //the first buffer pushed to the new sink
- g_signal_emit_by_name(session->m_videoIdentity,
- "resend-new-segment",
- false // don't emit connection-failed signal
- );
-
- gst_element_unlink(session->m_videoIdentity, session->m_videoSink);
- gst_bin_add(GST_BIN(session->m_videoOutputBin), session->m_colorSpace);
- gst_element_link_many(session->m_videoIdentity, session->m_colorSpace, session->m_videoSink, nullptr);
-
- GstState state = GST_STATE_VOID_PENDING;
-
- switch (session->m_pendingState) {
- case QMediaPlayer::StoppedState:
- state = GST_STATE_NULL;
- break;
- case QMediaPlayer::PausedState:
- state = GST_STATE_PAUSED;
- break;
- case QMediaPlayer::PlayingState:
- state = GST_STATE_PLAYING;
- break;
- }
-
- gst_element_set_state(session->m_colorSpace, state);
-}
-
-#endif
-
-bool QGstreamerPlayerSession::isVideoAvailable() const
-{
- return m_videoAvailable;
-}
-
-bool QGstreamerPlayerSession::isSeekable() const
-{
- return m_seekable;
-}
-
-bool QGstreamerPlayerSession::play()
-{
-#if GST_CHECK_VERSION(1,0,0)
- static bool dumpDot = qEnvironmentVariableIsSet("GST_DEBUG_DUMP_DOT_DIR");
- if (dumpDot)
- gst_debug_bin_to_dot_file_with_ts(GST_BIN(m_pipeline), GstDebugGraphDetails(GST_DEBUG_GRAPH_SHOW_ALL), "gst.play");
-#endif
-#ifdef DEBUG_PLAYBIN
- qDebug() << Q_FUNC_INFO;
-#endif
-
- m_everPlayed = false;
- if (m_pipeline) {
- m_pendingState = QMediaPlayer::PlayingState;
- if (gst_element_set_state(m_pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
- qWarning() << "GStreamer; Unable to play -" << m_request.url().toString();
- m_pendingState = m_state = QMediaPlayer::StoppedState;
- emit stateChanged(m_state);
- } else {
- resumeVideoProbes();
- return true;
- }
- }
-
- return false;
-}
-
-bool QGstreamerPlayerSession::pause()
-{
-#ifdef DEBUG_PLAYBIN
- qDebug() << Q_FUNC_INFO;
-#endif
- if (m_pipeline) {
- m_pendingState = QMediaPlayer::PausedState;
- if (m_pendingVideoSink != 0)
- return true;
-
- if (gst_element_set_state(m_pipeline, GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE) {
- qWarning() << "GStreamer; Unable to pause -" << m_request.url().toString();
- m_pendingState = m_state = QMediaPlayer::StoppedState;
- emit stateChanged(m_state);
- } else {
- resumeVideoProbes();
- return true;
- }
- }
-
- return false;
-}
-
-void QGstreamerPlayerSession::stop()
-{
-#ifdef DEBUG_PLAYBIN
- qDebug() << Q_FUNC_INFO;
-#endif
- m_everPlayed = false;
- if (m_pipeline) {
-
- if (m_renderer)
- m_renderer->stopRenderer();
-
- flushVideoProbes();
- gst_element_set_state(m_pipeline, GST_STATE_NULL);
-
- m_lastPosition = 0;
- QMediaPlayer::State oldState = m_state;
- m_pendingState = m_state = QMediaPlayer::StoppedState;
-
- finishVideoOutputChange();
-
- //we have to do it here, since gstreamer will not emit bus messages any more
- setSeekable(false);
- if (oldState != m_state)
- emit stateChanged(m_state);
- }
-}
-
-bool QGstreamerPlayerSession::seek(qint64 ms)
-{
-#ifdef DEBUG_PLAYBIN
- qDebug() << Q_FUNC_INFO << ms;
-#endif
- //seek locks when the video output sink is changing and pad is blocked
- if (m_pipeline && !m_pendingVideoSink && m_state != QMediaPlayer::StoppedState && m_seekable) {
- ms = qMax(ms,qint64(0));
- qint64 from = m_playbackRate > 0 ? ms : 0;
- qint64 to = m_playbackRate > 0 ? duration() : ms;
-
- bool isSeeking = gst_element_seek(m_pipeline, m_playbackRate, GST_FORMAT_TIME,
- GstSeekFlags(GST_SEEK_FLAG_FLUSH),
- GST_SEEK_TYPE_SET, from * 1000000,
- GST_SEEK_TYPE_SET, to * 1000000);
- if (isSeeking)
- m_lastPosition = ms;
-
- return isSeeking;
- }
-
- return false;
-}
-
-void QGstreamerPlayerSession::setVolume(int volume)
-{
-#ifdef DEBUG_PLAYBIN
- qDebug() << Q_FUNC_INFO << volume;
-#endif
-
- if (m_volume != volume) {
- m_volume = volume;
-
- if (m_volumeElement)
- g_object_set(G_OBJECT(m_volumeElement), "volume", m_volume / 100.0, nullptr);
-
- emit volumeChanged(m_volume);
- }
-}
-
-void QGstreamerPlayerSession::setMuted(bool muted)
-{
-#ifdef DEBUG_PLAYBIN
- qDebug() << Q_FUNC_INFO << muted;
-#endif
- if (m_muted != muted) {
- m_muted = muted;
-
- if (m_volumeElement)
- g_object_set(G_OBJECT(m_volumeElement), "mute", m_muted ? TRUE : FALSE, nullptr);
-
- emit mutedStateChanged(m_muted);
- }
-}
-
-
-void QGstreamerPlayerSession::setSeekable(bool seekable)
-{
-#ifdef DEBUG_PLAYBIN
- qDebug() << Q_FUNC_INFO << seekable;
-#endif
- if (seekable != m_seekable) {
- m_seekable = seekable;
- emit seekableChanged(m_seekable);
- }
-}
-
-bool QGstreamerPlayerSession::processBusMessage(const QGstreamerMessage &message)
-{
- GstMessage* gm = message.rawMessage();
- if (gm) {
- //tag message comes from elements inside playbin, not from playbin itself
- if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_TAG) {
- GstTagList *tag_list;
- gst_message_parse_tag(gm, &tag_list);
-
- QMap<QByteArray, QVariant> newTags = QGstUtils::gstTagListToMap(tag_list);
- QMap<QByteArray, QVariant>::const_iterator it = newTags.constBegin();
- for ( ; it != newTags.constEnd(); ++it)
- m_tags.insert(it.key(), it.value()); // overwrite existing tags
-
- gst_tag_list_free(tag_list);
-
- emit tagsChanged();
- } else if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_DURATION) {
- updateDuration();
- }
-
-#ifdef DEBUG_PLAYBIN
- if (m_sourceType == MMSSrc && qstrcmp(GST_OBJECT_NAME(GST_MESSAGE_SRC(gm)), "source") == 0) {
- qDebug() << "Message from MMSSrc: " << GST_MESSAGE_TYPE(gm);
- } else if (m_sourceType == RTSPSrc && qstrcmp(GST_OBJECT_NAME(GST_MESSAGE_SRC(gm)), "source") == 0) {
- qDebug() << "Message from RTSPSrc: " << GST_MESSAGE_TYPE(gm);
- } else {
- qDebug() << "Message from " << GST_OBJECT_NAME(GST_MESSAGE_SRC(gm)) << ":" << GST_MESSAGE_TYPE(gm);
- }
-#endif
-
- if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_BUFFERING) {
- int progress = 0;
- gst_message_parse_buffering(gm, &progress);
- emit bufferingProgressChanged(progress);
- }
-
- bool handlePlaybin2 = false;
- if (GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_pipeline)) {
- switch (GST_MESSAGE_TYPE(gm)) {
- case GST_MESSAGE_STATE_CHANGED:
- {
- GstState oldState;
- GstState newState;
- GstState pending;
-
- gst_message_parse_state_changed(gm, &oldState, &newState, &pending);
-
-#ifdef DEBUG_PLAYBIN
- static QStringList states = {
- QStringLiteral("GST_STATE_VOID_PENDING"), QStringLiteral("GST_STATE_NULL"),
- QStringLiteral("GST_STATE_READY"), QStringLiteral("GST_STATE_PAUSED"),
- QStringLiteral("GST_STATE_PLAYING") };
-
- qDebug() << QStringLiteral("state changed: old: %1 new: %2 pending: %3") \
- .arg(states[oldState]) \
- .arg(states[newState]) \
- .arg(states[pending]);
-#endif
-
- switch (newState) {
- case GST_STATE_VOID_PENDING:
- case GST_STATE_NULL:
- setSeekable(false);
- finishVideoOutputChange();
- if (m_state != QMediaPlayer::StoppedState)
- emit stateChanged(m_state = QMediaPlayer::StoppedState);
- break;
- case GST_STATE_READY:
- setSeekable(false);
- if (m_state != QMediaPlayer::StoppedState)
- emit stateChanged(m_state = QMediaPlayer::StoppedState);
- break;
- case GST_STATE_PAUSED:
- {
- QMediaPlayer::State prevState = m_state;
- m_state = QMediaPlayer::PausedState;
-
- //check for seekable
- if (oldState == GST_STATE_READY) {
- if (m_sourceType == SoupHTTPSrc || m_sourceType == MMSSrc) {
- //since udpsrc is a live source, it is not applicable here
- m_everPlayed = true;
- }
-
- getStreamsInfo();
- updateVideoResolutionTag();
-
- //gstreamer doesn't give a reliable indication the duration
- //information is ready, GST_MESSAGE_DURATION is not sent by most elements
- //the duration is queried up to 5 times with increasing delay
- m_durationQueries = 5;
- // This should also update the seekable flag.
- updateDuration();
-
- if (!qFuzzyCompare(m_playbackRate, qreal(1.0))) {
- qreal rate = m_playbackRate;
- m_playbackRate = 1.0;
- setPlaybackRate(rate);
- }
- }
-
- if (m_state != prevState)
- emit stateChanged(m_state);
-
- break;
- }
- case GST_STATE_PLAYING:
- m_everPlayed = true;
- if (m_state != QMediaPlayer::PlayingState) {
- emit stateChanged(m_state = QMediaPlayer::PlayingState);
-
- // For rtsp streams duration information might not be available
- // until playback starts.
- if (m_duration <= 0) {
- m_durationQueries = 5;
- updateDuration();
- }
- }
-
- break;
- }
- }
- break;
-
- case GST_MESSAGE_EOS:
- emit playbackFinished();
- break;
-
- case GST_MESSAGE_TAG:
- case GST_MESSAGE_STREAM_STATUS:
- case GST_MESSAGE_UNKNOWN:
- break;
- case GST_MESSAGE_ERROR: {
- GError *err;
- gchar *debug;
- gst_message_parse_error(gm, &err, &debug);
- if (err->domain == GST_STREAM_ERROR && err->code == GST_STREAM_ERROR_CODEC_NOT_FOUND)
- processInvalidMedia(QMediaPlayer::FormatError, tr("Cannot play stream of type: <unknown>"));
- else
- processInvalidMedia(QMediaPlayer::ResourceError, QString::fromUtf8(err->message));
- qWarning() << "Error:" << QString::fromUtf8(err->message);
- g_error_free(err);
- g_free(debug);
- }
- break;
- case GST_MESSAGE_WARNING:
- {
- GError *err;
- gchar *debug;
- gst_message_parse_warning (gm, &err, &debug);
- qWarning() << "Warning:" << QString::fromUtf8(err->message);
- g_error_free (err);
- g_free (debug);
- }
- break;
- case GST_MESSAGE_INFO:
-#ifdef DEBUG_PLAYBIN
- {
- GError *err;
- gchar *debug;
- gst_message_parse_info (gm, &err, &debug);
- qDebug() << "Info:" << QString::fromUtf8(err->message);
- g_error_free (err);
- g_free (debug);
- }
-#endif
- break;
- case GST_MESSAGE_BUFFERING:
- case GST_MESSAGE_STATE_DIRTY:
- case GST_MESSAGE_STEP_DONE:
- case GST_MESSAGE_CLOCK_PROVIDE:
- case GST_MESSAGE_CLOCK_LOST:
- case GST_MESSAGE_NEW_CLOCK:
- case GST_MESSAGE_STRUCTURE_CHANGE:
- case GST_MESSAGE_APPLICATION:
- case GST_MESSAGE_ELEMENT:
- break;
- case GST_MESSAGE_SEGMENT_START:
- {
- const GstStructure *structure = gst_message_get_structure(gm);
- qint64 position = g_value_get_int64(gst_structure_get_value(structure, "position"));
- position /= 1000000;
- m_lastPosition = position;
- emit positionChanged(position);
- }
- break;
- case GST_MESSAGE_SEGMENT_DONE:
- break;
- case GST_MESSAGE_LATENCY:
-#if GST_CHECK_VERSION(0,10,13)
- case GST_MESSAGE_ASYNC_START:
- break;
- case GST_MESSAGE_ASYNC_DONE:
- {
- gint64 position = 0;
- if (qt_gst_element_query_position(m_pipeline, GST_FORMAT_TIME, &position)) {
- position /= 1000000;
- m_lastPosition = position;
- emit positionChanged(position);
- }
- break;
- }
-#if GST_CHECK_VERSION(0,10,23)
- case GST_MESSAGE_REQUEST_STATE:
-#endif
-#endif
- case GST_MESSAGE_ANY:
- break;
- default:
- break;
- }
- } else if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ERROR) {
- GError *err;
- gchar *debug;
- gst_message_parse_error(gm, &err, &debug);
- // If the source has given up, so do we.
- if (qstrcmp(GST_OBJECT_NAME(GST_MESSAGE_SRC(gm)), "source") == 0) {
- bool everPlayed = m_everPlayed;
- // Try and differentiate network related resource errors from the others
- if (!m_request.url().isRelative() && m_request.url().scheme().compare(QLatin1String("file"), Qt::CaseInsensitive) != 0 ) {
- if (everPlayed ||
- (err->domain == GST_RESOURCE_ERROR && (
- err->code == GST_RESOURCE_ERROR_BUSY ||
- err->code == GST_RESOURCE_ERROR_OPEN_READ ||
- err->code == GST_RESOURCE_ERROR_READ ||
- err->code == GST_RESOURCE_ERROR_SEEK ||
- err->code == GST_RESOURCE_ERROR_SYNC))) {
- processInvalidMedia(QMediaPlayer::NetworkError, QString::fromUtf8(err->message));
- } else {
- processInvalidMedia(QMediaPlayer::ResourceError, QString::fromUtf8(err->message));
- }
- }
- else
- processInvalidMedia(QMediaPlayer::ResourceError, QString::fromUtf8(err->message));
- } else if (err->domain == GST_STREAM_ERROR
- && (err->code == GST_STREAM_ERROR_DECRYPT || err->code == GST_STREAM_ERROR_DECRYPT_NOKEY)) {
- processInvalidMedia(QMediaPlayer::AccessDeniedError, QString::fromUtf8(err->message));
- } else {
- handlePlaybin2 = true;
- }
- if (!handlePlaybin2)
- qWarning() << "Error:" << QString::fromUtf8(err->message);
- g_error_free(err);
- g_free(debug);
- } else if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT
- && qstrcmp(GST_OBJECT_NAME(GST_MESSAGE_SRC(gm)), "source") == 0
- && m_sourceType == UDPSrc
- && gst_structure_has_name(gst_message_get_structure(gm), "GstUDPSrcTimeout")) {
- //since udpsrc will not generate an error for the timeout event,
- //we need to process its element message here and treat it as an error.
- processInvalidMedia(m_everPlayed ? QMediaPlayer::NetworkError : QMediaPlayer::ResourceError,
- tr("UDP source timeout"));
- } else {
- handlePlaybin2 = true;
- }
-
- if (handlePlaybin2) {
- if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_WARNING) {
- GError *err;
- gchar *debug;
- gst_message_parse_warning(gm, &err, &debug);
- if (err->domain == GST_STREAM_ERROR && err->code == GST_STREAM_ERROR_CODEC_NOT_FOUND)
- emit error(int(QMediaPlayer::FormatError), tr("Cannot play stream of type: <unknown>"));
- // GStreamer shows warning for HTTP playlists
- if (err && err->message)
- qWarning() << "Warning:" << QString::fromUtf8(err->message);
- g_error_free(err);
- g_free(debug);
- } else if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ERROR) {
- GError *err;
- gchar *debug;
- gst_message_parse_error(gm, &err, &debug);
-
- // Nearly all errors map to ResourceError
- QMediaPlayer::Error qerror = QMediaPlayer::ResourceError;
- if (err->domain == GST_STREAM_ERROR
- && (err->code == GST_STREAM_ERROR_DECRYPT
- || err->code == GST_STREAM_ERROR_DECRYPT_NOKEY)) {
- qerror = QMediaPlayer::AccessDeniedError;
- }
- processInvalidMedia(qerror, QString::fromUtf8(err->message));
- if (err && err->message)
- qWarning() << "Error:" << QString::fromUtf8(err->message);
-
- g_error_free(err);
- g_free(debug);
- }
- }
- }
-
- return false;
-}
-
-void QGstreamerPlayerSession::getStreamsInfo()
-{
- if (!m_playbin)
- return;
-
- QList< QMap<QString,QVariant> > oldProperties = m_streamProperties;
- QList<QMediaStreamsControl::StreamType> oldTypes = m_streamTypes;
- QMap<QMediaStreamsControl::StreamType, int> oldOffset = m_playbin2StreamOffset;
-
- //check if video is available:
- bool haveAudio = false;
- bool haveVideo = false;
- m_streamProperties.clear();
- m_streamTypes.clear();
- m_playbin2StreamOffset.clear();
-
- gint audioStreamsCount = 0;
- gint videoStreamsCount = 0;
- gint textStreamsCount = 0;
-
- g_object_get(G_OBJECT(m_playbin), "n-audio", &audioStreamsCount, nullptr);
- g_object_get(G_OBJECT(m_playbin), "n-video", &videoStreamsCount, nullptr);
- g_object_get(G_OBJECT(m_playbin), "n-text", &textStreamsCount, nullptr);
-
- haveAudio = audioStreamsCount > 0;
- haveVideo = videoStreamsCount > 0;
-
- m_playbin2StreamOffset[QMediaStreamsControl::AudioStream] = 0;
- m_playbin2StreamOffset[QMediaStreamsControl::VideoStream] = audioStreamsCount;
- m_playbin2StreamOffset[QMediaStreamsControl::SubPictureStream] = audioStreamsCount+videoStreamsCount;
-
- for (int i=0; i<audioStreamsCount; i++)
- m_streamTypes.append(QMediaStreamsControl::AudioStream);
-
- for (int i=0; i<videoStreamsCount; i++)
- m_streamTypes.append(QMediaStreamsControl::VideoStream);
-
- for (int i=0; i<textStreamsCount; i++)
- m_streamTypes.append(QMediaStreamsControl::SubPictureStream);
-
- for (int i=0; i<m_streamTypes.count(); i++) {
- QMediaStreamsControl::StreamType streamType = m_streamTypes[i];
- QMap<QString, QVariant> streamProperties;
-
- int streamIndex = i - m_playbin2StreamOffset[streamType];
-
- GstTagList *tags = 0;
- switch (streamType) {
- case QMediaStreamsControl::AudioStream:
- g_signal_emit_by_name(G_OBJECT(m_playbin), "get-audio-tags", streamIndex, &tags);
- break;
- case QMediaStreamsControl::VideoStream:
- g_signal_emit_by_name(G_OBJECT(m_playbin), "get-video-tags", streamIndex, &tags);
- break;
- case QMediaStreamsControl::SubPictureStream:
- g_signal_emit_by_name(G_OBJECT(m_playbin), "get-text-tags", streamIndex, &tags);
- break;
- default:
- break;
- }
-#if GST_CHECK_VERSION(1,0,0)
- if (tags && GST_IS_TAG_LIST(tags)) {
-#else
- if (tags && gst_is_tag_list(tags)) {
-#endif
- gchar *languageCode = 0;
- if (gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &languageCode))
- streamProperties[QMediaMetaData::Language] = QString::fromUtf8(languageCode);
-
- //qDebug() << "language for setream" << i << QString::fromUtf8(languageCode);
- g_free (languageCode);
- gst_tag_list_free(tags);
- }
-
- m_streamProperties.append(streamProperties);
- }
-
- bool emitAudioChanged = (haveAudio != m_audioAvailable);
- bool emitVideoChanged = (haveVideo != m_videoAvailable);
-
- m_audioAvailable = haveAudio;
- m_videoAvailable = haveVideo;
-
- if (emitAudioChanged) {
- emit audioAvailableChanged(m_audioAvailable);
- }
- if (emitVideoChanged) {
- emit videoAvailableChanged(m_videoAvailable);
- }
-
- if (oldProperties != m_streamProperties || oldTypes != m_streamTypes || oldOffset != m_playbin2StreamOffset)
- emit streamsChanged();
-}
-
-void QGstreamerPlayerSession::updateVideoResolutionTag()
-{
- if (!m_videoIdentity)
- return;
-
-#ifdef DEBUG_PLAYBIN
- qDebug() << Q_FUNC_INFO;
-#endif
- QSize size;
- QSize aspectRatio;
- GstPad *pad = gst_element_get_static_pad(m_videoIdentity, "src");
- GstCaps *caps = qt_gst_pad_get_current_caps(pad);
-
- if (caps) {
- const GstStructure *structure = gst_caps_get_structure(caps, 0);
- gst_structure_get_int(structure, "width", &size.rwidth());
- gst_structure_get_int(structure, "height", &size.rheight());
-
- gint aspectNum = 0;
- gint aspectDenum = 0;
- if (!size.isEmpty() && gst_structure_get_fraction(
- structure, "pixel-aspect-ratio", &aspectNum, &aspectDenum)) {
- if (aspectDenum > 0)
- aspectRatio = QSize(aspectNum, aspectDenum);
- }
- gst_caps_unref(caps);
- }
-
- gst_object_unref(GST_OBJECT(pad));
-
- QSize currentSize = m_tags.value("resolution").toSize();
- QSize currentAspectRatio = m_tags.value("pixel-aspect-ratio").toSize();
-
- if (currentSize != size || currentAspectRatio != aspectRatio) {
- if (aspectRatio.isEmpty())
- m_tags.remove("pixel-aspect-ratio");
-
- if (size.isEmpty()) {
- m_tags.remove("resolution");
- } else {
- m_tags.insert("resolution", QVariant(size));
- if (!aspectRatio.isEmpty())
- m_tags.insert("pixel-aspect-ratio", QVariant(aspectRatio));
- }
-
- emit tagsChanged();
- }
-}
-
-void QGstreamerPlayerSession::updateDuration()
-{
- gint64 gstDuration = 0;
- int duration = 0;
-
- if (m_pipeline && qt_gst_element_query_duration(m_pipeline, GST_FORMAT_TIME, &gstDuration))
- duration = gstDuration / 1000000;
-
- if (m_duration != duration) {
- m_duration = duration;
- emit durationChanged(m_duration);
- }
-
- gboolean seekable = false;
- if (m_duration > 0) {
- m_durationQueries = 0;
- GstQuery *query = gst_query_new_seeking(GST_FORMAT_TIME);
- if (gst_element_query(m_pipeline, query))
- gst_query_parse_seeking(query, 0, &seekable, 0, 0);
- gst_query_unref(query);
- }
- setSeekable(seekable);
-
- if (m_durationQueries > 0) {
- //increase delay between duration requests
- int delay = 25 << (5 - m_durationQueries);
- QTimer::singleShot(delay, this, SLOT(updateDuration()));
- m_durationQueries--;
- }
-#ifdef DEBUG_PLAYBIN
- qDebug() << Q_FUNC_INFO << m_duration;
-#endif
-}
-
-void QGstreamerPlayerSession::playbinNotifySource(GObject *o, GParamSpec *p, gpointer d)
-{
- Q_UNUSED(p);
-
- GstElement *source = 0;
- g_object_get(o, "source", &source, nullptr);
- if (source == 0)
- return;
-
-#ifdef DEBUG_PLAYBIN
- qDebug() << "Playbin source added:" << G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS(source));
-#endif
-
- // Set Headers
- const QByteArray userAgentString("User-Agent");
-
- QGstreamerPlayerSession *self = reinterpret_cast<QGstreamerPlayerSession *>(d);
-
- // User-Agent - special case, souphhtpsrc will always set something, even if
- // defined in extra-headers
- if (g_object_class_find_property(G_OBJECT_GET_CLASS(source), "user-agent") != 0) {
- g_object_set(G_OBJECT(source), "user-agent",
- self->m_request.rawHeader(userAgentString).constData(), nullptr);
- }
-
- // The rest
- if (g_object_class_find_property(G_OBJECT_GET_CLASS(source), "extra-headers") != 0) {
- GstStructure *extras = qt_gst_structure_new_empty("extras");
-
- const auto rawHeaderList = self->m_request.rawHeaderList();
- for (const QByteArray &rawHeader : rawHeaderList) {
- if (rawHeader == userAgentString) // Filter User-Agent
- continue;
- else {
- GValue headerValue;
-
- memset(&headerValue, 0, sizeof(GValue));
- g_value_init(&headerValue, G_TYPE_STRING);
-
- g_value_set_string(&headerValue,
- self->m_request.rawHeader(rawHeader).constData());
-
- gst_structure_set_value(extras, rawHeader.constData(), &headerValue);
- }
- }
-
- if (gst_structure_n_fields(extras) > 0)
- g_object_set(G_OBJECT(source), "extra-headers", extras, nullptr);
-
- gst_structure_free(extras);
- }
-
- //set timeout property to 30 seconds
- const int timeout = 30;
- if (qstrcmp(G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS(source)), "GstUDPSrc") == 0) {
- quint64 convertedTimeout = timeout;
-#if GST_CHECK_VERSION(1,0,0)
- // Gst 1.x -> nanosecond
- convertedTimeout *= 1000000000;
-#else
- // Gst 0.10 -> microsecond
- convertedTimeout *= 1000000;
-#endif
- g_object_set(G_OBJECT(source), "timeout", convertedTimeout, nullptr);
- self->m_sourceType = UDPSrc;
- //The udpsrc is always a live source.
- self->m_isLiveSource = true;
-
- QUrlQuery query(self->m_request.url());
- const QString var = QLatin1String("udpsrc.caps");
- if (query.hasQueryItem(var)) {
- GstCaps *caps = gst_caps_from_string(query.queryItemValue(var).toLatin1().constData());
- g_object_set(G_OBJECT(source), "caps", caps, nullptr);
- gst_caps_unref(caps);
- }
- } else if (qstrcmp(G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS(source)), "GstSoupHTTPSrc") == 0) {
- //souphttpsrc timeout unit = second
- g_object_set(G_OBJECT(source), "timeout", guint(timeout), nullptr);
- self->m_sourceType = SoupHTTPSrc;
- //since gst_base_src_is_live is not reliable, so we check the source property directly
- gboolean isLive = false;
- g_object_get(G_OBJECT(source), "is-live", &isLive, nullptr);
- self->m_isLiveSource = isLive;
- } else if (qstrcmp(G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS(source)), "GstMMSSrc") == 0) {
- self->m_sourceType = MMSSrc;
- self->m_isLiveSource = gst_base_src_is_live(GST_BASE_SRC(source));
- g_object_set(G_OBJECT(source), "tcp-timeout", G_GUINT64_CONSTANT(timeout*1000000), nullptr);
- } else if (qstrcmp(G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS(source)), "GstRTSPSrc") == 0) {
- //rtspsrc acts like a live source and will therefore only generate data in the PLAYING state.
- self->m_sourceType = RTSPSrc;
- self->m_isLiveSource = true;
- g_object_set(G_OBJECT(source), "buffer-mode", 1, nullptr);
- } else {
- self->m_sourceType = UnknownSrc;
- self->m_isLiveSource = gst_base_src_is_live(GST_BASE_SRC(source));
- }
-
-#ifdef DEBUG_PLAYBIN
- if (self->m_isLiveSource)
- qDebug() << "Current source is a live source";
- else
- qDebug() << "Current source is a non-live source";
-#endif
-
- if (self->m_videoSink)
- g_object_set(G_OBJECT(self->m_videoSink), "sync", !self->m_isLiveSource, nullptr);
-
- gst_object_unref(source);
-}
-
-bool QGstreamerPlayerSession::isLiveSource() const
-{
- return m_isLiveSource;
-}
-
-void QGstreamerPlayerSession::handleVolumeChange(GObject *o, GParamSpec *p, gpointer d)
-{
- Q_UNUSED(o);
- Q_UNUSED(p);
- QGstreamerPlayerSession *session = reinterpret_cast<QGstreamerPlayerSession *>(d);
- QMetaObject::invokeMethod(session, "updateVolume", Qt::QueuedConnection);
-}
-
-void QGstreamerPlayerSession::updateVolume()
-{
- double volume = 1.0;
- g_object_get(m_playbin, "volume", &volume, nullptr);
-
- if (m_volume != int(volume*100 + 0.5)) {
- m_volume = int(volume*100 + 0.5);
-#ifdef DEBUG_PLAYBIN
- qDebug() << Q_FUNC_INFO << m_volume;
-#endif
- emit volumeChanged(m_volume);
- }
-}
-
-void QGstreamerPlayerSession::handleMutedChange(GObject *o, GParamSpec *p, gpointer d)
-{
- Q_UNUSED(o);
- Q_UNUSED(p);
- QGstreamerPlayerSession *session = reinterpret_cast<QGstreamerPlayerSession *>(d);
- QMetaObject::invokeMethod(session, "updateMuted", Qt::QueuedConnection);
-}
-
-void QGstreamerPlayerSession::updateMuted()
-{
- gboolean muted = FALSE;
- g_object_get(G_OBJECT(m_playbin), "mute", &muted, nullptr);
- if (m_muted != muted) {
- m_muted = muted;
-#ifdef DEBUG_PLAYBIN
- qDebug() << Q_FUNC_INFO << m_muted;
-#endif
- emit mutedStateChanged(muted);
- }
-}
-
-#if !GST_CHECK_VERSION(0, 10, 33)
-static gboolean factory_can_src_any_caps (GstElementFactory *factory, const GstCaps *caps)
-{
- GList *templates;
-
- g_return_val_if_fail(factory != nullptr, FALSE);
- g_return_val_if_fail(caps != nullptr, FALSE);
-
- templates = factory->staticpadtemplates;
-
- while (templates) {
- GstStaticPadTemplate *templ = (GstStaticPadTemplate *)templates->data;
-
- if (templ->direction == GST_PAD_SRC) {
- GstCaps *templcaps = gst_static_caps_get(&templ->static_caps);
-
- if (qt_gst_caps_can_intersect(caps, templcaps)) {
- gst_caps_unref(templcaps);
- return TRUE;
- }
- gst_caps_unref(templcaps);
- }
- templates = g_list_next(templates);
- }
-
- return FALSE;
-}
-#endif
-
-GstAutoplugSelectResult QGstreamerPlayerSession::handleAutoplugSelect(GstBin *bin, GstPad *pad, GstCaps *caps, GstElementFactory *factory, QGstreamerPlayerSession *session)
-{
- Q_UNUSED(bin);
- Q_UNUSED(pad);
- Q_UNUSED(caps);
-
- GstAutoplugSelectResult res = GST_AUTOPLUG_SELECT_TRY;
-
- // if VAAPI is available and can be used to decode but the current video sink cannot handle
- // the decoded format, don't use it
- const gchar *factoryName = gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(factory));
- if (g_str_has_prefix(factoryName, "vaapi")) {
- GstPad *sinkPad = gst_element_get_static_pad(session->m_videoSink, "sink");
-#if GST_CHECK_VERSION(1,0,0)
- GstCaps *sinkCaps = gst_pad_query_caps(sinkPad, nullptr);
-#else
- GstCaps *sinkCaps = gst_pad_get_caps(sinkPad);
-#endif
-
-#if !GST_CHECK_VERSION(0, 10, 33)
- if (!factory_can_src_any_caps(factory, sinkCaps))
-#else
- if (!gst_element_factory_can_src_any_caps(factory, sinkCaps))
-#endif
- res = GST_AUTOPLUG_SELECT_SKIP;
-
- gst_object_unref(sinkPad);
- gst_caps_unref(sinkCaps);
- }
-
- return res;
-}
-
-void QGstreamerPlayerSession::handleElementAdded(GstBin *bin, GstElement *element, QGstreamerPlayerSession *session)
-{
- Q_UNUSED(bin);
- //we have to configure queue2 element to enable media downloading
- //and reporting available ranges,
- //but it's added dynamically to playbin2
-
- gchar *elementName = gst_element_get_name(element);
-
- if (g_str_has_prefix(elementName, "queue2")) {
- // Disable on-disk buffering.
- g_object_set(G_OBJECT(element), "temp-template", nullptr, nullptr);
- } else if (g_str_has_prefix(elementName, "uridecodebin") ||
-#if GST_CHECK_VERSION(1,0,0)
- g_str_has_prefix(elementName, "decodebin")) {
-#else
- g_str_has_prefix(elementName, "decodebin2")) {
- if (g_str_has_prefix(elementName, "uridecodebin")) {
- // Add video/x-surface (VAAPI) to default raw formats
- g_object_set(G_OBJECT(element), "caps", gst_static_caps_get(&static_RawCaps), nullptr);
- // listen for uridecodebin autoplug-select to skip VAAPI usage when the current
- // video sink doesn't support it
- g_signal_connect(element, "autoplug-select", G_CALLBACK(handleAutoplugSelect), session);
- }
-#endif
- //listen for queue2 element added to uridecodebin/decodebin2 as well.
- //Don't touch other bins since they may have unrelated queues
- g_signal_connect(element, "element-added",
- G_CALLBACK(handleElementAdded), session);
- }
-
- g_free(elementName);
-}
-
-void QGstreamerPlayerSession::handleStreamsChange(GstBin *bin, gpointer user_data)
-{
- Q_UNUSED(bin);
-
- QGstreamerPlayerSession* session = reinterpret_cast<QGstreamerPlayerSession*>(user_data);
- QMetaObject::invokeMethod(session, "getStreamsInfo", Qt::QueuedConnection);
-}
-
-//doing proper operations when detecting an invalidMedia: change media status before signal the erorr
-void QGstreamerPlayerSession::processInvalidMedia(QMediaPlayer::Error errorCode, const QString& errorString)
-{
-#ifdef DEBUG_PLAYBIN
- qDebug() << Q_FUNC_INFO;
-#endif
- emit invalidMedia();
- stop();
- emit error(int(errorCode), errorString);
-}
-
-void QGstreamerPlayerSession::showPrerollFrames(bool enabled)
-{
-#ifdef DEBUG_PLAYBIN
- qDebug() << Q_FUNC_INFO << enabled;
-#endif
- if (enabled != m_displayPrerolledFrame && m_videoSink &&
- g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "show-preroll-frame") != 0) {
-
- gboolean value = enabled;
- g_object_set(G_OBJECT(m_videoSink), "show-preroll-frame", value, nullptr);
- m_displayPrerolledFrame = enabled;
- }
-}
-
-void QGstreamerPlayerSession::addProbe(QGstreamerVideoProbeControl* probe)
-{
- Q_ASSERT(!m_videoProbe);
- m_videoProbe = probe;
- addVideoBufferProbe();
-}
-
-void QGstreamerPlayerSession::removeProbe(QGstreamerVideoProbeControl* probe)
-{
- Q_ASSERT(m_videoProbe == probe);
- removeVideoBufferProbe();
- m_videoProbe = 0;
-}
-
-void QGstreamerPlayerSession::addProbe(QGstreamerAudioProbeControl* probe)
-{
- Q_ASSERT(!m_audioProbe);
- m_audioProbe = probe;
- addAudioBufferProbe();
-}
-
-void QGstreamerPlayerSession::removeProbe(QGstreamerAudioProbeControl* probe)
-{
- Q_ASSERT(m_audioProbe == probe);
- removeAudioBufferProbe();
- m_audioProbe = 0;
-}
-
-// This function is similar to stop(),
-// but does not set m_everPlayed, m_lastPosition,
-// and setSeekable() values.
-void QGstreamerPlayerSession::endOfMediaReset()
-{
- if (m_renderer)
- m_renderer->stopRenderer();
-
- flushVideoProbes();
- gst_element_set_state(m_pipeline, GST_STATE_PAUSED);
-
- QMediaPlayer::State oldState = m_state;
- m_pendingState = m_state = QMediaPlayer::StoppedState;
-
- finishVideoOutputChange();
-
- if (oldState != m_state)
- emit stateChanged(m_state);
-}
-
-void QGstreamerPlayerSession::removeVideoBufferProbe()
-{
- if (!m_videoProbe)
- return;
-
- GstPad *pad = gst_element_get_static_pad(m_videoSink, "sink");
- if (pad) {
- m_videoProbe->removeProbeFromPad(pad);
- gst_object_unref(GST_OBJECT(pad));
- }
-}
-
-void QGstreamerPlayerSession::addVideoBufferProbe()
-{
- if (!m_videoProbe)
- return;
-
- GstPad *pad = gst_element_get_static_pad(m_videoSink, "sink");
- if (pad) {
- m_videoProbe->addProbeToPad(pad);
- gst_object_unref(GST_OBJECT(pad));
- }
-}
-
-void QGstreamerPlayerSession::removeAudioBufferProbe()
-{
- if (!m_audioProbe)
- return;
-
- GstPad *pad = gst_element_get_static_pad(m_audioSink, "sink");
- if (pad) {
- m_audioProbe->removeProbeFromPad(pad);
- gst_object_unref(GST_OBJECT(pad));
- }
-}
-
-void QGstreamerPlayerSession::addAudioBufferProbe()
-{
- if (!m_audioProbe)
- return;
-
- GstPad *pad = gst_element_get_static_pad(m_audioSink, "sink");
- if (pad) {
- m_audioProbe->addProbeToPad(pad);
- gst_object_unref(GST_OBJECT(pad));
- }
-}
-
-void QGstreamerPlayerSession::flushVideoProbes()
-{
- if (m_videoProbe)
- m_videoProbe->startFlushing();
-}
-
-void QGstreamerPlayerSession::resumeVideoProbes()
-{
- if (m_videoProbe)
- m_videoProbe->stopFlushing();
-}
-
-QT_END_NAMESPACE
diff --git a/src/gsttools/qgstreamerplayersession_p.h b/src/gsttools/qgstreamerplayersession_p.h
deleted file mode 100644
index 797229e69..000000000
--- a/src/gsttools/qgstreamerplayersession_p.h
+++ /dev/null
@@ -1,284 +0,0 @@
-/****************************************************************************
-**
-** 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;
- 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();
- void pipelineChanged();
-
-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();
- bool parsePipeline();
- bool setPipeline(GstElement *pipeline);
- void resetElements();
- void initPlaybin();
- void setBus(GstBus *bus);
-
- QNetworkRequest m_request;
- QMediaPlayer::State m_state = QMediaPlayer::StoppedState;
- QMediaPlayer::State m_pendingState = QMediaPlayer::StoppedState;
- QGstreamerBusHelper *m_busHelper = nullptr;
- GstElement *m_playbin = nullptr;
- GstElement *m_pipeline = nullptr;
-
- GstElement *m_videoSink = nullptr;
-
- GstElement *m_videoOutputBin = nullptr;
- GstElement *m_videoIdentity = nullptr;
-#if !GST_CHECK_VERSION(1,0,0)
- GstElement *m_colorSpace = nullptr;
- bool m_usingColorspaceElement = false;
-#endif
- GstElement *m_pendingVideoSink = nullptr;
- GstElement *m_nullVideoSink = nullptr;
-
- GstElement *m_audioSink = nullptr;
- GstElement *m_volumeElement = nullptr;
-
- GstBus *m_bus = nullptr;
- QObject *m_videoOutput = nullptr;
- QGstreamerVideoRendererInterface *m_renderer = nullptr;
-
-#if QT_CONFIG(gstreamer_app)
- QGstAppSrc *m_appSrc = nullptr;
-#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 = nullptr;
- QGstreamerAudioProbeControl *m_audioProbe = nullptr;
-
- int m_volume = 100;
- qreal m_playbackRate = 1.0;
- bool m_muted = false;
- bool m_audioAvailable = false;
- bool m_videoAvailable = false;
- bool m_seekable = false;
-
- mutable qint64 m_lastPosition = 0;
- qint64 m_duration = 0;
- int m_durationQueries = 0;
-
- bool m_displayPrerolledFrame = true;
-
- enum SourceType
- {
- UnknownSrc,
- SoupHTTPSrc,
- UDPSrc,
- MMSSrc,
- RTSPSrc,
- };
- SourceType m_sourceType = UnknownSrc;
- bool m_everPlayed = false;
- bool m_isLiveSource = false;
-
- gulong pad_probe_id = 0;
-};
-
-QT_END_NAMESPACE
-
-#endif // QGSTREAMERPLAYERSESSION_H
diff --git a/src/gsttools/qgstreamervideoinputdevicecontrol.cpp b/src/gsttools/qgstreamervideoinputdevicecontrol.cpp
deleted file mode 100644
index 4d98afa62..000000000
--- a/src/gsttools/qgstreamervideoinputdevicecontrol.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#include "qgstreamervideoinputdevicecontrol_p.h"
-
-#include <QtCore/QDir>
-#include <QtCore/QDebug>
-
-#include <private/qgstutils_p.h>
-
-QGstreamerVideoInputDeviceControl::QGstreamerVideoInputDeviceControl(QObject *parent)
- : QVideoDeviceSelectorControl(parent)
-{
-}
-
-QGstreamerVideoInputDeviceControl::QGstreamerVideoInputDeviceControl(
- GstElementFactory *factory, QObject *parent)
- : QVideoDeviceSelectorControl(parent)
- , m_factory(factory)
-{
- if (m_factory)
- gst_object_ref(GST_OBJECT(m_factory));
-}
-
-QGstreamerVideoInputDeviceControl::~QGstreamerVideoInputDeviceControl()
-{
- if (m_factory)
- gst_object_unref(GST_OBJECT(m_factory));
-}
-
-int QGstreamerVideoInputDeviceControl::deviceCount() const
-{
- return QGstUtils::enumerateCameras(m_factory).count();
-}
-
-QString QGstreamerVideoInputDeviceControl::deviceName(int index) const
-{
- return QGstUtils::enumerateCameras(m_factory).value(index).name;
-}
-
-QString QGstreamerVideoInputDeviceControl::deviceDescription(int index) const
-{
- return QGstUtils::enumerateCameras(m_factory).value(index).description;
-}
-
-int QGstreamerVideoInputDeviceControl::defaultDevice() const
-{
- return 0;
-}
-
-int QGstreamerVideoInputDeviceControl::selectedDevice() const
-{
- return m_selectedDevice;
-}
-
-void QGstreamerVideoInputDeviceControl::setSelectedDevice(int index)
-{
- // Always update selected device and proxy it to clients
- m_selectedDevice = index;
- emit selectedDeviceChanged(index);
- emit selectedDeviceChanged(deviceName(index));
-}
diff --git a/src/gsttools/qgstreamervideoinputdevicecontrol_p.h b/src/gsttools/qgstreamervideoinputdevicecontrol_p.h
deleted file mode 100644
index 9d8dffd72..000000000
--- a/src/gsttools/qgstreamervideoinputdevicecontrol_p.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/****************************************************************************
-**
-** 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 QGSTREAMERVIDEOINPUTDEVICECONTROL_H
-#define QGSTREAMERVIDEOINPUTDEVICECONTROL_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 <private/qgsttools_global_p.h>
-#include <qvideodeviceselectorcontrol.h>
-#include <QtCore/qstringlist.h>
-
-#include <gst/gst.h>
-#include <qcamera.h>
-
-QT_BEGIN_NAMESPACE
-
-class Q_GSTTOOLS_EXPORT QGstreamerVideoInputDeviceControl : public QVideoDeviceSelectorControl
-{
-Q_OBJECT
-public:
- QGstreamerVideoInputDeviceControl(QObject *parent);
- QGstreamerVideoInputDeviceControl(GstElementFactory *factory, QObject *parent);
- ~QGstreamerVideoInputDeviceControl();
-
- int deviceCount() const override;
-
- QString deviceName(int index) const override;
- QString deviceDescription(int index) const override;
-
- int defaultDevice() const override;
- int selectedDevice() const override;
-
- static QString primaryCamera() { return tr("Main camera"); }
- static QString secondaryCamera() { return tr("Front camera"); }
-
-public Q_SLOTS:
- void setSelectedDevice(int index) override;
-
-private:
- GstElementFactory *m_factory = nullptr;
-
- int m_selectedDevice = 0;
-};
-
-QT_END_NAMESPACE
-
-#endif // QGSTREAMERAUDIOINPUTDEVICECONTROL_H
diff --git a/src/gsttools/qgstreamervideooverlay.cpp b/src/gsttools/qgstreamervideooverlay.cpp
deleted file mode 100644
index ea8149442..000000000
--- a/src/gsttools/qgstreamervideooverlay.cpp
+++ /dev/null
@@ -1,639 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#include "qgstreamervideooverlay_p.h"
-
-#include <QtGui/qguiapplication.h>
-#include "qgstutils_p.h"
-
-#if !GST_CHECK_VERSION(1,0,0)
-#include <gst/interfaces/xoverlay.h>
-#else
-#include <gst/video/videooverlay.h>
-#endif
-
-#include <QtMultimedia/private/qtmultimediaglobal_p.h>
-
-QT_BEGIN_NAMESPACE
-
-struct ElementMap
-{
- const char *qtPlatform;
- const char *gstreamerElement;
-};
-
-// Ordered by descending priority
-static const ElementMap elementMap[] =
-{
-#if QT_CONFIG(gstreamer_gl)
- { "xcb", "glimagesink" },
-#endif
- { "xcb", "vaapisink" },
- { "xcb", "xvimagesink" },
- { "xcb", "ximagesink" }
-};
-
-class QGstreamerSinkProperties
-{
-public:
- virtual ~QGstreamerSinkProperties()
- {
- }
-
- virtual bool hasShowPrerollFrame() const = 0;
- virtual void reset() = 0;
- virtual int brightness() const = 0;
- virtual bool setBrightness(int brightness) = 0;
- virtual int contrast() const = 0;
- virtual bool setContrast(int contrast) = 0;
- virtual int hue() const = 0;
- virtual bool setHue(int hue) = 0;
- virtual int saturation() const = 0;
- virtual bool setSaturation(int saturation) = 0;
- virtual Qt::AspectRatioMode aspectRatioMode() const = 0;
- virtual void setAspectRatioMode(Qt::AspectRatioMode mode) = 0;
-};
-
-class QXVImageSinkProperties : public QGstreamerSinkProperties
-{
-public:
- QXVImageSinkProperties(GstElement *sink)
- : m_videoSink(sink)
- {
- m_hasForceAspectRatio = g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "force-aspect-ratio");
- m_hasBrightness = g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "brightness");
- m_hasContrast = g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "contrast");
- m_hasHue = g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "hue");
- m_hasSaturation = g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "saturation");
- m_hasShowPrerollFrame = g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "show-preroll-frame");
- }
-
- bool hasShowPrerollFrame() const override
- {
- return m_hasShowPrerollFrame;
- }
-
- void reset() override
- {
- setAspectRatioMode(m_aspectRatioMode);
- setBrightness(m_brightness);
- setContrast(m_contrast);
- setHue(m_hue);
- setSaturation(m_saturation);
- }
-
- int brightness() const override
- {
- int brightness = 0;
- if (m_hasBrightness)
- g_object_get(G_OBJECT(m_videoSink), "brightness", &brightness, nullptr);
-
- return brightness / 10;
- }
-
- bool setBrightness(int brightness) override
- {
- m_brightness = brightness;
- if (m_hasBrightness)
- g_object_set(G_OBJECT(m_videoSink), "brightness", brightness * 10, nullptr);
-
- return m_hasBrightness;
- }
-
- int contrast() const override
- {
- int contrast = 0;
- if (m_hasContrast)
- g_object_get(G_OBJECT(m_videoSink), "contrast", &contrast, nullptr);
-
- return contrast / 10;
- }
-
- bool setContrast(int contrast) override
- {
- m_contrast = contrast;
- if (m_hasContrast)
- g_object_set(G_OBJECT(m_videoSink), "contrast", contrast * 10, nullptr);
-
- return m_hasContrast;
- }
-
- int hue() const override
- {
- int hue = 0;
- if (m_hasHue)
- g_object_get(G_OBJECT(m_videoSink), "hue", &hue, nullptr);
-
- return hue / 10;
- }
-
- bool setHue(int hue) override
- {
- m_hue = hue;
- if (m_hasHue)
- g_object_set(G_OBJECT(m_videoSink), "hue", hue * 10, nullptr);
-
- return m_hasHue;
- }
-
- int saturation() const override
- {
- int saturation = 0;
- if (m_hasSaturation)
- g_object_get(G_OBJECT(m_videoSink), "saturation", &saturation, nullptr);
-
- return saturation / 10;
- }
-
- bool setSaturation(int saturation) override
- {
- m_saturation = saturation;
- if (m_hasSaturation)
- g_object_set(G_OBJECT(m_videoSink), "saturation", saturation * 10, nullptr);
-
- return m_hasSaturation;
- }
-
- Qt::AspectRatioMode aspectRatioMode() const override
- {
- Qt::AspectRatioMode mode = Qt::KeepAspectRatio;
- if (m_hasForceAspectRatio) {
- gboolean forceAR = false;
- g_object_get(G_OBJECT(m_videoSink), "force-aspect-ratio", &forceAR, nullptr);
- if (!forceAR)
- mode = Qt::IgnoreAspectRatio;
- }
-
- return mode;
- }
-
- void setAspectRatioMode(Qt::AspectRatioMode mode) override
- {
- m_aspectRatioMode = mode;
- if (m_hasForceAspectRatio) {
- g_object_set(G_OBJECT(m_videoSink),
- "force-aspect-ratio",
- (mode == Qt::KeepAspectRatio),
- nullptr);
- }
- }
-
-protected:
-
- GstElement *m_videoSink = nullptr;
- bool m_hasForceAspectRatio = false;
- bool m_hasBrightness = false;
- bool m_hasContrast = false;
- bool m_hasHue = false;
- bool m_hasSaturation = false;
- bool m_hasShowPrerollFrame = false;
- Qt::AspectRatioMode m_aspectRatioMode = Qt::KeepAspectRatio;
- int m_brightness = 0;
- int m_contrast = 0;
- int m_hue = 0;
- int m_saturation = 0;
-};
-
-class QVaapiSinkProperties : public QXVImageSinkProperties
-{
-public:
- QVaapiSinkProperties(GstElement *sink)
- : QXVImageSinkProperties(sink)
- {
- // Set default values.
- m_contrast = 1;
- m_saturation = 1;
- }
-
- int brightness() const override
- {
- gfloat brightness = 0;
- if (m_hasBrightness)
- g_object_get(G_OBJECT(m_videoSink), "brightness", &brightness, nullptr);
-
- return brightness * 100; // [-1,1] -> [-100,100]
- }
-
- bool setBrightness(int brightness) override
- {
- m_brightness = brightness;
- if (m_hasBrightness) {
- gfloat v = brightness / 100.0; // [-100,100] -> [-1,1]
- g_object_set(G_OBJECT(m_videoSink), "brightness", v, nullptr);
- }
-
- return m_hasBrightness;
- }
-
- int contrast() const override
- {
- gfloat contrast = 1;
- if (m_hasContrast)
- g_object_get(G_OBJECT(m_videoSink), "contrast", &contrast, nullptr);
-
- return (contrast - 1) * 100; // [0,2] -> [-100,100]
- }
-
- bool setContrast(int contrast) override
- {
- m_contrast = contrast;
- if (m_hasContrast) {
- gfloat v = (contrast / 100.0) + 1; // [-100,100] -> [0,2]
- g_object_set(G_OBJECT(m_videoSink), "contrast", v, nullptr);
- }
-
- return m_hasContrast;
- }
-
- int hue() const override
- {
- gfloat hue = 0;
- if (m_hasHue)
- g_object_get(G_OBJECT(m_videoSink), "hue", &hue, nullptr);
-
- return hue / 180 * 100; // [-180,180] -> [-100,100]
- }
-
- bool setHue(int hue) override
- {
- m_hue = hue;
- if (m_hasHue) {
- gfloat v = hue / 100.0 * 180; // [-100,100] -> [-180,180]
- g_object_set(G_OBJECT(m_videoSink), "hue", v, nullptr);
- }
-
- return m_hasHue;
- }
-
- int saturation() const override
- {
- gfloat saturation = 1;
- if (m_hasSaturation)
- g_object_get(G_OBJECT(m_videoSink), "saturation", &saturation, nullptr);
-
- return (saturation - 1) * 100; // [0,2] -> [-100,100]
- }
-
- bool setSaturation(int saturation) override
- {
- m_saturation = saturation;
- if (m_hasSaturation) {
- gfloat v = (saturation / 100.0) + 1; // [-100,100] -> [0,2]
- g_object_set(G_OBJECT(m_videoSink), "saturation", v, nullptr);
- }
-
- return m_hasSaturation;
- }
-};
-
-static bool qt_gst_element_is_functioning(GstElement *element)
-{
- GstStateChangeReturn ret = gst_element_set_state(element, GST_STATE_READY);
- if (ret == GST_STATE_CHANGE_SUCCESS) {
- gst_element_set_state(element, GST_STATE_NULL);
- return true;
- }
-
- return false;
-}
-
-static GstElement *findBestVideoSink()
-{
- GstElement *choice = 0;
- QString platform = QGuiApplication::platformName();
-
- // We need a native window ID to use the GstVideoOverlay interface.
- // Bail out if the Qt platform plugin in use cannot provide a sensible WId.
- if (platform != QLatin1String("xcb"))
- return 0;
-
- // First, try some known video sinks, depending on the Qt platform plugin in use.
- for (quint32 i = 0; i < (sizeof(elementMap) / sizeof(ElementMap)); ++i) {
-#if QT_CONFIG(gstreamer_gl)
- if (!QGstUtils::useOpenGL() && qstrcmp(elementMap[i].gstreamerElement, "glimagesink") == 0)
- continue;
-#endif
- if (platform == QLatin1String(elementMap[i].qtPlatform)
- && (choice = gst_element_factory_make(elementMap[i].gstreamerElement, nullptr))) {
-
- if (qt_gst_element_is_functioning(choice))
- return choice;
-
- gst_object_unref(choice);
- choice = 0;
- }
- }
-
- // If none of the known video sinks are available, try to find one that implements the
- // GstVideoOverlay interface and has autoplugging rank.
- GList *list = qt_gst_video_sinks();
- for (GList *item = list; item != nullptr; item = item->next) {
- GstElementFactory *f = GST_ELEMENT_FACTORY(item->data);
-
- if (!gst_element_factory_has_interface(f, QT_GSTREAMER_VIDEOOVERLAY_INTERFACE_NAME))
- continue;
-
- if (GstElement *el = gst_element_factory_create(f, nullptr)) {
- if (qt_gst_element_is_functioning(el)) {
- choice = el;
- break;
- }
-
- gst_object_unref(el);
- }
- }
-
- gst_plugin_feature_list_free(list);
-
- return choice;
-}
-
-QGstreamerVideoOverlay::QGstreamerVideoOverlay(QObject *parent, const QByteArray &elementName)
- : QObject(parent)
- , QGstreamerBufferProbe(QGstreamerBufferProbe::ProbeCaps)
-{
- GstElement *sink = nullptr;
- if (!elementName.isEmpty())
- sink = gst_element_factory_make(elementName.constData(), nullptr);
- else
- sink = findBestVideoSink();
-
- setVideoSink(sink);
-}
-
-QGstreamerVideoOverlay::~QGstreamerVideoOverlay()
-{
- if (m_videoSink) {
- delete m_sinkProperties;
- GstPad *pad = gst_element_get_static_pad(m_videoSink, "sink");
- removeProbeFromPad(pad);
- gst_object_unref(GST_OBJECT(pad));
- gst_object_unref(GST_OBJECT(m_videoSink));
- }
-}
-
-GstElement *QGstreamerVideoOverlay::videoSink() const
-{
- return m_videoSink;
-}
-
-void QGstreamerVideoOverlay::setVideoSink(GstElement *sink)
-{
- if (!sink)
- return;
-
- if (m_videoSink)
- gst_object_unref(GST_OBJECT(m_videoSink));
-
- m_videoSink = sink;
- qt_gst_object_ref_sink(GST_OBJECT(m_videoSink));
-
- GstPad *pad = gst_element_get_static_pad(m_videoSink, "sink");
- addProbeToPad(pad);
- gst_object_unref(GST_OBJECT(pad));
-
- QString sinkName(QLatin1String(GST_OBJECT_NAME(sink)));
- bool isVaapi = sinkName.startsWith(QLatin1String("vaapisink"));
- delete m_sinkProperties;
- m_sinkProperties = isVaapi ? new QVaapiSinkProperties(sink) : new QXVImageSinkProperties(sink);
-
- if (m_sinkProperties->hasShowPrerollFrame())
- g_signal_connect(m_videoSink, "notify::show-preroll-frame",
- G_CALLBACK(showPrerollFrameChanged), this);
-}
-
-QSize QGstreamerVideoOverlay::nativeVideoSize() const
-{
- return m_nativeVideoSize;
-}
-
-void QGstreamerVideoOverlay::setWindowHandle(WId id)
-{
- m_windowId = id;
-
- if (isActive())
- setWindowHandle_helper(id);
-}
-
-void QGstreamerVideoOverlay::setWindowHandle_helper(WId id)
-{
-#if GST_CHECK_VERSION(1,0,0)
- if (m_videoSink && GST_IS_VIDEO_OVERLAY(m_videoSink)) {
- gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(m_videoSink), id);
-#else
- if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) {
-# if GST_CHECK_VERSION(0,10,31)
- gst_x_overlay_set_window_handle(GST_X_OVERLAY(m_videoSink), id);
-# else
- gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(m_videoSink), id);
-# endif
-#endif
-
- // Properties need to be reset when changing the winId.
- m_sinkProperties->reset();
- }
-}
-
-void QGstreamerVideoOverlay::expose()
-{
- if (!isActive())
- return;
-
-#if !GST_CHECK_VERSION(1,0,0)
- if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink))
- gst_x_overlay_expose(GST_X_OVERLAY(m_videoSink));
-#else
- if (m_videoSink && GST_IS_VIDEO_OVERLAY(m_videoSink)) {
- gst_video_overlay_expose(GST_VIDEO_OVERLAY(m_videoSink));
- }
-#endif
-}
-
-void QGstreamerVideoOverlay::setRenderRectangle(const QRect &rect)
-{
- int x = -1;
- int y = -1;
- int w = -1;
- int h = -1;
-
- if (!rect.isEmpty()) {
- x = rect.x();
- y = rect.y();
- w = rect.width();
- h = rect.height();
- }
-
-#if GST_CHECK_VERSION(1,0,0)
- if (m_videoSink && GST_IS_VIDEO_OVERLAY(m_videoSink))
- gst_video_overlay_set_render_rectangle(GST_VIDEO_OVERLAY(m_videoSink), x, y, w, h);
-#elif GST_CHECK_VERSION(0, 10, 29)
- if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink))
- gst_x_overlay_set_render_rectangle(GST_X_OVERLAY(m_videoSink), x, y , w , h);
-#else
- Q_UNUSED(x);
- Q_UNUSED(y);
- Q_UNUSED(w);
- Q_UNUSED(h);
-#endif
-}
-
-bool QGstreamerVideoOverlay::processSyncMessage(const QGstreamerMessage &message)
-{
- GstMessage* gm = message.rawMessage();
-
-#if !GST_CHECK_VERSION(1,0,0)
- if (gm && (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) &&
- gst_structure_has_name(gm->structure, "prepare-xwindow-id")) {
-#else
- if (gm && (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) &&
- gst_structure_has_name(gst_message_get_structure(gm), "prepare-window-handle")) {
-#endif
- setWindowHandle_helper(m_windowId);
- return true;
- }
-
- return false;
-}
-
-bool QGstreamerVideoOverlay::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)) {
-
- updateIsActive();
- }
-
- return false;
-}
-
-void QGstreamerVideoOverlay::probeCaps(GstCaps *caps)
-{
- QSize size = QGstUtils::capsCorrectedResolution(caps);
- if (size != m_nativeVideoSize) {
- m_nativeVideoSize = size;
- emit nativeVideoSizeChanged();
- }
-}
-
-bool QGstreamerVideoOverlay::isActive() const
-{
- return m_isActive;
-}
-
-void QGstreamerVideoOverlay::updateIsActive()
-{
- if (!m_videoSink)
- return;
-
- GstState state = GST_STATE(m_videoSink);
- gboolean showPreroll = true;
-
- if (m_sinkProperties->hasShowPrerollFrame())
- g_object_get(G_OBJECT(m_videoSink), "show-preroll-frame", &showPreroll, nullptr);
-
- bool newIsActive = (state == GST_STATE_PLAYING || (state == GST_STATE_PAUSED && showPreroll));
-
- if (newIsActive != m_isActive) {
- m_isActive = newIsActive;
- emit activeChanged();
- }
-}
-
-void QGstreamerVideoOverlay::showPrerollFrameChanged(GObject *, GParamSpec *, QGstreamerVideoOverlay *overlay)
-{
- overlay->updateIsActive();
-}
-
-Qt::AspectRatioMode QGstreamerVideoOverlay::aspectRatioMode() const
-{
- return m_sinkProperties->aspectRatioMode();
-}
-
-void QGstreamerVideoOverlay::setAspectRatioMode(Qt::AspectRatioMode mode)
-{
- m_sinkProperties->setAspectRatioMode(mode);
-}
-
-int QGstreamerVideoOverlay::brightness() const
-{
- return m_sinkProperties->brightness();
-}
-
-void QGstreamerVideoOverlay::setBrightness(int brightness)
-{
- if (m_sinkProperties->setBrightness(brightness))
- emit brightnessChanged(brightness);
-}
-
-int QGstreamerVideoOverlay::contrast() const
-{
- return m_sinkProperties->contrast();
-}
-
-void QGstreamerVideoOverlay::setContrast(int contrast)
-{
- if (m_sinkProperties->setContrast(contrast))
- emit contrastChanged(contrast);
-}
-
-int QGstreamerVideoOverlay::hue() const
-{
- return m_sinkProperties->hue();
-}
-
-void QGstreamerVideoOverlay::setHue(int hue)
-{
- if (m_sinkProperties->setHue(hue))
- emit hueChanged(hue);
-}
-
-int QGstreamerVideoOverlay::saturation() const
-{
- return m_sinkProperties->saturation();
-}
-
-void QGstreamerVideoOverlay::setSaturation(int saturation)
-{
- if (m_sinkProperties->setSaturation(saturation))
- emit saturationChanged(saturation);
-}
-
-QT_END_NAMESPACE
diff --git a/src/gsttools/qgstreamervideooverlay_p.h b/src/gsttools/qgstreamervideooverlay_p.h
deleted file mode 100644
index f2ca8a23b..000000000
--- a/src/gsttools/qgstreamervideooverlay_p.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/****************************************************************************
-**
-** 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 QGSTREAMERVIDEOOVERLAY_P_H
-#define QGSTREAMERVIDEOOVERLAY_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 <private/qgstreamerbushelper_p.h>
-#include <private/qgstreamerbufferprobe_p.h>
-#include <QtGui/qwindowdefs.h>
-#include <QtCore/qsize.h>
-
-QT_BEGIN_NAMESPACE
-
-class QGstreamerSinkProperties;
-class QGstreamerVideoOverlay
- : public QObject
- , public QGstreamerSyncMessageFilter
- , public QGstreamerBusMessageFilter
- , private QGstreamerBufferProbe
-{
- Q_OBJECT
- Q_INTERFACES(QGstreamerSyncMessageFilter QGstreamerBusMessageFilter)
-public:
- explicit QGstreamerVideoOverlay(QObject *parent = 0, const QByteArray &elementName = QByteArray());
- virtual ~QGstreamerVideoOverlay();
-
- GstElement *videoSink() const;
- void setVideoSink(GstElement *);
- QSize nativeVideoSize() const;
-
- void setWindowHandle(WId id);
- void expose();
- void setRenderRectangle(const QRect &rect);
-
- bool isActive() const;
-
- Qt::AspectRatioMode aspectRatioMode() const;
- void setAspectRatioMode(Qt::AspectRatioMode mode);
-
- int brightness() const;
- void setBrightness(int brightness);
-
- int contrast() const;
- void setContrast(int contrast);
-
- int hue() const;
- void setHue(int hue);
-
- int saturation() const;
- void setSaturation(int saturation);
-
- bool processSyncMessage(const QGstreamerMessage &message) override;
- bool processBusMessage(const QGstreamerMessage &message) override;
-
-Q_SIGNALS:
- void nativeVideoSizeChanged();
- void activeChanged();
- void brightnessChanged(int brightness);
- void contrastChanged(int contrast);
- void hueChanged(int hue);
- void saturationChanged(int saturation);
-
-private:
- void setWindowHandle_helper(WId id);
- void updateIsActive();
- void probeCaps(GstCaps *caps) override;
- static void showPrerollFrameChanged(GObject *, GParamSpec *, QGstreamerVideoOverlay *);
-
- GstElement *m_videoSink = nullptr;
- QSize m_nativeVideoSize;
- bool m_isActive = false;
-
- QGstreamerSinkProperties *m_sinkProperties = nullptr;
- WId m_windowId = 0;
-};
-
-QT_END_NAMESPACE
-
-#endif // QGSTREAMERVIDEOOVERLAY_P_H
-
diff --git a/src/gsttools/qgstreamervideoprobecontrol.cpp b/src/gsttools/qgstreamervideoprobecontrol.cpp
deleted file mode 100644
index f9ce4e412..000000000
--- a/src/gsttools/qgstreamervideoprobecontrol.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#include "qgstreamervideoprobecontrol_p.h"
-
-#include "qgstutils_p.h"
-#include <private/qgstvideobuffer_p.h>
-
-QGstreamerVideoProbeControl::QGstreamerVideoProbeControl(QObject *parent)
- : QMediaVideoProbeControl(parent)
-{
-}
-
-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::probeCaps(GstCaps *caps)
-{
-#if GST_CHECK_VERSION(1,0,0)
- GstVideoInfo videoInfo;
- QVideoSurfaceFormat format = QGstUtils::formatForCaps(caps, &videoInfo);
-
- QMutexLocker locker(&m_frameMutex);
- m_videoInfo = videoInfo;
-#else
- int bytesPerLine = 0;
- QVideoSurfaceFormat format = QGstUtils::formatForCaps(caps, &bytesPerLine);
-
- QMutexLocker locker(&m_frameMutex);
- m_bytesPerLine = bytesPerLine;
-#endif
- m_format = format;
-}
-
-bool QGstreamerVideoProbeControl::probeBuffer(GstBuffer *buffer)
-{
- QMutexLocker locker(&m_frameMutex);
-
- if (m_flushing || !m_format.isValid())
- return true;
-
- QVideoFrame frame(
-#if GST_CHECK_VERSION(1,0,0)
- new QGstVideoBuffer(buffer, m_videoInfo),
-#else
- new QGstVideoBuffer(buffer, m_bytesPerLine),
-#endif
- m_format.frameSize(),
- m_format.pixelFormat());
-
- QGstUtils::setFrameTimeStamps(&frame, buffer);
-
- m_frameProbed = true;
-
- if (!m_pendingFrame.isValid())
- QMetaObject::invokeMethod(this, "frameProbed", Qt::QueuedConnection);
- m_pendingFrame = frame;
-
- return true;
-}
-
-void QGstreamerVideoProbeControl::frameProbed()
-{
- QVideoFrame frame;
- {
- QMutexLocker locker(&m_frameMutex);
- if (!m_pendingFrame.isValid())
- return;
- frame = m_pendingFrame;
- m_pendingFrame = QVideoFrame();
- }
- emit videoFrameProbed(frame);
-}
diff --git a/src/gsttools/qgstreamervideoprobecontrol_p.h b/src/gsttools/qgstreamervideoprobecontrol_p.h
deleted file mode 100644
index 8f2101d74..000000000
--- a/src/gsttools/qgstreamervideoprobecontrol_p.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/****************************************************************************
-**
-** 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 QGSTREAMERVIDEOPROBECONTROL_H
-#define QGSTREAMERVIDEOPROBECONTROL_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 <private/qgsttools_global_p.h>
-#include <gst/gst.h>
-#include <gst/video/video.h>
-#include <qmediavideoprobecontrol.h>
-#include <QtCore/qmutex.h>
-#include <qvideoframe.h>
-#include <qvideosurfaceformat.h>
-
-#include <private/qgstreamerbufferprobe_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class Q_GSTTOOLS_EXPORT QGstreamerVideoProbeControl
- : public QMediaVideoProbeControl
- , public QGstreamerBufferProbe
- , public QSharedData
-{
- Q_OBJECT
-public:
- explicit QGstreamerVideoProbeControl(QObject *parent);
- virtual ~QGstreamerVideoProbeControl();
-
- void probeCaps(GstCaps *caps) override;
- bool probeBuffer(GstBuffer *buffer) override;
-
- void startFlushing();
- void stopFlushing();
-
-private slots:
- void frameProbed();
-
-private:
- QVideoSurfaceFormat m_format;
- QVideoFrame m_pendingFrame;
- QMutex m_frameMutex;
-#if GST_CHECK_VERSION(1,0,0)
- GstVideoInfo m_videoInfo;
-#else
- int m_bytesPerLine = 0;
-#endif
- bool m_flushing = false;
- bool m_frameProbed = false; // true if at least one frame was probed
-};
-
-QT_END_NAMESPACE
-
-#endif // QGSTREAMERVIDEOPROBECONTROL_H
diff --git a/src/gsttools/qgstreamervideorenderer.cpp b/src/gsttools/qgstreamervideorenderer.cpp
deleted file mode 100644
index c2226d658..000000000
--- a/src/gsttools/qgstreamervideorenderer.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#include "qgstreamervideorenderer_p.h"
-#include <private/qvideosurfacegstsink_p.h>
-#include <private/qgstutils_p.h>
-#include <qabstractvideosurface.h>
-#include <QtCore/qdebug.h>
-
-#include <gst/gst.h>
-
-static inline void resetSink(GstElement *&element, GstElement *v = nullptr)
-{
- if (element)
- gst_object_unref(GST_OBJECT(element));
-
- if (v)
- qt_gst_object_ref_sink(GST_OBJECT(v));
-
- element = v;
-}
-
-QGstreamerVideoRenderer::QGstreamerVideoRenderer(QObject *parent)
- : QVideoRendererControl(parent)
-{
-}
-
-QGstreamerVideoRenderer::~QGstreamerVideoRenderer()
-{
- resetSink(m_videoSink);
-}
-
-void QGstreamerVideoRenderer::setVideoSink(GstElement *sink)
-{
- if (!sink)
- return;
-
- resetSink(m_videoSink, sink);
- emit sinkChanged();
-}
-
-GstElement *QGstreamerVideoRenderer::videoSink()
-{
- if (!m_videoSink && m_surface) {
- auto sink = reinterpret_cast<GstElement *>(QVideoSurfaceGstSink::createSink(m_surface));
- resetSink(m_videoSink, sink);
- }
-
- return m_videoSink;
-}
-
-void QGstreamerVideoRenderer::stopRenderer()
-{
- if (m_surface)
- m_surface->stop();
-}
-
-QAbstractVideoSurface *QGstreamerVideoRenderer::surface() const
-{
- return m_surface;
-}
-
-void QGstreamerVideoRenderer::setSurface(QAbstractVideoSurface *surface)
-{
- if (m_surface != surface) {
- resetSink(m_videoSink);
-
- if (m_surface) {
- disconnect(m_surface.data(), SIGNAL(supportedFormatsChanged()),
- this, SLOT(handleFormatChange()));
- }
-
- bool wasReady = isReady();
-
- m_surface = surface;
-
- if (m_surface) {
- connect(m_surface.data(), SIGNAL(supportedFormatsChanged()),
- this, SLOT(handleFormatChange()));
- }
-
- if (wasReady != isReady())
- emit readyChanged(isReady());
-
- emit sinkChanged();
- }
-}
-
-void QGstreamerVideoRenderer::handleFormatChange()
-{
- setVideoSink(nullptr);
-}
diff --git a/src/gsttools/qgstreamervideorenderer_p.h b/src/gsttools/qgstreamervideorenderer_p.h
deleted file mode 100644
index d87bfcb8f..000000000
--- a/src/gsttools/qgstreamervideorenderer_p.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/****************************************************************************
-**
-** 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 QGSTREAMERVIDEORENDERER_H
-#define QGSTREAMERVIDEORENDERER_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 <private/qgsttools_global_p.h>
-#include <qvideorenderercontrol.h>
-#include <private/qvideosurfacegstsink_p.h>
-#include <qabstractvideosurface.h>
-
-#include "qgstreamervideorendererinterface_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class Q_GSTTOOLS_EXPORT QGstreamerVideoRenderer : public QVideoRendererControl, public QGstreamerVideoRendererInterface
-{
- Q_OBJECT
- Q_INTERFACES(QGstreamerVideoRendererInterface)
-public:
- QGstreamerVideoRenderer(QObject *parent = 0);
- virtual ~QGstreamerVideoRenderer();
-
- QAbstractVideoSurface *surface() const override;
- void setSurface(QAbstractVideoSurface *surface) override;
-
- GstElement *videoSink() override;
- void setVideoSink(GstElement *) override;
-
- void stopRenderer() override;
- bool isReady() const override { return m_surface != 0; }
-
-signals:
- void sinkChanged();
- void readyChanged(bool);
-
-private slots:
- void handleFormatChange();
-
-private:
- GstElement *m_videoSink = nullptr;
- QPointer<QAbstractVideoSurface> m_surface;
-};
-
-QT_END_NAMESPACE
-
-#endif // QGSTREAMERVIDEORENDRER_H
diff --git a/src/gsttools/qgstreamervideorendererinterface.cpp b/src/gsttools/qgstreamervideorendererinterface.cpp
deleted file mode 100644
index ae7de06f1..000000000
--- a/src/gsttools/qgstreamervideorendererinterface.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#include "qgstreamervideorendererinterface_p.h"
-
-QGstreamerVideoRendererInterface::~QGstreamerVideoRendererInterface()
-{
-}
diff --git a/src/gsttools/qgstreamervideorendererinterface_p.h b/src/gsttools/qgstreamervideorendererinterface_p.h
deleted file mode 100644
index 231c843db..000000000
--- a/src/gsttools/qgstreamervideorendererinterface_p.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/****************************************************************************
-**
-** 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 QGSTREAMERVIDEOOUTPUTCONTROL_H
-#define QGSTREAMERVIDEOOUTPUTCONTROL_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 <gst/gst.h>
-
-#include <QtCore/qobject.h>
-
-QT_BEGIN_NAMESPACE
-
-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
- //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/gsttools/qgstreamervideowidget.cpp b/src/gsttools/qgstreamervideowidget.cpp
deleted file mode 100644
index 4137aff32..000000000
--- a/src/gsttools/qgstreamervideowidget.cpp
+++ /dev/null
@@ -1,280 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#include "qgstreamervideowidget_p.h"
-#include "qgstutils_p.h"
-
-#include <QtCore/qcoreevent.h>
-#include <QtCore/qdebug.h>
-#include <QtGui/qpainter.h>
-
-QT_BEGIN_NAMESPACE
-
-class QGstreamerVideoWidget : public QWidget
-{
-public:
- QGstreamerVideoWidget(QWidget *parent = 0)
- :QWidget(parent)
- {
- setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
- QPalette palette;
- palette.setColor(QPalette::Window, Qt::black);
- setPalette(palette);
- }
-
- virtual ~QGstreamerVideoWidget() {}
-
- QSize sizeHint() const override
- {
- 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();
- }
- }
-
- void paint_helper()
- {
- QPainter painter(this);
- painter.fillRect(rect(), palette().window());
- }
-
-protected:
- void paintEvent(QPaintEvent *) override
- {
- paint_helper();
- }
-
- QSize m_nativeSize;
-};
-
-QGstreamerVideoWidgetControl::QGstreamerVideoWidgetControl(QObject *parent, const QByteArray &elementName)
- : QVideoWidgetControl(parent)
- , m_videoOverlay(this, !elementName.isEmpty() ? elementName : qgetenv("QT_GSTREAMER_WIDGET_VIDEOSINK"))
-{
- connect(&m_videoOverlay, &QGstreamerVideoOverlay::activeChanged,
- this, &QGstreamerVideoWidgetControl::onOverlayActiveChanged);
- connect(&m_videoOverlay, &QGstreamerVideoOverlay::nativeVideoSizeChanged,
- this, &QGstreamerVideoWidgetControl::onNativeVideoSizeChanged);
- connect(&m_videoOverlay, &QGstreamerVideoOverlay::brightnessChanged,
- this, &QGstreamerVideoWidgetControl::brightnessChanged);
- connect(&m_videoOverlay, &QGstreamerVideoOverlay::contrastChanged,
- this, &QGstreamerVideoWidgetControl::contrastChanged);
- connect(&m_videoOverlay, &QGstreamerVideoOverlay::hueChanged,
- this, &QGstreamerVideoWidgetControl::hueChanged);
- connect(&m_videoOverlay, &QGstreamerVideoOverlay::saturationChanged,
- this, &QGstreamerVideoWidgetControl::saturationChanged);
-}
-
-QGstreamerVideoWidgetControl::~QGstreamerVideoWidgetControl()
-{
- delete m_widget;
-}
-
-void QGstreamerVideoWidgetControl::createVideoWidget()
-{
- if (m_widget)
- return;
-
- m_widget = new QGstreamerVideoWidget;
-
- m_widget->installEventFilter(this);
- m_videoOverlay.setWindowHandle(m_windowId = m_widget->winId());
-}
-
-GstElement *QGstreamerVideoWidgetControl::videoSink()
-{
- return m_videoOverlay.videoSink();
-}
-
-void QGstreamerVideoWidgetControl::setVideoSink(GstElement *sink)
-{
- m_videoOverlay.setVideoSink(sink);
-}
-
-void QGstreamerVideoWidgetControl::onOverlayActiveChanged()
-{
- updateWidgetAttributes();
-}
-
-void QGstreamerVideoWidgetControl::stopRenderer()
-{
- m_stopped = true;
- updateWidgetAttributes();
- m_widget->setNativeSize(QSize());
-}
-
-void QGstreamerVideoWidgetControl::onNativeVideoSizeChanged()
-{
- const QSize &size = m_videoOverlay.nativeVideoSize();
-
- if (size.isValid())
- m_stopped = false;
-
- if (m_widget)
- m_widget->setNativeSize(size);
-}
-
-bool QGstreamerVideoWidgetControl::eventFilter(QObject *object, QEvent *e)
-{
- if (m_widget && object == m_widget) {
- if (e->type() == QEvent::ParentChange || e->type() == QEvent::Show || e->type() == QEvent::WinIdChange) {
- WId newWId = m_widget->winId();
- if (newWId != m_windowId)
- m_videoOverlay.setWindowHandle(m_windowId = newWId);
- }
-
- if (e->type() == QEvent::Paint) {
- // Update overlay by new size if any.
- if (QGstUtils::useOpenGL())
- m_videoOverlay.setRenderRectangle(QRect(0, 0, m_widget->width(), m_widget->height()));
- if (m_videoOverlay.isActive())
- m_videoOverlay.expose(); // triggers a repaint of the last frame
- else
- m_widget->paint_helper(); // paints the black background
-
- return true;
- }
- }
-
- return false;
-}
-
-void QGstreamerVideoWidgetControl::updateWidgetAttributes()
-{
- // When frames are being rendered (sink is active), we need the WA_PaintOnScreen attribute to
- // be set in order to avoid flickering when the widget is repainted (for example when resized).
- // We need to clear that flag when the the sink is inactive to allow the widget to paint its
- // background, otherwise some garbage will be displayed.
- if (m_videoOverlay.isActive() && !m_stopped) {
- m_widget->setAttribute(Qt::WA_NoSystemBackground, true);
- m_widget->setAttribute(Qt::WA_PaintOnScreen, true);
- } else {
- m_widget->setAttribute(Qt::WA_NoSystemBackground, false);
- m_widget->setAttribute(Qt::WA_PaintOnScreen, false);
- m_widget->update();
- }
-}
-
-bool QGstreamerVideoWidgetControl::processSyncMessage(const QGstreamerMessage &message)
-{
- return m_videoOverlay.processSyncMessage(message);
-}
-
-bool QGstreamerVideoWidgetControl::processBusMessage(const QGstreamerMessage &message)
-{
- return m_videoOverlay.processBusMessage(message);
-}
-
-QWidget *QGstreamerVideoWidgetControl::videoWidget()
-{
- createVideoWidget();
- return m_widget;
-}
-
-Qt::AspectRatioMode QGstreamerVideoWidgetControl::aspectRatioMode() const
-{
- return m_videoOverlay.aspectRatioMode();
-}
-
-void QGstreamerVideoWidgetControl::setAspectRatioMode(Qt::AspectRatioMode mode)
-{
- m_videoOverlay.setAspectRatioMode(mode);
-}
-
-bool QGstreamerVideoWidgetControl::isFullScreen() const
-{
- return m_fullScreen;
-}
-
-void QGstreamerVideoWidgetControl::setFullScreen(bool fullScreen)
-{
- emit fullScreenChanged(m_fullScreen = fullScreen);
-}
-
-int QGstreamerVideoWidgetControl::brightness() const
-{
- return m_videoOverlay.brightness();
-}
-
-void QGstreamerVideoWidgetControl::setBrightness(int brightness)
-{
- m_videoOverlay.setBrightness(brightness);
-}
-
-int QGstreamerVideoWidgetControl::contrast() const
-{
- return m_videoOverlay.contrast();
-}
-
-void QGstreamerVideoWidgetControl::setContrast(int contrast)
-{
- m_videoOverlay.setContrast(contrast);
-}
-
-int QGstreamerVideoWidgetControl::hue() const
-{
- return m_videoOverlay.hue();
-}
-
-void QGstreamerVideoWidgetControl::setHue(int hue)
-{
- m_videoOverlay.setHue(hue);
-}
-
-int QGstreamerVideoWidgetControl::saturation() const
-{
- return m_videoOverlay.saturation();
-}
-
-void QGstreamerVideoWidgetControl::setSaturation(int saturation)
-{
- m_videoOverlay.setSaturation(saturation);
-}
-
-QT_END_NAMESPACE
diff --git a/src/gsttools/qgstreamervideowidget_p.h b/src/gsttools/qgstreamervideowidget_p.h
deleted file mode 100644
index 6eec6ae52..000000000
--- a/src/gsttools/qgstreamervideowidget_p.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/****************************************************************************
-**
-** 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 QGSTREAMERVIDEOWIDGET_H
-#define QGSTREAMERVIDEOWIDGET_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 <private/qgsttools_global_p.h>
-#include <qvideowidgetcontrol.h>
-
-#include "qgstreamervideorendererinterface_p.h"
-#include <private/qgstreamerbushelper_p.h>
-#include <private/qgstreamervideooverlay_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class Q_GSTTOOLS_EXPORT QGstreamerVideoWidget;
-
-class Q_GSTTOOLS_EXPORT QGstreamerVideoWidgetControl
- : public QVideoWidgetControl
- , public QGstreamerVideoRendererInterface
- , public QGstreamerSyncMessageFilter
- , public QGstreamerBusMessageFilter
-{
- Q_OBJECT
- Q_INTERFACES(QGstreamerVideoRendererInterface QGstreamerSyncMessageFilter QGstreamerBusMessageFilter)
-public:
- explicit QGstreamerVideoWidgetControl(QObject *parent = 0, const QByteArray &elementName = QByteArray());
- virtual ~QGstreamerVideoWidgetControl();
-
- GstElement *videoSink() override;
- void setVideoSink(GstElement *) override;
-
- QWidget *videoWidget() override;
-
- void stopRenderer() override;
-
- Qt::AspectRatioMode aspectRatioMode() const override;
- void setAspectRatioMode(Qt::AspectRatioMode mode) override;
-
- bool isFullScreen() const override;
- void setFullScreen(bool fullScreen) override;
-
- int brightness() const override;
- void setBrightness(int brightness) override;
-
- int contrast() const override;
- void setContrast(int contrast) override;
-
- int hue() const override;
- void setHue(int hue) override;
-
- int saturation() const override;
- void setSaturation(int saturation) override;
-
- bool eventFilter(QObject *object, QEvent *event) override;
-
-signals:
- void sinkChanged();
- void readyChanged(bool);
-
-private Q_SLOTS:
- void onOverlayActiveChanged();
- void onNativeVideoSizeChanged();
-
-private:
- void createVideoWidget();
- void updateWidgetAttributes();
-
- bool processSyncMessage(const QGstreamerMessage &message) override;
- bool processBusMessage(const QGstreamerMessage &message) override;
-
- QGstreamerVideoOverlay m_videoOverlay;
- QGstreamerVideoWidget *m_widget = nullptr;
- bool m_stopped = false;
- WId m_windowId = 0;
- bool m_fullScreen = false;
-};
-
-QT_END_NAMESPACE
-
-#endif // QGSTREAMERVIDEOWIDGET_H
diff --git a/src/gsttools/qgstreamervideowindow.cpp b/src/gsttools/qgstreamervideowindow.cpp
deleted file mode 100644
index e7e3c5044..000000000
--- a/src/gsttools/qgstreamervideowindow.cpp
+++ /dev/null
@@ -1,179 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#include "qgstreamervideowindow_p.h"
-#include <private/qgstutils_p.h>
-
-#include <QtCore/qdebug.h>
-
-QGstreamerVideoWindow::QGstreamerVideoWindow(QObject *parent, const QByteArray &elementName)
- : QVideoWindowControl(parent)
- , m_videoOverlay(this, !elementName.isEmpty() ? elementName : qgetenv("QT_GSTREAMER_WINDOW_VIDEOSINK"))
-{
- connect(&m_videoOverlay, &QGstreamerVideoOverlay::nativeVideoSizeChanged,
- this, &QGstreamerVideoWindow::nativeSizeChanged);
- connect(&m_videoOverlay, &QGstreamerVideoOverlay::brightnessChanged,
- this, &QGstreamerVideoWindow::brightnessChanged);
- connect(&m_videoOverlay, &QGstreamerVideoOverlay::contrastChanged,
- this, &QGstreamerVideoWindow::contrastChanged);
- connect(&m_videoOverlay, &QGstreamerVideoOverlay::hueChanged,
- this, &QGstreamerVideoWindow::hueChanged);
- connect(&m_videoOverlay, &QGstreamerVideoOverlay::saturationChanged,
- this, &QGstreamerVideoWindow::saturationChanged);
-}
-
-QGstreamerVideoWindow::~QGstreamerVideoWindow()
-{
-}
-
-GstElement *QGstreamerVideoWindow::videoSink()
-{
- return m_videoOverlay.videoSink();
-}
-
-WId QGstreamerVideoWindow::winId() const
-{
- return m_windowId;
-}
-
-void QGstreamerVideoWindow::setWinId(WId id)
-{
- if (m_windowId == id)
- return;
-
- WId oldId = m_windowId;
- m_videoOverlay.setWindowHandle(m_windowId = id);
-
- if (!oldId)
- emit readyChanged(true);
-
- if (!id)
- emit readyChanged(false);
-}
-
-bool QGstreamerVideoWindow::processSyncMessage(const QGstreamerMessage &message)
-{
- return m_videoOverlay.processSyncMessage(message);
-}
-
-bool QGstreamerVideoWindow::processBusMessage(const QGstreamerMessage &message)
-{
- return m_videoOverlay.processBusMessage(message);
-}
-
-QRect QGstreamerVideoWindow::displayRect() const
-{
- return m_displayRect;
-}
-
-void QGstreamerVideoWindow::setDisplayRect(const QRect &rect)
-{
- m_videoOverlay.setRenderRectangle(m_displayRect = rect);
- repaint();
-}
-
-Qt::AspectRatioMode QGstreamerVideoWindow::aspectRatioMode() const
-{
- return m_videoOverlay.aspectRatioMode();
-}
-
-void QGstreamerVideoWindow::setAspectRatioMode(Qt::AspectRatioMode mode)
-{
- m_videoOverlay.setAspectRatioMode(mode);
-}
-
-void QGstreamerVideoWindow::repaint()
-{
- m_videoOverlay.expose();
-}
-
-int QGstreamerVideoWindow::brightness() const
-{
- return m_videoOverlay.brightness();
-}
-
-void QGstreamerVideoWindow::setBrightness(int brightness)
-{
- m_videoOverlay.setBrightness(brightness);
-}
-
-int QGstreamerVideoWindow::contrast() const
-{
- return m_videoOverlay.contrast();
-}
-
-void QGstreamerVideoWindow::setContrast(int contrast)
-{
- m_videoOverlay.setContrast(contrast);
-}
-
-int QGstreamerVideoWindow::hue() const
-{
- return m_videoOverlay.hue();
-}
-
-void QGstreamerVideoWindow::setHue(int hue)
-{
- m_videoOverlay.setHue(hue);
-}
-
-int QGstreamerVideoWindow::saturation() const
-{
- return m_videoOverlay.saturation();
-}
-
-void QGstreamerVideoWindow::setSaturation(int saturation)
-{
- m_videoOverlay.setSaturation(saturation);
-}
-
-bool QGstreamerVideoWindow::isFullScreen() const
-{
- return m_fullScreen;
-}
-
-void QGstreamerVideoWindow::setFullScreen(bool fullScreen)
-{
- emit fullScreenChanged(m_fullScreen = fullScreen);
-}
-
-QSize QGstreamerVideoWindow::nativeSize() const
-{
- return m_videoOverlay.nativeVideoSize();
-}
diff --git a/src/gsttools/qgstreamervideowindow_p.h b/src/gsttools/qgstreamervideowindow_p.h
deleted file mode 100644
index a0ed8599b..000000000
--- a/src/gsttools/qgstreamervideowindow_p.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/****************************************************************************
-**
-** 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 QGSTREAMERVIDEOWINDOW_H
-#define QGSTREAMERVIDEOWINDOW_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 <private/qgsttools_global_p.h>
-#include <qvideowindowcontrol.h>
-
-#include "qgstreamervideorendererinterface_p.h"
-#include <private/qgstreamerbushelper_p.h>
-#include <private/qgstreamervideooverlay_p.h>
-#include <QtGui/qcolor.h>
-
-QT_BEGIN_NAMESPACE
-class QAbstractVideoSurface;
-
-class Q_GSTTOOLS_EXPORT QGstreamerVideoWindow :
- public QVideoWindowControl,
- public QGstreamerVideoRendererInterface,
- public QGstreamerSyncMessageFilter,
- public QGstreamerBusMessageFilter
-{
- Q_OBJECT
- Q_INTERFACES(QGstreamerVideoRendererInterface QGstreamerSyncMessageFilter QGstreamerBusMessageFilter)
-public:
- explicit QGstreamerVideoWindow(QObject *parent = 0, const QByteArray &elementName = QByteArray());
- ~QGstreamerVideoWindow();
-
- WId winId() const override;
- void setWinId(WId id) override;
-
- QRect displayRect() const override;
- void setDisplayRect(const QRect &rect) override;
-
- bool isFullScreen() const override;
- void setFullScreen(bool fullScreen) override;
-
- QSize nativeSize() const override;
-
- Qt::AspectRatioMode aspectRatioMode() const override;
- void setAspectRatioMode(Qt::AspectRatioMode mode) override;
-
- void repaint() override;
-
- int brightness() const override;
- void setBrightness(int brightness) override;
-
- int contrast() const override;
- void setContrast(int contrast) override;
-
- int hue() const override;
- void setHue(int hue) override;
-
- int saturation() const override;
- void setSaturation(int saturation) override;
-
- QAbstractVideoSurface *surface() const;
-
- GstElement *videoSink() override;
-
- bool processSyncMessage(const QGstreamerMessage &message) override;
- bool processBusMessage(const QGstreamerMessage &message) override;
- bool isReady() const override { return m_windowId != 0; }
-
-signals:
- void sinkChanged();
- void readyChanged(bool);
-
-private:
- QGstreamerVideoOverlay m_videoOverlay;
- WId m_windowId = 0;
- QRect m_displayRect;
- bool m_fullScreen = false;
- mutable QColor m_colorKey = QColor::Invalid;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/gsttools/qgsttools_global_p.h b/src/gsttools/qgsttools_global_p.h
deleted file mode 100644
index babcd3aaf..000000000
--- a/src/gsttools/qgsttools_global_p.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 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 QGSTTOOLS_GLOBAL_H
-#define QGSTTOOLS_GLOBAL_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/qglobal.h>
-
-QT_BEGIN_NAMESPACE
-
-#ifndef QT_STATIC
-# if defined(QT_BUILD_MULTIMEDIAGSTTOOLS_LIB)
-# define Q_GSTTOOLS_EXPORT Q_DECL_EXPORT
-# else
-# define Q_GSTTOOLS_EXPORT Q_DECL_IMPORT
-# endif
-#else
-# define Q_GSTTOOLS_EXPORT
-#endif
-
-QT_END_NAMESPACE
-
-#endif // QGSTTOOLS_GLOBAL_H
diff --git a/src/gsttools/qgstutils.cpp b/src/gsttools/qgstutils.cpp
deleted file mode 100644
index 5c8d4c90c..000000000
--- a/src/gsttools/qgstutils.cpp
+++ /dev/null
@@ -1,1746 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#include <QtMultimedia/private/qtmultimediaglobal_p.h>
-#include "qgstutils_p.h"
-
-#include <QtCore/qdatetime.h>
-#include <QtCore/qdir.h>
-#include <QtCore/qbytearray.h>
-#include <QtCore/qvariant.h>
-#include <QtCore/qregularexpression.h>
-#include <QtCore/qsize.h>
-#include <QtCore/qset.h>
-#include <QtCore/qstringlist.h>
-#include <QtGui/qimage.h>
-#include <qaudioformat.h>
-#include <QtCore/qelapsedtimer.h>
-#include <QtMultimedia/qvideosurfaceformat.h>
-#include <private/qmultimediautils_p.h>
-
-#include <gst/audio/audio.h>
-#include <gst/video/video.h>
-
-template<typename T, int N> static int lengthOf(const T (&)[N]) { return N; }
-
-#if QT_CONFIG(linux_v4l)
-# include <private/qcore_unix_p.h>
-# include <linux/videodev2.h>
-#endif
-
-#include "qgstreamervideoinputdevicecontrol_p.h"
-
-QT_BEGIN_NAMESPACE
-
-//internal
-static void addTagToMap(const GstTagList *list,
- const gchar *tag,
- gpointer user_data)
-{
- QMap<QByteArray, QVariant> *map = reinterpret_cast<QMap<QByteArray, QVariant>* >(user_data);
-
- GValue val;
- val.g_type = 0;
- gst_tag_list_copy_value(&val,list,tag);
-
- switch( G_VALUE_TYPE(&val) ) {
- case G_TYPE_STRING:
- {
- const gchar *str_value = g_value_get_string(&val);
- map->insert(QByteArray(tag), QString::fromUtf8(str_value));
- break;
- }
- case G_TYPE_INT:
- map->insert(QByteArray(tag), g_value_get_int(&val));
- break;
- case G_TYPE_UINT:
- map->insert(QByteArray(tag), g_value_get_uint(&val));
- break;
- case G_TYPE_LONG:
- map->insert(QByteArray(tag), qint64(g_value_get_long(&val)));
- break;
- case G_TYPE_BOOLEAN:
- map->insert(QByteArray(tag), g_value_get_boolean(&val));
- break;
- case G_TYPE_CHAR:
-#if GLIB_CHECK_VERSION(2,32,0)
- map->insert(QByteArray(tag), g_value_get_schar(&val));
-#else
- map->insert(QByteArray(tag), g_value_get_char(&val));
-#endif
- break;
- case G_TYPE_DOUBLE:
- map->insert(QByteArray(tag), g_value_get_double(&val));
- break;
- default:
- // GST_TYPE_DATE is a function, not a constant, so pull it out of the switch
-#if GST_CHECK_VERSION(1,0,0)
- if (G_VALUE_TYPE(&val) == G_TYPE_DATE) {
- const GDate *date = (const GDate *)g_value_get_boxed(&val);
-#else
- if (G_VALUE_TYPE(&val) == GST_TYPE_DATE) {
- const GDate *date = gst_value_get_date(&val);
-#endif
- if (g_date_valid(date)) {
- int year = g_date_get_year(date);
- int month = g_date_get_month(date);
- int day = g_date_get_day(date);
- map->insert(QByteArray(tag), QDate(year,month,day));
- if (!map->contains("year"))
- map->insert("year", year);
- }
-#if GST_CHECK_VERSION(1,0,0)
- } else if (G_VALUE_TYPE(&val) == GST_TYPE_DATE_TIME) {
- const GstDateTime *dateTime = (const GstDateTime *)g_value_get_boxed(&val);
- int year = gst_date_time_has_year(dateTime) ? gst_date_time_get_year(dateTime) : 0;
- int month = gst_date_time_has_month(dateTime) ? gst_date_time_get_month(dateTime) : 0;
- int day = gst_date_time_has_day(dateTime) ? gst_date_time_get_day(dateTime) : 0;
- if (gst_date_time_has_time(dateTime)) {
- int hour = gst_date_time_get_hour(dateTime);
- int minute = gst_date_time_get_minute(dateTime);
- int second = gst_date_time_get_second(dateTime);
- float tz = gst_date_time_get_time_zone_offset(dateTime);
- QDateTime dateTime(QDate(year, month, day), QTime(hour, minute, second),
- Qt::OffsetFromUTC, tz * 60 * 60);
- map->insert(QByteArray(tag), dateTime);
- } else if (year > 0 && month > 0 && day > 0) {
- map->insert(QByteArray(tag), QDate(year,month,day));
- }
- if (!map->contains("year") && year > 0)
- map->insert("year", year);
- } else if (G_VALUE_TYPE(&val) == GST_TYPE_SAMPLE) {
- GstSample *sample = (GstSample *)g_value_get_boxed(&val);
- GstCaps* caps = gst_sample_get_caps(sample);
- if (caps && !gst_caps_is_empty(caps)) {
- GstStructure *structure = gst_caps_get_structure(caps, 0);
- const gchar *name = gst_structure_get_name(structure);
- if (QByteArray(name).startsWith("image/")) {
- GstBuffer *buffer = gst_sample_get_buffer(sample);
- if (buffer) {
- GstMapInfo info;
- gst_buffer_map(buffer, &info, GST_MAP_READ);
- map->insert(QByteArray(tag), QImage::fromData(info.data, info.size, name));
- gst_buffer_unmap(buffer, &info);
- }
- }
- }
-#endif
- } else if (G_VALUE_TYPE(&val) == GST_TYPE_FRACTION) {
- int nom = gst_value_get_fraction_numerator(&val);
- int denom = gst_value_get_fraction_denominator(&val);
-
- if (denom > 0) {
- map->insert(QByteArray(tag), double(nom)/denom);
- }
- }
- break;
- }
-
- g_value_unset(&val);
-}
-
-/*!
- \class QGstUtils
- \internal
-*/
-
-/*!
- Convert GstTagList structure to QMap<QByteArray, QVariant>.
-
- Mapping to int, bool, char, string, fractions and date are supported.
- Fraction values are converted to doubles.
-*/
-QMap<QByteArray, QVariant> QGstUtils::gstTagListToMap(const GstTagList *tags)
-{
- QMap<QByteArray, QVariant> res;
- gst_tag_list_foreach(tags, addTagToMap, &res);
-
- return res;
-}
-
-/*!
- Returns resolution of \a caps.
- If caps doesn't have a valid size, an empty QSize is returned.
-*/
-QSize QGstUtils::capsResolution(const GstCaps *caps)
-{
- if (gst_caps_get_size(caps) == 0)
- return QSize();
-
- return structureResolution(gst_caps_get_structure(caps, 0));
-}
-
-/*!
- Returns aspect ratio corrected resolution of \a caps.
- If caps doesn't have a valid size, an empty QSize is returned.
-*/
-QSize QGstUtils::capsCorrectedResolution(const GstCaps *caps)
-{
- QSize size;
-
- if (caps) {
- size = capsResolution(caps);
-
- gint aspectNum = 0;
- gint aspectDenum = 0;
- if (!size.isEmpty() && gst_structure_get_fraction(
- gst_caps_get_structure(caps, 0), "pixel-aspect-ratio", &aspectNum, &aspectDenum)) {
- if (aspectDenum > 0)
- size.setWidth(size.width()*aspectNum/aspectDenum);
- }
- }
-
- return size;
-}
-
-
-#if GST_CHECK_VERSION(1,0,0)
-namespace {
-
-struct AudioFormat
-{
- GstAudioFormat format;
- QAudioFormat::SampleType sampleType;
- QAudioFormat::Endian byteOrder;
- int sampleSize;
-};
-static const AudioFormat qt_audioLookup[] =
-{
- { GST_AUDIO_FORMAT_S8 , QAudioFormat::SignedInt , QAudioFormat::LittleEndian, 8 },
- { GST_AUDIO_FORMAT_U8 , QAudioFormat::UnSignedInt, QAudioFormat::LittleEndian, 8 },
- { GST_AUDIO_FORMAT_S16LE, QAudioFormat::SignedInt , QAudioFormat::LittleEndian, 16 },
- { GST_AUDIO_FORMAT_S16BE, QAudioFormat::SignedInt , QAudioFormat::BigEndian , 16 },
- { GST_AUDIO_FORMAT_U16LE, QAudioFormat::UnSignedInt, QAudioFormat::LittleEndian, 16 },
- { GST_AUDIO_FORMAT_U16BE, QAudioFormat::UnSignedInt, QAudioFormat::BigEndian , 16 },
- { GST_AUDIO_FORMAT_S32LE, QAudioFormat::SignedInt , QAudioFormat::LittleEndian, 32 },
- { GST_AUDIO_FORMAT_S32BE, QAudioFormat::SignedInt , QAudioFormat::BigEndian , 32 },
- { GST_AUDIO_FORMAT_U32LE, QAudioFormat::UnSignedInt, QAudioFormat::LittleEndian, 32 },
- { GST_AUDIO_FORMAT_U32BE, QAudioFormat::UnSignedInt, QAudioFormat::BigEndian , 32 },
- { GST_AUDIO_FORMAT_S24LE, QAudioFormat::SignedInt , QAudioFormat::LittleEndian, 24 },
- { GST_AUDIO_FORMAT_S24BE, QAudioFormat::SignedInt , QAudioFormat::BigEndian , 24 },
- { GST_AUDIO_FORMAT_U24LE, QAudioFormat::UnSignedInt, QAudioFormat::LittleEndian, 24 },
- { GST_AUDIO_FORMAT_U24BE, QAudioFormat::UnSignedInt, QAudioFormat::BigEndian , 24 },
- { GST_AUDIO_FORMAT_F32LE, QAudioFormat::Float , QAudioFormat::LittleEndian, 32 },
- { GST_AUDIO_FORMAT_F32BE, QAudioFormat::Float , QAudioFormat::BigEndian , 32 },
- { GST_AUDIO_FORMAT_F64LE, QAudioFormat::Float , QAudioFormat::LittleEndian, 64 },
- { GST_AUDIO_FORMAT_F64BE, QAudioFormat::Float , QAudioFormat::BigEndian , 64 }
-};
-
-}
-#endif
-
-/*!
- Returns audio format for caps.
- If caps doesn't have a valid audio format, an empty QAudioFormat is returned.
-*/
-
-QAudioFormat QGstUtils::audioFormatForCaps(const GstCaps *caps)
-{
- QAudioFormat format;
-#if GST_CHECK_VERSION(1,0,0)
- GstAudioInfo info;
- if (gst_audio_info_from_caps(&info, caps)) {
- for (int i = 0; i < lengthOf(qt_audioLookup); ++i) {
- if (qt_audioLookup[i].format != info.finfo->format)
- continue;
-
- format.setSampleType(qt_audioLookup[i].sampleType);
- format.setByteOrder(qt_audioLookup[i].byteOrder);
- format.setSampleSize(qt_audioLookup[i].sampleSize);
- format.setSampleRate(info.rate);
- format.setChannelCount(info.channels);
- format.setCodec(QStringLiteral("audio/pcm"));
-
- return format;
- }
- }
-#else
- const GstStructure *structure = gst_caps_get_structure(caps, 0);
-
- if (qstrcmp(gst_structure_get_name(structure), "audio/x-raw-int") == 0) {
-
- format.setCodec("audio/pcm");
-
- int endianness = 0;
- gst_structure_get_int(structure, "endianness", &endianness);
- if (endianness == 1234)
- format.setByteOrder(QAudioFormat::LittleEndian);
- else if (endianness == 4321)
- format.setByteOrder(QAudioFormat::BigEndian);
-
- gboolean isSigned = FALSE;
- gst_structure_get_boolean(structure, "signed", &isSigned);
- if (isSigned)
- format.setSampleType(QAudioFormat::SignedInt);
- else
- format.setSampleType(QAudioFormat::UnSignedInt);
-
- // Number of bits allocated per sample.
- int width = 0;
- gst_structure_get_int(structure, "width", &width);
-
- // The number of bits used per sample. This must be less than or equal to the width.
- int depth = 0;
- gst_structure_get_int(structure, "depth", &depth);
-
- if (width != depth) {
- // Unsupported sample layout.
- return QAudioFormat();
- }
- format.setSampleSize(width);
-
- int rate = 0;
- gst_structure_get_int(structure, "rate", &rate);
- format.setSampleRate(rate);
-
- int channels = 0;
- gst_structure_get_int(structure, "channels", &channels);
- format.setChannelCount(channels);
-
- } else if (qstrcmp(gst_structure_get_name(structure), "audio/x-raw-float") == 0) {
-
- format.setCodec("audio/pcm");
-
- int endianness = 0;
- gst_structure_get_int(structure, "endianness", &endianness);
- if (endianness == 1234)
- format.setByteOrder(QAudioFormat::LittleEndian);
- else if (endianness == 4321)
- format.setByteOrder(QAudioFormat::BigEndian);
-
- format.setSampleType(QAudioFormat::Float);
-
- int width = 0;
- gst_structure_get_int(structure, "width", &width);
-
- format.setSampleSize(width);
-
- int rate = 0;
- gst_structure_get_int(structure, "rate", &rate);
- format.setSampleRate(rate);
-
- int channels = 0;
- gst_structure_get_int(structure, "channels", &channels);
- format.setChannelCount(channels);
-
- } else {
- return QAudioFormat();
- }
-#endif
- return format;
-}
-
-#if GST_CHECK_VERSION(1,0,0)
-/*
- Returns audio format for a sample.
- If the buffer doesn't have a valid audio format, an empty QAudioFormat is returned.
-*/
-QAudioFormat QGstUtils::audioFormatForSample(GstSample *sample)
-{
- GstCaps* caps = gst_sample_get_caps(sample);
- if (!caps)
- return QAudioFormat();
-
- return QGstUtils::audioFormatForCaps(caps);
-}
-#else
-/*!
- Returns audio format for a buffer.
- If the buffer doesn't have a valid audio format, an empty QAudioFormat is returned.
-*/
-QAudioFormat QGstUtils::audioFormatForBuffer(GstBuffer *buffer)
-{
- GstCaps* caps = gst_buffer_get_caps(buffer);
- if (!caps)
- return QAudioFormat();
-
- QAudioFormat format = QGstUtils::audioFormatForCaps(caps);
- gst_caps_unref(caps);
- return format;
-}
-#endif
-
-/*!
- Builds GstCaps for an audio format.
- Returns 0 if the audio format is not valid.
- Caller must unref GstCaps.
-*/
-
-GstCaps *QGstUtils::capsForAudioFormat(const QAudioFormat &format)
-{
- if (!format.isValid())
- return 0;
-
-#if GST_CHECK_VERSION(1,0,0)
- const QAudioFormat::SampleType sampleType = format.sampleType();
- const QAudioFormat::Endian byteOrder = format.byteOrder();
- const int sampleSize = format.sampleSize();
-
- for (int i = 0; i < lengthOf(qt_audioLookup); ++i) {
- if (qt_audioLookup[i].sampleType != sampleType
- || qt_audioLookup[i].byteOrder != byteOrder
- || qt_audioLookup[i].sampleSize != sampleSize) {
- continue;
- }
-
- return gst_caps_new_simple(
- "audio/x-raw",
- "format" , G_TYPE_STRING, gst_audio_format_to_string(qt_audioLookup[i].format),
- "rate" , G_TYPE_INT , format.sampleRate(),
- "channels", G_TYPE_INT , format.channelCount(),
- nullptr);
- }
- return 0;
-#else
- GstStructure *structure = 0;
-
- if (format.isValid()) {
- if (format.sampleType() == QAudioFormat::SignedInt || format.sampleType() == QAudioFormat::UnSignedInt) {
- structure = gst_structure_new("audio/x-raw-int", nullptr);
- } else if (format.sampleType() == QAudioFormat::Float) {
- structure = gst_structure_new("audio/x-raw-float", nullptr);
- }
- }
-
- GstCaps *caps = 0;
-
- if (structure) {
- gst_structure_set(structure, "rate", G_TYPE_INT, format.sampleRate(), nullptr);
- gst_structure_set(structure, "channels", G_TYPE_INT, format.channelCount(), nullptr);
- gst_structure_set(structure, "width", G_TYPE_INT, format.sampleSize(), nullptr);
- gst_structure_set(structure, "depth", G_TYPE_INT, format.sampleSize(), nullptr);
-
- if (format.byteOrder() == QAudioFormat::LittleEndian)
- gst_structure_set(structure, "endianness", G_TYPE_INT, 1234, nullptr);
- else if (format.byteOrder() == QAudioFormat::BigEndian)
- gst_structure_set(structure, "endianness", G_TYPE_INT, 4321, nullptr);
-
- if (format.sampleType() == QAudioFormat::SignedInt)
- gst_structure_set(structure, "signed", G_TYPE_BOOLEAN, TRUE, nullptr);
- else if (format.sampleType() == QAudioFormat::UnSignedInt)
- gst_structure_set(structure, "signed", G_TYPE_BOOLEAN, FALSE, nullptr);
-
- caps = gst_caps_new_empty();
- Q_ASSERT(caps);
- gst_caps_append_structure(caps, structure);
- }
-
- return caps;
-#endif
-}
-
-void QGstUtils::initializeGst()
-{
- static bool initialized = false;
- if (!initialized) {
- initialized = true;
- gst_init(nullptr, nullptr);
- }
-}
-
-namespace {
- const char* getCodecAlias(const QString &codec)
- {
- if (codec.startsWith(QLatin1String("avc1.")))
- return "video/x-h264";
-
- if (codec.startsWith(QLatin1String("mp4a.")))
- return "audio/mpeg4";
-
- if (codec.startsWith(QLatin1String("mp4v.20.")))
- return "video/mpeg4";
-
- if (codec == QLatin1String("samr"))
- return "audio/amr";
-
- return 0;
- }
-
- const char* getMimeTypeAlias(const QString &mimeType)
- {
- if (mimeType == QLatin1String("video/mp4"))
- return "video/mpeg4";
-
- if (mimeType == QLatin1String("audio/mp4"))
- return "audio/mpeg4";
-
- if (mimeType == QLatin1String("video/ogg")
- || mimeType == QLatin1String("audio/ogg"))
- return "application/ogg";
-
- return 0;
- }
-}
-
-QMultimedia::SupportEstimate QGstUtils::hasSupport(const QString &mimeType,
- const QStringList &codecs,
- const QSet<QString> &supportedMimeTypeSet)
-{
- if (supportedMimeTypeSet.isEmpty())
- return QMultimedia::NotSupported;
-
- QString mimeTypeLowcase = mimeType.toLower();
- bool containsMimeType = supportedMimeTypeSet.contains(mimeTypeLowcase);
- if (!containsMimeType) {
- const char* mimeTypeAlias = getMimeTypeAlias(mimeTypeLowcase);
- containsMimeType = supportedMimeTypeSet.contains(QLatin1String(mimeTypeAlias));
- if (!containsMimeType) {
- containsMimeType = supportedMimeTypeSet.contains(QLatin1String("video/") + mimeTypeLowcase)
- || supportedMimeTypeSet.contains(QLatin1String("video/x-") + mimeTypeLowcase)
- || supportedMimeTypeSet.contains(QLatin1String("audio/") + mimeTypeLowcase)
- || supportedMimeTypeSet.contains(QLatin1String("audio/x-") + mimeTypeLowcase);
- }
- }
-
- int supportedCodecCount = 0;
- for (const QString &codec : codecs) {
- QString codecLowcase = codec.toLower();
- const char* codecAlias = getCodecAlias(codecLowcase);
- if (codecAlias) {
- if (supportedMimeTypeSet.contains(QLatin1String(codecAlias)))
- supportedCodecCount++;
- } else if (supportedMimeTypeSet.contains(QLatin1String("video/") + codecLowcase)
- || supportedMimeTypeSet.contains(QLatin1String("video/x-") + codecLowcase)
- || supportedMimeTypeSet.contains(QLatin1String("audio/") + codecLowcase)
- || supportedMimeTypeSet.contains(QLatin1String("audio/x-") + codecLowcase)) {
- supportedCodecCount++;
- }
- }
- if (supportedCodecCount > 0 && supportedCodecCount == codecs.size())
- return QMultimedia::ProbablySupported;
-
- if (supportedCodecCount == 0 && !containsMimeType)
- return QMultimedia::NotSupported;
-
- return QMultimedia::MaybeSupported;
-}
-
-namespace {
-
-typedef QHash<GstElementFactory *, QList<QGstUtils::CameraInfo>> FactoryCameraInfoMap;
-
-Q_GLOBAL_STATIC(FactoryCameraInfoMap, qt_camera_device_info);
-
-}
-
-QList<QGstUtils::CameraInfo> QGstUtils::enumerateCameras(GstElementFactory *factory)
-{
- static QElapsedTimer camerasCacheAgeTimer;
- if (camerasCacheAgeTimer.isValid() && camerasCacheAgeTimer.elapsed() > 500) // ms
- qt_camera_device_info()->clear();
-
- FactoryCameraInfoMap::const_iterator it = qt_camera_device_info()->constFind(factory);
- if (it != qt_camera_device_info()->constEnd())
- return *it;
-
- QList<CameraInfo> &devices = (*qt_camera_device_info())[factory];
-
- if (factory) {
- bool hasVideoSource = false;
-
- const GType type = gst_element_factory_get_element_type(factory);
- GObjectClass * const objectClass = type
- ? static_cast<GObjectClass *>(g_type_class_ref(type))
- : 0;
- if (objectClass) {
- if (g_object_class_find_property(objectClass, "camera-device")) {
- const CameraInfo primary = {
- QStringLiteral("primary"),
- QGstreamerVideoInputDeviceControl::primaryCamera(),
- 0,
- QCamera::BackFace,
- QByteArray()
- };
- const CameraInfo secondary = {
- QStringLiteral("secondary"),
- QGstreamerVideoInputDeviceControl::secondaryCamera(),
- 0,
- QCamera::FrontFace,
- QByteArray()
- };
-
- devices.append(primary);
- devices.append(secondary);
-
- GstElement *camera = g_object_class_find_property(objectClass, "sensor-mount-angle")
- ? gst_element_factory_create(factory, 0)
- : 0;
- if (camera) {
- if (gst_element_set_state(camera, GST_STATE_READY) != GST_STATE_CHANGE_SUCCESS) {
- // no-op
- } else for (int i = 0; i < 2; ++i) {
- gint orientation = 0;
- g_object_set(G_OBJECT(camera), "camera-device", i, nullptr);
- g_object_get(G_OBJECT(camera), "sensor-mount-angle", &orientation, nullptr);
-
- devices[i].orientation = (720 - orientation) % 360;
- }
- gst_element_set_state(camera, GST_STATE_NULL);
- gst_object_unref(GST_OBJECT(camera));
-
- }
- } else if (g_object_class_find_property(objectClass, "video-source")) {
- hasVideoSource = true;
- }
-
- g_type_class_unref(objectClass);
- }
-
- if (!devices.isEmpty() || !hasVideoSource) {
- camerasCacheAgeTimer.restart();
- return devices;
- }
- }
-
-#if QT_CONFIG(linux_v4l)
- QDir devDir(QStringLiteral("/dev"));
- devDir.setFilter(QDir::System);
-
- const QFileInfoList entries = devDir.entryInfoList(QStringList()
- << QStringLiteral("video*"));
-
- for (const QFileInfo &entryInfo : entries) {
- //qDebug() << "Try" << entryInfo.filePath();
-
- int fd = qt_safe_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) {
- const int ret = ::ioctl(fd, VIDIOC_S_INPUT, &input.index);
- isCamera = (ret == 0 || errno == ENOTTY || errno == EBUSY);
- break;
- }
- }
-
- if (isCamera) {
- // find out its driver "name"
- QByteArray driver;
- QString name;
- struct v4l2_capability vcap;
- memset(&vcap, 0, sizeof(struct v4l2_capability));
-
- if (ioctl(fd, VIDIOC_QUERYCAP, &vcap) != 0) {
- name = entryInfo.fileName();
- } else {
- driver = QByteArray((const char*)vcap.driver);
- name = QString::fromUtf8((const char*)vcap.card);
- if (name.isEmpty())
- name = entryInfo.fileName();
- }
- //qDebug() << "found camera: " << name;
-
-
- CameraInfo device = {
- entryInfo.absoluteFilePath(),
- name,
- 0,
- QCamera::UnspecifiedPosition,
- driver
- };
- devices.append(device);
- }
- qt_safe_close(fd);
- }
- camerasCacheAgeTimer.restart();
-#endif // linux_v4l
-
-#if GST_CHECK_VERSION(1,4,0) && (defined(Q_OS_WIN) || defined(Q_OS_MACOS))
- if (!devices.isEmpty())
- return devices;
-
-#if defined(Q_OS_WIN)
- const char *propName = "device-path";
- auto deviceDesc = [](GValue *value) {
- gchar *desc = g_value_dup_string(value);
- const QString id = QLatin1String(desc);
- g_free(desc);
- return id;
- };
-#elif defined(Q_OS_MACOS)
- const char *propName = "device-index";
- auto deviceDesc = [](GValue *value) {
- return QString::number(g_value_get_int(value));
- };
-#endif
-
- QGstUtils::initializeGst();
- GstDeviceMonitor *monitor = gst_device_monitor_new();
- auto caps = gst_caps_new_empty_simple("video/x-raw");
- gst_device_monitor_add_filter(monitor, "Video/Source", caps);
- gst_caps_unref(caps);
-
- GList *devs = gst_device_monitor_get_devices(monitor);
- while (devs) {
- GstDevice *dev = reinterpret_cast<GstDevice*>(devs->data);
- GstElement *element = gst_device_create_element(dev, nullptr);
- if (element) {
- gchar *name = gst_device_get_display_name(dev);
- const QString deviceName = QLatin1String(name);
- g_free(name);
- GParamSpec *prop = g_object_class_find_property(G_OBJECT_GET_CLASS(element), propName);
- if (prop) {
- GValue value = G_VALUE_INIT;
- g_value_init(&value, prop->value_type);
- g_object_get_property(G_OBJECT(element), prop->name, &value);
- const QString deviceId = deviceDesc(&value);
- g_value_unset(&value);
-
- CameraInfo device = {
- deviceId,
- deviceName,
- 0,
- QCamera::UnspecifiedPosition,
- QByteArray()
- };
-
- devices.append(device);
- }
-
- gst_object_unref(element);
- }
-
- gst_object_unref(dev);
- devs = g_list_delete_link(devs, devs);
- }
- gst_object_unref(monitor);
-#endif // GST_CHECK_VERSION(1,4,0) && (defined(Q_OS_WIN) || defined(Q_OS_MACOS))
-
- return devices;
-}
-
-QList<QByteArray> QGstUtils::cameraDevices(GstElementFactory * factory)
-{
- QList<QByteArray> devices;
-
- const auto cameras = enumerateCameras(factory);
- devices.reserve(cameras.size());
- for (const CameraInfo &camera : cameras)
- devices.append(camera.name.toUtf8());
-
- return devices;
-}
-
-QString QGstUtils::cameraDescription(const QString &device, GstElementFactory * factory)
-{
- const auto cameras = enumerateCameras(factory);
- for (const CameraInfo &camera : cameras) {
- if (camera.name == device)
- return camera.description;
- }
- return QString();
-}
-
-QCamera::Position QGstUtils::cameraPosition(const QString &device, GstElementFactory * factory)
-{
- const auto cameras = enumerateCameras(factory);
- for (const CameraInfo &camera : cameras) {
- if (camera.name == device)
- return camera.position;
- }
- return QCamera::UnspecifiedPosition;
-}
-
-int QGstUtils::cameraOrientation(const QString &device, GstElementFactory * factory)
-{
- const auto cameras = enumerateCameras(factory);
- for (const CameraInfo &camera : cameras) {
- if (camera.name == device)
- return camera.orientation;
- }
- return 0;
-}
-
-QByteArray QGstUtils::cameraDriver(const QString &device, GstElementFactory *factory)
-{
- const auto cameras = enumerateCameras(factory);
- for (const CameraInfo &camera : cameras) {
- if (camera.name == device)
- return camera.driver;
- }
- return QByteArray();
-}
-
-QSet<QString> QGstUtils::supportedMimeTypes(bool (*isValidFactory)(GstElementFactory *factory))
-{
- QSet<QString> supportedMimeTypes;
-
- //enumerate supported mime types
- gst_init(nullptr, nullptr);
-
-#if GST_CHECK_VERSION(1,0,0)
- GstRegistry *registry = gst_registry_get();
- GList *orig_plugins = gst_registry_get_plugin_list(registry);
-#else
- GstRegistry *registry = gst_registry_get_default();
- GList *orig_plugins = gst_default_registry_get_plugin_list ();
-#endif
- for (GList *plugins = orig_plugins; plugins; plugins = g_list_next(plugins)) {
- GstPlugin *plugin = (GstPlugin *) (plugins->data);
-#if GST_CHECK_VERSION(1,0,0)
- if (GST_OBJECT_FLAG_IS_SET(GST_OBJECT(plugin), GST_PLUGIN_FLAG_BLACKLISTED))
- continue;
-#else
- if (plugin->flags & (1<<1)) //GST_PLUGIN_FLAG_BLACKLISTED
- continue;
-#endif
-
- GList *orig_features = gst_registry_get_feature_list_by_plugin(
- registry, gst_plugin_get_name(plugin));
- for (GList *features = orig_features; features; features = g_list_next(features)) {
- if (G_UNLIKELY(features->data == nullptr))
- continue;
-
- GstPluginFeature *feature = GST_PLUGIN_FEATURE(features->data);
- GstElementFactory *factory;
-
- if (GST_IS_TYPE_FIND_FACTORY(feature)) {
- QString name(QLatin1String(gst_plugin_feature_get_name(feature)));
- if (name.contains(QLatin1Char('/'))) //filter out any string without '/' which is obviously not a mime type
- supportedMimeTypes.insert(name.toLower());
- continue;
- } else if (!GST_IS_ELEMENT_FACTORY (feature)
- || !(factory = GST_ELEMENT_FACTORY(gst_plugin_feature_load(feature)))) {
- continue;
- } else if (!isValidFactory(factory)) {
- // Do nothing
- } else for (const GList *pads = gst_element_factory_get_static_pad_templates(factory);
- pads;
- pads = g_list_next(pads)) {
- GstStaticPadTemplate *padtemplate = static_cast<GstStaticPadTemplate *>(pads->data);
-
- if (padtemplate->direction == GST_PAD_SINK && padtemplate->static_caps.string) {
- GstCaps *caps = gst_static_caps_get(&padtemplate->static_caps);
- if (gst_caps_is_any(caps) || gst_caps_is_empty(caps)) {
- } else for (guint i = 0; i < gst_caps_get_size(caps); i++) {
- GstStructure *structure = gst_caps_get_structure(caps, i);
- QString nameLowcase = QString::fromLatin1(gst_structure_get_name(structure)).toLower();
-
- supportedMimeTypes.insert(nameLowcase);
- if (nameLowcase.contains(QLatin1String("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 = QLatin1String(str);
- const QStringList elements = versions.split(QRegularExpression(QLatin1String("\\D+")), Qt::SkipEmptyParts);
- for (const QString &e : elements)
- supportedMimeTypes.insert(nameLowcase + e);
- g_free(str);
- }
- }
- }
- }
- }
- gst_object_unref(factory);
- }
- gst_plugin_feature_list_free(orig_features);
- }
- gst_plugin_list_free (orig_plugins);
-
-#if defined QT_SUPPORTEDMIMETYPES_DEBUG
- QStringList list = supportedMimeTypes.toList();
- list.sort();
- if (qgetenv("QT_DEBUG_PLUGINS").toInt() > 0) {
- for (const QString &type : qAsConst(list))
- qDebug() << type;
- }
-#endif
- return supportedMimeTypes;
-}
-
-#if GST_CHECK_VERSION(1, 0, 0)
-namespace {
-
-struct ColorFormat { QImage::Format imageFormat; GstVideoFormat gstFormat; };
-static const ColorFormat qt_colorLookup[] =
-{
- { QImage::Format_RGBX8888, GST_VIDEO_FORMAT_RGBx },
- { QImage::Format_RGBA8888, GST_VIDEO_FORMAT_RGBA },
- { QImage::Format_RGB888 , GST_VIDEO_FORMAT_RGB },
- { QImage::Format_RGB16 , GST_VIDEO_FORMAT_RGB16 }
-};
-
-}
-#endif
-
-#if GST_CHECK_VERSION(1,0,0)
-QImage QGstUtils::bufferToImage(GstBuffer *buffer, const GstVideoInfo &videoInfo)
-#else
-QImage QGstUtils::bufferToImage(GstBuffer *buffer)
-#endif
-{
- QImage img;
-
-#if GST_CHECK_VERSION(1,0,0)
- GstVideoInfo info = videoInfo;
- GstVideoFrame frame;
- if (!gst_video_frame_map(&frame, &info, buffer, GST_MAP_READ))
- return img;
-#else
- GstCaps *caps = gst_buffer_get_caps(buffer);
- if (!caps)
- return img;
-
- GstStructure *structure = gst_caps_get_structure (caps, 0);
- gint width = 0;
- gint height = 0;
-
- if (!structure
- || !gst_structure_get_int(structure, "width", &width)
- || !gst_structure_get_int(structure, "height", &height)
- || width <= 0
- || height <= 0) {
- gst_caps_unref(caps);
- return img;
- }
- gst_caps_unref(caps);
-#endif
-
-#if GST_CHECK_VERSION(1,0,0)
- if (videoInfo.finfo->format == GST_VIDEO_FORMAT_I420) {
- const int width = videoInfo.width;
- const int height = videoInfo.height;
-
- const int stride[] = { frame.info.stride[0], frame.info.stride[1], frame.info.stride[2] };
- const uchar *data[] = {
- static_cast<const uchar *>(frame.data[0]),
- static_cast<const uchar *>(frame.data[1]),
- static_cast<const uchar *>(frame.data[2])
- };
-#else
- if (qstrcmp(gst_structure_get_name(structure), "video/x-raw-yuv") == 0) {
- const int stride[] = { width, width / 2, width / 2 };
- const uchar *data[] = {
- (const uchar *)buffer->data,
- (const uchar *)buffer->data + width * height,
- (const uchar *)buffer->data + width * height * 5 / 4
- };
-#endif
- img = QImage(width/2, height/2, QImage::Format_RGB32);
-
- for (int y=0; y<height; y+=2) {
- const uchar *yLine = data[0] + (y * stride[0]);
- const uchar *uLine = data[1] + (y * stride[1] / 2);
- const uchar *vLine = data[2] + (y * stride[2] / 2);
-
- for (int x=0; x<width; x+=2) {
- const qreal Y = 1.164*(yLine[x]-16);
- const int U = uLine[x/2]-128;
- const int V = vLine[x/2]-128;
-
- int b = qBound(0, int(Y + 2.018*U), 255);
- int g = qBound(0, int(Y - 0.813*V - 0.391*U), 255);
- int r = qBound(0, int(Y + 1.596*V), 255);
-
- img.setPixel(x/2,y/2,qRgb(r,g,b));
- }
- }
-#if GST_CHECK_VERSION(1,0,0)
- } else for (int i = 0; i < lengthOf(qt_colorLookup); ++i) {
- if (qt_colorLookup[i].gstFormat != videoInfo.finfo->format)
- continue;
-
- const QImage image(
- static_cast<const uchar *>(frame.data[0]),
- videoInfo.width,
- videoInfo.height,
- frame.info.stride[0],
- qt_colorLookup[i].imageFormat);
- img = image;
- img.detach();
-
- break;
- }
-
- gst_video_frame_unmap(&frame);
-#else
- } else if (qstrcmp(gst_structure_get_name(structure), "video/x-raw-rgb") == 0) {
- QImage::Format format = QImage::Format_Invalid;
- int bpp = 0;
- gst_structure_get_int(structure, "bpp", &bpp);
-
- if (bpp == 24)
- format = QImage::Format_RGB888;
- else if (bpp == 32)
- format = QImage::Format_RGB32;
-
- if (format != QImage::Format_Invalid) {
- img = QImage((const uchar *)buffer->data,
- width,
- height,
- format);
- img.bits(); //detach
- }
- }
-#endif
- return img;
-}
-
-
-namespace {
-
-#if GST_CHECK_VERSION(1,0,0)
-
-struct VideoFormat
-{
- QVideoFrame::PixelFormat pixelFormat;
- GstVideoFormat gstFormat;
-};
-
-static const VideoFormat qt_videoFormatLookup[] =
-{
- { QVideoFrame::Format_YUV420P, GST_VIDEO_FORMAT_I420 },
- { QVideoFrame::Format_YUV422P, GST_VIDEO_FORMAT_Y42B },
- { QVideoFrame::Format_YV12 , GST_VIDEO_FORMAT_YV12 },
- { QVideoFrame::Format_UYVY , GST_VIDEO_FORMAT_UYVY },
- { QVideoFrame::Format_YUYV , GST_VIDEO_FORMAT_YUY2 },
- { QVideoFrame::Format_NV12 , GST_VIDEO_FORMAT_NV12 },
- { QVideoFrame::Format_NV21 , GST_VIDEO_FORMAT_NV21 },
- { QVideoFrame::Format_AYUV444, GST_VIDEO_FORMAT_AYUV },
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- { QVideoFrame::Format_RGB32 , GST_VIDEO_FORMAT_BGRx },
- { QVideoFrame::Format_BGR32 , GST_VIDEO_FORMAT_RGBx },
- { QVideoFrame::Format_ARGB32, GST_VIDEO_FORMAT_BGRA },
- { QVideoFrame::Format_ABGR32, GST_VIDEO_FORMAT_RGBA },
- { QVideoFrame::Format_BGRA32, GST_VIDEO_FORMAT_ARGB },
-#else
- { QVideoFrame::Format_RGB32 , GST_VIDEO_FORMAT_xRGB },
- { QVideoFrame::Format_BGR32 , GST_VIDEO_FORMAT_xBGR },
- { QVideoFrame::Format_ARGB32, GST_VIDEO_FORMAT_ARGB },
- { QVideoFrame::Format_ABGR32, GST_VIDEO_FORMAT_ABGR },
- { QVideoFrame::Format_BGRA32, GST_VIDEO_FORMAT_BGRA },
-#endif
- { QVideoFrame::Format_RGB24 , GST_VIDEO_FORMAT_RGB },
- { QVideoFrame::Format_BGR24 , GST_VIDEO_FORMAT_BGR },
- { QVideoFrame::Format_RGB565, GST_VIDEO_FORMAT_RGB16 }
-};
-
-static int indexOfVideoFormat(QVideoFrame::PixelFormat format)
-{
- for (int i = 0; i < lengthOf(qt_videoFormatLookup); ++i)
- if (qt_videoFormatLookup[i].pixelFormat == format)
- return i;
-
- return -1;
-}
-
-static int indexOfVideoFormat(GstVideoFormat format)
-{
- for (int i = 0; i < lengthOf(qt_videoFormatLookup); ++i)
- if (qt_videoFormatLookup[i].gstFormat == format)
- return i;
-
- return -1;
-}
-
-#else
-
-struct YuvFormat
-{
- QVideoFrame::PixelFormat pixelFormat;
- guint32 fourcc;
- int bitsPerPixel;
-};
-
-static const YuvFormat qt_yuvColorLookup[] =
-{
- { QVideoFrame::Format_YUV420P, GST_MAKE_FOURCC('I','4','2','0'), 8 },
- { QVideoFrame::Format_YUV422P, GST_MAKE_FOURCC('Y','4','2','B'), 8 },
- { QVideoFrame::Format_YV12, GST_MAKE_FOURCC('Y','V','1','2'), 8 },
- { QVideoFrame::Format_UYVY, GST_MAKE_FOURCC('U','Y','V','Y'), 16 },
- { QVideoFrame::Format_YUYV, GST_MAKE_FOURCC('Y','U','Y','2'), 16 },
- { QVideoFrame::Format_NV12, GST_MAKE_FOURCC('N','V','1','2'), 8 },
- { QVideoFrame::Format_NV21, GST_MAKE_FOURCC('N','V','2','1'), 8 },
- { QVideoFrame::Format_AYUV444, GST_MAKE_FOURCC('A','Y','U','V'), 32 }
-};
-
-static int indexOfYuvColor(QVideoFrame::PixelFormat format)
-{
- const int count = sizeof(qt_yuvColorLookup) / sizeof(YuvFormat);
-
- for (int i = 0; i < count; ++i)
- if (qt_yuvColorLookup[i].pixelFormat == format)
- return i;
-
- return -1;
-}
-
-static int indexOfYuvColor(guint32 fourcc)
-{
- const int count = sizeof(qt_yuvColorLookup) / sizeof(YuvFormat);
-
- for (int i = 0; i < count; ++i)
- if (qt_yuvColorLookup[i].fourcc == fourcc)
- return i;
-
- return -1;
-}
-
-struct RgbFormat
-{
- QVideoFrame::PixelFormat pixelFormat;
- int bitsPerPixel;
- int depth;
- int endianness;
- int red;
- int green;
- int blue;
- int alpha;
-};
-
-static const RgbFormat qt_rgbColorLookup[] =
-{
- { QVideoFrame::Format_RGB32 , 32, 24, 4321, 0x0000FF00, 0x00FF0000, int(0xFF000000), 0x00000000 },
- { QVideoFrame::Format_RGB32 , 32, 24, 1234, 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 },
- { QVideoFrame::Format_BGR32 , 32, 24, 4321, int(0xFF000000), 0x00FF0000, 0x0000FF00, 0x00000000 },
- { QVideoFrame::Format_BGR32 , 32, 24, 1234, 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 },
- { QVideoFrame::Format_ARGB32, 32, 24, 4321, 0x0000FF00, 0x00FF0000, int(0xFF000000), 0x000000FF },
- { QVideoFrame::Format_ARGB32, 32, 24, 1234, 0x00FF0000, 0x0000FF00, 0x000000FF, int(0xFF000000) },
- { QVideoFrame::Format_RGB24 , 24, 24, 4321, 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 },
- { QVideoFrame::Format_BGR24 , 24, 24, 4321, 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 },
- { QVideoFrame::Format_RGB565, 16, 16, 1234, 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }
-};
-
-static int indexOfRgbColor(
- int bits, int depth, int endianness, int red, int green, int blue, int alpha)
-{
- const int count = sizeof(qt_rgbColorLookup) / sizeof(RgbFormat);
-
- for (int i = 0; i < count; ++i) {
- if (qt_rgbColorLookup[i].bitsPerPixel == bits
- && qt_rgbColorLookup[i].depth == depth
- && qt_rgbColorLookup[i].endianness == endianness
- && qt_rgbColorLookup[i].red == red
- && qt_rgbColorLookup[i].green == green
- && qt_rgbColorLookup[i].blue == blue
- && qt_rgbColorLookup[i].alpha == alpha) {
- return i;
- }
- }
- return -1;
-}
-#endif
-
-}
-
-#if GST_CHECK_VERSION(1,0,0)
-
-QVideoSurfaceFormat QGstUtils::formatForCaps(
- GstCaps *caps, GstVideoInfo *info, QAbstractVideoBuffer::HandleType handleType)
-{
- GstVideoInfo vidInfo;
- GstVideoInfo *infoPtr = info ? info : &vidInfo;
-
- if (gst_video_info_from_caps(infoPtr, caps)) {
- int index = indexOfVideoFormat(infoPtr->finfo->format);
-
- if (index != -1) {
- QVideoSurfaceFormat format(
- QSize(infoPtr->width, infoPtr->height),
- qt_videoFormatLookup[index].pixelFormat,
- handleType);
-
- if (infoPtr->fps_d > 0)
- format.setFrameRate(qreal(infoPtr->fps_n) / infoPtr->fps_d);
-
- if (infoPtr->par_d > 0)
- format.setPixelAspectRatio(infoPtr->par_n, infoPtr->par_d);
-
- return format;
- }
- }
- return QVideoSurfaceFormat();
-}
-
-#else
-
-QVideoSurfaceFormat QGstUtils::formatForCaps(
- GstCaps *caps, int *bytesPerLine, QAbstractVideoBuffer::HandleType handleType)
-{
- const GstStructure *structure = gst_caps_get_structure(caps, 0);
-
- int bitsPerPixel = 0;
- QSize size = structureResolution(structure);
- QVideoFrame::PixelFormat pixelFormat = structurePixelFormat(structure, &bitsPerPixel);
-
- if (pixelFormat != QVideoFrame::Format_Invalid) {
- QVideoSurfaceFormat format(size, pixelFormat, handleType);
-
- QPair<qreal, qreal> rate = structureFrameRateRange(structure);
- if (rate.second)
- format.setFrameRate(rate.second);
-
- format.setPixelAspectRatio(structurePixelAspectRatio(structure));
-
- if (bytesPerLine)
- *bytesPerLine = ((size.width() * bitsPerPixel / 8) + 3) & ~3;
-
- return format;
- }
- return QVideoSurfaceFormat();
-}
-
-#endif
-
-GstCaps *QGstUtils::capsForFormats(const QList<QVideoFrame::PixelFormat> &formats)
-{
- GstCaps *caps = gst_caps_new_empty();
-
-#if GST_CHECK_VERSION(1,0,0)
- for (QVideoFrame::PixelFormat format : formats) {
- int index = indexOfVideoFormat(format);
-
- if (index != -1) {
- gst_caps_append_structure(caps, gst_structure_new(
- "video/x-raw",
- "format" , G_TYPE_STRING, gst_video_format_to_string(qt_videoFormatLookup[index].gstFormat),
- nullptr));
- }
- }
-#else
- for (QVideoFrame::PixelFormat format : formats) {
- int index = indexOfYuvColor(format);
-
- if (index != -1) {
- gst_caps_append_structure(caps, gst_structure_new(
- "video/x-raw-yuv",
- "format", GST_TYPE_FOURCC, qt_yuvColorLookup[index].fourcc,
- nullptr));
- continue;
- }
-
- const int count = sizeof(qt_rgbColorLookup) / sizeof(RgbFormat);
-
- for (int i = 0; i < count; ++i) {
- if (qt_rgbColorLookup[i].pixelFormat == format) {
- GstStructure *structure = gst_structure_new(
- "video/x-raw-rgb",
- "bpp" , G_TYPE_INT, qt_rgbColorLookup[i].bitsPerPixel,
- "depth" , G_TYPE_INT, qt_rgbColorLookup[i].depth,
- "endianness", G_TYPE_INT, qt_rgbColorLookup[i].endianness,
- "red_mask" , G_TYPE_INT, qt_rgbColorLookup[i].red,
- "green_mask", G_TYPE_INT, qt_rgbColorLookup[i].green,
- "blue_mask" , G_TYPE_INT, qt_rgbColorLookup[i].blue,
- nullptr);
-
- if (qt_rgbColorLookup[i].alpha != 0) {
- gst_structure_set(
- structure, "alpha_mask", G_TYPE_INT, qt_rgbColorLookup[i].alpha, nullptr);
- }
- gst_caps_append_structure(caps, structure);
- }
- }
- }
-#endif
-
- gst_caps_set_simple(
- caps,
- "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, INT_MAX, 1,
- "width" , GST_TYPE_INT_RANGE, 1, INT_MAX,
- "height" , GST_TYPE_INT_RANGE, 1, INT_MAX,
- nullptr);
-
- return caps;
-}
-
-void QGstUtils::setFrameTimeStamps(QVideoFrame *frame, GstBuffer *buffer)
-{
- // GStreamer uses nanoseconds, Qt uses microseconds
- qint64 startTime = GST_BUFFER_TIMESTAMP(buffer);
- if (startTime >= 0) {
- frame->setStartTime(startTime/G_GINT64_CONSTANT (1000));
-
- qint64 duration = GST_BUFFER_DURATION(buffer);
- if (duration >= 0)
- frame->setEndTime((startTime + duration)/G_GINT64_CONSTANT (1000));
- }
-}
-
-void QGstUtils::setMetaData(GstElement *element, const QMap<QByteArray, QVariant> &data)
-{
- if (!GST_IS_TAG_SETTER(element))
- return;
-
- gst_tag_setter_reset_tags(GST_TAG_SETTER(element));
-
- for (auto it = data.cbegin(), end = data.cend(); it != end; ++it) {
- const QString tagName = QString::fromLatin1(it.key());
- const QVariant &tagValue = it.value();
-
- switch (tagValue.type()) {
- case QVariant::String:
- gst_tag_setter_add_tags(GST_TAG_SETTER(element),
- GST_TAG_MERGE_REPLACE,
- tagName.toUtf8().constData(),
- tagValue.toString().toUtf8().constData(),
- nullptr);
- break;
- case QVariant::Int:
- case QVariant::LongLong:
- gst_tag_setter_add_tags(GST_TAG_SETTER(element),
- GST_TAG_MERGE_REPLACE,
- tagName.toUtf8().constData(),
- tagValue.toInt(),
- nullptr);
- break;
- case QVariant::Double:
- gst_tag_setter_add_tags(GST_TAG_SETTER(element),
- GST_TAG_MERGE_REPLACE,
- tagName.toUtf8().constData(),
- tagValue.toDouble(),
- nullptr);
- break;
-#if GST_CHECK_VERSION(0, 10, 31)
- case QVariant::DateTime: {
- QDateTime date = tagValue.toDateTime().toLocalTime();
- gst_tag_setter_add_tags(GST_TAG_SETTER(element),
- GST_TAG_MERGE_REPLACE,
- tagName.toUtf8().constData(),
- gst_date_time_new_local_time(
- date.date().year(), date.date().month(), date.date().day(),
- date.time().hour(), date.time().minute(), date.time().second()),
- nullptr);
- break;
- }
-#endif
- default:
- break;
- }
- }
-}
-
-void QGstUtils::setMetaData(GstBin *bin, const QMap<QByteArray, QVariant> &data)
-{
- GstIterator *elements = gst_bin_iterate_all_by_interface(bin, GST_TYPE_TAG_SETTER);
-#if GST_CHECK_VERSION(1,0,0)
- GValue item = G_VALUE_INIT;
- while (gst_iterator_next(elements, &item) == GST_ITERATOR_OK) {
- GstElement * const element = GST_ELEMENT(g_value_get_object(&item));
-#else
- GstElement *element = 0;
- while (gst_iterator_next(elements, (void**)&element) == GST_ITERATOR_OK) {
-#endif
- setMetaData(element, data);
- }
- gst_iterator_free(elements);
-}
-
-
-GstCaps *QGstUtils::videoFilterCaps()
-{
- const char *caps =
-#if GST_CHECK_VERSION(1,2,0)
- "video/x-raw(ANY);"
-#elif GST_CHECK_VERSION(1,0,0)
- "video/x-raw;"
-#else
- "video/x-raw-yuv;"
- "video/x-raw-rgb;"
- "video/x-raw-data;"
- "video/x-android-buffer;"
-#endif
- "image/jpeg;"
- "video/x-h264";
- static GstStaticCaps staticCaps = GST_STATIC_CAPS(caps);
-
- return gst_caps_make_writable(gst_static_caps_get(&staticCaps));
-}
-
-QSize QGstUtils::structureResolution(const GstStructure *s)
-{
- QSize size;
-
- int w, h;
- if (s && gst_structure_get_int(s, "width", &w) && gst_structure_get_int(s, "height", &h)) {
- size.rwidth() = w;
- size.rheight() = h;
- }
-
- return size;
-}
-
-QVideoFrame::PixelFormat QGstUtils::structurePixelFormat(const GstStructure *structure, int *bpp)
-{
- QVideoFrame::PixelFormat pixelFormat = QVideoFrame::Format_Invalid;
-
- if (!structure)
- return pixelFormat;
-
-#if GST_CHECK_VERSION(1,0,0)
- Q_UNUSED(bpp);
-
- if (gst_structure_has_name(structure, "video/x-raw")) {
- const gchar *s = gst_structure_get_string(structure, "format");
- if (s) {
- GstVideoFormat format = gst_video_format_from_string(s);
- int index = indexOfVideoFormat(format);
-
- if (index != -1)
- pixelFormat = qt_videoFormatLookup[index].pixelFormat;
- }
- }
-#else
- if (qstrcmp(gst_structure_get_name(structure), "video/x-raw-yuv") == 0) {
- guint32 fourcc = 0;
- gst_structure_get_fourcc(structure, "format", &fourcc);
-
- int index = indexOfYuvColor(fourcc);
- if (index != -1) {
- pixelFormat = qt_yuvColorLookup[index].pixelFormat;
- if (bpp)
- *bpp = qt_yuvColorLookup[index].bitsPerPixel;
- }
- } else if (qstrcmp(gst_structure_get_name(structure), "video/x-raw-rgb") == 0) {
- int bitsPerPixel = 0;
- int depth = 0;
- int endianness = 0;
- int red = 0;
- int green = 0;
- int blue = 0;
- int alpha = 0;
-
- gst_structure_get_int(structure, "bpp", &bitsPerPixel);
- gst_structure_get_int(structure, "depth", &depth);
- gst_structure_get_int(structure, "endianness", &endianness);
- gst_structure_get_int(structure, "red_mask", &red);
- gst_structure_get_int(structure, "green_mask", &green);
- gst_structure_get_int(structure, "blue_mask", &blue);
- gst_structure_get_int(structure, "alpha_mask", &alpha);
-
- int index = indexOfRgbColor(bitsPerPixel, depth, endianness, red, green, blue, alpha);
-
- if (index != -1) {
- pixelFormat = qt_rgbColorLookup[index].pixelFormat;
- if (bpp)
- *bpp = qt_rgbColorLookup[index].bitsPerPixel;
- }
- }
-#endif
-
- return pixelFormat;
-}
-
-QSize QGstUtils::structurePixelAspectRatio(const GstStructure *s)
-{
- QSize ratio(1, 1);
-
- gint aspectNum = 0;
- gint aspectDenum = 0;
- if (s && gst_structure_get_fraction(s, "pixel-aspect-ratio", &aspectNum, &aspectDenum)) {
- if (aspectDenum > 0) {
- ratio.rwidth() = aspectNum;
- ratio.rheight() = aspectDenum;
- }
- }
-
- return ratio;
-}
-
-QPair<qreal, qreal> QGstUtils::structureFrameRateRange(const GstStructure *s)
-{
- QPair<qreal, qreal> rate;
-
- if (!s)
- return rate;
-
- int n, d;
- if (gst_structure_get_fraction(s, "framerate", &n, &d)) {
- rate.second = qreal(n) / d;
- rate.first = rate.second;
- } else if (gst_structure_get_fraction(s, "max-framerate", &n, &d)) {
- rate.second = qreal(n) / d;
- if (gst_structure_get_fraction(s, "min-framerate", &n, &d))
- rate.first = qreal(n) / d;
- else
- rate.first = qreal(1);
- }
-
- return rate;
-}
-
-typedef QMap<QString, QString> FileExtensionMap;
-Q_GLOBAL_STATIC(FileExtensionMap, fileExtensionMap)
-
-QString QGstUtils::fileExtensionForMimeType(const QString &mimeType)
-{
- if (fileExtensionMap->isEmpty()) {
- //extension for containers hard to guess from mimetype
- fileExtensionMap->insert(QStringLiteral("video/x-matroska"), QLatin1String("mkv"));
- fileExtensionMap->insert(QStringLiteral("video/quicktime"), QLatin1String("mov"));
- fileExtensionMap->insert(QStringLiteral("video/x-msvideo"), QLatin1String("avi"));
- fileExtensionMap->insert(QStringLiteral("video/msvideo"), QLatin1String("avi"));
- fileExtensionMap->insert(QStringLiteral("audio/mpeg"), QLatin1String("mp3"));
- fileExtensionMap->insert(QStringLiteral("application/x-shockwave-flash"), QLatin1String("swf"));
- fileExtensionMap->insert(QStringLiteral("application/x-pn-realmedia"), QLatin1String("rm"));
- }
-
- //for container names like avi instead of video/x-msvideo, use it as extension
- if (!mimeType.contains(QLatin1Char('/')))
- return mimeType;
-
- QString format = mimeType.left(mimeType.indexOf(QLatin1Char(',')));
- QString extension = fileExtensionMap->value(format);
-
- if (!extension.isEmpty() || format.isEmpty())
- return extension;
-
- QRegularExpression rx(QStringLiteral("[-/]([\\w]+)$"));
- QRegularExpressionMatch match = rx.match(format);
-
- if (match.hasMatch())
- extension = match.captured(1);
-
- return extension;
-}
-
-#if GST_CHECK_VERSION(0,10,30)
-QVariant QGstUtils::fromGStreamerOrientation(const QVariant &value)
-{
- // Note gstreamer tokens either describe the counter clockwise rotation of the
- // image or the clockwise transform to apply to correct the image. The orientation
- // value returned is the clockwise rotation of the image.
- const QString token = value.toString();
- if (token == QStringLiteral("rotate-90"))
- return 270;
- if (token == QStringLiteral("rotate-180"))
- return 180;
- if (token == QStringLiteral("rotate-270"))
- return 90;
- return 0;
-}
-
-QVariant QGstUtils::toGStreamerOrientation(const QVariant &value)
-{
- switch (value.toInt()) {
- case 90:
- return QStringLiteral("rotate-270");
- case 180:
- return QStringLiteral("rotate-180");
- case 270:
- return QStringLiteral("rotate-90");
- default:
- return QStringLiteral("rotate-0");
- }
-}
-#endif
-
-bool QGstUtils::useOpenGL()
-{
- static bool result = qEnvironmentVariableIntValue("QT_GSTREAMER_USE_OPENGL_PLUGIN");
- return result;
-}
-
-void qt_gst_object_ref_sink(gpointer object)
-{
-#if GST_CHECK_VERSION(0,10,24)
- gst_object_ref_sink(object);
-#else
- g_return_if_fail (GST_IS_OBJECT(object));
-
- GST_OBJECT_LOCK(object);
- if (G_LIKELY(GST_OBJECT_IS_FLOATING(object))) {
- GST_OBJECT_FLAG_UNSET(object, GST_OBJECT_FLOATING);
- GST_OBJECT_UNLOCK(object);
- } else {
- GST_OBJECT_UNLOCK(object);
- gst_object_ref(object);
- }
-#endif
-}
-
-GstCaps *qt_gst_pad_get_current_caps(GstPad *pad)
-{
-#if GST_CHECK_VERSION(1,0,0)
- return gst_pad_get_current_caps(pad);
-#else
- return gst_pad_get_negotiated_caps(pad);
-#endif
-}
-
-GstCaps *qt_gst_pad_get_caps(GstPad *pad)
-{
-#if GST_CHECK_VERSION(1,0,0)
- return gst_pad_query_caps(pad, nullptr);
-#elif GST_CHECK_VERSION(0, 10, 26)
- return gst_pad_get_caps_reffed(pad);
-#else
- return gst_pad_get_caps(pad);
-#endif
-}
-
-GstStructure *qt_gst_structure_new_empty(const char *name)
-{
-#if GST_CHECK_VERSION(1,0,0)
- return gst_structure_new_empty(name);
-#else
- return gst_structure_new(name, nullptr);
-#endif
-}
-
-gboolean qt_gst_element_query_position(GstElement *element, GstFormat format, gint64 *cur)
-{
-#if GST_CHECK_VERSION(1,0,0)
- return gst_element_query_position(element, format, cur);
-#else
- return gst_element_query_position(element, &format, cur);
-#endif
-}
-
-gboolean qt_gst_element_query_duration(GstElement *element, GstFormat format, gint64 *cur)
-{
-#if GST_CHECK_VERSION(1,0,0)
- return gst_element_query_duration(element, format, cur);
-#else
- return gst_element_query_duration(element, &format, cur);
-#endif
-}
-
-GstCaps *qt_gst_caps_normalize(GstCaps *caps)
-{
-#if GST_CHECK_VERSION(1,0,0)
- // gst_caps_normalize() takes ownership of the argument in 1.0
- return gst_caps_normalize(caps);
-#else
- // in 0.10, it doesn't. Unref the argument to mimic the 1.0 behavior
- GstCaps *res = gst_caps_normalize(caps);
- gst_caps_unref(caps);
- return res;
-#endif
-}
-
-const gchar *qt_gst_element_get_factory_name(GstElement *element)
-{
- const gchar *name = 0;
- const GstElementFactory *factory = 0;
-
- if (element && (factory = gst_element_get_factory(element)))
- name = gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(factory));
-
- return name;
-}
-
-gboolean qt_gst_caps_can_intersect(const GstCaps * caps1, const GstCaps * caps2)
-{
-#if GST_CHECK_VERSION(0, 10, 25)
- return gst_caps_can_intersect(caps1, caps2);
-#else
- GstCaps *intersection = gst_caps_intersect(caps1, caps2);
- gboolean res = !gst_caps_is_empty(intersection);
- gst_caps_unref(intersection);
- return res;
-#endif
-}
-
-#if !GST_CHECK_VERSION(0, 10, 31)
-static gboolean qt_gst_videosink_factory_filter(GstPluginFeature *feature, gpointer)
-{
- guint rank;
- const gchar *klass;
-
- if (!GST_IS_ELEMENT_FACTORY(feature))
- return FALSE;
-
- klass = gst_element_factory_get_klass(GST_ELEMENT_FACTORY(feature));
- if (!(strstr(klass, "Sink") && strstr(klass, "Video")))
- return FALSE;
-
- rank = gst_plugin_feature_get_rank(feature);
- if (rank < GST_RANK_MARGINAL)
- return FALSE;
-
- return TRUE;
-}
-
-static gint qt_gst_compare_ranks(GstPluginFeature *f1, GstPluginFeature *f2)
-{
- gint diff;
-
- diff = gst_plugin_feature_get_rank(f2) - gst_plugin_feature_get_rank(f1);
- if (diff != 0)
- return diff;
-
- return strcmp(gst_plugin_feature_get_name(f2), gst_plugin_feature_get_name (f1));
-}
-#endif
-
-GList *qt_gst_video_sinks()
-{
- GList *list = nullptr;
-
-#if GST_CHECK_VERSION(0, 10, 31)
- list = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_SINK | GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO,
- GST_RANK_MARGINAL);
-#else
- list = gst_registry_feature_filter(gst_registry_get_default(),
- (GstPluginFeatureFilter)qt_gst_videosink_factory_filter,
- FALSE, nullptr);
- list = g_list_sort(list, (GCompareFunc)qt_gst_compare_ranks);
-#endif
-
- return list;
-}
-
-void qt_gst_util_double_to_fraction(gdouble src, gint *dest_n, gint *dest_d)
-{
-#if GST_CHECK_VERSION(0, 10, 26)
- gst_util_double_to_fraction(src, dest_n, dest_d);
-#else
- qt_real_to_fraction(src, dest_n, dest_d);
-#endif
-}
-
-QDebug operator <<(QDebug debug, GstCaps *caps)
-{
- if (caps) {
- gchar *string = gst_caps_to_string(caps);
- debug = debug << string;
- g_free(string);
- }
- return debug;
-}
-
-QT_END_NAMESPACE
diff --git a/src/gsttools/qgstutils_p.h b/src/gsttools/qgstutils_p.h
deleted file mode 100644
index 9ecf2e92c..000000000
--- a/src/gsttools/qgstutils_p.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/****************************************************************************
-**
-** 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 QGSTUTILS_P_H
-#define QGSTUTILS_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 <private/qgsttools_global_p.h>
-#include <QtCore/qlist.h>
-#include <QtCore/qmap.h>
-#include <QtCore/qset.h>
-#include <gst/gst.h>
-#include <gst/video/video.h>
-#include <qaudioformat.h>
-#include <qcamera.h>
-#include <qabstractvideobuffer.h>
-#include <qvideoframe.h>
-#include <QDebug>
-
-#if GST_CHECK_VERSION(1,0,0)
-# define QT_GSTREAMER_PLAYBIN_ELEMENT_NAME "playbin"
-# define QT_GSTREAMER_CAMERABIN_ELEMENT_NAME "camerabin"
-# define QT_GSTREAMER_COLORCONVERSION_ELEMENT_NAME "videoconvert"
-# define QT_GSTREAMER_RAW_AUDIO_MIME "audio/x-raw"
-# define QT_GSTREAMER_VIDEOOVERLAY_INTERFACE_NAME "GstVideoOverlay"
-#else
-# define QT_GSTREAMER_PLAYBIN_ELEMENT_NAME "playbin2"
-# define QT_GSTREAMER_CAMERABIN_ELEMENT_NAME "camerabin2"
-# define QT_GSTREAMER_COLORCONVERSION_ELEMENT_NAME "ffmpegcolorspace"
-# define QT_GSTREAMER_RAW_AUDIO_MIME "audio/x-raw-int"
-# define QT_GSTREAMER_VIDEOOVERLAY_INTERFACE_NAME "GstXOverlay"
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QSize;
-class QVariant;
-class QByteArray;
-class QImage;
-class QVideoSurfaceFormat;
-
-namespace QGstUtils {
- struct Q_GSTTOOLS_EXPORT CameraInfo
- {
- QString name;
- QString description;
- int orientation;
- QCamera::Position position;
- QByteArray driver;
- };
-
- Q_GSTTOOLS_EXPORT QMap<QByteArray, QVariant> gstTagListToMap(const GstTagList *list);
-
- Q_GSTTOOLS_EXPORT QSize capsResolution(const GstCaps *caps);
- Q_GSTTOOLS_EXPORT QSize capsCorrectedResolution(const GstCaps *caps);
- Q_GSTTOOLS_EXPORT QAudioFormat audioFormatForCaps(const GstCaps *caps);
-#if GST_CHECK_VERSION(1,0,0)
- Q_GSTTOOLS_EXPORT QAudioFormat audioFormatForSample(GstSample *sample);
-#else
- Q_GSTTOOLS_EXPORT QAudioFormat audioFormatForBuffer(GstBuffer *buffer);
-#endif
- Q_GSTTOOLS_EXPORT GstCaps *capsForAudioFormat(const QAudioFormat &format);
- Q_GSTTOOLS_EXPORT void initializeGst();
- Q_GSTTOOLS_EXPORT QMultimedia::SupportEstimate hasSupport(const QString &mimeType,
- const QStringList &codecs,
- const QSet<QString> &supportedMimeTypeSet);
-
- Q_GSTTOOLS_EXPORT QList<CameraInfo> enumerateCameras(GstElementFactory *factory = 0);
- Q_GSTTOOLS_EXPORT QList<QByteArray> cameraDevices(GstElementFactory * factory = 0);
- Q_GSTTOOLS_EXPORT QString cameraDescription(const QString &device, GstElementFactory * factory = 0);
- Q_GSTTOOLS_EXPORT QCamera::Position cameraPosition(const QString &device, GstElementFactory * factory = 0);
- Q_GSTTOOLS_EXPORT int cameraOrientation(const QString &device, GstElementFactory * factory = 0);
- Q_GSTTOOLS_EXPORT QByteArray cameraDriver(const QString &device, GstElementFactory * factory = 0);
-
- Q_GSTTOOLS_EXPORT QSet<QString> supportedMimeTypes(bool (*isValidFactory)(GstElementFactory *factory));
-
-#if GST_CHECK_VERSION(1,0,0)
- Q_GSTTOOLS_EXPORT QImage bufferToImage(GstBuffer *buffer, const GstVideoInfo &info);
- Q_GSTTOOLS_EXPORT QVideoSurfaceFormat formatForCaps(
- GstCaps *caps,
- GstVideoInfo *info = 0,
- QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle);
-#else
- Q_GSTTOOLS_EXPORT QImage bufferToImage(GstBuffer *buffer);
- Q_GSTTOOLS_EXPORT QVideoSurfaceFormat formatForCaps(
- GstCaps *caps,
- int *bytesPerLine = 0,
- QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle);
-#endif
-
- Q_GSTTOOLS_EXPORT GstCaps *capsForFormats(const QList<QVideoFrame::PixelFormat> &formats);
- void setFrameTimeStamps(QVideoFrame *frame, GstBuffer *buffer);
-
- Q_GSTTOOLS_EXPORT void setMetaData(GstElement *element, const QMap<QByteArray, QVariant> &data);
- Q_GSTTOOLS_EXPORT void setMetaData(GstBin *bin, const QMap<QByteArray, QVariant> &data);
-
- Q_GSTTOOLS_EXPORT GstCaps *videoFilterCaps();
-
- Q_GSTTOOLS_EXPORT QSize structureResolution(const GstStructure *s);
- Q_GSTTOOLS_EXPORT QVideoFrame::PixelFormat structurePixelFormat(const GstStructure *s, int *bpp = 0);
- Q_GSTTOOLS_EXPORT QSize structurePixelAspectRatio(const GstStructure *s);
- Q_GSTTOOLS_EXPORT QPair<qreal, qreal> structureFrameRateRange(const GstStructure *s);
-
- Q_GSTTOOLS_EXPORT QString fileExtensionForMimeType(const QString &mimeType);
-
-#if GST_CHECK_VERSION(0,10,30)
- Q_GSTTOOLS_EXPORT QVariant fromGStreamerOrientation(const QVariant &value);
- Q_GSTTOOLS_EXPORT QVariant toGStreamerOrientation(const QVariant &value);
-#endif
-
- Q_GSTTOOLS_EXPORT bool useOpenGL();
-}
-
-Q_GSTTOOLS_EXPORT void qt_gst_object_ref_sink(gpointer object);
-Q_GSTTOOLS_EXPORT GstCaps *qt_gst_pad_get_current_caps(GstPad *pad);
-Q_GSTTOOLS_EXPORT GstCaps *qt_gst_pad_get_caps(GstPad *pad);
-Q_GSTTOOLS_EXPORT GstStructure *qt_gst_structure_new_empty(const char *name);
-Q_GSTTOOLS_EXPORT gboolean qt_gst_element_query_position(GstElement *element, GstFormat format, gint64 *cur);
-Q_GSTTOOLS_EXPORT gboolean qt_gst_element_query_duration(GstElement *element, GstFormat format, gint64 *cur);
-Q_GSTTOOLS_EXPORT GstCaps *qt_gst_caps_normalize(GstCaps *caps);
-Q_GSTTOOLS_EXPORT const gchar *qt_gst_element_get_factory_name(GstElement *element);
-Q_GSTTOOLS_EXPORT gboolean qt_gst_caps_can_intersect(const GstCaps * caps1, const GstCaps * caps2);
-Q_GSTTOOLS_EXPORT GList *qt_gst_video_sinks();
-Q_GSTTOOLS_EXPORT void qt_gst_util_double_to_fraction(gdouble src, gint *dest_n, gint *dest_d);
-
-Q_GSTTOOLS_EXPORT QDebug operator <<(QDebug debug, GstCaps *caps);
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/gsttools/qgstvideobuffer.cpp b/src/gsttools/qgstvideobuffer.cpp
deleted file mode 100644
index 245b7e024..000000000
--- a/src/gsttools/qgstvideobuffer.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#include "qgstvideobuffer_p.h"
-
-QT_BEGIN_NAMESPACE
-
-#if GST_CHECK_VERSION(1,0,0)
-QGstVideoBuffer::QGstVideoBuffer(GstBuffer *buffer, const GstVideoInfo &info)
- : QAbstractPlanarVideoBuffer(NoHandle)
- , m_videoInfo(info)
-#else
-QGstVideoBuffer::QGstVideoBuffer(GstBuffer *buffer, int bytesPerLine)
- : QAbstractVideoBuffer(NoHandle)
- , m_bytesPerLine(bytesPerLine)
-#endif
- , m_buffer(buffer)
-{
- gst_buffer_ref(m_buffer);
-}
-
-#if GST_CHECK_VERSION(1,0,0)
-QGstVideoBuffer::QGstVideoBuffer(GstBuffer *buffer, const GstVideoInfo &info,
- QGstVideoBuffer::HandleType handleType,
- const QVariant &handle)
- : QAbstractPlanarVideoBuffer(handleType)
- , m_videoInfo(info)
-#else
-QGstVideoBuffer::QGstVideoBuffer(GstBuffer *buffer, int bytesPerLine,
- QGstVideoBuffer::HandleType handleType,
- const QVariant &handle)
- : QAbstractVideoBuffer(handleType)
- , m_bytesPerLine(bytesPerLine)
-#endif
- , m_buffer(buffer)
- , m_handle(handle)
-{
- gst_buffer_ref(m_buffer);
-}
-
-QGstVideoBuffer::~QGstVideoBuffer()
-{
- unmap();
-
- gst_buffer_unref(m_buffer);
-}
-
-
-QAbstractVideoBuffer::MapMode QGstVideoBuffer::mapMode() const
-{
- return m_mode;
-}
-
-#if GST_CHECK_VERSION(1,0,0)
-
-int QGstVideoBuffer::map(MapMode mode, int *numBytes, int bytesPerLine[4], uchar *data[4])
-{
- const GstMapFlags flags = GstMapFlags(((mode & ReadOnly) ? GST_MAP_READ : 0)
- | ((mode & WriteOnly) ? GST_MAP_WRITE : 0));
-
- if (mode == NotMapped || m_mode != NotMapped) {
- return 0;
- } else if (m_videoInfo.finfo->n_planes == 0) { // Encoded
- if (gst_buffer_map(m_buffer, &m_frame.map[0], flags)) {
- if (numBytes)
- *numBytes = m_frame.map[0].size;
- bytesPerLine[0] = -1;
- data[0] = static_cast<uchar *>(m_frame.map[0].data);
-
- m_mode = mode;
-
- return 1;
- }
- } else if (gst_video_frame_map(&m_frame, &m_videoInfo, m_buffer, flags)) {
- if (numBytes)
- *numBytes = m_frame.info.size;
-
- for (guint i = 0; i < m_frame.info.finfo->n_planes; ++i) {
- bytesPerLine[i] = m_frame.info.stride[i];
- data[i] = static_cast<uchar *>(m_frame.data[i]);
- }
-
- m_mode = mode;
-
- return m_frame.info.finfo->n_planes;
- }
- return 0;
-}
-
-#else
-
-uchar *QGstVideoBuffer::map(MapMode mode, int *numBytes, int *bytesPerLine)
-{
- if (mode != NotMapped && m_mode == NotMapped) {
- if (numBytes)
- *numBytes = m_buffer->size;
- if (bytesPerLine)
- *bytesPerLine = m_bytesPerLine;
-
- m_mode = mode;
-
- return m_buffer->data;
- } else {
- return 0;
- }
-}
-
-#endif
-
-void QGstVideoBuffer::unmap()
-{
-#if GST_CHECK_VERSION(1,0,0)
- if (m_mode != NotMapped) {
- if (m_videoInfo.finfo->n_planes == 0)
- gst_buffer_unmap(m_buffer, &m_frame.map[0]);
- else
- gst_video_frame_unmap(&m_frame);
- }
-#endif
- m_mode = NotMapped;
-}
-
-QT_END_NAMESPACE
diff --git a/src/gsttools/qgstvideobuffer_p.h b/src/gsttools/qgstvideobuffer_p.h
deleted file mode 100644
index b7de17e19..000000000
--- a/src/gsttools/qgstvideobuffer_p.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/****************************************************************************
-**
-** 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 QGSTVIDEOBUFFER_P_H
-#define QGSTVIDEOBUFFER_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 <private/qgsttools_global_p.h>
-#include <qabstractvideobuffer.h>
-#include <QtCore/qvariant.h>
-
-#include <gst/gst.h>
-#include <gst/video/video.h>
-
-QT_BEGIN_NAMESPACE
-
-#if GST_CHECK_VERSION(1,0,0)
-class Q_GSTTOOLS_EXPORT QGstVideoBuffer : public QAbstractPlanarVideoBuffer
-{
-public:
- QGstVideoBuffer(GstBuffer *buffer, const GstVideoInfo &info);
- QGstVideoBuffer(GstBuffer *buffer, const GstVideoInfo &info,
- HandleType handleType, const QVariant &handle);
-#else
-class Q_GSTTOOLS_EXPORT QGstVideoBuffer : public QAbstractVideoBuffer
-{
-public:
- QGstVideoBuffer(GstBuffer *buffer, int bytesPerLine);
- QGstVideoBuffer(GstBuffer *buffer, int bytesPerLine,
- HandleType handleType, const QVariant &handle);
-#endif
-
- ~QGstVideoBuffer();
-
- GstBuffer *buffer() const { return m_buffer; }
- MapMode mapMode() const override;
-
-#if GST_CHECK_VERSION(1,0,0)
- int map(MapMode mode, int *numBytes, int bytesPerLine[4], uchar *data[4]) override;
-#else
- uchar *map(MapMode mode, int *numBytes, int *bytesPerLine) override;
-#endif
-
- void unmap() override;
-
- QVariant handle() const override { return m_handle; }
-private:
-#if GST_CHECK_VERSION(1,0,0)
- GstVideoInfo m_videoInfo;
- GstVideoFrame m_frame;
-#else
- int m_bytesPerLine = 0;
-#endif
- GstBuffer *m_buffer = nullptr;
- MapMode m_mode = NotMapped;
- QVariant m_handle;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/gsttools/qgstvideorendererplugin.cpp b/src/gsttools/qgstvideorendererplugin.cpp
deleted file mode 100644
index 22028ac0e..000000000
--- a/src/gsttools/qgstvideorendererplugin.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Jolla 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$
-**
-****************************************************************************/
-
-#include "qgstvideorendererplugin_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QGstVideoRendererPlugin::QGstVideoRendererPlugin(QObject *parent) :
- QObject(parent)
-{
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qgstvideorendererplugin_p.cpp"
diff --git a/src/gsttools/qgstvideorendererplugin_p.h b/src/gsttools/qgstvideorendererplugin_p.h
deleted file mode 100644
index df36dbe09..000000000
--- a/src/gsttools/qgstvideorendererplugin_p.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Jolla 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 QGSTVIDEORENDERERPLUGIN_P_H
-#define QGSTVIDEORENDERERPLUGIN_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 <private/qgsttools_global_p.h>
-#include <qabstractvideobuffer.h>
-#include <qvideosurfaceformat.h>
-#include <QtCore/qobject.h>
-#include <QtCore/qplugin.h>
-
-#include <gst/gst.h>
-
-QT_BEGIN_NAMESPACE
-
-class QAbstractVideoSurface;
-
-const QLatin1String QGstVideoRendererPluginKey("gstvideorenderer");
-
-class Q_GSTTOOLS_EXPORT QGstVideoRenderer
-{
-public:
- virtual ~QGstVideoRenderer() {}
-
- virtual GstCaps *getCaps(QAbstractVideoSurface *surface) = 0;
- virtual bool start(QAbstractVideoSurface *surface, GstCaps *caps) = 0;
- virtual void stop(QAbstractVideoSurface *surface) = 0; // surface may be null if unexpectedly deleted.
- virtual bool proposeAllocation(GstQuery *query) = 0; // may be called from a thread.
-
- virtual bool present(QAbstractVideoSurface *surface, GstBuffer *buffer) = 0;
- virtual void flush(QAbstractVideoSurface *surface) = 0; // surface may be null if unexpectedly deleted.
-};
-
-/*
- Abstract interface for video buffers allocation.
-*/
-class Q_GSTTOOLS_EXPORT QGstVideoRendererInterface
-{
-public:
- virtual ~QGstVideoRendererInterface() {}
-
- virtual QGstVideoRenderer *createRenderer() = 0;
-};
-
-#define QGstVideoRendererInterface_iid "org.qt-project.qt.gstvideorenderer/5.4"
-Q_DECLARE_INTERFACE(QGstVideoRendererInterface, QGstVideoRendererInterface_iid)
-
-class Q_GSTTOOLS_EXPORT QGstVideoRendererPlugin : public QObject, public QGstVideoRendererInterface
-{
- Q_OBJECT
- Q_INTERFACES(QGstVideoRendererInterface)
-public:
- explicit QGstVideoRendererPlugin(QObject *parent = 0);
- virtual ~QGstVideoRendererPlugin() {}
-
- QGstVideoRenderer *createRenderer() override = 0;
-
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/gsttools/qgstvideorenderersink.cpp b/src/gsttools/qgstvideorenderersink.cpp
deleted file mode 100644
index 8f4f59358..000000000
--- a/src/gsttools/qgstvideorenderersink.cpp
+++ /dev/null
@@ -1,810 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Jolla 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$
-**
-****************************************************************************/
-
-#include <qabstractvideosurface.h>
-#include <qvideoframe.h>
-#include <QDebug>
-#include <QMap>
-#include <QThread>
-#include <QEvent>
-#include <QCoreApplication>
-
-#include <private/qmediapluginloader_p.h>
-#include "qgstvideobuffer_p.h"
-
-#include "qgstvideorenderersink_p.h"
-
-#include <gst/video/video.h>
-
-#include "qgstutils_p.h"
-
-#if QT_CONFIG(gstreamer_gl)
-#include <QOpenGLContext>
-#include <QGuiApplication>
-#include <QWindow>
-#include <qpa/qplatformnativeinterface.h>
-
-#include <gst/gl/gstglconfig.h>
-
-#if GST_GL_HAVE_WINDOW_X11
-# include <gst/gl/x11/gstgldisplay_x11.h>
-#endif
-#if GST_GL_HAVE_PLATFORM_EGL
-# include <gst/gl/egl/gstgldisplay_egl.h>
-#endif
-#if GST_CHECK_VERSION(1,11,1) && GST_GL_HAVE_WINDOW_WAYLAND
-# include <gst/gl/wayland/gstgldisplay_wayland.h>
-#endif
-#endif // #if QT_CONFIG(gstreamer_gl)
-
-//#define DEBUG_VIDEO_SURFACE_SINK
-
-QT_BEGIN_NAMESPACE
-
-QGstDefaultVideoRenderer::QGstDefaultVideoRenderer()
-{
-}
-
-QGstDefaultVideoRenderer::~QGstDefaultVideoRenderer()
-{
-}
-
-GstCaps *QGstDefaultVideoRenderer::getCaps(QAbstractVideoSurface *surface)
-{
-#if QT_CONFIG(gstreamer_gl)
- if (QGstUtils::useOpenGL()) {
- m_handleType = QAbstractVideoBuffer::GLTextureHandle;
- auto formats = surface->supportedPixelFormats(m_handleType);
- // Even if the surface does not support gl textures,
- // glupload will be added to the pipeline and GLMemory will be requested.
- // This will lead to upload data to gl textures
- // and download it when the buffer will be used within rendering.
- if (formats.isEmpty()) {
- m_handleType = QAbstractVideoBuffer::NoHandle;
- formats = surface->supportedPixelFormats(m_handleType);
- }
-
- GstCaps *caps = QGstUtils::capsForFormats(formats);
- for (guint i = 0; i < gst_caps_get_size(caps); ++i)
- gst_caps_set_features(caps, i, gst_caps_features_from_string("memory:GLMemory"));
-
- return caps;
- }
-#endif
- return QGstUtils::capsForFormats(surface->supportedPixelFormats(QAbstractVideoBuffer::NoHandle));
-}
-
-bool QGstDefaultVideoRenderer::start(QAbstractVideoSurface *surface, GstCaps *caps)
-{
- m_flushed = true;
- m_format = QGstUtils::formatForCaps(caps, &m_videoInfo, m_handleType);
-
- return m_format.isValid() && surface->start(m_format);
-}
-
-void QGstDefaultVideoRenderer::stop(QAbstractVideoSurface *surface)
-{
- m_flushed = true;
- if (surface)
- surface->stop();
-}
-
-bool QGstDefaultVideoRenderer::present(QAbstractVideoSurface *surface, GstBuffer *buffer)
-{
- m_flushed = false;
-
- QGstVideoBuffer *videoBuffer = nullptr;
-#if QT_CONFIG(gstreamer_gl)
- if (m_format.handleType() == QAbstractVideoBuffer::GLTextureHandle) {
- GstGLMemory *glmem = GST_GL_MEMORY_CAST(gst_buffer_peek_memory(buffer, 0));
- guint textureId = gst_gl_memory_get_texture_id(glmem);
- videoBuffer = new QGstVideoBuffer(buffer, m_videoInfo, m_format.handleType(), textureId);
- }
-#endif
-
- if (!videoBuffer)
- videoBuffer = new QGstVideoBuffer(buffer, m_videoInfo);
-
- auto meta = gst_buffer_get_video_crop_meta (buffer);
- if (meta) {
- QRect vp(meta->x, meta->y, meta->width, meta->height);
- if (m_format.viewport() != vp) {
-#ifdef DEBUG_VIDEO_SURFACE_SINK
- qDebug() << Q_FUNC_INFO << " Update viewport on Metadata: [" << meta->height << "x" << meta->width << " | " << meta->x << "x" << meta->y << "]";
-#endif
- //Update viewport if data is not the same
- m_format.setViewport(vp);
- surface->start(m_format);
- }
- }
-
- QVideoFrame frame(
- videoBuffer,
- m_format.frameSize(),
- m_format.pixelFormat());
- QGstUtils::setFrameTimeStamps(&frame, buffer);
-
- return surface->present(frame);
-}
-
-void QGstDefaultVideoRenderer::flush(QAbstractVideoSurface *surface)
-{
- if (surface && !m_flushed)
- surface->present(QVideoFrame());
- m_flushed = true;
-}
-
-bool QGstDefaultVideoRenderer::proposeAllocation(GstQuery *)
-{
- return true;
-}
-
-Q_GLOBAL_STATIC_WITH_ARGS(QMediaPluginLoader, rendererLoader,
- (QGstVideoRendererInterface_iid, QLatin1String("video/gstvideorenderer"), Qt::CaseInsensitive))
-
-QVideoSurfaceGstDelegate::QVideoSurfaceGstDelegate(QAbstractVideoSurface *surface)
- : m_surface(surface)
-{
- const auto instances = rendererLoader()->instances(QGstVideoRendererPluginKey);
- for (QObject *instance : instances) {
- auto plugin = qobject_cast<QGstVideoRendererInterface*>(instance);
- if (QGstVideoRenderer *renderer = plugin ? plugin->createRenderer() : nullptr)
- m_renderers.append(renderer);
- }
-
- m_renderers.append(new QGstDefaultVideoRenderer);
- updateSupportedFormats();
- connect(m_surface, SIGNAL(supportedFormatsChanged()), this, SLOT(updateSupportedFormats()));
-}
-
-QVideoSurfaceGstDelegate::~QVideoSurfaceGstDelegate()
-{
- qDeleteAll(m_renderers);
-
- if (m_surfaceCaps)
- gst_caps_unref(m_surfaceCaps);
- if (m_startCaps)
- gst_caps_unref(m_startCaps);
-#if QT_CONFIG(gstreamer_gl)
- if (m_gstGLDisplayContext)
- gst_object_unref(m_gstGLDisplayContext);
-#endif
-}
-
-GstCaps *QVideoSurfaceGstDelegate::caps()
-{
- QMutexLocker locker(&m_mutex);
-
- gst_caps_ref(m_surfaceCaps);
-
- return m_surfaceCaps;
-}
-
-bool QVideoSurfaceGstDelegate::start(GstCaps *caps)
-{
- QMutexLocker locker(&m_mutex);
-
- if (m_activeRenderer) {
- m_flush = true;
- m_stop = true;
- }
-
- if (m_startCaps)
- gst_caps_unref(m_startCaps);
- m_startCaps = caps;
- gst_caps_ref(m_startCaps);
-
- /*
- Waiting for start() to be invoked in the main thread may block
- if gstreamer blocks the main thread until this call is finished.
- This situation is rare and usually caused by setState(Null)
- while pipeline is being prerolled.
-
- The proper solution to this involves controlling gstreamer pipeline from
- other thread than video surface.
-
- Currently start() fails if wait() timed out.
- */
- if (!waitForAsyncEvent(&locker, &m_setupCondition, 1000) && m_startCaps) {
- qWarning() << "Failed to start video surface due to main thread blocked.";
- gst_caps_unref(m_startCaps);
- m_startCaps = 0;
- }
-
- return m_activeRenderer != 0;
-}
-
-void QVideoSurfaceGstDelegate::stop()
-{
- QMutexLocker locker(&m_mutex);
-
- if (!m_activeRenderer)
- return;
-
- m_flush = true;
- m_stop = true;
-
- if (m_startCaps) {
- gst_caps_unref(m_startCaps);
- m_startCaps = 0;
- }
-
- waitForAsyncEvent(&locker, &m_setupCondition, 500);
-}
-
-void QVideoSurfaceGstDelegate::unlock()
-{
- QMutexLocker locker(&m_mutex);
-
- m_setupCondition.wakeAll();
- m_renderCondition.wakeAll();
-}
-
-bool QVideoSurfaceGstDelegate::proposeAllocation(GstQuery *query)
-{
- QMutexLocker locker(&m_mutex);
-
- if (QGstVideoRenderer *pool = m_activeRenderer) {
- locker.unlock();
-
- return pool->proposeAllocation(query);
- } else {
- return false;
- }
-}
-
-void QVideoSurfaceGstDelegate::flush()
-{
- QMutexLocker locker(&m_mutex);
-
- m_flush = true;
- m_renderBuffer = 0;
- m_renderCondition.wakeAll();
-
- notify();
-}
-
-GstFlowReturn QVideoSurfaceGstDelegate::render(GstBuffer *buffer)
-{
- QMutexLocker locker(&m_mutex);
-
- m_renderReturn = GST_FLOW_OK;
- m_renderBuffer = buffer;
-
- waitForAsyncEvent(&locker, &m_renderCondition, 300);
-
- m_renderBuffer = 0;
-
- return m_renderReturn;
-}
-
-#if QT_CONFIG(gstreamer_gl)
-static GstGLContext *gstGLDisplayContext(QAbstractVideoSurface *surface)
-{
- auto glContext = qobject_cast<QOpenGLContext*>(surface->property("GLContext").value<QObject*>());
- // Context is not ready yet.
- if (!glContext)
- return nullptr;
-
- GstGLDisplay *display = nullptr;
- const QString platform = QGuiApplication::platformName();
- const char *contextName = "eglcontext";
- GstGLPlatform glPlatform = GST_GL_PLATFORM_EGL;
- QPlatformNativeInterface *pni = QGuiApplication::platformNativeInterface();
-
-#if GST_GL_HAVE_WINDOW_X11
- if (platform == QLatin1String("xcb")) {
- if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) {
- contextName = "glxcontext";
- glPlatform = GST_GL_PLATFORM_GLX;
- }
-
- display = (GstGLDisplay *)gst_gl_display_x11_new_with_display(
- (Display *)pni->nativeResourceForIntegration("display"));
- }
-#endif
-
-#if GST_GL_HAVE_PLATFORM_EGL
- if (!display && platform == QLatin1String("eglfs")) {
- display = (GstGLDisplay *)gst_gl_display_egl_new_with_egl_display(
- pni->nativeResourceForIntegration("egldisplay"));
- }
-#endif
-
-#if GST_CHECK_VERSION(1,11,1)
-#if GST_GL_HAVE_WINDOW_WAYLAND
- if (!display && platform.startsWith(QLatin1String("wayland"))) {
- const char *displayName = (platform == QLatin1String("wayland"))
- ? "display" : "egldisplay";
-
- display = (GstGLDisplay *)gst_gl_display_wayland_new_with_display(
- (struct wl_display *)pni->nativeResourceForIntegration(displayName));
- }
-#endif
-#endif
-
- if (!display) {
- qWarning() << "Could not create GstGLDisplay";
- return nullptr;
- }
-
- void *nativeContext = pni->nativeResourceForContext(contextName, glContext);
- if (!nativeContext)
- qWarning() << "Could not find resource for" << contextName;
-
- GstGLContext *appContext = gst_gl_context_new_wrapped(display, (guintptr)nativeContext, glPlatform, GST_GL_API_ANY);
- if (!appContext)
- qWarning() << "Could not create wrappped context for platform:" << glPlatform;
-
- GstGLContext *displayContext = nullptr;
- GError *error = nullptr;
- gst_gl_display_create_context(display, appContext, &displayContext, &error);
- if (error) {
- qWarning() << "Could not create display context:" << error->message;
- g_clear_error(&error);
- }
-
- if (appContext)
- gst_object_unref(appContext);
-
- gst_object_unref(display);
-
- return displayContext;
-}
-#endif // #if QT_CONFIG(gstreamer_gl)
-
-bool QVideoSurfaceGstDelegate::query(GstQuery *query)
-{
-#if QT_CONFIG(gstreamer_gl)
- if (GST_QUERY_TYPE(query) == GST_QUERY_CONTEXT) {
- const gchar *type;
- gst_query_parse_context_type(query, &type);
-
- if (strcmp(type, "gst.gl.local_context") != 0)
- return false;
-
- if (!m_gstGLDisplayContext)
- m_gstGLDisplayContext = gstGLDisplayContext(m_surface);
-
- // No context yet.
- if (!m_gstGLDisplayContext)
- return false;
-
- GstContext *context = nullptr;
- gst_query_parse_context(query, &context);
- context = context ? gst_context_copy(context) : gst_context_new(type, FALSE);
- GstStructure *structure = gst_context_writable_structure(context);
-#if GST_CHECK_VERSION(1,11,1)
- gst_structure_set(structure, "context", GST_TYPE_GL_CONTEXT, m_gstGLDisplayContext, nullptr);
-#else
- gst_structure_set(structure, "context", GST_GL_TYPE_CONTEXT, m_gstGLDisplayContext, nullptr);
-#endif
- gst_query_set_context(query, context);
- gst_context_unref(context);
-
- return m_gstGLDisplayContext;
- }
-#else
- Q_UNUSED(query);
-#endif
- return false;
-}
-
-bool QVideoSurfaceGstDelegate::event(QEvent *event)
-{
- if (event->type() == QEvent::UpdateRequest) {
- QMutexLocker locker(&m_mutex);
-
- if (m_notified) {
- while (handleEvent(&locker)) {}
- m_notified = false;
- }
- return true;
- } else {
- return QObject::event(event);
- }
-}
-
-bool QVideoSurfaceGstDelegate::handleEvent(QMutexLocker<QMutex> *locker)
-{
- if (m_flush) {
- m_flush = false;
- if (m_activeRenderer) {
- locker->unlock();
-
- m_activeRenderer->flush(m_surface);
- }
- } else if (m_stop) {
- m_stop = false;
-
- if (QGstVideoRenderer * const activePool = m_activeRenderer) {
- m_activeRenderer = 0;
- locker->unlock();
-
- activePool->stop(m_surface);
-
- locker->relock();
- }
- } else if (m_startCaps) {
- Q_ASSERT(!m_activeRenderer);
-
- GstCaps * const startCaps = m_startCaps;
- m_startCaps = 0;
-
- if (m_renderer && m_surface) {
- locker->unlock();
-
- const bool started = m_renderer->start(m_surface, startCaps);
-
- locker->relock();
-
- m_activeRenderer = started
- ? m_renderer
- : 0;
- } else if (QGstVideoRenderer * const activePool = m_activeRenderer) {
- m_activeRenderer = 0;
- locker->unlock();
-
- activePool->stop(m_surface);
-
- locker->relock();
- }
-
- gst_caps_unref(startCaps);
- } else if (m_renderBuffer) {
- GstBuffer *buffer = m_renderBuffer;
- m_renderBuffer = 0;
- m_renderReturn = GST_FLOW_ERROR;
-
- if (m_activeRenderer && m_surface) {
- gst_buffer_ref(buffer);
-
- locker->unlock();
-
- const bool rendered = m_activeRenderer->present(m_surface, buffer);
-
- gst_buffer_unref(buffer);
-
- locker->relock();
-
- if (rendered)
- m_renderReturn = GST_FLOW_OK;
- }
-
- m_renderCondition.wakeAll();
- } else {
- m_setupCondition.wakeAll();
-
- return false;
- }
- return true;
-}
-
-void QVideoSurfaceGstDelegate::notify()
-{
- if (!m_notified) {
- m_notified = true;
- QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
- }
-}
-
-bool QVideoSurfaceGstDelegate::waitForAsyncEvent(
- QMutexLocker<QMutex> *locker, QWaitCondition *condition, unsigned long time)
-{
- if (QThread::currentThread() == thread()) {
- while (handleEvent(locker)) {}
- m_notified = false;
-
- return true;
- } else {
- notify();
-
- return condition->wait(&m_mutex, time);
- }
-}
-
-void QVideoSurfaceGstDelegate::updateSupportedFormats()
-{
- if (m_surfaceCaps) {
- gst_caps_unref(m_surfaceCaps);
- m_surfaceCaps = 0;
- }
-
- for (QGstVideoRenderer *pool : qAsConst(m_renderers)) {
- if (GstCaps *caps = pool->getCaps(m_surface)) {
- if (gst_caps_is_empty(caps)) {
- gst_caps_unref(caps);
- continue;
- }
-
- if (m_surfaceCaps)
- gst_caps_unref(m_surfaceCaps);
-
- m_renderer = pool;
- m_surfaceCaps = caps;
- break;
- } else {
- gst_caps_unref(caps);
- }
- }
-}
-
-static GstVideoSinkClass *sink_parent_class;
-static QAbstractVideoSurface *current_surface;
-
-#define VO_SINK(s) QGstVideoRendererSink *sink(reinterpret_cast<QGstVideoRendererSink *>(s))
-
-QGstVideoRendererSink *QGstVideoRendererSink::createSink(QAbstractVideoSurface *surface)
-{
- setSurface(surface);
- QGstVideoRendererSink *sink = reinterpret_cast<QGstVideoRendererSink *>(
- g_object_new(QGstVideoRendererSink::get_type(), 0));
-
- g_signal_connect(G_OBJECT(sink), "notify::show-preroll-frame", G_CALLBACK(handleShowPrerollChange), sink);
-
- return sink;
-}
-
-void QGstVideoRendererSink::setSurface(QAbstractVideoSurface *surface)
-{
- current_surface = surface;
- get_type();
-}
-
-GType QGstVideoRendererSink::get_type()
-{
- static GType type = 0;
-
- if (type == 0) {
- static const GTypeInfo info =
- {
- sizeof(QGstVideoRendererSinkClass), // class_size
- base_init, // base_init
- nullptr, // base_finalize
- class_init, // class_init
- nullptr, // class_finalize
- nullptr, // class_data
- sizeof(QGstVideoRendererSink), // instance_size
- 0, // n_preallocs
- instance_init, // instance_init
- 0 // value_table
- };
-
- type = g_type_register_static(
- GST_TYPE_VIDEO_SINK, "QGstVideoRendererSink", &info, GTypeFlags(0));
-
- // Register the sink type to be used in custom piplines.
- // When surface is ready the sink can be used.
- gst_element_register(nullptr, "qtvideosink", GST_RANK_PRIMARY, type);
- }
-
- return type;
-}
-
-void QGstVideoRendererSink::class_init(gpointer g_class, gpointer class_data)
-{
- Q_UNUSED(class_data);
-
- sink_parent_class = reinterpret_cast<GstVideoSinkClass *>(g_type_class_peek_parent(g_class));
-
- GstVideoSinkClass *video_sink_class = reinterpret_cast<GstVideoSinkClass *>(g_class);
- video_sink_class->show_frame = QGstVideoRendererSink::show_frame;
-
- GstBaseSinkClass *base_sink_class = reinterpret_cast<GstBaseSinkClass *>(g_class);
- base_sink_class->get_caps = QGstVideoRendererSink::get_caps;
- base_sink_class->set_caps = QGstVideoRendererSink::set_caps;
- base_sink_class->propose_allocation = QGstVideoRendererSink::propose_allocation;
- base_sink_class->stop = QGstVideoRendererSink::stop;
- base_sink_class->unlock = QGstVideoRendererSink::unlock;
- base_sink_class->query = QGstVideoRendererSink::query;
-
- GstElementClass *element_class = reinterpret_cast<GstElementClass *>(g_class);
- element_class->change_state = QGstVideoRendererSink::change_state;
- gst_element_class_set_metadata(element_class,
- "Qt built-in video renderer sink",
- "Sink/Video",
- "Qt default built-in video renderer sink",
- "The Qt Company");
-
- GObjectClass *object_class = reinterpret_cast<GObjectClass *>(g_class);
- object_class->finalize = QGstVideoRendererSink::finalize;
-}
-
-void QGstVideoRendererSink::base_init(gpointer g_class)
-{
- static GstStaticPadTemplate sink_pad_template = GST_STATIC_PAD_TEMPLATE(
- "sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS(
- "video/x-raw, "
- "framerate = (fraction) [ 0, MAX ], "
- "width = (int) [ 1, MAX ], "
- "height = (int) [ 1, MAX ]"));
-
- gst_element_class_add_pad_template(
- GST_ELEMENT_CLASS(g_class), gst_static_pad_template_get(&sink_pad_template));
-}
-
-struct NullSurface : QAbstractVideoSurface
-{
- NullSurface(QObject *parent = nullptr) : QAbstractVideoSurface(parent) { }
-
- QList<QVideoFrame::PixelFormat> supportedPixelFormats(QAbstractVideoBuffer::HandleType) const override
- {
- return QList<QVideoFrame::PixelFormat>() << QVideoFrame::Format_RGB32;
- }
-
- bool present(const QVideoFrame &) override
- {
- return true;
- }
-};
-
-void QGstVideoRendererSink::instance_init(GTypeInstance *instance, gpointer g_class)
-{
- Q_UNUSED(g_class);
- VO_SINK(instance);
-
- if (!current_surface) {
- qWarning() << "Using qtvideosink element without video surface";
- static NullSurface nullSurface;
- current_surface = &nullSurface;
- }
-
- sink->delegate = new QVideoSurfaceGstDelegate(current_surface);
- sink->delegate->moveToThread(current_surface->thread());
- current_surface = nullptr;
-}
-
-void QGstVideoRendererSink::finalize(GObject *object)
-{
- VO_SINK(object);
-
- delete sink->delegate;
-
- // Chain up
- G_OBJECT_CLASS(sink_parent_class)->finalize(object);
-}
-
-void QGstVideoRendererSink::handleShowPrerollChange(GObject *o, GParamSpec *p, gpointer d)
-{
- Q_UNUSED(o);
- Q_UNUSED(p);
- QGstVideoRendererSink *sink = reinterpret_cast<QGstVideoRendererSink *>(d);
-
- gboolean showPrerollFrame = true; // "show-preroll-frame" property is true by default
- g_object_get(G_OBJECT(sink), "show-preroll-frame", &showPrerollFrame, nullptr);
-
- if (!showPrerollFrame) {
- GstState state = GST_STATE_VOID_PENDING;
- GstClockTime timeout = 10000000; // 10 ms
- gst_element_get_state(GST_ELEMENT(sink), &state, nullptr, timeout);
- // show-preroll-frame being set to 'false' while in GST_STATE_PAUSED means
- // the QMediaPlayer was stopped from the paused state.
- // We need to flush the current frame.
- if (state == GST_STATE_PAUSED)
- sink->delegate->flush();
- }
-}
-
-GstStateChangeReturn QGstVideoRendererSink::change_state(
- GstElement *element, GstStateChange transition)
-{
- QGstVideoRendererSink *sink = reinterpret_cast<QGstVideoRendererSink *>(element);
-
- gboolean showPrerollFrame = true; // "show-preroll-frame" property is true by default
- g_object_get(G_OBJECT(element), "show-preroll-frame", &showPrerollFrame, nullptr);
-
- // If show-preroll-frame is 'false' when transitioning from GST_STATE_PLAYING to
- // GST_STATE_PAUSED, it means the QMediaPlayer was stopped.
- // We need to flush the current frame.
- if (transition == GST_STATE_CHANGE_PLAYING_TO_PAUSED && !showPrerollFrame)
- sink->delegate->flush();
-
- return GST_ELEMENT_CLASS(sink_parent_class)->change_state(element, transition);
-}
-
-GstCaps *QGstVideoRendererSink::get_caps(GstBaseSink *base, GstCaps *filter)
-{
- VO_SINK(base);
-
- GstCaps *caps = sink->delegate->caps();
- GstCaps *unfiltered = caps;
- if (filter) {
- caps = gst_caps_intersect(unfiltered, filter);
- gst_caps_unref(unfiltered);
- }
-
- return caps;
-}
-
-gboolean QGstVideoRendererSink::set_caps(GstBaseSink *base, GstCaps *caps)
-{
- VO_SINK(base);
-
-#ifdef DEBUG_VIDEO_SURFACE_SINK
- qDebug() << "set_caps:";
- qDebug() << caps;
-#endif
-
- if (!caps) {
- sink->delegate->stop();
-
- return TRUE;
- } else if (sink->delegate->start(caps)) {
- return TRUE;
- } else {
- return FALSE;
- }
-}
-
-gboolean QGstVideoRendererSink::propose_allocation(GstBaseSink *base, GstQuery *query)
-{
- VO_SINK(base);
- return sink->delegate->proposeAllocation(query);
-}
-
-gboolean QGstVideoRendererSink::stop(GstBaseSink *base)
-{
- VO_SINK(base);
- sink->delegate->stop();
- return TRUE;
-}
-
-gboolean QGstVideoRendererSink::unlock(GstBaseSink *base)
-{
- VO_SINK(base);
- sink->delegate->unlock();
- return TRUE;
-}
-
-GstFlowReturn QGstVideoRendererSink::show_frame(GstVideoSink *base, GstBuffer *buffer)
-{
- VO_SINK(base);
- return sink->delegate->render(buffer);
-}
-
-gboolean QGstVideoRendererSink::query(GstBaseSink *base, GstQuery *query)
-{
- VO_SINK(base);
- if (sink->delegate->query(query))
- return TRUE;
-
- return GST_BASE_SINK_CLASS(sink_parent_class)->query(base, query);
-}
-
-QT_END_NAMESPACE
diff --git a/src/gsttools/qgstvideorenderersink_p.h b/src/gsttools/qgstvideorenderersink_p.h
deleted file mode 100644
index 81bcb5c02..000000000
--- a/src/gsttools/qgstvideorenderersink_p.h
+++ /dev/null
@@ -1,199 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Jolla 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 QGSTVIDEORENDERERSINK_P_H
-#define QGSTVIDEORENDERERSINK_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 <gst/video/gstvideosink.h>
-#include <gst/video/video.h>
-
-#include <QtCore/qlist.h>
-#include <QtCore/qmutex.h>
-#include <QtCore/qqueue.h>
-#include <QtCore/qpointer.h>
-#include <QtCore/qwaitcondition.h>
-#include <qvideosurfaceformat.h>
-#include <qvideoframe.h>
-#include <qabstractvideobuffer.h>
-
-#include "qgstvideorendererplugin_p.h"
-
-#include "qgstvideorendererplugin_p.h"
-
-#if QT_CONFIG(gstreamer_gl)
-#ifndef GST_USE_UNSTABLE_API
-#define GST_USE_UNSTABLE_API
-#endif
-#include <gst/gl/gl.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-class QAbstractVideoSurface;
-
-class QGstDefaultVideoRenderer : public QGstVideoRenderer
-{
-public:
- QGstDefaultVideoRenderer();
- ~QGstDefaultVideoRenderer();
-
- GstCaps *getCaps(QAbstractVideoSurface *surface) override;
- bool start(QAbstractVideoSurface *surface, GstCaps *caps) override;
- void stop(QAbstractVideoSurface *surface) override;
-
- bool proposeAllocation(GstQuery *query) override;
-
- bool present(QAbstractVideoSurface *surface, GstBuffer *buffer) override;
- void flush(QAbstractVideoSurface *surface) override;
-
-private:
- QVideoSurfaceFormat m_format;
- GstVideoInfo m_videoInfo;
- bool m_flushed = true;
- QAbstractVideoBuffer::HandleType m_handleType = QAbstractVideoBuffer::NoHandle;
-};
-
-class QVideoSurfaceGstDelegate : public QObject
-{
- Q_OBJECT
-public:
- QVideoSurfaceGstDelegate(QAbstractVideoSurface *surface);
- ~QVideoSurfaceGstDelegate();
-
- GstCaps *caps();
-
- bool start(GstCaps *caps);
- void stop();
- void unlock();
- bool proposeAllocation(GstQuery *query);
-
- void flush();
-
- GstFlowReturn render(GstBuffer *buffer);
-
- bool event(QEvent *event) override;
- bool query(GstQuery *query);
-
-private slots:
- bool handleEvent(QMutexLocker<QMutex> *locker);
- void updateSupportedFormats();
-
-private:
- void notify();
- bool waitForAsyncEvent(QMutexLocker<QMutex> *locker, QWaitCondition *condition, unsigned long time);
-
- QPointer<QAbstractVideoSurface> m_surface;
-
- QMutex m_mutex;
- QWaitCondition m_setupCondition;
- QWaitCondition m_renderCondition;
- GstFlowReturn m_renderReturn = GST_FLOW_OK;
- QList<QGstVideoRenderer *> m_renderers;
- QGstVideoRenderer *m_renderer = nullptr;
- QGstVideoRenderer *m_activeRenderer = nullptr;
-
- GstCaps *m_surfaceCaps = nullptr;
- GstCaps *m_startCaps = nullptr;
- GstBuffer *m_renderBuffer = nullptr;
-#if QT_CONFIG(gstreamer_gl)
- GstGLContext *m_gstGLDisplayContext = nullptr;
-#endif
-
- bool m_notified = false;
- bool m_stop = false;
- bool m_flush = false;
-};
-
-class Q_GSTTOOLS_EXPORT QGstVideoRendererSink
-{
-public:
- GstVideoSink parent;
-
- static QGstVideoRendererSink *createSink(QAbstractVideoSurface *surface);
- static void setSurface(QAbstractVideoSurface *surface);
-
-private:
- static GType get_type();
- static void class_init(gpointer g_class, gpointer class_data);
- static void base_init(gpointer g_class);
- static void instance_init(GTypeInstance *instance, gpointer g_class);
-
- static void finalize(GObject *object);
-
- static void handleShowPrerollChange(GObject *o, GParamSpec *p, gpointer d);
-
- static GstStateChangeReturn change_state(GstElement *element, GstStateChange transition);
-
- static GstCaps *get_caps(GstBaseSink *sink, GstCaps *filter);
- static gboolean set_caps(GstBaseSink *sink, GstCaps *caps);
-
- static gboolean propose_allocation(GstBaseSink *sink, GstQuery *query);
-
- static gboolean stop(GstBaseSink *sink);
-
- static gboolean unlock(GstBaseSink *sink);
-
- static GstFlowReturn show_frame(GstVideoSink *sink, GstBuffer *buffer);
- static gboolean query(GstBaseSink *element, GstQuery *query);
-
-private:
- QVideoSurfaceGstDelegate *delegate = nullptr;
-};
-
-
-class QGstVideoRendererSinkClass
-{
-public:
- GstVideoSinkClass parent_class;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/gsttools/qvideosurfacegstsink.cpp b/src/gsttools/qvideosurfacegstsink.cpp
deleted file mode 100644
index c6951bdef..000000000
--- a/src/gsttools/qvideosurfacegstsink.cpp
+++ /dev/null
@@ -1,712 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#include <qabstractvideosurface.h>
-#include <qvideoframe.h>
-#include <QDebug>
-#include <QMap>
-#include <QDebug>
-#include <QThread>
-
-#include <private/qmediapluginloader_p.h>
-#include "qgstvideobuffer_p.h"
-
-#include "qgstutils_p.h"
-#include "qvideosurfacegstsink_p.h"
-
-#if GST_VERSION_MAJOR >=1
-#include <gst/video/video.h>
-#endif
-
-//#define DEBUG_VIDEO_SURFACE_SINK
-
-QT_BEGIN_NAMESPACE
-
-Q_GLOBAL_STATIC_WITH_ARGS(QMediaPluginLoader, bufferPoolLoader,
- (QGstBufferPoolInterface_iid, QLatin1String("video/bufferpool"), Qt::CaseInsensitive))
-
-
-QVideoSurfaceGstDelegate::QVideoSurfaceGstDelegate(
- QAbstractVideoSurface *surface)
- : m_surface(surface)
-{
- if (m_surface) {
- const auto instances = bufferPoolLoader()->instances(QGstBufferPoolPluginKey);
- for (QObject *instance : instances) {
- auto plugin = qobject_cast<QGstBufferPoolInterface*>(instance);
-
- if (plugin) {
- m_pools.append(plugin);
- }
- }
-
- updateSupportedFormats();
- connect(m_surface, SIGNAL(supportedFormatsChanged()), this, SLOT(updateSupportedFormats()));
- }
-}
-
-QVideoSurfaceGstDelegate::~QVideoSurfaceGstDelegate()
-{
-}
-
-QList<QVideoFrame::PixelFormat> QVideoSurfaceGstDelegate::supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const
-{
- QMutexLocker locker(const_cast<QMutex *>(&m_mutex));
-
- if (!m_surface)
- return QList<QVideoFrame::PixelFormat>();
- else if (handleType == QAbstractVideoBuffer::NoHandle)
- return m_supportedPixelFormats;
- else if (handleType == m_pool->handleType())
- return m_supportedPoolPixelFormats;
- else
- return m_surface->supportedPixelFormats(handleType);
-}
-
-QVideoSurfaceFormat QVideoSurfaceGstDelegate::surfaceFormat() const
-{
- QMutexLocker locker(const_cast<QMutex *>(&m_mutex));
- return m_format;
-}
-
-bool QVideoSurfaceGstDelegate::start(const QVideoSurfaceFormat &format, int bytesPerLine)
-{
- if (!m_surface)
- return false;
-
- QMutexLocker locker(&m_mutex);
-
- m_format = format;
- m_bytesPerLine = bytesPerLine;
-
- if (QThread::currentThread() == thread()) {
- m_started = !m_surface.isNull() ? m_surface->start(m_format) : false;
- } else {
- m_started = false;
- m_startCanceled = false;
- QMetaObject::invokeMethod(this, "queuedStart", Qt::QueuedConnection);
-
- /*
- Waiting for start() to be invoked in the main thread may block
- if gstreamer blocks the main thread until this call is finished.
- This situation is rare and usually caused by setState(Null)
- while pipeline is being prerolled.
-
- The proper solution to this involves controlling gstreamer pipeline from
- other thread than video surface.
-
- Currently start() fails if wait() timed out.
- */
- if (!m_setupCondition.wait(&m_mutex, 1000)) {
- qWarning() << "Failed to start video surface due to main thread blocked.";
- m_startCanceled = true;
- }
- }
-
- m_format = m_surface->surfaceFormat();
-
- return m_started;
-}
-
-void QVideoSurfaceGstDelegate::stop()
-{
- if (!m_surface)
- return;
-
- QMutexLocker locker(&m_mutex);
-
- if (QThread::currentThread() == thread()) {
- if (!m_surface.isNull())
- m_surface->stop();
- } else {
- QMetaObject::invokeMethod(this, "queuedStop", Qt::QueuedConnection);
-
- // Waiting for stop() to be invoked in the main thread may block
- // if gstreamer blocks the main thread until this call is finished.
- m_setupCondition.wait(&m_mutex, 500);
- }
-
- m_started = false;
-}
-
-void QVideoSurfaceGstDelegate::unlock()
-{
- QMutexLocker locker(&m_mutex);
-
- m_startCanceled = true;
- m_setupCondition.wakeAll();
- m_renderCondition.wakeAll();
-}
-
-bool QVideoSurfaceGstDelegate::isActive()
-{
- QMutexLocker locker(&m_mutex);
- return !m_surface.isNull() && m_surface->isActive();
-}
-
-void QVideoSurfaceGstDelegate::clearPoolBuffers()
-{
- QMutexLocker locker(&m_poolMutex);
- if (m_pool)
- m_pool->clear();
-}
-
-void QVideoSurfaceGstDelegate::flush()
-{
- QMutexLocker locker(&m_mutex);
-
- m_frame = QVideoFrame();
- m_renderCondition.wakeAll();
-
- if (QThread::currentThread() == thread()) {
- if (!m_surface.isNull())
- m_surface->present(m_frame);
- } else {
- QMetaObject::invokeMethod(this, "queuedFlush", Qt::QueuedConnection);
- }
-}
-
-GstFlowReturn QVideoSurfaceGstDelegate::render(GstBuffer *buffer)
-{
- if (!m_surface) {
- qWarning() << "Rendering video frame to deleted surface, skip.";
- //return GST_FLOW_NOT_NEGOTIATED;
- return GST_FLOW_OK;
- }
-
- QMutexLocker locker(&m_mutex);
-
- QAbstractVideoBuffer *videoBuffer = 0;
-
- if (m_pool)
- videoBuffer = m_pool->prepareVideoBuffer(buffer, m_bytesPerLine);
-
- if (!videoBuffer)
- videoBuffer = new QGstVideoBuffer(buffer, m_bytesPerLine);
-
- m_frame = QVideoFrame(
- videoBuffer,
- m_format.frameSize(),
- m_format.pixelFormat());
-
- QGstUtils::setFrameTimeStamps(&m_frame, buffer);
-
- m_renderReturn = GST_FLOW_OK;
-
- if (QThread::currentThread() == thread()) {
- if (!m_surface.isNull())
- m_surface->present(m_frame);
- else
- qWarning() << "m_surface.isNull().";
- } else {
- QMetaObject::invokeMethod(this, "queuedRender", Qt::QueuedConnection);
- m_renderCondition.wait(&m_mutex, 300);
- }
-
- m_frame = QVideoFrame();
- return m_renderReturn;
-}
-
-void QVideoSurfaceGstDelegate::queuedStart()
-{
- QMutexLocker locker(&m_mutex);
-
- if (!m_startCanceled) {
- m_started = m_surface->start(m_format);
- m_setupCondition.wakeAll();
- }
-}
-
-void QVideoSurfaceGstDelegate::queuedStop()
-{
- QMutexLocker locker(&m_mutex);
-
- m_surface->stop();
-
- m_setupCondition.wakeAll();
-}
-
-void QVideoSurfaceGstDelegate::queuedFlush()
-{
- QMutexLocker locker(&m_mutex);
-
- if (!m_surface.isNull())
- m_surface->present(QVideoFrame());
-}
-
-void QVideoSurfaceGstDelegate::queuedRender()
-{
- QMutexLocker locker(&m_mutex);
-
- if (!m_frame.isValid())
- return;
-
- if (m_surface.isNull()) {
- qWarning() << "Rendering video frame to deleted surface, skip the frame";
- m_renderReturn = GST_FLOW_OK;
- } else if (m_surface->present(m_frame)) {
- m_renderReturn = GST_FLOW_OK;
- } else {
- switch (m_surface->error()) {
- case QAbstractVideoSurface::NoError:
- m_renderReturn = GST_FLOW_OK;
- break;
- case QAbstractVideoSurface::StoppedError:
- //It's likely we are in process of changing video output
- //and the surface is already stopped, ignore the frame
- m_renderReturn = GST_FLOW_OK;
- break;
- default:
- qWarning() << "Failed to render video frame:" << m_surface->error();
- m_renderReturn = GST_FLOW_OK;
- break;
- }
- }
-
- m_renderCondition.wakeAll();
-}
-
-void QVideoSurfaceGstDelegate::updateSupportedFormats()
-{
- QGstBufferPoolInterface *newPool = 0;
- for (QGstBufferPoolInterface *pool : qAsConst(m_pools)) {
- if (!m_surface->supportedPixelFormats(pool->handleType()).isEmpty()) {
- newPool = pool;
- break;
- }
- }
-
- if (newPool != m_pool) {
- QMutexLocker lock(&m_poolMutex);
-
- if (m_pool)
- m_pool->clear();
- m_pool = newPool;
- }
-
- QMutexLocker locker(&m_mutex);
-
- m_supportedPixelFormats.clear();
- m_supportedPoolPixelFormats.clear();
- if (m_surface) {
- m_supportedPixelFormats = m_surface->supportedPixelFormats();
- if (m_pool)
- m_supportedPoolPixelFormats = m_surface->supportedPixelFormats(m_pool->handleType());
- }
-}
-
-static GstVideoSinkClass *sink_parent_class;
-
-#define VO_SINK(s) QVideoSurfaceGstSink *sink(reinterpret_cast<QVideoSurfaceGstSink *>(s))
-
-QVideoSurfaceGstSink *QVideoSurfaceGstSink::createSink(QAbstractVideoSurface *surface)
-{
- QVideoSurfaceGstSink *sink = reinterpret_cast<QVideoSurfaceGstSink *>(
- g_object_new(QVideoSurfaceGstSink::get_type(), 0));
-
- sink->delegate = new QVideoSurfaceGstDelegate(surface);
-
- g_signal_connect(G_OBJECT(sink), "notify::show-preroll-frame", G_CALLBACK(handleShowPrerollChange), sink);
-
- return sink;
-}
-
-GType QVideoSurfaceGstSink::get_type()
-{
- static GType type = 0;
-
- if (type == 0) {
- static const GTypeInfo info =
- {
- sizeof(QVideoSurfaceGstSinkClass), // class_size
- base_init, // base_init
- nullptr, // base_finalize
- class_init, // class_init
- nullptr, // class_finalize
- nullptr, // class_data
- sizeof(QVideoSurfaceGstSink), // instance_size
- 0, // n_preallocs
- instance_init, // instance_init
- 0 // value_table
- };
-
- type = g_type_register_static(
- GST_TYPE_VIDEO_SINK, "QVideoSurfaceGstSink", &info, GTypeFlags(0));
- }
-
- return type;
-}
-
-void QVideoSurfaceGstSink::class_init(gpointer g_class, gpointer class_data)
-{
- Q_UNUSED(class_data);
-
- sink_parent_class = reinterpret_cast<GstVideoSinkClass *>(g_type_class_peek_parent(g_class));
-
- GstBaseSinkClass *base_sink_class = reinterpret_cast<GstBaseSinkClass *>(g_class);
- base_sink_class->get_caps = QVideoSurfaceGstSink::get_caps;
- base_sink_class->set_caps = QVideoSurfaceGstSink::set_caps;
- base_sink_class->buffer_alloc = QVideoSurfaceGstSink::buffer_alloc;
- base_sink_class->start = QVideoSurfaceGstSink::start;
- base_sink_class->stop = QVideoSurfaceGstSink::stop;
- base_sink_class->unlock = QVideoSurfaceGstSink::unlock;
-
-#if GST_CHECK_VERSION(0, 10, 25)
- GstVideoSinkClass *video_sink_class = reinterpret_cast<GstVideoSinkClass *>(g_class);
- video_sink_class->show_frame = QVideoSurfaceGstSink::show_frame;
-#else
- base_sink_class->preroll = QVideoSurfaceGstSink::preroll;
- base_sink_class->render = QVideoSurfaceGstSink::render;
-#endif
-
- GstElementClass *element_class = reinterpret_cast<GstElementClass *>(g_class);
- element_class->change_state = QVideoSurfaceGstSink::change_state;
-
- GObjectClass *object_class = reinterpret_cast<GObjectClass *>(g_class);
- object_class->finalize = QVideoSurfaceGstSink::finalize;
-}
-
-void QVideoSurfaceGstSink::base_init(gpointer g_class)
-{
- static GstStaticPadTemplate sink_pad_template = GST_STATIC_PAD_TEMPLATE(
- "sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS(
- "video/x-raw-rgb, "
- "framerate = (fraction) [ 0, MAX ], "
- "width = (int) [ 1, MAX ], "
- "height = (int) [ 1, MAX ]; "
- "video/x-raw-yuv, "
- "framerate = (fraction) [ 0, MAX ], "
- "width = (int) [ 1, MAX ], "
- "height = (int) [ 1, MAX ]"));
-
- gst_element_class_add_pad_template(
- GST_ELEMENT_CLASS(g_class), gst_static_pad_template_get(&sink_pad_template));
-}
-
-void QVideoSurfaceGstSink::instance_init(GTypeInstance *instance, gpointer g_class)
-{
- VO_SINK(instance);
-
- Q_UNUSED(g_class);
-
- sink->delegate = 0;
-
- sink->lastRequestedCaps = 0;
- sink->lastBufferCaps = 0;
- sink->lastSurfaceFormat = new QVideoSurfaceFormat;
-}
-
-void QVideoSurfaceGstSink::finalize(GObject *object)
-{
- VO_SINK(object);
-
- delete sink->lastSurfaceFormat;
- sink->lastSurfaceFormat = 0;
-
- if (sink->lastBufferCaps)
- gst_caps_unref(sink->lastBufferCaps);
- sink->lastBufferCaps = 0;
-
- if (sink->lastRequestedCaps)
- gst_caps_unref(sink->lastRequestedCaps);
- sink->lastRequestedCaps = 0;
-
- delete sink->delegate;
-
- // Chain up
- G_OBJECT_CLASS(sink_parent_class)->finalize(object);
-}
-
-void QVideoSurfaceGstSink::handleShowPrerollChange(GObject *o, GParamSpec *p, gpointer d)
-{
- Q_UNUSED(o);
- Q_UNUSED(p);
- QVideoSurfaceGstSink *sink = reinterpret_cast<QVideoSurfaceGstSink *>(d);
-
- gboolean showPrerollFrame = true; // "show-preroll-frame" property is true by default
- g_object_get(G_OBJECT(sink), "show-preroll-frame", &showPrerollFrame, nullptr);
-
- if (!showPrerollFrame) {
- GstState state = GST_STATE_VOID_PENDING;
- gst_element_get_state(GST_ELEMENT(sink), &state, nullptr, GST_CLOCK_TIME_NONE);
- // show-preroll-frame being set to 'false' while in GST_STATE_PAUSED means
- // the QMediaPlayer was stopped from the paused state.
- // We need to flush the current frame.
- if (state == GST_STATE_PAUSED)
- sink->delegate->flush();
- }
-}
-
-GstStateChangeReturn QVideoSurfaceGstSink::change_state(GstElement *element, GstStateChange transition)
-{
- QVideoSurfaceGstSink *sink = reinterpret_cast<QVideoSurfaceGstSink *>(element);
-
- gboolean showPrerollFrame = true; // "show-preroll-frame" property is true by default
- g_object_get(G_OBJECT(element), "show-preroll-frame", &showPrerollFrame, nullptr);
-
- // If show-preroll-frame is 'false' when transitioning from GST_STATE_PLAYING to
- // GST_STATE_PAUSED, it means the QMediaPlayer was stopped.
- // We need to flush the current frame.
- if (transition == GST_STATE_CHANGE_PLAYING_TO_PAUSED && !showPrerollFrame)
- sink->delegate->flush();
-
- return GST_ELEMENT_CLASS(sink_parent_class)->change_state(element, transition);
-}
-
-GstCaps *QVideoSurfaceGstSink::get_caps(GstBaseSink *base)
-{
- VO_SINK(base);
-
- // Find the supported pixel formats
- // with buffer pool specific formats listed first
- QList<QVideoFrame::PixelFormat> supportedFormats;
-
- QList<QVideoFrame::PixelFormat> poolHandleFormats;
- sink->delegate->poolMutex()->lock();
- QGstBufferPoolInterface *pool = sink->delegate->pool();
-
- if (pool)
- poolHandleFormats = sink->delegate->supportedPixelFormats(pool->handleType());
- sink->delegate->poolMutex()->unlock();
-
- supportedFormats = poolHandleFormats;
- const auto supportedPixelFormats = sink->delegate->supportedPixelFormats();
- for (QVideoFrame::PixelFormat format : supportedPixelFormats) {
- if (!poolHandleFormats.contains(format))
- supportedFormats.append(format);
- }
-
- return QGstUtils::capsForFormats(supportedFormats);
-}
-
-gboolean QVideoSurfaceGstSink::set_caps(GstBaseSink *base, GstCaps *caps)
-{
- VO_SINK(base);
-
-#ifdef DEBUG_VIDEO_SURFACE_SINK
- qDebug() << "set_caps:";
- qDebug() << gst_caps_to_string(caps);
-#endif
-
- if (!caps) {
- sink->delegate->stop();
-
- return TRUE;
- } else {
- int bytesPerLine = 0;
- QGstBufferPoolInterface *pool = sink->delegate->pool();
- QAbstractVideoBuffer::HandleType handleType =
- pool ? pool->handleType() : QAbstractVideoBuffer::NoHandle;
-
- QVideoSurfaceFormat format = QGstUtils::formatForCaps(caps, &bytesPerLine, handleType);
-
- if (sink->delegate->isActive()) {
- QVideoSurfaceFormat surfaceFormst = sink->delegate->surfaceFormat();
-
- if (format.pixelFormat() == surfaceFormst.pixelFormat() &&
- format.frameSize() == surfaceFormst.frameSize())
- return TRUE;
- else
- sink->delegate->stop();
- }
-
- if (sink->lastRequestedCaps)
- gst_caps_unref(sink->lastRequestedCaps);
- sink->lastRequestedCaps = 0;
-
-#ifdef DEBUG_VIDEO_SURFACE_SINK
- qDebug() << "Starting video surface, format:";
- qDebug() << format;
- qDebug() << "bytesPerLine:" << bytesPerLine;
-#endif
-
- if (sink->delegate->start(format, bytesPerLine))
- return TRUE;
- else
- qWarning() << "Failed to start video surface";
- }
-
- return FALSE;
-}
-
-GstFlowReturn QVideoSurfaceGstSink::buffer_alloc(
- GstBaseSink *base, guint64 offset, guint size, GstCaps *caps, GstBuffer **buffer)
-{
- VO_SINK(base);
-
- Q_UNUSED(offset);
- Q_UNUSED(size);
-
- if (!buffer)
- return GST_FLOW_ERROR;
-
- *buffer = nullptr;
-
- if (!sink->delegate->pool())
- return GST_FLOW_OK;
-
- QMutexLocker poolLock(sink->delegate->poolMutex());
- QGstBufferPoolInterface *pool = sink->delegate->pool();
-
- if (!pool)
- return GST_FLOW_OK;
-
- if (sink->lastRequestedCaps && gst_caps_is_equal(sink->lastRequestedCaps, caps)) {
- //qDebug() << "reusing last caps";
- *buffer = GST_BUFFER(pool->takeBuffer(*sink->lastSurfaceFormat, sink->lastBufferCaps));
- return GST_FLOW_OK;
- }
-
- if (sink->delegate->supportedPixelFormats(pool->handleType()).isEmpty()) {
- //qDebug() << "sink doesn't support native pool buffers, skip buffers allocation";
- return GST_FLOW_OK;
- }
-
- poolLock.unlock();
-
- GstCaps *intersection = gst_caps_intersect(get_caps(GST_BASE_SINK(sink)), caps);
-
- if (gst_caps_is_empty (intersection)) {
- gst_caps_unref(intersection);
- return GST_FLOW_NOT_NEGOTIATED;
- }
-
- if (sink->delegate->isActive()) {
- //if format was changed, restart the surface
- QVideoSurfaceFormat format = QGstUtils::formatForCaps(intersection);
- QVideoSurfaceFormat surfaceFormat = sink->delegate->surfaceFormat();
-
- if (format.pixelFormat() != surfaceFormat.pixelFormat() ||
- format.frameSize() != surfaceFormat.frameSize()) {
-#ifdef DEBUG_VIDEO_SURFACE_SINK
- qDebug() << "new format requested, restart video surface";
-#endif
- sink->delegate->stop();
- }
- }
-
- if (!sink->delegate->isActive()) {
- int bytesPerLine = 0;
- QGstBufferPoolInterface *pool = sink->delegate->pool();
- QAbstractVideoBuffer::HandleType handleType =
- pool ? pool->handleType() : QAbstractVideoBuffer::NoHandle;
-
- QVideoSurfaceFormat format = QGstUtils::formatForCaps(intersection, &bytesPerLine, handleType);
-
- if (!sink->delegate->start(format, bytesPerLine)) {
- qWarning() << "failed to start video surface";
- return GST_FLOW_NOT_NEGOTIATED;
- }
- }
-
- poolLock.relock();
- pool = sink->delegate->pool();
-
- QVideoSurfaceFormat surfaceFormat = sink->delegate->surfaceFormat();
-
- if (!pool->isFormatSupported(surfaceFormat)) {
- qDebug() << "sink doesn't support native pool format, skip custom buffers allocation";
- return GST_FLOW_OK;
- }
-
- if (sink->lastRequestedCaps)
- gst_caps_unref(sink->lastRequestedCaps);
- sink->lastRequestedCaps = caps;
- gst_caps_ref(sink->lastRequestedCaps);
-
- if (sink->lastBufferCaps)
- gst_caps_unref(sink->lastBufferCaps);
- sink->lastBufferCaps = intersection;
- gst_caps_ref(sink->lastBufferCaps);
-
- *sink->lastSurfaceFormat = surfaceFormat;
-
- *buffer = GST_BUFFER(pool->takeBuffer(surfaceFormat, intersection));
-
- return GST_FLOW_OK;
-}
-
-gboolean QVideoSurfaceGstSink::start(GstBaseSink *base)
-{
- Q_UNUSED(base);
- return TRUE;
-}
-
-gboolean QVideoSurfaceGstSink::stop(GstBaseSink *base)
-{
- VO_SINK(base);
- sink->delegate->clearPoolBuffers();
-
- return TRUE;
-}
-
-gboolean QVideoSurfaceGstSink::unlock(GstBaseSink *base)
-{
- VO_SINK(base);
- sink->delegate->unlock();
- return TRUE;
-}
-
-#if GST_CHECK_VERSION(0, 10, 25)
-GstFlowReturn QVideoSurfaceGstSink::show_frame(GstVideoSink *base, GstBuffer *buffer)
-{
- VO_SINK(base);
- return sink->delegate->render(buffer);
-}
-#else
-GstFlowReturn QVideoSurfaceGstSink::preroll(GstBaseSink *base, GstBuffer *buffer)
-{
- VO_SINK(base);
- gboolean showPrerollFrame = true;
- g_object_get(G_OBJECT(sink), "show-preroll-frame", &showPrerollFrame, nullptr);
-
- if (showPrerollFrame)
- return sink->delegate->render(buffer);
-
- return GST_FLOW_OK;
-}
-
-GstFlowReturn QVideoSurfaceGstSink::render(GstBaseSink *base, GstBuffer *buffer)
-{
- VO_SINK(base);
- return sink->delegate->render(buffer);
-}
-#endif
-
-QT_END_NAMESPACE
diff --git a/src/gsttools/qvideosurfacegstsink_p.h b/src/gsttools/qvideosurfacegstsink_p.h
deleted file mode 100644
index dd758ff82..000000000
--- a/src/gsttools/qvideosurfacegstsink_p.h
+++ /dev/null
@@ -1,192 +0,0 @@
-/****************************************************************************
-**
-** 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 VIDEOSURFACEGSTSINK_P_H
-#define VIDEOSURFACEGSTSINK_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 <gst/gst.h>
-
-#if GST_CHECK_VERSION(1,0,0)
-
-#include "qgstvideorenderersink_p.h"
-
-QT_BEGIN_NAMESPACE
-typedef QGstVideoRendererSink QVideoSurfaceGstSink;
-QT_END_NAMESPACE
-
-#else
-
-#include <gst/video/gstvideosink.h>
-
-#include <QtCore/qlist.h>
-#include <QtCore/qmutex.h>
-#include <QtCore/qqueue.h>
-#include <QtCore/qpointer.h>
-#include <QtCore/qwaitcondition.h>
-#include <qvideosurfaceformat.h>
-#include <qvideoframe.h>
-#include <qabstractvideobuffer.h>
-
-#include "qgstbufferpoolinterface_p.h"
-
-QT_BEGIN_NAMESPACE
-class QAbstractVideoSurface;
-
-class QVideoSurfaceGstDelegate : public QObject
-{
- Q_OBJECT
-public:
- QVideoSurfaceGstDelegate(QAbstractVideoSurface *surface);
- ~QVideoSurfaceGstDelegate();
-
- QList<QVideoFrame::PixelFormat> supportedPixelFormats(
- QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle) const;
-
- QVideoSurfaceFormat surfaceFormat() const;
-
- bool start(const QVideoSurfaceFormat &format, int bytesPerLine);
- void stop();
-
- void unlock();
-
- bool isActive();
-
- QGstBufferPoolInterface *pool() { return m_pool; }
- QMutex *poolMutex() { return &m_poolMutex; }
- void clearPoolBuffers();
-
- void flush();
-
- GstFlowReturn render(GstBuffer *buffer);
-
-private slots:
- void queuedStart();
- void queuedStop();
- void queuedFlush();
- void queuedRender();
-
- void updateSupportedFormats();
-
-private:
- QPointer<QAbstractVideoSurface> m_surface;
- QList<QVideoFrame::PixelFormat> m_supportedPixelFormats;
- //pixel formats of buffers pool native type
- QList<QVideoFrame::PixelFormat> m_supportedPoolPixelFormats;
- QGstBufferPoolInterface *m_pool = nullptr;
- QList<QGstBufferPoolInterface *> m_pools;
- QMutex m_poolMutex;
- QMutex m_mutex;
- QWaitCondition m_setupCondition;
- QWaitCondition m_renderCondition;
- QVideoSurfaceFormat m_format;
- QVideoFrame m_frame;
- GstFlowReturn m_renderReturn = GST_FLOW_ERROR;
- int m_bytesPerLine = 0;
- bool m_started = false;
- bool m_startCanceled = false;
-};
-
-class QVideoSurfaceGstSink
-{
-public:
- GstVideoSink parent;
-
- static QVideoSurfaceGstSink *createSink(QAbstractVideoSurface *surface);
- static void setSurface(QAbstractVideoSurface *surface) { Q_UNUSED(surface); }
-
-private:
- static GType get_type();
- static void class_init(gpointer g_class, gpointer class_data);
- static void base_init(gpointer g_class);
- static void instance_init(GTypeInstance *instance, gpointer g_class);
-
- static void finalize(GObject *object);
-
- static void handleShowPrerollChange(GObject *o, GParamSpec *p, gpointer d);
-
- static GstStateChangeReturn change_state(GstElement *element, GstStateChange transition);
-
- static GstCaps *get_caps(GstBaseSink *sink);
- static gboolean set_caps(GstBaseSink *sink, GstCaps *caps);
-
- static GstFlowReturn buffer_alloc(
- GstBaseSink *sink, guint64 offset, guint size, GstCaps *caps, GstBuffer **buffer);
-
- static gboolean start(GstBaseSink *sink);
- static gboolean stop(GstBaseSink *sink);
-
- static gboolean unlock(GstBaseSink *sink);
-
-#if GST_CHECK_VERSION(0, 10, 25)
- static GstFlowReturn show_frame(GstVideoSink *sink, GstBuffer *buffer);
-#else
- static GstFlowReturn preroll(GstBaseSink *sink, GstBuffer *buffer);
- static GstFlowReturn render(GstBaseSink *sink, GstBuffer *buffer);
-#endif
-
-private:
- QVideoSurfaceGstDelegate *delegate = nullptr;
-
- GstCaps *lastRequestedCaps = nullptr;
- GstCaps *lastBufferCaps = nullptr;
- QVideoSurfaceFormat *lastSurfaceFormat = nullptr;
-};
-
-class QVideoSurfaceGstSinkClass
-{
-public:
- GstVideoSinkClass parent_class;
-};
-
-QT_END_NAMESPACE
-
-#endif
-
-#endif