gboolean negotiated;
GstCaps *last_caps;
+ gboolean needs_src_caps_update;
+
GstEvent *segment_event;
guint32 segment_seqnum; /* Note: this is a GstEvent seqnum */
goto out;
}
+ if (gst_rtp_header_extension_wants_update_non_rtp_src_caps (ext)) {
+ depayload->priv->needs_src_caps_update = TRUE;
+ }
+
gst_object_unref (ext);
}
GST_OBJECT_UNLOCK (depayload);
set_headers (buf, 0, filter);
}
+ /* header extensions may want to update src caps */
+ if (G_UNLIKELY (filter->priv->needs_src_caps_update)) {
+ GstCaps *src_caps = gst_pad_get_current_caps (filter->srcpad);
+
+ if (src_caps) {
+ GstCaps *new_caps;
+ gboolean update_ok = TRUE;
+ gint i;
+
+ new_caps = gst_caps_copy (src_caps);
+ for (i = 0; i < filter->priv->header_exts->len; i++) {
+ GstRTPHeaderExtension *ext;
+
+ ext = g_ptr_array_index (filter->priv->header_exts, i);
+ update_ok =
+ gst_rtp_header_extension_update_non_rtp_src_caps (ext, new_caps);
+
+ if (!update_ok) {
+ GST_ELEMENT_ERROR (filter, STREAM, DECODE,
+ ("RTP header extension (%s) could not update src caps",
+ GST_OBJECT_NAME (ext)), (NULL));
+ break;
+ }
+ }
+
+ if (G_UNLIKELY (update_ok && !gst_caps_is_equal (src_caps, new_caps))) {
+ gst_pad_set_caps (filter->srcpad, new_caps);
+ }
+
+ gst_caps_unref (src_caps);
+ gst_caps_unref (new_caps);
+
+ if (!update_ok) {
+ return GST_FLOW_ERROR;
+ }
+ }
+
+ filter->priv->needs_src_caps_update = FALSE;
+ }
+
/* if this is the first buffer send a NEWSEGMENT */
if (G_UNLIKELY (filter->priv->segment_event)) {
gst_pad_push_event (filter->srcpad, filter->priv->segment_event);
}
/**
+ * gst_rtp_header_extension_wants_update_non_rtp_src_caps:
+ * @ext: a #GstRTPHeaderExtension
+ *
+ * Call this function after gst_rtp_header_extension_read() to check if
+ * the depayloader's src caps need updating with data received in the last RTP
+ * packet.
+ *
+ * Returns: Whether @ext wants to update depayloader's src caps.
+ *
+ * Since: 1.20
+ */
+gboolean
+gst_rtp_header_extension_wants_update_non_rtp_src_caps (GstRTPHeaderExtension *
+ ext)
+{
+ g_return_val_if_fail (GST_IS_RTP_HEADER_EXTENSION (ext), FALSE);
+
+ return ext->wants_update_non_rtp_src_caps;
+}
+
+/**
+ * gst_rtp_header_extension_set_wants_update_non_rtp_src_caps:
+ * @ext: a #GstRTPHeaderExtension
+ * @state: TRUE if caps update is needed
+ *
+ * Call this function in a subclass from #GstRTPHeaderExtensionClass::read to
+ * tell the depayloader whether the data just parsed from RTP packet require
+ * updating its src (non-RTP) caps. If @state is TRUE, #GstRTPBaseDepayload will
+ * eventually invoke gst_rtp_header_extension_update_non_rtp_src_caps() to
+ * have the caps update applied. Applying the update also flips the internal
+ * "wants update" flag back to FALSE.
+ *
+ * Since: 1.20
+ */
+void gst_rtp_header_extension_set_wants_update_non_rtp_src_caps
+ (GstRTPHeaderExtension * ext, gboolean state)
+{
+ g_return_if_fail (GST_IS_RTP_HEADER_EXTENSION (ext));
+
+ ext->wants_update_non_rtp_src_caps = state;
+}
+
+/**
* gst_rtp_header_extension_set_non_rtp_sink_caps:
* @ext: a #GstRTPHeaderExtension
* @caps: sink #GstCaps
}
/**
+ * gst_rtp_header_extension_update_non_rtp_src_caps:
+ * @ext: a #GstRTPHeaderExtension
+ * @caps: src #GstCaps to modify
+ *
+ * Updates depayloader src caps based on the information received in RTP header.
+ * @caps must be writable as this function may modify them.
+ *
+ * Returns: whether @caps were modified successfully
+ *
+ * Since: 1.20
+ */
+gboolean
+gst_rtp_header_extension_update_non_rtp_src_caps (GstRTPHeaderExtension * ext,
+ GstCaps * caps)
+{
+ GstRTPHeaderExtensionClass *klass;
+
+ g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
+ g_return_val_if_fail (gst_caps_is_writable (caps), FALSE);
+ g_return_val_if_fail (GST_IS_RTP_HEADER_EXTENSION (ext), FALSE);
+ g_return_val_if_fail (ext->ext_id <= MAX_RTP_EXT_ID, FALSE);
+ klass = GST_RTP_HEADER_EXTENSION_GET_CLASS (ext);
+
+ ext->wants_update_non_rtp_src_caps = FALSE;
+
+ if (klass->update_non_rtp_src_caps) {
+ return klass->update_non_rtp_src_caps (ext, caps);
+ }
+
+ return TRUE;
+}
+
+/**
* gst_rtp_header_extension_set_caps_from_attributes:
* @ext: a #GstRTPHeaderExtension
* @caps: writable #GstCaps to modify
GstElement parent;
guint ext_id;
+ gboolean wants_update_non_rtp_src_caps;
/*< private >*/
gpointer _gst_reserved[GST_PADDING];
* information, optionally adding some meta onto the output buffer.
* @set_non_rtp_sink_caps: read any information from sink caps that the header
* extension needs for its function.
+ * @update_non_rtp_src_caps: update depayloader non-RTP (depayloaded) caps with
+ * the information parsed from RTP header.
* @set_attributes_from_caps: read the caps information to set the necessary
* attributes that may be signaled e.g. with an SDP.
* @set_caps_from_attributes: write the necessary caps field/s for the configured
GstBuffer * buffer);
gboolean (*set_non_rtp_sink_caps) (GstRTPHeaderExtension * ext,
const GstCaps * caps);
+ gboolean (*update_non_rtp_src_caps) (GstRTPHeaderExtension * ext,
+ GstCaps * caps);
gboolean (*set_attributes_from_caps) (GstRTPHeaderExtension * ext,
const GstCaps * caps);
gboolean (*set_caps_from_attributes) (GstRTPHeaderExtension * ext,
gboolean gst_rtp_header_extension_set_non_rtp_sink_caps (GstRTPHeaderExtension * ext,
const GstCaps * caps);
GST_RTP_API
+gboolean gst_rtp_header_extension_wants_update_non_rtp_src_caps (GstRTPHeaderExtension * ext);
+GST_RTP_API
+void gst_rtp_header_extension_set_wants_update_non_rtp_src_caps (GstRTPHeaderExtension * ext,
+ gboolean state);
+GST_RTP_API
+gboolean gst_rtp_header_extension_update_non_rtp_src_caps (GstRTPHeaderExtension * ext,
+ GstCaps * caps);
+GST_RTP_API
gboolean gst_rtp_header_extension_set_caps_from_attributes (GstRTPHeaderExtension * ext,
GstCaps * caps);
GST_RTP_API