mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-09-29 23:32:33 +00:00
rtsp-media: Use flags to distinguish between PLAY and RECORD media
This commit is contained in:
parent
aa1feab874
commit
a93ed7e5d4
7 changed files with 147 additions and 86 deletions
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue