123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- /*
- * Copyright 2018-2020 Yury Gribov
- *
- * The MIT License (MIT)
- *
- * Use of this source code is governed by MIT license that can be
- * found in the LICENSE.txt file.
- */
- #include <dlfcn.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <assert.h>
- // Sanity check for ARM to avoid puzzling runtime crashes
- #ifdef __arm__
- # if defined __thumb__ && ! defined __THUMB_INTERWORK__
- # error "ARM trampolines need -mthumb-interwork to work in Thumb mode"
- # endif
- #endif
- #ifdef __cplusplus
- extern "C" {
- #endif
- #define CHECK(cond, fmt, ...) do { \
- if(!(cond)) { \
- fprintf(stderr, "implib-gen: libnvcuvid.so: " fmt "\n", ##__VA_ARGS__); \
- assert(0 && "Assertion in generated code"); \
- exit(1); \
- } \
- } while(0)
- #define CALL_USER_CALLBACK 0
- #define NO_DLOPEN False
- #define LAZY_LOAD 1
- static void *lib_handle;
- static int is_lib_loading;
- static void *load_library() {
- if(lib_handle)
- return lib_handle;
- is_lib_loading = 1;
- // TODO: dlopen and users callback must be protected w/ critical section (to avoid dlopening lib twice)
- #if NO_DLOPEN
- CHECK(0, "internal error"); // We shouldn't get here
- #elif CALL_USER_CALLBACK
- extern void *(const char *lib_name);
- lib_handle = ("libnvcuvid.so");
- CHECK(lib_handle, "callback '' failed to load library");
- #else
- lib_handle = dlopen("libnvcuvid.so", RTLD_LAZY | RTLD_GLOBAL);
- CHECK(lib_handle, "failed to load library: %s", dlerror());
- #endif
- is_lib_loading = 0;
- return lib_handle;
- }
- #if ! NO_DLOPEN && ! LAZY_LOAD
- static void __attribute__((constructor)) load_lib() {
- load_library();
- }
- #endif
- static void __attribute__((destructor)) unload_lib() {
- if(lib_handle)
- dlclose(lib_handle);
- }
- // TODO: convert to single 0-separated string
- static const char *const sym_names[] = {
- "__std_1U4S4U_X02",
- "__std_2U4S4U_X08",
- "__std_4U4S4U_X04",
- "cuvidConvertYUVToRGB",
- "cuvidConvertYUVToRGBArray",
- "cuvidCreateDecoder",
- "cuvidCreateVideoParser",
- "cuvidCreateVideoSource",
- "cuvidCreateVideoSourceW",
- "cuvidCtxLock",
- "cuvidCtxLockCreate",
- "cuvidCtxLockDestroy",
- "cuvidCtxUnlock",
- "cuvidDecodePicture",
- "cuvidDestroyDecoder",
- "cuvidDestroyVideoParser",
- "cuvidDestroyVideoSource",
- "cuvidGetDecodeStatus",
- "cuvidGetDecoderCaps",
- "cuvidGetSourceAudioFormat",
- "cuvidGetSourceVideoFormat",
- "cuvidGetVideoSourceState",
- "cuvidMapVideoFrame",
- "cuvidMapVideoFrame64",
- "cuvidParseVideoData",
- "cuvidPrivateOp",
- "cuvidReconfigureDecoder",
- "cuvidSetVideoSourceState",
- "cuvidUnmapVideoFrame",
- "cuvidUnmapVideoFrame64",
- 0
- };
- extern void *_libnvcuvid_so_tramp_table[];
- // Can be sped up by manually parsing library symtab...
- void _libnvcuvid_so_tramp_resolve(int i) {
- assert((unsigned)i + 1 < sizeof(sym_names) / sizeof(sym_names[0]));
- CHECK(!is_lib_loading, "library function '%s' called during library load", sym_names[i]);
- void *h = 0;
- #if NO_DLOPEN
- // FIXME: instead of RTLD_NEXT we should search for loaded lib_handle
- // as in https://github.com/jethrogb/ssltrace/blob/bf17c150a7/ssltrace.cpp#L74-L112
- h = RTLD_NEXT;
- #elif LAZY_LOAD
- h = load_library();
- #else
- h = lib_handle;
- CHECK(h, "failed to resolve symbol '%s', library failed to load", sym_names[i]);
- #endif
- // Dlsym is thread-safe so don't need to protect it.
- _libnvcuvid_so_tramp_table[i] = dlsym(h, sym_names[i]);
- CHECK(_libnvcuvid_so_tramp_table[i], "failed to resolve symbol '%s'", sym_names[i]);
- }
- // Helper for user to resolve all symbols
- void _libnvcuvid_so_tramp_resolve_all(void) {
- size_t i;
- for(i = 0; i + 1 < sizeof(sym_names) / sizeof(sym_names[0]); ++i)
- _libnvcuvid_so_tramp_resolve(i);
- }
- #ifdef __cplusplus
- } // extern "C"
- #endif
|