Check display mode before streaming

This commit is contained in:
Iwan Timmer
2017-05-27 16:41:52 +02:00
parent 7e73de80b3
commit 0e1cabbd82
6 changed files with 79 additions and 0 deletions

View File

@@ -232,6 +232,9 @@ static int load_server_status(PSERVER_DATA server) {
if (xml_search(data->memory, data->size, "GfeVersion", (char**) &server->serverInfo.serverInfoGfeVersion) != GS_OK)
goto cleanup;
if (xml_modelist(data->memory, data->size, &server->modes) != GS_OK)
goto cleanup;
// These fields are present on all version of GFE that this client supports
if (!strlen(currentGameText) || !strlen(pairedText) || !strlen(server->serverInfo.serverInfoAppVersion) || !strlen(stateText))
goto cleanup;
@@ -641,6 +644,18 @@ int gs_start_app(PSERVER_DATA server, STREAM_CONFIGURATION *config, int appId, b
char* result = NULL;
char uuid_str[37];
PDISPLAY_MODE mode = server->modes;
bool correct_mode = false;
while (mode != NULL) {
if (mode->width == config->width && mode->height == config->height && mode->refresh == config->fps)
correct_mode = true;
mode = mode->next;
}
if (!correct_mode)
return GS_NOT_SUPPORTED_MODE;
if (config->height >= 2160 && !server->supports4K)
return GS_NOT_SUPPORTED_4K;

View File

@@ -36,6 +36,7 @@ typedef struct _SERVER_DATA {
int currentGame;
int serverMajorVersion;
char* gsVersion;
PDISPLAY_MODE modes;
SERVER_INFORMATION serverInfo;
} SERVER_DATA, *PSERVER_DATA;

View File

@@ -27,5 +27,6 @@
#define GS_IO_ERROR -5
#define GS_NOT_SUPPORTED_4K -6
#define GS_UNSUPPORTED_VERSION -7
#define GS_NOT_SUPPORTED_MODE -8
const char* gs_error;

View File

@@ -79,6 +79,37 @@ static void XMLCALL _xml_end_applist_element(void *userData, const char *name) {
}
}
static void XMLCALL _xml_start_mode_element(void *userData, const char *name, const char **atts) {
struct xml_query *search = (struct xml_query*) userData;
if (strcmp("DisplayMode", name) == 0) {
PDISPLAY_MODE mode = calloc(1, sizeof(DISPLAY_MODE));
if (mode != NULL) {
mode->next = (PDISPLAY_MODE) search->data;
search->data = mode;
}
} else if (search->data != NULL && (strcmp("Height", name) == 0 || strcmp("Width", name) == 0 || strcmp("RefreshRate", name) == 0)) {
search->memory = malloc(1);
search->size = 0;
search->start = 1;
}
}
static void XMLCALL _xml_end_mode_element(void *userData, const char *name) {
struct xml_query *search = (struct xml_query*) userData;
if (search->data != NULL && search->start) {
PDISPLAY_MODE mode = (PDISPLAY_MODE) search->data;
if (strcmp("Width", name) == 0)
mode->width = atoi(search->memory);
else if (strcmp("Height", name) == 0)
mode->height = atoi(search->memory);
else if (strcmp("RefreshRate", name) == 0)
mode->refresh = atoi(search->memory);
free(search->memory);
search->start = 0;
}
}
static void XMLCALL _xml_write_data(void *userData, const XML_Char *s, int len) {
struct xml_query *search = (struct xml_query*) userData;
if (search->start > 0) {
@@ -141,3 +172,24 @@ int xml_applist(char* data, size_t len, PAPP_LIST *app_list) {
return GS_OK;
}
int xml_modelist(char* data, size_t len, PDISPLAY_MODE *mode_list) {
struct xml_query query = {0};
query.memory = calloc(1, 1);
XML_Parser parser = XML_ParserCreate("UTF-8");
XML_SetUserData(parser, &query);
XML_SetElementHandler(parser, _xml_start_mode_element, _xml_end_mode_element);
XML_SetCharacterDataHandler(parser, _xml_write_data);
if (! XML_Parse(parser, data, len, 1)) {
int code = XML_GetErrorCode(parser);
gs_error = XML_ErrorString(code);
XML_ParserFree(parser);
return GS_INVALID;
}
XML_ParserFree(parser);
*mode_list = (PDISPLAY_MODE) query.data;
return GS_OK;
}

View File

@@ -26,5 +26,13 @@ typedef struct _APP_LIST {
struct _APP_LIST *next;
} APP_LIST, *PAPP_LIST;
typedef struct _DISPLAY_MODE {
unsigned int height;
unsigned int width;
unsigned int refresh;
struct _DISPLAY_MODE *next;
} DISPLAY_MODE, *PDISPLAY_MODE;
int xml_search(char* data, size_t len, char* node, char** result);
int xml_applist(char* data, size_t len, PAPP_LIST *app_list);
int xml_modelist(char* data, size_t len, PDISPLAY_MODE *mode_list);

View File

@@ -88,6 +88,8 @@ static void stream(PSERVER_DATA server, PCONFIGURATION config, enum platform sys
if (ret < 0) {
if (ret == GS_NOT_SUPPORTED_4K)
fprintf(stderr, "Server doesn't support 4K\n");
else if (ret == GS_NOT_SUPPORTED_MODE)
fprintf(stderr, "Server doesn't support %dx%d (%d fps)\n", config->stream.width, config->stream.height, config->stream.fps);
else
fprintf(stderr, "Errorcode starting app: %d\n", ret);
exit(-1);