rtspsink: Add rtspclientsink element
[platform/upstream/gstreamer.git] / tests / check / gst / rtspclientsink.c
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>
7  *
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.
12  *
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.
17  *
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.
22  */
23
24 #include <gst/check/gstcheck.h>
25 #include <gst/sdp/gstsdpmessage.h>
26 #include <gst/rtp/gstrtpbuffer.h>
27 #include <gst/rtp/gstrtcpbuffer.h>
28
29 #include <stdio.h>
30 #include <netinet/in.h>
31
32 #include "rtsp-server.h"
33
34 #define TEST_MOUNT_POINT  "/test"
35
36 /* tested rtsp server */
37 static GstRTSPServer *server = NULL;
38
39 /* tcp port that the test server listens for rtsp requests on */
40 static gint test_port = 0;
41
42 /* id of the server's source within the GMainContext */
43 static guint source_id;
44
45 /* iterate the default main context until there are no events to dispatch */
46 static void
47 iterate (void)
48 {
49   while (g_main_context_iteration (NULL, FALSE)) {
50     GST_DEBUG ("iteration");
51   }
52 }
53
54 /* start the testing rtsp server for RECORD mode */
55 static GstRTSPMediaFactory *
56 start_record_server (const gchar * launch_line)
57 {
58   GstRTSPMediaFactory *factory;
59   GstRTSPMountPoints *mounts;
60   gchar *service;
61
62   mounts = gst_rtsp_server_get_mount_points (server);
63
64   factory = gst_rtsp_media_factory_new ();
65
66   gst_rtsp_media_factory_set_transport_mode (factory,
67       GST_RTSP_TRANSPORT_MODE_RECORD);
68   gst_rtsp_media_factory_set_launch (factory, launch_line);
69   gst_rtsp_mount_points_add_factory (mounts, TEST_MOUNT_POINT, factory);
70   g_object_unref (mounts);
71
72   /* set port to any */
73   gst_rtsp_server_set_service (server, "0");
74
75   /* attach to default main context */
76   source_id = gst_rtsp_server_attach (server, NULL);
77   fail_if (source_id == 0);
78
79   /* get port */
80   service = gst_rtsp_server_get_service (server);
81   test_port = atoi (service);
82   fail_unless (test_port != 0);
83   g_free (service);
84
85   GST_DEBUG ("rtsp server listening on port %d", test_port);
86   return factory;
87 }
88
89 /* stop the tested rtsp server */
90 static void
91 stop_server (void)
92 {
93   g_source_remove (source_id);
94   source_id = 0;
95
96   GST_DEBUG ("rtsp server stopped");
97 }
98
99 /* fixture setup function */
100 static void
101 setup (void)
102 {
103   server = gst_rtsp_server_new ();
104 }
105
106 /* fixture clean-up function */
107 static void
108 teardown (void)
109 {
110   if (server) {
111     g_object_unref (server);
112     server = NULL;
113   }
114   test_port = 0;
115 }
116
117 /* create an rtsp connection to the server on test_port */
118 static gchar *
119 get_server_uri (gint port, const gchar * mount_point)
120 {
121   gchar *address;
122   gchar *uri_string;
123   GstRTSPUrl *url = NULL;
124
125   address = gst_rtsp_server_get_address (server);
126   uri_string = g_strdup_printf ("rtsp://%s:%d%s", address, port, mount_point);
127   g_free (address);
128
129   fail_unless (gst_rtsp_url_parse (uri_string, &url) == GST_RTSP_OK);
130   gst_rtsp_url_free (url);
131
132   return uri_string;
133 }
134
135 static void
136 media_constructed_cb (GstRTSPMediaFactory * mfactory, GstRTSPMedia * media,
137     gpointer user_data)
138 {
139   GstElement **p_sink = user_data;
140   GstElement *bin;
141
142   bin = gst_rtsp_media_get_element (media);
143   *p_sink = gst_bin_get_by_name (GST_BIN (bin), "sink");
144   GST_INFO ("media constructed!: %" GST_PTR_FORMAT, *p_sink);
145 }
146
147 #define AUDIO_PIPELINE "audiotestsrc num-buffers=%d ! " \
148   "audio/x-raw,rate=8000 ! alawenc ! rtspclientsink name=sink location=%s"
149 #define RECORD_N_BUFS 10
150
151 GST_START_TEST (test_record)
152 {
153   GstRTSPMediaFactory *mfactory;
154   GstElement *server_sink = NULL;
155   gint i;
156
157   mfactory =
158       start_record_server ("( rtppcmadepay name=depay0 ! appsink name=sink )");
159
160   g_signal_connect (mfactory, "media-constructed",
161       G_CALLBACK (media_constructed_cb), &server_sink);
162
163   /* Create an rtspclientsink and send some data */
164   {
165     gchar *uri = get_server_uri (test_port, TEST_MOUNT_POINT);
166     gchar *pipe_str = g_strdup_printf (AUDIO_PIPELINE,
167         RECORD_N_BUFS, uri);
168     GstMessage *msg;
169     GstElement *pipeline;
170     GstBus *bus;
171
172     pipeline = gst_parse_launch (pipe_str, NULL);
173     fail_unless (pipeline != NULL);
174
175     bus = gst_element_get_bus (pipeline);
176     fail_if (bus == NULL);
177
178     gst_element_set_state (pipeline, GST_STATE_PLAYING);
179
180     msg = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_ERROR, -1);
181     fail_if (GST_MESSAGE_TYPE (msg) != GST_MESSAGE_EOS);
182     gst_message_unref (msg);
183
184     gst_element_set_state (pipeline, GST_STATE_NULL);
185     gst_object_unref (pipeline);
186   }
187
188   iterate ();
189
190   /* check received data (we assume every buffer created by audiotestsrc and
191    * subsequently encoded by mulawenc results in exactly one RTP packet) */
192   for (i = 0; i < RECORD_N_BUFS; ++i) {
193     GstSample *sample = NULL;
194
195     g_signal_emit_by_name (G_OBJECT (server_sink), "pull-sample", &sample);
196     GST_INFO ("%2d recv sample: %p", i, sample);
197     if (sample)
198       gst_sample_unref (sample);
199   }
200
201   /* clean up and iterate so the clean-up can finish */
202   stop_server ();
203   iterate ();
204 }
205
206 GST_END_TEST;
207
208 static Suite *
209 rtspclientsink_suite (void)
210 {
211   Suite *s = suite_create ("rtspclientsink");
212   TCase *tc = tcase_create ("general");
213
214   suite_add_tcase (s, tc);
215   tcase_add_checked_fixture (tc, setup, teardown);
216   tcase_set_timeout (tc, 120);
217   tcase_add_test (tc, test_record);
218   return s;
219 }
220
221 GST_CHECK_MAIN (rtspclientsink);