Skip to content

Commit 3ef6786

Browse files
Switch to CountDownLatch in SampleTester and BufferProbeTester.
1 parent 43be942 commit 3ef6786

File tree

3 files changed

+128
-116
lines changed

3 files changed

+128
-116
lines changed

test/org/freedesktop/gstreamer/BufferProbeTester.java

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,18 @@
2323
import static org.junit.Assert.assertNotNull;
2424
import static org.junit.Assert.fail;
2525

26-
import java.util.ArrayList;
26+
import java.util.concurrent.CountDownLatch;
27+
import java.util.concurrent.TimeUnit;
28+
import java.util.concurrent.TimeoutException;
2729
import java.util.function.Consumer;
2830

29-
import org.freedesktop.gstreamer.glib.GError;
30-
3131
/**
3232
* Utility class for unit testing API that operates on a Buffer.
3333
* <p>
3434
* Call {@link BufferTester#test(Consumer)} and pass a callback which will
35-
* perform the test on a Buffer it is supplied. The callback runs on the
36-
* AppSink.NEW_SAMPLE thread. The sample is produced by a simple, ephemeral
37-
* pipeline that is fed by a video test source.
35+
* perform the test on a Buffer it is supplied. The callback runs in a Pad data
36+
* probe. The buffer is produced by a simple, ephemeral pipeline that is fed by
37+
* a video test source.
3838
*/
3939
public class BufferProbeTester {
4040

@@ -49,29 +49,26 @@ public static void test(Consumer<Buffer> callback, String pipelineDescription) {
4949
public static void test(Consumer<Buffer> callback, String pipelineDescription, int skipFrames) {
5050
assertNotNull("Pipeline description can not be null", pipelineDescription);
5151
assertFalse("Pipeline description can not be empty", pipelineDescription.isEmpty());
52-
ArrayList<GError> errors = new ArrayList<>();
53-
Bin bin = Gst.parseBinFromDescription(pipelineDescription, false, errors);
54-
assertNotNull("Unable to create Bin from pipeline description: ", bin);
52+
Pipeline pipe = (Pipeline) Gst.parseLaunch(pipelineDescription);
53+
assertNotNull("Unable to create Pipeline from pipeline description: ", pipe);
5554

56-
Element sink = bin.getElementByName("sink");
55+
Element sink = pipe.getElementByName("sink");
5756
Pad pad = sink.getStaticPad("sink");
5857
BufferProbe probe = new BufferProbe(callback, skipFrames);
5958
pad.addDataProbe(probe);
6059

61-
bin.play();
60+
pipe.play();
6261

6362
// Wait for the sample to arrive and for the client supplied test function to
6463
// complete
6564
try {
66-
synchronized (probe) {
67-
probe.wait();
68-
}
69-
} catch (InterruptedException e) {
70-
fail("Unexpected interruption waiting for sample");
65+
probe.await(5000);
66+
} catch (Exception ex) {
67+
fail("Unexpected exception waiting for buffer\n" + ex);
68+
} finally {
69+
pipe.stop();
7170
}
7271

73-
bin.stop();
74-
7572
// If the test threw an exception on the sample listener thread, throw it here
7673
// (on the main thread)
7774
if (probe.exception != null) {
@@ -81,8 +78,10 @@ public static void test(Consumer<Buffer> callback, String pipelineDescription, i
8178

8279
private static class BufferProbe implements Pad.DATA_PROBE {
8380

84-
private Consumer<Buffer> callback;
8581
private final int skipFrames;
82+
private final CountDownLatch latch;
83+
private final Consumer<Buffer> callback;
84+
8685
private Throwable exception;
8786
private int counter = 0;
8887

@@ -93,11 +92,12 @@ private static class BufferProbe implements Pad.DATA_PROBE {
9392
BufferProbe(Consumer<Buffer> callback, int skip) {
9493
this.callback = callback;
9594
skipFrames = skip;
95+
latch = new CountDownLatch(1);
9696
}
9797

9898
@Override
9999
public PadProbeReturn dataReceived(Pad pad, Buffer buffer) {
100-
if (callback != null) {
100+
if (latch.getCount() > 0) {
101101
if (counter < skipFrames) {
102102
counter++;
103103
return PadProbeReturn.OK;
@@ -109,15 +109,18 @@ public PadProbeReturn dataReceived(Pad pad, Buffer buffer) {
109109
} catch (Throwable exc) {
110110
exception = exc;
111111
}
112-
callback = null;
113112
} finally {
114-
synchronized (this) {
115-
notify();
116-
}
113+
latch.countDown();
117114
}
118115
}
119116
return PadProbeReturn.OK;
120117
}
118+
119+
void await(long millis) throws InterruptedException, TimeoutException {
120+
if (!latch.await(millis, TimeUnit.MILLISECONDS)) {
121+
throw new TimeoutException();
122+
}
123+
}
121124
}
122125

123126
}

test/org/freedesktop/gstreamer/SampleTest.java

Lines changed: 53 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,14 @@
1717
* You should have received a copy of the GNU Lesser General Public License
1818
* along with gstreamer-java. If not, see <http://www.gnu.org/licenses/>.
1919
*/
20-
2120
package org.freedesktop.gstreamer;
2221

23-
import static org.junit.Assert.assertEquals;
22+
import static org.junit.Assert.*;
2423

2524
import org.freedesktop.gstreamer.glib.Natives;
2625
import org.freedesktop.gstreamer.util.TestAssumptions;
2726
import org.junit.AfterClass;
2827
import org.junit.BeforeClass;
29-
import org.junit.Ignore;
3028
import org.junit.Test;
3129

3230
public class SampleTest {
@@ -36,59 +34,71 @@ public SampleTest() {
3634

3735
@BeforeClass
3836
public static void setUpClass() throws Exception {
39-
Gst.init(Gst.getVersion(), "SampleTest");
37+
Gst.init(Gst.getVersion(), "SampleTest");
4038
}
41-
39+
4240
@AfterClass
4341
public static void tearDownClass() throws Exception {
4442
Gst.deinit();
4543
}
4644

4745
@Test
48-
@Ignore
49-
// @TODO for some reason this test is unreliable on GitHub Actions.
5046
public void testGetCaps() {
51-
SampleTester.test((Sample sample) -> {
52-
Caps caps = sample.getCaps();
53-
Structure struct = caps.getStructure(0);
54-
String name = struct.getName();
55-
assertEquals("video/x-raw", name);
56-
});
47+
SampleTester.test((Sample sample) -> {
48+
Caps caps = sample.getCaps();
49+
Structure struct = caps.getStructure(0);
50+
String name = struct.getName();
51+
assertEquals("video/x-raw", name);
52+
});
5753
}
5854

5955
@Test
6056
public void testGetBuffer() {
61-
SampleTester.test((Sample sample) -> {
62-
Buffer buffer = sample.getBuffer();
63-
assertEquals(1, buffer.getMemoryCount());
64-
});
57+
SampleTester.test((Sample sample) -> {
58+
Buffer buffer = sample.getBuffer();
59+
assertEquals(1, buffer.getMemoryCount());
60+
});
61+
}
62+
63+
@Test
64+
public void testSetBuffer() {
65+
// since gst 1.16, the sample is recycled and keep a reference on the last buffer received
66+
TestAssumptions.requireGstVersion(1, 16);
67+
68+
SampleTester.test((Sample sample) -> {
69+
70+
Buffer buffer = sample.getBuffer();
71+
72+
int refCount = buffer.getRefCount();
73+
74+
assertEquals(2, sample.getRefCount());
75+
76+
// make sample writable
77+
Natives.unref(sample);
78+
79+
// force sample to release the buffer
80+
sample.setBuffer(null);
81+
82+
Natives.ref(sample);
83+
84+
assertEquals(2, sample.getRefCount());
85+
86+
assertEquals(refCount - 1, buffer.getRefCount());
87+
});
6588
}
66-
89+
6790
@Test
68-
public void testSetBuffer() {
69-
// since gst 1.16, the sample is recycled and keep a reference on the last buffer received
70-
TestAssumptions.requireGstVersion(1, 16);
71-
72-
SampleTester.test((Sample sample) -> {
73-
74-
Buffer buffer = sample.getBuffer();
75-
76-
int refCount = buffer.getRefCount();
77-
78-
assertEquals(2, sample.getRefCount());
79-
80-
// make sample writable
81-
Natives.unref(sample);
82-
83-
// force sample to release the buffer
84-
sample.setBuffer(null);
85-
86-
Natives.ref(sample);
87-
88-
assertEquals(2, sample.getRefCount());
89-
90-
assertEquals(refCount-1, buffer.getRefCount());
91-
});
91+
public void testSampleTester() {
92+
try {
93+
SampleTester.test(sample -> {
94+
throw new IllegalStateException();
95+
});
96+
} catch (Throwable t) {
97+
assertTrue(t instanceof AssertionError);
98+
assertTrue(t.getCause() instanceof IllegalStateException);
99+
return;
100+
}
101+
fail("No exception thrown");
92102
}
93-
103+
94104
}

0 commit comments

Comments
 (0)