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
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.
+
stream = g_new0 (GstRTSPMediaStream, 1);
stream->media = media;
stream->payloader = pay;
- stream->idx = media->streams->len;
pad = gst_element_get_static_pad (pay, "src");
/**
* 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
* 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;
void (*handle_message) (GstRTSPMediaFactory *factory, GstRTSPMedia *media,
GstMessage *message);
-
-
};
GType gst_rtsp_media_factory_get_type (void);
/* 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;
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);
stream = gst_rtsp_media_get_stream (media, i);
- setup_stream (stream, media);
+ setup_stream (stream, i, media);
}
/* first go to PAUSED */
* 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
struct _GstRTSPMediaStream {
GstRTSPMedia *media;
- guint idx;
-
GstPad *srcpad;
GstElement *payloader;
gboolean prepared;
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
"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
/* 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;
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