[pitivi: 2/16] Refactor interpolator code slightly.
- From: Edward Hervey <edwardrv src gnome org>
- To: svn-commits-list gnome org
- Subject: [pitivi: 2/16] Refactor interpolator code slightly.
- Date: Wed, 8 Jul 2009 14:37:06 +0000 (UTC)
commit 690a19f0cac506c6de4d96ffe558be2af39d222b
Author: Alessandro Decina <alessandro d gmail com>
Date: Fri Jul 3 16:28:07 2009 +0200
Refactor interpolator code slightly.
Make track_object.interpolators a dictionary of the form property_name ->
(property, interpolator) so that we can lookup interpolators by property_name
without having to iterate all the keys every time.
Make it possible to rebuild interpolators when the content of a track_object's
bin changes. This commit is part of a larger change to make interpolator operations undoable.
pitivi/formatters/etree.py | 10 +++---
pitivi/timeline/track.py | 67 ++++++++++++++++++++++++++--------------
pitivi/ui/trackobject.py | 2 +-
tests/test_etree_formatter.py | 4 +-
4 files changed, 51 insertions(+), 32 deletions(-)
---
diff --git a/pitivi/formatters/etree.py b/pitivi/formatters/etree.py
index 7da1b43..45ca28f 100644
--- a/pitivi/formatters/etree.py
+++ b/pitivi/formatters/etree.py
@@ -329,11 +329,11 @@ class ElementTreeFormatter(Formatter):
element.append(factory_ref)
element.append(stream_ref)
- if track_object.interpolators:
- curves = Element("curves")
- for property, interpolator in track_object.interpolators.iteritems():
- curves.append(self._saveInterpolator(interpolator, property))
- element.append(curves)
+ interpolators = track_object.getInterpolators()
+ curves = Element("curves")
+ for property, interpolator in interpolators.itervalues():
+ curves.append(self._saveInterpolator(interpolator, property))
+ element.append(curves)
self._context.track_objects[track_object] = element
diff --git a/pitivi/timeline/track.py b/pitivi/timeline/track.py
index 31c647b..2b899ba 100644
--- a/pitivi/timeline/track.py
+++ b/pitivi/timeline/track.py
@@ -138,10 +138,6 @@ class Interpolator(Signallable, Loggable):
def __init__(self, trackobject, element, prop):
Loggable.__init__(self)
self.debug("track:%r, element:%r, property:%r", trackobject, element, prop)
- self._element = element
- self._default = self._element.get_property(prop.name)
- #self._default = 0
- self._property = prop
self._keyframes = []
# FIXME: get this from the property's param spec
# NOTE: keyframes necessarily work only on a closed range
@@ -152,11 +148,8 @@ class Interpolator(Signallable, Loggable):
# each Interpolator. We should instead create a ControlSource for each
# element. We can't do this until the new controller interface is
# exposed in gst-python.
- self.debug("Creating a GstController for element %r and property %s",
- self._element, prop.name)
- self._controller = gst.Controller(self._element, prop.name)
- self._controller.set_interpolation_mode(prop.name, gst.INTERPOLATE_LINEAR)
-
+ self.attachToElementProperty(prop, element)
+ self._default = self._element.get_property(prop.name)
self.start = FixedKeyframe(self)
self.end = FixedKeyframe(self)
self.start.value = self._default
@@ -164,9 +157,13 @@ class Interpolator(Signallable, Loggable):
self.end.value = self._default
self.end.setObjectTime(trackobject.factory.duration)
- #data = ((self.start.time, self.start.value), (self.end.time,
- # self.end.value))
- #self._controller.set_from_list(prop.name, data)
+ def attachToElementProperty(self, prop, element):
+ self._element = element
+ self._property = prop
+ self.debug("Creating a GstController for element %r and property %s",
+ self._element, prop.name)
+ self._controller = gst.Controller(self._element, prop.name)
+ self._controller.set_interpolation_mode(prop.name, gst.INTERPOLATE_LINEAR)
def newKeyFrame(self, time, value=None, mode=None):
"""add a new keyframe at the specified time, optionally with specified
@@ -275,6 +272,8 @@ class TrackObject(Signallable, Loggable):
self.stream = stream
self.track = None
self.timeline_object = None
+ self.interpolators = {}
+ self._rebuild_interpolators = True
self.gnl_object = obj = self._makeGnlObject()
self.makeBin()
self.trimmed_start = 0
@@ -301,19 +300,36 @@ class TrackObject(Signallable, Loggable):
self._connectToSignals(obj)
- self.interpolators = {}
+ def getInterpolator(self, property_name):
+ self._maybeBuildInterpolators()
- wprops = factory.getInterpolatedProperties(stream).keys()
- if stream:
- for sobj, prop in get_controllable_properties(self.gnl_object):
- if prop.name in wprops:
- self.interpolators[prop] = Interpolator(self, sobj, prop)
+ try:
+ return self.interpolators[property_name][1]
+ except KeyError:
+ raise TrackError("no interpolator for '%s'" % property_name)
- def getInterpolator(self, property_name):
- for prop, interpolator in self.interpolators.iteritems():
- if property_name == prop.name:
- return interpolator
- return None
+ def getInterpolators(self):
+ self._maybeBuildInterpolators()
+ return self.interpolators
+
+ def _maybeBuildInterpolators(self):
+ if not list(self.gnl_object.elements()):
+ raise TrackError("makeBin hasn't been called yet")
+
+ if not self._rebuild_interpolators:
+ return
+
+ self._rebuild_interpolators = False
+
+ factory_properties = self.factory.getInterpolatedProperties(self.stream).keys()
+
+ for gst_object, gst_object_property in \
+ get_controllable_properties(self.gnl_object):
+ if gst_object_property.name not in factory_properties:
+ continue
+
+ self.interpolators[gst_object_property.name] = (gst_object_property,
+ Interpolator(self, gst_object, gst_object_property))
def release(self):
self._disconnectFromSignals()
@@ -328,7 +344,8 @@ class TrackObject(Signallable, Loggable):
media_duration=self.media_duration, priority=self.priority)
other.trimmed_start = self.trimmed_start
- for property, interpolator in self.interpolators.iteritems():
+ interpolators = self.getInterpolators()
+ for property, interpolator in interpolators.itervalues():
other_interpolator = other.getInterpolator(property.name)
other_interpolator.start.value = interpolator.start.value
other_interpolator.start.mode = interpolator.start.mode
@@ -496,6 +513,7 @@ class TrackObject(Signallable, Loggable):
bin = self.factory.makeBin(self.stream)
self.gnl_object.add(bin)
+ self._maybeBuildInterpolators()
def releaseBin(self):
elts = list(self.gnl_object.elements())
@@ -504,6 +522,7 @@ class TrackObject(Signallable, Loggable):
self.gnl_object.remove(bin)
bin.set_state(gst.STATE_NULL)
self.factory.releaseBin(bin)
+ self._rebuild_interpolators = True
def _notifyStartCb(self, obj, pspec):
self.emit('start-changed', obj.props.start)
diff --git a/pitivi/ui/trackobject.py b/pitivi/ui/trackobject.py
index 06ff164..148c562 100644
--- a/pitivi/ui/trackobject.py
+++ b/pitivi/ui/trackobject.py
@@ -274,7 +274,7 @@ class TrackObject(View, goocanvas.Group, Zoomable):
self.start_handle, self.end_handle, self.namebg, self.name):
self.add_child(thing)
- for interpolator in element.interpolators.itervalues():
+ for prop, interpolator in element.getInterpolators().itervalues():
self.add_child(Curve(element, interpolator, 50))
self.element = element
diff --git a/tests/test_etree_formatter.py b/tests/test_etree_formatter.py
index ca76770..21e6aba 100644
--- a/tests/test_etree_formatter.py
+++ b/tests/test_etree_formatter.py
@@ -128,7 +128,7 @@ class TestFormatterSave(TestCase):
fakevol = gst.element_factory_make("volume")
prop = get_controllable_properties(fakevol)[1][1]
volcurve = Interpolator(track_object, fakevol, prop)
- track_object.interpolators[prop] = volcurve
+ track_object.interpolators[prop.name] = (prop, volcurve)
# add some points to the interpolator
value = float(0)
@@ -136,7 +136,7 @@ class TestFormatterSave(TestCase):
volcurve.start.value = 0
for t in xrange(3, 15, 3):
value = int(t % 2)
- volcurve.newKeyFrame(time=t * gst.SECOND, value=value)
+ volcurve.newKeyFrame(t * gst.SECOND, value)
volcurve.end.setObjectTime(15 * gst.SECOND)
volcurve.end.value = 15 % 2
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]