static void client_session_finalized (GstRTSPClient * client,
GstRTSPSession * session);
+static void unlink_session_streams (GstRTSPClient * client,
+ GstRTSPSession *session, GstRTSPSessionMedia * media);
G_DEFINE_TYPE (GstRTSPClient, gst_rtsp_client, G_TYPE_OBJECT);
{
}
-/* A client is finalized when the connection is broken */
static void
-gst_rtsp_client_finalize (GObject * obj)
+client_unlink_session (GstRTSPClient *client, GstRTSPSession *session)
{
- GstRTSPClient *client = GST_RTSP_CLIENT (obj);
- GList *walk;
+ GList *medias;
- GST_INFO ("finalize client %p", client);
+ /* unlink all media managed in this session */
+ for (medias = session->medias; medias; medias = g_list_next (medias)) {
+ unlink_session_streams (client, session, (GstRTSPSessionMedia *) medias->data);
+ }
+}
+
+static void
+client_cleanup_sessions (GstRTSPClient *client)
+{
+ GList *sessions;
/* remove weak-ref from sessions */
- for (walk = client->sessions; walk; walk = g_list_next (walk)) {
- GstRTSPSession *msession = (GstRTSPSession *) walk->data;
- g_object_weak_unref (G_OBJECT (msession),
+ for (sessions = client->sessions; sessions; sessions = g_list_next (sessions)) {
+ GstRTSPSession *session = (GstRTSPSession *) sessions->data;
+ g_object_weak_unref (G_OBJECT (session),
(GWeakNotify) client_session_finalized, client);
+ client_unlink_session (client, session);
}
-
g_list_free (client->sessions);
+ client->sessions = NULL;
+}
+
+/* A client is finalized when the connection is broken */
+static void
+gst_rtsp_client_finalize (GObject * obj)
+{
+ GstRTSPClient *client = GST_RTSP_CLIENT (obj);
+
+ GST_INFO ("finalize client %p", client);
+
+ client_cleanup_sessions (client);
gst_rtsp_connection_free (client->connection);
if (client->session_pool)
}
static void
-link_stream (GstRTSPClient * client, GstRTSPSessionStream * stream)
+link_stream (GstRTSPClient * client, GstRTSPSession *session, GstRTSPSessionStream * stream)
{
GST_DEBUG ("client %p: linking stream %p", client, stream);
gst_rtsp_session_stream_set_callbacks (stream, (GstRTSPSendFunc) do_send_data,
(GstRTSPSendFunc) do_send_data, client, NULL);
client->streams = g_list_prepend (client->streams, stream);
+ /* make sure our session can't expire */
+ gst_rtsp_session_prevent_expire (session);
}
static void
-unlink_stream (GstRTSPClient * client, GstRTSPSessionStream * stream)
+unlink_stream (GstRTSPClient * client, GstRTSPSession *session, GstRTSPSessionStream * stream)
{
GST_DEBUG ("client %p: unlinking stream %p", client, stream);
gst_rtsp_session_stream_set_callbacks (stream, NULL, NULL, NULL, NULL);
client->streams = g_list_remove (client->streams, stream);
+ /* our session can now expire */
+ gst_rtsp_session_allow_expire (session);
}
static void
-unlink_session_streams (GstRTSPClient * client, GstRTSPSessionMedia * media)
+unlink_session_streams (GstRTSPClient * client, GstRTSPSession *session, GstRTSPSessionMedia * media)
{
guint n_streams, i;
if (tr->lower_transport == GST_RTSP_LOWER_TRANS_TCP) {
/* for TCP, unlink the stream from the TCP connection of the client */
- unlink_stream (client, sstream);
+ unlink_stream (client, session, sstream);
}
}
}
goto not_found;
/* unlink the all TCP callbacks */
- unlink_session_streams (client, media);
+ unlink_session_streams (client, session, media);
/* remove the session from the watched sessions */
g_object_weak_unref (G_OBJECT (session),
goto invalid_state;
/* unlink the all TCP callbacks */
- unlink_session_streams (client, media);
+ unlink_session_streams (client, session, media);
/* then pause sending */
gst_rtsp_session_media_set_state (media, GST_STATE_PAUSED);
if (tr->lower_transport == GST_RTSP_LOWER_TRANS_TCP) {
/* for TCP, link the stream to the TCP connection of the client */
- link_stream (client, sstream);
+ link_stream (client, session, sstream);
}
stream = sstream->media_stream;
static void
client_session_finalized (GstRTSPClient * client, GstRTSPSession * session)
{
- GList *medias;
-
GST_INFO ("client %p: session %p finished", client, session);
/* unlink all media managed in this session */
- for (medias = session->medias; medias; medias = g_list_next (medias)) {
- unlink_session_streams (client, (GstRTSPSessionMedia *) medias->data);
- }
+ client_unlink_session (client, session);
+ /* remove the session */
if (!(client->sessions = g_list_remove (client->sessions, session))) {
GST_INFO ("client %p: all sessions finalized, close the connection", client);
close_connection (client);