From: Hyunil Date: Wed, 10 Jun 2020 02:10:32 +0000 (+0900) Subject: Add WebRTC sample app X-Git-Tag: submit/tizen/20200714.065000~20 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F05%2F235805%2F22;p=platform%2Fcore%2Fapi%2Fmediastreamer.git Add WebRTC sample app - Add creating mediastreamer pipeline for WebRTC - Add message callback for posting session description and ICE candidate - Add decoded ready callback for making audio/video rendering nodes - Add calling APIs for setting session description and ICE candidate [Version] 0.1.72 [Issue Type] Test Change-Id: Iea62f45b8ea7fde8a5890c5de4929907dec011ca Signed-off-by: Hyunil --- diff --git a/packaging/capi-media-streamer.spec b/packaging/capi-media-streamer.spec index fac9403..67eecad 100644 --- a/packaging/capi-media-streamer.spec +++ b/packaging/capi-media-streamer.spec @@ -1,6 +1,6 @@ Name: capi-media-streamer Summary: A Media Streamer API -Version: 0.1.71 +Version: 0.1.72 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/test/media_streamer_test.c b/test/media_streamer_test.c index a0a9cc9..155bee8 100644 --- a/test/media_streamer_test.c +++ b/test/media_streamer_test.c @@ -22,28 +22,28 @@ #include #include #include +#include -/* For signalling */ +/* For WebRTC */ #include #include -#include #ifdef PACKAGE #undef PACKAGE #endif #define PACKAGE "media_streamer_test" -/* webrtc */ +/* For WebRTC */ enum AppState { APP_STATE_UNKNOWN = 0, - APP_STATE_ERROR = 1, /* generic error */ + APP_STATE_ERROR = 1, SERVER_CONNECTING = 1000, SERVER_CONNECTION_ERROR, - SERVER_CONNECTED, /* Ready to register */ + SERVER_CONNECTED, /* Ready to register */ SERVER_REGISTERING = 2000, SERVER_REGISTRATION_ERROR, - SERVER_REGISTERED, /* Ready to call a peer */ - SERVER_CLOSED, /* server connection closed by us or the server */ + SERVER_REGISTERED, /* Ready to call a peer */ + SERVER_CLOSED, PEER_CONNECTING = 3000, PEER_CONNECTION_ERROR, PEER_CONNECTED, @@ -72,6 +72,7 @@ typedef enum { SUBMENU_STATE_UNKNOWN, SUBMENU_STATE_GETTING_PEER_ID, SUBMENU_STATE_GETTING_PROXY_ADDR, + SUBMENU_STATE_GETTING_SERVER_URL, SUBMENU_STATE_GETTING_IP, SUBMENU_STATE_GETTING_SEEK_POS, SUBMENU_STATE_GETTING_FILE_URI, @@ -147,7 +148,7 @@ typedef enum { #define DEFAULT_SEGMENT_PATH "/tmp/segment%05d.ts" #define DEFAULT_PLAYLIST_PATH "/tmp/playlist.m3u8" -#define ENTER g_print ("%s:%d>%s\n",__FILE__, __LINE__, __FUNCTION__); +#define ENTER g_print("%s:%d>%s\n",__FILE__, __LINE__, __FUNCTION__); /*--------------------------------------------------------------------------- | GLOBAL VARIABLE DEFINITIONS: | @@ -163,7 +164,6 @@ int g_node_counter = 0; #define APPEND_NODE(x) {g_nodes[g_node_counter++] = x; } gchar *g_broadcast_address = NULL; -gchar *g_proxy_address = NULL; int g_seek_pos = 0; int g_time = 0; int g_peer_id = 0; @@ -179,13 +179,18 @@ gboolean use_tbm = FALSE; gboolean g_autoplug_mode = FALSE; gboolean g_video_is_on = FALSE; gboolean g_audio_is_on = FALSE; -gboolean g_use_proxy = FALSE; -static gint32 our_id = 0; -static SoupWebsocketConnection *ws_conn = NULL; -static const gchar *server_url = "wss://webrtc.nirbheek.in:8443"; -static enum AppState app_state = 0; + +/* For WebRTC */ +static gint32 g_our_id = 0; +static SoupWebsocketConnection *g_ws_conn = NULL; +static gchar *g_proxy_address = NULL; +static gchar *g_server_url = NULL; +static enum AppState g_app_state = 0; static gboolean disable_ssl = FALSE; -media_streamer_node_h webrtcbin = NULL; +media_streamer_node_h g_webrtc = NULL; +media_streamer_node_h g_video_converter = NULL; +media_streamer_node_h g_video_sink = NULL; +media_streamer_node_h g_audio_sink = NULL; media_format_h vfmt_vp8 = NULL; media_format_h vfmt_i420 = NULL; @@ -196,6 +201,7 @@ media_format_h afmt_f32le = NULL; media_format_h afmt_encoded = NULL; media_format_h afmt_aac = NULL; media_format_h afmt_mp3 = NULL; +media_format_h afmt_opus = NULL; media_format_h cfmt_mpeg2ts = NULL; media_format_h cfmt_mp4 = NULL; @@ -217,6 +223,59 @@ struct appcore_ops ops = { appdata ad; +static void webrtc_decoded_ready_cb(media_streamer_node_h node, const char *src_pad_name, const char *media_type, void *user_data) +{ + media_streamer_node_h video_converter = NULL; + media_streamer_node_h video_sink = NULL; + media_streamer_node_h audio_sink = NULL; + + g_print("WebRTC node's decoded ready callback is called, src_pad_name[%s], media_type[%s]\n", src_pad_name, media_type); + + if (node == NULL) { + g_print("node is NULL\n"); + return; + } + if (src_pad_name == NULL) { + g_print("src_pad_name is NULL\n"); + return; + } + if (media_type == NULL) { + g_print("media_type is NULL\n"); + return; + } + + if (g_str_has_prefix (media_type, "video")) { + g_print("linking video renderer\n"); + + media_streamer_node_create(MEDIA_STREAMER_NODE_TYPE_VIDEO_CONVERTER, NULL, NULL, &video_converter); + media_streamer_node_add(current_media_streamer, video_converter); + APPEND_NODE(video_converter); + + media_streamer_node_create_sink(MEDIA_STREAMER_NODE_SINK_TYPE_OVERLAY, &video_sink); + media_streamer_node_add(current_media_streamer, video_sink); + media_streamer_node_set_param(video_sink, MEDIA_STREAMER_PARAM_DISPLAY, (void*)ad.win); + media_streamer_node_set_param(video_sink, MEDIA_STREAMER_PARAM_DISPLAY_GEOMETRY_METHOD, "1"); + APPEND_NODE(video_sink); + + media_streamer_node_link(node , src_pad_name, video_converter, "sink"); + media_streamer_node_link(video_converter, "src", video_sink, "sink"); + } else if (g_str_has_prefix (media_type, "audio")) { + g_print("linking audio renderer\n"); + + media_streamer_node_create_sink(MEDIA_STREAMER_NODE_SINK_TYPE_AUDIO, &audio_sink); + media_streamer_node_add(current_media_streamer, audio_sink); + APPEND_NODE(audio_sink); + + media_streamer_node_link(node , src_pad_name, audio_sink, "sink"); + } +} + +static void webrtc_message_cb(media_streamer_node_h webrtc_node, const char *message, void *user_data) +{ + g_print("Media Streamer webrtc posted message [%s] \n", message); + soup_websocket_connection_send_text (g_ws_conn, message); +} + static void streamer_error_cb(media_streamer_h streamer, media_streamer_error_e error, void *user_data) { g_print("Media Streamer posted error [%d] \n", error); @@ -438,6 +497,14 @@ static void create_formats(void) media_format_set_audio_channel(afmt_encoded, AUDIO_CHANNEL); media_format_set_audio_samplerate(afmt_encoded, AUDIO_SAMPLERATE); + media_format_create(&afmt_opus); + if (media_format_set_audio_mime(afmt_opus, MEDIA_FORMAT_OPUS) != MEDIA_FORMAT_ERROR_NONE) + g_print("media_format_set_audio_mime failed!\n"); + + media_format_set_audio_channel(afmt_opus, AUDIO_CHANNEL); + media_format_set_audio_samplerate(afmt_opus, AUDIO_SAMPLERATE); + + /* Define audio mp3 format */ media_format_create(&afmt_mp3); if (media_format_set_audio_mime(afmt_mp3, MEDIA_FORMAT_MP3) != MEDIA_FORMAT_ERROR_NONE) @@ -463,260 +530,327 @@ static void create_formats(void) g_print("media_format_set_container_mime failed!\n"); } -static gboolean -cleanup_webrtc (const gchar * msg, enum AppState state) +static void start_webrtc_pipeline() +{ + + /* Video */ + media_streamer_node_h video_src = NULL; +#if 0 + media_streamer_node_create_src(MEDIA_STREAMER_NODE_SRC_TYPE_CAMERA, &video_src); + media_streamer_node_add(current_media_streamer, video_src); + media_streamer_node_set_param(video_src, MEDIA_STREAMER_PARAM_CAMERA_ID, "1"); + APPEND_NODE(video_src); +#else + media_streamer_node_create_src(MEDIA_STREAMER_NODE_SRC_TYPE_VIDEO_TEST, &video_src); + media_streamer_node_set_param(video_src, MEDIA_STREAMER_PARAM_IS_LIVE_STREAM, "true"); + media_streamer_node_set_param(video_src, "pattern", "ball"); + media_streamer_node_add(current_media_streamer, video_src); + APPEND_NODE(video_src); +#endif + + /* it is important to link filter for camera output regardless of codec input format */ + media_streamer_node_h video_filter = NULL; + media_streamer_node_create(MEDIA_STREAMER_NODE_TYPE_FILTER, NULL, vfmt_i420, &video_filter); + media_streamer_node_add(current_media_streamer, video_filter); + APPEND_NODE(video_filter); + + media_streamer_node_h video_queue0 = NULL; + media_streamer_node_create(MEDIA_STREAMER_NODE_TYPE_QUEUE, NULL, NULL, &video_queue0); + media_streamer_node_add(current_media_streamer, video_queue0); + APPEND_NODE(video_queue0); + + media_streamer_node_h video_enc = NULL; + media_streamer_node_create(MEDIA_STREAMER_NODE_TYPE_VIDEO_ENCODER, vfmt_i420, vfmt_vp8, &video_enc); + media_streamer_node_add(current_media_streamer, video_enc); + APPEND_NODE(video_enc); + + media_streamer_node_h video_pay = NULL; + media_streamer_node_create(MEDIA_STREAMER_NODE_TYPE_VIDEO_PAY, vfmt_vp8, NULL, &video_pay); + media_streamer_node_add(current_media_streamer, video_pay); + APPEND_NODE(video_pay); + + media_streamer_node_h video_queue1 = NULL; + media_streamer_node_create(MEDIA_STREAMER_NODE_TYPE_QUEUE, NULL, NULL, &video_queue1); + media_streamer_node_add(current_media_streamer, video_queue1); + APPEND_NODE(video_queue1); + + /* Audio */ + media_streamer_node_h audio_src = NULL; + //media_streamer_node_create_src(MEDIA_STREAMER_NODE_SRC_TYPE_AUDIO_CAPTURE, &audio_src); + media_streamer_node_create_src(MEDIA_STREAMER_NODE_SRC_TYPE_AUDIO_TEST, &audio_src); + media_streamer_node_add(current_media_streamer, audio_src); + APPEND_NODE(audio_src); + + media_streamer_node_h audio_queue0 = NULL; + media_streamer_node_create(MEDIA_STREAMER_NODE_TYPE_QUEUE, NULL, NULL, &audio_queue0); + media_streamer_node_add(current_media_streamer, audio_queue0); + APPEND_NODE(audio_queue0); + + media_streamer_node_h audio_enc = NULL; + media_streamer_node_create(MEDIA_STREAMER_NODE_TYPE_AUDIO_ENCODER, afmt_pcm, afmt_opus, &audio_enc); + media_streamer_node_add(current_media_streamer, audio_enc); + APPEND_NODE(audio_enc); + + media_streamer_node_h audio_pay = NULL; + media_streamer_node_create(MEDIA_STREAMER_NODE_TYPE_AUDIO_PAY, afmt_opus, NULL, &audio_pay); + media_streamer_node_add(current_media_streamer, audio_pay); + APPEND_NODE(audio_pay); + + media_streamer_node_h audio_queue1 = NULL; + media_streamer_node_create(MEDIA_STREAMER_NODE_TYPE_QUEUE, NULL, NULL, &audio_queue1); + media_streamer_node_add(current_media_streamer, audio_queue1); + APPEND_NODE(audio_queue1); + + media_streamer_node_h webrtc = NULL; + media_streamer_node_create(MEDIA_STREAMER_NODE_TYPE_WEBRTC, NULL, NULL, &webrtc); + media_streamer_node_add(current_media_streamer, webrtc); + APPEND_NODE(webrtc); + if (g_peer_id) + media_streamer_node_set_param(webrtc, MEDIA_STREAMER_PARAM_WEBRTC_PEER_TYPE, "offer"); + else + media_streamer_node_set_param(webrtc, MEDIA_STREAMER_PARAM_WEBRTC_PEER_TYPE, "answer"); + media_streamer_webrtc_node_set_message_cb(webrtc, webrtc_message_cb, NULL); + media_streamer_node_set_decoded_ready_cb(webrtc, webrtc_decoded_ready_cb, NULL); + + /* Video link */ + media_streamer_node_link(video_src, "src", video_filter, "sink"); + media_streamer_node_link(video_filter, "src", video_queue0, "sink"); + media_streamer_node_link(video_queue0, "src", video_enc, "sink"); + media_streamer_node_link(video_enc, "src", video_pay, "sink"); + media_streamer_node_link(video_pay, "src", video_queue1, "sink"); + media_streamer_node_link(video_queue1, "src",webrtc, "video_in"); + + /* Audio link */ + media_streamer_node_link(audio_src, "src", audio_queue0, "sink"); + media_streamer_node_link(audio_queue0, "src", audio_enc, "sink"); + media_streamer_node_link(audio_enc, "src", audio_pay, "sink"); + media_streamer_node_link(audio_pay, "src", audio_queue1, "sink"); + media_streamer_node_link(audio_queue1, "src", webrtc, "audio_in"); + + + /* Note that setting pad format to WebRTC node is necessary, WebRTC use this format as media information for SDP */ + media_streamer_node_set_pad_format(webrtc, "audio_in", afmt_opus); + media_streamer_node_set_pad_format(webrtc, "video_in", vfmt_vp8); + + g_webrtc = webrtc; +} + +static void __cleanup_webrtc(const gchar * msg, enum AppState state) { ENTER; if (msg) - g_printerr ("%s\n", msg); + g_printerr("%s\n", msg); if (state > 0) - app_state = state; + g_app_state = state; - if (ws_conn) { - if (soup_websocket_connection_get_state (ws_conn) == - SOUP_WEBSOCKET_STATE_OPEN) + if (g_ws_conn) { + if (soup_websocket_connection_get_state(g_ws_conn) == SOUP_WEBSOCKET_STATE_OPEN) /* This will call us again */ - soup_websocket_connection_close (ws_conn, 1000, ""); + soup_websocket_connection_close(g_ws_conn, 1000, ""); else - g_object_unref (ws_conn); + g_object_unref(g_ws_conn); } - /* To allow usage as a GSourceFunc */ - return G_SOURCE_REMOVE; } -static gboolean -setup_call (void) +static gboolean __setup_call(void) { gchar *msg; ENTER; - if (soup_websocket_connection_get_state (ws_conn) != - SOUP_WEBSOCKET_STATE_OPEN) + if (soup_websocket_connection_get_state(g_ws_conn) != SOUP_WEBSOCKET_STATE_OPEN) return FALSE; if (!g_peer_id) return FALSE; - g_print ("Setting up signalling server call with %d\n", g_peer_id); - app_state = PEER_CONNECTING; - msg = g_strdup_printf ("SESSION %d", g_peer_id); - soup_websocket_connection_send_text (ws_conn, msg); - g_free (msg); + g_print("Setting up signalling server call with %d\n", g_peer_id); + g_app_state = PEER_CONNECTING; + msg = g_strdup_printf("SESSION %d", g_peer_id); + soup_websocket_connection_send_text(g_ws_conn, msg); + + g_free(msg); + return TRUE; } -/* One mega message handler for our asynchronous calling mechanism */ -static void -on_server_message (SoupWebsocketConnection * conn, SoupWebsocketDataType type, - GBytes * message, gpointer user_data) +static void __on_server_message(SoupWebsocketConnection * conn, SoupWebsocketDataType type, + GBytes * message, gpointer user_data) { gchar *text; ENTER; switch (type) { case SOUP_WEBSOCKET_DATA_BINARY: - g_printerr ("Received unknown binary message, ignoring\n"); + g_printerr("Received unknown binary message, ignoring\n"); return; case SOUP_WEBSOCKET_DATA_TEXT: { gsize size; - const gchar *data = g_bytes_get_data (message, &size); + const gchar *data = g_bytes_get_data(message, &size); /* Convert to NULL-terminated string */ - text = g_strndup (data, size); - g_print ("Received text message, [%s]\n", text); + text = g_strndup(data, size); + g_print("Received text message, [%s]\n", text); break; } default: - g_assert_not_reached (); + g_assert_not_reached(); } /* Server has accepted our registration, we are ready to send commands */ - if (g_strcmp0 (text, "HELLO") == 0) { - if (app_state != SERVER_REGISTERING) { - cleanup_webrtc ("ERROR: Received HELLO when not registering", - APP_STATE_ERROR); + if (g_strcmp0(text, "HELLO") == 0) { + if (g_app_state != SERVER_REGISTERING) { + __cleanup_webrtc("ERROR: Received HELLO when not registering",APP_STATE_ERROR); goto out; } - app_state = SERVER_REGISTERED; - g_print ("Registered with server\n"); + g_app_state = SERVER_REGISTERED; + g_print("Registered with server\n"); /* Ask signalling server to connect us with a specific peer */ if (g_peer_id) { - if (!setup_call ()) { - cleanup_webrtc ("ERROR: Failed to setup call", PEER_CALL_ERROR); + if (!__setup_call()) { + __cleanup_webrtc("ERROR: Failed to setup call", PEER_CALL_ERROR); goto out; } } else { /* should WAIT for another peer */ - g_print ("need to wait for another peer...(our id:%d)\n", our_id); - app_state = PEER_CALL_WAITING; - /* Start negotiation (exchange SDP and ICE candidates) */ - /* need to start pipeline_answer */ + g_print("need to wait for another peer...(our id:%d)\n", g_our_id); + g_app_state = PEER_CALL_WAITING; + + /* For answerer */ + start_webrtc_pipeline(); } /* Call has been setup by the server, now we can start negotiation */ - } else if (g_strcmp0 (text, "SESSION_OK") == 0) { - if (app_state != PEER_CONNECTING) { - cleanup_webrtc ("ERROR: Received SESSION_OK when not calling", - PEER_CONNECTION_ERROR); + } else if (g_strcmp0(text, "SESSION_OK") == 0) { + if (g_app_state != PEER_CONNECTING) { + __cleanup_webrtc("ERROR: Received SESSION_OK when not calling", PEER_CONNECTION_ERROR); goto out; } - app_state = PEER_CONNECTED; + g_app_state = PEER_CONNECTED; /* Start negotiation (exchange SDP and ICE candidates) */ /* need to start pipeline */ + start_webrtc_pipeline(); /* Handle errors */ - } else if (g_str_has_prefix (text, "ERROR")) { - switch (app_state) { + } else if (g_str_has_prefix(text, "ERROR")) { + switch (g_app_state) { case SERVER_CONNECTING: - app_state = SERVER_CONNECTION_ERROR; + g_app_state = SERVER_CONNECTION_ERROR; break; case SERVER_REGISTERING: - app_state = SERVER_REGISTRATION_ERROR; + g_app_state = SERVER_REGISTRATION_ERROR; break; case PEER_CONNECTING: - app_state = PEER_CONNECTION_ERROR; + g_app_state = PEER_CONNECTION_ERROR; break; case PEER_CALL_WAITING: case PEER_CONNECTED: case PEER_CALL_NEGOTIATING: - app_state = PEER_CALL_ERROR; + g_app_state = PEER_CALL_ERROR; break; default: - app_state = APP_STATE_ERROR; - } - cleanup_webrtc (text, 0); + g_app_state = APP_STATE_ERROR; + } + __cleanup_webrtc(text, 0); /* Look for JSON messages containing SDP and ICE candidates */ } else { JsonNode *root; - JsonObject *object, *child; - JsonParser *parser = json_parser_new (); - if (!json_parser_load_from_data (parser, text, -1, NULL)) { - g_printerr ("Unknown message '%s', ignoring", text); - g_object_unref (parser); + JsonObject *object; + JsonParser *parser = json_parser_new(); + + if (!json_parser_load_from_data(parser, text, -1, NULL)) { + g_printerr("Unknown message '%s', ignoring", text); + g_object_unref(parser); goto out; } - root = json_parser_get_root (parser); - if (!JSON_NODE_HOLDS_OBJECT (root)) { - g_printerr ("Unknown json message '%s', ignoring", text); - g_object_unref (parser); + root = json_parser_get_root(parser); + if (!JSON_NODE_HOLDS_OBJECT(root)) { + g_printerr("Unknown json message '%s', ignoring", text); + g_object_unref(parser); goto out; } - object = json_node_get_object (root); /* Check type of JSON message */ - if (json_object_has_member (object, "sdp")) { - const gchar *text, *sdptype; - - if (g_peer_id) - g_assert_cmphex (app_state, ==, PEER_CALL_NEGOTIATING); - else - g_assert_cmphex (app_state, ==, PEER_CALL_WAITING); - - child = json_object_get_object_member (object, "sdp"); - - if (!json_object_has_member (child, "type")) { - cleanup_webrtc ("ERROR: received SDP without 'type'", - PEER_CALL_ERROR); - goto out; - } - - sdptype = json_object_get_string_member (child, "type"); - text = json_object_get_string_member (child, "sdp"); - - - if (g_str_equal (sdptype, "answer")) { - g_print ("Received answer:\n%s\n", text); - - /* need to API: set remote description */ - - app_state = PEER_CALL_STARTED; - } else { - g_print ("Received offer:\n%s\n", text); - /* need to API: set remote description */ - } - - } else if (json_object_has_member (object, "ice")) { - /*need to API: Add ice candidate sent by remote peer */ + object = json_node_get_object(root); + if (json_object_has_member(object, "sdp")){ + /* set remote session description */ + if (media_streamer_node_set_param(g_webrtc, MEDIA_STREAMER_PARAM_WEBRTC_REMOTE_SESSION_DESCRIPTION, text) == MEDIA_STREAMER_ERROR_NONE) + g_app_state = PEER_CALL_STARTED; + } else if (json_object_has_member(object, "ice")){ + /* add ice candidates, several candidates arrive from the peer */ + media_streamer_node_set_param(g_webrtc, MEDIA_STREAMER_PARAM_WEBRTC_ADD_ICE_CANDIDATE, text); } else { - g_printerr ("Ignoring unknown JSON message:\n%s\n", text); + g_printerr("Ignoring unknown JSON message:\n%s\n", text); } - g_object_unref (parser); + g_object_unref(parser); } - out: g_free (text); } -static gint32 -register_with_server (void) +static gint32 __register_with_server(void) { gchar *hello; gint32 our_id; ENTER; - if (soup_websocket_connection_get_state (ws_conn) != - SOUP_WEBSOCKET_STATE_OPEN) + if (soup_websocket_connection_get_state(g_ws_conn) != SOUP_WEBSOCKET_STATE_OPEN) return -1; - our_id = g_random_int_range (10, 10000); - g_print ("Registering id %i with server\n", our_id); - app_state = SERVER_REGISTERING; + our_id = g_random_int_range(10, 10000); + g_print("Registering id %i with server\n", our_id); + g_app_state = SERVER_REGISTERING; /* Register with the server with a random integer id. Reply will be received * by on_server_message() */ - hello = g_strdup_printf ("HELLO %i", our_id); - soup_websocket_connection_send_text (ws_conn, hello); - g_free (hello); + hello = g_strdup_printf("HELLO %i", our_id); + soup_websocket_connection_send_text(g_ws_conn, hello); + + g_free(hello); return our_id; } /* Answer created by our pipeline, to be sent to the peer */ -static void -on_server_closed (SoupWebsocketConnection * conn G_GNUC_UNUSED, - gpointer user_data G_GNUC_UNUSED) +static void __on_server_closed(SoupWebsocketConnection * conn G_GNUC_UNUSED, gpointer user_data G_GNUC_UNUSED) { - app_state = SERVER_CLOSED; + g_app_state = SERVER_CLOSED; ENTER; - cleanup_webrtc ("Server connection closed", 0); + __cleanup_webrtc("Server connection closed", 0); } -static void -on_server_connected (SoupSession * session, GAsyncResult * res, - SoupMessage *msg) +static void __on_server_connected(SoupSession * session, GAsyncResult * res, SoupMessage *msg) { GError *error = NULL; ENTER; - g_print("on_server_connected\n"); - ws_conn = soup_session_websocket_connect_finish (session, res, &error); + g_print("__on_server_connected\n"); + g_ws_conn = soup_session_websocket_connect_finish(session, res, &error); if (error) { - cleanup_webrtc (error->message, SERVER_CONNECTION_ERROR); - g_error_free (error); + __cleanup_webrtc(error->message, SERVER_CONNECTION_ERROR); + g_error_free(error); return; } - g_assert_nonnull (ws_conn); + g_assert_nonnull(g_ws_conn); - app_state = SERVER_CONNECTED; - g_print ("Connected to signalling server\n"); + g_app_state = SERVER_CONNECTED; + g_print("Connected to signalling server\n"); - g_signal_connect (ws_conn, "closed", G_CALLBACK (on_server_closed), NULL); - g_signal_connect (ws_conn, "message", G_CALLBACK (on_server_message), NULL); + g_signal_connect(g_ws_conn, "closed", G_CALLBACK(__on_server_closed), NULL); + g_signal_connect(g_ws_conn, "message", G_CALLBACK(__on_server_message), NULL); /* Register with the server so it knows about us and can accept commands */ - our_id = register_with_server (); + g_our_id = __register_with_server(); } /* TIZEN: add for log */ -static inline gchar -gst_soup_util_log_make_level_tag (SoupLoggerLogLevel level) +static inline gchar __convert_log_level_tag(SoupLoggerLogLevel level) { gchar c; - if (G_UNLIKELY ((gint) level > 9)) + if (G_UNLIKELY((gint) level > 9)) return '?'; - switch (level) { + switch(level) { case SOUP_LOGGER_LOG_MINIMAL: c = 'M'; break; @@ -736,19 +870,16 @@ gst_soup_util_log_make_level_tag (SoupLoggerLogLevel level) return c; } -static void -_log_printer_cb (SoupLogger G_GNUC_UNUSED * logger, - SoupLoggerLogLevel level, char direction, const char *data, - gpointer user_data) +static void __log_printer_cb(SoupLogger G_GNUC_UNUSED * logger, SoupLoggerLogLevel level, + char direction, const char *data, gpointer user_data) { gchar c; - c = gst_soup_util_log_make_level_tag (level); + c = __convert_log_level_tag(level); g_print("HTTP_SESSION(%c): %c %s\n", c, direction, data); } -static void -connect_to_websocket_server_async (void) +static void __connect_to_websocket_server_async(void) { SoupLogger *logger; SoupMessage *message; @@ -757,35 +888,35 @@ connect_to_websocket_server_async (void) const char *https_aliases[] = {"wss", NULL}; ENTER; - if (!g_use_proxy){ - session = soup_session_new_with_options (SOUP_SESSION_SSL_STRICT, !disable_ssl, + if (!g_proxy_address){ + session = soup_session_new_with_options(SOUP_SESSION_SSL_STRICT, !disable_ssl, SOUP_SESSION_HTTPS_ALIASES, https_aliases, NULL); } else { - proxy_uri = soup_uri_new (g_proxy_address); - session = soup_session_new_with_options (SOUP_SESSION_SSL_STRICT, !disable_ssl, + g_print("Use proxy\n"); + proxy_uri = soup_uri_new(g_proxy_address); + session = soup_session_new_with_options(SOUP_SESSION_SSL_STRICT, !disable_ssl, SOUP_SESSION_SSL_USE_SYSTEM_CA_FILE, TRUE, SOUP_SESSION_PROXY_URI, proxy_uri, SOUP_SESSION_SSL_CA_FILE, "/opt/var/lib/ca-certificates/ca-bundle.pem", SOUP_SESSION_HTTPS_ALIASES, https_aliases, NULL); - soup_uri_free (proxy_uri); + soup_uri_free(proxy_uri); } - logger = soup_logger_new (SOUP_LOGGER_LOG_BODY, -1); + logger = soup_logger_new(SOUP_LOGGER_LOG_BODY, -1); - /* TIZEN: add for log */ - soup_logger_set_printer (logger, _log_printer_cb, NULL, NULL); + soup_logger_set_printer(logger, __log_printer_cb, NULL, NULL); - soup_session_add_feature (session, SOUP_SESSION_FEATURE (logger)); - g_object_unref (logger); + soup_session_add_feature(session, SOUP_SESSION_FEATURE (logger)); + g_object_unref(logger); - message = soup_message_new (SOUP_METHOD_GET, server_url); + message = soup_message_new(SOUP_METHOD_GET, g_server_url); - g_print ("Connecting to server[%s]...\n", server_url); + g_print("Connecting to server[%s]...\n", g_server_url); /* Once connected, we will register */ - soup_session_websocket_connect_async (session, message, NULL, NULL, NULL, - (GAsyncReadyCallback) on_server_connected, message); - app_state = SERVER_CONNECTING; + soup_session_websocket_connect_async(session, message, NULL, NULL, NULL, + (GAsyncReadyCallback) __on_server_connected, message); + g_app_state = SERVER_CONNECTING; } static void set_rtp_params(media_streamer_node_h rtp_node, const char *ip, int video_port, int audio_port, gboolean port_reverse) @@ -1493,25 +1624,20 @@ void reset_current_menu_state(void) g_media_streamer_2 = NULL; } - if (g_broadcast_address != NULL) { - g_free(g_broadcast_address); - g_broadcast_address = NULL; - } + g_free(g_broadcast_address); + g_broadcast_address = NULL; - if (g_proxy_address != NULL) { - g_free(g_proxy_address); - g_proxy_address = NULL; - } + g_free(g_proxy_address); + g_proxy_address = NULL; - if (g_uri != NULL) { - g_free(g_uri); - g_uri = NULL; - } + g_free(g_server_url); + g_server_url = NULL; - if (g_sub_uri != NULL) { - g_free(g_sub_uri); - g_sub_uri = NULL; - } + g_free(g_uri); + g_uri = NULL; + + g_free(g_sub_uri); + g_sub_uri = NULL; /* Clean Up Nodes */ int i = g_node_counter - 1; @@ -1538,6 +1664,14 @@ static void display_getting_proxy_addr_menu(void) g_print("----------------------------------------------------\n"); } +static void display_getting_server_url_menu(void) +{ + g_print("\n"); + g_print("====================================================\n"); + g_print("Please input server URL to handshake with peer \n"); + g_print("----------------------------------------------------\n"); +} + static void display_getting_peer_id_menu(void) { g_print("\n"); @@ -1791,6 +1925,9 @@ static void display_menu(void) case SUBMENU_STATE_GETTING_PROXY_ADDR: display_getting_proxy_addr_menu(); break; + case SUBMENU_STATE_GETTING_SERVER_URL: + display_getting_server_url_menu(); + break; case SUBMENU_STATE_GETTING_IP: display_getting_ip_menu(); break; @@ -1897,7 +2034,7 @@ void run_webrtc_preset(void) { if ((g_scenario_mode == SCENARIO_MODE_WEBRTC_SENDRECV_VIDEO_AUDIO)) { create_formats(); - connect_to_websocket_server_async (); + __connect_to_websocket_server_async(); } else { g_print("Invalid scenario menu preset was selected!"); } @@ -2143,7 +2280,7 @@ void _interpret_webrtc_scenario_menu(char *cmd) g_printf("g_sub_menu_state (%d)\n", g_sub_menu_state); } } - g_sub_menu_state = SUBMENU_STATE_GETTING_PROXY_ADDR; + g_sub_menu_state = SUBMENU_STATE_GETTING_SERVER_URL; } void _interpret_scenario_menu(char *cmd) @@ -2206,6 +2343,24 @@ void _interpret_scenario_menu(char *cmd) } } +void _interpret_getting_server_url_menu(char *cmd) +{ + int min_len = strlen("0.0.0.0"); + int cmd_len = strlen(cmd); + + if (g_server_url != NULL) + g_free(g_server_url); + + if (cmd_len > min_len) { + g_server_url = g_strdup(cmd); + g_print("User set server URL[%s]\n", g_server_url); + } else { + g_print("Invalid value\n"); + } + + g_sub_menu_state = SUBMENU_STATE_GETTING_PROXY_ADDR; +} + void _interpret_getting_proxy_addr_menu(char *cmd) { int min_len = strlen("0.0.0.0"); @@ -2215,11 +2370,11 @@ void _interpret_getting_proxy_addr_menu(char *cmd) if (cmd_len == 1) { if (cmd[0] == '0') { - g_use_proxy = FALSE; + g_print("Skip set proxy address\n"); } } else if (cmd_len > min_len) { g_proxy_address = g_strdup(cmd); - g_print("User set proxy address set to [%s]\n", g_proxy_address); + g_print("User set proxy address[%s]\n", g_proxy_address); } else { g_print("Invalid value\n"); } @@ -2446,6 +2601,9 @@ static void interpret_cmd(char *cmd) case SUBMENU_STATE_GETTING_PROXY_ADDR: _interpret_getting_proxy_addr_menu(cmd); break; + case SUBMENU_STATE_GETTING_SERVER_URL: + _interpret_getting_server_url_menu(cmd); + break; case SUBMENU_STATE_GETTING_PEER_ID: _interpret_getting_peer_id_menu(cmd); break;