1 /* GStreamer
2  *
3  * unit test for dtmf elements
4  * Copyright (C) 2013 Collabora Ltd
5  *   @author: Olivier Crete <olivier.crete@collabora.com>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26 
27 #include <gst/gst.h>
28 #include <gst/audio/audio.h>
29 #include <gst/check/gstcheck.h>
30 #include <gst/check/gsttestclock.h>
31 #include <gst/rtp/gstrtpbuffer.h>
32 
33 
34 /* Include this from the plugin to get the defines */
35 
36 #include "../../gst/dtmf/gstdtmfcommon.h"
37 
38 #define END_BIT (1<<7)
39 
40 static GstStaticPadTemplate audio_sink_template =
41 GST_STATIC_PAD_TEMPLATE ("sink",
42     GST_PAD_SINK,
43     GST_PAD_ALWAYS,
44     GST_STATIC_CAPS ("audio/x-raw, "
45         "format = (string) \"" GST_AUDIO_NE (S16) "\", "
46         "rate = " GST_AUDIO_RATE_RANGE ", " "channels = (int) 1")
47     );
48 
49 static GstStaticPadTemplate rtp_dtmf_src_template =
50 GST_STATIC_PAD_TEMPLATE ("src",
51     GST_PAD_SRC,
52     GST_PAD_ALWAYS,
53     GST_STATIC_CAPS ("application/x-rtp, "
54         "media = (string) \"audio\", "
55         "payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ", "
56         "clock-rate = (int) [ 0, MAX ], "
57         "encoding-name = (string) \"TELEPHONE-EVENT\"")
58     );
59 
60 
61 static void
check_get_dtmf_event_message(GstBus * bus,gint number,gint volume)62 check_get_dtmf_event_message (GstBus * bus, gint number, gint volume)
63 {
64   GstMessage *message;
65   gboolean have_message = FALSE;
66 
67   while (!have_message &&
68       (message = gst_bus_pop_filtered (bus, GST_MESSAGE_ELEMENT)) != NULL) {
69     if (gst_message_has_name (message, "dtmf-event")) {
70       const GstStructure *s = gst_message_get_structure (message);
71       gint stype, snumber, smethod, svolume;
72 
73       fail_unless (gst_structure_get (s,
74               "type", G_TYPE_INT, &stype,
75               "number", G_TYPE_INT, &snumber,
76               "method", G_TYPE_INT, &smethod,
77               "volume", G_TYPE_INT, &svolume, NULL));
78 
79       fail_unless (stype == 1);
80       fail_unless (smethod == 1);
81       fail_unless (snumber == number);
82       fail_unless (svolume == volume);
83       have_message = TRUE;
84     }
85     gst_message_unref (message);
86   }
87 
88   fail_unless (have_message);
89 }
90 
91 static void
check_no_dtmf_event_message(GstBus * bus)92 check_no_dtmf_event_message (GstBus * bus)
93 {
94   GstMessage *message;
95   gboolean have_message = FALSE;
96 
97   while (!have_message &&
98       (message = gst_bus_pop_filtered (bus, GST_MESSAGE_ELEMENT)) != NULL) {
99     if (gst_message_has_name (message, "dtmf-event") ||
100         gst_message_has_name (message, "dtmf-event-processed") ||
101         gst_message_has_name (message, "dtmf-event-dropped")) {
102       have_message = TRUE;
103     }
104     gst_message_unref (message);
105   }
106 
107   fail_unless (!have_message);
108 }
109 
110 static void
check_buffers_duration(GstClockTime expected_duration)111 check_buffers_duration (GstClockTime expected_duration)
112 {
113   GstClockTime duration = 0;
114 
115   while (buffers) {
116     GstBuffer *buf = buffers->data;
117 
118     buffers = g_list_delete_link (buffers, buffers);
119 
120     fail_unless (GST_BUFFER_DURATION_IS_VALID (buf));
121     duration += GST_BUFFER_DURATION (buf);
122     gst_buffer_unref (buf);
123   }
124 
125   fail_unless (duration == expected_duration);
126 }
127 
128 static void
send_rtp_packet(GstPad * src,guint timestamp,gboolean marker,gboolean end,guint number,guint volume,guint duration)129 send_rtp_packet (GstPad * src, guint timestamp, gboolean marker, gboolean end,
130     guint number, guint volume, guint duration)
131 {
132   GstBuffer *buf;
133   GstRTPBuffer rtpbuf = GST_RTP_BUFFER_INIT;
134   gchar *payload;
135   static guint seqnum = 1;
136 
137   buf = gst_rtp_buffer_new_allocate (4, 0, 0);
138   fail_unless (gst_rtp_buffer_map (buf, GST_MAP_READWRITE, &rtpbuf));
139   gst_rtp_buffer_set_seq (&rtpbuf, seqnum++);
140   gst_rtp_buffer_set_timestamp (&rtpbuf, timestamp);
141   gst_rtp_buffer_set_marker (&rtpbuf, marker);
142   payload = gst_rtp_buffer_get_payload (&rtpbuf);
143   payload[0] = number;
144   payload[1] = volume | (end ? END_BIT : 0);
145   GST_WRITE_UINT16_BE (payload + 2, duration);
146   gst_rtp_buffer_unmap (&rtpbuf);
147   fail_unless (gst_pad_push (src, buf) == GST_FLOW_OK);
148 }
149 
GST_START_TEST(test_rtpdtmfdepay)150 GST_START_TEST (test_rtpdtmfdepay)
151 {
152   GstElement *dtmfdepay;
153   GstPad *src, *sink;
154   GstBus *bus;
155   GstCaps *caps_in;
156   GstCaps *expected_caps_out;
157   GstCaps *caps_out;
158 
159   dtmfdepay = gst_check_setup_element ("rtpdtmfdepay");
160   sink = gst_check_setup_sink_pad (dtmfdepay, &audio_sink_template);
161   src = gst_check_setup_src_pad (dtmfdepay, &rtp_dtmf_src_template);
162 
163   bus = gst_bus_new ();
164   gst_element_set_bus (dtmfdepay, bus);
165 
166   gst_pad_set_active (src, TRUE);
167   gst_pad_set_active (sink, TRUE);
168   gst_element_set_state (dtmfdepay, GST_STATE_PLAYING);
169 
170 
171   caps_in = gst_caps_new_simple ("application/x-rtp",
172       "encoding-name", G_TYPE_STRING, "TELEPHONE-EVENT",
173       "media", G_TYPE_STRING, "audio",
174       "clock-rate", G_TYPE_INT, 1000, "payload", G_TYPE_INT, 99, NULL);
175   gst_check_setup_events (src, dtmfdepay, caps_in, GST_FORMAT_TIME);
176   gst_caps_unref (caps_in);
177 
178   caps_out = gst_pad_get_current_caps (sink);
179   expected_caps_out = gst_caps_new_simple ("audio/x-raw",
180       "format", G_TYPE_STRING, GST_AUDIO_NE (S16),
181       "rate", G_TYPE_INT, 1000, "channels", G_TYPE_INT, 1, NULL);
182   fail_unless (gst_caps_is_equal_fixed (caps_out, expected_caps_out));
183   gst_caps_unref (expected_caps_out);
184   gst_caps_unref (caps_out);
185 
186   /* Single packet DTMF */
187   send_rtp_packet (src, 200, TRUE, TRUE, 1, 5, 250);
188   check_get_dtmf_event_message (bus, 1, 5);
189   check_buffers_duration (250 * GST_MSECOND);
190 
191   /* Two packet DTMF */
192   send_rtp_packet (src, 800, TRUE, FALSE, 1, 5, 200);
193   send_rtp_packet (src, 800, FALSE, TRUE, 1, 5, 400);
194   check_buffers_duration (400 * GST_MSECOND);
195   check_get_dtmf_event_message (bus, 1, 5);
196 
197   /* Long DTMF */
198   send_rtp_packet (src, 3000, TRUE, FALSE, 1, 5, 200);
199   check_get_dtmf_event_message (bus, 1, 5);
200   check_buffers_duration (200 * GST_MSECOND);
201   send_rtp_packet (src, 3000, FALSE, FALSE, 1, 5, 400);
202   check_no_dtmf_event_message (bus);
203   check_buffers_duration (200 * GST_MSECOND);
204   send_rtp_packet (src, 3000, FALSE, FALSE, 1, 5, 600);
205   check_no_dtmf_event_message (bus);
206   check_buffers_duration (200 * GST_MSECOND);
207 
208   /* New without end to last */
209   send_rtp_packet (src, 4000, TRUE, TRUE, 1, 5, 250);
210   check_get_dtmf_event_message (bus, 1, 5);
211   check_buffers_duration (250 * GST_MSECOND);
212 
213   check_no_dtmf_event_message (bus);
214   fail_unless (buffers == NULL);
215   gst_element_set_bus (dtmfdepay, NULL);
216   gst_object_unref (bus);
217 
218   gst_pad_set_active (src, FALSE);
219   gst_pad_set_active (sink, FALSE);
220   gst_check_teardown_sink_pad (dtmfdepay);
221   gst_check_teardown_src_pad (dtmfdepay);
222   gst_check_teardown_element (dtmfdepay);
223 }
224 
225 GST_END_TEST;
226 
227 
228 static GstStaticPadTemplate rtp_dtmf_sink_template =
229 GST_STATIC_PAD_TEMPLATE ("sink",
230     GST_PAD_SINK,
231     GST_PAD_ALWAYS,
232     GST_STATIC_CAPS ("application/x-rtp, "
233         "media = (string) \"audio\", "
234         "payload = (int) 99, "
235         "clock-rate = (int) 1000, "
236         "seqnum-offset = (uint) 333, "
237         "timestamp-offset = (uint) 666, "
238         "ssrc = (uint) 999, "
239         "maxptime = (uint) 20, encoding-name = (string) \"TELEPHONE-EVENT\"")
240     );
241 
242 GstElement *dtmfsrc;
243 GstPad *sink;
244 GstClock *testclock;
245 GstBus *bus;
246 
247 static void
check_message_structure(GstStructure * expected_s)248 check_message_structure (GstStructure * expected_s)
249 {
250   GstMessage *message;
251   gboolean have_message = FALSE;
252 
253   while (!have_message &&
254       (message = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE,
255               GST_MESSAGE_ELEMENT)) != NULL) {
256     if (gst_message_has_name (message, gst_structure_get_name (expected_s))) {
257       const GstStructure *s = gst_message_get_structure (message);
258 
259       fail_unless (gst_structure_is_equal (s, expected_s));
260       have_message = TRUE;
261     }
262     gst_message_unref (message);
263   }
264 
265   fail_unless (have_message);
266 
267   gst_structure_free (expected_s);
268 }
269 
270 static void
check_rtp_buffer(GstClockTime ts,GstClockTime duration,gboolean start,gboolean end,guint rtpts,guint ssrc,guint volume,guint number,guint rtpduration)271 check_rtp_buffer (GstClockTime ts, GstClockTime duration, gboolean start,
272     gboolean end, guint rtpts, guint ssrc, guint volume, guint number,
273     guint rtpduration)
274 {
275   GstBuffer *buffer;
276   GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;
277   gchar *payload;
278 
279   g_mutex_lock (&check_mutex);
280   while (buffers == NULL)
281     g_cond_wait (&check_cond, &check_mutex);
282   g_mutex_unlock (&check_mutex);
283   fail_unless (buffers != NULL);
284 
285   buffer = buffers->data;
286   buffers = g_list_delete_link (buffers, buffers);
287 
288   fail_unless (GST_BUFFER_PTS (buffer) == ts);
289   fail_unless (GST_BUFFER_DURATION (buffer) == duration);
290 
291   fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtpbuffer));
292   fail_unless (gst_rtp_buffer_get_marker (&rtpbuffer) == start);
293   fail_unless (gst_rtp_buffer_get_timestamp (&rtpbuffer) == rtpts);
294   payload = gst_rtp_buffer_get_payload (&rtpbuffer);
295 
296   fail_unless (payload[0] == number);
297   fail_unless ((payload[1] & 0x7F) == volume);
298   fail_unless (! !(payload[1] & 0x80) == end);
299   fail_unless (GST_READ_UINT16_BE (payload + 2) == rtpduration);
300 
301   gst_rtp_buffer_unmap (&rtpbuffer);
302   gst_buffer_unref (buffer);
303 }
304 
305 gint method;
306 
307 static void
setup_rtpdtmfsrc(void)308 setup_rtpdtmfsrc (void)
309 {
310   testclock = gst_test_clock_new ();
311   bus = gst_bus_new ();
312 
313   method = 1;
314   dtmfsrc = gst_check_setup_element ("rtpdtmfsrc");
315   sink = gst_check_setup_sink_pad (dtmfsrc, &rtp_dtmf_sink_template);
316   gst_element_set_bus (dtmfsrc, bus);
317   fail_unless (gst_element_set_clock (dtmfsrc, testclock));
318 
319   gst_pad_set_active (sink, TRUE);
320   fail_unless (gst_element_set_state (dtmfsrc, GST_STATE_PLAYING) ==
321       GST_STATE_CHANGE_SUCCESS);
322 }
323 
324 static void
teardown_dtmfsrc(void)325 teardown_dtmfsrc (void)
326 {
327   gst_object_unref (testclock);
328   gst_pad_set_active (sink, FALSE);
329   gst_element_set_bus (dtmfsrc, NULL);
330   gst_object_unref (bus);
331   gst_check_teardown_sink_pad (dtmfsrc);
332   gst_check_teardown_element (dtmfsrc);
333 }
334 
GST_START_TEST(test_dtmfsrc_invalid_events)335 GST_START_TEST (test_dtmfsrc_invalid_events)
336 {
337   GstStructure *s;
338 
339   /* Missing start */
340   s = gst_structure_new ("dtmf-event",
341       "type", G_TYPE_INT, 1, "number", G_TYPE_INT, 3,
342       "method", G_TYPE_INT, method, "volume", G_TYPE_INT, 8, NULL);
343   fail_unless (gst_pad_push_event (sink,
344           gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM, s)) == FALSE);
345 
346   /* Missing volume */
347   s = gst_structure_new ("dtmf-event",
348       "type", G_TYPE_INT, 1, "number", G_TYPE_INT, 3,
349       "method", G_TYPE_INT, method, "start", G_TYPE_BOOLEAN, TRUE, NULL);
350   fail_unless (gst_pad_push_event (sink,
351           gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM, s)) == FALSE);
352 
353   /* Missing number */
354   s = gst_structure_new ("dtmf-event",
355       "type", G_TYPE_INT, 1, "method", G_TYPE_INT, method,
356       "volume", G_TYPE_INT, 8, "start", G_TYPE_BOOLEAN, TRUE, NULL);
357   fail_unless (gst_pad_push_event (sink,
358           gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM, s)) == FALSE);
359 
360   /* Missing type */
361   s = gst_structure_new ("dtmf-event",
362       "number", G_TYPE_INT, 3, "method", G_TYPE_INT, method,
363       "volume", G_TYPE_INT, 8, "start", G_TYPE_BOOLEAN, TRUE, NULL);
364   fail_unless (gst_pad_push_event (sink,
365           gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM, s)) == FALSE);
366 
367   /* Stop before start */
368   s = gst_structure_new ("dtmf-event",
369       "type", G_TYPE_INT, 1, "number", G_TYPE_INT, 3,
370       "method", G_TYPE_INT, method, "volume", G_TYPE_INT, 8,
371       "start", G_TYPE_BOOLEAN, FALSE, NULL);
372   fail_unless (gst_pad_push_event (sink,
373           gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM, s)) == FALSE);
374 
375   gst_element_set_state (dtmfsrc, GST_STATE_NULL);
376 }
377 
378 GST_END_TEST;
379 
GST_START_TEST(test_rtpdtmfsrc_min_duration)380 GST_START_TEST (test_rtpdtmfsrc_min_duration)
381 {
382   GstStructure *s;
383   GstClockID id;
384   guint timestamp = 0;
385   GstCaps *expected_caps, *caps;
386 
387   /* Minimum duration dtmf */
388 
389   s = gst_structure_new ("dtmf-event",
390       "type", G_TYPE_INT, 1, "number", G_TYPE_INT, 3,
391       "method", G_TYPE_INT, 1, "volume", G_TYPE_INT, 8,
392       "start", G_TYPE_BOOLEAN, TRUE, NULL);
393   fail_unless (gst_pad_push_event (sink,
394           gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM,
395               gst_structure_copy (s))));
396   check_no_dtmf_event_message (bus);
397   gst_test_clock_wait_for_next_pending_id (GST_TEST_CLOCK (testclock), NULL);
398   fail_unless (buffers == NULL);
399   id = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (testclock));
400   fail_unless (gst_clock_id_get_time (id) == 0);
401   gst_clock_id_unref (id);
402   gst_structure_set_name (s, "dtmf-event-processed");
403   check_message_structure (s);
404 
405   s = gst_structure_new ("dtmf-event",
406       "type", G_TYPE_INT, 1, "method", G_TYPE_INT, 1,
407       "start", G_TYPE_BOOLEAN, FALSE, NULL);
408   fail_unless (gst_pad_push_event (sink,
409           gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM,
410               gst_structure_copy (s))));
411 
412   check_rtp_buffer (0, 20 * GST_MSECOND, TRUE, FALSE, 666, 999, 8, 3, 20);
413 
414   for (timestamp = 20; timestamp < MIN_PULSE_DURATION + 20; timestamp += 20) {
415     gst_test_clock_advance_time (GST_TEST_CLOCK (testclock),
416         20 * GST_MSECOND + 1);
417     gst_test_clock_wait_for_next_pending_id (GST_TEST_CLOCK (testclock), NULL);
418     fail_unless (buffers == NULL);
419     id = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (testclock));
420     fail_unless (gst_clock_id_get_time (id) == timestamp * GST_MSECOND);
421     gst_clock_id_unref (id);
422 
423     if (timestamp < MIN_PULSE_DURATION) {
424       check_rtp_buffer (timestamp * GST_MSECOND, 20 * GST_MSECOND, FALSE,
425           FALSE, 666, 999, 8, 3, timestamp + 20);
426       check_no_dtmf_event_message (bus);
427     } else {
428       gst_structure_set_name (s, "dtmf-event-processed");
429       check_message_structure (s);
430       check_rtp_buffer (timestamp * GST_MSECOND,
431           (20 + MIN_INTER_DIGIT_INTERVAL) * GST_MSECOND, FALSE, TRUE, 666,
432           999, 8, 3, timestamp + 20);
433     }
434 
435     fail_unless (buffers == NULL);
436   }
437 
438 
439   fail_unless (gst_test_clock_peek_id_count (GST_TEST_CLOCK (testclock)) == 0);
440 
441   /* caps check */
442 
443   expected_caps = gst_caps_new_simple ("application/x-rtp",
444       "encoding-name", G_TYPE_STRING, "TELEPHONE-EVENT",
445       "media", G_TYPE_STRING, "audio",
446       "clock-rate", G_TYPE_INT, 1000, "payload", G_TYPE_INT, 99,
447       "seqnum-offset", G_TYPE_UINT, 333,
448       "timestamp-offset", G_TYPE_UINT, 666,
449       "ssrc", G_TYPE_UINT, 999, "ptime", G_TYPE_UINT, 20, NULL);
450   caps = gst_pad_get_current_caps (sink);
451   fail_unless (gst_caps_can_intersect (caps, expected_caps));
452   gst_caps_unref (caps);
453   gst_caps_unref (expected_caps);
454 
455   gst_element_set_state (dtmfsrc, GST_STATE_NULL);
456 
457   check_no_dtmf_event_message (bus);
458 }
459 
460 GST_END_TEST;
461 
462 static GstStaticPadTemplate audio_dtmfsrc_sink_template =
463 GST_STATIC_PAD_TEMPLATE ("sink",
464     GST_PAD_SINK,
465     GST_PAD_ALWAYS,
466     GST_STATIC_CAPS ("audio/x-raw, "
467         "format = (string) \"" GST_AUDIO_NE (S16) "\", "
468         "rate = (int) 8003, " "channels = (int) 1")
469     );
470 static void
setup_dtmfsrc(void)471 setup_dtmfsrc (void)
472 {
473   testclock = gst_test_clock_new ();
474   bus = gst_bus_new ();
475 
476   method = 2;
477   dtmfsrc = gst_check_setup_element ("dtmfsrc");
478   sink = gst_check_setup_sink_pad (dtmfsrc, &audio_dtmfsrc_sink_template);
479   gst_element_set_bus (dtmfsrc, bus);
480   fail_unless (gst_element_set_clock (dtmfsrc, testclock));
481 
482   gst_pad_set_active (sink, TRUE);
483   fail_unless (gst_element_set_state (dtmfsrc, GST_STATE_PLAYING) ==
484       GST_STATE_CHANGE_SUCCESS);
485 }
486 
487 
GST_START_TEST(test_dtmfsrc_min_duration)488 GST_START_TEST (test_dtmfsrc_min_duration)
489 {
490   GstStructure *s;
491   GstClockID id;
492   GstClockTime timestamp = 0;
493   GstCaps *expected_caps, *caps;
494   guint interval;
495 
496   g_object_get (dtmfsrc, "interval", &interval, NULL);
497   fail_unless (interval == 50);
498 
499   /* Minimum duration dtmf */
500   gst_test_clock_set_time (GST_TEST_CLOCK (testclock), 0);
501 
502   s = gst_structure_new ("dtmf-event",
503       "type", G_TYPE_INT, 1, "number", G_TYPE_INT, 3,
504       "method", G_TYPE_INT, 2, "volume", G_TYPE_INT, 8,
505       "start", G_TYPE_BOOLEAN, TRUE, NULL);
506   fail_unless (gst_pad_push_event (sink,
507           gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM,
508               gst_structure_copy (s))));
509 
510   gst_test_clock_wait_for_next_pending_id (GST_TEST_CLOCK (testclock), NULL);
511   id = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (testclock));
512   fail_unless (gst_clock_id_get_time (id) == 0);
513   gst_clock_id_unref (id);
514 
515   gst_structure_set_name (s, "dtmf-event-processed");
516   check_message_structure (s);
517 
518   s = gst_structure_new ("dtmf-event",
519       "type", G_TYPE_INT, 1, "method", G_TYPE_INT, 2,
520       "start", G_TYPE_BOOLEAN, FALSE, NULL);
521   fail_unless (gst_pad_push_event (sink,
522           gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM,
523               gst_structure_copy (s))));
524 
525   for (timestamp = interval * GST_MSECOND;
526       timestamp < (MIN_PULSE_DURATION + MIN_INTER_DIGIT_INTERVAL) *
527       GST_MSECOND; timestamp += GST_MSECOND * interval) {
528     gst_test_clock_wait_for_next_pending_id (GST_TEST_CLOCK (testclock), NULL);
529     gst_test_clock_advance_time (GST_TEST_CLOCK (testclock),
530         interval * GST_MSECOND);
531 
532     id = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (testclock));
533     fail_unless (gst_clock_id_get_time (id) == timestamp);
534     gst_clock_id_unref (id);
535   }
536 
537   gst_structure_set_name (s, "dtmf-event-processed");
538   check_message_structure (s);
539 
540   check_buffers_duration ((MIN_PULSE_DURATION + MIN_INTER_DIGIT_INTERVAL) *
541       GST_MSECOND);
542 
543   fail_unless (gst_test_clock_peek_id_count (GST_TEST_CLOCK (testclock)) == 0);
544 
545   /* caps check */
546 
547   expected_caps = gst_caps_new_simple ("audio/x-raw",
548       "format", G_TYPE_STRING, GST_AUDIO_NE (S16),
549       "rate", G_TYPE_INT, 8003, "channels", G_TYPE_INT, 1, NULL);
550   caps = gst_pad_get_current_caps (sink);
551   fail_unless (gst_caps_can_intersect (caps, expected_caps));
552   gst_caps_unref (caps);
553   gst_caps_unref (expected_caps);
554 
555   gst_element_set_state (dtmfsrc, GST_STATE_NULL);
556 
557   check_no_dtmf_event_message (bus);
558 }
559 
560 GST_END_TEST;
561 
562 static Suite *
dtmf_suite(void)563 dtmf_suite (void)
564 {
565   Suite *s = suite_create ("dtmf");
566   TCase *tc;
567 
568   tc = tcase_create ("rtpdtmfdepay");
569   tcase_add_test (tc, test_rtpdtmfdepay);
570   suite_add_tcase (s, tc);
571 
572   tc = tcase_create ("rtpdtmfsrc");
573   tcase_add_checked_fixture (tc, setup_rtpdtmfsrc, teardown_dtmfsrc);
574   tcase_add_test (tc, test_dtmfsrc_invalid_events);
575   tcase_add_test (tc, test_rtpdtmfsrc_min_duration);
576   suite_add_tcase (s, tc);
577 
578   tc = tcase_create ("dtmfsrc");
579   tcase_add_checked_fixture (tc, setup_dtmfsrc, teardown_dtmfsrc);
580   tcase_add_test (tc, test_dtmfsrc_invalid_events);
581   tcase_add_test (tc, test_dtmfsrc_min_duration);
582   suite_add_tcase (s, tc);
583 
584   return s;
585 }
586 
587 
588 GST_CHECK_MAIN (dtmf);
589