diff options
author | Vivia Nikolaidou <vivia@toolsonair.com> | 2015-05-29 16:02:31 +0300 |
---|---|---|
committer | Jan Schmidt <jan@centricular.com> | 2015-05-30 00:25:37 +1000 |
commit | fba7c97135ee8279ebf16f31faef7ca320252867 (patch) | |
tree | 2d9d9f1ba74ec854f5e5f801d969cc0611265925 /ext/rtmp | |
parent | 53451500ee70d63ce961afc8837ce1215cbb5611 (diff) | |
download | gstreamer-plugins-bad-fba7c97135ee8279ebf16f31faef7ca320252867.tar.gz |
rtmpsink: Do not crash when receiving buffers after GST_FLOW_ERROR
If the RTMP URI is invalid, the rtmpsink will return GST_FLOW_ERROR.
If it still receives buffers after that, it shouldn't crash.
https://bugzilla.gnome.org/show_bug.cgi?id=750104
Diffstat (limited to 'ext/rtmp')
-rw-r--r-- | ext/rtmp/gstrtmpsink.c | 34 | ||||
-rw-r--r-- | ext/rtmp/gstrtmpsink.h | 1 |
2 files changed, 34 insertions, 1 deletions
diff --git a/ext/rtmp/gstrtmpsink.c b/ext/rtmp/gstrtmpsink.c index 0e2e8501e..6886a89ff 100644 --- a/ext/rtmp/gstrtmpsink.c +++ b/ext/rtmp/gstrtmpsink.c @@ -75,6 +75,7 @@ static void gst_rtmp_sink_get_property (GObject * object, guint prop_id, static void gst_rtmp_sink_finalize (GObject * object); static gboolean gst_rtmp_sink_stop (GstBaseSink * sink); static gboolean gst_rtmp_sink_start (GstBaseSink * sink); +static gboolean gst_rtmp_sink_event (GstBaseSink * sink, GstEvent * event); static GstFlowReturn gst_rtmp_sink_render (GstBaseSink * sink, GstBuffer * buf); #define gst_rtmp_sink_parent_class parent_class @@ -113,6 +114,7 @@ gst_rtmp_sink_class_init (GstRTMPSinkClass * klass) gstbasesink_class->start = GST_DEBUG_FUNCPTR (gst_rtmp_sink_start); gstbasesink_class->stop = GST_DEBUG_FUNCPTR (gst_rtmp_sink_stop); gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_rtmp_sink_render); + gstbasesink_class->event = gst_rtmp_sink_event; GST_DEBUG_CATEGORY_INIT (gst_rtmp_sink_debug, "rtmpsink", 0, "RTMP server element"); @@ -177,6 +179,7 @@ gst_rtmp_sink_start (GstBaseSink * basesink) RTMP_EnableWrite (sink->rtmp); sink->first = TRUE; + sink->have_write_error = FALSE; return TRUE; } @@ -208,6 +211,12 @@ gst_rtmp_sink_render (GstBaseSink * bsink, GstBuffer * buf) GstBuffer *reffed_buf = NULL; GstMapInfo map; + if (sink->rtmp == NULL) { + /* Do not crash */ + GST_ELEMENT_ERROR (sink, RESOURCE, WRITE, (NULL), ("Failed to write data")); + return GST_FLOW_ERROR; + } + if (sink->first) { /* open the connection */ if (!RTMP_IsConnected (sink->rtmp)) { @@ -219,6 +228,7 @@ gst_rtmp_sink_render (GstBaseSink * bsink, GstBuffer * buf) sink->rtmp = NULL; g_free (sink->rtmp_uri); sink->rtmp_uri = NULL; + sink->have_write_error = TRUE; return GST_FLOW_ERROR; } GST_DEBUG_OBJECT (sink, "Opened connection to %s", sink->rtmp_uri); @@ -241,6 +251,9 @@ gst_rtmp_sink_render (GstBaseSink * bsink, GstBuffer * buf) sink->cache = NULL; } + if (sink->have_write_error) + goto write_failed; + GST_LOG_OBJECT (sink, "Sending %" G_GSIZE_FORMAT " bytes to RTMP server", gst_buffer_get_size (buf)); @@ -262,6 +275,7 @@ write_failed: gst_buffer_unmap (buf, &map); if (reffed_buf) gst_buffer_unref (reffed_buf); + sink->have_write_error = TRUE; return GST_FLOW_ERROR; } } @@ -330,8 +344,10 @@ gst_rtmp_sink_uri_set_uri (GstURIHandler * handler, const gchar * uri, free (playpath.av_val); } - if (ret) + if (ret) { + sink->have_write_error = FALSE; GST_DEBUG_OBJECT (sink, "Changed URI to %s", GST_STR_NULL (uri)); + } return ret; } @@ -364,6 +380,22 @@ gst_rtmp_sink_set_property (GObject * object, guint prop_id, } } +static gboolean +gst_rtmp_sink_event (GstBaseSink * sink, GstEvent * event) +{ + GstRTMPSink *rtmpsink = GST_RTMP_SINK (sink); + + switch (event->type) { + case GST_EVENT_FLUSH_STOP: + rtmpsink->have_write_error = FALSE; + break; + default: + break; + } + + return GST_BASE_SINK_CLASS (parent_class)->event (sink, event); +} + static void gst_rtmp_sink_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) diff --git a/ext/rtmp/gstrtmpsink.h b/ext/rtmp/gstrtmpsink.h index d89b0a41c..523f5ae0a 100644 --- a/ext/rtmp/gstrtmpsink.h +++ b/ext/rtmp/gstrtmpsink.h @@ -55,6 +55,7 @@ struct _GstRTMPSink { GstBuffer *cache; /* Cached buffer */ gboolean first; + gboolean have_write_error; }; struct _GstRTMPSinkClass { |