· 8 years ago · Feb 16, 2018, 01:36 AM
1/* GStreamer
2 * Copyright (C) 2008 Wim Taymans <wim.taymans at gmail.com>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20#include <gst/gst.h>
21
22#include <gst/rtsp-server/rtsp-server.h>
23#include <gst/rtsp-server/rtsp-media-factory-uri.h>
24
25#define DEFAULT_RTSP_PORT "8554"
26
27static char *port = (char *) DEFAULT_RTSP_PORT;
28
29static GOptionEntry entries[] = {
30 {"port", 'p', 0, G_OPTION_ARG_STRING, &port,
31 "Port to listen on (default: " DEFAULT_RTSP_PORT ")", "PORT"},
32 {NULL}
33};
34
35static void
36client_closed(GstRTSPClient *client,
37 gpointer user_data)
38{
39 g_print("client closed\n");
40}
41
42static gboolean
43timeout (GstRTSPServer * server)
44{
45 GstRTSPSessionPool *pool;
46
47 pool = gst_rtsp_server_get_session_pool (server);
48 gst_rtsp_session_pool_cleanup (pool);
49 g_object_unref (pool);
50
51 return TRUE;
52}
53
54static GstRTSPFilterResult
55remove_func (GstRTSPSessionPool *pool, GstRTSPSession *session, gpointer user_data) {
56 return GST_RTSP_FILTER_REMOVE;
57}
58
59static gboolean
60disconnect (GstRTSPClient * client)
61{
62 g_print("disconnect client\n");
63 gst_rtsp_client_close(client);
64 return FALSE;
65}
66
67static void
68client_connected(GstRTSPServer *server,
69 GstRTSPClient *client,
70 gpointer user_data)
71{
72 g_print("client connected\n");
73 g_signal_connect(client, "closed", (GCallback)client_closed,
74 NULL);
75 g_timeout_add_seconds (5, (GSourceFunc) disconnect, client);
76}
77
78#if 0
79static gboolean
80remove_map (GstRTSPServer * server)
81{
82 GstRTSPMountPoints *mounts;
83
84 g_print ("removing /test mount point\n");
85 mounts = gst_rtsp_server_get_mount_points (server);
86 gst_rtsp_mount_points_remove_factory (mounts, "/test");
87 g_object_unref (mounts);
88
89 return FALSE;
90}
91#endif
92
93int
94main (int argc, gchar * argv[])
95{
96 GMainLoop *loop;
97 GstRTSPServer *server;
98 GstRTSPMountPoints *mounts;
99 GstRTSPMediaFactoryURI *factory;
100 GOptionContext *optctx;
101 GError *error = NULL;
102 gchar *uri;
103
104 optctx = g_option_context_new ("<uri> - Test RTSP Server, URI");
105 g_option_context_add_main_entries (optctx, entries, NULL);
106 g_option_context_add_group (optctx, gst_init_get_option_group ());
107 if (!g_option_context_parse (optctx, &argc, &argv, &error)) {
108 g_printerr ("Error parsing options: %s\n", error->message);
109 g_option_context_free (optctx);
110 g_clear_error (&error);
111 return -1;
112 }
113 g_option_context_free (optctx);
114
115 if (argc < 2) {
116 g_printerr ("Please pass an URI or file as argument!\n");
117 return -1;
118 }
119
120 loop = g_main_loop_new (NULL, FALSE);
121
122 /* create a server instance */
123 server = gst_rtsp_server_new ();
124 g_object_set (server, "service", port, NULL);
125 g_signal_connect(server, "client-connected", (GCallback)client_connected,
126 NULL);
127 /* get the mount points for this server, every server has a default object
128 * that be used to map uri mount points to media factories */
129 mounts = gst_rtsp_server_get_mount_points (server);
130
131 /* make a URI media factory for a test stream. */
132 factory = gst_rtsp_media_factory_uri_new ();
133
134 /* when using GStreamer as a client, one can use the gst payloader, which is
135 * more efficient when there is no payloader for the compressed format */
136 /* g_object_set (factory, "use-gstpay", TRUE, NULL); */
137
138 /* check if URI is valid, otherwise convert filename to URI if it's a file */
139 if (gst_uri_is_valid (argv[1])) {
140 uri = g_strdup (argv[1]);
141 } else if (g_file_test (argv[1], G_FILE_TEST_EXISTS)) {
142 uri = gst_filename_to_uri (argv[1], NULL);
143 } else {
144 g_printerr ("Unrecognised command line argument '%s'.\n"
145 "Please pass an URI or file as argument!\n", argv[1]);
146 return -1;
147 }
148
149 gst_rtsp_media_factory_uri_set_uri (factory, uri);
150 g_free (uri);
151
152 /* if you want multiple clients to see the same video, set the shared property
153 * to TRUE */
154 /* gst_rtsp_media_factory_set_shared ( GST_RTSP_MEDIA_FACTORY (factory), TRUE); */
155
156 /* attach the test factory to the /test url */
157 gst_rtsp_mount_points_add_factory (mounts, "/test",
158 GST_RTSP_MEDIA_FACTORY (factory));
159
160 /* don't need the ref to the mapper anymore */
161 g_object_unref (mounts);
162
163 /* attach the server to the default maincontext */
164 if (gst_rtsp_server_attach (server, NULL) == 0)
165 goto failed;
166
167 /* do session cleanup every 2 seconds */
168 g_timeout_add_seconds (2, (GSourceFunc) timeout, server);
169
170#if 0
171 /* remove the mount point after 10 seconds, new clients won't be able to use
172 * the /test url anymore */
173 g_timeout_add_seconds (10, (GSourceFunc) remove_map, server);
174#endif
175
176 /* start serving */
177 g_print ("stream ready at rtsp://127.0.0.1:%s/test\n", port);
178 g_main_loop_run (loop);
179
180 return 0;
181
182 /* ERRORS */
183failed:
184 {
185 g_print ("failed to attach the server\n");
186 return -1;
187 }
188}