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