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
@ -545,17 +545,17 @@ _find_pad (GstWebRTCBin * webrtc, gconstpointer data, FindPadFunc func)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef gboolean (*FindDataChannelFunc) (GstWebRTCDataChannel * p1,
|
typedef gboolean (*FindDataChannelFunc) (WebRTCDataChannel * p1,
|
||||||
gconstpointer data);
|
gconstpointer data);
|
||||||
|
|
||||||
static GstWebRTCDataChannel *
|
static WebRTCDataChannel *
|
||||||
_find_data_channel (GstWebRTCBin * webrtc, gconstpointer data,
|
_find_data_channel (GstWebRTCBin * webrtc, gconstpointer data,
|
||||||
FindDataChannelFunc func)
|
FindDataChannelFunc func)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < webrtc->priv->data_channels->len; i++) {
|
for (i = 0; i < webrtc->priv->data_channels->len; i++) {
|
||||||
GstWebRTCDataChannel *channel =
|
WebRTCDataChannel *channel =
|
||||||
g_ptr_array_index (webrtc->priv->data_channels, i);
|
g_ptr_array_index (webrtc->priv->data_channels, i);
|
||||||
|
|
||||||
if (func (channel, data))
|
if (func (channel, data))
|
||||||
@ -566,15 +566,15 @@ _find_data_channel (GstWebRTCBin * webrtc, gconstpointer data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
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)
|
_find_data_channel_for_id (GstWebRTCBin * webrtc, gint id)
|
||||||
{
|
{
|
||||||
GstWebRTCDataChannel *channel;
|
WebRTCDataChannel *channel;
|
||||||
|
|
||||||
channel = _find_data_channel (webrtc, &id,
|
channel = _find_data_channel (webrtc, &id,
|
||||||
(FindDataChannelFunc) data_channel_match_for_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 */
|
/* this is called from the webrtc thread with the pc lock held */
|
||||||
static void
|
static void
|
||||||
_on_data_channel_ready_state (GstWebRTCDataChannel * channel,
|
_on_data_channel_ready_state (WebRTCDataChannel * channel,
|
||||||
GParamSpec * pspec, GstWebRTCBin * webrtc)
|
GParamSpec * pspec, GstWebRTCBin * webrtc)
|
||||||
{
|
{
|
||||||
GstWebRTCDataChannelState ready_state;
|
GstWebRTCDataChannelState ready_state;
|
||||||
@ -1749,7 +1749,7 @@ _on_data_channel_ready_state (GstWebRTCDataChannel * channel,
|
|||||||
gboolean found = FALSE;
|
gboolean found = FALSE;
|
||||||
|
|
||||||
for (i = 0; i < webrtc->priv->pending_data_channels->len; i++) {
|
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);
|
c = g_ptr_array_index (webrtc->priv->pending_data_channels, i);
|
||||||
if (c == channel) {
|
if (c == channel) {
|
||||||
@ -1774,7 +1774,7 @@ static void
|
|||||||
_on_sctpdec_pad_added (GstElement * sctpdec, GstPad * pad,
|
_on_sctpdec_pad_added (GstElement * sctpdec, GstPad * pad,
|
||||||
GstWebRTCBin * webrtc)
|
GstWebRTCBin * webrtc)
|
||||||
{
|
{
|
||||||
GstWebRTCDataChannel *channel;
|
WebRTCDataChannel *channel;
|
||||||
guint stream_id;
|
guint stream_id;
|
||||||
GstPad *sink_pad;
|
GstPad *sink_pad;
|
||||||
|
|
||||||
@ -1784,8 +1784,8 @@ _on_sctpdec_pad_added (GstElement * sctpdec, GstPad * pad,
|
|||||||
PC_LOCK (webrtc);
|
PC_LOCK (webrtc);
|
||||||
channel = _find_data_channel_for_id (webrtc, stream_id);
|
channel = _find_data_channel_for_id (webrtc, stream_id);
|
||||||
if (!channel) {
|
if (!channel) {
|
||||||
channel = g_object_new (GST_TYPE_WEBRTC_DATA_CHANNEL, NULL);
|
channel = g_object_new (WEBRTC_TYPE_DATA_CHANNEL, NULL);
|
||||||
channel->id = stream_id;
|
channel->parent.id = stream_id;
|
||||||
channel->webrtcbin = webrtc;
|
channel->webrtcbin = webrtc;
|
||||||
|
|
||||||
gst_bin_add (GST_BIN (webrtc), channel->appsrc);
|
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->appsrc);
|
||||||
gst_element_sync_state_with_parent (channel->appsink);
|
gst_element_sync_state_with_parent (channel->appsink);
|
||||||
|
|
||||||
gst_webrtc_data_channel_link_to_sctp (channel,
|
webrtc_data_channel_link_to_sctp (channel, webrtc->priv->sctp_transport);
|
||||||
webrtc->priv->sctp_transport);
|
|
||||||
|
|
||||||
g_ptr_array_add (webrtc->priv->pending_data_channels, channel);
|
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");
|
GST_DEBUG_OBJECT (webrtc, "SCTP association established");
|
||||||
|
|
||||||
for (i = 0; i < webrtc->priv->data_channels->len; i++) {
|
for (i = 0; i < webrtc->priv->data_channels->len; i++) {
|
||||||
GstWebRTCDataChannel *channel;
|
WebRTCDataChannel *channel;
|
||||||
|
|
||||||
channel = g_ptr_array_index (webrtc->priv->data_channels, i);
|
channel = g_ptr_array_index (webrtc->priv->data_channels, i);
|
||||||
|
|
||||||
gst_webrtc_data_channel_link_to_sctp (channel,
|
webrtc_data_channel_link_to_sctp (channel, webrtc->priv->sctp_transport);
|
||||||
webrtc->priv->sctp_transport);
|
|
||||||
|
|
||||||
if (!channel->negotiated && !channel->opened)
|
if (!channel->parent.negotiated && !channel->opened)
|
||||||
gst_webrtc_data_channel_start_negotiation (channel);
|
webrtc_data_channel_start_negotiation (channel);
|
||||||
}
|
}
|
||||||
PC_UNLOCK (webrtc);
|
PC_UNLOCK (webrtc);
|
||||||
}
|
}
|
||||||
@ -1993,12 +1991,11 @@ _get_or_create_data_channel_transports (GstWebRTCBin * webrtc, guint session_id)
|
|||||||
g_warn_if_reached ();
|
g_warn_if_reached ();
|
||||||
|
|
||||||
for (i = 0; i < webrtc->priv->data_channels->len; i++) {
|
for (i = 0; i < webrtc->priv->data_channels->len; i++) {
|
||||||
GstWebRTCDataChannel *channel;
|
WebRTCDataChannel *channel;
|
||||||
|
|
||||||
channel = g_ptr_array_index (webrtc->priv->data_channels, i);
|
channel = g_ptr_array_index (webrtc->priv->data_channels, i);
|
||||||
|
|
||||||
gst_webrtc_data_channel_link_to_sctp (channel,
|
webrtc_data_channel_link_to_sctp (channel, webrtc->priv->sctp_transport);
|
||||||
webrtc->priv->sctp_transport);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_element_sync_state_with_parent (GST_ELEMENT (stream->send_bin));
|
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 */
|
/* TODO: a better search algorithm */
|
||||||
do {
|
do {
|
||||||
GstWebRTCDataChannel *channel;
|
WebRTCDataChannel *channel;
|
||||||
|
|
||||||
new_id++;
|
new_id++;
|
||||||
|
|
||||||
@ -4087,21 +4084,20 @@ _update_data_channel_from_sdp_media (GstWebRTCBin * webrtc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < webrtc->priv->data_channels->len; i++) {
|
for (i = 0; i < webrtc->priv->data_channels->len; i++) {
|
||||||
GstWebRTCDataChannel *channel;
|
WebRTCDataChannel *channel;
|
||||||
|
|
||||||
channel = g_ptr_array_index (webrtc->priv->data_channels, i);
|
channel = g_ptr_array_index (webrtc->priv->data_channels, i);
|
||||||
|
|
||||||
if (channel->id == -1)
|
if (channel->parent.id == -1)
|
||||||
channel->id = _generate_data_channel_id (webrtc);
|
channel->parent.id = _generate_data_channel_id (webrtc);
|
||||||
if (channel->id == -1)
|
if (channel->parent.id == -1)
|
||||||
GST_ELEMENT_WARNING (webrtc, RESOURCE, NOT_FOUND,
|
GST_ELEMENT_WARNING (webrtc, RESOURCE, NOT_FOUND,
|
||||||
("%s", "Failed to generate an identifier for a data channel"), NULL);
|
("%s", "Failed to generate an identifier for a data channel"), NULL);
|
||||||
|
|
||||||
if (webrtc->priv->sctp_transport->association_established
|
if (webrtc->priv->sctp_transport->association_established
|
||||||
&& !channel->negotiated && !channel->opened) {
|
&& !channel->parent.negotiated && !channel->opened) {
|
||||||
gst_webrtc_data_channel_link_to_sctp (channel,
|
webrtc_data_channel_link_to_sctp (channel, webrtc->priv->sctp_transport);
|
||||||
webrtc->priv->sctp_transport);
|
webrtc_data_channel_start_negotiation (channel);
|
||||||
gst_webrtc_data_channel_start_negotiation (channel);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5049,7 +5045,7 @@ copy_sticky_events (GstPad * pad, GstEvent ** event, gpointer user_data)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstWebRTCDataChannel *
|
static WebRTCDataChannel *
|
||||||
gst_webrtc_bin_create_data_channel (GstWebRTCBin * webrtc, const gchar * label,
|
gst_webrtc_bin_create_data_channel (GstWebRTCBin * webrtc, const gchar * label,
|
||||||
GstStructure * init_params)
|
GstStructure * init_params)
|
||||||
{
|
{
|
||||||
@ -5060,7 +5056,7 @@ gst_webrtc_bin_create_data_channel (GstWebRTCBin * webrtc, const gchar * label,
|
|||||||
gboolean negotiated;
|
gboolean negotiated;
|
||||||
gint id;
|
gint id;
|
||||||
GstWebRTCPriorityType priority;
|
GstWebRTCPriorityType priority;
|
||||||
GstWebRTCDataChannel *ret;
|
WebRTCDataChannel *ret;
|
||||||
gint max_channels = 65534;
|
gint max_channels = 65534;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_WEBRTC_BIN (webrtc), NULL);
|
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);
|
PC_LOCK (webrtc);
|
||||||
/* check if the id has been used already */
|
/* check if the id has been used already */
|
||||||
if (id != -1) {
|
if (id != -1) {
|
||||||
GstWebRTCDataChannel *channel = _find_data_channel_for_id (webrtc, id);
|
WebRTCDataChannel *channel = _find_data_channel_for_id (webrtc, id);
|
||||||
if (channel) {
|
if (channel) {
|
||||||
GST_ELEMENT_WARNING (webrtc, LIBRARY, SETTINGS,
|
GST_ELEMENT_WARNING (webrtc, LIBRARY, SETTINGS,
|
||||||
("Attempting to add a data channel with a duplicate ID: %i", id),
|
("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,
|
"ordered", ordered, "max-packet-lifetime", max_packet_lifetime,
|
||||||
"max-retransmits", max_retransmits, "protocol", protocol,
|
"max-retransmits", max_retransmits, "protocol", protocol,
|
||||||
"negotiated", negotiated, "id", id, "priority", priority, NULL);
|
"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 = gst_object_ref (ret);
|
||||||
ret->webrtcbin = webrtc;
|
ret->webrtcbin = webrtc;
|
||||||
g_ptr_array_add (webrtc->priv->data_channels, ret);
|
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 &&
|
if (webrtc->priv->sctp_transport &&
|
||||||
webrtc->priv->sctp_transport->association_established
|
webrtc->priv->sctp_transport->association_established
|
||||||
&& !ret->negotiated) {
|
&& !ret->parent.negotiated) {
|
||||||
gst_webrtc_data_channel_start_negotiation (ret);
|
webrtc_data_channel_start_negotiation (ret);
|
||||||
} else {
|
} else {
|
||||||
_update_need_negotiation (webrtc);
|
_update_need_negotiation (webrtc);
|
||||||
}
|
}
|
||||||
|
@ -41,49 +41,14 @@
|
|||||||
#include "gstwebrtcbin.h"
|
#include "gstwebrtcbin.h"
|
||||||
#include "utils.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);
|
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||||
|
|
||||||
#define gst_webrtc_data_channel_parent_class parent_class
|
#define webrtc_data_channel_parent_class parent_class
|
||||||
G_DEFINE_TYPE_WITH_CODE (GstWebRTCDataChannel, gst_webrtc_data_channel,
|
G_DEFINE_TYPE_WITH_CODE (WebRTCDataChannel, webrtc_data_channel,
|
||||||
G_TYPE_OBJECT, GST_DEBUG_CATEGORY_INIT (gst_webrtc_data_channel_debug,
|
GST_TYPE_WEBRTC_DATA_CHANNEL,
|
||||||
"webrtcdatachannel", 0, "webrtcdatachannel"););
|
GST_DEBUG_CATEGORY_INIT (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 };
|
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
@ -142,11 +107,11 @@ priority_uint_to_type (guint16 val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static GstBuffer *
|
static GstBuffer *
|
||||||
construct_open_packet (GstWebRTCDataChannel * channel)
|
construct_open_packet (WebRTCDataChannel * channel)
|
||||||
{
|
{
|
||||||
GstByteWriter w;
|
GstByteWriter w;
|
||||||
gsize label_len = strlen (channel->label);
|
gsize label_len = strlen (channel->parent.label);
|
||||||
gsize proto_len = strlen (channel->protocol);
|
gsize proto_len = strlen (channel->parent.protocol);
|
||||||
gsize size = 12 + label_len + proto_len;
|
gsize size = 12 + label_len + proto_len;
|
||||||
DataChannelReliabilityType reliability = 0;
|
DataChannelReliabilityType reliability = 0;
|
||||||
guint32 reliability_param = 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))
|
if (!gst_byte_writer_put_uint8 (&w, (guint8) CHANNEL_MESSAGE_OPEN))
|
||||||
g_return_val_if_reached (NULL);
|
g_return_val_if_reached (NULL);
|
||||||
|
|
||||||
if (!channel->ordered)
|
if (!channel->parent.ordered)
|
||||||
reliability |= 0x80;
|
reliability |= 0x80;
|
||||||
if (channel->max_retransmits != -1) {
|
if (channel->parent.max_retransmits != -1) {
|
||||||
reliability |= 0x01;
|
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 |= 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))
|
if (!gst_byte_writer_put_uint8 (&w, (guint8) reliability))
|
||||||
g_return_val_if_reached (NULL);
|
g_return_val_if_reached (NULL);
|
||||||
@ -201,9 +166,11 @@ construct_open_packet (GstWebRTCDataChannel * channel)
|
|||||||
g_return_val_if_reached (NULL);
|
g_return_val_if_reached (NULL);
|
||||||
if (!gst_byte_writer_put_uint16_be (&w, (guint16) proto_len))
|
if (!gst_byte_writer_put_uint16_be (&w, (guint16) proto_len))
|
||||||
g_return_val_if_reached (NULL);
|
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);
|
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);
|
g_return_val_if_reached (NULL);
|
||||||
|
|
||||||
buf = gst_byte_writer_reset_and_get_buffer (&w);
|
buf = gst_byte_writer_reset_and_get_buffer (&w);
|
||||||
@ -216,7 +183,7 @@ construct_open_packet (GstWebRTCDataChannel * channel)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static GstBuffer *
|
static GstBuffer *
|
||||||
construct_ack_packet (GstWebRTCDataChannel * channel)
|
construct_ack_packet (WebRTCDataChannel * channel)
|
||||||
{
|
{
|
||||||
GstByteWriter w;
|
GstByteWriter w;
|
||||||
GstBuffer *buf;
|
GstBuffer *buf;
|
||||||
@ -272,7 +239,7 @@ _free_task (struct task *task)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_channel_enqueue_task (GstWebRTCDataChannel * channel, ChannelTask func,
|
_channel_enqueue_task (WebRTCDataChannel * channel, ChannelTask func,
|
||||||
gpointer user_data, GDestroyNotify notify)
|
gpointer user_data, GDestroyNotify notify)
|
||||||
{
|
{
|
||||||
struct task *task = g_new0 (struct task, 1);
|
struct task *task = g_new0 (struct task, 1);
|
||||||
@ -288,9 +255,9 @@ _channel_enqueue_task (GstWebRTCDataChannel * channel, ChannelTask func,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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) {
|
if (error) {
|
||||||
GST_WARNING_OBJECT (channel, "Error: %s",
|
GST_WARNING_OBJECT (channel, "Error: %s",
|
||||||
error ? error->message : "Unknown");
|
error ? error->message : "Unknown");
|
||||||
@ -299,76 +266,32 @@ _channel_store_error (GstWebRTCDataChannel * channel, GError * error)
|
|||||||
else
|
else
|
||||||
g_clear_error (&error);
|
g_clear_error (&error);
|
||||||
}
|
}
|
||||||
CHANNEL_UNLOCK (channel);
|
GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_maybe_emit_on_error (GstWebRTCDataChannel * channel, GError * error)
|
_emit_on_open (WebRTCDataChannel * channel, gpointer user_data)
|
||||||
{
|
{
|
||||||
if (error) {
|
gst_webrtc_data_channel_on_open (GST_WEBRTC_DATA_CHANNEL (channel));
|
||||||
GST_WARNING_OBJECT (channel, "error thrown");
|
|
||||||
g_signal_emit (channel, gst_webrtc_data_channel_signals[SIGNAL_ON_ERROR], 0,
|
|
||||||
error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_emit_on_open (GstWebRTCDataChannel * channel, gpointer user_data)
|
_transport_closed (WebRTCDataChannel * channel)
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
GError *error;
|
GError *error;
|
||||||
|
|
||||||
if (channel->ready_state == GST_WEBRTC_DATA_CHANNEL_STATE_CLOSED)
|
GST_WEBRTC_DATA_CHANNEL_LOCK (channel);
|
||||||
return;
|
|
||||||
|
|
||||||
channel->ready_state = GST_WEBRTC_DATA_CHANNEL_STATE_CLOSED;
|
|
||||||
|
|
||||||
error = channel->stored_error;
|
error = channel->stored_error;
|
||||||
channel->stored_error = NULL;
|
channel->stored_error = NULL;
|
||||||
CHANNEL_UNLOCK (channel);
|
GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
|
||||||
|
|
||||||
g_object_notify (G_OBJECT (channel), "ready-state");
|
if (error)
|
||||||
GST_INFO_OBJECT (channel, "We are closed for data");
|
gst_webrtc_data_channel_on_error (GST_WEBRTC_DATA_CHANNEL (channel), error);
|
||||||
|
gst_webrtc_data_channel_on_close (GST_WEBRTC_DATA_CHANNEL (channel));
|
||||||
_maybe_emit_on_error (channel, error);
|
|
||||||
|
|
||||||
g_signal_emit (channel, gst_webrtc_data_channel_signals[SIGNAL_ON_CLOSE], 0,
|
|
||||||
NULL);
|
|
||||||
CHANNEL_LOCK (channel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_transport_closed (GstWebRTCDataChannel * channel, gpointer user_data)
|
_close_sctp_stream (WebRTCDataChannel * channel, gpointer user_data)
|
||||||
{
|
|
||||||
CHANNEL_LOCK (channel);
|
|
||||||
_transport_closed_unlocked (channel);
|
|
||||||
CHANNEL_UNLOCK (channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
_close_sctp_stream (GstWebRTCDataChannel * channel, gpointer user_data)
|
|
||||||
{
|
{
|
||||||
GstPad *pad, *peer;
|
GstPad *pad, *peer;
|
||||||
|
|
||||||
@ -386,49 +309,49 @@ _close_sctp_stream (GstWebRTCDataChannel * channel, gpointer user_data)
|
|||||||
gst_object_unref (peer);
|
gst_object_unref (peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
_transport_closed (channel, NULL);
|
_transport_closed (channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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 */
|
/* https://www.w3.org/TR/webrtc/#data-transport-closing-procedure */
|
||||||
CHANNEL_LOCK (channel);
|
GST_WEBRTC_DATA_CHANNEL_LOCK (channel);
|
||||||
if (channel->ready_state == GST_WEBRTC_DATA_CHANNEL_STATE_CLOSED
|
if (channel->parent.ready_state == GST_WEBRTC_DATA_CHANNEL_STATE_CLOSED
|
||||||
|| channel->ready_state == GST_WEBRTC_DATA_CHANNEL_STATE_CLOSING) {
|
|| channel->parent.ready_state == GST_WEBRTC_DATA_CHANNEL_STATE_CLOSING) {
|
||||||
CHANNEL_UNLOCK (channel);
|
GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
channel->ready_state = GST_WEBRTC_DATA_CHANNEL_STATE_CLOSING;
|
channel->parent.ready_state = GST_WEBRTC_DATA_CHANNEL_STATE_CLOSING;
|
||||||
CHANNEL_UNLOCK (channel);
|
GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
|
||||||
g_object_notify (G_OBJECT (channel), "ready-state");
|
g_object_notify (G_OBJECT (channel), "ready-state");
|
||||||
|
|
||||||
CHANNEL_LOCK (channel);
|
GST_WEBRTC_DATA_CHANNEL_LOCK (channel);
|
||||||
if (channel->buffered_amount <= 0) {
|
if (channel->parent.buffered_amount <= 0) {
|
||||||
_channel_enqueue_task (channel, (ChannelTask) _close_sctp_stream,
|
_channel_enqueue_task (channel, (ChannelTask) _close_sctp_stream,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
CHANNEL_UNLOCK (channel);
|
GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_on_sctp_reset_stream (GstWebRTCSCTPTransport * sctp, guint stream_id,
|
_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,
|
_channel_enqueue_task (channel, (ChannelTask) _transport_closed,
|
||||||
GUINT_TO_POINTER (stream_id), NULL);
|
GUINT_TO_POINTER (stream_id), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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
|
static GstFlowReturn
|
||||||
_parse_control_packet (GstWebRTCDataChannel * channel, guint8 * data,
|
_parse_control_packet (WebRTCDataChannel * channel, guint8 * data,
|
||||||
gsize size, GError ** error)
|
gsize size, GError ** error)
|
||||||
{
|
{
|
||||||
GstByteReader r;
|
GstByteReader r;
|
||||||
@ -460,7 +383,7 @@ _parse_control_packet (GstWebRTCDataChannel * channel, guint8 * data,
|
|||||||
|
|
||||||
GST_INFO_OBJECT (channel, "Received channel open");
|
GST_INFO_OBJECT (channel, "Received channel open");
|
||||||
|
|
||||||
if (channel->negotiated) {
|
if (channel->parent.negotiated) {
|
||||||
g_set_error (error, GST_WEBRTC_BIN_ERROR,
|
g_set_error (error, GST_WEBRTC_BIN_ERROR,
|
||||||
GST_WEBRTC_BIN_ERROR_DATA_CHANNEL_FAILURE,
|
GST_WEBRTC_BIN_ERROR_DATA_CHANNEL_FAILURE,
|
||||||
"Data channel was signalled as negotiated already");
|
"Data channel was signalled as negotiated already");
|
||||||
@ -493,34 +416,35 @@ _parse_control_packet (GstWebRTCDataChannel * channel, guint8 * data,
|
|||||||
memcpy (proto, src, proto_len);
|
memcpy (proto, src, proto_len);
|
||||||
proto[proto_len] = '\0';
|
proto[proto_len] = '\0';
|
||||||
|
|
||||||
channel->label = label;
|
channel->parent.label = label;
|
||||||
channel->protocol = proto;
|
channel->parent.protocol = proto;
|
||||||
channel->priority = priority_uint_to_type (priority);
|
channel->parent.priority = priority_uint_to_type (priority);
|
||||||
channel->ordered = !(reliability & 0x80);
|
channel->parent.ordered = !(reliability & 0x80);
|
||||||
if (reliability & 0x01) {
|
if (reliability & 0x01) {
|
||||||
channel->max_retransmits = reliability_param;
|
channel->parent.max_retransmits = reliability_param;
|
||||||
channel->max_packet_lifetime = -1;
|
channel->parent.max_packet_lifetime = -1;
|
||||||
} else if (reliability & 0x02) {
|
} else if (reliability & 0x02) {
|
||||||
channel->max_retransmits = -1;
|
channel->parent.max_retransmits = -1;
|
||||||
channel->max_packet_lifetime = reliability_param;
|
channel->parent.max_packet_lifetime = reliability_param;
|
||||||
} else {
|
} else {
|
||||||
channel->max_retransmits = -1;
|
channel->parent.max_retransmits = -1;
|
||||||
channel->max_packet_lifetime = -1;
|
channel->parent.max_packet_lifetime = -1;
|
||||||
}
|
}
|
||||||
channel->opened = TRUE;
|
channel->opened = TRUE;
|
||||||
|
|
||||||
GST_INFO_OBJECT (channel, "Received channel open for SCTP stream %i "
|
GST_INFO_OBJECT (channel, "Received channel open for SCTP stream %i "
|
||||||
"label %s protocol %s ordered %s", channel->id, channel->label,
|
"label %s protocol %s ordered %s", channel->parent.id,
|
||||||
channel->protocol, channel->ordered ? "true" : "false");
|
channel->parent.label, channel->parent.protocol,
|
||||||
|
channel->parent.ordered ? "true" : "false");
|
||||||
|
|
||||||
_channel_enqueue_task (channel, (ChannelTask) _emit_on_open, NULL, NULL);
|
_channel_enqueue_task (channel, (ChannelTask) _emit_on_open, NULL, NULL);
|
||||||
|
|
||||||
GST_INFO_OBJECT (channel, "Sending channel ack");
|
GST_INFO_OBJECT (channel, "Sending channel ack");
|
||||||
buffer = construct_ack_packet (channel);
|
buffer = construct_ack_packet (channel);
|
||||||
|
|
||||||
CHANNEL_LOCK (channel);
|
GST_WEBRTC_DATA_CHANNEL_LOCK (channel);
|
||||||
channel->buffered_amount += gst_buffer_get_size (buffer);
|
channel->parent.buffered_amount += gst_buffer_get_size (buffer);
|
||||||
CHANNEL_UNLOCK (channel);
|
GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
|
||||||
|
|
||||||
ret = gst_app_src_push_buffer (GST_APP_SRC (channel->appsrc), buffer);
|
ret = gst_app_src_push_buffer (GST_APP_SRC (channel->appsrc), buffer);
|
||||||
if (ret != GST_FLOW_OK) {
|
if (ret != GST_FLOW_OK) {
|
||||||
@ -568,23 +492,21 @@ buffer_unmap_and_unref (struct map_info *info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_emit_have_data (GstWebRTCDataChannel * channel, GBytes * data)
|
_emit_have_data (WebRTCDataChannel * channel, GBytes * data)
|
||||||
{
|
{
|
||||||
GST_LOG_OBJECT (channel, "Have data %p", data);
|
gst_webrtc_data_channel_on_message_data (GST_WEBRTC_DATA_CHANNEL (channel),
|
||||||
g_signal_emit (channel,
|
data);
|
||||||
gst_webrtc_data_channel_signals[SIGNAL_ON_MESSAGE_DATA], 0, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_emit_have_string (GstWebRTCDataChannel * channel, gchar * str)
|
_emit_have_string (GstWebRTCDataChannel * channel, gchar * str)
|
||||||
{
|
{
|
||||||
GST_LOG_OBJECT (channel, "Have string %p", str);
|
gst_webrtc_data_channel_on_message_string (GST_WEBRTC_DATA_CHANNEL (channel),
|
||||||
g_signal_emit (channel,
|
str);
|
||||||
gst_webrtc_data_channel_signals[SIGNAL_ON_MESSAGE_STRING], 0, str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
_data_channel_have_sample (GstWebRTCDataChannel * channel, GstSample * sample,
|
_data_channel_have_sample (WebRTCDataChannel * channel, GstSample * sample,
|
||||||
GError ** error)
|
GError ** error)
|
||||||
{
|
{
|
||||||
GstSctpReceiveMeta *receive;
|
GstSctpReceiveMeta *receive;
|
||||||
@ -678,7 +600,7 @@ _data_channel_have_sample (GstWebRTCDataChannel * channel, GstSample * sample,
|
|||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
on_sink_preroll (GstAppSink * sink, gpointer user_data)
|
on_sink_preroll (GstAppSink * sink, gpointer user_data)
|
||||||
{
|
{
|
||||||
GstWebRTCDataChannel *channel = user_data;
|
WebRTCDataChannel *channel = user_data;
|
||||||
GstSample *sample = gst_app_sink_pull_preroll (sink);
|
GstSample *sample = gst_app_sink_pull_preroll (sink);
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
|
|
||||||
@ -703,7 +625,7 @@ on_sink_preroll (GstAppSink * sink, gpointer user_data)
|
|||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
on_sink_sample (GstAppSink * sink, gpointer user_data)
|
on_sink_sample (GstAppSink * sink, gpointer user_data)
|
||||||
{
|
{
|
||||||
GstWebRTCDataChannel *channel = user_data;
|
WebRTCDataChannel *channel = user_data;
|
||||||
GstSample *sample = gst_app_sink_pull_sample (sink);
|
GstSample *sample = gst_app_sink_pull_sample (sink);
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
@ -734,23 +656,24 @@ static GstAppSinkCallbacks sink_callbacks = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
gst_webrtc_data_channel_start_negotiation (GstWebRTCDataChannel * channel)
|
webrtc_data_channel_start_negotiation (WebRTCDataChannel * channel)
|
||||||
{
|
{
|
||||||
GstBuffer *buffer;
|
GstBuffer *buffer;
|
||||||
|
|
||||||
g_return_if_fail (!channel->negotiated);
|
g_return_if_fail (!channel->parent.negotiated);
|
||||||
g_return_if_fail (channel->id != -1);
|
g_return_if_fail (channel->parent.id != -1);
|
||||||
g_return_if_fail (channel->sctp_transport != NULL);
|
g_return_if_fail (channel->sctp_transport != NULL);
|
||||||
|
|
||||||
buffer = construct_open_packet (channel);
|
buffer = construct_open_packet (channel);
|
||||||
|
|
||||||
GST_INFO_OBJECT (channel, "Sending channel open for SCTP stream %i "
|
GST_INFO_OBJECT (channel, "Sending channel open for SCTP stream %i "
|
||||||
"label %s protocol %s ordered %s", channel->id, channel->label,
|
"label %s protocol %s ordered %s", channel->parent.id,
|
||||||
channel->protocol, channel->ordered ? "true" : "false");
|
channel->parent.label, channel->parent.protocol,
|
||||||
|
channel->parent.ordered ? "true" : "false");
|
||||||
|
|
||||||
CHANNEL_LOCK (channel);
|
GST_WEBRTC_DATA_CHANNEL_LOCK (channel);
|
||||||
channel->buffered_amount += gst_buffer_get_size (buffer);
|
channel->parent.buffered_amount += gst_buffer_get_size (buffer);
|
||||||
CHANNEL_UNLOCK (channel);
|
GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
|
||||||
|
|
||||||
if (gst_app_src_push_buffer (GST_APP_SRC (channel->appsrc),
|
if (gst_app_src_push_buffer (GST_APP_SRC (channel->appsrc),
|
||||||
buffer) == GST_FLOW_OK) {
|
buffer) == GST_FLOW_OK) {
|
||||||
@ -767,15 +690,15 @@ gst_webrtc_data_channel_start_negotiation (GstWebRTCDataChannel * channel)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_get_sctp_reliability (GstWebRTCDataChannel * channel,
|
_get_sctp_reliability (WebRTCDataChannel * channel,
|
||||||
GstSctpSendMetaPartiallyReliability * reliability, guint * rel_param)
|
GstSctpSendMetaPartiallyReliability * reliability, guint * rel_param)
|
||||||
{
|
{
|
||||||
if (channel->max_retransmits != -1) {
|
if (channel->parent.max_retransmits != -1) {
|
||||||
*reliability = GST_SCTP_SEND_META_PARTIAL_RELIABILITY_RTX;
|
*reliability = GST_SCTP_SEND_META_PARTIAL_RELIABILITY_RTX;
|
||||||
*rel_param = channel->max_retransmits;
|
*rel_param = channel->parent.max_retransmits;
|
||||||
} else if (channel->max_packet_lifetime != -1) {
|
} else if (channel->parent.max_packet_lifetime != -1) {
|
||||||
*reliability = GST_SCTP_SEND_META_PARTIAL_RELIABILITY_TTL;
|
*reliability = GST_SCTP_SEND_META_PARTIAL_RELIABILITY_TTL;
|
||||||
*rel_param = channel->max_packet_lifetime;
|
*rel_param = channel->parent.max_packet_lifetime;
|
||||||
} else {
|
} else {
|
||||||
*reliability = GST_SCTP_SEND_META_PARTIAL_RELIABILITY_NONE;
|
*reliability = GST_SCTP_SEND_META_PARTIAL_RELIABILITY_NONE;
|
||||||
*rel_param = 0;
|
*rel_param = 0;
|
||||||
@ -783,15 +706,16 @@ _get_sctp_reliability (GstWebRTCDataChannel * channel,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
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;
|
return size <= channel->sctp_transport->max_message_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_webrtc_data_channel_send_data (GstWebRTCDataChannel * channel,
|
webrtc_data_channel_send_data (GstWebRTCDataChannel * base_channel,
|
||||||
GBytes * bytes)
|
GBytes * bytes)
|
||||||
{
|
{
|
||||||
|
WebRTCDataChannel *channel = WEBRTC_DATA_CHANNEL (base_channel);
|
||||||
GstSctpSendMetaPartiallyReliability reliability;
|
GstSctpSendMetaPartiallyReliability reliability;
|
||||||
guint rel_param;
|
guint rel_param;
|
||||||
guint32 ppid;
|
guint32 ppid;
|
||||||
@ -824,15 +748,15 @@ gst_webrtc_data_channel_send_data (GstWebRTCDataChannel * channel,
|
|||||||
}
|
}
|
||||||
|
|
||||||
_get_sctp_reliability (channel, &reliability, &rel_param);
|
_get_sctp_reliability (channel, &reliability, &rel_param);
|
||||||
gst_sctp_buffer_add_send_meta (buffer, ppid, channel->ordered, reliability,
|
gst_sctp_buffer_add_send_meta (buffer, ppid, channel->parent.ordered,
|
||||||
rel_param);
|
reliability, rel_param);
|
||||||
|
|
||||||
GST_LOG_OBJECT (channel, "Sending data using buffer %" GST_PTR_FORMAT,
|
GST_LOG_OBJECT (channel, "Sending data using buffer %" GST_PTR_FORMAT,
|
||||||
buffer);
|
buffer);
|
||||||
|
|
||||||
CHANNEL_LOCK (channel);
|
GST_WEBRTC_DATA_CHANNEL_LOCK (channel);
|
||||||
channel->buffered_amount += gst_buffer_get_size (buffer);
|
channel->parent.buffered_amount += gst_buffer_get_size (buffer);
|
||||||
CHANNEL_UNLOCK (channel);
|
GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
|
||||||
|
|
||||||
ret = gst_app_src_push_buffer (GST_APP_SRC (channel->appsrc), buffer);
|
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
|
static void
|
||||||
gst_webrtc_data_channel_send_string (GstWebRTCDataChannel * channel,
|
webrtc_data_channel_send_string (GstWebRTCDataChannel * base_channel,
|
||||||
gchar * str)
|
const gchar * str)
|
||||||
{
|
{
|
||||||
|
WebRTCDataChannel *channel = WEBRTC_DATA_CHANNEL (base_channel);
|
||||||
GstSctpSendMetaPartiallyReliability reliability;
|
GstSctpSendMetaPartiallyReliability reliability;
|
||||||
guint rel_param;
|
guint rel_param;
|
||||||
guint32 ppid;
|
guint32 ppid;
|
||||||
GstBuffer *buffer;
|
GstBuffer *buffer;
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
|
|
||||||
if (!channel->negotiated)
|
if (!channel->parent.negotiated)
|
||||||
g_return_if_fail (channel->opened);
|
g_return_if_fail (channel->opened);
|
||||||
g_return_if_fail (channel->sctp_transport != NULL);
|
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);
|
_get_sctp_reliability (channel, &reliability, &rel_param);
|
||||||
gst_sctp_buffer_add_send_meta (buffer, ppid, channel->ordered, reliability,
|
gst_sctp_buffer_add_send_meta (buffer, ppid, channel->parent.ordered,
|
||||||
rel_param);
|
reliability, rel_param);
|
||||||
|
|
||||||
GST_TRACE_OBJECT (channel, "Sending string using buffer %" GST_PTR_FORMAT,
|
GST_TRACE_OBJECT (channel, "Sending string using buffer %" GST_PTR_FORMAT,
|
||||||
buffer);
|
buffer);
|
||||||
|
|
||||||
CHANNEL_LOCK (channel);
|
GST_WEBRTC_DATA_CHANNEL_LOCK (channel);
|
||||||
channel->buffered_amount += gst_buffer_get_size (buffer);
|
channel->parent.buffered_amount += gst_buffer_get_size (buffer);
|
||||||
CHANNEL_UNLOCK (channel);
|
GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
|
||||||
|
|
||||||
ret = gst_app_src_push_buffer (GST_APP_SRC (channel->appsrc), buffer);
|
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
|
static void
|
||||||
_on_sctp_notify_state_unlocked (GObject * sctp_transport,
|
_on_sctp_notify_state_unlocked (GObject * sctp_transport,
|
||||||
GstWebRTCDataChannel * channel)
|
WebRTCDataChannel * channel)
|
||||||
{
|
{
|
||||||
GstWebRTCSCTPTransportState state;
|
GstWebRTCSCTPTransportState state;
|
||||||
|
|
||||||
g_object_get (sctp_transport, "state", &state, NULL);
|
g_object_get (sctp_transport, "state", &state, NULL);
|
||||||
if (state == GST_WEBRTC_SCTP_TRANSPORT_STATE_CONNECTED) {
|
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);
|
_channel_enqueue_task (channel, (ChannelTask) _emit_on_open, NULL, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_on_sctp_notify_state (GObject * sctp_transport, GParamSpec * pspec,
|
_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);
|
_on_sctp_notify_state_unlocked (sctp_transport, channel);
|
||||||
CHANNEL_UNLOCK (channel);
|
GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_webrtc_data_channel_set_property (GObject * object, guint prop_id,
|
_emit_low_threshold (WebRTCDataChannel * channel, gpointer user_data)
|
||||||
const GValue * value, GParamSpec * pspec)
|
|
||||||
{
|
{
|
||||||
GstWebRTCDataChannel *channel = GST_WEBRTC_DATA_CHANNEL (object);
|
gst_webrtc_data_channel_on_buffered_amount_low (GST_WEBRTC_DATA_CHANNEL
|
||||||
|
(channel));
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstPadProbeReturn
|
static GstPadProbeReturn
|
||||||
on_appsrc_data (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
|
on_appsrc_data (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
|
||||||
{
|
{
|
||||||
GstWebRTCDataChannel *channel = user_data;
|
WebRTCDataChannel *channel = user_data;
|
||||||
guint64 prev_amount;
|
guint64 prev_amount;
|
||||||
guint64 size = 0;
|
guint64 size = 0;
|
||||||
|
|
||||||
@ -1041,25 +875,27 @@ on_appsrc_data (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
CHANNEL_LOCK (channel);
|
GST_WEBRTC_DATA_CHANNEL_LOCK (channel);
|
||||||
prev_amount = channel->buffered_amount;
|
prev_amount = channel->parent.buffered_amount;
|
||||||
channel->buffered_amount -= size;
|
channel->parent.buffered_amount -= size;
|
||||||
GST_TRACE_OBJECT (channel, "checking low-threshold: prev %"
|
GST_TRACE_OBJECT (channel, "checking low-threshold: prev %"
|
||||||
G_GUINT64_FORMAT " low-threshold %" G_GUINT64_FORMAT " buffered %"
|
G_GUINT64_FORMAT " low-threshold %" G_GUINT64_FORMAT " buffered %"
|
||||||
G_GUINT64_FORMAT, prev_amount, channel->buffered_amount_low_threshold,
|
G_GUINT64_FORMAT, prev_amount,
|
||||||
channel->buffered_amount);
|
channel->parent.buffered_amount_low_threshold,
|
||||||
if (prev_amount >= channel->buffered_amount_low_threshold &&
|
channel->parent.buffered_amount);
|
||||||
channel->buffered_amount < channel->buffered_amount_low_threshold) {
|
if (prev_amount >= channel->parent.buffered_amount_low_threshold
|
||||||
_channel_enqueue_task (channel, (ChannelTask) _emit_low_threshold,
|
&& channel->parent.buffered_amount <
|
||||||
NULL, NULL);
|
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
|
if (channel->parent.ready_state == GST_WEBRTC_DATA_CHANNEL_STATE_CLOSING
|
||||||
&& channel->buffered_amount <= 0) {
|
&& channel->parent.buffered_amount <= 0) {
|
||||||
_channel_enqueue_task (channel, (ChannelTask) _close_sctp_stream, NULL,
|
_channel_enqueue_task (channel, (ChannelTask) _close_sctp_stream, NULL,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
CHANNEL_UNLOCK (channel);
|
GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
return GST_PAD_PROBE_OK;
|
return GST_PAD_PROBE_OK;
|
||||||
@ -1068,7 +904,7 @@ on_appsrc_data (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
|
|||||||
static void
|
static void
|
||||||
gst_webrtc_data_channel_constructed (GObject * object)
|
gst_webrtc_data_channel_constructed (GObject * object)
|
||||||
{
|
{
|
||||||
GstWebRTCDataChannel *channel = GST_WEBRTC_DATA_CHANNEL (object);
|
WebRTCDataChannel *channel = WEBRTC_DATA_CHANNEL (object);
|
||||||
GstPad *pad;
|
GstPad *pad;
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
|
|
||||||
@ -1095,7 +931,7 @@ gst_webrtc_data_channel_constructed (GObject * object)
|
|||||||
static void
|
static void
|
||||||
gst_webrtc_data_channel_finalize (GObject * object)
|
gst_webrtc_data_channel_finalize (GObject * object)
|
||||||
{
|
{
|
||||||
GstWebRTCDataChannel *channel = GST_WEBRTC_DATA_CHANNEL (object);
|
WebRTCDataChannel *channel = WEBRTC_DATA_CHANNEL (object);
|
||||||
|
|
||||||
if (channel->src_probe) {
|
if (channel->src_probe) {
|
||||||
GstPad *pad = gst_element_get_static_pad (channel->appsrc, "src");
|
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;
|
channel->src_probe = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (channel->label);
|
|
||||||
channel->label = NULL;
|
|
||||||
|
|
||||||
g_free (channel->protocol);
|
|
||||||
channel->protocol = NULL;
|
|
||||||
|
|
||||||
if (channel->sctp_transport)
|
if (channel->sctp_transport)
|
||||||
g_signal_handlers_disconnect_by_data (channel->sctp_transport, channel);
|
g_signal_handlers_disconnect_by_data (channel->sctp_transport, channel);
|
||||||
g_clear_object (&channel->sctp_transport);
|
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->appsrc);
|
||||||
g_clear_object (&channel->appsink);
|
g_clear_object (&channel->appsink);
|
||||||
|
|
||||||
g_mutex_clear (&channel->lock);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_webrtc_data_channel_class_init (GstWebRTCDataChannelClass * klass)
|
webrtc_data_channel_class_init (WebRTCDataChannelClass * klass)
|
||||||
{
|
{
|
||||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||||
|
GstWebRTCDataChannelClass *channel_class =
|
||||||
|
(GstWebRTCDataChannelClass *) klass;
|
||||||
|
|
||||||
gobject_class->constructed = gst_webrtc_data_channel_constructed;
|
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;
|
gobject_class->finalize = gst_webrtc_data_channel_finalize;
|
||||||
|
|
||||||
g_object_class_install_property (gobject_class,
|
channel_class->send_data = webrtc_data_channel_send_data;
|
||||||
PROP_LABEL,
|
channel_class->send_string = webrtc_data_channel_send_string;
|
||||||
g_param_spec_string ("label",
|
channel_class->close = webrtc_data_channel_close;
|
||||||
"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
|
static void
|
||||||
gst_webrtc_data_channel_init (GstWebRTCDataChannel * channel)
|
webrtc_data_channel_init (WebRTCDataChannel * channel)
|
||||||
{
|
{
|
||||||
g_mutex_init (&channel->lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_data_channel_set_sctp_transport (GstWebRTCDataChannel * channel,
|
_data_channel_set_sctp_transport (WebRTCDataChannel * channel,
|
||||||
GstWebRTCSCTPTransport * sctp)
|
GstWebRTCSCTPTransport * sctp)
|
||||||
{
|
{
|
||||||
g_return_if_fail (GST_IS_WEBRTC_DATA_CHANNEL (channel));
|
g_return_if_fail (GST_IS_WEBRTC_DATA_CHANNEL (channel));
|
||||||
g_return_if_fail (GST_IS_WEBRTC_SCTP_TRANSPORT (sctp));
|
g_return_if_fail (GST_IS_WEBRTC_SCTP_TRANSPORT (sctp));
|
||||||
|
|
||||||
CHANNEL_LOCK (channel);
|
GST_WEBRTC_DATA_CHANNEL_LOCK (channel);
|
||||||
if (channel->sctp_transport)
|
if (channel->sctp_transport)
|
||||||
g_signal_handlers_disconnect_by_data (channel->sctp_transport, channel);
|
g_signal_handlers_disconnect_by_data (channel->sctp_transport, channel);
|
||||||
|
|
||||||
@ -1331,11 +991,11 @@ _data_channel_set_sctp_transport (GstWebRTCDataChannel * channel,
|
|||||||
channel);
|
channel);
|
||||||
_on_sctp_notify_state_unlocked (G_OBJECT (sctp), channel);
|
_on_sctp_notify_state_unlocked (G_OBJECT (sctp), channel);
|
||||||
}
|
}
|
||||||
CHANNEL_UNLOCK (channel);
|
GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gst_webrtc_data_channel_link_to_sctp (GstWebRTCDataChannel * channel,
|
webrtc_data_channel_link_to_sctp (WebRTCDataChannel * channel,
|
||||||
GstWebRTCSCTPTransport * sctp_transport)
|
GstWebRTCSCTPTransport * sctp_transport)
|
||||||
{
|
{
|
||||||
if (sctp_transport && !channel->sctp_transport) {
|
if (sctp_transport && !channel->sctp_transport) {
|
||||||
|
@ -17,68 +17,56 @@
|
|||||||
* Boston, MA 02110-1301, USA.
|
* Boston, MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __GST_WEBRTC_DATA_CHANNEL_H__
|
#ifndef __WEBRTC_DATA_CHANNEL_H__
|
||||||
#define __GST_WEBRTC_DATA_CHANNEL_H__
|
#define __WEBRTC_DATA_CHANNEL_H__
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gst/webrtc/webrtc_fwd.h>
|
#include <gst/webrtc/webrtc_fwd.h>
|
||||||
#include <gst/webrtc/dtlstransport.h>
|
#include <gst/webrtc/dtlstransport.h>
|
||||||
|
#include <gst/webrtc/datachannel.h>
|
||||||
#include "sctptransport.h"
|
#include "sctptransport.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
GType gst_webrtc_data_channel_get_type(void);
|
GType webrtc_data_channel_get_type(void);
|
||||||
#define GST_TYPE_WEBRTC_DATA_CHANNEL (gst_webrtc_data_channel_get_type())
|
#define WEBRTC_TYPE_DATA_CHANNEL (webrtc_data_channel_get_type())
|
||||||
#define GST_WEBRTC_DATA_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_WEBRTC_DATA_CHANNEL,GstWebRTCDataChannel))
|
#define WEBRTC_DATA_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),WEBRTC_TYPE_DATA_CHANNEL,WebRTCDataChannel))
|
||||||
#define GST_IS_WEBRTC_DATA_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_WEBRTC_DATA_CHANNEL))
|
#define WEBRTC_IS_DATA_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),WEBRTC_TYPE_DATA_CHANNEL))
|
||||||
#define GST_WEBRTC_DATA_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_WEBRTC_DATA_CHANNEL,GstWebRTCDataChannelClass))
|
#define WEBRTC_DATA_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass) ,WEBRTC_TYPE_DATA_CHANNEL,WebRTCDataChannelClass))
|
||||||
#define GST_IS_WEBRTC_DATA_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_WEBRTC_DATA_CHANNEL))
|
#define WEBRTC_IS_DATA_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,WEBRTC_TYPE_DATA_CHANNEL))
|
||||||
#define GST_WEBRTC_DATA_CHANNEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_WEBRTC_DATA_CHANNEL,GstWebRTCDataChannelClass))
|
#define WEBRTC_DATA_CHANNEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,WEBRTC_TYPE_DATA_CHANNEL,WebRTCDataChannelClass))
|
||||||
|
|
||||||
typedef struct _GstWebRTCDataChannel GstWebRTCDataChannel;
|
typedef struct _WebRTCDataChannel WebRTCDataChannel;
|
||||||
typedef struct _GstWebRTCDataChannelClass GstWebRTCDataChannelClass;
|
typedef struct _WebRTCDataChannelClass WebRTCDataChannelClass;
|
||||||
|
|
||||||
struct _GstWebRTCDataChannel
|
struct _WebRTCDataChannel
|
||||||
{
|
{
|
||||||
GObject parent;
|
GstWebRTCDataChannel parent;
|
||||||
|
|
||||||
GstWebRTCSCTPTransport *sctp_transport;
|
GstWebRTCSCTPTransport *sctp_transport;
|
||||||
GstElement *appsrc;
|
GstElement *appsrc;
|
||||||
GstElement *appsink;
|
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;
|
GstWebRTCBin *webrtcbin;
|
||||||
gboolean opened;
|
gboolean opened;
|
||||||
gulong src_probe;
|
gulong src_probe;
|
||||||
GError *stored_error;
|
GError *stored_error;
|
||||||
GMutex lock;
|
|
||||||
|
|
||||||
gpointer _padding[GST_PADDING];
|
gpointer _padding[GST_PADDING];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstWebRTCDataChannelClass
|
struct _WebRTCDataChannelClass
|
||||||
{
|
{
|
||||||
GObjectClass parent_class;
|
GstWebRTCDataChannelClass parent_class;
|
||||||
|
|
||||||
gpointer _padding[GST_PADDING];
|
gpointer _padding[GST_PADDING];
|
||||||
};
|
};
|
||||||
|
|
||||||
void gst_webrtc_data_channel_start_negotiation (GstWebRTCDataChannel *channel);
|
void webrtc_data_channel_start_negotiation (WebRTCDataChannel *channel);
|
||||||
G_GNUC_INTERNAL
|
G_GNUC_INTERNAL
|
||||||
void gst_webrtc_data_channel_link_to_sctp (GstWebRTCDataChannel *channel,
|
void webrtc_data_channel_link_to_sctp (WebRTCDataChannel *channel,
|
||||||
GstWebRTCSCTPTransport *sctp_transport);
|
GstWebRTCSCTPTransport *sctp_transport);
|
||||||
|
|
||||||
G_END_DECLS
|
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',
|
'rtpreceiver.c',
|
||||||
'rtpsender.c',
|
'rtpsender.c',
|
||||||
'rtptransceiver.c',
|
'rtptransceiver.c',
|
||||||
|
'datachannel.c',
|
||||||
]
|
]
|
||||||
|
|
||||||
webrtc_headers = [
|
webrtc_headers = [
|
||||||
@ -14,6 +15,7 @@ webrtc_headers = [
|
|||||||
'rtpreceiver.h',
|
'rtpreceiver.h',
|
||||||
'rtpsender.h',
|
'rtpsender.h',
|
||||||
'rtptransceiver.h',
|
'rtptransceiver.h',
|
||||||
|
'datachannel.h',
|
||||||
'webrtc_fwd.h',
|
'webrtc_fwd.h',
|
||||||
'webrtc.h',
|
'webrtc.h',
|
||||||
]
|
]
|
||||||
|
@ -29,5 +29,6 @@
|
|||||||
#include <gst/webrtc/rtpreceiver.h>
|
#include <gst/webrtc/rtpreceiver.h>
|
||||||
#include <gst/webrtc/rtpsender.h>
|
#include <gst/webrtc/rtpsender.h>
|
||||||
#include <gst/webrtc/rtptransceiver.h>
|
#include <gst/webrtc/rtptransceiver.h>
|
||||||
|
#include <gst/webrtc/datachannel.h>
|
||||||
|
|
||||||
#endif /* __GST_WEBRTC_WEBRTC_H__ */
|
#endif /* __GST_WEBRTC_WEBRTC_H__ */
|
||||||
|
@ -59,6 +59,9 @@ typedef struct _GstWebRTCSessionDescription GstWebRTCSessionDescription;
|
|||||||
typedef struct _GstWebRTCRTPTransceiver GstWebRTCRTPTransceiver;
|
typedef struct _GstWebRTCRTPTransceiver GstWebRTCRTPTransceiver;
|
||||||
typedef struct _GstWebRTCRTPTransceiverClass GstWebRTCRTPTransceiverClass;
|
typedef struct _GstWebRTCRTPTransceiverClass GstWebRTCRTPTransceiverClass;
|
||||||
|
|
||||||
|
typedef struct _GstWebRTCDataChannel GstWebRTCDataChannel;
|
||||||
|
typedef struct _GstWebRTCDataChannelClass GstWebRTCDataChannelClass;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstWebRTCDTLSTransportState:
|
* GstWebRTCDTLSTransportState:
|
||||||
* @GST_WEBRTC_DTLS_TRANSPORT_STATE_NEW: new
|
* @GST_WEBRTC_DTLS_TRANSPORT_STATE_NEW: new
|
||||||
|
Loading…
x
Reference in New Issue
Block a user