diff --git a/src/ctl/ctl-sink.c b/src/ctl/ctl-sink.c index 831be6d..b9a4a85 100644 --- a/src/ctl/ctl-sink.c +++ b/src/ctl/ctl-sink.c @@ -35,6 +35,7 @@ #include "rtsp.h" #include "shl_macro.h" #include "shl_util.h" +#include "wfd.h" struct ctl_sink { sd_event *event; @@ -55,6 +56,9 @@ struct ctl_sink { uint32_t resolutions_cea; uint32_t resolutions_vesa; uint32_t resolutions_hh; + + int hres; + int vres; }; /* @@ -190,6 +194,27 @@ static int sink_setup_fn(struct rtsp *bus, struct rtsp_message *m, void *data) return 0; } +static int sink_set_format(struct ctl_sink *s, + unsigned int cea_res, + unsigned int vesa_res, + unsigned int hh_res) +{ + int hres, vres; + + if ((vfd_get_cea_resolution(cea_res, &hres, &vres) == 0) || + (vfd_get_vesa_resolution(vesa_res, &hres, &vres) == 0) || + (vfd_get_hh_resolution(hh_res, &hres, &vres) == 0)) { + if (hres && vres) { + s->hres = hres; + s->vres = vres; + ctl_fn_sink_resolution_set(s, hres, vres); + return 0; + } + } + + return -EINVAL; +} + static void sink_handle_set_parameter(struct ctl_sink *s, struct rtsp_message *m) { @@ -197,6 +222,7 @@ static void sink_handle_set_parameter(struct ctl_sink *s, const char *trigger; const char *url; char *nu; + unsigned int cea_res, vesa_res, hh_res; int r; r = rtsp_message_new_reply_for(m, &rep, RTSP_CODE_OK, NULL); @@ -227,6 +253,15 @@ static void sink_handle_set_parameter(struct ctl_sink *s, } } + /* M4 again */ + r = rtsp_message_read(m, "{<****hhh>}", "wfd_video_formats", + &cea_res, &vesa_res, &hh_res); + if (r == 0) { + r = sink_set_format(s, cea_res, vesa_res, hh_res); + if (r) + return cli_vERR(r); + } + /* M5 */ r = rtsp_message_read(m, "{}", "wfd_trigger_method", &trigger); if (r < 0) diff --git a/src/ctl/ctl.h b/src/ctl/ctl.h index 125d7b5..29145d1 100644 --- a/src/ctl/ctl.h +++ b/src/ctl/ctl.h @@ -266,6 +266,7 @@ void ctl_fn_link_free(struct ctl_link *l); void ctl_fn_sink_connected(struct ctl_sink *s); void ctl_fn_sink_disconnected(struct ctl_sink *s); +void ctl_fn_sink_resolution_set(struct ctl_sink *s, int hres, int vres); void cli_fn_help(void); diff --git a/src/ctl/sinkctl.c b/src/ctl/sinkctl.c index 2006538..e668adc 100644 --- a/src/ctl/sinkctl.c +++ b/src/ctl/sinkctl.c @@ -325,9 +325,10 @@ static const struct cli_cmd cli_cmds[] = { { }, }; -static void spawn_gst(void) +static void spawn_gst(int hres, int vres) { char *argv[64]; + char resolution[64]; pid_t pid; int fd_journal, i; sigset_t mask; @@ -367,6 +368,11 @@ static void spawn_gst(void) argv[i++] = "-s"; argv[i++] = gst_scale_res; } + if (hres && vres) { + sprintf(resolution, "%dx%d", hres, vres); + argv[i++] = "-r"; + argv[i++] = resolution; + } argv[i] = NULL; execve(argv[0], argv, environ); @@ -389,7 +395,6 @@ void ctl_fn_sink_connected(struct ctl_sink *s) { cli_notice("SINK connected"); sink_connected = true; - spawn_gst(); } void ctl_fn_sink_disconnected(struct ctl_sink *s) @@ -403,6 +408,13 @@ void ctl_fn_sink_disconnected(struct ctl_sink *s) } } +void ctl_fn_sink_resolution_set(struct ctl_sink *s, int hres, int vres) +{ + cli_printf("SINK set resolution %dx%d\n", hres, vres); + if (sink_connected) + spawn_gst(hres, vres); +} + void ctl_fn_peer_new(struct ctl_peer *p) { if (p->l != running_link || shl_isempty(p->wfd_subelements))