[pitivi] effects: Move checking if GL effects work in a dedicated subprocess



commit ba3c0db74ca2bd326563c1e6952b9fd53279bb9c
Author: Thibault Saunier <tsaunier igalia com>
Date:   Sat Apr 27 20:04:15 2019 -0400

    effects: Move checking if GL effects work in a dedicated subprocess
    
    Bad thing can happen when trying to run the pipeline and we do not want it to affect the main process

 pitivi/effects.py              | 40 +++++++++---------------
 pitivi/utils/check_pipeline.py | 69 ++++++++++++++++++++++++++++++++++++++++++
 pre-commit.hook                |  2 +-
 3 files changed, 85 insertions(+), 26 deletions(-)
---
diff --git a/pitivi/effects.py b/pitivi/effects.py
index c80eeb44..ee8fc645 100644
--- a/pitivi/effects.py
+++ b/pitivi/effects.py
@@ -30,6 +30,9 @@
 """
 import os
 import re
+import subprocess
+import sys
+import threading
 from gettext import gettext as _
 
 from gi.repository import Gdk
@@ -284,32 +287,19 @@ class EffectsManager(Loggable):
         self.gl_effects = [element_factory.get_name()
                            for element_factory in gl_element_factories]
         if self.gl_effects:
-            # Checking whether the GL effects can be used
-            # by setting a pipeline with "gleffects" to PAUSED.
-            pipeline = Gst.parse_launch("videotestsrc ! glupload ! gleffects ! fakesink")
-            bus = pipeline.get_bus()
-            bus.add_signal_watch()
-            bus.connect("message", self._gl_pipeline_message_cb, pipeline)
-            res = pipeline.set_state(Gst.State.PAUSED)
-            assert res == Gst.StateChangeReturn.ASYNC
-
-    def _gl_pipeline_message_cb(self, bus, message, pipeline):
-        """Handles a `message` event on the pipeline for checking gl effects."""
-        done = False
-        if message.type == Gst.MessageType.ASYNC_DONE:
-            self.debug("GL effects check pipeline successfully PAUSED")
-            done = True
-        elif message.type == Gst.MessageType.ERROR:
-            # The pipeline cannot be set to PAUSED.
-            error, detail = message.parse_error()
-            self.debug("Hiding the GL effects because: %s, %s", error, detail)
-            HIDDEN_EFFECTS.extend(self.gl_effects)
-            done = True
+            thread = threading.Thread(target=self._check_gleffects)
+            thread.start()
 
-        if done:
-            bus.remove_signal_watch()
-            bus.disconnect_by_func(self._gl_pipeline_message_cb)
-            pipeline.set_state(Gst.State.NULL)
+    def _check_gleffects(self):
+        try:
+            res = subprocess.check_output([sys.executable,
+                os.path.join(os.path.dirname(__file__), "utils",
+                "check_pipeline.py"),
+                "videotestsrc ! glupload ! gleffects ! fakesink"])
+            self.debug(res)
+        except subprocess.CalledProcessError as e:
+            self.error("Can not use GL effects: %s", e)
+            HIDDEN_EFFECTS.extend(self.gl_effects)
 
     def getInfo(self, bin_description):
         """Gets the info for an effect which can be applied.
diff --git a/pitivi/utils/check_pipeline.py b/pitivi/utils/check_pipeline.py
new file mode 100644
index 00000000..1ada1d62
--- /dev/null
+++ b/pitivi/utils/check_pipeline.py
@@ -0,0 +1,69 @@
+# -*- coding: utf-8 -*-
+# Pitivi video editor
+# Copyright (c) 2019, Thibault Saunier <tsaunier igalia com>
+#
+# This program 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, write to the
+# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+"""
+Simple app to check if a GStreamer pipeline can run.
+"""
+import os
+import sys
+
+import gi
+
+gi.require_version("Gst", "1.0")
+
+from gi.repository import Gst  # pylint: disable-msg=wrong-import-position
+from gi.repository import GLib  # pylint: disable-msg=wrong-import-position
+
+
+def pipeline_message_cb(_, msg, pipeline):
+    """GStreamer bus message handler."""
+    if msg.type == Gst.MessageType.ASYNC_DONE:
+        print("pipeline successfully PAUSED")
+        pipeline.set_state(Gst.State.NULL)
+        sys.exit(0)
+    elif msg.type == Gst.MessageType.ERROR:
+        # The pipeline cannot be set to PAUSED.
+        error, detail = msg.parse_error()
+        print("Pipeline failed: %s, %s" % (error, detail), file=sys.stderr)
+        pipeline.set_state(Gst.State.NULL)
+        sys.exit(1)
+
+
+def timeout_cb(*args, **kwargs):
+    """Exit on timeout."""
+    print("Pipeline timed out", file=sys.stderr)
+    sys.exit(1)
+
+
+def main():
+    """Main function of the small app."""
+    os.environ["G_DEBUG"] = "fatal-criticals"
+    Gst.init(None)
+    pipeline = Gst.parse_launch(sys.argv[1])
+    bus = pipeline.get_bus()
+    bus.add_signal_watch()
+    bus.connect("message", pipeline_message_cb, pipeline)
+    res = pipeline.set_state(Gst.State.PAUSED)
+    assert res == Gst.StateChangeReturn.ASYNC
+
+    GLib.timeout_add_seconds(10, timeout_cb)
+    GLib.MainLoop.new(None, True).run()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/pre-commit.hook b/pre-commit.hook
index dcfcef62..8ad50c33 100755
--- a/pre-commit.hook
+++ b/pre-commit.hook
@@ -85,6 +85,6 @@ export PYTHONPATH=$TOPLEVEL/pitivi/coptimizations/.libs:$PYTHONPATH
 
 git-pylint-commit-hook --pylint="$TOPLEVEL/build/flatpak/pitivi-flatpak" --pylint-params="pylint" 
--pylintrc=$RCFILE $IGNORE_ARGS --limit=10.0 --suppress-report || exit 1
 
-git_pep8_commit_hook --pep8-params="--repeat --ignore=E501,E128" || exit 1
+git_pep8_commit_hook --pep8-params="--repeat --ignore=E501,E128,E402" || exit 1
 
 pre-commit run --config .pre-commit-config.yaml || exit 1


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]