diff --git a/res/sinkctl.protocol-extension.example b/res/sinkctl.protocol-extension.example new file mode 100644 index 0000000..a0205fe --- /dev/null +++ b/res/sinkctl.protocol-extension.example @@ -0,0 +1,18 @@ +#Example of extra parameters to extend sink request + +[sinkctl] +extends.wfd_video_formats=40 00 01 10 0001bdeb 051557ff 00000fff 10 0000 001f 11 0780 0438, 02 10 0001bdeb 155557ff 00000fff 10 0000 001f 11 0780 0438 +extends.wfd_audio_codecs=LPCM 00000003 00, AAC 0000000f 00, AC3 00000007 00 +extends.wfd_display_edid=0001 00ffffffffffff0051f38f50010000000e100104a51d10ff2f0000a057499b2610484f000000010101010101010101010101010101011a36809c70381f403020350025a510000018000000fc00496e7465726e616c204c43440a000000fd003c3c9a9a0e00000000000000000000000000000000000000000000000000000030 +extends.wfd_connector_type=05 +extends.microsoft_cursor=none +extends.microsoft_rtcp_capability=none +extends.wfd_idr_request_capability=1 +extends.microsoft_latency_management_capability=none +extends.microsoft_format_change_capability=none +extends.microsoft_diagnostics_capability=none +extends.intel_friendly_name=miraclecast +extends.intel_sink_manufacturer_name=GNU Linux +extends.intel_sink_model_name=Arch linux +extends.intel_sink_device_URL=http://github.com/albfan/miraclecast +extends.wfd_uibc_capability=input_category_list=GENERIC, HIDC;generic_cap_list=Keyboard;hidc_cap_list=Keyboard/USB, Mouse/USB, MultiTouch/USB, Gesture/USB, RemoteControl/USB;port=none diff --git a/src/ctl/ctl-sink.c b/src/ctl/ctl-sink.c index bd0d967..aeb59bf 100644 --- a/src/ctl/ctl-sink.c +++ b/src/ctl/ctl-sink.c @@ -88,26 +88,67 @@ static void sink_handle_get_parameter(struct ctl_sink *s, /* wfd_content_protection */ check_and_response_option("wfd_content_protection", "none"); + GHashTable* protocol_extensions = s->protocol_extensions; /* wfd_video_formats */ - char wfd_video_formats[128]; - sprintf(wfd_video_formats, "00 00 03 10 %08x %08x %08x 00 0000 0000 10 none none", - s->resolutions_cea, s->resolutions_vesa, s->resolutions_hh); - check_and_response_option("wfd_video_formats", wfd_video_formats); + gchar* wfd_video_formats = NULL; + if (protocol_extensions != NULL) { + gchar* wfd_video_formats_extension = g_hash_table_lookup(protocol_extensions, WFD_VIDEO_FORMATS); + if (wfd_video_formats_extension != NULL) { + wfd_video_formats = wfd_video_formats_extension; + } + } + if (wfd_video_formats == NULL) { + char video_formats[128]; + sprintf(video_formats, "00 00 03 10 %08x %08x %08x 00 0000 0000 10 none none", + s->resolutions_cea, s->resolutions_vesa, s->resolutions_hh); + wfd_video_formats = video_formats; + } + check_and_response_option(WFD_VIDEO_FORMATS, wfd_video_formats); + /* wfd_audio_codecs */ - check_and_response_option("wfd_audio_codecs", "AAC 00000007 00"); + gchar* wfd_audio_codecs = "AAC 00000007 00"; + if (protocol_extensions != NULL) { + gchar* wfd_audio_codecs_extension = g_hash_table_lookup(protocol_extensions, WFD_AUDIO_CODECS); + if (wfd_audio_codecs_extension != NULL) { + wfd_audio_codecs = wfd_audio_codecs_extension; + } + } + check_and_response_option(WFD_AUDIO_CODECS, wfd_audio_codecs); + /* wfd_client_rtp_ports */ char wfd_client_rtp_ports[128]; sprintf(wfd_client_rtp_ports, "RTP/AVP/UDP;unicast %d 0 mode=play", rstp_port); check_and_response_option("wfd_client_rtp_ports", wfd_client_rtp_ports); + if (protocol_extensions != NULL) { + GList* extension_keys = g_hash_table_get_keys(protocol_extensions); + for (int i = 0; isession); free(s->url); sd_event_unref(s->event); + g_hash_table_destroy(s->protocol_extensions); free(s); } diff --git a/src/ctl/ctl-sink.h b/src/ctl/ctl-sink.h index 996cba0..22c8401 100644 --- a/src/ctl/ctl-sink.h +++ b/src/ctl/ctl-sink.h @@ -32,6 +32,7 @@ #include #include #include +#include #include "ctl.h" #include "rtsp.h" @@ -39,6 +40,10 @@ #include "shl_util.h" #include "wfd.h" +#define WFD_VIDEO_FORMATS "wfd_video_formats" +#define WFD_AUDIO_CODECS "wfd_audio_codecs" +#define WFD_UIBC_CAPABILITY "wfd_uibc_capability" + extern int rstp_port; extern bool uibc_option; extern bool uibc_enabled; @@ -68,6 +73,8 @@ struct ctl_sink { int hres; int vres; + + GHashTable* protocol_extensions; }; bool check_rtsp_option(struct rtsp_message *m, char *option); diff --git a/src/ctl/sinkctl.c b/src/ctl/sinkctl.c index 03941a6..d53ff51 100644 --- a/src/ctl/sinkctl.c +++ b/src/ctl/sinkctl.c @@ -66,6 +66,7 @@ bool external_player; int rstp_port; int uibc_port; char* player; +GHashTable* protocol_extensions; unsigned int wfd_supported_res_cea = 0x0001ffff; unsigned int wfd_supported_res_vesa = 0x1fffffff; @@ -748,6 +749,7 @@ static int ctl_interactive(char **argv, int argc) r = ctl_sink_new(&sink, cli_event); if (r < 0) goto error; + sink->protocol_extensions = protocol_extensions; ctl_wifi_fetch(wifi); @@ -938,6 +940,22 @@ int main(int argc, char **argv) } g_free(autocmd); } + gchar** sinkctl_keys; + gsize len = 0; + protocol_extensions = g_hash_table_new(g_str_hash, g_str_equal); + + sinkctl_keys = g_key_file_get_keys (gkf, + "sinkctl", + &len, + NULL); + for (int i = 0; i < (int)len; i++) { + if (g_str_has_prefix(sinkctl_keys[i], "extends.")) { + gchar* orig_key = sinkctl_keys[i]; + gchar* key = orig_key+8; + gchar* value = g_key_file_get_string (gkf, "sinkctl", orig_key, NULL); + g_hash_table_insert(protocol_extensions, key, value); + } + } g_key_file_free(gkf); }