webrtcbin: support using an a=mid value from the sink/transceiver caps
[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 static void
1632 on_sdp_media_check_mid (struct test_webrtc *t, GstElement * element,
1633     GstWebRTCSessionDescription * desc, gpointer user_data)
1634 {
1635   const char **mid = user_data;
1636   guint i;
1637
1638   for (i = 0; i < gst_sdp_message_medias_len (desc->sdp); i++) {
1639     const GstSDPMedia *media = gst_sdp_message_get_media (desc->sdp, i);
1640     gboolean seen_mid = FALSE;
1641     guint j;
1642
1643     for (j = 0; j < gst_sdp_media_attributes_len (media); j++) {
1644       const GstSDPAttribute *attr = gst_sdp_media_get_attribute (media, j);
1645
1646       if (g_strcmp0 (attr->key, "mid") == 0) {
1647         fail_unless (!seen_mid);
1648         seen_mid = TRUE;
1649         fail_unless_equals_string (attr->value, mid[i]);
1650       }
1651     }
1652   }
1653 }
1654
1655 GST_START_TEST (test_add_recvonly_transceiver)
1656 {
1657   struct test_webrtc *t = test_webrtc_new ();
1658   GstWebRTCRTPTransceiverDirection direction;
1659   GstWebRTCRTPTransceiver *trans;
1660   VAL_SDP_INIT (no_duplicate_payloads, on_sdp_media_no_duplicate_payloads,
1661       NULL, NULL);
1662   guint media_format_count[] = { 1, 1, };
1663   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
1664       media_format_count, &no_duplicate_payloads);
1665   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (1),
1666       &media_formats);
1667   const char *expected_mid[] = { "gst", };
1668   VAL_SDP_INIT (mid, on_sdp_media_check_mid, expected_mid, &count);
1669   const gchar *expected_offer_setup[] = { "actpass", };
1670   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup, &mid);
1671   const gchar *expected_answer_setup[] = { "active", };
1672   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup, &mid);
1673   const gchar *expected_offer_direction[] = { "recvonly", };
1674   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
1675       &offer_setup);
1676   const gchar *expected_answer_direction[] = { "sendonly", };
1677   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
1678       &answer_setup);
1679   GstCaps *caps;
1680   GstHarness *h;
1681
1682   /* add a transceiver that will only receive an opus stream and check that
1683    * the created offer is marked as recvonly */
1684   t->on_negotiation_needed = NULL;
1685   t->on_ice_candidate = NULL;
1686   t->on_pad_added = _pad_added_fakesink;
1687
1688   /* setup recvonly transceiver */
1689   caps = gst_caps_from_string (OPUS_RTP_CAPS (96) ", a-mid=(string)gst");
1690   direction = GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_RECVONLY;
1691   g_signal_emit_by_name (t->webrtc1, "add-transceiver", direction, caps,
1692       &trans);
1693   gst_caps_unref (caps);
1694   fail_unless (trans != NULL);
1695   gst_object_unref (trans);
1696
1697   /* setup sendonly peer */
1698   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
1699   add_fake_audio_src_harness (h, 96);
1700   t->harnesses = g_list_prepend (t->harnesses, h);
1701   test_validate_sdp (t, &offer, &answer);
1702
1703   test_webrtc_free (t);
1704 }
1705
1706 GST_END_TEST;
1707
1708 GST_START_TEST (test_recvonly_sendonly)
1709 {
1710   struct test_webrtc *t = test_webrtc_new ();
1711   GstWebRTCRTPTransceiverDirection direction;
1712   GstWebRTCRTPTransceiver *trans;
1713   VAL_SDP_INIT (no_duplicate_payloads, on_sdp_media_no_duplicate_payloads,
1714       NULL, NULL);
1715   guint media_format_count[] = { 1, 1, };
1716   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
1717       media_format_count, &no_duplicate_payloads);
1718   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
1719       &media_formats);
1720   const gchar *expected_offer_setup[] = { "actpass", "actpass" };
1721   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup, &count);
1722   const gchar *expected_answer_setup[] = { "active", "active" };
1723   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
1724       &count);
1725   const gchar *expected_offer_direction[] = { "recvonly", "sendonly" };
1726   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
1727       &offer_setup);
1728   const gchar *expected_answer_direction[] = { "sendonly", "recvonly" };
1729   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
1730       &answer_setup);
1731   GstCaps *caps;
1732   GstHarness *h;
1733   GArray *transceivers;
1734
1735   /* add a transceiver that will only receive an opus stream and check that
1736    * the created offer is marked as recvonly */
1737   t->on_negotiation_needed = NULL;
1738   t->on_ice_candidate = NULL;
1739   t->on_pad_added = _pad_added_fakesink;
1740
1741   /* setup recvonly transceiver */
1742   caps = gst_caps_from_string (OPUS_RTP_CAPS (96));
1743   direction = GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_RECVONLY;
1744   g_signal_emit_by_name (t->webrtc1, "add-transceiver", direction, caps,
1745       &trans);
1746   gst_caps_unref (caps);
1747   fail_unless (trans != NULL);
1748   gst_object_unref (trans);
1749
1750   /* setup sendonly stream */
1751   h = gst_harness_new_with_element (t->webrtc1, "sink_1", NULL);
1752   add_fake_audio_src_harness (h, 96);
1753   t->harnesses = g_list_prepend (t->harnesses, h);
1754   g_signal_emit_by_name (t->webrtc1, "get-transceivers", &transceivers);
1755   fail_unless (transceivers != NULL);
1756   fail_unless_equals_int (transceivers->len, 2);
1757   trans = g_array_index (transceivers, GstWebRTCRTPTransceiver *, 1);
1758   g_object_set (trans, "direction",
1759       GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_SENDONLY, NULL);
1760
1761   g_array_unref (transceivers);
1762
1763   /* setup sendonly peer */
1764   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
1765   add_fake_audio_src_harness (h, 96);
1766   t->harnesses = g_list_prepend (t->harnesses, h);
1767
1768   test_validate_sdp (t, &offer, &answer);
1769
1770   test_webrtc_free (t);
1771 }
1772
1773 GST_END_TEST;
1774
1775 static void
1776 on_sdp_has_datachannel (struct test_webrtc *t, GstElement * element,
1777     GstWebRTCSessionDescription * desc, gpointer user_data)
1778 {
1779   gboolean have_data_channel = FALSE;
1780   int i;
1781
1782   for (i = 0; i < gst_sdp_message_medias_len (desc->sdp); i++) {
1783     if (_message_media_is_datachannel (desc->sdp, i)) {
1784       /* there should only be one data channel m= section */
1785       fail_unless_equals_int (FALSE, have_data_channel);
1786       have_data_channel = TRUE;
1787     }
1788   }
1789
1790   fail_unless_equals_int (TRUE, have_data_channel);
1791 }
1792
1793 static void
1794 on_channel_error_not_reached (GObject * channel, GError * error,
1795     gpointer user_data)
1796 {
1797   g_assert_not_reached ();
1798 }
1799
1800 GST_START_TEST (test_data_channel_create)
1801 {
1802   struct test_webrtc *t = test_webrtc_new ();
1803   GObject *channel = NULL;
1804   VAL_SDP_INIT (media_count, _count_num_sdp_media, GUINT_TO_POINTER (1), NULL);
1805   VAL_SDP_INIT (offer, on_sdp_has_datachannel, NULL, &media_count);
1806   gchar *label;
1807
1808   t->on_negotiation_needed = NULL;
1809   t->on_ice_candidate = NULL;
1810
1811   fail_if (gst_element_set_state (t->webrtc1,
1812           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
1813   fail_if (gst_element_set_state (t->webrtc2,
1814           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
1815
1816   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", NULL,
1817       &channel);
1818   g_assert_nonnull (channel);
1819   g_object_get (channel, "label", &label, NULL);
1820   g_assert_cmpstr (label, ==, "label");
1821   g_signal_connect (channel, "on-error",
1822       G_CALLBACK (on_channel_error_not_reached), NULL);
1823
1824   test_validate_sdp (t, &offer, &offer);
1825
1826   g_object_unref (channel);
1827   g_free (label);
1828   test_webrtc_free (t);
1829 }
1830
1831 GST_END_TEST;
1832
1833 static void
1834 have_data_channel (struct test_webrtc *t, GstElement * element,
1835     GObject * our, gpointer user_data)
1836 {
1837   GObject *other = user_data;
1838   gchar *our_label, *other_label;
1839
1840   g_signal_connect (our, "on-error", G_CALLBACK (on_channel_error_not_reached),
1841       NULL);
1842
1843   g_object_get (our, "label", &our_label, NULL);
1844   g_object_get (other, "label", &other_label, NULL);
1845
1846   g_assert_cmpstr (our_label, ==, other_label);
1847
1848   g_free (our_label);
1849   g_free (other_label);
1850
1851   test_webrtc_signal_state_unlocked (t, STATE_CUSTOM);
1852 }
1853
1854 GST_START_TEST (test_data_channel_remote_notify)
1855 {
1856   struct test_webrtc *t = test_webrtc_new ();
1857   GObject *channel = NULL;
1858   VAL_SDP_INIT (media_count, _count_num_sdp_media, GUINT_TO_POINTER (1), NULL);
1859   VAL_SDP_INIT (offer, on_sdp_has_datachannel, NULL, &media_count);
1860
1861   t->on_negotiation_needed = NULL;
1862   t->on_ice_candidate = NULL;
1863   t->on_data_channel = have_data_channel;
1864
1865   fail_if (gst_element_set_state (t->webrtc1,
1866           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
1867   fail_if (gst_element_set_state (t->webrtc2,
1868           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
1869
1870   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", NULL,
1871       &channel);
1872   g_assert_nonnull (channel);
1873   t->data_channel_data = channel;
1874   g_signal_connect (channel, "on-error",
1875       G_CALLBACK (on_channel_error_not_reached), NULL);
1876
1877   fail_if (gst_element_set_state (t->webrtc1,
1878           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
1879   fail_if (gst_element_set_state (t->webrtc2,
1880           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
1881
1882   test_validate_sdp_full (t, &offer, &offer, 1 << STATE_CUSTOM, FALSE);
1883
1884   g_object_unref (channel);
1885   test_webrtc_free (t);
1886 }
1887
1888 GST_END_TEST;
1889
1890 static const gchar *test_string = "GStreamer WebRTC is awesome!";
1891
1892 static void
1893 on_message_string (GObject * channel, const gchar * str, struct test_webrtc *t)
1894 {
1895   GstWebRTCDataChannelState state;
1896   gchar *expected;
1897
1898   g_object_get (channel, "ready-state", &state, NULL);
1899   fail_unless_equals_int (GST_WEBRTC_DATA_CHANNEL_STATE_OPEN, state);
1900
1901   expected = g_object_steal_data (channel, "expected");
1902   g_assert_cmpstr (expected, ==, str);
1903   g_free (expected);
1904
1905   test_webrtc_signal_state (t, STATE_CUSTOM);
1906 }
1907
1908 static void
1909 have_data_channel_transfer_string (struct test_webrtc *t, GstElement * element,
1910     GObject * our, gpointer user_data)
1911 {
1912   GObject *other = user_data;
1913   GstWebRTCDataChannelState state;
1914
1915   g_object_get (our, "ready-state", &state, NULL);
1916   fail_unless_equals_int (GST_WEBRTC_DATA_CHANNEL_STATE_OPEN, state);
1917
1918   g_object_set_data_full (our, "expected", g_strdup (test_string), g_free);
1919   g_signal_connect (our, "on-message-string", G_CALLBACK (on_message_string),
1920       t);
1921
1922   g_signal_connect (other, "on-error",
1923       G_CALLBACK (on_channel_error_not_reached), NULL);
1924   g_signal_emit_by_name (other, "send-string", test_string);
1925 }
1926
1927 GST_START_TEST (test_data_channel_transfer_string)
1928 {
1929   struct test_webrtc *t = test_webrtc_new ();
1930   GObject *channel = NULL;
1931   VAL_SDP_INIT (media_count, _count_num_sdp_media, GUINT_TO_POINTER (1), NULL);
1932   VAL_SDP_INIT (offer, on_sdp_has_datachannel, NULL, &media_count);
1933
1934   t->on_negotiation_needed = NULL;
1935   t->on_ice_candidate = NULL;
1936   t->on_data_channel = have_data_channel_transfer_string;
1937
1938   fail_if (gst_element_set_state (t->webrtc1,
1939           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
1940   fail_if (gst_element_set_state (t->webrtc2,
1941           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
1942
1943   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", NULL,
1944       &channel);
1945   g_assert_nonnull (channel);
1946   t->data_channel_data = channel;
1947   g_signal_connect (channel, "on-error",
1948       G_CALLBACK (on_channel_error_not_reached), NULL);
1949
1950   fail_if (gst_element_set_state (t->webrtc1,
1951           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
1952   fail_if (gst_element_set_state (t->webrtc2,
1953           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
1954
1955   test_validate_sdp_full (t, &offer, &offer, 1 << STATE_CUSTOM, FALSE);
1956
1957   g_object_unref (channel);
1958   test_webrtc_free (t);
1959 }
1960
1961 GST_END_TEST;
1962
1963 #define g_assert_cmpbytes(b1, b2)                       \
1964     G_STMT_START {                                      \
1965       gsize l1, l2;                                     \
1966       const guint8 *d1 = g_bytes_get_data (b1, &l1);    \
1967       const guint8 *d2 = g_bytes_get_data (b2, &l2);    \
1968       g_assert_cmpmem (d1, l1, d2, l2);                 \
1969     } G_STMT_END;
1970
1971 static void
1972 on_message_data (GObject * channel, GBytes * data, struct test_webrtc *t)
1973 {
1974   GstWebRTCDataChannelState state;
1975   GBytes *expected;
1976
1977   g_object_get (channel, "ready-state", &state, NULL);
1978   fail_unless_equals_int (GST_WEBRTC_DATA_CHANNEL_STATE_OPEN, state);
1979
1980   expected = g_object_steal_data (channel, "expected");
1981   g_assert_cmpbytes (data, expected);
1982   g_bytes_unref (expected);
1983
1984   test_webrtc_signal_state (t, STATE_CUSTOM);
1985 }
1986
1987 static void
1988 have_data_channel_transfer_data (struct test_webrtc *t, GstElement * element,
1989     GObject * our, gpointer user_data)
1990 {
1991   GObject *other = user_data;
1992   GBytes *data = g_bytes_new_static (test_string, strlen (test_string));
1993   GstWebRTCDataChannelState state;
1994
1995   g_object_get (our, "ready-state", &state, NULL);
1996   fail_unless_equals_int (GST_WEBRTC_DATA_CHANNEL_STATE_OPEN, state);
1997
1998   g_object_set_data_full (our, "expected", g_bytes_ref (data),
1999       (GDestroyNotify) g_bytes_unref);
2000   g_signal_connect (our, "on-message-data", G_CALLBACK (on_message_data), t);
2001
2002   g_signal_connect (other, "on-error",
2003       G_CALLBACK (on_channel_error_not_reached), NULL);
2004   g_signal_emit_by_name (other, "send-data", data);
2005   g_bytes_unref (data);
2006 }
2007
2008 GST_START_TEST (test_data_channel_transfer_data)
2009 {
2010   struct test_webrtc *t = test_webrtc_new ();
2011   GObject *channel = NULL;
2012   VAL_SDP_INIT (media_count, _count_num_sdp_media, GUINT_TO_POINTER (1), NULL);
2013   VAL_SDP_INIT (offer, on_sdp_has_datachannel, NULL, &media_count);
2014
2015   t->on_negotiation_needed = NULL;
2016   t->on_ice_candidate = NULL;
2017   t->on_data_channel = have_data_channel_transfer_data;
2018
2019   fail_if (gst_element_set_state (t->webrtc1,
2020           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
2021   fail_if (gst_element_set_state (t->webrtc2,
2022           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
2023
2024   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", NULL,
2025       &channel);
2026   g_assert_nonnull (channel);
2027   t->data_channel_data = channel;
2028   g_signal_connect (channel, "on-error",
2029       G_CALLBACK (on_channel_error_not_reached), NULL);
2030
2031   fail_if (gst_element_set_state (t->webrtc1,
2032           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2033   fail_if (gst_element_set_state (t->webrtc2,
2034           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2035
2036   test_validate_sdp_full (t, &offer, &offer, 1 << STATE_CUSTOM, FALSE);
2037
2038   g_object_unref (channel);
2039   test_webrtc_free (t);
2040 }
2041
2042 GST_END_TEST;
2043
2044 static void
2045 have_data_channel_create_data_channel (struct test_webrtc *t,
2046     GstElement * element, GObject * our, gpointer user_data)
2047 {
2048   GObject *another;
2049
2050   t->on_data_channel = have_data_channel_transfer_string;
2051
2052   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", NULL,
2053       &another);
2054   g_assert_nonnull (another);
2055   t->data_channel_data = another;
2056   t->data_channel_notify = (GDestroyNotify) g_object_unref;
2057   g_signal_connect (another, "on-error",
2058       G_CALLBACK (on_channel_error_not_reached), NULL);
2059 }
2060
2061 GST_START_TEST (test_data_channel_create_after_negotiate)
2062 {
2063   struct test_webrtc *t = test_webrtc_new ();
2064   GObject *channel = NULL;
2065   VAL_SDP_INIT (media_count, _count_num_sdp_media, GUINT_TO_POINTER (1), NULL);
2066   VAL_SDP_INIT (offer, on_sdp_has_datachannel, NULL, &media_count);
2067
2068   t->on_negotiation_needed = NULL;
2069   t->on_ice_candidate = NULL;
2070   t->on_data_channel = have_data_channel_create_data_channel;
2071
2072   fail_if (gst_element_set_state (t->webrtc1,
2073           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
2074   fail_if (gst_element_set_state (t->webrtc2,
2075           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
2076
2077   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "prev-label", NULL,
2078       &channel);
2079   g_assert_nonnull (channel);
2080   t->data_channel_data = channel;
2081   g_signal_connect (channel, "on-error",
2082       G_CALLBACK (on_channel_error_not_reached), NULL);
2083
2084   fail_if (gst_element_set_state (t->webrtc1,
2085           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2086   fail_if (gst_element_set_state (t->webrtc2,
2087           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2088
2089   test_validate_sdp_full (t, &offer, &offer, 1 << STATE_CUSTOM, FALSE);
2090
2091   g_object_unref (channel);
2092   test_webrtc_free (t);
2093 }
2094
2095 GST_END_TEST;
2096
2097 struct test_data_channel
2098 {
2099   GObject *dc1;
2100   GObject *dc2;
2101   gint n_open;
2102   gint n_closed;
2103   gint n_destroyed;
2104 };
2105
2106 static void
2107 have_data_channel_mark_open (struct test_webrtc *t,
2108     GstElement * element, GObject * our, gpointer user_data)
2109 {
2110   struct test_data_channel *tdc = t->data_channel_data;
2111
2112   tdc->dc2 = our;
2113   if (g_atomic_int_add (&tdc->n_open, 1) == 1) {
2114     test_webrtc_signal_state_unlocked (t, STATE_CUSTOM);
2115   }
2116 }
2117
2118 static gboolean
2119 is_data_channel_open (GObject * channel)
2120 {
2121   GstWebRTCDataChannelState ready_state = GST_WEBRTC_DATA_CHANNEL_STATE_CLOSED;
2122
2123   if (channel) {
2124     g_object_get (channel, "ready-state", &ready_state, NULL);
2125   }
2126
2127   return ready_state == GST_WEBRTC_DATA_CHANNEL_STATE_OPEN;
2128 }
2129
2130 static void
2131 on_data_channel_open (GObject * channel, GParamSpec * pspec,
2132     struct test_webrtc *t)
2133 {
2134   struct test_data_channel *tdc = t->data_channel_data;
2135
2136   if (is_data_channel_open (channel)) {
2137     if (g_atomic_int_add (&tdc->n_open, 1) == 1) {
2138       test_webrtc_signal_state (t, STATE_CUSTOM);
2139     }
2140   }
2141 }
2142
2143 static void
2144 on_data_channel_close (GObject * channel, GParamSpec * pspec,
2145     struct test_webrtc *t)
2146 {
2147   struct test_data_channel *tdc = t->data_channel_data;
2148   GstWebRTCDataChannelState ready_state;
2149
2150   g_object_get (channel, "ready-state", &ready_state, NULL);
2151
2152   if (ready_state == GST_WEBRTC_DATA_CHANNEL_STATE_CLOSED) {
2153     g_atomic_int_add (&tdc->n_closed, 1);
2154   }
2155 }
2156
2157 static void
2158 on_data_channel_destroyed (gpointer data, GObject * where_the_object_was)
2159 {
2160   struct test_webrtc *t = data;
2161   struct test_data_channel *tdc = t->data_channel_data;
2162
2163   if (where_the_object_was == tdc->dc1) {
2164     tdc->dc1 = NULL;
2165   } else if (where_the_object_was == tdc->dc2) {
2166     tdc->dc2 = NULL;
2167   }
2168
2169   if (g_atomic_int_add (&tdc->n_destroyed, 1) == 1) {
2170     test_webrtc_signal_state (t, STATE_CUSTOM);
2171   }
2172 }
2173
2174 GST_START_TEST (test_data_channel_close)
2175 {
2176 #define NUM_CHANNELS 3
2177   struct test_webrtc *t = test_webrtc_new ();
2178   struct test_data_channel tdc = { NULL, NULL, 0, 0, 0 };
2179   guint channel_id[NUM_CHANNELS] = { 0, 1, 2 };
2180   gulong sigid = 0;
2181   int i;
2182   VAL_SDP_INIT (media_count, _count_num_sdp_media, GUINT_TO_POINTER (1), NULL);
2183   VAL_SDP_INIT (offer, on_sdp_has_datachannel, NULL, &media_count);
2184
2185   t->on_negotiation_needed = NULL;
2186   t->on_ice_candidate = NULL;
2187   t->on_data_channel = have_data_channel_mark_open;
2188   t->data_channel_data = &tdc;
2189
2190   fail_if (gst_element_set_state (t->webrtc1,
2191           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
2192   fail_if (gst_element_set_state (t->webrtc2,
2193           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
2194
2195   /* open and close NUM_CHANNELS data channels to verify that we can reuse the
2196    * stream id of a previously closed data channel and that we have the same
2197    * behaviour no matter if we create the channel in READY or PLAYING state */
2198   for (i = 0; i < NUM_CHANNELS; i++) {
2199     tdc.n_open = 0;
2200     tdc.n_closed = 0;
2201     tdc.n_destroyed = 0;
2202
2203     g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", NULL,
2204         &tdc.dc1);
2205     g_assert_nonnull (tdc.dc1);
2206     g_object_unref (tdc.dc1);   /* webrtcbin should still hold a ref */
2207     g_object_weak_ref (tdc.dc1, on_data_channel_destroyed, t);
2208     g_signal_connect (tdc.dc1, "on-error",
2209         G_CALLBACK (on_channel_error_not_reached), NULL);
2210     sigid = g_signal_connect (tdc.dc1, "notify::ready-state",
2211         G_CALLBACK (on_data_channel_open), t);
2212
2213     if (i == 0) {
2214       fail_if (gst_element_set_state (t->webrtc1,
2215               GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2216       fail_if (gst_element_set_state (t->webrtc2,
2217               GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2218
2219       test_validate_sdp_full (t, &offer, &offer, 1 << STATE_CUSTOM, FALSE);
2220     } else {
2221       /* FIXME: Creating a data channel may result in "on-open" being sent
2222        * before we even had a chance to register the signal. For this test we
2223        * want to make sure that the channel is actually open before we try to
2224        * close it. So if we didn't receive the signal we fall back to a 1s
2225        * timeout where we explicitly check if both channels are open. */
2226       gint64 timeout = g_get_monotonic_time () + 1 * G_TIME_SPAN_SECOND;
2227       g_mutex_lock (&t->lock);
2228       while (((1 << t->state) & STATE_CUSTOM) == 0) {
2229         if (!g_cond_wait_until (&t->cond, &t->lock, timeout)) {
2230           g_assert (is_data_channel_open (tdc.dc1)
2231               && is_data_channel_open (tdc.dc2));
2232           break;
2233         }
2234       }
2235       g_mutex_unlock (&t->lock);
2236     }
2237
2238     g_object_get (tdc.dc1, "id", &channel_id[i], NULL);
2239
2240     g_signal_handler_disconnect (tdc.dc1, sigid);
2241     g_object_weak_ref (tdc.dc2, on_data_channel_destroyed, t);
2242     g_signal_connect (tdc.dc1, "notify::ready-state",
2243         G_CALLBACK (on_data_channel_close), t);
2244     g_signal_connect (tdc.dc2, "notify::ready-state",
2245         G_CALLBACK (on_data_channel_close), t);
2246     test_webrtc_signal_state (t, STATE_NEW);
2247
2248     /* currently we assume there is no renegotiation if the last data channel is
2249      * removed but if it changes this test could be extended to verify both
2250      * the behaviour of removing the last channel as well as the behaviour when
2251      * there are still data channels remaining */
2252     t->on_negotiation_needed = _negotiation_not_reached;
2253     g_signal_emit_by_name (tdc.dc1, "close");
2254
2255     test_webrtc_wait_for_state_mask (t, 1 << STATE_CUSTOM);
2256
2257     assert_equals_int (g_atomic_int_get (&tdc.n_closed), 2);
2258     assert_equals_pointer (tdc.dc1, NULL);
2259     assert_equals_pointer (tdc.dc2, NULL);
2260
2261     test_webrtc_signal_state (t, STATE_NEW);
2262   }
2263
2264   /* verify the same stream id has been reused for each data channel */
2265   assert_equals_int (channel_id[0], channel_id[1]);
2266   assert_equals_int (channel_id[0], channel_id[2]);
2267
2268   test_webrtc_free (t);
2269 #undef NUM_CHANNELS
2270 }
2271
2272 GST_END_TEST;
2273
2274 static void
2275 on_buffered_amount_low_emitted (GObject * channel, struct test_webrtc *t)
2276 {
2277   test_webrtc_signal_state (t, STATE_CUSTOM);
2278 }
2279
2280 static void
2281 have_data_channel_check_low_threshold_emitted (struct test_webrtc *t,
2282     GstElement * element, GObject * our, gpointer user_data)
2283 {
2284   g_signal_connect (our, "on-buffered-amount-low",
2285       G_CALLBACK (on_buffered_amount_low_emitted), t);
2286   g_object_set (our, "buffered-amount-low-threshold", 1, NULL);
2287
2288   g_signal_connect (our, "on-error", G_CALLBACK (on_channel_error_not_reached),
2289       NULL);
2290   g_signal_emit_by_name (our, "send-string", "A");
2291 }
2292
2293 GST_START_TEST (test_data_channel_low_threshold)
2294 {
2295   struct test_webrtc *t = test_webrtc_new ();
2296   GObject *channel = NULL;
2297   VAL_SDP_INIT (media_count, _count_num_sdp_media, GUINT_TO_POINTER (1), NULL);
2298   VAL_SDP_INIT (offer, on_sdp_has_datachannel, NULL, &media_count);
2299
2300   t->on_negotiation_needed = NULL;
2301   t->on_ice_candidate = NULL;
2302   t->on_data_channel = have_data_channel_check_low_threshold_emitted;
2303
2304   fail_if (gst_element_set_state (t->webrtc1,
2305           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
2306   fail_if (gst_element_set_state (t->webrtc2,
2307           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
2308
2309   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", NULL,
2310       &channel);
2311   g_assert_nonnull (channel);
2312   t->data_channel_data = channel;
2313   g_signal_connect (channel, "on-error",
2314       G_CALLBACK (on_channel_error_not_reached), NULL);
2315
2316   fail_if (gst_element_set_state (t->webrtc1,
2317           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2318   fail_if (gst_element_set_state (t->webrtc2,
2319           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2320
2321   test_validate_sdp_full (t, &offer, &offer, 1 << STATE_CUSTOM, FALSE);
2322
2323   g_object_unref (channel);
2324   test_webrtc_free (t);
2325 }
2326
2327 GST_END_TEST;
2328
2329 static void
2330 on_channel_error (GObject * channel, GError * error, struct test_webrtc *t)
2331 {
2332   g_assert_nonnull (error);
2333
2334   test_webrtc_signal_state (t, STATE_CUSTOM);
2335 }
2336
2337 static void
2338 have_data_channel_transfer_large_data (struct test_webrtc *t,
2339     GstElement * element, GObject * our, gpointer user_data)
2340 {
2341   GObject *other = user_data;
2342   const gsize size = 1024 * 1024;
2343   guint8 *random_data = g_new (guint8, size);
2344   GBytes *data;
2345   gsize i;
2346
2347   for (i = 0; i < size; i++)
2348     random_data[i] = (guint8) (i & 0xff);
2349
2350   data = g_bytes_new_with_free_func (random_data, size,
2351       (GDestroyNotify) g_free, random_data);
2352
2353   g_object_set_data_full (our, "expected", g_bytes_ref (data),
2354       (GDestroyNotify) g_bytes_unref);
2355   g_signal_connect (our, "on-message-data", G_CALLBACK (on_message_data), t);
2356
2357   g_signal_connect (other, "on-error", G_CALLBACK (on_channel_error), t);
2358   g_signal_emit_by_name (other, "send-data", data);
2359   g_bytes_unref (data);
2360 }
2361
2362 GST_START_TEST (test_data_channel_max_message_size)
2363 {
2364   struct test_webrtc *t = test_webrtc_new ();
2365   GObject *channel = NULL;
2366   VAL_SDP_INIT (media_count, _count_num_sdp_media, GUINT_TO_POINTER (1), NULL);
2367   VAL_SDP_INIT (offer, on_sdp_has_datachannel, NULL, &media_count);
2368
2369   t->on_negotiation_needed = NULL;
2370   t->on_ice_candidate = NULL;
2371   t->on_data_channel = have_data_channel_transfer_large_data;
2372
2373   fail_if (gst_element_set_state (t->webrtc1,
2374           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
2375   fail_if (gst_element_set_state (t->webrtc2,
2376           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
2377
2378   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", NULL,
2379       &channel);
2380   g_assert_nonnull (channel);
2381   t->data_channel_data = channel;
2382
2383   fail_if (gst_element_set_state (t->webrtc1,
2384           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2385   fail_if (gst_element_set_state (t->webrtc2,
2386           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2387
2388   test_validate_sdp_full (t, &offer, &offer, 1 << STATE_CUSTOM, FALSE);
2389
2390   g_object_unref (channel);
2391   test_webrtc_free (t);
2392 }
2393
2394 GST_END_TEST;
2395
2396 static void
2397 _on_ready_state_notify (GObject * channel, GParamSpec * pspec,
2398     struct test_webrtc *t)
2399 {
2400   gint *n_ready = t->data_channel_data;
2401   GstWebRTCDataChannelState ready_state;
2402
2403   g_object_get (channel, "ready-state", &ready_state, NULL);
2404
2405   if (ready_state == GST_WEBRTC_DATA_CHANNEL_STATE_OPEN) {
2406     if (g_atomic_int_add (n_ready, 1) >= 1) {
2407       test_webrtc_signal_state (t, STATE_CUSTOM);
2408     }
2409   }
2410 }
2411
2412 GST_START_TEST (test_data_channel_pre_negotiated)
2413 {
2414   struct test_webrtc *t = test_webrtc_new ();
2415   GObject *channel1 = NULL, *channel2 = NULL;
2416   VAL_SDP_INIT (media_count, _count_num_sdp_media, GUINT_TO_POINTER (1), NULL);
2417   VAL_SDP_INIT (offer, on_sdp_has_datachannel, NULL, &media_count);
2418   GstStructure *s;
2419   gint n_ready = 0;
2420
2421   t->on_negotiation_needed = NULL;
2422   t->on_ice_candidate = NULL;
2423
2424   fail_if (gst_element_set_state (t->webrtc1,
2425           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
2426   fail_if (gst_element_set_state (t->webrtc2,
2427           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
2428
2429   s = gst_structure_new ("application/data-channel", "negotiated",
2430       G_TYPE_BOOLEAN, TRUE, "id", G_TYPE_INT, 1, NULL);
2431
2432   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", s,
2433       &channel1);
2434   g_assert_nonnull (channel1);
2435   g_signal_emit_by_name (t->webrtc2, "create-data-channel", "label", s,
2436       &channel2);
2437   g_assert_nonnull (channel2);
2438
2439   fail_if (gst_element_set_state (t->webrtc1,
2440           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2441   fail_if (gst_element_set_state (t->webrtc2,
2442           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2443
2444   test_validate_sdp_full (t, &offer, &offer, 0, FALSE);
2445
2446   t->data_channel_data = &n_ready;
2447
2448   g_signal_connect (channel1, "notify::ready-state",
2449       G_CALLBACK (_on_ready_state_notify), t);
2450   g_signal_connect (channel2, "notify::ready-state",
2451       G_CALLBACK (_on_ready_state_notify), t);
2452
2453   test_webrtc_wait_for_state_mask (t, 1 << STATE_CUSTOM);
2454   test_webrtc_signal_state (t, STATE_NEW);
2455
2456   have_data_channel_transfer_string (t, t->webrtc1, channel1, channel2);
2457
2458   test_webrtc_wait_for_state_mask (t, 1 << STATE_CUSTOM);
2459
2460   g_object_unref (channel1);
2461   g_object_unref (channel2);
2462   gst_structure_free (s);
2463   test_webrtc_free (t);
2464 }
2465
2466 GST_END_TEST;
2467
2468 static void
2469 _count_non_rejected_media (struct test_webrtc *t, GstElement * element,
2470     GstWebRTCSessionDescription * sd, gpointer user_data)
2471 {
2472   guint expected = GPOINTER_TO_UINT (user_data);
2473   guint non_rejected_media;
2474   guint i;
2475
2476   non_rejected_media = 0;
2477
2478   for (i = 0; i < gst_sdp_message_medias_len (sd->sdp); i++) {
2479     const GstSDPMedia *media = gst_sdp_message_get_media (sd->sdp, i);
2480
2481     if (gst_sdp_media_get_port (media) != 0)
2482       non_rejected_media += 1;
2483   }
2484
2485   fail_unless_equals_int (non_rejected_media, expected);
2486 }
2487
2488 static void
2489 _check_bundle_tag (struct test_webrtc *t, GstElement * element,
2490     GstWebRTCSessionDescription * sd, gpointer user_data)
2491 {
2492   gchar **bundled = NULL;
2493   GStrv expected = user_data;
2494   guint i;
2495
2496   fail_unless (_parse_bundle (sd->sdp, &bundled, NULL));
2497
2498   if (!bundled) {
2499     fail_unless_equals_int (g_strv_length (expected), 0);
2500   } else {
2501     fail_unless_equals_int (g_strv_length (bundled), g_strv_length (expected));
2502   }
2503
2504   for (i = 0; i < g_strv_length (expected); i++) {
2505     fail_unless (g_strv_contains ((const gchar **) bundled, expected[i]));
2506   }
2507
2508   g_strfreev (bundled);
2509 }
2510
2511 static void
2512 _check_bundle_only_media (struct test_webrtc *t, GstElement * element,
2513     GstWebRTCSessionDescription * sd, gpointer user_data)
2514 {
2515   gchar **expected_bundle_only = user_data;
2516   guint i;
2517
2518   for (i = 0; i < gst_sdp_message_medias_len (sd->sdp); i++) {
2519     const GstSDPMedia *media = gst_sdp_message_get_media (sd->sdp, i);
2520     const gchar *mid = gst_sdp_media_get_attribute_val (media, "mid");
2521
2522     if (g_strv_contains ((const gchar **) expected_bundle_only, mid))
2523       fail_unless (_media_has_attribute_key (media, "bundle-only"));
2524   }
2525 }
2526
2527 GST_START_TEST (test_bundle_audio_video_max_bundle_max_bundle)
2528 {
2529   struct test_webrtc *t = create_audio_video_test ();
2530   const gchar *bundle[] = { "audio0", "video1", NULL };
2531   const gchar *offer_bundle_only[] = { "video1", NULL };
2532   const gchar *answer_bundle_only[] = { NULL };
2533
2534   guint media_format_count[] = { 1, 1, };
2535   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
2536       media_format_count, NULL);
2537   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
2538       &media_formats);
2539   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
2540   VAL_SDP_INIT (bundle_tag, _check_bundle_tag, bundle, &payloads);
2541   VAL_SDP_INIT (offer_non_reject, _count_non_rejected_media,
2542       GUINT_TO_POINTER (1), &bundle_tag);
2543   VAL_SDP_INIT (answer_non_reject, _count_non_rejected_media,
2544       GUINT_TO_POINTER (2), &bundle_tag);
2545   VAL_SDP_INIT (offer_bundle, _check_bundle_only_media, &offer_bundle_only,
2546       &offer_non_reject);
2547   VAL_SDP_INIT (answer_bundle, _check_bundle_only_media, &answer_bundle_only,
2548       &answer_non_reject);
2549   const gchar *expected_offer_setup[] = { "actpass", "actpass" };
2550   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
2551       &offer_bundle);
2552   const gchar *expected_answer_setup[] = { "active", "active" };
2553   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
2554       &answer_bundle);
2555   const gchar *expected_offer_direction[] = { "sendrecv", "sendrecv" };
2556   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
2557       &offer_setup);
2558   const gchar *expected_answer_direction[] = { "recvonly", "recvonly" };
2559   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
2560       &answer_setup);
2561
2562   /* We set a max-bundle policy on the offering webrtcbin,
2563    * this means that all the offered medias should be part
2564    * of the group:BUNDLE attribute, and they should be marked
2565    * as bundle-only
2566    */
2567   gst_util_set_object_arg (G_OBJECT (t->webrtc1), "bundle-policy",
2568       "max-bundle");
2569   /* We also set a max-bundle policy on the answering webrtcbin,
2570    * this means that all the offered medias should be part
2571    * of the group:BUNDLE attribute, but need not be marked
2572    * as bundle-only.
2573    */
2574   gst_util_set_object_arg (G_OBJECT (t->webrtc2), "bundle-policy",
2575       "max-bundle");
2576
2577   test_validate_sdp (t, &offer, &answer);
2578
2579   test_webrtc_free (t);
2580 }
2581
2582 GST_END_TEST;
2583
2584 GST_START_TEST (test_bundle_audio_video_max_compat_max_bundle)
2585 {
2586   struct test_webrtc *t = create_audio_video_test ();
2587   const gchar *bundle[] = { "audio0", "video1", NULL };
2588   const gchar *bundle_only[] = { NULL };
2589
2590   guint media_format_count[] = { 1, 1, };
2591   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
2592       media_format_count, NULL);
2593   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
2594       &media_formats);
2595   VAL_SDP_INIT (bundle_tag, _check_bundle_tag, bundle, &count);
2596   VAL_SDP_INIT (count_non_reject, _count_non_rejected_media,
2597       GUINT_TO_POINTER (2), &bundle_tag);
2598   VAL_SDP_INIT (bundle_sdp, _check_bundle_only_media, &bundle_only,
2599       &count_non_reject);
2600   const gchar *expected_offer_setup[] = { "actpass", "actpass" };
2601   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
2602       &bundle_sdp);
2603   const gchar *expected_answer_setup[] = { "active", "active" };
2604   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
2605       &bundle_sdp);
2606   const gchar *expected_offer_direction[] = { "sendrecv", "sendrecv" };
2607   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
2608       &offer_setup);
2609   const gchar *expected_answer_direction[] = { "recvonly", "recvonly" };
2610   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
2611       &answer_setup);
2612
2613   /* We set a max-compat policy on the offering webrtcbin,
2614    * this means that all the offered medias should be part
2615    * of the group:BUNDLE attribute, and they should *not* be marked
2616    * as bundle-only
2617    */
2618   gst_util_set_object_arg (G_OBJECT (t->webrtc1), "bundle-policy",
2619       "max-compat");
2620   /* We set a max-bundle policy on the answering webrtcbin,
2621    * this means that all the offered medias should be part
2622    * of the group:BUNDLE attribute, but need not be marked
2623    * as bundle-only.
2624    */
2625   gst_util_set_object_arg (G_OBJECT (t->webrtc2), "bundle-policy",
2626       "max-bundle");
2627
2628   test_validate_sdp (t, &offer, &answer);
2629
2630   test_webrtc_free (t);
2631 }
2632
2633 GST_END_TEST;
2634
2635 GST_START_TEST (test_bundle_audio_video_max_bundle_none)
2636 {
2637   struct test_webrtc *t = create_audio_video_test ();
2638   const gchar *offer_mid[] = { "audio0", "video1", NULL };
2639   const gchar *offer_bundle_only[] = { "video1", NULL };
2640   const gchar *answer_mid[] = { NULL };
2641   const gchar *answer_bundle_only[] = { NULL };
2642
2643   guint media_format_count[] = { 1, 1, };
2644   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
2645       media_format_count, NULL);
2646   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
2647       &media_formats);
2648   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
2649   VAL_SDP_INIT (count_non_reject, _count_non_rejected_media,
2650       GUINT_TO_POINTER (1), &payloads);
2651   VAL_SDP_INIT (offer_bundle_tag, _check_bundle_tag, offer_mid,
2652       &count_non_reject);
2653   VAL_SDP_INIT (answer_bundle_tag, _check_bundle_tag, answer_mid,
2654       &count_non_reject);
2655   VAL_SDP_INIT (offer_bundle, _check_bundle_only_media, &offer_bundle_only,
2656       &offer_bundle_tag);
2657   VAL_SDP_INIT (answer_bundle, _check_bundle_only_media, &answer_bundle_only,
2658       &answer_bundle_tag);
2659   const gchar *expected_offer_setup[] = { "actpass", "actpass" };
2660   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
2661       &offer_bundle);
2662   const gchar *expected_answer_setup[] = { "active", "active" };
2663   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
2664       &answer_bundle);
2665   const gchar *expected_offer_direction[] = { "sendrecv", "sendrecv" };
2666   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
2667       &offer_setup);
2668   const gchar *expected_answer_direction[] = { "recvonly", "recvonly" };
2669   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
2670       &answer_setup);
2671
2672   /* We set a max-bundle policy on the offering webrtcbin,
2673    * this means that all the offered medias should be part
2674    * of the group:BUNDLE attribute, and they should be marked
2675    * as bundle-only
2676    */
2677   gst_util_set_object_arg (G_OBJECT (t->webrtc1), "bundle-policy",
2678       "max-bundle");
2679   /* We set a none policy on the answering webrtcbin,
2680    * this means that the answer should contain no bundled
2681    * medias, and as the bundle-policy of the offering webrtcbin
2682    * is set to max-bundle, only one media should be active.
2683    */
2684   gst_util_set_object_arg (G_OBJECT (t->webrtc2), "bundle-policy", "none");
2685
2686   test_validate_sdp (t, &offer, &answer);
2687
2688   test_webrtc_free (t);
2689 }
2690
2691 GST_END_TEST;
2692
2693 GST_START_TEST (test_bundle_audio_video_data)
2694 {
2695   struct test_webrtc *t = create_audio_video_test ();
2696   const gchar *mids[] = { "audio0", "video1", "application2", NULL };
2697   const gchar *offer_bundle_only[] = { "video1", "application2", NULL };
2698   const gchar *answer_bundle_only[] = { NULL };
2699   GObject *channel = NULL;
2700
2701   guint media_format_count[] = { 1, 1, 1 };
2702   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
2703       media_format_count, NULL);
2704   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (3),
2705       &media_formats);
2706   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
2707   VAL_SDP_INIT (bundle_tag, _check_bundle_tag, mids, &payloads);
2708   VAL_SDP_INIT (offer_non_reject, _count_non_rejected_media,
2709       GUINT_TO_POINTER (1), &bundle_tag);
2710   VAL_SDP_INIT (answer_non_reject, _count_non_rejected_media,
2711       GUINT_TO_POINTER (3), &bundle_tag);
2712   VAL_SDP_INIT (offer_bundle, _check_bundle_only_media, &offer_bundle_only,
2713       &offer_non_reject);
2714   VAL_SDP_INIT (answer_bundle, _check_bundle_only_media, &answer_bundle_only,
2715       &answer_non_reject);
2716   const gchar *expected_offer_setup[] = { "actpass", "actpass", "actpass" };
2717   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
2718       &offer_bundle);
2719   const gchar *expected_answer_setup[] = { "active", "active", "active" };
2720   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
2721       &answer_bundle);
2722   const gchar *expected_offer_direction[] =
2723       { "sendrecv", "sendrecv", "sendrecv" };
2724   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
2725       &offer_setup);
2726   const gchar *expected_answer_direction[] =
2727       { "recvonly", "recvonly", "recvonly" };
2728   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
2729       &answer_setup);
2730
2731   /* We set a max-bundle policy on the offering webrtcbin,
2732    * this means that all the offered medias should be part
2733    * of the group:BUNDLE attribute, and they should be marked
2734    * as bundle-only
2735    */
2736   gst_util_set_object_arg (G_OBJECT (t->webrtc1), "bundle-policy",
2737       "max-bundle");
2738   /* We also set a max-bundle policy on the answering webrtcbin,
2739    * this means that all the offered medias should be part
2740    * of the group:BUNDLE attribute, but need not be marked
2741    * as bundle-only.
2742    */
2743   gst_util_set_object_arg (G_OBJECT (t->webrtc2), "bundle-policy",
2744       "max-bundle");
2745
2746   fail_if (gst_element_set_state (t->webrtc1,
2747           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
2748   fail_if (gst_element_set_state (t->webrtc2,
2749           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
2750
2751   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", NULL,
2752       &channel);
2753
2754   test_validate_sdp (t, &offer, &answer);
2755
2756   g_object_unref (channel);
2757   test_webrtc_free (t);
2758 }
2759
2760 GST_END_TEST;
2761
2762 GST_START_TEST (test_duplicate_nego)
2763 {
2764   struct test_webrtc *t = create_audio_video_test ();
2765   guint media_format_count[] = { 1, 1, };
2766   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
2767       media_format_count, NULL);
2768   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
2769       &media_formats);
2770   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
2771   const gchar *expected_offer_setup[] = { "actpass", "actpass" };
2772   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
2773       &payloads);
2774   const gchar *expected_answer_setup[] = { "active", "active" };
2775   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
2776       &payloads);
2777   const gchar *expected_offer_direction[] = { "sendrecv", "sendrecv" };
2778   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
2779       &offer_setup);
2780   const gchar *expected_answer_direction[] = { "sendrecv", "recvonly" };
2781   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
2782       &answer_setup);
2783   GstHarness *h;
2784   guint negotiation_flag = 0;
2785
2786   /* check that negotiating twice succeeds */
2787
2788   t->on_negotiation_needed = on_negotiation_needed_hit;
2789   t->negotiation_data = &negotiation_flag;
2790
2791   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
2792   add_fake_audio_src_harness (h, 96);
2793   t->harnesses = g_list_prepend (t->harnesses, h);
2794
2795   test_validate_sdp (t, &offer, &answer);
2796   fail_unless (negotiation_flag & (1 << 2));
2797
2798   test_webrtc_reset_negotiation (t);
2799   test_validate_sdp (t, &offer, &answer);
2800
2801   test_webrtc_free (t);
2802 }
2803
2804 GST_END_TEST;
2805
2806 GST_START_TEST (test_dual_audio)
2807 {
2808   struct test_webrtc *t = create_audio_test ();
2809   guint media_format_count[] = { 1, 1, };
2810   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
2811       media_format_count, NULL);
2812   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
2813       &media_formats);
2814   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
2815   const gchar *expected_offer_setup[] = { "actpass", "actpass" };
2816   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
2817       &payloads);
2818   const gchar *expected_answer_setup[] = { "active", "active" };
2819   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
2820       &payloads);
2821   const gchar *expected_offer_direction[] = { "sendrecv", "sendrecv" };
2822   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
2823       &offer_setup);
2824   const gchar *expected_answer_direction[] = { "sendrecv", "recvonly" };
2825   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
2826       &answer_setup);
2827   GstHarness *h;
2828   GstWebRTCRTPTransceiver *trans;
2829   GArray *transceivers;
2830   guint mline;
2831
2832   /* test that each mline gets a unique transceiver even with the same caps */
2833
2834   h = gst_harness_new_with_element (t->webrtc1, "sink_1", NULL);
2835   add_fake_audio_src_harness (h, 96);
2836   t->harnesses = g_list_prepend (t->harnesses, h);
2837
2838   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
2839   add_fake_audio_src_harness (h, 96);
2840   t->harnesses = g_list_prepend (t->harnesses, h);
2841
2842   t->on_negotiation_needed = NULL;
2843   test_validate_sdp (t, &offer, &answer);
2844
2845   g_signal_emit_by_name (t->webrtc1, "get-transceivers", &transceivers);
2846   fail_unless (transceivers != NULL);
2847   fail_unless_equals_int (2, transceivers->len);
2848
2849   trans = g_array_index (transceivers, GstWebRTCRTPTransceiver *, 0);
2850   fail_unless (trans != NULL);
2851   g_object_get (trans, "mlineindex", &mline, NULL);
2852   fail_unless_equals_int (mline, 0);
2853
2854   trans = g_array_index (transceivers, GstWebRTCRTPTransceiver *, 1);
2855   fail_unless (trans != NULL);
2856   g_object_get (trans, "mlineindex", &mline, NULL);
2857   fail_unless_equals_int (mline, 1);
2858
2859   g_array_unref (transceivers);
2860   test_webrtc_free (t);
2861 }
2862
2863 GST_END_TEST;
2864
2865 static void
2866 sdp_increasing_session_version (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   guint64 our_v, previous_v;
2873
2874   prop =
2875       TEST_SDP_IS_LOCAL (t, element,
2876       desc) ? "current-local-description" : "current-remote-description";
2877   g_object_get (element, prop, &previous, NULL);
2878
2879   our_origin = gst_sdp_message_get_origin (desc->sdp);
2880   previous_origin = gst_sdp_message_get_origin (previous->sdp);
2881
2882   our_v = g_ascii_strtoull (our_origin->sess_version, NULL, 10);
2883   previous_v = g_ascii_strtoull (previous_origin->sess_version, NULL, 10);
2884
2885   ck_assert_int_lt (previous_v, our_v);
2886
2887   gst_webrtc_session_description_free (previous);
2888 }
2889
2890 static void
2891 sdp_equal_session_id (struct test_webrtc *t, GstElement * element,
2892     GstWebRTCSessionDescription * desc, gpointer user_data)
2893 {
2894   GstWebRTCSessionDescription *previous;
2895   const GstSDPOrigin *our_origin, *previous_origin;
2896   const gchar *prop;
2897
2898   prop =
2899       TEST_SDP_IS_LOCAL (t, element,
2900       desc) ? "current-local-description" : "current-remote-description";
2901   g_object_get (element, prop, &previous, NULL);
2902
2903   our_origin = gst_sdp_message_get_origin (desc->sdp);
2904   previous_origin = gst_sdp_message_get_origin (previous->sdp);
2905
2906   fail_unless_equals_string (previous_origin->sess_id, our_origin->sess_id);
2907   gst_webrtc_session_description_free (previous);
2908 }
2909
2910 static void
2911 sdp_media_equal_attribute (struct test_webrtc *t, GstElement * element,
2912     GstWebRTCSessionDescription * desc, GstWebRTCSessionDescription * previous,
2913     const gchar * attr)
2914 {
2915   guint i, n;
2916
2917   n = MIN (gst_sdp_message_medias_len (previous->sdp),
2918       gst_sdp_message_medias_len (desc->sdp));
2919
2920   for (i = 0; i < n; i++) {
2921     const GstSDPMedia *our_media, *other_media;
2922     const gchar *our_mid, *other_mid;
2923
2924     our_media = gst_sdp_message_get_media (desc->sdp, i);
2925     other_media = gst_sdp_message_get_media (previous->sdp, i);
2926
2927     our_mid = gst_sdp_media_get_attribute_val (our_media, attr);
2928     other_mid = gst_sdp_media_get_attribute_val (other_media, attr);
2929
2930     fail_unless_equals_string (our_mid, other_mid);
2931   }
2932 }
2933
2934 static void
2935 sdp_media_equal_mid (struct test_webrtc *t, GstElement * element,
2936     GstWebRTCSessionDescription * desc, gpointer user_data)
2937 {
2938   GstWebRTCSessionDescription *previous;
2939   const gchar *prop;
2940
2941   prop =
2942       TEST_SDP_IS_LOCAL (t, element,
2943       desc) ? "current-local-description" : "current-remote-description";
2944   g_object_get (element, prop, &previous, NULL);
2945
2946   sdp_media_equal_attribute (t, element, desc, previous, "mid");
2947
2948   gst_webrtc_session_description_free (previous);
2949 }
2950
2951 static void
2952 sdp_media_equal_ice_params (struct test_webrtc *t, GstElement * element,
2953     GstWebRTCSessionDescription * desc, gpointer user_data)
2954 {
2955   GstWebRTCSessionDescription *previous;
2956   const gchar *prop;
2957
2958   prop =
2959       TEST_SDP_IS_LOCAL (t, element,
2960       desc) ? "current-local-description" : "current-remote-description";
2961   g_object_get (element, prop, &previous, NULL);
2962
2963   sdp_media_equal_attribute (t, element, desc, previous, "ice-ufrag");
2964   sdp_media_equal_attribute (t, element, desc, previous, "ice-pwd");
2965
2966   gst_webrtc_session_description_free (previous);
2967 }
2968
2969 static void
2970 sdp_media_equal_fingerprint (struct test_webrtc *t, GstElement * element,
2971     GstWebRTCSessionDescription * desc, gpointer user_data)
2972 {
2973   GstWebRTCSessionDescription *previous;
2974   const gchar *prop;
2975
2976   prop =
2977       TEST_SDP_IS_LOCAL (t, element,
2978       desc) ? "current-local-description" : "current-remote-description";
2979   g_object_get (element, prop, &previous, NULL);
2980
2981   sdp_media_equal_attribute (t, element, desc, previous, "fingerprint");
2982
2983   gst_webrtc_session_description_free (previous);
2984 }
2985
2986 GST_START_TEST (test_renego_add_stream)
2987 {
2988   struct test_webrtc *t = create_audio_video_test ();
2989   guint media_format_count[] = { 1, 1, 1 };
2990   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
2991       media_format_count, NULL);
2992   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
2993       &media_formats);
2994   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
2995   const gchar *expected_offer_setup[] = { "actpass", "actpass", "actpass" };
2996   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
2997       &payloads);
2998   const gchar *expected_answer_setup[] = { "active", "active", "active" };
2999   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
3000       &payloads);
3001   const gchar *expected_offer_direction[] =
3002       { "sendrecv", "sendrecv", "sendrecv" };
3003   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
3004       &offer_setup);
3005   const gchar *expected_answer_direction[] =
3006       { "sendrecv", "recvonly", "recvonly" };
3007   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
3008       &answer_setup);
3009   VAL_SDP_INIT (renego_mid, sdp_media_equal_mid, NULL, NULL);
3010   VAL_SDP_INIT (renego_ice_params, sdp_media_equal_ice_params, NULL,
3011       &renego_mid);
3012   VAL_SDP_INIT (renego_sess_id, sdp_equal_session_id, NULL, &renego_ice_params);
3013   VAL_SDP_INIT (renego_sess_ver, sdp_increasing_session_version, NULL,
3014       &renego_sess_id);
3015   VAL_SDP_INIT (renego_fingerprint, sdp_media_equal_fingerprint, NULL,
3016       &renego_sess_ver);
3017   GstHarness *h;
3018
3019   /* negotiate an AV stream and then renegotiate an extra stream */
3020   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
3021   add_fake_audio_src_harness (h, 96);
3022   t->harnesses = g_list_prepend (t->harnesses, h);
3023
3024   test_validate_sdp (t, &offer, &answer);
3025
3026   h = gst_harness_new_with_element (t->webrtc1, "sink_2", NULL);
3027   add_fake_audio_src_harness (h, 98);
3028   t->harnesses = g_list_prepend (t->harnesses, h);
3029
3030   media_formats.next = &renego_fingerprint;
3031   count.user_data = GUINT_TO_POINTER (3);
3032
3033   /* renegotiate! */
3034   test_webrtc_reset_negotiation (t);
3035   test_validate_sdp (t, &offer, &answer);
3036
3037   test_webrtc_free (t);
3038 }
3039
3040 GST_END_TEST;
3041
3042 GST_START_TEST (test_renego_stream_add_data_channel)
3043 {
3044   struct test_webrtc *t = create_audio_video_test ();
3045
3046   guint media_format_count[] = { 1, 1, 1 };
3047   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
3048       media_format_count, NULL);
3049   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
3050       &media_formats);
3051   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
3052   const gchar *expected_offer_setup[] = { "actpass", "actpass", "actpass" };
3053   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
3054       &payloads);
3055   const gchar *expected_answer_setup[] = { "active", "active", "active" };
3056   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
3057       &payloads);
3058   const gchar *expected_offer_direction[] = { "sendrecv", "sendrecv", NULL };
3059   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
3060       &offer_setup);
3061   const gchar *expected_answer_direction[] = { "sendrecv", "recvonly", NULL };
3062   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
3063       &answer_setup);
3064   VAL_SDP_INIT (renego_mid, sdp_media_equal_mid, NULL, NULL);
3065   VAL_SDP_INIT (renego_ice_params, sdp_media_equal_ice_params, NULL,
3066       &renego_mid);
3067   VAL_SDP_INIT (renego_sess_id, sdp_equal_session_id, NULL, &renego_ice_params);
3068   VAL_SDP_INIT (renego_sess_ver, sdp_increasing_session_version, NULL,
3069       &renego_sess_id);
3070   VAL_SDP_INIT (renego_fingerprint, sdp_media_equal_fingerprint, NULL,
3071       &renego_sess_ver);
3072   GObject *channel;
3073   GstHarness *h;
3074
3075   /* negotiate an AV stream and then renegotiate a data channel */
3076   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
3077   add_fake_audio_src_harness (h, 96);
3078   t->harnesses = g_list_prepend (t->harnesses, h);
3079
3080   test_validate_sdp (t, &offer, &answer);
3081
3082   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", NULL,
3083       &channel);
3084
3085   media_formats.next = &renego_fingerprint;
3086   count.user_data = GUINT_TO_POINTER (3);
3087
3088   /* renegotiate! */
3089   test_webrtc_reset_negotiation (t);
3090   test_validate_sdp (t, &offer, &answer);
3091
3092   g_object_unref (channel);
3093   test_webrtc_free (t);
3094 }
3095
3096 GST_END_TEST;
3097
3098 GST_START_TEST (test_renego_data_channel_add_stream)
3099 {
3100   struct test_webrtc *t = test_webrtc_new ();
3101   guint media_format_count[] = { 1, 1, 1 };
3102   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
3103       media_format_count, NULL);
3104   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (1),
3105       &media_formats);
3106   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
3107   const gchar *expected_offer_setup[] = { "actpass", "actpass" };
3108   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
3109       &payloads);
3110   const gchar *expected_answer_setup[] = { "active", "active" };
3111   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
3112       &payloads);
3113   const gchar *expected_offer_direction[] = { NULL, "sendrecv" };
3114   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
3115       &offer_setup);
3116   const gchar *expected_answer_direction[] = { NULL, "recvonly" };
3117   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
3118       &answer_setup);
3119   VAL_SDP_INIT (renego_mid, sdp_media_equal_mid, NULL, NULL);
3120   VAL_SDP_INIT (renego_ice_params, sdp_media_equal_ice_params, NULL,
3121       &renego_mid);
3122   VAL_SDP_INIT (renego_sess_id, sdp_equal_session_id, NULL, &renego_ice_params);
3123   VAL_SDP_INIT (renego_sess_ver, sdp_increasing_session_version, NULL,
3124       &renego_sess_id);
3125   VAL_SDP_INIT (renego_fingerprint, sdp_media_equal_fingerprint, NULL,
3126       &renego_sess_ver);
3127   GObject *channel;
3128   GstHarness *h;
3129
3130   /* negotiate an data channel and then renegotiate to add a av stream */
3131   t->on_negotiation_needed = NULL;
3132   t->on_ice_candidate = NULL;
3133   t->on_data_channel = NULL;
3134   t->on_pad_added = _pad_added_fakesink;
3135
3136   fail_if (gst_element_set_state (t->webrtc1,
3137           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
3138   fail_if (gst_element_set_state (t->webrtc2,
3139           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
3140
3141   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", NULL,
3142       &channel);
3143
3144   test_validate_sdp_full (t, &offer, &answer, 0, FALSE);
3145
3146   h = gst_harness_new_with_element (t->webrtc1, "sink_1", NULL);
3147   add_fake_audio_src_harness (h, 97);
3148   t->harnesses = g_list_prepend (t->harnesses, h);
3149
3150   media_formats.next = &renego_fingerprint;
3151   count.user_data = GUINT_TO_POINTER (2);
3152
3153   /* renegotiate! */
3154   test_webrtc_reset_negotiation (t);
3155   test_validate_sdp_full (t, &offer, &answer, 0, FALSE);
3156
3157   g_object_unref (channel);
3158   test_webrtc_free (t);
3159 }
3160
3161 GST_END_TEST;
3162
3163
3164 GST_START_TEST (test_renego_stream_data_channel_add_stream)
3165 {
3166   struct test_webrtc *t = test_webrtc_new ();
3167   guint media_format_count[] = { 1, 1, 1 };
3168   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
3169       media_format_count, NULL);
3170   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
3171       &media_formats);
3172   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
3173   const gchar *expected_offer_setup[] = { "actpass", "actpass", "actpass" };
3174   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
3175       &payloads);
3176   const gchar *expected_answer_setup[] = { "active", "active", "active" };
3177   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
3178       &payloads);
3179   const gchar *expected_offer_direction[] = { "sendrecv", NULL, "sendrecv" };
3180   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
3181       &offer_setup);
3182   const gchar *expected_answer_direction[] = { "recvonly", NULL, "recvonly" };
3183   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
3184       &answer_setup);
3185   VAL_SDP_INIT (renego_mid, sdp_media_equal_mid, NULL, NULL);
3186   VAL_SDP_INIT (renego_ice_params, sdp_media_equal_ice_params, NULL,
3187       &renego_mid);
3188   VAL_SDP_INIT (renego_sess_id, sdp_equal_session_id, NULL, &renego_ice_params);
3189   VAL_SDP_INIT (renego_sess_ver, sdp_increasing_session_version, NULL,
3190       &renego_sess_id);
3191   VAL_SDP_INIT (renego_fingerprint, sdp_media_equal_fingerprint, NULL,
3192       &renego_sess_ver);
3193   GObject *channel;
3194   GstHarness *h;
3195
3196   /* Negotiate a stream and a data channel, then renogotiate with a new stream */
3197   t->on_negotiation_needed = NULL;
3198   t->on_ice_candidate = NULL;
3199   t->on_data_channel = NULL;
3200   t->on_pad_added = _pad_added_fakesink;
3201
3202   h = gst_harness_new_with_element (t->webrtc1, "sink_0", NULL);
3203   add_fake_audio_src_harness (h, 97);
3204   t->harnesses = g_list_prepend (t->harnesses, h);
3205
3206   fail_if (gst_element_set_state (t->webrtc1,
3207           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
3208   fail_if (gst_element_set_state (t->webrtc2,
3209           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
3210
3211   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", NULL,
3212       &channel);
3213
3214   test_validate_sdp_full (t, &offer, &answer, 0, FALSE);
3215
3216   h = gst_harness_new_with_element (t->webrtc1, "sink_2", NULL);
3217   add_fake_audio_src_harness (h, 97);
3218   t->harnesses = g_list_prepend (t->harnesses, h);
3219
3220   media_formats.next = &renego_fingerprint;
3221   count.user_data = GUINT_TO_POINTER (3);
3222
3223   /* renegotiate! */
3224   test_webrtc_reset_negotiation (t);
3225   test_validate_sdp_full (t, &offer, &answer, 0, FALSE);
3226
3227   g_object_unref (channel);
3228   test_webrtc_free (t);
3229 }
3230
3231 GST_END_TEST;
3232
3233 GST_START_TEST (test_bundle_renego_add_stream)
3234 {
3235   struct test_webrtc *t = create_audio_video_test ();
3236   const gchar *bundle[] = { "audio0", "video1", "audio2", NULL };
3237   const gchar *offer_bundle_only[] = { "video1", "audio2", NULL };
3238   const gchar *answer_bundle_only[] = { NULL };
3239   guint media_format_count[] = { 1, 1, 1 };
3240   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
3241       media_format_count, NULL);
3242   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
3243       &media_formats);
3244   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
3245   const gchar *expected_offer_setup[] = { "actpass", "actpass", "actpass" };
3246   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
3247       &payloads);
3248   const gchar *expected_answer_setup[] = { "active", "active", "active" };
3249   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
3250       &payloads);
3251   const gchar *expected_offer_direction[] =
3252       { "sendrecv", "sendrecv", "sendrecv" };
3253   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
3254       &offer_setup);
3255   const gchar *expected_answer_direction[] =
3256       { "sendrecv", "recvonly", "recvonly" };
3257   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
3258       &answer_setup);
3259
3260   VAL_SDP_INIT (renego_mid, sdp_media_equal_mid, NULL, &payloads);
3261   VAL_SDP_INIT (renego_ice_params, sdp_media_equal_ice_params, NULL,
3262       &renego_mid);
3263   VAL_SDP_INIT (renego_sess_id, sdp_equal_session_id, NULL, &renego_ice_params);
3264   VAL_SDP_INIT (renego_sess_ver, sdp_increasing_session_version, NULL,
3265       &renego_sess_id);
3266   VAL_SDP_INIT (renego_fingerprint, sdp_media_equal_fingerprint, NULL,
3267       &renego_sess_ver);
3268   VAL_SDP_INIT (bundle_tag, _check_bundle_tag, bundle, &renego_fingerprint);
3269   VAL_SDP_INIT (offer_non_reject, _count_non_rejected_media,
3270       GUINT_TO_POINTER (1), &bundle_tag);
3271   VAL_SDP_INIT (answer_non_reject, _count_non_rejected_media,
3272       GUINT_TO_POINTER (3), &bundle_tag);
3273   VAL_SDP_INIT (offer_bundle_only_sdp, _check_bundle_only_media,
3274       &offer_bundle_only, &offer_non_reject);
3275   VAL_SDP_INIT (answer_bundle_only_sdp, _check_bundle_only_media,
3276       &answer_bundle_only, &answer_non_reject);
3277   GstHarness *h;
3278
3279   /* We set a max-bundle policy on the offering webrtcbin,
3280    * this means that all the offered medias should be part
3281    * of the group:BUNDLE attribute, and they should be marked
3282    * as bundle-only
3283    */
3284   gst_util_set_object_arg (G_OBJECT (t->webrtc1), "bundle-policy",
3285       "max-bundle");
3286   /* We also set a max-bundle policy on the answering webrtcbin,
3287    * this means that all the offered medias should be part
3288    * of the group:BUNDLE attribute, but need not be marked
3289    * as bundle-only.
3290    */
3291   gst_util_set_object_arg (G_OBJECT (t->webrtc2), "bundle-policy",
3292       "max-bundle");
3293
3294   /* negotiate an AV stream and then renegotiate an extra stream */
3295   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
3296   add_fake_audio_src_harness (h, 96);
3297   t->harnesses = g_list_prepend (t->harnesses, h);
3298
3299   test_validate_sdp (t, &offer, &answer);
3300
3301   h = gst_harness_new_with_element (t->webrtc1, "sink_2", NULL);
3302   add_fake_audio_src_harness (h, 98);
3303   t->harnesses = g_list_prepend (t->harnesses, h);
3304
3305   offer_setup.next = &offer_bundle_only_sdp;
3306   answer_setup.next = &answer_bundle_only_sdp;
3307   count.user_data = GUINT_TO_POINTER (3);
3308
3309   /* renegotiate! */
3310   test_webrtc_reset_negotiation (t);
3311   test_validate_sdp (t, &offer, &answer);
3312
3313   test_webrtc_free (t);
3314 }
3315
3316 GST_END_TEST;
3317
3318 GST_START_TEST (test_bundle_max_compat_max_bundle_renego_add_stream)
3319 {
3320   struct test_webrtc *t = create_audio_video_test ();
3321   const gchar *bundle[] = { "audio0", "video1", "audio2", NULL };
3322   const gchar *bundle_only[] = { NULL };
3323   guint media_format_count[] = { 1, 1, 1 };
3324   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
3325       media_format_count, NULL);
3326   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
3327       &media_formats);
3328   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
3329   const gchar *expected_offer_setup[] = { "actpass", "actpass", "actpass" };
3330   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
3331       &payloads);
3332   const gchar *expected_answer_setup[] = { "active", "active", "active" };
3333   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
3334       &payloads);
3335   const gchar *expected_offer_direction[] =
3336       { "sendrecv", "sendrecv", "sendrecv" };
3337   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
3338       &offer_setup);
3339   const gchar *expected_answer_direction[] =
3340       { "sendrecv", "recvonly", "recvonly" };
3341   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
3342       &answer_setup);
3343
3344   VAL_SDP_INIT (renego_mid, sdp_media_equal_mid, NULL, NULL);
3345   VAL_SDP_INIT (renego_ice_params, sdp_media_equal_ice_params, NULL,
3346       &renego_mid);
3347   VAL_SDP_INIT (renego_sess_id, sdp_equal_session_id, NULL, &renego_ice_params);
3348   VAL_SDP_INIT (renego_sess_ver, sdp_increasing_session_version, NULL,
3349       &renego_sess_id);
3350   VAL_SDP_INIT (renego_fingerprint, sdp_media_equal_fingerprint, NULL,
3351       &renego_sess_ver);
3352   VAL_SDP_INIT (bundle_tag, _check_bundle_tag, bundle, &renego_fingerprint);
3353   VAL_SDP_INIT (count_non_reject, _count_non_rejected_media,
3354       GUINT_TO_POINTER (3), &bundle_tag);
3355   VAL_SDP_INIT (bundle_sdp, _check_bundle_only_media, &bundle_only,
3356       &count_non_reject);
3357   GstHarness *h;
3358
3359   /* We set a max-compat policy on the offering webrtcbin,
3360    * this means that all the offered medias should be part
3361    * of the group:BUNDLE attribute, and they should *not* be marked
3362    * as bundle-only
3363    */
3364   gst_util_set_object_arg (G_OBJECT (t->webrtc1), "bundle-policy",
3365       "max-compat");
3366   /* We set a max-bundle policy on the answering webrtcbin,
3367    * this means that all the offered medias should be part
3368    * of the group:BUNDLE attribute, but need not be marked
3369    * as bundle-only.
3370    */
3371   gst_util_set_object_arg (G_OBJECT (t->webrtc2), "bundle-policy",
3372       "max-bundle");
3373
3374   /* negotiate an AV stream and then renegotiate an extra stream */
3375   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
3376   add_fake_audio_src_harness (h, 96);
3377   t->harnesses = g_list_prepend (t->harnesses, h);
3378
3379   test_validate_sdp (t, &offer, &answer);
3380
3381   h = gst_harness_new_with_element (t->webrtc1, "sink_2", NULL);
3382   add_fake_audio_src_harness (h, 98);
3383   t->harnesses = g_list_prepend (t->harnesses, h);
3384
3385   media_formats.next = &bundle_sdp;
3386   count.user_data = GUINT_TO_POINTER (3);
3387
3388   /* renegotiate! */
3389   test_webrtc_reset_negotiation (t);
3390   test_validate_sdp (t, &offer, &answer);
3391
3392   test_webrtc_free (t);
3393 }
3394
3395 GST_END_TEST;
3396
3397 GST_START_TEST (test_renego_transceiver_set_direction)
3398 {
3399   struct test_webrtc *t = create_audio_test ();
3400   guint media_format_count[] = { 1, };
3401   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
3402       media_format_count, NULL);
3403   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (1),
3404       &media_formats);
3405   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
3406   const gchar *expected_offer_setup[] = { "actpass", };
3407   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
3408       &payloads);
3409   const gchar *expected_answer_setup[] = { "active", };
3410   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
3411       &payloads);
3412   const gchar *expected_offer_direction[] = { "sendrecv", };
3413   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
3414       &offer_setup);
3415   const gchar *expected_answer_direction[] = { "sendrecv", };
3416   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
3417       &answer_setup);
3418   GstWebRTCRTPTransceiver *transceiver;
3419   GstHarness *h;
3420   GstPad *pad;
3421
3422   /* negotiate an AV stream and then change the transceiver direction */
3423   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
3424   add_fake_audio_src_harness (h, 96);
3425   t->harnesses = g_list_prepend (t->harnesses, h);
3426
3427   test_validate_sdp (t, &offer, &answer);
3428
3429   /* renegotiate an inactive transceiver! */
3430   pad = gst_element_get_static_pad (t->webrtc1, "sink_0");
3431   g_object_get (pad, "transceiver", &transceiver, NULL);
3432   fail_unless (transceiver != NULL);
3433   g_object_set (transceiver, "direction",
3434       GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_INACTIVE, NULL);
3435   expected_offer_direction[0] = "inactive";
3436   expected_answer_direction[0] = "inactive";
3437
3438   /* TODO: also validate EOS events from the inactive change */
3439
3440   test_webrtc_reset_negotiation (t);
3441   test_validate_sdp (t, &offer, &answer);
3442
3443   gst_object_unref (pad);
3444   gst_object_unref (transceiver);
3445   test_webrtc_free (t);
3446 }
3447
3448 GST_END_TEST;
3449
3450 static void
3451 offer_remove_last_media (struct test_webrtc *t, GstElement * element,
3452     GstPromise * promise, gpointer user_data)
3453 {
3454   guint i, n;
3455   GstSDPMessage *new, *old;
3456   const GstSDPOrigin *origin;
3457   const GstSDPConnection *conn;
3458
3459   old = t->offer_desc->sdp;
3460   fail_unless_equals_int (GST_SDP_OK, gst_sdp_message_new (&new));
3461
3462   origin = gst_sdp_message_get_origin (old);
3463   conn = gst_sdp_message_get_connection (old);
3464   fail_unless_equals_int (GST_SDP_OK, gst_sdp_message_set_version (new,
3465           gst_sdp_message_get_version (old)));
3466   fail_unless_equals_int (GST_SDP_OK, gst_sdp_message_set_origin (new,
3467           origin->username, origin->sess_id, origin->sess_version,
3468           origin->nettype, origin->addrtype, origin->addr));
3469   fail_unless_equals_int (GST_SDP_OK, gst_sdp_message_set_session_name (new,
3470           gst_sdp_message_get_session_name (old)));
3471   fail_unless_equals_int (GST_SDP_OK, gst_sdp_message_set_information (new,
3472           gst_sdp_message_get_information (old)));
3473   fail_unless_equals_int (GST_SDP_OK, gst_sdp_message_set_uri (new,
3474           gst_sdp_message_get_uri (old)));
3475   fail_unless_equals_int (GST_SDP_OK, gst_sdp_message_set_connection (new,
3476           conn->nettype, conn->addrtype, conn->address, conn->ttl,
3477           conn->addr_number));
3478
3479   n = gst_sdp_message_attributes_len (old);
3480   for (i = 0; i < n; i++) {
3481     const GstSDPAttribute *a = gst_sdp_message_get_attribute (old, i);
3482     fail_unless_equals_int (GST_SDP_OK, gst_sdp_message_add_attribute (new,
3483             a->key, a->value));
3484   }
3485
3486   n = gst_sdp_message_medias_len (old);
3487   fail_unless (n > 0);
3488   for (i = 0; i < n - 1; i++) {
3489     const GstSDPMedia *m = gst_sdp_message_get_media (old, i);
3490     GstSDPMedia *new_m;
3491
3492     fail_unless_equals_int (GST_SDP_OK, gst_sdp_media_copy (m, &new_m));
3493     fail_unless_equals_int (GST_SDP_OK, gst_sdp_message_add_media (new, new_m));
3494     gst_sdp_media_init (new_m);
3495     gst_sdp_media_free (new_m);
3496   }
3497
3498   gst_webrtc_session_description_free (t->offer_desc);
3499   t->offer_desc = gst_webrtc_session_description_new (GST_WEBRTC_SDP_TYPE_OFFER,
3500       new);
3501 }
3502
3503 static void
3504 offer_set_produced_error (struct test_webrtc *t, GstElement * element,
3505     GstPromise * promise, gpointer user_data)
3506 {
3507   const GstStructure *reply;
3508   GError *error = NULL;
3509
3510   reply = gst_promise_get_reply (promise);
3511   fail_unless (gst_structure_get (reply, "error", G_TYPE_ERROR, &error, NULL));
3512   GST_INFO ("error produced: %s", error->message);
3513   g_clear_error (&error);
3514
3515   test_webrtc_signal_state_unlocked (t, STATE_CUSTOM);
3516 }
3517
3518 static void
3519 offer_created_produced_error (struct test_webrtc *t, GstElement * element,
3520     GstPromise * promise, gpointer user_data)
3521 {
3522   const GstStructure *reply;
3523   GError *error = NULL;
3524
3525   reply = gst_promise_get_reply (promise);
3526   fail_unless (gst_structure_get (reply, "error", G_TYPE_ERROR, &error, NULL));
3527   GST_INFO ("error produced: %s", error->message);
3528   g_clear_error (&error);
3529 }
3530
3531 GST_START_TEST (test_renego_lose_media_fails)
3532 {
3533   struct test_webrtc *t = create_audio_video_test ();
3534   VAL_SDP_INIT (offer, _count_num_sdp_media, GUINT_TO_POINTER (2), NULL);
3535   VAL_SDP_INIT (answer, _count_num_sdp_media, GUINT_TO_POINTER (2), NULL);
3536
3537   /* check that removing an m=line will produce an error */
3538
3539   test_validate_sdp (t, &offer, &answer);
3540
3541   test_webrtc_reset_negotiation (t);
3542
3543   t->on_offer_created = offer_remove_last_media;
3544   t->on_offer_set = offer_set_produced_error;
3545   t->on_answer_created = NULL;
3546
3547   test_webrtc_create_offer (t);
3548   test_webrtc_wait_for_state_mask (t, 1 << STATE_CUSTOM);
3549
3550   test_webrtc_free (t);
3551 }
3552
3553 GST_END_TEST;
3554
3555 GST_START_TEST (test_bundle_codec_preferences_rtx_no_duplicate_payloads)
3556 {
3557   struct test_webrtc *t = test_webrtc_new ();
3558   GstWebRTCRTPTransceiverDirection direction;
3559   GstWebRTCRTPTransceiver *trans;
3560   guint offer_media_format_count[] = { 2, };
3561   guint answer_media_format_count[] = { 1, };
3562   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, NULL);
3563   VAL_SDP_INIT (offer_media_formats, on_sdp_media_count_formats,
3564       offer_media_format_count, &payloads);
3565   VAL_SDP_INIT (answer_media_formats, on_sdp_media_count_formats,
3566       answer_media_format_count, &payloads);
3567   const gchar *expected_offer_setup[] = { "actpass", };
3568   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
3569       &offer_media_formats);
3570   const gchar *expected_answer_setup[] = { "active", };
3571   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
3572       &answer_media_formats);
3573   const gchar *expected_offer_direction[] = { "recvonly", };
3574   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
3575       &offer_setup);
3576   const gchar *expected_answer_direction[] = { "sendonly", };
3577   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
3578       &answer_setup);
3579   GstCaps *caps;
3580   GstHarness *h;
3581
3582   /* add a transceiver that will only receive an opus stream and check that
3583    * the created offer is marked as recvonly */
3584   t->on_negotiation_needed = NULL;
3585   t->on_ice_candidate = NULL;
3586   t->on_pad_added = _pad_added_fakesink;
3587
3588   gst_util_set_object_arg (G_OBJECT (t->webrtc1), "bundle-policy",
3589       "max-bundle");
3590   gst_util_set_object_arg (G_OBJECT (t->webrtc2), "bundle-policy",
3591       "max-bundle");
3592
3593   /* setup recvonly transceiver */
3594   caps = gst_caps_from_string (VP8_RTP_CAPS (96));
3595   direction = GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_RECVONLY;
3596   g_signal_emit_by_name (t->webrtc1, "add-transceiver", direction, caps,
3597       &trans);
3598   g_object_set (GST_OBJECT (trans), "do-nack", TRUE, NULL);
3599   gst_caps_unref (caps);
3600   fail_unless (trans != NULL);
3601   gst_object_unref (trans);
3602
3603   /* setup sendonly peer */
3604   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
3605   add_fake_video_src_harness (h, 96);
3606   t->harnesses = g_list_prepend (t->harnesses, h);
3607   test_validate_sdp (t, &offer, &answer);
3608
3609   test_webrtc_free (t);
3610 }
3611
3612 GST_END_TEST;
3613
3614 static void
3615 on_sdp_media_no_duplicate_extmaps (struct test_webrtc *t, GstElement * element,
3616     GstWebRTCSessionDescription * desc, gpointer user_data)
3617 {
3618   const GstSDPMedia *media = gst_sdp_message_get_media (desc->sdp, 0);
3619
3620   fail_unless (media != NULL);
3621
3622   fail_unless_equals_string (gst_sdp_media_get_attribute_val_n (media, "extmap",
3623           0), "1 foobar");
3624
3625   fail_unless (gst_sdp_media_get_attribute_val_n (media, "extmap", 1) == NULL);
3626 }
3627
3628 /* In this test, we validate that identical extmaps for multiple formats
3629  * in the caps of a single transceiver are deduplicated. This is necessary
3630  * because Firefox will complain about duplicate extmap ids and fail negotiation
3631  * otherwise. */
3632 GST_START_TEST (test_codec_preferences_no_duplicate_extmaps)
3633 {
3634   struct test_webrtc *t = test_webrtc_new ();
3635   GstWebRTCRTPTransceiver *trans;
3636   GstWebRTCRTPTransceiverDirection direction;
3637   VAL_SDP_INIT (extmaps, on_sdp_media_no_duplicate_extmaps, NULL, NULL);
3638   GstCaps *caps;
3639   GstStructure *s;
3640
3641   caps = gst_caps_new_empty ();
3642
3643   s = gst_structure_from_string (VP8_RTP_CAPS (96), NULL);
3644   gst_structure_set (s, "extmap-1", G_TYPE_STRING, "foobar", NULL);
3645   gst_caps_append_structure (caps, s);
3646   s = gst_structure_from_string (H264_RTP_CAPS (97), NULL);
3647   gst_structure_set (s, "extmap-1", G_TYPE_STRING, "foobar", NULL);
3648   gst_caps_append_structure (caps, s);
3649
3650   direction = GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_SENDONLY;
3651   g_signal_emit_by_name (t->webrtc1, "add-transceiver", direction, caps,
3652       &trans);
3653   gst_caps_unref (caps);
3654   fail_unless (trans != NULL);
3655
3656   t->on_negotiation_needed = NULL;
3657   t->on_pad_added = NULL;
3658   t->on_ice_candidate = NULL;
3659
3660   test_validate_sdp (t, &extmaps, NULL);
3661
3662   test_webrtc_free (t);
3663 }
3664
3665 GST_END_TEST;
3666
3667 /* In this test, we validate that trying to use different values
3668  * for the same extmap id in multiple formats in the caps of a
3669  * single transceiver errors out when creating the offer. */
3670 GST_START_TEST (test_codec_preferences_incompatible_extmaps)
3671 {
3672   struct test_webrtc *t = test_webrtc_new ();
3673   GstWebRTCRTPTransceiver *trans;
3674   GstWebRTCRTPTransceiverDirection direction;
3675   GstCaps *caps;
3676   GstStructure *s;
3677
3678   caps = gst_caps_new_empty ();
3679
3680   s = gst_structure_from_string (VP8_RTP_CAPS (96), NULL);
3681   gst_structure_set (s, "extmap-1", G_TYPE_STRING, "foobar", NULL);
3682   gst_caps_append_structure (caps, s);
3683   s = gst_structure_from_string (H264_RTP_CAPS (97), NULL);
3684   gst_structure_set (s, "extmap-1", G_TYPE_STRING, "foobaz", NULL);
3685   gst_caps_append_structure (caps, s);
3686
3687   direction = GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_SENDONLY;
3688   g_signal_emit_by_name (t->webrtc1, "add-transceiver", direction, caps,
3689       &trans);
3690   gst_caps_unref (caps);
3691   fail_unless (trans != NULL);
3692
3693   t->on_negotiation_needed = NULL;
3694   t->on_pad_added = NULL;
3695   t->on_ice_candidate = NULL;
3696   t->on_offer_created = offer_created_produced_error;
3697
3698   test_validate_sdp_full (t, NULL, NULL, STATE_OFFER_CREATED, TRUE);
3699
3700   test_webrtc_free (t);
3701 }
3702
3703 GST_END_TEST;
3704
3705 /* In this test, we validate that extmap values must be of the correct type */
3706 GST_START_TEST (test_codec_preferences_invalid_extmap)
3707 {
3708   struct test_webrtc *t = test_webrtc_new ();
3709   GstWebRTCRTPTransceiver *trans;
3710   GstWebRTCRTPTransceiverDirection direction;
3711   GstCaps *caps;
3712   GstStructure *s;
3713
3714   caps = gst_caps_new_empty ();
3715
3716   s = gst_structure_from_string (VP8_RTP_CAPS (96), NULL);
3717   gst_structure_set (s, "extmap-1", G_TYPE_INT, 42, NULL);
3718   gst_caps_append_structure (caps, s);
3719
3720   direction = GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_SENDONLY;
3721   g_signal_emit_by_name (t->webrtc1, "add-transceiver", direction, caps,
3722       &trans);
3723   gst_caps_unref (caps);
3724   fail_unless (trans != NULL);
3725
3726   t->on_negotiation_needed = NULL;
3727   t->on_pad_added = NULL;
3728   t->on_ice_candidate = NULL;
3729   t->on_offer_created = offer_created_produced_error;
3730
3731   test_validate_sdp_full (t, NULL, NULL, STATE_OFFER_CREATED, TRUE);
3732
3733   test_webrtc_free (t);
3734 }
3735
3736 GST_END_TEST;
3737
3738 GST_START_TEST (test_reject_request_pad)
3739 {
3740   struct test_webrtc *t = test_webrtc_new ();
3741   GstWebRTCRTPTransceiverDirection direction;
3742   GstWebRTCRTPTransceiver *trans, *trans2;
3743   guint offer_media_format_count[] = { 1, };
3744   guint answer_media_format_count[] = { 1, };
3745   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, NULL);
3746   VAL_SDP_INIT (offer_media_formats, on_sdp_media_count_formats,
3747       offer_media_format_count, &payloads);
3748   VAL_SDP_INIT (answer_media_formats, on_sdp_media_count_formats,
3749       answer_media_format_count, &payloads);
3750   const gchar *expected_offer_setup[] = { "actpass", };
3751   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
3752       &offer_media_formats);
3753   const gchar *expected_answer_setup[] = { "active", };
3754   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
3755       &answer_media_formats);
3756   const gchar *expected_offer_direction[] = { "recvonly", };
3757   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
3758       &offer_setup);
3759   const gchar *expected_answer_direction[] = { "sendonly", };
3760   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
3761       &answer_setup);
3762   GstCaps *caps;
3763   GstHarness *h;
3764   GstPad *pad;
3765   GstPadTemplate *templ;
3766
3767   t->on_negotiation_needed = NULL;
3768   t->on_ice_candidate = NULL;
3769   t->on_pad_added = _pad_added_fakesink;
3770
3771   gst_util_set_object_arg (G_OBJECT (t->webrtc1), "bundle-policy",
3772       "max-bundle");
3773   gst_util_set_object_arg (G_OBJECT (t->webrtc2), "bundle-policy",
3774       "max-bundle");
3775
3776   /* setup recvonly transceiver */
3777   caps = gst_caps_from_string (VP8_RTP_CAPS (96));
3778   direction = GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_RECVONLY;
3779   g_signal_emit_by_name (t->webrtc1, "add-transceiver", direction, caps,
3780       &trans);
3781   gst_caps_unref (caps);
3782   fail_unless (trans != NULL);
3783
3784   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
3785   add_fake_video_src_harness (h, 96);
3786   t->harnesses = g_list_prepend (t->harnesses, h);
3787
3788   test_validate_sdp (t, &offer, &answer);
3789
3790   /* This should fail because the direction is wrong */
3791   pad = gst_element_request_pad_simple (t->webrtc1, "sink_0");
3792   fail_unless (pad == NULL);
3793
3794   g_object_set (trans, "direction",
3795       GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_SENDRECV, NULL);
3796
3797   templ = gst_element_get_pad_template (t->webrtc1, "sink_%u");
3798   fail_unless (templ != NULL);
3799
3800   /* This should fail because the caps are wrong */
3801   caps = gst_caps_from_string (OPUS_RTP_CAPS (96));
3802   pad = gst_element_request_pad (t->webrtc1, templ, "sink_0", caps);
3803   fail_unless (pad == NULL);
3804
3805   g_object_set (trans, "codec-preferences", NULL, NULL);
3806
3807   /* This should fail because the kind doesn't match */
3808   pad = gst_element_request_pad (t->webrtc1, templ, "sink_0", caps);
3809   fail_unless (pad == NULL);
3810   gst_caps_unref (caps);
3811
3812   /* This should succeed and give us sink_0 */
3813   pad = gst_element_request_pad_simple (t->webrtc1, "sink_0");
3814   fail_unless (pad != NULL);
3815
3816   g_object_get (pad, "transceiver", &trans2, NULL);
3817
3818   fail_unless (trans == trans2);
3819
3820   gst_object_unref (pad);
3821   gst_object_unref (trans);
3822   gst_object_unref (trans2);
3823
3824   test_webrtc_free (t);
3825 }
3826
3827 GST_END_TEST;
3828
3829 static void
3830 _verify_media_types (struct test_webrtc *t, GstElement * element,
3831     GstWebRTCSessionDescription * desc, gpointer user_data)
3832 {
3833   gchar **media_types = user_data;
3834   int i;
3835
3836   for (i = 0; i < gst_sdp_message_medias_len (desc->sdp); i++) {
3837     const GstSDPMedia *media = gst_sdp_message_get_media (desc->sdp, i);
3838
3839     fail_unless_equals_string (gst_sdp_media_get_media (media), media_types[i]);
3840   }
3841 }
3842
3843 GST_START_TEST (test_reject_create_offer)
3844 {
3845   struct test_webrtc *t = test_webrtc_new ();
3846   GstHarness *h;
3847   GstPromise *promise;
3848   GstPromiseResult res;
3849   const GstStructure *s;
3850   GError *error = NULL;
3851
3852   const gchar *media_types[] = { "video", "audio" };
3853   VAL_SDP_INIT (media_type, _verify_media_types, &media_types, NULL);
3854   guint media_format_count[] = { 1, 1 };
3855   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
3856       media_format_count, &media_type);
3857   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
3858       &media_formats);
3859   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
3860   const gchar *expected_offer_setup[] = { "actpass", "actpass" };
3861   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
3862       &payloads);
3863   const gchar *expected_answer_setup[] = { "active", "active" };
3864   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
3865       &payloads);
3866   const gchar *expected_offer_direction[] = { "sendrecv", "sendrecv" };
3867   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
3868       &offer_setup);
3869   const gchar *expected_answer_direction[] = { "recvonly", "recvonly" };
3870   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
3871       &answer_setup);
3872
3873   t->on_negotiation_needed = NULL;
3874   t->on_ice_candidate = NULL;
3875   t->on_pad_added = _pad_added_fakesink;
3876
3877   /* setup sendonly peer */
3878   h = gst_harness_new_with_element (t->webrtc1, "sink_1", NULL);
3879   add_fake_audio_src_harness (h, 96);
3880   t->harnesses = g_list_prepend (t->harnesses, h);
3881
3882   /* Check that if there is no 0, we can't create an offer with a hole */
3883   promise = gst_promise_new ();
3884   g_signal_emit_by_name (t->webrtc1, "create-offer", NULL, promise);
3885   res = gst_promise_wait (promise);
3886   fail_unless_equals_int (res, GST_PROMISE_RESULT_REPLIED);
3887   s = gst_promise_get_reply (promise);
3888   fail_unless (s != NULL);
3889   gst_structure_get (s, "error", G_TYPE_ERROR, &error, NULL);
3890   fail_unless (g_error_matches (error, GST_WEBRTC_ERROR,
3891           GST_WEBRTC_ERROR_INTERNAL_FAILURE));
3892   fail_unless (g_str_match_string
3893       ("has locked mline 1 but the whole offer only has 0 sections",
3894           error->message, FALSE));
3895   g_clear_error (&error);
3896   gst_promise_unref (promise);
3897
3898   h = gst_harness_new_with_element (t->webrtc1, "sink_%u", NULL);
3899   add_fake_video_src_harness (h, 97);
3900   t->harnesses = g_list_prepend (t->harnesses, h);
3901
3902   /* Adding a second sink, which will fill m-line 0, should fix it */
3903   test_validate_sdp (t, &offer, &answer);
3904
3905   test_webrtc_free (t);
3906 }
3907
3908 GST_END_TEST;
3909
3910 GST_START_TEST (test_reject_set_description)
3911 {
3912   struct test_webrtc *t = test_webrtc_new ();
3913   GstHarness *h;
3914   GstPromise *promise;
3915   GstPromiseResult res;
3916   const GstStructure *s;
3917   GError *error = NULL;
3918   GstWebRTCSessionDescription *desc = NULL;
3919   GstPadTemplate *templ;
3920   GstCaps *caps;
3921   GstPad *pad;
3922
3923   t->on_negotiation_needed = NULL;
3924   t->on_ice_candidate = NULL;
3925   t->on_pad_added = _pad_added_fakesink;
3926
3927   /* setup peer 1 */
3928   h = gst_harness_new_with_element (t->webrtc1, "sink_0", NULL);
3929   add_fake_audio_src_harness (h, 96);
3930   t->harnesses = g_list_prepend (t->harnesses, h);
3931
3932   /* Create a second side with specific video caps */
3933   templ = gst_element_get_pad_template (t->webrtc2, "sink_%u");
3934   fail_unless (templ != NULL);
3935   caps = gst_caps_from_string (VP8_RTP_CAPS (97));
3936   pad = gst_element_request_pad (t->webrtc2, templ, "sink_0", caps);
3937   fail_unless (pad != NULL);
3938   gst_caps_unref (caps);
3939   gst_object_unref (pad);
3940
3941   /* Create an offer */
3942   promise = gst_promise_new ();
3943   g_signal_emit_by_name (t->webrtc1, "create-offer", NULL, promise);
3944   res = gst_promise_wait (promise);
3945   fail_unless_equals_int (res, GST_PROMISE_RESULT_REPLIED);
3946   s = gst_promise_get_reply (promise);
3947   fail_unless (s != NULL);
3948   gst_structure_get (s, "offer", GST_TYPE_WEBRTC_SESSION_DESCRIPTION, &desc,
3949       NULL);
3950   fail_unless (desc != NULL);
3951   gst_promise_unref (promise);
3952
3953   fail_if (gst_element_set_state (t->webrtc2,
3954           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
3955
3956   /* Verify that setting an offer where there is a forced m-line with
3957      a different kind fails. */
3958   promise = gst_promise_new ();
3959   g_signal_emit_by_name (t->webrtc2, "set-remote-description", desc, promise);
3960   res = gst_promise_wait (promise);
3961   fail_unless_equals_int (res, GST_PROMISE_RESULT_REPLIED);
3962   s = gst_promise_get_reply (promise);
3963   gst_structure_get (s, "error", G_TYPE_ERROR, &error, NULL);
3964   fail_unless (g_error_matches (error, GST_WEBRTC_ERROR,
3965           GST_WEBRTC_ERROR_INTERNAL_FAILURE));
3966   fail_unless (g_str_match_string
3967       ("m-line 0 was locked to audio, but SDP has audio media", error->message,
3968           FALSE));
3969
3970   g_clear_error (&error);
3971   fail_unless (s != NULL);
3972   gst_promise_unref (promise);
3973   gst_webrtc_session_description_free (desc);
3974
3975   test_webrtc_free (t);
3976 }
3977
3978 GST_END_TEST;
3979
3980 GST_START_TEST (test_force_second_media)
3981 {
3982   struct test_webrtc *t = test_webrtc_new ();
3983   const gchar *media_types[] = { "audio" };
3984   VAL_SDP_INIT (media_type, _verify_media_types, &media_types, NULL);
3985   guint media_format_count[] = { 1, };
3986   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
3987       media_format_count, &media_type);
3988   const gchar *expected_offer_setup[] = { "actpass", };
3989   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
3990       &media_formats);
3991   const gchar *expected_answer_setup[] = { "active", };
3992   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
3993       &media_formats);
3994   const gchar *expected_offer_direction[] = { "sendrecv", };
3995   VAL_SDP_INIT (offer_direction, on_sdp_media_direction,
3996       expected_offer_direction, &offer_setup);
3997   const gchar *expected_answer_direction[] = { "recvonly", };
3998   VAL_SDP_INIT (answer_direction, on_sdp_media_direction,
3999       expected_answer_direction, &answer_setup);
4000   VAL_SDP_INIT (answer_count, _count_num_sdp_media, GUINT_TO_POINTER (1),
4001       &answer_direction);
4002   VAL_SDP_INIT (offer_count, _count_num_sdp_media, GUINT_TO_POINTER (1),
4003       &offer_direction);
4004
4005   const gchar *second_media_types[] = { "audio", "video" };
4006   VAL_SDP_INIT (second_media_type, _verify_media_types, &second_media_types,
4007       NULL);
4008   guint second_media_format_count[] = { 1, 1 };
4009   VAL_SDP_INIT (second_media_formats, on_sdp_media_count_formats,
4010       second_media_format_count, &second_media_type);
4011   const gchar *second_expected_offer_setup[] = { "active", "actpass" };
4012   VAL_SDP_INIT (second_offer_setup, on_sdp_media_setup,
4013       second_expected_offer_setup, &second_media_formats);
4014   const gchar *second_expected_answer_setup[] = { "passive", "active" };
4015   VAL_SDP_INIT (second_answer_setup, on_sdp_media_setup,
4016       second_expected_answer_setup, &second_media_formats);
4017   const gchar *second_expected_answer_direction[] = { "sendonly", "recvonly" };
4018   VAL_SDP_INIT (second_answer_direction, on_sdp_media_direction,
4019       second_expected_answer_direction, &second_answer_setup);
4020   const gchar *second_expected_offer_direction[] = { "recvonly", "sendrecv" };
4021   VAL_SDP_INIT (second_offer_direction, on_sdp_media_direction,
4022       second_expected_offer_direction, &second_offer_setup);
4023   VAL_SDP_INIT (second_answer_count, _count_num_sdp_media, GUINT_TO_POINTER (2),
4024       &second_answer_direction);
4025   VAL_SDP_INIT (second_offer_count, _count_num_sdp_media, GUINT_TO_POINTER (2),
4026       &second_offer_direction);
4027
4028   GstHarness *h;
4029   guint negotiation_flag = 0;
4030   GstPadTemplate *templ;
4031   GstCaps *caps;
4032   GstPad *pad;
4033
4034   /* add a transceiver that will only receive an opus stream and check that
4035    * the created offer is marked as recvonly */
4036   t->on_negotiation_needed = on_negotiation_needed_hit;
4037   t->negotiation_data = &negotiation_flag;
4038   t->on_ice_candidate = NULL;
4039   t->on_pad_added = _pad_added_fakesink;
4040
4041   /* setup peer */
4042   h = gst_harness_new_with_element (t->webrtc1, "sink_0", NULL);
4043   add_fake_audio_src_harness (h, 96);
4044   t->harnesses = g_list_prepend (t->harnesses, h);
4045
4046   /* Create a second side with specific video caps */
4047   templ = gst_element_get_pad_template (t->webrtc2, "sink_%u");
4048   fail_unless (templ != NULL);
4049   caps = gst_caps_from_string (VP8_RTP_CAPS (97));
4050   pad = gst_element_request_pad (t->webrtc2, templ, NULL, caps);
4051   gst_caps_unref (caps);
4052   fail_unless (pad != NULL);
4053   h = gst_harness_new_with_element (t->webrtc2, GST_PAD_NAME (pad), NULL);
4054   gst_object_unref (pad);
4055   add_fake_video_src_harness (h, 97);
4056   t->harnesses = g_list_prepend (t->harnesses, h);
4057
4058   test_validate_sdp (t, &offer_count, &answer_count);
4059   fail_unless (negotiation_flag & 1 << 2);
4060
4061   test_webrtc_reset_negotiation (t);
4062
4063   t->offerror = 2;
4064   test_validate_sdp (t, &second_offer_count, &second_answer_count);
4065
4066   test_webrtc_free (t);
4067 }
4068
4069 GST_END_TEST;
4070
4071 GST_START_TEST (test_codec_preferences_caps)
4072 {
4073   GstHarness *h;
4074   GstPad *pad;
4075   GstWebRTCRTPTransceiver *trans;
4076   GstCaps *caps, *caps2;
4077
4078   h = gst_harness_new_with_padnames ("webrtcbin", "sink_0", NULL);
4079   pad = gst_element_get_static_pad (h->element, "sink_0");
4080
4081   g_object_get (pad, "transceiver", &trans, NULL);
4082
4083   caps = gst_caps_from_string ("application/x-rtp, media=video,"
4084       "encoding-name=VP8, payload=115; application/x-rtp, media=video,"
4085       " encoding-name=H264, payload=104");
4086   g_object_set (trans, "codec-preferences", caps, NULL);
4087
4088   caps2 = gst_pad_query_caps (pad, NULL);
4089   fail_unless (gst_caps_is_equal (caps, caps2));
4090   gst_caps_unref (caps2);
4091   gst_caps_unref (caps);
4092
4093   caps = gst_caps_from_string (VP8_RTP_CAPS (115));
4094   fail_unless (gst_pad_query_accept_caps (pad, caps));
4095   gst_harness_set_src_caps (h, g_steal_pointer (&caps));
4096
4097   caps = gst_caps_from_string (VP8_RTP_CAPS (99));
4098   fail_unless (!gst_pad_query_accept_caps (pad, caps));
4099   gst_caps_unref (caps);
4100
4101   gst_object_unref (pad);
4102   gst_object_unref (trans);
4103   gst_harness_teardown (h);
4104 }
4105
4106 GST_END_TEST;
4107
4108 GST_START_TEST (test_codec_preferences_negotiation_sinkpad)
4109 {
4110   struct test_webrtc *t = test_webrtc_new ();
4111   guint media_format_count[] = { 1, };
4112   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
4113       media_format_count, NULL);
4114   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (1),
4115       &media_formats);
4116   VAL_SDP_INIT (payloads2, on_sdp_media_payload_types, GUINT_TO_POINTER (0),
4117       &count);
4118   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &payloads2);
4119   const gchar *expected_offer_setup[] = { "actpass", };
4120   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
4121       &payloads);
4122   const gchar *expected_answer_setup[] = { "active", };
4123   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
4124       &payloads);
4125   const gchar *expected_offer_direction[] = { "sendrecv", };
4126   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
4127       &offer_setup);
4128   const gchar *expected_answer_direction[] = { "recvonly", };
4129   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
4130       &answer_setup);
4131
4132   GstPad *pad;
4133   GstWebRTCRTPTransceiver *transceiver;
4134   GstHarness *h;
4135   GstCaps *caps;
4136   GstPromise *promise;
4137   GstPromiseResult res;
4138   const GstStructure *s;
4139   GError *error = NULL;
4140
4141   t->on_negotiation_needed = NULL;
4142   t->on_ice_candidate = NULL;
4143   t->on_pad_added = _pad_added_fakesink;
4144
4145   h = gst_harness_new_with_element (t->webrtc1, "sink_0", NULL);
4146   pad = gst_element_get_static_pad (t->webrtc1, "sink_0");
4147   g_object_get (pad, "transceiver", &transceiver, NULL);
4148   caps = gst_caps_from_string (VP8_RTP_CAPS (115) ";" VP8_RTP_CAPS (97));
4149   g_object_set (transceiver, "codec-preferences", caps, NULL);
4150   gst_caps_unref (caps);
4151   gst_object_unref (transceiver);
4152   gst_object_unref (pad);
4153
4154   add_fake_video_src_harness (h, 96);
4155   t->harnesses = g_list_prepend (t->harnesses, h);
4156
4157   promise = gst_promise_new ();
4158   g_signal_emit_by_name (t->webrtc1, "create-offer", NULL, promise);
4159   res = gst_promise_wait (promise);
4160   fail_unless_equals_int (res, GST_PROMISE_RESULT_REPLIED);
4161   s = gst_promise_get_reply (promise);
4162   fail_unless (s != NULL);
4163   gst_structure_get (s, "error", G_TYPE_ERROR, &error, NULL);
4164   fail_unless (g_error_matches (error, GST_WEBRTC_ERROR,
4165           GST_WEBRTC_ERROR_INTERNAL_FAILURE));
4166   fail_unless (g_str_match_string
4167       ("Caps negotiation on pad sink_0 failed against codec preferences",
4168           error->message, FALSE));
4169   g_clear_error (&error);
4170   gst_promise_unref (promise);
4171
4172   caps = gst_caps_from_string (VP8_RTP_CAPS (97));
4173   gst_harness_set_src_caps (h, caps);
4174
4175   test_validate_sdp (t, &offer, &answer);
4176
4177   test_webrtc_free (t);
4178 }
4179
4180 GST_END_TEST;
4181
4182
4183 static void
4184 add_audio_test_src_harness (GstHarness * h)
4185 {
4186 #define L16_CAPS "application/x-rtp, payload=11, media=audio," \
4187       " encoding-name=L16, clock-rate=44100, ssrc=(uint)3484078952"
4188   GstCaps *caps = gst_caps_from_string (L16_CAPS);
4189   gst_harness_set_src_caps (h, caps);
4190   gst_harness_add_src_parse (h, "audiotestsrc is-live=true ! rtpL16pay ! "
4191       L16_CAPS " ! identity", TRUE);
4192 }
4193
4194 static void
4195 _pad_added_harness (struct test_webrtc *t, GstElement * element,
4196     GstPad * pad, gpointer user_data)
4197 {
4198   GstHarness *h;
4199   GstHarness **sink_harness = user_data;
4200
4201   if (GST_PAD_DIRECTION (pad) != GST_PAD_SRC)
4202     return;
4203
4204   h = gst_harness_new_with_element (element, NULL, GST_OBJECT_NAME (pad));
4205   t->harnesses = g_list_prepend (t->harnesses, h);
4206
4207   if (sink_harness) {
4208     *sink_harness = h;
4209     g_cond_broadcast (&t->cond);
4210   }
4211 }
4212
4213 static void
4214 new_jitterbuffer_set_fast_start (GstElement * rtpbin,
4215     GstElement * rtpjitterbuffer, guint session_id, guint ssrc,
4216     gpointer user_data)
4217 {
4218   g_object_set (rtpjitterbuffer, "faststart-min-packets", 1, NULL);
4219 }
4220
4221 GST_START_TEST (test_codec_preferences_negotiation_srcpad)
4222 {
4223   struct test_webrtc *t = test_webrtc_new ();
4224   guint media_format_count[] = { 1, };
4225   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
4226       media_format_count, NULL);
4227   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (1),
4228       &media_formats);
4229   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
4230   const gchar *expected_offer_setup[] = { "actpass", };
4231   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
4232       &payloads);
4233   const gchar *expected_answer_setup[] = { "active", };
4234   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
4235       &payloads);
4236   const gchar *expected_offer_direction[] = { "sendrecv", };
4237   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
4238       &offer_setup);
4239   const gchar *expected_answer_direction[] = { "recvonly", };
4240   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
4241       &answer_setup);
4242   VAL_SDP_INIT (answer_non_reject, _count_non_rejected_media,
4243       GUINT_TO_POINTER (0), &count);
4244   GstHarness *h;
4245   GstHarness *sink_harness = NULL;
4246   guint i;
4247   GstElement *rtpbin2;
4248   GstBuffer *buf;
4249
4250   t->on_negotiation_needed = NULL;
4251   t->on_ice_candidate = NULL;
4252   t->on_pad_added = _pad_added_harness;
4253   t->pad_added_data = &sink_harness;
4254
4255   rtpbin2 = gst_bin_get_by_name (GST_BIN (t->webrtc2), "rtpbin");
4256   fail_unless (rtpbin2 != NULL);
4257   g_signal_connect (rtpbin2, "new-jitterbuffer",
4258       G_CALLBACK (new_jitterbuffer_set_fast_start), NULL);
4259   g_object_unref (rtpbin2);
4260
4261   h = gst_harness_new_with_element (t->webrtc1, "sink_0", NULL);
4262   add_audio_test_src_harness (h);
4263   t->harnesses = g_list_prepend (t->harnesses, h);
4264
4265   test_validate_sdp (t, &offer, &answer);
4266
4267   fail_if (gst_element_set_state (t->webrtc1,
4268           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
4269   fail_if (gst_element_set_state (t->webrtc2,
4270           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
4271
4272   for (i = 0; i < 10; i++)
4273     gst_harness_push_from_src (h);
4274
4275   g_mutex_lock (&t->lock);
4276   while (sink_harness == NULL) {
4277     gst_harness_push_from_src (h);
4278     g_cond_wait_until (&t->cond, &t->lock, g_get_monotonic_time () + 5000);
4279   }
4280   g_mutex_unlock (&t->lock);
4281   fail_unless (sink_harness->element == t->webrtc2);
4282
4283   /* Get one buffer out, this makes sure the capsfilter is primed and
4284    * avoids races.
4285    */
4286   buf = gst_harness_pull (sink_harness);
4287   fail_unless (buf != NULL);
4288   gst_buffer_unref (buf);
4289
4290   gst_harness_set_sink_caps_str (sink_harness, OPUS_RTP_CAPS (100));
4291
4292   test_webrtc_reset_negotiation (t);
4293   test_validate_sdp_full (t, &offer, &answer_non_reject, 0, FALSE);
4294
4295   test_webrtc_free (t);
4296 }
4297
4298 GST_END_TEST;
4299
4300 static void
4301 _on_new_transceiver_codec_preferences_h264 (GstElement * webrtcbin,
4302     GstWebRTCRTPTransceiver * trans, gpointer * user_data)
4303 {
4304   GstCaps *caps;
4305
4306   caps = gst_caps_from_string ("application/x-rtp,encoding-name=(string)H264");
4307   g_object_set (trans, "codec-preferences", caps, NULL);
4308   gst_caps_unref (caps);
4309 }
4310
4311 static void
4312 on_sdp_media_payload_types_only_h264 (struct test_webrtc *t,
4313     GstElement * element, GstWebRTCSessionDescription * desc,
4314     gpointer user_data)
4315 {
4316   const GstSDPMedia *vmedia;
4317   guint video_mline = GPOINTER_TO_UINT (user_data);
4318   guint j;
4319
4320   vmedia = gst_sdp_message_get_media (desc->sdp, video_mline);
4321
4322   for (j = 0; j < gst_sdp_media_attributes_len (vmedia); j++) {
4323     const GstSDPAttribute *attr = gst_sdp_media_get_attribute (vmedia, j);
4324
4325     if (!g_strcmp0 (attr->key, "rtpmap")) {
4326       fail_unless_equals_string (attr->value, "101 H264/90000");
4327     }
4328   }
4329 }
4330
4331
4332 GST_START_TEST (test_codec_preferences_in_on_new_transceiver)
4333 {
4334   struct test_webrtc *t = test_webrtc_new ();
4335   GstWebRTCRTPTransceiverDirection direction;
4336   GstWebRTCRTPTransceiver *trans;
4337   VAL_SDP_INIT (no_duplicate_payloads, on_sdp_media_no_duplicate_payloads,
4338       NULL, NULL);
4339   guint offer_media_format_count[] = { 2 };
4340   guint answer_media_format_count[] = { 1 };
4341   VAL_SDP_INIT (offer_media_formats, on_sdp_media_count_formats,
4342       offer_media_format_count, &no_duplicate_payloads);
4343   VAL_SDP_INIT (answer_media_formats, on_sdp_media_count_formats,
4344       answer_media_format_count, &no_duplicate_payloads);
4345   VAL_SDP_INIT (offer_count, _count_num_sdp_media, GUINT_TO_POINTER (1),
4346       &offer_media_formats);
4347   VAL_SDP_INIT (answer_count, _count_num_sdp_media, GUINT_TO_POINTER (1),
4348       &answer_media_formats);
4349   VAL_SDP_INIT (offer_payloads, on_sdp_media_payload_types,
4350       GUINT_TO_POINTER (0), &offer_count);
4351   VAL_SDP_INIT (answer_payloads, on_sdp_media_payload_types_only_h264,
4352       GUINT_TO_POINTER (0), &answer_count);
4353   const gchar *expected_offer_setup[] = { "actpass", };
4354   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
4355       &offer_payloads);
4356   const gchar *expected_answer_setup[] = { "active", };
4357   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
4358       &answer_payloads);
4359   const gchar *expected_offer_direction[] = { "sendonly", };
4360   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
4361       &offer_setup);
4362   const gchar *expected_answer_direction[] = { "recvonly", };
4363   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
4364       &answer_setup);
4365   GstCaps *caps;
4366   GstHarness *h;
4367
4368   t->on_negotiation_needed = NULL;
4369   t->on_ice_candidate = NULL;
4370   t->on_pad_added = _pad_added_fakesink;
4371
4372   /* setup sendonly transceiver with VP8 and H264 */
4373   caps = gst_caps_from_string (VP8_RTP_CAPS (97) ";" H264_RTP_CAPS (101));
4374   direction = GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_SENDONLY;
4375   g_signal_emit_by_name (t->webrtc1, "add-transceiver", direction, caps,
4376       &trans);
4377   gst_caps_unref (caps);
4378   fail_unless (trans != NULL);
4379   gst_object_unref (trans);
4380
4381   /* setup recvonly peer */
4382   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
4383   add_fake_video_src_harness (h, 101);
4384   t->harnesses = g_list_prepend (t->harnesses, h);
4385
4386   /* connect to "on-new-transceiver" to set codec-preferences to H264 */
4387   g_signal_connect (t->webrtc2, "on-new-transceiver",
4388       G_CALLBACK (_on_new_transceiver_codec_preferences_h264), NULL);
4389
4390   /* Answer SDP should now have H264 only. Without the codec-preferences it
4391    * would only have VP8 because that comes first in the SDP */
4392
4393   test_validate_sdp (t, &offer, &answer);
4394   test_webrtc_free (t);
4395 }
4396
4397 GST_END_TEST;
4398
4399 GST_START_TEST (test_renego_rtx)
4400 {
4401   struct test_webrtc *t = create_audio_video_test ();
4402   VAL_SDP_INIT (no_duplicate_payloads, on_sdp_media_no_duplicate_payloads,
4403       NULL, NULL);
4404   guint media_format_count[] = { 1, 1 };
4405   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
4406       media_format_count, &no_duplicate_payloads);
4407   VAL_SDP_INIT (count_media, _count_num_sdp_media, GUINT_TO_POINTER (2),
4408       &media_formats);
4409   VAL_SDP_INIT (payloads, on_sdp_media_payload_types,
4410       GUINT_TO_POINTER (1), &count_media);
4411   const gchar *expected_offer_direction[] = { "sendrecv", "sendrecv", };
4412   VAL_SDP_INIT (offer_direction, on_sdp_media_direction,
4413       expected_offer_direction, &payloads);
4414   const gchar *expected_answer_direction[] = { "recvonly", "recvonly", };
4415   VAL_SDP_INIT (answer_direction, on_sdp_media_direction,
4416       expected_answer_direction, &payloads);
4417   const gchar *expected_offer_setup[] = { "actpass", "actpass", };
4418   VAL_SDP_INIT (offer, on_sdp_media_setup, expected_offer_setup,
4419       &offer_direction);
4420   const gchar *expected_answer_setup[] = { "active", "active", };
4421   VAL_SDP_INIT (answer, on_sdp_media_setup, expected_answer_setup,
4422       &answer_direction);
4423   GstWebRTCRTPTransceiver *trans;
4424
4425   t->on_negotiation_needed = NULL;
4426   t->on_ice_candidate = NULL;
4427   t->on_pad_added = _pad_added_fakesink;
4428
4429   test_validate_sdp (t, &offer, &answer);
4430
4431   test_webrtc_reset_negotiation (t);
4432
4433   g_signal_emit_by_name (t->webrtc1, "get-transceiver", 1, &trans);
4434   g_object_set (trans, "do-nack", TRUE, "fec-type",
4435       GST_WEBRTC_FEC_TYPE_ULP_RED, NULL);
4436   g_clear_object (&trans);
4437
4438   g_signal_emit_by_name (t->webrtc2, "get-transceiver", 1, &trans);
4439   g_object_set (trans, "do-nack", TRUE, "fec-type",
4440       GST_WEBRTC_FEC_TYPE_ULP_RED, NULL);
4441   g_clear_object (&trans);
4442
4443   /* adding RTX/RED/FEC increases the number of media formats */
4444   media_format_count[1] = 5;
4445
4446   test_validate_sdp (t, &offer, &answer);
4447
4448   test_webrtc_free (t);
4449 }
4450
4451 GST_END_TEST;
4452
4453 GST_START_TEST (test_bundle_mid_header_extension)
4454 {
4455   struct test_webrtc *t = test_webrtc_new ();
4456   GstWebRTCRTPTransceiverDirection direction;
4457   GstWebRTCRTPTransceiver *trans;
4458   VAL_SDP_INIT (no_duplicate_payloads, on_sdp_media_no_duplicate_payloads,
4459       NULL, NULL);
4460   guint media_format_count[] = { 1, 1, };
4461   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
4462       media_format_count, &no_duplicate_payloads);
4463   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (1),
4464       &media_formats);
4465   const char *expected_mid[] = { "gst", };
4466   VAL_SDP_INIT (mid, on_sdp_media_check_mid, expected_mid, &count);
4467   const gchar *expected_offer_setup[] = { "actpass", };
4468   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup, &mid);
4469   const gchar *expected_answer_setup[] = { "active", };
4470   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup, &mid);
4471   const gchar *expected_offer_direction[] = { "recvonly", };
4472   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
4473       &offer_setup);
4474   const gchar *expected_answer_direction[] = { "sendonly", };
4475   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
4476       &answer_setup);
4477   GstCaps *caps;
4478   GstHarness *h;
4479   guint mline;
4480   char *trans_mid;
4481
4482   /* add a transceiver that will only receive an opus stream and check that
4483    * the created offer is marked as recvonly */
4484   t->on_negotiation_needed = NULL;
4485   t->on_ice_candidate = NULL;
4486   t->on_pad_added = _pad_added_fakesink;
4487
4488   /* setup recvonly transceiver */
4489   caps = gst_caps_from_string (OPUS_RTP_CAPS (96) ", a-mid=(string)gst");
4490   direction = GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_RECVONLY;
4491   g_signal_emit_by_name (t->webrtc1, "add-transceiver", direction, caps,
4492       &trans);
4493   gst_caps_unref (caps);
4494   fail_unless (trans != NULL);
4495   g_object_get (trans, "mlineindex", &mline, NULL);
4496   fail_unless_equals_int (mline, -1);
4497
4498   /* setup sendonly peer */
4499   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
4500   add_fake_audio_src_harness (h, 96);
4501   t->harnesses = g_list_prepend (t->harnesses, h);
4502
4503   test_validate_sdp (t, &offer, &answer);
4504
4505   g_object_get (trans, "mlineindex", &mline, "mid", &trans_mid, NULL);
4506   fail_unless_equals_int (mline, 0);
4507   fail_unless_equals_string (trans_mid, "gst");
4508   g_clear_pointer (&trans_mid, g_free);
4509   gst_object_unref (trans);
4510
4511   test_webrtc_free (t);
4512 }
4513
4514 GST_END_TEST;
4515
4516 static Suite *
4517 webrtcbin_suite (void)
4518 {
4519   Suite *s = suite_create ("webrtcbin");
4520   TCase *tc = tcase_create ("general");
4521   GstPluginFeature *nicesrc, *nicesink, *dtlssrtpdec, *dtlssrtpenc;
4522   GstPluginFeature *sctpenc, *sctpdec;
4523   GstRegistry *registry;
4524
4525   registry = gst_registry_get ();
4526   nicesrc = gst_registry_lookup_feature (registry, "nicesrc");
4527   nicesink = gst_registry_lookup_feature (registry, "nicesink");
4528   dtlssrtpenc = gst_registry_lookup_feature (registry, "dtlssrtpenc");
4529   dtlssrtpdec = gst_registry_lookup_feature (registry, "dtlssrtpdec");
4530   sctpenc = gst_registry_lookup_feature (registry, "sctpenc");
4531   sctpdec = gst_registry_lookup_feature (registry, "sctpdec");
4532
4533   tcase_add_test (tc, test_no_nice_elements_request_pad);
4534   tcase_add_test (tc, test_no_nice_elements_state_change);
4535   if (nicesrc && nicesink && dtlssrtpenc && dtlssrtpdec) {
4536     tcase_add_test (tc, test_sdp_no_media);
4537     tcase_add_test (tc, test_session_stats);
4538     tcase_add_test (tc, test_audio);
4539     tcase_add_test (tc, test_ice_port_restriction);
4540     tcase_add_test (tc, test_audio_video);
4541     tcase_add_test (tc, test_media_direction);
4542     tcase_add_test (tc, test_add_transceiver);
4543     tcase_add_test (tc, test_get_transceivers);
4544     tcase_add_test (tc, test_add_recvonly_transceiver);
4545     tcase_add_test (tc, test_recvonly_sendonly);
4546     tcase_add_test (tc, test_payload_types);
4547     tcase_add_test (tc, test_bundle_audio_video_max_bundle_max_bundle);
4548     tcase_add_test (tc, test_bundle_audio_video_max_bundle_none);
4549     tcase_add_test (tc, test_bundle_audio_video_max_compat_max_bundle);
4550     tcase_add_test (tc, test_dual_audio);
4551     tcase_add_test (tc, test_duplicate_nego);
4552     tcase_add_test (tc, test_renego_add_stream);
4553     tcase_add_test (tc, test_bundle_renego_add_stream);
4554     tcase_add_test (tc, test_bundle_max_compat_max_bundle_renego_add_stream);
4555     tcase_add_test (tc, test_renego_transceiver_set_direction);
4556     tcase_add_test (tc, test_renego_lose_media_fails);
4557     tcase_add_test (tc,
4558         test_bundle_codec_preferences_rtx_no_duplicate_payloads);
4559     tcase_add_test (tc, test_reject_request_pad);
4560     tcase_add_test (tc, test_reject_create_offer);
4561     tcase_add_test (tc, test_reject_set_description);
4562     tcase_add_test (tc, test_force_second_media);
4563     tcase_add_test (tc, test_codec_preferences_caps);
4564     tcase_add_test (tc, test_codec_preferences_negotiation_sinkpad);
4565     tcase_add_test (tc, test_codec_preferences_negotiation_srcpad);
4566     tcase_add_test (tc, test_codec_preferences_in_on_new_transceiver);
4567     tcase_add_test (tc, test_codec_preferences_no_duplicate_extmaps);
4568     tcase_add_test (tc, test_codec_preferences_incompatible_extmaps);
4569     tcase_add_test (tc, test_codec_preferences_invalid_extmap);
4570     tcase_add_test (tc, test_renego_rtx);
4571     tcase_add_test (tc, test_bundle_mid_header_extension);
4572     if (sctpenc && sctpdec) {
4573       tcase_add_test (tc, test_data_channel_create);
4574       tcase_add_test (tc, test_data_channel_remote_notify);
4575       tcase_add_test (tc, test_data_channel_transfer_string);
4576       tcase_add_test (tc, test_data_channel_transfer_data);
4577       tcase_add_test (tc, test_data_channel_create_after_negotiate);
4578       tcase_add_test (tc, test_data_channel_close);
4579       tcase_add_test (tc, test_data_channel_low_threshold);
4580       tcase_add_test (tc, test_data_channel_max_message_size);
4581       tcase_add_test (tc, test_data_channel_pre_negotiated);
4582       tcase_add_test (tc, test_bundle_audio_video_data);
4583       tcase_add_test (tc, test_renego_stream_add_data_channel);
4584       tcase_add_test (tc, test_renego_data_channel_add_stream);
4585       tcase_add_test (tc, test_renego_stream_data_channel_add_stream);
4586     } else {
4587       GST_WARNING ("Some required elements were not found. "
4588           "All datachannel tests are disabled. sctpenc %p, sctpdec %p", sctpenc,
4589           sctpdec);
4590     }
4591   } else {
4592     GST_WARNING ("Some required elements were not found. "
4593         "All media tests are disabled. nicesrc %p, nicesink %p, "
4594         "dtlssrtpenc %p, dtlssrtpdec %p", nicesrc, nicesink, dtlssrtpenc,
4595         dtlssrtpdec);
4596   }
4597
4598   if (nicesrc)
4599     gst_object_unref (nicesrc);
4600   if (nicesink)
4601     gst_object_unref (nicesink);
4602   if (dtlssrtpdec)
4603     gst_object_unref (dtlssrtpdec);
4604   if (dtlssrtpenc)
4605     gst_object_unref (dtlssrtpenc);
4606   if (sctpenc)
4607     gst_object_unref (sctpenc);
4608   if (sctpdec)
4609     gst_object_unref (sctpdec);
4610
4611   suite_add_tcase (s, tc);
4612
4613   return s;
4614 }
4615
4616 GST_CHECK_MAIN (webrtcbin);