mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-07-06 14:45:54 +00:00
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:
parent
45b77c57b4
commit
530f214bd5
15
ChangeLog
15
ChangeLog
|
@ -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>
|
2007-04-26 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
* gst/udp/gstudpsrc.c: (gst_udpsrc_create):
|
* gst/udp/gstudpsrc.c: (gst_udpsrc_create):
|
||||||
|
|
|
@ -302,6 +302,9 @@ gst_rtspsrc_init (GstRTSPSrc * src, GstRTSPSrcClass * g_class)
|
||||||
src->extension = rtsp_ext_wms_get_context ();
|
src->extension = rtsp_ext_wms_get_context ();
|
||||||
#endif
|
#endif
|
||||||
src->extension->src = (gpointer) src;
|
src->extension->src = (gpointer) src;
|
||||||
|
|
||||||
|
src->state_lock = g_mutex_new ();
|
||||||
|
src->state = RTSP_STATE_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -319,6 +322,7 @@ gst_rtspsrc_finalize (GObject * object)
|
||||||
g_free (rtspsrc->content_base);
|
g_free (rtspsrc->content_base);
|
||||||
rtsp_url_free (rtspsrc->url);
|
rtsp_url_free (rtspsrc->url);
|
||||||
g_free (rtspsrc->addr);
|
g_free (rtspsrc->addr);
|
||||||
|
g_mutex_free (rtspsrc->state_lock);
|
||||||
|
|
||||||
if (rtspsrc->extension) {
|
if (rtspsrc->extension) {
|
||||||
#ifdef WITH_EXT_REAL
|
#ifdef WITH_EXT_REAL
|
||||||
|
@ -2554,6 +2558,8 @@ gst_rtspsrc_open (GstRTSPSrc * src)
|
||||||
GstRTSPStream *stream = NULL;
|
GstRTSPStream *stream = NULL;
|
||||||
gchar *respcont = NULL;
|
gchar *respcont = NULL;
|
||||||
|
|
||||||
|
GST_RTSP_STATE_LOCK (src);
|
||||||
|
|
||||||
/* reset our state */
|
/* reset our state */
|
||||||
gst_segment_init (&src->segment, GST_FORMAT_TIME);
|
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);
|
stream = gst_rtspsrc_create_stream (src, &sdp, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
src->state = RTSP_STATE_INIT;
|
||||||
|
|
||||||
/* setup streams */
|
/* 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 */
|
/* clean up any messages */
|
||||||
rtsp_message_unset (&request);
|
rtsp_message_unset (&request);
|
||||||
|
@ -2705,8 +2717,14 @@ wrong_content_type:
|
||||||
("Server does not support SDP, got %s.", respcont));
|
("Server does not support SDP, got %s.", respcont));
|
||||||
goto cleanup_error;
|
goto cleanup_error;
|
||||||
}
|
}
|
||||||
|
setup_failed:
|
||||||
|
{
|
||||||
|
/* error was posted */
|
||||||
|
goto cleanup_error;
|
||||||
|
}
|
||||||
cleanup_error:
|
cleanup_error:
|
||||||
{
|
{
|
||||||
|
GST_RTSP_STATE_UNLOCK (src);
|
||||||
rtsp_message_unset (&request);
|
rtsp_message_unset (&request);
|
||||||
rtsp_message_unset (&response);
|
rtsp_message_unset (&response);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -2722,6 +2740,8 @@ gst_rtspsrc_close (GstRTSPSrc * src)
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (src, "TEARDOWN...");
|
GST_DEBUG_OBJECT (src, "TEARDOWN...");
|
||||||
|
|
||||||
|
GST_RTSP_STATE_LOCK (src);
|
||||||
|
|
||||||
gst_rtspsrc_loop_send_cmd (src, CMD_STOP);
|
gst_rtspsrc_loop_send_cmd (src, CMD_STOP);
|
||||||
|
|
||||||
/* stop task if any */
|
/* stop task if any */
|
||||||
|
@ -2767,17 +2787,22 @@ gst_rtspsrc_close (GstRTSPSrc * src)
|
||||||
/* cleanup */
|
/* cleanup */
|
||||||
gst_rtspsrc_cleanup (src);
|
gst_rtspsrc_cleanup (src);
|
||||||
|
|
||||||
|
src->state = RTSP_STATE_INVALID;
|
||||||
|
GST_RTSP_STATE_UNLOCK (src);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* ERRORS */
|
/* ERRORS */
|
||||||
create_request_failed:
|
create_request_failed:
|
||||||
{
|
{
|
||||||
|
GST_RTSP_STATE_UNLOCK (src);
|
||||||
GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL),
|
GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL),
|
||||||
("Could not create request."));
|
("Could not create request."));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
send_error:
|
send_error:
|
||||||
{
|
{
|
||||||
|
GST_RTSP_STATE_UNLOCK (src);
|
||||||
rtsp_message_unset (&request);
|
rtsp_message_unset (&request);
|
||||||
GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL),
|
GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL),
|
||||||
("Could not send message."));
|
("Could not send message."));
|
||||||
|
@ -2785,6 +2810,7 @@ send_error:
|
||||||
}
|
}
|
||||||
close_failed:
|
close_failed:
|
||||||
{
|
{
|
||||||
|
GST_RTSP_STATE_UNLOCK (src);
|
||||||
GST_ELEMENT_ERROR (src, RESOURCE, CLOSE, (NULL), ("Close failed."));
|
GST_ELEMENT_ERROR (src, RESOURCE, CLOSE, (NULL), ("Close failed."));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -2874,11 +2900,16 @@ gst_rtspsrc_play (GstRTSPSrc * src)
|
||||||
RTSPResult res;
|
RTSPResult res;
|
||||||
gchar *rtpinfo;
|
gchar *rtpinfo;
|
||||||
|
|
||||||
if (!(src->methods & RTSP_PLAY))
|
GST_RTSP_STATE_LOCK (src);
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (src, "PLAY...");
|
GST_DEBUG_OBJECT (src, "PLAY...");
|
||||||
|
|
||||||
|
if (!(src->methods & RTSP_PLAY))
|
||||||
|
goto not_supported;
|
||||||
|
|
||||||
|
if (src->state == RTSP_STATE_PLAYING)
|
||||||
|
goto was_playing;
|
||||||
|
|
||||||
/* do play */
|
/* do play */
|
||||||
res = rtsp_message_init_request (&request, RTSP_PLAY, src->req_location);
|
res = rtsp_message_init_request (&request, RTSP_PLAY, src->req_location);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
|
@ -2908,20 +2939,36 @@ gst_rtspsrc_play (GstRTSPSrc * src)
|
||||||
gst_task_set_lock (src->task, src->stream_rec_lock);
|
gst_task_set_lock (src->task, src->stream_rec_lock);
|
||||||
}
|
}
|
||||||
src->running = TRUE;
|
src->running = TRUE;
|
||||||
|
src->state = RTSP_STATE_PLAYING;
|
||||||
gst_rtspsrc_loop_send_cmd (src, CMD_WAIT);
|
gst_rtspsrc_loop_send_cmd (src, CMD_WAIT);
|
||||||
gst_task_start (src->task);
|
gst_task_start (src->task);
|
||||||
|
|
||||||
|
done:
|
||||||
|
GST_RTSP_STATE_UNLOCK (src);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* ERRORS */
|
/* 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:
|
create_request_failed:
|
||||||
{
|
{
|
||||||
|
GST_RTSP_STATE_UNLOCK (src);
|
||||||
GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL),
|
GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL),
|
||||||
("Could not create request."));
|
("Could not create request."));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
send_error:
|
send_error:
|
||||||
{
|
{
|
||||||
|
GST_RTSP_STATE_UNLOCK (src);
|
||||||
rtsp_message_unset (&request);
|
rtsp_message_unset (&request);
|
||||||
GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL),
|
GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL),
|
||||||
("Could not send message."));
|
("Could not send message."));
|
||||||
|
@ -2936,10 +2983,16 @@ gst_rtspsrc_pause (GstRTSPSrc * src)
|
||||||
RTSPMessage response = { 0 };
|
RTSPMessage response = { 0 };
|
||||||
RTSPResult res;
|
RTSPResult res;
|
||||||
|
|
||||||
if (!(src->methods & RTSP_PAUSE))
|
GST_RTSP_STATE_LOCK (src);
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (src, "PAUSE...");
|
GST_DEBUG_OBJECT (src, "PAUSE...");
|
||||||
|
|
||||||
|
if (!(src->methods & RTSP_PAUSE))
|
||||||
|
goto not_supported;
|
||||||
|
|
||||||
|
if (src->state == RTSP_STATE_READY)
|
||||||
|
goto was_paused;
|
||||||
|
|
||||||
/* do pause */
|
/* do pause */
|
||||||
res = rtsp_message_init_request (&request, RTSP_PAUSE, src->req_location);
|
res = rtsp_message_init_request (&request, RTSP_PAUSE, src->req_location);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
|
@ -2951,17 +3004,34 @@ gst_rtspsrc_pause (GstRTSPSrc * src)
|
||||||
rtsp_message_unset (&request);
|
rtsp_message_unset (&request);
|
||||||
rtsp_message_unset (&response);
|
rtsp_message_unset (&response);
|
||||||
|
|
||||||
|
src->state = RTSP_STATE_READY;
|
||||||
|
|
||||||
|
done:
|
||||||
|
GST_RTSP_STATE_UNLOCK (src);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* ERRORS */
|
/* 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:
|
create_request_failed:
|
||||||
{
|
{
|
||||||
|
GST_RTSP_STATE_UNLOCK (src);
|
||||||
GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL),
|
GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL),
|
||||||
("Could not create request."));
|
("Could not create request."));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
send_error:
|
send_error:
|
||||||
{
|
{
|
||||||
|
GST_RTSP_STATE_UNLOCK (src);
|
||||||
rtsp_message_unset (&request);
|
rtsp_message_unset (&request);
|
||||||
GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL),
|
GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL),
|
||||||
("Could not send message."));
|
("Could not send message."));
|
||||||
|
|
|
@ -67,6 +67,10 @@ G_BEGIN_DECLS
|
||||||
typedef struct _GstRTSPSrc GstRTSPSrc;
|
typedef struct _GstRTSPSrc GstRTSPSrc;
|
||||||
typedef struct _GstRTSPSrcClass GstRTSPSrcClass;
|
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_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_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)))
|
#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 */
|
/* cond to signal loop */
|
||||||
GCond *loop_cond;
|
GCond *loop_cond;
|
||||||
gint loop_cmd;
|
gint loop_cmd;
|
||||||
|
GMutex *state_lock;
|
||||||
|
|
||||||
gint numstreams;
|
gint numstreams;
|
||||||
GList *streams;
|
GList *streams;
|
||||||
|
@ -141,6 +146,7 @@ struct _GstRTSPSrc {
|
||||||
guint latency;
|
guint latency;
|
||||||
|
|
||||||
/* state */
|
/* state */
|
||||||
|
RTSPState state;
|
||||||
gchar *content_base;
|
gchar *content_base;
|
||||||
RTSPLowerTrans cur_protocols;
|
RTSPLowerTrans cur_protocols;
|
||||||
gboolean tried_url_auth;
|
gboolean tried_url_auth;
|
||||||
|
|
|
@ -142,7 +142,6 @@ rtsp_connection_create (RTSPUrl * url, RTSPConnection ** conn)
|
||||||
newconn->fd = -1;
|
newconn->fd = -1;
|
||||||
newconn->cseq = 0;
|
newconn->cseq = 0;
|
||||||
newconn->session_id[0] = 0;
|
newconn->session_id[0] = 0;
|
||||||
newconn->state = RTSP_STATE_INIT;
|
|
||||||
|
|
||||||
newconn->auth_method = RTSP_AUTH_NONE;
|
newconn->auth_method = RTSP_AUTH_NONE;
|
||||||
newconn->username = NULL;
|
newconn->username = NULL;
|
||||||
|
@ -524,7 +523,7 @@ parse_line (gchar * buffer, RTSPMessage * msg)
|
||||||
/* read key */
|
/* read key */
|
||||||
read_key (key, sizeof (key), &bptr);
|
read_key (key, sizeof (key), &bptr);
|
||||||
if (*bptr != ':')
|
if (*bptr != ':')
|
||||||
return RTSP_EINVAL;
|
goto no_column;
|
||||||
|
|
||||||
bptr++;
|
bptr++;
|
||||||
|
|
||||||
|
@ -536,6 +535,11 @@ parse_line (gchar * buffer, RTSPMessage * msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
return RTSP_OK;
|
return RTSP_OK;
|
||||||
|
|
||||||
|
no_column:
|
||||||
|
{
|
||||||
|
return RTSP_EINVAL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RTSPResult
|
RTSPResult
|
||||||
|
|
|
@ -61,7 +61,6 @@ typedef struct _RTSPConnection
|
||||||
gint control_sock[2];
|
gint control_sock[2];
|
||||||
|
|
||||||
/* Session state */
|
/* Session state */
|
||||||
RTSPState state;
|
|
||||||
gint cseq; /* sequence number */
|
gint cseq; /* sequence number */
|
||||||
gchar session_id[512]; /* session id */
|
gchar session_id[512]; /* session id */
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue