mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 05:06:17 +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_LAUNCH NULL
|
||||||
#define DEFAULT_SHARED FALSE
|
#define DEFAULT_SHARED FALSE
|
||||||
|
#define DEFAULT_EOS_SHUTDOWN FALSE
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_LAUNCH,
|
PROP_LAUNCH,
|
||||||
PROP_SHARED,
|
PROP_SHARED,
|
||||||
|
PROP_EOS_SHUTDOWN,
|
||||||
PROP_LAST
|
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",
|
g_param_spec_boolean ("shared", "Shared", "If media from this factory is shared",
|
||||||
DEFAULT_SHARED, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
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->gen_key = default_gen_key;
|
||||||
klass->get_element = default_get_element;
|
klass->get_element = default_get_element;
|
||||||
klass->construct = default_construct;
|
klass->construct = default_construct;
|
||||||
|
@ -96,6 +103,7 @@ gst_rtsp_media_factory_init (GstRTSPMediaFactory * factory)
|
||||||
{
|
{
|
||||||
factory->launch = g_strdup (DEFAULT_LAUNCH);
|
factory->launch = g_strdup (DEFAULT_LAUNCH);
|
||||||
factory->shared = DEFAULT_SHARED;
|
factory->shared = DEFAULT_SHARED;
|
||||||
|
factory->eos_shutdown = DEFAULT_EOS_SHUTDOWN;
|
||||||
|
|
||||||
factory->lock = g_mutex_new ();
|
factory->lock = g_mutex_new ();
|
||||||
factory->medias_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:
|
case PROP_SHARED:
|
||||||
g_value_set_boolean (value, gst_rtsp_media_factory_is_shared (factory));
|
g_value_set_boolean (value, gst_rtsp_media_factory_is_shared (factory));
|
||||||
break;
|
break;
|
||||||
|
case PROP_EOS_SHUTDOWN:
|
||||||
|
g_value_set_boolean (value, gst_rtsp_media_factory_is_eos_shutdown (factory));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
|
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:
|
case PROP_SHARED:
|
||||||
gst_rtsp_media_factory_set_shared (factory, g_value_get_boolean (value));
|
gst_rtsp_media_factory_set_shared (factory, g_value_get_boolean (value));
|
||||||
break;
|
break;
|
||||||
|
case PROP_EOS_SHUTDOWN:
|
||||||
|
gst_rtsp_media_factory_set_eos_shutdown (factory, g_value_get_boolean (value));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
|
||||||
}
|
}
|
||||||
|
@ -260,6 +274,48 @@ gst_rtsp_media_factory_is_shared (GstRTSPMediaFactory *factory)
|
||||||
return result;
|
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
|
static gboolean
|
||||||
compare_media (gpointer key, GstRTSPMedia *media1, GstRTSPMedia *media2)
|
compare_media (gpointer key, GstRTSPMedia *media1, GstRTSPMedia *media2)
|
||||||
{
|
{
|
||||||
|
@ -536,12 +592,14 @@ no_element:
|
||||||
static void
|
static void
|
||||||
default_configure (GstRTSPMediaFactory *factory, GstRTSPMedia *media)
|
default_configure (GstRTSPMediaFactory *factory, GstRTSPMedia *media)
|
||||||
{
|
{
|
||||||
gboolean shared;
|
gboolean shared, eos_shutdown;
|
||||||
|
|
||||||
/* configure the sharedness */
|
/* configure the sharedness */
|
||||||
g_mutex_lock (factory->lock);
|
g_mutex_lock (factory->lock);
|
||||||
shared = factory->shared;
|
shared = factory->shared;
|
||||||
|
eos_shutdown = factory->eos_shutdown;
|
||||||
g_mutex_unlock (factory->lock);
|
g_mutex_unlock (factory->lock);
|
||||||
|
|
||||||
gst_rtsp_media_set_shared (media, shared);
|
gst_rtsp_media_set_shared (media, shared);
|
||||||
|
gst_rtsp_media_set_eos_shutdown (media, eos_shutdown);
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,7 @@ struct _GstRTSPMediaFactory {
|
||||||
GMutex *lock;
|
GMutex *lock;
|
||||||
gchar *launch;
|
gchar *launch;
|
||||||
gboolean shared;
|
gboolean shared;
|
||||||
|
gboolean eos_shutdown;
|
||||||
|
|
||||||
GMutex *medias_lock;
|
GMutex *medias_lock;
|
||||||
GHashTable *medias;
|
GHashTable *medias;
|
||||||
|
@ -107,6 +108,10 @@ void gst_rtsp_media_factory_set_shared (GstRTSPMediaFactory *
|
||||||
gboolean shared);
|
gboolean shared);
|
||||||
gboolean gst_rtsp_media_factory_is_shared (GstRTSPMediaFactory *factory);
|
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 */
|
/* creating the media from the factory and a url */
|
||||||
GstRTSPMedia * gst_rtsp_media_factory_construct (GstRTSPMediaFactory *factory,
|
GstRTSPMedia * gst_rtsp_media_factory_construct (GstRTSPMediaFactory *factory,
|
||||||
const GstRTSPUrl *url);
|
const GstRTSPUrl *url);
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#define DEFAULT_REUSABLE FALSE
|
#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 | GST_RTSP_LOWER_TRANS_TCP
|
||||||
//#define DEFAULT_PROTOCOLS GST_RTSP_LOWER_TRANS_UDP_MCAST
|
//#define DEFAULT_PROTOCOLS GST_RTSP_LOWER_TRANS_UDP_MCAST
|
||||||
|
#define DEFAULT_EOS_SHUTDOWN FALSE
|
||||||
|
|
||||||
/* define to dump received RTCP packets */
|
/* define to dump received RTCP packets */
|
||||||
#undef DUMP_STATS
|
#undef DUMP_STATS
|
||||||
|
@ -39,6 +40,7 @@ enum
|
||||||
PROP_SHARED,
|
PROP_SHARED,
|
||||||
PROP_REUSABLE,
|
PROP_REUSABLE,
|
||||||
PROP_PROTOCOLS,
|
PROP_PROTOCOLS,
|
||||||
|
PROP_EOS_SHUTDOWN,
|
||||||
PROP_LAST
|
PROP_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -96,6 +98,11 @@ gst_rtsp_media_class_init (GstRTSPMediaClass * klass)
|
||||||
"Allowed lower transport protocols", GST_TYPE_RTSP_LOWER_TRANS,
|
"Allowed lower transport protocols", GST_TYPE_RTSP_LOWER_TRANS,
|
||||||
DEFAULT_PROTOCOLS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
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] =
|
gst_rtsp_media_signals[SIGNAL_UNPREPARED] =
|
||||||
g_signal_new ("unprepared", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
|
g_signal_new ("unprepared", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
|
||||||
G_STRUCT_OFFSET (GstRTSPMediaClass, unprepared), NULL, NULL,
|
G_STRUCT_OFFSET (GstRTSPMediaClass, unprepared), NULL, NULL,
|
||||||
|
@ -124,6 +131,7 @@ gst_rtsp_media_init (GstRTSPMedia * media)
|
||||||
media->shared = DEFAULT_SHARED;
|
media->shared = DEFAULT_SHARED;
|
||||||
media->reusable = DEFAULT_REUSABLE;
|
media->reusable = DEFAULT_REUSABLE;
|
||||||
media->protocols = DEFAULT_PROTOCOLS;
|
media->protocols = DEFAULT_PROTOCOLS;
|
||||||
|
media->eos_shutdown = DEFAULT_EOS_SHUTDOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME. this should be done in multiudpsink */
|
/* FIXME. this should be done in multiudpsink */
|
||||||
|
@ -245,6 +253,9 @@ gst_rtsp_media_get_property (GObject * object, guint propid,
|
||||||
case PROP_PROTOCOLS:
|
case PROP_PROTOCOLS:
|
||||||
g_value_set_flags (value, gst_rtsp_media_get_protocols (media));
|
g_value_set_flags (value, gst_rtsp_media_get_protocols (media));
|
||||||
break;
|
break;
|
||||||
|
case PROP_EOS_SHUTDOWN:
|
||||||
|
g_value_set_boolean (value, gst_rtsp_media_is_eos_shutdown (media));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
|
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:
|
case PROP_PROTOCOLS:
|
||||||
gst_rtsp_media_set_protocols (media, g_value_get_flags (value));
|
gst_rtsp_media_set_protocols (media, g_value_get_flags (value));
|
||||||
break;
|
break;
|
||||||
|
case PROP_EOS_SHUTDOWN:
|
||||||
|
gst_rtsp_media_set_eos_shutdown (media, g_value_get_boolean (value));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
|
||||||
}
|
}
|
||||||
|
@ -444,6 +458,39 @@ gst_rtsp_media_get_protocols (GstRTSPMedia * media)
|
||||||
return media->protocols;
|
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:
|
* gst_rtsp_media_n_streams:
|
||||||
* @media: a #GstRTSPMedia
|
* @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);
|
gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_PREPARED);
|
||||||
break;
|
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:
|
default:
|
||||||
GST_INFO ("%p: got message type %s", media,
|
GST_INFO ("%p: got message type %s", media,
|
||||||
gst_message_type_get_name (type));
|
gst_message_type_get_name (type));
|
||||||
|
@ -1572,8 +1628,19 @@ gst_rtsp_media_unprepare (GstRTSPMedia * media)
|
||||||
static gboolean
|
static gboolean
|
||||||
default_unprepare (GstRTSPMedia * media)
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -200,12 +200,14 @@ struct _GstRTSPMedia {
|
||||||
GstRTSPLowerTrans protocols;
|
GstRTSPLowerTrans protocols;
|
||||||
gboolean reused;
|
gboolean reused;
|
||||||
gboolean is_ipv6;
|
gboolean is_ipv6;
|
||||||
|
gboolean eos_shutdown;
|
||||||
|
|
||||||
GstElement *element;
|
GstElement *element;
|
||||||
GArray *streams;
|
GArray *streams;
|
||||||
GList *dynamic;
|
GList *dynamic;
|
||||||
GstRTSPMediaStatus status;
|
GstRTSPMediaStatus status;
|
||||||
gint active;
|
gint active;
|
||||||
|
gboolean eos_pending;
|
||||||
|
|
||||||
/* the pipeline for the media */
|
/* the pipeline for the media */
|
||||||
GstElement *pipeline;
|
GstElement *pipeline;
|
||||||
|
@ -265,6 +267,9 @@ gboolean gst_rtsp_media_is_reusable (GstRTSPMedia *media);
|
||||||
void gst_rtsp_media_set_protocols (GstRTSPMedia *media, GstRTSPLowerTrans protocols);
|
void gst_rtsp_media_set_protocols (GstRTSPMedia *media, GstRTSPLowerTrans protocols);
|
||||||
GstRTSPLowerTrans gst_rtsp_media_get_protocols (GstRTSPMedia *media);
|
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 */
|
/* prepare the media for playback */
|
||||||
gboolean gst_rtsp_media_prepare (GstRTSPMedia *media);
|
gboolean gst_rtsp_media_prepare (GstRTSPMedia *media);
|
||||||
gboolean gst_rtsp_media_is_prepared (GstRTSPMedia *media);
|
gboolean gst_rtsp_media_is_prepared (GstRTSPMedia *media);
|
||||||
|
|
Loading…
Reference in a new issue