1
# PiTiVi , Non-linear video editor
5
# Copyright (c) 2009, Alessandro Decina <alessandro.decina@collabora.co.uk>
7
# This program is free software; you can redistribute it and/or
8
# modify it under the terms of the GNU Lesser General Public
9
# License as published by the Free Software Foundation; either
10
# version 2.1 of the License, or (at your option) any later version.
12
# This program is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
# Lesser General Public License for more details.
17
# You should have received a copy of the GNU Lesser General Public
18
# License along with this program; if not, write to the
19
# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20
# Boston, MA 02110-1301, USA.
22
from unittest import TestCase
24
from xml.etree.ElementTree import Element, SubElement
26
from pitivi.reflect import qual
27
from pitivi.formatters.etree import ElementTreeFormatter, version,\
29
from pitivi.stream import VideoStream, AudioStream
30
from pitivi.factories.file import FileSourceFactory
31
from pitivi.factories.test import VideoTestSourceFactory, \
32
AudioTestSourceFactory
33
from pitivi.factories.operation import EffectFactory
34
from pitivi.timeline.track import Track, SourceTrackObject, Interpolator,\
36
from pitivi.timeline.timeline import Timeline, TimelineObject
37
from pitivi.project import Project
38
from pitivi.utils import get_controllable_properties
39
from pitivi.effects import EffectsHandler
42
class FakeElementTreeFormatter(ElementTreeFormatter):
47
return "(gint64)%s" % time
50
class TestSerialization(TestCase):
52
self.formatter = FakeElementTreeFormatter(EffectsHandler())
54
def testSerializeAndDeserialize(self):
55
element = Element('tag')
62
self.formatter._serializeDict(element, values_dict)
63
# Make sure that all the keys end up in element.
64
for key, unused_value in values_dict.iteritems():
65
self.assertTrue(key in element.attrib)
67
deserialized_values_dict = self.formatter._deserializeDict(element)
68
# Make sure that all the keys in the original dict end up in the
71
set(values_dict.keys()), set(deserialized_values_dict.keys()))
72
for key, value in values_dict.iteritems():
73
self.assertEqual(value, deserialized_values_dict[key])
76
class TestFormatterSave(TestCase):
78
self.formatter = FakeElementTreeFormatter(EffectsHandler())
80
def testSaveStream(self):
81
stream = VideoStream(gst.Caps("video/x-raw-rgb, blah=meh"))
82
element = self.formatter._saveStream(stream)
83
self.failUnlessEqual(element.tag, "stream")
84
self.failUnless("id" in element.attrib)
85
self.failUnlessEqual(element.attrib["type"], qual(stream.__class__))
86
self.failUnlessEqual(element.attrib["caps"], str(stream.caps))
88
def testSaveStreamRef(self):
89
# save a stream so that a mapping is created in the context
90
stream = VideoStream(gst.Caps("video/x-raw-rgb, blah=meh"))
91
element = self.formatter._saveStream(stream)
92
element_ref = self.formatter._saveStreamRef(stream)
93
self.failUnlessEqual(element_ref.tag, "stream-ref")
94
self.failUnlessEqual(element_ref.attrib["id"], element.attrib["id"])
96
def testSaveSource(self):
97
video_stream = VideoStream(gst.Caps("video/x-raw-yuv"))
98
audio_stream = AudioStream(gst.Caps("audio/x-raw-int"))
99
source1 = FileSourceFactory("file1.ogg")
100
source1.addOutputStream(video_stream)
101
source1.addOutputStream(audio_stream)
102
element = self.formatter._saveSource(source1)
103
self.failUnlessEqual(element.tag, "source")
104
self.failUnlessEqual(element.attrib["type"], qual(source1.__class__))
105
self.failUnlessEqual(element.attrib["filename"], "file1.ogg")
107
streams = element.find("output-streams")
108
self.failUnlessEqual(len(streams), 2)
110
def testSaveFactories(self):
111
video_stream = VideoStream(gst.Caps("video/x-raw-yuv"))
112
audio_stream = AudioStream(gst.Caps("audio/x-raw-int"))
114
source1 = FileSourceFactory("file1.ogg")
115
source1.addOutputStream(video_stream)
116
source1.addOutputStream(audio_stream)
118
source2 = FileSourceFactory("file2.ogg")
119
source2.addOutputStream(video_stream)
120
source2.addOutputStream(audio_stream)
122
source_factories = [source1, source2]
123
element = self.formatter._saveFactories(source_factories)
124
self.failUnlessEqual(element.tag, "factories")
126
sources = element.find("sources")
127
self.failUnlessEqual(len(sources), 2)
128
#source tags are tested in testSaveSource
130
def testSaveFactoryRef(self):
131
video_stream = VideoStream(gst.Caps("video/x-raw-yuv"))
132
audio_stream = AudioStream(gst.Caps("audio/x-raw-int"))
133
source1 = FileSourceFactory("file1.ogg")
134
source1.addOutputStream(video_stream)
135
source1.addOutputStream(audio_stream)
136
element = self.formatter._saveSource(source1)
138
element_ref = self.formatter._saveFactoryRef(source1)
139
self.failUnlessEqual(element_ref.tag, "factory-ref")
140
self.failUnlessEqual(element_ref.attrib["id"], element.attrib["id"])
142
def testSaveTrackEffect(self):
143
video_stream = VideoStream(gst.Caps("video/x-raw-yuv"))
144
audio_stream = AudioStream(gst.Caps("audio/x-raw-int"))
146
effect1 = EffectFactory('identity', 'identity')
147
effect1.addOutputStream(video_stream)
148
effect1.addInputStream(video_stream)
150
#It is necessary to had the identity factory to the
151
#effect_factories_dictionnary
152
self.formatter.avalaible_effects._effect_factories_dict['identity'] =\
154
track_effect = TrackEffect(effect1, video_stream,
155
start=10 * gst.SECOND, duration=20 * gst.SECOND,
156
in_point=5 * gst.SECOND, media_duration=15 * gst.SECOND,
159
track = Track(video_stream)
160
track.addTrackObject(track_effect)
162
element = self.formatter._saveTrackObject(track_effect)
163
self.failUnlessEqual(element.tag, "track-object")
164
self.failUnlessEqual(element.attrib["type"],
165
qual(track_effect.__class__))
166
self.failUnlessEqual(element.attrib["start"], ts(10 * gst.SECOND))
167
self.failUnlessEqual(element.attrib["duration"], ts(20 * gst.SECOND))
168
self.failUnlessEqual(element.attrib["in_point"], ts(5 * gst.SECOND))
169
self.failUnlessEqual(element.attrib["media_duration"],
171
self.failUnlessEqual(element.attrib["priority"], "(int)10")
173
effect_element = element.find('effect')
174
self.failIfEqual(effect_element, None)
175
self.failIfEqual(effect_element.find("factory"), None)
176
self.failIfEqual(effect_element.find("gst-element-properties"), None)
178
def testSaveTrackSource(self):
179
video_stream = VideoStream(gst.Caps("video/x-raw-yuv"))
180
audio_stream = AudioStream(gst.Caps("audio/x-raw-int"))
181
source1 = FileSourceFactory("file1.ogg")
182
source1.addOutputStream(video_stream)
184
# these two calls are needed to populate the context for the -ref
186
self.formatter._saveSource(source1)
187
self.formatter._saveStream(video_stream)
189
track_source = SourceTrackObject(source1, video_stream,
190
start=10 * gst.SECOND, duration=20 * gst.SECOND,
191
in_point=5 * gst.SECOND, media_duration=15 * gst.SECOND,
194
track = Track(video_stream)
195
track.addTrackObject(track_source)
197
# create an interpolator and insert it into the track object
198
fakevol = gst.element_factory_make("volume")
199
prop = get_controllable_properties(fakevol)[1][1]
200
volcurve = Interpolator(track_source, fakevol, prop)
201
track_source.interpolators[prop.name] = (prop, volcurve)
203
# add some points to the interpolator
205
volcurve.start.setObjectTime(0)
206
volcurve.start.value = 0
207
for t in xrange(3, 15, 3):
209
volcurve.newKeyframe(t * gst.SECOND, value)
210
volcurve.end.setObjectTime(15 * gst.SECOND)
211
volcurve.end.value = 15 % 2
213
element = self.formatter._saveTrackObject(track_source)
214
self.failUnlessEqual(element.tag, "track-object")
215
self.failUnlessEqual(element.attrib["type"],
216
qual(track_source.__class__))
217
self.failUnlessEqual(element.attrib["start"], ts(10 * gst.SECOND))
218
self.failUnlessEqual(element.attrib["duration"], ts(20 * gst.SECOND))
219
self.failUnlessEqual(element.attrib["in_point"], ts(5 * gst.SECOND))
220
self.failUnlessEqual(element.attrib["media_duration"],
222
self.failUnlessEqual(element.attrib["priority"], "(int)10")
224
self.failIfEqual(element.find("factory-ref"), None)
225
self.failIfEqual(element.find("stream-ref"), None)
227
# find the interpolation keyframes
228
curves = element.find("curves")
229
self.failIfEqual(curves, None)
230
curve = curves.find("curve")
231
self.failIfEqual(curve, None)
232
self.failUnlessEqual(curve.attrib["property"], "volume")
234
# compute a dictionary of keyframes
235
saved_points = dict(((obj.attrib["time"], (obj.attrib["value"],
236
obj.attrib["mode"])) for obj in curve.getiterator("keyframe")))
238
# compare this with the expected values
239
expected = dict(((str(t * gst.SECOND), ("(gdouble)%s" % (t % 2), "2")) for t in
241
self.failUnlessEqual(expected, saved_points)
243
def testSaveTrackObjectRef(self):
244
video_stream = VideoStream(gst.Caps("video/x-raw-yuv"))
245
audio_stream = AudioStream(gst.Caps("audio/x-raw-int"))
246
source1 = FileSourceFactory("file1.ogg")
247
source1.addOutputStream(video_stream)
249
# these two calls are needed to populate the context for the -ref
251
self.formatter._saveSource(source1)
252
self.formatter._saveStream(video_stream)
254
track_object = SourceTrackObject(source1, video_stream,
255
start=10 * gst.SECOND, duration=20 * gst.SECOND,
256
in_point=5 * gst.SECOND, media_duration=15 * gst.SECOND,
258
track = Track(video_stream)
259
track.addTrackObject(track_object)
261
element = self.formatter._saveTrackObject(track_object)
262
element_ref = self.formatter._saveTrackObjectRef(track_object)
263
self.failUnlessEqual(element_ref.tag, "track-object-ref")
264
self.failUnlessEqual(element.attrib["id"], element.attrib["id"])
266
def testSaveTrack(self):
267
video_stream = VideoStream(gst.Caps("video/x-raw-yuv"))
268
audio_stream = AudioStream(gst.Caps("audio/x-raw-int"))
269
source1 = VideoTestSourceFactory()
271
# these two calls are needed to populate the context for the -ref
273
self.formatter._saveSource(source1)
274
self.formatter._saveStream(video_stream)
276
track_object = SourceTrackObject(source1, video_stream,
277
start=10 * gst.SECOND, duration=20 * gst.SECOND,
278
in_point=5 * gst.SECOND, media_duration=15 * gst.SECOND,
281
track = Track(video_stream)
282
track.addTrackObject(track_object)
284
element = self.formatter._saveTrack(track)
285
self.failUnlessEqual(element.tag, "track")
286
track_objects_element = element.find("track-objects")
287
self.failUnlessEqual(len(track_objects_element), 1)
289
def testSaveTimelineObject(self):
290
video_stream = VideoStream(gst.Caps("video/x-raw-yuv"))
291
audio_stream = AudioStream(gst.Caps("audio/x-raw-int"))
292
source1 = FileSourceFactory("file1.ogg")
293
source1.addOutputStream(video_stream)
295
# these two calls are needed to populate the context for the -ref
297
self.formatter._saveSource(source1)
298
self.formatter._saveStream(video_stream)
300
track_object = SourceTrackObject(source1, video_stream,
301
start=10 * gst.SECOND, duration=20 * gst.SECOND,
302
in_point=5 * gst.SECOND, media_duration=15 * gst.SECOND,
304
track = Track(video_stream)
305
track.addTrackObject(track_object)
307
self.formatter._saveTrackObject(track_object)
309
timeline_object = TimelineObject(source1)
310
timeline_object.addTrackObject(track_object)
312
element = self.formatter._saveTimelineObject(timeline_object)
313
self.failUnlessEqual(element.tag, "timeline-object")
314
self.failIfEqual(element.find("factory-ref"), None)
315
track_object_refs = element.find("track-object-refs")
316
self.failUnlessEqual(len(track_object_refs), 1)
318
def testSavetimelineObjects(self):
319
video_stream = VideoStream(gst.Caps("video/x-raw-yuv"))
320
audio_stream = AudioStream(gst.Caps("audio/x-raw-int"))
321
source1 = FileSourceFactory("file1.ogg")
322
source1.addOutputStream(video_stream)
324
# these two calls are needed to populate the context for the -ref
326
self.formatter._saveSource(source1)
327
self.formatter._saveStream(video_stream)
329
track_object = SourceTrackObject(source1, video_stream,
330
start=10 * gst.SECOND, duration=20 * gst.SECOND,
331
in_point=5 * gst.SECOND, media_duration=15 * gst.SECOND,
333
track = Track(video_stream)
334
track.addTrackObject(track_object)
335
self.formatter._saveTrackObject(track_object)
337
timeline_object = TimelineObject(source1)
338
timeline_object.addTrackObject(track_object)
340
element = self.formatter._saveTimelineObjects([timeline_object])
341
self.failUnlessEqual(len(element), 1)
343
def testSaveTimeline(self):
344
video_stream = VideoStream(gst.Caps("video/x-raw-yuv"))
345
audio_stream = AudioStream(gst.Caps("audio/x-raw-int"))
346
source1 = VideoTestSourceFactory()
347
source1.addOutputStream(video_stream)
349
self.formatter._saveSource(source1)
350
self.formatter._saveStream(video_stream)
352
track_object = SourceTrackObject(source1, video_stream,
353
start=10 * gst.SECOND, duration=20 * gst.SECOND,
354
in_point=5 * gst.SECOND, media_duration=15 * gst.SECOND,
357
track = Track(video_stream)
358
track.addTrackObject(track_object)
360
self.formatter._saveTrackObject(track_object)
362
timeline_object = TimelineObject(source1)
363
timeline_object.addTrackObject(track_object)
365
self.formatter._saveTimelineObject(timeline_object)
367
timeline = Timeline()
368
timeline.addTrack(track)
370
element = self.formatter._saveTimeline(timeline)
371
self.failUnlessEqual(element.tag, "timeline")
372
tracks = element.find("tracks")
373
self.failUnlessEqual(len(tracks), 1)
375
def testSaveMainTag(self):
376
element = self.formatter._saveMainTag()
377
self.failUnlessEqual(element.tag, "pitivi")
378
self.failUnlessEqual(element.attrib["formatter"], "etree")
379
self.failUnlessEqual(element.attrib["version"], version)
381
def testSaveProject(self):
382
video_stream = VideoStream(gst.Caps("video/x-raw-yuv"))
383
audio_stream = AudioStream(gst.Caps("audio/x-raw-int"))
384
source1 = VideoTestSourceFactory()
386
self.formatter._saveSource(source1)
387
self.formatter._saveStream(video_stream)
389
track_object = SourceTrackObject(source1, video_stream,
390
start=10 * gst.SECOND, duration=20 * gst.SECOND,
391
in_point=5 * gst.SECOND, media_duration=15 * gst.SECOND,
394
track = Track(video_stream)
395
track.addTrackObject(track_object)
397
self.formatter._saveTrackObject(track_object)
399
timeline_object = TimelineObject(source1)
400
timeline_object.addTrackObject(track_object)
402
self.formatter._saveTimelineObject(timeline_object)
404
timeline = Timeline()
405
timeline.addTrack(track)
407
self.formatter._saveTimeline(timeline)
410
project.timeline = timeline
411
project.sources.addFactory(source1)
413
element = self.formatter._serializeProject(project)
415
self.failUnlessEqual(element.tag, "pitivi")
416
self.failIfEqual(element.find("factories"), None)
417
self.failIfEqual(element.find("timeline"), None)
420
class TestFormatterLoad(TestCase):
422
self.formatter = FakeElementTreeFormatter(EffectsHandler())
424
def testLoadStream(self):
425
caps = gst.Caps("video/x-raw-yuv")
426
element = Element("stream")
427
element.attrib["id"] = "1"
428
element.attrib["type"] = "pitivi.stream.VideoStream"
429
element.attrib["caps"] = str(caps)
431
stream = self.formatter._loadStream(element)
432
self.failUnlessEqual(qual(stream.__class__), element.attrib["type"])
433
self.failUnlessEqual(str(stream.caps), str(caps))
434
self.failUnlessEqual(stream, self.formatter._context.streams["1"])
436
def testLoadTrackEffect(self):
437
# create fake document tree
438
element = Element("track-object",\
439
type="pitivi.timeline.track.TrackEffect",
440
start=ts(1 * gst.SECOND), duration=ts(10 * gst.SECOND),
441
in_point=ts(5 * gst.SECOND),
442
media_duration=ts(15 * gst.SECOND), priority=ts(5), id="1")
443
effect_elem = SubElement(element, "effect")
444
factory_elem = SubElement(effect_elem, "factory", name="identity")
445
properties_elem = SubElement(effect_elem, "gst-element-properties", sync="(bool)True")
447
# insert our fake factory into the context
448
stream = AudioStream(gst.Caps("audio/x-raw-int"))
449
factory = EffectFactory('identity')
450
factory.addInputStream(stream)
451
factory.addOutputStream(stream)
452
self.formatter.avalaible_effects._effect_factories_dict['identity'] = factory
454
track = Track(stream)
455
track_object = self.formatter._loadTrackObject(track, element)
456
self.failUnless(isinstance(track_object, TrackEffect))
457
self.failUnlessEqual(track_object.factory, factory)
458
self.failUnlessEqual(track_object.stream, stream)
460
self.failUnlessEqual(track_object.start, 1 * gst.SECOND)
461
self.failUnlessEqual(track_object.duration, 10 * gst.SECOND)
462
self.failUnlessEqual(track_object.in_point, 5 * gst.SECOND)
463
self.failUnlessEqual(track_object.media_duration, 15 * gst.SECOND)
464
self.failUnlessEqual(track_object.priority, 5)
466
def testLoadStreamRef(self):
467
stream = VideoStream(gst.Caps("meh"))
468
self.formatter._context.streams["1"] = stream
469
element = Element("stream-ref")
470
element.attrib["id"] = "1"
471
stream1 = self.formatter._loadStreamRef(element)
472
self.failUnlessEqual(stream, stream1)
474
def testLoadFactory(self):
475
element = Element("source")
476
element.attrib["id"] = "1"
477
element.attrib["type"] = "pitivi.factories.test.VideoTestSourceFactory"
478
element.attrib["duration"] = 5 * gst.SECOND
479
element.attrib["default_duration"] = 5 * gst.SECOND
480
output_streams = SubElement(element, "output-streams")
481
output_stream = SubElement(output_streams, "stream")
482
caps = gst.Caps("video/x-raw-yuv")
483
output_stream.attrib["id"] = "1"
484
output_stream.attrib["type"] = "pitivi.stream.VideoStream"
485
output_stream.attrib["caps"] = str(caps)
487
factory = self.formatter._loadFactory(element)
488
self.failUnless(isinstance(factory, VideoTestSourceFactory))
489
self.failUnlessEqual(len(factory.output_streams), 2)
491
self.failUnlessEqual(self.formatter._context.factories["1"], factory)
492
self.failUnlessEqual(factory.duration, 5 * gst.SECOND)
493
self.failUnlessEqual(factory.default_duration, 5 * gst.SECOND)
495
def testLoadFactoryRef(self):
499
self.formatter._context.factories["1"] = tag
500
element = Element("factory-ref", id="1")
501
ret = self.formatter._loadFactoryRef(element)
502
self.failUnless(ret is tag)
504
def testLoadTrackSource(self):
505
# create fake document tree
506
element = Element("track-object",
507
type="pitivi.timeline.track.SourceTrackObject",
508
start=ts(1 * gst.SECOND), duration=ts(10 * gst.SECOND),
509
in_point=ts(5 * gst.SECOND),
510
media_duration=ts(15 * gst.SECOND), priority=ts(5), id="1")
511
factory_ref = SubElement(element, "factory-ref", id="1")
512
stream_ref = SubElement(element, "stream-ref", id="1")
514
# insert our fake factory into the context
515
factory = AudioTestSourceFactory()
516
factory.duration = 10 * gst.SECOND
517
self.formatter._context.factories["1"] = factory
519
# insert fake stream into the context
520
stream = AudioStream(gst.Caps("audio/x-raw-int"))
521
self.formatter._context.streams["1"] = stream
524
curves = SubElement(element, "curves")
525
curve = SubElement(curves, "curve", property="volume",
527
expected = dict((long(t * gst.SECOND), (float(t % 2), gst.INTERPOLATE_LINEAR))
528
for t in xrange(1, 10))
529
start = SubElement(curve, "start", value="0.0", mode="2")
530
for time, (value, mode) in expected.iteritems():
531
SubElement(curve, "keyframe", time=str(time), value=str(value),
533
end = SubElement(curve, "end", value=str(10 % 2), mode="2")
535
track = Track(stream)
536
# point gun at foot; pull trigger
537
track_object = self.formatter._loadTrackObject(track, element)
538
self.failUnless(isinstance(track_object, SourceTrackObject))
539
self.failUnlessEqual(track_object.factory, factory)
540
self.failUnlessEqual(track_object.stream, stream)
542
self.failUnlessEqual(track_object.start, 1 * gst.SECOND)
543
self.failUnlessEqual(track_object.duration, 10 * gst.SECOND)
544
self.failUnlessEqual(track_object.in_point, 5 * gst.SECOND)
545
self.failUnlessEqual(track_object.media_duration, 15 * gst.SECOND)
546
self.failUnlessEqual(track_object.priority, 5)
548
self.failIfEqual(track_object.interpolators, None)
549
interpolator = track_object.getInterpolator("volume")
550
self.failIfEqual(interpolator, None)
551
curve = dict(((kf.time, (kf.value, kf.mode)) for kf in
552
interpolator.getInteriorKeyframes()))
553
self.failUnlessEqual(curve, expected)
555
self.failUnlessEqual(interpolator.start.value, 0.0)
556
self.failUnlessEqual(interpolator.start.time, 5 * gst.SECOND)
557
self.failUnlessEqual(interpolator.end.value, 0.0)
558
self.failUnlessEqual(interpolator.end.time, 15 * gst.SECOND)
560
def testLoadInterpolatorV0(self):
561
# create fake document tree
562
element = Element("track-object",
563
type="pitivi.timeline.track.SourceTrackObject",
564
start=ts(1 * gst.SECOND), duration=ts(15 * gst.SECOND),
565
in_point=ts(5 * gst.SECOND),
566
media_duration=ts(15 * gst.SECOND), priority=ts(5), id="1")
567
factory_ref = SubElement(element, "factory-ref", id="1")
568
stream_ref = SubElement(element, "stream-ref", id="1")
570
# insert our fake factory into the context
571
factory = AudioTestSourceFactory()
572
factory.duration = 20 * gst.SECOND
573
self.formatter._context.factories["1"] = factory
575
# insert fake stream into the context
576
stream = AudioStream(gst.Caps("audio/x-raw-int"))
577
self.formatter._context.streams["1"] = stream
580
curves = SubElement(element, "curves")
581
curve = SubElement(curves, "curve", property="volume")
582
expected = dict((long(t * gst.SECOND), (float(t % 2), gst.INTERPOLATE_LINEAR))
583
for t in xrange(6, 15))
584
start = SubElement(curve, "start", value="1.0", mode="2")
585
for time, (value, mode) in expected.iteritems():
586
SubElement(curve, "keyframe", time=str(time), value=str(value),
588
end = SubElement(curve, "end", value="1.0", mode="2")
590
track = Track(stream)
591
# point gun at foot; pull trigger
592
track_object = self.formatter._loadTrackObject(track, element)
593
self.failIfEqual(track_object.interpolators, None)
594
interpolator = track_object.getInterpolator("volume")
595
self.failIfEqual(interpolator, None)
596
curve = dict(((kf.time, (kf.value, kf.mode)) for kf in
597
interpolator.getInteriorKeyframes()))
598
self.failUnlessEqual(curve, expected)
600
# check that start keyframe value has been properly adjusted so as not
601
# to change the shape of the curve. rounding is applied here because
602
# the controller seems to round to a different precision
603
# than python. we just want to check that the value is "in the
604
# ballpark", indicating the keyframes have been updated. If you do the
605
# math you'll see that both start and end keyframe values should be
607
self.failUnlessEqual(
608
round(interpolator.start.value, 6),
609
round((-5.0 / 6) + 1, 6))
610
self.failUnlessEqual(interpolator.start.time, 5 * gst.SECOND)
612
# check that end keyrame value has been properly adjusted so as not to
613
# change the shape of the curve
614
self.failUnlessEqual(interpolator.end.time, 15 * gst.SECOND)
615
self.failUnlessEqual(
616
round(interpolator.end.value, 6),
617
round((15.0 / 6) - (7.0 / 3), 6))
619
def testLoadTrackObjectRef(self):
623
self.formatter._context.track_objects["1"] = tag
624
element = Element("track-object-ref", id="1")
625
ret = self.formatter._loadTrackObjectRef(element)
626
self.failUnless(ret is tag)
628
def testLoadTrack(self):
629
# create fake document tree
630
element = Element("track")
631
stream_element = SubElement(element, "stream", id="1",
632
type="pitivi.stream.VideoStream", caps="video/x-raw-rgb")
634
track_objects_element = SubElement(element, "track-objects")
635
track_object = SubElement(track_objects_element, "track-object",
636
type="pitivi.timeline.track.SourceTrackObject",
637
start=ts(1 * gst.SECOND), duration=ts(10 * gst.SECOND),
638
in_point=ts(5 * gst.SECOND),
639
media_duration=ts(15 * gst.SECOND), priority=ts(5), id="1")
640
factory_ref = SubElement(track_object, "factory-ref", id="1")
641
stream_ref = SubElement(track_object, "stream-ref", id="1")
643
# insert fake factories and streams into current context
644
factory = VideoTestSourceFactory()
645
self.formatter._context.factories["1"] = factory
646
stream = VideoStream(gst.Caps("video/x-raw-rgb"))
647
self.formatter._context.streams["1"] = stream
649
# point gun at foot; pull trigger
650
track = self.formatter._loadTrack(element)
652
self.failUnlessEqual(len(track.track_objects), 1)
653
# FIXME: this is an hack
654
self.failUnlessEqual(str(track.stream), str(stream))
656
def testLoadTimelineObject(self):
657
video_stream = VideoStream(gst.Caps("video/x-raw-yuv"))
658
source1 = VideoTestSourceFactory()
659
self.formatter._context.factories["1"] = source1
660
self.formatter._context.track_objects["1"] = SourceTrackObject(source1, video_stream)
662
element = Element("timeline-object")
663
factory_ref = SubElement(element, "factory-ref", id="1")
664
stream_ref = SubElement(element, "stream-ref", id="1")
665
track_object_refs = SubElement(element, "track-object-refs")
666
track_object_ref = SubElement(track_object_refs,
667
"track-object-ref", id="1")
670
self.formatter._loadTimelineObject(element)
672
self.failUnlessEqual(timeline_object.factory, source1)
673
self.failUnlessEqual(len(timeline_object.track_objects), 1)
675
def testLoadTimeline(self):
676
# we need a project for this to work
677
self.formatter.project = Project()
679
# create fake document tree
680
timeline_element = Element("timeline")
682
tracks_element = SubElement(timeline_element, "tracks")
683
track_element = SubElement(tracks_element, "track")
684
stream_element = SubElement(track_element, "stream", id="1",
685
type="pitivi.stream.VideoStream", caps="video/x-raw-rgb")
686
track_objects_element = SubElement(track_element, "track-objects")
687
track_object = SubElement(track_objects_element, "track-object",
688
type="pitivi.timeline.track.SourceTrackObject",
689
start=ts(1 * gst.SECOND), duration=ts(10 * gst.SECOND),
690
in_point=ts(5 * gst.SECOND),
691
media_duration=ts(15 * gst.SECOND), priority=ts(5), id="1")
692
factory_ref = SubElement(track_object, "factory-ref", id="1")
693
stream_ref = SubElement(track_object, "stream-ref", id="1")
694
timeline_objects_element = SubElement(timeline_element,
696
timeline_object_element = \
697
SubElement(timeline_objects_element, "timeline-object")
698
factory_ref = SubElement(timeline_object_element, "factory-ref", id="1")
699
stream_ref = SubElement(timeline_object_element, "stream-ref", id="1")
700
track_object_refs = SubElement(timeline_object_element, "track-object-refs")
701
track_object_ref = SubElement(track_object_refs,
702
"track-object-ref", id="1")
704
# insert fake streams and factories into context
705
factory = VideoTestSourceFactory()
706
self.formatter._context.factories["1"] = factory
707
stream = VideoStream(gst.Caps("video/x-raw-rgb"))
708
self.formatter._context.streams["1"] = stream
709
video_stream = VideoStream(gst.Caps("video/x-raw-yuv"))
710
source1 = VideoTestSourceFactory()
711
self.formatter._context.factories["2"] = source1
712
self.formatter._context.track_objects["1"] = SourceTrackObject(source1, video_stream)
714
# point gun at foot; pull trigger
715
self.formatter._loadTimeline(timeline_element)
716
self.failUnlessEqual(len(self.formatter.project.timeline.tracks), 1)
718
def testLoadProject(self):
719
video_stream = VideoStream(gst.Caps("video/x-raw-yuv"))
720
audio_stream = AudioStream(gst.Caps("audio/x-raw-int"))
721
source1 = VideoTestSourceFactory()
723
self.formatter._saveSource(source1)
724
self.formatter._saveStream(video_stream)
726
track_object = SourceTrackObject(source1, video_stream,
727
start=10 * gst.SECOND, duration=20 * gst.SECOND,
728
in_point=5 * gst.SECOND, media_duration=15 * gst.SECOND,
731
track = Track(video_stream)
732
track.addTrackObject(track_object)
734
self.formatter._saveTrackObject(track_object)
736
timeline_object = TimelineObject(source1)
737
timeline_object.addTrackObject(track_object)
739
self.formatter._saveTimelineObject(timeline_object)
741
timeline = Timeline()
742
timeline.addTrack(track)
744
self.formatter._saveTimeline(timeline)
747
project.timeline = timeline
748
project.sources.addFactory(source1)
750
element = self.formatter._serializeProject(project)
752
self.failUnlessEqual(element.tag, "pitivi")
753
self.failIfEqual(element.find("factories"), None)
754
self.failIfEqual(element.find("timeline"), None)
757
f = file("/tmp/untitled.pptv", "w")
758
f.write(tostring(element))
761
## following test is disabled until I figure out a better way of
762
## testing the mapping system.
763
# def testDirectoryMapping(self):
764
# pa = "file:///if/you/have/this/file/you/are/on/crack.avi"
765
# pb = "file:///I/really/mean/it/you/crack.avi"
767
# self.formatter.addMapping(pa,pb)
768
# self.assertEquals(self.formatter.validateSourceURI(pa),