#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
+#include <inttypes.h>
#include <getopt.h>
-#ifdef PACKAGE
-#undef PACKAGE
-#endif
-#define PACKAGE "webrtc_test"
-
#ifdef LOG_TAG
#undef LOG_TAG
#endif
#define MAX_EXPECTED_SIZE 1024 * 1024 * 1024
#define USE_GSTBUFFER_WITHOUT_COPY true
-#define FONT_SIZE 30
const char *g_server_status_str[] = {
[SERVER_STATUS_DISCONNECTED] = "DISCONNECTED",
return &g_ad;
}
-static void win_del(void *data, Evas_Object *obj, void *event)
-{
- elm_exit();
-}
-
-static Evas_Object *create_win(const char *name, int *w, int *h)
-{
- Evas_Object *eo;
-
- if (!w || !h) {
- g_printerr("w[%p] or h[%p] is NULL\n", w, h);
- return NULL;
- }
-
- eo = elm_win_add(NULL, name, ELM_WIN_BASIC);
- if (!eo) {
- g_printerr("eo is NULL\n");
- return NULL;
- }
-
- elm_win_title_set(eo, name);
- elm_win_borderless_set(eo, EINA_TRUE);
- evas_object_smart_callback_add(eo, "delete,request", win_del, NULL);
- elm_win_screen_size_get(eo, NULL, NULL, w, h);
- g_print("eo[%p], window size: %d x %d\n", eo, *w, *h);
- evas_object_resize(eo, *w, *h);
- elm_win_autodel_set(eo, EINA_TRUE);
- elm_win_alpha_set(eo, EINA_TRUE);
-
- return eo;
-}
-
-static Evas_Object *create_image_object(Evas_Object *eo_parent)
-{
- Evas_Object *eo = NULL;
- Evas *evas;
-
- if (!eo_parent)
- return NULL;
-
- evas = evas_object_evas_get(eo_parent);
- eo = evas_object_image_add(evas);
-
- g_print("image eo[%p]\n", eo);
-
- return eo;
-}
-
-static Evas_Object *create_text_object(Evas_Object *eo_parent)
-{
- Evas_Object *eo = NULL;
- Evas *evas;
-
- if (!eo_parent)
- return NULL;
-
- evas = evas_object_evas_get(eo_parent);
- eo = evas_object_text_add(evas);
-
- g_print("text eo[%p]\n", eo);
-
- return eo;
-}
-
-void create_render_rect_and_bg(Evas_Object *win)
-{
- RET_IF(!win, "win is NULL");
- Evas_Object *bg, *rect;
-
- bg = elm_bg_add(win);
- elm_win_resize_object_add(win, bg);
- evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
- evas_object_show(bg);
-
- rect = evas_object_rectangle_add(evas_object_evas_get(win));
- RET_IF(!rect, "rect is NULL");
-
- evas_object_color_set(rect, 0, 0, 0, 0);
- evas_object_render_op_set(rect, EVAS_RENDER_COPY);
-
- elm_win_resize_object_add(win, rect);
- evas_object_size_hint_weight_set(rect, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
- evas_object_show(rect);
- evas_object_show(win);
-}
-
-static int app_create(void *data)
-{
- appdata_s *ad = data;
- Evas_Object *win = NULL;
- int i;
- Evas_Object **eo;
-
- ad->menu_items = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
- for (i = 0; g_menu_infos[i].cmd != NULL; i++) {
- if (g_strcmp0(g_menu_infos[i].cmd, "none") == 0)
- continue;
- if (!g_hash_table_insert(ad->menu_items, (gpointer)g_menu_infos[i].cmd, &g_menu_infos[i])) {
- g_printerr("should not be reached here, cmd[%s] already exist", g_menu_infos[i].cmd);
- continue;
- }
- }
-
- /* use gl backend */
- elm_config_accel_preference_set("opengl");
-
- /* create window */
- win = create_win(PACKAGE, &ad->win_width, &ad->win_height);
- if (win == NULL)
- return -1;
- ad->win = win;
- ad->win_id = win;
- create_render_rect_and_bg(ad->win);
-
- /* Create evas image object for EVAS surface.
- * _________________________________________ *
- * | eo (mine) | eo (remote0) | *
- * |____________________|____________________| *
- * | eo (remote1) | eo (remote2) | *
- * |____________________|____________________| */
- for (i = 0; i < MAX_CONNECTION_LEN + 1; i++) {
- eo = (i == 0) ? &g_ad.eo_mine : &g_ad.conns[i - 1].render.eo;
- *eo = create_image_object(ad->win);
- if (!*eo) {
- g_print("failed to create evas image object\n");
- continue;
- }
- evas_object_image_size_set(*eo, ad->win_width / 2, ad->win_height / 2);
- evas_object_image_fill_set(*eo, 0, 0, ad->win_width / 2, ad->win_height / 2);
- evas_object_resize(*eo, ad->win_width / 2, ad->win_height / 2);
- evas_object_move(*eo, (i % 2) * (ad->win_width / 2), (i / 2) * (ad->win_height / 2));
- }
- elm_win_activate(win);
- evas_object_show(win);
-
- return 0;
-}
-
-static void __render_text_message(Evas_Object **eo, int i, const char *text)
-{
- if (*eo) {
- evas_object_hide(*eo);
- evas_object_del(*eo);
- }
-
- *eo = create_text_object(g_ad.win);
- if (!*eo) {
- g_print("failed to create evas text object\n");
- return;
- }
- evas_object_text_style_set(*eo, EVAS_TEXT_STYLE_PLAIN);
- evas_object_text_font_set(*eo, "Courier", FONT_SIZE);
- evas_object_text_text_set(*eo, text);
- evas_object_color_set(*eo, 255, 255, 255, 255);
- evas_object_resize(*eo, g_ad.win_width / 2, FONT_SIZE * 2);
- evas_object_move(*eo, (i % 2) * (g_ad.win_width / 2), ((i / 2) * (g_ad.win_height / 2)) + ((g_ad.win_height / 2) - (FONT_SIZE * 2)));
- evas_object_show(*eo);
-}
-
typedef struct _idle_userdata {
connection_s *conn;
char *message;
return G_SOURCE_REMOVE;
conn = data->conn;
- __render_text_message(&conn->render.text_eo, conn->index + 1, data->message);
+
+ _render_text_message(&conn->render.text_eo, conn->index + 1, data->message);
free (data->message);
return G_SOURCE_REMOVE;
g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, __idle_cb, data, g_free);
}
-static int app_terminate(void *data)
-{
- appdata_s *ad = data;
- int i;
-
- for (i = 0; i < MAX_CONNECTION_LEN; i++) {
- if (g_ad.conns[i].render.eo) {
- evas_object_del(g_ad.conns[i].render.eo);
- g_ad.conns[i].render.eo = NULL;
- }
- if (g_ad.conns[i].render.text_eo) {
- evas_object_del(g_ad.conns[i].render.text_eo);
- g_ad.conns[i].render.text_eo = NULL;
- }
- }
-
- if (g_ad.eo_mine) {
- evas_object_del(g_ad.eo_mine);
- g_ad.eo_mine = NULL;
- }
-
- if (ad->win_id) {
- evas_object_del(ad->win_id);
- ad->win_id = NULL;
- }
-
- ad->win = NULL;
-
- g_hash_table_destroy(ad->menu_items);
- ad->menu_items = NULL;
-
- return 0;
-}
-
-struct appcore_ops ops = {
- .create = app_create,
- .terminate = app_terminate,
-};
-
static void __disconnect_signal(GObject *obj, gulong signal_id)
{
RET_IF(!obj, "obj is NULL");
ret = webrtc_media_source_unset_video_loopback(g_ad.conns[index].webrtc, source_id);
RET_IF(ret != WEBRTC_ERROR_NONE, "ret[0x%x]", ret);
- evas_object_hide(g_ad.eo_mine);
-
g_print("webrtc_media_source_unset_video_loopback() success, source_id[%u]\n", source_id);
}
}
}
if (g_ad.conns[i].render.loopback_track_id > 0)
- __render_text_message(&g_ad.text_eo_mine, 0, string_with_peer_id);
+ _render_text_message(&g_ad.text_eo_mine, 0, string_with_peer_id);
}
g_free(string_with_peer_id);
int ret = WEBRTC_ERROR_NONE;
int i;
struct stat st;
- gchar *expected_name;
- gchar *expected_size;
+ g_autofree gchar *expected_name = NULL;
+ g_autofree gchar *base_name = NULL;
+ g_autofree gchar *expected_size = NULL;
ssize_t read_size;
unsigned long long sum_size;
char buffer[BUFFER_SIZE] = {0, };
/* NOTE that logic regarding sending file size and name before sending data may differ from application implementations.
* Here we use two magic string - 'expected name:' and 'expected size:' */
+ base_name = g_path_get_basename((const gchar *)file_path);
expected_size = g_strdup_printf("expected size:%llu", (unsigned long long)st.st_size);
- expected_name = g_strdup_printf("expected name:%s", basename((char *)file_path));
+ expected_name = g_strdup_printf("expected name:%s", base_name);
ret = webrtc_data_channel_send_string(g_ad.conns[index].channels[i], expected_size);
if (ret != WEBRTC_ERROR_NONE)
else
g_print("webrtc_data_channel_send_string() success, string[%s]\n", expected_name);
- g_free(expected_size);
- g_free(expected_name);
-
sum_size = 0;
while ((read_size = read(fd, buffer, BUFFER_SIZE)) > 0) {
sum_size += read_size;
if (type == WEBRTC_MEDIA_TYPE_VIDEO) {
if (!g_ad.validate_encoded_frame_cb) {
g_print("Video track is added, set display - display_type[%d], display[%p]\n",
- conn->render.display_type, conn->render.display_type == WEBRTC_DISPLAY_TYPE_OVERLAY ? g_ad.win_id : conn->render.eo);
+ conn->render.display_type, conn->render.display_type == WEBRTC_DISPLAY_TYPE_OVERLAY ? g_ad.win : conn->render.eo);
#ifdef TIZEN_FEATURE_ESPP
if (conn->render.espp.handle) {
conn->render.espp.video_track_preparing = true;
if (conn->render.display_type == WEBRTC_DISPLAY_TYPE_OVERLAY)
- esplusplayer_set_display(conn->render.espp.handle, ESPLUSPLAYER_DISPLAY_TYPE_OVERLAY, g_ad.win_id);
+ esplusplayer_set_display(conn->render.espp.handle, ESPLUSPLAYER_DISPLAY_TYPE_OVERLAY, g_ad.win);
else if (conn->render.display_type == WEBRTC_DISPLAY_TYPE_EVAS)
esplusplayer_set_display(conn->render.espp.handle, ESPLUSPLAYER_DISPLAY_TYPE_EVAS, conn->render.eo);
else
#endif
{
if (conn->render.display_type == WEBRTC_DISPLAY_TYPE_OVERLAY)
- webrtc_set_display(webrtc, id, WEBRTC_DISPLAY_TYPE_OVERLAY, g_ad.win_id);
+ webrtc_set_display(webrtc, id, WEBRTC_DISPLAY_TYPE_OVERLAY, g_ad.win);
else if (conn->render.display_type == WEBRTC_DISPLAY_TYPE_EVAS)
webrtc_set_display(webrtc, id, WEBRTC_DISPLAY_TYPE_EVAS, conn->render.eo);
else
g_print("quit program\n");
g_ad.menu_status = CURRENT_STATUS_TERMINATE;
- elm_exit();
+ _app_stop();
}
static bool interpret_main_menu_cmd(char *cmd)
g_timeout_add(100, timeout_menu_display_cb, 0);
}
+static void get_menu_items(void)
+{
+ int i;
+
+ g_ad.menu_items = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
+ for (i = 0; g_menu_infos[i].cmd != NULL; i++) {
+ if (g_strcmp0(g_menu_infos[i].cmd, "none") == 0)
+ continue;
+ if (!g_hash_table_insert(get_appdata()->menu_items, (gpointer)g_menu_infos[i].cmd, &g_menu_infos[i])) {
+ g_printerr("should not be reached here, cmd[%s] already exist", g_menu_infos[i].cmd);
+ continue;
+ }
+ }
+}
+
+static void free_menu_items(void)
+{
+ g_hash_table_destroy(g_ad.menu_items);
+ g_ad.menu_items = NULL;
+}
+
static gboolean input_watch_cb(GIOChannel *channel, GIOCondition condition, gpointer data)
{
GIOStatus status;
static void print_usage()
{
- printf("Usage : ");
- printf("webrtc_test [option]\n\n"
+ g_print("Usage : ");
+ g_print("webrtc_test [option]\n\n"
" -p, --proxy proxy URL to use (e.g. http://123.123.123.123:8080)\n"
" -l, --launch-signaling-server port to be used for private signaling server (e.g. 8080)\n"
" -c, --connect-signaling-server signaling server URL:PORT to connect (e.g. wss://123.123.123.123:8443, 192.168.1.123:8080)\n"
static int option_connect_signaling_server(char *url)
{
g_auto(GStrv) str_arr = g_strsplit((const gchar *)optarg, ":", 2);
- printf("%s %s\n", str_arr[0], str_arr[1]);
+ g_print("%s %s\n", str_arr[0], str_arr[1]);
if (g_str_has_prefix(str_arr[0], "wss") || g_str_has_prefix(str_arr[0], "ws")) {
if (_setting_uri(g_ad.signaling_server.public.url, optarg) == -1) {
- printf("invalid port number\n");
+ g_print("invalid port number\n");
return -1;
}
if (_connect_signaling_server() == -1)
g_io_add_watch(stdin_channel, G_IO_IN, input_watch_cb, NULL);
memset(&g_ad, 0x0, sizeof(appdata_s));
- ops.data = &g_ad;
while (1) {
int opt;
break;
case 'l': {
if (atoi(optarg) == 0) {
- printf("invalid port number\n");
+ g_print("invalid port number\n");
goto out;
}
if (option_launch_signaling_server(atoi(optarg)) == -1)
}
displaymenu();
+ get_menu_items();
- return appcore_efl_main(PACKAGE, &argc, &argv, &ops);
+ _app_start(&argc, argv);
+
+ free_menu_items();
+
+ return 0;
}
--- /dev/null
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "webrtc_test_priv.h"
+#include <appcore-efl.h>
+#include <Elementary.h>
+
+#ifdef PACKAGE
+#undef PACKAGE
+#endif
+#define PACKAGE "webrtc_test"
+#define FONT_SIZE 30
+
+static void win_del(void *data, Evas_Object *obj, void *event)
+{
+ elm_exit();
+}
+
+static Evas_Object *create_win(const char *name, int *w, int *h)
+{
+ Evas_Object *eo;
+
+ if (!w || !h) {
+ g_printerr("w[%p] or h[%p] is NULL\n", w, h);
+ return NULL;
+ }
+
+ eo = elm_win_add(NULL, name, ELM_WIN_BASIC);
+ if (!eo) {
+ g_printerr("eo is NULL\n");
+ return NULL;
+ }
+
+ elm_win_title_set(eo, name);
+ elm_win_borderless_set(eo, EINA_TRUE);
+ evas_object_smart_callback_add(eo, "delete,request", win_del, NULL);
+ elm_win_screen_size_get(eo, NULL, NULL, w, h);
+ g_print("eo[%p], window size: %d x %d\n", eo, *w, *h);
+ evas_object_resize(eo, *w, *h);
+ elm_win_autodel_set(eo, EINA_TRUE);
+ elm_win_alpha_set(eo, EINA_TRUE);
+
+ return eo;
+}
+
+static Evas_Object *create_image_object(Evas_Object *eo_parent)
+{
+ Evas_Object *eo = NULL;
+ Evas *evas;
+
+ if (!eo_parent)
+ return NULL;
+
+ evas = evas_object_evas_get(eo_parent);
+ eo = evas_object_image_add(evas);
+
+ g_print("image eo[%p]\n", eo);
+
+ return eo;
+}
+
+static Evas_Object *create_text_object(Evas_Object *eo_parent)
+{
+ Evas_Object *eo = NULL;
+ Evas *evas;
+
+ if (!eo_parent)
+ return NULL;
+
+ evas = evas_object_evas_get(eo_parent);
+ eo = evas_object_text_add(evas);
+
+ g_print("text eo[%p]\n", eo);
+
+ return eo;
+}
+
+static void create_render_rect_and_bg(Evas_Object *win)
+{
+ RET_IF(!win, "win is NULL");
+ Evas_Object *bg, *rect;
+
+ bg = elm_bg_add(win);
+ elm_win_resize_object_add(win, bg);
+ evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_show(bg);
+
+ rect = evas_object_rectangle_add(evas_object_evas_get(win));
+ RET_IF(!rect, "rect is NULL");
+
+ evas_object_color_set(rect, 0, 0, 0, 0);
+ evas_object_render_op_set(rect, EVAS_RENDER_COPY);
+
+ elm_win_resize_object_add(win, rect);
+ evas_object_size_hint_weight_set(rect, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_show(rect);
+ evas_object_show(win);
+}
+
+static int app_create(void *data)
+{
+ appdata_s *ad = data;
+ Evas_Object *win = NULL;
+ Evas_Object **eo;
+ int i;
+
+ /* use gl backend */
+ elm_config_accel_preference_set("opengl");
+
+ /* create window */
+ win = create_win(PACKAGE, &ad->win_width, &ad->win_height);
+ if (win == NULL)
+ return -1;
+ ad->win = win;
+ create_render_rect_and_bg(ad->win);
+
+ /* Create evas image object for EVAS surface.
+ * _________________________________________ *
+ * | eo (mine) | eo (remote0) | *
+ * |____________________|____________________| *
+ * | eo (remote1) | eo (remote2) | *
+ * |____________________|____________________| */
+ for (i = 0; i < MAX_CONNECTION_LEN + 1; i++) {
+ eo = (i == 0) ? (Evas_Object **)&ad->eo_mine : (Evas_Object **)&ad->conns[i - 1].render.eo;
+ *eo = create_image_object(ad->win);
+ if (!*eo) {
+ g_print("failed to create evas image object\n");
+ continue;
+ }
+ evas_object_image_size_set(*eo, ad->win_width / 2, ad->win_height / 2);
+ evas_object_image_fill_set(*eo, 0, 0, ad->win_width / 2, ad->win_height / 2);
+ evas_object_resize(*eo, ad->win_width / 2, ad->win_height / 2);
+ evas_object_move(*eo, (i % 2) * (ad->win_width / 2), (i / 2) * (ad->win_height / 2));
+ }
+ elm_win_activate(win);
+ evas_object_show(win);
+
+ return 0;
+}
+
+static int app_terminate(void *data)
+{
+ appdata_s *ad = data;
+ int i;
+
+ for (i = 0; i < MAX_CONNECTION_LEN; i++) {
+ if (ad->conns[i].render.eo) {
+ evas_object_del(ad->conns[i].render.eo);
+ ad->conns[i].render.eo = NULL;
+ }
+ if (ad->conns[i].render.text_eo) {
+ evas_object_del(ad->conns[i].render.text_eo);
+ ad->conns[i].render.text_eo = NULL;
+ }
+ }
+
+ if (ad->eo_mine) {
+ evas_object_del(ad->eo_mine);
+ ad->eo_mine = NULL;
+ }
+
+ if (ad->win) {
+ evas_object_del(ad->win);
+ ad->win = NULL;
+ }
+
+ ad->win = NULL;
+
+ return 0;
+}
+
+struct appcore_ops ops = {
+ .create = app_create,
+ .terminate = app_terminate,
+};
+
+void _render_text_message(void **eo, int i, const char *text)
+{
+ Evas_Object **_eo = (Evas_Object **)eo;
+ if (*_eo) {
+ evas_object_hide(*_eo);
+ evas_object_del(*_eo);
+ }
+
+ *_eo = create_text_object(get_appdata()->win);
+ if (!*_eo) {
+ g_print("failed to create evas text object\n");
+ return;
+ }
+ evas_object_text_style_set(*_eo, EVAS_TEXT_STYLE_PLAIN);
+ evas_object_text_font_set(*_eo, "Courier", FONT_SIZE);
+ evas_object_text_text_set(*_eo, text);
+ evas_object_color_set(*_eo, 255, 255, 255, 255);
+ evas_object_resize(*_eo, get_appdata()->win_width / 2, FONT_SIZE * 2);
+ evas_object_move(*_eo, (i % 2) * (get_appdata()->win_width / 2), ((i / 2) * (get_appdata()->win_height / 2)) + ((get_appdata()->win_height / 2) - (FONT_SIZE * 2)));
+ evas_object_show(*_eo);
+}
+
+void _app_start(int *argc, char **argv)
+{
+ int ret;
+
+ ops.data = get_appdata();
+ ret = appcore_efl_main(PACKAGE, argc, &argv, &ops);
+ g_print("appcore_efl_main() returned %d\n", ret);
+}
+
+void _app_stop(void)
+{
+ elm_exit();
+}
\ No newline at end of file