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] > 2828import com .sun .jna .Pointer ;
2929import java .util .HashSet ;
3030import java .util .Set ;
31+ import org .freedesktop .gstreamer .glib .NativeFlags ;
3132import org .freedesktop .gstreamer .glib .Natives ;
3233
3334import org .freedesktop .gstreamer .lowlevel .GstAPI .GstCallback ;
8081public 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}
0 commit comments