diff options
3 files changed, 119 insertions, 38 deletions
diff --git a/docs/README b/docs/README
index 76d4ab9..50ad82f 100644
--- a/docs/README
+++ b/docs/README
@@ -103,7 +103,7 @@ can build simple server applications with it.
alternative implementation can be used by the server.
The GstRTSPMediaMapping object is more interesting and needs more configuration
- before the server object is useful. This object manages to mapping from a
+ before the server object is useful. This object manages the mapping from a
request URL to a specific stream and its configuration. We explain in the next
topic how to configure this object.
@@ -202,7 +202,7 @@ can build simple server applications with it.
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 stream over TCP when requested.
* the GstRTSPClient object
@@ -212,61 +212,143 @@ can build simple server applications with it.
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.
+ The default GstRTSPClient will accept the connection and will attach a watch to
+ the server mainloop. In RTSP it is usual to keep the connection
+ open between multiple RTSP requests. The client watch will be dispatched by the
+ server mainloop when a new GstRTSPMessage is received, which will then be
+ handled and a response will be sent.
+ The GstRTSPClient object remains alive for as long as a client has a TCP
+ connection open with the server. Since is possible for a client to open and close
+ the TCP connection between requests, we cannot store the state related
+ to the configured RTSP session in the GstRTSPClient object. This server state
+ is instead stored in the GstRTSPSession object.
- 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.
+* GstRTSPSession
+ This object contains state about a specific RTSP session identified with a
+ session id. This state contains the configured streams and their associated
+ transports.
+ When a GstRTSPClient performs a SETUP request, the server will allocate a new
+ GstRTSPSession with a unique session id from the GstRTSPSessionPool. The pool
+ maintains a list of all existing sessions and makes sure that no session id is
+ used multiple times. The session id is sent to the client so that the client
+ can refer to its previously configured state by sending the session id in
+ further requests.
+ A client will then use the session id to configure one or more streams,
+ identified by their url. This information is kept in a GstRTSPSessionMedia
+ structure that is refered to from the GstRTSPSession.
+* GstRTSPSessionMedia and GstRTSPSessionStream
+ A GstRTSPSessionMedia is identified by a URL and is referenced by a
+ GstRTSPSession. It is created as soon as a client performs a SETUP operation on
+ a particular URL. It will contain a link to the GstRTSPMedia object associated
+ with the URL along with the state of the media and the configured transports
+ for each of the streams in the media.
+ Each SETUP request performed by the client will configure a
+ GstRTSPSessionStream object linked to by the GstRTSPSessionMedia structure.
+ It will contain the transport information needed to send this stream to the
+ client. The GstRTSPSessionStream also contains a link to the GstRTSPMediaStream
+ object that generates the actual data to be streamed to the client.
- 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.
+ Note how GstRTSPMedia and GstRTSPMediaStream (the providers of the data to
+ stream) are decoupled from GstRTSPSessionMedia and GstRTSPSessionStream (the
+ configuration of how to send this stream to a client) in order to be able to
+ send the data of one GstRTSPMedia to multiple clients.
- 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.
+* media control
- - PLAY
+ After a client has configured the transports for a GstRTSPMedia and its
+ GstRTSPMediaStreams, the client can play/pause/stop the stream.
- 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.
+ The GstRTSPMedia object was prepared in the DESCRIBE call (or during SETUP when
+ the client skipped the DESCRIBE request). As seen earlier, this configures a
+ couple of multiudpsink and udpsrc elements to respectively send and receive the
+ media to clients.
+ When a client performs a PLAY request, its configured destination UDP ports are
+ added to the GstRTSPMediaStream target destinations, at which point data will
+ be sent to the client. The corresponding GstRTSPMedia object will be set to the
+ PLAYING state if it was not allready in order to send the data to the
+ destination.
- The session configuration is retrieved with the sessionid and the client
- ports are removed from the UDP sinks, the streaming to the client
- pauses.
+ The server needs to prepare an RTP-Info header field in the PLAY response,
+ which consists of the sequence number and the RTP timestamp of the next RTP
+ packet. In order to achive this, the server queries the payloaders for this
+ information when it prerolled the pipeline.
+ When a client performs a PAUSE request, the destination UDP ports are removed
+ from the GstRTSPMediaStream object and the GstRTSPMedia object is set to PAUSED
+ if no other destinations are configured anymore.
- 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.
+* seeking
+ A seek is performed when a client sends a Range header in the PLAY request.
+ This only works when not dealing with shared (live) streams.
+ The server performs a GStreamer flushing seek on the media, waits for the
+ pipeline to preroll again and then responds to the client after collecting the
+ new RTP sequence number and timestamp from the payloaders.
+* session management
+ The server has to react to clients that suddenly disappear because of network
+ problems or otherwise. It needs to make sure that it can reasonable free the
+ resources that are used by the various objects in use for streaming when the
+ client appears to be gone.
+ Each of the GstRTSPSession objects managed by a GstRTSPSessionPool has
+ therefore a last_access field that contains the timestamp of when activity from
+ a client was last recorded.
+ Various ways exist to detect activity from a client:
+ - RTSP keepalive requests. When a client is receiving RTP data, the RTSP TCP
+ connection is largely unused. It is the client responsability to
+ periodically send keep-alive requests over the TCP channel.
+ Whenever a keep-alive request is received by the server (any request that
+ contains a session id, usually an OPTION or GET_PARAMETER request) the
+ last_access of the session is updated.
+ - Since it is not required for a client to keep the RTSP TCP connection open
+ while streaming, gst-rtsp-server also detects activity from clients by
+ looking at the RTCP messages it receives.
+ When an RTCP message is received from a client, the server looks in its list
+ of active ports if this message originates from a known host/port pair that
+ is currently active in a GstRTSPSession. If this is the case, the session is
+ kept alive.
+ Since the server does not know anything about the port number that will be
+ used by the client to send RTCP, this method does not always work. Later
+ RTSP RFCs will include support for negotiating this port number with the
+ server. Most clients however use the same port number for sending and
+ receiving RTCP exactly for this reason.
+ If there was no activity in a particular session for a long time (by default 60
+ seconds), the sessionpool will destroy the session along with all related
+ objects and media as if a TEARDOWN happened from the client.
+ A TEARDOWN request will first location the GstRTSPSessionMedia of the URL. It
+ will then remove all transports from the streams, making sure that streaming
+ stops to the client. It will then remove the GstRTSPSessionMedia and
+ GstRTSPSessionStream structures. Finally the GstRTSPSession is released back
+ into the pool.
+ When there are no more references to the GstRTSPMedia, the media pipeline is
+ shut down and destroyed.
diff --git a/gst/rtsp-server/rtsp-client.c b/gst/rtsp-server/rtsp-client.c
index c8f75dc..ee76abc 100644
--- a/gst/rtsp-server/rtsp-client.c
+++ b/gst/rtsp-server/rtsp-client.c
@@ -1475,7 +1475,7 @@ static GstRTSPWatchFuncs watch_funcs = {
* @client: a #GstRTSPClient
* @channel: a #GIOChannel
- * Accept a new connection for @client on the socket in @source.
+ * Accept a new connection for @client on the socket in @channel.
* This function should be called when the client properties and urls are fully
* configured and the client is ready to start.
diff --git a/gst/rtsp-server/rtsp-server.c b/gst/rtsp-server/rtsp-server.c
index 3d690f8..489224f 100644
--- a/gst/rtsp-server/rtsp-server.c
+++ b/gst/rtsp-server/rtsp-server.c
@@ -464,8 +464,7 @@ default_accept_client (GstRTSPServer *server, GIOChannel *channel)
/* set the session pool that this client should use */
gst_rtsp_client_set_session_pool (client, server->session_pool);
- /* set the session pool that this client should use */
+ /* set the media mapping that this client should use */
gst_rtsp_client_set_media_mapping (client, server->media_mapping);
/* accept connections for that client, this function returns after accepting