srtpenc: Handle session object disappearing

During element shutdown, the srtp encryption session
object can be cleaned up. In that case, return GST_FLOW_FLUSHING
from the chain function. Also properly return GST_FLOW_ERROR
upstream during actual errors.

https://bugzilla.gnome.org/show_bug.cgi?id=790508
This commit is contained in:
Jan Schmidt 2018-05-05 01:59:53 +10:00
parent e9e98715b0
commit 3740837c18

View file

@ -160,6 +160,7 @@ typedef struct ProcessBufferItData
GstSrtpEnc *filter; GstSrtpEnc *filter;
GstPad *pad; GstPad *pad;
GstBufferList *out_list; GstBufferList *out_list;
GstFlowReturn flowret;
gboolean is_rtcp; gboolean is_rtcp;
} ProcessBufferItData; } ProcessBufferItData;
@ -1029,10 +1030,11 @@ gst_srtp_enc_check_set_caps (GstSrtpEnc * filter, GstPad * pad,
return GST_FLOW_OK; return GST_FLOW_OK;
} }
static GstBuffer * static GstFlowReturn
gst_srtp_enc_process_buffer (GstSrtpEnc * filter, GstPad * pad, gst_srtp_enc_process_buffer (GstSrtpEnc * filter, GstPad * pad,
GstBuffer * buf, gboolean is_rtcp) GstBuffer * buf, gboolean is_rtcp, GstBuffer ** outbuf_ptr)
{ {
GstFlowReturn ret = GST_FLOW_OK;
gint size_max, size; gint size_max, size;
GstBuffer *bufout = NULL; GstBuffer *bufout = NULL;
GstMapInfo mapout; GstMapInfo mapout;
@ -1051,6 +1053,13 @@ gst_srtp_enc_process_buffer (GstSrtpEnc * filter, GstPad * pad,
gst_srtp_init_event_reporter (); gst_srtp_init_event_reporter ();
if (filter->session == NULL) {
/* The rtcp session disappeared (element shutting down) */
GST_OBJECT_UNLOCK (filter);
ret = GST_FLOW_FLUSHING;
goto fail;
}
if (is_rtcp) if (is_rtcp)
err = srtp_protect_rtcp (filter->session, mapout.data, &size); err = srtp_protect_rtcp (filter->session, mapout.data, &size);
else else
@ -1073,20 +1082,23 @@ gst_srtp_enc_process_buffer (GstSrtpEnc * filter, GstPad * pad,
GST_ELEMENT_ERROR (GST_ELEMENT_CAST (filter), STREAM, ENCODE, GST_ELEMENT_ERROR (GST_ELEMENT_CAST (filter), STREAM, ENCODE,
("Key usage limit has been reached"), ("Key usage limit has been reached"),
("Unable to protect buffer (hard key usage limit reached)")); ("Unable to protect buffer (hard key usage limit reached)"));
ret = GST_FLOW_ERROR;
goto fail; goto fail;
} else { } else {
/* srtp_protect failed */ /* srtp_protect failed */
GST_ELEMENT_ERROR (filter, LIBRARY, FAILED, (NULL), GST_ELEMENT_ERROR (filter, LIBRARY, FAILED, (NULL),
("Unable to protect buffer (protect failed) code %d", err)); ("Unable to protect buffer (protect failed) code %d", err));
ret = GST_FLOW_ERROR;
goto fail; goto fail;
} }
return bufout; *outbuf_ptr = bufout;
return ret;
fail: fail:
gst_buffer_unref (bufout); gst_buffer_unref (bufout);
return NULL; return ret;
} }
static GstFlowReturn static GstFlowReturn
@ -1112,17 +1124,17 @@ gst_srtp_enc_chain (GstPad * pad, GstObject * parent, GstBuffer * buf,
GST_OBJECT_UNLOCK (filter); GST_OBJECT_UNLOCK (filter);
if ((bufout = gst_srtp_enc_process_buffer (filter, pad, buf, is_rtcp))) { ret = gst_srtp_enc_process_buffer (filter, pad, buf, is_rtcp, &bufout);
/* Push buffer to source pad */ if (ret != GST_FLOW_OK)
otherpad = get_rtp_other_pad (pad); goto out;
ret = gst_pad_push (otherpad, bufout);
bufout = NULL;
if (ret != GST_FLOW_OK) /* Push buffer to source pad */
goto out; otherpad = get_rtp_other_pad (pad);
} else { ret = gst_pad_push (otherpad, bufout);
goto fail; bufout = NULL;
}
if (ret != GST_FLOW_OK)
goto out;
GST_OBJECT_LOCK (filter); GST_OBJECT_LOCK (filter);
@ -1137,14 +1149,8 @@ gst_srtp_enc_chain (GstPad * pad, GstObject * parent, GstBuffer * buf,
GST_OBJECT_UNLOCK (filter); GST_OBJECT_UNLOCK (filter);
out: out:
gst_buffer_unref (buf); gst_buffer_unref (buf);
return ret; return ret;
fail:
ret = GST_FLOW_ERROR;
goto out;
} }
static gboolean static gboolean
@ -1152,15 +1158,17 @@ process_buffer_it (GstBuffer ** buffer, guint index, gpointer user_data)
{ {
ProcessBufferItData *data = user_data; ProcessBufferItData *data = user_data;
GstBuffer *bufout; GstBuffer *bufout;
GstFlowReturn ret;
if ((bufout = ret = gst_srtp_enc_process_buffer (data->filter, data->pad, *buffer,
gst_srtp_enc_process_buffer (data->filter, data->pad, *buffer, data->is_rtcp, &bufout);
data->is_rtcp))) { if (ret != GST_FLOW_OK) {
gst_buffer_list_add (data->out_list, bufout); data->flowret = ret;
} else { return FALSE;
GST_WARNING_OBJECT (data->filter, "Error encoding buffer, dropping");
} }
gst_buffer_list_add (data->out_list, bufout);
return TRUE; return TRUE;
} }
@ -1199,8 +1207,12 @@ gst_srtp_enc_chain_list (GstPad * pad, GstObject * parent,
process_data.pad = pad; process_data.pad = pad;
process_data.is_rtcp = is_rtcp; process_data.is_rtcp = is_rtcp;
process_data.out_list = out_list; process_data.out_list = out_list;
process_data.flowret = GST_FLOW_OK;
gst_buffer_list_foreach (buf_list, process_buffer_it, &process_data); if (!gst_buffer_list_foreach (buf_list, process_buffer_it, &process_data)) {
ret = process_data.flowret;
goto out;
}
if (!gst_buffer_list_length (out_list)) { if (!gst_buffer_list_length (out_list)) {
gst_buffer_list_unref (out_list); gst_buffer_list_unref (out_list);