예제 #1
0
    def testSaveTimeline(self):
        video_stream = VideoStream(gst.Caps("video/x-raw-yuv"))
        audio_stream = AudioStream(gst.Caps("audio/x-raw-int"))
        source1 = VideoTestSourceFactory()
        source1.addOutputStream(video_stream)

        self.formatter._saveSource(source1)
        self.formatter._saveStream(video_stream)

        track_object = SourceTrackObject(source1, video_stream,
                start=10 * gst.SECOND, duration=20 * gst.SECOND,
                in_point=5 * gst.SECOND, media_duration=15 * gst.SECOND,
                priority=10)

        track = Track(video_stream)
        track.addTrackObject(track_object)

        self.formatter._saveTrackObject(track_object)

        timeline_object = TimelineObject(source1)
        timeline_object.addTrackObject(track_object)

        self.formatter._saveTimelineObject(timeline_object)

        timeline = Timeline()
        timeline.addTrack(track)

        element = self.formatter._saveTimeline(timeline)
        self.failUnlessEqual(element.tag, "timeline")
        tracks = element.find("tracks")
        self.failUnlessEqual(len(tracks), 1)
예제 #2
0
    def testPads(self):
        timeline = Timeline()
        stream1 = VideoStream(gst.Caps('video/x-raw-rgb'), 'src0')
        stream2 = AudioStream(gst.Caps('audio/x-raw-int'), 'src1')
        track1 = Track(stream1)
        track2 = Track(stream2)

        timeline.addTrack(track1)
        timeline.addTrack(track2)

        factory = TimelineSourceFactory(timeline)
        bin = factory.makeBin()

        self.failUnlessEqual(len(list(bin.src_pads())), 0)

        pad1 = gst.Pad('src0', gst.PAD_SRC)
        pad1.set_caps(gst.Caps('asd'))
        pad1.set_active(True)
        track1.composition.add_pad(pad1)

        pad2 = gst.Pad('src0', gst.PAD_SRC)
        pad2.set_caps(gst.Caps('asd'))
        pad2.set_active(True)
        track2.composition.add_pad(pad2)

        self.failUnlessEqual(len(list(bin.src_pads())), 2)
        track1.composition.remove_pad(pad1)
        self.failUnlessEqual(len(list(bin.src_pads())), 1)
        track2.composition.remove_pad(pad2)
        self.failUnlessEqual(len(list(bin.src_pads())), 0)

        factory.clean()
예제 #3
0
    def test_layer_removed(self):
        timeline_ui = Timeline(container=None, app=None)
        timeline_ui.setProject(self.app.project_manager.current_project)

        layer1 = self.layer
        layer2 = self.timeline.append_layer()
        layer3 = self.timeline.append_layer()

        self.assertEqual([layer1, layer2, layer3], self.timeline.get_layers())
        self.assertEqual([l.props.priority for l in [layer1, layer2, layer3]],
                         list(range(3)))

        with self.action_log.started("layer removed"):
            self.timeline.remove_layer(layer2)

        self.assertEqual([layer1, layer3], self.timeline.get_layers())
        self.assertEqual([l.props.priority for l in [layer1, layer3]],
                         list(range(2)))

        self.action_log.undo()
        self.assertEqual([layer1, layer2, layer3], self.timeline.get_layers())
        self.assertEqual([l.props.priority for l in [layer1, layer2, layer3]],
                         list(range(3)))
        self.action_log.redo()
        self.assertEqual([layer1, layer3], self.timeline.get_layers())
        self.assertEqual([l.props.priority for l in [layer1, layer3]],
                         list(range(2)))
    def testPads(self):
        timeline = Timeline()
        stream1 = VideoStream(gst.Caps('video/x-raw-rgb'), 'src0')
        stream2 = AudioStream(gst.Caps('audio/x-raw-int'), 'src1')
        track1 = Track(stream1)
        track2 = Track(stream2)

        timeline.addTrack(track1)
        timeline.addTrack(track2)

        factory = TimelineSourceFactory(timeline)
        bin = factory.makeBin()

        self.failUnlessEqual(len(list(bin.src_pads())), 0)

        pad1 = gst.Pad('src0', gst.PAD_SRC)
        pad1.set_caps(gst.Caps('asd'))
        pad1.set_active(True)
        track1.composition.add_pad(pad1)

        pad2 = gst.Pad('src0', gst.PAD_SRC)
        pad2.set_caps(gst.Caps('asd'))
        pad2.set_active(True)
        track2.composition.add_pad(pad2)

        self.failUnlessEqual(len(list(bin.src_pads())), 2)
        track1.composition.remove_pad(pad1)
        self.failUnlessEqual(len(list(bin.src_pads())), 1)
        track2.composition.remove_pad(pad2)
        self.failUnlessEqual(len(list(bin.src_pads())), 0)

        factory.clean()
예제 #5
0
    def __init__(self, name="", uri=None, **kwargs):
        """
        name : the name of the project
        uri : the uri of the project
        """
        Loggable.__init__(self)
        self.log("name:%s, uri:%s", name, uri)
        self.name = name
        self.settings = None
        self.description = ""
        self.uri = uri
        self.urichanged = False
        self.format = None
        self.sources = SourceList()
        self.sources.connect("source-removed", self._sourceRemovedCb)

        self.settingssigid = 0
        self._dirty = False

        self.timeline = Timeline()

        self.factory = TimelineSourceFactory(self.timeline)
        self.pipeline = Pipeline()
        self.view_action = ViewAction()
        self.view_action.addProducers(self.factory)
예제 #6
0
    def testConnectionAndDisconnection(self):
        timeline = Timeline()
        stream = new_stream()
        factory = new_source_factory()
        track = Track(stream)
        track_object1 = SourceTrackObject(factory, stream)
        track.addTrackObject(track_object1)
        timeline.addTrack(track)
        timeline_object1 = TimelineObject(factory)
        timeline_object1.addTrackObject(track_object1)
        timeline.addTimelineObject(timeline_object1)

        self.observer.startObserving(timeline)
        self.failUnless(timeline.connected)
        self.failUnless(timeline_object1.connected)

        timeline.removeTimelineObject(timeline_object1)
        self.failIf(timeline_object1.connected)

        timeline.addTimelineObject(timeline_object1)
        self.failUnless(timeline_object1)

        self.observer.stopObserving(timeline)
        self.failIf(timeline.connected)
        self.failIf(timeline_object1.connected)
예제 #7
0
    def testSaveTimeline(self):
        video_stream = VideoStream(gst.Caps("video/x-raw-yuv"))
        audio_stream = AudioStream(gst.Caps("audio/x-raw-int"))
        source1 = VideoTestSourceFactory()
        source1.addOutputStream(video_stream)

        self.formatter._saveSource(source1)
        self.formatter._saveStream(video_stream)

        track_object = SourceTrackObject(source1,
                                         video_stream,
                                         start=10 * gst.SECOND,
                                         duration=20 * gst.SECOND,
                                         in_point=5 * gst.SECOND,
                                         media_duration=15 * gst.SECOND,
                                         priority=10)

        track = Track(video_stream)
        track.addTrackObject(track_object)

        self.formatter._saveTrackObject(track_object)

        timeline_object = TimelineObject(source1)
        timeline_object.addTrackObject(track_object)

        self.formatter._saveTimelineObject(timeline_object)

        timeline = Timeline()
        timeline.addTrack(track)

        element = self.formatter._saveTimeline(timeline)
        self.failUnlessEqual(element.tag, "timeline")
        tracks = element.find("tracks")
        self.failUnlessEqual(len(tracks), 1)
예제 #8
0
    def __init__(self, name="", uri=None, **kwargs):
        """
        @param name: the name of the project
        @param uri: the uri of the project
        """
        Loggable.__init__(self)
        self.log("name:%s, uri:%s", name, uri)
        self.name = name
        self.settings = None
        self.description = ""
        self.uri = uri
        self.urichanged = False
        self.format = None
        self.sources = SourceList()
        self.sources.connect("source-added", self._sourceAddedCb)
        self.sources.connect("source-removed", self._sourceRemovedCb)

        self._dirty = False

        self.timeline = Timeline()

        self.factory = TimelineSourceFactory(self.timeline)
        self.pipeline = Pipeline()
        self.view_action = ViewAction()
        self.view_action.addProducers(self.factory)
        self.seeker = Seeker(80)

        self.settings = ExportSettings()
        self._videocaps = self.settings.getVideoCaps()
예제 #9
0
    def testLayerMoved(self):
        layer1 = self.layer
        layer2 = self.timeline.append_layer()
        layer3 = self.timeline.append_layer()
        self.assertEqual(self.timeline.get_layers(), [layer1, layer2, layer3])

        timeline_ui = Timeline(app=self.app, size_group=mock.Mock())
        timeline_ui.setProject(self.app.project_manager.current_project)

        # Click and drag a layer control box to move the layer.
        with mock.patch.object(Gtk, 'get_event_widget') as get_event_widget:
            event = mock.Mock()
            event.get_button.return_value = True, 1

            get_event_widget.return_value = layer1.control_ui
            timeline_ui._button_press_event_cb(None, event=event)

            with mock.patch.object(layer1.control_ui, "translate_coordinates") as translate_coordinates:
                translate_coordinates.return_value = (0, 0)
                with mock.patch.object(timeline_ui, "_get_layer_at") as _get_layer_at:
                    _get_layer_at.return_value = layer3, None
                    timeline_ui._motion_notify_event_cb(None, event=event)

            timeline_ui._button_release_event_cb(None, event=event)
        self.check_layers([layer2, layer3, layer1])

        self.action_log.undo()
        self.check_layers([layer1, layer2, layer3])

        self.action_log.redo()
        self.check_layers([layer2, layer3, layer1])
예제 #10
0
    def testConnectionAndDisconnection(self):
        timeline = Timeline()
        stream = new_stream()
        factory = new_source_factory()
        track = Track(stream)
        track_object1 = SourceTrackObject(factory, stream)
        track.addTrackObject(track_object1)
        timeline.addTrack(track)
        timeline_object1 = TimelineObject(factory)
        timeline_object1.addTrackObject(track_object1)
        timeline.addTimelineObject(timeline_object1)

        self.observer.startObserving(timeline)
        self.failUnless(timeline.connected)
        self.failUnless(timeline_object1.connected)

        timeline.removeTimelineObject(timeline_object1)
        self.failIf(timeline_object1.connected)

        timeline.addTimelineObject(timeline_object1)
        self.failUnless(timeline_object1)

        self.observer.stopObserving(timeline)
        self.failIf(timeline.connected)
        self.failIf(timeline_object1.connected)
예제 #11
0
    def testLayerMoved(self):
        layer1 = self.layer
        layer2 = self.timeline.append_layer()
        layer3 = self.timeline.append_layer()
        self.assertEqual(self.timeline.get_layers(), [layer1, layer2, layer3])

        timeline_ui = Timeline(app=self.app, size_group=mock.Mock())
        timeline_ui.setProject(self.app.project_manager.current_project)

        # Click and drag a layer control box to move the layer.
        with mock.patch.object(Gtk, 'get_event_widget') as get_event_widget:
            event = mock.Mock()
            event.get_button.return_value = True, 1

            get_event_widget.return_value = layer1.control_ui
            timeline_ui._button_press_event_cb(None, event=event)

            with mock.patch.object(layer1.control_ui, "translate_coordinates") as translate_coordinates:
                translate_coordinates.return_value = (0, 0)
                with mock.patch.object(timeline_ui, "_get_layer_at") as _get_layer_at:
                    _get_layer_at.return_value = layer3, None
                    timeline_ui._motion_notify_event_cb(None, event=event)

            timeline_ui._button_release_event_cb(None, event=event)
        self.check_layers([layer2, layer3, layer1])

        self.action_log.undo()
        self.check_layers([layer1, layer2, layer3])

        self.action_log.redo()
        self.check_layers([layer2, layer3, layer1])
예제 #12
0
    def testTracks(self):
        timeline = Timeline()
        stream1 = VideoStream(gst.Caps('video/x-raw-rgb'), 'src0')
        stream2 = AudioStream(gst.Caps('audio/x-raw-int'), 'src1')
        track1 = Track(stream1)
        track2 = Track(stream2)

        # start with 2 tracks
        timeline.addTrack(track1)
        timeline.addTrack(track2)

        factory = TimelineSourceFactory(timeline)
        bin = factory.makeBin()
        self.failUnlessEqual(len(list(bin)), 2)
        self.failUnlessEqual(set(factory.getOutputStreams()),
                             set([stream1, stream2]))

        # add a new track
        stream3 = AudioStream(gst.Caps('audio/x-raw-int'), 'src2')
        track3 = Track(stream3)
        timeline.addTrack(track3)
        self.failUnlessEqual(len(list(bin)), 3)
        self.failUnlessEqual(set(factory.getOutputStreams()),
                             set([stream1, stream2, stream3]))

        # remove a track
        timeline.removeTrack(track3)
        self.failUnlessEqual(len(list(bin)), 2)
        self.failUnlessEqual(set(factory.getOutputStreams()),
                             set([stream1, stream2]))

        factory.clean()
예제 #13
0
파일: project.py 프로젝트: bemasc/pitivi
    def __init__(self, name="", uri=None, **kwargs):
        """
        @param name: the name of the project
        @param uri: the uri of the project
        """
        Loggable.__init__(self)
        self.log("name:%s, uri:%s", name, uri)
        self.name = name
        self.settings = None
        self.description = ""
        self.uri = uri
        self.urichanged = False
        self.format = None
        self.sources = SourceList()
        self.sources.connect("source-added", self._sourceAddedCb)
        self.sources.connect("source-removed", self._sourceRemovedCb)

        self._dirty = False

        self.timeline = Timeline()

        self.factory = TimelineSourceFactory(self.timeline)
        self.pipeline = Pipeline()
        self.view_action = ViewAction()
        self.view_action.addProducers(self.factory)
        self.seeker = Seeker(80)

        self.settings = ExportSettings()
        self._videocaps = self.settings.getVideoCaps()
예제 #14
0
 def createTimeline(self, layers_heights):
     project_manager = ProjectManager(app=None)
     project_manager.newBlankProject()
     project = project_manager.current_project
     timeline = Timeline(container=None, app=None)
     timeline.get_parent = mock.MagicMock()
     timeline.setProject(project)
     y = 0
     for priority, height in enumerate(layers_heights):
         bLayer = timeline.createLayer(priority=priority)
         rect = Gdk.Rectangle()
         rect.y = y
         rect.height = height
         bLayer.ui.set_allocation(rect)
         y += height + SEPARATOR_HEIGHT
     return timeline
예제 #15
0
    def testAudioOnly(self):
        audio_factory1 = AudioTestSourceFactory(3)
        audio_factory1.duration = 10 * gst.SECOND
        stream = AudioStream(gst.Caps('audio/x-raw-int'), 'src0')
        audio_factory1.addOutputStream(stream)

        timeline = Timeline()
        track = Track(stream)
        track_object1 = SourceTrackObject(audio_factory1, stream)
        track_object1.start = 2 * gst.SECOND
        track.addTrackObject(track_object1)
        timeline.addTrack(track)

        factory = TimelineSourceFactory(timeline)
        bin = factory.makeBin()
        self.failUnlessEqual(len(list(bin)), 1)
        self.failUnlessEqual(factory.duration, 12 * gst.SECOND)

        fakesink = gst.element_factory_make('fakesink')

        def bin_pad_added_cb(bin, pad):
            pad.link(fakesink.get_pad('sink'))

        bin.connect('pad-added', bin_pad_added_cb)

        def error_cb(bus, message):
            gerror, debug = message.parse_error()
            self.fail('%s: %s' % (gerror.message, debug))

        def eos_cb(bus, message):
            self.loop.quit()

        pipeline = gst.Pipeline()
        bus = pipeline.get_bus()
        bus.add_signal_watch()
        bus.connect('message::error', error_cb)
        bus.connect('message::eos', eos_cb)

        pipeline.add(bin)
        pipeline.add(fakesink)

        pipeline.set_state(gst.STATE_PLAYING)
        self.loop.run()
        pipeline.set_state(gst.STATE_NULL)

        factory.clean()
예제 #16
0
 def testCheckMediaTypesWhenNoUI(self):
     ges_layer = GES.Layer()
     png = common.get_sample_uri("flat_colour1_640x480.png")
     video_clip = GES.UriClipAsset.request_sync(png).extract()
     self.assertTrue(ges_layer.add_clip(video_clip))
     self.assertEqual(len(ges_layer.get_clips()), 1)
     timeline = Timeline(container=None, app=None)
     layer = Layer(ges_layer, timeline)
    def testAudioOnly(self):
        audio_factory1 = AudioTestSourceFactory(3)
        audio_factory1.duration = 10 * gst.SECOND
        stream = AudioStream(gst.Caps('audio/x-raw-int'), 'src0')
        audio_factory1.addOutputStream(stream)

        timeline = Timeline()
        track = Track(stream)
        track_object1 = SourceTrackObject(audio_factory1, stream)
        track_object1.start = 2 * gst.SECOND
        track.addTrackObject(track_object1)
        timeline.addTrack(track)

        factory = TimelineSourceFactory(timeline)
        bin = factory.makeBin()
        self.failUnlessEqual(len(list(bin)), 1)
        self.failUnlessEqual(factory.duration, 12 * gst.SECOND)

        fakesink = gst.element_factory_make('fakesink')

        def bin_pad_added_cb(bin, pad):
            pad.link(fakesink.get_pad('sink'))

        bin.connect('pad-added', bin_pad_added_cb)

        def error_cb(bus, message):
            gerror, debug = message.parse_error()
            self.fail('%s: %s' % (gerror.message, debug))

        def eos_cb(bus, message):
            self.loop.quit()

        pipeline = gst.Pipeline()
        bus = pipeline.get_bus()
        bus.add_signal_watch()
        bus.connect('message::error', error_cb)
        bus.connect('message::eos', eos_cb)

        pipeline.add(bin)
        pipeline.add(fakesink)

        pipeline.set_state(gst.STATE_PLAYING)
        self.loop.run()
        pipeline.set_state(gst.STATE_NULL)

        factory.clean()
예제 #18
0
    def testLoadProject(self):
        video_stream = VideoStream(gst.Caps("video/x-raw-yuv"))
        audio_stream = AudioStream(gst.Caps("audio/x-raw-int"))
        source1 = VideoTestSourceFactory()

        self.formatter._saveSource(source1)
        self.formatter._saveStream(video_stream)

        track_object = SourceTrackObject(source1,
                                         video_stream,
                                         start=10 * gst.SECOND,
                                         duration=20 * gst.SECOND,
                                         in_point=5 * gst.SECOND,
                                         media_duration=15 * gst.SECOND,
                                         priority=10)

        track = Track(video_stream)
        track.addTrackObject(track_object)

        self.formatter._saveTrackObject(track_object)

        timeline_object = TimelineObject(source1)
        timeline_object.addTrackObject(track_object)

        self.formatter._saveTimelineObject(timeline_object)

        timeline = Timeline()
        timeline.addTrack(track)

        self.formatter._saveTimeline(timeline)

        project = Project()
        project.timeline = timeline
        project.sources.addFactory(source1)

        element = self.formatter._serializeProject(project)

        self.failUnlessEqual(element.tag, "pitivi")
        self.failIfEqual(element.find("factories"), None)
        self.failIfEqual(element.find("timeline"), None)

        indent(element)
        f = file("/tmp/untitled.pptv", "w")
        f.write(tostring(element))
        f.close()
    def testTracks(self):
        timeline = Timeline()
        stream1 = VideoStream(gst.Caps('video/x-raw-rgb'), 'src0')
        stream2 = AudioStream(gst.Caps('audio/x-raw-int'), 'src1')
        track1 = Track(stream1)
        track2 = Track(stream2)

        # start with 2 tracks
        timeline.addTrack(track1)
        timeline.addTrack(track2)

        factory = TimelineSourceFactory(timeline)
        bin = factory.makeBin()
        self.failUnlessEqual(len(list(bin)), 2)
        self.failUnlessEqual(set(factory.getOutputStreams()),
                set([stream1, stream2]))

        # add a new track
        stream3 = AudioStream(gst.Caps('audio/x-raw-int'), 'src2')
        track3 = Track(stream3)
        timeline.addTrack(track3)
        self.failUnlessEqual(len(list(bin)), 3)
        self.failUnlessEqual(set(factory.getOutputStreams()),
                set([stream1, stream2, stream3]))

        # remove a track
        timeline.removeTrack(track3)
        self.failUnlessEqual(len(list(bin)), 2)
        self.failUnlessEqual(set(factory.getOutputStreams()),
                set([stream1, stream2]))

        factory.clean()
예제 #20
0
    def testEmpty(self):
        timeline = Timeline()
        factory = TimelineSourceFactory(timeline)
        bin = factory.makeBin()
        self.failUnlessRaises(ObjectFactoryError, factory.makeBin)

        self.failUnlessEqual(len(list(bin)), 0)

        factory.clean()
예제 #21
0
    def testLoadProject(self):
        video_stream = VideoStream(gst.Caps("video/x-raw-yuv"))
        audio_stream = AudioStream(gst.Caps("audio/x-raw-int"))
        source1 = VideoTestSourceFactory()

        self.formatter._saveSource(source1)
        self.formatter._saveStream(video_stream)

        track_object = SourceTrackObject(source1, video_stream,
                start=10 * gst.SECOND, duration=20 * gst.SECOND,
                in_point=5 * gst.SECOND, media_duration=15 * gst.SECOND,
                priority=10)

        track = Track(video_stream)
        track.addTrackObject(track_object)

        self.formatter._saveTrackObject(track_object)

        timeline_object = TimelineObject(source1)
        timeline_object.addTrackObject(track_object)

        self.formatter._saveTimelineObject(timeline_object)

        timeline = Timeline()
        timeline.addTrack(track)

        self.formatter._saveTimeline(timeline)

        project = Project()
        project.timeline = timeline
        project.sources.addFactory(source1)

        element = self.formatter._serializeProject(project)

        self.failUnlessEqual(element.tag, "pitivi")
        self.failIfEqual(element.find("factories"), None)
        self.failIfEqual(element.find("timeline"), None)

        indent(element)
        f = file("/tmp/untitled.pptv", "w")
        f.write(tostring(element))
        f.close()
예제 #22
0
 def setUp(self):
     self.stream = new_stream()
     self.factory = new_source_factory()
     self.effect_factory = TestEffectFactory(self.stream)
     self.track1 = Track(self.stream)
     self.track2 = Track(self.stream)
     self.timeline = Timeline()
     self.timeline.addTrack(self.track1)
     self.timeline.addTrack(self.track2)
     self.track_object1 = SourceTrackObject(self.factory, self.stream)
     self.track_object2 = SourceTrackObject(self.factory, self.stream)
     self.track_effect1 = TrackEffect(self.effect_factory, self.stream)
     self.track_effect2 = TrackEffect(self.effect_factory, self.stream)
     self.track1.addTrackObject(self.track_object1)
     self.track2.addTrackObject(self.track_object2)
     self.timeline_object1 = TimelineObject(self.factory)
     self.timeline_object1.addTrackObject(self.track_object1)
     self.timeline_object1.addTrackObject(self.track_object2)
     self.action_log = UndoableActionLog()
     self.observer = TestTimelineLogObserver(self.action_log)
     self.observer.startObserving(self.timeline)
예제 #23
0
 def setUp(self):
     self.stream = new_stream()
     self.factory = new_factory()
     self.track1 = Track(self.stream)
     self.track2 = Track(self.stream)
     self.timeline = Timeline()
     self.timeline.addTrack(self.track1)
     self.timeline.addTrack(self.track2)
     self.track_object1 = SourceTrackObject(self.factory, self.stream)
     self.track_object2 = SourceTrackObject(self.factory, self.stream)
     self.track1.addTrackObject(self.track_object1)
     self.track2.addTrackObject(self.track_object2)
     self.timeline_object1 = TimelineObject(self.factory)
     self.timeline_object1.addTrackObject(self.track_object1)
     self.timeline_object1.addTrackObject(self.track_object2)
     self.action_log = UndoableActionLog()
     self.observer = TestTimelineLogObserver(self.action_log)
     self.observer.startObserving(self.timeline)
예제 #24
0
    def setUp(self):
        self.mainloop = gobject.MainLoop()

        samples = os.path.join(os.path.dirname(__file__), "samples")
        self.facs = []
        self.facs.append([PictureFileSourceFactory('file://' + os.path.join(samples, "flat_colour1_640x480.png")), VideoStream(gst.Caps("video/x-raw-rgb,bpp=(int)24,depth=(int)24,endianness=(int)4321,red_mask=(int)16711680,green_mask=(int)65280,blue_mask=(int)255"))])
        self.facs.append([PictureFileSourceFactory('file://' + os.path.join(samples, "flat_colour2_640x480.png")), VideoStream(gst.Caps("video/x-raw-rgb,bpp=(int)24,depth=(int)24,endianness=(int)4321,red_mask=(int)16711680,green_mask=(int)65280,blue_mask=(int)255"))])
        self.facs.append([PictureFileSourceFactory('file://' + os.path.join(samples, "flat_colour3_320x180.png")), VideoStream(gst.Caps("video/x-raw-rgb,bpp=(int)24,depth=(int)24,endianness=(int)4321,red_mask=(int)16711680,green_mask=(int)65280,blue_mask=(int)255"))])
        # one video with a different resolution
        self.facs.append([VideoTestSourceFactory(), VideoStream(gst.Caps('video/x-raw-yuv,width=(int)640,height=(int)480,format=(fourcc)I420'))])

        # configure durations and add output streams to factories
        for fac in self.facs:
            factory = fac[0]
            stream = fac[1]
            factory.duration = self.clip_duration
            factory.addOutputStream(stream)
        self.track_objects = []
        self.track = Track(self.facs[0][1])
        self.timeline = Timeline()
        self.timeline.addTrack(self.track)

        vsettings = StreamEncodeSettings(encoder="theoraenc")
        rsettings = RenderSettings(settings=[vsettings],
                                   muxer="oggmux")
        self.fakesink = common.FakeSinkFactory()
        rendersink = RenderSinkFactory(RenderFactory(settings=rsettings),
                                       self.fakesink)
        self.render = RenderAction()
        self.pipeline = Pipeline()
        self.pipeline.connect("eos", self._renderEOSCb)
        self.pipeline.connect("error", self._renderErrorCb)
        self.pipeline.addAction(self.render)
        self.render.addConsumers(rendersink)
        timeline_factory = TimelineSourceFactory(self.timeline)
        self.render.addProducers(timeline_factory)
예제 #25
0
class TestStillImage(TestCase):
    clip_duration = 3 * gst.SECOND

    def setUp(self):
        self.mainloop = gobject.MainLoop()

        samples = os.path.join(os.path.dirname(__file__), "samples")
        self.facs = []
        self.facs.append([
            PictureFileSourceFactory(
                'file://' + os.path.join(samples, "flat_colour1_640x480.png")),
            VideoStream(
                gst.Caps(
                    "video/x-raw-rgb,bpp=(int)24,depth=(int)24,endianness=(int)4321,red_mask=(int)16711680,green_mask=(int)65280,blue_mask=(int)255"
                ))
        ])
        self.facs.append([
            PictureFileSourceFactory(
                'file://' + os.path.join(samples, "flat_colour2_640x480.png")),
            VideoStream(
                gst.Caps(
                    "video/x-raw-rgb,bpp=(int)24,depth=(int)24,endianness=(int)4321,red_mask=(int)16711680,green_mask=(int)65280,blue_mask=(int)255"
                ))
        ])
        self.facs.append([
            PictureFileSourceFactory(
                'file://' + os.path.join(samples, "flat_colour3_320x180.png")),
            VideoStream(
                gst.Caps(
                    "video/x-raw-rgb,bpp=(int)24,depth=(int)24,endianness=(int)4321,red_mask=(int)16711680,green_mask=(int)65280,blue_mask=(int)255"
                ))
        ])
        # one video with a different resolution
        self.facs.append([
            VideoTestSourceFactory(),
            VideoStream(
                gst.Caps(
                    'video/x-raw-yuv,width=(int)640,height=(int)480,format=(fourcc)I420'
                ))
        ])

        # configure durations and add output streams to factories
        for fac in self.facs:
            factory = fac[0]
            stream = fac[1]
            factory.duration = self.clip_duration
            factory.addOutputStream(stream)
        self.track_objects = []
        self.track = Track(self.facs[0][1])
        self.timeline = Timeline()
        self.timeline.addTrack(self.track)

        vsettings = StreamEncodeSettings(encoder="theoraenc")
        rsettings = RenderSettings(settings=[vsettings], muxer="oggmux")
        self.fakesink = common.FakeSinkFactory()
        rendersink = RenderSinkFactory(RenderFactory(settings=rsettings),
                                       self.fakesink)
        self.render = RenderAction()
        self.pipeline = Pipeline()
        self.pipeline.connect("eos", self._renderEOSCb)
        self.pipeline.connect("error", self._renderErrorCb)
        self.pipeline.addAction(self.render)
        self.render.addConsumers(rendersink)
        timeline_factory = TimelineSourceFactory(self.timeline)
        self.render.addProducers(timeline_factory)

    def tearDown(self):
        self.mainloop.quit()

    def configureStreams(self, inputs, offsets):
        count = 0
        for i in inputs:
            factory = self.facs[i][0]
            stream = self.facs[i][1]
            track_object = SourceTrackObject(factory, stream)
            self.track_objects.append(track_object)
            track_object.start = offsets[count]
            self.track.addTrackObject(track_object)
            count += 1

    def startRender(self):
        self.render.activate()
        self.data_written = 0
        self.fakesink.bins[0].props.signal_handoffs = True
        self.fakesink.bins[0].connect("handoff", self._fakesinkHandoffCb)
        self.pipeline.play()
        self.mainloop.run()

    def _fakesinkHandoffCb(self, fakesink, buf, pad):
        self.data_written += buf.size

    def _renderEOSCb(self, obj):
        self.mainloop.quit()
        # check the render was successful
        self.assertTrue(self.data_written > 0)

    def _renderErrorCb(self, obj, error, details):
        print "Error: %s\nDetails: %s" % (str(error), str(details))
        self.fail("Pipeline rendering error")

    def cleanUp(self):
        self.render.deactivate()
        self.track.removeAllTrackObjects()
        self.track_objects = []

    def testRendering(self):
        # use one of the still image streams
        self.configureStreams(range(1), [0])
        self.startRender()
        self.cleanUp()

        # use two images with the same resolution and concatenate them
        self.configureStreams(range(2), [0, self.clip_duration])
        self.startRender()
        self.cleanUp()

        # concatenate images with different resolutions
        self.configureStreams(range(3),
                              [0, self.clip_duration, 2 * self.clip_duration])
        self.startRender()
        self.cleanUp()

        # mix images with different resolutions by overlapping
        self.configureStreams(range(3),
                              [0, self.clip_duration // 2, self.clip_duration])
        self.startRender()
        self.cleanUp()

        # mix images and videos with the same resolution
        self.configureStreams([0, 1, 3],
                              [0, self.clip_duration, 2 * self.clip_duration])
        self.startRender()
        self.cleanUp()

        # mix images and videos with different resolutions
        self.configureStreams(range(4), [
            0, self.clip_duration, 2 * self.clip_duration,
            3 * self.clip_duration
        ])
        self.startRender()
        self.cleanUp()

        # mix images and videos with different resolutions by overlapping
        self.configureStreams(range(4), [
            0, self.clip_duration // 2, self.clip_duration,
            (3 * self.clip_duration) // 2
        ])
        self.startRender()
        self.cleanUp()
예제 #26
0
class  TestTimelineUndo(TestCase):
    def setUp(self):
        self.stream = new_stream()
        self.factory = new_source_factory()
        self.effect_factory = TestEffectFactory(self.stream)
        self.track1 = Track(self.stream)
        self.track2 = Track(self.stream)
        self.timeline = Timeline()
        self.timeline.addTrack(self.track1)
        self.timeline.addTrack(self.track2)
        self.track_object1 = SourceTrackObject(self.factory, self.stream)
        self.track_object2 = SourceTrackObject(self.factory, self.stream)
        self.track_effect1 = TrackEffect(self.effect_factory, self.stream)
        self.track_effect2 = TrackEffect(self.effect_factory, self.stream)
        self.track1.addTrackObject(self.track_object1)
        self.track2.addTrackObject(self.track_object2)
        self.timeline_object1 = TimelineObject(self.factory)
        self.timeline_object1.addTrackObject(self.track_object1)
        self.timeline_object1.addTrackObject(self.track_object2)
        self.action_log = UndoableActionLog()
        self.observer = TestTimelineLogObserver(self.action_log)
        self.observer.startObserving(self.timeline)

    def testAddTimelineObject(self):
        stacks = []

        def commitCb(action_log, stack, nested):
            stacks.append(stack)
        self.action_log.connect("commit", commitCb)

        self.action_log.begin("add clip")
        self.timeline.addTimelineObject(self.timeline_object1)
        self.action_log.commit()

        self.failUnlessEqual(len(stacks), 1)
        stack = stacks[0]
        self.failUnlessEqual(len(stack.done_actions), 1)
        action = stack.done_actions[0]
        self.failUnless(isinstance(action, TimelineObjectAdded))

        self.failUnless(self.timeline_object1 \
                in self.timeline.timeline_objects)
        self.action_log.undo()
        self.failIf(self.timeline_object1 \
                in self.timeline.timeline_objects)

        self.action_log.redo()
        self.failUnless(self.timeline_object1 \
                in self.timeline.timeline_objects)

    def testRemoveTimelineObject(self):
        stacks = []

        def commitCb(action_log, stack, nested):
            stacks.append(stack)
        self.action_log.connect("commit", commitCb)

        self.timeline.addTimelineObject(self.timeline_object1)
        self.action_log.begin("remove clip")
        self.timeline.removeTimelineObject(self.timeline_object1, deep=True)
        self.action_log.commit()

        self.failUnlessEqual(len(stacks), 1)
        stack = stacks[0]
        self.failUnlessEqual(len(stack.done_actions), 1)
        action = stack.done_actions[0]
        self.failUnless(isinstance(action, TimelineObjectRemoved))

        self.failIf(self.timeline_object1 \
                in self.timeline.timeline_objects)
        self.action_log.undo()
        self.failUnless(self.timeline_object1 \
                in self.timeline.timeline_objects)

        self.action_log.redo()
        self.failIf(self.timeline_object1 \
                in self.timeline.timeline_objects)

    def testAddEffectToTimelineObject(self):
        stacks = []
        pipeline = Pipeline()

        def commitCb(action_log, stack, nested):
            stacks.append(stack)
        self.action_log.connect("commit", commitCb)
        self.observer.pipeline = pipeline

        #FIXME Should I commit it and check there are 2 elements
        #in the stacks
        self.timeline.addTimelineObject(self.timeline_object1)
        self.track1.addTrackObject(self.track_effect1)

        self.action_log.begin("add effect")
        self.timeline_object1.addTrackObject(self.track_effect1)
        self.action_log.commit()

        self.failUnlessEqual(len(stacks), 1)
        stack = stacks[0]
        self.failUnlessEqual(len(stack.done_actions), 1)
        action = stack.done_actions[0]
        self.failUnless(isinstance(action, TrackEffectAdded))

        self.failUnless(self.track_effect1 \
                in self.timeline_object1.track_objects)
        self.failUnless(self.track_effect1 \
                in self.track1.track_objects)
        self.failUnless(len([effect for effect in \
                                self.timeline_object1.track_objects
                                if isinstance(effect, TrackEffect)]) == 1)
        self.failUnless(len([effect for effect in self.track1.track_objects
                             if isinstance(effect, TrackEffect)]) == 1)

        self.action_log.undo()
        self.failIf(self.track_effect1 \
                in self.timeline_object1.track_objects)
        self.failIf(self.track_effect1 \
                in self.track1.track_objects)

        self.action_log.redo()
        self.failUnless(len([effect for effect in
                                self.timeline_object1.track_objects
                                if isinstance(effect, TrackEffect)]) == 1)
        self.failUnless(len([effect for effect in self.track1.track_objects
                             if isinstance(effect, TrackEffect)]) == 1)

        self.timeline.removeTimelineObject(self.timeline_object1, deep=True)

    def testTimelineObjectPropertyChange(self):
        stacks = []

        def commitCb(action_log, stack, nested):
            stacks.append(stack)
        self.action_log.connect("commit", commitCb)

        self.timeline_object1.start = 5 * gst.SECOND
        self.timeline_object1.duration = 20 * gst.SECOND
        self.timeline.addTimelineObject(self.timeline_object1)
        self.action_log.begin("modify clip")
        self.timeline_object1.start = 10 * gst.SECOND
        self.action_log.commit()

        self.failUnlessEqual(len(stacks), 1)
        stack = stacks[0]
        self.failUnlessEqual(len(stack.done_actions), 1)
        action = stack.done_actions[0]
        self.failUnless(isinstance(action, TimelineObjectPropertyChanged))

        self.failUnlessEqual(self.timeline_object1.start, 10 * gst.SECOND)
        self.action_log.undo()
        self.failUnlessEqual(self.timeline_object1.start, 5 * gst.SECOND)
        self.action_log.redo()
        self.failUnlessEqual(self.timeline_object1.start, 10 * gst.SECOND)

        self.timeline_object1.priority = 10
        self.action_log.begin("priority change")
        self.timeline_object1.priority = 20
        self.action_log.commit()

        self.failUnlessEqual(self.timeline_object1.priority, 20)
        self.action_log.undo()
        self.failUnlessEqual(self.timeline_object1.priority, 10)
        self.action_log.redo()
        self.failUnlessEqual(self.timeline_object1.priority, 20)

    def testUngroup(self):
        self.timeline_object1.start = 5 * gst.SECOND
        self.timeline_object1.duration = 20 * gst.SECOND

        self.timeline.addTimelineObject(self.timeline_object1)
        self.timeline.setSelectionToObj(self.track_object1, SELECT_ADD)

        self.failUnlessEqual(len(self.timeline.timeline_objects), 1)
        self.failUnlessEqual(self.timeline.timeline_objects[0].start,
                5 * gst.SECOND)
        self.failUnlessEqual(self.timeline.timeline_objects[0].duration,
                20 * gst.SECOND)

        self.action_log.begin("ungroup")
        self.timeline.ungroupSelection()
        self.action_log.commit()

        self.failUnlessEqual(len(self.timeline.timeline_objects), 2)
        self.failUnlessEqual(self.timeline.timeline_objects[0].start,
                5 * gst.SECOND)
        self.failUnlessEqual(self.timeline.timeline_objects[0].duration,
                20 * gst.SECOND)
        self.failUnlessEqual(self.timeline.timeline_objects[1].start,
                5 * gst.SECOND)
        self.failUnlessEqual(self.timeline.timeline_objects[1].duration,
                20 * gst.SECOND)

        self.action_log.undo()

        self.failUnlessEqual(len(self.timeline.timeline_objects), 1)
        self.failUnlessEqual(self.timeline.timeline_objects[0].start,
                5 * gst.SECOND)
        self.failUnlessEqual(self.timeline.timeline_objects[0].duration,
                20 * gst.SECOND)
예제 #27
0
class Project(Signallable, Loggable):
    """The base class for PiTiVi projects

    @ivar name: The name of the project
    @type name: C{str}
    @ivar description: A description of the project
    @type description: C{str}
    @ivar sources: The sources used by this project
    @type sources: L{SourceList}
    @ivar timeline: The timeline
    @type timeline: L{Timeline}
    @ivar pipeline: The timeline's pipeline
    @type pipeline: L{Pipeline}
    @ivar factory: The timeline factory
    @type factory: L{TimelineSourceFactory}
    @ivar format: The format under which the project is currently stored.
    @type format: L{FormatterClass}
    @ivar loaded: Whether the project is fully loaded or not.
    @type loaded: C{bool}

    Signals:
     - C{loaded} : The project is now fully loaded.
    """

    __signals__ = {
        "settings-changed": None,
    }

    def __init__(self, name="", uri=None, **kwargs):
        """
        name : the name of the project
        uri : the uri of the project
        """
        Loggable.__init__(self)
        self.log("name:%s, uri:%s", name, uri)
        self.name = name
        self.settings = None
        self.description = ""
        self.uri = uri
        self.urichanged = False
        self.format = None
        self.sources = SourceList()
        self.sources.connect("source-removed", self._sourceRemovedCb)

        self.settingssigid = 0
        self._dirty = False

        self.timeline = Timeline()

        self.factory = TimelineSourceFactory(self.timeline)
        self.pipeline = Pipeline()
        self.view_action = ViewAction()
        self.view_action.addProducers(self.factory)

    def release(self):
        self.pipeline.release()
        self.pipeline = None

    #{ Settings methods

    def _settingsChangedCb(self, unused_settings):
        self.emit('settings-changed')

    def getSettings(self):
        """
        return the currently configured settings.
        If no setting have been explicitely set, some smart settings will be
        chosen.
        """
        self.debug("self.settings %s", self.settings)
        return self.settings or self.getAutoSettings()

    def setSettings(self, settings):
        """
        Sets the given settings as the project's settings.
        If settings is None, the current settings will be unset
        """
        self.log("Setting %s as the project's settings", settings)
        if self.settings:
            self.settings.disconnect(self.settingssigid)
        self.settings = settings
        self.emit('settings-changed')
        self.settingssigid = self.settings.connect('settings-changed',
                                                   self._settingsChangedCb)

    def unsetSettings(self, unused_settings):
        """ Remove the currently configured settings."""
        self.setSettings(None)

    def getAutoSettings(self):
        """
        Computes and returns smart settings for the project.
        If the project only has one source, it will be that source's settings.
        If it has more than one, it will return the largest setting that suits
        all contained sources.
        """
        settings = ExportSettings()
        if not self.timeline:
            self.warning(
                "project doesn't have a timeline, returning default settings")
            return settings

        # FIXME: this is ugly, but rendering for now assumes at most one audio
        # and one video tracks
        have_audio = have_video = False
        for track in self.timeline.tracks:
            if isinstance(track.stream, VideoStream) and track.duration != 0:
                have_video = True
            elif isinstance(track.stream, AudioStream) and track.duration != 0:
                have_audio = True

        if not have_audio:
            settings.aencoder = None

        if not have_video:
            settings.vencoder = None

        return settings

    #}

    #{ Save and Load features

    def save(self, location=None, overwrite=False):
        """
        Save the project to the given location.

        @param location: The location to write to. If not specified, the
        current project location will be used (if set).
        @type location: C{URI}
        @param overwrite: Whether to overwrite existing location.
        @type overwrite: C{bool}
        """
        # import here to break circular import
        from pitivi.formatters.format import save_project
        from pitivi.formatters.base import FormatterError

        self.log("saving...")
        location = location or self.uri

        if location == None:
            raise FormatterError("Location unknown")

        save_project(self, location or self.uri, self.format, overwrite)

        self.uri = location

    def setModificationState(self, state):
        self._dirty = state

    def hasUnsavedModifications(self):
        return self._dirty

    def _sourceRemovedCb(self, sourclist, uri, factory):
        self.timeline.removeFactory(factory)
예제 #28
0
class  TestTimelineUndo(TestCase):
    def setUp(self):
        self.stream = new_stream()
        self.factory = new_source_factory()
        self.effect_factory = TestEffectFactory(self.stream)
        self.track1 = Track(self.stream)
        self.track2 = Track(self.stream)
        self.timeline = Timeline()
        self.timeline.addTrack(self.track1)
        self.timeline.addTrack(self.track2)
        self.track_object1 = SourceTrackObject(self.factory, self.stream)
        self.track_object2 = SourceTrackObject(self.factory, self.stream)
        self.track_effect1 = TrackEffect(self.effect_factory, self.stream)
        self.track_effect2 = TrackEffect(self.effect_factory, self.stream)
        self.track1.addTrackObject(self.track_object1)
        self.track2.addTrackObject(self.track_object2)
        self.timeline_object1 = TimelineObject(self.factory)
        self.timeline_object1.addTrackObject(self.track_object1)
        self.timeline_object1.addTrackObject(self.track_object2)
        self.action_log = UndoableActionLog()
        self.observer = TestTimelineLogObserver(self.action_log)
        self.observer.startObserving(self.timeline)

    def testAddTimelineObject(self):
        stacks = []
        def commitCb(action_log, stack, nested):
            stacks.append(stack)
        self.action_log.connect("commit", commitCb)

        self.action_log.begin("add clip")
        self.timeline.addTimelineObject(self.timeline_object1)
        self.action_log.commit()

        self.failUnlessEqual(len(stacks), 1)
        stack = stacks[0]
        self.failUnlessEqual(len(stack.done_actions), 1)
        action = stack.done_actions[0]
        self.failUnless(isinstance(action, TimelineObjectAdded))

        self.failUnless(self.timeline_object1 \
                in self.timeline.timeline_objects)
        self.action_log.undo()
        self.failIf(self.timeline_object1 \
                in self.timeline.timeline_objects)

        self.action_log.redo()
        self.failUnless(self.timeline_object1 \
                in self.timeline.timeline_objects)

    def testRemoveTimelineObject(self):
        stacks = []
        def commitCb(action_log, stack, nested):
            stacks.append(stack)
        self.action_log.connect("commit", commitCb)

        self.timeline.addTimelineObject(self.timeline_object1)
        self.action_log.begin("remove clip")
        self.timeline.removeTimelineObject(self.timeline_object1, deep=True)
        self.action_log.commit()

        self.failUnlessEqual(len(stacks), 1)
        stack = stacks[0]
        self.failUnlessEqual(len(stack.done_actions), 1)
        action = stack.done_actions[0]
        self.failUnless(isinstance(action, TimelineObjectRemoved))

        self.failIf(self.timeline_object1 \
                in self.timeline.timeline_objects)
        self.action_log.undo()
        self.failUnless(self.timeline_object1 \
                in self.timeline.timeline_objects)

        self.action_log.redo()
        self.failIf(self.timeline_object1 \
                in self.timeline.timeline_objects)

    def testAddEffectToTimelineObject(self):
        stacks = []
        pipeline = Pipeline()
        def commitCb(action_log, stack, nested):
            stacks.append(stack)
        self.action_log.connect("commit", commitCb)
        self.observer.pipeline = pipeline

        #FIXME Should I commit it and check there are 2 elements
        #in the stacks
        self.timeline.addTimelineObject(self.timeline_object1)
        self.track1.addTrackObject(self.track_effect1)

        self.action_log.begin("add effect")
        self.timeline_object1.addTrackObject(self.track_effect1)
        self.action_log.commit()

        self.failUnlessEqual(len(stacks), 1)
        stack = stacks[0]
        self.failUnlessEqual(len(stack.done_actions), 1)
        action = stack.done_actions[0]
        self.failUnless(isinstance(action, TrackEffectAdded))

        self.failUnless(self.track_effect1 \
                in self.timeline_object1.track_objects)
        self.failUnless(self.track_effect1 \
                in self.track1.track_objects)
        self.failUnless(len([effect for effect in \
                                self.timeline_object1.track_objects
                                if isinstance(effect, TrackEffect)]) == 1)
        self.failUnless(len([effect for effect in self.track1.track_objects
                             if isinstance(effect, TrackEffect)]) == 1)

        self.action_log.undo()
        self.failIf(self.track_effect1 \
                in self.timeline_object1.track_objects)
        self.failIf(self.track_effect1 \
                in self.track1.track_objects)

        self.action_log.redo()
        self.failUnless(len([effect for effect in
                                self.timeline_object1.track_objects
                                if isinstance(effect, TrackEffect)]) == 1)
        self.failUnless(len([effect for effect in self.track1.track_objects
                             if isinstance(effect, TrackEffect)]) == 1)

        self.timeline.removeTimelineObject(self.timeline_object1, deep=True)

    def testTimelineObjectPropertyChange(self):
        stacks = []
        def commitCb(action_log, stack, nested):
            stacks.append(stack)
        self.action_log.connect("commit", commitCb)

        self.timeline_object1.start = 5 * gst.SECOND
        self.timeline_object1.duration = 20 * gst.SECOND
        self.timeline.addTimelineObject(self.timeline_object1)
        self.action_log.begin("modify clip")
        self.timeline_object1.start = 10 * gst.SECOND
        self.action_log.commit()

        self.failUnlessEqual(len(stacks), 1)
        stack = stacks[0]
        self.failUnlessEqual(len(stack.done_actions), 1)
        action = stack.done_actions[0]
        self.failUnless(isinstance(action, TimelineObjectPropertyChanged))

        self.failUnlessEqual(self.timeline_object1.start, 10 * gst.SECOND)
        self.action_log.undo()
        self.failUnlessEqual(self.timeline_object1.start, 5 * gst.SECOND)
        self.action_log.redo()
        self.failUnlessEqual(self.timeline_object1.start, 10 * gst.SECOND)

        self.timeline_object1.priority = 10
        self.action_log.begin("priority change")
        self.timeline_object1.priority = 20
        self.action_log.commit()

        self.failUnlessEqual(self.timeline_object1.priority, 20)
        self.action_log.undo()
        self.failUnlessEqual(self.timeline_object1.priority, 10)
        self.action_log.redo()
        self.failUnlessEqual(self.timeline_object1.priority, 20)

    def testUngroup(self):
        self.timeline_object1.start = 5 * gst.SECOND
        self.timeline_object1.duration = 20 * gst.SECOND

        self.timeline.addTimelineObject(self.timeline_object1)
        self.timeline.setSelectionToObj(self.track_object1, SELECT_ADD)

        self.failUnlessEqual(len(self.timeline.timeline_objects), 1)
        self.failUnlessEqual(self.timeline.timeline_objects[0].start,
                5 * gst.SECOND)
        self.failUnlessEqual(self.timeline.timeline_objects[0].duration,
                20 * gst.SECOND)

        self.action_log.begin("ungroup")
        self.timeline.ungroupSelection()
        self.action_log.commit()

        self.failUnlessEqual(len(self.timeline.timeline_objects), 2)
        self.failUnlessEqual(self.timeline.timeline_objects[0].start,
                5 * gst.SECOND)
        self.failUnlessEqual(self.timeline.timeline_objects[0].duration,
                20 * gst.SECOND)
        self.failUnlessEqual(self.timeline.timeline_objects[1].start,
                5 * gst.SECOND)
        self.failUnlessEqual(self.timeline.timeline_objects[1].duration,
                20 * gst.SECOND)

        self.action_log.undo()

        self.failUnlessEqual(len(self.timeline.timeline_objects), 1)
        self.failUnlessEqual(self.timeline.timeline_objects[0].start,
                5 * gst.SECOND)
        self.failUnlessEqual(self.timeline.timeline_objects[0].duration,
                20 * gst.SECOND)
예제 #29
0
class TestGap(TestCase):
    def setUp(self):
        self.factory = StubFactory()
        self.stream = AudioStream(gst.Caps('audio/x-raw-int'))
        self.factory.addOutputStream(self.stream)
        self.track1 = Track(self.stream)
        self.timeline = Timeline()

    def makeTimelineObject(self):
        track_object = SourceTrackObject(self.factory, self.stream)
        self.track1.addTrackObject(track_object)
        timeline_object = TimelineObject(self.factory)
        timeline_object.addTrackObject(track_object)
        self.timeline.addTimelineObject(timeline_object)

        return timeline_object

    def testGapCmp(self):
        gap1 = Gap(None, None, start=10, duration=5)
        gap2 = Gap(None, None, start=10, duration=5)
        self.failUnlessEqual(gap1, gap2)

        gap2 = Gap(None, None, start=15, duration=4)
        self.failUnless(gap1 > gap2)
        self.failUnless(gap2 < gap1)

    def testFindAroundObject(self):
        timeline_object1 = self.makeTimelineObject()
        timeline_object2 = self.makeTimelineObject()

        timeline_object1.start = 5 * gst.SECOND
        timeline_object1.duration = 10 * gst.SECOND
        timeline_object2.start = 20 * gst.SECOND
        timeline_object2.duration = 10 * gst.SECOND

        left_gap, right_gap = Gap.findAroundObject(timeline_object1)
        self.failUnlessEqual(left_gap.left_object, None)
        self.failUnlessEqual(left_gap.right_object, timeline_object1)
        self.failUnlessEqual(left_gap.start, 0 * gst.SECOND)
        self.failUnlessEqual(left_gap.duration, 5 * gst.SECOND)
        self.failUnlessEqual(right_gap.left_object, timeline_object1)
        self.failUnlessEqual(right_gap.right_object, timeline_object2)
        self.failUnlessEqual(right_gap.start, 15 * gst.SECOND)
        self.failUnlessEqual(right_gap.duration, 5 * gst.SECOND)

        left_gap, right_gap = Gap.findAroundObject(timeline_object2)
        self.failUnlessEqual(left_gap.left_object, timeline_object1)
        self.failUnlessEqual(left_gap.right_object, timeline_object2)
        self.failUnlessEqual(left_gap.start, 15 * gst.SECOND)
        self.failUnlessEqual(left_gap.duration, 5 * gst.SECOND)
        self.failUnlessEqual(right_gap.left_object, timeline_object2)
        self.failUnlessEqual(right_gap.right_object, None)
        self.failUnlessEqual(right_gap.start, 30 * gst.SECOND)
        self.failUnlessEqual(right_gap.duration, infinity)

        # make the objects overlap
        timeline_object2.start = 10 * gst.SECOND
        left_gap, right_gap = Gap.findAroundObject(timeline_object1)
        self.failUnlessEqual(right_gap.left_object, timeline_object1)
        self.failUnlessEqual(right_gap.right_object, timeline_object2)
        self.failUnlessEqual(right_gap.start, 15 * gst.SECOND)
        self.failUnlessEqual(right_gap.duration, -5 * gst.SECOND)

    def testGapFinder(self):
        timeline_object1 = self.makeTimelineObject()
        timeline_object2 = self.makeTimelineObject()
        timeline_object3 = self.makeTimelineObject()
        timeline_object4 = self.makeTimelineObject()

        timeline_object1.start = 5 * gst.SECOND
        timeline_object1.duration = 10 * gst.SECOND
        timeline_object1.priority = 1

        timeline_object2.start = 20 * gst.SECOND
        timeline_object2.duration = 10 * gst.SECOND
        timeline_object2.priority = 1

        timeline_object3.start = 31 * gst.SECOND
        timeline_object3.duration = 10 * gst.SECOND
        timeline_object3.priority = 2

        timeline_object4.start = 50 * gst.SECOND
        timeline_object4.duration = 10 * gst.SECOND
        timeline_object4.priority = 2

        gap_finder = SmallestGapsFinder(
            set([timeline_object2, timeline_object3]))
        gap_finder.update(*Gap.findAroundObject(timeline_object2))
        gap_finder.update(*Gap.findAroundObject(timeline_object3))

        left_gap = gap_finder.left_gap
        right_gap = gap_finder.right_gap
        self.failUnlessEqual(left_gap.left_object, timeline_object1)
        self.failUnlessEqual(left_gap.right_object, timeline_object2)
        self.failUnlessEqual(left_gap.start, 15 * gst.SECOND)
        self.failUnlessEqual(left_gap.duration, 5 * gst.SECOND)
        self.failUnlessEqual(right_gap.left_object, timeline_object3)
        self.failUnlessEqual(right_gap.right_object, timeline_object4)
        self.failUnlessEqual(right_gap.start, 41 * gst.SECOND)
        self.failUnlessEqual(right_gap.duration, 9 * gst.SECOND)

        # make timeline_object3 and timeline_object4 overlap
        timeline_object3.duration = 20 * gst.SECOND

        gap_finder = SmallestGapsFinder(set([timeline_object4]))
        gap_finder.update(*Gap.findAroundObject(timeline_object4))
        left_gap = gap_finder.left_gap
        right_gap = gap_finder.right_gap
        self.failUnlessEqual(left_gap, invalid_gap)
        self.failUnlessEqual(right_gap.left_object, timeline_object4)
        self.failUnlessEqual(right_gap.right_object, None)
        self.failUnlessEqual(right_gap.start, 60 * gst.SECOND)
        self.failUnlessEqual(right_gap.duration, infinity)

        gap_finder = SmallestGapsFinder(set([timeline_object3]))
        gap_finder.update(*Gap.findAroundObject(timeline_object3))
        left_gap = gap_finder.left_gap
        right_gap = gap_finder.right_gap
        self.failUnlessEqual(left_gap.left_object, None)
        self.failUnlessEqual(left_gap.right_object, timeline_object3)
        self.failUnlessEqual(left_gap.start, 0 * gst.SECOND)
        self.failUnlessEqual(left_gap.duration, 31 * gst.SECOND)
        self.failUnlessEqual(right_gap, invalid_gap)

    def testFindAllGaps(self):

        simple = ((3 * gst.SECOND, 1 * gst.SECOND), (1 * gst.SECOND,
                                                     1 * gst.SECOND))

        objs = []
        for start, duration in simple:
            obj = self.makeTimelineObject()
            obj.start = start
            obj.duration = duration
            objs.append(obj)

        result = [(g.start, g.initial_duration) for g in Gap.findAllGaps(objs)]

        self.assertEquals(result, [
            (0 * gst.SECOND, 1 * gst.SECOND),
            (2 * gst.SECOND, 1 * gst.SECOND),
        ])

        complex = [
            (1 * gst.SECOND, 2 * gst.SECOND),
            (6 * gst.SECOND, 2 * gst.SECOND),
            (10 * gst.SECOND, 2 * gst.SECOND),
            (8 * gst.SECOND, 2 * gst.SECOND),
            (14 * gst.SECOND, 1 * gst.SECOND),
            (4 * gst.SECOND, 1 * gst.SECOND),
        ]

        objs = []
        for start, duration in complex:
            obj = self.makeTimelineObject()
            obj.start = start
            obj.duration = duration
            objs.append(obj)

        result = [(g.start, g.initial_duration) for g in Gap.findAllGaps(objs)]

        self.assertEquals(result, [
            (0 * gst.SECOND, 1 * gst.SECOND),
            (3 * gst.SECOND, 1 * gst.SECOND),
            (5 * gst.SECOND, 1 * gst.SECOND),
            (12 * gst.SECOND, 2 * gst.SECOND),
        ])

        complex.append((2 * gst.SECOND, 5 * gst.SECOND))

        objs = []
        for start, duration in complex:
            obj = self.makeTimelineObject()
            obj.start = start
            obj.duration = duration
            objs.append(obj)

        result = [(g.start, g.initial_duration) for g in Gap.findAllGaps(objs)]

        self.assertEquals(result, [
            (0 * gst.SECOND, 1 * gst.SECOND),
            (12 * gst.SECOND, 2 * gst.SECOND),
        ])
예제 #30
0
 def setUp(self):
     self.factory = StubFactory()
     self.stream = AudioStream(gst.Caps('audio/x-raw-int'))
     self.factory.addOutputStream(self.stream)
     self.track1 = Track(self.stream)
     self.timeline = Timeline()
예제 #31
0
class Project(Signallable, Loggable):
    """The base class for PiTiVi projects

    @ivar name: The name of the project
    @type name: C{str}
    @ivar description: A description of the project
    @type description: C{str}
    @ivar sources: The sources used by this project
    @type sources: L{SourceList}
    @ivar timeline: The timeline
    @type timeline: L{Timeline}
    @ivar pipeline: The timeline's pipeline
    @type pipeline: L{Pipeline}
    @ivar factory: The timeline factory
    @type factory: L{TimelineSourceFactory}
    @ivar format: The format under which the project is currently stored.
    @type format: L{FormatterClass}
    @ivar loaded: Whether the project is fully loaded or not.
    @type loaded: C{bool}

    Signals:
     - C{loaded} : The project is now fully loaded.
    """

    __signals__ = {
        "settings-changed": ['old', 'new'],
        "project-changed": [],
    }

    def __init__(self, name="", uri=None, **kwargs):
        """
        @param name: the name of the project
        @param uri: the uri of the project
        """
        Loggable.__init__(self)
        self.log("name:%s, uri:%s", name, uri)
        self.name = name
        self.settings = None
        self.description = ""
        self.uri = uri
        self.urichanged = False
        self.format = None
        self.sources = SourceList()
        self.sources.connect("source-added", self._sourceAddedCb)
        self.sources.connect("source-removed", self._sourceRemovedCb)

        self._dirty = False

        self.timeline = Timeline()

        self.factory = TimelineSourceFactory(self.timeline)
        self.pipeline = Pipeline()
        self.view_action = ViewAction()
        self.view_action.addProducers(self.factory)
        self.seeker = Seeker(80)

        self.settings = ExportSettings()
        self._videocaps = self.settings.getVideoCaps()

    def release(self):
        self.pipeline.release()
        self.pipeline = None

    #{ Settings methods

    def getSettings(self):
        """
        return the currently configured settings.
        """
        self.debug("self.settings %s", self.settings)
        return self.settings

    def setSettings(self, settings):
        """
        Sets the given settings as the project's settings.
        @param settings: The new settings for the project.
        @type settings: ExportSettings
        """
        assert settings
        self.log("Setting %s as the project's settings", settings)
        oldsettings = self.settings
        self.settings = settings
        self._projectSettingsChanged()
        self.emit('settings-changed', oldsettings, settings)

    #}

    #{ Save and Load features

    def setModificationState(self, state):
        self._dirty = state
        if state:
            self.emit('project-changed')

    def hasUnsavedModifications(self):
        return self._dirty

    def _projectSettingsChanged(self):
        settings = self.getSettings()
        self._videocaps = settings.getVideoCaps()
        if self.timeline:
            self.timeline.updateVideoCaps(self._videocaps)

        for fact in self.sources.getSources():
            fact.setFilterCaps(self._videocaps)
        if self.pipeline.getState() != gst.STATE_NULL:
            self.pipeline.stop()
            self.pipeline.pause()

    def _sourceAddedCb(self, sourcelist, factory):
        factory.setFilterCaps(self._videocaps)

    def _sourceRemovedCb(self, sourclist, uri, factory):
        self.timeline.removeFactory(factory)
예제 #32
0
파일: test_gap.py 프로젝트: bemasc/pitivi
 def setUp(self):
     self.factory = StubFactory()
     self.stream = AudioStream(gst.Caps('audio/x-raw-int'))
     self.factory.addOutputStream(self.stream)
     self.track1 = Track(self.stream)
     self.timeline = Timeline()
예제 #33
0
파일: test_gap.py 프로젝트: bemasc/pitivi
class TestGap(TestCase):
    def setUp(self):
        self.factory = StubFactory()
        self.stream = AudioStream(gst.Caps('audio/x-raw-int'))
        self.factory.addOutputStream(self.stream)
        self.track1 = Track(self.stream)
        self.timeline = Timeline()

    def makeTimelineObject(self):
        track_object = SourceTrackObject(self.factory, self.stream)
        self.track1.addTrackObject(track_object)
        timeline_object = TimelineObject(self.factory)
        timeline_object.addTrackObject(track_object)
        self.timeline.addTimelineObject(timeline_object)

        return timeline_object

    def testGapCmp(self):
        gap1 = Gap(None, None, start=10, duration=5)
        gap2 = Gap(None, None, start=10, duration=5)
        self.failUnlessEqual(gap1, gap2)

        gap2 = Gap(None, None, start=15, duration=4)
        self.failUnless(gap1 > gap2)
        self.failUnless(gap2 < gap1)

    def testFindAroundObject(self):
        timeline_object1 = self.makeTimelineObject()
        timeline_object2 = self.makeTimelineObject()

        timeline_object1.start = 5 * gst.SECOND
        timeline_object1.duration = 10 * gst.SECOND
        timeline_object2.start = 20 * gst.SECOND
        timeline_object2.duration = 10 * gst.SECOND

        left_gap, right_gap = Gap.findAroundObject(timeline_object1)
        self.failUnlessEqual(left_gap.left_object, None)
        self.failUnlessEqual(left_gap.right_object, timeline_object1)
        self.failUnlessEqual(left_gap.start, 0 * gst.SECOND)
        self.failUnlessEqual(left_gap.duration, 5 * gst.SECOND)
        self.failUnlessEqual(right_gap.left_object, timeline_object1)
        self.failUnlessEqual(right_gap.right_object, timeline_object2)
        self.failUnlessEqual(right_gap.start, 15 * gst.SECOND)
        self.failUnlessEqual(right_gap.duration, 5 * gst.SECOND)

        left_gap, right_gap = Gap.findAroundObject(timeline_object2)
        self.failUnlessEqual(left_gap.left_object, timeline_object1)
        self.failUnlessEqual(left_gap.right_object, timeline_object2)
        self.failUnlessEqual(left_gap.start, 15 * gst.SECOND)
        self.failUnlessEqual(left_gap.duration, 5 * gst.SECOND)
        self.failUnlessEqual(right_gap.left_object, timeline_object2)
        self.failUnlessEqual(right_gap.right_object, None)
        self.failUnlessEqual(right_gap.start, 30 * gst.SECOND)
        self.failUnlessEqual(right_gap.duration, infinity)

        # make the objects overlap
        timeline_object2.start = 10 * gst.SECOND
        left_gap, right_gap = Gap.findAroundObject(timeline_object1)
        self.failUnlessEqual(right_gap.left_object, timeline_object1)
        self.failUnlessEqual(right_gap.right_object, timeline_object2)
        self.failUnlessEqual(right_gap.start, 15 * gst.SECOND)
        self.failUnlessEqual(right_gap.duration, -5 * gst.SECOND)

    def testGapFinder(self):
        timeline_object1 = self.makeTimelineObject()
        timeline_object2 = self.makeTimelineObject()
        timeline_object3 = self.makeTimelineObject()
        timeline_object4 = self.makeTimelineObject()

        timeline_object1.start = 5 * gst.SECOND
        timeline_object1.duration = 10 * gst.SECOND
        timeline_object1.priority = 1

        timeline_object2.start = 20 * gst.SECOND
        timeline_object2.duration = 10 * gst.SECOND
        timeline_object2.priority = 1

        timeline_object3.start = 31 * gst.SECOND
        timeline_object3.duration = 10 * gst.SECOND
        timeline_object3.priority = 2

        timeline_object4.start = 50 * gst.SECOND
        timeline_object4.duration = 10 * gst.SECOND
        timeline_object4.priority = 2

        gap_finder = SmallestGapsFinder(set([timeline_object2,
                timeline_object3]))
        gap_finder.update(*Gap.findAroundObject(timeline_object2))
        gap_finder.update(*Gap.findAroundObject(timeline_object3))

        left_gap = gap_finder.left_gap
        right_gap = gap_finder.right_gap
        self.failUnlessEqual(left_gap.left_object, timeline_object1)
        self.failUnlessEqual(left_gap.right_object, timeline_object2)
        self.failUnlessEqual(left_gap.start, 15 * gst.SECOND)
        self.failUnlessEqual(left_gap.duration, 5 * gst.SECOND)
        self.failUnlessEqual(right_gap.left_object, timeline_object3)
        self.failUnlessEqual(right_gap.right_object, timeline_object4)
        self.failUnlessEqual(right_gap.start, 41 * gst.SECOND)
        self.failUnlessEqual(right_gap.duration, 9 * gst.SECOND)

        # make timeline_object3 and timeline_object4 overlap
        timeline_object3.duration = 20 * gst.SECOND

        gap_finder = SmallestGapsFinder(set([timeline_object4]))
        gap_finder.update(*Gap.findAroundObject(timeline_object4))
        left_gap = gap_finder.left_gap
        right_gap = gap_finder.right_gap
        self.failUnlessEqual(left_gap, invalid_gap)
        self.failUnlessEqual(right_gap.left_object, timeline_object4)
        self.failUnlessEqual(right_gap.right_object, None)
        self.failUnlessEqual(right_gap.start, 60 * gst.SECOND)
        self.failUnlessEqual(right_gap.duration, infinity)

        gap_finder = SmallestGapsFinder(set([timeline_object3]))
        gap_finder.update(*Gap.findAroundObject(timeline_object3))
        left_gap = gap_finder.left_gap
        right_gap = gap_finder.right_gap
        self.failUnlessEqual(left_gap.left_object, None)
        self.failUnlessEqual(left_gap.right_object, timeline_object3)
        self.failUnlessEqual(left_gap.start, 0 * gst.SECOND)
        self.failUnlessEqual(left_gap.duration, 31 * gst.SECOND)
        self.failUnlessEqual(right_gap, invalid_gap)

    def testFindAllGaps(self):

        simple = (
            (3 * gst.SECOND, 1 * gst.SECOND),
            (1 * gst.SECOND, 1 * gst.SECOND)
        )

        objs = []
        for start, duration in simple:
            obj = self.makeTimelineObject()
            obj.start = start
            obj.duration = duration
            objs.append(obj)

        result = [(g.start, g.initial_duration) for g in
            Gap.findAllGaps(objs)]

        self.assertEquals(result, [
            (0 * gst.SECOND, 1 * gst.SECOND),
            (2 * gst.SECOND, 1 * gst.SECOND),
        ])

        complex = [
            (1 * gst.SECOND, 2 * gst.SECOND),
            (6 * gst.SECOND, 2 * gst.SECOND),
            (10 * gst.SECOND, 2 * gst.SECOND),
            (8 * gst.SECOND, 2 * gst.SECOND),
            (14 * gst.SECOND, 1 * gst.SECOND),
            (4 * gst.SECOND, 1 * gst.SECOND),
        ]

        objs = []
        for start, duration in complex:
            obj = self.makeTimelineObject()
            obj.start = start
            obj.duration = duration
            objs.append(obj)

        result = [(g.start, g.initial_duration) for g in
            Gap.findAllGaps(objs)]

        self.assertEquals(result, [
            (0 * gst.SECOND, 1 * gst.SECOND),
            (3 * gst.SECOND, 1 * gst.SECOND),
            (5 * gst.SECOND, 1 * gst.SECOND),
            (12 * gst.SECOND, 2 * gst.SECOND),
        ])

        complex.append((2 * gst.SECOND, 5 * gst.SECOND))

        objs = []
        for start, duration in complex:
            obj = self.makeTimelineObject()
            obj.start = start
            obj.duration = duration
            objs.append(obj)

        result = [(g.start, g.initial_duration) for g in
            Gap.findAllGaps(objs)]

        self.assertEquals(result, [
            (0 * gst.SECOND, 1 * gst.SECOND),
            (12 * gst.SECOND, 2 * gst.SECOND),
        ])
예제 #34
0
class Project(Signallable, Loggable):
    """The base class for PiTiVi projects

    @ivar name: The name of the project
    @type name: C{str}
    @ivar description: A description of the project
    @type description: C{str}
    @ivar sources: The sources used by this project
    @type sources: L{SourceList}
    @ivar timeline: The timeline
    @type timeline: L{Timeline}
    @ivar pipeline: The timeline's pipeline
    @type pipeline: L{Pipeline}
    @ivar factory: The timeline factory
    @type factory: L{TimelineSourceFactory}
    @ivar format: The format under which the project is currently stored.
    @type format: L{FormatterClass}
    @ivar loaded: Whether the project is fully loaded or not.
    @type loaded: C{bool}

    Signals:
     - C{loaded} : The project is now fully loaded.
    """

    __signals__ = {
        "settings-changed" : ['old', 'new'],
        }

    def __init__(self, name="", uri=None, **kwargs):
        """
        name : the name of the project
        uri : the uri of the project
        """
        Loggable.__init__(self)
        self.log("name:%s, uri:%s", name, uri)
        self.name = name
        self.settings = None
        self.description = ""
        self.uri = uri
        self.urichanged = False
        self.format = None
        self.sources = SourceList()
        self.sources.connect("source-added", self._sourceAddedCb)
        self.sources.connect("source-removed", self._sourceRemovedCb)

        self._dirty = False

        self.timeline = Timeline()

        self.factory = TimelineSourceFactory(self.timeline)
        self.pipeline = Pipeline()
        self.view_action = ViewAction()
        self.view_action.addProducers(self.factory)
        self.seeker = Seeker(80)

        self.getCapsFromSettings()

    def getCapsFromSettings(self):
        settings = self.getSettings()
        #formatstr = "video/x-raw-rgb,width=(int)%d,height=(int)%d;"\
        #    "video/x-raw-yuv,width=(int)%d,height=(int)%d"
        #capstr = formatstr % (
        #    settings.videowidth,
        #    settings.videoheight,
        #    settings.videowidth,
        #    settings.videoheight)
        #self._videocaps = gst.Caps(capstr)
        self._videocaps = settings.getVideoCaps()

    def release(self):
        self.pipeline.release()
        self.pipeline = None

    #{ Settings methods

    def getSettings(self):
        """
        return the currently configured settings.
        If no setting have been explicitely set, some smart settings will be
        chosen.
        """
        self.debug("self.settings %s", self.settings)
        return self.settings or self.getAutoSettings()

    def setSettings(self, settings):
        """
        Sets the given settings as the project's settings.
        If settings is None, the current settings will be unset
        """
        self.log("Setting %s as the project's settings", settings)
        oldsettings = self.settings
        self.settings = settings
        self._projectSettingsChanged()
        self.emit('settings-changed', oldsettings, settings)

    def unsetSettings(self, unused_settings):
        """ Remove the currently configured settings."""
        self.setSettings(None)

    def getAutoSettings(self):
        """
        Computes and returns smart settings for the project.
        If the project only has one source, it will be that source's settings.
        If it has more than one, it will return the largest setting that suits
        all contained sources.
        """
        settings = ExportSettings()
        if not self.timeline:
            self.warning("project doesn't have a timeline, returning default settings")
            return settings

        # FIXME: this is ugly, but rendering for now assumes at most one audio
        # and one video tracks
        have_audio = have_video = False
        for track in self.timeline.tracks:
            if isinstance(track.stream, VideoStream) and track.duration != 0:
                have_video = True
            elif isinstance(track.stream, AudioStream) and track.duration != 0:
                have_audio = True

        if not have_audio:
            settings.aencoder = None

        if not have_video:
            settings.vencoder = None

        return settings

    #}

    #{ Save and Load features

    def save(self, location=None, overwrite=False):
        """
        Save the project to the given location.

        @param location: The location to write to. If not specified, the
        current project location will be used (if set).
        @type location: C{URI}
        @param overwrite: Whether to overwrite existing location.
        @type overwrite: C{bool}
        """
        # import here to break circular import
        from pitivi.formatters.format import save_project
        from pitivi.formatters.base import FormatterError

        self.log("saving...")
        location = location or self.uri

        if location == None:
            raise FormatterError("Location unknown")

        save_project(self, location or self.uri, self.format,
                     overwrite)

        self.uri = location

    def setModificationState(self, state):
        self._dirty = state

    def hasUnsavedModifications(self):
        return self._dirty

    def _projectSettingsChanged(self):
        self.getCapsFromSettings()
        for fact in self.sources.getSources():
            fact.setFilterCaps(self._videocaps)
        if self.pipeline.getState() != gst.STATE_NULL:
            self.pipeline.stop()
            self.pipeline.pause()

    def _sourceAddedCb(self, sourcelist, factory):
        factory.setFilterCaps(self._videocaps)

    def _sourceRemovedCb(self, sourclist, uri, factory):
        self.timeline.removeFactory(factory)
예제 #35
0
class TestStillImage(TestCase):
    clip_duration = 3 * gst.SECOND
    def setUp(self):
        self.mainloop = gobject.MainLoop()

        samples = os.path.join(os.path.dirname(__file__), "samples")
        self.facs = []
        self.facs.append([PictureFileSourceFactory('file://' + os.path.join(samples, "flat_colour1_640x480.png")), VideoStream(gst.Caps("video/x-raw-rgb,bpp=(int)24,depth=(int)24,endianness=(int)4321,red_mask=(int)16711680,green_mask=(int)65280,blue_mask=(int)255"))])
        self.facs.append([PictureFileSourceFactory('file://' + os.path.join(samples, "flat_colour2_640x480.png")), VideoStream(gst.Caps("video/x-raw-rgb,bpp=(int)24,depth=(int)24,endianness=(int)4321,red_mask=(int)16711680,green_mask=(int)65280,blue_mask=(int)255"))])
        self.facs.append([PictureFileSourceFactory('file://' + os.path.join(samples, "flat_colour3_320x180.png")), VideoStream(gst.Caps("video/x-raw-rgb,bpp=(int)24,depth=(int)24,endianness=(int)4321,red_mask=(int)16711680,green_mask=(int)65280,blue_mask=(int)255"))])
        # one video with a different resolution
        self.facs.append([VideoTestSourceFactory(), VideoStream(gst.Caps('video/x-raw-yuv,width=(int)640,height=(int)480,format=(fourcc)I420'))])

        # configure durations and add output streams to factories
        for fac in self.facs:
            factory = fac[0]
            stream = fac[1]
            factory.duration = self.clip_duration
            factory.addOutputStream(stream)
        self.track_objects = []
        self.track = Track(self.facs[0][1])
        self.timeline = Timeline()
        self.timeline.addTrack(self.track)

        vsettings = StreamEncodeSettings(encoder="theoraenc")
        rsettings = RenderSettings(settings=[vsettings],
                                   muxer="oggmux")
        self.fakesink = common.FakeSinkFactory()
        rendersink = RenderSinkFactory(RenderFactory(settings=rsettings),
                                       self.fakesink)
        self.render = RenderAction()
        self.pipeline = Pipeline()
        self.pipeline.connect("eos", self._renderEOSCb)
        self.pipeline.connect("error", self._renderErrorCb)
        self.pipeline.addAction(self.render)
        self.render.addConsumers(rendersink)
        timeline_factory = TimelineSourceFactory(self.timeline)
        self.render.addProducers(timeline_factory)

    def tearDown(self):
        self.mainloop.quit()

    def configureStreams(self, inputs, offsets):
        count = 0
        for i in inputs:
            factory = self.facs[i][0]
            stream = self.facs[i][1]
            track_object = SourceTrackObject(factory, stream)
            self.track_objects.append(track_object)
            track_object.start = offsets[count]
            self.track.addTrackObject(track_object)
            count += 1

    def startRender(self):
        self.render.activate()
        self.data_written = 0
        self.fakesink.bins[0].props.signal_handoffs = True
        self.fakesink.bins[0].connect("handoff", self._fakesinkHandoffCb)
        self.pipeline.play()
        self.mainloop.run()

    def _fakesinkHandoffCb(self, fakesink, buf, pad):
        self.data_written += buf.size

    def _renderEOSCb(self, obj):
        self.mainloop.quit()
        # check the render was successful
        self.assertTrue(self.data_written > 0)

    def _renderErrorCb(self, obj, error, details):
        print "Error: %s\nDetails: %s" % (str(error), str(details))
        self.fail("Pipeline rendering error")

    def cleanUp(self):
        self.render.deactivate()
        self.track.removeAllTrackObjects()
        self.track_objects = []

    def testRendering(self):
        # use one of the still image streams
        self.configureStreams(range(1), [0])
        self.startRender()
        self.cleanUp()


        # use two images with the same resolution and concatenate them
        self.configureStreams(range(2), [0, self.clip_duration])
        self.startRender()
        self.cleanUp()


        # concatenate images with different resolutions
        self.configureStreams(range(3), [0, self.clip_duration, 2 * self.clip_duration])
        self.startRender()
        self.cleanUp()


        # mix images with different resolutions by overlapping
        self.configureStreams(range(3), [0, self.clip_duration // 2, self.clip_duration])
        self.startRender()
        self.cleanUp()


        # mix images and videos with the same resolution
        self.configureStreams([0, 1, 3], [0, self.clip_duration, 2 * self.clip_duration])
        self.startRender()
        self.cleanUp()


        # mix images and videos with different resolutions
        self.configureStreams(range(4), [0, self.clip_duration, 2 * self.clip_duration, 3 * self.clip_duration])
        self.startRender()
        self.cleanUp()


        # mix images and videos with different resolutions by overlapping
        self.configureStreams(range(4), [0, self.clip_duration // 2, self.clip_duration, (3 * self.clip_duration) // 2])
        self.startRender()
        self.cleanUp()
예제 #36
0
    def setUp(self):
        self.mainloop = gobject.MainLoop()

        samples = os.path.join(os.path.dirname(__file__), "samples")
        self.facs = []
        self.facs.append([
            PictureFileSourceFactory(
                'file://' + os.path.join(samples, "flat_colour1_640x480.png")),
            VideoStream(
                gst.Caps(
                    "video/x-raw-rgb,bpp=(int)24,depth=(int)24,endianness=(int)4321,red_mask=(int)16711680,green_mask=(int)65280,blue_mask=(int)255"
                ))
        ])
        self.facs.append([
            PictureFileSourceFactory(
                'file://' + os.path.join(samples, "flat_colour2_640x480.png")),
            VideoStream(
                gst.Caps(
                    "video/x-raw-rgb,bpp=(int)24,depth=(int)24,endianness=(int)4321,red_mask=(int)16711680,green_mask=(int)65280,blue_mask=(int)255"
                ))
        ])
        self.facs.append([
            PictureFileSourceFactory(
                'file://' + os.path.join(samples, "flat_colour3_320x180.png")),
            VideoStream(
                gst.Caps(
                    "video/x-raw-rgb,bpp=(int)24,depth=(int)24,endianness=(int)4321,red_mask=(int)16711680,green_mask=(int)65280,blue_mask=(int)255"
                ))
        ])
        # one video with a different resolution
        self.facs.append([
            VideoTestSourceFactory(),
            VideoStream(
                gst.Caps(
                    'video/x-raw-yuv,width=(int)640,height=(int)480,format=(fourcc)I420'
                ))
        ])

        # configure durations and add output streams to factories
        for fac in self.facs:
            factory = fac[0]
            stream = fac[1]
            factory.duration = self.clip_duration
            factory.addOutputStream(stream)
        self.track_objects = []
        self.track = Track(self.facs[0][1])
        self.timeline = Timeline()
        self.timeline.addTrack(self.track)

        vsettings = StreamEncodeSettings(encoder="theoraenc")
        rsettings = RenderSettings(settings=[vsettings], muxer="oggmux")
        self.fakesink = common.FakeSinkFactory()
        rendersink = RenderSinkFactory(RenderFactory(settings=rsettings),
                                       self.fakesink)
        self.render = RenderAction()
        self.pipeline = Pipeline()
        self.pipeline.connect("eos", self._renderEOSCb)
        self.pipeline.connect("error", self._renderErrorCb)
        self.pipeline.addAction(self.render)
        self.render.addConsumers(rendersink)
        timeline_factory = TimelineSourceFactory(self.timeline)
        self.render.addProducers(timeline_factory)
예제 #37
0
파일: project.py 프로젝트: bemasc/pitivi
class Project(Signallable, Loggable):
    """The base class for PiTiVi projects

    @ivar name: The name of the project
    @type name: C{str}
    @ivar description: A description of the project
    @type description: C{str}
    @ivar sources: The sources used by this project
    @type sources: L{SourceList}
    @ivar timeline: The timeline
    @type timeline: L{Timeline}
    @ivar pipeline: The timeline's pipeline
    @type pipeline: L{Pipeline}
    @ivar factory: The timeline factory
    @type factory: L{TimelineSourceFactory}
    @ivar format: The format under which the project is currently stored.
    @type format: L{FormatterClass}
    @ivar loaded: Whether the project is fully loaded or not.
    @type loaded: C{bool}

    Signals:
     - C{loaded} : The project is now fully loaded.
    """

    __signals__ = {
        "settings-changed" : ['old', 'new'],
        "project-changed" : [],
        }

    def __init__(self, name="", uri=None, **kwargs):
        """
        @param name: the name of the project
        @param uri: the uri of the project
        """
        Loggable.__init__(self)
        self.log("name:%s, uri:%s", name, uri)
        self.name = name
        self.settings = None
        self.description = ""
        self.uri = uri
        self.urichanged = False
        self.format = None
        self.sources = SourceList()
        self.sources.connect("source-added", self._sourceAddedCb)
        self.sources.connect("source-removed", self._sourceRemovedCb)

        self._dirty = False

        self.timeline = Timeline()

        self.factory = TimelineSourceFactory(self.timeline)
        self.pipeline = Pipeline()
        self.view_action = ViewAction()
        self.view_action.addProducers(self.factory)
        self.seeker = Seeker(80)

        self.settings = ExportSettings()
        self._videocaps = self.settings.getVideoCaps()

    def release(self):
        self.pipeline.release()
        self.pipeline = None

    #{ Settings methods

    def getSettings(self):
        """
        return the currently configured settings.
        """
        self.debug("self.settings %s", self.settings)
        return self.settings

    def setSettings(self, settings):
        """
        Sets the given settings as the project's settings.
        @param settings: The new settings for the project.
        @type settings: ExportSettings
        """
        assert settings
        self.log("Setting %s as the project's settings", settings)
        oldsettings = self.settings
        self.settings = settings
        self._projectSettingsChanged()
        self.emit('settings-changed', oldsettings, settings)

    #}

    #{ Save and Load features

    def setModificationState(self, state):
        self._dirty = state
        if state:
            self.emit('project-changed')

    def hasUnsavedModifications(self):
        return self._dirty

    def _projectSettingsChanged(self):
        settings = self.getSettings()
        self._videocaps = settings.getVideoCaps()
        if self.timeline:
            self.timeline.updateVideoCaps(self._videocaps)

        for fact in self.sources.getSources():
            fact.setFilterCaps(self._videocaps)
        if self.pipeline.getState() != gst.STATE_NULL:
            self.pipeline.stop()
            self.pipeline.pause()

    def _sourceAddedCb(self, sourcelist, factory):
        factory.setFilterCaps(self._videocaps)

    def _sourceRemovedCb(self, sourclist, uri, factory):
        self.timeline.removeFactory(factory)