gstreamer/gst/rtsp-server/rtsp-session.c
Wim Taymans 704720f306 Cleanups to the session object
Remove some unneeded variables in the session state of a stream such as the
owner media and the server transport.
Get the configuration of a media stream in a session based on the media_stream
in the original object instead of our cached index.
Free more data in the finalize method.
2009-01-30 12:17:57 +01:00

307 lines
7.2 KiB
C

/* GStreamer
* Copyright (C) 2008 Wim Taymans <wim.taymans at gmail.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., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <string.h>
#include "rtsp-session.h"
#undef DEBUG
static void gst_rtsp_session_finalize (GObject * obj);
G_DEFINE_TYPE (GstRTSPSession, gst_rtsp_session, G_TYPE_OBJECT);
static void
gst_rtsp_session_class_init (GstRTSPSessionClass * klass)
{
GObjectClass *gobject_class;
gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = gst_rtsp_session_finalize;
}
static void
gst_rtsp_session_init (GstRTSPSession * session)
{
}
static void
gst_rtsp_session_free_stream (GstRTSPSessionStream *stream, GstRTSPSessionMedia *media)
{
if (stream->client_trans)
gst_rtsp_transport_free (stream->client_trans);
g_free (stream);
}
static void
gst_rtsp_session_free_media (GstRTSPSessionMedia *media, GstRTSPSession *session)
{
g_list_foreach (media->streams, (GFunc) gst_rtsp_session_free_stream,
media);
g_list_free (media->streams);
if (media->url)
gst_rtsp_url_free (media->url);
if (media->media)
g_object_unref (media->media);
g_free (media);
}
static void
gst_rtsp_session_finalize (GObject * obj)
{
GstRTSPSession *session;
session = GST_RTSP_SESSION (obj);
/* free all media */
g_list_foreach (session->medias, (GFunc) gst_rtsp_session_free_media,
session);
g_list_free (session->medias);
/* free session id */
g_free (session->sessionid);
G_OBJECT_CLASS (gst_rtsp_session_parent_class)->finalize (obj);
}
/**
* gst_rtsp_session_manage_media:
* @sess: a #GstRTSPSession
* @url: the url for the media
* @obj: a #GstRTSPMediaObject
*
* Manage the media object @obj in @sess. @url will be used to retrieve this
* media object from the session with gst_rtsp_session_get_media().
*
* Returns: a new @GstRTSPSessionMedia object.
*/
GstRTSPSessionMedia *
gst_rtsp_session_manage_media (GstRTSPSession *sess, const GstRTSPUrl *uri,
GstRTSPMedia *media)
{
GstRTSPSessionMedia *result;
result = g_new0 (GstRTSPSessionMedia, 1);
result->media = media;
result->url = gst_rtsp_url_copy ((GstRTSPUrl *)uri);
sess->medias = g_list_prepend (sess->medias, result);
g_message ("manage new media %p in session %p", media, sess);
return result;
}
/**
* gst_rtsp_session_get_media:
* @sess: a #GstRTSPSession
* @url: the url for the media
*
* Get the session media of the @url.
*
* Returns: the configuration for @url in @sess.
*/
GstRTSPSessionMedia *
gst_rtsp_session_get_media (GstRTSPSession *sess, const GstRTSPUrl *url)
{
GstRTSPSessionMedia *result;
GList *walk;
g_return_val_if_fail (GST_IS_RTSP_SESSION (sess), NULL);
g_return_val_if_fail (url != NULL, NULL);
result = NULL;
for (walk = sess->medias; walk; walk = g_list_next (walk)) {
result = (GstRTSPSessionMedia *) walk->data;
if (strcmp (result->url->abspath, url->abspath) == 0)
break;
result = NULL;
}
return result;
}
/**
* gst_rtsp_session_media_get_stream:
* @media: a #GstRTSPSessionMedia
* @idx: the stream index
*
* Get a previously created or create a new #GstRTSPSessionStream at @idx.
*
* Returns: a #GstRTSPSessionStream that is valid until the session of @media
* is unreffed.
*/
GstRTSPSessionStream *
gst_rtsp_session_media_get_stream (GstRTSPSessionMedia *media, guint idx)
{
GstRTSPSessionStream *result;
GstRTSPMediaStream *media_stream;
GList *walk;
g_return_val_if_fail (media != NULL, NULL);
g_return_val_if_fail (media->media != NULL, NULL);
media_stream = gst_rtsp_media_get_stream (media->media, idx);
if (media_stream == NULL)
goto no_media;
result = NULL;
for (walk = media->streams; walk; walk = g_list_next (walk)) {
result = (GstRTSPSessionStream *) walk->data;
if (result->media_stream == media_stream)
break;
result = NULL;
}
if (result == NULL) {
result = g_new0 (GstRTSPSessionStream, 1);
result->media_stream = media_stream;
media->streams = g_list_prepend (media->streams, result);
}
return result;
/* ERRORS */
no_media:
{
return NULL;
}
}
/**
* gst_rtsp_session_new:
*
* Create a new #GstRTSPSession instance.
*/
GstRTSPSession *
gst_rtsp_session_new (const gchar *sessionid)
{
GstRTSPSession *result;
result = g_object_new (GST_TYPE_RTSP_SESSION, NULL);
result->sessionid = g_strdup (sessionid);
return result;
}
/**
* gst_rtsp_session_stream_init_udp:
* @stream: a #GstRTSPSessionStream
* @ct: a client #GstRTSPTransport
*
* Set @ct as the client transport and create and return a matching server
* transport.
*
* Returns: a server transport or NULL if something went wrong.
*/
GstRTSPTransport *
gst_rtsp_session_stream_set_transport (GstRTSPSessionStream *stream,
GstRTSPTransport *ct)
{
GstRTSPTransport *st;
/* prepare the server transport */
gst_rtsp_transport_new (&st);
st->trans = ct->trans;
st->profile = ct->profile;
st->lower_transport = ct->lower_transport;
st->client_port = ct->client_port;
/* keep track of the transports */
if (stream->client_trans)
gst_rtsp_transport_free (stream->client_trans);
stream->client_trans = ct;
st->server_port.min = stream->media_stream->server_port.min;
st->server_port.max = stream->media_stream->server_port.max;
return st;
}
/**
* gst_rtsp_session_media_play:
* @media: a #GstRTSPSessionMedia
*
* Tell the media object @media to start playing and streaming to the client.
*
* Returns: a #GstStateChangeReturn
*/
GstStateChangeReturn
gst_rtsp_session_media_play (GstRTSPSessionMedia *media)
{
GstStateChangeReturn ret;
GstRTSPSessionStream *stream;
GList *walk;
for (walk = media->streams; walk; walk = g_list_next (walk)) {
stream = (GstRTSPSessionStream *) walk->data;
gst_rtsp_media_stream_add (stream->media_stream, stream->client_trans);
}
ret = gst_rtsp_media_play (media->media);
return ret;
}
/**
* gst_rtsp_session_media_pause:
* @media: a #GstRTSPSessionMedia
*
* Tell the media object @media to pause.
*
* Returns: a #GstStateChangeReturn
*/
GstStateChangeReturn
gst_rtsp_session_media_pause (GstRTSPSessionMedia *media)
{
GstStateChangeReturn ret;
ret = gst_rtsp_media_pause (media->media);
return ret;
}
/**
* gst_rtsp_session_media_stop:
* @media: a #GstRTSPSessionMedia
*
* Tell the media object @media to stop playing. After this call the media
* cannot be played or paused anymore
*
* Returns: a #GstStateChangeReturn
*/
GstStateChangeReturn
gst_rtsp_session_media_stop (GstRTSPSessionMedia *media)
{
GstStateChangeReturn ret;
ret = gst_rtsp_media_stop (media->media);
return ret;
}