summaryrefslogtreecommitdiffstats
path: root/gst
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@gmail.com>2007-05-18 10:36:12 +0000
committerWim Taymans <wim.taymans@gmail.com>2007-05-18 10:36:12 +0000
commite4720e286ca217afdf43996ebe7e44c2aeab932c (patch)
tree3d4f057cfb00f190df0e2c55015d5a3f4e04b476 /gst
parentccd7a136a92b43a94d3db61565352be0a59e3014 (diff)
gst/rtsp/gstrtspsrc.c: Refactor timeout handling.
Original commit message from CVS: * gst/rtsp/gstrtspsrc.c: (gst_rtspsrc_send_keep_alive), (gst_rtspsrc_loop_interleaved), (gst_rtspsrc_loop_udp), (gst_rtspsrc_try_send), (gst_rtspsrc_send), (gst_rtspsrc_setup_streams): Refactor timeout handling. Also send keep-alive when dealing with TCP transport. * gst/rtsp/rtspconnection.c: (rtsp_connection_create), (rtsp_connection_free), (rtsp_connection_next_timeout), (rtsp_connection_reset_timeout): * gst/rtsp/rtspconnection.h: Use a timer to handle the session timeouts, add some methods to deal with timeouts.
Diffstat (limited to 'gst')
-rw-r--r--gst/rtsp/gstrtspsrc.c146
-rw-r--r--gst/rtsp/rtspconnection.c36
-rw-r--r--gst/rtsp/rtspconnection.h11
3 files changed, 130 insertions, 63 deletions
diff --git a/gst/rtsp/gstrtspsrc.c b/gst/rtsp/gstrtspsrc.c
index 15861713..d7743a98 100644
--- a/gst/rtsp/gstrtspsrc.c
+++ b/gst/rtsp/gstrtspsrc.c
@@ -2079,6 +2079,47 @@ send_error:
}
}
+/* send server keep-alive */
+static RTSPResult
+gst_rtspsrc_send_keep_alive (GstRTSPSrc * src)
+{
+ RTSPMessage request = { 0 };
+ RTSPResult res;
+ RTSPMethod method;
+
+ GST_DEBUG_OBJECT (src, "creating server keep-alive");
+
+ /* find a method to use for keep-alive */
+ if (src->methods & RTSP_GET_PARAMETER)
+ method = RTSP_GET_PARAMETER;
+ else
+ method = RTSP_OPTIONS;
+
+ res = rtsp_message_init_request (&request, method, src->req_location);
+ if (res < 0)
+ goto send_error;
+
+ if ((res = rtsp_connection_send (src->connection, &request, NULL)) < 0)
+ goto send_error;
+
+ rtsp_connection_reset_timeout (src->connection);
+ rtsp_message_unset (&request);
+
+ return RTSP_OK;
+
+ /* ERRORS */
+send_error:
+ {
+ gchar *str = rtsp_strresult (res);
+
+ rtsp_message_unset (&request);
+ GST_ELEMENT_WARNING (src, RESOURCE, WRITE, (NULL),
+ ("Could not send keep-alive. (%s)", str));
+ g_free (str);
+ return res;
+ }
+}
+
static void
gst_rtspsrc_loop_interleaved (GstRTSPSrc * src)
{
@@ -2096,10 +2137,35 @@ gst_rtspsrc_loop_interleaved (GstRTSPSrc * src)
have_data = FALSE;
do {
+ GTimeVal tv_timeout;
+
+ /* get the next timeout interval */
+ rtsp_connection_next_timeout (src->connection, &tv_timeout);
+
+ /* see if the timeout period expired */
+ if ((tv_timeout.tv_usec | tv_timeout.tv_usec) == 0) {
+ GST_DEBUG_OBJECT (src, "timout, sending keep-alive");
+ /* send keep-alive, ignore the result, a warning will be posted. */
+ res = gst_rtspsrc_send_keep_alive (src);
+ }
+
GST_DEBUG_OBJECT (src, "doing receive");
- if ((res = rtsp_connection_receive (src->connection, &message, NULL)) < 0)
- goto receive_error;
+ res = rtsp_connection_receive (src->connection, &message, NULL);
+
+ switch (res) {
+ case RTSP_OK:
+ GST_DEBUG_OBJECT (src, "we received a server message");
+ break;
+ case RTSP_EINTR:
+ /* we got interrupted, see what we have to do */
+ GST_DEBUG_OBJECT (src, "we got interrupted, unset flushing");
+ /* unset flushing so we can do something else */
+ rtsp_connection_flush (src->connection, FALSE);
+ goto interrupt;
+ default:
+ goto receive_error;
+ }
switch (message.type) {
case RTSP_MESSAGE_REQUEST:
@@ -2200,6 +2266,13 @@ unknown_stream:
rtsp_message_unset (&message);
return;
}
+interrupt:
+ {
+ GST_DEBUG_OBJECT (src, "we got interrupted");
+ rtsp_message_unset (&message);
+ ret = GST_FLOW_WRONG_STATE;
+ goto need_pause;
+ }
receive_error:
{
gchar *str = rtsp_strresult (res);
@@ -2260,49 +2333,6 @@ need_pause:
}
}
-/* send server keep-alive */
-static RTSPResult
-gst_rtspsrc_send_keep_alive (GstRTSPSrc * src)
-{
- RTSPMessage request = { 0 };
- RTSPMessage response = { 0 };
- RTSPResult res;
- RTSPStatusCode code;
- RTSPMethod method;
-
- GST_DEBUG_OBJECT (src, "creating server keep-alive");
-
- /* find a method to use for keep-alive */
- if (src->methods & RTSP_GET_PARAMETER)
- method = RTSP_GET_PARAMETER;
- else
- method = RTSP_OPTIONS;
-
- res = rtsp_message_init_request (&request, method, src->req_location);
- if (res < 0)
- goto send_error;
-
- /* let us handle the error code because we don't care */
- if ((res = gst_rtspsrc_send (src, &request, &response, &code)) < 0)
- goto send_error;
-
- rtsp_message_unset (&request);
-
- return RTSP_OK;
-
- /* ERRORS */
-send_error:
- {
- gchar *str = rtsp_strresult (res);
-
- rtsp_message_unset (&request);
- GST_ELEMENT_WARNING (src, RESOURCE, WRITE, (NULL),
- ("Could not send keep-alive. (%s)", str));
- g_free (str);
- return res;
- }
-}
-
static void
gst_rtspsrc_loop_udp (GstRTSPSrc * src)
{
@@ -2314,26 +2344,17 @@ gst_rtspsrc_loop_udp (GstRTSPSrc * src)
goto stopping;
while (src->loop_cmd == CMD_WAIT) {
- GTimeVal tv_timeout;
- gint timeout;
-
GST_OBJECT_UNLOCK (src);
while (TRUE) {
RTSPMessage message = { 0 };
+ GTimeVal tv_timeout;
- /* calculate the session timeout. We should send the keep-alive request a
- * little earlier to compensate for the round trip time to the server. We
- * subtract 1 second here. */
- timeout = src->connection->timeout;
- if (timeout > 1)
- timeout -= 1;
-
- /* use the session timeout for receiving data */
- tv_timeout.tv_sec = timeout;
- tv_timeout.tv_usec = 0;
+ /* get the next timeout interval */
+ rtsp_connection_next_timeout (src->connection, &tv_timeout);
- GST_DEBUG_OBJECT (src, "doing receive with timeout %d seconds", timeout);
+ GST_DEBUG_OBJECT (src, "doing receive with timeout %d seconds",
+ tv_timeout.tv_sec);
/* we should continue reading the TCP socket because the server might
* send us requests. When the session timeout expires, we need to send a
@@ -2366,9 +2387,12 @@ gst_rtspsrc_loop_udp (GstRTSPSrc * src)
goto handle_request_failed;
break;
case RTSP_MESSAGE_RESPONSE:
+ /* we ignore response and data messages */
+ GST_DEBUG_OBJECT (src, "ignoring response message");
+ break;
case RTSP_MESSAGE_DATA:
/* we ignore response and data messages */
- GST_DEBUG_OBJECT (src, "ignoring message");
+ GST_DEBUG_OBJECT (src, "ignoring data message");
break;
default:
GST_WARNING_OBJECT (src, "ignoring unknown message type %d",
@@ -2673,6 +2697,8 @@ gst_rtspsrc_try_send (GstRTSPSrc * src, RTSPMessage * request,
if ((res = rtsp_connection_send (src->connection, request, NULL)) < 0)
goto send_error;
+ rtsp_connection_reset_timeout (src->connection);
+
next:
if ((res = rtsp_connection_receive (src->connection, response, NULL)) < 0)
goto receive_error;
diff --git a/gst/rtsp/rtspconnection.c b/gst/rtsp/rtspconnection.c
index d806b50a..cb81c72c 100644
--- a/gst/rtsp/rtspconnection.c
+++ b/gst/rtsp/rtspconnection.c
@@ -142,6 +142,7 @@ rtsp_connection_create (RTSPUrl * url, RTSPConnection ** conn)
newconn->fd = -1;
newconn->cseq = 0;
newconn->session_id[0] = 0;
+ newconn->timer = g_timer_new ();
newconn->auth_method = RTSP_AUTH_NONE;
newconn->username = NULL;
@@ -900,6 +901,7 @@ rtsp_connection_free (RTSPConnection * conn)
WSACleanup ();
#endif
+ g_timer_destroy (conn->timer);
g_free (conn->username);
g_free (conn->passwd);
@@ -909,6 +911,40 @@ rtsp_connection_free (RTSPConnection * conn)
}
RTSPResult
+rtsp_connection_next_timeout (RTSPConnection * conn, GTimeVal * timeout)
+{
+ gdouble elapsed;
+ glong sec;
+ gulong usec;
+
+ g_return_val_if_fail (conn != NULL, RTSP_EINVAL);
+ g_return_val_if_fail (timeout != NULL, RTSP_EINVAL);
+
+ elapsed = g_timer_elapsed (conn->timer, &usec);
+ if (elapsed >= conn->timeout) {
+ sec = 0;
+ usec = 0;
+ } else {
+ sec = conn->timeout - elapsed;
+ }
+
+ timeout->tv_sec = sec;
+ timeout->tv_usec = usec;
+
+ return RTSP_OK;
+}
+
+RTSPResult
+rtsp_connection_reset_timeout (RTSPConnection * conn)
+{
+ g_return_val_if_fail (conn != NULL, RTSP_EINVAL);
+
+ g_timer_start (conn->timer);
+
+ return RTSP_OK;
+}
+
+RTSPResult
rtsp_connection_flush (RTSPConnection * conn, gboolean flush)
{
g_return_val_if_fail (conn != NULL, RTSP_EINVAL);
diff --git a/gst/rtsp/rtspconnection.h b/gst/rtsp/rtspconnection.h
index b2fcd072..28272587 100644
--- a/gst/rtsp/rtspconnection.h
+++ b/gst/rtsp/rtspconnection.h
@@ -65,11 +65,12 @@ typedef struct _RTSPConnection
gint cseq; /* sequence number */
gchar session_id[512]; /* session id */
gint timeout; /* session timeout in seconds */
+ GTimer *timer; /* timeout timer */
/* Authentication */
- RTSPAuthMethod auth_method;
- gchar *username;
- gchar *passwd;
+ RTSPAuthMethod auth_method;
+ gchar *username;
+ gchar *passwd;
} RTSPConnection;
/* opening/closing a connection */
@@ -88,6 +89,10 @@ RTSPResult rtsp_connection_write (RTSPConnection * conn, const guint8 *
RTSPResult rtsp_connection_send (RTSPConnection *conn, RTSPMessage *message, GTimeVal *timeout);
RTSPResult rtsp_connection_receive (RTSPConnection *conn, RTSPMessage *message, GTimeVal *timeout);
+/* reset the timeout */
+RTSPResult rtsp_connection_next_timeout (RTSPConnection *conn, GTimeVal *timeout);
+RTSPResult rtsp_connection_reset_timeout (RTSPConnection *conn);
+
/* flushing state */
RTSPResult rtsp_connection_flush (RTSPConnection *conn, gboolean flush);