gst/rtsp/gstrtspsrc.c: Improve flushing behaviour.

Original commit message from CVS:
* gst/rtsp/gstrtspsrc.c: (gst_rtspsrc_flush),
(gst_rtspsrc_perform_seek), (gst_rtspsrc_handle_src_event),
(gst_rtspsrc_handle_internal_src_query),
(gst_rtspsrc_handle_src_query), (new_session_pad),
(gst_rtspsrc_stream_configure_tcp),
(gst_rtspsrc_stream_configure_transport),
(gst_rtspsrc_loop_send_cmd):
Improve flushing behaviour.
Set state of the udp sources to PAUSE/PLAYING correctly.
Handle events and queries for UDP and TCP transport now.
This commit is contained in:
Wim Taymans 2007-10-05 13:18:19 +00:00
parent 11aaae270b
commit 7624f91497
2 changed files with 106 additions and 17 deletions

View file

@ -1,3 +1,16 @@
2007-10-05 Wim Taymans <wim.taymans@gmail.com>
* gst/rtsp/gstrtspsrc.c: (gst_rtspsrc_flush),
(gst_rtspsrc_perform_seek), (gst_rtspsrc_handle_src_event),
(gst_rtspsrc_handle_internal_src_query),
(gst_rtspsrc_handle_src_query), (new_session_pad),
(gst_rtspsrc_stream_configure_tcp),
(gst_rtspsrc_stream_configure_transport),
(gst_rtspsrc_loop_send_cmd):
Improve flushing behaviour.
Set state of the udp sources to PAUSE/PLAYING correctly.
Handle events and queries for UDP and TCP transport now.
2007-10-04 Stefan Kost <ensonic@users.sf.net> 2007-10-04 Stefan Kost <ensonic@users.sf.net>
* gst/rtp/gstrtpgsmdepay.c: * gst/rtp/gstrtpgsmdepay.c:

View file

@ -195,6 +195,8 @@ static GstStateChangeReturn gst_rtspsrc_change_state (GstElement * element,
GstStateChange transition); GstStateChange transition);
static void gst_rtspsrc_handle_message (GstBin * bin, GstMessage * message); static void gst_rtspsrc_handle_message (GstBin * bin, GstMessage * message);
static void gst_rtspsrc_loop_send_cmd (GstRTSPSrc * src, gint cmd,
gboolean flush);
static GstRTSPResult gst_rtspsrc_send_cb (GstRTSPExtension * ext, static GstRTSPResult gst_rtspsrc_send_cb (GstRTSPExtension * ext,
GstRTSPMessage * request, GstRTSPMessage * response, GstRTSPSrc * src); GstRTSPMessage * request, GstRTSPMessage * response, GstRTSPSrc * src);
@ -1119,17 +1121,34 @@ static void
gst_rtspsrc_flush (GstRTSPSrc * src, gboolean flush) gst_rtspsrc_flush (GstRTSPSrc * src, gboolean flush)
{ {
GstEvent *event; GstEvent *event;
gint cmd, i;
GstState state;
GList *walk;
if (flush) { if (flush) {
event = gst_event_new_flush_start (); event = gst_event_new_flush_start ();
GST_DEBUG_OBJECT (src, "start flush"); GST_DEBUG_OBJECT (src, "start flush");
cmd = CMD_STOP;
state = GST_STATE_PAUSED;
} else { } else {
event = gst_event_new_flush_stop (); event = gst_event_new_flush_stop ();
GST_DEBUG_OBJECT (src, "stop flush"); GST_DEBUG_OBJECT (src, "stop flush");
cmd = CMD_WAIT;
state = GST_STATE_PLAYING;
} }
gst_rtsp_connection_flush (src->connection, flush);
gst_rtspsrc_push_event (src, event); gst_rtspsrc_push_event (src, event);
gst_rtspsrc_loop_send_cmd (src, cmd, flush);
/* */
for (walk = src->streams; walk; walk = g_list_next (walk)) {
GstRTSPStream *stream = (GstRTSPStream *) walk->data;
for (i = 0; i < 2; i++) {
if (stream->udpsrc[i]) {
gst_element_set_state (stream->udpsrc[i], state);
}
}
}
} }
static GstRTSPResult static GstRTSPResult
@ -1219,12 +1238,17 @@ gst_rtspsrc_perform_seek (GstRTSPSrc * src, GstEvent * event)
GST_DEBUG_OBJECT (src, "starting flush"); GST_DEBUG_OBJECT (src, "starting flush");
gst_rtspsrc_flush (src, TRUE); gst_rtspsrc_flush (src, TRUE);
} else { } else {
//gst_pad_pause_task (src->sinkpad); if (src->task) {
gst_task_pause (src->task);
}
} }
/* we should now be able to grab the streaming thread because we stopped it /* we should now be able to grab the streaming thread because we stopped it
* with the above flush/pause code */ * with the above flush/pause code */
//GST_PAD_STREAM_LOCK (src->sinkpad); GST_RTSP_STREAM_LOCK (src);
/* stop flushing state */
gst_rtspsrc_loop_send_cmd (src, CMD_WAIT, FALSE);
/* save current position */ /* save current position */
last_stop = src->segment.last_stop; last_stop = src->segment.last_stop;
@ -1299,13 +1323,7 @@ gst_rtspsrc_perform_seek (GstRTSPSrc * src, GstEvent * event)
GST_DEBUG_OBJECT (src, "mark DISCONT, we did a seek to another position"); GST_DEBUG_OBJECT (src, "mark DISCONT, we did a seek to another position");
//src->discont = TRUE; //src->discont = TRUE;
} }
GST_RTSP_STREAM_UNLOCK (src);
/* and start the streaming task again */
src->running = TRUE;
//gst_pad_start_task (src->sinkpad, (GstTaskFunction) gst_srcparse_loop,
// src->sinkpad);
//GST_PAD_STREAM_UNLOCK (src->sinkpad);
return TRUE; return TRUE;
@ -1328,7 +1346,7 @@ gst_rtspsrc_handle_src_event (GstPad * pad, GstEvent * event)
GstRTSPSrc *src; GstRTSPSrc *src;
gboolean res = FALSE; gboolean res = FALSE;
src = GST_RTSPSRC_CAST (gst_pad_get_element_private (pad)); src = GST_RTSPSRC_CAST (gst_pad_get_parent (pad));
GST_DEBUG_OBJECT (src, "pad %s:%s received event %s", GST_DEBUG_OBJECT (src, "pad %s:%s received event %s",
GST_DEBUG_PAD_NAME (pad), GST_EVENT_TYPE_NAME (event)); GST_DEBUG_PAD_NAME (pad), GST_EVENT_TYPE_NAME (event));
@ -1346,11 +1364,15 @@ gst_rtspsrc_handle_src_event (GstPad * pad, GstEvent * event)
default: default:
break; break;
} }
gst_object_unref (src);
return res; return res;
} }
/* this is the final query function we receive on the internal source pad when
* we deal with TCP connections */
static gboolean static gboolean
gst_rtspsrc_handle_src_query (GstPad * pad, GstQuery * query) gst_rtspsrc_handle_internal_src_query (GstPad * pad, GstQuery * query)
{ {
GstRTSPSrc *src; GstRTSPSrc *src;
gboolean res = TRUE; gboolean res = TRUE;
@ -1363,6 +1385,7 @@ gst_rtspsrc_handle_src_query (GstPad * pad, GstQuery * query)
switch (GST_QUERY_TYPE (query)) { switch (GST_QUERY_TYPE (query)) {
case GST_QUERY_POSITION: case GST_QUERY_POSITION:
{ {
/* no idea */
break; break;
} }
case GST_QUERY_DURATION: case GST_QUERY_DURATION:
@ -1383,7 +1406,8 @@ gst_rtspsrc_handle_src_query (GstPad * pad, GstQuery * query)
} }
case GST_QUERY_LATENCY: case GST_QUERY_LATENCY:
{ {
/* we are live with a min latency of 0 and unlimited max latency */ /* we are live with a min latency of 0 and unlimited max latency, this
* result will be updated by the session manager if there is any. */
gst_query_set_latency (query, TRUE, 0, -1); gst_query_set_latency (query, TRUE, 0, -1);
break; break;
} }
@ -1394,6 +1418,52 @@ gst_rtspsrc_handle_src_query (GstPad * pad, GstQuery * query)
return res; return res;
} }
/* this query is executed on the ghost source pad exposed on rtspsrc. */
static gboolean
gst_rtspsrc_handle_src_query (GstPad * pad, GstQuery * query)
{
GstRTSPSrc *src;
gboolean res = FALSE;
src = GST_RTSPSRC_CAST (gst_pad_get_parent (pad));
GST_DEBUG_OBJECT (src, "pad %s:%s received query %s",
GST_DEBUG_PAD_NAME (pad), GST_QUERY_TYPE_NAME (query));
switch (GST_QUERY_TYPE (query)) {
case GST_QUERY_DURATION:
{
GstFormat format;
gst_query_parse_duration (query, &format, NULL);
switch (format) {
case GST_FORMAT_TIME:
gst_query_set_duration (query, format, src->segment.duration);
res = TRUE;
break;
default:
break;
}
break;
}
default:
{
GstPad *target = gst_ghost_pad_get_target (GST_GHOST_PAD_CAST (pad));
/* forward the query to the proxy target pad */
if (target) {
res = gst_pad_query (target, query);
gst_object_unref (target);
}
break;
}
}
gst_object_unref (src);
return res;
}
/* callback for RTCP messages to be sent to the server when operating in TCP /* callback for RTCP messages to be sent to the server when operating in TCP
* mode. */ * mode. */
static GstFlowReturn static GstFlowReturn
@ -1497,6 +1567,8 @@ new_session_pad (GstElement * session, GstPad * pad, GstRTSPSrc * src)
g_free (name); g_free (name);
stream->added = TRUE; stream->added = TRUE;
gst_pad_set_event_function (stream->srcpad, gst_rtspsrc_handle_src_event);
gst_pad_set_query_function (stream->srcpad, gst_rtspsrc_handle_src_query);
gst_pad_set_active (stream->srcpad, TRUE); gst_pad_set_active (stream->srcpad, TRUE);
gst_element_add_pad (GST_ELEMENT_CAST (src), stream->srcpad); gst_element_add_pad (GST_ELEMENT_CAST (src), stream->srcpad);
@ -1764,12 +1836,11 @@ gst_rtspsrc_stream_configure_tcp (GstRTSPSrc * src, GstRTSPStream * stream,
/* allocate pads for sending the channel data into the manager */ /* allocate pads for sending the channel data into the manager */
pad0 = gst_pad_new_from_template (template, "internalsrc0"); pad0 = gst_pad_new_from_template (template, "internalsrc0");
gst_pad_set_event_function (pad0, gst_rtspsrc_handle_src_event);
gst_pad_set_query_function (pad0, gst_rtspsrc_handle_src_query);
gst_pad_link (pad0, stream->channelpad[0]); gst_pad_link (pad0, stream->channelpad[0]);
stream->channelpad[0] = pad0; stream->channelpad[0] = pad0;
gst_pad_set_active (pad0, TRUE); gst_pad_set_query_function (pad0, gst_rtspsrc_handle_internal_src_query);
gst_pad_set_element_private (pad0, src); gst_pad_set_element_private (pad0, src);
gst_pad_set_active (pad0, TRUE);
if (stream->channelpad[1]) { if (stream->channelpad[1]) {
/* if we have a sinkpad for the other channel, create a pad and link to the /* if we have a sinkpad for the other channel, create a pad and link to the
@ -2066,6 +2137,8 @@ gst_rtspsrc_stream_configure_transport (GstRTSPStream * stream,
name = g_strdup_printf ("stream%d", stream->id); name = g_strdup_printf ("stream%d", stream->id);
template = gst_static_pad_template_get (&rtptemplate); template = gst_static_pad_template_get (&rtptemplate);
stream->srcpad = gst_ghost_pad_new_from_template (name, outpad, template); stream->srcpad = gst_ghost_pad_new_from_template (name, outpad, template);
gst_pad_set_event_function (stream->srcpad, gst_rtspsrc_handle_src_event);
gst_pad_set_query_function (stream->srcpad, gst_rtspsrc_handle_src_query);
gst_object_unref (template); gst_object_unref (template);
g_free (name); g_free (name);
@ -2773,6 +2846,9 @@ gst_rtspsrc_loop_send_cmd (GstRTSPSrc * src, gint cmd, gboolean flush)
if (flush) { if (flush) {
GST_DEBUG_OBJECT (src, "start connection flush"); GST_DEBUG_OBJECT (src, "start connection flush");
gst_rtsp_connection_flush (src->connection, TRUE); gst_rtsp_connection_flush (src->connection, TRUE);
} else {
GST_DEBUG_OBJECT (src, "stop connection flush");
gst_rtsp_connection_flush (src->connection, FALSE);
} }
GST_OBJECT_UNLOCK (src); GST_OBJECT_UNLOCK (src);
} }