avifenc, avifdec: Allow "-j all" to automatically use all of the cores on the machine Fixes: #645
diff --git a/apps/avifdec.c b/apps/avifdec.c index 313439c..81de197 100644 --- a/apps/avifdec.c +++ b/apps/avifdec.c
@@ -29,7 +29,7 @@ printf("Options:\n"); printf(" -h,--help : Show syntax help\n"); printf(" -V,--version : Show the version number\n"); - printf(" -j,--jobs J : Number of jobs (worker threads, default: 1)\n"); + printf(" -j,--jobs J : Number of jobs (worker threads, default: 1. Use \"all\" to use all available cores)\n"); printf(" -c,--codec C : AV1 codec to use (choose from versions list below)\n"); printf(" -d,--depth D : Output depth [8,16]. (PNG only; For y4m, depth is retained, and JPEG is always 8bpc)\n"); printf(" -q,--quality Q : Output quality [0-100]. (JPEG only, default: %d)\n", DEFAULT_JPEG_QUALITY); @@ -74,9 +74,13 @@ return 0; } else if (!strcmp(arg, "-j") || !strcmp(arg, "--jobs")) { NEXTARG(); - jobs = atoi(arg); - if (jobs < 1) { - jobs = 1; + if (!strcmp(arg, "all")) { + jobs = avifQueryMaxThreads(); + } else { + jobs = atoi(arg); + if (jobs < 1) { + jobs = 1; + } } } else if (!strcmp(arg, "-c") || !strcmp(arg, "--codec")) { NEXTARG();
diff --git a/apps/avifenc.c b/apps/avifenc.c index 3e8a3b0..4415bf8 100644 --- a/apps/avifenc.c +++ b/apps/avifenc.c
@@ -51,7 +51,7 @@ printf("Options:\n"); printf(" -h,--help : Show syntax help\n"); printf(" -V,--version : Show the version number\n"); - printf(" -j,--jobs J : Number of jobs (worker threads, default: 1)\n"); + printf(" -j,--jobs J : Number of jobs (worker threads, default: 1. Use \"all\" to use all available cores)\n"); printf(" -o,--output FILENAME : Instead of using the last filename given as output, use this filename\n"); printf(" -l,--lossless : Set all defaults to encode losslessly, and emit warnings when settings/input don't allow for it\n"); printf(" -d,--depth D : Output depth [8,10,12]. (JPEG/PNG only; For y4m or stdin, depth is retained)\n"); @@ -487,9 +487,13 @@ goto cleanup; } else if (!strcmp(arg, "-j") || !strcmp(arg, "--jobs")) { NEXTARG(); - jobs = atoi(arg); - if (jobs < 1) { - jobs = 1; + if (!strcmp(arg, "all")) { + jobs = avifQueryMaxThreads(); + } else { + jobs = atoi(arg); + if (jobs < 1) { + jobs = 1; + } } } else if (!strcmp(arg, "--stdin")) { input.useStdin = AVIF_TRUE;
diff --git a/apps/shared/avifutil.c b/apps/shared/avifutil.c index e99d8f0..4ddc406 100644 --- a/apps/shared/avifutil.c +++ b/apps/shared/avifutil.c
@@ -220,3 +220,74 @@ printf("Diagnostics:\n"); printf(" * %s\n", diag->error); } + +// --------------------------------------------------------------------------- +// avifQueryMaxThreads (separated into OS implementations) + +#if defined(_WIN32) + +// Windows + +#pragma warning(disable : 5031) +#pragma warning(disable : 5032) +#include <windows.h> + +int avifQueryMaxThreads(void) +{ + int numCPU; + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + numCPU = sysinfo.dwNumberOfProcessors; + return numCPU; +} + +#elif defined(__APPLE__) + +// Apple + +#include <sys/sysctl.h> + +int avifQueryMaxThreads() +{ + int mib[4]; + int numCPU; + size_t len = sizeof(numCPU); + + /* set the mib for hw.ncpu */ + mib[0] = CTL_HW; + mib[1] = HW_AVAILCPU; // alternatively, try HW_NCPU; + + /* get the number of CPUs from the system */ + sysctl(mib, 2, &numCPU, &len, NULL, 0); + + if (numCPU < 1) { + mib[1] = HW_NCPU; + sysctl(mib, 2, &numCPU, &len, NULL, 0); + if (numCPU < 1) + numCPU = 1; + } + return numCPU; +} + +#elif defined(__EMSCRIPTEN__) + +// Emscripten + +int avifQueryMaxThreads() +{ + return 1; +} + +#else + +// POSIX + +#include <unistd.h> + +int avifQueryMaxThreads() +{ + int numCPU = (int)sysconf(_SC_NPROCESSORS_ONLN); + return (numCPU > 0) ? numCPU : 1; +} + +#endif
diff --git a/apps/shared/avifutil.h b/apps/shared/avifutil.h index 2c1ac01..2921cf6 100644 --- a/apps/shared/avifutil.h +++ b/apps/shared/avifutil.h
@@ -24,6 +24,7 @@ void avifContainerDump(avifDecoder * decoder); void avifPrintVersions(void); void avifDumpDiagnostics(const avifDiagnostics * diag); +int avifQueryMaxThreads(void); typedef enum avifAppFileFormat {