From 7a41d396ae0ac12b7ef934981949a04b48ab491b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 30 Dec 2015 16:31:13 +0200 Subject: [PATCH] rtsp-media: Add API to directly configure a clock on the media pipelines --- gst/rtsp-server/rtsp-media-factory.c | 70 ++++++++++++++++++++++++++++++++++++ gst/rtsp-server/rtsp-media-factory.h | 4 +++ gst/rtsp-server/rtsp-media.c | 46 ++++++++++++++++++++++++ gst/rtsp-server/rtsp-media.h | 2 ++ 4 files changed, 122 insertions(+) diff --git a/gst/rtsp-server/rtsp-media-factory.c b/gst/rtsp-server/rtsp-media-factory.c index 82afff5..3fd769d 100644 --- a/gst/rtsp-server/rtsp-media-factory.c +++ b/gst/rtsp-server/rtsp-media-factory.c @@ -69,6 +69,8 @@ struct _GstRTSPMediaFactoryPrivate GHashTable *medias; /* protected by medias_lock */ GType media_gtype; + + GstClock *clock; }; #define DEFAULT_LAUNCH NULL @@ -96,6 +98,7 @@ enum PROP_LATENCY, PROP_TRANSPORT_MODE, PROP_STOP_ON_DISCONNECT, + PROP_CLOCK, PROP_LAST }; @@ -212,6 +215,12 @@ gst_rtsp_media_factory_class_init (GstRTSPMediaFactoryClass * klass) DEFAULT_STOP_ON_DISCONNECT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_CLOCK, + g_param_spec_object ("clock", "Clock", + "Clock to be used by the pipelines created for all " + "medias of this factory", GST_TYPE_CLOCK, + 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, @@ -319,6 +328,9 @@ gst_rtsp_media_factory_get_property (GObject * object, guint propid, g_value_set_boolean (value, gst_rtsp_media_factory_is_stop_on_disonnect (factory)); break; + case PROP_CLOCK: + g_value_take_object (value, gst_rtsp_media_factory_get_clock (factory)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec); } @@ -366,6 +378,8 @@ gst_rtsp_media_factory_set_property (GObject * object, guint propid, gst_rtsp_media_factory_set_stop_on_disconnect (factory, g_value_get_boolean (value)); break; + case PROP_CLOCK: + gst_rtsp_media_factory_set_clock (factory, g_value_get_object (value)); default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec); } @@ -1211,6 +1225,55 @@ gst_rtsp_media_factory_get_media_gtype (GstRTSPMediaFactory * factory) return ret; } +/** + * gst_rtsp_media_factory_set_clock: + * @factory: a #GstRTSPMediaFactory + * @clockd: the clock to be used by the media factory + * + * Configures a specific clock to be used by the pipelines + * of all medias created from this factory. + * + * Since: 1.8 + */ +void +gst_rtsp_media_factory_set_clock (GstRTSPMediaFactory * factory, + GstClock * clock) +{ + GstRTSPMediaFactoryPrivate *priv; + + g_return_if_fail (GST_IS_CLOCK (clock) || clock == NULL); + + GST_RTSP_MEDIA_FACTORY_LOCK (factory); + priv = factory->priv; + priv->clock = clock ? gst_object_ref (clock) : NULL; + GST_RTSP_MEDIA_FACTORY_UNLOCK (factory); +} + +/** + * gst_rtsp_media_factory_get_clock: + * @factory: a #GstRTSPMediaFactory + * + * Returns the clock that is going to be used by the pipelines + * of all medias created from this factory. + * + * Returns: (transfer full): The GstClock + * + * Since: 1.8 + */ +GstClock * +gst_rtsp_media_factory_get_clock (GstRTSPMediaFactory * factory) +{ + GstRTSPMediaFactoryPrivate *priv; + GstClock *ret; + + GST_RTSP_MEDIA_FACTORY_LOCK (factory); + priv = factory->priv; + ret = priv->clock ? gst_object_ref (priv->clock) : NULL; + GST_RTSP_MEDIA_FACTORY_UNLOCK (factory); + + return ret; +} + static gchar * default_gen_key (GstRTSPMediaFactory * factory, const GstRTSPUrl * url) { @@ -1354,6 +1417,7 @@ default_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media) GstClockTime rtx_time; guint latency; GstRTSPTransportMode transport_mode; + GstClock *clock; /* configure the sharedness */ GST_RTSP_MEDIA_FACTORY_LOCK (factory); @@ -1367,6 +1431,7 @@ default_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media) latency = priv->latency; transport_mode = priv->transport_mode; stop_on_disconnect = priv->stop_on_disconnect; + clock = priv->clock ? gst_object_ref (priv->clock) : NULL; GST_RTSP_MEDIA_FACTORY_UNLOCK (factory); gst_rtsp_media_set_suspend_mode (media, suspend_mode); @@ -1380,6 +1445,11 @@ 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); + if (clock) { + gst_rtsp_media_set_clock (media, clock); + gst_object_unref (clock); + } + if ((pool = gst_rtsp_media_factory_get_address_pool (factory))) { gst_rtsp_media_set_address_pool (media, pool); g_object_unref (pool); diff --git a/gst/rtsp-server/rtsp-media-factory.h b/gst/rtsp-server/rtsp-media-factory.h index e82b64a..c4e0a8e 100644 --- a/gst/rtsp-server/rtsp-media-factory.h +++ b/gst/rtsp-server/rtsp-media-factory.h @@ -161,6 +161,10 @@ void gst_rtsp_media_factory_set_media_gtype (GstRTSPMediaFacto GType media_gtype); GType gst_rtsp_media_factory_get_media_gtype (GstRTSPMediaFactory * factory); +void gst_rtsp_media_factory_set_clock (GstRTSPMediaFactory *factory, + GstClock * clock); +GstClock * gst_rtsp_media_factory_get_clock (GstRTSPMediaFactory *factory); + /* creating the media from the factory and a url */ GstRTSPMedia * gst_rtsp_media_factory_construct (GstRTSPMediaFactory *factory, const GstRTSPUrl *url); diff --git a/gst/rtsp-server/rtsp-media.c b/gst/rtsp-server/rtsp-media.c index 6024bab..ae590bb 100644 --- a/gst/rtsp-server/rtsp-media.c +++ b/gst/rtsp-server/rtsp-media.c @@ -139,6 +139,7 @@ struct _GstRTSPMediaPrivate GList *payloads; /* protected by lock */ GstClockTime rtx_time; /* protected by lock */ guint latency; /* protected by lock */ + GstClock *clock; /* protected by lock */ }; #define DEFAULT_SHARED FALSE @@ -172,6 +173,7 @@ enum PROP_LATENCY, PROP_TRANSPORT_MODE, PROP_STOP_ON_DISCONNECT, + PROP_CLOCK, PROP_LAST }; @@ -339,6 +341,11 @@ gst_rtsp_media_class_init (GstRTSPMediaClass * klass) DEFAULT_STOP_ON_DISCONNECT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_CLOCK, + g_param_spec_object ("clock", "Clock", + "Clock to be used by the media pipeline", + GST_TYPE_CLOCK, 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, @@ -486,6 +493,9 @@ gst_rtsp_media_get_property (GObject * object, guint propid, case PROP_STOP_ON_DISCONNECT: g_value_set_boolean (value, gst_rtsp_media_is_stop_on_disconnect (media)); break; + case PROP_CLOCK: + g_value_take_object (value, gst_rtsp_media_get_clock (media)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec); } @@ -536,6 +546,9 @@ gst_rtsp_media_set_property (GObject * object, guint propid, gst_rtsp_media_set_stop_on_disconnect (media, g_value_get_boolean (value)); break; + case PROP_CLOCK: + gst_rtsp_media_set_clock (media, g_value_get_object (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec); } @@ -1391,6 +1404,39 @@ gst_rtsp_media_is_time_provider (GstRTSPMedia * media) } /** + * gst_rtsp_media_set_clock: + * @media: a #GstRTSPMedia + * @clock: #GstClock to be used + * + * Configure the clock used for the media. + */ +void +gst_rtsp_media_set_clock (GstRTSPMedia * media, GstClock * clock) +{ + GstRTSPMediaPrivate *priv; + + g_return_if_fail (GST_IS_RTSP_MEDIA (media)); + g_return_if_fail (GST_IS_CLOCK (clock) || clock == NULL); + + GST_LOG_OBJECT (media, "setting clock %" GST_PTR_FORMAT, clock); + + priv = media->priv; + + g_mutex_lock (&priv->lock); + if (priv->clock) + gst_object_unref (priv->clock); + priv->clock = clock ? gst_object_ref (clock) : NULL; + if (priv->pipeline) { + if (clock) + gst_pipeline_use_clock (GST_PIPELINE_CAST (priv->pipeline), clock); + else + gst_pipeline_auto_clock (GST_PIPELINE_CAST (priv->pipeline)); + } + + g_mutex_unlock (&priv->lock); +} + +/** * gst_rtsp_media_set_address_pool: * @media: a #GstRTSPMedia * @pool: (transfer none): a #GstRTSPAddressPool diff --git a/gst/rtsp-server/rtsp-media.h b/gst/rtsp-server/rtsp-media.h index edf669f..400c123 100644 --- a/gst/rtsp-server/rtsp-media.h +++ b/gst/rtsp-server/rtsp-media.h @@ -221,6 +221,8 @@ gboolean gst_rtsp_media_is_time_provider (GstRTSPMedia *media); GstNetTimeProvider * gst_rtsp_media_get_time_provider (GstRTSPMedia *media, const gchar *address, guint16 port); +void gst_rtsp_media_set_clock (GstRTSPMedia *media, GstClock * clock); + /* prepare the media for playback */ gboolean gst_rtsp_media_prepare (GstRTSPMedia *media, GstRTSPThread *thread); gboolean gst_rtsp_media_unprepare (GstRTSPMedia *media); -- 2.7.4