diff -Nrup a/cmake/modules/FindGLIB2.cmake b/cmake/modules/FindGLIB2.cmake --- a/cmake/modules/FindGLIB2.cmake 2014-07-08 20:38:36.000000000 +0200 +++ b/cmake/modules/FindGLIB2.cmake 2018-05-05 02:56:22.000000000 +0200 @@ -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 diff -Nrup a/cmake/modules/FindGStreamer.cmake b/cmake/modules/FindGStreamer.cmake --- a/cmake/modules/FindGStreamer.cmake 2014-07-08 20:38:36.000000000 +0200 +++ b/cmake/modules/FindGStreamer.cmake 2018-05-05 02:56:22.000000000 +0200 @@ -2,7 +2,8 @@ # 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 # @@ -32,10 +33,13 @@ set(GSTREAMER_ABI_VERSION "1.0") find_package(PkgConfig) if (PKG_CONFIG_FOUND) - pkg_check_modules(PKG_GSTREAMER gstreamer-${GSTREAMER_ABI_VERSION}) - exec_program(${PKG_CONFIG_EXECUTABLE} - ARGS --variable pluginsdir gstreamer-${GSTREAMER_ABI_VERSION} - OUTPUT_VARIABLE PKG_GSTREAMER_PLUGIN_DIR) + 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 @@ -47,6 +51,14 @@ find_path(GSTREAMER_INCLUDE_DIR HINTS ${PKG_GSTREAMER_INCLUDE_DIRS} ${PKG_GSTREAMER_INCLUDEDIR} PATH_SUFFIXES gstreamer-${GSTREAMER_ABI_VERSION}) +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() @@ -57,14 +69,17 @@ 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_PLUGIN_DIR) +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() @@ -88,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) @@ -113,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() @@ -128,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 -Nrup a/cmake/modules/FindGStreamerPluginsBase.cmake b/cmake/modules/FindGStreamerPluginsBase.cmake --- a/cmake/modules/FindGStreamerPluginsBase.cmake 2014-07-08 20:38:36.000000000 +0200 +++ b/cmake/modules/FindGStreamerPluginsBase.cmake 2018-05-05 02:56:22.000000000 +0200 @@ -23,15 +23,19 @@ set(GSTREAMER_ABI_VERSION "1.0") 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() @@ -67,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 -Nrup a/cmake/modules/FindQt4or5.cmake b/cmake/modules/FindQt4or5.cmake --- a/cmake/modules/FindQt4or5.cmake 2014-07-08 20:38:36.000000000 +0200 +++ b/cmake/modules/FindQt4or5.cmake 2018-05-05 02:56:22.000000000 +0200 @@ -49,6 +49,16 @@ macro(_qt4or5_component_names_to_qt_comp 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() @@ -195,13 +205,13 @@ function(qt4or5_use_modules _target _lin set(modules ${_link_type} ${ARGN}) endif() - _qt4or5_component_names_to_qt_components(real_modules ${modules}) - # 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_use_modules(${_target} ${link_type} ${real_modules}) + _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() diff -Nrup a/cmake/modules/MacroFindGStreamerLibrary.cmake b/cmake/modules/MacroFindGStreamerLibrary.cmake --- a/cmake/modules/MacroFindGStreamerLibrary.cmake 2014-07-08 20:38:36.000000000 +0200 +++ b/cmake/modules/MacroFindGStreamerLibrary.cmake 2018-05-05 02:56:22.000000000 +0200 @@ -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 _head 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 _head 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 -Nrup a/cmake/modules/QtGStreamerConfig.cmake.in b/cmake/modules/QtGStreamerConfig.cmake.in --- a/cmake/modules/QtGStreamerConfig.cmake.in 2014-07-08 20:38:36.000000000 +0200 +++ b/cmake/modules/QtGStreamerConfig.cmake.in 2018-05-05 02:56:22.000000000 +0200 @@ -67,11 +67,8 @@ endif() unset(_QTGSTREAMER_FIND_DEPS_ARGS) -# include QtGStreamerConfigCommon.cmake from the same directory -find_file(_QTGSTREAMER_CONFIG_COMMON_FILE QtGStreamerConfigCommon.cmake - PATHS ${_QTGSTREAMER_CONFIG_DIR} NO_DEFAULT_PATH) -include(${_QTGSTREAMER_CONFIG_COMMON_FILE}) -unset(_QTGSTREAMER_CONFIG_COMMON_FILE) +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 -Nrup a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt 2014-07-08 20:38:36.000000000 +0200 +++ b/CMakeLists.txt 2018-05-05 02:56:22.000000000 +0200 @@ -78,26 +78,26 @@ endif() set(QTGSTREAMER_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/src) include(QtGStreamerConfigCommon) -find_package(GStreamer 1.0.0 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 "1.0.0") + "http://gstreamer.freedesktop.org/" TRUE "1.2.0") macro_log_feature(GSTREAMER_BASE_LIBRARY_FOUND "GStreamer base library" "Used for building the ${QTVIDEOSINK_NAME} element" - "http://gstreamer.freedesktop.org/" FALSE "1.0.0") + "http://gstreamer.freedesktop.org/" FALSE "1.2.0") -find_package(GStreamerPluginsBase 1.0.0 COMPONENTS app audio video pbutils) +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 "1.0.0") + "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 "1.0.0") + "http://gstreamer.freedesktop.org/" TRUE "1.2.0") macro_log_feature(GSTREAMER_VIDEO_LIBRARY_FOUND "GStreamer video library" "Required to build QtGStreamer" - "http://gstreamer.freedesktop.org/" TRUE "1.0.0") + "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.0.0") + "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) @@ -106,6 +106,7 @@ find_package(GObject) macro_log_feature(GOBJECT_FOUND "GObject" "Required to build QtGLib" "http://www.gtk.org/" TRUE) set(CMAKE_REQUIRED_INCLUDES ${QTGSTREAMER_INCLUDES}) +add_definitions(${GSTREAMER_DEFINITIONS}) include(CheckCXXSourceCompiles) check_cxx_source_compiles(" #include <QtCore/QtGlobal> diff -Nrup a/elements/CMakeLists.txt b/elements/CMakeLists.txt --- a/elements/CMakeLists.txt 2014-07-08 20:38:36.000000000 +0200 +++ b/elements/CMakeLists.txt 2018-05-05 02:56:22.000000000 +0200 @@ -8,7 +8,7 @@ add_definitions(-DPACKAGE="qt-gstreamer" -DGST_DISABLE_XML -DGST_DISABLE_LOADSAVE) -include_directories(${GSTREAMER_INCLUDE_DIR} ${GLIB2_INCLUDE_DIR}) +include_directories(${GSTREAMER_INCLUDE_DIRS} ${GLIB2_INCLUDE_DIR}) if (GSTREAMER_BASE_LIBRARY_FOUND AND GSTREAMER_VIDEO_LIBRARY_FOUND) include_directories(${GSTREAMER_BASE_INCLUDE_DIR} ${GSTREAMER_VIDEO_INCLUDE_DIR}) diff -Nrup a/elements/gstqtvideosink/delegates/basedelegate.cpp b/elements/gstqtvideosink/delegates/basedelegate.cpp --- a/elements/gstqtvideosink/delegates/basedelegate.cpp 2014-07-08 20:38:36.000000000 +0200 +++ b/elements/gstqtvideosink/delegates/basedelegate.cpp 2018-05-05 02:56:22.000000000 +0200 @@ -155,7 +155,7 @@ bool BaseDelegate::event(QEvent *event) BufferEvent *bufEvent = dynamic_cast<BufferEvent*>(event); Q_ASSERT(bufEvent); - GST_TRACE_OBJECT(m_sink, "Received buffer %"GST_PTR_FORMAT, bufEvent->buffer); + GST_TRACE_OBJECT(m_sink, "Received buffer %" GST_PTR_FORMAT, bufEvent->buffer); if (isActive()) { gst_buffer_replace (&m_buffer, bufEvent->buffer); @@ -181,7 +181,7 @@ bool BaseDelegate::event(QEvent *event) { GST_LOG_OBJECT(m_sink, "Received deactivate event"); - g_clear_pointer(&m_buffer, gst_buffer_unref); + gst_buffer_replace (&m_buffer, NULL); update(); return true; diff -Nrup a/elements/gstqtvideosink/delegates/qtquick2videosinkdelegate.cpp b/elements/gstqtvideosink/delegates/qtquick2videosinkdelegate.cpp --- a/elements/gstqtvideosink/delegates/qtquick2videosinkdelegate.cpp 2014-07-08 20:38:36.000000000 +0200 +++ b/elements/gstqtvideosink/delegates/qtquick2videosinkdelegate.cpp 2018-05-05 02:56:22.000000000 +0200 @@ -32,6 +32,7 @@ QSGNode* QtQuick2VideoSinkDelegate::upda if (!vnode) { GST_INFO_OBJECT(m_sink, "creating new VideoNode"); vnode = new VideoNode; + m_formatDirty = true; } if (!m_buffer) { diff -Nrup a/elements/gstqtvideosink/delegates/qwidgetvideosinkdelegate.cpp b/elements/gstqtvideosink/delegates/qwidgetvideosinkdelegate.cpp --- a/elements/gstqtvideosink/delegates/qwidgetvideosinkdelegate.cpp 2014-07-08 20:38:36.000000000 +0200 +++ b/elements/gstqtvideosink/delegates/qwidgetvideosinkdelegate.cpp 2018-05-05 02:56:22.000000000 +0200 @@ -36,7 +36,7 @@ QWidget *QWidgetVideoSinkDelegate::widge void QWidgetVideoSinkDelegate::setWidget(QWidget *widget) { - GST_LOG_OBJECT(m_sink, "Setting \"widget\" property to %"GST_PTR_FORMAT, widget); + GST_LOG_OBJECT(m_sink, "Setting \"widget\" property to %" GST_PTR_FORMAT, widget); if (m_widget) { m_widget.data()->removeEventFilter(this); diff -Nrup a/elements/gstqtvideosink/gstqtglvideosinkbase.cpp b/elements/gstqtvideosink/gstqtglvideosinkbase.cpp --- a/elements/gstqtvideosink/gstqtglvideosinkbase.cpp 2014-07-08 20:38:36.000000000 +0200 +++ b/elements/gstqtvideosink/gstqtglvideosinkbase.cpp 2018-05-05 02:56:22.000000000 +0200 @@ -122,13 +122,13 @@ void GstQtGLVideoSinkBase::finalize(GObj //------------------------------ -void GstQtGLVideoSinkBase::colorbalance_init(GstColorBalanceInterface *interface, gpointer data) +void GstQtGLVideoSinkBase::colorbalance_init(GstColorBalanceInterface *balance_interface, gpointer data) { Q_UNUSED(data); - interface->list_channels = GstQtGLVideoSinkBase::colorbalance_list_channels; - interface->set_value = GstQtGLVideoSinkBase::colorbalance_set_value; - interface->get_value = GstQtGLVideoSinkBase::colorbalance_get_value; - interface->get_balance_type = GstQtGLVideoSinkBase::colorbalance_get_balance_type; + 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) diff -Nrup a/elements/gstqtvideosink/gstqtglvideosinkbase.h b/elements/gstqtvideosink/gstqtglvideosinkbase.h --- a/elements/gstqtvideosink/gstqtglvideosinkbase.h 2014-07-08 20:38:36.000000000 +0200 +++ b/elements/gstqtvideosink/gstqtglvideosinkbase.h 2018-05-05 02:56:22.000000000 +0200 @@ -61,7 +61,7 @@ private: static void init(GTypeInstance *instance, gpointer g_class); static void finalize(GObject *object); - static void colorbalance_init(GstColorBalanceInterface *interface, gpointer data); + 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, diff -Nrup a/elements/gstqtvideosink/gstqtquick2videosink.cpp b/elements/gstqtvideosink/gstqtquick2videosink.cpp --- a/elements/gstqtvideosink/gstqtquick2videosink.cpp 2014-07-08 20:38:36.000000000 +0200 +++ b/elements/gstqtvideosink/gstqtquick2videosink.cpp 2018-05-05 02:56:22.000000000 +0200 @@ -248,7 +248,7 @@ gst_qt_quick2_video_sink_show_frame(GstV { GstQtQuick2VideoSink *self = GST_QT_QUICK2_VIDEO_SINK (sink); - GST_TRACE_OBJECT(self, "Posting new buffer (%"GST_PTR_FORMAT") for rendering.", buffer); + GST_TRACE_OBJECT(self, "Posting new buffer (%" GST_PTR_FORMAT ") for rendering.", buffer); QCoreApplication::postEvent(self->priv->delegate, new BaseDelegate::BufferEvent(buffer)); diff -Nrup a/elements/gstqtvideosink/gstqtvideosinkbase.cpp b/elements/gstqtvideosink/gstqtvideosinkbase.cpp --- a/elements/gstqtvideosink/gstqtvideosinkbase.cpp 2014-07-08 20:38:36.000000000 +0200 +++ b/elements/gstqtvideosink/gstqtvideosinkbase.cpp 2018-05-05 02:56:22.000000000 +0200 @@ -207,7 +207,7 @@ GstFlowReturn GstQtVideoSinkBase::show_f { GstQtVideoSinkBase *sink = GST_QT_VIDEO_SINK_BASE(video_sink); - GST_TRACE_OBJECT(sink, "Posting new buffer (%"GST_PTR_FORMAT") for rendering.", buffer); + GST_TRACE_OBJECT(sink, "Posting new buffer (%" GST_PTR_FORMAT ") for rendering.", buffer); QCoreApplication::postEvent(sink->delegate, new BaseDelegate::BufferEvent(buffer)); diff -Nrup a/elements/gstqtvideosink/painters/openglsurfacepainter.cpp b/elements/gstqtvideosink/painters/openglsurfacepainter.cpp --- a/elements/gstqtvideosink/painters/openglsurfacepainter.cpp 2014-07-08 20:38:36.000000000 +0200 +++ b/elements/gstqtvideosink/painters/openglsurfacepainter.cpp 2018-05-05 02:56:22.000000000 +0200 @@ -37,10 +37,10 @@ #define QRECT_TO_GLMATRIX(rect) \ { \ - GLfloat(rect.left()) , GLfloat(rect.bottom() + 1), \ - GLfloat(rect.right() + 1), GLfloat(rect.bottom() + 1), \ + GLfloat(rect.left()) , GLfloat(rect.bottom()), \ + GLfloat(rect.right()), GLfloat(rect.bottom()), \ GLfloat(rect.left()) , GLfloat(rect.top()), \ - GLfloat(rect.right() + 1), GLfloat(rect.top()) \ + GLfloat(rect.right()), GLfloat(rect.top()) \ } OpenGLSurfacePainter::OpenGLSurfacePainter() @@ -146,9 +146,9 @@ void OpenGLSurfacePainter::updateColors( #endif case GST_VIDEO_COLOR_MATRIX_BT709: m_colorMatrix *= QMatrix4x4( - 1.164, 0.000, 1.793, -0.5727, - 1.164, -0.534, -0.213, 0.3007, - 1.164, 2.115, 0.000, -1.1302, + 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: diff -Nrup a/elements/gstqtvideosink/painters/videomaterial.cpp b/elements/gstqtvideosink/painters/videomaterial.cpp --- a/elements/gstqtvideosink/painters/videomaterial.cpp 2014-07-08 20:38:36.000000000 +0200 +++ b/elements/gstqtvideosink/painters/videomaterial.cpp 2018-05-05 02:56:22.000000000 +0200 @@ -252,6 +252,7 @@ VideoMaterial::~VideoMaterial() { if (!m_textureSize.isEmpty()) glDeleteTextures(m_textureCount, m_textureIds); + gst_buffer_replace(&m_frame, NULL); } int VideoMaterial::compare(const QSGMaterial *other) const @@ -383,9 +384,9 @@ void VideoMaterial::updateColors(int bri switch (m_colorMatrixType) { case GST_VIDEO_COLOR_MATRIX_BT709: m_colorMatrix *= QMatrix4x4( - 1.164, 0.000, 1.793, -0.5727, - 1.164, -0.534, -0.213, 0.3007, - 1.164, 2.115, 0.000, -1.1302, + 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: @@ -413,19 +414,27 @@ void VideoMaterial::bind() if (frame) { GstMapInfo info; gst_buffer_map(frame, &info, GST_MAP_READ); - functions->glActiveTexture(GL_TEXTURE1); - bindTexture(1, info.data); - functions->glActiveTexture(GL_TEXTURE2); - bindTexture(2, info.data); + 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 { - functions->glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, m_textureIds[1]); - functions->glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, m_textureIds[2]); + 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]); } diff -Nrup a/elements/gstqtvideosink/painters/videonode.cpp b/elements/gstqtvideosink/painters/videonode.cpp --- a/elements/gstqtvideosink/painters/videonode.cpp 2014-07-08 20:38:36.000000000 +0200 +++ b/elements/gstqtvideosink/painters/videonode.cpp 2018-05-05 02:56:22.000000000 +0200 @@ -22,7 +22,7 @@ #include <QtQuick/QSGFlatColorMaterial> VideoNode::VideoNode() - : QSGGeometryNode() + : m_validGeometry(false), QSGGeometryNode() { setFlags(OwnsGeometry | OwnsMaterial, true); setMaterialTypeSolidBlack(); @@ -31,8 +31,8 @@ VideoNode::VideoNode() void VideoNode::changeFormat(const BufferFormat & format) { setMaterial(VideoMaterial::create(format)); - setGeometry(0); m_materialType = MaterialTypeVideo; + m_validGeometry = false; } void VideoNode::setMaterialTypeSolidBlack() @@ -40,8 +40,8 @@ void VideoNode::setMaterialTypeSolidBlac QSGFlatColorMaterial *m = new QSGFlatColorMaterial; m->setColor(Qt::black); setMaterial(m); - setGeometry(0); m_materialType = MaterialTypeSolidBlack; + m_validGeometry = false; } void VideoNode::setCurrentFrame(GstBuffer* buffer) @@ -77,7 +77,7 @@ void VideoNode::updateGeometry(const Pai QSGGeometry *g = geometry(); if (m_materialType == MaterialTypeVideo) { - if (!g) + if (!m_validGeometry) g = new QSGGeometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4); QSGGeometry::TexturedPoint2D *v = g->vertexDataAsTexturedPoint2D(); @@ -94,7 +94,7 @@ void VideoNode::updateGeometry(const Pai setTex(v + 2, areas.sourceRect.topRight()); setTex(v + 3, areas.sourceRect.bottomRight()); } else { - if (!g) + if (!m_validGeometry) g = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 4); QSGGeometry::Point2D *v = g->vertexDataAsPoint2D(); @@ -105,8 +105,10 @@ void VideoNode::updateGeometry(const Pai setGeom(v + 3, areas.videoArea.bottomRight()); } - if (!geometry()) + if (!m_validGeometry) { setGeometry(g); + m_validGeometry = true; + } markDirty(DirtyGeometry); } diff -Nrup a/elements/gstqtvideosink/painters/videonode.h b/elements/gstqtvideosink/painters/videonode.h --- a/elements/gstqtvideosink/painters/videonode.h 2014-07-08 20:38:36.000000000 +0200 +++ b/elements/gstqtvideosink/painters/videonode.h 2018-05-05 02:56:22.000000000 +0200 @@ -45,6 +45,7 @@ public: private: MaterialType m_materialType; + bool m_validGeometry; }; #endif // VIDEONODE_H diff -Nrup a/examples/CMakeLists.txt b/examples/CMakeLists.txt --- a/examples/CMakeLists.txt 2014-07-08 20:38:36.000000000 +0200 +++ b/examples/CMakeLists.txt 2018-05-05 02:56:22.000000000 +0200 @@ -39,3 +39,6 @@ if (Qt4or5_Quick2_FOUND) add_subdirectory(qmlplayer2) example_distcheck(qmlplayer2) endif() + +add_subdirectory(devmon) +example_distcheck(devmon) diff -Nrup a/examples/devmon/CMakeLists.txt b/examples/devmon/CMakeLists.txt --- a/examples/devmon/CMakeLists.txt 1970-01-01 01:00:00.000000000 +0100 +++ b/examples/devmon/CMakeLists.txt 2018-05-05 02:56:22.000000000 +0200 @@ -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 -Nrup a/examples/devmon/devmon.pro b/examples/devmon/devmon.pro --- a/examples/devmon/devmon.pro 1970-01-01 01:00:00.000000000 +0100 +++ b/examples/devmon/devmon.pro 2018-05-05 02:56:22.000000000 +0200 @@ -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 -Nrup a/examples/devmon/main.cpp b/examples/devmon/main.cpp --- a/examples/devmon/main.cpp 1970-01-01 01:00:00.000000000 +0100 +++ b/examples/devmon/main.cpp 2018-05-05 02:56:22.000000000 +0200 @@ -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 -Nrup a/examples/devmon/mainwindow.cpp b/examples/devmon/mainwindow.cpp --- a/examples/devmon/mainwindow.cpp 1970-01-01 01:00:00.000000000 +0100 +++ b/examples/devmon/mainwindow.cpp 2018-05-05 02:56:22.000000000 +0200 @@ -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 -Nrup a/examples/devmon/mainwindow.h b/examples/devmon/mainwindow.h --- a/examples/devmon/mainwindow.h 1970-01-01 01:00:00.000000000 +0100 +++ b/examples/devmon/mainwindow.h 2018-05-05 02:56:22.000000000 +0200 @@ -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 -Nrup a/README b/README --- a/README 2014-07-08 20:38:36.000000000 +0200 +++ b/README 2018-05-05 02:56:22.000000000 +0200 @@ -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 -------- @@ -188,14 +215,15 @@ Mailing list: 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.com> -Last updated: Jun 24, 2014 +Last updated: May 5, 2018 diff -Nrup a/src/QGlib/connect.cpp b/src/QGlib/connect.cpp --- a/src/QGlib/connect.cpp 2014-07-08 20:38:36.000000000 +0200 +++ b/src/QGlib/connect.cpp 2018-05-05 02:56:22.000000000 +0200 @@ -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 { diff -Nrup a/src/QGst/CMakeLists.txt b/src/QGst/CMakeLists.txt --- a/src/QGst/CMakeLists.txt 2014-07-08 20:38:36.000000000 +0200 +++ b/src/QGst/CMakeLists.txt 2018-05-05 02:56:22.000000000 +0200 @@ -34,6 +34,8 @@ set(QtGStreamer_SRCS bufferlist.cpp discoverer.cpp segment.cpp + device.cpp + devicemonitor.cpp ${CMAKE_CURRENT_BINARY_DIR}/gen.cpp ) @@ -88,13 +90,15 @@ set(QtGStreamer_INSTALLED_HEADERS buffer.h Buffer sample.h Sample allocator.h Allocator - memory.h Memory + 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 @@ -140,7 +144,7 @@ set(QTGSTREAMER_QUICK_SOVERSION 0) set(QTGSTREAMER_UI_SOVERSION 0) set(QTGSTREAMER_UTILS_SOVERSION 0) include_directories( - ${GSTREAMER_INCLUDE_DIR} + ${GSTREAMER_INCLUDE_DIRS} ${GSTREAMER_AUDIO_INCLUDE_DIR} ${GSTREAMER_VIDEO_INCLUDE_DIR} ${GSTREAMER_BASE_INCLUDE_DIR} diff -Nrup a/src/QGst/Device b/src/QGst/Device --- a/src/QGst/Device 1970-01-01 01:00:00.000000000 +0100 +++ b/src/QGst/Device 2018-05-05 02:56:22.000000000 +0200 @@ -0,0 +1 @@ +#include "device.h" diff -Nrup a/src/QGst/device.cpp b/src/QGst/device.cpp --- a/src/QGst/device.cpp 1970-01-01 01:00:00.000000000 +0100 +++ b/src/QGst/device.cpp 2018-05-05 02:56:22.000000000 +0200 @@ -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 -Nrup a/src/QGst/device.h b/src/QGst/device.h --- a/src/QGst/device.h 1970-01-01 01:00:00.000000000 +0100 +++ b/src/QGst/device.h 2018-05-05 02:56:22.000000000 +0200 @@ -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 -Nrup a/src/QGst/DeviceMonitor b/src/QGst/DeviceMonitor --- a/src/QGst/DeviceMonitor 1970-01-01 01:00:00.000000000 +0100 +++ b/src/QGst/DeviceMonitor 2018-05-05 02:56:22.000000000 +0200 @@ -0,0 +1 @@ +#include "devicemonitor.h" diff -Nrup a/src/QGst/devicemonitor.cpp b/src/QGst/devicemonitor.cpp --- a/src/QGst/devicemonitor.cpp 1970-01-01 01:00:00.000000000 +0100 +++ b/src/QGst/devicemonitor.cpp 2018-05-05 02:56:22.000000000 +0200 @@ -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 -Nrup a/src/QGst/devicemonitor.h b/src/QGst/devicemonitor.h --- a/src/QGst/devicemonitor.h 1970-01-01 01:00:00.000000000 +0100 +++ b/src/QGst/devicemonitor.h 2018-05-05 02:56:22.000000000 +0200 @@ -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 -Nrup a/src/QGst/enums.h b/src/QGst/enums.h --- a/src/QGst/enums.h 2014-07-08 20:38:36.000000000 +0200 +++ b/src/QGst/enums.h 2018-05-05 02:56:22.000000000 +0200 @@ -193,6 +193,15 @@ namespace QGst { 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 }; } diff -Nrup a/src/QGst/gen.cpp b/src/QGst/gen.cpp --- a/src/QGst/gen.cpp 2014-07-08 20:38:36.000000000 +0200 +++ b/src/QGst/gen.cpp 2018-05-05 02:56:22.000000000 +0200 @@ -37,75 +37,14 @@ #include <gst/pbutils/gstdiscoverer.h> #include <gst/pbutils/pbutils-enumtypes.h> #include <QGlib/Quark> -#include "QGst/objectstore_p.h" - -#include "QGst/message.h" +#include "QGst/urihandler.h" -REGISTER_TYPE_IMPLEMENTATION(QGst::Message,GST_TYPE_MESSAGE) +REGISTER_TYPE_IMPLEMENTATION(QGst::UriHandler,GST_TYPE_URI_HANDLER) namespace QGst { - QGlib::RefCountedObject *Message_new(void *instance) + QGlib::RefCountedObject *UriHandler_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; - default: - cppClass = new QGst::Message; - break; - } + QGst::UriHandler *cppClass = new QGst::UriHandler; cppClass->m_object = instance; return cppClass; } @@ -124,199 +63,122 @@ namespace QGst { } } //namespace QGst -#include "QGst/videoorientation.h" +#include "QGst/parse.h" -REGISTER_TYPE_IMPLEMENTATION(QGst::VideoOrientation,GST_TYPE_VIDEO_ORIENTATION) +#include "QGst/clock.h" + +REGISTER_TYPE_IMPLEMENTATION(QGst::Clock,GST_TYPE_CLOCK) namespace QGst { - QGlib::RefCountedObject *VideoOrientation_new(void *instance) + QGlib::RefCountedObject *Clock_new(void *instance) { - QGst::VideoOrientation *cppClass = new QGst::VideoOrientation; + QGst::Clock *cppClass = new QGst::Clock; cppClass->m_object = instance; return cppClass; } } //namespace QGst -#include "QGst/structure.h" +#include "QGst/segment.h" -REGISTER_TYPE_IMPLEMENTATION(QGst::Structure,GST_TYPE_STRUCTURE) +REGISTER_TYPE_IMPLEMENTATION(QGst::Segment,GST_TYPE_SEGMENT) -#include "QGst/clock.h" +#include "QGst/videooverlay.h" -REGISTER_TYPE_IMPLEMENTATION(QGst::Clock,GST_TYPE_CLOCK) +REGISTER_TYPE_IMPLEMENTATION(QGst::VideoOverlay,GST_TYPE_VIDEO_OVERLAY) namespace QGst { - QGlib::RefCountedObject *Clock_new(void *instance) + QGlib::RefCountedObject *VideoOverlay_new(void *instance) { - QGst::Clock *cppClass = new QGst::Clock; + QGst::VideoOverlay *cppClass = new QGst::VideoOverlay; cppClass->m_object = instance; return cppClass; } } //namespace QGst -#include "QGst/childproxy.h" +#include "QGst/sample.h" -REGISTER_TYPE_IMPLEMENTATION(QGst::ChildProxy,GST_TYPE_CHILD_PROXY) +REGISTER_TYPE_IMPLEMENTATION(QGst::Sample,GST_TYPE_SAMPLE) namespace QGst { - QGlib::RefCountedObject *ChildProxy_new(void *instance) + QGlib::RefCountedObject *Sample_new(void *instance) { - QGst::ChildProxy *cppClass = new QGst::ChildProxy; + QGst::Sample *cppClass = new QGst::Sample; cppClass->m_object = instance; return cppClass; } } //namespace QGst -#include "QGst/query.h" +#include "QGst/message.h" -REGISTER_TYPE_IMPLEMENTATION(QGst::Query,GST_TYPE_QUERY) +REGISTER_TYPE_IMPLEMENTATION(QGst::Message,GST_TYPE_MESSAGE) namespace QGst { - QGlib::RefCountedObject *Query_new(void *instance) + QGlib::RefCountedObject *Message_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; + QGst::Message *cppClass = NULL; + switch(GST_MESSAGE_TYPE(instance)) { + case QGst::MessageEos: + cppClass = new QGst::EosMessage; break; - case QGst::QuerySegment: - cppClass = new QGst::SegmentQuery; + case QGst::MessageError: + cppClass = new QGst::ErrorMessage; break; - case QGst::QueryConvert: - cppClass = new QGst::ConvertQuery; + case QGst::MessageWarning: + cppClass = new QGst::WarningMessage; break; - case QGst::QueryFormats: - cppClass = new QGst::FormatsQuery; + case QGst::MessageInfo: + cppClass = new QGst::InfoMessage; break; - case QGst::QueryBuffering: - cppClass = new QGst::BufferingQuery; + case QGst::MessageTag: + cppClass = new QGst::TagMessage; break; - case QGst::QueryUri: - cppClass = new QGst::UriQuery; + case QGst::MessageBuffering: + cppClass = new QGst::BufferingMessage; break; - default: - cppClass = new QGst::Query; + case QGst::MessageStateChanged: + cppClass = new QGst::StateChangedMessage; break; - } - 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/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 - -#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/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/miniobject.h" - -#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; + case QGst::MessageStepDone: + cppClass = new QGst::StepDoneMessage; break; - case QGst::EventFlushStop: - cppClass = new QGst::FlushStopEvent; + case QGst::MessageStreamStatus: + cppClass = new QGst::StreamStatusMessage; break; - case QGst::EventEos: - cppClass = new QGst::EosEvent; + case QGst::MessageApplication: + cppClass = new QGst::ApplicationMessage; break; - case QGst::EventCaps: - cppClass = new QGst::CapsEvent; + case QGst::MessageElement: + cppClass = new QGst::ElementMessage; break; - case QGst::EventSegment: - cppClass = new QGst::SegmentEvent; + case QGst::MessageSegmentDone: + cppClass = new QGst::SegmentDoneMessage; break; - case QGst::EventTag: - cppClass = new QGst::TagEvent; + case QGst::MessageDurationChanged: + cppClass = new QGst::DurationChangedMessage; break; - case QGst::EventBufferSize: - cppClass = new QGst::BufferSizeEvent; + case QGst::MessageLatency: + cppClass = new QGst::LatencyMessage; break; - case QGst::EventSinkMessage: - cppClass = new QGst::SinkMessageEvent; + case QGst::MessageAsyncDone: + cppClass = new QGst::AsyncDoneMessage; break; - case QGst::EventQos: - cppClass = new QGst::QosEvent; + case QGst::MessageRequestState: + cppClass = new QGst::RequestStateMessage; break; - case QGst::EventSeek: - cppClass = new QGst::SeekEvent; + case QGst::MessageStepStart: + cppClass = new QGst::StepStartMessage; break; - case QGst::EventNavigation: - cppClass = new QGst::NavigationEvent; + case QGst::MessageQos: + cppClass = new QGst::QosMessage; break; - case QGst::EventLatency: - cppClass = new QGst::LatencyEvent; + case QGst::MessageDeviceAdded: + cppClass = new QGst::DeviceAddedMessage; break; - case QGst::EventStep: - cppClass = new QGst::StepEvent; + case QGst::MessageDeviceRemoved: + cppClass = new QGst::DeviceRemovedMessage; break; default: - cppClass = new QGst::Event; + cppClass = new QGst::Message; break; } cppClass->m_object = instance; @@ -324,153 +186,14 @@ namespace QGst { } } //namespace QGst -#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/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/taglist.h" - -REGISTER_TYPE_IMPLEMENTATION(QGst::TagList,GST_TYPE_TAG_LIST) - -#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/clocktime.h" - -REGISTER_TYPE_IMPLEMENTATION(QGst::ClockTime,GST_TYPE_CLOCK_TIME) - -#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/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/urihandler.h" +#include "QGst/bufferlist.h" -REGISTER_TYPE_IMPLEMENTATION(QGst::UriHandler,GST_TYPE_URI_HANDLER) +REGISTER_TYPE_IMPLEMENTATION(QGst::BufferList,GST_TYPE_BUFFER_LIST) namespace QGst { - QGlib::RefCountedObject *UriHandler_new(void *instance) + QGlib::RefCountedObject *BufferList_new(void *instance) { - QGst::UriHandler *cppClass = new QGst::UriHandler; + QGst::BufferList *cppClass = new QGst::BufferList; cppClass->m_object = instance; return cppClass; } @@ -663,6 +386,15 @@ namespace QGst { 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)); } @@ -878,7 +610,161 @@ namespace QGst { BOOST_STATIC_ASSERT(static_cast<int>(MemoryFlagLast) == static_cast<int>(GST_MEMORY_FLAG_LAST)); } -#include "QGst/parse.h" +#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" @@ -904,19 +790,21 @@ namespace QGst { } } //namespace QGst -#include "QGst/videooverlay.h" +#include "QGst/caps.h" -REGISTER_TYPE_IMPLEMENTATION(QGst::VideoOverlay,GST_TYPE_VIDEO_OVERLAY) +REGISTER_TYPE_IMPLEMENTATION(QGst::Caps,GST_TYPE_CAPS) namespace QGst { - QGlib::RefCountedObject *VideoOverlay_new(void *instance) + QGlib::RefCountedObject *Caps_new(void *instance) { - QGst::VideoOverlay *cppClass = new QGst::VideoOverlay; + 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) @@ -930,124 +818,288 @@ namespace QGst { } } //namespace QGst -#include "QGst/ghostpad.h" +#include "QGst/allocator.h" -REGISTER_TYPE_IMPLEMENTATION(QGst::GhostPad,GST_TYPE_GHOST_PAD) +REGISTER_TYPE_IMPLEMENTATION(QGst::Allocator,GST_TYPE_ALLOCATOR) namespace QGst { - QGlib::RefCountedObject *GhostPad_new(void *instance) + QGlib::RefCountedObject *Allocator_new(void *instance) { - QGst::GhostPad *cppClass = new QGst::GhostPad; + QGst::Allocator *cppClass = new QGst::Allocator; cppClass->m_object = instance; return cppClass; } } //namespace QGst -#include "QGst/elementfactory.h" +#include "QGst/devicemonitor.h" -REGISTER_TYPE_IMPLEMENTATION(QGst::ElementFactory,GST_TYPE_ELEMENT_FACTORY) +REGISTER_TYPE_IMPLEMENTATION(QGst::DeviceMonitor,GST_TYPE_DEVICE_MONITOR) namespace QGst { - QGlib::RefCountedObject *ElementFactory_new(void *instance) + QGlib::RefCountedObject *DeviceMonitor_new(void *instance) { - QGst::ElementFactory *cppClass = new QGst::ElementFactory; + QGst::DeviceMonitor *cppClass = new QGst::DeviceMonitor; cppClass->m_object = instance; return cppClass; } } //namespace QGst -#include "QGst/sample.h" +#include "QGst/device.h" -REGISTER_TYPE_IMPLEMENTATION(QGst::Sample,GST_TYPE_SAMPLE) +REGISTER_TYPE_IMPLEMENTATION(QGst::Device,GST_TYPE_DEVICE) namespace QGst { - QGlib::RefCountedObject *Sample_new(void *instance) + QGlib::RefCountedObject *Device_new(void *instance) { - QGst::Sample *cppClass = new QGst::Sample; + QGst::Device *cppClass = new QGst::Device; cppClass->m_object = instance; return cppClass; } } //namespace QGst -#include "QGst/bin.h" +#include "QGst/clocktime.h" -REGISTER_TYPE_IMPLEMENTATION(QGst::Bin,GST_TYPE_BIN) +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 *Bin_new(void *instance) + QGlib::RefCountedObject *Event_new(void *instance) { - QGst::Bin *cppClass = new QGst::Bin; + 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) -#include "QGst/segment.h" +REGISTER_TYPE_IMPLEMENTATION(QGst::DiscovererContainerInfo,GST_TYPE_DISCOVERER_CONTAINER_INFO) -REGISTER_TYPE_IMPLEMENTATION(QGst::Segment,GST_TYPE_SEGMENT) +REGISTER_TYPE_IMPLEMENTATION(QGst::DiscovererAudioInfo,GST_TYPE_DISCOVERER_AUDIO_INFO) -#include "QGst/bufferlist.h" +REGISTER_TYPE_IMPLEMENTATION(QGst::DiscovererVideoInfo,GST_TYPE_DISCOVERER_VIDEO_INFO) -REGISTER_TYPE_IMPLEMENTATION(QGst::BufferList,GST_TYPE_BUFFER_LIST) +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 *BufferList_new(void *instance) + QGlib::RefCountedObject *DiscovererStreamInfo_new(void *instance) { - QGst::BufferList *cppClass = new QGst::BufferList; + QGst::DiscovererStreamInfo *cppClass = new QGst::DiscovererStreamInfo; cppClass->m_object = instance; return cppClass; } } //namespace QGst -#include "QGst/object.h" +namespace QGst { + QGlib::RefCountedObject *DiscovererContainerInfo_new(void *instance) + { + QGst::DiscovererContainerInfo *cppClass = new QGst::DiscovererContainerInfo; + cppClass->m_object = instance; + return cppClass; + } +} //namespace QGst -REGISTER_TYPE_IMPLEMENTATION(QGst::Object,GST_TYPE_OBJECT) +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 *Object_new(void *instance) + QGlib::RefCountedObject *DiscovererVideoInfo_new(void *instance) { - QGst::Object *cppClass = new QGst::Object; + QGst::DiscovererVideoInfo *cppClass = new QGst::DiscovererVideoInfo; cppClass->m_object = instance; return cppClass; } } //namespace QGst -#include "QGst/bus.h" +namespace QGst { + QGlib::RefCountedObject *DiscovererSubtitleInfo_new(void *instance) + { + QGst::DiscovererSubtitleInfo *cppClass = new QGst::DiscovererSubtitleInfo; + cppClass->m_object = instance; + return cppClass; + } +} //namespace QGst -REGISTER_TYPE_IMPLEMENTATION(QGst::Bus,GST_TYPE_BUS) +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 *Bus_new(void *instance) + QGlib::RefCountedObject *Discoverer_new(void *instance) { - QGst::Bus *cppClass = new QGst::Bus; + QGst::Discoverer *cppClass = new QGst::Discoverer; cppClass->m_object = instance; return cppClass; } } //namespace QGst -#include "QGst/init.h" +#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<Message>().setQuarkData(q, reinterpret_cast<void*>(&Message_new)); + QGlib::GetType<UriHandler>().setQuarkData(q, reinterpret_cast<void*>(&UriHandler_new)); QGlib::GetType<Pad>().setQuarkData(q, reinterpret_cast<void*>(&Pad_new)); - QGlib::GetType<VideoOrientation>().setQuarkData(q, reinterpret_cast<void*>(&VideoOrientation_new)); QGlib::GetType<Clock>().setQuarkData(q, reinterpret_cast<void*>(&Clock_new)); - QGlib::GetType<ChildProxy>().setQuarkData(q, reinterpret_cast<void*>(&ChildProxy_new)); - QGlib::GetType<Query>().setQuarkData(q, reinterpret_cast<void*>(&Query_new)); - QGlib::GetType<Pipeline>().setQuarkData(q, reinterpret_cast<void*>(&Pipeline_new)); - QGlib::GetType<StreamVolume>().setQuarkData(q, reinterpret_cast<void*>(&StreamVolume_new)); - QGlib::GetType<Caps>().setQuarkData(q, reinterpret_cast<void*>(&Caps_new)); - QGlib::GetType<Event>().setQuarkData(q, reinterpret_cast<void*>(&Event_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<PluginFeature>().setQuarkData(q, reinterpret_cast<void*>(&PluginFeature_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)); @@ -1055,18 +1107,9 @@ namespace Private { 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<UriHandler>().setQuarkData(q, reinterpret_cast<void*>(&UriHandler_new)); - QGlib::GetType<ColorBalanceChannel>().setQuarkData(q, reinterpret_cast<void*>(&ColorBalanceChannel_new)); - QGlib::GetType<ColorBalance>().setQuarkData(q, reinterpret_cast<void*>(&ColorBalance_new)); - QGlib::GetType<VideoOverlay>().setQuarkData(q, reinterpret_cast<void*>(&VideoOverlay_new)); - QGlib::GetType<Buffer>().setQuarkData(q, reinterpret_cast<void*>(&Buffer_new)); - QGlib::GetType<GhostPad>().setQuarkData(q, reinterpret_cast<void*>(&GhostPad_new)); QGlib::GetType<ElementFactory>().setQuarkData(q, reinterpret_cast<void*>(&ElementFactory_new)); - QGlib::GetType<Sample>().setQuarkData(q, reinterpret_cast<void*>(&Sample_new)); - QGlib::GetType<Bin>().setQuarkData(q, reinterpret_cast<void*>(&Bin_new)); - QGlib::GetType<BufferList>().setQuarkData(q, reinterpret_cast<void*>(&BufferList_new)); - QGlib::GetType<Object>().setQuarkData(q, reinterpret_cast<void*>(&Object_new)); - QGlib::GetType<Bus>().setQuarkData(q, reinterpret_cast<void*>(&Bus_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 -Nrup a/src/QGst/global.h b/src/QGst/global.h --- a/src/QGst/global.h 2014-07-08 20:38:36.000000000 +0200 +++ b/src/QGst/global.h 2018-05-05 02:56:22.000000000 +0200 @@ -75,6 +75,8 @@ 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) @@ -104,6 +106,8 @@ QGST_WRAPPER_REFPOINTER_DECLARATION(Asyn 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) diff -Nrup a/src/QGst/Memory b/src/QGst/Memory --- a/src/QGst/Memory 2014-07-08 20:38:36.000000000 +0200 +++ b/src/QGst/Memory 1970-01-01 01:00:00.000000000 +0100 @@ -1,2 +0,0 @@ -#include "memory.h" - diff -Nrup a/src/QGst/memory.h b/src/QGst/memory.h --- a/src/QGst/memory.h 2014-07-08 20:38:36.000000000 +0200 +++ b/src/QGst/memory.h 2018-05-05 02:56:22.000000000 +0200 @@ -41,7 +41,7 @@ private: void *m_object; }; -/*! \headerfile memory.h <QGst/Memory> +/*! \headerfile memory.h <QGst/QGstMemory> * \brief Wrapper class for GstMemory * * GstMemory is a lightweight refcounted object that wraps a region diff -Nrup a/src/QGst/message.cpp b/src/QGst/message.cpp --- a/src/QGst/message.cpp 2014-07-08 20:38:36.000000000 +0200 +++ b/src/QGst/message.cpp 2018-05-05 02:56:22.000000000 +0200 @@ -348,7 +348,7 @@ void StreamStatusMessage::setStreamStatu 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); } @@ -356,7 +356,7 @@ ApplicationMessagePtr ApplicationMessage 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); } @@ -575,4 +575,34 @@ void QosMessage::setStats(Format format, 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 -Nrup a/src/QGst/message.h b/src/QGst/message.h --- a/src/QGst/message.h 2014-07-08 20:38:36.000000000 +0200 +++ b/src/QGst/message.h 2018-05-05 02:56:22.000000000 +0200 @@ -18,6 +18,7 @@ #define QGST_MESSAGE_H #include "clocktime.h" +#include "device.h" #include "miniobject.h" #include "structure.h" #include "taglist.h" @@ -205,7 +206,7 @@ class QTGSTREAMER_EXPORT ApplicationMess 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> @@ -216,7 +217,7 @@ class QTGSTREAMER_EXPORT ElementMessage 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) @@ -325,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) @@ -346,5 +371,7 @@ QGST_REGISTER_SUBCLASS(Message, AsyncDon 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 -Nrup a/src/QGst/pad.cpp b/src/QGst/pad.cpp --- a/src/QGst/pad.cpp 2014-07-08 20:38:36.000000000 +0200 +++ b/src/QGst/pad.cpp 2018-05-05 02:56:22.000000000 +0200 @@ -111,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 -Nrup a/src/QGst/QGstMemory b/src/QGst/QGstMemory --- a/src/QGst/QGstMemory 1970-01-01 01:00:00.000000000 +0100 +++ b/src/QGst/QGstMemory 2018-05-05 02:56:22.000000000 +0200 @@ -0,0 +1 @@ +#include "memory.h" diff -Nrup a/tests/auto/allocatortest.cpp b/tests/auto/allocatortest.cpp --- a/tests/auto/allocatortest.cpp 2014-07-08 20:38:36.000000000 +0200 +++ b/tests/auto/allocatortest.cpp 2018-05-05 02:56:22.000000000 +0200 @@ -18,7 +18,7 @@ #include "qgsttest.h" #include <QGlib/Error> #include <QGst/Allocator> -#include <QGst/Memory> +#include <QGst/QGstMemory> class AllocatorTest : public QGstTest { diff -Nrup a/tests/auto/buffertest.cpp b/tests/auto/buffertest.cpp --- a/tests/auto/buffertest.cpp 2014-07-08 20:38:36.000000000 +0200 +++ b/tests/auto/buffertest.cpp 2018-05-05 02:56:22.000000000 +0200 @@ -17,7 +17,7 @@ */ #include "qgsttest.h" #include <QGst/Buffer> -#include <QGst/Memory> +#include <QGst/QGstMemory> #include <QGst/Caps> class BufferTest : public QGstTest diff -Nrup a/tests/auto/CMakeLists.txt b/tests/auto/CMakeLists.txt --- a/tests/auto/CMakeLists.txt 2014-07-08 20:38:36.000000000 +0200 +++ b/tests/auto/CMakeLists.txt 2018-05-05 02:56:22.000000000 +0200 @@ -1,4 +1,4 @@ -include_directories(${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}") @@ -33,3 +33,12 @@ 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 -Nrup a/tests/auto/discoverertest.cpp b/tests/auto/discoverertest.cpp --- a/tests/auto/discoverertest.cpp 2014-07-08 20:38:36.000000000 +0200 +++ b/tests/auto/discoverertest.cpp 2018-05-05 02:56:22.000000000 +0200 @@ -391,9 +391,6 @@ void DiscovererTest::setupDiscoveryData( ->setSampleRate(48000)->setChannels(1)->setDepth(16) ->addTag("audio-codec", "FLAC") ->addTag("container-format", "Ogg")) - << StreamInfoPtr((new AudioStreamInfo("audio/x-flac")) - ->setSampleRate(48000)->setChannels(1) - ->setNative(false)) << StreamInfoPtr((new VideoStreamInfo("video/x-theora")) ->setWidth(160)->setHeight(120)->setInterlaced(false) ->setBitrate(200000)->setFramerate(QGst::Fraction(5, 1)) @@ -410,8 +407,10 @@ void DiscovererTest::setupDiscoveryData( << QGst::ClockTime(0) << Seekable << (StreamInfoList() << StreamInfoPtr((new VideoStreamInfo("image/png", VideoStreamInfo::ManualCaps)) - ->setWidth(160)->setHeight(120)->setInterlaced(false))) - << (TagList()); + ->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 diff -Nrup a/tests/auto/memorytest.cpp b/tests/auto/memorytest.cpp --- a/tests/auto/memorytest.cpp 2014-07-08 20:38:36.000000000 +0200 +++ b/tests/auto/memorytest.cpp 2018-05-05 02:56:22.000000000 +0200 @@ -17,7 +17,7 @@ #include "qgsttest.h" #include <QGlib/Error> -#include <QGst/Memory> +#include <QGst/QGstMemory> #include <QGst/Allocator> class MemoryTest : public QGstTest diff -Nrup a/tests/auto/qtquick2test.cpp b/tests/auto/qtquick2test.cpp --- a/tests/auto/qtquick2test.cpp 1970-01-01 01:00:00.000000000 +0100 +++ b/tests/auto/qtquick2test.cpp 2018-05-05 02:56:22.000000000 +0200 @@ -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 -Nrup a/tests/auto/refpointertest.cpp b/tests/auto/refpointertest.cpp --- a/tests/auto/refpointertest.cpp 2014-07-08 20:38:36.000000000 +0200 +++ b/tests/auto/refpointertest.cpp 2018-05-05 02:56:22.000000000 +0200 @@ -171,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->())); @@ -186,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 -Nrup a/tests/auto/taglisttest.cpp b/tests/auto/taglisttest.cpp --- a/tests/auto/taglisttest.cpp 2014-07-08 20:38:36.000000000 +0200 +++ b/tests/auto/taglisttest.cpp 2018-05-05 02:56:22.000000000 +0200 @@ -396,12 +396,15 @@ void TagListTest::sampleTest() QCOMPARE(structure4->name(), QString("files")); QCOMPARE(structure4->value("attachment").get<QString>(), QString("avalue")); + 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(sample3, QGst::TagMergeAppend); + tl.setImage(sample5, QGst::TagMergeAppend); QCOMPARE(tl.imageCount(), 2); tl.setAttachment(sample2, QGst::TagMergePrepend); - QCOMPARE(tl.attachmentCount(), 2); + QCOMPARE(tl.attachmentCount(), 1); } diff -Nrup a/tests/auto/videoitemtest.qml b/tests/auto/videoitemtest.qml --- a/tests/auto/videoitemtest.qml 1970-01-01 01:00:00.000000000 +0100 +++ b/tests/auto/videoitemtest.qml 2018-05-05 02:56:22.000000000 +0200 @@ -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 + } + } +}