From 108dbd54cf14a3c8622064cf66237b1b666da284 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 18 Sep 2006 14:00:41 +0000 Subject: gst/rtsp/gstrtspsrc.*: Export sometimes source pad with correct caps on the template, create the ghostpad from the te... Original commit message from CVS: * gst/rtsp/gstrtspsrc.c: (gst_rtspsrc_base_init), (gst_rtspsrc_stream_configure_transport), (gst_rtspsrc_push_event), (gst_rtspsrc_loop), (gst_rtspsrc_uri_set_uri): * gst/rtsp/gstrtspsrc.h: Export sometimes source pad with correct caps on the template, create the ghostpad from the template. Remove RTCP template as we never expose RTCP. Protect against invalid body size. Avoid memcpy when creating the output buffer. Properly post an error and send EOS when the loop function is shut down. --- gst/rtsp/gstrtspsrc.c | 85 +++++++++++++++++++++++++++++++++++++++------------ gst/rtsp/gstrtspsrc.h | 2 ++ 2 files changed, 68 insertions(+), 19 deletions(-) (limited to 'gst') diff --git a/gst/rtsp/gstrtspsrc.c b/gst/rtsp/gstrtspsrc.c index 3d29815c..1353852c 100644 --- a/gst/rtsp/gstrtspsrc.c +++ b/gst/rtsp/gstrtspsrc.c @@ -86,13 +86,7 @@ static GstStaticPadTemplate rtptemplate = GST_STATIC_PAD_TEMPLATE ("rtp_stream%d", GST_PAD_SRC, GST_PAD_SOMETIMES, - GST_STATIC_CAPS_ANY); - -static GstStaticPadTemplate rtcptemplate = -GST_STATIC_PAD_TEMPLATE ("rtcp_stream%d", - GST_PAD_SRC, - GST_PAD_SOMETIMES, - GST_STATIC_CAPS_ANY); + GST_STATIC_CAPS ("application/x-rtp")); enum { @@ -178,8 +172,6 @@ gst_rtspsrc_base_init (gpointer g_class) gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&rtptemplate)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&rtcptemplate)); gst_element_class_set_details (element_class, &gst_rtspsrc_details); } @@ -649,7 +641,8 @@ gst_rtspsrc_stream_configure_transport (GstRTSPStream * stream, SDPMedia * media, RTSPTransport * transport) { GstRTSPSrc *src; - GstPad *pad; + GstPad *pad, *gpad; + GstPadTemplate *template; GstStateChangeReturn ret; gchar *name; @@ -736,11 +729,18 @@ gst_rtspsrc_stream_configure_transport (GstRTSPStream * stream, gst_pad_use_fixed_caps (pad); gst_pad_set_caps (pad, stream->caps); } + + /* create ghostpad */ name = g_strdup_printf ("rtp_stream%d", stream->id); - gst_element_add_pad (GST_ELEMENT_CAST (src), gst_ghost_pad_new (name, pad)); + template = gst_static_pad_template_get (&rtptemplate); + gpad = gst_ghost_pad_new_from_template (name, pad, template); + gst_object_unref (template); g_free (name); + gst_object_unref (pad); + gst_element_add_pad (GST_ELEMENT_CAST (src), gpad); + return TRUE; /* ERRORS */ @@ -801,6 +801,22 @@ done: return ret; } +static void +gst_rtspsrc_push_event (GstRTSPSrc * src, GstEvent * event) +{ + GList *streams; + + for (streams = src->streams; streams; streams = g_list_next (streams)) { + GstRTSPStream *ostream = (GstRTSPStream *) streams->data; + + gst_event_ref (event); + gst_pad_push_event (ostream->rtpdecrtp, event); + gst_event_ref (event); + gst_pad_push_event (ostream->rtpdecrtcp, event); + } + gst_event_unref (event); +} + static void gst_rtspsrc_loop (GstRTSPSrc * src) { @@ -838,7 +854,10 @@ gst_rtspsrc_loop (GstRTSPSrc * src) outpad = stream->rtpdecrtcp; } + /* take a look at the body to figure out what we have */ rtsp_message_get_body (&response, &data, &size); + if (size < 2) + goto invalid_length; /* channels are not correct on some servers, do extra check */ if (data[1] >= 200 && data[1] <= 204) { @@ -854,11 +873,15 @@ gst_rtspsrc_loop (GstRTSPSrc * src) { GstBuffer *buf; + rtsp_message_steal_body (&response, &data, &size); + /* strip the trailing \0 */ size -= 1; buf = gst_buffer_new_and_alloc (size); - memcpy (GST_BUFFER_DATA (buf), data, size); + GST_BUFFER_DATA (buf) = data; + GST_BUFFER_MALLOCDATA (buf) = data; + GST_BUFFER_SIZE (buf) = size; if (caps) gst_buffer_set_caps (buf, caps); @@ -869,7 +892,7 @@ gst_rtspsrc_loop (GstRTSPSrc * src) /* chain to the peer pad */ ret = gst_pad_chain (outpad, buf); - /* combine all streams */ + /* combine all stream flows */ ret = gst_rtspsrc_combine_flows (src, stream, ret); if (ret != GST_FLOW_OK) goto need_pause; @@ -884,19 +907,43 @@ unknown_stream: } receive_error: { - GST_ELEMENT_ERROR (src, RESOURCE, WRITE, + GST_ELEMENT_ERROR (src, RESOURCE, READ, ("Could not receive message."), (NULL)); ret = GST_FLOW_UNEXPECTED; - /* - gst_pad_push_event (src->srcpad, gst_event_new (GST_EVENT_EOS)); - */ goto need_pause; } +invalid_length: + { + GST_ELEMENT_WARNING (src, RESOURCE, READ, + ("Short message received."), (NULL)); + return; + } need_pause: { - GST_DEBUG_OBJECT (src, "pausing task, reason %d (%s)", ret, - gst_flow_get_name (ret)); + const gchar *reason = gst_flow_get_name (ret); + + GST_DEBUG_OBJECT (src, "pausing task, reason %s", reason); + src->running = FALSE; gst_task_pause (src->task); + if (GST_FLOW_IS_FATAL (ret) || ret == GST_FLOW_NOT_LINKED) { + if (ret == GST_FLOW_UNEXPECTED) { + /* perform EOS logic */ + if (src->segment.flags & GST_SEEK_FLAG_SEGMENT) { + gst_element_post_message (GST_ELEMENT_CAST (src), + gst_message_new_segment_done (GST_OBJECT_CAST (src), + src->segment.format, src->segment.last_stop)); + } else { + gst_rtspsrc_push_event (src, gst_event_new_eos ()); + } + } else { + /* for fatal errors we post an error message, post the error + * first so the app knows about the error first. */ + GST_ELEMENT_ERROR (src, STREAM, FAILED, + ("Internal data flow error."), + ("streaming task paused, reason %s (%d)", reason, ret)); + gst_rtspsrc_push_event (src, gst_event_new_eos ()); + } + } return; } } diff --git a/gst/rtsp/gstrtspsrc.h b/gst/rtsp/gstrtspsrc.h index 2731e080..73267edd 100644 --- a/gst/rtsp/gstrtspsrc.h +++ b/gst/rtsp/gstrtspsrc.h @@ -91,6 +91,8 @@ struct _GstRTSPSrc { gboolean interleaved; GstTask *task; GStaticRecMutex *stream_rec_lock; + GstSegment segment; + gboolean running; gint numstreams; GList *streams; -- cgit