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