Skip to content

Commit

Permalink
rtpbasepayload: add auto-header-extension property
Browse files Browse the repository at this point in the history
Using RTP header extensions is currently not convenient. Users have to
handle signals from the RTP payloader and instantiate the extension
element themselves, making it impossible to use with gst-launch.

Adding a property allowing the payloader to automatically try creating
extensions. This should help simple use cases and testing using
gst-launch.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/1022>
  • Loading branch information
Guillaume Desmottes committed Feb 3, 2021
1 parent 23370ec commit bad4b17
Showing 1 changed file with 70 additions and 3 deletions.
73 changes: 70 additions & 3 deletions gst-libs/gst/rtp/gstrtpbasepayload.c
Expand Up @@ -56,6 +56,7 @@ struct _GstRTPBasePayloadPrivate
guint64 base_rtime_hz;
guint64 running_time;
gboolean scale_rtptime;
gboolean auto_hdr_ext;

gint64 prop_max_ptime;
gint64 caps_max_ptime;
Expand Down Expand Up @@ -105,6 +106,7 @@ static guint gst_rtp_base_payload_signals[LAST_SIGNAL] = { 0 };
#define DEFAULT_SOURCE_INFO FALSE
#define DEFAULT_ONVIF_NO_RATE_CONTROL FALSE
#define DEFAULT_SCALE_RTPTIME TRUE
#define DEFAULT_AUTO_HEADER_EXTENSION TRUE

#define RTP_HEADER_EXT_ONE_BYTE_MAX_SIZE 16
#define RTP_HEADER_EXT_TWO_BYTE_MAX_SIZE 256
Expand All @@ -129,6 +131,7 @@ enum
PROP_SOURCE_INFO,
PROP_ONVIF_NO_RATE_CONTROL,
PROP_SCALE_RTPTIME,
PROP_AUTO_HEADER_EXTENSION,
PROP_LAST
};

Expand Down Expand Up @@ -208,6 +211,45 @@ gst_rtp_base_payload_get_instance_private (GstRTPBasePayload * self)
return (G_STRUCT_MEMBER_P (self, private_offset));
}

static GstRTPHeaderExtension *
gst_rtp_base_payload_request_extension_default (GstRTPBasePayload * payload,
guint ext_id, const gchar * uri)
{
GstRTPHeaderExtension *ext = NULL;

if (!payload->priv->auto_hdr_ext)
return NULL;

ext = gst_rtp_header_extension_create_from_uri (uri);
if (ext) {
GST_DEBUG_OBJECT (payload,
"Automatically enabled extension %s for uri \'%s\'",
GST_ELEMENT_NAME (ext), uri);

gst_rtp_header_extension_set_id (ext, ext_id);
} else {
GST_DEBUG_OBJECT (payload,
"Didn't find any extension implementing uri \'%s\'", uri);
}

return ext;
}

static gboolean
extension_accumulator (GSignalInvocationHint * ihint,
GValue * return_accu, const GValue * handler_return, gpointer data)
{
gpointer ext;

/* Call default handler if user callback didn't create the extension */
ext = g_value_get_object (handler_return);
if (!ext)
return TRUE;

g_value_set_object (return_accu, ext);
return FALSE;
}

static void
gst_rtp_base_payload_class_init (GstRTPBasePayloadClass * klass)
{
Expand Down Expand Up @@ -381,6 +423,23 @@ gst_rtp_base_payload_class_init (GstRTPBasePayloadClass * klass)
"Whether the RTP timestamp should be scaled with the rate (speed)",
DEFAULT_SCALE_RTPTIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

/**
* GstRTPBasePayload:auto-header-extension:
*
* If enabled, the payloader will automatically try to enable all the
* RTP header extensions provided in the src caps, saving the application
* the need to handle these extensions manually using the
* GstRTPBasePayload::request-extension: signal.
*
* Since: 1.20
*/
g_object_class_install_property (G_OBJECT_CLASS (klass),
PROP_AUTO_HEADER_EXTENSION, g_param_spec_boolean ("auto-header-extension",
"Automatic RTP header extension",
"Whether RTP header extensions should be automatically enabled, if an implementation is available",
DEFAULT_AUTO_HEADER_EXTENSION,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

/**
* GstRTPBasePayload::add-extension:
* @object: the #GstRTPBasePayload
Expand Down Expand Up @@ -412,7 +471,9 @@ gst_rtp_base_payload_class_init (GstRTPBasePayloadClass * klass)
*/
gst_rtp_base_payload_signals[SIGNAL_REQUEST_EXTENSION] =
g_signal_new_class_handler ("request-extension",
G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, NULL, NULL, NULL, NULL,
G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_CALLBACK (gst_rtp_base_payload_request_extension_default),
extension_accumulator, NULL, NULL,
GST_TYPE_RTP_HEADER_EXTENSION, 2, G_TYPE_UINT, G_TYPE_STRING);

/**
Expand Down Expand Up @@ -491,6 +552,7 @@ gst_rtp_base_payload_init (GstRTPBasePayload * rtpbasepayload, gpointer g_class)
rtpbasepayload->priv->base_rtime_hz = GST_BUFFER_OFFSET_NONE;
rtpbasepayload->priv->onvif_no_rate_control = DEFAULT_ONVIF_NO_RATE_CONTROL;
rtpbasepayload->priv->scale_rtptime = DEFAULT_SCALE_RTPTIME;
rtpbasepayload->priv->auto_hdr_ext = DEFAULT_AUTO_HEADER_EXTENSION;

rtpbasepayload->media = NULL;
rtpbasepayload->encoding_name = NULL;
Expand Down Expand Up @@ -1382,6 +1444,7 @@ gst_rtp_base_payload_negotiate (GstRTPBasePayload * payload)
"for id %" G_GUINT64_FORMAT " and uri %s", ext,
ext ? GST_OBJECT_NAME (ext) : "", ext_id, uri);

/* We require caller to set the appropriate extension if it's required */
if (ext && gst_rtp_header_extension_get_id (ext) != ext_id) {
g_warning ("\'request-extension\' signal provided an rtp header "
"extension for uri \'%s\' that does not match the requested "
Expand All @@ -1400,8 +1463,6 @@ gst_rtp_base_payload_negotiate (GstRTPBasePayload * payload)
goto ext_out;
}

/* We don't create an extension implementation by default and require
* the caller to set the appropriate extension if it's required */
if (ext) {
g_ptr_array_add (to_add, ext);
}
Expand Down Expand Up @@ -2072,6 +2133,9 @@ gst_rtp_base_payload_set_property (GObject * object, guint prop_id,
case PROP_SCALE_RTPTIME:
priv->scale_rtptime = g_value_get_boolean (value);
break;
case PROP_AUTO_HEADER_EXTENSION:
priv->auto_hdr_ext = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
Expand Down Expand Up @@ -2145,6 +2209,9 @@ gst_rtp_base_payload_get_property (GObject * object, guint prop_id,
case PROP_SCALE_RTPTIME:
g_value_set_boolean (value, priv->scale_rtptime);
break;
case PROP_AUTO_HEADER_EXTENSION:
g_value_set_boolean (value, priv->auto_hdr_ext);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
Expand Down

0 comments on commit bad4b17

Please sign in to comment.