Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
863 changes: 863 additions & 0 deletions c4-system-context.drawio

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions client/deps/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
gstreamer_android
*.tar.xz
2 changes: 1 addition & 1 deletion client/setup-tunnel.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
set -x
set -e

adb logcat -c
# adb logcat -c
adb reverse tcp:61943 tcp:61943
adb reverse tcp:8080 tcp:8080
9 changes: 6 additions & 3 deletions client/src/em/em_connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -340,8 +340,9 @@ emconn_webrtc_deep_notify_callback(GstObject *self, GstObject *prop_object, GPar
{
GstWebRTCPeerConnectionState state;
g_object_get(prop_object, "connection-state", &state, NULL);
ALOGI("RYLIE: deep-notify callback says peer connection state is %s", peer_connection_state_to_string(state));
emconn_update_status_from_peer_connection_state(emconn, state);
ALOGV("RYLIE: deep-notify callback says peer connection state is %s - but it lies sometimes",
peer_connection_state_to_string(state));
// emconn_update_status_from_peer_connection_state(emconn, state);
}

static void
Expand Down Expand Up @@ -616,7 +617,9 @@ static void
emconn_connect_internal(EmConnection *emconn, enum em_status status)
{
em_connection_disconnect(emconn);

if (!emconn->ws_cancel) {
emconn->ws_cancel = g_cancellable_new();
}
g_cancellable_reset(emconn->ws_cancel);
ALOGI("RYLIE: calling soup_session_websocket_connect_async. websocket_uri = %s", emconn->websocket_uri);
#if SOUP_MAJOR_VERSION == 2
Expand Down
29 changes: 22 additions & 7 deletions client/src/em/em_remote_experience.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,13 +335,9 @@ em_remote_experience_poll_and_render_frame(EmRemoteExperience *exp)
if (0 != clock_gettime(CLOCK_MONOTONIC, &beginTime)) {
ALOGE("%s: clock_gettime failed, which is very unexpected", __FUNCTION__);
// TODO how to handle this?
return EM_POLL_RENDER_RESULT_SHOULD_NOT_RENDER;
}

// Locate views, set up layers
XrView views[2] = {};
views[0].type = XR_TYPE_VIEW;
views[1].type = XR_TYPE_VIEW;


XrViewLocateInfo locateInfo = {.type = XR_TYPE_VIEW_LOCATE_INFO,
.viewConfigurationType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO,
Expand All @@ -350,12 +346,18 @@ em_remote_experience_poll_and_render_frame(EmRemoteExperience *exp)

XrViewState viewState = {.type = XR_TYPE_VIEW_STATE};

uint32_t viewCount = 2;
result = xrLocateViews(session, &locateInfo, &viewState, 2, &viewCount, views);
// Locate views, set up layers
XrView views[2] = {};
views[0].type = XR_TYPE_VIEW;
views[1].type = XR_TYPE_VIEW;

uint32_t viewCount = 0;
result = xrLocateViews(session, &locateInfo, &viewState, sizeof(views) / sizeof(views[0]), &viewCount, views);

if (XR_FAILED(result)) {
ALOGE("Failed to locate views");
// TODO how to handle this?
return EM_POLL_RENDER_RESULT_SHOULD_NOT_RENDER;
}

XrCompositionLayerProjection layer = {};
Expand Down Expand Up @@ -444,6 +446,19 @@ em_remote_experience_inner_poll_and_render_frame(EmRemoteExperience *exp,
uint32_t width = exp->eye_extents.width;
uint32_t height = exp->eye_extents.height;

static bool showedFov = false;
if (!showedFov) {
showedFov = true;
ALOGI(
"RYLIE XrFovf 0: (xrt_fov){ .angle_left = %0.03ff, .angle_right = %0.03ff, .angle_up = %0.03ff, "
".angle_down = %0.03ff }",
views[0].fov.angleLeft, views[0].fov.angleRight, views[0].fov.angleUp, views[0].fov.angleDown);
ALOGI(
"RYLIE XrFovf 1: (xrt_fov){ .angle_left = %0.03ff, .angle_right = %0.03ff, .angle_up = %0.03ff, "
".angle_down = %0.03ff }",
views[1].fov.angleLeft, views[1].fov.angleRight, views[1].fov.angleUp, views[1].fov.angleDown);
}

projectionLayer->space = exp->xr_owned.worldSpace;

projectionViews[0].subImage.swapchain = exp->xr_owned.swapchain;
Expand Down
3 changes: 1 addition & 2 deletions client/src/em/em_stream_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ struct em_sc_sample
GstSample *sample;
};


struct _EmStreamClient
{
GMainLoop *loop;
Expand Down Expand Up @@ -581,6 +580,7 @@ em_stream_client_stop(EmStreamClient *sc)
gst_clear_object(&sc->pipeline);
gst_clear_object(&sc->appsink);
gst_clear_object(&sc->context);
gst_clear_object(&sc->connection);

sc->pipeline_is_running = false;
}
Expand All @@ -590,7 +590,6 @@ em_stream_client_try_pull_sample(EmStreamClient *sc, struct timespec *out_decode
{
if (!sc->appsink) {
// not setup yet.
ALOGV("%s: no app sink yet, waiting for connection", __FUNCTION__);
return NULL;
}

Expand Down
26 changes: 22 additions & 4 deletions client/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ struct em_state
uint32_t height;

EmConnection *connection;

bool shouldStop;
bool stopped;
};

em_state state = {};
Expand All @@ -77,7 +80,10 @@ onAppCmd(struct android_app *app, int32_t cmd)
switch (cmd) {
case APP_CMD_START: ALOGE("APP_CMD_START"); break;
case APP_CMD_RESUME: ALOGE("APP_CMD_RESUME"); break;
case APP_CMD_PAUSE: ALOGE("APP_CMD_PAUSE"); break;
case APP_CMD_PAUSE:
ALOGE("APP_CMD_PAUSE - setting shouldStop");
state.shouldStop = true;
break;
case APP_CMD_STOP:
ALOGE("APP_CMD_STOP - shutting down connection");
em_connection_disconnect(state.connection);
Expand Down Expand Up @@ -152,10 +158,17 @@ poll_events(struct android_app *app, struct em_state &state)
case XR_SESSION_STATE_FOCUSED: ALOGI("OpenXR session is now FOCUSED"); break;
case XR_SESSION_STATE_STOPPING:
ALOGI("OpenXR session is now STOPPING");
state.shouldStop = true;
xrEndSession(state.session);
break;
case XR_SESSION_STATE_LOSS_PENDING: ALOGI("OpenXR session is now LOSS_PENDING"); break;
case XR_SESSION_STATE_EXITING: ALOGI("OpenXR session is now EXITING"); break;
case XR_SESSION_STATE_LOSS_PENDING:
ALOGI("OpenXR session is now LOSS_PENDING");
state.shouldStop = true;
break;
case XR_SESSION_STATE_EXITING:
ALOGI("OpenXR session is now EXITING");
state.shouldStop = true;
break;
default: break;
}

Expand Down Expand Up @@ -369,9 +382,14 @@ android_main(struct android_app *app)
// Main rendering loop.
ALOGI("DEBUG: Starting main loop.\n");
while (!app->destroyRequested) {
if (poll_events(app, state)) {
if (!state.stopped && poll_events(app, state)) {
em_remote_experience_poll_and_render_frame(remote_experience);
}
if (state.shouldStop && !state.stopped) {
ALOGI("Calling em_stream_client_stop");
em_stream_client_stop(stream_client);
state.stopped = true;
}
}

ALOGI("DEBUG: Exited main loop, cleaning up.\n");
Expand Down
2 changes: 2 additions & 0 deletions server/src/ems/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,5 @@ target_link_libraries(
)

target_link_libraries(ems_streaming_server PRIVATE st_gui xrt-external-imgui-sdl2 aux_ogl)

install(TARGETS ems_streaming_server RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
2 changes: 1 addition & 1 deletion server/src/ems/ems_compositor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ compositor_init_vulkan(struct ems_compositor *c)

// Init command pool.
constexpr VkCommandPoolCreateFlags flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT;
U_LOG_E("%s", vk_result_string(ret));
// U_LOG_I("%s", vk_result_string(ret));
ret = vk_cmd_pool_init(vk, &c->cmd_pool, flags);
if (ret != VK_SUCCESS) {
EMS_COMP_ERROR(c, "vk_cmd_pool_init: %s", vk_result_string(ret));
Expand Down
34 changes: 16 additions & 18 deletions server/src/ems/ems_hmd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,24 +203,22 @@ ems_hmd_create(ems_instance &emsi)

// TODO: Find out the remote device's actual FOV. Or maybe remove this because I think get_view_poses lets us
// set the FOV dynamically.
const double hFOV = 90 * (M_PI / 180.0);
const double vFOV = 96.73 * (M_PI / 180.0);
// center of projection
const double hCOP = 0.529;
const double vCOP = 0.5;
if (
/* right eye */
!math_compute_fovs(1, hCOP, hFOV, 1, vCOP, vFOV, &eh->base.hmd->distortion.fov[1]) ||
/*
* left eye - same as right eye, except the horizontal center of projection is moved in the opposite
* direction now
*/
!math_compute_fovs(1, 1.0 - hCOP, hFOV, 1, vCOP, vFOV, &eh->base.hmd->distortion.fov[0])) {
// If those failed, it means our math was impossible.
EMS_ERROR(eh, "Failed to setup basic device info");
ems_hmd_destroy(&eh->base);
return NULL;
}

eh->base.hmd->distortion.fov[0] = (xrt_fov){
// .angle_left = -0.75f,
.angle_left = -0.855f,
.angle_right = 0.785f,
.angle_up = 0.838f,
.angle_down = -0.873f,
};
eh->base.hmd->distortion.fov[1] = (xrt_fov){
.angle_left = -0.785f,
// .angle_right = 0.75f,
.angle_right = 0.855f,
.angle_up = 0.838f,
.angle_down = -0.873f,
};

// TODO: Ditto, figure out the device's actual resolution
const int panel_w = 1080;
const int panel_h = 1200;
Expand Down
1 change: 1 addition & 0 deletions server/src/ems/gst/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ target_include_directories(
${JSONGLIB_INCLUDE_DIRS}
${GIO_INCLUDE_DIRS}
)
target_compile_definitions(ems_gst PUBLIC G_LOG_DOMAIN="ElectricMapleServer")
16 changes: 8 additions & 8 deletions server/src/ems/gst/ems_gstreamer_pipeline.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ on_offer_created(GstPromise *promise, GstElement *webrtcbin)
static void
webrtc_on_data_channel_cb(GstElement *webrtcbin, GObject *data_channel, struct ems_gstreamer_pipeline *egp)
{
U_LOG_E("called!!!!");
U_LOG_I("called!!!!");
}


Expand All @@ -187,7 +187,7 @@ webrtc_on_ice_candidate_cb(GstElement *webrtcbin, guint mlineindex, gchar *candi
static void
data_channel_error_cb(GstWebRTCDataChannel *datachannel, struct ems_gstreamer_pipeline *egp)
{
U_LOG_E("error\n");
U_LOG_E("error");
}

gboolean
Expand All @@ -205,15 +205,15 @@ datachannel_send_message(GstWebRTCDataChannel *datachannel)
static void
data_channel_open_cb(GstWebRTCDataChannel *datachannel, struct ems_gstreamer_pipeline *egp)
{
U_LOG_E("data channel opened\n");
U_LOG_I("data channel opened");

egp->timeout_src_id = g_timeout_add_seconds(3, G_SOURCE_FUNC(datachannel_send_message), datachannel);
}

static void
data_channel_close_cb(GstWebRTCDataChannel *datachannel, struct ems_gstreamer_pipeline *egp)
{
U_LOG_E("data channel closed\n");
U_LOG_I("data channel closed");

g_clear_handle_id(&egp->timeout_src_id, g_source_remove);
g_clear_object(&egp->data_channel);
Expand All @@ -240,7 +240,7 @@ data_channel_message_data_cb(GstWebRTCDataChannel *datachannel, GBytes *data, st
static void
data_channel_message_string_cb(GstWebRTCDataChannel *datachannel, gchar *str, struct ems_gstreamer_pipeline *egp)
{
U_LOG_E("Received data channel message: %s\n", str);
U_LOG_I("Received data channel message: %s\n", str);
}


Expand Down Expand Up @@ -277,7 +277,7 @@ webrtc_client_connected_cb(EmsSignalingServer *server, EmsClientId client_id, st
U_LOG_E("Couldn't make datachannel!");
assert(false);
} else {
U_LOG_E("Successfully created datachannel!");
U_LOG_I("Successfully created datachannel!");

g_signal_connect(egp->data_channel, "on-open", G_CALLBACK(data_channel_open_cb), egp);
g_signal_connect(egp->data_channel, "on-close", G_CALLBACK(data_channel_close_cb), egp);
Expand Down Expand Up @@ -536,7 +536,7 @@ loop_thread(void *data)
void
ems_gstreamer_pipeline_play(struct gstreamer_pipeline *gp)
{
U_LOG_E("Starting pipeline");
U_LOG_I("Starting pipeline");
struct ems_gstreamer_pipeline *egp = (struct ems_gstreamer_pipeline *)gp;

main_loop = g_main_loop_new(NULL, FALSE);
Expand All @@ -556,7 +556,7 @@ void
ems_gstreamer_pipeline_stop(struct gstreamer_pipeline *gp)
{
struct ems_gstreamer_pipeline *egp = (struct ems_gstreamer_pipeline *)gp;
U_LOG_E("Stopping pipeline");
U_LOG_I("Stopping pipeline");

// Settle the pipeline.
U_LOG_T("Sending EOS");
Expand Down
6 changes: 3 additions & 3 deletions server/src/ems/gst/ems_signaling_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ message_cb(SoupWebsocketConnection *connection, gint type, GBytes *message, gpoi
static void
ems_signaling_server_remove_websocket_connection(EmsSignalingServer *server, SoupWebsocketConnection *connection)
{
g_info("%s", __FUNCTION__);
g_info("%s", __func__);
EmsClientId client_id;

client_id = g_object_get_data(G_OBJECT(connection), "client_id");
Expand All @@ -155,7 +155,7 @@ closed_cb(SoupWebsocketConnection *connection, gpointer user_data)
static void
ems_signaling_server_add_websocket_connection(EmsSignalingServer *server, SoupWebsocketConnection *connection)
{
g_info("%s", __FUNCTION__);
g_info("%s", __func__);
g_object_ref(connection);
server->websocket_connections = g_slist_append(server->websocket_connections, connection);
g_object_set_data(G_OBJECT(connection), "client_id", connection);
Expand Down Expand Up @@ -215,7 +215,7 @@ ems_signaling_server_send_to_websocket_client(EmsSignalingServer *server, EmsCli
{
SoupWebsocketConnection *connection = client_id;
SoupWebsocketState socket_state;
g_info("%s", __FUNCTION__);
g_info("%s", __func__);

if (!g_slist_find(server->websocket_connections, connection)) {
g_warning("Unknown websocket connection.");
Expand Down
8 changes: 4 additions & 4 deletions server/src/test/webrtc_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ data_channel_error_cb(GstWebRTCDataChannel *datachannel, void *data)
static void
data_channel_close_cb(GstWebRTCDataChannel *datachannel, gpointer timeout_src_id)
{
U_LOG_E("Data channel closed");
U_LOG_I("Data channel closed");

g_source_remove(GPOINTER_TO_UINT(timeout_src_id));
g_clear_object(&datachannel);
Expand All @@ -58,13 +58,13 @@ data_channel_close_cb(GstWebRTCDataChannel *datachannel, gpointer timeout_src_id
static void
data_channel_message_data_cb(GstWebRTCDataChannel *datachannel, GBytes *data, void *user_data)
{
U_LOG_E("Received data channel message data: %u", (uint32_t)g_bytes_get_size(data));
U_LOG_I("Received data channel message data: %u", (uint32_t)g_bytes_get_size(data));
}

static void
data_channel_message_string_cb(GstWebRTCDataChannel *datachannel, gchar *str, void *user_data)
{
U_LOG_E("Received data channel message string: %s", str);
U_LOG_I("Received data channel message string: %s", str);
}

static gboolean
Expand All @@ -80,7 +80,7 @@ webrtc_on_data_channel_cb(GstElement *webrtcbin, GstWebRTCDataChannel *data_chan
{
guint timeout_src_id;

U_LOG_E("Successfully created datachannel");
U_LOG_I("Successfully created datachannel");

g_assert_null(datachannel);

Expand Down