mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 00:36:51 +00:00
media-factory: add eos-shutdown property
Add an eos-shutdown property that will send an EOS to the pipeline before shutting it down. This allows for nice cleanup in case of a muxer. Fixes #625597
This commit is contained in:
parent
a900866570
commit
dc33070da3
4 changed files with 138 additions and 3 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
@ -444,6 +458,39 @@ gst_rtsp_media_get_protocols (GstRTSPMedia * media)
|
|||
return media->protocols;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue