Skip to content

Commit de80ed1

Browse files
Add support for generic probes on Pad, better matching upstream API.
1 parent de98f61 commit de80ed1

File tree

8 files changed

+623
-17
lines changed

8 files changed

+623
-17
lines changed

src/org/freedesktop/gstreamer/Pad.java

Lines changed: 107 additions & 13 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) 2018 Antonio Morales
44
* Copyright (C) 2014 Tom Greenwood <[email protected]>
55
* Copyright (C) 2009 Tamas Korodi <[email protected]>
@@ -28,6 +28,7 @@
2828
import com.sun.jna.Pointer;
2929
import java.util.HashSet;
3030
import java.util.Set;
31+
import org.freedesktop.gstreamer.glib.NativeFlags;
3132
import org.freedesktop.gstreamer.glib.Natives;
3233

3334
import org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback;
@@ -80,7 +81,7 @@
8081
public class Pad extends GstObject {
8182

8283
public static final String GTYPE_NAME = "GstPad";
83-
84+
8485
private static final int EVENT_HAS_INFO_MASK = GstPadAPI.GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM | GstPadAPI.GST_PAD_PROBE_TYPE_EVENT_UPSTREAM;
8586
private final Handle handle;
8687

@@ -95,7 +96,7 @@ private Pad(Handle handle, boolean needRef) {
9596
super(handle, needRef);
9697
this.handle = handle;
9798
}
98-
99+
99100
/**
100101
* Creates a new pad with the given name in the given direction. If name is
101102
* null, a guaranteed unique name (across all pads) will be assigned.
@@ -190,7 +191,7 @@ public Pad getPeer() {
190191
* filter contains the caps accepted by downstream in the preferred order.
191192
* filter might be NULL but if it is not NULL the returned caps will be a
192193
* subset of filter .
193-
*
194+
*
194195
* @param filter Caps to filter by, or null
195196
* @return the {@link Caps} of the peer pad, or null if there is no peer
196197
* pad.
@@ -386,6 +387,79 @@ public void disconnect(UNLINKED listener) {
386387
disconnect(UNLINKED.class, listener);
387388
}
388389

390+
/**
391+
* Be notified of different states of pads. The provided callback is called
392+
* for every state that matches mask.
393+
* <p>
394+
* Probes are called in groups: First {@link PadProbeType#BLOCK} probes are
395+
* called, then others, then finally {@link PadProbeType#IDLE}. The only
396+
* exception here are IDLE probes that are called immediately if the pad is
397+
* already idle while calling addProbe(). In each of the groups, probes are
398+
* called in the order in which they were added.
399+
*
400+
* @param mask set of mask flags for probe - common options are fields of
401+
* {@link PadProbeType}
402+
* @param callback callback that will be called with notifications of the
403+
* pad state
404+
*/
405+
public void addProbe(final Set<PadProbeType> mask, PROBE callback) {
406+
addProbe(NativeFlags.toInt(mask), callback);
407+
}
408+
409+
/**
410+
* Be notified of different states of pads. The provided callback is called
411+
* for every state that matches mask.
412+
* <p>
413+
* Probes are called in groups: First {@link PadProbeType#BLOCK} probes are
414+
* called, then others, then finally {@link PadProbeType#IDLE}. The only
415+
* exception here are IDLE probes that are called immediately if the pad is
416+
* already idle while calling addProbe(). In each of the groups, probes are
417+
* called in the order in which they were added.
418+
*
419+
* @param mask mask flag for probe
420+
* @param callback callback that will be called with notifications of the
421+
* pad state
422+
*/
423+
public void addProbe(PadProbeType mask, PROBE callback) {
424+
addProbe(mask.intValue(), callback);
425+
}
426+
427+
synchronized void addProbe(int mask, PROBE callback) {
428+
final GstPadAPI.PadProbeCallback probe = new GstPadAPI.PadProbeCallback() {
429+
@Override
430+
public PadProbeReturn callback(Pad pad, GstPadProbeInfo probeInfo, Pointer user_data) {
431+
PadProbeInfo info = new PadProbeInfo(probeInfo);
432+
PadProbeReturn ret = callback.probeCallback(pad, info);
433+
info.invalidate();
434+
return ret;
435+
}
436+
};
437+
438+
NativeLong id = handle.addProbe(mask, probe);
439+
if (id.longValue() == 0) {
440+
// the Probe was an IDLE-Probe and it was already handled synchronously in handle.addProbe,
441+
// so no Callback needs to be registered
442+
return;
443+
}
444+
445+
GCallback cb = new GCallback(id, probe) {
446+
@Override
447+
protected void disconnect() {
448+
handle.removeProbe(id);
449+
}
450+
};
451+
addCallback(PROBE.class, callback, cb);
452+
}
453+
454+
/**
455+
* Remove the provided probe callback from the Pad.
456+
*
457+
* @param callback callback to remove
458+
*/
459+
public synchronized void removeProbe(PROBE callback) {
460+
removeCallback(PROBE.class, callback);
461+
}
462+
389463
public void addEventProbe(final EVENT_PROBE listener) {
390464
final int mask = GstPadAPI.GST_PAD_PROBE_TYPE_EVENT_BOTH | GstPadAPI.GST_PAD_PROBE_TYPE_EVENT_FLUSH;
391465
addEventProbe(listener, mask);
@@ -609,7 +683,6 @@ public PadTemplate getTemplate() {
609683
public boolean hasCurrentCaps() {
610684
return GSTPAD_API.gst_pad_has_current_caps(this);
611685
}
612-
613686

614687
/**
615688
* Signal emitted when new this {@link Pad} is linked to another {@link Pad}
@@ -646,6 +719,28 @@ public static interface UNLINKED {
646719
public void unlinked(Pad pad, Pad peer);
647720
}
648721

722+
/**
723+
* Callback used by
724+
* {@link #addProbe(java.util.EnumSet, org.freedesktop.gstreamer.Pad.PROBE)}
725+
*/
726+
public static interface PROBE {
727+
728+
/**
729+
* Callback used by
730+
* {@link #addProbe(java.util.EnumSet, org.freedesktop.gstreamer.Pad.PROBE)}.
731+
* Gets called to notify about the current blocking type.
732+
* <p>
733+
* <b>The PadProbeInfo and any Buffer, Event or Query referenced from
734+
* it, is only valid for the duration of the callback.</b>
735+
*
736+
* @param pad Pad that is blocked
737+
* @param info PadProbeInfo with access to underlying data
738+
* @return PadProbeReturn value
739+
*/
740+
public PadProbeReturn probeCallback(Pad pad, PadProbeInfo info);
741+
742+
}
743+
649744
/**
650745
* Signal emitted when an event passes through this <tt>Pad</tt>.
651746
*
@@ -667,11 +762,11 @@ public static interface DATA_PROBE {
667762

668763
public PadProbeReturn dataReceived(Pad pad, Buffer buffer);
669764
}
670-
765+
671766
private static class Handle extends GstObject.Handle {
672-
767+
673768
private final Set<NativeLong> probes;
674-
769+
675770
private Handle(GstPadPtr ptr, boolean ownsHandle) {
676771
super(ptr, ownsHandle);
677772
probes = new HashSet<>();
@@ -681,21 +776,21 @@ private Handle(GstPadPtr ptr, boolean ownsHandle) {
681776
protected GstPadPtr getPointer() {
682777
return (GstPadPtr) super.getPointer();
683778
}
684-
779+
685780
private synchronized NativeLong addProbe(int mask, GstPadAPI.PadProbeCallback probe) {
686781
NativeLong id = GSTPAD_API.gst_pad_add_probe(getPointer(), mask, probe, null, null);
687782
if (id.longValue() != 0) {
688783
probes.add(id);
689784
}
690785
return id;
691786
}
692-
787+
693788
private synchronized void removeProbe(NativeLong id) {
694789
if (probes.remove(id)) {
695790
GSTPAD_API.gst_pad_remove_probe(getPointer(), id);
696791
}
697792
}
698-
793+
699794
private synchronized void clearProbes() {
700795
probes.forEach(id -> GSTPAD_API.gst_pad_remove_probe(getPointer(), id));
701796
probes.clear();
@@ -712,7 +807,6 @@ public void dispose() {
712807
clearProbes();
713808
super.dispose();
714809
}
715-
716-
810+
717811
}
718812
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright (C) 2020 Neil C Smith
3+
*
4+
* This file is part of gstreamer-java.
5+
*
6+
* This code is free software: you can redistribute it and/or modify it under
7+
* the terms of the GNU Lesser General Public License version 3 only, as
8+
* published by the Free Software Foundation.
9+
*
10+
* This code is distributed in the hope that it will be useful, but WITHOUT
11+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
13+
* version 3 for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public License
16+
* version 3 along with this work. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
package org.freedesktop.gstreamer;
19+
20+
import java.util.Set;
21+
import org.freedesktop.gstreamer.event.Event;
22+
import org.freedesktop.gstreamer.glib.NativeFlags;
23+
import org.freedesktop.gstreamer.lowlevel.GstPadProbeInfo;
24+
import org.freedesktop.gstreamer.query.Query;
25+
26+
import static org.freedesktop.gstreamer.lowlevel.GstPadAPI.GSTPAD_API;
27+
28+
/**
29+
* Probe info passed in to Pad.PROBE callback.
30+
*/
31+
public final class PadProbeInfo {
32+
33+
private GstPadProbeInfo info;
34+
35+
PadProbeInfo(GstPadProbeInfo info) {
36+
this.info = info;
37+
}
38+
39+
/**
40+
* Get the set of flags for the current probe type.
41+
*
42+
* @return probe type
43+
*/
44+
public Set<PadProbeType> getType() {
45+
return NativeFlags.fromInt(PadProbeType.class, info.padProbeType);
46+
}
47+
48+
/**
49+
* Get the Buffer from the probe, or null.
50+
*
51+
* @return buffer or null
52+
*/
53+
public Buffer getBuffer() {
54+
return GSTPAD_API.gst_pad_probe_info_get_buffer(info);
55+
}
56+
57+
/**
58+
* Get the Event from the probe, or null.
59+
*
60+
* @return event or null
61+
*/
62+
public Event getEvent() {
63+
return GSTPAD_API.gst_pad_probe_info_get_event(info);
64+
}
65+
66+
/**
67+
* Get the query from the probe, or null.
68+
*
69+
* @return query or null
70+
*/
71+
public Query getQuery() {
72+
return GSTPAD_API.gst_pad_probe_info_get_query(info);
73+
}
74+
75+
void invalidate() {
76+
info = null;
77+
}
78+
79+
}

0 commit comments

Comments
 (0)