mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 19:51:11 +00:00
rtsp: Add support for ONVIF backchannel
This adds a new RTSP server, client, media-factory and media subclass for handling the specifics of the backchannel. Ideally this later can be extended with other ONVIF specific features.
This commit is contained in:
parent
231700b2bb
commit
72dc8acd86
17 changed files with 1497 additions and 7 deletions
|
@ -33,6 +33,10 @@
|
|||
<xi:include href="xml/rtsp-token.xml"/>
|
||||
<xi:include href="xml/rtsp-permissions.xml"/>
|
||||
<xi:include href="xml/rtsp-params.xml"/>
|
||||
<xi:include href="xml/rtsp-onvif-server.xml"/>
|
||||
<xi:include href="xml/rtsp-onvif-client.xml"/>
|
||||
<xi:include href="xml/rtsp-onvif-media-factory.xml"/>
|
||||
<xi:include href="xml/rtsp-onvif-media.xml"/>
|
||||
</chapter>
|
||||
|
||||
<chapter id="rtsp-server-hierarchy">
|
||||
|
|
|
@ -182,7 +182,9 @@ gst_rtsp_media_set_latency
|
|||
gst_rtsp_media_get_latency
|
||||
|
||||
gst_rtsp_media_setup_sdp
|
||||
gst_rtsp_media_setup_sdp_full
|
||||
gst_rtsp_media_handle_sdp
|
||||
gst_rtsp_media_handle_sdp_full
|
||||
|
||||
<SUBSECTION MediaPrepare>
|
||||
gst_rtsp_media_prepare
|
||||
|
@ -281,7 +283,9 @@ gst_rtsp_media_factory_set_media_gtype
|
|||
gst_rtsp_media_factory_get_media_gtype
|
||||
|
||||
gst_rtsp_media_factory_construct
|
||||
gst_rtsp_media_factory_construct_full
|
||||
gst_rtsp_media_factory_create_element
|
||||
gst_rtsp_media_factory_create_element_full
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GST_RTSP_MEDIA_FACTORY_CAST
|
||||
|
@ -739,3 +743,106 @@ GST_TYPE_RTSP_TOKEN
|
|||
gst_rtsp_token_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>rtsp-onvif-server</FILE>
|
||||
<TITLE>GstRTSPOnvifServer</TITLE>
|
||||
GstRTSPOnvifServer
|
||||
GstRTSPOnvifServerClass
|
||||
|
||||
gst_rtsp_onvif_server_new
|
||||
|
||||
GST_RTSP_ONVIF_BACKCHANNEL_REQUIREMENT
|
||||
<SUBSECTION Standard>
|
||||
gst_rtsp_onvif_server_get_type
|
||||
GST_TYPE_RTSP_ONVIF_SERVER
|
||||
GST_RTSP_ONVIF_SERVER
|
||||
GST_RTSP_ONVIF_SERVER_CAST
|
||||
GST_RTSP_ONVIF_SERVER_CLASS
|
||||
GST_RTSP_ONVIF_SERVER_CLASS_CAST
|
||||
GST_RTSP_ONVIF_SERVER_GET_CLASS
|
||||
GST_IS_RTSP_ONVIF_SERVER
|
||||
GST_IS_RTSP_ONVIF_SERVER_CLASS
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>rtsp-onvif-server</FILE>
|
||||
<TITLE>GstRTSPOnvifServer</TITLE>
|
||||
GstRTSPOnvifServer
|
||||
GstRTSPOnvifServerClass
|
||||
|
||||
gst_rtsp_onvif_server_new
|
||||
<SUBSECTION Standard>
|
||||
gst_rtsp_onvif_server_get_type
|
||||
GST_TYPE_RTSP_ONVIF_SERVER
|
||||
GST_RTSP_ONVIF_SERVER
|
||||
GST_RTSP_ONVIF_SERVER_CAST
|
||||
GST_RTSP_ONVIF_SERVER_CLASS
|
||||
GST_RTSP_ONVIF_SERVER_CLASS_CAST
|
||||
GST_RTSP_ONVIF_SERVER_GET_CLASS
|
||||
GST_IS_RTSP_ONVIF_SERVER
|
||||
GST_IS_RTSP_ONVIF_SERVER_CLASS
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>rtsp-onvif-client</FILE>
|
||||
<TITLE>GstRTSPOnvifClient</TITLE>
|
||||
GstRTSPOnvifClient
|
||||
GstRTSPOnvifClientClass
|
||||
<SUBSECTION Standard>
|
||||
gst_rtsp_onvif_client_get_type
|
||||
GST_TYPE_RTSP_ONVIF_CLIENT
|
||||
GST_RTSP_ONVIF_CLIENT
|
||||
GST_RTSP_ONVIF_CLIENT_CAST
|
||||
GST_RTSP_ONVIF_CLIENT_CLASS
|
||||
GST_RTSP_ONVIF_CLIENT_CLASS_CAST
|
||||
GST_RTSP_ONVIF_CLIENT_GET_CLASS
|
||||
GST_IS_RTSP_ONVIF_CLIENT
|
||||
GST_IS_RTSP_ONVIF_CLIENT_CLASS
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>rtsp-onvif-media-factory</FILE>
|
||||
<TITLE>GstRTSPOnvifMediaFactory</TITLE>
|
||||
GstRTSPOnvifMediaFactory
|
||||
GstRTSPOnvifMediaFactoryClass
|
||||
|
||||
gst_rtsp_onvif_media_factory_new
|
||||
gst_rtsp_onvif_media_factory_has_backchannel_support
|
||||
gst_rtsp_onvif_media_factory_set_backchannel_bandwidth
|
||||
gst_rtsp_onvif_media_factory_get_backchannel_bandwidth
|
||||
gst_rtsp_onvif_media_factory_set_backchannel_launch
|
||||
gst_rtsp_onvif_media_factory_get_backchannel_launch
|
||||
<SUBSECTION Standard>
|
||||
GstRTSPOnvifMediaFactoryPrivate
|
||||
gst_rtsp_onvif_media_factory_get_type
|
||||
GST_TYPE_RTSP_ONVIF_MEDIA_FACTORY
|
||||
GST_RTSP_ONVIF_MEDIA_FACTORY
|
||||
GST_RTSP_ONVIF_MEDIA_FACTORY_CAST
|
||||
GST_RTSP_ONVIF_MEDIA_FACTORY_CLASS
|
||||
GST_RTSP_ONVIF_MEDIA_FACTORY_CLASS_CAST
|
||||
GST_RTSP_ONVIF_MEDIA_FACTORY_GET_CLASS
|
||||
GST_IS_RTSP_ONVIF_MEDIA_FACTORY
|
||||
GST_IS_RTSP_ONVIF_MEDIA_FACTORY_CLASS
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>rtsp-onvif-media</FILE>
|
||||
<TITLE>GstRTSPOnvifMedia</TITLE>
|
||||
GstRTSPOnvifMedia
|
||||
GstRTSPOnvifMediaClass
|
||||
|
||||
gst_rtsp_onvif_media_collect_backchannel
|
||||
gst_rtsp_onvif_media_get_backchannel_bandwidth
|
||||
gst_rtsp_onvif_media_set_backchannel_bandwidth
|
||||
<SUBSECTION Standard>
|
||||
GstRTSPOnvifMediaPrivate
|
||||
gst_rtsp_onvif_media_get_type
|
||||
GST_TYPE_RTSP_ONVIF_MEDIA
|
||||
GST_RTSP_ONVIF_MEDIA
|
||||
GST_RTSP_ONVIF_MEDIA_CAST
|
||||
GST_RTSP_ONVIF_MEDIA_CLASS
|
||||
GST_RTSP_ONVIF_MEDIA_CLASS_CAST
|
||||
GST_RTSP_ONVIF_MEDIA_GET_CLASS
|
||||
GST_IS_RTSP_ONVIF_MEDIA
|
||||
GST_IS_RTSP_ONVIF_MEDIA_CLASS
|
||||
</SECTION>
|
||||
|
|
1
examples/.gitignore
vendored
1
examples/.gitignore
vendored
|
@ -13,3 +13,4 @@ test-uri
|
|||
test-auth
|
||||
test-netclock
|
||||
test-netclock-client
|
||||
test-onvif-backchannel
|
||||
|
|
|
@ -2,7 +2,8 @@ noinst_PROGRAMS = test-video test-ogg test-mp4 test-readme \
|
|||
test-launch test-sdp test-uri test-auth test-auth-digest \
|
||||
test-multicast test-multicast2 test-appsrc \
|
||||
test-video-rtx test-record test-record-auth \
|
||||
test-netclock test-netclock-client
|
||||
test-netclock test-netclock-client \
|
||||
test-onvif-backchannel
|
||||
|
||||
#INCLUDES = -I$(top_srcdir) -I$(srcdir)
|
||||
|
||||
|
@ -28,3 +29,10 @@ test_netclock_client_LDADD = \
|
|||
$(LDADD) \
|
||||
$(GST_NET_LIBS)
|
||||
|
||||
test_onvif_backchannel_CFLAGS = \
|
||||
$(AM_CFLAGS) \
|
||||
$(GST_PLUGINS_BASE_CFLAGS)
|
||||
test_onvif_backchannel_LDADD = \
|
||||
$(LDADD) \
|
||||
$(GST_PLUGINS_BASE_LIBS) -lgstrtsp-1.0 -lgstsdp-1.0
|
||||
|
||||
|
|
71
examples/test-onvif-backchannel.c
Normal file
71
examples/test-onvif-backchannel.c
Normal file
|
@ -0,0 +1,71 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) 2017 Sebastian Dröge <sebastian@centricular.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/rtsp-server/rtsp-onvif-server.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
GMainLoop *loop;
|
||||
GstRTSPServer *server;
|
||||
GstRTSPMountPoints *mounts;
|
||||
GstRTSPMediaFactory *factory;
|
||||
|
||||
gst_init (&argc, &argv);
|
||||
|
||||
loop = g_main_loop_new (NULL, FALSE);
|
||||
|
||||
/* create a server instance */
|
||||
server = gst_rtsp_onvif_server_new ();
|
||||
|
||||
/* get the mount points for this server, every server has a default object
|
||||
* that be used to map uri mount points to media factories */
|
||||
mounts = gst_rtsp_server_get_mount_points (server);
|
||||
|
||||
/* make a media factory for a test stream. The default media factory can use
|
||||
* gst-launch syntax to create pipelines.
|
||||
* any launch line works as long as it contains elements named pay%d. Each
|
||||
* element with pay%d names will be a stream */
|
||||
factory = gst_rtsp_onvif_media_factory_new ();
|
||||
gst_rtsp_media_factory_set_launch (factory,
|
||||
"( videotestsrc is-live=true ! x264enc ! rtph264pay name=pay0 pt=96 audiotestsrc is-live=true ! mulawenc ! rtppcmupay name=pay1 )");
|
||||
gst_rtsp_onvif_media_factory_set_backchannel_launch
|
||||
(GST_RTSP_ONVIF_MEDIA_FACTORY (factory),
|
||||
"( capsfilter caps=\"application/x-rtp, media=audio, payload=0, clock-rate=8000, encoding-name=PCMU\" name=depay_backchannel ! rtppcmudepay ! fakesink async=false )");
|
||||
gst_rtsp_media_factory_set_shared (factory, FALSE);
|
||||
gst_rtsp_media_factory_set_media_gtype (factory, GST_TYPE_RTSP_ONVIF_MEDIA);
|
||||
|
||||
/* attach the test factory to the /test url */
|
||||
gst_rtsp_mount_points_add_factory (mounts, "/test", factory);
|
||||
|
||||
/* don't need the ref to the mapper anymore */
|
||||
g_object_unref (mounts);
|
||||
|
||||
/* attach the server to the default maincontext */
|
||||
gst_rtsp_server_attach (server, NULL);
|
||||
|
||||
/* start serving */
|
||||
g_print ("stream ready at rtsp://127.0.0.1:8554/test\n");
|
||||
g_main_loop_run (loop);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -17,7 +17,11 @@ public_headers = \
|
|||
rtsp-session-pool.h \
|
||||
rtsp-token.h \
|
||||
rtsp-client.h \
|
||||
rtsp-server.h
|
||||
rtsp-server.h \
|
||||
rtsp-onvif-server.h \
|
||||
rtsp-onvif-client.h \
|
||||
rtsp-onvif-media-factory.h \
|
||||
rtsp-onvif-media.h
|
||||
|
||||
c_sources = \
|
||||
rtsp-auth.c \
|
||||
|
@ -38,7 +42,11 @@ c_sources = \
|
|||
rtsp-session-pool.c \
|
||||
rtsp-token.c \
|
||||
rtsp-client.c \
|
||||
rtsp-server.c
|
||||
rtsp-server.c \
|
||||
rtsp-onvif-server.c \
|
||||
rtsp-onvif-client.c \
|
||||
rtsp-onvif-media-factory.c \
|
||||
rtsp-onvif-media.c
|
||||
|
||||
noinst_HEADERS =
|
||||
|
||||
|
|
|
@ -332,7 +332,6 @@ gboolean gst_rtsp_media_setup_sdp (GstRTSPMedia * media, Gst
|
|||
GST_EXPORT
|
||||
gboolean gst_rtsp_media_handle_sdp (GstRTSPMedia * media, GstSDPMessage * sdp);
|
||||
|
||||
|
||||
/* creating streams */
|
||||
|
||||
GST_EXPORT
|
||||
|
|
100
gst/rtsp-server/rtsp-onvif-client.c
Normal file
100
gst/rtsp-server/rtsp-onvif-client.c
Normal file
|
@ -0,0 +1,100 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) 2017 Sebastian Dröge <sebastian@centricular.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "rtsp-onvif-client.h"
|
||||
#include "rtsp-onvif-server.h"
|
||||
#include "rtsp-onvif-media-factory.h"
|
||||
|
||||
G_DEFINE_TYPE (GstRTSPOnvifClient, gst_rtsp_onvif_client, GST_TYPE_RTSP_CLIENT);
|
||||
|
||||
static gchar *
|
||||
gst_rtsp_onvif_client_check_requirements (GstRTSPClient * client,
|
||||
GstRTSPContext * ctx, gchar ** requirements)
|
||||
{
|
||||
GstRTSPMountPoints *mount_points = NULL;
|
||||
GstRTSPMediaFactory *factory = NULL;
|
||||
gchar *path = NULL;
|
||||
gboolean has_backchannel = FALSE;
|
||||
GString *unsupported = g_string_new ("");
|
||||
|
||||
while (*requirements) {
|
||||
if (strcmp (*requirements, GST_RTSP_ONVIF_BACKCHANNEL_REQUIREMENT) == 0) {
|
||||
has_backchannel = TRUE;
|
||||
} else {
|
||||
if (unsupported->len)
|
||||
g_string_append (unsupported, ", ");
|
||||
g_string_append (unsupported, *requirements);
|
||||
}
|
||||
requirements++;
|
||||
}
|
||||
|
||||
if (unsupported->len)
|
||||
goto out;
|
||||
|
||||
mount_points = gst_rtsp_client_get_mount_points (client);
|
||||
if (!(path = gst_rtsp_mount_points_make_path (mount_points, ctx->uri)))
|
||||
goto out;
|
||||
|
||||
if (!(factory = gst_rtsp_mount_points_match (mount_points, path, NULL)))
|
||||
goto out;
|
||||
|
||||
if (has_backchannel && !GST_IS_RTSP_ONVIF_MEDIA_FACTORY (factory)) {
|
||||
if (unsupported->len)
|
||||
g_string_append (unsupported, ", ");
|
||||
g_string_append (unsupported, GST_RTSP_ONVIF_BACKCHANNEL_REQUIREMENT);
|
||||
} else if (has_backchannel) {
|
||||
GstRTSPOnvifMediaFactory *onvif_factory =
|
||||
GST_RTSP_ONVIF_MEDIA_FACTORY (factory);
|
||||
|
||||
if (!gst_rtsp_onvif_media_factory_has_backchannel_support (onvif_factory)) {
|
||||
if (unsupported->len)
|
||||
g_string_append (unsupported, ", ");
|
||||
g_string_append (unsupported, GST_RTSP_ONVIF_BACKCHANNEL_REQUIREMENT);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (path)
|
||||
g_free (path);
|
||||
if (factory)
|
||||
g_object_unref (factory);
|
||||
if (mount_points)
|
||||
g_object_unref (mount_points);
|
||||
|
||||
return g_string_free (unsupported, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtsp_onvif_client_class_init (GstRTSPOnvifClientClass * klass)
|
||||
{
|
||||
GstRTSPClientClass *client_klass = (GstRTSPClientClass *) klass;
|
||||
|
||||
client_klass->check_requirements = gst_rtsp_onvif_client_check_requirements;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtsp_onvif_client_init (GstRTSPOnvifClient * client)
|
||||
{
|
||||
}
|
57
gst/rtsp-server/rtsp-onvif-client.h
Normal file
57
gst/rtsp-server/rtsp-onvif-client.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) 2017 Sebastian Dröge <sebastian@centricular.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_RTSP_ONVIF_CLIENT_H__
|
||||
#define __GST_RTSP_ONVIF_CLIENT_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include "rtsp-client.h"
|
||||
|
||||
#define GST_TYPE_RTSP_ONVIF_CLIENT (gst_rtsp_onvif_client_get_type ())
|
||||
#define GST_IS_RTSP_ONVIF_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_RTSP_ONVIF_CLIENT))
|
||||
#define GST_IS_RTSP_ONVIF_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_RTSP_ONVIF_CLIENT))
|
||||
#define GST_RTSP_ONVIF_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_RTSP_ONVIF_CLIENT, GstRTSPOnvifClientClass))
|
||||
#define GST_RTSP_ONVIF_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_RTSP_ONVIF_CLIENT, GstRTSPOnvifClient))
|
||||
#define GST_RTSP_ONVIF_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_RTSP_ONVIF_CLIENT, GstRTSPOnvifClientClass))
|
||||
#define GST_RTSP_ONVIF_CLIENT_CAST(obj) ((GstRTSPOnvifClient*)(obj))
|
||||
#define GST_RTSP_ONVIF_CLIENT_CLASS_CAST(klass) ((GstRTSPOnvifClientClass*)(klass))
|
||||
|
||||
typedef struct GstRTSPOnvifClientClass GstRTSPOnvifClientClass;
|
||||
typedef struct GstRTSPOnvifClient GstRTSPOnvifClient;
|
||||
|
||||
struct GstRTSPOnvifClientClass
|
||||
{
|
||||
GstRTSPClientClass parent;
|
||||
|
||||
/*< private >*/
|
||||
gpointer _gst_reserved[GST_PADDING_LARGE];
|
||||
};
|
||||
|
||||
struct GstRTSPOnvifClient
|
||||
{
|
||||
GstRTSPClient parent;
|
||||
|
||||
/*< private >*/
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
GST_EXPORT
|
||||
GType gst_rtsp_onvif_client_get_type (void);
|
||||
|
||||
#endif /* __GST_RTSP_ONVIF_CLIENT_H__ */
|
491
gst/rtsp-server/rtsp-onvif-media-factory.c
Normal file
491
gst/rtsp-server/rtsp-onvif-media-factory.c
Normal file
|
@ -0,0 +1,491 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) 2017 Sebastian Dröge <sebastian@centricular.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:rtsp-onvif-media-factory
|
||||
* @short_description: A factory for ONVIF media pipelines
|
||||
* @see_also: #GstRTSPMediaFactory, #GstRTSPOnvifMedia
|
||||
*
|
||||
* The #GstRTSPOnvifMediaFactory is responsible for creating or recycling
|
||||
* #GstRTSPMedia objects based on the passed URL. Different to
|
||||
* #GstRTSPMediaFactory, this supports special ONVIF features and can create
|
||||
* #GstRTSPOnvifMedia in addition to normal #GstRTSPMedia.
|
||||
*
|
||||
* Special ONVIF features that are currently supported is a backchannel for
|
||||
* the client to send back media to the server in a normal PLAY media, see
|
||||
* gst_rtsp_onvif_media_factory_set_backchannel_launch() and
|
||||
* gst_rtsp_onvif_media_factory_set_backchannel_bandwidth().
|
||||
*
|
||||
* Since: 1.14
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "rtsp-onvif-media-factory.h"
|
||||
#include "rtsp-onvif-media.h"
|
||||
#include "rtsp-onvif-server.h"
|
||||
|
||||
struct GstRTSPOnvifMediaFactoryPrivate
|
||||
{
|
||||
GMutex lock;
|
||||
gchar *backchannel_launch;
|
||||
guint backchannel_bandwidth;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GstRTSPOnvifMediaFactory,
|
||||
gst_rtsp_onvif_media_factory, GST_TYPE_RTSP_MEDIA_FACTORY);
|
||||
|
||||
static gboolean
|
||||
requires_backchannel (GstRTSPMessage * msg)
|
||||
{
|
||||
GstRTSPResult res;
|
||||
gint i;
|
||||
gchar *reqs = NULL;
|
||||
|
||||
i = 0;
|
||||
do {
|
||||
res = gst_rtsp_message_get_header (msg, GST_RTSP_HDR_REQUIRE, &reqs, i++);
|
||||
|
||||
if (res == GST_RTSP_ENOTIMPL)
|
||||
break;
|
||||
|
||||
if (strcmp (reqs, GST_RTSP_ONVIF_BACKCHANNEL_REQUIREMENT) == 0)
|
||||
return TRUE;
|
||||
} while (TRUE);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gchar *
|
||||
gst_rtsp_onvif_media_factory_gen_key (GstRTSPMediaFactory * factory,
|
||||
const GstRTSPUrl * url)
|
||||
{
|
||||
GstRTSPContext *ctx = gst_rtsp_context_get_current ();
|
||||
GstRTSPMessage *msg = ctx->request;
|
||||
|
||||
/* Only medias where no backchannel was requested can be shared */
|
||||
if (requires_backchannel (msg))
|
||||
return NULL;
|
||||
|
||||
return
|
||||
GST_RTSP_MEDIA_FACTORY_CLASS
|
||||
(gst_rtsp_onvif_media_factory_parent_class)->gen_key (factory, url);
|
||||
}
|
||||
|
||||
static GstRTSPMedia *
|
||||
gst_rtsp_onvif_media_factory_construct (GstRTSPMediaFactory * factory,
|
||||
const GstRTSPUrl * url)
|
||||
{
|
||||
GstRTSPMedia *media;
|
||||
GstElement *element, *pipeline;
|
||||
GstRTSPMediaFactoryClass *klass;
|
||||
GType media_gtype;
|
||||
gboolean got_backchannel_stream;
|
||||
GstRTSPContext *ctx = gst_rtsp_context_get_current ();
|
||||
|
||||
/* Mostly a copy of the default implementation but with backchannel support below,
|
||||
* unfortunately we can't re-use the default one because of how the virtual
|
||||
* method is define */
|
||||
|
||||
/* Everything but play is unsupported */
|
||||
if (gst_rtsp_media_factory_get_transport_mode (factory) !=
|
||||
GST_RTSP_TRANSPORT_MODE_PLAY)
|
||||
return NULL;
|
||||
|
||||
/* we only support onvif media here: otherwise a plain GstRTSPMediaFactory
|
||||
* could've been used as well */
|
||||
media_gtype = gst_rtsp_media_factory_get_media_gtype (factory);
|
||||
if (!g_type_is_a (media_gtype, GST_TYPE_RTSP_ONVIF_MEDIA))
|
||||
return NULL;
|
||||
|
||||
klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS (factory);
|
||||
|
||||
if (!klass->create_pipeline)
|
||||
goto no_create;
|
||||
|
||||
element = gst_rtsp_media_factory_create_element (factory, url);
|
||||
if (element == NULL)
|
||||
goto no_element;
|
||||
|
||||
/* create a new empty media */
|
||||
media =
|
||||
g_object_new (media_gtype, "element", element,
|
||||
"transport-mode", GST_RTSP_TRANSPORT_MODE_PLAY, NULL);
|
||||
|
||||
/* this adds the non-backchannel streams */
|
||||
gst_rtsp_media_collect_streams (media);
|
||||
|
||||
/* this adds the backchannel stream */
|
||||
got_backchannel_stream =
|
||||
gst_rtsp_onvif_media_collect_backchannel (GST_RTSP_ONVIF_MEDIA (media));
|
||||
/* FIXME: This should not happen! We checked for that before */
|
||||
if (requires_backchannel (ctx->request) && !got_backchannel_stream) {
|
||||
g_object_unref (media);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pipeline = klass->create_pipeline (factory, media);
|
||||
if (pipeline == NULL)
|
||||
goto no_pipeline;
|
||||
|
||||
gst_rtsp_onvif_media_set_backchannel_bandwidth (GST_RTSP_ONVIF_MEDIA (media),
|
||||
GST_RTSP_ONVIF_MEDIA_FACTORY (factory)->priv->backchannel_bandwidth);
|
||||
|
||||
return media;
|
||||
|
||||
/* ERRORS */
|
||||
no_create:
|
||||
{
|
||||
g_critical ("no create_pipeline function");
|
||||
return NULL;
|
||||
}
|
||||
no_element:
|
||||
{
|
||||
g_critical ("could not create element");
|
||||
return NULL;
|
||||
}
|
||||
no_pipeline:
|
||||
{
|
||||
g_critical ("can't create pipeline");
|
||||
g_object_unref (media);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static GstElement *
|
||||
gst_rtsp_onvif_media_factory_create_element (GstRTSPMediaFactory * factory,
|
||||
const GstRTSPUrl * url)
|
||||
{
|
||||
GstElement *element;
|
||||
GError *error = NULL;
|
||||
gchar *launch;
|
||||
GstRTSPContext *ctx = gst_rtsp_context_get_current ();
|
||||
|
||||
/* Mostly a copy of the default implementation but with backchannel support below,
|
||||
* unfortunately we can't re-use the default one because of how the virtual
|
||||
* method is define */
|
||||
|
||||
launch = gst_rtsp_media_factory_get_launch (factory);
|
||||
|
||||
/* we need a parse syntax */
|
||||
if (launch == NULL)
|
||||
goto no_launch;
|
||||
|
||||
/* parse the user provided launch line */
|
||||
element =
|
||||
gst_parse_launch_full (launch, NULL, GST_PARSE_FLAG_PLACE_IN_BIN, &error);
|
||||
if (element == NULL)
|
||||
goto parse_error;
|
||||
|
||||
g_free (launch);
|
||||
|
||||
if (error != NULL) {
|
||||
/* a recoverable error was encountered */
|
||||
GST_WARNING ("recoverable parsing error: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
/* add backchannel pipeline part, if requested */
|
||||
if (requires_backchannel (ctx->request)) {
|
||||
GstRTSPOnvifMediaFactory *onvif_factory =
|
||||
GST_RTSP_ONVIF_MEDIA_FACTORY (factory);
|
||||
GstElement *backchannel_bin;
|
||||
GstElement *backchannel_depay;
|
||||
GstPad *depay_pad, *depay_ghostpad;
|
||||
|
||||
launch =
|
||||
gst_rtsp_onvif_media_factory_get_backchannel_launch (onvif_factory);
|
||||
if (launch == NULL)
|
||||
goto no_launch_backchannel;
|
||||
|
||||
backchannel_bin =
|
||||
gst_parse_bin_from_description_full (launch, FALSE, NULL,
|
||||
GST_PARSE_FLAG_PLACE_IN_BIN, &error);
|
||||
if (backchannel_bin == NULL)
|
||||
goto parse_error_backchannel;
|
||||
|
||||
g_free (launch);
|
||||
|
||||
if (error != NULL) {
|
||||
/* a recoverable error was encountered */
|
||||
GST_WARNING ("recoverable parsing error: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
gst_object_set_name (GST_OBJECT (backchannel_bin), "onvif-backchannel");
|
||||
|
||||
backchannel_depay =
|
||||
gst_bin_get_by_name (GST_BIN (backchannel_bin), "depay_backchannel");
|
||||
if (!backchannel_depay) {
|
||||
gst_object_unref (backchannel_bin);
|
||||
goto wrongly_formatted_backchannel_bin;
|
||||
}
|
||||
|
||||
depay_pad = gst_element_get_static_pad (backchannel_depay, "sink");
|
||||
if (!depay_pad) {
|
||||
gst_object_unref (backchannel_depay);
|
||||
gst_object_unref (backchannel_bin);
|
||||
goto wrongly_formatted_backchannel_bin;
|
||||
}
|
||||
|
||||
depay_ghostpad = gst_ghost_pad_new ("sink", depay_pad);
|
||||
gst_element_add_pad (backchannel_bin, depay_ghostpad);
|
||||
|
||||
gst_bin_add (GST_BIN (element), backchannel_bin);
|
||||
}
|
||||
|
||||
return element;
|
||||
|
||||
/* ERRORS */
|
||||
no_launch:
|
||||
{
|
||||
g_critical ("no launch line specified");
|
||||
g_free (launch);
|
||||
return NULL;
|
||||
}
|
||||
parse_error:
|
||||
{
|
||||
g_critical ("could not parse launch syntax (%s): %s", launch,
|
||||
(error ? error->message : "unknown reason"));
|
||||
if (error)
|
||||
g_error_free (error);
|
||||
g_free (launch);
|
||||
return NULL;
|
||||
}
|
||||
no_launch_backchannel:
|
||||
{
|
||||
g_critical ("no backchannel launch line specified");
|
||||
gst_object_unref (element);
|
||||
return NULL;
|
||||
}
|
||||
parse_error_backchannel:
|
||||
{
|
||||
g_critical ("could not parse backchannel launch syntax (%s): %s", launch,
|
||||
(error ? error->message : "unknown reason"));
|
||||
if (error)
|
||||
g_error_free (error);
|
||||
g_free (launch);
|
||||
gst_object_unref (element);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wrongly_formatted_backchannel_bin:
|
||||
{
|
||||
g_critical ("invalidly formatted backchannel bin");
|
||||
|
||||
gst_object_unref (element);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_rtsp_onvif_media_factory_has_backchannel_support_default
|
||||
(GstRTSPOnvifMediaFactory * factory)
|
||||
{
|
||||
/* No locking here, we just check if it's non-NULL */
|
||||
return factory->priv->backchannel_launch != NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtsp_onvif_media_factory_finalize (GObject * object)
|
||||
{
|
||||
GstRTSPOnvifMediaFactory *factory = GST_RTSP_ONVIF_MEDIA_FACTORY (object);
|
||||
|
||||
g_free (factory->priv->backchannel_launch);
|
||||
factory->priv->backchannel_launch = NULL;
|
||||
|
||||
g_mutex_clear (&factory->priv->lock);
|
||||
|
||||
return
|
||||
G_OBJECT_CLASS (gst_rtsp_onvif_media_factory_parent_class)->finalize
|
||||
(object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtsp_onvif_media_factory_class_init (GstRTSPOnvifMediaFactoryClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
GstRTSPMediaFactoryClass *factory_klass = (GstRTSPMediaFactoryClass *) klass;
|
||||
|
||||
gobject_class->finalize = gst_rtsp_onvif_media_factory_finalize;
|
||||
|
||||
factory_klass->gen_key = gst_rtsp_onvif_media_factory_gen_key;
|
||||
factory_klass->construct = gst_rtsp_onvif_media_factory_construct;
|
||||
factory_klass->create_element = gst_rtsp_onvif_media_factory_create_element;
|
||||
|
||||
klass->has_backchannel_support =
|
||||
gst_rtsp_onvif_media_factory_has_backchannel_support_default;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtsp_onvif_media_factory_init (GstRTSPOnvifMediaFactory * factory)
|
||||
{
|
||||
factory->priv = gst_rtsp_onvif_media_factory_get_instance_private (factory);
|
||||
g_mutex_init (&factory->priv->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_onvif_media_factory_set_backchannel_launch:
|
||||
* @factory: a #GstRTSPMediaFactory
|
||||
* @launch: the launch description
|
||||
*
|
||||
* The gst_parse_launch() line to use for constructing the ONVIF backchannel
|
||||
* pipeline in the default prepare vmethod if requested by the client.
|
||||
*
|
||||
* The pipeline description should return a GstBin as the toplevel element
|
||||
* which can be accomplished by enclosing the description with brackets '('
|
||||
* ')'.
|
||||
*
|
||||
* The description should return a pipeline with a single depayloader named
|
||||
* depay_backchannel. A caps query on the depayloader's sinkpad should return
|
||||
* all possible, complete RTP caps that are going to be supported. At least
|
||||
* the payload type, clock-rate and encoding-name need to be specified.
|
||||
*
|
||||
* Since: 1.14
|
||||
*/
|
||||
void
|
||||
gst_rtsp_onvif_media_factory_set_backchannel_launch (GstRTSPOnvifMediaFactory *
|
||||
factory, const gchar * launch)
|
||||
{
|
||||
g_return_if_fail (GST_IS_RTSP_ONVIF_MEDIA_FACTORY (factory));
|
||||
|
||||
g_mutex_lock (&factory->priv->lock);
|
||||
g_free (factory->priv->backchannel_launch);
|
||||
factory->priv->backchannel_launch = g_strdup (launch);
|
||||
g_mutex_unlock (&factory->priv->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_onvif_media_factory_get_backchannel_launch:
|
||||
* @factory: a #GstRTSPMediaFactory
|
||||
*
|
||||
* Get the gst_parse_launch() pipeline description that will be used in the
|
||||
* default prepare vmethod for generating the ONVIF backchannel pipeline.
|
||||
*
|
||||
* Returns: (transfer full): the configured backchannel launch description. g_free() after
|
||||
* usage.
|
||||
*
|
||||
* Since: 1.14
|
||||
*/
|
||||
gchar *
|
||||
gst_rtsp_onvif_media_factory_get_backchannel_launch (GstRTSPOnvifMediaFactory *
|
||||
factory)
|
||||
{
|
||||
gchar *launch;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_ONVIF_MEDIA_FACTORY (factory), NULL);
|
||||
|
||||
g_mutex_lock (&factory->priv->lock);
|
||||
launch = g_strdup (factory->priv->backchannel_launch);
|
||||
g_mutex_unlock (&factory->priv->lock);
|
||||
|
||||
return launch;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_onvif_media_factory_has_backchannel_support:
|
||||
* @factory: a #GstRTSPMediaFactory
|
||||
*
|
||||
* Returns %TRUE if an ONVIF backchannel is supported by the media factory.
|
||||
*
|
||||
* Returns: %TRUE if an ONVIF backchannel is supported by the media factory.
|
||||
*
|
||||
* Since: 1.14
|
||||
*/
|
||||
gboolean
|
||||
gst_rtsp_onvif_media_factory_has_backchannel_support (GstRTSPOnvifMediaFactory *
|
||||
factory)
|
||||
{
|
||||
GstRTSPOnvifMediaFactoryClass *klass;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_ONVIF_MEDIA_FACTORY (factory), FALSE);
|
||||
|
||||
klass = GST_RTSP_ONVIF_MEDIA_FACTORY_GET_CLASS (factory);
|
||||
|
||||
if (klass->has_backchannel_support)
|
||||
return klass->has_backchannel_support (factory);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_onvif_media_factory_set_backchannel_bandwidth:
|
||||
* @factory: a #GstRTSPMediaFactory
|
||||
* @bandwidth: the bandwidth in bits per second
|
||||
*
|
||||
* Set the configured/supported bandwidth of the ONVIF backchannel pipeline in
|
||||
* bits per second.
|
||||
*
|
||||
* Since: 1.14
|
||||
*/
|
||||
void
|
||||
gst_rtsp_onvif_media_factory_set_backchannel_bandwidth (GstRTSPOnvifMediaFactory
|
||||
* factory, guint bandwidth)
|
||||
{
|
||||
g_return_if_fail (GST_IS_RTSP_ONVIF_MEDIA_FACTORY (factory));
|
||||
|
||||
g_mutex_lock (&factory->priv->lock);
|
||||
factory->priv->backchannel_bandwidth = bandwidth;
|
||||
g_mutex_unlock (&factory->priv->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_onvif_media_factory_get_backchannel_bandwidth:
|
||||
* @factory: a #GstRTSPMediaFactory
|
||||
*
|
||||
* Get the configured/supported bandwidth of the ONVIF backchannel pipeline in
|
||||
* bits per second.
|
||||
*
|
||||
* Returns: the configured/supported backchannel bandwidth.
|
||||
*
|
||||
* Since: 1.14
|
||||
*/
|
||||
guint
|
||||
gst_rtsp_onvif_media_factory_get_backchannel_bandwidth (GstRTSPOnvifMediaFactory
|
||||
* factory)
|
||||
{
|
||||
guint bandwidth;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_ONVIF_MEDIA_FACTORY (factory), 0);
|
||||
|
||||
g_mutex_lock (&factory->priv->lock);
|
||||
bandwidth = factory->priv->backchannel_bandwidth;
|
||||
g_mutex_unlock (&factory->priv->lock);
|
||||
|
||||
return bandwidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_onvif_media_factory_new:
|
||||
*
|
||||
* Create a new #GstRTSPOnvifMediaFactory
|
||||
*
|
||||
* Returns: A new #GstRTSPOnvifMediaFactory
|
||||
*
|
||||
* Since: 1.14
|
||||
*/
|
||||
GstRTSPMediaFactory *
|
||||
gst_rtsp_onvif_media_factory_new (void)
|
||||
{
|
||||
return g_object_new (GST_TYPE_RTSP_ONVIF_MEDIA_FACTORY, NULL);
|
||||
}
|
77
gst/rtsp-server/rtsp-onvif-media-factory.h
Normal file
77
gst/rtsp-server/rtsp-onvif-media-factory.h
Normal file
|
@ -0,0 +1,77 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) 2017 Sebastian Dröge <sebastian@centricular.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_RTSP_ONVIF_MEDIA_FACTORY_H__
|
||||
#define __GST_RTSP_ONVIF_MEDIA_FACTORY_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include "rtsp-media-factory.h"
|
||||
|
||||
#define GST_TYPE_RTSP_ONVIF_MEDIA_FACTORY (gst_rtsp_onvif_media_factory_get_type ())
|
||||
#define GST_IS_RTSP_ONVIF_MEDIA_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_RTSP_ONVIF_MEDIA_FACTORY))
|
||||
#define GST_IS_RTSP_ONVIF_MEDIA_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_RTSP_ONVIF_MEDIA_FACTORY))
|
||||
#define GST_RTSP_ONVIF_MEDIA_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_RTSP_ONVIF_MEDIA_FACTORY, GstRTSPOnvifMediaFactoryClass))
|
||||
#define GST_RTSP_ONVIF_MEDIA_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_RTSP_ONVIF_MEDIA_FACTORY, GstRTSPOnvifMediaFactory))
|
||||
#define GST_RTSP_ONVIF_MEDIA_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_RTSP_ONVIF_MEDIA_FACTORY, GstRTSPOnvifMediaFactoryClass))
|
||||
#define GST_RTSP_ONVIF_MEDIA_FACTORY_CAST(obj) ((GstRTSPOnvifMediaFactory*)(obj))
|
||||
#define GST_RTSP_ONVIF_MEDIA_FACTORY_CLASS_CAST(klass) ((GstRTSPOnvifMediaFactoryClass*)(klass))
|
||||
|
||||
typedef struct GstRTSPOnvifMediaFactoryClass GstRTSPOnvifMediaFactoryClass;
|
||||
typedef struct GstRTSPOnvifMediaFactory GstRTSPOnvifMediaFactory;
|
||||
typedef struct GstRTSPOnvifMediaFactoryPrivate GstRTSPOnvifMediaFactoryPrivate;
|
||||
|
||||
struct GstRTSPOnvifMediaFactoryClass
|
||||
{
|
||||
GstRTSPMediaFactoryClass parent;
|
||||
gboolean (*has_backchannel_support) (GstRTSPOnvifMediaFactory * factory);
|
||||
|
||||
/*< private >*/
|
||||
gpointer _gst_reserved[GST_PADDING_LARGE];
|
||||
};
|
||||
|
||||
struct GstRTSPOnvifMediaFactory
|
||||
{
|
||||
GstRTSPMediaFactory parent;
|
||||
GstRTSPOnvifMediaFactoryPrivate *priv;
|
||||
|
||||
/*< private >*/
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
GST_EXPORT
|
||||
GType gst_rtsp_onvif_media_factory_get_type (void);
|
||||
|
||||
GST_EXPORT
|
||||
GstRTSPMediaFactory *gst_rtsp_onvif_media_factory_new (void);
|
||||
|
||||
GST_EXPORT
|
||||
void gst_rtsp_onvif_media_factory_set_backchannel_launch (GstRTSPOnvifMediaFactory *
|
||||
factory, const gchar * launch);
|
||||
GST_EXPORT
|
||||
gchar * gst_rtsp_onvif_media_factory_get_backchannel_launch (GstRTSPOnvifMediaFactory * factory);
|
||||
|
||||
GST_EXPORT
|
||||
gboolean gst_rtsp_onvif_media_factory_has_backchannel_support (GstRTSPOnvifMediaFactory * factory);
|
||||
|
||||
GST_EXPORT
|
||||
void gst_rtsp_onvif_media_factory_set_backchannel_bandwidth (GstRTSPOnvifMediaFactory * factory, guint bandwidth);
|
||||
GST_EXPORT
|
||||
guint gst_rtsp_onvif_media_factory_get_backchannel_bandwidth (GstRTSPOnvifMediaFactory * factory);
|
||||
|
||||
#endif /* __GST_RTSP_ONVIF_MEDIA_FACTORY_H__ */
|
330
gst/rtsp-server/rtsp-onvif-media.c
Normal file
330
gst/rtsp-server/rtsp-onvif-media.c
Normal file
|
@ -0,0 +1,330 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) 2017 Sebastian Dröge <sebastian@centricular.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:rtsp-onvif-media
|
||||
* @short_description: The ONVIF media pipeline
|
||||
* @see_also: #GstRTSPMedia, #GstRTSPOnvifMediaFactory, #GstRTSPStream, #GstRTSPSession,
|
||||
* #GstRTSPSessionMedia
|
||||
*
|
||||
* a #GstRTSPOnvifMedia contains the complete GStreamer pipeline to manage the
|
||||
* streaming to the clients. The actual data transfer is done by the
|
||||
* #GstRTSPStream objects that are created and exposed by the #GstRTSPMedia.
|
||||
*
|
||||
* On top of #GstRTSPMedia this subclass adds special ONVIF features.
|
||||
* Special ONVIF features that are currently supported is a backchannel for
|
||||
* the client to send back media to the server in a normal PLAY media. To
|
||||
* handle the ONVIF backchannel, a #GstRTSPOnvifMediaFactory and
|
||||
* #GstRTSPOnvifServer has to be used.
|
||||
*
|
||||
* Since: 1.14
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "rtsp-onvif-media.h"
|
||||
|
||||
struct GstRTSPOnvifMediaPrivate
|
||||
{
|
||||
GMutex lock;
|
||||
guint backchannel_bandwidth;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GstRTSPOnvifMedia, gst_rtsp_onvif_media,
|
||||
GST_TYPE_RTSP_MEDIA);
|
||||
|
||||
static gboolean
|
||||
gst_rtsp_onvif_media_setup_sdp (GstRTSPMedia * media, GstSDPMessage * sdp,
|
||||
GstSDPInfo * info)
|
||||
{
|
||||
guint i, n_streams;
|
||||
gchar *rangestr;
|
||||
gboolean res;
|
||||
|
||||
/* Mostly a copy of gst_rtsp_sdp_from_media() which handles the backchannel
|
||||
* stream separately and adds sendonly/recvonly attributes to each media
|
||||
*/
|
||||
|
||||
n_streams = gst_rtsp_media_n_streams (media);
|
||||
|
||||
rangestr = gst_rtsp_media_get_range_string (media, FALSE, GST_RTSP_RANGE_NPT);
|
||||
if (rangestr == NULL)
|
||||
goto not_prepared;
|
||||
|
||||
gst_sdp_message_add_attribute (sdp, "range", rangestr);
|
||||
g_free (rangestr);
|
||||
|
||||
res = TRUE;
|
||||
for (i = 0; res && (i < n_streams); i++) {
|
||||
GstRTSPStream *stream;
|
||||
GstCaps *caps = NULL;
|
||||
GstRTSPProfile profiles;
|
||||
guint mask;
|
||||
gboolean res;
|
||||
GstPad *sinkpad = NULL;
|
||||
guint n_caps, j;
|
||||
|
||||
/* Mostly a copy of gst_rtsp_sdp_from_stream() which handles the
|
||||
* backchannel stream separately */
|
||||
|
||||
stream = gst_rtsp_media_get_stream (media, i);
|
||||
|
||||
if ((sinkpad = gst_rtsp_stream_get_sinkpad (stream))) {
|
||||
caps = gst_pad_query_caps (sinkpad, NULL);
|
||||
} else {
|
||||
caps = gst_rtsp_stream_get_caps (stream);
|
||||
}
|
||||
|
||||
if (caps == NULL) {
|
||||
GST_ERROR ("stream %p has no caps", stream);
|
||||
res = FALSE;
|
||||
if (sinkpad)
|
||||
gst_object_unref (sinkpad);
|
||||
break;
|
||||
} else if (!sinkpad && !gst_caps_is_fixed (caps)) {
|
||||
GST_ERROR ("stream %p has unfixed caps", stream);
|
||||
res = FALSE;
|
||||
gst_caps_unref (caps);
|
||||
break;
|
||||
}
|
||||
|
||||
n_caps = gst_caps_get_size (caps);
|
||||
for (j = 0; res && j < n_caps; j++) {
|
||||
GstStructure *s = gst_caps_get_structure (caps, j);
|
||||
GstCaps *media_caps = gst_caps_new_full (gst_structure_copy (s), NULL);
|
||||
|
||||
if (!gst_caps_is_fixed (media_caps)) {
|
||||
GST_ERROR ("media caps for stream %p are not all fixed", stream);
|
||||
res = FALSE;
|
||||
gst_caps_unref (media_caps);
|
||||
break;
|
||||
}
|
||||
|
||||
/* make a new media for each profile */
|
||||
profiles = gst_rtsp_stream_get_profiles (stream);
|
||||
mask = 1;
|
||||
res = TRUE;
|
||||
while (res && (profiles >= mask)) {
|
||||
GstRTSPProfile prof = profiles & mask;
|
||||
|
||||
if (prof) {
|
||||
res = gst_rtsp_sdp_make_media (sdp, info, stream, media_caps, prof);
|
||||
if (res) {
|
||||
GstSDPMedia *smedia =
|
||||
&g_array_index (sdp->medias, GstSDPMedia, sdp->medias->len - 1);
|
||||
|
||||
if (sinkpad) {
|
||||
GstRTSPOnvifMedia *onvif_media = GST_RTSP_ONVIF_MEDIA (media);
|
||||
|
||||
gst_sdp_media_add_attribute (smedia, "sendonly", "");
|
||||
if (onvif_media->priv->backchannel_bandwidth > 0)
|
||||
gst_sdp_media_add_bandwidth (smedia, GST_SDP_BWTYPE_AS,
|
||||
onvif_media->priv->backchannel_bandwidth);
|
||||
} else {
|
||||
gst_sdp_media_add_attribute (smedia, "recvonly", "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mask <<= 1;
|
||||
}
|
||||
|
||||
if (sinkpad) {
|
||||
GstStructure *s = gst_caps_get_structure (media_caps, 0);
|
||||
gint pt = -1;
|
||||
|
||||
if (!gst_structure_get_int (s, "payload", &pt) || pt < 0) {
|
||||
GST_ERROR ("stream %p has no payload type", stream);
|
||||
res = FALSE;
|
||||
gst_caps_unref (media_caps);
|
||||
gst_object_unref (sinkpad);
|
||||
break;
|
||||
}
|
||||
|
||||
gst_rtsp_stream_set_pt_map (stream, pt, media_caps);
|
||||
}
|
||||
|
||||
gst_caps_unref (media_caps);
|
||||
}
|
||||
|
||||
gst_caps_unref (caps);
|
||||
if (sinkpad)
|
||||
gst_object_unref (sinkpad);
|
||||
}
|
||||
|
||||
{
|
||||
GstNetTimeProvider *provider;
|
||||
|
||||
if ((provider =
|
||||
gst_rtsp_media_get_time_provider (media, info->server_ip, 0))) {
|
||||
GstClock *clock;
|
||||
gchar *address, *str;
|
||||
gint port;
|
||||
|
||||
g_object_get (provider, "clock", &clock, "address", &address, "port",
|
||||
&port, NULL);
|
||||
|
||||
str = g_strdup_printf ("GstNetTimeProvider %s %s:%d %" G_GUINT64_FORMAT,
|
||||
g_type_name (G_TYPE_FROM_INSTANCE (clock)), address, port,
|
||||
gst_clock_get_time (clock));
|
||||
|
||||
gst_sdp_message_add_attribute (sdp, "x-gst-clock", str);
|
||||
g_free (str);
|
||||
gst_object_unref (clock);
|
||||
g_free (address);
|
||||
gst_object_unref (provider);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
|
||||
/* ERRORS */
|
||||
not_prepared:
|
||||
{
|
||||
GST_ERROR ("media %p is not prepared", media);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtsp_onvif_media_finalize (GObject * object)
|
||||
{
|
||||
GstRTSPOnvifMedia *media = GST_RTSP_ONVIF_MEDIA (object);
|
||||
|
||||
g_mutex_clear (&media->priv->lock);
|
||||
|
||||
return G_OBJECT_CLASS (gst_rtsp_onvif_media_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtsp_onvif_media_class_init (GstRTSPOnvifMediaClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
GstRTSPMediaClass *media_class = (GstRTSPMediaClass *) klass;
|
||||
|
||||
gobject_class->finalize = gst_rtsp_onvif_media_finalize;
|
||||
|
||||
media_class->setup_sdp = gst_rtsp_onvif_media_setup_sdp;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtsp_onvif_media_init (GstRTSPOnvifMedia * media)
|
||||
{
|
||||
media->priv = gst_rtsp_onvif_media_get_instance_private (media);
|
||||
g_mutex_init (&media->priv->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_onvif_media_collect_backchannel:
|
||||
* @media: a #GstRTSPOnvifMedia
|
||||
*
|
||||
* Find the ONVIF backchannel depayloader element. It should be named
|
||||
* 'depay_backchannel', be placed in a bin called 'onvif-backchannel'
|
||||
* and return all supported RTP caps on a caps query. Complete RTP caps with
|
||||
* at least the payload type, clock-rate and encoding-name are required.
|
||||
*
|
||||
* A new #GstRTSPStream is created for the backchannel if found.
|
||||
*
|
||||
* Returns: %TRUE if a backchannel stream could be found and created
|
||||
*
|
||||
* Since: 1.14
|
||||
*/
|
||||
gboolean
|
||||
gst_rtsp_onvif_media_collect_backchannel (GstRTSPOnvifMedia * media)
|
||||
{
|
||||
GstElement *element, *backchannel_bin = NULL;
|
||||
GstPad *pad = NULL;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_ONVIF_MEDIA (media), FALSE);
|
||||
|
||||
element = gst_rtsp_media_get_element (GST_RTSP_MEDIA (media));
|
||||
if (!element)
|
||||
return ret;
|
||||
|
||||
backchannel_bin =
|
||||
gst_bin_get_by_name (GST_BIN (element), "onvif-backchannel");
|
||||
if (!backchannel_bin)
|
||||
goto out;
|
||||
|
||||
pad = gst_element_get_static_pad (backchannel_bin, "sink");
|
||||
if (!pad)
|
||||
goto out;
|
||||
|
||||
gst_rtsp_media_create_stream (GST_RTSP_MEDIA (media), backchannel_bin, pad);
|
||||
ret = TRUE;
|
||||
|
||||
out:
|
||||
if (pad)
|
||||
gst_object_unref (pad);
|
||||
if (backchannel_bin)
|
||||
gst_object_unref (backchannel_bin);
|
||||
gst_object_unref (element);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_onvif_media_set_backchannel_bandwidth:
|
||||
* @factory: a #GstRTSPMedia
|
||||
* @bandwidth: the bandwidth in bits per second
|
||||
*
|
||||
* Set the configured/supported bandwidth of the ONVIF backchannel pipeline in
|
||||
* bits per second.
|
||||
*
|
||||
* Since: 1.14
|
||||
*/
|
||||
void
|
||||
gst_rtsp_onvif_media_set_backchannel_bandwidth (GstRTSPOnvifMedia * media,
|
||||
guint bandwidth)
|
||||
{
|
||||
g_return_if_fail (GST_IS_RTSP_ONVIF_MEDIA (media));
|
||||
|
||||
g_mutex_lock (&media->priv->lock);
|
||||
media->priv->backchannel_bandwidth = bandwidth;
|
||||
g_mutex_unlock (&media->priv->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_onvif_media_get_backchannel_bandwidth:
|
||||
* @factory: a #GstRTSPMedia
|
||||
*
|
||||
* Get the configured/supported bandwidth of the ONVIF backchannel pipeline in
|
||||
* bits per second.
|
||||
*
|
||||
* Returns: the configured/supported backchannel bandwidth.
|
||||
*
|
||||
* Since: 1.14
|
||||
*/
|
||||
guint
|
||||
gst_rtsp_onvif_media_get_backchannel_bandwidth (GstRTSPOnvifMedia * media)
|
||||
{
|
||||
guint bandwidth;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTSP_ONVIF_MEDIA (media), 0);
|
||||
|
||||
g_mutex_lock (&media->priv->lock);
|
||||
bandwidth = media->priv->backchannel_bandwidth;
|
||||
g_mutex_unlock (&media->priv->lock);
|
||||
|
||||
return bandwidth;
|
||||
}
|
66
gst/rtsp-server/rtsp-onvif-media.h
Normal file
66
gst/rtsp-server/rtsp-onvif-media.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) 2017 Sebastian Dröge <sebastian@centricular.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_RTSP_ONVIF_MEDIA_H__
|
||||
#define __GST_RTSP_ONVIF_MEDIA_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include "rtsp-media.h"
|
||||
|
||||
#define GST_TYPE_RTSP_ONVIF_MEDIA (gst_rtsp_onvif_media_get_type ())
|
||||
#define GST_IS_RTSP_ONVIF_MEDIA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_RTSP_ONVIF_MEDIA))
|
||||
#define GST_IS_RTSP_ONVIF_MEDIA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_RTSP_ONVIF_MEDIA))
|
||||
#define GST_RTSP_ONVIF_MEDIA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_RTSP_ONVIF_MEDIA, GstRTSPOnvifMediaClass))
|
||||
#define GST_RTSP_ONVIF_MEDIA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_RTSP_ONVIF_MEDIA, GstRTSPOnvifMedia))
|
||||
#define GST_RTSP_ONVIF_MEDIA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_RTSP_ONVIF_MEDIA, GstRTSPOnvifMediaClass))
|
||||
#define GST_RTSP_ONVIF_MEDIA_CAST(obj) ((GstRTSPOnvifMedia*)(obj))
|
||||
#define GST_RTSP_ONVIF_MEDIA_CLASS_CAST(klass) ((GstRTSPOnvifMediaClass*)(klass))
|
||||
|
||||
typedef struct GstRTSPOnvifMediaClass GstRTSPOnvifMediaClass;
|
||||
typedef struct GstRTSPOnvifMedia GstRTSPOnvifMedia;
|
||||
typedef struct GstRTSPOnvifMediaPrivate GstRTSPOnvifMediaPrivate;
|
||||
|
||||
struct GstRTSPOnvifMediaClass
|
||||
{
|
||||
GstRTSPMediaClass parent;
|
||||
|
||||
/*< private >*/
|
||||
gpointer _gst_reserved[GST_PADDING_LARGE];
|
||||
};
|
||||
|
||||
struct GstRTSPOnvifMedia
|
||||
{
|
||||
GstRTSPMedia parent;
|
||||
GstRTSPOnvifMediaPrivate *priv;
|
||||
|
||||
/*< private >*/
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
GST_EXPORT
|
||||
GType gst_rtsp_onvif_media_get_type (void);
|
||||
GST_EXPORT
|
||||
gboolean gst_rtsp_onvif_media_collect_backchannel (GstRTSPOnvifMedia * media);
|
||||
|
||||
GST_EXPORT
|
||||
void gst_rtsp_onvif_media_set_backchannel_bandwidth (GstRTSPOnvifMedia * media, guint bandwidth);
|
||||
GST_EXPORT
|
||||
guint gst_rtsp_onvif_media_get_backchannel_bandwidth (GstRTSPOnvifMedia * media);
|
||||
|
||||
#endif /* __GST_RTSP_ONVIF_MEDIA_H__ */
|
100
gst/rtsp-server/rtsp-onvif-server.c
Normal file
100
gst/rtsp-server/rtsp-onvif-server.c
Normal file
|
@ -0,0 +1,100 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) 2017 Sebastian Dröge <sebastian@centricular.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
/**
|
||||
* SECTION:rtsp-onvif-server
|
||||
* @short_description: The main server object
|
||||
* @see_also: #GstRTSPOnvifMediaFactory, #GstRTSPClient
|
||||
*
|
||||
* The server object is the object listening for connections on a port and
|
||||
* creating #GstRTSPOnvifClient objects to handle those connections.
|
||||
*
|
||||
* The only different to #GstRTSPServer is that #GstRTSPOnvifServer creates
|
||||
* #GstRTSPOnvifClient that have special handling for ONVIF specific features,
|
||||
* like a backchannel that allows clients to send back media to the server.
|
||||
*
|
||||
* Since: 1.14
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "rtsp-onvif-server.h"
|
||||
#include "rtsp-onvif-client.h"
|
||||
|
||||
G_DEFINE_TYPE (GstRTSPOnvifServer, gst_rtsp_onvif_server, GST_TYPE_RTSP_SERVER);
|
||||
|
||||
static GstRTSPClient *
|
||||
gst_rtsp_onvif_server_create_client (GstRTSPServer * server)
|
||||
{
|
||||
GstRTSPClient *client;
|
||||
GstRTSPSessionPool *session_pool;
|
||||
GstRTSPMountPoints *mount_points;
|
||||
GstRTSPAuth *auth;
|
||||
GstRTSPThreadPool *thread_pool;
|
||||
|
||||
/* a new client connected, create a session to handle the client. */
|
||||
client = g_object_new (GST_TYPE_RTSP_ONVIF_CLIENT, NULL);
|
||||
|
||||
/* set the session pool that this client should use */
|
||||
session_pool = gst_rtsp_server_get_session_pool (server);
|
||||
gst_rtsp_client_set_session_pool (client, session_pool);
|
||||
g_object_unref (session_pool);
|
||||
/* set the mount points that this client should use */
|
||||
mount_points = gst_rtsp_server_get_mount_points (server);
|
||||
gst_rtsp_client_set_mount_points (client, mount_points);
|
||||
g_object_unref (mount_points);
|
||||
/* set authentication manager */
|
||||
auth = gst_rtsp_server_get_auth (server);
|
||||
gst_rtsp_client_set_auth (client, auth);
|
||||
if (auth)
|
||||
g_object_unref (auth);
|
||||
/* set threadpool */
|
||||
thread_pool = gst_rtsp_server_get_thread_pool (server);
|
||||
gst_rtsp_client_set_thread_pool (client, thread_pool);
|
||||
g_object_unref (thread_pool);
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_onvif_server_new:
|
||||
*
|
||||
* Create a new #GstRTSPOnvifServer instance.
|
||||
*
|
||||
* Returns: (transfer full): a new #GstRTSPOnvifServer
|
||||
*/
|
||||
GstRTSPServer *
|
||||
gst_rtsp_onvif_server_new (void)
|
||||
{
|
||||
return g_object_new (GST_TYPE_RTSP_ONVIF_SERVER, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtsp_onvif_server_class_init (GstRTSPOnvifServerClass * klass)
|
||||
{
|
||||
GstRTSPServerClass *server_klass = (GstRTSPServerClass *) klass;
|
||||
|
||||
server_klass->create_client = gst_rtsp_onvif_server_create_client;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtsp_onvif_server_init (GstRTSPOnvifServer * server)
|
||||
{
|
||||
}
|
65
gst/rtsp-server/rtsp-onvif-server.h
Normal file
65
gst/rtsp-server/rtsp-onvif-server.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) 2017 Sebastian Dröge <sebastian@centricular.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_RTSP_ONVIF_SERVER_H__
|
||||
#define __GST_RTSP_ONVIF_SERVER_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include "rtsp-server.h"
|
||||
|
||||
#define GST_TYPE_RTSP_ONVIF_SERVER (gst_rtsp_onvif_server_get_type ())
|
||||
#define GST_IS_RTSP_ONVIF_SERVER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_RTSP_ONVIF_SERVER))
|
||||
#define GST_IS_RTSP_ONVIF_SERVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_RTSP_ONVIF_SERVER))
|
||||
#define GST_RTSP_ONVIF_SERVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_RTSP_ONVIF_SERVER, GstRTSPOnvifServerClass))
|
||||
#define GST_RTSP_ONVIF_SERVER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_RTSP_ONVIF_SERVER, GstRTSPOnvifServer))
|
||||
#define GST_RTSP_ONVIF_SERVER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_RTSP_ONVIF_SERVER, GstRTSPOnvifServerClass))
|
||||
#define GST_RTSP_ONVIF_SERVER_CAST(obj) ((GstRTSPOnvifServer*)(obj))
|
||||
#define GST_RTSP_ONVIF_SERVER_CLASS_CAST(klass) ((GstRTSPOnvifServerClass*)(klass))
|
||||
|
||||
typedef struct GstRTSPOnvifServerClass GstRTSPOnvifServerClass;
|
||||
typedef struct GstRTSPOnvifServer GstRTSPOnvifServer;
|
||||
|
||||
struct GstRTSPOnvifServerClass
|
||||
{
|
||||
GstRTSPServerClass parent;
|
||||
|
||||
/*< private >*/
|
||||
gpointer _gst_reserved[GST_PADDING_LARGE];
|
||||
};
|
||||
|
||||
struct GstRTSPOnvifServer
|
||||
{
|
||||
GstRTSPServer parent;
|
||||
|
||||
/*< private >*/
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
GST_EXPORT
|
||||
GType gst_rtsp_onvif_server_get_type (void);
|
||||
GST_EXPORT
|
||||
GstRTSPServer *gst_rtsp_onvif_server_new (void);
|
||||
|
||||
#define GST_RTSP_ONVIF_BACKCHANNEL_REQUIREMENT "www.onvif.org/ver20/backchannel"
|
||||
|
||||
#include "rtsp-onvif-client.h"
|
||||
#include "rtsp-onvif-media-factory.h"
|
||||
#include "rtsp-onvif-media.h"
|
||||
|
||||
#endif /* __GST_RTSP_ONVIF_SERVER_H__ */
|
|
@ -70,6 +70,8 @@ update_sdp_from_tags (GstRTSPStream * stream, GstSDPMedia * stream_media)
|
|||
GstPad *src_pad;
|
||||
|
||||
src_pad = gst_rtsp_stream_get_srcpad (stream);
|
||||
if (!src_pad)
|
||||
return;
|
||||
|
||||
gst_pad_sticky_events_foreach (src_pad, get_info_from_tags, stream_media);
|
||||
|
||||
|
@ -179,8 +181,8 @@ cleanup:
|
|||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
make_media (GstSDPMessage * sdp, GstSDPInfo * info,
|
||||
gboolean
|
||||
gst_rtsp_sdp_make_media (GstSDPMessage * sdp, GstSDPInfo * info,
|
||||
GstRTSPStream * stream, GstCaps * caps, GstRTSPProfile profile)
|
||||
{
|
||||
GstSDPMedia *smedia;
|
||||
|
@ -557,7 +559,7 @@ gst_rtsp_sdp_from_stream (GstSDPMessage * sdp, GstSDPInfo * info,
|
|||
GstRTSPProfile prof = profiles & mask;
|
||||
|
||||
if (prof)
|
||||
res = make_media (sdp, info, stream, caps, prof);
|
||||
res = gst_rtsp_sdp_make_media (sdp, info, stream, caps, prof);
|
||||
|
||||
mask <<= 1;
|
||||
}
|
||||
|
|
|
@ -40,6 +40,10 @@ gboolean gst_rtsp_sdp_from_media (GstSDPMessage *sdp, GstSDPInfo *in
|
|||
GST_EXPORT
|
||||
gboolean gst_rtsp_sdp_from_stream (GstSDPMessage * sdp, GstSDPInfo * info, GstRTSPStream *stream);
|
||||
|
||||
GST_EXPORT
|
||||
gboolean
|
||||
gst_rtsp_sdp_make_media (GstSDPMessage * sdp, GstSDPInfo * info, GstRTSPStream * stream, GstCaps * caps, GstRTSPProfile profile);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTSP_SDP_H__ */
|
||||
|
|
Loading…
Reference in a new issue