Skip to content

Commit

Permalink
rtphdrext: allow updating depayloader src caps
Browse files Browse the repository at this point in the history
Add overridable method that updates depayloader's src caps based on
the data from RTP header.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/1011>
  • Loading branch information
xhaakon committed Mar 12, 2021
1 parent 899c69a commit c222f32
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 0 deletions.
46 changes: 46 additions & 0 deletions gst-libs/gst/rtp/gstrtpbasedepayload.c
Expand Up @@ -60,6 +60,8 @@ struct _GstRTPBaseDepayloadPrivate
gboolean negotiated;

GstCaps *last_caps;
gboolean needs_src_caps_update;

GstEvent *segment_event;
guint32 segment_seqnum; /* Note: this is a GstEvent seqnum */

Expand Down Expand Up @@ -1241,6 +1243,10 @@ read_rtp_header_extensions (GstRTPBaseDepayload * depayload,
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);
Expand Down Expand Up @@ -1307,6 +1313,46 @@ gst_rtp_base_depayload_prepare_push (GstRTPBaseDepayload * filter,
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);
Expand Down
76 changes: 76 additions & 0 deletions gst-libs/gst/rtp/gstrtphdrext.c
Expand Up @@ -394,6 +394,49 @@ gst_rtp_header_extension_set_attributes_from_caps (GstRTPHeaderExtension * ext,
return klass->set_attributes_from_caps (ext, caps);
}

/**
* 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
Expand Down Expand Up @@ -424,6 +467,39 @@ gst_rtp_header_extension_set_non_rtp_sink_caps (GstRTPHeaderExtension * ext,
return TRUE;
}

/**
* 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
Expand Down
13 changes: 13 additions & 0 deletions gst-libs/gst/rtp/gstrtphdrext.h
Expand Up @@ -117,6 +117,7 @@ struct _GstRTPHeaderExtension
GstElement parent;

guint ext_id;
gboolean wants_update_non_rtp_src_caps;

/*< private >*/
gpointer _gst_reserved[GST_PADDING];
Expand All @@ -140,6 +141,8 @@ struct _GstRTPHeaderExtension
* 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
Expand Down Expand Up @@ -173,6 +176,8 @@ struct _GstRTPHeaderExtensionClass
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,
Expand Down Expand Up @@ -224,6 +229,14 @@ GST_RTP_API
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
Expand Down

0 comments on commit c222f32

Please sign in to comment.