diff --git a/build/make/rtcd.sh b/build/make/rtcd.sh index 1dffde58a221df7925c06f07f721e45017ac17b9..2123aa1c55b0c887218dab47a232c6d60d1ce966 100755 --- a/build/make/rtcd.sh +++ b/build/make/rtcd.sh @@ -211,6 +211,8 @@ common_top() { $(process_forward_decls) $(declare_function_pointers c $ALL_ARCHS) + +void ${symbol:-rtcd}(void); EOF } @@ -231,11 +233,10 @@ x86() { cat <<EOF $(common_top) -void ${symbol:-rtcd}(void); #ifdef RTCD_C #include "vpx_ports/x86.h" -void ${symbol:-rtcd}(void) +static void setup_rtcd_internal(void) { int flags = x86_simd_caps(); @@ -261,11 +262,9 @@ arm() { $(common_top) #include "vpx_config.h" -void ${symbol:-rtcd}(void); - #ifdef RTCD_C #include "vpx_ports/arm.h" -void ${symbol:-rtcd}(void) +static void setup_rtcd_internal(void) { int flags = arm_cpu_caps(); @@ -285,10 +284,8 @@ unoptimized() { $(common_top) #include "vpx_config.h" -void ${symbol:-rtcd}(void); - #ifdef RTCD_C -void ${symbol:-rtcd}(void) +static void setup_rtcd_internal(void) { $(set_function_pointers c) } diff --git a/vp8/common/generic/systemdependent.c b/vp8/common/generic/systemdependent.c index 2a30166181ad523d42d73d41cba3aecd9b1d4698..5a6ac7b0e3a5d12729bc8341c735a0993741c30f 100644 --- a/vp8/common/generic/systemdependent.c +++ b/vp8/common/generic/systemdependent.c @@ -83,57 +83,6 @@ static int get_cpu_count() #endif -#if HAVE_PTHREAD_H -#include <pthread.h> -static void once(void (*func)(void)) -{ - static pthread_once_t lock = PTHREAD_ONCE_INIT; - pthread_once(&lock, func); -} - - -#elif defined(_WIN32) -static void once(void (*func)(void)) -{ - /* Using a static initializer here rather than InitializeCriticalSection() - * since there's no race-free context in which to execute it. Protecting - * it with an atomic op like InterlockedCompareExchangePointer introduces - * an x86 dependency, and InitOnceExecuteOnce requires Vista. - */ - static CRITICAL_SECTION lock = {(void *)-1, -1, 0, 0, 0, 0}; - static int done; - - EnterCriticalSection(&lock); - - if (!done) - { - func(); - done = 1; - } - - LeaveCriticalSection(&lock); -} - - -#else -/* No-op version that performs no synchronization. vpx_rtcd() is idempotent, - * so as long as your platform provides atomic loads/stores of pointers - * no synchronization is strictly necessary. - */ - -static void once(void (*func)(void)) -{ - static int done; - - if(!done) - { - func(); - done = 1; - } -} -#endif - - void vp8_machine_specific_config(VP8_COMMON *ctx) { #if CONFIG_MULTITHREAD @@ -145,6 +94,4 @@ void vp8_machine_specific_config(VP8_COMMON *ctx) #elif ARCH_X86 || ARCH_X86_64 ctx->cpu_caps = x86_simd_caps(); #endif - - once(vpx_rtcd); } diff --git a/vp8/common/rtcd.c b/vp8/common/rtcd.c index 232640dc87a3e5c8be6bf827d1cea794f5f22607..4980f48ad95d60edbe55cf1333133b7a50494788 100644 --- a/vp8/common/rtcd.c +++ b/vp8/common/rtcd.c @@ -10,3 +10,60 @@ #include "vpx_config.h" #define RTCD_C #include "vpx_rtcd.h" + +#if CONFIG_MULTITHREAD && HAVE_PTHREAD_H +#include <pthread.h> +static void once(void (*func)(void)) +{ + static pthread_once_t lock = PTHREAD_ONCE_INIT; + pthread_once(&lock, func); +} + + +#elif CONFIG_MULTITHREAD && defined(_WIN32) +#include <windows.h> +static void once(void (*func)(void)) +{ + /* Using a static initializer here rather than InitializeCriticalSection() + * since there's no race-free context in which to execute it. Protecting + * it with an atomic op like InterlockedCompareExchangePointer introduces + * an x86 dependency, and InitOnceExecuteOnce requires Vista. + */ + static CRITICAL_SECTION lock = {(void *)-1, -1, 0, 0, 0, 0}; + static int done; + + EnterCriticalSection(&lock); + + if (!done) + { + func(); + done = 1; + } + + LeaveCriticalSection(&lock); +} + + +#else +/* No-op version that performs no synchronization. vpx_rtcd() is idempotent, + * so as long as your platform provides atomic loads/stores of pointers + * no synchronization is strictly necessary. + */ + +static void once(void (*func)(void)) +{ + static int done; + + if(!done) + { + func(); + done = 1; + } +} +#endif + + +void vpx_rtcd() +{ + once(setup_rtcd_internal); +} diff --git a/vp8/vp8_cx_iface.c b/vp8/vp8_cx_iface.c index 967110768247fade45556821680fe1f803007224..a499825fd90c51247b934dbb58941de272eb5f54 100644 --- a/vp8/vp8_cx_iface.c +++ b/vp8/vp8_cx_iface.c @@ -9,6 +9,7 @@ */ +#include "vpx_rtcd.h" #include "vpx/vpx_codec.h" #include "vpx/internal/vpx_codec_internal.h" #include "vpx_version.h" @@ -572,6 +573,8 @@ static vpx_codec_err_t vp8e_init(vpx_codec_ctx_t *ctx, struct VP8_COMP *optr; + vpx_rtcd(); + if (!ctx->priv) { priv = calloc(1, sizeof(struct vpx_codec_alg_priv)); diff --git a/vp8/vp8_dx_iface.c b/vp8/vp8_dx_iface.c index 37773dba5e19dd187080b5188e001249eb17df1e..fe8c9a0c0bfd8834d19356f8995024726c888824 100644 --- a/vp8/vp8_dx_iface.c +++ b/vp8/vp8_dx_iface.c @@ -11,6 +11,7 @@ #include <stdlib.h> #include <string.h> +#include "vpx_rtcd.h" #include "vpx/vpx_decoder.h" #include "vpx/vp8dx.h" #include "vpx/internal/vpx_codec_internal.h" @@ -187,6 +188,8 @@ static vpx_codec_err_t vp8_init(vpx_codec_ctx_t *ctx, vpx_codec_err_t res = VPX_CODEC_OK; (void) data; + vpx_rtcd(); + /* This function only allocates space for the vpx_codec_alg_priv_t * structure. More memory may be required at the time the stream * information becomes known. diff --git a/vpx/vpx_decoder.h b/vpx/vpx_decoder.h index 7992cc4fcc85435dd856a34d5ff12ae270b51179..1ccf1c5d3ab5cf64ad425c74abd2f2641520d066 100644 --- a/vpx/vpx_decoder.h +++ b/vpx/vpx_decoder.h @@ -113,6 +113,10 @@ extern "C" { * function directly, to ensure that the ABI version number parameter * is properly initialized. * + * If the library was configured with --disable-multithread, this call + * is not thread safe and should be guarded with a lock if being used + * in a multithreaded context. + * * In XMA mode (activated by setting VPX_CODEC_USE_XMA in the flags * parameter), the storage pointed to by the cfg parameter must be * kept readable and stable until all memory maps have been set. diff --git a/vpx/vpx_encoder.h b/vpx/vpx_encoder.h index 239036edb5f8340431337bbece434d0106e10741..67d9033331d872b77e9be9767b80d9f37b90a639 100644 --- a/vpx/vpx_encoder.h +++ b/vpx/vpx_encoder.h @@ -655,6 +655,10 @@ extern "C" { * function directly, to ensure that the ABI version number parameter * is properly initialized. * + * If the library was configured with --disable-multithread, this call + * is not thread safe and should be guarded with a lock if being used + * in a multithreaded context. + * * In XMA mode (activated by setting VPX_CODEC_USE_XMA in the flags * parameter), the storage pointed to by the cfg parameter must be * kept readable and stable until all memory maps have been set.