summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@gmail.com>2007-04-26 10:08:27 +0000
committerWim Taymans <wim.taymans@gmail.com>2007-04-26 10:08:27 +0000
commit530f214bd57cfd8fa9e001d957808211a28df06a (patch)
tree8944590d331da0b46e33872ca750442bb9999533
parent45b77c57b4d71ac737e31a28688065c15c6f68f0 (diff)
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.
-rw-r--r--ChangeLog15
-rw-r--r--gst/rtsp/gstrtspsrc.c80
-rw-r--r--gst/rtsp/gstrtspsrc.h6
-rw-r--r--gst/rtsp/rtspconnection.c8
-rw-r--r--gst/rtsp/rtspconnection.h1
5 files changed, 102 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index 1b1a2cdd..98d487b7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,20 @@
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):
Handle the case where there are exactly 0 bytes to read and the ioctl
did not report an error. Fixes #433530.
diff --git a/gst/rtsp/gstrtspsrc.c b/gst/rtsp/gstrtspsrc.c
index ef79b6e3..85966dbd 100644
--- a/gst/rtsp/gstrtspsrc.c
+++ b/gst/rtsp/gstrtspsrc.c
@@ -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."));
diff --git a/gst/rtsp/gstrtspsrc.h b/gst/rtsp/gstrtspsrc.h
index 82582cf3..7d595f69 100644
--- a/gst/rtsp/gstrtspsrc.h
+++ b/gst/rtsp/gstrtspsrc.h
@@ -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;
diff --git a/gst/rtsp/rtspconnection.c b/gst/rtsp/rtspconnection.c
index e921a346..448dccd3 100644
--- a/gst/rtsp/rtspconnection.c
+++ b/gst/rtsp/rtspconnection.c
@@ -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
diff --git a/gst/rtsp/rtspconnection.h b/gst/rtsp/rtspconnection.h
index 2076950b..fc3b28cf 100644
--- a/gst/rtsp/rtspconnection.h
+++ b/gst/rtsp/rtspconnection.h
@@ -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 */