Skip to content

Commit dd6213f

Browse files
Fix behaviour with PadProbeReturn.REMOVE for new and old probe types; tidy up tests and documentation.
1 parent de80ed1 commit dd6213f

File tree

3 files changed

+121
-16
lines changed

3 files changed

+121
-16
lines changed

src/org/freedesktop/gstreamer/Pad.java

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,12 @@ public PadProbeReturn callback(Pad pad, GstPadProbeInfo probeInfo, Pointer user_
431431
PadProbeInfo info = new PadProbeInfo(probeInfo);
432432
PadProbeReturn ret = callback.probeCallback(pad, info);
433433
info.invalidate();
434+
if (ret == PadProbeReturn.REMOVE) {
435+
// don't want handle to try and remove in GCallback::disconnect
436+
// @TODO move to Map<PROBE, NativeLong> of probes over callback
437+
handle.probes.remove(probeInfo.id);
438+
removeCallback(PROBE.class, callback);
439+
}
434440
return ret;
435441
}
436442
};
@@ -468,16 +474,20 @@ public void addEventProbe(final EVENT_PROBE listener) {
468474
synchronized void addEventProbe(final EVENT_PROBE listener, final int mask) {
469475
final GstPadAPI.PadProbeCallback probe = new GstPadAPI.PadProbeCallback() {
470476
public PadProbeReturn callback(Pad pad, GstPadProbeInfo probeInfo, Pointer user_data) {
471-
// System.out.println("CALLBACK " + probeInfo.padProbeType);
472477
if ((probeInfo.padProbeType & mask) != 0) {
473478
Event event = null;
474479
if ((probeInfo.padProbeType & EVENT_HAS_INFO_MASK) != 0) {
475480
event = GSTPAD_API.gst_pad_probe_info_get_event(probeInfo);
476481
}
477-
return listener.eventReceived(pad, event);
482+
PadProbeReturn ret = listener.eventReceived(pad, event);
483+
if (ret == PadProbeReturn.REMOVE) {
484+
// don't want handle to try and remove in GCallback::disconnect
485+
handle.probes.remove(probeInfo.id);
486+
removeCallback(EVENT_PROBE.class, listener);
487+
}
488+
return ret;
478489
}
479490

480-
//We have to negate the return value to keep consistency with gstreamer's API
481491
return PadProbeReturn.OK;
482492
}
483493
};
@@ -508,10 +518,15 @@ public synchronized void addDataProbe(final DATA_PROBE listener) {
508518
public PadProbeReturn callback(Pad pad, GstPadProbeInfo probeInfo, Pointer user_data) {
509519
if ((probeInfo.padProbeType & GstPadAPI.GST_PAD_PROBE_TYPE_BUFFER) != 0) {
510520
Buffer buffer = GSTPAD_API.gst_pad_probe_info_get_buffer(probeInfo);
511-
return listener.dataReceived(pad, buffer);
521+
PadProbeReturn ret = listener.dataReceived(pad, buffer);
522+
if (ret == PadProbeReturn.REMOVE) {
523+
// don't want handle to try and remove in GCallback::disconnect
524+
handle.probes.remove(probeInfo.id);
525+
removeCallback(DATA_PROBE.class, listener);
526+
}
527+
return ret;
512528
}
513529

514-
//We have to negate the return value to keep consistency with gstreamer's API
515530
return PadProbeReturn.OK;
516531
}
517532
};
@@ -742,25 +757,27 @@ public static interface PROBE {
742757
}
743758

744759
/**
745-
* Signal emitted when an event passes through this <tt>Pad</tt>.
760+
* Probe for listening when an event passes through this Pad.
746761
*
747762
* @see #addEventProbe(EVENT_PROBE)
748763
* @see #removeEventProbe(EVENT_PROBE)
749764
*/
750765
public static interface EVENT_PROBE {
751766

752767
public PadProbeReturn eventReceived(Pad pad, Event event);
768+
753769
}
754770

755771
/**
756-
* Signal emitted when new data is available on the {@link Pad}
772+
* Probe for listening when new data is available on the Pad.
757773
*
758774
* @see #addDataProbe(DATA_PROBE)
759775
* @see #removeDataProbe(DATA_PROBE)
760776
*/
761777
public static interface DATA_PROBE {
762778

763779
public PadProbeReturn dataReceived(Pad pad, Buffer buffer);
780+
764781
}
765782

766783
private static class Handle extends GstObject.Handle {

test/org/freedesktop/gstreamer/PadProbeTypeTest.java

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,10 @@
2121
import java.util.Set;
2222
import org.freedesktop.gstreamer.glib.NativeFlags;
2323
import org.freedesktop.gstreamer.lowlevel.GstPadAPI;
24-
import org.junit.After;
25-
import org.junit.AfterClass;
26-
import org.junit.Before;
27-
import org.junit.BeforeClass;
2824
import org.junit.Test;
2925

3026
import static org.junit.Assert.*;
3127

32-
/**
33-
*
34-
*/
3528
public class PadProbeTypeTest {
3629

3730

test/org/freedesktop/gstreamer/PadTest.java

Lines changed: 97 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019 Neil C Smith
2+
* Copyright (c) 2020 Neil C Smith
33
* Copyright (c) 2007 Wayne Meissner
44
*
55
* This file is part of gstreamer-java.
@@ -27,6 +27,7 @@
2727
import static org.junit.Assert.assertTrue;
2828

2929
import java.lang.ref.WeakReference;
30+
import java.util.concurrent.atomic.AtomicBoolean;
3031
import java.util.concurrent.atomic.AtomicReference;
3132
import org.freedesktop.gstreamer.event.FlushStopEvent;
3233

@@ -35,7 +36,6 @@
3536
import org.junit.AfterClass;
3637
import org.junit.Before;
3738
import org.junit.BeforeClass;
38-
import org.junit.Ignore;
3939
import org.junit.Test;
4040

4141
/**
@@ -127,6 +127,40 @@ public PadProbeReturn eventReceived(Pad pad, Event event) {
127127
assertNotSame("event_prober.probeEvent() should not have been called", ev2, e.get());
128128
}
129129

130+
@Test
131+
public void addEventProbe_Remove() {
132+
Element elem = ElementFactory.make("identity", "src");
133+
Event ev = new TagEvent(new TagList());
134+
135+
Pad sink = elem.getStaticPad("sink");
136+
137+
final AtomicReference<Event> e = new AtomicReference<Event>();
138+
139+
Pad.EVENT_PROBE event_probe = new Pad.EVENT_PROBE() {
140+
141+
public PadProbeReturn eventReceived(Pad pad, Event event) {
142+
e.set(event);
143+
return PadProbeReturn.REMOVE;
144+
}
145+
};
146+
147+
sink.setActive(true);
148+
sink.sendEvent(new FlushStopEvent());
149+
150+
sink.addEventProbe(event_probe);
151+
sink.sendEvent(ev);
152+
assertEquals("event_prober.probeEvent() was not called", ev, e.get());
153+
154+
Event ev2 = new TagEvent(new TagList());
155+
sink.sendEvent(ev2);
156+
assertNotSame("event_prober.probeEvent() should not have been called", ev2, e.get());
157+
158+
WeakReference<Pad.EVENT_PROBE> probeRef = new WeakReference<>(event_probe);
159+
event_probe = null;
160+
assertTrue("Removed probe not collected", GCTracker.waitGC(probeRef));
161+
162+
}
163+
130164
@Test
131165
public void addProbe_Event() {
132166
Element elem = ElementFactory.make("identity", "src");
@@ -156,6 +190,42 @@ public void addProbe_Event() {
156190
sink.sendEvent(ev2);
157191
assertNotSame("Probe (Event) should not have been called", ev2, e.get());
158192
}
193+
194+
@Test
195+
public void addProbe_EventRemove() {
196+
Element elem = ElementFactory.make("identity", "src");
197+
Event ev = new TagEvent(new TagList());
198+
199+
Pad sink = elem.getStaticPad("sink");
200+
201+
final AtomicReference<Event> e = new AtomicReference<>();
202+
203+
Pad.PROBE probe = (Pad pad, PadProbeInfo info) -> {
204+
assertTrue("Info type does not include event downstream",
205+
info.getType().contains(PadProbeType.EVENT_DOWNSTREAM));
206+
e.set(info.getEvent());
207+
return PadProbeReturn.REMOVE;
208+
};
209+
210+
sink.setActive(true);
211+
sink.sendEvent(new FlushStopEvent());
212+
213+
sink.addProbe(PadProbeType.EVENT_BOTH, probe);
214+
sink.sendEvent(ev);
215+
assertEquals("Probe (Event) was not called", ev, e.get());
216+
217+
Event ev2 = new TagEvent(new TagList());
218+
sink.sendEvent(ev2);
219+
assertNotSame("Probe (Event) should not have been called", ev2, e.get());
220+
221+
WeakReference<Pad.PROBE> probeRef = new WeakReference<>(probe);
222+
probe = null;
223+
assertTrue("Removed probe not collected", GCTracker.waitGC(probeRef));
224+
225+
Event ev3 = new TagEvent(new TagList());
226+
sink.sendEvent(ev3);
227+
assertNotSame("Probe (Event) should not have been called", ev3, e.get());
228+
}
159229

160230
@Test
161231
public void addDataProbe() {
@@ -229,4 +299,29 @@ public void addProbe_Data() {
229299
assertNotSame("Probe (Data) should not have been called", buf2, b.get());
230300
}
231301

302+
@Test
303+
public void addProbe_Idle() {
304+
305+
Element elem = ElementFactory.make("identity", "src");
306+
final AtomicBoolean called = new AtomicBoolean();
307+
308+
Pad src = elem.getStaticPad("src");
309+
310+
Pad.PROBE probe = (Pad pad, PadProbeInfo info) -> {
311+
called.set(true);
312+
return PadProbeReturn.REMOVE;
313+
};
314+
315+
src.addProbe(PadProbeType.IDLE, probe);
316+
317+
assertTrue("Idle probe not called", called.get());
318+
319+
WeakReference<Pad.PROBE> probeRef = new WeakReference<>(probe);
320+
321+
probe = null;
322+
323+
assertTrue("Idle probe not collected", GCTracker.waitGC(probeRef));
324+
325+
}
326+
232327
}

0 commit comments

Comments
 (0)