3 * unit test for GstRTSPServer
5 * Copyright (C) 2012 Axis Communications <dev-gstreamer at axis dot com>
6 * @author David Svensson Fors <davidsf at axis dot com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
24 #include <gst/check/gstcheck.h>
25 #include <gst/sdp/gstsdpmessage.h>
26 #include <gst/rtp/gstrtpbuffer.h>
27 #include <gst/rtp/gstrtcpbuffer.h>
30 #include <netinet/in.h>
32 #include "rtsp-server.h"
34 #define VIDEO_PIPELINE "videotestsrc ! " \
35 "video/x-raw,width=352,height=288 ! " \
36 "rtpgstpay name=pay0 pt=96"
37 #define AUDIO_PIPELINE "audiotestsrc ! " \
38 "audio/x-raw,rate=8000 ! " \
39 "rtpgstpay name=pay1 pt=97"
41 #define TEST_MOUNT_POINT "/test"
42 #define TEST_PROTO "RTP/AVP"
43 #define TEST_ENCODING "X-GST"
44 #define TEST_CLOCK_RATE "90000"
46 /* tested rtsp server */
47 static GstRTSPServer *server = NULL;
49 /* tcp port that the test server listens for rtsp requests on */
50 static gint test_port = 0;
52 /* id of the server's source within the GMainContext */
53 static guint source_id;
55 /* iterate the default main loop until there are no events to dispatch */
59 while (g_main_context_iteration (NULL, FALSE)) {
60 GST_DEBUG ("iteration");
65 get_client_ports_full (GstRTSPRange * range, GSocket ** rtp_socket,
66 GSocket ** rtcp_socket)
72 GInetAddress *anyaddr = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4);
73 GSocketAddress *sockaddr;
80 rtp = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM,
81 G_SOCKET_PROTOCOL_UDP, NULL);
82 fail_unless (rtp != NULL);
84 sockaddr = g_inet_socket_address_new (anyaddr, rtp_port);
85 fail_unless (sockaddr != NULL);
86 bound = g_socket_bind (rtp, sockaddr, FALSE, NULL);
87 g_object_unref (sockaddr);
93 sockaddr = g_socket_get_local_address (rtp, NULL);
94 fail_unless (sockaddr != NULL && G_IS_INET_SOCKET_ADDRESS (sockaddr));
96 g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (sockaddr));
97 g_object_unref (sockaddr);
99 if (rtp_port % 2 != 0) {
101 g_object_unref (rtp);
105 rtcp_port = rtp_port + 1;
107 rtcp = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM,
108 G_SOCKET_PROTOCOL_UDP, NULL);
109 fail_unless (rtcp != NULL);
111 sockaddr = g_inet_socket_address_new (anyaddr, rtcp_port);
112 fail_unless (sockaddr != NULL);
113 bound = g_socket_bind (rtcp, sockaddr, FALSE, NULL);
114 g_object_unref (sockaddr);
116 g_object_unref (rtp);
117 g_object_unref (rtcp);
121 sockaddr = g_socket_get_local_address (rtcp, NULL);
122 fail_unless (sockaddr != NULL && G_IS_INET_SOCKET_ADDRESS (sockaddr));
123 fail_unless (rtcp_port ==
124 g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (sockaddr)));
125 g_object_unref (sockaddr);
130 range->min = rtp_port;
131 range->max = rtcp_port;
135 g_object_unref (rtp);
139 g_object_unref (rtcp);
140 GST_DEBUG ("client_port=%d-%d", range->min, range->max);
141 g_object_unref (anyaddr);
144 /* get a free rtp/rtcp client port pair */
146 get_client_ports (GstRTSPRange * range)
148 get_client_ports_full (range, NULL, NULL);
151 /* start the tested rtsp server */
155 GstRTSPMountPoints *mounts;
157 GstRTSPMediaFactory *factory;
159 mounts = gst_rtsp_server_get_mount_points (server);
161 factory = gst_rtsp_media_factory_new ();
163 gst_rtsp_media_factory_set_launch (factory,
164 "( " VIDEO_PIPELINE " " AUDIO_PIPELINE " )");
165 gst_rtsp_mount_points_add_factory (mounts, TEST_MOUNT_POINT, factory);
166 g_object_unref (mounts);
168 /* set port to any */
169 gst_rtsp_server_set_service (server, "0");
171 /* attach to default main context */
172 source_id = gst_rtsp_server_attach (server, NULL);
173 fail_if (source_id == 0);
176 service = gst_rtsp_server_get_service (server);
177 test_port = atoi (service);
178 fail_unless (test_port != 0);
181 GST_DEBUG ("rtsp server listening on port %d", test_port);
184 /* stop the tested rtsp server */
188 g_source_remove (source_id);
191 GST_DEBUG ("rtsp server stopped");
194 /* create an rtsp connection to the server on test_port */
195 static GstRTSPConnection *
196 connect_to_server (gint port, const gchar * mount_point)
198 GstRTSPConnection *conn = NULL;
201 GstRTSPUrl *url = NULL;
203 address = gst_rtsp_server_get_address (server);
204 uri_string = g_strdup_printf ("rtsp://%s:%d%s", address, port, mount_point);
206 fail_unless (gst_rtsp_url_parse (uri_string, &url) == GST_RTSP_OK);
209 fail_unless (gst_rtsp_connection_create (url, &conn) == GST_RTSP_OK);
210 gst_rtsp_url_free (url);
212 fail_unless (gst_rtsp_connection_connect (conn, NULL) == GST_RTSP_OK);
217 /* create an rtsp request */
218 static GstRTSPMessage *
219 create_request (GstRTSPConnection * conn, GstRTSPMethod method,
220 const gchar * control)
222 GstRTSPMessage *request = NULL;
226 base_uri = gst_rtsp_url_get_request_uri (gst_rtsp_connection_get_url (conn));
227 full_uri = g_strdup_printf ("%s/%s", base_uri, control ? control : "");
229 if (gst_rtsp_message_new_request (&request, method, full_uri) != GST_RTSP_OK) {
230 GST_DEBUG ("failed to create request object");
238 /* send an rtsp request */
240 send_request (GstRTSPConnection * conn, GstRTSPMessage * request)
242 if (gst_rtsp_connection_send (conn, request, NULL) != GST_RTSP_OK) {
243 GST_DEBUG ("failed to send request");
249 /* read rtsp response. response must be freed by the caller */
250 static GstRTSPMessage *
251 read_response (GstRTSPConnection * conn)
253 GstRTSPMessage *response = NULL;
255 if (gst_rtsp_message_new (&response) != GST_RTSP_OK) {
256 GST_DEBUG ("failed to create response object");
259 if (gst_rtsp_connection_receive (conn, response, NULL) != GST_RTSP_OK) {
260 GST_DEBUG ("failed to read response");
261 gst_rtsp_message_free (response);
264 fail_unless (gst_rtsp_message_get_type (response) ==
265 GST_RTSP_MESSAGE_RESPONSE);
269 /* send an rtsp request and receive response. gchar** parameters are out
270 * parameters that have to be freed by the caller */
271 static GstRTSPStatusCode
272 do_request_full (GstRTSPConnection * conn, GstRTSPMethod method,
273 const gchar * control, const gchar * session_in, const gchar * transport_in,
274 const gchar * range_in, const gchar * require_in,
275 gchar ** content_type, gchar ** content_base, gchar ** body,
276 gchar ** session_out, gchar ** transport_out, gchar ** range_out,
277 gchar ** unsupported_out)
279 GstRTSPMessage *request;
280 GstRTSPMessage *response;
281 GstRTSPStatusCode code;
285 request = create_request (conn, method, control);
289 gst_rtsp_message_add_header (request, GST_RTSP_HDR_SESSION, session_in);
292 gst_rtsp_message_add_header (request, GST_RTSP_HDR_TRANSPORT, transport_in);
295 gst_rtsp_message_add_header (request, GST_RTSP_HDR_RANGE, range_in);
298 gst_rtsp_message_add_header (request, GST_RTSP_HDR_REQUIRE, require_in);
302 fail_unless (send_request (conn, request));
303 gst_rtsp_message_free (request);
308 response = read_response (conn);
310 /* check status line */
311 gst_rtsp_message_parse_response (response, &code, NULL, NULL);
312 if (code != GST_RTSP_STS_OK) {
313 if (unsupported_out != NULL && code == GST_RTSP_STS_OPTION_NOT_SUPPORTED) {
314 gst_rtsp_message_get_header (response, GST_RTSP_HDR_UNSUPPORTED,
316 *unsupported_out = g_strdup (value);
318 gst_rtsp_message_free (response);
322 /* get information from response */
324 gst_rtsp_message_get_header (response, GST_RTSP_HDR_CONTENT_TYPE,
326 *content_type = g_strdup (value);
329 gst_rtsp_message_get_header (response, GST_RTSP_HDR_CONTENT_BASE,
331 *content_base = g_strdup (value);
334 *body = g_malloc (response->body_size + 1);
335 strncpy (*body, (gchar *) response->body, response->body_size);
338 gst_rtsp_message_get_header (response, GST_RTSP_HDR_SESSION, &value, 0);
340 value = g_strdup (value);
342 /* Remove the timeout */
344 char *pos = strchr (value, ';');
349 /* check that we got the same session back */
350 fail_unless (!g_strcmp0 (value, session_in));
352 *session_out = value;
355 gst_rtsp_message_get_header (response, GST_RTSP_HDR_TRANSPORT, &value, 0);
356 *transport_out = g_strdup (value);
359 gst_rtsp_message_get_header (response, GST_RTSP_HDR_RANGE, &value, 0);
360 *range_out = g_strdup (value);
363 gst_rtsp_message_free (response);
367 /* send an rtsp request and receive response. gchar** parameters are out
368 * parameters that have to be freed by the caller */
369 static GstRTSPStatusCode
370 do_request (GstRTSPConnection * conn, GstRTSPMethod method,
371 const gchar * control, const gchar * session_in,
372 const gchar * transport_in, const gchar * range_in,
373 gchar ** content_type, gchar ** content_base, gchar ** body,
374 gchar ** session_out, gchar ** transport_out, gchar ** range_out)
376 return do_request_full (conn, method, control, session_in, transport_in,
377 range_in, NULL, content_type, content_base, body, session_out,
378 transport_out, range_out, NULL);
381 /* send an rtsp request with a method and a session, and receive response */
382 static GstRTSPStatusCode
383 do_simple_request (GstRTSPConnection * conn, GstRTSPMethod method,
384 const gchar * session)
386 return do_request (conn, method, NULL, session, NULL, NULL, NULL,
387 NULL, NULL, NULL, NULL, NULL);
390 /* send a DESCRIBE request and receive response. returns a received
391 * GstSDPMessage that must be freed by the caller */
392 static GstSDPMessage *
393 do_describe (GstRTSPConnection * conn, const gchar * mount_point)
395 GstSDPMessage *sdp_message;
400 gchar *expected_content_base;
402 /* send DESCRIBE request */
403 fail_unless (do_request (conn, GST_RTSP_DESCRIBE, NULL, NULL, NULL, NULL,
404 &content_type, &content_base, &body, NULL, NULL, NULL) ==
407 /* check response values */
408 fail_unless (!g_strcmp0 (content_type, "application/sdp"));
409 address = gst_rtsp_server_get_address (server);
410 expected_content_base =
411 g_strdup_printf ("rtsp://%s:%d%s/", address, test_port, mount_point);
412 fail_unless (!g_strcmp0 (content_base, expected_content_base));
414 /* create sdp message */
415 fail_unless (gst_sdp_message_new (&sdp_message) == GST_SDP_OK);
416 fail_unless (gst_sdp_message_parse_buffer ((guint8 *) body,
417 strlen (body), sdp_message) == GST_SDP_OK);
420 g_free (content_type);
421 g_free (content_base);
424 g_free (expected_content_base);
429 /* send a SETUP request and receive response. if *session is not NULL,
430 * it is used in the request. otherwise, *session is set to a returned
431 * session string that must be freed by the caller. the returned
432 * transport must be freed by the caller. */
433 static GstRTSPStatusCode
434 do_setup_full (GstRTSPConnection * conn, const gchar * control,
435 const GstRTSPRange * client_ports, const gchar * require, gchar ** session,
436 GstRTSPTransport ** transport, gchar ** unsupported)
438 GstRTSPStatusCode code;
439 gchar *session_in = NULL;
440 gchar *transport_string_in = NULL;
441 gchar **session_out = NULL;
442 gchar *transport_string_out = NULL;
444 /* prepare and send SETUP request */
447 session_in = *session;
449 session_out = session;
452 transport_string_in =
453 g_strdup_printf (TEST_PROTO ";unicast;client_port=%d-%d",
454 client_ports->min, client_ports->max);
456 do_request_full (conn, GST_RTSP_SETUP, control, session_in,
457 transport_string_in, NULL, require, NULL, NULL, NULL, session_out,
458 &transport_string_out, NULL, unsupported);
459 g_free (transport_string_in);
461 if (transport_string_out) {
462 /* create transport */
463 fail_unless (gst_rtsp_transport_new (transport) == GST_RTSP_OK);
464 fail_unless (gst_rtsp_transport_parse (transport_string_out,
465 *transport) == GST_RTSP_OK);
466 g_free (transport_string_out);
468 GST_INFO ("code=%d", code);
472 /* send a SETUP request and receive response. if *session is not NULL,
473 * it is used in the request. otherwise, *session is set to a returned
474 * session string that must be freed by the caller. the returned
475 * transport must be freed by the caller. */
476 static GstRTSPStatusCode
477 do_setup (GstRTSPConnection * conn, const gchar * control,
478 const GstRTSPRange * client_ports, gchar ** session,
479 GstRTSPTransport ** transport)
481 return do_setup_full (conn, control, client_ports, NULL, session, transport,
485 /* fixture setup function */
489 server = gst_rtsp_server_new ();
492 /* fixture clean-up function */
497 g_object_unref (server);
503 GST_START_TEST (test_connect)
505 GstRTSPConnection *conn;
509 /* connect to server */
510 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
513 gst_rtsp_connection_free (conn);
516 /* iterate so the clean-up can finish */
522 GST_START_TEST (test_describe)
524 GstRTSPConnection *conn;
525 GstSDPMessage *sdp_message = NULL;
526 const GstSDPMedia *sdp_media;
528 gchar *expected_rtpmap;
530 const gchar *control_video;
531 const gchar *control_audio;
535 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
537 /* send DESCRIBE request */
538 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
540 fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
542 /* check video sdp */
543 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
544 fail_unless (!g_strcmp0 (gst_sdp_media_get_proto (sdp_media), TEST_PROTO));
545 fail_unless (gst_sdp_media_formats_len (sdp_media) == 1);
546 sscanf (gst_sdp_media_get_format (sdp_media, 0), "%" G_GINT32_FORMAT,
549 g_strdup_printf ("%d " TEST_ENCODING "/" TEST_CLOCK_RATE, format);
550 rtpmap = gst_sdp_media_get_attribute_val (sdp_media, "rtpmap");
551 fail_unless (!g_strcmp0 (rtpmap, expected_rtpmap));
552 g_free (expected_rtpmap);
553 control_video = gst_sdp_media_get_attribute_val (sdp_media, "control");
554 fail_unless (!g_strcmp0 (control_video, "stream=0"));
556 /* check audio sdp */
557 sdp_media = gst_sdp_message_get_media (sdp_message, 1);
558 fail_unless (!g_strcmp0 (gst_sdp_media_get_proto (sdp_media), TEST_PROTO));
559 fail_unless (gst_sdp_media_formats_len (sdp_media) == 1);
560 sscanf (gst_sdp_media_get_format (sdp_media, 0), "%" G_GINT32_FORMAT,
563 g_strdup_printf ("%d " TEST_ENCODING "/" TEST_CLOCK_RATE, format);
564 rtpmap = gst_sdp_media_get_attribute_val (sdp_media, "rtpmap");
565 fail_unless (!g_strcmp0 (rtpmap, expected_rtpmap));
566 g_free (expected_rtpmap);
567 control_audio = gst_sdp_media_get_attribute_val (sdp_media, "control");
568 fail_unless (!g_strcmp0 (control_audio, "stream=1"));
570 /* clean up and iterate so the clean-up can finish */
571 gst_sdp_message_free (sdp_message);
572 gst_rtsp_connection_free (conn);
579 GST_START_TEST (test_describe_non_existing_mount_point)
581 GstRTSPConnection *conn;
585 /* send DESCRIBE request for a non-existing mount point
586 * and check that we get a 404 Not Found */
587 conn = connect_to_server (test_port, "/non-existing");
588 fail_unless (do_simple_request (conn, GST_RTSP_DESCRIBE, NULL)
589 == GST_RTSP_STS_NOT_FOUND);
591 /* clean up and iterate so the clean-up can finish */
592 gst_rtsp_connection_free (conn);
599 GST_START_TEST (test_setup)
601 GstRTSPConnection *conn;
602 GstSDPMessage *sdp_message = NULL;
603 const GstSDPMedia *sdp_media;
604 const gchar *video_control;
605 const gchar *audio_control;
606 GstRTSPRange client_ports;
607 gchar *session = NULL;
608 GstRTSPTransport *video_transport = NULL;
609 GstRTSPTransport *audio_transport = NULL;
613 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
615 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
617 /* get control strings from DESCRIBE response */
618 fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
619 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
620 video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
621 sdp_media = gst_sdp_message_get_media (sdp_message, 1);
622 audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
624 get_client_ports (&client_ports);
626 /* send SETUP request for video */
627 fail_unless (do_setup (conn, video_control, &client_ports, &session,
628 &video_transport) == GST_RTSP_STS_OK);
629 GST_DEBUG ("set up video %s, got session '%s'", video_control, session);
631 /* check response from SETUP */
632 fail_unless (video_transport->trans == GST_RTSP_TRANS_RTP);
633 fail_unless (video_transport->profile == GST_RTSP_PROFILE_AVP);
634 fail_unless (video_transport->lower_transport == GST_RTSP_LOWER_TRANS_UDP);
635 fail_unless (video_transport->mode_play);
636 gst_rtsp_transport_free (video_transport);
638 /* send SETUP request for audio */
639 fail_unless (do_setup (conn, audio_control, &client_ports, &session,
640 &audio_transport) == GST_RTSP_STS_OK);
641 GST_DEBUG ("set up audio %s with session '%s'", audio_control, session);
643 /* check response from SETUP */
644 fail_unless (audio_transport->trans == GST_RTSP_TRANS_RTP);
645 fail_unless (audio_transport->profile == GST_RTSP_PROFILE_AVP);
646 fail_unless (audio_transport->lower_transport == GST_RTSP_LOWER_TRANS_UDP);
647 fail_unless (audio_transport->mode_play);
648 gst_rtsp_transport_free (audio_transport);
650 /* send TEARDOWN request and check that we get 200 OK */
651 fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
652 session) == GST_RTSP_STS_OK);
654 /* clean up and iterate so the clean-up can finish */
656 gst_sdp_message_free (sdp_message);
657 gst_rtsp_connection_free (conn);
664 GST_START_TEST (test_setup_with_require_header)
666 GstRTSPConnection *conn;
667 GstSDPMessage *sdp_message = NULL;
668 const GstSDPMedia *sdp_media;
669 const gchar *video_control;
670 GstRTSPRange client_ports;
671 gchar *session = NULL;
672 gchar *unsupported = NULL;
673 GstRTSPTransport *video_transport = NULL;
677 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
679 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
681 /* get control strings from DESCRIBE response */
682 fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
683 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
684 video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
686 get_client_ports (&client_ports);
688 /* send SETUP request for video, with single Require header */
689 fail_unless_equals_int (do_setup_full (conn, video_control, &client_ports,
690 "funky-feature", &session, &video_transport, &unsupported),
691 GST_RTSP_STS_OPTION_NOT_SUPPORTED);
692 fail_unless_equals_string (unsupported, "funky-feature");
693 g_free (unsupported);
696 /* send SETUP request for video, with multiple Require headers */
697 fail_unless_equals_int (do_setup_full (conn, video_control, &client_ports,
698 "funky-feature, foo-bar, superburst", &session, &video_transport,
699 &unsupported), GST_RTSP_STS_OPTION_NOT_SUPPORTED);
700 fail_unless_equals_string (unsupported, "funky-feature, foo-bar, superburst");
701 g_free (unsupported);
704 /* ok, just do a normal setup then (make sure that still works) */
705 fail_unless_equals_int (do_setup (conn, video_control, &client_ports,
706 &session, &video_transport), GST_RTSP_STS_OK);
708 GST_DEBUG ("set up video %s, got session '%s'", video_control, session);
710 /* check response from SETUP */
711 fail_unless (video_transport->trans == GST_RTSP_TRANS_RTP);
712 fail_unless (video_transport->profile == GST_RTSP_PROFILE_AVP);
713 fail_unless (video_transport->lower_transport == GST_RTSP_LOWER_TRANS_UDP);
714 fail_unless (video_transport->mode_play);
715 gst_rtsp_transport_free (video_transport);
717 /* send TEARDOWN request and check that we get 200 OK */
718 fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
719 session) == GST_RTSP_STS_OK);
721 /* clean up and iterate so the clean-up can finish */
723 gst_sdp_message_free (sdp_message);
724 gst_rtsp_connection_free (conn);
731 GST_START_TEST (test_setup_non_existing_stream)
733 GstRTSPConnection *conn;
734 GstRTSPRange client_ports;
738 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
740 get_client_ports (&client_ports);
742 /* send SETUP request with a non-existing stream and check that we get a
744 fail_unless (do_setup (conn, "stream=7", &client_ports, NULL,
745 NULL) == GST_RTSP_STS_NOT_FOUND);
747 /* clean up and iterate so the clean-up can finish */
748 gst_rtsp_connection_free (conn);
756 receive_rtp (GSocket * socket, GSocketAddress ** addr)
758 GstBuffer *buffer = gst_buffer_new_allocate (NULL, 65536, NULL);
762 GstMapInfo map = GST_MAP_INFO_INIT;
763 GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;
765 gst_buffer_map (buffer, &map, GST_MAP_WRITE);
766 bytes = g_socket_receive_from (socket, addr, (gchar *) map.data,
767 map.maxsize, NULL, NULL);
768 fail_unless (bytes > 0);
769 gst_buffer_unmap (buffer, &map);
770 gst_buffer_set_size (buffer, bytes);
772 if (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtpbuffer)) {
773 gst_rtp_buffer_unmap (&rtpbuffer);
778 g_clear_object (addr);
781 gst_buffer_unref (buffer);
785 receive_rtcp (GSocket * socket, GSocketAddress ** addr, GstRTCPType type)
787 GstBuffer *buffer = gst_buffer_new_allocate (NULL, 65536, NULL);
791 GstMapInfo map = GST_MAP_INFO_INIT;
793 gst_buffer_map (buffer, &map, GST_MAP_WRITE);
794 bytes = g_socket_receive_from (socket, addr, (gchar *) map.data,
795 map.maxsize, NULL, NULL);
796 fail_unless (bytes > 0);
797 gst_buffer_unmap (buffer, &map);
798 gst_buffer_set_size (buffer, bytes);
800 if (gst_rtcp_buffer_validate (buffer)) {
801 GstRTCPBuffer rtcpbuffer = GST_RTCP_BUFFER_INIT;
802 GstRTCPPacket packet;
805 fail_unless (gst_rtcp_buffer_map (buffer, GST_MAP_READ, &rtcpbuffer));
806 fail_unless (gst_rtcp_buffer_get_first_packet (&rtcpbuffer, &packet));
808 if (gst_rtcp_packet_get_type (&packet) == type) {
809 gst_rtcp_buffer_unmap (&rtcpbuffer);
812 } while (gst_rtcp_packet_move_to_next (&packet));
813 gst_rtcp_buffer_unmap (&rtcpbuffer);
820 g_clear_object (addr);
825 gst_buffer_unref (buffer);
829 do_test_play (const gchar * range)
831 GstRTSPConnection *conn;
832 GstSDPMessage *sdp_message = NULL;
833 const GstSDPMedia *sdp_media;
834 const gchar *video_control;
835 const gchar *audio_control;
836 GstRTSPRange client_port;
837 gchar *session = NULL;
838 GstRTSPTransport *video_transport = NULL;
839 GstRTSPTransport *audio_transport = NULL;
840 GSocket *rtp_socket, *rtcp_socket;
841 gchar *range_out = NULL;
843 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
845 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
847 /* get control strings from DESCRIBE response */
848 fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
849 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
850 video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
851 sdp_media = gst_sdp_message_get_media (sdp_message, 1);
852 audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
854 get_client_ports_full (&client_port, &rtp_socket, &rtcp_socket);
856 /* do SETUP for video and audio */
857 fail_unless (do_setup (conn, video_control, &client_port, &session,
858 &video_transport) == GST_RTSP_STS_OK);
859 fail_unless (do_setup (conn, audio_control, &client_port, &session,
860 &audio_transport) == GST_RTSP_STS_OK);
862 /* send PLAY request and check that we get 200 OK */
863 fail_unless (do_request (conn, GST_RTSP_PLAY, NULL, session, NULL, range,
864 NULL, NULL, NULL, NULL, NULL, &range_out) == GST_RTSP_STS_OK);
866 fail_unless_equals_string (range, range_out);
869 receive_rtp (rtp_socket, NULL);
870 receive_rtcp (rtcp_socket, NULL, 0);
872 /* send TEARDOWN request and check that we get 200 OK */
873 fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
874 session) == GST_RTSP_STS_OK);
876 /* FIXME: The rtsp-server always disconnects the transport before
877 * sending the RTCP BYE
878 * receive_rtcp (rtcp_socket, NULL, GST_RTCP_TYPE_BYE);
881 /* clean up and iterate so the clean-up can finish */
882 g_object_unref (rtp_socket);
883 g_object_unref (rtcp_socket);
885 gst_rtsp_transport_free (video_transport);
886 gst_rtsp_transport_free (audio_transport);
887 gst_sdp_message_free (sdp_message);
888 gst_rtsp_connection_free (conn);
892 GST_START_TEST (test_play)
904 GST_START_TEST (test_play_without_session)
906 GstRTSPConnection *conn;
910 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
912 /* send PLAY request without a session and check that we get a
913 * 454 Session Not Found */
914 fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
915 NULL) == GST_RTSP_STS_SESSION_NOT_FOUND);
917 /* clean up and iterate so the clean-up can finish */
918 gst_rtsp_connection_free (conn);
925 GST_START_TEST (test_bind_already_in_use)
928 GSocketService *service;
929 GError *error = NULL;
933 serv = gst_rtsp_server_new ();
934 service = g_socket_service_new ();
936 /* bind service to port */
938 g_socket_listener_add_any_inet_port (G_SOCKET_LISTENER (service), NULL,
940 g_assert_no_error (error);
942 port_str = g_strdup_printf ("%d\n", port);
944 /* try to bind server to the same port */
945 g_object_set (serv, "service", port_str, NULL);
948 /* attach to default main context */
949 fail_unless (gst_rtsp_server_attach (serv, NULL) == 0);
952 g_object_unref (serv);
953 g_socket_service_stop (service);
954 g_object_unref (service);
960 GST_START_TEST (test_play_multithreaded)
962 GstRTSPThreadPool *pool;
964 pool = gst_rtsp_server_get_thread_pool (server);
965 gst_rtsp_thread_pool_set_max_threads (pool, 2);
966 g_object_unref (pool);
987 media_constructed_block (GstRTSPMediaFactory * factory,
988 GstRTSPMedia * media, gpointer user_data)
990 gint *block_state = user_data;
992 g_mutex_lock (&check_mutex);
994 *block_state = BLOCKED;
995 g_cond_broadcast (&check_cond);
997 while (*block_state != UNBLOCK)
998 g_cond_wait (&check_cond, &check_mutex);
999 g_mutex_unlock (&check_mutex);
1003 GST_START_TEST (test_play_multithreaded_block_in_describe)
1005 GstRTSPConnection *conn;
1006 GstRTSPMountPoints *mounts;
1007 GstRTSPMediaFactory *factory;
1008 gint block_state = BLOCK_ME;
1009 GstRTSPMessage *request;
1010 GstRTSPMessage *response;
1011 GstRTSPStatusCode code;
1012 GstRTSPThreadPool *pool;
1014 pool = gst_rtsp_server_get_thread_pool (server);
1015 gst_rtsp_thread_pool_set_max_threads (pool, 2);
1016 g_object_unref (pool);
1018 mounts = gst_rtsp_server_get_mount_points (server);
1019 fail_unless (mounts != NULL);
1020 factory = gst_rtsp_media_factory_new ();
1021 gst_rtsp_media_factory_set_launch (factory,
1022 "( " VIDEO_PIPELINE " " AUDIO_PIPELINE " )");
1023 g_signal_connect (factory, "media-constructed",
1024 G_CALLBACK (media_constructed_block), &block_state);
1025 gst_rtsp_mount_points_add_factory (mounts, TEST_MOUNT_POINT "2", factory);
1026 g_object_unref (mounts);
1030 conn = connect_to_server (test_port, TEST_MOUNT_POINT "2");
1033 /* do describe, it will not return now as we've blocked it */
1034 request = create_request (conn, GST_RTSP_DESCRIBE, NULL);
1035 fail_unless (send_request (conn, request));
1036 gst_rtsp_message_free (request);
1038 g_mutex_lock (&check_mutex);
1039 while (block_state != BLOCKED)
1040 g_cond_wait (&check_cond, &check_mutex);
1041 g_mutex_unlock (&check_mutex);
1043 /* Do a second connection while the first one is blocked */
1044 do_test_play (NULL);
1046 /* Now unblock the describe */
1047 g_mutex_lock (&check_mutex);
1048 block_state = UNBLOCK;
1049 g_cond_broadcast (&check_cond);
1050 g_mutex_unlock (&check_mutex);
1052 response = read_response (conn);
1053 gst_rtsp_message_parse_response (response, &code, NULL, NULL);
1054 fail_unless (code == GST_RTSP_STS_OK);
1055 gst_rtsp_message_free (response);
1058 gst_rtsp_connection_free (conn);
1068 new_session_timeout_one (GstRTSPClient * client,
1069 GstRTSPSession * session, gpointer user_data)
1071 gst_rtsp_session_set_timeout (session, 1);
1073 g_signal_handlers_disconnect_by_func (client, new_session_timeout_one,
1078 session_connected_new_session_cb (GstRTSPServer * server,
1079 GstRTSPClient * client, gpointer user_data)
1082 g_signal_connect (client, "new-session", user_data, NULL);
1085 GST_START_TEST (test_play_multithreaded_timeout_client)
1087 GstRTSPConnection *conn;
1088 GstSDPMessage *sdp_message = NULL;
1089 const GstSDPMedia *sdp_media;
1090 const gchar *video_control;
1091 const gchar *audio_control;
1092 GstRTSPRange client_port;
1093 gchar *session = NULL;
1094 GstRTSPTransport *video_transport = NULL;
1095 GstRTSPTransport *audio_transport = NULL;
1096 GstRTSPSessionPool *pool;
1097 GstRTSPThreadPool *thread_pool;
1099 thread_pool = gst_rtsp_server_get_thread_pool (server);
1100 gst_rtsp_thread_pool_set_max_threads (thread_pool, 2);
1101 g_object_unref (thread_pool);
1103 pool = gst_rtsp_server_get_session_pool (server);
1104 g_signal_connect (server, "client-connected",
1105 G_CALLBACK (session_connected_new_session_cb), new_session_timeout_one);
1110 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
1112 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
1114 /* get control strings from DESCRIBE response */
1115 fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
1116 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
1117 video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1118 sdp_media = gst_sdp_message_get_media (sdp_message, 1);
1119 audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1121 get_client_ports (&client_port);
1123 /* do SETUP for video and audio */
1124 fail_unless (do_setup (conn, video_control, &client_port, &session,
1125 &video_transport) == GST_RTSP_STS_OK);
1126 fail_unless (do_setup (conn, audio_control, &client_port, &session,
1127 &audio_transport) == GST_RTSP_STS_OK);
1129 fail_unless (gst_rtsp_session_pool_get_n_sessions (pool) == 1);
1131 /* send PLAY request and check that we get 200 OK */
1132 fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
1133 session) == GST_RTSP_STS_OK);
1137 fail_unless (gst_rtsp_session_pool_cleanup (pool) == 1);
1138 fail_unless (gst_rtsp_session_pool_get_n_sessions (pool) == 0);
1140 /* clean up and iterate so the clean-up can finish */
1141 g_object_unref (pool);
1143 gst_rtsp_transport_free (video_transport);
1144 gst_rtsp_transport_free (audio_transport);
1145 gst_sdp_message_free (sdp_message);
1146 gst_rtsp_connection_free (conn);
1155 GST_START_TEST (test_play_multithreaded_timeout_session)
1157 GstRTSPConnection *conn;
1158 GstSDPMessage *sdp_message = NULL;
1159 const GstSDPMedia *sdp_media;
1160 const gchar *video_control;
1161 const gchar *audio_control;
1162 GstRTSPRange client_port;
1163 gchar *session1 = NULL;
1164 gchar *session2 = NULL;
1165 GstRTSPTransport *video_transport = NULL;
1166 GstRTSPTransport *audio_transport = NULL;
1167 GstRTSPSessionPool *pool;
1168 GstRTSPThreadPool *thread_pool;
1170 thread_pool = gst_rtsp_server_get_thread_pool (server);
1171 gst_rtsp_thread_pool_set_max_threads (thread_pool, 2);
1172 g_object_unref (thread_pool);
1174 pool = gst_rtsp_server_get_session_pool (server);
1175 g_signal_connect (server, "client-connected",
1176 G_CALLBACK (session_connected_new_session_cb), new_session_timeout_one);
1181 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
1183 gst_rtsp_connection_set_remember_session_id (conn, FALSE);
1185 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
1187 /* get control strings from DESCRIBE response */
1188 fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
1189 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
1190 video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1191 sdp_media = gst_sdp_message_get_media (sdp_message, 1);
1192 audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1194 get_client_ports (&client_port);
1196 /* do SETUP for video and audio */
1197 fail_unless (do_setup (conn, video_control, &client_port, &session1,
1198 &video_transport) == GST_RTSP_STS_OK);
1199 fail_unless (do_setup (conn, audio_control, &client_port, &session2,
1200 &audio_transport) == GST_RTSP_STS_OK);
1202 fail_unless (gst_rtsp_session_pool_get_n_sessions (pool) == 2);
1204 /* send PLAY request and check that we get 200 OK */
1205 fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
1206 session1) == GST_RTSP_STS_OK);
1207 fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
1208 session2) == GST_RTSP_STS_OK);
1212 fail_unless (gst_rtsp_session_pool_cleanup (pool) == 1);
1214 /* send TEARDOWN request and check that we get 454 Session Not found */
1215 fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
1216 session1) == GST_RTSP_STS_SESSION_NOT_FOUND);
1218 fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
1219 session2) == GST_RTSP_STS_OK);
1221 /* clean up and iterate so the clean-up can finish */
1222 g_object_unref (pool);
1225 gst_rtsp_transport_free (video_transport);
1226 gst_rtsp_transport_free (audio_transport);
1227 gst_sdp_message_free (sdp_message);
1228 gst_rtsp_connection_free (conn);
1237 GST_START_TEST (test_play_disconnect)
1239 GstRTSPConnection *conn;
1240 GstSDPMessage *sdp_message = NULL;
1241 const GstSDPMedia *sdp_media;
1242 const gchar *video_control;
1243 const gchar *audio_control;
1244 GstRTSPRange client_port;
1245 gchar *session = NULL;
1246 GstRTSPTransport *video_transport = NULL;
1247 GstRTSPTransport *audio_transport = NULL;
1248 GstRTSPSessionPool *pool;
1250 pool = gst_rtsp_server_get_session_pool (server);
1251 g_signal_connect (server, "client-connected",
1252 G_CALLBACK (session_connected_new_session_cb), new_session_timeout_one);
1256 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
1258 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
1260 /* get control strings from DESCRIBE response */
1261 fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
1262 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
1263 video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1264 sdp_media = gst_sdp_message_get_media (sdp_message, 1);
1265 audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1267 get_client_ports (&client_port);
1269 /* do SETUP for video and audio */
1270 fail_unless (do_setup (conn, video_control, &client_port, &session,
1271 &video_transport) == GST_RTSP_STS_OK);
1272 fail_unless (do_setup (conn, audio_control, &client_port, &session,
1273 &audio_transport) == GST_RTSP_STS_OK);
1275 fail_unless (gst_rtsp_session_pool_get_n_sessions (pool) == 1);
1277 /* send PLAY request and check that we get 200 OK */
1278 fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
1279 session) == GST_RTSP_STS_OK);
1281 gst_rtsp_connection_free (conn);
1285 fail_unless (gst_rtsp_session_pool_get_n_sessions (pool) == 1);
1286 fail_unless (gst_rtsp_session_pool_cleanup (pool) == 1);
1289 /* clean up and iterate so the clean-up can finish */
1290 g_object_unref (pool);
1292 gst_rtsp_transport_free (video_transport);
1293 gst_rtsp_transport_free (audio_transport);
1294 gst_sdp_message_free (sdp_message);
1302 /* Only different with test_play is the specific ports selected */
1304 GST_START_TEST (test_play_specific_server_port)
1306 GstRTSPMountPoints *mounts;
1308 GstRTSPMediaFactory *factory;
1309 GstRTSPAddressPool *pool;
1310 GstRTSPConnection *conn;
1311 GstSDPMessage *sdp_message = NULL;
1312 const GstSDPMedia *sdp_media;
1313 const gchar *video_control;
1314 GstRTSPRange client_port;
1315 gchar *session = NULL;
1316 GstRTSPTransport *video_transport = NULL;
1317 GSocket *rtp_socket, *rtcp_socket;
1318 GSocketAddress *rtp_address, *rtcp_address;
1319 guint16 rtp_port, rtcp_port;
1321 mounts = gst_rtsp_server_get_mount_points (server);
1323 factory = gst_rtsp_media_factory_new ();
1324 pool = gst_rtsp_address_pool_new ();
1325 gst_rtsp_address_pool_add_range (pool, GST_RTSP_ADDRESS_POOL_ANY_IPV4,
1326 GST_RTSP_ADDRESS_POOL_ANY_IPV4, 7770, 7780, 0);
1327 gst_rtsp_media_factory_set_address_pool (factory, pool);
1328 g_object_unref (pool);
1329 gst_rtsp_media_factory_set_launch (factory, "( " VIDEO_PIPELINE " )");
1330 gst_rtsp_mount_points_add_factory (mounts, TEST_MOUNT_POINT, factory);
1331 g_object_unref (mounts);
1333 /* set port to any */
1334 gst_rtsp_server_set_service (server, "0");
1336 /* attach to default main context */
1337 source_id = gst_rtsp_server_attach (server, NULL);
1338 fail_if (source_id == 0);
1341 service = gst_rtsp_server_get_service (server);
1342 test_port = atoi (service);
1343 fail_unless (test_port != 0);
1346 GST_DEBUG ("rtsp server listening on port %d", test_port);
1349 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
1351 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
1353 /* get control strings from DESCRIBE response */
1354 fail_unless (gst_sdp_message_medias_len (sdp_message) == 1);
1355 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
1356 video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1358 get_client_ports_full (&client_port, &rtp_socket, &rtcp_socket);
1360 /* do SETUP for video */
1361 fail_unless (do_setup (conn, video_control, &client_port, &session,
1362 &video_transport) == GST_RTSP_STS_OK);
1364 /* send PLAY request and check that we get 200 OK */
1365 fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
1366 session) == GST_RTSP_STS_OK);
1368 receive_rtp (rtp_socket, &rtp_address);
1369 receive_rtcp (rtcp_socket, &rtcp_address, 0);
1371 fail_unless (G_IS_INET_SOCKET_ADDRESS (rtp_address));
1372 fail_unless (G_IS_INET_SOCKET_ADDRESS (rtcp_address));
1374 g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (rtp_address));
1376 g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (rtcp_address));
1377 fail_unless (rtp_port >= 7770 && rtp_port <= 7780 && rtp_port % 2 == 0);
1378 fail_unless (rtcp_port >= 7770 && rtcp_port <= 7780 && rtcp_port % 2 == 1);
1379 fail_unless (rtp_port + 1 == rtcp_port);
1381 g_object_unref (rtp_address);
1382 g_object_unref (rtcp_address);
1384 /* send TEARDOWN request and check that we get 200 OK */
1385 fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
1386 session) == GST_RTSP_STS_OK);
1388 /* FIXME: The rtsp-server always disconnects the transport before
1389 * sending the RTCP BYE
1390 * receive_rtcp (rtcp_socket, NULL, GST_RTCP_TYPE_BYE);
1393 /* clean up and iterate so the clean-up can finish */
1394 g_object_unref (rtp_socket);
1395 g_object_unref (rtcp_socket);
1397 gst_rtsp_transport_free (video_transport);
1398 gst_sdp_message_free (sdp_message);
1399 gst_rtsp_connection_free (conn);
1409 GST_START_TEST (test_play_smpte_range)
1413 do_test_play ("npt=5-");
1414 do_test_play ("smpte=0:00:00-");
1415 do_test_play ("smpte=1:00:00-");
1416 do_test_play ("smpte=1:00:03-");
1417 do_test_play ("clock=20120321T152256Z-");
1427 rtspserver_suite (void)
1429 Suite *s = suite_create ("rtspserver");
1430 TCase *tc = tcase_create ("general");
1432 suite_add_tcase (s, tc);
1433 tcase_add_checked_fixture (tc, setup, teardown);
1434 tcase_set_timeout (tc, 20);
1435 tcase_add_test (tc, test_connect);
1436 tcase_add_test (tc, test_describe);
1437 tcase_add_test (tc, test_describe_non_existing_mount_point);
1438 tcase_add_test (tc, test_setup);
1439 tcase_add_test (tc, test_setup_with_require_header);
1440 tcase_add_test (tc, test_setup_non_existing_stream);
1441 tcase_add_test (tc, test_play);
1442 tcase_add_test (tc, test_play_without_session);
1443 tcase_add_test (tc, test_bind_already_in_use);
1444 tcase_add_test (tc, test_play_multithreaded);
1445 tcase_add_test (tc, test_play_multithreaded_block_in_describe);
1446 tcase_add_test (tc, test_play_multithreaded_timeout_client);
1447 tcase_add_test (tc, test_play_multithreaded_timeout_session);
1448 tcase_add_test (tc, test_play_disconnect);
1449 tcase_add_test (tc, test_play_specific_server_port);
1450 tcase_add_test (tc, test_play_smpte_range);
1454 GST_CHECK_MAIN (rtspserver);