...
 
Commits (10)
include: "https://gitlab.freedesktop.org/gstreamer/gst-ci/raw/master/gitlab/ci_template.yml"
include: "https://gitlab.freedesktop.org/gstreamer/gst-ci/raw/1.16/gitlab/ci_template.yml"
=== release 1.16.1 ===
2019-09-23 11:17:41 +0100 Tim-Philipp Müller <tim@centricular.com>
* ChangeLog:
* NEWS:
* RELEASE:
* configure.ac:
* gst-rtsp-server.doap:
* meson.build:
Release 1.16.1
2019-08-30 14:00:52 +0200 Kristofer Björkström <kristofb@axis.com>
* gst/rtsp-server/rtsp-client.c:
rtsp-client: RTP Info must exist in PLAY response
If RTP Info is missing. Then return GST_RTSP_STS_INTERNAL_SERVER_ERROR
Fixes #76
2019-06-25 13:19:44 +0100 Tim-Philipp Müller <tim@centricular.com>
* gst/rtsp-server/rtsp-onvif-media-factory.c:
* gst/rtsp-server/rtsp-onvif-media.c:
onvif-media: fix "void function returning a value" compiler warning
2019-04-23 14:38:05 +0300 Sebastian Dröge <sebastian@centricular.com>
* gst/rtsp-server/rtsp-media-factory.c:
* gst/rtsp-server/rtsp-media.c:
* gst/rtsp-server/rtsp-stream-transport.c:
* gst/rtsp-server/rtsp-stream.c:
rtsp-server: Add various missing Since: 1.16 markers
2019-04-23 15:01:32 +0300 Sebastian Dröge <sebastian@centricular.com>
* gst/rtsp-server/rtsp-media.c:
* gst/rtsp-server/rtsp-sdp.c:
* gst/rtsp-server/rtsp-session-media.c:
* gst/rtsp-server/rtsp-stream.c:
rtsp-server: Add various Since: 1.14 markers
2019-04-23 15:09:34 +0300 Sebastian Dröge <sebastian@centricular.com>
* gst/rtsp-server/rtsp-auth.c:
* gst/rtsp-server/rtsp-client.h:
rtsp-server: Fix various Since markers
2019-05-02 12:35:34 +0100 Tim-Philipp Müller <tim@centricular.com>
* .gitlab-ci.yml:
ci: use template from 1.16 branch
=== release 1.16.0 ===
2019-04-19 00:34:54 +0100 Tim-Philipp Müller <tim@centricular.com>
......
This diff is collapsed.
This is GStreamer gst-rtsp-server 1.16.0.
This is GStreamer gst-rtsp-server 1.16.1.
The GStreamer team is thrilled to announce a new major feature release in the
stable 1.0 API series of your favourite cross-platform multimedia framework!
As always, this release is again packed with new features, bug fixes and
other improvements.
The GStreamer team is pleased to announce another bug-fix release in the
stable 1.x API series of your favourite cross-platform multimedia framework!
The 1.16 release series adds new features on top of the 1.14 series and is
part of the API and ABI-stable 1.x release series of the GStreamer multimedia
......@@ -60,7 +57,7 @@ You can find source releases of gstreamer in the download
directory: https://gstreamer.freedesktop.org/src/gstreamer/
The git repository and details how to clone it can be found at
https://cgit.freedesktop.org/gstreamer/gstreamer/
https://gitlab.freedesktop.org/gstreamer/
==== Homepage ====
......
......@@ -2,7 +2,7 @@ AC_PREREQ(2.69)
dnl initialize autoconf
dnl when going to/from release please set the nano (fourth number) right !
dnl releases only do Wall, cvs and prerelease does Werror too
AC_INIT([GStreamer RTSP Server Library], [1.16.0],
AC_INIT([GStreamer RTSP Server Library], [1.16.1],
[http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer],
[gst-rtsp-server])
AG_GST_INIT
......@@ -53,13 +53,13 @@ dnl 1.2.5 => 205
dnl 1.10.9 (who knows) => 1009
dnl
dnl sets GST_LT_LDFLAGS
AS_LIBTOOL(GST, 1600, 0, 1600)
AS_LIBTOOL(GST, 1601, 0, 1601)
dnl *** required versions of GStreamer stuff ***
GST_REQ=1.16.0
GSTPB_REQ=1.16.0
GSTPG_REQ=1.16.0
GSTPD_REQ=1.16.0
GST_REQ=1.16.1
GSTPB_REQ=1.16.1
GSTPG_REQ=1.16.1
GSTPD_REQ=1.16.1
dnl *** autotools stuff ****
......
......@@ -30,6 +30,16 @@ RTSP server library based on GStreamer
</GitRepository>
</repository>
<release>
<Version>
<revision>1.16.1</revision>
<branch>1.16</branch>
<name></name>
<created>2019-09-23</created>
<file-release rdf:resource="https://gstreamer.freedesktop.org/src/gst-rtsp-server/gst-rtsp-server-1.16.1.tar.xz" />
</Version>
</release>
<release>
<Version>
<revision>1.16.0</revision>
......
......@@ -323,7 +323,7 @@ gst_rtsp_auth_get_tls_certificate (GstRTSPAuth * auth)
* If set to %NULL (the default), then peer certificate validation will always
* set the %G_TLS_CERTIFICATE_UNKNOWN_CA error.
*
* Since 1.6
* Since: 1.6
*/
void
gst_rtsp_auth_set_tls_database (GstRTSPAuth * auth, GTlsDatabase * database)
......
......@@ -202,6 +202,7 @@ static GstRTSPStatusCode default_pre_signal_handler (GstRTSPClient * client,
GstRTSPContext * ctx);
static gboolean pre_signal_accumulator (GSignalInvocationHint * ihint,
GValue * return_accu, const GValue * handler_return, gpointer data);
gboolean gst_rtsp_media_has_completed_sender (GstRTSPMedia * media);
G_DEFINE_TYPE_WITH_PRIVATE (GstRTSPClient, gst_rtsp_client, G_TYPE_OBJECT);
......@@ -1741,7 +1742,7 @@ handle_play_request (GstRTSPClient * client, GstRTSPContext * ctx)
GstRTSPResult res;
GstRTSPState rtspstate;
GstRTSPRangeUnit unit = GST_RTSP_RANGE_NPT;
gchar *path, *rtpinfo;
gchar *path, *rtpinfo = NULL;
gint matched;
gchar *seek_style = NULL;
GstRTSPStatusCode sig_result;
......@@ -1830,7 +1831,9 @@ handle_play_request (GstRTSPClient * client, GstRTSPContext * ctx)
}
/* grab RTPInfo from the media now */
rtpinfo = gst_rtsp_session_media_get_rtpinfo (sessmedia);
if (gst_rtsp_media_has_completed_sender (media) &&
!(rtpinfo = gst_rtsp_session_media_get_rtpinfo (sessmedia)))
goto rtp_info_error;
/* construct the response now */
code = GST_RTSP_STS_OK;
......@@ -1927,6 +1930,12 @@ unsupported_mode:
send_generic_response (client, GST_RTSP_STS_METHOD_NOT_ALLOWED, ctx);
return FALSE;
}
rtp_info_error:
{
GST_ERROR ("client %p: failed to add RTP-Info", client);
send_generic_response (client, GST_RTSP_STS_INTERNAL_SERVER_ERROR, ctx);
return FALSE;
}
}
static void
......@@ -3086,16 +3095,18 @@ handle_announce_request (GstRTSPClient * client, GstRTSPContext * ctx)
n_streams = gst_rtsp_media_n_streams (media);
for (i = 0; i < n_streams; i++) {
GstRTSPStream *stream = gst_rtsp_media_get_stream (media, i);
gchar *location =
g_strdup_printf ("rtsp://%s%s:8554/stream=%d", priv->server_ip, path,
i);
gchar *keymgmt = stream_make_keymgmt (client, location, stream);
gchar *uri, *location, *keymgmt;
uri = gst_rtsp_url_get_request_uri (ctx->uri);
location = g_strdup_printf ("%s/stream=%d", uri, i);
keymgmt = stream_make_keymgmt (client, location, stream);
if (keymgmt)
gst_rtsp_message_take_header (ctx->response, GST_RTSP_HDR_KEYMGMT,
keymgmt);
g_free (location);
g_free (uri);
}
/* we suspend after the announce */
......
......@@ -108,7 +108,7 @@ struct _GstRTSPClient {
* @params_get: get parameters. This function should also initialize the
* RTSP response(ctx->response) via a call to gst_rtsp_message_init_response()
* @tunnel_http_response: called when a response to the GET request is about to
* be sent for a tunneled connection. The response can be modified. Since 1.4
* be sent for a tunneled connection. The response can be modified. Since: 1.4
*
* The client class structure.
*/
......
......@@ -1511,6 +1511,8 @@ gst_rtsp_media_factory_get_publish_clock_mode (GstRTSPMediaFactory * factory)
* Set the maximum time-to-live value of outgoing multicast packets.
*
* Returns: %TRUE if the requested ttl has been set successfully.
*
* Since: 1.16
*/
gboolean
gst_rtsp_media_factory_set_max_mcast_ttl (GstRTSPMediaFactory * factory,
......@@ -1541,6 +1543,8 @@ gst_rtsp_media_factory_set_max_mcast_ttl (GstRTSPMediaFactory * factory,
* Get the the maximum time-to-live value of outgoing multicast packets.
*
* Returns: the maximum time-to-live value of outgoing multicast packets.
*
* Since: 1.16
*/
guint
gst_rtsp_media_factory_get_max_mcast_ttl (GstRTSPMediaFactory * factory)
......@@ -1566,6 +1570,8 @@ gst_rtsp_media_factory_get_max_mcast_ttl (GstRTSPMediaFactory * factory)
*
* Decide whether the multicast socket should be bound to a multicast address or
* INADDR_ANY.
*
* Since: 1.16
*/
void
gst_rtsp_media_factory_set_bind_mcast_address (GstRTSPMediaFactory * factory,
......@@ -1589,6 +1595,8 @@ gst_rtsp_media_factory_set_bind_mcast_address (GstRTSPMediaFactory * factory,
* Check if multicast sockets are configured to be bound to multicast addresses.
*
* Returns: %TRUE if multicast sockets are configured to be bound to multicast addresses.
*
* Since: 1.16
*/
gboolean
gst_rtsp_media_factory_is_bind_mcast_address (GstRTSPMediaFactory * factory)
......
......@@ -237,6 +237,9 @@ static GstElement *find_payload_element (GstElement * payloader);
static guint gst_rtsp_media_signals[SIGNAL_LAST] = { 0 };
static gboolean check_complete (GstRTSPMedia * media);
gboolean gst_rtsp_media_has_completed_sender (GstRTSPMedia * media);
static gboolean gst_rtsp_media_is_receive_only (GstRTSPMedia * media);
#define C_ENUM(v) ((gint) v)
......@@ -731,23 +734,24 @@ default_create_rtpbin (GstRTSPMedia * media)
return rtpbin;
}
/* Must be called with priv->lock */
static gboolean
is_receive_only (GstRTSPMedia * media)
{
GstRTSPMediaPrivate *priv = media->priv;
gboolean recive_only = TRUE;
gboolean receive_only = TRUE;
guint i;
for (i = 0; i < priv->streams->len; i++) {
GstRTSPStream *stream = g_ptr_array_index (priv->streams, i);
if (gst_rtsp_stream_is_sender (stream) ||
!gst_rtsp_stream_is_receiver (stream)) {
recive_only = FALSE;
receive_only = FALSE;
break;
}
}
return recive_only;
return receive_only;
}
/* must be called with state lock */
......@@ -757,6 +761,7 @@ check_seekable (GstRTSPMedia * media)
GstQuery *query;
GstRTSPMediaPrivate *priv = media->priv;
g_mutex_lock (&priv->lock);
/* Update the seekable state of the pipeline in case it changed */
if (is_receive_only (media)) {
/* TODO: Seeking for "receive-only"? */
......@@ -770,6 +775,7 @@ check_seekable (GstRTSPMedia * media)
if (gst_rtsp_stream_get_publish_clock_mode (stream) ==
GST_RTSP_PUBLISH_CLOCK_MODE_CLOCK_AND_OFFSET) {
priv->seekable = -1;
g_mutex_unlock (&priv->lock);
return;
}
}
......@@ -796,7 +802,7 @@ check_seekable (GstRTSPMedia * media)
}
GST_DEBUG_OBJECT (media, "seekable:%" G_GINT64_FORMAT, priv->seekable);
g_mutex_unlock (&priv->lock);
gst_query_unref (query);
}
......@@ -818,7 +824,7 @@ check_complete (GstRTSPMedia * media)
return FALSE;
}
/* must be called with state lock */
/* must be called with state lock and private lock */
static void
collect_media_stats (GstRTSPMedia * media)
{
......@@ -826,8 +832,9 @@ collect_media_stats (GstRTSPMedia * media)
gint64 position = 0, stop = -1;
if (priv->status != GST_RTSP_MEDIA_STATUS_PREPARED &&
priv->status != GST_RTSP_MEDIA_STATUS_PREPARING)
priv->status != GST_RTSP_MEDIA_STATUS_PREPARING) {
return;
}
priv->range.unit = GST_RTSP_RANGE_NPT;
......@@ -887,8 +894,9 @@ collect_media_stats (GstRTSPMedia * media)
priv->range.max.seconds = ((gdouble) stop) / GST_SECOND;
priv->range_stop = stop;
}
g_mutex_unlock (&priv->lock);
check_seekable (media);
g_mutex_lock (&priv->lock);
}
}
......@@ -1869,6 +1877,8 @@ gst_rtsp_media_get_multicast_iface (GstRTSPMedia * media)
* Set the maximum time-to-live value of outgoing multicast packets.
*
* Returns: %TRUE if the requested ttl has been set successfully.
*
* Since: 1.16
*/
gboolean
gst_rtsp_media_set_max_mcast_ttl (GstRTSPMedia * media, guint ttl)
......@@ -1907,6 +1917,8 @@ gst_rtsp_media_set_max_mcast_ttl (GstRTSPMedia * media, guint ttl)
* Get the the maximum time-to-live value of outgoing multicast packets.
*
* Returns: the maximum time-to-live value of outgoing multicast packets.
*
* Since: 1.16
*/
guint
gst_rtsp_media_get_max_mcast_ttl (GstRTSPMedia * media)
......@@ -1932,6 +1944,8 @@ gst_rtsp_media_get_max_mcast_ttl (GstRTSPMedia * media)
*
* Decide whether the multicast socket should be bound to a multicast address or
* INADDR_ANY.
*
* Since: 1.16
*/
void
gst_rtsp_media_set_bind_mcast_address (GstRTSPMedia * media,
......@@ -1960,6 +1974,8 @@ gst_rtsp_media_set_bind_mcast_address (GstRTSPMedia * media,
* Check if multicast sockets are configured to be bound to multicast addresses.
*
* Returns: %TRUE if multicast sockets are configured to be bound to multicast addresses.
*
* Since: 1.16
*/
gboolean
gst_rtsp_media_is_bind_mcast_address (GstRTSPMedia * media)
......@@ -2510,9 +2526,8 @@ gst_rtsp_media_get_range_string (GstRTSPMedia * media, gboolean play,
priv->status != GST_RTSP_MEDIA_STATUS_SUSPENDED)
goto not_prepared;
g_mutex_lock (&priv->lock);
/* Update the range value with current position/duration */
g_mutex_lock (&priv->lock);
collect_media_stats (media);
/* make copy */
......@@ -2546,6 +2561,27 @@ conversion_failed:
}
}
gboolean
gst_rtsp_media_has_completed_sender (GstRTSPMedia * media)
{
GstRTSPMediaPrivate *priv = media->priv;
gboolean sender = FALSE;
guint i;
g_mutex_lock (&priv->lock);
for (i = 0; i < priv->streams->len; i++) {
GstRTSPStream *stream = g_ptr_array_index (priv->streams, i);
if (gst_rtsp_stream_is_complete (stream) &&
gst_rtsp_stream_is_sender (stream)) {
sender = TRUE;
break;
}
}
g_mutex_unlock (&priv->lock);
return sender;
}
static void
stream_update_blocked (GstRTSPStream * stream, GstRTSPMedia * media)
{
......@@ -2637,6 +2673,8 @@ gst_rtsp_media_get_status (GstRTSPMedia * media)
* the pipeline must contain all needed transport parts (transport sinks).
*
* Returns: %TRUE on success.
*
* Since: 1.14
*/
gboolean
gst_rtsp_media_seek_full (GstRTSPMedia * media, GstRTSPTimeRange * range,
......@@ -2900,10 +2938,13 @@ default_handle_message (GstRTSPMedia * media, GstMessage * message)
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 (priv->no_more_pads_pending == 0 && is_receive_only (media) &&
old == GST_STATE_READY && new == GST_STATE_PAUSED) {
if (priv->no_more_pads_pending == 0
&& gst_rtsp_media_is_receive_only (media) && old == GST_STATE_READY
&& new == GST_STATE_PAUSED) {
GST_INFO ("%p: went to PAUSED, prepared now", media);
g_mutex_lock (&priv->lock);
collect_media_stats (media);
g_mutex_unlock (&priv->lock);
if (priv->status == GST_RTSP_MEDIA_STATUS_PREPARING)
gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_PREPARED);
......@@ -2985,7 +3026,9 @@ default_handle_message (GstRTSPMedia * media, GstMessage * message)
if (priv->blocked && media_streams_blocking (media) &&
priv->no_more_pads_pending == 0) {
GST_DEBUG_OBJECT (GST_MESSAGE_SRC (message), "media is blocking");
g_mutex_lock (&priv->lock);
collect_media_stats (media);
g_mutex_unlock (&priv->lock);
if (priv->status == GST_RTSP_MEDIA_STATUS_PREPARING)
gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_PREPARED);
......@@ -3375,7 +3418,7 @@ start_prepare (GstRTSPMedia * media)
g_object_set_data (G_OBJECT (elem), "gst-rtsp-dynpay-handlers", handlers);
}
if (priv->nb_dynamic_elements == 0 && is_receive_only (media)) {
if (priv->nb_dynamic_elements == 0 && gst_rtsp_media_is_receive_only (media)) {
/* If we are receive_only (RECORD), do not try to preroll, to avoid
* a second ASYNC state change failing */
priv->is_live = TRUE;
......@@ -4202,7 +4245,7 @@ default_unsuspend (GstRTSPMedia * media)
switch (priv->suspend_mode) {
case GST_RTSP_SUSPEND_MODE_NONE:
if (is_receive_only (media))
if (gst_rtsp_media_is_receive_only (media))
break;
if (media_streams_blocking (media)) {
gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_PREPARING);
......@@ -4441,7 +4484,7 @@ gst_rtsp_media_set_state (GstRTSPMedia * media, GstState state,
/* we just activated the first media, do the playing state change */
if (old_active == 0 && activate)
do_state = TRUE;
/* if we have no more active media and prepare count is not indicate
/* if we have no more active media and prepare count is not indicate
* that there are new session/sessions ongoing,
* do the downward state changes */
else if (priv->n_active == 0 && priv->prepare_count <= 1)
......@@ -4462,9 +4505,11 @@ gst_rtsp_media_set_state (GstRTSPMedia * media, GstState state,
/* remember where we are */
if (state != GST_STATE_NULL && (state == GST_STATE_PAUSED ||
old_active != priv->n_active))
old_active != priv->n_active)) {
g_mutex_lock (&priv->lock);
collect_media_stats (media);
g_mutex_unlock (&priv->lock);
}
g_rec_mutex_unlock (&priv->state_lock);
return TRUE;
......@@ -4546,7 +4591,7 @@ gst_rtsp_media_get_transport_mode (GstRTSPMedia * media)
}
/**
* gst_rtsp_media_get_seekable:
* gst_rtsp_media_seekable:
* @media: a #GstRTSPMedia
*
* Check if the pipeline for @media seek and up to what point in time,
......@@ -4555,6 +4600,8 @@ gst_rtsp_media_get_transport_mode (GstRTSPMedia * media)
* Returns: -1 if the stream is not seekable, 0 if seekable only to the beginning
* and > 0 to indicate the longest duration between any two random access points.
* %G_MAXINT64 means any value is possible.
*
* Since: 1.14
*/
GstClockTimeDiff
gst_rtsp_media_seekable (GstRTSPMedia * media)
......@@ -4584,6 +4631,8 @@ gst_rtsp_media_seekable (GstRTSPMedia * media)
* SETUP.
*
* Returns: %TRUE if the media pipeline has been sucessfully updated.
*
* Since: 1.14
*/
gboolean
gst_rtsp_media_complete_pipeline (GstRTSPMedia * media, GPtrArray * transports)
......@@ -4625,3 +4674,16 @@ gst_rtsp_media_complete_pipeline (GstRTSPMedia * media, GPtrArray * transports)
return TRUE;
}
gboolean
gst_rtsp_media_is_receive_only (GstRTSPMedia * media)
{
GstRTSPMediaPrivate *priv = media->priv;
gboolean receive_only;
g_mutex_lock (&priv->lock);
receive_only = is_receive_only (media);
g_mutex_unlock (&priv->lock);
return receive_only;
}
......@@ -330,9 +330,7 @@ gst_rtsp_onvif_media_factory_finalize (GObject * object)
g_mutex_clear (&factory->priv->lock);
return
G_OBJECT_CLASS (gst_rtsp_onvif_media_factory_parent_class)->finalize
(object);
G_OBJECT_CLASS (gst_rtsp_onvif_media_factory_parent_class)->finalize (object);
}
static void
......
......@@ -212,7 +212,7 @@ gst_rtsp_onvif_media_finalize (GObject * object)
g_mutex_clear (&media->priv->lock);
return G_OBJECT_CLASS (gst_rtsp_onvif_media_parent_class)->finalize (object);
G_OBJECT_CLASS (gst_rtsp_onvif_media_parent_class)->finalize (object);
}
static void
......
......@@ -184,6 +184,20 @@ cleanup:
}
}
/**
* gst_rtsp_sdp_make_media:
* @sdp: a #GstRTSPMessage
* @info: a #GstSDPInfo
* @stream: a #GstRTSPStream
* @caps: a #GstCaps
* @profile: a #GstRTSPProfile
*
* Creates a #GstSDPMedia from the parameters and stores it in @sdp.
*
* Returns: %TRUE on success
*
* Since: 1.14
*/
gboolean
gst_rtsp_sdp_make_media (GstSDPMessage * sdp, GstSDPInfo * info,
GstRTSPStream * stream, GstCaps * caps, GstRTSPProfile profile)
......
......@@ -416,6 +416,8 @@ gst_rtsp_session_media_get_transport (GstRTSPSessionMedia * media, guint idx)
*
* Returns: (transfer full) (element-type GstRTSPStreamTransport): a
* list of #GstRTSPStreamTransport, g_ptr_array_unref () after usage.
*
* Since: 1.14
*/
GPtrArray *
gst_rtsp_session_media_get_transports (GstRTSPSessionMedia * media)
......
......@@ -682,6 +682,8 @@ gst_rtsp_stream_transport_keep_alive (GstRTSPStreamTransport * trans)
* @trans: a #GstRTSPStreamTransport
*
* Signal the installed message_sent callback for @trans.
*
* Since: 1.16
*/
void
gst_rtsp_stream_transport_message_sent (GstRTSPStreamTransport * trans)
......
......@@ -2107,6 +2107,7 @@ gst_rtsp_stream_get_buffer_size (GstRTSPStream * stream)
*
* Returns: %TRUE if the requested ttl has been set successfully.
*
* Since: 1.16
*/
gboolean
gst_rtsp_stream_set_max_mcast_ttl (GstRTSPStream * stream, guint ttl)
......@@ -2133,6 +2134,7 @@ gst_rtsp_stream_set_max_mcast_ttl (GstRTSPStream * stream, guint ttl)
*
* Returns: the maximum time-to-live value of outgoing multicast packets.
*
* Since: 1.16
*/
guint
gst_rtsp_stream_get_max_mcast_ttl (GstRTSPStream * stream)
......@@ -2155,6 +2157,7 @@ gst_rtsp_stream_get_max_mcast_ttl (GstRTSPStream * stream)
*
* Returns: TRUE if the requested ttl value is allowed.
*
* Since: 1.16
*/
gboolean
gst_rtsp_stream_verify_mcast_ttl (GstRTSPStream * stream, guint ttl)
......@@ -2176,6 +2179,8 @@ gst_rtsp_stream_verify_mcast_ttl (GstRTSPStream * stream, guint ttl)
*
* Decide whether the multicast socket should be bound to a multicast address or
* INADDR_ANY.
*
* Since: 1.16
*/
void
gst_rtsp_stream_set_bind_mcast_address (GstRTSPStream * stream,
......@@ -2195,6 +2200,8 @@ gst_rtsp_stream_set_bind_mcast_address (GstRTSPStream * stream,
* Check if multicast sockets are configured to be bound to multicast addresses.
*
* Returns: %TRUE if multicast sockets are configured to be bound to multicast addresses.
*
* Since: 1.16
*/
gboolean
gst_rtsp_stream_is_bind_mcast_address (GstRTSPStream * stream)
......@@ -4639,6 +4646,7 @@ gst_rtsp_stream_get_rtcp_socket (GstRTSPStream * stream, GSocketFamily family)
* Get the multicast RTP socket from @stream for a @family.
*
* Returns: (transfer full) (nullable): the multicast RTP socket or %NULL if no
*
* socket could be allocated for @family. Unref after usage
*/
GSocket *
......@@ -4674,6 +4682,8 @@ gst_rtsp_stream_get_rtp_multicast_socket (GstRTSPStream * stream,
*
* Returns: (transfer full) (nullable): the multicast RTCP socket or %NULL if no
* socket could be allocated for @family. Unref after usage
*
* Since: 1.14
*/
GSocket *
gst_rtsp_stream_get_rtcp_multicast_socket (GstRTSPStream * stream,
......@@ -4712,6 +4722,8 @@ gst_rtsp_stream_get_rtcp_multicast_socket (GstRTSPStream * stream,
* allocated.
*
* Returns: %TRUE if @destination can be addedd and handled by @stream.
*
* Since: 1.16
*/
gboolean
gst_rtsp_stream_add_multicast_client_address (GstRTSPStream * stream,
......@@ -4760,6 +4772,8 @@ add_addr_error:
* Get all multicast client addresses that RTP data will be sent to
*
* Returns: A comma separated list of host:port pairs with destinations
*
* Since: 1.16
*/
gchar *
gst_rtsp_stream_get_multicast_client_addresses (GstRTSPStream * stream)
......@@ -5021,6 +5035,8 @@ gst_rtsp_stream_set_blocked (GstRTSPStream * stream, gboolean blocked)
* Unblocks the dataflow on @stream if it is linked.
*
* Returns: %TRUE on success
*
* Since: 1.14
*/
gboolean
gst_rtsp_stream_unblock_linked (GstRTSPStream * stream)
......@@ -5237,6 +5253,8 @@ gst_rtsp_stream_query_stop (GstRTSPStream * stream, gint64 * stop)
* Checks whether the individual @stream is seekable.
*
* Returns: %TRUE if @stream is seekable, else %FALSE.
*
* Since: 1.14
*/
gboolean
gst_rtsp_stream_seekable (GstRTSPStream * stream)
......@@ -5291,6 +5309,8 @@ beach:
* SETUP.
*
* Returns: %TRUE if the stream has been sucessfully updated.
*
* Since: 1.14
*/
gboolean
gst_rtsp_stream_complete_stream (GstRTSPStream * stream,
......@@ -5341,6 +5361,8 @@ unallowed_transport:
* seek operations on it.
*
* Returns: %TRUE if the stream contains at least one sink element.
*
* Since: 1.14
*/
gboolean
gst_rtsp_stream_is_complete (GstRTSPStream * stream)
......@@ -5365,6 +5387,8 @@ gst_rtsp_stream_is_complete (GstRTSPStream * stream)
* Checks whether the stream is a sender.
*
* Returns: %TRUE if the stream is a sender and %FALSE otherwise.
*
* Since: 1.14
*/
gboolean
gst_rtsp_stream_is_sender (GstRTSPStream * stream)
......@@ -5389,6 +5413,8 @@ gst_rtsp_stream_is_sender (GstRTSPStream * stream)
* Checks whether the stream is a receiver.
*
* Returns: %TRUE if the stream is a receiver and %FALSE otherwise.
*
* Since: 1.14
*/
gboolean
gst_rtsp_stream_is_receiver (GstRTSPStream * stream)
......
project('gst-rtsp-server', 'c',
version : '1.16.0',
version : '1.16.1',
meson_version : '>= 0.47',
default_options : ['warning_level=1', 'buildtype=debugoptimized'])
......
......@@ -54,6 +54,51 @@ test_response_200 (GstRTSPClient * client, GstRTSPMessage * response,
return TRUE;
}
static gboolean
test_response_play_200 (GstRTSPClient * client, GstRTSPMessage * response,
gboolean close, gpointer user_data)
{
GstRTSPStatusCode code;
const gchar *reason;
GstRTSPVersion version;
gchar *str;
gchar **session_hdr_params;
gchar *pattern;
fail_unless_equals_int (gst_rtsp_message_get_type (response),
GST_RTSP_MESSAGE_RESPONSE);
fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
&version)
== GST_RTSP_OK);
fail_unless_equals_int (code, GST_RTSP_STS_OK);
fail_unless_equals_string (reason, "OK");
fail_unless_equals_int (version, GST_RTSP_VERSION_1_0);
/* Verify mandatory headers according to RFC 2326 */
/* verify mandatory CSeq header */
fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_CSEQ, &str,
0) == GST_RTSP_OK);
fail_unless (atoi (str) == cseq++);
/* verify mandatory Session header */
fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_SESSION,
&str, 0) == GST_RTSP_OK);
session_hdr_params = g_strsplit (str, ";", -1);
fail_unless (session_hdr_params[0] != NULL);
g_strfreev (session_hdr_params);
/* verify mandatory RTP-Info header */
fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_RTP_INFO,
&str, 0) == GST_RTSP_OK);
pattern = g_strdup_printf ("^url=rtsp://.+;seq=[0-9]+;rtptime=[0-9]+");
fail_unless (g_regex_match_simple (pattern, str, 0, 0),
"GST_RTSP_HDR_RTP_INFO '%s' doesn't match pattern '%s'", str, pattern);
g_free (pattern);
return TRUE;
}
static gboolean
test_response_400 (GstRTSPClient * client, GstRTSPMessage * response,
gboolean close, gpointer user_data)
......@@ -1707,7 +1752,55 @@ GST_START_TEST (test_client_multicast_invalid_ttl)
GST_END_TEST;
static Suite *
GST_START_TEST (test_client_play)
{
GstRTSPClient *client;
GstRTSPMessage request = { 0, };
gchar *str;
GstRTSPContext ctx = { NULL };
client = setup_multicast_client (1);
ctx.client = client;
ctx.auth = gst_rtsp_auth_new ();
ctx.token =
gst_rtsp_token_new (GST_RTSP_TOKEN_MEDIA_FACTORY_ROLE, G_TYPE_STRING,
"user", NULL);
gst_rtsp_context_push_current (&ctx);
fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
"rtsp://localhost/test/stream=0") == GST_RTSP_OK);
str = g_strdup_printf ("%d", cseq);
gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
"RTP/AVP;multicast");
/* destination is from adress pool */
expected_transport = "RTP/AVP;multicast;destination=233.252.0.1;"
"ttl=1;port=.*;mode=\"PLAY\"";
gst_rtsp_client_set_send_func (client, test_setup_response_200, NULL, NULL);
fail_unless (gst_rtsp_client_handle_message (client,
&request) == GST_RTSP_OK);
gst_rtsp_message_unset (&request);
expected_transport = NULL;
fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_PLAY,
"rtsp://localhost/test") == GST_RTSP_OK);
str = g_strdup_printf ("%d", cseq);
gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
gst_rtsp_message_add_header (&request, GST_RTSP_HDR_SESSION, session_id);
gst_rtsp_client_set_send_func (client, test_response_play_200, NULL, NULL);
fail_unless (gst_rtsp_client_handle_message (client,
&request) == GST_RTSP_OK);
gst_rtsp_message_unset (&request);
send_teardown (client);
teardown_client (client);
g_object_unref (ctx.auth);
gst_rtsp_token_unref (ctx.token);
gst_rtsp_context_pop_current (&ctx);
}
GST_END_TEST static Suite *
rtspclient_suite (void)
{
Suite *s = suite_create ("rtspclient");
......@@ -1759,6 +1852,7 @@ rtspclient_suite (void)
tcase_add_test (tc, test_client_multicast_max_ttl_first_client);
tcase_add_test (tc, test_client_multicast_max_ttl_second_client);
tcase_add_test (tc, test_client_multicast_invalid_ttl);
tcase_add_test (tc, test_client_play);
return s;
}
......