1 /* GStreamer unit test for rtspclientsink
2 * Copyright (C) 2012 Axis Communications <dev-gstreamer at axis dot com>
3 * @author David Svensson Fors <davidsf at axis dot com>
4 * Copyright (C) 2015 Centricular Ltd
5 * @author Tim-Philipp Müller <tim@centricular.com>
6 * @author Jan Schmidt <jan@centricular.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 TEST_MOUNT_POINT "/test"
36 /* tested rtsp server */
37 static GstRTSPServer *server = NULL;
39 /* tcp port that the test server listens for rtsp requests on */
40 static gint test_port = 0;
41 static gint server_send_rtcp_port;
43 /* id of the server's source within the GMainContext */
44 static guint source_id;
46 /* iterate the default main context until there are no events to dispatch */
50 while (g_main_context_iteration (NULL, FALSE)) {
51 GST_DEBUG ("iteration");
55 /* start the testing rtsp server for RECORD mode */
56 static GstRTSPMediaFactory *
57 start_record_server (const gchar * launch_line)
59 GstRTSPMediaFactory *factory;
60 GstRTSPMountPoints *mounts;
63 mounts = gst_rtsp_server_get_mount_points (server);
65 factory = gst_rtsp_media_factory_new ();
67 gst_rtsp_media_factory_set_transport_mode (factory,
68 GST_RTSP_TRANSPORT_MODE_RECORD);
69 gst_rtsp_media_factory_set_launch (factory, launch_line);
70 gst_rtsp_mount_points_add_factory (mounts, TEST_MOUNT_POINT, factory);
71 g_object_unref (mounts);
74 gst_rtsp_server_set_service (server, "0");
76 /* attach to default main context */
77 source_id = gst_rtsp_server_attach (server, NULL);
78 fail_if (source_id == 0);
81 service = gst_rtsp_server_get_service (server);
82 test_port = atoi (service);
83 fail_unless (test_port != 0);
86 GST_DEBUG ("rtsp server listening on port %d", test_port);
90 /* stop the tested rtsp server */
94 g_source_remove (source_id);
97 GST_DEBUG ("rtsp server stopped");
100 /* fixture setup function */
104 server = gst_rtsp_server_new ();
107 /* fixture clean-up function */
112 g_object_unref (server);
118 /* create an rtsp connection to the server on test_port */
120 get_server_uri (gint port, const gchar * mount_point)
124 GstRTSPUrl *url = NULL;
126 address = gst_rtsp_server_get_address (server);
127 uri_string = g_strdup_printf ("rtsp://%s:%d%s", address, port, mount_point);
130 fail_unless (gst_rtsp_url_parse (uri_string, &url) == GST_RTSP_OK);
131 gst_rtsp_url_free (url);
136 static GstRTSPFilterResult
137 check_transport (GstRTSPStream * stream, GstRTSPStreamTransport * strans,
140 const GstRTSPTransport *trans =
141 gst_rtsp_stream_transport_get_transport (strans);
143 server_send_rtcp_port = trans->client_port.max;
145 return GST_RTSP_FILTER_KEEP;
149 new_state_cb (GstRTSPMedia * media, gint state, gpointer user_data)
151 if (state == GST_STATE_PLAYING) {
152 GstRTSPStream *stream = gst_rtsp_media_get_stream (media, 0);
154 gst_rtsp_stream_transport_filter (stream,
155 (GstRTSPStreamTransportFilterFunc) check_transport, user_data);
160 media_constructed_cb (GstRTSPMediaFactory * mfactory, GstRTSPMedia * media,
163 GstElement **p_sink = user_data;
166 g_signal_connect (media, "new-state", G_CALLBACK (new_state_cb), user_data);
168 bin = gst_rtsp_media_get_element (media);
169 *p_sink = gst_bin_get_by_name (GST_BIN (bin), "sink");
170 GST_INFO ("media constructed!: %" GST_PTR_FORMAT, *p_sink);
171 gst_object_unref (bin);
174 #define AUDIO_PIPELINE "audiotestsrc num-buffers=%d ! " \
175 "audio/x-raw,rate=8000 ! alawenc ! rtspclientsink name=sink location=%s"
176 #define RECORD_N_BUFS 10
178 GST_START_TEST (test_record)
180 GstRTSPMediaFactory *mfactory;
181 GstElement *server_sink = NULL;
185 start_record_server ("( rtppcmadepay name=depay0 ! appsink name=sink )");
187 g_signal_connect (mfactory, "media-constructed",
188 G_CALLBACK (media_constructed_cb), &server_sink);
190 /* Create an rtspclientsink and send some data */
192 gchar *uri = get_server_uri (test_port, TEST_MOUNT_POINT);
195 GstElement *pipeline;
198 pipe_str = g_strdup_printf (AUDIO_PIPELINE, RECORD_N_BUFS, uri);
201 pipeline = gst_parse_launch (pipe_str, NULL);
204 fail_unless (pipeline != NULL);
206 bus = gst_element_get_bus (pipeline);
207 fail_if (bus == NULL);
209 gst_element_set_state (pipeline, GST_STATE_PLAYING);
211 msg = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_ERROR, -1);
212 fail_if (GST_MESSAGE_TYPE (msg) != GST_MESSAGE_EOS);
213 gst_message_unref (msg);
215 gst_element_set_state (pipeline, GST_STATE_NULL);
216 gst_object_unref (pipeline);
221 fail_unless (server_send_rtcp_port != 0);
223 /* check received data (we assume every buffer created by audiotestsrc and
224 * subsequently encoded by mulawenc results in exactly one RTP packet) */
225 for (i = 0; i < RECORD_N_BUFS; ++i) {
226 GstSample *sample = NULL;
228 g_signal_emit_by_name (G_OBJECT (server_sink), "pull-sample", &sample);
229 GST_INFO ("%2d recv sample: %p", i, sample);
231 gst_sample_unref (sample);
234 /* clean up and iterate so the clean-up can finish */
241 /* Make sure we can shut down rtspclientsink while it's still waiting for
242 * the initial preroll data */
243 GST_START_TEST (test_record_no_data)
246 start_record_server ("( rtppcmadepay name=depay0 ! fakesink )");
248 /* Create an rtspclientsink and send some data */
250 gchar *uri = get_server_uri (test_port, TEST_MOUNT_POINT);
253 GstElement *pipeline;
256 pipe_str = g_strdup_printf ("appsrc caps=audio/x-alaw,rate=8000,channels=1"
257 " ! rtspclientsink name=sink location=%s", uri);
260 pipeline = gst_parse_launch (pipe_str, NULL);
263 fail_unless (pipeline != NULL);
265 bus = gst_element_get_bus (pipeline);
266 fail_if (bus == NULL);
268 gst_element_set_state (pipeline, GST_STATE_PLAYING);
271 msg = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_ERROR,
273 fail_unless (msg == NULL);
275 gst_element_set_state (pipeline, GST_STATE_NULL);
276 gst_object_unref (pipeline);
277 gst_object_unref (bus);
280 /* clean up and iterate so the clean-up can finish */
288 rtspclientsink_suite (void)
290 Suite *s = suite_create ("rtspclientsink");
291 TCase *tc = tcase_create ("general");
293 suite_add_tcase (s, tc);
294 tcase_add_checked_fixture (tc, setup, teardown);
295 tcase_set_timeout (tc, 120);
296 tcase_add_test (tc, test_record);
297 tcase_add_test (tc, test_record_no_data);
301 GST_CHECK_MAIN (rtspclientsink);