From: Patricia Muscalu Date: Tue, 24 Jul 2018 07:35:46 +0000 (+0200) Subject: Add new API for setting/getting maximum multicast ttl value X-Git-Tag: 1.19.3~495^2~234 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a7bb684e9b2d56b5f95f42b042501c17bbcbf094;p=platform%2Fupstream%2Fgstreamer.git Add new API for setting/getting maximum multicast ttl value Change-Id: I5ef4758188c14785e17fb8fbf42a3dc0cb054233 https://bugzilla.gnome.org/show_bug.cgi?id=793441 --- diff --git a/gst/rtsp-server/rtsp-media-factory.c b/gst/rtsp-server/rtsp-media-factory.c index a4f10dd..53bce3e 100644 --- a/gst/rtsp-server/rtsp-media-factory.c +++ b/gst/rtsp-server/rtsp-media-factory.c @@ -59,6 +59,7 @@ struct _GstRTSPMediaFactoryPrivate GstRTSPTransportMode transport_mode; gboolean stop_on_disconnect; gchar *multicast_iface; + guint max_mcast_ttl; GstClockTime rtx_time; guint latency; @@ -83,6 +84,7 @@ struct _GstRTSPMediaFactoryPrivate GST_RTSP_LOWER_TRANS_TCP #define DEFAULT_BUFFER_SIZE 0x80000 #define DEFAULT_LATENCY 200 +#define DEFAULT_MAX_MCAST_TTL 255 #define DEFAULT_TRANSPORT_MODE GST_RTSP_TRANSPORT_MODE_PLAY #define DEFAULT_STOP_ON_DISCONNECT TRUE #define DEFAULT_DO_RETRANSMISSION FALSE @@ -101,6 +103,7 @@ enum PROP_TRANSPORT_MODE, PROP_STOP_ON_DISCONNECT, PROP_CLOCK, + PROP_MAX_MCAST_TTL, PROP_LAST }; @@ -222,6 +225,12 @@ gst_rtsp_media_factory_class_init (GstRTSPMediaFactoryClass * klass) "medias of this factory", GST_TYPE_CLOCK, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_MAX_MCAST_TTL, + g_param_spec_uint ("max-mcast-ttl", "Maximum multicast ttl", + "The maximum time-to-live value of outgoing multicast packets", 1, + 255, DEFAULT_MAX_MCAST_TTL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONSTRUCTED] = g_signal_new ("media-constructed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPMediaFactoryClass, @@ -263,6 +272,7 @@ gst_rtsp_media_factory_init (GstRTSPMediaFactory * factory) priv->stop_on_disconnect = DEFAULT_STOP_ON_DISCONNECT; priv->publish_clock_mode = GST_RTSP_PUBLISH_CLOCK_MODE_CLOCK; priv->do_retransmission = DEFAULT_DO_RETRANSMISSION; + priv->max_mcast_ttl = DEFAULT_MAX_MCAST_TTL; g_mutex_init (&priv->lock); g_mutex_init (&priv->medias_lock); @@ -337,6 +347,9 @@ gst_rtsp_media_factory_get_property (GObject * object, guint propid, case PROP_CLOCK: g_value_take_object (value, gst_rtsp_media_factory_get_clock (factory)); break; + case PROP_MAX_MCAST_TTL: + g_value_set_uint (value, + gst_rtsp_media_factory_get_max_mcast_ttl (factory)); default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec); } @@ -387,6 +400,9 @@ gst_rtsp_media_factory_set_property (GObject * object, guint propid, case PROP_CLOCK: gst_rtsp_media_factory_set_clock (factory, g_value_get_object (value)); break; + case PROP_MAX_MCAST_TTL: + gst_rtsp_media_factory_set_max_mcast_ttl (factory, + g_value_get_uint (value)); default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec); } @@ -1463,6 +1479,62 @@ gst_rtsp_media_factory_get_publish_clock_mode (GstRTSPMediaFactory * factory) return ret; } +/** + * gst_rtsp_media_factory_set_max_mcast_ttl: + * @factory: a #GstRTSPMedia + * @ttl: the new multicast ttl value + * + * Set the maximum time-to-live value of outgoing multicast packets. + * + * Returns: %TRUE if the requested ttl has been set successfully. + */ +gboolean +gst_rtsp_media_factory_set_max_mcast_ttl (GstRTSPMediaFactory * factory, + guint ttl) +{ + GstRTSPMediaFactoryPrivate *priv; + + g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), FALSE); + + priv = factory->priv; + + GST_RTSP_MEDIA_FACTORY_LOCK (factory); + if (ttl == 0 || ttl > DEFAULT_MAX_MCAST_TTL) { + GST_WARNING_OBJECT (factory, "The requested mcast TTL value is not valid."); + GST_RTSP_MEDIA_FACTORY_UNLOCK (factory); + return FALSE; + } + priv->max_mcast_ttl = ttl; + GST_RTSP_MEDIA_FACTORY_UNLOCK (factory); + + return TRUE; +} + +/** + * gst_rtsp_media_factory_get_max_mcast_ttl: + * @factory: a #GstRTSPMedia + * + * Get the the maximum time-to-live value of outgoing multicast packets. + * + * Returns: the maximum time-to-live value of outgoing multicast packets. + */ +guint +gst_rtsp_media_factory_get_max_mcast_ttl (GstRTSPMediaFactory * factory) +{ + GstRTSPMediaFactoryPrivate *priv; + guint result; + + g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), 0); + + priv = factory->priv; + + GST_RTSP_MEDIA_FACTORY_LOCK (factory); + result = priv->max_mcast_ttl; + GST_RTSP_MEDIA_FACTORY_UNLOCK (factory); + + return result; +} + static gchar * default_gen_key (GstRTSPMediaFactory * factory, const GstRTSPUrl * url) { @@ -1613,6 +1685,7 @@ default_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media) GstClock *clock; gchar *multicast_iface; GstRTSPPublishClockMode publish_clock_mode; + guint ttl; /* configure the sharedness */ GST_RTSP_MEDIA_FACTORY_LOCK (factory); @@ -1628,6 +1701,7 @@ default_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media) stop_on_disconnect = priv->stop_on_disconnect; clock = priv->clock ? gst_object_ref (priv->clock) : NULL; publish_clock_mode = priv->publish_clock_mode; + ttl = priv->max_mcast_ttl; GST_RTSP_MEDIA_FACTORY_UNLOCK (factory); gst_rtsp_media_set_suspend_mode (media, suspend_mode); @@ -1642,6 +1716,7 @@ default_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media) gst_rtsp_media_set_transport_mode (media, transport_mode); gst_rtsp_media_set_stop_on_disconnect (media, stop_on_disconnect); gst_rtsp_media_set_publish_clock_mode (media, publish_clock_mode); + gst_rtsp_media_set_max_mcast_ttl (media, ttl); if (clock) { gst_rtsp_media_set_clock (media, clock); diff --git a/gst/rtsp-server/rtsp-media-factory.h b/gst/rtsp-server/rtsp-media-factory.h index 7fb7fcc..46d7d55 100644 --- a/gst/rtsp-server/rtsp-media-factory.h +++ b/gst/rtsp-server/rtsp-media-factory.h @@ -239,6 +239,13 @@ void gst_rtsp_media_factory_set_publish_clock_mode (GstRTSPMe GST_RTSP_SERVER_API GstRTSPPublishClockMode gst_rtsp_media_factory_get_publish_clock_mode (GstRTSPMediaFactory * factory); +GST_RTSP_SERVER_API +gboolean gst_rtsp_media_factory_set_max_mcast_ttl (GstRTSPMediaFactory * factory, + guint ttl); + +GST_RTSP_SERVER_API +guint gst_rtsp_media_factory_get_max_mcast_ttl (GstRTSPMediaFactory * factory); + /* creating the media from the factory and a url */ GST_RTSP_SERVER_API diff --git a/gst/rtsp-server/rtsp-media.c b/gst/rtsp-server/rtsp-media.c index f23b4c5..1073b89 100644 --- a/gst/rtsp-server/rtsp-media.c +++ b/gst/rtsp-server/rtsp-media.c @@ -98,6 +98,7 @@ struct _GstRTSPMediaPrivate guint buffer_size; GstRTSPAddressPool *pool; gchar *multicast_iface; + guint max_mcast_ttl; gboolean blocked; GstRTSPTransportMode transport_mode; gboolean stop_on_disconnect; @@ -158,6 +159,7 @@ struct _GstRTSPMediaPrivate #define DEFAULT_LATENCY 200 #define DEFAULT_TRANSPORT_MODE GST_RTSP_TRANSPORT_MODE_PLAY #define DEFAULT_STOP_ON_DISCONNECT TRUE +#define DEFAULT_MAX_MCAST_TTL 255 #define DEFAULT_DO_RETRANSMISSION FALSE @@ -180,6 +182,7 @@ enum PROP_TRANSPORT_MODE, PROP_STOP_ON_DISCONNECT, PROP_CLOCK, + PROP_MAX_MCAST_TTL, PROP_LAST }; @@ -375,6 +378,12 @@ gst_rtsp_media_class_init (GstRTSPMediaClass * klass) "Clock to be used by the media pipeline", GST_TYPE_CLOCK, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_MAX_MCAST_TTL, + g_param_spec_uint ("max-mcast-ttl", "Maximum multicast ttl", + "The maximum time-to-live value of outgoing multicast packets", 1, + 255, DEFAULT_MAX_MCAST_TTL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + gst_rtsp_media_signals[SIGNAL_NEW_STREAM] = g_signal_new ("new-stream", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPMediaClass, new_stream), NULL, NULL, @@ -445,6 +454,7 @@ gst_rtsp_media_init (GstRTSPMedia * media) priv->stop_on_disconnect = DEFAULT_STOP_ON_DISCONNECT; priv->publish_clock_mode = GST_RTSP_PUBLISH_CLOCK_MODE_CLOCK; priv->do_retransmission = DEFAULT_DO_RETRANSMISSION; + priv->max_mcast_ttl = DEFAULT_MAX_MCAST_TTL; } static void @@ -531,6 +541,9 @@ gst_rtsp_media_get_property (GObject * object, guint propid, case PROP_CLOCK: g_value_take_object (value, gst_rtsp_media_get_clock (media)); break; + case PROP_MAX_MCAST_TTL: + g_value_set_uint (value, gst_rtsp_media_get_max_mcast_ttl (media)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec); } @@ -584,6 +597,9 @@ gst_rtsp_media_set_property (GObject * object, guint propid, case PROP_CLOCK: gst_rtsp_media_set_clock (media, g_value_get_object (value)); break; + case PROP_MAX_MCAST_TTL: + gst_rtsp_media_set_max_mcast_ttl (media, g_value_get_uint (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec); } @@ -1823,6 +1839,70 @@ gst_rtsp_media_get_multicast_iface (GstRTSPMedia * media) return result; } +/** + * gst_rtsp_media_set_max_mcast_ttl: + * @media: a #GstRTSPMedia + * @ttl: the new multicast ttl value + * + * Set the maximum time-to-live value of outgoing multicast packets. + * + * Returns: %TRUE if the requested ttl has been set successfully. + */ +gboolean +gst_rtsp_media_set_max_mcast_ttl (GstRTSPMedia * media, guint ttl) +{ + GstRTSPMediaPrivate *priv; + guint i; + + g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), FALSE); + + GST_LOG_OBJECT (media, "set max mcast ttl %u", ttl); + + priv = media->priv; + + g_mutex_lock (&priv->lock); + + if (ttl == 0 || ttl > DEFAULT_MAX_MCAST_TTL) { + GST_WARNING_OBJECT (media, "The reqested mcast TTL value is not valid."); + g_mutex_unlock (&priv->lock); + return FALSE; + } + priv->max_mcast_ttl = ttl; + + for (i = 0; i < priv->streams->len; i++) { + GstRTSPStream *stream = g_ptr_array_index (priv->streams, i); + gst_rtsp_stream_set_max_mcast_ttl (stream, ttl); + } + g_mutex_unlock (&priv->lock); + + return TRUE; +} + +/** + * gst_rtsp_media_get_max_mcast_ttl: + * @media: a #GstRTSPMedia + * + * Get the the maximum time-to-live value of outgoing multicast packets. + * + * Returns: the maximum time-to-live value of outgoing multicast packets. + */ +guint +gst_rtsp_media_get_max_mcast_ttl (GstRTSPMedia * media) +{ + GstRTSPMediaPrivate *priv; + guint res; + + g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), FALSE); + + priv = media->priv; + + g_mutex_lock (&priv->lock); + res = priv->max_mcast_ttl; + g_mutex_unlock (&priv->lock); + + return res; +} + static GList * _find_payload_types (GstRTSPMedia * media) { @@ -2140,6 +2220,7 @@ gst_rtsp_media_create_stream (GstRTSPMedia * media, GstElement * payloader, if (priv->pool) gst_rtsp_stream_set_address_pool (stream, priv->pool); gst_rtsp_stream_set_multicast_iface (stream, priv->multicast_iface); + gst_rtsp_stream_set_max_mcast_ttl (stream, priv->max_mcast_ttl); gst_rtsp_stream_set_profiles (stream, priv->profiles); gst_rtsp_stream_set_protocols (stream, priv->protocols); gst_rtsp_stream_set_retransmission_time (stream, priv->rtx_time); diff --git a/gst/rtsp-server/rtsp-media.h b/gst/rtsp-server/rtsp-media.h index 84dfb14..92b3866 100644 --- a/gst/rtsp-server/rtsp-media.h +++ b/gst/rtsp-server/rtsp-media.h @@ -314,6 +314,12 @@ void gst_rtsp_media_set_publish_clock_mode (GstRTSPMedia * me GST_RTSP_SERVER_API GstRTSPPublishClockMode gst_rtsp_media_get_publish_clock_mode (GstRTSPMedia * media); +GST_RTSP_SERVER_API +gboolean gst_rtsp_media_set_max_mcast_ttl (GstRTSPMedia *media, guint ttl); + +GST_RTSP_SERVER_API +guint gst_rtsp_media_get_max_mcast_ttl (GstRTSPMedia *media); + /* prepare the media for playback */ GST_RTSP_SERVER_API diff --git a/gst/rtsp-server/rtsp-stream.c b/gst/rtsp-server/rtsp-stream.c index b95ead9..1a68fd5 100644 --- a/gst/rtsp-server/rtsp-stream.c +++ b/gst/rtsp-server/rtsp-stream.c @@ -145,6 +145,7 @@ struct _GstRTSPStreamPrivate GstRTSPAddress *mcast_addr_v6; gchar *multicast_iface; + guint max_mcast_ttl; /* the caps of the stream */ gulong caps_sig; @@ -181,6 +182,7 @@ struct _GstRTSPStreamPrivate #define DEFAULT_PROFILES GST_RTSP_PROFILE_AVP #define DEFAULT_PROTOCOLS GST_RTSP_LOWER_TRANS_UDP | GST_RTSP_LOWER_TRANS_UDP_MCAST | \ GST_RTSP_LOWER_TRANS_TCP +#define DEFAULT_MAX_MCAST_TTL 255 enum { @@ -280,6 +282,7 @@ gst_rtsp_stream_init (GstRTSPStream * stream) priv->allowed_protocols = DEFAULT_PROTOCOLS; priv->configured_protocols = 0; priv->publish_clock_mode = GST_RTSP_PUBLISH_CLOCK_MODE_CLOCK; + priv->max_mcast_ttl = DEFAULT_MAX_MCAST_TTL; g_mutex_init (&priv->lock); @@ -1884,6 +1887,54 @@ gst_rtsp_stream_get_buffer_size (GstRTSPStream * stream) return buffer_size; } +/** + * gst_rtsp_stream_set_max_mcast_ttl: + * @stream: a #GstRTSPStream + * @ttl: the new multicast ttl value + * + * Set the maximum time-to-live value of outgoing multicast packets. + * + * Returns: %TRUE if the requested ttl has been set successfully. + * + */ +gboolean +gst_rtsp_stream_set_max_mcast_ttl (GstRTSPStream * stream, guint ttl) +{ + g_return_val_if_fail (GST_IS_RTSP_STREAM (stream), FALSE); + + g_mutex_lock (&stream->priv->lock); + if (ttl == 0 || ttl > DEFAULT_MAX_MCAST_TTL) { + GST_WARNING_OBJECT (stream, "The reqested mcast TTL value is not valid."); + g_mutex_unlock (&stream->priv->lock); + return FALSE; + } + stream->priv->max_mcast_ttl = ttl; + g_mutex_unlock (&stream->priv->lock); + + return TRUE; +} + +/** + * gst_rtsp_stream_get_max_mcast_ttl: + * @stream: a #GstRTSPStream + * + * Get the the maximum time-to-live value of outgoing multicast packets. + * + * Returns: the maximum time-to-live value of outgoing multicast packets. + * + */ +guint +gst_rtsp_stream_get_max_mcast_ttl (GstRTSPStream * stream) +{ + guint ttl; + + g_mutex_lock (&stream->priv->lock); + ttl = stream->priv->max_mcast_ttl; + g_mutex_unlock (&stream->priv->lock); + + return ttl; +} + /* executed from streaming thread */ static void caps_notify (GstPad * pad, GParamSpec * unused, GstRTSPStream * stream) diff --git a/gst/rtsp-server/rtsp-stream.h b/gst/rtsp-server/rtsp-stream.h index 1f527a4..1ee146d 100644 --- a/gst/rtsp-server/rtsp-stream.h +++ b/gst/rtsp-server/rtsp-stream.h @@ -293,6 +293,12 @@ GST_RTSP_SERVER_API GstRTSPPublishClockMode gst_rtsp_stream_get_publish_clock_mode (GstRTSPStream * stream); GST_RTSP_SERVER_API +gboolean gst_rtsp_stream_set_max_mcast_ttl (GstRTSPStream *stream, guint ttl); + +GST_RTSP_SERVER_API +guint gst_rtsp_stream_get_max_mcast_ttl (GstRTSPStream *stream); + +GST_RTSP_SERVER_API gboolean gst_rtsp_stream_complete_stream (GstRTSPStream * stream, const GstRTSPTransport * transport); GST_RTSP_SERVER_API diff --git a/tests/check/gst/mediafactory.c b/tests/check/gst/mediafactory.c index b6b250b..ba1719e 100644 --- a/tests/check/gst/mediafactory.c +++ b/tests/check/gst/mediafactory.c @@ -314,6 +314,63 @@ GST_START_TEST (test_reset) GST_END_TEST; +GST_START_TEST (test_mcast_ttl) +{ + GstRTSPMediaFactory *factory; + GstElement *element; + GstRTSPMedia *media; + GstRTSPUrl *url; + GstRTSPStream *stream; + + factory = gst_rtsp_media_factory_new (); + gst_rtsp_media_factory_set_shared (factory, TRUE); + fail_unless (gst_rtsp_url_parse ("rtsp://localhost:8554/test", + &url) == GST_RTSP_OK); + + gst_rtsp_media_factory_set_launch (factory, + "( videotestsrc ! rtpvrawpay pt=96 name=pay0 " + " audiotestsrc ! audioconvert ! rtpL16pay name=pay1 )"); + + /* try to set an invalid ttl and make sure that the default ttl value (255) is + * set */ + gst_rtsp_media_factory_set_max_mcast_ttl (factory, 0); + fail_unless (gst_rtsp_media_factory_get_max_mcast_ttl (factory) == 255); + gst_rtsp_media_factory_set_max_mcast_ttl (factory, 300); + fail_unless (gst_rtsp_media_factory_get_max_mcast_ttl (factory) == 255); + + /* set a valid ttl value */ + gst_rtsp_media_factory_set_max_mcast_ttl (factory, 3); + fail_unless (gst_rtsp_media_factory_get_max_mcast_ttl (factory) == 3); + + element = gst_rtsp_media_factory_create_element (factory, url); + fail_unless (GST_IS_BIN (element)); + fail_if (GST_IS_PIPELINE (element)); + gst_object_unref (element); + + media = gst_rtsp_media_factory_construct (factory, url); + fail_unless (GST_IS_RTSP_MEDIA (media)); + + fail_unless (gst_rtsp_media_n_streams (media) == 2); + fail_unless (gst_rtsp_media_get_max_mcast_ttl (media) == 3); + + /* verify that the correct ttl value has been propageted to the media + * streams */ + stream = gst_rtsp_media_get_stream (media, 0); + fail_unless (stream != NULL); + fail_unless (gst_rtsp_stream_get_max_mcast_ttl (stream) == 3); + + stream = gst_rtsp_media_get_stream (media, 1); + fail_unless (stream != NULL); + fail_unless (gst_rtsp_stream_get_max_mcast_ttl (stream) == 3); + + g_object_unref (media); + + gst_rtsp_url_free (url); + g_object_unref (factory); +} + +GST_END_TEST; + static Suite * rtspmediafactory_suite (void) { @@ -329,6 +386,7 @@ rtspmediafactory_suite (void) tcase_add_test (tc, test_addresspool); tcase_add_test (tc, test_permissions); tcase_add_test (tc, test_reset); + tcase_add_test (tc, test_mcast_ttl); return s; }