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 gst_rtsp_url_parse (uri_string, &url);
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 (GstRTSPConnection * conn, GstRTSPMethod method,
273 const gchar * control, const gchar * session_in, const gchar * transport_in,
274 const gchar * range_in,
275 gchar ** content_type, gchar ** content_base, gchar ** body,
276 gchar ** session_out, gchar ** transport_out, gchar ** range_out)
278 GstRTSPMessage *request;
279 GstRTSPMessage *response;
280 GstRTSPStatusCode code;
284 request = create_request (conn, method, control);
288 gst_rtsp_message_add_header (request, GST_RTSP_HDR_SESSION, session_in);
291 gst_rtsp_message_add_header (request, GST_RTSP_HDR_TRANSPORT, transport_in);
294 gst_rtsp_message_add_header (request, GST_RTSP_HDR_RANGE, range_in);
298 fail_unless (send_request (conn, request));
299 gst_rtsp_message_free (request);
304 response = read_response (conn);
306 /* check status line */
307 gst_rtsp_message_parse_response (response, &code, NULL, NULL);
308 if (code != GST_RTSP_STS_OK) {
309 gst_rtsp_message_free (response);
313 /* get information from response */
315 gst_rtsp_message_get_header (response, GST_RTSP_HDR_CONTENT_TYPE,
317 *content_type = g_strdup (value);
320 gst_rtsp_message_get_header (response, GST_RTSP_HDR_CONTENT_BASE,
322 *content_base = g_strdup (value);
325 *body = g_malloc (response->body_size + 1);
326 strncpy (*body, (gchar *) response->body, response->body_size);
329 gst_rtsp_message_get_header (response, GST_RTSP_HDR_SESSION, &value, 0);
331 value = g_strdup (value);
333 /* Remove the timeout */
335 char *pos = strchr (value, ';');
340 /* check that we got the same session back */
341 fail_unless (!g_strcmp0 (value, session_in));
343 *session_out = value;
346 gst_rtsp_message_get_header (response, GST_RTSP_HDR_TRANSPORT, &value, 0);
347 *transport_out = g_strdup (value);
350 gst_rtsp_message_get_header (response, GST_RTSP_HDR_RANGE, &value, 0);
351 *range_out = g_strdup (value);
354 gst_rtsp_message_free (response);
358 /* send an rtsp request with a method and a session, and receive response */
359 static GstRTSPStatusCode
360 do_simple_request (GstRTSPConnection * conn, GstRTSPMethod method,
361 const gchar * session)
363 return do_request (conn, method, NULL, session, NULL, NULL, NULL,
364 NULL, NULL, NULL, NULL, NULL);
367 /* send a DESCRIBE request and receive response. returns a received
368 * GstSDPMessage that must be freed by the caller */
369 static GstSDPMessage *
370 do_describe (GstRTSPConnection * conn, const gchar * mount_point)
372 GstSDPMessage *sdp_message;
377 gchar *expected_content_base;
379 /* send DESCRIBE request */
380 fail_unless (do_request (conn, GST_RTSP_DESCRIBE, NULL, NULL, NULL, NULL,
381 &content_type, &content_base, &body, NULL, NULL, NULL) ==
384 /* check response values */
385 fail_unless (!g_strcmp0 (content_type, "application/sdp"));
386 address = gst_rtsp_server_get_address (server);
387 expected_content_base =
388 g_strdup_printf ("rtsp://%s:%d%s/", address, test_port, mount_point);
389 fail_unless (!g_strcmp0 (content_base, expected_content_base));
391 /* create sdp message */
392 fail_unless (gst_sdp_message_new (&sdp_message) == GST_SDP_OK);
393 fail_unless (gst_sdp_message_parse_buffer ((guint8 *) body,
394 strlen (body), sdp_message) == GST_SDP_OK);
397 g_free (content_type);
398 g_free (content_base);
401 g_free (expected_content_base);
406 /* send a SETUP request and receive response. if *session is not NULL,
407 * it is used in the request. otherwise, *session is set to a returned
408 * session string that must be freed by the caller. the returned
409 * transport must be freed by the caller. */
410 static GstRTSPStatusCode
411 do_setup (GstRTSPConnection * conn, const gchar * control,
412 const GstRTSPRange * client_ports, gchar ** session,
413 GstRTSPTransport ** transport)
415 GstRTSPStatusCode code;
416 gchar *session_in = NULL;
417 gchar *transport_string_in = NULL;
418 gchar **session_out = NULL;
419 gchar *transport_string_out = NULL;
421 /* prepare and send SETUP request */
424 session_in = *session;
426 session_out = session;
429 transport_string_in =
430 g_strdup_printf (TEST_PROTO ";unicast;client_port=%d-%d",
431 client_ports->min, client_ports->max);
433 do_request (conn, GST_RTSP_SETUP, control, session_in,
434 transport_string_in, NULL, NULL, NULL, NULL, session_out,
435 &transport_string_out, NULL);
436 g_free (transport_string_in);
438 if (transport_string_out) {
439 /* create transport */
440 fail_unless (gst_rtsp_transport_new (transport) == GST_RTSP_OK);
441 fail_unless (gst_rtsp_transport_parse (transport_string_out,
442 *transport) == GST_RTSP_OK);
443 g_free (transport_string_out);
449 /* fixture setup function */
453 server = gst_rtsp_server_new ();
456 /* fixture clean-up function */
461 g_object_unref (server);
467 GST_START_TEST (test_connect)
469 GstRTSPConnection *conn;
473 /* connect to server */
474 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
477 gst_rtsp_connection_free (conn);
480 /* iterate so the clean-up can finish */
486 GST_START_TEST (test_describe)
488 GstRTSPConnection *conn;
489 GstSDPMessage *sdp_message = NULL;
490 const GstSDPMedia *sdp_media;
492 gchar *expected_rtpmap;
494 const gchar *control_video;
495 const gchar *control_audio;
499 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
501 /* send DESCRIBE request */
502 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
504 fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
506 /* check video sdp */
507 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
508 fail_unless (!g_strcmp0 (gst_sdp_media_get_proto (sdp_media), TEST_PROTO));
509 fail_unless (gst_sdp_media_formats_len (sdp_media) == 1);
510 sscanf (gst_sdp_media_get_format (sdp_media, 0), "%" G_GINT32_FORMAT,
513 g_strdup_printf ("%d " TEST_ENCODING "/" TEST_CLOCK_RATE, format);
514 rtpmap = gst_sdp_media_get_attribute_val (sdp_media, "rtpmap");
515 fail_unless (!g_strcmp0 (rtpmap, expected_rtpmap));
516 g_free (expected_rtpmap);
517 control_video = gst_sdp_media_get_attribute_val (sdp_media, "control");
518 fail_unless (!g_strcmp0 (control_video, "stream=0"));
520 /* check audio sdp */
521 sdp_media = gst_sdp_message_get_media (sdp_message, 1);
522 fail_unless (!g_strcmp0 (gst_sdp_media_get_proto (sdp_media), TEST_PROTO));
523 fail_unless (gst_sdp_media_formats_len (sdp_media) == 1);
524 sscanf (gst_sdp_media_get_format (sdp_media, 0), "%" G_GINT32_FORMAT,
527 g_strdup_printf ("%d " TEST_ENCODING "/" TEST_CLOCK_RATE, format);
528 rtpmap = gst_sdp_media_get_attribute_val (sdp_media, "rtpmap");
529 fail_unless (!g_strcmp0 (rtpmap, expected_rtpmap));
530 g_free (expected_rtpmap);
531 control_audio = gst_sdp_media_get_attribute_val (sdp_media, "control");
532 fail_unless (!g_strcmp0 (control_audio, "stream=1"));
534 /* clean up and iterate so the clean-up can finish */
535 gst_sdp_message_free (sdp_message);
536 gst_rtsp_connection_free (conn);
543 GST_START_TEST (test_describe_non_existing_mount_point)
545 GstRTSPConnection *conn;
549 /* send DESCRIBE request for a non-existing mount point
550 * and check that we get a 404 Not Found */
551 conn = connect_to_server (test_port, "/non-existing");
552 fail_unless (do_simple_request (conn, GST_RTSP_DESCRIBE, NULL)
553 == GST_RTSP_STS_NOT_FOUND);
555 /* clean up and iterate so the clean-up can finish */
556 gst_rtsp_connection_free (conn);
563 GST_START_TEST (test_setup)
565 GstRTSPConnection *conn;
566 GstSDPMessage *sdp_message = NULL;
567 const GstSDPMedia *sdp_media;
568 const gchar *video_control;
569 const gchar *audio_control;
570 GstRTSPRange client_ports;
571 gchar *session = NULL;
572 GstRTSPTransport *video_transport = NULL;
573 GstRTSPTransport *audio_transport = NULL;
577 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
579 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
581 /* get control strings from DESCRIBE response */
582 fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
583 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
584 video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
585 sdp_media = gst_sdp_message_get_media (sdp_message, 1);
586 audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
588 get_client_ports (&client_ports);
590 /* send SETUP request for video */
591 fail_unless (do_setup (conn, video_control, &client_ports, &session,
592 &video_transport) == GST_RTSP_STS_OK);
593 GST_DEBUG ("set up video %s, got session '%s'", video_control, session);
595 /* check response from SETUP */
596 fail_unless (video_transport->trans == GST_RTSP_TRANS_RTP);
597 fail_unless (video_transport->profile == GST_RTSP_PROFILE_AVP);
598 fail_unless (video_transport->lower_transport == GST_RTSP_LOWER_TRANS_UDP);
599 fail_unless (video_transport->mode_play);
600 gst_rtsp_transport_free (video_transport);
602 /* send SETUP request for audio */
603 fail_unless (do_setup (conn, audio_control, &client_ports, &session,
604 &audio_transport) == GST_RTSP_STS_OK);
605 GST_DEBUG ("set up audio %s with session '%s'", audio_control, session);
607 /* check response from SETUP */
608 fail_unless (audio_transport->trans == GST_RTSP_TRANS_RTP);
609 fail_unless (audio_transport->profile == GST_RTSP_PROFILE_AVP);
610 fail_unless (audio_transport->lower_transport == GST_RTSP_LOWER_TRANS_UDP);
611 fail_unless (audio_transport->mode_play);
612 gst_rtsp_transport_free (audio_transport);
614 /* clean up and iterate so the clean-up can finish */
616 gst_sdp_message_free (sdp_message);
617 gst_rtsp_connection_free (conn);
624 GST_START_TEST (test_setup_non_existing_stream)
626 GstRTSPConnection *conn;
627 GstRTSPRange client_ports;
631 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
633 get_client_ports (&client_ports);
635 /* send SETUP request with a non-existing stream and check that we get a
637 fail_unless (do_setup (conn, "stream=7", &client_ports, NULL,
638 NULL) == GST_RTSP_STS_NOT_FOUND);
640 /* clean up and iterate so the clean-up can finish */
641 gst_rtsp_connection_free (conn);
649 receive_rtp (GSocket * socket, GSocketAddress ** addr)
651 GstBuffer *buffer = gst_buffer_new_allocate (NULL, 65536, NULL);
655 GstMapInfo map = GST_MAP_INFO_INIT;
656 GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;
658 gst_buffer_map (buffer, &map, GST_MAP_WRITE);
659 bytes = g_socket_receive_from (socket, addr, (gchar *) map.data,
660 map.maxsize, NULL, NULL);
661 fail_unless (bytes > 0);
662 gst_buffer_unmap (buffer, &map);
663 gst_buffer_set_size (buffer, bytes);
665 if (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtpbuffer)) {
666 gst_rtp_buffer_unmap (&rtpbuffer);
671 g_clear_object (addr);
674 gst_buffer_unref (buffer);
678 receive_rtcp (GSocket * socket, GSocketAddress ** addr, GstRTCPType type)
680 GstBuffer *buffer = gst_buffer_new_allocate (NULL, 65536, NULL);
684 GstMapInfo map = GST_MAP_INFO_INIT;
686 gst_buffer_map (buffer, &map, GST_MAP_WRITE);
687 bytes = g_socket_receive_from (socket, addr, (gchar *) map.data,
688 map.maxsize, NULL, NULL);
689 fail_unless (bytes > 0);
690 gst_buffer_unmap (buffer, &map);
691 gst_buffer_set_size (buffer, bytes);
693 if (gst_rtcp_buffer_validate (buffer)) {
694 GstRTCPBuffer rtcpbuffer = GST_RTCP_BUFFER_INIT;
695 GstRTCPPacket packet;
698 fail_unless (gst_rtcp_buffer_map (buffer, GST_MAP_READ, &rtcpbuffer));
699 fail_unless (gst_rtcp_buffer_get_first_packet (&rtcpbuffer, &packet));
701 if (gst_rtcp_packet_get_type (&packet) == type) {
702 gst_rtcp_buffer_unmap (&rtcpbuffer);
705 } while (gst_rtcp_packet_move_to_next (&packet));
706 gst_rtcp_buffer_unmap (&rtcpbuffer);
713 g_clear_object (addr);
718 gst_buffer_unref (buffer);
722 do_test_play (const gchar * range)
724 GstRTSPConnection *conn;
725 GstSDPMessage *sdp_message = NULL;
726 const GstSDPMedia *sdp_media;
727 const gchar *video_control;
728 const gchar *audio_control;
729 GstRTSPRange client_port;
730 gchar *session = NULL;
731 GstRTSPTransport *video_transport = NULL;
732 GstRTSPTransport *audio_transport = NULL;
733 GSocket *rtp_socket, *rtcp_socket;
734 gchar *range_out = NULL;
736 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
738 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
740 /* get control strings from DESCRIBE response */
741 fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
742 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
743 video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
744 sdp_media = gst_sdp_message_get_media (sdp_message, 1);
745 audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
747 get_client_ports_full (&client_port, &rtp_socket, &rtcp_socket);
749 /* do SETUP for video and audio */
750 fail_unless (do_setup (conn, video_control, &client_port, &session,
751 &video_transport) == GST_RTSP_STS_OK);
752 fail_unless (do_setup (conn, audio_control, &client_port, &session,
753 &audio_transport) == GST_RTSP_STS_OK);
755 /* send PLAY request and check that we get 200 OK */
756 fail_unless (do_request (conn, GST_RTSP_PLAY, NULL, session, NULL, range,
757 NULL, NULL, NULL, NULL, NULL, &range_out) == GST_RTSP_STS_OK);
759 fail_unless_equals_string (range, range_out);
762 receive_rtp (rtp_socket, NULL);
763 receive_rtcp (rtcp_socket, NULL, 0);
765 /* send TEARDOWN request and check that we get 200 OK */
766 fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
767 session) == GST_RTSP_STS_OK);
769 /* FIXME: The rtsp-server always disconnects the transport before
770 * sending the RTCP BYE
771 * receive_rtcp (rtcp_socket, NULL, GST_RTCP_TYPE_BYE);
774 /* clean up and iterate so the clean-up can finish */
775 g_object_unref (rtp_socket);
776 g_object_unref (rtcp_socket);
778 gst_rtsp_transport_free (video_transport);
779 gst_rtsp_transport_free (audio_transport);
780 gst_sdp_message_free (sdp_message);
781 gst_rtsp_connection_free (conn);
785 GST_START_TEST (test_play)
797 GST_START_TEST (test_play_without_session)
799 GstRTSPConnection *conn;
803 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
805 /* send PLAY request without a session and check that we get a
806 * 454 Session Not Found */
807 fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
808 NULL) == GST_RTSP_STS_SESSION_NOT_FOUND);
810 /* clean up and iterate so the clean-up can finish */
811 gst_rtsp_connection_free (conn);
818 GST_START_TEST (test_bind_already_in_use)
821 GSocketService *service;
822 GError *error = NULL;
826 serv = gst_rtsp_server_new ();
827 service = g_socket_service_new ();
829 /* bind service to port */
831 g_socket_listener_add_any_inet_port (G_SOCKET_LISTENER (service), NULL,
833 g_assert_no_error (error);
835 port_str = g_strdup_printf ("%d\n", port);
837 /* try to bind server to the same port */
838 g_object_set (serv, "service", port_str, NULL);
841 /* attach to default main context */
842 fail_unless (gst_rtsp_server_attach (serv, NULL) == 0);
845 g_object_unref (serv);
846 g_socket_service_stop (service);
847 g_object_unref (service);
853 GST_START_TEST (test_play_multithreaded)
855 GstRTSPThreadPool *pool;
857 pool = gst_rtsp_server_get_thread_pool (server);
858 gst_rtsp_thread_pool_set_max_threads (pool, 2);
859 g_object_unref (pool);
880 media_constructed_block (GstRTSPMediaFactory * factory,
881 GstRTSPMedia * media, gpointer user_data)
883 gint *block_state = user_data;
885 g_mutex_lock (&check_mutex);
887 *block_state = BLOCKED;
888 g_cond_broadcast (&check_cond);
890 while (*block_state != UNBLOCK)
891 g_cond_wait (&check_cond, &check_mutex);
892 g_mutex_unlock (&check_mutex);
896 GST_START_TEST (test_play_multithreaded_block_in_describe)
898 GstRTSPConnection *conn;
899 GstRTSPMountPoints *mounts;
900 GstRTSPMediaFactory *factory;
901 gint block_state = BLOCK_ME;
902 GstRTSPMessage *request;
903 GstRTSPMessage *response;
904 GstRTSPStatusCode code;
905 GstRTSPThreadPool *pool;
907 pool = gst_rtsp_server_get_thread_pool (server);
908 gst_rtsp_thread_pool_set_max_threads (pool, 2);
909 g_object_unref (pool);
911 mounts = gst_rtsp_server_get_mount_points (server);
912 fail_unless (mounts != NULL);
913 factory = gst_rtsp_media_factory_new ();
914 gst_rtsp_media_factory_set_launch (factory,
915 "( " VIDEO_PIPELINE " " AUDIO_PIPELINE " )");
916 g_signal_connect (factory, "media-constructed",
917 G_CALLBACK (media_constructed_block), &block_state);
918 gst_rtsp_mount_points_add_factory (mounts, TEST_MOUNT_POINT "2", factory);
919 g_object_unref (mounts);
923 conn = connect_to_server (test_port, TEST_MOUNT_POINT "2");
926 /* do describe, it will not return now as we've blocked it */
927 request = create_request (conn, GST_RTSP_DESCRIBE, NULL);
928 fail_unless (send_request (conn, request));
929 gst_rtsp_message_free (request);
931 g_mutex_lock (&check_mutex);
932 while (block_state != BLOCKED)
933 g_cond_wait (&check_cond, &check_mutex);
934 g_mutex_unlock (&check_mutex);
936 /* Do a second connection while the first one is blocked */
939 /* Now unblock the describe */
940 g_mutex_lock (&check_mutex);
941 block_state = UNBLOCK;
942 g_cond_broadcast (&check_cond);
943 g_mutex_unlock (&check_mutex);
945 response = read_response (conn);
946 gst_rtsp_message_parse_response (response, &code, NULL, NULL);
947 fail_unless (code == GST_RTSP_STS_OK);
948 gst_rtsp_message_free (response);
951 gst_rtsp_connection_free (conn);
961 new_session_timeout_one (GstRTSPClient * client,
962 GstRTSPSession * session, gpointer user_data)
964 gst_rtsp_session_set_timeout (session, 1);
966 g_signal_handlers_disconnect_by_func (client, new_session_timeout_one,
971 session_connected_new_session_cb (GstRTSPServer * server,
972 GstRTSPClient * client, gpointer user_data)
975 g_signal_connect (client, "new-session", user_data, NULL);
978 GST_START_TEST (test_play_multithreaded_timeout_client)
980 GstRTSPConnection *conn;
981 GstSDPMessage *sdp_message = NULL;
982 const GstSDPMedia *sdp_media;
983 const gchar *video_control;
984 const gchar *audio_control;
985 GstRTSPRange client_port;
986 gchar *session = NULL;
987 GstRTSPTransport *video_transport = NULL;
988 GstRTSPTransport *audio_transport = NULL;
989 GstRTSPSessionPool *pool;
990 GstRTSPThreadPool *thread_pool;
992 thread_pool = gst_rtsp_server_get_thread_pool (server);
993 gst_rtsp_thread_pool_set_max_threads (thread_pool, 2);
994 g_object_unref (thread_pool);
996 pool = gst_rtsp_server_get_session_pool (server);
997 g_signal_connect (server, "client-connected",
998 G_CALLBACK (session_connected_new_session_cb), new_session_timeout_one);
1003 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
1005 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
1007 /* get control strings from DESCRIBE response */
1008 fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
1009 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
1010 video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1011 sdp_media = gst_sdp_message_get_media (sdp_message, 1);
1012 audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1014 get_client_ports (&client_port);
1016 /* do SETUP for video and audio */
1017 fail_unless (do_setup (conn, video_control, &client_port, &session,
1018 &video_transport) == GST_RTSP_STS_OK);
1019 fail_unless (do_setup (conn, audio_control, &client_port, &session,
1020 &audio_transport) == GST_RTSP_STS_OK);
1022 fail_unless (gst_rtsp_session_pool_get_n_sessions (pool) == 1);
1024 /* send PLAY request and check that we get 200 OK */
1025 fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
1026 session) == GST_RTSP_STS_OK);
1030 fail_unless (gst_rtsp_session_pool_cleanup (pool) == 1);
1031 fail_unless (gst_rtsp_session_pool_get_n_sessions (pool) == 0);
1033 /* clean up and iterate so the clean-up can finish */
1034 g_object_unref (pool);
1036 gst_rtsp_transport_free (video_transport);
1037 gst_rtsp_transport_free (audio_transport);
1038 gst_sdp_message_free (sdp_message);
1039 gst_rtsp_connection_free (conn);
1048 GST_START_TEST (test_play_multithreaded_timeout_session)
1050 GstRTSPConnection *conn;
1051 GstSDPMessage *sdp_message = NULL;
1052 const GstSDPMedia *sdp_media;
1053 const gchar *video_control;
1054 const gchar *audio_control;
1055 GstRTSPRange client_port;
1056 gchar *session1 = NULL;
1057 gchar *session2 = NULL;
1058 GstRTSPTransport *video_transport = NULL;
1059 GstRTSPTransport *audio_transport = NULL;
1060 GstRTSPSessionPool *pool;
1061 GstRTSPThreadPool *thread_pool;
1063 thread_pool = gst_rtsp_server_get_thread_pool (server);
1064 gst_rtsp_thread_pool_set_max_threads (thread_pool, 2);
1065 g_object_unref (thread_pool);
1067 pool = gst_rtsp_server_get_session_pool (server);
1068 g_signal_connect (server, "client-connected",
1069 G_CALLBACK (session_connected_new_session_cb), new_session_timeout_one);
1074 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
1076 gst_rtsp_connection_set_remember_session_id (conn, FALSE);
1078 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
1080 /* get control strings from DESCRIBE response */
1081 fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
1082 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
1083 video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1084 sdp_media = gst_sdp_message_get_media (sdp_message, 1);
1085 audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1087 get_client_ports (&client_port);
1089 /* do SETUP for video and audio */
1090 fail_unless (do_setup (conn, video_control, &client_port, &session1,
1091 &video_transport) == GST_RTSP_STS_OK);
1092 fail_unless (do_setup (conn, audio_control, &client_port, &session2,
1093 &audio_transport) == GST_RTSP_STS_OK);
1095 fail_unless (gst_rtsp_session_pool_get_n_sessions (pool) == 2);
1097 /* send PLAY request and check that we get 200 OK */
1098 fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
1099 session1) == GST_RTSP_STS_OK);
1100 fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
1101 session2) == GST_RTSP_STS_OK);
1105 fail_unless (gst_rtsp_session_pool_cleanup (pool) == 1);
1107 /* send TEARDOWN request and check that we get 454 Session Not found */
1108 fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
1109 session1) == GST_RTSP_STS_SESSION_NOT_FOUND);
1111 fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
1112 session2) == GST_RTSP_STS_OK);
1114 /* clean up and iterate so the clean-up can finish */
1115 g_object_unref (pool);
1118 gst_rtsp_transport_free (video_transport);
1119 gst_rtsp_transport_free (audio_transport);
1120 gst_sdp_message_free (sdp_message);
1121 gst_rtsp_connection_free (conn);
1130 GST_START_TEST (test_play_disconnect)
1132 GstRTSPConnection *conn;
1133 GstSDPMessage *sdp_message = NULL;
1134 const GstSDPMedia *sdp_media;
1135 const gchar *video_control;
1136 const gchar *audio_control;
1137 GstRTSPRange client_port;
1138 gchar *session = NULL;
1139 GstRTSPTransport *video_transport = NULL;
1140 GstRTSPTransport *audio_transport = NULL;
1141 GstRTSPSessionPool *pool;
1143 pool = gst_rtsp_server_get_session_pool (server);
1144 g_signal_connect (server, "client-connected",
1145 G_CALLBACK (session_connected_new_session_cb), new_session_timeout_one);
1149 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
1151 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
1153 /* get control strings from DESCRIBE response */
1154 fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
1155 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
1156 video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1157 sdp_media = gst_sdp_message_get_media (sdp_message, 1);
1158 audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1160 get_client_ports (&client_port);
1162 /* do SETUP for video and audio */
1163 fail_unless (do_setup (conn, video_control, &client_port, &session,
1164 &video_transport) == GST_RTSP_STS_OK);
1165 fail_unless (do_setup (conn, audio_control, &client_port, &session,
1166 &audio_transport) == GST_RTSP_STS_OK);
1168 fail_unless (gst_rtsp_session_pool_get_n_sessions (pool) == 1);
1170 /* send PLAY request and check that we get 200 OK */
1171 fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
1172 session) == GST_RTSP_STS_OK);
1174 gst_rtsp_connection_free (conn);
1178 fail_unless (gst_rtsp_session_pool_get_n_sessions (pool) == 1);
1179 fail_unless (gst_rtsp_session_pool_cleanup (pool) == 1);
1182 /* clean up and iterate so the clean-up can finish */
1183 g_object_unref (pool);
1185 gst_rtsp_transport_free (video_transport);
1186 gst_rtsp_transport_free (audio_transport);
1187 gst_sdp_message_free (sdp_message);
1195 /* Only different with test_play is the specific ports selected */
1197 GST_START_TEST (test_play_specific_server_port)
1199 GstRTSPMountPoints *mounts;
1201 GstRTSPMediaFactory *factory;
1202 GstRTSPAddressPool *pool;
1203 GstRTSPConnection *conn;
1204 GstSDPMessage *sdp_message = NULL;
1205 const GstSDPMedia *sdp_media;
1206 const gchar *video_control;
1207 GstRTSPRange client_port;
1208 gchar *session = NULL;
1209 GstRTSPTransport *video_transport = NULL;
1210 GSocket *rtp_socket, *rtcp_socket;
1211 GSocketAddress *rtp_address, *rtcp_address;
1212 guint16 rtp_port, rtcp_port;
1214 mounts = gst_rtsp_server_get_mount_points (server);
1216 factory = gst_rtsp_media_factory_new ();
1217 pool = gst_rtsp_address_pool_new ();
1218 gst_rtsp_address_pool_add_range (pool, GST_RTSP_ADDRESS_POOL_ANY_IPV4,
1219 GST_RTSP_ADDRESS_POOL_ANY_IPV4, 7770, 7780, 0);
1220 gst_rtsp_media_factory_set_address_pool (factory, pool);
1221 g_object_unref (pool);
1222 gst_rtsp_media_factory_set_launch (factory, "( " VIDEO_PIPELINE " )");
1223 gst_rtsp_mount_points_add_factory (mounts, TEST_MOUNT_POINT, factory);
1224 g_object_unref (mounts);
1226 /* set port to any */
1227 gst_rtsp_server_set_service (server, "0");
1229 /* attach to default main context */
1230 source_id = gst_rtsp_server_attach (server, NULL);
1231 fail_if (source_id == 0);
1234 service = gst_rtsp_server_get_service (server);
1235 test_port = atoi (service);
1236 fail_unless (test_port != 0);
1239 GST_DEBUG ("rtsp server listening on port %d", test_port);
1242 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
1244 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
1246 /* get control strings from DESCRIBE response */
1247 fail_unless (gst_sdp_message_medias_len (sdp_message) == 1);
1248 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
1249 video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1251 get_client_ports_full (&client_port, &rtp_socket, &rtcp_socket);
1253 /* do SETUP for video */
1254 fail_unless (do_setup (conn, video_control, &client_port, &session,
1255 &video_transport) == GST_RTSP_STS_OK);
1257 /* send PLAY request and check that we get 200 OK */
1258 fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
1259 session) == GST_RTSP_STS_OK);
1261 receive_rtp (rtp_socket, &rtp_address);
1262 receive_rtcp (rtcp_socket, &rtcp_address, 0);
1264 fail_unless (G_IS_INET_SOCKET_ADDRESS (rtp_address));
1265 fail_unless (G_IS_INET_SOCKET_ADDRESS (rtcp_address));
1267 g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (rtp_address));
1269 g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (rtcp_address));
1270 fail_unless (rtp_port >= 7770 && rtp_port <= 7780 && rtp_port % 2 == 0);
1271 fail_unless (rtcp_port >= 7770 && rtcp_port <= 7780 && rtcp_port % 2 == 1);
1272 fail_unless (rtp_port + 1 == rtcp_port);
1274 g_object_unref (rtp_address);
1275 g_object_unref (rtcp_address);
1277 /* send TEARDOWN request and check that we get 200 OK */
1278 fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
1279 session) == GST_RTSP_STS_OK);
1281 /* FIXME: The rtsp-server always disconnects the transport before
1282 * sending the RTCP BYE
1283 * receive_rtcp (rtcp_socket, NULL, GST_RTCP_TYPE_BYE);
1286 /* clean up and iterate so the clean-up can finish */
1287 g_object_unref (rtp_socket);
1288 g_object_unref (rtcp_socket);
1290 gst_rtsp_transport_free (video_transport);
1291 gst_sdp_message_free (sdp_message);
1292 gst_rtsp_connection_free (conn);
1302 GST_START_TEST (test_play_smpte_range)
1306 do_test_play ("npt=5-");
1307 do_test_play ("smpte=0:00:00-");
1308 do_test_play ("smpte=1:00:00-");
1309 do_test_play ("smpte=1:00:03-");
1310 do_test_play ("clock=20120321T152256Z-");
1320 rtspserver_suite (void)
1322 Suite *s = suite_create ("rtspserver");
1323 TCase *tc = tcase_create ("general");
1325 suite_add_tcase (s, tc);
1326 tcase_add_checked_fixture (tc, setup, teardown);
1327 tcase_set_timeout (tc, 20);
1328 tcase_add_test (tc, test_connect);
1329 tcase_add_test (tc, test_describe);
1330 tcase_add_test (tc, test_describe_non_existing_mount_point);
1331 tcase_add_test (tc, test_setup);
1332 tcase_add_test (tc, test_setup_non_existing_stream);
1333 tcase_add_test (tc, test_play);
1334 tcase_add_test (tc, test_play_without_session);
1335 tcase_add_test (tc, test_bind_already_in_use);
1336 tcase_add_test (tc, test_play_multithreaded);
1337 tcase_add_test (tc, test_play_multithreaded_block_in_describe);
1338 tcase_add_test (tc, test_play_multithreaded_timeout_client);
1339 tcase_add_test (tc, test_play_multithreaded_timeout_session);
1340 tcase_add_test (tc, test_play_disconnect);
1341 tcase_add_test (tc, test_play_specific_server_port);
1342 tcase_add_test (tc, test_play_smpte_range);
1346 GST_CHECK_MAIN (rtspserver);