def testPendingLink(self): a = Action() p = Pipeline() src = common.FakeGnlFactory() src.addOutputStream(VideoStream(gst.Caps("video/x-raw-yuv"), pad_name="src")) sink = common.FakeSinkFactory() sink.addInputStream(MultimediaStream(gst.Caps("any"), pad_name="sink")) # set the link, it will be activated once the pad is added a.setLink(src, sink) # Let's see if the link is present self.assertEquals(a._links, [(src, sink, None, None)]) p.setAction(a) gst.debug("about to activate action") a.activate() # only the producer and the consumer are created, the other elements are # created dinamically self.assertEquals(len(list(p._pipeline.elements())), 2) p.setState(STATE_PLAYING) time.sleep(1) # and make sure that all other elements were created (4) # FIXME if it's failing here, run the test a few times trying to raise # the time.sleep() above, it may just be racy... self.assertEquals(len(list(p._pipeline.elements())), 4) a.deactivate() p.setState(STATE_NULL) self.assertEquals(len(list(p._pipeline.elements())), 0) p.release()
def testDynamicLink(self): a = DynamicAction() p = Pipeline() src = common.FakeGnlFactory() src.addOutputStream(VideoStream(gst.Caps("video/x-raw-yuv"), pad_name="src")) # the link will be added dynamically self.assertEquals(a._links, []) p.setAction(a) a.addProducers(src) self.assertEquals(len(list(p._pipeline.elements())), 0) a.activate() # theoretically... there shouldn't only be the source, since # the pad for the source hasn't been created yet (and therefore not # requiring a consumer self.assertEquals(len(list(p._pipeline.elements())), 1) p.setState(STATE_PLAYING) time.sleep(1) p.getState() # and make sure that all other elements were created (4) self.assertEquals(len(list(p._pipeline.elements())), 4) p.setState(STATE_READY) time.sleep(1) a.deactivate() self.assertEquals(len(list(p._pipeline.elements())), 0) p.setState(STATE_NULL) p.release()
class TestPipeline(TestCase): def setUp(self): TestCase.setUp(self) gst.debug("start") self.pipeline = Pipeline() self.monitor = SignalMonitor(self.pipeline, 'action-added', 'action-removed', 'factory-added', 'factory-removed', 'state-changed') self.assertEquals(self.monitor.action_added_count, 0) self.assertEquals(self.monitor.action_added_collect, []) def tearDown(self): self.pipeline.setState(STATE_NULL) self.pipeline.release() self.monitor.disconnectFromObj(self.pipeline) del self.pipeline del self.monitor TestCase.tearDown(self) def testAddRemoveActionSimple(self): """ Simple add/remove of Actions """ ac1 = BogusAction() # add the action to the pipeline res = self.pipeline.addAction(ac1) # the returned value should be the given action self.assertEquals(res, ac1) # it should now be in the list of actions... self.failUnlessEqual(self.pipeline.actions, [ac1]) # ... and the action should be set to that pipeline self.failUnlessEqual(ac1.pipeline, self.pipeline) # the 'action-added' signal should be triggered once self.assertEquals(self.monitor.action_added_count, 1) # And it contained our action self.assertEquals(self.monitor.action_added_collect, [(ac1, )]) # if we try to add that action again, it should be silently ignored res = self.pipeline.addAction(ac1) self.assertEquals(res, ac1) # the list of actions shouldn't have changed self.failUnlessEqual(self.pipeline.actions, [ac1]) # it shouldn't have changed the pipeline set on action self.failUnlessEqual(ac1.pipeline, self.pipeline) # the 'action-added' signal should NOT have been triggered again self.assertEquals(self.monitor.action_added_count, 1) # And now to remove it self.pipeline.removeAction(ac1) # the 'action-removed' signal should have been triggered once.. self.assertEquals(self.monitor.action_removed_count, 1) # .. with the action as an argument self.assertEquals(self.monitor.action_removed_collect, [(ac1, )]) # And there should be no actions left on the pipeline self.assertEquals(self.pipeline.actions, []) def testAddRemoveActionAdvanced(self): """ Advanced add/remove of Actions """ ac1 = BogusAction() ac2 = BogusAction() p2 = Pipeline() res = self.pipeline.addAction(ac1) self.assertEquals(self.pipeline.actions, [ac1]) # we can't add an action to two pipelines at the same time self.failUnlessRaises(PipelineError, p2.addAction, ac1) self.pipeline.removeAction(ac1) self.assertEquals(self.pipeline.actions, []) res = self.pipeline.setAction(ac1) self.assertEquals(res, ac1) self.assertEquals(self.pipeline.actions, [ac1]) # calling setAction while a similar action is already set should # return the existing action and not change anything else res = self.pipeline.setAction(ac2) self.assertEquals(res, ac1) self.assertEquals(self.pipeline.actions, [ac1]) # we can't remove active actions while in PAUSED/PLAYING self.pipeline.setState(STATE_PAUSED) ac1.state = STATE_ACTIVE self.assertEquals(self.pipeline.getState(), STATE_PAUSED) self.failUnlessRaises(PipelineError, self.pipeline.removeAction, ac1) # but we can remove deactivated actions while in PAUSED/PLAYING self.pipeline.setState(STATE_PAUSED) ac1.state = STATE_NOT_ACTIVE self.assertEquals(self.pipeline.getState(), STATE_PAUSED) self.pipeline.removeAction(ac1) # we can add actions while in PAUSED/PLAYING res = self.pipeline.addAction(ac2) self.assertEquals(res, ac2) self.assertEquals(self.pipeline.actions, [ac2]) self.pipeline.removeAction(ac2) p2.release() def testStateChange(self): loop = gobject.MainLoop() bag = {"last_state": None} def state_changed_cb(pipeline, state, bag, loop): bag["last_state"] = state loop.quit() self.pipeline.connect('state-changed', state_changed_cb, bag, loop) # playing self.pipeline.setState(STATE_PLAYING) loop.run() self.failUnlessEqual(bag["last_state"], STATE_PLAYING) self.failUnlessEqual(self.pipeline.getState(), STATE_PLAYING) self.assertEquals(self.monitor.state_changed_count, 1) # playing again self.pipeline.setState(STATE_PLAYING) self.assertEquals(self.monitor.state_changed_count, 1) # ready self.pipeline.setState(STATE_READY) loop.run() self.failUnlessEqual(bag["last_state"], STATE_READY) self.failUnlessEqual(self.pipeline.getState(), STATE_READY) self.assertEquals(self.monitor.state_changed_count, 2) # PLAYING self.pipeline.play() loop.run() self.failUnlessEqual(bag["last_state"], STATE_PLAYING) self.failUnlessEqual(self.pipeline.getState(), STATE_PLAYING) self.assertEquals(self.monitor.state_changed_count, 3) # PAUSE self.pipeline.pause() loop.run() self.failUnlessEqual(bag["last_state"], STATE_PAUSED) self.failUnlessEqual(self.pipeline.getState(), STATE_PAUSED) self.assertEquals(self.monitor.state_changed_count, 4) self.pipeline.stop() loop.run() self.failUnlessEqual(bag["last_state"], STATE_READY) self.failUnlessEqual(self.pipeline.getState(), STATE_READY) self.assertEquals(self.monitor.state_changed_count, 5) def testGetReleaseBinForFactoryStream(self): factory = VideoTestSourceFactory() stream = VideoStream(gst.Caps('video/x-raw-rgb; video/x-raw-yuv'), 'src0') factory.addOutputStream(stream) # try to get a cached instance self.failUnlessRaises(PipelineError, self.pipeline.getBinForFactoryStream, factory, stream, False) # create a bin bin1 = self.pipeline.getBinForFactoryStream(factory, stream, True) self.failUnless(isinstance(bin1, gst.Element)) # return the cached instance bin2 = self.pipeline.getBinForFactoryStream(factory, stream, True) self.failUnlessEqual(id(bin1), id(bin2)) self.pipeline.releaseBinForFactoryStream(factory, stream) self.pipeline.releaseBinForFactoryStream(factory, stream) # the bin has been destroyed at this point self.failUnlessRaises(PipelineError, self.pipeline.releaseBinForFactoryStream, factory, stream) # we should get a new instance bin2 = self.pipeline.getBinForFactoryStream(factory, stream, True) self.pipeline.releaseBinForFactoryStream(factory, stream) def testGetReleaseTeeForFactoryStream(self): factory = VideoTestSourceFactory() stream = VideoStream(gst.Caps('video/x-raw-rgb; video/x-raw-yuv'), 'src') factory.addOutputStream(stream) self.failUnlessRaises(PipelineError, self.pipeline.getTeeForFactoryStream, factory, stream, True) # getBinForFactoryStream(factory, stream) must be called before self.failUnlessRaises(PipelineError, self.pipeline.getTeeForFactoryStream, factory, stream, True) # create the bin bin1 = self.pipeline.getBinForFactoryStream(factory, stream, True) # try to get a cached tee self.failUnlessRaises(PipelineError, self.pipeline.getTeeForFactoryStream, factory, stream, False) # create tee tee1 = self.pipeline.getTeeForFactoryStream(factory, stream, True) self.failUnless(isinstance(tee1, gst.Element)) # get the cached instance tee2 = self.pipeline.getTeeForFactoryStream(factory, stream, True) self.failUnlessEqual(id(tee1), id(tee2)) # release self.pipeline.releaseTeeForFactoryStream(factory, stream) # there's still a tee alive, so we can't release the bin #self.failUnlessRaises(PipelineError, # self.pipeline.releaseBinForFactoryStream, factory, stream) self.pipeline.releaseTeeForFactoryStream(factory, stream) self.failUnlessRaises(PipelineError, self.pipeline.releaseTeeForFactoryStream, factory, stream) # should always fail with a sink bin factory2 = FakeSinkFactory() stream2 = VideoStream(gst.Caps('video/x-raw-rgb; video/x-raw-yuv'), 'src') factory2.addInputStream(stream2) self.failUnlessRaises(PipelineError, self.pipeline.getTeeForFactoryStream, factory2, stream2, True) self.pipeline.releaseBinForFactoryStream(factory, stream) def testGetReleaseQueueForFactoryStream(self): factory = FakeSinkFactory() stream = VideoStream(gst.Caps('any'), 'sink') factory.addInputStream(stream) self.failUnlessRaises(PipelineError, self.pipeline.getQueueForFactoryStream, factory, stream, True) # getBinForFactoryStream(factory, stream) must be called before self.failUnlessRaises(PipelineError, self.pipeline.getQueueForFactoryStream, factory, stream, True) # create the bin bin1 = self.pipeline.getBinForFactoryStream(factory, stream, True) # try to get a cached queue self.failUnlessRaises(PipelineError, self.pipeline.getQueueForFactoryStream, factory, stream, False) # create queue queue1 = self.pipeline.getQueueForFactoryStream(factory, stream, True) self.failUnless(isinstance(queue1, gst.Element)) gst.debug("pouet") # get the cached instance queue2 = self.pipeline.getQueueForFactoryStream(factory, stream, True) self.failUnlessEqual(id(queue1), id(queue2)) # release self.pipeline.releaseQueueForFactoryStream(factory, stream) gst.debug("pouet") # there's still a queue alive, so we can't release the bin self.failUnlessRaises(PipelineError, self.pipeline.releaseBinForFactoryStream, factory, stream) self.pipeline.releaseQueueForFactoryStream(factory, stream) gst.debug("pouet2") self.failUnlessRaises(PipelineError, self.pipeline.releaseQueueForFactoryStream, factory, stream) # should always fail with a src bin factory2 = VideoTestSourceFactory() stream2 = VideoStream(gst.Caps('any'), 'src') factory2.addOutputStream(stream2) bin1 = self.pipeline.getBinForFactoryStream(factory, stream, True) self.failUnlessRaises(PipelineError, self.pipeline.getQueueForFactoryStream, factory2, stream2, True) self.pipeline.releaseBinForFactoryStream(factory, stream) self.pipeline.releaseBinForFactoryStream(factory, stream) self.assertEquals(factory.current_bins, 0)
def testPipelineAction(self): """Testing pipeline state interaction""" p = Pipeline() a = Action() src = VideoTestSourceFactory() sink = common.FakeSinkFactory() sink.addInputStream(MultimediaStream(gst.Caps("any"), pad_name="sink")) # set the Action on the Pipeline p.setAction(a) self.assertEquals(p.actions, [a]) # set the Producer and Consumer a.addProducers(src) a.addConsumers(sink) a.setLink(src, sink) # activate the Action a.activate() self.failUnlessEqual(src.current_bins, 1) self.failUnlessEqual(sink.current_bins, 1) # call get*ForFactoryStream(..., automake=False). They will raise # exceptions if the action didn't create the elements. bin = p.getBinForFactoryStream(src, automake=False) p.releaseBinForFactoryStream(src) tee = p.getTeeForFactoryStream(src, automake=False) p.releaseTeeForFactoryStream(src) bin = p.getBinForFactoryStream(sink, automake=False) queue = p.getQueueForFactoryStream(sink, automake=False) self.failUnlessEqual(queue.get_pad('src').get_peer().get_parent(), bin) p.releaseBinForFactoryStream(sink) p.releaseQueueForFactoryStream(sink) # switch to PLAYING p.setState(STATE_PLAYING) # wait half a second # switch to READY p.setState(STATE_READY) # deactivate action a.deactivate() # since we're the last Action to be release, the tees # and queues should have gone self.failUnlessEqual(src.current_bins, 0) self.failUnlessEqual(sink.current_bins, 0) # remove the action from the pipeline p.removeAction(a) # the gst.Pipeline should be empty ! self.assertEquals(list(p._pipeline.elements()), []) p.release()