Commit ccf6c6eb authored by Sebastian Dröge's avatar Sebastian Dröge 🍵

Add initial support for RECORD

We currently only support media that is RECORD or PLAY only, not both at once.

https://bugzilla.gnome.org/show_bug.cgi?id=743175
parent 18668bf4
noinst_PROGRAMS = test-video test-ogg test-mp4 test-readme \
test-launch test-sdp test-uri test-auth \
test-multicast test-multicast2 test-appsrc \
test-video-rtx
test-video-rtx test-record
#INCLUDES = -I$(top_srcdir) -I$(srcdir)
......
/* GStreamer
* Copyright (C) 2008 Wim Taymans <wim.taymans at gmail.com>
* Copyright (C) 2015 Centricular Ltd
* Author: Sebastian Dröge <sebastian@centricular.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <gst/gst.h>
#include <gst/rtsp-server/rtsp-server.h>
int
main (int argc, char *argv[])
{
GMainLoop *loop;
GstRTSPServer *server;
GstRTSPMountPoints *mounts;
GstRTSPMediaFactory *factory;
gst_init (&argc, &argv);
loop = g_main_loop_new (NULL, FALSE);
/* create a server instance */
server = gst_rtsp_server_new ();
/* get the mount points for this server, every server has a default object
* that be used to map uri mount points to media factories */
mounts = gst_rtsp_server_get_mount_points (server);
/* make a media factory for a test stream. The default media factory can use
* gst-launch syntax to create pipelines.
* any launch line works as long as it contains elements named depay%d. Each
* element with depay%d names will be a stream */
factory = gst_rtsp_media_factory_new ();
gst_rtsp_media_factory_set_record (factory, TRUE);
gst_rtsp_media_factory_set_launch (factory,
"( decodebin name=depay0 ! autovideosink decodebin name=depay1 ! autoaudiosink )");
/* attach the test factory to the /test url */
gst_rtsp_mount_points_add_factory (mounts, "/test", factory);
/* don't need the ref to the mapper anymore */
g_object_unref (mounts);
/* attach the server to the default maincontext */
gst_rtsp_server_attach (server, NULL);
/* start serving */
g_print ("stream ready at rtsp://127.0.0.1:8554/test\n");
g_main_loop_run (loop);
return 0;
}
This diff is collapsed.
......@@ -121,8 +121,14 @@ struct _GstRTSPClientClass {
GstRTSPMessage * response);
void (*send_message) (GstRTSPClient * client, GstRTSPContext *ctx,
GstRTSPMessage * response);
gboolean (*handle_sdp) (GstRTSPClient *client, GstRTSPContext *ctx, GstRTSPMedia *media, GstSDPMessage *sdp);
void (*announce_request) (GstRTSPClient *client, GstRTSPContext *ctx);
void (*record_request) (GstRTSPClient *client, GstRTSPContext *ctx);
/*< private >*/
gpointer _gst_reserved[GST_PADDING_LARGE-2];
gpointer _gst_reserved[GST_PADDING_LARGE-5];
};
GType gst_rtsp_client_get_type (void);
......
/* GStreamer
* Copyright (C) 2008 Wim Taymans <wim.taymans at gmail.com>
* Copyright (C) 2015 Centricular Ltd
* Author: Sebastian Dröge <sebastian@centricular.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
......@@ -51,6 +53,7 @@ struct _GstRTSPMediaFactoryPrivate
GstRTSPPermissions *permissions;
gchar *launch;
gboolean shared;
gboolean record;
GstRTSPSuspendMode suspend_mode;
gboolean eos_shutdown;
GstRTSPProfile profiles;
......@@ -72,6 +75,7 @@ struct _GstRTSPMediaFactoryPrivate
#define DEFAULT_PROTOCOLS GST_RTSP_LOWER_TRANS_UDP | GST_RTSP_LOWER_TRANS_UDP_MCAST | \
GST_RTSP_LOWER_TRANS_TCP
#define DEFAULT_BUFFER_SIZE 0x80000
#define DEFAULT_RECORD FALSE
enum
{
......@@ -83,6 +87,7 @@ enum
PROP_PROFILES,
PROP_PROTOCOLS,
PROP_BUFFER_SIZE,
PROP_RECORD,
PROP_LAST
};
......@@ -181,6 +186,14 @@ gst_rtsp_media_factory_class_init (GstRTSPMediaFactoryClass * klass)
"The kernel UDP buffer size to use", 0, G_MAXUINT,
DEFAULT_BUFFER_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/* FIXME: Should this be a flag property to allow RECORD and PLAY?
* Or just another boolean PLAY property that default to TRUE?
*/
g_object_class_install_property (gobject_class, PROP_RECORD,
g_param_spec_boolean ("record", "Record",
"If media from this factory is for PLAY or RECORD", DEFAULT_RECORD,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONSTRUCTED] =
g_signal_new ("media-constructed", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPMediaFactoryClass,
......@@ -273,6 +286,9 @@ gst_rtsp_media_factory_get_property (GObject * object, guint propid,
g_value_set_uint (value,
gst_rtsp_media_factory_get_buffer_size (factory));
break;
case PROP_RECORD:
g_value_set_boolean (value, gst_rtsp_media_factory_is_record (factory));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
}
......@@ -309,6 +325,9 @@ gst_rtsp_media_factory_set_property (GObject * object, guint propid,
gst_rtsp_media_factory_set_buffer_size (factory,
g_value_get_uint (value));
break;
case PROP_RECORD:
gst_rtsp_media_factory_set_record (factory, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
}
......@@ -1136,6 +1155,7 @@ default_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
GstRTSPAddressPool *pool;
GstRTSPPermissions *perms;
GstClockTime rtx_time;
gboolean record;
/* configure the sharedness */
GST_RTSP_MEDIA_FACTORY_LOCK (factory);
......@@ -1146,6 +1166,7 @@ default_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
profiles = priv->profiles;
protocols = priv->protocols;
rtx_time = priv->rtx_time;
record = priv->record;
GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
gst_rtsp_media_set_suspend_mode (media, suspend_mode);
......@@ -1155,6 +1176,7 @@ default_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
gst_rtsp_media_set_profiles (media, profiles);
gst_rtsp_media_set_protocols (media, protocols);
gst_rtsp_media_set_retransmission_time (media, rtx_time);
gst_rtsp_media_set_record (media, record);
if ((pool = gst_rtsp_media_factory_get_address_pool (factory))) {
gst_rtsp_media_set_address_pool (media, pool);
......@@ -1199,3 +1221,51 @@ gst_rtsp_media_factory_create_element (GstRTSPMediaFactory * factory,
return result;
}
/**
* gst_rtsp_media_factory_set_record:
* @factory: a #GstRTSPMediaFactory
* @record: the new value
*
* Configure if this factory creates media for PLAY or RECORD methods.
*/
void
gst_rtsp_media_factory_set_record (GstRTSPMediaFactory * factory,
gboolean record)
{
GstRTSPMediaFactoryPrivate *priv;
g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
priv = factory->priv;
GST_RTSP_MEDIA_FACTORY_LOCK (factory);
priv->record = record;
GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
}
/**
* gst_rtsp_media_factory_is_record:
* @factory: a #GstRTSPMediaFactory
*
* Get if media created from this factory can be used for PLAY or RECORD
* methods.
*
* Returns: %TRUE if the media will be record between clients.
*/
gboolean
gst_rtsp_media_factory_is_record (GstRTSPMediaFactory * factory)
{
GstRTSPMediaFactoryPrivate *priv;
gboolean result;
g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), FALSE);
priv = factory->priv;
GST_RTSP_MEDIA_FACTORY_LOCK (factory);
result = priv->record;
GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
return result;
}
......@@ -145,6 +145,10 @@ void gst_rtsp_media_factory_set_retransmission_time (GstRTSPMed
GstClockTime time);
GstClockTime gst_rtsp_media_factory_get_retransmission_time (GstRTSPMediaFactory * factory);
void gst_rtsp_media_factory_set_record (GstRTSPMediaFactory *factory,
gboolean record);
gboolean gst_rtsp_media_factory_is_record (GstRTSPMediaFactory *factory);
/* creating the media from the factory and a url */
GstRTSPMedia * gst_rtsp_media_factory_construct (GstRTSPMediaFactory *factory,
const GstRTSPUrl *url);
......
This diff is collapsed.
......@@ -149,8 +149,10 @@ struct _GstRTSPMediaClass {
void (*target_state) (GstRTSPMedia *media, GstState state);
void (*new_state) (GstRTSPMedia *media, GstState state);
gboolean (*handle_sdp) (GstRTSPMedia *media, GstSDPMessage *sdp);
/*< private >*/
gpointer _gst_reserved[GST_PADDING_LARGE];
gpointer _gst_reserved[GST_PADDING_LARGE-1];
};
GType gst_rtsp_media_get_type (void);
......@@ -170,6 +172,9 @@ GstRTSPPermissions * gst_rtsp_media_get_permissions (GstRTSPMedia *media);
void gst_rtsp_media_set_shared (GstRTSPMedia *media, gboolean shared);
gboolean gst_rtsp_media_is_shared (GstRTSPMedia *media);
void gst_rtsp_media_set_record (GstRTSPMedia *media, gboolean record);
gboolean gst_rtsp_media_is_record (GstRTSPMedia *media);
void gst_rtsp_media_set_reusable (GstRTSPMedia *media, gboolean reusable);
gboolean gst_rtsp_media_is_reusable (GstRTSPMedia *media);
......@@ -209,6 +214,9 @@ gboolean gst_rtsp_media_unsuspend (GstRTSPMedia *media);
gboolean gst_rtsp_media_setup_sdp (GstRTSPMedia * media, GstSDPMessage * sdp,
GstSDPInfo * info);
gboolean gst_rtsp_media_handle_sdp (GstRTSPMedia * media, GstSDPMessage * sdp);
/* creating streams */
void gst_rtsp_media_collect_streams (GstRTSPMedia *media);
GstRTSPStream * gst_rtsp_media_create_stream (GstRTSPMedia *media,
......
/* GStreamer
* Copyright (C) 2008 Wim Taymans <wim.taymans at gmail.com>
* Copyright (C) 2015 Centricular Ltd
* Author: Sebastian Dröge <sebastian@centricular.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
......@@ -144,6 +146,7 @@ gst_rtsp_session_media_new (const gchar * path, GstRTSPMedia * media)
g_return_val_if_fail (path != NULL, NULL);
g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), NULL);
status = gst_rtsp_media_get_status (media);
g_return_val_if_fail (status == GST_RTSP_MEDIA_STATUS_PREPARED || status ==
GST_RTSP_MEDIA_STATUS_SUSPENDED, NULL);
......
This diff is collapsed.
......@@ -67,10 +67,11 @@ struct _GstRTSPStreamClass {
GType gst_rtsp_stream_get_type (void);
GstRTSPStream * gst_rtsp_stream_new (guint idx, GstElement *payloader,
GstPad *srcpad);
GstPad *pad);
guint gst_rtsp_stream_get_index (GstRTSPStream *stream);
guint gst_rtsp_stream_get_pt (GstRTSPStream *stream);
GstPad * gst_rtsp_stream_get_srcpad (GstRTSPStream *stream);
GstPad * gst_rtsp_stream_get_sinkpad (GstRTSPStream *stream);
void gst_rtsp_stream_set_control (GstRTSPStream *stream, const gchar *control);
gchar * gst_rtsp_stream_get_control (GstRTSPStream *stream);
......@@ -160,6 +161,8 @@ guint gst_rtsp_stream_get_retransmission_pt (GstRTSPStream * s
void gst_rtsp_stream_set_retransmission_pt (GstRTSPStream * stream,
guint rtx_pt);
void gst_rtsp_stream_set_pt_map (GstRTSPStream * stream, guint pt, GstCaps * caps);
/**
* GstRTSPStreamTransportFilterFunc:
* @stream: a #GstRTSPStream object
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment