28
28
import java .util .concurrent .CountDownLatch ;
29
29
import java .util .concurrent .TimeUnit ;
30
30
import java .util .concurrent .TimeoutException ;
31
- import java .util .function .Consumer ;
32
- import java .util .function .Function ;
31
+ import java .util .function .Predicate ;
33
32
34
33
/**
35
34
* Utility class for unit testing API that operates on a Probe.
36
35
* <p>
37
36
* Call {@link ProbeTester#test(Consumer)} and pass a callback which will
38
37
* perform the test on a PadProbeInfo it is supplied. The callback runs in a Pad
39
- * probe. The buffer is produced by a simple, ephemeral pipeline that is fed by
40
- * a video test source.
38
+ * probe. The test uses a simple, ephemeral pipeline that is fed by a video test
39
+ * source (or custom pipeline).
40
+ * <p>
41
+ * The callback is a {@link Predicate} and should return false if the input info
42
+ * doesn't match that required by the test. Test exceptions should be thrown as
43
+ * normal. This is to allow the probe to be called repeatedly until the input
44
+ * info matches that expected. If the probe never matches the test will time
45
+ * out.
41
46
*/
42
47
public class ProbeTester {
43
48
44
- public static void test (Set <PadProbeType > mask , Function <PadProbeInfo , Boolean > callback ) {
45
- test ("videotestsrc ! videoconvert ! fakesink name=sink" , mask , callback );
49
+ /**
50
+ * Run a probe test on a simple test pipeline. The callback will be called
51
+ * by the probe until it returns true, allowing for probe callbacks to be
52
+ * ignored. If the callback never returns true the test will timeout and
53
+ * fail.
54
+ * <p>
55
+ * The pipeline is <code>videotestsrc ! fakesink name=sink</code>. The probe
56
+ * will be attached to the sink pad of the sink element.
57
+ *
58
+ * @param mask PadProbeType mask to use when attaching probe to sink pad
59
+ * @param callback probe callback
60
+ */
61
+ public static void test (Set <PadProbeType > mask , Predicate <PadProbeInfo > callback ) {
62
+ test ("videotestsrc ! fakesink name=sink" , mask , callback );
46
63
}
47
64
48
- public static void test (String pipeline , Set <PadProbeType > mask , Function <PadProbeInfo , Boolean > callback ) {
65
+ /**
66
+ * Run a probe test on a simple test pipeline. The callback will be called
67
+ * by the probe until it returns true, allowing for probe callbacks to be
68
+ * ignored. If the callback never returns true the test will timeout and
69
+ * fail.
70
+ * <p>
71
+ * The pipeline must have a sink element named sink. The probe will be
72
+ * attached to the sink pad of the sink element.
73
+ *
74
+ * @param pipeline custom pipeline with named sink element
75
+ * @param mask PadProbeType mask to use when attaching probe to sink pad
76
+ * @param callback probe callback
77
+ */
78
+ public static void test (String pipeline , Set <PadProbeType > mask , Predicate <PadProbeInfo > callback ) {
49
79
assertNotNull ("Pipeline description can not be null" , pipeline );
50
80
assertFalse ("Pipeline description can not be empty" , pipeline .isEmpty ());
51
81
Pipeline pipe = (Pipeline ) Gst .parseLaunch (pipeline );
52
82
assertNotNull ("Unable to create Pipeline from pipeline description: " , pipe );
53
83
54
84
Element sink = pipe .getElementByName ("sink" );
55
85
Pad pad = sink .getStaticPad ("sink" );
56
- PadProbe probe = new PadProbe (callback , 0 );
86
+ PadProbe probe = new PadProbe (callback );
57
87
pad .addProbe (mask , probe );
58
88
59
89
pipe .play ();
60
90
61
- // Wait for the sample to arrive and for the client supplied test function to
62
- // complete
91
+ // Wait for the probe to complete
63
92
try {
64
93
probe .await (5000 );
94
+ } catch (TimeoutException ex ) {
95
+ fail ("Timed out waiting for probe condition\n " + ex );
65
96
} catch (Exception ex ) {
66
- fail ("Unexpected exception waiting for buffer \n " + ex );
97
+ fail ("Unexpected exception waiting for probe \n " + ex );
67
98
} finally {
68
99
pipe .stop ();
69
100
}
@@ -75,46 +106,27 @@ public static void test(String pipeline, Set<PadProbeType> mask, Function<PadPro
75
106
}
76
107
}
77
108
78
- public static void test (Consumer <Buffer > callback , String pipelineDescription , int skipFrames ) {
79
-
80
- }
81
-
82
109
private static class PadProbe implements Pad .PROBE {
83
110
84
- private final int skipFrames ;
85
111
private final CountDownLatch latch ;
86
- private final Function <PadProbeInfo , Boolean > callback ;
112
+ private final Predicate <PadProbeInfo > callback ;
87
113
88
114
private Throwable exception ;
89
- private int counter = 0 ;
90
115
91
- PadProbe (Function <PadProbeInfo , Boolean > callback ) {
92
- this (callback , 0 );
93
- }
94
-
95
- PadProbe (Function <PadProbeInfo , Boolean > callback , int skip ) {
116
+ PadProbe (Predicate <PadProbeInfo > callback ) {
96
117
this .callback = callback ;
97
- skipFrames = skip ;
98
118
latch = new CountDownLatch (1 );
99
119
}
100
120
101
121
@ Override
102
122
public PadProbeReturn probeCallback (Pad pad , PadProbeInfo info ) {
103
123
if (latch .getCount () > 0 ) {
104
- if (counter < skipFrames ) {
105
- counter ++;
106
- return PadProbeReturn .OK ;
107
- }
108
124
try {
109
- // Run the client's test logic on the buffer (only once)
110
- try {
111
- if (!callback .apply (info )) {
112
- return PadProbeReturn .OK ;
113
- }
114
- } catch (Throwable exc ) {
115
- exception = exc ;
125
+ if (callback .test (info )) {
126
+ latch .countDown ();
116
127
}
117
- } finally {
128
+ } catch (Throwable exc ) {
129
+ exception = exc ;
118
130
latch .countDown ();
119
131
}
120
132
}
0 commit comments