2 proposal of enhancement for multilib exe/dll
Now there is possible to make one big multilib DLL, but x265.exe can't handle such DLL. So the first proposition:
*** api.cpp.org Wed Jul 8 02:31:02 2015
--- api.cpp Wed Jul 8 22:06:25 2015
***************
*** 366,376 ****
#if _WIN32
HMODULE h = LoadLibraryA(libname);
if (h)
{
api_get_func get = (api_get_func)GetProcAddress(h, method);
if (get)
! api = get(0);
}
#else
void* h = dlopen(libname, RTLD_LAZY | RTLD_LOCAL);
--- 366,381 ----
#if _WIN32
HMODULE h = LoadLibraryA(libname);
+ if (h == NULL)
+ {
+ libname = "libx265" ext;
+ h = LoadLibraryA(libname);
+ }
if (h)
{
api_get_func get = (api_get_func)GetProcAddress(h, method);
if (get)
! api = get(bitDepth);
}
#else
void* h = dlopen(libname, RTLD_LAZY | RTLD_LOCAL);
***************
*** 437,442 ****
--- 442,452 ----
#if _WIN32
HMODULE h = LoadLibraryA(libname);
+ if (h == NULL)
+ {
+ libname = "libx265" ext;
+ h = LoadLibraryA(libname);
+ }
if (h)
{
e = X265_API_QUERY_ERR_FUNC_NOT_FOUND;
If the attempt to load "libx265_mainX.dll" fails, we can try with "libx265.dll" + specify exactly bit-depth what we want: api = get(bitDepth);
Second proposal: if we use multilib EXE we have default 8-bit encoding, but we can use 10-bit EXE + multilib DLL and we have default 10-bit encoding. So there are options sets that are valid for one model and wrong for another (and with this both cases we can encode with any bit depth). My proposition is to try to switch to required bit-depth if the user set --profile|-P option:
*** x265.cpp.org Wed Jul 8 02:33:24 2015
--- x265.cpp Wed Jul 8 02:50:01 2015
***************
*** 376,381 ****
--- 376,398 ----
tune = optarg;
else if (c == 'D')
outputBitDepth = atoi(optarg);
+ else if (c == 'P')
+ {
+ profile = optarg;
+ if (!outputBitDepth)
+ {
+ if (!strcmp(profile, "main") || !strcmp(profile, "mainstillpicture") || !strcmp(profile, "msp") ||
+ !strcmp(profile, "main444-8") || !strcmp(profile, "main-intra") ||
+ !strcmp(profile, "main444-intra") || !strcmp(profile, "main444-stillpicture"))
+ outputBitDepth = 8;
+ else if (!strcmp(profile, "main10") || !strcmp(profile, "main422-10") || !strcmp(profile, "main444-10") ||
+ !strcmp(profile, "main10-intra") || !strcmp(profile, "main422-10-intra") || !strcmp(profile, "main444-10-intra"))
+ outputBitDepth = 10;
+ else if (!strcmp(profile, "main12") || !strcmp(profile, "main422-12") || !strcmp(profile, "main444-12") ||
+ !strcmp(profile, "main12-intra") || !strcmp(profile, "main422-12-intra") || !strcmp(profile, "main444-12-intra"))
+ outputBitDepth = 12;
+ }
+ }
else if (c == '?')
bShowHelp = true;
}
***************
*** 471,477 ****
OPT("dither") this->bDither = true;
OPT("recon-depth") reconFileBitDepth = (uint32_t)x265_atoi(optarg, bError);
OPT("y4m") this->bForceY4m = true;
! OPT("profile") profile = optarg; /* handled last */
OPT("preset") /* handled above */;
OPT("tune") /* handled above */;
OPT("output-depth") /* handled above */;
--- 488,494 ----
OPT("dither") this->bDither = true;
OPT("recon-depth") reconFileBitDepth = (uint32_t)x265_atoi(optarg, bError);
OPT("y4m") this->bForceY4m = true;
! OPT("profile") /* handled above */;
OPT("preset") /* handled above */;
OPT("tune") /* handled above */;
OPT("output-depth") /* handled above */;
Comments (6)
-
-
api: fallback to multilib library if profile-named library not found (refs
#156)If you call x265_api_get(10) and libx265_main10.dll is not found, it will now fallback to trying to bind libx265.dll and request bitDepth 10 from that library (in the hope that it is a multilib library supporting all bit depths)
→ <<cset 13b2356290d6>>
-
reporter Thanks!
-
reporter Unfortunately x265_api_query and x265_api_get are wrong. Consider libx265.dll with only 8-bit encoder inside and x265.exe with only 8-bit encoder inside. Command x265 -D10 -V hangs x265.
My solution:
diff -r 996ebce8c874 source/encoder/api.cpp --- a/source/encoder/api.cpp Mon Aug 17 10:52:15 2015 +0530 +++ b/source/encoder/api.cpp Mon Aug 17 19:56:17 2015 +0200 @@ -365,36 +365,43 @@ return NULL; const x265_api* api = NULL; - int reqDepth = 0; + static int Recursion; + + if (Recursion) + return NULL; + + Recursion = 1; #if _WIN32 HMODULE h = LoadLibraryA(libname); if (!h) { - h = LoadLibraryA(multilibname); - reqDepth = bitDepth; + libname = multilibname; + h = LoadLibraryA(libname); } if (h) { api_get_func get = (api_get_func)GetProcAddress(h, method); if (get) - api = get(reqDepth); + api = get(bitDepth); } #else void* h = dlopen(libname, RTLD_LAZY | RTLD_LOCAL); if (!h) { - h = dlopen(multilibname, RTLD_LAZY | RTLD_LOCAL); - reqDepth = bitDepth; + libname = multilibname; + h = dlopen(libname, RTLD_LAZY | RTLD_LOCAL); } if (h) { api_get_func get = (api_get_func)dlsym(h, method); if (get) - api = get(reqDepth); + api = get(bitDepth); } #endif + Recursion = 0; + if (api && bitDepth != api->bit_depth) { x265_log(NULL, X265_LOG_WARNING, "%s does not support requested bitDepth %d\n", libname, bitDepth); @@ -447,39 +454,49 @@ } const x265_api* api = NULL; - int reqDepth = 0; int e = X265_API_QUERY_ERR_LIB_NOT_FOUND; + static int Recursion; + + if (Recursion) + { + if (err) *err = X265_API_QUERY_ERR_WRONG_BITDEPTH; + return NULL; + } + + Recursion = 1; #if _WIN32 HMODULE h = LoadLibraryA(libname); if (!h) { - h = LoadLibraryA(multilibname); - reqDepth = bitDepth; + libname = multilibname; + h = LoadLibraryA(libname); } if (h) { e = X265_API_QUERY_ERR_FUNC_NOT_FOUND; api_query_func query = (api_query_func)GetProcAddress(h, method); if (query) - api = query(reqDepth, apiVersion, err); + api = query(bitDepth, apiVersion, err); } #else void* h = dlopen(libname, RTLD_LAZY | RTLD_LOCAL); if (!h) { - h = dlopen(multilibname, RTLD_LAZY | RTLD_LOCAL); - reqDepth = bitDepth; + libname = multilibname; + h = dlopen(libname, RTLD_LAZY | RTLD_LOCAL); } if (h) { e = X265_API_QUERY_ERR_FUNC_NOT_FOUND; api_query_func query = (api_query_func)dlsym(h, method); if (query) - api = query(reqDepth, apiVersion, err); + api = query(bitDepth, apiVersion, err); } #endif + Recursion = 0; + if (api && bitDepth != api->bit_depth) { x265_log(NULL, X265_LOG_WARNING, "%s does not support requested bitDepth %d\n", libname, bitDepth);
-
api: prevent recursion in libx265.dll fallback (refs
#156)If libx265.dll did not contain a requested bitdepth, it would result in infinite recursion. So we use a global int to break the recursion
→ <<cset b99b4940c063>>
-
- changed status to closed
cli: derive output bit depth from --profile if --output-depth is not specified
Closes
#156.→ <<cset 8b000a007573>>
- Log in to comment
I'm not sure I see the point of supporting multilib DLLs when you can just as easily make a multilib executable (an x265.exe that supports all bit depths). On Windows the EXE must statically link to libx265 so at least one bit depth of libx265 is being linked into the EXE. Why not link them all?
we had a discussion about using --profile to select the bit depth but in the end decided to add an explicit -D|--output-depth argument. This was thought to be more consistent with the way x265 is used by ffmpeg, and has the least surprise.