diff --git a/.gitmodules b/.gitmodules index df27376892d3743af3a07e74814aee9f65c9247a..ecd295be6366e4a6c1b0f96ef72fe61a74fe5ab0 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,6 @@ [submodule "libs/OpenSSL/android_openssl"] path = libs/OpenSSL/android_openssl url = https://github.com/Auterion/android_openssl +[submodule "libs/gst-plugins-good"] + path = libs/gst-plugins-good + url = https://gitlab.freedesktop.org/andrew.voznytsa/gst-plugins-good.git diff --git a/.travis.yml b/.travis.yml index cfccd575a1868b3e814c630c5ff6f265b58151ba..705b8f7b711d5ddcebb4438d338ef3f328b9aa09 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,12 +16,12 @@ matrix: include: - name: "Linux Installer" os: linux - dist: xenial + dist: bionic env: SPEC=linux-g++-64 CONFIG=installer sudo: required - name: "Linux Debug" os: linux - dist: xenial + dist: bionic env: SPEC=linux-g++-64 CONFIG=debug services: xvfb sudo: required diff --git a/QGCInstaller.pri b/QGCInstaller.pri index 6b7b206dc524005e49e80b93020ab58e6059a1c6..5f25b20cafb3730e5beb388095f7d3f21484520f 100644 --- a/QGCInstaller.pri +++ b/QGCInstaller.pri @@ -45,7 +45,7 @@ installer { LinuxBuild { #-- TODO: This uses hardcoded paths. It should use $${DESTDIR} QMAKE_POST_LINK += && mkdir -p release/package - QMAKE_POST_LINK += && tar --warning=no-file-changed -cjf release/package/QGroundControl.tar.bz2 release --exclude='package' --transform 's/release/qgroundcontrol/' + QMAKE_POST_LINK += && tar -cj --exclude='package' -f release/package/QGroundControl.tar.bz2 release --transform 's/release/qgroundcontrol/' } AndroidBuild { QMAKE_POST_LINK += && mkdir -p $${DESTDIR}/package diff --git a/libs/gst-plugins-good b/libs/gst-plugins-good new file mode 160000 index 0000000000000000000000000000000000000000..9d782fad9dc0384ba86ecae64511c193f6149f93 --- /dev/null +++ b/libs/gst-plugins-good @@ -0,0 +1 @@ +Subproject commit 9d782fad9dc0384ba86ecae64511c193f6149f93 diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 4b6d3db54f3a9cb57e049368221a963b27891138..4bd40cfd4b09cbec6c2ac763d53ff505706e3e6b 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -1374,18 +1374,13 @@ INCLUDEPATH += \ src/VideoStreaming HEADERS += \ - src/VideoStreaming/VideoItem.h \ src/VideoStreaming/VideoReceiver.h \ src/VideoStreaming/VideoStreaming.h \ - src/VideoStreaming/VideoSurface.h \ - src/VideoStreaming/VideoSurface_p.h \ src/VideoStreaming/SubtitleWriter.h \ SOURCES += \ - src/VideoStreaming/VideoItem.cc \ src/VideoStreaming/VideoReceiver.cc \ src/VideoStreaming/VideoStreaming.cc \ - src/VideoStreaming/VideoSurface.cc \ src/VideoStreaming/SubtitleWriter.cc \ contains (CONFIG, DISABLE_VIDEOSTREAMING) { diff --git a/qmlglsink.pri b/qmlglsink.pri new file mode 100644 index 0000000000000000000000000000000000000000..e23fd4de29c1468e218537f7080fdf9c46ca8495 --- /dev/null +++ b/qmlglsink.pri @@ -0,0 +1,33 @@ +# FIXME: will be fixed after converting qmlglsink into .pro#static lib +QMAKE_CXXFLAGS_WARN_ON = + +LinuxBuild { + DEFINES += HAVE_QT_X11 HAVE_QT_EGLFS HAVE_QT_WAYLAND +} else:MacBuild { + DEFINES += HAVE_QT_MAC +} else:iOSBuild { + DEFINES += HAVE_QT_IOS +} else:WindowsBuild { + DEFINES += HAVE_QT_WIN32 + LIBS += opengl32.lib user32.lib +} else:AndroidBuild { + DEFINES += HAVE_QT_ANDROID +} + +SOURCES += \ + libs/gst-plugins-good/ext/qt/gstplugin.cc \ + libs/gst-plugins-good/ext/qt/gstqtglutility.cc \ + libs/gst-plugins-good/ext/qt/gstqsgtexture.cc \ + libs/gst-plugins-good/ext/qt/gstqtsink.cc \ + libs/gst-plugins-good/ext/qt/gstqtsrc.cc \ + libs/gst-plugins-good/ext/qt/qtwindow.cc \ + libs/gst-plugins-good/ext/qt/qtitem.cc + +HEADERS += \ + libs/gst-plugins-good/ext/qt/gstqsgtexture.h \ + libs/gst-plugins-good/ext/qt/gstqtgl.h \ + libs/gst-plugins-good/ext/qt/gstqtglutility.h \ + libs/gst-plugins-good/ext/qt/gstqtsink.h \ + libs/gst-plugins-good/ext/qt/gstqtsrc.h \ + libs/gst-plugins-good/ext/qt/qtwindow.h \ + libs/gst-plugins-good/ext/qt/qtitem.h diff --git a/src/FlightDisplay/FlightDisplayViewVideo.qml b/src/FlightDisplay/FlightDisplayViewVideo.qml index 1ef06d24033b6c5235def35a7b9d3b699f7c3b51..393886a9e22eb2ba9cc426d391ed1081355cbe38 100644 --- a/src/FlightDisplay/FlightDisplayViewVideo.qml +++ b/src/FlightDisplay/FlightDisplayViewVideo.qml @@ -79,8 +79,8 @@ Item { id: videoBackgroundComponent QGCVideoBackground { id: videoContent + objectName: "videoContent" receiver: _videoReceiver - display: _videoReceiver && _videoReceiver.videoSurface Connections { target: _videoReceiver @@ -125,13 +125,13 @@ Item { Loader { // GStreamer is causing crashes on Lenovo laptop OpenGL Intel drivers. In order to workaround this // we don't load a QGCVideoBackground object when video is disabled. This prevents any video rendering - // code from running. Setting QGCVideoBackground.receiver/display = null does not work to prevent any + // code from running. Setting QGCVideoBackground.receiver = null does not work to prevent any // video OpenGL from being generated. Hence the Loader to completely remove it. height: parent.getHeight() width: parent.getWidth() anchors.centerIn: parent visible: _videoReceiver && _videoReceiver.videoRunning - sourceComponent: videoDisabled ? null : videoBackgroundComponent + sourceComponent: videoBackgroundComponent property bool videoDisabled: QGroundControl.settingsManager.videoSettings.videoSource.rawValue === QGroundControl.settingsManager.videoSettings.disabledVideoSource } @@ -169,9 +169,9 @@ Item { } QGCVideoBackground { id: thermalVideo + objectName: "thermalVideo" anchors.fill: parent receiver: QGroundControl.videoManager.thermalVideoReceiver - display: QGroundControl.videoManager.thermalVideoReceiver ? QGroundControl.videoManager.thermalVideoReceiver.videoSurface : null opacity: _camera ? (_camera.thermalMode === QGCCameraControl.THERMAL_BLEND ? _camera.thermalOpacity / 100 : 1.0) : 0 } } diff --git a/src/FlightDisplay/VideoManager.cc b/src/FlightDisplay/VideoManager.cc index 2cd1fe1ffa20071573df54e9258afa4bb915cc5f..8be76469e64a93688bbaa0700043087765c570cd 100644 --- a/src/FlightDisplay/VideoManager.cc +++ b/src/FlightDisplay/VideoManager.cc @@ -18,8 +18,6 @@ #include #endif -#include - #include "ScreenToolsController.h" #include "VideoManager.h" #include "QGCToolbox.h" @@ -57,7 +55,6 @@ VideoManager::setToolbox(QGCToolbox *toolbox) QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership); qmlRegisterUncreatableType ("QGroundControl.VideoManager", 1, 0, "VideoManager", "Reference only"); qmlRegisterUncreatableType("QGroundControl", 1, 0, "VideoReceiver","Reference only"); - qmlRegisterUncreatableType ("QGroundControl", 1, 0, "VideoSurface", "Reference only"); _videoSettings = toolbox->settingsManager()->videoSettings(); QString videoSource = _videoSettings->videoSource()->rawValue().toString(); connect(_videoSettings->videoSource(), &Fact::rawValueChanged, this, &VideoManager::_videoSourceChanged); @@ -285,6 +282,113 @@ VideoManager::setfullScreen(bool f) emit fullScreenChanged(); } +//----------------------------------------------------------------------------- +#if defined(QGC_GST_STREAMING) +GstElement* +VideoManager::_makeVideoSink(const QString& widgetName) +{ + GstElement* glupload = nullptr; + GstElement* glcolorconvert = nullptr; + GstElement* qmlglsink = nullptr; + GstElement* bin = nullptr; + GstElement* sink = nullptr; + + do { + QQuickItem* root = qgcApp()->mainRootWindow(); + + if (root == nullptr) { + qCDebug(VideoManagerLog) << "VideoManager::_makeVideoSink() failed. No root window"; + break; + } + + QQuickItem* widget = root->findChild(widgetName); + + if (widget == nullptr) { + qCDebug(VideoManagerLog) << "VideoManager::_makeVideoSink() failed. Widget \'" << widgetName << "\' not found"; + break; + } + + if ((glupload = gst_element_factory_make("glupload", nullptr)) == nullptr) { + qCritical() << "VideoManager::_makeVideoSink() failed. Error with gst_element_factory_make('glupload')"; + break; + } + + if ((glcolorconvert = gst_element_factory_make("glcolorconvert", nullptr)) == nullptr) { + qCritical() << "VideoManager::_makeVideoSink() failed. Error with gst_element_factory_make('glcolorconvert')"; + break; + } + + if ((qmlglsink = gst_element_factory_make("qmlglsink", nullptr)) == nullptr) { + qCritical() << "VideoManager::_makeVideoSink() failed. Error with gst_element_factory_make('qmlglsink')"; + break; + } + + g_object_set(qmlglsink, "widget", widget, NULL); + + if ((bin = gst_bin_new("videosink")) == nullptr) { + qCritical() << "VideoManager::_makeVideoSink() failed. Error with gst_bin_new('videosink')"; + break; + } + + GstPad* pad; + + if ((pad = gst_element_get_static_pad(glupload, "sink")) == nullptr) { + qCritical() << "VideoManager::_makeVideoSink() failed. Error with gst_element_get_static_pad(glupload, 'sink')"; + break; + } + + gst_bin_add_many(GST_BIN(bin), glupload, glcolorconvert, qmlglsink, nullptr); + gboolean ret = gst_element_link_many(glupload, glcolorconvert, qmlglsink, nullptr); + + qmlglsink = glcolorconvert = glupload = nullptr; + + if (!ret) { + qCritical() << "VideoManager::_makeVideoSink() failed. Error with gst_element_link_many()"; + break; + } + + gst_element_add_pad(bin, gst_ghost_pad_new("sink", pad)); + gst_object_unref(pad); + pad = nullptr; + + sink = bin; + bin = nullptr; + } while(0); + + if (bin != nullptr) { + gst_object_unref(bin); + bin = nullptr; + } + + if (qmlglsink != nullptr) { + gst_object_unref(qmlglsink); + qmlglsink = nullptr; + } + + if (glcolorconvert != nullptr) { + gst_object_unref(glcolorconvert); + glcolorconvert = nullptr; + } + + if (glupload != nullptr) { + gst_object_unref(glupload); + glupload = nullptr; + } + + return sink; +} +#endif + +//----------------------------------------------------------------------------- +void +VideoManager::_initVideo() +{ +#if defined(QGC_GST_STREAMING) + _videoReceiver->setVideoSink(_makeVideoSink("videoContent")); + _thermalVideoReceiver->setVideoSink(_makeVideoSink("thermalVideo")); +#endif +} + //----------------------------------------------------------------------------- void VideoManager::_updateSettings() diff --git a/src/FlightDisplay/VideoManager.h b/src/FlightDisplay/VideoManager.h index 3410e369bceffe066ed629382fc021d832b8a494..3f4066ac3d3f9852d57e9e57a6d03606068f8f5f 100644 --- a/src/FlightDisplay/VideoManager.h +++ b/src/FlightDisplay/VideoManager.h @@ -103,6 +103,11 @@ protected slots: void _connectionLostChanged (bool connectionLost); protected: + friend class FinishVideoInitialization; +#if defined(QGC_GST_STREAMING) + GstElement* _makeVideoSink (const QString& widgetName); +#endif + void _initVideo (); void _updateSettings (); protected: diff --git a/src/FlightMap/QGCVideoBackground.qml b/src/FlightMap/QGCVideoBackground.qml index 6f461ff06945ea6d57f8eda81237c49f3e9965b1..f2de43c22f5950d62647b1a6d9973c40c7de95a7 100644 --- a/src/FlightMap/QGCVideoBackground.qml +++ b/src/FlightMap/QGCVideoBackground.qml @@ -14,13 +14,11 @@ * @author Gus Grubba */ -import QtQuick 2.11 -import QtQuick.Controls 2.4 -import QGroundControl.QgcQtGStreamer 1.0 +import QtQuick 2.11 +import QtQuick.Controls 2.4 +import org.freedesktop.gstreamer.GLVideoItem 1.0 -VideoItem { +GstGLVideoItem { id: videoBackground - property var display property var receiver - surface: display } diff --git a/src/QGCApplication.cc b/src/QGCApplication.cc index 028aa1cb0baa28318aba210709099a46383b1afd..a456f5cc761c5fa15ad94ec17af78f2e0cba9d92 100644 --- a/src/QGCApplication.cc +++ b/src/QGCApplication.cc @@ -26,6 +26,7 @@ #include #include #include +#include #ifdef QGC_ENABLE_BLUETOOTH #include @@ -68,7 +69,6 @@ #include "CoordinateVector.h" #include "PlanMasterController.h" #include "VideoManager.h" -#include "VideoSurface.h" #include "VideoReceiver.h" #include "LogDownloadController.h" #if defined(QGC_ENABLE_MAVLINK_INSPECTOR) @@ -128,6 +128,22 @@ #include "QGCMapEngine.h" +class FinishVideoInitialization : public QRunnable +{ +public: + FinishVideoInitialization(VideoManager* manager) + : _manager(manager) + {} + + void run () { + _manager->_initVideo(); + } + +private: + VideoManager* _manager; +}; + + QGCApplication* QGCApplication::_app = nullptr; const char* QGCApplication::_deleteAllSettingsKey = "DeleteAllSettingsNextBoot"; @@ -560,6 +576,13 @@ bool QGCApplication::_initForNormalAppBoot() _qmlAppEngine = toolbox()->corePlugin()->createRootWindow(this); + QQuickWindow* rootWindow = (QQuickWindow*)qgcApp()->mainRootWindow(); + + if (rootWindow) { + rootWindow->scheduleRenderJob (new FinishVideoInitialization (toolbox()->videoManager()), + QQuickWindow::BeforeSynchronizingStage); + } + // Safe to show popup error messages now that main window is created UASMessageHandler* msgHandler = qgcApp()->toolbox()->uasMessageHandler(); if (msgHandler) { diff --git a/src/VideoStreaming/GLVideoItemStub.cc b/src/VideoStreaming/GLVideoItemStub.cc new file mode 100644 index 0000000000000000000000000000000000000000..22b8011f3624932f0e50340510dbf1f3949df7c2 --- /dev/null +++ b/src/VideoStreaming/GLVideoItemStub.cc @@ -0,0 +1,9 @@ +#include "GLVideoItemStub.h" + +GLVideoItemStub::GLVideoItemStub() +{ +} + +GLVideoItemStub::~GLVideoItemStub() +{ +} diff --git a/src/VideoStreaming/GLVideoItemStub.h b/src/VideoStreaming/GLVideoItemStub.h new file mode 100644 index 0000000000000000000000000000000000000000..9d4650e3d2b2db6048fb472a316153feb4bca31b --- /dev/null +++ b/src/VideoStreaming/GLVideoItemStub.h @@ -0,0 +1,17 @@ +#pragma once + +#include + +class GLVideoItemStub : public QQuickItem +{ + Q_OBJECT + +public: + GLVideoItemStub(); + ~GLVideoItemStub(); + +protected: + +private: + +}; diff --git a/src/VideoStreaming/VideoItem.cc b/src/VideoStreaming/VideoItem.cc deleted file mode 100644 index e18c6633cc8ab4ffd8cd22959d3b9ec4e51d6d56..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/VideoItem.cc +++ /dev/null @@ -1,135 +0,0 @@ -/**************************************************************************** - * - * (c) 2009-2020 QGROUNDCONTROL PROJECT - * - * QGroundControl is licensed according to the terms in the file - * COPYING.md in the root of the source code directory. - * - ****************************************************************************/ - - -/** - * @file - * @brief QGC Video Item - * @author Gus Grubba - */ - -#include -#include -#include - -#include "VideoItem.h" -#if defined(QGC_GST_STREAMING) -#include "VideoSurface_p.h" -#endif - -#if defined(QGC_GST_STREAMING) -struct VideoItem::Private -{ - QPointer surface; - bool surfaceDirty; - QRectF targetArea; -}; -#endif - -VideoItem::VideoItem(QQuickItem *parent) - : QQuickItem(parent) -#if defined(QGC_GST_STREAMING) - , _data(new Private) -#endif -{ -#if defined(QGC_GST_STREAMING) - _data->surfaceDirty = true; - setFlag(QQuickItem::ItemHasContents, true); -#endif -} - -VideoItem::~VideoItem() -{ -#if defined(QGC_GST_STREAMING) - setSurface(0); - delete _data; -#endif -} - -VideoSurface *VideoItem::surface() const -{ -#if defined(QGC_GST_STREAMING) - return _data->surface.data(); -#else - return nullptr; -#endif -} - -void VideoItem::setSurface(VideoSurface *surface) -{ -#if defined(QGC_GST_STREAMING) - if (_data->surface) { - _data->surface.data()->_data->items.remove(this); - } - _data->surface = surface; - _data->surfaceDirty = true; - if (_data->surface) { - _data->surface.data()->_data->items.insert(this); - } -#else - Q_UNUSED(surface) -#endif -} - -#if defined(QGC_GST_STREAMING) -QSGGeometry* VideoItem::_createDefaultGeometry(QRectF& rectBound) -{ - QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 4); - geometry->vertexDataAsPoint2D()[0].set(rectBound.x(), rectBound.y()); - geometry->vertexDataAsPoint2D()[1].set(rectBound.x(), rectBound.height()); - geometry->vertexDataAsPoint2D()[2].set(rectBound.width(), rectBound.y()); - geometry->vertexDataAsPoint2D()[3].set(rectBound.width(), rectBound.height()); - - return geometry; -} - -QSGNode* VideoItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData*) -{ - QRectF r = boundingRect(); - QSGNode* newNode = nullptr; - - if (_data->surfaceDirty) { - delete oldNode; - oldNode = nullptr; - _data->surfaceDirty = false; - } - - if (!_data->surface || _data->surface.data()->_data->videoSink == nullptr) { - if (!oldNode) { - QSGFlatColorMaterial *material = new QSGFlatColorMaterial; - material->setColor(Qt::black); - QSGGeometryNode *node = new QSGGeometryNode; - node->setMaterial(material); - node->setFlag(QSGNode::OwnsMaterial); - node->setFlag(QSGNode::OwnsGeometry); - newNode = node; - _data->targetArea = QRectF(); //force geometry to be set - } else { - newNode = oldNode; - } - if (r != _data->targetArea) { - QSGGeometryNode *node = static_cast(newNode); - node->setGeometry(_createDefaultGeometry(r)); - _data->targetArea = r; - } - } else { - g_signal_emit_by_name(_data->surface.data()->_data->videoSink, "update-node", (void*)oldNode, r.x(), r.y(), r.width(), r.height(), (void**)&newNode); - } - - // Sometimes we can still end up here with no geometry when gstreamer fails to create it for whatever reason. If that happens it can - // cause crashes. - QSGGeometryNode *node = static_cast(newNode); - if (node->geometry() == nullptr) { - qDebug() << "Creating default geom"; - node->setGeometry(_createDefaultGeometry(r)); - } - - return newNode; -} -#endif diff --git a/src/VideoStreaming/VideoItem.h b/src/VideoStreaming/VideoItem.h deleted file mode 100644 index b4d8261a74cd6189cc7ba13a845a2719ff1430f8..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/VideoItem.h +++ /dev/null @@ -1,51 +0,0 @@ -/**************************************************************************** - * - * (c) 2009-2020 QGROUNDCONTROL PROJECT - * - * QGroundControl is licensed according to the terms in the file - * COPYING.md in the root of the source code directory. - * - ****************************************************************************/ - - -/** - * @file - * @brief QGC Video Item - * @author Gus Grubba - */ - -#pragma once - -#include -#include "VideoSurface.h" - -class QSGGeometry; - -class VideoItem : public QQuickItem -{ - Q_OBJECT - Q_DISABLE_COPY(VideoItem) - Q_PROPERTY(VideoSurface* surface READ surface WRITE setSurface) - -public: - explicit VideoItem(QQuickItem *parent = 0); - virtual ~VideoItem(); - - VideoSurface *surface() const; - void setSurface(VideoSurface *surface); - -protected: -#if defined(QGC_GST_STREAMING) - /*! Reimplemented from QQuickItem. */ - virtual QSGNode* updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData); -#endif - -private: -#if defined(QGC_GST_STREAMING) - QSGGeometry* _createDefaultGeometry(QRectF& rectBound); - - struct Private; - Private* const _data; -#endif -}; - diff --git a/src/VideoStreaming/VideoReceiver.cc b/src/VideoStreaming/VideoReceiver.cc index e348bf67474b1bf28c8e5bfb95d9accd40ff1102..aecd1fb914b9235a29fcbbd9af12d9f15987ad8b 100644 --- a/src/VideoStreaming/VideoReceiver.cc +++ b/src/VideoStreaming/VideoReceiver.cc @@ -64,24 +64,23 @@ VideoReceiver::VideoReceiver(QObject* parent) , _pipeline(nullptr) , _pipelineStopRec(nullptr) , _videoSink(nullptr) + , _lastFrameId(G_MAXUINT64) + , _lastFrameTime(0) , _restart_time_ms(1389) , _socket(nullptr) , _serverPresent(false) , _tcpTestInterval_ms(5000) , _udpReconnect_us(5000000) #endif - , _videoSurface(nullptr) , _videoRunning(false) , _showFullScreen(false) , _videoSettings(nullptr) , _hwDecoderName(nullptr) , _swDecoderName("avdec_h264") { - _videoSurface = new VideoSurface; _videoSettings = qgcApp()->toolbox()->settingsManager()->videoSettings(); #if defined(QGC_GST_STREAMING) setVideoDecoder(H264_SW); - _setVideoSink(_videoSurface->videoSink()); _restart_timer.setSingleShot(true); connect(&_restart_timer, &QTimer::timeout, this, &VideoReceiver::_restart_timeout); _tcp_timer.setSingleShot(true); @@ -98,32 +97,9 @@ VideoReceiver::~VideoReceiver() { #if defined(QGC_GST_STREAMING) stop(); - if(_socket) { - delete _socket; - _socket = nullptr; - } - if (_videoSink) { - gst_object_unref(_videoSink); - } + setVideoSink(nullptr); #endif - if(_videoSurface) - delete _videoSurface; -} - -#if defined(QGC_GST_STREAMING) -void -VideoReceiver::_setVideoSink(GstElement* sink) -{ - if (_videoSink) { - gst_object_unref(_videoSink); - _videoSink = nullptr; - } - if (sink) { - _videoSink = sink; - gst_object_ref_sink(_videoSink); - } } -#endif //----------------------------------------------------------------------------- void @@ -287,6 +263,9 @@ VideoReceiver::start() return; } + _lastFrameId = G_MAXUINT64; + _lastFrameTime = 0; + bool running = false; bool pipelineUp = false; @@ -458,11 +437,21 @@ VideoReceiver::start() // If we failed before adding items to the pipeline, then clean up if (!pipelineUp) { + if (queue1 != nullptr) { + gst_object_unref(queue1); + queue1 = nullptr; + } + if (decoder != nullptr) { gst_object_unref(decoder); decoder = nullptr; } + if (queue != nullptr) { + gst_object_unref(queue); + queue = nullptr; + } + if (parser != nullptr) { gst_object_unref(parser); parser = nullptr; @@ -480,13 +469,9 @@ VideoReceiver::start() if (_tee != nullptr) { gst_object_unref(_tee); - dataSource = nullptr; + _tee = nullptr; } - if (queue != nullptr) { - gst_object_unref(queue); - dataSource = nullptr; - } } _running = false; @@ -552,7 +537,6 @@ VideoReceiver::_shutdownPipeline() { bus = nullptr; } gst_element_set_state(_pipeline, GST_STATE_NULL); - gst_bin_remove(GST_BIN(_pipeline), _videoSink); gst_object_unref(_pipeline); _pipeline = nullptr; delete _sink; @@ -712,6 +696,38 @@ VideoReceiver::setVideoDecoder(VideoEncoding encoding) } } +//----------------------------------------------------------------------------- +#if defined(QGC_GST_STREAMING) +void +VideoReceiver::setVideoSink(GstElement* videoSink) +{ + if(_pipeline != nullptr) { + qCDebug(VideoReceiverLog) << "Video receiver pipeline is active, video sink change is not possible"; + return; + } + + if (_videoSink != nullptr) { + gst_object_unref(_videoSink); + _videoSink = nullptr; + } + + if (videoSink != nullptr) { + _videoSink = videoSink; + gst_object_ref(_videoSink); + + GstPad* pad = gst_element_get_static_pad(_videoSink, "sink"); + + if (pad != nullptr) { + gst_pad_add_probe(pad, (GstPadProbeType)(GST_PAD_PROBE_TYPE_BUFFER), _videoSinkProbe, this, nullptr); + gst_object_unref(pad); + pad = nullptr; + } else { + qCDebug(VideoReceiverLog) << "Unable to find sink pad of video sink"; + } + } +} +#endif + //----------------------------------------------------------------------------- // When we finish our pipeline will look like this: // @@ -923,6 +939,30 @@ VideoReceiver::_unlinkCallBack(GstPad* pad, GstPadProbeInfo* info, gpointer user } #endif +//----------------------------------------------------------------------------- +#if defined(QGC_GST_STREAMING) +GstPadProbeReturn +VideoReceiver::_videoSinkProbe(GstPad* pad, GstPadProbeInfo* info, gpointer user_data) +{ + Q_UNUSED(pad); + if(info != nullptr && user_data != nullptr) { + VideoReceiver* pThis = static_cast(user_data); + pThis->_noteVideoSinkFrame(); + } + + return GST_PAD_PROBE_OK; +} +#endif + +//----------------------------------------------------------------------------- +#if defined(QGC_GST_STREAMING) +void +VideoReceiver::_noteVideoSinkFrame() +{ + _lastFrameTime = QDateTime::currentSecsSinceEpoch(); +} +#endif + //----------------------------------------------------------------------------- #if defined(QGC_GST_STREAMING) GstPadProbeReturn @@ -971,41 +1011,39 @@ void VideoReceiver::_updateTimer() { #if defined(QGC_GST_STREAMING) - if(_videoSurface) { - if(_stopping || _starting) { - return; - } - if(_streaming) { - if(!_videoRunning) { - _videoSurface->setLastFrame(0); - _videoRunning = true; - emit videoRunningChanged(); - } - } else { - if(_videoRunning) { - _videoRunning = false; - emit videoRunningChanged(); - } + if(_stopping || _starting) { + return; + } + + if(_streaming) { + if(!_videoRunning) { + _videoRunning = true; + emit videoRunningChanged(); } + } else { if(_videoRunning) { - uint32_t timeout = 1; - if(qgcApp()->toolbox() && qgcApp()->toolbox()->settingsManager()) { - timeout = _videoSettings->rtspTimeout()->rawValue().toUInt(); - } - time_t elapsed = 0; - time_t lastFrame = _videoSurface->lastFrame(); - if(lastFrame != 0) { - elapsed = time(nullptr) - _videoSurface->lastFrame(); - } - if(elapsed > static_cast(timeout) && _videoSurface) { - stop(); - // We want to start it back again with _updateTimer - _stop = false; - } - } else { - if(!_stop && _running && !_uri.isEmpty() && _videoSettings->streamEnabled()->rawValue().toBool()) { - start(); - } + _videoRunning = false; + emit videoRunningChanged(); + } + } + + if(_videoRunning) { + uint32_t timeout = 1; + if(qgcApp()->toolbox() && qgcApp()->toolbox()->settingsManager()) { + timeout = _videoSettings->rtspTimeout()->rawValue().toUInt(); + } + + const qint64 now = QDateTime::currentSecsSinceEpoch(); + + if(now - _lastFrameTime > timeout) { + stop(); + // We want to start it back again with _updateTimer + _stop = false; + } + } else { + // FIXME: AV: if pipeline is _running but not _streaming for some time then we need to restart + if(!_stop && !_running && !_uri.isEmpty() && _videoSettings->streamEnabled()->rawValue().toBool()) { + start(); } } #endif diff --git a/src/VideoStreaming/VideoReceiver.h b/src/VideoStreaming/VideoReceiver.h index 21f78468862459c2bea6306fe06e36c2a9c66abb..f6acdbc8af68d83f931106b5091bb2ba4a0178a6 100644 --- a/src/VideoStreaming/VideoReceiver.h +++ b/src/VideoStreaming/VideoReceiver.h @@ -20,8 +20,6 @@ #include #include -#include "VideoSurface.h" - #if defined(QGC_GST_STREAMING) #include #endif @@ -44,7 +42,6 @@ public: #if defined(QGC_GST_STREAMING) Q_PROPERTY(bool recording READ recording NOTIFY recordingChanged) #endif - Q_PROPERTY(VideoSurface* videoSurface READ videoSurface CONSTANT) Q_PROPERTY(bool videoRunning READ videoRunning NOTIFY videoRunningChanged) Q_PROPERTY(QString imageFile READ imageFile NOTIFY imageFileChanged) Q_PROPERTY(QString videoFile READ videoFile NOTIFY videoFileChanged) @@ -57,7 +54,6 @@ public: virtual bool recording () { return _recording; } #endif - virtual VideoSurface* videoSurface () { return _videoSurface; } virtual bool videoRunning () { return _videoRunning; } virtual QString imageFile () { return _imageFile; } virtual QString videoFile () { return _videoFile; } @@ -68,6 +64,9 @@ public: virtual void setShowFullScreen (bool show) { _showFullScreen = show; emit showFullScreenChanged(); } void setVideoDecoder (VideoEncoding encoding); +#if defined(QGC_GST_STREAMING) + void setVideoSink (GstElement* videoSink); +#endif signals: void videoRunningChanged (); @@ -123,19 +122,23 @@ protected: Sink* _sink; GstElement* _tee; + void _noteVideoSinkFrame (); + static gboolean _onBusMessage (GstBus* bus, GstMessage* message, gpointer user_data); static GstPadProbeReturn _unlinkCallBack (GstPad* pad, GstPadProbeInfo* info, gpointer user_data); + static GstPadProbeReturn _videoSinkProbe (GstPad* pad, GstPadProbeInfo* info, gpointer user_data); static GstPadProbeReturn _keyframeWatch (GstPad* pad, GstPadProbeInfo* info, gpointer user_data); virtual void _detachRecordingBranch (GstPadProbeInfo* info); virtual void _shutdownRecordingBranch(); virtual void _shutdownPipeline (); virtual void _cleanupOldVideos (); - virtual void _setVideoSink (GstElement* sink); GstElement* _pipeline; GstElement* _pipelineStopRec; GstElement* _videoSink; + guint64 _lastFrameId; + qint64 _lastFrameTime; //-- Wait for Video Server to show up before starting QTimer _frameTimer; @@ -153,7 +156,6 @@ protected: QString _uri; QString _imageFile; QString _videoFile; - VideoSurface* _videoSurface; bool _videoRunning; bool _showFullScreen; VideoSettings* _videoSettings; diff --git a/src/VideoStreaming/VideoStreaming.cc b/src/VideoStreaming/VideoStreaming.cc index 4f53b100718c489c4b422b6f8fd182458985b3c4..e72ef0acef200da584a62e1f17d550456170a3c4 100644 --- a/src/VideoStreaming/VideoStreaming.cc +++ b/src/VideoStreaming/VideoStreaming.cc @@ -25,16 +25,14 @@ #if defined(__ios__) #include "gst_ios_init.h" #endif +#else +#include "GLVideoItemStub.h" #endif #include "VideoStreaming.h" -#include "VideoItem.h" -#include "VideoSurface.h" #if defined(QGC_GST_STREAMING) G_BEGIN_DECLS - // Our own plugin - GST_PLUGIN_STATIC_DECLARE(QGC_VIDEOSINK_PLUGIN); // The static plugins we use #if defined(__mobile__) GST_PLUGIN_STATIC_DECLARE(coreelements); @@ -47,10 +45,12 @@ GST_PLUGIN_STATIC_DECLARE(rtpmanager); GST_PLUGIN_STATIC_DECLARE(isomp4); GST_PLUGIN_STATIC_DECLARE(matroska); + GST_PLUGIN_STATIC_DECLARE(opengl); #endif #if defined(__android__) GST_PLUGIN_STATIC_DECLARE(androidmedia); #endif + GST_PLUGIN_STATIC_DECLARE(qmlgl); G_END_DECLS #endif @@ -148,8 +148,6 @@ void initializeVideoStreaming(int &argc, char* argv[], char* logpath, char* debu g_error_free(error); } #endif - // Our own plugin - GST_PLUGIN_STATIC_REGISTER(QGC_VIDEOSINK_PLUGIN); // The static plugins we use #if defined(__android__) GST_PLUGIN_STATIC_REGISTER(coreelements); @@ -164,12 +162,33 @@ void initializeVideoStreaming(int &argc, char* argv[], char* logpath, char* debu GST_PLUGIN_STATIC_REGISTER(matroska); GST_PLUGIN_STATIC_REGISTER(androidmedia); #endif + +#if defined(__mobile__) + GST_PLUGIN_STATIC_REGISTER(opengl); +#endif + + /* the plugin must be loaded before loading the qml file to register the + * GstGLVideoItem qml item + * FIXME Add a QQmlExtensionPlugin into qmlglsink to register GstGLVideoItem + * with the QML engine, then remove this */ + GstElement *sink = gst_element_factory_make("qmlglsink", nullptr); + + if (sink == nullptr) { + GST_PLUGIN_STATIC_REGISTER(qmlgl); + sink = gst_element_factory_make("qmlglsink", nullptr); + } + + if (sink != nullptr) { + gst_object_unref(sink); + sink = nullptr; + } else { + qCritical() << "unable to find qmlglsink - you need to build it yourself and add to GST_PLUGIN_PATH"; + } #else - Q_UNUSED(argc); - Q_UNUSED(argv); - Q_UNUSED(logpath); - Q_UNUSED(debuglevel); + qmlRegisterType ("org.freedesktop.gstreamer.GLVideoItem", 1, 0, "GstGLVideoItem"); + Q_UNUSED(argc) + Q_UNUSED(argv) + Q_UNUSED(logpath) + Q_UNUSED(debuglevel) #endif - qmlRegisterType ("QGroundControl.QgcQtGStreamer", 1, 0, "VideoItem"); - qmlRegisterUncreatableType("QGroundControl.QgcQtGStreamer", 1, 0, "VideoSurface", QStringLiteral("VideoSurface from QML is not supported")); } diff --git a/src/VideoStreaming/VideoStreaming.h b/src/VideoStreaming/VideoStreaming.h index 9ac6e1d6296b44dd6388248c2609e6a056dba500..58f27cf2f727da6d4d134716e9a9d6bee678cc54 100644 --- a/src/VideoStreaming/VideoStreaming.h +++ b/src/VideoStreaming/VideoStreaming.h @@ -17,5 +17,3 @@ #pragma once extern void initializeVideoStreaming (int &argc, char *argv[], char* filename, char* debuglevel); - - diff --git a/src/VideoStreaming/VideoStreaming.pri b/src/VideoStreaming/VideoStreaming.pri index 8e9e2cdc9c3a66f48627f09a1162b2d63bd367dc..17d7d1e35b9c0687753c3f07b996625359946901 100644 --- a/src/VideoStreaming/VideoStreaming.pri +++ b/src/VideoStreaming/VideoStreaming.pri @@ -12,9 +12,10 @@ # LinuxBuild { + QT += x11extras waylandclient CONFIG += link_pkgconfig packagesExist(gstreamer-1.0) { - PKGCONFIG += gstreamer-1.0 gstreamer-video-1.0 + PKGCONFIG += gstreamer-1.0 gstreamer-video-1.0 gstreamer-gl-1.0 CONFIG += VideoEnabled } } else:MacBuild { @@ -39,10 +40,11 @@ LinuxBuild { exists($$GST_ROOT) { CONFIG += VideoEnabled - LIBS += -L$$GST_ROOT/lib -lgstreamer-1.0 -lgstvideo-1.0 -lgstbase-1.0 + LIBS += -L$$GST_ROOT/lib -lgstreamer-1.0 -lgstgl-1.0 -lgstvideo-1.0 -lgstbase-1.0 LIBS += -lglib-2.0 -lintl -lgobject-2.0 INCLUDEPATH += \ + $$GST_ROOT/include \ $$GST_ROOT/include/gstreamer-1.0 \ $$GST_ROOT/include/glib-2.0 \ $$GST_ROOT/lib/gstreamer-1.0/include \ @@ -86,10 +88,12 @@ LinuxBuild { -lgstrtpmanager \ -lgstisomp4 \ -lgstmatroska \ - -lgstandroidmedia + -lgstandroidmedia \ + -lgstopengl # Rest of GStreamer dependencies LIBS += -L$$GST_ROOT/lib \ + -lgraphene-1.0 -ljpeg -lpng16 \ -lgstfft-1.0 -lm \ -lgstnet-1.0 -lgio-2.0 \ -lgstphotography-1.0 -lgstgl-1.0 -lEGL \ @@ -113,68 +117,16 @@ VideoEnabled { message("Including support for video streaming") DEFINES += \ - QGC_GST_STREAMING \ - GST_PLUGIN_BUILD_STATIC \ - QTGLVIDEOSINK_NAME=qt5glvideosink \ - QGC_VIDEOSINK_PLUGIN=qt5videosink - - INCLUDEPATH += \ - $$PWD/gstqtvideosink \ - $$PWD/gstqtvideosink/delegates \ - $$PWD/gstqtvideosink/painters \ - $$PWD/gstqtvideosink/utils \ - - #-- QtGstreamer (gutted to our needs) - - HEADERS += \ - $$PWD/gstqtvideosink/delegates/basedelegate.h \ - $$PWD/gstqtvideosink/delegates/qtquick2videosinkdelegate.h \ - $$PWD/gstqtvideosink/delegates/qtvideosinkdelegate.h \ - $$PWD/gstqtvideosink/delegates/qwidgetvideosinkdelegate.h \ - $$PWD/gstqtvideosink/gstqtglvideosink.h \ - $$PWD/gstqtvideosink/gstqtglvideosinkbase.h \ - $$PWD/gstqtvideosink/gstqtquick2videosink.h \ - $$PWD/gstqtvideosink/gstqtvideosink.h \ - $$PWD/gstqtvideosink/gstqtvideosinkbase.h \ - $$PWD/gstqtvideosink/gstqtvideosinkmarshal.h \ - $$PWD/gstqtvideosink/gstqtvideosinkplugin.h \ - $$PWD/gstqtvideosink/gstqwidgetvideosink.h \ - $$PWD/gstqtvideosink/painters/abstractsurfacepainter.h \ - $$PWD/gstqtvideosink/painters/genericsurfacepainter.h \ - $$PWD/gstqtvideosink/painters/openglsurfacepainter.h \ - $$PWD/gstqtvideosink/painters/videomaterial.h \ - $$PWD/gstqtvideosink/painters/videonode.h \ - $$PWD/gstqtvideosink/utils/bufferformat.h \ - $$PWD/gstqtvideosink/utils/utils.h \ - $$PWD/gstqtvideosink/utils/glutils.h \ - - SOURCES += \ - $$PWD/gstqtvideosink/delegates/basedelegate.cpp \ - $$PWD/gstqtvideosink/delegates/qtquick2videosinkdelegate.cpp \ - $$PWD/gstqtvideosink/delegates/qtvideosinkdelegate.cpp \ - $$PWD/gstqtvideosink/delegates/qwidgetvideosinkdelegate.cpp \ - $$PWD/gstqtvideosink/gstqtglvideosink.cpp \ - $$PWD/gstqtvideosink/gstqtglvideosinkbase.cpp \ - $$PWD/gstqtvideosink/gstqtvideosinkmarshal.c \ - $$PWD/gstqtvideosink/gstqtquick2videosink.cpp \ - $$PWD/gstqtvideosink/gstqtvideosink.cpp \ - $$PWD/gstqtvideosink/gstqtvideosinkbase.cpp \ - $$PWD/gstqtvideosink/gstqtvideosinkplugin.cpp \ - $$PWD/gstqtvideosink/gstqwidgetvideosink.cpp \ - $$PWD/gstqtvideosink/painters/genericsurfacepainter.cpp \ - $$PWD/gstqtvideosink/painters/openglsurfacepainter.cpp \ - $$PWD/gstqtvideosink/painters/videomaterial.cpp \ - $$PWD/gstqtvideosink/painters/videonode.cpp \ - $$PWD/gstqtvideosink/utils/bufferformat.cpp \ - $$PWD/gstqtvideosink/utils/utils.cpp \ + QGC_GST_STREAMING iOSBuild { OBJECTIVE_SOURCES += \ - $$PWD/ios/gst_ios_init.m + $$PWD/iOS/gst_ios_init.m INCLUDEPATH += \ - $$PWD/ios + $$PWD/iOS } + include($$PWD/../../qmlglsink.pri) } else { LinuxBuild|MacBuild|iOSBuild|WindowsBuild|AndroidBuild { message("Skipping support for video streaming (GStreamer libraries not installed)") @@ -182,5 +134,10 @@ VideoEnabled { } else { message("Skipping support for video streaming (Unsupported platform)") } -} + SOURCES += \ + $$PWD/GLVideoItemStub.cc + + HEADERS += \ + $$PWD/GLVideoItemStub.h +} diff --git a/src/VideoStreaming/VideoSurface.cc b/src/VideoStreaming/VideoSurface.cc deleted file mode 100644 index bc92112a7477b4ecfeb54d83cbe6797c20894bea..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/VideoSurface.cc +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** - * - * (c) 2009-2020 QGROUNDCONTROL PROJECT - * - * QGroundControl is licensed according to the terms in the file - * COPYING.md in the root of the source code directory. - * - ****************************************************************************/ - - -/** - * @file - * @brief QGC Video Surface - * @author Gus Grubba - */ - -#if defined(QGC_GST_STREAMING) -#include "VideoSurface_p.h" -#endif -#include "VideoSurface.h" - -#include -#include - -VideoSurface::VideoSurface(QObject *parent) - : QObject(parent) -#if defined(QGC_GST_STREAMING) - , _data(new VideoSurfacePrivate) - , _lastFrame(0) - , _refed(false) -#endif -{ -} - -VideoSurface::~VideoSurface() -{ -#if defined(QGC_GST_STREAMING) - if (!_refed && _data->videoSink != nullptr) { - gst_element_set_state(_data->videoSink, GST_STATE_NULL); - } - delete _data; -#endif -} - -#if defined(QGC_GST_STREAMING) -GstElement* VideoSurface::videoSink() -{ - if (_data->videoSink == nullptr) { - if ((_data->videoSink = gst_element_factory_make("qtquick2videosink", nullptr)) == nullptr) { - qCritical("Failed to create qtquick2videosink. Make sure it is installed correctly"); - return nullptr; - } - g_object_set(G_OBJECT(_data->videoSink), "sync", gboolean(false), nullptr); - g_signal_connect(_data->videoSink, "update", G_CALLBACK(onUpdateThunk), (void* )this); - _refed = true; - } - return _data->videoSink; -} - -void VideoSurface::onUpdate() -{ - _lastFrame = time(nullptr); - Q_FOREACH(QQuickItem *item, _data->items) { - item->update(); - } -} - -void VideoSurface::onUpdateThunk(GstElement* sink, gpointer data) -{ - Q_UNUSED(sink); - VideoSurface* pThis = (VideoSurface* )data; - pThis->onUpdate(); -} -#endif - diff --git a/src/VideoStreaming/VideoSurface.h b/src/VideoStreaming/VideoSurface.h deleted file mode 100644 index a65357af7e7f57c33ba060f483835b02d41c161d..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/VideoSurface.h +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** - * - * (c) 2009-2020 QGROUNDCONTROL PROJECT - * - * QGroundControl is licensed according to the terms in the file - * COPYING.md in the root of the source code directory. - * - ****************************************************************************/ - - -/** - * @file - * @brief QGC Video Surface - * @author Gus Grubba - */ - -#pragma once - -#include - -#if defined(QGC_GST_STREAMING) -#include -#endif - -#if defined(QGC_GST_STREAMING) -class VideoSurfacePrivate; -#endif - -class VideoSurface : public QObject -{ - Q_OBJECT - Q_DISABLE_COPY(VideoSurface) -public: - explicit VideoSurface(QObject *parent = 0); - virtual ~VideoSurface(); - - /*! Returns the video sink element that provides this surface's image. - * The element will be constructed the first time that this function - * is called. The surface will always keep a reference to this element. - */ -#if defined(QGC_GST_STREAMING) - GstElement* videoSink(); - time_t lastFrame() { return _lastFrame; } - void setLastFrame(time_t t) { _lastFrame = t; } -#endif - -protected: -#if defined(QGC_GST_STREAMING) - void onUpdate(); - static void onUpdateThunk(GstElement* sink, gpointer data); -#endif - -private: - friend class VideoItem; -#if defined(QGC_GST_STREAMING) - VideoSurfacePrivate * const _data; - time_t _lastFrame; - bool _refed; -#endif -}; - -Q_DECLARE_METATYPE(VideoSurface*) - diff --git a/src/VideoStreaming/VideoSurface_p.h b/src/VideoStreaming/VideoSurface_p.h deleted file mode 100644 index c090a8e17525ed61e808efc48cddd7bf2c31b7ab..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/VideoSurface_p.h +++ /dev/null @@ -1,32 +0,0 @@ -/**************************************************************************** - * - * (c) 2009-2020 QGROUNDCONTROL PROJECT - * - * QGroundControl is licensed according to the terms in the file - * COPYING.md in the root of the source code directory. - * - ****************************************************************************/ - - -/** - * @file - * @brief QGC Video Surface (Private Interface) - * @author Gus Grubba - */ - -#pragma once - -#include "VideoSurface.h" -#include "VideoItem.h" - -class VideoSurfacePrivate -{ -public: - VideoSurfacePrivate() - : videoSink(nullptr) - { - } - QSet items; - GstElement* videoSink; -}; - diff --git a/src/VideoStreaming/gstqtvideosink/delegates/basedelegate.cpp b/src/VideoStreaming/gstqtvideosink/delegates/basedelegate.cpp deleted file mode 100644 index 0b29a34626e44195336a0b5a7e88ecc4b9d380d9..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/delegates/basedelegate.cpp +++ /dev/null @@ -1,203 +0,0 @@ -/* - Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). - Copyright (C) 2011-2013 Collabora Ltd. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License version 2.1 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/** - * @file - * @brief Extracted from QtGstreamer to avoid overly complex dependency - * @author Gus Grubba - */ - -#include "basedelegate.h" - -#include - -BaseDelegate::BaseDelegate(GstElement * sink, QObject * parent) - : QObject(parent) - , m_colorsDirty(true) - , m_brightness(0) - , m_contrast(0) - , m_hue(0) - , m_saturation(0) - , m_pixelAspectRatio(1, 1) - , m_forceAspectRatioDirty(true) - , m_forceAspectRatio(false) - , m_formatDirty(true) - , m_isActive(false) - , m_buffer(nullptr) - , m_sink(sink) -{ -} - -BaseDelegate::~BaseDelegate() -{ - Q_ASSERT(!isActive()); -} - -//------------------------------------- - -bool BaseDelegate::isActive() const -{ - QReadLocker l(&m_isActiveLock); - return m_isActive; -} - -void BaseDelegate::setActive(bool active) -{ - GST_INFO_OBJECT(m_sink, active ? "Activating" : "Deactivating"); - - QWriteLocker l(&m_isActiveLock); - m_isActive = active; - if (!active) { - QCoreApplication::postEvent(this, new DeactivateEvent()); - } -} - -//------------------------------------- - -int BaseDelegate::brightness() const -{ - QReadLocker l(&m_colorsLock); - return m_brightness; -} - -void BaseDelegate::setBrightness(int brightness) -{ - QWriteLocker l(&m_colorsLock); - m_brightness = qBound(-100, brightness, 100); - m_colorsDirty = true; -} - -int BaseDelegate::contrast() const -{ - QReadLocker l(&m_colorsLock); - return m_contrast; -} - -void BaseDelegate::setContrast(int contrast) -{ - QWriteLocker l(&m_colorsLock); - m_contrast = qBound(-100, contrast, 100); - m_colorsDirty = true; -} - -int BaseDelegate::hue() const -{ - QReadLocker l(&m_colorsLock); - return m_hue; -} - -void BaseDelegate::setHue(int hue) -{ - QWriteLocker l(&m_colorsLock); - m_hue = qBound(-100, hue, 100); - m_colorsDirty = true; -} - -int BaseDelegate::saturation() const -{ - QReadLocker l(&m_colorsLock); - return m_saturation; -} - -void BaseDelegate::setSaturation(int saturation) -{ - QWriteLocker l(&m_colorsLock); - m_saturation = qBound(-100, saturation, 100); - m_colorsDirty = true; -} - -//------------------------------------- - -Fraction BaseDelegate::pixelAspectRatio() const -{ - QReadLocker l(&m_pixelAspectRatioLock); - return m_pixelAspectRatio; -} - -void BaseDelegate::setPixelAspectRatio(const Fraction & f) -{ - QWriteLocker l(&m_pixelAspectRatioLock); - m_pixelAspectRatio = f; -} - -//------------------------------------- - -bool BaseDelegate::forceAspectRatio() const -{ - QReadLocker l(&m_forceAspectRatioLock); - return m_forceAspectRatio; -} - -void BaseDelegate::setForceAspectRatio(bool force) -{ - QWriteLocker l(&m_forceAspectRatioLock); - if (m_forceAspectRatio != force) { - m_forceAspectRatio = force; - m_forceAspectRatioDirty = true; - } -} - -//------------------------------------- - -bool BaseDelegate::event(QEvent *event) -{ - switch((int) event->type()) { - case BufferEventType: - { - BufferEvent *bufEvent = dynamic_cast(event); - Q_ASSERT(bufEvent); - - GST_TRACE_OBJECT(m_sink, "Received buffer %" GST_PTR_FORMAT, bufEvent->buffer); - - if (isActive()) { - gst_buffer_replace (&m_buffer, bufEvent->buffer); - update(); - } - - return true; - } - case BufferFormatEventType: - { - BufferFormatEvent *bufFmtEvent = dynamic_cast(event); - Q_ASSERT(bufFmtEvent); - - GST_TRACE_OBJECT (m_sink, "Received buffer format event. New format: %s", - gst_video_format_to_string(bufFmtEvent->format.videoFormat())); - - m_formatDirty = true; - m_bufferFormat = bufFmtEvent->format; - - return true; - } - case DeactivateEventType: - { - GST_LOG_OBJECT(m_sink, "Received deactivate event"); - - gst_buffer_replace (&m_buffer, nullptr); - update(); - - return true; - } - default: - return QObject::event(event); - } -} - -void BaseDelegate::update() -{ - g_signal_emit_by_name(m_sink, "update"); -} diff --git a/src/VideoStreaming/gstqtvideosink/delegates/basedelegate.h b/src/VideoStreaming/gstqtvideosink/delegates/basedelegate.h deleted file mode 100644 index e063017530ec161fafcf520bcf57c2ac9d682e0b..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/delegates/basedelegate.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). - Copyright (C) 2011-2013 Collabora Ltd. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License version 2.1 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/** - * @file - * @brief Extracted from QtGstreamer to avoid overly complex dependency - * @author Gus Grubba - */ - -#pragma once - -#include - -#include "../gstqtvideosinkplugin.h" //for debug category -#include "../utils/bufferformat.h" -#include "../utils/utils.h" - -#include -#include -#include - -class BaseDelegate : public QObject -{ - Q_OBJECT -public: - enum EventType { - BufferEventType = QEvent::User, - BufferFormatEventType, - DeactivateEventType - }; - - //------------------------------------- - - class BufferEvent : public QEvent - { - public: - inline BufferEvent(GstBuffer *buf) - : QEvent(static_cast(BufferEventType)), - buffer(gst_buffer_ref(buf)) - {} - - virtual ~BufferEvent() { - gst_buffer_unref(buffer); - } - - GstBuffer *buffer; - }; - - class BufferFormatEvent : public QEvent - { - public: - inline BufferFormatEvent(const BufferFormat &format) - : QEvent(static_cast(BufferFormatEventType)), - format(format) - {} - - BufferFormat format; - }; - - class DeactivateEvent : public QEvent - { - public: - inline DeactivateEvent() - : QEvent(static_cast(DeactivateEventType)) - { - } - }; - - //------------------------------------- - - explicit BaseDelegate(GstElement *sink, QObject *parent = 0); - virtual ~BaseDelegate(); - - bool isActive() const; - void setActive(bool playing); - - // GstColorBalance interface - - 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); - - // pixel-aspect-ratio property - Fraction pixelAspectRatio() const; - void setPixelAspectRatio(const Fraction & f); - - // force-aspect-ratio property - bool forceAspectRatio() const; - void setForceAspectRatio(bool force); - -protected: - // internal event handling - virtual bool event(QEvent *event); - - // tells the surface to repaint itself - virtual void update(); - -protected: - // colorbalance interface properties - mutable QReadWriteLock m_colorsLock; - bool m_colorsDirty; - int m_brightness; - int m_contrast; - int m_hue; - int m_saturation; - - // pixel-aspect-ratio property - mutable QReadWriteLock m_pixelAspectRatioLock; - Fraction m_pixelAspectRatio; - - // force-aspect-ratio property - mutable QReadWriteLock m_forceAspectRatioLock; - bool m_forceAspectRatioDirty; - bool m_forceAspectRatio; - - // format caching - bool m_formatDirty; - BufferFormat m_bufferFormat; - PaintAreas m_areas; - - // whether the sink is active (PAUSED or PLAYING) - mutable QReadWriteLock m_isActiveLock; - bool m_isActive; - - // the buffer to be drawn next - GstBuffer *m_buffer; - - // the video sink element - GstElement * const m_sink; -}; - diff --git a/src/VideoStreaming/gstqtvideosink/delegates/qtquick2videosinkdelegate.cpp b/src/VideoStreaming/gstqtvideosink/delegates/qtquick2videosinkdelegate.cpp deleted file mode 100644 index f898a8b072c5a8a5a5d431f864851cb96175f891..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/delegates/qtquick2videosinkdelegate.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/* - Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). - Copyright (C) 2011-2013 Collabora Ltd. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License version 2.1 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/** - * @file - * @brief Extracted from QtGstreamer to avoid overly complex dependency - * @author Gus Grubba - */ - -#include "qtquick2videosinkdelegate.h" -#include "../painters/videonode.h" - -QtQuick2VideoSinkDelegate::QtQuick2VideoSinkDelegate(GstElement *sink, QObject *parent) - : BaseDelegate(sink, parent) -{ -} - -QSGNode* QtQuick2VideoSinkDelegate::updateNode(QSGNode *node, const QRectF & targetArea) -{ - GST_TRACE_OBJECT(m_sink, "updateNode called"); - bool sgnodeFormatChanged = false; - - VideoNode *vnode = dynamic_cast(node); - if (!vnode) { - GST_INFO_OBJECT(m_sink, "creating new VideoNode"); - vnode = new VideoNode; - } - - if (!m_buffer) { - if (vnode->materialType() != VideoNode::MaterialTypeSolidBlack) { - vnode->setMaterialTypeSolidBlack(); - sgnodeFormatChanged = true; - } - if (sgnodeFormatChanged || targetArea != m_areas.targetArea) { - m_areas.targetArea = targetArea; - vnode->updateGeometry(m_areas); - } - } else { - //change format before geometry, so that we change QSGGeometry as well - if (m_formatDirty) { - vnode->changeFormat(m_bufferFormat); - sgnodeFormatChanged = true; - } - - //recalculate the video area if needed - QReadLocker forceAspectRatioLocker(&m_forceAspectRatioLock); - if (sgnodeFormatChanged || targetArea != m_areas.targetArea || m_forceAspectRatioDirty) { - m_forceAspectRatioDirty = false; - - QReadLocker pixelAspectRatioLocker(&m_pixelAspectRatioLock); - Qt::AspectRatioMode aspectRatioMode = m_forceAspectRatio ? - Qt::KeepAspectRatio : Qt::IgnoreAspectRatio; - m_areas.calculate(targetArea, m_bufferFormat.frameSize(), - m_bufferFormat.pixelAspectRatio(), m_pixelAspectRatio, - aspectRatioMode); - pixelAspectRatioLocker.unlock(); - - GST_LOG_OBJECT(m_sink, - "Recalculated paint areas: " - "Frame size: " QSIZE_FORMAT ", " - "target area: " QRECTF_FORMAT ", " - "video area: " QRECTF_FORMAT ", " - "black1: " QRECTF_FORMAT ", " - "black2: " QRECTF_FORMAT, - QSIZE_FORMAT_ARGS(m_bufferFormat.frameSize()), - QRECTF_FORMAT_ARGS(m_areas.targetArea), - QRECTF_FORMAT_ARGS(m_areas.videoArea), - QRECTF_FORMAT_ARGS(m_areas.blackArea1), - QRECTF_FORMAT_ARGS(m_areas.blackArea2) - ); - - vnode->updateGeometry(m_areas); - } - forceAspectRatioLocker.unlock(); - - if (m_formatDirty) { - m_formatDirty = false; - - //make sure to update the colors after changing material - m_colorsDirty = true; - } - - QReadLocker colorsLocker(&m_colorsLock); - if (m_colorsDirty) { - vnode->updateColors(m_brightness, m_contrast, m_hue, m_saturation); - m_colorsDirty = false; - } - colorsLocker.unlock(); - - vnode->setCurrentFrame(m_buffer); - } - - return vnode; -} diff --git a/src/VideoStreaming/gstqtvideosink/delegates/qtquick2videosinkdelegate.h b/src/VideoStreaming/gstqtvideosink/delegates/qtquick2videosinkdelegate.h deleted file mode 100644 index 0698c8c87323e96f31ce3af01c48388f4786916c..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/delegates/qtquick2videosinkdelegate.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - Copyright (C) 2013 Collabora Ltd. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License version 2.1 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/** - * @file - * @brief Extracted from QtGstreamer to avoid overly complex dependency - * @author Gus Grubba - */ - -#pragma once - -#include "basedelegate.h" -#include - -class QtQuick2VideoSinkDelegate : public BaseDelegate -{ - Q_OBJECT -public: - explicit QtQuick2VideoSinkDelegate(GstElement * sink, QObject * parent = 0); - - QSGNode *updateNode(QSGNode *node, const QRectF & targetArea); -}; - diff --git a/src/VideoStreaming/gstqtvideosink/delegates/qtvideosinkdelegate.cpp b/src/VideoStreaming/gstqtvideosink/delegates/qtvideosinkdelegate.cpp deleted file mode 100644 index ff35d118de034644775b7ab0d51d0a08126aa011..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/delegates/qtvideosinkdelegate.cpp +++ /dev/null @@ -1,247 +0,0 @@ -/* - Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). - Copyright (C) 2011 Collabora Ltd. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License version 2.1 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/** - * @file - * @brief Extracted from QtGstreamer to avoid overly complex dependency - * @author Gus Grubba - */ - -#include "qtvideosinkdelegate.h" -#include "../painters/genericsurfacepainter.h" -#include "../painters/openglsurfacepainter.h" - -#include -#include - -#include "glutils.h" - -QtVideoSinkDelegate::QtVideoSinkDelegate(GstElement *sink, QObject *parent) - : BaseDelegate(sink, parent) - , m_painter(0) - , m_supportedPainters(Generic) -#ifndef GST_QT_VIDEO_SINK_NO_OPENGL - , m_glContext(0) -#endif -{ -} - -QtVideoSinkDelegate::~QtVideoSinkDelegate() -{ - destroyPainter(); -} - -void QtVideoSinkDelegate::paint(QPainter *painter, const QRectF & targetArea) -{ - GST_TRACE_OBJECT(m_sink, "paint called"); - -#ifndef GST_QT_VIDEO_SINK_NO_OPENGL - if (m_glContext) { - Q_ASSERT_X(m_glContext == QGLContext::currentContext(), - "qtvideosink - paint", - "Please use a QPainter that is initialized to paint on the " - "GL surface that has the same context as the one given on the glcontext property" - ); - } -#endif - - if (!m_buffer) { - painter->fillRect(targetArea, Qt::black); - } else { - //recalculate the video area if needed - QReadLocker forceAspectRatioLocker(&m_forceAspectRatioLock); - if (targetArea != m_areas.targetArea || m_formatDirty - || m_forceAspectRatioDirty) - { - m_forceAspectRatioDirty = false; - - QReadLocker pixelAspectRatioLocker(&m_pixelAspectRatioLock); - Qt::AspectRatioMode aspectRatioMode = m_forceAspectRatio ? - Qt::KeepAspectRatio : Qt::IgnoreAspectRatio; - m_areas.calculate(targetArea, m_bufferFormat.frameSize(), - m_bufferFormat.pixelAspectRatio(), m_pixelAspectRatio, - aspectRatioMode); - pixelAspectRatioLocker.unlock(); - - GST_LOG_OBJECT(m_sink, - "Recalculated paint areas: " - "Frame size: " QSIZE_FORMAT ", " - "target area: " QRECTF_FORMAT ", " - "video area: " QRECTF_FORMAT ", " - "black1: " QRECTF_FORMAT ", " - "black2: " QRECTF_FORMAT, - QSIZE_FORMAT_ARGS(m_bufferFormat.frameSize()), - QRECTF_FORMAT_ARGS(m_areas.targetArea), - QRECTF_FORMAT_ARGS(m_areas.videoArea), - QRECTF_FORMAT_ARGS(m_areas.blackArea1), - QRECTF_FORMAT_ARGS(m_areas.blackArea2) - ); - } - forceAspectRatioLocker.unlock(); - - //if either pixelFormat or frameSize have changed, we need to reset the painter - //and/or change painter, in case the current one does not handle the requested format - if ((m_formatDirty) || !m_painter) - { - changePainter(m_bufferFormat); - - m_formatDirty = false; - - //make sure to update the colors after changing painter - m_colorsDirty = true; - } - - if (G_LIKELY(m_painter)) { - QReadLocker colorsLocker(&m_colorsLock); - if (m_colorsDirty) { - m_painter->updateColors(m_brightness, m_contrast, m_hue, m_saturation); - m_colorsDirty = false; - } - colorsLocker.unlock(); - - GstMapInfo mem_info; - if (gst_buffer_map(m_buffer, &mem_info, GST_MAP_READ)) { - m_painter->paint(mem_info.data, m_bufferFormat, painter, m_areas); - gst_buffer_unmap(m_buffer, &mem_info); - } - } - } -} - -#ifndef GST_QT_VIDEO_SINK_NO_OPENGL - -QGLContext *QtVideoSinkDelegate::glContext() const -{ - return m_glContext; -} - -void QtVideoSinkDelegate::setGLContext(QGLContext *context) -{ - if (m_glContext == context) - return; - - m_glContext = context; - m_supportedPainters = Generic; - - if (m_glContext) { - m_glContext->makeCurrent(); - QOpenGLFunctionsDef *funcs = getQOpenGLFunctions(); - if (funcs) { - const QByteArray extensions(reinterpret_cast(funcs->glGetString(GL_EXTENSIONS))); - GST_LOG_OBJECT(m_sink, "Available GL extensions: %s", extensions.constData()); - -#ifndef QT_OPENGL_ES - if (extensions.contains("ARB_fragment_program")) - m_supportedPainters |= ArbFp; -#endif - -#ifndef QT_OPENGL_ES_2 - if (QGLShaderProgram::hasOpenGLShaderPrograms(m_glContext) - && extensions.contains("ARB_shader_objects")) -#endif - m_supportedPainters |= Glsl; - } - } - - GST_LOG_OBJECT(m_sink, "Done setting GL context. m_supportedPainters=%x", (int) m_supportedPainters); -} - -#endif - -void QtVideoSinkDelegate::changePainter(const BufferFormat & format) -{ - if (m_painter) { - m_painter->cleanup(); - if (G_UNLIKELY(!m_painter->supportsFormat(format.videoFormat()))) { - destroyPainter(); - } - } - - QStack possiblePainters; - if (GenericSurfacePainter::supportedPixelFormats().contains(format.videoFormat())) { - possiblePainters.push(Generic); - } - -#ifndef GST_QT_VIDEO_SINK_NO_OPENGL - if (OpenGLSurfacePainter::supportedPixelFormats().contains(format.videoFormat())) { - if (m_supportedPainters & ArbFp) { - possiblePainters.push(ArbFp); - } - - if (m_supportedPainters & Glsl) { - possiblePainters.push(Glsl); - } - } -#endif - - while (!possiblePainters.isEmpty()) { - if (!m_painter) { - PainterType type = possiblePainters.pop(); - switch(type) { -#ifndef GST_QT_VIDEO_SINK_NO_OPENGL - case Glsl: - GST_LOG_OBJECT(m_sink, "Creating GLSL painter"); - m_painter = new GlslSurfacePainter; - break; -# ifndef QT_OPENGL_ES - case ArbFp: - GST_LOG_OBJECT(m_sink, "Creating ARB Fragment Shader painter"); - m_painter = new ArbFpSurfacePainter; - break; -# endif -#endif - case Generic: - GST_LOG_OBJECT(m_sink, "Creating Generic painter"); - m_painter = new GenericSurfacePainter; - break; - default: - Q_ASSERT(false); - } - } - - try { - m_painter->init(format); - return; - } catch (const QString & error) { - GST_ELEMENT_WARNING(m_sink, RESOURCE, FAILED, - ("Failed to start painter"), ("%s", error.toUtf8().constData())); - delete m_painter; - m_painter = 0; - } - } - - GST_ELEMENT_ERROR(m_sink, RESOURCE, FAILED, - ("Failed to create a painter for the given format"), (nullptr)); -} - -void QtVideoSinkDelegate::destroyPainter() -{ - GST_LOG_OBJECT(m_sink, "Destroying painter"); - delete m_painter; - m_painter = 0; -} - -bool QtVideoSinkDelegate::event(QEvent *event) -{ - if (event->type() == (QEvent::Type)DeactivateEventType) { - if (m_painter) { - m_painter->cleanup(); - destroyPainter(); - } - } - return BaseDelegate::event(event); -} diff --git a/src/VideoStreaming/gstqtvideosink/delegates/qtvideosinkdelegate.h b/src/VideoStreaming/gstqtvideosink/delegates/qtvideosinkdelegate.h deleted file mode 100644 index 7c4c105eb2e2cc718c8dad8a22ae38b93ec4ff00..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/delegates/qtvideosinkdelegate.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). - Copyright (C) 2011 Collabora Ltd. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License version 2.1 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/** - * @file - * @brief Extracted from QtGstreamer to avoid overly complex dependency - * @author Gus Grubba - */ - -#pragma once - -#include "basedelegate.h" -#include "../painters/abstractsurfacepainter.h" - -class QGLContext; - -class QtVideoSinkDelegate : public BaseDelegate -{ - Q_OBJECT -public: - enum PainterType { - Generic = 0x00, - ArbFp = 0x01, - Glsl = 0x02 - }; - Q_DECLARE_FLAGS(PainterTypes, PainterType); - - explicit QtVideoSinkDelegate(GstElement *sink, QObject *parent = 0); - virtual ~QtVideoSinkDelegate(); - - PainterTypes supportedPainterTypes() const { return m_supportedPainters; } - -#ifndef GST_QT_VIDEO_SINK_NO_OPENGL - // glcontext property - QGLContext *glContext() const; - void setGLContext(QGLContext *context); -#endif - - // paint action - void paint(QPainter *painter, const QRectF & targetArea); - -protected: - // internal event handling - virtual bool event(QEvent *event); - -private: - void changePainter(const BufferFormat & format); - void destroyPainter(); - - AbstractSurfacePainter *m_painter; - PainterTypes m_supportedPainters; - -#ifndef GST_QT_VIDEO_SINK_NO_OPENGL - QGLContext *m_glContext; -#endif -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(QtVideoSinkDelegate::PainterTypes) - diff --git a/src/VideoStreaming/gstqtvideosink/delegates/qwidgetvideosinkdelegate.cpp b/src/VideoStreaming/gstqtvideosink/delegates/qwidgetvideosinkdelegate.cpp deleted file mode 100644 index 8ee7d59a2c5fc28a948ddada420d3927237087b2..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/delegates/qwidgetvideosinkdelegate.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - Copyright (C) 2010 George Kiagiadakis - Copyright (C) 2012 Collabora Ltd. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/** - * @file - * @brief Extracted from QtGstreamer to avoid overly complex dependency - * @author Gus Grubba - */ - -#include "qwidgetvideosinkdelegate.h" -#include - -QWidgetVideoSinkDelegate::QWidgetVideoSinkDelegate(GstElement * sink, QObject * parent) - : QtVideoSinkDelegate(sink, parent) -{ - -} - -QWidgetVideoSinkDelegate::~QWidgetVideoSinkDelegate() -{ - setWidget(nullptr); -} - -QWidget *QWidgetVideoSinkDelegate::widget() const -{ - return m_widget.data(); -} - -void QWidgetVideoSinkDelegate::setWidget(QWidget *widget) -{ - GST_LOG_OBJECT(m_sink, "Setting \"widget\" property to %" GST_PTR_FORMAT, widget); - - if (m_widget) { - m_widget.data()->removeEventFilter(this); - m_widget.data()->setAttribute(Qt::WA_OpaquePaintEvent, m_opaquePaintEventAttribute); - m_widget.data()->update(); - - m_widget = nullptr; - } - - if (widget) { - widget->installEventFilter(this); - m_opaquePaintEventAttribute = widget->testAttribute(Qt::WA_OpaquePaintEvent); - widget->setAttribute(Qt::WA_OpaquePaintEvent, true); - widget->update(); - - m_widget = widget; - } -} - -bool QWidgetVideoSinkDelegate::eventFilter(QObject *filteredObject, QEvent *event) -{ - if (filteredObject == m_widget.data()) { - switch(event->type()) { - case QEvent::Paint: - { - QPainter painter(m_widget.data()); - paint(&painter, m_widget.data()->rect()); - return true; - } - default: - return false; - } - } else { - return QtVideoSinkDelegate::eventFilter(filteredObject, event); - } -} - -void QWidgetVideoSinkDelegate::update() -{ - if (m_widget) { - m_widget.data()->update(); - } -} diff --git a/src/VideoStreaming/gstqtvideosink/delegates/qwidgetvideosinkdelegate.h b/src/VideoStreaming/gstqtvideosink/delegates/qwidgetvideosinkdelegate.h deleted file mode 100644 index 3cc5337c92480eb4406b7069ea816c0f07c1cd40..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/delegates/qwidgetvideosinkdelegate.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - Copyright (C) 2010 George Kiagiadakis - Copyright (C) 2012 Collabora Ltd. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/** - * @file - * @brief Extracted from QtGstreamer to avoid overly complex dependency - * @author Gus Grubba - */ - -#pragma once - -#include "qtvideosinkdelegate.h" -#include -#include -#include - -class QWidgetVideoSinkDelegate : public QtVideoSinkDelegate -{ - Q_OBJECT -public: - explicit QWidgetVideoSinkDelegate(GstElement * sink, QObject * parent = 0); - virtual ~QWidgetVideoSinkDelegate(); - - // "widget" property - QWidget *widget() const; - void setWidget(QWidget *widget); - -protected: - virtual bool eventFilter(QObject *filteredObject, QEvent *event); - virtual void update(); - -private: - // "widget" property - QPointer m_widget; - - // original value of the Qt::WA_OpaquePaintEvent attribute - bool m_opaquePaintEventAttribute; -}; - diff --git a/src/VideoStreaming/gstqtvideosink/gstqtglvideosink.cpp b/src/VideoStreaming/gstqtvideosink/gstqtglvideosink.cpp deleted file mode 100644 index e083d827e04cb5770890db26f034ecaddb5d7482..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/gstqtglvideosink.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/* - Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). - Copyright (C) 2011-2012 Collabora Ltd. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License version 2.1 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/** - * @file - * @brief Extracted from QtGstreamer to avoid overly complex dependency - * @author Gus Grubba - */ - -/* - * Note on the marshallers - * - * If it ever needs to be recreated, here is what you need to do: - * - * cat > marshaller.src - * VOID:POINTER,FLOAT,FLOAT,FLOAT,FLOAT - * VOID:POINTER,DOUBLE,DOUBLE,DOUBLE,DOUBLE - * POINTER:POINTER,FLOAT,FLOAT,FLOAT,FLOAT - * POINTER:POINTER,DOUBLE,DOUBLE,DOUBLE,DOUBLE - * Ctrl+D (EOF) - * - * glib-genmarshal --header marshaller.list > gstqtvideosinkmarshal.h - * glib-genmarshal --body marshaller.list > gstqtvideosinkmarshal.c - * - */ - -#include "gstqtglvideosink.h" -#include "gstqtvideosinkmarshal.h" -#include "delegates/qtvideosinkdelegate.h" - - -guint GstQtGLVideoSink::s_signals[]; - -DEFINE_TYPE(GstQtGLVideoSink, GST_TYPE_QT_GL_VIDEO_SINK_BASE) - -//------------------------------ - -void GstQtGLVideoSink::emit_update(gpointer sink) -{ - g_signal_emit(sink, GstQtGLVideoSink::s_signals[UPDATE_SIGNAL], 0, NULL); -} - -//------------------------------ - -void GstQtGLVideoSink::base_init(gpointer g_class) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS(g_class); - - gst_element_class_set_details_simple(element_class, "Qt GL video sink", "Sink/Video", - "A video sink that can draw on any Qt GL surface", - "George Kiagiadakis "); -} - -void GstQtGLVideoSink::class_init(gpointer g_class, gpointer class_data) -{ - Q_UNUSED(class_data); - - GObjectClass *object_class = G_OBJECT_CLASS(g_class); - object_class->set_property = GstQtGLVideoSink::set_property; - - GstQtGLVideoSinkClass *qt_video_sink_class = reinterpret_cast(g_class); - qt_video_sink_class->paint = GstQtGLVideoSink::paint; - - /** - * GstQtGLVideoSink::paint - * @painter: A valid QPainter pointer that will be used to paint the video - * @x: The x coordinate of the target area rectangle - * @y: The y coordinate of the target area rectangle - * @width: The width of the target area rectangle - * @height: The height of the target area rectangle - * - * This is an action signal that you can call from your Qt surface class inside - * its paint function to render the video. It takes a QPainter* and the target - * area rectangle as arguments. You should schedule to call this function to - * repaint the surface whenever the ::update signal is emitted. - * - * Note that the x,y,width and height arguments are actually qreal. This means - * that on architectures like arm they will be float instead of double. You should - * cast the arguments to qreal if they are not already when emitting this signal. - */ - - s_signals[PAINT_SIGNAL] = - g_signal_new("paint", G_TYPE_FROM_CLASS(g_class), - static_cast(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION), - G_STRUCT_OFFSET(GstQtGLVideoSinkClass, paint), - nullptr, nullptr, - qRealIsDouble() ? - g_cclosure_user_marshal_VOID__POINTER_DOUBLE_DOUBLE_DOUBLE_DOUBLE : - g_cclosure_user_marshal_VOID__POINTER_FLOAT_FLOAT_FLOAT_FLOAT, - G_TYPE_NONE, 5, - G_TYPE_POINTER, G_TYPE_QREAL, G_TYPE_QREAL, G_TYPE_QREAL, G_TYPE_QREAL); - - /** - * GstQtGLVideoSink::update - * - * This signal is emitted when the surface should be repainted. It should - * be connected to QWidget::update() or QGraphicsItem::update() or any - * other similar function in your surface. - */ - s_signals[UPDATE_SIGNAL] = - g_signal_new("update", G_TYPE_FROM_CLASS(g_class), - G_SIGNAL_RUN_LAST, - 0, nullptr, nullptr, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - - /** - * GstQtGLVideoSink::glcontext - * - * This property holds a pointer to the QGLContext that will be used to render - * the video using OpenGL acceleration. You must set this to a valid QGLContext - * pointer before the element changes state to READY, or else the state change will fail. - **/ - g_object_class_install_property(object_class, PROP_GLCONTEXT, - g_param_spec_pointer("glcontext", "GL context", - "The QGLContext that will be used to do OpenGL-accelerated rendering", - static_cast(G_PARAM_WRITABLE))); -} - -void GstQtGLVideoSink::init(GTypeInstance *instance, gpointer g_class) -{ - Q_UNUSED(g_class); - - GstQtVideoSinkBase *sinkBase = GST_QT_VIDEO_SINK_BASE(instance); - sinkBase->delegate = new QtVideoSinkDelegate(GST_ELEMENT(sinkBase)); -} - -//------------------------------ - -void GstQtGLVideoSink::set_property(GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) -{ - GstQtVideoSinkBase *sinkBase = GST_QT_VIDEO_SINK_BASE(object); - - switch (prop_id) { - case PROP_GLCONTEXT: - sinkBase->delegate->setGLContext(static_cast(g_value_get_pointer(value))); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -//------------------------------ - -void GstQtGLVideoSink::paint(GstQtGLVideoSink *sink, gpointer painter, - qreal x, qreal y, qreal width, qreal height) -{ - GST_QT_VIDEO_SINK_BASE(sink)->delegate->paint(static_cast(painter), - QRectF(x, y, width, height)); -} diff --git a/src/VideoStreaming/gstqtvideosink/gstqtglvideosink.h b/src/VideoStreaming/gstqtvideosink/gstqtglvideosink.h deleted file mode 100644 index d4fe18b77fd28de6822cb720160d7d8e9bb58f79..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/gstqtglvideosink.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). - Copyright (C) 2011-2012 Collabora Ltd. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License version 2.1 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/** - * @file - * @brief Extracted from QtGstreamer to avoid overly complex dependency - * @author Gus Grubba - */ - -#pragma once - -#include "gstqtglvideosinkbase.h" - -#ifndef GST_QT_VIDEO_SINK_NO_OPENGL - -#define GST_TYPE_QT_GL_VIDEO_SINK \ - (GstQtGLVideoSink::get_type()) - -struct GstQtGLVideoSink -{ -public: - GstQtGLVideoSinkBase parent; - - static GType get_type(); - static void emit_update(gpointer sink); - -private: - enum { - PROP_0, - PROP_GLCONTEXT - }; - - enum { - PAINT_SIGNAL, - UPDATE_SIGNAL, - LAST_SIGNAL - }; - - static void base_init(gpointer g_class); - static void class_init(gpointer g_class, gpointer class_data); - static void init(GTypeInstance *instance, gpointer g_class); - - static void set_property(GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec); - - static void paint(GstQtGLVideoSink *sink, gpointer painter, - qreal x, qreal y, qreal width, qreal height); - - static guint s_signals[LAST_SIGNAL]; -}; - - -struct GstQtGLVideoSinkClass -{ - GstQtGLVideoSinkBaseClass parent_class; - - /* paint action signal */ - void (*paint) (GstQtGLVideoSink *sink, gpointer painter, - qreal x, qreal y, qreal width, qreal height); -}; - -#endif // GST_QT_VIDEO_SINK_NO_OPENGL diff --git a/src/VideoStreaming/gstqtvideosink/gstqtglvideosinkbase.cpp b/src/VideoStreaming/gstqtvideosink/gstqtglvideosinkbase.cpp deleted file mode 100644 index b0f23903ae58fc4c31a610221cb2ff57770358e8..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/gstqtglvideosinkbase.cpp +++ /dev/null @@ -1,268 +0,0 @@ -/* - Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). - Copyright (C) 2011-2012 Collabora Ltd. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License version 2.1 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/** - * @file - * @brief Extracted from QtGstreamer to avoid overly complex dependency - * @author Gus Grubba - */ - -#include "gstqtglvideosinkbase.h" -#include "painters/openglsurfacepainter.h" -#include "delegates/qtvideosinkdelegate.h" -#include - -#define CAPS_FORMATS "{ BGRA, BGRx, ARGB, xRGB, RGB, RGB16, BGR, v308, AYUV, YV12, I420 }" - -const char * const GstQtGLVideoSinkBase::s_colorbalance_labels[] = { - "contrast", "brightness", "hue", "saturation" -}; - -GstQtVideoSinkBaseClass *GstQtGLVideoSinkBase::s_parent_class = nullptr; - -//------------------------------ - -DEFINE_TYPE_WITH_CODE(GstQtGLVideoSinkBase, GST_TYPE_QT_VIDEO_SINK_BASE, init_interfaces) - -void GstQtGLVideoSinkBase::init_interfaces(GType type) -{ - static const GInterfaceInfo colorbalance_info = { - (GInterfaceInitFunc) &GstQtGLVideoSinkBase::colorbalance_init, nullptr, nullptr - }; - - g_type_add_interface_static(type, GST_TYPE_COLOR_BALANCE, &colorbalance_info); -} - -//------------------------------ - -void GstQtGLVideoSinkBase::base_init(gpointer g_class) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS(g_class); - element_class->padtemplates = nullptr; //get rid of the pad template of the base class - - static GstStaticPadTemplate sink_pad_template = - GST_STATIC_PAD_TEMPLATE("sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (CAPS_FORMATS)) - ); - - gst_element_class_add_pad_template( - element_class, gst_static_pad_template_get(&sink_pad_template)); -} - -void GstQtGLVideoSinkBase::class_init(gpointer g_class, gpointer class_data) -{ - Q_UNUSED(class_data); - - s_parent_class = reinterpret_cast(g_type_class_peek_parent(g_class)); - - GObjectClass *object_class = G_OBJECT_CLASS(g_class); - object_class->finalize = GstQtGLVideoSinkBase::finalize; - object_class->set_property = GstQtGLVideoSinkBase::set_property; - object_class->get_property = GstQtGLVideoSinkBase::get_property; - - GstBaseSinkClass *base_sink_class = GST_BASE_SINK_CLASS(g_class); - base_sink_class->start = GstQtGLVideoSinkBase::start; - base_sink_class->set_caps = GstQtGLVideoSinkBase::set_caps; - - g_object_class_install_property(object_class, PROP_CONTRAST, - g_param_spec_int("contrast", "Contrast", "The contrast of the video", - -100, 100, 0, static_cast(G_PARAM_READWRITE))); - g_object_class_install_property(object_class, PROP_BRIGHTNESS, - g_param_spec_int("brightness", "Brightness", "The brightness of the video", - -100, 100, 0, static_cast(G_PARAM_READWRITE))); - g_object_class_install_property(object_class, PROP_HUE, - g_param_spec_int("hue", "Hue", "The hue of the video", - -100, 100, 0, static_cast(G_PARAM_READWRITE))); - g_object_class_install_property(object_class, PROP_SATURATION, - g_param_spec_int("saturation", "Saturation", "The saturation of the video", - -100, 100, 0, static_cast(G_PARAM_READWRITE))); -} - -void GstQtGLVideoSinkBase::init(GTypeInstance *instance, gpointer g_class) -{ - Q_UNUSED(g_class); - GstQtGLVideoSinkBase *self = GST_QT_GL_VIDEO_SINK_BASE(instance); - - GstColorBalanceChannel *channel; - self->m_channels_list = nullptr; - - for (int i=0; i < LABEL_LAST; i++) { - channel = GST_COLOR_BALANCE_CHANNEL(g_object_new(GST_TYPE_COLOR_BALANCE_CHANNEL, nullptr)); - channel->label = g_strdup(s_colorbalance_labels[i]); - channel->min_value = -100; - channel->max_value = 100; - - self->m_channels_list = g_list_append(self->m_channels_list, channel); - } -} - -void GstQtGLVideoSinkBase::finalize(GObject *object) -{ - GstQtGLVideoSinkBase *self = GST_QT_GL_VIDEO_SINK_BASE(object); - - while (self->m_channels_list) { - GstColorBalanceChannel *channel = GST_COLOR_BALANCE_CHANNEL(self->m_channels_list->data); - g_object_unref(channel); - self->m_channels_list = g_list_next(self->m_channels_list); - } - - g_list_free(self->m_channels_list); - - G_OBJECT_CLASS(s_parent_class)->finalize(object); -} - -//------------------------------ - - -void GstQtGLVideoSinkBase::colorbalance_init(GstColorBalanceInterface *balance_interface, gpointer data) -{ - Q_UNUSED(data); - balance_interface->list_channels = GstQtGLVideoSinkBase::colorbalance_list_channels; - balance_interface->set_value = GstQtGLVideoSinkBase::colorbalance_set_value; - balance_interface->get_value = GstQtGLVideoSinkBase::colorbalance_get_value; - balance_interface->get_balance_type = GstQtGLVideoSinkBase::colorbalance_get_balance_type; -} - -const GList *GstQtGLVideoSinkBase::colorbalance_list_channels(GstColorBalance *balance) -{ - return GST_QT_GL_VIDEO_SINK_BASE(balance)->m_channels_list; -} - -void GstQtGLVideoSinkBase::colorbalance_set_value(GstColorBalance *balance, - GstColorBalanceChannel *channel, gint value) -{ - GstQtVideoSinkBase *sink = GST_QT_VIDEO_SINK_BASE(balance); - - if (!qstrcmp(channel->label, s_colorbalance_labels[LABEL_CONTRAST])) { - sink->delegate->setContrast(value); - } else if (!qstrcmp(channel->label, s_colorbalance_labels[LABEL_BRIGHTNESS])) { - sink->delegate->setBrightness(value); - } else if (!qstrcmp(channel->label, s_colorbalance_labels[LABEL_HUE])) { - sink->delegate->setHue(value); - } else if (!qstrcmp(channel->label, s_colorbalance_labels[LABEL_SATURATION])) { - sink->delegate->setSaturation(value); - } else { - GST_WARNING_OBJECT(sink, "Unknown colorbalance channel %s", channel->label); - } -} - -gint GstQtGLVideoSinkBase::colorbalance_get_value(GstColorBalance *balance, - GstColorBalanceChannel *channel) -{ - GstQtVideoSinkBase *sink = GST_QT_VIDEO_SINK_BASE(balance); - - if (!qstrcmp(channel->label, s_colorbalance_labels[LABEL_CONTRAST])) { - return sink->delegate->contrast(); - } else if (!qstrcmp(channel->label, s_colorbalance_labels[LABEL_BRIGHTNESS])) { - return sink->delegate->brightness(); - } else if (!qstrcmp(channel->label, s_colorbalance_labels[LABEL_HUE])) { - return sink->delegate->hue(); - } else if (!qstrcmp(channel->label, s_colorbalance_labels[LABEL_SATURATION])) { - return sink->delegate->saturation(); - } else { - GST_WARNING_OBJECT(sink, "Unknown colorbalance channel %s", channel->label); - } - - return 0; -} - -GstColorBalanceType GstQtGLVideoSinkBase::colorbalance_get_balance_type(GstColorBalance *balance) -{ - Q_UNUSED(balance); - return GST_COLOR_BALANCE_HARDWARE; -} - -//------------------------------ - -void GstQtGLVideoSinkBase::set_property(GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) -{ - GstQtVideoSinkBase *sink = GST_QT_VIDEO_SINK_BASE(object); - - switch (prop_id) { - case PROP_CONTRAST: - sink->delegate->setContrast(g_value_get_int(value)); - break; - case PROP_BRIGHTNESS: - sink->delegate->setBrightness(g_value_get_int(value)); - break; - case PROP_HUE: - sink->delegate->setHue(g_value_get_int(value)); - break; - case PROP_SATURATION: - sink->delegate->setSaturation(g_value_get_int(value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -void GstQtGLVideoSinkBase::get_property(GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) -{ - GstQtVideoSinkBase *sink = GST_QT_VIDEO_SINK_BASE(object); - - switch (prop_id) { - case PROP_CONTRAST: - g_value_set_int(value, sink->delegate->contrast()); - break; - case PROP_BRIGHTNESS: - g_value_set_int(value, sink->delegate->brightness()); - break; - case PROP_HUE: - g_value_set_int(value, sink->delegate->hue()); - break; - case PROP_SATURATION: - g_value_set_int(value, sink->delegate->saturation()); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -//------------------------------ - -gboolean GstQtGLVideoSinkBase::start(GstBaseSink *base) -{ - GstQtVideoSinkBase *sink = GST_QT_VIDEO_SINK_BASE(base); - - //fail on purpose if the user hasn't set a context - if (sink->delegate->supportedPainterTypes() == QtVideoSinkDelegate::Generic) { - GST_WARNING_OBJECT(sink, "Neither GLSL nor ARB Fragment Program are supported " - "for painting. Did you forget to set a gl context?"); - return FALSE; - } else { - return TRUE; - } -} - -gboolean GstQtGLVideoSinkBase::set_caps(GstBaseSink *base, GstCaps *caps) -{ - GstQtVideoSinkBase *sink = GST_QT_VIDEO_SINK_BASE(base); - - GST_LOG_OBJECT(sink, "new caps %" GST_PTR_FORMAT, caps); - BufferFormat format = BufferFormat::fromCaps(caps); - if (OpenGLSurfacePainter::supportedPixelFormats().contains(format.videoFormat())) { - QCoreApplication::postEvent(sink->delegate, - new BaseDelegate::BufferFormatEvent(format)); - return TRUE; - } else { - return FALSE; - } -} diff --git a/src/VideoStreaming/gstqtvideosink/gstqtglvideosinkbase.h b/src/VideoStreaming/gstqtvideosink/gstqtglvideosinkbase.h deleted file mode 100644 index 962115ea03e2d3084e490333f670c37a59c990f2..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/gstqtglvideosinkbase.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). - Copyright (C) 2011-2012 Collabora Ltd. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License version 2.1 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/** - * @file - * @brief Extracted from QtGstreamer to avoid overly complex dependency - * @author Gus Grubba - */ - -#pragma once - -#include "gstqtvideosinkbase.h" -#include - -#ifndef GST_QT_VIDEO_SINK_NO_OPENGL - -#define GST_TYPE_QT_GL_VIDEO_SINK_BASE \ - (GstQtGLVideoSinkBase::get_type()) -#define GST_QT_GL_VIDEO_SINK_BASE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_QT_GL_VIDEO_SINK_BASE, GstQtGLVideoSinkBase)) - -struct GstQtGLVideoSinkBase -{ -public: - GstQtVideoSinkBase parent; - - static GType get_type(); - -private: - enum { - PROP_0, - PROP_CONTRAST, - PROP_BRIGHTNESS, - PROP_HUE, - PROP_SATURATION - }; - - //index for s_colorbalance_labels - enum { - LABEL_CONTRAST = 0, - LABEL_BRIGHTNESS, - LABEL_HUE, - LABEL_SATURATION, - LABEL_LAST - }; - - static void init_interfaces(GType type); - - static void base_init(gpointer g_class); - static void class_init(gpointer g_class, gpointer class_data); - - static void init(GTypeInstance *instance, gpointer g_class); - static void finalize(GObject *object); - - static void colorbalance_init(GstColorBalanceInterface *balance_interface, gpointer data); - static const GList *colorbalance_list_channels(GstColorBalance *balance); - static void colorbalance_set_value(GstColorBalance *balance, - GstColorBalanceChannel *channel, - gint value); - static gint colorbalance_get_value(GstColorBalance *balance, - GstColorBalanceChannel *channel); - static GstColorBalanceType colorbalance_get_balance_type(GstColorBalance *balance); - - static void set_property(GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec); - static void get_property(GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec); - - static gboolean start(GstBaseSink *sink); - static gboolean set_caps(GstBaseSink *sink, GstCaps *caps); - - - GList *m_channels_list; - static const char * const s_colorbalance_labels[]; - static GstQtVideoSinkBaseClass *s_parent_class; -}; - - -struct GstQtGLVideoSinkBaseClass -{ - GstQtVideoSinkBaseClass parent_class; -}; - -#endif // GST_QT_VIDEO_SINK_NO_OPENGL diff --git a/src/VideoStreaming/gstqtvideosink/gstqtquick2videosink.cpp b/src/VideoStreaming/gstqtvideosink/gstqtquick2videosink.cpp deleted file mode 100644 index 8463e4953a8f75526b51599b318be8b8f645c384..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/gstqtquick2videosink.cpp +++ /dev/null @@ -1,459 +0,0 @@ -/* - Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). - Copyright (C) 2011-2013 Collabora Ltd. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License version 2.1 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/** - * @file - * @brief Extracted from QtGstreamer to avoid overly complex dependency - * @author Gus Grubba - */ - -#include "gstqtquick2videosink.h" -#include "gstqtvideosinkplugin.h" -#include "gstqtvideosinkmarshal.h" -#include "delegates/qtquick2videosinkdelegate.h" - -#include - -#include -#include - -#define CAPS_FORMATS "{ BGRA, BGRx, ARGB, xRGB, RGB, RGB16, BGR, v308, AYUV, YV12, I420 }" - -#define GST_QT_QUICK2_VIDEO_SINK_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_QT_QUICK2_VIDEO_SINK, GstQtQuick2VideoSinkPrivate)) - -struct _GstQtQuick2VideoSinkPrivate -{ - QtQuick2VideoSinkDelegate *delegate; - GList *channels_list; -}; - -static void gst_qt_quick2_video_sink_colorbalance_init (GstColorBalanceInterface * iface, gpointer data); - -#define parent_class gst_qt_quick2_video_sink_parent_class -G_DEFINE_TYPE_WITH_CODE (GstQtQuick2VideoSink, gst_qt_quick2_video_sink, - GST_TYPE_VIDEO_SINK, - G_IMPLEMENT_INTERFACE (GST_TYPE_COLOR_BALANCE, - gst_qt_quick2_video_sink_colorbalance_init)); - -enum { - PROP_0, - PROP_PIXEL_ASPECT_RATIO, - PROP_FORCE_ASPECT_RATIO, - PROP_CONTRAST, - PROP_BRIGHTNESS, - PROP_HUE, - PROP_SATURATION, -}; - -enum { - ACTION_UPDATE_NODE, - SIGNAL_UPDATE, - LAST_SIGNAL -}; - -static guint s_signals[LAST_SIGNAL] = { 0 }; - -const char * const s_colorbalance_labels[] = { - "contrast", "brightness", "hue", "saturation" -}; - -//index for s_colorbalance_labels -enum { - LABEL_CONTRAST = 0, - LABEL_BRIGHTNESS, - LABEL_HUE, - LABEL_SATURATION, - LABEL_LAST -}; - -static void -gst_qt_quick2_video_sink_init (GstQtQuick2VideoSink *self) -{ - self->priv = GST_QT_QUICK2_VIDEO_SINK_GET_PRIVATE (self); - - // delegate - self->priv->delegate = new QtQuick2VideoSinkDelegate(GST_ELEMENT(self)); - - // colorbalance - GstColorBalanceChannel *channel; - self->priv->channels_list = nullptr; - - for (int i=0; i < LABEL_LAST; i++) { - channel = GST_COLOR_BALANCE_CHANNEL(g_object_new(GST_TYPE_COLOR_BALANCE_CHANNEL, nullptr)); - channel->label = g_strdup(s_colorbalance_labels[i]); - channel->min_value = -100; - channel->max_value = 100; - - self->priv->channels_list = g_list_append(self->priv->channels_list, channel); - } -} - -static void -gst_qt_quick2_video_sink_finalize (GObject *gobject) -{ - GstQtQuick2VideoSink *self = GST_QT_QUICK2_VIDEO_SINK (gobject); - - delete self->priv->delegate; - self->priv->delegate = nullptr; - - while (self->priv->channels_list) { - GstColorBalanceChannel *channel = - GST_COLOR_BALANCE_CHANNEL(self->priv->channels_list->data); - g_object_unref(channel); - self->priv->channels_list = g_list_next(self->priv->channels_list); - } - - g_list_free(self->priv->channels_list); - - G_OBJECT_CLASS (parent_class)->finalize (gobject); -} - -static void -gst_qt_quick2_video_sink_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - GstQtQuick2VideoSink *self = GST_QT_QUICK2_VIDEO_SINK (object); - - switch (property_id) { - case PROP_PIXEL_ASPECT_RATIO: - { - GValue tmp; - std::memset(&tmp, 0, sizeof(GValue)); - g_value_init(&tmp, GST_TYPE_FRACTION); - if (g_value_transform(value, &tmp)) { - int n = gst_value_get_fraction_numerator(&tmp); - int d = gst_value_get_fraction_denominator(&tmp); - self->priv->delegate->setPixelAspectRatio(Fraction(n, d)); - } else { - GST_WARNING_OBJECT(object, "Could not transform string to aspect ratio"); - } - g_value_unset(&tmp); - break; - } - case PROP_FORCE_ASPECT_RATIO: - self->priv->delegate->setForceAspectRatio(g_value_get_boolean(value)); - break; - case PROP_CONTRAST: - self->priv->delegate->setContrast(g_value_get_int(value)); - break; - case PROP_BRIGHTNESS: - self->priv->delegate->setBrightness(g_value_get_int(value)); - break; - case PROP_HUE: - self->priv->delegate->setHue(g_value_get_int(value)); - break; - case PROP_SATURATION: - self->priv->delegate->setSaturation(g_value_get_int(value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -gst_qt_quick2_video_sink_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - GstQtQuick2VideoSink *self = GST_QT_QUICK2_VIDEO_SINK (object); - - switch (property_id) { - case PROP_PIXEL_ASPECT_RATIO: - { - GValue tmp; - Fraction par = self->priv->delegate->pixelAspectRatio(); - std::memset(&tmp, 0, sizeof(GValue)); - g_value_init(&tmp, GST_TYPE_FRACTION); - gst_value_set_fraction(&tmp, par.numerator, par.denominator); - g_value_transform(&tmp, value); - g_value_unset(&tmp); - break; - } - case PROP_FORCE_ASPECT_RATIO: - g_value_set_boolean(value, self->priv->delegate->forceAspectRatio()); - break; - case PROP_CONTRAST: - g_value_set_int(value, self->priv->delegate->contrast()); - break; - case PROP_BRIGHTNESS: - g_value_set_int(value, self->priv->delegate->brightness()); - break; - case PROP_HUE: - g_value_set_int(value, self->priv->delegate->hue()); - break; - case PROP_SATURATION: - g_value_set_int(value, self->priv->delegate->saturation()); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static GstStateChangeReturn -gst_qt_quick2_video_sink_change_state(GstElement *element, - GstStateChange transition) -{ - GstQtQuick2VideoSink *self = GST_QT_QUICK2_VIDEO_SINK (element); - - switch (transition) { - case GST_STATE_CHANGE_READY_TO_PAUSED: - self->priv->delegate->setActive(true); - break; - case GST_STATE_CHANGE_PAUSED_TO_READY: - self->priv->delegate->setActive(false); - break; - default: - break; - } - - return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); -} - -static gboolean -gst_qt_quick2_video_sink_set_caps(GstBaseSink *sink, GstCaps *caps) -{ - GstQtQuick2VideoSink *self = GST_QT_QUICK2_VIDEO_SINK (sink); - - GST_LOG_OBJECT(self, "new caps %" GST_PTR_FORMAT, caps); - BufferFormat format = BufferFormat::fromCaps(caps); - - //too lazy to do proper checks. if the format is not UNKNOWN, then - //it should conform to the template caps formats, unless gstreamer - //core has a bug. - if (format.videoFormat() != GST_VIDEO_FORMAT_UNKNOWN) { - QCoreApplication::postEvent(self->priv->delegate, - new BaseDelegate::BufferFormatEvent(format)); - return TRUE; - } else { - return FALSE; - } -} - -static GstFlowReturn -gst_qt_quick2_video_sink_show_frame(GstVideoSink *sink, GstBuffer *buffer) -{ - GstQtQuick2VideoSink *self = GST_QT_QUICK2_VIDEO_SINK (sink); - - GST_TRACE_OBJECT(self, "Posting new buffer (%" GST_PTR_FORMAT ") for rendering.", buffer); - - QCoreApplication::postEvent(self->priv->delegate, new BaseDelegate::BufferEvent(buffer)); - - return GST_FLOW_OK; -} - -//------------------------------ - -static gpointer -gst_qt_quick2_video_sink_update_node(GstQtQuick2VideoSink *self, gpointer node, - qreal x, qreal y, qreal w, qreal h) -{ - return self->priv->delegate->updateNode(static_cast(node), - QRectF(x, y, w, h)); -} - -//------------------------------ - -static const GList * -gst_qt_quick2_video_sink_colorbalance_list_channels(GstColorBalance *balance) -{ - return GST_QT_QUICK2_VIDEO_SINK (balance)->priv->channels_list; -} - -static void -gst_qt_quick2_video_sink_colorbalance_set_value(GstColorBalance *balance, - GstColorBalanceChannel *channel, gint value) -{ - GstQtQuick2VideoSink *self = GST_QT_QUICK2_VIDEO_SINK (balance); - - if (!qstrcmp(channel->label, s_colorbalance_labels[LABEL_CONTRAST])) { - self->priv->delegate->setContrast(value); - } else if (!qstrcmp(channel->label, s_colorbalance_labels[LABEL_BRIGHTNESS])) { - self->priv->delegate->setBrightness(value); - } else if (!qstrcmp(channel->label, s_colorbalance_labels[LABEL_HUE])) { - self->priv->delegate->setHue(value); - } else if (!qstrcmp(channel->label, s_colorbalance_labels[LABEL_SATURATION])) { - self->priv->delegate->setSaturation(value); - } else { - GST_WARNING_OBJECT(self, "Unknown colorbalance channel %s", channel->label); - } -} - -static gint -gst_qt_quick2_video_sink_colorbalance_get_value(GstColorBalance *balance, - GstColorBalanceChannel *channel) -{ - GstQtQuick2VideoSink *self = GST_QT_QUICK2_VIDEO_SINK (balance); - - if (!qstrcmp(channel->label, s_colorbalance_labels[LABEL_CONTRAST])) { - return self->priv->delegate->contrast(); - } else if (!qstrcmp(channel->label, s_colorbalance_labels[LABEL_BRIGHTNESS])) { - return self->priv->delegate->brightness(); - } else if (!qstrcmp(channel->label, s_colorbalance_labels[LABEL_HUE])) { - return self->priv->delegate->hue(); - } else if (!qstrcmp(channel->label, s_colorbalance_labels[LABEL_SATURATION])) { - return self->priv->delegate->saturation(); - } else { - GST_WARNING_OBJECT(self, "Unknown colorbalance channel %s", channel->label); - } - - return 0; -} - -static GstColorBalanceType -gst_qt_quick2_video_sink_colorbalance_get_balance_type (GstColorBalance * balance) -{ - Q_UNUSED(balance); - return GST_COLOR_BALANCE_HARDWARE; -} - -static void -gst_qt_quick2_video_sink_colorbalance_init(GstColorBalanceInterface *iface, gpointer data) -{ - Q_UNUSED(data); - iface->list_channels = gst_qt_quick2_video_sink_colorbalance_list_channels; - iface->set_value = gst_qt_quick2_video_sink_colorbalance_set_value; - iface->get_value = gst_qt_quick2_video_sink_colorbalance_get_value; - iface->get_balance_type = gst_qt_quick2_video_sink_colorbalance_get_balance_type; -} - -//------------------------------ - -static void -gst_qt_quick2_video_sink_class_init (GstQtQuick2VideoSinkClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = gst_qt_quick2_video_sink_finalize; - gobject_class->set_property = gst_qt_quick2_video_sink_set_property; - gobject_class->get_property = gst_qt_quick2_video_sink_get_property; - - GstElementClass *element_class = GST_ELEMENT_CLASS(klass); - element_class->change_state = gst_qt_quick2_video_sink_change_state; - - GstBaseSinkClass *base_sink_class = GST_BASE_SINK_CLASS(klass); - base_sink_class->set_caps = gst_qt_quick2_video_sink_set_caps; - - GstVideoSinkClass *video_sink_class = GST_VIDEO_SINK_CLASS(klass); - video_sink_class->show_frame = gst_qt_quick2_video_sink_show_frame; - - GstQtQuick2VideoSinkClass *qtquick2_class = GST_QT_QUICK2_VIDEO_SINK_CLASS(klass); - qtquick2_class->update_node = gst_qt_quick2_video_sink_update_node; - - /** - * GstQtQuick2VideoSink::pixel-aspect-ratio - * - * The pixel aspect ratio of the display device. - **/ - g_object_class_install_property(gobject_class, PROP_PIXEL_ASPECT_RATIO, - g_param_spec_string("pixel-aspect-ratio", "Pixel aspect ratio", - "The pixel aspect ratio of the display device", - "1/1", static_cast(G_PARAM_READWRITE))); - - /** - * GstQtQuick2VideoSink::force-aspect-ratio - * - * If set to TRUE, the sink will scale the video respecting its original aspect ratio - * and any remaining space will be filled with black. - * If set to FALSE, the sink will scale the video to fit the whole drawing area. - **/ - g_object_class_install_property(gobject_class, PROP_FORCE_ASPECT_RATIO, - g_param_spec_boolean("force-aspect-ratio", "Force aspect ratio", - "When enabled, scaling will respect original aspect ratio", - FALSE, static_cast(G_PARAM_READWRITE))); - - g_object_class_install_property(gobject_class, PROP_CONTRAST, - g_param_spec_int("contrast", "Contrast", "The contrast of the video", - -100, 100, 0, static_cast(G_PARAM_READWRITE))); - - g_object_class_install_property(gobject_class, PROP_BRIGHTNESS, - g_param_spec_int("brightness", "Brightness", "The brightness of the video", - -100, 100, 0, static_cast(G_PARAM_READWRITE))); - - g_object_class_install_property(gobject_class, PROP_HUE, - g_param_spec_int("hue", "Hue", "The hue of the video", - -100, 100, 0, static_cast(G_PARAM_READWRITE))); - - g_object_class_install_property(gobject_class, PROP_SATURATION, - g_param_spec_int("saturation", "Saturation", "The saturation of the video", - -100, 100, 0, static_cast(G_PARAM_READWRITE))); - - - /** - * GstQtQuick2VideoSink::update-node - * @node: The QSGNode to update - * @x: The x coordinate of the target area rectangle - * @y: The y coordinate of the target area rectangle - * @width: The width of the target area rectangle - * @height: The height of the target area rectangle - * @returns: The updated QGSNode - * - * This is an action signal that you can call from your QQuickItem subclass - * inside its updateNode function to render the video. It takes a QSGNode* - * and the item's area rectangle as arguments. You should schedule to call - * this function to repaint the surface whenever the ::update signal is - * emitted. - * - * Note that the x,y,width and height arguments are actually qreal. - * This means that on architectures like arm they will be float instead - * of double. You should cast the arguments to qreal if they are not - * already when emitting this signal. - */ - - s_signals[ACTION_UPDATE_NODE] = - g_signal_new("update-node", G_TYPE_FROM_CLASS(klass), - static_cast(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION), - G_STRUCT_OFFSET(GstQtQuick2VideoSinkClass, update_node), - nullptr, nullptr, - qRealIsDouble() ? - g_cclosure_user_marshal_POINTER__POINTER_DOUBLE_DOUBLE_DOUBLE_DOUBLE : - g_cclosure_user_marshal_POINTER__POINTER_FLOAT_FLOAT_FLOAT_FLOAT, - G_TYPE_POINTER, 5, - G_TYPE_POINTER, G_TYPE_QREAL, G_TYPE_QREAL, G_TYPE_QREAL, G_TYPE_QREAL); - - /** - * GstQtQuick2VideoSink::update - * - * This signal is emitted when the surface should be repainted. It should - * be connected to QQuickItem::update(). - */ - s_signals[SIGNAL_UPDATE] = - g_signal_new("update", G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - 0, nullptr, nullptr, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - g_type_class_add_private (klass, sizeof (GstQtQuick2VideoSinkPrivate)); - - static GstStaticPadTemplate sink_pad_template = - GST_STATIC_PAD_TEMPLATE("sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (CAPS_FORMATS)) - ); - - gst_element_class_add_pad_template( - element_class, gst_static_pad_template_get(&sink_pad_template)); - - gst_element_class_set_details_simple(element_class, - "QtQuick2 video sink", "Sink/Video", - "A video sink that can draw on a QQuickItem", - "George Kiagiadakis "); -} diff --git a/src/VideoStreaming/gstqtvideosink/gstqtquick2videosink.h b/src/VideoStreaming/gstqtvideosink/gstqtquick2videosink.h deleted file mode 100644 index 900e682578d578216fd35a201489671f3b7137e8..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/gstqtquick2videosink.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - Copyright (C) 2013 Collabora Ltd. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/** - * @file - * @brief Extracted from QtGstreamer to avoid overly complex dependency - * @author Gus Grubba - */ - -#pragma once - -#include -#include - -#define GST_TYPE_QT_QUICK2_VIDEO_SINK \ - (gst_qt_quick2_video_sink_get_type ()) -#define GST_QT_QUICK2_VIDEO_SINK(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_QT_QUICK2_VIDEO_SINK, GstQtQuick2VideoSink)) -#define GST_IS_QT_QUICK2_VIDEO_SINK(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_QT_QUICK2_VIDEO_SINK)) -#define GST_QT_QUICK2_VIDEO_SINK_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_QT_QUICK2_VIDEO_SINK, GstQtQuick2VideoSinkClass)) -#define GST_IS_QT_QUICK2_VIDEO_SINK_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_QT_QUICK2_VIDEO_SINK)) -#define GST_QT_QUICK2_VIDEO_SINK_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_QT_QUICK2_VIDEO_SINK, GstQtQuick2VideoSinkClass)) - -typedef struct _GstQtQuick2VideoSink GstQtQuick2VideoSink; -typedef struct _GstQtQuick2VideoSinkClass GstQtQuick2VideoSinkClass; -typedef struct _GstQtQuick2VideoSinkPrivate GstQtQuick2VideoSinkPrivate; - -struct _GstQtQuick2VideoSink -{ - GstVideoSink parent_instance; - GstQtQuick2VideoSinkPrivate *priv; -}; - -struct _GstQtQuick2VideoSinkClass -{ - GstVideoSinkClass parent_class; - - gpointer (*update_node)(GstQtQuick2VideoSink *self, - gpointer node, qreal x, qreal y, qreal w, qreal h); -}; - -GType gst_qt_quick2_video_sink_get_type (void); - diff --git a/src/VideoStreaming/gstqtvideosink/gstqtvideosink.cpp b/src/VideoStreaming/gstqtvideosink/gstqtvideosink.cpp deleted file mode 100644 index 9e1220f4e24b1f5798febd062c5defc1c4656353..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/gstqtvideosink.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* - Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). - Copyright (C) 2011-2012 Collabora Ltd. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License version 2.1 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/** - * @file - * @brief Extracted from QtGstreamer to avoid overly complex dependency - * @author Gus Grubba - */ - -#include "gstqtvideosink.h" -#include "gstqtvideosinkmarshal.h" -#include "delegates/qtvideosinkdelegate.h" - - -guint GstQtVideoSink::s_signals[]; - -DEFINE_TYPE(GstQtVideoSink, GST_TYPE_QT_VIDEO_SINK_BASE) - -//------------------------------ - -void GstQtVideoSink::emit_update(gpointer sink) -{ - g_signal_emit(sink, GstQtVideoSink::s_signals[UPDATE_SIGNAL], 0, NULL); -} - -//------------------------------ - -void GstQtVideoSink::base_init(gpointer g_class) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS(g_class); - - gst_element_class_set_details_simple(element_class, "Qt video sink", "Sink/Video", - "A video sink that can draw on any Qt surface", - "George Kiagiadakis "); -} - -void GstQtVideoSink::class_init(gpointer g_class, gpointer class_data) -{ - Q_UNUSED(class_data); - - GstQtVideoSinkClass *qt_video_sink_class = reinterpret_cast(g_class); - qt_video_sink_class->paint = GstQtVideoSink::paint; - - /** - * GstQtVideoSink::paint - * @painter: A valid QPainter pointer that will be used to paint the video - * @x: The x coordinate of the target area rectangle - * @y: The y coordinate of the target area rectangle - * @width: The width of the target area rectangle - * @height: The height of the target area rectangle - * - * This is an action signal that you can call from your Qt surface class inside - * its paint function to render the video. It takes a QPainter* and the target - * area rectangle as arguments. You should schedule to call this function to - * repaint the surface whenever the ::update signal is emitted. - * - * Note that the x,y,width and height arguments are actually qreal. This means - * that on architectures like arm they will be float instead of double. You should - * cast the arguments to qreal if they are not already when emitting this signal. - */ - - s_signals[PAINT_SIGNAL] = - g_signal_new("paint", G_TYPE_FROM_CLASS(g_class), - static_cast(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION), - G_STRUCT_OFFSET(GstQtVideoSinkClass, paint), - nullptr, nullptr, - qRealIsDouble() ? - g_cclosure_user_marshal_VOID__POINTER_DOUBLE_DOUBLE_DOUBLE_DOUBLE : - g_cclosure_user_marshal_VOID__POINTER_FLOAT_FLOAT_FLOAT_FLOAT, - G_TYPE_NONE, 5, - G_TYPE_POINTER, G_TYPE_QREAL, G_TYPE_QREAL, G_TYPE_QREAL, G_TYPE_QREAL); - - /** - * GstQtVideoSink::update - * - * This signal is emitted when the surface should be repainted. It should - * be connected to QWidget::update() or QGraphicsItem::update() or any - * other similar function in your surface. - */ - s_signals[UPDATE_SIGNAL] = - g_signal_new("update", G_TYPE_FROM_CLASS(g_class), - G_SIGNAL_RUN_LAST, - 0, nullptr, nullptr, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -void GstQtVideoSink::init(GTypeInstance *instance, gpointer g_class) -{ - Q_UNUSED(g_class); - - GstQtVideoSinkBase *sinkBase = GST_QT_VIDEO_SINK_BASE(instance); - sinkBase->delegate = new QtVideoSinkDelegate(GST_ELEMENT(sinkBase)); -} - -//------------------------------ - -void GstQtVideoSink::paint(GstQtVideoSink *sink, gpointer painter, - qreal x, qreal y, qreal width, qreal height) -{ - GST_QT_VIDEO_SINK_BASE(sink)->delegate->paint(static_cast(painter), - QRectF(x, y, width, height)); -} diff --git a/src/VideoStreaming/gstqtvideosink/gstqtvideosink.h b/src/VideoStreaming/gstqtvideosink/gstqtvideosink.h deleted file mode 100644 index 79488cf2525e7f73f0a172bc96360744eaaa08ae..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/gstqtvideosink.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). - Copyright (C) 2011-2012 Collabora Ltd. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License version 2.1 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/** - * @file - * @brief Extracted from QtGstreamer to avoid overly complex dependency - * @author Gus Grubba - */ - -#pragma once - -#include "gstqtvideosinkbase.h" - -#define GST_TYPE_QT_VIDEO_SINK \ - (GstQtVideoSink::get_type()) - -struct GstQtVideoSink -{ -public: - GstQtVideoSinkBase parent; - - static GType get_type(); - static void emit_update(gpointer sink); - -private: - enum { - PAINT_SIGNAL, - UPDATE_SIGNAL, - LAST_SIGNAL - }; - - static void base_init(gpointer g_class); - static void class_init(gpointer g_class, gpointer class_data); - static void init(GTypeInstance *instance, gpointer g_class); - - static void paint(GstQtVideoSink *sink, gpointer painter, - qreal x, qreal y, qreal width, qreal height); - - static guint s_signals[LAST_SIGNAL]; -}; - - -struct GstQtVideoSinkClass -{ - GstQtVideoSinkBaseClass parent_class; - - /* paint action signal */ - void (*paint) (GstQtVideoSink *sink, gpointer painter, - qreal x, qreal y, qreal width, qreal height); -}; - diff --git a/src/VideoStreaming/gstqtvideosink/gstqtvideosinkbase.cpp b/src/VideoStreaming/gstqtvideosink/gstqtvideosinkbase.cpp deleted file mode 100644 index 21fdb35a6e82cd034773fab230cc9e699518c0f6..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/gstqtvideosinkbase.cpp +++ /dev/null @@ -1,221 +0,0 @@ -/* - Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). - Copyright (C) 2011-2012 Collabora Ltd. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License version 2.1 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/** - * @file - * @brief Extracted from QtGstreamer to avoid overly complex dependency - * @author Gus Grubba - */ - -#include "gstqtvideosinkbase.h" -#include "delegates/qtvideosinkdelegate.h" -#include "painters/genericsurfacepainter.h" -#include -#include - -#if Q_BYTE_ORDER == Q_BIG_ENDIAN -# define CAPS_FORMATS "{ ARGB, xRGB, RGB, RGB16 }" -#else -# define CAPS_FORMATS "{ BGRA, BGRx, RGB, RGB16 }" -#endif - -GstVideoSinkClass *GstQtVideoSinkBase::s_parent_class = nullptr; - -DEFINE_TYPE(GstQtVideoSinkBase, GST_TYPE_VIDEO_SINK) - -//------------------------------ - -void GstQtVideoSinkBase::base_init(gpointer g_class) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS(g_class); - - static GstStaticPadTemplate sink_pad_template = - GST_STATIC_PAD_TEMPLATE("sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (CAPS_FORMATS)) - ); - - gst_element_class_add_pad_template( - element_class, gst_static_pad_template_get(&sink_pad_template)); -} - -void GstQtVideoSinkBase::class_init(gpointer g_class, gpointer class_data) -{ - Q_UNUSED(class_data); - - s_parent_class = reinterpret_cast(g_type_class_peek_parent(g_class)); - - GObjectClass *object_class = G_OBJECT_CLASS(g_class); - object_class->finalize = GstQtVideoSinkBase::finalize; - object_class->set_property = GstQtVideoSinkBase::set_property; - object_class->get_property = GstQtVideoSinkBase::get_property; - - GstElementClass *element_class = GST_ELEMENT_CLASS(g_class); - element_class->change_state = GstQtVideoSinkBase::change_state; - - GstBaseSinkClass *base_sink_class = GST_BASE_SINK_CLASS(g_class); - base_sink_class->set_caps = GstQtVideoSinkBase::set_caps; - - GstVideoSinkClass *video_sink_class = GST_VIDEO_SINK_CLASS(g_class); - video_sink_class->show_frame = GstQtVideoSinkBase::show_frame; - - /** - * GstQtVideoSinkBase::pixel-aspect-ratio - * - * The pixel aspect ratio of the display device. - **/ - g_object_class_install_property(object_class, PROP_PIXEL_ASPECT_RATIO, - g_param_spec_string("pixel-aspect-ratio", "Pixel aspect ratio", - "The pixel aspect ratio of the display device", - "1/1", static_cast(G_PARAM_READWRITE))); - - /** - * GstQtVideoSinkBase::force-aspect-ratio - * - * If set to TRUE, the sink will scale the video respecting its original aspect ratio - * and any remaining space will be filled with black. - * If set to FALSE, the sink will scale the video to fit the whole drawing area. - **/ - g_object_class_install_property(object_class, PROP_FORCE_ASPECT_RATIO, - g_param_spec_boolean("force-aspect-ratio", "Force aspect ratio", - "When enabled, scaling will respect original aspect ratio", - FALSE, static_cast(G_PARAM_READWRITE))); - -} - -void GstQtVideoSinkBase::init(GTypeInstance *instance, gpointer g_class) -{ - Q_UNUSED(instance); - Q_UNUSED(g_class); - - /* sink->delegate is initialized in the subclasses */ -} - -void GstQtVideoSinkBase::finalize(GObject *object) -{ - GstQtVideoSinkBase *sink = GST_QT_VIDEO_SINK_BASE(object); - - delete sink->delegate; - sink->delegate = 0; -} - -//------------------------------ - -void GstQtVideoSinkBase::set_property(GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) -{ - GstQtVideoSinkBase *sink = GST_QT_VIDEO_SINK_BASE(object); - - switch (prop_id) { - case PROP_PIXEL_ASPECT_RATIO: - { - GValue tmp; - std::memset(&tmp, 0, sizeof(GValue)); - g_value_init(&tmp, GST_TYPE_FRACTION); - if (g_value_transform(value, &tmp)) { - int n = gst_value_get_fraction_numerator(&tmp); - int d = gst_value_get_fraction_denominator(&tmp); - sink->delegate->setPixelAspectRatio(Fraction(n, d)); - } else { - GST_WARNING_OBJECT(object, "Could not transform string to aspect ratio"); - } - g_value_unset(&tmp); - break; - } - case PROP_FORCE_ASPECT_RATIO: - sink->delegate->setForceAspectRatio(g_value_get_boolean(value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -void GstQtVideoSinkBase::get_property(GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) -{ - GstQtVideoSinkBase *sink = GST_QT_VIDEO_SINK_BASE(object); - - switch (prop_id) { - case PROP_PIXEL_ASPECT_RATIO: - { - GValue tmp; - Fraction par = sink->delegate->pixelAspectRatio(); - std::memset(&tmp, 0, sizeof(GValue)); - g_value_init(&tmp, GST_TYPE_FRACTION); - gst_value_set_fraction(&tmp, par.numerator, par.denominator); - g_value_transform(&tmp, value); - g_value_unset(&tmp); - break; - } - case PROP_FORCE_ASPECT_RATIO: - g_value_set_boolean(value, sink->delegate->forceAspectRatio()); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -//------------------------------ - -GstStateChangeReturn GstQtVideoSinkBase::change_state(GstElement *element, GstStateChange transition) -{ - GstQtVideoSinkBase *sink = GST_QT_VIDEO_SINK_BASE(element); - - switch (transition) { - case GST_STATE_CHANGE_READY_TO_PAUSED: - sink->delegate->setActive(true); - break; - case GST_STATE_CHANGE_PAUSED_TO_READY: - sink->delegate->setActive(false); - break; - default: - break; - } - - return GST_ELEMENT_CLASS(s_parent_class)->change_state(element, transition); -} - -//------------------------------ - -gboolean GstQtVideoSinkBase::set_caps(GstBaseSink *base, GstCaps *caps) -{ - GstQtVideoSinkBase *sink = GST_QT_VIDEO_SINK_BASE(base); - - GST_LOG_OBJECT(sink, "new caps %" GST_PTR_FORMAT, caps); - BufferFormat format = BufferFormat::fromCaps(caps); - if (GenericSurfacePainter::supportedPixelFormats().contains(format.videoFormat())) { - QCoreApplication::postEvent(sink->delegate, - new BaseDelegate::BufferFormatEvent(format)); - return TRUE; - } else { - return FALSE; - } -} - -//------------------------------ - -GstFlowReturn GstQtVideoSinkBase::show_frame(GstVideoSink *video_sink, GstBuffer *buffer) -{ - GstQtVideoSinkBase *sink = GST_QT_VIDEO_SINK_BASE(video_sink); - - GST_TRACE_OBJECT(sink, "Posting new buffer (%" GST_PTR_FORMAT") for rendering.", buffer); - - QCoreApplication::postEvent(sink->delegate, new BaseDelegate::BufferEvent(buffer)); - - return GST_FLOW_OK; -} diff --git a/src/VideoStreaming/gstqtvideosink/gstqtvideosinkbase.h b/src/VideoStreaming/gstqtvideosink/gstqtvideosinkbase.h deleted file mode 100644 index e53f35cfc39e35249e064535866756bb54c5a179..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/gstqtvideosinkbase.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). - Copyright (C) 2011-2012 Collabora Ltd. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License version 2.1 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/** - * @file - * @brief Extracted from QtGstreamer to avoid overly complex dependency - * @author Gus Grubba - */ - -#pragma once - -#include "gstqtvideosinkplugin.h" -#include - -#define GST_TYPE_QT_VIDEO_SINK_BASE \ - (GstQtVideoSinkBase::get_type()) -#define GST_QT_VIDEO_SINK_BASE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_QT_VIDEO_SINK_BASE, GstQtVideoSinkBase)) -#define GST_QT_VIDEO_SINK_BASE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_QT_VIDEO_SINK_BASE, GstQtVideoSinkBaseClass)) -#define GST_QT_VIDEO_SINK_BASE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_QT_VIDEO_SINK_BASE, GstQtVideoSinkBaseClass)) - -class QtVideoSinkDelegate; - -struct GstQtVideoSinkBase -{ -public: - GstVideoSink parent; - - static GType get_type(); - -private: - enum { - PROP_0, - PROP_PIXEL_ASPECT_RATIO, - PROP_FORCE_ASPECT_RATIO, - }; - - static void base_init(gpointer g_class); - static void class_init(gpointer g_class, gpointer class_data); - static void init(GTypeInstance *instance, gpointer g_class); - static void finalize(GObject *object); - - static void set_property(GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec); - static void get_property(GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec); - - static GstStateChangeReturn change_state(GstElement *element, GstStateChange transition); - - static gboolean set_caps(GstBaseSink *sink, GstCaps *caps); - - static GstFlowReturn show_frame(GstVideoSink *sink, GstBuffer *buffer); - -public: - QtVideoSinkDelegate *delegate; - -private: - static GstVideoSinkClass *s_parent_class; -}; - - -struct GstQtVideoSinkBaseClass -{ - GstVideoSinkClass parent_class; -}; - diff --git a/src/VideoStreaming/gstqtvideosink/gstqtvideosinkmarshal.c b/src/VideoStreaming/gstqtvideosink/gstqtvideosinkmarshal.c deleted file mode 100644 index 3ea35fc8088d3b586017a2781102b74aed8debba..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/gstqtvideosinkmarshal.c +++ /dev/null @@ -1,234 +0,0 @@ - -#include - -#if defined(_MSC_VER) -#pragma warning(disable: 4100) -#endif - -#ifdef G_ENABLE_DEBUG -#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) -#define g_marshal_value_peek_char(v) g_value_get_schar (v) -#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) -#define g_marshal_value_peek_int(v) g_value_get_int (v) -#define g_marshal_value_peek_uint(v) g_value_get_uint (v) -#define g_marshal_value_peek_long(v) g_value_get_long (v) -#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) -#define g_marshal_value_peek_int64(v) g_value_get_int64 (v) -#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) -#define g_marshal_value_peek_enum(v) g_value_get_enum (v) -#define g_marshal_value_peek_flags(v) g_value_get_flags (v) -#define g_marshal_value_peek_float(v) g_value_get_float (v) -#define g_marshal_value_peek_double(v) g_value_get_double (v) -#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) -#define g_marshal_value_peek_param(v) g_value_get_param (v) -#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) -#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) -#define g_marshal_value_peek_object(v) g_value_get_object (v) -#define g_marshal_value_peek_variant(v) g_value_get_variant (v) -#else /* !G_ENABLE_DEBUG */ -/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. - * Do not access GValues directly in your code. Instead, use the - * g_value_get_*() functions - */ -#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int -#define g_marshal_value_peek_char(v) (v)->data[0].v_int -#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint -#define g_marshal_value_peek_int(v) (v)->data[0].v_int -#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint -#define g_marshal_value_peek_long(v) (v)->data[0].v_long -#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong -#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 -#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 -#define g_marshal_value_peek_enum(v) (v)->data[0].v_long -#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong -#define g_marshal_value_peek_float(v) (v)->data[0].v_float -#define g_marshal_value_peek_double(v) (v)->data[0].v_double -#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer -#endif /* !G_ENABLE_DEBUG */ - - -/* VOID:POINTER,FLOAT,FLOAT,FLOAT,FLOAT (marshaller.src:1) */ -void -g_cclosure_user_marshal_VOID__POINTER_FLOAT_FLOAT_FLOAT_FLOAT (GClosure *closure, - GValue *return_value G_GNUC_UNUSED, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint G_GNUC_UNUSED, - gpointer marshal_data) -{ - typedef void (*GMarshalFunc_VOID__POINTER_FLOAT_FLOAT_FLOAT_FLOAT) (gpointer data1, - gpointer arg_1, - gfloat arg_2, - gfloat arg_3, - gfloat arg_4, - gfloat arg_5, - gpointer data2); - register GMarshalFunc_VOID__POINTER_FLOAT_FLOAT_FLOAT_FLOAT callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; - - g_return_if_fail (n_param_values == 6); - - if (G_CCLOSURE_SWAP_DATA (closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } - else - { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = (GMarshalFunc_VOID__POINTER_FLOAT_FLOAT_FLOAT_FLOAT) (marshal_data ? marshal_data : cc->callback); - - callback (data1, - g_marshal_value_peek_pointer (param_values + 1), - g_marshal_value_peek_float (param_values + 2), - g_marshal_value_peek_float (param_values + 3), - g_marshal_value_peek_float (param_values + 4), - g_marshal_value_peek_float (param_values + 5), - data2); -} - -/* VOID:POINTER,DOUBLE,DOUBLE,DOUBLE,DOUBLE (marshaller.src:2) */ -void -g_cclosure_user_marshal_VOID__POINTER_DOUBLE_DOUBLE_DOUBLE_DOUBLE (GClosure *closure, - GValue *return_value G_GNUC_UNUSED, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint G_GNUC_UNUSED, - gpointer marshal_data) -{ - typedef void (*GMarshalFunc_VOID__POINTER_DOUBLE_DOUBLE_DOUBLE_DOUBLE) (gpointer data1, - gpointer arg_1, - gdouble arg_2, - gdouble arg_3, - gdouble arg_4, - gdouble arg_5, - gpointer data2); - register GMarshalFunc_VOID__POINTER_DOUBLE_DOUBLE_DOUBLE_DOUBLE callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; - - g_return_if_fail (n_param_values == 6); - - if (G_CCLOSURE_SWAP_DATA (closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } - else - { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = (GMarshalFunc_VOID__POINTER_DOUBLE_DOUBLE_DOUBLE_DOUBLE) (marshal_data ? marshal_data : cc->callback); - - callback (data1, - g_marshal_value_peek_pointer (param_values + 1), - g_marshal_value_peek_double (param_values + 2), - g_marshal_value_peek_double (param_values + 3), - g_marshal_value_peek_double (param_values + 4), - g_marshal_value_peek_double (param_values + 5), - data2); -} - -/* POINTER:POINTER,FLOAT,FLOAT,FLOAT,FLOAT (marshaller.src:3) */ -void -g_cclosure_user_marshal_POINTER__POINTER_FLOAT_FLOAT_FLOAT_FLOAT (GClosure *closure, - GValue *return_value G_GNUC_UNUSED, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint G_GNUC_UNUSED, - gpointer marshal_data) -{ - typedef gpointer (*GMarshalFunc_POINTER__POINTER_FLOAT_FLOAT_FLOAT_FLOAT) (gpointer data1, - gpointer arg_1, - gfloat arg_2, - gfloat arg_3, - gfloat arg_4, - gfloat arg_5, - gpointer data2); - register GMarshalFunc_POINTER__POINTER_FLOAT_FLOAT_FLOAT_FLOAT callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; - gpointer v_return; - - g_return_if_fail (return_value != NULL); - g_return_if_fail (n_param_values == 6); - - if (G_CCLOSURE_SWAP_DATA (closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } - else - { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = (GMarshalFunc_POINTER__POINTER_FLOAT_FLOAT_FLOAT_FLOAT) (marshal_data ? marshal_data : cc->callback); - - v_return = callback (data1, - g_marshal_value_peek_pointer (param_values + 1), - g_marshal_value_peek_float (param_values + 2), - g_marshal_value_peek_float (param_values + 3), - g_marshal_value_peek_float (param_values + 4), - g_marshal_value_peek_float (param_values + 5), - data2); - - g_value_set_pointer (return_value, v_return); -} - -/* POINTER:POINTER,DOUBLE,DOUBLE,DOUBLE,DOUBLE (marshaller.src:4) */ -void -g_cclosure_user_marshal_POINTER__POINTER_DOUBLE_DOUBLE_DOUBLE_DOUBLE (GClosure *closure, - GValue *return_value G_GNUC_UNUSED, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint G_GNUC_UNUSED, - gpointer marshal_data) -{ - typedef gpointer (*GMarshalFunc_POINTER__POINTER_DOUBLE_DOUBLE_DOUBLE_DOUBLE) (gpointer data1, - gpointer arg_1, - gdouble arg_2, - gdouble arg_3, - gdouble arg_4, - gdouble arg_5, - gpointer data2); - register GMarshalFunc_POINTER__POINTER_DOUBLE_DOUBLE_DOUBLE_DOUBLE callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; - gpointer v_return; - - g_return_if_fail (return_value != NULL); - g_return_if_fail (n_param_values == 6); - - if (G_CCLOSURE_SWAP_DATA (closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } - else - { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = (GMarshalFunc_POINTER__POINTER_DOUBLE_DOUBLE_DOUBLE_DOUBLE) (marshal_data ? marshal_data : cc->callback); - - v_return = callback (data1, - g_marshal_value_peek_pointer (param_values + 1), - g_marshal_value_peek_double (param_values + 2), - g_marshal_value_peek_double (param_values + 3), - g_marshal_value_peek_double (param_values + 4), - g_marshal_value_peek_double (param_values + 5), - data2); - - g_value_set_pointer (return_value, v_return); -} - diff --git a/src/VideoStreaming/gstqtvideosink/gstqtvideosinkmarshal.h b/src/VideoStreaming/gstqtvideosink/gstqtvideosinkmarshal.h deleted file mode 100644 index fadef06174311273da4148794024b5b41e86c518..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/gstqtvideosinkmarshal.h +++ /dev/null @@ -1,42 +0,0 @@ - -#pragma once - -#include - -G_BEGIN_DECLS - -/* VOID:POINTER,FLOAT,FLOAT,FLOAT,FLOAT (marshaller.src:1) */ -extern void g_cclosure_user_marshal_VOID__POINTER_FLOAT_FLOAT_FLOAT_FLOAT (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); - -/* VOID:POINTER,DOUBLE,DOUBLE,DOUBLE,DOUBLE (marshaller.src:2) */ -extern void g_cclosure_user_marshal_VOID__POINTER_DOUBLE_DOUBLE_DOUBLE_DOUBLE (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); - -/* POINTER:POINTER,FLOAT,FLOAT,FLOAT,FLOAT (marshaller.src:3) */ -extern void g_cclosure_user_marshal_POINTER__POINTER_FLOAT_FLOAT_FLOAT_FLOAT (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); - -/* POINTER:POINTER,DOUBLE,DOUBLE,DOUBLE,DOUBLE (marshaller.src:4) */ -extern void g_cclosure_user_marshal_POINTER__POINTER_DOUBLE_DOUBLE_DOUBLE_DOUBLE (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); - -G_END_DECLS - - diff --git a/src/VideoStreaming/gstqtvideosink/gstqtvideosinkplugin.cpp b/src/VideoStreaming/gstqtvideosink/gstqtvideosinkplugin.cpp deleted file mode 100644 index 78e6ff34fa8bec24ae4ff75c6b702069a1a8ba70..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/gstqtvideosinkplugin.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* - Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). - Copyright (C) 2011 Collabora Ltd. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License version 2.1 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/** - * @file - * @brief Extracted from QtGstreamer to avoid overly complex dependency - * @author Gus Grubba - */ - -#include "gstqtvideosinkplugin.h" -#include "gstqtvideosink.h" -#include "gstqtglvideosink.h" -#include "gstqwidgetvideosink.h" - -#define PACKAGE "mini-qt-gstreamer" -#define PACKAGE_NAME "QgcQtGStreamer" -#define PACKAGE_ORIGIN "http://gstreamer.freedesktop.org/" -#define PACKAGE_VERSION "1.2.0" - -#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) -# include "gstqtquick2videosink.h" -#endif - -GST_DEBUG_CATEGORY(gst_qt5gstvideosink_debug); - -/* entry point to initialize the plug-in */ -static gboolean plugin_init(GstPlugin *plugin) -{ - GST_DEBUG_CATEGORY_INIT(gst_qt5gstvideosink_debug, - G_STRINGIFY(QGC_VIDEOSINK_PLUGIN), 0, - "Debug category for GstQtVideoSink"); - - if(!gst_element_register(plugin, G_STRINGIFY(QGC_VIDEOSINK_PLUGIN), - GST_RANK_NONE, GST_TYPE_QT_VIDEO_SINK)) { - GST_ERROR("Failed to register " G_STRINGIFY(QGC_VIDEOSINK_PLUGIN)); - return FALSE; - } -#ifndef GST_QT_VIDEO_SINK_NO_OPENGL - if(!gst_element_register(plugin, G_STRINGIFY(QTGLVIDEOSINK_NAME), - GST_RANK_NONE, GST_TYPE_QT_GL_VIDEO_SINK)) { - GST_ERROR("Failed to register " G_STRINGIFY(QTGLVIDEOSINK_NAME)); - return FALSE; - } -#endif - if(!gst_element_register(plugin, G_STRINGIFY(QWIDGETVIDEOSINK_NAME), - GST_RANK_NONE, GST_TYPE_QWIDGET_VIDEO_SINK)) { - GST_ERROR("Failed to register " G_STRINGIFY(QWIDGETVIDEOSINK_NAME)); - return FALSE; - } - -#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) - if (!gst_element_register(plugin, "qtquick2videosink", - GST_RANK_NONE, GST_TYPE_QT_QUICK2_VIDEO_SINK)) { - GST_ERROR("Failed to register qtquick2videosink"); - return FALSE; - } -#endif - - return TRUE; -} - -GST_PLUGIN_DEFINE ( - GST_VERSION_MAJOR, - GST_VERSION_MINOR, - QGC_VIDEOSINK_PLUGIN, - "A video sink that can draw on any Qt surface", - plugin_init, - PACKAGE_VERSION, - "LGPL", - PACKAGE_NAME, - PACKAGE_ORIGIN -) diff --git a/src/VideoStreaming/gstqtvideosink/gstqtvideosinkplugin.h b/src/VideoStreaming/gstqtvideosink/gstqtvideosinkplugin.h deleted file mode 100644 index 2b4c7ed319f766218230f3825a96ec7c96d6cfab..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/gstqtvideosinkplugin.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). - Copyright (C) 2011 Collabora Ltd. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License version 2.1 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/** - * @file - * @brief Extracted from QtGstreamer to avoid overly complex dependency - * @author Gus Grubba - */ - -#pragma once - -#include -#include - -GST_DEBUG_CATEGORY_EXTERN(gst_qt5gstvideosink_debug); -#define GST_CAT_DEFAULT gst_qt5gstvideosink_debug - - -#define DEFINE_TYPE_FULL(cpp_type, type_name, parent_type, additional_initializations) \ - GType cpp_type::get_type() \ - { \ - static volatile gsize gonce_data = 0; \ - if (g_once_init_enter(&gonce_data)) { \ - GType type = 0; \ - GTypeInfo info; \ - info.class_size = sizeof(cpp_type##Class); \ - info.base_init = &cpp_type::base_init; \ - info.base_finalize = NULL; \ - info.class_init = &cpp_type::class_init; \ - info.class_finalize = NULL; \ - info.class_data = NULL; \ - info.instance_size = sizeof(cpp_type); \ - info.n_preallocs = 0; \ - info.instance_init = &cpp_type::init; \ - info.value_table = 0; \ - type = g_type_register_static(parent_type, g_intern_static_string(type_name), &info, (GTypeFlags)0); \ - additional_initializations(type); \ - g_once_init_leave(&gonce_data, (gsize) type); \ - } \ - return (GType) gonce_data; \ - } - -// To allow qt4 and qt5 versions of the plugin to be installed at the same time, -// use a different name for their GType, so that the glib type system can handle -// both plugins being loaded by the gstreamer registry -#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) -# define DEFINE_TYPE(cpp_type, parent_type) \ - DEFINE_TYPE_FULL(cpp_type, #cpp_type "_qt5", parent_type, Q_UNUSED) -# define DEFINE_TYPE_WITH_CODE(cpp_type, parent_type, additional_initializations) \ - DEFINE_TYPE_FULL(cpp_type, #cpp_type "_qt5", parent_type, additional_initializations) -#else -# define DEFINE_TYPE(cpp_type, parent_type) \ - DEFINE_TYPE_FULL(cpp_type, #cpp_type, parent_type, Q_UNUSED) -# define DEFINE_TYPE_WITH_CODE(cpp_type, parent_type, additional_initializations) \ - DEFINE_TYPE_FULL(cpp_type, #cpp_type, parent_type, additional_initializations) -#endif - -inline bool qRealIsDouble() { return sizeof(qreal) == sizeof(double); } -#define G_TYPE_QREAL qRealIsDouble() ? G_TYPE_DOUBLE : G_TYPE_FLOAT - - diff --git a/src/VideoStreaming/gstqtvideosink/gstqwidgetvideosink.cpp b/src/VideoStreaming/gstqtvideosink/gstqwidgetvideosink.cpp deleted file mode 100644 index 5c6b9abfb0d7a79bd7d0cc1701e91acff4d37236..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/gstqwidgetvideosink.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - Copyright (C) 2010 George Kiagiadakis - Copyright (C) 2012 Collabora Ltd. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/** - * @file - * @brief Extracted from QtGstreamer to avoid overly complex dependency - * @author Gus Grubba - */ - -#include "gstqwidgetvideosink.h" -#include "delegates/qwidgetvideosinkdelegate.h" - -DEFINE_TYPE(GstQWidgetVideoSink, GST_TYPE_QT_VIDEO_SINK_BASE) - -//------------------------------ - -void GstQWidgetVideoSink::base_init(gpointer gclass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS(gclass); - - gst_element_class_set_details_simple(element_class, "QWidget video sink", "Sink/Video", - "A video sink that draws on a QWidget using QPainter", - "George Kiagiadakis "); -} - -void GstQWidgetVideoSink::class_init(gpointer g_class, gpointer class_data) -{ - Q_UNUSED(class_data); - - GObjectClass *gobject_class = G_OBJECT_CLASS(g_class); - gobject_class->set_property = GstQWidgetVideoSink::set_property; - gobject_class->get_property = GstQWidgetVideoSink::get_property; - - /** - * GstQWidgetVideoSink::widget - * - * This property holds a pointer to the QWidget on which the sink will paint the video. - * You can set this property at any time, even if the element is in PLAYING - * state. You can also set this property to NULL at any time to release - * the widget. In this case, qwidgetvideosink will behave like a fakesink, - * i.e. it will silently drop all the frames that it receives. It is also safe - * to delete the widget that has been set as this property; the sink will be - * signaled and this property will automatically be set to NULL. - **/ - g_object_class_install_property(gobject_class, PROP_WIDGET, - g_param_spec_pointer("widget", "Widget", - "The widget on which this element will paint the video", - static_cast(G_PARAM_READWRITE))); -} - -void GstQWidgetVideoSink::init(GTypeInstance *instance, gpointer g_class) -{ - Q_UNUSED(g_class); - - GstQtVideoSinkBase *sinkBase = GST_QT_VIDEO_SINK_BASE(instance); - sinkBase->delegate = new QWidgetVideoSinkDelegate(GST_ELEMENT(sinkBase)); -} - -void GstQWidgetVideoSink::set_property(GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) -{ - GstQtVideoSinkBase *sinkBase = GST_QT_VIDEO_SINK_BASE(object); - QWidgetVideoSinkDelegate *delegate = static_cast(sinkBase->delegate); - - switch (prop_id) { - case PROP_WIDGET: - delegate->setWidget(static_cast(g_value_get_pointer(value))); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -void GstQWidgetVideoSink::get_property(GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) -{ - GstQtVideoSinkBase *sinkBase = GST_QT_VIDEO_SINK_BASE(object); - QWidgetVideoSinkDelegate *delegate = static_cast(sinkBase->delegate); - - switch (prop_id) { - case PROP_WIDGET: - g_value_set_pointer(value, delegate->widget()); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} diff --git a/src/VideoStreaming/gstqtvideosink/gstqwidgetvideosink.h b/src/VideoStreaming/gstqtvideosink/gstqwidgetvideosink.h deleted file mode 100644 index 6218e42efbb597dc8b12b026f25f3f678bf1c09b..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/gstqwidgetvideosink.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - Copyright (C) 2010 George Kiagiadakis - Copyright (C) 2012 Collabora Ltd. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/** - * @file - * @brief Extracted from QtGstreamer to avoid overly complex dependency - * @author Gus Grubba - */ - -#pragma once - -#include "gstqtvideosinkbase.h" - -#define GST_TYPE_QWIDGET_VIDEO_SINK \ - (GstQWidgetVideoSink::get_type()) - -struct GstQWidgetVideoSink -{ -public: - GstQtVideoSinkBase parent; - - static GType get_type(); - -private: - enum { - PROP_0, - PROP_WIDGET - }; - - static void base_init(gpointer g_class); - static void class_init(gpointer g_class, gpointer class_data); - static void init(GTypeInstance *instance, gpointer g_class); - - static void set_property(GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec); - static void get_property(GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec); -}; - -struct GstQWidgetVideoSinkClass -{ - GstQtVideoSinkBaseClass parent_class; -}; - diff --git a/src/VideoStreaming/gstqtvideosink/marshaller.src b/src/VideoStreaming/gstqtvideosink/marshaller.src deleted file mode 100644 index 8bc7d1be0e260e023a61961865c8e03a470adf22..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/marshaller.src +++ /dev/null @@ -1,4 +0,0 @@ -VOID:POINTER,FLOAT,FLOAT,FLOAT,FLOAT -VOID:POINTER,DOUBLE,DOUBLE,DOUBLE,DOUBLE -POINTER:POINTER,FLOAT,FLOAT,FLOAT,FLOAT -POINTER:POINTER,DOUBLE,DOUBLE,DOUBLE,DOUBLE diff --git a/src/VideoStreaming/gstqtvideosink/painters/abstractsurfacepainter.h b/src/VideoStreaming/gstqtvideosink/painters/abstractsurfacepainter.h deleted file mode 100644 index 358d071354239c578957a29b68197ed6a1641f9c..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/painters/abstractsurfacepainter.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). - Copyright (C) 2011-2012 Collabora Ltd. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License version 2.1 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/** - * @file - * @brief Extracted from QtGstreamer to avoid overly complex dependency - * @author Gus Grubba - */ - -#pragma once - -#include "../utils/bufferformat.h" -#include - -class QPainter; - -/** Common interface for all the painters */ -class AbstractSurfacePainter -{ -public: - virtual ~AbstractSurfacePainter() {} - - virtual bool supportsFormat(GstVideoFormat format) const = 0; - - virtual void init(const BufferFormat & format) = 0; - virtual void cleanup() = 0; - - virtual void paint(quint8 *data, const BufferFormat & frameFormat, - QPainter *painter, const PaintAreas & areas) = 0; - - virtual void updateColors(int brightness, int contrast, int hue, int saturation) = 0; -}; - diff --git a/src/VideoStreaming/gstqtvideosink/painters/genericsurfacepainter.cpp b/src/VideoStreaming/gstqtvideosink/painters/genericsurfacepainter.cpp deleted file mode 100644 index e6688b67c8e9d0e171f1db788ac5dd79e1967bdc..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/painters/genericsurfacepainter.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/* - Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). - Copyright (C) 2011-2012 Collabora Ltd. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License version 2.1 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/** - * @file - * @brief Extracted from QtGstreamer to avoid overly complex dependency - * @author Gus Grubba - */ - -#include "genericsurfacepainter.h" -#include - -GenericSurfacePainter::GenericSurfacePainter() - : m_imageFormat(QImage::Format_Invalid) -{ -} - -//static -QSet GenericSurfacePainter::supportedPixelFormats() -{ - return QSet({ -#if Q_BYTE_ORDER == Q_BIG_ENDIAN - GST_VIDEO_FORMAT_ARGB, - GST_VIDEO_FORMAT_xRGB, -#else - GST_VIDEO_FORMAT_BGRA, - GST_VIDEO_FORMAT_BGRx, -#endif - GST_VIDEO_FORMAT_RGB, - GST_VIDEO_FORMAT_RGB16, - }); -} - -void GenericSurfacePainter::init(const BufferFormat &format) -{ - switch (format.videoFormat()) { - // QImage is shitty and reads integers instead of bytes, - // thus it is affected by the host's endianness -#if Q_BYTE_ORDER == Q_BIG_ENDIAN - case GST_VIDEO_FORMAT_ARGB: -#else - case GST_VIDEO_FORMAT_BGRA: -#endif - m_imageFormat = QImage::Format_ARGB32; - break; -#if Q_BYTE_ORDER == Q_BIG_ENDIAN - case GST_VIDEO_FORMAT_xRGB: -#else - case GST_VIDEO_FORMAT_BGRx: -#endif - m_imageFormat = QImage::Format_RGB32; - break; - //16-bit RGB formats use host's endianness in GStreamer - //FIXME-0.11 do endianness checks like above if semantics have changed - case GST_VIDEO_FORMAT_RGB16: - m_imageFormat = QImage::Format_RGB16; - break; - //This is not affected by endianness - case GST_VIDEO_FORMAT_RGB: - m_imageFormat = QImage::Format_RGB888; - break; - default: - throw QString("Unsupported format"); - } -} - -void GenericSurfacePainter::cleanup() -{ - m_imageFormat = QImage::Format_Invalid; -} - -void GenericSurfacePainter::paint(quint8 *data, - const BufferFormat & frameFormat, - QPainter *painter, - const PaintAreas & areas) -{ - Q_ASSERT(m_imageFormat != QImage::Format_Invalid); - - QImage image( - data, - frameFormat.frameSize().width(), - frameFormat.frameSize().height(), - frameFormat.bytesPerLine(), - m_imageFormat); - - QRectF sourceRect = areas.sourceRect; - sourceRect.setX(sourceRect.x() * frameFormat.frameSize().width()); - sourceRect.setY(sourceRect.y() * frameFormat.frameSize().height()); - sourceRect.setWidth(sourceRect.width() * frameFormat.frameSize().width()); - sourceRect.setHeight(sourceRect.height() * frameFormat.frameSize().height()); - - painter->fillRect(areas.blackArea1, Qt::black); - painter->drawImage(areas.videoArea, image, sourceRect); - painter->fillRect(areas.blackArea2, Qt::black); -} - -void GenericSurfacePainter::updateColors(int, int, int, int) -{ -} diff --git a/src/VideoStreaming/gstqtvideosink/painters/genericsurfacepainter.h b/src/VideoStreaming/gstqtvideosink/painters/genericsurfacepainter.h deleted file mode 100644 index bf5e77185fdca29c51adca8662a9f37feb7e1f0e..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/painters/genericsurfacepainter.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). - Copyright (C) 2011 Collabora Ltd. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License version 2.1 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/** - * @file - * @brief Extracted from QtGstreamer to avoid overly complex dependency - * @author Gus Grubba - */ - -#pragma once - -#include "abstractsurfacepainter.h" -#include -#include - -/** - * Generic painter that paints using the QPainter API. - * No colorspace conversion is done and no colors adjustment either. - */ -class GenericSurfacePainter : public AbstractSurfacePainter -{ -public: - GenericSurfacePainter(); - - static QSet supportedPixelFormats(); - - virtual bool supportsFormat(GstVideoFormat format) const { - return supportedPixelFormats().contains(format); - } - - virtual void init(const BufferFormat &format); - virtual void cleanup(); - - virtual void paint(quint8 *data, const BufferFormat & frameFormat, - QPainter *painter, const PaintAreas & areas); - - virtual void updateColors(int brightness, int contrast, int hue, int saturation); - -private: - QImage::Format m_imageFormat; -}; - diff --git a/src/VideoStreaming/gstqtvideosink/painters/openglsurfacepainter.cpp b/src/VideoStreaming/gstqtvideosink/painters/openglsurfacepainter.cpp deleted file mode 100644 index 7217eb970ff5ee29a649d4a8e12c0a36b794cbae..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/painters/openglsurfacepainter.cpp +++ /dev/null @@ -1,821 +0,0 @@ -/* - Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). - Copyright (C) 2011-2012 Collabora Ltd. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License version 2.1 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/** - * @file - * @brief Extracted from QtGstreamer to avoid overly complex dependency - * @author Gus Grubba - */ - -#include "openglsurfacepainter.h" -#include - -#include "glutils.h" - -#ifndef GL_TEXTURE0 -# define GL_TEXTURE0 0x84C0 -# define GL_TEXTURE1 0x84C1 -# define GL_TEXTURE2 0x84C2 -#endif - -#ifndef GL_PROGRAM_ERROR_STRING_ARB -# define GL_PROGRAM_ERROR_STRING_ARB 0x8874 -#endif - -#ifndef GL_UNSIGNED_SHORT_5_6_5 -# define GL_UNSIGNED_SHORT_5_6_5 33635 -#endif - -#ifndef GL_CLAMP_TO_EDGE -# define GL_CLAMP_TO_EDGE 0x812F -#endif - -#define QRECT_TO_GLMATRIX(rect) \ - { \ - GLfloat(rect.left()) , GLfloat(rect.bottom() + 1), \ - GLfloat(rect.right() + 1), GLfloat(rect.bottom() + 1), \ - GLfloat(rect.left()) , GLfloat(rect.top()), \ - GLfloat(rect.right() + 1), GLfloat(rect.top()) \ - } - -OpenGLSurfacePainter::OpenGLSurfacePainter() - : m_textureFormat(0) - , m_textureInternalFormat(0) - , m_textureType(0) - , m_textureCount(0) - , m_videoColorMatrix(GST_VIDEO_COLOR_MATRIX_UNKNOWN) -{ -#ifndef QT_OPENGL_ES - glActiveTexture = (_glActiveTexture) QGLContext::currentContext()->getProcAddress(QStringLiteral("glActiveTexture")); -#endif -} - -//static -QSet OpenGLSurfacePainter::supportedPixelFormats() -{ - return QSet({ - //also handled by the generic painter on LE - GST_VIDEO_FORMAT_BGRA, - GST_VIDEO_FORMAT_BGRx, - - //also handled by the generic painter on BE - GST_VIDEO_FORMAT_ARGB, - GST_VIDEO_FORMAT_xRGB, - - //also handled by the generic painter everywhere - GST_VIDEO_FORMAT_RGB, - GST_VIDEO_FORMAT_RGB16, - - //not handled by the generic painter - GST_VIDEO_FORMAT_BGR, - GST_VIDEO_FORMAT_v308, - GST_VIDEO_FORMAT_AYUV, - GST_VIDEO_FORMAT_YV12, - GST_VIDEO_FORMAT_I420, - }); -} - -void OpenGLSurfacePainter::updateColors(int brightness, int contrast, int hue, int saturation) -{ - const qreal b = brightness / 200.0; - const qreal c = contrast / 100.0 + 1.0; - const qreal h = hue / 100.0; - const qreal s = saturation / 100.0 + 1.0; - - const qreal cosH = qCos(M_PI * h); - const qreal sinH = qSin(M_PI * h); - - const qreal h11 = 0.787 * cosH - 0.213 * sinH + 0.213; - const qreal h21 = -0.213 * cosH + 0.143 * sinH + 0.213; - const qreal h31 = -0.213 * cosH - 0.787 * sinH + 0.213; - - const qreal h12 = -0.715 * cosH - 0.715 * sinH + 0.715; - const qreal h22 = 0.285 * cosH + 0.140 * sinH + 0.715; - const qreal h32 = -0.715 * cosH + 0.715 * sinH + 0.715; - - const qreal h13 = -0.072 * cosH + 0.928 * sinH + 0.072; - const qreal h23 = -0.072 * cosH - 0.283 * sinH + 0.072; - const qreal h33 = 0.928 * cosH + 0.072 * sinH + 0.072; - - const qreal sr = (1.0 - s) * 0.3086; - const qreal sg = (1.0 - s) * 0.6094; - const qreal sb = (1.0 - s) * 0.0820; - - const qreal sr_s = sr + s; - const qreal sg_s = sg + s; - const qreal sb_s = sr + s; - - const float m4 = (s + sr + sg + sb) * (0.5 - 0.5 * c + b); - - m_colorMatrix(0, 0) = c * (sr_s * h11 + sg * h21 + sb * h31); - m_colorMatrix(0, 1) = c * (sr_s * h12 + sg * h22 + sb * h32); - m_colorMatrix(0, 2) = c * (sr_s * h13 + sg * h23 + sb * h33); - m_colorMatrix(0, 3) = m4; - - m_colorMatrix(1, 0) = c * (sr * h11 + sg_s * h21 + sb * h31); - m_colorMatrix(1, 1) = c * (sr * h12 + sg_s * h22 + sb * h32); - m_colorMatrix(1, 2) = c * (sr * h13 + sg_s * h23 + sb * h33); - m_colorMatrix(1, 3) = m4; - - m_colorMatrix(2, 0) = c * (sr * h11 + sg * h21 + sb_s * h31); - m_colorMatrix(2, 1) = c * (sr * h12 + sg * h22 + sb_s * h32); - m_colorMatrix(2, 2) = c * (sr * h13 + sg * h23 + sb_s * h33); - m_colorMatrix(2, 3) = m4; - - m_colorMatrix(3, 0) = 0.0; - m_colorMatrix(3, 1) = 0.0; - m_colorMatrix(3, 2) = 0.0; - m_colorMatrix(3, 3) = 1.0; - - switch (m_videoColorMatrix) { -#if 0 - //I have no idea what this is - it's not needed currently in this code - case BufferFormat::YCbCr_JPEG: - m_colorMatrix *= QMatrix4x4( - 1.0, 0.000, 1.402, -0.701, - 1.0, -0.344, -0.714, 0.529, - 1.0, 1.772, 0.000, -0.886, - 0.0, 0.000, 0.000, 1.0000); - break; -#endif - case GST_VIDEO_COLOR_MATRIX_BT709: -/* - * This is bogus (Gus Grubba 20150706) - m_colorMatrix *= QMatrix4x4( - 1.164, 0.000, 1.793, -0.5727, - 1.164, -0.534, -0.213, 0.3007, - 1.164, 2.115, 0.000, -1.1302, - 0.0, 0.000, 0.000, 1.0000); - break; -*/ - case GST_VIDEO_COLOR_MATRIX_BT601: - m_colorMatrix *= QMatrix4x4( - 1.164f, 0.000f, 1.596f, -0.8708f, - 1.164f, -0.392f, -0.813f, 0.5296f, - 1.164f, 2.017f, 0.000f, -1.081f, - 0.0f, 0.000f, 0.000f, 1.0000f); - break; - default: - break; - } -} - -void OpenGLSurfacePainter::paint(quint8 *data, - const BufferFormat & /*frameFormat*/, - QPainter *painter, - const PaintAreas & areas) -{ - QOpenGLFunctionsDef *funcs = getQOpenGLFunctions(); - if (!funcs) - return; - - // if these are enabled, we need to reenable them after beginNativePainting() - // has been called, as they may get disabled - bool stencilTestEnabled = funcs->glIsEnabled(GL_STENCIL_TEST); - bool scissorTestEnabled = funcs->glIsEnabled(GL_SCISSOR_TEST); - - painter->beginNativePainting(); - - if (stencilTestEnabled) - funcs->glEnable(GL_STENCIL_TEST); - if (scissorTestEnabled) - funcs->glEnable(GL_SCISSOR_TEST); - - const GLfloat vertexCoordArray[] = QRECT_TO_GLMATRIX(areas.videoArea); - - const GLfloat txLeft = areas.sourceRect.left(); - const GLfloat txRight = areas.sourceRect.right(); - const GLfloat txTop = areas.sourceRect.top(); - const GLfloat txBottom = areas.sourceRect.bottom(); - - const GLfloat textureCoordArray[] = - { - txLeft , txBottom, - txRight, txBottom, - txLeft , txTop, - txRight, txTop - }; - - for (int i = 0; i < m_textureCount; ++i) { - funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[i]); - funcs->glTexImage2D( - GL_TEXTURE_2D, - 0, - m_textureInternalFormat, - m_textureWidths[i], - m_textureHeights[i], - 0, - m_textureFormat, - m_textureType, - data + m_textureOffsets[i]); - funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - } - - paintImpl(painter, vertexCoordArray, textureCoordArray); - - painter->endNativePainting(); - painter->fillRect(areas.blackArea1, Qt::black); - painter->fillRect(areas.blackArea2, Qt::black); -} - -void OpenGLSurfacePainter::initRgbTextureInfo( - GLenum internalFormat, GLuint format, GLenum type, const QSize &size) -{ -#ifndef QT_OPENGL_ES - //make sure we get 8 bits per component, at least on the desktop GL where we can - switch(internalFormat) { - case GL_RGBA: - internalFormat = GL_RGBA8; - break; - case GL_RGB: - internalFormat = GL_RGB8; - break; - default: - break; - } -#endif - - m_textureInternalFormat = internalFormat; - m_textureFormat = format; - m_textureType = type; - m_textureCount = 1; - m_textureWidths[0] = size.width(); - m_textureHeights[0] = size.height(); - m_textureOffsets[0] = 0; -} - -void OpenGLSurfacePainter::initYuv420PTextureInfo(const QSize &size) -{ - int bytesPerLine = (size.width() + 3) & ~3; - int bytesPerLine2 = (size.width() / 2 + 3) & ~3; - - m_textureInternalFormat = GL_LUMINANCE; - m_textureFormat = GL_LUMINANCE; - m_textureType = GL_UNSIGNED_BYTE; - m_textureCount = 3; - m_textureWidths[0] = bytesPerLine; - m_textureHeights[0] = size.height(); - m_textureOffsets[0] = 0; - m_textureWidths[1] = bytesPerLine2; - m_textureHeights[1] = size.height() / 2; - m_textureOffsets[1] = bytesPerLine * size.height(); - m_textureWidths[2] = bytesPerLine2; - m_textureHeights[2] = size.height() / 2; - m_textureOffsets[2] = bytesPerLine * size.height() + bytesPerLine2 * size.height()/2; -} - -void OpenGLSurfacePainter::initYv12TextureInfo(const QSize &size) -{ - int bytesPerLine = (size.width() + 3) & ~3; - int bytesPerLine2 = (size.width() / 2 + 3) & ~3; - - m_textureInternalFormat = GL_LUMINANCE; - m_textureFormat = GL_LUMINANCE; - m_textureType = GL_UNSIGNED_BYTE; - m_textureCount = 3; - m_textureWidths[0] = bytesPerLine; - m_textureHeights[0] = size.height(); - m_textureOffsets[0] = 0; - m_textureWidths[1] = bytesPerLine2; - m_textureHeights[1] = size.height() / 2; - m_textureOffsets[1] = bytesPerLine * size.height() + bytesPerLine2 * size.height()/2; - m_textureWidths[2] = bytesPerLine2; - m_textureHeights[2] = size.height() / 2; - m_textureOffsets[2] = bytesPerLine * size.height(); -} - -#ifndef QT_OPENGL_ES - -# ifndef GL_FRAGMENT_PROGRAM_ARB -# define GL_FRAGMENT_PROGRAM_ARB 0x8804 -# define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 -# endif - -// Interprets the RGBA texture as in fact being BGRx and paints it. -static const char *qt_arbfp_bgrxShaderProgram = - "!!ARBfp1.0\n" - "PARAM matrix[4] = { program.local[0..2]," - "{ 0.0, 0.0, 0.0, 1.0 } };\n" - "TEMP bgrx;\n" - "TEX bgrx.xyz, fragment.texcoord[0], texture[0], 2D;\n" - "MOV bgrx.w, matrix[3].w;\n" - "DP4 result.color.x, bgrx.zyxw, matrix[0];\n" - "DP4 result.color.y, bgrx.zyxw, matrix[1];\n" - "DP4 result.color.z, bgrx.zyxw, matrix[2];\n" - "END"; - -// Interprets the RGBA texture as in fact being BGRA and paints it. -static const char *qt_arbfp_bgraShaderProgram = - "!!ARBfp1.0\n" - "PARAM matrix[4] = { program.local[0..2]," - "{ 0.0, 0.0, 0.0, 1.0 } };\n" - "TEMP bgra;\n" - "TEX bgra, fragment.texcoord[0], texture[0], 2D;\n" - "MOV bgra.w, matrix[3].w;\n" - "DP4 result.color.x, bgra.zyxw, matrix[0];\n" - "DP4 result.color.y, bgra.zyxw, matrix[1];\n" - "DP4 result.color.z, bgra.zyxw, matrix[2];\n" - "TEX result.color.w, fragment.texcoord[0], texture, 2D;\n" - "END"; - -// Interprets the RGBA texture as in fact being xRGB and paints it. -static const char *qt_arbfp_xrgbShaderProgram = - "!!ARBfp1.0\n" - "PARAM matrix[4] = { program.local[0..2]," - "{ 0.0, 0.0, 0.0, 1.0 } };\n" - "TEMP xrgb;\n" - "TEX xrgb, fragment.texcoord[0], texture[0], 2D;\n" - "MOV xrgb.x, matrix[3].w;\n" - "DP4 result.color.x, xrgb.yzwx, matrix[0];\n" - "DP4 result.color.y, xrgb.yzwx, matrix[1];\n" - "DP4 result.color.z, xrgb.yzwx, matrix[2];\n" - "END"; - -// Interprets the RGBA texture as in fact being ARGB and paints it. -static const char *qt_arbfp_argbShaderProgram = - "!!ARBfp1.0\n" - "PARAM matrix[4] = { program.local[0..2]," - "{ 0.0, 0.0, 0.0, 1.0 } };\n" - "TEMP argb;\n" - "TEX argb, fragment.texcoord[0], texture[0], 2D;\n" - "MOV argb.x, matrix[3].w;\n" - "DP4 result.color.x, argb.yzwx, matrix[0];\n" - "DP4 result.color.y, argb.yzwx, matrix[1];\n" - "DP4 result.color.z, argb.yzwx, matrix[2];\n" - "TEX result.color.w, fragment.texcoord[0], texture, 2D;\n" - "END"; - -// Paints RGB frames without doing any color channel flipping. -static const char *qt_arbfp_rgbxShaderProgram = - "!!ARBfp1.0\n" - "PARAM matrix[4] = { program.local[0..2]," - "{ 0.0, 0.0, 0.0, 1.0 } };\n" - "TEMP rgb;\n" - "TEX rgb.xyz, fragment.texcoord[0], texture[0], 2D;\n" - "MOV rgb.w, matrix[3].w;\n" - "DP4 result.color.x, rgb, matrix[0];\n" - "DP4 result.color.y, rgb, matrix[1];\n" - "DP4 result.color.z, rgb, matrix[2];\n" - "END"; - -// Paints a YUV420P or YV12 frame. -static const char *qt_arbfp_yuvPlanarShaderProgram = - "!!ARBfp1.0\n" - "PARAM matrix[4] = { program.local[0..2]," - "{ 0.0, 0.0, 0.0, 1.0 } };\n" - "TEMP yuv;\n" - "TEX yuv.x, fragment.texcoord[0], texture[0], 2D;\n" - "TEX yuv.y, fragment.texcoord[0], texture[1], 2D;\n" - "TEX yuv.z, fragment.texcoord[0], texture[2], 2D;\n" - "MOV yuv.w, matrix[3].w;\n" - "DP4 result.color.x, yuv, matrix[0];\n" - "DP4 result.color.y, yuv, matrix[1];\n" - "DP4 result.color.z, yuv, matrix[2];\n" - "END"; - - - -ArbFpSurfacePainter::ArbFpSurfacePainter() - : OpenGLSurfacePainter() - , m_programId(0) -{ - const QGLContext *context = QGLContext::currentContext(); - glProgramStringARB = (_glProgramStringARB) context->getProcAddress(QStringLiteral("glProgramStringARB")); - glBindProgramARB = (_glBindProgramARB) context->getProcAddress(QStringLiteral("glBindProgramARB")); - glDeleteProgramsARB = (_glDeleteProgramsARB) context->getProcAddress(QStringLiteral("glDeleteProgramsARB")); - glGenProgramsARB = (_glGenProgramsARB) context->getProcAddress(QStringLiteral("glGenProgramsARB")); - glProgramLocalParameter4fARB = (_glProgramLocalParameter4fARB) context->getProcAddress(QStringLiteral("glProgramLocalParameter4fARB")); -} - -void ArbFpSurfacePainter::init(const BufferFormat &format) -{ - Q_ASSERT(m_textureCount == 0); - QOpenGLFunctionsDef *funcs = getQOpenGLFunctions(); - if (!funcs) - return; - - const char *program = 0; - - switch (format.videoFormat()) { - case GST_VIDEO_FORMAT_BGRx: - initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize()); - program = qt_arbfp_bgrxShaderProgram; - break; - case GST_VIDEO_FORMAT_xRGB: - initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize()); - program = qt_arbfp_xrgbShaderProgram; - break; - case GST_VIDEO_FORMAT_BGRA: - initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize()); - program = qt_arbfp_bgraShaderProgram; - break; - case GST_VIDEO_FORMAT_ARGB: - initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize()); - program = qt_arbfp_argbShaderProgram; - break; - case GST_VIDEO_FORMAT_RGB: - initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize()); - program = qt_arbfp_rgbxShaderProgram; - break; - case GST_VIDEO_FORMAT_BGR: - initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize()); - program = qt_arbfp_bgrxShaderProgram; - break; - //NOTE: unlike the other formats, this is endianness-dependent, - //but using GL_UNSIGNED_SHORT_5_6_5 ensures that it's handled correctly - case GST_VIDEO_FORMAT_RGB16: - initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, format.frameSize()); - program = qt_arbfp_rgbxShaderProgram; - break; - case GST_VIDEO_FORMAT_v308: - initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize()); - program = qt_arbfp_rgbxShaderProgram; - break; - case GST_VIDEO_FORMAT_AYUV: - initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize()); - program = qt_arbfp_argbShaderProgram; - break; - case GST_VIDEO_FORMAT_YV12: - initYv12TextureInfo(format.frameSize()); - program = qt_arbfp_yuvPlanarShaderProgram; - break; - case GST_VIDEO_FORMAT_I420: - initYuv420PTextureInfo(format.frameSize()); - program = qt_arbfp_yuvPlanarShaderProgram; - break; - default: - Q_ASSERT(false); - break; - } - - m_videoColorMatrix = format.colorMatrix(); - - glGenProgramsARB(1, &m_programId); - - GLenum glError = funcs->glGetError(); - if (glError != GL_NO_ERROR) { - throw QString("ARBfb Shader allocation error ") + - QString::number(static_cast(glError), 16); - } else { - glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_programId); - glProgramStringARB( - GL_FRAGMENT_PROGRAM_ARB, - GL_PROGRAM_FORMAT_ASCII_ARB, - qstrlen(program), - reinterpret_cast(program)); - - if ((glError = funcs->glGetError()) != GL_NO_ERROR) { - const GLubyte* errorString = funcs->glGetString(GL_PROGRAM_ERROR_STRING_ARB); - glDeleteProgramsARB(1, &m_programId); - m_textureCount = 0; - m_programId = 0; - throw QString("ARBfp Shader compile error ") + - QString::number(static_cast(glError), 16) + - reinterpret_cast(errorString); - } else { - funcs->glGenTextures(m_textureCount, m_textureIds); - } - } -} - -void ArbFpSurfacePainter::cleanup() -{ - QOpenGLFunctionsDef *funcs = getQOpenGLFunctions(); - if (funcs) - { - funcs->glDeleteTextures(m_textureCount, m_textureIds); - glDeleteProgramsARB(1, &m_programId); - } - m_textureCount = 0; - m_programId = 0; -} - -void ArbFpSurfacePainter::paintImpl(const QPainter *painter, - const GLfloat *vertexCoordArray, - const GLfloat *textureCoordArray) -{ - Q_UNUSED(painter); - QOpenGLFunctionsDef *funcs = getQOpenGLFunctions(); - if (!funcs) - return; - - funcs->glEnable(GL_FRAGMENT_PROGRAM_ARB); - glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_programId); - - glProgramLocalParameter4fARB( - GL_FRAGMENT_PROGRAM_ARB, - 0, - m_colorMatrix(0, 0), - m_colorMatrix(0, 1), - m_colorMatrix(0, 2), - m_colorMatrix(0, 3)); - glProgramLocalParameter4fARB( - GL_FRAGMENT_PROGRAM_ARB, - 1, - m_colorMatrix(1, 0), - m_colorMatrix(1, 1), - m_colorMatrix(1, 2), - m_colorMatrix(1, 3)); - glProgramLocalParameter4fARB( - GL_FRAGMENT_PROGRAM_ARB, - 2, - m_colorMatrix(2, 0), - m_colorMatrix(2, 1), - m_colorMatrix(2, 2), - m_colorMatrix(2, 3)); - - funcs->glActiveTexture(GL_TEXTURE0); - funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[0]); - - if (m_textureCount == 3) { - funcs->glActiveTexture(GL_TEXTURE1); - funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[1]); - funcs->glActiveTexture(GL_TEXTURE2); - funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[2]); - funcs->glActiveTexture(GL_TEXTURE0); - } - - funcs->glVertexPointer(2, GL_FLOAT, 0, vertexCoordArray); - funcs->glTexCoordPointer(2, GL_FLOAT, 0, textureCoordArray); - - funcs->glEnableClientState(GL_VERTEX_ARRAY); - funcs->glEnableClientState(GL_TEXTURE_COORD_ARRAY); - - funcs->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - funcs->glDisableClientState(GL_VERTEX_ARRAY); - funcs->glDisableClientState(GL_TEXTURE_COORD_ARRAY); - funcs->glDisable(GL_FRAGMENT_PROGRAM_ARB); -} - -#endif - -static const char *qt_glsl_vertexShaderProgram = - "attribute highp vec4 vertexCoordArray;\n" - "attribute highp vec2 textureCoordArray;\n" - "uniform highp mat4 positionMatrix;\n" - "varying highp vec2 textureCoord;\n" - "void main(void)\n" - "{\n" - " gl_Position = positionMatrix * vertexCoordArray;\n" - " textureCoord = textureCoordArray;\n" - "}\n"; - -// Interprets the RGBA texture as in fact being BGRx and paints it. -static const char *qt_glsl_bgrxShaderProgram = - "uniform sampler2D texRgb;\n" - "uniform mediump mat4 colorMatrix;\n" - "varying highp vec2 textureCoord;\n" - "void main(void)\n" - "{\n" - " highp vec4 color = vec4(texture2D(texRgb, textureCoord.st).bgr, 1.0);\n" - " gl_FragColor = colorMatrix * color;\n" - "}\n"; - -// Interprets the RGBA texture as in fact being BGRA and paints it. -static const char *qt_glsl_bgraShaderProgram = - "uniform sampler2D texRgb;\n" - "uniform mediump mat4 colorMatrix;\n" - "varying highp vec2 textureCoord;\n" - "void main(void)\n" - "{\n" - " highp vec4 color = vec4(texture2D(texRgb, textureCoord.st).bgr, 1.0);\n" - " color = colorMatrix * color;\n" - " gl_FragColor = vec4(color.rgb, texture2D(texRgb, textureCoord.st).a);\n" - "}\n"; - -// Interprets the RGBA texture as in fact being xRGB and paints it. -static const char *qt_glsl_xrgbShaderProgram = - "uniform sampler2D texRgb;\n" - "uniform mediump mat4 colorMatrix;\n" - "varying highp vec2 textureCoord;\n" - "void main(void)\n" - "{\n" - " highp vec4 color = vec4(texture2D(texRgb, textureCoord.st).gba, 1.0);\n" - " gl_FragColor = colorMatrix * color;\n" - "}\n"; - -// Interprets the RGBA texture as in fact being ARGB and paints it. -static const char *qt_glsl_argbShaderProgram = - "uniform sampler2D texRgb;\n" - "uniform mediump mat4 colorMatrix;\n" - "varying highp vec2 textureCoord;\n" - "void main(void)\n" - "{\n" - " highp vec4 color = vec4(texture2D(texRgb, textureCoord.st).gba, 1.0);\n" - " color = colorMatrix * color;\n" - " gl_FragColor = vec4(color.rgb, texture2D(texRgb, textureCoord.st).r);\n" - "}\n"; - -// Paints RGB frames without doing any color channel flipping. -static const char *qt_glsl_rgbxShaderProgram = - "uniform sampler2D texRgb;\n" - "uniform mediump mat4 colorMatrix;\n" - "varying highp vec2 textureCoord;\n" - "void main(void)\n" - "{\n" - " highp vec4 color = vec4(texture2D(texRgb, textureCoord.st).rgb, 1.0);\n" - " gl_FragColor = colorMatrix * color;\n" - "}\n"; - -// Paints planar yuv frames. -static const char *qt_glsl_yuvPlanarShaderProgram = - "uniform sampler2D texY;\n" - "uniform sampler2D texU;\n" - "uniform sampler2D texV;\n" - "uniform mediump mat4 colorMatrix;\n" - "varying highp vec2 textureCoord;\n" - "void main(void)\n" - "{\n" - " highp vec4 color = vec4(\n" - " texture2D(texY, textureCoord.st).r,\n" - " texture2D(texU, textureCoord.st).r,\n" - " texture2D(texV, textureCoord.st).r,\n" - " 1.0);\n" - " gl_FragColor = colorMatrix * color;\n" - "}\n"; - - -GlslSurfacePainter::GlslSurfacePainter() - : OpenGLSurfacePainter() -{ -} - -void GlslSurfacePainter::init(const BufferFormat &format) -{ - Q_ASSERT(m_textureCount == 0); - - const char *fragmentProgram = 0; - - switch (format.videoFormat()) { - case GST_VIDEO_FORMAT_BGRx: - initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize()); - fragmentProgram = qt_glsl_bgrxShaderProgram; - break; - case GST_VIDEO_FORMAT_xRGB: - initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize()); - fragmentProgram = qt_glsl_xrgbShaderProgram; - break; - case GST_VIDEO_FORMAT_BGRA: - initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize()); - fragmentProgram = qt_glsl_bgraShaderProgram; - break; - case GST_VIDEO_FORMAT_ARGB: - initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize()); - fragmentProgram = qt_glsl_argbShaderProgram; - break; - case GST_VIDEO_FORMAT_RGB: - initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize()); - fragmentProgram = qt_glsl_rgbxShaderProgram; - break; - case GST_VIDEO_FORMAT_BGR: - initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize()); - fragmentProgram = qt_glsl_bgrxShaderProgram; - break; - //NOTE: unlike the other formats, this is endianness-dependent, - //but using GL_UNSIGNED_SHORT_5_6_5 ensures that it's handled correctly - case GST_VIDEO_FORMAT_RGB16: - initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, format.frameSize()); - fragmentProgram = qt_glsl_rgbxShaderProgram; - break; - case GST_VIDEO_FORMAT_v308: - initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize()); - fragmentProgram = qt_glsl_rgbxShaderProgram; - break; - case GST_VIDEO_FORMAT_AYUV: - initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize()); - fragmentProgram = qt_glsl_argbShaderProgram; - break; - case GST_VIDEO_FORMAT_YV12: - initYv12TextureInfo(format.frameSize()); - fragmentProgram = qt_glsl_yuvPlanarShaderProgram; - break; - case GST_VIDEO_FORMAT_I420: - initYuv420PTextureInfo(format.frameSize()); - fragmentProgram = qt_glsl_yuvPlanarShaderProgram; - break; - default: - Q_ASSERT(false); - break; - } - - m_videoColorMatrix = format.colorMatrix(); - - if (!m_program.addShaderFromSourceCode(QGLShader::Vertex, qt_glsl_vertexShaderProgram)) { - throw QString("Vertex shader compile error ") + m_program.log(); - } - - if (!m_program.addShaderFromSourceCode(QGLShader::Fragment, fragmentProgram)) { - throw QString("Shader compile error ") + m_program.log(); - } - - if(!m_program.link()) { - throw QString("Shader link error ") + m_program.log(); - } - - QOpenGLFunctionsDef *funcs = getQOpenGLFunctions(); - if (funcs) - funcs->glGenTextures(m_textureCount, m_textureIds); -} - -void GlslSurfacePainter::cleanup() -{ - QOpenGLFunctionsDef *funcs = getQOpenGLFunctions(); - if (funcs) - { - funcs->glDeleteTextures(m_textureCount, m_textureIds); - m_program.removeAllShaders(); - } - m_textureCount = 0; -} - -void GlslSurfacePainter::paintImpl(const QPainter *painter, - const GLfloat *vertexCoordArray, - const GLfloat *textureCoordArray) -{ - const int deviceWidth = painter->device()->width(); - const int deviceHeight = painter->device()->height(); - - const QTransform transform = painter->deviceTransform(); - - const GLfloat wfactor = 2.0 / deviceWidth; - const GLfloat hfactor = -2.0 / deviceHeight; - - const GLfloat positionMatrix[4][4] = - { - { - /*(0,0)*/ GLfloat(wfactor * transform.m11() - transform.m13()), - /*(0,1)*/ GLfloat(hfactor * transform.m12() + transform.m13()), - /*(0,2)*/ 0.0, - /*(0,3)*/ GLfloat(transform.m13()) - }, { - /*(1,0)*/ GLfloat(wfactor * transform.m21() - transform.m23()), - /*(1,1)*/ GLfloat(hfactor * transform.m22() + transform.m23()), - /*(1,2)*/ 0.0, - /*(1,3)*/ GLfloat(transform.m23()) - }, { - /*(2,0)*/ 0.0, - /*(2,1)*/ 0.0, - /*(2,2)*/ -1.0, - /*(2,3)*/ 0.0 - }, { - /*(3,0)*/ GLfloat(wfactor * transform.dx() - transform.m33()), - /*(3,1)*/ GLfloat(hfactor * transform.dy() + transform.m33()), - /*(3,2)*/ 0.0, - /*(3,3)*/ GLfloat(transform.m33()) - } - }; - - m_program.bind(); - - m_program.enableAttributeArray("vertexCoordArray"); - m_program.enableAttributeArray("textureCoordArray"); - m_program.setAttributeArray("vertexCoordArray", vertexCoordArray, 2); - m_program.setAttributeArray("textureCoordArray", textureCoordArray, 2); - m_program.setUniformValue("positionMatrix", positionMatrix); - - QOpenGLFunctionsDef *funcs = getQOpenGLFunctions(); - if (!funcs) - return; - - if (m_textureCount == 3) { - funcs->glActiveTexture(GL_TEXTURE0); - funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[0]); - funcs->glActiveTexture(GL_TEXTURE1); - funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[1]); - funcs->glActiveTexture(GL_TEXTURE2); - funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[2]); - funcs->glActiveTexture(GL_TEXTURE0); - - m_program.setUniformValue("texY", 0); - m_program.setUniformValue("texU", 1); - m_program.setUniformValue("texV", 2); - } else { - funcs->glActiveTexture(GL_TEXTURE0); - funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[0]); - - m_program.setUniformValue("texRgb", 0); - } - m_program.setUniformValue("colorMatrix", m_colorMatrix); - - funcs->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - m_program.release(); -} diff --git a/src/VideoStreaming/gstqtvideosink/painters/openglsurfacepainter.h b/src/VideoStreaming/gstqtvideosink/painters/openglsurfacepainter.h deleted file mode 100644 index e032ae132c568919539e9dcecf4a7d2ba2aa8aac..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/painters/openglsurfacepainter.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). - Copyright (C) 2011-2012 Collabora Ltd. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License version 2.1 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/** - * @file - * @brief Extracted from QtGstreamer to avoid overly complex dependency - * @author Gus Grubba - */ - -#pragma once - -#ifndef GST_QT_VIDEO_SINK_NO_OPENGL - -#include "abstractsurfacepainter.h" -#include - -#ifndef Q_WS_MAC -# ifndef APIENTRYP -# ifdef APIENTRY -# define APIENTRYP APIENTRY * -# else -# define APIENTRY -# define APIENTRYP * -# endif -# endif -#else -# define APIENTRY -# define APIENTRYP * -#endif - -class OpenGLSurfacePainter : public AbstractSurfacePainter -{ -public: - OpenGLSurfacePainter(); - - static QSet supportedPixelFormats(); - - virtual bool supportsFormat(GstVideoFormat format) const { - return supportedPixelFormats().contains(format); - } - - virtual void updateColors(int brightness, int contrast, int hue, int saturation); - virtual void paint(quint8 *data, const BufferFormat & frameFormat, - QPainter *painter, const PaintAreas & areas); - -protected: - void initRgbTextureInfo(GLenum internalFormat, GLuint format, GLenum type, const QSize &size); - void initYuv420PTextureInfo(const QSize &size); - void initYv12TextureInfo(const QSize &size); - - virtual void paintImpl(const QPainter *painter, - const GLfloat *vertexCoordArray, - const GLfloat *textureCoordArray) = 0; - -#ifndef QT_OPENGL_ES - typedef void (APIENTRY *_glActiveTexture) (GLenum); - _glActiveTexture glActiveTexture; -#endif - - GLenum m_textureFormat; - GLuint m_textureInternalFormat; - GLenum m_textureType; - int m_textureCount; - GLuint m_textureIds[3]; - int m_textureWidths[3]; - int m_textureHeights[3]; - int m_textureOffsets[3]; - - QMatrix4x4 m_colorMatrix; - GstVideoColorMatrix m_videoColorMatrix; -}; - -#ifndef QT_OPENGL_ES - -class ArbFpSurfacePainter : public OpenGLSurfacePainter -{ -public: - ArbFpSurfacePainter(); - - virtual void init(const BufferFormat & format); - virtual void cleanup(); - -protected: - virtual void paintImpl(const QPainter *painter, - const GLfloat *vertexCoordArray, - const GLfloat *textureCoordArray); - -private: - typedef void (APIENTRY *_glProgramStringARB) (GLenum, GLenum, GLsizei, const GLvoid *); - typedef void (APIENTRY *_glBindProgramARB) (GLenum, GLuint); - typedef void (APIENTRY *_glDeleteProgramsARB) (GLsizei, const GLuint *); - typedef void (APIENTRY *_glGenProgramsARB) (GLsizei, GLuint *); - typedef void (APIENTRY *_glProgramLocalParameter4fARB) ( - GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat); - typedef void (APIENTRY *_glActiveTexture) (GLenum); - - _glProgramStringARB glProgramStringARB; - _glBindProgramARB glBindProgramARB; - _glDeleteProgramsARB glDeleteProgramsARB; - _glGenProgramsARB glGenProgramsARB; - _glProgramLocalParameter4fARB glProgramLocalParameter4fARB; - - GLuint m_programId; -}; - -#endif - -class GlslSurfacePainter : public OpenGLSurfacePainter -{ -public: - GlslSurfacePainter(); - - virtual void init(const BufferFormat & format); - virtual void cleanup(); - -protected: - virtual void paintImpl(const QPainter *painter, - const GLfloat *vertexCoordArray, - const GLfloat *textureCoordArray); - -private: - QGLShaderProgram m_program; -}; - -#endif // GST_QT_VIDEO_SINK_NO_OPENGL diff --git a/src/VideoStreaming/gstqtvideosink/painters/videomaterial.cpp b/src/VideoStreaming/gstqtvideosink/painters/videomaterial.cpp deleted file mode 100644 index 6131244207d6635aa1bb212ba9e0418c3f8b8e20..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/painters/videomaterial.cpp +++ /dev/null @@ -1,561 +0,0 @@ -/* - Copyright (C) 2011-2013 Collabora Ltd. - Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). - Copyright (C) 2013 basysKom GmbH - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License version 2.1 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/** - * @file - * @brief Extracted (and fixed) from QtGstreamer to avoid overly complex dependency - * @author Gus Grubba - */ - -#include "videomaterial.h" - -#include -#include -#include - -#include "glutils.h" - -static const char * const qtvideosink_glsl_vertexShader = - "uniform highp mat4 qt_Matrix; \n" - "attribute highp vec4 qt_VertexPosition; \n" - "attribute highp vec2 qt_VertexTexCoord; \n" - "varying highp vec2 qt_TexCoord; \n" - "void main() { \n" - " qt_TexCoord = qt_VertexTexCoord; \n" - " gl_Position = qt_Matrix * qt_VertexPosition; \n" - "}"; - -inline const char * qtvideosink_glsl_bgrxFragmentShader() -{ - return - "uniform sampler2D rgbTexture;\n" - "uniform lowp float opacity;\n" - "uniform mediump mat4 colorMatrix;\n" - "varying highp vec2 qt_TexCoord;\n" - "void main(void)\n" - "{\n" - " highp vec4 color = vec4(texture2D(rgbTexture, qt_TexCoord.st).bgr, 1.0);\n" - " gl_FragColor = colorMatrix * color * opacity;\n" - "}\n"; -} - -inline const char * qtvideosink_glsl_xrgbFragmentShader() -{ - return - "uniform sampler2D rgbTexture;\n" - "uniform lowp float opacity;\n" - "uniform mediump mat4 colorMatrix;\n" - "varying highp vec2 qt_TexCoord;\n" - "void main(void)\n" - "{\n" - " highp vec4 color = vec4(texture2D(rgbTexture, qt_TexCoord.st).gba, 1.0);\n" - " gl_FragColor = colorMatrix * color * opacity;\n" - "}\n"; -} - -inline const char * qtvideosink_glsl_rgbxFragmentShader() -{ - return - "uniform sampler2D rgbTexture;\n" - "uniform lowp float opacity;\n" - "uniform mediump mat4 colorMatrix;\n" - "varying highp vec2 qt_TexCoord;\n" - "void main(void)\n" - "{\n" - " highp vec4 color = vec4(texture2D(rgbTexture, qt_TexCoord.st).rgb, 1.0);\n" - " gl_FragColor = colorMatrix * color * opacity;\n" - "}\n"; -} - -inline const char * qtvideosink_glsl_yuvPlanarFragmentShader() -{ - return - "uniform sampler2D yTexture;\n" - "uniform sampler2D uTexture;\n" - "uniform sampler2D vTexture;\n" - "uniform mediump mat4 colorMatrix;\n" - "uniform lowp float opacity;\n" - "varying highp vec2 qt_TexCoord;\n" - "void main(void)\n" - "{\n" - " highp vec4 color = vec4(\n" - " texture2D(yTexture, qt_TexCoord.st).r,\n" - " texture2D(uTexture, qt_TexCoord.st).r,\n" - " texture2D(vTexture, qt_TexCoord.st).r,\n" - " 1.0);\n" - " gl_FragColor = colorMatrix * color * opacity;\n" - "}\n"; -} - -class VideoMaterialShader : public QSGMaterialShader -{ -public: - virtual void updateState(const RenderState &state, - QSGMaterial *newMaterial, QSGMaterial *oldMaterial) - { - Q_UNUSED(oldMaterial); - - VideoMaterial *material = static_cast(newMaterial); - if (m_id_rgbTexture > 0) { - program()->setUniformValue(m_id_rgbTexture, 0); - } else { - program()->setUniformValue(m_id_yTexture, 0); - program()->setUniformValue(m_id_uTexture, 1); - program()->setUniformValue(m_id_vTexture, 2); - } - - if (state.isOpacityDirty()) { - material->setFlag(QSGMaterial::Blending, - qFuzzyCompare(state.opacity(), 1.0f) ? false : true); - program()->setUniformValue(m_id_opacity, GLfloat(state.opacity())); - } - - if (state.isMatrixDirty()) - program()->setUniformValue(m_id_matrix, state.combinedMatrix()); - - program()->setUniformValue(m_id_colorMatrix, material->m_colorMatrix); - - material->bind(); - } - - virtual char const *const *attributeNames() const { - static const char *names[] = { - "qt_VertexPosition", - "qt_VertexTexCoord", - 0 - }; - return names; - } - -protected: - virtual void initialize() { - m_id_matrix = program()->uniformLocation("qt_Matrix"); - m_id_rgbTexture = program()->uniformLocation("rgbTexture"); - m_id_yTexture = program()->uniformLocation("yTexture"); - m_id_uTexture = program()->uniformLocation("uTexture"); - m_id_vTexture = program()->uniformLocation("vTexture"); - m_id_colorMatrix = program()->uniformLocation("colorMatrix"); - m_id_opacity = program()->uniformLocation("opacity"); - } - - virtual const char *vertexShader() const { - return qtvideosink_glsl_vertexShader; - } - - int m_id_matrix; - int m_id_rgbTexture; - int m_id_yTexture; - int m_id_uTexture; - int m_id_vTexture; - int m_id_colorMatrix; - int m_id_opacity; -}; - -template -class VideoMaterialShaderImpl : public VideoMaterialShader -{ -protected: - virtual const char *fragmentShader() const { - return FragmentShader(); - } -}; - -template -class VideoMaterialImpl : public VideoMaterial -{ -public: - virtual QSGMaterialType *type() const { - static QSGMaterialType theType; - return &theType; - } - - virtual QSGMaterialShader *createShader() const { - return new VideoMaterialShaderImpl; - } -}; - -VideoMaterial *VideoMaterial::create(const BufferFormat & format) -{ - VideoMaterial *material = nullptr; - - switch (format.videoFormat()) { - // BGRx - case GST_VIDEO_FORMAT_BGRx: - case GST_VIDEO_FORMAT_BGRA: - material = new VideoMaterialImpl; - material->initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.videoInfo()); - break; - case GST_VIDEO_FORMAT_BGR: - material = new VideoMaterialImpl; - material->initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, format.videoInfo()); - break; - - // xRGB - case GST_VIDEO_FORMAT_xRGB: - case GST_VIDEO_FORMAT_ARGB: - case GST_VIDEO_FORMAT_AYUV: - material = new VideoMaterialImpl; - material->initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.videoInfo()); - break; - - // RGBx - case GST_VIDEO_FORMAT_RGB: - case GST_VIDEO_FORMAT_v308: - material = new VideoMaterialImpl; - material->initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, format.videoInfo()); - break; - case GST_VIDEO_FORMAT_RGB16: - material = new VideoMaterialImpl; - material->initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, format.videoInfo()); - break; - - // YUV 420 planar - case GST_VIDEO_FORMAT_I420: - case GST_VIDEO_FORMAT_YV12: - material = new VideoMaterialImpl; - material->initYuv420PTextureInfo(format.videoInfo()); - break; - - default: - Q_ASSERT(false); - break; - } - - material->init(format.colorMatrix()); - return material; -} - -VideoMaterial::VideoMaterial() - : m_bufferPool(0) - , m_frame(0) - , m_textureCount(0) - , m_textureFormat(0) - , m_textureInternalFormat(0) - , m_textureType(0) - , m_colorMatrixType(GST_VIDEO_COLOR_MATRIX_UNKNOWN) -{ - memset(m_textureIds, 0, sizeof(m_textureIds)); - setFlag(Blending, false); -} - -VideoMaterial::~VideoMaterial() -{ - if (m_textureCount > 0) { - QOpenGLFunctionsDef *funcs = getQOpenGLFunctions(); - - if (funcs) { - funcs->glDeleteTextures(m_textureCount, m_textureIds); - } - } - - gst_buffer_replace(&m_frame, nullptr); -} - -int VideoMaterial::compare(const QSGMaterial *other) const -{ - const VideoMaterial *m = static_cast(other); - int d = m_textureIds[0] - m->m_textureIds[0]; - if (d || m_textureCount == 1) - return d; - else if ((d = m_textureIds[1] - m->m_textureIds[1]) != 0) - return d; - else - return m_textureIds[2] - m->m_textureIds[2]; -} - -void VideoMaterial::initRgbTextureInfo( - GLenum internalFormat, GLuint format, GLenum type, const GstVideoInfo& videoInfo) -{ -#ifndef QT_OPENGL_ES - //make sure we get 8 bits per component, at least on the desktop GL where we can - switch(internalFormat) { - case GL_RGBA: - internalFormat = GL_RGBA8; - break; - case GL_RGB: - internalFormat = GL_RGB8; - break; - default: - break; - } -#endif - - m_videoInfo = videoInfo; - - m_textureInternalFormat = internalFormat; - m_textureFormat = format; - m_textureType = type; - m_textureCount = 1; - - m_textureWidths[0] = videoInfo.width; - m_textureHeights[0] = videoInfo.height; - m_textureOffsets[0] = videoInfo.offset[0]; - m_textureStrides[0] = videoInfo.stride[0]; - m_textureAllocated[0] = false; -} - -void VideoMaterial::initYuv420PTextureInfo(const GstVideoInfo& videoInfo) -{ - m_videoInfo = videoInfo; - - m_textureInternalFormat = GL_LUMINANCE; - m_textureFormat = GL_LUMINANCE; - m_textureType = GL_UNSIGNED_BYTE; - m_textureCount = 3; - - m_textureWidths[0] = GST_VIDEO_INFO_COMP_WIDTH(&videoInfo, 0); - m_textureHeights[0] = GST_VIDEO_INFO_COMP_HEIGHT(&videoInfo, 0); - m_textureAllocated[0] = false; - - m_textureWidths[1] = GST_VIDEO_INFO_COMP_WIDTH(&videoInfo, 1); - m_textureHeights[1] = GST_VIDEO_INFO_COMP_HEIGHT(&videoInfo, 1); - m_textureAllocated[1] = false; - - m_textureWidths[2] = GST_VIDEO_INFO_COMP_WIDTH(&videoInfo, 2); - m_textureHeights[2] = GST_VIDEO_INFO_COMP_HEIGHT(&videoInfo, 2); - m_textureAllocated[2] = false; - - updateYuv420PTextureInfo(videoInfo); -} - -void VideoMaterial::updateYuv420PTextureInfo(const GstVideoInfo& videoInfo) -{ - const unsigned lumaPlane = GST_VIDEO_INFO_COMP_PLANE(&videoInfo, 0); - - m_textureOffsets[0] = GST_VIDEO_INFO_PLANE_OFFSET(&videoInfo, lumaPlane); - m_textureStrides[0] = GST_VIDEO_INFO_PLANE_STRIDE(&videoInfo, lumaPlane); - - const unsigned cbPlane = GST_VIDEO_INFO_COMP_PLANE(&videoInfo, 1); - - m_textureOffsets[1] = GST_VIDEO_INFO_PLANE_OFFSET(&videoInfo, cbPlane); - m_textureStrides[1] = GST_VIDEO_INFO_PLANE_STRIDE(&videoInfo, cbPlane); - - const unsigned crPlane = GST_VIDEO_INFO_COMP_PLANE(&videoInfo, 2); - - m_textureOffsets[2] = GST_VIDEO_INFO_PLANE_OFFSET(&videoInfo, crPlane); - m_textureStrides[2] = GST_VIDEO_INFO_PLANE_STRIDE(&videoInfo, crPlane); - -} - -void VideoMaterial::init(GstVideoColorMatrix colorMatrixType) -{ - QOpenGLFunctionsDef *funcs = getQOpenGLFunctions(); - if (funcs) - { - funcs->glGenTextures(m_textureCount, m_textureIds); - m_colorMatrixType = colorMatrixType; - updateColors(0, 0, 0, 0); - } -} - -void VideoMaterial::setCurrentFrame(GstBuffer *buffer) -{ - QMutexLocker lock(&m_frameMutex); - gst_buffer_replace(&m_frame, buffer); -} - -void VideoMaterial::updateColors(int brightness, int contrast, int hue, int saturation) -{ - const qreal b = brightness / 200.0; - const qreal c = contrast / 100.0 + 1.0; - const qreal h = hue / 100.0; - const qreal s = saturation / 100.0 + 1.0; - - const qreal cosH = qCos(M_PI * h); - const qreal sinH = qSin(M_PI * h); - - const qreal h11 = 0.787 * cosH - 0.213 * sinH + 0.213; - const qreal h21 = -0.213 * cosH + 0.143 * sinH + 0.213; - const qreal h31 = -0.213 * cosH - 0.787 * sinH + 0.213; - - const qreal h12 = -0.715 * cosH - 0.715 * sinH + 0.715; - const qreal h22 = 0.285 * cosH + 0.140 * sinH + 0.715; - const qreal h32 = -0.715 * cosH + 0.715 * sinH + 0.715; - - const qreal h13 = -0.072 * cosH + 0.928 * sinH + 0.072; - const qreal h23 = -0.072 * cosH - 0.283 * sinH + 0.072; - const qreal h33 = 0.928 * cosH + 0.072 * sinH + 0.072; - - const qreal sr = (1.0 - s) * 0.3086; - const qreal sg = (1.0 - s) * 0.6094; - const qreal sb = (1.0 - s) * 0.0820; - - const qreal sr_s = sr + s; - const qreal sg_s = sg + s; - const qreal sb_s = sr + s; - - const float m4 = (s + sr + sg + sb) * (0.5 - 0.5 * c + b); - - m_colorMatrix(0, 0) = c * (sr_s * h11 + sg * h21 + sb * h31); - m_colorMatrix(0, 1) = c * (sr_s * h12 + sg * h22 + sb * h32); - m_colorMatrix(0, 2) = c * (sr_s * h13 + sg * h23 + sb * h33); - m_colorMatrix(0, 3) = m4; - - m_colorMatrix(1, 0) = c * (sr * h11 + sg_s * h21 + sb * h31); - m_colorMatrix(1, 1) = c * (sr * h12 + sg_s * h22 + sb * h32); - m_colorMatrix(1, 2) = c * (sr * h13 + sg_s * h23 + sb * h33); - m_colorMatrix(1, 3) = m4; - - m_colorMatrix(2, 0) = c * (sr * h11 + sg * h21 + sb_s * h31); - m_colorMatrix(2, 1) = c * (sr * h12 + sg * h22 + sb_s * h32); - m_colorMatrix(2, 2) = c * (sr * h13 + sg * h23 + sb_s * h33); - m_colorMatrix(2, 3) = m4; - - m_colorMatrix(3, 0) = 0.0; - m_colorMatrix(3, 1) = 0.0; - m_colorMatrix(3, 2) = 0.0; - m_colorMatrix(3, 3) = 1.0; - - switch (m_colorMatrixType) { - case GST_VIDEO_COLOR_MATRIX_BT709: -/* - * This is bogus (Gus Grubba 20150706) - m_colorMatrix *= QMatrix4x4( - 1.164, 0.000, 1.793, -0.5727, - 1.164, -0.534, -0.213, 0.3007, - 1.164, 2.115, 0.000, -1.1302, - 0.0, 0.000, 0.000, 1.0000); - break; -*/ - case GST_VIDEO_COLOR_MATRIX_BT601: - m_colorMatrix *= QMatrix4x4( - 1.164f, 0.000f, 1.596f, -0.8708f, - 1.164f, -0.392f, -0.813f, 0.5296f, - 1.164f, 2.017f, 0.000f, -1.081f, - 0.0f, 0.000f, 0.000f, 1.0000f); - break; - default: - break; - } -} - -void VideoMaterial::bind() -{ - QOpenGLFunctionsDef *funcs = getQOpenGLFunctions(); - if (!funcs) - return; - - GstBuffer *frame = nullptr; - - m_frameMutex.lock(); - if (m_frame) - frame = gst_buffer_ref(m_frame); - m_frameMutex.unlock(); - - if (frame) { - GstMapInfo info; - gst_buffer_map(frame, &info, GST_MAP_READ); - - if (m_bufferPool != frame->pool) { - GstStructure* structure = gst_buffer_pool_get_config(frame->pool); - - if (structure != NULL) { - GstCaps* caps; - - if(gst_buffer_pool_config_get_params(structure, &caps, NULL, NULL, NULL) != FALSE) { - updateYuv420PTextureInfo(BufferFormat::fromCaps(caps).videoInfo()); - } else { - updateYuv420PTextureInfo(m_videoInfo); - } - - gst_structure_free(structure); - structure = NULL; - } else { - updateYuv420PTextureInfo(m_videoInfo); - } - - m_bufferPool = frame->pool; - } - - funcs->glActiveTexture(GL_TEXTURE1); - bindTexture(1, info.data); - funcs->glActiveTexture(GL_TEXTURE2); - bindTexture(2, info.data); - funcs->glActiveTexture(GL_TEXTURE0); // Finish with 0 as default texture unit - bindTexture(0, info.data); - gst_buffer_unmap(frame, &info); - gst_buffer_unref(frame); - } else { - funcs->glActiveTexture(GL_TEXTURE1); - funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[1]); - funcs->glActiveTexture(GL_TEXTURE2); - funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[2]); - funcs->glActiveTexture(GL_TEXTURE0); // Finish with 0 as default texture unit - funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[0]); - } -} - -void VideoMaterial::bindTexture(int i, const quint8 *data) -{ - QOpenGLFunctionsDef *funcs = getQOpenGLFunctions(); - if (!funcs) - return; - - funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[i]); - - if (!m_textureAllocated[i]) { - funcs->glTexImage2D( - GL_TEXTURE_2D, - 0, - m_textureInternalFormat, - m_textureWidths[i], - m_textureHeights[i], - 0, - m_textureFormat, - m_textureType, - NULL); - - m_textureAllocated[i] = true; - } - - if (m_textureStrides[i] != m_textureWidths[i]) { - const unsigned char* line = data + m_textureOffsets[i]; - - for (int j = 0; j < m_textureHeights[i]; j++) { - funcs->glTexSubImage2D( - GL_TEXTURE_2D, - 0, - 0, - j, - m_textureWidths[i], - 1, - m_textureFormat, - m_textureType, - line); - - line += m_textureStrides[i]; - } - } else { - funcs->glTexImage2D( - GL_TEXTURE_2D, - 0, - m_textureInternalFormat, - m_textureWidths[i], - m_textureHeights[i], - 0, - m_textureFormat, - m_textureType, - data + m_textureOffsets[i]); - } - - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); -} - diff --git a/src/VideoStreaming/gstqtvideosink/painters/videomaterial.h b/src/VideoStreaming/gstqtvideosink/painters/videomaterial.h deleted file mode 100644 index b7c86ff9d59accadb4a62e3b0892860a3cc15f77..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/painters/videomaterial.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). - Copyright (C) 2013 basysKom GmbH - Copyright (C) 2013 Collabora Ltd. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License version 2.1 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/** - * @file - * @brief Extracted from QtGstreamer to avoid overly complex dependency - * @author Gus Grubba - */ - -#pragma once - -#include "../utils/bufferformat.h" -#include -#include -#include - -#include - -class VideoMaterialShader; - -class VideoMaterial : public QSGMaterial -{ -public: - static VideoMaterial *create(const BufferFormat & format); - - virtual ~VideoMaterial(); - - virtual int compare(const QSGMaterial *other) const; - - void setCurrentFrame(GstBuffer *buffer); - void updateColors(int brightness, int contrast, int hue, int saturation); - - void bind(); - -protected: - VideoMaterial(); - void initRgbTextureInfo(GLenum internalFormat, GLuint format, - GLenum type, const GstVideoInfo& videoInfo); - void initYuv420PTextureInfo(const GstVideoInfo& videoInfo); - void updateYuv420PTextureInfo(const GstVideoInfo& videoInfo); - void init(GstVideoColorMatrix colorMatrixType); - -private: - void bindTexture(int i, const quint8 *data); - - GstVideoInfo m_videoInfo; - GstBufferPool* m_bufferPool; - GstBuffer *m_frame; - QMutex m_frameMutex; - - static const int Num_Texture_IDs = 3; - int m_textureCount; - GLuint m_textureIds[Num_Texture_IDs]; - int m_textureWidths[Num_Texture_IDs]; - int m_textureHeights[Num_Texture_IDs]; - int m_textureOffsets[Num_Texture_IDs]; - int m_textureStrides[Num_Texture_IDs]; - bool m_textureAllocated[Num_Texture_IDs]; - - GLenum m_textureFormat; - GLuint m_textureInternalFormat; - GLenum m_textureType; - - QMatrix4x4 m_colorMatrix; - GstVideoColorMatrix m_colorMatrixType; - - friend class VideoMaterialShader; -}; - diff --git a/src/VideoStreaming/gstqtvideosink/painters/videonode.cpp b/src/VideoStreaming/gstqtvideosink/painters/videonode.cpp deleted file mode 100644 index 865c4d52e49905780145a882125e090bb0960cde..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/painters/videonode.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/* - Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). - Copyright (C) 2013 basysKom GmbH - Copyright (C) 2013 Collabora Ltd. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License version 2.1 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/** - * @file - * @brief Extracted from QtGstreamer to avoid overly complex dependency - * @author Gus Grubba - */ - -#include "videonode.h" -#include "videomaterial.h" - -#include - -VideoNode::VideoNode() - : QSGGeometryNode() -{ - setFlags(OwnsGeometry | OwnsMaterial, true); - setMaterialTypeSolidBlack(); -} - -void VideoNode::changeFormat(const BufferFormat & format) -{ - setMaterial(VideoMaterial::create(format)); - setGeometry(0); - m_materialType = MaterialTypeVideo; -} - -void VideoNode::setMaterialTypeSolidBlack() -{ - QSGFlatColorMaterial *m = new QSGFlatColorMaterial; - m->setColor(Qt::black); - setMaterial(m); - setGeometry(0); - m_materialType = MaterialTypeSolidBlack; -} - -void VideoNode::setCurrentFrame(GstBuffer* buffer) -{ - if (m_materialType != MaterialTypeVideo) { - return; - } - static_cast(material())->setCurrentFrame(buffer); - markDirty(DirtyMaterial); -} - -void VideoNode::updateColors(int brightness, int contrast, int hue, int saturation) -{ - if (m_materialType != MaterialTypeVideo) { - return; - } - static_cast(material())->updateColors(brightness, contrast, hue, saturation); - markDirty(DirtyMaterial); -} - -/* Helpers */ -template -static inline void setGeom(V *v, const QPointF &p) -{ - v->x = p.x(); - v->y = p.y(); -} - -static inline void setTex(QSGGeometry::TexturedPoint2D *v, const QPointF &p) -{ - v->tx = p.x(); - v->ty = p.y(); -} - -void VideoNode::updateGeometry(const PaintAreas & areas) -{ - QSGGeometry *g = geometry(); - - if (m_materialType == MaterialTypeVideo) { - if (!g) - g = new QSGGeometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4); - - QSGGeometry::TexturedPoint2D *v = g->vertexDataAsTexturedPoint2D(); - - // Set geometry first - setGeom(v + 0, areas.videoArea.topLeft()); - setGeom(v + 1, areas.videoArea.bottomLeft()); - setGeom(v + 2, areas.videoArea.topRight()); - setGeom(v + 3, areas.videoArea.bottomRight()); - - // and then texture coordinates - setTex(v + 0, areas.sourceRect.topLeft()); - setTex(v + 1, areas.sourceRect.bottomLeft()); - setTex(v + 2, areas.sourceRect.topRight()); - setTex(v + 3, areas.sourceRect.bottomRight()); - } else { - if (!g) - g = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 4); - - QSGGeometry::Point2D *v = g->vertexDataAsPoint2D(); - - setGeom(v + 0, areas.videoArea.topLeft()); - setGeom(v + 1, areas.videoArea.bottomLeft()); - setGeom(v + 2, areas.videoArea.topRight()); - setGeom(v + 3, areas.videoArea.bottomRight()); - } - - if (!geometry()) - setGeometry(g); - - markDirty(DirtyGeometry); -} diff --git a/src/VideoStreaming/gstqtvideosink/painters/videonode.h b/src/VideoStreaming/gstqtvideosink/painters/videonode.h deleted file mode 100644 index 76f607bd22fc374c10621d4ec54c12954aa88311..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/painters/videonode.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). - Copyright (C) 2013 basysKom GmbH - Copyright (C) 2013 Collabora Ltd. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License version 2.1 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/** - * @file - * @brief Extracted from QtGstreamer to avoid overly complex dependency - * @author Gus Grubba - */ - -#pragma once - -#include "../utils/bufferformat.h" - -#include - -class VideoNode : public QSGGeometryNode -{ -public: - VideoNode(); - - enum MaterialType { - MaterialTypeVideo, - MaterialTypeSolidBlack - }; - - MaterialType materialType() const { return m_materialType; } - - void changeFormat(const BufferFormat &format); - void setMaterialTypeSolidBlack(); - - void setCurrentFrame(GstBuffer *buffer); - void updateColors(int brightness, int contrast, int hue, int saturation); - - void updateGeometry(const PaintAreas & areas); - -private: - MaterialType m_materialType; -}; - diff --git a/src/VideoStreaming/gstqtvideosink/utils/bufferformat.cpp b/src/VideoStreaming/gstqtvideosink/utils/bufferformat.cpp deleted file mode 100644 index 507ca6a87ea3f541e0a4ceec1ada50c7596462cd..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/utils/bufferformat.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). - Copyright (C) 2011-2012 Collabora Ltd. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License version 2.1 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/** - * @file - * @brief Extracted from QtGstreamer to avoid overly complex dependency - * @author Gus Grubba - */ - -#include "bufferformat.h" -#include - -BufferFormat BufferFormat::fromCaps(GstCaps *caps) -{ - BufferFormat result; - if (caps && gst_video_info_from_caps(&(result.d->videoInfo), caps)) { - return result; - } else { - return BufferFormat(); - } -} - -GstCaps* BufferFormat::newCaps(GstVideoFormat format, const QSize & size, - const Fraction & framerate, const Fraction & pixelAspectRatio) -{ - GstVideoInfo videoInfo; - gst_video_info_init(&videoInfo); - gst_video_info_set_format(&videoInfo, format, size.width(), size.height()); - - videoInfo.fps_n = framerate.numerator; - videoInfo.fps_d = framerate.denominator; - - videoInfo.par_n = pixelAspectRatio.numerator; - videoInfo.par_d = pixelAspectRatio.denominator; - - return gst_video_info_to_caps(&videoInfo); -} - -int BufferFormat::bytesPerLine(int component) const -{ - return GST_VIDEO_INFO_PLANE_STRIDE(&(d->videoInfo), component); -} - -bool operator==(BufferFormat a, BufferFormat b) -{ - return a.d == b.d; -} - -bool operator!=(BufferFormat a, BufferFormat b) -{ - return a.d != b.d; -} diff --git a/src/VideoStreaming/gstqtvideosink/utils/bufferformat.h b/src/VideoStreaming/gstqtvideosink/utils/bufferformat.h deleted file mode 100644 index 1172beb28add35425c2ff94e84cee96e758886de..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/utils/bufferformat.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). - Copyright (C) 2011-2012 Collabora Ltd. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License version 2.1 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ -#pragma once - -#include "utils.h" -#include -#include - -/** - * This class is a cheap way to represent Caps. - * Based on QVideoSurfaceFormat. - */ -class BufferFormat -{ -public: - static BufferFormat fromCaps(GstCaps *caps); - static GstCaps *newCaps(GstVideoFormat format, const QSize & size, - const Fraction & framerate, const Fraction & pixelAspectRatio); - - inline BufferFormat() : d(new Data) {} - - inline GstVideoInfo videoInfo() const { return d->videoInfo; } - inline GstVideoFormat videoFormat() const { return GST_VIDEO_INFO_FORMAT(&(d->videoInfo)); } - inline GstVideoColorMatrix colorMatrix() const { return d->videoInfo.colorimetry.matrix; } - QSize frameSize() const { - return QSize(GST_VIDEO_INFO_WIDTH(&(d->videoInfo)), - GST_VIDEO_INFO_HEIGHT(&(d->videoInfo))); - } - Fraction pixelAspectRatio() const { - return Fraction(GST_VIDEO_INFO_PAR_N(&(d->videoInfo)), - GST_VIDEO_INFO_PAR_D(&(d->videoInfo))); - } - - int bytesPerLine(int component = 0) const; - -private: - friend bool operator==(BufferFormat a, BufferFormat b); - friend bool operator!=(BufferFormat a, BufferFormat b); - - struct Data : public QSharedData - { - Data() - { gst_video_info_init(&videoInfo); } - - GstVideoInfo videoInfo; - }; - QSharedDataPointer d; -}; - -Q_DECLARE_METATYPE(GstVideoInfo) -Q_DECLARE_METATYPE(GstVideoFormat) -Q_DECLARE_METATYPE(GstVideoColorMatrix) -Q_DECLARE_METATYPE(BufferFormat) - diff --git a/src/VideoStreaming/gstqtvideosink/utils/glutils.h b/src/VideoStreaming/gstqtvideosink/utils/glutils.h deleted file mode 100644 index 733364fbb9532e0cd2c71fbcdd50c2c6999adfb1..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/utils/glutils.h +++ /dev/null @@ -1,35 +0,0 @@ -/**************************************************************************** - * - * (c) 2009-2020 QGROUNDCONTROL PROJECT - * - * QGroundControl is licensed according to the terms in the file - * COPYING.md in the root of the source code directory. - * - ****************************************************************************/ - - -/** - * @file - * @brief QGC Video Item - * @author Gus Grubba - */ - -#pragma once - -#if defined(__android__) || defined(__ios__) -#include -#define getQOpenGLFunctions() QOpenGLContext::currentContext()->functions() -#define QOpenGLFunctionsDef QOpenGLFunctions -#endif - -#ifdef __rasp_pi2__ -#include -#define getQOpenGLFunctions() QOpenGLContext::currentContext()->versionFunctions() -#define QOpenGLFunctionsDef QOpenGLFunctions_ES2 -#endif - -#ifndef QOpenGLFunctionsDef -#include -#define getQOpenGLFunctions() QOpenGLContext::currentContext()->versionFunctions() -#define QOpenGLFunctionsDef QOpenGLFunctions_2_0 -#endif diff --git a/src/VideoStreaming/gstqtvideosink/utils/utils.cpp b/src/VideoStreaming/gstqtvideosink/utils/utils.cpp deleted file mode 100644 index b6116955d05ff727235a1544abff8cad3e01fce5..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/utils/utils.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* - Copyright (C) 2011-2013 Collabora Ltd. - Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). - Copyright (C) 2013 basysKom GmbH - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License version 2.1 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/** - * @file - * @brief Extracted from QtGstreamer to avoid overly complex dependency - * @author Gus Grubba - */ - -#include "utils.h" - -void PaintAreas::calculate(const QRectF & targetArea, - const QSize & videoSize, - const Fraction & pixelAspectRatio, - const Fraction & displayAspectRatio, - Qt::AspectRatioMode aspectRatioMode) -{ - this->targetArea = targetArea; - - switch (aspectRatioMode) { - case Qt::IgnoreAspectRatio: - videoArea = targetArea; - sourceRect = QRectF(0, 0, 1, 1); - blackArea1 = blackArea2 = QRectF(); - break; - default: - { - qreal aspectRatio = pixelAspectRatio.ratio() * displayAspectRatio.invRatio(); - - QSizeF videoSizeAdjusted = QSizeF(videoSize.width() * aspectRatio, videoSize.height()); - videoSizeAdjusted.scale(targetArea.size(), aspectRatioMode); - - // the area that the original video occupies, scaled - QRectF videoRect = QRectF(QPointF(), videoSizeAdjusted); - videoRect.moveCenter(targetArea.center()); - - if (aspectRatioMode == Qt::KeepAspectRatio) { - videoArea = videoRect; - sourceRect = QRectF(0, 0, 1, 1); - } else { // Qt::KeepAspectRatioByExpanding - videoArea = targetArea; - sourceRect = QRectF( - (videoArea.left() - videoRect.left()) / videoRect.width(), - (videoArea.top() - videoRect.top()) / videoRect.height(), - videoArea.width() / videoRect.width(), - videoArea.height() / videoRect.height()); - } - break; - } - } - - if (aspectRatioMode == Qt::IgnoreAspectRatio - || aspectRatioMode == Qt::KeepAspectRatioByExpanding - || videoArea == targetArea) { - blackArea1 = blackArea2 = QRectF(); - } else { - blackArea1 = QRectF( - targetArea.left(), - targetArea.top(), - videoArea.left() == targetArea.left() ? - targetArea.width() : videoArea.left() - targetArea.left(), - videoArea.top() == targetArea.top() ? - targetArea.height() : videoArea.top() - targetArea.top() - ); - - blackArea2 = QRectF( - videoArea.right() == targetArea.right() ? - targetArea.left() : videoArea.right(), - videoArea.bottom() == targetArea.bottom() ? - targetArea.top() : videoArea.bottom(), - videoArea.right() == targetArea.right() ? - targetArea.width() : targetArea.right() - videoArea.right(), - videoArea.bottom() == targetArea.bottom() ? - targetArea.height() : targetArea.bottom() - videoArea.bottom() - ); - } -} diff --git a/src/VideoStreaming/gstqtvideosink/utils/utils.h b/src/VideoStreaming/gstqtvideosink/utils/utils.h deleted file mode 100644 index 79517a1212144f42710cf5defbc136d9fe36a8c8..0000000000000000000000000000000000000000 --- a/src/VideoStreaming/gstqtvideosink/utils/utils.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - Copyright (C) 2011-2012 Collabora Ltd. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License version 2.1 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ -#pragma once - -#include -#include -#include - -// utilities for GST_DEBUG -#define QSIZE_FORMAT "(%d x %d)" -#define QSIZE_FORMAT_ARGS(size) \ - size.width(), size.height() -#define QRECTF_FORMAT "(x: %f, y: %f, w: %f, h: %f)" -#define QRECTF_FORMAT_ARGS(rect) \ - (float) rect.x(), (float) rect.y(), (float) rect.width(), (float) rect.height() - -struct Fraction -{ - inline Fraction() {} - inline Fraction(int numerator, int denominator) - : numerator(numerator), denominator(denominator) {} - - inline bool operator==(const Fraction & other) const - { return numerator == other.numerator && denominator == other.denominator; } - inline bool operator!=(const Fraction & other) const - { return !operator==(other); } - - inline qreal ratio() const - { return (qreal) numerator / (qreal) denominator; } - inline qreal invRatio() const - { return (qreal) denominator / (qreal) numerator; } - - int numerator; - int denominator; -}; - -struct PaintAreas -{ - void calculate(const QRectF & targetArea, - const QSize & videoSize, - const Fraction & pixelAspectRatio, - const Fraction & displayAspectRatio, - Qt::AspectRatioMode aspectRatioMode); - - // the area that we paint on - QRectF targetArea; - // the area where the video should be painted on - // (subrect of or equal to targetArea) - QRectF videoArea; - - // the part of the video rectangle that we are going to blit on the videoArea - // in the normalized (0,1] range (texture coordinates) - QRectF sourceRect; - - // these are small subrects of targetArea that are not - // covered by videoArea to keep the video's aspect ratio - QRectF blackArea1; - QRectF blackArea2; -}; - -Q_DECLARE_METATYPE(Fraction) -Q_DECLARE_METATYPE(PaintAreas) -