[pitivi] previewers: Do not block the mainloop waiting on GStreamer to start processing
- From: Thibault Saunier <tsaunier src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pitivi] previewers: Do not block the mainloop waiting on GStreamer to start processing
- Date: Fri, 18 Aug 2017 01:34:28 +0000 (UTC)
commit fae83dcd4944f19f7a90a1a53d28b0756abfdfb5
Author: Thibault Saunier <tsaunier gnome org>
Date: Wed Aug 16 21:22:25 2017 -0300
previewers: Do not block the mainloop waiting on GStreamer to start processing
This is plain wrong and we should handle state changes to PAUSED
asynchronously.
Reviewed-by: Alex Băluț <<alexandru balut gmail com>>
Differential Revision: https://phabricator.freedesktop.org/D1844
pitivi/timeline/previewers.py | 45 +++++++++++++++++++---------------------
1 files changed, 21 insertions(+), 24 deletions(-)
---
diff --git a/pitivi/timeline/previewers.py b/pitivi/timeline/previewers.py
index 331adad..5f99e16 100644
--- a/pitivi/timeline/previewers.py
+++ b/pitivi/timeline/previewers.py
@@ -42,6 +42,7 @@ from pitivi.utils.misc import hash_file
from pitivi.utils.misc import path_from_uri
from pitivi.utils.misc import quantize
from pitivi.utils.misc import quote_uri
+from pitivi.utils.pipeline import MAX_BRINGING_TO_PAUSED_DURATION
from pitivi.utils.system import CPUUsageTracker
from pitivi.utils.timeline import Zoomable
from pitivi.utils.ui import EXPANDED_SIZE
@@ -417,6 +418,8 @@ class VideoPreviewer(Previewer, Zoomable, Loggable):
# Guard against malformed URIs
self.uri = quote_uri(get_proxy_target(ges_elem).props.id)
+ self.__preroll_timeout_id = 0
+
# Variables related to thumbnailing
self.wishlist = []
self.queue = []
@@ -469,34 +472,15 @@ class VideoPreviewer(Previewer, Zoomable, Loggable):
# get the gdkpixbufsink and the sinkpad
self.gdkpixbufsink = self.pipeline.get_by_name("gdkpixbufsink")
- sinkpad = self.gdkpixbufsink.get_static_pad("sink")
-
- self.pipeline.set_state(Gst.State.PAUSED)
-
- # Wait for the pipeline to be prerolled so we can check the width
- # that the thumbnails will have and set the aspect ratio accordingly
- # as well as getting the framerate of the video:
- change_return = self.pipeline.get_state(Gst.CLOCK_TIME_NONE)
- if Gst.StateChangeReturn.SUCCESS == change_return[0]:
- neg_caps = sinkpad.get_current_caps()[0]
- self.thumb_width = neg_caps["width"]
- else:
- # the pipeline couldn't be prerolled so we can't determine the
- # correct values. Set sane defaults (this should never happen)
- self.warning("Couldn't preroll the pipeline")
- # assume 16:9 aspect ratio
- self.thumb_width = 16 * self.thumb_height / 9
decode = self.pipeline.get_by_name("decode")
decode.connect("autoplug-select", self._autoplug_select_cb)
- # pop all messages from the bus so we won't be flooded with messages
- # from the prerolling phase
- while self.pipeline.get_bus().pop():
- continue
- # add a message handler that listens for the created pixbufs
+ self.__preroll_timeout_id = GLib.timeout_add_seconds(MAX_BRINGING_TO_PAUSED_DURATION,
+ self.__preroll_timed_out_cb)
self.pipeline.get_bus().add_signal_watch()
self.pipeline.get_bus().connect("message", self.__bus_message_cb)
+ self.pipeline.set_state(Gst.State.PAUSED)
def _checkCPU(self):
"""Adjusts when the next thumbnail is generated.
@@ -671,21 +655,34 @@ class VideoPreviewer(Previewer, Zoomable, Loggable):
self._update_thumbnails()
# Callbacks
-
def __bus_message_cb(self, unused_bus, message):
if message.type == Gst.MessageType.ELEMENT and \
- message.src == self.gdkpixbufsink:
+ message.src == self.gdkpixbufsink and \
+ self.__preroll_timeout_id == 0:
struct = message.get_structure()
struct_name = struct.get_name()
if struct_name == "preroll-pixbuf":
stream_time = struct.get_value("stream-time")
pixbuf = struct.get_value("pixbuf")
self._set_pixbuf(stream_time, pixbuf)
+ elif message.src == self.pipeline and message.type == Gst.MessageType.STATE_CHANGED:
+ if message.parse_state_changed()[1] == Gst.State.PAUSED:
+ if self.__preroll_timeout_id:
+ GLib.source_remove(self.__preroll_timeout_id)
+ self.__preroll_timeout_id = 0
+ sinkpad = self.gdkpixbufsink.get_static_pad("sink")
+ neg_caps = sinkpad.get_current_caps()[0]
+ self.thumb_width = neg_caps["width"]
+
+ self._update_thumbnails()
elif message.type == Gst.MessageType.ASYNC_DONE and \
message.src == self.pipeline:
self._checkCPU()
return Gst.BusSyncReply.PASS
+ def __preroll_timed_out_cb(self):
+ self.stopGeneration()
+
# pylint: disable=no-self-use
def _autoplug_select_cb(self, unused_decode, unused_pad, unused_caps, factory):
# Don't plug audio decoders / parsers.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]