Functions are added as below.
- typedef void (*webrtc_data_channel_buffered_amount_low_cb)()
- webrtc_data_channel_get_buffered_amount()
- webrtc_data_channel_set_buffered_amount_low_cb()
- webrtc_data_channel_get_buffered_amount_low_threshold()
- webrtc_data_channel_unset_buffered_amount_low_cb()
[Version] 0.3.40
[Issue Type] API
Change-Id: I3279925a1508955eded709927639ca2249c20137
*/
typedef void (*webrtc_data_channel_close_cb)(webrtc_data_channel_h channel, void *user_data);
+/**
+ * @brief Called when the number of bytes of data currently queued to be sent over the data channel falls below the threshold.
+ * @since_tizen 7.0
+ * @remarks The @a channel is the same object for which the callback was set.\n
+ * The @a channel should not be released.
+ * @param[in] channel WebRTC data channel handle
+ * @param[in] user_data The user data passed from the callback registration function
+ * @see webrtc_create_data_channel()
+ * @see webrtc_destroy_data_channel()
+ * @see webrtc_data_channel_set_buffered_amount_low_cb()
+ * @see webrtc_data_channel_unset_buffered_amount_low_cb()
+ */
+typedef void (*webrtc_data_channel_buffered_amount_low_cb)(webrtc_data_channel_h channel, void *user_data);
/**
* @}
*/
*/
int webrtc_get_data(webrtc_bytes_data_h bytes, const char **data, unsigned long *size);
+/**
+ * @brief Gets the number of bytes of data currently queued to be sent over the data channel.
+ * @since_tizen 7.0
+ * @param[in] channel Data channel handle
+ * @param[out] buffered_amount The number of bytes of data
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #WEBRTC_ERROR_NONE Successful
+ * @retval #WEBRTC_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #WEBRTC_ERROR_INVALID_OPERATION Invalid operation
+ * @see webrtc_create_data_channel()
+ */
+int webrtc_data_channel_get_buffered_amount(webrtc_data_channel_h channel, unsigned int *buffered_amount);
+
+/**
+ * @brief Sets the threshold at which the buffered amount is considered low and callback function.
+ * @since_tizen 7.0
+ * @remarks The registered callback will be invoked in an internal thread of the webrtc.\n
+ Callback function will be invoked when the number of bytes currently queued falls below the @a threshold.
+ * @param[in] channel Data channel handle
+ * @param[in] threshold The threshold
+ * @param[in] callback Callback function pointer
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #WEBRTC_ERROR_NONE Successful
+ * @retval #WEBRTC_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #WEBRTC_ERROR_INVALID_OPERATION Invalid operation
+ * @post webrtc_data_channel_buffered_amount_low_cb() will be invoked.
+ * @see webrtc_data_channel_buffered_amount_low_cb()
+ * @see webrtc_data_channel_get_buffered_amount_low_threshold()
+ * @see webrtc_data_channel_unset_buffered_amount_low_cb()
+ */
+int webrtc_data_channel_set_buffered_amount_low_cb(webrtc_data_channel_h channel, unsigned int threshold, webrtc_data_channel_buffered_amount_low_cb callback, void *user_data);
+
+/**
+ * @brief Gets the threshold at which the buffered amount is considered low.
+ * @since_tizen 7.0
+ * @remarks The default value is 0.
+ * @param[in] channel Data channel handle
+ * @param[out] threshold The threshold
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #WEBRTC_ERROR_NONE Successful
+ * @retval #WEBRTC_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #WEBRTC_ERROR_INVALID_OPERATION Invalid operation
+ * @see webrtc_data_channel_set_buffered_amount_low_cb()
+ */
+int webrtc_data_channel_get_buffered_amount_low_threshold(webrtc_data_channel_h channel, unsigned int *threshold);
+
+/**
+ * @brief Unsets the data channel buffered amount low callback function.
+ * @since_tizen 7.0
+ * @param[in] channel Data channel handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #WEBRTC_ERROR_NONE Successful
+ * @retval #WEBRTC_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #WEBRTC_ERROR_INVALID_OPERATION Invalid operation
+ * @see webrtc_data_channel_set_buffered_amount_low_cb()
+ */
+int webrtc_data_channel_unset_buffered_amount_low_cb(webrtc_data_channel_h channel);
+
/**
* @}
*/
webrtc_callbacks_s message_cb;
webrtc_callbacks_s error_cb;
webrtc_callbacks_s close_cb;
+ webrtc_callbacks_s buffered_amount_low_cb;
} webrtc_data_channel_s;
typedef struct _webrtc_bytes_data_s {
Name: capi-media-webrtc
Summary: A WebRTC library in Tizen Native API
-Version: 0.3.39
+Version: 0.3.40
Release: 0
Group: Multimedia/API
License: Apache-2.0
return WEBRTC_ERROR_NONE;
}
+
+int webrtc_data_channel_set_buffered_amount_low_cb(webrtc_data_channel_h channel, unsigned int threshold, webrtc_data_channel_buffered_amount_low_cb callback, void *user_data)
+{
+ g_autoptr(GMutexLocker) locker = NULL;
+ webrtc_data_channel_s *_channel = (webrtc_data_channel_s*)channel;
+
+ RET_VAL_IF(_channel == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "channel is NULL");
+ RET_VAL_IF(_channel->channel == NULL, WEBRTC_ERROR_INVALID_OPERATION, "data_channel is NULL");
+
+ locker = g_mutex_locker_new(&_channel->mutex);
+
+ g_object_set(_channel->channel, "buffered-amount-low-threshold", (guint64)threshold, NULL);
+
+ LOG_WARNING_IF_CALLBACK_EXISTS(_channel->buffered_amount_low_cb);
+
+ _channel->buffered_amount_low_cb.callback = callback;
+ _channel->buffered_amount_low_cb.user_data = user_data;
+
+ LOG_INFO("channel[%p] threshold[%u] callback[%p] user_data[%p]", _channel, threshold, callback, user_data);
+
+ return WEBRTC_ERROR_NONE;
+}
+
+int webrtc_data_channel_get_buffered_amount_low_threshold(webrtc_data_channel_h channel, unsigned int *threshold)
+{
+ g_autoptr(GMutexLocker) locker = NULL;
+ webrtc_data_channel_s *_channel = (webrtc_data_channel_s*)channel;
+ guint64 _threshold;
+
+ RET_VAL_IF(_channel == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "channel is NULL");
+ RET_VAL_IF(threshold == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "threshold is NULL");
+ RET_VAL_IF(_channel->channel == NULL, WEBRTC_ERROR_INVALID_OPERATION, "data_channel is NULL");
+
+ locker = g_mutex_locker_new(&_channel->mutex);
+
+ g_object_get(_channel->channel, "buffered-amount-low-threshold", &_threshold, NULL);
+
+ *threshold = (unsigned int)_threshold;
+
+ LOG_INFO("channel[%p] threshold[%u]", _channel, *threshold);
+
+ return WEBRTC_ERROR_NONE;
+}
+
+int webrtc_data_channel_get_buffered_amount(webrtc_data_channel_h channel, unsigned int *buffered_amount)
+{
+ g_autoptr(GMutexLocker) locker = NULL;
+ webrtc_data_channel_s *_channel = (webrtc_data_channel_s*)channel;
+ guint64 _buffered_amount;
+
+ RET_VAL_IF(_channel == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "channel is NULL");
+ RET_VAL_IF(buffered_amount == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "buffered_amount is NULL");
+ RET_VAL_IF(_channel->channel == NULL, WEBRTC_ERROR_INVALID_OPERATION, "data_channel is NULL");
+
+ locker = g_mutex_locker_new(&_channel->mutex);
+
+ g_object_get(_channel->channel, "buffered-amount", &_buffered_amount, NULL);
+
+ *buffered_amount = _buffered_amount;
+
+ LOG_INFO("channel[%p] buffered_amount[%u]", _channel, *buffered_amount);
+
+ return WEBRTC_ERROR_NONE;
+}
+
+int webrtc_data_channel_unset_buffered_amount_low_cb(webrtc_data_channel_h channel)
+{
+ g_autoptr(GMutexLocker) locker = NULL;
+ webrtc_data_channel_s *_channel = (webrtc_data_channel_s*)channel;
+
+ RET_VAL_IF(_channel == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "channel is NULL");
+
+ locker = g_mutex_locker_new(&_channel->mutex);
+
+ RET_VAL_IF(_channel->buffered_amount_low_cb.callback == NULL, WEBRTC_ERROR_INVALID_OPERATION, "callback was not set");
+
+ LOG_INFO("channel[%p] callback[%p] user_data[%p] is reset to NULL",
+ _channel, _channel->buffered_amount_low_cb.callback, _channel->buffered_amount_low_cb.user_data);
+
+ g_object_set(_channel->channel, "buffered-amount-low-threshold", 0, NULL);
+
+ _channel->buffered_amount_low_cb.callback = NULL;
+ _channel->buffered_amount_low_cb.user_data = NULL;
+
+ return WEBRTC_ERROR_NONE;
+}
}
}
+static void __data_channel_on_buffered_amount_low_cb(GObject *data_channel, gpointer user_data)
+{
+ webrtc_data_channel_s *channel = (webrtc_data_channel_s *)user_data;
+ guint64 threshold;
+
+ RET_IF(channel == NULL, "channel is NULL");
+
+ g_object_get(data_channel, "buffered-amount-low-threshold", &threshold, NULL);
+ LOG_DEBUG("channel[%p, %s] user_data[%p] threshold[%"G_GUINT64_FORMAT"]", channel, GST_OBJECT_NAME(data_channel), user_data, threshold);
+
+ if (channel->buffered_amount_low_cb.callback) {
+ LOG_DEBUG(">>> callback[%p] user_data[%p]", channel->buffered_amount_low_cb.callback, channel->buffered_amount_low_cb.user_data);
+ ((webrtc_data_channel_buffered_amount_low_cb)(channel->buffered_amount_low_cb.callback))((webrtc_data_channel_h)channel, channel->buffered_amount_low_cb.user_data);
+ LOG_DEBUG("<<< end of the callback");
+ }
+}
+
void _webrtcbin_on_data_channel_cb(GstElement *webrtcbin, GObject *data_channel, gpointer user_data)
{
webrtc_s *webrtc = (webrtc_s *)user_data;
_connect_and_append_signal(&_channel->signals, data_channel, "on-message-data", G_CALLBACK(__data_channel_on_message_data_cb), _channel);
_connect_and_append_signal(&_channel->signals, data_channel, "on-error", G_CALLBACK(__data_channel_on_error_cb), _channel);
_connect_and_append_signal(&_channel->signals, data_channel, "on-close", G_CALLBACK(__data_channel_on_close_cb), _channel);
+ _connect_and_append_signal(&_channel->signals, data_channel, "on-buffered-amount-low", G_CALLBACK(__data_channel_on_buffered_amount_low_cb), _channel);
*channel = _channel;
CURRENT_STATUS_DATA_CHANNEL_SEND_STRING,
CURRENT_STATUS_DATA_CHANNEL_SEND_STRING_AS_BYTES,
CURRENT_STATUS_DATA_CHANNEL_SEND_FILE,
+ CURRENT_STATUS_DATA_CHANNEL_SET_BUFFERED_AMOUNT_LOW_CB,
CURRENT_STATUS_SET_STUN_SERVER,
CURRENT_STATUS_ADD_TURN_SERVER,
CURRENT_STATUS_SET_ICE_TRANSPORT_POLICY,
ssize_t sum_size;
char buffer[BUFFER_SIZE] = {0, };
int fd;
+ unsigned int buffered_amount;
for (i = 0; i < MAX_CHANNEL_LEN; i++) {
if (g_conns[index].channels[i] == NULL)
sum_size = 0;
while((read_size = read(fd, buffer, BUFFER_SIZE)) > 0) {
sum_size += read_size;
- g_print("[%zd / %llu]bytes is read", sum_size, (unsigned long long)st.st_size);
+ g_print("%s : [%zd / %llu]bytes is read.", file_path, sum_size, (unsigned long long)st.st_size);
ret = webrtc_data_channel_send_bytes(g_conns[index].channels[i], buffer, (unsigned int)read_size);
if (ret != WEBRTC_ERROR_NONE)
g_print("failed to webrtc_data_channel_send_bytes(), file_path[%s], size[%zd]\n", file_path, read_size);
- else
- g_print("webrtc_data_channel_send_bytes() success, file_path[%s], size[%zd]\n", file_path, read_size);
+
+ ret = webrtc_data_channel_get_buffered_amount(g_conns[index].channels[i], &buffered_amount);
+ if (ret != WEBRTC_ERROR_NONE)
+ g_print("failed to webrtc_data_channel_get_buffered_amount()\n");
+ if (buffered_amount > 0)
+ g_print(" buffered_amount [%u]", buffered_amount);
+ g_print("\n");
}
close(fd);
free(label);
}
+static void __data_channel_buffered_amount_low_cb(webrtc_data_channel_h channel, void *user_data)
+{
+ connection_s *conn = (connection_s*)user_data;
+ char *label = __get_channel_label(channel);
+
+ g_print("__data_channel_buffered_amount_low_cb() is called, channel[%p], conn[%p] label[%s]\n", channel, conn, label);
+
+ if (label)
+ free(label);
+}
+
static void __data_channel_cb(webrtc_h webrtc, webrtc_data_channel_h channel, void *user_data)
{
int i;
g_print("webrtc_unset_data_channel_cb() success\n");
}
+static void _webrtc_data_channel_set_buffered_amount_low_cb(int index, unsigned int threshold)
+{
+ int ret = WEBRTC_ERROR_NONE;
+ int i;
+
+ for (i = 0; i < MAX_CHANNEL_LEN; i++) {
+ if (g_conns[index].channels[i] == NULL)
+ continue;
+
+ ret = webrtc_data_channel_set_buffered_amount_low_cb(g_conns[index].channels[i], threshold, __data_channel_buffered_amount_low_cb, &g_conns[index]);
+ if (ret != WEBRTC_ERROR_NONE)
+ g_print("failed to webrtc_data_channel_set_buffered_amount_low_cb(), index[%d]\n", i);
+ else
+ g_print("webrtc_data_channel_set_buffered_amount_low_cb() success, index[%d] threshold[%u]\n", i, threshold);
+ }
+}
+
+static void _webrtc_data_channel_get_buffered_amount_low_threshold(int index)
+{
+ int ret = WEBRTC_ERROR_NONE;
+ int i;
+ unsigned int threshold;
+
+ for (i = 0; i < MAX_CHANNEL_LEN; i++) {
+ if (g_conns[index].channels[i] == NULL)
+ continue;
+
+ ret = webrtc_data_channel_get_buffered_amount_low_threshold(g_conns[index].channels[i], &threshold);
+ if (ret != WEBRTC_ERROR_NONE)
+ g_print("failed to webrtc_data_channel_get_buffered_amount_low_threshold(), index[%d]\n", i);
+ else
+ g_print("webrtc_data_channel_get_buffered_amount_low_threshold() success, index[%d] threshold[%u]\n", i, threshold);
+ }
+}
+
+static void _webrtc_data_channel_unset_buffered_amount_low_cb(int index)
+{
+ int ret = WEBRTC_ERROR_NONE;
+ int i;
+
+ for (i = 0; i < MAX_CHANNEL_LEN; i++) {
+ if (g_conns[index].channels[i] == NULL)
+ continue;
+
+ ret = webrtc_data_channel_unset_buffered_amount_low_cb(g_conns[index].channels[i]);
+ if (ret != WEBRTC_ERROR_NONE)
+ g_print("failed to webrtc_data_channel_unset_buffered_amount_low_cb(), index[%d]\n", i);
+ else
+ g_print("webrtc_data_channel_unset_buffered_amount_low_cb() success, index[%d]\n", i);
+ }
+}
+
+static void _webrtc_data_channel_get_buffered_amount(int index)
+{
+ int ret = WEBRTC_ERROR_NONE;
+ int i;
+ unsigned int buffered_amount;
+
+ for (i = 0; i < MAX_CHANNEL_LEN; i++) {
+ if (g_conns[index].channels[i] == NULL)
+ continue;
+
+ ret = webrtc_data_channel_get_buffered_amount(g_conns[index].channels[i], &buffered_amount);
+ if (ret != WEBRTC_ERROR_NONE)
+ g_print("failed to webrtc_data_channel_get_buffered_amount(), index[%d]\n", i);
+ else
+ g_print("webrtc_data_channel_get_buffered_amount() success, index[%d] buffered_amount[%u]\n", i, buffered_amount);
+ }
+}
+
static void __error_cb(webrtc_h webrtc, webrtc_error_e error, webrtc_state_e state, void *user_data)
{
g_print("__error_cb() is invoked, webrtc[%p], error[0x%x], state[%d], user_data[%p]\n",
} else if (strncmp(cmd, "zf", 2) == 0) {
g_menu_state = CURRENT_STATUS_DATA_CHANNEL_SEND_FILE;
+ } else if (strncmp(cmd, "ba", 2) == 0) {
+ _webrtc_data_channel_get_buffered_amount(0);
+
} else if (strncmp(cmd, "mu", 2) == 0) {
g_menu_state = CURRENT_STATUS_MUTE_MEDIA_SOURCE;
} else if (strncmp(cmd, "gfl", 3) == 0) {
g_menu_state = CURRENT_STATUS_MEDIA_SOURCE_GET_FILE_LOOPING;
+ } else if (strncmp(cmd, "sbc", 3) == 0) {
+ g_menu_state = CURRENT_STATUS_DATA_CHANNEL_SET_BUFFERED_AMOUNT_LOW_CB;
+
+ } else if (strncmp(cmd, "gbt", 3) == 0) {
+ _webrtc_data_channel_get_buffered_amount_low_threshold(0);
+
+ } else if (strncmp(cmd, "ubc", 3) == 0) {
+ _webrtc_data_channel_unset_buffered_amount_low_cb(0);
+
} else {
g_print("unknown menu \n");
}
g_print("zs. Send string via data channel\n");
g_print("zb. Send string as bytes data via data channel\t");
g_print("zf. Send file via data channel\n");
+ g_print("ba. Get buffered amount\n");
+ g_print("sbc. Set buffered amount low callback\n");
+ g_print("gbt. Get buffered amount low threshold\n");
+ g_print("ubc. Unset buffered amount low callback\n");
g_print("------------------------------------- Callbacks -----------------------------------------\n");
g_print("sac. Set all callbacks below (except for the encoded frame callbacks)\n");
g_print("san. Set all the negotiation state change callbacks\t");
} else if (g_menu_state == CURRENT_STATUS_DATA_CHANNEL_SEND_FILE) {
g_print("*** input file path to send.\n");
- } else if (g_menu_state == CURRENT_STATUS_MUTE_MEDIA_SOURCE) {
+ } else if (g_menu_state == CURRENT_STATUS_DATA_CHANNEL_SET_BUFFERED_AMOUNT_LOW_CB) {
+ g_print("*** input data channel buffered amount low threshold.\n");
+
+ }
+ else if (g_menu_state == CURRENT_STATUS_MUTE_MEDIA_SOURCE) {
if (g_cnt == 0)
g_print("*** input source id.\n");
else if (g_cnt == 1)
reset_menu_state();
break;
}
+ case CURRENT_STATUS_DATA_CHANNEL_SET_BUFFERED_AMOUNT_LOW_CB: {
+ _webrtc_data_channel_set_buffered_amount_low_cb(0, (unsigned int)atoi(cmd));
+ reset_menu_state();
+ break;
+ }
case CURRENT_STATUS_SET_STUN_SERVER: {
_webrtc_set_stun_server(0, cmd);
reset_menu_state();