webrtcbin test: Add for the case where a second m-line is renegotiated
[platform/upstream/gstreamer.git] / tests / check / elements / webrtcbin.c
1 /* GStreamer
2  *
3  * Unit tests for webrtcbin
4  *
5  * Copyright (C) 2017 Matthew Waters <matthew@centricular.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
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include <gst/gst.h>
29 #include <gst/check/gstcheck.h>
30 #include <gst/check/gstharness.h>
31 #include <gst/webrtc/webrtc.h>
32 #include "../../../ext/webrtc/webrtcsdp.h"
33 #include "../../../ext/webrtc/webrtcsdp.c"
34 #include "../../../ext/webrtc/utils.h"
35 #include "../../../ext/webrtc/utils.c"
36
37 #define OPUS_RTP_CAPS(pt) "application/x-rtp,payload=" G_STRINGIFY(pt) ",encoding-name=OPUS,media=audio,clock-rate=48000,ssrc=(uint)3384078950"
38 #define VP8_RTP_CAPS(pt) "application/x-rtp,payload=" G_STRINGIFY(pt) ",encoding-name=VP8,media=video,clock-rate=90000,ssrc=(uint)3484078950"
39
40 #define TEST_IS_OFFER_ELEMENT(t, e) ((((t)->offerror == 1 && (e) == (t)->webrtc1) || ((t)->offerror == 2 && (e) == (t)->webrtc2)) ? TRUE : FALSE)
41 #define TEST_GET_OFFEROR(t) (TEST_IS_OFFER_ELEMENT(t, t->webrtc1) ? (t)->webrtc1 : t->webrtc2)
42 #define TEST_GET_ANSWERER(t) (TEST_IS_OFFER_ELEMENT(t, t->webrtc1) ? (t)->webrtc2 : t->webrtc1)
43
44 #define TEST_SDP_IS_LOCAL(t, e, d) ((TEST_IS_OFFER_ELEMENT (t, e) ^ ((d)->type == GST_WEBRTC_SDP_TYPE_OFFER)) == 0)
45
46 typedef enum
47 {
48   STATE_NEW,
49   STATE_NEGOTIATION_NEEDED,
50   STATE_OFFER_CREATED,
51   STATE_OFFER_SET,
52   STATE_ANSWER_CREATED,
53   STATE_ANSWER_SET,
54   STATE_EOS,
55   STATE_ERROR,
56   STATE_CUSTOM,
57 } TestState;
58
59 /* basic premise of this is that webrtc1 and webrtc2 are attempting to connect
60  * to each other in various configurations */
61 struct test_webrtc;
62 struct test_webrtc
63 {
64   GList *harnesses;
65   GThread *thread;
66   GMainLoop *loop;
67   GstBus *bus1;
68   GstBus *bus2;
69   GstElement *webrtc1;
70   GstElement *webrtc2;
71   GMutex lock;
72   GCond cond;
73   TestState state;
74   guint offerror;
75   gpointer user_data;
76   GDestroyNotify data_notify;
77 /* *INDENT-OFF* */
78   void      (*on_negotiation_needed)    (struct test_webrtc * t,
79                                          GstElement * element,
80                                          gpointer user_data);
81   gpointer negotiation_data;
82   GDestroyNotify negotiation_notify;
83   void      (*on_ice_candidate)         (struct test_webrtc * t,
84                                          GstElement * element,
85                                          guint mlineindex,
86                                          gchar * candidate,
87                                          GstElement * other,
88                                          gpointer user_data);
89   gpointer ice_candidate_data;
90   GDestroyNotify ice_candidate_notify;
91   void      (*on_offer_created)         (struct test_webrtc * t,
92                                          GstElement * element,
93                                          GstPromise * promise,
94                                          gpointer user_data);
95   GstWebRTCSessionDescription *offer_desc;
96   guint offer_set_count;
97   gpointer offer_data;
98   GDestroyNotify offer_notify;
99   void      (*on_offer_set)             (struct test_webrtc * t,
100                                          GstElement * element,
101                                          GstPromise * promise,
102                                          gpointer user_data);
103   gpointer offer_set_data;
104   GDestroyNotify offer_set_notify;
105   void      (*on_answer_created)        (struct test_webrtc * t,
106                                          GstElement * element,
107                                          GstPromise * promise,
108                                          gpointer user_data);
109   GstWebRTCSessionDescription *answer_desc;
110   guint answer_set_count;
111   gpointer answer_data;
112   GDestroyNotify answer_notify;
113   void      (*on_answer_set)            (struct test_webrtc * t,
114                                          GstElement * element,
115                                          GstPromise * promise,
116                                          gpointer user_data);
117   gpointer answer_set_data;
118   GDestroyNotify answer_set_notify;
119   void      (*on_data_channel)          (struct test_webrtc * t,
120                                          GstElement * element,
121                                          GObject *data_channel,
122                                          gpointer user_data);
123   gpointer data_channel_data;
124   GDestroyNotify data_channel_notify;
125   void      (*on_pad_added)             (struct test_webrtc * t,
126                                          GstElement * element,
127                                          GstPad * pad,
128                                          gpointer user_data);
129   gpointer pad_added_data;
130   GDestroyNotify pad_added_notify;
131   void      (*bus_message)              (struct test_webrtc * t,
132                                          GstBus * bus,
133                                          GstMessage * msg,
134                                          gpointer user_data);
135   gpointer bus_data;
136   GDestroyNotify bus_notify;
137 /* *INDENT-ON* */
138 };
139
140 static void
141 test_webrtc_signal_state_unlocked (struct test_webrtc *t, TestState state)
142 {
143   t->state = state;
144   g_cond_broadcast (&t->cond);
145 }
146
147 static void
148 test_webrtc_signal_state (struct test_webrtc *t, TestState state)
149 {
150   g_mutex_lock (&t->lock);
151   test_webrtc_signal_state_unlocked (t, state);
152   g_mutex_unlock (&t->lock);
153 }
154
155 static void
156 _on_answer_set (GstPromise * promise, gpointer user_data)
157 {
158   struct test_webrtc *t = user_data;
159   GstElement *answerer = TEST_GET_ANSWERER (t);
160
161   g_mutex_lock (&t->lock);
162   if (++t->answer_set_count >= 2 && t->on_answer_set) {
163     t->on_answer_set (t, answerer, promise, t->answer_set_data);
164   }
165   if (t->state == STATE_ANSWER_CREATED)
166     t->state = STATE_ANSWER_SET;
167   g_cond_broadcast (&t->cond);
168   gst_promise_unref (promise);
169   g_mutex_unlock (&t->lock);
170 }
171
172 static void
173 _on_answer_received (GstPromise * promise, gpointer user_data)
174 {
175   struct test_webrtc *t = user_data;
176   GstElement *offeror = TEST_GET_OFFEROR (t);
177   GstElement *answerer = TEST_GET_ANSWERER (t);
178   const GstStructure *reply;
179   GstWebRTCSessionDescription *answer = NULL;
180   GError *error = NULL;
181
182   reply = gst_promise_get_reply (promise);
183   if (gst_structure_get (reply, "answer",
184           GST_TYPE_WEBRTC_SESSION_DESCRIPTION, &answer, NULL)) {
185     gchar *desc = gst_sdp_message_as_text (answer->sdp);
186     GST_INFO ("Created Answer: %s", desc);
187     g_free (desc);
188   } else if (gst_structure_get (reply, "error", G_TYPE_ERROR, &error, NULL)) {
189     GST_INFO ("Creating answer resulted in error: %s", error->message);
190   } else {
191     g_assert_not_reached ();
192   }
193
194   g_mutex_lock (&t->lock);
195
196   g_assert (t->answer_desc == NULL);
197   t->answer_desc = answer;
198
199   if (t->on_answer_created) {
200     t->on_answer_created (t, answerer, promise, t->answer_data);
201   }
202   gst_promise_unref (promise);
203
204   if (error)
205     goto error;
206
207   if (t->answer_desc) {
208     promise = gst_promise_new_with_change_func (_on_answer_set, t, NULL);
209     g_signal_emit_by_name (answerer, "set-local-description", t->answer_desc,
210         promise);
211     promise = gst_promise_new_with_change_func (_on_answer_set, t, NULL);
212     g_signal_emit_by_name (offeror, "set-remote-description", t->answer_desc,
213         promise);
214   }
215
216   test_webrtc_signal_state_unlocked (t, STATE_ANSWER_CREATED);
217   g_mutex_unlock (&t->lock);
218   return;
219
220 error:
221   g_clear_error (&error);
222   if (t->state < STATE_ERROR)
223     test_webrtc_signal_state_unlocked (t, STATE_ERROR);
224   g_mutex_unlock (&t->lock);
225   return;
226 }
227
228 static void
229 _on_offer_set (GstPromise * promise, gpointer user_data)
230 {
231   struct test_webrtc *t = user_data;
232   GstElement *offeror = TEST_GET_OFFEROR (t);
233
234   g_mutex_lock (&t->lock);
235   if (++t->offer_set_count >= 2 && t->on_offer_set) {
236     t->on_offer_set (t, offeror, promise, t->offer_set_data);
237   }
238   if (t->state == STATE_OFFER_CREATED)
239     t->state = STATE_OFFER_SET;
240   g_cond_broadcast (&t->cond);
241   gst_promise_unref (promise);
242   g_mutex_unlock (&t->lock);
243 }
244
245 static void
246 _on_offer_received (GstPromise * promise, gpointer user_data)
247 {
248   struct test_webrtc *t = user_data;
249   GstElement *offeror = TEST_GET_OFFEROR (t);
250   GstElement *answerer = TEST_GET_ANSWERER (t);
251   const GstStructure *reply;
252   GstWebRTCSessionDescription *offer = NULL;
253   GError *error = NULL;
254
255   reply = gst_promise_get_reply (promise);
256   if (gst_structure_get (reply, "offer",
257           GST_TYPE_WEBRTC_SESSION_DESCRIPTION, &offer, NULL)) {
258     gchar *desc = gst_sdp_message_as_text (offer->sdp);
259     GST_INFO ("Created offer: %s", desc);
260     g_free (desc);
261   } else if (gst_structure_get (reply, "error", G_TYPE_ERROR, &error, NULL)) {
262     GST_INFO ("Creating offer resulted in error: %s", error->message);
263   } else {
264     g_assert_not_reached ();
265   }
266
267   g_mutex_lock (&t->lock);
268
269   g_assert (t->offer_desc == NULL);
270   t->offer_desc = offer;
271
272   if (t->on_offer_created) {
273     t->on_offer_created (t, offeror, promise, t->offer_data);
274   }
275   gst_promise_unref (promise);
276
277   if (error)
278     goto error;
279
280   if (t->offer_desc) {
281     promise = gst_promise_new_with_change_func (_on_offer_set, t, NULL);
282     g_signal_emit_by_name (offeror, "set-local-description", t->offer_desc,
283         promise);
284     promise = gst_promise_new_with_change_func (_on_offer_set, t, NULL);
285     g_signal_emit_by_name (answerer, "set-remote-description", t->offer_desc,
286         promise);
287
288     promise = gst_promise_new_with_change_func (_on_answer_received, t, NULL);
289     g_signal_emit_by_name (answerer, "create-answer", NULL, promise);
290   }
291
292   test_webrtc_signal_state_unlocked (t, STATE_OFFER_CREATED);
293   g_mutex_unlock (&t->lock);
294   return;
295
296 error:
297   g_clear_error (&error);
298   if (t->state < STATE_ERROR)
299     test_webrtc_signal_state_unlocked (t, STATE_ERROR);
300   g_mutex_unlock (&t->lock);
301   return;
302 }
303
304 static gboolean
305 _bus_watch (GstBus * bus, GstMessage * msg, struct test_webrtc *t)
306 {
307   g_mutex_lock (&t->lock);
308   switch (GST_MESSAGE_TYPE (msg)) {
309     case GST_MESSAGE_STATE_CHANGED:
310       if (GST_ELEMENT (msg->src) == t->webrtc1
311           || GST_ELEMENT (msg->src) == t->webrtc2) {
312         GstState old, new, pending;
313
314         gst_message_parse_state_changed (msg, &old, &new, &pending);
315
316         {
317           gchar *dump_name = g_strconcat ("%s-state_changed-",
318               GST_OBJECT_NAME (msg->src), gst_element_state_get_name (old), "_",
319               gst_element_state_get_name (new), NULL);
320           GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (msg->src),
321               GST_DEBUG_GRAPH_SHOW_ALL, dump_name);
322           g_free (dump_name);
323         }
324       }
325       break;
326     case GST_MESSAGE_ERROR:{
327       GError *err = NULL;
328       gchar *dbg_info = NULL;
329
330       {
331         gchar *dump_name;
332         dump_name =
333             g_strconcat ("%s-error", GST_OBJECT_NAME (t->webrtc1), NULL);
334         GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (t->webrtc1),
335             GST_DEBUG_GRAPH_SHOW_ALL, dump_name);
336         g_free (dump_name);
337         dump_name =
338             g_strconcat ("%s-error", GST_OBJECT_NAME (t->webrtc2), NULL);
339         GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (t->webrtc2),
340             GST_DEBUG_GRAPH_SHOW_ALL, dump_name);
341         g_free (dump_name);
342       }
343
344       gst_message_parse_error (msg, &err, &dbg_info);
345       GST_WARNING ("ERROR from element %s: %s",
346           GST_OBJECT_NAME (msg->src), err->message);
347       GST_WARNING ("Debugging info: %s", (dbg_info) ? dbg_info : "none");
348       g_error_free (err);
349       g_free (dbg_info);
350       test_webrtc_signal_state_unlocked (t, STATE_ERROR);
351       break;
352     }
353     case GST_MESSAGE_EOS:{
354       {
355         gchar *dump_name;
356         dump_name = g_strconcat ("%s-eos", GST_OBJECT_NAME (t->webrtc1), NULL);
357         GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (t->webrtc1),
358             GST_DEBUG_GRAPH_SHOW_ALL, dump_name);
359         g_free (dump_name);
360         dump_name = g_strconcat ("%s-eos", GST_OBJECT_NAME (t->webrtc2), NULL);
361         GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (t->webrtc2),
362             GST_DEBUG_GRAPH_SHOW_ALL, dump_name);
363         g_free (dump_name);
364       }
365       GST_INFO ("EOS received");
366       test_webrtc_signal_state_unlocked (t, STATE_EOS);
367       break;
368     }
369     default:
370       break;
371   }
372
373   if (t->bus_message)
374     t->bus_message (t, bus, msg, t->bus_data);
375   g_mutex_unlock (&t->lock);
376
377   return TRUE;
378 }
379
380 static void
381 _on_negotiation_needed (GstElement * webrtc, struct test_webrtc *t)
382 {
383   g_mutex_lock (&t->lock);
384   if (t->on_negotiation_needed)
385     t->on_negotiation_needed (t, webrtc, t->negotiation_data);
386   if (t->state == STATE_NEW)
387     t->state = STATE_NEGOTIATION_NEEDED;
388   g_cond_broadcast (&t->cond);
389   g_mutex_unlock (&t->lock);
390 }
391
392 static void
393 _on_ice_candidate (GstElement * webrtc, guint mlineindex, gchar * candidate,
394     struct test_webrtc *t)
395 {
396   GstElement *other;
397
398   g_mutex_lock (&t->lock);
399   other = webrtc == t->webrtc1 ? t->webrtc2 : t->webrtc1;
400
401   if (t->on_ice_candidate)
402     t->on_ice_candidate (t, webrtc, mlineindex, candidate, other,
403         t->ice_candidate_data);
404
405   g_signal_emit_by_name (other, "add-ice-candidate", mlineindex, candidate);
406   g_mutex_unlock (&t->lock);
407 }
408
409 static void
410 _on_pad_added (GstElement * webrtc, GstPad * new_pad, struct test_webrtc *t)
411 {
412   g_mutex_lock (&t->lock);
413   if (t->on_pad_added)
414     t->on_pad_added (t, webrtc, new_pad, t->pad_added_data);
415   g_mutex_unlock (&t->lock);
416 }
417
418 static void
419 _on_data_channel (GstElement * webrtc, GObject * data_channel,
420     struct test_webrtc *t)
421 {
422   g_mutex_lock (&t->lock);
423   if (t->on_data_channel)
424     t->on_data_channel (t, webrtc, data_channel, t->data_channel_data);
425   g_mutex_unlock (&t->lock);
426 }
427
428 static void
429 _pad_added_not_reached (struct test_webrtc *t, GstElement * element,
430     GstPad * pad, gpointer user_data)
431 {
432   g_assert_not_reached ();
433 }
434
435 static void
436 _ice_candidate_not_reached (struct test_webrtc *t, GstElement * element,
437     guint mlineindex, gchar * candidate, GstElement * other, gpointer user_data)
438 {
439   g_assert_not_reached ();
440 }
441
442 static void
443 _negotiation_not_reached (struct test_webrtc *t, GstElement * element,
444     gpointer user_data)
445 {
446   g_assert_not_reached ();
447 }
448
449 static void
450 _bus_no_errors (struct test_webrtc *t, GstBus * bus, GstMessage * msg,
451     gpointer user_data)
452 {
453   switch (GST_MESSAGE_TYPE (msg)) {
454     case GST_MESSAGE_ERROR:{
455       g_assert_not_reached ();
456       break;
457     }
458     default:
459       break;
460   }
461 }
462
463 static void
464 _offer_answer_not_reached (struct test_webrtc *t, GstElement * element,
465     GstPromise * promise, gpointer user_data)
466 {
467   g_assert_not_reached ();
468 }
469
470 static void
471 _on_data_channel_not_reached (struct test_webrtc *t, GstElement * element,
472     GObject * data_channel, gpointer user_data)
473 {
474   g_assert_not_reached ();
475 }
476
477 static void
478 _broadcast (struct test_webrtc *t)
479 {
480   g_mutex_lock (&t->lock);
481   g_cond_broadcast (&t->cond);
482   g_mutex_unlock (&t->lock);
483 }
484
485 static gboolean
486 _unlock_create_thread (GMutex * lock)
487 {
488   g_mutex_unlock (lock);
489   return G_SOURCE_REMOVE;
490 }
491
492 static gpointer
493 _bus_thread (struct test_webrtc *t)
494 {
495   g_mutex_lock (&t->lock);
496   t->loop = g_main_loop_new (NULL, FALSE);
497   g_idle_add ((GSourceFunc) _unlock_create_thread, &t->lock);
498   g_cond_broadcast (&t->cond);
499
500   g_main_loop_run (t->loop);
501
502   g_mutex_lock (&t->lock);
503   g_main_loop_unref (t->loop);
504   t->loop = NULL;
505   g_cond_broadcast (&t->cond);
506   g_mutex_unlock (&t->lock);
507
508   return NULL;
509 }
510
511 static void
512 element_added_disable_sync (GstBin * bin, GstBin * sub_bin,
513     GstElement * element, gpointer user_data)
514 {
515   GObjectClass *class = G_OBJECT_GET_CLASS (element);
516   if (g_object_class_find_property (class, "async"))
517     g_object_set (element, "async", FALSE, NULL);
518   if (g_object_class_find_property (class, "sync"))
519     g_object_set (element, "sync", FALSE, NULL);
520 }
521
522 static struct test_webrtc *
523 test_webrtc_new (void)
524 {
525   struct test_webrtc *ret = g_new0 (struct test_webrtc, 1);
526
527   ret->on_negotiation_needed = _negotiation_not_reached;
528   ret->on_ice_candidate = _ice_candidate_not_reached;
529   ret->on_pad_added = _pad_added_not_reached;
530   ret->on_offer_created = _offer_answer_not_reached;
531   ret->on_answer_created = _offer_answer_not_reached;
532   ret->on_data_channel = _on_data_channel_not_reached;
533   ret->bus_message = _bus_no_errors;
534   ret->offerror = 1;
535
536   g_mutex_init (&ret->lock);
537   g_cond_init (&ret->cond);
538
539   ret->thread = g_thread_new ("test-webrtc", (GThreadFunc) _bus_thread, ret);
540
541   g_mutex_lock (&ret->lock);
542   while (!ret->loop)
543     g_cond_wait (&ret->cond, &ret->lock);
544   g_mutex_unlock (&ret->lock);
545
546   ret->bus1 = gst_bus_new ();
547   ret->bus2 = gst_bus_new ();
548   gst_bus_add_watch (ret->bus1, (GstBusFunc) _bus_watch, ret);
549   gst_bus_add_watch (ret->bus2, (GstBusFunc) _bus_watch, ret);
550   ret->webrtc1 = gst_element_factory_make ("webrtcbin", NULL);
551   ret->webrtc2 = gst_element_factory_make ("webrtcbin", NULL);
552   fail_unless (ret->webrtc1 != NULL && ret->webrtc2 != NULL);
553
554   gst_element_set_bus (ret->webrtc1, ret->bus1);
555   gst_element_set_bus (ret->webrtc2, ret->bus2);
556
557   g_signal_connect (ret->webrtc1, "deep-element-added",
558       G_CALLBACK (element_added_disable_sync), NULL);
559   g_signal_connect (ret->webrtc2, "deep-element-added",
560       G_CALLBACK (element_added_disable_sync), NULL);
561   g_signal_connect (ret->webrtc1, "on-negotiation-needed",
562       G_CALLBACK (_on_negotiation_needed), ret);
563   g_signal_connect (ret->webrtc2, "on-negotiation-needed",
564       G_CALLBACK (_on_negotiation_needed), ret);
565   g_signal_connect (ret->webrtc1, "on-ice-candidate",
566       G_CALLBACK (_on_ice_candidate), ret);
567   g_signal_connect (ret->webrtc2, "on-ice-candidate",
568       G_CALLBACK (_on_ice_candidate), ret);
569   g_signal_connect (ret->webrtc1, "on-data-channel",
570       G_CALLBACK (_on_data_channel), ret);
571   g_signal_connect (ret->webrtc2, "on-data-channel",
572       G_CALLBACK (_on_data_channel), ret);
573   g_signal_connect (ret->webrtc1, "pad-added", G_CALLBACK (_on_pad_added), ret);
574   g_signal_connect (ret->webrtc2, "pad-added", G_CALLBACK (_on_pad_added), ret);
575   g_signal_connect_swapped (ret->webrtc1, "notify::ice-gathering-state",
576       G_CALLBACK (_broadcast), ret);
577   g_signal_connect_swapped (ret->webrtc2, "notify::ice-gathering-state",
578       G_CALLBACK (_broadcast), ret);
579   g_signal_connect_swapped (ret->webrtc1, "notify::ice-connection-state",
580       G_CALLBACK (_broadcast), ret);
581   g_signal_connect_swapped (ret->webrtc2, "notify::ice-connection-state",
582       G_CALLBACK (_broadcast), ret);
583
584   return ret;
585 }
586
587 static void
588 test_webrtc_reset_negotiation (struct test_webrtc *t)
589 {
590   if (t->offer_desc)
591     gst_webrtc_session_description_free (t->offer_desc);
592   t->offer_desc = NULL;
593   t->offer_set_count = 0;
594   if (t->answer_desc)
595     gst_webrtc_session_description_free (t->answer_desc);
596   t->answer_desc = NULL;
597   t->answer_set_count = 0;
598
599   test_webrtc_signal_state (t, STATE_NEGOTIATION_NEEDED);
600 }
601
602 static void
603 test_webrtc_free (struct test_webrtc *t)
604 {
605   /* Otherwise while one webrtcbin is being destroyed, the other could
606    * generate a signal that calls into the destroyed webrtcbin */
607   g_signal_handlers_disconnect_by_data (t->webrtc1, t);
608   g_signal_handlers_disconnect_by_data (t->webrtc2, t);
609
610   g_main_loop_quit (t->loop);
611   g_mutex_lock (&t->lock);
612   while (t->loop)
613     g_cond_wait (&t->cond, &t->lock);
614   g_mutex_unlock (&t->lock);
615
616   g_thread_join (t->thread);
617
618   gst_bus_remove_watch (t->bus1);
619   gst_bus_remove_watch (t->bus2);
620
621   gst_bus_set_flushing (t->bus1, TRUE);
622   gst_bus_set_flushing (t->bus2, TRUE);
623
624   gst_object_unref (t->bus1);
625   gst_object_unref (t->bus2);
626
627   g_list_free_full (t->harnesses, (GDestroyNotify) gst_harness_teardown);
628
629   if (t->data_notify)
630     t->data_notify (t->user_data);
631   if (t->negotiation_notify)
632     t->negotiation_notify (t->negotiation_data);
633   if (t->ice_candidate_notify)
634     t->ice_candidate_notify (t->ice_candidate_data);
635   if (t->offer_notify)
636     t->offer_notify (t->offer_data);
637   if (t->offer_set_notify)
638     t->offer_set_notify (t->offer_set_data);
639   if (t->answer_notify)
640     t->answer_notify (t->answer_data);
641   if (t->answer_set_notify)
642     t->answer_set_notify (t->answer_set_data);
643   if (t->pad_added_notify)
644     t->pad_added_notify (t->pad_added_data);
645   if (t->data_channel_notify)
646     t->data_channel_notify (t->data_channel_data);
647
648   fail_unless_equals_int (GST_STATE_CHANGE_SUCCESS,
649       gst_element_set_state (t->webrtc1, GST_STATE_NULL));
650   fail_unless_equals_int (GST_STATE_CHANGE_SUCCESS,
651       gst_element_set_state (t->webrtc2, GST_STATE_NULL));
652
653   test_webrtc_reset_negotiation (t);
654
655   gst_object_unref (t->webrtc1);
656   gst_object_unref (t->webrtc2);
657
658   g_mutex_clear (&t->lock);
659   g_cond_clear (&t->cond);
660
661   g_free (t);
662 }
663
664 static void
665 test_webrtc_create_offer (struct test_webrtc *t)
666 {
667   GstPromise *promise;
668   GstElement *offeror = TEST_GET_OFFEROR (t);
669
670   promise = gst_promise_new_with_change_func (_on_offer_received, t, NULL);
671   g_signal_emit_by_name (offeror, "create-offer", NULL, promise);
672 }
673
674 static void
675 test_webrtc_wait_for_state_mask (struct test_webrtc *t, TestState state)
676 {
677   g_mutex_lock (&t->lock);
678   while (((1 << t->state) & state) == 0) {
679     GST_INFO ("test state 0x%x, current 0x%x", state, (1 << t->state));
680     g_cond_wait (&t->cond, &t->lock);
681   }
682   GST_INFO ("have test state 0x%x, current 0x%x", state, 1 << t->state);
683   g_mutex_unlock (&t->lock);
684 }
685
686 static void
687 test_webrtc_wait_for_answer_error_eos (struct test_webrtc *t)
688 {
689   TestState states = 0;
690   states |= (1 << STATE_ANSWER_SET);
691   states |= (1 << STATE_EOS);
692   states |= (1 << STATE_ERROR);
693   test_webrtc_wait_for_state_mask (t, states);
694 }
695
696 static void
697 test_webrtc_wait_for_ice_gathering_complete (struct test_webrtc *t)
698 {
699   GstWebRTCICEGatheringState ice_state1, ice_state2;
700   g_mutex_lock (&t->lock);
701   g_object_get (t->webrtc1, "ice-gathering-state", &ice_state1, NULL);
702   g_object_get (t->webrtc2, "ice-gathering-state", &ice_state2, NULL);
703   while (ice_state1 != GST_WEBRTC_ICE_GATHERING_STATE_COMPLETE &&
704       ice_state2 != GST_WEBRTC_ICE_GATHERING_STATE_COMPLETE) {
705     g_cond_wait (&t->cond, &t->lock);
706     g_object_get (t->webrtc1, "ice-gathering-state", &ice_state1, NULL);
707     g_object_get (t->webrtc2, "ice-gathering-state", &ice_state2, NULL);
708   }
709   g_mutex_unlock (&t->lock);
710 }
711
712 #if 0
713 static void
714 test_webrtc_wait_for_ice_connection (struct test_webrtc *t,
715     GstWebRTCICEConnectionState states)
716 {
717   GstWebRTCICEConnectionState ice_state1, ice_state2, current;
718   g_mutex_lock (&t->lock);
719   g_object_get (t->webrtc1, "ice-connection-state", &ice_state1, NULL);
720   g_object_get (t->webrtc2, "ice-connection-state", &ice_state2, NULL);
721   current = (1 << ice_state1) | (1 << ice_state2);
722   while ((current & states) == 0 || (current & ~states)) {
723     g_cond_wait (&t->cond, &t->lock);
724     g_object_get (t->webrtc1, "ice-connection-state", &ice_state1, NULL);
725     g_object_get (t->webrtc2, "ice-connection-state", &ice_state2, NULL);
726     current = (1 << ice_state1) | (1 << ice_state2);
727   }
728   g_mutex_unlock (&t->lock);
729 }
730 #endif
731 static void
732 _pad_added_fakesink (struct test_webrtc *t, GstElement * element,
733     GstPad * pad, gpointer user_data)
734 {
735   GstHarness *h;
736
737   if (GST_PAD_DIRECTION (pad) != GST_PAD_SRC)
738     return;
739
740   h = gst_harness_new_with_element (element, NULL, "src_%u");
741   gst_harness_add_sink_parse (h, "fakesink async=false sync=false");
742
743   t->harnesses = g_list_prepend (t->harnesses, h);
744 }
745
746 static void
747 on_negotiation_needed_hit (struct test_webrtc *t, GstElement * element,
748     gpointer user_data)
749 {
750   guint *flag = (guint *) user_data;
751
752   *flag |= 1 << ((element == t->webrtc1) ? 1 : 2);
753 }
754
755 typedef void (*ValidateSDPFunc) (struct test_webrtc * t, GstElement * element,
756     GstWebRTCSessionDescription * desc, gpointer user_data);
757
758 struct validate_sdp;
759 struct validate_sdp
760 {
761   ValidateSDPFunc validate;
762   gpointer user_data;
763   struct validate_sdp *next;
764 };
765
766 #define VAL_SDP_INIT(name,func,data,next) \
767     struct validate_sdp name = { func, data, next }
768
769 static void
770 _check_validate_sdp (struct test_webrtc *t, GstElement * element,
771     GstPromise * promise, gpointer user_data)
772 {
773   struct validate_sdp *validate = user_data;
774   GstWebRTCSessionDescription *desc = NULL;
775
776   if (TEST_IS_OFFER_ELEMENT (t, element))
777     desc = t->offer_desc;
778   else
779     desc = t->answer_desc;
780
781   while (validate) {
782     validate->validate (t, element, desc, validate->user_data);
783     validate = validate->next;
784   }
785 }
786
787 static void
788 test_validate_sdp_full (struct test_webrtc *t, struct validate_sdp *offer,
789     struct validate_sdp *answer, TestState wait_mask,
790     gboolean perform_state_change)
791 {
792   if (offer) {
793     t->offer_data = offer;
794     t->on_offer_created = _check_validate_sdp;
795   } else {
796     t->offer_data = NULL;
797     t->on_offer_created = NULL;
798   }
799   if (answer) {
800     t->answer_data = answer;
801     t->on_answer_created = _check_validate_sdp;
802   } else {
803     t->answer_data = NULL;
804     t->on_answer_created = NULL;
805   }
806
807   if (perform_state_change) {
808     fail_if (gst_element_set_state (t->webrtc1,
809             GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
810     fail_if (gst_element_set_state (t->webrtc2,
811             GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
812   }
813
814   test_webrtc_create_offer (t);
815
816   if (wait_mask == 0) {
817     test_webrtc_wait_for_answer_error_eos (t);
818     fail_unless (t->state == STATE_ANSWER_SET);
819   } else {
820     test_webrtc_wait_for_state_mask (t, wait_mask);
821   }
822 }
823
824 static void
825 test_validate_sdp (struct test_webrtc *t, struct validate_sdp *offer,
826     struct validate_sdp *answer)
827 {
828   test_validate_sdp_full (t, offer, answer, 0, TRUE);
829 }
830
831 static void
832 _count_num_sdp_media (struct test_webrtc *t, GstElement * element,
833     GstWebRTCSessionDescription * desc, gpointer user_data)
834 {
835   guint expected = GPOINTER_TO_UINT (user_data);
836
837   fail_unless_equals_int (gst_sdp_message_medias_len (desc->sdp), expected);
838 }
839
840 GST_START_TEST (test_sdp_no_media)
841 {
842   struct test_webrtc *t = test_webrtc_new ();
843   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (0), NULL);
844
845   /* check that a no stream connection creates 0 media sections */
846
847   t->on_negotiation_needed = NULL;
848   test_validate_sdp (t, &count, &count);
849
850   test_webrtc_free (t);
851 }
852
853 GST_END_TEST;
854
855 static void
856 on_sdp_media_direction (struct test_webrtc *t, GstElement * element,
857     GstWebRTCSessionDescription * desc, gpointer user_data)
858 {
859   gchar **expected_directions = user_data;
860   int i;
861
862   for (i = 0; i < gst_sdp_message_medias_len (desc->sdp); i++) {
863     const GstSDPMedia *media = gst_sdp_message_get_media (desc->sdp, i);
864
865     if (g_strcmp0 (gst_sdp_media_get_media (media), "audio") == 0
866         || g_strcmp0 (gst_sdp_media_get_media (media), "video") == 0) {
867       gboolean have_direction = FALSE;
868       int j;
869
870       for (j = 0; j < gst_sdp_media_attributes_len (media); j++) {
871         const GstSDPAttribute *attr = gst_sdp_media_get_attribute (media, j);
872
873         if (g_strcmp0 (attr->key, "inactive") == 0) {
874           fail_unless (have_direction == FALSE,
875               "duplicate/multiple directions for media %u", j);
876           have_direction = TRUE;
877           fail_unless (g_strcmp0 (attr->key, expected_directions[i]) == 0);
878         } else if (g_strcmp0 (attr->key, "sendonly") == 0) {
879           fail_unless (have_direction == FALSE,
880               "duplicate/multiple directions for media %u", j);
881           have_direction = TRUE;
882           fail_unless (g_strcmp0 (attr->key, expected_directions[i]) == 0);
883         } else if (g_strcmp0 (attr->key, "recvonly") == 0) {
884           fail_unless (have_direction == FALSE,
885               "duplicate/multiple directions for media %u", j);
886           have_direction = TRUE;
887           fail_unless (g_strcmp0 (attr->key, expected_directions[i]) == 0);
888         } else if (g_strcmp0 (attr->key, "sendrecv") == 0) {
889           fail_unless (have_direction == FALSE,
890               "duplicate/multiple directions for media %u", j);
891           have_direction = TRUE;
892           fail_unless (g_strcmp0 (attr->key, expected_directions[i]) == 0);
893         }
894       }
895       fail_unless (have_direction, "no direction attribute in media %u", i);
896     }
897   }
898 }
899
900 static void
901 on_sdp_media_no_duplicate_payloads (struct test_webrtc *t, GstElement * element,
902     GstWebRTCSessionDescription * desc, gpointer user_data)
903 {
904   int i, j, k;
905
906   for (i = 0; i < gst_sdp_message_medias_len (desc->sdp); i++) {
907     const GstSDPMedia *media = gst_sdp_message_get_media (desc->sdp, i);
908
909     GArray *media_formats = g_array_new (FALSE, FALSE, sizeof (int));
910     for (j = 0; j < gst_sdp_media_formats_len (media); j++) {
911       int pt = atoi (gst_sdp_media_get_format (media, j));
912       for (k = 0; k < media_formats->len; k++) {
913         int val = g_array_index (media_formats, int, k);
914         if (pt == val)
915           fail ("found an unexpected duplicate payload type %u within media %u",
916               pt, i);
917       }
918       g_array_append_val (media_formats, pt);
919     }
920     g_array_free (media_formats, TRUE);
921   }
922 }
923
924 static void
925 on_sdp_media_count_formats (struct test_webrtc *t, GstElement * element,
926     GstWebRTCSessionDescription * desc, gpointer user_data)
927 {
928   guint *expected_n_media_formats = user_data;
929   int i;
930
931   for (i = 0; i < gst_sdp_message_medias_len (desc->sdp); i++) {
932     const GstSDPMedia *media = gst_sdp_message_get_media (desc->sdp, i);
933     fail_unless_equals_int (gst_sdp_media_formats_len (media),
934         expected_n_media_formats[i]);
935   }
936 }
937
938 static void
939 on_sdp_media_setup (struct test_webrtc *t, GstElement * element,
940     GstWebRTCSessionDescription * desc, gpointer user_data)
941 {
942   gchar **expected_setup = user_data;
943   int i;
944
945   for (i = 0; i < gst_sdp_message_medias_len (desc->sdp); i++) {
946     const GstSDPMedia *media = gst_sdp_message_get_media (desc->sdp, i);
947     gboolean have_setup = FALSE;
948     int j;
949
950     for (j = 0; j < gst_sdp_media_attributes_len (media); j++) {
951       const GstSDPAttribute *attr = gst_sdp_media_get_attribute (media, j);
952
953       if (g_strcmp0 (attr->key, "setup") == 0) {
954         fail_unless (have_setup == FALSE,
955             "duplicate/multiple setup for media %u", j);
956         have_setup = TRUE;
957         fail_unless (g_strcmp0 (attr->value, expected_setup[i]) == 0);
958       }
959     }
960     fail_unless (have_setup, "no setup attribute in media %u", i);
961   }
962 }
963
964 static void
965 add_fake_audio_src_harness (GstHarness * h, gint pt)
966 {
967   GstCaps *caps = gst_caps_from_string (OPUS_RTP_CAPS (pt));
968   GstStructure *s = gst_caps_get_structure (caps, 0);
969   gst_structure_set (s, "payload", G_TYPE_INT, pt, NULL);
970   gst_harness_set_src_caps (h, caps);
971   gst_harness_add_src_parse (h, "fakesrc is-live=true", TRUE);
972 }
973
974 static void
975 add_fake_video_src_harness (GstHarness * h, gint pt)
976 {
977   GstCaps *caps = gst_caps_from_string (VP8_RTP_CAPS (pt));
978   GstStructure *s = gst_caps_get_structure (caps, 0);
979   gst_structure_set (s, "payload", G_TYPE_INT, pt, NULL);
980   gst_harness_set_src_caps (h, caps);
981   gst_harness_add_src_parse (h, "fakesrc is-live=true", TRUE);
982 }
983
984 static struct test_webrtc *
985 create_audio_test (void)
986 {
987   struct test_webrtc *t = test_webrtc_new ();
988   GstHarness *h;
989
990   t->on_negotiation_needed = NULL;
991   t->on_ice_candidate = NULL;
992   t->on_pad_added = _pad_added_fakesink;
993
994   h = gst_harness_new_with_element (t->webrtc1, "sink_0", NULL);
995   add_fake_audio_src_harness (h, 96);
996   t->harnesses = g_list_prepend (t->harnesses, h);
997
998   return t;
999 }
1000
1001 GST_START_TEST (test_audio)
1002 {
1003   struct test_webrtc *t = create_audio_test ();
1004   VAL_SDP_INIT (no_duplicate_payloads, on_sdp_media_no_duplicate_payloads,
1005       NULL, NULL);
1006   guint media_format_count[] = { 1 };
1007   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
1008       media_format_count, &no_duplicate_payloads);
1009   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (1),
1010       &media_formats);
1011   const gchar *expected_offer_setup[] = { "actpass", };
1012   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup, &count);
1013   const gchar *expected_answer_setup[] = { "active", };
1014   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
1015       &count);
1016   const gchar *expected_offer_direction[] = { "sendrecv", };
1017   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
1018       &offer_setup);
1019   const gchar *expected_answer_direction[] = { "recvonly", };
1020   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
1021       &answer_setup);
1022
1023   /* check that a single stream connection creates the associated number
1024    * of media sections */
1025
1026   test_validate_sdp (t, &offer, &answer);
1027   test_webrtc_free (t);
1028 }
1029
1030 GST_END_TEST;
1031
1032 static void
1033 _check_ice_port_restriction (struct test_webrtc *t, GstElement * element,
1034     guint mlineindex, gchar * candidate, GstElement * other, gpointer user_data)
1035 {
1036   GRegex *regex;
1037   GMatchInfo *match_info;
1038
1039   gchar *candidate_port;
1040   gchar *candidate_protocol;
1041   gchar *candidate_typ;
1042   guint port_as_int;
1043   guint peer_number;
1044
1045   regex =
1046       g_regex_new ("candidate:(\\d+) (1) (UDP|TCP) (\\d+) ([0-9.]+|[0-9a-f:]+)"
1047       " (\\d+) typ ([a-z]+)", 0, 0, NULL);
1048
1049   g_regex_match (regex, candidate, 0, &match_info);
1050   fail_unless (g_match_info_get_match_count (match_info) == 8, candidate);
1051
1052   candidate_protocol = g_match_info_fetch (match_info, 2);
1053   candidate_port = g_match_info_fetch (match_info, 6);
1054   candidate_typ = g_match_info_fetch (match_info, 7);
1055
1056   peer_number = t->webrtc1 == element ? 1 : 2;
1057
1058   port_as_int = atoi (candidate_port);
1059
1060   if (!g_strcmp0 (candidate_typ, "host") && port_as_int != 9) {
1061     guint expected_min = peer_number * 10000 + 1000;
1062     guint expected_max = expected_min + 999;
1063
1064     fail_unless (port_as_int >= expected_min);
1065     fail_unless (port_as_int <= expected_max);
1066   }
1067
1068   g_free (candidate_port);
1069   g_free (candidate_protocol);
1070   g_free (candidate_typ);
1071   g_match_info_free (match_info);
1072   g_regex_unref (regex);
1073 }
1074
1075 GST_START_TEST (test_ice_port_restriction)
1076 {
1077   struct test_webrtc *t = create_audio_test ();
1078   GObject *webrtcice;
1079
1080   VAL_SDP_INIT (offer, _count_num_sdp_media, GUINT_TO_POINTER (1), NULL);
1081   VAL_SDP_INIT (answer, _count_num_sdp_media, GUINT_TO_POINTER (1), NULL);
1082
1083   /*
1084    *  Ports are defined as follows "{peer}{protocol}000"
1085    *  - peer number: "1" for t->webrtc1, "2" for t->webrtc2
1086    */
1087   g_object_get (t->webrtc1, "ice-agent", &webrtcice, NULL);
1088   g_object_set (webrtcice, "min-rtp-port", 11000, "max-rtp-port", 11999, NULL);
1089   g_object_unref (webrtcice);
1090
1091   g_object_get (t->webrtc2, "ice-agent", &webrtcice, NULL);
1092   g_object_set (webrtcice, "min-rtp-port", 21000, "max-rtp-port", 21999, NULL);
1093   g_object_unref (webrtcice);
1094
1095   t->on_ice_candidate = _check_ice_port_restriction;
1096   test_validate_sdp (t, &offer, &answer);
1097
1098   test_webrtc_wait_for_ice_gathering_complete (t);
1099   test_webrtc_free (t);
1100 }
1101
1102 GST_END_TEST;
1103
1104 static struct test_webrtc *
1105 create_audio_video_test (void)
1106 {
1107   struct test_webrtc *t = create_audio_test ();
1108   GstHarness *h;
1109
1110   h = gst_harness_new_with_element (t->webrtc1, "sink_1", NULL);
1111   add_fake_video_src_harness (h, 97);
1112   t->harnesses = g_list_prepend (t->harnesses, h);
1113
1114   return t;
1115 }
1116
1117 GST_START_TEST (test_audio_video)
1118 {
1119   struct test_webrtc *t = create_audio_video_test ();
1120   VAL_SDP_INIT (no_duplicate_payloads, on_sdp_media_no_duplicate_payloads,
1121       NULL, NULL);
1122   guint media_format_count[] = { 1, 1 };
1123   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
1124       media_format_count, &no_duplicate_payloads);
1125   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
1126       &media_formats);
1127   const gchar *expected_offer_setup[] = { "actpass", "actpass" };
1128   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup, &count);
1129   const gchar *expected_answer_setup[] = { "active", "active" };
1130   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
1131       &count);
1132   const gchar *expected_offer_direction[] = { "sendrecv", "sendrecv" };
1133   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
1134       &offer_setup);
1135   const gchar *expected_answer_direction[] = { "recvonly", "recvonly" };
1136   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
1137       &answer_setup);
1138
1139   /* check that a dual stream connection creates the associated number
1140    * of media sections */
1141
1142   test_validate_sdp (t, &offer, &answer);
1143   test_webrtc_free (t);
1144 }
1145
1146 GST_END_TEST;
1147
1148 GST_START_TEST (test_media_direction)
1149 {
1150   struct test_webrtc *t = create_audio_video_test ();
1151   VAL_SDP_INIT (no_duplicate_payloads, on_sdp_media_no_duplicate_payloads,
1152       NULL, NULL);
1153   guint media_format_count[] = { 1, 1 };
1154   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
1155       media_format_count, &no_duplicate_payloads);
1156   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
1157       &media_formats);
1158   const gchar *expected_offer_setup[] = { "actpass", "actpass" };
1159   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup, &count);
1160   const gchar *expected_answer_setup[] = { "active", "active" };
1161   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
1162       &count);
1163
1164   const gchar *expected_offer_direction[] = { "sendrecv", "sendrecv" };
1165   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
1166       &offer_setup);
1167   const gchar *expected_answer_direction[] = { "sendrecv", "recvonly" };
1168   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
1169       &answer_setup);
1170   GstHarness *h;
1171
1172   /* check the default media directions for transceivers */
1173
1174   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
1175   add_fake_audio_src_harness (h, 96);
1176   t->harnesses = g_list_prepend (t->harnesses, h);
1177
1178   test_validate_sdp (t, &offer, &answer);
1179   test_webrtc_free (t);
1180 }
1181
1182 GST_END_TEST;
1183
1184 static void
1185 on_sdp_media_payload_types (struct test_webrtc *t, GstElement * element,
1186     GstWebRTCSessionDescription * desc, gpointer user_data)
1187 {
1188   const GstSDPMedia *vmedia;
1189   guint j;
1190
1191   vmedia = gst_sdp_message_get_media (desc->sdp, 1);
1192
1193   for (j = 0; j < gst_sdp_media_attributes_len (vmedia); j++) {
1194     const GstSDPAttribute *attr = gst_sdp_media_get_attribute (vmedia, j);
1195
1196     if (!g_strcmp0 (attr->key, "rtpmap")) {
1197       if (g_str_has_prefix (attr->value, "97")) {
1198         fail_unless_equals_string (attr->value, "97 VP8/90000");
1199       } else if (g_str_has_prefix (attr->value, "96")) {
1200         fail_unless_equals_string (attr->value, "96 red/90000");
1201       } else if (g_str_has_prefix (attr->value, "98")) {
1202         fail_unless_equals_string (attr->value, "98 ulpfec/90000");
1203       } else if (g_str_has_prefix (attr->value, "99")) {
1204         fail_unless_equals_string (attr->value, "99 rtx/90000");
1205       } else if (g_str_has_prefix (attr->value, "100")) {
1206         fail_unless_equals_string (attr->value, "100 rtx/90000");
1207       }
1208     }
1209   }
1210 }
1211
1212 /* In this test we verify that webrtcbin will pick available payload
1213  * types when it needs to, in that example for RTX and FEC */
1214 GST_START_TEST (test_payload_types)
1215 {
1216   struct test_webrtc *t = create_audio_video_test ();
1217   VAL_SDP_INIT (no_duplicate_payloads, on_sdp_media_no_duplicate_payloads,
1218       NULL, NULL);
1219   guint media_format_count[] = { 1, 5, };
1220   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
1221       media_format_count, &no_duplicate_payloads);
1222   VAL_SDP_INIT (payloads, on_sdp_media_payload_types, NULL, &media_formats);
1223   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2), &payloads);
1224   const gchar *expected_offer_setup[] = { "actpass", "actpass" };
1225   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup, &count);
1226   const gchar *expected_offer_direction[] = { "sendrecv", "sendrecv" };
1227   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
1228       &offer_setup);
1229   GstWebRTCRTPTransceiver *trans;
1230   GArray *transceivers;
1231
1232   g_signal_emit_by_name (t->webrtc1, "get-transceivers", &transceivers);
1233   fail_unless_equals_int (transceivers->len, 2);
1234   trans = g_array_index (transceivers, GstWebRTCRTPTransceiver *, 1);
1235   g_object_set (trans, "fec-type", GST_WEBRTC_FEC_TYPE_ULP_RED, "do-nack", TRUE,
1236       NULL);
1237   g_array_unref (transceivers);
1238
1239   /* We don't really care about the answer here */
1240   test_validate_sdp (t, &offer, NULL);
1241   test_webrtc_free (t);
1242 }
1243
1244 GST_END_TEST;
1245
1246 GST_START_TEST (test_no_nice_elements_request_pad)
1247 {
1248   struct test_webrtc *t = test_webrtc_new ();
1249   GstPluginFeature *nicesrc, *nicesink;
1250   GstRegistry *registry;
1251   GstPad *pad;
1252
1253   /* check that the absence of libnice elements posts an error on the bus
1254    * when requesting a pad */
1255
1256   registry = gst_registry_get ();
1257   nicesrc = gst_registry_lookup_feature (registry, "nicesrc");
1258   nicesink = gst_registry_lookup_feature (registry, "nicesink");
1259
1260   if (nicesrc)
1261     gst_registry_remove_feature (registry, nicesrc);
1262   if (nicesink)
1263     gst_registry_remove_feature (registry, nicesink);
1264
1265   t->bus_message = NULL;
1266
1267   pad = gst_element_get_request_pad (t->webrtc1, "sink_0");
1268   fail_unless (pad == NULL);
1269
1270   test_webrtc_wait_for_answer_error_eos (t);
1271   fail_unless_equals_int (STATE_ERROR, t->state);
1272   test_webrtc_free (t);
1273
1274   if (nicesrc)
1275     gst_registry_add_feature (registry, nicesrc);
1276   if (nicesink)
1277     gst_registry_add_feature (registry, nicesink);
1278 }
1279
1280 GST_END_TEST;
1281
1282 GST_START_TEST (test_no_nice_elements_state_change)
1283 {
1284   struct test_webrtc *t = test_webrtc_new ();
1285   GstPluginFeature *nicesrc, *nicesink;
1286   GstRegistry *registry;
1287
1288   /* check that the absence of libnice elements posts an error on the bus */
1289
1290   registry = gst_registry_get ();
1291   nicesrc = gst_registry_lookup_feature (registry, "nicesrc");
1292   nicesink = gst_registry_lookup_feature (registry, "nicesink");
1293
1294   if (nicesrc)
1295     gst_registry_remove_feature (registry, nicesrc);
1296   if (nicesink)
1297     gst_registry_remove_feature (registry, nicesink);
1298
1299   t->bus_message = NULL;
1300   gst_element_set_state (t->webrtc1, GST_STATE_READY);
1301
1302   test_webrtc_wait_for_answer_error_eos (t);
1303   fail_unless_equals_int (STATE_ERROR, t->state);
1304   test_webrtc_free (t);
1305
1306   if (nicesrc)
1307     gst_registry_add_feature (registry, nicesrc);
1308   if (nicesink)
1309     gst_registry_add_feature (registry, nicesink);
1310 }
1311
1312 GST_END_TEST;
1313
1314 static void
1315 validate_rtc_stats (const GstStructure * s)
1316 {
1317   GstWebRTCStatsType type = 0;
1318   double ts = 0.;
1319   gchar *id = NULL;
1320
1321   fail_unless (gst_structure_get (s, "type", GST_TYPE_WEBRTC_STATS_TYPE, &type,
1322           NULL));
1323   fail_unless (gst_structure_get (s, "id", G_TYPE_STRING, &id, NULL));
1324   fail_unless (gst_structure_get (s, "timestamp", G_TYPE_DOUBLE, &ts, NULL));
1325   fail_unless (type != 0);
1326   fail_unless (ts != 0.);
1327   fail_unless (id != NULL);
1328
1329   g_free (id);
1330 }
1331
1332 static void
1333 validate_codec_stats (const GstStructure * s)
1334 {
1335   guint pt = 0, clock_rate = 0;
1336
1337   fail_unless (gst_structure_get (s, "payload-type", G_TYPE_UINT, &pt, NULL));
1338   fail_unless (gst_structure_get (s, "clock-rate", G_TYPE_UINT, &clock_rate,
1339           NULL));
1340   fail_unless (pt >= 0 && pt <= 127);
1341   fail_unless (clock_rate >= 0);
1342 }
1343
1344 static void
1345 validate_rtc_stream_stats (const GstStructure * s, const GstStructure * stats)
1346 {
1347   gchar *codec_id, *transport_id;
1348   GstStructure *codec, *transport;
1349
1350   fail_unless (gst_structure_get (s, "codec-id", G_TYPE_STRING, &codec_id,
1351           NULL));
1352   fail_unless (gst_structure_get (s, "transport-id", G_TYPE_STRING,
1353           &transport_id, NULL));
1354
1355   fail_unless (gst_structure_get (stats, codec_id, GST_TYPE_STRUCTURE, &codec,
1356           NULL));
1357   fail_unless (gst_structure_get (stats, transport_id, GST_TYPE_STRUCTURE,
1358           &transport, NULL));
1359
1360   fail_unless (codec != NULL);
1361   fail_unless (transport != NULL);
1362
1363   gst_structure_free (transport);
1364   gst_structure_free (codec);
1365
1366   g_free (codec_id);
1367   g_free (transport_id);
1368 }
1369
1370 static void
1371 validate_inbound_rtp_stats (const GstStructure * s, const GstStructure * stats)
1372 {
1373   guint ssrc, fir, pli, nack;
1374   gint packets_lost;
1375   guint64 packets_received, bytes_received;
1376   double jitter;
1377   gchar *remote_id;
1378   GstStructure *remote;
1379
1380   validate_rtc_stream_stats (s, stats);
1381
1382   fail_unless (gst_structure_get (s, "ssrc", G_TYPE_UINT, &ssrc, NULL));
1383   fail_unless (gst_structure_get (s, "fir-count", G_TYPE_UINT, &fir, NULL));
1384   fail_unless (gst_structure_get (s, "pli-count", G_TYPE_UINT, &pli, NULL));
1385   fail_unless (gst_structure_get (s, "nack-count", G_TYPE_UINT, &nack, NULL));
1386   fail_unless (gst_structure_get (s, "packets-received", G_TYPE_UINT64,
1387           &packets_received, NULL));
1388   fail_unless (gst_structure_get (s, "bytes-received", G_TYPE_UINT64,
1389           &bytes_received, NULL));
1390   fail_unless (gst_structure_get (s, "jitter", G_TYPE_DOUBLE, &jitter, NULL));
1391   fail_unless (gst_structure_get (s, "packets-lost", G_TYPE_INT, &packets_lost,
1392           NULL));
1393   fail_unless (gst_structure_get (s, "remote-id", G_TYPE_STRING, &remote_id,
1394           NULL));
1395   fail_unless (gst_structure_get (stats, remote_id, GST_TYPE_STRUCTURE, &remote,
1396           NULL));
1397   fail_unless (remote != NULL);
1398
1399   gst_structure_free (remote);
1400   g_free (remote_id);
1401 }
1402
1403 static void
1404 validate_remote_inbound_rtp_stats (const GstStructure * s,
1405     const GstStructure * stats)
1406 {
1407   guint ssrc;
1408   gint packets_lost;
1409   double jitter, rtt;
1410   gchar *local_id;
1411   GstStructure *local;
1412
1413   validate_rtc_stream_stats (s, stats);
1414
1415   fail_unless (gst_structure_get (s, "ssrc", G_TYPE_UINT, &ssrc, NULL));
1416   fail_unless (gst_structure_get (s, "jitter", G_TYPE_DOUBLE, &jitter, NULL));
1417   fail_unless (gst_structure_get (s, "packets-lost", G_TYPE_INT, &packets_lost,
1418           NULL));
1419   fail_unless (gst_structure_get (s, "round-trip-time", G_TYPE_DOUBLE, &rtt,
1420           NULL));
1421   fail_unless (gst_structure_get (s, "local-id", G_TYPE_STRING, &local_id,
1422           NULL));
1423   fail_unless (gst_structure_get (stats, local_id, GST_TYPE_STRUCTURE, &local,
1424           NULL));
1425   fail_unless (local != NULL);
1426
1427   gst_structure_free (local);
1428   g_free (local_id);
1429 }
1430
1431 static void
1432 validate_outbound_rtp_stats (const GstStructure * s, const GstStructure * stats)
1433 {
1434   guint ssrc, fir, pli, nack;
1435   guint64 packets_sent, bytes_sent;
1436   gchar *remote_id;
1437   GstStructure *remote;
1438
1439   validate_rtc_stream_stats (s, stats);
1440
1441   fail_unless (gst_structure_get (s, "ssrc", G_TYPE_UINT, &ssrc, NULL));
1442   fail_unless (gst_structure_get (s, "fir-count", G_TYPE_UINT, &fir, NULL));
1443   fail_unless (gst_structure_get (s, "pli-count", G_TYPE_UINT, &pli, NULL));
1444   fail_unless (gst_structure_get (s, "nack-count", G_TYPE_UINT, &nack, NULL));
1445   fail_unless (gst_structure_get (s, "packets-sent", G_TYPE_UINT64,
1446           &packets_sent, NULL));
1447   fail_unless (gst_structure_get (s, "bytes-sent", G_TYPE_UINT64, &bytes_sent,
1448           NULL));
1449   fail_unless (gst_structure_get (s, "remote-id", G_TYPE_STRING, &remote_id,
1450           NULL));
1451   fail_unless (gst_structure_get (stats, remote_id, GST_TYPE_STRUCTURE, &remote,
1452           NULL));
1453   fail_unless (remote != NULL);
1454
1455   gst_structure_free (remote);
1456   g_free (remote_id);
1457 }
1458
1459 static void
1460 validate_remote_outbound_rtp_stats (const GstStructure * s,
1461     const GstStructure * stats)
1462 {
1463   guint ssrc;
1464   gchar *local_id;
1465   GstStructure *local;
1466
1467   validate_rtc_stream_stats (s, stats);
1468
1469   fail_unless (gst_structure_get (s, "ssrc", G_TYPE_UINT, &ssrc, NULL));
1470   fail_unless (gst_structure_get (s, "local-id", G_TYPE_STRING, &local_id,
1471           NULL));
1472   fail_unless (gst_structure_get (stats, local_id, GST_TYPE_STRUCTURE, &local,
1473           NULL));
1474   fail_unless (local != NULL);
1475
1476   gst_structure_free (local);
1477   g_free (local_id);
1478 }
1479
1480 static gboolean
1481 validate_stats_foreach (GQuark field_id, const GValue * value,
1482     const GstStructure * stats)
1483 {
1484   const gchar *field = g_quark_to_string (field_id);
1485   GstWebRTCStatsType type;
1486   const GstStructure *s;
1487
1488   fail_unless (GST_VALUE_HOLDS_STRUCTURE (value));
1489
1490   s = gst_value_get_structure (value);
1491
1492   GST_INFO ("validating field %s %" GST_PTR_FORMAT, field, s);
1493
1494   validate_rtc_stats (s);
1495   gst_structure_get (s, "type", GST_TYPE_WEBRTC_STATS_TYPE, &type, NULL);
1496   if (type == GST_WEBRTC_STATS_CODEC) {
1497     validate_codec_stats (s);
1498   } else if (type == GST_WEBRTC_STATS_INBOUND_RTP) {
1499     validate_inbound_rtp_stats (s, stats);
1500   } else if (type == GST_WEBRTC_STATS_OUTBOUND_RTP) {
1501     validate_outbound_rtp_stats (s, stats);
1502   } else if (type == GST_WEBRTC_STATS_REMOTE_INBOUND_RTP) {
1503     validate_remote_inbound_rtp_stats (s, stats);
1504   } else if (type == GST_WEBRTC_STATS_REMOTE_OUTBOUND_RTP) {
1505     validate_remote_outbound_rtp_stats (s, stats);
1506   } else if (type == GST_WEBRTC_STATS_CSRC) {
1507   } else if (type == GST_WEBRTC_STATS_PEER_CONNECTION) {
1508   } else if (type == GST_WEBRTC_STATS_DATA_CHANNEL) {
1509   } else if (type == GST_WEBRTC_STATS_STREAM) {
1510   } else if (type == GST_WEBRTC_STATS_TRANSPORT) {
1511   } else if (type == GST_WEBRTC_STATS_CANDIDATE_PAIR) {
1512   } else if (type == GST_WEBRTC_STATS_LOCAL_CANDIDATE) {
1513   } else if (type == GST_WEBRTC_STATS_REMOTE_CANDIDATE) {
1514   } else if (type == GST_WEBRTC_STATS_CERTIFICATE) {
1515   } else {
1516     g_assert_not_reached ();
1517   }
1518
1519   return TRUE;
1520 }
1521
1522 static void
1523 validate_stats (const GstStructure * stats)
1524 {
1525   gst_structure_foreach (stats,
1526       (GstStructureForeachFunc) validate_stats_foreach, (gpointer) stats);
1527 }
1528
1529 static void
1530 _on_stats (GstPromise * promise, gpointer user_data)
1531 {
1532   struct test_webrtc *t = user_data;
1533   const GstStructure *reply = gst_promise_get_reply (promise);
1534   int i;
1535
1536   validate_stats (reply);
1537   i = GPOINTER_TO_INT (t->user_data);
1538   i++;
1539   t->user_data = GINT_TO_POINTER (i);
1540   if (i >= 2)
1541     test_webrtc_signal_state (t, STATE_CUSTOM);
1542
1543   gst_promise_unref (promise);
1544 }
1545
1546 GST_START_TEST (test_session_stats)
1547 {
1548   struct test_webrtc *t = test_webrtc_new ();
1549   GstPromise *p;
1550
1551   /* test that the stats generated without any streams are sane */
1552   t->on_negotiation_needed = NULL;
1553   test_validate_sdp (t, NULL, NULL);
1554
1555   p = gst_promise_new_with_change_func (_on_stats, t, NULL);
1556   g_signal_emit_by_name (t->webrtc1, "get-stats", NULL, p);
1557   p = gst_promise_new_with_change_func (_on_stats, t, NULL);
1558   g_signal_emit_by_name (t->webrtc2, "get-stats", NULL, p);
1559
1560   test_webrtc_wait_for_state_mask (t, 1 << STATE_CUSTOM);
1561
1562   test_webrtc_free (t);
1563 }
1564
1565 GST_END_TEST;
1566
1567 GST_START_TEST (test_add_transceiver)
1568 {
1569   struct test_webrtc *t = test_webrtc_new ();
1570   GstWebRTCRTPTransceiverDirection direction;
1571   GstWebRTCRTPTransceiver *trans;
1572
1573   direction = GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_SENDRECV;
1574   g_signal_emit_by_name (t->webrtc1, "add-transceiver", direction, NULL,
1575       &trans);
1576   fail_unless (trans != NULL);
1577   fail_unless_equals_int (direction, trans->direction);
1578
1579   gst_object_unref (trans);
1580
1581   test_webrtc_free (t);
1582 }
1583
1584 GST_END_TEST;
1585
1586 GST_START_TEST (test_get_transceivers)
1587 {
1588   struct test_webrtc *t = create_audio_test ();
1589   GstWebRTCRTPTransceiver *trans;
1590   GArray *transceivers;
1591
1592   g_signal_emit_by_name (t->webrtc1, "get-transceivers", &transceivers);
1593   fail_unless (transceivers != NULL);
1594   fail_unless_equals_int (1, transceivers->len);
1595
1596   trans = g_array_index (transceivers, GstWebRTCRTPTransceiver *, 0);
1597   fail_unless (trans != NULL);
1598
1599   g_array_unref (transceivers);
1600
1601   test_webrtc_free (t);
1602 }
1603
1604 GST_END_TEST;
1605
1606 GST_START_TEST (test_add_recvonly_transceiver)
1607 {
1608   struct test_webrtc *t = test_webrtc_new ();
1609   GstWebRTCRTPTransceiverDirection direction;
1610   GstWebRTCRTPTransceiver *trans;
1611   VAL_SDP_INIT (no_duplicate_payloads, on_sdp_media_no_duplicate_payloads,
1612       NULL, NULL);
1613   guint media_format_count[] = { 1, 1, };
1614   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
1615       media_format_count, &no_duplicate_payloads);
1616   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (1),
1617       &media_formats);
1618   const gchar *expected_offer_setup[] = { "actpass", };
1619   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup, &count);
1620   const gchar *expected_answer_setup[] = { "active", };
1621   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
1622       &count);
1623   const gchar *expected_offer_direction[] = { "recvonly", };
1624   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
1625       &offer_setup);
1626   const gchar *expected_answer_direction[] = { "sendonly", };
1627   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
1628       &answer_setup);
1629   GstCaps *caps;
1630   GstHarness *h;
1631
1632   /* add a transceiver that will only receive an opus stream and check that
1633    * the created offer is marked as recvonly */
1634   t->on_negotiation_needed = NULL;
1635   t->on_ice_candidate = NULL;
1636   t->on_pad_added = _pad_added_fakesink;
1637
1638   /* setup recvonly transceiver */
1639   caps = gst_caps_from_string (OPUS_RTP_CAPS (96));
1640   direction = GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_RECVONLY;
1641   g_signal_emit_by_name (t->webrtc1, "add-transceiver", direction, caps,
1642       &trans);
1643   gst_caps_unref (caps);
1644   fail_unless (trans != NULL);
1645   gst_object_unref (trans);
1646
1647   /* setup sendonly peer */
1648   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
1649   add_fake_audio_src_harness (h, 96);
1650   t->harnesses = g_list_prepend (t->harnesses, h);
1651   test_validate_sdp (t, &offer, &answer);
1652
1653   test_webrtc_free (t);
1654 }
1655
1656 GST_END_TEST;
1657
1658 GST_START_TEST (test_recvonly_sendonly)
1659 {
1660   struct test_webrtc *t = test_webrtc_new ();
1661   GstWebRTCRTPTransceiverDirection direction;
1662   GstWebRTCRTPTransceiver *trans;
1663   VAL_SDP_INIT (no_duplicate_payloads, on_sdp_media_no_duplicate_payloads,
1664       NULL, NULL);
1665   guint media_format_count[] = { 1, 1, };
1666   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
1667       media_format_count, &no_duplicate_payloads);
1668   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
1669       &media_formats);
1670   const gchar *expected_offer_setup[] = { "actpass", "actpass" };
1671   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup, &count);
1672   const gchar *expected_answer_setup[] = { "active", "active" };
1673   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
1674       &count);
1675   const gchar *expected_offer_direction[] = { "recvonly", "sendonly" };
1676   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
1677       &offer_setup);
1678   const gchar *expected_answer_direction[] = { "sendonly", "recvonly" };
1679   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
1680       &answer_setup);
1681   GstCaps *caps;
1682   GstHarness *h;
1683   GArray *transceivers;
1684
1685   /* add a transceiver that will only receive an opus stream and check that
1686    * the created offer is marked as recvonly */
1687   t->on_negotiation_needed = NULL;
1688   t->on_ice_candidate = NULL;
1689   t->on_pad_added = _pad_added_fakesink;
1690
1691   /* setup recvonly transceiver */
1692   caps = gst_caps_from_string (OPUS_RTP_CAPS (96));
1693   direction = GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_RECVONLY;
1694   g_signal_emit_by_name (t->webrtc1, "add-transceiver", direction, caps,
1695       &trans);
1696   gst_caps_unref (caps);
1697   fail_unless (trans != NULL);
1698   gst_object_unref (trans);
1699
1700   /* setup sendonly stream */
1701   h = gst_harness_new_with_element (t->webrtc1, "sink_1", NULL);
1702   add_fake_audio_src_harness (h, 96);
1703   t->harnesses = g_list_prepend (t->harnesses, h);
1704   g_signal_emit_by_name (t->webrtc1, "get-transceivers", &transceivers);
1705   fail_unless (transceivers != NULL);
1706   fail_unless_equals_int (transceivers->len, 2);
1707   trans = g_array_index (transceivers, GstWebRTCRTPTransceiver *, 1);
1708   trans->direction = GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_SENDONLY;
1709
1710   g_array_unref (transceivers);
1711
1712   /* setup sendonly peer */
1713   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
1714   add_fake_audio_src_harness (h, 96);
1715   t->harnesses = g_list_prepend (t->harnesses, h);
1716
1717   test_validate_sdp (t, &offer, &answer);
1718
1719   test_webrtc_free (t);
1720 }
1721
1722 GST_END_TEST;
1723
1724 static void
1725 on_sdp_has_datachannel (struct test_webrtc *t, GstElement * element,
1726     GstWebRTCSessionDescription * desc, gpointer user_data)
1727 {
1728   gboolean have_data_channel = FALSE;
1729   int i;
1730
1731   for (i = 0; i < gst_sdp_message_medias_len (desc->sdp); i++) {
1732     if (_message_media_is_datachannel (desc->sdp, i)) {
1733       /* there should only be one data channel m= section */
1734       fail_unless_equals_int (FALSE, have_data_channel);
1735       have_data_channel = TRUE;
1736     }
1737   }
1738
1739   fail_unless_equals_int (TRUE, have_data_channel);
1740 }
1741
1742 static void
1743 on_channel_error_not_reached (GObject * channel, GError * error,
1744     gpointer user_data)
1745 {
1746   g_assert_not_reached ();
1747 }
1748
1749 GST_START_TEST (test_data_channel_create)
1750 {
1751   struct test_webrtc *t = test_webrtc_new ();
1752   GObject *channel = NULL;
1753   VAL_SDP_INIT (media_count, _count_num_sdp_media, GUINT_TO_POINTER (1), NULL);
1754   VAL_SDP_INIT (offer, on_sdp_has_datachannel, NULL, &media_count);
1755   gchar *label;
1756
1757   t->on_negotiation_needed = NULL;
1758   t->on_ice_candidate = NULL;
1759
1760   fail_if (gst_element_set_state (t->webrtc1,
1761           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
1762   fail_if (gst_element_set_state (t->webrtc2,
1763           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
1764
1765   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", NULL,
1766       &channel);
1767   g_assert_nonnull (channel);
1768   g_object_get (channel, "label", &label, NULL);
1769   g_assert_cmpstr (label, ==, "label");
1770   g_signal_connect (channel, "on-error",
1771       G_CALLBACK (on_channel_error_not_reached), NULL);
1772
1773   test_validate_sdp (t, &offer, &offer);
1774
1775   g_object_unref (channel);
1776   g_free (label);
1777   test_webrtc_free (t);
1778 }
1779
1780 GST_END_TEST;
1781
1782 static void
1783 have_data_channel (struct test_webrtc *t, GstElement * element,
1784     GObject * our, gpointer user_data)
1785 {
1786   GObject *other = user_data;
1787   gchar *our_label, *other_label;
1788
1789   g_signal_connect (our, "on-error", G_CALLBACK (on_channel_error_not_reached),
1790       NULL);
1791
1792   g_object_get (our, "label", &our_label, NULL);
1793   g_object_get (other, "label", &other_label, NULL);
1794
1795   g_assert_cmpstr (our_label, ==, other_label);
1796
1797   g_free (our_label);
1798   g_free (other_label);
1799
1800   test_webrtc_signal_state_unlocked (t, STATE_CUSTOM);
1801 }
1802
1803 GST_START_TEST (test_data_channel_remote_notify)
1804 {
1805   struct test_webrtc *t = test_webrtc_new ();
1806   GObject *channel = NULL;
1807   VAL_SDP_INIT (media_count, _count_num_sdp_media, GUINT_TO_POINTER (1), NULL);
1808   VAL_SDP_INIT (offer, on_sdp_has_datachannel, NULL, &media_count);
1809
1810   t->on_negotiation_needed = NULL;
1811   t->on_ice_candidate = NULL;
1812   t->on_data_channel = have_data_channel;
1813
1814   fail_if (gst_element_set_state (t->webrtc1,
1815           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
1816   fail_if (gst_element_set_state (t->webrtc2,
1817           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
1818
1819   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", NULL,
1820       &channel);
1821   g_assert_nonnull (channel);
1822   t->data_channel_data = channel;
1823   g_signal_connect (channel, "on-error",
1824       G_CALLBACK (on_channel_error_not_reached), NULL);
1825
1826   fail_if (gst_element_set_state (t->webrtc1,
1827           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
1828   fail_if (gst_element_set_state (t->webrtc2,
1829           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
1830
1831   test_validate_sdp_full (t, &offer, &offer, 1 << STATE_CUSTOM, FALSE);
1832
1833   g_object_unref (channel);
1834   test_webrtc_free (t);
1835 }
1836
1837 GST_END_TEST;
1838
1839 static const gchar *test_string = "GStreamer WebRTC is awesome!";
1840
1841 static void
1842 on_message_string (GObject * channel, const gchar * str, struct test_webrtc *t)
1843 {
1844   GstWebRTCDataChannelState state;
1845   gchar *expected;
1846
1847   g_object_get (channel, "ready-state", &state, NULL);
1848   fail_unless_equals_int (GST_WEBRTC_DATA_CHANNEL_STATE_OPEN, state);
1849
1850   expected = g_object_steal_data (channel, "expected");
1851   g_assert_cmpstr (expected, ==, str);
1852   g_free (expected);
1853
1854   test_webrtc_signal_state (t, STATE_CUSTOM);
1855 }
1856
1857 static void
1858 have_data_channel_transfer_string (struct test_webrtc *t, GstElement * element,
1859     GObject * our, gpointer user_data)
1860 {
1861   GObject *other = user_data;
1862   GstWebRTCDataChannelState state;
1863
1864   g_object_get (our, "ready-state", &state, NULL);
1865   fail_unless_equals_int (GST_WEBRTC_DATA_CHANNEL_STATE_OPEN, state);
1866
1867   g_object_set_data_full (our, "expected", g_strdup (test_string), g_free);
1868   g_signal_connect (our, "on-message-string", G_CALLBACK (on_message_string),
1869       t);
1870
1871   g_signal_connect (other, "on-error",
1872       G_CALLBACK (on_channel_error_not_reached), NULL);
1873   g_signal_emit_by_name (other, "send-string", test_string);
1874 }
1875
1876 GST_START_TEST (test_data_channel_transfer_string)
1877 {
1878   struct test_webrtc *t = test_webrtc_new ();
1879   GObject *channel = NULL;
1880   VAL_SDP_INIT (media_count, _count_num_sdp_media, GUINT_TO_POINTER (1), NULL);
1881   VAL_SDP_INIT (offer, on_sdp_has_datachannel, NULL, &media_count);
1882
1883   t->on_negotiation_needed = NULL;
1884   t->on_ice_candidate = NULL;
1885   t->on_data_channel = have_data_channel_transfer_string;
1886
1887   fail_if (gst_element_set_state (t->webrtc1,
1888           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
1889   fail_if (gst_element_set_state (t->webrtc2,
1890           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
1891
1892   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", NULL,
1893       &channel);
1894   g_assert_nonnull (channel);
1895   t->data_channel_data = channel;
1896   g_signal_connect (channel, "on-error",
1897       G_CALLBACK (on_channel_error_not_reached), NULL);
1898
1899   fail_if (gst_element_set_state (t->webrtc1,
1900           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
1901   fail_if (gst_element_set_state (t->webrtc2,
1902           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
1903
1904   test_validate_sdp_full (t, &offer, &offer, 1 << STATE_CUSTOM, FALSE);
1905
1906   g_object_unref (channel);
1907   test_webrtc_free (t);
1908 }
1909
1910 GST_END_TEST;
1911
1912 #define g_assert_cmpbytes(b1, b2)                       \
1913     G_STMT_START {                                      \
1914       gsize l1, l2;                                     \
1915       const guint8 *d1 = g_bytes_get_data (b1, &l1);    \
1916       const guint8 *d2 = g_bytes_get_data (b2, &l2);    \
1917       g_assert_cmpmem (d1, l1, d2, l2);                 \
1918     } G_STMT_END;
1919
1920 static void
1921 on_message_data (GObject * channel, GBytes * data, struct test_webrtc *t)
1922 {
1923   GstWebRTCDataChannelState state;
1924   GBytes *expected;
1925
1926   g_object_get (channel, "ready-state", &state, NULL);
1927   fail_unless_equals_int (GST_WEBRTC_DATA_CHANNEL_STATE_OPEN, state);
1928
1929   expected = g_object_steal_data (channel, "expected");
1930   g_assert_cmpbytes (data, expected);
1931   g_bytes_unref (expected);
1932
1933   test_webrtc_signal_state (t, STATE_CUSTOM);
1934 }
1935
1936 static void
1937 have_data_channel_transfer_data (struct test_webrtc *t, GstElement * element,
1938     GObject * our, gpointer user_data)
1939 {
1940   GObject *other = user_data;
1941   GBytes *data = g_bytes_new_static (test_string, strlen (test_string));
1942   GstWebRTCDataChannelState state;
1943
1944   g_object_get (our, "ready-state", &state, NULL);
1945   fail_unless_equals_int (GST_WEBRTC_DATA_CHANNEL_STATE_OPEN, state);
1946
1947   g_object_set_data_full (our, "expected", g_bytes_ref (data),
1948       (GDestroyNotify) g_bytes_unref);
1949   g_signal_connect (our, "on-message-data", G_CALLBACK (on_message_data), t);
1950
1951   g_signal_connect (other, "on-error",
1952       G_CALLBACK (on_channel_error_not_reached), NULL);
1953   g_signal_emit_by_name (other, "send-data", data);
1954   g_bytes_unref (data);
1955 }
1956
1957 GST_START_TEST (test_data_channel_transfer_data)
1958 {
1959   struct test_webrtc *t = test_webrtc_new ();
1960   GObject *channel = NULL;
1961   VAL_SDP_INIT (media_count, _count_num_sdp_media, GUINT_TO_POINTER (1), NULL);
1962   VAL_SDP_INIT (offer, on_sdp_has_datachannel, NULL, &media_count);
1963
1964   t->on_negotiation_needed = NULL;
1965   t->on_ice_candidate = NULL;
1966   t->on_data_channel = have_data_channel_transfer_data;
1967
1968   fail_if (gst_element_set_state (t->webrtc1,
1969           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
1970   fail_if (gst_element_set_state (t->webrtc2,
1971           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
1972
1973   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", NULL,
1974       &channel);
1975   g_assert_nonnull (channel);
1976   t->data_channel_data = channel;
1977   g_signal_connect (channel, "on-error",
1978       G_CALLBACK (on_channel_error_not_reached), NULL);
1979
1980   fail_if (gst_element_set_state (t->webrtc1,
1981           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
1982   fail_if (gst_element_set_state (t->webrtc2,
1983           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
1984
1985   test_validate_sdp_full (t, &offer, &offer, 1 << STATE_CUSTOM, FALSE);
1986
1987   g_object_unref (channel);
1988   test_webrtc_free (t);
1989 }
1990
1991 GST_END_TEST;
1992
1993 static void
1994 have_data_channel_create_data_channel (struct test_webrtc *t,
1995     GstElement * element, GObject * our, gpointer user_data)
1996 {
1997   GObject *another;
1998
1999   t->on_data_channel = have_data_channel_transfer_string;
2000
2001   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", NULL,
2002       &another);
2003   g_assert_nonnull (another);
2004   t->data_channel_data = another;
2005   t->data_channel_notify = (GDestroyNotify) g_object_unref;
2006   g_signal_connect (another, "on-error",
2007       G_CALLBACK (on_channel_error_not_reached), NULL);
2008 }
2009
2010 GST_START_TEST (test_data_channel_create_after_negotiate)
2011 {
2012   struct test_webrtc *t = test_webrtc_new ();
2013   GObject *channel = NULL;
2014   VAL_SDP_INIT (media_count, _count_num_sdp_media, GUINT_TO_POINTER (1), NULL);
2015   VAL_SDP_INIT (offer, on_sdp_has_datachannel, NULL, &media_count);
2016
2017   t->on_negotiation_needed = NULL;
2018   t->on_ice_candidate = NULL;
2019   t->on_data_channel = have_data_channel_create_data_channel;
2020
2021   fail_if (gst_element_set_state (t->webrtc1,
2022           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
2023   fail_if (gst_element_set_state (t->webrtc2,
2024           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
2025
2026   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "prev-label", NULL,
2027       &channel);
2028   g_assert_nonnull (channel);
2029   t->data_channel_data = channel;
2030   g_signal_connect (channel, "on-error",
2031       G_CALLBACK (on_channel_error_not_reached), NULL);
2032
2033   fail_if (gst_element_set_state (t->webrtc1,
2034           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2035   fail_if (gst_element_set_state (t->webrtc2,
2036           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2037
2038   test_validate_sdp_full (t, &offer, &offer, 1 << STATE_CUSTOM, FALSE);
2039
2040   g_object_unref (channel);
2041   test_webrtc_free (t);
2042 }
2043
2044 GST_END_TEST;
2045
2046 static void
2047 on_buffered_amount_low_emitted (GObject * channel, struct test_webrtc *t)
2048 {
2049   test_webrtc_signal_state (t, STATE_CUSTOM);
2050 }
2051
2052 static void
2053 have_data_channel_check_low_threshold_emitted (struct test_webrtc *t,
2054     GstElement * element, GObject * our, gpointer user_data)
2055 {
2056   g_signal_connect (our, "on-buffered-amount-low",
2057       G_CALLBACK (on_buffered_amount_low_emitted), t);
2058   g_object_set (our, "buffered-amount-low-threshold", 1, NULL);
2059
2060   g_signal_connect (our, "on-error", G_CALLBACK (on_channel_error_not_reached),
2061       NULL);
2062   g_signal_emit_by_name (our, "send-string", "A");
2063 }
2064
2065 GST_START_TEST (test_data_channel_low_threshold)
2066 {
2067   struct test_webrtc *t = test_webrtc_new ();
2068   GObject *channel = NULL;
2069   VAL_SDP_INIT (media_count, _count_num_sdp_media, GUINT_TO_POINTER (1), NULL);
2070   VAL_SDP_INIT (offer, on_sdp_has_datachannel, NULL, &media_count);
2071
2072   t->on_negotiation_needed = NULL;
2073   t->on_ice_candidate = NULL;
2074   t->on_data_channel = have_data_channel_check_low_threshold_emitted;
2075
2076   fail_if (gst_element_set_state (t->webrtc1,
2077           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
2078   fail_if (gst_element_set_state (t->webrtc2,
2079           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
2080
2081   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", NULL,
2082       &channel);
2083   g_assert_nonnull (channel);
2084   t->data_channel_data = channel;
2085   g_signal_connect (channel, "on-error",
2086       G_CALLBACK (on_channel_error_not_reached), NULL);
2087
2088   fail_if (gst_element_set_state (t->webrtc1,
2089           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2090   fail_if (gst_element_set_state (t->webrtc2,
2091           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2092
2093   test_validate_sdp_full (t, &offer, &offer, 1 << STATE_CUSTOM, FALSE);
2094
2095   g_object_unref (channel);
2096   test_webrtc_free (t);
2097 }
2098
2099 GST_END_TEST;
2100
2101 static void
2102 on_channel_error (GObject * channel, GError * error, struct test_webrtc *t)
2103 {
2104   g_assert_nonnull (error);
2105
2106   test_webrtc_signal_state (t, STATE_CUSTOM);
2107 }
2108
2109 static void
2110 have_data_channel_transfer_large_data (struct test_webrtc *t,
2111     GstElement * element, GObject * our, gpointer user_data)
2112 {
2113   GObject *other = user_data;
2114   const gsize size = 1024 * 1024;
2115   guint8 *random_data = g_new (guint8, size);
2116   GBytes *data;
2117   gsize i;
2118
2119   for (i = 0; i < size; i++)
2120     random_data[i] = (guint8) (i & 0xff);
2121
2122   data = g_bytes_new_with_free_func (random_data, size,
2123       (GDestroyNotify) g_free, random_data);
2124
2125   g_object_set_data_full (our, "expected", g_bytes_ref (data),
2126       (GDestroyNotify) g_bytes_unref);
2127   g_signal_connect (our, "on-message-data", G_CALLBACK (on_message_data), t);
2128
2129   g_signal_connect (other, "on-error", G_CALLBACK (on_channel_error), t);
2130   g_signal_emit_by_name (other, "send-data", data);
2131   g_bytes_unref (data);
2132 }
2133
2134 GST_START_TEST (test_data_channel_max_message_size)
2135 {
2136   struct test_webrtc *t = test_webrtc_new ();
2137   GObject *channel = NULL;
2138   VAL_SDP_INIT (media_count, _count_num_sdp_media, GUINT_TO_POINTER (1), NULL);
2139   VAL_SDP_INIT (offer, on_sdp_has_datachannel, NULL, &media_count);
2140
2141   t->on_negotiation_needed = NULL;
2142   t->on_ice_candidate = NULL;
2143   t->on_data_channel = have_data_channel_transfer_large_data;
2144
2145   fail_if (gst_element_set_state (t->webrtc1,
2146           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
2147   fail_if (gst_element_set_state (t->webrtc2,
2148           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
2149
2150   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", NULL,
2151       &channel);
2152   g_assert_nonnull (channel);
2153   t->data_channel_data = channel;
2154
2155   fail_if (gst_element_set_state (t->webrtc1,
2156           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2157   fail_if (gst_element_set_state (t->webrtc2,
2158           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2159
2160   test_validate_sdp_full (t, &offer, &offer, 1 << STATE_CUSTOM, FALSE);
2161
2162   g_object_unref (channel);
2163   test_webrtc_free (t);
2164 }
2165
2166 GST_END_TEST;
2167
2168 static void
2169 _on_ready_state_notify (GObject * channel, GParamSpec * pspec,
2170     struct test_webrtc *t)
2171 {
2172   gint *n_ready = t->data_channel_data;
2173   GstWebRTCDataChannelState ready_state;
2174
2175   g_object_get (channel, "ready-state", &ready_state, NULL);
2176
2177   if (ready_state == GST_WEBRTC_DATA_CHANNEL_STATE_OPEN) {
2178     if (g_atomic_int_add (n_ready, 1) >= 1) {
2179       test_webrtc_signal_state (t, STATE_CUSTOM);
2180     }
2181   }
2182 }
2183
2184 GST_START_TEST (test_data_channel_pre_negotiated)
2185 {
2186   struct test_webrtc *t = test_webrtc_new ();
2187   GObject *channel1 = NULL, *channel2 = NULL;
2188   VAL_SDP_INIT (media_count, _count_num_sdp_media, GUINT_TO_POINTER (1), NULL);
2189   VAL_SDP_INIT (offer, on_sdp_has_datachannel, NULL, &media_count);
2190   GstStructure *s;
2191   gint n_ready = 0;
2192
2193   t->on_negotiation_needed = NULL;
2194   t->on_ice_candidate = NULL;
2195
2196   fail_if (gst_element_set_state (t->webrtc1,
2197           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
2198   fail_if (gst_element_set_state (t->webrtc2,
2199           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
2200
2201   s = gst_structure_new ("application/data-channel", "negotiated",
2202       G_TYPE_BOOLEAN, TRUE, "id", G_TYPE_INT, 1, NULL);
2203
2204   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", s,
2205       &channel1);
2206   g_assert_nonnull (channel1);
2207   g_signal_emit_by_name (t->webrtc2, "create-data-channel", "label", s,
2208       &channel2);
2209   g_assert_nonnull (channel2);
2210
2211   fail_if (gst_element_set_state (t->webrtc1,
2212           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2213   fail_if (gst_element_set_state (t->webrtc2,
2214           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2215
2216   test_validate_sdp_full (t, &offer, &offer, 0, FALSE);
2217
2218   t->data_channel_data = &n_ready;
2219
2220   g_signal_connect (channel1, "notify::ready-state",
2221       G_CALLBACK (_on_ready_state_notify), t);
2222   g_signal_connect (channel2, "notify::ready-state",
2223       G_CALLBACK (_on_ready_state_notify), t);
2224
2225   test_webrtc_wait_for_state_mask (t, 1 << STATE_CUSTOM);
2226   test_webrtc_signal_state (t, STATE_NEW);
2227
2228   have_data_channel_transfer_string (t, t->webrtc1, channel1, channel2);
2229
2230   test_webrtc_wait_for_state_mask (t, 1 << STATE_CUSTOM);
2231
2232   g_object_unref (channel1);
2233   g_object_unref (channel2);
2234   gst_structure_free (s);
2235   test_webrtc_free (t);
2236 }
2237
2238 GST_END_TEST;
2239
2240 static void
2241 _count_non_rejected_media (struct test_webrtc *t, GstElement * element,
2242     GstWebRTCSessionDescription * sd, gpointer user_data)
2243 {
2244   guint expected = GPOINTER_TO_UINT (user_data);
2245   guint non_rejected_media;
2246   guint i;
2247
2248   non_rejected_media = 0;
2249
2250   for (i = 0; i < gst_sdp_message_medias_len (sd->sdp); i++) {
2251     const GstSDPMedia *media = gst_sdp_message_get_media (sd->sdp, i);
2252
2253     if (gst_sdp_media_get_port (media) != 0)
2254       non_rejected_media += 1;
2255   }
2256
2257   fail_unless_equals_int (non_rejected_media, expected);
2258 }
2259
2260 static void
2261 _check_bundle_tag (struct test_webrtc *t, GstElement * element,
2262     GstWebRTCSessionDescription * sd, gpointer user_data)
2263 {
2264   gchar **bundled = NULL;
2265   GStrv expected = user_data;
2266   guint i;
2267
2268   fail_unless (_parse_bundle (sd->sdp, &bundled, NULL));
2269
2270   if (!bundled) {
2271     fail_unless_equals_int (g_strv_length (expected), 0);
2272   } else {
2273     fail_unless_equals_int (g_strv_length (bundled), g_strv_length (expected));
2274   }
2275
2276   for (i = 0; i < g_strv_length (expected); i++) {
2277     fail_unless (g_strv_contains ((const gchar **) bundled, expected[i]));
2278   }
2279
2280   g_strfreev (bundled);
2281 }
2282
2283 static void
2284 _check_bundle_only_media (struct test_webrtc *t, GstElement * element,
2285     GstWebRTCSessionDescription * sd, gpointer user_data)
2286 {
2287   gchar **expected_bundle_only = user_data;
2288   guint i;
2289
2290   for (i = 0; i < gst_sdp_message_medias_len (sd->sdp); i++) {
2291     const GstSDPMedia *media = gst_sdp_message_get_media (sd->sdp, i);
2292     const gchar *mid = gst_sdp_media_get_attribute_val (media, "mid");
2293
2294     if (g_strv_contains ((const gchar **) expected_bundle_only, mid))
2295       fail_unless (_media_has_attribute_key (media, "bundle-only"));
2296   }
2297 }
2298
2299 GST_START_TEST (test_bundle_audio_video_max_bundle_max_bundle)
2300 {
2301   struct test_webrtc *t = create_audio_video_test ();
2302   const gchar *bundle[] = { "audio0", "video1", NULL };
2303   const gchar *offer_bundle_only[] = { "video1", NULL };
2304   const gchar *answer_bundle_only[] = { NULL };
2305
2306   guint media_format_count[] = { 1, 1, };
2307   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
2308       media_format_count, NULL);
2309   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
2310       &media_formats);
2311   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
2312   VAL_SDP_INIT (bundle_tag, _check_bundle_tag, bundle, &payloads);
2313   VAL_SDP_INIT (offer_non_reject, _count_non_rejected_media,
2314       GUINT_TO_POINTER (1), &bundle_tag);
2315   VAL_SDP_INIT (answer_non_reject, _count_non_rejected_media,
2316       GUINT_TO_POINTER (2), &bundle_tag);
2317   VAL_SDP_INIT (offer_bundle, _check_bundle_only_media, &offer_bundle_only,
2318       &offer_non_reject);
2319   VAL_SDP_INIT (answer_bundle, _check_bundle_only_media, &answer_bundle_only,
2320       &answer_non_reject);
2321   const gchar *expected_offer_setup[] = { "actpass", "actpass" };
2322   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
2323       &offer_bundle);
2324   const gchar *expected_answer_setup[] = { "active", "active" };
2325   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
2326       &answer_bundle);
2327   const gchar *expected_offer_direction[] = { "sendrecv", "sendrecv" };
2328   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
2329       &offer_setup);
2330   const gchar *expected_answer_direction[] = { "recvonly", "recvonly" };
2331   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
2332       &answer_setup);
2333
2334   /* We set a max-bundle policy on the offering webrtcbin,
2335    * this means that all the offered medias should be part
2336    * of the group:BUNDLE attribute, and they should be marked
2337    * as bundle-only
2338    */
2339   gst_util_set_object_arg (G_OBJECT (t->webrtc1), "bundle-policy",
2340       "max-bundle");
2341   /* We also set a max-bundle policy on the answering webrtcbin,
2342    * this means that all the offered medias should be part
2343    * of the group:BUNDLE attribute, but need not be marked
2344    * as bundle-only.
2345    */
2346   gst_util_set_object_arg (G_OBJECT (t->webrtc2), "bundle-policy",
2347       "max-bundle");
2348
2349   test_validate_sdp (t, &offer, &answer);
2350
2351   test_webrtc_free (t);
2352 }
2353
2354 GST_END_TEST;
2355
2356 GST_START_TEST (test_bundle_audio_video_max_compat_max_bundle)
2357 {
2358   struct test_webrtc *t = create_audio_video_test ();
2359   const gchar *bundle[] = { "audio0", "video1", NULL };
2360   const gchar *bundle_only[] = { NULL };
2361
2362   guint media_format_count[] = { 1, 1, };
2363   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
2364       media_format_count, NULL);
2365   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
2366       &media_formats);
2367   VAL_SDP_INIT (bundle_tag, _check_bundle_tag, bundle, &count);
2368   VAL_SDP_INIT (count_non_reject, _count_non_rejected_media,
2369       GUINT_TO_POINTER (2), &bundle_tag);
2370   VAL_SDP_INIT (bundle_sdp, _check_bundle_only_media, &bundle_only,
2371       &count_non_reject);
2372   const gchar *expected_offer_setup[] = { "actpass", "actpass" };
2373   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
2374       &bundle_sdp);
2375   const gchar *expected_answer_setup[] = { "active", "active" };
2376   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
2377       &bundle_sdp);
2378   const gchar *expected_offer_direction[] = { "sendrecv", "sendrecv" };
2379   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
2380       &offer_setup);
2381   const gchar *expected_answer_direction[] = { "recvonly", "recvonly" };
2382   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
2383       &answer_setup);
2384
2385   /* We set a max-compat policy on the offering webrtcbin,
2386    * this means that all the offered medias should be part
2387    * of the group:BUNDLE attribute, and they should *not* be marked
2388    * as bundle-only
2389    */
2390   gst_util_set_object_arg (G_OBJECT (t->webrtc1), "bundle-policy",
2391       "max-compat");
2392   /* We set a max-bundle policy on the answering webrtcbin,
2393    * this means that all the offered medias should be part
2394    * of the group:BUNDLE attribute, but need not be marked
2395    * as bundle-only.
2396    */
2397   gst_util_set_object_arg (G_OBJECT (t->webrtc2), "bundle-policy",
2398       "max-bundle");
2399
2400   test_validate_sdp (t, &offer, &answer);
2401
2402   test_webrtc_free (t);
2403 }
2404
2405 GST_END_TEST;
2406
2407 GST_START_TEST (test_bundle_audio_video_max_bundle_none)
2408 {
2409   struct test_webrtc *t = create_audio_video_test ();
2410   const gchar *offer_mid[] = { "audio0", "video1", NULL };
2411   const gchar *offer_bundle_only[] = { "video1", NULL };
2412   const gchar *answer_mid[] = { NULL };
2413   const gchar *answer_bundle_only[] = { NULL };
2414
2415   guint media_format_count[] = { 1, 1, };
2416   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
2417       media_format_count, NULL);
2418   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
2419       &media_formats);
2420   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
2421   VAL_SDP_INIT (count_non_reject, _count_non_rejected_media,
2422       GUINT_TO_POINTER (1), &payloads);
2423   VAL_SDP_INIT (offer_bundle_tag, _check_bundle_tag, offer_mid,
2424       &count_non_reject);
2425   VAL_SDP_INIT (answer_bundle_tag, _check_bundle_tag, answer_mid,
2426       &count_non_reject);
2427   VAL_SDP_INIT (offer_bundle, _check_bundle_only_media, &offer_bundle_only,
2428       &offer_bundle_tag);
2429   VAL_SDP_INIT (answer_bundle, _check_bundle_only_media, &answer_bundle_only,
2430       &answer_bundle_tag);
2431   const gchar *expected_offer_setup[] = { "actpass", "actpass" };
2432   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
2433       &offer_bundle);
2434   const gchar *expected_answer_setup[] = { "active", "active" };
2435   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
2436       &answer_bundle);
2437   const gchar *expected_offer_direction[] = { "sendrecv", "sendrecv" };
2438   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
2439       &offer_setup);
2440   const gchar *expected_answer_direction[] = { "recvonly", "recvonly" };
2441   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
2442       &answer_setup);
2443
2444   /* We set a max-bundle policy on the offering webrtcbin,
2445    * this means that all the offered medias should be part
2446    * of the group:BUNDLE attribute, and they should be marked
2447    * as bundle-only
2448    */
2449   gst_util_set_object_arg (G_OBJECT (t->webrtc1), "bundle-policy",
2450       "max-bundle");
2451   /* We set a none policy on the answering webrtcbin,
2452    * this means that the answer should contain no bundled
2453    * medias, and as the bundle-policy of the offering webrtcbin
2454    * is set to max-bundle, only one media should be active.
2455    */
2456   gst_util_set_object_arg (G_OBJECT (t->webrtc2), "bundle-policy", "none");
2457
2458   test_validate_sdp (t, &offer, &answer);
2459
2460   test_webrtc_free (t);
2461 }
2462
2463 GST_END_TEST;
2464
2465 GST_START_TEST (test_bundle_audio_video_data)
2466 {
2467   struct test_webrtc *t = create_audio_video_test ();
2468   const gchar *mids[] = { "audio0", "video1", "application2", NULL };
2469   const gchar *offer_bundle_only[] = { "video1", "application2", NULL };
2470   const gchar *answer_bundle_only[] = { NULL };
2471   GObject *channel = NULL;
2472
2473   guint media_format_count[] = { 1, 1, 1 };
2474   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
2475       media_format_count, NULL);
2476   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (3),
2477       &media_formats);
2478   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
2479   VAL_SDP_INIT (bundle_tag, _check_bundle_tag, mids, &payloads);
2480   VAL_SDP_INIT (offer_non_reject, _count_non_rejected_media,
2481       GUINT_TO_POINTER (1), &bundle_tag);
2482   VAL_SDP_INIT (answer_non_reject, _count_non_rejected_media,
2483       GUINT_TO_POINTER (3), &bundle_tag);
2484   VAL_SDP_INIT (offer_bundle, _check_bundle_only_media, &offer_bundle_only,
2485       &offer_non_reject);
2486   VAL_SDP_INIT (answer_bundle, _check_bundle_only_media, &answer_bundle_only,
2487       &answer_non_reject);
2488   const gchar *expected_offer_setup[] = { "actpass", "actpass", "actpass" };
2489   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
2490       &offer_bundle);
2491   const gchar *expected_answer_setup[] = { "active", "active", "active" };
2492   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
2493       &answer_bundle);
2494   const gchar *expected_offer_direction[] =
2495       { "sendrecv", "sendrecv", "sendrecv" };
2496   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
2497       &offer_setup);
2498   const gchar *expected_answer_direction[] =
2499       { "recvonly", "recvonly", "recvonly" };
2500   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
2501       &answer_setup);
2502
2503   /* We set a max-bundle policy on the offering webrtcbin,
2504    * this means that all the offered medias should be part
2505    * of the group:BUNDLE attribute, and they should be marked
2506    * as bundle-only
2507    */
2508   gst_util_set_object_arg (G_OBJECT (t->webrtc1), "bundle-policy",
2509       "max-bundle");
2510   /* We also set a max-bundle policy on the answering webrtcbin,
2511    * this means that all the offered medias should be part
2512    * of the group:BUNDLE attribute, but need not be marked
2513    * as bundle-only.
2514    */
2515   gst_util_set_object_arg (G_OBJECT (t->webrtc2), "bundle-policy",
2516       "max-bundle");
2517
2518   fail_if (gst_element_set_state (t->webrtc1,
2519           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
2520   fail_if (gst_element_set_state (t->webrtc2,
2521           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
2522
2523   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", NULL,
2524       &channel);
2525
2526   test_validate_sdp (t, &offer, &answer);
2527
2528   g_object_unref (channel);
2529   test_webrtc_free (t);
2530 }
2531
2532 GST_END_TEST;
2533
2534 GST_START_TEST (test_duplicate_nego)
2535 {
2536   struct test_webrtc *t = create_audio_video_test ();
2537   guint media_format_count[] = { 1, 1, };
2538   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
2539       media_format_count, NULL);
2540   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
2541       &media_formats);
2542   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
2543   const gchar *expected_offer_setup[] = { "actpass", "actpass" };
2544   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
2545       &payloads);
2546   const gchar *expected_answer_setup[] = { "active", "active" };
2547   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
2548       &payloads);
2549   const gchar *expected_offer_direction[] = { "sendrecv", "sendrecv" };
2550   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
2551       &offer_setup);
2552   const gchar *expected_answer_direction[] = { "sendrecv", "recvonly" };
2553   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
2554       &answer_setup);
2555   GstHarness *h;
2556   guint negotiation_flag = 0;
2557
2558   /* check that negotiating twice succeeds */
2559
2560   t->on_negotiation_needed = on_negotiation_needed_hit;
2561   t->negotiation_data = &negotiation_flag;
2562
2563   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
2564   add_fake_audio_src_harness (h, 96);
2565   t->harnesses = g_list_prepend (t->harnesses, h);
2566
2567   test_validate_sdp (t, &offer, &answer);
2568   fail_unless (negotiation_flag & (1 << 2));
2569
2570   test_webrtc_reset_negotiation (t);
2571   test_validate_sdp (t, &offer, &answer);
2572
2573   test_webrtc_free (t);
2574 }
2575
2576 GST_END_TEST;
2577
2578 GST_START_TEST (test_dual_audio)
2579 {
2580   struct test_webrtc *t = create_audio_test ();
2581   guint media_format_count[] = { 1, 1, };
2582   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
2583       media_format_count, NULL);
2584   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
2585       &media_formats);
2586   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
2587   const gchar *expected_offer_setup[] = { "actpass", "actpass" };
2588   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
2589       &payloads);
2590   const gchar *expected_answer_setup[] = { "active", "active" };
2591   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
2592       &payloads);
2593   const gchar *expected_offer_direction[] = { "sendrecv", "sendrecv" };
2594   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
2595       &offer_setup);
2596   const gchar *expected_answer_direction[] = { "sendrecv", "recvonly" };
2597   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
2598       &answer_setup);
2599   GstHarness *h;
2600   GstWebRTCRTPTransceiver *trans;
2601   GArray *transceivers;
2602
2603   /* test that each mline gets a unique transceiver even with the same caps */
2604
2605   h = gst_harness_new_with_element (t->webrtc1, "sink_1", NULL);
2606   add_fake_audio_src_harness (h, 96);
2607   t->harnesses = g_list_prepend (t->harnesses, h);
2608
2609   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
2610   add_fake_audio_src_harness (h, 96);
2611   t->harnesses = g_list_prepend (t->harnesses, h);
2612
2613   t->on_negotiation_needed = NULL;
2614   test_validate_sdp (t, &offer, &answer);
2615
2616   g_signal_emit_by_name (t->webrtc1, "get-transceivers", &transceivers);
2617   fail_unless (transceivers != NULL);
2618   fail_unless_equals_int (2, transceivers->len);
2619
2620   trans = g_array_index (transceivers, GstWebRTCRTPTransceiver *, 0);
2621   fail_unless (trans != NULL);
2622   fail_unless_equals_int (trans->mline, 0);
2623
2624   trans = g_array_index (transceivers, GstWebRTCRTPTransceiver *, 1);
2625   fail_unless (trans != NULL);
2626   fail_unless_equals_int (trans->mline, 1);
2627
2628   g_array_unref (transceivers);
2629   test_webrtc_free (t);
2630 }
2631
2632 GST_END_TEST;
2633
2634 static void
2635 sdp_increasing_session_version (struct test_webrtc *t, GstElement * element,
2636     GstWebRTCSessionDescription * desc, gpointer user_data)
2637 {
2638   GstWebRTCSessionDescription *previous;
2639   const GstSDPOrigin *our_origin, *previous_origin;
2640   const gchar *prop;
2641   guint64 our_v, previous_v;
2642
2643   prop =
2644       TEST_SDP_IS_LOCAL (t, element,
2645       desc) ? "current-local-description" : "current-remote-description";
2646   g_object_get (element, prop, &previous, NULL);
2647
2648   our_origin = gst_sdp_message_get_origin (desc->sdp);
2649   previous_origin = gst_sdp_message_get_origin (previous->sdp);
2650
2651   our_v = g_ascii_strtoull (our_origin->sess_version, NULL, 10);
2652   previous_v = g_ascii_strtoull (previous_origin->sess_version, NULL, 10);
2653
2654   ck_assert_int_lt (previous_v, our_v);
2655
2656   gst_webrtc_session_description_free (previous);
2657 }
2658
2659 static void
2660 sdp_equal_session_id (struct test_webrtc *t, GstElement * element,
2661     GstWebRTCSessionDescription * desc, gpointer user_data)
2662 {
2663   GstWebRTCSessionDescription *previous;
2664   const GstSDPOrigin *our_origin, *previous_origin;
2665   const gchar *prop;
2666
2667   prop =
2668       TEST_SDP_IS_LOCAL (t, element,
2669       desc) ? "current-local-description" : "current-remote-description";
2670   g_object_get (element, prop, &previous, NULL);
2671
2672   our_origin = gst_sdp_message_get_origin (desc->sdp);
2673   previous_origin = gst_sdp_message_get_origin (previous->sdp);
2674
2675   fail_unless_equals_string (previous_origin->sess_id, our_origin->sess_id);
2676   gst_webrtc_session_description_free (previous);
2677 }
2678
2679 static void
2680 sdp_media_equal_attribute (struct test_webrtc *t, GstElement * element,
2681     GstWebRTCSessionDescription * desc, GstWebRTCSessionDescription * previous,
2682     const gchar * attr)
2683 {
2684   guint i, n;
2685
2686   n = MIN (gst_sdp_message_medias_len (previous->sdp),
2687       gst_sdp_message_medias_len (desc->sdp));
2688
2689   for (i = 0; i < n; i++) {
2690     const GstSDPMedia *our_media, *other_media;
2691     const gchar *our_mid, *other_mid;
2692
2693     our_media = gst_sdp_message_get_media (desc->sdp, i);
2694     other_media = gst_sdp_message_get_media (previous->sdp, i);
2695
2696     our_mid = gst_sdp_media_get_attribute_val (our_media, attr);
2697     other_mid = gst_sdp_media_get_attribute_val (other_media, attr);
2698
2699     fail_unless_equals_string (our_mid, other_mid);
2700   }
2701 }
2702
2703 static void
2704 sdp_media_equal_mid (struct test_webrtc *t, GstElement * element,
2705     GstWebRTCSessionDescription * desc, gpointer user_data)
2706 {
2707   GstWebRTCSessionDescription *previous;
2708   const gchar *prop;
2709
2710   prop =
2711       TEST_SDP_IS_LOCAL (t, element,
2712       desc) ? "current-local-description" : "current-remote-description";
2713   g_object_get (element, prop, &previous, NULL);
2714
2715   sdp_media_equal_attribute (t, element, desc, previous, "mid");
2716
2717   gst_webrtc_session_description_free (previous);
2718 }
2719
2720 static void
2721 sdp_media_equal_ice_params (struct test_webrtc *t, GstElement * element,
2722     GstWebRTCSessionDescription * desc, gpointer user_data)
2723 {
2724   GstWebRTCSessionDescription *previous;
2725   const gchar *prop;
2726
2727   prop =
2728       TEST_SDP_IS_LOCAL (t, element,
2729       desc) ? "current-local-description" : "current-remote-description";
2730   g_object_get (element, prop, &previous, NULL);
2731
2732   sdp_media_equal_attribute (t, element, desc, previous, "ice-ufrag");
2733   sdp_media_equal_attribute (t, element, desc, previous, "ice-pwd");
2734
2735   gst_webrtc_session_description_free (previous);
2736 }
2737
2738 static void
2739 sdp_media_equal_fingerprint (struct test_webrtc *t, GstElement * element,
2740     GstWebRTCSessionDescription * desc, gpointer user_data)
2741 {
2742   GstWebRTCSessionDescription *previous;
2743   const gchar *prop;
2744
2745   prop =
2746       TEST_SDP_IS_LOCAL (t, element,
2747       desc) ? "current-local-description" : "current-remote-description";
2748   g_object_get (element, prop, &previous, NULL);
2749
2750   sdp_media_equal_attribute (t, element, desc, previous, "fingerprint");
2751
2752   gst_webrtc_session_description_free (previous);
2753 }
2754
2755 GST_START_TEST (test_renego_add_stream)
2756 {
2757   struct test_webrtc *t = create_audio_video_test ();
2758   guint media_format_count[] = { 1, 1, 1 };
2759   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
2760       media_format_count, NULL);
2761   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
2762       &media_formats);
2763   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
2764   const gchar *expected_offer_setup[] = { "actpass", "actpass", "actpass" };
2765   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
2766       &payloads);
2767   const gchar *expected_answer_setup[] = { "active", "active", "active" };
2768   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
2769       &payloads);
2770   const gchar *expected_offer_direction[] =
2771       { "sendrecv", "sendrecv", "sendrecv" };
2772   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
2773       &offer_setup);
2774   const gchar *expected_answer_direction[] =
2775       { "sendrecv", "recvonly", "recvonly" };
2776   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
2777       &answer_setup);
2778   VAL_SDP_INIT (renego_mid, sdp_media_equal_mid, NULL, NULL);
2779   VAL_SDP_INIT (renego_ice_params, sdp_media_equal_ice_params, NULL,
2780       &renego_mid);
2781   VAL_SDP_INIT (renego_sess_id, sdp_equal_session_id, NULL, &renego_ice_params);
2782   VAL_SDP_INIT (renego_sess_ver, sdp_increasing_session_version, NULL,
2783       &renego_sess_id);
2784   VAL_SDP_INIT (renego_fingerprint, sdp_media_equal_fingerprint, NULL,
2785       &renego_sess_ver);
2786   GstHarness *h;
2787
2788   /* negotiate an AV stream and then renegotiate an extra stream */
2789   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
2790   add_fake_audio_src_harness (h, 96);
2791   t->harnesses = g_list_prepend (t->harnesses, h);
2792
2793   test_validate_sdp (t, &offer, &answer);
2794
2795   h = gst_harness_new_with_element (t->webrtc1, "sink_2", NULL);
2796   add_fake_audio_src_harness (h, 98);
2797   t->harnesses = g_list_prepend (t->harnesses, h);
2798
2799   media_formats.next = &renego_fingerprint;
2800   count.user_data = GUINT_TO_POINTER (3);
2801
2802   /* renegotiate! */
2803   test_webrtc_reset_negotiation (t);
2804   test_validate_sdp (t, &offer, &answer);
2805
2806   test_webrtc_free (t);
2807 }
2808
2809 GST_END_TEST;
2810
2811 GST_START_TEST (test_renego_stream_add_data_channel)
2812 {
2813   struct test_webrtc *t = create_audio_video_test ();
2814
2815   guint media_format_count[] = { 1, 1, 1 };
2816   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
2817       media_format_count, NULL);
2818   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
2819       &media_formats);
2820   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
2821   const gchar *expected_offer_setup[] = { "actpass", "actpass", "actpass" };
2822   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
2823       &payloads);
2824   const gchar *expected_answer_setup[] = { "active", "active", "active" };
2825   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
2826       &payloads);
2827   const gchar *expected_offer_direction[] = { "sendrecv", "sendrecv", NULL };
2828   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
2829       &offer_setup);
2830   const gchar *expected_answer_direction[] = { "sendrecv", "recvonly", NULL };
2831   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
2832       &answer_setup);
2833   VAL_SDP_INIT (renego_mid, sdp_media_equal_mid, NULL, NULL);
2834   VAL_SDP_INIT (renego_ice_params, sdp_media_equal_ice_params, NULL,
2835       &renego_mid);
2836   VAL_SDP_INIT (renego_sess_id, sdp_equal_session_id, NULL, &renego_ice_params);
2837   VAL_SDP_INIT (renego_sess_ver, sdp_increasing_session_version, NULL,
2838       &renego_sess_id);
2839   VAL_SDP_INIT (renego_fingerprint, sdp_media_equal_fingerprint, NULL,
2840       &renego_sess_ver);
2841   GObject *channel;
2842   GstHarness *h;
2843
2844   /* negotiate an AV stream and then renegotiate a data channel */
2845   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
2846   add_fake_audio_src_harness (h, 96);
2847   t->harnesses = g_list_prepend (t->harnesses, h);
2848
2849   test_validate_sdp (t, &offer, &answer);
2850
2851   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", NULL,
2852       &channel);
2853
2854   media_formats.next = &renego_fingerprint;
2855   count.user_data = GUINT_TO_POINTER (3);
2856
2857   /* renegotiate! */
2858   test_webrtc_reset_negotiation (t);
2859   test_validate_sdp (t, &offer, &answer);
2860
2861   g_object_unref (channel);
2862   test_webrtc_free (t);
2863 }
2864
2865 GST_END_TEST;
2866
2867 GST_START_TEST (test_renego_data_channel_add_stream)
2868 {
2869   struct test_webrtc *t = test_webrtc_new ();
2870   guint media_format_count[] = { 1, 1, 1 };
2871   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
2872       media_format_count, NULL);
2873   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (1),
2874       &media_formats);
2875   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
2876   const gchar *expected_offer_setup[] = { "actpass", "actpass" };
2877   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
2878       &payloads);
2879   const gchar *expected_answer_setup[] = { "active", "active" };
2880   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
2881       &payloads);
2882   const gchar *expected_offer_direction[] = { NULL, "sendrecv" };
2883   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
2884       &offer_setup);
2885   const gchar *expected_answer_direction[] = { NULL, "recvonly" };
2886   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
2887       &answer_setup);
2888   VAL_SDP_INIT (renego_mid, sdp_media_equal_mid, NULL, NULL);
2889   VAL_SDP_INIT (renego_ice_params, sdp_media_equal_ice_params, NULL,
2890       &renego_mid);
2891   VAL_SDP_INIT (renego_sess_id, sdp_equal_session_id, NULL, &renego_ice_params);
2892   VAL_SDP_INIT (renego_sess_ver, sdp_increasing_session_version, NULL,
2893       &renego_sess_id);
2894   VAL_SDP_INIT (renego_fingerprint, sdp_media_equal_fingerprint, NULL,
2895       &renego_sess_ver);
2896   GObject *channel;
2897   GstHarness *h;
2898
2899   /* negotiate an data channel and then renegotiate to add a av stream */
2900   t->on_negotiation_needed = NULL;
2901   t->on_ice_candidate = NULL;
2902   t->on_pad_added = _pad_added_fakesink;
2903
2904   fail_if (gst_element_set_state (t->webrtc1,
2905           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2906   fail_if (gst_element_set_state (t->webrtc2,
2907           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2908
2909   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", NULL,
2910       &channel);
2911
2912   test_validate_sdp_full (t, &offer, &answer, 0, FALSE);
2913
2914   h = gst_harness_new_with_element (t->webrtc1, "sink_1", NULL);
2915   add_fake_audio_src_harness (h, 97);
2916   t->harnesses = g_list_prepend (t->harnesses, h);
2917
2918   media_formats.next = &renego_fingerprint;
2919   count.user_data = GUINT_TO_POINTER (2);
2920
2921   /* renegotiate! */
2922   test_webrtc_reset_negotiation (t);
2923   test_validate_sdp_full (t, &offer, &answer, 0, FALSE);
2924
2925   g_object_unref (channel);
2926   test_webrtc_free (t);
2927 }
2928
2929 GST_END_TEST;
2930
2931
2932 GST_START_TEST (test_renego_stream_data_channel_add_stream)
2933 {
2934   struct test_webrtc *t = test_webrtc_new ();
2935   guint media_format_count[] = { 1, 1, 1 };
2936   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
2937       media_format_count, NULL);
2938   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
2939       &media_formats);
2940   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
2941   const gchar *expected_offer_setup[] = { "actpass", "actpass", "actpass" };
2942   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
2943       &payloads);
2944   const gchar *expected_answer_setup[] = { "active", "active", "active" };
2945   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
2946       &payloads);
2947   const gchar *expected_offer_direction[] = { "sendrecv", NULL, "sendrecv" };
2948   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
2949       &offer_setup);
2950   const gchar *expected_answer_direction[] = { "recvonly", NULL, "recvonly" };
2951   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
2952       &answer_setup);
2953   VAL_SDP_INIT (renego_mid, sdp_media_equal_mid, NULL, NULL);
2954   VAL_SDP_INIT (renego_ice_params, sdp_media_equal_ice_params, NULL,
2955       &renego_mid);
2956   VAL_SDP_INIT (renego_sess_id, sdp_equal_session_id, NULL, &renego_ice_params);
2957   VAL_SDP_INIT (renego_sess_ver, sdp_increasing_session_version, NULL,
2958       &renego_sess_id);
2959   VAL_SDP_INIT (renego_fingerprint, sdp_media_equal_fingerprint, NULL,
2960       &renego_sess_ver);
2961   GObject *channel;
2962   GstHarness *h;
2963
2964   /* Negotiate a stream and a data channel, then renogotiate with a new stream */
2965   t->on_negotiation_needed = NULL;
2966   t->on_ice_candidate = NULL;
2967   t->on_pad_added = _pad_added_fakesink;
2968
2969   h = gst_harness_new_with_element (t->webrtc1, "sink_0", NULL);
2970   add_fake_audio_src_harness (h, 97);
2971   t->harnesses = g_list_prepend (t->harnesses, h);
2972
2973   fail_if (gst_element_set_state (t->webrtc1,
2974           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2975   fail_if (gst_element_set_state (t->webrtc2,
2976           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2977
2978   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", NULL,
2979       &channel);
2980
2981   test_validate_sdp_full (t, &offer, &answer, 0, FALSE);
2982
2983   h = gst_harness_new_with_element (t->webrtc1, "sink_2", NULL);
2984   add_fake_audio_src_harness (h, 97);
2985   t->harnesses = g_list_prepend (t->harnesses, h);
2986
2987   media_formats.next = &renego_fingerprint;
2988   count.user_data = GUINT_TO_POINTER (3);
2989
2990   /* renegotiate! */
2991   test_webrtc_reset_negotiation (t);
2992   test_validate_sdp_full (t, &offer, &answer, 0, FALSE);
2993
2994   g_object_unref (channel);
2995   test_webrtc_free (t);
2996 }
2997
2998 GST_END_TEST;
2999
3000 GST_START_TEST (test_bundle_renego_add_stream)
3001 {
3002   struct test_webrtc *t = create_audio_video_test ();
3003   const gchar *bundle[] = { "audio0", "video1", "audio2", NULL };
3004   const gchar *offer_bundle_only[] = { "video1", "audio2", NULL };
3005   const gchar *answer_bundle_only[] = { NULL };
3006   guint media_format_count[] = { 1, 1, 1 };
3007   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
3008       media_format_count, NULL);
3009   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
3010       &media_formats);
3011   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
3012   const gchar *expected_offer_setup[] = { "actpass", "actpass", "actpass" };
3013   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
3014       &payloads);
3015   const gchar *expected_answer_setup[] = { "active", "active", "active" };
3016   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
3017       &payloads);
3018   const gchar *expected_offer_direction[] =
3019       { "sendrecv", "sendrecv", "sendrecv" };
3020   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
3021       &offer_setup);
3022   const gchar *expected_answer_direction[] =
3023       { "sendrecv", "recvonly", "recvonly" };
3024   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
3025       &answer_setup);
3026
3027   VAL_SDP_INIT (renego_mid, sdp_media_equal_mid, NULL, &payloads);
3028   VAL_SDP_INIT (renego_ice_params, sdp_media_equal_ice_params, NULL,
3029       &renego_mid);
3030   VAL_SDP_INIT (renego_sess_id, sdp_equal_session_id, NULL, &renego_ice_params);
3031   VAL_SDP_INIT (renego_sess_ver, sdp_increasing_session_version, NULL,
3032       &renego_sess_id);
3033   VAL_SDP_INIT (renego_fingerprint, sdp_media_equal_fingerprint, NULL,
3034       &renego_sess_ver);
3035   VAL_SDP_INIT (bundle_tag, _check_bundle_tag, bundle, &renego_fingerprint);
3036   VAL_SDP_INIT (offer_non_reject, _count_non_rejected_media,
3037       GUINT_TO_POINTER (1), &bundle_tag);
3038   VAL_SDP_INIT (answer_non_reject, _count_non_rejected_media,
3039       GUINT_TO_POINTER (3), &bundle_tag);
3040   VAL_SDP_INIT (offer_bundle_only_sdp, _check_bundle_only_media,
3041       &offer_bundle_only, &offer_non_reject);
3042   VAL_SDP_INIT (answer_bundle_only_sdp, _check_bundle_only_media,
3043       &answer_bundle_only, &answer_non_reject);
3044   GstHarness *h;
3045
3046   /* We set a max-bundle policy on the offering webrtcbin,
3047    * this means that all the offered medias should be part
3048    * of the group:BUNDLE attribute, and they should be marked
3049    * as bundle-only
3050    */
3051   gst_util_set_object_arg (G_OBJECT (t->webrtc1), "bundle-policy",
3052       "max-bundle");
3053   /* We also set a max-bundle policy on the answering webrtcbin,
3054    * this means that all the offered medias should be part
3055    * of the group:BUNDLE attribute, but need not be marked
3056    * as bundle-only.
3057    */
3058   gst_util_set_object_arg (G_OBJECT (t->webrtc2), "bundle-policy",
3059       "max-bundle");
3060
3061   /* negotiate an AV stream and then renegotiate an extra stream */
3062   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
3063   add_fake_audio_src_harness (h, 96);
3064   t->harnesses = g_list_prepend (t->harnesses, h);
3065
3066   test_validate_sdp (t, &offer, &answer);
3067
3068   h = gst_harness_new_with_element (t->webrtc1, "sink_2", NULL);
3069   add_fake_audio_src_harness (h, 98);
3070   t->harnesses = g_list_prepend (t->harnesses, h);
3071
3072   offer_setup.next = &offer_bundle_only_sdp;
3073   answer_setup.next = &answer_bundle_only_sdp;
3074   count.user_data = GUINT_TO_POINTER (3);
3075
3076   /* renegotiate! */
3077   test_webrtc_reset_negotiation (t);
3078   test_validate_sdp (t, &offer, &answer);
3079
3080   test_webrtc_free (t);
3081 }
3082
3083 GST_END_TEST;
3084
3085 GST_START_TEST (test_bundle_max_compat_max_bundle_renego_add_stream)
3086 {
3087   struct test_webrtc *t = create_audio_video_test ();
3088   const gchar *bundle[] = { "audio0", "video1", "audio2", NULL };
3089   const gchar *bundle_only[] = { NULL };
3090   guint media_format_count[] = { 1, 1, 1 };
3091   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
3092       media_format_count, NULL);
3093   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
3094       &media_formats);
3095   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
3096   const gchar *expected_offer_setup[] = { "actpass", "actpass", "actpass" };
3097   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
3098       &payloads);
3099   const gchar *expected_answer_setup[] = { "active", "active", "active" };
3100   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
3101       &payloads);
3102   const gchar *expected_offer_direction[] =
3103       { "sendrecv", "sendrecv", "sendrecv" };
3104   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
3105       &offer_setup);
3106   const gchar *expected_answer_direction[] =
3107       { "sendrecv", "recvonly", "recvonly" };
3108   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
3109       &answer_setup);
3110
3111   VAL_SDP_INIT (renego_mid, sdp_media_equal_mid, NULL, NULL);
3112   VAL_SDP_INIT (renego_ice_params, sdp_media_equal_ice_params, NULL,
3113       &renego_mid);
3114   VAL_SDP_INIT (renego_sess_id, sdp_equal_session_id, NULL, &renego_ice_params);
3115   VAL_SDP_INIT (renego_sess_ver, sdp_increasing_session_version, NULL,
3116       &renego_sess_id);
3117   VAL_SDP_INIT (renego_fingerprint, sdp_media_equal_fingerprint, NULL,
3118       &renego_sess_ver);
3119   VAL_SDP_INIT (bundle_tag, _check_bundle_tag, bundle, &renego_fingerprint);
3120   VAL_SDP_INIT (count_non_reject, _count_non_rejected_media,
3121       GUINT_TO_POINTER (3), &bundle_tag);
3122   VAL_SDP_INIT (bundle_sdp, _check_bundle_only_media, &bundle_only,
3123       &count_non_reject);
3124   GstHarness *h;
3125
3126   /* We set a max-compat policy on the offering webrtcbin,
3127    * this means that all the offered medias should be part
3128    * of the group:BUNDLE attribute, and they should *not* be marked
3129    * as bundle-only
3130    */
3131   gst_util_set_object_arg (G_OBJECT (t->webrtc1), "bundle-policy",
3132       "max-compat");
3133   /* We set a max-bundle policy on the answering webrtcbin,
3134    * this means that all the offered medias should be part
3135    * of the group:BUNDLE attribute, but need not be marked
3136    * as bundle-only.
3137    */
3138   gst_util_set_object_arg (G_OBJECT (t->webrtc2), "bundle-policy",
3139       "max-bundle");
3140
3141   /* negotiate an AV stream and then renegotiate an extra stream */
3142   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
3143   add_fake_audio_src_harness (h, 96);
3144   t->harnesses = g_list_prepend (t->harnesses, h);
3145
3146   test_validate_sdp (t, &offer, &answer);
3147
3148   h = gst_harness_new_with_element (t->webrtc1, "sink_2", NULL);
3149   add_fake_audio_src_harness (h, 98);
3150   t->harnesses = g_list_prepend (t->harnesses, h);
3151
3152   media_formats.next = &bundle_sdp;
3153   count.user_data = GUINT_TO_POINTER (3);
3154
3155   /* renegotiate! */
3156   test_webrtc_reset_negotiation (t);
3157   test_validate_sdp (t, &offer, &answer);
3158
3159   test_webrtc_free (t);
3160 }
3161
3162 GST_END_TEST;
3163
3164 GST_START_TEST (test_renego_transceiver_set_direction)
3165 {
3166   struct test_webrtc *t = create_audio_test ();
3167   guint media_format_count[] = { 1, };
3168   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
3169       media_format_count, NULL);
3170   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (1),
3171       &media_formats);
3172   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
3173   const gchar *expected_offer_setup[] = { "actpass", };
3174   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
3175       &payloads);
3176   const gchar *expected_answer_setup[] = { "active", };
3177   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
3178       &payloads);
3179   const gchar *expected_offer_direction[] = { "sendrecv", };
3180   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
3181       &offer_setup);
3182   const gchar *expected_answer_direction[] = { "sendrecv", };
3183   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
3184       &answer_setup);
3185   GstWebRTCRTPTransceiver *transceiver;
3186   GstHarness *h;
3187   GstPad *pad;
3188
3189   /* negotiate an AV stream and then change the transceiver direction */
3190   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
3191   add_fake_audio_src_harness (h, 96);
3192   t->harnesses = g_list_prepend (t->harnesses, h);
3193
3194   test_validate_sdp (t, &offer, &answer);
3195
3196   /* renegotiate an inactive transceiver! */
3197   pad = gst_element_get_static_pad (t->webrtc1, "sink_0");
3198   g_object_get (pad, "transceiver", &transceiver, NULL);
3199   fail_unless (transceiver != NULL);
3200   g_object_set (transceiver, "direction",
3201       GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_INACTIVE, NULL);
3202   expected_offer_direction[0] = "inactive";
3203   expected_answer_direction[0] = "inactive";
3204
3205   /* TODO: also validate EOS events from the inactive change */
3206
3207   test_webrtc_reset_negotiation (t);
3208   test_validate_sdp (t, &offer, &answer);
3209
3210   gst_object_unref (pad);
3211   gst_object_unref (transceiver);
3212   test_webrtc_free (t);
3213 }
3214
3215 GST_END_TEST;
3216
3217 static void
3218 offer_remove_last_media (struct test_webrtc *t, GstElement * element,
3219     GstPromise * promise, gpointer user_data)
3220 {
3221   guint i, n;
3222   GstSDPMessage *new, *old;
3223   const GstSDPOrigin *origin;
3224   const GstSDPConnection *conn;
3225
3226   old = t->offer_desc->sdp;
3227   fail_unless_equals_int (GST_SDP_OK, gst_sdp_message_new (&new));
3228
3229   origin = gst_sdp_message_get_origin (old);
3230   conn = gst_sdp_message_get_connection (old);
3231   fail_unless_equals_int (GST_SDP_OK, gst_sdp_message_set_version (new,
3232           gst_sdp_message_get_version (old)));
3233   fail_unless_equals_int (GST_SDP_OK, gst_sdp_message_set_origin (new,
3234           origin->username, origin->sess_id, origin->sess_version,
3235           origin->nettype, origin->addrtype, origin->addr));
3236   fail_unless_equals_int (GST_SDP_OK, gst_sdp_message_set_session_name (new,
3237           gst_sdp_message_get_session_name (old)));
3238   fail_unless_equals_int (GST_SDP_OK, gst_sdp_message_set_information (new,
3239           gst_sdp_message_get_information (old)));
3240   fail_unless_equals_int (GST_SDP_OK, gst_sdp_message_set_uri (new,
3241           gst_sdp_message_get_uri (old)));
3242   fail_unless_equals_int (GST_SDP_OK, gst_sdp_message_set_connection (new,
3243           conn->nettype, conn->addrtype, conn->address, conn->ttl,
3244           conn->addr_number));
3245
3246   n = gst_sdp_message_attributes_len (old);
3247   for (i = 0; i < n; i++) {
3248     const GstSDPAttribute *a = gst_sdp_message_get_attribute (old, i);
3249     fail_unless_equals_int (GST_SDP_OK, gst_sdp_message_add_attribute (new,
3250             a->key, a->value));
3251   }
3252
3253   n = gst_sdp_message_medias_len (old);
3254   fail_unless (n > 0);
3255   for (i = 0; i < n - 1; i++) {
3256     const GstSDPMedia *m = gst_sdp_message_get_media (old, i);
3257     GstSDPMedia *new_m;
3258
3259     fail_unless_equals_int (GST_SDP_OK, gst_sdp_media_copy (m, &new_m));
3260     fail_unless_equals_int (GST_SDP_OK, gst_sdp_message_add_media (new, new_m));
3261     gst_sdp_media_init (new_m);
3262     gst_sdp_media_free (new_m);
3263   }
3264
3265   gst_webrtc_session_description_free (t->offer_desc);
3266   t->offer_desc = gst_webrtc_session_description_new (GST_WEBRTC_SDP_TYPE_OFFER,
3267       new);
3268 }
3269
3270 static void
3271 offer_set_produced_error (struct test_webrtc *t, GstElement * element,
3272     GstPromise * promise, gpointer user_data)
3273 {
3274   const GstStructure *reply;
3275   GError *error = NULL;
3276
3277   reply = gst_promise_get_reply (promise);
3278   fail_unless (gst_structure_get (reply, "error", G_TYPE_ERROR, &error, NULL));
3279   GST_INFO ("error produced: %s", error->message);
3280   g_clear_error (&error);
3281
3282   test_webrtc_signal_state_unlocked (t, STATE_CUSTOM);
3283 }
3284
3285 GST_START_TEST (test_renego_lose_media_fails)
3286 {
3287   struct test_webrtc *t = create_audio_video_test ();
3288   VAL_SDP_INIT (offer, _count_num_sdp_media, GUINT_TO_POINTER (2), NULL);
3289   VAL_SDP_INIT (answer, _count_num_sdp_media, GUINT_TO_POINTER (2), NULL);
3290
3291   /* check that removing an m=line will produce an error */
3292
3293   test_validate_sdp (t, &offer, &answer);
3294
3295   test_webrtc_reset_negotiation (t);
3296
3297   t->on_offer_created = offer_remove_last_media;
3298   t->on_offer_set = offer_set_produced_error;
3299   t->on_answer_created = NULL;
3300
3301   test_webrtc_create_offer (t);
3302   test_webrtc_wait_for_state_mask (t, 1 << STATE_CUSTOM);
3303
3304   test_webrtc_free (t);
3305 }
3306
3307 GST_END_TEST;
3308
3309 GST_START_TEST (test_bundle_codec_preferences_rtx_no_duplicate_payloads)
3310 {
3311   struct test_webrtc *t = test_webrtc_new ();
3312   GstWebRTCRTPTransceiverDirection direction;
3313   GstWebRTCRTPTransceiver *trans;
3314   guint offer_media_format_count[] = { 2, };
3315   guint answer_media_format_count[] = { 1, };
3316   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, NULL);
3317   VAL_SDP_INIT (offer_media_formats, on_sdp_media_count_formats,
3318       offer_media_format_count, &payloads);
3319   VAL_SDP_INIT (answer_media_formats, on_sdp_media_count_formats,
3320       answer_media_format_count, &payloads);
3321   const gchar *expected_offer_setup[] = { "actpass", };
3322   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
3323       &offer_media_formats);
3324   const gchar *expected_answer_setup[] = { "active", };
3325   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
3326       &answer_media_formats);
3327   const gchar *expected_offer_direction[] = { "recvonly", };
3328   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
3329       &offer_setup);
3330   const gchar *expected_answer_direction[] = { "sendonly", };
3331   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
3332       &answer_setup);
3333   GstCaps *caps;
3334   GstHarness *h;
3335
3336   /* add a transceiver that will only receive an opus stream and check that
3337    * the created offer is marked as recvonly */
3338   t->on_negotiation_needed = NULL;
3339   t->on_ice_candidate = NULL;
3340   t->on_pad_added = _pad_added_fakesink;
3341
3342   gst_util_set_object_arg (G_OBJECT (t->webrtc1), "bundle-policy",
3343       "max-bundle");
3344   gst_util_set_object_arg (G_OBJECT (t->webrtc2), "bundle-policy",
3345       "max-bundle");
3346
3347   /* setup recvonly transceiver */
3348   caps = gst_caps_from_string (VP8_RTP_CAPS (96));
3349   direction = GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_RECVONLY;
3350   g_signal_emit_by_name (t->webrtc1, "add-transceiver", direction, caps,
3351       &trans);
3352   g_object_set (GST_OBJECT (trans), "do-nack", TRUE, NULL);
3353   gst_caps_unref (caps);
3354   fail_unless (trans != NULL);
3355   gst_object_unref (trans);
3356
3357   /* setup sendonly peer */
3358   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
3359   add_fake_video_src_harness (h, 96);
3360   t->harnesses = g_list_prepend (t->harnesses, h);
3361   test_validate_sdp (t, &offer, &answer);
3362
3363   test_webrtc_free (t);
3364 }
3365
3366 GST_END_TEST;
3367
3368 GST_START_TEST (test_reject_request_pad)
3369 {
3370   struct test_webrtc *t = test_webrtc_new ();
3371   GstWebRTCRTPTransceiverDirection direction;
3372   GstWebRTCRTPTransceiver *trans, *trans2;
3373   guint offer_media_format_count[] = { 1, };
3374   guint answer_media_format_count[] = { 1, };
3375   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, NULL);
3376   VAL_SDP_INIT (offer_media_formats, on_sdp_media_count_formats,
3377       offer_media_format_count, &payloads);
3378   VAL_SDP_INIT (answer_media_formats, on_sdp_media_count_formats,
3379       answer_media_format_count, &payloads);
3380   const gchar *expected_offer_setup[] = { "actpass", };
3381   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
3382       &offer_media_formats);
3383   const gchar *expected_answer_setup[] = { "active", };
3384   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
3385       &answer_media_formats);
3386   const gchar *expected_offer_direction[] = { "recvonly", };
3387   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
3388       &offer_setup);
3389   const gchar *expected_answer_direction[] = { "sendonly", };
3390   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
3391       &answer_setup);
3392   GstCaps *caps;
3393   GstHarness *h;
3394   GstPad *pad;
3395   GstPadTemplate *templ;
3396
3397   t->on_negotiation_needed = NULL;
3398   t->on_ice_candidate = NULL;
3399   t->on_pad_added = _pad_added_fakesink;
3400
3401   gst_util_set_object_arg (G_OBJECT (t->webrtc1), "bundle-policy",
3402       "max-bundle");
3403   gst_util_set_object_arg (G_OBJECT (t->webrtc2), "bundle-policy",
3404       "max-bundle");
3405
3406   /* setup recvonly transceiver */
3407   caps = gst_caps_from_string (VP8_RTP_CAPS (96));
3408   direction = GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_RECVONLY;
3409   g_signal_emit_by_name (t->webrtc1, "add-transceiver", direction, caps,
3410       &trans);
3411   gst_caps_unref (caps);
3412   fail_unless (trans != NULL);
3413
3414   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
3415   add_fake_video_src_harness (h, 96);
3416   t->harnesses = g_list_prepend (t->harnesses, h);
3417
3418   test_validate_sdp (t, &offer, &answer);
3419
3420   /* This should fail because the direction is wrong */
3421   pad = gst_element_get_request_pad (t->webrtc1, "sink_0");
3422   fail_unless (pad == NULL);
3423
3424   g_object_set (trans, "direction",
3425       GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_SENDRECV, NULL);
3426
3427   templ = gst_element_get_pad_template (t->webrtc1, "sink_%u");
3428   fail_unless (templ != NULL);
3429
3430   /* This should fail because the caps are wrong */
3431   caps = gst_caps_from_string (OPUS_RTP_CAPS (96));
3432   pad = gst_element_request_pad (t->webrtc1, templ, "sink_0", caps);
3433   fail_unless (pad == NULL);
3434
3435   gst_caps_unref (trans->codec_preferences);
3436   trans->codec_preferences = NULL;
3437
3438   /* This should fail because the kind doesn't match */
3439   pad = gst_element_request_pad (t->webrtc1, templ, "sink_0", caps);
3440   fail_unless (pad == NULL);
3441   gst_caps_unref (caps);
3442
3443   /* This should succeed and give us sink_0 */
3444   pad = gst_element_get_request_pad (t->webrtc1, "sink_0");
3445   fail_unless (pad != NULL);
3446
3447   g_object_get (pad, "transceiver", &trans2, NULL);
3448
3449   fail_unless (trans == trans2);
3450
3451   gst_object_unref (pad);
3452   gst_object_unref (trans);
3453   gst_object_unref (trans2);
3454
3455   test_webrtc_free (t);
3456 }
3457
3458 GST_END_TEST;
3459
3460 static void
3461 _verify_media_types (struct test_webrtc *t, GstElement * element,
3462     GstWebRTCSessionDescription * desc, gpointer user_data)
3463 {
3464   gchar **media_types = user_data;
3465   int i;
3466
3467   for (i = 0; i < gst_sdp_message_medias_len (desc->sdp); i++) {
3468     const GstSDPMedia *media = gst_sdp_message_get_media (desc->sdp, i);
3469
3470     fail_unless_equals_string (gst_sdp_media_get_media (media), media_types[i]);
3471   }
3472 }
3473
3474 GST_START_TEST (test_reject_create_offer)
3475 {
3476   struct test_webrtc *t = test_webrtc_new ();
3477   GstHarness *h;
3478   GstPromise *promise;
3479   GstPromiseResult res;
3480   const GstStructure *s;
3481   GError *error = NULL;
3482
3483   const gchar *media_types[] = { "video", "audio" };
3484   VAL_SDP_INIT (media_type, _verify_media_types, &media_types, NULL);
3485   guint media_format_count[] = { 1, 1 };
3486   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
3487       media_format_count, &media_type);
3488   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
3489       &media_formats);
3490   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
3491   const gchar *expected_offer_setup[] = { "actpass", "actpass" };
3492   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
3493       &payloads);
3494   const gchar *expected_answer_setup[] = { "active", "active" };
3495   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
3496       &payloads);
3497   const gchar *expected_offer_direction[] = { "sendrecv", "sendrecv" };
3498   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
3499       &offer_setup);
3500   const gchar *expected_answer_direction[] = { "recvonly", "recvonly" };
3501   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
3502       &answer_setup);
3503
3504   t->on_negotiation_needed = NULL;
3505   t->on_ice_candidate = NULL;
3506   t->on_pad_added = _pad_added_fakesink;
3507
3508   /* setup sendonly peer */
3509   h = gst_harness_new_with_element (t->webrtc1, "sink_1", NULL);
3510   add_fake_audio_src_harness (h, 96);
3511   t->harnesses = g_list_prepend (t->harnesses, h);
3512
3513   /* Check that if there is no 0, we can't create an offer with a hole */
3514   promise = gst_promise_new ();
3515   g_signal_emit_by_name (t->webrtc1, "create-offer", NULL, promise);
3516   res = gst_promise_wait (promise);
3517   fail_unless_equals_int (res, GST_PROMISE_RESULT_REPLIED);
3518   s = gst_promise_get_reply (promise);
3519   fail_unless (s != NULL);
3520   fail_unless (gst_structure_has_name (s, "application/x-gstwebrtcbin-error"));
3521   gst_structure_get (s, "error", G_TYPE_ERROR, &error, NULL);
3522   fail_unless (g_error_matches (error, GST_WEBRTC_BIN_ERROR,
3523           GST_WEBRTC_BIN_ERROR_IMPOSSIBLE_MLINE_RESTRICTION));
3524   g_clear_error (&error);
3525   gst_promise_unref (promise);
3526
3527   h = gst_harness_new_with_element (t->webrtc1, "sink_%u", NULL);
3528   add_fake_video_src_harness (h, 97);
3529   t->harnesses = g_list_prepend (t->harnesses, h);
3530
3531   /* Adding a second sink, which will fill m-line 0, should fix it */
3532   test_validate_sdp (t, &offer, &answer);
3533
3534   test_webrtc_free (t);
3535 }
3536
3537 GST_END_TEST;
3538
3539 GST_START_TEST (test_reject_set_description)
3540 {
3541   struct test_webrtc *t = test_webrtc_new ();
3542   GstHarness *h;
3543   GstPromise *promise;
3544   GstPromiseResult res;
3545   const GstStructure *s;
3546   GError *error = NULL;
3547   GstWebRTCSessionDescription *desc = NULL;
3548   GstPadTemplate *templ;
3549   GstCaps *caps;
3550   GstPad *pad;
3551
3552   t->on_negotiation_needed = NULL;
3553   t->on_ice_candidate = NULL;
3554   t->on_pad_added = _pad_added_fakesink;
3555
3556   /* setup peer 1 */
3557   h = gst_harness_new_with_element (t->webrtc1, "sink_0", NULL);
3558   add_fake_audio_src_harness (h, 96);
3559   t->harnesses = g_list_prepend (t->harnesses, h);
3560
3561   /* Create a second side with specific video caps */
3562   templ = gst_element_get_pad_template (t->webrtc2, "sink_%u");
3563   fail_unless (templ != NULL);
3564   caps = gst_caps_from_string (VP8_RTP_CAPS (97));
3565   pad = gst_element_request_pad (t->webrtc2, templ, "sink_0", caps);
3566   fail_unless (pad != NULL);
3567   gst_caps_unref (caps);
3568   gst_object_unref (pad);
3569
3570   /* Create an offer */
3571   promise = gst_promise_new ();
3572   g_signal_emit_by_name (t->webrtc1, "create-offer", NULL, promise);
3573   res = gst_promise_wait (promise);
3574   fail_unless_equals_int (res, GST_PROMISE_RESULT_REPLIED);
3575   s = gst_promise_get_reply (promise);
3576   fail_unless (s != NULL);
3577   fail_unless (gst_structure_has_name (s, "application/x-gst-promise"));
3578   gst_structure_get (s, "offer", GST_TYPE_WEBRTC_SESSION_DESCRIPTION, &desc,
3579       NULL);
3580   fail_unless (desc != NULL);
3581   gst_promise_unref (promise);
3582
3583   fail_if (gst_element_set_state (t->webrtc2,
3584           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
3585
3586   /* Verify that setting an offer where there is a forced m-line with
3587      a different kind fails. */
3588   promise = gst_promise_new ();
3589   g_signal_emit_by_name (t->webrtc2, "set-remote-description", desc, promise);
3590   res = gst_promise_wait (promise);
3591   fail_unless_equals_int (res, GST_PROMISE_RESULT_REPLIED);
3592   s = gst_promise_get_reply (promise);
3593   fail_unless (gst_structure_has_name (s, "application/x-gstwebrtcbin-error"));
3594   gst_structure_get (s, "error", G_TYPE_ERROR, &error, NULL);
3595   fail_unless (g_error_matches (error, GST_WEBRTC_BIN_ERROR,
3596           GST_WEBRTC_BIN_ERROR_IMPOSSIBLE_MLINE_RESTRICTION));
3597   g_clear_error (&error);
3598   fail_unless (s != NULL);
3599   gst_promise_unref (promise);
3600   gst_webrtc_session_description_free (desc);
3601
3602   test_webrtc_free (t);
3603 }
3604
3605 GST_END_TEST;
3606
3607 GST_START_TEST (test_force_second_media)
3608 {
3609   struct test_webrtc *t = test_webrtc_new ();
3610   const gchar *media_types[] = { "audio" };
3611   VAL_SDP_INIT (media_type, _verify_media_types, &media_types, NULL);
3612   guint media_format_count[] = { 1, };
3613   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
3614       media_format_count, &media_type);
3615   const gchar *expected_offer_setup[] = { "actpass", };
3616   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
3617       &media_formats);
3618   const gchar *expected_answer_setup[] = { "active", };
3619   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
3620       &media_formats);
3621   const gchar *expected_offer_direction[] = { "sendrecv", };
3622   VAL_SDP_INIT (offer_direction, on_sdp_media_direction,
3623       expected_offer_direction, &offer_setup);
3624   const gchar *expected_answer_direction[] = { "recvonly", };
3625   VAL_SDP_INIT (answer_direction, on_sdp_media_direction,
3626       expected_answer_direction, &answer_setup);
3627   VAL_SDP_INIT (answer_count, _count_num_sdp_media, GUINT_TO_POINTER (1),
3628       &answer_direction);
3629   VAL_SDP_INIT (offer_count, _count_num_sdp_media, GUINT_TO_POINTER (1),
3630       &offer_direction);
3631
3632   const gchar *second_media_types[] = { "audio", "video" };
3633   VAL_SDP_INIT (second_media_type, _verify_media_types, &second_media_types,
3634       NULL);
3635   guint second_media_format_count[] = { 1, 1 };
3636   VAL_SDP_INIT (second_media_formats, on_sdp_media_count_formats,
3637       second_media_format_count, &second_media_type);
3638   const gchar *second_expected_offer_setup[] = { "active", "actpass" };
3639   VAL_SDP_INIT (second_offer_setup, on_sdp_media_setup,
3640       second_expected_offer_setup, &second_media_formats);
3641   const gchar *second_expected_answer_setup[] = { "passive", "active" };
3642   VAL_SDP_INIT (second_answer_setup, on_sdp_media_setup,
3643       second_expected_answer_setup, &second_media_formats);
3644   const gchar *second_expected_answer_direction[] = { "sendonly", "recvonly" };
3645   VAL_SDP_INIT (second_answer_direction, on_sdp_media_direction,
3646       second_expected_answer_direction, &second_answer_setup);
3647   const gchar *second_expected_offer_direction[] = { "recvonly", "sendrecv" };
3648   VAL_SDP_INIT (second_offer_direction, on_sdp_media_direction,
3649       second_expected_offer_direction, &second_offer_setup);
3650   VAL_SDP_INIT (second_answer_count, _count_num_sdp_media, GUINT_TO_POINTER (2),
3651       &second_answer_direction);
3652   VAL_SDP_INIT (second_offer_count, _count_num_sdp_media, GUINT_TO_POINTER (2),
3653       &second_offer_direction);
3654
3655   GstHarness *h;
3656   guint negotiation_flag = 0;
3657   GstPadTemplate *templ;
3658   GstCaps *caps;
3659   GstPad *pad;
3660
3661   /* add a transceiver that will only receive an opus stream and check that
3662    * the created offer is marked as recvonly */
3663   t->on_negotiation_needed = on_negotiation_needed_hit;
3664   t->negotiation_data = &negotiation_flag;
3665   t->on_ice_candidate = NULL;
3666   t->on_pad_added = _pad_added_fakesink;
3667
3668   /* setup peer */
3669   h = gst_harness_new_with_element (t->webrtc1, "sink_0", NULL);
3670   add_fake_audio_src_harness (h, 96);
3671   t->harnesses = g_list_prepend (t->harnesses, h);
3672
3673   /* Create a second side with specific video caps */
3674   templ = gst_element_get_pad_template (t->webrtc2, "sink_%u");
3675   fail_unless (templ != NULL);
3676   caps = gst_caps_from_string (VP8_RTP_CAPS (97));
3677   pad = gst_element_request_pad (t->webrtc2, templ, NULL, caps);
3678   gst_caps_unref (caps);
3679   fail_unless (pad != NULL);
3680   h = gst_harness_new_with_element (t->webrtc2, GST_PAD_NAME (pad), NULL);
3681   gst_object_unref (pad);
3682   add_fake_video_src_harness (h, 97);
3683   t->harnesses = g_list_prepend (t->harnesses, h);
3684
3685   test_validate_sdp (t, &offer_count, &answer_count);
3686   fail_unless (negotiation_flag & 1 << 2);
3687
3688   test_webrtc_reset_negotiation (t);
3689
3690   t->offerror = 2;
3691   test_validate_sdp (t, &second_offer_count, &second_answer_count);
3692
3693   test_webrtc_free (t);
3694 }
3695
3696 GST_END_TEST;
3697
3698 static Suite *
3699 webrtcbin_suite (void)
3700 {
3701   Suite *s = suite_create ("webrtcbin");
3702   TCase *tc = tcase_create ("general");
3703   GstPluginFeature *nicesrc, *nicesink, *dtlssrtpdec, *dtlssrtpenc;
3704   GstPluginFeature *sctpenc, *sctpdec;
3705   GstRegistry *registry;
3706
3707   registry = gst_registry_get ();
3708   nicesrc = gst_registry_lookup_feature (registry, "nicesrc");
3709   nicesink = gst_registry_lookup_feature (registry, "nicesink");
3710   dtlssrtpenc = gst_registry_lookup_feature (registry, "dtlssrtpenc");
3711   dtlssrtpdec = gst_registry_lookup_feature (registry, "dtlssrtpdec");
3712   sctpenc = gst_registry_lookup_feature (registry, "sctpenc");
3713   sctpdec = gst_registry_lookup_feature (registry, "sctpdec");
3714
3715   tcase_add_test (tc, test_no_nice_elements_request_pad);
3716   tcase_add_test (tc, test_no_nice_elements_state_change);
3717   if (nicesrc && nicesink && dtlssrtpenc && dtlssrtpdec) {
3718     tcase_add_test (tc, test_sdp_no_media);
3719     tcase_add_test (tc, test_session_stats);
3720     tcase_add_test (tc, test_audio);
3721     tcase_add_test (tc, test_ice_port_restriction);
3722     tcase_add_test (tc, test_audio_video);
3723     tcase_add_test (tc, test_media_direction);
3724     tcase_add_test (tc, test_add_transceiver);
3725     tcase_add_test (tc, test_get_transceivers);
3726     tcase_add_test (tc, test_add_recvonly_transceiver);
3727     tcase_add_test (tc, test_recvonly_sendonly);
3728     tcase_add_test (tc, test_payload_types);
3729     tcase_add_test (tc, test_bundle_audio_video_max_bundle_max_bundle);
3730     tcase_add_test (tc, test_bundle_audio_video_max_bundle_none);
3731     tcase_add_test (tc, test_bundle_audio_video_max_compat_max_bundle);
3732     tcase_add_test (tc, test_dual_audio);
3733     tcase_add_test (tc, test_duplicate_nego);
3734     tcase_add_test (tc, test_renego_add_stream);
3735     tcase_add_test (tc, test_bundle_renego_add_stream);
3736     tcase_add_test (tc, test_bundle_max_compat_max_bundle_renego_add_stream);
3737     tcase_add_test (tc, test_renego_transceiver_set_direction);
3738     tcase_add_test (tc, test_renego_lose_media_fails);
3739     tcase_add_test (tc,
3740         test_bundle_codec_preferences_rtx_no_duplicate_payloads);
3741     tcase_add_test (tc, test_reject_request_pad);
3742     tcase_add_test (tc, test_reject_create_offer);
3743     tcase_add_test (tc, test_reject_set_description);
3744     tcase_add_test (tc, test_force_second_media);
3745     if (sctpenc && sctpdec) {
3746       tcase_add_test (tc, test_data_channel_create);
3747       tcase_add_test (tc, test_data_channel_remote_notify);
3748       tcase_add_test (tc, test_data_channel_transfer_string);
3749       tcase_add_test (tc, test_data_channel_transfer_data);
3750       tcase_add_test (tc, test_data_channel_create_after_negotiate);
3751       tcase_add_test (tc, test_data_channel_low_threshold);
3752       tcase_add_test (tc, test_data_channel_max_message_size);
3753       tcase_add_test (tc, test_data_channel_pre_negotiated);
3754       tcase_add_test (tc, test_bundle_audio_video_data);
3755       tcase_add_test (tc, test_renego_stream_add_data_channel);
3756       tcase_add_test (tc, test_renego_data_channel_add_stream);
3757       tcase_add_test (tc, test_renego_stream_data_channel_add_stream);
3758     } else {
3759       GST_WARNING ("Some required elements were not found. "
3760           "All datachannel tests are disabled. sctpenc %p, sctpdec %p", sctpenc,
3761           sctpdec);
3762     }
3763   } else {
3764     GST_WARNING ("Some required elements were not found. "
3765         "All media tests are disabled. nicesrc %p, nicesink %p, "
3766         "dtlssrtpenc %p, dtlssrtpdec %p", nicesrc, nicesink, dtlssrtpenc,
3767         dtlssrtpdec);
3768   }
3769
3770   if (nicesrc)
3771     gst_object_unref (nicesrc);
3772   if (nicesink)
3773     gst_object_unref (nicesink);
3774   if (dtlssrtpdec)
3775     gst_object_unref (dtlssrtpdec);
3776   if (dtlssrtpenc)
3777     gst_object_unref (dtlssrtpenc);
3778   if (sctpenc)
3779     gst_object_unref (sctpenc);
3780   if (sctpdec)
3781     gst_object_unref (sctpdec);
3782
3783   suite_add_tcase (s, tc);
3784
3785   return s;
3786 }
3787
3788 GST_CHECK_MAIN (webrtcbin);