mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
webrtc: Add GstWebRTCDataChannel to the library API
This makes it more discoverable for bindings and allows bindings to generate static API for the signals and functions. Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/issues/1168 Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1313>
This commit is contained in:
parent
a4d900332b
commit
b25d153c34
8 changed files with 864 additions and 551 deletions
|
@ -545,17 +545,17 @@ _find_pad (GstWebRTCBin * webrtc, gconstpointer data, FindPadFunc func)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
typedef gboolean (*FindDataChannelFunc) (GstWebRTCDataChannel * p1,
|
||||
typedef gboolean (*FindDataChannelFunc) (WebRTCDataChannel * p1,
|
||||
gconstpointer data);
|
||||
|
||||
static GstWebRTCDataChannel *
|
||||
static WebRTCDataChannel *
|
||||
_find_data_channel (GstWebRTCBin * webrtc, gconstpointer data,
|
||||
FindDataChannelFunc func)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < webrtc->priv->data_channels->len; i++) {
|
||||
GstWebRTCDataChannel *channel =
|
||||
WebRTCDataChannel *channel =
|
||||
g_ptr_array_index (webrtc->priv->data_channels, i);
|
||||
|
||||
if (func (channel, data))
|
||||
|
@ -566,15 +566,15 @@ _find_data_channel (GstWebRTCBin * webrtc, gconstpointer data,
|
|||
}
|
||||
|
||||
static gboolean
|
||||
data_channel_match_for_id (GstWebRTCDataChannel * channel, gint * id)
|
||||
data_channel_match_for_id (WebRTCDataChannel * channel, gint * id)
|
||||
{
|
||||
return channel->id == *id;
|
||||
return channel->parent.id == *id;
|
||||
}
|
||||
|
||||
static GstWebRTCDataChannel *
|
||||
static WebRTCDataChannel *
|
||||
_find_data_channel_for_id (GstWebRTCBin * webrtc, gint id)
|
||||
{
|
||||
GstWebRTCDataChannel *channel;
|
||||
WebRTCDataChannel *channel;
|
||||
|
||||
channel = _find_data_channel (webrtc, &id,
|
||||
(FindDataChannelFunc) data_channel_match_for_id);
|
||||
|
@ -1737,7 +1737,7 @@ _get_or_create_rtp_transport_channel (GstWebRTCBin * webrtc, guint session_id)
|
|||
|
||||
/* this is called from the webrtc thread with the pc lock held */
|
||||
static void
|
||||
_on_data_channel_ready_state (GstWebRTCDataChannel * channel,
|
||||
_on_data_channel_ready_state (WebRTCDataChannel * channel,
|
||||
GParamSpec * pspec, GstWebRTCBin * webrtc)
|
||||
{
|
||||
GstWebRTCDataChannelState ready_state;
|
||||
|
@ -1749,7 +1749,7 @@ _on_data_channel_ready_state (GstWebRTCDataChannel * channel,
|
|||
gboolean found = FALSE;
|
||||
|
||||
for (i = 0; i < webrtc->priv->pending_data_channels->len; i++) {
|
||||
GstWebRTCDataChannel *c;
|
||||
WebRTCDataChannel *c;
|
||||
|
||||
c = g_ptr_array_index (webrtc->priv->pending_data_channels, i);
|
||||
if (c == channel) {
|
||||
|
@ -1774,7 +1774,7 @@ static void
|
|||
_on_sctpdec_pad_added (GstElement * sctpdec, GstPad * pad,
|
||||
GstWebRTCBin * webrtc)
|
||||
{
|
||||
GstWebRTCDataChannel *channel;
|
||||
WebRTCDataChannel *channel;
|
||||
guint stream_id;
|
||||
GstPad *sink_pad;
|
||||
|
||||
|
@ -1784,8 +1784,8 @@ _on_sctpdec_pad_added (GstElement * sctpdec, GstPad * pad,
|
|||
PC_LOCK (webrtc);
|
||||
channel = _find_data_channel_for_id (webrtc, stream_id);
|
||||
if (!channel) {
|
||||
channel = g_object_new (GST_TYPE_WEBRTC_DATA_CHANNEL, NULL);
|
||||
channel->id = stream_id;
|
||||
channel = g_object_new (WEBRTC_TYPE_DATA_CHANNEL, NULL);
|
||||
channel->parent.id = stream_id;
|
||||
channel->webrtcbin = webrtc;
|
||||
|
||||
gst_bin_add (GST_BIN (webrtc), channel->appsrc);
|
||||
|
@ -1794,8 +1794,7 @@ _on_sctpdec_pad_added (GstElement * sctpdec, GstPad * pad,
|
|||
gst_element_sync_state_with_parent (channel->appsrc);
|
||||
gst_element_sync_state_with_parent (channel->appsink);
|
||||
|
||||
gst_webrtc_data_channel_link_to_sctp (channel,
|
||||
webrtc->priv->sctp_transport);
|
||||
webrtc_data_channel_link_to_sctp (channel, webrtc->priv->sctp_transport);
|
||||
|
||||
g_ptr_array_add (webrtc->priv->pending_data_channels, channel);
|
||||
}
|
||||
|
@ -1826,15 +1825,14 @@ _on_sctp_state_notify (GstWebRTCSCTPTransport * sctp, GParamSpec * pspec,
|
|||
GST_DEBUG_OBJECT (webrtc, "SCTP association established");
|
||||
|
||||
for (i = 0; i < webrtc->priv->data_channels->len; i++) {
|
||||
GstWebRTCDataChannel *channel;
|
||||
WebRTCDataChannel *channel;
|
||||
|
||||
channel = g_ptr_array_index (webrtc->priv->data_channels, i);
|
||||
|
||||
gst_webrtc_data_channel_link_to_sctp (channel,
|
||||
webrtc->priv->sctp_transport);
|
||||
webrtc_data_channel_link_to_sctp (channel, webrtc->priv->sctp_transport);
|
||||
|
||||
if (!channel->negotiated && !channel->opened)
|
||||
gst_webrtc_data_channel_start_negotiation (channel);
|
||||
if (!channel->parent.negotiated && !channel->opened)
|
||||
webrtc_data_channel_start_negotiation (channel);
|
||||
}
|
||||
PC_UNLOCK (webrtc);
|
||||
}
|
||||
|
@ -1993,12 +1991,11 @@ _get_or_create_data_channel_transports (GstWebRTCBin * webrtc, guint session_id)
|
|||
g_warn_if_reached ();
|
||||
|
||||
for (i = 0; i < webrtc->priv->data_channels->len; i++) {
|
||||
GstWebRTCDataChannel *channel;
|
||||
WebRTCDataChannel *channel;
|
||||
|
||||
channel = g_ptr_array_index (webrtc->priv->data_channels, i);
|
||||
|
||||
gst_webrtc_data_channel_link_to_sctp (channel,
|
||||
webrtc->priv->sctp_transport);
|
||||
webrtc_data_channel_link_to_sctp (channel, webrtc->priv->sctp_transport);
|
||||
}
|
||||
|
||||
gst_element_sync_state_with_parent (GST_ELEMENT (stream->send_bin));
|
||||
|
@ -4001,7 +3998,7 @@ _generate_data_channel_id (GstWebRTCBin * webrtc)
|
|||
|
||||
/* TODO: a better search algorithm */
|
||||
do {
|
||||
GstWebRTCDataChannel *channel;
|
||||
WebRTCDataChannel *channel;
|
||||
|
||||
new_id++;
|
||||
|
||||
|
@ -4087,21 +4084,20 @@ _update_data_channel_from_sdp_media (GstWebRTCBin * webrtc,
|
|||
}
|
||||
|
||||
for (i = 0; i < webrtc->priv->data_channels->len; i++) {
|
||||
GstWebRTCDataChannel *channel;
|
||||
WebRTCDataChannel *channel;
|
||||
|
||||
channel = g_ptr_array_index (webrtc->priv->data_channels, i);
|
||||
|
||||
if (channel->id == -1)
|
||||
channel->id = _generate_data_channel_id (webrtc);
|
||||
if (channel->id == -1)
|
||||
if (channel->parent.id == -1)
|
||||
channel->parent.id = _generate_data_channel_id (webrtc);
|
||||
if (channel->parent.id == -1)
|
||||
GST_ELEMENT_WARNING (webrtc, RESOURCE, NOT_FOUND,
|
||||
("%s", "Failed to generate an identifier for a data channel"), NULL);
|
||||
|
||||
if (webrtc->priv->sctp_transport->association_established
|
||||
&& !channel->negotiated && !channel->opened) {
|
||||
gst_webrtc_data_channel_link_to_sctp (channel,
|
||||
webrtc->priv->sctp_transport);
|
||||
gst_webrtc_data_channel_start_negotiation (channel);
|
||||
&& !channel->parent.negotiated && !channel->opened) {
|
||||
webrtc_data_channel_link_to_sctp (channel, webrtc->priv->sctp_transport);
|
||||
webrtc_data_channel_start_negotiation (channel);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5049,7 +5045,7 @@ copy_sticky_events (GstPad * pad, GstEvent ** event, gpointer user_data)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static GstWebRTCDataChannel *
|
||||
static WebRTCDataChannel *
|
||||
gst_webrtc_bin_create_data_channel (GstWebRTCBin * webrtc, const gchar * label,
|
||||
GstStructure * init_params)
|
||||
{
|
||||
|
@ -5060,7 +5056,7 @@ gst_webrtc_bin_create_data_channel (GstWebRTCBin * webrtc, const gchar * label,
|
|||
gboolean negotiated;
|
||||
gint id;
|
||||
GstWebRTCPriorityType priority;
|
||||
GstWebRTCDataChannel *ret;
|
||||
WebRTCDataChannel *ret;
|
||||
gint max_channels = 65534;
|
||||
|
||||
g_return_val_if_fail (GST_IS_WEBRTC_BIN (webrtc), NULL);
|
||||
|
@ -5125,7 +5121,7 @@ gst_webrtc_bin_create_data_channel (GstWebRTCBin * webrtc, const gchar * label,
|
|||
PC_LOCK (webrtc);
|
||||
/* check if the id has been used already */
|
||||
if (id != -1) {
|
||||
GstWebRTCDataChannel *channel = _find_data_channel_for_id (webrtc, id);
|
||||
WebRTCDataChannel *channel = _find_data_channel_for_id (webrtc, id);
|
||||
if (channel) {
|
||||
GST_ELEMENT_WARNING (webrtc, LIBRARY, SETTINGS,
|
||||
("Attempting to add a data channel with a duplicate ID: %i", id),
|
||||
|
@ -5147,7 +5143,7 @@ gst_webrtc_bin_create_data_channel (GstWebRTCBin * webrtc, const gchar * label,
|
|||
}
|
||||
}
|
||||
|
||||
ret = g_object_new (GST_TYPE_WEBRTC_DATA_CHANNEL, "label", label,
|
||||
ret = g_object_new (WEBRTC_TYPE_DATA_CHANNEL, "label", label,
|
||||
"ordered", ordered, "max-packet-lifetime", max_packet_lifetime,
|
||||
"max-retransmits", max_retransmits, "protocol", protocol,
|
||||
"negotiated", negotiated, "id", id, "priority", priority, NULL);
|
||||
|
@ -5162,11 +5158,11 @@ gst_webrtc_bin_create_data_channel (GstWebRTCBin * webrtc, const gchar * label,
|
|||
ret = gst_object_ref (ret);
|
||||
ret->webrtcbin = webrtc;
|
||||
g_ptr_array_add (webrtc->priv->data_channels, ret);
|
||||
gst_webrtc_data_channel_link_to_sctp (ret, webrtc->priv->sctp_transport);
|
||||
webrtc_data_channel_link_to_sctp (ret, webrtc->priv->sctp_transport);
|
||||
if (webrtc->priv->sctp_transport &&
|
||||
webrtc->priv->sctp_transport->association_established
|
||||
&& !ret->negotiated) {
|
||||
gst_webrtc_data_channel_start_negotiation (ret);
|
||||
&& !ret->parent.negotiated) {
|
||||
webrtc_data_channel_start_negotiation (ret);
|
||||
} else {
|
||||
_update_need_negotiation (webrtc);
|
||||
}
|
||||
|
|
|
@ -41,49 +41,14 @@
|
|||
#include "gstwebrtcbin.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define GST_CAT_DEFAULT gst_webrtc_data_channel_debug
|
||||
#define GST_CAT_DEFAULT webrtc_data_channel_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
|
||||
#define gst_webrtc_data_channel_parent_class parent_class
|
||||
G_DEFINE_TYPE_WITH_CODE (GstWebRTCDataChannel, gst_webrtc_data_channel,
|
||||
G_TYPE_OBJECT, GST_DEBUG_CATEGORY_INIT (gst_webrtc_data_channel_debug,
|
||||
"webrtcdatachannel", 0, "webrtcdatachannel"););
|
||||
|
||||
#define CHANNEL_LOCK(channel) g_mutex_lock(&channel->lock)
|
||||
#define CHANNEL_UNLOCK(channel) g_mutex_unlock(&channel->lock)
|
||||
|
||||
enum
|
||||
{
|
||||
SIGNAL_0,
|
||||
SIGNAL_ON_OPEN,
|
||||
SIGNAL_ON_CLOSE,
|
||||
SIGNAL_ON_ERROR,
|
||||
SIGNAL_ON_MESSAGE_DATA,
|
||||
SIGNAL_ON_MESSAGE_STRING,
|
||||
SIGNAL_ON_BUFFERED_AMOUNT_LOW,
|
||||
SIGNAL_SEND_DATA,
|
||||
SIGNAL_SEND_STRING,
|
||||
SIGNAL_CLOSE,
|
||||
LAST_SIGNAL,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_LABEL,
|
||||
PROP_ORDERED,
|
||||
PROP_MAX_PACKET_LIFETIME,
|
||||
PROP_MAX_RETRANSMITS,
|
||||
PROP_PROTOCOL,
|
||||
PROP_NEGOTIATED,
|
||||
PROP_ID,
|
||||
PROP_PRIORITY,
|
||||
PROP_READY_STATE,
|
||||
PROP_BUFFERED_AMOUNT,
|
||||
PROP_BUFFERED_AMOUNT_LOW_THRESHOLD,
|
||||
};
|
||||
|
||||
static guint gst_webrtc_data_channel_signals[LAST_SIGNAL] = { 0 };
|
||||
#define webrtc_data_channel_parent_class parent_class
|
||||
G_DEFINE_TYPE_WITH_CODE (WebRTCDataChannel, webrtc_data_channel,
|
||||
GST_TYPE_WEBRTC_DATA_CHANNEL,
|
||||
GST_DEBUG_CATEGORY_INIT (webrtc_data_channel_debug, "webrtcdatachannel", 0,
|
||||
"webrtcdatachannel"););
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
@ -142,11 +107,11 @@ priority_uint_to_type (guint16 val)
|
|||
}
|
||||
|
||||
static GstBuffer *
|
||||
construct_open_packet (GstWebRTCDataChannel * channel)
|
||||
construct_open_packet (WebRTCDataChannel * channel)
|
||||
{
|
||||
GstByteWriter w;
|
||||
gsize label_len = strlen (channel->label);
|
||||
gsize proto_len = strlen (channel->protocol);
|
||||
gsize label_len = strlen (channel->parent.label);
|
||||
gsize proto_len = strlen (channel->parent.protocol);
|
||||
gsize size = 12 + label_len + proto_len;
|
||||
DataChannelReliabilityType reliability = 0;
|
||||
guint32 reliability_param = 0;
|
||||
|
@ -178,18 +143,18 @@ construct_open_packet (GstWebRTCDataChannel * channel)
|
|||
if (!gst_byte_writer_put_uint8 (&w, (guint8) CHANNEL_MESSAGE_OPEN))
|
||||
g_return_val_if_reached (NULL);
|
||||
|
||||
if (!channel->ordered)
|
||||
if (!channel->parent.ordered)
|
||||
reliability |= 0x80;
|
||||
if (channel->max_retransmits != -1) {
|
||||
if (channel->parent.max_retransmits != -1) {
|
||||
reliability |= 0x01;
|
||||
reliability_param = channel->max_retransmits;
|
||||
reliability_param = channel->parent.max_retransmits;
|
||||
}
|
||||
if (channel->max_packet_lifetime != -1) {
|
||||
if (channel->parent.max_packet_lifetime != -1) {
|
||||
reliability |= 0x02;
|
||||
reliability_param = channel->max_packet_lifetime;
|
||||
reliability_param = channel->parent.max_packet_lifetime;
|
||||
}
|
||||
|
||||
priority = priority_type_to_uint (channel->priority);
|
||||
priority = priority_type_to_uint (channel->parent.priority);
|
||||
|
||||
if (!gst_byte_writer_put_uint8 (&w, (guint8) reliability))
|
||||
g_return_val_if_reached (NULL);
|
||||
|
@ -201,9 +166,11 @@ construct_open_packet (GstWebRTCDataChannel * channel)
|
|||
g_return_val_if_reached (NULL);
|
||||
if (!gst_byte_writer_put_uint16_be (&w, (guint16) proto_len))
|
||||
g_return_val_if_reached (NULL);
|
||||
if (!gst_byte_writer_put_data (&w, (guint8 *) channel->label, label_len))
|
||||
if (!gst_byte_writer_put_data (&w, (guint8 *) channel->parent.label,
|
||||
label_len))
|
||||
g_return_val_if_reached (NULL);
|
||||
if (!gst_byte_writer_put_data (&w, (guint8 *) channel->protocol, proto_len))
|
||||
if (!gst_byte_writer_put_data (&w, (guint8 *) channel->parent.protocol,
|
||||
proto_len))
|
||||
g_return_val_if_reached (NULL);
|
||||
|
||||
buf = gst_byte_writer_reset_and_get_buffer (&w);
|
||||
|
@ -216,7 +183,7 @@ construct_open_packet (GstWebRTCDataChannel * channel)
|
|||
}
|
||||
|
||||
static GstBuffer *
|
||||
construct_ack_packet (GstWebRTCDataChannel * channel)
|
||||
construct_ack_packet (WebRTCDataChannel * channel)
|
||||
{
|
||||
GstByteWriter w;
|
||||
GstBuffer *buf;
|
||||
|
@ -272,7 +239,7 @@ _free_task (struct task *task)
|
|||
}
|
||||
|
||||
static void
|
||||
_channel_enqueue_task (GstWebRTCDataChannel * channel, ChannelTask func,
|
||||
_channel_enqueue_task (WebRTCDataChannel * channel, ChannelTask func,
|
||||
gpointer user_data, GDestroyNotify notify)
|
||||
{
|
||||
struct task *task = g_new0 (struct task, 1);
|
||||
|
@ -288,9 +255,9 @@ _channel_enqueue_task (GstWebRTCDataChannel * channel, ChannelTask func,
|
|||
}
|
||||
|
||||
static void
|
||||
_channel_store_error (GstWebRTCDataChannel * channel, GError * error)
|
||||
_channel_store_error (WebRTCDataChannel * channel, GError * error)
|
||||
{
|
||||
CHANNEL_LOCK (channel);
|
||||
GST_WEBRTC_DATA_CHANNEL_LOCK (channel);
|
||||
if (error) {
|
||||
GST_WARNING_OBJECT (channel, "Error: %s",
|
||||
error ? error->message : "Unknown");
|
||||
|
@ -299,76 +266,32 @@ _channel_store_error (GstWebRTCDataChannel * channel, GError * error)
|
|||
else
|
||||
g_clear_error (&error);
|
||||
}
|
||||
CHANNEL_UNLOCK (channel);
|
||||
GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
|
||||
}
|
||||
|
||||
static void
|
||||
_maybe_emit_on_error (GstWebRTCDataChannel * channel, GError * error)
|
||||
_emit_on_open (WebRTCDataChannel * channel, gpointer user_data)
|
||||
{
|
||||
if (error) {
|
||||
GST_WARNING_OBJECT (channel, "error thrown");
|
||||
g_signal_emit (channel, gst_webrtc_data_channel_signals[SIGNAL_ON_ERROR], 0,
|
||||
error);
|
||||
}
|
||||
gst_webrtc_data_channel_on_open (GST_WEBRTC_DATA_CHANNEL (channel));
|
||||
}
|
||||
|
||||
static void
|
||||
_emit_on_open (GstWebRTCDataChannel * channel, gpointer user_data)
|
||||
{
|
||||
CHANNEL_LOCK (channel);
|
||||
if (channel->ready_state == GST_WEBRTC_DATA_CHANNEL_STATE_CLOSING ||
|
||||
channel->ready_state == GST_WEBRTC_DATA_CHANNEL_STATE_CLOSED) {
|
||||
CHANNEL_UNLOCK (channel);
|
||||
return;
|
||||
}
|
||||
|
||||
if (channel->ready_state != GST_WEBRTC_DATA_CHANNEL_STATE_OPEN) {
|
||||
channel->ready_state = GST_WEBRTC_DATA_CHANNEL_STATE_OPEN;
|
||||
CHANNEL_UNLOCK (channel);
|
||||
g_object_notify (G_OBJECT (channel), "ready-state");
|
||||
|
||||
GST_INFO_OBJECT (channel, "We are open and ready for data!");
|
||||
g_signal_emit (channel, gst_webrtc_data_channel_signals[SIGNAL_ON_OPEN], 0,
|
||||
NULL);
|
||||
} else {
|
||||
CHANNEL_UNLOCK (channel);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_transport_closed_unlocked (GstWebRTCDataChannel * channel)
|
||||
_transport_closed (WebRTCDataChannel * channel)
|
||||
{
|
||||
GError *error;
|
||||
|
||||
if (channel->ready_state == GST_WEBRTC_DATA_CHANNEL_STATE_CLOSED)
|
||||
return;
|
||||
|
||||
channel->ready_state = GST_WEBRTC_DATA_CHANNEL_STATE_CLOSED;
|
||||
|
||||
GST_WEBRTC_DATA_CHANNEL_LOCK (channel);
|
||||
error = channel->stored_error;
|
||||
channel->stored_error = NULL;
|
||||
CHANNEL_UNLOCK (channel);
|
||||
GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
|
||||
|
||||
g_object_notify (G_OBJECT (channel), "ready-state");
|
||||
GST_INFO_OBJECT (channel, "We are closed for data");
|
||||
|
||||
_maybe_emit_on_error (channel, error);
|
||||
|
||||
g_signal_emit (channel, gst_webrtc_data_channel_signals[SIGNAL_ON_CLOSE], 0,
|
||||
NULL);
|
||||
CHANNEL_LOCK (channel);
|
||||
if (error)
|
||||
gst_webrtc_data_channel_on_error (GST_WEBRTC_DATA_CHANNEL (channel), error);
|
||||
gst_webrtc_data_channel_on_close (GST_WEBRTC_DATA_CHANNEL (channel));
|
||||
}
|
||||
|
||||
static void
|
||||
_transport_closed (GstWebRTCDataChannel * channel, gpointer user_data)
|
||||
{
|
||||
CHANNEL_LOCK (channel);
|
||||
_transport_closed_unlocked (channel);
|
||||
CHANNEL_UNLOCK (channel);
|
||||
}
|
||||
|
||||
static void
|
||||
_close_sctp_stream (GstWebRTCDataChannel * channel, gpointer user_data)
|
||||
_close_sctp_stream (WebRTCDataChannel * channel, gpointer user_data)
|
||||
{
|
||||
GstPad *pad, *peer;
|
||||
|
||||
|
@ -386,49 +309,49 @@ _close_sctp_stream (GstWebRTCDataChannel * channel, gpointer user_data)
|
|||
gst_object_unref (peer);
|
||||
}
|
||||
|
||||
_transport_closed (channel, NULL);
|
||||
_transport_closed (channel);
|
||||
}
|
||||
|
||||
static void
|
||||
_close_procedure (GstWebRTCDataChannel * channel, gpointer user_data)
|
||||
_close_procedure (WebRTCDataChannel * channel, gpointer user_data)
|
||||
{
|
||||
/* https://www.w3.org/TR/webrtc/#data-transport-closing-procedure */
|
||||
CHANNEL_LOCK (channel);
|
||||
if (channel->ready_state == GST_WEBRTC_DATA_CHANNEL_STATE_CLOSED
|
||||
|| channel->ready_state == GST_WEBRTC_DATA_CHANNEL_STATE_CLOSING) {
|
||||
CHANNEL_UNLOCK (channel);
|
||||
GST_WEBRTC_DATA_CHANNEL_LOCK (channel);
|
||||
if (channel->parent.ready_state == GST_WEBRTC_DATA_CHANNEL_STATE_CLOSED
|
||||
|| channel->parent.ready_state == GST_WEBRTC_DATA_CHANNEL_STATE_CLOSING) {
|
||||
GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
|
||||
return;
|
||||
}
|
||||
channel->ready_state = GST_WEBRTC_DATA_CHANNEL_STATE_CLOSING;
|
||||
CHANNEL_UNLOCK (channel);
|
||||
channel->parent.ready_state = GST_WEBRTC_DATA_CHANNEL_STATE_CLOSING;
|
||||
GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
|
||||
g_object_notify (G_OBJECT (channel), "ready-state");
|
||||
|
||||
CHANNEL_LOCK (channel);
|
||||
if (channel->buffered_amount <= 0) {
|
||||
GST_WEBRTC_DATA_CHANNEL_LOCK (channel);
|
||||
if (channel->parent.buffered_amount <= 0) {
|
||||
_channel_enqueue_task (channel, (ChannelTask) _close_sctp_stream,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
CHANNEL_UNLOCK (channel);
|
||||
GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
|
||||
}
|
||||
|
||||
static void
|
||||
_on_sctp_reset_stream (GstWebRTCSCTPTransport * sctp, guint stream_id,
|
||||
GstWebRTCDataChannel * channel)
|
||||
WebRTCDataChannel * channel)
|
||||
{
|
||||
if (channel->id == stream_id)
|
||||
if (channel->parent.id == stream_id)
|
||||
_channel_enqueue_task (channel, (ChannelTask) _transport_closed,
|
||||
GUINT_TO_POINTER (stream_id), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_webrtc_data_channel_close (GstWebRTCDataChannel * channel)
|
||||
webrtc_data_channel_close (GstWebRTCDataChannel * channel)
|
||||
{
|
||||
_close_procedure (channel, NULL);
|
||||
_close_procedure (WEBRTC_DATA_CHANNEL (channel), NULL);
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
_parse_control_packet (GstWebRTCDataChannel * channel, guint8 * data,
|
||||
_parse_control_packet (WebRTCDataChannel * channel, guint8 * data,
|
||||
gsize size, GError ** error)
|
||||
{
|
||||
GstByteReader r;
|
||||
|
@ -460,7 +383,7 @@ _parse_control_packet (GstWebRTCDataChannel * channel, guint8 * data,
|
|||
|
||||
GST_INFO_OBJECT (channel, "Received channel open");
|
||||
|
||||
if (channel->negotiated) {
|
||||
if (channel->parent.negotiated) {
|
||||
g_set_error (error, GST_WEBRTC_BIN_ERROR,
|
||||
GST_WEBRTC_BIN_ERROR_DATA_CHANNEL_FAILURE,
|
||||
"Data channel was signalled as negotiated already");
|
||||
|
@ -493,34 +416,35 @@ _parse_control_packet (GstWebRTCDataChannel * channel, guint8 * data,
|
|||
memcpy (proto, src, proto_len);
|
||||
proto[proto_len] = '\0';
|
||||
|
||||
channel->label = label;
|
||||
channel->protocol = proto;
|
||||
channel->priority = priority_uint_to_type (priority);
|
||||
channel->ordered = !(reliability & 0x80);
|
||||
channel->parent.label = label;
|
||||
channel->parent.protocol = proto;
|
||||
channel->parent.priority = priority_uint_to_type (priority);
|
||||
channel->parent.ordered = !(reliability & 0x80);
|
||||
if (reliability & 0x01) {
|
||||
channel->max_retransmits = reliability_param;
|
||||
channel->max_packet_lifetime = -1;
|
||||
channel->parent.max_retransmits = reliability_param;
|
||||
channel->parent.max_packet_lifetime = -1;
|
||||
} else if (reliability & 0x02) {
|
||||
channel->max_retransmits = -1;
|
||||
channel->max_packet_lifetime = reliability_param;
|
||||
channel->parent.max_retransmits = -1;
|
||||
channel->parent.max_packet_lifetime = reliability_param;
|
||||
} else {
|
||||
channel->max_retransmits = -1;
|
||||
channel->max_packet_lifetime = -1;
|
||||
channel->parent.max_retransmits = -1;
|
||||
channel->parent.max_packet_lifetime = -1;
|
||||
}
|
||||
channel->opened = TRUE;
|
||||
|
||||
GST_INFO_OBJECT (channel, "Received channel open for SCTP stream %i "
|
||||
"label %s protocol %s ordered %s", channel->id, channel->label,
|
||||
channel->protocol, channel->ordered ? "true" : "false");
|
||||
"label %s protocol %s ordered %s", channel->parent.id,
|
||||
channel->parent.label, channel->parent.protocol,
|
||||
channel->parent.ordered ? "true" : "false");
|
||||
|
||||
_channel_enqueue_task (channel, (ChannelTask) _emit_on_open, NULL, NULL);
|
||||
|
||||
GST_INFO_OBJECT (channel, "Sending channel ack");
|
||||
buffer = construct_ack_packet (channel);
|
||||
|
||||
CHANNEL_LOCK (channel);
|
||||
channel->buffered_amount += gst_buffer_get_size (buffer);
|
||||
CHANNEL_UNLOCK (channel);
|
||||
GST_WEBRTC_DATA_CHANNEL_LOCK (channel);
|
||||
channel->parent.buffered_amount += gst_buffer_get_size (buffer);
|
||||
GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
|
||||
|
||||
ret = gst_app_src_push_buffer (GST_APP_SRC (channel->appsrc), buffer);
|
||||
if (ret != GST_FLOW_OK) {
|
||||
|
@ -568,23 +492,21 @@ buffer_unmap_and_unref (struct map_info *info)
|
|||
}
|
||||
|
||||
static void
|
||||
_emit_have_data (GstWebRTCDataChannel * channel, GBytes * data)
|
||||
_emit_have_data (WebRTCDataChannel * channel, GBytes * data)
|
||||
{
|
||||
GST_LOG_OBJECT (channel, "Have data %p", data);
|
||||
g_signal_emit (channel,
|
||||
gst_webrtc_data_channel_signals[SIGNAL_ON_MESSAGE_DATA], 0, data);
|
||||
gst_webrtc_data_channel_on_message_data (GST_WEBRTC_DATA_CHANNEL (channel),
|
||||
data);
|
||||
}
|
||||
|
||||
static void
|
||||
_emit_have_string (GstWebRTCDataChannel * channel, gchar * str)
|
||||
{
|
||||
GST_LOG_OBJECT (channel, "Have string %p", str);
|
||||
g_signal_emit (channel,
|
||||
gst_webrtc_data_channel_signals[SIGNAL_ON_MESSAGE_STRING], 0, str);
|
||||
gst_webrtc_data_channel_on_message_string (GST_WEBRTC_DATA_CHANNEL (channel),
|
||||
str);
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
_data_channel_have_sample (GstWebRTCDataChannel * channel, GstSample * sample,
|
||||
_data_channel_have_sample (WebRTCDataChannel * channel, GstSample * sample,
|
||||
GError ** error)
|
||||
{
|
||||
GstSctpReceiveMeta *receive;
|
||||
|
@ -678,7 +600,7 @@ _data_channel_have_sample (GstWebRTCDataChannel * channel, GstSample * sample,
|
|||
static GstFlowReturn
|
||||
on_sink_preroll (GstAppSink * sink, gpointer user_data)
|
||||
{
|
||||
GstWebRTCDataChannel *channel = user_data;
|
||||
WebRTCDataChannel *channel = user_data;
|
||||
GstSample *sample = gst_app_sink_pull_preroll (sink);
|
||||
GstFlowReturn ret;
|
||||
|
||||
|
@ -703,7 +625,7 @@ on_sink_preroll (GstAppSink * sink, gpointer user_data)
|
|||
static GstFlowReturn
|
||||
on_sink_sample (GstAppSink * sink, gpointer user_data)
|
||||
{
|
||||
GstWebRTCDataChannel *channel = user_data;
|
||||
WebRTCDataChannel *channel = user_data;
|
||||
GstSample *sample = gst_app_sink_pull_sample (sink);
|
||||
GstFlowReturn ret;
|
||||
GError *error = NULL;
|
||||
|
@ -734,23 +656,24 @@ static GstAppSinkCallbacks sink_callbacks = {
|
|||
};
|
||||
|
||||
void
|
||||
gst_webrtc_data_channel_start_negotiation (GstWebRTCDataChannel * channel)
|
||||
webrtc_data_channel_start_negotiation (WebRTCDataChannel * channel)
|
||||
{
|
||||
GstBuffer *buffer;
|
||||
|
||||
g_return_if_fail (!channel->negotiated);
|
||||
g_return_if_fail (channel->id != -1);
|
||||
g_return_if_fail (!channel->parent.negotiated);
|
||||
g_return_if_fail (channel->parent.id != -1);
|
||||
g_return_if_fail (channel->sctp_transport != NULL);
|
||||
|
||||
buffer = construct_open_packet (channel);
|
||||
|
||||
GST_INFO_OBJECT (channel, "Sending channel open for SCTP stream %i "
|
||||
"label %s protocol %s ordered %s", channel->id, channel->label,
|
||||
channel->protocol, channel->ordered ? "true" : "false");
|
||||
"label %s protocol %s ordered %s", channel->parent.id,
|
||||
channel->parent.label, channel->parent.protocol,
|
||||
channel->parent.ordered ? "true" : "false");
|
||||
|
||||
CHANNEL_LOCK (channel);
|
||||
channel->buffered_amount += gst_buffer_get_size (buffer);
|
||||
CHANNEL_UNLOCK (channel);
|
||||
GST_WEBRTC_DATA_CHANNEL_LOCK (channel);
|
||||
channel->parent.buffered_amount += gst_buffer_get_size (buffer);
|
||||
GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
|
||||
|
||||
if (gst_app_src_push_buffer (GST_APP_SRC (channel->appsrc),
|
||||
buffer) == GST_FLOW_OK) {
|
||||
|
@ -767,15 +690,15 @@ gst_webrtc_data_channel_start_negotiation (GstWebRTCDataChannel * channel)
|
|||
}
|
||||
|
||||
static void
|
||||
_get_sctp_reliability (GstWebRTCDataChannel * channel,
|
||||
_get_sctp_reliability (WebRTCDataChannel * channel,
|
||||
GstSctpSendMetaPartiallyReliability * reliability, guint * rel_param)
|
||||
{
|
||||
if (channel->max_retransmits != -1) {
|
||||
if (channel->parent.max_retransmits != -1) {
|
||||
*reliability = GST_SCTP_SEND_META_PARTIAL_RELIABILITY_RTX;
|
||||
*rel_param = channel->max_retransmits;
|
||||
} else if (channel->max_packet_lifetime != -1) {
|
||||
*rel_param = channel->parent.max_retransmits;
|
||||
} else if (channel->parent.max_packet_lifetime != -1) {
|
||||
*reliability = GST_SCTP_SEND_META_PARTIAL_RELIABILITY_TTL;
|
||||
*rel_param = channel->max_packet_lifetime;
|
||||
*rel_param = channel->parent.max_packet_lifetime;
|
||||
} else {
|
||||
*reliability = GST_SCTP_SEND_META_PARTIAL_RELIABILITY_NONE;
|
||||
*rel_param = 0;
|
||||
|
@ -783,15 +706,16 @@ _get_sctp_reliability (GstWebRTCDataChannel * channel,
|
|||
}
|
||||
|
||||
static gboolean
|
||||
_is_within_max_message_size (GstWebRTCDataChannel * channel, gsize size)
|
||||
_is_within_max_message_size (WebRTCDataChannel * channel, gsize size)
|
||||
{
|
||||
return size <= channel->sctp_transport->max_message_size;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_webrtc_data_channel_send_data (GstWebRTCDataChannel * channel,
|
||||
webrtc_data_channel_send_data (GstWebRTCDataChannel * base_channel,
|
||||
GBytes * bytes)
|
||||
{
|
||||
WebRTCDataChannel *channel = WEBRTC_DATA_CHANNEL (base_channel);
|
||||
GstSctpSendMetaPartiallyReliability reliability;
|
||||
guint rel_param;
|
||||
guint32 ppid;
|
||||
|
@ -824,15 +748,15 @@ gst_webrtc_data_channel_send_data (GstWebRTCDataChannel * channel,
|
|||
}
|
||||
|
||||
_get_sctp_reliability (channel, &reliability, &rel_param);
|
||||
gst_sctp_buffer_add_send_meta (buffer, ppid, channel->ordered, reliability,
|
||||
rel_param);
|
||||
gst_sctp_buffer_add_send_meta (buffer, ppid, channel->parent.ordered,
|
||||
reliability, rel_param);
|
||||
|
||||
GST_LOG_OBJECT (channel, "Sending data using buffer %" GST_PTR_FORMAT,
|
||||
buffer);
|
||||
|
||||
CHANNEL_LOCK (channel);
|
||||
channel->buffered_amount += gst_buffer_get_size (buffer);
|
||||
CHANNEL_UNLOCK (channel);
|
||||
GST_WEBRTC_DATA_CHANNEL_LOCK (channel);
|
||||
channel->parent.buffered_amount += gst_buffer_get_size (buffer);
|
||||
GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
|
||||
|
||||
ret = gst_app_src_push_buffer (GST_APP_SRC (channel->appsrc), buffer);
|
||||
|
||||
|
@ -846,16 +770,17 @@ gst_webrtc_data_channel_send_data (GstWebRTCDataChannel * channel,
|
|||
}
|
||||
|
||||
static void
|
||||
gst_webrtc_data_channel_send_string (GstWebRTCDataChannel * channel,
|
||||
gchar * str)
|
||||
webrtc_data_channel_send_string (GstWebRTCDataChannel * base_channel,
|
||||
const gchar * str)
|
||||
{
|
||||
WebRTCDataChannel *channel = WEBRTC_DATA_CHANNEL (base_channel);
|
||||
GstSctpSendMetaPartiallyReliability reliability;
|
||||
guint rel_param;
|
||||
guint32 ppid;
|
||||
GstBuffer *buffer;
|
||||
GstFlowReturn ret;
|
||||
|
||||
if (!channel->negotiated)
|
||||
if (!channel->parent.negotiated)
|
||||
g_return_if_fail (channel->opened);
|
||||
g_return_if_fail (channel->sctp_transport != NULL);
|
||||
|
||||
|
@ -884,15 +809,15 @@ gst_webrtc_data_channel_send_string (GstWebRTCDataChannel * channel,
|
|||
}
|
||||
|
||||
_get_sctp_reliability (channel, &reliability, &rel_param);
|
||||
gst_sctp_buffer_add_send_meta (buffer, ppid, channel->ordered, reliability,
|
||||
rel_param);
|
||||
gst_sctp_buffer_add_send_meta (buffer, ppid, channel->parent.ordered,
|
||||
reliability, rel_param);
|
||||
|
||||
GST_TRACE_OBJECT (channel, "Sending string using buffer %" GST_PTR_FORMAT,
|
||||
buffer);
|
||||
|
||||
CHANNEL_LOCK (channel);
|
||||
channel->buffered_amount += gst_buffer_get_size (buffer);
|
||||
CHANNEL_UNLOCK (channel);
|
||||
GST_WEBRTC_DATA_CHANNEL_LOCK (channel);
|
||||
channel->parent.buffered_amount += gst_buffer_get_size (buffer);
|
||||
GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
|
||||
|
||||
ret = gst_app_src_push_buffer (GST_APP_SRC (channel->appsrc), buffer);
|
||||
|
||||
|
@ -907,128 +832,37 @@ gst_webrtc_data_channel_send_string (GstWebRTCDataChannel * channel,
|
|||
|
||||
static void
|
||||
_on_sctp_notify_state_unlocked (GObject * sctp_transport,
|
||||
GstWebRTCDataChannel * channel)
|
||||
WebRTCDataChannel * channel)
|
||||
{
|
||||
GstWebRTCSCTPTransportState state;
|
||||
|
||||
g_object_get (sctp_transport, "state", &state, NULL);
|
||||
if (state == GST_WEBRTC_SCTP_TRANSPORT_STATE_CONNECTED) {
|
||||
if (channel->negotiated)
|
||||
if (channel->parent.negotiated)
|
||||
_channel_enqueue_task (channel, (ChannelTask) _emit_on_open, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_on_sctp_notify_state (GObject * sctp_transport, GParamSpec * pspec,
|
||||
GstWebRTCDataChannel * channel)
|
||||
WebRTCDataChannel * channel)
|
||||
{
|
||||
CHANNEL_LOCK (channel);
|
||||
GST_WEBRTC_DATA_CHANNEL_LOCK (channel);
|
||||
_on_sctp_notify_state_unlocked (sctp_transport, channel);
|
||||
CHANNEL_UNLOCK (channel);
|
||||
GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_webrtc_data_channel_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
_emit_low_threshold (WebRTCDataChannel * channel, gpointer user_data)
|
||||
{
|
||||
GstWebRTCDataChannel *channel = GST_WEBRTC_DATA_CHANNEL (object);
|
||||
|
||||
CHANNEL_LOCK (channel);
|
||||
switch (prop_id) {
|
||||
case PROP_LABEL:
|
||||
channel->label = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_ORDERED:
|
||||
channel->ordered = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_MAX_PACKET_LIFETIME:
|
||||
channel->max_packet_lifetime = g_value_get_int (value);
|
||||
break;
|
||||
case PROP_MAX_RETRANSMITS:
|
||||
channel->max_retransmits = g_value_get_int (value);
|
||||
break;
|
||||
case PROP_PROTOCOL:
|
||||
channel->protocol = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_NEGOTIATED:
|
||||
channel->negotiated = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_ID:
|
||||
channel->id = g_value_get_int (value);
|
||||
break;
|
||||
case PROP_PRIORITY:
|
||||
channel->priority = g_value_get_enum (value);
|
||||
break;
|
||||
case PROP_BUFFERED_AMOUNT_LOW_THRESHOLD:
|
||||
channel->buffered_amount_low_threshold = g_value_get_uint64 (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
CHANNEL_UNLOCK (channel);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_webrtc_data_channel_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstWebRTCDataChannel *channel = GST_WEBRTC_DATA_CHANNEL (object);
|
||||
|
||||
CHANNEL_LOCK (channel);
|
||||
switch (prop_id) {
|
||||
case PROP_LABEL:
|
||||
g_value_set_string (value, channel->label);
|
||||
break;
|
||||
case PROP_ORDERED:
|
||||
g_value_set_boolean (value, channel->ordered);
|
||||
break;
|
||||
case PROP_MAX_PACKET_LIFETIME:
|
||||
g_value_set_int (value, channel->max_packet_lifetime);
|
||||
break;
|
||||
case PROP_MAX_RETRANSMITS:
|
||||
g_value_set_int (value, channel->max_retransmits);
|
||||
break;
|
||||
case PROP_PROTOCOL:
|
||||
g_value_set_string (value, channel->protocol);
|
||||
break;
|
||||
case PROP_NEGOTIATED:
|
||||
g_value_set_boolean (value, channel->negotiated);
|
||||
break;
|
||||
case PROP_ID:
|
||||
g_value_set_int (value, channel->id);
|
||||
break;
|
||||
case PROP_PRIORITY:
|
||||
g_value_set_enum (value, channel->priority);
|
||||
break;
|
||||
case PROP_READY_STATE:
|
||||
g_value_set_enum (value, channel->ready_state);
|
||||
break;
|
||||
case PROP_BUFFERED_AMOUNT:
|
||||
g_value_set_uint64 (value, channel->buffered_amount);
|
||||
break;
|
||||
case PROP_BUFFERED_AMOUNT_LOW_THRESHOLD:
|
||||
g_value_set_uint64 (value, channel->buffered_amount_low_threshold);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
CHANNEL_UNLOCK (channel);
|
||||
}
|
||||
|
||||
static void
|
||||
_emit_low_threshold (GstWebRTCDataChannel * channel, gpointer user_data)
|
||||
{
|
||||
GST_LOG_OBJECT (channel, "Low threshold reached");
|
||||
g_signal_emit (channel,
|
||||
gst_webrtc_data_channel_signals[SIGNAL_ON_BUFFERED_AMOUNT_LOW], 0);
|
||||
gst_webrtc_data_channel_on_buffered_amount_low (GST_WEBRTC_DATA_CHANNEL
|
||||
(channel));
|
||||
}
|
||||
|
||||
static GstPadProbeReturn
|
||||
on_appsrc_data (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
|
||||
{
|
||||
GstWebRTCDataChannel *channel = user_data;
|
||||
WebRTCDataChannel *channel = user_data;
|
||||
guint64 prev_amount;
|
||||
guint64 size = 0;
|
||||
|
||||
|
@ -1041,25 +875,27 @@ on_appsrc_data (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
|
|||
}
|
||||
|
||||
if (size > 0) {
|
||||
CHANNEL_LOCK (channel);
|
||||
prev_amount = channel->buffered_amount;
|
||||
channel->buffered_amount -= size;
|
||||
GST_WEBRTC_DATA_CHANNEL_LOCK (channel);
|
||||
prev_amount = channel->parent.buffered_amount;
|
||||
channel->parent.buffered_amount -= size;
|
||||
GST_TRACE_OBJECT (channel, "checking low-threshold: prev %"
|
||||
G_GUINT64_FORMAT " low-threshold %" G_GUINT64_FORMAT " buffered %"
|
||||
G_GUINT64_FORMAT, prev_amount, channel->buffered_amount_low_threshold,
|
||||
channel->buffered_amount);
|
||||
if (prev_amount >= channel->buffered_amount_low_threshold &&
|
||||
channel->buffered_amount < channel->buffered_amount_low_threshold) {
|
||||
_channel_enqueue_task (channel, (ChannelTask) _emit_low_threshold,
|
||||
NULL, NULL);
|
||||
G_GUINT64_FORMAT, prev_amount,
|
||||
channel->parent.buffered_amount_low_threshold,
|
||||
channel->parent.buffered_amount);
|
||||
if (prev_amount >= channel->parent.buffered_amount_low_threshold
|
||||
&& channel->parent.buffered_amount <
|
||||
channel->parent.buffered_amount_low_threshold) {
|
||||
_channel_enqueue_task (channel, (ChannelTask) _emit_low_threshold, NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
if (channel->ready_state == GST_WEBRTC_DATA_CHANNEL_STATE_CLOSING
|
||||
&& channel->buffered_amount <= 0) {
|
||||
if (channel->parent.ready_state == GST_WEBRTC_DATA_CHANNEL_STATE_CLOSING
|
||||
&& channel->parent.buffered_amount <= 0) {
|
||||
_channel_enqueue_task (channel, (ChannelTask) _close_sctp_stream, NULL,
|
||||
NULL);
|
||||
}
|
||||
CHANNEL_UNLOCK (channel);
|
||||
GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
|
||||
}
|
||||
|
||||
return GST_PAD_PROBE_OK;
|
||||
|
@ -1068,7 +904,7 @@ on_appsrc_data (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
|
|||
static void
|
||||
gst_webrtc_data_channel_constructed (GObject * object)
|
||||
{
|
||||
GstWebRTCDataChannel *channel = GST_WEBRTC_DATA_CHANNEL (object);
|
||||
WebRTCDataChannel *channel = WEBRTC_DATA_CHANNEL (object);
|
||||
GstPad *pad;
|
||||
GstCaps *caps;
|
||||
|
||||
|
@ -1095,7 +931,7 @@ gst_webrtc_data_channel_constructed (GObject * object)
|
|||
static void
|
||||
gst_webrtc_data_channel_finalize (GObject * object)
|
||||
{
|
||||
GstWebRTCDataChannel *channel = GST_WEBRTC_DATA_CHANNEL (object);
|
||||
WebRTCDataChannel *channel = WEBRTC_DATA_CHANNEL (object);
|
||||
|
||||
if (channel->src_probe) {
|
||||
GstPad *pad = gst_element_get_static_pad (channel->appsrc, "src");
|
||||
|
@ -1104,12 +940,6 @@ gst_webrtc_data_channel_finalize (GObject * object)
|
|||
channel->src_probe = 0;
|
||||
}
|
||||
|
||||
g_free (channel->label);
|
||||
channel->label = NULL;
|
||||
|
||||
g_free (channel->protocol);
|
||||
channel->protocol = NULL;
|
||||
|
||||
if (channel->sctp_transport)
|
||||
g_signal_handlers_disconnect_by_data (channel->sctp_transport, channel);
|
||||
g_clear_object (&channel->sctp_transport);
|
||||
|
@ -1117,207 +947,37 @@ gst_webrtc_data_channel_finalize (GObject * object)
|
|||
g_clear_object (&channel->appsrc);
|
||||
g_clear_object (&channel->appsink);
|
||||
|
||||
g_mutex_clear (&channel->lock);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_webrtc_data_channel_class_init (GstWebRTCDataChannelClass * klass)
|
||||
webrtc_data_channel_class_init (WebRTCDataChannelClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
GstWebRTCDataChannelClass *channel_class =
|
||||
(GstWebRTCDataChannelClass *) klass;
|
||||
|
||||
gobject_class->constructed = gst_webrtc_data_channel_constructed;
|
||||
gobject_class->get_property = gst_webrtc_data_channel_get_property;
|
||||
gobject_class->set_property = gst_webrtc_data_channel_set_property;
|
||||
gobject_class->finalize = gst_webrtc_data_channel_finalize;
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_LABEL,
|
||||
g_param_spec_string ("label",
|
||||
"Label", "Data channel label",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_ORDERED,
|
||||
g_param_spec_boolean ("ordered",
|
||||
"Ordered", "Using ordered transmission mode",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_MAX_PACKET_LIFETIME,
|
||||
g_param_spec_int ("max-packet-lifetime",
|
||||
"Maximum Packet Lifetime",
|
||||
"Maximum number of milliseconds that transmissions and "
|
||||
"retransmissions may occur in unreliable mode (-1 = unset)",
|
||||
-1, G_MAXUINT16, -1,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_MAX_RETRANSMITS,
|
||||
g_param_spec_int ("max-retransmits",
|
||||
"Maximum Retransmits",
|
||||
"Maximum number of retransmissions attempted in unreliable mode",
|
||||
-1, G_MAXUINT16, 0,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_PROTOCOL,
|
||||
g_param_spec_string ("protocol",
|
||||
"Protocol", "Data channel protocol",
|
||||
"",
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_NEGOTIATED,
|
||||
g_param_spec_boolean ("negotiated",
|
||||
"Negotiated",
|
||||
"Whether this data channel was negotiated by the application", FALSE,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_ID,
|
||||
g_param_spec_int ("id",
|
||||
"ID",
|
||||
"ID negotiated by this data channel (-1 = unset)",
|
||||
-1, G_MAXUINT16, -1,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_PRIORITY,
|
||||
g_param_spec_enum ("priority",
|
||||
"Priority",
|
||||
"The priority of data sent using this data channel",
|
||||
GST_TYPE_WEBRTC_PRIORITY_TYPE,
|
||||
GST_WEBRTC_PRIORITY_TYPE_LOW,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_READY_STATE,
|
||||
g_param_spec_enum ("ready-state",
|
||||
"Ready State",
|
||||
"The Ready state of this data channel",
|
||||
GST_TYPE_WEBRTC_DATA_CHANNEL_STATE,
|
||||
GST_WEBRTC_DATA_CHANNEL_STATE_NEW,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_BUFFERED_AMOUNT,
|
||||
g_param_spec_uint64 ("buffered-amount",
|
||||
"Buffered Amount",
|
||||
"The amount of data in bytes currently buffered",
|
||||
0, G_MAXUINT64, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_BUFFERED_AMOUNT_LOW_THRESHOLD,
|
||||
g_param_spec_uint64 ("buffered-amount-low-threshold",
|
||||
"Buffered Amount Low Threshold",
|
||||
"The threshold at which the buffered amount is considered low and "
|
||||
"the buffered-amount-low signal is emitted",
|
||||
0, G_MAXUINT64, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* GstWebRTCDataChannel::on-open:
|
||||
* @object: the #GstWebRTCDataChannel
|
||||
*/
|
||||
gst_webrtc_data_channel_signals[SIGNAL_ON_OPEN] =
|
||||
g_signal_new ("on-open", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
* GstWebRTCDataChannel::on-close:
|
||||
* @object: the #GstWebRTCDataChannel
|
||||
*/
|
||||
gst_webrtc_data_channel_signals[SIGNAL_ON_CLOSE] =
|
||||
g_signal_new ("on-close", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
* GstWebRTCDataChannel::on-error:
|
||||
* @object: the #GstWebRTCDataChannel
|
||||
* @error: the #GError thrown
|
||||
*/
|
||||
gst_webrtc_data_channel_signals[SIGNAL_ON_ERROR] =
|
||||
g_signal_new ("on-error", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_ERROR);
|
||||
|
||||
/**
|
||||
* GstWebRTCDataChannel::on-message-data:
|
||||
* @object: the #GstWebRTCDataChannel
|
||||
* @data: (nullable): a #GBytes of the data received
|
||||
*/
|
||||
gst_webrtc_data_channel_signals[SIGNAL_ON_MESSAGE_DATA] =
|
||||
g_signal_new ("on-message-data", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_BYTES);
|
||||
|
||||
/**
|
||||
* GstWebRTCDataChannel::on-message-string:
|
||||
* @object: the #GstWebRTCDataChannel
|
||||
* @data: (nullable): the data received as a string
|
||||
*/
|
||||
gst_webrtc_data_channel_signals[SIGNAL_ON_MESSAGE_STRING] =
|
||||
g_signal_new ("on-message-string", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_STRING);
|
||||
|
||||
/**
|
||||
* GstWebRTCDataChannel::on-buffered-amount-low:
|
||||
* @object: the #GstWebRTCDataChannel
|
||||
*/
|
||||
gst_webrtc_data_channel_signals[SIGNAL_ON_BUFFERED_AMOUNT_LOW] =
|
||||
g_signal_new ("on-buffered-amount-low", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
* GstWebRTCDataChannel::send-data:
|
||||
* @object: the #GstWebRTCDataChannel
|
||||
* @data: (nullable): a #GBytes with the data
|
||||
*/
|
||||
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_CALLBACK (gst_webrtc_data_channel_send_data), NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1, G_TYPE_BYTES);
|
||||
|
||||
/**
|
||||
* GstWebRTCDataChannel::send-string:
|
||||
* @object: the #GstWebRTCDataChannel
|
||||
* @data: (nullable): the data to send as a string
|
||||
*/
|
||||
gst_webrtc_data_channel_signals[SIGNAL_SEND_STRING] =
|
||||
g_signal_new_class_handler ("send-string", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
|
||||
G_CALLBACK (gst_webrtc_data_channel_send_string), NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1, G_TYPE_STRING);
|
||||
|
||||
/**
|
||||
* GstWebRTCDataChannel::close:
|
||||
* @object: the #GstWebRTCDataChannel
|
||||
*
|
||||
* Close the data channel
|
||||
*/
|
||||
gst_webrtc_data_channel_signals[SIGNAL_CLOSE] =
|
||||
g_signal_new_class_handler ("close", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
|
||||
G_CALLBACK (gst_webrtc_data_channel_close), NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
channel_class->send_data = webrtc_data_channel_send_data;
|
||||
channel_class->send_string = webrtc_data_channel_send_string;
|
||||
channel_class->close = webrtc_data_channel_close;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_webrtc_data_channel_init (GstWebRTCDataChannel * channel)
|
||||
webrtc_data_channel_init (WebRTCDataChannel * channel)
|
||||
{
|
||||
g_mutex_init (&channel->lock);
|
||||
}
|
||||
|
||||
static void
|
||||
_data_channel_set_sctp_transport (GstWebRTCDataChannel * channel,
|
||||
_data_channel_set_sctp_transport (WebRTCDataChannel * channel,
|
||||
GstWebRTCSCTPTransport * sctp)
|
||||
{
|
||||
g_return_if_fail (GST_IS_WEBRTC_DATA_CHANNEL (channel));
|
||||
g_return_if_fail (GST_IS_WEBRTC_SCTP_TRANSPORT (sctp));
|
||||
|
||||
CHANNEL_LOCK (channel);
|
||||
GST_WEBRTC_DATA_CHANNEL_LOCK (channel);
|
||||
if (channel->sctp_transport)
|
||||
g_signal_handlers_disconnect_by_data (channel->sctp_transport, channel);
|
||||
|
||||
|
@ -1331,11 +991,11 @@ _data_channel_set_sctp_transport (GstWebRTCDataChannel * channel,
|
|||
channel);
|
||||
_on_sctp_notify_state_unlocked (G_OBJECT (sctp), channel);
|
||||
}
|
||||
CHANNEL_UNLOCK (channel);
|
||||
GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
|
||||
}
|
||||
|
||||
void
|
||||
gst_webrtc_data_channel_link_to_sctp (GstWebRTCDataChannel * channel,
|
||||
webrtc_data_channel_link_to_sctp (WebRTCDataChannel * channel,
|
||||
GstWebRTCSCTPTransport * sctp_transport)
|
||||
{
|
||||
if (sctp_transport && !channel->sctp_transport) {
|
||||
|
|
|
@ -17,68 +17,56 @@
|
|||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_WEBRTC_DATA_CHANNEL_H__
|
||||
#define __GST_WEBRTC_DATA_CHANNEL_H__
|
||||
#ifndef __WEBRTC_DATA_CHANNEL_H__
|
||||
#define __WEBRTC_DATA_CHANNEL_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/webrtc/webrtc_fwd.h>
|
||||
#include <gst/webrtc/dtlstransport.h>
|
||||
#include <gst/webrtc/datachannel.h>
|
||||
#include "sctptransport.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GType gst_webrtc_data_channel_get_type(void);
|
||||
#define GST_TYPE_WEBRTC_DATA_CHANNEL (gst_webrtc_data_channel_get_type())
|
||||
#define GST_WEBRTC_DATA_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_WEBRTC_DATA_CHANNEL,GstWebRTCDataChannel))
|
||||
#define GST_IS_WEBRTC_DATA_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_WEBRTC_DATA_CHANNEL))
|
||||
#define GST_WEBRTC_DATA_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_WEBRTC_DATA_CHANNEL,GstWebRTCDataChannelClass))
|
||||
#define GST_IS_WEBRTC_DATA_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_WEBRTC_DATA_CHANNEL))
|
||||
#define GST_WEBRTC_DATA_CHANNEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_WEBRTC_DATA_CHANNEL,GstWebRTCDataChannelClass))
|
||||
GType webrtc_data_channel_get_type(void);
|
||||
#define WEBRTC_TYPE_DATA_CHANNEL (webrtc_data_channel_get_type())
|
||||
#define WEBRTC_DATA_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),WEBRTC_TYPE_DATA_CHANNEL,WebRTCDataChannel))
|
||||
#define WEBRTC_IS_DATA_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),WEBRTC_TYPE_DATA_CHANNEL))
|
||||
#define WEBRTC_DATA_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass) ,WEBRTC_TYPE_DATA_CHANNEL,WebRTCDataChannelClass))
|
||||
#define WEBRTC_IS_DATA_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,WEBRTC_TYPE_DATA_CHANNEL))
|
||||
#define WEBRTC_DATA_CHANNEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,WEBRTC_TYPE_DATA_CHANNEL,WebRTCDataChannelClass))
|
||||
|
||||
typedef struct _GstWebRTCDataChannel GstWebRTCDataChannel;
|
||||
typedef struct _GstWebRTCDataChannelClass GstWebRTCDataChannelClass;
|
||||
typedef struct _WebRTCDataChannel WebRTCDataChannel;
|
||||
typedef struct _WebRTCDataChannelClass WebRTCDataChannelClass;
|
||||
|
||||
struct _GstWebRTCDataChannel
|
||||
struct _WebRTCDataChannel
|
||||
{
|
||||
GObject parent;
|
||||
GstWebRTCDataChannel parent;
|
||||
|
||||
GstWebRTCSCTPTransport *sctp_transport;
|
||||
GstElement *appsrc;
|
||||
GstElement *appsink;
|
||||
|
||||
gchar *label;
|
||||
gboolean ordered;
|
||||
guint max_packet_lifetime;
|
||||
guint max_retransmits;
|
||||
gchar *protocol;
|
||||
gboolean negotiated;
|
||||
gint id;
|
||||
GstWebRTCPriorityType priority;
|
||||
GstWebRTCDataChannelState ready_state;
|
||||
guint64 buffered_amount;
|
||||
guint64 buffered_amount_low_threshold;
|
||||
|
||||
GstWebRTCBin *webrtcbin;
|
||||
gboolean opened;
|
||||
gulong src_probe;
|
||||
GError *stored_error;
|
||||
GMutex lock;
|
||||
|
||||
gpointer _padding[GST_PADDING];
|
||||
};
|
||||
|
||||
struct _GstWebRTCDataChannelClass
|
||||
struct _WebRTCDataChannelClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
GstWebRTCDataChannelClass parent_class;
|
||||
|
||||
gpointer _padding[GST_PADDING];
|
||||
};
|
||||
|
||||
void gst_webrtc_data_channel_start_negotiation (GstWebRTCDataChannel *channel);
|
||||
void webrtc_data_channel_start_negotiation (WebRTCDataChannel *channel);
|
||||
G_GNUC_INTERNAL
|
||||
void gst_webrtc_data_channel_link_to_sctp (GstWebRTCDataChannel *channel,
|
||||
GstWebRTCSCTPTransport *sctp_transport);
|
||||
void webrtc_data_channel_link_to_sctp (WebRTCDataChannel *channel,
|
||||
GstWebRTCSCTPTransport *sctp_transport);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_WEBRTC_DATA_CHANNEL_H__ */
|
||||
#endif /* __WEBRTC_DATA_CHANNEL_H__ */
|
||||
|
|
555
gst-libs/gst/webrtc/datachannel.c
Normal file
555
gst-libs/gst/webrtc/datachannel.c
Normal file
|
@ -0,0 +1,555 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) 2017 Matthew Waters <matthew@centricular.com>
|
||||
* Copyright (C) 2020 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:gstwebrtc-datachannel
|
||||
* @short_description: RTCDataChannel object
|
||||
* @title: GstWebRTCDataChannel
|
||||
*
|
||||
* <https://www.w3.org/TR/webrtc/#rtcdatachannel>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "datachannel.h"
|
||||
|
||||
#define GST_CAT_DEFAULT gst_webrtc_data_channel_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
|
||||
#define gst_webrtc_data_channel_parent_class parent_class
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstWebRTCDataChannel, gst_webrtc_data_channel,
|
||||
G_TYPE_OBJECT, GST_DEBUG_CATEGORY_INIT (gst_webrtc_data_channel_debug,
|
||||
"webrtcdatachannel", 0, "webrtcdatachannel"););
|
||||
|
||||
enum
|
||||
{
|
||||
SIGNAL_0,
|
||||
SIGNAL_ON_OPEN,
|
||||
SIGNAL_ON_CLOSE,
|
||||
SIGNAL_ON_ERROR,
|
||||
SIGNAL_ON_MESSAGE_DATA,
|
||||
SIGNAL_ON_MESSAGE_STRING,
|
||||
SIGNAL_ON_BUFFERED_AMOUNT_LOW,
|
||||
SIGNAL_SEND_DATA,
|
||||
SIGNAL_SEND_STRING,
|
||||
SIGNAL_CLOSE,
|
||||
LAST_SIGNAL,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_LABEL,
|
||||
PROP_ORDERED,
|
||||
PROP_MAX_PACKET_LIFETIME,
|
||||
PROP_MAX_RETRANSMITS,
|
||||
PROP_PROTOCOL,
|
||||
PROP_NEGOTIATED,
|
||||
PROP_ID,
|
||||
PROP_PRIORITY,
|
||||
PROP_READY_STATE,
|
||||
PROP_BUFFERED_AMOUNT,
|
||||
PROP_BUFFERED_AMOUNT_LOW_THRESHOLD,
|
||||
};
|
||||
|
||||
static guint gst_webrtc_data_channel_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
static void
|
||||
gst_webrtc_data_channel_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstWebRTCDataChannel *channel = GST_WEBRTC_DATA_CHANNEL (object);
|
||||
|
||||
GST_WEBRTC_DATA_CHANNEL_LOCK (channel);
|
||||
switch (prop_id) {
|
||||
case PROP_LABEL:
|
||||
channel->label = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_ORDERED:
|
||||
channel->ordered = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_MAX_PACKET_LIFETIME:
|
||||
channel->max_packet_lifetime = g_value_get_int (value);
|
||||
break;
|
||||
case PROP_MAX_RETRANSMITS:
|
||||
channel->max_retransmits = g_value_get_int (value);
|
||||
break;
|
||||
case PROP_PROTOCOL:
|
||||
channel->protocol = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_NEGOTIATED:
|
||||
channel->negotiated = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_ID:
|
||||
channel->id = g_value_get_int (value);
|
||||
break;
|
||||
case PROP_PRIORITY:
|
||||
channel->priority = g_value_get_enum (value);
|
||||
break;
|
||||
case PROP_BUFFERED_AMOUNT_LOW_THRESHOLD:
|
||||
channel->buffered_amount_low_threshold = g_value_get_uint64 (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_webrtc_data_channel_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstWebRTCDataChannel *channel = GST_WEBRTC_DATA_CHANNEL (object);
|
||||
|
||||
GST_WEBRTC_DATA_CHANNEL_LOCK (channel);
|
||||
switch (prop_id) {
|
||||
case PROP_LABEL:
|
||||
g_value_set_string (value, channel->label);
|
||||
break;
|
||||
case PROP_ORDERED:
|
||||
g_value_set_boolean (value, channel->ordered);
|
||||
break;
|
||||
case PROP_MAX_PACKET_LIFETIME:
|
||||
g_value_set_int (value, channel->max_packet_lifetime);
|
||||
break;
|
||||
case PROP_MAX_RETRANSMITS:
|
||||
g_value_set_int (value, channel->max_retransmits);
|
||||
break;
|
||||
case PROP_PROTOCOL:
|
||||
g_value_set_string (value, channel->protocol);
|
||||
break;
|
||||
case PROP_NEGOTIATED:
|
||||
g_value_set_boolean (value, channel->negotiated);
|
||||
break;
|
||||
case PROP_ID:
|
||||
g_value_set_int (value, channel->id);
|
||||
break;
|
||||
case PROP_PRIORITY:
|
||||
g_value_set_enum (value, channel->priority);
|
||||
break;
|
||||
case PROP_READY_STATE:
|
||||
g_value_set_enum (value, channel->ready_state);
|
||||
break;
|
||||
case PROP_BUFFERED_AMOUNT:
|
||||
g_value_set_uint64 (value, channel->buffered_amount);
|
||||
break;
|
||||
case PROP_BUFFERED_AMOUNT_LOW_THRESHOLD:
|
||||
g_value_set_uint64 (value, channel->buffered_amount_low_threshold);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_webrtc_data_channel_finalize (GObject * object)
|
||||
{
|
||||
GstWebRTCDataChannel *channel = GST_WEBRTC_DATA_CHANNEL (object);
|
||||
|
||||
g_free (channel->label);
|
||||
channel->label = NULL;
|
||||
|
||||
g_free (channel->protocol);
|
||||
channel->protocol = NULL;
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_webrtc_data_channel_class_init (GstWebRTCDataChannelClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
|
||||
gobject_class->get_property = gst_webrtc_data_channel_get_property;
|
||||
gobject_class->set_property = gst_webrtc_data_channel_set_property;
|
||||
gobject_class->finalize = gst_webrtc_data_channel_finalize;
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_LABEL,
|
||||
g_param_spec_string ("label",
|
||||
"Label", "Data channel label",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_ORDERED,
|
||||
g_param_spec_boolean ("ordered",
|
||||
"Ordered", "Using ordered transmission mode",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_MAX_PACKET_LIFETIME,
|
||||
g_param_spec_int ("max-packet-lifetime",
|
||||
"Maximum Packet Lifetime",
|
||||
"Maximum number of milliseconds that transmissions and "
|
||||
"retransmissions may occur in unreliable mode (-1 = unset)",
|
||||
-1, G_MAXUINT16, -1,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_MAX_RETRANSMITS,
|
||||
g_param_spec_int ("max-retransmits",
|
||||
"Maximum Retransmits",
|
||||
"Maximum number of retransmissions attempted in unreliable mode",
|
||||
-1, G_MAXUINT16, 0,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_PROTOCOL,
|
||||
g_param_spec_string ("protocol",
|
||||
"Protocol", "Data channel protocol",
|
||||
"",
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_NEGOTIATED,
|
||||
g_param_spec_boolean ("negotiated",
|
||||
"Negotiated",
|
||||
"Whether this data channel was negotiated by the application", FALSE,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_ID,
|
||||
g_param_spec_int ("id",
|
||||
"ID",
|
||||
"ID negotiated by this data channel (-1 = unset)",
|
||||
-1, G_MAXUINT16, -1,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_PRIORITY,
|
||||
g_param_spec_enum ("priority",
|
||||
"Priority",
|
||||
"The priority of data sent using this data channel",
|
||||
GST_TYPE_WEBRTC_PRIORITY_TYPE,
|
||||
GST_WEBRTC_PRIORITY_TYPE_LOW,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_READY_STATE,
|
||||
g_param_spec_enum ("ready-state",
|
||||
"Ready State",
|
||||
"The Ready state of this data channel",
|
||||
GST_TYPE_WEBRTC_DATA_CHANNEL_STATE,
|
||||
GST_WEBRTC_DATA_CHANNEL_STATE_NEW,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_BUFFERED_AMOUNT,
|
||||
g_param_spec_uint64 ("buffered-amount",
|
||||
"Buffered Amount",
|
||||
"The amount of data in bytes currently buffered",
|
||||
0, G_MAXUINT64, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_BUFFERED_AMOUNT_LOW_THRESHOLD,
|
||||
g_param_spec_uint64 ("buffered-amount-low-threshold",
|
||||
"Buffered Amount Low Threshold",
|
||||
"The threshold at which the buffered amount is considered low and "
|
||||
"the buffered-amount-low signal is emitted",
|
||||
0, G_MAXUINT64, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* GstWebRTCDataChannel::on-open:
|
||||
* @object: the #GstWebRTCDataChannel
|
||||
*/
|
||||
gst_webrtc_data_channel_signals[SIGNAL_ON_OPEN] =
|
||||
g_signal_new ("on-open", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
* GstWebRTCDataChannel::on-close:
|
||||
* @object: the #GstWebRTCDataChannel
|
||||
*/
|
||||
gst_webrtc_data_channel_signals[SIGNAL_ON_CLOSE] =
|
||||
g_signal_new ("on-close", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
* GstWebRTCDataChannel::on-error:
|
||||
* @object: the #GstWebRTCDataChannel
|
||||
* @error: the #GError thrown
|
||||
*/
|
||||
gst_webrtc_data_channel_signals[SIGNAL_ON_ERROR] =
|
||||
g_signal_new ("on-error", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_ERROR);
|
||||
|
||||
/**
|
||||
* GstWebRTCDataChannel::on-message-data:
|
||||
* @object: the #GstWebRTCDataChannel
|
||||
* @data: (nullable): a #GBytes of the data received
|
||||
*/
|
||||
gst_webrtc_data_channel_signals[SIGNAL_ON_MESSAGE_DATA] =
|
||||
g_signal_new ("on-message-data", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_BYTES);
|
||||
|
||||
/**
|
||||
* GstWebRTCDataChannel::on-message-string:
|
||||
* @object: the #GstWebRTCDataChannel
|
||||
* @data: (nullable): the data received as a string
|
||||
*/
|
||||
gst_webrtc_data_channel_signals[SIGNAL_ON_MESSAGE_STRING] =
|
||||
g_signal_new ("on-message-string", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_STRING);
|
||||
|
||||
/**
|
||||
* GstWebRTCDataChannel::on-buffered-amount-low:
|
||||
* @object: the #GstWebRTCDataChannel
|
||||
*/
|
||||
gst_webrtc_data_channel_signals[SIGNAL_ON_BUFFERED_AMOUNT_LOW] =
|
||||
g_signal_new ("on-buffered-amount-low", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
* GstWebRTCDataChannel::send-data:
|
||||
* @object: the #GstWebRTCDataChannel
|
||||
* @data: (nullable): a #GBytes with the data
|
||||
*/
|
||||
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_CALLBACK (gst_webrtc_data_channel_send_data), NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1, G_TYPE_BYTES);
|
||||
|
||||
/**
|
||||
* GstWebRTCDataChannel::send-string:
|
||||
* @object: the #GstWebRTCDataChannel
|
||||
* @data: (nullable): the data to send as a string
|
||||
*/
|
||||
gst_webrtc_data_channel_signals[SIGNAL_SEND_STRING] =
|
||||
g_signal_new_class_handler ("send-string", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
|
||||
G_CALLBACK (gst_webrtc_data_channel_send_string), NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1, G_TYPE_STRING);
|
||||
|
||||
/**
|
||||
* GstWebRTCDataChannel::close:
|
||||
* @object: the #GstWebRTCDataChannel
|
||||
*
|
||||
* Close the data channel
|
||||
*/
|
||||
gst_webrtc_data_channel_signals[SIGNAL_CLOSE] =
|
||||
g_signal_new_class_handler ("close", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
|
||||
G_CALLBACK (gst_webrtc_data_channel_close), NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_webrtc_data_channel_init (GstWebRTCDataChannel * channel)
|
||||
{
|
||||
g_mutex_init (&channel->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_webrtc_data_channel_on_open:
|
||||
* @channel: a #GstWebRTCDataChannel
|
||||
*
|
||||
* Signal that the data channel was opened. Should only be used by subclasses.
|
||||
*/
|
||||
void
|
||||
gst_webrtc_data_channel_on_open (GstWebRTCDataChannel * channel)
|
||||
{
|
||||
g_return_if_fail (GST_IS_WEBRTC_DATA_CHANNEL (channel));
|
||||
|
||||
GST_WEBRTC_DATA_CHANNEL_LOCK (channel);
|
||||
if (channel->ready_state == GST_WEBRTC_DATA_CHANNEL_STATE_CLOSING ||
|
||||
channel->ready_state == GST_WEBRTC_DATA_CHANNEL_STATE_CLOSED) {
|
||||
GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
|
||||
return;
|
||||
}
|
||||
|
||||
if (channel->ready_state != GST_WEBRTC_DATA_CHANNEL_STATE_OPEN) {
|
||||
channel->ready_state = GST_WEBRTC_DATA_CHANNEL_STATE_OPEN;
|
||||
GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
|
||||
g_object_notify (G_OBJECT (channel), "ready-state");
|
||||
|
||||
GST_INFO_OBJECT (channel, "We are open and ready for data!");
|
||||
} else {
|
||||
GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
|
||||
}
|
||||
|
||||
GST_INFO_OBJECT (channel, "Opened");
|
||||
|
||||
g_signal_emit (channel, gst_webrtc_data_channel_signals[SIGNAL_ON_OPEN], 0,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_webrtc_data_channel_on_close:
|
||||
* @channel: a #GstWebRTCDataChannel
|
||||
*
|
||||
* Signal that the data channel was closed. Should only be used by subclasses.
|
||||
*/
|
||||
void
|
||||
gst_webrtc_data_channel_on_close (GstWebRTCDataChannel * channel)
|
||||
{
|
||||
g_return_if_fail (GST_IS_WEBRTC_DATA_CHANNEL (channel));
|
||||
|
||||
GST_INFO_OBJECT (channel, "Closed");
|
||||
|
||||
GST_WEBRTC_DATA_CHANNEL_LOCK (channel);
|
||||
if (channel->ready_state == GST_WEBRTC_DATA_CHANNEL_STATE_CLOSED) {
|
||||
GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
|
||||
return;
|
||||
}
|
||||
|
||||
channel->ready_state = GST_WEBRTC_DATA_CHANNEL_STATE_CLOSED;
|
||||
GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
|
||||
|
||||
g_object_notify (G_OBJECT (channel), "ready-state");
|
||||
GST_INFO_OBJECT (channel, "We are closed for data");
|
||||
|
||||
g_signal_emit (channel, gst_webrtc_data_channel_signals[SIGNAL_ON_CLOSE], 0,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_webrtc_data_channel_on_error:
|
||||
* @channel: a #GstWebRTCDataChannel
|
||||
* @error: (transfer full): a #GError
|
||||
*
|
||||
* Signal that the data channel had an error. Should only be used by subclasses.
|
||||
*/
|
||||
void
|
||||
gst_webrtc_data_channel_on_error (GstWebRTCDataChannel * channel,
|
||||
GError * error)
|
||||
{
|
||||
g_return_if_fail (GST_IS_WEBRTC_DATA_CHANNEL (channel));
|
||||
g_return_if_fail (error != NULL);
|
||||
|
||||
GST_WARNING_OBJECT (channel, "Error: %s", GST_STR_NULL (error->message));
|
||||
|
||||
g_signal_emit (channel, gst_webrtc_data_channel_signals[SIGNAL_ON_ERROR], 0,
|
||||
error);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_webrtc_data_channel_on_message_data:
|
||||
* @channel: a #GstWebRTCDataChannel
|
||||
* @data: (nullable): a #GBytes or %NULL
|
||||
*
|
||||
* Signal that the data channel received a data message. Should only be used by subclasses.
|
||||
*/
|
||||
void
|
||||
gst_webrtc_data_channel_on_message_data (GstWebRTCDataChannel * channel,
|
||||
GBytes * data)
|
||||
{
|
||||
g_return_if_fail (GST_IS_WEBRTC_DATA_CHANNEL (channel));
|
||||
|
||||
GST_LOG_OBJECT (channel, "Have data %p", data);
|
||||
g_signal_emit (channel,
|
||||
gst_webrtc_data_channel_signals[SIGNAL_ON_MESSAGE_DATA], 0, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_webrtc_data_channel_on_message_string:
|
||||
* @channel: a #GstWebRTCDataChannel
|
||||
* @str: (nullable): a string or %NULL
|
||||
*
|
||||
* Signal that the data channel received a string message. Should only be used by subclasses.
|
||||
*/
|
||||
void
|
||||
gst_webrtc_data_channel_on_message_string (GstWebRTCDataChannel * channel,
|
||||
const gchar * str)
|
||||
{
|
||||
g_return_if_fail (GST_IS_WEBRTC_DATA_CHANNEL (channel));
|
||||
|
||||
GST_LOG_OBJECT (channel, "Have string %p", str);
|
||||
g_signal_emit (channel,
|
||||
gst_webrtc_data_channel_signals[SIGNAL_ON_MESSAGE_STRING], 0, str);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_webrtc_data_channel_on_buffered_amount_low:
|
||||
* @channel: a #GstWebRTCDataChannel
|
||||
*
|
||||
* Signal that the data channel reached a low buffered amount. Should only be used by subclasses.
|
||||
*/
|
||||
void
|
||||
gst_webrtc_data_channel_on_buffered_amount_low (GstWebRTCDataChannel * channel)
|
||||
{
|
||||
g_return_if_fail (GST_IS_WEBRTC_DATA_CHANNEL (channel));
|
||||
|
||||
GST_LOG_OBJECT (channel, "Low threshold reached");
|
||||
g_signal_emit (channel,
|
||||
gst_webrtc_data_channel_signals[SIGNAL_ON_BUFFERED_AMOUNT_LOW], 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_webrtc_data_channel_send_data:
|
||||
* @channel: a #GstWebRTCDataChannel
|
||||
* @data: (nullable): a #GBytes or %NULL
|
||||
*
|
||||
* Send @data as a data message over @channel.
|
||||
*/
|
||||
void
|
||||
gst_webrtc_data_channel_send_data (GstWebRTCDataChannel * channel,
|
||||
GBytes * data)
|
||||
{
|
||||
GstWebRTCDataChannelClass *klass;
|
||||
|
||||
g_return_if_fail (GST_IS_WEBRTC_DATA_CHANNEL (channel));
|
||||
|
||||
klass = GST_WEBRTC_DATA_CHANNEL_GET_CLASS (channel);
|
||||
klass->send_data (channel, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_webrtc_data_channel_send_string:
|
||||
* @channel: a #GstWebRTCDataChannel
|
||||
* @str: (nullable): a string or %NULL
|
||||
*
|
||||
* Send @str as a string message over @channel.
|
||||
*/
|
||||
void
|
||||
gst_webrtc_data_channel_send_string (GstWebRTCDataChannel * channel,
|
||||
const gchar * str)
|
||||
{
|
||||
GstWebRTCDataChannelClass *klass;
|
||||
|
||||
g_return_if_fail (GST_IS_WEBRTC_DATA_CHANNEL (channel));
|
||||
|
||||
klass = GST_WEBRTC_DATA_CHANNEL_GET_CLASS (channel);
|
||||
klass->send_string (channel, str);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_webrtc_data_channel_close:
|
||||
* @channel: a #GstWebRTCDataChannel
|
||||
*
|
||||
* Close the @channel.
|
||||
*/
|
||||
void
|
||||
gst_webrtc_data_channel_close (GstWebRTCDataChannel * channel)
|
||||
{
|
||||
GstWebRTCDataChannelClass *klass;
|
||||
|
||||
g_return_if_fail (GST_IS_WEBRTC_DATA_CHANNEL (channel));
|
||||
|
||||
klass = GST_WEBRTC_DATA_CHANNEL_GET_CLASS (channel);
|
||||
klass->close (channel);
|
||||
}
|
108
gst-libs/gst/webrtc/datachannel.h
Normal file
108
gst-libs/gst/webrtc/datachannel.h
Normal file
|
@ -0,0 +1,108 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) 2018 Matthew Waters <matthew@centricular.com>
|
||||
* Copyright (C) 2020 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_WEBRTC_DATA_CHANNEL_H__
|
||||
#define __GST_WEBRTC_DATA_CHANNEL_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/webrtc/webrtc_fwd.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GST_WEBRTC_API
|
||||
GType gst_webrtc_data_channel_get_type(void);
|
||||
|
||||
#define GST_TYPE_WEBRTC_DATA_CHANNEL (gst_webrtc_data_channel_get_type())
|
||||
#define GST_WEBRTC_DATA_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_WEBRTC_DATA_CHANNEL,GstWebRTCDataChannel))
|
||||
#define GST_IS_WEBRTC_DATA_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_WEBRTC_DATA_CHANNEL))
|
||||
#define GST_WEBRTC_DATA_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_WEBRTC_DATA_CHANNEL,GstWebRTCDataChannelClass))
|
||||
#define GST_IS_WEBRTC_DATA_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_WEBRTC_DATA_CHANNEL))
|
||||
#define GST_WEBRTC_DATA_CHANNEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_WEBRTC_DATA_CHANNEL,GstWebRTCDataChannelClass))
|
||||
|
||||
#define GST_WEBRTC_DATA_CHANNEL_LOCK(channel) g_mutex_lock(&((GstWebRTCDataChannel *)(channel))->lock)
|
||||
#define GST_WEBRTC_DATA_CHANNEL_UNLOCK(channel) g_mutex_unlock(&((GstWebRTCDataChannel *)(channel))->lock)
|
||||
|
||||
/**
|
||||
* GstWebRTCDataChannel:
|
||||
*/
|
||||
struct _GstWebRTCDataChannel
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
GMutex lock;
|
||||
|
||||
gchar *label;
|
||||
gboolean ordered;
|
||||
guint max_packet_lifetime;
|
||||
guint max_retransmits;
|
||||
gchar *protocol;
|
||||
gboolean negotiated;
|
||||
gint id;
|
||||
GstWebRTCPriorityType priority;
|
||||
GstWebRTCDataChannelState ready_state;
|
||||
guint64 buffered_amount;
|
||||
guint64 buffered_amount_low_threshold;
|
||||
|
||||
gpointer _padding[GST_PADDING];
|
||||
};
|
||||
|
||||
struct _GstWebRTCDataChannelClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (*send_data) (GstWebRTCDataChannel * channel, GBytes *data);
|
||||
void (*send_string) (GstWebRTCDataChannel * channel, const gchar *str);
|
||||
void (*close) (GstWebRTCDataChannel * channel);
|
||||
|
||||
gpointer _padding[GST_PADDING];
|
||||
};
|
||||
|
||||
GST_WEBRTC_API
|
||||
void gst_webrtc_data_channel_on_open (GstWebRTCDataChannel * channel);
|
||||
|
||||
GST_WEBRTC_API
|
||||
void gst_webrtc_data_channel_on_close (GstWebRTCDataChannel * channel);
|
||||
|
||||
GST_WEBRTC_API
|
||||
void gst_webrtc_data_channel_on_error (GstWebRTCDataChannel * channel, GError * error);
|
||||
|
||||
GST_WEBRTC_API
|
||||
void gst_webrtc_data_channel_on_message_data (GstWebRTCDataChannel * channel, GBytes * data);
|
||||
|
||||
GST_WEBRTC_API
|
||||
void gst_webrtc_data_channel_on_message_string (GstWebRTCDataChannel * channel, const gchar * str);
|
||||
|
||||
GST_WEBRTC_API
|
||||
void gst_webrtc_data_channel_on_buffered_amount_low (GstWebRTCDataChannel * channel);
|
||||
|
||||
GST_WEBRTC_API
|
||||
void gst_webrtc_data_channel_send_data (GstWebRTCDataChannel * channel, GBytes * data);
|
||||
|
||||
GST_WEBRTC_API
|
||||
void gst_webrtc_data_channel_send_string (GstWebRTCDataChannel * channel, const gchar * str);
|
||||
|
||||
GST_WEBRTC_API
|
||||
void gst_webrtc_data_channel_close (GstWebRTCDataChannel * channel);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstWebRTCDataChannel, g_object_unref)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_WEBRTC_DATA_CHANNEL_H__ */
|
|
@ -5,6 +5,7 @@ webrtc_sources = [
|
|||
'rtpreceiver.c',
|
||||
'rtpsender.c',
|
||||
'rtptransceiver.c',
|
||||
'datachannel.c',
|
||||
]
|
||||
|
||||
webrtc_headers = [
|
||||
|
@ -14,6 +15,7 @@ webrtc_headers = [
|
|||
'rtpreceiver.h',
|
||||
'rtpsender.h',
|
||||
'rtptransceiver.h',
|
||||
'datachannel.h',
|
||||
'webrtc_fwd.h',
|
||||
'webrtc.h',
|
||||
]
|
||||
|
|
|
@ -29,5 +29,6 @@
|
|||
#include <gst/webrtc/rtpreceiver.h>
|
||||
#include <gst/webrtc/rtpsender.h>
|
||||
#include <gst/webrtc/rtptransceiver.h>
|
||||
#include <gst/webrtc/datachannel.h>
|
||||
|
||||
#endif /* __GST_WEBRTC_WEBRTC_H__ */
|
||||
|
|
|
@ -59,6 +59,9 @@ typedef struct _GstWebRTCSessionDescription GstWebRTCSessionDescription;
|
|||
typedef struct _GstWebRTCRTPTransceiver GstWebRTCRTPTransceiver;
|
||||
typedef struct _GstWebRTCRTPTransceiverClass GstWebRTCRTPTransceiverClass;
|
||||
|
||||
typedef struct _GstWebRTCDataChannel GstWebRTCDataChannel;
|
||||
typedef struct _GstWebRTCDataChannelClass GstWebRTCDataChannelClass;
|
||||
|
||||
/**
|
||||
* GstWebRTCDTLSTransportState:
|
||||
* @GST_WEBRTC_DTLS_TRANSPORT_STATE_NEW: new
|
||||
|
|
Loading…
Reference in a new issue