gst/rtsp/gstrtspsrc.*: Protect state changes with a lock.

Original commit message from CVS:
* gst/rtsp/gstrtspsrc.c: (gst_rtspsrc_init),
(gst_rtspsrc_finalize), (gst_rtspsrc_stream_configure_transport),
(gst_rtspsrc_open), (gst_rtspsrc_close),
(gst_rtspsrc_parse_rtpinfo), (gst_rtspsrc_play),
(gst_rtspsrc_pause):
* gst/rtsp/gstrtspsrc.h:
Protect state changes with a lock.
* gst/rtsp/rtspconnection.c: (rtsp_connection_create),
(parse_line):
* gst/rtsp/rtspconnection.h:
Remove some unused stuff.
This commit is contained in:
Wim Taymans 2007-04-26 10:08:27 +00:00
parent 45b77c57b4
commit 530f214bd5
5 changed files with 102 additions and 8 deletions

View file

@ -1,3 +1,18 @@
2007-04-26 Wim Taymans <wim@fluendo.com>
* gst/rtsp/gstrtspsrc.c: (gst_rtspsrc_init),
(gst_rtspsrc_finalize), (gst_rtspsrc_stream_configure_transport),
(gst_rtspsrc_open), (gst_rtspsrc_close),
(gst_rtspsrc_parse_rtpinfo), (gst_rtspsrc_play),
(gst_rtspsrc_pause):
* gst/rtsp/gstrtspsrc.h:
Protect state changes with a lock.
* gst/rtsp/rtspconnection.c: (rtsp_connection_create),
(parse_line):
* gst/rtsp/rtspconnection.h:
Remove some unused stuff.
2007-04-26 Wim Taymans <wim@fluendo.com>
* gst/udp/gstudpsrc.c: (gst_udpsrc_create):

View file

@ -302,6 +302,9 @@ gst_rtspsrc_init (GstRTSPSrc * src, GstRTSPSrcClass * g_class)
src->extension = rtsp_ext_wms_get_context ();
#endif
src->extension->src = (gpointer) src;
src->state_lock = g_mutex_new ();
src->state = RTSP_STATE_INVALID;
}
static void
@ -319,6 +322,7 @@ gst_rtspsrc_finalize (GObject * object)
g_free (rtspsrc->content_base);
rtsp_url_free (rtspsrc->url);
g_free (rtspsrc->addr);
g_mutex_free (rtspsrc->state_lock);
if (rtspsrc->extension) {
#ifdef WITH_EXT_REAL
@ -2554,6 +2558,8 @@ gst_rtspsrc_open (GstRTSPSrc * src)
GstRTSPStream *stream = NULL;
gchar *respcont = NULL;
GST_RTSP_STATE_LOCK (src);
/* reset our state */
gst_segment_init (&src->segment, GST_FORMAT_TIME);
@ -2645,8 +2651,14 @@ gst_rtspsrc_open (GstRTSPSrc * src)
stream = gst_rtspsrc_create_stream (src, &sdp, i);
}
src->state = RTSP_STATE_INIT;
/* setup streams */
gst_rtspsrc_setup_streams (src);
if (!gst_rtspsrc_setup_streams (src))
goto setup_failed;
src->state = RTSP_STATE_READY;
GST_RTSP_STATE_UNLOCK (src);
/* clean up any messages */
rtsp_message_unset (&request);
@ -2705,8 +2717,14 @@ wrong_content_type:
("Server does not support SDP, got %s.", respcont));
goto cleanup_error;
}
setup_failed:
{
/* error was posted */
goto cleanup_error;
}
cleanup_error:
{
GST_RTSP_STATE_UNLOCK (src);
rtsp_message_unset (&request);
rtsp_message_unset (&response);
return FALSE;
@ -2722,6 +2740,8 @@ gst_rtspsrc_close (GstRTSPSrc * src)
GST_DEBUG_OBJECT (src, "TEARDOWN...");
GST_RTSP_STATE_LOCK (src);
gst_rtspsrc_loop_send_cmd (src, CMD_STOP);
/* stop task if any */
@ -2767,17 +2787,22 @@ gst_rtspsrc_close (GstRTSPSrc * src)
/* cleanup */
gst_rtspsrc_cleanup (src);
src->state = RTSP_STATE_INVALID;
GST_RTSP_STATE_UNLOCK (src);
return TRUE;
/* ERRORS */
create_request_failed:
{
GST_RTSP_STATE_UNLOCK (src);
GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL),
("Could not create request."));
return FALSE;
}
send_error:
{
GST_RTSP_STATE_UNLOCK (src);
rtsp_message_unset (&request);
GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL),
("Could not send message."));
@ -2785,6 +2810,7 @@ send_error:
}
close_failed:
{
GST_RTSP_STATE_UNLOCK (src);
GST_ELEMENT_ERROR (src, RESOURCE, CLOSE, (NULL), ("Close failed."));
return FALSE;
}
@ -2874,11 +2900,16 @@ gst_rtspsrc_play (GstRTSPSrc * src)
RTSPResult res;
gchar *rtpinfo;
if (!(src->methods & RTSP_PLAY))
return TRUE;
GST_RTSP_STATE_LOCK (src);
GST_DEBUG_OBJECT (src, "PLAY...");
if (!(src->methods & RTSP_PLAY))
goto not_supported;
if (src->state == RTSP_STATE_PLAYING)
goto was_playing;
/* do play */
res = rtsp_message_init_request (&request, RTSP_PLAY, src->req_location);
if (res < 0)
@ -2908,20 +2939,36 @@ gst_rtspsrc_play (GstRTSPSrc * src)
gst_task_set_lock (src->task, src->stream_rec_lock);
}
src->running = TRUE;
src->state = RTSP_STATE_PLAYING;
gst_rtspsrc_loop_send_cmd (src, CMD_WAIT);
gst_task_start (src->task);
done:
GST_RTSP_STATE_UNLOCK (src);
return TRUE;
/* ERRORS */
not_supported:
{
GST_DEBUG_OBJECT (src, "PLAY is not supported");
goto done;
}
was_playing:
{
GST_DEBUG_OBJECT (src, "we were already PLAYING");
goto done;
}
create_request_failed:
{
GST_RTSP_STATE_UNLOCK (src);
GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL),
("Could not create request."));
return FALSE;
}
send_error:
{
GST_RTSP_STATE_UNLOCK (src);
rtsp_message_unset (&request);
GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL),
("Could not send message."));
@ -2936,10 +2983,16 @@ gst_rtspsrc_pause (GstRTSPSrc * src)
RTSPMessage response = { 0 };
RTSPResult res;
if (!(src->methods & RTSP_PAUSE))
return TRUE;
GST_RTSP_STATE_LOCK (src);
GST_DEBUG_OBJECT (src, "PAUSE...");
if (!(src->methods & RTSP_PAUSE))
goto not_supported;
if (src->state == RTSP_STATE_READY)
goto was_paused;
/* do pause */
res = rtsp_message_init_request (&request, RTSP_PAUSE, src->req_location);
if (res < 0)
@ -2951,17 +3004,34 @@ gst_rtspsrc_pause (GstRTSPSrc * src)
rtsp_message_unset (&request);
rtsp_message_unset (&response);
src->state = RTSP_STATE_READY;
done:
GST_RTSP_STATE_UNLOCK (src);
return TRUE;
/* ERRORS */
not_supported:
{
GST_DEBUG_OBJECT (src, "PAUSE is not supported");
goto done;
}
was_paused:
{
GST_DEBUG_OBJECT (src, "we were already PAUSED");
goto done;
}
create_request_failed:
{
GST_RTSP_STATE_UNLOCK (src);
GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL),
("Could not create request."));
return FALSE;
}
send_error:
{
GST_RTSP_STATE_UNLOCK (src);
rtsp_message_unset (&request);
GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL),
("Could not send message."));

View file

@ -67,6 +67,10 @@ G_BEGIN_DECLS
typedef struct _GstRTSPSrc GstRTSPSrc;
typedef struct _GstRTSPSrcClass GstRTSPSrcClass;
#define GST_RTSP_STATE_GET_LOCK(rtsp) (GST_RTSPSRC_CAST(rtsp)->state_lock)
#define GST_RTSP_STATE_LOCK(rtsp) (g_mutex_lock (GST_RTSP_STATE_GET_LOCK(rtsp)))
#define GST_RTSP_STATE_UNLOCK(rtsp) (g_mutex_unlock (GST_RTSP_STATE_GET_LOCK(rtsp)))
#define GST_RTSP_LOOP_GET_COND(rtsp) (GST_RTSPSRC_CAST(rtsp)->loop_cond)
#define GST_RTSP_LOOP_WAIT(rtsp) (g_cond_wait(GST_RTSP_LOOP_GET_COND (rtsp), GST_OBJECT_GET_LOCK (rtsp)))
#define GST_RTSP_LOOP_SIGNAL(rtsp) (g_cond_signal(GST_RTSP_LOOP_GET_COND (rtsp)))
@ -124,6 +128,7 @@ struct _GstRTSPSrc {
/* cond to signal loop */
GCond *loop_cond;
gint loop_cmd;
GMutex *state_lock;
gint numstreams;
GList *streams;
@ -141,6 +146,7 @@ struct _GstRTSPSrc {
guint latency;
/* state */
RTSPState state;
gchar *content_base;
RTSPLowerTrans cur_protocols;
gboolean tried_url_auth;

View file

@ -142,7 +142,6 @@ rtsp_connection_create (RTSPUrl * url, RTSPConnection ** conn)
newconn->fd = -1;
newconn->cseq = 0;
newconn->session_id[0] = 0;
newconn->state = RTSP_STATE_INIT;
newconn->auth_method = RTSP_AUTH_NONE;
newconn->username = NULL;
@ -524,7 +523,7 @@ parse_line (gchar * buffer, RTSPMessage * msg)
/* read key */
read_key (key, sizeof (key), &bptr);
if (*bptr != ':')
return RTSP_EINVAL;
goto no_column;
bptr++;
@ -536,6 +535,11 @@ parse_line (gchar * buffer, RTSPMessage * msg)
}
return RTSP_OK;
no_column:
{
return RTSP_EINVAL;
}
}
RTSPResult

View file

@ -61,7 +61,6 @@ typedef struct _RTSPConnection
gint control_sock[2];
/* Session state */
RTSPState state;
gint cseq; /* sequence number */
gchar session_id[512]; /* session id */