1
# PiTiVi , Non-linear video editor
3
# tests/test_timeline.py
5
# Copyright (c) 2008,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.
24
from pitivi.factories.test import AudioTestSourceFactory
25
from pitivi.stream import AudioStream, VideoStream
26
from pitivi.timeline.timeline import Timeline, TimelineObject, TimelineError, \
27
Link, TimelineEdges, MoveContext, TrimStartContext, \
29
from pitivi.timeline.track import Track, SourceTrackObject, TrackEffect
30
from pitivi.utils import UNKNOWN_DURATION
32
from tests.common import FakeEffectFactory, FakeSourceFactory, \
33
SignalMonitor, StubFactory, TestCase
36
class TimelineSignalMonitor(SignalMonitor):
37
def __init__(self, track_object):
38
SignalMonitor.__init__(self, track_object, 'start-changed',
39
'duration-changed', 'in-point-changed', 'media-duration-changed')
42
class TestTimelineObjectAddRemoveTrackObjects(TestCase):
43
def testAddRemoveTrackObjects(self):
44
source_factory = StubFactory()
45
timeline_object1 = TimelineObject(source_factory)
46
timeline_object2 = TimelineObject(source_factory)
48
stream = AudioStream(gst.Caps('audio/x-raw-int'))
49
source_factory.addOutputStream(stream)
51
track_object1 = SourceTrackObject(source_factory, stream)
52
track_object2 = SourceTrackObject(source_factory, stream)
54
track.addTrackObject(track_object1)
55
timeline_object1.addTrackObject(track_object1)
58
self.failUnlessRaises(TimelineError,
59
timeline_object1.addTrackObject, track_object1)
61
# can't add to different timeline objects
62
self.failUnlessRaises(TimelineError,
63
timeline_object2.addTrackObject, track_object1)
65
track.addTrackObject(track_object2)
66
timeline_object1.addTrackObject(track_object2)
68
timeline_object1.removeTrackObject(track_object1)
71
self.failUnlessRaises(TimelineError,
72
timeline_object1.removeTrackObject, track_object1)
74
timeline_object1.removeTrackObject(track_object2)
77
class TestTimelineObjectProperties(TestCase):
80
source_factory = StubFactory()
81
self.timeline_object = TimelineObject(source_factory)
82
self.monitor = SignalMonitor(self.timeline_object, 'start-changed',
83
'duration-changed', 'in-point-changed', 'out-point-changed',
84
'media-duration-changed', 'priority-changed')
85
stream = AudioStream(gst.Caps('audio/x-raw-int'))
86
source_factory.addOutputStream(stream)
87
self.track = Track(stream)
88
self.track_object1 = SourceTrackObject(source_factory, stream)
89
self.track_object2 = SourceTrackObject(source_factory, stream)
90
self.track.addTrackObject(self.track_object1)
91
self.track.addTrackObject(self.track_object2)
94
self.track.removeTrackObject(self.track_object1)
95
self.track.removeTrackObject(self.track_object2)
97
del self.track_object1
98
del self.track_object2
100
del self.timeline_object
101
TestCase.tearDown(self)
103
def testDefaultProperties(self):
104
obj = self.timeline_object
105
self.failUnlessEqual(obj.start, 0)
106
self.failUnlessEqual(obj.duration, UNKNOWN_DURATION)
107
self.failUnlessEqual(obj.in_point, 0)
108
self.failUnlessEqual(obj.out_point, 0)
109
self.failUnlessEqual(obj.media_duration, UNKNOWN_DURATION)
110
self.failUnlessEqual(obj.priority, 0)
112
def testChangePropertiesFromTimelineObject(self):
113
timeline_object = self.timeline_object
114
self.track_object1 = self.track_object1
115
timeline_object.addTrackObject(self.track_object1)
117
start = 1 * gst.SECOND
118
timeline_object.start = start
119
self.failUnlessEqual(timeline_object.start, start)
120
self.failUnlessEqual(self.track_object1.start, start)
121
self.failUnlessEqual(self.monitor.start_changed_count, 1)
123
duration = 10 * gst.SECOND
124
timeline_object.duration = duration
125
self.failUnlessEqual(timeline_object.duration, duration)
126
self.failUnlessEqual(self.track_object1.duration, duration)
127
self.failUnlessEqual(self.monitor.duration_changed_count, 1)
129
in_point = 5 * gst.SECOND
130
timeline_object.in_point = in_point
131
self.failUnlessEqual(timeline_object.in_point, in_point)
132
self.failUnlessEqual(self.track_object1.in_point, in_point)
133
self.failUnlessEqual(self.monitor.in_point_changed_count, 1)
135
media_duration = 5 * gst.SECOND
136
timeline_object.media_duration = media_duration
137
self.failUnlessEqual(timeline_object.media_duration, media_duration)
138
self.failUnlessEqual(self.track_object1.media_duration, media_duration)
139
self.failUnlessEqual(self.monitor.media_duration_changed_count, 1)
140
self.failUnlessEqual(timeline_object.out_point,
141
in_point + media_duration)
142
self.failUnlessEqual(self.track_object1.out_point,
143
in_point + media_duration)
145
#self.failUnlessEqual(self.monitor.out_point_changed_count, 1)
148
timeline_object.priority = priority
149
self.failUnlessEqual(timeline_object.priority, priority)
150
self.failUnlessEqual(self.track_object1.priority, priority)
151
self.failUnlessEqual(self.monitor.priority_changed_count, 1)
153
def testChangePropertiesFromTimelineObject2(self):
154
timeline_object = self.timeline_object
155
self.track_object1 = self.track_object1
156
timeline_object.addTrackObject(self.track_object1)
157
timeline_object.addTrackObject(self.track_object2)
159
start = 1 * gst.SECOND
160
timeline_object.start = start
161
self.failUnlessEqual(timeline_object.start, start)
162
self.failUnlessEqual(self.track_object1.start, start)
163
self.failUnlessEqual(self.track_object2.start, start)
164
self.failUnlessEqual(self.monitor.start_changed_count, 1)
166
duration = 10 * gst.SECOND
167
timeline_object.duration = duration
168
self.failUnlessEqual(timeline_object.duration, duration)
169
self.failUnlessEqual(self.track_object1.duration, duration)
170
self.failUnlessEqual(self.track_object2.duration, duration)
171
self.failUnlessEqual(self.monitor.duration_changed_count, 1)
173
in_point = 5 * gst.SECOND
174
timeline_object.in_point = in_point
175
self.failUnlessEqual(timeline_object.in_point, in_point)
176
self.failUnlessEqual(self.track_object1.in_point, in_point)
177
self.failUnlessEqual(self.track_object2.in_point, in_point)
178
self.failUnlessEqual(self.monitor.in_point_changed_count, 1)
180
media_duration = 5 * gst.SECOND
181
timeline_object.media_duration = media_duration
182
self.failUnlessEqual(timeline_object.media_duration, media_duration)
183
self.failUnlessEqual(self.track_object1.media_duration, media_duration)
184
self.failUnlessEqual(self.track_object2.media_duration, media_duration)
185
self.failUnlessEqual(self.monitor.media_duration_changed_count, 1)
188
timeline_object.priority = priority
189
self.failUnlessEqual(timeline_object.priority, priority)
190
self.failUnlessEqual(self.track_object1.priority, priority)
191
self.failUnlessEqual(self.track_object2.priority, priority)
192
self.failUnlessEqual(self.monitor.priority_changed_count, 1)
194
def testChangePropertiesFromTrackObject(self):
195
timeline_object = self.timeline_object
196
track_object = self.track_object1
197
timeline_object.addTrackObject(track_object)
199
start = 1 * gst.SECOND
200
track_object.start = start
201
self.failUnlessEqual(timeline_object.start, start)
202
self.failUnlessEqual(self.monitor.start_changed_count, 1)
204
duration = 10 * gst.SECOND
205
track_object.duration = duration
206
self.failUnlessEqual(timeline_object.duration, duration)
207
self.failUnlessEqual(self.monitor.duration_changed_count, 1)
209
in_point = 5 * gst.SECOND
210
track_object.in_point = in_point
211
self.failUnlessEqual(timeline_object.in_point, in_point)
212
self.failUnlessEqual(self.monitor.in_point_changed_count, 1)
214
media_duration = 5 * gst.SECOND
215
track_object.media_duration = media_duration
216
self.failUnlessEqual(timeline_object.media_duration, media_duration)
217
self.failUnlessEqual(self.monitor.media_duration_changed_count, 1)
220
track_object.priority = priority
221
self.failUnlessEqual(timeline_object.priority, priority)
222
self.failUnlessEqual(self.monitor.priority_changed_count, 1)
225
obj = self.timeline_object
226
track_object = self.track_object1
227
obj.addTrackObject(track_object)
229
obj.start = 3 * gst.SECOND
230
obj.duration = 10 * gst.SECOND
232
monitor = TimelineSignalMonitor(obj)
234
self.failUnlessRaises(TimelineError, obj.split, 2 * gst.SECOND)
235
self.failUnlessRaises(TimelineError, obj.split, 14 * gst.SECOND)
237
# should these be possible (ie create empty objects) ?
238
self.failUnlessRaises(TimelineError, obj.split, 3 * gst.SECOND)
239
self.failUnlessRaises(TimelineError, obj.split, 13 * gst.SECOND)
241
# split at 4s should result in:
242
# obj (start 3, end 4) other1 (start 4, end 13)
243
other1 = obj.split(4 * gst.SECOND)
245
self.failUnlessEqual(obj.start, 3 * gst.SECOND)
246
self.failUnlessEqual(obj.duration, 1 * gst.SECOND)
248
self.failUnlessEqual(other1.start, 4 * gst.SECOND)
249
self.failUnlessEqual(other1.duration, 9 * gst.SECOND)
251
self.failUnlessEqual(monitor.start_changed_count, 0)
252
self.failUnlessEqual(monitor.duration_changed_count, 1)
255
monitor = TimelineSignalMonitor(other1)
257
other2 = other1.split(11 * gst.SECOND)
258
self.failUnlessEqual(other1.start, 4 * gst.SECOND)
259
self.failUnlessEqual(other1.duration, 7 * gst.SECOND)
261
self.failUnlessEqual(other2.start, 11 * gst.SECOND)
262
self.failUnlessEqual(other2.duration, 2 * gst.SECOND)
264
self.failUnlessEqual(monitor.start_changed_count, 0)
265
self.failUnlessEqual(monitor.duration_changed_count, 1)
268
class TestTimelineAddRemoveTracks(TestCase):
269
def testAddRemoveTracks(self):
270
stream = AudioStream(gst.Caps('audio/x-raw-int'))
271
track1 = Track(stream)
272
track2 = Track(stream)
274
timeline = Timeline()
276
timeline.addTrack(track1)
277
self.failUnlessRaises(TimelineError, timeline.addTrack, track1)
279
timeline.addTrack(track2)
281
timeline.removeTrack(track1)
282
self.failUnlessRaises(TimelineError, timeline.removeTrack, track1)
284
timeline.removeTrack(track2)
287
class TestTimelineAddRemoveTimelineObjects(TestCase):
288
def testAddRemoveTimelineObjects(self):
289
source_factory = StubFactory()
290
stream = AudioStream(gst.Caps('audio/x-raw-int'))
291
source_factory.addOutputStream(stream)
292
timeline = Timeline()
293
track = Track(stream)
295
track_object1 = SourceTrackObject(source_factory, stream)
296
track_object2 = SourceTrackObject(source_factory, stream)
297
track.addTrackObject(track_object1)
298
track.addTrackObject(track_object2)
300
timeline_object1 = TimelineObject(source_factory)
301
timeline_object2 = TimelineObject(source_factory)
303
self.failUnlessRaises(TimelineError,
304
timeline.addTimelineObject, timeline_object1)
306
timeline_object1.addTrackObject(track_object1)
307
timeline.addTimelineObject(timeline_object1)
309
self.failUnlessRaises(TimelineError,
310
timeline.addTimelineObject, timeline_object1)
312
timeline_object2.addTrackObject(track_object2)
313
timeline.addTimelineObject(timeline_object2)
315
timeline.removeTimelineObject(timeline_object1)
316
self.failUnlessRaises(TimelineError,
317
timeline.removeTimelineObject, timeline_object1)
319
timeline.removeTimelineObject(timeline_object2)
321
def testRemoveFactory(self):
322
source_factory = StubFactory()
323
stream = AudioStream(gst.Caps("audio/x-raw-int"))
324
source_factory.addOutputStream(stream)
325
track = Track(stream)
326
track_object1 = SourceTrackObject(source_factory, stream)
327
track.addTrackObject(track_object1)
328
track_object2 = SourceTrackObject(source_factory, stream)
329
track.addTrackObject(track_object2)
330
track_object3 = SourceTrackObject(source_factory, stream)
331
track.addTrackObject(track_object3)
332
timeline_object1 = TimelineObject(source_factory)
333
timeline_object1.addTrackObject(track_object1)
334
timeline_object2 = TimelineObject(source_factory)
335
timeline_object2.addTrackObject(track_object2)
336
timeline_object3 = TimelineObject(source_factory)
337
timeline_object3.addTrackObject(track_object3)
338
timeline = Timeline()
339
timeline.addTrack(track)
340
timeline.addTimelineObject(timeline_object1)
341
timeline.addTimelineObject(timeline_object2)
342
timeline.addTimelineObject(timeline_object3)
344
self.failUnlessEqual(len(timeline.timeline_objects), 3)
345
timeline.removeFactory(source_factory)
346
self.failUnlessEqual(len(timeline.timeline_objects), 0)
349
class TestTimelineAddRemoveEffectsTracks(TestCase):
350
def testAddRemoveEffectTracks(self):
351
stream = VideoStream(gst.Caps("video/x-raw-rgb"))
352
source_factory = StubFactory()
353
source_factory.addOutputStream(stream)
354
effect_factory = FakeEffectFactory()
355
effect_factory.addInputStream(stream)
356
effect_factory.addOutputStream(stream)
357
timeline = Timeline()
358
track = Track(stream)
360
track_effect1 = TrackEffect(effect_factory, stream)
361
track_effect2 = TrackEffect(effect_factory, stream)
363
track_object1 = SourceTrackObject(source_factory, stream)
364
track.addTrackObject(track_object1)
365
timeline_object1 = TimelineObject(source_factory)
366
timeline_object1.addTrackObject(track_object1)
367
timeline.addTimelineObject(timeline_object1)
369
track.addTrackObject(track_effect1)
370
timeline_object1.addTrackObject(track_effect1)
371
self.failUnlessRaises(TimelineError,
372
timeline_object1.addTrackObject, track_effect1)
373
track.addTrackObject(track_effect2)
374
timeline_object1.addTrackObject(track_effect2)
375
self.failUnlessRaises(TimelineError,
376
timeline_object1.addTrackObject, track_effect2)
378
timeline_object1.removeTrackObject(track_effect1)
379
self.failUnlessRaises(TimelineError,
380
timeline_object1.removeTrackObject, track_effect1)
381
timeline_object1.removeTrackObject(track_effect2)
382
self.failUnlessRaises(TimelineError,
383
timeline_object1.removeTrackObject, track_effect2)
385
track.removeTrackObject(track_effect1)
386
track.removeTrackObject(track_effect2)
387
timeline.removeTimelineObject(timeline_object1)
389
def testRemoveEffectFactory(self):
390
effect_factory = FakeEffectFactory()
391
stream = AudioStream(gst.Caps("audio/x-raw-int"))
392
effect_factory.addInputStream(stream)
393
effect_factory.addOutputStream(stream)
394
track = Track(stream)
395
track_effect1 = TrackEffect(effect_factory, stream)
396
track.addTrackObject(track_effect1)
397
track_effect2 = TrackEffect(effect_factory, stream)
398
track.addTrackObject(track_effect2)
399
track_effect3 = TrackEffect(effect_factory, stream)
400
track.addTrackObject(track_effect3)
401
timeline_object1 = TimelineObject(effect_factory)
402
timeline_object1.addTrackObject(track_effect1)
403
timeline_object1.addTrackObject(track_effect2)
404
timeline_object1.addTrackObject(track_effect3)
405
timeline = Timeline()
406
timeline.addTrack(track)
407
timeline.addTimelineObject(timeline_object1)
409
self.failUnlessEqual(len(timeline_object1.track_objects), 3)
410
self.failUnlessEqual(len(timeline.timeline_objects), 1)
411
self.failUnlessEqual(len(track.track_objects), 3)
412
timeline.removeFactory(effect_factory)
413
self.failUnlessEqual(len(track.track_objects), 0)
414
self.failUnlessEqual(len(timeline.timeline_objects), 0)
417
class TestTimeline(TestCase):
419
self.source_factory = StubFactory()
420
self.stream = AudioStream(gst.Caps('audio/x-raw-int'))
421
self.source_factory.addOutputStream(self.stream)
422
self.track1 = Track(self.stream)
423
self.timeline = Timeline()
427
del self.source_factory
432
def makeTimelineObject(self):
433
track_object = SourceTrackObject(self.source_factory, self.stream)
434
self.track1.addTrackObject(track_object)
435
timeline_object = TimelineObject(self.source_factory)
436
timeline_object.addTrackObject(track_object)
437
self.timeline.addTimelineObject(timeline_object)
439
return timeline_object
441
def testGetPreviousTimelineObject(self):
442
timeline_object1 = self.makeTimelineObject()
443
timeline_object2 = self.makeTimelineObject()
444
timeline_object3 = self.makeTimelineObject()
445
timeline_object4 = self.makeTimelineObject()
447
timeline_object1.start = 1 * gst.SECOND
448
timeline_object1.duration = 5 * gst.SECOND
449
timeline_object1.priority = 1
451
timeline_object2.start = 8 * gst.SECOND
452
timeline_object2.duration = 5 * gst.SECOND
453
timeline_object2.priority = 1
455
timeline_object3.start = 6 * gst.SECOND
456
timeline_object3.duration = 5 * gst.SECOND
457
timeline_object3.priority = 2
459
timeline_object4.start = 7 * gst.SECOND
460
timeline_object4.duration = 5 * gst.SECOND
461
timeline_object4.priority = 3
463
timeline = self.timeline
465
# no previous track_objectect
466
self.failUnlessRaises(TimelineError,
467
timeline.getPreviousTimelineObject, timeline_object4)
470
prev = timeline.getPreviousTimelineObject(timeline_object2)
471
self.failUnlessEqual(prev, timeline_object1)
474
prev = timeline.getPreviousTimelineObject(timeline_object2, priority=2)
475
self.failUnlessEqual(prev, timeline_object3)
478
prev = timeline.getPreviousTimelineObject(timeline_object2, priority=None)
479
self.failUnlessEqual(prev, timeline_object4)
481
def testGetPreviousTimelineObjectSameStart(self):
482
timeline_object1 = self.makeTimelineObject()
483
timeline_object2 = self.makeTimelineObject()
484
timeline = self.timeline
486
timeline_object1.start = 1 * gst.SECOND
487
timeline_object1.duration = 5 * gst.SECOND
488
timeline_object1.priority = 1
490
timeline_object2.start = 1 * gst.SECOND
491
timeline_object2.duration = 5 * gst.SECOND
492
timeline_object2.priority = 2
494
self.failUnlessRaises(TimelineError,
495
timeline.getPreviousTimelineObject, timeline_object1)
496
self.failUnlessRaises(TimelineError,
497
timeline.getPreviousTimelineObject, timeline_object2)
499
prev = timeline.getPreviousTimelineObject(timeline_object2, priority=None)
500
self.failUnlessEqual(prev, timeline_object1)
502
prev = timeline.getPreviousTimelineObject(timeline_object1, priority=None)
503
self.failUnlessEqual(prev, timeline_object2)
505
def testGetNextTrackObject(self):
506
timeline_object1 = self.makeTimelineObject()
507
timeline_object2 = self.makeTimelineObject()
508
timeline_object3 = self.makeTimelineObject()
509
timeline_object4 = self.makeTimelineObject()
511
timeline_object1.start = 1 * gst.SECOND
512
timeline_object1.duration = 5 * gst.SECOND
513
timeline_object1.priority = 1
515
timeline_object2.start = 8 * gst.SECOND
516
timeline_object2.duration = 5 * gst.SECOND
517
timeline_object2.priority = 1
519
timeline_object3.start = 6 * gst.SECOND
520
timeline_object3.duration = 5 * gst.SECOND
521
timeline_object3.priority = 2
523
timeline_object4.start = 7 * gst.SECOND
524
timeline_object4.duration = 5 * gst.SECOND
525
timeline_object4.priority = 3
527
timeline = self.timeline
529
# no next timeline_objectect
530
self.failUnlessRaises(TimelineError, timeline.getNextTimelineObject, timeline_object2)
533
prev = timeline.getNextTimelineObject(timeline_object1)
534
self.failUnlessEqual(prev, timeline_object2)
537
prev = timeline.getNextTimelineObject(timeline_object1, priority=2)
538
self.failUnlessEqual(prev, timeline_object3)
541
prev = timeline.getNextTimelineObject(timeline_object3, priority=None)
542
self.failUnlessEqual(prev, timeline_object4)
544
def testGetObjsAtTime(self):
545
# we're going use this time as our test time
547
time2 = 3 * gst.SECOND
548
time3 = 6 * gst.SECOND
549
time4 = 10 * gst.SECOND
551
clip1 = self.makeTimelineObject()
552
clip1.start = 2 * gst.SECOND
553
clip1.duration = 5 * gst.SECOND
555
# clip2 -- overlaps left edge of clip1
556
clip2 = self.makeTimelineObject()
557
clip2.start = 1 * gst.SECOND
558
clip2.duration = 4 * gst.SECOND
560
# clip 3 -- overlaps right edge of clip1
561
clip3 = self.makeTimelineObject()
562
clip3.start = long(2.5 * gst.SECOND)
563
clip3.duration = 5 * gst.SECOND
565
# clip 4 -- doesn't overlap at all
566
clip4 = self.makeTimelineObject()
567
clip4.start = 10 * gst.SECOND
568
clip4.duration = 4 * gst.SECOND
570
result = set(self.timeline.getObjsAtTime(time1))
571
self.failUnlessEqual(result, set())
573
result = set(self.timeline.getObjsAtTime(time2))
574
self.failUnlessEqual(result, set((clip1, clip2, clip3)))
576
result = set(self.timeline.getObjsAtTime(time3))
577
self.failUnlessEqual(result, set((clip1, clip3)))
579
result = set(self.timeline.getObjsAtTime(time4))
580
self.failUnlessEqual(result, set())
582
def testSplitSelection(self):
583
# we're going use this time as our test time
584
noclips = 7 * gst.SECOND
585
oneclip = long(6.5 * gst.SECOND)
586
threeclips = long(4.5 * gst.SECOND)
587
fourclipsoneselected = long(2.5 * gst.SECOND)
589
clip1 = self.makeTimelineObject()
590
clip1.start = 2 * gst.SECOND
591
clip1.duration = 5 * gst.SECOND
593
clip2 = self.makeTimelineObject()
594
clip2.start = 2 * gst.SECOND
595
clip2.duration = 4 * gst.SECOND
597
clip3 = self.makeTimelineObject()
598
clip3.start = 2 * gst.SECOND
599
clip3.duration = 3 * gst.SECOND
601
clip4 = self.makeTimelineObject()
602
clip4.start = 2 * gst.SECOND
603
clip4.duration = 2 * gst.SECOND
605
# test split no clips
606
self.timeline.split(noclips)
607
for i, clip in enumerate([clip1, clip2, clip3, clip4]):
608
self.failUnlessEqual(clip.start, 2 * gst.SECOND)
609
self.failUnlessEqual(clip.duration,
610
(5 - i) * gst.SECOND)
612
# test split one clip
613
self.timeline.split(oneclip)
614
self.failUnlessEqual(clip1.start, 2 * gst.SECOND)
615
self.failUnlessEqual(clip1.duration, oneclip - 2 * gst.SECOND)
616
for i, clip in enumerate([clip2, clip3, clip4]):
617
self.failUnlessEqual(clip.start, 2 * gst.SECOND)
618
self.failUnlessEqual(clip.duration,
619
(5 - (i + 1)) * gst.SECOND)
621
# test split three clips
622
self.timeline.split(threeclips)
623
for i, clip in enumerate([clip1, clip2, clip3]):
624
self.failUnlessEqual(clip.start, 2 * gst.SECOND)
625
self.failUnlessEqual(clip.start + clip.duration, threeclips)
626
self.failUnlessEqual(clip4.start, 2 * gst.SECOND)
627
self.failUnlessEqual(clip4.duration, 2 * gst.SECOND)
629
# test split three clips, one selected
630
self.timeline.selection.selected = set((clip4,))
631
self.timeline.split(fourclipsoneselected)
632
for i, clip in enumerate([clip1, clip2, clip3]):
633
self.failUnlessEqual(clip.start, 2 * gst.SECOND)
634
self.failUnlessEqual(clip.start + clip.duration, threeclips)
635
self.failUnlessEqual(clip4.start, 2 * gst.SECOND)
636
self.failUnlessEqual(clip4.duration + clip4.start,
637
fourclipsoneselected)
639
def testGetObjs(self):
640
obj1 = self.makeTimelineObject()
641
obj2 = self.makeTimelineObject()
642
obj3 = self.makeTimelineObject()
643
obj4 = self.makeTimelineObject()
645
obj1.start = 0 * gst.SECOND
646
obj1.duration = 5 * gst.SECOND
649
obj2.start = 5 * gst.SECOND
650
obj2.duration = 5 * gst.SECOND
653
obj3.start = 8 * gst.SECOND
654
obj3.duration = 5 * gst.SECOND
657
obj4.start = 15 * gst.SECOND
658
obj4.duration = 5 * gst.SECOND
661
timeline = self.timeline
663
time1 = 0 * gst.SECOND
664
time2 = 5 * gst.SECOND
665
time3 = 9 * gst.SECOND
666
time4 = 14 * gst.SECOND
669
# Objects before time.
671
result = timeline.getObjsBeforeTime(time1)
672
self.failUnlessEqual(result, tmp_obj_list)
673
tmp_obj_list = [obj1]
674
result = timeline.getObjsBeforeTime(time2)
675
self.failUnlessEqual(result, tmp_obj_list)
676
tmp_obj_list = [obj1]
677
result = timeline.getObjsBeforeTime(time3)
678
self.failUnlessEqual(result, tmp_obj_list)
679
tmp_obj_list = [obj1, obj2, obj3]
680
result = timeline.getObjsBeforeTime(time4)
681
self.failUnlessEqual(result, tmp_obj_list)
683
# Objects after time.
684
tmp_obj_list = [obj1, obj2, obj3, obj4]
685
result = timeline.getObjsAfterTime(time1)
686
self.failUnlessEqual(result, tmp_obj_list)
687
tmp_obj_list = [obj2, obj3, obj4]
688
result = timeline.getObjsAfterTime(time2)
689
self.failUnlessEqual(result, tmp_obj_list)
690
tmp_obj_list = [obj4]
691
result = timeline.getObjsAfterTime(time3)
692
self.failUnlessEqual(result, tmp_obj_list)
693
tmp_obj_list = [obj4]
694
result = timeline.getObjsAfterTime(time4)
695
self.failUnlessEqual(result, tmp_obj_list)
699
result = timeline.getObjsAtTime(time1)
700
self.failUnlessEqual(result, tmp_obj_list)
702
result = timeline.getObjsAtTime(time2)
703
self.failUnlessEqual(result, tmp_obj_list)
704
tmp_obj_list = [obj2, obj3]
705
result = timeline.getObjsAtTime(time3)
706
self.failUnlessEqual(result, tmp_obj_list)
708
result = timeline.getObjsAtTime(time4)
709
self.failUnlessEqual(result, tmp_obj_list)
712
tmp_obj_list = [obj1]
713
result = timeline.getObjsInRegion(time1, time2)
714
self.failUnlessEqual(result, tmp_obj_list)
716
result = timeline.getObjsInRegion(time3, time4)
717
self.failUnlessEqual(result, tmp_obj_list)
718
tmp_obj_list = [obj3]
719
result = timeline.getObjsInRegion(time1, time4, \
720
min_priority=3, max_priority=4)
721
self.failUnlessEqual(result, tmp_obj_list)
723
def testGetKeyframe(self):
724
timeline_object0 = self.makeTimelineObject()
725
timeline_object1 = self.makeTimelineObject()
726
timeline_object3 = self.makeTimelineObject()
728
timeline_object0.start = 0 * gst.SECOND
729
timeline_object0.duration = 1 * gst.SECOND
730
timeline_object0.priority = 0
732
timeline_object1.start = 1 * gst.SECOND
733
timeline_object1.duration = 5 * gst.SECOND
734
timeline_object1.priority = 1
736
timeline_object3.start = 15 * gst.SECOND
737
timeline_object3.duration = 5 * gst.SECOND
738
timeline_object3.priority = 2
740
factory = AudioTestSourceFactory()
741
stream = AudioStream(gst.Caps("audio/x-raw-int"))
742
track_object = SourceTrackObject(factory, stream)
743
self.track1.addTrackObject(track_object)
744
timeline_object2 = TimelineObject(factory)
745
timeline_object2.addTrackObject(track_object)
746
self.timeline.addTimelineObject(timeline_object2)
747
timeline_object2.start = 3 * gst.SECOND
748
timeline_object2.duration = 10 * gst.SECOND
749
timeline_object2.priority = 1
751
interpolator = track_object.getInterpolator("volume")
752
keyframe_position = 7 * gst.SECOND - timeline_object2.start
753
interpolator.newKeyframe(keyframe_position, 0.0, "mode")
755
timeline = self.timeline
758
time2 = 0.5 * gst.SECOND
759
time3 = 2 * gst.SECOND
760
time4 = 6.5 * gst.SECOND
761
time5 = 10 * gst.SECOND
762
time6 = 14 * gst.SECOND
763
time7 = 25 * gst.SECOND
765
result = timeline.getPrevKeyframe(time1)
766
self.failUnlessEqual(result, None)
767
result = timeline.getPrevKeyframe(time2)
768
self.failUnlessEqual(result, 0 * gst.SECOND)
769
result = timeline.getPrevKeyframe(time3)
770
self.failUnlessEqual(result, 1 * gst.SECOND)
771
result = timeline.getPrevKeyframe(time4)
772
self.failUnlessEqual(result, 6 * gst.SECOND)
773
result = timeline.getPrevKeyframe(time5)
774
self.failUnlessEqual(result, 7 * gst.SECOND)
775
result = timeline.getPrevKeyframe(time6)
776
self.failUnlessEqual(result, 13 * gst.SECOND)
777
result = timeline.getPrevKeyframe(time7)
778
self.failUnlessEqual(result, 20 * gst.SECOND)
780
result = timeline.getNextKeyframe(time1)
781
self.failUnlessEqual(result, 1 * gst.SECOND)
782
result = timeline.getNextKeyframe(time2)
783
self.failUnlessEqual(result, 1 * gst.SECOND)
784
result = timeline.getNextKeyframe(time3)
785
self.failUnlessEqual(result, 3 * gst.SECOND)
786
result = timeline.getNextKeyframe(time4)
787
self.failUnlessEqual(result, 7 * gst.SECOND)
788
result = timeline.getNextKeyframe(time5)
789
self.failUnlessEqual(result, 13 * gst.SECOND)
790
result = timeline.getNextKeyframe(time6)
791
self.failUnlessEqual(result, 15 * gst.SECOND)
792
result = timeline.getNextKeyframe(time7)
793
self.failUnlessEqual(result, None)
795
other_object2 = timeline_object2.split(8 * gst.SECOND)
796
timeline_object2.start = 5 * gst.SECOND
797
other_object2.start = 7 * gst.SECOND
798
time1 = 7 * gst.SECOND
799
time2 = 10 * gst.SECOND
800
result = timeline.getNextKeyframe(time1)
801
self.failUnlessEqual(result, 9 * gst.SECOND)
802
result = timeline.getNextKeyframe(time2)
803
self.failUnlessEqual(result, 12 * gst.SECOND)
805
position = 8.5 * gst.SECOND
806
interpolator = other_object2.track_objects[0].getInterpolator("volume")
807
interpolator.newKeyframe(position)
808
result = timeline.getNextKeyframe(time2)
809
self.failUnlessEqual(result, 10.5 * gst.SECOND)
812
class TestLink(TestCase):
817
def testAddRemoveTimelineObjects(self):
818
source_factory = StubFactory()
819
source_factory.addOutputStream(VideoStream(gst.Caps("video/x-raw-yuv")))
820
timeline_object1 = TimelineObject(source_factory)
821
timeline_object2 = TimelineObject(source_factory)
824
link.addTimelineObject(timeline_object1)
825
self.failUnlessRaises(TimelineError,
826
link.addTimelineObject, timeline_object1)
828
link.addTimelineObject(timeline_object2)
830
link.removeTimelineObject(timeline_object1)
831
self.failUnlessRaises(TimelineError,
832
link.removeTimelineObject, timeline_object1)
834
link.removeTimelineObject(timeline_object2)
838
self.source_factory = StubFactory()
839
self.stream = AudioStream(gst.Caps('audio/x-raw-int'))
840
self.source_factory.addOutputStream(self.stream)
841
self.track1 = Track(self.stream)
842
self.track2 = Track(self.stream)
843
self.track_object1 = SourceTrackObject(self.source_factory, self.stream)
844
self.track_object2 = SourceTrackObject(self.source_factory, self.stream)
845
self.track_object3 = SourceTrackObject(self.source_factory, self.stream)
846
self.track1.addTrackObject(self.track_object1)
847
self.track1.addTrackObject(self.track_object2)
848
self.track2.addTrackObject(self.track_object3)
849
self.timeline_object1 = TimelineObject(self.source_factory)
850
self.timeline_object1.addTrackObject(self.track_object1)
851
self.timeline_object2 = TimelineObject(self.source_factory)
852
self.timeline_object2.addTrackObject(self.track_object2)
853
self.timeline_object3 = TimelineObject(self.source_factory)
854
self.timeline_object3.addTrackObject(self.track_object3)
857
self.timeline_object3.removeTrackObject(self.track_object3)
858
self.timeline_object2.removeTrackObject(self.track_object2)
859
self.timeline_object1.removeTrackObject(self.track_object1)
860
self.track1.removeTrackObject(self.track_object1)
861
self.track1.removeTrackObject(self.track_object2)
862
self.track2.removeTrackObject(self.track_object3)
863
del self.timeline_object3
864
del self.timeline_object2
865
del self.timeline_object1
866
del self.track_object1
867
del self.track_object2
868
del self.track_object3
872
del self.source_factory
873
TestCase.tearDown(self)
875
def testLinkAttribute(self):
876
timeline_object1 = self.timeline_object1
877
timeline_object2 = self.timeline_object2
878
timeline_object3 = self.timeline_object3
880
self.failUnlessEqual(timeline_object1.link, None)
881
self.failUnlessEqual(timeline_object2.link, None)
882
self.failUnlessEqual(timeline_object3.link, None)
885
link.addTimelineObject(timeline_object1)
886
link.addTimelineObject(timeline_object2)
887
link.addTimelineObject(timeline_object3)
890
self.failUnlessRaises(TimelineError,
891
link2.addTimelineObject, timeline_object1)
893
self.failIfEqual(timeline_object1.link, None)
894
self.failIfEqual(timeline_object2.link, None)
895
self.failIfEqual(timeline_object3.link, None)
897
link.removeTimelineObject(timeline_object1)
898
self.failUnlessEqual(timeline_object1.link, None)
900
link.removeTimelineObject(timeline_object2)
901
self.failUnlessEqual(timeline_object2.link, None)
903
link.removeTimelineObject(timeline_object3)
904
self.failUnlessEqual(timeline_object3.link, None)
906
def testLinkJoin(self):
907
timeline_object1 = self.timeline_object1
908
timeline_object2 = self.timeline_object2
909
timeline_object3 = self.timeline_object3
912
link1.addTimelineObject(timeline_object1)
913
link1.addTimelineObject(timeline_object2)
916
link2.addTimelineObject(timeline_object3)
918
self.failUnlessEqual(timeline_object1.link, link1)
919
self.failUnlessEqual(timeline_object2.link, link1)
920
self.failUnlessEqual(timeline_object3.link, link2)
922
link3 = link1.join(link2)
923
self.failUnlessEqual(timeline_object1.link, link3)
924
self.failUnlessEqual(timeline_object2.link, link3)
925
self.failUnlessEqual(timeline_object3.link, link3)
927
def testChangeStart(self):
928
source_factory = self.source_factory
932
track_object1 = self.track_object1
933
track_object2 = self.track_object2
934
track_object3 = self.track_object3
936
timeline_object1 = self.timeline_object1
937
timeline_object2 = self.timeline_object2
938
timeline_object3 = self.timeline_object3
941
link.addTimelineObject(timeline_object1)
942
link.addTimelineObject(timeline_object2)
944
self.failUnlessEqual(timeline_object1.start, 0)
945
self.failUnlessEqual(timeline_object2.start, 0)
948
start = 3 * gst.SECOND
949
timeline_object1.start = start
950
self.failUnlessEqual(timeline_object1.start, start)
951
self.failUnlessEqual(timeline_object2.start, start)
954
start = 2 * gst.SECOND
955
timeline_object2.start = start
956
self.failUnlessEqual(timeline_object1.start, start)
957
self.failUnlessEqual(timeline_object2.start, start)
959
# add a third object (on a different track)
960
timeline_object3.start = 10 * gst.SECOND
961
link.addTimelineObject(timeline_object3)
963
# move start from 2 to 4, this should shift timeline_object3 from 10 to
965
start = 4 * gst.SECOND
966
timeline_object2.start = start
967
self.failUnlessEqual(timeline_object1.start, start)
968
self.failUnlessEqual(timeline_object2.start, start)
969
self.failUnlessEqual(timeline_object3.start, 12 * gst.SECOND)
971
# try to move timeline_object3 5 seconds back (to 7s). It should
972
# actually stop the move to 8s so that timeline_object1 and
973
# timeline_object2 don't go < 0s.
974
start = 7 * gst.SECOND
975
timeline_object3.start = start
976
self.failUnlessEqual(timeline_object1.start, 0)
977
self.failUnlessEqual(timeline_object2.start, 0)
978
self.failUnlessEqual(timeline_object3.start, 8 * gst.SECOND)
980
# unlink timeline_object1 and move it back to start = 1
981
link.removeTimelineObject(timeline_object1)
982
timeline_object1.start = 1 * gst.SECOND
983
self.failUnlessEqual(timeline_object1.start, 1 * gst.SECOND)
984
self.failUnlessEqual(timeline_object2.start, 0)
985
self.failUnlessEqual(timeline_object3.start, 8 * gst.SECOND)
988
class TestTimelineEdges(TestCase):
991
self.timeline_edges = TimelineEdges()
993
def testRemove(self):
994
self.timeline_edges.addStartEnd(0, 2000)
995
self.timeline_edges.removeStartEnd(0, 2000)
997
def testRemoveNotExisting(self):
998
self.failUnlessRaises(TimelineError,
999
self.timeline_edges.removeStartEnd, 1, 2000)
1001
self.timeline_edges.addStartEnd(0, 2000)
1002
self.failUnlessRaises(TimelineError,
1003
self.timeline_edges.removeStartEnd, 1, 2000)
1004
self.failUnlessRaises(TimelineError,
1005
self.timeline_edges.removeStartEnd, 0, 2001)
1007
def testNoEdges(self):
1008
self.failUnlessEqual(self.timeline_edges.snapToEdge(500, 1000), (500, 0))
1010
def testSimple(self):
1011
self.timeline_edges.addStartEnd(0, 2000)
1012
self.failUnlessEqual(self.timeline_edges.snapToEdge(500, 1000), (0, 500))
1014
self.timeline_edges.removeStartEnd(0, 2000)
1015
self.failUnlessEqual(self.timeline_edges.snapToEdge(500, 1000), (500, 0))
1017
def testSamePosition(self):
1018
self.timeline_edges.addStartEnd(0, 2000)
1019
self.timeline_edges.addStartEnd(0, 2000)
1021
self.failUnlessEqual(self.timeline_edges.snapToEdge(500, 1000), (0, 500))
1023
self.timeline_edges.removeStartEnd(0, 2000)
1025
self.failUnlessEqual(self.timeline_edges.snapToEdge(500, 1000), (0, 500))
1027
self.timeline_edges.removeStartEnd(0, 2000)
1029
self.failUnlessEqual(self.timeline_edges.snapToEdge(500, 1000), (500, 0))
1031
def testSnapStart(self):
1032
self.timeline_edges = TimelineEdges()
1034
self.timeline_edges.addStartEnd(1000, 2000)
1037
self.failUnlessEqual(self.timeline_edges.snapToEdge(900, 1400), (1000, 100))
1040
self.failUnlessEqual(self.timeline_edges.snapToEdge(1000, 1999), (1000, 0))
1043
self.failUnlessEqual(self.timeline_edges.snapToEdge(1200, 1400), (1000, 200))
1046
self.failUnlessEqual(self.timeline_edges.snapToEdge(1600, 1999), (1601, 1))
1049
self.failUnlessEqual(self.timeline_edges.snapToEdge(1001, 2000), (1001, 0))
1052
self.failUnlessEqual(self.timeline_edges.snapToEdge(2100, 3000), (2000, 100))
1054
# match both start and end, start is returned
1055
self.failUnlessEqual(self.timeline_edges.snapToEdge(1000, 2000), (1000, 0))
1057
def testSnapDuration(self):
1058
self.timeline_edges.addStartEnd(1000, 2000)
1061
self.failUnlessEqual(self.timeline_edges.snapToEdge(900), (1000, 100))
1064
self.failUnlessEqual(self.timeline_edges.snapToEdge(1000), (1000, 0))
1067
self.failUnlessEqual(self.timeline_edges.snapToEdge(1200), (1000, 200))
1070
self.failUnlessEqual(self.timeline_edges.snapToEdge(1999), (2000, 1))
1073
self.failUnlessEqual(self.timeline_edges.snapToEdge(2000), (2000, 0))
1076
self.failUnlessEqual(self.timeline_edges.snapToEdge(3000), (2000, 1000))
1078
def testAdjacenctObjs(self):
1079
source_factory = FakeSourceFactory()
1080
stream = AudioStream(gst.Caps("meh"))
1081
track_object1 = SourceTrackObject(source_factory, stream)
1082
track_object2 = SourceTrackObject(source_factory, stream)
1083
track_object1.start = 500
1084
track_object1.duration = 500
1085
track_object2.start = 1000
1086
track_object2.duration = 500
1087
self.timeline_edges.addTrackObject(track_object1)
1088
self.timeline_edges.addTrackObject(track_object2)
1089
self.assertEquals(self.timeline_edges.getObjsIncidentOnTime(1000),
1090
[track_object1, track_object2])
1091
self.assertEquals(self.timeline_edges.getObjsAdjacentToStart(track_object2),
1093
self.assertEquals(self.timeline_edges.getObjsAdjacentToEnd(track_object1),
1096
self.timeline_edges.removeTrackObject(track_object2)
1097
self.assertEquals(self.timeline_edges.getObjsIncidentOnTime(1000),
1100
self.timeline_edges.removeTrackObject(track_object1)
1101
self.assertEquals(self.timeline_edges.getObjsIncidentOnTime(1000), [])
1103
track_object1.release()
1104
track_object2.release()
1108
class TestTimelineAddFactory(TestCase):
1110
TestCase.setUp(self)
1111
self.audio_stream1 = AudioStream(gst.Caps('audio/x-raw-int'))
1112
self.audio_stream2 = AudioStream(gst.Caps('audio/x-raw-int'))
1113
self.audio_stream3 = AudioStream(gst.Caps('audio/x-raw-int'))
1114
self.video_stream1 = VideoStream(gst.Caps('video/x-raw-rgb'))
1115
self.video_stream2 = VideoStream(gst.Caps('video/x-raw-rgb'))
1116
self.audio_track1 = Track(self.audio_stream1)
1117
self.audio_track2 = Track(self.audio_stream2)
1118
self.video_track1 = Track(self.video_stream1)
1119
self.video_track2 = Track(self.video_stream2)
1120
self.timeline = Timeline()
1121
self.timeline.addTrack(self.audio_track1)
1122
self.timeline.addTrack(self.audio_track2)
1123
self.timeline.addTrack(self.video_track1)
1124
self.timeline.addTrack(self.video_track2)
1126
self.source_factory = StubFactory()
1127
self.effect_factory = FakeEffectFactory()
1130
del self.audio_stream1
1131
del self.audio_stream2
1132
del self.audio_stream3
1133
del self.video_stream1
1134
del self.video_stream2
1135
del self.audio_track1
1136
del self.audio_track2
1137
del self.video_track1
1138
del self.video_track2
1140
del self.source_factory
1141
del self.effect_factory
1142
TestCase.tearDown(self)
1144
def testNoStreams(self):
1145
self.failUnlessRaises(TimelineError, self.timeline.addSourceFactory, self.source_factory)
1147
def testAudioOnly(self):
1148
self.source_factory.addOutputStream(self.audio_stream1)
1149
self.timeline.addSourceFactory(self.source_factory)
1150
self.failUnlessEqual(len(self.audio_track1.track_objects), 1)
1151
self.failUnlessEqual(len(self.audio_track2.track_objects), 0)
1152
self.failUnlessEqual(len(self.video_track1.track_objects), 0)
1153
self.failUnlessEqual(len(self.video_track2.track_objects), 0)
1155
def testVideoOnly(self):
1156
self.source_factory.addOutputStream(self.video_stream1)
1157
self.timeline.addSourceFactory(self.source_factory)
1158
self.failUnlessEqual(len(self.audio_track1.track_objects), 0)
1159
self.failUnlessEqual(len(self.audio_track2.track_objects), 0)
1160
self.failUnlessEqual(len(self.video_track1.track_objects), 1)
1161
self.failUnlessEqual(len(self.video_track2.track_objects), 0)
1163
def testVideoStreamVideoEffect(self):
1164
self.source_factory.addOutputStream(self.video_stream1)
1165
self.timeline.addSourceFactory(self.source_factory)
1166
self.effect_factory.addInputStream(self.video_stream1)
1167
self.effect_factory.addOutputStream(self.video_stream2)
1168
self.timeline.addEffectFactoryOnObject(self.effect_factory, self.timeline.timeline_objects)
1169
self.failUnlessEqual(len(self.audio_track1.track_objects), 0)
1170
self.failUnlessEqual(len(self.audio_track2.track_objects), 0)
1171
self.failUnlessEqual(len(self.video_track1.track_objects), 2)
1172
self.failUnlessEqual(len(self.video_track2.track_objects), 0)
1174
def testAudioStreamAudioEffect(self):
1175
self.source_factory.addOutputStream(self.audio_stream1)
1176
self.timeline.addSourceFactory(self.source_factory)
1177
self.effect_factory.addInputStream(self.audio_stream1)
1178
self.effect_factory.addOutputStream(self.audio_stream2)
1179
self.timeline.addEffectFactoryOnObject(self.effect_factory, self.timeline.timeline_objects)
1180
self.failUnlessEqual(len(self.audio_track1.track_objects), 2)
1181
self.failUnlessEqual(len(self.audio_track2.track_objects), 0)
1182
self.failUnlessEqual(len(self.video_track1.track_objects), 0)
1183
self.failUnlessEqual(len(self.video_track2.track_objects), 0)
1185
def test1Audio1Video(self):
1186
self.source_factory.addOutputStream(self.audio_stream1)
1187
self.source_factory.addOutputStream(self.video_stream1)
1188
self.timeline.addSourceFactory(self.source_factory)
1189
self.failUnlessEqual(len(self.audio_track1.track_objects), 1)
1190
self.failUnlessEqual(len(self.audio_track2.track_objects), 0)
1191
self.failUnlessEqual(len(self.video_track1.track_objects), 1)
1192
self.failUnlessEqual(len(self.video_track2.track_objects), 0)
1194
def testConflictNotEnoughTracks(self):
1195
# 3 audio streams, only 2 audio tracks in the timeline
1196
self.source_factory.addOutputStream(self.audio_stream1)
1197
self.source_factory.addOutputStream(self.audio_stream2)
1198
self.source_factory.addOutputStream(self.audio_stream3)
1199
self.failUnlessRaises(TimelineError, self.timeline.addSourceFactory,
1200
self.source_factory, strict=True)
1201
self.failUnlessEqual(len(self.audio_track1.track_objects), 0)
1202
self.failUnlessEqual(len(self.audio_track2.track_objects), 0)
1203
self.failUnlessEqual(len(self.video_track1.track_objects), 0)
1204
self.failUnlessEqual(len(self.video_track2.track_objects), 0)
1207
class TestContexts(TestCase):
1210
TestCase.setUp(self)
1211
self.timeline = Timeline()
1212
self.source_factory = StubFactory()
1213
self.stream = AudioStream(gst.Caps('audio/x-raw-int'))
1214
self.source_factory.addOutputStream(self.stream)
1215
self.track1 = Track(self.stream)
1216
self.track2 = Track(self.stream)
1217
self.track_object1 = SourceTrackObject(self.source_factory, self.stream)
1218
self.track_object2 = SourceTrackObject(self.source_factory, self.stream)
1219
self.track_object3 = SourceTrackObject(self.source_factory, self.stream)
1220
self.track1.addTrackObject(self.track_object1)
1221
self.track1.addTrackObject(self.track_object2)
1222
self.track2.addTrackObject(self.track_object3)
1223
self.timeline_object1 = TimelineObject(self.source_factory)
1224
self.timeline_object1.addTrackObject(self.track_object1)
1225
self.timeline_object2 = TimelineObject(self.source_factory)
1226
self.timeline_object2.addTrackObject(self.track_object2)
1227
self.timeline_object3 = TimelineObject(self.source_factory)
1228
self.timeline_object3.addTrackObject(self.track_object3)
1229
self.timeline.addTimelineObject(self.timeline_object1)
1230
self.timeline.addTimelineObject(self.timeline_object2)
1231
self.timeline.addTimelineObject(self.timeline_object3)
1232
self.other = set([self.track_object2, self.track_object3])
1234
def testMoveContext(self):
1235
# set up the initial state of the timeline and create the track object
1236
# [focus] [t2 ] [t3 ]
1237
self.track_object1.start = 0
1238
self.track_object1.duration = gst.SECOND * 5
1239
self.track_object2.start = 15 * gst.SECOND
1240
self.track_object3.start = 25 * gst.SECOND
1241
context = MoveContext(self.timeline, self.track_object1, set())
1243
# make an edit, check that the edit worked as expected
1244
# [focus] [t2 ] [t3 ]
1245
context.editTo(gst.SECOND * 10, 0)
1246
self.failUnlessEqual(self.track_object1.start, gst.SECOND * 10)
1247
self.failUnlessEqual(self.track_object1.duration, gst.SECOND * 5)
1248
self.failUnlessEqual(self.track_object1.in_point, 0)
1249
self.failUnlessEqual(self.track_object2.start, gst.SECOND * 15)
1250
self.failUnlessEqual(self.track_object3.start, gst.SECOND * 25)
1252
# change to the ripple mode, check that the edit worked as expected
1253
# [focus] [t2 ] [t3 ]
1254
context.setMode(context.RIPPLE)
1255
context.editTo(gst.SECOND * 20, 0)
1256
self.failUnlessEqual(self.track_object1.start, gst.SECOND * 20)
1257
self.failUnlessEqual(self.track_object1.duration, gst.SECOND * 5)
1258
self.failUnlessEqual(self.track_object1.in_point, 0)
1259
self.failUnlessEqual(self.track_object2.start, gst.SECOND * 35)
1260
self.failUnlessEqual(self.track_object3.start, gst.SECOND * 45)
1262
# change back to default mode, and make sure this works as expected
1265
context.setMode(context.DEFAULT)
1266
self.failUnlessEqual(self.track_object1.start, gst.SECOND * 20)
1267
self.failUnlessEqual(self.track_object1.duration, gst.SECOND * 5)
1268
self.failUnlessEqual(self.track_object1.in_point, 0)
1269
self.failUnlessEqual(self.track_object2.start, gst.SECOND * 15)
1270
self.failUnlessEqual(self.track_object3.start, gst.SECOND * 25)
1273
def testMoveContextOverlapDifferentTracks(self):
1275
# track1: [focus][t2]
1277
self.track_object1.start = 20 * gst.SECOND
1278
self.track_object1.duration = 10 * gst.SECOND
1279
self.track_object1.priority = 1
1280
self.track_object2.start = 30 * gst.SECOND
1281
self.track_object2.duration = 10 * gst.SECOND
1282
self.track_object2.priority = 1
1283
self.track_object3.start = 1 * gst.SECOND
1284
self.track_object3.duration = 10 * gst.SECOND
1285
self.track_object3.priority = 1
1288
# track1: [focus][t2]
1290
context = MoveContext(self.timeline, self.track_object1,
1291
set([self.track_object2]))
1292
context.editTo(gst.SECOND * 1, 0)
1294
self.failUnlessEqual(self.track_object1.start, 1 * gst.SECOND)
1295
self.failUnlessEqual(self.track_object1.duration, 10 * gst.SECOND)
1296
self.failUnlessEqual(self.track_object2.start, 11 * gst.SECOND)
1297
self.failUnlessEqual(self.track_object2.duration, 10 * gst.SECOND)
1298
self.failUnlessEqual(self.track_object3.start, 1 * gst.SECOND)
1299
self.failUnlessEqual(self.track_object3.duration, 10 * gst.SECOND)
1302
# track1: [focus][t2]
1304
context = MoveContext(self.timeline, self.track_object3,
1306
context.editTo(gst.SECOND * 10, 0)
1308
self.failUnlessEqual(self.track_object1.start, 1 * gst.SECOND)
1309
self.failUnlessEqual(self.track_object1.duration, 10 * gst.SECOND)
1310
self.failUnlessEqual(self.track_object2.start, 11 * gst.SECOND)
1311
self.failUnlessEqual(self.track_object2.duration, 10 * gst.SECOND)
1312
self.failUnlessEqual(self.track_object3.start, 10 * gst.SECOND)
1313
self.failUnlessEqual(self.track_object3.duration, 10 * gst.SECOND)
1315
def testMoveContextOverlapTransition(self):
1317
# track1: [focus ][ t2 ]
1319
self.track_object1.start = 0 * gst.SECOND
1320
self.track_object1.duration = 10 * gst.SECOND
1321
self.track_object1.priority = 1
1322
self.track_object2.start = 10 * gst.SECOND
1323
self.track_object2.duration = 10 * gst.SECOND
1324
self.track_object2.priority = 1
1325
self.track_object3.start = 0 * gst.SECOND
1326
self.track_object3.duration = 10 * gst.SECOND
1327
self.track_object3.priority = 1
1330
# track1: [focus[ ]t2 ]
1332
context = MoveContext(self.timeline, self.track_object2, set([]))
1333
context.editTo(gst.SECOND * 5, 1)
1335
self.failUnlessEqual(self.track_object1.start, 0 * gst.SECOND)
1336
self.failUnlessEqual(self.track_object1.duration, 10 * gst.SECOND)
1337
self.failUnlessEqual(self.track_object2.start, 5 * gst.SECOND)
1338
self.failUnlessEqual(self.track_object2.duration, 10 * gst.SECOND)
1339
self.failUnlessEqual(self.track_object3.start, 0 * gst.SECOND)
1340
self.failUnlessEqual(self.track_object3.duration, 10 * gst.SECOND)
1342
def testMoveContextFocusNotEarliest(self):
1343
# [t2 ][focus] [t3 ]
1344
self.track_object1.start = 10 * gst.SECOND
1345
self.track_object1.duration = 5 * gst.SECOND
1346
self.track_object2.start = 1 * gst.SECOND
1347
self.track_object2.duration = 9 * gst.SECOND
1348
self.track_object3.start = 15 * gst.SECOND
1349
self.track_object3.duration = 10 * gst.SECOND
1350
self.track_object3.priority = 1
1351
other = set([self.track_object2])
1353
context = MoveContext(self.timeline, self.track_object1, other)
1354
context.editTo(20 * gst.SECOND, 0)
1358
self.failUnlessEqual(self.track_object1.start, 20 * gst.SECOND)
1359
self.failUnlessEqual(self.track_object2.start, 11 * gst.SECOND)
1360
self.failUnlessEqual(self.track_object3.start, 15 * gst.SECOND)
1362
context.setMode(context.RIPPLE)
1364
# [t2 ][focus] [t3 ]
1365
self.failUnlessEqual(self.track_object1.start, 20 * gst.SECOND)
1366
self.failUnlessEqual(self.track_object2.start, 11 * gst.SECOND)
1367
self.failUnlessEqual(self.track_object3.start, 25 * gst.SECOND)
1369
context.setMode(context.DEFAULT)
1373
self.failUnlessEqual(self.track_object1.start, 20 * gst.SECOND)
1374
self.failUnlessEqual(self.track_object2.start, 11 * gst.SECOND)
1375
self.failUnlessEqual(self.track_object3.start, 15 * gst.SECOND)
1379
def testMoveContextMargins(self):
1380
self.other = set([self.track_object3])
1382
self.track_object1.start = 16 * gst.SECOND
1383
self.track_object1.duration = 10 * gst.SECOND
1385
self.track_object2.start = 10 * gst.SECOND
1386
self.track_object2.duration = 5 * gst.SECOND
1388
self.track_object3.start = 3 * gst.SECOND
1389
self.track_object3.duration = 7 * gst.SECOND
1391
# move before left margin, should clamp
1392
context = MoveContext(self.timeline, self.track_object1, self.other)
1393
context.editTo(8 * gst.SECOND, 0)
1396
self.failUnlessEqual(self.track_object1.start, 15 * gst.SECOND)
1397
self.failUnlessEqual(self.track_object2.start, 10 * gst.SECOND)
1398
self.failUnlessEqual(self.track_object3.start, 2 * gst.SECOND)
1400
# move back, no clamp
1401
context = MoveContext(self.timeline, self.track_object1, self.other)
1402
context.editTo(16 * gst.SECOND, 0)
1405
self.failUnlessEqual(self.track_object1.start, 16 * gst.SECOND)
1406
self.failUnlessEqual(self.track_object2.start, 10 * gst.SECOND)
1407
self.failUnlessEqual(self.track_object3.start, 3 * gst.SECOND)
1409
# move past right margin, should clamp
1410
context = MoveContext(self.timeline, self.track_object2, self.other)
1411
context.editTo(20 * gst.SECOND, 0)
1414
self.failUnlessEqual(self.track_object1.start, 16 * gst.SECOND)
1415
self.failUnlessEqual(self.track_object2.start, 11 * gst.SECOND)
1416
self.failUnlessEqual(self.track_object3.start, 4 * gst.SECOND)
1418
def testMoveContextMarginsPriorityChange(self):
1419
self.other = set([self.track_object3])
1421
self.track_object1.start = 5 * gst.SECOND
1422
self.track_object1.duration = 10 * gst.SECOND
1423
self.track_object1.priority = 0
1425
self.track_object2.start = 5 * gst.SECOND
1426
self.track_object2.duration = 10 * gst.SECOND
1427
self.track_object2.priority = 1
1429
self.track_object3.start = 15 * gst.SECOND
1430
self.track_object3.duration = 10 * gst.SECOND
1431
self.track_object3.priority = 1
1433
# same start, priority bump
1434
context = MoveContext(self.timeline, self.track_object2, self.other)
1435
context.editTo(5 * gst.SECOND, 0)
1438
self.failUnlessEqual(self.track_object1.start, 5 * gst.SECOND)
1439
self.failUnlessEqual(self.track_object1.priority, 0)
1440
self.failUnlessEqual(self.track_object2.start, 5 * gst.SECOND)
1441
self.failUnlessEqual(self.track_object2.priority, 1)
1442
self.failUnlessEqual(self.track_object3.start, 15 * gst.SECOND)
1443
self.failUnlessEqual(self.track_object3.priority, 1)
1446
self.track_object2.start = 4 * gst.SECOND
1447
self.track_object2.duration = 10 * gst.SECOND
1448
self.track_object2.priority = 1
1450
context = MoveContext(self.timeline, self.track_object2, self.other)
1451
context.editTo(4 * gst.SECOND, 0)
1454
self.failUnlessEqual(self.track_object1.start, 5 * gst.SECOND)
1455
self.failUnlessEqual(self.track_object1.priority, 0)
1456
self.failUnlessEqual(self.track_object2.start, 4 * gst.SECOND)
1457
self.failUnlessEqual(self.track_object2.priority, 1)
1458
self.failUnlessEqual(self.track_object3.start, 15 * gst.SECOND)
1459
self.failUnlessEqual(self.track_object3.priority, 1)
1462
self.track_object2.start = 6 * gst.SECOND
1463
self.track_object2.duration = 10 * gst.SECOND
1464
self.track_object2.priority = 1
1466
context = MoveContext(self.timeline, self.track_object2, self.other)
1467
context.editTo(6 * gst.SECOND, 0)
1470
self.failUnlessEqual(self.track_object1.start, 5 * gst.SECOND)
1471
self.failUnlessEqual(self.track_object1.priority, 0)
1472
self.failUnlessEqual(self.track_object2.start, 6 * gst.SECOND)
1473
self.failUnlessEqual(self.track_object2.priority, 1)
1474
self.failUnlessEqual(self.track_object3.start, 15 * gst.SECOND)
1475
self.failUnlessEqual(self.track_object3.priority, 1)
1477
def testMoveContextMarginsPriorityChangeMore(self):
1478
self.other = set([self.track_object3])
1480
self.track_object1.start = 20 * gst.SECOND
1481
self.track_object1.duration = 10 * gst.SECOND
1482
self.track_object1.priority = 0
1484
self.track_object2.start = 10 * gst.SECOND
1485
self.track_object2.duration = 10 * gst.SECOND
1486
self.track_object2.priority = 1
1488
self.track_object3.start = 20 * gst.SECOND
1489
self.track_object3.duration = 10 * gst.SECOND
1490
self.track_object3.priority = 1
1492
# same start, priority bump
1493
context = MoveContext(self.timeline, self.track_object2, self.other)
1494
context.editTo(10 * gst.SECOND, 0)
1497
self.failUnlessEqual(self.track_object1.start, 20 * gst.SECOND)
1498
self.failUnlessEqual(self.track_object1.priority, 0)
1499
self.failUnlessEqual(self.track_object2.start, 10 * gst.SECOND)
1500
self.failUnlessEqual(self.track_object2.priority, 1)
1501
self.failUnlessEqual(self.track_object3.start, 20 * gst.SECOND)
1502
self.failUnlessEqual(self.track_object3.priority, 1)
1505
self.track_object2.start = 9 * gst.SECOND
1506
self.track_object2.duration = 10 * gst.SECOND
1507
self.track_object2.priority = 1
1509
self.track_object3.start = 19 * gst.SECOND
1510
self.track_object3.duration = 10 * gst.SECOND
1511
self.track_object3.priority = 1
1513
context = MoveContext(self.timeline, self.track_object2, self.other)
1514
context.editTo(9 * gst.SECOND, 0)
1517
self.failUnlessEqual(self.track_object1.start, 20 * gst.SECOND)
1518
self.failUnlessEqual(self.track_object1.priority, 0)
1519
self.failUnlessEqual(self.track_object2.start, 9 * gst.SECOND)
1520
self.failUnlessEqual(self.track_object2.priority, 1)
1521
self.failUnlessEqual(self.track_object3.start, 19 * gst.SECOND)
1522
self.failUnlessEqual(self.track_object3.priority, 1)
1525
self.track_object2.start = 21 * gst.SECOND
1526
self.track_object2.duration = 10 * gst.SECOND
1527
self.track_object2.priority = 1
1529
self.track_object3.start = 31 * gst.SECOND
1530
self.track_object3.duration = 10 * gst.SECOND
1531
self.track_object3.priority = 1
1533
context = MoveContext(self.timeline,
1534
self.track_object3, set([self.track_object2]))
1535
context.editTo(31 * gst.SECOND, 0)
1538
self.failUnlessEqual(self.track_object1.start, 20 * gst.SECOND)
1539
self.failUnlessEqual(self.track_object1.priority, 0)
1540
self.failUnlessEqual(self.track_object2.start, 21 * gst.SECOND)
1541
self.failUnlessEqual(self.track_object2.priority, 1)
1542
self.failUnlessEqual(self.track_object3.start, 31 * gst.SECOND)
1543
self.failUnlessEqual(self.track_object3.priority, 1)
1545
def testMoveContextMarginsZigZag(self):
1546
self.track_object4 = SourceTrackObject(self.source_factory, self.stream)
1547
self.track1.addTrackObject(self.track_object4)
1548
self.timeline_object4 = TimelineObject(self.source_factory)
1549
self.timeline_object4.addTrackObject(self.track_object4)
1550
self.timeline.addTimelineObject(self.timeline_object4)
1552
self.track_object1.start = 0 * gst.SECOND
1553
self.track_object1.duration = 10 * gst.SECOND
1554
self.track_object1.priority = 0
1556
self.track_object2.start = 15 * gst.SECOND
1557
self.track_object2.duration = 10 * gst.SECOND
1558
self.track_object2.priority = 0
1560
self.track_object3.start = 10 * gst.SECOND
1561
self.track_object3.duration = 10 * gst.SECOND
1562
self.track_object3.priority = 1
1564
self.track_object4.start = 25 * gst.SECOND
1565
self.track_object4.duration = 10 * gst.SECOND
1566
self.track_object4.priority = 1
1568
context = MoveContext(self.timeline, self.track_object2,
1569
set([self.track_object3]))
1570
context.editTo(9 * gst.SECOND, 0)
1573
self.failUnlessEqual(self.track_object1.start, 0 * gst.SECOND)
1574
self.failUnlessEqual(self.track_object1.priority, 0)
1575
self.failUnlessEqual(self.track_object2.start, 10 * gst.SECOND)
1576
self.failUnlessEqual(self.track_object2.priority, 0)
1577
self.failUnlessEqual(self.track_object3.start, 5 * gst.SECOND)
1578
self.failUnlessEqual(self.track_object3.priority, 1)
1579
self.failUnlessEqual(self.track_object4.start, 25 * gst.SECOND)
1580
self.failUnlessEqual(self.track_object4.priority, 1)
1582
context = MoveContext(self.timeline, self.track_object2,
1583
set([self.track_object3]))
1584
context.editTo(25 * gst.SECOND, 0)
1587
self.failUnlessEqual(self.track_object1.start, 0 * gst.SECOND)
1588
self.failUnlessEqual(self.track_object1.priority, 0)
1589
self.failUnlessEqual(self.track_object2.start, 20 * gst.SECOND)
1590
self.failUnlessEqual(self.track_object2.priority, 0)
1591
self.failUnlessEqual(self.track_object3.start, 15 * gst.SECOND)
1592
self.failUnlessEqual(self.track_object3.priority, 1)
1593
self.failUnlessEqual(self.track_object4.start, 25 * gst.SECOND)
1594
self.failUnlessEqual(self.track_object4.priority, 1)
1596
del self.timeline_object4
1597
del self.track_object4
1599
def testTrimStartContext(self):
1600
self.track_object1.start = 1 * gst.SECOND
1601
self.track_object1.in_point = 3 * gst.SECOND
1602
self.track_object1.duration = 10 * gst.SECOND
1603
self.track_object2.start = 11 * gst.SECOND
1604
self.track_object2.in_point = 10 * gst.SECOND
1605
self.track_object2.duration = 10 * gst.SECOND
1606
self.track_object3.start = 25 * gst.SECOND
1607
self.track_object3.in_point = 20 * gst.SECOND
1608
self.track_object3.duration = 10 * gst.SECOND
1610
# set up the initial state of the timeline and create the track object
1611
# [focus] [t2 ] [t3 ]
1612
context = TrimStartContext(self.timeline, self.track_object1, self.other)
1613
context.editTo(gst.SECOND * 5, 0)
1616
self.failUnlessEqual(self.track_object1.start, 5 * gst.SECOND)
1617
self.failUnlessEqual(self.track_object1.in_point, 7 * gst.SECOND)
1618
self.failUnlessEqual(self.track_object2.start, 11 * gst.SECOND)
1619
self.failUnlessEqual(self.track_object2.in_point, 10 * gst.SECOND)
1620
self.failUnlessEqual(self.track_object3.start, 25 * gst.SECOND)
1621
self.failUnlessEqual(self.track_object3.in_point, 20 * gst.SECOND)
1623
def testTrimStartContextMargins(self):
1624
self.track_object1.start = 1 * gst.SECOND
1625
self.track_object1.in_point = 2 * gst.SECOND
1626
self.track_object1.duration = 10 * gst.SECOND
1627
self.track_object2.start = 12 * gst.SECOND
1628
self.track_object2.in_point = 3 * gst.SECOND
1629
self.track_object2.duration = 10 * gst.SECOND
1631
context = TrimStartContext(self.timeline, self.track_object2, self.other)
1632
context.editTo(gst.SECOND * 9, 0)
1635
self.failUnlessEqual(self.track_object1.start, 1 * gst.SECOND)
1636
self.failUnlessEqual(self.track_object1.in_point, 2 * gst.SECOND)
1637
self.failUnlessEqual(self.track_object1.duration, 10 * gst.SECOND)
1638
self.failUnlessEqual(self.track_object2.start, 11 * gst.SECOND)
1639
self.failUnlessEqual(self.track_object2.in_point, 2 * gst.SECOND)
1640
self.failUnlessEqual(self.track_object2.duration, 11 * gst.SECOND)
1642
def testTrimStartContextMarginsDifferentTracks(self):
1644
# track1: [focus][t2]
1646
self.track_object1.start = 20 * gst.SECOND
1647
self.track_object1.in_point = 15 * gst.SECOND
1648
self.track_object1.duration = 10 * gst.SECOND
1649
self.track_object1.priority = 1
1650
self.track_object2.start = 30 * gst.SECOND
1651
self.track_object2.duration = 10 * gst.SECOND
1652
self.track_object2.priority = 1
1653
self.track_object3.start = 1 * gst.SECOND
1654
self.track_object3.duration = 10 * gst.SECOND
1655
self.track_object3.priority = 1
1658
# track1: [ focus][t2]
1660
context = TrimStartContext(self.timeline, self.track_object1, set([]))
1661
context.editTo(gst.SECOND * 5, 0)
1663
self.failUnlessEqual(self.track_object1.start, 5 * gst.SECOND)
1664
self.failUnlessEqual(self.track_object1.duration, 25 * gst.SECOND)
1665
self.failUnlessEqual(self.track_object2.start, 30 * gst.SECOND)
1666
self.failUnlessEqual(self.track_object2.duration, 10 * gst.SECOND)
1667
self.failUnlessEqual(self.track_object3.start, 1 * gst.SECOND)
1668
self.failUnlessEqual(self.track_object3.duration, 10 * gst.SECOND)
1670
def testTrimEndContext(self):
1671
self.track_object1.start = 1 * gst.SECOND
1672
self.track_object1.in_point = 3 * gst.SECOND
1673
self.track_object1.duration = 15 * gst.SECOND
1674
self.track_object2.start = 16 * gst.SECOND
1675
self.track_object2.in_point = 10 * gst.SECOND
1676
self.track_object2.duration = 16 * gst.SECOND
1677
self.track_object3.start = 32 * gst.SECOND
1678
self.track_object3.in_point = 19 * gst.SECOND
1679
self.track_object3.duration = 23 * gst.SECOND
1681
context = TrimEndContext(self.timeline, self.track_object1, self.other)
1682
context.editTo(gst.SECOND * 10, 0)
1685
self.failUnlessEqual(self.track_object1.start, 1 * gst.SECOND)
1686
self.failUnlessEqual(self.track_object1.in_point, 3 * gst.SECOND)
1687
self.failUnlessEqual(self.track_object1.duration, 9 * gst.SECOND)
1688
self.failUnlessEqual(self.track_object2.start, 16 * gst.SECOND)
1689
self.failUnlessEqual(self.track_object2.in_point, 10 * gst.SECOND)
1690
self.failUnlessEqual(self.track_object2.duration, 16 * gst.SECOND)
1691
self.failUnlessEqual(self.track_object3.start, 32 * gst.SECOND)
1692
self.failUnlessEqual(self.track_object3.in_point, 19 * gst.SECOND)
1693
self.failUnlessEqual(self.track_object3.duration, 23 * gst.SECOND)
1695
def testTrimEndContextMargins(self):
1696
self.track_object1.start = 1 * gst.SECOND
1697
self.track_object1.in_point = 2 * gst.SECOND
1698
self.track_object1.duration = 10 * gst.SECOND
1699
self.track_object2.start = 12 * gst.SECOND
1700
self.track_object2.in_point = 3 * gst.SECOND
1701
self.track_object2.duration = 10 * gst.SECOND
1703
context = TrimEndContext(self.timeline, self.track_object1, self.other)
1704
context.editTo(gst.SECOND * 13, 0)
1707
self.failUnlessEqual(self.track_object1.start, 1 * gst.SECOND)
1708
self.failUnlessEqual(self.track_object1.in_point, 2 * gst.SECOND)
1709
self.failUnlessEqual(self.track_object1.duration, 11 * gst.SECOND)
1710
self.failUnlessEqual(self.track_object2.start, 12 * gst.SECOND)
1711
self.failUnlessEqual(self.track_object2.in_point, 3 * gst.SECOND)
1712
self.failUnlessEqual(self.track_object2.duration, 10 * gst.SECOND)
1714
def testTrimEndContextMarginsDifferentTracks(self):
1718
self.track_object1.start = 1 * gst.SECOND
1719
self.track_object1.duration = 10 * gst.SECOND
1720
self.track_object1.priority = 1
1721
self.track_object2.start = 10 * gst.SECOND
1722
self.track_object2.duration = 10 * gst.SECOND
1723
self.track_object2.timeline_object.factory.duration = 30 * gst.SECOND
1724
self.track_object2.priority = 1
1725
self.track_object3.start = 25 * gst.SECOND
1726
self.track_object3.duration = 10 * gst.SECOND
1727
self.track_object3.priority = 1
1732
context = TrimEndContext(self.timeline, self.track_object2, set([]))
1733
context.editTo(gst.SECOND * 30, 0)
1735
self.failUnlessEqual(self.track_object1.start, 1 * gst.SECOND)
1736
self.failUnlessEqual(self.track_object1.duration, 10 * gst.SECOND)
1737
self.failUnlessEqual(self.track_object2.start, 10 * gst.SECOND)
1738
self.failUnlessEqual(self.track_object2.duration, 20 * gst.SECOND)
1739
self.failUnlessEqual(self.track_object3.start, 25 * gst.SECOND)
1740
self.failUnlessEqual(self.track_object3.duration, 10 * gst.SECOND)
1742
def testTrimStartRipple(self):
1745
self.track_object2.start = 1 * gst.SECOND
1746
self.track_object2.duration = 4 * gst.SECOND
1748
self.track_object3.start = 10 * gst.SECOND
1749
self.track_object3.duration = 5 * gst.SECOND
1751
self.track_object1.start = 15 * gst.SECOND
1752
self.track_object1.duration = 10 * gst.SECOND
1753
self.track_object1.trimStart(20 * gst.SECOND)
1754
# set maximum duration on focus
1755
self.track_object1.factory.duration = 10 * gst.SECOND
1757
self.failUnlessEqual(self.track_object1.start, 20 * gst.SECOND)
1758
self.failUnlessEqual(self.track_object1.in_point, 5 * gst.SECOND)
1759
self.failUnlessEqual(self.track_object1.duration, 5 * gst.SECOND)
1763
context = TrimStartContext(self.timeline, self.track_object1, self.other)
1764
context.editTo(gst.SECOND * 15, 0)
1766
self.failUnlessEqual(self.track_object1.start, 15 * gst.SECOND)
1767
self.failUnlessEqual(self.track_object1.in_point, 0 * gst.SECOND)
1768
self.failUnlessEqual(self.track_object2.start, 1 * gst.SECOND)
1769
self.failUnlessEqual(self.track_object2.in_point, 0 * gst.SECOND)
1770
self.failUnlessEqual(self.track_object3.start, 10 * gst.SECOND)
1771
self.failUnlessEqual(self.track_object3.in_point, 0 * gst.SECOND)
1773
# switch to ripple mode
1775
context.setMode(context.RIPPLE)
1777
self.failUnlessEqual(self.track_object1.start, 15 * gst.SECOND)
1778
self.failUnlessEqual(self.track_object1.in_point, 0 * gst.SECOND)
1779
self.failUnlessEqual(self.track_object1.duration, 10 * gst.SECOND)
1780
self.failUnlessEqual(self.track_object2.start, 0 * gst.SECOND)
1781
self.failUnlessEqual(self.track_object2.in_point, 0 * gst.SECOND)
1782
self.failUnlessEqual(self.track_object3.start, 9 * gst.SECOND)
1783
self.failUnlessEqual(self.track_object3.in_point, 0 * gst.SECOND)
1787
context.editTo(25 * gst.SECOND, 0)
1788
self.failUnlessEqual(self.track_object1.start, 25 * gst.SECOND)
1789
self.failUnlessEqual(self.track_object1.in_point, 10 * gst.SECOND)
1790
self.failUnlessEqual(self.track_object2.start, 6 * gst.SECOND)
1791
self.failUnlessEqual(self.track_object3.start, 15 * gst.SECOND)
1793
# check that ripple is clamped to object duration
1795
context.editTo(30 * gst.SECOND, 0)
1796
self.failUnlessEqual(self.track_object1.start, 25 * gst.SECOND)
1797
self.failUnlessEqual(self.track_object1.in_point, 10 * gst.SECOND)
1798
self.failUnlessEqual(self.track_object2.start, 6 * gst.SECOND)
1799
self.failUnlessEqual(self.track_object3.start, 15 * gst.SECOND)
1801
# test switch back to default
1803
context.setMode(context.DEFAULT)
1804
self.failUnlessEqual(self.track_object1.start, 25 * gst.SECOND)
1805
self.failUnlessEqual(self.track_object1.in_point, 10 * gst.SECOND)
1806
self.failUnlessEqual(self.track_object2.start, 1 * gst.SECOND)
1807
self.failUnlessEqual(self.track_object3.start, 10 * gst.SECOND)
1809
# test switch back to ripple
1811
context.setMode(context.RIPPLE)
1812
self.failUnlessEqual(self.track_object1.start, 25 * gst.SECOND)
1813
self.failUnlessEqual(self.track_object1.in_point, 10 * gst.SECOND)
1814
self.failUnlessEqual(self.track_object2.start, 6 * gst.SECOND)
1815
self.failUnlessEqual(self.track_object3.start, 15 * gst.SECOND)
1819
def testTrimEndContextRipple(self):
1822
self.track_object1.start = 1 * gst.SECOND
1823
self.track_object1.duration = 4 * gst.SECOND
1824
self.track_object1.factory.duration = 10 * gst.SECOND
1825
self.track_object2.start = 5 * gst.SECOND
1826
self.track_object2.duration = 5 * gst.SECOND
1827
self.track_object3.start = 10 * gst.SECOND
1828
self.track_object3.duration = 5 * gst.SECOND
1832
context = TrimEndContext(self.timeline, self.track_object1, self.other)
1833
context.editTo(gst.SECOND * 10, 0)
1835
self.failUnlessEqual(self.track_object1.start, 1 * gst.SECOND)
1836
self.failUnlessEqual(self.track_object1.duration, 9 * gst.SECOND)
1837
self.failUnlessEqual(self.track_object2.start, 5 * gst.SECOND)
1838
self.failUnlessEqual(self.track_object2.duration, 5 * gst.SECOND)
1839
self.failUnlessEqual(self.track_object3.start, 10 * gst.SECOND)
1840
self.failUnlessEqual(self.track_object3.duration, 5 * gst.SECOND)
1842
# switch to ripple mode
1844
context.setMode(context.RIPPLE)
1846
self.failUnlessEqual(self.track_object1.start, 1 * gst.SECOND)
1847
self.failUnlessEqual(self.track_object1.duration, 9 * gst.SECOND)
1848
self.failUnlessEqual(self.track_object2.start, 10 * gst.SECOND)
1849
self.failUnlessEqual(self.track_object2.duration, 5 * gst.SECOND)
1850
self.failUnlessEqual(self.track_object3.start, 15 * gst.SECOND)
1851
self.failUnlessEqual(self.track_object3.duration, 5 * gst.SECOND)
1853
context.editTo(gst.SECOND * 10, 0)
1855
# check that we can't ripple past focal object duration
1857
context.editTo(gst.SECOND * 15, 0)
1858
self.failUnlessEqual(self.track_object1.duration, 10 * gst.SECOND)
1859
self.failUnlessEqual(self.track_object2.start, 11 * gst.SECOND)
1860
self.failUnlessEqual(self.track_object3.start, 16 * gst.SECOND)
1862
# check that we can't ripple before initial start of focal object
1864
context.editTo(0, 0)
1865
self.failUnlessEqual(self.track_object1.duration, 0 * gst.SECOND)
1866
self.failUnlessEqual(self.track_object2.start, 1 * gst.SECOND)
1867
self.failUnlessEqual(self.track_object3.start, 6 * gst.SECOND)
1869
# switch back to default mode
1871
context.setMode(context.DEFAULT)
1873
self.failUnlessEqual(self.track_object1.start, 1 * gst.SECOND)
1874
self.failUnlessEqual(self.track_object1.duration, 0 * gst.SECOND)
1875
self.failUnlessEqual(self.track_object2.start, 5 * gst.SECOND)
1876
self.failUnlessEqual(self.track_object2.duration, 5 * gst.SECOND)
1877
self.failUnlessEqual(self.track_object3.start, 10 * gst.SECOND)
1878
self.failUnlessEqual(self.track_object3.duration, 5 * gst.SECOND)
1880
# switch back to ripple mode
1882
context.setMode(context.RIPPLE)
1884
self.failUnlessEqual(self.track_object1.duration, 0 * gst.SECOND)
1885
self.failUnlessEqual(self.track_object2.start, 1 * gst.SECOND)
1886
self.failUnlessEqual(self.track_object3.start, 6 * gst.SECOND)
1890
def testEmptyOther(self):
1891
context = MoveContext(self.timeline, self.track_object1, set())
1893
context = TrimStartContext(self.timeline, self.track_object1, set())
1895
context = TrimEndContext(self.timeline, self.track_object1, set())
1898
def testNothingToRipple(self):
1899
self.track_object1.start = 20 * gst.SECOND
1900
self.track_object1.duration = 5 * gst.SECOND
1901
self.track_object2.start = 10 * gst.SECOND
1902
self.track_object2.duration = 1 * gst.SECOND
1903
self.track_object2.priority = 1
1904
self.track_object3.start = 11 * gst.SECOND
1905
self.track_object3.duration = 1 * gst.SECOND
1906
self.track_object3.priority = 1
1908
context = MoveContext(self.timeline, self.track_object1, set())
1909
context.setMode(context.RIPPLE)
1910
context.editTo(10 * gst.SECOND, 0)
1912
self.failUnlessEqual(self.track_object1.start, 10 * gst.SECOND)
1913
self.failUnlessEqual(self.track_object2.start, 10 * gst.SECOND)
1914
self.failUnlessEqual(self.track_object3.start, 11 * gst.SECOND)
1917
del self.timeline_object1
1918
del self.timeline_object2
1919
del self.timeline_object3
1920
del self.track_object1
1921
del self.track_object2
1922
del self.track_object3
1925
del self.source_factory
1929
TestCase.tearDown(self)