summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gst/rtsp-server/rtsp-media-factory.c60
-rw-r--r--gst/rtsp-server/rtsp-media-factory.h5
-rw-r--r--gst/rtsp-server/rtsp-media.c71
-rw-r--r--gst/rtsp-server/rtsp-media.h5
4 files changed, 138 insertions, 3 deletions
diff --git a/gst/rtsp-server/rtsp-media-factory.c b/gst/rtsp-server/rtsp-media-factory.c
index 44d8098..92591aa 100644
--- a/gst/rtsp-server/rtsp-media-factory.c
+++ b/gst/rtsp-server/rtsp-media-factory.c
@@ -21,12 +21,14 @@
#define DEFAULT_LAUNCH NULL
#define DEFAULT_SHARED FALSE
+#define DEFAULT_EOS_SHUTDOWN FALSE
enum
{
PROP_0,
PROP_LAUNCH,
PROP_SHARED,
+ PROP_EOS_SHUTDOWN,
PROP_LAST
};
@@ -82,6 +84,11 @@ gst_rtsp_media_factory_class_init (GstRTSPMediaFactoryClass * klass)
g_param_spec_boolean ("shared", "Shared", "If media from this factory is shared",
DEFAULT_SHARED, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class, PROP_EOS_SHUTDOWN,
+ g_param_spec_boolean ("eos-shutdown", "EOS Shutdown",
+ "Send EOS down the pipeline before shutting down",
+ DEFAULT_EOS_SHUTDOWN, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
klass->gen_key = default_gen_key;
klass->get_element = default_get_element;
klass->construct = default_construct;
@@ -96,6 +103,7 @@ gst_rtsp_media_factory_init (GstRTSPMediaFactory * factory)
{
factory->launch = g_strdup (DEFAULT_LAUNCH);
factory->shared = DEFAULT_SHARED;
+ factory->eos_shutdown = DEFAULT_EOS_SHUTDOWN;
factory->lock = g_mutex_new ();
factory->medias_lock = g_mutex_new ();
@@ -129,6 +137,9 @@ gst_rtsp_media_factory_get_property (GObject *object, guint propid,
case PROP_SHARED:
g_value_set_boolean (value, gst_rtsp_media_factory_is_shared (factory));
break;
+ case PROP_EOS_SHUTDOWN:
+ g_value_set_boolean (value, gst_rtsp_media_factory_is_eos_shutdown (factory));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
}
@@ -147,6 +158,9 @@ gst_rtsp_media_factory_set_property (GObject *object, guint propid,
case PROP_SHARED:
gst_rtsp_media_factory_set_shared (factory, g_value_get_boolean (value));
break;
+ case PROP_EOS_SHUTDOWN:
+ gst_rtsp_media_factory_set_eos_shutdown (factory, g_value_get_boolean (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
}
@@ -260,6 +274,48 @@ gst_rtsp_media_factory_is_shared (GstRTSPMediaFactory *factory)
return result;
}
+/**
+ * gst_rtsp_media_factory_set_eos_shutdown:
+ * @factory: a #GstRTSPMediaFactory
+ * @eos_shutdown: the new value
+ *
+ * Configure if media created from this factory will have an EOS sent to the
+ * pipeline before shutdown.
+ */
+void
+gst_rtsp_media_factory_set_eos_shutdown (GstRTSPMediaFactory *factory,
+ gboolean eos_shutdown)
+{
+ g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
+
+ g_mutex_lock (factory->lock);
+ factory->eos_shutdown = eos_shutdown;
+ g_mutex_unlock (factory->lock);
+}
+
+/**
+ * gst_rtsp_media_factory_is_eos_shutdown:
+ * @factory: a #GstRTSPMediaFactory
+ *
+ * Get if media created from this factory will have an EOS event sent to the
+ * pipeline before shutdown.
+ *
+ * Returns: %TRUE if the media will receive EOS before shutdown.
+ */
+gboolean
+gst_rtsp_media_factory_is_eos_shutdown (GstRTSPMediaFactory *factory)
+{
+ gboolean result;
+
+ g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), FALSE);
+
+ g_mutex_lock (factory->lock);
+ result = factory->eos_shutdown;
+ g_mutex_unlock (factory->lock);
+
+ return result;
+}
+
static gboolean
compare_media (gpointer key, GstRTSPMedia *media1, GstRTSPMedia *media2)
{
@@ -536,12 +592,14 @@ no_element:
static void
default_configure (GstRTSPMediaFactory *factory, GstRTSPMedia *media)
{
- gboolean shared;
+ gboolean shared, eos_shutdown;
/* configure the sharedness */
g_mutex_lock (factory->lock);
shared = factory->shared;
+ eos_shutdown = factory->eos_shutdown;
g_mutex_unlock (factory->lock);
gst_rtsp_media_set_shared (media, shared);
+ gst_rtsp_media_set_eos_shutdown (media, eos_shutdown);
}
diff --git a/gst/rtsp-server/rtsp-media-factory.h b/gst/rtsp-server/rtsp-media-factory.h
index 3d1ac9b..d462914 100644
--- a/gst/rtsp-server/rtsp-media-factory.h
+++ b/gst/rtsp-server/rtsp-media-factory.h
@@ -57,6 +57,7 @@ struct _GstRTSPMediaFactory {
GMutex *lock;
gchar *launch;
gboolean shared;
+ gboolean eos_shutdown;
GMutex *medias_lock;
GHashTable *medias;
@@ -107,6 +108,10 @@ void gst_rtsp_media_factory_set_shared (GstRTSPMediaFactory *
gboolean shared);
gboolean gst_rtsp_media_factory_is_shared (GstRTSPMediaFactory *factory);
+void gst_rtsp_media_factory_set_eos_shutdown (GstRTSPMediaFactory *factory,
+ gboolean eos_shutdown);
+gboolean gst_rtsp_media_factory_is_eos_shutdown (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 c2dc996..02a9317 100644
--- a/gst/rtsp-server/rtsp-media.c
+++ b/gst/rtsp-server/rtsp-media.c
@@ -29,6 +29,7 @@
#define DEFAULT_REUSABLE FALSE
#define DEFAULT_PROTOCOLS GST_RTSP_LOWER_TRANS_UDP | GST_RTSP_LOWER_TRANS_TCP
//#define DEFAULT_PROTOCOLS GST_RTSP_LOWER_TRANS_UDP_MCAST
+#define DEFAULT_EOS_SHUTDOWN FALSE
/* define to dump received RTCP packets */
#undef DUMP_STATS
@@ -39,6 +40,7 @@ enum
PROP_SHARED,
PROP_REUSABLE,
PROP_PROTOCOLS,
+ PROP_EOS_SHUTDOWN,
PROP_LAST
};
@@ -96,6 +98,11 @@ gst_rtsp_media_class_init (GstRTSPMediaClass * klass)
"Allowed lower transport protocols", GST_TYPE_RTSP_LOWER_TRANS,
DEFAULT_PROTOCOLS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class, PROP_EOS_SHUTDOWN,
+ g_param_spec_boolean ("eos-shutdown", "EOS Shutdown",
+ "Send an EOS event to the pipeline before unpreparing",
+ DEFAULT_EOS_SHUTDOWN, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
gst_rtsp_media_signals[SIGNAL_UNPREPARED] =
g_signal_new ("unprepared", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstRTSPMediaClass, unprepared), NULL, NULL,
@@ -124,6 +131,7 @@ gst_rtsp_media_init (GstRTSPMedia * media)
media->shared = DEFAULT_SHARED;
media->reusable = DEFAULT_REUSABLE;
media->protocols = DEFAULT_PROTOCOLS;
+ media->eos_shutdown = DEFAULT_EOS_SHUTDOWN;
}
/* FIXME. this should be done in multiudpsink */
@@ -245,6 +253,9 @@ gst_rtsp_media_get_property (GObject * object, guint propid,
case PROP_PROTOCOLS:
g_value_set_flags (value, gst_rtsp_media_get_protocols (media));
break;
+ case PROP_EOS_SHUTDOWN:
+ g_value_set_boolean (value, gst_rtsp_media_is_eos_shutdown (media));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
}
@@ -266,6 +277,9 @@ gst_rtsp_media_set_property (GObject * object, guint propid,
case PROP_PROTOCOLS:
gst_rtsp_media_set_protocols (media, g_value_get_flags (value));
break;
+ case PROP_EOS_SHUTDOWN:
+ gst_rtsp_media_set_eos_shutdown (media, g_value_get_boolean (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
}
@@ -445,6 +459,39 @@ gst_rtsp_media_get_protocols (GstRTSPMedia * media)
}
/**
+ * gst_rtsp_media_set_eos_shutdown:
+ * @media: a #GstRTSPMedia
+ * @eos_shutdown: the new value
+ *
+ * Set or unset if an EOS event will be sent to the pipeline for @media before
+ * it is unprepared.
+ */
+void
+gst_rtsp_media_set_eos_shutdown (GstRTSPMedia *media, gboolean eos_shutdown)
+{
+ g_return_if_fail (GST_IS_RTSP_MEDIA (media));
+
+ media->eos_shutdown = eos_shutdown;
+}
+
+/**
+ * gst_rtsp_media_is_eos_shutdown:
+ * @media: a #GstRTSPMedia
+ *
+ * Check if the pipeline for @media will send an EOS down the pipeline before
+ * unpreparing.
+ *
+ * Returns: %TRUE if the media will send EOS before unpreparing.
+ */
+gboolean
+gst_rtsp_media_is_eos_shutdown (GstRTSPMedia *media)
+{
+ g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), FALSE);
+
+ return media->eos_shutdown;
+}
+
+/**
* gst_rtsp_media_n_streams:
* @media: a #GstRTSPMedia
*
@@ -1328,6 +1375,15 @@ default_handle_message (GstRTSPMedia * media, GstMessage * message)
gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_PREPARED);
break;
+ case GST_MESSAGE_EOS:
+ GST_INFO ("%p: got EOS", media);
+ if (media->eos_pending) {
+ GST_DEBUG ("shutting down after EOS");
+ gst_element_set_state (media->pipeline, GST_STATE_NULL);
+ media->eos_pending = FALSE;
+ g_object_unref (media);
+ }
+ break;
default:
GST_INFO ("%p: got message type %s", media,
gst_message_type_get_name (type));
@@ -1572,8 +1628,19 @@ gst_rtsp_media_unprepare (GstRTSPMedia * media)
static gboolean
default_unprepare (GstRTSPMedia * media)
{
- gst_element_set_state (media->pipeline, GST_STATE_NULL);
-
+ if (media->eos_shutdown) {
+ GST_DEBUG ("sending EOS for shutdown");
+ /* ref so that we don't disappear */
+ g_object_ref (media);
+ media->eos_pending = TRUE;
+ gst_element_send_event (media->pipeline, gst_event_new_eos());
+ /* we need to go to playing again for the EOS to propagate, normally in this
+ * state, nothing is receiving data from us anymore so this is ok. */
+ gst_element_set_state (media->pipeline, GST_STATE_PLAYING);
+ } else {
+ GST_DEBUG ("shutting down");
+ gst_element_set_state (media->pipeline, GST_STATE_NULL);
+ }
return TRUE;
}
diff --git a/gst/rtsp-server/rtsp-media.h b/gst/rtsp-server/rtsp-media.h
index 0dea08a..9f62074 100644
--- a/gst/rtsp-server/rtsp-media.h
+++ b/gst/rtsp-server/rtsp-media.h
@@ -200,12 +200,14 @@ struct _GstRTSPMedia {
GstRTSPLowerTrans protocols;
gboolean reused;
gboolean is_ipv6;
+ gboolean eos_shutdown;
GstElement *element;
GArray *streams;
GList *dynamic;
GstRTSPMediaStatus status;
gint active;
+ gboolean eos_pending;
/* the pipeline for the media */
GstElement *pipeline;
@@ -265,6 +267,9 @@ gboolean gst_rtsp_media_is_reusable (GstRTSPMedia *media);
void gst_rtsp_media_set_protocols (GstRTSPMedia *media, GstRTSPLowerTrans protocols);
GstRTSPLowerTrans gst_rtsp_media_get_protocols (GstRTSPMedia *media);
+void gst_rtsp_media_set_eos_shutdown (GstRTSPMedia *media, gboolean eos_shutdown);
+gboolean gst_rtsp_media_is_eos_shutdown (GstRTSPMedia *media);
+
/* prepare the media for playback */
gboolean gst_rtsp_media_prepare (GstRTSPMedia *media);
gboolean gst_rtsp_media_is_prepared (GstRTSPMedia *media);