playback/player: qt: emit player signals from Qt event loop
authorAlexandre Moreno <alexmorenocano@gmail.com>
Tue, 6 Oct 2015 15:19:03 +0000 (23:19 +0800)
committerSebastian Dröge <sebastian@centricular.com>
Tue, 6 Oct 2015 15:40:27 +0000 (16:40 +0100)
playback/player/qt/qgstplayer.cpp
playback/player/qt/qgstplayer.h

index c2fb3fb..c2c0ee0 100644 (file)
@@ -21,8 +21,9 @@
 #include "qgstplayer.h"
 #include <QDebug>
 #include <QSize>
-
 #include <QMetaObject>
+#include <functional>
+#include <QThread>
 
 class QGstPlayerRegisterMetaTypes
 {
@@ -86,7 +87,8 @@ QGstPlayer::QGstPlayer(QObject *parent, QGstPlayer::VideoRenderer *renderer)
     , videoAvailable_(false)
 {
 
-    player_ = gst_player_new_full(renderer ? renderer->renderer() : 0, 0);
+    player_ = gst_player_new_full(renderer ? renderer->renderer() : 0,
+        gst_player_qt_signal_dispatcher_new(this));
 
     g_object_connect(player_,
         "swapped-signal::state-changed", G_CALLBACK (QGstPlayer::onStateChanged), this,
@@ -354,7 +356,6 @@ gst_player_qt_video_renderer_set_property (GObject * object,
 
   switch (prop_id) {
     case QT_VIDEO_RENDERER_PROP_RENDERER:
-      qDebug() << "setting renderer";
       self->renderer = g_value_get_pointer (value);
       break;
     default:
@@ -433,3 +434,140 @@ gst_player_qt_video_renderer_interface_init
 {
   iface->create_video_sink = gst_player_qt_video_renderer_create_video_sink;
 }
+
+struct _GstPlayerQtSignalDispatcher
+{
+  GObject parent;
+
+  gpointer player;
+};
+
+struct _GstPlayerQtSignalDispatcherClass
+{
+  GObjectClass parent_class;
+};
+
+static void
+gst_player_qt_signal_dispatcher_interface_init
+    (GstPlayerSignalDispatcherInterface * iface);
+
+enum
+{
+  QT_SIGNAL_DISPATCHER_PROP_0,
+  QT_SIGNAL_DISPATCHER_PROP_PLAYER,
+  QT_SIGNAL_DISPATCHER_PROP_LAST
+};
+
+G_DEFINE_TYPE_WITH_CODE (GstPlayerQtSignalDispatcher,
+    gst_player_qt_signal_dispatcher, G_TYPE_OBJECT,
+    G_IMPLEMENT_INTERFACE (GST_TYPE_PLAYER_SIGNAL_DISPATCHER,
+        gst_player_qt_signal_dispatcher_interface_init));
+
+static GParamSpec
+* qt_signal_dispatcher_param_specs
+[QT_SIGNAL_DISPATCHER_PROP_LAST] = { NULL, };
+
+static void
+gst_player_qt_signal_dispatcher_finalize (GObject * object)
+{
+  GstPlayerQtSignalDispatcher *self =
+      GST_PLAYER_QT_SIGNAL_DISPATCHER (object);
+
+  G_OBJECT_CLASS
+      (gst_player_qt_signal_dispatcher_parent_class)->finalize
+      (object);
+}
+
+static void
+gst_player_qt_signal_dispatcher_set_property (GObject * object,
+    guint prop_id, const GValue * value, GParamSpec * pspec)
+{
+  GstPlayerQtSignalDispatcher *self =
+      GST_PLAYER_QT_SIGNAL_DISPATCHER (object);
+
+  switch (prop_id) {
+    case QT_SIGNAL_DISPATCHER_PROP_PLAYER:
+      self->player = g_value_get_pointer (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_player_qt_signal_dispatcher_get_property (GObject * object,
+    guint prop_id, GValue * value, GParamSpec * pspec)
+{
+  GstPlayerQtSignalDispatcher *self =
+      GST_PLAYER_QT_SIGNAL_DISPATCHER (object);
+
+  switch (prop_id) {
+    case QT_SIGNAL_DISPATCHER_PROP_PLAYER:
+      g_value_set_pointer (value, self->player);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+    gst_player_qt_signal_dispatcher_class_init
+    (GstPlayerQtSignalDispatcherClass * klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+  gobject_class->finalize =
+      gst_player_qt_signal_dispatcher_finalize;
+  gobject_class->set_property =
+      gst_player_qt_signal_dispatcher_set_property;
+  gobject_class->get_property =
+      gst_player_qt_signal_dispatcher_get_property;
+
+  qt_signal_dispatcher_param_specs
+      [QT_SIGNAL_DISPATCHER_PROP_PLAYER] =
+      g_param_spec_pointer ("player", "QGstPlayer instance", "",
+      static_cast<GParamFlags>(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_properties (gobject_class,
+      QT_SIGNAL_DISPATCHER_PROP_LAST,
+      qt_signal_dispatcher_param_specs);
+}
+
+static void
+gst_player_qt_signal_dispatcher_init
+    (GstPlayerQtSignalDispatcher * self)
+{
+
+}
+
+static void
+gst_player_qt_signal_dispatcher_dispatch (GstPlayerSignalDispatcher
+    * iface, GstPlayer * player, void (*emitter) (gpointer data), gpointer data,
+    GDestroyNotify destroy)
+{
+  GstPlayerQtSignalDispatcher *self = GST_PLAYER_QT_SIGNAL_DISPATCHER (iface);
+  QObject dispatch;
+  QObject *receiver = static_cast<QObject*>(self->player);
+
+  QObject::connect(&dispatch, &QObject::destroyed, receiver, [=]() {
+    emitter(data);
+    if (destroy) destroy(data);
+  }, Qt::QueuedConnection);
+}
+
+static void
+gst_player_qt_signal_dispatcher_interface_init
+(GstPlayerSignalDispatcherInterface * iface)
+{
+  iface->dispatch = gst_player_qt_signal_dispatcher_dispatch;
+}
+
+GstPlayerSignalDispatcher *
+gst_player_qt_signal_dispatcher_new (gpointer player)
+{
+  return static_cast<GstPlayerSignalDispatcher*>
+  (g_object_new (GST_TYPE_PLAYER_QT_SIGNAL_DISPATCHER,
+      "player", player, NULL));
+}
index aeb45a5..c0c39d0 100644 (file)
@@ -136,7 +136,10 @@ private:
     bool videoAvailable_;
 };
 
-G_BEGIN_DECLS
+Q_DECLARE_METATYPE(QGstPlayer*)
+Q_DECLARE_METATYPE(QGstPlayer::State)
+
+extern "C" {
 
 typedef struct _GstPlayerQtVideoRenderer
     GstPlayerQtVideoRenderer;
@@ -154,9 +157,25 @@ typedef struct _GstPlayerQtVideoRendererClass
 
 GType gst_player_qt_video_renderer_get_type (void);
 
-G_END_DECLS
+typedef struct _GstPlayerQtSignalDispatcher
+    GstPlayerQtSignalDispatcher;
 
-Q_DECLARE_METATYPE(QGstPlayer*)
-Q_DECLARE_METATYPE(QGstPlayer::State)
+typedef struct _GstPlayerQtSignalDispatcherClass
+    GstPlayerQtSignalDispatcherClass;
+
+#define GST_TYPE_PLAYER_QT_SIGNAL_DISPATCHER             (gst_player_qt_signal_dispatcher_get_type ())
+#define GST_IS_PLAYER_QT_SIGNAL_DISPATCHER(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_PLAYER_QT_SIGNAL_DISPATCHER))
+#define GST_IS_PLAYER_QT_SIGNAL_DISPATCHER_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_PLAYER_QT_SIGNAL_DISPATCHER))
+#define GST_PLAYER_QT_SIGNAL_DISPATCHER_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_PLAYER_QT_SIGNAL_DISPATCHER, GstPlayerQtSignalDispatcherClass))
+#define GST_PLAYER_QT_SIGNAL_DISPATCHER(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_PLAYER_QT_SIGNAL_DISPATCHER, GstPlayerQtSignalDispatcher))
+#define GST_PLAYER_QT_SIGNAL_DISPATCHER_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_PLAYER_QT_SIGNAL_DISPATCHER, GstPlayerQtSignalDispatcherClass))
+#define GST_PLAYER_QT_SIGNAL_DISPATCHER_CAST(obj)        ((GstPlayerQtSignalDispatcher*)(obj))
+
+GType gst_player_qt_video_renderer_get_type (void);
+
+GstPlayerSignalDispatcher *
+gst_player_qt_signal_dispatcher_new (gpointer player);
+
+}
 
 #endif // QGSTPLAYER_H