typedef void (*media_streamer_interrupted_cb)(media_streamer_interrupted_code_e code, void *user_data);
/**
+ * @brief Called when the media streamer WebRTC node needs to send the message to the remote peer of WebRTC connection.
+ * @since_tizen 6.0
+ * @remarks Two types will be delivered with @ message which is JSON string.
+ * One is for the remote session description and the other is for a new ICE candidate.
+ * For the remote session description, @ message will be {"sdp":{"type":"offer or answer","sdp":"..."}}.
+ * For the new ICE candidate, @ message will be {"ice":{"candidate":"..."}}.
+ * @param[in] webrtc Media streamer WebRTC node handle
+ * @param[in] message The message to be passed to the remote peer over the signaling channel
+ * @param[in] user_data The user data passed from the callback registration function
+ * @see media_streamer_webrtc_node_set_message_cb()
+ * @see media_streamer_webrtc_node_unset_message_cb()
+ */
+typedef void (*media_streamer_webrtc_message_cb)(media_streamer_node_h webrtc, const char *message, void *user_data);
+
+/**
* @brief Sets a error callback function to be invoked when an error occurs.
* @details Following error codes can be delivered by error callback.
* #MEDIA_STREAMER_ERROR_INVALID_OPERATION,
int media_streamer_node_set_param(media_streamer_node_h node,
const char *param_name, const char *param_value);
-
/**
* @brief Gets value of parameter.
* @details Gets parameter one by one without creating param bundle.
const char *param_name, char **param_value);
/**
+ * @brief Sets a callback function to be invoked when WebRTC node needs to send the message to the remote peer of WebRTC connection.
+ * @details This function can be called only for #MEDIA_STREAMER_NODE_TYPE_WEBRTC type.
+ * @since_tizen 6.0
+ * @param[in] webrtc Media streamer WebRTC node handle
+ * @param[in] callback The WebRTC message callback function to register
+ * @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 #MEDIA_STREAMER_ERROR_NONE Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @pre Create a media streamer WebRTC node handle by calling media_streamer_node_create().
+ * @post media_streamer_webrtc_message_cb() will be invoked.
+ * @see media_streamer_webrtc_node_unset_message_cb()
+ * @see media_streamer_webrtc_message_cb()
+ */
+int media_streamer_webrtc_node_set_message_cb(media_streamer_node_h webrtc, media_streamer_webrtc_message_cb callback, void *user_data);
+
+/**
+ * @brief Unsets the webrtc message callback function.
+ * @since_tizen 6.0
+ * @param[in] src Media streamer WebRTC node handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #MEDIA_STREAMER_ERROR_NONE Successful
+ * @retval #MEDIA_STREAMER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see media_streamer_webrtc_node_set_message_cb()
+ */
+int media_streamer_webrtc_node_unset_message_cb(media_streamer_node_h webrtc);
+
+/**
* @}
*/
mm_resource_manager_res_h resource;
device_policy_manager_h dpm_handle;
int policy_changed_cb_id;
+
+ media_streamer_callback_s user_cb;
} media_streamer_node_s;
/**
Name: capi-media-streamer
Summary: A Media Streamer API
-Version: 0.1.51
+Version: 0.1.52
Release: 0
Group: Multimedia/API
License: Apache-2.0
return MEDIA_STREAMER_ERROR_NONE;
}
+
+int media_streamer_webrtc_node_set_message_cb(media_streamer_node_h webrtc, media_streamer_webrtc_message_cb callback, void *user_data)
+{
+ media_streamer_node_s *ms_node = (media_streamer_node_s *) webrtc;
+
+ ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
+ ms_retvm_if(ms_node->type != MEDIA_STREAMER_NODE_TYPE_WEBRTC, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is not for WebRTC");
+
+ ms_debug_fenter();
+
+ ms_node->user_cb.callback = callback;
+ ms_node->user_cb.user_data = user_data;
+
+ ms_debug_fleave();
+
+ return MEDIA_STREAMER_ERROR_NONE;
+}
+
+int media_streamer_webrtc_node_unset_message_cb(media_streamer_node_h webrtc)
+{
+ media_streamer_node_s *ms_node = (media_streamer_node_s *) webrtc;
+
+ ms_retvm_if(ms_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
+ ms_retvm_if(ms_node->type != MEDIA_STREAMER_NODE_TYPE_WEBRTC, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is not for WebRTC");
+
+ ms_debug_fenter();
+
+ ms_node->user_cb.callback = NULL;
+ ms_node->user_cb.user_data = NULL;
+
+ ms_debug_fleave();
+
+ return MEDIA_STREAMER_ERROR_NONE;
+}
\ No newline at end of file
return text;
}
+static void __trigger_message_callback(media_streamer_node_s *webrtc_node, gchar *message)
+{
+ ms_retm_if(webrtc_node == NULL, "webrtc_node is NULL");
+
+ ms_debug("message is : \n%s", message);
+
+ if (webrtc_node->user_cb.callback) {
+ ms_debug("=====> Now trigger user callback(%p)", webrtc_node->user_cb.callback);
+ ((media_streamer_webrtc_message_cb)(webrtc_node->user_cb.callback))(webrtc_node, message, webrtc_node->user_cb.user_data);
+ ms_debug("<===== End of the callback");
+ } else {
+ ms_warning("message callback is NULL");
+ }
+}
+
static void __on_answer_created_cb(GstPromise *promise, gpointer user_data)
{
GstWebRTCSessionDescription *answer = NULL;
{
GstWebRTCSessionDescription *offer = NULL;
const GstStructure *reply;
- GstElement *webrtcbin = (GstElement *)user_data;
+ media_streamer_node_s *webrtc_node = (media_streamer_node_s *)user_data;
+ node_info_s *node_klass_type = NULL;
+ GstElement *webrtcbin = NULL;
gchar *sdp_msg;
ms_retm_if(promise == NULL, "promise is NULL");
- ms_retm_if(webrtcbin == NULL, "webrtcbin is NULL");
+ ms_retm_if(webrtc_node == NULL, "webrtc_node is NULL");
ms_retm_if(gst_promise_wait(promise) != GST_PROMISE_RESULT_REPLIED, "promise is not for replied result");
ms_debug_fenter();
+ node_klass_type = ms_node_get_klass_by_its_type(MEDIA_STREAMER_NODE_TYPE_WEBRTC);
+ if (!(webrtcbin = ms_find_element_in_bin_by_type(webrtc_node->gst_element, node_klass_type))) {
+ ms_error("Could not find webrtcbin by type[%s, %s]", node_klass_type->klass_name, node_klass_type->default_name);
+ return;
+ }
+
reply = gst_promise_get_reply(promise);
gst_structure_get(reply, "offer",
GST_TYPE_WEBRTC_SESSION_DESCRIPTION, &offer, NULL);
sdp_msg = __make_sdp_message(offer);
- /* TODO: need to add to send this message to signalling server */
- ms_debug("SDP message is sent: %s", sdp_msg);
+ __trigger_message_callback(webrtc_node, sdp_msg);
g_free(sdp_msg);
-
gst_webrtc_session_description_free(offer);
ms_debug_fleave();
GstPromise *promise;
ms_retm_if(webrtcbin == NULL, "webrtcbin is NULL");
+ ms_retm_if(user_data == NULL, "user_data is NULL");
ms_debug_fenter();
- promise = gst_promise_new_with_change_func(__on_offer_created_cb, webrtcbin, NULL);
+ promise = gst_promise_new_with_change_func(__on_offer_created_cb, user_data, NULL);
g_signal_emit_by_name(G_OBJECT(webrtcbin), "create-offer", NULL, promise);
ms_debug_fleave();
void ms_webrtcbin_on_ice_candidate_cb(GstElement *webrtcbin, guint mlineindex, gchar *candidate, gpointer user_data)
{
gchar *ice_candidate_msg = NULL;
+ media_streamer_node_s *webrtc_node = (media_streamer_node_s *)user_data;
ms_retm_if(webrtcbin == NULL, "webrtcbin is NULL");
ms_retm_if(candidate == NULL, "candidate is NULL");
+ ms_retm_if(webrtc_node == NULL, "webrtc_node is NULL");
ice_candidate_msg = __make_ice_candidate_message(mlineindex, candidate);
- /* TODO: need to add to send this message to signalling server */
- ms_debug("ICE candidate message is sent: %s", ice_candidate_msg);
+ __trigger_message_callback(webrtc_node, ice_candidate_msg);
g_free(ice_candidate_msg);
}
ms_debug_fenter();
ms_retvm_if(!ms_streamer, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "ms_streamer is NULL");
- ms_retvm_if(!node, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "node is NULL");
+ ms_retvm_if(!node, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
+ ms_retvm_if(node->type != MEDIA_STREAMER_NODE_TYPE_WEBRTC, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is not WebRTC");
node_klass_type = ms_node_get_klass_by_its_type(MEDIA_STREAMER_NODE_TYPE_WEBRTC);
if (!(webrtcbin = ms_find_element_in_bin_by_type(node->gst_element, node_klass_type))) {
return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
}
+ if (!node->user_cb.callback) {
+ ms_error("message callback should be set before preparing");
+ return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+ }
+
if (__ms_webrtc_node_is_offerer(node, &is_offerer)) {
ms_error("Failed to get peer type");
return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
}
if (is_offerer)
- ms_signal_create(&node->sig_list, webrtcbin, "on-negotiation-needed", G_CALLBACK(ms_webrtcbin_on_negotiation_needed_cb), NULL);
+ ms_signal_create(&node->sig_list, webrtcbin, "on-negotiation-needed", G_CALLBACK(ms_webrtcbin_on_negotiation_needed_cb), node);
- ms_signal_create(&node->sig_list, webrtcbin, "on-ice-candidate", G_CALLBACK(ms_webrtcbin_on_ice_candidate_cb), NULL);
+ ms_signal_create(&node->sig_list, webrtcbin, "on-ice-candidate", G_CALLBACK(ms_webrtcbin_on_ice_candidate_cb), node);
ms_signal_create(&node->sig_list, webrtcbin, "notify::ice-gathering-state", G_CALLBACK(ms_webrtcbin_notify_ice_gathering_state_cb), NULL);
if (ms_element_set_state(webrtcbin, GST_STATE_READY)) {