#include <string.h>
#include <gst/sdp/gstmikey.h>
+#include <gst/rtsp/gstrtsp-enumtypes.h>
#include "rtsp-client.h"
#include "rtsp-sdp.h"
{
SIGNAL_CLOSED,
SIGNAL_NEW_SESSION,
+ SIGNAL_PRE_OPTIONS_REQUEST,
SIGNAL_OPTIONS_REQUEST,
+ SIGNAL_PRE_DESCRIBE_REQUEST,
SIGNAL_DESCRIBE_REQUEST,
+ SIGNAL_PRE_SETUP_REQUEST,
SIGNAL_SETUP_REQUEST,
+ SIGNAL_PRE_PLAY_REQUEST,
SIGNAL_PLAY_REQUEST,
+ SIGNAL_PRE_PAUSE_REQUEST,
SIGNAL_PAUSE_REQUEST,
+ SIGNAL_PRE_TEARDOWN_REQUEST,
SIGNAL_TEARDOWN_REQUEST,
+ SIGNAL_PRE_SET_PARAMETER_REQUEST,
SIGNAL_SET_PARAMETER_REQUEST,
+ SIGNAL_PRE_GET_PARAMETER_REQUEST,
SIGNAL_GET_PARAMETER_REQUEST,
SIGNAL_HANDLE_RESPONSE,
SIGNAL_SEND_MESSAGE,
+ SIGNAL_PRE_ANNOUNCE_REQUEST,
SIGNAL_ANNOUNCE_REQUEST,
+ SIGNAL_PRE_RECORD_REQUEST,
SIGNAL_RECORD_REQUEST,
SIGNAL_CHECK_REQUIREMENTS,
SIGNAL_LAST
const GstRTSPUrl * uri);
static void client_session_removed (GstRTSPSessionPool * pool,
GstRTSPSession * session, GstRTSPClient * client);
+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);
G_DEFINE_TYPE (GstRTSPClient, gst_rtsp_client, G_TYPE_OBJECT);
klass->params_get = default_params_get;
klass->make_path_from_uri = default_make_path_from_uri;
+ klass->pre_options_request = default_pre_signal_handler;
+ klass->pre_describe_request = default_pre_signal_handler;
+ klass->pre_setup_request = default_pre_signal_handler;
+ klass->pre_play_request = default_pre_signal_handler;
+ klass->pre_pause_request = default_pre_signal_handler;
+ klass->pre_teardown_request = default_pre_signal_handler;
+ klass->pre_set_parameter_request = default_pre_signal_handler;
+ klass->pre_get_parameter_request = default_pre_signal_handler;
+ klass->pre_announce_request = default_pre_signal_handler;
+ klass->pre_record_request = default_pre_signal_handler;
+
g_object_class_install_property (gobject_class, PROP_SESSION_POOL,
g_param_spec_object ("session-pool", "Session Pool",
"The session pool to use for client session",
G_STRUCT_OFFSET (GstRTSPClientClass, new_session), NULL, NULL,
g_cclosure_marshal_generic, G_TYPE_NONE, 1, GST_TYPE_RTSP_SESSION);
+ /**
+ * GstRTSPClient::pre-options-request:
+ * @client: a #GstRTSPClient
+ * @ctx: a #GstRTSPContext
+ *
+ * Returns: a #GstRTSPStatusCode, GST_RTSP_STS_OK in case of success,
+ * otherwise an appropriate return code
+ *
+ * Since: 1.12
+ */
+ gst_rtsp_client_signals[SIGNAL_PRE_OPTIONS_REQUEST] =
+ g_signal_new ("pre-options-request", G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPClientClass,
+ pre_options_request), pre_signal_accumulator, NULL,
+ g_cclosure_marshal_generic, GST_TYPE_RTSP_STATUS_CODE, 1,
+ GST_TYPE_RTSP_CONTEXT);
+
gst_rtsp_client_signals[SIGNAL_OPTIONS_REQUEST] =
g_signal_new ("options-request", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPClientClass, options_request),
NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1,
GST_TYPE_RTSP_CONTEXT);
+ /**
+ * GstRTSPClient::pre-describe-request:
+ * @client: a #GstRTSPClient
+ * @ctx: a #GstRTSPContext
+ *
+ * Returns: a #GstRTSPStatusCode, GST_RTSP_STS_OK in case of success,
+ * otherwise an appropriate return code
+ *
+ * Since: 1.12
+ */
+ gst_rtsp_client_signals[SIGNAL_PRE_DESCRIBE_REQUEST] =
+ g_signal_new ("pre-describe-request", G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPClientClass,
+ pre_describe_request), pre_signal_accumulator, NULL,
+ g_cclosure_marshal_generic, GST_TYPE_RTSP_STATUS_CODE, 1,
+ GST_TYPE_RTSP_CONTEXT);
+
gst_rtsp_client_signals[SIGNAL_DESCRIBE_REQUEST] =
g_signal_new ("describe-request", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPClientClass, describe_request),
NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1,
GST_TYPE_RTSP_CONTEXT);
+ /**
+ * GstRTSPClient::pre-setup-request:
+ * @client: a #GstRTSPClient
+ * @ctx: a #GstRTSPContext
+ *
+ * Returns: a #GstRTSPStatusCode, GST_RTSP_STS_OK in case of success,
+ * otherwise an appropriate return code
+ *
+ * Since: 1.12
+ */
+ gst_rtsp_client_signals[SIGNAL_PRE_SETUP_REQUEST] =
+ g_signal_new ("pre-setup-request", G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPClientClass,
+ pre_setup_request), pre_signal_accumulator, NULL,
+ g_cclosure_marshal_generic, GST_TYPE_RTSP_STATUS_CODE, 1,
+ GST_TYPE_RTSP_CONTEXT);
+
gst_rtsp_client_signals[SIGNAL_SETUP_REQUEST] =
g_signal_new ("setup-request", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPClientClass, setup_request),
NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1,
GST_TYPE_RTSP_CONTEXT);
+ /**
+ * GstRTSPClient::pre-play-request:
+ * @client: a #GstRTSPClient
+ * @ctx: a #GstRTSPContext
+ *
+ * Returns: a #GstRTSPStatusCode, GST_RTSP_STS_OK in case of success,
+ * otherwise an appropriate return code
+ *
+ * Since: 1.12
+ */
+ gst_rtsp_client_signals[SIGNAL_PRE_PLAY_REQUEST] =
+ g_signal_new ("pre-play-request", G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPClientClass,
+ pre_play_request), pre_signal_accumulator, NULL,
+ g_cclosure_marshal_generic, GST_TYPE_RTSP_STATUS_CODE, 1,
+ GST_TYPE_RTSP_CONTEXT);
+
gst_rtsp_client_signals[SIGNAL_PLAY_REQUEST] =
g_signal_new ("play-request", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPClientClass, play_request),
NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1,
GST_TYPE_RTSP_CONTEXT);
+ /**
+ * GstRTSPClient::pre-pause-request:
+ * @client: a #GstRTSPClient
+ * @ctx: a #GstRTSPContext
+ *
+ * Returns: a #GstRTSPStatusCode, GST_RTSP_STS_OK in case of success,
+ * otherwise an appropriate return code
+ *
+ * Since: 1.12
+ */
+ gst_rtsp_client_signals[SIGNAL_PRE_PAUSE_REQUEST] =
+ g_signal_new ("pre-pause-request", G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPClientClass,
+ pre_pause_request), pre_signal_accumulator, NULL,
+ g_cclosure_marshal_generic, GST_TYPE_RTSP_STATUS_CODE, 1,
+ GST_TYPE_RTSP_CONTEXT);
+
gst_rtsp_client_signals[SIGNAL_PAUSE_REQUEST] =
g_signal_new ("pause-request", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPClientClass, pause_request),
NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1,
GST_TYPE_RTSP_CONTEXT);
+ /**
+ * GstRTSPClient::pre-teardown-request:
+ * @client: a #GstRTSPClient
+ * @ctx: a #GstRTSPContext
+ *
+ * Returns: a #GstRTSPStatusCode, GST_RTSP_STS_OK in case of success,
+ * otherwise an appropriate return code
+ *
+ * Since: 1.12
+ */
+ gst_rtsp_client_signals[SIGNAL_PRE_TEARDOWN_REQUEST] =
+ g_signal_new ("pre-teardown-request", G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPClientClass,
+ pre_teardown_request), pre_signal_accumulator, NULL,
+ g_cclosure_marshal_generic, GST_TYPE_RTSP_STATUS_CODE, 1,
+ GST_TYPE_RTSP_CONTEXT);
+
gst_rtsp_client_signals[SIGNAL_TEARDOWN_REQUEST] =
g_signal_new ("teardown-request", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPClientClass, teardown_request),
NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1,
GST_TYPE_RTSP_CONTEXT);
+ /**
+ * GstRTSPClient::pre-set-parameter-request:
+ * @client: a #GstRTSPClient
+ * @ctx: a #GstRTSPContext
+ *
+ * Returns: a #GstRTSPStatusCode, GST_RTSP_STS_OK in case of success,
+ * otherwise an appropriate return code
+ *
+ * Since: 1.12
+ */
+ gst_rtsp_client_signals[SIGNAL_PRE_SET_PARAMETER_REQUEST] =
+ g_signal_new ("pre-set-parameter-request", G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPClientClass,
+ pre_set_parameter_request), pre_signal_accumulator, NULL,
+ g_cclosure_marshal_generic,
+ GST_TYPE_RTSP_STATUS_CODE, 1, GST_TYPE_RTSP_CONTEXT);
+
gst_rtsp_client_signals[SIGNAL_SET_PARAMETER_REQUEST] =
g_signal_new ("set-parameter-request", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPClientClass,
set_parameter_request), NULL, NULL, g_cclosure_marshal_generic,
G_TYPE_NONE, 1, GST_TYPE_RTSP_CONTEXT);
+ /**
+ * GstRTSPClient::pre-get-parameter-request:
+ * @client: a #GstRTSPClient
+ * @ctx: a #GstRTSPContext
+ *
+ * Returns: a #GstRTSPStatusCode, GST_RTSP_STS_OK in case of success,
+ * otherwise an appropriate return code
+ *
+ * Since: 1.12
+ */
+ gst_rtsp_client_signals[SIGNAL_PRE_GET_PARAMETER_REQUEST] =
+ g_signal_new ("pre-get-parameter-request", G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPClientClass,
+ pre_get_parameter_request), pre_signal_accumulator, NULL,
+ g_cclosure_marshal_generic, GST_TYPE_RTSP_STATUS_CODE, 1,
+ GST_TYPE_RTSP_CONTEXT);
+
gst_rtsp_client_signals[SIGNAL_GET_PARAMETER_REQUEST] =
g_signal_new ("get-parameter-request", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPClientClass,
send_message), NULL, NULL, g_cclosure_marshal_generic,
G_TYPE_NONE, 2, GST_TYPE_RTSP_CONTEXT, G_TYPE_POINTER);
+ /**
+ * GstRTSPClient::pre-announce-request:
+ * @client: a #GstRTSPClient
+ * @ctx: a #GstRTSPContext
+ *
+ * Returns: a #GstRTSPStatusCode, GST_RTSP_STS_OK in case of success,
+ * otherwise an appropriate return code
+ *
+ * Since: 1.12
+ */
+ gst_rtsp_client_signals[SIGNAL_PRE_ANNOUNCE_REQUEST] =
+ g_signal_new ("pre-announce-request", G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPClientClass,
+ pre_announce_request), pre_signal_accumulator, NULL,
+ g_cclosure_marshal_generic, GST_TYPE_RTSP_STATUS_CODE, 1,
+ GST_TYPE_RTSP_CONTEXT);
+
gst_rtsp_client_signals[SIGNAL_ANNOUNCE_REQUEST] =
g_signal_new ("announce-request", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPClientClass, announce_request),
NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1,
GST_TYPE_RTSP_CONTEXT);
+ /**
+ * GstRTSPClient::pre-record-request:
+ * @client: a #GstRTSPClient
+ * @ctx: a #GstRTSPContext
+ *
+ * Returns: a #GstRTSPStatusCode, GST_RTSP_STS_OK in case of success,
+ * otherwise an appropriate return code
+ *
+ * Since: 1.12
+ */
+ gst_rtsp_client_signals[SIGNAL_PRE_RECORD_REQUEST] =
+ g_signal_new ("pre-record-request", G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPClientClass,
+ pre_record_request), pre_signal_accumulator, NULL,
+ g_cclosure_marshal_generic, GST_TYPE_RTSP_STATUS_CODE, 1,
+ GST_TYPE_RTSP_CONTEXT);
+
gst_rtsp_client_signals[SIGNAL_RECORD_REQUEST] =
g_signal_new ("record-request", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPClientClass, record_request),
return path;
}
+/* Default signal handler function for all "pre-command" signals, like
+ * pre-options-request. It just returns the RTSP return code 200.
+ * Subclasses can override this to get another default behaviour.
+ */
+static GstRTSPStatusCode
+default_pre_signal_handler (GstRTSPClient * client, GstRTSPContext * ctx)
+{
+ GST_LOG_OBJECT (client, "returning GST_RTSP_STS_OK");
+ return GST_RTSP_STS_OK;
+}
+
+/* The pre-signal accumulator function checks the return value of the signal
+ * handlers. If any of them returns an RTSP status code that does not start
+ * with 2 it will return FALSE, no more signal handlers will be called, and
+ * this last RTSP status code will be the result of the signal emission.
+ */
+static gboolean
+pre_signal_accumulator (GSignalInvocationHint * ihint, GValue * return_accu,
+ const GValue * handler_return, gpointer data)
+{
+ GstRTSPStatusCode handler_value = g_value_get_enum (handler_return);
+ GstRTSPStatusCode accumulated_value = g_value_get_enum (return_accu);
+
+ if (handler_value < 200 || handler_value > 299) {
+ GST_DEBUG ("handler_value : %d, returning FALSE", handler_value);
+ g_value_set_enum (return_accu, handler_value);
+ return FALSE;
+ }
+
+ /* the accumulated value is initiated to 0 by GLib. if current handler value is
+ * bigger then use that instead
+ *
+ * FIXME: Should we prioritize the 2xx codes in a smarter way?
+ * Like, "201 Created" > "250 Low On Storage Space" > "200 OK"?
+ */
+ if (handler_value > accumulated_value)
+ g_value_set_enum (return_accu, handler_value);
+
+ return TRUE;
+}
+
static gboolean
handle_teardown_request (GstRTSPClient * client, GstRTSPContext * ctx)
{
gchar *path;
gint matched;
gboolean keep_session;
+ GstRTSPStatusCode sig_result;
if (!ctx->session)
goto no_session;
ctx->sessmedia = sessmedia;
+ g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_PRE_TEARDOWN_REQUEST],
+ 0, ctx, &sig_result);
+ if (sig_result != GST_RTSP_STS_OK) {
+ goto sig_failed;
+ }
+
/* we emit the signal before closing the connection */
g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_TEARDOWN_REQUEST],
0, ctx);
g_free (path);
return FALSE;
}
+sig_failed:
+ {
+ GST_ERROR ("client %p: pre signal returned error: %s", client,
+ gst_rtsp_status_as_text (sig_result));
+ send_generic_response (client, sig_result, ctx);
+ return FALSE;
+ }
}
static GstRTSPResult
GstRTSPResult res;
guint8 *data;
guint size;
+ GstRTSPStatusCode sig_result;
+
+ g_signal_emit (client,
+ gst_rtsp_client_signals[SIGNAL_PRE_GET_PARAMETER_REQUEST], 0, ctx,
+ &sig_result);
+ if (sig_result != GST_RTSP_STS_OK) {
+ goto sig_failed;
+ }
res = gst_rtsp_message_get_body (ctx->request, &data, &size);
if (res != GST_RTSP_OK)
return TRUE;
/* ERRORS */
+sig_failed:
+ {
+ GST_ERROR ("client %p: pre signal returned error: %s", client,
+ gst_rtsp_status_as_text (sig_result));
+ send_generic_response (client, sig_result, ctx);
+ return FALSE;
+ }
bad_request:
{
GST_ERROR ("client %p: bad request", client);
GstRTSPResult res;
guint8 *data;
guint size;
+ GstRTSPStatusCode sig_result;
+
+ g_signal_emit (client,
+ gst_rtsp_client_signals[SIGNAL_PRE_SET_PARAMETER_REQUEST], 0, ctx,
+ &sig_result);
+ if (sig_result != GST_RTSP_STS_OK) {
+ goto sig_failed;
+ }
res = gst_rtsp_message_get_body (ctx->request, &data, &size);
if (res != GST_RTSP_OK)
return TRUE;
/* ERRORS */
+sig_failed:
+ {
+ GST_ERROR ("client %p: pre signal returned error: %s", client,
+ gst_rtsp_status_as_text (sig_result));
+ send_generic_response (client, sig_result, ctx);
+ return FALSE;
+ }
bad_request:
{
GST_ERROR ("client %p: bad request", client);
GstRTSPState rtspstate;
gchar *path;
gint matched;
+ GstRTSPStatusCode sig_result;
guint i, n;
if (!(session = ctx->session))
ctx->sessmedia = sessmedia;
+ g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_PRE_PAUSE_REQUEST], 0,
+ ctx, &sig_result);
+ if (sig_result != GST_RTSP_STS_OK) {
+ goto sig_failed;
+ }
+
rtspstate = gst_rtsp_session_media_get_rtsp_state (sessmedia);
/* the session state must be playing or recording */
if (rtspstate != GST_RTSP_STATE_PLAYING &&
g_free (path);
return FALSE;
}
+sig_failed:
+ {
+ GST_ERROR ("client %p: pre signal returned error: %s", client,
+ gst_rtsp_status_as_text (sig_result));
+ send_generic_response (client, sig_result, ctx);
+ return FALSE;
+ }
invalid_state:
{
GST_ERROR ("client %p: not PLAYING or RECORDING", client);
GstRTSPRangeUnit unit = GST_RTSP_RANGE_NPT;
gchar *path, *rtpinfo;
gint matched;
+ GstRTSPStatusCode sig_result;
if (!(session = ctx->session))
goto no_session;
ctx->sessmedia = sessmedia;
ctx->media = media = gst_rtsp_session_media_get_media (sessmedia);
+ g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_PRE_PLAY_REQUEST], 0,
+ ctx, &sig_result);
+ if (sig_result != GST_RTSP_STS_OK) {
+ goto sig_failed;
+ }
+
if (!(gst_rtsp_media_get_transport_mode (media) &
GST_RTSP_TRANSPORT_MODE_PLAY))
goto unsupported_mode;
g_free (path);
return FALSE;
}
+sig_failed:
+ {
+ GST_ERROR ("client %p: pre signal returned error: %s", client,
+ gst_rtsp_status_as_text (sig_result));
+ send_generic_response (client, sig_result, ctx);
+ return FALSE;
+ }
invalid_state:
{
GST_ERROR ("client %p: not PLAYING or READY", client);
gchar *path, *control = NULL;
gint matched;
gboolean new_session = FALSE;
+ GstRTSPStatusCode sig_result;
if (!ctx->uri)
goto no_uri;
ctx->stream = stream;
ctx->media = media;
+ g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_PRE_SETUP_REQUEST], 0,
+ ctx, &sig_result);
+ if (sig_result != GST_RTSP_STS_OK) {
+ goto sig_failed;
+ }
+
if (session == NULL) {
/* create a session if this fails we probably reached our session limit or
* something. */
g_object_unref (media);
goto cleanup_session;
}
+sig_failed:
+ {
+ GST_ERROR ("client %p: pre signal returned error: %s", client,
+ gst_rtsp_status_as_text (sig_result));
+ send_generic_response (client, sig_result, ctx);
+ g_object_unref (media);
+ goto cleanup_path;
+ }
service_unavailable:
{
GST_ERROR ("client %p: can't create session", client);
gchar *path, *str;
GstRTSPMedia *media;
GstRTSPClientClass *klass;
+ GstRTSPStatusCode sig_result;
klass = GST_RTSP_CLIENT_GET_CLASS (client);
if (!ctx->uri)
goto no_uri;
+ g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_PRE_DESCRIBE_REQUEST],
+ 0, ctx, &sig_result);
+ if (sig_result != GST_RTSP_STS_OK) {
+ goto sig_failed;
+ }
+
/* check what kind of format is accepted, we don't really do anything with it
* and always return SDP for now. */
for (i = 0;; i++) {
return TRUE;
/* ERRORS */
+sig_failed:
+ {
+ GST_ERROR ("client %p: pre signal returned error: %s", client,
+ gst_rtsp_status_as_text (sig_result));
+ send_generic_response (client, sig_result, ctx);
+ return FALSE;
+ }
no_uri:
{
GST_ERROR ("client %p: no uri", client);
gchar *path, *cont = NULL;
guint8 *data;
guint size;
+ GstRTSPStatusCode sig_result;
klass = GST_RTSP_CLIENT_GET_CLASS (client);
if (!(media = find_media (client, ctx, path, NULL)))
goto no_media;
+ ctx->media = media;
+
+ g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_PRE_ANNOUNCE_REQUEST],
+ 0, ctx, &sig_result);
+ if (sig_result != GST_RTSP_STS_OK) {
+ goto sig_failed;
+ }
+
if (!(gst_rtsp_media_get_transport_mode (media) &
GST_RTSP_TRANSPORT_MODE_RECORD))
goto unsupported_mode;
gst_sdp_message_free (sdp);
return FALSE;
}
+sig_failed:
+ {
+ GST_ERROR ("client %p: pre signal returned error: %s", client,
+ gst_rtsp_status_as_text (sig_result));
+ send_generic_response (client, sig_result, ctx);
+ gst_sdp_message_free (sdp);
+ return FALSE;
+ }
unsupported_mode:
{
GST_ERROR ("client %p: media does not support ANNOUNCE", client);
GstRTSPState rtspstate;
gchar *path;
gint matched;
+ GstRTSPStatusCode sig_result;
if (!(session = ctx->session))
goto no_session;
ctx->sessmedia = sessmedia;
ctx->media = media = gst_rtsp_session_media_get_media (sessmedia);
+ g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_PRE_RECORD_REQUEST], 0,
+ ctx, &sig_result);
+ if (sig_result != GST_RTSP_STS_OK) {
+ goto sig_failed;
+ }
+
if (!(gst_rtsp_media_get_transport_mode (media) &
GST_RTSP_TRANSPORT_MODE_RECORD))
goto unsupported_mode;
g_free (path);
return FALSE;
}
+sig_failed:
+ {
+ GST_ERROR ("client %p: pre signal returned error: %s", client,
+ gst_rtsp_status_as_text (sig_result));
+ send_generic_response (client, sig_result, ctx);
+ return FALSE;
+ }
unsupported_mode:
{
GST_ERROR ("client %p: media does not support RECORD", client);
{
GstRTSPMethod options;
gchar *str;
+ GstRTSPStatusCode sig_result;
options = GST_RTSP_DESCRIBE |
GST_RTSP_OPTIONS |
gst_rtsp_message_add_header (ctx->response, GST_RTSP_HDR_PUBLIC, str);
g_free (str);
+ g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_PRE_OPTIONS_REQUEST], 0,
+ ctx, &sig_result);
+ if (sig_result != GST_RTSP_STS_OK) {
+ goto sig_failed;
+ }
+
send_message (client, ctx, ctx->response, FALSE);
g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_OPTIONS_REQUEST],
0, ctx);
return TRUE;
+
+/* ERRORS */
+sig_failed:
+ {
+ GST_ERROR ("client %p: pre signal returned error: %s", client,
+ gst_rtsp_status_as_text (sig_result));
+ send_generic_response (client, sig_result, ctx);
+ gst_rtsp_message_free (ctx->response);
+ return FALSE;
+ }
}
/* remove duplicate and trailing '/' */