diff --git a/gst/rtsp-server/rtsp-media-factory.c b/gst/rtsp-server/rtsp-media-factory.c index d04c6382c3..590b1f7d69 100644 --- a/gst/rtsp-server/rtsp-media-factory.c +++ b/gst/rtsp-server/rtsp-media-factory.c @@ -51,6 +51,7 @@ struct _GstRTSPMediaFactoryPrivate GstRTSPPermissions *permissions; gchar *launch; gboolean shared; + GstRTSPSuspendMode suspend_mode; gboolean eos_shutdown; GstRTSPLowerTrans protocols; guint buffer_size; @@ -62,6 +63,7 @@ struct _GstRTSPMediaFactoryPrivate #define DEFAULT_LAUNCH NULL #define DEFAULT_SHARED FALSE +#define DEFAULT_SUSPEND_MODE GST_RTSP_SUSPEND_MODE_NONE #define DEFAULT_EOS_SHUTDOWN FALSE #define DEFAULT_PROTOCOLS GST_RTSP_LOWER_TRANS_UDP | GST_RTSP_LOWER_TRANS_UDP_MCAST | \ GST_RTSP_LOWER_TRANS_TCP @@ -72,6 +74,7 @@ enum PROP_0, PROP_LAUNCH, PROP_SHARED, + PROP_SUSPEND_MODE, PROP_EOS_SHUTDOWN, PROP_PROTOCOLS, PROP_BUFFER_SIZE, @@ -148,6 +151,11 @@ gst_rtsp_media_factory_class_init (GstRTSPMediaFactoryClass * klass) "If media from this factory is shared", DEFAULT_SHARED, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_SUSPEND_MODE, + g_param_spec_enum ("suspend-mode", "Suspend Mode", + "Control how media will be suspended", GST_TYPE_RTSP_SUSPEND_MODE, + DEFAULT_SUSPEND_MODE, 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", @@ -194,6 +202,7 @@ gst_rtsp_media_factory_init (GstRTSPMediaFactory * factory) priv->launch = g_strdup (DEFAULT_LAUNCH); priv->shared = DEFAULT_SHARED; + priv->suspend_mode = DEFAULT_SUSPEND_MODE; priv->eos_shutdown = DEFAULT_EOS_SHUTDOWN; priv->protocols = DEFAULT_PROTOCOLS; priv->buffer_size = DEFAULT_BUFFER_SIZE; @@ -235,6 +244,10 @@ 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_SUSPEND_MODE: + g_value_set_enum (value, + gst_rtsp_media_factory_get_suspend_mode (factory)); + break; case PROP_EOS_SHUTDOWN: g_value_set_boolean (value, gst_rtsp_media_factory_is_eos_shutdown (factory)); @@ -264,6 +277,10 @@ 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_SUSPEND_MODE: + gst_rtsp_media_factory_set_suspend_mode (factory, + g_value_get_enum (value)); + break; case PROP_EOS_SHUTDOWN: gst_rtsp_media_factory_set_eos_shutdown (factory, g_value_get_boolean (value)); @@ -442,6 +459,54 @@ gst_rtsp_media_factory_get_launch (GstRTSPMediaFactory * factory) return result; } +/** + * gst_rtsp_media_factory_set_suspend_mode: + * @factory: a #GstRTSPMediaFactory + * @mode: the new #GstRTSPSuspendMode + * + * Configure how media created from this factory will be suspended. + */ +void +gst_rtsp_media_factory_set_suspend_mode (GstRTSPMediaFactory * factory, + GstRTSPSuspendMode mode) +{ + GstRTSPMediaFactoryPrivate *priv; + + g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory)); + + priv = factory->priv; + + GST_RTSP_MEDIA_FACTORY_LOCK (factory); + priv->suspend_mode = mode; + GST_RTSP_MEDIA_FACTORY_UNLOCK (factory); +} + +/** + * gst_rtsp_media_factory_get_suspend_mode: + * @factory: a #GstRTSPMediaFactory + * + * Get how media created from this factory will be suspended. + * + * Returns: a #GstRTSPSuspendMode. + */ +GstRTSPSuspendMode +gst_rtsp_media_factory_get_suspend_mode (GstRTSPMediaFactory * factory) +{ + GstRTSPMediaFactoryPrivate *priv; + GstRTSPSuspendMode result; + + g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), + GST_RTSP_SUSPEND_MODE_NONE); + + priv = factory->priv; + + GST_RTSP_MEDIA_FACTORY_LOCK (factory); + result = priv->suspend_mode; + GST_RTSP_MEDIA_FACTORY_UNLOCK (factory); + + return result; +} + /** * gst_rtsp_media_factory_set_shared: * @factory: a #GstRTSPMediaFactory @@ -946,18 +1011,21 @@ default_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media) GstRTSPMediaFactoryPrivate *priv = factory->priv; gboolean shared, eos_shutdown; guint size; + GstRTSPSuspendMode suspend_mode; GstRTSPLowerTrans protocols; GstRTSPAddressPool *pool; GstRTSPPermissions *perms; /* configure the sharedness */ GST_RTSP_MEDIA_FACTORY_LOCK (factory); + suspend_mode = priv->suspend_mode; shared = priv->shared; eos_shutdown = priv->eos_shutdown; size = priv->buffer_size; protocols = priv->protocols; GST_RTSP_MEDIA_FACTORY_UNLOCK (factory); + gst_rtsp_media_set_suspend_mode (media, suspend_mode); gst_rtsp_media_set_shared (media, shared); gst_rtsp_media_set_eos_shutdown (media, eos_shutdown); gst_rtsp_media_set_buffer_size (media, size); diff --git a/gst/rtsp-server/rtsp-media-factory.h b/gst/rtsp-server/rtsp-media-factory.h index d8819b16eb..63f4d827cf 100644 --- a/gst/rtsp-server/rtsp-media-factory.h +++ b/gst/rtsp-server/rtsp-media-factory.h @@ -114,6 +114,10 @@ void gst_rtsp_media_factory_set_shared (GstRTSPMediaFacto gboolean shared); gboolean gst_rtsp_media_factory_is_shared (GstRTSPMediaFactory *factory); +void gst_rtsp_media_factory_set_suspend_mode (GstRTSPMediaFactory *factory, + GstRTSPSuspendMode mode); +GstRTSPSuspendMode gst_rtsp_media_factory_get_suspend_mode (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); diff --git a/gst/rtsp-server/rtsp-media.c b/gst/rtsp-server/rtsp-media.c index e1dd573059..2c72d97205 100644 --- a/gst/rtsp-server/rtsp-media.c +++ b/gst/rtsp-server/rtsp-media.c @@ -80,6 +80,7 @@ struct _GstRTSPMediaPrivate /* protected by lock */ GstRTSPPermissions *permissions; gboolean shared; + gboolean suspend_mode; gboolean reusable; GstRTSPLowerTrans protocols; gboolean reused; @@ -122,6 +123,7 @@ struct _GstRTSPMediaPrivate }; #define DEFAULT_SHARED FALSE +#define DEFAULT_SUSPEND_MODE GST_RTSP_SUSPEND_MODE_NONE #define DEFAULT_REUSABLE FALSE #define DEFAULT_PROTOCOLS GST_RTSP_LOWER_TRANS_UDP | GST_RTSP_LOWER_TRANS_UDP_MCAST | \ GST_RTSP_LOWER_TRANS_TCP @@ -136,6 +138,7 @@ enum { PROP_0, PROP_SHARED, + PROP_SUSPEND_MODE, PROP_REUSABLE, PROP_PROTOCOLS, PROP_EOS_SHUTDOWN, @@ -178,6 +181,29 @@ static gboolean wait_preroll (GstRTSPMedia * media); static guint gst_rtsp_media_signals[SIGNAL_LAST] = { 0 }; +#define C_ENUM(v) ((gint) v) + +#define GST_TYPE_RTSP_SUSPEND_MODE (gst_rtsp_suspend_mode_get_type()) +GType +gst_rtsp_suspend_mode_get_type (void) +{ + static gsize id = 0; + static const GEnumValue values[] = { + {C_ENUM (GST_RTSP_SUSPEND_MODE_NONE), "GST_RTSP_SUSPEND_MODE_NONE", "none"}, + {C_ENUM (GST_RTSP_SUSPEND_MODE_PAUSE), "GST_RTSP_SUSPEND_MODE_PAUSE", + "pause"}, + {C_ENUM (GST_RTSP_SUSPEND_MODE_RESET), "GST_RTSP_SUSPEND_MODE_RESET", + "reset"}, + {0, NULL, NULL} + }; + + if (g_once_init_enter (&id)) { + GType tmp = g_enum_register_static ("GstRTSPSuspendMode", values); + g_once_init_leave (&id, tmp); + } + return (GType) id; +} + G_DEFINE_TYPE (GstRTSPMedia, gst_rtsp_media, G_TYPE_OBJECT); static void @@ -198,6 +224,11 @@ gst_rtsp_media_class_init (GstRTSPMediaClass * klass) "If this media pipeline can be shared", DEFAULT_SHARED, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_SUSPEND_MODE, + g_param_spec_enum ("suspend-mode", "Suspend Mode", + "How to suspend the media in PAUSED", GST_TYPE_RTSP_SUSPEND_MODE, + DEFAULT_SUSPEND_MODE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_REUSABLE, g_param_spec_boolean ("reusable", "Reusable", "If this media pipeline can be reused after an unprepare", @@ -276,6 +307,7 @@ gst_rtsp_media_init (GstRTSPMedia * media) g_rec_mutex_init (&priv->state_lock); priv->shared = DEFAULT_SHARED; + priv->suspend_mode = DEFAULT_SUSPEND_MODE; priv->reusable = DEFAULT_REUSABLE; priv->protocols = DEFAULT_PROTOCOLS; priv->eos_shutdown = DEFAULT_EOS_SHUTDOWN; @@ -328,6 +360,9 @@ gst_rtsp_media_get_property (GObject * object, guint propid, case PROP_SHARED: g_value_set_boolean (value, gst_rtsp_media_is_shared (media)); break; + case PROP_SUSPEND_MODE: + g_value_set_enum (value, gst_rtsp_media_get_suspend_mode (media)); + break; case PROP_REUSABLE: g_value_set_boolean (value, gst_rtsp_media_is_reusable (media)); break; @@ -362,6 +397,9 @@ gst_rtsp_media_set_property (GObject * object, guint propid, case PROP_SHARED: gst_rtsp_media_set_shared (media, g_value_get_boolean (value)); break; + case PROP_SUSPEND_MODE: + gst_rtsp_media_set_suspend_mode (media, g_value_get_enum (value)); + break; case PROP_REUSABLE: gst_rtsp_media_set_reusable (media, g_value_get_boolean (value)); break; @@ -606,6 +644,66 @@ gst_rtsp_media_get_permissions (GstRTSPMedia * media) return result; } +/** + * gst_rtsp_media_set_suspend_mode: + * @media: a #GstRTSPMedia + * @mode: the new #GstRTSPSuspendMode + * + * Control how @ media will be suspended after the SDP has been generated and + * after a PAUSE request has been performed. + * + * Media must be unprepared when setting the suspend mode. + */ +void +gst_rtsp_media_set_suspend_mode (GstRTSPMedia * media, GstRTSPSuspendMode mode) +{ + GstRTSPMediaPrivate *priv; + + g_return_if_fail (GST_IS_RTSP_MEDIA (media)); + + priv = media->priv; + + g_rec_mutex_lock (&priv->state_lock); + if (priv->status == GST_RTSP_MEDIA_STATUS_PREPARED) + goto was_prepared; + priv->suspend_mode = mode; + g_rec_mutex_unlock (&priv->state_lock); + + return; + + /* ERRORS */ +was_prepared: + { + GST_WARNING ("media %p was prepared", media); + g_rec_mutex_unlock (&priv->state_lock); + } +} + +/** + * gst_rtsp_media_get_suspend_mode: + * @media: a #GstRTSPMedia + * + * Get how @media will be suspended. + * + * Returns: #GstRTSPSuspendMode. + */ +GstRTSPSuspendMode +gst_rtsp_media_get_suspend_mode (GstRTSPMedia * media) +{ + GstRTSPMediaPrivate *priv; + GstRTSPSuspendMode res; + + g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), GST_RTSP_SUSPEND_MODE_NONE); + + priv = media->priv; + + g_rec_mutex_lock (&priv->state_lock); + res = priv->suspend_mode; + g_rec_mutex_unlock (&priv->state_lock); + + return res; +} + /** * gst_rtsp_media_set_shared: * @media: a #GstRTSPMedia @@ -2271,6 +2369,144 @@ gst_rtsp_media_get_time_provider (GstRTSPMedia * media, const gchar * address, return provider; } +/** + * gst_rtsp_media_suspend: + * @media: a #GstRTSPMedia + * + * Suspend @media. The state of the pipeline managed by @media is set to + * GST_STATE_NULL but all streams are kept. @media can be prepared again + * with gst_rtsp_media_undo_reset() + * + * @media must be prepared with gst_rtsp_media_prepare(); + * + * Returns: %TRUE on success. + */ +gboolean +gst_rtsp_media_suspend (GstRTSPMedia * media) +{ + GstRTSPMediaPrivate *priv = media->priv; + GstStateChangeReturn ret; + + g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), FALSE); + + GST_FIXME ("suspend for dynamic pipelines needs fixing"); + + g_rec_mutex_lock (&priv->state_lock); + if (priv->status != GST_RTSP_MEDIA_STATUS_PREPARED) + goto not_prepared; + + /* don't attempt to suspend when something is busy */ + if (priv->n_active > 0) + goto done; + + switch (priv->suspend_mode) { + case GST_RTSP_SUSPEND_MODE_NONE: + GST_DEBUG ("media %p no suspend", media); + break; + case GST_RTSP_SUSPEND_MODE_PAUSE: + GST_DEBUG ("media %p suspend to PAUSED", media); + priv->target_state = GST_STATE_PAUSED; + ret = gst_element_set_state (priv->pipeline, GST_STATE_PAUSED); + if (ret == GST_STATE_CHANGE_FAILURE) + goto state_failed; + break; + case GST_RTSP_SUSPEND_MODE_RESET: + GST_DEBUG ("media %p suspend to NULL", media); + priv->target_state = GST_STATE_NULL; + ret = gst_element_set_state (priv->pipeline, GST_STATE_NULL); + if (ret == GST_STATE_CHANGE_FAILURE) + goto state_failed; + break; + default: + break; + } + /* let the streams do the state changes freely, if any */ + media_streams_set_blocked (media, FALSE); + priv->status = GST_RTSP_MEDIA_STATUS_SUSPENDED; +done: + g_rec_mutex_unlock (&priv->state_lock); + + return TRUE; + + /* ERRORS */ +not_prepared: + { + g_rec_mutex_unlock (&priv->state_lock); + GST_WARNING ("media %p was not prepared", media); + return FALSE; + } +state_failed: + { + g_rec_mutex_unlock (&priv->state_lock); + gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_ERROR); + GST_WARNING ("failed changing pipeline's state for media %p", media); + return FALSE; + } +} + +/** + * gst_rtsp_media_unsuspend: + * @media: a #GstRTSPMedia + * + * Unsuspend @media if it was in a suspended state. This method does nothing + * when the media was not in the suspended state. + * + * Returns: %TRUE on success. + */ +gboolean +gst_rtsp_media_unsuspend (GstRTSPMedia * media) +{ + GstRTSPMediaPrivate *priv = media->priv; + + g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), FALSE); + + g_rec_mutex_lock (&priv->state_lock); + if (priv->status != GST_RTSP_MEDIA_STATUS_SUSPENDED) + goto done; + + switch (priv->suspend_mode) { + case GST_RTSP_SUSPEND_MODE_NONE: + priv->status = GST_RTSP_MEDIA_STATUS_PREPARED; + break; + case GST_RTSP_SUSPEND_MODE_PAUSE: + priv->status = GST_RTSP_MEDIA_STATUS_PREPARED; + break; + case GST_RTSP_SUSPEND_MODE_RESET: + { + priv->status = GST_RTSP_MEDIA_STATUS_PREPARING; + if (!start_preroll (media)) + goto start_failed; + g_rec_mutex_unlock (&priv->state_lock); + + if (!wait_preroll (media)) + goto preroll_failed; + + g_rec_mutex_lock (&priv->state_lock); + } + default: + break; + } +done: + g_rec_mutex_unlock (&priv->state_lock); + + return TRUE; + + /* ERRORS */ +start_failed: + { + g_rec_mutex_unlock (&priv->state_lock); + GST_WARNING ("failed to preroll pipeline"); + gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_ERROR); + return FALSE; + } +preroll_failed: + { + GST_WARNING ("failed to preroll pipeline"); + return FALSE; + } +} + +/* must be called with state-lock */ static void media_set_pipeline_state_locked (GstRTSPMedia * media, GstState state) { @@ -2291,6 +2527,10 @@ media_set_pipeline_state_locked (GstRTSPMedia * media, GstState state) media_streams_set_blocked (media, FALSE); gst_element_set_state (priv->pipeline, state); + + /* and suspend after pause */ + if (state == GST_STATE_PAUSED) + gst_rtsp_media_suspend (media); } } } diff --git a/gst/rtsp-server/rtsp-media.h b/gst/rtsp-server/rtsp-media.h index 016526dd88..735576ba6f 100644 --- a/gst/rtsp-server/rtsp-media.h +++ b/gst/rtsp-server/rtsp-media.h @@ -41,11 +41,6 @@ typedef struct _GstRTSPMedia GstRTSPMedia; typedef struct _GstRTSPMediaClass GstRTSPMediaClass; typedef struct _GstRTSPMediaPrivate GstRTSPMediaPrivate; -#include "rtsp-stream.h" -#include "rtsp-thread-pool.h" -#include "rtsp-permissions.h" -#include "rtsp-address-pool.h" - /** * GstRTSPMediaStatus: * @GST_RTSP_MEDIA_STATUS_UNPREPARED: media pipeline not prerolled @@ -53,6 +48,7 @@ typedef struct _GstRTSPMediaPrivate GstRTSPMediaPrivate; * shutdown. * @GST_RTSP_MEDIA_STATUS_PREPARING: media pipeline is prerolling * @GST_RTSP_MEDIA_STATUS_PREPARED: media pipeline is prerolled + * @GST_RTSP_MEDIA_STATUS_SUSPENDED: media is suspended * @GST_RTSP_MEDIA_STATUS_ERROR: media pipeline is in error * * The state of the media pipeline. @@ -62,9 +58,33 @@ typedef enum { GST_RTSP_MEDIA_STATUS_UNPREPARING = 1, GST_RTSP_MEDIA_STATUS_PREPARING = 2, GST_RTSP_MEDIA_STATUS_PREPARED = 3, - GST_RTSP_MEDIA_STATUS_ERROR = 4 + GST_RTSP_MEDIA_STATUS_SUSPENDED = 4, + GST_RTSP_MEDIA_STATUS_ERROR = 5 } GstRTSPMediaStatus; +/** + * GstRTSPSuspendMode: + * @GST_RTSP_SUSPEND_MODE_NONE: Media is not suspended + * @GST_RTSP_SUSPEND_MODE_PAUSE: Media is PAUSED in suspend + * @GST_RTSP_SUSPEND_MODE_RESET: The media is set to NULL when suspended + * + * The suspend mode of the media pipeline. A media pipeline is suspended right + * after creating the SDP and when the client preforms a PAUSED request. + */ +typedef enum { + GST_RTSP_SUSPEND_MODE_NONE = 0, + GST_RTSP_SUSPEND_MODE_PAUSE = 1, + GST_RTSP_SUSPEND_MODE_RESET = 2 +} GstRTSPSuspendMode; + +#define GST_TYPE_RTSP_SUSPEND_MODE (gst_rtsp_suspend_mode_get_type()) +GType gst_rtsp_suspend_mode_get_type (void); + +#include "rtsp-stream.h" +#include "rtsp-thread-pool.h" +#include "rtsp-permissions.h" +#include "rtsp-address-pool.h" + /** * GstRTSPMedia: * @@ -154,6 +174,12 @@ GstNetTimeProvider * gst_rtsp_media_get_time_provider (GstRTSPMedia *media, gboolean gst_rtsp_media_prepare (GstRTSPMedia *media, GstRTSPThread *thread); gboolean gst_rtsp_media_unprepare (GstRTSPMedia *media); +void gst_rtsp_media_set_suspend_mode (GstRTSPMedia *media, GstRTSPSuspendMode mode); +GstRTSPSuspendMode gst_rtsp_media_get_suspend_mode (GstRTSPMedia *media); + +gboolean gst_rtsp_media_suspend (GstRTSPMedia *media); +gboolean gst_rtsp_media_unsuspend (GstRTSPMedia *media); + /* creating streams */ void gst_rtsp_media_collect_streams (GstRTSPMedia *media); GstRTSPStream * gst_rtsp_media_create_stream (GstRTSPMedia *media, diff --git a/gst/rtsp-server/rtsp-session-media.c b/gst/rtsp-server/rtsp-session-media.c index 796da5ac6f..d042ea0b7d 100644 --- a/gst/rtsp-server/rtsp-session-media.c +++ b/gst/rtsp-server/rtsp-session-media.c @@ -138,11 +138,13 @@ gst_rtsp_session_media_new (const gchar * path, GstRTSPMedia * media) GstRTSPSessionMediaPrivate *priv; GstRTSPSessionMedia *result; guint n_streams; + GstRTSPMediaStatus status; g_return_val_if_fail (path != NULL, NULL); g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), NULL); - g_return_val_if_fail (gst_rtsp_media_get_status (media) == - GST_RTSP_MEDIA_STATUS_PREPARED, NULL); + status = gst_rtsp_media_get_status (media); + g_return_val_if_fail (status == GST_RTSP_MEDIA_STATUS_PREPARED || status == + GST_RTSP_MEDIA_STATUS_SUSPENDED, NULL); result = g_object_new (GST_TYPE_RTSP_SESSION_MEDIA, NULL); priv = result->priv; diff --git a/gst/rtsp-server/rtsp-session.c b/gst/rtsp-server/rtsp-session.c index 204ccf78f7..b2ff36d7c6 100644 --- a/gst/rtsp-server/rtsp-session.c +++ b/gst/rtsp-server/rtsp-session.c @@ -205,12 +205,14 @@ gst_rtsp_session_manage_media (GstRTSPSession * sess, const gchar * path, { GstRTSPSessionPrivate *priv; GstRTSPSessionMedia *result; + GstRTSPMediaStatus status; g_return_val_if_fail (GST_IS_RTSP_SESSION (sess), NULL); g_return_val_if_fail (path != NULL, NULL); g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), NULL); - g_return_val_if_fail (gst_rtsp_media_get_status (media) == - GST_RTSP_MEDIA_STATUS_PREPARED, NULL); + status = gst_rtsp_media_get_status (media); + g_return_val_if_fail (status == GST_RTSP_MEDIA_STATUS_PREPARED || status == + GST_RTSP_MEDIA_STATUS_SUSPENDED, NULL); priv = sess->priv; diff --git a/tests/check/gst/media.c b/tests/check/gst/media.c index ca2c324b0d..23e858626a 100644 --- a/tests/check/gst/media.c +++ b/tests/check/gst/media.c @@ -300,6 +300,50 @@ GST_START_TEST (test_media_take_pipeline) GST_END_TEST; +GST_START_TEST (test_media_reset) +{ + GstRTSPMediaFactory *factory; + GstRTSPMedia *media; + GstRTSPUrl *url; + GstRTSPThreadPool *pool; + GstRTSPThread *thread; + + pool = gst_rtsp_thread_pool_new (); + + factory = gst_rtsp_media_factory_new (); + fail_if (gst_rtsp_media_factory_is_shared (factory)); + gst_rtsp_url_parse ("rtsp://localhost:8554/test", &url); + + gst_rtsp_media_factory_set_launch (factory, + "( videotestsrc ! rtpvrawpay pt=96 name=pay0 )"); + + media = gst_rtsp_media_factory_construct (factory, url); + fail_unless (GST_IS_RTSP_MEDIA (media)); + + thread = gst_rtsp_thread_pool_get_thread (pool, + GST_RTSP_THREAD_TYPE_MEDIA, NULL); + fail_unless (gst_rtsp_media_prepare (media, thread)); + fail_unless (gst_rtsp_media_suspend (media)); + fail_unless (gst_rtsp_media_unprepare (media)); + g_object_unref (media); + + media = gst_rtsp_media_factory_construct (factory, url); + fail_unless (GST_IS_RTSP_MEDIA (media)); + + thread = gst_rtsp_thread_pool_get_thread (pool, + GST_RTSP_THREAD_TYPE_MEDIA, NULL); + gst_rtsp_media_set_suspend_mode (media, GST_RTSP_SUSPEND_MODE_RESET); + fail_unless (gst_rtsp_media_prepare (media, thread)); + fail_unless (gst_rtsp_media_suspend (media)); + fail_unless (gst_rtsp_media_unprepare (media)); + g_object_unref (media); + + gst_rtsp_url_free (url); + g_object_unref (factory); +} + +GST_END_TEST; + static Suite * rtspmedia_suite (void) { @@ -313,6 +357,7 @@ rtspmedia_suite (void) tcase_add_test (tc, test_media_prepare); tcase_add_test (tc, test_media_dyn_prepare); tcase_add_test (tc, test_media_take_pipeline); + tcase_add_test (tc, test_media_reset); return s; } diff --git a/tests/check/gst/mediafactory.c b/tests/check/gst/mediafactory.c index 73e4883207..b6b250beb7 100644 --- a/tests/check/gst/mediafactory.c +++ b/tests/check/gst/mediafactory.c @@ -280,6 +280,40 @@ GST_START_TEST (test_permissions) GST_END_TEST; +GST_START_TEST (test_reset) +{ + GstRTSPMediaFactory *factory; + GstRTSPMedia *media; + GstRTSPUrl *url; + + factory = gst_rtsp_media_factory_new (); + fail_if (gst_rtsp_media_factory_is_shared (factory)); + gst_rtsp_url_parse ("rtsp://localhost:8554/test", &url); + + gst_rtsp_media_factory_set_launch (factory, + "( videotestsrc ! rtpvrawpay pt=96 name=pay0 )"); + + media = gst_rtsp_media_factory_construct (factory, url); + fail_unless (GST_IS_RTSP_MEDIA (media)); + fail_if (gst_rtsp_media_get_suspend_mode (media) != + GST_RTSP_SUSPEND_MODE_NONE); + g_object_unref (media); + + gst_rtsp_media_factory_set_suspend_mode (factory, + GST_RTSP_SUSPEND_MODE_RESET); + + media = gst_rtsp_media_factory_construct (factory, url); + fail_unless (GST_IS_RTSP_MEDIA (media)); + fail_if (gst_rtsp_media_get_suspend_mode (media) != + GST_RTSP_SUSPEND_MODE_RESET); + g_object_unref (media); + + gst_rtsp_url_free (url); + g_object_unref (factory); +} + +GST_END_TEST; + static Suite * rtspmediafactory_suite (void) { @@ -294,6 +328,7 @@ rtspmediafactory_suite (void) tcase_add_test (tc, test_shared); tcase_add_test (tc, test_addresspool); tcase_add_test (tc, test_permissions); + tcase_add_test (tc, test_reset); return s; }