From 1b9225078b807fe4a191988c43984b732d5552d7 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 30 Jan 2009 14:53:28 +0100 Subject: [PATCH] More docs and small cleanups Add some more docs and update the README Cleanup some method names. Remove an unneeded idx field in the GstRTSPMediaStream --- docs/README | 97 ++++++++++++++++++++++++++++ gst/rtsp-server/rtsp-media-factory.c | 1 - gst/rtsp-server/rtsp-media-factory.h | 16 ++--- gst/rtsp-server/rtsp-media.c | 12 ++-- gst/rtsp-server/rtsp-media.h | 3 - gst/rtsp-server/rtsp-server.c | 6 +- gst/rtsp-server/rtsp-server.h | 4 +- 7 files changed, 116 insertions(+), 23 deletions(-) diff --git a/docs/README b/docs/README index 06a28c746a..76d4ab9807 100644 --- a/docs/README +++ b/docs/README @@ -107,6 +107,7 @@ can build simple server applications with it. request URL to a specific stream and its configuration. We explain in the next topic how to configure this object. + * Making url mappings Next we need to define what media is attached to a particular URL. What we want @@ -161,6 +162,102 @@ can build simple server applications with it. found in the examples/test-readme.c file. +* more on GstRTSPMediaFactory + + The GstRTSPMediaFactory is responsible for creating and caching GstRTSPMedia + objects. + + A freshly created GstRTSPMedia object from the factory initialy only contains a + GstElement containing the elements to produce the RTP streams for the media and + a GArray of GstRTSPMediaStream objects describing the payloader and its source + pad. The media is unprepared in this state. + + Usually the url will determine what kind of pipeline should be created. You can + for example use query parameters to configure certain parts of the pipeline or + select encoders and payloaders based on some url pattern. + + When dealing with a live stream from, for example, a webcam, it can be + interesting to share the pipeline with multiple clients. This must be done when + only one instance of the video capture element can be used at a time. In this + case, the shared property of GstRTSPMedia must be used to instruct the default + GstRTSPMediaFactory implementation to cache the media. + + When all objects created from a factory can be shared, you can set the shared + property directly on the factory. + +* more on GstRTSPMedia + + After creating the GstRTSPMedia object from the factory, it can be prepared + with gst_rtsp_media_prepare(). This method will put those objects in a + GstPipeline and will construct and link the streaming elements and the + gstrtpbin session manager object. + + The _prepare() method will then preroll the pipeline in order to figure out the + caps on the payloaders. After the GstRTSPMedia prerolled it will be in the + prepared state and can be used for creating SDP files or for streaming to + clients. + + The prepare method will also create 2 UDP ports for each stream that can be + used for sending and receiving RTP/RTCP from clients. These port numbers will + have to be negotiated with the client in the SETUP requests. + + When preparing a GstRTSPMedia, a multifdsink is also constructed for streaming + the stream over TCP^when requested. + + +* the GstRTSPClient object + + When a server detects a new client connection on its port, it will call its + accept_client vmethod. The default implementation of this function will create + a new GstRTCPClient object, will configure the session pool and media mapper + objects in it and will then call the accept function of the client. + + The default GstRTSPClient will accept the connection and will start a new + GThread to handle the connection. In RTSP it is usual to keep the connection + open between multiple RTSP requests. The client thread will simply block for a + new GstRTSPMessage, will dispatch it and will send a response. + + We will briefly describe how it deals with some common requests. + + - DESCRIBE: + + locates the GstRTSPMedia for the url, prepares it and asks the sdp helper + function to construct an SDP from the caps of the prepared media pipeline. + It will also cache the url+media object so that it can be reused later. + + - SETUP + + A new GstRTSPSession object will be created from the GstRTSPSessionPool + object configured in the GstRTSPClient. This session will contain the + configuration of the client regarding the media it is streaming and the + ports/transport it negotiated with the server. + + The sessionid is set in the response header. The client will add the + sessionid to any further SETUP/PLAY/PAUSE/TEARDOWN request so that we can + always find the session again. + + The session configuration for a sessionid will have a link to the prepared + GstRTSPMedia object of the stream. The port and transport of the client is + stored in the session configuration. + + - PLAY + + The session configuration is retrieved with the sessionid and the client + ports are configured in the UDP sinks, then the streaming to the client + is started. + + - PAUSE + + The session configuration is retrieved with the sessionid and the client + ports are removed from the UDP sinks, the streaming to the client + pauses. + + - TEARDOWN + + The session configuration is released along with its link to the + GstRTSPMedia object. When no more clients are refering to the GstRTSPMedia + object, it can be released as well. + diff --git a/gst/rtsp-server/rtsp-media-factory.c b/gst/rtsp-server/rtsp-media-factory.c index 1a5954c5b0..7dd1419902 100644 --- a/gst/rtsp-server/rtsp-media-factory.c +++ b/gst/rtsp-server/rtsp-media-factory.c @@ -418,7 +418,6 @@ default_construct (GstRTSPMediaFactory *factory, const GstRTSPUrl *url) stream = g_new0 (GstRTSPMediaStream, 1); stream->media = media; stream->payloader = pay; - stream->idx = media->streams->len; pad = gst_element_get_static_pad (pay, "src"); diff --git a/gst/rtsp-server/rtsp-media-factory.h b/gst/rtsp-server/rtsp-media-factory.h index 6eafdd0a98..f44192c590 100644 --- a/gst/rtsp-server/rtsp-media-factory.h +++ b/gst/rtsp-server/rtsp-media-factory.h @@ -64,11 +64,13 @@ struct _GstRTSPMediaFactory { /** * GstRTSPMediaFactoryClass: - * @gen_key: convert @url to a key for caching media - * @get_element: Construct an return a #GstElement thast is a #GstBin containing - * the elements to use for the media. The bin should contain payloaders - * pay%d for each stream. The default implementation of this functions - * returns the bin created from the launch parameter. + * @gen_key: convert @url to a key for caching shared #GstRTSPMedia objects. + * The default implementation of this function will use the complete URL + * including the query parameters to return a key. + * @get_element: Construct and return a #GstElement that is a #GstBin containing + * the elements to use for streaming the media. The bin should contain + * payloaders pay%d for each stream. The default implementation of this + * function returns the bin created from the launch parameter. * @construct: the vmethod that will be called when the factory has to create the * #GstRTSPMedia for @url. The default implementation of this * function calls get_element to retrieve an element and then looks for @@ -77,7 +79,7 @@ struct _GstRTSPMediaFactory { * implementation will configure the 'shared' property of the media. * @handle_message: Handle a bus message for @media created from @factory. * - * the #GstRTSPMediaFactory class structure. + * The #GstRTSPMediaFactory class structure. */ struct _GstRTSPMediaFactoryClass { GObjectClass parent_class; @@ -90,8 +92,6 @@ struct _GstRTSPMediaFactoryClass { void (*handle_message) (GstRTSPMediaFactory *factory, GstRTSPMedia *media, GstMessage *message); - - }; GType gst_rtsp_media_factory_get_type (void); diff --git a/gst/rtsp-server/rtsp-media.c b/gst/rtsp-server/rtsp-media.c index 023a153266..f619f02225 100644 --- a/gst/rtsp-server/rtsp-media.c +++ b/gst/rtsp-server/rtsp-media.c @@ -386,7 +386,7 @@ caps_notify (GstPad * pad, GParamSpec * unused, GstRTSPMediaStream * stream) /* prepare the pipeline objects to handle @stream in @media */ static gboolean -setup_stream (GstRTSPMediaStream *stream, GstRTSPMedia *media) +setup_stream (GstRTSPMediaStream *stream, guint idx, GstRTSPMedia *media) { gchar *name; GstPad *pad; @@ -399,16 +399,16 @@ setup_stream (GstRTSPMediaStream *stream, GstRTSPMedia *media) gst_bin_add (GST_BIN_CAST (media->pipeline), stream->udpsrc[1]); /* hook up the stream to the RTP session elements. */ - name = g_strdup_printf ("send_rtp_sink_%d", stream->idx); + name = g_strdup_printf ("send_rtp_sink_%d", idx); stream->send_rtp_sink = gst_element_get_request_pad (media->rtpbin, name); g_free (name); - name = g_strdup_printf ("send_rtp_src_%d", stream->idx); + name = g_strdup_printf ("send_rtp_src_%d", idx); stream->send_rtp_src = gst_element_get_static_pad (media->rtpbin, name); g_free (name); - name = g_strdup_printf ("send_rtcp_src_%d", stream->idx); + name = g_strdup_printf ("send_rtcp_src_%d", idx); stream->send_rtcp_src = gst_element_get_request_pad (media->rtpbin, name); g_free (name); - name = g_strdup_printf ("recv_rtcp_sink_%d", stream->idx); + name = g_strdup_printf ("recv_rtcp_sink_%d", idx); stream->recv_rtcp_sink = gst_element_get_request_pad (media->rtpbin, name); g_free (name); @@ -478,7 +478,7 @@ gst_rtsp_media_prepare (GstRTSPMedia *media) stream = gst_rtsp_media_get_stream (media, i); - setup_stream (stream, media); + setup_stream (stream, i, media); } /* first go to PAUSED */ diff --git a/gst/rtsp-server/rtsp-media.h b/gst/rtsp-server/rtsp-media.h index 1fb685f105..94cb097efd 100644 --- a/gst/rtsp-server/rtsp-media.h +++ b/gst/rtsp-server/rtsp-media.h @@ -43,7 +43,6 @@ typedef struct _GstRTSPMediaClass GstRTSPMediaClass; * GstRTSPMediaStream: * * @media: the owner #GstRTSPMedia - * @idx: the stream index * @srcpad: the srcpad of the stream * @payloader: the payloader of the format * @prepared: if the stream is prepared for streaming @@ -62,8 +61,6 @@ typedef struct _GstRTSPMediaClass GstRTSPMediaClass; struct _GstRTSPMediaStream { GstRTSPMedia *media; - guint idx; - GstPad *srcpad; GstElement *payloader; gboolean prepared; diff --git a/gst/rtsp-server/rtsp-server.c b/gst/rtsp-server/rtsp-server.c index 873ca37b01..c77fcea7e0 100644 --- a/gst/rtsp-server/rtsp-server.c +++ b/gst/rtsp-server/rtsp-server.c @@ -42,7 +42,7 @@ static void gst_rtsp_server_get_property (GObject *object, guint propid, static void gst_rtsp_server_set_property (GObject *object, guint propid, const GValue *value, GParamSpec *pspec); -static GstRTSPClient * gst_rtsp_server_accept_client (GstRTSPServer *server, +static GstRTSPClient * default_accept_client (GstRTSPServer *server, GIOChannel *channel); static void @@ -99,7 +99,7 @@ gst_rtsp_server_class_init (GstRTSPServerClass * klass) "The media mapping to use for client session", GST_TYPE_RTSP_MEDIA_MAPPING, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - klass->accept_client = gst_rtsp_server_accept_client; + klass->accept_client = default_accept_client; } static void @@ -438,7 +438,7 @@ bind_failed: /* default method for creating a new client object in the server to accept and * handle a client connection on this server */ static GstRTSPClient * -gst_rtsp_server_accept_client (GstRTSPServer *server, GIOChannel *channel) +default_accept_client (GstRTSPServer *server, GIOChannel *channel) { GstRTSPClient *client; diff --git a/gst/rtsp-server/rtsp-server.h b/gst/rtsp-server/rtsp-server.h index e719873a96..73c5b131a5 100644 --- a/gst/rtsp-server/rtsp-server.h +++ b/gst/rtsp-server/rtsp-server.h @@ -106,12 +106,12 @@ void gst_rtsp_server_set_media_mapping (GstRTSPServer *serve GstRTSPMediaMapping * gst_rtsp_server_get_media_mapping (GstRTSPServer *server); gboolean gst_rtsp_server_io_func (GIOChannel *channel, GIOCondition condition, - GstRTSPServer *server); + GstRTSPServer *server); GIOChannel * gst_rtsp_server_get_io_channel (GstRTSPServer *server); GSource * gst_rtsp_server_create_watch (GstRTSPServer *server); guint gst_rtsp_server_attach (GstRTSPServer *server, - GMainContext *context); + GMainContext *context); G_END_DECLS