2 * Copyright (C) 2012 Wim Taymans <wim.taymans@gmail.com>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
20 #include <gst/check/gstcheck.h>
22 #include <rtsp-client.h>
24 #define VIDEO_PIPELINE "videotestsrc ! " \
25 "video/x-raw,width=352,height=288 ! " \
26 "rtpgstpay name=pay0 pt=96"
27 #define AUDIO_PIPELINE "audiotestsrc ! " \
28 "audio/x-raw,rate=8000 ! " \
29 "rtpgstpay name=pay1 pt=97"
31 static gchar *session_id;
33 static guint expected_session_timeout = 60;
34 static const gchar *expected_unsupported_header;
37 test_response_200 (GstRTSPClient * client, GstRTSPMessage * response,
38 gboolean close, gpointer user_data)
40 GstRTSPStatusCode code;
42 GstRTSPVersion version;
44 fail_unless (gst_rtsp_message_get_type (response) ==
45 GST_RTSP_MESSAGE_RESPONSE);
47 fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
50 fail_unless (code == GST_RTSP_STS_OK);
51 fail_unless (g_str_equal (reason, "OK"));
52 fail_unless (version == GST_RTSP_VERSION_1_0);
58 test_response_400 (GstRTSPClient * client, GstRTSPMessage * response,
59 gboolean close, gpointer user_data)
61 GstRTSPStatusCode code;
63 GstRTSPVersion version;
65 fail_unless (gst_rtsp_message_get_type (response) ==
66 GST_RTSP_MESSAGE_RESPONSE);
68 fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
71 fail_unless (code == GST_RTSP_STS_BAD_REQUEST);
72 fail_unless (g_str_equal (reason, "Bad Request"));
73 fail_unless (version == GST_RTSP_VERSION_1_0);
79 test_response_404 (GstRTSPClient * client, GstRTSPMessage * response,
80 gboolean close, gpointer user_data)
82 GstRTSPStatusCode code;
84 GstRTSPVersion version;
86 fail_unless (gst_rtsp_message_get_type (response) ==
87 GST_RTSP_MESSAGE_RESPONSE);
89 fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
92 fail_unless (code == GST_RTSP_STS_NOT_FOUND);
93 fail_unless (g_str_equal (reason, "Not Found"));
94 fail_unless (version == GST_RTSP_VERSION_1_0);
100 test_response_454 (GstRTSPClient * client, GstRTSPMessage * response,
101 gboolean close, gpointer user_data)
103 GstRTSPStatusCode code;
105 GstRTSPVersion version;
107 fail_unless (gst_rtsp_message_get_type (response) ==
108 GST_RTSP_MESSAGE_RESPONSE);
110 fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
113 fail_unless (code == GST_RTSP_STS_SESSION_NOT_FOUND);
114 fail_unless (g_str_equal (reason, "Session Not Found"));
115 fail_unless (version == GST_RTSP_VERSION_1_0);
121 test_response_551 (GstRTSPClient * client, GstRTSPMessage * response,
122 gboolean close, gpointer user_data)
124 GstRTSPStatusCode code;
126 GstRTSPVersion version;
129 fail_unless (gst_rtsp_message_get_type (response) ==
130 GST_RTSP_MESSAGE_RESPONSE);
132 fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
135 fail_unless (code == GST_RTSP_STS_OPTION_NOT_SUPPORTED);
136 fail_unless (g_str_equal (reason, "Option not supported"));
137 fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_UNSUPPORTED,
138 &options, 0) == GST_RTSP_OK);
139 fail_unless (!g_strcmp0 (expected_unsupported_header, options));
140 fail_unless (version == GST_RTSP_VERSION_1_0);
146 create_connection (GstRTSPConnection ** conn)
149 GError *error = NULL;
151 sock = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_STREAM,
152 G_SOCKET_PROTOCOL_TCP, &error);
153 g_assert_no_error (error);
154 fail_unless (gst_rtsp_connection_create_from_socket (sock, "127.0.0.1", 444,
155 NULL, conn) == GST_RTSP_OK);
156 g_object_unref (sock);
159 static GstRTSPClient *
160 setup_client (const gchar * launch_line)
162 GstRTSPClient *client;
163 GstRTSPSessionPool *session_pool;
164 GstRTSPMountPoints *mount_points;
165 GstRTSPMediaFactory *factory;
166 GstRTSPThreadPool *thread_pool;
168 client = gst_rtsp_client_new ();
170 session_pool = gst_rtsp_session_pool_new ();
171 gst_rtsp_client_set_session_pool (client, session_pool);
173 mount_points = gst_rtsp_mount_points_new ();
174 factory = gst_rtsp_media_factory_new ();
175 if (launch_line == NULL)
176 gst_rtsp_media_factory_set_launch (factory,
177 "( " VIDEO_PIPELINE " " AUDIO_PIPELINE " )");
179 gst_rtsp_media_factory_set_launch (factory, launch_line);
181 gst_rtsp_mount_points_add_factory (mount_points, "/test", factory);
182 gst_rtsp_client_set_mount_points (client, mount_points);
184 thread_pool = gst_rtsp_thread_pool_new ();
185 gst_rtsp_client_set_thread_pool (client, thread_pool);
187 g_object_unref (mount_points);
188 g_object_unref (session_pool);
189 g_object_unref (thread_pool);
195 teardown_client (GstRTSPClient * client)
197 gst_rtsp_client_set_thread_pool (client, NULL);
198 g_object_unref (client);
202 check_requirements_cb (GstRTSPClient * client, GstRTSPContext * ctx,
203 gchar ** req, gpointer user_data)
206 GString *result = g_string_new ("");
208 while (req[index] != NULL) {
209 if (g_strcmp0 (req[index], "test-requirements")) {
211 g_string_append (result, ", ");
212 g_string_append (result, req[index]);
217 return g_string_free (result, FALSE);
220 GST_START_TEST (test_require)
222 GstRTSPClient *client;
223 GstRTSPMessage request = { 0, };
226 client = gst_rtsp_client_new ();
228 /* require header without handler */
229 fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
230 "rtsp://localhost/test") == GST_RTSP_OK);
231 str = g_strdup_printf ("test-not-supported1");
232 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_REQUIRE, str);
235 expected_unsupported_header = "test-not-supported1";
236 gst_rtsp_client_set_send_func (client, test_response_551, NULL, NULL);
237 fail_unless (gst_rtsp_client_handle_message (client,
238 &request) == GST_RTSP_OK);
239 gst_rtsp_message_unset (&request);
241 g_signal_connect (G_OBJECT (client), "check-requirements",
242 G_CALLBACK (check_requirements_cb), NULL);
244 /* one supported option */
245 fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
246 "rtsp://localhost/test") == GST_RTSP_OK);
247 str = g_strdup_printf ("test-requirements");
248 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_REQUIRE, str);
251 gst_rtsp_client_set_send_func (client, test_response_200, NULL, NULL);
252 fail_unless (gst_rtsp_client_handle_message (client,
253 &request) == GST_RTSP_OK);
254 gst_rtsp_message_unset (&request);
256 /* unsupported option */
257 fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
258 "rtsp://localhost/test") == GST_RTSP_OK);
259 str = g_strdup_printf ("test-not-supported1");
260 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_REQUIRE, str);
263 expected_unsupported_header = "test-not-supported1";
264 gst_rtsp_client_set_send_func (client, test_response_551, NULL, NULL);
265 fail_unless (gst_rtsp_client_handle_message (client,
266 &request) == GST_RTSP_OK);
267 gst_rtsp_message_unset (&request);
269 /* more than one unsupported options */
270 fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
271 "rtsp://localhost/test") == GST_RTSP_OK);
272 str = g_strdup_printf ("test-not-supported1");
273 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_REQUIRE, str);
275 str = g_strdup_printf ("test-not-supported2");
276 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_REQUIRE, str);
279 expected_unsupported_header = "test-not-supported1, test-not-supported2";
280 gst_rtsp_client_set_send_func (client, test_response_551, NULL, NULL);
281 fail_unless (gst_rtsp_client_handle_message (client,
282 &request) == GST_RTSP_OK);
283 gst_rtsp_message_unset (&request);
285 /* supported and unsupported together */
286 fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
287 "rtsp://localhost/test") == GST_RTSP_OK);
288 str = g_strdup_printf ("test-not-supported1");
289 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_REQUIRE, str);
291 str = g_strdup_printf ("test-requirements");
292 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_REQUIRE, str);
294 str = g_strdup_printf ("test-not-supported2");
295 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_REQUIRE, str);
298 expected_unsupported_header = "test-not-supported1, test-not-supported2";
299 gst_rtsp_client_set_send_func (client, test_response_551, NULL, NULL);
300 fail_unless (gst_rtsp_client_handle_message (client,
301 &request) == GST_RTSP_OK);
302 gst_rtsp_message_unset (&request);
304 g_object_unref (client);
309 GST_START_TEST (test_request)
311 GstRTSPClient *client;
312 GstRTSPMessage request = { 0, };
314 GstRTSPConnection *conn;
316 client = gst_rtsp_client_new ();
318 /* OPTIONS with invalid url */
319 fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
320 "foopy://padoop/") == GST_RTSP_OK);
321 str = g_strdup_printf ("%d", cseq);
322 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
325 gst_rtsp_client_set_send_func (client, test_response_400, NULL, NULL);
326 fail_unless (gst_rtsp_client_handle_message (client,
327 &request) == GST_RTSP_OK);
329 gst_rtsp_message_unset (&request);
331 /* OPTIONS with unknown session id */
332 fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
333 "rtsp://localhost/test") == GST_RTSP_OK);
334 str = g_strdup_printf ("%d", cseq);
335 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
337 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_SESSION, "foobar");
339 gst_rtsp_client_set_send_func (client, test_response_454, NULL, NULL);
340 fail_unless (gst_rtsp_client_handle_message (client,
341 &request) == GST_RTSP_OK);
343 gst_rtsp_message_unset (&request);
345 /* OPTIONS with an absolute path instead of an absolute url */
346 /* set host information */
347 create_connection (&conn);
348 fail_unless (gst_rtsp_client_set_connection (client, conn));
349 fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
350 "/test") == GST_RTSP_OK);
351 str = g_strdup_printf ("%d", cseq);
352 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
355 gst_rtsp_client_set_send_func (client, test_response_200, NULL, NULL);
356 fail_unless (gst_rtsp_client_handle_message (client,
357 &request) == GST_RTSP_OK);
358 gst_rtsp_message_unset (&request);
360 /* OPTIONS with an absolute path instead of an absolute url with invalid
361 * host information */
362 g_object_unref (client);
363 client = gst_rtsp_client_new ();
364 fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
365 "/test") == GST_RTSP_OK);
366 str = g_strdup_printf ("%d", cseq);
367 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
370 gst_rtsp_client_set_send_func (client, test_response_400, NULL, NULL);
371 fail_unless (gst_rtsp_client_handle_message (client,
372 &request) == GST_RTSP_OK);
373 gst_rtsp_message_unset (&request);
375 g_object_unref (client);
381 test_option_response_200 (GstRTSPClient * client, GstRTSPMessage * response,
382 gboolean close, gpointer user_data)
384 GstRTSPStatusCode code;
386 GstRTSPVersion version;
388 GstRTSPMethod methods;
390 fail_unless (gst_rtsp_message_get_type (response) ==
391 GST_RTSP_MESSAGE_RESPONSE);
393 fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
396 fail_unless (code == GST_RTSP_STS_OK);
397 fail_unless (g_str_equal (reason, "OK"));
398 fail_unless (version == GST_RTSP_VERSION_1_0);
400 fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_CSEQ, &str,
402 fail_unless (atoi (str) == cseq++);
404 fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_PUBLIC, &str,
407 methods = gst_rtsp_options_from_text (str);
408 fail_if (methods == 0);
409 fail_unless (methods == (GST_RTSP_DESCRIBE |
416 GST_RTSP_GET_PARAMETER | GST_RTSP_SET_PARAMETER | GST_RTSP_TEARDOWN));
421 GST_START_TEST (test_options)
423 GstRTSPClient *client;
424 GstRTSPMessage request = { 0, };
427 client = gst_rtsp_client_new ();
430 fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
431 "rtsp://localhost/test") == GST_RTSP_OK);
432 str = g_strdup_printf ("%d", cseq);
433 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
436 gst_rtsp_client_set_send_func (client, test_option_response_200, NULL, NULL);
437 fail_unless (gst_rtsp_client_handle_message (client,
438 &request) == GST_RTSP_OK);
439 gst_rtsp_message_unset (&request);
441 g_object_unref (client);
446 GST_START_TEST (test_describe)
448 GstRTSPClient *client;
449 GstRTSPMessage request = { 0, };
452 client = gst_rtsp_client_new ();
454 /* simple DESCRIBE for non-existing url */
455 fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_DESCRIBE,
456 "rtsp://localhost/test") == GST_RTSP_OK);
457 str = g_strdup_printf ("%d", cseq);
458 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
461 gst_rtsp_client_set_send_func (client, test_response_404, NULL, NULL);
462 fail_unless (gst_rtsp_client_handle_message (client,
463 &request) == GST_RTSP_OK);
464 gst_rtsp_message_unset (&request);
466 g_object_unref (client);
468 /* simple DESCRIBE for an existing url */
469 client = setup_client (NULL);
470 fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_DESCRIBE,
471 "rtsp://localhost/test") == GST_RTSP_OK);
472 str = g_strdup_printf ("%d", cseq);
473 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
476 gst_rtsp_client_set_send_func (client, test_response_200, NULL, NULL);
477 fail_unless (gst_rtsp_client_handle_message (client,
478 &request) == GST_RTSP_OK);
479 gst_rtsp_message_unset (&request);
481 teardown_client (client);
486 static const gchar *expected_transport = NULL;
489 test_setup_response_200 (GstRTSPClient * client, GstRTSPMessage * response,
490 gboolean close, gpointer user_data)
492 GstRTSPStatusCode code;
494 GstRTSPVersion version;
497 GstRTSPSessionPool *session_pool;
498 GstRTSPSession *session;
499 gchar **session_hdr_params;
501 fail_unless (expected_transport != NULL);
503 fail_unless_equals_int (gst_rtsp_message_get_type (response),
504 GST_RTSP_MESSAGE_RESPONSE);
506 fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
509 fail_unless_equals_int (code, GST_RTSP_STS_OK);
510 fail_unless_equals_string (reason, "OK");
511 fail_unless_equals_int (version, GST_RTSP_VERSION_1_0);
513 fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_CSEQ, &str,
515 fail_unless (atoi (str) == cseq++);
517 fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_TRANSPORT,
518 &str, 0) == GST_RTSP_OK);
520 pattern = g_strdup_printf ("^%s$", expected_transport);
521 fail_unless (g_regex_match_simple (pattern, str, 0, 0),
522 "Transport '%s' doesn't match pattern '%s'", str, pattern);
525 fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_SESSION,
526 &str, 0) == GST_RTSP_OK);
527 session_hdr_params = g_strsplit (str, ";", -1);
529 /* session-id value */
530 fail_unless (session_hdr_params[0] != NULL);
532 if (expected_session_timeout != 60) {
533 /* session timeout param */
534 gchar *timeout_str = g_strdup_printf ("timeout=%u",
535 expected_session_timeout);
537 fail_unless (session_hdr_params[1] != NULL);
538 g_strstrip (session_hdr_params[1]);
539 fail_unless (g_strcmp0 (session_hdr_params[1], timeout_str) == 0);
540 g_free (timeout_str);
543 session_pool = gst_rtsp_client_get_session_pool (client);
544 fail_unless (session_pool != NULL);
546 session = gst_rtsp_session_pool_find (session_pool, session_hdr_params[0]);
547 g_strfreev (session_hdr_params);
549 /* remember session id to be able to send teardown */
552 session_id = g_strdup (gst_rtsp_session_get_sessionid (session));
553 fail_unless (session_id != NULL);
555 fail_unless (session != NULL);
556 g_object_unref (session);
558 g_object_unref (session_pool);
565 test_setup_response_461 (GstRTSPClient * client,
566 GstRTSPMessage * response, gboolean close, gpointer user_data)
568 GstRTSPStatusCode code;
570 GstRTSPVersion version;
573 fail_unless (expected_transport == NULL);
575 fail_unless (gst_rtsp_message_get_type (response) ==
576 GST_RTSP_MESSAGE_RESPONSE);
578 fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
581 fail_unless (code == GST_RTSP_STS_UNSUPPORTED_TRANSPORT);
582 fail_unless (g_str_equal (reason, "Unsupported transport"));
583 fail_unless (version == GST_RTSP_VERSION_1_0);
585 fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_CSEQ, &str,
587 fail_unless (atoi (str) == cseq++);
594 test_teardown_response_200 (GstRTSPClient * client,
595 GstRTSPMessage * response, gboolean close, gpointer user_data)
597 GstRTSPStatusCode code;
599 GstRTSPVersion version;
601 fail_unless (gst_rtsp_message_get_type (response) ==
602 GST_RTSP_MESSAGE_RESPONSE);
604 fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
607 fail_unless (code == GST_RTSP_STS_OK);
608 fail_unless (g_str_equal (reason, "OK"));
609 fail_unless (version == GST_RTSP_VERSION_1_0);
615 send_teardown (GstRTSPClient * client)
617 GstRTSPMessage request = { 0, };
620 fail_unless (session_id != NULL);
621 fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_TEARDOWN,
622 "rtsp://localhost/test") == GST_RTSP_OK);
623 str = g_strdup_printf ("%d", cseq);
624 gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
625 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_SESSION, session_id);
626 gst_rtsp_client_set_send_func (client, test_teardown_response_200,
628 fail_unless (gst_rtsp_client_handle_message (client,
629 &request) == GST_RTSP_OK);
630 gst_rtsp_message_unset (&request);
635 GST_START_TEST (test_setup_tcp)
637 GstRTSPClient *client;
638 GstRTSPConnection *conn;
639 GstRTSPMessage request = { 0, };
642 client = setup_client (NULL);
643 create_connection (&conn);
644 fail_unless (gst_rtsp_client_set_connection (client, conn));
646 fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
647 "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
648 str = g_strdup_printf ("%d", cseq);
649 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
651 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
652 "RTP/AVP/TCP;unicast");
654 gst_rtsp_client_set_send_func (client, test_setup_response_200, NULL, NULL);
656 "RTP/AVP/TCP;unicast;interleaved=0-1;ssrc=.*;mode=\"PLAY\"";
657 fail_unless (gst_rtsp_client_handle_message (client,
658 &request) == GST_RTSP_OK);
660 gst_rtsp_message_unset (&request);
662 send_teardown (client);
663 teardown_client (client);
668 GST_START_TEST (test_setup_tcp_two_streams_same_channels)
670 GstRTSPClient *client;
671 GstRTSPConnection *conn;
672 GstRTSPMessage request = { 0, };
675 client = setup_client (NULL);
676 create_connection (&conn);
677 fail_unless (gst_rtsp_client_set_connection (client, conn));
679 /* test SETUP of a video stream with 0-1 as interleaved channels */
680 fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
681 "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
682 str = g_strdup_printf ("%d", cseq);
683 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
685 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
686 "RTP/AVP/TCP;unicast;interleaved=0-1");
687 gst_rtsp_client_set_send_func (client, test_setup_response_200, NULL, NULL);
689 "RTP/AVP/TCP;unicast;interleaved=0-1;ssrc=.*;mode=\"PLAY\"";
690 fail_unless (gst_rtsp_client_handle_message (client,
691 &request) == GST_RTSP_OK);
692 gst_rtsp_message_unset (&request);
694 /* test SETUP of an audio stream with *the same* interleaved channels.
695 * we expect the server to allocate new channel numbers */
696 fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
697 "rtsp://localhost/test/stream=1") == GST_RTSP_OK);
698 str = g_strdup_printf ("%d", cseq);
699 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
701 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
702 "RTP/AVP/TCP;unicast;interleaved=0-1");
703 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_SESSION, session_id);
704 gst_rtsp_client_set_send_func (client, test_setup_response_200, NULL, NULL);
706 "RTP/AVP/TCP;unicast;interleaved=2-3;ssrc=.*;mode=\"PLAY\"";
707 fail_unless (gst_rtsp_client_handle_message (client,
708 &request) == GST_RTSP_OK);
709 gst_rtsp_message_unset (&request);
711 send_teardown (client);
712 teardown_client (client);
717 static GstRTSPClient *
718 setup_multicast_client (guint max_ttl)
720 GstRTSPClient *client;
721 GstRTSPSessionPool *session_pool;
722 GstRTSPMountPoints *mount_points;
723 GstRTSPMediaFactory *factory;
724 GstRTSPAddressPool *address_pool;
725 GstRTSPThreadPool *thread_pool;
727 client = gst_rtsp_client_new ();
729 session_pool = gst_rtsp_session_pool_new ();
730 gst_rtsp_client_set_session_pool (client, session_pool);
732 mount_points = gst_rtsp_mount_points_new ();
733 factory = gst_rtsp_media_factory_new ();
734 gst_rtsp_media_factory_set_launch (factory,
735 "audiotestsrc ! audio/x-raw,rate=44100 ! audioconvert ! rtpL16pay name=pay0");
736 address_pool = gst_rtsp_address_pool_new ();
737 fail_unless (gst_rtsp_address_pool_add_range (address_pool,
738 "233.252.0.1", "233.252.0.1", 5000, 5010, 1));
739 gst_rtsp_media_factory_set_address_pool (factory, address_pool);
740 gst_rtsp_media_factory_add_role (factory, "user",
741 "media.factory.access", G_TYPE_BOOLEAN, TRUE,
742 "media.factory.construct", G_TYPE_BOOLEAN, TRUE, NULL);
743 gst_rtsp_mount_points_add_factory (mount_points, "/test", factory);
744 gst_rtsp_client_set_mount_points (client, mount_points);
745 gst_rtsp_media_factory_set_max_mcast_ttl (factory, max_ttl);
747 thread_pool = gst_rtsp_thread_pool_new ();
748 gst_rtsp_client_set_thread_pool (client, thread_pool);
750 g_object_unref (mount_points);
751 g_object_unref (session_pool);
752 g_object_unref (address_pool);
753 g_object_unref (thread_pool);
758 GST_START_TEST (test_client_multicast_transport_404)
760 GstRTSPClient *client;
761 GstRTSPMessage request = { 0, };
764 client = setup_multicast_client (1);
766 /* simple SETUP for non-existing url */
767 fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
768 "rtsp://localhost/test2/stream=0") == GST_RTSP_OK);
769 str = g_strdup_printf ("%d", cseq);
770 gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
771 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
772 "RTP/AVP;multicast");
774 gst_rtsp_client_set_send_func (client, test_response_404, NULL, NULL);
775 fail_unless (gst_rtsp_client_handle_message (client,
776 &request) == GST_RTSP_OK);
777 gst_rtsp_message_unset (&request);
779 teardown_client (client);
785 new_session_cb (GObject * client, GstRTSPSession * session, gpointer user_data)
787 GST_DEBUG ("%p: new session %p", client, session);
788 gst_rtsp_session_set_timeout (session, expected_session_timeout);
791 GST_START_TEST (test_client_multicast_transport)
793 GstRTSPClient *client;
794 GstRTSPMessage request = { 0, };
797 client = setup_multicast_client (1);
799 expected_session_timeout = 20;
800 g_signal_connect (G_OBJECT (client), "new-session",
801 G_CALLBACK (new_session_cb), NULL);
803 /* simple SETUP with a valid URI and multicast */
804 fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
805 "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
806 str = g_strdup_printf ("%d", cseq);
807 gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
808 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
809 "RTP/AVP;multicast");
811 expected_transport = "RTP/AVP;multicast;destination=233.252.0.1;"
812 "ttl=1;port=5000-5001;mode=\"PLAY\"";
813 gst_rtsp_client_set_send_func (client, test_setup_response_200, NULL, NULL);
814 fail_unless (gst_rtsp_client_handle_message (client,
815 &request) == GST_RTSP_OK);
816 gst_rtsp_message_unset (&request);
817 expected_transport = NULL;
818 expected_session_timeout = 60;
820 send_teardown (client);
822 teardown_client (client);
827 GST_START_TEST (test_client_multicast_ignore_transport_specific)
829 GstRTSPClient *client;
830 GstRTSPMessage request = { 0, };
833 client = setup_multicast_client (1);
835 /* simple SETUP with a valid URI and multicast and a specific dest,
837 fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
838 "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
839 str = g_strdup_printf ("%d", cseq);
840 gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
841 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
842 "RTP/AVP;multicast;destination=233.252.0.2;ttl=2;port=5001-5006;");
844 expected_transport = "RTP/AVP;multicast;destination=233.252.0.1;"
845 "ttl=1;port=5000-5001;mode=\"PLAY\"";
846 gst_rtsp_client_set_send_func (client, test_setup_response_200, NULL, NULL);
847 fail_unless (gst_rtsp_client_handle_message (client,
848 &request) == GST_RTSP_OK);
849 gst_rtsp_message_unset (&request);
850 expected_transport = NULL;
852 send_teardown (client);
854 teardown_client (client);
860 multicast_transport_specific (void)
862 GstRTSPClient *client;
863 GstRTSPMessage request = { 0, };
865 GstRTSPSessionPool *session_pool;
866 GstRTSPContext ctx = { NULL };
868 client = setup_multicast_client (1);
871 ctx.auth = gst_rtsp_auth_new ();
873 gst_rtsp_token_new (GST_RTSP_TOKEN_TRANSPORT_CLIENT_SETTINGS,
874 G_TYPE_BOOLEAN, TRUE, GST_RTSP_TOKEN_MEDIA_FACTORY_ROLE, G_TYPE_STRING,
876 gst_rtsp_context_push_current (&ctx);
878 /* simple SETUP with a valid URI */
879 fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
880 "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
881 str = g_strdup_printf ("%d", cseq);
882 gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
883 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
886 gst_rtsp_client_set_send_func (client, test_setup_response_200, NULL, NULL);
887 fail_unless (gst_rtsp_client_handle_message (client,
888 &request) == GST_RTSP_OK);
889 gst_rtsp_message_unset (&request);
891 gst_rtsp_client_set_send_func (client, test_setup_response_200, NULL, NULL);
892 session_pool = gst_rtsp_client_get_session_pool (client);
893 fail_unless (session_pool != NULL);
894 fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 1);
895 g_object_unref (session_pool);
897 /* send PLAY request */
898 fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_PLAY,
899 "rtsp://localhost/test") == GST_RTSP_OK);
900 str = g_strdup_printf ("%d", cseq);
901 gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
902 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_SESSION, session_id);
903 gst_rtsp_client_set_send_func (client, test_response_200, NULL, NULL);
904 fail_unless (gst_rtsp_client_handle_message (client,
905 &request) == GST_RTSP_OK);
906 gst_rtsp_message_unset (&request);
908 send_teardown (client);
909 teardown_client (client);
910 g_object_unref (ctx.auth);
911 gst_rtsp_token_unref (ctx.token);
912 gst_rtsp_context_pop_current (&ctx);
915 /* CASE: multicast address requested by the client exists in the address pool */
916 GST_START_TEST (test_client_multicast_transport_specific)
918 expected_transport = "RTP/AVP;multicast;destination=233.252.0.1;"
919 "ttl=1;port=5000-5001;mode=\"PLAY\"";
920 multicast_transport_specific ();
921 expected_transport = NULL;
926 /* CASE: multicast address requested by the client does not exist in the address pool */
927 GST_START_TEST (test_client_multicast_transport_specific_no_address_in_pool)
929 expected_transport = "RTP/AVP;multicast;destination=234.252.0.3;"
930 "ttl=1;port=6000-6001;mode=\"PLAY\"";
931 multicast_transport_specific ();
932 expected_transport = NULL;
938 test_response_sdp (GstRTSPClient * client, GstRTSPMessage * response,
939 gboolean close, gpointer user_data)
943 GstSDPMessage *sdp_msg;
944 const GstSDPMedia *sdp_media;
945 const GstSDPBandwidth *bw;
946 gint bandwidth_val = GPOINTER_TO_INT (user_data);
948 fail_unless (gst_rtsp_message_get_body (response, &data, &size)
950 gst_sdp_message_new (&sdp_msg);
951 fail_unless (gst_sdp_message_parse_buffer (data, size, sdp_msg)
954 /* session description */
956 fail_unless (gst_sdp_message_get_version (sdp_msg) != NULL);
958 fail_unless (gst_sdp_message_get_origin (sdp_msg) != NULL);
960 fail_unless (gst_sdp_message_get_session_name (sdp_msg) != NULL);
962 fail_unless (gst_sdp_message_times_len (sdp_msg) == 0);
964 /* verify number of medias */
965 fail_unless (gst_sdp_message_medias_len (sdp_msg) == 1);
967 /* media description */
968 sdp_media = gst_sdp_message_get_media (sdp_msg, 0);
969 fail_unless (sdp_media != NULL);
972 fail_unless (gst_sdp_media_get_media (sdp_media) != NULL);
974 /* media bandwidth */
976 fail_unless (gst_sdp_media_bandwidths_len (sdp_media) == 1);
977 bw = gst_sdp_media_get_bandwidth (sdp_media, 0);
978 fail_unless (bw != NULL);
979 fail_unless (g_strcmp0 (bw->bwtype, "AS") == 0);
980 fail_unless (bw->bandwidth == bandwidth_val);
982 fail_unless (gst_sdp_media_bandwidths_len (sdp_media) == 0);
985 gst_sdp_message_free (sdp_msg);
991 test_client_sdp (const gchar * launch_line, guint * bandwidth_val)
993 GstRTSPClient *client;
994 GstRTSPMessage request = { 0, };
997 /* simple DESCRIBE for an existing url */
998 client = setup_client (launch_line);
999 fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_DESCRIBE,
1000 "rtsp://localhost/test") == GST_RTSP_OK);
1001 str = g_strdup_printf ("%d", cseq);
1002 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
1005 gst_rtsp_client_set_send_func (client, test_response_sdp,
1006 (gpointer) bandwidth_val, NULL);
1007 fail_unless (gst_rtsp_client_handle_message (client,
1008 &request) == GST_RTSP_OK);
1009 gst_rtsp_message_unset (&request);
1011 teardown_client (client);
1014 GST_START_TEST (test_client_sdp_with_max_bitrate_tag)
1016 test_client_sdp ("videotestsrc "
1017 "! taginject tags=\"maximum-bitrate=(uint)50000000\" "
1018 "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
1019 GUINT_TO_POINTER (50000));
1022 /* max-bitrate=0: no bandwidth line */
1023 test_client_sdp ("videotestsrc "
1024 "! taginject tags=\"maximum-bitrate=(uint)0\" "
1025 "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
1026 GUINT_TO_POINTER (0));
1031 GST_START_TEST (test_client_sdp_with_bitrate_tag)
1033 test_client_sdp ("videotestsrc "
1034 "! taginject tags=\"bitrate=(uint)7000000\" "
1035 "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
1036 GUINT_TO_POINTER (7000));
1038 /* bitrate=0: no bandwdith line */
1039 test_client_sdp ("videotestsrc "
1040 "! taginject tags=\"bitrate=(uint)0\" "
1041 "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
1042 GUINT_TO_POINTER (0));
1047 GST_START_TEST (test_client_sdp_with_max_bitrate_and_bitrate_tags)
1049 test_client_sdp ("videotestsrc "
1050 "! taginject tags=\"bitrate=(uint)7000000,maximum-bitrate=(uint)50000000\" "
1051 "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
1052 GUINT_TO_POINTER (50000));
1054 /* max-bitrate is zero: fallback to bitrate */
1055 test_client_sdp ("videotestsrc "
1056 "! taginject tags=\"bitrate=(uint)7000000,maximum-bitrate=(uint)0\" "
1057 "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
1058 GUINT_TO_POINTER (7000));
1060 /* max-bitrate=bitrate=0o: no bandwidth line */
1061 test_client_sdp ("videotestsrc "
1062 "! taginject tags=\"bitrate=(uint)0,maximum-bitrate=(uint)0\" "
1063 "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96",
1064 GUINT_TO_POINTER (0));
1069 GST_START_TEST (test_client_sdp_with_no_bitrate_tags)
1071 test_client_sdp ("videotestsrc "
1072 "! video/x-raw,width=352,height=288 ! rtpgstpay name=pay0 pt=96", NULL);
1078 mcast_transport_two_clients (gboolean shared, const gchar * transport1,
1079 const gchar * expected_transport1, const gchar * addr1,
1080 const gchar * transport2, const gchar * expected_transport2,
1081 const gchar * addr2, gboolean bind_mcast_address)
1083 GstRTSPClient *client1, *client2;
1084 GstRTSPMessage request = { 0, };
1086 GstRTSPSessionPool *session_pool;
1087 GstRTSPContext ctx = { NULL };
1088 GstRTSPContext ctx2 = { NULL };
1089 GstRTSPMountPoints *mount_points;
1090 GstRTSPMediaFactory *factory;
1091 GstRTSPAddressPool *address_pool;
1092 GstRTSPThreadPool *thread_pool;
1094 gchar *client_addr = NULL;
1096 mount_points = gst_rtsp_mount_points_new ();
1097 factory = gst_rtsp_media_factory_new ();
1099 gst_rtsp_media_factory_set_shared (factory, TRUE);
1100 gst_rtsp_media_factory_set_max_mcast_ttl (factory, 5);
1101 gst_rtsp_media_factory_set_bind_mcast_address (factory, bind_mcast_address);
1102 gst_rtsp_media_factory_set_launch (factory,
1103 "audiotestsrc ! audio/x-raw,rate=44100 ! audioconvert ! rtpL16pay name=pay0");
1104 address_pool = gst_rtsp_address_pool_new ();
1105 fail_unless (gst_rtsp_address_pool_add_range (address_pool,
1106 "233.252.0.1", "233.252.0.1", 5000, 5001, 1));
1107 gst_rtsp_media_factory_set_address_pool (factory, address_pool);
1108 gst_rtsp_media_factory_add_role (factory, "user",
1109 "media.factory.access", G_TYPE_BOOLEAN, TRUE,
1110 "media.factory.construct", G_TYPE_BOOLEAN, TRUE, NULL);
1111 gst_rtsp_mount_points_add_factory (mount_points, "/test", factory);
1112 session_pool = gst_rtsp_session_pool_new ();
1113 thread_pool = gst_rtsp_thread_pool_new ();
1115 /* first multicast client with transport specific request */
1116 client1 = gst_rtsp_client_new ();
1117 gst_rtsp_client_set_session_pool (client1, session_pool);
1118 gst_rtsp_client_set_mount_points (client1, mount_points);
1119 gst_rtsp_client_set_thread_pool (client1, thread_pool);
1121 ctx.client = client1;
1122 ctx.auth = gst_rtsp_auth_new ();
1124 gst_rtsp_token_new (GST_RTSP_TOKEN_TRANSPORT_CLIENT_SETTINGS,
1125 G_TYPE_BOOLEAN, TRUE, GST_RTSP_TOKEN_MEDIA_FACTORY_ROLE, G_TYPE_STRING,
1127 gst_rtsp_context_push_current (&ctx);
1129 expected_transport = expected_transport1;
1131 /* send SETUP request */
1132 fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
1133 "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
1134 str = g_strdup_printf ("%d", cseq);
1135 gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
1136 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT, transport1);
1138 gst_rtsp_client_set_send_func (client1, test_setup_response_200, NULL, NULL);
1139 fail_unless (gst_rtsp_client_handle_message (client1,
1140 &request) == GST_RTSP_OK);
1141 gst_rtsp_message_unset (&request);
1142 expected_transport = NULL;
1144 /* send PLAY request */
1145 fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_PLAY,
1146 "rtsp://localhost/test") == GST_RTSP_OK);
1147 str = g_strdup_printf ("%d", cseq);
1148 gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
1149 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_SESSION, session_id);
1150 gst_rtsp_client_set_send_func (client1, test_response_200, NULL, NULL);
1151 fail_unless (gst_rtsp_client_handle_message (client1,
1152 &request) == GST_RTSP_OK);
1153 gst_rtsp_message_unset (&request);
1156 client_addr = gst_rtsp_stream_get_multicast_client_addresses (ctx.stream);
1157 fail_if (client_addr == NULL);
1158 fail_unless (g_str_equal (client_addr, addr1));
1159 g_free (client_addr);
1161 gst_rtsp_context_pop_current (&ctx);
1162 session_id1 = g_strdup (session_id);
1164 /* second multicast client with transport specific request */
1166 client2 = gst_rtsp_client_new ();
1167 gst_rtsp_client_set_session_pool (client2, session_pool);
1168 gst_rtsp_client_set_mount_points (client2, mount_points);
1169 gst_rtsp_client_set_thread_pool (client2, thread_pool);
1171 ctx2.client = client2;
1172 ctx2.auth = gst_rtsp_auth_new ();
1174 gst_rtsp_token_new (GST_RTSP_TOKEN_TRANSPORT_CLIENT_SETTINGS,
1175 G_TYPE_BOOLEAN, TRUE, GST_RTSP_TOKEN_MEDIA_FACTORY_ROLE, G_TYPE_STRING,
1177 gst_rtsp_context_push_current (&ctx2);
1179 expected_transport = expected_transport2;
1181 /* send SETUP request */
1182 fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
1183 "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
1184 str = g_strdup_printf ("%d", cseq);
1185 gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
1186 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT, transport2);
1188 gst_rtsp_client_set_send_func (client2, test_setup_response_200, NULL, NULL);
1189 fail_unless (gst_rtsp_client_handle_message (client2,
1190 &request) == GST_RTSP_OK);
1191 gst_rtsp_message_unset (&request);
1192 expected_transport = NULL;
1194 /* send PLAY request */
1195 fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_PLAY,
1196 "rtsp://localhost/test") == GST_RTSP_OK);
1197 str = g_strdup_printf ("%d", cseq);
1198 gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
1199 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_SESSION, session_id);
1200 gst_rtsp_client_set_send_func (client2, test_response_200, NULL, NULL);
1201 fail_unless (gst_rtsp_client_handle_message (client2,
1202 &request) == GST_RTSP_OK);
1203 gst_rtsp_message_unset (&request);
1205 /* check addresses */
1206 client_addr = gst_rtsp_stream_get_multicast_client_addresses (ctx2.stream);
1207 fail_if (client_addr == NULL);
1209 if (g_str_equal (addr1, addr2)) {
1210 fail_unless (g_str_equal (client_addr, addr1));
1212 gchar *addr_str = g_strdup_printf ("%s,%s", addr2, addr1);
1213 fail_unless (g_str_equal (client_addr, addr_str));
1217 fail_unless (g_str_equal (client_addr, addr2));
1219 g_free (client_addr);
1221 send_teardown (client2);
1222 gst_rtsp_context_pop_current (&ctx2);
1224 gst_rtsp_context_push_current (&ctx);
1225 session_id = session_id1;
1226 send_teardown (client1);
1227 gst_rtsp_context_pop_current (&ctx);
1229 teardown_client (client1);
1230 teardown_client (client2);
1231 g_object_unref (ctx.auth);
1232 g_object_unref (ctx2.auth);
1233 gst_rtsp_token_unref (ctx.token);
1234 gst_rtsp_token_unref (ctx2.token);
1235 g_object_unref (mount_points);
1236 g_object_unref (session_pool);
1237 g_object_unref (address_pool);
1238 g_object_unref (thread_pool);
1241 /* test if two multicast clients can choose different transport settings
1242 * CASE: media is shared */
1244 (test_client_multicast_transport_specific_two_clients_shared_media) {
1245 const gchar *transport_client_1 = "RTP/AVP;multicast;destination=233.252.0.1;"
1246 "ttl=1;port=5000-5001;mode=\"PLAY\"";
1247 const gchar *expected_transport_1 = transport_client_1;
1248 const gchar *addr_client_1 = "233.252.0.1:5000";
1250 const gchar *transport_client_2 = "RTP/AVP;multicast;destination=233.252.0.2;"
1251 "ttl=1;port=5002-5003;mode=\"PLAY\"";
1252 const gchar *expected_transport_2 = transport_client_2;
1253 const gchar *addr_client_2 = "233.252.0.2:5002";
1255 mcast_transport_two_clients (TRUE, transport_client_1,
1256 expected_transport_1, addr_client_1, transport_client_2,
1257 expected_transport_2, addr_client_2, FALSE);
1262 /* test if two multicast clients can choose different transport settings
1263 * CASE: media is not shared */
1264 GST_START_TEST (test_client_multicast_transport_specific_two_clients)
1266 const gchar *transport_client_1 = "RTP/AVP;multicast;destination=233.252.0.1;"
1267 "ttl=1;port=5000-5001;mode=\"PLAY\"";
1268 const gchar *expected_transport_1 = transport_client_1;
1269 const gchar *addr_client_1 = "233.252.0.1:5000";
1271 const gchar *transport_client_2 = "RTP/AVP;multicast;destination=233.252.0.2;"
1272 "ttl=1;port=5002-5003;mode=\"PLAY\"";
1273 const gchar *expected_transport_2 = transport_client_2;
1274 const gchar *addr_client_2 = "233.252.0.2:5002";
1276 mcast_transport_two_clients (FALSE, transport_client_1,
1277 expected_transport_1, addr_client_1, transport_client_2,
1278 expected_transport_2, addr_client_2, FALSE);
1283 /* test if two multicast clients can choose the same ports but different
1284 * multicast destinations
1285 * CASE: media is not shared */
1286 GST_START_TEST (test_client_multicast_transport_specific_two_clients_same_ports)
1288 const gchar *transport_client_1 = "RTP/AVP;multicast;destination=233.252.0.1;"
1289 "ttl=1;port=9000-9001;mode=\"PLAY\"";
1290 const gchar *expected_transport_1 = transport_client_1;
1291 const gchar *addr_client_1 = "233.252.0.1:9000";
1293 const gchar *transport_client_2 = "RTP/AVP;multicast;destination=233.252.0.2;"
1294 "ttl=1;port=9000-9001;mode=\"PLAY\"";
1295 const gchar *expected_transport_2 = transport_client_2;
1296 const gchar *addr_client_2 = "233.252.0.2:9000";
1298 /* configure the multicast socket to be bound to the requested multicast address instead of INADDR_ANY.
1299 * The clients request the same rtp/rtcp borts and having the socket that are bound to ANY would result
1300 * in bind() failure */
1301 gboolean allow_bind_mcast_address = TRUE;
1303 mcast_transport_two_clients (FALSE, transport_client_1,
1304 expected_transport_1, addr_client_1, transport_client_2,
1305 expected_transport_2, addr_client_2, allow_bind_mcast_address);
1310 /* test if two multicast clients can choose the same multicast destination but different
1312 * CASE: media is not shared */
1314 (test_client_multicast_transport_specific_two_clients_same_destination) {
1315 const gchar *transport_client_1 = "RTP/AVP;multicast;destination=233.252.0.2;"
1316 "ttl=1;port=9002-9003;mode=\"PLAY\"";
1317 const gchar *expected_transport_1 = transport_client_1;
1318 const gchar *addr_client_1 = "233.252.0.2:9002";
1320 const gchar *transport_client_2 = "RTP/AVP;multicast;destination=233.252.0.2;"
1321 "ttl=1;port=9004-9005;mode=\"PLAY\"";
1322 const gchar *expected_transport_2 = transport_client_2;
1323 const gchar *addr_client_2 = "233.252.0.2:9004";
1325 mcast_transport_two_clients (FALSE, transport_client_1,
1326 expected_transport_1, addr_client_1, transport_client_2,
1327 expected_transport_2, addr_client_2, FALSE);
1331 /* test if two multicast clients can choose the same transport settings.
1332 * CASE: media is shared */
1334 (test_client_multicast_transport_specific_two_clients_shared_media_same_transport)
1337 const gchar *transport_client_1 = "RTP/AVP;multicast;destination=233.252.0.1;"
1338 "ttl=1;port=5000-5001;mode=\"PLAY\"";
1339 const gchar *expected_transport_1 = transport_client_1;
1340 const gchar *addr_client_1 = "233.252.0.1:5000";
1342 const gchar *transport_client_2 = transport_client_1;
1343 const gchar *expected_transport_2 = expected_transport_1;
1344 const gchar *addr_client_2 = addr_client_1;
1346 mcast_transport_two_clients (TRUE, transport_client_1,
1347 expected_transport_1, addr_client_1, transport_client_2,
1348 expected_transport_2, addr_client_2, FALSE);
1353 /* test if two multicast clients get the same transport settings without
1354 * requesting specific transport.
1355 * CASE: media is shared */
1356 GST_START_TEST (test_client_multicast_two_clients_shared_media)
1358 const gchar *transport_client_1 = "RTP/AVP;multicast;mode=\"PLAY\"";
1359 const gchar *expected_transport_1 =
1360 "RTP/AVP;multicast;destination=233.252.0.1;"
1361 "ttl=1;port=5000-5001;mode=\"PLAY\"";
1362 const gchar *addr_client_1 = "233.252.0.1:5000";
1364 const gchar *transport_client_2 = transport_client_1;
1365 const gchar *expected_transport_2 = expected_transport_1;
1366 const gchar *addr_client_2 = addr_client_1;
1368 mcast_transport_two_clients (TRUE, transport_client_1,
1369 expected_transport_1, addr_client_1, transport_client_2,
1370 expected_transport_2, addr_client_2, FALSE);
1375 /* test if two multicast clients get the different transport settings: the first client
1376 * requests the specific transport configuration while the second client lets
1377 * the server select the multicast address and the ports.
1378 * CASE: media is shared */
1380 (test_client_multicast_two_clients_first_specific_transport_shared_media) {
1381 const gchar *transport_client_1 = "RTP/AVP;multicast;destination=233.252.0.1;"
1382 "ttl=1;port=5000-5001;mode=\"PLAY\"";
1383 const gchar *expected_transport_1 = transport_client_1;
1384 const gchar *addr_client_1 = "233.252.0.1:5000";
1386 const gchar *transport_client_2 = "RTP/AVP;multicast;mode=\"PLAY\"";
1387 const gchar *expected_transport_2 = expected_transport_1;
1388 const gchar *addr_client_2 = addr_client_1;
1390 mcast_transport_two_clients (TRUE, transport_client_1,
1391 expected_transport_1, addr_client_1, transport_client_2,
1392 expected_transport_2, addr_client_2, FALSE);
1396 /* test if two multicast clients get the different transport settings: the first client lets
1397 * the server select the multicast address and the ports while the second client requests
1398 * the specific transport configuration.
1399 * CASE: media is shared */
1401 (test_client_multicast_two_clients_second_specific_transport_shared_media) {
1402 const gchar *transport_client_1 = "RTP/AVP;multicast;mode=\"PLAY\"";
1403 const gchar *expected_transport_1 =
1404 "RTP/AVP;multicast;destination=233.252.0.1;"
1405 "ttl=1;port=5000-5001;mode=\"PLAY\"";
1406 const gchar *addr_client_1 = "233.252.0.1:5000";
1408 const gchar *transport_client_2 = "RTP/AVP;multicast;destination=233.252.0.2;"
1409 "ttl=2;port=5004-5005;mode=\"PLAY\"";
1410 const gchar *expected_transport_2 = transport_client_2;
1411 const gchar *addr_client_2 = "233.252.0.2:5004";
1413 mcast_transport_two_clients (TRUE, transport_client_1,
1414 expected_transport_1, addr_client_1, transport_client_2,
1415 expected_transport_2, addr_client_2, FALSE);
1420 /* test if the maximum ttl multicast value is chosen by the server
1421 * CASE: the first client provides the highest ttl value */
1422 GST_START_TEST (test_client_multicast_max_ttl_first_client)
1424 const gchar *transport_client_1 = "RTP/AVP;multicast;destination=233.252.0.1;"
1425 "ttl=3;port=5000-5001;mode=\"PLAY\"";
1426 const gchar *expected_transport_1 = transport_client_1;
1427 const gchar *addr_client_1 = "233.252.0.1:5000";
1429 const gchar *transport_client_2 = "RTP/AVP;multicast;destination=233.252.0.2;"
1430 "ttl=1;port=5002-5003;mode=\"PLAY\"";
1431 const gchar *expected_transport_2 =
1432 "RTP/AVP;multicast;destination=233.252.0.2;"
1433 "ttl=3;port=5002-5003;mode=\"PLAY\"";
1434 const gchar *addr_client_2 = "233.252.0.2:5002";
1436 mcast_transport_two_clients (TRUE, transport_client_1,
1437 expected_transport_1, addr_client_1, transport_client_2,
1438 expected_transport_2, addr_client_2, FALSE);
1443 /* test if the maximum ttl multicast value is chosen by the server
1444 * CASE: the second client provides the highest ttl value */
1445 GST_START_TEST (test_client_multicast_max_ttl_second_client)
1447 const gchar *transport_client_1 = "RTP/AVP;multicast;destination=233.252.0.1;"
1448 "ttl=2;port=5000-5001;mode=\"PLAY\"";
1449 const gchar *expected_transport_1 = transport_client_1;
1450 const gchar *addr_client_1 = "233.252.0.1:5000";
1452 const gchar *transport_client_2 = "RTP/AVP;multicast;destination=233.252.0.2;"
1453 "ttl=4;port=5002-5003;mode=\"PLAY\"";
1454 const gchar *expected_transport_2 = transport_client_2;
1455 const gchar *addr_client_2 = "233.252.0.2:5002";
1457 mcast_transport_two_clients (TRUE, transport_client_1,
1458 expected_transport_1, addr_client_1, transport_client_2,
1459 expected_transport_2, addr_client_2, FALSE);
1463 GST_START_TEST (test_client_multicast_invalid_ttl)
1465 GstRTSPClient *client;
1466 GstRTSPMessage request = { 0, };
1468 GstRTSPSessionPool *session_pool;
1469 GstRTSPContext ctx = { NULL };
1471 client = setup_multicast_client (3);
1473 ctx.client = client;
1474 ctx.auth = gst_rtsp_auth_new ();
1476 gst_rtsp_token_new (GST_RTSP_TOKEN_TRANSPORT_CLIENT_SETTINGS,
1477 G_TYPE_BOOLEAN, TRUE, GST_RTSP_TOKEN_MEDIA_FACTORY_ROLE, G_TYPE_STRING,
1479 gst_rtsp_context_push_current (&ctx);
1481 /* simple SETUP with an invalid ttl=0 */
1482 fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
1483 "rtsp://localhost/test/stream=0") == GST_RTSP_OK);
1484 str = g_strdup_printf ("%d", cseq);
1485 gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
1486 gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
1487 "RTP/AVP;multicast;destination=233.252.0.1;ttl=0;port=5000-5001;");
1489 gst_rtsp_client_set_send_func (client, test_setup_response_461, NULL, NULL);
1490 fail_unless (gst_rtsp_client_handle_message (client,
1491 &request) == GST_RTSP_OK);
1492 gst_rtsp_message_unset (&request);
1494 session_pool = gst_rtsp_client_get_session_pool (client);
1495 fail_unless (session_pool != NULL);
1496 fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 0);
1497 g_object_unref (session_pool);
1499 teardown_client (client);
1500 g_object_unref (ctx.auth);
1501 gst_rtsp_token_unref (ctx.token);
1502 gst_rtsp_context_pop_current (&ctx);
1508 rtspclient_suite (void)
1510 Suite *s = suite_create ("rtspclient");
1511 TCase *tc = tcase_create ("general");
1513 suite_add_tcase (s, tc);
1514 tcase_set_timeout (tc, 20);
1515 tcase_add_test (tc, test_require);
1516 tcase_add_test (tc, test_request);
1517 tcase_add_test (tc, test_options);
1518 tcase_add_test (tc, test_describe);
1519 tcase_add_test (tc, test_setup_tcp);
1520 tcase_add_test (tc, test_setup_tcp_two_streams_same_channels);
1521 tcase_add_test (tc, test_client_multicast_transport_404);
1522 tcase_add_test (tc, test_client_multicast_transport);
1523 tcase_add_test (tc, test_client_multicast_ignore_transport_specific);
1524 tcase_add_test (tc, test_client_multicast_transport_specific);
1525 tcase_add_test (tc, test_client_sdp_with_max_bitrate_tag);
1526 tcase_add_test (tc, test_client_sdp_with_bitrate_tag);
1527 tcase_add_test (tc, test_client_sdp_with_max_bitrate_and_bitrate_tags);
1528 tcase_add_test (tc, test_client_sdp_with_no_bitrate_tags);
1530 test_client_multicast_transport_specific_two_clients_shared_media);
1531 tcase_add_test (tc, test_client_multicast_transport_specific_two_clients);
1534 test_client_multicast_transport_specific_two_clients_same_ports);
1536 /* skip the test on windows as the test restricts the multicast sockets to multicast traffic only,
1537 * by specifying the multicast IP as the bind address and this currently doesn't work on Windows */
1538 tcase_skip_broken_test (tc,
1539 test_client_multicast_transport_specific_two_clients_same_ports);
1542 test_client_multicast_transport_specific_two_clients_same_destination);
1544 test_client_multicast_transport_specific_two_clients_shared_media_same_transport);
1545 tcase_add_test (tc, test_client_multicast_two_clients_shared_media);
1547 test_client_multicast_two_clients_first_specific_transport_shared_media);
1549 test_client_multicast_two_clients_second_specific_transport_shared_media);
1551 test_client_multicast_transport_specific_no_address_in_pool);
1552 tcase_add_test (tc, test_client_multicast_max_ttl_first_client);
1553 tcase_add_test (tc, test_client_multicast_max_ttl_second_client);
1554 tcase_add_test (tc, test_client_multicast_invalid_ttl);
1559 GST_CHECK_MAIN (rtspclient);