rtspsrc: Add a signal to allow outgoing messages to be modified or dropped

This feature allows applications to implement extensions to the RTSP
protocol, such as those defined in the ONVIF Streaming Specification.

https://bugzilla.gnome.org/show_bug.cgi?id=762884
This commit is contained in:
Matt Staples 2017-11-01 08:21:37 -06:00 committed by Sebastian Dröge
parent 3c0d006c03
commit ea1b10e4ca

View file

@ -125,6 +125,7 @@ enum
SIGNAL_NEW_MANAGER, SIGNAL_NEW_MANAGER,
SIGNAL_REQUEST_RTCP_KEY, SIGNAL_REQUEST_RTCP_KEY,
SIGNAL_ACCEPT_CERTIFICATE, SIGNAL_ACCEPT_CERTIFICATE,
SIGNAL_BEFORE_SEND,
LAST_SIGNAL LAST_SIGNAL
}; };
@ -437,6 +438,26 @@ select_stream_accum (GSignalInvocationHint * ihint,
return myboolean; return myboolean;
} }
static gboolean
default_before_send (GstRTSPSrc * src, GstRTSPMessage * msg)
{
GST_DEBUG_OBJECT (src, "default handler");
return TRUE;
}
static gboolean
before_send_accum (GSignalInvocationHint * ihint,
GValue * return_accu, const GValue * handler_return, gpointer data)
{
gboolean myboolean;
myboolean = g_value_get_boolean (handler_return);
g_value_set_boolean (return_accu, myboolean);
/* prevent send if FALSE */
return myboolean;
}
static void static void
gst_rtspsrc_class_init (GstRTSPSrcClass * klass) gst_rtspsrc_class_init (GstRTSPSrcClass * klass)
{ {
@ -921,6 +942,29 @@ gst_rtspsrc_class_init (GstRTSPSrcClass * klass)
G_TYPE_BOOLEAN, 3, G_TYPE_TLS_CONNECTION, G_TYPE_TLS_CERTIFICATE, G_TYPE_BOOLEAN, 3, G_TYPE_TLS_CONNECTION, G_TYPE_TLS_CERTIFICATE,
G_TYPE_TLS_CERTIFICATE_FLAGS); G_TYPE_TLS_CERTIFICATE_FLAGS);
/*
* GstRTSPSrc::before-send
* @rtspsrc: a #GstRTSPSrc
* @num: the stream number
*
* Emitted before each RTSP request is sent, in order to allow
* the application to modify send parameters or to skip the message entirely.
* This can be used, for example, to work with ONVIF Profile G servers,
* which need a different/additional range, rate-control, and intra/x
* parameters.
*
* Returns: %TRUE when the command should be sent, %FALSE when the
* command should be dropped.
*
* Since: 1.14
*/
gst_rtspsrc_signals[SIGNAL_BEFORE_SEND] =
g_signal_new_class_handler ("before-send", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_CLEANUP,
(GCallback) default_before_send, before_send_accum, NULL,
g_cclosure_marshal_generic, G_TYPE_BOOLEAN,
1, GST_TYPE_RTSP_MESSAGE | G_SIGNAL_TYPE_STATIC_SCOPE);
gstelement_class->send_event = gst_rtspsrc_send_event; gstelement_class->send_event = gst_rtspsrc_send_event;
gstelement_class->provide_clock = gst_rtspsrc_provide_clock; gstelement_class->provide_clock = gst_rtspsrc_provide_clock;
gstelement_class->change_state = gst_rtspsrc_change_state; gstelement_class->change_state = gst_rtspsrc_change_state;
@ -5697,11 +5741,19 @@ gst_rtspsrc_try_send (GstRTSPSrc * src, GstRTSPConnInfo * conninfo,
{ {
GstRTSPResult res; GstRTSPResult res;
gint try = 0; gint try = 0;
gboolean allow_send = TRUE;
again: again:
if (!src->short_header) if (!src->short_header)
gst_rtsp_ext_list_before_send (src->extensions, request); gst_rtsp_ext_list_before_send (src->extensions, request);
g_signal_emit (src, gst_rtspsrc_signals[SIGNAL_BEFORE_SEND], 0,
request, &allow_send);
if (!allow_send) {
GST_DEBUG_OBJECT (src, "skipping message, disabled by signal");
return GST_RTSP_OK;
}
GST_DEBUG_OBJECT (src, "sending message"); GST_DEBUG_OBJECT (src, "sending message");
DEBUG_RTSP (src, request); DEBUG_RTSP (src, request);