diff --git a/gst-libs/gst/rtp/gstrtpbasedepayload.c b/gst-libs/gst/rtp/gstrtpbasedepayload.c index 4f351b26e5..596ec8835e 100644 --- a/gst-libs/gst/rtp/gstrtpbasedepayload.c +++ b/gst-libs/gst/rtp/gstrtpbasedepayload.c @@ -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; } } diff --git a/gst-libs/gst/rtp/gstrtpbasedepayload.h b/gst-libs/gst/rtp/gstrtpbasedepayload.h index f452bc57b4..20c0b00026 100644 --- a/gst-libs/gst/rtp/gstrtpbasedepayload.h +++ b/gst-libs/gst/rtp/gstrtpbasedepayload.h @@ -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);