* any launch line works as long as it contains elements named depay%d. Each
* element with depay%d names will be a stream */
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_latency (factory, 2000);
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;
thread = gst_rtsp_thread_pool_get_thread (priv->thread_pool,
ctx->sessmedia = sessmedia;
ctx->media = media = gst_rtsp_session_media_get_media (sessmedia);
- if (gst_rtsp_media_is_record (media))
- goto record_media;
+ if (!(gst_rtsp_media_get_transport_mode (media) &
+ GST_RTSP_TRANSPORT_MODE_PLAY))
+ goto unsupported_mode;
/* the session state must be playing or ready */
rtspstate = gst_rtsp_session_media_get_rtsp_state (sessmedia);
send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, ctx);
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);
return FALSE;
}
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);
return st;
if (!parse_transport (transport, stream, ct))
goto unsupported_transports;
- /* TODO: Add support for PLAY,RECORD media */
- if ((ct->mode_play && gst_rtsp_media_is_record (media)) ||
- (ct->mode_record && !gst_rtsp_media_is_record (media)))
+ if ((ct->mode_play
+ && !(gst_rtsp_media_get_transport_mode (media) &
+ GST_RTSP_TRANSPORT_MODE_PLAY)) || (ct->mode_record
+ && !(gst_rtsp_media_get_transport_mode (media) &
+ GST_RTSP_TRANSPORT_MODE_RECORD)))
goto unsupported_mode;
/* parse the keymgmt */
}
unsupported_mode:
{
- GST_ERROR ("client %p: unsupported mode (media record: %d, mode play: %d"
- ", mode record: %d)", client, gst_rtsp_media_is_record (media),
- ct->mode_play, ct->mode_record);
+ GST_ERROR ("client %p: unsupported mode (media play: %d, media record: %d, "
+ "mode play: %d, mode record: %d)", client,
+ ! !(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);
goto cleanup_transport;
}
if (!(media = find_media (client, ctx, path, NULL)))
goto no_media;
- if (gst_rtsp_media_is_record (media))
- goto record_media;
+ if (!(gst_rtsp_media_get_transport_mode (media) &
+ GST_RTSP_TRANSPORT_MODE_PLAY))
+ goto unsupported_mode;
/* create an SDP for the media object on this client */
if (!(sdp = klass->create_sdp (client, media)))
/* error reply is already sent */
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);
g_free (path);
g_object_unref (media);
if (!(media = find_media (client, ctx, path, NULL)))
goto no_media;
- if (!gst_rtsp_media_is_record (media))
- goto play_media;
+ if (!(gst_rtsp_media_get_transport_mode (media) &
+ GST_RTSP_TRANSPORT_MODE_RECORD))
+ goto unsupported_mode;
/* Tell client subclass about the media */
if (!klass->handle_sdp (client, ctx, media, sdp))
gst_sdp_message_free (sdp);
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);
g_free (path);
g_object_unref (media);
ctx->sessmedia = sessmedia;
ctx->media = media = gst_rtsp_session_media_get_media (sessmedia);
- if (!gst_rtsp_media_is_record (media))
- goto play_media;
+ if (!(gst_rtsp_media_get_transport_mode (media) &
+ GST_RTSP_TRANSPORT_MODE_RECORD))
+ goto unsupported_mode;
/* the session state must be playing or ready */
rtspstate = gst_rtsp_session_media_get_rtsp_state (sessmedia);
g_free (path);
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);
return FALSE;
}
GstRTSPPermissions *permissions;
gchar *launch;
gboolean shared;
- gboolean record;
GstRTSPSuspendMode suspend_mode;
gboolean eos_shutdown;
GstRTSPProfile profiles;
GstRTSPLowerTrans protocols;
guint buffer_size;
GstRTSPAddressPool *pool;
+ GstRTSPTransportMode transport_mode;
GstClockTime rtx_time;
guint latency;
GST_RTSP_LOWER_TRANS_TCP
#define DEFAULT_BUFFER_SIZE 0x80000
#define DEFAULT_LATENCY 200
-#define DEFAULT_RECORD FALSE
+#define DEFAULT_TRANSPORT_MODE GST_RTSP_TRANSPORT_MODE_PLAY
enum
{
PROP_PROTOCOLS,
PROP_BUFFER_SIZE,
PROP_LATENCY,
- PROP_RECORD,
+ PROP_TRANSPORT_MODE,
PROP_LAST
};
"Latency used for receiving media in milliseconds", 0, G_MAXUINT,
DEFAULT_LATENCY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- /* FIXME: Should this be a flag property to allow RECORD and PLAY?
- * Or just another boolean PLAY property that default to TRUE?
- */
- g_object_class_install_property (gobject_class, PROP_RECORD,
- g_param_spec_boolean ("record", "Record",
- "If media from this factory is for PLAY or RECORD", DEFAULT_RECORD,
+ g_object_class_install_property (gobject_class, PROP_TRANSPORT_MODE,
+ g_param_spec_flags ("transport-mode", "Transport Mode",
+ "If media from this factory is for PLAY or RECORD",
+ GST_TYPE_RTSP_TRANSPORT_MODE, DEFAULT_TRANSPORT_MODE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONSTRUCTED] =
priv->protocols = DEFAULT_PROTOCOLS;
priv->buffer_size = DEFAULT_BUFFER_SIZE;
priv->latency = DEFAULT_LATENCY;
+ priv->transport_mode = DEFAULT_TRANSPORT_MODE;
g_mutex_init (&priv->lock);
g_mutex_init (&priv->medias_lock);
case PROP_LATENCY:
g_value_set_uint (value, gst_rtsp_media_factory_get_latency (factory));
break;
- case PROP_RECORD:
- g_value_set_boolean (value, gst_rtsp_media_factory_is_record (factory));
+ case PROP_TRANSPORT_MODE:
+ g_value_set_flags (value,
+ gst_rtsp_media_factory_get_transport_mode (factory));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
case PROP_LATENCY:
gst_rtsp_media_factory_set_latency (factory, g_value_get_uint (value));
break;
- case PROP_RECORD:
- gst_rtsp_media_factory_set_record (factory, g_value_get_boolean (value));
+ case PROP_TRANSPORT_MODE:
+ gst_rtsp_media_factory_set_transport_mode (factory,
+ g_value_get_flags (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
GstRTSPPermissions *perms;
GstClockTime rtx_time;
guint latency;
- gboolean record;
+ GstRTSPTransportMode transport_mode;
/* configure the sharedness */
GST_RTSP_MEDIA_FACTORY_LOCK (factory);
protocols = priv->protocols;
rtx_time = priv->rtx_time;
latency = priv->latency;
- record = priv->record;
+ transport_mode = priv->transport_mode;
GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
gst_rtsp_media_set_suspend_mode (media, suspend_mode);
gst_rtsp_media_set_protocols (media, protocols);
gst_rtsp_media_set_retransmission_time (media, rtx_time);
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))) {
gst_rtsp_media_set_address_pool (media, pool);
}
/**
- * gst_rtsp_media_factory_set_record:
+ * gst_rtsp_media_factory_set_transport_mode:
* @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
-gst_rtsp_media_factory_set_record (GstRTSPMediaFactory * factory,
- gboolean record)
+gst_rtsp_media_factory_set_transport_mode (GstRTSPMediaFactory * factory,
+ GstRTSPTransportMode mode)
{
GstRTSPMediaFactoryPrivate *priv;
priv = factory->priv;
GST_RTSP_MEDIA_FACTORY_LOCK (factory);
- priv->record = record;
+ priv->transport_mode = mode;
GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
}
/**
- * gst_rtsp_media_factory_is_record:
+ * gst_rtsp_media_factory_get_transport_mode:
* @factory: a #GstRTSPMediaFactory
*
* Get if media created from this factory can be used for PLAY or RECORD
* methods.
*
- * Returns: %TRUE if the media will be record between clients.
+ * Returns: The supported transport modes.
*/
-gboolean
-gst_rtsp_media_factory_is_record (GstRTSPMediaFactory * factory)
+GstRTSPTransportMode
+gst_rtsp_media_factory_get_transport_mode (GstRTSPMediaFactory * factory)
{
GstRTSPMediaFactoryPrivate *priv;
- gboolean result;
+ GstRTSPTransportMode result;
g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), FALSE);
priv = factory->priv;
GST_RTSP_MEDIA_FACTORY_LOCK (factory);
- result = priv->record;
+ result = priv->transport_mode;
GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
return result;
guint latency);
guint gst_rtsp_media_factory_get_latency (GstRTSPMediaFactory * factory);
-void gst_rtsp_media_factory_set_record (GstRTSPMediaFactory *factory,
- gboolean record);
-gboolean gst_rtsp_media_factory_is_record (GstRTSPMediaFactory *factory);
+void gst_rtsp_media_factory_set_transport_mode (GstRTSPMediaFactory *factory,
+ GstRTSPTransportMode mode);
+GstRTSPTransportMode gst_rtsp_media_factory_get_transport_mode (GstRTSPMediaFactory *factory);
/* creating the media from the factory and a url */
GstRTSPMedia * gst_rtsp_media_factory_construct (GstRTSPMediaFactory *factory,
guint buffer_size;
GstRTSPAddressPool *pool;
gboolean blocked;
- gboolean record;
+ GstRTSPTransportMode transport_mode;
GstElement *element;
GRecMutex state_lock; /* locking order: state lock, lock */
#define DEFAULT_BUFFER_SIZE 0x80000
#define DEFAULT_TIME_PROVIDER FALSE
#define DEFAULT_LATENCY 200
-#define DEFAULT_RECORD FALSE
+#define DEFAULT_TRANSPORT_MODE GST_RTSP_TRANSPORT_MODE_PLAY
/* define to dump received RTCP packets */
#undef DUMP_STATS
PROP_ELEMENT,
PROP_TIME_PROVIDER,
PROP_LATENCY,
- PROP_RECORD,
+ PROP_TRANSPORT_MODE,
PROP_LAST
};
#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)
{
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);
static void
"Latency used for receiving media in milliseconds", 0, G_MAXUINT,
DEFAULT_BUFFER_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (gobject_class, PROP_RECORD,
- g_param_spec_boolean ("record", "Record",
+ g_object_class_install_property (gobject_class, PROP_TRANSPORT_MODE,
+ g_param_spec_flags ("transport-mode", "Transport Mode",
"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] =
g_signal_new ("new-stream", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
priv->eos_shutdown = DEFAULT_EOS_SHUTDOWN;
priv->buffer_size = DEFAULT_BUFFER_SIZE;
priv->time_provider = DEFAULT_TIME_PROVIDER;
- priv->record = DEFAULT_RECORD;
+ priv->transport_mode = DEFAULT_TRANSPORT_MODE;
}
static void
case PROP_LATENCY:
g_value_set_uint (value, gst_rtsp_media_get_latency (media));
break;
- case PROP_RECORD:
- g_value_set_boolean (value, gst_rtsp_media_is_record (media));
+ case PROP_TRANSPORT_MODE:
+ g_value_set_flags (value, gst_rtsp_media_get_transport_mode (media));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
case PROP_LATENCY:
gst_rtsp_media_set_latency (media, g_value_get_uint (value));
break;
- case PROP_RECORD:
- gst_rtsp_media_set_record (media, g_value_get_boolean (value));
+ case PROP_TRANSPORT_MODE:
+ gst_rtsp_media_set_transport_mode (media, g_value_get_flags (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
GstPad *pad;
gint i;
gboolean have_elem;
+ GstRTSPTransportMode mode = 0;
g_return_if_fail (GST_IS_RTSP_MEDIA (media));
gst_object_unref (elem);
have_elem = TRUE;
+ mode |= GST_RTSP_TRANSPORT_MODE_PLAY;
}
g_free (name);
g_mutex_unlock (&priv->lock);
have_elem = TRUE;
+ mode |= GST_RTSP_TRANSPORT_MODE_PLAY;
}
g_free (name);
gst_object_unref (elem);
have_elem = TRUE;
+ mode |= GST_RTSP_TRANSPORT_MODE_RECORD;
}
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);
+ }
}
/**
goto not_prepared;
/* 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? */
priv->seekable = FALSE;
} else {
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 (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) {
GST_INFO ("%p: went to PAUSED, prepared now", media);
collect_media_stats (media);
* seeking query in preroll instead */
priv->seekable = FALSE;
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 */
media_streams_set_blocked (media, TRUE);
}
}
/**
- * gst_rtsp_media_set_record:
+ * gst_rtsp_media_set_transport_mode:
* @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
- * methods.
+ * Sets if the media pipeline can work in PLAY or RECORD mode
*/
void
-gst_rtsp_media_set_record (GstRTSPMedia * media, gboolean record)
+gst_rtsp_media_set_transport_mode (GstRTSPMedia * media,
+ GstRTSPTransportMode mode)
{
GstRTSPMediaPrivate *priv;
priv = media->priv;
g_mutex_lock (&priv->lock);
- priv->record = record;
+ priv->transport_mode = mode;
g_mutex_unlock (&priv->lock);
}
/**
- * gst_rtsp_media_is_record:
+ * gst_rtsp_media_get_transport_mode:
* @media: a #GstRTSPMedia
*
* 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
-gst_rtsp_media_is_record (GstRTSPMedia * media)
+GstRTSPTransportMode
+gst_rtsp_media_get_transport_mode (GstRTSPMedia * media)
{
GstRTSPMediaPrivate *priv;
- gboolean res;
+ GstRTSPTransportMode res;
g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), FALSE);
priv = media->priv;
g_mutex_lock (&priv->lock);
- res = priv->record;
+ res = priv->transport_mode;
g_mutex_unlock (&priv->lock);
return res;
GST_RTSP_SUSPEND_MODE_RESET = 2
} 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())
GType gst_rtsp_suspend_mode_get_type (void);
void gst_rtsp_media_set_shared (GstRTSPMedia *media, gboolean shared);
gboolean gst_rtsp_media_is_shared (GstRTSPMedia *media);
-void gst_rtsp_media_set_record (GstRTSPMedia *media, gboolean record);
-gboolean gst_rtsp_media_is_record (GstRTSPMedia *media);
+void gst_rtsp_media_set_transport_mode (GstRTSPMedia *media, GstRTSPTransportMode mode);
+GstRTSPTransportMode gst_rtsp_media_get_transport_mode (GstRTSPMedia *media);
void gst_rtsp_media_set_reusable (GstRTSPMedia *media, gboolean reusable);
gboolean gst_rtsp_media_is_reusable (GstRTSPMedia *media);
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_mount_points_add_factory (mounts, TEST_MOUNT_POINT, factory);
g_object_unref (mounts);