/* * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see <http://www.gnu.org/licenses/>. */ package org.gstreamer; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.lang.ref.WeakReference; import java.util.Iterator; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import org.gstreamer.lowlevel.GstBinAPI; import org.gstreamer.lowlevel.GstPipelineAPI; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; /** * * @author wayne */ public class BinTest { public BinTest() { } @BeforeClass public static void setUpClass() throws Exception { Gst.init("BinTest", new String[] {}); } @AfterClass public static void tearDownClass() throws Exception { Gst.deinit(); } @Before public void setUp() throws Exception { } @After public void tearDown() throws Exception { } public boolean waitGC(WeakReference<? extends Object> ref) throws InterruptedException { System.gc(); for (int i = 0; ref.get() != null && i < 20; ++i) { Thread.sleep(10); System.gc(); } return ref.get() == null; } @Test public void testGetElements() { Bin bin = new Bin("test"); Element e1 = ElementFactory.make("fakesrc", "source"); Element e2 = ElementFactory.make("fakesink", "sink"); bin.addMany(e1, e2); List<Element> elements = bin.getElements(); assertFalse("Bin returned empty list from getElements", elements.isEmpty()); assertTrue("Element list does not contain e1", elements.contains(e1)); assertTrue("Element list does not contain e2", elements.contains(e2)); } @Test public void testGetSinks() throws Exception { Bin bin = new Bin("test"); Element e1 = ElementFactory.make("fakesrc", "source"); Element e2 = ElementFactory.make("fakesink", "sink"); bin.addMany(e1, e2); List<Element> elements = bin.getSinks(); assertFalse("Bin returned empty list from getElements", elements.isEmpty()); assertTrue("Element list does not contain sink", elements.contains(e2)); } @Test public void testGetSources() throws Exception { Bin bin = new Bin("test"); Element e1 = ElementFactory.make("fakesrc", "source"); Element e2 = ElementFactory.make("fakesink", "sink"); bin.addMany(e1, e2); List<Element> elements = bin.getSources(); assertFalse("Bin returned empty list from getElements", elements.isEmpty()); assertTrue("Element list does not contain source", elements.contains(e1)); } @Test public void testGetElementByName() throws Exception { Bin bin = new Bin("test"); Element e1 = ElementFactory.make("fakesrc", "source"); Element e2 = ElementFactory.make("fakesink", "sink"); bin.addMany(e1, e2); assertEquals("source not returned", e1, bin.getElementByName("source")); assertEquals("sink not returned", e2, bin.getElementByName("sink")); } @Test public void testElementAddedCallback() throws Exception { Bin bin = new Bin("test"); final Element e1 = ElementFactory.make("fakesrc", "source"); final Element e2 = ElementFactory.make("fakesink", "sink"); final AtomicInteger added = new AtomicInteger(0); bin.connect(new Bin.ELEMENT_ADDED() { public void elementAdded(Bin b, Element elem) { if (elem == e1 || elem == e2) { added.incrementAndGet(); } } }); bin.addMany(e1, e2); assertEquals("Callback not called", 2, added.get()); } @Test public void testElementRemovedCallback() { Bin bin = new Bin("test"); final Element e1 = ElementFactory.make("fakesrc", "source"); final Element e2 = ElementFactory.make("fakesink", "sink"); final AtomicInteger removed = new AtomicInteger(0); bin.connect(new Bin.ELEMENT_ADDED() { public void elementAdded(Bin b, Element elem) { if (elem == e1 || elem == e2) { removed.incrementAndGet(); } } }); bin.addMany(e1, e2); assertEquals("Callback not called", 2, removed.get()); } @Test public void addLinked() { /* adding an element with linked pads to a bin unlinks the pads */ Pipeline pipeline = new Pipeline((String) null); assertNotNull("Could not create pipeline", pipeline); Element src = ElementFactory.make("fakesrc", null); assertNotNull("Could not create fakesrc", src); Element sink = ElementFactory.make("fakesink", null); assertNotNull("Could not create fakesink", sink); Pad srcpad = src.getStaticPad("src"); assertNotNull("Could not get src pad", srcpad); Pad sinkpad = sink.getStaticPad("sink"); assertNotNull("Could not get sink pad", sinkpad); assertEquals("Could not link src and sink pads", PadLinkReturn.OK, srcpad.link(sinkpad)); /* pads are linked now */ assertTrue("srcpad not linked", srcpad.isLinked()); assertTrue("sinkpad not linked", sinkpad.isLinked()); /* adding element to bin voids hierarchy so pads are unlinked */ pipeline.add(src); /* check if pads really are unlinked */ assertFalse("srcpad is still linked after being added to bin", srcpad.isLinked()); assertFalse("sinkpad is still linked after being added to bin", sinkpad.isLinked()); /* cannot link pads in wrong hierarchy */ assertEquals("Should not be able to link pads in different hierarchy", PadLinkReturn.WRONG_HIERARCHY, srcpad.link(sinkpad)); /* adding other element to bin as well */ pipeline.add(sink); /* now we can link again */ assertEquals("Could not link src and sink pads when in same bin", PadLinkReturn.OK, srcpad.link(sinkpad)); /* check if pads really are linked */ assertTrue("srcpad not linked", srcpad.isLinked()); assertTrue("sinkpad not linked", sinkpad.isLinked()); // Force disposal to flush out any refcounting bugs. pipeline.dispose(); src.dispose(); sink.dispose(); srcpad.dispose(); sinkpad.dispose(); } @Test public void addSelf() { Bin bin = new Bin(""); // Enable the line below once we know how to avoid gstreamer spitting out warnings //assertFalse("Should not be able to add bin to itself", bin.add(bin)); bin.dispose(); } // This test doesn't work correctly on older gstreamer? //@Test public void iterateSorted() { Pipeline pipeline = GstPipelineAPI.GSTPIPELINE_API.gst_pipeline_new(null); assertNotNull("Failed to create Pipeline", pipeline); Bin bin = GstBinAPI.GSTBIN_API.gst_bin_new(null); assertNotNull("Failed to create bin", bin); Element src = ElementFactory.make("fakesrc", null); assertNotNull("Failed to create fakesrc", src); Element tee = ElementFactory.make("tee", null); assertNotNull("Failed to create tee", tee); Element sink1 = ElementFactory.make("fakesink", null); assertNotNull("Failed to create fakesink", sink1); bin.addMany(src, tee, sink1); assertTrue("Could not link fakesrc to tee", src.link(tee)); assertTrue("Could not link tee to fakesink", tee.link(sink1)); Element identity = ElementFactory.make("identity", null); assertNotNull("Failed to create identity", identity); Element sink2 = ElementFactory.make("fakesink", null); assertNotNull("Failed to create fakesink", sink2); pipeline.addMany(bin, identity, sink2); // gst_bin_add_many (GST_BIN (pipeline), bin, identity, sink2, NULL); assertTrue("Could not link tee to identity", tee.link(identity)); assertTrue("Could not link identity to second fakesink", identity.link(sink2)); Iterator<Element> it = pipeline.getElementsSorted().iterator(); assertEquals("First sorted element should be sink2", sink2, it.next()); assertEquals("Second sorted element should be identity", identity, it.next()); assertEquals("Third sorted element should be bin", bin, it.next()); pipeline.dispose(); } @Test public void testLaunch() { Bin bin = Bin.launch("fakesrc ! fakesink", false); assertNotNull("Bin not created", bin); } @Test public void testLaunchElementCount() { Bin bin = Bin.launch("fakesrc ! fakesink", false); assertEquals("Number of elements in pipeline incorrect", 2, bin.getElements().size()); } @Test public void testLaunchSrcElement() { Bin bin = Bin.launch("fakesrc ! fakesink", false); assertEquals("First element not a fakesrc", "fakesrc", bin.getSources().get(0).getFactory().getName()); } @Test public void testLaunchSinkElement() { Bin bin = Bin.launch("fakesrc ! fakesink", false); assertEquals("First element not a fakesink", "fakesink", bin.getSinks().get(0).getFactory().getName()); } @Test public void testLaunchDisabledGhostPadsForSource() { Bin bin = Bin.launch("fakesrc", false); assertEquals("Number of src pads incorrect", 0, bin.getSrcPads().size()); } @Test public void testLaunchDisabledGhostPadsForSink() { Bin bin = Bin.launch("fakesink", false); assertEquals("Number of sink pads incorrect", 0, bin.getSinkPads().size()); } @Test public void testLaunchEnabledGhostPadsForSource() { Bin bin = Bin.launch("fakesrc", true); assertEquals("Number of src pads incorrect", 1, bin.getSrcPads().size()); } @Test public void testLaunchEnabledGhostPadsForSink() { Bin bin = Bin.launch("fakesink", true); assertEquals("Number of sink pads incorrect", 1, bin.getSinkPads().size()); } @Test public void testLaunchEnabledGhostPadsForSourceWithNoUsablePads() { Bin bin = Bin.launch("fakesrc ! fakesink", true); assertEquals("Number of src pads incorrect", 0, bin.getSrcPads().size()); } @Test public void testLaunchEnabledGhostPadsForSinkWithNoUsablePads() { Bin bin = Bin.launch("fakesrc ! fakesink", true); assertEquals("Number of sink pads incorrect", 0, bin.getSinkPads().size()); } @Test public void testLaunchEnabledGhostPadsWithNoUsablePads() { Bin bin = Bin.launch("fakesrc ! fakesink", true); assertEquals("Number of pads incorrect", 0, bin.getPads().size()); } }