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");
64 /* returns an unused port that can be used by the test */
66 get_unused_port (gint type)
69 struct sockaddr_in addr;
74 fail_unless ((sock = socket (AF_INET, type, 0)) > 0);
76 /* pass port 0 to bind, which will bind to any free port */
77 memset (&addr, 0, sizeof addr);
78 addr.sin_family = AF_INET;
79 addr.sin_addr.s_addr = INADDR_ANY;
80 addr.sin_port = htons (0);
81 fail_unless (bind (sock, (struct sockaddr *) &addr, sizeof addr) == 0);
83 /* ask what port was bound using getsockname */
84 addr_len = sizeof addr;
85 memset (&addr, 0, addr_len);
86 fail_unless (getsockname (sock, (struct sockaddr *) &addr, &addr_len) == 0);
87 port = ntohs (addr.sin_port);
89 /* close the socket so the port gets unbound again (and can be used by the
97 get_client_ports_full (GstRTSPRange * range, GSocket ** rtp_socket,
98 GSocket ** rtcp_socket)
101 GSocket *rtcp = NULL;
104 GInetAddress *anyaddr = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4);
105 GSocketAddress *sockaddr;
112 rtp = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM,
113 G_SOCKET_PROTOCOL_UDP, NULL);
114 fail_unless (rtp != NULL);
116 sockaddr = g_inet_socket_address_new (anyaddr, rtp_port);
117 fail_unless (sockaddr != NULL);
118 bound = g_socket_bind (rtp, sockaddr, FALSE, NULL);
119 g_object_unref (sockaddr);
121 g_object_unref (rtp);
125 sockaddr = g_socket_get_local_address (rtp, NULL);
126 fail_unless (sockaddr != NULL && G_IS_INET_SOCKET_ADDRESS (sockaddr));
128 g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (sockaddr));
129 g_object_unref (sockaddr);
131 if (rtp_port % 2 != 0) {
133 g_object_unref (rtp);
137 rtcp_port = rtp_port + 1;
139 rtcp = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM,
140 G_SOCKET_PROTOCOL_UDP, NULL);
141 fail_unless (rtcp != NULL);
143 sockaddr = g_inet_socket_address_new (anyaddr, rtcp_port);
144 fail_unless (sockaddr != NULL);
145 bound = g_socket_bind (rtcp, sockaddr, FALSE, NULL);
146 g_object_unref (sockaddr);
148 g_object_unref (rtp);
149 g_object_unref (rtcp);
153 sockaddr = g_socket_get_local_address (rtcp, NULL);
154 fail_unless (sockaddr != NULL && G_IS_INET_SOCKET_ADDRESS (sockaddr));
155 fail_unless (rtcp_port ==
156 g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (sockaddr)));
157 g_object_unref (sockaddr);
162 range->min = rtp_port;
163 range->max = rtcp_port;
167 g_object_unref (rtp);
171 g_object_unref (rtcp);
172 GST_DEBUG ("client_port=%d-%d", range->min, range->max);
173 g_object_unref (anyaddr);
176 /* get a free rtp/rtcp client port pair */
178 get_client_ports (GstRTSPRange * range)
180 get_client_ports_full (range, NULL, NULL);
183 /* start the tested rtsp server */
187 GstRTSPMountPoints *mounts;
189 GstRTSPMediaFactory *factory;
191 mounts = gst_rtsp_server_get_mount_points (server);
193 factory = gst_rtsp_media_factory_new ();
195 gst_rtsp_media_factory_set_launch (factory,
196 "( " VIDEO_PIPELINE " " AUDIO_PIPELINE " )");
197 gst_rtsp_mount_points_add_factory (mounts, TEST_MOUNT_POINT, factory);
198 g_object_unref (mounts);
201 test_port = get_unused_port (SOCK_STREAM);
202 service = g_strdup_printf ("%d", test_port);
203 gst_rtsp_server_set_service (server, service);
206 /* attach to default main context */
207 source_id = gst_rtsp_server_attach (server, NULL);
208 fail_if (source_id == 0);
210 GST_DEBUG ("rtsp server listening on port %d", test_port);
213 /* stop the tested rtsp server */
217 g_source_remove (source_id);
220 GST_DEBUG ("rtsp server stopped");
223 /* create an rtsp connection to the server on test_port */
224 static GstRTSPConnection *
225 connect_to_server (gint port, const gchar * mount_point)
227 GstRTSPConnection *conn = NULL;
230 GstRTSPUrl *url = NULL;
232 address = gst_rtsp_server_get_address (server);
233 uri_string = g_strdup_printf ("rtsp://%s:%d%s", address, port, mount_point);
235 gst_rtsp_url_parse (uri_string, &url);
238 fail_unless (gst_rtsp_connection_create (url, &conn) == GST_RTSP_OK);
239 gst_rtsp_url_free (url);
241 fail_unless (gst_rtsp_connection_connect (conn, NULL) == GST_RTSP_OK);
246 /* create an rtsp request */
247 static GstRTSPMessage *
248 create_request (GstRTSPConnection * conn, GstRTSPMethod method,
249 const gchar * control)
251 GstRTSPMessage *request = NULL;
255 base_uri = gst_rtsp_url_get_request_uri (gst_rtsp_connection_get_url (conn));
256 full_uri = g_strdup_printf ("%s/%s", base_uri, control ? control : "");
258 if (gst_rtsp_message_new_request (&request, method, full_uri) != GST_RTSP_OK) {
259 GST_DEBUG ("failed to create request object");
267 /* send an rtsp request */
269 send_request (GstRTSPConnection * conn, GstRTSPMessage * request)
271 if (gst_rtsp_connection_send (conn, request, NULL) != GST_RTSP_OK) {
272 GST_DEBUG ("failed to send request");
278 /* read rtsp response. response must be freed by the caller */
279 static GstRTSPMessage *
280 read_response (GstRTSPConnection * conn)
282 GstRTSPMessage *response = NULL;
284 if (gst_rtsp_message_new (&response) != GST_RTSP_OK) {
285 GST_DEBUG ("failed to create response object");
288 if (gst_rtsp_connection_receive (conn, response, NULL) != GST_RTSP_OK) {
289 GST_DEBUG ("failed to read response");
290 gst_rtsp_message_free (response);
293 fail_unless (gst_rtsp_message_get_type (response) ==
294 GST_RTSP_MESSAGE_RESPONSE);
298 /* send an rtsp request and receive response. gchar** parameters are out
299 * parameters that have to be freed by the caller */
300 static GstRTSPStatusCode
301 do_request (GstRTSPConnection * conn, GstRTSPMethod method,
302 const gchar * control, const gchar * session_in, const gchar * transport_in,
303 gchar ** content_type, gchar ** content_base, gchar ** body,
304 gchar ** session_out, gchar ** transport_out)
306 GstRTSPMessage *request;
307 GstRTSPMessage *response;
308 GstRTSPStatusCode code;
312 request = create_request (conn, method, control);
316 gst_rtsp_message_add_header (request, GST_RTSP_HDR_SESSION, session_in);
319 gst_rtsp_message_add_header (request, GST_RTSP_HDR_TRANSPORT, transport_in);
323 fail_unless (send_request (conn, request));
324 gst_rtsp_message_free (request);
329 response = read_response (conn);
331 /* check status line */
332 gst_rtsp_message_parse_response (response, &code, NULL, NULL);
333 if (code != GST_RTSP_STS_OK) {
334 gst_rtsp_message_free (response);
338 /* get information from response */
340 gst_rtsp_message_get_header (response, GST_RTSP_HDR_CONTENT_TYPE,
342 *content_type = g_strdup (value);
345 gst_rtsp_message_get_header (response, GST_RTSP_HDR_CONTENT_BASE,
347 *content_base = g_strdup (value);
350 *body = g_malloc (response->body_size + 1);
351 strncpy (*body, (gchar *) response->body, response->body_size);
354 gst_rtsp_message_get_header (response, GST_RTSP_HDR_SESSION, &value, 0);
356 value = g_strdup (value);
358 /* Remove the timeout */
360 char *pos = strchr (value, ';');
365 /* check that we got the same session back */
366 fail_unless (!g_strcmp0 (value, session_in));
368 *session_out = value;
371 gst_rtsp_message_get_header (response, GST_RTSP_HDR_TRANSPORT, &value, 0);
372 *transport_out = g_strdup (value);
375 gst_rtsp_message_free (response);
379 /* send an rtsp request with a method and a session, and receive response */
380 static GstRTSPStatusCode
381 do_simple_request (GstRTSPConnection * conn, GstRTSPMethod method,
382 const gchar * session)
384 return do_request (conn, method, NULL, session, NULL, NULL, NULL,
388 /* send a DESCRIBE request and receive response. returns a received
389 * GstSDPMessage that must be freed by the caller */
390 static GstSDPMessage *
391 do_describe (GstRTSPConnection * conn, const gchar * mount_point)
393 GstSDPMessage *sdp_message;
398 gchar *expected_content_base;
400 /* send DESCRIBE request */
401 fail_unless (do_request (conn, GST_RTSP_DESCRIBE, NULL, NULL, NULL,
402 &content_type, &content_base, &body, NULL, NULL) == GST_RTSP_STS_OK);
404 /* check response values */
405 fail_unless (!g_strcmp0 (content_type, "application/sdp"));
406 address = gst_rtsp_server_get_address (server);
407 expected_content_base =
408 g_strdup_printf ("rtsp://%s:%d%s/", address, test_port, mount_point);
409 fail_unless (!g_strcmp0 (content_base, expected_content_base));
411 /* create sdp message */
412 fail_unless (gst_sdp_message_new (&sdp_message) == GST_SDP_OK);
413 fail_unless (gst_sdp_message_parse_buffer ((guint8 *) body,
414 strlen (body), sdp_message) == GST_SDP_OK);
417 g_free (content_type);
418 g_free (content_base);
421 g_free (expected_content_base);
426 /* send a SETUP request and receive response. if *session is not NULL,
427 * it is used in the request. otherwise, *session is set to a returned
428 * session string that must be freed by the caller. the returned
429 * transport must be freed by the caller. */
430 static GstRTSPStatusCode
431 do_setup (GstRTSPConnection * conn, const gchar * control,
432 const GstRTSPRange * client_ports, gchar ** session,
433 GstRTSPTransport ** transport)
435 GstRTSPStatusCode code;
436 gchar *session_in = NULL;
437 gchar *transport_string_in = NULL;
438 gchar **session_out = NULL;
439 gchar *transport_string_out = NULL;
441 /* prepare and send SETUP request */
444 session_in = *session;
446 session_out = session;
449 transport_string_in =
450 g_strdup_printf (TEST_PROTO ";unicast;client_port=%d-%d",
451 client_ports->min, client_ports->max);
453 do_request (conn, GST_RTSP_SETUP, control, session_in,
454 transport_string_in, NULL, NULL, NULL, session_out,
455 &transport_string_out);
456 g_free (transport_string_in);
458 if (transport_string_out) {
459 /* create transport */
460 fail_unless (gst_rtsp_transport_new (transport) == GST_RTSP_OK);
461 fail_unless (gst_rtsp_transport_parse (transport_string_out,
462 *transport) == GST_RTSP_OK);
463 g_free (transport_string_out);
469 /* fixture setup function */
473 server = gst_rtsp_server_new ();
476 /* fixture clean-up function */
481 g_object_unref (server);
487 GST_START_TEST (test_connect)
489 GstRTSPConnection *conn;
493 /* connect to server */
494 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
497 gst_rtsp_connection_free (conn);
500 /* iterate so the clean-up can finish */
506 GST_START_TEST (test_describe)
508 GstRTSPConnection *conn;
509 GstSDPMessage *sdp_message = NULL;
510 const GstSDPMedia *sdp_media;
512 gchar *expected_rtpmap;
514 const gchar *control_video;
515 const gchar *control_audio;
519 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
521 /* send DESCRIBE request */
522 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
524 fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
526 /* check video sdp */
527 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
528 fail_unless (!g_strcmp0 (gst_sdp_media_get_proto (sdp_media), TEST_PROTO));
529 fail_unless (gst_sdp_media_formats_len (sdp_media) == 1);
530 sscanf (gst_sdp_media_get_format (sdp_media, 0), "%" G_GINT32_FORMAT,
533 g_strdup_printf ("%d " TEST_ENCODING "/" TEST_CLOCK_RATE, format);
534 rtpmap = gst_sdp_media_get_attribute_val (sdp_media, "rtpmap");
535 fail_unless (!g_strcmp0 (rtpmap, expected_rtpmap));
536 g_free (expected_rtpmap);
537 control_video = gst_sdp_media_get_attribute_val (sdp_media, "control");
538 fail_unless (!g_strcmp0 (control_video, "stream=0"));
540 /* check audio sdp */
541 sdp_media = gst_sdp_message_get_media (sdp_message, 1);
542 fail_unless (!g_strcmp0 (gst_sdp_media_get_proto (sdp_media), TEST_PROTO));
543 fail_unless (gst_sdp_media_formats_len (sdp_media) == 1);
544 sscanf (gst_sdp_media_get_format (sdp_media, 0), "%" G_GINT32_FORMAT,
547 g_strdup_printf ("%d " TEST_ENCODING "/" TEST_CLOCK_RATE, format);
548 rtpmap = gst_sdp_media_get_attribute_val (sdp_media, "rtpmap");
549 fail_unless (!g_strcmp0 (rtpmap, expected_rtpmap));
550 g_free (expected_rtpmap);
551 control_audio = gst_sdp_media_get_attribute_val (sdp_media, "control");
552 fail_unless (!g_strcmp0 (control_audio, "stream=1"));
554 /* clean up and iterate so the clean-up can finish */
555 gst_sdp_message_free (sdp_message);
556 gst_rtsp_connection_free (conn);
563 GST_START_TEST (test_describe_non_existing_mount_point)
565 GstRTSPConnection *conn;
569 /* send DESCRIBE request for a non-existing mount point
570 * and check that we get a 404 Not Found */
571 conn = connect_to_server (test_port, "/non-existing");
572 fail_unless (do_simple_request (conn, GST_RTSP_DESCRIBE, NULL)
573 == GST_RTSP_STS_NOT_FOUND);
575 /* clean up and iterate so the clean-up can finish */
576 gst_rtsp_connection_free (conn);
583 GST_START_TEST (test_setup)
585 GstRTSPConnection *conn;
586 GstSDPMessage *sdp_message = NULL;
587 const GstSDPMedia *sdp_media;
588 const gchar *video_control;
589 const gchar *audio_control;
590 GstRTSPRange client_ports;
591 gchar *session = NULL;
592 GstRTSPTransport *video_transport = NULL;
593 GstRTSPTransport *audio_transport = NULL;
597 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
599 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
601 /* get control strings from DESCRIBE response */
602 fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
603 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
604 video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
605 sdp_media = gst_sdp_message_get_media (sdp_message, 1);
606 audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
608 get_client_ports (&client_ports);
610 /* send SETUP request for video */
611 fail_unless (do_setup (conn, video_control, &client_ports, &session,
612 &video_transport) == GST_RTSP_STS_OK);
613 GST_DEBUG ("set up video %s, got session '%s'", video_control, session);
615 /* check response from SETUP */
616 fail_unless (video_transport->trans == GST_RTSP_TRANS_RTP);
617 fail_unless (video_transport->profile == GST_RTSP_PROFILE_AVP);
618 fail_unless (video_transport->lower_transport == GST_RTSP_LOWER_TRANS_UDP);
619 fail_unless (video_transport->mode_play);
620 gst_rtsp_transport_free (video_transport);
622 /* send SETUP request for audio */
623 fail_unless (do_setup (conn, audio_control, &client_ports, &session,
624 &audio_transport) == GST_RTSP_STS_OK);
625 GST_DEBUG ("set up audio %s with session '%s'", audio_control, session);
627 /* check response from SETUP */
628 fail_unless (audio_transport->trans == GST_RTSP_TRANS_RTP);
629 fail_unless (audio_transport->profile == GST_RTSP_PROFILE_AVP);
630 fail_unless (audio_transport->lower_transport == GST_RTSP_LOWER_TRANS_UDP);
631 fail_unless (audio_transport->mode_play);
632 gst_rtsp_transport_free (audio_transport);
634 /* clean up and iterate so the clean-up can finish */
636 gst_sdp_message_free (sdp_message);
637 gst_rtsp_connection_free (conn);
644 GST_START_TEST (test_setup_non_existing_stream)
646 GstRTSPConnection *conn;
647 GstRTSPRange client_ports;
651 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
653 get_client_ports (&client_ports);
655 /* send SETUP request with a non-existing stream and check that we get a
657 fail_unless (do_setup (conn, "stream=7", &client_ports, NULL,
658 NULL) == GST_RTSP_STS_NOT_FOUND);
660 /* clean up and iterate so the clean-up can finish */
661 gst_rtsp_connection_free (conn);
665 /* need to unref the server here, otherwise threads will remain
666 * and teardown won't be run */
667 g_object_unref (server);
674 receive_rtp (GSocket * socket, GSocketAddress ** addr)
676 GstBuffer *buffer = gst_buffer_new_allocate (NULL, 65536, NULL);
680 GstMapInfo map = GST_MAP_INFO_INIT;
681 GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;
683 gst_buffer_map (buffer, &map, GST_MAP_WRITE);
684 bytes = g_socket_receive_from (socket, addr, (gchar *) map.data,
685 map.maxsize, NULL, NULL);
686 fail_unless (bytes > 0);
687 gst_buffer_unmap (buffer, &map);
688 gst_buffer_set_size (buffer, bytes);
690 if (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtpbuffer)) {
691 gst_rtp_buffer_unmap (&rtpbuffer);
696 g_clear_object (addr);
699 gst_buffer_unref (buffer);
703 receive_rtcp (GSocket * socket, GSocketAddress ** addr, GstRTCPType type)
705 GstBuffer *buffer = gst_buffer_new_allocate (NULL, 65536, NULL);
709 GstMapInfo map = GST_MAP_INFO_INIT;
711 gst_buffer_map (buffer, &map, GST_MAP_WRITE);
712 bytes = g_socket_receive_from (socket, addr, (gchar *) map.data,
713 map.maxsize, NULL, NULL);
714 fail_unless (bytes > 0);
715 gst_buffer_unmap (buffer, &map);
716 gst_buffer_set_size (buffer, bytes);
718 if (gst_rtcp_buffer_validate (buffer)) {
719 GstRTCPBuffer rtcpbuffer = GST_RTCP_BUFFER_INIT;
720 GstRTCPPacket packet;
723 fail_unless (gst_rtcp_buffer_map (buffer, GST_MAP_READ, &rtcpbuffer));
724 fail_unless (gst_rtcp_buffer_get_first_packet (&rtcpbuffer, &packet));
726 if (gst_rtcp_packet_get_type (&packet) == type) {
727 gst_rtcp_buffer_unmap (&rtcpbuffer);
730 } while (gst_rtcp_packet_move_to_next (&packet));
731 gst_rtcp_buffer_unmap (&rtcpbuffer);
738 g_clear_object (addr);
743 gst_buffer_unref (buffer);
749 GstRTSPConnection *conn;
750 GstSDPMessage *sdp_message = NULL;
751 const GstSDPMedia *sdp_media;
752 const gchar *video_control;
753 const gchar *audio_control;
754 GstRTSPRange client_port;
755 gchar *session = NULL;
756 GstRTSPTransport *video_transport = NULL;
757 GstRTSPTransport *audio_transport = NULL;
758 GSocket *rtp_socket, *rtcp_socket;
760 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
762 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
764 /* get control strings from DESCRIBE response */
765 fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
766 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
767 video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
768 sdp_media = gst_sdp_message_get_media (sdp_message, 1);
769 audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
771 get_client_ports_full (&client_port, &rtp_socket, &rtcp_socket);
773 /* do SETUP for video and audio */
774 fail_unless (do_setup (conn, video_control, &client_port, &session,
775 &video_transport) == GST_RTSP_STS_OK);
776 fail_unless (do_setup (conn, audio_control, &client_port, &session,
777 &audio_transport) == GST_RTSP_STS_OK);
779 /* send PLAY request and check that we get 200 OK */
780 fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
781 session) == GST_RTSP_STS_OK);
783 receive_rtp (rtp_socket, NULL);
784 receive_rtcp (rtcp_socket, NULL, 0);
786 /* send TEARDOWN request and check that we get 200 OK */
787 fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
788 session) == GST_RTSP_STS_OK);
790 /* FIXME: The rtsp-server always disconnects the transport before
791 * sending the RTCP BYE
792 * receive_rtcp (rtcp_socket, NULL, GST_RTCP_TYPE_BYE);
795 /* clean up and iterate so the clean-up can finish */
796 g_object_unref (rtp_socket);
797 g_object_unref (rtcp_socket);
799 gst_rtsp_transport_free (video_transport);
800 gst_rtsp_transport_free (audio_transport);
801 gst_sdp_message_free (sdp_message);
802 gst_rtsp_connection_free (conn);
806 GST_START_TEST (test_play)
818 GST_START_TEST (test_play_without_session)
820 GstRTSPConnection *conn;
824 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
826 /* send PLAY request without a session and check that we get a
827 * 454 Session Not Found */
828 fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
829 NULL) == GST_RTSP_STS_SESSION_NOT_FOUND);
831 /* clean up and iterate so the clean-up can finish */
832 gst_rtsp_connection_free (conn);
839 GST_START_TEST (test_bind_already_in_use)
842 GSocketService *service;
843 GError *error = NULL;
847 serv = gst_rtsp_server_new ();
848 service = g_socket_service_new ();
850 /* bind service to port */
852 g_socket_listener_add_any_inet_port (G_SOCKET_LISTENER (service), NULL,
854 g_assert_no_error (error);
856 port_str = g_strdup_printf ("%d\n", port);
858 /* try to bind server to the same port */
859 g_object_set (serv, "service", port_str, NULL);
862 /* attach to default main context */
863 fail_unless (gst_rtsp_server_attach (serv, NULL) == 0);
866 g_object_unref (serv);
867 g_socket_listener_close (G_SOCKET_LISTENER (service));
868 g_object_unref (service);
874 GST_START_TEST (test_play_multithreaded)
876 gst_rtsp_server_set_max_threads (server, 2);
897 media_constructed_block (GstRTSPMediaFactory * factory,
898 GstRTSPMedia * media, gpointer user_data)
900 gint *block_state = user_data;
902 g_mutex_lock (&check_mutex);
904 *block_state = BLOCKED;
905 g_cond_broadcast (&check_cond);
907 while (*block_state != UNBLOCK)
908 g_cond_wait (&check_cond, &check_mutex);
909 g_mutex_unlock (&check_mutex);
913 GST_START_TEST (test_play_multithreaded_block_in_describe)
915 GstRTSPConnection *conn;
916 GstRTSPMountPoints *mounts;
917 GstRTSPMediaFactory *factory;
918 gint block_state = BLOCK_ME;
919 GstRTSPMessage *request;
920 GstRTSPMessage *response;
921 GstRTSPStatusCode code;
923 gst_rtsp_server_set_max_threads (server, 2);
925 mounts = gst_rtsp_server_get_mount_points (server);
926 fail_unless (mounts != NULL);
927 factory = gst_rtsp_media_factory_new ();
928 gst_rtsp_media_factory_set_launch (factory,
929 "( " VIDEO_PIPELINE " " AUDIO_PIPELINE " )");
930 g_signal_connect (factory, "media-constructed",
931 G_CALLBACK (media_constructed_block), &block_state);
932 gst_rtsp_mount_points_add_factory (mounts, TEST_MOUNT_POINT "2", factory);
933 g_object_unref (mounts);
937 conn = connect_to_server (test_port, TEST_MOUNT_POINT "2");
940 /* do describe, it will not return now as we've blocked it */
941 request = create_request (conn, GST_RTSP_DESCRIBE, NULL);
942 fail_unless (send_request (conn, request));
943 gst_rtsp_message_free (request);
945 g_mutex_lock (&check_mutex);
946 while (block_state != BLOCKED)
947 g_cond_wait (&check_cond, &check_mutex);
948 g_mutex_unlock (&check_mutex);
950 /* Do a second connection while the first one is blocked */
953 /* Now unblock the describe */
954 g_mutex_lock (&check_mutex);
955 block_state = UNBLOCK;
956 g_cond_broadcast (&check_cond);
957 g_mutex_unlock (&check_mutex);
959 response = read_response (conn);
960 gst_rtsp_message_parse_response (response, &code, NULL, NULL);
961 fail_unless (code == GST_RTSP_STS_OK);
962 gst_rtsp_message_free (response);
965 gst_rtsp_connection_free (conn);
975 new_session_timeout_one (GstRTSPClient * client,
976 GstRTSPSession * session, gpointer user_data)
978 gst_rtsp_session_set_timeout (session, 1);
980 g_signal_handlers_disconnect_by_func (client, new_session_timeout_one,
985 session_connected_new_session_cb (GstRTSPServer * server,
986 GstRTSPClient * client, gpointer user_data)
989 g_signal_connect (client, "new-session", user_data, NULL);
992 GST_START_TEST (test_play_multithreaded_timeout_client)
994 GstRTSPConnection *conn;
995 GstSDPMessage *sdp_message = NULL;
996 const GstSDPMedia *sdp_media;
997 const gchar *video_control;
998 const gchar *audio_control;
999 GstRTSPRange client_port;
1000 gchar *session = NULL;
1001 GstRTSPTransport *video_transport = NULL;
1002 GstRTSPTransport *audio_transport = NULL;
1003 GstRTSPSessionPool *pool;
1004 GstRTSPMessage *request;
1005 GstRTSPMessage *response;
1007 gst_rtsp_server_set_max_threads (server, 2);
1008 pool = gst_rtsp_server_get_session_pool (server);
1009 g_signal_connect (server, "client-connected",
1010 G_CALLBACK (session_connected_new_session_cb), new_session_timeout_one);
1015 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
1017 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
1019 /* get control strings from DESCRIBE response */
1020 fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
1021 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
1022 video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1023 sdp_media = gst_sdp_message_get_media (sdp_message, 1);
1024 audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1026 get_client_ports (&client_port);
1028 /* do SETUP for video and audio */
1029 fail_unless (do_setup (conn, video_control, &client_port, &session,
1030 &video_transport) == GST_RTSP_STS_OK);
1031 fail_unless (do_setup (conn, audio_control, &client_port, &session,
1032 &audio_transport) == GST_RTSP_STS_OK);
1034 fail_unless (gst_rtsp_session_pool_get_n_sessions (pool) == 1);
1036 /* send PLAY request and check that we get 200 OK */
1037 fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
1038 session) == GST_RTSP_STS_OK);
1042 fail_unless (gst_rtsp_session_pool_cleanup (pool) == 1);
1045 /* send TEARDOWN request and check that we get 454 Session Not found */
1046 request = create_request (conn, GST_RTSP_TEARDOWN, NULL);
1047 gst_rtsp_message_add_header (request, GST_RTSP_HDR_SESSION, session);
1048 fail_unless (send_request (conn, request));
1049 gst_rtsp_message_free (request);
1051 fail_unless (gst_rtsp_message_new (&response) == GST_RTSP_OK);
1052 fail_unless (gst_rtsp_connection_receive (conn, response, NULL) ==
1054 fail_unless (errno == ECONNRESET);
1055 gst_rtsp_message_free (response);
1057 /* clean up and iterate so the clean-up can finish */
1058 g_object_unref (pool);
1060 gst_rtsp_transport_free (video_transport);
1061 gst_rtsp_transport_free (audio_transport);
1062 gst_sdp_message_free (sdp_message);
1063 gst_rtsp_connection_free (conn);
1072 GST_START_TEST (test_play_multithreaded_timeout_session)
1074 GstRTSPConnection *conn;
1075 GstSDPMessage *sdp_message = NULL;
1076 const GstSDPMedia *sdp_media;
1077 const gchar *video_control;
1078 const gchar *audio_control;
1079 GstRTSPRange client_port;
1080 gchar *session1 = NULL;
1081 gchar *session2 = NULL;
1082 GstRTSPTransport *video_transport = NULL;
1083 GstRTSPTransport *audio_transport = NULL;
1084 GstRTSPSessionPool *pool;
1086 gst_rtsp_server_set_max_threads (server, 2);
1087 pool = gst_rtsp_server_get_session_pool (server);
1088 g_signal_connect (server, "client-connected",
1089 G_CALLBACK (session_connected_new_session_cb), new_session_timeout_one);
1094 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
1096 gst_rtsp_connection_set_remember_session_id (conn, FALSE);
1098 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
1100 /* get control strings from DESCRIBE response */
1101 fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
1102 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
1103 video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1104 sdp_media = gst_sdp_message_get_media (sdp_message, 1);
1105 audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1107 get_client_ports (&client_port);
1109 /* do SETUP for video and audio */
1110 fail_unless (do_setup (conn, video_control, &client_port, &session1,
1111 &video_transport) == GST_RTSP_STS_OK);
1112 fail_unless (do_setup (conn, audio_control, &client_port, &session2,
1113 &audio_transport) == GST_RTSP_STS_OK);
1115 fail_unless (gst_rtsp_session_pool_get_n_sessions (pool) == 2);
1117 /* send PLAY request and check that we get 200 OK */
1118 fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
1119 session1) == GST_RTSP_STS_OK);
1120 fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
1121 session2) == GST_RTSP_STS_OK);
1125 fail_unless (gst_rtsp_session_pool_cleanup (pool) == 1);
1127 /* send TEARDOWN request and check that we get 454 Session Not found */
1128 fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
1129 session1) == GST_RTSP_STS_SESSION_NOT_FOUND);
1131 fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
1132 session2) == GST_RTSP_STS_OK);
1134 /* clean up and iterate so the clean-up can finish */
1135 g_object_unref (pool);
1138 gst_rtsp_transport_free (video_transport);
1139 gst_rtsp_transport_free (audio_transport);
1140 gst_sdp_message_free (sdp_message);
1141 gst_rtsp_connection_free (conn);
1150 GST_START_TEST (test_play_disconnect)
1152 GstRTSPConnection *conn;
1153 GstSDPMessage *sdp_message = NULL;
1154 const GstSDPMedia *sdp_media;
1155 const gchar *video_control;
1156 const gchar *audio_control;
1157 GstRTSPRange client_port;
1158 gchar *session = NULL;
1159 GstRTSPTransport *video_transport = NULL;
1160 GstRTSPTransport *audio_transport = NULL;
1161 GstRTSPSessionPool *pool;
1163 pool = gst_rtsp_server_get_session_pool (server);
1164 g_signal_connect (server, "client-connected",
1165 G_CALLBACK (session_connected_new_session_cb), new_session_timeout_one);
1169 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
1171 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
1173 /* get control strings from DESCRIBE response */
1174 fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
1175 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
1176 video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1177 sdp_media = gst_sdp_message_get_media (sdp_message, 1);
1178 audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1180 get_client_ports (&client_port);
1182 /* do SETUP for video and audio */
1183 fail_unless (do_setup (conn, video_control, &client_port, &session,
1184 &video_transport) == GST_RTSP_STS_OK);
1185 fail_unless (do_setup (conn, audio_control, &client_port, &session,
1186 &audio_transport) == GST_RTSP_STS_OK);
1188 fail_unless (gst_rtsp_session_pool_get_n_sessions (pool) == 1);
1190 /* send PLAY request and check that we get 200 OK */
1191 fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
1192 session) == GST_RTSP_STS_OK);
1194 gst_rtsp_connection_free (conn);
1198 fail_unless (gst_rtsp_session_pool_get_n_sessions (pool) == 1);
1199 fail_unless (gst_rtsp_session_pool_cleanup (pool) == 1);
1202 /* clean up and iterate so the clean-up can finish */
1203 g_object_unref (pool);
1205 gst_rtsp_transport_free (video_transport);
1206 gst_rtsp_transport_free (audio_transport);
1207 gst_sdp_message_free (sdp_message);
1215 /* Only different with test_play is the specific ports selected */
1217 GST_START_TEST (test_play_specific_server_port)
1219 GstRTSPMountPoints *mounts;
1221 GstRTSPMediaFactory *factory;
1222 GstRTSPAddressPool *pool;
1223 GstRTSPConnection *conn;
1224 GstSDPMessage *sdp_message = NULL;
1225 const GstSDPMedia *sdp_media;
1226 const gchar *video_control;
1227 GstRTSPRange client_port;
1228 gchar *session = NULL;
1229 GstRTSPTransport *video_transport = NULL;
1230 GSocket *rtp_socket, *rtcp_socket;
1231 GSocketAddress *rtp_address, *rtcp_address;
1232 guint16 rtp_port, rtcp_port;
1234 mounts = gst_rtsp_server_get_mount_points (server);
1236 factory = gst_rtsp_media_factory_new ();
1237 pool = gst_rtsp_address_pool_new ();
1238 gst_rtsp_address_pool_add_range_unicast (pool, GST_RTSP_ADDRESS_POOL_ANY_IPV4,
1239 GST_RTSP_ADDRESS_POOL_ANY_IPV4, 7770, 7780);
1240 gst_rtsp_media_factory_set_address_pool (factory, pool);
1241 g_object_unref (pool);
1242 gst_rtsp_media_factory_set_launch (factory, "( " VIDEO_PIPELINE " )");
1243 gst_rtsp_mount_points_add_factory (mounts, TEST_MOUNT_POINT, factory);
1244 g_object_unref (mounts);
1247 test_port = get_unused_port (SOCK_STREAM);
1248 service = g_strdup_printf ("%d", test_port);
1249 gst_rtsp_server_set_service (server, service);
1252 /* attach to default main context */
1253 source_id = gst_rtsp_server_attach (server, NULL);
1254 fail_if (source_id == 0);
1256 GST_DEBUG ("rtsp server listening on port %d", test_port);
1259 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
1261 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
1263 /* get control strings from DESCRIBE response */
1264 fail_unless (gst_sdp_message_medias_len (sdp_message) == 1);
1265 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
1266 video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1268 get_client_ports_full (&client_port, &rtp_socket, &rtcp_socket);
1270 /* do SETUP for video */
1271 fail_unless (do_setup (conn, video_control, &client_port, &session,
1272 &video_transport) == GST_RTSP_STS_OK);
1274 /* send PLAY request and check that we get 200 OK */
1275 fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
1276 session) == GST_RTSP_STS_OK);
1278 receive_rtp (rtp_socket, &rtp_address);
1279 receive_rtcp (rtcp_socket, &rtcp_address, 0);
1281 fail_unless (G_IS_INET_SOCKET_ADDRESS (rtp_address));
1282 fail_unless (G_IS_INET_SOCKET_ADDRESS (rtcp_address));
1284 g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (rtp_address));
1286 g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (rtcp_address));
1287 fail_unless (rtp_port >= 7770 && rtp_port <= 7780 && rtp_port % 2 == 0);
1288 fail_unless (rtcp_port >= 7770 && rtcp_port <= 7780 && rtcp_port % 2 == 1);
1289 fail_unless (rtp_port + 1 == rtcp_port);
1291 g_object_unref (rtp_address);
1292 g_object_unref (rtcp_address);
1294 /* send TEARDOWN request and check that we get 200 OK */
1295 fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
1296 session) == GST_RTSP_STS_OK);
1298 /* FIXME: The rtsp-server always disconnects the transport before
1299 * sending the RTCP BYE
1300 * receive_rtcp (rtcp_socket, NULL, GST_RTCP_TYPE_BYE);
1303 /* clean up and iterate so the clean-up can finish */
1304 g_object_unref (rtp_socket);
1305 g_object_unref (rtcp_socket);
1307 gst_rtsp_transport_free (video_transport);
1308 gst_sdp_message_free (sdp_message);
1309 gst_rtsp_connection_free (conn);
1319 rtspserver_suite (void)
1321 Suite *s = suite_create ("rtspserver");
1322 TCase *tc = tcase_create ("general");
1324 suite_add_tcase (s, tc);
1325 tcase_add_checked_fixture (tc, setup, teardown);
1326 tcase_set_timeout (tc, 20);
1327 tcase_add_test (tc, test_connect);
1328 tcase_add_test (tc, test_describe);
1329 tcase_add_test (tc, test_describe_non_existing_mount_point);
1330 tcase_add_test (tc, test_setup);
1331 tcase_add_test (tc, test_setup_non_existing_stream);
1332 tcase_add_test (tc, test_play);
1333 tcase_add_test (tc, test_play_without_session);
1334 tcase_add_test (tc, test_bind_already_in_use);
1335 tcase_add_test (tc, test_play_multithreaded);
1336 tcase_add_test (tc, test_play_multithreaded_block_in_describe);
1337 tcase_add_test (tc, test_play_multithreaded_timeout_client);
1338 tcase_add_test (tc, test_play_multithreaded_timeout_session);
1339 tcase_add_test (tc, test_play_disconnect);
1340 tcase_add_test (tc, test_play_specific_server_port);
1344 GST_CHECK_MAIN (rtspserver);