media: add suspend modes

Add support for different suspend modes. The stream is suspended right after
producing the SDP and after PAUSE. Different suspend modes are available that
affect the state of the pipeline. NONE leaves the pipeline state unchanged and
is the current and old behaviour, PAUSE will set the pipeline to the PAUSED
state and RESET will bring the pipeline to the NULL state.
A stream is also unsuspended when it goes back to PLAYING, for RESET streams,
this means that the pipeline needs to be prerolled again.

Base on patches by Ognyan Tonchev <ognyan@axis.com>

See https://bugzilla.gnome.org/show_bug.cgi?id=711257
This commit is contained in:
Wim Taymans 2013-11-28 14:10:19 +01:00
parent db771c5167
commit 2f17369e9d
8 changed files with 432 additions and 10 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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);
}
}
}

View file

@ -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,

View file

@ -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;

View file

@ -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;

View file

@ -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;
}

View file

@ -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;
}