return size <= channel->sctp_transport->max_message_size;
}
-static void
+static gboolean
webrtc_data_channel_send_data (GstWebRTCDataChannel * base_channel,
- GBytes * bytes)
+ GBytes * bytes, GError ** error)
{
WebRTCDataChannel *channel = WEBRTC_DATA_CHANNEL (base_channel);
GstSctpSendMetaPartiallyReliability reliability;
guint rel_param;
guint32 ppid;
GstBuffer *buffer;
+ gsize size = 0;
GstFlowReturn ret;
if (!bytes) {
buffer = gst_buffer_new ();
ppid = DATA_CHANNEL_PPID_WEBRTC_BINARY_EMPTY;
} else {
- gsize size;
guint8 *data;
data = (guint8 *) g_bytes_get_data (bytes, &size);
- g_return_if_fail (data != NULL);
+ g_return_val_if_fail (data != NULL, FALSE);
if (!_is_within_max_message_size (channel, size)) {
- GError *error = NULL;
- g_set_error (&error, GST_WEBRTC_ERROR,
- GST_WEBRTC_ERROR_DATA_CHANNEL_FAILURE,
+ g_set_error (error, GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_TYPE_ERROR,
"Requested to send data that is too large");
- _channel_store_error (channel, error);
- _channel_enqueue_task (channel, (ChannelTask) _close_procedure, NULL,
- NULL);
- return;
+ return FALSE;
}
buffer = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY, data, size,
buffer);
GST_WEBRTC_DATA_CHANNEL_LOCK (channel);
- channel->parent.buffered_amount += gst_buffer_get_size (buffer);
+ if (channel->parent.ready_state == GST_WEBRTC_DATA_CHANNEL_STATE_OPEN) {
+ channel->parent.buffered_amount += size;
+ } else {
+ GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
+ g_set_error (error, GST_WEBRTC_ERROR,
+ GST_WEBRTC_ERROR_INVALID_STATE, "channel is not open");
+ return FALSE;
+ }
GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
- g_object_notify (G_OBJECT (&channel->parent), "buffered-amount");
ret = gst_app_src_push_buffer (GST_APP_SRC (channel->appsrc), buffer);
-
- if (ret != GST_FLOW_OK) {
- GError *error = NULL;
- g_set_error (&error, GST_WEBRTC_ERROR,
+ if (ret == GST_FLOW_OK) {
+ g_object_notify (G_OBJECT (&channel->parent), "buffered-amount");
+ } else {
+ g_set_error (error, GST_WEBRTC_ERROR,
GST_WEBRTC_ERROR_DATA_CHANNEL_FAILURE, "Failed to send data");
- _channel_store_error (channel, error);
+
+ GST_WEBRTC_DATA_CHANNEL_LOCK (channel);
+ channel->parent.buffered_amount -= size;
+ GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
+
_channel_enqueue_task (channel, (ChannelTask) _close_procedure, NULL, NULL);
+ return FALSE;
}
+
+ return TRUE;
}
-static void
+static gboolean
webrtc_data_channel_send_string (GstWebRTCDataChannel * base_channel,
- const gchar * str)
+ const gchar * str, GError ** error)
{
WebRTCDataChannel *channel = WEBRTC_DATA_CHANNEL (base_channel);
GstSctpSendMetaPartiallyReliability reliability;
guint rel_param;
guint32 ppid;
GstBuffer *buffer;
+ gsize size = 0;
GstFlowReturn ret;
if (!channel->parent.negotiated)
- g_return_if_fail (channel->opened);
- g_return_if_fail (channel->sctp_transport != NULL);
+ g_return_val_if_fail (channel->opened, FALSE);
+ g_return_val_if_fail (channel->sctp_transport != NULL, FALSE);
if (!str) {
buffer = gst_buffer_new ();
ppid = DATA_CHANNEL_PPID_WEBRTC_STRING_EMPTY;
} else {
- gsize size = strlen (str);
gchar *str_copy;
+ size = strlen (str);
if (!_is_within_max_message_size (channel, size)) {
- GError *error = NULL;
- g_set_error (&error, GST_WEBRTC_ERROR,
- GST_WEBRTC_ERROR_DATA_CHANNEL_FAILURE,
+ g_set_error (error, GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_TYPE_ERROR,
"Requested to send a string that is too large");
- _channel_store_error (channel, error);
- _channel_enqueue_task (channel, (ChannelTask) _close_procedure, NULL,
- NULL);
- return;
+ return FALSE;
}
str_copy = g_strdup (str);
buffer);
GST_WEBRTC_DATA_CHANNEL_LOCK (channel);
- channel->parent.buffered_amount += gst_buffer_get_size (buffer);
+ if (channel->parent.ready_state == GST_WEBRTC_DATA_CHANNEL_STATE_OPEN) {
+ channel->parent.buffered_amount += size;
+ } else {
+ GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
+ g_set_error (error, GST_WEBRTC_ERROR,
+ GST_WEBRTC_ERROR_INVALID_STATE, "channel is not open");
+ return FALSE;
+ }
GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
- g_object_notify (G_OBJECT (&channel->parent), "buffered-amount");
ret = gst_app_src_push_buffer (GST_APP_SRC (channel->appsrc), buffer);
-
- if (ret != GST_FLOW_OK) {
- GError *error = NULL;
- g_set_error (&error, GST_WEBRTC_ERROR,
+ if (ret == GST_FLOW_OK) {
+ g_object_notify (G_OBJECT (&channel->parent), "buffered-amount");
+ } else {
+ g_set_error (error, GST_WEBRTC_ERROR,
GST_WEBRTC_ERROR_DATA_CHANNEL_FAILURE, "Failed to send string");
- _channel_store_error (channel, error);
+
+ GST_WEBRTC_DATA_CHANNEL_LOCK (channel);
+ channel->parent.buffered_amount -= size;
+ GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
+
_channel_enqueue_task (channel, (ChannelTask) _close_procedure, NULL, NULL);
+ return FALSE;
}
+
+ return TRUE;
}
static void
*/
gst_webrtc_data_channel_signals[SIGNAL_SEND_DATA] =
g_signal_new_class_handler ("send-data", G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION | G_SIGNAL_DEPRECATED,
G_CALLBACK (gst_webrtc_data_channel_send_data), NULL, NULL, NULL,
G_TYPE_NONE, 1, G_TYPE_BYTES);
g_return_if_fail (GST_IS_WEBRTC_DATA_CHANNEL (channel));
klass = GST_WEBRTC_DATA_CHANNEL_GET_CLASS (channel);
- klass->send_data (channel, data);
+ (void) klass->send_data (channel, data, NULL);
+}
+
+/**
+ * gst_webrtc_data_channel_send_data_full:
+ * @channel: a #GstWebRTCDataChannel
+ * @data: (nullable): a #GBytes or %NULL
+ * @error: (nullable): location to a #GError or %NULL
+ *
+ * Send @data as a data message over @channel.
+ *
+ * Returns: TRUE if @channel is open and data could be queued
+ *
+ * Since: 1.22
+ */
+gboolean
+gst_webrtc_data_channel_send_data_full (GstWebRTCDataChannel * channel,
+ GBytes * data, GError ** error)
+{
+ GstWebRTCDataChannelClass *klass;
+
+ g_return_val_if_fail (GST_IS_WEBRTC_DATA_CHANNEL (channel), FALSE);
+
+ klass = GST_WEBRTC_DATA_CHANNEL_GET_CLASS (channel);
+ return klass->send_data (channel, data, error);
}
/**
g_return_if_fail (GST_IS_WEBRTC_DATA_CHANNEL (channel));
klass = GST_WEBRTC_DATA_CHANNEL_GET_CLASS (channel);
- klass->send_string (channel, str);
+ (void) klass->send_string (channel, str, NULL);
+}
+
+/**
+ * gst_webrtc_data_channel_send_string_full:
+ * @channel: a #GstWebRTCDataChannel
+ * @str: (nullable): a string or %NULL
+ *
+ * Send @str as a string message over @channel.
+ *
+ * Returns: TRUE if @channel is open and data could be queued
+ *
+ * Since: 1.22
+ */
+gboolean
+gst_webrtc_data_channel_send_string_full (GstWebRTCDataChannel * channel,
+ const gchar * str, GError ** error)
+{
+ GstWebRTCDataChannelClass *klass;
+
+ g_return_val_if_fail (GST_IS_WEBRTC_DATA_CHANNEL (channel), FALSE);
+
+ klass = GST_WEBRTC_DATA_CHANNEL_GET_CLASS (channel);
+ return klass->send_string (channel, str, error);
}
/**
#define GST_WEBRTC_DATA_CHANNEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_WEBRTC_DATA_CHANNEL,GstWebRTCDataChannelClass))
GST_WEBRTC_API
-void gst_webrtc_data_channel_send_data (GstWebRTCDataChannel * channel, GBytes * data);
+gboolean gst_webrtc_data_channel_send_data_full (GstWebRTCDataChannel * channel, GBytes * data, GError ** error);
GST_WEBRTC_API
-void gst_webrtc_data_channel_send_string (GstWebRTCDataChannel * channel, const gchar * str);
+gboolean gst_webrtc_data_channel_send_string_full (GstWebRTCDataChannel * channel, const gchar * str, GError ** error);
GST_WEBRTC_API
void gst_webrtc_data_channel_close (GstWebRTCDataChannel * channel);
+#ifndef GST_REMOVE_DEPRECATED
+GST_WEBRTC_DEPRECATED_FOR(gst_webrtc_data_channel_send_data_full)
+void gst_webrtc_data_channel_send_data (GstWebRTCDataChannel * channel, GBytes * data);
+
+GST_WEBRTC_DEPRECATED_FOR(gst_webrtc_data_channel_send_string_full)
+void gst_webrtc_data_channel_send_string (GstWebRTCDataChannel * channel, const gchar * str);
+#endif
+
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstWebRTCDataChannel, g_object_unref)
G_END_DECLS
{
GObjectClass parent_class;
- void (*send_data) (GstWebRTCDataChannel * channel, GBytes *data);
- void (*send_string) (GstWebRTCDataChannel * channel, const gchar *str);
+ gboolean (*send_data) (GstWebRTCDataChannel * channel, GBytes *data, GError ** error);
+ gboolean (*send_string) (GstWebRTCDataChannel * channel, const gchar *str, GError ** error);
void (*close) (GstWebRTCDataChannel * channel);
gpointer _padding[GST_PADDING];
# endif
#endif
+/**
+ * GST_WEBRTC_DEPRECATED: (attributes doc.skip=true)
+ */
+/**
+ * GST_WEBRTC_DEPRECATED_FOR: (attributes doc.skip=true)
+ */
+#ifndef GST_DISABLE_DEPRECATED
+#define GST_WEBRTC_DEPRECATED GST_WEBRTC_API
+#define GST_WEBRTC_DEPRECATED_FOR(f) GST_WEBRTC_API
+#else
+#define GST_WEBRTC_DEPRECATED G_DEPRECATED GST_WEBRTC_API
+#define GST_WEBRTC_DEPRECATED_FOR(f) G_DEPRECATED_FOR(f) GST_WEBRTC_API
+#endif
+
#include <gst/webrtc/webrtc-enumtypes.h>
/**
* Since: 1.20
*/
/**
+ * GST_WEBRTC_ERROR_TYPE_ERROR:
+ *
+ * type-error (maps to JavaScript TypeError)
+ *
+ * Since: 1.22
+ */
+/**
* GST_WEBRTC_ERROR_INVALID_MODIFICATION:
*
* invalid-modification (part of WebIDL specification)
GST_WEBRTC_ERROR_HARDWARE_ENCODER_NOT_AVAILABLE,
GST_WEBRTC_ERROR_ENCODER_ERROR,
GST_WEBRTC_ERROR_INVALID_STATE,
+ GST_WEBRTC_ERROR_TYPE_ERROR,
GST_WEBRTC_ERROR_INTERNAL_FAILURE,
GST_WEBRTC_ERROR_INVALID_MODIFICATION,
} GstWebRTCError;
{
GObject *other = user_data;
GstWebRTCDataChannelState state;
+ GError *error = NULL;
g_object_get (our, "ready-state", &state, NULL);
fail_unless_equals_int (GST_WEBRTC_DATA_CHANNEL_STATE_OPEN, state);
g_object_set_data_full (our, "expected", g_strdup (test_string), g_free);
- g_signal_emit_by_name (other, "send-string", test_string);
+ fail_unless (gst_webrtc_data_channel_send_string_full (GST_WEBRTC_DATA_CHANNEL
+ (other), test_string, &error));
+ g_assert_null (error);
}
GST_START_TEST (test_data_channel_transfer_string)
GObject *other = user_data;
GBytes *data = g_bytes_new_static (test_string, strlen (test_string));
GstWebRTCDataChannelState state;
+ GError *error = NULL;
g_object_get (our, "ready-state", &state, NULL);
fail_unless_equals_int (GST_WEBRTC_DATA_CHANNEL_STATE_OPEN, state);
g_object_set_data_full (our, "expected", g_bytes_ref (data),
(GDestroyNotify) g_bytes_unref);
- g_signal_emit_by_name (other, "send-data", data);
+ fail_unless (gst_webrtc_data_channel_send_data_full (GST_WEBRTC_DATA_CHANNEL
+ (other), data, &error));
+ g_assert_null (error);
g_bytes_unref (data);
}
g_signal_connect (our, "on-error", G_CALLBACK (on_channel_error_not_reached),
NULL);
- g_signal_emit_by_name (our, "send-string", "A");
+ gst_webrtc_data_channel_send_string_full (GST_WEBRTC_DATA_CHANNEL (our), "A",
+ NULL);
}
GST_START_TEST (test_data_channel_low_threshold)
GST_END_TEST;
static void
-on_channel_error (GObject * channel, GError * error, struct test_webrtc *t)
-{
- g_assert_nonnull (error);
-
- test_webrtc_signal_state (t, STATE_CUSTOM);
-}
-
-static void
have_data_channel_transfer_large_data (struct test_webrtc *t,
GstElement * element, GObject * our, gpointer user_data)
{
guint8 *random_data = g_new (guint8, size);
GBytes *data;
gsize i;
+ GError *error = NULL;
for (i = 0; i < size; i++)
random_data[i] = (guint8) (i & 0xff);
(GDestroyNotify) g_bytes_unref);
g_signal_connect (our, "on-message-data", G_CALLBACK (on_message_data), t);
- g_signal_connect (other, "on-error", G_CALLBACK (on_channel_error), t);
- g_signal_emit_by_name (other, "send-data", data);
+ g_signal_connect (other, "on-error",
+ G_CALLBACK (on_channel_error_not_reached), NULL);
+ fail_if (gst_webrtc_data_channel_send_data_full (GST_WEBRTC_DATA_CHANNEL
+ (other), data, &error));
+ g_assert_nonnull (error);
+ g_clear_error (&error);
g_bytes_unref (data);
+
+ test_webrtc_signal_state_unlocked (t, STATE_CUSTOM);
}
GST_START_TEST (test_data_channel_max_message_size)