[pitivi] pitivi: Start libpitivi and make use of it to handle viewer embedding
- From: Thibault Saunier <tsaunier src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pitivi] pitivi: Start libpitivi and make use of it to handle viewer embedding
- Date: Wed, 25 Feb 2015 11:34:34 +0000 (UTC)
commit 64704126662533bf270839859cf5921c4dc16017
Author: Thibault Saunier <tsaunier gnome org>
Date: Sat Feb 21 12:32:21 2015 +0100
pitivi: Start libpitivi and make use of it to handle viewer embedding
We currently need it to be able to cleanly work on mac as the GdkQuartz
API can not easily be exposed through GI.
This is currently for internal use only but in the long term that will
be used to expose Pitivi plugin API. We might end up having to gir
files, one called PitiviInternal and the otherone Pitivi at that point.
.gitignore | 6 +++
bin/pitivi-git-environment.sh | 2 +
configure.ac | 37 +++++++++++++++
pitivi/Makefile.am | 1 +
pitivi/libpitivi/Makefile.am | 62 +++++++++++++++++++++++++
pitivi/libpitivi/libpitivi.c | 20 ++++++++
pitivi/libpitivi/pitivi.h | 26 +++++++++++
pitivi/libpitivi/pitiviviewer.c | 95 +++++++++++++++++++++++++++++++++++++++
pitivi/libpitivi/pitiviviewer.h | 31 +++++++++++++
pitivi/mediafilespreviewer.py | 8 +---
pitivi/utils/pipeline.py | 10 ----
pitivi/viewer.py | 26 +++--------
12 files changed, 287 insertions(+), 37 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 03cb84c..5f6b5e8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -55,3 +55,9 @@ po/pitivi.pot
# Generated when running the project
*.pyc
+
+# libpitivi
+pitivi/libpitivi/.deps/*
+pitivi/libpitivi/.libs/*
+*.gir
+*.typelib
diff --git a/bin/pitivi-git-environment.sh b/bin/pitivi-git-environment.sh
index ebada89..b520165 100755
--- a/bin/pitivi-git-environment.sh
+++ b/bin/pitivi-git-environment.sh
@@ -65,6 +65,8 @@ else
fi
PYTHONPATH=$MYPITIVI/pitivi:$PYTHONPATH
+GI_TYPELIB_PATH=$MYPITIVI/pitivi/pitivi/libpitivi:$GI_TYPELIB_PATH
+LD_LIBRARY_PATH=$MYPITIVI/pitivi/pitivi/libpitivi/.libs:${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}
# The following decision has to be made before we've set any env variables,
# otherwise the script will detect our "gst uninstalled" and think it's the
diff --git a/configure.ac b/configure.ac
index 8961df2..ed70ff3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,3 +1,8 @@
+m4_define([gi_req_version], [1.31.1])
+m4_define([glib_req_version], [2.30.0])
+m4_define([gstreamer_req_version], [1.4.0])
+m4_define([gtk_req_version], [3.10.0])
+
AC_PREREQ(2.52)
dnl Note for packagers: see pitivi/check.py for the dependencies
@@ -75,6 +80,31 @@ AC_SUBST(CONFIGURED_GI_TYPELIB_PATH)
AC_CONFIG_FILES([bin/pitivi], [chmod +x bin/pitivi])
+dnl === GObject introspection =================================================
+
+GOBJECT_INTROSPECTION_CHECK([gi_req_version])
+
+PKG_CHECK_MODULES(GTK, [gtk+-3.0 >= gtk_req_version],
+ [HAVE_GTK=yes],
+ [HAVE_GTK=no])
+
+AS_IF([test "x$HAVE_GTK" = xno],
+ [AC_MSG_ERROR([GTK+ >= $gtk_req_version is required])])
+
+PKG_CHECK_MODULES(GTK_X11, gtk+-x11-3.0 >= gtk_req_version, HAVE_GTK_X11=yes, HAVE_GTK_X11=no)
+PKG_CHECK_MODULES(GTK_QUARTZ, gtk+-quartz-3.0 >= gtk_req_version, HAVE_GTK_QUARTZ=yes, HAVE_GTK_QUARTZ=no)
+AM_CONDITIONAL(HAVE_GTK_X11, test "x$HAVE_GTK_X11" = "xyes")
+AM_CONDITIONAL(HAVE_GTK_QUARTZ, test "x$HAVE_GTK_QUARTZ" = "xyes")
+
+PKG_CHECK_MODULES(GSTREAMER, [gstreamer-1.0 >= gstreamer_req_version gstreamer-video-1.0 >=
gstreamer_req_version],
+ [HAVE_GSTREAMER=yes],
+ [HAVE_GSTREAMER=no])
+AC_SUBST(GTK_LIBS)
+
+
+AS_IF([test "x$HAVE_GSTREAMER" = xno],
+ [AC_MSG_ERROR([GStreamer >= $gstreamer_req_version is required])])
+
PKG_CHECK_MODULES([cairo], [cairo])
PKG_CHECK_MODULES([py3cairo], [py3cairo])
@@ -94,6 +124,12 @@ if test x$BUILD_HELP = xyes; then
YELP_HELP_INIT
fi
+PITIVI_CFLAGS="$GTK_CFLAGS $GSTREAMER_CFLAGS $GSTREAMER_VIDEO_CFLAGS"
+PITIVI_LIBS="$LIBM $GTK_LIBS $GSTREAMER_LIBS $GSTREAMER_VIDEO_CFLAGS"
+
+AC_SUBST(PITIVI_CFLAGS)
+AC_SUBST(PITIVI_LIBS)
+
dnl output stuff
AC_OUTPUT(
Makefile
@@ -107,6 +143,7 @@ pitivi/dialogs/Makefile
pitivi/undo/Makefile
pitivi/utils/Makefile
pitivi/timeline/Makefile
+pitivi/libpitivi/Makefile
pitivi/coptimizations/Makefile
po/Makefile.in
tests/Makefile
diff --git a/pitivi/Makefile.am b/pitivi/Makefile.am
index ce2cc38..a817fa2 100644
--- a/pitivi/Makefile.am
+++ b/pitivi/Makefile.am
@@ -1,5 +1,6 @@
SUBDIRS = \
coptimizations \
+ libpitivi \
dialogs \
utils \
timeline \
diff --git a/pitivi/libpitivi/Makefile.am b/pitivi/libpitivi/Makefile.am
new file mode 100644
index 0000000..4e2e0fd
--- /dev/null
+++ b/pitivi/libpitivi/Makefile.am
@@ -0,0 +1,62 @@
+CLEANFILES =
+
+if HAVE_GTK_QUARTZ
+ AM_CPPFLAGS = '-xobjective-c'
+endif
+
+source_h = \
+ pitiviviewer.h \
+ pitivi.h
+
+source_c = \
+ pitiviviewer.c
+
+noinst_HEADERS = $(source_h)
+
+libpitivi_1_0_la_CFLAGS = $(AM_CFLAGS) $(PITIVI_CFLAGS)
+libpitivi_1_0_la_LIBADD = $(shared_libadd) $(PITIVI_LIBS)
+libpitivi_1_0_la_LDFLAGS = -module -avoid-version $(LIBS)
+libpitivi_1_0_la_SOURCES = $(source_c)
+
+lib_LTLIBRARIES = libpitivi-1.0.la
+
+INTROSPECTION_GIRS = Pitivi-1.0.gir
+
+introspection_source_h = $(source_h)
+introspection_source_c = $(source_c)
+Pitivi-1.0.gir: $(INTROSPECTION_SCANNER) libpitivi-1.0.la
+ $(INTROSPECTION_SCANNER) -v --namespace Pitivi \
+ --nsversion=1.0 \
+ --identifier-prefix=Pitivi \
+ --symbol-prefix=pitivi \
+ -DIN_GOBJECT_INTROSPECTION=1 \
+ --library=libpitivi-1.0.la \
+ --include=GLib-2.0 \
+ --include=GObject-2.0 \
+ --include=Gst-1.0 \
+ --include=GstVideo-1.0 \
+ --include=Gtk-3.0 \
+ --libtool="${LIBTOOL}" \
+ --pkg glib-2.0 \
+ --pkg gobject-2.0 \
+ --pkg gstreamer-1.0 \
+ --pkg gtk+-3.0 \
+ --output $@ \
+ $(introspection_source_h) \
+ $(introspection_source_c)
+
+girdir = $(datadir)/gir-1.0
+nodist_gir_DATA = $(INTROSPECTION_GIRS)
+CLEANFILES += $(nodist_gir_DATA)
+
+typelibdir = $(libdir)/girepository-1.0
+nodist_typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib)
+CLEANFILES += $(nodist_typelib_DATA)
+
+%.typelib: %.gir $(INTROSPECTION_COMPILER)
+ $(AM_V_GEN)$(INTROSPECTION_COMPILER) \
+ --includedir='/home/thiblahute/devel/pitivi/1.0-uninstalled/pitivi/pitivi/libpitivi' \
+ --includedir=`$(PKG_CONFIG) --variable=girdir gstreamer-1.0` \
+ --includedir=`$(PKG_CONFIG) --variable=girdir gstreamer-video-1.0` \
+ --includedir=`$(PKG_CONFIG) --variable=girdir gtk+-3.0` \
+ $(INTROSPECTION_COMPILER_OPTS) $< -o $(@F)
diff --git a/pitivi/libpitivi/libpitivi.c b/pitivi/libpitivi/libpitivi.c
new file mode 100644
index 0000000..92f6356
--- /dev/null
+++ b/pitivi/libpitivi/libpitivi.c
@@ -0,0 +1,20 @@
+/* Pitivi
+ *
+ *
+ * Copyright (C) 2015 Thibault Saunier <tsaunier gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
diff --git a/pitivi/libpitivi/pitivi.h b/pitivi/libpitivi/pitivi.h
new file mode 100644
index 0000000..a092eed
--- /dev/null
+++ b/pitivi/libpitivi/pitivi.h
@@ -0,0 +1,26 @@
+/* Pitivi
+ *
+ * Copyright (C) 2015 Thibault Saunier <tsaunier gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __PITIVI_H__
+#define __PITIVI_H__
+
+#include "pitiviviewer.h"
+
+#endif /* __PITIVI_H__ */
diff --git a/pitivi/libpitivi/pitiviviewer.c b/pitivi/libpitivi/pitiviviewer.c
new file mode 100644
index 0000000..1e920ee
--- /dev/null
+++ b/pitivi/libpitivi/pitiviviewer.c
@@ -0,0 +1,95 @@
+/* Pitivi
+ *
+ * Copyright (C) 2015 Thibault Saunier <tsaunier gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pitiviviewer.h"
+
+#include <gdk/gdk.h>
+#if defined (GDK_WINDOWING_X11)
+#include <gdk/gdkx.h>
+#elif defined (GDK_WINDOWING_WIN32)
+#include <gdk/gdkwin32.h>
+#elif defined (GDK_WINDOWING_QUARTZ)
+#include <gdk/gdkquartz.h>
+#endif
+
+
+static guintptr
+get_window_handle (GtkWidget * widget)
+{
+ guintptr embed_xid;
+
+ GdkWindow *window = gtk_widget_get_window (widget);
+
+ g_return_val_if_fail (gdk_window_ensure_native (window), FALSE);
+
+#if defined (GDK_WINDOWING_WIN32)
+ embed_xid = (guintptr) GDK_WINDOW_HWND (window);
+#elif defined (GDK_WINDOWING_QUARTZ)
+ embed_xid = (guintptr) gdk_quartz_window_get_nsview (window);
+#elif defined (GDK_WINDOWING_X11)
+ embed_xid = GDK_WINDOW_XID (window);
+#endif
+
+ return embed_xid;
+}
+
+static void
+realize_cb (GtkWidget * widget, GstElement * videosink)
+{
+ gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (videosink),
+ get_window_handle (widget));
+
+ g_signal_handlers_disconnect_by_func (widget, realize_cb, videosink);
+}
+
+/**
+ * pitivi_viewer_new:
+ * @videosink: (transfer none) (allow-none): the sink
+ *
+ * Returns: (transfer full): The new GtkDrawing area ready to be used
+ */
+GtkWidget *
+pitivi_viewer_new (GstElement * videosink)
+{
+ GtkWidget *res = gtk_drawing_area_new ();
+
+ if (videosink)
+ pitivi_viewer_set_sink (res, videosink);
+
+ return res;
+}
+
+gboolean
+pitivi_viewer_set_sink (GtkWidget * widget, GstElement * videosink)
+{
+ if (gtk_widget_get_realized (widget)) {
+ gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (videosink),
+ get_window_handle (widget));
+ return TRUE;
+ }
+
+ g_signal_connect (widget, "realize", G_CALLBACK (realize_cb), videosink);
+
+ return FALSE;
+}
diff --git a/pitivi/libpitivi/pitiviviewer.h b/pitivi/libpitivi/pitiviviewer.h
new file mode 100644
index 0000000..fd9853f
--- /dev/null
+++ b/pitivi/libpitivi/pitiviviewer.h
@@ -0,0 +1,31 @@
+/* Pitivi
+ *
+ * Copyright (C) 2015 Thibault Saunier <tsaunier gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __PITIVI_VIEWER_H__
+#define __PITIVI_VIEWER_H__
+
+#include <gst/gst.h>
+#include <gst/video/videooverlay.h>
+#include <gtk/gtk.h>
+
+GtkWidget *pitivi_viewer_new (GstElement *videosink);
+gboolean pitivi_viewer_set_sink (GtkWidget * widget, GstElement * videosink);
+
+#endif /* __PITIVI_VIEWER_H__ */
diff --git a/pitivi/mediafilespreviewer.py b/pitivi/mediafilespreviewer.py
index d72c00f..b828590 100644
--- a/pitivi/mediafilespreviewer.py
+++ b/pitivi/mediafilespreviewer.py
@@ -108,9 +108,7 @@ class PreviewWidget(Gtk.Grid, Loggable):
# Gui elements:
# Drawing area for video output
- self.preview_video = ViewerWidget(
- realizedCb=self._on_preview_video_realize_cb)
- self.preview_video.sink = self.player.video_sink
+ self.preview_video = ViewerWidget(sink=self.player.video_sink)
self.preview_video.props.hexpand = minimal
self.preview_video.props.vexpand = minimal
self.attach(self.preview_video, 0, 0, 1, 1)
@@ -368,10 +366,6 @@ class PreviewWidget(Gtk.Grid, Loggable):
self.pos_adj.set_value(int(curr_pos))
return self.is_playing
- def _on_preview_video_realize_cb(self, unused_drawing_area, unused_widget):
- if self.current_preview_type == 'video':
- self.player.connectWithViewer(self.preview_video)
-
def _on_start_stop_clicked_cb(self, button):
if self.is_playing:
self.pause()
diff --git a/pitivi/utils/pipeline.py b/pitivi/utils/pipeline.py
index 9602d3b..300636a 100644
--- a/pitivi/utils/pipeline.py
+++ b/pitivi/utils/pipeline.py
@@ -194,8 +194,6 @@ class SimplePipeline(GObject.Object, Loggable):
self._timeout_async_id = 0
self._force_position_listener = False
- # Create a cluttersink element used for display. Subclasses must connect
- # it to self._pipeline themselves
self.video_sink = Gst.ElementFactory.make("glimagesink", None)
if isinstance(pipeline, GES.Pipeline):
self._pipeline.preview_set_video_sink(self.video_sink)
@@ -574,14 +572,6 @@ class AssetPipeline(SimplePipeline):
def setClipUri(self, uri):
self._pipeline.set_property("uri", uri)
- def connectWithViewer(self, widget):
- if platform.system() == 'Windows':
- handle = widget.drawing_area.get_window().get_handle()
- else:
- handle = widget.drawing_area.get_window().get_xid()
-
- self.video_sink.set_window_handle(handle)
-
class Pipeline(GES.Pipeline, SimplePipeline):
diff --git a/pitivi/viewer.py b/pitivi/viewer.py
index a285f29..ff2a40b 100644
--- a/pitivi/viewer.py
+++ b/pitivi/viewer.py
@@ -23,14 +23,10 @@ from gi.repository import Clutter
from gi.repository import Gtk
from gi.repository import GtkClutter
from gi.repository import Gdk
-try:
- from gi.repository import GdkX11
-except ImportError:
-
- pass
from gi.repository import Gst
from gi.repository import GObject
from gi.repository import GES
+from gi.repository import Pitivi
import cairo
from gettext import gettext as _
@@ -492,19 +488,9 @@ class ViewerContainer(Gtk.Box, Loggable):
if self.pipeline is None:
return
- if self.target.get_realized():
- self.debug("Connecting the pipeline to the viewer's texture")
- if platform.system() == 'Windows':
- xid = self.target.drawing_area.get_window().get_handle()
- else:
- xid = self.target.drawing_area.get_window().get_xid()
-
- self.sink.set_window_handle(xid)
+ self.target.show()
+ if Pitivi.viewer_set_sink(self.target.drawing_area, self.sink):
self.sink.expose()
- else:
- # Show the widget and wait for the realized callback
- self.log("Target is not realized, showing the widget")
- self.target.show()
class Point():
@@ -840,14 +826,14 @@ class ViewerWidget(Gtk.AspectFrame, Loggable):
__gsignals__ = {}
- def __init__(self, settings=None, realizedCb=None):
+ def __init__(self, settings=None, realizedCb=None, sink=None):
# Prevent black frames and flickering while resizing or changing focus:
# The aspect ratio gets overridden by setDisplayAspectRatio.
Gtk.AspectFrame.__init__(self, xalign=0.5, yalign=0.5,
ratio=4.0 / 3.0, obey_child=False)
Loggable.__init__(self)
- self.drawing_area = Gtk.DrawingArea()
+ self.drawing_area = Pitivi.viewer_new(sink)
self.drawing_area.set_double_buffered(False)
self.drawing_area.connect("draw", self._drawCb, None)
# We keep the ViewerWidget hidden initially, or the desktop wallpaper
@@ -864,7 +850,7 @@ class ViewerWidget(Gtk.AspectFrame, Loggable):
self.stored = False
self.area = None
self.zoom = 1.0
- self.sink = None
+ self.sink = sink
self.pixbuf = None
self.pipeline = None
self.transformation_properties = None
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]