diff options
author | Wim Taymans <wim.taymans@gmail.com> | 2006-09-18 14:00:41 +0000 |
---|---|---|
committer | Wim Taymans <wim.taymans@gmail.com> | 2006-09-18 14:00:41 +0000 |
commit | 108dbd54cf14a3c8622064cf66237b1b666da284 (patch) | |
tree | 4a1b69299ba0e19bf9b7cb9e8350cd94f4af4938 /gst | |
parent | cac807b641796e00d21a82e8704cbdf3992bedcb (diff) |
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.
Diffstat (limited to 'gst')
-rw-r--r-- | gst/rtsp/gstrtspsrc.c | 85 | ||||
-rw-r--r-- | gst/rtsp/gstrtspsrc.h | 2 |
2 files changed, 68 insertions, 19 deletions
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 */ @@ -802,6 +802,22 @@ done: } 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) { RTSPMessage response = { 0 }; @@ -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; |