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
This commit is contained in:
parent
53451500ee
commit
fba7c97135
@ -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 void gst_rtmp_sink_finalize (GObject * object);
|
||||||
static gboolean gst_rtmp_sink_stop (GstBaseSink * sink);
|
static gboolean gst_rtmp_sink_stop (GstBaseSink * sink);
|
||||||
static gboolean gst_rtmp_sink_start (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);
|
static GstFlowReturn gst_rtmp_sink_render (GstBaseSink * sink, GstBuffer * buf);
|
||||||
|
|
||||||
#define gst_rtmp_sink_parent_class parent_class
|
#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->start = GST_DEBUG_FUNCPTR (gst_rtmp_sink_start);
|
||||||
gstbasesink_class->stop = GST_DEBUG_FUNCPTR (gst_rtmp_sink_stop);
|
gstbasesink_class->stop = GST_DEBUG_FUNCPTR (gst_rtmp_sink_stop);
|
||||||
gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_rtmp_sink_render);
|
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,
|
GST_DEBUG_CATEGORY_INIT (gst_rtmp_sink_debug, "rtmpsink", 0,
|
||||||
"RTMP server element");
|
"RTMP server element");
|
||||||
@ -177,6 +179,7 @@ gst_rtmp_sink_start (GstBaseSink * basesink)
|
|||||||
RTMP_EnableWrite (sink->rtmp);
|
RTMP_EnableWrite (sink->rtmp);
|
||||||
|
|
||||||
sink->first = TRUE;
|
sink->first = TRUE;
|
||||||
|
sink->have_write_error = FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -208,6 +211,12 @@ gst_rtmp_sink_render (GstBaseSink * bsink, GstBuffer * buf)
|
|||||||
GstBuffer *reffed_buf = NULL;
|
GstBuffer *reffed_buf = NULL;
|
||||||
GstMapInfo map;
|
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) {
|
if (sink->first) {
|
||||||
/* open the connection */
|
/* open the connection */
|
||||||
if (!RTMP_IsConnected (sink->rtmp)) {
|
if (!RTMP_IsConnected (sink->rtmp)) {
|
||||||
@ -219,6 +228,7 @@ gst_rtmp_sink_render (GstBaseSink * bsink, GstBuffer * buf)
|
|||||||
sink->rtmp = NULL;
|
sink->rtmp = NULL;
|
||||||
g_free (sink->rtmp_uri);
|
g_free (sink->rtmp_uri);
|
||||||
sink->rtmp_uri = NULL;
|
sink->rtmp_uri = NULL;
|
||||||
|
sink->have_write_error = TRUE;
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
GST_DEBUG_OBJECT (sink, "Opened connection to %s", sink->rtmp_uri);
|
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;
|
sink->cache = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sink->have_write_error)
|
||||||
|
goto write_failed;
|
||||||
|
|
||||||
GST_LOG_OBJECT (sink, "Sending %" G_GSIZE_FORMAT " bytes to RTMP server",
|
GST_LOG_OBJECT (sink, "Sending %" G_GSIZE_FORMAT " bytes to RTMP server",
|
||||||
gst_buffer_get_size (buf));
|
gst_buffer_get_size (buf));
|
||||||
|
|
||||||
@ -262,6 +275,7 @@ write_failed:
|
|||||||
gst_buffer_unmap (buf, &map);
|
gst_buffer_unmap (buf, &map);
|
||||||
if (reffed_buf)
|
if (reffed_buf)
|
||||||
gst_buffer_unref (reffed_buf);
|
gst_buffer_unref (reffed_buf);
|
||||||
|
sink->have_write_error = TRUE;
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -330,8 +344,10 @@ gst_rtmp_sink_uri_set_uri (GstURIHandler * handler, const gchar * uri,
|
|||||||
free (playpath.av_val);
|
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));
|
GST_DEBUG_OBJECT (sink, "Changed URI to %s", GST_STR_NULL (uri));
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
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
|
static void
|
||||||
gst_rtmp_sink_get_property (GObject * object, guint prop_id,
|
gst_rtmp_sink_get_property (GObject * object, guint prop_id,
|
||||||
GValue * value, GParamSpec * pspec)
|
GValue * value, GParamSpec * pspec)
|
||||||
|
@ -55,6 +55,7 @@ struct _GstRTMPSink {
|
|||||||
|
|
||||||
GstBuffer *cache; /* Cached buffer */
|
GstBuffer *cache; /* Cached buffer */
|
||||||
gboolean first;
|
gboolean first;
|
||||||
|
gboolean have_write_error;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstRTMPSinkClass {
|
struct _GstRTMPSinkClass {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user