diff --git a/src/disp/disp.h b/src/disp/disp.h index deaf5b5..509807a 100644 --- a/src/disp/disp.h +++ b/src/disp/disp.h @@ -58,16 +58,30 @@ enum wfd_session_state WFD_SESSION_STATE_TEARING_DOWN, }; +struct wfd_rectangle +{ + int x; + int y; + int width; + int height; +}; + +enum wfd_display_server_type +{ + WFD_DISPLAY_SERVER_TYPE_UNKNOWN = 0, + WFD_DISPLAY_SERVER_TYPE_X, +}; + +enum wfd_audio_server_type +{ + WFD_AUDIO_SERVER_TYPE_UNKNOWN = 0, + WFD_AUDIO_SERVER_TYPE_PULSE_AUDIO, +}; + int wfd_out_session_new(struct wfd_session **out, - struct wfd_sink *sink, - const char *authority, - const char *display, - uint32_t x, - uint32_t y, - uint32_t width, - uint32_t height, - const char *audio_dev); -int wfd_session_start(struct wfd_session *s, uint64_t id); + unsigned int id, + struct wfd_sink *sink); +int wfd_session_start(struct wfd_session *s); enum wfd_session_dir wfd_session_get_dir(struct wfd_session *s); uint64_t wfd_session_get_id(struct wfd_session *s); const char * wfd_session_get_stream_url(struct wfd_session *s); @@ -80,6 +94,20 @@ struct wfd_session * wfd_session_ref(struct wfd_session *s); void wfd_session_unref(struct wfd_session *s); uint64_t wfd_session_get_id(struct wfd_session *s); struct wfd_sink * wfd_out_session_get_sink(struct wfd_session *s); +enum wfd_display_server_type wfd_session_get_disp_type(struct wfd_session *s); +int wfd_session_set_disp_type(struct wfd_session *s, enum wfd_display_server_type); +const char * wfd_session_get_disp_name(struct wfd_session *s); +int wfd_session_set_disp_name(struct wfd_session *s, const char *disp_name); +const char * wfd_session_get_disp_params(struct wfd_session *s); +int wfd_session_set_disp_params(struct wfd_session *s, const char *disp_params); +const char * wfd_session_get_disp_auth(struct wfd_session *s); +int wfd_session_set_disp_auth(struct wfd_session *s, const char *disp_auth); +const struct wfd_rectangle * wfd_session_get_disp_dimension(struct wfd_session *s); +int wfd_session_set_disp_dimension(struct wfd_session *s, const struct wfd_rectangle *rect); +enum wfd_audio_server_type wfd_session_get_audio_type(struct wfd_session *s); +int wfd_session_set_audio_type(struct wfd_session *s, enum wfd_audio_server_type audio_type); +const char * wfd_session_get_audio_dev_name(struct wfd_session *s); +int wfd_session_set_audio_dev_name(struct wfd_session *s, char *audio_dev_name); void wfd_session_unrefp(struct wfd_session **s); unsigned int * wfd_session_to_htable(struct wfd_session *s); struct wfd_session * wfd_session_from_htable(unsigned int *e); @@ -107,15 +135,7 @@ void wfd_sink_free(struct wfd_sink *sink); const char * wfd_sink_get_label(struct wfd_sink *sink); const union wfd_sube * wfd_sink_get_dev_info(struct wfd_sink *sink); -int wfd_sink_start_session(struct wfd_sink *sink, - struct wfd_session **out, - const char *authority, - const char *display, - uint32_t x, - uint32_t y, - uint32_t width, - uint32_t height, - const char *audio_dev); +int wfd_sink_create_session(struct wfd_sink *sink, struct wfd_session **out); void wfd_sink_handle_session_ended(struct wfd_sink *sink); bool wfd_sink_is_session_started(struct wfd_sink *sink); static inline void wfd_sink_freep(struct wfd_sink **s) diff --git a/src/disp/wfd-dbus.c b/src/disp/wfd-dbus.c index ddd86a1..e3a4753 100644 --- a/src/disp/wfd-dbus.c +++ b/src/disp/wfd-dbus.c @@ -371,43 +371,92 @@ static int wfd_dbus_sink_start_session(sd_bus_message *m, sd_bus_error *ret_error) { struct wfd_sink *sink = userdata; - _wfd_session_unref_ struct wfd_session *session = NULL; - _shl_free_ char *path = NULL; - const char *authority; - const char *display; - uint32_t x, y, width, height; + _wfd_session_unref_ struct wfd_session *sess = NULL; + _shl_free_ char *path = NULL, *disp_type_name = NULL, *disp_name = NULL; + char *disp_params; + const char *disp, *disp_auth; const char *audio_dev; + struct wfd_rectangle rect; int r; r = sd_bus_message_read(m, "ssuuuus", - &authority, - &display, - &x, - &y, - &width, - &height, + &disp_auth, + &disp, + &rect.x, + &rect.y, + &rect.width, + &rect.height, &audio_dev); if(0 > r) { return r; } - r = wfd_sink_start_session(sink, - &session, - authority, - display, - x, y, width, height, - audio_dev); + r = sscanf(disp, "%m[^:]://%ms", + &disp_type_name, + &disp_name); + if(r != 2) { + return -EINVAL; + } + + if(strcmp("x", disp_type_name)) { + return -EINVAL; + } + + r = wfd_sink_create_session(sink, &sess); if(0 > r) { return r; } - r = wfd_dbus_get_session_path(session, &path); + wfd_session_set_disp_type(sess, WFD_DISPLAY_SERVER_TYPE_X); if(0 > r) { return r; } - session = NULL; + disp_params = strchr(disp_name, '?'); + if(disp_params) { + *disp_params ++ = '\0'; + } + + r = wfd_session_set_disp_name(sess, disp_name); + if(0 > r) { + return r; + } + + r = wfd_session_set_disp_params(sess, disp_params); + if(0 > r) { + return r; + } + + r = wfd_session_set_disp_auth(sess, disp_auth); + if(0 > r) { + return r; + } + + r = wfd_session_set_disp_dimension(sess, &rect); + if(0 > r) { + return r; + } + + r = wfd_session_set_audio_type(sess, WFD_AUDIO_SERVER_TYPE_PULSE_AUDIO); + if(0 > r) { + return r; + } + + r = wfd_session_set_audio_type(sess, WFD_AUDIO_SERVER_TYPE_PULSE_AUDIO); + if(0 > r) { + return r; + } + + r = wfd_session_start(sess); + if(0 > r) { + return r; + } + + r = wfd_dbus_get_session_path(sess, &path); + if(0 > r) { + return r; + } return sd_bus_reply_method_return(m, "o", path); } diff --git a/src/disp/wfd-out-session.c b/src/disp/wfd-out-session.c index 59f21c7..552607a 100644 --- a/src/disp/wfd-out-session.c +++ b/src/disp/wfd-out-session.c @@ -32,12 +32,6 @@ #define LOCAL_RTP_PORT 16384 #define LOCAL_RTCP_PORT 16385 -enum wfd_display_type -{ - WFD_DISPLAY_TYPE_UNKNOWN, - WFD_DISPLAY_TYPE_X, -}; - struct wfd_out_session { struct wfd_session parent; @@ -48,18 +42,10 @@ struct wfd_out_session sd_event_source *encoder_source; - enum wfd_display_type display_type; - char *authority; - char *display_name; const char *display_param_name; const char *display_param_value; - uint16_t x; - uint16_t y; - uint16_t width; - uint16_t height; enum wfd_resolution_standard std; uint32_t mask; - char *audio_dev; /*GstElement *pipeline;*/ /*GstBus *bus;*/ @@ -70,96 +56,51 @@ static int force_proc_exit(pid_t pid); static const struct rtsp_dispatch_entry out_session_rtsp_disp_tbl[]; int wfd_out_session_new(struct wfd_session **out, - struct wfd_sink *sink, - const char *authority, - const char *display, - uint32_t x, - uint32_t y, - uint32_t width, - uint32_t height, - const char *audio_dev) + unsigned int id, + struct wfd_sink *sink) { - _shl_free_ char *display_schema = NULL; - _shl_free_ char *display_name = NULL; - char *display_param; _wfd_session_unref_ struct wfd_session *s; struct wfd_out_session *os; - enum wfd_display_type display_type; - enum wfd_resolution_standard std; - uint32_t mask; + //enum wfd_resolution_standard std; + //uint32_t mask; int r; - r = sscanf(display, "%m[^:]://%ms", - &display_schema, - &display_name); - if(r != 2) { - return -EINVAL; - } - - if(!strcmp("x", display_schema)) { - display_type = WFD_DISPLAY_TYPE_X; - } - else { - return -EINVAL; - } - - display_param = strchr(display_name, '?'); - if(display_param) { - *display_param ++ = '\0'; - } - - if(!width || !height) { - return -EINVAL; - } - - r = vfd_get_mask_from_resolution(width, height, &std, &mask); - if(0 > r) { - return -EINVAL; - } +// r = vfd_get_mask_from_resolution(width, height, &std, &mask); +// if(0 > r) { +// return -EINVAL; +// } s = calloc(1, sizeof(struct wfd_out_session)); if(!s) { return -ENOMEM; } + r = wfd_session_init(s, + id, + WFD_SESSION_DIR_OUT, + out_session_rtsp_disp_tbl); + if(0 > r) { + return r; + } + os = wfd_out_session(s); - os->authority = strdup(authority); - if(!os->authority) { - free(s); - return -ENOMEM; - } - - os->audio_dev = strdup(audio_dev); - if(!os->audio_dev) { - free(s); - return -ENOMEM; - } - - wfd_session_init(s, WFD_SESSION_DIR_OUT, out_session_rtsp_disp_tbl); os->fd = -1; os->sink = sink; - os->display_type = display_type; - os->display_name = display_name; - os->x = x; - os->y = y; - os->width = width; - os->height = height; - os->mask = mask; - os->std = std; +// os->mask = mask; +// os->std = std; +// +// if(display_param) { +// os->display_param_name = display_param; +// display_param = strchr(display_param, '='); +// if(!display_param) { +// return -EINVAL; +// } +// *display_param ++ = '\0'; +// os->display_param_value = display_param; +// } - if(display_param) { - os->display_param_name = display_param; - display_param = strchr(display_param, '='); - if(!display_param) { - return -EINVAL; - } - *display_param ++ = '\0'; - os->display_param_value = display_param; - } - - *out = wfd_session(s); + *out = s; s = NULL; - display_name = NULL; return 0; } @@ -319,21 +260,6 @@ void wfd_out_session_destroy(struct wfd_session *s) /*os->gst_launch_source = NULL;*/ /*}*/ - if(os->audio_dev) { - free(os->audio_dev); - os->audio_dev = NULL; - } - - if(os->display_name) { - free(os->display_name); - os->display_name = NULL; - } - - if(os->authority) { - free(os->authority); - os->authority = NULL; - } - /*if(os->bus) {*/ /*gst_bus_remove_watch(os->bus);*/ /*g_object_unref(os->bus);*/ diff --git a/src/disp/wfd-session.c b/src/disp/wfd-session.c index eb7c6e2..3524b33 100644 --- a/src/disp/wfd-session.c +++ b/src/disp/wfd-session.c @@ -240,6 +240,21 @@ void wfd_session_unref(struct wfd_session *s) s->stream.url = NULL; } + if(s->disp_auth) { + free(s->disp_auth); + s->disp_auth = NULL; + } + + if(s->disp_name) { + free(s->disp_name); + s->disp_name = NULL; + } + + if(s->audio_dev_name) { + free(s->audio_dev_name); + s->audio_dev_name = NULL; + } + wfd_session_hup(s); s->rtp_ports[0] = 0; @@ -537,10 +552,12 @@ error: } int wfd_session_init(struct wfd_session *s, + unsigned int id, enum wfd_session_dir dir, const struct rtsp_dispatch_entry *disp_tbl) { s->ref_count = 1; + s->id = id; s->dir = dir; s->rtsp_disp_tbl = disp_tbl; @@ -668,14 +685,13 @@ static void wfd_session_hup(struct wfd_session *s) s->rtsp = NULL; } -int wfd_session_start(struct wfd_session *s, uint64_t id) +int wfd_session_start(struct wfd_session *s) { int r; _shl_close_ int fd = -1; uint32_t mask; assert(wfd_is_session(s)); - assert(id); if(WFD_SESSION_STATE_NULL != s->state) { return -EINPROGRESS; @@ -698,12 +714,135 @@ int wfd_session_start(struct wfd_session *s, uint64_t id) fd = -1; - s->id = id; wfd_session_set_state(s, WFD_SESSION_STATE_CONNECTING); return 0; } +enum wfd_display_server_type wfd_session_get_disp_type(struct wfd_session *s) +{ + return s->disp_type; +} + +int wfd_session_set_disp_type(struct wfd_session *s, enum wfd_display_server_type disp_type) +{ + s->disp_type = disp_type; + + return 0; +} + +const char * wfd_session_get_disp_name(struct wfd_session *s) +{ + return s->disp_name; +} + +int wfd_session_set_disp_name(struct wfd_session *s, const char *disp_name) +{ + char *name = disp_name ? strdup(disp_name) : NULL; + if(!name) { + return -ENOMEM; + } + + if(s->disp_name) { + free(s->disp_name); + } + + s->disp_name = name; + + return 0; +} + +const char * wfd_session_get_disp_params(struct wfd_session *s) +{ + return s->disp_params; +} + +int wfd_session_set_disp_params(struct wfd_session *s, const char *disp_params) +{ + char *params = disp_params ? strdup(disp_params) : NULL; + if(disp_params && !params) { + return -ENOMEM; + } + + if(s->disp_params) { + free(s->disp_params); + } + + s->disp_params = params; + + return 0; +} + +const char * wfd_session_get_disp_auth(struct wfd_session *s) +{ + return s->disp_auth; +} + +int wfd_session_set_disp_auth(struct wfd_session *s, const char *disp_auth) +{ + char *auth = disp_auth ? strdup(disp_auth) : NULL; + if(!auth) { + return -ENOMEM; + } + + if(s->disp_auth) { + free(s->disp_auth); + } + + s->disp_auth = auth; + + return 0; +} + +const struct wfd_rectangle * wfd_session_get_disp_dimension(struct wfd_session *s) +{ + return &s->disp_dimen; +} + +int wfd_session_set_disp_dimension(struct wfd_session *s, const struct wfd_rectangle *rect) +{ + assert(rect); + + if(rect) { + s->disp_dimen = *rect; + } + + return 0; +} + +enum wfd_audio_server_type wfd_session_get_audio_type(struct wfd_session *s) +{ + return s->audio_type; +} + +int wfd_session_set_audio_type(struct wfd_session *s, enum wfd_audio_server_type audio_type) +{ + s->audio_type = audio_type; + + return 0; +} + +const char * wfd_session_get_audio_dev_name(struct wfd_session *s) +{ + return s->audio_dev_name; +} + +int wfd_session_set_audio_dev_name(struct wfd_session *s, char *audio_dev_name) +{ + char *name = audio_dev_name ? strdup(audio_dev_name) : NULL; + if(!name) { + return -ENOMEM; + } + + if(s->audio_dev_name) { + free(s->audio_dev_name); + } + + s->audio_dev_name = name; + + return 0; +} + void wfd_session_unrefp(struct wfd_session **s) { if(s) { diff --git a/src/disp/wfd-session.h b/src/disp/wfd-session.h index 079f682..c462884 100644 --- a/src/disp/wfd-session.h +++ b/src/disp/wfd-session.h @@ -111,9 +111,19 @@ struct wfd_session uint16_t rtp_port; uint16_t rtcp_port; } stream; + + enum wfd_display_server_type disp_type; + char *disp_name; + char *disp_params; + char *disp_auth; + struct wfd_rectangle disp_dimen; + + enum wfd_audio_server_type audio_type; + char *audio_dev_name; }; int wfd_session_init(struct wfd_session *s, + unsigned int id, enum wfd_session_dir dir, const struct rtsp_dispatch_entry *disp_tbl); int wfd_session_gen_stream_url(struct wfd_session *s, diff --git a/src/disp/wfd-sink.c b/src/disp/wfd-sink.c index c4313e6..b8a7007 100644 --- a/src/disp/wfd-sink.c +++ b/src/disp/wfd-sink.c @@ -113,18 +113,10 @@ struct ctl_peer * wfd_sink_get_peer(struct wfd_sink *sink) return sink->peer; } -int wfd_sink_start_session(struct wfd_sink *sink, - struct wfd_session **out, - const char *authority, - const char *display, - uint32_t x, - uint32_t y, - uint32_t width, - uint32_t height, - const char *audio_dev) +int wfd_sink_create_session(struct wfd_sink *sink, struct wfd_session **out) { int r; - _wfd_session_unref_ struct wfd_session *s = NULL; + _wfd_session_unref_ struct wfd_session *sess = NULL; assert(sink); assert(out); @@ -133,34 +125,24 @@ int wfd_sink_start_session(struct wfd_sink *sink, return -EALREADY; } - r = wfd_out_session_new(&s, - sink, - authority, - display, - x, - y, - width, - height, - audio_dev); + r = wfd_out_session_new(&sess, + ctl_wfd_alloc_session_id(ctl_wfd_get()), + sink); if(0 > r) { return r; } - r = wfd_session_start(s, ctl_wfd_alloc_session_id(ctl_wfd_get())); + r = wfd_sink_set_session(sink, sess); if(0 > r) { return r; } - r = wfd_sink_set_session(sink, s); - if(0 > r) { - return r; - } + sink->session = sess; + *out = wfd_session_ref(sess); + sess = NULL; wfd_fn_sink_properties_changed(sink, "Session"); - sink->session = s; - *out = s; - return 0; }