summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt173
-rw-r--r--NEWS100
-rw-r--r--README123
-rw-r--r--cmake/modules/FindGLIB2.cmake22
-rw-r--r--cmake/modules/FindGObject.cmake4
-rw-r--r--cmake/modules/FindGStreamer.cmake51
-rw-r--r--cmake/modules/FindGStreamerPluginsBase.cmake22
-rw-r--r--cmake/modules/FindOpenGLES2.cmake20
-rw-r--r--cmake/modules/FindQt4or5.cmake235
-rw-r--r--cmake/modules/FindQtGStreamer.cmake125
-rw-r--r--cmake/modules/HandleImportedTargetsInCMakeRequiredLibraries.cmake83
-rw-r--r--cmake/modules/MacroFindGStreamerLibrary.cmake6
-rw-r--r--cmake/modules/QtGStreamerConfig.cmake.in74
-rw-r--r--cmake/modules/QtGStreamerConfigCommon.cmake31
-rw-r--r--codegen/CMakeLists.txt4
-rw-r--r--codegen/analyzer.l4
-rw-r--r--codegen/generator.cpp40
-rw-r--r--codegen/generator.h2
-rw-r--r--codegen/parser.y4
-rw-r--r--codegen/yystype.h2
-rw-r--r--elements/CMakeLists.txt18
-rw-r--r--elements/gstqtvideosink/CMakeLists.txt106
-rw-r--r--elements/gstqtvideosink/autotest.cpp1041
-rw-r--r--elements/gstqtvideosink/delegates/basedelegate.cpp197
-rw-r--r--elements/gstqtvideosink/delegates/basedelegate.h149
-rw-r--r--elements/gstqtvideosink/delegates/qtquick2videosinkdelegate.cpp103
-rw-r--r--elements/gstqtvideosink/delegates/qtquick2videosinkdelegate.h32
-rw-r--r--elements/gstqtvideosink/delegates/qtvideosinkdelegate.cpp239
-rw-r--r--elements/gstqtvideosink/delegates/qtvideosinkdelegate.h69
-rw-r--r--elements/gstqtvideosink/delegates/qwidgetvideosinkdelegate.cpp82
-rw-r--r--elements/gstqtvideosink/delegates/qwidgetvideosinkdelegate.h49
-rw-r--r--elements/gstqtvideosink/gstqtglvideosink.cpp143
-rw-r--r--elements/gstqtvideosink/gstqtglvideosink.h72
-rw-r--r--elements/gstqtvideosink/gstqtglvideosinkbase.cpp262
-rw-r--r--elements/gstqtvideosink/gstqtglvideosinkbase.h94
-rw-r--r--elements/gstqtvideosink/gstqtquick2videosink.cpp452
-rw-r--r--elements/gstqtvideosink/gstqtquick2videosink.h57
-rw-r--r--elements/gstqtvideosink/gstqtvideosink.cpp110
-rw-r--r--elements/gstqtvideosink/gstqtvideosink.h61
-rw-r--r--elements/gstqtvideosink/gstqtvideosinkbase.cpp215
-rw-r--r--elements/gstqtvideosink/gstqtvideosinkbase.h78
-rw-r--r--elements/gstqtvideosink/gstqtvideosinkplugin.cpp75
-rw-r--r--elements/gstqtvideosink/gstqtvideosinkplugin.h70
-rw-r--r--elements/gstqtvideosink/gstqwidgetvideosink.cpp98
-rw-r--r--elements/gstqtvideosink/gstqwidgetvideosink.h55
-rw-r--r--elements/gstqtvideosink/painters/abstractsurfacepainter.h42
-rw-r--r--elements/gstqtvideosink/painters/genericsurfacepainter.cpp106
-rw-r--r--elements/gstqtvideosink/painters/genericsurfacepainter.h51
-rw-r--r--elements/gstqtvideosink/painters/openglsurfacepainter.cpp796
-rw-r--r--elements/gstqtvideosink/painters/openglsurfacepainter.h135
-rw-r--r--elements/gstqtvideosink/painters/videomaterial.cpp461
-rw-r--r--elements/gstqtvideosink/painters/videomaterial.h78
-rw-r--r--elements/gstqtvideosink/painters/videonode.cpp114
-rw-r--r--elements/gstqtvideosink/painters/videonode.h51
-rw-r--r--elements/gstqtvideosink/utils/bufferformat.cpp59
-rw-r--r--elements/gstqtvideosink/utils/bufferformat.h70
-rw-r--r--elements/gstqtvideosink/utils/utils.cpp85
-rw-r--r--elements/gstqtvideosink/utils/utils.h78
-rw-r--r--elements/gstqwidgetvideosink.cpp637
-rw-r--r--examples/CMakeLists.txt40
-rw-r--r--examples/RunExamplesDistCheck.cmake39
-rw-r--r--examples/appsink-src/CMakeLists.txt15
-rw-r--r--examples/appsink-src/appsink-src.pro12
-rw-r--r--examples/appsink-src/main.cpp18
-rw-r--r--examples/devmon/CMakeLists.txt23
-rw-r--r--examples/devmon/devmon.pro23
-rw-r--r--examples/devmon/main.cpp34
-rw-r--r--examples/devmon/mainwindow.cpp270
-rw-r--r--examples/devmon/mainwindow.h55
-rw-r--r--examples/examples.dox23
-rw-r--r--examples/player/CMakeLists.txt21
-rw-r--r--examples/player/main.cpp4
-rw-r--r--examples/player/mediaapp.cpp23
-rw-r--r--examples/player/mediaapp.h8
-rw-r--r--examples/player/player.cpp15
-rw-r--r--examples/player/player.h6
-rw-r--r--examples/player/player.pro22
-rw-r--r--examples/qmlplayer/CMakeLists.txt50
-rw-r--r--examples/qmlplayer/main.cpp67
-rw-r--r--examples/qmlplayer/player.cpp107
-rw-r--r--examples/qmlplayer/player.h49
-rw-r--r--examples/qmlplayer/qmlplayer.pro34
-rw-r--r--examples/qmlplayer/qmlplayer.qml76
-rw-r--r--examples/qmlplayer/qmlplayer.qrc6
-rw-r--r--examples/qmlplayer2/CMakeLists.txt30
-rw-r--r--examples/qmlplayer2/main.cpp60
-rw-r--r--examples/qmlplayer2/player.cpp94
-rw-r--r--examples/qmlplayer2/player.h47
-rw-r--r--examples/qmlplayer2/qmlplayer2.pro28
-rw-r--r--examples/qmlplayer2/qmlplayer2.qml79
-rw-r--r--examples/qmlplayer2/qmlplayer2.qrc6
-rw-r--r--examples/recorder/CMakeLists.txt24
-rw-r--r--examples/recorder/main.cpp136
-rw-r--r--examples/recorder/recorder.pro30
-rw-r--r--examples/recorder/recorder.ui53
-rw-r--r--examples/voip/CMakeLists.txt22
-rw-r--r--examples/voip/main.cpp25
-rw-r--r--examples/voip/voip.pro30
-rwxr-xr-xmake_tarballs.sh7
-rw-r--r--src/CMakeLists.txt76
-rw-r--r--src/QGlib/CMakeLists.txt14
-rw-r--r--src/QGlib/QtGLib-2.0.pc.in10
-rw-r--r--src/QGlib/Signal2
-rw-r--r--src/QGlib/connect.cpp6
-rw-r--r--src/QGlib/connect.h2
-rw-r--r--src/QGlib/connectimpl.h4
-rw-r--r--src/QGlib/emitimpl.h2
-rw-r--r--src/QGlib/error.cpp32
-rw-r--r--src/QGlib/error.h9
-rw-r--r--src/QGlib/gen.cpp153
-rw-r--r--src/QGlib/global.h9
-rw-r--r--src/QGlib/init.cpp2
-rw-r--r--src/QGlib/init.h2
-rw-r--r--src/QGlib/object.cpp2
-rw-r--r--src/QGlib/object.h2
-rw-r--r--src/QGlib/paramspec.cpp2
-rw-r--r--src/QGlib/paramspec.h2
-rw-r--r--src/QGlib/qglib_signal.h (renamed from src/QGlib/signal.h)4
-rw-r--r--src/QGlib/quark.cpp2
-rw-r--r--src/QGlib/quark.h2
-rw-r--r--src/QGlib/refpointer.h2
-rw-r--r--src/QGlib/signal.cpp4
-rw-r--r--src/QGlib/string_p.h2
-rw-r--r--src/QGlib/type.cpp2
-rw-r--r--src/QGlib/type.h2
-rw-r--r--src/QGlib/value.cpp32
-rw-r--r--src/QGlib/value.h23
-rw-r--r--src/QGlib/wrap.cpp5
-rw-r--r--src/QGlib/wrap.h2
-rw-r--r--src/QGst/Allocator1
-rw-r--r--src/QGst/CMakeLists.txt128
-rw-r--r--src/QGst/Device1
-rw-r--r--src/QGst/DeviceMonitor1
-rw-r--r--src/QGst/Discoverer1
-rw-r--r--src/QGst/PropertyProbe1
-rw-r--r--src/QGst/QGstMemory1
-rw-r--r--src/QGst/QtGStreamer-0.10.pc.in12
-rw-r--r--src/QGst/QtGStreamer-1.0.pc.in12
-rw-r--r--src/QGst/QtGStreamerQuick-1.0.pc.in11
-rw-r--r--src/QGst/QtGStreamerUi-0.10.pc.in11
-rw-r--r--src/QGst/QtGStreamerUi-1.0.pc.in11
-rw-r--r--src/QGst/QtGStreamerUtils-0.10.pc.in12
-rw-r--r--src/QGst/QtGStreamerUtils-1.0.pc.in12
-rw-r--r--src/QGst/Quick/VideoItem1
-rw-r--r--src/QGst/Quick/VideoSurface1
-rw-r--r--src/QGst/Quick/global.h42
-rw-r--r--src/QGst/Quick/videoitem.cpp118
-rw-r--r--src/QGst/Quick/videoitem.h65
-rw-r--r--src/QGst/Quick/videosurface.cpp70
-rw-r--r--src/QGst/Quick/videosurface.h84
-rw-r--r--src/QGst/Quick/videosurface_p.h37
-rw-r--r--src/QGst/Sample1
-rw-r--r--src/QGst/Segment1
-rw-r--r--src/QGst/Ui/GraphicsVideoSurface1
-rw-r--r--src/QGst/Ui/GraphicsVideoWidget1
-rw-r--r--src/QGst/Ui/global.h9
-rw-r--r--src/QGst/Ui/graphicsvideosurface.cpp90
-rw-r--r--src/QGst/Ui/graphicsvideosurface.h118
-rw-r--r--src/QGst/Ui/graphicsvideosurface_p.h38
-rw-r--r--src/QGst/Ui/graphicsvideowidget.cpp71
-rw-r--r--src/QGst/Ui/graphicsvideowidget.h65
-rw-r--r--src/QGst/Ui/videowidget.cpp150
-rw-r--r--src/QGst/Ui/videowidget.h28
-rw-r--r--src/QGst/Utils/applicationsink.cpp52
-rw-r--r--src/QGst/Utils/applicationsink.h79
-rw-r--r--src/QGst/Utils/applicationsource.cpp10
-rw-r--r--src/QGst/Utils/applicationsource.h2
-rw-r--r--src/QGst/Utils/global.h9
-rw-r--r--src/QGst/VideoOverlay1
-rw-r--r--src/QGst/XOverlay1
-rw-r--r--src/QGst/allocator.cpp128
-rw-r--r--src/QGst/allocator.h86
-rw-r--r--src/QGst/bin.cpp5
-rw-r--r--src/QGst/bin.h4
-rw-r--r--src/QGst/buffer.cpp62
-rw-r--r--src/QGst/buffer.h20
-rw-r--r--src/QGst/bufferlist.cpp70
-rw-r--r--src/QGst/bufferlist.h72
-rw-r--r--src/QGst/bus.cpp4
-rw-r--r--src/QGst/bus.h2
-rw-r--r--src/QGst/caps.cpp77
-rw-r--r--src/QGst/caps.h32
-rw-r--r--src/QGst/childproxy.cpp26
-rw-r--r--src/QGst/childproxy.h11
-rw-r--r--src/QGst/clock.cpp5
-rw-r--r--src/QGst/clock.h2
-rw-r--r--src/QGst/clocktime.cpp4
-rw-r--r--src/QGst/clocktime.h27
-rw-r--r--src/QGst/colorbalance.cpp4
-rw-r--r--src/QGst/colorbalance.h2
-rw-r--r--src/QGst/device.cpp60
-rw-r--r--src/QGst/device.h50
-rw-r--r--src/QGst/devicemonitor.cpp71
-rw-r--r--src/QGst/devicemonitor.h53
-rw-r--r--src/QGst/discoverer.cpp426
-rw-r--r--src/QGst/discoverer.h180
-rw-r--r--src/QGst/element.cpp11
-rw-r--r--src/QGst/element.h2
-rw-r--r--src/QGst/elementfactory.cpp53
-rw-r--r--src/QGst/elementfactory.h15
-rw-r--r--src/QGst/enums.h248
-rw-r--r--src/QGst/event.cpp113
-rw-r--r--src/QGst/event.h48
-rw-r--r--src/QGst/gen.cpp1116
-rw-r--r--src/QGst/ghostpad.cpp4
-rw-r--r--src/QGst/ghostpad.h2
-rw-r--r--src/QGst/global.h41
-rw-r--r--src/QGst/init.cpp2
-rw-r--r--src/QGst/init.h2
-rw-r--r--src/QGst/memory.cpp93
-rw-r--r--src/QGst/memory.h71
-rw-r--r--src/QGst/message.cpp72
-rw-r--r--src/QGst/message.h50
-rw-r--r--src/QGst/miniobject.cpp4
-rw-r--r--src/QGst/miniobject.h15
-rw-r--r--src/QGst/object.cpp4
-rw-r--r--src/QGst/object.h2
-rw-r--r--src/QGst/objectstore.cpp6
-rw-r--r--src/QGst/objectstore_p.h2
-rw-r--r--src/QGst/pad.cpp26
-rw-r--r--src/QGst/pad.h13
-rw-r--r--src/QGst/parse.cpp4
-rw-r--r--src/QGst/parse.h2
-rw-r--r--src/QGst/pipeline.cpp4
-rw-r--r--src/QGst/pipeline.h2
-rw-r--r--src/QGst/pluginfeature.cpp4
-rw-r--r--src/QGst/pluginfeature.h2
-rw-r--r--src/QGst/propertyprobe.cpp109
-rw-r--r--src/QGst/propertyprobe.h55
-rw-r--r--src/QGst/query.cpp12
-rw-r--r--src/QGst/query.h4
-rw-r--r--src/QGst/sample.cpp58
-rw-r--r--src/QGst/sample.h47
-rw-r--r--src/QGst/segment.cpp158
-rw-r--r--src/QGst/segment.h69
-rw-r--r--src/QGst/streamvolume.cpp4
-rw-r--r--src/QGst/streamvolume.h2
-rw-r--r--src/QGst/structs.h15
-rw-r--r--src/QGst/structure.cpp8
-rw-r--r--src/QGst/structure.h2
-rw-r--r--src/QGst/taglist.cpp56
-rw-r--r--src/QGst/taglist.h18
-rw-r--r--src/QGst/urihandler.cpp22
-rw-r--r--src/QGst/urihandler.h2
-rw-r--r--src/QGst/value.cpp44
-rw-r--r--src/QGst/videoorientation.cpp4
-rw-r--r--src/QGst/videoorientation.h2
-rw-r--r--src/QGst/videooverlay.cpp (renamed from src/QGst/xoverlay.cpp)33
-rw-r--r--src/QGst/videooverlay.h (renamed from src/QGst/xoverlay.h)22
-rw-r--r--src/main.dox142
-rw-r--r--src/qml/CMakeLists.txt7
-rw-r--r--src/qml/quick1/CMakeLists.txt27
-rw-r--r--src/qml/quick1/plugin.cpp44
-rw-r--r--src/qml/quick1/videoitem.cpp45
-rw-r--r--src/qml/quick1/videoitem.h42
-rw-r--r--src/qml/quick2/CMakeLists.txt26
-rw-r--r--src/qml/quick2/QtGStreamerQuick2.json2
-rw-r--r--src/qml/quick2/plugin.cpp40
-rw-r--r--tests/auto/CMakeLists.txt25
-rw-r--r--tests/auto/allocatortest.cpp85
-rw-r--r--tests/auto/buffertest.cpp48
-rw-r--r--tests/auto/bustest.cpp4
-rw-r--r--tests/auto/capstest.cpp20
-rw-r--r--tests/auto/childproxytest.cpp6
-rw-r--r--tests/auto/clocktest.cpp2
-rw-r--r--tests/auto/data/numbers.ogvbin0 -> 112640 bytes
-rw-r--r--tests/auto/data/numbers07.jpgbin0 -> 3017 bytes
-rw-r--r--tests/auto/data/numbers07.pngbin0 -> 1213 bytes
-rw-r--r--tests/auto/data/sine.oggbin0 -> 7683 bytes
-rw-r--r--tests/auto/discoverertest.cpp640
-rw-r--r--tests/auto/eventtest.cpp39
-rw-r--r--tests/auto/memorytest.cpp52
-rw-r--r--tests/auto/messagetest.cpp42
-rw-r--r--tests/auto/padtest.cpp55
-rw-r--r--tests/auto/parsetest.cpp2
-rw-r--r--tests/auto/propertiestest.cpp2
-rw-r--r--tests/auto/qgsttest.h27
-rw-r--r--tests/auto/qtquick2test.cpp87
-rw-r--r--tests/auto/querytest.cpp17
-rw-r--r--tests/auto/refpointertest.cpp51
-rw-r--r--tests/auto/signalstest.cpp10
-rw-r--r--tests/auto/structstest.cpp2
-rw-r--r--tests/auto/structuretest.cpp32
-rw-r--r--tests/auto/taglisttest.cpp65
-rw-r--r--tests/auto/urihandlertest.cpp5
-rw-r--r--tests/auto/valuetest.cpp28
-rw-r--r--tests/auto/videoitemtest.qml20
-rw-r--r--tests/compilation/CMakeLists.txt8
-rw-r--r--tests/compilation/CompilationTests.cmake2
-rw-r--r--tests/compilation/CompilationTests_CMakeLists.txt14
-rw-r--r--tests/compilation/RunCompilationTests.cmake2
-rw-r--r--tests/manual/CMakeLists.txt29
-rw-r--r--tests/manual/qwidgetvideosinktest.cpp9
-rw-r--r--tests/manual/videoorientationtest.cpp8
-rw-r--r--tests/manual/videowidgetpipelinetest.cpp6
-rw-r--r--tests/manual/videowidgettest.cpp8
296 files changed, 14915 insertions, 2473 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6a9d97d..5744015 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,47 +1,103 @@
project(QtGStreamer)
-cmake_minimum_required(VERSION 2.8)
+cmake_minimum_required(VERSION 2.8.9)
enable_testing()
+set(CMAKE_POSITION_INDEPENDENT_CODE ON)
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules)
-set(QTGSTREAMER_VERSION 0.10.1.1)
+
+set(QTGSTREAMER_VERSION 1.2.0)
option(QTGSTREAMER_STATIC "Build QtGStreamer as a static library" OFF)
option(QTGSTREAMER_TESTS "Build QtGStreamer's tests" OFF)
option(QTGSTREAMER_EXAMPLES "Build QtGStreamer's examples" ON)
+option(QTGSTREAMER_CODEGEN "Build and use QtGStreamer's codegen" OFF)
+option(USE_GST_PLUGIN_DIR "Install gstreamer plugins at the system location" ON)
+option(USE_QT_PLUGIN_DIR "Install qt plugins at the system location" ON)
+include(GNUInstallDirs)
include(MacroLogFeature)
-find_package(Qt4 COMPONENTS QtCore QtGui QtTest)
-macro_log_feature(QT4_FOUND "Qt 4" "Required for building everything" "http://qt.nokia.com/" TRUE "4.5")
+set(Qt4_MIN_VERSION 4.7)
+set(Qt5_MIN_VERSION 5.0.0)
+find_package(Qt4or5 COMPONENTS Core Gui Widgets OPTIONAL_COMPONENTS OpenGL Quick1 Quick2 Qml Test)
+macro_log_feature(Qt4or5_FOUND "Qt" "Required for building everything"
+ "http://qt-project.org/" TRUE "${Qt4or5_MIN_VERSION}")
+macro_log_feature(Qt4or5_OpenGL_FOUND "QtOpenGL"
+ "Required for OpenGL acceleration in qtvideosink and QtGStreamerUi"
+ "http://qt-project.org/" FALSE "${Qt4or5_MIN_VERSION}")
+macro_log_feature(Qt4or5_Quick1_FOUND "QtQuick1 (QtDeclarative)"
+ "Required for building QtQuick1 support"
+ "http://qt-project.org/" FALSE "${Qt4or5_MIN_VERSION}")
+if (${QT_VERSION} STREQUAL "5")
+ macro_log_feature(Qt4or5_Quick2_FOUND "QtQuick2 (QtQuick)"
+ "Required for building QtQuick2 support"
+ "http://qt-project.org/" TRUE "${Qt4or5_MIN_VERSION}")
+ macro_log_feature(Qt4or5_Qml_FOUND "QtQml"
+ "Required for building QtQuick2 support"
+ "http://qt-project.org/" TRUE "${Qt4or5_MIN_VERSION}")
+endif()
+
+if (QTGSTREAMER_TESTS)
+ macro_log_feature(Qt4or5_Test_FOUND "QtTest" "Required for building unit tests"
+ "http://qt-project.org/" FALSE "${Qt4or5_MIN_VERSION}")
+ if (NOT Qt4or5_Test_FOUND)
+ set(QTGSTREAMER_TESTS OFF)
+ endif()
+endif()
find_package(Boost 1.39)
macro_log_feature(Boost_FOUND "Boost" "Required for building QtGLib" "http://www.boost.org/" TRUE "1.39")
-# this just sets the QTGSTREAMER_* cmake variables
+# set the QTGSTREAMER_* cmake variables
set(BUILDING_QTGSTREAMER TRUE)
-find_package(QtGStreamer REQUIRED)
-
-find_package(Automoc4)
-macro_log_feature(Automoc4_FOUND "Automoc 4" "Required for the build system to generate moc files properly"
- "https://projects.kde.org/projects/kdesupport/automoc" TRUE "0.9.88")
+if (${QT_VERSION} STREQUAL "5")
+ set(USE_QT5 TRUE)
+ set(QTGLIB_LIBRARY Qt5GLib)
+ set(QTGSTREAMER_LIBRARY Qt5GStreamer)
+ set(QTGSTREAMER_QUICK_LIBRARY Qt5GStreamerQuick)
+ set(QTGSTREAMER_UI_LIBRARY Qt5GStreamerUi)
+ set(QTGSTREAMER_UTILS_LIBRARY Qt5GStreamerUtils)
+ set(QTGSTREAMER_PACKAGE_NAME Qt5GStreamer)
+ set(QTVIDEOSINK_NAME qt5videosink)
+ set(QTGLVIDEOSINK_NAME qt5glvideosink)
+ set(QWIDGETVIDEOSINK_NAME qwidget5videosink)
+elseif (${QT_VERSION} STREQUAL "4")
+ set(USE_QT4 TRUE)
+ set(QTGLIB_LIBRARY QtGLib)
+ set(QTGSTREAMER_LIBRARY QtGStreamer)
+ set(QTGSTREAMER_QUICK_LIBRARY "")
+ set(QTGSTREAMER_UI_LIBRARY QtGStreamerUi)
+ set(QTGSTREAMER_UTILS_LIBRARY QtGStreamerUtils)
+ set(QTGSTREAMER_PACKAGE_NAME QtGStreamer)
+ set(QTVIDEOSINK_NAME qtvideosink)
+ set(QTGLVIDEOSINK_NAME qtglvideosink)
+ set(QWIDGETVIDEOSINK_NAME qwidgetvideosink)
+endif()
+set(QTGSTREAMER_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/src)
+include(QtGStreamerConfigCommon)
-find_package(GStreamer 0.10.31 COMPONENTS base)
+find_package(GStreamer 1.2.0 COMPONENTS base)
macro_log_feature(GSTREAMER_FOUND "GStreamer" "Required to build QtGStreamer"
- "http://gstreamer.freedesktop.org/" TRUE "0.10.31")
+ "http://gstreamer.freedesktop.org/" TRUE "1.2.0")
macro_log_feature(GSTREAMER_BASE_LIBRARY_FOUND "GStreamer base library"
- "Used for building the qwidgetvideosink element"
- "http://gstreamer.freedesktop.org/" FALSE "0.10.31")
+ "Used for building the ${QTVIDEOSINK_NAME} element"
+ "http://gstreamer.freedesktop.org/" FALSE "1.2.0")
-find_package(GStreamerPluginsBase 0.10.31 COMPONENTS app interfaces video)
+find_package(GStreamerPluginsBase 1.2.0 COMPONENTS app audio video pbutils)
macro_log_feature(GSTREAMER_APP_LIBRARY_FOUND "GStreamer app library"
"Required to build QtGStreamerUtils"
- "http://gstreamer.freedesktop.org/" TRUE "0.10.31")
-macro_log_feature(GSTREAMER_INTERFACES_LIBRARY_FOUND "GStreamer interfaces library"
+ "http://gstreamer.freedesktop.org/" TRUE "1.2.0")
+macro_log_feature(GSTREAMER_AUDIO_LIBRARY_FOUND "GStreamer audio library"
"Required to build QtGStreamer"
- "http://gstreamer.freedesktop.org/" TRUE "0.10.31")
+ "http://gstreamer.freedesktop.org/" TRUE "1.2.0")
macro_log_feature(GSTREAMER_VIDEO_LIBRARY_FOUND "GStreamer video library"
- "Used for building the qwidgetvideosink element"
- "http://gstreamer.freedesktop.org/" FALSE "0.10.31")
+ "Required to build QtGStreamer"
+ "http://gstreamer.freedesktop.org/" TRUE "1.2.0")
+macro_log_feature(GSTREAMER_PBUTILS_LIBRARY_FOUND "GStreamer pbutils library"
+ "Used for building the Discoverer API"
+ "http://gstreamer.freedesktop.org/" TRUE "1.2.0")
find_package(GLIB2)
macro_log_feature(GLIB2_FOUND "GLib" "Required to build QtGLib" "http://www.gtk.org/" TRUE)
@@ -49,20 +105,81 @@ macro_log_feature(GLIB2_FOUND "GLib" "Required to build QtGLib" "http://www.gtk.
find_package(GObject)
macro_log_feature(GOBJECT_FOUND "GObject" "Required to build QtGLib" "http://www.gtk.org/" TRUE)
-find_package(FLEX)
-macro_log_feature(FLEX_FOUND "Flex" "Required to build codegen, a helper code generator"
- "http://flex.sourceforge.net/" TRUE)
+set(CMAKE_REQUIRED_INCLUDES ${QTGSTREAMER_INCLUDES})
+add_definitions(${GSTREAMER_DEFINITIONS})
+include(CheckCXXSourceCompiles)
+check_cxx_source_compiles("
+#include <QtCore/QtGlobal>
+#if !defined(QT_OPENGL_ES)
+#error \"No OpenGLES\"
+#endif
+int main() {}
+" USE_OPENGLES)
+
+if (USE_OPENGLES)
+ find_package(OpenGLES2)
+ macro_log_feature(OPENGLES2_FOUND "OpenGLES"
+ "Required for OpenGLES rendering support in ${QTVIDEOSINK_NAME}"
+ "http://www.opengl.org" FALSE "2.0")
+else()
+ find_package(OpenGL)
+ macro_log_feature(OPENGL_FOUND "OpenGL"
+ "Required for OpenGL rendering support in ${QTVIDEOSINK_NAME}"
+ "http://www.opengl.org" FALSE)
+endif()
+
+if (QTGSTREAMER_CODEGEN AND CMAKE_CROSSCOMPILING)
+ message(WARNING "Codegen use requested, but we are crosscompiling. Disabling...")
+ set(QTGSTREAMER_CODEGEN OFF)
+endif()
+
+if (QTGSTREAMER_CODEGEN)
+ find_package(FLEX)
+ macro_log_feature(FLEX_FOUND "Flex" "Required to build codegen, a helper code generator"
+ "http://flex.sourceforge.net/" TRUE)
-find_package(BISON)
-macro_log_feature(BISON_FOUND "Bison" "Required to build codegen, a helper code generator"
- "http://www.gnu.org/software/bison/" TRUE)
+ find_package(BISON)
+ macro_log_feature(BISON_FOUND "Bison" "Required to build codegen, a helper code generator"
+ "http://www.gnu.org/software/bison/" TRUE)
+endif()
if (CMAKE_COMPILER_IS_GNUCXX)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wformat-security -Wundef -Wpointer-arith -Wcast-align -fno-common")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wformat-security -Wundef -Wpointer-arith -fno-common")
endif ()
-add_subdirectory(codegen)
+
+set(QTGSTREAMER_INSTALL_TARGET_DEFAULT_ARGS
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
+set(QTGSTREAMER_PC_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
+set(QTGSTREAMER_CMAKE_CONFIG_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/${QTGSTREAMER_PACKAGE_NAME})
+set(QTGSTREAMER_INCLUDES_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR}/${QTGSTREAMER_PACKAGE_NAME})
+
+if (USE_GST_PLUGIN_DIR)
+ set(QTGSTREAMER_GST_PLUGINS_INSTALL_DIR ${GSTREAMER_PLUGIN_DIR})
+else()
+ set(QTGSTREAMER_GST_PLUGINS_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/gstreamer-${GSTREAMER_ABI_VERSION})
+endif()
+
+if (USE_QT_PLUGIN_DIR)
+ set(QTGSTREAMER_QTQUICK1_INSTALL_DIR ${QT_IMPORTS_DIR})
+ set(QTGSTREAMER_QTQUICK2_INSTALL_DIR ${QT_QML_DIR})
+else()
+ if (USE_QT5)
+ set(QTGSTREAMER_QTQUICK1_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/qt5/imports)
+ set(QTGSTREAMER_QTQUICK2_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/qt5/qml)
+ else()
+ set(QTGSTREAMER_QTQUICK1_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/qt4/imports)
+ endif()
+endif()
+
+
+if (QTGSTREAMER_CODEGEN AND FLEX_FOUND AND BISON_FOUND)
+ add_subdirectory(codegen)
+endif()
+
add_subdirectory(src)
add_subdirectory(elements)
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..e5ab0bc
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,100 @@
+qt-gstreamer 1.2.0 (2014-07-08)
+===============================
+
+ * Initial port to the GStreamer 1.0 series (BREAKS API & ABI)
+
+Further additions:
+ * Added QtQuick2 support, which includes:
+ - The qtquick2videosink gstreamer element
+ - The QtGStreamerQuick2 QML plugin
+ - The Qt5GStreamerQuick glue library
+ - The qmlplayer2 example
+
+Packaging changes:
+ * Tarballs are now distributed in .tar.xz format, together
+ with a .tar.xz.sha256sum check file, like the rest of the
+ GStreamer modules.
+ * Package is NOT fully co-installable with QtGStreamer 0.10.3
+
+Versioning changes:
+ * Version numbers are now going to be synced to the GStreamer API
+ that qt-gstreamer targets, to avoid confusion. So, this release,
+ instead of being version 1.0.0, it is 1.2.0.
+
+qt-gstreamer 0.10.3 (2013-10-14)
+==================================
+
+Additions:
+ * Added Qt5 support.
+ * Added GstDiscoverer bindings.
+ * QGlib::Error can now be used in QGlib::Value
+ * Added convenience constructors for QGst::ClockTime
+
+Fixes:
+ * Fixed qtglvideosink painting on QGLFrameBufferObject
+ * Fixed codegen compilation with bison 2.6
+ * Fixed example code in the QGst::Ui::GraphicsVideoSurface apidocs
+ * Many fixes for windows support
+
+Build system fixes and enhancements:
+ * Use recent cmake goodies:
+ * CMakePackageConfigHelpers, which simplifies QtGStreamerConfig.cmake
+ and adds version checking in find_package(QtGStreamer)
+ * CMAKE_POSITION_INDEPENDENT_CODE, which eliminates issues with
+ missing -fPIC / -fPIE
+ * GNUInstallDirs, which adds automagic support for debian multiarch
+ and also takes away the need for LIB_SUFFIX
+ * .dll's are now installed in the correct place ($prefix/bin) on windows
+ * cmake config files are now installed in $libdir/cmake/$package
+ instead of $libdir/$package
+ * Renamed signal.h to qglib_signal.h to avoid problems where the compiler
+ mixes it up with the C <signal.h>
+ * Determine whether to use OpenGLES or desktop OpenGL by looking at
+ what Qt is using on the target system instead of guessing.
+
+Changes in dependencies:
+ * CMake 2.8.9 is now required
+ * Drop completely automoc dependency in favor of cmake's internal automoc
+ * Qt5 can be used instead of Qt4. The resulting qt-gstreamer files
+ will be co-installable with the ones built using Qt4.
+
+qt-gstreamer 0.10.2 (2012-04-15)
+================================
+
+Additions:
+ * Added qHash(const RefPointer<T> &) function.
+ * Added Element::removePad() and Pad::setActive() methods.
+ * Added extra documentation about the design of the wrapping system.
+ * Added new examples: VoIP and QMLPlayer.
+ * Added new elements: qtvideosink and qtglvideosink.
+ * Added helper classes for painting video on QGraphicsView.
+ * Added QML plugin that provides an item for painting video.
+
+Fixes:
+ * Fixed compilation with newer glib versions.
+ * Fixed compilation with boost 1.48 (QTBUG-22829).
+ * Fixed compilation with -DQT_NO_STL.
+ * Fixed Element::unlink() to work correctly.
+ * Fixed Structure::fromString() to actually compile.
+
+Build system fixes and enhancements:
+ * Utils/global.h is now properly installed.
+ * Support lib64.
+ * Support installing gstreamer plugins in the plugin directory indicated by pkg-config.
+ * Support cmake's internal automoc.
+ * Fixed error output when automoc4 is required and not found.
+ * Fixed cross-compilation issues.
+ * Made all examples compilable standalone with both qmake and cmake.
+ * Fixed FindGObject.cmake not to use pkg-config variables directly.
+ * Fixed UseDoxygen.cmake to not output latex docs by default.
+
+Changes in dependencies:
+ * GStreamer 0.10.33 is now required.
+ * Qt 4.7 is now required.
+ * Flex and bison are no longer required.
+ * Automoc is no longer a mandatory dependency, if cmake >= 2.8.6 is present.
+
+qt-gstreamer 0.10.1 (2011-01-23)
+================================
+
+Initial release.
diff --git a/README b/README
index 05c1f7b..1d7d6cd 100644
--- a/README
+++ b/README
@@ -1,3 +1,30 @@
+0. Maintenance Notice
+---------------------
+
+This code is unmaintained. You can use it at your own risk.
+
+If you want to integrate video display in your QML-based UI,
+you should consider using 'qmlglsink', from gst-plugins-good.
+This is a well supported video sink that uses the generic
+gstreamer-gl stack and is in many ways superior to 'qtquick2videosink'
+that is provided by qt-gstreamer. You can use this code as an example:
+https://cgit.freedesktop.org/gstreamer/gst-plugins-good/tree/tests/examples/qt/qmlsink
+
+If you are not interested in using QML in your UI, then you
+may use one of the other elements provided by this module
+(see below). If you do that, it would be helpful to let us
+know that this code is still useful to you. We may consider
+adding these elements in one of the core gstreamer modules.
+
+If you are here for the Qt-style bindings, I'm sorry to disappoint you.
+The alternative is to use the C API, or the GStreamermm C++ API.
+Qt-style bindings are cool, but unfortunately they are very hard
+to maintain because they are written by hand. If you are interested
+in continuing this project, you are welcome to implement a
+generator for them, probably based on GObject-Introspection.
+I am happy to provide directions if you want to pursue such a thing.
+
+
1. About
--------
@@ -9,16 +36,20 @@ Currently, it consists of the following parts:
* QtGLib - Library providing C++/Qt bindings for parts of the GLib
and GObject APIs, a base on which QtGStreamer is built.
* QtGStreamer - Library providing C++/Qt bindings for GStreamer
- * QtGStreamerUi - Library providing integration with QtGui. Currently,
+ * QtGStreamerUi - Library providing integration with QtWidgets. Currently,
it only provides a video widget that embeds GStreamer's
video sinks.
* QtGStreamerUtils - Library providing some high level utility classes.
+ * QtGStreamerQuick - Library providing integration with QtQuick (Qt5 only).
-In addition, it provides a "qwidgetvideosink" GStreamer element, an video
-sink element that can draw directly on QWidgets using QPainter.
+In addition, it provides GStreamer elements for painting video on Qt surfaces:
+ * qwidgetvideosink - For painting on QWidgets
+ * qtvideosink - For painting on any surface with QPainter
+ * qtglvideosink - For painting on any surface with QPainter and OpenGL
+ * qtquick2videosink - For painting on QtQuick2 surfaces (Qt5 only)
[1]. http://gstreamer.freedesktop.org/
-[2]. http://qt.nokia.com/
+[2]. http://qt-project.org/
2. Building
-----------
@@ -27,16 +58,15 @@ sink element that can draw directly on QWidgets using QPainter.
----------------
QtGStreamer requires the following software to be installed in order to build:
- * CMake 2.8 or later <http://www.cmake.org/>
- * GStreamer 0.10.31 or later <http://gstreamer.freedesktop.org/>
+ * CMake 2.8.9 or later <http://www.cmake.org/>
+ * GStreamer 1.0.0 or later <http://gstreamer.freedesktop.org/>
With its dependencies:
- Glib / GObject <http://www.gtk.org/>
- and including gstreamer-plugins-base (0.10.31 or later)
- * Qt 4.5 or later <http://qt.nokia.com/>
- * Automoc <https://projects.kde.org/projects/kdesupport/automoc/>
+ and including gstreamer-plugins-base (1.0.0 or later)
+ * Qt4 or Qt5 (4.7 or later / 5.0 or later) <http://qt-project.org/>
* Boost 1.39 or later <http://www.boost.org/>
- * Flex <http://flex.sourceforge.net/>
- * Bison <http://www.gnu.org/software/bison/>
+ * Flex (only if QTGSTREAMER_CODEGEN=ON, see below) <http://flex.sourceforge.net/>
+ * Bison (only if QTGSTREAMER_CODEGEN=ON, see below) <http://www.gnu.org/software/bison/>
In addition, if gcc is used as the compiler, libstdc++ version 4.5 or later is
required at runtime. This is due to a bug in earlier versions of libstdc++ that
@@ -45,6 +75,10 @@ sometimes makes dynamic_cast fail under conditions where it should not.
2.2 Compiler
------------
+Note: This paragraph is outdated. It was written at a time where C++11 support
+was not very widespread among compilers. Nowadays, any C++11 capable compiler
+should work fine.
+
A decent compiler with proper support for advanced templates, including features
such as partial template specialization, is required. QtGStreamer can also make
use of C++0x features (see below for details). A compiler supporting at least
@@ -78,6 +112,10 @@ Other options that can be passed to cmake include:
Allows you to specify the type of the build. This is a standard
cmake option, see the cmake man page for details.
+* -DQT_VERSION=[4|5]
+ Allows you to specify the Qt version that you want to build against.
+ The default is 4.
+
* -DQTGSTREAMER_STATIC=[ON|OFF]
Allows you to choose whether to build static or dynamic libraries.
ON means static, OFF means dynamic.
@@ -89,6 +127,25 @@ Other options that can be passed to cmake include:
* -DQTGSTREAMER_TESTS=[ON|OFF]
Allows you to choose whether to build tests or not.
+* -DQTGSTREAMER_CODEGEN=[ON|OFF]
+ Allows you to choose whether to build and use the QtGStreamer code generator or not.
+ This code generator generates some extra code based on the QtGlib/QtGStreamer
+ headers. This extra code is required, but it is also shipped in the source tree,
+ so it is not necessary to regenerate it, unless you are developing QtGStreamer and
+ you are making changes to the headers. If you are crosscompiling, you should make
+ sure to turn this feature off, since this will compile codegen for the target
+ architecture and then try to run it, which will fail.
+
+* -DUSE_GST_PLUGIN_DIR=[ON|OFF]
+ Allows you to choose whether to install plugin together with the rest of the
+ gstreamer plugins or whether to install them in the same prefix as QtGStreamer.
+ You will probably want to set this to OFF if you are installing in a prefix
+ different than GStreamer (say somewhere in $HOME) while GStreamer is installed
+ in a system location and you don't want to gain root privileges to do "make install".
+
+* -DUSE_QT_PLUGIN_DIR=[ON|OFF]
+ Same as USE_GST_PLUGIN_DIR, but for Qt (QML) plugins.
+
* -DGST_PACKAGE_NAME="some string"
Allows you to specify the name that gst-inspect will show as the "Binary package"
name for all the element plugins that are build from this source package.
@@ -97,14 +154,26 @@ Other options that can be passed to cmake include:
Allows you to specify the url that gst-inspect will show as the "Origin URL"
for all the element plugins that are build from this source package.
-2.4 Generating documentation
+2.4 Parallel installation
+-------------------------
+
+QtGStreamer can be built both with Qt4 and Qt5. Installing both versions in
+parallel is possible, since all the libraries, directories and plugins are
+named differently.
+
+Parallel installation is also possible, to a certain extent, between the
+GStreamer-0.10 based version and the GStreamer-1.0 based version. The libraries
+and the GStreamer plugins are co-installable, however the QML plugins as well
+as the headers are NOT.
+
+2.5 Generating documentation
----------------------------
QtGStreamer uses doxygen for documentation. To generate the documentation you need
to install doxygen and run "make doc" after you have run cmake. This will generate
the documentation in <builddir>/doc/html/.
-2.5 Running tests
+2.6 Running tests
-----------------
QtGStreamer comes with a suite of automatic unit tests that ensure QtGStreamer
@@ -114,6 +183,25 @@ plus some gstreamer plugins from the base and good sets.
To run them, simply invoke "make test" or "ctest" in the build directory.
For advanced usage, refer to the ctest manual page.
+2.7 Checking build system integrity
+-----------------------------------
+
+In order to check if the installed build system files (QtGStreamerConfig.cmake,
+pkg-config files, etc) are correct and usable externally, you can run:
+
+$ make examples_distcheck
+
+This checks compilation of the examples with both cmake and qmake.
+
+Note that you should also set your environment accordingly for cmake and qmake
+to be able to find QtGStreamer. For example, on my debian system where I have
+installed the Qt5 version of QtGStreamer in /home/gkiagia/install, I would
+have to do:
+
+$ export QT_SELECT=5 # for debian's qmake wrapper to work with Qt5
+$ export PKG_CONFIG_PATH=/home/gkiagia/install/lib/x86_64-linux-gnu/pkgconfig/
+$ export CMAKE_PREFIX_PATH=/home/gkiagia/install/
+$ make examples_distcheck
3. Links & Contact information
------------------------------
@@ -123,18 +211,19 @@ Web:
http://gstreamer.freedesktop.org/wiki/QtGStreamer
Mailing list:
- mailto:gstreamer-devel@lists.sourceforge.net
+ mailto:gstreamer-devel@lists.freedesktop.org
Irc channels:
irc://irc.freenode.net/gstreamer
- irc://irc.freenode.net/qtgstreamer
Git repository:
http://cgit.freedesktop.org/gstreamer/qt-gstreamer/
Bugs, feature requests & patches should be sent at:
https://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer&component=qt-gstreamer
+ **Note**: This component has been closed as of May 5, 2018.
+ See the maintenance notice at the top of this file
--
-George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
-Last updated: Jan 10, 2011
+George Kiagiadakis <george.kiagiadakis@collabora.com>
+Last updated: May 5, 2018
diff --git a/cmake/modules/FindGLIB2.cmake b/cmake/modules/FindGLIB2.cmake
index b48b5f3..b608ab1 100644
--- a/cmake/modules/FindGLIB2.cmake
+++ b/cmake/modules/FindGLIB2.cmake
@@ -17,8 +17,10 @@ if(GLIB2_INCLUDE_DIR AND GLIB2_LIBRARIES)
endif(GLIB2_INCLUDE_DIR AND GLIB2_LIBRARIES)
if (NOT WIN32)
- find_package(PkgConfig REQUIRED)
- pkg_check_modules(PKG_GLIB REQUIRED glib-2.0)
+ find_package(PkgConfig QUIET)
+ if(PKG_CONFIG_FOUND)
+ pkg_check_modules(PKG_GLIB QUIET glib-2.0)
+ endif()
endif(NOT WIN32)
find_path(GLIB2_MAIN_INCLUDE_DIR glib.h
@@ -46,3 +48,19 @@ include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GLIB2 DEFAULT_MSG GLIB2_LIBRARIES GLIB2_MAIN_INCLUDE_DIR)
mark_as_advanced(GLIB2_INCLUDE_DIR GLIB2_LIBRARIES)
+
+
+find_program(GLIB2_GENMARSHAL_UTIL glib-genmarshal)
+
+macro(glib2_genmarshal output_name)
+ file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/genmarshal_tmp)
+ foreach(_declaration ${ARGN})
+ file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/genmarshal_tmp "${_declaration}\n")
+ endforeach()
+ add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${output_name}.h ${CMAKE_CURRENT_BINARY_DIR}/${output_name}.c
+ COMMAND ${GLIB2_GENMARSHAL_UTIL} --header genmarshal_tmp > ${output_name}.h
+ COMMAND ${GLIB2_GENMARSHAL_UTIL} --body genmarshal_tmp > ${output_name}.c
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ )
+endmacro()
diff --git a/cmake/modules/FindGObject.cmake b/cmake/modules/FindGObject.cmake
index 1a1e657..12a8af0 100644
--- a/cmake/modules/FindGObject.cmake
+++ b/cmake/modules/FindGObject.cmake
@@ -55,11 +55,7 @@ FIND_LIBRARY(_GLibs NAMES glib-2.0
${PKG_GOBJECT2_LIBDIR}
)
-IF (WIN32)
SET (GOBJECT_LIBRARIES ${_GObjectLibs} ${_GModuleLibs} ${_GThreadLibs} ${_GLibs})
-ELSE (WIN32)
-SET (GOBJECT_LIBRARIES ${PKG_GOBJECT2_LIBRARIES})
-ENDIF (WIN32)
MARK_AS_ADVANCED(GOBJECT_INCLUDE_DIR GOBJECT_LIBRARIES)
diff --git a/cmake/modules/FindGStreamer.cmake b/cmake/modules/FindGStreamer.cmake
index 4c990d0..8ad91ca 100644
--- a/cmake/modules/FindGStreamer.cmake
+++ b/cmake/modules/FindGStreamer.cmake
@@ -2,8 +2,10 @@
# Once done this will define
#
# GSTREAMER_FOUND - system has GStreamer
-# GSTREAMER_INCLUDE_DIR - the GStreamer include directory
+# GSTREAMER_INCLUDE_DIR - the GStreamer main include directory
+# GSTREAMER_INCLUDE_DIRS - the GStreamer include directories
# GSTREAMER_LIBRARY - the main GStreamer library
+# GSTREAMER_PLUGIN_DIR - the GStreamer plugin directory
#
# And for all the plugin libraries specified in the COMPONENTS
# of find_package, this module will define:
@@ -24,14 +26,20 @@ else()
set(GStreamer_FIND_QUIETLY FALSE)
endif()
-set(GSTREAMER_ABI_VERSION "0.10")
+set(GSTREAMER_ABI_VERSION "1.0")
# Find the main library
find_package(PkgConfig)
if (PKG_CONFIG_FOUND)
- pkg_check_modules(PKG_GSTREAMER gstreamer-${GSTREAMER_ABI_VERSION})
+ pkg_check_modules(PKG_GSTREAMER QUIET gstreamer-${GSTREAMER_ABI_VERSION})
+ if(PKG_GSTREAMER_FOUND)
+ exec_program(${PKG_CONFIG_EXECUTABLE}
+ ARGS --variable pluginsdir gstreamer-${GSTREAMER_ABI_VERSION}
+ OUTPUT_VARIABLE PKG_GSTREAMER_PLUGIN_DIR)
+ endif()
+ set(GSTREAMER_DEFINITIONS ${PKG_GSTREAMER_CFLAGS})
endif()
find_library(GSTREAMER_LIBRARY
@@ -43,14 +51,35 @@ find_path(GSTREAMER_INCLUDE_DIR
HINTS ${PKG_GSTREAMER_INCLUDE_DIRS} ${PKG_GSTREAMER_INCLUDEDIR}
PATH_SUFFIXES gstreamer-${GSTREAMER_ABI_VERSION})
-mark_as_advanced(GSTREAMER_LIBRARY GSTREAMER_INCLUDE_DIR)
+find_path(GSTREAMER_gstconfig_INCLUDE_DIR
+ gst/gstconfig.h
+ HINTS ${PKG_GSTREAMER_INCLUDE_DIRS} ${PKG_GSTREAMER_INCLUDEDIR}
+ PATH_SUFFIXES gstreamer-${GSTREAMER_ABI_VERSION})
+
+set(GSTREAMER_INCLUDE_DIRS ${GSTREAMER_INCLUDE_DIR} ${GSTREAMER_gstconfig_INCLUDE_DIR})
+list(REMOVE_DUPLICATES GSTREAMER_INCLUDE_DIRS)
+
+if (PKG_GSTREAMER_PLUGIN_DIR)
+ set(_GSTREAMER_PLUGIN_DIR ${PKG_GSTREAMER_PLUGIN_DIR})
+else()
+ get_filename_component(_GSTREAMER_LIB_DIR ${GSTREAMER_LIBRARY} PATH)
+ set(_GSTREAMER_PLUGIN_DIR ${_GSTREAMER_LIB_DIR}/gstreamer-${GSTREAMER_ABI_VERSION})
+endif()
+
+set(GSTREAMER_PLUGIN_DIR ${_GSTREAMER_PLUGIN_DIR}
+ CACHE PATH "The path to the gstreamer plugins installation directory")
+
+mark_as_advanced(GSTREAMER_LIBRARY
+ GSTREAMER_INCLUDE_DIR
+ GSTREAMER_gstconfig_INCLUDE_DIR
+ GSTREAMER_PLUGIN_DIR)
# Find additional libraries
include(MacroFindGStreamerLibrary)
macro(_find_gst_component _name _header)
- find_gstreamer_library(${_name} ${_header} ${GSTREAMER_ABI_VERSION})
+ find_gstreamer_library(${_name} ${_header} ${GSTREAMER_ABI_VERSION} ${GStreamer_FIND_QUIETLY})
set(_GSTREAMER_EXTRA_VARIABLES ${_GSTREAMER_EXTRA_VARIABLES}
GSTREAMER_${_name}_LIBRARY GSTREAMER_${_name}_INCLUDE_DIR)
endmacro()
@@ -61,9 +90,7 @@ foreach(_component ${GStreamer_FIND_COMPONENTS})
elseif (${_component} STREQUAL "check")
_find_gst_component(CHECK gstcheck.h)
elseif (${_component} STREQUAL "controller")
- _find_gst_component(CONTROLLER gstcontroller.h)
- elseif (${_component} STREQUAL "dataprotocol")
- _find_gst_component(DATAPROTOCOL dataprotocol.h)
+ _find_gst_component(CONTROLLER gstargbcontrolbinding.h)
elseif (${_component} STREQUAL "net")
_find_gst_component(NET gstnet.h)
else()
@@ -76,7 +103,9 @@ endforeach()
if (GStreamer_FIND_VERSION)
if (PKG_GSTREAMER_FOUND)
if("${PKG_GSTREAMER_VERSION}" VERSION_LESS "${GStreamer_FIND_VERSION}")
- message(STATUS "Found GStreamer version ${PKG_GSTREAMER_VERSION}, but at least version ${GStreamer_FIND_VERSION} is required")
+ if(NOT GStreamer_FIND_QUIETLY)
+ message(STATUS "Found GStreamer version ${PKG_GSTREAMER_VERSION}, but at least version ${GStreamer_FIND_VERSION} is required")
+ endif()
set(GSTREAMER_VERSION_COMPATIBLE FALSE)
else()
set(GSTREAMER_VERSION_COMPATIBLE TRUE)
@@ -101,7 +130,7 @@ int main() { return 0; }
#endif
" GSTREAMER_VERSION_COMPATIBLE)
- if (NOT GSTREAMER_VERSION_COMPATIBLE)
+ if (NOT GSTREAMER_VERSION_COMPATIBLE AND NOT GStreamer_FIND_QUIETLY)
message(STATUS "GStreamer ${GStreamer_FIND_VERSION} is required, but the version found is older")
endif()
else()
@@ -116,5 +145,5 @@ endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GStreamer DEFAULT_MSG
- GSTREAMER_LIBRARY GSTREAMER_INCLUDE_DIR
+ GSTREAMER_LIBRARY GSTREAMER_INCLUDE_DIRS
GSTREAMER_VERSION_COMPATIBLE ${_GSTREAMER_EXTRA_VARIABLES})
diff --git a/cmake/modules/FindGStreamerPluginsBase.cmake b/cmake/modules/FindGStreamerPluginsBase.cmake
index a795b27..516cdc0 100644
--- a/cmake/modules/FindGStreamerPluginsBase.cmake
+++ b/cmake/modules/FindGStreamerPluginsBase.cmake
@@ -16,22 +16,26 @@
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
-set(GSTREAMER_ABI_VERSION "0.10")
+set(GSTREAMER_ABI_VERSION "1.0")
# Find the pkg-config file for doing the version check
find_package(PkgConfig)
if (PKG_CONFIG_FOUND)
- pkg_check_modules(PKG_GSTREAMER_PLUGINS_BASE gstreamer-plugins-base-${GSTREAMER_ABI_VERSION})
+ pkg_check_modules(PKG_GSTREAMER_PLUGINS_BASE QUIET gstreamer-plugins-base-${GSTREAMER_ABI_VERSION})
endif()
# Find the plugin libraries
include(MacroFindGStreamerLibrary)
+if (NOT DEFINED GStreamerPluginsBase_FIND_QUIETLY)
+ set(GStreamerPluginsBase_FIND_QUIETLY 0)
+endif()
+
macro(_find_gst_plugins_base_component _name _header)
- find_gstreamer_library(${_name} ${_header} ${GSTREAMER_ABI_VERSION})
+ find_gstreamer_library(${_name} ${_header} ${GSTREAMER_ABI_VERSION} ${GStreamerPluginsBase_FIND_QUIETLY})
set(_GSTREAMER_PLUGINS_BASE_EXTRA_VARIABLES ${_GSTREAMER_PLUGINS_BASE_EXTRA_VARIABLES}
GSTREAMER_${_name}_LIBRARY GSTREAMER_${_name}_INCLUDE_DIR)
endmacro()
@@ -41,16 +45,8 @@ foreach(_component ${GStreamerPluginsBase_FIND_COMPONENTS})
_find_gst_plugins_base_component(APP gstappsrc.h)
elseif (${_component} STREQUAL "audio")
_find_gst_plugins_base_component(AUDIO audio.h)
- elseif (${_component} STREQUAL "cdda")
- _find_gst_plugins_base_component(CDDA gstcddabasesrc.h)
elseif (${_component} STREQUAL "fft")
_find_gst_plugins_base_component(FFT gstfft.h)
- elseif (${_component} STREQUAL "floatcast")
- _find_gst_plugins_base_component(FLOATCAST floatcast.h)
- elseif (${_component} STREQUAL "interfaces")
- _find_gst_plugins_base_component(INTERFACES xoverlay.h)
- elseif (${_component} STREQUAL "netbuffer")
- _find_gst_plugins_base_component(NETBUFFER gstnetbuffer.h)
elseif (${_component} STREQUAL "riff")
_find_gst_plugins_base_component(RIFF riff-ids.h)
elseif (${_component} STREQUAL "rtp")
@@ -75,7 +71,9 @@ endforeach()
if (GStreamerPluginsBase_FIND_VERSION)
if (PKG_GSTREAMER_PLUGINS_BASE_FOUND)
if("${PKG_GSTREAMER_PLUGINS_BASE_VERSION}" VERSION_LESS "${GStreamerPluginsBase_FIND_VERSION}")
- message(STATUS "Found gst-plugins-base version ${PKG_GSTREAMER_PLUGINS_BASE_VERSION}, but at least version ${GStreamerPluginsBase_FIND_VERSION} is required")
+ if (NOT GStreamerPluginsBase_FIND_QUIETLY)
+ message(STATUS "Found gst-plugins-base version ${PKG_GSTREAMER_PLUGINS_BASE_VERSION}, but at least version ${GStreamerPluginsBase_FIND_VERSION} is required")
+ endif()
set(GSTREAMER_PLUGINS_BASE_VERSION_COMPATIBLE FALSE)
else()
set(GSTREAMER_PLUGINS_BASE_VERSION_COMPATIBLE TRUE)
diff --git a/cmake/modules/FindOpenGLES2.cmake b/cmake/modules/FindOpenGLES2.cmake
new file mode 100644
index 0000000..2b6ecf4
--- /dev/null
+++ b/cmake/modules/FindOpenGLES2.cmake
@@ -0,0 +1,20 @@
+# - Try to find OpenGLES2
+# Once done this will define
+#
+# OPENGLES2_FOUND - system has OpenGLES2
+# OPENGLES2_INCLUDE_DIR - the GLES2 include directory
+# OPENGLES2_LIBRARY - the GLES2 library
+#
+# Copyright (c) 2012, George Kiagiadakis <kiagiadakis.george@gmail.com>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+find_path(OPENGLES2_INCLUDE_DIR GLES2/gl2.h)
+find_library(OPENGLES2_LIBRARY NAMES GLESv2)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(OpenGLES2 DEFAULT_MSG OPENGLES2_INCLUDE_DIR OPENGLES2_LIBRARY)
+
+mark_as_advanced(OPENGLES2_INCLUDE_DIR OPENGLES2_LIBRARY)
+
diff --git a/cmake/modules/FindQt4or5.cmake b/cmake/modules/FindQt4or5.cmake
new file mode 100644
index 0000000..d73b3a2
--- /dev/null
+++ b/cmake/modules/FindQt4or5.cmake
@@ -0,0 +1,235 @@
+# - Try to find an installed version of Qt based on QT_VERSION
+# Once done this will define
+#
+# Qt4or5_FOUND - The specified Qt version was found
+# Qt4or5_<Component>_FOUND - For each <Component> specified, if found
+# QT_QMAKE_EXECUTABLE - Path to qmake
+# QT_IMPORTS_DIR - Path to qtquick1 imports dir
+#
+# Use qt4or5_use_modules(target [ LINK_PUBLIC | LINK_PRIVATE ] <modules>)
+# to make use of Qt4 or Qt5 on a target
+#
+# Copyright (c) 2013, Fluendo S.L. <support@fluendo.com>
+# Copyright (c) 2013, Collabora Ltd. <info@collabora.com>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+set(QT_VERSION "4" CACHE STRING "Qt version used for the build")
+
+macro(_qt4or5_component_name_to_qt_component qt_component component)
+ if (${component} STREQUAL "Widgets" AND ${QT_VERSION} STREQUAL "4")
+ set(${qt_component} "Gui")
+ elseif (${component} STREQUAL "Quick1")
+ set(${qt_component} "Declarative")
+ elseif (${component} STREQUAL "Quick2" AND ${QT_VERSION} STREQUAL "5")
+ set(${qt_component} "Quick")
+ else()
+ set(${qt_component} ${component})
+ endif()
+endmacro()
+
+macro(_qt4or5_component_name_from_qt_component component qt_component)
+ if (${qt_component} STREQUAL "Declarative")
+ set(${component} "Quick1")
+ elseif (${qt_component} STREQUAL "Quick")
+ set(${component} "Quick2")
+ else()
+ set(${component} ${qt_component})
+ endif()
+endmacro()
+
+macro(_qt4or5_component_names_to_qt_components output_list)
+ foreach(module ${ARGN})
+ _qt4or5_component_name_to_qt_component(qt_component ${module})
+ list(APPEND ${output_list} ${qt_component})
+ unset(qt_component)
+ endforeach()
+
+ list(REMOVE_DUPLICATES ${output_list})
+endmacro()
+
+macro(_qt5_component_names_to_target_link_libaries output_list)
+ foreach(module ${ARGN})
+ _qt4or5_component_name_to_qt_component(qt_component ${module})
+ list(APPEND ${output_list} Qt5::${qt_component})
+ unset(qt_component)
+ endforeach()
+
+ list(REMOVE_DUPLICATES ${output_list})
+endmacro()
+
+if (Qt4or5_FIND_QUIETLY)
+ set(_Qt4or5_FIND_PACKAGE_ARGS QUIET)
+endif()
+
+_qt4or5_component_names_to_qt_components(_Qt4or5_FIND_COMPONENTS ${Qt4or5_FIND_COMPONENTS})
+_qt4or5_component_names_to_qt_components(_Qt4or5_FIND_COMPONENTS ${Qt4or5_FIND_OPTIONAL_COMPONENTS})
+
+if (${QT_VERSION} STREQUAL "5")
+
+ set(Qt4or5_MIN_VERSION "${Qt5_MIN_VERSION}")
+
+ if (NOT Qt4or5_FIND_QUIETLY)
+ message(STATUS "Using Qt5 (min: ${Qt4or5_MIN_VERSION})")
+ endif()
+
+ # Find Qt5 modules
+ foreach (qt_component ${_Qt4or5_FIND_COMPONENTS})
+ find_package(Qt5${qt_component} ${Qt5_MIN_VERSION} ${_Qt4or5_FIND_PACKAGE_ARGS})
+ if (Qt5${qt_component}_FOUND)
+ _qt4or5_component_name_from_qt_component(component ${qt_component})
+ set (Qt4or5_${component}_FOUND TRUE)
+ unset(component)
+ endif()
+ endforeach()
+
+ set(_Qt4or5_FOUND ${Qt5Core_FOUND})
+
+ # Set QT_QMAKE_EXECUTABLE, QT_IMPORTS_DIR and QT_QML_DIR
+ if (Qt5Core_FOUND)
+ get_target_property(QT_QMAKE_EXECUTABLE ${Qt5Core_QMAKE_EXECUTABLE} IMPORTED_LOCATION)
+
+ function(_QT5_QUERY_QMAKE VAR RESULT)
+ execute_process(COMMAND "${QT_QMAKE_EXECUTABLE}" -query ${VAR}
+ RESULT_VARIABLE return_code
+ OUTPUT_VARIABLE output
+ OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_STRIP_TRAILING_WHITESPACE)
+ if(NOT return_code)
+ file(TO_CMAKE_PATH "${output}" output)
+ set(${RESULT} ${output} PARENT_SCOPE)
+ endif()
+ endfunction()
+
+ _qt5_query_qmake(QT_INSTALL_IMPORTS QT_IMPORTS_DIR)
+ _qt5_query_qmake(QT_INSTALL_QML QT_QML_DIR)
+ endif()
+
+ # Set pkg-config package names
+ foreach(component Core Gui Widgets Quick1 Quick2 Test OpenGL)
+ _qt4or5_component_name_to_qt_component(qt_component ${component})
+ set(Qt4or5_${component}_PKGCONFIG_DEP "Qt5${qt_component}")
+ unset(qt_component)
+ endforeach()
+
+elseif (${QT_VERSION} STREQUAL "4")
+
+ set(Qt4or5_MIN_VERSION "${Qt4_MIN_VERSION}")
+
+ if (NOT Qt4or5_FIND_QUIETLY)
+ message(STATUS "Using Qt4 (min: ${Qt4or5_MIN_VERSION})")
+ endif()
+
+ # Find Qt4
+ set(QT_USE_IMPORTED_TARGETS TRUE)
+ find_package(Qt4 ${Qt4_MIN_VERSION} ${_Qt4or5_FIND_PACKAGE_ARGS})
+
+ set(_Qt4or5_FOUND ${QT4_FOUND})
+
+ # set Qt4or5_Foo_FOUND
+ foreach (qt_component ${_Qt4or5_FIND_COMPONENTS})
+ string(TOUPPER ${qt_component} u_qt_component)
+ if (QT_QT${u_qt_component}_FOUND)
+ _qt4or5_component_name_from_qt_component(component ${qt_component})
+ set (Qt4or5_${component}_FOUND TRUE)
+ # special case for QtWidgets, which is part of QtGui in Qt4
+ if (${component} STREQUAL "Gui")
+ set(Qt4or5_Widgets_FOUND TRUE)
+ endif()
+ unset(component)
+ endif()
+ unset(u_qt_component)
+ endforeach()
+
+ # define or include qt4_use_modules()
+ if (CMAKE_VERSION VERSION_LESS 2.8.10)
+ # copy-paste from Qt4Macros, just to support cmake 2.8.9
+ function(qt4_use_modules _target _link_type)
+ if ("${_link_type}" STREQUAL "LINK_PUBLIC" OR "${_link_type}" STREQUAL "LINK_PRIVATE")
+ set(modules ${ARGN})
+ set(link_type ${_link_type})
+ else()
+ set(modules ${_link_type} ${ARGN})
+ endif()
+ foreach(_module ${modules})
+ string(TOUPPER ${_module} _ucmodule)
+ if (NOT QT_QT${_ucmodule}_FOUND)
+ message(FATAL_ERROR "Can not use \"${_module}\" module which has not yet been found.")
+ endif()
+ if ("${_ucmodule}" STREQUAL "MAIN")
+ message(FATAL_ERROR "Can not use \"${_module}\" module with qt4_use_modules.")
+ endif()
+ target_link_libraries(${_target} ${link_type} ${QT_QT${_ucmodule}_LIBRARY})
+ set_property(TARGET ${_target} APPEND PROPERTY INCLUDE_DIRECTORIES
+ ${QT_QT${_ucmodule}_INCLUDE_DIR} ${QT_HEADERS_DIR} ${QT_MKSPECS_DIR}/default)
+ set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS
+ ${QT_QT${_ucmodule}_COMPILE_DEFINITIONS})
+ endforeach()
+ endfunction()
+ else()
+ include(Qt4Macros)
+ endif()
+
+ # Set pkg-config package names
+ foreach(component Core Gui Widgets Quick1 Quick2 Test OpenGL)
+ _qt4or5_component_name_to_qt_component(qt_component ${component})
+ set(Qt4or5_${component}_PKGCONFIG_DEP "Qt${qt_component}")
+ unset(qt_component)
+ endforeach()
+
+else()
+
+ message(WARNING "Unsupported QT_VERSION specified: ${QT_VERSION}")
+ set (_Qt4or5_FOUND FALSE)
+
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Qt4or5 REQUIRED_VARS _Qt4or5_FOUND HANDLE_COMPONENTS)
+set(Qt4or5_FOUND ${QT4OR5_FOUND})
+
+# Core library needed for compilation tests
+if (${QT_VERSION} STREQUAL "4")
+ set (Qt4or5_Core_LIBRARIES ${QT_QTCORE_LIBRARY})
+else()
+ set (Qt4or5_Core_LIBRARIES ${Qt5Core_LIBRARIES})
+endif()
+
+# qt4or5_use_modules(target [ LINK_PUBLIC | LINK_PRIVATE ] <modules>)
+# Supported modules: Core, Gui, Widgets, Quick1, Quick2, Test, OpenGL
+function(qt4or5_use_modules _target _link_type)
+ if ("${_link_type}" STREQUAL "LINK_PUBLIC" OR "${_link_type}" STREQUAL "LINK_PRIVATE")
+ set(modules ${ARGN})
+ set(link_type ${_link_type})
+ else()
+ set(modules ${_link_type} ${ARGN})
+ endif()
+
+ # Verify that Qt5 was found before using qt5_* macros,
+ # otherwise cmake will bail out if they are undefined.
+ if (${QT_VERSION} STREQUAL "5" AND Qt5Core_FOUND)
+ _qt5_component_names_to_target_link_libaries(real_modules ${modules})
+ target_link_libraries(${_target} ${link_type} ${real_modules})
+ elseif (${QT_VERSION} STREQUAL "4")
+ _qt4or5_component_names_to_qt_components(real_modules ${modules})
+ qt4_use_modules(${_target} ${link_type} ${real_modules})
+ endif()
+endfunction()
+
+# qt4or5_wrap_ui(outfiles inputfile ... )
+macro(qt4or5_wrap_ui)
+ if (${QT_VERSION} STREQUAL "5" AND Qt5Core_FOUND)
+ qt5_wrap_ui(${ARGV})
+ elseif (${QT_VERSION} STREQUAL "4")
+ qt4_wrap_ui(${ARGV})
+ endif()
+endmacro()
+
+# qt4or5_add_resources(outfiles inputfile ... )
+macro(qt4or5_add_resources)
+ if (${QT_VERSION} STREQUAL "5" AND Qt5Core_FOUND)
+ qt5_add_resources(${ARGV})
+ elseif (${QT_VERSION} STREQUAL "4")
+ qt4_add_resources(${ARGV})
+ endif()
+endmacro()
diff --git a/cmake/modules/FindQtGStreamer.cmake b/cmake/modules/FindQtGStreamer.cmake
deleted file mode 100644
index 4c7d3f4..0000000
--- a/cmake/modules/FindQtGStreamer.cmake
+++ /dev/null
@@ -1,125 +0,0 @@
-# - Try to find QtGStreamer
-# Once done this will define
-#
-# QTGSTREAMER_FOUND - system has QtGStreamer
-# QTGSTREAMER_INCLUDE_DIR - the QtGStreamer include directory
-# QTGSTREAMER_INCLUDES - the include directories needed to use QtGStreamer
-# QTGLIB_LIBRARY - the QtGLib library
-# QTGLIB_LIBRARIES - the libraries needed to use QtGLib
-# QTGSTREAMER_LIBRARY - the QtGStreamer library
-# QTGSTREAMER_LIBRARIES - the libraries needed to use QtGStreamer
-# QTGSTREAMER_UI_LIBRARY - the QtGStreamerUi library
-# QTGSTREAMER_UI_LIBRARIES - the libraries needed to use QtGStreamerUi
-# QTGSTREAMER_UTILS_LIBRARY - the QtGStreamerUtils library
-# QTGSTREAMER_UTILS_LIBRARIES - the libraries needed to use QtGStreamerUtils
-# QTGSTREAMER_DEFINITIONS - definitions recommended for using QtGStreamer
-# QTGSTREAMER_FLAGS - extra compiler switches recommended for using QtGStreamer
-#
-# Copyright (c) 2010, George Kiagiadakis <kiagiadakis.george@gmail.com>
-#
-# Redistribution and use is allowed according to the terms of the BSD license.
-# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
-
-
-# if variables are already in cache or we are building QtGStreamer
-if((QTGSTREAMER_LIBRARY AND QTGSTREAMER_INCLUDE_DIR) OR BUILDING_QTGSTREAMER)
- set(QtGStreamer_FIND_QUIETLY TRUE)
-else()
- set(QtGStreamer_FIND_QUIETLY FALSE)
-endif()
-
-set(_QTGSTREAMER_LINK_TO_QT_REQUIRED FALSE)
-
-if(BUILDING_QTGSTREAMER)
- set(QTGLIB_LIBRARY QtGLib)
- set(QTGSTREAMER_LIBRARY QtGStreamer)
- set(QTGSTREAMER_UI_LIBRARY QtGStreamerUi)
- set(QTGSTREAMER_UTILS_LIBRARY QtGStreamerUtils)
- set(QTGSTREAMER_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/src)
-else()
- # Attempt to find the generated QtGStreamerTargets.cmake in the same directory
- get_filename_component(_QTGSTREAMER_CONFIG_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
- find_file(_QTGSTREAMER_TARGETS_FILE QtGStreamerTargets.cmake PATHS ${_QTGSTREAMER_CONFIG_DIR} NO_DEFAULT_PATH)
-
- if(NOT _QTGSTREAMER_TARGETS_FILE)
- # Targets file not found. Do a typical search for QtGStreamer.
- # Normally, this path is never executed. It is just provided as a fallback in case something goes wrong.
- find_library(QTGLIB_LIBRARY QtGLib-2.0
- PATHS "${_QTGSTREAMER_CONFIG_DIR}/../../lib")
- find_library(QTGSTREAMER_LIBRARY QtGStreamer-0.10
- PATHS "${_QTGSTREAMER_CONFIG_DIR}/../../lib")
- find_library(QTGSTREAMER_UI_LIBRARY QtGStreamerUi-0.10
- PATHS "${_QTGSTREAMER_CONFIG_DIR}/../../lib")
- find_library(QTGSTREAMER_UTILS_LIBRARY QtGStreamerUtils-0.10
- PATHS "${_QTGSTREAMER_CONFIG_DIR}/../../lib")
- find_path(QTGSTREAMER_INCLUDE_DIR QGst/global.h
- PATHS "${_QTGSTREAMER_CONFIG_DIR}/../../include"
- PATH_SUFFIXES QtGStreamer)
- set(_QTGSTREAMER_LINK_TO_QT_REQUIRED TRUE)
- mark_as_advanced(QTGLIB_LIBRARY QTGSTREAMER_LIBRARY QTGSTREAMER_UI_LIBRARY
- QTGSTREAMER_UTILS_LIBRARY QTGSTREAMER_INCLUDE_DIR)
- else()
- # Targets file found. Use imported QtGStreamer target and relative include path.
- # We assume that this file has been installed in $PREFIX/lib/QtGStreamer/,
- # so the include path should evaluate to $PREFIX/include/QtGStreamer
- include(${_QTGSTREAMER_TARGETS_FILE})
- set(QTGLIB_LIBRARY QtGLib)
- set(QTGSTREAMER_LIBRARY QtGStreamer)
- set(QTGSTREAMER_UI_LIBRARY QtGStreamerUi)
- set(QTGSTREAMER_UTILS_LIBRARY QtGStreamerUtils)
- get_filename_component(QTGSTREAMER_INCLUDE_DIR "${_QTGSTREAMER_CONFIG_DIR}/../../include/QtGStreamer" ABSOLUTE)
- endif()
-endif()
-
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(QtGStreamer DEFAULT_MSG QTGSTREAMER_INCLUDE_DIR QTGLIB_LIBRARY
- QTGSTREAMER_LIBRARY QTGSTREAMER_UI_LIBRARY
- QTGSTREAMER_UTILS_LIBRARY)
-
-if(QTGSTREAMER_FOUND)
- # Find dependencies, if not already found
- if (NOT DEFINED QT_INCLUDE_DIR)
- message(STATUS "Qt hasn't been found yet. Looking...")
- find_package(Qt4 COMPONENTS QtCore QtGui REQUIRED)
- endif()
-
- if (NOT DEFINED Boost_INCLUDE_DIRS)
- message(STATUS "Boost hasn't been found yet. Looking...")
- find_package(Boost REQUIRED)
- endif()
-
- # Set misc variables
- set(QTGSTREAMER_INCLUDES ${QTGSTREAMER_INCLUDE_DIR} ${QT_INCLUDE_DIR} ${Boost_INCLUDE_DIRS})
- set(QTGSTREAMER_DEFINITIONS "-DQT_NO_KEYWORDS")
-
- if (_QTGSTREAMER_LINK_TO_QT_REQUIRED)
- set(QTGLIB_LIBRARIES ${QTGLIB_LIBRARY} ${QT_QTCORE_LIBRARY})
- set(QTGSTREAMER_LIBRARIES ${QTGSTREAMER_LIBRARY} ${QTGLIB_LIBRARIES})
- set(QTGSTREAMER_UI_LIBRARIES ${QTGSTREAMER_UI_LIBRARY} ${QT_QTGUI_LIBRARY} ${QTGSTREAMER_LIBRARIES})
- set(QTGSTREAMER_UTILS_LIBRARIES ${QTGSTREAMER_UTILS_LIBRARY} ${QTGSTREAMER_LIBRARIES})
- else()
- set(QTGLIB_LIBRARIES ${QTGLIB_LIBRARY})
- set(QTGSTREAMER_LIBRARIES ${QTGSTREAMER_LIBRARY})
- set(QTGSTREAMER_UI_LIBRARIES ${QTGSTREAMER_UI_LIBRARY})
- set(QTGSTREAMER_UTILS_LIBRARIES ${QTGSTREAMER_UTILS_LIBRARY})
- endif()
-
- if (CMAKE_COMPILER_IS_GNUCXX)
- execute_process(COMMAND ${CMAKE_CXX_COMPILER} "-dumpversion"
- RESULT_VARIABLE _GCC_DUMPVERSION_RESULT
- OUTPUT_VARIABLE _GCC_VERSION
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
-
- if ((${_GCC_DUMPVERSION_RESULT} EQUAL 0)
- AND (${_GCC_VERSION} VERSION_GREATER 4.4.99)
- AND (NOT QTGSTREAMER_DISABLE_CXX0X))
-
- if (NOT QTGSTREAMER_FLAGS) # be quiet if we try to find QtGStreamer multiple times
- message(STATUS "GCC 4.5 or later detected. Enabling C++0x support in QTGSTREAMER_FLAGS.")
- endif()
- set(QTGSTREAMER_FLAGS "-std=c++0x")
- endif()
- endif()
-
-endif()
diff --git a/cmake/modules/HandleImportedTargetsInCMakeRequiredLibraries.cmake b/cmake/modules/HandleImportedTargetsInCMakeRequiredLibraries.cmake
new file mode 100644
index 0000000..10b6806
--- /dev/null
+++ b/cmake/modules/HandleImportedTargetsInCMakeRequiredLibraries.cmake
@@ -0,0 +1,83 @@
+# This is a helper function used by CheckCXXSourceRuns.cmake and
+# CheckCXXSourceCompiles.cmake. Actually it should be used by all macros which
+# use TRY_COMPILE() or TRY_RUN().
+# It takes the CMAKE_REQUIRED_LIBRARY variable and searches it for imported
+# (library) targets. Since the project created by TRY_COMPILE() (and TRY_RUN())
+# does not know about these imported targets, this macro here replaces these
+# imported targets with the actual library files on disk and it also
+# adds the libraries from the link interface of these imported targets.
+# E.g the imported target KDE4__kdeui is replaced on my system with /opt/kdelibs/lib/libkdeui.so
+# and the link interface libraries, which includes e.g. /opt/kdelibs/lib/libkdecore.so.
+# This way imported targets work also when used with CHECK_CXX_SOURCE_COMPILES/RUNS().
+
+# Copyright (c) 2009, Alexander Neundorf, <neundorf@kde.org>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+FUNCTION(HANDLE_IMPORTED_TARGETS_IN_CMAKE_REQUIRED_LIBRARIES _RESULT)
+# handle imported library targets
+ SET(_CCSR_IMP_TARGETS_MAP)
+ SET(_CCSR_REQ_LIBS ${CMAKE_REQUIRED_LIBRARIES})
+ SET(_CHECK_FOR_IMPORTED_TARGETS TRUE)
+ SET(_CCSR_LOOP_COUNTER 0)
+ WHILE(_CHECK_FOR_IMPORTED_TARGETS)
+ MATH(EXPR _CCSR_LOOP_COUNTER "${_CCSR_LOOP_COUNTER} + 1 ")
+ SET(_CCSR_NEW_REQ_LIBS )
+ SET(_CHECK_FOR_IMPORTED_TARGETS FALSE)
+ FOREACH(_CURRENT_LIB ${_CCSR_REQ_LIBS})
+ GET_TARGET_PROPERTY(_importedConfigs ${_CURRENT_LIB} IMPORTED_CONFIGURATIONS)
+ IF (_importedConfigs)
+ # Ok, so this is an imported target.
+ # First we get the imported configurations.
+ # Then we get the location of the actual library on disk of the first configuration.
+ # then we'll get its link interface libraries property,
+ # iterate through it and replace all imported targets we find there
+ # with there actual location.
+
+ # guard against infinite loop: abort after 100 iterations ( 100 is arbitrary chosen)
+ IF ("${_CCSR_LOOP_COUNTER}" LESS 100)
+ SET(_CHECK_FOR_IMPORTED_TARGETS TRUE)
+# ELSE ("${_CCSR_LOOP_COUNTER}" LESS 1)
+# MESSAGE(STATUS "********* aborting loop, counter : ${_CCSR_LOOP_COUNTER}")
+ ENDIF ("${_CCSR_LOOP_COUNTER}" LESS 100)
+
+ LIST(GET _importedConfigs 0 _firstImportedConfig)
+ GET_TARGET_PROPERTY(_firstImportedLocation ${_CURRENT_LIB} IMPORTED_LOCATION_${_firstImportedConfig})
+ GET_TARGET_PROPERTY(_linkInterfaceLibs ${_CURRENT_LIB} IMPORTED_LINK_INTERFACE_LIBRARIES_${_firstImportedConfig} )
+
+ LIST(APPEND _CCSR_NEW_REQ_LIBS ${_firstImportedLocation})
+# MESSAGE(STATUS "Appending lib ${_CURRENT_LIB} as ${_firstImportedLocation}")
+ IF(_linkInterfaceLibs)
+ FOREACH(_currentLinkInterfaceLib ${_linkInterfaceLibs})
+# MESSAGE(STATUS "Appending link interface lib ${_currentLinkInterfaceLib}")
+ IF(_currentLinkInterfaceLib)
+ LIST(APPEND _CCSR_NEW_REQ_LIBS ${_currentLinkInterfaceLib} )
+ ENDIF(_currentLinkInterfaceLib)
+ ENDFOREACH(_currentLinkInterfaceLib ${_linkInterfaceLibs})
+ ENDIF(_linkInterfaceLibs)
+ ELSE(_importedConfigs)
+ # "Normal" libraries are just used as they are.
+ LIST(APPEND _CCSR_NEW_REQ_LIBS ${_CURRENT_LIB} )
+# MESSAGE(STATUS "Appending lib directly: ${_CURRENT_LIB}")
+ ENDIF(_importedConfigs)
+ ENDFOREACH(_CURRENT_LIB ${_CCSR_REQ_LIBS})
+
+ SET(_CCSR_REQ_LIBS ${_CCSR_NEW_REQ_LIBS} )
+ ENDWHILE(_CHECK_FOR_IMPORTED_TARGETS)
+
+ # Finally we iterate once more over all libraries. This loop only removes
+ # all remaining imported target names (there shouldn't be any left anyway).
+ SET(_CCSR_NEW_REQ_LIBS )
+ FOREACH(_CURRENT_LIB ${_CCSR_REQ_LIBS})
+ GET_TARGET_PROPERTY(_importedConfigs ${_CURRENT_LIB} IMPORTED_CONFIGURATIONS)
+ IF (NOT _importedConfigs)
+ LIST(APPEND _CCSR_NEW_REQ_LIBS ${_CURRENT_LIB} )
+# MESSAGE(STATUS "final: appending ${_CURRENT_LIB}")
+ ELSE (NOT _importedConfigs)
+# MESSAGE(STATUS "final: skipping ${_CURRENT_LIB}")
+ ENDIF (NOT _importedConfigs)
+ ENDFOREACH(_CURRENT_LIB ${_CCSR_REQ_LIBS})
+ SET(${_RESULT} ${_CCSR_NEW_REQ_LIBS} PARENT_SCOPE)
+
+ENDFUNCTION(HANDLE_IMPORTED_TARGETS_IN_CMAKE_REQUIRED_LIBRARIES _RESULT)
diff --git a/cmake/modules/MacroFindGStreamerLibrary.cmake b/cmake/modules/MacroFindGStreamerLibrary.cmake
index 761a80c..b46cbe8 100644
--- a/cmake/modules/MacroFindGStreamerLibrary.cmake
+++ b/cmake/modules/MacroFindGStreamerLibrary.cmake
@@ -6,7 +6,7 @@
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
-macro(find_gstreamer_library _name _header _abi_version)
+macro(find_gstreamer_library _name _header _abi_version _quiet)
string(TOLOWER ${_name} _lower_name)
string(TOUPPER ${_name} _upper_name)
@@ -17,7 +17,7 @@ macro(find_gstreamer_library _name _header _abi_version)
endif()
if (PKG_CONFIG_FOUND)
- pkg_check_modules(PKG_GSTREAMER_${_upper_name} gstreamer-${_lower_name}-${_abi_version})
+ pkg_check_modules(PKG_GSTREAMER_${_upper_name} QUIET gstreamer-${_lower_name}-${_abi_version})
endif()
find_library(GSTREAMER_${_upper_name}_LIBRARY
@@ -39,7 +39,7 @@ macro(find_gstreamer_library _name _header _abi_version)
set(GSTREAMER_${_upper_name}_LIBRARY_FOUND FALSE)
endif()
- if (NOT _GSTREAMER_${_upper_name}_QUIET)
+ if (NOT _GSTREAMER_${_upper_name}_QUIET AND NOT _quiet)
if (GSTREAMER_${_upper_name}_LIBRARY)
message(STATUS "Found GSTREAMER_${_upper_name}_LIBRARY: ${GSTREAMER_${_upper_name}_LIBRARY}")
else()
diff --git a/cmake/modules/QtGStreamerConfig.cmake.in b/cmake/modules/QtGStreamerConfig.cmake.in
new file mode 100644
index 0000000..54c5456
--- /dev/null
+++ b/cmake/modules/QtGStreamerConfig.cmake.in
@@ -0,0 +1,74 @@
+set(QTGSTREAMER_VERSION @QTGSTREAMER_VERSION@)
+
+@PACKAGE_INIT@
+
+get_filename_component(_QTGSTREAMER_CONFIG_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
+
+# include the generated QtGStreamerTargets.cmake from the same directory
+find_file(_QTGSTREAMER_TARGETS_FILE @QTGSTREAMER_PACKAGE_NAME@Targets.cmake
+ PATHS ${_QTGSTREAMER_CONFIG_DIR} NO_DEFAULT_PATH)
+include(${_QTGSTREAMER_TARGETS_FILE})
+unset(_QTGSTREAMER_TARGETS_FILE)
+
+set(@QTGSTREAMER_PACKAGE_NAME@_FOUND TRUE)
+set(QTGLIB_LIBRARY @QTGLIB_LIBRARY@)
+set(QTGSTREAMER_LIBRARY @QTGSTREAMER_LIBRARY@)
+set(QTGSTREAMER_QUICK_LIBRARY @QTGSTREAMER_QUICK_LIBRARY@)
+set(QTGSTREAMER_UI_LIBRARY @QTGSTREAMER_UI_LIBRARY@)
+set(QTGSTREAMER_UTILS_LIBRARY @QTGSTREAMER_UTILS_LIBRARY@)
+set_and_check(QTGSTREAMER_INCLUDE_DIR @PACKAGE_QTGSTREAMER_INCLUDES_INSTALL_DIR@)
+
+if (@QTGSTREAMER_PACKAGE_NAME@_FIND_QUIET)
+ set(_QTGSTREAMER_FIND_DEPS_ARGS QUIET)
+endif()
+
+# Find dependencies, if not already found
+if ("@QTGSTREAMER_PACKAGE_NAME@" STREQUAL "Qt5GStreamer")
+ if (NOT DEFINED Qt5Core_INCLUDE_DIRS)
+ if (NOT @QTGSTREAMER_PACKAGE_NAME@_FIND_QUIET)
+ message(STATUS "Qt5 hasn't been found yet. Looking...")
+ endif()
+
+ find_package(Qt5Core ${_QTGSTREAMER_FIND_DEPS_ARGS})
+
+ # import targets for linking to QtGStreamerUi, but don't fail
+ # if they are not found. One may only want QtGStreamer (no Ui).
+ find_package(Qt5Widgets QUIET)
+
+ if (NOT Qt5Core_FOUND)
+ set (@QTGSTREAMER_PACKAGE_NAME@_FOUND FALSE)
+ endif()
+ endif()
+else()
+ if (NOT DEFINED QT_INCLUDE_DIR)
+ if (NOT @QTGSTREAMER_PACKAGE_NAME@_FIND_QUIET)
+ message(STATUS "Qt4 hasn't been found yet. Looking...")
+ endif()
+
+ find_package(Qt4 COMPONENTS QtCore ${_QTGSTREAMER_FIND_DEPS_ARGS})
+
+ if (NOT Qt4_FOUND)
+ set (@QTGSTREAMER_PACKAGE_NAME@_FOUND FALSE)
+ endif()
+ endif()
+endif()
+
+if (NOT DEFINED Boost_INCLUDE_DIRS)
+ if (NOT @QTGSTREAMER_PACKAGE_NAME@_FIND_QUIET)
+ message(STATUS "Boost hasn't been found yet. Looking...")
+ endif()
+
+ find_package(Boost ${_QTGSTREAMER_FIND_DEPS_ARGS})
+
+ if (NOT Boost_FOUND)
+ set (@QTGSTREAMER_PACKAGE_NAME@_FOUND FALSE)
+ endif()
+endif()
+
+unset(_QTGSTREAMER_FIND_DEPS_ARGS)
+
+include("${CMAKE_CURRENT_LIST_DIR}/QtGStreamerConfigCommon.cmake")
+include("${CMAKE_CURRENT_LIST_DIR}/@QTGSTREAMER_PACKAGE_NAME@Targets.cmake")
+
+# compatibility variable
+set(QTGSTREAMER_FOUND ${@QTGSTREAMER_PACKAGE_NAME@_FOUND})
diff --git a/cmake/modules/QtGStreamerConfigCommon.cmake b/cmake/modules/QtGStreamerConfigCommon.cmake
new file mode 100644
index 0000000..b0dba33
--- /dev/null
+++ b/cmake/modules/QtGStreamerConfigCommon.cmake
@@ -0,0 +1,31 @@
+set(QTGLIB_LIBRARIES ${QTGLIB_LIBRARY})
+set(QTGSTREAMER_LIBRARIES ${QTGSTREAMER_LIBRARY})
+set(QTGSTREAMER_UI_LIBRARIES ${QTGSTREAMER_UI_LIBRARY})
+set(QTGSTREAMER_UTILS_LIBRARIES ${QTGSTREAMER_UTILS_LIBRARY})
+set(QTGSTREAMER_INCLUDES ${QTGSTREAMER_INCLUDE_DIR} ${Boost_INCLUDE_DIRS})
+set(QTGSTREAMER_DEFINITIONS "-DQT_NO_KEYWORDS")
+
+if (${QTGSTREAMER_LIBRARY} MATCHES ".*Qt5GStreamer.*")
+ set(QTGSTREAMER_QUICK_LIBRARIES ${QTGSTREAMER_QUICK_LIBRARY})
+ set(QTGSTREAMER_INCLUDES ${QTGSTREAMER_INCLUDES} ${Qt5Core_INCLUDE_DIRS})
+else()
+ set(QTGSTREAMER_INCLUDES ${QTGSTREAMER_INCLUDES} ${QT_INCLUDE_DIR})
+endif()
+
+if (CMAKE_COMPILER_IS_GNUCXX)
+ execute_process(COMMAND ${CMAKE_CXX_COMPILER} "-dumpversion"
+ RESULT_VARIABLE _GCC_DUMPVERSION_RESULT
+ OUTPUT_VARIABLE _GCC_VERSION
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ if ((${_GCC_DUMPVERSION_RESULT} EQUAL 0)
+ AND (${_GCC_VERSION} VERSION_GREATER 4.4.99)
+ AND (NOT QTGSTREAMER_DISABLE_CXX0X))
+
+ if (NOT QTGSTREAMER_FLAGS) # be quiet if we try to find QtGStreamer multiple times
+ message(STATUS "GCC 4.5 or later detected. Enabling C++0x support in QTGSTREAMER_FLAGS.")
+ endif()
+ set(QTGSTREAMER_FLAGS "-std=c++0x")
+ endif()
+endif()
diff --git a/codegen/CMakeLists.txt b/codegen/CMakeLists.txt
index ef26b04..f0318dc 100644
--- a/codegen/CMakeLists.txt
+++ b/codegen/CMakeLists.txt
@@ -1,5 +1,3 @@
-include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${QT_INCLUDE_DIR})
-
flex_target(analyzer analyzer.l ${CMAKE_CURRENT_BINARY_DIR}/analyzer.cpp)
bison_target(parser parser.y ${CMAKE_CURRENT_BINARY_DIR}/parser.cpp COMPILE_FLAGS "--defines")
add_flex_bison_dependency(analyzer parser)
@@ -12,4 +10,4 @@ if (MSVC)
endif()
add_executable(codegen ${FLEX_analyzer_OUTPUTS} ${BISON_parser_OUTPUTS} generator.cpp)
-target_link_libraries(codegen ${QT_QTCORE_LIBRARY})
+qt4or5_use_modules(codegen Core)
diff --git a/codegen/analyzer.l b/codegen/analyzer.l
index 3ea81cb..4417fa4 100644
--- a/codegen/analyzer.l
+++ b/codegen/analyzer.l
@@ -11,14 +11,14 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
*/
%{
-#include "yystype.h"
#include "generator.h"
+#include "yystype.h"
#define YY_DECL int yylex(CodeGen *codegen)
void yyerror(CodeGen *codegen, const char *msg);
diff --git a/codegen/generator.cpp b/codegen/generator.cpp
index 08acf57..5359b13 100644
--- a/codegen/generator.cpp
+++ b/codegen/generator.cpp
@@ -11,7 +11,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -32,15 +32,35 @@ int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QTextStream outStream(stdout);
- outStream << "// Autogenerated by the QtGStreamer helper code generator" << endl
- << "#define INCLUDED_FROM_CODEGEN" << endl
- << "#include <boost/static_assert.hpp>" << endl
- << endl
- << "#define REGISTER_TYPE_IMPLEMENTATION(T, GTYPE) \\" << endl
- << " namespace QGlib { \\" << endl
- << " GetTypeImpl<T>::operator Type() { return (GTYPE); } \\" << endl
- << " }" << endl
- << endl;
+ outStream
+ << "// Autogenerated by the QtGStreamer helper code generator - DO NOT EDIT" << endl
+ << "/*" << endl
+ << " Copyright (C) 2010 George Kiagiadakis <kiagiadakis.george@gmail.com>" << endl
+ << " Copyright (C) 2010 Collabora Ltd." << endl
+ << " @author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>" << endl
+ << endl
+ << " This library is free software; you can redistribute it and/or modify" << endl
+ << " it under the terms of the GNU Lesser General Public License as published" << endl
+ << " by the Free Software Foundation; either version 2.1 of the License, or" << endl
+ << " (at your option) any later version." << endl
+ << endl
+ << " This program is distributed in the hope that it will be useful," << endl
+ << " but WITHOUT ANY WARRANTY; without even the implied warranty of" << endl
+ << " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the" << endl
+ << " GNU Lesser General Public License for more details." << endl
+ << endl
+ << " You should have received a copy of the GNU Lesser General Public License" << endl
+ << " along with this program. If not, see <http://www.gnu.org/licenses/>." << endl
+ << "*/" << endl
+ << endl
+ << "#define INCLUDED_FROM_CODEGEN" << endl
+ << "#include <boost/static_assert.hpp>" << endl
+ << endl
+ << "#define REGISTER_TYPE_IMPLEMENTATION(T, GTYPE) \\" << endl
+ << " namespace QGlib { \\" << endl
+ << " GetTypeImpl<T>::operator Type() { return (GTYPE); } \\" << endl
+ << " }" << endl
+ << endl;
for (int i=1; i<argc; ++i) {
QString fileName(QFile::decodeName(argv[i]));
diff --git a/codegen/generator.h b/codegen/generator.h
index 3108fc2..9927e2e 100644
--- a/codegen/generator.h
+++ b/codegen/generator.h
@@ -11,7 +11,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/codegen/parser.y b/codegen/parser.y
index 1417d99..b3753cf 100644
--- a/codegen/parser.y
+++ b/codegen/parser.y
@@ -11,14 +11,14 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
*/
%{
-#include "yystype.h"
#include "generator.h"
+#include "yystype.h"
int yylex(CodeGen *codegen);
void yyerror(CodeGen *codegen, const char *msg);
diff --git a/codegen/yystype.h b/codegen/yystype.h
index 54b3f29..6e854b6 100644
--- a/codegen/yystype.h
+++ b/codegen/yystype.h
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/elements/CMakeLists.txt b/elements/CMakeLists.txt
index 0991a9b..242d082 100644
--- a/elements/CMakeLists.txt
+++ b/elements/CMakeLists.txt
@@ -4,17 +4,13 @@ set(GST_PACKAGE_ORIGIN "http://gstreamer.freedesktop.org/" CACHE STRING "The ori
add_definitions(-DPACKAGE="qt-gstreamer"
-DPACKAGE_NAME="${GST_PACKAGE_NAME}"
-DPACKAGE_ORIGIN="${GST_PACKAGE_ORIGIN}"
- -DPACKAGE_VERSION="${QTGSTREAMER_VERSION}")
+ -DPACKAGE_VERSION="${QTGSTREAMER_VERSION}"
+ -DGST_DISABLE_XML
+ -DGST_DISABLE_LOADSAVE)
-if (GSTREAMER_BASE_LIBRARY_FOUND AND GSTREAMER_VIDEO_LIBRARY_FOUND)
- include_directories(${CMAKE_CURRENT_BINARY_DIR} ${QT_INCLUDE_DIR} ${GSTREAMER_INCLUDE_DIR}
- ${GLIB2_INCLUDE_DIR} ${GSTREAMER_BASE_INCLUDE_DIR}
- ${GSTREAMER_VIDEO_INCLUDE_DIR})
- add_definitions(-DGST_DISABLE_XML -DGST_DISABLE_LOADSAVE)
+include_directories(${GSTREAMER_INCLUDE_DIRS} ${GLIB2_INCLUDE_DIR})
- automoc4_add_library(gstqwidgetvideosink MODULE gstqwidgetvideosink.cpp)
- target_link_libraries(gstqwidgetvideosink ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY}
- ${GOBJECT_LIBRARIES} ${GSTREAMER_LIBRARY}
- ${GSTREAMER_BASE_LIBRARY} ${GSTREAMER_VIDEO_LIBRARY})
- install(TARGETS gstqwidgetvideosink DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/gstreamer-0.10)
+if (GSTREAMER_BASE_LIBRARY_FOUND AND GSTREAMER_VIDEO_LIBRARY_FOUND)
+ include_directories(${GSTREAMER_BASE_INCLUDE_DIR} ${GSTREAMER_VIDEO_INCLUDE_DIR})
+ add_subdirectory(gstqtvideosink)
endif()
diff --git a/elements/gstqtvideosink/CMakeLists.txt b/elements/gstqtvideosink/CMakeLists.txt
new file mode 100644
index 0000000..65265a0
--- /dev/null
+++ b/elements/gstqtvideosink/CMakeLists.txt
@@ -0,0 +1,106 @@
+glib2_genmarshal(gstqtvideosinkmarshal
+ VOID:POINTER,FLOAT,FLOAT,FLOAT,FLOAT
+ VOID:POINTER,DOUBLE,DOUBLE,DOUBLE,DOUBLE
+ POINTER:POINTER,FLOAT,FLOAT,FLOAT,FLOAT
+ POINTER:POINTER,DOUBLE,DOUBLE,DOUBLE,DOUBLE
+)
+
+set(GstQtVideoSink_SRCS
+ utils/utils.cpp
+ utils/bufferformat.cpp
+
+ painters/genericsurfacepainter.cpp
+
+ delegates/basedelegate.cpp
+ delegates/qtvideosinkdelegate.cpp
+ delegates/qwidgetvideosinkdelegate.cpp
+
+ gstqtvideosinkplugin.cpp
+ gstqtvideosinkbase.cpp
+ gstqtvideosink.cpp
+ gstqwidgetvideosink.cpp
+
+ ${CMAKE_CURRENT_BINARY_DIR}/gstqtvideosinkmarshal.c
+)
+
+if (Qt4or5_Quick2_FOUND AND (OPENGL_FOUND OR OPENGLES2_FOUND))
+ set(GstQtVideoSink_SRCS
+ ${GstQtVideoSink_SRCS}
+ painters/videomaterial.cpp
+ painters/videonode.cpp
+
+ delegates/qtquick2videosinkdelegate.cpp
+
+ gstqtquick2videosink.cpp
+ )
+ set(GstQtVideoSink_LINK_OPENGL TRUE)
+endif()
+
+if (Qt4or5_OpenGL_FOUND AND (OPENGL_FOUND OR OPENGLES2_FOUND))
+ set(GstQtVideoSink_SRCS
+ ${GstQtVideoSink_SRCS}
+ painters/openglsurfacepainter.cpp
+ gstqtglvideosinkbase.cpp
+ gstqtglvideosink.cpp
+ )
+ set(GstQtVideoSink_test_GL_SRCS
+ painters/openglsurfacepainter.cpp
+ )
+ set(GstQtVideoSink_LINK_OPENGL TRUE)
+else()
+ add_definitions(-DGST_QT_VIDEO_SINK_NO_OPENGL)
+endif()
+
+add_definitions(
+ -DQTVIDEOSINK_NAME=${QTVIDEOSINK_NAME}
+ -DQTGLVIDEOSINK_NAME=${QTGLVIDEOSINK_NAME}
+ -DQWIDGETVIDEOSINK_NAME=${QWIDGETVIDEOSINK_NAME}
+)
+
+if (GstQtVideoSink_LINK_OPENGL)
+ if (OPENGLES2_FOUND)
+ set(GstQtVideoSink_GL_LIBS ${OPENGLES2_LIBRARY})
+ include_directories(${OPENGLES2_INCLUDE_DIR})
+ else()
+ set(GstQtVideoSink_GL_LIBS ${OPENGL_gl_LIBRARY})
+ include_directories(${OPENGL_INCLUDE_DIR})
+ endif()
+endif()
+
+add_library(gst${QTVIDEOSINK_NAME} MODULE ${GstQtVideoSink_SRCS})
+target_link_libraries(gst${QTVIDEOSINK_NAME}
+ ${GOBJECT_LIBRARIES}
+ ${GSTREAMER_LIBRARY}
+ ${GSTREAMER_BASE_LIBRARY}
+ ${GSTREAMER_VIDEO_LIBRARY}
+ ${GstQtVideoSink_GL_LIBS}
+)
+qt4or5_use_modules(gst${QTVIDEOSINK_NAME} Core Gui Widgets)
+if (Qt4or5_Quick2_FOUND AND (OPENGL_FOUND OR OPENGLES2_FOUND))
+ qt4or5_use_modules(gst${QTVIDEOSINK_NAME} Quick2)
+endif()
+if (Qt4or5_OpenGL_FOUND AND (OPENGL_FOUND OR OPENGLES2_FOUND))
+ qt4or5_use_modules(gst${QTVIDEOSINK_NAME} OpenGL)
+endif()
+install(TARGETS gst${QTVIDEOSINK_NAME} DESTINATION ${QTGSTREAMER_GST_PLUGINS_INSTALL_DIR})
+
+if (QTGSTREAMER_TESTS)
+ add_executable(qtvideosink_autotest
+ autotest.cpp
+ utils/utils.cpp
+ utils/bufferformat.cpp
+ painters/genericsurfacepainter.cpp
+ ${GstQtVideoSink_test_GL_SRCS}
+ )
+ target_link_libraries(qtvideosink_autotest
+ ${GOBJECT_LIBRARIES}
+ ${GSTREAMER_LIBRARY}
+ ${GSTREAMER_BASE_LIBRARY}
+ ${GSTREAMER_VIDEO_LIBRARY}
+ ${GstQtVideoSink_GL_LIBS}
+ )
+ qt4or5_use_modules(qtvideosink_autotest Core Gui Widgets Test)
+ if (Qt4or5_OpenGL_FOUND AND (OPENGL_FOUND OR OPENGLES2_FOUND))
+ qt4or5_use_modules(qtvideosink_autotest OpenGL)
+ endif()
+endif()
diff --git a/elements/gstqtvideosink/autotest.cpp b/elements/gstqtvideosink/autotest.cpp
new file mode 100644
index 0000000..6674ab2
--- /dev/null
+++ b/elements/gstqtvideosink/autotest.cpp
@@ -0,0 +1,1041 @@
+/*
+ Copyright (C) 2012 Collabora Ltd.
+ @author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#include <gst/gst.h>
+#include <gst/video/video.h>
+
+#include <QTest>
+#include <QPainter>
+#include <QDebug>
+#include <QWidget>
+#include <QLabel>
+#include <QGridLayout>
+
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
+# define SkipSingle 0
+# define SkipAll 0
+# define QSKIP_PORT(m, a) QSKIP(m)
+#else
+# define QSKIP_PORT(m, a) QSKIP(m, a)
+#endif
+
+#ifndef GST_QT_VIDEO_SINK_NO_OPENGL
+# include "painters/openglsurfacepainter.h"
+# include <QGLWidget>
+# include <QGLPixelBuffer>
+#endif
+
+#include "painters/genericsurfacepainter.h"
+
+Q_DECLARE_METATYPE(Qt::AspectRatioMode)
+
+struct PipelineDeleter
+{
+ static inline void cleanup(GstPipeline *ptr) {
+ if (ptr) {
+ gst_element_set_state(GST_ELEMENT(ptr), GST_STATE_NULL);
+ g_object_unref(ptr);
+ }
+ }
+};
+
+typedef QScopedPointer<GstPipeline, PipelineDeleter> GstPipelinePtr;
+
+
+struct ElementDeleter
+{
+ static inline void cleanup(GstElement *ptr) {
+ if (ptr) {
+ g_object_unref(ptr);
+ }
+ }
+};
+
+typedef QScopedPointer<GstElement, ElementDeleter> GstElementPtr;
+
+
+struct SampleDeleter
+{
+ static inline void cleanup(GstSample *ptr) {
+ if (ptr) {
+ gst_sample_unref(ptr);
+ }
+ }
+};
+
+typedef QScopedPointer<GstSample, SampleDeleter> GstSamplePtr;
+
+//------------------------------------
+
+template <class T>
+class VideoWidgetT : public T
+{
+public:
+ explicit VideoWidgetT(QWidget *parent = 0)
+ : T(parent), m_sink(NULL) {}
+
+ virtual ~VideoWidgetT() {
+ if (m_sink) {
+ g_object_unref(m_sink);
+ }
+ }
+
+ void setVideoSink(GstElement *sink) {
+ m_sink = sink;
+ g_object_connect(m_sink, "signal::update", &VideoWidgetT::onUpdate, this, NULL);
+ this->setAttribute(Qt::WA_OpaquePaintEvent, true);
+ }
+
+protected:
+ virtual void paintEvent(QPaintEvent*)
+ {
+ QPainter painter(this);
+ QRect targetArea = this->rect();
+ if (m_sink) {
+ g_signal_emit_by_name(m_sink, "paint", (void*)&painter,
+ (qreal) targetArea.x(), (qreal) targetArea.y(),
+ (qreal) targetArea.width(), (qreal) targetArea.height(), NULL);
+ } else {
+ painter.fillRect(targetArea, Qt::black);
+ }
+ }
+
+private:
+ static void onUpdate(GstElement*, VideoWidgetT *self) { self->update(); }
+
+ GstElement *m_sink;
+};
+
+typedef VideoWidgetT<QWidget> VideoWidget;
+
+#ifndef GST_QT_VIDEO_SINK_NO_OPENGL
+typedef VideoWidgetT<QGLWidget> VideoGLWidget;
+#endif
+
+//------------------------------------
+
+class QtVideoSinkTest : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QtVideoSinkTest(QObject* parent = 0)
+ : QObject(parent), haveArbFp(false), haveGlsl(false) {}
+
+private Q_SLOTS:
+ void initTestCase();
+
+ void bufferFormatTest_data();
+ void bufferFormatTest();
+
+ void paintAreasTest_data();
+ void paintAreasTest();
+
+ void genericSurfacePainterFormatsTest_data();
+ void genericSurfacePainterFormatsTest();
+
+#ifndef GST_QT_VIDEO_SINK_NO_OPENGL
+ void glSurfacePainterFormatsTest_data();
+ void glSurfacePainterFormatsTest();
+#endif
+
+ void qtVideoSinkTest_data();
+ void qtVideoSinkTest();
+
+ void cleanupTestCase();
+
+private:
+ GstSample *generateTestSample(GstVideoFormat format, int pattern);
+ GstPipeline *constructPipeline(GstCaps *caps, GstCaps *fakesinkCaps,
+ bool forceAspectRatio, void *context);
+ void imageCompare(const QImage & image1, const QImage & image2, const QSize & sourceSize);
+ bool pixelsSimilar(const QRgb & pixel1, const QRgb & pixel2);
+
+ bool haveArbFp;
+ bool haveGlsl;
+};
+
+//------------------------------------
+
+void QtVideoSinkTest::initTestCase()
+{
+ gst_init(NULL, NULL);
+
+#ifndef GST_QT_VIDEO_SINK_NO_OPENGL
+ // this is just to create a gl context
+ QGLPixelBuffer pixelBuffer(100, 100);
+ pixelBuffer.makeCurrent();
+
+ const QByteArray extensions(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)));
+
+# ifndef QT_OPENGL_ES
+ haveArbFp = extensions.contains("ARB_fragment_program");
+# endif
+
+# ifndef QT_OPENGL_ES_2
+ haveGlsl = QGLShaderProgram::hasOpenGLShaderPrograms()
+ && extensions.contains("ARB_shader_objects");
+# else
+ haveGlsl = true;
+# endif
+#endif
+}
+
+void QtVideoSinkTest::cleanupTestCase()
+{
+ gst_deinit();
+}
+
+//------------------------------------
+
+void QtVideoSinkTest::bufferFormatTest_data()
+{
+ QTest::addColumn<GstVideoFormat>("format");
+ QTest::addColumn<GstVideoColorMatrix>("colorMatrix");
+
+ QTest::newRow("ARGB") << GST_VIDEO_FORMAT_ARGB << GST_VIDEO_COLOR_MATRIX_RGB;
+ QTest::newRow("BGRA") << GST_VIDEO_FORMAT_BGRA << GST_VIDEO_COLOR_MATRIX_RGB;
+ QTest::newRow("xRGB") << GST_VIDEO_FORMAT_xRGB << GST_VIDEO_COLOR_MATRIX_RGB;
+ QTest::newRow("BGRx") << GST_VIDEO_FORMAT_BGRx << GST_VIDEO_COLOR_MATRIX_RGB;
+ QTest::newRow("RGB16") << GST_VIDEO_FORMAT_RGB16 << GST_VIDEO_COLOR_MATRIX_RGB;
+ QTest::newRow("BGR16") << GST_VIDEO_FORMAT_BGR16 << GST_VIDEO_COLOR_MATRIX_RGB;
+ QTest::newRow("RGB") << GST_VIDEO_FORMAT_RGB << GST_VIDEO_COLOR_MATRIX_RGB;
+ QTest::newRow("BGR") << GST_VIDEO_FORMAT_BGR << GST_VIDEO_COLOR_MATRIX_RGB;
+ QTest::newRow("I420") << GST_VIDEO_FORMAT_I420 << GST_VIDEO_COLOR_MATRIX_BT601;
+ QTest::newRow("YV12") << GST_VIDEO_FORMAT_YV12 << GST_VIDEO_COLOR_MATRIX_BT601;
+ QTest::newRow("v308") << GST_VIDEO_FORMAT_v308 << GST_VIDEO_COLOR_MATRIX_BT601;
+ QTest::newRow("AYUV") << GST_VIDEO_FORMAT_AYUV << GST_VIDEO_COLOR_MATRIX_BT601;
+}
+
+void QtVideoSinkTest::bufferFormatTest()
+{
+ QFETCH(GstVideoFormat, format);
+ QFETCH(GstVideoColorMatrix, colorMatrix);
+
+ GstCaps *caps = BufferFormat::newCaps(format, QSize(100, 200), Fraction(3, 4), Fraction(5, 6));
+ BufferFormat bufferFormat = BufferFormat::fromCaps(caps);
+ gst_caps_unref(caps);
+
+ QCOMPARE(bufferFormat.videoFormat(), format);
+ QCOMPARE(bufferFormat.colorMatrix(), colorMatrix);
+ QCOMPARE(bufferFormat.frameSize(), QSize(100, 200));
+ QCOMPARE(bufferFormat.pixelAspectRatio(), Fraction(5, 6));
+}
+
+//------------------------------------
+
+void QtVideoSinkTest::paintAreasTest_data()
+{
+ QTest::addColumn<QRectF>("targetArea");
+ QTest::addColumn<QSize>("frameSize");
+ QTest::addColumn<Fraction>("pixelAspectRatio");
+ QTest::addColumn<Fraction>("displayAspectRatio");
+ QTest::addColumn<QRectF>("blackArea1");
+ QTest::addColumn<QRectF>("videoArea");
+ QTest::addColumn<QRectF>("blackArea2");
+ QTest::addColumn<Qt::AspectRatioMode>("mode");
+
+ QTest::newRow("targetArea == videoArea")
+ << QRectF(0.0, 0.0, 320.0, 240.0)
+ << QSize(320, 240) << Fraction(1, 1) << Fraction(1, 1)
+ << QRectF(0.0, 0.0, 0.0, 0.0)
+ << QRectF(0.0, 0.0, 320.0, 240.0)
+ << QRectF(0.0, 0.0, 0.0, 0.0)
+ << Qt::KeepAspectRatio;
+
+ QTest::newRow("targetArea wide")
+ << QRectF(0.0, 0.0, 400.0, 240.0)
+ << QSize(320, 240) << Fraction(1, 1) << Fraction(1, 1)
+ << QRectF(0.0, 0.0, 40.0, 240.0)
+ << QRectF(40.0, 0.0, 320.0, 240.0)
+ << QRectF(360.0, 0.0, 40.0, 240.0)
+ << Qt::KeepAspectRatio;
+
+ QTest::newRow("targetArea tall")
+ << QRectF(0.0, 0.0, 320.0, 300.0)
+ << QSize(320, 240) << Fraction(1, 1) << Fraction(1, 1)
+ << QRectF(0.0, 0.0, 320.0, 30.0)
+ << QRectF(0.0, 30.0, 320.0, 240.0)
+ << QRectF(0.0, 270.0, 320.0, 30.0)
+ << Qt::KeepAspectRatio;
+
+
+ QTest::newRow("targetArea == videoArea @ (2, 3)")
+ << QRectF(2.0, 3.0, 320.0, 240.0)
+ << QSize(320, 240) << Fraction(1, 1) << Fraction(1, 1)
+ << QRectF(0.0, 0.0, 0.0, 0.0)
+ << QRectF(2.0, 3.0, 320.0, 240.0)
+ << QRectF(0.0, 0.0, 0.0, 0.0)
+ << Qt::KeepAspectRatio;
+
+ QTest::newRow("targetArea wide @ (2, 3)")
+ << QRectF(2.0, 3.0, 400.0, 240.0)
+ << QSize(320, 240) << Fraction(1, 1) << Fraction(1, 1)
+ << QRectF(2.0, 3.0, 40.0, 240.0)
+ << QRectF(42.0, 3.0, 320.0, 240.0)
+ << QRectF(362.0, 3.0, 40.0, 240.0)
+ << Qt::KeepAspectRatio;
+
+ QTest::newRow("targetArea tall @ (2, 3)")
+ << QRectF(2.0, 3.0, 320.0, 300.0)
+ << QSize(320, 240) << Fraction(1, 1) << Fraction(1, 1)
+ << QRectF(2.0, 3.0, 320.0, 30.0)
+ << QRectF(2.0, 33.0, 320.0, 240.0)
+ << QRectF(2.0, 273.0, 320.0, 30.0)
+ << Qt::KeepAspectRatio;
+
+
+ QTest::newRow("targetArea.size() == videoSize w/ par 2/1")
+ << QRectF(0.0, 0.0, 160.0, 240.0)
+ << QSize(160, 240) << Fraction(2, 1) << Fraction(1, 1)
+ << QRectF(0.0, 0.0, 160.0, 60.0)
+ << QRectF(0.0, 60.0, 160.0, 120.0)
+ << QRectF(0.0, 180.0, 160.0, 60.0)
+ << Qt::KeepAspectRatio;
+
+ QTest::newRow("dar 2/1")
+ << QRectF(0.0, 0.0, 160.0, 240.0)
+ << QSize(320, 240) << Fraction(1, 1) << Fraction(2, 1)
+ << QRectF(0.0, 0.0, 0.0, 0.0)
+ << QRectF(0.0, 0.0, 160.0, 240.0)
+ << QRectF(0.0, 0.0, 0.0, 0.0)
+ << Qt::KeepAspectRatio;
+}
+
+void QtVideoSinkTest::paintAreasTest()
+{
+ QFETCH(QRectF, targetArea);
+ QFETCH(QSize, frameSize);
+ QFETCH(Fraction, pixelAspectRatio);
+ QFETCH(Fraction, displayAspectRatio);
+ QFETCH(QRectF, blackArea1);
+ QFETCH(QRectF, videoArea);
+ QFETCH(QRectF, blackArea2);
+ QFETCH(Qt::AspectRatioMode, mode);
+
+ PaintAreas areas;
+ areas.calculate(targetArea, frameSize, pixelAspectRatio, displayAspectRatio, mode);
+ QCOMPARE(areas.targetArea, targetArea);
+ QCOMPARE(areas.videoArea, videoArea);
+ QCOMPARE(areas.blackArea1, blackArea1);
+ QCOMPARE(areas.blackArea2, blackArea2);
+}
+
+//------------------------------------
+
+void QtVideoSinkTest::genericSurfacePainterFormatsTest_data()
+{
+ QTest::addColumn<GstVideoFormat>("format");
+
+ QSet<GstVideoFormat> formats = GenericSurfacePainter::supportedPixelFormats();
+ GEnumClass *gstVideoFormatClass = G_ENUM_CLASS(g_type_class_ref(GST_TYPE_VIDEO_FORMAT));
+
+ Q_FOREACH(GstVideoFormat format, formats) {
+ GEnumValue *value = g_enum_get_value(gstVideoFormatClass, format);
+ QTest::newRow(value->value_name) << format;
+ }
+
+ g_type_class_unref(gstVideoFormatClass);
+}
+
+void QtVideoSinkTest::genericSurfacePainterFormatsTest()
+{
+ QFETCH(GstVideoFormat, format);
+ QVERIFY(format != GST_VIDEO_FORMAT_UNKNOWN);
+
+ GstCaps *caps = BufferFormat::newCaps(format, QSize(100, 100), Fraction(1, 1), Fraction(1, 1));
+ BufferFormat bufferFormat = BufferFormat::fromCaps(caps);
+ gst_caps_unref(caps);
+
+ PaintAreas areas;
+ areas.targetArea = QRectF(QPointF(0,0), bufferFormat.frameSize());
+ areas.videoArea = areas.targetArea;
+ areas.sourceRect = QRectF(0, 0, 1, 1);
+
+ GenericSurfacePainter genericSurfacePainter;
+ QVERIFY(genericSurfacePainter.supportsFormat(format));
+ try {
+ genericSurfacePainter.init(bufferFormat);
+ } catch (const QString & error) {
+ QFAIL("Failed to initialize GenericSurfacePainter");
+ }
+
+ QImage targetImage(QSize(100, 100), QImage::Format_ARGB32);
+ targetImage.fill(Qt::black);
+ QPainter painter(&targetImage);
+
+ GstSamplePtr sample(generateTestSample(format, 4)); //pattern = red
+ QVERIFY(!sample.isNull());
+ GstBuffer *buffer = gst_sample_get_buffer(sample.data());
+ QVERIFY(buffer);
+ GstMapInfo info;
+ QVERIFY(gst_buffer_map(buffer, &info, GST_MAP_READ));
+ genericSurfacePainter.paint(
+ info.data,
+ bufferFormat,
+ &painter,
+ areas);
+ QCOMPARE(targetImage.pixel(50, 50), qRgb(255, 0, 0));
+ gst_buffer_unmap(buffer, &info);
+
+ sample.reset(generateTestSample(format, 5)); //pattern = green
+ QVERIFY(!sample.isNull());
+ buffer = gst_sample_get_buffer(sample.data());
+ QVERIFY(buffer);
+ QVERIFY(gst_buffer_map(buffer, &info, GST_MAP_READ));
+ genericSurfacePainter.paint(
+ info.data,
+ bufferFormat,
+ &painter,
+ areas);
+ QCOMPARE(targetImage.pixel(50, 50), qRgb(0, 255, 0));
+ gst_buffer_unmap(buffer, &info);
+
+ sample.reset(generateTestSample(format, 6)); //pattern = blue
+ QVERIFY(!sample.isNull());
+ buffer = gst_sample_get_buffer(sample.data());
+ QVERIFY(buffer);
+ QVERIFY(gst_buffer_map(buffer, &info, GST_MAP_READ));
+ genericSurfacePainter.paint(
+ info.data,
+ bufferFormat,
+ &painter,
+ areas);
+ QCOMPARE(targetImage.pixel(50, 50), qRgb(0, 0, 255));
+
+
+ QBENCHMARK {
+ genericSurfacePainter.paint(
+ info.data,
+ bufferFormat,
+ &painter,
+ areas);
+ }
+ gst_buffer_unmap(buffer, &info);
+}
+
+//------------------------------------
+
+#ifndef GST_QT_VIDEO_SINK_NO_OPENGL
+
+void QtVideoSinkTest::glSurfacePainterFormatsTest_data()
+{
+ QTest::addColumn<GstVideoFormat>("format");
+ QTest::addColumn<bool>("glsl");
+
+
+ QSet<GstVideoFormat> formats = OpenGLSurfacePainter::supportedPixelFormats();
+ GEnumClass *gstVideoFormatClass = G_ENUM_CLASS(g_type_class_ref(GST_TYPE_VIDEO_FORMAT));
+
+ Q_FOREACH(GstVideoFormat format, formats) {
+ GEnumValue *value = g_enum_get_value(gstVideoFormatClass, format);
+ QTest::newRow(QByteArray("glsl ") + value->value_name) << format << true;
+ QTest::newRow(QByteArray("arbfp ") + value->value_name) << format << false;
+ }
+
+ g_type_class_unref(gstVideoFormatClass);
+}
+
+void QtVideoSinkTest::glSurfacePainterFormatsTest()
+{
+ QFETCH(GstVideoFormat, format);
+ QFETCH(bool, glsl);
+ QVERIFY(format != GST_VIDEO_FORMAT_UNKNOWN);
+
+ if (glsl && !haveGlsl) {
+ QSKIP_PORT("Skipping because the system does not support GLSL", SkipSingle);
+ }
+
+ if (!glsl && !haveArbFp) {
+ QSKIP_PORT("Skipping because the system does not support ARB Fragment Programs", SkipSingle);
+ }
+
+ GstCaps *caps = BufferFormat::newCaps(format, QSize(100, 100), Fraction(1, 1), Fraction(1, 1));
+ BufferFormat bufferFormat = BufferFormat::fromCaps(caps);
+ gst_caps_unref(caps);
+
+ PaintAreas areas;
+ areas.targetArea = QRectF(QPointF(0,0), bufferFormat.frameSize());
+ areas.videoArea = areas.targetArea;
+ areas.sourceRect = QRectF(0, 0, 1, 1);
+
+ QGLPixelBuffer pixelBuffer(100, 100);
+ pixelBuffer.makeCurrent();
+
+ QScopedPointer<AbstractSurfacePainter> glSurfacePainter;
+ if (glsl) {
+ glSurfacePainter.reset(new GlslSurfacePainter);
+ } else {
+#ifndef QT_OPENGL_ES
+ glSurfacePainter.reset(new ArbFpSurfacePainter);
+#endif
+ }
+
+ QVERIFY(glSurfacePainter->supportsFormat(format));
+
+ try {
+ glSurfacePainter->init(bufferFormat);
+ } catch (const QString & error) {
+ QFAIL("Failed to initialize OpenGLSurfacePainter");
+ }
+
+ glSurfacePainter->updateColors(0, 0, 0, 0);
+ QPainter painter(&pixelBuffer);
+
+ GstSamplePtr sample(generateTestSample(format, 4)); //pattern = red
+ QVERIFY(!sample.isNull());
+ GstMapInfo info;
+ GstBuffer *buffer = gst_sample_get_buffer(sample.data());
+ QVERIFY(buffer);
+
+ QVERIFY(gst_buffer_map(buffer, &info, GST_MAP_READ));
+ glSurfacePainter->paint(
+ info.data,
+ bufferFormat,
+ &painter,
+ areas);
+ QRgb pixel1 = pixelBuffer.toImage().pixel(50, 50);
+ QRgb pixel2 = qRgb(255, 0, 0);
+ if (!pixelsSimilar(pixel1, pixel2)) {
+ qWarning("Found difference (%d, %d, %d) vs (%d, %d, %d)",
+ qRed(pixel1), qGreen(pixel1), qBlue(pixel1),
+ qRed(pixel2), qGreen(pixel2), qBlue(pixel2));
+ QFAIL("Failing due to differences in the compared images");
+ }
+ gst_buffer_unmap(buffer, &info);
+
+ sample.reset(generateTestSample(format, 5)); //pattern = green
+ QVERIFY(!sample.isNull());
+ buffer = gst_sample_get_buffer(sample.data());
+ QVERIFY(buffer);
+ QVERIFY(gst_buffer_map(buffer, &info, GST_MAP_READ));
+ glSurfacePainter->paint(
+ info.data,
+ bufferFormat,
+ &painter,
+ areas);
+ pixel1 = pixelBuffer.toImage().pixel(50, 50);
+ pixel2 = qRgb(0, 255, 0);
+ if (!pixelsSimilar(pixel1, pixel2)) {
+ qWarning("Found difference (%d, %d, %d) vs (%d, %d, %d)",
+ qRed(pixel1), qGreen(pixel1), qBlue(pixel1),
+ qRed(pixel2), qGreen(pixel2), qBlue(pixel2));
+ }
+ gst_buffer_unmap(buffer, &info);
+
+ sample.reset(generateTestSample(format, 6)); //pattern = blue
+ QVERIFY(!sample.isNull());
+ buffer = gst_sample_get_buffer(sample.data());
+ QVERIFY(buffer);
+ QVERIFY(gst_buffer_map(buffer, &info, GST_MAP_READ));
+ glSurfacePainter->paint(
+ info.data,
+ bufferFormat,
+ &painter,
+ areas);
+ pixel1 = pixelBuffer.toImage().pixel(50, 50);
+ pixel2 = qRgb(0, 0, 255);
+ if (!pixelsSimilar(pixel1, pixel2)) {
+ qWarning("Found difference (%d, %d, %d) vs (%d, %d, %d)",
+ qRed(pixel1), qGreen(pixel1), qBlue(pixel1),
+ qRed(pixel2), qGreen(pixel2), qBlue(pixel2));
+ }
+
+
+ QBENCHMARK {
+ glSurfacePainter->paint(
+ info.data,
+ bufferFormat,
+ &painter,
+ areas);
+ }
+ gst_buffer_unmap(buffer, &info);
+
+}
+
+#endif
+
+//------------------------------------
+
+struct ColorsTuple
+{
+ ColorsTuple()
+ : contrast(0), brightness(0), hue(0), saturation(0) {}
+
+ void randomize() {
+ contrast = rand() % 200 - 100;
+ brightness = rand() % 200 -100;
+ hue = rand() % 200 -100;
+ saturation = rand() % 200 -100;
+ }
+
+ int contrast;
+ int brightness;
+ int hue;
+ int saturation;
+};
+
+void QtVideoSinkTest::qtVideoSinkTest_data()
+{
+ QTest::addColumn<GstVideoFormat>("format");
+ QTest::addColumn<QSize>("sourceSize");
+ QTest::addColumn<QSize>("widgetSize");
+ QTest::addColumn<bool>("forceAspectRatio");
+ QTest::addColumn<bool>("useGL");
+
+ QTest::newRow("BGRA 320x240 -> 400x240")
+ << GST_VIDEO_FORMAT_BGRA
+ << QSize(320, 240)
+ << QSize(400, 240)
+ << true
+ << true;
+
+ QTest::newRow("I420 320x240 -> 400x240 scaled")
+ << GST_VIDEO_FORMAT_I420
+ << QSize(320, 240)
+ << QSize(400, 240)
+ << false
+ << true;
+
+ QTest::newRow("RGB16 320x240 -> 400x500")
+ << GST_VIDEO_FORMAT_RGB16
+ << QSize(320, 240)
+ << QSize(400, 500)
+ << true
+ << false;
+
+ QTest::newRow("RGB 320x240 -> 400x500 scaled")
+ << GST_VIDEO_FORMAT_RGB
+ << QSize(320, 240)
+ << QSize(400, 500)
+ << false
+ << false;
+}
+
+void QtVideoSinkTest::qtVideoSinkTest()
+{
+ QFETCH(GstVideoFormat, format);
+ QFETCH(QSize, sourceSize);
+ QFETCH(QSize, widgetSize);
+ QFETCH(bool, forceAspectRatio);
+ QFETCH(bool, useGL);
+ Fraction fps(15, 1);
+ Fraction par(1, 1);
+
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ GstVideoFormat imageFormat = GST_VIDEO_FORMAT_BGRA;
+#else
+ GstVideoFormat imageFormat = GST_VIDEO_FORMAT_ARGB;
+#endif
+
+ QScopedPointer<QWidget> widget;
+ void *context = 0;
+
+ if (useGL) {
+#ifndef GST_QT_VIDEO_SINK_NO_OPENGL
+ if (haveArbFp || haveGlsl) {
+ widget.reset(new VideoGLWidget);
+ context = (void*) qobject_cast<QGLWidget*>(widget.data())->context();
+ QVERIFY(context != 0);
+ } else
+#endif
+ QSKIP_PORT("Skipping because we have no OpenGL support", SkipSingle);
+ } else {
+ widget.reset(new VideoWidget);
+ }
+
+ GstCaps *caps = BufferFormat::newCaps(format, sourceSize, fps, par);
+ GstCaps *fakesinkCaps = BufferFormat::newCaps(imageFormat, widgetSize, fps, par);
+
+ GstPipelinePtr pipeline(constructPipeline(caps, fakesinkCaps, forceAspectRatio, context));
+
+ gst_caps_unref(fakesinkCaps);
+ gst_caps_unref(caps);
+
+ QVERIFY(!pipeline.isNull());
+
+ GstElementPtr qtvideosink(gst_bin_get_by_name(GST_BIN(pipeline.data()), "qtvideosink"));
+ QVERIFY(G_TYPE_CHECK_INSTANCE(qtvideosink.data()));
+
+ //colorbalance test
+ if (useGL) {
+ GstColorBalance *balance = GST_COLOR_BALANCE(qtvideosink.data());
+ QVERIFY(balance != NULL);
+
+ //set colors using the interface
+ GList *channels = (GList*) gst_color_balance_list_channels(balance);
+ QVERIFY(channels != NULL);
+
+ int successFlags = 0;
+ ColorsTuple colors;
+ colors.randomize();
+
+ while (channels) {
+ GstColorBalanceChannel *channel = GST_COLOR_BALANCE_CHANNEL(channels->data);
+ QVERIFY(channel != NULL);
+ int value;
+
+ if (qstrcmp(channel->label, "contrast") == 0) {
+ value = colors.contrast;
+ successFlags |= 0x1;
+ } else if (qstrcmp(channel->label, "brightness") == 0) {
+ value = colors.brightness;
+ successFlags |= 0x2;
+ } else if (qstrcmp(channel->label, "hue") == 0) {
+ value = colors.hue;
+ successFlags |= 0x4;
+ } else if (qstrcmp(channel->label, "saturation") == 0) {
+ value = colors.saturation;
+ successFlags |= 0x8;
+ } else {
+ QFAIL("Invalid colorbalance label");
+ }
+
+ QCOMPARE(channel->min_value, -100);
+ QCOMPARE(channel->max_value, 100);
+ QVERIFY(value <= 100 && value >= -100);
+
+ gst_color_balance_set_value(balance, channel, value);
+ channels = g_list_next(channels);
+ }
+
+ //verify that we have set all the channels
+ QCOMPARE(successFlags, 0xF);
+
+ //verify that everything is set correctly using the properties
+ ColorsTuple receivedColors;
+ g_object_get(balance,
+ "contrast", &receivedColors.contrast,
+ "brightness", &receivedColors.brightness,
+ "hue", &receivedColors.hue,
+ "saturation", &receivedColors.saturation,
+ NULL);
+ QCOMPARE(receivedColors.contrast, colors.contrast);
+ QCOMPARE(receivedColors.brightness, colors.brightness);
+ QCOMPARE(receivedColors.hue, colors.hue);
+ QCOMPARE(receivedColors.saturation, colors.saturation);
+
+ //set everything again to new values using the properties
+ colors.randomize();
+
+ g_object_set(balance,
+ "contrast", colors.contrast,
+ "brightness", colors.brightness,
+ "hue", colors.hue,
+ "saturation", colors.saturation,
+ NULL);
+
+ //verify again that everything is set correctly using the interface
+ channels = (GList*) gst_color_balance_list_channels(balance);
+ successFlags = 0;
+
+ while (channels) {
+ GstColorBalanceChannel *channel = GST_COLOR_BALANCE_CHANNEL(channels->data);
+ QVERIFY(channel != NULL);
+
+ if (qstrcmp(channel->label, "contrast") == 0) {
+ receivedColors.contrast = gst_color_balance_get_value(balance, channel);
+ successFlags |= 0x1;
+ } else if (qstrcmp(channel->label, "brightness") == 0) {
+ receivedColors.brightness = gst_color_balance_get_value(balance, channel);
+ successFlags |= 0x2;
+ } else if (qstrcmp(channel->label, "hue") == 0) {
+ receivedColors.hue = gst_color_balance_get_value(balance, channel);
+ successFlags |= 0x4;
+ } else if (qstrcmp(channel->label, "saturation") == 0) {
+ receivedColors.saturation = gst_color_balance_get_value(balance, channel);
+ successFlags |= 0x8;
+ } else {
+ QFAIL("Invalid colorbalance label");
+ }
+ channels = g_list_next(channels);
+ }
+
+ QCOMPARE(successFlags, 0xF);
+
+ //reset back to zero
+ colors = ColorsTuple();
+ g_object_set(balance,
+ "contrast", colors.contrast,
+ "brightness", colors.brightness,
+ "hue", colors.hue,
+ "saturation", colors.saturation,
+ NULL);
+ }
+
+#ifndef GST_QT_VIDEO_SINK_NO_OPENGL
+ if (useGL) {
+ VideoGLWidget *glw = dynamic_cast<VideoGLWidget*>(widget.data());
+ QVERIFY(glw);
+ glw->setVideoSink(GST_ELEMENT(g_object_ref(qtvideosink.data())));
+ } else
+#endif
+ {
+ VideoWidget *w = dynamic_cast<VideoWidget*>(widget.data());
+ QVERIFY(w);
+ w->setVideoSink(GST_ELEMENT(g_object_ref(qtvideosink.data())));
+ }
+ widget->setWindowTitle(G_STRINGIFY(QTVIDEOSINK_NAME));
+ widget->resize(widgetSize);
+ widget->show();
+ widget->raise();
+
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
+ QTest::qWaitForWindowExposed(widget.data()->windowHandle());
+#else
+ QTest::qWaitForWindowShown(widget.data());
+#endif
+
+ GstStateChangeReturn stateReturn = gst_element_set_state(
+ GST_ELEMENT(pipeline.data()), GST_STATE_PAUSED);
+ QCOMPARE(stateReturn, GST_STATE_CHANGE_ASYNC);
+
+ GstState state = GST_STATE_NULL;
+ stateReturn = gst_element_get_state(GST_ELEMENT(pipeline.data()), &state, NULL, 10 * GST_SECOND);
+ QCOMPARE(stateReturn, GST_STATE_CHANGE_SUCCESS);
+ QCOMPARE(state, GST_STATE_PAUSED);
+
+ //process the pending BufferEvent in qtvideosink and subsequently the QPaintEvent in the widget
+ //and wait a bit for X/window manager/GPU/whatever to actually render the window
+ QTest::qWait(1000);
+
+ GstSample *samplePtr = NULL;
+ gst_child_proxy_get(GST_CHILD_PROXY(pipeline.data()), "fakesink::last-sample", &samplePtr, NULL);
+
+ GstSamplePtr sample(samplePtr);
+ GstMapInfo info;
+ QVERIFY(!sample.isNull());
+ GstBuffer *buffer = gst_sample_get_buffer(sample.data());
+ QVERIFY(buffer);
+ QVERIFY(gst_buffer_map(buffer, &info, GST_MAP_READ));
+
+ { //increased scope so that expectedImage gets deleted before the sample
+ // replacing gst_video_format_get_row_stride(imageFormat, 0, widgetSize.width())
+ const GstVideoFormatInfo *video_info = gst_video_format_get_info(imageFormat);
+ QVERIFY(video_info);
+
+ QImage expectedImage(info.data,
+ widgetSize.width(), widgetSize.height(),
+ GST_VIDEO_FORMAT_INFO_PSTRIDE(video_info, 0) * widgetSize.width(),
+ QImage::Format_ARGB32);
+ QImage actualImage = QPixmap::grabWindow(widget->winId()).toImage();
+
+#if 0
+ // visual debugging
+ QScopedPointer<QWidget> referenceWidget(new QWidget);
+ referenceWidget->setWindowTitle("Results");
+
+ QLabel *label1 = new QLabel(referenceWidget.data());
+ label1->setPixmap(QPixmap::fromImage(actualImage));
+ QLabel *label1Txt = new QLabel(referenceWidget.data());
+ label1Txt->setText("Grabbed image from qtvideosink window");
+
+ QLabel *label2 = new QLabel(referenceWidget.data());
+ label2->setPixmap(QPixmap::fromImage(expectedImage));
+ QLabel *label2Txt = new QLabel(referenceWidget.data());
+ label2Txt->setText("Expected image, as received on fakesink");
+
+ QGridLayout *layout = new QGridLayout(referenceWidget.data());
+ layout->addWidget(label1, 0, 0);
+ layout->addWidget(label1Txt, 1, 0);
+ layout->addWidget(label2, 0, 1);
+ layout->addWidget(label2Txt, 1, 1);
+ referenceWidget->setLayout(layout);
+
+ referenceWidget->show();
+ referenceWidget->raise();
+
+ QTest::qWaitForWindowShown(referenceWidget.data());
+ QTest::qWait(1000); //just for visual feedback
+#endif
+
+ imageCompare(actualImage, expectedImage, forceAspectRatio ? sourceSize : QSize());
+ gst_buffer_unmap(buffer, &info);
+ }
+}
+
+//------------------------------------
+
+#define MAKE_ELEMENT(variable, name) \
+ GstElement *variable = gst_element_factory_make(name, #variable); \
+ if (!variable) { \
+ QWARN("Failed to create " #variable); \
+ return NULL; \
+ } else { \
+ gst_bin_add(GST_BIN(pipeline.data()), variable); \
+ }
+
+GstSample* QtVideoSinkTest::generateTestSample(GstVideoFormat format, int pattern)
+{
+ GstPipelinePtr pipeline(GST_PIPELINE(gst_pipeline_new("generate-test-sample-pipeline")));
+ if (!pipeline) {
+ return NULL;
+ }
+
+ MAKE_ELEMENT(videotestsrc, "videotestsrc");
+ MAKE_ELEMENT(videoconvert, "videoconvert");
+ MAKE_ELEMENT(capsfilter, "capsfilter");
+ MAKE_ELEMENT(fakesink, "fakesink");
+
+ GstCaps *caps = BufferFormat::newCaps(format, QSize(100, 100), Fraction(1, 1), Fraction(1, 1));
+ g_object_set(capsfilter, "caps", caps, NULL);
+ gst_caps_unref(caps);
+
+ g_object_set(videotestsrc, "pattern", pattern, NULL);
+ g_object_set(fakesink, "enable-last-sample", TRUE, NULL);
+
+ if (!gst_element_link_many(videotestsrc, videoconvert, capsfilter, fakesink, NULL)) {
+ QWARN("Failed to link generate-test-sample-pipeline");
+ return NULL;
+ }
+
+ gst_element_set_state(GST_ELEMENT(pipeline.data()), GST_STATE_PAUSED);
+
+ GstState state = GST_STATE_NULL;
+ GstStateChangeReturn stateReturn = gst_element_get_state(GST_ELEMENT(pipeline.data()),
+ &state, NULL, 10 * GST_SECOND);
+ if (stateReturn != GST_STATE_CHANGE_SUCCESS || state != GST_STATE_PAUSED) {
+ QWARN("Failed to set generate-test-sample-pipeline to PAUSED");
+ return NULL;
+ }
+
+ GstSample *samplePtr = NULL;
+ g_object_get(fakesink, "last-sample", &samplePtr, NULL);
+ return samplePtr;
+}
+
+GstPipeline *QtVideoSinkTest::constructPipeline(GstCaps *caps,
+ GstCaps *fakesinkCaps, bool forceAspectRatio, void *context)
+{
+ GstPipelinePtr pipeline(GST_PIPELINE(gst_pipeline_new("test-pipeline")));
+ if (!pipeline) {
+ return NULL;
+ }
+
+ MAKE_ELEMENT(videotestsrc, "videotestsrc");
+ MAKE_ELEMENT(capsfilter, "capsfilter");
+ MAKE_ELEMENT(tee, "tee");
+
+ MAKE_ELEMENT(queue, "queue");
+ MAKE_ELEMENT(qtvideosink, context ?
+ G_STRINGIFY(QTGLVIDEOSINK_NAME) : G_STRINGIFY(QTVIDEOSINK_NAME));
+
+ MAKE_ELEMENT(queue2, "queue");
+ MAKE_ELEMENT(colorspace, "videoconvert");
+ MAKE_ELEMENT(videoscale, "videoscale");
+ MAKE_ELEMENT(capsfilter2, "capsfilter");
+ MAKE_ELEMENT(fakesink, "fakesink");
+
+ g_object_set(videotestsrc, "pattern", 19, NULL); //color bars
+ g_object_set(capsfilter, "caps", caps, NULL);
+ g_object_set(capsfilter2, "caps", fakesinkCaps, NULL);
+ g_object_set(fakesink, "enable-last-sample", TRUE, NULL);
+
+ if (context) {
+ g_object_set(qtvideosink, "glcontext", context, NULL);
+ }
+
+ g_object_set(qtvideosink, "force-aspect-ratio", (gboolean) forceAspectRatio, NULL);
+ g_object_set(videoscale, "add-borders", (gboolean) forceAspectRatio, NULL);
+
+ if (!gst_element_link_many(videotestsrc, capsfilter, tee, NULL)) {
+ QWARN("Failed to link upstream elements");
+ return NULL;
+ }
+
+ if (!gst_element_link(queue, qtvideosink)) {
+ QWARN("Failed to link qtvideosink branch");
+ return NULL;
+ }
+
+ if (!gst_element_link_pads(tee, "src_%u", queue, "sink")) {
+ QWARN("Failed to link tee to qtvideosink");
+ return NULL;
+ }
+
+ if (!gst_element_link_many(queue2, colorspace, videoscale, capsfilter2, fakesink, NULL)) {
+ QWARN("Failed to link fakesink branch");
+ return NULL;
+ }
+
+ if (!gst_element_link_pads(tee, "src_%u", queue2, "sink")) {
+ QWARN("Failed to link tee to fakesink branch");
+ return NULL;
+ }
+
+ return GST_PIPELINE(g_object_ref(pipeline.data()));
+}
+
+void QtVideoSinkTest::imageCompare(const QImage & image1, const QImage & image2, const QSize & sourceSize)
+{
+ QVERIFY(image1.size() == image2.size());
+
+ QVector<int> hStartStopPoints;
+ QVector<int> vStartStopPoints;
+
+ QRect barsArea;
+ if (sourceSize.isValid() && sourceSize != image1.size()) {
+ PaintAreas areas;
+ areas.calculate(image1.rect(), sourceSize, Fraction(1,1), Fraction(1,1), Qt::KeepAspectRatio);
+ barsArea = areas.videoArea.toRect();
+ } else {
+ barsArea = image1.rect();
+ }
+
+ // do not compare scaling artifacts - this algorithm depends on videotestsrc's pattern 19
+ qreal colorChangePoint = barsArea.width() / 7.0;
+
+ // omit 9% of the pixels before and after the color change
+ int area = qRound(colorChangePoint * 0.09);
+ hStartStopPoints.append(barsArea.left() + 2);
+ for (int i = 1; i < 7; i++) {
+ hStartStopPoints.append(barsArea.left() + int(colorChangePoint * i) - area);
+ hStartStopPoints.append(barsArea.left() + int(colorChangePoint * i) + area + 1);
+ }
+ hStartStopPoints.append(barsArea.right() - 1);
+
+ vStartStopPoints.append(barsArea.top() + 2);
+ vStartStopPoints.append(barsArea.bottom() - 1);
+
+ for (int hsspCounter = 0; hsspCounter < hStartStopPoints.size() - 1; hsspCounter += 2) {
+ for (int i = hStartStopPoints.at(hsspCounter); i < hStartStopPoints.at(hsspCounter+1); i++) {
+ for (int vsspCounter = 0; vsspCounter < vStartStopPoints.size() - 1; vsspCounter += 2) {
+ for (int j = vStartStopPoints.at(vsspCounter); j < vStartStopPoints.at(vsspCounter+1); j++) {
+ QRgb pixel1 = image1.pixel(i, j);
+ QRgb pixel2 = image2.pixel(i, j);
+
+ //yuv formats are lossy, therefore we cannot use pixel1 == pixel2
+ if (!pixelsSimilar(pixel1, pixel2)) {
+ qWarning("Found difference at %d, %d (%d, %d, %d) vs (%d, %d, %d)", i, j,
+ qRed(pixel1), qGreen(pixel1), qBlue(pixel1),
+ qRed(pixel2), qGreen(pixel2), qBlue(pixel2));
+ QFAIL("Failing due to differences in the compared images");
+ }
+ }
+ }
+ }
+ }
+}
+
+bool QtVideoSinkTest::pixelsSimilar(const QRgb & pixel1, const QRgb & pixel2)
+{
+ return !(qAbs(qRed(pixel1) - qRed(pixel2)) > 5 ||
+ qAbs(qGreen(pixel1) - qGreen(pixel2)) > 5 ||
+ qAbs(qBlue(pixel1) - qBlue(pixel2)) > 5);
+}
+
+QTEST_MAIN(QtVideoSinkTest)
+#include "autotest.moc"
diff --git a/elements/gstqtvideosink/delegates/basedelegate.cpp b/elements/gstqtvideosink/delegates/basedelegate.cpp
new file mode 100644
index 0000000..65f364c
--- /dev/null
+++ b/elements/gstqtvideosink/delegates/basedelegate.cpp
@@ -0,0 +1,197 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). <qt-info@nokia.com>
+ Copyright (C) 2011-2013 Collabora Ltd. <info@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "basedelegate.h"
+
+#include <QCoreApplication>
+
+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(NULL)
+ , 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<BufferEvent*>(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<BufferFormatEvent*>(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, NULL);
+ update();
+
+ return true;
+ }
+ default:
+ return QObject::event(event);
+ }
+}
+
+void BaseDelegate::update()
+{
+ g_signal_emit_by_name(m_sink, "update");
+}
diff --git a/elements/gstqtvideosink/delegates/basedelegate.h b/elements/gstqtvideosink/delegates/basedelegate.h
new file mode 100644
index 0000000..5e177d2
--- /dev/null
+++ b/elements/gstqtvideosink/delegates/basedelegate.h
@@ -0,0 +1,149 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). <qt-info@nokia.com>
+ Copyright (C) 2011-2013 Collabora Ltd. <info@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef BASEDELEGATE_H
+#define BASEDELEGATE_H
+
+#include <gst/gst.h>
+
+#include "../gstqtvideosinkplugin.h" //for debug category
+#include "../utils/bufferformat.h"
+#include "../utils/utils.h"
+
+#include <QObject>
+#include <QEvent>
+#include <QReadWriteLock>
+
+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<QEvent::Type>(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<QEvent::Type>(BufferFormatEventType)),
+ format(format)
+ {}
+
+ BufferFormat format;
+ };
+
+ class DeactivateEvent : public QEvent
+ {
+ public:
+ inline DeactivateEvent()
+ : QEvent(static_cast<QEvent::Type>(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;
+};
+
+#endif // BASEDELEGATE_H
diff --git a/elements/gstqtvideosink/delegates/qtquick2videosinkdelegate.cpp b/elements/gstqtvideosink/delegates/qtquick2videosinkdelegate.cpp
new file mode 100644
index 0000000..b4e894a
--- /dev/null
+++ b/elements/gstqtvideosink/delegates/qtquick2videosinkdelegate.cpp
@@ -0,0 +1,103 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). <qt-info@nokia.com>
+ Copyright (C) 2011-2013 Collabora Ltd. <info@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#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<VideoNode*>(node);
+ if (!vnode) {
+ GST_INFO_OBJECT(m_sink, "creating new VideoNode");
+ vnode = new VideoNode;
+ m_formatDirty = true;
+ }
+
+ 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/elements/gstqtvideosink/delegates/qtquick2videosinkdelegate.h b/elements/gstqtvideosink/delegates/qtquick2videosinkdelegate.h
new file mode 100644
index 0000000..b596658
--- /dev/null
+++ b/elements/gstqtvideosink/delegates/qtquick2videosinkdelegate.h
@@ -0,0 +1,32 @@
+/*
+ Copyright (C) 2013 Collabora Ltd. <info@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef QTQUICK2VIDEOSINKDELEGATE_H
+#define QTQUICK2VIDEOSINKDELEGATE_H
+
+#include "basedelegate.h"
+#include <QtQuick/QSGNode>
+
+class QtQuick2VideoSinkDelegate : public BaseDelegate
+{
+ Q_OBJECT
+public:
+ explicit QtQuick2VideoSinkDelegate(GstElement * sink, QObject * parent = 0);
+
+ QSGNode *updateNode(QSGNode *node, const QRectF & targetArea);
+};
+
+#endif // QTQUICK2VIDEOSINKDELEGATE_H
diff --git a/elements/gstqtvideosink/delegates/qtvideosinkdelegate.cpp b/elements/gstqtvideosink/delegates/qtvideosinkdelegate.cpp
new file mode 100644
index 0000000..1fac7fe
--- /dev/null
+++ b/elements/gstqtvideosink/delegates/qtvideosinkdelegate.cpp
@@ -0,0 +1,239 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). <qt-info@nokia.com>
+ Copyright (C) 2011 Collabora Ltd. <info@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "qtvideosinkdelegate.h"
+#include "../painters/genericsurfacepainter.h"
+#include "../painters/openglsurfacepainter.h"
+
+#include <QStack>
+#include <QPainter>
+
+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();
+
+ const QByteArray extensions(reinterpret_cast<const char *>(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<PainterType> 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"), (NULL));
+}
+
+void QtVideoSinkDelegate::destroyPainter()
+{
+ GST_LOG_OBJECT(m_sink, "Destroying painter");
+
+ delete m_painter;
+ m_painter = 0;
+}
+
+bool QtVideoSinkDelegate::event(QEvent *event)
+{
+ if (event->type() == DeactivateEventType) {
+ if (m_painter) {
+ m_painter->cleanup();
+ destroyPainter();
+ }
+ }
+
+ return BaseDelegate::event(event);
+}
diff --git a/elements/gstqtvideosink/delegates/qtvideosinkdelegate.h b/elements/gstqtvideosink/delegates/qtvideosinkdelegate.h
new file mode 100644
index 0000000..32f266b
--- /dev/null
+++ b/elements/gstqtvideosink/delegates/qtvideosinkdelegate.h
@@ -0,0 +1,69 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). <qt-info@nokia.com>
+ Copyright (C) 2011 Collabora Ltd. <info@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef QT_VIDEO_SINK_DELEGATE_H
+#define QT_VIDEO_SINK_DELEGATE_H
+
+#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)
+
+#endif // QT_VIDEO_SINK_DELEGATE_H
diff --git a/elements/gstqtvideosink/delegates/qwidgetvideosinkdelegate.cpp b/elements/gstqtvideosink/delegates/qwidgetvideosinkdelegate.cpp
new file mode 100644
index 0000000..c42513f
--- /dev/null
+++ b/elements/gstqtvideosink/delegates/qwidgetvideosinkdelegate.cpp
@@ -0,0 +1,82 @@
+/*
+ Copyright (C) 2010 George Kiagiadakis <kiagiadakis.george@gmail.com>
+ Copyright (C) 2012 Collabora Ltd. <info@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#include "qwidgetvideosinkdelegate.h"
+#include <QPainter>
+
+QWidgetVideoSinkDelegate::QWidgetVideoSinkDelegate(GstElement * sink, QObject * parent)
+ : QtVideoSinkDelegate(sink, parent)
+{
+
+}
+
+QWidgetVideoSinkDelegate::~QWidgetVideoSinkDelegate()
+{
+ setWidget(NULL);
+}
+
+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 = NULL;
+ }
+
+ 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/elements/gstqtvideosink/delegates/qwidgetvideosinkdelegate.h b/elements/gstqtvideosink/delegates/qwidgetvideosinkdelegate.h
new file mode 100644
index 0000000..007b7aa
--- /dev/null
+++ b/elements/gstqtvideosink/delegates/qwidgetvideosinkdelegate.h
@@ -0,0 +1,49 @@
+/*
+ Copyright (C) 2010 George Kiagiadakis <kiagiadakis.george@gmail.com>
+ Copyright (C) 2012 Collabora Ltd. <info@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#ifndef QWIDGET_VIDEO_SINK_DELEGATE_H
+#define QWIDGET_VIDEO_SINK_DELEGATE_H
+
+#include "qtvideosinkdelegate.h"
+#include <QEvent>
+#include <QPointer>
+#include <QWidget>
+
+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<QWidget> m_widget;
+
+ // original value of the Qt::WA_OpaquePaintEvent attribute
+ bool m_opaquePaintEventAttribute;
+};
+
+#endif // QWIDGET_VIDEO_SINK_DELEGATE_H
diff --git a/elements/gstqtvideosink/gstqtglvideosink.cpp b/elements/gstqtvideosink/gstqtglvideosink.cpp
new file mode 100644
index 0000000..27307f6
--- /dev/null
+++ b/elements/gstqtvideosink/gstqtglvideosink.cpp
@@ -0,0 +1,143 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). <qt-info@nokia.com>
+ Copyright (C) 2011-2012 Collabora Ltd. <info@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#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 <george.kiagiadakis@collabora.com>");
+}
+
+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<GstQtGLVideoSinkClass*>(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 emited.
+ *
+ * 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<GSignalFlags>(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+ G_STRUCT_OFFSET(GstQtGLVideoSinkClass, paint),
+ NULL, NULL,
+ 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 emited 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, NULL, NULL,
+ 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<GParamFlags>(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<QGLContext*>(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<QPainter*>(painter),
+ QRectF(x, y, width, height));
+}
diff --git a/elements/gstqtvideosink/gstqtglvideosink.h b/elements/gstqtvideosink/gstqtglvideosink.h
new file mode 100644
index 0000000..eb5d2e5
--- /dev/null
+++ b/elements/gstqtvideosink/gstqtglvideosink.h
@@ -0,0 +1,72 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). <qt-info@nokia.com>
+ Copyright (C) 2011-2012 Collabora Ltd. <info@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef GST_QT_GL_VIDEO_SINK_H
+#define GST_QT_GL_VIDEO_SINK_H
+
+#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
+#endif // GST_QT_GL_VIDEO_SINK_H
diff --git a/elements/gstqtvideosink/gstqtglvideosinkbase.cpp b/elements/gstqtvideosink/gstqtglvideosinkbase.cpp
new file mode 100644
index 0000000..2efdbef
--- /dev/null
+++ b/elements/gstqtvideosink/gstqtglvideosinkbase.cpp
@@ -0,0 +1,262 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). <qt-info@nokia.com>
+ Copyright (C) 2011-2012 Collabora Ltd. <info@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "gstqtglvideosinkbase.h"
+#include "painters/openglsurfacepainter.h"
+#include "delegates/qtvideosinkdelegate.h"
+#include <QCoreApplication>
+
+#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 = 0;
+
+//------------------------------
+
+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, NULL, NULL
+ };
+
+ 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 = NULL; //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<GstQtVideoSinkBaseClass*>(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<GParamFlags>(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<GParamFlags>(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<GParamFlags>(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<GParamFlags>(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 = NULL;
+
+ for (int i=0; i < LABEL_LAST; i++) {
+ channel = GST_COLOR_BALANCE_CHANNEL(g_object_new(GST_TYPE_COLOR_BALANCE_CHANNEL, NULL));
+ 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/elements/gstqtvideosink/gstqtglvideosinkbase.h b/elements/gstqtvideosink/gstqtglvideosinkbase.h
new file mode 100644
index 0000000..cfe8bb7
--- /dev/null
+++ b/elements/gstqtvideosink/gstqtglvideosinkbase.h
@@ -0,0 +1,94 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). <qt-info@nokia.com>
+ Copyright (C) 2011-2012 Collabora Ltd. <info@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef GST_QT_GL_VIDEO_SINK_BASE_H
+#define GST_QT_GL_VIDEO_SINK_BASE_H
+
+#include "gstqtvideosinkbase.h"
+#include <gst/video/colorbalance.h>
+
+#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
+#endif // GST_QT_GL_VIDEO_SINK_BASE_H
diff --git a/elements/gstqtvideosink/gstqtquick2videosink.cpp b/elements/gstqtvideosink/gstqtquick2videosink.cpp
new file mode 100644
index 0000000..bedc074
--- /dev/null
+++ b/elements/gstqtvideosink/gstqtquick2videosink.cpp
@@ -0,0 +1,452 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). <qt-info@nokia.com>
+ Copyright (C) 2011-2013 Collabora Ltd. <info@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "gstqtquick2videosink.h"
+#include "gstqtvideosinkplugin.h"
+#include "gstqtvideosinkmarshal.h"
+#include "delegates/qtquick2videosinkdelegate.h"
+
+#include <gst/video/colorbalance.h>
+
+#include <cstring>
+#include <QCoreApplication>
+
+#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 = NULL;
+
+ for (int i=0; i < LABEL_LAST; i++) {
+ channel = GST_COLOR_BALANCE_CHANNEL(g_object_new(GST_TYPE_COLOR_BALANCE_CHANNEL, NULL));
+ 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 = 0;
+
+ 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<QSGNode*>(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<GParamFlags>(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<GParamFlags>(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<GParamFlags>(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<GParamFlags>(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<GParamFlags>(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<GParamFlags>(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
+ * emited.
+ *
+ * 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<GSignalFlags>(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+ G_STRUCT_OFFSET(GstQtQuick2VideoSinkClass, update_node),
+ NULL, NULL,
+ 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 emited 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, NULL, NULL,
+ 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 <george.kiagiadakis@collabora.com>");
+}
diff --git a/elements/gstqtvideosink/gstqtquick2videosink.h b/elements/gstqtvideosink/gstqtquick2videosink.h
new file mode 100644
index 0000000..e5122d5
--- /dev/null
+++ b/elements/gstqtvideosink/gstqtquick2videosink.h
@@ -0,0 +1,57 @@
+/*
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __GST_QT_QUICK2_VIDEO_SINK_H__
+#define __GST_QT_QUICK2_VIDEO_SINK_H__
+
+#include <gst/video/gstvideosink.h>
+#include <QtGlobal>
+
+#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);
+
+#endif /* __GST_QT_QUICK2_VIDEO_SINK_H__ */
diff --git a/elements/gstqtvideosink/gstqtvideosink.cpp b/elements/gstqtvideosink/gstqtvideosink.cpp
new file mode 100644
index 0000000..f7e2581
--- /dev/null
+++ b/elements/gstqtvideosink/gstqtvideosink.cpp
@@ -0,0 +1,110 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). <qt-info@nokia.com>
+ Copyright (C) 2011-2012 Collabora Ltd. <info@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#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 <george.kiagiadakis@collabora.com>");
+}
+
+void GstQtVideoSink::class_init(gpointer g_class, gpointer class_data)
+{
+ Q_UNUSED(class_data);
+
+ GstQtVideoSinkClass *qt_video_sink_class = reinterpret_cast<GstQtVideoSinkClass*>(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 emited.
+ *
+ * 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<GSignalFlags>(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+ G_STRUCT_OFFSET(GstQtVideoSinkClass, paint),
+ NULL, NULL,
+ 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 emited 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, NULL, NULL,
+ 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<QPainter*>(painter),
+ QRectF(x, y, width, height));
+}
diff --git a/elements/gstqtvideosink/gstqtvideosink.h b/elements/gstqtvideosink/gstqtvideosink.h
new file mode 100644
index 0000000..f6544b4
--- /dev/null
+++ b/elements/gstqtvideosink/gstqtvideosink.h
@@ -0,0 +1,61 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). <qt-info@nokia.com>
+ Copyright (C) 2011-2012 Collabora Ltd. <info@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef GST_QT_VIDEO_SINK_H
+#define GST_QT_VIDEO_SINK_H
+
+#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);
+};
+
+#endif
diff --git a/elements/gstqtvideosink/gstqtvideosinkbase.cpp b/elements/gstqtvideosink/gstqtvideosinkbase.cpp
new file mode 100644
index 0000000..a707e02
--- /dev/null
+++ b/elements/gstqtvideosink/gstqtvideosinkbase.cpp
@@ -0,0 +1,215 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). <qt-info@nokia.com>
+ Copyright (C) 2011-2012 Collabora Ltd. <info@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "gstqtvideosinkbase.h"
+#include "delegates/qtvideosinkdelegate.h"
+#include "painters/genericsurfacepainter.h"
+#include <cstring>
+#include <QCoreApplication>
+
+#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 = NULL;
+
+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<GstVideoSinkClass*>(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<GParamFlags>(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<GParamFlags>(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/elements/gstqtvideosink/gstqtvideosinkbase.h b/elements/gstqtvideosink/gstqtvideosinkbase.h
new file mode 100644
index 0000000..c5cdfdb
--- /dev/null
+++ b/elements/gstqtvideosink/gstqtvideosinkbase.h
@@ -0,0 +1,78 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). <qt-info@nokia.com>
+ Copyright (C) 2011-2012 Collabora Ltd. <info@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef GST_QT_VIDEO_SINK_BASE_H
+#define GST_QT_VIDEO_SINK_BASE_H
+
+#include "gstqtvideosinkplugin.h"
+#include <gst/video/gstvideosink.h>
+
+#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;
+};
+
+#endif
diff --git a/elements/gstqtvideosink/gstqtvideosinkplugin.cpp b/elements/gstqtvideosink/gstqtvideosinkplugin.cpp
new file mode 100644
index 0000000..3f3b6df
--- /dev/null
+++ b/elements/gstqtvideosink/gstqtvideosinkplugin.cpp
@@ -0,0 +1,75 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). <qt-info@nokia.com>
+ Copyright (C) 2011 Collabora Ltd. <info@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "gstqtvideosinkplugin.h"
+#include "gstqtvideosink.h"
+#include "gstqtglvideosink.h"
+#include "gstqwidgetvideosink.h"
+
+#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
+# include "gstqtquick2videosink.h"
+#endif
+
+GST_DEBUG_CATEGORY(gst_qt_video_sink_debug);
+
+/* entry point to initialize the plug-in */
+static gboolean plugin_init(GstPlugin *plugin)
+{
+ GST_DEBUG_CATEGORY_INIT(gst_qt_video_sink_debug,
+ G_STRINGIFY(QTVIDEOSINK_NAME), 0,
+ "Debug category for GstQtVideoSink");
+
+ if(!gst_element_register(plugin, G_STRINGIFY(QTVIDEOSINK_NAME),
+ GST_RANK_NONE, GST_TYPE_QT_VIDEO_SINK)) {
+ GST_ERROR("Failed to register " G_STRINGIFY(QTVIDEOSINK_NAME));
+ 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,
+ QTVIDEOSINK_NAME,
+ "A video sink that can draw on any Qt surface",
+ plugin_init,
+ PACKAGE_VERSION,
+ "LGPL",
+ PACKAGE_NAME,
+ PACKAGE_ORIGIN
+)
diff --git a/elements/gstqtvideosink/gstqtvideosinkplugin.h b/elements/gstqtvideosink/gstqtvideosinkplugin.h
new file mode 100644
index 0000000..dc04671
--- /dev/null
+++ b/elements/gstqtvideosink/gstqtvideosinkplugin.h
@@ -0,0 +1,70 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). <qt-info@nokia.com>
+ Copyright (C) 2011 Collabora Ltd. <info@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#ifndef GST_QT_VIDEO_SINK_PLUGIN_H
+#define GST_QT_VIDEO_SINK_PLUGIN_H
+
+#include <gst/gst.h>
+#include <QtGlobal>
+
+GST_DEBUG_CATEGORY_EXTERN(gst_qt_video_sink_debug);
+#define GST_CAT_DEFAULT gst_qt_video_sink_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
+
+
+#endif
diff --git a/elements/gstqtvideosink/gstqwidgetvideosink.cpp b/elements/gstqtvideosink/gstqwidgetvideosink.cpp
new file mode 100644
index 0000000..6c98096
--- /dev/null
+++ b/elements/gstqtvideosink/gstqwidgetvideosink.cpp
@@ -0,0 +1,98 @@
+/*
+ Copyright (C) 2010 George Kiagiadakis <kiagiadakis.george@gmail.com>
+ Copyright (C) 2012 Collabora Ltd. <info@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#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 <george.kiagiadakis@collabora.com>");
+}
+
+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<GParamFlags>(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<QWidgetVideoSinkDelegate*>(sinkBase->delegate);
+
+ switch (prop_id) {
+ case PROP_WIDGET:
+ delegate->setWidget(static_cast<QWidget*>(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<QWidgetVideoSinkDelegate*>(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/elements/gstqtvideosink/gstqwidgetvideosink.h b/elements/gstqtvideosink/gstqwidgetvideosink.h
new file mode 100644
index 0000000..f56c043
--- /dev/null
+++ b/elements/gstqtvideosink/gstqwidgetvideosink.h
@@ -0,0 +1,55 @@
+/*
+ Copyright (C) 2010 George Kiagiadakis <kiagiadakis.george@gmail.com>
+ Copyright (C) 2012 Collabora Ltd. <info@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef GST_QWIDGET_VIDEO_SINK_H
+#define GST_QWIDGET_VIDEO_SINK_H
+
+#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;
+};
+
+#endif
diff --git a/elements/gstqtvideosink/painters/abstractsurfacepainter.h b/elements/gstqtvideosink/painters/abstractsurfacepainter.h
new file mode 100644
index 0000000..edc4177
--- /dev/null
+++ b/elements/gstqtvideosink/painters/abstractsurfacepainter.h
@@ -0,0 +1,42 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). <qt-info@nokia.com>
+ Copyright (C) 2011-2012 Collabora Ltd. <info@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#ifndef ABSTRACTSURFACEPAINTER_H
+#define ABSTRACTSURFACEPAINTER_H
+
+#include "../utils/bufferformat.h"
+#include <QRectF>
+
+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;
+};
+
+#endif
diff --git a/elements/gstqtvideosink/painters/genericsurfacepainter.cpp b/elements/gstqtvideosink/painters/genericsurfacepainter.cpp
new file mode 100644
index 0000000..fcdeadd
--- /dev/null
+++ b/elements/gstqtvideosink/painters/genericsurfacepainter.cpp
@@ -0,0 +1,106 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). <qt-info@nokia.com>
+ Copyright (C) 2011-2012 Collabora Ltd. <info@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#include "genericsurfacepainter.h"
+#include <QPainter>
+
+GenericSurfacePainter::GenericSurfacePainter()
+ : m_imageFormat(QImage::Format_Invalid)
+{
+}
+
+//static
+QSet<GstVideoFormat> GenericSurfacePainter::supportedPixelFormats()
+{
+ return QSet<GstVideoFormat>()
+#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/elements/gstqtvideosink/painters/genericsurfacepainter.h b/elements/gstqtvideosink/painters/genericsurfacepainter.h
new file mode 100644
index 0000000..e481a75
--- /dev/null
+++ b/elements/gstqtvideosink/painters/genericsurfacepainter.h
@@ -0,0 +1,51 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). <qt-info@nokia.com>
+ Copyright (C) 2011 Collabora Ltd. <info@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#ifndef GENERICSURFACEPAINTER_H
+#define GENERICSURFACEPAINTER_H
+
+#include "abstractsurfacepainter.h"
+#include <QSet>
+#include <QImage>
+
+/**
+ * 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<GstVideoFormat> 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;
+};
+
+#endif // GENERICSURFACEPAINTER_H
diff --git a/elements/gstqtvideosink/painters/openglsurfacepainter.cpp b/elements/gstqtvideosink/painters/openglsurfacepainter.cpp
new file mode 100644
index 0000000..51afab2
--- /dev/null
+++ b/elements/gstqtvideosink/painters/openglsurfacepainter.cpp
@@ -0,0 +1,796 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). <qt-info@nokia.com>
+ Copyright (C) 2011-2012 Collabora Ltd. <info@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#include "openglsurfacepainter.h"
+#include <QtCore/qmath.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()), \
+ GLfloat(rect.right()), GLfloat(rect.bottom()), \
+ GLfloat(rect.left()) , GLfloat(rect.top()), \
+ GLfloat(rect.right()), 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(
+ QLatin1String("glActiveTexture"));
+#endif
+}
+
+//static
+QSet<GstVideoFormat> OpenGLSurfacePainter::supportedPixelFormats()
+{
+ return QSet<GstVideoFormat>()
+ //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:
+ m_colorMatrix *= QMatrix4x4(
+ 1.164, 0.000, 1.793, -0.969,
+ 1.164, -0.213, -0.533, 0.300,
+ 1.164, 2.112, 0.000, -1.129,
+ 0.0, 0.000, 0.000, 1.0000);
+ break;
+ case GST_VIDEO_COLOR_MATRIX_BT601:
+ m_colorMatrix *= QMatrix4x4(
+ 1.164, 0.000, 1.596, -0.8708,
+ 1.164, -0.392, -0.813, 0.5296,
+ 1.164, 2.017, 0.000, -1.081,
+ 0.0, 0.000, 0.000, 1.0000);
+ break;
+ default:
+ break;
+ }
+}
+
+void OpenGLSurfacePainter::paint(quint8 *data,
+ const BufferFormat & frameFormat,
+ QPainter *painter,
+ const PaintAreas & areas)
+{
+ // if these are enabled, we need to reenable them after beginNativePainting()
+ // has been called, as they may get disabled
+ bool stencilTestEnabled = glIsEnabled(GL_STENCIL_TEST);
+ bool scissorTestEnabled = glIsEnabled(GL_SCISSOR_TEST);
+
+ painter->beginNativePainting();
+
+ if (stencilTestEnabled)
+ glEnable(GL_STENCIL_TEST);
+ if (scissorTestEnabled)
+ 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) {
+ glBindTexture(GL_TEXTURE_2D, m_textureIds[i]);
+ glTexImage2D(
+ GL_TEXTURE_2D,
+ 0,
+ m_textureInternalFormat,
+ m_textureWidths[i],
+ m_textureHeights[i],
+ 0,
+ m_textureFormat,
+ m_textureType,
+ data + m_textureOffsets[i]);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ 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(
+ QLatin1String("glProgramStringARB"));
+ glBindProgramARB = (_glBindProgramARB) context->getProcAddress(
+ QLatin1String("glBindProgramARB"));
+ glDeleteProgramsARB = (_glDeleteProgramsARB) context->getProcAddress(
+ QLatin1String("glDeleteProgramsARB"));
+ glGenProgramsARB = (_glGenProgramsARB) context->getProcAddress(
+ QLatin1String("glGenProgramsARB"));
+ glProgramLocalParameter4fARB = (_glProgramLocalParameter4fARB) context->getProcAddress(
+ QLatin1String("glProgramLocalParameter4fARB"));
+}
+
+void ArbFpSurfacePainter::init(const BufferFormat &format)
+{
+ Q_ASSERT(m_textureCount == 0);
+
+ 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 = glGetError();
+ if (glError != GL_NO_ERROR) {
+ throw QString("ARBfb Shader allocation error ") +
+ QString::number(static_cast<int>(glError), 16);
+ } else {
+ glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_programId);
+ glProgramStringARB(
+ GL_FRAGMENT_PROGRAM_ARB,
+ GL_PROGRAM_FORMAT_ASCII_ARB,
+ qstrlen(program),
+ reinterpret_cast<const GLvoid *>(program));
+
+ if ((glError = glGetError()) != GL_NO_ERROR) {
+ const GLubyte* errorString = 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<int>(glError), 16) +
+ reinterpret_cast<const char *>(errorString);
+ } else {
+ glGenTextures(m_textureCount, m_textureIds);
+ }
+ }
+}
+
+void ArbFpSurfacePainter::cleanup()
+{
+ 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);
+
+ 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));
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, m_textureIds[0]);
+
+ if (m_textureCount == 3) {
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, m_textureIds[1]);
+ glActiveTexture(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_2D, m_textureIds[2]);
+ glActiveTexture(GL_TEXTURE0);
+ }
+
+ glVertexPointer(2, GL_FLOAT, 0, vertexCoordArray);
+ glTexCoordPointer(2, GL_FLOAT, 0, textureCoordArray);
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ 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();
+ }
+
+ glGenTextures(m_textureCount, m_textureIds);
+}
+
+void GlslSurfacePainter::cleanup()
+{
+ 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);
+
+ if (m_textureCount == 3) {
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, m_textureIds[0]);
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, m_textureIds[1]);
+ glActiveTexture(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_2D, m_textureIds[2]);
+ glActiveTexture(GL_TEXTURE0);
+
+ m_program.setUniformValue("texY", 0);
+ m_program.setUniformValue("texU", 1);
+ m_program.setUniformValue("texV", 2);
+ } else {
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, m_textureIds[0]);
+
+ m_program.setUniformValue("texRgb", 0);
+ }
+ m_program.setUniformValue("colorMatrix", m_colorMatrix);
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ m_program.release();
+}
diff --git a/elements/gstqtvideosink/painters/openglsurfacepainter.h b/elements/gstqtvideosink/painters/openglsurfacepainter.h
new file mode 100644
index 0000000..05762dc
--- /dev/null
+++ b/elements/gstqtvideosink/painters/openglsurfacepainter.h
@@ -0,0 +1,135 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). <qt-info@nokia.com>
+ Copyright (C) 2011-2012 Collabora Ltd. <info@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#ifndef OPENGLSURFACEPAINTER_H
+#define OPENGLSURFACEPAINTER_H
+
+#ifndef GST_QT_VIDEO_SINK_NO_OPENGL
+
+#include "abstractsurfacepainter.h"
+#include <QGLShaderProgram>
+
+#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<GstVideoFormat> 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
+
+#endif // OPENGLSURFACEPAINTER_H
diff --git a/elements/gstqtvideosink/painters/videomaterial.cpp b/elements/gstqtvideosink/painters/videomaterial.cpp
new file mode 100644
index 0000000..7221aa5
--- /dev/null
+++ b/elements/gstqtvideosink/painters/videomaterial.cpp
@@ -0,0 +1,461 @@
+/*
+ Copyright (C) 2011-2013 Collabora Ltd. <info@collabora.com>
+ Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+ Copyright (C) 2013 basysKom GmbH <info@basyskom.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "videomaterial.h"
+
+#include <qmath.h>
+#include <QOpenGLContext>
+#include <QOpenGLFunctions>
+#include <QtQuick/QSGMaterialShader>
+
+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 * const 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 * const 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 * const 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 * const 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<VideoMaterial *>(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 <const char * const (*FragmentShader)()>
+class VideoMaterialShaderImpl : public VideoMaterialShader
+{
+protected:
+ virtual const char *fragmentShader() const {
+ return FragmentShader();
+ }
+};
+
+template <const char * const (*FragmentShader)()>
+class VideoMaterialImpl : public VideoMaterial
+{
+public:
+ virtual QSGMaterialType *type() const {
+ static QSGMaterialType theType;
+ return &theType;
+ }
+
+ virtual QSGMaterialShader *createShader() const {
+ return new VideoMaterialShaderImpl<FragmentShader>;
+ }
+};
+
+VideoMaterial *VideoMaterial::create(const BufferFormat & format)
+{
+ VideoMaterial *material = NULL;
+
+ switch (format.videoFormat()) {
+ // BGRx
+ case GST_VIDEO_FORMAT_BGRx:
+ case GST_VIDEO_FORMAT_BGRA:
+ material = new VideoMaterialImpl<qtvideosink_glsl_bgrxFragmentShader>;
+ material->initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
+ break;
+ case GST_VIDEO_FORMAT_BGR:
+ material = new VideoMaterialImpl<qtvideosink_glsl_bgrxFragmentShader>;
+ material->initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize());
+ break;
+
+ // xRGB
+ case GST_VIDEO_FORMAT_xRGB:
+ case GST_VIDEO_FORMAT_ARGB:
+ case GST_VIDEO_FORMAT_AYUV:
+ material = new VideoMaterialImpl<qtvideosink_glsl_xrgbFragmentShader>;
+ material->initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
+ break;
+
+ // RGBx
+ case GST_VIDEO_FORMAT_RGB:
+ case GST_VIDEO_FORMAT_v308:
+ material = new VideoMaterialImpl<qtvideosink_glsl_rgbxFragmentShader>;
+ material->initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize());
+ break;
+ case GST_VIDEO_FORMAT_RGB16:
+ material = new VideoMaterialImpl<qtvideosink_glsl_rgbxFragmentShader>;
+ material->initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, format.frameSize());
+ break;
+
+ // YUV 420 planar
+ case GST_VIDEO_FORMAT_I420:
+ case GST_VIDEO_FORMAT_YV12:
+ material = new VideoMaterialImpl<qtvideosink_glsl_yuvPlanarFragmentShader>;
+ material->initYuv420PTextureInfo(
+ (format.videoFormat() == GST_VIDEO_FORMAT_YV12) /* uvSwapped */,
+ format.frameSize());
+ break;
+
+ default:
+ Q_ASSERT(false);
+ break;
+ }
+
+ material->init(format.colorMatrix());
+ return material;
+}
+
+VideoMaterial::VideoMaterial() :
+ m_frame(0),
+ m_textureCount(0),
+ m_format(GST_VIDEO_FORMAT_UNKNOWN),
+ 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_textureSize.isEmpty())
+ glDeleteTextures(m_textureCount, m_textureIds);
+ gst_buffer_replace(&m_frame, NULL);
+}
+
+int VideoMaterial::compare(const QSGMaterial *other) const
+{
+ const VideoMaterial *m = static_cast<const VideoMaterial *>(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 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 VideoMaterial::initYuv420PTextureInfo(bool uvSwapped, 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;
+
+ if (uvSwapped)
+ qSwap (m_textureOffsets[1], m_textureOffsets[2]);
+}
+
+void VideoMaterial::init(GstVideoColorMatrix colorMatrixType)
+{
+ 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:
+ m_colorMatrix *= QMatrix4x4(
+ 1.164, 0.000, 1.793, -0.969,
+ 1.164, -0.213, -0.533, 0.300,
+ 1.164, 2.112, 0.000, -1.129,
+ 0.0, 0.000, 0.000, 1.0000);
+ break;
+ case GST_VIDEO_COLOR_MATRIX_BT601:
+ m_colorMatrix *= QMatrix4x4(
+ 1.164, 0.000, 1.596, -0.8708,
+ 1.164, -0.392, -0.813, 0.5296,
+ 1.164, 2.017, 0.000, -1.081,
+ 0.0, 0.000, 0.000, 1.0000);
+ break;
+ default:
+ break;
+ }
+}
+
+void VideoMaterial::bind()
+{
+ QOpenGLFunctions *functions = QOpenGLContext::currentContext()->functions();
+ GstBuffer *frame = NULL;
+
+ 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_textureCount > 1) {
+ functions->glActiveTexture(GL_TEXTURE1);
+ bindTexture(1, info.data);
+ }
+ if (m_textureCount > 2) {
+ functions->glActiveTexture(GL_TEXTURE2);
+ bindTexture(2, info.data);
+ }
+ functions->glActiveTexture(GL_TEXTURE0); // Finish with 0 as default texture unit
+ bindTexture(0, info.data);
+ gst_buffer_unmap(frame, &info);
+ gst_buffer_unref(frame);
+ } else {
+ if (m_textureCount > 1) {
+ functions->glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, m_textureIds[1]);
+ }
+ if (m_textureCount > 2) {
+ functions->glActiveTexture(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_2D, m_textureIds[2]);
+ }
+ functions->glActiveTexture(GL_TEXTURE0); // Finish with 0 as default texture unit
+ glBindTexture(GL_TEXTURE_2D, m_textureIds[0]);
+ }
+}
+
+void VideoMaterial::bindTexture(int i, const quint8 *data)
+{
+ glBindTexture(GL_TEXTURE_2D, m_textureIds[i]);
+ glTexImage2D(
+ GL_TEXTURE_2D,
+ 0,
+ m_textureInternalFormat,
+ m_textureWidths[i],
+ m_textureHeights[i],
+ 0,
+ m_textureFormat,
+ m_textureType,
+ data + m_textureOffsets[i]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+}
+
diff --git a/elements/gstqtvideosink/painters/videomaterial.h b/elements/gstqtvideosink/painters/videomaterial.h
new file mode 100644
index 0000000..90a6379
--- /dev/null
+++ b/elements/gstqtvideosink/painters/videomaterial.h
@@ -0,0 +1,78 @@
+/*
+ Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+ Copyright (C) 2013 basysKom GmbH <info@basyskom.com>
+ Copyright (C) 2013 Collabora Ltd. <info@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef VIDEOMATERIAL_H
+#define VIDEOMATERIAL_H
+
+#include "../utils/bufferformat.h"
+#include <QSize>
+#include <QMutex>
+#include <QMatrix4x4>
+
+#include <QtQuick/QSGMaterial>
+
+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 QSize &size);
+ void initYuv420PTextureInfo(bool uvSwapped, const QSize &size);
+ void init(GstVideoColorMatrix colorMatrixType);
+
+private:
+ void bindTexture(int i, const quint8 *data);
+
+
+ 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];
+ QSize m_textureSize;
+
+ GstVideoFormat m_format;
+ GLenum m_textureFormat;
+ GLuint m_textureInternalFormat;
+ GLenum m_textureType;
+
+ QMatrix4x4 m_colorMatrix;
+ GstVideoColorMatrix m_colorMatrixType;
+
+ friend class VideoMaterialShader;
+};
+
+#endif // VIDEOMATERIAL_H
diff --git a/elements/gstqtvideosink/painters/videonode.cpp b/elements/gstqtvideosink/painters/videonode.cpp
new file mode 100644
index 0000000..e14287c
--- /dev/null
+++ b/elements/gstqtvideosink/painters/videonode.cpp
@@ -0,0 +1,114 @@
+/*
+ Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+ Copyright (C) 2013 basysKom GmbH <info@basyskom.com>
+ Copyright (C) 2013 Collabora Ltd. <info@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "videonode.h"
+#include "videomaterial.h"
+
+#include <QtQuick/QSGFlatColorMaterial>
+
+VideoNode::VideoNode()
+ : m_validGeometry(false), QSGGeometryNode()
+{
+ setFlags(OwnsGeometry | OwnsMaterial, true);
+ setMaterialTypeSolidBlack();
+}
+
+void VideoNode::changeFormat(const BufferFormat & format)
+{
+ setMaterial(VideoMaterial::create(format));
+ m_materialType = MaterialTypeVideo;
+ m_validGeometry = false;
+}
+
+void VideoNode::setMaterialTypeSolidBlack()
+{
+ QSGFlatColorMaterial *m = new QSGFlatColorMaterial;
+ m->setColor(Qt::black);
+ setMaterial(m);
+ m_materialType = MaterialTypeSolidBlack;
+ m_validGeometry = false;
+}
+
+void VideoNode::setCurrentFrame(GstBuffer* buffer)
+{
+ Q_ASSERT (m_materialType == MaterialTypeVideo);
+ static_cast<VideoMaterial*>(material())->setCurrentFrame(buffer);
+ markDirty(DirtyMaterial);
+}
+
+void VideoNode::updateColors(int brightness, int contrast, int hue, int saturation)
+{
+ Q_ASSERT (m_materialType == MaterialTypeVideo);
+ static_cast<VideoMaterial*>(material())->updateColors(brightness, contrast, hue, saturation);
+ markDirty(DirtyMaterial);
+}
+
+/* Helpers */
+template <typename V>
+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 (!m_validGeometry)
+ 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 (!m_validGeometry)
+ 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 (!m_validGeometry) {
+ setGeometry(g);
+ m_validGeometry = true;
+ }
+
+ markDirty(DirtyGeometry);
+}
diff --git a/elements/gstqtvideosink/painters/videonode.h b/elements/gstqtvideosink/painters/videonode.h
new file mode 100644
index 0000000..8ba4c3b
--- /dev/null
+++ b/elements/gstqtvideosink/painters/videonode.h
@@ -0,0 +1,51 @@
+/*
+ Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+ Copyright (C) 2013 basysKom GmbH <info@basyskom.com>
+ Copyright (C) 2013 Collabora Ltd. <info@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef VIDEONODE_H
+#define VIDEONODE_H
+
+#include "../utils/bufferformat.h"
+
+#include <QtQuick/QSGGeometryNode>
+
+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;
+ bool m_validGeometry;
+};
+
+#endif // VIDEONODE_H
diff --git a/elements/gstqtvideosink/utils/bufferformat.cpp b/elements/gstqtvideosink/utils/bufferformat.cpp
new file mode 100644
index 0000000..e2cc2c0
--- /dev/null
+++ b/elements/gstqtvideosink/utils/bufferformat.cpp
@@ -0,0 +1,59 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). <qt-info@nokia.com>
+ Copyright (C) 2011-2012 Collabora Ltd. <info@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#include "bufferformat.h"
+#include <QByteArray>
+
+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/elements/gstqtvideosink/utils/bufferformat.h b/elements/gstqtvideosink/utils/bufferformat.h
new file mode 100644
index 0000000..44ba953
--- /dev/null
+++ b/elements/gstqtvideosink/utils/bufferformat.h
@@ -0,0 +1,70 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). <qt-info@nokia.com>
+ Copyright (C) 2011-2012 Collabora Ltd. <info@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#ifndef BUFFERFORMAT_H
+#define BUFFERFORMAT_H
+
+#include "utils.h"
+#include <QSharedData>
+#include <gst/video/video.h>
+
+/**
+ * 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<Data> d;
+};
+
+Q_DECLARE_METATYPE(GstVideoInfo)
+Q_DECLARE_METATYPE(GstVideoFormat)
+Q_DECLARE_METATYPE(GstVideoColorMatrix)
+Q_DECLARE_METATYPE(BufferFormat)
+
+#endif // BUFFERFORMAT_H
diff --git a/elements/gstqtvideosink/utils/utils.cpp b/elements/gstqtvideosink/utils/utils.cpp
new file mode 100644
index 0000000..0c83f04
--- /dev/null
+++ b/elements/gstqtvideosink/utils/utils.cpp
@@ -0,0 +1,85 @@
+/*
+ Copyright (C) 2011-2013 Collabora Ltd. <info@collabora.com>
+ Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+ Copyright (C) 2013 basysKom GmbH <info@basyskom.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#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/elements/gstqtvideosink/utils/utils.h b/elements/gstqtvideosink/utils/utils.h
new file mode 100644
index 0000000..f1528e6
--- /dev/null
+++ b/elements/gstqtvideosink/utils/utils.h
@@ -0,0 +1,78 @@
+/*
+ Copyright (C) 2011-2012 Collabora Ltd. <info@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#ifndef UTILS_H
+#define UTILS_H
+
+#include <QRectF>
+#include <QSize>
+#include <QMetaType>
+
+// 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)
+
+#endif
diff --git a/elements/gstqwidgetvideosink.cpp b/elements/gstqwidgetvideosink.cpp
deleted file mode 100644
index 27d89e7..0000000
--- a/elements/gstqwidgetvideosink.cpp
+++ /dev/null
@@ -1,637 +0,0 @@
-/*
- Copyright (C) 2010 George Kiagiadakis <kiagiadakis.george@gmail.com>
-
- 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 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 <http://www.gnu.org/licenses/>.
-*/
-
-/**
- * SECTION:element-qwidgetvideosink
- *
- * qwidgetvideosink is a video sink element that can draw directly on a QWidget
- * using the QPainter API. To use it, you only have to set a QWidget pointer as
- * the "widget" property and the video will then be rendered on that QWidget.
- *
- * This is useful for cases where you cannot or you do not want to use one of the
- * sinks that implement the GstXOverlay interface, for example for rendering video
- * inside a QGraphicsView or for rendering video on the QWS (Qt/Embedded) platform.
- * This sink is guaranteed to work on all platforms supported by Qt, however it
- * is not recommended to use it if you have another choice. For example, on X11 it
- * is recommended to use "xvimagesink" instead, which uses hardware acceleration.
- *
- * There are certain rules for using qwidgetvideosink with threads. It must be
- * created in the main thread, it must be destructed in the main thread and the
- * "widget" property may only be read or written from the main thread as well.
- * This is a (reasonable) limitation implied by Qt.
- */
-
-#include <gst/gst.h>
-#include <gst/video/gstvideosink.h>
-#include <gst/video/video.h>
-#include <QtCore/QCoreApplication>
-#include <QtCore/QWeakPointer>
-#include <QtCore/QEvent>
-#include <QtCore/QMutex>
-#include <QtGui/QWidget>
-#include <QtGui/QResizeEvent>
-#include <QtGui/QPainter>
-
-//BEGIN ******** declarations ********
-
-enum {
- BufferEventType = QEvent::User,
- DeactivateEventType
-};
-
-class BufferEvent : public QEvent
-{
-public:
- inline BufferEvent(GstBuffer *buf)
- : QEvent(static_cast<QEvent::Type>(BufferEventType)),
- buffer(gst_buffer_ref(buf))
- {
- }
-
- GstBuffer *buffer;
-};
-
-class DeactivateEvent : public QEvent
-{
-public:
- inline DeactivateEvent()
- : QEvent(static_cast<QEvent::Type>(DeactivateEventType))
- {
- }
-};
-
-class WidgetProxy : public QObject
-{
- Q_OBJECT
-public:
- WidgetProxy(GObject *sink);
- virtual ~WidgetProxy();
-
- // "widget" property
- QWidget *widget() const;
- void setWidget(QWidget *widget);
-
- // "force-aspect-ratio" property
- bool forceAspectRatio() const;
- void setForceAspectRatio(bool force);
-
- bool isActive() const;
- void setActive(bool active);
-
- QSize widgetSize() const;
- void setWidgetSize(const QSize & size);
-
-private Q_SLOTS:
- void widgetDestroyed();
-
-protected:
- virtual bool event(QEvent *event);
- virtual bool eventFilter(QObject *filteredObject, QEvent *event);
-
-private:
-#ifndef GST_DISABLE_GST_DEBUG
- //used for calling the Gst debug macros
- GObject *m_sink;
-#endif
-
- // "widget" property
- QWeakPointer<QWidget> m_widget;
-
- // original value of the Qt::WA_OpaquePaintEvent attribute
- bool m_opaquePaintEventAttribute : 1;
-
- // "force-aspect-ratio" property
- bool m_forceAspectRatio : 1;
-
- // whether the sink is active (PAUSED or PLAYING)
- bool m_isActive : 1;
- mutable QMutex m_isActiveMutex;
-
- // the current widget size, used for caps negotiation
- mutable QMutex m_widgetSizeMutex;
- QSize m_widgetSize;
-
- // the buffer to be drawn next
- GstBuffer *m_buffer;
-};
-
-
-GST_DEBUG_CATEGORY_STATIC(gst_qwidget_video_sink_debug);
-#define GST_CAT_DEFAULT gst_qwidget_video_sink_debug
-
-static const char *qwidgetvideosink_description = "A video sink that draws on a QWidget using QPainter";
-
-#define GST_TYPE_QWIDGETVIDEOSINK \
- (gst_qwidget_video_sink_get_type())
-#define GST_QWIDGETVIDEOSINK(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_QWIDGETVIDEOSINK,GstQWidgetVideoSink))
-#define GST_QWIDGETVIDEOSINK_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_QWIDGETVIDEOSINK,GstQWidgetVideoSinkClass))
-
-typedef struct _GstQWidgetVideoSink GstQWidgetVideoSink;
-typedef struct _GstQWidgetVideoSinkClass GstQWidgetVideoSinkClass;
-
-struct _GstQWidgetVideoSink
-{
- GstVideoSink element;
- WidgetProxy *proxy;
-};
-
-struct _GstQWidgetVideoSinkClass
-{
- GstVideoSinkClass parent_class;
-};
-
-enum {
- PROP_0,
- PROP_WIDGET,
- PROP_FORCE_ASPECT_RATIO
-};
-
-static void
-gst_qwidget_video_sink_finalize(GObject *object);
-
-static void
-gst_qwidget_video_sink_set_property(GObject *object, guint prop_id,
- const GValue *value, GParamSpec *pspec);
-
-static void
-gst_qwidget_video_sink_get_property(GObject *object, guint prop_id,
- GValue *value, GParamSpec *pspec);
-
-static GstStateChangeReturn
-gst_qwidget_video_sink_change_state(GstElement *element, GstStateChange transition);
-
-static GstFlowReturn
-gst_qwidget_video_sink_buffer_alloc(GstBaseSink *sink, guint64 offset,
- guint size, GstCaps *caps, GstBuffer **buf);
-
-static GstFlowReturn
-gst_qwidget_video_sink_show_frame(GstVideoSink *video_sink, GstBuffer *buf);
-
-//END ******** declarations ********
-//BEGIN ******** WidgetProxy ********
-
-WidgetProxy::WidgetProxy(GObject *sink)
- : QObject(),
-#ifndef GST_DISABLE_GST_DEBUG
- m_sink(sink),
-#endif
- m_forceAspectRatio(false),
- m_isActive(false),
- m_buffer(NULL)
-{
-}
-
-WidgetProxy::~WidgetProxy()
-{
- if (m_buffer) {
- gst_buffer_unref(m_buffer);
- }
- setWidget(NULL);
-}
-
-QWidget *WidgetProxy::widget() const
-{
- return m_widget.data();
-}
-
-void WidgetProxy::setWidget(QWidget *widget)
-{
- GST_DEBUG_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();
- disconnect(m_widget.data(), SIGNAL(destroyed(QObject*)), this, SLOT(widgetDestroyed()));
-
- m_widget = QWeakPointer<QWidget>();
- }
-
- if (widget) {
- widget->installEventFilter(this);
- m_opaquePaintEventAttribute = widget->testAttribute(Qt::WA_OpaquePaintEvent);
- widget->setAttribute(Qt::WA_OpaquePaintEvent, true);
- widget->update();
- connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(widgetDestroyed()));
-
- m_widget = widget;
- setWidgetSize(widget->size());
- }
-}
-
-void WidgetProxy::widgetDestroyed()
-{
- m_widget = QWeakPointer<QWidget>();
-}
-
-bool WidgetProxy::forceAspectRatio() const
-{
- return m_forceAspectRatio;
-}
-
-void WidgetProxy::setForceAspectRatio(bool force)
-{
- GST_DEBUG_OBJECT(m_sink, "Setting \"force-aspect-ratio\" property to %s", force ? "true" : "false");
-
- m_forceAspectRatio = force;
-}
-
-bool WidgetProxy::isActive() const
-{
- QMutexLocker lock(&m_isActiveMutex);
- return m_isActive;
-}
-
-void WidgetProxy::setActive(bool active)
-{
- GST_INFO_OBJECT(m_sink, active ? "Activating" : "Deactivating");
-
- QMutexLocker lock(&m_isActiveMutex);
- m_isActive = active;
- if (!active) {
- QCoreApplication::postEvent(this, new DeactivateEvent());
- }
-}
-
-QSize WidgetProxy::widgetSize() const
-{
- QMutexLocker lock(&m_widgetSizeMutex);
- return m_widgetSize;
-}
-
-void WidgetProxy::setWidgetSize(const QSize & size)
-{
- GST_DEBUG_OBJECT(m_sink, "Widget size changed to (%d, %d)", size.width(), size.height());
-
- QMutexLocker lock(&m_widgetSizeMutex);
- m_widgetSize = size;
-}
-
-bool WidgetProxy::event(QEvent *event)
-{
- switch(event->type()) {
- case BufferEventType:
- {
- BufferEvent *bufEvent = dynamic_cast<BufferEvent*>(event);
- Q_ASSERT(bufEvent);
-
- GST_LOG_OBJECT(m_sink, "Received buffer %"GST_PTR_FORMAT, bufEvent->buffer);
-
- if (m_buffer) {
- //free the previous buffer
- gst_buffer_unref(m_buffer);
- m_buffer = NULL;
- }
-
- if (m_widget && isActive()) {
- //schedule this frame for rendering
- m_buffer = bufEvent->buffer;
- m_widget.data()->update();
- } else {
- //no widget, drop the frame
- gst_buffer_unref(bufEvent->buffer);
- }
-
- return true;
- }
- case DeactivateEventType:
- {
- GST_LOG_OBJECT(m_sink, "Received deactivate event");
-
- if (m_buffer) {
- gst_buffer_unref(m_buffer);
- m_buffer = NULL;
- }
-
- if (m_widget) {
- m_widget.data()->update();
- }
-
- return true;
- }
- default:
- return QObject::event(event);
- }
-}
-
-bool WidgetProxy::eventFilter(QObject *filteredObject, QEvent *event)
-{
- if (filteredObject == m_widget.data()) {
- switch(event->type()) {
- case QEvent::Paint:
- {
- QPainter painter(m_widget.data());
- if (m_buffer && isActive()) {
- GstCaps *caps = GST_BUFFER_CAPS(m_buffer);
- GstStructure *structure = gst_caps_get_structure(caps, 0);
-
- GstVideoRectangle srcRect;
- srcRect.x = srcRect.y = 0;
- gst_structure_get_int(structure, "width", &srcRect.w);
- gst_structure_get_int(structure, "height", &srcRect.h);
-
- QRect drawRect;
- if (m_forceAspectRatio) {
- GstVideoRectangle destRect;
- destRect.x = destRect.y = 0;
- destRect.w = m_widget.data()->width();
- destRect.h = m_widget.data()->height();
-
- GstVideoRectangle resultRect;
- gst_video_sink_center_rect(srcRect, destRect, &resultRect, TRUE);
- drawRect = QRect(resultRect.x, resultRect.y, resultRect.w, resultRect.h);
-
- //we are probably not going to paint all the widget,
- //so fill the remaining space with black
- painter.fillRect(m_widget.data()->rect(), Qt::black);
- } else {
- drawRect = m_widget.data()->rect();
- }
-
- GST_LOG_OBJECT(m_sink, "Rendering buffer %"GST_PTR_FORMAT". "
- "Frame size is (%d, %d), "
- "widget size is (%d, %d), "
- "calculated draw area is (%d, %d)",
- m_buffer,
- srcRect.w, srcRect.h,
- m_widget.data()->width(), m_widget.data()->height(),
- drawRect.width(), drawRect.height());
-
- QImage image(m_buffer->data, srcRect.w, srcRect.h, QImage::Format_RGB32);
- painter.drawImage(drawRect, image);
- } else {
- GST_LOG_OBJECT(m_sink, "Filling widget with black");
- painter.fillRect(m_widget.data()->rect(), Qt::black);
- }
- return true;
- }
- case QEvent::Resize:
- {
- QResizeEvent *resizeEvent = dynamic_cast<QResizeEvent*>(event);
- setWidgetSize(resizeEvent->size());
- return false;
- }
- default:
- return false;
- }
- } else {
- return QObject::eventFilter(filteredObject, event);
- }
-}
-
-//END ******** WidgetProxy ********
-//BEGIN ******** GstQWidgetVideoSink pad template & boilerplate ********
-
-static GstStaticPadTemplate pad_template =
- GST_STATIC_PAD_TEMPLATE("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_VIDEO_CAPS_xRGB_HOST_ENDIAN));
-
-GST_BOILERPLATE(GstQWidgetVideoSink, gst_qwidget_video_sink, GstVideoSink, GST_TYPE_VIDEO_SINK);
-
-//END ******** GstQWidgetVideoSink pad template & boilerplate ********
-//BEGIN ******** GstQWidgetVideoSinkClass initialization methods ********
-
-static void gst_qwidget_video_sink_base_init(gpointer gclass)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS(gclass);
-
- gst_element_class_set_details_simple(element_class, "QWidgetVideoSink", "Sink/Video",
- qwidgetvideosink_description,
- "George Kiagiadakis <kiagiadakis.george@gmail.com>");
-
- gst_element_class_add_pad_template(element_class, gst_static_pad_template_get(&pad_template));
-}
-
-/* initialize the class vtable */
-static void gst_qwidget_video_sink_class_init(GstQWidgetVideoSinkClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
- gobject_class->finalize = gst_qwidget_video_sink_finalize;
- gobject_class->set_property = gst_qwidget_video_sink_set_property;
- gobject_class->get_property = gst_qwidget_video_sink_get_property;
-
- GstElementClass *element_class = GST_ELEMENT_CLASS(klass);
- element_class->change_state = gst_qwidget_video_sink_change_state;
-
- GstBaseSinkClass *basesink_class = GST_BASE_SINK_CLASS(klass);
- basesink_class->buffer_alloc = gst_qwidget_video_sink_buffer_alloc;
-
- GstVideoSinkClass *videosink_class = GST_VIDEO_SINK_CLASS(klass);
- videosink_class->show_frame = gst_qwidget_video_sink_show_frame;
-
- /**
- * 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<GParamFlags>(G_PARAM_READWRITE)));
-
- /**
- * GstQWidgetVideoSink::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 widget.
- **/
- 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<GParamFlags>(G_PARAM_READWRITE)));
-}
-
-//END ******** GstQWidgetVideoSinkClass initialization methods ********
-//BEGIN ******** GstQWidgetVideoSink instance virtual methods ********
-
-/* element constructor */
-static void gst_qwidget_video_sink_init(GstQWidgetVideoSink *sink, GstQWidgetVideoSinkClass*)
-{
- GST_INFO_OBJECT(sink, "Initializing qwidgetvideosink");
- sink->proxy = new WidgetProxy(G_OBJECT(sink));
-}
-
-/* element destructor */
-static void gst_qwidget_video_sink_finalize(GObject *object)
-{
- GstQWidgetVideoSink *sink = GST_QWIDGETVIDEOSINK(object);
-
- delete sink->proxy;
- sink->proxy = NULL;
- GST_INFO_OBJECT(sink, "Finalized qwidgetvideosink");
-
- G_OBJECT_CLASS(parent_class)->finalize(object);
-}
-
-static void gst_qwidget_video_sink_set_property(GObject *object, guint prop_id,
- const GValue *value, GParamSpec *pspec)
-{
- GstQWidgetVideoSink *sink = GST_QWIDGETVIDEOSINK(object);
-
- switch (prop_id) {
- case PROP_WIDGET:
- sink->proxy->setWidget(static_cast<QWidget*>(g_value_get_pointer(value)));
- break;
- case PROP_FORCE_ASPECT_RATIO:
- sink->proxy->setForceAspectRatio(g_value_get_boolean(value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void gst_qwidget_video_sink_get_property(GObject *object, guint prop_id,
- GValue *value, GParamSpec *pspec)
-{
- GstQWidgetVideoSink *sink = GST_QWIDGETVIDEOSINK(object);
-
- switch (prop_id) {
- case PROP_WIDGET:
- g_value_set_pointer(value, sink->proxy->widget());
- break;
- case PROP_FORCE_ASPECT_RATIO:
- g_value_set_boolean(value, sink->proxy->forceAspectRatio());
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static GstStateChangeReturn gst_qwidget_video_sink_change_state(GstElement *element,
- GstStateChange transition)
-{
- GstQWidgetVideoSink *sink = GST_QWIDGETVIDEOSINK(element);
-
- switch(transition) {
- case GST_STATE_CHANGE_READY_TO_PAUSED:
- sink->proxy->setActive(true);
- break;
- case GST_STATE_CHANGE_PAUSED_TO_READY:
- sink->proxy->setActive(false);
- break;
- default:
- break;
- }
-
- return GST_ELEMENT_CLASS(parent_class)->change_state(element, transition);
-}
-
-static GstFlowReturn gst_qwidget_video_sink_buffer_alloc(GstBaseSink *base_sink, guint64 offset,
- guint size, GstCaps *caps, GstBuffer **buf)
-{
- GstQWidgetVideoSink *sink = GST_QWIDGETVIDEOSINK(base_sink);
-
- bool unrefCaps = false;
- GstStructure *structure = gst_caps_get_structure(caps, 0);
-
- GstVideoRectangle srcRect;
- srcRect.x = srcRect.y = 0;
- if (!gst_structure_get_int(structure, "width", &srcRect.w) ||
- !gst_structure_get_int(structure, "height", &srcRect.h))
- {
- return GST_FLOW_NOT_NEGOTIATED;
- }
-
- GstVideoRectangle destRect;
- destRect.x = destRect.y = 0;
- QSize widgetSize = sink->proxy->widgetSize();
- destRect.w = widgetSize.width();
- destRect.h = widgetSize.height();
-
- GstVideoRectangle resultRect;
- if (sink->proxy->forceAspectRatio()) {
- gst_video_sink_center_rect(srcRect, destRect, &resultRect, TRUE);
- } else {
- resultRect = destRect;
- }
-
- if (resultRect.w != srcRect.w || resultRect.h != srcRect.h) {
- GstCaps *desiredCaps = gst_caps_copy(caps);
- GstStructure *structure = gst_caps_get_structure(desiredCaps, 0);
- gst_structure_set(structure, "width", G_TYPE_INT, resultRect.w,
- "height", G_TYPE_INT, resultRect.h, NULL);
-
- if (gst_pad_peer_accept_caps(GST_VIDEO_SINK_PAD(sink), desiredCaps)) {
- caps = desiredCaps;
- unrefCaps = true;
- size = resultRect.w * resultRect.h * 4;
- } else {
- gst_caps_unref(desiredCaps);
- }
- }
-
- *buf = gst_buffer_new_and_alloc(size);
- gst_buffer_set_caps(*buf, caps);
- GST_BUFFER_OFFSET(*buf) = offset;
-
- if (unrefCaps) {
- gst_caps_unref(caps);
- }
-
- GST_LOG_OBJECT(sink, "Requested buffer was (%d, %d), allocated was (%d, %d)",
- srcRect.w, srcRect.h, resultRect.w, resultRect.h);
-
- return GST_FLOW_OK;
-}
-
-static GstFlowReturn gst_qwidget_video_sink_show_frame(GstVideoSink *video_sink, GstBuffer *buf)
-{
- GstQWidgetVideoSink *sink = GST_QWIDGETVIDEOSINK(video_sink);
- GST_LOG_OBJECT(sink, "Posting new buffer (%"GST_PTR_FORMAT") for rendering", buf);
- QCoreApplication::postEvent(sink->proxy, new BufferEvent(buf));
- return GST_FLOW_OK;
-}
-
-//END ******** GstQWidgetVideoSink instance virtual methods ********
-//BEGIN ******** plugin interface ********
-
-/* entry point to initialize the plug-in */
-static gboolean plugin_init(GstPlugin *plugin)
-{
- GST_DEBUG_CATEGORY_INIT(gst_qwidget_video_sink_debug, "qwidgetvideosink",
- 0, qwidgetvideosink_description);
-
- return gst_element_register(plugin, "qwidgetvideosink",
- GST_RANK_NONE, GST_TYPE_QWIDGETVIDEOSINK);
-}
-
-GST_PLUGIN_DEFINE (
- GST_VERSION_MAJOR,
- GST_VERSION_MINOR,
- "qwidgetvideosink",
- qwidgetvideosink_description,
- plugin_init,
- PACKAGE_VERSION,
- "LGPL",
- PACKAGE_NAME,
- PACKAGE_ORIGIN
-)
-
-//END ******** plugin interface ********
-
-#include "gstqwidgetvideosink.moc"
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 195b5b5..01ae289 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -1,4 +1,44 @@
+macro(example_distcheck example)
+ add_custom_target(example_${example}_distcheck
+ ${CMAKE_COMMAND}
+ -DCMAKE_BUILD_TOOL=${CMAKE_BUILD_TOOL}
+ -DQT_QMAKE_EXECUTABLE=${QT_QMAKE_EXECUTABLE}
+ -DQT_VERSION=${QT_VERSION}
+ -DBINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}
+ -DSOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}
+ -DEXAMPLE=${example}
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/RunExamplesDistCheck.cmake
+ )
+
+ get_target_property(EXAMPLES_DISTCHECK_TARGET examples_distcheck TYPE)
+ if(NOT EXAMPLES_DISTCHECK_TARGET)
+ add_custom_target(examples_distcheck)
+ endif()
+
+ add_dependencies(examples_distcheck example_${example}_distcheck)
+endmacro()
+
add_subdirectory(player)
+example_distcheck(player)
+
add_subdirectory(appsink-src)
+example_distcheck(appsink-src)
+
add_subdirectory(recorder)
+example_distcheck(recorder)
+
add_subdirectory(voip)
+example_distcheck(voip)
+
+if (Qt4or5_Quick1_FOUND)
+ add_subdirectory(qmlplayer)
+ example_distcheck(qmlplayer)
+endif()
+
+if (Qt4or5_Quick2_FOUND)
+ add_subdirectory(qmlplayer2)
+ example_distcheck(qmlplayer2)
+endif()
+
+add_subdirectory(devmon)
+example_distcheck(devmon)
diff --git a/examples/RunExamplesDistCheck.cmake b/examples/RunExamplesDistCheck.cmake
new file mode 100644
index 0000000..369773e
--- /dev/null
+++ b/examples/RunExamplesDistCheck.cmake
@@ -0,0 +1,39 @@
+
+function (run_check tool tool_name)
+
+ execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory ${BINARY_DIR}/build-${EXAMPLE}-${tool_name})
+ execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${BINARY_DIR}/build-${EXAMPLE}-${tool_name})
+
+ if (${tool_name} STREQUAL "cmake")
+ set(arguments "-DQT_VERSION=${QT_VERSION}")
+ endif()
+
+ execute_process(COMMAND ${tool} ${SOURCE_DIR}/${EXAMPLE} ${arguments}
+ WORKING_DIRECTORY ${BINARY_DIR}/build-${EXAMPLE}-${tool_name}
+ RESULT_VARIABLE ${tool_name}_RESULT
+ )
+
+ if (NOT (${${tool_name}_RESULT} EQUAL 0))
+ execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory ${BINARY_DIR}/build-${EXAMPLE}-${tool_name})
+ message(FATAL_ERROR "-- ${tool_name} failed --")
+ else()
+ execute_process(COMMAND ${CMAKE_BUILD_TOOL}
+ WORKING_DIRECTORY ${BINARY_DIR}/build-${EXAMPLE}-${tool_name}
+ RESULT_VARIABLE MAKE_RESULT
+ )
+
+ if (NOT (${MAKE_RESULT} EQUAL 0))
+ execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory ${BINARY_DIR}/build-${EXAMPLE}-${tool_name})
+ message(FATAL_ERROR "-- make (${tool_name}) failed --")
+ endif()
+ endif()
+
+ execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory ${BINARY_DIR}/build-${EXAMPLE}-${tool_name})
+
+endfunction()
+
+message("##### Running CMAKE on ${EXAMPLE} example #####")
+run_check(${CMAKE_COMMAND} cmake)
+
+message("##### Running QMAKE on ${EXAMPLE} example #####")
+run_check(${QT_QMAKE_EXECUTABLE} qmake)
diff --git a/examples/appsink-src/CMakeLists.txt b/examples/appsink-src/CMakeLists.txt
index 9985a38..18103d3 100644
--- a/examples/appsink-src/CMakeLists.txt
+++ b/examples/appsink-src/CMakeLists.txt
@@ -1,9 +1,22 @@
# This file serves as an example of how to use cmake with QtGStreamer.
# It can be used for building this example either in the QtGStreamer source tree or standalone.
-find_package(QtGStreamer REQUIRED)
+project(qtgst-example-appsink-src)
+
+if (NOT BUILDING_QTGSTREAMER)
+ set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/modules)
+ find_package(Qt4or5 COMPONENTS Core REQUIRED)
+ if (${QT_VERSION} STREQUAL "5")
+ find_package(Qt5GStreamer REQUIRED)
+ else()
+ find_package(QtGStreamer REQUIRED)
+ endif()
+endif()
+
include_directories(${QTGSTREAMER_INCLUDES})
add_definitions(${QTGSTREAMER_DEFINITIONS})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${QTGSTREAMER_FLAGS}")
+
add_executable(appsink-src main.cpp)
target_link_libraries(appsink-src ${QTGSTREAMER_UTILS_LIBRARIES})
+qt4or5_use_modules(appsink-src Core)
diff --git a/examples/appsink-src/appsink-src.pro b/examples/appsink-src/appsink-src.pro
index a666cee..bcb048b 100644
--- a/examples/appsink-src/appsink-src.pro
+++ b/examples/appsink-src/appsink-src.pro
@@ -3,11 +3,19 @@
TEMPLATE = app
TARGET = appsink-src
+# produce nice compilation output
+CONFIG += silent
+
# Tell qmake to use pkg-config to find QtGStreamer.
CONFIG += link_pkgconfig
-# Now tell qmake to link to QtGStreamerUtils-0.10 and also use its include path and Cflags.
-PKGCONFIG += QtGStreamerUtils-0.10
+# Now tell qmake to link to QtGStreamer and also use its include path and Cflags.
+contains(QT_VERSION, ^4\\..*) {
+ PKGCONFIG += QtGStreamer-1.0 QtGStreamerUtils-1.0
+}
+contains(QT_VERSION, ^5\\..*) {
+ PKGCONFIG += Qt5GStreamer-1.0 Qt5GStreamerUtils-1.0
+}
# Recommended if you are using g++ 4.5 or later. Must be removed for other compilers.
#QMAKE_CXXFLAGS += -std=c++0x
diff --git a/examples/appsink-src/main.cpp b/examples/appsink-src/main.cpp
index d15cddc..723670c 100644
--- a/examples/appsink-src/main.cpp
+++ b/examples/appsink-src/main.cpp
@@ -10,13 +10,13 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
*/
#include <iostream>
-#include <QtCore/QCoreApplication>
+#include <QCoreApplication>
#include <QGlib/Error>
#include <QGlib/Connect>
#include <QGst/Init>
@@ -40,9 +40,10 @@ protected:
m_src->endOfStream();
}
- virtual QGst::FlowReturn newBuffer()
+ virtual QGst::FlowReturn newSample()
{
- m_src->pushBuffer(pullBuffer());
+ QGst::SamplePtr sample = pullSample();
+ m_src->pushBuffer(sample->buffer());
return QGst::FlowOk;
}
@@ -77,12 +78,12 @@ Player::Player(int argc, char **argv)
std::exit(1);
}
- const char *caps = "audio/x-raw-int,channels=1,rate=8000,"
- "signed=(boolean)true,width=16,depth=16,endianness=1234";
+ const char *caps = "audio/x-raw, format=(string)S16LE, channels=(int)1,"
+ " rate=(int)44100, layout=(string)interleaved";
/* source pipeline */
QString pipe1Descr = QString("filesrc location=\"%1\" ! "
- "decodebin2 ! "
+ "decodebin ! "
"audioconvert ! "
"audioresample ! "
"appsink name=\"mysink\" caps=\"%2\"").arg(argv[1], caps);
@@ -92,7 +93,8 @@ Player::Player(int argc, char **argv)
pipeline1->bus()->addSignalWatch();
/* sink pipeline */
- QString pipe2Descr = QString("appsrc name=\"mysrc\" caps=\"%1\" ! autoaudiosink").arg(caps);
+ QString pipe2Descr = QString("appsrc name=\"mysrc\" caps=\"%1\" is-live=true format=3 ! "
+ "autoaudiosink").arg(caps);
pipeline2 = QGst::Parse::launch(pipe2Descr).dynamicCast<QGst::Pipeline>();
m_src.setElement(pipeline2->getElementByName("mysrc"));
QGlib::connect(pipeline2->bus(), "message", this, &Player::onBusMessage);
diff --git a/examples/devmon/CMakeLists.txt b/examples/devmon/CMakeLists.txt
new file mode 100644
index 0000000..5f0674c
--- /dev/null
+++ b/examples/devmon/CMakeLists.txt
@@ -0,0 +1,23 @@
+project(qtgst-example-devmon)
+
+if (NOT BUILDING_QTGSTREAMER)
+ set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/modules)
+ find_package(Qt4or5 COMPONENTS Core Gui Widgets REQUIRED)
+ if (${QT_VERSION} STREQUAL "5")
+ find_package(Qt5GStreamer REQUIRED)
+ else()
+ find_package(QtGStreamer REQUIRED)
+ endif()
+ set(CMAKE_AUTOMOC ON)
+ set(CMAKE_INCLUDE_CURRENT_DIR ON)
+endif()
+
+include_directories(${QTGSTREAMER_INCLUDES})
+add_definitions(${QTGSTREAMER_DEFINITIONS})
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${QTGSTREAMER_FLAGS}")
+
+set(devmon_SOURCES main.cpp mainwindow.cpp)
+
+add_executable(devmon ${devmon_SOURCES})
+target_link_libraries(devmon ${QTGSTREAMER_UI_LIBRARIES})
+qt4or5_use_modules(devmon Core Gui Widgets)
diff --git a/examples/devmon/devmon.pro b/examples/devmon/devmon.pro
new file mode 100644
index 0000000..f553067
--- /dev/null
+++ b/examples/devmon/devmon.pro
@@ -0,0 +1,23 @@
+#
+# Copyright (C) 2015 Pavel Bludov <pbludov@gmail.com>
+#
+# 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 <http://www.gnu.org/licenses/>.
+QT += core gui widgets
+CONFIG += link_pkgconfig
+PKGCONFIG += Qt5GLib-2.0 Qt5GStreamer-1.0
+TARGET = devmon
+TEMPLATE = app
+SOURCES += main.cpp mainwindow.cpp
+HEADERS += mainwindow.h
+
diff --git a/examples/devmon/main.cpp b/examples/devmon/main.cpp
new file mode 100644
index 0000000..43b6126
--- /dev/null
+++ b/examples/devmon/main.cpp
@@ -0,0 +1,34 @@
+/*
+ Copyright (C) 2015 Pavel Bludov <pbludov@gmail.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#include "mainwindow.h"
+#include <QApplication>
+
+#include <QGst/Init>
+
+int main(int argc, char *argv[])
+{
+ QGst::init(&argc, &argv);
+ QApplication a(argc, argv);
+
+ MainWindow w;
+ w.show();
+
+ int ret = a.exec();
+
+ QGst::cleanup();
+ return ret;
+}
diff --git a/examples/devmon/mainwindow.cpp b/examples/devmon/mainwindow.cpp
new file mode 100644
index 0000000..eef3022
--- /dev/null
+++ b/examples/devmon/mainwindow.cpp
@@ -0,0 +1,270 @@
+/*
+ Copyright (C) 2015 Pavel Bludov <pbludov@gmail.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#include "mainwindow.h"
+
+#include <QApplication>
+#include <QBoxLayout>
+#include <QDebug>
+#include <QHeaderView>
+#include <QMessageBox>
+#include <QMenuBar>
+#include <QTextEdit>
+#include <QTreeWidget>
+
+#include <QGlib/Connect>
+#include <QGlib/ParamSpec>
+#include <QGst/ElementFactory>
+#include <QGst/Pipeline>
+
+MainWindow::MainWindow(QWidget *parent) :
+ QWidget(parent)
+{
+ //
+ // UI
+ //
+
+ deviceTree = new QTreeWidget;
+ propEdit = new QTextEdit;
+ capsEdit = new QTextEdit;
+
+ QLayout *layout = new QVBoxLayout();
+ layout->addWidget(deviceTree);
+ layout->addWidget(propEdit);
+ layout->addWidget(capsEdit);
+ setLayout(layout);
+
+ deviceTree->setColumnCount(2);
+ deviceTree->setColumnWidth(0, 250);
+ deviceTree->setHeaderLabels(QStringList(tr("Name")) << tr("Display name"));
+ deviceTree->addTopLevelItem(new QTreeWidgetItem(QStringList(tr("Devices"))));
+ deviceTree->setMinimumHeight(300);
+ connect(deviceTree, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
+ this, SLOT(onCurrentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)));
+ connect(deviceTree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT(onItemDoubleClicked(QTreeWidgetItem*,int)));
+
+ propEdit->setMinimumHeight(60);
+ propEdit->setReadOnly(true);
+
+ capsEdit->setMinimumHeight(200);
+ capsEdit->setReadOnly(true);
+ resize(800, 600);
+
+ //
+ // Menu
+ //
+
+ QMenuBar *bar = new QMenuBar();
+ QMenu *menu = new QMenu(tr("&Device Monitor"));
+ bar->addMenu(menu);
+ layout->setMenuBar(bar);
+
+ createElementAction = menu->addAction(tr("&Create"), this, SLOT(onCreateElement()), QKeySequence::New);
+ menu->addSeparator();
+ menu->addAction(tr("&Quit"), qApp, SLOT(quit()), QKeySequence::Quit);
+
+ //
+ // DeviceMonitor
+ //
+
+ monitor = QGst::DeviceMonitor::create();
+
+ if (!monitor) {
+ QMessageBox::warning(this, this->windowTitle(), "Failed to create the device monitor");
+ return;
+ }
+
+ if (!monitor->start()) {
+ QMessageBox::warning(this, this->windowTitle(), "Failed to start the device monitor");
+ return;
+ }
+
+ QGst::BusPtr bus = monitor->bus();
+ bus->addSignalWatch();
+ QGlib::connect(bus, "message", this, &MainWindow::onBusMessage);
+
+ // Add all existing devices to the list
+ Q_FOREACH (QGst::DevicePtr device, monitor->devices()) {
+ onDeviceAdded(device);
+ }
+}
+
+MainWindow::~MainWindow()
+{
+ QGst::BusPtr bus = monitor->bus();
+ bus->removeSignalWatch();
+ QGlib::disconnect(bus, "message", this, &MainWindow::onBusMessage);
+ monitor->stop();
+}
+
+void MainWindow::onBusMessage(const QGst::MessagePtr& msg)
+{
+ switch (msg->type()) {
+ case QGst::MessageDeviceAdded:
+ onDeviceAdded(msg.staticCast<QGst::DeviceAddedMessage>()->device());
+ break;
+ case QGst::MessageDeviceRemoved:
+ onDeviceRemoved(msg.staticCast<QGst::DeviceRemovedMessage>()->device());
+ break;
+ default:
+ qDebug() << msg->typeName() << " " << msg->source()->property("name").toString();
+ break;
+ }
+}
+
+void MainWindow::onDeviceAdded(const QGst::DevicePtr & device)
+{
+ QTreeWidgetItem *parent = deviceTree->topLevelItem(0);
+
+ // Create the class hierarchy tree
+ Q_FOREACH (QString cls, device->deviceClass().split('/')) {
+ QTreeWidgetItem* next = NULL;
+ for (int idx = 0; idx < parent->childCount(); ++idx) {
+ QTreeWidgetItem* item = parent->child(idx);
+ if (item->text(0) == cls) {
+ next = item;
+ break;
+ }
+ }
+ if (!next) {
+ next = new QTreeWidgetItem(QStringList(cls));
+ parent->addChild(next);
+ }
+ parent = next;
+ }
+
+ // Add newly created item for the device
+ QTreeWidgetItem* newItem = new QTreeWidgetItem(QStringList(device->name()) << device->displayName());
+ parent->addChild(newItem);
+ deviceTree->expandAll();
+
+ // Display all device properties. All of them are internal, undocumented, and should be never used
+ QString info;
+ Q_FOREACH (const QGlib::ParamSpecPtr & prop, device->listProperties()) {
+ if (QGlib::GetType<QGst::Device>().isA(prop->ownerType())) {
+ // Filter out all base class properties
+ continue;
+ }
+
+ info.append(prop->name())
+ .append('=')
+ .append(device->property(prop->name().toUtf8()).toString())
+ .append("\r\n");
+ }
+ newItem->setData(0, Qt::UserRole, info);
+ propEdit->setText(info);
+
+ // Dsiplay the device caps
+ QString caps = device->caps()->toString().replace("; ", ";\r\n");
+ newItem->setData(1, Qt::UserRole, caps);
+ capsEdit->setText(caps);
+}
+
+void MainWindow::onDeviceRemoved(const QGst::DevicePtr & device)
+{
+ Q_FOREACH (QTreeWidgetItem *item, deviceTree->findItems(device->name(), Qt::MatchRecursive)) {
+ if (item->isSelected()) {
+ // Clear prop & caps
+ onCurrentItemChanged(NULL, NULL);
+ }
+ delete item;
+ }
+}
+
+// Probe the device. Only Audio|Video/Source|Sink are implemented.
+void MainWindow::createElement(const QGst::DevicePtr & device)
+{
+ QGst::PipelinePtr pipeline = QGst::Pipeline::create();
+ QGst::ElementPtr src;
+ QGst::ElementPtr sink;
+
+ if (device->hasClasses("Source"))
+ {
+ src = device->createElement("src");
+ if (!src) {
+ QMessageBox::critical(this, this->windowTitle(), tr("Failed to create the source element"));
+ return;
+ }
+ sink = QGst::ElementFactory::make(device->hasClasses("Video")? "autovideosink": "autoaudiosink");
+ if (!sink) {
+ QMessageBox::critical(this, this->windowTitle(), tr("Failed to create the autosink element"));
+ return;
+ }
+ }
+ else if (device->hasClasses("Sink")) {
+ sink = device->createElement("sink");
+ if (!sink) {
+ QMessageBox::critical(this, this->windowTitle(), tr("Failed to create the sink element"));
+ return;
+ }
+ src = QGst::ElementFactory::make(device->hasClasses("Video")? "videotestsrc": "audiotestsrc");
+ if (!src) {
+ QMessageBox::critical(this, this->windowTitle(), tr("Failed to create the test source element"));
+ return;
+ }
+ }
+ else {
+ QMessageBox::warning(this, this->windowTitle(), tr("Unsupported class '%1'").arg(device->deviceClass()));
+ return;
+ }
+
+ // Build sample pipeline for testing
+
+ pipeline->add(src, sink);
+ src->link(sink);
+
+ pipeline->setState(QGst::StatePlaying);
+ if (QGst::StateChangeSuccess != pipeline->getState(NULL, NULL, QGst::ClockTime::fromSeconds(10))) {
+ QMessageBox::critical(this, this->windowTitle(), tr("Failed to set the pipeline to playing state"));
+ } else {
+ QMessageBox::information(this, device->displayName(), tr("It works! Press 'OK' to continue"));
+ }
+ pipeline->setState(QGst::StateNull);
+ pipeline->getState(NULL, NULL, QGst::ClockTime::fromSeconds(10));
+}
+
+void MainWindow::onCurrentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *)
+{
+ if (current) {
+ propEdit->setText(current->data(0, Qt::UserRole).toString());
+ capsEdit->setText(current->data(1, Qt::UserRole).toString());
+ createElementAction->setEnabled(!current->data(0, Qt::UserRole).isNull());
+ }
+ else {
+ propEdit->clear();
+ capsEdit->clear();
+ createElementAction->setEnabled(false);
+ }
+}
+
+void MainWindow::onCreateElement()
+{
+ QTreeWidgetItem *item = deviceTree->currentItem();
+ if (item) {
+ onItemDoubleClicked(item, 0);
+ }
+ }
+
+void MainWindow::onItemDoubleClicked(QTreeWidgetItem *item, int)
+{
+ QString name = item->text(0);
+ Q_FOREACH (QGst::DevicePtr device, monitor->devices()) {
+ if (device->name() == name) {
+ createElement(device);
+ break;
+ }
+ }
+}
diff --git a/examples/devmon/mainwindow.h b/examples/devmon/mainwindow.h
new file mode 100644
index 0000000..71e4c35
--- /dev/null
+++ b/examples/devmon/mainwindow.h
@@ -0,0 +1,55 @@
+/*
+ Copyright (C) 2015 Pavel Bludov <pbludov@gmail.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QWidget>
+
+#include <QGst/DeviceMonitor>
+#include <QGst/Message>
+
+class QTextEdit;
+class QTreeWidget;
+class QTreeWidgetItem;
+
+class MainWindow : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit MainWindow(QWidget *parent = 0);
+ ~MainWindow();
+
+private Q_SLOTS:
+ void onCreateElement();
+ void onCurrentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem*);
+ void onItemDoubleClicked(QTreeWidgetItem *item, int);
+
+private:
+ QAction *createElementAction;
+ QTreeWidget *deviceTree;
+ QTextEdit *propEdit;
+ QTextEdit *capsEdit;
+ QGst::DeviceMonitorPtr monitor;
+
+ void onBusMessage(const QGst::MessagePtr & msg);
+ void onDeviceAdded(const QGst::DevicePtr & device);
+ void onDeviceRemoved(const QGst::DevicePtr & device);
+ void createElement(const QGst::DevicePtr & device);
+};
+
+#endif // MAINWINDOW_H
diff --git a/examples/examples.dox b/examples/examples.dox
index acfc02d..b9f75e8 100644
--- a/examples/examples.dox
+++ b/examples/examples.dox
@@ -10,7 +10,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -65,7 +65,6 @@
* Tasks demonstrated in this example include:
* \li How to create and link elements manually.
* \li How to create and link elements using a pipeline description.
- * \li How to use the QGst::PropertyProbe interface.
* \li How to handle bus messages.
* \li Others...
*/
@@ -79,3 +78,23 @@
* you need to configure the destination ports of the one side to be the source
* ports of the other and vice versa.
*/
+
+/*! \example examples/qmlplayer/main.cpp
+ * This example demonstrates how to paint video on QML.
+ *
+ * Much of the code here is borrowed from the player example and it is not generally
+ * a good example on how to write QML and connect it with C++. The intention is just
+ * to demonstrate the use of QGst::Ui::GraphicsVideoSurface, which is bound on the
+ * QML context and then used by the VideoItem.
+ *
+ * qmlplayer.qml:
+ * \include examples/qmlplayer/qmlplayer.qml
+ *
+ * player.h:
+ * \include examples/qmlplayer/player.h
+ *
+ * player.cpp:
+ * \include examples/qmlplayer/player.cpp
+ *
+ * main.cpp:
+ */
diff --git a/examples/player/CMakeLists.txt b/examples/player/CMakeLists.txt
index de0665f..c6f4872 100644
--- a/examples/player/CMakeLists.txt
+++ b/examples/player/CMakeLists.txt
@@ -1,6 +1,23 @@
-include_directories(${QTGSTREAMER_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR})
+project(qtgst-example-player)
+
+if (NOT BUILDING_QTGSTREAMER)
+ set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/modules)
+ find_package(Qt4or5 COMPONENTS Core Gui Widgets REQUIRED)
+ if (${QT_VERSION} STREQUAL "5")
+ find_package(Qt5GStreamer REQUIRED)
+ else()
+ find_package(QtGStreamer REQUIRED)
+ endif()
+ set(CMAKE_AUTOMOC ON)
+ set(CMAKE_INCLUDE_CURRENT_DIR ON)
+endif()
+
+include_directories(${QTGSTREAMER_INCLUDES})
add_definitions(${QTGSTREAMER_DEFINITIONS})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${QTGSTREAMER_FLAGS}")
+
set(player_SOURCES main.cpp player.cpp mediaapp.cpp)
-automoc4_add_executable(player ${player_SOURCES})
+
+add_executable(player ${player_SOURCES})
target_link_libraries(player ${QTGSTREAMER_UI_LIBRARIES})
+qt4or5_use_modules(player Core Gui Widgets)
diff --git a/examples/player/main.cpp b/examples/player/main.cpp
index c104a93..f3ae8b5 100644
--- a/examples/player/main.cpp
+++ b/examples/player/main.cpp
@@ -9,13 +9,13 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
*/
#include "mediaapp.h"
-#include <QtGui/QApplication>
+#include <QApplication>
#include <QGst/Init>
int main(int argc, char *argv[])
diff --git a/examples/player/mediaapp.cpp b/examples/player/mediaapp.cpp
index 7802b1e..1f9ccf1 100644
--- a/examples/player/mediaapp.cpp
+++ b/examples/player/mediaapp.cpp
@@ -11,19 +11,20 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
*/
#include "mediaapp.h"
#include "player.h"
-#include <QtGui/QBoxLayout>
-#include <QtGui/QFileDialog>
-#include <QtGui/QToolButton>
-#include <QtGui/QLabel>
-#include <QtGui/QSlider>
-#include <QtGui/QMouseEvent>
+
+#include <QBoxLayout>
+#include <QFileDialog>
+#include <QToolButton>
+#include <QLabel>
+#include <QSlider>
+#include <QMouseEvent>
MediaApp::MediaApp(QWidget *parent)
: QWidget(parent)
@@ -128,7 +129,7 @@ void MediaApp::onPositionChanged()
length.toString("hh:mm:ss.zzz"));
if (length != QTime(0,0)) {
- m_positionSlider->setValue(curpos.msecsTo(QTime()) * 1000 / length.msecsTo(QTime()));
+ m_positionSlider->setValue(curpos.msecsTo(QTime(0,0)) * 1000 / length.msecsTo(QTime(0,0)));
} else {
m_positionSlider->setValue(0);
}
@@ -142,9 +143,9 @@ void MediaApp::onPositionChanged()
/* Called when the user changes the slider's position */
void MediaApp::setPosition(int value)
{
- uint length = -m_player->length().msecsTo(QTime());
+ uint length = -m_player->length().msecsTo(QTime(0,0));
if (length != 0 && value > 0) {
- QTime pos;
+ QTime pos(0,0);
pos = pos.addMSecs(length * (value / 1000.0));
m_player->setPosition(pos);
}
@@ -240,4 +241,4 @@ void MediaApp::createUI(QBoxLayout *appLayout)
appLayout->addLayout(btnLayout);
}
-#include "mediaapp.moc"
+#include "moc_mediaapp.cpp"
diff --git a/examples/player/mediaapp.h b/examples/player/mediaapp.h
index 2e50a15..fae333b 100644
--- a/examples/player/mediaapp.h
+++ b/examples/player/mediaapp.h
@@ -11,7 +11,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -19,9 +19,9 @@
#ifndef MEDIAAPP_H
#define MEDIAAPP_H
-#include <QtGui/QWidget>
-#include <QtGui/QStyle>
-#include <QtCore/QTimer>
+#include <QTimer>
+#include <QWidget>
+#include <QStyle>
class Player;
class QBoxLayout;
diff --git a/examples/player/player.cpp b/examples/player/player.cpp
index 6266644..bc67640 100644
--- a/examples/player/player.cpp
+++ b/examples/player/player.cpp
@@ -11,13 +11,14 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
*/
#include "player.h"
-#include <QtCore/QDir>
+#include <QDir>
+#include <QUrl>
#include <QGlib/Connect>
#include <QGlib/Error>
#include <QGst/Pipeline>
@@ -51,11 +52,11 @@ void Player::setUri(const QString & uri)
//if uri is not a real uri, assume it is a file path
if (realUri.indexOf("://") < 0) {
- realUri = "file://" + QFileInfo(realUri).absoluteFilePath();
+ realUri = QUrl::fromLocalFile(realUri).toEncoded();
}
if (!m_pipeline) {
- m_pipeline = QGst::ElementFactory::make("playbin2").dynamicCast<QGst::Pipeline>();
+ m_pipeline = QGst::ElementFactory::make("playbin").dynamicCast<QGst::Pipeline>();
if (m_pipeline) {
//let the video widget watch the pipeline for new video sinks
watchPipeline(m_pipeline);
@@ -83,7 +84,7 @@ QTime Player::position() const
m_pipeline->query(query);
return QGst::ClockTime(query->position()).toTime();
} else {
- return QTime();
+ return QTime(0,0);
}
}
@@ -134,7 +135,7 @@ QTime Player::length() const
m_pipeline->query(query);
return QGst::ClockTime(query->duration()).toTime();
} else {
- return QTime();
+ return QTime(0,0);
}
}
@@ -209,4 +210,4 @@ void Player::handlePipelineStateChange(const QGst::StateChangedMessagePtr & scm)
Q_EMIT stateChanged();
}
-#include "player.moc"
+#include "moc_player.cpp"
diff --git a/examples/player/player.h b/examples/player/player.h
index 3a42ca2..500dacc 100644
--- a/examples/player/player.h
+++ b/examples/player/player.h
@@ -11,7 +11,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -19,8 +19,8 @@
#ifndef PLAYER_H
#define PLAYER_H
-#include <QtCore/QTimer>
-#include <QtCore/QTime>
+#include <QTimer>
+#include <QTime>
#include <QGst/Pipeline>
#include <QGst/Ui/VideoWidget>
diff --git a/examples/player/player.pro b/examples/player/player.pro
index 1d56905..8657abd 100644
--- a/examples/player/player.pro
+++ b/examples/player/player.pro
@@ -3,12 +3,20 @@
TEMPLATE = app
TARGET = player
+# produce nice compilation output
+CONFIG += silent
+
# Tell qmake to use pkg-config to find QtGStreamer.
CONFIG += link_pkgconfig
-# Now tell qmake to link to QtGStreamer-0.10 and also use its include path and Cflags.
-# Also add QtGStreamerUi-0.10 here if you are using classes from QGst::Ui
-PKGCONFIG += QtGStreamer-0.10
+# Now tell qmake to link to QtGStreamer and also use its include path and Cflags.
+contains(QT_VERSION, ^4\\..*) {
+ PKGCONFIG += QtGStreamer-1.0 QtGStreamerUi-1.0
+}
+contains(QT_VERSION, ^5\\..*) {
+ PKGCONFIG += Qt5GStreamer-1.0 Qt5GStreamerUi-1.0
+ QT += widgets
+}
# Recommended if you are using g++ 4.5 or later. Must be removed for other compilers.
#QMAKE_CXXFLAGS += -std=c++0x
@@ -17,9 +25,7 @@ PKGCONFIG += QtGStreamer-0.10
# You can otherwise also define QT_NO_EMIT, but notice that this is not a documented Qt macro.
DEFINES += QT_NO_KEYWORDS
-# This example has no GUI
-QT -= gui
-
# Input
-HEADERS += movieplayer.h player.h
-SOURCES += main.cpp movieplayer.cpp player.cpp
+HEADERS += mediaapp.h player.h
+SOURCES += main.cpp mediaapp.cpp player.cpp
+
diff --git a/examples/qmlplayer/CMakeLists.txt b/examples/qmlplayer/CMakeLists.txt
new file mode 100644
index 0000000..7599754
--- /dev/null
+++ b/examples/qmlplayer/CMakeLists.txt
@@ -0,0 +1,50 @@
+project(qtgst-example-qmlplayer)
+
+if (NOT BUILDING_QTGSTREAMER)
+ set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/modules)
+ find_package(Qt4or5 COMPONENTS Core Gui Widgets Quick1 REQUIRED)
+ if (${QT_VERSION} STREQUAL "5")
+ find_package(Qt5GStreamer REQUIRED)
+ else()
+ find_package(QtGStreamer REQUIRED)
+ endif()
+
+ find_package(OpenGL)
+ find_package(OpenGLES2)
+
+ set(CMAKE_AUTOMOC ON)
+ set(CMAKE_INCLUDE_CURRENT_DIR ON)
+else()
+ # allow the example to run from the build tree without installing QtGStreamer
+ add_definitions(
+ -DQTVIDEOSINK_PATH="${QtGStreamer_BINARY_DIR}/elements/gstqtvideosink"
+ -DUNINSTALLED_IMPORTS_DIR="${QtGStreamer_BINARY_DIR}/src/qml/quick1"
+ )
+endif()
+
+include_directories(${QTGSTREAMER_INCLUDES})
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${QTGSTREAMER_FLAGS}")
+add_definitions(${QTGSTREAMER_DEFINITIONS})
+
+if (Qt4or5_OpenGL_FOUND AND (OPENGL_FOUND OR OPENGLES2_FOUND))
+ if (OPENGLES2_FOUND)
+ include_directories(${OPENGLES2_INCLUDE_DIR})
+ else()
+ include_directories(${OPENGL_INCLUDE_DIR})
+ endif()
+else()
+ add_definitions(-DQMLPLAYER_NO_OPENGL)
+endif()
+
+set(qmlplayer_SOURCES main.cpp player.cpp)
+qt4or5_add_resources(qmlplayer_rcc_SOURCES qmlplayer.qrc)
+
+add_executable(qmlplayer
+ ${qmlplayer_SOURCES}
+ ${qmlplayer_rcc_SOURCES}
+)
+target_link_libraries(qmlplayer ${QTGSTREAMER_UI_LIBRARIES})
+qt4or5_use_modules(qmlplayer Core Gui Widgets Quick1)
+if (Qt4or5_OpenGL_FOUND AND (OPENGL_FOUND OR OPENGLES2_FOUND))
+ qt4or5_use_modules(qmlplayer OpenGL)
+endif()
diff --git a/examples/qmlplayer/main.cpp b/examples/qmlplayer/main.cpp
new file mode 100644
index 0000000..bd94c76
--- /dev/null
+++ b/examples/qmlplayer/main.cpp
@@ -0,0 +1,67 @@
+/*
+ Copyright (C) 2012 Collabora Ltd. <info@collabora.com>
+ @author George Kiagiadakis <george.kiagiadakis@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#include "player.h"
+#include <cstdlib>
+#include <QApplication>
+#include <QDeclarativeView>
+#include <QDeclarativeContext>
+#include <QDeclarativeEngine>
+#include <QGst/Ui/GraphicsVideoSurface>
+#include <QGst/Init>
+
+#ifndef QMLPLAYER_NO_OPENGL
+# include <QGLWidget>
+#endif
+
+int main(int argc, char **argv)
+{
+#if defined(QTVIDEOSINK_PATH)
+ //this allows the example to run from the QtGStreamer build tree without installing QtGStreamer
+ qputenv("GST_PLUGIN_PATH", QTVIDEOSINK_PATH);
+#endif
+
+ QApplication app(argc, argv);
+ QGst::init(&argc, &argv);
+
+ QDeclarativeView view;
+
+#if !defined(QMLPLAYER_NO_OPENGL)
+ /*
+ * Setting a QGLWidget as the viewport is highly recommended as
+ * it enables hardware scaling & color conversion on the video sink
+ */
+ view.setViewport(new QGLWidget);
+#endif
+
+ QGst::Ui::GraphicsVideoSurface *surface = new QGst::Ui::GraphicsVideoSurface(&view);
+ view.rootContext()->setContextProperty(QLatin1String("videoSurface1"), surface);
+
+ Player *player = new Player(&view);
+ player->setVideoSink(surface->videoSink());
+ view.rootContext()->setContextProperty(QLatin1String("player"), player);
+
+#if defined(UNINSTALLED_IMPORTS_DIR)
+ //this allows the example to run from the QtGStreamer build tree without installing QtGStreamer
+ view.engine()->addImportPath(QLatin1String(UNINSTALLED_IMPORTS_DIR));
+#endif
+
+ view.setSource(QUrl(QLatin1String("qrc:///qmlplayer.qml")));
+ view.show();
+
+ return app.exec();
+}
diff --git a/examples/qmlplayer/player.cpp b/examples/qmlplayer/player.cpp
new file mode 100644
index 0000000..8b83615
--- /dev/null
+++ b/examples/qmlplayer/player.cpp
@@ -0,0 +1,107 @@
+/*
+ Copyright (C) 2010 Marco Ballesio <gibrovacco@gmail.com>
+ Copyright (C) 2011-2012 Collabora Ltd.
+ @author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
+
+ 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 <http://www.gnu.org/licenses/>.
+ */
+#include "player.h"
+#include <QUrl>
+#include <QFileDialog>
+#include <QGlib/Connect>
+#include <QGlib/Error>
+#include <QGst/ElementFactory>
+#include <QGst/Bus>
+
+Player::Player(QObject *parent)
+ : QObject(parent)
+{
+}
+
+void Player::setVideoSink(const QGst::ElementPtr & sink)
+{
+ m_videoSink = sink;
+}
+
+void Player::play()
+{
+ if (m_pipeline) {
+ m_pipeline->setState(QGst::StatePlaying);
+ }
+}
+
+void Player::stop()
+{
+ if (m_pipeline) {
+ m_pipeline->setState(QGst::StateNull);
+ }
+}
+
+void Player::open()
+{
+ // parent() is the QDeclarativeView here
+ QString fileName = QFileDialog::getOpenFileName(qobject_cast<QWidget*>(parent()),
+ tr("Open a Movie"), m_baseDir);
+
+ if (!fileName.isEmpty()) {
+ openFile(fileName);
+ }
+}
+
+void Player::openFile(const QString & fileName)
+{
+ m_baseDir = QFileInfo(fileName).path();
+
+ stop();
+ setUri(QUrl::fromLocalFile(fileName).toEncoded());
+ play();
+}
+
+void Player::setUri(const QString & uri)
+{
+ if (!m_pipeline) {
+ m_pipeline = QGst::ElementFactory::make("playbin").dynamicCast<QGst::Pipeline>();
+ if (m_pipeline) {
+ m_pipeline->setProperty("video-sink", m_videoSink);
+
+ //watch the bus for messages
+ QGst::BusPtr bus = m_pipeline->bus();
+ bus->addSignalWatch();
+ QGlib::connect(bus, "message", this, &Player::onBusMessage);
+ } else {
+ qCritical() << "Failed to create the pipeline";
+ }
+ }
+
+ if (m_pipeline) {
+ m_pipeline->setProperty("uri", uri);
+ }
+}
+
+void Player::onBusMessage(const QGst::MessagePtr & message)
+{
+ switch (message->type()) {
+ case QGst::MessageEos: //End of stream. We reached the end of the file.
+ stop();
+ break;
+ case QGst::MessageError: //Some error occurred.
+ qCritical() << message.staticCast<QGst::ErrorMessage>()->error();
+ stop();
+ break;
+ default:
+ break;
+ }
+}
+
+#include "moc_player.cpp"
diff --git a/examples/qmlplayer/player.h b/examples/qmlplayer/player.h
new file mode 100644
index 0000000..f527456
--- /dev/null
+++ b/examples/qmlplayer/player.h
@@ -0,0 +1,49 @@
+/*
+ Copyright (C) 2010 Marco Ballesio <gibrovacco@gmail.com>
+ Copyright (C) 2011-2012 Collabora Ltd.
+ @author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
+
+ 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 <http://www.gnu.org/licenses/>.
+ */
+#ifndef PLAYER_H
+#define PLAYER_H
+
+#include <QObject>
+#include <QGst/Pipeline>
+#include <QGst/Message>
+
+class Player : public QObject
+{
+ Q_OBJECT
+public:
+ explicit Player(QObject *parent = 0);
+
+ void setVideoSink(const QGst::ElementPtr & sink);
+
+public Q_SLOTS:
+ void play();
+ void stop();
+ void open();
+
+private:
+ void openFile(const QString & fileName);
+ void setUri(const QString & uri);
+ void onBusMessage(const QGst::MessagePtr & message);
+
+ QGst::PipelinePtr m_pipeline;
+ QGst::ElementPtr m_videoSink;
+ QString m_baseDir;
+};
+
+#endif // PLAYER_H
diff --git a/examples/qmlplayer/qmlplayer.pro b/examples/qmlplayer/qmlplayer.pro
new file mode 100644
index 0000000..2c7e8f8
--- /dev/null
+++ b/examples/qmlplayer/qmlplayer.pro
@@ -0,0 +1,34 @@
+# This is a qmake project file, provided as an example on how to use qmake with QtGStreamer.
+
+TEMPLATE = app
+TARGET = qmlplayer
+
+# produce nice compilation output
+CONFIG += silent
+
+# Tell qmake to use pkg-config to find QtGStreamer.
+CONFIG += link_pkgconfig
+
+# Now tell qmake to link to QtGStreamer and also use its include path and Cflags.
+contains(QT_VERSION, ^4\\..*) {
+ PKGCONFIG += QtGStreamer-1.0 QtGStreamerUi-1.0
+}
+contains(QT_VERSION, ^5\\..*) {
+ PKGCONFIG += Qt5GStreamer-1.0 Qt5GStreamerUi-1.0
+ QT += widgets
+}
+
+# Recommended if you are using g++ 4.5 or later. Must be removed for other compilers.
+#QMAKE_CXXFLAGS += -std=c++0x
+
+# Recommended, to avoid possible issues with the "emit" keyword
+# You can otherwise also define QT_NO_EMIT, but notice that this is not a documented Qt macro.
+DEFINES += QT_NO_KEYWORDS
+
+# link against QtDeclarative and QtOpenGL
+QT += declarative opengl
+
+# Input
+HEADERS += player.h
+SOURCES += main.cpp player.cpp
+RESOURCES += qmlplayer.qrc
diff --git a/examples/qmlplayer/qmlplayer.qml b/examples/qmlplayer/qmlplayer.qml
new file mode 100644
index 0000000..cadc460
--- /dev/null
+++ b/examples/qmlplayer/qmlplayer.qml
@@ -0,0 +1,76 @@
+/*
+ Copyright (C) 2012 Collabora Ltd. <info@collabora.com>
+ @author George Kiagiadakis <george.kiagiadakis@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+import QtQuick 1.0
+import QtGStreamer 1.0
+
+Rectangle {
+ id: window
+ width: 400
+ height: 300
+
+ Column {
+ VideoItem {
+ id: video
+
+ width: window.width
+ height: 260
+ surface: videoSurface1 //bound on the context from main()
+ }
+
+ Row {
+ id: buttons
+
+ width: window.width
+ height: 35
+ spacing: 5
+
+ Rectangle {
+ id: playButton
+ color: "black"
+
+ width: 60
+ height: 30
+
+ Text { text: "Play"; color: "white"; anchors.centerIn: parent }
+ MouseArea { anchors.fill: parent; onClicked: player.play() }
+ }
+
+ Rectangle {
+ id: stopButton
+ color: "black"
+
+ width: 60
+ height: 30
+
+ Text { text: "Stop"; color: "white"; anchors.centerIn: parent }
+ MouseArea { anchors.fill: parent; onClicked: player.stop() }
+ }
+
+ Rectangle {
+ id: openButton
+ color: "black"
+
+ width: 60
+ height: 30
+
+ Text { text: "Open file"; color: "white"; anchors.centerIn: parent }
+ MouseArea { anchors.fill: parent; onClicked: player.open() }
+ }
+ }
+ }
+}
diff --git a/examples/qmlplayer/qmlplayer.qrc b/examples/qmlplayer/qmlplayer.qrc
new file mode 100644
index 0000000..ebbb493
--- /dev/null
+++ b/examples/qmlplayer/qmlplayer.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC>
+<RCC version="1.0">
+ <qresource>
+ <file>qmlplayer.qml</file>
+ </qresource>
+</RCC>
diff --git a/examples/qmlplayer2/CMakeLists.txt b/examples/qmlplayer2/CMakeLists.txt
new file mode 100644
index 0000000..cbd58ee
--- /dev/null
+++ b/examples/qmlplayer2/CMakeLists.txt
@@ -0,0 +1,30 @@
+project(qtgst-example-qmlplayer2)
+
+if (NOT BUILDING_QTGSTREAMER)
+ set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/modules)
+ find_package(Qt4or5 COMPONENTS Core Gui Quick2 Qml REQUIRED)
+ find_package(Qt5GStreamer REQUIRED)
+
+ set(CMAKE_AUTOMOC ON)
+ set(CMAKE_INCLUDE_CURRENT_DIR ON)
+else()
+ # allow the example to run from the build tree without installing QtGStreamer
+ add_definitions(
+ -DQTVIDEOSINK_PATH="${QtGStreamer_BINARY_DIR}/elements/gstqtvideosink"
+ -DUNINSTALLED_IMPORTS_DIR="${QtGStreamer_BINARY_DIR}/src/qml/quick2"
+ )
+endif()
+
+include_directories(${QTGSTREAMER_INCLUDES})
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${QTGSTREAMER_FLAGS}")
+add_definitions(${QTGSTREAMER_DEFINITIONS})
+
+set(qmlplayer2_SOURCES main.cpp player.cpp)
+qt4or5_add_resources(qmlplayer2_rcc_SOURCES qmlplayer2.qrc)
+
+add_executable(qmlplayer2
+ ${qmlplayer2_SOURCES}
+ ${qmlplayer2_rcc_SOURCES}
+)
+target_link_libraries(qmlplayer2 ${QTGSTREAMER_QUICK_LIBRARIES})
+qt4or5_use_modules(qmlplayer2 Core Gui Quick2 Qml)
diff --git a/examples/qmlplayer2/main.cpp b/examples/qmlplayer2/main.cpp
new file mode 100644
index 0000000..797ceff
--- /dev/null
+++ b/examples/qmlplayer2/main.cpp
@@ -0,0 +1,60 @@
+/*
+ Copyright (C) 2012-2013 Collabora Ltd. <info@collabora.com>
+ @author George Kiagiadakis <george.kiagiadakis@collabora.com>
+ Copyright (C) 2013 basysKom GmbH <info@basyskom.com>
+ @author Benjamin Federau <benjamin.federau@basyskom.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#include "player.h"
+#include <QtGui/QGuiApplication>
+#include <QtQuick/QQuickView>
+#include <QtQml/QQmlContext>
+#include <QtQml/QQmlEngine>
+#include <QGst/Init>
+#include <QGst/Quick/VideoSurface>
+
+int main(int argc, char **argv)
+{
+#if defined(QTVIDEOSINK_PATH)
+ //this allows the example to run from the QtGStreamer build tree without installing QtGStreamer
+ qputenv("GST_PLUGIN_PATH", QTVIDEOSINK_PATH);
+#endif
+
+ QGuiApplication app(argc, argv);
+ QGst::init(&argc, &argv);
+
+ QQuickView view;
+
+ QGst::Quick::VideoSurface *surface = new QGst::Quick::VideoSurface;
+ view.rootContext()->setContextProperty(QLatin1String("videoSurface1"), surface);
+
+ Player *player = new Player(&view);
+ player->setVideoSink(surface->videoSink());
+ if (argc > 1)
+ player->setUri(QString::fromLocal8Bit(argv[1]));
+ else
+ player->setUri(QLatin1Literal("http://download.blender.org/peach/bigbuckbunny_movies/big_buck_bunny_480p_surround-fix.avi"));
+ view.rootContext()->setContextProperty(QLatin1String("player"), player);
+
+#if defined(UNINSTALLED_IMPORTS_DIR)
+ //this allows the example to run from the QtGStreamer build tree without installing QtGStreamer
+ view.engine()->addImportPath(QLatin1String(UNINSTALLED_IMPORTS_DIR));
+#endif
+
+ view.setSource(QUrl(QLatin1String("qrc:///qmlplayer2.qml")));
+ view.show();
+
+ return app.exec();
+}
diff --git a/examples/qmlplayer2/player.cpp b/examples/qmlplayer2/player.cpp
new file mode 100644
index 0000000..9baf3b3
--- /dev/null
+++ b/examples/qmlplayer2/player.cpp
@@ -0,0 +1,94 @@
+/*
+ Copyright (C) 2010 Marco Ballesio <gibrovacco@gmail.com>
+ Copyright (C) 2011-2013 Collabora Ltd.
+ @author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
+
+ 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 <http://www.gnu.org/licenses/>.
+ */
+#include "player.h"
+#include <QUrl>
+#include <QDebug>
+#include <QGlib/Connect>
+#include <QGlib/Error>
+#include <QGst/ElementFactory>
+#include <QGst/Bus>
+
+Player::Player(QObject *parent)
+ : QObject(parent)
+{
+}
+
+void Player::setVideoSink(const QGst::ElementPtr & sink)
+{
+ m_videoSink = sink;
+}
+
+void Player::play()
+{
+ if (m_pipeline) {
+ m_pipeline->setState(QGst::StatePlaying);
+ }
+}
+
+void Player::pause()
+{
+ if (m_pipeline) {
+ m_pipeline->setState(QGst::StatePaused);
+ }
+}
+
+void Player::stop()
+{
+ if (m_pipeline) {
+ m_pipeline->setState(QGst::StateNull);
+ }
+}
+
+void Player::setUri(const QString & uri)
+{
+ if (!m_pipeline) {
+ m_pipeline = QGst::ElementFactory::make("playbin").dynamicCast<QGst::Pipeline>();
+ if (m_pipeline) {
+ m_pipeline->setProperty("video-sink", m_videoSink);
+
+ //watch the bus for messages
+ QGst::BusPtr bus = m_pipeline->bus();
+ bus->addSignalWatch();
+ QGlib::connect(bus, "message", this, &Player::onBusMessage);
+ } else {
+ qCritical() << "Failed to create the pipeline";
+ }
+ }
+
+ if (m_pipeline) {
+ m_pipeline->setProperty("uri", uri);
+ }
+}
+
+void Player::onBusMessage(const QGst::MessagePtr & message)
+{
+ switch (message->type()) {
+ case QGst::MessageEos: //End of stream. We reached the end of the file.
+ stop();
+ break;
+ case QGst::MessageError: //Some error occurred.
+ qCritical() << message.staticCast<QGst::ErrorMessage>()->error();
+ stop();
+ break;
+ default:
+ break;
+ }
+}
+
+#include "moc_player.cpp"
diff --git a/examples/qmlplayer2/player.h b/examples/qmlplayer2/player.h
new file mode 100644
index 0000000..a3188e8
--- /dev/null
+++ b/examples/qmlplayer2/player.h
@@ -0,0 +1,47 @@
+/*
+ Copyright (C) 2010 Marco Ballesio <gibrovacco@gmail.com>
+ Copyright (C) 2011-2013 Collabora Ltd.
+ @author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
+
+ 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 <http://www.gnu.org/licenses/>.
+ */
+#ifndef PLAYER_H
+#define PLAYER_H
+
+#include <QObject>
+#include <QGst/Pipeline>
+#include <QGst/Message>
+
+class Player : public QObject
+{
+ Q_OBJECT
+public:
+ explicit Player(QObject *parent = 0);
+
+ void setVideoSink(const QGst::ElementPtr & sink);
+
+public Q_SLOTS:
+ void play();
+ void pause();
+ void stop();
+ void setUri(const QString & uri);
+
+private:
+ void onBusMessage(const QGst::MessagePtr & message);
+
+ QGst::PipelinePtr m_pipeline;
+ QGst::ElementPtr m_videoSink;
+};
+
+#endif // PLAYER_H
diff --git a/examples/qmlplayer2/qmlplayer2.pro b/examples/qmlplayer2/qmlplayer2.pro
new file mode 100644
index 0000000..405aa9d
--- /dev/null
+++ b/examples/qmlplayer2/qmlplayer2.pro
@@ -0,0 +1,28 @@
+# This is a qmake project file, provided as an example on how to use qmake with QtGStreamer.
+
+TEMPLATE = app
+TARGET = qmlplayer2
+
+# produce nice compilation output
+CONFIG += silent
+
+# Tell qmake to use pkg-config to find QtGStreamer.
+CONFIG += link_pkgconfig
+
+# Now tell qmake to link to QtGStreamer and also use its include path and Cflags.
+PKGCONFIG += Qt5GStreamerQuick-1.0
+
+# Recommended if you are using g++ 4.5 or later. Must be removed for other compilers.
+#QMAKE_CXXFLAGS += -std=c++0x
+
+# Recommended, to avoid possible issues with the "emit" keyword
+# You can otherwise also define QT_NO_EMIT, but notice that this is not a documented Qt macro.
+DEFINES += QT_NO_KEYWORDS
+
+# link against QtDeclarative and QtOpenGL
+QT += declarative opengl
+
+# Input
+HEADERS += player.h
+SOURCES += main.cpp player.cpp
+RESOURCES += qmlplayer2.qrc
diff --git a/examples/qmlplayer2/qmlplayer2.qml b/examples/qmlplayer2/qmlplayer2.qml
new file mode 100644
index 0000000..298fba4
--- /dev/null
+++ b/examples/qmlplayer2/qmlplayer2.qml
@@ -0,0 +1,79 @@
+/*
+ Copyright (C) 2012-2013 Collabora Ltd. <info@collabora.com>
+ @author George Kiagiadakis <george.kiagiadakis@collabora.com>
+ Copyright (C) 2013 basysKom GmbH <info@basyskom.com>
+ @author Benjamin Federau <benjamin.federau@basyskom.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+import QtQuick 2.0
+import QtGStreamer 1.0
+
+Rectangle {
+ id: window
+ width: 600
+ height: 300
+
+ Column {
+
+ VideoItem {
+ id: video
+
+ width: window.width
+ height: 260
+ surface: videoSurface1 //bound on the context from main()
+ }
+
+ Row {
+ id: buttons
+
+ width: window.width
+ height: 35
+ spacing: 5
+
+ Rectangle {
+ id: playButton
+ color: "black"
+
+ width: 60
+ height: 30
+
+ Text { text: "Play"; color: "white"; anchors.centerIn: parent }
+ MouseArea { anchors.fill: parent; onClicked: player.play() }
+ }
+
+ Rectangle {
+ id: pauseButton
+ color: "black"
+
+ width: 60
+ height: 30
+
+ Text { text: "Pause"; color: "white"; anchors.centerIn: parent }
+ MouseArea { anchors.fill: parent; onClicked: { player.pause(); } }
+ }
+
+ Rectangle {
+ id: stopButton
+ color: "black"
+
+ width: 60
+ height: 30
+
+ Text { text: "Stop"; color: "white"; anchors.centerIn: parent }
+ MouseArea { anchors.fill: parent; onClicked: player.stop() }
+ }
+ }
+ }
+}
diff --git a/examples/qmlplayer2/qmlplayer2.qrc b/examples/qmlplayer2/qmlplayer2.qrc
new file mode 100644
index 0000000..fa5e55a
--- /dev/null
+++ b/examples/qmlplayer2/qmlplayer2.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC>
+<RCC version="1.0">
+ <qresource>
+ <file>qmlplayer2.qml</file>
+ </qresource>
+</RCC>
diff --git a/examples/recorder/CMakeLists.txt b/examples/recorder/CMakeLists.txt
index 8352a3f..5185adf 100644
--- a/examples/recorder/CMakeLists.txt
+++ b/examples/recorder/CMakeLists.txt
@@ -1,6 +1,22 @@
-include_directories(${QTGSTREAMER_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR})
+project(qtgst-example-recorder)
+
+if (NOT BUILDING_QTGSTREAMER)
+ set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/modules)
+ find_package(Qt4or5 COMPONENTS Core Gui Widgets REQUIRED)
+ if (${QT_VERSION} STREQUAL "5")
+ find_package(Qt5GStreamer REQUIRED)
+ else()
+ find_package(QtGStreamer REQUIRED)
+ endif()
+ set(CMAKE_AUTOMOC ON)
+ set(CMAKE_INCLUDE_CURRENT_DIR ON)
+endif()
+
+include_directories(${QTGSTREAMER_INCLUDES})
add_definitions(${QTGSTREAMER_DEFINITIONS})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${QTGSTREAMER_FLAGS}")
-qt4_wrap_ui(recorder_UI_SRCS recorder.ui)
-automoc4_add_executable(recorder main.cpp ${recorder_UI_SRCS})
-target_link_libraries(recorder ${QTGSTREAMER_LIBRARIES} ${QT_QTGUI_LIBRARY})
+
+qt4or5_wrap_ui(recorder_UI_SRCS recorder.ui)
+add_executable(recorder main.cpp ${recorder_UI_SRCS})
+target_link_libraries(recorder ${QTGSTREAMER_LIBRARIES})
+qt4or5_use_modules(recorder Core Gui Widgets)
diff --git a/examples/recorder/main.cpp b/examples/recorder/main.cpp
index 66c31a4..f29b4ab 100644
--- a/examples/recorder/main.cpp
+++ b/examples/recorder/main.cpp
@@ -10,24 +10,23 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
*/
#include "ui_recorder.h"
-#include <QtCore/QDir>
-#include <QtGui/QApplication>
-#include <QtGui/QDialog>
-#include <QtGui/QMessageBox>
+#include <QDir>
+#include <QApplication>
+#include <QDialog>
+#include <QMessageBox>
#include <QGlib/Error>
#include <QGlib/Connect>
#include <QGst/Init>
#include <QGst/ElementFactory>
#include <QGst/ChildProxy>
-#include <QGst/PropertyProbe>
#include <QGst/Pipeline>
#include <QGst/Pad>
#include <QGst/Event>
@@ -35,7 +34,7 @@
#include <QGst/Bus>
#ifdef Q_WS_X11
-# include <QtGui/QX11Info>
+# include <QX11Info>
#endif
@@ -47,8 +46,6 @@ public:
private:
enum Device { AudioSrc, VideoSrc };
- void findDevices(Device device);
- void probeForDevices(const QGst::PropertyProbePtr & propertyProbe);
QGst::BinPtr createAudioSrcBin();
QGst::BinPtr createVideoSrcBin();
@@ -63,8 +60,6 @@ private Q_SLOTS:
private:
Ui::Recorder m_ui;
- QGst::PropertyProbePtr m_audioProbe;
- QGst::PropertyProbePtr m_videoProbe;
QGst::PipelinePtr m_pipeline;
};
@@ -73,10 +68,6 @@ Recorder::Recorder(QWidget *parent)
{
m_ui.setupUi(this);
- //setup the device combo boxes
- findDevices(AudioSrc);
- findDevices(VideoSrc);
-
QGst::ElementFactoryPtr ximagesrc = QGst::ElementFactory::find("ximagesrc");
if (!ximagesrc) {
//if we don't have ximagesrc, disable the choice to use it
@@ -92,72 +83,6 @@ Recorder::Recorder(QWidget *parent)
m_ui.outputFileEdit->setText(QDir::currentPath() + QDir::separator() + "out.ogv");
}
-void Recorder::findDevices(Device device)
-{
- const char *srcElementName = (device == AudioSrc) ? "autoaudiosrc" : "autovideosrc";
- QGst::ElementPtr src = QGst::ElementFactory::make(srcElementName);
-
- if (!src) {
- QMessageBox::critical(this, tr("Error"),
- tr("Failed to create element \"%1\". Make sure you have "
- "gstreamer-plugins-good installed").arg(srcElementName));
- return;
- }
-
- QGst::PropertyProbePtr propertyProbe;
-
- //autoaudiosrc and autovideosrc implement the child proxy interface
- //and create the correct child element when they go to the READY state
- src->setState(QGst::StateReady);
- QGst::ChildProxyPtr childProxy = src.dynamicCast<QGst::ChildProxy>();
- if (childProxy && childProxy->childrenCount() > 0) {
- //the actual source is the first child
- //this source usually implements the property probe interface
- propertyProbe = childProxy->childByIndex(0).dynamicCast<QGst::PropertyProbe>();
- }
- //we got a reference to the underlying propertyProbe, so we don't need src anymore.
- src->setState(QGst::StateNull);
-
- //Most sources and sinks have a "device" property which supports probe
- //and probing it returns all the available devices on the system.
- //Here we try to make use of that to list the system's devices
- //and if it fails, we just leave the source to use its default device.
- if (propertyProbe && propertyProbe->propertySupportsProbe("device")) {
- ((device == AudioSrc) ? m_audioProbe : m_videoProbe) = propertyProbe;
- probeForDevices(propertyProbe);
-
- //this signal will notify us when devices change
- QGlib::connect(propertyProbe, "probe-needed",
- this, &Recorder::probeForDevices, QGlib::PassSender);
- } else {
- QComboBox *box = (device == AudioSrc) ? m_ui.audioDeviceComboBox : m_ui.videoDeviceComboBox;
- box->addItem(tr("Default"));
- }
-}
-
-void Recorder::probeForDevices(const QGst::PropertyProbePtr & propertyProbe)
-{
- QComboBox *box = (propertyProbe == m_audioProbe) ?
- m_ui.audioDeviceComboBox : m_ui.videoDeviceComboBox;
-
- box->clear();
- box->addItem(tr("Default"));
-
- //get a list of devices that the element supports
- QList<QGlib::Value> devices = propertyProbe->probeAndGetValues("device");
-
- Q_FOREACH(const QGlib::Value & device, devices) {
- //set the element's device to the current device and retrieve its
- //human-readable name through the "device-name" property
- propertyProbe->setProperty("device", device);
- QString deviceName = propertyProbe->property("device-name").toString();
-
- //add the device on the combobox
- box->addItem(QString("%1 (%2)").arg(deviceName, device.toString()),
- device.toString());
- }
-}
-
QGst::BinPtr Recorder::createAudioSrcBin()
{
QGst::BinPtr audioBin;
@@ -170,22 +95,10 @@ QGst::BinPtr Recorder::createAudioSrcBin()
return QGst::BinPtr();
}
- //set the source's properties
- QVariant device = m_ui.audioDeviceComboBox->itemData(m_ui.audioDeviceComboBox->currentIndex());
- if (device.isValid()) {
- QGst::ElementPtr src = audioBin->getElementByName("audiosrc");
-
- //autoaudiosrc creates the actual source in the READY state
- src->setState(QGst::StateReady);
-
- QGst::ChildProxyPtr childProxy = src.dynamicCast<QGst::ChildProxy>();
- if (childProxy && childProxy->childrenCount() > 0) {
- //the actual source is the first child
- QGst::ObjectPtr realSrc = childProxy->childByIndex(0);
- realSrc->setProperty("device", device.toString());
- }
- }
+ QGst::ElementPtr src = audioBin->getElementByName("audiosrc");
+ //autoaudiosrc creates the actual source in the READY state
+ src->setState(QGst::StateReady);
return audioBin;
}
@@ -195,11 +108,12 @@ QGst::BinPtr Recorder::createVideoSrcBin()
try {
if (m_ui.videoSourceComboBox->currentIndex() == 0) { //camera
- videoBin = QGst::Bin::fromDescription("autovideosrc name=\"videosrc\" ! "
- "ffmpegcolorspace ! theoraenc ! queue");
+ videoBin = QGst::Bin::fromDescription("autovideosrc name=\"videosrc\" !"
+ "videoconvert ! theoraenc ! queue");
+ return videoBin;
} else { //screencast
videoBin = QGst::Bin::fromDescription("ximagesrc name=\"videosrc\" ! "
- "ffmpegcolorspace ! theoraenc ! queue");
+ "videoconvert ! theoraenc ! queue");
}
} catch (const QGlib::Error & error) {
qCritical() << "Failed to create video source bin:" << error;
@@ -207,22 +121,7 @@ QGst::BinPtr Recorder::createVideoSrcBin()
}
//set the source's properties
- if (m_ui.videoSourceComboBox->currentIndex() == 0) { //camera
- QVariant device = m_ui.videoDeviceComboBox->itemData(m_ui.videoDeviceComboBox->currentIndex());
- if (device.isValid()) {
- QGst::ElementPtr src = videoBin->getElementByName("videosrc");
-
- //autovideosrc creates the actual source in the READY state
- src->setState(QGst::StateReady);
-
- QGst::ChildProxyPtr childProxy = src.dynamicCast<QGst::ChildProxy>();
- if (childProxy && childProxy->childrenCount() > 0) {
- //the actual source is the first child
- QGst::ObjectPtr realSrc = childProxy->childByIndex(0);
- realSrc->setProperty("device", device.toString());
- }
- }
- } else { //screencast
+ if (m_ui.videoSourceComboBox->currentIndex() == 1) { //screencast
videoBin->getElementByName("videosrc")->setProperty("screen-num", m_ui.displayNumSpinBox->value());
}
@@ -248,10 +147,11 @@ void Recorder::start()
m_pipeline->add(audioSrcBin, videoSrcBin, mux, sink);
//link elements
- QGst::PadPtr audioPad = mux->getRequestPad("sink_%d");
+ QGst::PadPtr audioPad = mux->getRequestPad("audio_%u");
+
audioSrcBin->getStaticPad("src")->link(audioPad);
- QGst::PadPtr videoPad = mux->getRequestPad("sink_%d");
+ QGst::PadPtr videoPad = mux->getRequestPad("video_%u");
videoSrcBin->getStaticPad("src")->link(videoPad);
mux->link(sink);
@@ -319,4 +219,4 @@ int main(int argc, char *argv[])
return app.exec();
}
-#include "recorder.moc"
+#include "main.moc"
diff --git a/examples/recorder/recorder.pro b/examples/recorder/recorder.pro
new file mode 100644
index 0000000..b012e98
--- /dev/null
+++ b/examples/recorder/recorder.pro
@@ -0,0 +1,30 @@
+# This is a qmake project file, provided as an example on how to use qmake with QtGStreamer.
+
+TEMPLATE = app
+TARGET = recorder
+
+# produce nice compilation output
+CONFIG += silent
+
+# Tell qmake to use pkg-config to find QtGStreamer.
+CONFIG += link_pkgconfig
+
+# Now tell qmake to link to QtGStreamer and also use its include path and Cflags.
+contains(QT_VERSION, ^4\\..*) {
+ PKGCONFIG += QtGStreamer-1.0
+}
+contains(QT_VERSION, ^5\\..*) {
+ PKGCONFIG += Qt5GStreamer-1.0
+ QT += widgets
+}
+
+# Recommended if you are using g++ 4.5 or later. Must be removed for other compilers.
+#QMAKE_CXXFLAGS += -std=c++0x
+
+# Recommended, to avoid possible issues with the "emit" keyword
+# You can otherwise also define QT_NO_EMIT, but notice that this is not a documented Qt macro.
+DEFINES += QT_NO_KEYWORDS
+
+# Input
+FORMS += recorder.ui
+SOURCES += main.cpp
diff --git a/examples/recorder/recorder.ui b/examples/recorder/recorder.ui
index 7e750db..a22eda3 100644
--- a/examples/recorder/recorder.ui
+++ b/examples/recorder/recorder.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>306</width>
- <height>284</height>
+ <height>291</height>
</rect>
</property>
<property name="windowTitle">
@@ -46,33 +46,6 @@
</item>
</layout>
</item>
- <item>
- <widget class="QStackedWidget" name="audioSourcePropertiesWidget">
- <property name="currentIndex">
- <number>0</number>
- </property>
- <widget class="QWidget" name="microphonePage">
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <item>
- <widget class="QLabel" name="audioDeviceLabel">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Device:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QComboBox" name="audioDeviceComboBox"/>
- </item>
- </layout>
- </widget>
- </widget>
- </item>
</layout>
</widget>
</item>
@@ -121,21 +94,15 @@
<widget class="QWidget" name="cameraPage">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
- <widget class="QLabel" name="videoDeviceLabel">
+ <widget class="QLabel" name="emptyLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="text">
- <string>Device:</string>
- </property>
</widget>
</item>
- <item>
- <widget class="QComboBox" name="videoDeviceComboBox"/>
- </item>
</layout>
</widget>
<widget class="QWidget" name="screencastPage">
@@ -222,22 +189,6 @@
<resources/>
<connections>
<connection>
- <sender>audioSourceComboBox</sender>
- <signal>currentIndexChanged(int)</signal>
- <receiver>audioSourcePropertiesWidget</receiver>
- <slot>setCurrentIndex(int)</slot>
- <hints>
- <hint type="sourcelabel">
- <x>305</x>
- <y>52</y>
- </hint>
- <hint type="destinationlabel">
- <x>231</x>
- <y>73</y>
- </hint>
- </hints>
- </connection>
- <connection>
<sender>videoSourceComboBox</sender>
<signal>currentIndexChanged(int)</signal>
<receiver>videoSourcePropertiesWidget</receiver>
diff --git a/examples/voip/CMakeLists.txt b/examples/voip/CMakeLists.txt
index ef8dacf..96f608f 100644
--- a/examples/voip/CMakeLists.txt
+++ b/examples/voip/CMakeLists.txt
@@ -1,6 +1,22 @@
-include_directories(${QTGSTREAMER_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR})
+project(qtgst-example-voip)
+
+if (NOT BUILDING_QTGSTREAMER)
+ set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/modules)
+ find_package(Qt4or5 COMPONENTS Core Gui Widgets REQUIRED)
+ if (${QT_VERSION} STREQUAL "5")
+ find_package(Qt5GStreamer REQUIRED)
+ else()
+ find_package(QtGStreamer REQUIRED)
+ endif()
+ set(CMAKE_AUTOMOC ON)
+ set(CMAKE_INCLUDE_CURRENT_DIR ON)
+endif()
+
+include_directories(${QTGSTREAMER_INCLUDES})
add_definitions(${QTGSTREAMER_DEFINITIONS})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${QTGSTREAMER_FLAGS}")
-qt4_wrap_ui(voip_UI_SRCS voip.ui)
-automoc4_add_executable(voip main.cpp ${voip_UI_SRCS})
+
+qt4or5_wrap_ui(voip_UI_SRCS voip.ui)
+add_executable(voip main.cpp ${voip_UI_SRCS})
target_link_libraries(voip ${QTGSTREAMER_UI_LIBRARIES})
+qt4or5_use_modules(voip Core Gui Widgets)
diff --git a/examples/voip/main.cpp b/examples/voip/main.cpp
index 77f2f3e..d4f78f1 100644
--- a/examples/voip/main.cpp
+++ b/examples/voip/main.cpp
@@ -10,7 +10,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -43,14 +43,14 @@
'-------' | |
'----------'
- In the two sessions, the gstrtpbin element is common and the sessions are
+ In the two sessions, the rtpbin element is common and the sessions are
distinguished from the number at the end of rtpbin's pad names.
*/
#include "ui_voip.h"
-#include <QtGui/QApplication>
-#include <QtGui/QDialog>
+#include <QApplication>
+#include <QDialog>
#include <QGlib/Connect>
#include <QGlib/Error>
@@ -106,9 +106,9 @@ void VoipExample::on_startCallButton_clicked()
{
m_pipeline = QGst::Pipeline::create();
- QGst::ElementPtr rtpbin = QGst::ElementFactory::make("gstrtpbin");
+ QGst::ElementPtr rtpbin = QGst::ElementFactory::make("rtpbin");
if (!rtpbin) {
- qFatal("Failed to create gstrtpbin");
+ qFatal("Failed to create rtpbin");
}
m_pipeline->add(rtpbin);
@@ -118,7 +118,7 @@ void VoipExample::on_startCallButton_clicked()
QGst::ElementPtr audiosrc;
try {
audiosrc = QGst::Bin::fromDescription(
- "autoaudiosrc ! queue ! audioconvert ! audiorate ! audio/x-raw-int,rate=8000 "
+ "autoaudiosrc ! queue ! audioconvert ! audiorate ! audio/x-raw,rate=8000 "
"! speexenc ! rtpspeexpay"
);
} catch (const QGlib::Error & error) {
@@ -173,7 +173,7 @@ void VoipExample::on_startCallButton_clicked()
QGst::ElementPtr videosrc;
try {
videosrc = QGst::Bin::fromDescription(
- "videotestsrc is-live=true ! video/x-raw-yuv,width=320,height=240,framerate=15/1 "
+ "videotestsrc is-live=true ! video/x-raw,width=320,height=240,framerate=15/1 "
"! x264enc tune=zerolatency byte-stream=true bitrate=300 ! rtph264pay"
);
} catch (const QGlib::Error & error) {
@@ -242,13 +242,14 @@ void VoipExample::onRtpBinPadAdded(const QGst::PadPtr & pad)
QGst::ElementPtr bin;
try {
- if (pad->caps()->internalStructure(0)->value("media").toString() == QLatin1String("audio")) {
+ //recv_rtp_src_1_* -> session 1 - audio
+ if (pad->name().startsWith(QLatin1String("recv_rtp_src_1"))) {
bin = QGst::Bin::fromDescription(
"rtpspeexdepay ! speexdec ! audioconvert ! autoaudiosink"
);
- } else {
+ } else { //recv_rtp_src_2_* -> session 2 - video
bin = QGst::Bin::fromDescription(
- "rtph264depay ! ffdec_h264 ! ffmpegcolorspace ! autovideosink"
+ "rtph264depay ! avdec_h264 ! videoconvert ! autovideosink"
);
}
} catch (const QGlib::Error & error) {
@@ -287,4 +288,4 @@ int main(int argc, char *argv[])
return app.exec();
}
-#include "voipexample.moc"
+#include "main.moc"
diff --git a/examples/voip/voip.pro b/examples/voip/voip.pro
new file mode 100644
index 0000000..50dfda7
--- /dev/null
+++ b/examples/voip/voip.pro
@@ -0,0 +1,30 @@
+# This is a qmake project file, provided as an example on how to use qmake with QtGStreamer.
+
+TEMPLATE = app
+TARGET = voip
+
+# produce nice compilation output
+CONFIG += silent
+
+# Tell qmake to use pkg-config to find QtGStreamer.
+CONFIG += link_pkgconfig
+
+# Now tell qmake to link to QtGStreamer and also use its include path and Cflags.
+contains(QT_VERSION, ^4\\..*) {
+ PKGCONFIG += QtGStreamer-1.0 QtGStreamerUi-1.0
+}
+contains(QT_VERSION, ^5\\..*) {
+ PKGCONFIG += Qt5GStreamer-1.0 Qt5GStreamerUi-1.0
+ QT += widgets
+}
+
+# Recommended if you are using g++ 4.5 or later. Must be removed for other compilers.
+#QMAKE_CXXFLAGS += -std=c++0x
+
+# Recommended, to avoid possible issues with the "emit" keyword
+# You can otherwise also define QT_NO_EMIT, but notice that this is not a documented Qt macro.
+DEFINES += QT_NO_KEYWORDS
+
+# Input
+FORMS += voip.ui
+SOURCES += main.cpp
diff --git a/make_tarballs.sh b/make_tarballs.sh
index 57ca83a..4a26863 100755
--- a/make_tarballs.sh
+++ b/make_tarballs.sh
@@ -8,10 +8,7 @@
VERSION=`cat CMakeLists.txt | grep QTGSTREAMER_VERSION | sed -r 's#set\(QTGSTREAMER_VERSION ([0-9\.]+)\)#\1#'`
echo "Making tarballs for version $VERSION..."
-git archive --format=tar --prefix=qt-gstreamer-$VERSION/ HEAD | gzip -9 > qt-gstreamer-$VERSION.tar.gz
-md5sum qt-gstreamer-$VERSION.tar.gz > qt-gstreamer-$VERSION.tar.gz.md5
-
-git archive --format=tar --prefix=qt-gstreamer-$VERSION/ HEAD | bzip2 -9 > qt-gstreamer-$VERSION.tar.bz2
-md5sum qt-gstreamer-$VERSION.tar.bz2 > qt-gstreamer-$VERSION.tar.bz2.md5
+git archive --format=tar --prefix=qt-gstreamer-$VERSION/ HEAD | xz > qt-gstreamer-$VERSION.tar.xz
+sha256sum qt-gstreamer-$VERSION.tar.xz > qt-gstreamer-$VERSION.tar.xz.sha256sum
echo "Done."
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 11afe42..c0011df 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,7 +1,4 @@
-# Common variables
-set(LIB_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/lib)
-set(INCLUDES_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include/QtGStreamer)
-set(EXPORT_TARGET_SET QtGStreamerTargets)
+set(EXPORT_TARGET_SET ${QTGSTREAMER_PACKAGE_NAME}Targets)
if (QTGSTREAMER_STATIC)
set(SHARED_OR_STATIC "STATIC")
@@ -14,24 +11,33 @@ endif()
# Macro to run codegen from the subdirs
macro(run_codegen _dir_name _includes _headers)
- set(_prefixed_headers "")
- foreach(_header ${_headers})
- list(APPEND _prefixed_headers ${_dir_name}/${_header})
- endforeach()
+ if (QTGSTREAMER_CODEGEN)
+ set(_prefixed_headers "")
+ foreach(_header ${_headers})
+ list(APPEND _prefixed_headers ${_dir_name}/${_header})
+ endforeach()
+
+ add_custom_command(OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/gen.cpp
+ COMMAND codegen
+ ARGS ${_includes} ${_prefixed_headers}
+ > ${CMAKE_CURRENT_SOURCE_DIR}/gen.cpp
+ DEPENDS codegen ${_headers}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/..)
+ endif()
- add_custom_command(OUTPUT gen.cpp
- COMMAND codegen
- ARGS ${_includes} ${_prefixed_headers}
- > ${CMAKE_CURRENT_BINARY_DIR}/gen.cpp
- DEPENDS codegen ${_headers}
- WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/..)
+ add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/gen.cpp
+ COMMAND ${CMAKE_COMMAND}
+ ARGS -E copy ${CMAKE_CURRENT_SOURCE_DIR}/gen.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/gen.cpp
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/gen.cpp
+ COMMENT "Copying gen.cpp to the build directory")
endmacro()
# Macro to install headers from the subdirs
macro(install_headers _dir_name)
foreach(header ${ARGN})
get_filename_component(header_path ${header} PATH)
- install(FILES ${header} DESTINATION ${INCLUDES_INSTALL_DIR}/${_dir_name}/${header_path})
+ install(FILES ${header} DESTINATION ${QTGSTREAMER_INCLUDES_INSTALL_DIR}/${_dir_name}/${header_path})
endforeach()
endmacro()
@@ -40,21 +46,49 @@ include_directories(${QTGSTREAMER_INCLUDES})
add_definitions(${QTGSTREAMER_DEFINITIONS})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${QTGSTREAMER_FLAGS}")
+add_definitions(
+ -DQTVIDEOSINK_NAME="${QTVIDEOSINK_NAME}"
+ -DQTGLVIDEOSINK_NAME="${QTGLVIDEOSINK_NAME}"
+ -DQWIDGETVIDEOSINK_NAME="${QWIDGETVIDEOSINK_NAME}"
+)
+
# Build the libraries
add_subdirectory(QGlib)
add_subdirectory(QGst)
+# Build the qml plugins
+add_subdirectory(qml)
+
# Install the cmake scripts that are used to find the installed library from external projects
-install(EXPORT ${EXPORT_TARGET_SET} DESTINATION ${LIB_INSTALL_DIR}/QtGStreamer)
-install(FILES ${CMAKE_SOURCE_DIR}/cmake/modules/FindQtGStreamer.cmake
- DESTINATION ${LIB_INSTALL_DIR}/QtGStreamer
- RENAME QtGStreamerConfig.cmake)
+include(CMakePackageConfigHelpers)
+configure_package_config_file(
+ ${CMAKE_SOURCE_DIR}/cmake/modules/QtGStreamerConfig.cmake.in
+ ${CMAKE_CURRENT_BINARY_DIR}/${QTGSTREAMER_PACKAGE_NAME}Config.cmake
+ INSTALL_DESTINATION ${QTGSTREAMER_CMAKE_CONFIG_INSTALL_DIR}
+ PATH_VARS QTGSTREAMER_INCLUDES_INSTALL_DIR
+ NO_CHECK_REQUIRED_COMPONENTS_MACRO)
+write_basic_package_version_file(
+ ${CMAKE_CURRENT_BINARY_DIR}/${QTGSTREAMER_PACKAGE_NAME}ConfigVersion.cmake
+ VERSION ${QTGSTREAMER_VERSION}
+ COMPATIBILITY SameMajorVersion)
+install(EXPORT ${EXPORT_TARGET_SET} DESTINATION ${QTGSTREAMER_CMAKE_CONFIG_INSTALL_DIR})
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${QTGSTREAMER_PACKAGE_NAME}Config.cmake
+ ${CMAKE_CURRENT_BINARY_DIR}/${QTGSTREAMER_PACKAGE_NAME}ConfigVersion.cmake
+ ${CMAKE_SOURCE_DIR}/cmake/modules/QtGStreamerConfigCommon.cmake
+ DESTINATION ${QTGSTREAMER_CMAKE_CONFIG_INSTALL_DIR})
# Install pkgconfig files
file(GLOB_RECURSE PC_IN_FILES "*.pc.in")
foreach(pc_in_file ${PC_IN_FILES})
get_filename_component(pc_out_file ${pc_in_file} NAME)
string(REPLACE ".pc.in" ".pc" pc_out_file ${pc_out_file})
- configure_file(${pc_in_file} ${CMAKE_CURRENT_BINARY_DIR}/${pc_out_file} @ONLY)
- install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${pc_out_file} DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
+ if (USE_QT5)
+ string(REPLACE "Qt" "Qt5" pc_out_file ${pc_out_file})
+ endif()
+ # Qt4 version of the QtGStreamerQuick .pc file should not be installed
+ if (NOT ${pc_out_file} MATCHES "QtGStreamerQuick.*")
+ configure_file(${pc_in_file} ${CMAKE_CURRENT_BINARY_DIR}/${pc_out_file} @ONLY)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${pc_out_file}
+ DESTINATION ${QTGSTREAMER_PC_INSTALL_DIR})
+ endif()
endforeach()
diff --git a/src/QGlib/CMakeLists.txt b/src/QGlib/CMakeLists.txt
index ac3129c..e2df4d1 100644
--- a/src/QGlib/CMakeLists.txt
+++ b/src/QGlib/CMakeLists.txt
@@ -22,7 +22,7 @@ set(QtGLib_INSTALLED_HEADERS
paramspec.h ParamSpec
object.h Object
value.h Value
- signal.h Signal
+ qglib_signal.h Signal
emitimpl.h
connect.h Connect
connectimpl.h
@@ -39,19 +39,19 @@ set(QtGLib_CODEGEN_INCLUDES
# Setup the environment
set(QTGLIB_API_VERSION 2.0)
set(QTGLIB_SOVERSION 0)
-include_directories(${CMAKE_CURRENT_BINARY_DIR} ${GOBJECT_INCLUDE_DIR} ${GLIB2_INCLUDE_DIR})
+include_directories(${GOBJECT_INCLUDE_DIR} ${GLIB2_INCLUDE_DIR})
# Add command to generate gen.cpp using codegen
run_codegen("QGlib" "${QtGLib_CODEGEN_INCLUDES}" "${QtGLib_CODEGEN_HEADERS}")
# Build and link QtGLib
-automoc4_add_library(QtGLib ${SHARED_OR_STATIC} ${QtGLib_SRCS})
-set_target_properties(QtGLib PROPERTIES OUTPUT_NAME QtGLib-${QTGLIB_API_VERSION}
+add_library(${QTGLIB_LIBRARY} ${SHARED_OR_STATIC} ${QtGLib_SRCS})
+set_target_properties(${QTGLIB_LIBRARY} PROPERTIES OUTPUT_NAME ${QTGLIB_LIBRARY}-${QTGLIB_API_VERSION}
SOVERSION ${QTGLIB_SOVERSION}
VERSION ${QTGSTREAMER_VERSION})
-target_link_libraries(QtGLib ${QT_QTCORE_LIBRARY} ${GOBJECT_LIBRARIES})
-target_link_libraries(QtGLib LINK_INTERFACE_LIBRARIES ${QT_QTCORE_LIBRARY})
+target_link_libraries(${QTGLIB_LIBRARY} LINK_PRIVATE ${GOBJECT_LIBRARIES})
+qt4or5_use_modules(${QTGLIB_LIBRARY} LINK_PUBLIC Core)
# Install
-install(TARGETS QtGLib DESTINATION ${LIB_INSTALL_DIR} EXPORT ${EXPORT_TARGET_SET})
+install(TARGETS ${QTGLIB_LIBRARY} EXPORT ${EXPORT_TARGET_SET} ${QTGSTREAMER_INSTALL_TARGET_DEFAULT_ARGS})
install_headers("QGlib" ${QtGLib_INSTALLED_HEADERS})
diff --git a/src/QGlib/QtGLib-2.0.pc.in b/src/QGlib/QtGLib-2.0.pc.in
index cedb05e..96dac7c 100644
--- a/src/QGlib/QtGLib-2.0.pc.in
+++ b/src/QGlib/QtGLib-2.0.pc.in
@@ -1,12 +1,12 @@
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=${prefix}
-libdir=@LIB_INSTALL_DIR@
-includedir=@INCLUDES_INSTALL_DIR@
+libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
+includedir=${prefix}/@QTGSTREAMER_INCLUDES_INSTALL_DIR@
-Name: QtGLib-2.0
+Name: @QTGLIB_LIBRARY@-2.0
Description: Qt-style C++ bindings library for GLib & GObject
-Requires: QtCore
+Requires: @Qt4or5_Core_PKGCONFIG_DEP@
Requires.private: gobject-2.0
Version: @QTGSTREAMER_VERSION@
Cflags: -I${includedir}
-Libs: -L${libdir} -lQtGLib-2.0
+Libs: -L${libdir} -l@QTGLIB_LIBRARY@-2.0
diff --git a/src/QGlib/Signal b/src/QGlib/Signal
index d0e5cf6..e9b59c3 100644
--- a/src/QGlib/Signal
+++ b/src/QGlib/Signal
@@ -1 +1 @@
-#include "signal.h"
+#include "qglib_signal.h"
diff --git a/src/QGlib/connect.cpp b/src/QGlib/connect.cpp
index 749ccb6..58a3367 100644
--- a/src/QGlib/connect.cpp
+++ b/src/QGlib/connect.cpp
@@ -11,7 +11,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -21,8 +21,10 @@
#include <QtCore/QHash>
#include <QtCore/QMutex>
#include <boost/multi_index_container.hpp>
+#ifndef Q_MOC_RUN // See: https://bugreports.qt-project.org/browse/QTBUG-22829
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/ordered_index.hpp>
+#endif
#include <boost/multi_index/member.hpp>
namespace QGlib {
@@ -91,7 +93,7 @@ static void c_marshaller(GClosure *closure, GValue *returnValue, uint paramValue
"This is most likely a bug in the code that invoked the signal.");
}
} catch (...) {
- msg = QString::fromAscii(e.what());
+ msg = QString::fromLatin1(e.what());
}
}
diff --git a/src/QGlib/connect.h b/src/QGlib/connect.h
index 9b0e19b..acab694 100644
--- a/src/QGlib/connect.h
+++ b/src/QGlib/connect.h
@@ -11,7 +11,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/src/QGlib/connectimpl.h b/src/QGlib/connectimpl.h
index 1b3cb3d..3f40d1d 100644
--- a/src/QGlib/connectimpl.h
+++ b/src/QGlib/connectimpl.h
@@ -11,7 +11,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -158,7 +158,7 @@ struct CppClosure<F, R (Args...)>
virtual void marshaller(Value & result, const QList<Value> & params)
{
- if (static_cast<unsigned int>(params.size()) < sizeof...(Args)) {
+ if (static_cast<size_t>(params.size()) < sizeof...(Args)) {
throw std::logic_error("The signal provides less arguments than what the closure expects");
}
diff --git a/src/QGlib/emitimpl.h b/src/QGlib/emitimpl.h
index 188e7e9..cfd03e4 100644
--- a/src/QGlib/emitimpl.h
+++ b/src/QGlib/emitimpl.h
@@ -11,7 +11,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/src/QGlib/error.cpp b/src/QGlib/error.cpp
index 8535bc9..a7f9699 100644
--- a/src/QGlib/error.cpp
+++ b/src/QGlib/error.cpp
@@ -9,13 +9,13 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
*/
#include "error.h"
-#include <glib/gerror.h>
+#include <glib.h>
#include <QtCore/QDebug>
namespace QGlib {
@@ -32,42 +32,54 @@ Error::Error(Quark domain, int code, const QString & message)
m_error = g_error_new_literal(domain, code, message.toUtf8());
}
+Error Error::copy(GError *error)
+{
+ return Error(error ? g_error_copy(error) : NULL);
+}
+
Error::Error(const Error & other)
: std::exception()
{
- m_error = g_error_copy(other.m_error);
+ m_error = other.m_error ? g_error_copy(other.m_error) : NULL;
}
Error & Error::operator=(const Error & other)
{
- g_error_free(m_error);
- m_error = g_error_copy(other.m_error);
+ if (m_error != other.m_error) {
+ if(m_error) {
+ g_error_free(m_error);
+ }
+
+ m_error = other.m_error ? g_error_copy(other.m_error) : NULL;
+ }
return *this;
}
Error::~Error() throw()
{
- g_error_free(m_error);
+ if (m_error) {
+ g_error_free(m_error);
+ }
}
const char* Error::what() const throw()
{
- return m_error->message;
+ return m_error ? m_error->message : "";
}
Quark Error::domain() const
{
- return m_error->domain;
+ return m_error ? m_error->domain : 0;
}
int Error::code() const
{
- return m_error->code;
+ return m_error ? m_error->code : 0;
}
QString Error::message() const
{
- return QString::fromUtf8(m_error->message);
+ return m_error ? QString::fromUtf8(m_error->message) : QString();
}
Error::operator GError *()
diff --git a/src/QGlib/error.h b/src/QGlib/error.h
index 9bb3f9f..c685278 100644
--- a/src/QGlib/error.h
+++ b/src/QGlib/error.h
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -18,6 +18,7 @@
#define QGLIB_ERROR_H
#include "global.h"
+#include "type.h"
#include "quark.h"
#include <exception>
@@ -31,11 +32,13 @@ class QTGLIB_EXPORT Error : public std::exception
public:
/*! Wraps an existing GError into an Error.
* \note the constructed Error takes ownership of \a error */
- Error(GError *error);
+ Error(GError *error = NULL);
/*! Creates a new Error with the given \a domain, \a code and \a message */
Error(Quark domain, int code, const QString & message);
+ static Error copy(GError *error);
+
Error(const Error & other);
Error & operator=(const Error & other);
virtual ~Error() throw();
@@ -71,4 +74,6 @@ QTGLIB_EXPORT QDebug operator<<(QDebug dbg, const Error & error);
} //namespace QGlib
+QGLIB_REGISTER_TYPE(QGlib::Error)
+
#endif // QGLIB_ERROR_H
diff --git a/src/QGlib/gen.cpp b/src/QGlib/gen.cpp
new file mode 100644
index 0000000..7a972ac
--- /dev/null
+++ b/src/QGlib/gen.cpp
@@ -0,0 +1,153 @@
+// Autogenerated by the QtGStreamer helper code generator - DO NOT EDIT
+/*
+ Copyright (C) 2010 George Kiagiadakis <kiagiadakis.george@gmail.com>
+ Copyright (C) 2010 Collabora Ltd.
+ @author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#define INCLUDED_FROM_CODEGEN
+#include <boost/static_assert.hpp>
+
+#define REGISTER_TYPE_IMPLEMENTATION(T, GTYPE) \
+ namespace QGlib { \
+ GetTypeImpl<T>::operator Type() { return (GTYPE); } \
+ }
+
+#include <glib-object.h>
+#include "QGlib/string_p.h"
+
+#include "QGlib/qglib_signal.h"
+
+namespace QGlib {
+ BOOST_STATIC_ASSERT(static_cast<int>(Signal::RunFirst) == static_cast<int>(G_SIGNAL_RUN_FIRST));
+ BOOST_STATIC_ASSERT(static_cast<int>(Signal::RunLast) == static_cast<int>(G_SIGNAL_RUN_LAST));
+ BOOST_STATIC_ASSERT(static_cast<int>(Signal::RunCleanup) == static_cast<int>(G_SIGNAL_RUN_CLEANUP));
+ BOOST_STATIC_ASSERT(static_cast<int>(Signal::NoRecurse) == static_cast<int>(G_SIGNAL_NO_RECURSE));
+ BOOST_STATIC_ASSERT(static_cast<int>(Signal::Detailed) == static_cast<int>(G_SIGNAL_DETAILED));
+ BOOST_STATIC_ASSERT(static_cast<int>(Signal::Action) == static_cast<int>(G_SIGNAL_ACTION));
+ BOOST_STATIC_ASSERT(static_cast<int>(Signal::NoHooks) == static_cast<int>(G_SIGNAL_NO_HOOKS));
+}
+
+#include "QGlib/paramspec.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGlib::ParamSpec,G_TYPE_PARAM)
+
+REGISTER_TYPE_IMPLEMENTATION(QGlib::ParamSpec::ParamFlags,G_TYPE_PARAM_FLAGS)
+
+namespace QGlib {
+ QGlib::RefCountedObject *ParamSpec_new(void *instance)
+ {
+ QGlib::ParamSpec *cppClass = new QGlib::ParamSpec;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGlib
+
+namespace QGlib {
+ BOOST_STATIC_ASSERT(static_cast<int>(ParamSpec::Readable) == static_cast<int>(G_PARAM_READABLE));
+ BOOST_STATIC_ASSERT(static_cast<int>(ParamSpec::Writable) == static_cast<int>(G_PARAM_WRITABLE));
+ BOOST_STATIC_ASSERT(static_cast<int>(ParamSpec::ReadWrite) == static_cast<int>(G_PARAM_READWRITE));
+ BOOST_STATIC_ASSERT(static_cast<int>(ParamSpec::Construct) == static_cast<int>(G_PARAM_CONSTRUCT));
+ BOOST_STATIC_ASSERT(static_cast<int>(ParamSpec::ConstructOnly) == static_cast<int>(G_PARAM_CONSTRUCT_ONLY));
+ BOOST_STATIC_ASSERT(static_cast<int>(ParamSpec::LaxValidation) == static_cast<int>(G_PARAM_LAX_VALIDATION));
+ BOOST_STATIC_ASSERT(static_cast<int>(ParamSpec::Deprecated) == static_cast<int>(G_PARAM_DEPRECATED));
+}
+
+#include "QGlib/global.h"
+
+#include "QGlib/value.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGlib::Value,G_TYPE_VALUE)
+
+#include "QGlib/object.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGlib::Object,G_TYPE_OBJECT)
+
+REGISTER_TYPE_IMPLEMENTATION(QGlib::Interface,G_TYPE_INTERFACE)
+
+namespace QGlib {
+ QGlib::RefCountedObject *Object_new(void *instance)
+ {
+ QGlib::Object *cppClass = new QGlib::Object;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGlib
+
+namespace QGlib {
+ QGlib::RefCountedObject *Interface_new(void *instance)
+ {
+ QGlib::Interface *cppClass = new QGlib::Interface;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGlib
+
+#include "QGlib/error.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGlib::Error,G_TYPE_ERROR)
+
+#include "QGlib/type.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGlib::Type,G_TYPE_GTYPE)
+
+namespace QGlib {
+ BOOST_STATIC_ASSERT(static_cast<int>(Type::Invalid) == static_cast<int>(G_TYPE_INVALID));
+ BOOST_STATIC_ASSERT(static_cast<int>(Type::None) == static_cast<int>(G_TYPE_NONE));
+ BOOST_STATIC_ASSERT(static_cast<int>(Type::Interface) == static_cast<int>(G_TYPE_INTERFACE));
+ BOOST_STATIC_ASSERT(static_cast<int>(Type::Char) == static_cast<int>(G_TYPE_CHAR));
+ BOOST_STATIC_ASSERT(static_cast<int>(Type::Uchar) == static_cast<int>(G_TYPE_UCHAR));
+ BOOST_STATIC_ASSERT(static_cast<int>(Type::Boolean) == static_cast<int>(G_TYPE_BOOLEAN));
+ BOOST_STATIC_ASSERT(static_cast<int>(Type::Int) == static_cast<int>(G_TYPE_INT));
+ BOOST_STATIC_ASSERT(static_cast<int>(Type::Uint) == static_cast<int>(G_TYPE_UINT));
+ BOOST_STATIC_ASSERT(static_cast<int>(Type::Long) == static_cast<int>(G_TYPE_LONG));
+ BOOST_STATIC_ASSERT(static_cast<int>(Type::Ulong) == static_cast<int>(G_TYPE_ULONG));
+ BOOST_STATIC_ASSERT(static_cast<int>(Type::Int64) == static_cast<int>(G_TYPE_INT64));
+ BOOST_STATIC_ASSERT(static_cast<int>(Type::Uint64) == static_cast<int>(G_TYPE_UINT64));
+ BOOST_STATIC_ASSERT(static_cast<int>(Type::Enum) == static_cast<int>(G_TYPE_ENUM));
+ BOOST_STATIC_ASSERT(static_cast<int>(Type::Flags) == static_cast<int>(G_TYPE_FLAGS));
+ BOOST_STATIC_ASSERT(static_cast<int>(Type::Float) == static_cast<int>(G_TYPE_FLOAT));
+ BOOST_STATIC_ASSERT(static_cast<int>(Type::Double) == static_cast<int>(G_TYPE_DOUBLE));
+ BOOST_STATIC_ASSERT(static_cast<int>(Type::String) == static_cast<int>(G_TYPE_STRING));
+ BOOST_STATIC_ASSERT(static_cast<int>(Type::Pointer) == static_cast<int>(G_TYPE_POINTER));
+ BOOST_STATIC_ASSERT(static_cast<int>(Type::Boxed) == static_cast<int>(G_TYPE_BOXED));
+ BOOST_STATIC_ASSERT(static_cast<int>(Type::Param) == static_cast<int>(G_TYPE_PARAM));
+ BOOST_STATIC_ASSERT(static_cast<int>(Type::Object) == static_cast<int>(G_TYPE_OBJECT));
+}
+
+#include "QGlib/quark.h"
+
+#include "QGlib/refpointer.h"
+
+#include "QGlib/connect.h"
+
+
+#include "QGlib/init.h"
+
+#include "QGlib/wrap.h"
+
+namespace QGlib {
+namespace Private {
+ void registerWrapperConstructors()
+ {
+ QGlib::Quark q = g_quark_from_static_string("QGlib__wrapper_constructor");
+ QGlib::GetType<ParamSpec>().setQuarkData(q, reinterpret_cast<void*>(&ParamSpec_new));
+ QGlib::GetType<Object>().setQuarkData(q, reinterpret_cast<void*>(&Object_new));
+ QGlib::GetType<Interface>().setQuarkData(q, reinterpret_cast<void*>(&Interface_new));
+ }
+} //namespace Private
+} //namespace QGlib
+
diff --git a/src/QGlib/global.h b/src/QGlib/global.h
index 314ed02..57e755f 100644
--- a/src/QGlib/global.h
+++ b/src/QGlib/global.h
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -17,11 +17,16 @@
#ifndef QGLIB_GLOBAL_H
#define QGLIB_GLOBAL_H
+// workaround for https://bugreports.qt-project.org/browse/QTBUG-22829
+#if defined(Q_MOC_RUN) && !defined(BOOST_TT_HAS_OPERATOR_HPP_INCLUDED)
+#define BOOST_TT_HAS_OPERATOR_HPP_INCLUDED
+#endif
+
#include <QtCore/QtGlobal>
#include <boost/config.hpp>
/* defined by cmake when building this library */
-#if defined(QtGLib_EXPORTS)
+#if defined(QtGLib_EXPORTS) || defined(Qt5GLib_EXPORTS)
# define QTGLIB_EXPORT Q_DECL_EXPORT
#else
# define QTGLIB_EXPORT Q_DECL_IMPORT
diff --git a/src/QGlib/init.cpp b/src/QGlib/init.cpp
index ab0cb7c..fc05731 100644
--- a/src/QGlib/init.cpp
+++ b/src/QGlib/init.cpp
@@ -10,7 +10,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/src/QGlib/init.h b/src/QGlib/init.h
index ae8f670..56c5fa1 100644
--- a/src/QGlib/init.h
+++ b/src/QGlib/init.h
@@ -10,7 +10,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/src/QGlib/object.cpp b/src/QGlib/object.cpp
index 77fc7e0..db5d44d 100644
--- a/src/QGlib/object.cpp
+++ b/src/QGlib/object.cpp
@@ -11,7 +11,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/src/QGlib/object.h b/src/QGlib/object.h
index 357c74b..8c723d0 100644
--- a/src/QGlib/object.h
+++ b/src/QGlib/object.h
@@ -11,7 +11,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/src/QGlib/paramspec.cpp b/src/QGlib/paramspec.cpp
index 63dc0f3..58ad673 100644
--- a/src/QGlib/paramspec.cpp
+++ b/src/QGlib/paramspec.cpp
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/src/QGlib/paramspec.h b/src/QGlib/paramspec.h
index c1a2980..8754f6c 100644
--- a/src/QGlib/paramspec.h
+++ b/src/QGlib/paramspec.h
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/src/QGlib/signal.h b/src/QGlib/qglib_signal.h
index fa3b55f..b317897 100644
--- a/src/QGlib/signal.h
+++ b/src/QGlib/qglib_signal.h
@@ -11,7 +11,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -41,7 +41,7 @@
namespace QGlib {
-/*! \headerfile signal.h <QGlib/Signal>
+/*! \headerfile qglib_signal.h <QGlib/Signal>
* \brief Helper class providing introspection of GObject signals
*
* Signals are a generic notification mechanism. Each signal is bound to a
diff --git a/src/QGlib/quark.cpp b/src/QGlib/quark.cpp
index 0398b63..efaa5c5 100644
--- a/src/QGlib/quark.cpp
+++ b/src/QGlib/quark.cpp
@@ -11,7 +11,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/src/QGlib/quark.h b/src/QGlib/quark.h
index 7464ada..f2bb4d4 100644
--- a/src/QGlib/quark.h
+++ b/src/QGlib/quark.h
@@ -11,7 +11,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/src/QGlib/refpointer.h b/src/QGlib/refpointer.h
index 4061731..966c0ba 100644
--- a/src/QGlib/refpointer.h
+++ b/src/QGlib/refpointer.h
@@ -11,7 +11,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/src/QGlib/signal.cpp b/src/QGlib/signal.cpp
index d03a125..db3b5fc 100644
--- a/src/QGlib/signal.cpp
+++ b/src/QGlib/signal.cpp
@@ -11,12 +11,12 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
*/
-#include "signal.h"
+#include "qglib_signal.h"
#include "quark.h"
#include <glib-object.h>
#include <QtCore/QStringList>
diff --git a/src/QGlib/string_p.h b/src/QGlib/string_p.h
index a893c73..3e8fc54 100644
--- a/src/QGlib/string_p.h
+++ b/src/QGlib/string_p.h
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/src/QGlib/type.cpp b/src/QGlib/type.cpp
index 267d6eb..c07fdd1 100644
--- a/src/QGlib/type.cpp
+++ b/src/QGlib/type.cpp
@@ -11,7 +11,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/src/QGlib/type.h b/src/QGlib/type.h
index c087f3b..01d37e5 100644
--- a/src/QGlib/type.h
+++ b/src/QGlib/type.h
@@ -11,7 +11,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/src/QGlib/value.cpp b/src/QGlib/value.cpp
index 61ae03d..932ffad 100644
--- a/src/QGlib/value.cpp
+++ b/src/QGlib/value.cpp
@@ -11,7 +11,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -292,6 +292,16 @@ void Value::registerValueVTable(Type type, const ValueVTable & vtable)
s_dispatcher()->setVTable(type, vtable);
}
+static inline std::string toStdStringHelper(const QString & str)
+{
+#ifndef QT_NO_STL
+ return str.toStdString();
+#else
+ const QByteArray asc = str.toAscii();
+ return std::string(asc.constData(), asc.length());
+#endif
+}
+
void Value::getData(Type dataType, void *data) const
{
if (!isValid()) {
@@ -301,21 +311,21 @@ void Value::getData(Type dataType, void *data) const
if (vtable.get != NULL) {
vtable.get(*this, data);
} else {
- throw Private::UnregisteredTypeException(dataType.name().toStdString());
+ throw Private::UnregisteredTypeException(toStdStringHelper(dataType.name()));
}
} else if (dataType.isValueType() && g_value_type_transformable(type(), dataType)) {
Value v;
v.init(dataType);
if (!g_value_transform(d->value(), v.d->value())) {
- throw Private::TransformationFailedException(type().name().toStdString(),
- dataType.name().toStdString());
+ throw Private::TransformationFailedException(toStdStringHelper(type().name()),
+ toStdStringHelper(dataType.name()));
}
v.getData(dataType, data);
} else {
- throw Private::InvalidTypeException(dataType.name().toStdString(),
- type().name().toStdString());
+ throw Private::InvalidTypeException(toStdStringHelper(dataType.name()),
+ toStdStringHelper(type().name()));
}
}
@@ -328,7 +338,7 @@ void Value::setData(Type dataType, const void *data)
if (vtable.set != NULL) {
vtable.set(*this, data);
} else {
- throw Private::UnregisteredTypeException(dataType.name().toStdString());
+ throw Private::UnregisteredTypeException(toStdStringHelper(dataType.name()));
}
} else if (dataType.isValueType() && g_value_type_transformable(dataType, type())) {
Value v;
@@ -336,12 +346,12 @@ void Value::setData(Type dataType, const void *data)
v.setData(dataType, data);
if (!g_value_transform(v.d->value(), d->value())) {
- throw Private::TransformationFailedException(dataType.name().toStdString(),
- type().name().toStdString());
+ throw Private::TransformationFailedException(toStdStringHelper(dataType.name()),
+ toStdStringHelper(type().name()));
}
} else {
- throw Private::InvalidTypeException(dataType.name().toStdString(),
- type().name().toStdString());
+ throw Private::InvalidTypeException(toStdStringHelper(dataType.name()),
+ toStdStringHelper(type().name()));
}
}
diff --git a/src/QGlib/value.h b/src/QGlib/value.h
index c62e221..6d10736 100644
--- a/src/QGlib/value.h
+++ b/src/QGlib/value.h
@@ -11,7 +11,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -22,6 +22,7 @@
#include "global.h"
#include "type.h"
#include "refpointer.h"
+#include "error.h"
#include <boost/mpl/if.hpp>
#include <boost/type_traits.hpp>
#include <stdexcept>
@@ -222,6 +223,8 @@ public:
/*! Returns the held value as a QString. Equivalent to get<QString>(ok); \sa get() */
inline QString toString(bool *ok = NULL) const { return get<QString>(ok); }
+ /*! Returns the held value as a QGlib::Error. Equivalent to get<QGlib::Error>(ok); \sa get() */
+ inline Error toError(bool *ok = NULL) const { return get<Error>(ok); }
/*! This is a cast operator that gives access to the underlying GValue instance.
* It is provided for convenience, to be able to pass this Value as argument to C
@@ -468,6 +471,24 @@ struct ValueImpl<Value>
}
};
+// -- ValueImpl specialization for Error --
+
+template <>
+struct ValueImpl<Error>
+{
+ static inline Error get(const Value & value)
+ {
+ GError *error = 0;
+ value.getData(GetType<Error>(), &error);
+ return Error::copy(error);
+ }
+
+ static inline void set(Value & value, const Error & data)
+ {
+ value.setData(GetType<Error>(), static_cast<const GError *>(data));
+ }
+};
+
// -- Exceptions thrown from getData/setData --
namespace Private {
diff --git a/src/QGlib/wrap.cpp b/src/QGlib/wrap.cpp
index 73a00a3..39aeabc 100644
--- a/src/QGlib/wrap.cpp
+++ b/src/QGlib/wrap.cpp
@@ -10,7 +10,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -37,7 +37,8 @@ RefCountedObject *constructWrapper(Type instanceType, void *instance)
}
Q_ASSERT_X(false, "QGlib::constructWrapper",
- "No wrapper constructor found for this type. Did you forget to call init()?.");
+ QString(QLatin1String("No wrapper constructor found for this type (") +
+ instanceType.name() + QLatin1String("). Did you forget to call init()?.")).toUtf8());
return cppClass;
}
diff --git a/src/QGlib/wrap.h b/src/QGlib/wrap.h
index 7247db5..7b4e872 100644
--- a/src/QGlib/wrap.h
+++ b/src/QGlib/wrap.h
@@ -10,7 +10,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/src/QGst/Allocator b/src/QGst/Allocator
new file mode 100644
index 0000000..30c4efa
--- /dev/null
+++ b/src/QGst/Allocator
@@ -0,0 +1 @@
+#include "allocator.h"
diff --git a/src/QGst/CMakeLists.txt b/src/QGst/CMakeLists.txt
index 0bcae17..901ff03 100644
--- a/src/QGst/CMakeLists.txt
+++ b/src/QGst/CMakeLists.txt
@@ -19,22 +19,35 @@ set(QtGStreamer_SRCS
parse.cpp
urihandler.cpp
videoorientation.cpp
- xoverlay.cpp
+ videooverlay.cpp
streamvolume.cpp
colorbalance.cpp
- propertyprobe.cpp
query.cpp
clock.cpp
+ allocator.cpp
+ memory.cpp
buffer.cpp
event.cpp
clocktime.cpp
taglist.cpp
+ sample.cpp
bufferlist.cpp
+ discoverer.cpp
+ segment.cpp
+ device.cpp
+ devicemonitor.cpp
${CMAKE_CURRENT_BINARY_DIR}/gen.cpp
)
+set(QtGStreamerQuick_SRCS
+ Quick/videosurface.cpp
+ Quick/videoitem.cpp
+)
+
set(QtGStreamerUi_SRCS
Ui/videowidget.cpp
+ Ui/graphicsvideosurface.cpp
+ Ui/graphicsvideowidget.cpp
)
set(QtGStreamerUtils_SRCS
@@ -69,86 +82,141 @@ set(QtGStreamer_INSTALLED_HEADERS
parse.h Parse
urihandler.h UriHandler
videoorientation.h VideoOrientation
- xoverlay.h XOverlay
+ videooverlay.h VideoOverlay
streamvolume.h StreamVolume
colorbalance.h ColorBalance
- propertyprobe.h PropertyProbe
query.h Query
clock.h Clock
buffer.h Buffer
+ sample.h Sample
+ allocator.h Allocator
+ memory.h QGstMemory
event.h Event
clocktime.h ClockTime
taglist.h TagList
bufferlist.h BufferList
+ discoverer.h Discoverer
+ segment.h Segment
+ device.h Device
+ devicemonitor.h DeviceMonitor
Ui/global.h
- Ui/videowidget.h Ui/VideoWidget
+ Ui/videowidget.h Ui/VideoWidget
+ Ui/graphicsvideosurface.h Ui/GraphicsVideoSurface
+ Ui/graphicsvideowidget.h Ui/GraphicsVideoWidget
Utils/global.h
Utils/applicationsink.h Utils/ApplicationSink
Utils/applicationsource.h Utils/ApplicationSource
)
+if (Qt4or5_Quick2_FOUND)
+ set(QtGStreamer_INSTALLED_HEADERS
+ ${QtGStreamer_INSTALLED_HEADERS}
+ Quick/global.h
+ Quick/videosurface.h Quick/VideoSurface
+ Quick/videoitem.h Quick/VideoItem
+ )
+endif()
+
file(GLOB QtGStreamer_CODEGEN_HEADERS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "*.h")
list(REMOVE_ITEM QtGStreamer_CODEGEN_HEADERS "global.h")
set(QtGStreamer_CODEGEN_INCLUDES
-Igst/gst.h
- -Igst/interfaces/interfaces-enumtypes.h
- -Igst/interfaces/xoverlay.h
- -Igst/interfaces/streamvolume.h
- -Igst/interfaces/colorbalance.h
- -Igst/interfaces/videoorientation.h
- -Igst/interfaces/propertyprobe.h
+ -Igst/audio/audio-enumtypes.h
+ -Igst/audio/streamvolume.h
+ -Igst/video/video-enumtypes.h
+ -Igst/video/videooverlay.h
+ -Igst/video/colorbalance.h
+ -Igst/video/videoorientation.h
-Igst/app/gstappsrc.h
+ -Igst/pbutils/gstdiscoverer.h
+ -Igst/pbutils/pbutils-enumtypes.h
-IQGlib/Quark
)
# Setup the environment
-set(QTGSTREAMER_API_VERSION 0.10)
+set(QTGSTREAMER_API_VERSION 1.0)
set(QTGSTREAMER_SOVERSION 0)
+set(QTGSTREAMER_QUICK_SOVERSION 0)
set(QTGSTREAMER_UI_SOVERSION 0)
set(QTGSTREAMER_UTILS_SOVERSION 0)
include_directories(
- ${CMAKE_CURRENT_BINARY_DIR}
- ${GSTREAMER_INCLUDE_DIR}
- ${GSTREAMER_INTERFACES_INCLUDE_DIR}
+ ${GSTREAMER_INCLUDE_DIRS}
+ ${GSTREAMER_AUDIO_INCLUDE_DIR}
+ ${GSTREAMER_VIDEO_INCLUDE_DIR}
${GSTREAMER_BASE_INCLUDE_DIR}
${GSTREAMER_APP_INCLUDE_DIR}
+ ${GSTREAMER_PBUTILS_INCLUDE_DIR}
${GLIB2_INCLUDE_DIR}
)
add_definitions(-DGST_DISABLE_XML -DGST_DISABLE_LOADSAVE)
+if (Qt4or5_OpenGL_FOUND AND (OPENGL_FOUND OR OPENGLES2_FOUND))
+ if (OPENGLES2_FOUND)
+ include_directories(${OPENGLES2_INCLUDE_DIR})
+ else()
+ include_directories(${OPENGL_INCLUDE_DIR})
+ endif()
+else()
+ add_definitions(-DQTGSTREAMER_UI_NO_OPENGL)
+endif()
+
# Add command to generate gen.cpp using codegen
run_codegen("QGst" "${QtGStreamer_CODEGEN_INCLUDES}" "${QtGStreamer_CODEGEN_HEADERS}")
# Build and link QtGStreamer
-automoc4_add_library(QtGStreamer ${SHARED_OR_STATIC} ${QtGStreamer_SRCS})
-set_target_properties(QtGStreamer PROPERTIES OUTPUT_NAME QtGStreamer-${QTGSTREAMER_API_VERSION}
+add_library(${QTGSTREAMER_LIBRARY} ${SHARED_OR_STATIC} ${QtGStreamer_SRCS})
+set_target_properties(${QTGSTREAMER_LIBRARY} PROPERTIES OUTPUT_NAME ${QTGSTREAMER_LIBRARY}-${QTGSTREAMER_API_VERSION}
SOVERSION ${QTGSTREAMER_SOVERSION}
VERSION ${QTGSTREAMER_VERSION})
-target_link_libraries(QtGStreamer ${QTGLIB_LIBRARY} ${GOBJECT_LIBRARIES}
- ${GSTREAMER_LIBRARY} ${GSTREAMER_INTERFACES_LIBRARY})
-target_link_libraries(QtGStreamer LINK_INTERFACE_LIBRARIES ${QTGLIB_LIBRARY})
+target_link_libraries(${QTGSTREAMER_LIBRARY} LINK_PUBLIC ${QTGLIB_LIBRARY})
+target_link_libraries(${QTGSTREAMER_LIBRARY} LINK_PRIVATE ${GOBJECT_LIBRARIES}
+ ${GSTREAMER_LIBRARY}
+ ${GSTREAMER_AUDIO_LIBRARY}
+ ${GSTREAMER_VIDEO_LIBRARY}
+ ${GSTREAMER_PBUTILS_LIBRARY})
+qt4or5_use_modules(${QTGSTREAMER_LIBRARY} LINK_PUBLIC Core)
+
+# Build and link QtGStreamerQuick
+if (Qt4or5_Quick2_FOUND)
+ add_library(${QTGSTREAMER_QUICK_LIBRARY} ${SHARED_OR_STATIC} ${QtGStreamerQuick_SRCS})
+ set_target_properties(${QTGSTREAMER_QUICK_LIBRARY} PROPERTIES OUTPUT_NAME ${QTGSTREAMER_QUICK_LIBRARY}-${QTGSTREAMER_API_VERSION}
+ SOVERSION ${QTGSTREAMER_QUICK_SOVERSION}
+ VERSION ${QTGSTREAMER_VERSION})
+ target_link_libraries(${QTGSTREAMER_QUICK_LIBRARY} LINK_PUBLIC ${QTGSTREAMER_LIBRARY})
+ qt4or5_use_modules(${QTGSTREAMER_QUICK_LIBRARY} LINK_PUBLIC Quick2)
+ qt4or5_use_modules(${QTGSTREAMER_QUICK_LIBRARY} LINK_PRIVATE Core)
+endif()
# Build and link QtGStreamerUi
-automoc4_add_library(QtGStreamerUi ${SHARED_OR_STATIC} ${QtGStreamerUi_SRCS})
-set_target_properties(QtGStreamerUi PROPERTIES OUTPUT_NAME QtGStreamerUi-${QTGSTREAMER_API_VERSION}
+add_library(${QTGSTREAMER_UI_LIBRARY} ${SHARED_OR_STATIC} ${QtGStreamerUi_SRCS})
+set_target_properties(${QTGSTREAMER_UI_LIBRARY} PROPERTIES OUTPUT_NAME ${QTGSTREAMER_UI_LIBRARY}-${QTGSTREAMER_API_VERSION}
SOVERSION ${QTGSTREAMER_UI_SOVERSION}
VERSION ${QTGSTREAMER_VERSION})
-target_link_libraries(QtGStreamerUi ${QT_QTGUI_LIBRARY} ${QTGSTREAMER_LIBRARY})
+target_link_libraries(${QTGSTREAMER_UI_LIBRARY} LINK_PUBLIC ${QTGSTREAMER_LIBRARY})
+qt4or5_use_modules(${QTGSTREAMER_UI_LIBRARY} LINK_PUBLIC Widgets Gui)
+qt4or5_use_modules(${QTGSTREAMER_UI_LIBRARY} LINK_PRIVATE Core)
+if (Qt4or5_OpenGL_FOUND AND (OPENGL_FOUND OR OPENGLES2_FOUND))
+ qt4or5_use_modules(${QTGSTREAMER_UI_LIBRARY} LINK_PRIVATE OpenGL)
+endif()
# Build and link QtGStreamerUtils
-automoc4_add_library(QtGStreamerUtils ${SHARED_OR_STATIC} ${QtGStreamerUtils_SRCS})
-set_target_properties(QtGStreamerUtils PROPERTIES OUTPUT_NAME QtGStreamerUtils-${QTGSTREAMER_API_VERSION}
+add_library(${QTGSTREAMER_UTILS_LIBRARY} ${SHARED_OR_STATIC} ${QtGStreamerUtils_SRCS})
+set_target_properties(${QTGSTREAMER_UTILS_LIBRARY} PROPERTIES OUTPUT_NAME ${QTGSTREAMER_UTILS_LIBRARY}-${QTGSTREAMER_API_VERSION}
SOVERSION ${QTGSTREAMER_UTILS_SOVERSION}
VERSION ${QTGSTREAMER_VERSION})
-target_link_libraries(QtGStreamerUtils ${QTGSTREAMER_LIBRARY} ${GSTREAMER_LIBRARY} ${GSTREAMER_APP_LIBRARY})
-target_link_libraries(QtGStreamerUtils LINK_INTERFACE_LIBRARIES ${QTGSTREAMER_LIBRARY})
+target_link_libraries(${QTGSTREAMER_UTILS_LIBRARY} LINK_PUBLIC ${QTGSTREAMER_LIBRARY})
+target_link_libraries(${QTGSTREAMER_UTILS_LIBRARY} LINK_PRIVATE ${GSTREAMER_LIBRARY} ${GSTREAMER_APP_LIBRARY})
+qt4or5_use_modules(${QTGSTREAMER_UTILS_LIBRARY} LINK_PRIVATE Core)
# Install
-install(TARGETS QtGStreamer DESTINATION ${LIB_INSTALL_DIR} EXPORT ${EXPORT_TARGET_SET})
-install(TARGETS QtGStreamerUi DESTINATION ${LIB_INSTALL_DIR} EXPORT ${EXPORT_TARGET_SET})
-install(TARGETS QtGStreamerUtils DESTINATION ${LIB_INSTALL_DIR} EXPORT ${EXPORT_TARGET_SET})
+install(TARGETS ${QTGSTREAMER_LIBRARY} EXPORT ${EXPORT_TARGET_SET} ${QTGSTREAMER_INSTALL_TARGET_DEFAULT_ARGS})
+if (Qt4or5_Quick2_FOUND)
+ install(TARGETS ${QTGSTREAMER_QUICK_LIBRARY} EXPORT ${EXPORT_TARGET_SET} ${QTGSTREAMER_INSTALL_TARGET_DEFAULT_ARGS})
+endif()
+install(TARGETS ${QTGSTREAMER_UI_LIBRARY} EXPORT ${EXPORT_TARGET_SET} ${QTGSTREAMER_INSTALL_TARGET_DEFAULT_ARGS})
+install(TARGETS ${QTGSTREAMER_UTILS_LIBRARY} EXPORT ${EXPORT_TARGET_SET} ${QTGSTREAMER_INSTALL_TARGET_DEFAULT_ARGS})
install_headers("QGst" ${QtGStreamer_INSTALLED_HEADERS})
diff --git a/src/QGst/Device b/src/QGst/Device
new file mode 100644
index 0000000..155c911
--- /dev/null
+++ b/src/QGst/Device
@@ -0,0 +1 @@
+#include "device.h"
diff --git a/src/QGst/DeviceMonitor b/src/QGst/DeviceMonitor
new file mode 100644
index 0000000..ce319e6
--- /dev/null
+++ b/src/QGst/DeviceMonitor
@@ -0,0 +1 @@
+#include "devicemonitor.h"
diff --git a/src/QGst/Discoverer b/src/QGst/Discoverer
new file mode 100644
index 0000000..57b0414
--- /dev/null
+++ b/src/QGst/Discoverer
@@ -0,0 +1 @@
+#include "discoverer.h"
diff --git a/src/QGst/PropertyProbe b/src/QGst/PropertyProbe
deleted file mode 100644
index 1677dca..0000000
--- a/src/QGst/PropertyProbe
+++ /dev/null
@@ -1 +0,0 @@
-#include "propertyprobe.h"
diff --git a/src/QGst/QGstMemory b/src/QGst/QGstMemory
new file mode 100644
index 0000000..b31569d
--- /dev/null
+++ b/src/QGst/QGstMemory
@@ -0,0 +1 @@
+#include "memory.h"
diff --git a/src/QGst/QtGStreamer-0.10.pc.in b/src/QGst/QtGStreamer-0.10.pc.in
deleted file mode 100644
index 9e783cd..0000000
--- a/src/QGst/QtGStreamer-0.10.pc.in
+++ /dev/null
@@ -1,12 +0,0 @@
-prefix=@CMAKE_INSTALL_PREFIX@
-exec_prefix=${prefix}
-libdir=@LIB_INSTALL_DIR@
-includedir=@INCLUDES_INSTALL_DIR@
-
-Name: QtGStreamer-0.10
-Description: Qt-style C++ bindings library for GStreamer
-Requires: QtGLib-2.0
-Requires.private: gstreamer-0.10 gstreamer-interfaces-0.10 gobject-2.0
-Version: @QTGSTREAMER_VERSION@
-Cflags: -I${includedir}
-Libs: -L${libdir} -lQtGStreamer-0.10
diff --git a/src/QGst/QtGStreamer-1.0.pc.in b/src/QGst/QtGStreamer-1.0.pc.in
new file mode 100644
index 0000000..d6fabc6
--- /dev/null
+++ b/src/QGst/QtGStreamer-1.0.pc.in
@@ -0,0 +1,12 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=${prefix}
+libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
+includedir=${prefix}/@QTGSTREAMER_INCLUDES_INSTALL_DIR@
+
+Name: @QTGSTREAMER_LIBRARY@-1.0
+Description: Qt-style C++ bindings library for GStreamer
+Requires: @QTGLIB_LIBRARY@-2.0
+Requires.private: gstreamer-1.0 gstreamer-audio-1.0 gstreamer-video-1.0 gstreamer-pbutils-1.0 gobject-2.0
+Version: @QTGSTREAMER_VERSION@
+Cflags: -I${includedir}
+Libs: -L${libdir} -l@QTGSTREAMER_LIBRARY@-1.0
diff --git a/src/QGst/QtGStreamerQuick-1.0.pc.in b/src/QGst/QtGStreamerQuick-1.0.pc.in
new file mode 100644
index 0000000..21ca0ec
--- /dev/null
+++ b/src/QGst/QtGStreamerQuick-1.0.pc.in
@@ -0,0 +1,11 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=${prefix}
+libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
+includedir=${prefix}/@QTGSTREAMER_INCLUDES_INSTALL_DIR@
+
+Name: @QTGSTREAMER_QUICK_LIBRARY@-1.0
+Description: QtQuick GStreamer integration library
+Requires: @Qt4or5_Quick2_PKGCONFIG_DEP@ @QTGSTREAMER_LIBRARY@-1.0
+Version: @QTGSTREAMER_VERSION@
+Cflags: -I${includedir}
+Libs: -L${libdir} -l@QTGSTREAMER_QUICK_LIBRARY@-1.0
diff --git a/src/QGst/QtGStreamerUi-0.10.pc.in b/src/QGst/QtGStreamerUi-0.10.pc.in
deleted file mode 100644
index 04d3fd5..0000000
--- a/src/QGst/QtGStreamerUi-0.10.pc.in
+++ /dev/null
@@ -1,11 +0,0 @@
-prefix=@CMAKE_INSTALL_PREFIX@
-exec_prefix=${prefix}
-libdir=@LIB_INSTALL_DIR@
-includedir=@INCLUDES_INSTALL_DIR@
-
-Name: QtGStreamerUi-0.10
-Description: QtGui GStreamer integration library
-Requires: QtGui QtGStreamer-0.10
-Version: @QTGSTREAMER_VERSION@
-Cflags: -I${includedir}
-Libs: -L${libdir} -lQtGStreamerUi-0.10
diff --git a/src/QGst/QtGStreamerUi-1.0.pc.in b/src/QGst/QtGStreamerUi-1.0.pc.in
new file mode 100644
index 0000000..fb62189
--- /dev/null
+++ b/src/QGst/QtGStreamerUi-1.0.pc.in
@@ -0,0 +1,11 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=${prefix}
+libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
+includedir=${prefix}/@QTGSTREAMER_INCLUDES_INSTALL_DIR@
+
+Name: @QTGSTREAMER_UI_LIBRARY@-1.0
+Description: QtGui/QtWidgets GStreamer integration library
+Requires: @Qt4or5_Widgets_PKGCONFIG_DEP@ @QTGSTREAMER_LIBRARY@-1.0
+Version: @QTGSTREAMER_VERSION@
+Cflags: -I${includedir}
+Libs: -L${libdir} -l@QTGSTREAMER_UI_LIBRARY@-1.0
diff --git a/src/QGst/QtGStreamerUtils-0.10.pc.in b/src/QGst/QtGStreamerUtils-0.10.pc.in
deleted file mode 100644
index 2254a38..0000000
--- a/src/QGst/QtGStreamerUtils-0.10.pc.in
+++ /dev/null
@@ -1,12 +0,0 @@
-prefix=@CMAKE_INSTALL_PREFIX@
-exec_prefix=${prefix}
-libdir=@LIB_INSTALL_DIR@
-includedir=@INCLUDES_INSTALL_DIR@
-
-Name: QtGStreamerUtils-0.10
-Description: QtGStreamer's high level utility classes
-Requires: QtGStreamer-0.10
-Requires.private: gstreamer-0.10 gstreamer-app-0.10
-Version: @QTGSTREAMER_VERSION@
-Cflags: -I${includedir}
-Libs: -L${libdir} -lQtGStreamerUtils-0.10
diff --git a/src/QGst/QtGStreamerUtils-1.0.pc.in b/src/QGst/QtGStreamerUtils-1.0.pc.in
new file mode 100644
index 0000000..96965ee
--- /dev/null
+++ b/src/QGst/QtGStreamerUtils-1.0.pc.in
@@ -0,0 +1,12 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=${prefix}
+libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
+includedir=${prefix}/@QTGSTREAMER_INCLUDES_INSTALL_DIR@
+
+Name: @QTGSTREAMER_UTILS_LIBRARY@-1.0
+Description: QtGStreamer's high level utility classes
+Requires: @QTGSTREAMER_LIBRARY@-1.0
+Requires.private: gstreamer-1.0 gstreamer-app-1.0
+Version: @QTGSTREAMER_VERSION@
+Cflags: -I${includedir}
+Libs: -L${libdir} -l@QTGSTREAMER_UTILS_LIBRARY@-1.0
diff --git a/src/QGst/Quick/VideoItem b/src/QGst/Quick/VideoItem
new file mode 100644
index 0000000..8082d8d
--- /dev/null
+++ b/src/QGst/Quick/VideoItem
@@ -0,0 +1 @@
+#include "videoitem.h" \ No newline at end of file
diff --git a/src/QGst/Quick/VideoSurface b/src/QGst/Quick/VideoSurface
new file mode 100644
index 0000000..ebfe51f
--- /dev/null
+++ b/src/QGst/Quick/VideoSurface
@@ -0,0 +1 @@
+#include "videosurface.h"
diff --git a/src/QGst/Quick/global.h b/src/QGst/Quick/global.h
new file mode 100644
index 0000000..132804e
--- /dev/null
+++ b/src/QGst/Quick/global.h
@@ -0,0 +1,42 @@
+/*
+ Copyright (C) 2011-2013 Collabora Ltd.
+ @author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#ifndef QTGSTREAMERQUICK_EXPORT_H
+#define QTGSTREAMERQUICK_EXPORT_H
+
+// workaround for https://bugreports.qt-project.org/browse/QTBUG-22829
+#if defined(Q_MOC_RUN) && !defined(BOOST_TT_HAS_OPERATOR_HPP_INCLUDED)
+#define BOOST_TT_HAS_OPERATOR_HPP_INCLUDED
+#endif
+
+#include <QtCore/QtGlobal>
+
+/* defined by cmake when building this library */
+#if defined(QtGStreamerQuick_EXPORTS) || defined(Qt5GStreamerQuick_EXPORTS)
+# define QTGSTREAMERQUICK_EXPORT Q_DECL_EXPORT
+#else
+# define QTGSTREAMERQUICK_EXPORT Q_DECL_IMPORT
+#endif
+
+#if !defined(Q_OS_WIN) && !defined(Q_CC_NOKIAX86) && \
+ !defined(Q_CC_RVCT) && defined(QT_VISIBILITY_AVAILABLE)
+# define QTGSTREAMERQUICK_NO_EXPORT __attribute__((visibility("hidden")))
+#else
+# define QTGSTREAMERQUICK_NO_EXPORT
+#endif
+
+#endif
diff --git a/src/QGst/Quick/videoitem.cpp b/src/QGst/Quick/videoitem.cpp
new file mode 100644
index 0000000..f03de4f
--- /dev/null
+++ b/src/QGst/Quick/videoitem.cpp
@@ -0,0 +1,118 @@
+/*
+ Copyright (C) 2012-2013 Collabora Ltd. <info@collabora.com>
+ @author George Kiagiadakis <george.kiagiadakis@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "videoitem.h"
+#include "videosurface_p.h"
+#include <QtQuick/QSGNode>
+#include <QtQuick/QSGFlatColorMaterial>
+#include "../../QGlib/Signal"
+
+namespace QGst {
+namespace Quick {
+
+struct VideoItem::Private
+{
+ QPointer<VideoSurface> surface;
+ bool surfaceDirty;
+ QRectF targetArea;
+};
+
+VideoItem::VideoItem(QQuickItem *parent)
+ : QQuickItem(parent), d(new Private)
+{
+ d->surfaceDirty = true;
+ setFlag(QQuickItem::ItemHasContents, true);
+}
+
+VideoItem::~VideoItem()
+{
+ setSurface(0);
+ delete d;
+}
+
+VideoSurface *VideoItem::surface() const
+{
+ return d->surface.data();
+}
+
+void VideoItem::setSurface(VideoSurface *surface)
+{
+ if (d->surface) {
+ d->surface.data()->d->items.remove(this);
+ }
+
+ d->surface = surface;
+ d->surfaceDirty = true;
+
+ if (d->surface) {
+ d->surface.data()->d->items.insert(this);
+ }
+}
+
+QSGNode* VideoItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
+{
+ Q_UNUSED(data)
+
+ QRectF r = boundingRect();
+ QSGNode *newNode = 0;
+
+ if (d->surfaceDirty) {
+ delete oldNode;
+ oldNode = 0;
+ d->surfaceDirty = false;
+ }
+
+ if (!d->surface || d->surface.data()->d->videoSink.isNull()) {
+ 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;
+ d->targetArea = QRectF(); //force geometry to be set
+ } else {
+ newNode = oldNode;
+ }
+
+ if (r != d->targetArea) {
+ QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 4);
+ geometry->vertexDataAsPoint2D()[0].set(r.x(), r.y());
+ geometry->vertexDataAsPoint2D()[1].set(r.x(), r.height());
+ geometry->vertexDataAsPoint2D()[2].set(r.width(), r.y());
+ geometry->vertexDataAsPoint2D()[3].set(r.width(), r.height());
+
+ QSGGeometryNode *node = static_cast<QSGGeometryNode*>(newNode);
+ node->setGeometry(geometry);
+
+ d->targetArea = r;
+ }
+ } else {
+ newNode = (QSGNode*) QGlib::emit<void*>(d->surface.data()->d->videoSink,
+ "update-node", (void*)oldNode,
+ r.x(), r.y(), r.width(), r.height());
+ }
+
+ return newNode;
+}
+
+} // namespace Quick
+} // namespace QGst
diff --git a/src/QGst/Quick/videoitem.h b/src/QGst/Quick/videoitem.h
new file mode 100644
index 0000000..be408d2
--- /dev/null
+++ b/src/QGst/Quick/videoitem.h
@@ -0,0 +1,65 @@
+/*
+ Copyright (C) 2012-2013 Collabora Ltd. <info@collabora.com>
+ @author George Kiagiadakis <george.kiagiadakis@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef QGST_QUICK_VIDEOITEM_H
+#define QGST_QUICK_VIDEOITEM_H
+
+#include "videosurface.h"
+#include <QtQuick/QQuickItem>
+#include <QtCore/QPointer>
+
+namespace QGst {
+namespace Quick {
+
+/*! \headerfile videoitem.h <QGst/Quick/VideoItem>
+ * \brief A QQuickItem for displaying video
+ *
+ * This is a QQuickItem subclass that can display video. To use it,
+ * you have to create a VideoSurface and connect it with this
+ * item using the setSurface() method or the surface property.
+ * See the VideoSurface documentation for details and examples.
+ *
+ * \sa VideoSurface
+ */
+class QTGSTREAMERQUICK_EXPORT VideoItem : public QQuickItem
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(VideoItem)
+ Q_PROPERTY(QGst::Quick::VideoSurface* surface READ surface WRITE setSurface)
+
+public:
+ explicit VideoItem(QQuickItem *parent = 0);
+ virtual ~VideoItem();
+
+ VideoSurface *surface() const;
+ void setSurface(VideoSurface *surface);
+
+protected:
+ /*! Reimplemented from QQuickItem. */
+ virtual QSGNode* updatePaintNode(QSGNode *oldNode,
+ UpdatePaintNodeData *updatePaintNodeData);
+
+private:
+ struct Private;
+ Private *const d;
+};
+
+} // namespace Quick
+} // namespace QGst
+
+#endif // QGST_QUICK_VIDEOITEM_H
diff --git a/src/QGst/Quick/videosurface.cpp b/src/QGst/Quick/videosurface.cpp
new file mode 100644
index 0000000..c99e578
--- /dev/null
+++ b/src/QGst/Quick/videosurface.cpp
@@ -0,0 +1,70 @@
+/*
+ Copyright (C) 2012-2013 Collabora Ltd. <info@collabora.com>
+ @author George Kiagiadakis <george.kiagiadakis@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#include "videosurface_p.h"
+
+#include "../elementfactory.h"
+#include "../../QGlib/connect.h"
+
+#include <QtCore/QDebug>
+#include <QtQuick/QQuickItem>
+
+namespace QGst {
+namespace Quick {
+
+VideoSurface::VideoSurface(QObject *parent)
+ : QObject(parent), d(new VideoSurfacePrivate)
+{
+}
+
+VideoSurface::~VideoSurface()
+{
+ if (!d->videoSink.isNull()) {
+ d->videoSink->setState(QGst::StateNull);
+ }
+
+ delete d;
+}
+
+ElementPtr VideoSurface::videoSink() const
+{
+ if (d->videoSink.isNull()) {
+ d->videoSink = QGst::ElementFactory::make("qtquick2videosink");
+
+ if (d->videoSink.isNull()) {
+ qCritical("Failed to create qtquick2videosink. Make sure it is installed correctly");
+ return ElementPtr();
+ }
+
+ QGlib::connect(d->videoSink, "update",
+ const_cast<VideoSurface*>(this),
+ &VideoSurface::onUpdate);
+
+ }
+
+ return d->videoSink;
+}
+
+void VideoSurface::onUpdate()
+{
+ Q_FOREACH(QQuickItem *item, d->items) {
+ item->update();
+ }
+}
+
+} // namespace Quick
+} // namespace QGst
diff --git a/src/QGst/Quick/videosurface.h b/src/QGst/Quick/videosurface.h
new file mode 100644
index 0000000..ef08015
--- /dev/null
+++ b/src/QGst/Quick/videosurface.h
@@ -0,0 +1,84 @@
+/*
+ Copyright (C) 2012-2013 Collabora Ltd. <info@collabora.com>
+ @author George Kiagiadakis <george.kiagiadakis@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#ifndef QGST_QUICK_VIDEOSURFACE_H
+#define QGST_QUICK_VIDEOSURFACE_H
+
+#include "global.h"
+#include "../element.h"
+#include <QtCore/QObject>
+
+namespace QGst {
+namespace Quick {
+
+class VideoSurfacePrivate;
+
+/*! \headerfile videosurface.h <QGst/Quick/VideoSurface>
+ * \brief Helper class for painting video on a QtQuick2 VideoItem
+ *
+ * This is a helper class that represents a video surface on a QQuickView.
+ * To use it, create a VideoItem from QML and connect it with this surface.
+ *
+ * Example:
+ * \code
+ * // in your C++ code
+ * QQuickView *view = new QQuickView;
+ * ...
+ * QGst::Quick::VideoSurface *surface = new QGst::Quick::VideoSurface;
+ * view->rootContext()->setContextProperty(QLatin1String("videoSurface"), surface);
+ * ...
+ * // and in your qml file:
+ * import QtGStreamer 1.0
+ * ...
+ * VideoItem {
+ * id: video
+ * width: 320
+ * height: 240
+ * surface: videoSurface
+ * }
+ * \endcode
+ *
+ * \sa VideoItem
+ */
+class QTGSTREAMERQUICK_EXPORT 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.
+ */
+ ElementPtr videoSink() const;
+
+protected:
+ QTGSTREAMERQUICK_NO_EXPORT void onUpdate();
+
+private:
+ friend class VideoItem;
+ VideoSurfacePrivate * const d;
+};
+
+} // namespace Quick
+} // namespace QGst
+
+Q_DECLARE_METATYPE(QGst::Quick::VideoSurface*)
+
+#endif // QGST_QUICK_VIDEOSURFACE_H
diff --git a/src/QGst/Quick/videosurface_p.h b/src/QGst/Quick/videosurface_p.h
new file mode 100644
index 0000000..6f74bce
--- /dev/null
+++ b/src/QGst/Quick/videosurface_p.h
@@ -0,0 +1,37 @@
+/*
+ Copyright (C) 2012-2013 Collabora Ltd. <info@collabora.com>
+ @author George Kiagiadakis <george.kiagiadakis@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#ifndef QGST_QUICK_VIDEOSURFACE_P_H
+#define QGST_QUICK_VIDEOSURFACE_P_H
+
+#include "videosurface.h"
+#include "videoitem.h"
+
+namespace QGst {
+namespace Quick {
+
+class QTGSTREAMERQUICK_NO_EXPORT VideoSurfacePrivate
+{
+public:
+ QSet<VideoItem*> items;
+ ElementPtr videoSink;
+};
+
+} // namespace Quick
+} // namespace QGst
+
+#endif // QGST_QUICK_VIDEOSURFACE_P_H
diff --git a/src/QGst/Sample b/src/QGst/Sample
new file mode 100644
index 0000000..a6a6ab8
--- /dev/null
+++ b/src/QGst/Sample
@@ -0,0 +1 @@
+#include "sample.h"
diff --git a/src/QGst/Segment b/src/QGst/Segment
new file mode 100644
index 0000000..9689573
--- /dev/null
+++ b/src/QGst/Segment
@@ -0,0 +1 @@
+#include "segment.h"
diff --git a/src/QGst/Ui/GraphicsVideoSurface b/src/QGst/Ui/GraphicsVideoSurface
new file mode 100644
index 0000000..b28203c
--- /dev/null
+++ b/src/QGst/Ui/GraphicsVideoSurface
@@ -0,0 +1 @@
+#include "graphicsvideosurface.h"
diff --git a/src/QGst/Ui/GraphicsVideoWidget b/src/QGst/Ui/GraphicsVideoWidget
new file mode 100644
index 0000000..81379db
--- /dev/null
+++ b/src/QGst/Ui/GraphicsVideoWidget
@@ -0,0 +1 @@
+#include "graphicsvideowidget.h"
diff --git a/src/QGst/Ui/global.h b/src/QGst/Ui/global.h
index cba1806..7912b73 100644
--- a/src/QGst/Ui/global.h
+++ b/src/QGst/Ui/global.h
@@ -10,7 +10,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -18,10 +18,15 @@
#ifndef QTGSTREAMERUI_EXPORT_H
#define QTGSTREAMERUI_EXPORT_H
+// workaround for https://bugreports.qt-project.org/browse/QTBUG-22829
+#if defined(Q_MOC_RUN) && !defined(BOOST_TT_HAS_OPERATOR_HPP_INCLUDED)
+#define BOOST_TT_HAS_OPERATOR_HPP_INCLUDED
+#endif
+
#include <QtCore/QtGlobal>
/* defined by cmake when building this library */
-#if defined(QtGStreamerUi_EXPORTS)
+#if defined(QtGStreamerUi_EXPORTS) || defined(Qt5GStreamerUi_EXPORTS)
# define QTGSTREAMERUI_EXPORT Q_DECL_EXPORT
#else
# define QTGSTREAMERUI_EXPORT Q_DECL_IMPORT
diff --git a/src/QGst/Ui/graphicsvideosurface.cpp b/src/QGst/Ui/graphicsvideosurface.cpp
new file mode 100644
index 0000000..74b2d97
--- /dev/null
+++ b/src/QGst/Ui/graphicsvideosurface.cpp
@@ -0,0 +1,90 @@
+/*
+ Copyright (C) 2012 Collabora Ltd. <info@collabora.com>
+ @author George Kiagiadakis <george.kiagiadakis@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#include "graphicsvideosurface_p.h"
+#include "../elementfactory.h"
+#include "../../QGlib/connect.h"
+
+#ifndef QTGSTREAMER_UI_NO_OPENGL
+# include <QtOpenGL/QGLWidget>
+#endif
+
+namespace QGst {
+namespace Ui {
+
+GraphicsVideoSurface::GraphicsVideoSurface(QGraphicsView *parent)
+ : QObject(parent), d(new GraphicsVideoSurfacePrivate)
+{
+ d->view = parent;
+}
+
+GraphicsVideoSurface::~GraphicsVideoSurface()
+{
+ if (!d->videoSink.isNull()) {
+ d->videoSink->setState(QGst::StateNull);
+ }
+
+ delete d;
+}
+
+ElementPtr GraphicsVideoSurface::videoSink() const
+{
+ if (d->videoSink.isNull()) {
+#ifndef QTGSTREAMER_UI_NO_OPENGL
+ //if the viewport is a QGLWidget, profit from it
+ QGLWidget *glw = qobject_cast<QGLWidget*>(d->view->viewport());
+ if (glw) {
+ d->videoSink = QGst::ElementFactory::make(QTGLVIDEOSINK_NAME);
+
+ if (!d->videoSink.isNull()) {
+ glw->makeCurrent();
+ d->videoSink->setProperty("glcontext", (void*) QGLContext::currentContext());
+ glw->doneCurrent();
+
+ if (d->videoSink->setState(QGst::StateReady) != QGst::StateChangeSuccess) {
+ d->videoSink.clear();
+ }
+ }
+ }
+#endif
+
+ if (d->videoSink.isNull()) {
+ d->videoSink = QGst::ElementFactory::make(QTVIDEOSINK_NAME);
+
+ if (d->videoSink.isNull()) {
+ qCritical("Failed to create qtvideosink. Make sure it is installed correctly");
+ return ElementPtr();
+ }
+ }
+
+ QGlib::connect(d->videoSink, "update",
+ const_cast<GraphicsVideoSurface*>(this),
+ &GraphicsVideoSurface::onUpdate);
+ }
+
+ return d->videoSink;
+}
+
+void GraphicsVideoSurface::onUpdate()
+{
+ Q_FOREACH(GraphicsVideoWidget *item, d->items) {
+ item->update(item->rect());
+ }
+}
+
+} // namespace Ui
+} // namespace QGst
diff --git a/src/QGst/Ui/graphicsvideosurface.h b/src/QGst/Ui/graphicsvideosurface.h
new file mode 100644
index 0000000..48d8db6
--- /dev/null
+++ b/src/QGst/Ui/graphicsvideosurface.h
@@ -0,0 +1,118 @@
+/*
+ Copyright (C) 2012 Collabora Ltd. <info@collabora.com>
+ @author George Kiagiadakis <george.kiagiadakis@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#ifndef QGST_UI_GRAPHICSVIDEOSURFACE_H
+#define QGST_UI_GRAPHICSVIDEOSURFACE_H
+
+#include "global.h"
+#include "../element.h"
+
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
+# include <QtWidgets/QGraphicsView>
+#else
+# include <QtGui/QGraphicsView>
+#endif
+
+namespace QGst {
+namespace Ui {
+
+class GraphicsVideoWidget;
+class GraphicsVideoSurfacePrivate;
+
+/*! \headerfile graphicsvideosurface.h <QGst/Ui/GraphicsVideoSurface>
+ * \brief Helper class for painting video on a QGraphicsView
+ *
+ * This is a helper class that represents a video surface on a QGraphicsView.
+ * This is not a QGraphicsItem, though, it is just a helper class to bind
+ * the video sink to a specific view. To use it, create a GraphicsVideoWidget,
+ * add it to your scene and connect it with this surface.
+ *
+ * Example
+ * \code
+ * QGraphicsScene *scene = new QGraphicsScene;
+ * QGraphicsView *view = new QGraphicsView (scene);
+ * view->setViewport(new QGLWidget); //recommended
+ * QGst::Ui::GraphicsVideoSurface *surface = new QGst::Ui::GraphicsVideoSurface(view);
+ * ...
+ * QGst::Ui::GraphicsVideoWidget *widget = new QGst::Ui::GraphicsVideoWidget;
+ * widget->setSurface(surface);
+ * scene->addItem(widget);
+ * \endcode
+ *
+ * This class internally creates and uses either a "qtglvideosink" or a "qtvideosink"
+ * element ("qt5glvideosink" / "qt5videosink" in Qt5). This element is created the
+ * first time it is requested and a reference is kept internally.
+ *
+ * To make use of OpenGL hardware acceleration (using qtglvideosink), you need to set
+ * a QGLWidget as the viewport of the QGraphicsView. Note that you must do this before
+ * the video sink element is requested for the first time using the videoSink() method,
+ * as this method needs to find a GL context to be able to construct qtglvideosink and
+ * query the hardware about supported features. Using OpenGL acceleration is recommended.
+ * If you don't use it, painting will be done in software with QImage and QPainter
+ * (using qtvideosink).
+ *
+ * This class can also be used to paint video on QML.
+ *
+ * Example:
+ * \code
+ * // in your C++ code
+ * QDeclarativeView *view = new QDeclarativeView;
+ * view->setViewport(new QGLWidget); //recommended
+ * QGst::Ui::GraphicsVideoSurface *surface = new QGst::Ui::GraphicsVideoSurface(view);
+ * view->rootContext()->setContextProperty(QLatin1String("videoSurface"), surface);
+ * ...
+ * // and in your qml file:
+ * import QtGStreamer 1.0
+ * ...
+ * VideoItem {
+ * id: video
+ * width: 320
+ * height: 240
+ * surface: videoSurface
+ * }
+ * \endcode
+ *
+ * \sa GraphicsVideoWidget
+ */
+class QTGSTREAMERUI_EXPORT GraphicsVideoSurface : public QObject
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(GraphicsVideoSurface)
+public:
+ explicit GraphicsVideoSurface(QGraphicsView *parent);
+ virtual ~GraphicsVideoSurface();
+
+ /*! 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.
+ */
+ ElementPtr videoSink() const;
+
+private:
+ QTGSTREAMERUI_NO_EXPORT void onUpdate();
+
+private:
+ friend class GraphicsVideoWidget;
+ GraphicsVideoSurfacePrivate * const d;
+};
+
+} // namespace Ui
+} // namespace QGst
+
+Q_DECLARE_METATYPE(QGst::Ui::GraphicsVideoSurface*)
+
+#endif // QGST_UI_GRAPHICSVIDEOSURFACE_H
diff --git a/src/QGst/Ui/graphicsvideosurface_p.h b/src/QGst/Ui/graphicsvideosurface_p.h
new file mode 100644
index 0000000..3c8cede
--- /dev/null
+++ b/src/QGst/Ui/graphicsvideosurface_p.h
@@ -0,0 +1,38 @@
+/*
+ Copyright (C) 2012 Collabora Ltd. <info@collabora.com>
+ @author George Kiagiadakis <george.kiagiadakis@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#ifndef QGST_UI_GRAPHICSVIDEOSURFACE_P_H
+#define QGST_UI_GRAPHICSVIDEOSURFACE_P_H
+
+#include "graphicsvideosurface.h"
+#include "graphicsvideowidget.h"
+
+namespace QGst {
+namespace Ui {
+
+class QTGSTREAMERUI_NO_EXPORT GraphicsVideoSurfacePrivate
+{
+public:
+ QGraphicsView *view;
+ QSet<GraphicsVideoWidget*> items;
+ ElementPtr videoSink;
+};
+
+} // namespace Ui
+} // namespace QGst
+
+#endif // QGST_UI_GRAPHICSVIDEOSURFACE_P_H
diff --git a/src/QGst/Ui/graphicsvideowidget.cpp b/src/QGst/Ui/graphicsvideowidget.cpp
new file mode 100644
index 0000000..37f2eea
--- /dev/null
+++ b/src/QGst/Ui/graphicsvideowidget.cpp
@@ -0,0 +1,71 @@
+/*
+ Copyright (C) 2012 Collabora Ltd. <info@collabora.com>
+ @author George Kiagiadakis <george.kiagiadakis@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#include "graphicsvideowidget.h"
+#include "graphicsvideosurface_p.h"
+#include "../../QGlib/Signal"
+
+namespace QGst {
+namespace Ui {
+
+GraphicsVideoWidget::GraphicsVideoWidget(QGraphicsItem *parent, Qt::WindowFlags wFlags)
+ : QGraphicsWidget(parent, wFlags)
+{
+ setFlag(QGraphicsItem::ItemHasNoContents, false);
+}
+
+GraphicsVideoWidget::~GraphicsVideoWidget()
+{
+ setSurface(0);
+}
+
+GraphicsVideoSurface *GraphicsVideoWidget::surface() const
+{
+ return m_surface.data();
+}
+
+void GraphicsVideoWidget::setSurface(GraphicsVideoSurface *surface)
+{
+ if (m_surface) {
+ m_surface.data()->d->items.remove(this);
+ }
+
+ m_surface = surface;
+
+ if (m_surface) {
+ m_surface.data()->d->items.insert(this);
+ }
+}
+
+void GraphicsVideoWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ Q_UNUSED(option);
+
+ QRectF r = rect();
+
+ if (!m_surface || m_surface.data()->d->videoSink.isNull() ||
+ widget != m_surface.data()->d->view->viewport()
+ ) {
+ painter->fillRect(r, Qt::black);
+ } else {
+ QGlib::emit<void>(m_surface.data()->d->videoSink, "paint",
+ (void*)painter, r.x(), r.y(), r.width(), r.height());
+ }
+}
+
+} // namespace Ui
+} // namespace QGst
diff --git a/src/QGst/Ui/graphicsvideowidget.h b/src/QGst/Ui/graphicsvideowidget.h
new file mode 100644
index 0000000..e6434b7
--- /dev/null
+++ b/src/QGst/Ui/graphicsvideowidget.h
@@ -0,0 +1,65 @@
+/*
+ Copyright (C) 2012 Collabora Ltd. <info@collabora.com>
+ @author George Kiagiadakis <george.kiagiadakis@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#ifndef QGST_UI_GRAPHICSVIDEOWIDGET_H
+#define QGST_UI_GRAPHICSVIDEOWIDGET_H
+
+#include "graphicsvideosurface.h"
+#include <QtCore/QPointer>
+
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
+# include <QtWidgets/QGraphicsWidget>
+#else
+# include <QtGui/QGraphicsWidget>
+#endif
+
+namespace QGst {
+namespace Ui {
+
+/*! \headerfile graphicsvideowidget.h <QGst/Ui/GraphicsVideoWidget>
+ * \brief A QGraphicsWidget for displaying video on a QGraphicsScene
+ *
+ * This is a QGraphicsWidget subclass that can display video. To use it,
+ * you have to create a GraphicsVideoSurface and connect it with this
+ * widget using the setSurface() method or the surface property.
+ * See the GraphicsVideoSurface documentation for details and examples.
+ *
+ * \sa GraphicsVideoSurface
+ */
+class QTGSTREAMERUI_EXPORT GraphicsVideoWidget : public QGraphicsWidget
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(GraphicsVideoWidget)
+ Q_PROPERTY(QGst::Ui::GraphicsVideoSurface* surface READ surface WRITE setSurface)
+public:
+ explicit GraphicsVideoWidget(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0);
+ virtual ~GraphicsVideoWidget();
+
+ /*! Reimplemented from QGraphicsWidget. Do not call directly. */
+ virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+ GraphicsVideoSurface *surface() const;
+ void setSurface(GraphicsVideoSurface *surface);
+
+private:
+ QPointer<GraphicsVideoSurface> m_surface;
+};
+
+} // namespace Ui
+} // namespace QGst
+
+#endif // QGST_UI_GRAPHICSVIDEOWIDGET_H
diff --git a/src/QGst/Ui/videowidget.cpp b/src/QGst/Ui/videowidget.cpp
index c4edabd..aca0c6b 100644
--- a/src/QGst/Ui/videowidget.cpp
+++ b/src/QGst/Ui/videowidget.cpp
@@ -1,6 +1,6 @@
/*
Copyright (C) 2010 George Kiagiadakis <kiagiadakis.george@gmail.com>
- Copyright (C) 2011 Collabora Ltd.
+ Copyright (C) 2011-2012 Collabora Ltd.
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
This library is free software; you can redistribute it and/or modify
@@ -11,24 +11,36 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
*/
#include "videowidget.h"
-#include "../xoverlay.h"
+#include "../videooverlay.h"
#include "../pipeline.h"
#include "../bus.h"
#include "../message.h"
#include "../../QGlib/connect.h"
+#include "../../QGlib/Signal"
#include <QtCore/QDebug>
#include <QtCore/QMutex>
#include <QtCore/QThread>
#include <QtGui/QPainter>
#include <QtGui/QPaintEvent>
#include <QtGui/QResizeEvent>
-#include <QtGui/QApplication>
+
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
+# include <QtWidgets/QApplication>
+# include <QtWidgets/QHBoxLayout>
+#else
+# include <QtGui/QApplication>
+# include <QtGui/QHBoxLayout>
+#endif
+
+#ifndef QTGSTREAMER_UI_NO_OPENGL
+# include <QtOpenGL/QGLWidget>
+#endif
namespace QGst {
namespace Ui {
@@ -43,14 +55,16 @@ public:
};
-class XOverlayRenderer : public QObject, public AbstractRenderer
+class VideoOverlayRenderer : public QObject, public AbstractRenderer
{
public:
- XOverlayRenderer(QWidget *parent)
+ VideoOverlayRenderer(QWidget *parent)
: QObject(parent)
{
m_windowId = widget()->winId(); //create a new X window (if we are on X11 with alien widgets)
+#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
QApplication::syncX(); //inform other applications about the new window (on X11)
+#endif
widget()->installEventFilter(this);
widget()->setAttribute(Qt::WA_NoSystemBackground, true);
@@ -58,7 +72,7 @@ public:
widget()->update();
}
- virtual ~XOverlayRenderer()
+ virtual ~VideoOverlayRenderer()
{
if (m_sink) {
m_sink->setWindowHandle(0);
@@ -69,7 +83,7 @@ public:
widget()->update();
}
- void setVideoSink(const XOverlayPtr & sink)
+ void setVideoSink(const VideoOverlayPtr & sink)
{
QMutexLocker l(&m_sinkMutex);
if (m_sink) {
@@ -110,10 +124,90 @@ private:
inline QWidget *widget() { return static_cast<QWidget*>(parent()); }
WId m_windowId;
mutable QMutex m_sinkMutex;
- XOverlayPtr m_sink;
+ VideoOverlayPtr m_sink;
};
+class QtVideoSinkRenderer : public QObject, public AbstractRenderer
+{
+public:
+ QtVideoSinkRenderer(const ElementPtr & sink, QWidget *parent)
+ : QObject(parent), m_sink(sink)
+ {
+ QGlib::connect(sink, "update", this, &QtVideoSinkRenderer::onUpdate);
+ parent->installEventFilter(this);
+ parent->setAttribute(Qt::WA_OpaquePaintEvent, true);
+ }
+
+ virtual ~QtVideoSinkRenderer()
+ {
+ widget()->removeEventFilter(this);
+ widget()->setAttribute(Qt::WA_OpaquePaintEvent, false);
+ }
+
+ virtual ElementPtr videoSink() const { return m_sink; }
+
+protected:
+ virtual bool eventFilter(QObject *filteredObject, QEvent *event)
+ {
+ if (filteredObject == parent() && event->type() == QEvent::Paint) {
+ QPainter painter(widget());
+ QRect targetArea = widget()->rect();
+ QGlib::emit<void>(m_sink, "paint", (void*) &painter,
+ (qreal) targetArea.x(), (qreal) targetArea.y(),
+ (qreal) targetArea.width(), (qreal) targetArea.height());
+ return true;
+ } else {
+ return QObject::eventFilter(filteredObject, event);
+ }
+ }
+
+private:
+ inline QWidget *widget() { return static_cast<QWidget*>(parent()); }
+ void onUpdate() { widget()->update(); }
+
+ ElementPtr m_sink;
+};
+
+
+#ifndef QTGSTREAMER_UI_NO_OPENGL
+
+class QtGLVideoSinkRenderer : public AbstractRenderer
+{
+public:
+ QtGLVideoSinkRenderer(const ElementPtr & sink, QWidget *parent)
+ {
+ m_layout = new QHBoxLayout(parent);
+ m_glWidget = new QGLWidget(parent);
+ m_layout->setContentsMargins(0, 0, 0, 0);
+ m_layout->addWidget(m_glWidget);
+ parent->setLayout(m_layout);
+
+ m_renderer = new QtVideoSinkRenderer(sink, m_glWidget);
+
+ m_glWidget->makeCurrent();
+ sink->setProperty("glcontext", (void*) QGLContext::currentContext());
+ m_glWidget->doneCurrent();
+ }
+
+ virtual ~QtGLVideoSinkRenderer()
+ {
+ delete m_renderer;
+ delete m_glWidget;
+ delete m_layout;
+ }
+
+ virtual ElementPtr videoSink() const { return m_renderer->videoSink(); }
+
+private:
+ QtVideoSinkRenderer *m_renderer;
+ QHBoxLayout *m_layout;
+ QGLWidget *m_glWidget;
+};
+
+#endif // QTGSTREAMER_UI_NO_OPENGL
+
+
class QWidgetVideoSinkRenderer : public AbstractRenderer
{
public:
@@ -140,7 +234,7 @@ class PipelineWatch : public QObject, public AbstractRenderer
{
public:
PipelineWatch(const PipelinePtr & pipeline, QWidget *parent)
- : QObject(parent), m_renderer(new XOverlayRenderer(parent)), m_pipeline(pipeline)
+ : QObject(parent), m_renderer(new VideoOverlayRenderer(parent)), m_pipeline(pipeline)
{
pipeline->bus()->enableSyncMessageEmission();
QGlib::connect(pipeline->bus(), "sync-message",
@@ -155,15 +249,15 @@ public:
virtual ElementPtr videoSink() const { return m_renderer->videoSink(); }
- void releaseSink() { m_renderer->setVideoSink(XOverlayPtr()); }
+ void releaseSink() { m_renderer->setVideoSink(VideoOverlayPtr()); }
private:
void onBusSyncMessage(const MessagePtr & msg)
{
switch (msg->type()) {
case MessageElement:
- if (msg->internalStructure()->name() == QLatin1String("prepare-xwindow-id")) {
- XOverlayPtr overlay = msg->source().dynamicCast<XOverlay>();
+ if (VideoOverlay::isPrepareWindowHandleMessage(msg)) {
+ VideoOverlayPtr overlay = msg->source().dynamicCast<VideoOverlay>();
m_renderer->setVideoSink(overlay);
}
break;
@@ -180,21 +274,43 @@ private:
}
private:
- XOverlayRenderer *m_renderer;
+ VideoOverlayRenderer *m_renderer;
PipelinePtr m_pipeline;
};
AbstractRenderer *AbstractRenderer::create(const ElementPtr & sink, QWidget *videoWidget)
{
- XOverlayPtr overlay = sink.dynamicCast<XOverlay>();
+ VideoOverlayPtr overlay = sink.dynamicCast<VideoOverlay>();
if (overlay) {
- XOverlayRenderer *r = new XOverlayRenderer(videoWidget);
+ VideoOverlayRenderer *r = new VideoOverlayRenderer(videoWidget);
r->setVideoSink(overlay);
return r;
}
- if (QGlib::Type::fromInstance(sink).name() == QLatin1String("GstQWidgetVideoSink")) {
+ if (QGlib::Type::fromInstance(sink).name() == QLatin1String("GstQtVideoSink"
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
+ "_qt5"
+#endif
+ )) {
+ return new QtVideoSinkRenderer(sink, videoWidget);
+ }
+
+#ifndef QTGSTREAMER_UI_NO_OPENGL
+ if (QGlib::Type::fromInstance(sink).name() == QLatin1String("GstQtGLVideoSink"
+# if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
+ "_qt5"
+# endif
+ )) {
+ return new QtGLVideoSinkRenderer(sink, videoWidget);
+ }
+#endif
+
+ if (QGlib::Type::fromInstance(sink).name() == QLatin1String("GstQWidgetVideoSink"
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
+ "_qt5"
+#endif
+ )) {
return new QWidgetVideoSinkRenderer(sink, videoWidget);
}
diff --git a/src/QGst/Ui/videowidget.h b/src/QGst/Ui/videowidget.h
index 01b2457..e4d4d45 100644
--- a/src/QGst/Ui/videowidget.h
+++ b/src/QGst/Ui/videowidget.h
@@ -11,7 +11,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -21,7 +21,12 @@
#include "global.h"
#include "../element.h"
-#include <QtGui/QWidget>
+
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
+# include <QtWidgets/QWidget>
+#else
+# include <QtGui/QWidget>
+#endif
namespace QGst {
namespace Ui {
@@ -35,11 +40,13 @@ class AbstractRenderer;
*
* There are two ways of using this widget:
* \li Create a video sink yourself and set it with the setVideoSink() method.
- * This will work for all sinks that implement the XOverlay interface, plus
- * the "qwidgetvideosink", which paints directly on the widget.
+ * This will work for all sinks that implement the VideoOverlay interface, plus
+ * "qtvideosink", "qtglvideosink" and "qwidgetvideosink" (or "qt5videosink",
+ * "qt5glvideosink" and "qwidget5videosink" in Qt5), which paint directly
+ * on the widget.
* \li Create a pipeline and let the widget watch the pipeline using the
* watchPipeline() method. This will cause the widget to watch the bus for
- * the "prepare-xwindow-id" that all XOverlay sinks send right before
+ * the "prepare-window-handle" that all VideoOverlay sinks send right before
* creating a window and will embed any sink that sends this message.
* You need to make sure however that there can only be one video sink in
* this pipeline. If there are more than one, you should handle them yourself
@@ -55,14 +62,15 @@ class AbstractRenderer;
*
* \note Autoplug video sinks such as autovideosink are not supported due
* to the complexity of handling them correctly. If you wish to use autovideosink,
- * you can either set it to READY state and get its child XOverlay element
+ * you can either set it to READY state and get its child VideoOverlay element
* or just watch the pipeline in which you plug it.
*/
class QTGSTREAMERUI_EXPORT VideoWidget : public QWidget
{
Q_OBJECT
+ Q_DISABLE_COPY(VideoWidget)
public:
- VideoWidget(QWidget *parent = 0, Qt::WindowFlags f = 0);
+ explicit VideoWidget(QWidget *parent = 0, Qt::WindowFlags f = 0);
virtual ~VideoWidget();
@@ -72,7 +80,9 @@ public:
ElementPtr videoSink() const;
/*! Sets the video sink element that is going to be embedded.
- * Any sink that implements the XOverlay interface will work, as well as "qwidgetvideosink".
+ * Any sink that implements the VideoOverlay interface will work, as well as
+ * "qtvideosink", "qtglvideosink" and "qwidgetvideosink" (or "qt5videosink",
+ * "qt5glvideosink" and "qwidget5videosink" in Qt5)
* \note
* \li This method \em must be called from Qt's GUI thread.
* \li Passing a null ElementPtr has the same effect as calling releaseVideoSink().
@@ -86,7 +96,7 @@ public:
void releaseVideoSink();
- /*! Starts watching a pipeline for any attached XOverlay sinks. If such
+ /*! Starts watching a pipeline for any attached VideoOverlay sinks. If such
* a sink is found while the pipeline prepares itself to start playing,
* it is embedded to the widget.
* \note
diff --git a/src/QGst/Utils/applicationsink.cpp b/src/QGst/Utils/applicationsink.cpp
index ed2e975..5e4c65b 100644
--- a/src/QGst/Utils/applicationsink.cpp
+++ b/src/QGst/Utils/applicationsink.cpp
@@ -10,7 +10,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -40,13 +40,11 @@ public:
private:
static void eos(GstAppSink *sink, gpointer user_data);
static GstFlowReturn new_preroll(GstAppSink *sink, gpointer user_data);
- static GstFlowReturn new_buffer(GstAppSink *sink, gpointer user_data);
- static GstFlowReturn new_buffer_list(GstAppSink *sink, gpointer user_data);
+ static GstFlowReturn new_sample(GstAppSink *sink, gpointer user_data);
static void eos_noop(GstAppSink*, gpointer) {}
static GstFlowReturn new_preroll_noop(GstAppSink*, gpointer) { return GST_FLOW_OK; }
- static GstFlowReturn new_buffer_noop(GstAppSink*, gpointer) { return GST_FLOW_OK; }
- static GstFlowReturn new_buffer_list_noop(GstAppSink*, gpointer) { return GST_FLOW_OK; }
+ static GstFlowReturn new_sample_noop(GstAppSink*, gpointer) { return GST_FLOW_OK; }
};
void ApplicationSink::Priv::lazyConstruct(ApplicationSink *self)
@@ -64,12 +62,11 @@ void ApplicationSink::Priv::setCallbacks(ApplicationSink *self)
{
if (m_appsink) {
if (self) {
- static GstAppSinkCallbacks callbacks = { &eos, &new_preroll,
- &new_buffer, &new_buffer_list };
+ static GstAppSinkCallbacks callbacks = { &eos, &new_preroll, &new_sample };
gst_app_sink_set_callbacks(appSink(), &callbacks, self, NULL);
} else {
static GstAppSinkCallbacks callbacks = { &eos_noop, &new_preroll_noop,
- &new_buffer_noop, &new_buffer_list_noop };
+ &new_sample_noop };
gst_app_sink_set_callbacks(appSink(), &callbacks, NULL, NULL);
}
}
@@ -87,16 +84,10 @@ GstFlowReturn ApplicationSink::Priv::new_preroll(GstAppSink* sink, gpointer user
return static_cast<GstFlowReturn>(static_cast<ApplicationSink*>(user_data)->newPreroll());
}
-GstFlowReturn ApplicationSink::Priv::new_buffer(GstAppSink* sink, gpointer user_data)
+GstFlowReturn ApplicationSink::Priv::new_sample(GstAppSink* sink, gpointer user_data)
{
Q_UNUSED(sink);
- return static_cast<GstFlowReturn>(static_cast<ApplicationSink*>(user_data)->newBuffer());
-}
-
-GstFlowReturn ApplicationSink::Priv::new_buffer_list(GstAppSink* sink, gpointer user_data)
-{
- Q_UNUSED(sink);
- return static_cast<GstFlowReturn>(static_cast<ApplicationSink*>(user_data)->newBufferList());
+ return static_cast<GstFlowReturn>(static_cast<ApplicationSink*>(user_data)->newSample());
}
#endif //DOXYGEN_RUN
@@ -175,29 +166,20 @@ void ApplicationSink::enableDrop(bool enable)
}
}
-BufferPtr ApplicationSink::pullPreroll()
+SamplePtr ApplicationSink::pullPreroll()
{
- BufferPtr buf;
+ SamplePtr buf;
if (d->appSink()) {
- buf = BufferPtr::wrap(gst_app_sink_pull_preroll(d->appSink()), false);
+ buf = SamplePtr::wrap(gst_app_sink_pull_preroll(d->appSink()), false);
}
return buf;
}
-BufferPtr ApplicationSink::pullBuffer()
+SamplePtr ApplicationSink::pullSample()
{
- BufferPtr buf;
+ SamplePtr buf;
if (d->appSink()) {
- buf = BufferPtr::wrap(gst_app_sink_pull_buffer(d->appSink()), false);
- }
- return buf;
-}
-
-BufferListPtr ApplicationSink::pullBufferList()
-{
- BufferListPtr buf;
- if (d->appSink()) {
- buf = BufferListPtr::wrap(gst_app_sink_pull_buffer_list(d->appSink()), false);
+ buf = SamplePtr::wrap(gst_app_sink_pull_sample(d->appSink()), false);
}
return buf;
}
@@ -211,16 +193,10 @@ FlowReturn ApplicationSink::newPreroll()
return FlowOk;
}
-FlowReturn ApplicationSink::newBuffer()
+FlowReturn ApplicationSink::newSample()
{
return FlowOk;
}
-FlowReturn ApplicationSink::newBufferList()
-{
- return FlowOk;
-}
-
-
} //namespace Utils
} //namespace QGst
diff --git a/src/QGst/Utils/applicationsink.h b/src/QGst/Utils/applicationsink.h
index 09de45d..98a9488 100644
--- a/src/QGst/Utils/applicationsink.h
+++ b/src/QGst/Utils/applicationsink.h
@@ -10,7 +10,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -20,7 +20,7 @@
#include "global.h"
#include "../element.h"
-#include "../bufferlist.h"
+#include "../sample.h"
namespace QGst {
namespace Utils {
@@ -33,25 +33,25 @@ namespace Utils {
* provides external API functions. This class exports those API functions in the bindings
* and makes it easy to implement a custom sink.
*
- * The normal way of retrieving buffers from appsink is by using the pullBuffer() and pullPreroll()
- * methods. These methods block until a buffer becomes available in the sink or when the sink is
+ * The normal way of retrieving sample from appsink is by using the pullSample() and pullPreroll()
+ * methods. These methods block until a sample becomes available in the sink or when the sink is
* shut down or reaches EOS.
*
- * Appsink will internally use a queue to collect buffers from the streaming thread. If the
- * application is not pulling buffers fast enough, this queue will consume a lot of memory over
+ * Appsink will internally use a queue to collect samples from the streaming thread. If the
+ * application is not pulling samples fast enough, this queue will consume a lot of memory over
* time. setMaxBuffers() can be used to limit the queue size. enableDrop() controls whether the
- * streaming thread blocks or if older buffers are dropped when the maximum queue size is reached.
+ * streaming thread blocks or if older samples are dropped when the maximum queue size is reached.
* Note that blocking the streaming thread can negatively affect real-time performance and
* should be avoided.
*
* If a blocking behaviour is not desirable, you can subclass this class and implement the
- * newPreroll(), newBuffer() and newBufferList() which will be called to notify you when a new
- * buffer is available.
+ * newPreroll(), newSample() and newBufferList() which will be called to notify you when a new
+ * sample is available.
*
* setCaps() can be used to control the formats that appsink can receive. This property can contain
- * non-fixed caps. The format of the pulled buffers can be obtained by getting the buffer caps.
+ * non-fixed caps. The format of the pulled samples can be obtained by getting the sample caps.
*
- * If one of the pullPreroll() or pullBuffer() methods return NULL, the appsink is stopped or in
+ * If one of the pullPreroll() or pullSample() methods return NULL, the appsink is stopped or in
* the EOS state. You can check for the EOS state with isEos(). The eos() virtual method can also
* be reimplemented to be informed when the EOS state is reached to avoid polling.
*
@@ -105,48 +105,48 @@ public:
/*! Enables dropping old buffers when the maximum amount of queued buffers is reached. */
void enableDrop(bool enable);
- /*! Get the last preroll buffer in appsink. This was the buffer that caused the appsink
- * to preroll in the PAUSED state. This buffer can be pulled many times and remains
+ /*! Get the last preroll sample in appsink. This was the sample that caused the appsink
+ * to preroll in the PAUSED state. This sample can be pulled many times and remains
* available to the application even after EOS.
*
* This function is typically used when dealing with a pipeline in the PAUSED state.
- * Calling this function after doing a seek will give the buffer right after the seek position.
+ * Calling this function after doing a seek will give the sample right after the seek position.
*
- * Note that the preroll buffer will also be returned as the first buffer when calling
- * pullBuffer().
+ * Note that the preroll sample will also be returned as the first sample when calling
+ * pullSample().
*
- * If an EOS event was received before any buffers, this function returns a null BufferPtr.
+ * If an EOS event was received before any samples, this function returns a null SamplePtr.
* Use isEos() to check for the EOS condition.
*
- * This function blocks until a preroll buffer or EOS is received or the appsink element
+ * This function blocks until a preroll sample or EOS is received or the appsink element
* is set to the READY/NULL state.
*/
- BufferPtr pullPreroll();
+ SamplePtr pullPreroll();
- /*! This function blocks until a buffer or EOS becomes available or the appsink
+ /*! This function blocks until a sample or EOS becomes available or the appsink
* element is set to the READY/NULL state.
*
- * This function will only return buffers when the appsink is in the PLAYING state.
- * All rendered buffers will be put in a queue so that the application can pull buffers
- * at its own rate. Note that when the application does not pull buffers fast enough, the
- * queued buffers could consume a lot of memory, especially when dealing with raw video frames.
+ * This function will only return samples when the appsink is in the PLAYING state.
+ * All rendered samples will be put in a queue so that the application can pull samples
+ * at its own rate. Note that when the application does not pull samples fast enough, the
+ * queued samples could consume a lot of memory, especially when dealing with raw video frames.
*
- * If an EOS event was received before any buffers, this function returns a null BufferPtr.
+ * If an EOS event was received before any samples, this function returns a null SamplePtr.
* Use isEos() to check for the EOS condition.
*/
- BufferPtr pullBuffer();
+ SamplePtr pullSample();
- /*! This function blocks until a buffer list or EOS becomes available or the appsink
+ /*! This function blocks until a sample list or EOS becomes available or the appsink
* element is set to the READY/NULL state.
*
- * This function will only return buffer lists when the appsink is in the PLAYING state.
- * All rendered buffer lists will be put in a queue so that the application can pull buffer
- * lists at its own rate. Note that when the application does not pull buffer lists fast
- * enough, the queued buffer lists could consume a lot of memory, especially when dealing
+ * This function will only return sample lists when the appsink is in the PLAYING state.
+ * All rendered sample lists will be put in a queue so that the application can pull sample
+ * lists at its own rate. Note that when the application does not pull sample lists fast
+ * enough, the queued sample lists could consume a lot of memory, especially when dealing
* with raw video frames.
*
- * If an EOS event was received before any buffer lists, this function returns a null
- * BufferListPtr. Use isEos() to check for the EOS condition.
+ * If an EOS event was received before any sample lists, this function returns a null
+ * SampleListPtr. Use isEos() to check for the EOS condition.
*/
BufferListPtr pullBufferList();
@@ -155,20 +155,15 @@ protected:
* \note This function is called from the steaming thread. */
virtual void eos();
- /*! Called when a new preroll buffer is available. The new preroll buffer can be
+ /*! Called when a new preroll sample is available. The new preroll sample can be
* retrieved with pullPreroll() either from this function or from any other thread.
* \note This function is called from the steaming thread. */
virtual FlowReturn newPreroll();
- /*! Called when a new buffer is available. The new buffer can be retrieved
- * with pullBuffer() either from this function or from any other thread.
+ /*! Called when a new sample is available. The new sample can be retrieved
+ * with pullSample() either from this function or from any other thread.
* \note This function is called from the steaming thread. */
- virtual FlowReturn newBuffer();
-
- /*! Called when a new buffer list is available. The new buffer list can be retrieved
- * with pullBufferList() either from this function or from any other thread.
- * \note This function is called from the steaming thread. */
- virtual FlowReturn newBufferList();
+ virtual FlowReturn newSample();
private:
/* vtable padding */
diff --git a/src/QGst/Utils/applicationsource.cpp b/src/QGst/Utils/applicationsource.cpp
index fd02f0d..c7cbef3 100644
--- a/src/QGst/Utils/applicationsource.cpp
+++ b/src/QGst/Utils/applicationsource.cpp
@@ -10,7 +10,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -62,10 +62,10 @@ void ApplicationSource::Priv::setCallbacks(ApplicationSource *self)
{
if (m_appsrc) {
if (self) {
- static GstAppSrcCallbacks callbacks = { &need_data, &enough_data, &seek_data };
+ static GstAppSrcCallbacks callbacks = { &need_data, &enough_data, &seek_data, NULL };
gst_app_src_set_callbacks(appSrc(), &callbacks, self, NULL);
} else {
- static GstAppSrcCallbacks callbacks = { &need_data_noop, &enough_data_noop, &seek_data_noop };
+ static GstAppSrcCallbacks callbacks = { &need_data_noop, &enough_data_noop, &seek_data_noop, NULL };
gst_app_src_set_callbacks(appSrc(), &callbacks, NULL, NULL);
}
}
@@ -256,7 +256,7 @@ FlowReturn ApplicationSource::pushBuffer(const BufferPtr & buffer)
if (d->appSrc()) {
return static_cast<FlowReturn>(gst_app_src_push_buffer(d->appSrc(), gst_buffer_ref(buffer)));
} else {
- return FlowWrongState;
+ return FlowFlushing;
}
}
@@ -265,7 +265,7 @@ FlowReturn ApplicationSource::endOfStream()
if (d->appSrc()) {
return static_cast<FlowReturn>(gst_app_src_end_of_stream(d->appSrc()));
} else {
- return FlowWrongState;
+ return FlowFlushing;
}
}
diff --git a/src/QGst/Utils/applicationsource.h b/src/QGst/Utils/applicationsource.h
index 5cd1706..8254904 100644
--- a/src/QGst/Utils/applicationsource.h
+++ b/src/QGst/Utils/applicationsource.h
@@ -10,7 +10,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/src/QGst/Utils/global.h b/src/QGst/Utils/global.h
index ed598e6..50051f4 100644
--- a/src/QGst/Utils/global.h
+++ b/src/QGst/Utils/global.h
@@ -10,7 +10,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -18,10 +18,15 @@
#ifndef QGST_UTILS_GLOBAL_H
#define QGST_UTILS_GLOBAL_H
+// workaround for https://bugreports.qt-project.org/browse/QTBUG-22829
+#if defined(Q_MOC_RUN) && !defined(BOOST_TT_HAS_OPERATOR_HPP_INCLUDED)
+#define BOOST_TT_HAS_OPERATOR_HPP_INCLUDED
+#endif
+
#include <QtCore/QtGlobal>
/* defined by cmake when building this library */
-#if defined(QtGStreamerUtils_EXPORTS)
+#if defined(QtGStreamerUtils_EXPORTS) || defined(Qt5GStreamerUtils_EXPORTS)
# define QTGSTREAMERUTILS_EXPORT Q_DECL_EXPORT
#else
# define QTGSTREAMERUTILS_EXPORT Q_DECL_IMPORT
diff --git a/src/QGst/VideoOverlay b/src/QGst/VideoOverlay
new file mode 100644
index 0000000..8213aca
--- /dev/null
+++ b/src/QGst/VideoOverlay
@@ -0,0 +1 @@
+#include "videooverlay.h"
diff --git a/src/QGst/XOverlay b/src/QGst/XOverlay
deleted file mode 100644
index 4a825a0..0000000
--- a/src/QGst/XOverlay
+++ /dev/null
@@ -1 +0,0 @@
-#include "xoverlay.h"
diff --git a/src/QGst/allocator.cpp b/src/QGst/allocator.cpp
new file mode 100644
index 0000000..fc3cb89
--- /dev/null
+++ b/src/QGst/allocator.cpp
@@ -0,0 +1,128 @@
+/*
+ Copyright (C) 2014 Diane Trout <diane@ghic.org>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "allocator.h"
+#include <gst/gst.h>
+
+namespace QGst {
+
+AllocationParams::AllocationParams()
+ : d(g_slice_new0(GstAllocationParams))
+{
+ gst_allocation_params_init(d);
+}
+
+AllocationParams::AllocationParams(const AllocationParams & other)
+ : d(gst_allocation_params_copy(other.d))
+{
+}
+
+AllocationParams::~AllocationParams()
+{
+ gst_allocation_params_free(d);
+}
+
+AllocationParams & AllocationParams::operator=(const AllocationParams & other)
+{
+ gst_allocation_params_free(d);
+ d = gst_allocation_params_copy(other.d);
+ return *this;
+}
+
+MemoryFlags AllocationParams::flags() const
+{
+ return static_cast<QGst::MemoryFlags>(static_cast<unsigned int>(d->flags));
+}
+
+void AllocationParams::setFlags(MemoryFlags flags)
+{
+ d->flags = static_cast<GstMemoryFlags>(static_cast<unsigned int>(flags));
+}
+
+size_t AllocationParams::align() const
+{
+ return d->align;
+}
+
+void AllocationParams::setAlign(size_t align)
+{
+ d->align = align;
+}
+
+size_t AllocationParams::prefix() const
+{
+ return d->prefix;
+}
+
+void AllocationParams::setPrefix(size_t align)
+{
+ d->prefix = align;
+}
+
+size_t AllocationParams::padding() const
+{
+ return d->padding;
+}
+
+void AllocationParams::setPadding(size_t padding)
+{
+ d->padding = padding;
+}
+
+AllocationParams::operator const GstAllocationParams*() const
+{
+ return d;
+}
+
+AllocationParams::operator GstAllocationParams*()
+{
+ return d;
+}
+
+//static
+AllocatorPtr Allocator::find(const char *name)
+{
+ return AllocatorPtr::wrap(gst_allocator_find(name), false);
+}
+
+//static
+AllocatorPtr Allocator::getDefault()
+{
+ return find(NULL);
+}
+
+//static
+AllocatorPtr Allocator::getSystemMemory()
+{
+ return find(GST_ALLOCATOR_SYSMEM);
+}
+
+MemoryPtr Allocator::alloc(size_t size, const AllocationParams & params)
+{
+ return MemoryPtr::wrap(gst_allocator_alloc(object<GstAllocator>(), size,
+ const_cast<GstAllocationParams *>(static_cast<const GstAllocationParams *>(params))), false);
+}
+
+void Allocator::free(MemoryPtr & memory)
+{
+ GstMemory *mem = memory;
+ gst_memory_ref(mem);
+ memory.clear();
+ gst_allocator_free(object<GstAllocator>(), mem);
+}
+
+} /* QGst */
diff --git a/src/QGst/allocator.h b/src/QGst/allocator.h
new file mode 100644
index 0000000..934866e
--- /dev/null
+++ b/src/QGst/allocator.h
@@ -0,0 +1,86 @@
+/*
+ Copyright (C) 2014 Diane Trout <diane@ghic.org>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef QGST_ALLOCATOR_H
+#define QGST_ALLOCATOR_H
+
+#include "global.h"
+#include "object.h"
+#include "memory.h"
+
+namespace QGst {
+
+/*! \headerfile allocator.h <QGst/Allocator>
+ * \brief Wrapper class for GstAllocationParams
+ */
+class QTGSTREAMER_EXPORT AllocationParams
+{
+public:
+ AllocationParams();
+ AllocationParams(const AllocationParams & other);
+ virtual ~AllocationParams();
+
+ AllocationParams & operator=(const AllocationParams & other);
+
+ MemoryFlags flags() const;
+ void setFlags(MemoryFlags flags);
+
+ size_t align() const;
+ void setAlign(size_t align);
+
+ size_t prefix() const;
+ void setPrefix(size_t align);
+
+ size_t padding() const;
+ void setPadding(size_t padding);
+
+ operator GstAllocationParams*();
+ operator const GstAllocationParams*() const;
+
+private:
+ friend class Allocator;
+ GstAllocationParams *d;
+};
+
+/*! \headerfile allocator.h <QGst/Allocator>
+ * \brief Wrapper class for GstAllocator
+ */
+class QTGSTREAMER_EXPORT Allocator : public Object
+{
+ QGST_WRAPPER(Allocator)
+public:
+ /*! search for an already registered allocator. */
+ static AllocatorPtr find(const char *name);
+
+ /*! get the default allocator */
+ static AllocatorPtr getDefault();
+ /*! get the system memory allocator */
+ static AllocatorPtr getSystemMemory();
+
+ /*! create a chunk of memory using this allocator */
+ MemoryPtr alloc(size_t size, const AllocationParams &params = AllocationParams());
+ /*! release memory allocated with alloc()
+ * \note this takes a reference to the memory pointer and makes
+ * it null after freeing the memory segment */
+ void free(MemoryPtr & memory);
+};
+
+} //namespace QGst
+
+QGST_REGISTER_TYPE(QGst::Allocator)
+
+#endif /* QGST_ALLOCATOR_H */
diff --git a/src/QGst/bin.cpp b/src/QGst/bin.cpp
index c07053c..eec9886 100644
--- a/src/QGst/bin.cpp
+++ b/src/QGst/bin.cpp
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -17,8 +17,7 @@
#include "bin.h"
#include "pad.h"
#include "../QGlib/error.h"
-#include <gst/gstbin.h>
-#include <gst/gstutils.h>
+#include <gst/gst.h>
namespace QGst {
diff --git a/src/QGst/bin.h b/src/QGst/bin.h
index 9fa6c4e..50618fe 100644
--- a/src/QGst/bin.h
+++ b/src/QGst/bin.h
@@ -11,7 +11,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -152,7 +152,7 @@ public:
/*! Looks for an element inside the bin that implements the given interface
* and returns it casted to the interface type. Example:
* \code
- * QGst::XOverlayPtr xoverlay = bin->getElementByInterface<QGst::XOverlay>();
+ * QGst::VideoOverlayPtr videooverlay = bin->getElementByInterface<QGst::VideoOverlay>();
* \endcode
*/
template <typename T> QGlib::RefPointer<T> getElementByInterface() const;
diff --git a/src/QGst/buffer.cpp b/src/QGst/buffer.cpp
index 6641464..a56f2e0 100644
--- a/src/QGst/buffer.cpp
+++ b/src/QGst/buffer.cpp
@@ -10,7 +10,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -21,25 +21,26 @@
#include <gst/gst.h>
namespace QGst {
+class MapInfo;
BufferPtr Buffer::create(uint size)
{
- return BufferPtr::wrap(gst_buffer_try_new_and_alloc(size), false);
+ return BufferPtr::wrap(gst_buffer_new_allocate(NULL, size, NULL), false);
}
-quint8 * Buffer::data() const
+quint32 Buffer::size() const
{
- return GST_BUFFER_DATA(object<GstBuffer>());
+ return gst_buffer_get_size(object<GstBuffer>());
}
-quint32 Buffer::size() const
+ClockTime Buffer::decodingTimeStamp() const
{
- return GST_BUFFER_SIZE(object<GstBuffer>());
+ return GST_BUFFER_DTS(object<GstBuffer>());
}
-ClockTime Buffer::timeStamp() const
+ClockTime Buffer::presentationTimeStamp() const
{
- return GST_BUFFER_TIMESTAMP(object<GstBuffer>());
+ return GST_BUFFER_PTS(object<GstBuffer>());
}
ClockTime Buffer::duration() const
@@ -47,17 +48,6 @@ ClockTime Buffer::duration() const
return GST_BUFFER_DURATION(object<GstBuffer>());
}
-CapsPtr Buffer::caps() const
-{
- //wrap increasing the refcount
- return QGst::CapsPtr::wrap(GST_BUFFER_CAPS(object<GstBuffer>()));
-}
-
-void Buffer::setCaps(const CapsPtr & caps)
-{
- gst_buffer_set_caps(object<GstBuffer>(), caps);
-}
-
quint64 Buffer::offset() const
{
return GST_BUFFER_OFFSET(object<GstBuffer>());
@@ -83,4 +73,38 @@ BufferPtr Buffer::copy() const
return BufferPtr::wrap(gst_buffer_copy(object<GstBuffer>()), false);
}
+void Buffer::setSize(uint size)
+{
+ gst_buffer_set_size(object<GstBuffer>(), size);
+}
+
+uint Buffer::extract(uint offset, void *dest, uint size)
+{
+ return gst_buffer_extract(object<GstBuffer>(), offset, dest, size);
+}
+
+uint Buffer::memoryCount() const
+{
+ return gst_buffer_n_memory (object<GstBuffer>());
+}
+
+MemoryPtr Buffer::getMemory(uint index) const
+{
+ return MemoryPtr::wrap(gst_buffer_get_memory(object<GstBuffer>(), index), false);
+}
+
+bool Buffer::map(MapInfo &info, MapFlags flags)
+{
+ if (!gst_buffer_map(object<GstBuffer>(), static_cast<GstMapInfo *>(info.m_object),
+ static_cast<GstMapFlags>(static_cast<int>(flags)))) {
+ return false;
+ }
+ return true;
+}
+
+void Buffer::unmap(MapInfo &info)
+{
+ gst_buffer_unmap(object<GstBuffer>(), static_cast<GstMapInfo *>(info.m_object));
+}
+
} //namespace QGst
diff --git a/src/QGst/buffer.h b/src/QGst/buffer.h
index 9f3959f..272107d 100644
--- a/src/QGst/buffer.h
+++ b/src/QGst/buffer.h
@@ -10,7 +10,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -20,6 +20,7 @@
#include "miniobject.h"
#include "clocktime.h"
+#include "memory.h"
namespace QGst {
@@ -37,23 +38,30 @@ class QTGSTREAMER_EXPORT Buffer : public MiniObject
public:
static BufferPtr create(uint size);
- quint8 * data() const;
quint32 size() const;
- ClockTime timeStamp() const;
+ ClockTime decodingTimeStamp() const;
+ ClockTime presentationTimeStamp() const;
ClockTime duration() const;
- CapsPtr caps() const;
- void setCaps(const CapsPtr & caps);
-
quint64 offset() const;
quint64 offsetEnd() const;
BufferFlags flags() const;
void setFlags(const BufferFlags flags);
+ void setSize(uint size);
+
+ uint extract(uint offset, void *dest, uint size);
+
+ uint memoryCount() const;
+ MemoryPtr getMemory(uint index) const;
+
BufferPtr copy() const;
inline BufferPtr makeWritable() const;
+
+ bool map(MapInfo &info, MapFlags flags);
+ void unmap(MapInfo &info);
};
BufferPtr Buffer::makeWritable() const
diff --git a/src/QGst/bufferlist.cpp b/src/QGst/bufferlist.cpp
index 5eeef16..9a77df9 100644
--- a/src/QGst/bufferlist.cpp
+++ b/src/QGst/bufferlist.cpp
@@ -10,13 +10,13 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
*/
#include "bufferlist.h"
-#include <gst/gstbufferlist.h>
+#include <gst/gst.h>
namespace QGst {
@@ -25,72 +25,14 @@ BufferListPtr BufferList::create()
return BufferListPtr::wrap(gst_buffer_list_new(), false);
}
-uint BufferList::groupsCount() const
+uint BufferList::length() const
{
- return gst_buffer_list_n_groups(object<GstBufferList>());
+ return gst_buffer_list_length(object<GstBufferList>());
}
-BufferPtr BufferList::bufferAt(uint group, uint index) const
+BufferPtr BufferList::bufferAt(uint index) const
{
- return BufferPtr::wrap(gst_buffer_list_get(object<GstBufferList>(), group, index));
-}
-
-
-BufferListIterator::BufferListIterator(const BufferListPtr & list)
-{
- m_it = gst_buffer_list_iterate(list);
-}
-
-BufferListIterator::~BufferListIterator()
-{
- gst_buffer_list_iterator_free(m_it);
-}
-
-uint BufferListIterator::buffersInCurrentGroup() const
-{
- return gst_buffer_list_iterator_n_buffers(m_it);
-}
-
-BufferPtr BufferListIterator::next()
-{
- return BufferPtr::wrap(gst_buffer_list_iterator_next(m_it));
-}
-
-void BufferListIterator::insert(const BufferPtr & buffer)
-{
- gst_buffer_list_iterator_add(m_it, gst_buffer_ref(buffer));
-}
-
-void BufferListIterator::remove()
-{
- gst_buffer_list_iterator_remove(m_it);
-}
-
-BufferPtr BufferListIterator::take()
-{
- BufferPtr buf = BufferPtr::wrap(gst_buffer_list_iterator_steal(m_it), false);
- gst_buffer_list_iterator_remove(m_it);
- return buf;
-}
-
-void BufferListIterator::replace(const BufferPtr & other)
-{
- gst_buffer_list_iterator_take(m_it, gst_buffer_ref(other));
-}
-
-void BufferListIterator::addGroup()
-{
- gst_buffer_list_iterator_add_group(m_it);
-}
-
-bool BufferListIterator::nextGroup()
-{
- return gst_buffer_list_iterator_next_group(m_it);
-}
-
-BufferPtr BufferListIterator::mergeGroup() const
-{
- return BufferPtr::wrap(gst_buffer_list_iterator_merge_group(m_it), false);
+ return BufferPtr::wrap(gst_buffer_list_get(object<GstBufferList>(), index));
}
} //namespace QGst
diff --git a/src/QGst/bufferlist.h b/src/QGst/bufferlist.h
index 648e3fa..cde8025 100644
--- a/src/QGst/bufferlist.h
+++ b/src/QGst/bufferlist.h
@@ -10,7 +10,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -35,8 +35,8 @@ class QTGSTREAMER_EXPORT BufferList : public MiniObject
public:
static BufferListPtr create();
- uint groupsCount() const;
- BufferPtr bufferAt(uint group, uint index) const;
+ uint length() const;
+ BufferPtr bufferAt(uint index) const;
inline BufferListPtr copy() const;
inline BufferListPtr makeWritable() const;
@@ -52,72 +52,6 @@ inline BufferListPtr BufferList::makeWritable() const
return MiniObject::makeWritable().staticCast<BufferList>();
}
-
-/*! \headerfile bufferlist.h <QGst/BufferList>
- * \brief Wrapper class for GstBufferListIterator
- *
- * This class allows you to iterate through and modify a BufferList.
- *
- * The iterator has no current buffer; its cursor position lies between buffers,
- * immediately before the buffer that would be returned by next(). After iterating
- * to the end of a group the iterator must be advanced to the next group by a call
- * to nextGroup() before any further calls to next() can return buffers again.
- *
- * The cursor position of a newly created iterator lies before the first group;
- * a call to nextGroup() is necessary before calls to next() can return buffers.
- *
- * \sa BufferList
- */
-class QTGSTREAMER_EXPORT BufferListIterator
-{
-public:
- BufferListIterator(const BufferListPtr & list);
- ~BufferListIterator();
-
- /*! Returns the number of buffers in the current group */
- uint buffersInCurrentGroup() const;
-
- /*! Advances to the next buffer in the list. If a new group
- * is reached, it will return a null BufferPtr. */
- BufferPtr next();
-
- /*! Inserts a new buffer in the current group, immediately
- * before the buffer that would be returned by next(). */
- void insert(const BufferPtr & buffer);
-
- /*! Removes the last buffer returned by next() from the list.
- * \note You must call next() before calling this function
- * and make sure it doesn't return a null BufferPtr. */
- void remove();
-
- /*! Removes and returns the last buffer returned by next().
- * \note You must call next() before calling this function
- * and make sure it doesn't return a null BufferPtr. */
- BufferPtr take();
-
- /*! Replaces the last buffer returned by next() with \a other.
- * The buffer that was previously in its place will be unrefed.
- * \note You must call next() before calling this function
- * and make sure it doesn't return a null BufferPtr. */
- void replace(const BufferPtr & other);
-
- /*! Adds a new empty group in the list, imeediately before the group
- * that would be returned by nextGroup(). The iterator is advanced
- * to point at the beginning of the new group. */
- void addGroup();
-
- /*! Advances the iterator to the beginning of the next group and
- * returns true if it succeeded or false if there are no more groups. */
- bool nextGroup();
-
- /*! Merges all the buffers of the current group in a signle buffer and retruns it. */
- BufferPtr mergeGroup() const;
-
-private:
- GstBufferListIterator *m_it;
- Q_DISABLE_COPY(BufferListIterator)
-};
-
} //namespace QGst
QGST_REGISTER_TYPE(QGst::BufferList)
diff --git a/src/QGst/bus.cpp b/src/QGst/bus.cpp
index 7f38e01..2e04059 100644
--- a/src/QGst/bus.cpp
+++ b/src/QGst/bus.cpp
@@ -9,14 +9,14 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
*/
#include "bus.h"
#include "message.h"
-#include "../QGlib/signal.h"
+#include "../QGlib/Signal"
#include <gst/gst.h>
#include <QtCore/QObject>
#include <QtCore/QTimerEvent>
diff --git a/src/QGst/bus.h b/src/QGst/bus.h
index ec4e683..30c5fcb 100644
--- a/src/QGst/bus.h
+++ b/src/QGst/bus.h
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/src/QGst/caps.cpp b/src/QGst/caps.cpp
index 0be9b70..a15b701 100644
--- a/src/QGst/caps.cpp
+++ b/src/QGst/caps.cpp
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -19,15 +19,14 @@
#include "../QGlib/string_p.h"
#include "objectstore_p.h"
#include <QtCore/QDebug>
-#include <gst/gstcaps.h>
-#include <gst/gstvalue.h>
+#include <gst/gst.h>
namespace QGst {
//static
CapsPtr Caps::createSimple(const char *mediaType)
{
- return CapsPtr::wrap(gst_caps_new_simple(mediaType, NULL), false);
+ return CapsPtr::wrap(gst_caps_new_empty_simple(mediaType), false);
}
//static
@@ -55,12 +54,13 @@ QString Caps::toString() const
void Caps::append(const CapsPtr & caps2)
{
- gst_caps_append(object<GstCaps>(), gst_caps_copy(caps2));
+ const GstCaps * caps2ptr = caps2;
+ gst_caps_append(object<GstCaps>(), gst_caps_copy(caps2ptr));
}
-void Caps::merge(const CapsPtr & caps2)
+CapsPtr Caps::merge(CapsPtr & caps2)
{
- gst_caps_merge(object<GstCaps>(), gst_caps_copy(caps2));
+ return CapsPtr::wrap(gst_caps_merge(object<GstCaps>(), caps2), false);
}
void Caps::setValue(const char *field, const QGlib::Value & value)
@@ -70,12 +70,12 @@ void Caps::setValue(const char *field, const QGlib::Value & value)
bool Caps::simplify()
{
- return gst_caps_do_simplify(object<GstCaps>());
+ return gst_caps_simplify(object<GstCaps>());
}
-void Caps::truncate()
+CapsPtr Caps::truncate()
{
- gst_caps_truncate(object<GstCaps>());
+ return CapsPtr::wrap(gst_caps_truncate(object<GstCaps>()), false);
}
StructurePtr Caps::internalStructure(uint index)
@@ -89,9 +89,9 @@ void Caps::appendStructure(const Structure & structure)
gst_caps_append_structure(object<GstCaps>(), gst_structure_copy(structure));
}
-void Caps::mergeStructure(const Structure & structure)
+CapsPtr Caps::mergeStructure(Structure & structure)
{
- gst_caps_merge_structure(object<GstCaps>(), gst_structure_copy(structure));
+ return CapsPtr::wrap(gst_caps_merge_structure(object<GstCaps>(), structure), false);
}
void Caps::removeStructure(uint index)
@@ -124,11 +124,6 @@ bool Caps::isFixed() const
return gst_caps_is_fixed(object<GstCaps>());
}
-bool Caps::isWritable() const
-{
- return (GST_CAPS_REFCOUNT_VALUE(object<GstCaps>()) == 1);
-}
-
bool Caps::equals(const CapsPtr & caps2) const
{
return gst_caps_is_equal(object<GstCaps>(), caps2);
@@ -154,12 +149,7 @@ CapsPtr Caps::getIntersection(const CapsPtr & caps2) const
return CapsPtr::wrap(gst_caps_intersect(object<GstCaps>(), caps2), false);
}
-CapsPtr Caps::getUnion(const CapsPtr & caps2) const
-{
- return CapsPtr::wrap(gst_caps_union(object<GstCaps>(), caps2), false);
-}
-
-CapsPtr Caps::getNormal() const
+CapsPtr Caps::getNormal()
{
return CapsPtr::wrap(gst_caps_normalize(object<GstCaps>()), false);
}
@@ -179,51 +169,10 @@ CapsPtr Caps::copyNth(uint index) const
return CapsPtr::wrap(gst_caps_copy_nth(object<GstCaps>(), index), false);
}
-void Caps::ref(bool increaseRef)
-{
- if (Private::ObjectStore::put(this)) {
- if (increaseRef) {
- gst_caps_ref(GST_CAPS(m_object));
- }
- }
-}
-
-void Caps::unref()
-{
- if (Private::ObjectStore::take(this)) {
- gst_caps_unref(GST_CAPS(m_object));
- delete this;
- }
-}
-
-CapsPtr Caps::makeWritable() const
-{
- /*
- * Calling gst_*_make_writable() below is tempting but wrong.
- * Since MiniObjects and Caps do not share the same C++ instance in various wrappings, calling
- * gst_*_make_writable() on an already writable object and wrapping the result is wrong,
- * since it would just return the same pointer and we would wrap it in a new C++ instance.
- */
- if (!isWritable()) {
- return copy();
- } else {
- return CapsPtr(const_cast<Caps*>(this));
- }
-}
-
QDebug operator<<(QDebug debug, const CapsPtr & caps)
{
debug.nospace() << "QGst::Caps(" << caps->toString() << ")";
return debug.space();
}
-
-namespace Private {
-
-QGlib::RefCountedObject *wrapCaps(void *caps)
-{
- return QGlib::constructWrapper(GST_CAPS(caps)->type, caps);
-}
-
-} //namespace Private
} //namespace QGst
diff --git a/src/QGst/caps.h b/src/QGst/caps.h
index ec9aa29..741e97a 100644
--- a/src/QGst/caps.h
+++ b/src/QGst/caps.h
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -18,6 +18,7 @@
#define QGST_CAPS_H
#include "global.h"
+#include "miniobject.h"
#include "../QGlib/value.h"
#include "../QGlib/refpointer.h"
#include "../QGlib/type.h"
@@ -27,7 +28,7 @@ namespace QGst {
/*! \headerfile caps.h <QGst/Caps>
* \brief Wrapper class for GstCaps
*/
-class QTGSTREAMER_EXPORT Caps : public QGlib::RefCountedObject
+class QTGSTREAMER_EXPORT Caps : public QGst::MiniObject
{
QGST_WRAPPER(Caps)
public:
@@ -40,17 +41,17 @@ public:
QString toString() const;
void append(const CapsPtr & caps2);
- void merge(const CapsPtr & caps2);
+ CapsPtr merge(CapsPtr & caps2);
template <typename T>
inline void setValue(const char *field, const T & value);
void setValue(const char *field, const QGlib::Value & value);
bool simplify();
- void truncate();
+ CapsPtr truncate();
StructurePtr internalStructure(uint index);
void appendStructure(const Structure & structure);
- void mergeStructure(const Structure & structure);
+ CapsPtr mergeStructure(Structure & structure);
void removeStructure(uint index);
uint size() const;
@@ -63,19 +64,13 @@ public:
bool isSubsetOf(const CapsPtr & superset) const;
bool canIntersect(const CapsPtr & caps2) const;
CapsPtr getIntersection(const CapsPtr & caps2) const;
- CapsPtr getUnion(const CapsPtr & caps2) const;
- CapsPtr getNormal() const;
+ CapsPtr getNormal();
CapsPtr subtract(const CapsPtr & subtrahend) const;
CapsPtr copy() const;
CapsPtr copyNth(uint index) const;
- bool isWritable() const;
- CapsPtr makeWritable() const;
-
-protected:
- virtual void ref(bool increaseRef);
- virtual void unref();
+ inline CapsPtr makeWritable() const;
};
template <typename T>
@@ -90,18 +85,17 @@ inline CapsPtr Caps::fromString(const QString & string)
return fromString(string.toUtf8().constData());
}
+inline CapsPtr Caps::makeWritable() const
+{
+ return MiniObject::makeWritable().staticCast<Caps>();
+}
+
/*! \relates QGst::Caps */
QTGSTREAMER_EXPORT QDebug operator<<(QDebug debug, const CapsPtr & caps);
-namespace Private {
-
-QTGSTREAMER_EXPORT QGlib::RefCountedObject *wrapCaps(void *caps);
-
-} //namespace Private
} //namespace QGst
QGST_REGISTER_TYPE(QGst::Caps)
-QGLIB_REGISTER_WRAPIMPL_FOR_SUBCLASSES_OF(QGst::Caps, QGst::Private::wrapCaps)
#endif
diff --git a/src/QGst/childproxy.cpp b/src/QGst/childproxy.cpp
index 6434ae4..faa1aaa 100644
--- a/src/QGst/childproxy.cpp
+++ b/src/QGst/childproxy.cpp
@@ -9,14 +9,13 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
*/
#include "childproxy.h"
-#include <gst/gstobject.h>
-#include <gst/gstchildproxy.h>
+#include <gst/gst.h>
namespace QGst {
@@ -25,23 +24,24 @@ uint ChildProxy::childrenCount() const
return gst_child_proxy_get_children_count(object<GstChildProxy>());
}
-ObjectPtr ChildProxy::childByName(const char *name) const
+QGlib::ObjectPtr ChildProxy::childByName(const char *name) const
{
- return ObjectPtr::wrap(gst_child_proxy_get_child_by_name(object<GstChildProxy>(), name), false);
+ return QGlib::ObjectPtr::wrap(gst_child_proxy_get_child_by_name(object<GstChildProxy>(), name), false);
}
-ObjectPtr ChildProxy::childByIndex(uint index) const
+QGlib::ObjectPtr ChildProxy::childByIndex(uint index) const
{
- return ObjectPtr::wrap(gst_child_proxy_get_child_by_index(object<GstChildProxy>(), index), false);
+ return QGlib::ObjectPtr::wrap(gst_child_proxy_get_child_by_index(object<GstChildProxy>(), index), false);
}
-bool ChildProxy::findChildProperty(const char *name, ObjectPtr *obj, QGlib::ParamSpecPtr *paramSpec) const
+bool ChildProxy::findChildProperty(const char *name, QGlib::ObjectPtr *obj,
+ QGlib::ParamSpecPtr *paramSpec) const
{
- GstObject *op;
+ GObject *op;
GParamSpec *pp;
- bool result = gst_child_proxy_lookup(object<GstObject>(), name, &op, &pp);
+ bool result = gst_child_proxy_lookup(object<GstChildProxy>(), name, &op, &pp);
if (result) {
- *obj = ObjectPtr::wrap(op, false);
+ *obj = QGlib::ObjectPtr::wrap(op, false);
*paramSpec = QGlib::ParamSpecPtr::wrap(pp, false);
}
return result;
@@ -50,7 +50,7 @@ bool ChildProxy::findChildProperty(const char *name, ObjectPtr *obj, QGlib::Para
QGlib::Value ChildProxy::childProperty(const char *name) const
{
QGlib::ParamSpecPtr param;
- ObjectPtr object;
+ QGlib::ObjectPtr object;
if (findChildProperty(name, &object, &param)) {
return object->property(param->name().toUtf8());
} else {
@@ -58,4 +58,4 @@ QGlib::Value ChildProxy::childProperty(const char *name) const
}
}
-} \ No newline at end of file
+}
diff --git a/src/QGst/childproxy.h b/src/QGst/childproxy.h
index 9003437..945ea33 100644
--- a/src/QGst/childproxy.h
+++ b/src/QGst/childproxy.h
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -29,10 +29,11 @@ class QTGSTREAMER_EXPORT ChildProxy : public QGlib::Interface
QGST_WRAPPER(ChildProxy)
public:
uint childrenCount() const;
- ObjectPtr childByName(const char *name) const;
- ObjectPtr childByIndex(uint index) const;
+ QGlib::ObjectPtr childByName(const char *name) const;
+ QGlib::ObjectPtr childByIndex(uint index) const;
- bool findChildProperty(const char *name, ObjectPtr *object, QGlib::ParamSpecPtr *paramSpec) const;
+ bool findChildProperty(const char *name, QGlib::ObjectPtr *object,
+ QGlib::ParamSpecPtr *paramSpec) const;
QGlib::Value childProperty(const char *name) const;
template <typename T> void setChildProperty(const char *name, const T & value);
};
@@ -41,7 +42,7 @@ template <typename T>
void ChildProxy::setChildProperty(const char *name, const T & value)
{
QGlib::ParamSpecPtr param;
- ObjectPtr object;
+ QGlib::ObjectPtr object;
if (findChildProperty(name, &object, &param)) {
QGlib::Value v;
v.init(param->valueType());
diff --git a/src/QGst/clock.cpp b/src/QGst/clock.cpp
index 848f94b..e129c8e 100644
--- a/src/QGst/clock.cpp
+++ b/src/QGst/clock.cpp
@@ -10,7 +10,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -18,8 +18,7 @@
#include "clock.h"
#include <QtCore/QTime>
-#include <gst/gstclock.h>
-#include <gst/gstsystemclock.h>
+#include <gst/gst.h>
namespace QGst {
diff --git a/src/QGst/clock.h b/src/QGst/clock.h
index c6a3734..54389b1 100644
--- a/src/QGst/clock.h
+++ b/src/QGst/clock.h
@@ -10,7 +10,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/src/QGst/clocktime.cpp b/src/QGst/clocktime.cpp
index 3b23ee8..ae75d2c 100644
--- a/src/QGst/clocktime.cpp
+++ b/src/QGst/clocktime.cpp
@@ -10,7 +10,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -18,7 +18,7 @@
#include "clocktime.h"
#include <QtCore/QTime>
-#include <gst/gstclock.h>
+#include <gst/gst.h>
namespace QGst {
diff --git a/src/QGst/clocktime.h b/src/QGst/clocktime.h
index ea3ced6..19c68af 100644
--- a/src/QGst/clocktime.h
+++ b/src/QGst/clocktime.h
@@ -10,7 +10,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -55,10 +55,35 @@ public:
/*! Creates a ClockTime from a QTime */
static ClockTime fromTime(const QTime & time);
+ /*! Creates a ClockTime from seconds */
+ inline static ClockTime fromSeconds(quint64 seconds);
+
+ /*! Creates a ClockTime from milli seconds */
+ inline static ClockTime fromMSecs(quint64 msec);
+
+ /*! Creates a ClockTime from micro seconds */
+ inline static ClockTime fromUSecs(quint64 usec);
+
private:
quint64 m_clocktime;
};
+inline ClockTime ClockTime::fromSeconds(quint64 seconds)
+{
+ return ClockTime(seconds * 1000 * 1000 * 1000);
+}
+
+inline ClockTime ClockTime::fromMSecs(quint64 msec)
+{
+ return ClockTime(msec * 1000 * 1000);
+}
+
+inline ClockTime ClockTime::fromUSecs(quint64 usec)
+{
+ return ClockTime(usec * 1000);
+}
+
+
} //namspace QGst
QGST_REGISTER_TYPE(QGst::ClockTime)
diff --git a/src/QGst/colorbalance.cpp b/src/QGst/colorbalance.cpp
index d83fb62..b2185aa 100644
--- a/src/QGst/colorbalance.cpp
+++ b/src/QGst/colorbalance.cpp
@@ -9,13 +9,13 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
*/
#include "colorbalance.h"
-#include <gst/interfaces/colorbalance.h>
+#include <gst/video/colorbalance.h>
namespace QGst {
diff --git a/src/QGst/colorbalance.h b/src/QGst/colorbalance.h
index bece181..fff9b3a 100644
--- a/src/QGst/colorbalance.h
+++ b/src/QGst/colorbalance.h
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/src/QGst/device.cpp b/src/QGst/device.cpp
new file mode 100644
index 0000000..2efb912
--- /dev/null
+++ b/src/QGst/device.cpp
@@ -0,0 +1,60 @@
+/*
+ Copyright (C) 2015 Pavel Bludov <pbludov@gmail.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#include "device.h"
+#include "caps.h"
+#include "element.h"
+#include "../QGlib/string_p.h"
+#include <QtCore/QDebug>
+#include <gst/gst.h>
+
+namespace QGst {
+
+ElementPtr Device::createElement(const char* name) const
+{
+ GstElement *e = gst_device_create_element(object<GstDevice>(), name);
+ if (e) {
+ gst_object_ref_sink(e);
+ }
+ return ElementPtr::wrap(e, false);
+}
+
+CapsPtr Device::caps() const
+{
+ return CapsPtr::wrap(gst_device_get_caps(object<GstDevice>()), false);
+}
+
+QString Device::deviceClass() const
+{
+ return QGlib::Private::stringFromGCharPtr(gst_device_get_device_class(object<GstDevice>()));
+}
+
+QString Device::displayName() const
+{
+ return QGlib::Private::stringFromGCharPtr(gst_device_get_display_name(object<GstDevice>()));
+}
+
+bool Device::hasClasses(const char *classes) const
+{
+ return gst_device_has_classes(object<GstDevice>(), classes);
+}
+
+bool Device::reconfigureElement(const ElementPtr & element) const
+{
+ return gst_device_reconfigure_element(object<GstDevice>(), element);
+}
+
+} //namespace QGst
diff --git a/src/QGst/device.h b/src/QGst/device.h
new file mode 100644
index 0000000..e1692d5
--- /dev/null
+++ b/src/QGst/device.h
@@ -0,0 +1,50 @@
+/*
+ Copyright (C) 2015 Pavel Bludov <pbludov@gmail.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#ifndef QGST_DEVICE_H
+#define QGST_DEVICE_H
+
+#include "object.h"
+
+namespace QGst {
+
+ /*! \headerfile device.h <QGst/Device>
+ * \brief Wrapper class for GstDevice
+ *
+ * Device are objects representing a hardware device, they contain relevant
+ * metadata about the device, such as its class and the Caps representing
+ * the media types it can produce or handle.
+ *
+ */
+class QTGSTREAMER_EXPORT Device : public Object
+{
+ QGST_WRAPPER(Device)
+public:
+ QString displayName() const;
+ CapsPtr caps() const;
+
+ ElementPtr createElement(const char* name) const;
+ bool reconfigureElement(const ElementPtr & element) const;
+
+ QString deviceClass() const;
+ bool hasClasses(const char *classes) const;
+};
+
+} //namespace QGst
+
+QGST_REGISTER_TYPE(QGst::Device)
+
+#endif
diff --git a/src/QGst/devicemonitor.cpp b/src/QGst/devicemonitor.cpp
new file mode 100644
index 0000000..d424e56
--- /dev/null
+++ b/src/QGst/devicemonitor.cpp
@@ -0,0 +1,71 @@
+/*
+ Copyright (C) 2015 Pavel Bludov <pbludov@gmail.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#include "global.h"
+#include "devicemonitor.h"
+#include <gst/gst.h>
+
+namespace QGst {
+
+//static
+DeviceMonitorPtr DeviceMonitor::create()
+{
+ GstDeviceMonitor *m = gst_device_monitor_new();
+ if (m) {
+ gst_object_ref_sink(m);
+ }
+ return DeviceMonitorPtr::wrap(m, false);
+}
+
+BusPtr DeviceMonitor::bus() const
+{
+ return BusPtr::wrap(gst_device_monitor_get_bus(object<GstDeviceMonitor>()), false);
+}
+
+quint32 DeviceMonitor::addFilter(const char* classes, const CapsPtr & caps)
+{
+ return gst_device_monitor_add_filter(object<GstDeviceMonitor>(), classes, caps);
+}
+
+bool DeviceMonitor::removeFilter(quint32 filterId)
+{
+ return gst_device_monitor_remove_filter(object<GstDeviceMonitor>(), filterId);
+}
+
+bool DeviceMonitor::start()
+{
+ return gst_device_monitor_start(object<GstDeviceMonitor>());
+}
+
+void DeviceMonitor::stop()
+{
+ gst_device_monitor_stop(object<GstDeviceMonitor>());
+}
+
+QList<DevicePtr> DeviceMonitor::devices() const
+{
+ QList<DevicePtr> output;
+ GList *input = gst_device_monitor_get_devices(object<GstDeviceMonitor>());
+
+ while (input) {
+ output += DevicePtr::wrap(GST_DEVICE(input->data), false);
+ input = g_list_delete_link(input, input);
+ }
+
+ return output;
+}
+
+}
diff --git a/src/QGst/devicemonitor.h b/src/QGst/devicemonitor.h
new file mode 100644
index 0000000..5bb2083
--- /dev/null
+++ b/src/QGst/devicemonitor.h
@@ -0,0 +1,53 @@
+/*
+ Copyright (C) 2015 Pavel Bludov <pbludov@gmail.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#ifndef QGST_DEVICEMONITOR_H
+#define QGST_DEVICEMONITOR_H
+
+#include "bus.h"
+#include "caps.h"
+#include "device.h"
+#include "object.h"
+
+namespace QGst {
+
+/*! \headerfile devicemonitor.h <QGst/DeviceMonitor>
+ * \brief Wrapper class for GstDeviceMonitor
+ *
+ * A device monitor and prober
+ */
+class QTGSTREAMER_EXPORT DeviceMonitor : public Object
+{
+ QGST_WRAPPER(DeviceMonitor)
+public:
+ static DeviceMonitorPtr create();
+
+ BusPtr bus() const;
+
+ quint32 addFilter(const char* classes, const CapsPtr & caps);
+ bool removeFilter(quint32 filterId);
+
+ bool start();
+ void stop();
+
+ QList<DevicePtr> devices() const;
+};
+
+}
+
+QGST_REGISTER_TYPE(QGst::DeviceMonitor)
+
+#endif
diff --git a/src/QGst/discoverer.cpp b/src/QGst/discoverer.cpp
new file mode 100644
index 0000000..09999e9
--- /dev/null
+++ b/src/QGst/discoverer.cpp
@@ -0,0 +1,426 @@
+/*
+ Copyright (C) 2012 Openismus GmbH
+ @author Mathias Hasselmann <mathias@openismus.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#include "discoverer.h"
+
+#include <QGlib/Error>
+#include <QGst/Caps>
+
+#include <gst/pbutils/gstdiscoverer.h>
+
+namespace QGst {
+
+static QList<DiscovererStreamInfoPtr> wrapStreamInfoList(GList *input, bool increaseRef)
+{
+ QList<DiscovererStreamInfoPtr> output;
+
+ while(input) {
+ output += DiscovererStreamInfoPtr::wrap(GST_DISCOVERER_STREAM_INFO(input->data), increaseRef);
+ input = g_list_delete_link(input, input);
+ }
+
+ return output;
+}
+
+DiscovererStreamInfoPtr DiscovererStreamInfo::previous() const
+{
+ return DiscovererStreamInfoPtr::wrap(gst_discoverer_stream_info_get_previous(object<GstDiscovererStreamInfo>()), false);
+}
+
+DiscovererStreamInfoPtr DiscovererStreamInfo::next() const
+{
+ return DiscovererStreamInfoPtr::wrap(gst_discoverer_stream_info_get_next(object<GstDiscovererStreamInfo>()), false);
+}
+
+QString DiscovererStreamInfo::streamTypeNick() const
+{
+ return QString::fromUtf8(gst_discoverer_stream_info_get_stream_type_nick(object<GstDiscovererStreamInfo>()));
+}
+
+CapsPtr DiscovererStreamInfo::caps() const
+{
+ return CapsPtr::wrap(gst_discoverer_stream_info_get_caps(object<GstDiscovererStreamInfo>()), false);
+}
+
+TagList DiscovererStreamInfo::tags() const
+{
+ return gst_discoverer_stream_info_get_tags(object<GstDiscovererStreamInfo>());
+}
+
+Structure DiscovererStreamInfo::misc() const
+{
+ const GstStructure *const misc = gst_discoverer_stream_info_get_misc(object<GstDiscovererStreamInfo>());
+ return misc ? Structure(misc) : Structure();
+}
+
+QList<DiscovererStreamInfoPtr> DiscovererContainerInfo::streams() const
+{
+ return wrapStreamInfoList(gst_discoverer_container_info_get_streams(object<GstDiscovererContainerInfo>()), false);
+}
+
+uint DiscovererAudioInfo::channels() const
+{
+ return gst_discoverer_audio_info_get_channels(object<GstDiscovererAudioInfo>());
+}
+
+uint DiscovererAudioInfo::sampleRate() const
+{
+ return gst_discoverer_audio_info_get_sample_rate(object<GstDiscovererAudioInfo>());
+}
+
+uint DiscovererAudioInfo::depth() const
+{
+ return gst_discoverer_audio_info_get_depth(object<GstDiscovererAudioInfo>());
+}
+
+uint DiscovererAudioInfo::bitrate() const
+{
+ return gst_discoverer_audio_info_get_bitrate(object<GstDiscovererAudioInfo>());
+}
+
+uint DiscovererAudioInfo::maxBitrate() const
+{
+ return gst_discoverer_audio_info_get_max_bitrate(object<GstDiscovererAudioInfo>());
+}
+
+QString DiscovererAudioInfo::language() const
+{
+ return QString::fromUtf8(gst_discoverer_audio_info_get_language(object<GstDiscovererAudioInfo>()));
+}
+
+uint DiscovererVideoInfo::width() const
+{
+ return gst_discoverer_video_info_get_width(object<GstDiscovererVideoInfo>());
+}
+
+uint DiscovererVideoInfo::height() const
+{
+ return gst_discoverer_video_info_get_height(object<GstDiscovererVideoInfo>());
+}
+
+uint DiscovererVideoInfo::depth() const
+{
+ return gst_discoverer_video_info_get_depth(object<GstDiscovererVideoInfo>());
+}
+
+Fraction DiscovererVideoInfo::framerate() const
+{
+ return Fraction(gst_discoverer_video_info_get_framerate_num(object<GstDiscovererVideoInfo>()),
+ gst_discoverer_video_info_get_framerate_denom(object<GstDiscovererVideoInfo>()));
+}
+
+Fraction DiscovererVideoInfo::pixelAspectRatio() const
+{
+ return Fraction(gst_discoverer_video_info_get_par_num(object<GstDiscovererVideoInfo>()),
+ gst_discoverer_video_info_get_par_denom(object<GstDiscovererVideoInfo>()));
+}
+
+uint DiscovererVideoInfo::bitrate() const
+{
+ return gst_discoverer_video_info_get_bitrate(object<GstDiscovererVideoInfo>());
+}
+
+uint DiscovererVideoInfo::maxBitrate() const
+{
+ return gst_discoverer_video_info_get_max_bitrate(object<GstDiscovererVideoInfo>());
+}
+
+bool DiscovererVideoInfo::isInterlaced() const
+{
+ return gst_discoverer_video_info_is_interlaced(object<GstDiscovererVideoInfo>());
+}
+
+bool DiscovererVideoInfo::isImage() const
+{
+ return gst_discoverer_video_info_is_image(object<GstDiscovererVideoInfo>());
+}
+
+QString DiscovererSubtitleInfo::language() const
+{
+ return QString::fromUtf8(gst_discoverer_subtitle_info_get_language(object<GstDiscovererSubtitleInfo>()));
+}
+
+QUrl DiscovererInfo::uri() const
+{
+ return QUrl::fromEncoded(gst_discoverer_info_get_uri(object<GstDiscovererInfo>()));
+}
+
+DiscovererResult DiscovererInfo::result() const
+{
+ return DiscovererResult(gst_discoverer_info_get_result(object<GstDiscovererInfo>()));
+}
+
+ClockTime DiscovererInfo::duration() const
+{
+ return gst_discoverer_info_get_duration(object<GstDiscovererInfo>());
+}
+
+bool DiscovererInfo::seekable() const
+{
+ return gst_discoverer_info_get_seekable(object<GstDiscovererInfo>());
+}
+
+Structure DiscovererInfo::misc() const
+{
+ const GstStructure *const misc = gst_discoverer_info_get_misc(object<GstDiscovererInfo>());
+ return misc ? Structure(misc) : Structure();
+}
+
+TagList DiscovererInfo::tags() const
+{
+ return gst_discoverer_info_get_tags(object<GstDiscovererInfo>());
+}
+
+DiscovererStreamInfoPtr DiscovererInfo::streamInfo() const
+{
+ return DiscovererStreamInfoPtr::wrap(gst_discoverer_info_get_stream_info(object<GstDiscovererInfo>()), false);
+}
+
+QList<DiscovererStreamInfoPtr> DiscovererInfo::streams() const
+{
+ return wrapStreamInfoList(gst_discoverer_info_get_stream_list(object<GstDiscovererInfo>()), false);
+}
+
+QList<DiscovererStreamInfoPtr> DiscovererInfo::streams(QGlib::Type streamType) const
+{
+ return wrapStreamInfoList(gst_discoverer_info_get_streams(object<GstDiscovererInfo>(), streamType), false);
+}
+
+QList<DiscovererStreamInfoPtr> DiscovererInfo::audioStreams() const
+{
+ return wrapStreamInfoList(gst_discoverer_info_get_audio_streams(object<GstDiscovererInfo>()), false);
+}
+
+QList<DiscovererStreamInfoPtr> DiscovererInfo::videoStreams() const
+{
+ return wrapStreamInfoList(gst_discoverer_info_get_video_streams(object<GstDiscovererInfo>()), false);
+}
+
+QList<DiscovererStreamInfoPtr> DiscovererInfo::subtitleStreams() const
+{
+ return wrapStreamInfoList(gst_discoverer_info_get_subtitle_streams(object<GstDiscovererInfo>()), false);
+}
+
+QList<DiscovererStreamInfoPtr> DiscovererInfo::containerStreams() const
+{
+ return wrapStreamInfoList(gst_discoverer_info_get_container_streams(object<GstDiscovererInfo>()), false);
+}
+
+DiscovererPtr Discoverer::create(ClockTime timeout)
+{
+ GError *error = NULL;
+ GstDiscoverer *discoverer = gst_discoverer_new(timeout, &error);
+ if (error) {
+ throw QGlib::Error(error);
+ }
+ if (discoverer) {
+ g_object_ref_sink(discoverer);
+ }
+ return DiscovererPtr::wrap(discoverer, false);
+}
+
+void Discoverer::start()
+{
+ gst_discoverer_start(object<GstDiscoverer>());
+}
+
+void Discoverer::stop()
+{
+ gst_discoverer_stop(object<GstDiscoverer>());
+}
+
+bool Discoverer::discoverUriAsync(const char *uri)
+{
+ return gst_discoverer_discover_uri_async(object<GstDiscoverer>(), uri);
+}
+
+DiscovererInfoPtr Discoverer::discoverUri(const char *uri)
+{
+ GError *error = NULL;
+ GstDiscovererInfo *info = gst_discoverer_discover_uri(object<GstDiscoverer>(), uri, &error);
+ if (error) {
+ throw QGlib::Error(error);
+ }
+ return DiscovererInfoPtr::wrap(info, false);
+}
+
+QDebug operator<<(QDebug debug, DiscovererResult result)
+{
+ switch(result) {
+ case DiscovererOk:
+ return debug << "QGst::DiscovererOk";
+ case DiscovererUriInvalid:
+ return debug << "QGst::DiscovererUriInvalid";
+ case DiscovererError:
+ return debug << "QGst::DiscovererError";
+ case DiscovererTimeout:
+ return debug << "QGst::DiscovererTimeout";
+ case DiscovererBusy:
+ return debug << "QGst::DiscovererBusy";
+ case DiscovererMissingPlugins:
+ return debug << "QGst::DiscovererMissingPlugins";
+ }
+
+ return (debug.nospace() << "QGst::DiscovererResult(" << uint(result) << ")").maybeSpace();
+}
+
+template <typename T>
+static const char *typeName();
+
+template <typename T>
+static QDebug printStreamInfoDetails(QDebug debug, const T &);
+
+template <>
+const char *typeName<DiscovererStreamInfoPtr>()
+{
+ return "QGst::DiscovererStreamInfoPtr";
+}
+
+template <>
+const char *typeName<DiscovererContainerInfoPtr>()
+{
+ return "QGst::DiscovererContainerInfoPtr";
+}
+
+template <>
+const char *typeName<DiscovererAudioInfoPtr>()
+{
+ return "QGst::DiscovererAudioInfoPtr";
+}
+
+template <>
+const char *typeName<DiscovererVideoInfoPtr>()
+{
+ return "QGst::DiscovererVideoInfoPtr";
+}
+
+template <>
+const char *typeName<DiscovererSubtitleInfoPtr>()
+{
+ return "QGst::DiscovererSubtitleInfoPtr";
+}
+
+template <>
+QDebug printStreamInfoDetails(QDebug debug, const DiscovererStreamInfoPtr &)
+{
+ return debug;
+}
+
+template <>
+QDebug printStreamInfoDetails(QDebug debug, const DiscovererContainerInfoPtr &info)
+{
+ return debug.nospace()
+ << ", streams=" << info->streams();
+}
+
+template <>
+QDebug printStreamInfoDetails(QDebug debug, const DiscovererAudioInfoPtr &info)
+{
+ return debug.nospace()
+ << ", channels=" << info->channels()
+ << ", sampleRate=" << info->sampleRate()
+ << ", depth=" << info->depth()
+ << ", bitrate=" << info->bitrate()
+ << ", maxBitrate=" << info->maxBitrate()
+ << ", language=" << info->language();
+}
+
+template <>
+QDebug printStreamInfoDetails(QDebug debug, const DiscovererVideoInfoPtr &info)
+{
+ return debug.nospace()
+ << ", width=" << info->width()
+ << ", height=" << info->height()
+ << ", depth=" << info->depth()
+ << ", framerate=" << info->framerate()
+ << ", pixelAspectRatio=" << info->pixelAspectRatio()
+ << ", bitrate=" << info->bitrate()
+ << ", maxBitrate=" << info->maxBitrate()
+ << ", isInterlaced=" << info->isInterlaced()
+ << ", isImage=" << info->isImage();
+}
+
+template <>
+QDebug printStreamInfoDetails(QDebug debug, const DiscovererSubtitleInfoPtr &info)
+{
+ return debug.nospace()
+ << ", language=" << info->language();
+}
+
+template <typename T>
+static QDebug printStreamInfo(QDebug debug, const T &info)
+{
+ debug.nospace() << typeName<T>() << "(";
+
+ if (info) {
+ debug.nospace() << info->streamTypeNick()
+ << ", caps=" << info->caps();
+ debug.nospace() << ", tags=" << info->tags();
+ debug.nospace() << ", misc=" << info->misc();
+ debug.nospace() << ", hasPrevious=" << !info->previous().isNull();
+ debug.nospace() << ", hasNext=" << !info->next().isNull();
+ debug = printStreamInfoDetails(debug, info);
+ } else {
+ debug << "<null>";
+ }
+
+ return (debug << ")").maybeSpace();
+}
+
+QDebug operator<<(QDebug debug, const DiscovererStreamInfoPtr &info)
+{
+ if (const DiscovererContainerInfoPtr containerInfo = info.dynamicCast<DiscovererContainerInfo>()) {
+ return printStreamInfo(debug, containerInfo);
+ }
+ if (const DiscovererAudioInfoPtr audioInfo = info.dynamicCast<DiscovererAudioInfo>()) {
+ return printStreamInfo(debug, audioInfo);
+ }
+ if (const DiscovererVideoInfoPtr videoInfo = info.dynamicCast<DiscovererVideoInfo>()) {
+ return printStreamInfo(debug, videoInfo);
+ }
+ if (const DiscovererSubtitleInfoPtr subtitleInfo = info.dynamicCast<DiscovererSubtitleInfo>()) {
+ return printStreamInfo(debug, subtitleInfo);
+ }
+
+ return printStreamInfo(debug, info);
+}
+
+QDebug operator<<(QDebug debug, const DiscovererInfoPtr &info)
+{
+ debug.nospace() << "QGst::DiscovererInfoPtr(";
+
+ if (info) {
+ debug.nospace() << "result=" << info->result()
+ << ", uri=" << info->uri()
+ << ", duration=" << info->duration()
+ << ", seekable=" << info->seekable()
+ << ", misc=" << info->misc();
+ debug.nospace() << ", tags=" << info->tags();
+ debug.nospace() << ", streamInfo=" << info->streamInfo();
+ debug.nospace() << ", streams=" << info->streams();
+ debug.nospace() << ", audioStreams=" << info->audioStreams();
+ debug.nospace() << ", videoStreams=" << info->videoStreams();
+ debug.nospace() << ", subtitleStreams=" << info->subtitleStreams();
+ debug.nospace() << ", containerStreams=" << info->containerStreams();
+ } else {
+ debug << "<null>";
+ }
+
+ return (debug << ")").maybeSpace();
+}
+
+} // namespace QGst
diff --git a/src/QGst/discoverer.h b/src/QGst/discoverer.h
new file mode 100644
index 0000000..a8abee6
--- /dev/null
+++ b/src/QGst/discoverer.h
@@ -0,0 +1,180 @@
+/*
+ Copyright (C) 2012 Openismus GmbH
+ @author Mathias Hasselmann <mathias@openismus.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#ifndef QGST_DISCOVERER_H
+#define QGST_DISCOVERER_H
+
+#include <QGst/ClockTime>
+#include <QGst/Fraction>
+#include <QGst/MiniObject>
+#include <QGst/Object>
+#include <QGst/Structure>
+#include <QGst/TagList>
+
+#include <QtCore/QUrl>
+
+#include "global.h"
+
+namespace QGst {
+
+class QTGSTREAMER_EXPORT DiscovererStreamInfo : public QGlib::Object
+{
+ QGST_WRAPPER(DiscovererStreamInfo)
+
+public:
+ DiscovererStreamInfoPtr previous() const;
+ DiscovererStreamInfoPtr next() const;
+ QString streamTypeNick() const;
+ CapsPtr caps() const;
+ TagList tags() const;
+ Structure misc() const;
+};
+
+class QTGSTREAMER_EXPORT DiscovererContainerInfo : public DiscovererStreamInfo
+{
+ QGST_WRAPPER(DiscovererContainerInfo)
+
+public:
+ QList<DiscovererStreamInfoPtr> streams() const;
+};
+
+class QTGSTREAMER_EXPORT DiscovererAudioInfo : public DiscovererStreamInfo
+{
+ QGST_WRAPPER(DiscovererAudioInfo)
+
+public:
+ uint channels() const;
+ uint sampleRate() const;
+ uint depth() const;
+ uint bitrate() const;
+ uint maxBitrate() const;
+ QString language() const;
+};
+
+class QTGSTREAMER_EXPORT DiscovererVideoInfo : public DiscovererStreamInfo
+{
+ QGST_WRAPPER(DiscovererVideoInfo)
+
+public:
+ uint width() const;
+ uint height() const;
+ uint depth() const;
+ Fraction framerate() const;
+ Fraction pixelAspectRatio() const;
+ uint bitrate() const;
+ uint maxBitrate() const;
+ bool isInterlaced() const;
+ bool isImage() const;
+};
+
+class QTGSTREAMER_EXPORT DiscovererSubtitleInfo : public DiscovererStreamInfo
+{
+ QGST_WRAPPER(DiscovererSubtitleInfo)
+
+public:
+ QString language() const;
+};
+
+class QTGSTREAMER_EXPORT DiscovererInfo : public QGlib::Object
+{
+ QGST_WRAPPER(DiscovererInfo)
+
+public:
+ QUrl uri() const;
+ DiscovererResult result() const;
+
+ ClockTime duration() const;
+ bool seekable() const;
+ Structure misc() const;
+ TagList tags() const;
+
+ DiscovererStreamInfoPtr streamInfo() const;
+ QList<DiscovererStreamInfoPtr> streams() const;
+ QList<DiscovererStreamInfoPtr> streams(QGlib::Type streamType) const;
+ QList<DiscovererStreamInfoPtr> audioStreams() const;
+ QList<DiscovererStreamInfoPtr> videoStreams() const;
+ QList<DiscovererStreamInfoPtr> subtitleStreams() const;
+ QList<DiscovererStreamInfoPtr> containerStreams() const;
+};
+
+class QTGSTREAMER_EXPORT Discoverer : public QGlib::Object
+{
+ QGST_WRAPPER(Discoverer)
+
+public:
+ /*! Creates a new discoverer with the provided timeout.
+ * \throws QGlib::Error when there was a problem creating the discoverer
+ */
+ static DiscovererPtr create(ClockTime timeout);
+
+ /*! Allow asynchronous discovering of URIs to take place.
+ * \note A GLib event loop must be available for QGst::Discoverer to work
+ * properly in asynchronous mode. This feature might not be available on all
+ * platforms supported by Qt.
+ * \ingroup async
+ */
+ void start();
+
+ /*! Stop the discovery of any pending URIs and clears the list of pending URIS (if any).
+ * \ingroup async
+ */
+ void stop();
+
+ /*! Appends the given \param uri to the list of URIs to discoverer.
+ * The actual discovery of the \param uri will only take place if start() has been called.
+ * \ingroup async
+ */
+ bool discoverUriAsync(const char *uri);
+
+ /*! \overload */
+ inline bool discoverUriAsync(const QUrl &uri);
+
+ /*! Synchronously discovers the given \param uri.
+ * \throws QGlib::Error if an error occurred
+ * \ingroup sync
+ */
+ DiscovererInfoPtr discoverUri(const char *uri);
+
+ /*! \overload */
+ inline DiscovererInfoPtr discoverUri(const QUrl &uri);
+};
+
+inline bool Discoverer::discoverUriAsync(const QUrl &uri)
+{
+ return discoverUriAsync(uri.toEncoded().constData());
+}
+
+inline DiscovererInfoPtr Discoverer::discoverUri(const QUrl &uri)
+{
+ return discoverUri(uri.toEncoded().constData());
+}
+
+QTGSTREAMER_EXPORT QDebug operator<<(QDebug debug, DiscovererResult result);
+QTGSTREAMER_EXPORT QDebug operator<<(QDebug debug, const DiscovererStreamInfoPtr &info);
+QTGSTREAMER_EXPORT QDebug operator<<(QDebug debug, const DiscovererInfoPtr &info);
+
+} // namespace QGst
+
+QGST_REGISTER_TYPE(QGst::DiscovererStreamInfo)
+QGST_REGISTER_TYPE(QGst::DiscovererContainerInfo)
+QGST_REGISTER_TYPE(QGst::DiscovererAudioInfo)
+QGST_REGISTER_TYPE(QGst::DiscovererVideoInfo)
+QGST_REGISTER_TYPE(QGst::DiscovererSubtitleInfo)
+QGST_REGISTER_TYPE(QGst::DiscovererInfo)
+QGST_REGISTER_TYPE(QGst::Discoverer)
+
+#endif // QGST_DISCOVERER_H
diff --git a/src/QGst/element.cpp b/src/QGst/element.cpp
index a41ff7a..95b3aca 100644
--- a/src/QGst/element.cpp
+++ b/src/QGst/element.cpp
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -19,8 +19,7 @@
#include "query.h"
#include "clock.h"
#include "event.h"
-#include <gst/gstelement.h>
-#include <gst/gstutils.h>
+#include <gst/gst.h>
namespace QGst {
@@ -155,11 +154,7 @@ bool Element::query(const QueryPtr & query)
ClockPtr Element::clock() const
{
- if (gst_element_provides_clock(object<GstElement>())) {
- return ClockPtr::wrap(gst_element_get_clock(object<GstElement>()), false);
- } else {
- return ClockPtr();
- }
+ return ClockPtr::wrap(gst_element_get_clock(object<GstElement>()), false);
}
bool Element::setClock(const ClockPtr & clock)
diff --git a/src/QGst/element.h b/src/QGst/element.h
index c5bd104..fee88fa 100644
--- a/src/QGst/element.h
+++ b/src/QGst/element.h
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/src/QGst/elementfactory.cpp b/src/QGst/elementfactory.cpp
index cb1d487..a2b687c 100644
--- a/src/QGst/elementfactory.cpp
+++ b/src/QGst/elementfactory.cpp
@@ -9,16 +9,14 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
*/
#include "elementfactory.h"
#include "element.h"
-#include <gst/gstelement.h>
-#include <gst/gstelementfactory.h>
-#include <gst/gstutils.h>
+#include <gst/gst.h>
namespace QGst {
@@ -43,34 +41,9 @@ QGlib::Type ElementFactory::elementType() const
return gst_element_factory_get_element_type(object<GstElementFactory>());
}
-QString ElementFactory::longName() const
+QString ElementFactory::metadata(const char *key) const
{
- return QString::fromUtf8(gst_element_factory_get_longname(object<GstElementFactory>()));
-}
-
-QString ElementFactory::klass() const
-{
- return QString::fromUtf8(gst_element_factory_get_klass(object<GstElementFactory>()));
-}
-
-QString ElementFactory::description() const
-{
- return QString::fromUtf8(gst_element_factory_get_description(object<GstElementFactory>()));
-}
-
-QString ElementFactory::author() const
-{
- return QString::fromUtf8(gst_element_factory_get_author(object<GstElementFactory>()));
-}
-
-QString ElementFactory::documentationUri() const
-{
- return QString::fromUtf8(gst_element_factory_get_documentation_uri(object<GstElementFactory>()));
-}
-
-QString ElementFactory::iconName() const
-{
- return QString::fromUtf8(gst_element_factory_get_icon_name(object<GstElementFactory>()));
+ return QString::fromUtf8(gst_element_factory_get_metadata(object<GstElementFactory>(), key));
}
uint ElementFactory::padTemplatesCount() const
@@ -88,14 +61,24 @@ bool ElementFactory::hasInterface(const char *interfaceName) const
return gst_element_factory_has_interface(object<GstElementFactory>(), interfaceName);
}
-bool ElementFactory::canSinkCaps(const CapsPtr & caps) const
+bool ElementFactory::canSinkAllCaps(const CapsPtr & caps) const
+{
+ return gst_element_factory_can_sink_all_caps(object<GstElementFactory>(), caps);
+}
+
+bool ElementFactory::canSrcAllCaps(const CapsPtr & caps) const
+{
+ return gst_element_factory_can_src_all_caps(object<GstElementFactory>(), caps);
+}
+
+bool ElementFactory::canSinkAnyCaps(const CapsPtr & caps) const
{
- return gst_element_factory_can_sink_caps(object<GstElementFactory>(), caps);
+ return gst_element_factory_can_sink_any_caps(object<GstElementFactory>(), caps);
}
-bool ElementFactory::canSrcCaps(const CapsPtr & caps) const
+bool ElementFactory::canSrcAnyCaps(const CapsPtr & caps) const
{
- return gst_element_factory_can_src_caps(object<GstElementFactory>(), caps);
+ return gst_element_factory_can_src_any_caps(object<GstElementFactory>(), caps);
}
ElementPtr ElementFactory::create(const char *elementName) const
diff --git a/src/QGst/elementfactory.h b/src/QGst/elementfactory.h
index 9c1552f..7bc778e 100644
--- a/src/QGst/elementfactory.h
+++ b/src/QGst/elementfactory.h
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -36,18 +36,15 @@ public:
static inline ElementPtr make(const QString & factoryName, const char *elementName = NULL);
QGlib::Type elementType() const;
- QString longName() const;
- QString klass() const;
- QString description() const;
- QString author() const;
- QString documentationUri() const;
- QString iconName() const;
+ QString metadata(const char *key) const;
uint padTemplatesCount() const;
int uriType() const;
bool hasInterface(const char *interfaceName) const;
- bool canSinkCaps(const CapsPtr & caps) const;
- bool canSrcCaps(const CapsPtr & caps) const;
+ bool canSinkAllCaps(const CapsPtr & caps) const;
+ bool canSrcAllCaps(const CapsPtr & caps) const;
+ bool canSinkAnyCaps(const CapsPtr & caps) const;
+ bool canSrcAnyCaps(const CapsPtr & caps) const;
ElementPtr create(const char *elementName = NULL) const;
};
diff --git a/src/QGst/enums.h b/src/QGst/enums.h
index 706309b..6cd0d71 100644
--- a/src/QGst/enums.h
+++ b/src/QGst/enums.h
@@ -11,7 +11,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -24,7 +24,8 @@
namespace QGst {
enum MiniObjectFlag {
- MiniObjectFlagReadonly = (1<<0),
+ MiniObjectFlagLockable = (1<<0),
+ MiniObjectFlagLockReadonly = (1<<1),
/*padding*/
MiniObjectFlagLast = (1<<4)
};
@@ -36,8 +37,6 @@ QGST_REGISTER_TYPE(QGst::MiniObjectFlags);
namespace QGst {
enum ObjectFlag {
- ObjectDisposing = (1<<0),
- ObjectFloating = (1<<1),
/*padding*/
ObjectFlagLast = (1<<4)
};
@@ -92,14 +91,19 @@ QGST_REGISTER_TYPE(QGst::PadDirection)
namespace QGst {
enum PadFlag {
- //codegen: PadInGetCaps=PAD_IN_GETCAPS, PadInSetCaps=PAD_IN_SETCAPS
- PadBlocked = (ObjectFlagLast << 0),
- PadFlushing = (ObjectFlagLast << 1),
- PadInGetCaps = (ObjectFlagLast << 2),
- PadInSetCaps = (ObjectFlagLast << 3),
- PadBlocking = (ObjectFlagLast << 4),
+ PadFlagBlocked = (ObjectFlagLast << 0),
+ PadFlagFlushing = (ObjectFlagLast << 1),
+ PadFlagEos = (ObjectFlagLast << 2),
+ PadFlagBlocking = (ObjectFlagLast << 3),
+ PadFlagNeedParent = (ObjectFlagLast << 4),
+ PadFlagNeedReconfigure = (ObjectFlagLast << 5),
+ PadFlagPendingEvents = (ObjectFlagLast << 6),
+ PadFlagFixedCaps = (ObjectFlagLast << 7),
+ PadFlagProxyCaps = (ObjectFlagLast << 8),
+ PadFlagProxyAllocation = (ObjectFlagLast << 9),
+ PadFlagProxyScheduling = (ObjectFlagLast << 10),
/*padding*/
- PadFlagLast = (ObjectFlagLast << 8)
+ PadFlagLast = (ObjectFlagLast << 16)
};
Q_DECLARE_FLAGS(PadFlags, PadFlag);
Q_DECLARE_OPERATORS_FOR_FLAGS(PadFlags);
@@ -122,28 +126,32 @@ QGST_REGISTER_TYPE(QGst::PadLinkReturn)
namespace QGst {
enum FlowReturn {
+ //codegen: FlowCustomSuccess2=FLOW_CUSTOM_SUCCESS_2, FlowCustomSuccess1=FLOW_CUSTOM_SUCCESS_1, FlowCustomError1=FLOW_CUSTOM_ERROR_1, FlowCustomError2=FLOW_CUSTOM_ERROR_2
+ FlowCustomSuccess2 = 102,
+ FlowCustomSuccess1 = 101,
FlowCustomSuccess = 100,
- FlowResend = 1,
FlowOk = 0,
FlowNotLinked = -1,
- FlowWrongState = -2,
- FlowUnexpected = -3,
+ FlowFlushing = -2,
+ FlowEos = -3,
FlowNotNegotiated = -4,
FlowError = -5,
FlowNotSupported = -6,
- FlowCustomError = -100
+ FlowCustomError = -100,
+ FlowCustomError1 = -101,
+ FlowCustomError2 = -102
};
}
QGST_REGISTER_TYPE(QGst::FlowReturn)
namespace QGst {
- enum ActivateMode {
- ActivateNone,
- ActivatePush,
- ActivatePull
+ enum PadMode {
+ PadModeNone,
+ PadModePush,
+ PadModePull
};
}
-QGST_REGISTER_TYPE(QGst::ActivateMode)
+QGST_REGISTER_TYPE(QGst::PadMode)
namespace QGst {
@@ -178,13 +186,22 @@ namespace QGst {
MessageElement = (1 << 15),
MessageSegmentStart = (1 << 16),
MessageSegmentDone = (1 << 17),
- MessageDuration = (1 << 18),
+ MessageDurationChanged = (1 << 18),
MessageLatency = (1 << 19),
MessageAsyncStart = (1 << 20),
MessageAsyncDone = (1 << 21),
MessageRequestState = (1 << 22),
MessageStepStart = (1 << 23),
MessageQos = (1 << 24),
+ MessageProgress = (1 << 25),
+ MessageToc = (1 << 26),
+ MessageResetTime = (1 << 27),
+ MessageStreamStart = (1 << 28),
+ MessageNeedContext = (1 << 29),
+ MessageHaveContext = (1 << 30),
+ MessageExtended = (1 << 31),
+ MessageDeviceAdded /*= MessageExtended + 1*/,
+ MessageDeviceRemoved /*= MessageExtended + 2*/,
MessageAny = ~0
};
}
@@ -256,7 +273,7 @@ namespace QGst {
StreamVolumeFormatDb
};
}
-QGST_REGISTER_TYPE(QGst::StreamVolumeFormat)
+//QGST_REGISTER_TYPE(QGst::StreamVolumeFormat)
namespace QGst {
enum ColorBalanceType {
@@ -267,42 +284,60 @@ namespace QGst {
QGST_REGISTER_TYPE(QGst::ColorBalanceType)
namespace QGst {
+ enum QueryTypeFlag {
+ QueryTypeUpstream = 1 << 0,
+ QueryTypeDownstream = 1 << 1,
+ QueryTypeSerialized = 1 << 2,
+ QueryTypeBoth = (QueryTypeUpstream | QueryTypeDownstream)
+ };
+ Q_DECLARE_FLAGS(QueryTypeFlags, QueryTypeFlag);
+ Q_DECLARE_OPERATORS_FOR_FLAGS(QueryTypeFlags)
+}
+QGST_REGISTER_TYPE(QGst::QueryTypeFlags)
+
+namespace QGst {
enum QueryType {
- QueryNone = 0,
- QueryPosition,
- QueryDuration,
- QueryLatency,
- QueryJitter,
- QueryRate,
- QuerySeeking,
- QuerySegment,
- QueryConvert,
- QueryFormats,
- QueryBuffering,
- QueryCustom,
- QueryUri
+ QueryUnknown = 0,
+ QueryPosition = (10 << 8) | QueryTypeBoth,
+ QueryDuration = (20 << 8) | QueryTypeBoth,
+ QueryLatency = (30 << 8) | QueryTypeBoth,
+ QueryJitter = (40 << 8) | QueryTypeBoth,
+ QueryRate = (50 << 8) | QueryTypeBoth,
+ QuerySeeking = (60 << 8) | QueryTypeBoth,
+ QuerySegment = (70 << 8) | QueryTypeBoth,
+ QueryConvert = (80 << 8) | QueryTypeBoth,
+ QueryFormats = (90 << 8) | QueryTypeBoth,
+ QueryBuffering = (110 << 8) | QueryTypeBoth,
+ QueryCustom = (120 << 8) | QueryTypeBoth,
+ QueryUri = (130 << 8) | QueryTypeBoth,
+ QueryAllocation = (140 << 8) | QueryTypeDownstream | QueryTypeSerialized,
+ QueryScheduling = (150 << 8) | QueryTypeUpstream,
+ QueryAcceptCaps = (160 << 8) | QueryTypeBoth,
+ QueryCaps = (170 << 8) | QueryTypeBoth,
+ QueryDrain = (180 << 8) | QueryTypeDownstream | QueryTypeSerialized,
+ QueryContext = (190 << 8) | QueryTypeBoth
};
}
QGST_REGISTER_TYPE(QGst::QueryType)
namespace QGst {
enum BufferFlag {
- //codegen: BufferFlagReadOnly=BUFFER_FLAG_READONLY
- BufferFlagReadOnly = MiniObjectFlagReadonly,
- BufferFlagPreroll = (MiniObjectFlagLast << 0),
- BufferFlagDiscont = (MiniObjectFlagLast << 1),
- BufferFlagInCaps = (MiniObjectFlagLast << 2),
- BufferFlagGap = (MiniObjectFlagLast << 3),
- BufferFlagDeltaUnit = (MiniObjectFlagLast << 4),
- BufferFlagMedia1 = (MiniObjectFlagLast << 5),
- BufferFlagMedia2 = (MiniObjectFlagLast << 6),
- BufferFlagMedia3 = (MiniObjectFlagLast << 7),
- BufferFlagLast = (MiniObjectFlagLast << 8)
+ BufferFlagLive = (MiniObjectFlagLast << 0),
+ BufferFlagDecodeOnly = (MiniObjectFlagLast << 1),
+ BufferFlagDiscont = (MiniObjectFlagLast << 2),
+ BufferFlagResync = (MiniObjectFlagLast << 3),
+ BufferFlagCorrupted = (MiniObjectFlagLast << 4),
+ BufferFlagMarker = (MiniObjectFlagLast << 5),
+ BufferFlagHeader = (MiniObjectFlagLast << 6),
+ BufferFlagGap = (MiniObjectFlagLast << 7),
+ BufferFlagDroppable = (MiniObjectFlagLast << 8),
+ BufferFlagDeltaUnit = (MiniObjectFlagLast << 9),
+ BufferFlagLast = (MiniObjectFlagLast << 16)
};
Q_DECLARE_FLAGS(BufferFlags, BufferFlag);
Q_DECLARE_OPERATORS_FOR_FLAGS(BufferFlags)
}
-QGST_REGISTER_TYPE(QGst::BufferFlags) //codegen: GType=GST_TYPE_BUFFER_FLAG
+QGST_REGISTER_TYPE(QGst::BufferFlags)
namespace QGst {
@@ -310,6 +345,8 @@ namespace QGst {
EventTypeUpstream = 1 << 0,
EventTypeDownstream = 1 << 1,
EventTypeSerialized = 1 << 2,
+ EventTypeSticky = 1 << 3,
+ EventTypeStickyMulti = 1 << 4,
EventTypeBoth = (EventTypeUpstream | EventTypeDownstream)
};
Q_DECLARE_FLAGS(EventTypeFlags, EventTypeFlag);
@@ -319,25 +356,41 @@ QGST_REGISTER_TYPE(QGst::EventTypeFlags)
namespace QGst {
enum EventType {
- //codegen: EventNewSegment=EVENT_NEWSEGMENT, EventBufferSize=EVENT_BUFFERSIZE
- EventUnknown = (0 << 4),
- EventFlushStart = (1 << 4) | EventTypeBoth,
- EventFlushStop = (2 << 4) | EventTypeBoth | EventTypeSerialized,
- EventEos = (5 << 4) | EventTypeDownstream | EventTypeSerialized,
- EventNewSegment = (6 << 4) | EventTypeDownstream | EventTypeSerialized,
- EventTag = (7 << 4) | EventTypeDownstream | EventTypeSerialized,
- EventBufferSize = (8 << 4) | EventTypeDownstream | EventTypeSerialized,
- EventSinkMessage = (9 << 4) | EventTypeDownstream | EventTypeSerialized,
- EventQos = (15 << 4) | EventTypeUpstream,
- EventSeek = (16 << 4) | EventTypeUpstream,
- EventNavigation = (17 << 4) | EventTypeUpstream,
- EventLatency = (18 << 4) | EventTypeUpstream,
- EventStep = (19 << 4) | EventTypeUpstream,
- EventCustomUpstream = (32 << 4) | EventTypeUpstream,
- EventCustomDownstream = (32 << 4) | EventTypeDownstream | EventTypeSerialized,
- EventCustomDownstreamOob = (32 << 4) | EventTypeDownstream,
- EventCustomBoth = (32 << 4) | EventTypeBoth | EventTypeSerialized,
- EventCustomBothOob = (32 << 4) | EventTypeBoth
+ //codegen: EventBufferSize=EVENT_BUFFERSIZE
+ EventUnknown = (0 << 8),
+ EventFlushStart = (10 << 8) | EventTypeBoth,
+ EventFlushStop = (20 << 8) | EventTypeBoth | EventTypeSerialized,
+
+ /* downstream */
+ EventStreamStart = (40 << 8) | EventTypeDownstream | EventTypeSerialized | EventTypeSticky,
+ EventCaps = (50 << 8) | EventTypeDownstream | EventTypeSerialized | EventTypeSticky,
+ EventSegment = (70 << 8) | EventTypeDownstream | EventTypeSerialized | EventTypeSticky,
+ EventTag = (80 << 8) | EventTypeDownstream | EventTypeSerialized | EventTypeSticky | EventTypeStickyMulti,
+ EventBufferSize = (90 << 8) | EventTypeDownstream | EventTypeSerialized | EventTypeSticky,
+ EventSinkMessage = (100 << 8) | EventTypeDownstream | EventTypeSerialized | EventTypeSticky | EventTypeStickyMulti,
+ EventEos = (110 << 8) | EventTypeDownstream | EventTypeSerialized | EventTypeSticky,
+ EventToc = (120 << 8) | EventTypeDownstream | EventTypeSerialized | EventTypeSticky | EventTypeStickyMulti,
+
+ /* non sticky downstream */
+ EventSegmentDone = (150 << 8) | EventTypeDownstream | EventTypeSerialized,
+ EventGap = (160 << 8) | EventTypeDownstream | EventTypeSerialized,
+
+ /* upstream events */
+ EventQos = (190 << 8) | EventTypeUpstream,
+ EventSeek = (200 << 8) | EventTypeUpstream,
+ EventNavigation = (210 << 8) | EventTypeUpstream,
+ EventLatency = (220 << 8) | EventTypeUpstream,
+ EventStep = (230 << 8) | EventTypeUpstream,
+ EventReconfigure = (240 << 8 ) | EventTypeUpstream,
+ EventTocSelect = (250 << 8) | EventTypeUpstream,
+
+ /* custom events */
+ EventCustomUpstream = (270 << 8) | EventTypeUpstream,
+ EventCustomDownstream = (280 << 8) | EventTypeDownstream | EventTypeSerialized,
+ EventCustomDownstreamOob = (290 << 8) | EventTypeDownstream,
+ EventCustomDownstreamSticky = (300 << 8) | EventTypeDownstream | EventTypeSerialized | EventTypeSticky | EventTypeStickyMulti,
+ EventCustomBoth = (310 << 8) | EventTypeBoth | EventTypeSerialized,
+ EventCustomBothOob = (320 << 8) | EventTypeBoth
};
}
QGST_REGISTER_TYPE(QGst::EventType)
@@ -359,14 +412,34 @@ QGST_REGISTER_TYPE(QGst::SeekFlags)
namespace QGst {
enum SeekType {
SeekTypeNone = 0,
- SeekTypeCur = 1,
- SeekTypeSet = 2,
- SeekTypeEnd = 3
+ SeekTypeSet = 1,
+ SeekTypeEnd = 2
};
}
QGST_REGISTER_TYPE(QGst::SeekType)
namespace QGst {
+ enum SegmentFlag {
+ SegmentFlagNone = SeekFlagNone,
+ SegmentFlagReset = SeekFlagFlush,
+ SegmentFlagSkip = SeekFlagSkip,
+ SegmentFlagSegment = SeekFlagSegment
+ };
+ Q_DECLARE_FLAGS(SegmentFlags, SegmentFlag);
+ Q_DECLARE_OPERATORS_FOR_FLAGS(SegmentFlags);
+}
+QGST_REGISTER_TYPE(QGst::SegmentFlags);
+
+namespace QGst {
+ enum QosType {
+ QosTypeOverflow = 0,
+ QosTypeUnderflow = 1,
+ QosTypeThrottle = 2
+ };
+}
+QGST_REGISTER_TYPE(QGst::QosType);
+
+namespace QGst {
enum TagMergeMode {
TagMergeUndefined,
TagMergeReplaceAll,
@@ -415,4 +488,41 @@ namespace QGlib {
};
}
+namespace QGst {
+ enum DiscovererResult {
+ DiscovererOk,
+ DiscovererUriInvalid,
+ DiscovererError,
+ DiscovererTimeout,
+ DiscovererBusy,
+ DiscovererMissingPlugins
+ };
+}
+QGST_REGISTER_TYPE(QGst::DiscovererResult)
+
+namespace QGst {
+ enum MapFlag {
+ MapRead = (1 << 0),
+ MapWrite = (1 << 1),
+ MapFlagLast = (1 << 16)
+ };
+ Q_DECLARE_FLAGS(MapFlags, MapFlag);
+}
+Q_DECLARE_OPERATORS_FOR_FLAGS(QGst::MapFlags)
+QGST_REGISTER_TYPE(QGst::MapFlags)
+
+namespace QGst {
+ enum MemoryFlag {
+ MemoryFlagReadonly = MiniObjectFlagLockReadonly,
+ MemoryFlagNoShare = (MiniObjectFlagLast << 0),
+ MemoryFlagZeroPrefixed = (MiniObjectFlagLast << 1),
+ MemoryFlagZeroPadded = (MiniObjectFlagLast << 2),
+ MemoryFlagPhysicallyContiguous = (MiniObjectFlagLast << 3),
+ MemoryFlagNotMappable = (MiniObjectFlagLast << 4),
+ MemoryFlagLast = (MiniObjectFlagLast << 16)
+ };
+ Q_DECLARE_FLAGS(MemoryFlags, MemoryFlag);
+}
+Q_DECLARE_OPERATORS_FOR_FLAGS(QGst::MemoryFlags)
+QGST_REGISTER_TYPE(QGst::MemoryFlags)
#endif
diff --git a/src/QGst/event.cpp b/src/QGst/event.cpp
index cd87abb..0530f0b 100644
--- a/src/QGst/event.cpp
+++ b/src/QGst/event.cpp
@@ -10,24 +10,21 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
*/
+#include "caps.h"
#include "event.h"
#include "message.h"
#include "object.h"
+#include "segment.h"
#include <QtCore/QDebug>
#include <gst/gst.h>
namespace QGst {
-ObjectPtr Event::source() const
-{
- return ObjectPtr::wrap(GST_EVENT_SRC(object<GstEvent>()));
-}
-
quint64 Event::timestamp() const
{
return object<GstEvent>()->timestamp;
@@ -40,12 +37,18 @@ EventType Event::type() const
QString Event::typeName() const
{
- return QString::fromUtf8(GST_EVENT_TYPE_NAME(object<GstQuery>()));
+ return QString::fromUtf8(GST_EVENT_TYPE_NAME(object<GstEvent>()));
+}
+
+StructureConstPtr Event::internalStructure()
+{
+ const GstStructure *structure = gst_event_get_structure(object<GstEvent>());
+ return SharedStructure::fromMiniObject(const_cast<GstStructure *>(structure), MiniObjectPtr(this));
}
-StructurePtr Event::internalStructure()
+bool Event::hasName(const char *name) const
{
- return SharedStructure::fromMiniObject(object<GstEvent>()->structure, MiniObjectPtr(this));
+ return gst_event_has_name(object<GstEvent>(), name);
}
quint32 Event::sequenceNumber() const
@@ -72,81 +75,54 @@ FlushStartEventPtr FlushStartEvent::create()
//********************************************************
-FlushStopEventPtr FlushStopEvent::create()
+FlushStopEventPtr FlushStopEvent::create(bool reset_time)
{
- return FlushStopEventPtr::wrap(gst_event_new_flush_stop(), false);
+ return FlushStopEventPtr::wrap(gst_event_new_flush_stop(reset_time), false);
}
-//********************************************************
-
-EosEventPtr EosEvent::create()
+bool FlushStopEvent::resetTime() const
{
- return EosEventPtr::wrap(gst_event_new_eos(), false);
+ gboolean r;
+ gst_event_parse_flush_stop(object<GstEvent>(), &r);
+ return r;
}
//********************************************************
-NewSegmentEventPtr NewSegmentEvent::create(bool update, double rate, double appliedRate,
- Format format, qint64 start, qint64 stop, qint64 position)
-{
- GstEvent * e = gst_event_new_new_segment_full(update, rate, appliedRate,
- static_cast<GstFormat>(format), start, stop,
- position);
-
- return NewSegmentEventPtr::wrap(e, false);
-}
-
-bool NewSegmentEvent::isUpdate() const
+EosEventPtr EosEvent::create()
{
- gboolean u;
- gst_event_parse_new_segment_full(object<GstEvent>(), &u, NULL, NULL, NULL, NULL, NULL, NULL);
- return u;
+ return EosEventPtr::wrap(gst_event_new_eos(), false);
}
-double NewSegmentEvent::rate() const
+//********************************************************
+CapsEventPtr CapsEvent::create(const CapsPtr &caps)
{
- double r;
- gst_event_parse_new_segment_full(object<GstEvent>(), NULL, &r, NULL, NULL, NULL, NULL, NULL);
- return r;
+ return CapsEventPtr::wrap(gst_event_new_caps(caps), false);
}
-double NewSegmentEvent::appliedRate() const
+CapsPtr CapsEvent::caps() const
{
- double r;
- gst_event_parse_new_segment_full(object<GstEvent>(), NULL, NULL, &r, NULL, NULL, NULL, NULL);
- return r;
+ GstCaps *c;
+ gst_event_parse_caps (object<GstEvent>(), &c);
+ return CapsPtr::wrap (c);
}
-Format NewSegmentEvent::format() const
-{
- GstFormat f;
- gst_event_parse_new_segment_full(object<GstEvent>(), NULL, NULL, NULL, &f, NULL, NULL, NULL);
- return static_cast<Format>(f);
-}
+//********************************************************
-qint64 NewSegmentEvent::start() const
+SegmentEventPtr SegmentEvent::create(const Segment & segment)
{
- gint64 s;
- gst_event_parse_new_segment_full(object<GstEvent>(), NULL, NULL, NULL, NULL, &s, NULL, NULL);
- return s;
+ return SegmentEventPtr::wrap(gst_event_new_segment(segment), false);
}
-qint64 NewSegmentEvent::stop() const
+Segment SegmentEvent::segment() const
{
- gint64 s;
- gst_event_parse_new_segment_full(object<GstEvent>(), NULL, NULL, NULL, NULL, NULL, &s, NULL);
- return s;
-}
+ const GstSegment *s;
+ gst_event_parse_segment(object<GstEvent>(), &s);
-qint64 NewSegmentEvent::position() const
-{
- gint64 p;
- gst_event_parse_new_segment_full(object<GstEvent>(), NULL, NULL, NULL, NULL, NULL, NULL, &p);
- return p;
+ return Segment(s);
}
//********************************************************
-
TagEventPtr TagEvent::create(const TagList & taglist)
{
GstEvent * e = gst_event_new_tag(gst_tag_list_copy(taglist));
@@ -202,9 +178,9 @@ bool BufferSizeEvent::isAsync() const
//********************************************************
-SinkMessageEventPtr SinkMessageEvent::create(const MessagePtr & msg)
+SinkMessageEventPtr SinkMessageEvent::create(const QString &name, const MessagePtr & msg)
{
- GstEvent * e = gst_event_new_sink_message(msg);
+ GstEvent * e = gst_event_new_sink_message(name.toUtf8().constData(), msg);
return SinkMessageEventPtr::wrap(e, false);
}
@@ -218,30 +194,37 @@ MessagePtr SinkMessageEvent::message() const
//********************************************************
-QosEventPtr QosEvent::create(double proportion, ClockTimeDiff diff, ClockTime timeStamp)
+QosEventPtr QosEvent::create(QosType qos, double proportion, ClockTimeDiff diff, ClockTime timeStamp)
{
- GstEvent * e = gst_event_new_qos(proportion, diff, static_cast<GstClockTime>(timeStamp));
+ GstEvent * e = gst_event_new_qos(static_cast<GstQOSType>(qos), proportion, diff, static_cast<GstClockTime>(timeStamp));
return QosEventPtr::wrap(e, false);
}
+QosType QosEvent::qosType() const
+{
+ GstQOSType t;
+ gst_event_parse_qos(object<GstEvent>(), &t, NULL, NULL, NULL);
+ return static_cast<QosType>(t);
+}
+
double QosEvent::proportion() const
{
double d;
- gst_event_parse_qos(object<GstEvent>(), &d, NULL, NULL);
+ gst_event_parse_qos(object<GstEvent>(), NULL, &d, NULL, NULL);
return d;
}
ClockTimeDiff QosEvent::diff() const
{
GstClockTimeDiff c;
- gst_event_parse_qos(object<GstEvent>(), NULL, &c, NULL);
+ gst_event_parse_qos(object<GstEvent>(), NULL, NULL, &c, NULL);
return c;
}
ClockTime QosEvent::timestamp() const
{
GstClockTime c;
- gst_event_parse_qos(object<GstEvent>(), NULL, NULL, &c);
+ gst_event_parse_qos(object<GstEvent>(), NULL, NULL, NULL, &c);
return c;
}
diff --git a/src/QGst/event.h b/src/QGst/event.h
index 1011bfe..f424d23 100644
--- a/src/QGst/event.h
+++ b/src/QGst/event.h
@@ -10,7 +10,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -56,12 +56,13 @@ class QTGSTREAMER_EXPORT Event : public MiniObject
{
QGST_WRAPPER(Event)
public:
- ObjectPtr source() const;
quint64 timestamp() const;
EventType type() const;
QString typeName() const;
- StructurePtr internalStructure();
+ StructureConstPtr internalStructure();
+
+ bool hasName(const char *name) const;
quint32 sequenceNumber() const;
void setSequenceNumber(quint32 num);
@@ -87,7 +88,9 @@ class QTGSTREAMER_EXPORT FlushStopEvent : public Event
{
QGST_WRAPPER_FAKE_SUBCLASS(FlushStop, Event)
public:
- static FlushStopEventPtr create();
+ static FlushStopEventPtr create(bool reset_time=true);
+
+ bool resetTime() const;
};
/*! \headerfile event.h <QGst/Event>
@@ -101,22 +104,27 @@ public:
};
/*! \headerfile event.h <QGst/Event>
- * \brief Wrapper class for events of type QGst::NewSegmentEvent
+ * \brief Wrapper class for events of type QGst::EventCaps
*/
-class QTGSTREAMER_EXPORT NewSegmentEvent : public Event
+ class QTGSTREAMER_EXPORT CapsEvent : public Event
+ {
+ QGST_WRAPPER_FAKE_SUBCLASS(Caps, Event)
+public:
+ static CapsEventPtr create(const CapsPtr & caps);
+
+ CapsPtr caps() const;
+ };
+
+/*! \headerfile event.h <QGst/Event>
+ * \brief Wrapper class for events of type QGst::SegmentEvent
+ */
+class QTGSTREAMER_EXPORT SegmentEvent : public Event
{
- QGST_WRAPPER_FAKE_SUBCLASS(NewSegment, Event)
+ QGST_WRAPPER_FAKE_SUBCLASS(Segment, Event)
public:
- static NewSegmentEventPtr create(bool update, double rate, double appliedRate, Format format,
- qint64 start, qint64 stop, qint64 position);
+ static SegmentEventPtr create(const Segment & segment);
- bool isUpdate() const;
- double rate() const;
- double appliedRate() const;
- Format format() const;
- qint64 start() const;
- qint64 stop() const;
- qint64 position() const;
+ Segment segment() const;
};
/*! \headerfile event.h <QGst/Event>
@@ -153,7 +161,7 @@ class QTGSTREAMER_EXPORT SinkMessageEvent : public Event
{
QGST_WRAPPER_FAKE_SUBCLASS(SinkMessage, Event)
public:
- static SinkMessageEventPtr create(const MessagePtr & msg);
+ static SinkMessageEventPtr create(const QString &name, const MessagePtr & msg);
MessagePtr message() const;
};
@@ -165,8 +173,9 @@ class QTGSTREAMER_EXPORT QosEvent : public Event
{
QGST_WRAPPER_FAKE_SUBCLASS(Qos, Event)
public:
- static QosEventPtr create(double proportion, ClockTimeDiff diff, ClockTime timestamp);
+ static QosEventPtr create(QosType qos, double proportion, ClockTimeDiff diff, ClockTime timestamp);
+ QosType qosType() const;
double proportion() const;
ClockTimeDiff diff() const;
ClockTime timestamp() const;
@@ -236,7 +245,8 @@ QGST_REGISTER_TYPE(QGst::Event)
QGST_REGISTER_SUBCLASS(Event, FlushStart)
QGST_REGISTER_SUBCLASS(Event, FlushStop)
QGST_REGISTER_SUBCLASS(Event, Eos)
-QGST_REGISTER_SUBCLASS(Event, NewSegment)
+QGST_REGISTER_SUBCLASS(Event, Caps)
+QGST_REGISTER_SUBCLASS(Event, Segment)
QGST_REGISTER_SUBCLASS(Event, Tag)
QGST_REGISTER_SUBCLASS(Event, BufferSize)
QGST_REGISTER_SUBCLASS(Event, SinkMessage)
diff --git a/src/QGst/gen.cpp b/src/QGst/gen.cpp
new file mode 100644
index 0000000..fec9147
--- /dev/null
+++ b/src/QGst/gen.cpp
@@ -0,0 +1,1116 @@
+// Autogenerated by the QtGStreamer helper code generator - DO NOT EDIT
+/*
+ Copyright (C) 2010 George Kiagiadakis <kiagiadakis.george@gmail.com>
+ Copyright (C) 2010 Collabora Ltd.
+ @author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#define INCLUDED_FROM_CODEGEN
+#include <boost/static_assert.hpp>
+
+#define REGISTER_TYPE_IMPLEMENTATION(T, GTYPE) \
+ namespace QGlib { \
+ GetTypeImpl<T>::operator Type() { return (GTYPE); } \
+ }
+
+#include <gst/gst.h>
+#include <gst/audio/audio-enumtypes.h>
+#include <gst/audio/streamvolume.h>
+#include <gst/video/video-enumtypes.h>
+#include <gst/video/videooverlay.h>
+#include <gst/video/colorbalance.h>
+#include <gst/video/videoorientation.h>
+#include <gst/app/gstappsrc.h>
+#include <gst/pbutils/gstdiscoverer.h>
+#include <gst/pbutils/pbutils-enumtypes.h>
+#include <QGlib/Quark>
+#include "QGst/urihandler.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::UriHandler,GST_TYPE_URI_HANDLER)
+
+namespace QGst {
+ QGlib::RefCountedObject *UriHandler_new(void *instance)
+ {
+ QGst::UriHandler *cppClass = new QGst::UriHandler;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+#include "QGst/pad.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::Pad,GST_TYPE_PAD)
+
+namespace QGst {
+ QGlib::RefCountedObject *Pad_new(void *instance)
+ {
+ QGst::Pad *cppClass = new QGst::Pad;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+#include "QGst/parse.h"
+
+#include "QGst/clock.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::Clock,GST_TYPE_CLOCK)
+
+namespace QGst {
+ QGlib::RefCountedObject *Clock_new(void *instance)
+ {
+ QGst::Clock *cppClass = new QGst::Clock;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+#include "QGst/segment.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::Segment,GST_TYPE_SEGMENT)
+
+#include "QGst/videooverlay.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::VideoOverlay,GST_TYPE_VIDEO_OVERLAY)
+
+namespace QGst {
+ QGlib::RefCountedObject *VideoOverlay_new(void *instance)
+ {
+ QGst::VideoOverlay *cppClass = new QGst::VideoOverlay;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+#include "QGst/sample.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::Sample,GST_TYPE_SAMPLE)
+
+namespace QGst {
+ QGlib::RefCountedObject *Sample_new(void *instance)
+ {
+ QGst::Sample *cppClass = new QGst::Sample;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+#include "QGst/message.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::Message,GST_TYPE_MESSAGE)
+
+namespace QGst {
+ QGlib::RefCountedObject *Message_new(void *instance)
+ {
+ QGst::Message *cppClass = NULL;
+ switch(GST_MESSAGE_TYPE(instance)) {
+ case QGst::MessageEos:
+ cppClass = new QGst::EosMessage;
+ break;
+ case QGst::MessageError:
+ cppClass = new QGst::ErrorMessage;
+ break;
+ case QGst::MessageWarning:
+ cppClass = new QGst::WarningMessage;
+ break;
+ case QGst::MessageInfo:
+ cppClass = new QGst::InfoMessage;
+ break;
+ case QGst::MessageTag:
+ cppClass = new QGst::TagMessage;
+ break;
+ case QGst::MessageBuffering:
+ cppClass = new QGst::BufferingMessage;
+ break;
+ case QGst::MessageStateChanged:
+ cppClass = new QGst::StateChangedMessage;
+ break;
+ case QGst::MessageStepDone:
+ cppClass = new QGst::StepDoneMessage;
+ break;
+ case QGst::MessageStreamStatus:
+ cppClass = new QGst::StreamStatusMessage;
+ break;
+ case QGst::MessageApplication:
+ cppClass = new QGst::ApplicationMessage;
+ break;
+ case QGst::MessageElement:
+ cppClass = new QGst::ElementMessage;
+ break;
+ case QGst::MessageSegmentDone:
+ cppClass = new QGst::SegmentDoneMessage;
+ break;
+ case QGst::MessageDurationChanged:
+ cppClass = new QGst::DurationChangedMessage;
+ break;
+ case QGst::MessageLatency:
+ cppClass = new QGst::LatencyMessage;
+ break;
+ case QGst::MessageAsyncDone:
+ cppClass = new QGst::AsyncDoneMessage;
+ break;
+ case QGst::MessageRequestState:
+ cppClass = new QGst::RequestStateMessage;
+ break;
+ case QGst::MessageStepStart:
+ cppClass = new QGst::StepStartMessage;
+ break;
+ case QGst::MessageQos:
+ cppClass = new QGst::QosMessage;
+ break;
+ case QGst::MessageDeviceAdded:
+ cppClass = new QGst::DeviceAddedMessage;
+ break;
+ case QGst::MessageDeviceRemoved:
+ cppClass = new QGst::DeviceRemovedMessage;
+ break;
+ default:
+ cppClass = new QGst::Message;
+ break;
+ }
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+#include "QGst/bufferlist.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::BufferList,GST_TYPE_BUFFER_LIST)
+
+namespace QGst {
+ QGlib::RefCountedObject *BufferList_new(void *instance)
+ {
+ QGst::BufferList *cppClass = new QGst::BufferList;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+#include "QGst/enums.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::MiniObjectFlags,GST_TYPE_MINI_OBJECT_FLAGS)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::ObjectFlags,GST_TYPE_OBJECT_FLAGS)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::State,GST_TYPE_STATE)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::StateChange,GST_TYPE_STATE_CHANGE)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::StateChangeReturn,GST_TYPE_STATE_CHANGE_RETURN)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::PadDirection,GST_TYPE_PAD_DIRECTION)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::PadFlags,GST_TYPE_PAD_FLAGS)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::PadLinkReturn,GST_TYPE_PAD_LINK_RETURN)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::FlowReturn,GST_TYPE_FLOW_RETURN)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::PadMode,GST_TYPE_PAD_MODE)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::Rank,GST_TYPE_RANK)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::MessageType,GST_TYPE_MESSAGE_TYPE)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::ParseError,GST_TYPE_PARSE_ERROR)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::UriType,GST_TYPE_URI_TYPE)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::BufferingMode,GST_TYPE_BUFFERING_MODE)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::Format,GST_TYPE_FORMAT)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::StreamStatusType,GST_TYPE_STREAM_STATUS_TYPE)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::ColorBalanceType,GST_TYPE_COLOR_BALANCE_TYPE)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::QueryTypeFlags,GST_TYPE_QUERY_TYPE_FLAGS)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::QueryType,GST_TYPE_QUERY_TYPE)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::BufferFlags,GST_TYPE_BUFFER_FLAGS)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::EventTypeFlags,GST_TYPE_EVENT_TYPE_FLAGS)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::EventType,GST_TYPE_EVENT_TYPE)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::SeekFlags,GST_TYPE_SEEK_FLAGS)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::SeekType,GST_TYPE_SEEK_TYPE)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::SegmentFlags,GST_TYPE_SEGMENT_FLAGS)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::QosType,GST_TYPE_QOS_TYPE)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::TagMergeMode,GST_TYPE_TAG_MERGE_MODE)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::TagFlags,GST_TYPE_TAG_FLAG)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::DiscovererResult,GST_TYPE_DISCOVERER_RESULT)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::MapFlags,GST_TYPE_MAP_FLAGS)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::MemoryFlags,GST_TYPE_MEMORY_FLAGS)
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(MiniObjectFlagLockable) == static_cast<int>(GST_MINI_OBJECT_FLAG_LOCKABLE));
+ BOOST_STATIC_ASSERT(static_cast<int>(MiniObjectFlagLockReadonly) == static_cast<int>(GST_MINI_OBJECT_FLAG_LOCK_READONLY));
+ BOOST_STATIC_ASSERT(static_cast<int>(MiniObjectFlagLast) == static_cast<int>(GST_MINI_OBJECT_FLAG_LAST));
+}
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(ObjectFlagLast) == static_cast<int>(GST_OBJECT_FLAG_LAST));
+}
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(StateVoidPending) == static_cast<int>(GST_STATE_VOID_PENDING));
+ BOOST_STATIC_ASSERT(static_cast<int>(StateNull) == static_cast<int>(GST_STATE_NULL));
+ BOOST_STATIC_ASSERT(static_cast<int>(StateReady) == static_cast<int>(GST_STATE_READY));
+ BOOST_STATIC_ASSERT(static_cast<int>(StatePaused) == static_cast<int>(GST_STATE_PAUSED));
+ BOOST_STATIC_ASSERT(static_cast<int>(StatePlaying) == static_cast<int>(GST_STATE_PLAYING));
+}
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(StateChangeNullToReady) == static_cast<int>(GST_STATE_CHANGE_NULL_TO_READY));
+ BOOST_STATIC_ASSERT(static_cast<int>(StateChangeReadyToPaused) == static_cast<int>(GST_STATE_CHANGE_READY_TO_PAUSED));
+ BOOST_STATIC_ASSERT(static_cast<int>(StateChangePausedToPlaying) == static_cast<int>(GST_STATE_CHANGE_PAUSED_TO_PLAYING));
+ BOOST_STATIC_ASSERT(static_cast<int>(StateChangePlayingToPaused) == static_cast<int>(GST_STATE_CHANGE_PLAYING_TO_PAUSED));
+ BOOST_STATIC_ASSERT(static_cast<int>(StateChangePausedToReady) == static_cast<int>(GST_STATE_CHANGE_PAUSED_TO_READY));
+ BOOST_STATIC_ASSERT(static_cast<int>(StateChangeReadyToNull) == static_cast<int>(GST_STATE_CHANGE_READY_TO_NULL));
+}
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(StateChangeFailure) == static_cast<int>(GST_STATE_CHANGE_FAILURE));
+ BOOST_STATIC_ASSERT(static_cast<int>(StateChangeSuccess) == static_cast<int>(GST_STATE_CHANGE_SUCCESS));
+ BOOST_STATIC_ASSERT(static_cast<int>(StateChangeAsync) == static_cast<int>(GST_STATE_CHANGE_ASYNC));
+ BOOST_STATIC_ASSERT(static_cast<int>(StateChangeNoPreroll) == static_cast<int>(GST_STATE_CHANGE_NO_PREROLL));
+}
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(PadUnknown) == static_cast<int>(GST_PAD_UNKNOWN));
+ BOOST_STATIC_ASSERT(static_cast<int>(PadSrc) == static_cast<int>(GST_PAD_SRC));
+ BOOST_STATIC_ASSERT(static_cast<int>(PadSink) == static_cast<int>(GST_PAD_SINK));
+}
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(PadFlagBlocked) == static_cast<int>(GST_PAD_FLAG_BLOCKED));
+ BOOST_STATIC_ASSERT(static_cast<int>(PadFlagFlushing) == static_cast<int>(GST_PAD_FLAG_FLUSHING));
+ BOOST_STATIC_ASSERT(static_cast<int>(PadFlagEos) == static_cast<int>(GST_PAD_FLAG_EOS));
+ BOOST_STATIC_ASSERT(static_cast<int>(PadFlagBlocking) == static_cast<int>(GST_PAD_FLAG_BLOCKING));
+ BOOST_STATIC_ASSERT(static_cast<int>(PadFlagNeedParent) == static_cast<int>(GST_PAD_FLAG_NEED_PARENT));
+ BOOST_STATIC_ASSERT(static_cast<int>(PadFlagNeedReconfigure) == static_cast<int>(GST_PAD_FLAG_NEED_RECONFIGURE));
+ BOOST_STATIC_ASSERT(static_cast<int>(PadFlagPendingEvents) == static_cast<int>(GST_PAD_FLAG_PENDING_EVENTS));
+ BOOST_STATIC_ASSERT(static_cast<int>(PadFlagFixedCaps) == static_cast<int>(GST_PAD_FLAG_FIXED_CAPS));
+ BOOST_STATIC_ASSERT(static_cast<int>(PadFlagProxyCaps) == static_cast<int>(GST_PAD_FLAG_PROXY_CAPS));
+ BOOST_STATIC_ASSERT(static_cast<int>(PadFlagProxyAllocation) == static_cast<int>(GST_PAD_FLAG_PROXY_ALLOCATION));
+ BOOST_STATIC_ASSERT(static_cast<int>(PadFlagProxyScheduling) == static_cast<int>(GST_PAD_FLAG_PROXY_SCHEDULING));
+ BOOST_STATIC_ASSERT(static_cast<int>(PadFlagLast) == static_cast<int>(GST_PAD_FLAG_LAST));
+}
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(PadLinkOk) == static_cast<int>(GST_PAD_LINK_OK));
+ BOOST_STATIC_ASSERT(static_cast<int>(PadLinkWrongHierarchy) == static_cast<int>(GST_PAD_LINK_WRONG_HIERARCHY));
+ BOOST_STATIC_ASSERT(static_cast<int>(PadLinkWasLinked) == static_cast<int>(GST_PAD_LINK_WAS_LINKED));
+ BOOST_STATIC_ASSERT(static_cast<int>(PadLinkWrongDirection) == static_cast<int>(GST_PAD_LINK_WRONG_DIRECTION));
+ BOOST_STATIC_ASSERT(static_cast<int>(PadLinkNoFormat) == static_cast<int>(GST_PAD_LINK_NOFORMAT));
+ BOOST_STATIC_ASSERT(static_cast<int>(PadLinkNoSched) == static_cast<int>(GST_PAD_LINK_NOSCHED));
+ BOOST_STATIC_ASSERT(static_cast<int>(PadLinkRefused) == static_cast<int>(GST_PAD_LINK_REFUSED));
+}
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(FlowCustomSuccess2) == static_cast<int>(GST_FLOW_CUSTOM_SUCCESS_2));
+ BOOST_STATIC_ASSERT(static_cast<int>(FlowCustomSuccess1) == static_cast<int>(GST_FLOW_CUSTOM_SUCCESS_1));
+ BOOST_STATIC_ASSERT(static_cast<int>(FlowCustomSuccess) == static_cast<int>(GST_FLOW_CUSTOM_SUCCESS));
+ BOOST_STATIC_ASSERT(static_cast<int>(FlowOk) == static_cast<int>(GST_FLOW_OK));
+ BOOST_STATIC_ASSERT(static_cast<int>(FlowNotLinked) == static_cast<int>(GST_FLOW_NOT_LINKED));
+ BOOST_STATIC_ASSERT(static_cast<int>(FlowFlushing) == static_cast<int>(GST_FLOW_FLUSHING));
+ BOOST_STATIC_ASSERT(static_cast<int>(FlowEos) == static_cast<int>(GST_FLOW_EOS));
+ BOOST_STATIC_ASSERT(static_cast<int>(FlowNotNegotiated) == static_cast<int>(GST_FLOW_NOT_NEGOTIATED));
+ BOOST_STATIC_ASSERT(static_cast<int>(FlowError) == static_cast<int>(GST_FLOW_ERROR));
+ BOOST_STATIC_ASSERT(static_cast<int>(FlowNotSupported) == static_cast<int>(GST_FLOW_NOT_SUPPORTED));
+ BOOST_STATIC_ASSERT(static_cast<int>(FlowCustomError) == static_cast<int>(GST_FLOW_CUSTOM_ERROR));
+ BOOST_STATIC_ASSERT(static_cast<int>(FlowCustomError1) == static_cast<int>(GST_FLOW_CUSTOM_ERROR_1));
+ BOOST_STATIC_ASSERT(static_cast<int>(FlowCustomError2) == static_cast<int>(GST_FLOW_CUSTOM_ERROR_2));
+}
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(PadModeNone) == static_cast<int>(GST_PAD_MODE_NONE));
+ BOOST_STATIC_ASSERT(static_cast<int>(PadModePush) == static_cast<int>(GST_PAD_MODE_PUSH));
+ BOOST_STATIC_ASSERT(static_cast<int>(PadModePull) == static_cast<int>(GST_PAD_MODE_PULL));
+}
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(RankNone) == static_cast<int>(GST_RANK_NONE));
+ BOOST_STATIC_ASSERT(static_cast<int>(RankMarginal) == static_cast<int>(GST_RANK_MARGINAL));
+ BOOST_STATIC_ASSERT(static_cast<int>(RankSecondary) == static_cast<int>(GST_RANK_SECONDARY));
+ BOOST_STATIC_ASSERT(static_cast<int>(RankPrimary) == static_cast<int>(GST_RANK_PRIMARY));
+}
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageUnknown) == static_cast<int>(GST_MESSAGE_UNKNOWN));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageEos) == static_cast<int>(GST_MESSAGE_EOS));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageError) == static_cast<int>(GST_MESSAGE_ERROR));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageWarning) == static_cast<int>(GST_MESSAGE_WARNING));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageInfo) == static_cast<int>(GST_MESSAGE_INFO));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageTag) == static_cast<int>(GST_MESSAGE_TAG));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageBuffering) == static_cast<int>(GST_MESSAGE_BUFFERING));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageStateChanged) == static_cast<int>(GST_MESSAGE_STATE_CHANGED));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageStateDirty) == static_cast<int>(GST_MESSAGE_STATE_DIRTY));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageStepDone) == static_cast<int>(GST_MESSAGE_STEP_DONE));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageClockProvide) == static_cast<int>(GST_MESSAGE_CLOCK_PROVIDE));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageClockLost) == static_cast<int>(GST_MESSAGE_CLOCK_LOST));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageNewClock) == static_cast<int>(GST_MESSAGE_NEW_CLOCK));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageStructureChange) == static_cast<int>(GST_MESSAGE_STRUCTURE_CHANGE));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageStreamStatus) == static_cast<int>(GST_MESSAGE_STREAM_STATUS));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageApplication) == static_cast<int>(GST_MESSAGE_APPLICATION));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageElement) == static_cast<int>(GST_MESSAGE_ELEMENT));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageSegmentStart) == static_cast<int>(GST_MESSAGE_SEGMENT_START));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageSegmentDone) == static_cast<int>(GST_MESSAGE_SEGMENT_DONE));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageDurationChanged) == static_cast<int>(GST_MESSAGE_DURATION_CHANGED));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageLatency) == static_cast<int>(GST_MESSAGE_LATENCY));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageAsyncStart) == static_cast<int>(GST_MESSAGE_ASYNC_START));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageAsyncDone) == static_cast<int>(GST_MESSAGE_ASYNC_DONE));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageRequestState) == static_cast<int>(GST_MESSAGE_REQUEST_STATE));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageStepStart) == static_cast<int>(GST_MESSAGE_STEP_START));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageQos) == static_cast<int>(GST_MESSAGE_QOS));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageProgress) == static_cast<int>(GST_MESSAGE_PROGRESS));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageToc) == static_cast<int>(GST_MESSAGE_TOC));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageResetTime) == static_cast<int>(GST_MESSAGE_RESET_TIME));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageStreamStart) == static_cast<int>(GST_MESSAGE_STREAM_START));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageNeedContext) == static_cast<int>(GST_MESSAGE_NEED_CONTEXT));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageHaveContext) == static_cast<int>(GST_MESSAGE_HAVE_CONTEXT));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageExtended) == static_cast<int>(GST_MESSAGE_EXTENDED));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageDeviceAdded) == static_cast<int>(GST_MESSAGE_DEVICE_ADDED));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageDeviceRemoved) == static_cast<int>(GST_MESSAGE_DEVICE_REMOVED));
+ BOOST_STATIC_ASSERT(static_cast<int>(MessageAny) == static_cast<int>(GST_MESSAGE_ANY));
+}
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(ParseErrorSyntax) == static_cast<int>(GST_PARSE_ERROR_SYNTAX));
+ BOOST_STATIC_ASSERT(static_cast<int>(ParseErrorNoSuchElement) == static_cast<int>(GST_PARSE_ERROR_NO_SUCH_ELEMENT));
+ BOOST_STATIC_ASSERT(static_cast<int>(ParseErrorNoSuchProperty) == static_cast<int>(GST_PARSE_ERROR_NO_SUCH_PROPERTY));
+ BOOST_STATIC_ASSERT(static_cast<int>(ParseErrorLink) == static_cast<int>(GST_PARSE_ERROR_LINK));
+ BOOST_STATIC_ASSERT(static_cast<int>(ParseErrorCouldNotSetProperty) == static_cast<int>(GST_PARSE_ERROR_COULD_NOT_SET_PROPERTY));
+ BOOST_STATIC_ASSERT(static_cast<int>(ParseErrorEmptyBin) == static_cast<int>(GST_PARSE_ERROR_EMPTY_BIN));
+ BOOST_STATIC_ASSERT(static_cast<int>(ParseErrorEmpty) == static_cast<int>(GST_PARSE_ERROR_EMPTY));
+}
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(UriUnknown) == static_cast<int>(GST_URI_UNKNOWN));
+ BOOST_STATIC_ASSERT(static_cast<int>(UriSink) == static_cast<int>(GST_URI_SINK));
+ BOOST_STATIC_ASSERT(static_cast<int>(UriSrc) == static_cast<int>(GST_URI_SRC));
+}
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(BufferingStream) == static_cast<int>(GST_BUFFERING_STREAM));
+ BOOST_STATIC_ASSERT(static_cast<int>(BufferingDownload) == static_cast<int>(GST_BUFFERING_DOWNLOAD));
+ BOOST_STATIC_ASSERT(static_cast<int>(BufferingTimeshift) == static_cast<int>(GST_BUFFERING_TIMESHIFT));
+ BOOST_STATIC_ASSERT(static_cast<int>(BufferingLive) == static_cast<int>(GST_BUFFERING_LIVE));
+}
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(FormatUndefined) == static_cast<int>(GST_FORMAT_UNDEFINED));
+ BOOST_STATIC_ASSERT(static_cast<int>(FormatDefault) == static_cast<int>(GST_FORMAT_DEFAULT));
+ BOOST_STATIC_ASSERT(static_cast<int>(FormatBytes) == static_cast<int>(GST_FORMAT_BYTES));
+ BOOST_STATIC_ASSERT(static_cast<int>(FormatTime) == static_cast<int>(GST_FORMAT_TIME));
+ BOOST_STATIC_ASSERT(static_cast<int>(FormatBuffers) == static_cast<int>(GST_FORMAT_BUFFERS));
+ BOOST_STATIC_ASSERT(static_cast<int>(FormatPercent) == static_cast<int>(GST_FORMAT_PERCENT));
+}
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(StreamStatusTypeCreate) == static_cast<int>(GST_STREAM_STATUS_TYPE_CREATE));
+ BOOST_STATIC_ASSERT(static_cast<int>(StreamStatusTypeEnter) == static_cast<int>(GST_STREAM_STATUS_TYPE_ENTER));
+ BOOST_STATIC_ASSERT(static_cast<int>(StreamStatusTypeLeave) == static_cast<int>(GST_STREAM_STATUS_TYPE_LEAVE));
+ BOOST_STATIC_ASSERT(static_cast<int>(StreamStatusTypeDestroy) == static_cast<int>(GST_STREAM_STATUS_TYPE_DESTROY));
+ BOOST_STATIC_ASSERT(static_cast<int>(StreamStatusTypeStart) == static_cast<int>(GST_STREAM_STATUS_TYPE_START));
+ BOOST_STATIC_ASSERT(static_cast<int>(StreamStatusTypePause) == static_cast<int>(GST_STREAM_STATUS_TYPE_PAUSE));
+ BOOST_STATIC_ASSERT(static_cast<int>(StreamStatusTypeStop) == static_cast<int>(GST_STREAM_STATUS_TYPE_STOP));
+}
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(StreamVolumeFormatLinear) == static_cast<int>(GST_STREAM_VOLUME_FORMAT_LINEAR));
+ BOOST_STATIC_ASSERT(static_cast<int>(StreamVolumeFormatCubic) == static_cast<int>(GST_STREAM_VOLUME_FORMAT_CUBIC));
+ BOOST_STATIC_ASSERT(static_cast<int>(StreamVolumeFormatDb) == static_cast<int>(GST_STREAM_VOLUME_FORMAT_DB));
+}
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(ColorBalanceHardware) == static_cast<int>(GST_COLOR_BALANCE_HARDWARE));
+ BOOST_STATIC_ASSERT(static_cast<int>(ColorBalanceSoftware) == static_cast<int>(GST_COLOR_BALANCE_SOFTWARE));
+}
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(QueryTypeUpstream) == static_cast<int>(GST_QUERY_TYPE_UPSTREAM));
+ BOOST_STATIC_ASSERT(static_cast<int>(QueryTypeDownstream) == static_cast<int>(GST_QUERY_TYPE_DOWNSTREAM));
+ BOOST_STATIC_ASSERT(static_cast<int>(QueryTypeSerialized) == static_cast<int>(GST_QUERY_TYPE_SERIALIZED));
+ BOOST_STATIC_ASSERT(static_cast<int>(QueryTypeBoth) == static_cast<int>(GST_QUERY_TYPE_BOTH));
+}
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(QueryUnknown) == static_cast<int>(GST_QUERY_UNKNOWN));
+ BOOST_STATIC_ASSERT(static_cast<int>(QueryPosition) == static_cast<int>(GST_QUERY_POSITION));
+ BOOST_STATIC_ASSERT(static_cast<int>(QueryDuration) == static_cast<int>(GST_QUERY_DURATION));
+ BOOST_STATIC_ASSERT(static_cast<int>(QueryLatency) == static_cast<int>(GST_QUERY_LATENCY));
+ BOOST_STATIC_ASSERT(static_cast<int>(QueryJitter) == static_cast<int>(GST_QUERY_JITTER));
+ BOOST_STATIC_ASSERT(static_cast<int>(QueryRate) == static_cast<int>(GST_QUERY_RATE));
+ BOOST_STATIC_ASSERT(static_cast<int>(QuerySeeking) == static_cast<int>(GST_QUERY_SEEKING));
+ BOOST_STATIC_ASSERT(static_cast<int>(QuerySegment) == static_cast<int>(GST_QUERY_SEGMENT));
+ BOOST_STATIC_ASSERT(static_cast<int>(QueryConvert) == static_cast<int>(GST_QUERY_CONVERT));
+ BOOST_STATIC_ASSERT(static_cast<int>(QueryFormats) == static_cast<int>(GST_QUERY_FORMATS));
+ BOOST_STATIC_ASSERT(static_cast<int>(QueryBuffering) == static_cast<int>(GST_QUERY_BUFFERING));
+ BOOST_STATIC_ASSERT(static_cast<int>(QueryCustom) == static_cast<int>(GST_QUERY_CUSTOM));
+ BOOST_STATIC_ASSERT(static_cast<int>(QueryUri) == static_cast<int>(GST_QUERY_URI));
+ BOOST_STATIC_ASSERT(static_cast<int>(QueryAllocation) == static_cast<int>(GST_QUERY_ALLOCATION));
+ BOOST_STATIC_ASSERT(static_cast<int>(QueryScheduling) == static_cast<int>(GST_QUERY_SCHEDULING));
+ BOOST_STATIC_ASSERT(static_cast<int>(QueryAcceptCaps) == static_cast<int>(GST_QUERY_ACCEPT_CAPS));
+ BOOST_STATIC_ASSERT(static_cast<int>(QueryCaps) == static_cast<int>(GST_QUERY_CAPS));
+ BOOST_STATIC_ASSERT(static_cast<int>(QueryDrain) == static_cast<int>(GST_QUERY_DRAIN));
+ BOOST_STATIC_ASSERT(static_cast<int>(QueryContext) == static_cast<int>(GST_QUERY_CONTEXT));
+}
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(BufferFlagLive) == static_cast<int>(GST_BUFFER_FLAG_LIVE));
+ BOOST_STATIC_ASSERT(static_cast<int>(BufferFlagDecodeOnly) == static_cast<int>(GST_BUFFER_FLAG_DECODE_ONLY));
+ BOOST_STATIC_ASSERT(static_cast<int>(BufferFlagDiscont) == static_cast<int>(GST_BUFFER_FLAG_DISCONT));
+ BOOST_STATIC_ASSERT(static_cast<int>(BufferFlagResync) == static_cast<int>(GST_BUFFER_FLAG_RESYNC));
+ BOOST_STATIC_ASSERT(static_cast<int>(BufferFlagCorrupted) == static_cast<int>(GST_BUFFER_FLAG_CORRUPTED));
+ BOOST_STATIC_ASSERT(static_cast<int>(BufferFlagMarker) == static_cast<int>(GST_BUFFER_FLAG_MARKER));
+ BOOST_STATIC_ASSERT(static_cast<int>(BufferFlagHeader) == static_cast<int>(GST_BUFFER_FLAG_HEADER));
+ BOOST_STATIC_ASSERT(static_cast<int>(BufferFlagGap) == static_cast<int>(GST_BUFFER_FLAG_GAP));
+ BOOST_STATIC_ASSERT(static_cast<int>(BufferFlagDroppable) == static_cast<int>(GST_BUFFER_FLAG_DROPPABLE));
+ BOOST_STATIC_ASSERT(static_cast<int>(BufferFlagDeltaUnit) == static_cast<int>(GST_BUFFER_FLAG_DELTA_UNIT));
+ BOOST_STATIC_ASSERT(static_cast<int>(BufferFlagLast) == static_cast<int>(GST_BUFFER_FLAG_LAST));
+}
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(EventTypeUpstream) == static_cast<int>(GST_EVENT_TYPE_UPSTREAM));
+ BOOST_STATIC_ASSERT(static_cast<int>(EventTypeDownstream) == static_cast<int>(GST_EVENT_TYPE_DOWNSTREAM));
+ BOOST_STATIC_ASSERT(static_cast<int>(EventTypeSerialized) == static_cast<int>(GST_EVENT_TYPE_SERIALIZED));
+ BOOST_STATIC_ASSERT(static_cast<int>(EventTypeSticky) == static_cast<int>(GST_EVENT_TYPE_STICKY));
+ BOOST_STATIC_ASSERT(static_cast<int>(EventTypeStickyMulti) == static_cast<int>(GST_EVENT_TYPE_STICKY_MULTI));
+ BOOST_STATIC_ASSERT(static_cast<int>(EventTypeBoth) == static_cast<int>(GST_EVENT_TYPE_BOTH));
+}
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(EventUnknown) == static_cast<int>(GST_EVENT_UNKNOWN));
+ BOOST_STATIC_ASSERT(static_cast<int>(EventFlushStart) == static_cast<int>(GST_EVENT_FLUSH_START));
+ BOOST_STATIC_ASSERT(static_cast<int>(EventFlushStop) == static_cast<int>(GST_EVENT_FLUSH_STOP));
+ BOOST_STATIC_ASSERT(static_cast<int>(EventStreamStart) == static_cast<int>(GST_EVENT_STREAM_START));
+ BOOST_STATIC_ASSERT(static_cast<int>(EventCaps) == static_cast<int>(GST_EVENT_CAPS));
+ BOOST_STATIC_ASSERT(static_cast<int>(EventSegment) == static_cast<int>(GST_EVENT_SEGMENT));
+ BOOST_STATIC_ASSERT(static_cast<int>(EventTag) == static_cast<int>(GST_EVENT_TAG));
+ BOOST_STATIC_ASSERT(static_cast<int>(EventBufferSize) == static_cast<int>(GST_EVENT_BUFFERSIZE));
+ BOOST_STATIC_ASSERT(static_cast<int>(EventSinkMessage) == static_cast<int>(GST_EVENT_SINK_MESSAGE));
+ BOOST_STATIC_ASSERT(static_cast<int>(EventEos) == static_cast<int>(GST_EVENT_EOS));
+ BOOST_STATIC_ASSERT(static_cast<int>(EventToc) == static_cast<int>(GST_EVENT_TOC));
+ BOOST_STATIC_ASSERT(static_cast<int>(EventSegmentDone) == static_cast<int>(GST_EVENT_SEGMENT_DONE));
+ BOOST_STATIC_ASSERT(static_cast<int>(EventGap) == static_cast<int>(GST_EVENT_GAP));
+ BOOST_STATIC_ASSERT(static_cast<int>(EventQos) == static_cast<int>(GST_EVENT_QOS));
+ BOOST_STATIC_ASSERT(static_cast<int>(EventSeek) == static_cast<int>(GST_EVENT_SEEK));
+ BOOST_STATIC_ASSERT(static_cast<int>(EventNavigation) == static_cast<int>(GST_EVENT_NAVIGATION));
+ BOOST_STATIC_ASSERT(static_cast<int>(EventLatency) == static_cast<int>(GST_EVENT_LATENCY));
+ BOOST_STATIC_ASSERT(static_cast<int>(EventStep) == static_cast<int>(GST_EVENT_STEP));
+ BOOST_STATIC_ASSERT(static_cast<int>(EventReconfigure) == static_cast<int>(GST_EVENT_RECONFIGURE));
+ BOOST_STATIC_ASSERT(static_cast<int>(EventTocSelect) == static_cast<int>(GST_EVENT_TOC_SELECT));
+ BOOST_STATIC_ASSERT(static_cast<int>(EventCustomUpstream) == static_cast<int>(GST_EVENT_CUSTOM_UPSTREAM));
+ BOOST_STATIC_ASSERT(static_cast<int>(EventCustomDownstream) == static_cast<int>(GST_EVENT_CUSTOM_DOWNSTREAM));
+ BOOST_STATIC_ASSERT(static_cast<int>(EventCustomDownstreamOob) == static_cast<int>(GST_EVENT_CUSTOM_DOWNSTREAM_OOB));
+ BOOST_STATIC_ASSERT(static_cast<int>(EventCustomDownstreamSticky) == static_cast<int>(GST_EVENT_CUSTOM_DOWNSTREAM_STICKY));
+ BOOST_STATIC_ASSERT(static_cast<int>(EventCustomBoth) == static_cast<int>(GST_EVENT_CUSTOM_BOTH));
+ BOOST_STATIC_ASSERT(static_cast<int>(EventCustomBothOob) == static_cast<int>(GST_EVENT_CUSTOM_BOTH_OOB));
+}
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(SeekFlagNone) == static_cast<int>(GST_SEEK_FLAG_NONE));
+ BOOST_STATIC_ASSERT(static_cast<int>(SeekFlagFlush) == static_cast<int>(GST_SEEK_FLAG_FLUSH));
+ BOOST_STATIC_ASSERT(static_cast<int>(SeekFlagAccurate) == static_cast<int>(GST_SEEK_FLAG_ACCURATE));
+ BOOST_STATIC_ASSERT(static_cast<int>(SeekFlagKeyUnit) == static_cast<int>(GST_SEEK_FLAG_KEY_UNIT));
+ BOOST_STATIC_ASSERT(static_cast<int>(SeekFlagSegment) == static_cast<int>(GST_SEEK_FLAG_SEGMENT));
+ BOOST_STATIC_ASSERT(static_cast<int>(SeekFlagSkip) == static_cast<int>(GST_SEEK_FLAG_SKIP));
+}
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(SeekTypeNone) == static_cast<int>(GST_SEEK_TYPE_NONE));
+ BOOST_STATIC_ASSERT(static_cast<int>(SeekTypeSet) == static_cast<int>(GST_SEEK_TYPE_SET));
+ BOOST_STATIC_ASSERT(static_cast<int>(SeekTypeEnd) == static_cast<int>(GST_SEEK_TYPE_END));
+}
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(SegmentFlagNone) == static_cast<int>(GST_SEGMENT_FLAG_NONE));
+ BOOST_STATIC_ASSERT(static_cast<int>(SegmentFlagReset) == static_cast<int>(GST_SEGMENT_FLAG_RESET));
+ BOOST_STATIC_ASSERT(static_cast<int>(SegmentFlagSkip) == static_cast<int>(GST_SEGMENT_FLAG_SKIP));
+ BOOST_STATIC_ASSERT(static_cast<int>(SegmentFlagSegment) == static_cast<int>(GST_SEGMENT_FLAG_SEGMENT));
+}
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(QosTypeOverflow) == static_cast<int>(GST_QOS_TYPE_OVERFLOW));
+ BOOST_STATIC_ASSERT(static_cast<int>(QosTypeUnderflow) == static_cast<int>(GST_QOS_TYPE_UNDERFLOW));
+ BOOST_STATIC_ASSERT(static_cast<int>(QosTypeThrottle) == static_cast<int>(GST_QOS_TYPE_THROTTLE));
+}
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(TagMergeUndefined) == static_cast<int>(GST_TAG_MERGE_UNDEFINED));
+ BOOST_STATIC_ASSERT(static_cast<int>(TagMergeReplaceAll) == static_cast<int>(GST_TAG_MERGE_REPLACE_ALL));
+ BOOST_STATIC_ASSERT(static_cast<int>(TagMergeReplace) == static_cast<int>(GST_TAG_MERGE_REPLACE));
+ BOOST_STATIC_ASSERT(static_cast<int>(TagMergeAppend) == static_cast<int>(GST_TAG_MERGE_APPEND));
+ BOOST_STATIC_ASSERT(static_cast<int>(TagMergePrepend) == static_cast<int>(GST_TAG_MERGE_PREPEND));
+ BOOST_STATIC_ASSERT(static_cast<int>(TagMergeKeep) == static_cast<int>(GST_TAG_MERGE_KEEP));
+ BOOST_STATIC_ASSERT(static_cast<int>(TagMergeKeepAll) == static_cast<int>(GST_TAG_MERGE_KEEP_ALL));
+ BOOST_STATIC_ASSERT(static_cast<int>(TagMergeCount) == static_cast<int>(GST_TAG_MERGE_COUNT));
+}
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(TagFlagUndefined) == static_cast<int>(GST_TAG_FLAG_UNDEFINED));
+ BOOST_STATIC_ASSERT(static_cast<int>(TagFlagMeta) == static_cast<int>(GST_TAG_FLAG_META));
+ BOOST_STATIC_ASSERT(static_cast<int>(TagFlagEncoded) == static_cast<int>(GST_TAG_FLAG_ENCODED));
+ BOOST_STATIC_ASSERT(static_cast<int>(TagFlagDecoded) == static_cast<int>(GST_TAG_FLAG_DECODED));
+ BOOST_STATIC_ASSERT(static_cast<int>(TagFlagCount) == static_cast<int>(GST_TAG_FLAG_COUNT));
+}
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(AppStreamTypeStream) == static_cast<int>(GST_APP_STREAM_TYPE_STREAM));
+ BOOST_STATIC_ASSERT(static_cast<int>(AppStreamTypeSeekable) == static_cast<int>(GST_APP_STREAM_TYPE_SEEKABLE));
+ BOOST_STATIC_ASSERT(static_cast<int>(AppStreamTypeRandomAccess) == static_cast<int>(GST_APP_STREAM_TYPE_RANDOM_ACCESS));
+}
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(DiscovererOk) == static_cast<int>(GST_DISCOVERER_OK));
+ BOOST_STATIC_ASSERT(static_cast<int>(DiscovererUriInvalid) == static_cast<int>(GST_DISCOVERER_URI_INVALID));
+ BOOST_STATIC_ASSERT(static_cast<int>(DiscovererError) == static_cast<int>(GST_DISCOVERER_ERROR));
+ BOOST_STATIC_ASSERT(static_cast<int>(DiscovererTimeout) == static_cast<int>(GST_DISCOVERER_TIMEOUT));
+ BOOST_STATIC_ASSERT(static_cast<int>(DiscovererBusy) == static_cast<int>(GST_DISCOVERER_BUSY));
+ BOOST_STATIC_ASSERT(static_cast<int>(DiscovererMissingPlugins) == static_cast<int>(GST_DISCOVERER_MISSING_PLUGINS));
+}
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(MapRead) == static_cast<int>(GST_MAP_READ));
+ BOOST_STATIC_ASSERT(static_cast<int>(MapWrite) == static_cast<int>(GST_MAP_WRITE));
+ BOOST_STATIC_ASSERT(static_cast<int>(MapFlagLast) == static_cast<int>(GST_MAP_FLAG_LAST));
+}
+
+namespace QGst {
+ BOOST_STATIC_ASSERT(static_cast<int>(MemoryFlagReadonly) == static_cast<int>(GST_MEMORY_FLAG_READONLY));
+ BOOST_STATIC_ASSERT(static_cast<int>(MemoryFlagNoShare) == static_cast<int>(GST_MEMORY_FLAG_NO_SHARE));
+ BOOST_STATIC_ASSERT(static_cast<int>(MemoryFlagZeroPrefixed) == static_cast<int>(GST_MEMORY_FLAG_ZERO_PREFIXED));
+ BOOST_STATIC_ASSERT(static_cast<int>(MemoryFlagZeroPadded) == static_cast<int>(GST_MEMORY_FLAG_ZERO_PADDED));
+ BOOST_STATIC_ASSERT(static_cast<int>(MemoryFlagPhysicallyContiguous) == static_cast<int>(GST_MEMORY_FLAG_PHYSICALLY_CONTIGUOUS));
+ BOOST_STATIC_ASSERT(static_cast<int>(MemoryFlagNotMappable) == static_cast<int>(GST_MEMORY_FLAG_NOT_MAPPABLE));
+ BOOST_STATIC_ASSERT(static_cast<int>(MemoryFlagLast) == static_cast<int>(GST_MEMORY_FLAG_LAST));
+}
+
+#include "QGst/objectstore_p.h"
+
+#include "QGst/ghostpad.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::GhostPad,GST_TYPE_GHOST_PAD)
+
+namespace QGst {
+ QGlib::RefCountedObject *GhostPad_new(void *instance)
+ {
+ QGst::GhostPad *cppClass = new QGst::GhostPad;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+#include "QGst/pluginfeature.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::PluginFeature,GST_TYPE_PLUGIN_FEATURE)
+
+namespace QGst {
+ QGlib::RefCountedObject *PluginFeature_new(void *instance)
+ {
+ QGst::PluginFeature *cppClass = new QGst::PluginFeature;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+#include "QGst/taglist.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::TagList,GST_TYPE_TAG_LIST)
+
+#include "QGst/memory.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::Memory,GST_TYPE_MEMORY)
+
+namespace QGst {
+ QGlib::RefCountedObject *Memory_new(void *instance)
+ {
+ QGst::Memory *cppClass = new QGst::Memory;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+#include "QGst/object.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::Object,GST_TYPE_OBJECT)
+
+namespace QGst {
+ QGlib::RefCountedObject *Object_new(void *instance)
+ {
+ QGst::Object *cppClass = new QGst::Object;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+#include "QGst/videoorientation.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::VideoOrientation,GST_TYPE_VIDEO_ORIENTATION)
+
+namespace QGst {
+ QGlib::RefCountedObject *VideoOrientation_new(void *instance)
+ {
+ QGst::VideoOrientation *cppClass = new QGst::VideoOrientation;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+#include "QGst/bus.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::Bus,GST_TYPE_BUS)
+
+namespace QGst {
+ QGlib::RefCountedObject *Bus_new(void *instance)
+ {
+ QGst::Bus *cppClass = new QGst::Bus;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+#include "QGst/pipeline.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::Pipeline,GST_TYPE_PIPELINE)
+
+namespace QGst {
+ QGlib::RefCountedObject *Pipeline_new(void *instance)
+ {
+ QGst::Pipeline *cppClass = new QGst::Pipeline;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+#include "QGst/structs.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::Fourcc,G_TYPE_UINT)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::Fraction,GST_TYPE_FRACTION)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::IntRange,GST_TYPE_INT_RANGE)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::Int64Range,GST_TYPE_INT64_RANGE)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::DoubleRange,GST_TYPE_DOUBLE_RANGE)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::FractionRange,GST_TYPE_FRACTION_RANGE)
+
+#include "QGst/structure.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::Structure,GST_TYPE_STRUCTURE)
+
+#include "QGst/childproxy.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::ChildProxy,GST_TYPE_CHILD_PROXY)
+
+namespace QGst {
+ QGlib::RefCountedObject *ChildProxy_new(void *instance)
+ {
+ QGst::ChildProxy *cppClass = new QGst::ChildProxy;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+#include "QGst/bin.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::Bin,GST_TYPE_BIN)
+
+namespace QGst {
+ QGlib::RefCountedObject *Bin_new(void *instance)
+ {
+ QGst::Bin *cppClass = new QGst::Bin;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+
+
+#include "QGst/element.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::Element,GST_TYPE_ELEMENT)
+
+namespace QGst {
+ QGlib::RefCountedObject *Element_new(void *instance)
+ {
+ QGst::Element *cppClass = new QGst::Element;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+#include "QGst/colorbalance.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::ColorBalanceChannel,GST_TYPE_COLOR_BALANCE_CHANNEL)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::ColorBalance,GST_TYPE_COLOR_BALANCE)
+
+namespace QGst {
+ QGlib::RefCountedObject *ColorBalanceChannel_new(void *instance)
+ {
+ QGst::ColorBalanceChannel *cppClass = new QGst::ColorBalanceChannel;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+namespace QGst {
+ QGlib::RefCountedObject *ColorBalance_new(void *instance)
+ {
+ QGst::ColorBalance *cppClass = new QGst::ColorBalance;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+#include "QGst/caps.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::Caps,GST_TYPE_CAPS)
+
+namespace QGst {
+ QGlib::RefCountedObject *Caps_new(void *instance)
+ {
+ QGst::Caps *cppClass = new QGst::Caps;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+#include "QGst/init.h"
+
+#include "QGst/buffer.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::Buffer,GST_TYPE_BUFFER)
+
+namespace QGst {
+ QGlib::RefCountedObject *Buffer_new(void *instance)
+ {
+ QGst::Buffer *cppClass = new QGst::Buffer;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+#include "QGst/allocator.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::Allocator,GST_TYPE_ALLOCATOR)
+
+namespace QGst {
+ QGlib::RefCountedObject *Allocator_new(void *instance)
+ {
+ QGst::Allocator *cppClass = new QGst::Allocator;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+#include "QGst/devicemonitor.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::DeviceMonitor,GST_TYPE_DEVICE_MONITOR)
+
+namespace QGst {
+ QGlib::RefCountedObject *DeviceMonitor_new(void *instance)
+ {
+ QGst::DeviceMonitor *cppClass = new QGst::DeviceMonitor;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+#include "QGst/device.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::Device,GST_TYPE_DEVICE)
+
+namespace QGst {
+ QGlib::RefCountedObject *Device_new(void *instance)
+ {
+ QGst::Device *cppClass = new QGst::Device;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+#include "QGst/clocktime.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::ClockTime,GST_TYPE_CLOCK_TIME)
+
+#include "QGst/event.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::Event,GST_TYPE_EVENT)
+
+namespace QGst {
+ QGlib::RefCountedObject *Event_new(void *instance)
+ {
+ QGst::Event *cppClass = NULL;
+ switch(GST_EVENT_TYPE(instance)) {
+ case QGst::EventFlushStart:
+ cppClass = new QGst::FlushStartEvent;
+ break;
+ case QGst::EventFlushStop:
+ cppClass = new QGst::FlushStopEvent;
+ break;
+ case QGst::EventEos:
+ cppClass = new QGst::EosEvent;
+ break;
+ case QGst::EventCaps:
+ cppClass = new QGst::CapsEvent;
+ break;
+ case QGst::EventSegment:
+ cppClass = new QGst::SegmentEvent;
+ break;
+ case QGst::EventTag:
+ cppClass = new QGst::TagEvent;
+ break;
+ case QGst::EventBufferSize:
+ cppClass = new QGst::BufferSizeEvent;
+ break;
+ case QGst::EventSinkMessage:
+ cppClass = new QGst::SinkMessageEvent;
+ break;
+ case QGst::EventQos:
+ cppClass = new QGst::QosEvent;
+ break;
+ case QGst::EventSeek:
+ cppClass = new QGst::SeekEvent;
+ break;
+ case QGst::EventNavigation:
+ cppClass = new QGst::NavigationEvent;
+ break;
+ case QGst::EventLatency:
+ cppClass = new QGst::LatencyEvent;
+ break;
+ case QGst::EventStep:
+ cppClass = new QGst::StepEvent;
+ break;
+ default:
+ cppClass = new QGst::Event;
+ break;
+ }
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+#include "QGst/discoverer.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::DiscovererStreamInfo,GST_TYPE_DISCOVERER_STREAM_INFO)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::DiscovererContainerInfo,GST_TYPE_DISCOVERER_CONTAINER_INFO)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::DiscovererAudioInfo,GST_TYPE_DISCOVERER_AUDIO_INFO)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::DiscovererVideoInfo,GST_TYPE_DISCOVERER_VIDEO_INFO)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::DiscovererSubtitleInfo,GST_TYPE_DISCOVERER_SUBTITLE_INFO)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::DiscovererInfo,GST_TYPE_DISCOVERER_INFO)
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::Discoverer,GST_TYPE_DISCOVERER)
+
+namespace QGst {
+ QGlib::RefCountedObject *DiscovererStreamInfo_new(void *instance)
+ {
+ QGst::DiscovererStreamInfo *cppClass = new QGst::DiscovererStreamInfo;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+namespace QGst {
+ QGlib::RefCountedObject *DiscovererContainerInfo_new(void *instance)
+ {
+ QGst::DiscovererContainerInfo *cppClass = new QGst::DiscovererContainerInfo;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+namespace QGst {
+ QGlib::RefCountedObject *DiscovererAudioInfo_new(void *instance)
+ {
+ QGst::DiscovererAudioInfo *cppClass = new QGst::DiscovererAudioInfo;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+namespace QGst {
+ QGlib::RefCountedObject *DiscovererVideoInfo_new(void *instance)
+ {
+ QGst::DiscovererVideoInfo *cppClass = new QGst::DiscovererVideoInfo;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+namespace QGst {
+ QGlib::RefCountedObject *DiscovererSubtitleInfo_new(void *instance)
+ {
+ QGst::DiscovererSubtitleInfo *cppClass = new QGst::DiscovererSubtitleInfo;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+namespace QGst {
+ QGlib::RefCountedObject *DiscovererInfo_new(void *instance)
+ {
+ QGst::DiscovererInfo *cppClass = new QGst::DiscovererInfo;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+namespace QGst {
+ QGlib::RefCountedObject *Discoverer_new(void *instance)
+ {
+ QGst::Discoverer *cppClass = new QGst::Discoverer;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+#include "QGst/elementfactory.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::ElementFactory,GST_TYPE_ELEMENT_FACTORY)
+
+namespace QGst {
+ QGlib::RefCountedObject *ElementFactory_new(void *instance)
+ {
+ QGst::ElementFactory *cppClass = new QGst::ElementFactory;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+#include "QGst/miniobject.h"
+
+#include "QGst/query.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::Query,GST_TYPE_QUERY)
+
+namespace QGst {
+ QGlib::RefCountedObject *Query_new(void *instance)
+ {
+ QGst::Query *cppClass = NULL;
+ switch(GST_QUERY_TYPE(instance)) {
+ case QGst::QueryPosition:
+ cppClass = new QGst::PositionQuery;
+ break;
+ case QGst::QueryDuration:
+ cppClass = new QGst::DurationQuery;
+ break;
+ case QGst::QueryLatency:
+ cppClass = new QGst::LatencyQuery;
+ break;
+ case QGst::QuerySeeking:
+ cppClass = new QGst::SeekingQuery;
+ break;
+ case QGst::QuerySegment:
+ cppClass = new QGst::SegmentQuery;
+ break;
+ case QGst::QueryConvert:
+ cppClass = new QGst::ConvertQuery;
+ break;
+ case QGst::QueryFormats:
+ cppClass = new QGst::FormatsQuery;
+ break;
+ case QGst::QueryBuffering:
+ cppClass = new QGst::BufferingQuery;
+ break;
+ case QGst::QueryUri:
+ cppClass = new QGst::UriQuery;
+ break;
+ default:
+ cppClass = new QGst::Query;
+ break;
+ }
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+#include "QGst/streamvolume.h"
+
+REGISTER_TYPE_IMPLEMENTATION(QGst::StreamVolume,GST_TYPE_STREAM_VOLUME)
+
+namespace QGst {
+ QGlib::RefCountedObject *StreamVolume_new(void *instance)
+ {
+ QGst::StreamVolume *cppClass = new QGst::StreamVolume;
+ cppClass->m_object = instance;
+ return cppClass;
+ }
+} //namespace QGst
+
+namespace QGst {
+namespace Private {
+ void registerWrapperConstructors()
+ {
+ QGlib::Quark q = g_quark_from_static_string("QGlib__wrapper_constructor");
+ QGlib::GetType<UriHandler>().setQuarkData(q, reinterpret_cast<void*>(&UriHandler_new));
+ QGlib::GetType<Pad>().setQuarkData(q, reinterpret_cast<void*>(&Pad_new));
+ QGlib::GetType<Clock>().setQuarkData(q, reinterpret_cast<void*>(&Clock_new));
+ QGlib::GetType<VideoOverlay>().setQuarkData(q, reinterpret_cast<void*>(&VideoOverlay_new));
+ QGlib::GetType<Sample>().setQuarkData(q, reinterpret_cast<void*>(&Sample_new));
+ QGlib::GetType<Message>().setQuarkData(q, reinterpret_cast<void*>(&Message_new));
+ QGlib::GetType<BufferList>().setQuarkData(q, reinterpret_cast<void*>(&BufferList_new));
+ QGlib::GetType<GhostPad>().setQuarkData(q, reinterpret_cast<void*>(&GhostPad_new));
+ QGlib::GetType<PluginFeature>().setQuarkData(q, reinterpret_cast<void*>(&PluginFeature_new));
+ QGlib::GetType<Memory>().setQuarkData(q, reinterpret_cast<void*>(&Memory_new));
+ QGlib::GetType<Object>().setQuarkData(q, reinterpret_cast<void*>(&Object_new));
+ QGlib::GetType<VideoOrientation>().setQuarkData(q, reinterpret_cast<void*>(&VideoOrientation_new));
+ QGlib::GetType<Bus>().setQuarkData(q, reinterpret_cast<void*>(&Bus_new));
+ QGlib::GetType<Pipeline>().setQuarkData(q, reinterpret_cast<void*>(&Pipeline_new));
+ QGlib::GetType<ChildProxy>().setQuarkData(q, reinterpret_cast<void*>(&ChildProxy_new));
+ QGlib::GetType<Bin>().setQuarkData(q, reinterpret_cast<void*>(&Bin_new));
+ QGlib::GetType<Element>().setQuarkData(q, reinterpret_cast<void*>(&Element_new));
+ QGlib::GetType<ColorBalanceChannel>().setQuarkData(q, reinterpret_cast<void*>(&ColorBalanceChannel_new));
+ QGlib::GetType<ColorBalance>().setQuarkData(q, reinterpret_cast<void*>(&ColorBalance_new));
+ QGlib::GetType<Caps>().setQuarkData(q, reinterpret_cast<void*>(&Caps_new));
+ QGlib::GetType<Buffer>().setQuarkData(q, reinterpret_cast<void*>(&Buffer_new));
+ QGlib::GetType<Allocator>().setQuarkData(q, reinterpret_cast<void*>(&Allocator_new));
+ QGlib::GetType<DeviceMonitor>().setQuarkData(q, reinterpret_cast<void*>(&DeviceMonitor_new));
+ QGlib::GetType<Device>().setQuarkData(q, reinterpret_cast<void*>(&Device_new));
+ QGlib::GetType<Event>().setQuarkData(q, reinterpret_cast<void*>(&Event_new));
+ QGlib::GetType<DiscovererStreamInfo>().setQuarkData(q, reinterpret_cast<void*>(&DiscovererStreamInfo_new));
+ QGlib::GetType<DiscovererContainerInfo>().setQuarkData(q, reinterpret_cast<void*>(&DiscovererContainerInfo_new));
+ QGlib::GetType<DiscovererAudioInfo>().setQuarkData(q, reinterpret_cast<void*>(&DiscovererAudioInfo_new));
+ QGlib::GetType<DiscovererVideoInfo>().setQuarkData(q, reinterpret_cast<void*>(&DiscovererVideoInfo_new));
+ QGlib::GetType<DiscovererSubtitleInfo>().setQuarkData(q, reinterpret_cast<void*>(&DiscovererSubtitleInfo_new));
+ QGlib::GetType<DiscovererInfo>().setQuarkData(q, reinterpret_cast<void*>(&DiscovererInfo_new));
+ QGlib::GetType<Discoverer>().setQuarkData(q, reinterpret_cast<void*>(&Discoverer_new));
+ QGlib::GetType<ElementFactory>().setQuarkData(q, reinterpret_cast<void*>(&ElementFactory_new));
+ QGlib::GetType<Query>().setQuarkData(q, reinterpret_cast<void*>(&Query_new));
+ QGlib::GetType<StreamVolume>().setQuarkData(q, reinterpret_cast<void*>(&StreamVolume_new));
+ }
+} //namespace Private
+} //namespace QGst
+
diff --git a/src/QGst/ghostpad.cpp b/src/QGst/ghostpad.cpp
index 501a4e4..e05c33e 100644
--- a/src/QGst/ghostpad.cpp
+++ b/src/QGst/ghostpad.cpp
@@ -9,13 +9,13 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
*/
#include "ghostpad.h"
-#include <gst/gstghostpad.h>
+#include <gst/gst.h>
namespace QGst {
diff --git a/src/QGst/ghostpad.h b/src/QGst/ghostpad.h
index 0a80146..fe0cfc7 100644
--- a/src/QGst/ghostpad.h
+++ b/src/QGst/ghostpad.h
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/src/QGst/global.h b/src/QGst/global.h
index ae64cfd..f5464b1 100644
--- a/src/QGst/global.h
+++ b/src/QGst/global.h
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -17,13 +17,18 @@
#ifndef QGST_GLOBAL_H
#define QGST_GLOBAL_H
+// workaround for https://bugreports.qt-project.org/browse/QTBUG-22829
+#if defined(Q_MOC_RUN) && !defined(BOOST_TT_HAS_OPERATOR_HPP_INCLUDED)
+#define BOOST_TT_HAS_OPERATOR_HPP_INCLUDED
+#endif
+
#include "../QGlib/type.h"
#include <QtCore/QtGlobal>
#include <QtCore/QDate>
#include <QtCore/QSharedPointer>
/* defined by cmake when building this library */
-#if defined(QtGStreamer_EXPORTS)
+#if defined(QtGStreamer_EXPORTS) || defined(Qt5GStreamer_EXPORTS)
# define QTGSTREAMER_EXPORT Q_DECL_EXPORT
#else
# define QTGSTREAMER_EXPORT Q_DECL_IMPORT
@@ -70,6 +75,15 @@ QGST_WRAPPER_DECLARATION(ChildProxy)
QGST_WRAPPER_DECLARATION(Clock)
QGST_WRAPPER_DECLARATION(ColorBalanceChannel)
QGST_WRAPPER_DECLARATION(ColorBalance)
+QGST_WRAPPER_DECLARATION(Device)
+QGST_WRAPPER_DECLARATION(DeviceMonitor)
+QGST_WRAPPER_DECLARATION(Discoverer)
+QGST_WRAPPER_DECLARATION(DiscovererInfo)
+QGST_WRAPPER_DECLARATION(DiscovererStreamInfo)
+QGST_WRAPPER_DECLARATION(DiscovererContainerInfo)
+QGST_WRAPPER_DECLARATION(DiscovererAudioInfo)
+QGST_WRAPPER_DECLARATION(DiscovererVideoInfo)
+QGST_WRAPPER_DECLARATION(DiscovererSubtitleInfo)
QGST_WRAPPER_DECLARATION(Element)
QGST_WRAPPER_DECLARATION(ElementFactory)
QGST_WRAPPER_DECLARATION(GhostPad)
@@ -86,18 +100,19 @@ QGST_WRAPPER_REFPOINTER_DECLARATION(StreamStatusMessage)
QGST_WRAPPER_REFPOINTER_DECLARATION(ApplicationMessage)
QGST_WRAPPER_REFPOINTER_DECLARATION(ElementMessage)
QGST_WRAPPER_REFPOINTER_DECLARATION(SegmentDoneMessage)
-QGST_WRAPPER_REFPOINTER_DECLARATION(DurationMessage)
+QGST_WRAPPER_REFPOINTER_DECLARATION(DurationChangedMessage)
QGST_WRAPPER_REFPOINTER_DECLARATION(LatencyMessage)
QGST_WRAPPER_REFPOINTER_DECLARATION(AsyncDoneMessage)
QGST_WRAPPER_REFPOINTER_DECLARATION(RequestStateMessage)
QGST_WRAPPER_REFPOINTER_DECLARATION(StepStartMessage)
QGST_WRAPPER_REFPOINTER_DECLARATION(QosMessage)
+QGST_WRAPPER_REFPOINTER_DECLARATION(DeviceAddedMessage)
+QGST_WRAPPER_REFPOINTER_DECLARATION(DeviceRemovedMessage)
QGST_WRAPPER_DECLARATION(MiniObject)
QGST_WRAPPER_DECLARATION(Object)
QGST_WRAPPER_DECLARATION(Pad)
QGST_WRAPPER_DECLARATION(Pipeline)
QGST_WRAPPER_DECLARATION(PluginFeature)
-QGST_WRAPPER_DECLARATION(PropertyProbe)
QGST_WRAPPER_DECLARATION(Query)
QGST_WRAPPER_REFPOINTER_DECLARATION(PositionQuery)
QGST_WRAPPER_REFPOINTER_DECLARATION(DurationQuery)
@@ -109,13 +124,15 @@ QGST_WRAPPER_REFPOINTER_DECLARATION(FormatsQuery)
QGST_WRAPPER_REFPOINTER_DECLARATION(BufferingQuery)
QGST_WRAPPER_REFPOINTER_DECLARATION(UriQuery)
QGST_WRAPPER_DECLARATION(Buffer)
+QGST_WRAPPER_DECLARATION(Allocator)
+QGST_WRAPPER_DECLARATION(Memory)
QGST_WRAPPER_DECLARATION(BufferList)
-QGST_WRAPPER_GSTCLASS_DECLARATION(BufferListIterator)
QGST_WRAPPER_DECLARATION(Event)
QGST_WRAPPER_REFPOINTER_DECLARATION(FlushStartEvent)
QGST_WRAPPER_REFPOINTER_DECLARATION(FlushStopEvent)
+QGST_WRAPPER_REFPOINTER_DECLARATION(CapsEvent)
QGST_WRAPPER_REFPOINTER_DECLARATION(EosEvent)
-QGST_WRAPPER_REFPOINTER_DECLARATION(NewSegmentEvent)
+QGST_WRAPPER_REFPOINTER_DECLARATION(SegmentEvent)
QGST_WRAPPER_REFPOINTER_DECLARATION(TagEvent)
QGST_WRAPPER_REFPOINTER_DECLARATION(BufferSizeEvent)
QGST_WRAPPER_REFPOINTER_DECLARATION(SinkMessageEvent)
@@ -125,18 +142,24 @@ QGST_WRAPPER_REFPOINTER_DECLARATION(NavigationEvent)
QGST_WRAPPER_REFPOINTER_DECLARATION(LatencyEvent)
QGST_WRAPPER_REFPOINTER_DECLARATION(StepEvent)
QGST_WRAPPER_DECLARATION(StreamVolume)
+QGST_WRAPPER_DECLARATION(Sample)
QGST_WRAPPER_GSTCLASS_DECLARATION(Structure)
-QGST_WRAPPER_DIFFERENT_GSTCLASS_DECLARATION(TagList,Structure)
-
+QGST_WRAPPER_GSTCLASS_DECLARATION(TagList)
+QGST_WRAPPER_GSTCLASS_DECLARATION(Segment)
+QGST_WRAPPER_GSTCLASS_DECLARATION(AllocationParams)
namespace QGst {
class Structure;
class SharedStructure;
typedef QSharedPointer<SharedStructure> StructurePtr;
+ typedef QSharedPointer<const SharedStructure> StructureConstPtr;
+ class AllocationParams;
+ class MapInfo;
+ class Segment;
}
QGST_WRAPPER_GSTCLASS_DECLARATION(URIHandler)
QGST_WRAPPER_REFPOINTER_DECLARATION(UriHandler)
QGST_WRAPPER_DECLARATION(VideoOrientation)
-QGST_WRAPPER_DECLARATION(XOverlay)
+QGST_WRAPPER_DECLARATION(VideoOverlay)
#undef QGST_WRAPPER_DECLARATION
#undef QGST_WRAPPER_REFPOINTER_DECLARATION
diff --git a/src/QGst/init.cpp b/src/QGst/init.cpp
index aa17d3d..8d8ec57 100644
--- a/src/QGst/init.cpp
+++ b/src/QGst/init.cpp
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/src/QGst/init.h b/src/QGst/init.h
index 2cb8d07..9c25ee9 100644
--- a/src/QGst/init.h
+++ b/src/QGst/init.h
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/src/QGst/memory.cpp b/src/QGst/memory.cpp
new file mode 100644
index 0000000..c3b55e3
--- /dev/null
+++ b/src/QGst/memory.cpp
@@ -0,0 +1,93 @@
+/*
+ Copyright (C) 2013 Diane Trout <diane@ghic.org>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#include "allocator.h"
+#include "memory.h"
+#include "buffer.h"
+#include <gst/gst.h>
+
+namespace QGst {
+
+MapInfo::MapInfo()
+{
+ m_object = g_slice_new0(GstMapInfo);
+}
+
+MapInfo::~MapInfo()
+{
+ g_slice_free(GstMapInfo, m_object);
+}
+
+MapFlags MapInfo::flags() const
+{
+ return static_cast<MapFlag>(static_cast<GstMapInfo*>(m_object)->flags);
+}
+
+quint8 *MapInfo::data() const
+{
+ return static_cast<GstMapInfo*>(m_object)->data;
+}
+
+size_t MapInfo::size() const
+{
+ return static_cast<GstMapInfo*>(m_object)->size;
+}
+
+size_t MapInfo::maxSize() const
+{
+ return static_cast<GstMapInfo*>(m_object)->maxsize;
+}
+
+//-----------------------
+
+AllocatorPtr Memory::allocator() const
+{
+ return AllocatorPtr::wrap(object<GstMemory>()->allocator);
+}
+
+size_t Memory::size() const
+{
+ return object<GstMemory>()->size;
+}
+
+size_t Memory::offset() const
+{
+ return object<GstMemory>()->offset;
+}
+
+size_t Memory::maxSize() const
+{
+ return object<GstMemory>()->maxsize;
+}
+
+bool Memory::isType(const char *type) const
+{
+ return gst_memory_is_type(object<GstMemory>(), type);
+}
+
+bool Memory::map(MapInfo &info, MapFlags flags)
+{
+ return gst_memory_map(object<GstMemory>(), static_cast<GstMapInfo*>(info.m_object),
+ static_cast<GstMapFlags>(static_cast<int>(flags)));
+}
+
+void Memory::unmap(MapInfo &info)
+{
+ gst_memory_unmap(object<GstMemory>(), static_cast<GstMapInfo*>(info.m_object));
+}
+
+} // namespace QGst
+
diff --git a/src/QGst/memory.h b/src/QGst/memory.h
new file mode 100644
index 0000000..e3faaa8
--- /dev/null
+++ b/src/QGst/memory.h
@@ -0,0 +1,71 @@
+/*
+ Copyright (C) 2014 Diane Trout <diane@ghic.org>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#ifndef QGST_MEMORY_H
+#define QGST_MEMORY_H
+
+#include "global.h"
+#include "miniobject.h"
+
+namespace QGst {
+
+class QTGSTREAMER_EXPORT MapInfo
+{
+public:
+ MapInfo();
+ virtual ~MapInfo();
+
+ MapFlags flags() const;
+ quint8 *data() const;
+ size_t size() const;
+ size_t maxSize() const;
+
+private:
+ friend class Buffer;
+ friend class Memory;
+ Q_DISABLE_COPY(MapInfo);
+
+ void *m_object;
+};
+
+/*! \headerfile memory.h <QGst/QGstMemory>
+ * \brief Wrapper class for GstMemory
+ *
+ * GstMemory is a lightweight refcounted object that wraps a region
+ * of memory. They are typically used to manage the data of a
+ * GstBuffer.
+ */
+class QTGSTREAMER_EXPORT Memory : public MiniObject
+{
+ QGST_WRAPPER(Memory)
+public:
+ QGst::AllocatorPtr allocator() const;
+
+ size_t size() const;
+ size_t offset() const;
+ size_t maxSize() const;
+
+ bool isType(const char *type) const;
+
+ bool map(MapInfo &info, MapFlags flags);
+ void unmap(MapInfo &info);
+};
+
+} // namespace QGst
+
+QGST_REGISTER_TYPE(QGst::Memory)
+
+#endif
diff --git a/src/QGst/message.cpp b/src/QGst/message.cpp
index e6127c2..ae845cc 100644
--- a/src/QGst/message.cpp
+++ b/src/QGst/message.cpp
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -43,9 +43,10 @@ MessageType Message::type() const
return static_cast<MessageType>(GST_MESSAGE_TYPE(object<GstMessage>()));
}
-StructurePtr Message::internalStructure()
+StructureConstPtr Message::internalStructure()
{
- return SharedStructure::fromMiniObject(object<GstMessage>()->structure, MiniObjectPtr(this));
+ const GstStructure *structure = gst_message_get_structure(object<GstMessage>());
+ return SharedStructure::fromMiniObject(const_cast<GstStructure *>(structure), MiniObjectPtr(this));
}
quint32 Message::sequenceNumber() const
@@ -347,7 +348,7 @@ void StreamStatusMessage::setStreamStatusObject(const QGlib::Value & obj)
ApplicationMessagePtr ApplicationMessage::create(const ObjectPtr & source, const Structure & structure)
{
- GstStructure *s = structure.isValid() ? gst_structure_copy(structure) : NULL;
+ GstStructure *s = structure.isValid() ? gst_structure_copy(structure) : gst_structure_new_empty("null");
return ApplicationMessagePtr::wrap(gst_message_new_application(source, s), false);
}
@@ -355,7 +356,7 @@ ApplicationMessagePtr ApplicationMessage::create(const ObjectPtr & source, const
ElementMessagePtr ElementMessage::create(const ObjectPtr & source, const Structure & structure)
{
- GstStructure *s = structure.isValid() ? gst_structure_copy(structure) : NULL;
+ GstStructure *s = structure.isValid() ? gst_structure_copy(structure) : gst_structure_new_empty("null");
return ElementMessagePtr::wrap(gst_message_new_element(source, s), false);
}
@@ -383,24 +384,10 @@ qint64 SegmentDoneMessage::position() const
//********************************************************
-DurationMessagePtr DurationMessage::create(const ObjectPtr & source, Format format, qint64 duration)
+DurationChangedMessagePtr DurationChangedMessage::create(const ObjectPtr & source)
{
- GstMessage *m = gst_message_new_duration(source, static_cast<GstFormat>(format), duration);
- return DurationMessagePtr::wrap(m, false);
-}
-
-Format DurationMessage::format() const
-{
- GstFormat f;
- gst_message_parse_duration(object<GstMessage>(), &f, NULL);
- return static_cast<Format>(f);
-}
-
-qint64 DurationMessage::duration() const
-{
- gint64 d;
- gst_message_parse_duration(object<GstMessage>(), NULL, &d);
- return d;
+ GstMessage *m = gst_message_new_duration_changed(source);
+ return DurationChangedMessagePtr::wrap(m, false);
}
//********************************************************
@@ -412,9 +399,16 @@ LatencyMessagePtr LatencyMessage::create(const ObjectPtr & source)
//********************************************************
-AsyncDoneMessagePtr AsyncDoneMessage::create(const ObjectPtr & source)
+AsyncDoneMessagePtr AsyncDoneMessage::create(const ObjectPtr & source, ClockTime running_time)
{
- return AsyncDoneMessagePtr::wrap(gst_message_new_async_done(source), false);
+ return AsyncDoneMessagePtr::wrap(gst_message_new_async_done(source, running_time), false);
+}
+
+ClockTime AsyncDoneMessage::runningTime() const
+{
+ GstClockTime c;
+ gst_message_parse_async_done(object<GstMessage>(), &c);
+ return static_cast<ClockTime>(c);
}
//********************************************************
@@ -581,4 +575,34 @@ void QosMessage::setStats(Format format, quint64 processed, quint64 dropped)
dropped);
}
+//********************************************************
+
+DeviceAddedMessagePtr DeviceAddedMessage::create(const ObjectPtr & source, const DevicePtr & device)
+{
+ GstMessage *m = gst_message_new_device_added(source, device);
+ return DeviceAddedMessagePtr::wrap(m, false);
+}
+
+DevicePtr DeviceAddedMessage::device() const
+{
+ GstDevice *d;
+ gst_message_parse_device_added(object<GstMessage>(), &d);
+ return DevicePtr::wrap(d, false);
+}
+
+//********************************************************
+
+DeviceRemovedMessagePtr DeviceRemovedMessage::create(const ObjectPtr & source, const DevicePtr & device)
+{
+ GstMessage *m = gst_message_new_device_removed(source, device);
+ return DeviceRemovedMessagePtr::wrap(m, false);
+}
+
+DevicePtr DeviceRemovedMessage::device() const
+{
+ GstDevice *d;
+ gst_message_parse_device_removed(object<GstMessage>(), &d);
+ return DevicePtr::wrap(d, false);
+}
+
} //namespace QGst
diff --git a/src/QGst/message.h b/src/QGst/message.h
index 569d52d..cd489b7 100644
--- a/src/QGst/message.h
+++ b/src/QGst/message.h
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -17,6 +17,8 @@
#ifndef QGST_MESSAGE_H
#define QGST_MESSAGE_H
+#include "clocktime.h"
+#include "device.h"
#include "miniobject.h"
#include "structure.h"
#include "taglist.h"
@@ -53,7 +55,7 @@ public:
QString typeName() const;
MessageType type() const;
- StructurePtr internalStructure();
+ StructureConstPtr internalStructure();
quint32 sequenceNumber() const;
void setSequenceNumber(quint32 num);
@@ -204,7 +206,7 @@ class QTGSTREAMER_EXPORT ApplicationMessage : public Message
QGST_WRAPPER_FAKE_SUBCLASS(Application, Message)
public:
static ApplicationMessagePtr create(const ObjectPtr & source,
- const Structure & structure = Structure());
+ const Structure & structure=Structure());
};
/*! \headerfile message.h <QGst/Message>
@@ -215,7 +217,7 @@ class QTGSTREAMER_EXPORT ElementMessage : public Message
QGST_WRAPPER_FAKE_SUBCLASS(Element, Message)
public:
static ElementMessagePtr create(const ObjectPtr & source,
- const Structure & structure = Structure());
+ const Structure & structure=Structure());
};
//maybe do: SEGMENT_START (internal)
@@ -236,14 +238,12 @@ public:
/*! \headerfile message.h <QGst/Message>
* \brief Wrapper class for messages of type QGst::MessageDuration
*/
-class QTGSTREAMER_EXPORT DurationMessage : public Message
+class QTGSTREAMER_EXPORT DurationChangedMessage : public Message
{
- QGST_WRAPPER_FAKE_SUBCLASS(Duration, Message)
+ QGST_WRAPPER_FAKE_SUBCLASS(DurationChanged, Message)
public:
- static DurationMessagePtr create(const ObjectPtr & source, Format format, qint64 duration);
+ static DurationChangedMessagePtr create(const ObjectPtr & source);
- Format format() const;
- qint64 duration() const;
};
/*! \headerfile message.h <QGst/Message>
@@ -265,7 +265,9 @@ class QTGSTREAMER_EXPORT AsyncDoneMessage : public Message
{
QGST_WRAPPER_FAKE_SUBCLASS(AsyncDone, Message)
public:
- static AsyncDoneMessagePtr create(const ObjectPtr & source);
+ static AsyncDoneMessagePtr create(const ObjectPtr & source, ClockTime running_time);
+
+ ClockTime runningTime() const;
};
/*! \headerfile message.h <QGst/Message>
@@ -324,6 +326,30 @@ public:
void setStats(Format format, quint64 processed, quint64 dropped);
};
+/*! \headerfile message.h <QGst/Message>
+ * \brief Wrapper class for messages of type QGst::MessageDeviceAdded
+ */
+class QTGSTREAMER_EXPORT DeviceAddedMessage : public Message
+{
+ QGST_WRAPPER_FAKE_SUBCLASS(DeviceAdded, Message)
+public:
+ static DeviceAddedMessagePtr create(const ObjectPtr & source, const DevicePtr& device);
+
+ DevicePtr device() const;
+};
+
+/*! \headerfile message.h <QGst/Message>
+ * \brief Wrapper class for messages of type QGst::MessageDeviceRemoved
+ */
+class QTGSTREAMER_EXPORT DeviceRemovedMessage : public Message
+{
+ QGST_WRAPPER_FAKE_SUBCLASS(DeviceRemoved, Message)
+public:
+ static DeviceRemovedMessagePtr create(const ObjectPtr & source, const DevicePtr& device);
+
+ DevicePtr device() const;
+};
+
} //namespace QGst
QGST_REGISTER_TYPE(QGst::Message)
@@ -339,11 +365,13 @@ QGST_REGISTER_SUBCLASS(Message, StreamStatus)
QGST_REGISTER_SUBCLASS(Message, Application)
QGST_REGISTER_SUBCLASS(Message, Element)
QGST_REGISTER_SUBCLASS(Message, SegmentDone)
-QGST_REGISTER_SUBCLASS(Message, Duration)
+QGST_REGISTER_SUBCLASS(Message, DurationChanged)
QGST_REGISTER_SUBCLASS(Message, Latency)
QGST_REGISTER_SUBCLASS(Message, AsyncDone)
QGST_REGISTER_SUBCLASS(Message, RequestState)
QGST_REGISTER_SUBCLASS(Message, StepStart)
QGST_REGISTER_SUBCLASS(Message, Qos)
+QGST_REGISTER_SUBCLASS(Message, DeviceAdded)
+QGST_REGISTER_SUBCLASS(Message, DeviceRemoved)
#endif
diff --git a/src/QGst/miniobject.cpp b/src/QGst/miniobject.cpp
index 90ef7f3..7d55b31 100644
--- a/src/QGst/miniobject.cpp
+++ b/src/QGst/miniobject.cpp
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -67,7 +67,7 @@ namespace Private {
QGlib::RefCountedObject *wrapMiniObject(void *miniObject)
{
- return QGlib::constructWrapper(QGlib::Type::fromInstance(miniObject), miniObject);
+ return QGlib::constructWrapper(GST_MINI_OBJECT_TYPE(miniObject), miniObject);
}
} //namespace Private
diff --git a/src/QGst/miniobject.h b/src/QGst/miniobject.h
index c26e973..dd1c788 100644
--- a/src/QGst/miniobject.h
+++ b/src/QGst/miniobject.h
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -28,7 +28,17 @@ namespace QGst {
*/
class QTGSTREAMER_EXPORT MiniObject : public QGlib::RefCountedObject
{
- QGST_WRAPPER(MiniObject)
+// expanded QGST_WRAPPER(MiniObject) but without MiniObject_new()
+// this is to avoid codegen picking it up, since MiniObject has no
+// GType and cannot be handled properly
+public:
+ typedef GstMiniObject CType;
+protected:
+ MiniObject() {}
+ MiniObject(const MiniObject &);
+ MiniObject & operator=(const MiniObject &);
+ ~MiniObject() {}
+
public:
MiniObjectPtr copy() const;
bool isWritable() const;
@@ -47,7 +57,6 @@ QTGSTREAMER_EXPORT QGlib::RefCountedObject *wrapMiniObject(void *miniObject);
} //namespace Private
} //namespace QGst
-QGST_REGISTER_TYPE(QGst::MiniObject)
QGLIB_REGISTER_WRAPIMPL_FOR_SUBCLASSES_OF(QGst::MiniObject, QGst::Private::wrapMiniObject)
#endif
diff --git a/src/QGst/object.cpp b/src/QGst/object.cpp
index 8fd1b5a..f337ed3 100644
--- a/src/QGst/object.cpp
+++ b/src/QGst/object.cpp
@@ -9,14 +9,14 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
*/
#include "object.h"
#include "../QGlib/string_p.h"
-#include <gst/gstobject.h>
+#include <gst/gst.h>
namespace QGst {
diff --git a/src/QGst/object.h b/src/QGst/object.h
index f76ab0b..a943e39 100644
--- a/src/QGst/object.h
+++ b/src/QGst/object.h
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/src/QGst/objectstore.cpp b/src/QGst/objectstore.cpp
index eadae78..156f4d6 100644
--- a/src/QGst/objectstore.cpp
+++ b/src/QGst/objectstore.cpp
@@ -10,7 +10,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -70,7 +70,11 @@ bool ObjectStore::take(const void * ptr)
//Decrease our bindings (weak) reference count
(gs->refCount[ptr]).deref();
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
+ if (!gs->refCount[ptr].load()) {
+#else
if (!gs->refCount[ptr]) {
+#endif
//refCount is 0
gs->refCount.remove(ptr);
mustSubtractStrongRef = true;
diff --git a/src/QGst/objectstore_p.h b/src/QGst/objectstore_p.h
index af41ba9..5b4109a 100644
--- a/src/QGst/objectstore_p.h
+++ b/src/QGst/objectstore_p.h
@@ -10,7 +10,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/src/QGst/pad.cpp b/src/QGst/pad.cpp
index 92fafa5..1a07f0a 100644
--- a/src/QGst/pad.cpp
+++ b/src/QGst/pad.cpp
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -20,8 +20,7 @@
#include "query.h"
#include "event.h"
#include <QtCore/QDebug>
-#include <gst/gstpad.h>
-#include <gst/gstutils.h>
+#include <gst/gst.h>
namespace QGst {
@@ -70,9 +69,9 @@ bool Pad::unlink(const PadPtr & sink)
return gst_pad_unlink(object<GstPad>(), sink);
}
-CapsPtr Pad::caps() const
+CapsPtr Pad::currentCaps() const
{
- return CapsPtr::wrap(gst_pad_get_caps_reffed(object<GstPad>()), false);
+ return CapsPtr::wrap(gst_pad_get_current_caps(object<GstPad>()), false);
}
CapsPtr Pad::allowedCaps() const
@@ -80,14 +79,9 @@ CapsPtr Pad::allowedCaps() const
return CapsPtr::wrap(gst_pad_get_allowed_caps(object<GstPad>()), false);
}
-CapsPtr Pad::negotiatedCaps() const
+CapsPtr Pad::padTemplateCaps() const
{
- return CapsPtr::wrap(gst_pad_get_negotiated_caps(object<GstPad>()), false);
-}
-
-bool Pad::setCaps(const CapsPtr & caps)
-{
- return gst_pad_set_caps(object<GstPad>(), caps);
+ return CapsPtr::wrap(gst_pad_get_pad_template_caps(object<GstPad>()), false);
}
bool Pad::isActive() const
@@ -110,11 +104,6 @@ bool Pad::isBlocking() const
return gst_pad_is_blocking(object<GstPad>());
}
-bool Pad::setBlocked(bool blocked)
-{
- return gst_pad_set_blocked(object<GstPad>(), blocked);
-}
-
bool Pad::query(const QueryPtr & query)
{
return gst_pad_query(object<GstPad>(), query);
@@ -122,6 +111,9 @@ bool Pad::query(const QueryPtr & query)
bool Pad::sendEvent(const EventPtr &event)
{
+ //Sending an event passes ownership of it, so we need to strong ref() it as we still
+ //hold a pointer to the object, and will release it when the wrapper is cleared.
+ gst_event_ref(event);
return gst_pad_send_event(object<GstPad>(), event);
}
diff --git a/src/QGst/pad.h b/src/QGst/pad.h
index 01435f5..7e526d5 100644
--- a/src/QGst/pad.h
+++ b/src/QGst/pad.h
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -44,22 +44,15 @@ public:
PadLinkReturn link(const PadPtr & sink);
bool unlink(const PadPtr & sink);
- /*! Gets the capabilities this pad can produce or consume. Note that this method doesn't
- * necessarily return the caps set by setCaps(). This method returns all possible caps a
- * pad can operate with, using the pad's get_caps function; this returns the pad template
- * caps if not explicitly set.
- */
- CapsPtr caps() const;
+ CapsPtr currentCaps() const;
CapsPtr allowedCaps() const;
- CapsPtr negotiatedCaps() const;
- bool setCaps(const CapsPtr & caps);
+ CapsPtr padTemplateCaps() const;
bool isActive() const;
bool setActive(bool active);
bool isBlocked() const;
bool isBlocking() const;
- bool setBlocked(bool blocked);
bool query(const QueryPtr & query);
bool sendEvent(const EventPtr & event);
diff --git a/src/QGst/parse.cpp b/src/QGst/parse.cpp
index 1af4690..354340a 100644
--- a/src/QGst/parse.cpp
+++ b/src/QGst/parse.cpp
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -17,7 +17,7 @@
#include "parse.h"
#include "element.h"
#include "../QGlib/error.h"
-#include <gst/gstparse.h>
+#include <gst/gst.h>
namespace QGst {
namespace Parse {
diff --git a/src/QGst/parse.h b/src/QGst/parse.h
index 6ed4f04..d204704 100644
--- a/src/QGst/parse.h
+++ b/src/QGst/parse.h
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/src/QGst/pipeline.cpp b/src/QGst/pipeline.cpp
index 93e7a0c..aedfe63 100644
--- a/src/QGst/pipeline.cpp
+++ b/src/QGst/pipeline.cpp
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -17,7 +17,7 @@
#include "pipeline.h"
#include "bus.h"
#include "clock.h"
-#include <gst/gstpipeline.h>
+#include <gst/gst.h>
namespace QGst {
diff --git a/src/QGst/pipeline.h b/src/QGst/pipeline.h
index 4303f00..eaaf605 100644
--- a/src/QGst/pipeline.h
+++ b/src/QGst/pipeline.h
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/src/QGst/pluginfeature.cpp b/src/QGst/pluginfeature.cpp
index f884296..cb40a20 100644
--- a/src/QGst/pluginfeature.cpp
+++ b/src/QGst/pluginfeature.cpp
@@ -9,13 +9,13 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
*/
#include "pluginfeature.h"
-#include <gst/gstpluginfeature.h>
+#include <gst/gst.h>
namespace QGst {
diff --git a/src/QGst/pluginfeature.h b/src/QGst/pluginfeature.h
index 13f7c2e..c15e4bf 100644
--- a/src/QGst/pluginfeature.h
+++ b/src/QGst/pluginfeature.h
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/src/QGst/propertyprobe.cpp b/src/QGst/propertyprobe.cpp
deleted file mode 100644
index d81c669..0000000
--- a/src/QGst/propertyprobe.cpp
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- Copyright (C) 2010 George Kiagiadakis <kiagiadakis.george@gmail.com>
-
- 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 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 <http://www.gnu.org/licenses/>.
-*/
-#include "propertyprobe.h"
-#include <gst/interfaces/propertyprobe.h>
-
-namespace QGst {
-
-QList<QGlib::ParamSpecPtr> PropertyProbe::properties() const
-{
- QList<QGlib::ParamSpecPtr> result;
- const GList *list = gst_property_probe_get_properties(object<GstPropertyProbe>());
- while(list) {
- result.append(QGlib::ParamSpecPtr::wrap(G_PARAM_SPEC(list->data)));
- list = list->next;
- }
- return result;
-}
-
-bool PropertyProbe::propertySupportsProbe(const QGlib::ParamSpecPtr & property) const
-{
- const GList *list = gst_property_probe_get_properties(object<GstPropertyProbe>());
- while(list) {
- GParamSpec *param = G_PARAM_SPEC(list->data);
- if (param == property) {
- return true;
- }
- list = list->next;
- }
- return false;
-}
-
-bool PropertyProbe::propertySupportsProbe(const char *property) const
-{
- const GParamSpec *param = gst_property_probe_get_property(object<GstPropertyProbe>(), property);
- return param != NULL;
-}
-
-bool PropertyProbe::needsProbe(const QGlib::ParamSpecPtr & property) const
-{
- return gst_property_probe_needs_probe(object<GstPropertyProbe>(), property);
-}
-
-bool PropertyProbe::needsProbe(const char *property) const
-{
- return gst_property_probe_needs_probe_name(object<GstPropertyProbe>(), property);
-}
-
-void PropertyProbe::probe(const QGlib::ParamSpecPtr & property)
-{
- gst_property_probe_probe_property(object<GstPropertyProbe>(), property);
-}
-
-void PropertyProbe::probe(const char *property)
-{
- gst_property_probe_probe_property_name(object<GstPropertyProbe>(), property);
-}
-
-static QList<QGlib::Value> valueArrayToList(GValueArray *array)
-{
- QList<QGlib::Value> result;
- if (array) {
- for(uint i = 0; i < array->n_values; ++i) {
- const GValue *v = g_value_array_get_nth(array, i);
- result.append(QGlib::Value(v));
- }
- g_value_array_free(array);
- }
- return result;
-}
-
-QList<QGlib::Value> PropertyProbe::values(const QGlib::ParamSpecPtr & property) const
-{
- GValueArray *array = gst_property_probe_get_values(object<GstPropertyProbe>(), property);
- return valueArrayToList(array);
-}
-
-QList<QGlib::Value> PropertyProbe::values(const char *property) const
-{
- GValueArray *array = gst_property_probe_get_values_name(object<GstPropertyProbe>(), property);
- return valueArrayToList(array);
-}
-
-QList<QGlib::Value> PropertyProbe::probeAndGetValues(const QGlib::ParamSpecPtr & property)
-{
- GValueArray *array = gst_property_probe_probe_and_get_values(object<GstPropertyProbe>(), property);
- return valueArrayToList(array);
-}
-
-QList<QGlib::Value> PropertyProbe::probeAndGetValues(const char *property)
-{
- GValueArray *array = gst_property_probe_probe_and_get_values_name(object<GstPropertyProbe>(), property);
- return valueArrayToList(array);
-}
-
-}
diff --git a/src/QGst/propertyprobe.h b/src/QGst/propertyprobe.h
deleted file mode 100644
index 31082d1..0000000
--- a/src/QGst/propertyprobe.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- Copyright (C) 2010 George Kiagiadakis <kiagiadakis.george@gmail.com>
-
- 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 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 <http://www.gnu.org/licenses/>.
-*/
-#ifndef QGST_PROPERTYPROBE_H
-#define QGST_PROPERTYPROBE_H
-
-#include "global.h"
-#include "../QGlib/object.h"
-
-namespace QGst {
-
-/*! \interface PropertyProbe propertyprobe.h <QGst/PropertyProbe>
- * \brief Wrapper class for GstPropertyProbe
- */
-class QTGSTREAMER_EXPORT PropertyProbe : public QGlib::Interface
-{
- QGST_WRAPPER(PropertyProbe)
-public:
- QList<QGlib::ParamSpecPtr> properties() const;
-
- bool propertySupportsProbe(const QGlib::ParamSpecPtr & property) const;
- bool propertySupportsProbe(const char *property) const;
-
- bool needsProbe(const QGlib::ParamSpecPtr & property) const;
- bool needsProbe(const char *property) const;
-
- void probe(const QGlib::ParamSpecPtr & property);
- void probe(const char *property);
-
- QList<QGlib::Value> values(const QGlib::ParamSpecPtr & property) const;
- QList<QGlib::Value> values(const char *property) const;
-
- QList<QGlib::Value> probeAndGetValues(const QGlib::ParamSpecPtr & property);
- QList<QGlib::Value> probeAndGetValues(const char *property);
-};
-
-}
-
-QGST_REGISTER_TYPE(QGst::PropertyProbe)
-QGLIB_REGISTER_INTERFACE(QGst::PropertyProbe)
-
-#endif // QGST_PROPERTYPROBE_H
diff --git a/src/QGst/query.cpp b/src/QGst/query.cpp
index 9b03354..fc0a0d1 100644
--- a/src/QGst/query.cpp
+++ b/src/QGst/query.cpp
@@ -10,7 +10,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -35,10 +35,10 @@ QueryType Query::type() const
return static_cast<QueryType>(GST_QUERY_TYPE(object<GstQuery>()));
}
-StructurePtr Query::internalStructure()
+StructureConstPtr Query::internalStructure()
{
- GstStructure *structure = gst_query_get_structure(object<GstQuery>());
- return SharedStructure::fromMiniObject(structure, MiniObjectPtr(this));
+ const GstStructure *structure = gst_query_get_structure(object<GstQuery>());
+ return SharedStructure::fromMiniObject(const_cast<GstStructure *>(structure), MiniObjectPtr(this));
}
//********************************************************
@@ -262,10 +262,10 @@ QList<Format> FormatsQuery::formats() const
{
guint cnt;
QList<Format> formats;
- gst_query_parse_formats_length(object<GstQuery>(), &cnt);
+ gst_query_parse_n_formats(object<GstQuery>(), &cnt);
GstFormat f;
for (uint i=0; i<cnt; i++) {
- gst_query_parse_formats_nth(object<GstQuery>(), i, &f);
+ gst_query_parse_nth_format(object<GstQuery>(), i, &f);
formats << static_cast<Format>(f);
}
return formats;
diff --git a/src/QGst/query.h b/src/QGst/query.h
index ca51b74..a8e1dd4 100644
--- a/src/QGst/query.h
+++ b/src/QGst/query.h
@@ -10,7 +10,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -57,7 +57,7 @@ public:
QString typeName() const;
QueryType type() const;
- StructurePtr internalStructure();
+ StructureConstPtr internalStructure();
};
/*! \headerfile query.h <QGst/Query>
diff --git a/src/QGst/sample.cpp b/src/QGst/sample.cpp
new file mode 100644
index 0000000..625fbbd
--- /dev/null
+++ b/src/QGst/sample.cpp
@@ -0,0 +1,58 @@
+/*
+ Copyright (C) 2013 Diane Trout
+ @author Diane Trout <diane@ghic.org>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#include "buffer.h"
+#include "caps.h"
+#include "sample.h"
+#include "structure.h"
+#include "segment.h"
+#include <QtCore/QDebug>
+#include <gst/gst.h>
+
+namespace QGst {
+
+SamplePtr Sample::create(const BufferPtr & buffer, const CapsPtr & caps,
+ const Segment & segment, const Structure & info)
+{
+ GstStructure *cinfo = NULL;
+ if (info.isValid())
+ cinfo = gst_structure_copy(info);
+
+ return SamplePtr::wrap(gst_sample_new(buffer, caps, segment, cinfo), false);
+}
+
+BufferPtr Sample::buffer() const
+{
+ return BufferPtr::wrap(gst_sample_get_buffer(object<GstSample>()));
+}
+
+CapsPtr Sample::caps() const
+{
+ return CapsPtr::wrap(gst_sample_get_caps(object<GstSample>()));
+}
+
+Structure Sample::info() const
+{
+ return Structure(gst_sample_get_info(object<GstSample>()));
+}
+
+Segment Sample::segment() const
+{
+ return Segment(gst_sample_get_segment(object<GstSample>()));
+}
+
+} //namespace QGst
diff --git a/src/QGst/sample.h b/src/QGst/sample.h
new file mode 100644
index 0000000..bc7d37a
--- /dev/null
+++ b/src/QGst/sample.h
@@ -0,0 +1,47 @@
+/*
+ Copyright (C) 2013 Diane Trout
+ @author Diane Trout <diane@ghic.org>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#ifndef QGST_SAMPLE_H
+#define QGST_SAMPLE_H
+
+#include "miniobject.h"
+
+namespace QGst {
+
+ /*! \headerfile sample.h <QGst/Sample>
+ * \brief Wrapper class for GstSample
+ *
+ * Samples are small objects containg data, a type, timing and extra arbitrary information.
+ *
+ */
+class QTGSTREAMER_EXPORT Sample : public MiniObject
+{
+ QGST_WRAPPER(Sample)
+public:
+ static SamplePtr create(const BufferPtr & buffer, const CapsPtr & caps,
+ const Segment & segment, const Structure & info);
+
+ BufferPtr buffer() const;
+ CapsPtr caps() const;
+ Structure info() const;
+ Segment segment() const;
+};
+} //namespace QGst
+
+QGST_REGISTER_TYPE(QGst::Sample)
+
+#endif
diff --git a/src/QGst/segment.cpp b/src/QGst/segment.cpp
new file mode 100644
index 0000000..e4cf5f6
--- /dev/null
+++ b/src/QGst/segment.cpp
@@ -0,0 +1,158 @@
+/*
+ Copyright (C) 2014 George Kiagiadakis <kiagiadakis.george@gmail.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#include "segment.h"
+#include <gst/gst.h>
+
+namespace QGst {
+
+#ifndef DOXYGEN_RUN
+
+struct QTGSTREAMER_NO_EXPORT Segment::Data : public QSharedData
+{
+ Data() : QSharedData(), segment(NULL) {}
+ Data(const Data & other);
+ virtual ~Data();
+
+ GstSegment *segment;
+};
+
+Segment::Data::Data(const Segment::Data & other)
+ : QSharedData(other), segment(NULL)
+{
+ if (other.segment) {
+ segment = gst_segment_copy(other.segment);
+ }
+}
+
+Segment::Data::~Data()
+{
+ if (segment) {
+ gst_segment_free(segment);
+ }
+}
+
+#endif //DOXYGEN_RUN
+
+Segment::Segment()
+ : d(new Data)
+{
+}
+
+Segment::Segment(Format fmt)
+ : d(new Data)
+{
+ d->segment = gst_segment_new();
+ init(fmt);
+}
+
+Segment::Segment(const GstSegment * segment)
+ : d(new Data)
+{
+ d->segment = gst_segment_copy(segment);
+}
+
+Segment::Segment(const Segment & other)
+ : d(other.d)
+{
+}
+
+Segment & Segment::operator=(const Segment & other)
+{
+ d = other.d;
+ return *this;
+}
+
+Segment::~Segment()
+{
+}
+
+bool Segment::isValid() const
+{
+ return d->segment != NULL;
+}
+
+void Segment::init(Format fmt)
+{
+ gst_segment_init(d->segment, static_cast<GstFormat>(fmt));
+}
+
+SegmentFlags Segment::flags() const
+{
+ return d->segment ? static_cast<SegmentFlag>(d->segment->flags) : SegmentFlagNone;
+}
+
+double Segment::rate() const
+{
+ return d->segment ? d->segment->rate : 1.0;
+}
+
+double Segment::appliedRate() const
+{
+ return d->segment ? d->segment->applied_rate : 1.0;
+}
+
+Format Segment::format() const
+{
+ return d->segment ? static_cast<Format>(d->segment->format) : FormatUndefined;
+}
+
+quint64 Segment::base() const
+{
+ return d->segment ? d->segment->base : 0;
+}
+
+quint64 Segment::offset() const
+{
+ return d->segment ? d->segment->offset : 0;
+}
+
+quint64 Segment::start() const
+{
+ return d->segment ? d->segment->start : 0;
+}
+
+quint64 Segment::stop() const
+{
+ return d->segment ? d->segment->stop : -1;
+}
+
+quint64 Segment::time() const
+{
+ return d->segment ? d->segment->time : 0;
+}
+
+quint64 Segment::position() const
+{
+ return d->segment ? d->segment->position : 0;
+}
+
+quint64 Segment::duration() const
+{
+ return d->segment ? d->segment->duration : -1;
+}
+
+Segment::operator GstSegment*()
+{
+ return d->segment;
+}
+
+Segment::operator const GstSegment*() const
+{
+ return d->segment;
+}
+
+} //namespace QGst
diff --git a/src/QGst/segment.h b/src/QGst/segment.h
new file mode 100644
index 0000000..78fca77
--- /dev/null
+++ b/src/QGst/segment.h
@@ -0,0 +1,69 @@
+/*
+ Copyright (C) 2014 George Kiagiadakis <kiagiadakis.george@gmail.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#ifndef QGST_SEGMENT_H
+#define QGST_SEGMENT_H
+
+#include "global.h"
+
+namespace QGst {
+
+/*! \headerfile segment.h <QGst/Segment>
+ * \brief Wrapper for GstSegment
+ */
+class QTGSTREAMER_EXPORT Segment
+{
+public:
+ Segment();
+ explicit Segment(Format fmt);
+ explicit Segment(const GstSegment *segment);
+ Segment(const Segment & other);
+ virtual ~Segment();
+
+ Segment & operator=(const Segment & other);
+
+ bool isValid() const;
+ void init(Format fmt);
+
+ // fields
+ SegmentFlags flags() const;
+
+ double rate() const;
+ double appliedRate() const;
+
+ Format format() const;
+ quint64 base() const;
+ quint64 offset() const;
+ quint64 start() const;
+ quint64 stop() const;
+ quint64 time() const;
+
+ quint64 position() const;
+ quint64 duration() const;
+
+ operator GstSegment*();
+ operator const GstSegment*() const;
+
+private:
+ struct Data;
+ QSharedDataPointer<Data> d;
+};
+
+} //namespace QGst
+
+QGST_REGISTER_TYPE(QGst::Segment)
+
+#endif
diff --git a/src/QGst/streamvolume.cpp b/src/QGst/streamvolume.cpp
index fdac47b..a868ca8 100644
--- a/src/QGst/streamvolume.cpp
+++ b/src/QGst/streamvolume.cpp
@@ -9,13 +9,13 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
*/
#include "streamvolume.h"
-#include <gst/interfaces/streamvolume.h>
+#include <gst/audio/streamvolume.h>
namespace QGst {
diff --git a/src/QGst/streamvolume.h b/src/QGst/streamvolume.h
index 95edb89..e59f301 100644
--- a/src/QGst/streamvolume.h
+++ b/src/QGst/streamvolume.h
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/src/QGst/structs.h b/src/QGst/structs.h
index f1bf70f..464dbee 100644
--- a/src/QGst/structs.h
+++ b/src/QGst/structs.h
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -18,6 +18,7 @@
#define QGST_STRUCTS_H
#include "global.h"
+#include <QtCore/QDebug>
namespace QGst {
@@ -63,7 +64,7 @@ namespace QGst {
} value;
};
}
-QGST_REGISTER_TYPE(QGst::Fourcc)
+QGST_REGISTER_TYPE(QGst::Fourcc) //codegen: GType=G_TYPE_UINT
namespace QGst {
/*! \headerfile structs.h <QGst/Fraction>
@@ -75,9 +76,19 @@ namespace QGst {
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); }
+
int numerator;
int denominator;
};
+
+ inline QDebug operator<<(QDebug debug, const Fraction &f)
+ {
+ return (debug.nospace() << f.numerator << "/" << f.denominator).maybeSpace();
+ }
}
QGST_REGISTER_TYPE(QGst::Fraction)
diff --git a/src/QGst/structure.cpp b/src/QGst/structure.cpp
index 872b59e..15e0247 100644
--- a/src/QGst/structure.cpp
+++ b/src/QGst/structure.cpp
@@ -13,7 +13,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -22,7 +22,7 @@
#include "miniobject.h"
#include "caps.h"
#include "../QGlib/string_p.h"
-#include <gst/gststructure.h>
+#include <gst/gst.h>
#include <QtCore/QDebug>
namespace QGst {
@@ -68,7 +68,7 @@ Structure::Structure(Data* data)
Structure::Structure(const char *name)
: d(new Data)
{
- d->structure = gst_structure_empty_new(name);
+ d->structure = gst_structure_new_empty(name);
}
Structure::Structure(const GstStructure* structure)
@@ -110,7 +110,7 @@ void Structure::setName(const char *name)
{
if (!d->structure) {
//lazy construction
- d->structure = gst_structure_empty_new(name);
+ d->structure = gst_structure_new_empty(name);
} else {
gst_structure_set_name(d->structure, name);
}
diff --git a/src/QGst/structure.h b/src/QGst/structure.h
index 212c27f..b7107be 100644
--- a/src/QGst/structure.h
+++ b/src/QGst/structure.h
@@ -13,7 +13,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/src/QGst/taglist.cpp b/src/QGst/taglist.cpp
index 4905d9f..5a7a58a 100644
--- a/src/QGst/taglist.cpp
+++ b/src/QGst/taglist.cpp
@@ -12,19 +12,17 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
*/
#include "taglist.h"
+#include "sample.h"
#include "../QGlib/string_p.h"
-#include <gst/gsttaglist.h>
-#include <gst/gstvalue.h>
-//#include <gst/gstdatetime.h>
+#include <gst/gst.h>
#include <QtCore/QDebug>
#include <QtCore/QDate>
-#include <QGst/Buffer>
namespace QGst {
@@ -51,12 +49,12 @@ double getDoubleTag(GstTagList * list, const gchar * tag, int index)
return value;
}
-QGst::BufferPtr getBufferTag(GstTagList * list, const gchar * tag, int index)
+SamplePtr getSampleTag(GstTagList * list, const gchar * tag, int index)
{
- GstBuffer * value = 0;
- gst_tag_list_get_buffer_index(list, tag, index, &value);
+ GstSample *s = NULL;
+ gst_tag_list_get_sample_index(list, tag, index, &s);
//Buffer is already refd()
- return QGst::BufferPtr::wrap(value, false);
+ return SamplePtr::wrap(s, false);
}
#ifndef DOXYGEN_RUN
@@ -74,16 +72,16 @@ struct QTGSTREAMER_NO_EXPORT TagList::Data : public QSharedData
TagList::Data::Data()
: QSharedData()
{
- taglist = gst_tag_list_new();
+ taglist = gst_tag_list_new_empty();
}
TagList::Data::Data(const GstTagList *tl)
: QSharedData()
{
- if (tl && gst_is_tag_list(tl)) {
+ if (tl && GST_IS_TAG_LIST(tl)) {
taglist = gst_tag_list_copy(tl);
} else {
- taglist = gst_tag_list_new();
+ taglist = gst_tag_list_new_empty();
}
}
@@ -95,7 +93,7 @@ TagList::Data::Data(const TagList::Data & other)
TagList::Data::~Data()
{
- gst_tag_list_free(taglist);
+ gst_tag_list_unref(taglist);
}
#endif //DOXYGEN_RUN
@@ -143,7 +141,7 @@ TagList TagList::merge(const TagList & firstList, const TagList & secondList, Ta
//avoid copying the merged taglist by freeing the new one and assigning this one to d->taglist
TagList tl;
- gst_tag_list_free(tl.d->taglist);
+ gst_tag_list_unref(tl.d->taglist);
tl.d->taglist = taglist;
return tl;
}
@@ -165,8 +163,8 @@ int TagList::tagValueCount(const char *tag) const
void TagList::clear()
{
- gst_tag_list_free(d->taglist);
- d->taglist = gst_tag_list_new();
+ gst_tag_list_unref(d->taglist);
+ d->taglist = gst_tag_list_new_empty();
}
void TagList::removeTag(const char *tag)
@@ -720,12 +718,12 @@ void TagList::setLanguageCode(const QString & value)
GST_TAG_LANGUAGE_CODE, QGlib::Value::create(value));
}
-BufferPtr TagList::image(int index) const
+SamplePtr TagList::image(int index) const
{
- return getBufferTag(d->taglist, GST_TAG_IMAGE, index);
+ return getSampleTag(d->taglist, GST_TAG_IMAGE, index);
}
-void TagList::setImage(const BufferPtr & value, TagMergeMode mode)
+void TagList::setImage(const SamplePtr & value, TagMergeMode mode)
{
gst_tag_list_add_value(d->taglist, static_cast<GstTagMergeMode>(mode),
GST_TAG_IMAGE, QGlib::Value::create(value));
@@ -736,23 +734,23 @@ int TagList::imageCount() const
return gst_tag_list_get_tag_size(d->taglist, GST_TAG_IMAGE);
}
-BufferPtr TagList::previewImage() const
+SamplePtr TagList::previewImage() const
{
- return getBufferTag(d->taglist, GST_TAG_PREVIEW_IMAGE, 0);
+ return getSampleTag(d->taglist, GST_TAG_PREVIEW_IMAGE, 0);
}
-void TagList::setPreviewImage(const BufferPtr & value)
+void TagList::setPreviewImage(const SamplePtr & value)
{
gst_tag_list_add_value(d->taglist, GST_TAG_MERGE_REPLACE_ALL,
GST_TAG_PREVIEW_IMAGE, QGlib::Value::create(value));
}
-BufferPtr TagList::attachment(int index) const
+SamplePtr TagList::attachment(int index) const
{
- return getBufferTag(d->taglist, GST_TAG_ATTACHMENT, index);
+ return getSampleTag(d->taglist, GST_TAG_ATTACHMENT, index);
}
-void TagList::setAttachment(const BufferPtr & value, TagMergeMode mode)
+void TagList::setAttachment(const SamplePtr & value, TagMergeMode mode)
{
gst_tag_list_add_value(d->taglist, static_cast<GstTagMergeMode>(mode),
GST_TAG_ATTACHMENT, QGlib::Value::create(value));
@@ -1048,12 +1046,12 @@ void TagList::setApplicationName(const QString & value)
GST_TAG_APPLICATION_NAME, QGlib::Value::create(value));
}
-BufferPtr TagList::applicationData() const
+SamplePtr TagList::applicationData() const
{
- return getBufferTag(d->taglist, GST_TAG_APPLICATION_DATA, 0);
+ return getSampleTag(d->taglist, GST_TAG_APPLICATION_DATA, 0);
}
-void TagList::setApplicationData(const BufferPtr & value)
+void TagList::setApplicationData(const SamplePtr & value)
{
gst_tag_list_add_value(d->taglist, GST_TAG_MERGE_REPLACE_ALL,
GST_TAG_APPLICATION_DATA, QGlib::Value::create(value));
@@ -1074,7 +1072,7 @@ void TagList::setDateTime(const QDateTime & value)
QDebug operator<<(QDebug debug, const TagList & taglist)
{
debug.nospace() << "QGst::TagList("
- << QGlib::Private::stringFromGCharPtr(gst_structure_to_string(taglist)) << ")";
+ << QGlib::Private::stringFromGCharPtr(gst_tag_list_to_string(taglist)) << ")";
return debug.space();
}
diff --git a/src/QGst/taglist.h b/src/QGst/taglist.h
index a06e629..0c517fa 100644
--- a/src/QGst/taglist.h
+++ b/src/QGst/taglist.h
@@ -10,7 +10,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -240,15 +240,15 @@ public:
QString languageCode() const;
void setLanguageCode(const QString & value);
- BufferPtr image(int index = 0) const;
- void setImage(const BufferPtr & value, TagMergeMode mode = TagMergeReplaceAll);
+ SamplePtr image(int index = 0) const;
+ void setImage(const SamplePtr & value, TagMergeMode mode = TagMergeReplaceAll);
int imageCount() const;
- BufferPtr previewImage() const;
- void setPreviewImage(const BufferPtr & value);
+ SamplePtr previewImage() const;
+ void setPreviewImage(const SamplePtr & value);
- BufferPtr attachment(int index = 0) const;
- void setAttachment(const BufferPtr & value, TagMergeMode mode = TagMergeReplaceAll);
+ SamplePtr attachment(int index = 0) const;
+ void setAttachment(const SamplePtr & value, TagMergeMode mode = TagMergeReplaceAll);
int attachmentCount() const;
double beatsPerMinute() const;
@@ -326,8 +326,8 @@ public:
QString applicationName() const;
void setApplicationName(const QString & value);
- BufferPtr applicationData() const;
- void setApplicationData(const BufferPtr & value);
+ SamplePtr applicationData() const;
+ void setApplicationData(const SamplePtr & value);
QDateTime dateTime() const;
void setDateTime(const QDateTime & value);
diff --git a/src/QGst/urihandler.cpp b/src/QGst/urihandler.cpp
index 2cc5126..6256b41 100644
--- a/src/QGst/urihandler.cpp
+++ b/src/QGst/urihandler.cpp
@@ -9,14 +9,14 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
*/
#include "urihandler.h"
#include "element.h"
-#include <gst/gsturi.h>
+#include <gst/gst.h>
#include <QtCore/QUrl>
#include <QtCore/QStringList>
@@ -31,7 +31,11 @@ bool UriHandler::protocolIsSupported(UriType type, const char *protocol)
//static
ElementPtr UriHandler::makeFromUri(UriType type, const QUrl & uri, const char *elementName)
{
- GstElement *e = gst_element_make_from_uri(static_cast<GstURIType>(type), uri.toEncoded(), elementName);
+ GError *error = NULL;
+ GstElement *e = gst_element_make_from_uri(static_cast<GstURIType>(type), uri.toEncoded(), elementName, &error);
+ if (error) {
+ throw QGlib::Error(error);
+ }
if (e) {
gst_object_ref_sink(e);
}
@@ -46,9 +50,9 @@ UriType UriHandler::uriType() const
QStringList UriHandler::supportedProtocols() const
{
QStringList result;
- char **protocols = gst_uri_handler_get_protocols(object<GstURIHandler>());
+ const char * const *protocols = gst_uri_handler_get_protocols(object<GstURIHandler>());
if (protocols) {
- for (char **p = protocols; p && *p; ++p) {
+ for (const char * const *p = protocols; p && *p; ++p) {
result.append(QString::fromUtf8(*p));
}
}
@@ -64,7 +68,13 @@ QUrl UriHandler::uri() const
bool UriHandler::setUri(const QUrl & uri)
{
- return gst_uri_handler_set_uri(object<GstURIHandler>(), uri.toEncoded());
+ GError *error = NULL;
+ bool result;
+ result = gst_uri_handler_set_uri(object<GstURIHandler>(), uri.toEncoded(), &error);
+ if (error) {
+ throw QGlib::Error(error);
+ }
+ return result;
}
} //namespace QGst
diff --git a/src/QGst/urihandler.h b/src/QGst/urihandler.h
index 405119e..43839ea 100644
--- a/src/QGst/urihandler.h
+++ b/src/QGst/urihandler.h
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/src/QGst/value.cpp b/src/QGst/value.cpp
index cd58011..1e13b8f 100644
--- a/src/QGst/value.cpp
+++ b/src/QGst/value.cpp
@@ -10,7 +10,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -20,13 +20,11 @@
#include "structure.h"
#include "../QGlib/value.h"
#include <cmath>
-#include <gst/gstvalue.h>
-#include <gst/gstminiobject.h>
-#include <gst/gstdatetime.h>
+#include <gst/gst.h>
namespace QGlib {
-GetTypeImpl<QDate>::operator Type() { return GST_TYPE_DATE; }
+GetTypeImpl<QDate>::operator Type() { return G_TYPE_DATE; }
GetTypeImpl<QDateTime>::operator Type() { return GST_TYPE_DATE_TIME; }
} //namespace QGlib
@@ -36,38 +34,6 @@ namespace Private {
void registerValueVTables()
{
- struct ValueVTable_MiniObject
- {
- static void get(const QGlib::Value & value, void *data)
- {
- *reinterpret_cast<GstMiniObject**>(data) = gst_value_get_mini_object(value);
- };
-
- static void set(QGlib::Value & value, const void *data)
- {
- gst_value_set_mini_object(value, *reinterpret_cast<GstMiniObject* const *>(data));
- };
- };
- QGlib::Value::registerValueVTable(QGlib::GetType<MiniObject>(),
- QGlib::ValueVTable(ValueVTable_MiniObject::set, ValueVTable_MiniObject::get));
-
-
- struct ValueVTable_Fourcc
- {
- static void get(const QGlib::Value & value, void *data)
- {
- reinterpret_cast<Fourcc*>(data)->value.as_integer = gst_value_get_fourcc(value);
- };
-
- static void set(QGlib::Value & value, const void *data)
- {
- gst_value_set_fourcc(value, reinterpret_cast<Fourcc const *>(data)->value.as_integer);
- };
- };
- QGlib::Value::registerValueVTable(QGlib::GetType<Fourcc>(),
- QGlib::ValueVTable(ValueVTable_Fourcc::set, ValueVTable_Fourcc::get));
-
-
struct ValueVTable_Fraction
{
static void get(const QGlib::Value & value, void *data)
@@ -184,7 +150,7 @@ void registerValueVTables()
{
static void get(const QGlib::Value & value, void *data)
{
- const GDate *gdate = gst_value_get_date(value);
+ const GDate *gdate = static_cast<const GDate *>(g_value_get_boxed(value));
*reinterpret_cast<QDate*>(data) = QDate(g_date_get_year(gdate),
g_date_get_month(gdate),
g_date_get_day(gdate));
@@ -196,7 +162,7 @@ void registerValueVTables()
GDate *gdate = g_date_new_dmy(qdate->day(),
static_cast<GDateMonth>(qdate->month()),
qdate->year());
- gst_value_set_date(value, gdate);
+ g_value_set_boxed(value, gdate);
g_date_free(gdate);
}
};
diff --git a/src/QGst/videoorientation.cpp b/src/QGst/videoorientation.cpp
index 71c1917..a055afb 100644
--- a/src/QGst/videoorientation.cpp
+++ b/src/QGst/videoorientation.cpp
@@ -11,13 +11,13 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
*/
#include "videoorientation.h"
-#include <gst/interfaces/videoorientation.h>
+#include <gst/video/videoorientation.h>
namespace QGst {
diff --git a/src/QGst/videoorientation.h b/src/QGst/videoorientation.h
index 5fefd7c..12046b6 100644
--- a/src/QGst/videoorientation.h
+++ b/src/QGst/videoorientation.h
@@ -11,7 +11,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/src/QGst/xoverlay.cpp b/src/QGst/videooverlay.cpp
index 4c337d8..997dc41 100644
--- a/src/QGst/xoverlay.cpp
+++ b/src/QGst/videooverlay.cpp
@@ -9,46 +9,53 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
*/
-#include "xoverlay.h"
-#include <gst/interfaces/xoverlay.h>
+
+#include "videooverlay.h"
+#include "message.h"
+#include <gst/video/videooverlay.h>
#include <QtCore/QRect>
namespace QGst {
-void XOverlay::expose()
+void VideoOverlay::expose()
{
- gst_x_overlay_expose(object<GstXOverlay>());
+ gst_video_overlay_expose(object<GstVideoOverlay>());
}
-void XOverlay::setWindowHandle(WId id)
+void VideoOverlay::setWindowHandle(WId id)
{
#if defined(Q_WS_WIN)
QGLIB_STATIC_ASSERT(sizeof(WId) == sizeof(guintptr),
"Size of WId doesn't match guintptr. Please file a bug report.");
- gst_x_overlay_set_window_handle(object<GstXOverlay>(), *reinterpret_cast<guintptr*>(&id));
+ gst_video_overlay_set_window_handle(object<GstVideoOverlay>(), *reinterpret_cast<guintptr*>(&id));
#else
- gst_x_overlay_set_window_handle(object<GstXOverlay>(), id);
+ gst_video_overlay_set_window_handle(object<GstVideoOverlay>(), id);
#endif
}
-void XOverlay::enableEventHandling(bool enabled)
+void VideoOverlay::enableEventHandling(bool enabled)
{
- gst_x_overlay_handle_events(object<GstXOverlay>(), enabled);
+ gst_video_overlay_handle_events(object<GstVideoOverlay>(), enabled);
}
-bool XOverlay::setRenderRectangle(int x, int y, int width, int height)
+bool VideoOverlay::setRenderRectangle(int x, int y, int width, int height)
{
- return gst_x_overlay_set_render_rectangle(object<GstXOverlay>(), x, y, width, height);
+ return gst_video_overlay_set_render_rectangle(object<GstVideoOverlay>(), x, y, width, height);
}
-bool XOverlay::setRenderRectangle(const QRect& rect)
+bool VideoOverlay::setRenderRectangle(const QRect& rect)
{
return setRenderRectangle(rect.x(), rect.y(), rect.width(), rect.height());
}
+bool VideoOverlay::isPrepareWindowHandleMessage(const MessagePtr & msg)
+{
+ return gst_is_video_overlay_prepare_window_handle_message(msg);
+}
+
} //namespace QGst
diff --git a/src/QGst/xoverlay.h b/src/QGst/videooverlay.h
index 627da5b..a733664 100644
--- a/src/QGst/xoverlay.h
+++ b/src/QGst/videooverlay.h
@@ -9,13 +9,13 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
*/
-#ifndef QGST_XOVERLAY_H
-#define QGST_XOVERLAY_H
+#ifndef QGST_VIDEOOVERLAY_H
+#define QGST_VIDEOOVERLAY_H
#include "global.h"
#include "../QGlib/object.h"
@@ -25,23 +25,25 @@ class QRect;
namespace QGst {
-/*! \interface XOverlay xoverlay.h <QGst/XOverlay>
- * \brief Wrapper class for GstXOverlay
+/*! \interface VideoOverlay videooverlay.h <QGst/VideoOverlay>
+ * \brief Wrapper class for GstVideoOverlay
*/
-class QTGSTREAMER_EXPORT XOverlay : public QGlib::Interface
+class QTGSTREAMER_EXPORT VideoOverlay : public QGlib::Interface
{
- QGST_WRAPPER(XOverlay)
+ QGST_WRAPPER(VideoOverlay)
public:
void expose();
void setWindowHandle(WId id);
void enableEventHandling(bool enabled);
bool setRenderRectangle(int x, int y, int width, int height);
bool setRenderRectangle(const QRect & rect);
+
+ static bool isPrepareWindowHandleMessage(const MessagePtr & msg);
};
} //namespace QGst
-QGST_REGISTER_TYPE(QGst::XOverlay)
-QGLIB_REGISTER_INTERFACE(QGst::XOverlay)
+QGST_REGISTER_TYPE(QGst::VideoOverlay)
+QGLIB_REGISTER_INTERFACE(QGst::VideoOverlay)
-#endif // QGST_XOVERLAY_H
+#endif // QGST_VIDEOOVERLAY_H
diff --git a/src/main.dox b/src/main.dox
index cfb5384..9e51897 100644
--- a/src/main.dox
+++ b/src/main.dox
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2010 George Kiagiadakis <kiagiadakis.george@gmail.com>
+ Copyright (C) 2010-2014 George Kiagiadakis <kiagiadakis.george@gmail.com>
Copyright (C) 2010-2011 Collabora Ltd.
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
@@ -11,7 +11,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -28,13 +28,13 @@
* Currently, it consists of the following parts:
* \li QtGLib - Library providing C++/Qt bindings for parts of the GLib
* and GObject APIs, a base on which QtGStreamer is built.
- * \li QtGStreamer - Library providing C++/Qt bindings for GStreamer
- * \li QtGStreamerUi - Library providing integration with QtGui. Currently,
- * it only provides a video widget that embeds GStreamer's video sinks.
+ * \li QtGStreamer - Library providing C++/Qt bindings for GStreamer.
+ * \li QtGStreamerQuick - Library providing integration with QtQuick (Qt5 only).
+ * \li QtGStreamerUi - Library providing integration with QtWidgets.
* \li QtGStreamerUtils - Library providing some high level utility classes.
*
- * In addition, it provides a "qwidgetvideosink" GStreamer element, an video
- * sink element that can draw directly on QWidgets using QPainter.
+ * In addition, it provides GStreamer elements for drawing video on widgets,
+ * graphics items and QtQuick items.
*
* \section api_reference API Reference
* \li <a href="classes.html">All Classes</a>
@@ -43,6 +43,9 @@
* \section using_qtgstreamer Using QtGStreamer
* \li \subpage build_system_integration
* \li \subpage coding_conventions
+ *
+ * \section elements Elements provided by QtGStreamer
+ * \li \subpage qtvideosink_overview
*/
/*! \page build_system_integration Build system integration
@@ -53,7 +56,9 @@
* You can just do:
*
* \code
- * find_package(QtGStreamer)
+ * find_package(QtGStreamer) # for Qt4 QtGStreamer
+ * # ..... OR .....
+ * find_package(Qt5GStreamer) # for Qt5 QtGStreamer
* \endcode
*
* which will find QtGStreamer and define the following variables:
@@ -65,6 +70,8 @@
* \li QTGLIB_LIBRARIES - the libraries needed to use QtGLib
* \li QTGSTREAMER_LIBRARY - the QtGStreamer library
* \li QTGSTREAMER_LIBRARIES - the libraries needed to use QtGStreamer
+ * \li QTGSTREAMER_QUICK_LIBRARY - the QtGStreamerQuick library
+ * \li QTGSTREAMER_QUICK_LIBRARIES - the libraries needed to use QtGStreamerQuick
* \li QTGSTREAMER_UI_LIBRARY - the QtGStreamerUi library
* \li QTGSTREAMER_UI_LIBRARIES - the libraries needed to use QtGStreamerUi
* \li QTGSTREAMER_UTILS_LIBRARY - the QtGStreamerUtils library
@@ -81,15 +88,26 @@
*
* \code
* CONFIG += link_pkgconfig
- * PKGCONFIG += QtGStreamer-0.10
+ * PKGCONFIG += QtGStreamer-1.0
* \endcode
*
* In the PKGCONFIG variable you can set one or more of:
*
* \li QtGLib-2.0 - the libraries needed to use QtGLib
- * \li QtGStreamer-0.10 - the libraries needed to use QtGStreamer
- * \li QtGStreamerUi-0.10 - the libraries needed to use QtGStreamerUi
- * \li QtGStreamerUtils-0.10 - the libraries needed to use QtGStreamerUtils
+ * \li QtGStreamer-1.0 - the libraries needed to use QtGStreamer
+ * \li QtGStreamerUi-1.0 - the libraries needed to use QtGStreamerUi
+ * \li QtGStreamerUtils-1.0 - the libraries needed to use QtGStreamerUtils
+ *
+ * When QtGStreamer is built using Qt5, those packages are called differently:
+ *
+ * \li Qt5GLib-2.0
+ * \li Qt5GStreamer-1.0
+ * \li Qt5GStreamerUi-1.0
+ * \li Qt5GStreamerUtils-1.0
+ *
+ * And additionally in Qt5 there is:
+ *
+ * \li Qt5GStreamerQuick-1.0 - the libraries needed to use Qt5GStreamerQuick
*
* \section other_build_systems Other build systems
*
@@ -125,6 +143,93 @@
* \endcode
*/
+/*! \page qtvideosink_overview qtvideosink / qtglvideosink / qwidgetvideosink / qtquick2videosink
+ *
+ * \section overview Overview
+ *
+ * qtvideosink and its variants are elements that provide native video drawing
+ * support for Qt surfaces. qtvideosink and qwidgetvideosink do software painting,
+ * using QImage and QPainter. qtglvideosink and qtquick2videosink use
+ * OpenGL/OpenGLES and support hardware colorspace conversion and color balance.
+ *
+ * The API of qtvideosink and qtglvideosink is the same, except that qtglvideosink
+ * has an extra "glcontext" property that must be set with the surface's QGLContext
+ * pointer as early as possible after construction.
+ *
+ * qwidgetvideosink has the same features as qtvideosink, but a different API.
+ * In qwidgetvideosink, you can set a QWidget pointer directly to its "widget"
+ * property and it will paint in this widget, without any further tampering,
+ * while in qtvideosink you need to handle its signals.
+ *
+ * qtquick2videosink has a similar concept to qtvideosink, but it uses the new
+ * scene-graph architecture for drawing in QtQuick items instead of using QPainter.
+ *
+ * All 4 elements require a running Qt event loop and have the inherited limitation
+ * from Qt that they must be created, destroyed and have their signals and
+ * properties handled from the main (GUI) thread.
+ *
+ * When drawing video on QtQuick1 (QML) or QGraphicsView, it is recommended to
+ * use qtglvideosink, if possible, and fall back to qtvideosink otherwise.
+ * When drawing on QWidgets, it is recommended to embed the platform's
+ * hardware accelerated sink, such as xvimagesink on X11, and if this is
+ * not possible, use qwidgetvideosink. Finally, when drawing on QtQuick2 (Qt5),
+ * the only way is to use qtquick2videosink.
+ *
+ * All 4 elements are independent of the QtGStreamer libraries and can be built
+ * and used without them. However, QtGStreamer provides helper integration classes
+ * that you may find useful.
+ *
+ * \section usage_without_qtgstreamer Usage without QtGStreamer
+ *
+ * qtvideosink and qtglvideosink provide two signals, an action signal
+ * (a slot in Qt terminology) called “paint” and a normal signal called “update”.
+ * “update” is emitted every time the sink needs the surface to be repainted.
+ * This is meant to be connected directly to QWidget::update() or QGraphicsItem::update()
+ * or something similar. The “paint” slot takes a QPainter pointer and a rectangle
+ * (x, y, width, height as qreals) as its arguments and paints the video inside the
+ * given rectangle using the given painter. This is meant to be called from the widget’s
+ * paint event or the graphics item’s paint() function. All you need to do is to take
+ * care of those two signals and qtvideosink/qtglvideosink will do everything else.
+ *
+ * qtglvideosink also requires an initialization with the surface's QGLContext pointer.
+ * In addition, it is wise to try to make it READY before using it, to verify that
+ * the required OpenGL features are supported by the hardware. If this fails, it is
+ * sensible to fall back to qtvideosink, which can be used with the same API.
+ * \code
+ * QGst::Element videoSink = QGst::ElementFactory::make("qtglvideosink");
+ * glwidget->makeCurrent();
+ * videoSink->setProperty("glcontext", (void*) QGLContext::currentContext());
+ * glwidget->doneCurrent();
+ *
+ * if (videoSink->setState(QGst::StateReady) != QGst::StateChangeSuccess) {
+ * // fall back to qtvideosink
+ * videoSink = QGst::ElementFactory::make("qtvideosink");
+ * }
+ * \endcode
+ *
+ * \section usage_with_qtgstreamer Usage with QtGStreamer
+ *
+ * If you are using the QtGStreamer libraries in your applications, you can directly
+ * use QGst::Ui::VideoWidget to embed any of the 3 first variants (i.e. except
+ * the qtquick2 one) in a QWidget, or QGst::Ui::GraphicsVideoWidget with
+ * QGst::Ui::GraphicsVideoSurface to paint on a QGraphicsView.
+ *
+ * If you are using QtQuick (either QtQuick1 with Qt4 or Qt5, or QtQuick2 with Qt5),
+ * there is also a "VideoItem" element available when you import "QtGStreamer 1.0".
+ * See the qmlplayer and qmlplayer2 examples for details.
+ *
+ * \section qt5_notes Qt5 notes
+ *
+ * When QtGStreamer is compiled with Qt5, the first 3 elements are named:
+ *
+ * \li qt5videosink
+ * \li qt5glvideosink
+ * \li qwidget5videosink
+ *
+ * This is done to allow them to be parallel installable to their Qt4 counterparts
+ * and to avoid Qt version mixing through gstreamer's plugin loading.
+ */
+
/*! \namespace QGlib
* \brief Wrappers for Glib and GObject classes
*
@@ -144,10 +249,10 @@
*/
/*! \namespace QGst::Ui
- * \brief Helper classes for better integration of GStreamer in graphical Qt applications
+ * \brief Helper classes for better integration of GStreamer in QtWidgets-based graphical applications
*
* This namespace provides helper classes for better integration of GStreamer
- * in graphical Qt applications.
+ * in QtWidgets-based graphical applications.
*
* \note This namespace is contained in the QtGStreamerUi library.
*/
@@ -161,6 +266,15 @@
* \note This namespace is contained in the QtGStreamerUtils library.
*/
+/*! \namespace QGst::Quick
+ * \brief Helper classes for better integration of GStreamer in QtQuick-based graphical applications
+ *
+ * This namespace provides helper classes for better integration of GStreamer
+ * in QtQuick-based graphical applications.
+ *
+ * \note This namespace is contained in the QtGStreamerQuick library.
+ */
+
/*! \page internal_design_details Internal Design Details
*
* This page documents various implementation details for people that are interested
diff --git a/src/qml/CMakeLists.txt b/src/qml/CMakeLists.txt
new file mode 100644
index 0000000..179abba
--- /dev/null
+++ b/src/qml/CMakeLists.txt
@@ -0,0 +1,7 @@
+if (Qt4or5_Quick1_FOUND)
+ add_subdirectory(quick1)
+endif()
+
+if (Qt4or5_Quick2_FOUND)
+ add_subdirectory(quick2)
+endif()
diff --git a/src/qml/quick1/CMakeLists.txt b/src/qml/quick1/CMakeLists.txt
new file mode 100644
index 0000000..53ded96
--- /dev/null
+++ b/src/qml/quick1/CMakeLists.txt
@@ -0,0 +1,27 @@
+set(QtGStreamerQuick1_SRCS
+ plugin.cpp
+ videoitem.cpp
+)
+
+add_library(QtGStreamerQuick1 MODULE ${QtGStreamerQuick1_SRCS})
+target_link_libraries(QtGStreamerQuick1 ${QTGSTREAMER_UI_LIBRARIES})
+qt4or5_use_modules(QtGStreamerQuick1 Quick1)
+
+if (WIN32 AND CMAKE_COMPILER_IS_GNUCXX)
+ # On windows with gcc, cmake calls the binary libFOO.dll, but the Qt plugin loader
+ # does not remove the lib prefix when searching for .dlls, unlike what happens on unix
+ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/qmldir "plugin libQtGStreamerQuick1")
+else()
+ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/qmldir "plugin QtGStreamerQuick1")
+endif()
+
+install(TARGETS QtGStreamerQuick1 DESTINATION ${QTGSTREAMER_QTQUICK1_INSTALL_DIR}/QtGStreamer)
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/qmldir DESTINATION ${QTGSTREAMER_QTQUICK1_INSTALL_DIR}/QtGStreamer)
+
+# create a layout similar to the one in ${QTGSTREAMER_QTQUICK1_INSTALL_DIR} for testing
+add_custom_command(TARGET QtGStreamerQuick1 POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/QtGStreamer
+ COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:QtGStreamerQuick1> ${CMAKE_CURRENT_BINARY_DIR}/QtGStreamer/
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/qmldir ${CMAKE_CURRENT_BINARY_DIR}/QtGStreamer/
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+)
diff --git a/src/qml/quick1/plugin.cpp b/src/qml/quick1/plugin.cpp
new file mode 100644
index 0000000..6da8bfc
--- /dev/null
+++ b/src/qml/quick1/plugin.cpp
@@ -0,0 +1,44 @@
+/*
+ Copyright (C) 2012 Collabora Ltd. <info@collabora.com>
+ @author George Kiagiadakis <george.kiagiadakis@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#include "videoitem.h"
+#include <QtDeclarative/QDeclarativeExtensionPlugin>
+
+#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
+# define Q_PLUGIN_METADATA(x)
+#endif
+
+class QtGStreamerPlugin : public QDeclarativeExtensionPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.freedesktop.gstreamer.Qt5GStreamerQuick1-1.0")
+public:
+ void registerTypes(const char *uri);
+};
+
+void QtGStreamerPlugin::registerTypes(const char *uri)
+{
+ qmlRegisterType<VideoItem>(uri, 1, 0, "VideoItem");
+ qmlRegisterUncreatableType<QGst::Ui::GraphicsVideoSurface>(uri, 1, 0, "GraphicsVideoSurface",
+ QLatin1String("Creating a QGst::Ui::GraphicsVideoSurface from QML is not supported"));
+}
+
+#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
+Q_EXPORT_PLUGIN2(qtgstPlugin, QtGStreamerPlugin)
+#endif
+
+#include "plugin.moc"
diff --git a/src/qml/quick1/videoitem.cpp b/src/qml/quick1/videoitem.cpp
new file mode 100644
index 0000000..3a20d2f
--- /dev/null
+++ b/src/qml/quick1/videoitem.cpp
@@ -0,0 +1,45 @@
+/*
+ Copyright (C) 2012 Collabora Ltd. <info@collabora.com>
+ @author George Kiagiadakis <george.kiagiadakis@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#include "videoitem.h"
+#include "../../QGst/Ui/graphicsvideowidget.h"
+
+VideoItem::VideoItem(QDeclarativeItem *parent)
+ : QDeclarativeItem(parent)
+{
+ m_widget = new QGst::Ui::GraphicsVideoWidget(this);
+}
+
+VideoItem::~VideoItem()
+{
+}
+
+QGst::Ui::GraphicsVideoSurface *VideoItem::surface() const
+{
+ return m_widget->surface();
+}
+
+void VideoItem::setSurface(QGst::Ui::GraphicsVideoSurface *surface)
+{
+ m_widget->setSurface(surface);
+}
+
+void VideoItem::geometryChanged(const QRectF& newGeometry, const QRectF& oldGeometry)
+{
+ m_widget->setGeometry(newGeometry);
+ QDeclarativeItem::geometryChanged(newGeometry, oldGeometry);
+}
diff --git a/src/qml/quick1/videoitem.h b/src/qml/quick1/videoitem.h
new file mode 100644
index 0000000..b5bb84b
--- /dev/null
+++ b/src/qml/quick1/videoitem.h
@@ -0,0 +1,42 @@
+/*
+ Copyright (C) 2012 Collabora Ltd. <info@collabora.com>
+ @author George Kiagiadakis <george.kiagiadakis@collabora.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#ifndef VIDEOITEM_H
+#define VIDEOITEM_H
+
+#include "../../QGst/Ui/graphicsvideosurface.h"
+#include <QtDeclarative/QDeclarativeItem>
+
+class VideoItem : public QDeclarativeItem
+{
+ Q_OBJECT
+ Q_PROPERTY(QGst::Ui::GraphicsVideoSurface* surface READ surface WRITE setSurface)
+public:
+ explicit VideoItem(QDeclarativeItem *parent = 0);
+ virtual ~VideoItem();
+
+ QGst::Ui::GraphicsVideoSurface *surface() const;
+ void setSurface(QGst::Ui::GraphicsVideoSurface *surface);
+
+protected:
+ virtual void geometryChanged(const QRectF & newGeometry, const QRectF & oldGeometry);
+
+private:
+ QGst::Ui::GraphicsVideoWidget *m_widget;
+};
+
+#endif // VIDEOITEM_H
diff --git a/src/qml/quick2/CMakeLists.txt b/src/qml/quick2/CMakeLists.txt
new file mode 100644
index 0000000..9ab4b70
--- /dev/null
+++ b/src/qml/quick2/CMakeLists.txt
@@ -0,0 +1,26 @@
+set(QtGStreamerQuick2_SRCS
+ plugin.cpp
+)
+
+add_library(QtGStreamerQuick2 MODULE ${QtGStreamerQuick2_SRCS})
+target_link_libraries(QtGStreamerQuick2 ${QTGSTREAMER_QUICK_LIBRARIES})
+qt4or5_use_modules(QtGStreamerQuick2 Qml)
+
+if (WIN32 AND CMAKE_COMPILER_IS_GNUCXX)
+ # On windows with gcc, cmake calls the binary libFOO.dll, but the Qt plugin loader
+ # does not remove the lib prefix when searching for .dlls, unlike what happens on unix
+ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/qmldir "module QtGStreamer\nplugin libQtGStreamerQuick2")
+else()
+ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/qmldir "module QtGStreamer\nplugin QtGStreamerQuick2")
+endif()
+
+install(TARGETS QtGStreamerQuick2 DESTINATION ${QTGSTREAMER_QTQUICK2_INSTALL_DIR}/QtGStreamer/)
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/qmldir DESTINATION ${QTGSTREAMER_QTQUICK2_INSTALL_DIR}/QtGStreamer/)
+
+# create a layout similar to the one in ${QTGSTREAMER_QTQUICK2_INSTALL_DIR} for testing
+add_custom_command(TARGET QtGStreamerQuick2 POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/QtGStreamer
+ COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:QtGStreamerQuick2> ${CMAKE_CURRENT_BINARY_DIR}/QtGStreamer/
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/qmldir ${CMAKE_CURRENT_BINARY_DIR}/QtGStreamer/
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+)
diff --git a/src/qml/quick2/QtGStreamerQuick2.json b/src/qml/quick2/QtGStreamerQuick2.json
new file mode 100644
index 0000000..311847d
--- /dev/null
+++ b/src/qml/quick2/QtGStreamerQuick2.json
@@ -0,0 +1,2 @@
+{}
+
diff --git a/src/qml/quick2/plugin.cpp b/src/qml/quick2/plugin.cpp
new file mode 100644
index 0000000..8795f63
--- /dev/null
+++ b/src/qml/quick2/plugin.cpp
@@ -0,0 +1,40 @@
+/*
+ Copyright (C) 2013 basysKom GmbH <info@basyskom.com>
+ @author Benjamin Federau <benjamin.federau@basyskom.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "../../QGst/Quick/videoitem.h"
+#include "../../QGst/Quick/videosurface.h"
+#include <QtQml/QQmlExtensionPlugin>
+
+class QtGStreamerPlugin : public QQmlExtensionPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.freedesktop.gstreamer.QtGStreamerQuick2-1.0"
+ FILE "QtGStreamerQuick2.json")
+public:
+ virtual void registerTypes(const char *uri);
+};
+
+void QtGStreamerPlugin::registerTypes(const char *uri)
+{
+ // @uri org.freedesktop.gstreamer.QtGStreamerQuick2-1.0
+ qmlRegisterType<QGst::Quick::VideoItem>(uri, 1, 0, "VideoItem");
+ qmlRegisterUncreatableType<QGst::Quick::VideoSurface>(uri, 1, 0, "VideoSurface",
+ QLatin1String("Creating a QGst::Quick::VideoSurface from QML is not supported"));
+}
+
+#include "plugin.moc"
diff --git a/tests/auto/CMakeLists.txt b/tests/auto/CMakeLists.txt
index 716349d..d395450 100644
--- a/tests/auto/CMakeLists.txt
+++ b/tests/auto/CMakeLists.txt
@@ -1,12 +1,14 @@
-include_directories(${CMAKE_CURRENT_BINARY_DIR} ${GSTREAMER_INCLUDE_DIR}
- ${GLIB2_INCLUDE_DIR} ${QTGSTREAMER_INCLUDES})
+include_directories(${GSTREAMER_INCLUDE_DIRS} ${GSTREAMER_PBUTILS_INCLUDE_DIR} ${GLIB2_INCLUDE_DIR} ${QTGSTREAMER_INCLUDES})
add_definitions(${QTGSTREAMER_DEFINITIONS} -DGST_DISABLE_XML -DGST_DISABLE_LOADSAVE)
+add_definitions(-DSRCDIR="${CMAKE_CURRENT_SOURCE_DIR}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${QTGSTREAMER_FLAGS}")
macro(qgst_test target)
- automoc4_add_executable(${target} "${target}.cpp")
- target_link_libraries(${target} ${QT_QTTEST_LIBRARY} ${GSTREAMER_LIBRARY}
- ${GOBJECT_LIBRARIES} ${QTGSTREAMER_LIBRARIES})
+ add_executable(${target} "${target}.cpp")
+ target_link_libraries(${target} ${GSTREAMER_LIBRARY} ${GOBJECT_LIBRARIES}
+ ${QTGSTREAMER_LIBRARIES}
+ ${GSTREAMER_PBUTILS_LIBRARY})
+ qt4or5_use_modules(${target} Test)
add_test(NAME ${target} COMMAND ${target})
endmacro(qgst_test)
@@ -27,3 +29,16 @@ qgst_test(buffertest)
qgst_test(eventtest)
qgst_test(messagetest)
qgst_test(taglisttest)
+qgst_test(discoverertest)
+qgst_test(allocatortest)
+qgst_test(memorytest)
+qgst_test(padtest)
+
+if(TARGET Qt5GStreamerQuick)
+ add_executable(qtquick2test qtquick2test.cpp)
+ target_link_libraries(qtquick2test Qt5::Qml Qt5GStreamerQuick ${QTGSTREAMER_LIBRARIES})
+ qt4or5_use_modules(qtquick2test Test)
+ add_test(NAME qtquick2test
+ COMMAND cmake -E env QML2_IMPORT_PATH=${CMAKE_BINARY_DIR}/src/qml/quick2/:$ENV{QML2_IMPORT_PATH} GST_PLUGIN_PATH=${CMAKE_BINARY_DIR}/elements/gstqtvideosink/:$ENV{GST_PLUGIN_PATH} ${CMAKE_CURRENT_BINARY_DIR}/qtquick2test
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
+endif()
diff --git a/tests/auto/allocatortest.cpp b/tests/auto/allocatortest.cpp
new file mode 100644
index 0000000..cfb4fc6
--- /dev/null
+++ b/tests/auto/allocatortest.cpp
@@ -0,0 +1,85 @@
+/*
+ Copyright (C) 2014 Diane Trout <diane@ghic.org>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "qgsttest.h"
+#include <QGlib/Error>
+#include <QGst/Allocator>
+#include <QGst/QGstMemory>
+
+class AllocatorTest : public QGstTest
+{
+ Q_OBJECT
+private Q_SLOTS:
+
+ void testAllocationParams();
+ void testAllocator();
+};
+
+void AllocatorTest::testAllocationParams()
+{
+ QGst::AllocationParams *p(new QGst::AllocationParams);
+
+ // its really pathetic but sometimes getters and
+ // setters break
+ p->setFlags(QGst::MemoryFlagReadonly | QGst::MemoryFlagNotMappable);
+ p->setAlign(10ul);
+ p->setPrefix(20ul);
+ p->setPadding(30ul);
+
+ QCOMPARE(p->flags(), QGst::MemoryFlagReadonly | QGst::MemoryFlagNotMappable);
+ QCOMPARE(p->align(), 10ul);
+ QCOMPARE(p->prefix(), 20ul);
+ QCOMPARE(p->padding(), 30ul);
+
+ // Does copy work?
+ QGst::AllocationParams c(*p);
+
+ QCOMPARE(c.flags(), QGst::MemoryFlagReadonly | QGst::MemoryFlagNotMappable);
+ QCOMPARE(c.align(), 10ul);
+ QCOMPARE(c.prefix(), 20ul);
+ QCOMPARE(c.padding(), 30ul);
+
+ // Does copy really work. (delete the source)
+ delete p;
+
+ QCOMPARE(c.flags(), QGst::MemoryFlagReadonly | QGst::MemoryFlagNotMappable);
+ QCOMPARE(c.align(), 10ul);
+ QCOMPARE(c.prefix(), 20ul);
+ QCOMPARE(c.padding(), 30ul);
+}
+
+void AllocatorTest::testAllocator()
+{
+ GstAllocator *g_system = gst_allocator_find("SystemMemory");
+ QGst::AllocatorPtr system(QGst::Allocator::getSystemMemory());
+ QVERIFY(system);
+ QCOMPARE(g_system, static_cast<GstAllocator *>(system));
+
+ QGst::AllocationParams params;
+ params.setFlags(QGst::MemoryFlagNotMappable);
+
+ QGst::MemoryPtr mem = system->alloc(100, params);
+ QVERIFY(mem);
+ QCOMPARE(mem->size(), static_cast<size_t>(100));
+
+ system->free(mem);
+}
+
+QTEST_APPLESS_MAIN(AllocatorTest)
+
+#include "moc_qgsttest.cpp"
+#include "allocatortest.moc"
diff --git a/tests/auto/buffertest.cpp b/tests/auto/buffertest.cpp
index c176322..2d3a482 100644
--- a/tests/auto/buffertest.cpp
+++ b/tests/auto/buffertest.cpp
@@ -10,13 +10,14 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
*/
#include "qgsttest.h"
#include <QGst/Buffer>
+#include <QGst/QGstMemory>
#include <QGst/Caps>
class BufferTest : public QGstTest
@@ -24,9 +25,9 @@ class BufferTest : public QGstTest
Q_OBJECT
private Q_SLOTS:
void simpleTest();
- void capsTest();
void flagsTest();
void copyTest();
+ void memoryPeekTest();
};
void BufferTest::simpleTest()
@@ -34,46 +35,33 @@ void BufferTest::simpleTest()
QGst::BufferPtr buffer = QGst::Buffer::create(10);
QCOMPARE(buffer->size(), (quint32) 10);
- QVERIFY(buffer->data());
-}
-
-void BufferTest::capsTest()
-{
- QGst::BufferPtr buffer = QGst::Buffer::create(10);
- QGst::CapsPtr caps = QGst::Caps::createSimple("video/x-raw-yuv");
- caps->setValue("width", 320);
- caps->setValue("height", 240);
-
- buffer->setCaps(caps);
-
- QGst::CapsPtr caps2 = buffer->caps();
-
- QVERIFY(caps->equals(caps2));
+ QVERIFY(buffer->getMemory(0));
}
void BufferTest::flagsTest()
{
QGst::BufferPtr buffer = QGst::Buffer::create(10);
- QGst::BufferFlags flags(QGst::BufferFlagReadOnly & QGst::BufferFlagDiscont);
+ QGst::BufferFlags flags(QGst::BufferFlagLive & QGst::BufferFlagDiscont);
buffer->setFlags(flags);
QGst::BufferFlags flags2 = buffer->flags();
QCOMPARE(flags, flags2);
- QGst::BufferFlags flags3(QGst::BufferFlagReadOnly);
+ QGst::BufferFlags flags3(QGst::BufferFlagLive);
QVERIFY(flags2!=flags3);
}
void BufferTest::copyTest()
{
QGst::BufferPtr buffer = QGst::Buffer::create(10);
- QGst::BufferFlags flags(QGst::BufferFlagReadOnly & QGst::BufferFlagDiscont);
+ QGst::BufferFlags flags(QGst::BufferFlagLive & QGst::BufferFlagDiscont);
buffer->setFlags(flags);
QGst::BufferPtr buffer2 = buffer->copy();
QCOMPARE(buffer->size(), buffer2->size());
- QCOMPARE(buffer->timeStamp(), buffer2->timeStamp());
+ QCOMPARE(buffer->decodingTimeStamp(), buffer2->decodingTimeStamp());
+ QCOMPARE(buffer->presentationTimeStamp(), buffer2->presentationTimeStamp());
QCOMPARE(buffer->duration(), buffer2->duration());
QGst::BufferFlags flags2(QGst::BufferFlagDiscont);
@@ -82,6 +70,24 @@ void BufferTest::copyTest()
QVERIFY(buffer->flags() != buffer2->flags());
}
+void BufferTest::memoryPeekTest()
+{
+ QGst::BufferPtr buffer = QGst::Buffer::create(10);
+ guint8 bytes[100];
+ size_t returned_bytes;
+
+ returned_bytes = buffer->extract(0, &bytes, 10);
+ QCOMPARE(returned_bytes, static_cast<size_t>(10));
+
+ returned_bytes = buffer->extract(0, &bytes, 20);
+ QCOMPARE(returned_bytes, static_cast<size_t>(10));
+
+ QGst::MemoryPtr m = buffer->getMemory(0);
+
+ QVERIFY(m);
+ QVERIFY(m->isWritable());
+
+}
QTEST_APPLESS_MAIN(BufferTest)
#include "moc_qgsttest.cpp"
diff --git a/tests/auto/bustest.cpp b/tests/auto/bustest.cpp
index cd42693..52c293a 100644
--- a/tests/auto/bustest.cpp
+++ b/tests/auto/bustest.cpp
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -67,7 +67,7 @@ void BusTest::messageClosure(const QGst::MessagePtr & msg)
//check if the message is the same we sent from the other thread
QVERIFY(!msg.isNull());
QCOMPARE(msg->type(), QGst::MessageApplication);
- const QGst::StructurePtr s = msg->internalStructure();
+ QGst::StructureConstPtr s = msg->internalStructure();
QCOMPARE(s->name(), QString("test"));
QCOMPARE(s->value("sequence").get<int>(), m_messagesReceived);
diff --git a/tests/auto/capstest.cpp b/tests/auto/capstest.cpp
index 5fb4184..6db1d4c 100644
--- a/tests/auto/capstest.cpp
+++ b/tests/auto/capstest.cpp
@@ -11,7 +11,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -34,7 +34,7 @@ private Q_SLOTS:
void CapsTest::simpleTest()
{
- QGst::CapsPtr caps = QGst::Caps::createSimple("video/x-raw-yuv");
+ QGst::CapsPtr caps = QGst::Caps::createSimple("video/x-raw");
QVERIFY(caps->isSimple());
QVERIFY(!caps->isEmpty());
QVERIFY(!caps->isAny());
@@ -69,7 +69,7 @@ void CapsTest::anyTest()
void CapsTest::fullTest()
{
- QGst::Structure s("video/x-raw-yuv");
+ QGst::Structure s("video/x-raw");
s.setValue("width", 320);
s.setValue("height", 240);
@@ -85,7 +85,7 @@ void CapsTest::fullTest()
QVERIFY(!caps->isAny());
QVERIFY(caps->size() == 1);
- QGst::CapsPtr caps2 = QGst::Caps::createSimple("video/x-raw-yuv");
+ QGst::CapsPtr caps2 = QGst::Caps::createSimple("video/x-raw");
caps2->setValue("width", 320);
caps2->setValue("height", 240);
@@ -94,21 +94,21 @@ void CapsTest::fullTest()
void CapsTest::writabilityTest()
{
- QGst::CapsPtr caps = QGst::Caps::createSimple("video/x-raw-yuv");
- QVERIFY(GST_CAPS_REFCOUNT_VALUE(caps) == 1);
+ QGst::CapsPtr caps = QGst::Caps::createSimple("video/x-raw");
+ QVERIFY(GST_CAPS_REFCOUNT_VALUE(static_cast<GstCaps *>(caps)) == 1);
{
QGst::CapsPtr caps2 = caps;
- QCOMPARE(GST_CAPS_REFCOUNT_VALUE(caps), 1);
+ QCOMPARE(GST_CAPS_REFCOUNT_VALUE(static_cast<GstCaps *>(caps)), 1);
QVERIFY(static_cast<GstCaps*>(caps2) == static_cast<GstCaps*>(caps));
}
GstCaps *oldPtr = caps;
- QVERIFY(GST_CAPS_REFCOUNT_VALUE(caps) == 1);
+ QVERIFY(GST_CAPS_REFCOUNT_VALUE(static_cast<GstCaps *>(caps)) == 1);
//Increase external refcount to lock it
gst_caps_ref(oldPtr);
QVERIFY(oldPtr == static_cast<GstCaps*>(caps));
- QVERIFY(GST_CAPS_REFCOUNT_VALUE(caps) == 2);
+ QVERIFY(GST_CAPS_REFCOUNT_VALUE(static_cast<GstCaps *>(caps)) == 2);
QVERIFY(!caps->isWritable());
caps = caps->makeWritable(); //creates a copy
@@ -118,7 +118,7 @@ void CapsTest::writabilityTest()
void CapsTest::setValueTest()
{
- QGst::CapsPtr caps = QGst::Caps::createSimple("video/x-raw-yuv");
+ QGst::CapsPtr caps = QGst::Caps::createSimple("video/x-raw");
QGst::BinPtr bin = QGst::Bin::create();
diff --git a/tests/auto/childproxytest.cpp b/tests/auto/childproxytest.cpp
index 75d8512..86134fc 100644
--- a/tests/auto/childproxytest.cpp
+++ b/tests/auto/childproxytest.cpp
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -76,12 +76,12 @@ void ChildProxyTest::propertiesTest()
QCOMPARE(bin->add(tee), true);
{
- QGst::ObjectPtr obj;
+ QGlib::ObjectPtr obj;
QGlib::ParamSpecPtr param;
QCOMPARE(bin->findChildProperty("mytee::has-chain", &obj, &param), true);
QVERIFY(!obj.isNull());
QVERIFY(!param.isNull());
- QCOMPARE(obj->name(), QString("mytee"));
+ QCOMPARE(obj->property("name").get<QString>(), QString("mytee"));
QCOMPARE(param->name(), QString("has-chain"));
}
diff --git a/tests/auto/clocktest.cpp b/tests/auto/clocktest.cpp
index 3b8f88b..cf4a036 100644
--- a/tests/auto/clocktest.cpp
+++ b/tests/auto/clocktest.cpp
@@ -10,7 +10,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/tests/auto/data/numbers.ogv b/tests/auto/data/numbers.ogv
new file mode 100644
index 0000000..bdc0494
--- /dev/null
+++ b/tests/auto/data/numbers.ogv
Binary files differ
diff --git a/tests/auto/data/numbers07.jpg b/tests/auto/data/numbers07.jpg
new file mode 100644
index 0000000..c92fd79
--- /dev/null
+++ b/tests/auto/data/numbers07.jpg
Binary files differ
diff --git a/tests/auto/data/numbers07.png b/tests/auto/data/numbers07.png
new file mode 100644
index 0000000..8518b67
--- /dev/null
+++ b/tests/auto/data/numbers07.png
Binary files differ
diff --git a/tests/auto/data/sine.ogg b/tests/auto/data/sine.ogg
new file mode 100644
index 0000000..767cc1f
--- /dev/null
+++ b/tests/auto/data/sine.ogg
Binary files differ
diff --git a/tests/auto/discoverertest.cpp b/tests/auto/discoverertest.cpp
new file mode 100644
index 0000000..ee9b92a
--- /dev/null
+++ b/tests/auto/discoverertest.cpp
@@ -0,0 +1,640 @@
+/*
+ Copyright (C) 2012 Openismus GmbH
+ @author Mathias Hasselmann <mathias@openismus.com>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#include "qgsttest.h"
+
+#include <QGlib/Connect>
+#include <QGlib/Error>
+
+#include <QGst/Caps>
+#include <QGst/ClockTime>
+#include <QGst/Discoverer>
+
+#include <gst/pbutils/pbutils.h>
+
+// Declare a simple tag list that actually supports iteration. Needed for our test data.
+typedef QPair<const char *, QGlib::Value> Tag;
+typedef QList<Tag> TagList;
+
+static Tag makeTag(const char *name, const QGlib::Value &value)
+{
+ return qMakePair(name, value);
+}
+
+namespace QGlib {
+
+// Declare a simple compare operator for QGlib::Value.
+// Comparing by string value isn't accurate at all, but good enough for our testing purposes.
+static bool operator ==(const Value &a, const Value &b)
+{
+ bool okA = false, okB = false;
+ return a.type() == b.type() && a.toString(&okA) == b.toString(&okB) && okA && okB;
+}
+
+static bool operator !=(const Value &a, const Value &b)
+{
+ return !(a == b);
+}
+
+} //namespace QGlib
+
+// This classes describes what kind of streams we expect.
+class StreamInfo : public QSharedData
+{
+ Q_DISABLE_COPY(StreamInfo)
+
+public:
+ enum DebugMode
+ {
+ NoDebug,
+ Debug
+ };
+
+ enum CapsMode
+ {
+ AutoCaps,
+ ManualCaps
+ };
+
+ virtual ~StreamInfo() {}
+
+protected:
+ StreamInfo(const QString &caps, CapsMode capsMode)
+ : m_isNative(true)
+ , m_caps(QGst::Caps::fromString(caps))
+ , m_capsMode(capsMode)
+ {
+ }
+
+ template<typename T>
+ class Field
+ {
+ public:
+ Field()
+ : m_value(T())
+ , m_assigned(false)
+ {
+ }
+
+ Field & operator =(const T &value)
+ {
+ m_value = value;
+ m_assigned = true;
+ return *this;
+ }
+
+ bool operator ==(const T &other) const
+ {
+ return !m_assigned || m_value == other;
+ }
+
+ bool operator !=(const T &other) const
+ {
+ return !operator =(other);
+ }
+
+ private:
+ T m_value;
+ bool m_assigned;
+ };
+
+public:
+ virtual bool acceptStreamType(QGlib::Type streamType) const
+ {
+ return streamType.isA(GST_TYPE_DISCOVERER_STREAM_INFO);
+ }
+
+ virtual bool acceptStream(QGst::DiscovererStreamInfoPtr info) const
+ {
+ return acceptStream(info, NoDebug);
+ }
+
+ virtual bool acceptStream(QGst::DiscovererStreamInfoPtr info, DebugMode debugMode) const
+ {
+ if (info.isNull()) {
+ if (debugMode) {
+ qDebug() << "stream info is null";
+ }
+ return false;
+ }
+
+ if (info->tags().isEmpty() != m_tags.isEmpty()) {
+ if (debugMode) {
+ qDebug() << (m_tags.isEmpty() ? "tags should be empty, but aren't"
+ : "none of the expected tags found");
+ qDebug() << m_tags;
+ }
+
+ return false;
+ }
+
+ Q_FOREACH(const Tag &tag, m_tags) {
+ if (info->tags().tagValue(tag.first) != tag.second) {
+ if (debugMode) {
+ qDebug() << tag.first << "tag has bad value\n"
+ << " expected value:" << tag.second << "\n"
+ << " actual value: " << info->tags().tagValue(tag.first);
+ }
+ return false;
+ }
+ }
+
+ if (!info->caps()->isAlwaysCompatibleWith(m_caps)) {
+ if (debugMode) {
+ qDebug() << "capabilities are incompatible\n"
+ << " expected caps:" << m_caps->toString() << "\n"
+ << " actual caps: " << info->caps()->toString();
+ }
+
+ return false;
+ }
+
+ return true;
+ }
+
+ StreamInfo * setNative(bool value) { m_isNative = value; return this; }
+ bool isNative() const { return m_isNative; }
+
+ StreamInfo * addTag(const char *name, const QGlib::Value &value)
+ {
+ m_tags += makeTag(name, value);
+ return this;
+ }
+
+ StreamInfo * addCap(const char *name, const QGlib::Value &value)
+ {
+ if (m_capsMode == AutoCaps) {
+ m_caps->setValue(name, value);
+ }
+
+ return this;
+ }
+
+ bool isImage() const
+ {
+ return m_caps->toString().startsWith("image/");
+ }
+
+private:
+ bool m_isNative;
+ TagList m_tags;
+ QGst::CapsPtr m_caps;
+ CapsMode m_capsMode;
+};
+
+class AudioStreamInfo : public StreamInfo
+{
+public:
+ AudioStreamInfo(const QString &caps, CapsMode capsMode = AutoCaps)
+ : StreamInfo(caps, capsMode)
+ {
+ }
+
+ bool acceptStreamType(QGlib::Type streamType) const
+ {
+ return streamType.isA(GST_TYPE_DISCOVERER_AUDIO_INFO);
+ }
+
+ bool acceptStream(QGst::DiscovererStreamInfoPtr info) const
+ {
+ QGst::DiscovererAudioInfoPtr audioInfo = info.dynamicCast<QGst::DiscovererAudioInfo>();
+
+ return !audioInfo.isNull()
+ && StreamInfo::acceptStream(info)
+ && m_channels == audioInfo->channels()
+ && m_sampleRate == audioInfo->sampleRate()
+ && m_bitrate == audioInfo->bitrate()
+ && m_depth == audioInfo->depth();
+ }
+
+ AudioStreamInfo * setChannels(uint value) { m_channels = value; addCap("channels", int(value)); return this; }
+ AudioStreamInfo * setSampleRate(uint value) { m_sampleRate = value; addCap("rate", int(value)); return this; }
+ AudioStreamInfo * setBitrate(uint value) { m_bitrate = value; addTag("bitrate", value); return this; }
+ AudioStreamInfo * setDepth(uint value) { m_depth = value; return this; }
+
+private:
+ Field<uint> m_channels;
+ Field<uint> m_sampleRate;
+ Field<uint> m_bitrate;
+ Field<uint> m_depth;
+};
+
+class VideoStreamInfo : public StreamInfo
+{
+public:
+ VideoStreamInfo(const QString &caps, CapsMode capsMode = AutoCaps)
+ : StreamInfo(caps, capsMode)
+ {
+ if (capsMode != AutoCaps) {
+ qWarning("working around PNG decoder bug");
+ }
+ }
+
+ bool acceptStreamType(QGlib::Type streamType) const
+ {
+ return streamType.isA(GST_TYPE_DISCOVERER_VIDEO_INFO);
+ }
+
+ bool acceptStream(QGst::DiscovererStreamInfoPtr info) const
+ {
+ QGst::DiscovererVideoInfoPtr videoInfo = info.dynamicCast<QGst::DiscovererVideoInfo>();
+
+ return !videoInfo.isNull()
+ && StreamInfo::acceptStream(info)
+ && isImage() == videoInfo->isImage()
+ && m_width == videoInfo->width()
+ && m_height == videoInfo->height()
+ && m_interlaced == videoInfo->isInterlaced()
+ && m_bitrate == videoInfo->bitrate()
+ && m_framerate == videoInfo->framerate()
+ && m_pixelAspectRatio == videoInfo->pixelAspectRatio();
+ }
+
+ VideoStreamInfo * setWidth(uint value) { m_width = value; addCap("width", int(value)); return this; }
+ VideoStreamInfo * setHeight(uint value) { m_height = value; addCap("height", int(value)); return this; }
+ VideoStreamInfo * setInterlaced(bool value) { m_interlaced = value; return this; }
+ VideoStreamInfo * setBitrate(uint value) { m_bitrate = value; addTag("bitrate", value); return this; }
+ VideoStreamInfo * setFramerate(const QGst::Fraction &value) { m_framerate = value; addCap("framerate", QGlib::Value::create(value)); return this; }
+ VideoStreamInfo * setPixelAspectRatio(const QGst::Fraction &value) { m_pixelAspectRatio = value; addCap("pixel-aspect-ratio", QGlib::Value::create(value)); return this; }
+
+private:
+ Field<uint> m_width;
+ Field<uint> m_height;
+ Field<bool> m_interlaced;
+ Field<uint> m_bitrate;
+ Field<QGst::Fraction> m_framerate;
+ Field<QGst::Fraction> m_pixelAspectRatio;
+};
+
+typedef QSharedDataPointer<StreamInfo> StreamInfoPtr;
+typedef QList<StreamInfoPtr> StreamInfoList;
+
+// A few filtering algorithms
+template<class Container, class UnaryPredicate>
+static Container filter(const Container &input, UnaryPredicate predicate)
+{
+ Container result;
+
+ const typename Container::ConstIterator end = input.constEnd();
+ for(typename Container::ConstIterator it = input.constBegin(); it != end; ++it) {
+ if (predicate(it->data())) {
+ result += *it;
+ }
+ }
+
+ return result;
+}
+
+static StreamInfoList filterByStreamType(const StreamInfoList &streams, QGlib::Type streamType)
+{
+ return filter(streams, std::bind2nd(std::mem_fun(&StreamInfo::acceptStreamType), streamType));
+}
+
+// Declare a few metatypes, so that we can use this types for test data.
+Q_DECLARE_METATYPE(QGst::ClockTime)
+Q_DECLARE_METATYPE(StreamInfoList)
+Q_DECLARE_METATYPE(TagList)
+
+// The actual test
+class DiscovererTest : public QGstTest
+{
+ Q_OBJECT
+
+public:
+ enum DiscoveryState {
+ DiscoveryPending,
+ DiscoveryStarted,
+ UriDiscovered,
+ DiscoveryFinished
+ };
+
+private:
+ void setupDiscoveryData();
+ void verifyStreamInfo(QGst::DiscovererInfoPtr info);
+
+private Q_SLOTS:
+ void cleanup();
+
+ void testGLibTypes_data();
+ void testGLibTypes();
+
+ void testSyncDiscovery_data();
+ void testSyncDiscovery();
+
+ void testAsyncDiscovery_data();
+ void testAsyncDiscovery();
+
+protected: // mark as protected to avoid that QTestLib invoking those methods as test
+ void onStartingDiscovery();
+ void onUriDiscovered(QGst::DiscovererInfoPtr info, const QGlib::Error &error);
+ void onDiscoveryFinished();
+
+private:
+ QScopedPointer<QEventLoop> m_eventLoop;
+ DiscoveryState m_discoveryState;
+};
+
+namespace QTest {
+template<> char *toString(const DiscovererTest::DiscoveryState &state)
+{
+ switch(state) {
+ case DiscovererTest::DiscoveryPending: return toString("discovery-pending");
+ case DiscovererTest::DiscoveryStarted: return toString("discovery-started");
+ case DiscovererTest::UriDiscovered: return toString("uri-discovered");
+ case DiscovererTest::DiscoveryFinished: return toString("discovery-finished");
+ }
+
+ return toString(uint(state));
+}
+}
+
+void DiscovererTest::setupDiscoveryData()
+{
+ QTest::addColumn<QUrl>("uri");
+ QTest::addColumn<int>("errorCode");
+ QTest::addColumn<QString>("errorDomain");
+ QTest::addColumn<QGst::ClockTime>("duration");
+ QTest::addColumn<bool>("seekable");
+ QTest::addColumn<StreamInfoList>("streams");
+ QTest::addColumn<TagList>("expectedTags");
+
+ const bool Seekable = true;
+ const bool NonSeekable = false;
+ const QUrl baseUrl = QUrl::fromLocalFile(QString::fromLocal8Bit(SRCDIR) + "/");
+
+ QTest::newRow("null")
+ << QUrl("about:null")
+ << int(GST_CORE_ERROR_MISSING_PLUGIN)
+ << QString::fromUtf8(g_quark_to_string(GST_CORE_ERROR))
+ << QGst::ClockTime(0) << Seekable
+ << StreamInfoList()
+ << TagList();
+ QTest::newRow("numbers.ogv")
+ << baseUrl.resolved(QUrl::fromEncoded("data/numbers.ogv")) << 0 << QString()
+ << QGst::ClockTime(2017333333) << Seekable
+ << (StreamInfoList()
+ << StreamInfoPtr((new AudioStreamInfo("audio/x-flac, framed=true"))
+ ->setSampleRate(48000)->setChannels(1)->setDepth(16)
+ ->addTag("audio-codec", "FLAC")
+ ->addTag("container-format", "Ogg"))
+ << StreamInfoPtr((new VideoStreamInfo("video/x-theora"))
+ ->setWidth(160)->setHeight(120)->setInterlaced(false)
+ ->setBitrate(200000)->setFramerate(QGst::Fraction(5, 1))
+ ->setPixelAspectRatio(QGst::Fraction(1, 1))
+ ->addTag("container-format", "Ogg")
+ ->addTag("video-codec", "Theora")))
+ << (TagList()
+ << makeTag("container-format", "Ogg")
+ << makeTag("audio-codec", "FLAC")
+ << makeTag("video-codec", "Theora")
+ << makeTag("bitrate", 200000U));
+ QTest::newRow("numbers07.png")
+ << baseUrl.resolved(QUrl::fromEncoded("data/numbers07.png")) << 0 << QString()
+ << QGst::ClockTime(0) << Seekable
+ << (StreamInfoList()
+ << StreamInfoPtr((new VideoStreamInfo("image/png", VideoStreamInfo::ManualCaps))
+ ->setWidth(160)->setHeight(120)->setInterlaced(false)
+ ->addTag("video-codec", "PNG")))
+ << (TagList()
+ << makeTag("video-codec", "PNG"));
+ QTest::newRow("numbers07.jpg")
+ << baseUrl.resolved(QUrl::fromEncoded("data/numbers07.jpg")) << 0 << QString()
+ << QGst::ClockTime(0) << NonSeekable
+ << (StreamInfoList()
+ << StreamInfoPtr((new VideoStreamInfo("image/jpeg"))
+ ->setWidth(120)->setHeight(160)->setInterlaced(false)))
+ << (TagList());
+ QTest::newRow("sine.ogg")
+ << baseUrl.resolved(QUrl::fromEncoded("data/sine.ogg")) << 0 << QString()
+ << QGst::ClockTime::fromSeconds(2) << Seekable
+ << (StreamInfoList()
+ << StreamInfoPtr((new AudioStreamInfo("audio/x-vorbis"))
+ ->setSampleRate(48000)->setChannels(1)
+ ->setBitrate(80000)
+ ->addTag("container-format", "Ogg")
+ ->addTag("audio-codec", "Vorbis")))
+ << (TagList()
+ << makeTag("container-format", "Ogg")
+ << makeTag("audio-codec", "Vorbis")
+ << makeTag("bitrate", 80000U));
+}
+
+void DiscovererTest::verifyStreamInfo(QGst::DiscovererInfoPtr info)
+{
+ // verify discovery result
+ QVERIFY(!info.isNull());
+ QTEST(info->uri(), "uri");
+ QTEST(QString(), "errorDomain");
+ QCOMPARE(info->result(), QGst::DiscovererOk);
+ QTEST(info->duration(), "duration");
+ QTEST(info->seekable(), "seekable");
+ QVERIFY(!info->misc().isValid());
+
+ QFETCH(TagList, expectedTags);
+ QCOMPARE(info->tags().isEmpty(), expectedTags.isEmpty());
+
+ Q_FOREACH(const Tag &tag, expectedTags) {
+ QCOMPARE(info->tags().tagValue(tag.first), tag.second);
+ }
+
+ QFETCH(StreamInfoList, streams);
+ QVERIFY(!info->streamInfo().isNull());
+
+ if (streams.count() != 1 || !(*streams.constBegin())->isImage()) {
+ const QGst::DiscovererContainerInfoPtr root = info->streamInfo().dynamicCast<QGst::DiscovererContainerInfo>();
+ QVERIFY(!root.isNull());
+
+ const StreamInfoList nativeStreams = filter(streams, std::mem_fun(&StreamInfo::isNative));
+ QCOMPARE(root->streams().count(), nativeStreams.count());
+ } else {
+ const QGst::DiscovererVideoInfoPtr root = info->streamInfo().dynamicCast<QGst::DiscovererVideoInfo>();
+ QVERIFY(!root.isNull());
+ QVERIFY(root->isImage());
+ }
+
+ const StreamInfoList audioStreams = filterByStreamType(streams, GST_TYPE_DISCOVERER_AUDIO_INFO);
+ QCOMPARE(info->streams(GST_TYPE_DISCOVERER_AUDIO_INFO).count(), audioStreams.count());
+ QCOMPARE(info->audioStreams().count(), audioStreams.count());
+
+ const StreamInfoList videoStreams = filterByStreamType(streams, GST_TYPE_DISCOVERER_VIDEO_INFO);
+ QCOMPARE(info->streams(GST_TYPE_DISCOVERER_VIDEO_INFO).count(), videoStreams.count());
+ QCOMPARE(info->videoStreams().count(), videoStreams.count());
+
+ const StreamInfoList subtitleStreams = filterByStreamType(streams, GST_TYPE_DISCOVERER_SUBTITLE_INFO);
+ QCOMPARE(info->streams(GST_TYPE_DISCOVERER_SUBTITLE_INFO).count(), subtitleStreams.count());
+ QCOMPARE(info->subtitleStreams().count(), subtitleStreams.count());
+
+ const StreamInfoList containerStreams = filterByStreamType(streams, GST_TYPE_DISCOVERER_CONTAINER_INFO);
+ QCOMPARE(info->streams(GST_TYPE_DISCOVERER_CONTAINER_INFO).count(), containerStreams.count());
+ QCOMPARE(info->containerStreams().count(), containerStreams.count());
+
+ QCOMPARE(info->streams(GST_TYPE_DISCOVERER_STREAM_INFO).count(), streams.count());
+ QCOMPARE(info->streams().count(), streams.count());
+
+ Q_FOREACH(const QGst::DiscovererStreamInfoPtr &streamInfo, info->streams()) {
+ const StreamInfoList::ConstIterator it =
+ std::find_if(streams.constBegin(), streams.constEnd(),
+ std::bind2nd(std::mem_fun(&StreamInfo::acceptStream), streamInfo));
+
+ if (it == streams.constEnd()) {
+ Q_FOREACH(const StreamInfoPtr expectedInfo, streams) {
+ expectedInfo->acceptStream(streamInfo, StreamInfo::Debug);
+ }
+
+ QFAIL(qPrintable("Unexpected stream: " + streamInfo->caps()->toString()));
+ }
+
+ streams.removeAt(it - streams.constBegin());
+ QVERIFY(!streamInfo->misc().isValid());
+ }
+
+ QVERIFY(streams.isEmpty());
+}
+
+void DiscovererTest::cleanup()
+{
+ m_eventLoop.reset();
+}
+
+void DiscovererTest::testGLibTypes_data()
+{
+ QTest::addColumn<QString>("wrappedTypeName");
+ QTest::addColumn<QString>("expectedTypeName");
+
+ QTest::newRow("discoverer")
+ << QGlib::GetType<QGst::Discoverer>().name()
+ << QString::fromLatin1(g_type_name(GST_TYPE_DISCOVERER));
+ QTest::newRow("discoverer-info")
+ << QGlib::GetType<QGst::DiscovererInfo>().name()
+ << QString::fromLatin1(g_type_name(GST_TYPE_DISCOVERER_INFO));
+ QTest::newRow("discoverer-stream-info")
+ << QGlib::GetType<QGst::DiscovererStreamInfo>().name()
+ << QString::fromLatin1(g_type_name(GST_TYPE_DISCOVERER_STREAM_INFO));
+ QTest::newRow("discoverer-container-info")
+ << QGlib::GetType<QGst::DiscovererContainerInfo>().name()
+ << QString::fromLatin1(g_type_name(GST_TYPE_DISCOVERER_CONTAINER_INFO));
+ QTest::newRow("discoverer-audio-info")
+ << QGlib::GetType<QGst::DiscovererAudioInfo>().name()
+ << QString::fromLatin1(g_type_name(GST_TYPE_DISCOVERER_AUDIO_INFO));
+ QTest::newRow("discoverer-video-info")
+ << QGlib::GetType<QGst::DiscovererVideoInfo>().name()
+ << QString::fromLatin1(g_type_name(GST_TYPE_DISCOVERER_VIDEO_INFO));
+ QTest::newRow("discoverer-subtitle-info")
+ << QGlib::GetType<QGst::DiscovererSubtitleInfo>().name()
+ << QString::fromLatin1(g_type_name(GST_TYPE_DISCOVERER_SUBTITLE_INFO));
+}
+
+void DiscovererTest::testGLibTypes()
+{
+ QFETCH(QString, wrappedTypeName);
+ QFETCH(QString, expectedTypeName);
+
+ QCOMPARE(wrappedTypeName, expectedTypeName);
+}
+
+void DiscovererTest::testSyncDiscovery_data()
+{
+ setupDiscoveryData();
+}
+
+void DiscovererTest::testSyncDiscovery()
+{
+ // create a discoverer
+ QGst::DiscovererPtr discoverer = QGst::Discoverer::create(QGst::ClockTime::fromSeconds(1));
+ QVERIFY(!discoverer.isNull());
+
+ // test discovery request
+ QGst::DiscovererInfoPtr info;
+ QFETCH(QUrl, uri);
+
+ try {
+ info = discoverer->discoverUri(uri);
+ } catch(const QGlib::Error &error) {
+ QTEST(error.domain().toString(), "errorDomain");
+ QTEST(error.code(), "errorCode");
+ return;
+ }
+
+ verifyStreamInfo(info);
+}
+
+void DiscovererTest::testAsyncDiscovery_data()
+{
+ setupDiscoveryData();
+}
+
+void DiscovererTest::testAsyncDiscovery()
+{
+// glib event loop required - see QCoreApplicationPrivate::createEventDispatcher() for the defines check
+#if defined(Q_OS_WIN) || defined(Q_OS_BLACKBERRY) || defined(QT_NO_GLIB)
+ QSKIP_PORT("Platform does not have a GLib event loop", SkipAll);
+#endif
+
+ // setup discovery timeout
+ m_eventLoop.reset(new QEventLoop);
+ QTimer::singleShot(3000, m_eventLoop.data(), SLOT(quit()));
+
+ // create a discoverer
+ m_discoveryState = DiscoveryPending;
+ QGst::DiscovererPtr discoverer = QGst::Discoverer::create(QGst::ClockTime::fromSeconds(1));
+ QVERIFY(!discoverer.isNull());
+
+ QVERIFY(QGlib::connect(discoverer, "starting", this, &DiscovererTest::onStartingDiscovery, 0/*QGlib::PassSender*/));
+ QVERIFY(QGlib::connect(discoverer, "discovered", this, &DiscovererTest::onUriDiscovered));
+ QVERIFY(QGlib::connect(discoverer, "finished", this, &DiscovererTest::onDiscoveryFinished, QGlib::PassSender));
+
+ // place URI to discover
+ QFETCH(QUrl, uri);
+ discoverer->start();
+ QVERIFY(discoverer->discoverUriAsync(uri));
+
+ // verify discovery succeeded
+ QVERIFY2(m_eventLoop->exec(), "Discovery timeout out");
+ QCOMPARE(m_discoveryState, DiscoveryFinished);
+}
+
+void DiscovererTest::onStartingDiscovery()
+{
+ QCOMPARE(m_discoveryState, DiscoveryPending);
+ m_discoveryState = DiscoveryStarted;
+}
+
+void DiscovererTest::onUriDiscovered(QGst::DiscovererInfoPtr info, const QGlib::Error &error)
+{
+ QCOMPARE(m_discoveryState, DiscoveryStarted);
+ m_discoveryState = UriDiscovered;
+
+ if (error) {
+ QTEST(error.domain().toString(), "errorDomain");
+ QTEST(error.code(), "errorCode");
+ return;
+ }
+
+ verifyStreamInfo(info);
+}
+
+void DiscovererTest::onDiscoveryFinished()
+{
+ m_eventLoop->exit(1);
+ QCOMPARE(m_discoveryState, UriDiscovered);
+ m_discoveryState = DiscoveryFinished;
+}
+
+QTEST_MAIN(DiscovererTest)
+
+#include "moc_qgsttest.cpp"
+#include "discoverertest.moc"
diff --git a/tests/auto/eventtest.cpp b/tests/auto/eventtest.cpp
index 7392df4..1370df7 100644
--- a/tests/auto/eventtest.cpp
+++ b/tests/auto/eventtest.cpp
@@ -10,7 +10,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -20,6 +20,7 @@
#include <QGst/Object>
#include <QGst/Message>
#include <QGst/TagList>
+#include <QGst/Segment>
class EventTest : public QGstTest
{
@@ -43,19 +44,18 @@ private Q_SLOTS:
void EventTest::baseTest()
{
QGst::Structure s("mystructure");
+ s.setValue("myfield", 365);
+
QGst::EventPtr evt = QGst::NavigationEvent::create(s);
QVERIFY(evt->type()==QGst::EventNavigation);
QCOMPARE(evt->typeName(), QString("navigation"));
- QGst::StructurePtr ss = evt->internalStructure();
+ QGst::StructureConstPtr ss = evt->internalStructure();
QVERIFY(ss->isValid());
-
- ss->setValue("myfield", 365);
QCOMPARE(ss->value("myfield").get<int>(), 365);
QVERIFY(evt->timestamp());
- QVERIFY(evt->source().isNull());
evt->setSequenceNumber(123445);
QCOMPARE(evt->sequenceNumber(), static_cast<quint32>(123445));
@@ -72,7 +72,7 @@ void EventTest::copyTest()
QCOMPARE(evt->type(), evt2->type());
QCOMPARE(evt->timestamp(), evt2->timestamp());
- QGst::StructurePtr ss = evt2->internalStructure();
+ QGst::StructureConstPtr ss = evt2->internalStructure();
QVERIFY(ss->isValid());
QCOMPARE(ss->value("myfield").get<int>(), 365);
}
@@ -100,18 +100,14 @@ void EventTest::eosTest()
void EventTest::newSegmentTest()
{
- QGst::NewSegmentEventPtr evt = QGst::NewSegmentEvent::create(true, 1.0, 0.5, QGst::FormatTime, 12345,
- 234567, 12346);
- QVERIFY(evt->type()==QGst::EventNewSegment);
- QCOMPARE(evt->typeName(), QString("newsegment"));
-
- QVERIFY(evt->isUpdate());
- QCOMPARE(evt->rate(), 1.0);
- QCOMPARE(evt->appliedRate(), 0.5);
- QVERIFY(evt->format() == QGst::FormatTime);
- QCOMPARE(evt->start(), static_cast<qint64>(12345));
- QCOMPARE(evt->stop(), static_cast<qint64>(234567));
- QCOMPARE(evt->position(), static_cast<qint64>(12346));
+ QGst::Segment segment(QGst::FormatTime);
+ QGst::SegmentEventPtr evt = QGst::SegmentEvent::create(segment);
+
+ QVERIFY(evt->type()==QGst::EventSegment);
+ QCOMPARE(evt->typeName(), QString("segment"));
+
+ QGst::Segment segment2 = evt->segment();
+ QCOMPARE(segment2.format(), QGst::FormatTime);
};
//TODO GST_EVENT_TAG
@@ -119,7 +115,7 @@ void EventTest::newSegmentTest()
void EventTest::sinkMessageTest()
{
QGst::MessagePtr msg = QGst::BufferingMessage::create(QGst::ObjectPtr(), 90);
- QGst::SinkMessageEventPtr evt = QGst::SinkMessageEvent::create(msg);
+ QGst::SinkMessageEventPtr evt = QGst::SinkMessageEvent::create("sink-message", msg);
QVERIFY(evt->type()==QGst::EventSinkMessage);
QCOMPARE(evt->typeName(), QString("sink-message"));
@@ -131,10 +127,11 @@ void EventTest::sinkMessageTest()
void EventTest::qosTest()
{
- QGst::QosEventPtr evt = QGst::QosEvent::create(123.4, 23455, 98765432);
+ QGst::QosEventPtr evt = QGst::QosEvent::create(QGst::QosTypeUnderflow, 123.4, 23455, 98765432);
QVERIFY(evt->type()==QGst::EventQos);
QCOMPARE(evt->typeName(), QString("qos"));
+ QVERIFY(evt->qosType()==QGst::QosTypeUnderflow);
QCOMPARE(evt->proportion(), 123.4);
QCOMPARE(evt->diff(), QGst::ClockTimeDiff(23455));
QCOMPARE(evt->timestamp(), QGst::ClockTime(98765432));
@@ -165,7 +162,7 @@ void EventTest::navigationTest()
QVERIFY(evt->type()==QGst::EventNavigation);
QCOMPARE(evt->typeName(), QString("navigation"));
- QGst::StructurePtr ss = evt->internalStructure();
+ QGst::StructureConstPtr ss = evt->internalStructure();
QVERIFY(ss->isValid());
QCOMPARE(ss->value("myfield").get<int>(), 365);
}
diff --git a/tests/auto/memorytest.cpp b/tests/auto/memorytest.cpp
new file mode 100644
index 0000000..afa73de
--- /dev/null
+++ b/tests/auto/memorytest.cpp
@@ -0,0 +1,52 @@
+/*
+ Copyright (C) 2014 Diane Trout <diane@ghic.org>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "qgsttest.h"
+#include <QGlib/Error>
+#include <QGst/QGstMemory>
+#include <QGst/Allocator>
+
+class MemoryTest : public QGstTest
+{
+ Q_OBJECT
+private Q_SLOTS:
+ void testMap();
+};
+
+void MemoryTest::testMap()
+{
+ QGst::AllocatorPtr allocator = QGst::Allocator::getDefault();
+ QGst::MemoryPtr mem = allocator->alloc(100);
+
+ QCOMPARE(mem->size(), static_cast<size_t>(100));
+ QCOMPARE(mem->offset(), static_cast<size_t>(0));
+ QVERIFY(mem->maxSize() >= 100);
+
+ QGst::MapInfo info;
+ QVERIFY(mem->map(info, QGst::MapRead));
+ QVERIFY(info.data() != NULL);
+ QCOMPARE(info.size(), static_cast<size_t>(100));
+ QCOMPARE(info.maxSize(), mem->maxSize());
+
+ mem->unmap(info);
+ allocator->free(mem);
+}
+
+QTEST_APPLESS_MAIN(MemoryTest)
+
+#include "moc_qgsttest.cpp"
+#include "memorytest.moc"
diff --git a/tests/auto/messagetest.cpp b/tests/auto/messagetest.cpp
index 4d9fae3..fe9be95 100644
--- a/tests/auto/messagetest.cpp
+++ b/tests/auto/messagetest.cpp
@@ -10,7 +10,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -26,7 +26,6 @@ class MessageTest : public QGstTest
{
Q_OBJECT
private Q_SLOTS:
- void baseTest();
void eosMessageTest();
void errorMessageTest();
void warningMessageTest();
@@ -38,7 +37,7 @@ private Q_SLOTS:
void applicationMessageTest();
void elementMessageTest();
void segmentDoneMessageTest();
- void durationMessageTest();
+ void durationChangedMessageTest();
void latencyMessageTest();
void asyncDoneMessageTest();
void requestStateMessageTest();
@@ -46,29 +45,15 @@ private Q_SLOTS:
void qosMessageTest();
};
-void MessageTest::baseTest()
-{
- QGst::Structure s("mystructure");
- QGlib::Quark q = QGlib::Quark::fromString("test");
- QGlib::Error err(q, 10, "test error");
- QGst::ErrorMessagePtr msg = QGst::ErrorMessage::create(QGst::ObjectPtr(), err,
- "Test suite error");
-
- QGst::StructurePtr ss = msg->internalStructure();
- QVERIFY(ss->isValid());
- ss->setValue("myfield", 365);
- QCOMPARE(ss->value("myfield").get<int>(), 365);
-
- msg->setSequenceNumber(1456);
- QCOMPARE(msg->sequenceNumber(), 1456U);
-}
-
void MessageTest::eosMessageTest()
{
QGst::EosMessagePtr msg = QGst::EosMessage::create(QGst::ObjectPtr());
QVERIFY(msg->type()==QGst::MessageEos);
QCOMPARE(msg->typeName(), QString("eos"));
+
+ msg->setSequenceNumber(1456);
+ QCOMPARE(msg->sequenceNumber(), 1456U);
}
void MessageTest::errorMessageTest()
@@ -236,16 +221,11 @@ void MessageTest::segmentDoneMessageTest()
QCOMPARE(msg->position(), static_cast<qint64>(4567898));
}
-void MessageTest::durationMessageTest()
+void MessageTest::durationChangedMessageTest()
{
- QGst::DurationMessagePtr msg = QGst::DurationMessage::create(QGst::ObjectPtr(),
- QGst::FormatBytes, 1456788);
-
- QVERIFY(msg->type()==QGst::MessageDuration);
- QCOMPARE(msg->typeName(), QString("duration"));
-
- QVERIFY(msg->format()==QGst::FormatBytes);
- QCOMPARE(msg->duration(), static_cast<qint64>(1456788));
+ QGst::DurationChangedMessagePtr msg = QGst::DurationChangedMessage::create(QGst::ObjectPtr());
+ QVERIFY(msg->type()==QGst::MessageDurationChanged);
+ QCOMPARE(msg->typeName(), QString("duration-changed"));
}
void MessageTest::latencyMessageTest()
@@ -258,10 +238,12 @@ void MessageTest::latencyMessageTest()
void MessageTest::asyncDoneMessageTest()
{
- QGst::AsyncDoneMessagePtr msg = QGst::AsyncDoneMessage::create(QGst::ObjectPtr());
+ QGst::ClockTime time = QGst::ClockTime::fromTime(QTime(17,0));
+ QGst::AsyncDoneMessagePtr msg = QGst::AsyncDoneMessage::create(QGst::ObjectPtr(), time);
QVERIFY(msg->type()==QGst::MessageAsyncDone);
QCOMPARE(msg->typeName(), QString("async-done"));
+ QCOMPARE(msg->runningTime().toTime(), QTime(17,0));
}
void MessageTest::requestStateMessageTest()
diff --git a/tests/auto/padtest.cpp b/tests/auto/padtest.cpp
new file mode 100644
index 0000000..bb6fb54
--- /dev/null
+++ b/tests/auto/padtest.cpp
@@ -0,0 +1,55 @@
+/*
+ Copyright (C) 2013 Diane Trout <diane@ghic.org>.
+ (This was copied from buffertest.cpp)
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#include "qgsttest.h"
+#include <QGst/Element>
+#include <QGst/ElementFactory>
+#include <QGst/Pad>
+#include <QGst/Caps>
+#include <QGst/Event>
+
+class PadTest : public QGstTest
+{
+ Q_OBJECT
+private Q_SLOTS:
+ void capsTest();
+};
+
+void PadTest::capsTest()
+{
+ QGst::ElementPtr queue = QGst::ElementFactory::make("queue", NULL);
+ QGst::PadPtr pad = queue->getStaticPad("sink");
+ QGst::CapsPtr caps = QGst::Caps::createSimple("video/x-raw");
+ caps->setValue("width", 320);
+ caps->setValue("height", 240);
+
+ queue->setState(QGst::StatePlaying);
+
+ QGst::CapsEventPtr event = QGst::CapsEvent::create(caps);
+ QVERIFY(pad->sendEvent(event));
+
+ QGst::CapsPtr caps2 = pad->currentCaps();
+
+ QVERIFY(caps->equals(caps2));
+ queue->setState(QGst::StateNull);
+}
+QTEST_APPLESS_MAIN(PadTest)
+
+#include "moc_qgsttest.cpp"
+#include "padtest.moc"
+
+
diff --git a/tests/auto/parsetest.cpp b/tests/auto/parsetest.cpp
index b1fcd42..214920e 100644
--- a/tests/auto/parsetest.cpp
+++ b/tests/auto/parsetest.cpp
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/tests/auto/propertiestest.cpp b/tests/auto/propertiestest.cpp
index aa15f51..fa929b1 100644
--- a/tests/auto/propertiestest.cpp
+++ b/tests/auto/propertiestest.cpp
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/tests/auto/qgsttest.h b/tests/auto/qgsttest.h
index 99a82d4..f60e5f1 100644
--- a/tests/auto/qgsttest.h
+++ b/tests/auto/qgsttest.h
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -18,9 +18,19 @@
#define QGSTTEST_H
#include <QtTest/QtTest>
+#include <QGlib/Value>
+#include <QGst/ClockTime>
#include <QGst/Init>
#include <gst/gst.h>
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
+# define SkipSingle 0
+# define SkipAll 0
+# define QSKIP_PORT(m, a) QSKIP(m)
+#else
+# define QSKIP_PORT(m, a) QSKIP(m, a)
+#endif
+
class QGstTest : public QObject
{
Q_OBJECT
@@ -29,4 +39,19 @@ private Q_SLOTS:
void cleanupTestCase() { QGst::cleanup(); }
};
+namespace QTest // teach QCOMPARE() printing of certain GStreamer values
+{
+template<> char *toString(const QGst::ClockTime &t)
+{
+ return toString(quint64(t));
+}
+
+template<> char *toString(const QGlib::Value &value)
+{
+ bool ok = false;
+ QString text = value.type().name() + "(" + value.toString(&ok) + ")";
+ return ok ? toString(text) : 0;
+}
+} // namespace QTest
+
#endif
diff --git a/tests/auto/qtquick2test.cpp b/tests/auto/qtquick2test.cpp
new file mode 100644
index 0000000..05f1575
--- /dev/null
+++ b/tests/auto/qtquick2test.cpp
@@ -0,0 +1,87 @@
+/*
+ Copyright (C) 2017 Aleix Pol Gonzalez <aleixpol@kde.org>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include <QTest>
+#include <QSignalSpy>
+#include <QGst/Init>
+#include <QQmlApplicationEngine>
+#include <QQmlParserStatus>
+#include <QQmlContext>
+#include <QGlib/Connect>
+#include <QGst/Pipeline>
+#include <QGst/Bus>
+#include <QGst/Parse>
+#include <QGst/ElementFactory>
+#include <QGst/Message>
+#include <QGst/Quick/VideoSurface>
+
+
+class QtQuick2Test : public QObject
+{
+ Q_OBJECT
+private:
+ void onBusMessage(const QGst::MessagePtr &msg)
+ {
+ switch (msg->type()) {
+ case QGst::MessageError: //Some error occurred.
+ qCritical() << msg.staticCast<QGst::ErrorMessage>()->error();
+ break;
+ default:
+// qDebug() << msg->type();
+// qDebug() << msg->typeName();
+// qDebug() << msg->internalStructure()->name();
+ break;
+ }
+ }
+
+private Q_SLOTS:
+ void testLaunch();
+};
+
+void QtQuick2Test::testLaunch()
+{
+ QGst::init();
+
+ QQmlApplicationEngine* engine = new QQmlApplicationEngine(this);
+ QGst::Quick::VideoSurface *surface = new QGst::Quick::VideoSurface(this);
+
+ auto source = QGst::ElementFactory::make("videotestsrc", "");
+
+ auto pipeline = QGst::Pipeline::create();
+ auto bus = pipeline->bus();
+ bus->addSignalWatch();
+ QGlib::connect(bus, "message", this, &QtQuick2Test::onBusMessage);
+ pipeline->add(source, surface->videoSink());
+
+ source->link(surface->videoSink());
+
+ pipeline->setState(QGst::StatePlaying);
+
+ engine->rootContext()->setContextProperty("surface1", surface);
+ engine->load(QUrl("videoitemtest.qml"));
+
+ QSignalSpy spy(engine->rootObjects().first(), SIGNAL(frameSwapped()));
+ spy.wait(100);
+
+ pipeline->setState(QGst::StateNull);
+
+ delete engine;
+}
+
+QTEST_MAIN(QtQuick2Test)
+
+#include "qtquick2test.moc"
diff --git a/tests/auto/querytest.cpp b/tests/auto/querytest.cpp
index e94244e..19c1430 100644
--- a/tests/auto/querytest.cpp
+++ b/tests/auto/querytest.cpp
@@ -10,7 +10,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -36,13 +36,9 @@ private Q_SLOTS:
void QueryTest::baseTest()
{
- QGst::Structure s("mystructure");
QGst::PositionQueryPtr query = QGst::PositionQuery::create(QGst::FormatBytes);
-
- QGst::StructurePtr ss = query->internalStructure();
+ QGst::StructureConstPtr ss = query->internalStructure();
QVERIFY(ss->isValid());
- ss->setValue("myfield", 365);
- QCOMPARE(ss->value("myfield").get<int>(), 365);
}
void QueryTest::positionTest()
@@ -52,21 +48,18 @@ void QueryTest::positionTest()
QCOMPARE(query->typeName(), QString("position"));
QVERIFY(query->format()==QGst::FormatBytes);
- query->setValues(QGst::FormatTime, 1234567);
- QVERIFY(query->format()!=QGst::FormatBytes);
- QVERIFY(query->format()==QGst::FormatTime);
+ query->setValues(QGst::FormatBytes, 1234567);
QCOMPARE(query->position(), static_cast<qint64>(1234567));
}
void QueryTest::durationTest()
{
- QGst::DurationQueryPtr query = QGst::DurationQuery::create(QGst::FormatBytes);
+ QGst::DurationQueryPtr query = QGst::DurationQuery::create(QGst::FormatTime);
QVERIFY(query->type()==QGst::QueryDuration);
QCOMPARE(query->typeName(), QString("duration"));
- QVERIFY(query->format()==QGst::FormatBytes);
+ QVERIFY(query->format()==QGst::FormatTime);
query->setValues(QGst::FormatTime, 1234567);
- QVERIFY(query->format()!=QGst::FormatBytes);
QVERIFY(query->format()==QGst::FormatTime);
QCOMPARE(query->duration(), static_cast<qint64>(1234567));
}
diff --git a/tests/auto/refpointertest.cpp b/tests/auto/refpointertest.cpp
index bbb28ff..3bbca6b 100644
--- a/tests/auto/refpointertest.cpp
+++ b/tests/auto/refpointertest.cpp
@@ -11,7 +11,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -42,16 +42,20 @@ private Q_SLOTS:
void RefPointerTest::refTest1()
{
- GstObject *bin = GST_OBJECT(gst_object_ref(GST_OBJECT(gst_bin_new(NULL))));
- gst_object_sink(bin);
- QGst::ObjectPtr object = QGst::ObjectPtr::wrap(bin, false);
- QCOMPARE(GST_OBJECT_REFCOUNT_VALUE(bin), 1);
+ GstElement *element = gst_bin_new(NULL);
+ GstObject *bin1 = GST_OBJECT(element);
+ QCOMPARE(GST_OBJECT_REFCOUNT_VALUE(element), 1);
+
+ GstObject *bin2 = GST_OBJECT(gst_object_ref_sink(bin1));
+ QCOMPARE(GST_OBJECT_REFCOUNT_VALUE(bin2), 1);
+ QGst::ObjectPtr object = QGst::ObjectPtr::wrap(bin2, false);
+ QCOMPARE(GST_OBJECT_REFCOUNT_VALUE(bin2), 1);
}
void RefPointerTest::refTest2()
{
- GstObject *bin = GST_OBJECT(gst_object_ref(GST_OBJECT(gst_bin_new(NULL))));
- gst_object_sink(bin);
+ GstObject *bin = GST_OBJECT(gst_object_ref_sink(GST_OBJECT(gst_bin_new(NULL))));
+
{
QGst::ObjectPtr object = QGst::ObjectPtr::wrap(bin);
QCOMPARE(GST_OBJECT_REFCOUNT_VALUE(bin), 2);
@@ -66,8 +70,7 @@ void RefPointerTest::refTest2()
void RefPointerTest::dynamicCastTest()
{
- GstObject *bin = GST_OBJECT(gst_object_ref(GST_OBJECT(gst_bin_new(NULL))));
- gst_object_sink(bin);
+ GstObject *bin = GST_OBJECT(gst_object_ref_sink(GST_OBJECT(gst_bin_new(NULL))));
{
QGst::ObjectPtr object = QGst::ObjectPtr::wrap(bin);
@@ -84,8 +87,7 @@ void RefPointerTest::dynamicCastTest()
void RefPointerTest::dynamicCastDownObjectTest()
{
- GstObject *bin = GST_OBJECT(gst_object_ref(gst_bin_new(NULL)));
- gst_object_sink(bin);
+ GstObject *bin = GST_OBJECT(gst_object_ref_sink(gst_bin_new(NULL)));
{
QGlib::ObjectPtr object = QGlib::ObjectPtr::wrap(G_OBJECT(bin));
@@ -99,8 +101,7 @@ void RefPointerTest::dynamicCastDownObjectTest()
void RefPointerTest::dynamicCastUpObjectTest()
{
- GstBin *bin = GST_BIN(gst_object_ref(gst_bin_new(NULL)));
- gst_object_sink(bin);
+ GstBin *bin = GST_BIN(gst_object_ref_sink(gst_bin_new(NULL)));
{
QGst::BinPtr object = QGst::BinPtr::wrap(bin);
@@ -135,7 +136,7 @@ void RefPointerTest::dynamicCastIfaceToObjectTest()
void RefPointerTest::cppWrappersTest()
{
- QGst::ElementPtr e = QGst::ElementFactory::make("playbin2");
+ QGst::ElementPtr e = QGst::ElementFactory::make("playbin");
QVERIFY(!e.isNull());
{
@@ -170,7 +171,23 @@ void RefPointerTest::cppWrappersTest()
}
{
- QGst::MessagePtr msg = QGst::ApplicationMessage::create(e);
+ QGst::Structure s("mystruct");
+ s.setValue("days", 365);
+ QGst::MessagePtr msg = QGst::ApplicationMessage::create(e, s);
+ QVERIFY(!msg.isNull());
+ QGst::MessagePtr msg2 = msg;
+ QCOMPARE(static_cast<QGlib::RefCountedObject*>(msg.operator->()),
+ static_cast<QGlib::RefCountedObject*>(msg2.operator->()));
+ QVERIFY(msg2 == msg);
+
+ QGst::MessagePtr msg3 = QGst::MessagePtr::wrap(msg2);
+ QVERIFY(static_cast<QGlib::RefCountedObject*>(msg3.operator->())
+ != static_cast<QGlib::RefCountedObject*>(msg2.operator->()));
+ QVERIFY(msg3 == msg2);
+ }
+
+ {
+ QGst::MessagePtr msg = QGst::ElementMessage::create(e);
QGst::MessagePtr msg2 = msg;
QCOMPARE(static_cast<QGlib::RefCountedObject*>(msg.operator->()),
static_cast<QGlib::RefCountedObject*>(msg2.operator->()));
@@ -185,8 +202,10 @@ void RefPointerTest::cppWrappersTest()
void RefPointerTest::messageDynamicCastTest()
{
+ QGst::Structure s("mystruct");
+ s.setValue("frequency", 123456);
QGst::BinPtr bin = QGst::Bin::create();
- QGst::MessagePtr msg = QGst::ApplicationMessage::create(bin);
+ QGst::MessagePtr msg = QGst::ApplicationMessage::create(bin, s);
QVERIFY(!msg.isNull());
QVERIFY(!msg.dynamicCast<QGst::ApplicationMessage>().isNull());
QVERIFY(msg.dynamicCast<QGst::EosMessage>().isNull());
diff --git a/tests/auto/signalstest.cpp b/tests/auto/signalstest.cpp
index f7b13ac..a363654 100644
--- a/tests/auto/signalstest.cpp
+++ b/tests/auto/signalstest.cpp
@@ -11,7 +11,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -54,8 +54,8 @@ void SignalsTest::closureTest()
QGst::BinPtr bin = QGst::Bin::create("mybin");
closureCalled = false;
- QGlib::connect(bin, "parent-set", this, &SignalsTest::closureTestClosure, QGlib::PassSender);
- bin->setParent(pipeline);
+ QGlib::connect(bin, "element-added", this, &SignalsTest::closureTestClosure, QGlib::PassSender);
+ bin->add(pipeline);
QCOMPARE(closureCalled, true);
}
@@ -127,11 +127,11 @@ void SignalsTest::emitTest()
void SignalsTest::emitTypeTest()
{
QGst::BinPtr bin = QGst::Bin::create("mybin");
- QGlib::connect(bin, "parent-set", this, &SignalsTest::closureTestClosure, QGlib::PassSender);
+ QGlib::connect(bin, "deep-notify", this, &SignalsTest::closureTestClosure, QGlib::PassSender);
closureCalled = false;
QGst::PipelinePtr pipeline = QGst::Pipeline::create("mypipeline");
- QGlib::emit<void>(bin, "parent-set", pipeline);
+ QGlib::emit<void>(bin, "deep-notify", pipeline, bin->findProperty("name"));
QCOMPARE(closureCalled, true);
}
diff --git a/tests/auto/structstest.cpp b/tests/auto/structstest.cpp
index 001a511..33fcf8e 100644
--- a/tests/auto/structstest.cpp
+++ b/tests/auto/structstest.cpp
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
diff --git a/tests/auto/structuretest.cpp b/tests/auto/structuretest.cpp
index 8f55300..e9c7541 100644
--- a/tests/auto/structuretest.cpp
+++ b/tests/auto/structuretest.cpp
@@ -11,15 +11,18 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
*/
#include "qgsttest.h"
#include <QGst/Structure>
-#include <QGst/Buffer>
+#include <QGst/Element>
+#include <QGst/ElementFactory>
#include <QGst/Caps>
+#include <QGst/Pad>
+#include <QGst/Event>
class StructureTest : public QGstTest
{
@@ -107,23 +110,36 @@ void StructureTest::valueTest()
void StructureTest::sharedStructureTest()
{
- QGst::BufferPtr buffer = QGst::Buffer::create(10);
+ QGst::ElementPtr queue = QGst::ElementFactory::make("queue", NULL);
+ QGst::PadPtr pad = queue->getStaticPad("sink");
+ queue->setState(QGst::StatePlaying);
+
{
- QGst::CapsPtr caps = QGst::Caps::createSimple("video/x-raw-yuv");
+ QGst::CapsPtr caps = QGst::Caps::createSimple("video/x-raw");
caps->setValue("width", 320);
caps->setValue("height", 240);
- buffer->setCaps(caps);
+
+ // verify the Caps was created correctly
+ QGst::StructurePtr structure = caps->internalStructure(0);
+ QCOMPARE(caps->size(), static_cast<unsigned int>(1));
+ QCOMPARE(structure->name(), QString("video/x-raw"));
+
+ QGst::CapsEventPtr event = QGst::CapsEvent::create(caps);
+ QVERIFY(pad->sendEvent(event));
}
- QGst::StructurePtr structure = buffer->caps()->internalStructure(0);
- QCOMPARE(structure->name(), QString("video/x-raw-yuv"));
+ QCOMPARE(pad->currentCaps()->size(), static_cast<unsigned int>(1));
+ QGst::StructurePtr structure = pad->currentCaps()->internalStructure(0);
+ QCOMPARE(structure->name(), QString("video/x-raw"));
QCOMPARE(structure->value("width").toInt(), 320);
QCOMPARE(structure->value("height").toInt(), 240);
QGst::Structure s = structure->copy();
- QCOMPARE(s.name(), QString("video/x-raw-yuv"));
+ QCOMPARE(s.name(), QString("video/x-raw"));
QCOMPARE(s.value("width").toInt(), 320);
QCOMPARE(s.value("height").toInt(), 240);
+
+ queue->setState(QGst::StateNull);
}
diff --git a/tests/auto/taglisttest.cpp b/tests/auto/taglisttest.cpp
index 130bbc8..043f930 100644
--- a/tests/auto/taglisttest.cpp
+++ b/tests/auto/taglisttest.cpp
@@ -10,7 +10,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -19,7 +19,9 @@
#include <QGst/TagList>
#include <QGst/Buffer>
#include <QGst/Caps>
+#include <QGst/Sample>
#include <QGst/Structure>
+#include <QGst/Segment>
#include <QtCore/QDate>
class TagListTest : public QGstTest
@@ -31,7 +33,7 @@ private Q_SLOTS:
void dateTimeTest();
void copyTest();
void stringsTest();
- void bufferTest();
+ void sampleTest();
void numericTest();
};
@@ -108,11 +110,11 @@ void TagListTest::copyTest()
tl.setBitrate(320);
tl.setAlbumGain(0.85);
QGst::BufferPtr buffer = QGst::Buffer::create(10);
- QGst::CapsPtr caps = QGst::Caps::createSimple("video/x-raw-yuv");
+ QGst::CapsPtr caps = QGst::Caps::createSimple("video/x-raw");
caps->setValue("width", 320);
caps->setValue("height", 240);
- buffer->setCaps(caps);
- tl.setImage(buffer);
+ QGst::SamplePtr sample = QGst::Sample::create(buffer, caps, QGst::Segment(), QGst::Structure());
+ tl.setImage(sample);
QGst::TagList tl2(tl);
QCOMPARE(tl.title(), tl2.title());
@@ -120,11 +122,11 @@ void TagListTest::copyTest()
QCOMPARE(tl.bitrate(), tl2.bitrate());
QCOMPARE(tl.albumGain(), tl2.albumGain());
- QGst::BufferPtr buffer2 = tl2.image();
- QVERIFY(!buffer2.isNull());
- QGst::CapsPtr caps2 = buffer2->caps();
+ QGst::SamplePtr sample2 = tl2.image();
+ QVERIFY(!sample2.isNull());
+ QGst::CapsPtr caps2 = sample2->caps();
QGst::StructurePtr structure = caps2->internalStructure(0);
- QCOMPARE(structure->name(), QString("video/x-raw-yuv"));
+ QCOMPARE(structure->name(), QString("video/x-raw"));
int width = structure->value("width").get<int>();
QCOMPARE(width, 320);
}
@@ -354,52 +356,55 @@ void TagListTest::stringsTest()
qDebug() << tl;
}
-void TagListTest::bufferTest()
+void TagListTest::sampleTest()
{
QGst::TagList tl;
QGst::BufferPtr buffer = QGst::Buffer::create(10);
- QGst::CapsPtr caps = QGst::Caps::createSimple("video/x-raw-yuv");
+ QGst::CapsPtr caps = QGst::Caps::createSimple("video/x-raw");
caps->setValue("width", 320);
caps->setValue("height", 240);
- buffer->setCaps(caps);
- tl.setImage(buffer);
+ QGst::SamplePtr sample = QGst::Sample::create(buffer, caps, QGst::Segment(), QGst::Structure());
+ tl.setImage(sample);
QGst::BufferPtr bufferb = QGst::Buffer::create(10);
- QGst::CapsPtr capsb = QGst::Caps::createSimple("video/x-raw-rgb");
+ QGst::CapsPtr capsb = QGst::Caps::createSimple("video/x-raw");
capsb->setValue("width", 160);
- bufferb->setCaps(capsb);
- tl.setPreviewImage(bufferb);
+ QGst::SamplePtr sampleb = QGst::Sample::create(bufferb, capsb, QGst::Segment(), QGst::Structure());
+ tl.setPreviewImage(sampleb);
QGst::BufferPtr bufferc = QGst::Buffer::create(10);
QGst::CapsPtr capsc = QGst::Caps::createSimple("files");
capsc->setValue("attachment", QString("avalue"));
- bufferc->setCaps(capsc);
- tl.setAttachment(bufferc);
+ QGst::SamplePtr samplec = QGst::Sample::create(bufferc, capsc, QGst::Segment(), QGst::Structure());
+ tl.setAttachment(samplec);
- QGst::BufferPtr buffer2 = tl.image();
- QGst::CapsPtr caps2 = buffer2->caps();
+ QGst::SamplePtr sample2 = tl.image();
+ QGst::CapsPtr caps2 = sample2->caps();
QGst::StructurePtr structure2 = caps2->internalStructure(0);
- QCOMPARE(structure2->name(), QString("video/x-raw-yuv"));
+ QCOMPARE(structure2->name(), QString("video/x-raw"));
QCOMPARE(structure2->value("width").get<int>(), 320);
- QGst::BufferPtr buffer3 = tl.previewImage();
- QGst::CapsPtr caps3 = buffer3->caps();
+ QGst::SamplePtr sample3 = tl.previewImage();
+ QGst::CapsPtr caps3 = sample3->caps();
QGst::StructurePtr structure3 = caps3->internalStructure(0);
- QCOMPARE(structure3->name(), QString("video/x-raw-rgb"));
+ QCOMPARE(structure3->name(), QString("video/x-raw"));
QCOMPARE(structure3->value("width").get<int>(), 160);
- QGst::BufferPtr buffer4 = tl.attachment();
- QGst::CapsPtr caps4 = buffer4->caps();
+ QGst::SamplePtr sample4 = tl.attachment();
+ QGst::CapsPtr caps4 = sample4->caps();
QGst::StructurePtr structure4 = caps4->internalStructure(0);
QCOMPARE(structure4->name(), QString("files"));
QCOMPARE(structure4->value("attachment").get<QString>(), QString("avalue"));
- //now set multiple buffers and verify the count
- tl.setImage(buffer3, QGst::TagMergeAppend);
+ QGst::BufferPtr buffer2 = QGst::Buffer::create(222);
+ QGst::SamplePtr sample5 = QGst::Sample::create(buffer2, caps, QGst::Segment(), QGst::Structure());
+
+ //now set multiple samples and verify the count
+ tl.setImage(sample5, QGst::TagMergeAppend);
QCOMPARE(tl.imageCount(), 2);
- tl.setAttachment(buffer2, QGst::TagMergePrepend);
- QCOMPARE(tl.attachmentCount(), 2);
+ tl.setAttachment(sample2, QGst::TagMergePrepend);
+ QCOMPARE(tl.attachmentCount(), 1);
}
diff --git a/tests/auto/urihandlertest.cpp b/tests/auto/urihandlertest.cpp
index 2b2f39d..a449cf8 100644
--- a/tests/auto/urihandlertest.cpp
+++ b/tests/auto/urihandlertest.cpp
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -38,7 +38,8 @@ void UriHandlerTest::interfaceTest()
QVERIFY(u->setUri(QUrl::fromLocalFile("/bin/sh")));
QCOMPARE(u->uri(), QUrl::fromLocalFile("/bin/sh"));
- QCOMPARE(u->property("location").get<QString>(), QString("/bin/sh"));
+ QCOMPARE(u->property("location").get<QString>(),
+ QDir::toNativeSeparators(QLatin1String("/bin/sh")));
}
void UriHandlerTest::makeTest()
diff --git a/tests/auto/valuetest.cpp b/tests/auto/valuetest.cpp
index 22f4aea..3c4fa00 100644
--- a/tests/auto/valuetest.cpp
+++ b/tests/auto/valuetest.cpp
@@ -11,7 +11,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -42,6 +42,7 @@ private Q_SLOTS:
void castTest();
void qdebugTest();
void datetimeTest();
+ void errorTest();
};
void ValueTest::intTest()
@@ -91,9 +92,9 @@ void ValueTest::enumTest()
void ValueTest::flagsTest()
{
- QGlib::Value v = QGlib::Value::create(QGst::PadBlocked | QGst::PadFlushing | QGst::PadFlagLast);
+ QGlib::Value v = QGlib::Value::create(QGst::PadFlagBlocked | QGst::PadFlagFlushing | QGst::PadFlagLast);
QCOMPARE(v.type(), QGlib::GetType<QGst::PadFlags>());
- QCOMPARE(v.get<QGst::PadFlags>(), QGst::PadBlocked | QGst::PadFlushing | QGst::PadFlagLast);
+ QCOMPARE(v.get<QGst::PadFlags>(), QGst::PadFlagBlocked | QGst::PadFlagFlushing | QGst::PadFlagLast);
}
void ValueTest::objectTest()
@@ -117,12 +118,13 @@ void ValueTest::miniObjectTest()
void ValueTest::capsTest()
{
- QGst::CapsPtr caps = QGst::Caps::createSimple("video/x-raw-rgb");
+ QGst::CapsPtr caps = QGst::Caps::createSimple("video/x-raw");
+ QVERIFY(caps);
QGlib::Value v = QGlib::Value::create(caps);
QCOMPARE(v.type(), QGlib::GetType<QGst::Caps>());
QCOMPARE(static_cast<GstCaps*>(v.get<QGst::CapsPtr>()), static_cast<GstCaps*>(caps));
- QCOMPARE(v.get<QGst::CapsPtr>()->toString(), QString("video/x-raw-rgb"));
- QCOMPARE(v.get<QString>(), QString("video/x-raw-rgb"));
+ QCOMPARE(v.get<QGst::CapsPtr>()->toString(), QString("video/x-raw"));
+ QCOMPARE(v.get<QString>(), QString("video/x-raw"));
}
void ValueTest::valueTest()
@@ -259,6 +261,20 @@ void ValueTest::datetimeTest()
}
}
+void ValueTest::errorTest()
+{
+ QGlib::Value v;
+ QVERIFY(!v.isValid());
+ v.init<QGlib::Error>();
+ const QGlib::Quark domain = QGlib::Quark::fromString("test-error");
+ g_value_take_boxed(v, g_error_new_literal(domain, 42, "This is a test"));
+ QCOMPARE(v.type(), QGlib::GetType<QGlib::Error>());
+ const QGlib::Error error = v.toError();
+ QCOMPARE(error.domain().toString(), QString::fromUtf8("test-error"));
+ QCOMPARE(error.message(), QString::fromUtf8("This is a test"));
+ QCOMPARE(error.code(), 42);
+}
+
QTEST_APPLESS_MAIN(ValueTest)
#include "moc_qgsttest.cpp"
diff --git a/tests/auto/videoitemtest.qml b/tests/auto/videoitemtest.qml
new file mode 100644
index 0000000..589ca6e
--- /dev/null
+++ b/tests/auto/videoitemtest.qml
@@ -0,0 +1,20 @@
+import QtQuick 2.1
+import QtQuick.Window 2.1
+import QtGStreamer 1.0
+
+Window {
+ width: 200
+ height: 200
+ visible: true
+
+ ListView {
+ anchors.fill: parent
+ model: 3
+
+ delegate: VideoItem {
+ width: 100
+ height: 100
+ surface: surface1
+ }
+ }
+}
diff --git a/tests/compilation/CMakeLists.txt b/tests/compilation/CMakeLists.txt
index 9fa7ce7..0621ffd 100644
--- a/tests/compilation/CMakeLists.txt
+++ b/tests/compilation/CMakeLists.txt
@@ -1,13 +1,13 @@
add_test(NAME compilation_tests
COMMAND ${CMAKE_COMMAND}
- -DQTGLIB_LIBRARY=$<TARGET_FILE:${QTGLIB_LIBRARY}>
- -DQTGSTREAMER_LIBRARY=$<TARGET_FILE:${QTGSTREAMER_LIBRARY}>
- -DQTGSTREAMER_UI_LIBRARY=$<TARGET_FILE:${QTGSTREAMER_UI_LIBRARY}>
- -DQTGSTREAMER_UTILS_LIBRARY=$<TARGET_FILE:${QTGSTREAMER_UTILS_LIBRARY}>
+ -DQT_VERSION=${QT_VERSION}
+ -DQTGLIB_LIBRARY=$<TARGET_LINKER_FILE:${QTGLIB_LIBRARY}>
+ -DQTGSTREAMER_LIBRARY=$<TARGET_LINKER_FILE:${QTGSTREAMER_LIBRARY}>
-DQTGSTREAMER_INCLUDE_DIR=${QTGSTREAMER_INCLUDE_DIR}
-DQTGSTREAMER_STATIC=${QTGSTREAMER_STATIC}
-DCMAKE_MODULE_PATH=${CMAKE_MODULE_PATH}
-DBINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}/CompilationTests
-DSOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}
+ -DGENERATOR=${CMAKE_GENERATOR}
-P ${CMAKE_CURRENT_SOURCE_DIR}/RunCompilationTests.cmake
)
diff --git a/tests/compilation/CompilationTests.cmake b/tests/compilation/CompilationTests.cmake
index 13ac012..ca44979 100644
--- a/tests/compilation/CompilationTests.cmake
+++ b/tests/compilation/CompilationTests.cmake
@@ -11,7 +11,7 @@
# 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 General Public License for more details.
+# 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 <http://www.gnu.org/licenses/>.
diff --git a/tests/compilation/CompilationTests_CMakeLists.txt b/tests/compilation/CompilationTests_CMakeLists.txt
index aa5b2bc..ccfc865 100644
--- a/tests/compilation/CompilationTests_CMakeLists.txt
+++ b/tests/compilation/CompilationTests_CMakeLists.txt
@@ -2,11 +2,16 @@
# We misuse cmake here by running tests with the try_compile command and basing
# the result of the whole test suite on the cmake exit status.
-cmake_minimum_required(VERSION 2.8)
-find_package(QtGStreamer REQUIRED)
+cmake_minimum_required(VERSION 2.8.9)
+set(CMAKE_POSITION_INDEPENDENT_CODE ON)
+
+find_package(Boost 1.39 REQUIRED)
+find_package(Qt4or5 COMPONENTS Core REQUIRED)
+
+include(QtGStreamerConfigCommon)
include(MacroCXXCompilationTest)
-set(CMAKE_REQUIRED_LIBRARIES ${QTGSTREAMER_LIBRARIES})
+set(CMAKE_REQUIRED_LIBRARIES ${QTGSTREAMER_LIBRARY} ${QTGLIB_LIBRARY} ${Qt4or5_Core_LIBRARIES})
set(CMAKE_REQUIRED_INCLUDES ${QTGSTREAMER_INCLUDES})
set(CMAKE_REQUIRED_DEFINITIONS ${QTGSTREAMER_DEFINITIONS})
set(CMAKE_REQUIRED_FLAGS "${QTGSTREAMER_FLAGS}")
@@ -19,6 +24,9 @@ if (QTGSTREAMER_STATIC)
${GSTREAMER_INTERFACES_LIBRARY})
endif()
+include(HandleImportedTargetsInCMakeRequiredLibraries)
+handle_imported_targets_in_cmake_required_libraries(CMAKE_REQUIRED_LIBRARIES)
+
message("********* Begin running compilation tests *********")
include(CompilationTests.cmake)
evaluate_cxx_compilation_test_results()
diff --git a/tests/compilation/RunCompilationTests.cmake b/tests/compilation/RunCompilationTests.cmake
index 904f9a2..f1f4dcf 100644
--- a/tests/compilation/RunCompilationTests.cmake
+++ b/tests/compilation/RunCompilationTests.cmake
@@ -12,6 +12,8 @@ execute_process(COMMAND ${CMAKE_COMMAND} -E copy ${SOURCE_DIR}/CompilationTests.
# Run cmake to execute the tests
execute_process(COMMAND ${CMAKE_COMMAND}
+ -G "${GENERATOR}"
+ -DQT_VERSION=${QT_VERSION}
-DQTGLIB_LIBRARY=${QTGLIB_LIBRARY}
-DQTGSTREAMER_LIBRARY=${QTGSTREAMER_LIBRARY}
-DQTGSTREAMER_UI_LIBRARY=${QTGSTREAMER_UI_LIBRARY}
diff --git a/tests/manual/CMakeLists.txt b/tests/manual/CMakeLists.txt
index 5d4ac2b..ca33d0f 100644
--- a/tests/manual/CMakeLists.txt
+++ b/tests/manual/CMakeLists.txt
@@ -1,20 +1,29 @@
-include_directories(${CMAKE_CURRENT_BINARY_DIR} ${QTGSTREAMER_INCLUDES})
+include_directories(${QTGSTREAMER_INCLUDES})
add_definitions(${QTGSTREAMER_DEFINITIONS})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${QTGSTREAMER_FLAGS}")
-qt4_wrap_ui(QWIDGETVIDEOSINKTEST_UI qwidgetvideosinktest.ui)
-automoc4_add_executable(qwidgetvideosinktest qwidgetvideosinktest.cpp ${QWIDGETVIDEOSINKTEST_UI})
-target_link_libraries(qwidgetvideosinktest ${QT_QTGUI_LIBRARIES} ${QTGSTREAMER_LIBRARIES})
+add_definitions(
+ -DQTVIDEOSINK_NAME="${QTVIDEOSINK_NAME}"
+ -DQTGLVIDEOSINK_NAME="${QTGLVIDEOSINK_NAME}"
+ -DQWIDGETVIDEOSINK_NAME="${QWIDGETVIDEOSINK_NAME}"
+)
+qt4or5_wrap_ui(QWIDGETVIDEOSINKTEST_UI qwidgetvideosinktest.ui)
+add_executable(qwidgetvideosinktest qwidgetvideosinktest.cpp ${QWIDGETVIDEOSINKTEST_UI})
+target_link_libraries(qwidgetvideosinktest ${QTGSTREAMER_LIBRARIES})
+qt4or5_use_modules(qwidgetvideosinktest Core Gui Widgets)
-qt4_wrap_ui(VIDEOWIDGETTEST_UI videowidgettest.ui)
-automoc4_add_executable(videowidgettest videowidgettest.cpp ${VIDEOWIDGETTEST_UI})
+qt4or5_wrap_ui(VIDEOWIDGETTEST_UI videowidgettest.ui)
+add_executable(videowidgettest videowidgettest.cpp ${VIDEOWIDGETTEST_UI})
target_link_libraries(videowidgettest ${QTGSTREAMER_UI_LIBRARIES})
+qt4or5_use_modules(videowidgettest Core Gui Widgets)
-qt4_wrap_ui(VIDEOWIDGETPIPELINETEST_UI videowidgetpipelinetest.ui)
-automoc4_add_executable(videowidgetpipelinetest videowidgetpipelinetest.cpp ${VIDEOWIDGETPIPELINETEST_UI})
+qt4or5_wrap_ui(VIDEOWIDGETPIPELINETEST_UI videowidgetpipelinetest.ui)
+add_executable(videowidgetpipelinetest videowidgetpipelinetest.cpp ${VIDEOWIDGETPIPELINETEST_UI})
target_link_libraries(videowidgetpipelinetest ${QTGSTREAMER_UI_LIBRARIES})
+qt4or5_use_modules(videowidgetpipelinetest Core Gui Widgets)
-qt4_wrap_ui(VIDEOORIENTATIONTEST_UI videoorientationtest.ui)
-automoc4_add_executable(videoorientationtest videoorientationtest.cpp ${VIDEOORIENTATIONTEST_UI})
+qt4or5_wrap_ui(VIDEOORIENTATIONTEST_UI videoorientationtest.ui)
+add_executable(videoorientationtest videoorientationtest.cpp ${VIDEOORIENTATIONTEST_UI})
target_link_libraries(videoorientationtest ${QTGSTREAMER_UI_LIBRARIES})
+qt4or5_use_modules(videoorientationtest Core Gui Widgets)
diff --git a/tests/manual/qwidgetvideosinktest.cpp b/tests/manual/qwidgetvideosinktest.cpp
index 06bb5d0..c43a488 100644
--- a/tests/manual/qwidgetvideosinktest.cpp
+++ b/tests/manual/qwidgetvideosinktest.cpp
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -18,8 +18,9 @@
#include <QGst/Init>
#include <QGst/Pipeline>
#include <QGst/ElementFactory>
-#include <QtGui/QApplication>
-#include <QtGui/QWidget>
+#include <QApplication>
+#include <QWidget>
+
class QWidgetVideoSinkTest : public QWidget
{
@@ -51,7 +52,7 @@ QWidgetVideoSinkTest::QWidgetVideoSinkTest(QWidget *parent, Qt::WindowFlags f)
m_pipeline = QGst::Pipeline::create();
QGst::ElementPtr src = QGst::ElementFactory::make("videotestsrc");
- m_sink = QGst::ElementFactory::make("qwidgetvideosink");
+ m_sink = QGst::ElementFactory::make(QWIDGETVIDEOSINK_NAME);
if (!src || !m_sink) {
throw std::runtime_error("Unable to initialize the required elements");
diff --git a/tests/manual/videoorientationtest.cpp b/tests/manual/videoorientationtest.cpp
index 51ab119..083ea27 100644
--- a/tests/manual/videoorientationtest.cpp
+++ b/tests/manual/videoorientationtest.cpp
@@ -10,7 +10,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -20,9 +20,9 @@
#include <QGst/Pipeline>
#include <QGst/ElementFactory>
#include <QGst/VideoOrientation>
-#include <QtGui/QApplication>
-#include <QtGui/QMessageBox>
-#include <QtGui/QCheckBox>
+#include <QApplication>
+#include <QMessageBox>
+#include <QCheckBox>
class VideoOrientationTest : public QWidget
{
diff --git a/tests/manual/videowidgetpipelinetest.cpp b/tests/manual/videowidgetpipelinetest.cpp
index 7b7732e..81fe86a 100644
--- a/tests/manual/videowidgetpipelinetest.cpp
+++ b/tests/manual/videowidgetpipelinetest.cpp
@@ -10,7 +10,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -19,7 +19,7 @@
#include <QGst/Init>
#include <QGst/Pipeline>
#include <QGst/ElementFactory>
-#include <QtGui/QApplication>
+#include <QApplication>
class VideoWidgetPipelineTest : public QWidget
{
@@ -69,4 +69,4 @@ int main(int argc, char **argv)
return app.exec();
}
-#include "videowidgetpipelinetest.moc" \ No newline at end of file
+#include "videowidgetpipelinetest.moc"
diff --git a/tests/manual/videowidgettest.cpp b/tests/manual/videowidgettest.cpp
index 6d41cf5..a269dc4 100644
--- a/tests/manual/videowidgettest.cpp
+++ b/tests/manual/videowidgettest.cpp
@@ -9,7 +9,7 @@
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 General Public License for more details.
+ 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 <http://www.gnu.org/licenses/>.
@@ -18,9 +18,9 @@
#include <QGst/Init>
#include <QGst/Pipeline>
#include <QGst/ElementFactory>
-#include <QtGui/QApplication>
-#include <QtGui/QMessageBox>
-#include <QtGui/QButtonGroup>
+#include <QApplication>
+#include <QMessageBox>
+#include <QButtonGroup>
class VideoWidgetTest : public QWidget
{