2
# PiTiVi , Non-linear video editor
4
# test_factories_base.py
6
# Copyright (c) 2008 Alessandro Decina <alessandro.decina@collabora.co.uk>
8
# This program is free software; you can redistribute it and/or
9
# modify it under the terms of the GNU Lesser General Public
10
# License as published by the Free Software Foundation; either
11
# version 2.1 of the License, or (at your option) any later version.
13
# This program is distributed in the hope that it will be useful,
14
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
# Lesser General Public License for more details.
18
# You should have received a copy of the GNU Lesser General Public
19
# License along with this program; if not, write to the
20
# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
21
# Boston, MA 02110-1301, USA.
25
from pitivi.factories.base import ObjectFactory, ObjectFactoryError, \
26
SourceFactory, RandomAccessSourceFactory, LiveSourceFactory
27
from pitivi.stream import AudioStream, VideoStream
29
from common import SignalMonitor, TestCase
32
class TestObjectFactory(TestCase):
35
self.factory = ObjectFactory('name')
39
TestCase.tearDown(self)
42
# by default icon is None
43
self.failUnlessEqual(self.factory.icon, None)
45
# assign and check the result. This may seem stupid but icon is a
46
# property so it has a setter method that we want to exercise.
47
self.factory.icon = 'icon'
48
self.failUnlessEqual(self.factory.icon, 'icon')
50
# icon is inherited from parents
51
factory1 = ObjectFactory('name')
52
self.failUnlessEqual(factory1.icon, None)
53
factory1.parent = self.factory
54
self.failUnlessEqual(factory1.icon, 'icon')
56
# setting it directly doesn't make it go up to the parent anymore
57
factory1.icon = 'icon1'
58
self.failUnlessEqual(factory1.icon, 'icon1')
59
self.failUnlessEqual(self.factory.icon, 'icon')
61
def testDuration(self):
62
# if default_duration isn't set explicitly, it defaults to duration
63
self.failUnlessEqual(self.factory.duration, gst.CLOCK_TIME_NONE)
64
self.failUnlessEqual(self.factory.default_duration, gst.CLOCK_TIME_NONE)
65
self.factory.duration = 60 * gst.SECOND
66
self.failUnlessEqual(self.factory.default_duration, 60 * gst.SECOND)
68
# assigning to default_duration shouldn't influence duration
69
self.factory.default_duration = 10 * gst.SECOND
70
self.failUnlessEqual(self.factory.default_duration, 10 * gst.SECOND)
71
self.failUnlessEqual(self.factory.duration, 60 * gst.SECOND)
74
class StubSourceFactory(SourceFactory):
75
def _makeBin(self, output_stream=None):
78
def _releaseBin(self, bin):
82
class TestSourceFactory(TestCase):
85
self.factory = StubSourceFactory('name')
86
caps = gst.Caps('video/x-raw-rgb')
87
self.stream = VideoStream(caps, pad_name='src0')
88
# source factories can't have input streams
89
self.failUnlessRaises(AssertionError,
90
self.factory.addInputStream, self.stream)
91
self.factory.addOutputStream(self.stream)
92
self.monitor = SignalMonitor(self.factory, 'bin-created', 'bin-released')
98
TestCase.tearDown(self)
100
def testMakeAndReleaseBin(self):
101
caps = gst.Caps('video/x-raw-yuv')
102
stream1 = VideoStream(caps)
103
# calling factory.makeBin(stream) with a stream that doesn't belong to a
104
# factory should result in an error
105
self.failUnlessRaises(ObjectFactoryError,
106
self.factory.makeBin, stream1)
108
self.failUnlessEqual(self.factory.current_bins, 0)
109
self.failUnlessEqual(self.monitor.bin_created_count, 0)
110
# check makeBin with a specific stream
111
bin1 = self.factory.makeBin(self.stream)
112
self.failUnlessEqual(self.factory.current_bins, 1)
113
self.failUnlessEqual(self.monitor.bin_created_count, 1)
114
self.failUnless(isinstance(bin1, gst.Bin))
115
# now check the "default" bin case
116
bin2 = self.factory.makeBin()
117
self.failUnlessEqual(self.factory.current_bins, 2)
118
self.failUnlessEqual(self.monitor.bin_created_count, 2)
119
self.failUnless(isinstance(bin2, gst.Bin))
121
self.factory.releaseBin(bin1)
122
self.failUnlessEqual(self.factory.current_bins, 1)
123
self.failUnlessEqual(self.monitor.bin_released_count, 1)
124
self.factory.releaseBin(bin2)
125
self.failUnlessEqual(self.factory.current_bins, 0)
126
self.failUnlessEqual(self.monitor.bin_released_count, 2)
129
class TestLiveSourceFactory(TestCase):
130
def testDefaultDuration(self):
131
# pass an explicit default_duration
132
factory = LiveSourceFactory('live://', 'name', 10 * gst.SECOND)
133
self.failUnlessEqual(factory.default_duration, 10 * gst.SECOND)
135
# check that if a LiveSourceFactory derived class doesn't pass a
136
# default_duration it's still set to 5 seconds
137
factory = LiveSourceFactory('name')
138
self.failUnlessEqual(factory.duration, gst.CLOCK_TIME_NONE)
139
self.failUnlessEqual(factory.default_duration, 5 * gst.SECOND)
142
class TestRandomAccessSourceFactory(TestCase):
143
def testOffsetAndLength(self):
144
# no offset and length
145
factory = RandomAccessSourceFactory('name')
146
self.failUnlessEqual(factory.offset, 0)
147
self.failUnlessEqual(factory.offset_length, gst.CLOCK_TIME_NONE)
148
self.failUnlessEqual(factory.abs_offset, 0)
149
self.failUnlessEqual(factory.abs_offset_length, gst.CLOCK_TIME_NONE)
151
# offset and length without parent
152
factory.offset = 5 * gst.SECOND
153
factory.offset_length = 10 * gst.SECOND
154
self.failUnlessEqual(factory.offset, 5 * gst.SECOND)
155
self.failUnlessEqual(factory.abs_offset, 5 * gst.SECOND)
156
self.failUnlessEqual(factory.offset_length, 10 * gst.SECOND)
157
self.failUnlessEqual(factory.abs_offset_length, 10 * gst.SECOND)
160
relative = RandomAccessSourceFactory('name1')
161
relative.parent = factory
162
self.failUnlessEqual(relative.offset, 0)
163
self.failUnlessEqual(relative.offset_length, gst.CLOCK_TIME_NONE)
164
self.failUnlessEqual(relative.abs_offset, 5 * gst.SECOND)
165
self.failUnlessEqual(relative.abs_offset_length, 10 * gst.SECOND)
168
relative.offset = 1 * gst.SECOND
169
relative.offset_length = 2 * gst.SECOND
170
self.failUnlessEqual(relative.offset, 1 * gst.SECOND)
171
self.failUnlessEqual(relative.offset_length, 2 * gst.SECOND)
172
self.failUnlessEqual(relative.abs_offset, 6 * gst.SECOND)
173
self.failUnlessEqual(relative.abs_offset_length, 2 * gst.SECOND)
175
relative.parent = None
176
self.failUnlessEqual(relative.abs_offset, 1 * gst.SECOND)
177
self.failUnlessEqual(relative.abs_offset_length, 2 * gst.SECOND)
178
relative.parent = factory
180
# offset out of boundary
181
relative.offset = 11 * gst.SECOND
182
self.failUnlessEqual(relative.abs_offset, 15 * gst.SECOND)
183
self.failUnlessEqual(relative.abs_offset_length, 0)
186
relative.offset = 5 * gst.SECOND
187
relative.offset_length = 6 * gst.SECOND
188
self.failUnlessEqual(relative.abs_offset, 10 * gst.SECOND)
189
self.failUnlessEqual(relative.abs_offset_length, 5 * gst.SECOND)
191
relative.offset = 4 * gst.SECOND
192
self.failUnlessEqual(relative.abs_offset, 9 * gst.SECOND)
193
self.failUnlessEqual(relative.abs_offset_length, 6 * gst.SECOND)