summaryrefslogtreecommitdiff
path: root/gst-libs/gst/rtp
diff options
context:
space:
mode:
authorTim-Philipp Müller <tim@centricular.com>2015-05-21 13:59:55 +0100
committerTim-Philipp Müller <tim@centricular.com>2015-06-01 19:00:55 +0100
commitbc309a100f4a10fae48468036ee1041d1673a322 (patch)
tree8ad1cb2b392bae85ffd8486422cd6fcb92e58f2c /gst-libs/gst/rtp
parentdcfb8a83a53a083b84d14e5360cb42c7efc7bcf0 (diff)
rtpbasedepayload: provide chain_list function on sink pad
Implement a chain_list function, which avoids lots of locking compared to the default fallback implementation in GstPad. We may also want to do some more sophisticated timestamp tracking here at some point, but for now leave it up to the jitterbuffer and/or subclasses (in case buffers in the buffer list have no timestamp set on them, there may only be a timestamp for the whole list on the first buffer). This provides the exact same behaviour as the default fallback implementation.
Diffstat (limited to 'gst-libs/gst/rtp')
-rw-r--r--gst-libs/gst/rtp/gstrtpbasedepayload.c75
-rw-r--r--gst-libs/gst/rtp/gstrtpbasedepayload.h5
2 files changed, 67 insertions, 13 deletions
diff --git a/gst-libs/gst/rtp/gstrtpbasedepayload.c b/gst-libs/gst/rtp/gstrtpbasedepayload.c
index 06b773be7..8b0a7212a 100644
--- a/gst-libs/gst/rtp/gstrtpbasedepayload.c
+++ b/gst-libs/gst/rtp/gstrtpbasedepayload.c
@@ -78,6 +78,8 @@ static void gst_rtp_base_depayload_get_property (GObject * object,
static GstFlowReturn gst_rtp_base_depayload_chain (GstPad * pad,
GstObject * parent, GstBuffer * in);
+static GstFlowReturn gst_rtp_base_depayload_chain_list (GstPad * pad,
+ GstObject * parent, GstBufferList * list);
static gboolean gst_rtp_base_depayload_handle_sink_event (GstPad * pad,
GstObject * parent, GstEvent * event);
@@ -227,6 +229,8 @@ gst_rtp_base_depayload_init (GstRTPBaseDepayload * filter,
g_return_if_fail (pad_template != NULL);
filter->sinkpad = gst_pad_new_from_template (pad_template, "sink");
gst_pad_set_chain_function (filter->sinkpad, gst_rtp_base_depayload_chain);
+ gst_pad_set_chain_list_function (filter->sinkpad,
+ gst_rtp_base_depayload_chain_list);
gst_pad_set_event_function (filter->sinkpad,
gst_rtp_base_depayload_handle_sink_event);
gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad);
@@ -342,11 +346,10 @@ caps_not_changed:
}
static GstFlowReturn
-gst_rtp_base_depayload_chain (GstPad * pad, GstObject * parent, GstBuffer * in)
+gst_rtp_base_depayload_handle_buffer (GstRTPBaseDepayload * filter,
+ GstRTPBaseDepayloadClass * bclass, GstBuffer * in)
{
- GstRTPBaseDepayload *filter;
GstRTPBaseDepayloadPrivate *priv;
- GstRTPBaseDepayloadClass *bclass;
GstFlowReturn ret = GST_FLOW_OK;
GstBuffer *out_buf;
GstClockTime pts, dts;
@@ -356,7 +359,6 @@ gst_rtp_base_depayload_chain (GstPad * pad, GstObject * parent, GstBuffer * in)
gint gap;
GstRTPBuffer rtp = { NULL };
- filter = GST_RTP_BASE_DEPAYLOAD (parent);
priv = filter->priv;
/* we must have a setcaps first */
@@ -440,8 +442,6 @@ gst_rtp_base_depayload_chain (GstPad * pad, GstObject * parent, GstBuffer * in)
filter->need_newsegment = FALSE;
}
- bclass = GST_RTP_BASE_DEPAYLOAD_GET_CLASS (filter);
-
if (G_UNLIKELY (bclass->process == NULL))
goto no_process;
@@ -450,7 +450,6 @@ gst_rtp_base_depayload_chain (GstPad * pad, GstObject * parent, GstBuffer * in)
if (out_buf) {
ret = gst_rtp_base_depayload_push (filter, out_buf);
}
- gst_buffer_unref (in);
return ret;
@@ -466,7 +465,6 @@ not_negotiated:
"element before the depayloader and setting the 'caps' property "
"on that. Also see http://cgit.freedesktop.org/gstreamer/"
"gst-plugins-good/tree/gst/rtp/README"));
- gst_buffer_unref (in);
return GST_FLOW_NOT_NEGOTIATED;
}
invalid_buffer:
@@ -474,13 +472,11 @@ invalid_buffer:
/* this is not fatal but should be filtered earlier */
GST_ELEMENT_WARNING (filter, STREAM, DECODE, (NULL),
("Received invalid RTP payload, dropping"));
- gst_buffer_unref (in);
return GST_FLOW_OK;
}
dropping:
{
GST_WARNING_OBJECT (filter, "%d <= 100, dropping old packet", gap);
- gst_buffer_unref (in);
return GST_FLOW_OK;
}
no_process:
@@ -488,11 +484,68 @@ no_process:
/* this is not fatal but should be filtered earlier */
GST_ELEMENT_ERROR (filter, STREAM, NOT_IMPLEMENTED, (NULL),
("The subclass does not have a process method"));
- gst_buffer_unref (in);
return GST_FLOW_ERROR;
}
}
+static GstFlowReturn
+gst_rtp_base_depayload_chain (GstPad * pad, GstObject * parent, GstBuffer * in)
+{
+ GstRTPBaseDepayloadClass *bclass;
+ GstRTPBaseDepayload *basedepay;
+ GstFlowReturn flow_ret;
+
+ basedepay = GST_RTP_BASE_DEPAYLOAD_CAST (parent);
+
+ bclass = GST_RTP_BASE_DEPAYLOAD_GET_CLASS (basedepay);
+
+ flow_ret = gst_rtp_base_depayload_handle_buffer (basedepay, bclass, in);
+
+ gst_buffer_unref (in);
+
+ return flow_ret;
+}
+
+static GstFlowReturn
+gst_rtp_base_depayload_chain_list (GstPad * pad, GstObject * parent,
+ GstBufferList * list)
+{
+ GstRTPBaseDepayloadClass *bclass;
+ GstRTPBaseDepayload *basedepay;
+ GstFlowReturn flow_ret;
+ GstBuffer *buffer;
+ guint i, len;
+
+ basedepay = GST_RTP_BASE_DEPAYLOAD_CAST (parent);
+
+ bclass = GST_RTP_BASE_DEPAYLOAD_GET_CLASS (basedepay);
+
+ flow_ret = GST_FLOW_OK;
+
+ /* chain each buffer in list individually */
+ len = gst_buffer_list_length (list);
+
+ if (len == 0)
+ goto done;
+
+ for (i = 0; i < len; i++) {
+ buffer = gst_buffer_list_get (list, i);
+
+ /* Should we fix up any missing timestamps for list buffers here
+ * (e.g. set to first or previous timestamp in list) or just assume
+ * the's a jitterbuffer that will have done that for us? */
+ flow_ret = gst_rtp_base_depayload_handle_buffer (basedepay, bclass, buffer);
+ if (flow_ret != GST_FLOW_OK)
+ break;
+ }
+
+done:
+
+ gst_buffer_list_unref (list);
+
+ return flow_ret;
+}
+
static gboolean
gst_rtp_base_depayload_handle_event (GstRTPBaseDepayload * filter,
GstEvent * event)
diff --git a/gst-libs/gst/rtp/gstrtpbasedepayload.h b/gst-libs/gst/rtp/gstrtpbasedepayload.h
index 91586de5e..f452bc57b 100644
--- a/gst-libs/gst/rtp/gstrtpbasedepayload.h
+++ b/gst-libs/gst/rtp/gstrtpbasedepayload.h
@@ -36,9 +36,10 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_BASE_DEPAYLOAD))
#define GST_IS_RTP_BASE_DEPAYLOAD_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_BASE_DEPAYLOAD))
+#define GST_RTP_BASE_DEPAYLOAD_CAST(obj) ((GstRTPBaseDepayload *)(obj))
-#define GST_RTP_BASE_DEPAYLOAD_SINKPAD(depayload) (GST_RTP_BASE_DEPAYLOAD (depayload)->sinkpad)
-#define GST_RTP_BASE_DEPAYLOAD_SRCPAD(depayload) (GST_RTP_BASE_DEPAYLOAD (depayload)->srcpad)
+#define GST_RTP_BASE_DEPAYLOAD_SINKPAD(depayload) (GST_RTP_BASE_DEPAYLOAD_CAST (depayload)->sinkpad)
+#define GST_RTP_BASE_DEPAYLOAD_SRCPAD(depayload) (GST_RTP_BASE_DEPAYLOAD_CAST (depayload)->srcpad)
typedef struct _GstRTPBaseDepayload GstRTPBaseDepayload;
typedef struct _GstRTPBaseDepayloadClass GstRTPBaseDepayloadClass;