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 const gchar * range_in,
304 gchar ** content_type, gchar ** content_base, gchar ** body,
305 gchar ** session_out, gchar ** transport_out, gchar ** range_out)
307 GstRTSPMessage *request;
308 GstRTSPMessage *response;
309 GstRTSPStatusCode code;
313 request = create_request (conn, method, control);
317 gst_rtsp_message_add_header (request, GST_RTSP_HDR_SESSION, session_in);
320 gst_rtsp_message_add_header (request, GST_RTSP_HDR_TRANSPORT, transport_in);
323 gst_rtsp_message_add_header (request, GST_RTSP_HDR_RANGE, range_in);
327 fail_unless (send_request (conn, request));
328 gst_rtsp_message_free (request);
333 response = read_response (conn);
335 /* check status line */
336 gst_rtsp_message_parse_response (response, &code, NULL, NULL);
337 if (code != GST_RTSP_STS_OK) {
338 gst_rtsp_message_free (response);
342 /* get information from response */
344 gst_rtsp_message_get_header (response, GST_RTSP_HDR_CONTENT_TYPE,
346 *content_type = g_strdup (value);
349 gst_rtsp_message_get_header (response, GST_RTSP_HDR_CONTENT_BASE,
351 *content_base = g_strdup (value);
354 *body = g_malloc (response->body_size + 1);
355 strncpy (*body, (gchar *) response->body, response->body_size);
358 gst_rtsp_message_get_header (response, GST_RTSP_HDR_SESSION, &value, 0);
360 value = g_strdup (value);
362 /* Remove the timeout */
364 char *pos = strchr (value, ';');
369 /* check that we got the same session back */
370 fail_unless (!g_strcmp0 (value, session_in));
372 *session_out = value;
375 gst_rtsp_message_get_header (response, GST_RTSP_HDR_TRANSPORT, &value, 0);
376 *transport_out = g_strdup (value);
379 gst_rtsp_message_get_header (response, GST_RTSP_HDR_RANGE, &value, 0);
380 *range_out = g_strdup (value);
383 gst_rtsp_message_free (response);
387 /* send an rtsp request with a method and a session, and receive response */
388 static GstRTSPStatusCode
389 do_simple_request (GstRTSPConnection * conn, GstRTSPMethod method,
390 const gchar * session)
392 return do_request (conn, method, NULL, session, NULL, NULL, NULL,
393 NULL, NULL, NULL, NULL, NULL);
396 /* send a DESCRIBE request and receive response. returns a received
397 * GstSDPMessage that must be freed by the caller */
398 static GstSDPMessage *
399 do_describe (GstRTSPConnection * conn, const gchar * mount_point)
401 GstSDPMessage *sdp_message;
406 gchar *expected_content_base;
408 /* send DESCRIBE request */
409 fail_unless (do_request (conn, GST_RTSP_DESCRIBE, NULL, NULL, NULL, NULL,
410 &content_type, &content_base, &body, NULL, NULL, NULL) ==
413 /* check response values */
414 fail_unless (!g_strcmp0 (content_type, "application/sdp"));
415 address = gst_rtsp_server_get_address (server);
416 expected_content_base =
417 g_strdup_printf ("rtsp://%s:%d%s/", address, test_port, mount_point);
418 fail_unless (!g_strcmp0 (content_base, expected_content_base));
420 /* create sdp message */
421 fail_unless (gst_sdp_message_new (&sdp_message) == GST_SDP_OK);
422 fail_unless (gst_sdp_message_parse_buffer ((guint8 *) body,
423 strlen (body), sdp_message) == GST_SDP_OK);
426 g_free (content_type);
427 g_free (content_base);
430 g_free (expected_content_base);
435 /* send a SETUP request and receive response. if *session is not NULL,
436 * it is used in the request. otherwise, *session is set to a returned
437 * session string that must be freed by the caller. the returned
438 * transport must be freed by the caller. */
439 static GstRTSPStatusCode
440 do_setup (GstRTSPConnection * conn, const gchar * control,
441 const GstRTSPRange * client_ports, gchar ** session,
442 GstRTSPTransport ** transport)
444 GstRTSPStatusCode code;
445 gchar *session_in = NULL;
446 gchar *transport_string_in = NULL;
447 gchar **session_out = NULL;
448 gchar *transport_string_out = NULL;
450 /* prepare and send SETUP request */
453 session_in = *session;
455 session_out = session;
458 transport_string_in =
459 g_strdup_printf (TEST_PROTO ";unicast;client_port=%d-%d",
460 client_ports->min, client_ports->max);
462 do_request (conn, GST_RTSP_SETUP, control, session_in,
463 transport_string_in, NULL, NULL, NULL, NULL, session_out,
464 &transport_string_out, NULL);
465 g_free (transport_string_in);
467 if (transport_string_out) {
468 /* create transport */
469 fail_unless (gst_rtsp_transport_new (transport) == GST_RTSP_OK);
470 fail_unless (gst_rtsp_transport_parse (transport_string_out,
471 *transport) == GST_RTSP_OK);
472 g_free (transport_string_out);
478 /* fixture setup function */
482 server = gst_rtsp_server_new ();
485 /* fixture clean-up function */
490 g_object_unref (server);
496 GST_START_TEST (test_connect)
498 GstRTSPConnection *conn;
502 /* connect to server */
503 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
506 gst_rtsp_connection_free (conn);
509 /* iterate so the clean-up can finish */
515 GST_START_TEST (test_describe)
517 GstRTSPConnection *conn;
518 GstSDPMessage *sdp_message = NULL;
519 const GstSDPMedia *sdp_media;
521 gchar *expected_rtpmap;
523 const gchar *control_video;
524 const gchar *control_audio;
528 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
530 /* send DESCRIBE request */
531 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
533 fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
535 /* check video sdp */
536 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
537 fail_unless (!g_strcmp0 (gst_sdp_media_get_proto (sdp_media), TEST_PROTO));
538 fail_unless (gst_sdp_media_formats_len (sdp_media) == 1);
539 sscanf (gst_sdp_media_get_format (sdp_media, 0), "%" G_GINT32_FORMAT,
542 g_strdup_printf ("%d " TEST_ENCODING "/" TEST_CLOCK_RATE, format);
543 rtpmap = gst_sdp_media_get_attribute_val (sdp_media, "rtpmap");
544 fail_unless (!g_strcmp0 (rtpmap, expected_rtpmap));
545 g_free (expected_rtpmap);
546 control_video = gst_sdp_media_get_attribute_val (sdp_media, "control");
547 fail_unless (!g_strcmp0 (control_video, "stream=0"));
549 /* check audio sdp */
550 sdp_media = gst_sdp_message_get_media (sdp_message, 1);
551 fail_unless (!g_strcmp0 (gst_sdp_media_get_proto (sdp_media), TEST_PROTO));
552 fail_unless (gst_sdp_media_formats_len (sdp_media) == 1);
553 sscanf (gst_sdp_media_get_format (sdp_media, 0), "%" G_GINT32_FORMAT,
556 g_strdup_printf ("%d " TEST_ENCODING "/" TEST_CLOCK_RATE, format);
557 rtpmap = gst_sdp_media_get_attribute_val (sdp_media, "rtpmap");
558 fail_unless (!g_strcmp0 (rtpmap, expected_rtpmap));
559 g_free (expected_rtpmap);
560 control_audio = gst_sdp_media_get_attribute_val (sdp_media, "control");
561 fail_unless (!g_strcmp0 (control_audio, "stream=1"));
563 /* clean up and iterate so the clean-up can finish */
564 gst_sdp_message_free (sdp_message);
565 gst_rtsp_connection_free (conn);
572 GST_START_TEST (test_describe_non_existing_mount_point)
574 GstRTSPConnection *conn;
578 /* send DESCRIBE request for a non-existing mount point
579 * and check that we get a 404 Not Found */
580 conn = connect_to_server (test_port, "/non-existing");
581 fail_unless (do_simple_request (conn, GST_RTSP_DESCRIBE, NULL)
582 == GST_RTSP_STS_NOT_FOUND);
584 /* clean up and iterate so the clean-up can finish */
585 gst_rtsp_connection_free (conn);
592 GST_START_TEST (test_setup)
594 GstRTSPConnection *conn;
595 GstSDPMessage *sdp_message = NULL;
596 const GstSDPMedia *sdp_media;
597 const gchar *video_control;
598 const gchar *audio_control;
599 GstRTSPRange client_ports;
600 gchar *session = NULL;
601 GstRTSPTransport *video_transport = NULL;
602 GstRTSPTransport *audio_transport = NULL;
606 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
608 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
610 /* get control strings from DESCRIBE response */
611 fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
612 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
613 video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
614 sdp_media = gst_sdp_message_get_media (sdp_message, 1);
615 audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
617 get_client_ports (&client_ports);
619 /* send SETUP request for video */
620 fail_unless (do_setup (conn, video_control, &client_ports, &session,
621 &video_transport) == GST_RTSP_STS_OK);
622 GST_DEBUG ("set up video %s, got session '%s'", video_control, session);
624 /* check response from SETUP */
625 fail_unless (video_transport->trans == GST_RTSP_TRANS_RTP);
626 fail_unless (video_transport->profile == GST_RTSP_PROFILE_AVP);
627 fail_unless (video_transport->lower_transport == GST_RTSP_LOWER_TRANS_UDP);
628 fail_unless (video_transport->mode_play);
629 gst_rtsp_transport_free (video_transport);
631 /* send SETUP request for audio */
632 fail_unless (do_setup (conn, audio_control, &client_ports, &session,
633 &audio_transport) == GST_RTSP_STS_OK);
634 GST_DEBUG ("set up audio %s with session '%s'", audio_control, session);
636 /* check response from SETUP */
637 fail_unless (audio_transport->trans == GST_RTSP_TRANS_RTP);
638 fail_unless (audio_transport->profile == GST_RTSP_PROFILE_AVP);
639 fail_unless (audio_transport->lower_transport == GST_RTSP_LOWER_TRANS_UDP);
640 fail_unless (audio_transport->mode_play);
641 gst_rtsp_transport_free (audio_transport);
643 /* clean up and iterate so the clean-up can finish */
645 gst_sdp_message_free (sdp_message);
646 gst_rtsp_connection_free (conn);
653 GST_START_TEST (test_setup_non_existing_stream)
655 GstRTSPConnection *conn;
656 GstRTSPRange client_ports;
660 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
662 get_client_ports (&client_ports);
664 /* send SETUP request with a non-existing stream and check that we get a
666 fail_unless (do_setup (conn, "stream=7", &client_ports, NULL,
667 NULL) == GST_RTSP_STS_NOT_FOUND);
669 /* clean up and iterate so the clean-up can finish */
670 gst_rtsp_connection_free (conn);
678 receive_rtp (GSocket * socket, GSocketAddress ** addr)
680 GstBuffer *buffer = gst_buffer_new_allocate (NULL, 65536, NULL);
684 GstMapInfo map = GST_MAP_INFO_INIT;
685 GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;
687 gst_buffer_map (buffer, &map, GST_MAP_WRITE);
688 bytes = g_socket_receive_from (socket, addr, (gchar *) map.data,
689 map.maxsize, NULL, NULL);
690 fail_unless (bytes > 0);
691 gst_buffer_unmap (buffer, &map);
692 gst_buffer_set_size (buffer, bytes);
694 if (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtpbuffer)) {
695 gst_rtp_buffer_unmap (&rtpbuffer);
700 g_clear_object (addr);
703 gst_buffer_unref (buffer);
707 receive_rtcp (GSocket * socket, GSocketAddress ** addr, GstRTCPType type)
709 GstBuffer *buffer = gst_buffer_new_allocate (NULL, 65536, NULL);
713 GstMapInfo map = GST_MAP_INFO_INIT;
715 gst_buffer_map (buffer, &map, GST_MAP_WRITE);
716 bytes = g_socket_receive_from (socket, addr, (gchar *) map.data,
717 map.maxsize, NULL, NULL);
718 fail_unless (bytes > 0);
719 gst_buffer_unmap (buffer, &map);
720 gst_buffer_set_size (buffer, bytes);
722 if (gst_rtcp_buffer_validate (buffer)) {
723 GstRTCPBuffer rtcpbuffer = GST_RTCP_BUFFER_INIT;
724 GstRTCPPacket packet;
727 fail_unless (gst_rtcp_buffer_map (buffer, GST_MAP_READ, &rtcpbuffer));
728 fail_unless (gst_rtcp_buffer_get_first_packet (&rtcpbuffer, &packet));
730 if (gst_rtcp_packet_get_type (&packet) == type) {
731 gst_rtcp_buffer_unmap (&rtcpbuffer);
734 } while (gst_rtcp_packet_move_to_next (&packet));
735 gst_rtcp_buffer_unmap (&rtcpbuffer);
742 g_clear_object (addr);
747 gst_buffer_unref (buffer);
751 do_test_play (const gchar * range)
753 GstRTSPConnection *conn;
754 GstSDPMessage *sdp_message = NULL;
755 const GstSDPMedia *sdp_media;
756 const gchar *video_control;
757 const gchar *audio_control;
758 GstRTSPRange client_port;
759 gchar *session = NULL;
760 GstRTSPTransport *video_transport = NULL;
761 GstRTSPTransport *audio_transport = NULL;
762 GSocket *rtp_socket, *rtcp_socket;
763 gchar *range_out = NULL;
765 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
767 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
769 /* get control strings from DESCRIBE response */
770 fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
771 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
772 video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
773 sdp_media = gst_sdp_message_get_media (sdp_message, 1);
774 audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
776 get_client_ports_full (&client_port, &rtp_socket, &rtcp_socket);
778 /* do SETUP for video and audio */
779 fail_unless (do_setup (conn, video_control, &client_port, &session,
780 &video_transport) == GST_RTSP_STS_OK);
781 fail_unless (do_setup (conn, audio_control, &client_port, &session,
782 &audio_transport) == GST_RTSP_STS_OK);
784 /* send PLAY request and check that we get 200 OK */
785 fail_unless (do_request (conn, GST_RTSP_PLAY, NULL, session, NULL, range,
786 NULL, NULL, NULL, NULL, NULL, &range_out) == GST_RTSP_STS_OK);
788 fail_unless_equals_string (range, range_out);
791 receive_rtp (rtp_socket, NULL);
792 receive_rtcp (rtcp_socket, NULL, 0);
794 /* send TEARDOWN request and check that we get 200 OK */
795 fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
796 session) == GST_RTSP_STS_OK);
798 /* FIXME: The rtsp-server always disconnects the transport before
799 * sending the RTCP BYE
800 * receive_rtcp (rtcp_socket, NULL, GST_RTCP_TYPE_BYE);
803 /* clean up and iterate so the clean-up can finish */
804 g_object_unref (rtp_socket);
805 g_object_unref (rtcp_socket);
807 gst_rtsp_transport_free (video_transport);
808 gst_rtsp_transport_free (audio_transport);
809 gst_sdp_message_free (sdp_message);
810 gst_rtsp_connection_free (conn);
814 GST_START_TEST (test_play)
826 GST_START_TEST (test_play_without_session)
828 GstRTSPConnection *conn;
832 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
834 /* send PLAY request without a session and check that we get a
835 * 454 Session Not Found */
836 fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
837 NULL) == GST_RTSP_STS_SESSION_NOT_FOUND);
839 /* clean up and iterate so the clean-up can finish */
840 gst_rtsp_connection_free (conn);
847 GST_START_TEST (test_bind_already_in_use)
850 GSocketService *service;
851 GError *error = NULL;
855 serv = gst_rtsp_server_new ();
856 service = g_socket_service_new ();
858 /* bind service to port */
860 g_socket_listener_add_any_inet_port (G_SOCKET_LISTENER (service), NULL,
862 g_assert_no_error (error);
864 port_str = g_strdup_printf ("%d\n", port);
866 /* try to bind server to the same port */
867 g_object_set (serv, "service", port_str, NULL);
870 /* attach to default main context */
871 fail_unless (gst_rtsp_server_attach (serv, NULL) == 0);
874 g_object_unref (serv);
875 g_socket_service_stop (service);
876 g_object_unref (service);
882 GST_START_TEST (test_play_multithreaded)
884 GstRTSPThreadPool *pool;
886 pool = gst_rtsp_server_get_thread_pool (server);
887 gst_rtsp_thread_pool_set_max_threads (pool, 2);
888 g_object_unref (pool);
909 media_constructed_block (GstRTSPMediaFactory * factory,
910 GstRTSPMedia * media, gpointer user_data)
912 gint *block_state = user_data;
914 g_mutex_lock (&check_mutex);
916 *block_state = BLOCKED;
917 g_cond_broadcast (&check_cond);
919 while (*block_state != UNBLOCK)
920 g_cond_wait (&check_cond, &check_mutex);
921 g_mutex_unlock (&check_mutex);
925 GST_START_TEST (test_play_multithreaded_block_in_describe)
927 GstRTSPConnection *conn;
928 GstRTSPMountPoints *mounts;
929 GstRTSPMediaFactory *factory;
930 gint block_state = BLOCK_ME;
931 GstRTSPMessage *request;
932 GstRTSPMessage *response;
933 GstRTSPStatusCode code;
934 GstRTSPThreadPool *pool;
936 pool = gst_rtsp_server_get_thread_pool (server);
937 gst_rtsp_thread_pool_set_max_threads (pool, 2);
938 g_object_unref (pool);
940 mounts = gst_rtsp_server_get_mount_points (server);
941 fail_unless (mounts != NULL);
942 factory = gst_rtsp_media_factory_new ();
943 gst_rtsp_media_factory_set_launch (factory,
944 "( " VIDEO_PIPELINE " " AUDIO_PIPELINE " )");
945 g_signal_connect (factory, "media-constructed",
946 G_CALLBACK (media_constructed_block), &block_state);
947 gst_rtsp_mount_points_add_factory (mounts, TEST_MOUNT_POINT "2", factory);
948 g_object_unref (mounts);
952 conn = connect_to_server (test_port, TEST_MOUNT_POINT "2");
955 /* do describe, it will not return now as we've blocked it */
956 request = create_request (conn, GST_RTSP_DESCRIBE, NULL);
957 fail_unless (send_request (conn, request));
958 gst_rtsp_message_free (request);
960 g_mutex_lock (&check_mutex);
961 while (block_state != BLOCKED)
962 g_cond_wait (&check_cond, &check_mutex);
963 g_mutex_unlock (&check_mutex);
965 /* Do a second connection while the first one is blocked */
968 /* Now unblock the describe */
969 g_mutex_lock (&check_mutex);
970 block_state = UNBLOCK;
971 g_cond_broadcast (&check_cond);
972 g_mutex_unlock (&check_mutex);
974 response = read_response (conn);
975 gst_rtsp_message_parse_response (response, &code, NULL, NULL);
976 fail_unless (code == GST_RTSP_STS_OK);
977 gst_rtsp_message_free (response);
980 gst_rtsp_connection_free (conn);
990 new_session_timeout_one (GstRTSPClient * client,
991 GstRTSPSession * session, gpointer user_data)
993 gst_rtsp_session_set_timeout (session, 1);
995 g_signal_handlers_disconnect_by_func (client, new_session_timeout_one,
1000 session_connected_new_session_cb (GstRTSPServer * server,
1001 GstRTSPClient * client, gpointer user_data)
1004 g_signal_connect (client, "new-session", user_data, NULL);
1007 GST_START_TEST (test_play_multithreaded_timeout_client)
1009 GstRTSPConnection *conn;
1010 GstSDPMessage *sdp_message = NULL;
1011 const GstSDPMedia *sdp_media;
1012 const gchar *video_control;
1013 const gchar *audio_control;
1014 GstRTSPRange client_port;
1015 gchar *session = NULL;
1016 GstRTSPTransport *video_transport = NULL;
1017 GstRTSPTransport *audio_transport = NULL;
1018 GstRTSPSessionPool *pool;
1019 GstRTSPMessage *request;
1020 GstRTSPMessage *response;
1021 GstRTSPStatusCode code;
1022 GstRTSPThreadPool *thread_pool;
1024 thread_pool = gst_rtsp_server_get_thread_pool (server);
1025 gst_rtsp_thread_pool_set_max_threads (thread_pool, 2);
1026 g_object_unref (thread_pool);
1028 pool = gst_rtsp_server_get_session_pool (server);
1029 g_signal_connect (server, "client-connected",
1030 G_CALLBACK (session_connected_new_session_cb), new_session_timeout_one);
1035 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
1037 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
1039 /* get control strings from DESCRIBE response */
1040 fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
1041 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
1042 video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1043 sdp_media = gst_sdp_message_get_media (sdp_message, 1);
1044 audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1046 get_client_ports (&client_port);
1048 /* do SETUP for video and audio */
1049 fail_unless (do_setup (conn, video_control, &client_port, &session,
1050 &video_transport) == GST_RTSP_STS_OK);
1051 fail_unless (do_setup (conn, audio_control, &client_port, &session,
1052 &audio_transport) == GST_RTSP_STS_OK);
1054 fail_unless (gst_rtsp_session_pool_get_n_sessions (pool) == 1);
1056 /* send PLAY request and check that we get 200 OK */
1057 fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
1058 session) == GST_RTSP_STS_OK);
1062 fail_unless (gst_rtsp_session_pool_cleanup (pool) == 1);
1065 /* send TEARDOWN request and check that we get 454 Session Not found */
1066 request = create_request (conn, GST_RTSP_TEARDOWN, NULL);
1067 gst_rtsp_message_add_header (request, GST_RTSP_HDR_SESSION, session);
1068 fail_unless (send_request (conn, request));
1069 gst_rtsp_message_free (request);
1071 fail_unless (gst_rtsp_message_new (&response) == GST_RTSP_OK);
1072 fail_unless (gst_rtsp_connection_receive (conn, response, NULL) ==
1074 gst_rtsp_message_parse_response (response, &code, NULL, NULL);
1075 fail_unless (code == GST_RTSP_STS_SESSION_NOT_FOUND);
1076 gst_rtsp_message_free (response);
1079 fail_unless (gst_rtsp_message_new (&response) == GST_RTSP_OK);
1080 fail_unless (gst_rtsp_connection_receive (conn, response, NULL) ==
1082 fail_unless (errno == ECONNRESET);
1083 gst_rtsp_message_free (response);
1086 /* clean up and iterate so the clean-up can finish */
1087 g_object_unref (pool);
1089 gst_rtsp_transport_free (video_transport);
1090 gst_rtsp_transport_free (audio_transport);
1091 gst_sdp_message_free (sdp_message);
1092 gst_rtsp_connection_free (conn);
1101 GST_START_TEST (test_play_multithreaded_timeout_session)
1103 GstRTSPConnection *conn;
1104 GstSDPMessage *sdp_message = NULL;
1105 const GstSDPMedia *sdp_media;
1106 const gchar *video_control;
1107 const gchar *audio_control;
1108 GstRTSPRange client_port;
1109 gchar *session1 = NULL;
1110 gchar *session2 = NULL;
1111 GstRTSPTransport *video_transport = NULL;
1112 GstRTSPTransport *audio_transport = NULL;
1113 GstRTSPSessionPool *pool;
1114 GstRTSPThreadPool *thread_pool;
1116 thread_pool = gst_rtsp_server_get_thread_pool (server);
1117 gst_rtsp_thread_pool_set_max_threads (thread_pool, 2);
1118 g_object_unref (thread_pool);
1120 pool = gst_rtsp_server_get_session_pool (server);
1121 g_signal_connect (server, "client-connected",
1122 G_CALLBACK (session_connected_new_session_cb), new_session_timeout_one);
1127 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
1129 gst_rtsp_connection_set_remember_session_id (conn, FALSE);
1131 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
1133 /* get control strings from DESCRIBE response */
1134 fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
1135 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
1136 video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1137 sdp_media = gst_sdp_message_get_media (sdp_message, 1);
1138 audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1140 get_client_ports (&client_port);
1142 /* do SETUP for video and audio */
1143 fail_unless (do_setup (conn, video_control, &client_port, &session1,
1144 &video_transport) == GST_RTSP_STS_OK);
1145 fail_unless (do_setup (conn, audio_control, &client_port, &session2,
1146 &audio_transport) == GST_RTSP_STS_OK);
1148 fail_unless (gst_rtsp_session_pool_get_n_sessions (pool) == 2);
1150 /* send PLAY request and check that we get 200 OK */
1151 fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
1152 session1) == GST_RTSP_STS_OK);
1153 fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
1154 session2) == GST_RTSP_STS_OK);
1158 fail_unless (gst_rtsp_session_pool_cleanup (pool) == 1);
1160 /* send TEARDOWN request and check that we get 454 Session Not found */
1161 fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
1162 session1) == GST_RTSP_STS_SESSION_NOT_FOUND);
1164 fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
1165 session2) == GST_RTSP_STS_OK);
1167 /* clean up and iterate so the clean-up can finish */
1168 g_object_unref (pool);
1171 gst_rtsp_transport_free (video_transport);
1172 gst_rtsp_transport_free (audio_transport);
1173 gst_sdp_message_free (sdp_message);
1174 gst_rtsp_connection_free (conn);
1183 GST_START_TEST (test_play_disconnect)
1185 GstRTSPConnection *conn;
1186 GstSDPMessage *sdp_message = NULL;
1187 const GstSDPMedia *sdp_media;
1188 const gchar *video_control;
1189 const gchar *audio_control;
1190 GstRTSPRange client_port;
1191 gchar *session = NULL;
1192 GstRTSPTransport *video_transport = NULL;
1193 GstRTSPTransport *audio_transport = NULL;
1194 GstRTSPSessionPool *pool;
1196 pool = gst_rtsp_server_get_session_pool (server);
1197 g_signal_connect (server, "client-connected",
1198 G_CALLBACK (session_connected_new_session_cb), new_session_timeout_one);
1202 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
1204 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
1206 /* get control strings from DESCRIBE response */
1207 fail_unless (gst_sdp_message_medias_len (sdp_message) == 2);
1208 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
1209 video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1210 sdp_media = gst_sdp_message_get_media (sdp_message, 1);
1211 audio_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1213 get_client_ports (&client_port);
1215 /* do SETUP for video and audio */
1216 fail_unless (do_setup (conn, video_control, &client_port, &session,
1217 &video_transport) == GST_RTSP_STS_OK);
1218 fail_unless (do_setup (conn, audio_control, &client_port, &session,
1219 &audio_transport) == GST_RTSP_STS_OK);
1221 fail_unless (gst_rtsp_session_pool_get_n_sessions (pool) == 1);
1223 /* send PLAY request and check that we get 200 OK */
1224 fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
1225 session) == GST_RTSP_STS_OK);
1227 gst_rtsp_connection_free (conn);
1231 fail_unless (gst_rtsp_session_pool_get_n_sessions (pool) == 1);
1232 fail_unless (gst_rtsp_session_pool_cleanup (pool) == 1);
1235 /* clean up and iterate so the clean-up can finish */
1236 g_object_unref (pool);
1238 gst_rtsp_transport_free (video_transport);
1239 gst_rtsp_transport_free (audio_transport);
1240 gst_sdp_message_free (sdp_message);
1248 /* Only different with test_play is the specific ports selected */
1250 GST_START_TEST (test_play_specific_server_port)
1252 GstRTSPMountPoints *mounts;
1254 GstRTSPMediaFactory *factory;
1255 GstRTSPAddressPool *pool;
1256 GstRTSPConnection *conn;
1257 GstSDPMessage *sdp_message = NULL;
1258 const GstSDPMedia *sdp_media;
1259 const gchar *video_control;
1260 GstRTSPRange client_port;
1261 gchar *session = NULL;
1262 GstRTSPTransport *video_transport = NULL;
1263 GSocket *rtp_socket, *rtcp_socket;
1264 GSocketAddress *rtp_address, *rtcp_address;
1265 guint16 rtp_port, rtcp_port;
1267 mounts = gst_rtsp_server_get_mount_points (server);
1269 factory = gst_rtsp_media_factory_new ();
1270 pool = gst_rtsp_address_pool_new ();
1271 gst_rtsp_address_pool_add_range_unicast (pool, GST_RTSP_ADDRESS_POOL_ANY_IPV4,
1272 GST_RTSP_ADDRESS_POOL_ANY_IPV4, 7770, 7780);
1273 gst_rtsp_media_factory_set_address_pool (factory, pool);
1274 g_object_unref (pool);
1275 gst_rtsp_media_factory_set_launch (factory, "( " VIDEO_PIPELINE " )");
1276 gst_rtsp_mount_points_add_factory (mounts, TEST_MOUNT_POINT, factory);
1277 g_object_unref (mounts);
1280 test_port = get_unused_port (SOCK_STREAM);
1281 service = g_strdup_printf ("%d", test_port);
1282 gst_rtsp_server_set_service (server, service);
1285 /* attach to default main context */
1286 source_id = gst_rtsp_server_attach (server, NULL);
1287 fail_if (source_id == 0);
1289 GST_DEBUG ("rtsp server listening on port %d", test_port);
1292 conn = connect_to_server (test_port, TEST_MOUNT_POINT);
1294 sdp_message = do_describe (conn, TEST_MOUNT_POINT);
1296 /* get control strings from DESCRIBE response */
1297 fail_unless (gst_sdp_message_medias_len (sdp_message) == 1);
1298 sdp_media = gst_sdp_message_get_media (sdp_message, 0);
1299 video_control = gst_sdp_media_get_attribute_val (sdp_media, "control");
1301 get_client_ports_full (&client_port, &rtp_socket, &rtcp_socket);
1303 /* do SETUP for video */
1304 fail_unless (do_setup (conn, video_control, &client_port, &session,
1305 &video_transport) == GST_RTSP_STS_OK);
1307 /* send PLAY request and check that we get 200 OK */
1308 fail_unless (do_simple_request (conn, GST_RTSP_PLAY,
1309 session) == GST_RTSP_STS_OK);
1311 receive_rtp (rtp_socket, &rtp_address);
1312 receive_rtcp (rtcp_socket, &rtcp_address, 0);
1314 fail_unless (G_IS_INET_SOCKET_ADDRESS (rtp_address));
1315 fail_unless (G_IS_INET_SOCKET_ADDRESS (rtcp_address));
1317 g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (rtp_address));
1319 g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (rtcp_address));
1320 fail_unless (rtp_port >= 7770 && rtp_port <= 7780 && rtp_port % 2 == 0);
1321 fail_unless (rtcp_port >= 7770 && rtcp_port <= 7780 && rtcp_port % 2 == 1);
1322 fail_unless (rtp_port + 1 == rtcp_port);
1324 g_object_unref (rtp_address);
1325 g_object_unref (rtcp_address);
1327 /* send TEARDOWN request and check that we get 200 OK */
1328 fail_unless (do_simple_request (conn, GST_RTSP_TEARDOWN,
1329 session) == GST_RTSP_STS_OK);
1331 /* FIXME: The rtsp-server always disconnects the transport before
1332 * sending the RTCP BYE
1333 * receive_rtcp (rtcp_socket, NULL, GST_RTCP_TYPE_BYE);
1336 /* clean up and iterate so the clean-up can finish */
1337 g_object_unref (rtp_socket);
1338 g_object_unref (rtcp_socket);
1340 gst_rtsp_transport_free (video_transport);
1341 gst_sdp_message_free (sdp_message);
1342 gst_rtsp_connection_free (conn);
1352 GST_START_TEST (test_play_smpte_range)
1356 do_test_play ("npt=5-");
1357 do_test_play ("smpte=0:00:00-");
1358 do_test_play ("smpte=1:00:00-");
1359 do_test_play ("smpte=1:00:03-");
1360 do_test_play ("clock=20120321T152256Z-");
1370 rtspserver_suite (void)
1372 Suite *s = suite_create ("rtspserver");
1373 TCase *tc = tcase_create ("general");
1375 suite_add_tcase (s, tc);
1376 tcase_add_checked_fixture (tc, setup, teardown);
1377 tcase_set_timeout (tc, 20);
1378 tcase_add_test (tc, test_connect);
1379 tcase_add_test (tc, test_describe);
1380 tcase_add_test (tc, test_describe_non_existing_mount_point);
1381 tcase_add_test (tc, test_setup);
1382 tcase_add_test (tc, test_setup_non_existing_stream);
1383 tcase_add_test (tc, test_play);
1384 tcase_add_test (tc, test_play_without_session);
1385 tcase_add_test (tc, test_bind_already_in_use);
1386 tcase_add_test (tc, test_play_multithreaded);
1387 tcase_add_test (tc, test_play_multithreaded_block_in_describe);
1388 tcase_add_test (tc, test_play_multithreaded_timeout_client);
1389 tcase_add_test (tc, test_play_multithreaded_timeout_session);
1390 tcase_add_test (tc, test_play_disconnect);
1391 tcase_add_test (tc, test_play_specific_server_port);
1392 tcase_add_test (tc, test_play_smpte_range);
1396 GST_CHECK_MAIN (rtspserver);