rtsp-onvif-media-factory: Add create_backchannel_stream() vfunc

Move the functionality that collects the backchannel bin and turns
it into an RTSP stream object into a vfunc so that implementations
can override the behaviour or timing of the call

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8378>
This commit is contained in:
Jan Schmidt 2025-01-20 20:57:07 +11:00 committed by GStreamer Marge Bot
parent a18b8c3f16
commit 84f8fcedc6
3 changed files with 104 additions and 11 deletions

View File

@ -7102,6 +7102,33 @@ bits per second.</doc>
</parameter>
</parameters>
</function>
<virtual-method name="create_backchannel_stream" version="1.26">
<doc xml:space="preserve" filename="../subprojects/gst-rtsp-server/gst/rtsp-server/rtsp-onvif-media-factory.h">Called by the factory from #GstRTSPMediaFactoryClass::construct(). The default implementation
creates the * #GstRTSPStream for the backchannel receiver by calling
gst_rtsp_onvif_media_collect_backchannel (media). Implementations
that want to create the backchannel later should return TRUE here
and call gst_rtsp_onvif_media_collect_backchannel() later, but must
do so before the media finishes preparing.</doc>
<source-position filename="../subprojects/gst-rtsp-server/gst/rtsp-server/rtsp-onvif-media-factory.h"/>
<return-value transfer-ownership="none">
<doc xml:space="preserve" filename="../subprojects/gst-rtsp-server/gst/rtsp-server/rtsp-onvif-media-factory.h">TRUE on success. FALSE on a fatal error.</doc>
<type name="gboolean" c:type="gboolean"/>
</return-value>
<parameters>
<instance-parameter name="factory" transfer-ownership="none">
<doc xml:space="preserve" filename="../subprojects/gst-rtsp-server/gst/rtsp-server/rtsp-onvif-media-factory.h">a #GstRTSPOnvifMediaFactory</doc>
<type name="RTSPOnvifMediaFactory" c:type="GstRTSPOnvifMediaFactory*"/>
</instance-parameter>
<parameter name="media" transfer-ownership="none">
<doc xml:space="preserve" filename="../subprojects/gst-rtsp-server/gst/rtsp-server/rtsp-onvif-media-factory.h">a #GstRTSPOnvifMedia</doc>
<type name="RTSPOnvifMedia" c:type="GstRTSPOnvifMedia*"/>
</parameter>
<parameter name="ctx" transfer-ownership="none">
<doc xml:space="preserve" filename="../subprojects/gst-rtsp-server/gst/rtsp-server/rtsp-onvif-media-factory.h">a #GstRTSPContext</doc>
<type name="RTSPContext" c:type="GstRTSPContext*"/>
</parameter>
</parameters>
</virtual-method>
<virtual-method name="has_backchannel_support" invoker="has_backchannel_support" version="1.14">
<doc xml:space="preserve" filename="../subprojects/gst-rtsp-server/gst/rtsp-server/rtsp-onvif-media-factory.c">Returns %TRUE if an ONVIF backchannel is supported by the media factory.</doc>
<source-position filename="../subprojects/gst-rtsp-server/gst/rtsp-server/rtsp-onvif-media-factory.h"/>
@ -7270,8 +7297,31 @@ prepare.</doc>
</parameters>
</callback>
</field>
<field name="create_backchannel_stream">
<callback name="create_backchannel_stream">
<source-position filename="../subprojects/gst-rtsp-server/gst/rtsp-server/rtsp-onvif-media-factory.h"/>
<return-value transfer-ownership="none">
<doc xml:space="preserve" filename="../subprojects/gst-rtsp-server/gst/rtsp-server/rtsp-onvif-media-factory.h">TRUE on success. FALSE on a fatal error.</doc>
<type name="gboolean" c:type="gboolean"/>
</return-value>
<parameters>
<parameter name="factory" transfer-ownership="none">
<doc xml:space="preserve" filename="../subprojects/gst-rtsp-server/gst/rtsp-server/rtsp-onvif-media-factory.h">a #GstRTSPOnvifMediaFactory</doc>
<type name="RTSPOnvifMediaFactory" c:type="GstRTSPOnvifMediaFactory*"/>
</parameter>
<parameter name="media" transfer-ownership="none">
<doc xml:space="preserve" filename="../subprojects/gst-rtsp-server/gst/rtsp-server/rtsp-onvif-media-factory.h">a #GstRTSPOnvifMedia</doc>
<type name="RTSPOnvifMedia" c:type="GstRTSPOnvifMedia*"/>
</parameter>
<parameter name="ctx" transfer-ownership="none">
<doc xml:space="preserve" filename="../subprojects/gst-rtsp-server/gst/rtsp-server/rtsp-onvif-media-factory.h">a #GstRTSPContext</doc>
<type name="RTSPContext" c:type="GstRTSPContext*"/>
</parameter>
</parameters>
</callback>
</field>
<field name="_gst_reserved" readable="0" private="1">
<array zero-terminated="0" fixed-size="20">
<array zero-terminated="0" fixed-size="19">
<type name="gpointer" c:type="gpointer"/>
</array>
</field>

View File

@ -114,7 +114,6 @@ gst_rtsp_onvif_media_factory_construct (GstRTSPMediaFactory * factory,
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,
@ -153,14 +152,17 @@ gst_rtsp_onvif_media_factory_construct (GstRTSPMediaFactory * factory,
/* 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 (gst_rtsp_onvif_media_factory_requires_backchannel (factory, ctx) &&
!got_backchannel_stream) {
g_object_unref (media);
return NULL;
GstRTSPOnvifMediaFactory *onvif_factory =
GST_RTSP_ONVIF_MEDIA_FACTORY (factory);
GstRTSPOnvifMediaFactoryClass *onvif_klass =
GST_RTSP_ONVIF_MEDIA_FACTORY_GET_CLASS (factory);
if (onvif_klass->create_backchannel_stream != NULL) {
/* this creates and adds the backchannel stream */
if (!onvif_klass->create_backchannel_stream (onvif_factory,
GST_RTSP_ONVIF_MEDIA (media), ctx)) {
g_object_unref (media);
return NULL;
}
}
pipeline = klass->create_pipeline (factory, media);
@ -325,6 +327,26 @@ static gboolean
return factory->priv->backchannel_launch != NULL;
}
static gboolean
create_backchannel_stream_default (GstRTSPOnvifMediaFactory * factory,
GstRTSPOnvifMedia * media, GstRTSPContext * ctx)
{
/* this adds the backchannel stream */
gboolean got_backchannel_stream =
gst_rtsp_onvif_media_collect_backchannel (media);
/* FIXME: This should not happen! We checked for that before */
if (gst_rtsp_onvif_media_factory_requires_backchannel (GST_RTSP_MEDIA_FACTORY
(factory), ctx) && !got_backchannel_stream) {
GST_WARNING_OBJECT (factory,
"Failed to collect backchannel, but factory requires backchannel");
return FALSE;
}
return TRUE;
}
static void
gst_rtsp_onvif_media_factory_finalize (GObject * object)
{
@ -352,6 +374,7 @@ gst_rtsp_onvif_media_factory_class_init (GstRTSPOnvifMediaFactoryClass * klass)
klass->has_backchannel_support =
gst_rtsp_onvif_media_factory_has_backchannel_support_default;
klass->create_backchannel_stream = create_backchannel_stream_default;
}
static void

View File

@ -22,6 +22,7 @@
#include <gst/gst.h>
#include "rtsp-media-factory.h"
#include "rtsp-onvif-media.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))
@ -46,8 +47,27 @@ struct GstRTSPOnvifMediaFactoryClass
GstRTSPMediaFactoryClass parent;
gboolean (*has_backchannel_support) (GstRTSPOnvifMediaFactory * factory);
/**
* GstRTSPOnvifMediaFactoryClass::create_backchannel_stream:
* @factory: a #GstRTSPOnvifMediaFactory
* @media: a #GstRTSPOnvifMedia
* @ctx: a #GstRTSPContext
*
* Called by the factory from #GstRTSPMediaFactoryClass::construct(). The default implementation
* creates the * #GstRTSPStream for the backchannel receiver by calling
* gst_rtsp_onvif_media_collect_backchannel (media). Implementations
* that want to create the backchannel later should return TRUE here
* and call gst_rtsp_onvif_media_collect_backchannel() later, but must
* do so before the media finishes preparing.
*
* Returns: TRUE on success. FALSE on a fatal error.
*
* Since: 1.26
*/
gboolean (*create_backchannel_stream) (GstRTSPOnvifMediaFactory * factory, GstRTSPOnvifMedia *media, GstRTSPContext *ctx);
/*< private >*/
gpointer _gst_reserved[GST_PADDING_LARGE];
gpointer _gst_reserved[GST_PADDING_LARGE-1];
};
struct GstRTSPOnvifMediaFactory