rtp: rtpbasedepayload: add process_rtp_packet() vfunc
authorTim-Philipp Müller <tim@centricular.com>
Wed, 27 May 2015 17:55:20 +0000 (18:55 +0100)
committerTim-Philipp Müller <tim@centricular.com>
Sun, 12 Jul 2015 13:29:29 +0000 (14:29 +0100)
Add process_rtp_packet() vfunc that works just like the
existing process() vfunc only that it takes the GstRTPBuffer
that the base class has already mapped (with MAP_READ),
which means that the subclass doesn't have to map it again,
which allows more performant processing of input buffers
for most RTP depayloaders.

https://bugzilla.gnome.org/show_bug.cgi?id=750235

gst-libs/gst/rtp/gstrtpbasedepayload.c
gst-libs/gst/rtp/gstrtpbasedepayload.h

index 4f351b2..596ec88 100644 (file)
@@ -349,6 +349,9 @@ static GstFlowReturn
 gst_rtp_base_depayload_handle_buffer (GstRTPBaseDepayload * filter,
     GstRTPBaseDepayloadClass * bclass, GstBuffer * in)
 {
+  GstBuffer *(*process_rtp_packet_func) (GstRTPBaseDepayload * base,
+      GstRTPBuffer * rtp_buffer);
+  GstBuffer *(*process_func) (GstRTPBaseDepayload * base, GstBuffer * in);
   GstRTPBaseDepayloadPrivate *priv;
   GstFlowReturn ret = GST_FLOW_OK;
   GstBuffer *out_buf;
@@ -361,6 +364,9 @@ gst_rtp_base_depayload_handle_buffer (GstRTPBaseDepayload * filter,
 
   priv = filter->priv;
 
+  process_func = bclass->process;
+  process_rtp_packet_func = bclass->process_rtp_packet;
+
   /* we must have a setcaps first */
   if (G_UNLIKELY (!priv->negotiated))
     goto not_negotiated;
@@ -382,7 +388,6 @@ gst_rtp_base_depayload_handle_buffer (GstRTPBaseDepayload * filter,
 
   seqnum = gst_rtp_buffer_get_seq (&rtp);
   rtptime = gst_rtp_buffer_get_timestamp (&rtp);
-  gst_rtp_buffer_unmap (&rtp);
 
   priv->last_seqnum = seqnum;
   priv->last_rtptime = rtptime;
@@ -442,11 +447,17 @@ gst_rtp_base_depayload_handle_buffer (GstRTPBaseDepayload * filter,
     filter->need_newsegment = FALSE;
   }
 
-  if (G_UNLIKELY (bclass->process == NULL))
+  if (process_rtp_packet_func != NULL) {
+    out_buf = process_rtp_packet_func (filter, &rtp);
+    gst_rtp_buffer_unmap (&rtp);
+  } else if (process_func != NULL) {
+    gst_rtp_buffer_unmap (&rtp);
+    out_buf = process_func (filter, in);
+  } else {
     goto no_process;
+  }
 
   /* let's send it out to processing */
-  out_buf = bclass->process (filter, in);
   if (out_buf) {
     ret = gst_rtp_base_depayload_push (filter, out_buf);
   }
@@ -483,7 +494,7 @@ 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"));
+        ("The subclass does not have a process or process_rtp_packet method"));
     return GST_FLOW_ERROR;
   }
 }
index f452bc5..20c0b00 100644 (file)
@@ -80,7 +80,8 @@ struct _GstRTPBaseDepayloadClass
   /* virtuals, inform the subclass of the caps. */
   gboolean (*set_caps) (GstRTPBaseDepayload *filter, GstCaps *caps);
 
-  /* pure virtual function, child must use this to process incoming
+  /* pure virtual function, child must implement either this method
+   * or the process_rtp_packet virtual method to process incoming
    * rtp packets. If the child returns a buffer without a valid timestamp,
    * the timestamp of @in will be applied to the result buffer and the
    * buffer will be pushed. If this function returns %NULL, nothing is
@@ -96,8 +97,21 @@ struct _GstRTPBaseDepayloadClass
    * implementation can override. */
   gboolean (*handle_event) (GstRTPBaseDepayload * filter, GstEvent * event);
 
+  /* Optional. Same as the process virtual function, but slightly more
+   * efficient, since it is passed the rtp buffer structure that has already
+   * been mapped (with GST_MAP_READ) by the base class and thus does not have
+   * to be mapped again by the subclass. Can be used by the subclass to process
+   * incoming rtp packets. If the subclass returns a buffer without a valid
+   * timestamp, the timestamp of the input buffer will be applied to the result
+   * buffer and the output buffer will be pushed out. If this function returns
+   * %NULL, nothing is pushed out.
+   *
+   * Since: 1.6
+   */
+  GstBuffer * (*process_rtp_packet) (GstRTPBaseDepayload *base, GstRTPBuffer * rtp_buffer);
+
   /*< private >*/
-  gpointer _gst_reserved[GST_PADDING];
+  gpointer _gst_reserved[GST_PADDING - 1];
 };
 
 GType gst_rtp_base_depayload_get_type (void);