[pitivi/ges] pipeline: Create a SimplePipeline that is reusable in more use cases
- From: Thibault Saunier <tsaunier src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pitivi/ges] pipeline: Create a SimplePipeline that is reusable in more use cases
- Date: Sat, 5 May 2012 20:19:00 +0000 (UTC)
commit 8dad82bbfbfef56de886492a0ba99f4ed46916c1
Author: Thibault Saunier <thibault saunier collabora com>
Date: Tue May 1 23:50:16 2012 -0400
pipeline: Create a SimplePipeline that is reusable in more use cases
Factor out the code from the Pipeline class so it can be reused in other
places
pitivi/utils/pipeline.py | 145 +++++++++++++++++++++++++++++-----------------
1 files changed, 92 insertions(+), 53 deletions(-)
---
diff --git a/pitivi/utils/pipeline.py b/pitivi/utils/pipeline.py
index 33d97f5..921ad57 100644
--- a/pitivi/utils/pipeline.py
+++ b/pitivi/utils/pipeline.py
@@ -148,9 +148,8 @@ def togglePlayback(pipeline):
return state
-class Pipeline(ges.TimelinePipeline, Loggable):
+class SimplePipeline(Loggable, Signallable):
"""
-
The Pipeline is only responsible for:
- State changes
- Position seeking
@@ -164,36 +163,26 @@ class Pipeline(ges.TimelinePipeline, Loggable):
- C{error} : An error happened.
"""
- __gsignals__ = {
- "state-changed": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
- (gobject.TYPE_INT,)),
- "position": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
- (gobject.TYPE_UINT64,)),
- "duration-changed": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
- (gobject.TYPE_UINT64,)),
- "eos": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
- ()),
- "error": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
- (gobject.TYPE_STRING, gobject.TYPE_STRING)),
- "element-message": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
- (gobject.TYPE_POINTER,))}
-
- def __init__(self):
+ __signals__ = {
+ "state-changed": ["state"],
+ "position": ["position"],
+ "duration-changed": ["duration"],
+ "eos": [],
+ "error": ["message", "details"],
+ "element-message": ["message"]}
+
+ def __init__(self, pipeline):
Loggable.__init__(self)
- ges.TimelinePipeline.__init__(self)
- self._bus = self.get_bus()
+ Signallable.__init__(self)
+ self._pipeline = pipeline
+ self._bus = self._pipeline.get_bus()
self._bus.add_signal_watch()
self._bus.connect("message", self._busMessageCb)
self._bus.set_sync_handler(self._busSyncMessageHandler)
self._listening = False # for the position handler
self._listeningInterval = 300 # default 300ms
self._listeningSigId = 0
- self._seeker = Seeker()
-
self._duration = gst.CLOCK_TIME_NONE
- self._seeker.connect("seek", self._seekCb)
- self._seeker.connect("seek-relative", self._seekRelativeCb)
- self._seeker.connect("flush", self._seekFlushCb)
def release(self):
"""
@@ -210,28 +199,9 @@ class Pipeline(ges.TimelinePipeline, Loggable):
self._bus.remove_signal_watch()
self._bus.set_sync_handler(None)
- self._seeker.disconnect_by_func(self._seekRelativeCb)
- self._seeker.disconnect_by_func(self._seekFlushCb)
- self._seeker.disconnect_by_func(self._seekCb)
-
- self.setState(gst.STATE_NULL)
+ self._pipeline.setState(gst.STATE_NULL)
self._bus = None
- def _seekRelativeCb(self, unused_seeker, time):
- self.seekRelative(time)
-
- def _seekFlushCb(self, unused_seeker):
- self.flushSeek()
-
- def _seekCb(self, ruler, position, format):
- """
- The app's main seek method used when the user seeks manually.
-
- We clamp the seeker position so that it cannot go past 0 or the
- end of the timeline.
- """
- self.simple_seek(position)
-
def flushSeek(self):
self.pause()
try:
@@ -247,10 +217,10 @@ class Pipeline(ges.TimelinePipeline, Loggable):
the requested state.
"""
self.debug("state:%r" % state)
- res = self.set_state(state)
+ res = self._pipeline.set_state(state)
if res == gst.STATE_CHANGE_FAILURE:
# reset to NULL
- self.set_state(gst.STATE_NULL)
+ self._pipeline.set_state(gst.STATE_NULL)
raise PipelineError("Failure changing state of the gst.Pipeline to %r, currently reset to NULL" % state)
def getState(self):
@@ -263,7 +233,7 @@ class Pipeline(ges.TimelinePipeline, Loggable):
@return: The current state.
@rtype: C{State}
"""
- change, state, pending = self.get_state(0)
+ change, state, pending = self._pipeline.get_state(0)
self.debug("change:%r, state:%r, pending:%r" % (change, state, pending))
return state
@@ -315,7 +285,7 @@ class Pipeline(ges.TimelinePipeline, Loggable):
"""
self.log("format %r" % format)
try:
- cur, format = self.query_position(format)
+ cur, format = self._pipeline.query_position(format)
except Exception, e:
self.handleException(e)
raise PipelineError("Couldn't get position")
@@ -329,7 +299,7 @@ class Pipeline(ges.TimelinePipeline, Loggable):
"""
self.log("format %r" % format)
try:
- dur, format = self.query_duration(format)
+ dur, format = self._pipeline.query_duration(format)
except Exception, e:
self.handleException(e)
@@ -411,7 +381,7 @@ class Pipeline(ges.TimelinePipeline, Loggable):
if format == gst.FORMAT_TIME:
position = max(0, min(position, self.getDuration()) - 1)
- res = self.seek(1.0, format, gst.SEEK_FLAG_FLUSH,
+ res = self._pipeline.seek(1.0, format, gst.SEEK_FLAG_FLUSH,
gst.SEEK_TYPE_SET, position,
gst.SEEK_TYPE_NONE, -1)
if not res:
@@ -438,7 +408,7 @@ class Pipeline(ges.TimelinePipeline, Loggable):
self.debug("element %s state change %s" % (message.src,
(prev, new, pending)))
- if message.src == self:
+ if message.src == self._pipeline:
self.debug("Pipeline change state prev:%r, new:%r, pending:%r" % (prev, new, pending))
emit_state_change = pending == gst.STATE_VOID_PENDING
@@ -450,9 +420,9 @@ class Pipeline(ges.TimelinePipeline, Loggable):
# no sinks??
pass
elif prev == gst.STATE_PAUSED and new == gst.STATE_PLAYING:
- self.activatePositionListener(True)
+ self._listenToPosition(True)
elif prev == gst.STATE_PLAYING and new == gst.STATE_PAUSED:
- self.activatePositionListener(False)
+ self._listenToPosition(False)
if emit_state_change:
self.emit('state-changed', new)
@@ -482,3 +452,72 @@ class Pipeline(ges.TimelinePipeline, Loggable):
# handle element message synchronously
self.emit('element-message', message)
return gst.BUS_PASS
+
+
+class Pipeline(ges.TimelinePipeline, SimplePipeline):
+ """
+ The Pipeline is only responsible for:
+ - State changes
+ - Position seeking
+ - Position Querying
+ - Along with an periodic callback (optional)
+
+ Signals:
+ - C{state-changed} : The state of the pipeline changed.
+ - C{position} : The current position of the pipeline changed.
+ - C{eos} : The Pipeline has finished playing.
+ - C{error} : An error happened.
+ """
+
+ __gsignals__ = {
+ "state-changed": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
+ (gobject.TYPE_INT,)),
+ "position": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
+ (gobject.TYPE_UINT64,)),
+ "duration-changed": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
+ (gobject.TYPE_UINT64,)),
+ "eos": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
+ ()),
+ "error": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
+ (gobject.TYPE_STRING, gobject.TYPE_STRING)),
+ "element-message": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
+ (gobject.TYPE_PYOBJECT,))}
+
+ def __init__(self, pipeline=None):
+ ges.TimelinePipeline.__init__(self)
+ SimplePipeline.__init__(self, self)
+
+ self._seeker = Seeker()
+ self._seeker.connect("seek", self._seekCb)
+ self._seeker.connect("seek-relative", self._seekRelativeCb)
+ self._seeker.connect("flush", self._seekFlushCb)
+
+ def release(self):
+ """
+ Release the L{Pipeline} and all used L{ObjectFactory} and
+ L{Action}s.
+
+ Call this method when the L{Pipeline} is no longer used. Forgetting to do
+ so will result in memory loss.
+
+ @postcondition: The L{Pipeline} will no longer be usable.
+ """
+ self._seeker.disconnect_by_func(self._seekRelativeCb)
+ self._seeker.disconnect_by_func(self._seekFlushCb)
+ self._seeker.disconnect_by_func(self._seekCb)
+ SimplePipeline.release(self)
+
+ def _seekRelativeCb(self, unused_seeker, time):
+ self.seekRelative(time)
+
+ def _seekFlushCb(self, unused_seeker):
+ self.flushSeek()
+
+ def _seekCb(self, ruler, position, format):
+ """
+ The app's main seek method used when the user seeks manually.
+
+ We clamp the seeker position so that it cannot go past 0 or the
+ end of the timeline.
+ """
+ self.simple_seek(position)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]