mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-27 02:30:35 +00:00
ristsrc: Add support for dynamic payload
This commit ports functionality from the `rtpsrc` to make the `ristsrc` work with dynamic payload types. It adds two properties: - `caps` - `encoding-name` These can be used to make the `ristsrc` receive other payload types than the MPEG TS one. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5422>
This commit is contained in:
parent
8057597dd2
commit
f4fb4a5606
1 changed files with 128 additions and 12 deletions
|
@ -41,6 +41,22 @@
|
|||
* gst-play-1.0 "rist://0.0.0.0:5004?receiver-buffer=700"
|
||||
* ]|
|
||||
*
|
||||
* In order to use a dynamic payload type the element needs to be able
|
||||
* to set the correct caps. It can be done through setting the #GstRistSrc:caps
|
||||
* property or one can use the #GstRistSrc:encoding-name property and the
|
||||
* element can work out the caps from it.
|
||||
*
|
||||
* ## Example pipelines for sending and receiving dynamic payload
|
||||
* |[
|
||||
* gst-launch-1.0 videotestsrc ! videoconvert ! x264enc ! h264parse ! \
|
||||
* rtph264pay ! ristsink address=127.0.0.1 port=5000
|
||||
* ]| Encode and payload H264 video from videotestsrc. The H264 RTP packets are
|
||||
* sent on port 5000.
|
||||
* |[
|
||||
* gst-launch-1.0 ristsrc address=0.0.0.0 port=5000 encoding-name="h264" ! \
|
||||
* rtph264depay ! h264parse ! matroskamux ! filesink location=h264.mkv
|
||||
* ] Receive and depayload the H264 video via RIST.
|
||||
*
|
||||
* Additionally, this element supports link bonding, which means it
|
||||
* can receive the same stream from multiple addresses. Each address
|
||||
* will be mapped to its own RTP session. In order to enable bonding
|
||||
|
@ -92,7 +108,9 @@ enum
|
|||
PROP_MULTICAST_LOOPBACK,
|
||||
PROP_MULTICAST_IFACE,
|
||||
PROP_MULTICAST_TTL,
|
||||
PROP_BONDING_ADDRESSES
|
||||
PROP_BONDING_ADDRESSES,
|
||||
PROP_CAPS,
|
||||
PROP_ENCODING_NAME
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
|
||||
|
@ -156,6 +174,10 @@ struct _GstRistSrc
|
|||
* to fail state changes later */
|
||||
gboolean construct_failed;
|
||||
const gchar *missing_plugin;
|
||||
|
||||
/* For handling dynamic payload */
|
||||
GstCaps *caps;
|
||||
gchar *encoding_name;
|
||||
};
|
||||
|
||||
static void gst_rist_src_uri_init (gpointer g_iface, gpointer iface_data);
|
||||
|
@ -236,22 +258,52 @@ static GstCaps *
|
|||
gst_rist_src_request_pt_map (GstRistSrc * src, guint session_id, guint pt,
|
||||
GstElement * rtpbin)
|
||||
{
|
||||
const GstRTPPayloadInfo *pt_info;
|
||||
const GstRTPPayloadInfo *pt_info = NULL;
|
||||
GstCaps *ret;
|
||||
|
||||
pt_info = gst_rtp_payload_info_for_pt (pt);
|
||||
if (!pt_info || !pt_info->clock_rate)
|
||||
return NULL;
|
||||
GST_DEBUG_OBJECT (src,
|
||||
"Requesting caps for session-id 0x%x and pt %u.", session_id, pt);
|
||||
|
||||
ret = gst_caps_new_simple ("application/x-rtp",
|
||||
"media", G_TYPE_STRING, pt_info->media,
|
||||
"encoding_name", G_TYPE_STRING, pt_info->encoding_name,
|
||||
"clock-rate", G_TYPE_INT, (gint) pt_info->clock_rate, NULL);
|
||||
if (G_UNLIKELY (src->caps)) {
|
||||
GST_DEBUG_OBJECT (src,
|
||||
"Full caps were set, no need for lookup %" GST_PTR_FORMAT, src->caps);
|
||||
return gst_caps_copy (src->caps);
|
||||
}
|
||||
|
||||
/* FIXME add sprop-parameter-set if any */
|
||||
g_warn_if_fail (pt_info->encoding_parameters == NULL);
|
||||
if (src->encoding_name != NULL) {
|
||||
/* Unfortunately, the media needs to be passed in the function. Since
|
||||
* it is not known, try for video if video not found. */
|
||||
pt_info = gst_rtp_payload_info_for_name ("video", src->encoding_name);
|
||||
if (pt_info == NULL)
|
||||
pt_info = gst_rtp_payload_info_for_name ("audio", src->encoding_name);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* If we have not found any info from encoding-name we will try with a
|
||||
* static one. We need to check that is not a dynamic, since some encoders
|
||||
* do not use dynamic values. */
|
||||
if (pt_info == NULL) {
|
||||
if (!GST_RTP_PAYLOAD_IS_DYNAMIC (pt))
|
||||
pt_info = gst_rtp_payload_info_for_pt (pt);
|
||||
}
|
||||
|
||||
if (pt_info != NULL) {
|
||||
ret = gst_caps_new_simple ("application/x-rtp",
|
||||
"media", G_TYPE_STRING, pt_info->media,
|
||||
"encoding-name", G_TYPE_STRING, pt_info->encoding_name,
|
||||
"clock-rate", G_TYPE_INT, (gint) pt_info->clock_rate, NULL);
|
||||
|
||||
GST_DEBUG_OBJECT (src, "Decided on caps %" GST_PTR_FORMAT, ret);
|
||||
|
||||
/* FIXME add sprop-parameter-set if any */
|
||||
g_warn_if_fail (pt_info->encoding_parameters == NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (src,
|
||||
"Could not determine caps based on pt or encoding name.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GstElement *
|
||||
|
@ -407,6 +459,9 @@ gst_rist_src_init (GstRistSrc * src)
|
|||
g_mutex_init (&src->bonds_lock);
|
||||
src->bonds = g_ptr_array_new ();
|
||||
|
||||
src->encoding_name = NULL;
|
||||
src->caps = NULL;
|
||||
|
||||
/* Construct the RIST RTP receiver pipeline.
|
||||
*
|
||||
* udpsrc -> [recv_rtp_sink_%u] -------- [recv_rtp_src_%u_%u_%u]
|
||||
|
@ -1118,6 +1173,14 @@ gst_rist_src_get_property (GObject * object, guint prop_id,
|
|||
g_value_take_string (value, gst_rist_src_get_bonds (src));
|
||||
break;
|
||||
|
||||
case PROP_CAPS:
|
||||
gst_value_set_caps (value, src->caps);
|
||||
break;
|
||||
|
||||
case PROP_ENCODING_NAME:
|
||||
g_value_set_string (value, src->encoding_name);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -1218,6 +1281,31 @@ gst_rist_src_set_property (GObject * object, guint prop_id,
|
|||
gst_rist_src_set_bonds (src, g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_CAPS:
|
||||
{
|
||||
const GstCaps *new_caps_val = gst_value_get_caps (value);
|
||||
GstCaps *new_caps = NULL;
|
||||
|
||||
if (new_caps_val != NULL)
|
||||
new_caps = gst_caps_copy (new_caps_val);
|
||||
|
||||
gst_caps_replace (&src->caps, new_caps);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PROP_ENCODING_NAME:
|
||||
{
|
||||
g_free (src->encoding_name);
|
||||
src->encoding_name = g_value_dup_string (value);
|
||||
if (bond->rtp_src) {
|
||||
GstCaps *caps = gst_rist_src_request_pt_map (src, 0, 96, NULL);
|
||||
g_object_set (G_OBJECT (bond->rtp_src), "caps", caps, NULL);
|
||||
gst_caps_unref (caps);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -1246,6 +1334,9 @@ gst_rist_src_finalize (GObject * object)
|
|||
g_clear_object (&src->jitterbuffer);
|
||||
g_clear_object (&src->rtxbin);
|
||||
|
||||
gst_caps_unref (src->caps);
|
||||
g_free (src->encoding_name);
|
||||
|
||||
g_mutex_unlock (&src->bonds_lock);
|
||||
g_mutex_clear (&src->bonds_lock);
|
||||
|
||||
|
@ -1350,6 +1441,31 @@ gst_rist_src_class_init (GstRistSrcClass * klass)
|
|||
"Comma (,) separated list of <address>:<port> to receive from. "
|
||||
"Only used if 'enable-bonding' is set.", NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* GstRistSrc:encoding-name:
|
||||
*
|
||||
* Set the encoding name of the stream to use. This is a short-hand for
|
||||
* the full caps and maps typically to the encoding-name in the RTP caps.
|
||||
*
|
||||
* Since: 1.24
|
||||
*/
|
||||
g_object_class_install_property (object_class, PROP_ENCODING_NAME,
|
||||
g_param_spec_string ("encoding-name", "Caps encoding name",
|
||||
"Encoding name use to determine caps parameters",
|
||||
NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* GstRistSrc:caps:
|
||||
*
|
||||
* The RTP caps of the incoming RIST stream.
|
||||
*
|
||||
* Since: 1.24
|
||||
*/
|
||||
g_object_class_install_property (object_class, PROP_CAPS,
|
||||
g_param_spec_boxed ("caps", "Caps",
|
||||
"The caps of the incoming stream", GST_TYPE_CAPS,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
}
|
||||
|
||||
static GstURIType
|
||||
|
|
Loading…
Reference in a new issue