[pitivi: 1/2] Add pitivi.utils.Seeker. Make ruler and viewer use
- From: Edward Hervey <edwardrv src gnome org>
- To: svn-commits-list gnome org
- Subject: [pitivi: 1/2] Add pitivi.utils.Seeker. Make ruler and viewer use
- Date: Tue, 3 Mar 2009 09:40:59 -0500 (EST)
commit b4ac961512044d3929d08277f00648039cc878e5
Author: Alessandro Decina <alessandro decina collabora co uk>
Date: Tue Mar 3 13:18:43 2009 +0100
Add pitivi.utils.Seeker. Make ruler and viewer use it.
---
pitivi/ui/ruler.py | 32 +++++++---------------
pitivi/ui/viewer.py | 33 +++++-----------------
pitivi/utils.py | 27 ++++++++++++++++++
tests/test_seeker.py | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 117 insertions(+), 47 deletions(-)
diff --git a/pitivi/ui/ruler.py b/pitivi/ui/ruler.py
index c205dc7..71fb7ab 100644
--- a/pitivi/ui/ruler.py
+++ b/pitivi/ui/ruler.py
@@ -28,7 +28,7 @@ import gtk
import gst
from pitivi.ui.zoominterface import Zoomable
from pitivi.log.loggable import Loggable
-from pitivi.utils import time_to_string
+from pitivi.utils import time_to_string, Seeker
class ScaleRuler(gtk.Layout, Zoomable, Loggable):
@@ -68,13 +68,11 @@ class ScaleRuler(gtk.Layout, Zoomable, Loggable):
# position is in nanoseconds
self.position = 0
- self.requested_time = gst.CLOCK_TIME_NONE
- self.currentlySeeking = False
self.pressed = False
- self.pending_seek_id = None
self.shaded_duration = gst.CLOCK_TIME_NONE
self.max_duration = gst.CLOCK_TIME_NONE
- self.seek_delay = 80
+ self.seeker = Seeker(80)
+ self.seeker.connect('seek', self._seekerSeekCb)
## Zoomable interface override
@@ -168,32 +166,22 @@ class ScaleRuler(gtk.Layout, Zoomable, Loggable):
## Seeking methods
- def _seekTimeoutCb(self):
- self.pending_seek_id = None
-
- self.debug("delayed seek timeout %s %s",
- gst.TIME_ARGS(self.seek_position), self.seek_format)
-
+ def _seekerSeekCb(self, seeker, position, format):
# clamping values within acceptable range
duration = self.getShadedDuration()
if duration == gst.CLOCK_TIME_NONE:
return
- if self.seek_position > duration:
- self.seek_position = duration - (1 * gst.MSECOND)
- elif self.seek_position < 0:
- self.seek_position = 0
+ if position > duration:
+ position = duration - (1 * gst.MSECOND)
+ elif position < 0:
+ position = 0
- self.emit('seek', self.seek_position)
+ self.emit('seek', position)
return False
def _doSeek(self, value, format=gst.FORMAT_TIME):
- if self.pending_seek_id is None:
- self.pending_seek_id = gobject.timeout_add(self.seek_delay,
- self._seekTimeoutCb)
-
- self.seek_position = value
- self.seek_format = format
+ self.seeker.seek(value, format)
## Drawing methods
diff --git a/pitivi/ui/viewer.py b/pitivi/ui/viewer.py
index 3000b67..ec509dc 100644
--- a/pitivi/ui/viewer.py
+++ b/pitivi/ui/viewer.py
@@ -26,7 +26,7 @@ import gst
from pitivi.action import ViewAction
-from pitivi.utils import time_to_string
+from pitivi.utils import time_to_string, Seeker
from pitivi.log.loggable import Loggable
class ViewerError(Exception):
@@ -53,15 +53,15 @@ class PitiviViewer(gtk.VBox, Loggable):
Loggable.__init__(self)
self.log("New PitiviViewer")
+ self.seeker = Seeker(80)
+ self.seeker.connect('seek', self._seekerSeekCb)
self.action = action
self.pipeline = pipeline
self.producer = None
self.current_time = long(0)
- self.requested_time = gst.CLOCK_TIME_NONE
self._initial_seek = None
self.current_frame = -1
- self.currentlySeeking = False
self.currentState = gst.STATE_PAUSED
self._haveUI = False
@@ -322,29 +322,12 @@ class PitiviViewer(gtk.VBox, Loggable):
seekvalue = min(self.current_frame + 1, self.pipeline.getDuration())
self._doSeek(seekvalue, gst.FORMAT_DEFAULT)
- def _seekTimeoutCb(self):
- self.debug("requested_time %s", gst.TIME_ARGS(self.requested_time))
- self.currentlySeeking = False
- if (self.requested_time != gst.CLOCK_TIME_NONE) and (self.current_time != self.requested_time):
- self._doSeek(self.requested_time)
- return False
+ def _doSeek(self, position, format=gst.FORMAT_TIME):
+ self.seeker.seek(position, format)
- def _doSeek(self, value, format=gst.FORMAT_TIME):
- self.debug("%s , currentlySeeking:%r", gst.TIME_ARGS(value),
- self.currentlySeeking)
- if not self.currentlySeeking:
- self.currentlySeeking = True
- try:
- self.pipeline.seek(value, format=format)
- self.debug("seek succeeded, request_time = NONE")
- self.requested_time = gst.CLOCK_TIME_NONE
- gobject.timeout_add(80, self._seekTimeoutCb)
- self._newTime(value)
- except:
- self.currentlySeeking = False
- else:
- if format == gst.FORMAT_TIME:
- self.requested_time = value
+ def _seekerSeekCb(self, seeker, position, format):
+ self.pipeline.seek(position, format)
+ self._newTime(position)
def _newTime(self, value, frame=-1):
self.info("value:%s, frame:%d", gst.TIME_ARGS(value), frame)
diff --git a/pitivi/utils.py b/pitivi/utils.py
index 5143d3b..ba5dc75 100644
--- a/pitivi/utils.py
+++ b/pitivi/utils.py
@@ -22,6 +22,7 @@
# set of utility functions
+import gobject
import gst, bisect
from pitivi.signalinterface import Signallable
import pitivi.log.log as log
@@ -206,3 +207,29 @@ class PropertyChangeTracker(object, Signallable):
self.properties[property_name] = value
self.emit(property_name + '-changed', timeline_object, old_value, value)
+
+class Seeker(object, Signallable):
+ __signals__ = {'seek': ['position', 'format']}
+
+ def __init__(self, timeout):
+ self.timeout = timeout
+ self.pending_seek_id = None
+ self.position = None
+ self.format = None
+
+ def seek(self, position, format=gst.FORMAT_TIME):
+ if self.pending_seek_id is None:
+ self.pending_seek_id = self._scheduleSeek(self.timeout,
+ self._seekTimeoutCb)
+
+ self.position = position
+ self.format = format
+
+ def _scheduleSeek(self, timeout, callback):
+ return gobject.timeout_add(timeout, callback)
+
+ def _seekTimeoutCb(self):
+ self.pending_seek_id = None
+ position, self.position = self.position, None
+ format, self.format = self.format, None
+ self.emit('seek', position, format)
diff --git a/tests/test_seeker.py b/tests/test_seeker.py
new file mode 100644
index 0000000..97af9ab
--- /dev/null
+++ b/tests/test_seeker.py
@@ -0,0 +1,72 @@
+# PiTiVi , Non-linear video editor
+#
+# tests/test_timeline.py
+#
+# Copyright (c) 2009, Alessandro Decina <alessandro decina collabora co uk>
+#
+# 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+from unittest import TestCase
+from pitivi.utils import Seeker
+import gst
+
+class StubSeeker(Seeker):
+ seek_id = 0
+
+ def _scheduleSeek(self, position, format):
+ # mock Seeker._scheduleSeek so that we don't need a mainloop
+ seek_id = self.seek_id
+ self.seek_id += 1
+
+ return seek_id
+
+class TestSeeker(TestCase):
+ def setUp(self):
+ self.seek_count = 0
+ self.seek_position = None
+ self.seek_format = None
+
+ def testSeek(self):
+ def seek_cb(seeker, position, format):
+ self.seek_count += 1
+ self.seek_position = position
+ self.seek_format = format
+
+ seeker = StubSeeker(timeout=10)
+ seeker.connect('seek', seek_cb)
+
+ seeker.seek(1)
+ self.failUnlessEqual(seeker.pending_seek_id, 0)
+ self.failUnlessEqual(seeker.position, 1)
+ self.failUnlessEqual(seeker.format, gst.FORMAT_TIME)
+
+ seeker.seek(2, gst.FORMAT_BYTES)
+ self.failUnlessEqual(seeker.pending_seek_id, 0)
+ self.failUnlessEqual(seeker.position, 2)
+ self.failUnlessEqual(seeker.format, gst.FORMAT_BYTES)
+
+ seeker._seekTimeoutCb()
+ self.failUnlessEqual(self.seek_count, 1)
+ self.failUnlessEqual(self.seek_position, 2)
+ self.failUnlessEqual(self.seek_format, gst.FORMAT_BYTES)
+ self.failUnlessEqual(seeker.pending_seek_id, None)
+ self.failUnlessEqual(seeker.position, None)
+ self.failUnlessEqual(seeker.format, None)
+
+ seeker.seek(3)
+ self.failUnlessEqual(seeker.pending_seek_id, 1)
+ self.failUnlessEqual(seeker.position, 3)
+ self.failUnlessEqual(seeker.format, gst.FORMAT_TIME)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]