rtsp-media: Use flags to distinguish between PLAY and RECORD media

This commit is contained in:
Sebastian Dröge 2015-01-28 18:54:01 +01:00
parent aa1feab874
commit a93ed7e5d4
7 changed files with 147 additions and 86 deletions

View file

@ -67,7 +67,8 @@ main (int argc, char *argv[])
* any launch line works as long as it contains elements named depay%d. Each * any launch line works as long as it contains elements named depay%d. Each
* element with depay%d names will be a stream */ * element with depay%d names will be a stream */
factory = gst_rtsp_media_factory_new (); factory = gst_rtsp_media_factory_new ();
gst_rtsp_media_factory_set_record (factory, TRUE); gst_rtsp_media_factory_set_transport_mode (factory,
GST_RTSP_TRANSPORT_MODE_RECORD);
gst_rtsp_media_factory_set_launch (factory, argv[1]); gst_rtsp_media_factory_set_launch (factory, argv[1]);
gst_rtsp_media_factory_set_latency (factory, 2000); gst_rtsp_media_factory_set_latency (factory, 2000);

View file

@ -635,7 +635,8 @@ find_media (GstRTSPClient * client, GstRTSPContext * ctx, gchar * path,
ctx->media = media; ctx->media = media;
if (!gst_rtsp_media_is_record (media)) { if (!(gst_rtsp_media_get_transport_mode (media) &
GST_RTSP_TRANSPORT_MODE_RECORD)) {
GstRTSPThread *thread; GstRTSPThread *thread;
thread = gst_rtsp_thread_pool_get_thread (priv->thread_pool, thread = gst_rtsp_thread_pool_get_thread (priv->thread_pool,
@ -1145,8 +1146,9 @@ handle_play_request (GstRTSPClient * client, GstRTSPContext * ctx)
ctx->sessmedia = sessmedia; ctx->sessmedia = sessmedia;
ctx->media = media = gst_rtsp_session_media_get_media (sessmedia); ctx->media = media = gst_rtsp_session_media_get_media (sessmedia);
if (gst_rtsp_media_is_record (media)) if (!(gst_rtsp_media_get_transport_mode (media) &
goto record_media; GST_RTSP_TRANSPORT_MODE_PLAY))
goto unsupported_mode;
/* the session state must be playing or ready */ /* the session state must be playing or ready */
rtspstate = gst_rtsp_session_media_get_rtsp_state (sessmedia); rtspstate = gst_rtsp_session_media_get_rtsp_state (sessmedia);
@ -1237,9 +1239,9 @@ unsuspend_failed:
send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, ctx); send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, ctx);
return FALSE; return FALSE;
} }
record_media: unsupported_mode:
{ {
GST_ERROR ("client %p: RECORD media does not support PLAY", client); GST_ERROR ("client %p: media does not support PLAY", client);
send_generic_response (client, GST_RTSP_STS_METHOD_NOT_ALLOWED, ctx); send_generic_response (client, GST_RTSP_STS_METHOD_NOT_ALLOWED, ctx);
return FALSE; return FALSE;
} }
@ -1475,7 +1477,8 @@ make_server_transport (GstRTSPClient * client, GstRTSPMedia * media,
break; break;
} }
if (!gst_rtsp_media_is_record (media)) if ((gst_rtsp_media_get_transport_mode (media) &
GST_RTSP_TRANSPORT_MODE_PLAY))
gst_rtsp_stream_get_ssrc (ctx->stream, &st->ssrc); gst_rtsp_stream_get_ssrc (ctx->stream, &st->ssrc);
return st; return st;
@ -1857,9 +1860,11 @@ handle_setup_request (GstRTSPClient * client, GstRTSPContext * ctx)
if (!parse_transport (transport, stream, ct)) if (!parse_transport (transport, stream, ct))
goto unsupported_transports; goto unsupported_transports;
/* TODO: Add support for PLAY,RECORD media */ if ((ct->mode_play
if ((ct->mode_play && gst_rtsp_media_is_record (media)) || && !(gst_rtsp_media_get_transport_mode (media) &
(ct->mode_record && !gst_rtsp_media_is_record (media))) GST_RTSP_TRANSPORT_MODE_PLAY)) || (ct->mode_record
&& !(gst_rtsp_media_get_transport_mode (media) &
GST_RTSP_TRANSPORT_MODE_RECORD)))
goto unsupported_mode; goto unsupported_mode;
/* parse the keymgmt */ /* parse the keymgmt */
@ -2029,9 +2034,12 @@ unsupported_client_transport:
} }
unsupported_mode: unsupported_mode:
{ {
GST_ERROR ("client %p: unsupported mode (media record: %d, mode play: %d" GST_ERROR ("client %p: unsupported mode (media play: %d, media record: %d, "
", mode record: %d)", client, gst_rtsp_media_is_record (media), "mode play: %d, mode record: %d)", client,
ct->mode_play, ct->mode_record); ! !(gst_rtsp_media_get_transport_mode (media) &
GST_RTSP_TRANSPORT_MODE_PLAY),
! !(gst_rtsp_media_get_transport_mode (media) &
GST_RTSP_TRANSPORT_MODE_RECORD), ct->mode_play, ct->mode_record);
send_generic_response (client, GST_RTSP_STS_UNSUPPORTED_TRANSPORT, ctx); send_generic_response (client, GST_RTSP_STS_UNSUPPORTED_TRANSPORT, ctx);
goto cleanup_transport; goto cleanup_transport;
} }
@ -2148,8 +2156,9 @@ handle_describe_request (GstRTSPClient * client, GstRTSPContext * ctx)
if (!(media = find_media (client, ctx, path, NULL))) if (!(media = find_media (client, ctx, path, NULL)))
goto no_media; goto no_media;
if (gst_rtsp_media_is_record (media)) if (!(gst_rtsp_media_get_transport_mode (media) &
goto record_media; GST_RTSP_TRANSPORT_MODE_PLAY))
goto unsupported_mode;
/* create an SDP for the media object on this client */ /* create an SDP for the media object on this client */
if (!(sdp = klass->create_sdp (client, media))) if (!(sdp = klass->create_sdp (client, media)))
@ -2210,9 +2219,9 @@ no_media:
/* error reply is already sent */ /* error reply is already sent */
return FALSE; return FALSE;
} }
record_media: unsupported_mode:
{ {
GST_ERROR ("client %p: RECORD media does not support DESCRIBE", client); GST_ERROR ("client %p: media does not support DESCRIBE", client);
send_generic_response (client, GST_RTSP_STS_METHOD_NOT_ALLOWED, ctx); send_generic_response (client, GST_RTSP_STS_METHOD_NOT_ALLOWED, ctx);
g_free (path); g_free (path);
g_object_unref (media); g_object_unref (media);
@ -2316,8 +2325,9 @@ handle_announce_request (GstRTSPClient * client, GstRTSPContext * ctx)
if (!(media = find_media (client, ctx, path, NULL))) if (!(media = find_media (client, ctx, path, NULL)))
goto no_media; goto no_media;
if (!gst_rtsp_media_is_record (media)) if (!(gst_rtsp_media_get_transport_mode (media) &
goto play_media; GST_RTSP_TRANSPORT_MODE_RECORD))
goto unsupported_mode;
/* Tell client subclass about the media */ /* Tell client subclass about the media */
if (!klass->handle_sdp (client, ctx, media, sdp)) if (!klass->handle_sdp (client, ctx, media, sdp))
@ -2385,9 +2395,9 @@ no_media:
gst_sdp_message_free (sdp); gst_sdp_message_free (sdp);
return FALSE; return FALSE;
} }
play_media: unsupported_mode:
{ {
GST_ERROR ("client %p: PLAY media does not support ANNOUNCE", client); GST_ERROR ("client %p: media does not support ANNOUNCE", client);
send_generic_response (client, GST_RTSP_STS_METHOD_NOT_ALLOWED, ctx); send_generic_response (client, GST_RTSP_STS_METHOD_NOT_ALLOWED, ctx);
g_free (path); g_free (path);
g_object_unref (media); g_object_unref (media);
@ -2439,8 +2449,9 @@ handle_record_request (GstRTSPClient * client, GstRTSPContext * ctx)
ctx->sessmedia = sessmedia; ctx->sessmedia = sessmedia;
ctx->media = media = gst_rtsp_session_media_get_media (sessmedia); ctx->media = media = gst_rtsp_session_media_get_media (sessmedia);
if (!gst_rtsp_media_is_record (media)) if (!(gst_rtsp_media_get_transport_mode (media) &
goto play_media; GST_RTSP_TRANSPORT_MODE_RECORD))
goto unsupported_mode;
/* the session state must be playing or ready */ /* the session state must be playing or ready */
rtspstate = gst_rtsp_session_media_get_rtsp_state (sessmedia); rtspstate = gst_rtsp_session_media_get_rtsp_state (sessmedia);
@ -2493,9 +2504,9 @@ no_aggregate:
g_free (path); g_free (path);
return FALSE; return FALSE;
} }
play_media: unsupported_mode:
{ {
GST_ERROR ("client %p: PLAY media does not support RECORD", client); GST_ERROR ("client %p: media does not support RECORD", client);
send_generic_response (client, GST_RTSP_STS_METHOD_NOT_ALLOWED, ctx); send_generic_response (client, GST_RTSP_STS_METHOD_NOT_ALLOWED, ctx);
return FALSE; return FALSE;
} }

View file

@ -53,13 +53,13 @@ struct _GstRTSPMediaFactoryPrivate
GstRTSPPermissions *permissions; GstRTSPPermissions *permissions;
gchar *launch; gchar *launch;
gboolean shared; gboolean shared;
gboolean record;
GstRTSPSuspendMode suspend_mode; GstRTSPSuspendMode suspend_mode;
gboolean eos_shutdown; gboolean eos_shutdown;
GstRTSPProfile profiles; GstRTSPProfile profiles;
GstRTSPLowerTrans protocols; GstRTSPLowerTrans protocols;
guint buffer_size; guint buffer_size;
GstRTSPAddressPool *pool; GstRTSPAddressPool *pool;
GstRTSPTransportMode transport_mode;
GstClockTime rtx_time; GstClockTime rtx_time;
guint latency; guint latency;
@ -77,7 +77,7 @@ struct _GstRTSPMediaFactoryPrivate
GST_RTSP_LOWER_TRANS_TCP GST_RTSP_LOWER_TRANS_TCP
#define DEFAULT_BUFFER_SIZE 0x80000 #define DEFAULT_BUFFER_SIZE 0x80000
#define DEFAULT_LATENCY 200 #define DEFAULT_LATENCY 200
#define DEFAULT_RECORD FALSE #define DEFAULT_TRANSPORT_MODE GST_RTSP_TRANSPORT_MODE_PLAY
enum enum
{ {
@ -90,7 +90,7 @@ enum
PROP_PROTOCOLS, PROP_PROTOCOLS,
PROP_BUFFER_SIZE, PROP_BUFFER_SIZE,
PROP_LATENCY, PROP_LATENCY,
PROP_RECORD, PROP_TRANSPORT_MODE,
PROP_LAST PROP_LAST
}; };
@ -194,12 +194,10 @@ gst_rtsp_media_factory_class_init (GstRTSPMediaFactoryClass * klass)
"Latency used for receiving media in milliseconds", 0, G_MAXUINT, "Latency used for receiving media in milliseconds", 0, G_MAXUINT,
DEFAULT_LATENCY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); DEFAULT_LATENCY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/* FIXME: Should this be a flag property to allow RECORD and PLAY? g_object_class_install_property (gobject_class, PROP_TRANSPORT_MODE,
* Or just another boolean PLAY property that default to TRUE? g_param_spec_flags ("transport-mode", "Transport Mode",
*/ "If media from this factory is for PLAY or RECORD",
g_object_class_install_property (gobject_class, PROP_RECORD, GST_TYPE_RTSP_TRANSPORT_MODE, DEFAULT_TRANSPORT_MODE,
g_param_spec_boolean ("record", "Record",
"If media from this factory is for PLAY or RECORD", DEFAULT_RECORD,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONSTRUCTED] = gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONSTRUCTED] =
@ -239,6 +237,7 @@ gst_rtsp_media_factory_init (GstRTSPMediaFactory * factory)
priv->protocols = DEFAULT_PROTOCOLS; priv->protocols = DEFAULT_PROTOCOLS;
priv->buffer_size = DEFAULT_BUFFER_SIZE; priv->buffer_size = DEFAULT_BUFFER_SIZE;
priv->latency = DEFAULT_LATENCY; priv->latency = DEFAULT_LATENCY;
priv->transport_mode = DEFAULT_TRANSPORT_MODE;
g_mutex_init (&priv->lock); g_mutex_init (&priv->lock);
g_mutex_init (&priv->medias_lock); g_mutex_init (&priv->medias_lock);
@ -298,8 +297,9 @@ gst_rtsp_media_factory_get_property (GObject * object, guint propid,
case PROP_LATENCY: case PROP_LATENCY:
g_value_set_uint (value, gst_rtsp_media_factory_get_latency (factory)); g_value_set_uint (value, gst_rtsp_media_factory_get_latency (factory));
break; break;
case PROP_RECORD: case PROP_TRANSPORT_MODE:
g_value_set_boolean (value, gst_rtsp_media_factory_is_record (factory)); g_value_set_flags (value,
gst_rtsp_media_factory_get_transport_mode (factory));
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
@ -340,8 +340,9 @@ gst_rtsp_media_factory_set_property (GObject * object, guint propid,
case PROP_LATENCY: case PROP_LATENCY:
gst_rtsp_media_factory_set_latency (factory, g_value_get_uint (value)); gst_rtsp_media_factory_set_latency (factory, g_value_get_uint (value));
break; break;
case PROP_RECORD: case PROP_TRANSPORT_MODE:
gst_rtsp_media_factory_set_record (factory, g_value_get_boolean (value)); gst_rtsp_media_factory_set_transport_mode (factory,
g_value_get_flags (value));
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
@ -1220,7 +1221,7 @@ default_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
GstRTSPPermissions *perms; GstRTSPPermissions *perms;
GstClockTime rtx_time; GstClockTime rtx_time;
guint latency; guint latency;
gboolean record; GstRTSPTransportMode transport_mode;
/* configure the sharedness */ /* configure the sharedness */
GST_RTSP_MEDIA_FACTORY_LOCK (factory); GST_RTSP_MEDIA_FACTORY_LOCK (factory);
@ -1232,7 +1233,7 @@ default_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
protocols = priv->protocols; protocols = priv->protocols;
rtx_time = priv->rtx_time; rtx_time = priv->rtx_time;
latency = priv->latency; latency = priv->latency;
record = priv->record; transport_mode = priv->transport_mode;
GST_RTSP_MEDIA_FACTORY_UNLOCK (factory); GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
gst_rtsp_media_set_suspend_mode (media, suspend_mode); gst_rtsp_media_set_suspend_mode (media, suspend_mode);
@ -1243,7 +1244,7 @@ default_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
gst_rtsp_media_set_protocols (media, protocols); gst_rtsp_media_set_protocols (media, protocols);
gst_rtsp_media_set_retransmission_time (media, rtx_time); gst_rtsp_media_set_retransmission_time (media, rtx_time);
gst_rtsp_media_set_latency (media, latency); gst_rtsp_media_set_latency (media, latency);
gst_rtsp_media_set_record (media, record); gst_rtsp_media_set_transport_mode (media, transport_mode);
if ((pool = gst_rtsp_media_factory_get_address_pool (factory))) { if ((pool = gst_rtsp_media_factory_get_address_pool (factory))) {
gst_rtsp_media_set_address_pool (media, pool); gst_rtsp_media_set_address_pool (media, pool);
@ -1290,15 +1291,15 @@ gst_rtsp_media_factory_create_element (GstRTSPMediaFactory * factory,
} }
/** /**
* gst_rtsp_media_factory_set_record: * gst_rtsp_media_factory_set_transport_mode:
* @factory: a #GstRTSPMediaFactory * @factory: a #GstRTSPMediaFactory
* @record: the new value * @mode: the new value
* *
* Configure if this factory creates media for PLAY or RECORD methods. * Configure if this factory creates media for PLAY or RECORD modes.
*/ */
void void
gst_rtsp_media_factory_set_record (GstRTSPMediaFactory * factory, gst_rtsp_media_factory_set_transport_mode (GstRTSPMediaFactory * factory,
gboolean record) GstRTSPTransportMode mode)
{ {
GstRTSPMediaFactoryPrivate *priv; GstRTSPMediaFactoryPrivate *priv;
@ -1307,31 +1308,31 @@ gst_rtsp_media_factory_set_record (GstRTSPMediaFactory * factory,
priv = factory->priv; priv = factory->priv;
GST_RTSP_MEDIA_FACTORY_LOCK (factory); GST_RTSP_MEDIA_FACTORY_LOCK (factory);
priv->record = record; priv->transport_mode = mode;
GST_RTSP_MEDIA_FACTORY_UNLOCK (factory); GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
} }
/** /**
* gst_rtsp_media_factory_is_record: * gst_rtsp_media_factory_get_transport_mode:
* @factory: a #GstRTSPMediaFactory * @factory: a #GstRTSPMediaFactory
* *
* Get if media created from this factory can be used for PLAY or RECORD * Get if media created from this factory can be used for PLAY or RECORD
* methods. * methods.
* *
* Returns: %TRUE if the media will be record between clients. * Returns: The supported transport modes.
*/ */
gboolean GstRTSPTransportMode
gst_rtsp_media_factory_is_record (GstRTSPMediaFactory * factory) gst_rtsp_media_factory_get_transport_mode (GstRTSPMediaFactory * factory)
{ {
GstRTSPMediaFactoryPrivate *priv; GstRTSPMediaFactoryPrivate *priv;
gboolean result; GstRTSPTransportMode result;
g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), FALSE); g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), FALSE);
priv = factory->priv; priv = factory->priv;
GST_RTSP_MEDIA_FACTORY_LOCK (factory); GST_RTSP_MEDIA_FACTORY_LOCK (factory);
result = priv->record; result = priv->transport_mode;
GST_RTSP_MEDIA_FACTORY_UNLOCK (factory); GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
return result; return result;

View file

@ -149,9 +149,9 @@ void gst_rtsp_media_factory_set_latency (GstRTSPMediaFacto
guint latency); guint latency);
guint gst_rtsp_media_factory_get_latency (GstRTSPMediaFactory * factory); guint gst_rtsp_media_factory_get_latency (GstRTSPMediaFactory * factory);
void gst_rtsp_media_factory_set_record (GstRTSPMediaFactory *factory, void gst_rtsp_media_factory_set_transport_mode (GstRTSPMediaFactory *factory,
gboolean record); GstRTSPTransportMode mode);
gboolean gst_rtsp_media_factory_is_record (GstRTSPMediaFactory *factory); GstRTSPTransportMode gst_rtsp_media_factory_get_transport_mode (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,

View file

@ -101,7 +101,7 @@ struct _GstRTSPMediaPrivate
guint buffer_size; guint buffer_size;
GstRTSPAddressPool *pool; GstRTSPAddressPool *pool;
gboolean blocked; gboolean blocked;
gboolean record; GstRTSPTransportMode transport_mode;
GstElement *element; GstElement *element;
GRecMutex state_lock; /* locking order: state lock, lock */ GRecMutex state_lock; /* locking order: state lock, lock */
@ -150,7 +150,7 @@ struct _GstRTSPMediaPrivate
#define DEFAULT_BUFFER_SIZE 0x80000 #define DEFAULT_BUFFER_SIZE 0x80000
#define DEFAULT_TIME_PROVIDER FALSE #define DEFAULT_TIME_PROVIDER FALSE
#define DEFAULT_LATENCY 200 #define DEFAULT_LATENCY 200
#define DEFAULT_RECORD FALSE #define DEFAULT_TRANSPORT_MODE GST_RTSP_TRANSPORT_MODE_PLAY
/* define to dump received RTCP packets */ /* define to dump received RTCP packets */
#undef DUMP_STATS #undef DUMP_STATS
@ -168,7 +168,7 @@ enum
PROP_ELEMENT, PROP_ELEMENT,
PROP_TIME_PROVIDER, PROP_TIME_PROVIDER,
PROP_LATENCY, PROP_LATENCY,
PROP_RECORD, PROP_TRANSPORT_MODE,
PROP_LAST PROP_LAST
}; };
@ -215,7 +215,6 @@ static guint gst_rtsp_media_signals[SIGNAL_LAST] = { 0 };
#define C_ENUM(v) ((gint) v) #define C_ENUM(v) ((gint) v)
#define GST_TYPE_RTSP_SUSPEND_MODE (gst_rtsp_suspend_mode_get_type())
GType GType
gst_rtsp_suspend_mode_get_type (void) gst_rtsp_suspend_mode_get_type (void)
{ {
@ -236,6 +235,27 @@ gst_rtsp_suspend_mode_get_type (void)
return (GType) id; return (GType) id;
} }
#define C_FLAGS(v) ((guint) v)
GType
gst_rtsp_transport_mode_get_type (void)
{
static gsize id = 0;
static const GFlagsValue values[] = {
{C_FLAGS (GST_RTSP_TRANSPORT_MODE_PLAY), "GST_RTSP_TRANSPORT_MODE_PLAY",
"play"},
{C_FLAGS (GST_RTSP_TRANSPORT_MODE_RECORD), "GST_RTSP_TRANSPORT_MODE_RECORD",
"record"},
{0, NULL, NULL}
};
if (g_once_init_enter (&id)) {
GType tmp = g_flags_register_static ("GstRTSPTransportMode", values);
g_once_init_leave (&id, tmp);
}
return (GType) id;
}
G_DEFINE_TYPE (GstRTSPMedia, gst_rtsp_media, G_TYPE_OBJECT); G_DEFINE_TYPE (GstRTSPMedia, gst_rtsp_media, G_TYPE_OBJECT);
static void static void
@ -301,10 +321,11 @@ gst_rtsp_media_class_init (GstRTSPMediaClass * klass)
"Latency used for receiving media in milliseconds", 0, G_MAXUINT, "Latency used for receiving media in milliseconds", 0, G_MAXUINT,
DEFAULT_BUFFER_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); DEFAULT_BUFFER_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_RECORD, g_object_class_install_property (gobject_class, PROP_TRANSPORT_MODE,
g_param_spec_boolean ("record", "Record", g_param_spec_flags ("transport-mode", "Transport Mode",
"If this media pipeline can be used for PLAY or RECORD", "If this media pipeline can be used for PLAY or RECORD",
DEFAULT_RECORD, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); GST_TYPE_RTSP_TRANSPORT_MODE, DEFAULT_TRANSPORT_MODE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gst_rtsp_media_signals[SIGNAL_NEW_STREAM] = gst_rtsp_media_signals[SIGNAL_NEW_STREAM] =
g_signal_new ("new-stream", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, g_signal_new ("new-stream", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
@ -372,7 +393,7 @@ gst_rtsp_media_init (GstRTSPMedia * media)
priv->eos_shutdown = DEFAULT_EOS_SHUTDOWN; priv->eos_shutdown = DEFAULT_EOS_SHUTDOWN;
priv->buffer_size = DEFAULT_BUFFER_SIZE; priv->buffer_size = DEFAULT_BUFFER_SIZE;
priv->time_provider = DEFAULT_TIME_PROVIDER; priv->time_provider = DEFAULT_TIME_PROVIDER;
priv->record = DEFAULT_RECORD; priv->transport_mode = DEFAULT_TRANSPORT_MODE;
} }
static void static void
@ -446,8 +467,8 @@ gst_rtsp_media_get_property (GObject * object, guint propid,
case PROP_LATENCY: case PROP_LATENCY:
g_value_set_uint (value, gst_rtsp_media_get_latency (media)); g_value_set_uint (value, gst_rtsp_media_get_latency (media));
break; break;
case PROP_RECORD: case PROP_TRANSPORT_MODE:
g_value_set_boolean (value, gst_rtsp_media_is_record (media)); g_value_set_flags (value, gst_rtsp_media_get_transport_mode (media));
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
@ -492,8 +513,8 @@ gst_rtsp_media_set_property (GObject * object, guint propid,
case PROP_LATENCY: case PROP_LATENCY:
gst_rtsp_media_set_latency (media, g_value_get_uint (value)); gst_rtsp_media_set_latency (media, g_value_get_uint (value));
break; break;
case PROP_RECORD: case PROP_TRANSPORT_MODE:
gst_rtsp_media_set_record (media, g_value_get_boolean (value)); gst_rtsp_media_set_transport_mode (media, g_value_get_flags (value));
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
@ -1405,6 +1426,7 @@ gst_rtsp_media_collect_streams (GstRTSPMedia * media)
GstPad *pad; GstPad *pad;
gint i; gint i;
gboolean have_elem; gboolean have_elem;
GstRTSPTransportMode mode = 0;
g_return_if_fail (GST_IS_RTSP_MEDIA (media)); g_return_if_fail (GST_IS_RTSP_MEDIA (media));
@ -1429,6 +1451,7 @@ gst_rtsp_media_collect_streams (GstRTSPMedia * media)
gst_object_unref (elem); gst_object_unref (elem);
have_elem = TRUE; have_elem = TRUE;
mode |= GST_RTSP_TRANSPORT_MODE_PLAY;
} }
g_free (name); g_free (name);
@ -1442,6 +1465,7 @@ gst_rtsp_media_collect_streams (GstRTSPMedia * media)
g_mutex_unlock (&priv->lock); g_mutex_unlock (&priv->lock);
have_elem = TRUE; have_elem = TRUE;
mode |= GST_RTSP_TRANSPORT_MODE_PLAY;
} }
g_free (name); g_free (name);
@ -1457,9 +1481,17 @@ gst_rtsp_media_collect_streams (GstRTSPMedia * media)
gst_object_unref (elem); gst_object_unref (elem);
have_elem = TRUE; have_elem = TRUE;
mode |= GST_RTSP_TRANSPORT_MODE_RECORD;
} }
g_free (name); g_free (name);
} }
if (have_elem) {
if (priv->transport_mode != mode)
GST_WARNING ("found different mode than expected (0x%02x != 0x%02d)",
priv->transport_mode, mode);
gst_rtsp_media_set_transport_mode (media, mode);
}
} }
/** /**
@ -1834,7 +1866,7 @@ gst_rtsp_media_seek (GstRTSPMedia * media, GstRTSPTimeRange * range)
goto not_prepared; goto not_prepared;
/* Update the seekable state of the pipeline in case it changed */ /* Update the seekable state of the pipeline in case it changed */
if (gst_rtsp_media_is_record (media)) { if ((priv->transport_mode & GST_RTSP_TRANSPORT_MODE_RECORD)) {
/* TODO: Seeking for RECORD? */ /* TODO: Seeking for RECORD? */
priv->seekable = FALSE; priv->seekable = FALSE;
} else { } else {
@ -2032,7 +2064,7 @@ default_handle_message (GstRTSPMedia * media, GstMessage * message)
GST_DEBUG ("%p: went from %s to %s (pending %s)", media, GST_DEBUG ("%p: went from %s to %s (pending %s)", media,
gst_element_state_get_name (old), gst_element_state_get_name (new), gst_element_state_get_name (old), gst_element_state_get_name (new),
gst_element_state_get_name (pending)); gst_element_state_get_name (pending));
if (gst_rtsp_media_is_record (media) if ((priv->transport_mode & GST_RTSP_TRANSPORT_MODE_RECORD)
&& old == GST_STATE_READY && new == GST_STATE_PAUSED) { && old == GST_STATE_READY && new == GST_STATE_PAUSED) {
GST_INFO ("%p: went to PAUSED, prepared now", media); GST_INFO ("%p: went to PAUSED, prepared now", media);
collect_media_stats (media); collect_media_stats (media);
@ -2347,7 +2379,7 @@ start_preroll (GstRTSPMedia * media)
* seeking query in preroll instead */ * seeking query in preroll instead */
priv->seekable = FALSE; priv->seekable = FALSE;
priv->is_live = TRUE; priv->is_live = TRUE;
if (!gst_rtsp_media_is_record (media)) { if (!(priv->transport_mode & GST_RTSP_TRANSPORT_MODE_RECORD)) {
/* start blocked to make sure nothing goes to the sink */ /* start blocked to make sure nothing goes to the sink */
media_streams_set_blocked (media, TRUE); media_streams_set_blocked (media, TRUE);
} }
@ -3941,15 +3973,15 @@ error_status:
} }
/** /**
* gst_rtsp_media_set_record: * gst_rtsp_media_set_transport_mode:
* @media: a #GstRTSPMedia * @media: a #GstRTSPMedia
* @record: the new value * @mode: the new value
* *
* Set or unset if the pipeline for @media can be used for PLAY or RECORD * Sets if the media pipeline can work in PLAY or RECORD mode
* methods.
*/ */
void void
gst_rtsp_media_set_record (GstRTSPMedia * media, gboolean record) gst_rtsp_media_set_transport_mode (GstRTSPMedia * media,
GstRTSPTransportMode mode)
{ {
GstRTSPMediaPrivate *priv; GstRTSPMediaPrivate *priv;
@ -3958,30 +3990,30 @@ gst_rtsp_media_set_record (GstRTSPMedia * media, gboolean record)
priv = media->priv; priv = media->priv;
g_mutex_lock (&priv->lock); g_mutex_lock (&priv->lock);
priv->record = record; priv->transport_mode = mode;
g_mutex_unlock (&priv->lock); g_mutex_unlock (&priv->lock);
} }
/** /**
* gst_rtsp_media_is_record: * gst_rtsp_media_get_transport_mode:
* @media: a #GstRTSPMedia * @media: a #GstRTSPMedia
* *
* Check if the pipeline for @media can be used for PLAY or RECORD methods. * Check if the pipeline for @media can be used for PLAY or RECORD methods.
* *
* Returns: %TRUE if the media can be record between clients. * Returns: The transport mode.
*/ */
gboolean GstRTSPTransportMode
gst_rtsp_media_is_record (GstRTSPMedia * media) gst_rtsp_media_get_transport_mode (GstRTSPMedia * media)
{ {
GstRTSPMediaPrivate *priv; GstRTSPMediaPrivate *priv;
gboolean res; GstRTSPTransportMode res;
g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), FALSE); g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), FALSE);
priv = media->priv; priv = media->priv;
g_mutex_lock (&priv->lock); g_mutex_lock (&priv->lock);
res = priv->record; res = priv->transport_mode;
g_mutex_unlock (&priv->lock); g_mutex_unlock (&priv->lock);
return res; return res;

View file

@ -77,6 +77,21 @@ typedef enum {
GST_RTSP_SUSPEND_MODE_RESET = 2 GST_RTSP_SUSPEND_MODE_RESET = 2
} GstRTSPSuspendMode; } GstRTSPSuspendMode;
/**
* GstRTSPTransportMode:
* @GST_RTSP_TRANSPORT_MODE_PLAY: Transport supports PLAY mode
* @GST_RTSP_TRANSPORT_MODE_RECORD: Transport supports RECORD mode
*
* The supported modes of the media.
*/
typedef enum {
GST_RTSP_TRANSPORT_MODE_PLAY = 1,
GST_RTSP_TRANSPORT_MODE_RECORD = 2,
} GstRTSPTransportMode;
#define GST_TYPE_RTSP_TRANSPORT_MODE (gst_rtsp_transport_mode_get_type())
GType gst_rtsp_transport_mode_get_type (void);
#define GST_TYPE_RTSP_SUSPEND_MODE (gst_rtsp_suspend_mode_get_type()) #define GST_TYPE_RTSP_SUSPEND_MODE (gst_rtsp_suspend_mode_get_type())
GType gst_rtsp_suspend_mode_get_type (void); GType gst_rtsp_suspend_mode_get_type (void);
@ -172,8 +187,8 @@ GstRTSPPermissions * gst_rtsp_media_get_permissions (GstRTSPMedia *media);
void gst_rtsp_media_set_shared (GstRTSPMedia *media, gboolean shared); void gst_rtsp_media_set_shared (GstRTSPMedia *media, gboolean shared);
gboolean gst_rtsp_media_is_shared (GstRTSPMedia *media); gboolean gst_rtsp_media_is_shared (GstRTSPMedia *media);
void gst_rtsp_media_set_record (GstRTSPMedia *media, gboolean record); void gst_rtsp_media_set_transport_mode (GstRTSPMedia *media, GstRTSPTransportMode mode);
gboolean gst_rtsp_media_is_record (GstRTSPMedia *media); GstRTSPTransportMode gst_rtsp_media_get_transport_mode (GstRTSPMedia *media);
void gst_rtsp_media_set_reusable (GstRTSPMedia *media, gboolean reusable); void gst_rtsp_media_set_reusable (GstRTSPMedia *media, gboolean reusable);
gboolean gst_rtsp_media_is_reusable (GstRTSPMedia *media); gboolean gst_rtsp_media_is_reusable (GstRTSPMedia *media);

View file

@ -193,7 +193,8 @@ start_record_server (const gchar * launch_line)
factory = gst_rtsp_media_factory_new (); factory = gst_rtsp_media_factory_new ();
gst_rtsp_media_factory_set_record (factory, TRUE); gst_rtsp_media_factory_set_transport_mode (factory,
GST_RTSP_TRANSPORT_MODE_RECORD);
gst_rtsp_media_factory_set_launch (factory, launch_line); gst_rtsp_media_factory_set_launch (factory, launch_line);
gst_rtsp_mount_points_add_factory (mounts, TEST_MOUNT_POINT, factory); gst_rtsp_mount_points_add_factory (mounts, TEST_MOUNT_POINT, factory);
g_object_unref (mounts); g_object_unref (mounts);