PROP_0
};
+typedef struct _ValidateBufferItData
+{
+ GstSrtpDecSsrcStream **stream;
+ GstSrtpDec *filter;
+ guint32 *ssrc;
+ gboolean *is_rtcp;
+} ValidateBufferItData;
+
+typedef struct _DecodeBufferItData
+{
+ GstSrtpDec *filter;
+ GstPad *pad;
+ guint32 ssrc;
+ gboolean is_rtcp;
+} DecodeBufferItData;
+
/* the capabilities of the inputs and outputs.
*
* describe the real formats here.
static GstFlowReturn gst_srtp_dec_chain_rtcp (GstPad * pad,
GstObject * parent, GstBuffer * buf);
+static GstFlowReturn gst_srtp_dec_chain_list_rtp (GstPad * pad,
+ GstObject * parent, GstBufferList * buf_list);
+static GstFlowReturn gst_srtp_dec_chain_list_rtcp (GstPad * pad,
+ GstObject * parent, GstBufferList * buf_list);
+
static GstStateChangeReturn gst_srtp_dec_change_state (GstElement * element,
GstStateChange transition);
GST_DEBUG_FUNCPTR (gst_srtp_dec_iterate_internal_links_rtp));
gst_pad_set_chain_function (filter->rtp_sinkpad,
GST_DEBUG_FUNCPTR (gst_srtp_dec_chain_rtp));
+ gst_pad_set_chain_list_function (filter->rtp_sinkpad,
+ GST_DEBUG_FUNCPTR (gst_srtp_dec_chain_list_rtp));
filter->rtp_srcpad =
gst_pad_new_from_static_template (&rtp_src_template, "rtp_src");
GST_DEBUG_FUNCPTR (gst_srtp_dec_iterate_internal_links_rtcp));
gst_pad_set_chain_function (filter->rtcp_sinkpad,
GST_DEBUG_FUNCPTR (gst_srtp_dec_chain_rtcp));
+ gst_pad_set_chain_list_function (filter->rtcp_sinkpad,
+ GST_DEBUG_FUNCPTR (gst_srtp_dec_chain_list_rtcp));
filter->rtcp_srcpad =
gst_pad_new_from_static_template (&rtcp_src_template, "rtcp_src");
GST_OBJECT_LOCK (filter);
/* Check if this stream exists, if not create a new stream */
-
if (!(stream = validate_buffer (filter, buf, &ssrc, &is_rtcp))) {
GST_OBJECT_UNLOCK (filter);
GST_WARNING_OBJECT (filter, "Invalid buffer, dropping");
return ret;
}
+static gboolean
+validate_buffer_it (GstBuffer ** buffer, guint index, gpointer user_data)
+{
+ ValidateBufferItData *data = user_data;
+
+ if (!(*data->stream =
+ validate_buffer (data->filter, *buffer, data->ssrc, data->is_rtcp))) {
+ GST_WARNING_OBJECT (data->filter, "Invalid buffer, dropping");
+ gst_buffer_replace (buffer, NULL);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+decode_buffer_it (GstBuffer ** buffer, guint index, gpointer user_data)
+{
+ DecodeBufferItData *data = user_data;
+
+ if (!gst_srtp_dec_decode_buffer (data->filter, data->pad, *buffer,
+ data->is_rtcp, data->ssrc)) {
+ GST_WARNING_OBJECT (data->filter, "Error decoding buffer, dropping");
+ gst_buffer_replace (buffer, NULL);
+ }
+
+ return TRUE;
+}
+
+static GstFlowReturn
+gst_srtp_dec_chain_list (GstPad * pad, GstObject * parent,
+ GstBufferList * buf_list, gboolean is_rtcp)
+{
+ GstSrtpDec *filter = GST_SRTP_DEC (parent);
+ GstPad *otherpad;
+ GstSrtpDecSsrcStream *stream = NULL;
+ GstFlowReturn ret = GST_FLOW_OK;
+ guint32 ssrc = 0;
+ ValidateBufferItData validate_data;
+ DecodeBufferItData decode_data;
+
+ validate_data.stream = &stream;
+ validate_data.filter = filter;
+ validate_data.ssrc = &ssrc;
+ validate_data.is_rtcp = &is_rtcp;
+
+ decode_data.filter = filter;
+ decode_data.pad = pad;
+
+ GST_OBJECT_LOCK (filter);
+
+ /* Check if this stream exists, if not create a new stream */
+ gst_buffer_list_foreach (buf_list, validate_buffer_it, &validate_data);
+
+ if (!gst_buffer_list_length (buf_list)) {
+ GST_OBJECT_LOCK (filter);
+ gst_buffer_list_unref (buf_list);
+ return GST_FLOW_OK;
+ }
+
+ if (!STREAM_HAS_CRYPTO (stream)) {
+ GST_OBJECT_UNLOCK (filter);
+ goto push_out;
+ }
+
+ decode_data.ssrc = ssrc;
+ decode_data.is_rtcp = is_rtcp;
+
+ gst_buffer_list_foreach (buf_list, decode_buffer_it, &decode_data);
+
+ GST_OBJECT_UNLOCK (filter);
+
+ if (!gst_buffer_list_length (buf_list)) {
+ gst_buffer_list_unref (buf_list);
+ return GST_FLOW_OK;
+ }
+
+ /* If all is well, we may have reached soft limit */
+ if (gst_srtp_get_soft_limit_reached ())
+ request_key_with_signal (filter, ssrc, SIGNAL_SOFT_LIMIT);
+
+push_out:
+ /* Push buffer list to source pad */
+ if (is_rtcp) {
+ otherpad = filter->rtcp_srcpad;
+ if (!filter->rtcp_has_segment)
+ gst_srtp_dec_push_early_events (filter, filter->rtcp_srcpad,
+ filter->rtp_srcpad, TRUE);
+ } else {
+ otherpad = filter->rtp_srcpad;
+ if (!filter->rtp_has_segment)
+ gst_srtp_dec_push_early_events (filter, filter->rtp_srcpad,
+ filter->rtcp_srcpad, FALSE);
+ }
+
+ GST_LOG_OBJECT (pad, "Pushing buffer chain of %d",
+ gst_buffer_list_length (buf_list));
+ ret = gst_pad_push_list (otherpad, buf_list);
+
+ return ret;
+}
+
static GstFlowReturn
gst_srtp_dec_chain_rtp (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
return gst_srtp_dec_chain (pad, parent, buf, TRUE);
}
+static GstFlowReturn
+gst_srtp_dec_chain_list_rtp (GstPad * pad, GstObject * parent,
+ GstBufferList * buf_list)
+{
+ return gst_srtp_dec_chain_list (pad, parent, buf_list, FALSE);
+}
+
+static GstFlowReturn
+gst_srtp_dec_chain_list_rtcp (GstPad * pad, GstObject * parent,
+ GstBufferList * buf_list)
+{
+ return gst_srtp_dec_chain_list (pad, parent, buf_list, TRUE);
+}
+
+
static GstStateChangeReturn
gst_srtp_dec_change_state (GstElement * element, GstStateChange transition)
{