diff --git a/common/include/common/option.h b/common/include/common/option.h index 4b9b780c..1ebe12be 100644 --- a/common/include/common/option.h +++ b/common/include/common/option.h @@ -51,6 +51,7 @@ struct Option char * description; const char shortopt; bool preset; + void * opaque; enum OptionType type; union @@ -67,6 +68,7 @@ struct Option bool (*validator)(struct Option * opt, const char ** error); char * (*toString )(struct Option * opt); StringList (*getValues)(struct Option * opt); + void (*cleanup )(struct Option * opt); void (*printHelp)(void); diff --git a/common/src/option.c b/common/src/option.c index c9d4df7f..3f130005 100644 --- a/common/src/option.c +++ b/common/src/option.c @@ -280,6 +280,9 @@ void option_free(void) for(int i = 0; i < state.oCount; ++i) { struct Option * o = state.options[i]; + if (o->cleanup) + o->cleanup(o); + if (o->type == OPTION_TYPE_STRING && o->value.x_string) free(o->value.x_string); free(o); diff --git a/host/include/downsample_parser.h b/host/include/downsample_parser.h index c25b02e1..1987faf3 100644 --- a/host/include/downsample_parser.h +++ b/host/include/downsample_parser.h @@ -24,6 +24,7 @@ typedef struct { + const char * module; unsigned int id; bool greater; unsigned int x; @@ -33,18 +34,19 @@ typedef struct } DownsampleRule; -extern Vector downsampleRules; - bool downsampleParser(struct Option * opt, const char * str); +void downsampleCleanup(struct Option * opt); -DownsampleRule * downsampleRule_match(int x, int y); +DownsampleRule * downsampleRule_match(Vector * rules, int x, int y); -#define DOWNSAMPLE_PARSER(moduleName) \ +#define DOWNSAMPLE_PARSER(moduleName, vector) \ { \ .module = moduleName, \ .name = "downsample", \ .description = "Downsample rules, format: [>](width)x(height):(toWidth)x(toHeight)", \ .type = OPTION_TYPE_STRING, \ .value.x_string = NULL, \ - .parser = downsampleParser \ + .parser = downsampleParser, \ + .cleanup = downsampleCleanup, \ + .opaque = (void*)(vector) \ } diff --git a/host/platform/Windows/capture/DXGI/src/pp/downsample.c b/host/platform/Windows/capture/DXGI/src/pp/downsample.c index ba7e56e2..739954c7 100644 --- a/host/platform/Windows/capture/DXGI/src/pp/downsample.c +++ b/host/platform/Windows/capture/DXGI/src/pp/downsample.c @@ -50,12 +50,13 @@ typedef struct } DownsampleInst; +static Vector downsampleRules = {0}; static void downsample_earlyInit(void) { struct Option options[] = { - DOWNSAMPLE_PARSER("dxgi"), + DOWNSAMPLE_PARSER("dxgi", &downsampleRules), {0} }; @@ -99,7 +100,9 @@ static bool downsample_configure(void * opaque, if (!this.pshader) { - DownsampleRule * rule = downsampleRule_match(*width, *height); + DownsampleRule * rule = downsampleRule_match(&downsampleRules, + *width, *height); + if (!rule || (rule->targetX == *width && rule->targetY == *height)) { this.disabled = true; diff --git a/host/platform/Windows/capture/NVFBC/src/nvfbc.c b/host/platform/Windows/capture/NVFBC/src/nvfbc.c index 4f68d374..83b6c9f6 100644 --- a/host/platform/Windows/capture/NVFBC/src/nvfbc.c +++ b/host/platform/Windows/capture/NVFBC/src/nvfbc.c @@ -136,11 +136,13 @@ static const char * nvfbc_getName(void) return "NVFBC"; }; +static Vector downsampleRules = {0}; + static void nvfbc_initOptions(void) { struct Option options[] = { - DOWNSAMPLE_PARSER("nvfbc"), + DOWNSAMPLE_PARSER("nvfbc", &downsampleRules), { .module = "nvfbc", .name = "decoupleCursor", @@ -202,12 +204,14 @@ static bool nvfbc_create( static void updateScale(void) { - DownsampleRule * rule = downsampleRule_match(this->width, this->height); + DownsampleRule * rule = downsampleRule_match(&downsampleRules, + this->width, this->height); if (rule) { this->scale = true; this->targetWidth = rule->targetX; this->targetHeight = rule->targetY; + DEBUG_INFO("Downsampling to %dx%d", this->targetWidth, this->targetHeight); return; } diff --git a/host/src/downsample_parser.c b/host/src/downsample_parser.c index d93047cd..f649bcbe 100644 --- a/host/src/downsample_parser.c +++ b/host/src/downsample_parser.c @@ -32,10 +32,11 @@ bool downsampleParser(struct Option * opt, const char * str) opt->value.x_string = strdup(str); - if (downsampleRules.data) - vector_destroy(&downsampleRules); + Vector * downsampleRules = (Vector *)opt->opaque; + if (downsampleRules->data) + vector_destroy(downsampleRules); - if (!vector_create(&downsampleRules, sizeof(DownsampleRule), 10)) + if (!vector_create(downsampleRules, sizeof(DownsampleRule), 10)) { DEBUG_ERROR("Failed to allocate ram"); return false; @@ -53,6 +54,7 @@ bool downsampleParser(struct Option * opt, const char * str) ++token; } + rule.module = opt->module; if (sscanf(token, "%ux%u:%ux%u", &rule.x, &rule.y, @@ -66,7 +68,9 @@ bool downsampleParser(struct Option * opt, const char * str) rule.id = count++; DEBUG_INFO( - "Rule %u: %ux%u IF X %s %4u %s Y %s %4u", + "%s:%s rule %u: %ux%u IF X %s %4u %s Y %s %4u", + opt->module, + opt->name, rule.id, rule.targetX, rule.targetY, @@ -76,7 +80,7 @@ bool downsampleParser(struct Option * opt, const char * str) rule.greater ? "> " : "==", rule.y ); - vector_push(&downsampleRules, &rule); + vector_push(downsampleRules, &rule); token = strtok(NULL, ","); } @@ -85,14 +89,20 @@ bool downsampleParser(struct Option * opt, const char * str) return true; } -DownsampleRule * downsampleRule_match(int x, int y) +void downsampleCleanup(struct Option * opt) +{ + Vector * downsampleRules = (Vector *)opt->opaque; + if (downsampleRules->data) + vector_destroy(downsampleRules); +} + +DownsampleRule * downsampleRule_match(Vector * rules, int x, int y) { DownsampleRule * rule, * match = NULL; - vector_forEachRef(rule, &downsampleRules) + vector_forEachRef(rule, rules) { - if ( - ( rule->greater && (x > rule->x || y > rule->y)) || - (!rule->greater && (x == rule->x && y == rule->y))) + if (( rule->greater && (x > rule->x || y > rule->y)) || + (!rule->greater && (x == rule->x && y == rule->y))) { match = rule; }