Line data Source code
1 : /*
2 : * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 : *
4 : * Use of this source code is governed by a BSD-style license
5 : * that can be found in the LICENSE file in the root of the source
6 : * tree. An additional intellectual property rights grant can be found
7 : * in the file PATENTS. All contributing project authors may
8 : * be found in the AUTHORS file in the root of the source tree.
9 : */
10 :
11 : /* The global function contained in this file initializes SPL function
12 : * pointers, currently only for ARM platforms.
13 : *
14 : * Some code came from common/rtcd.c in the WebM project.
15 : */
16 :
17 : #include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
18 : #include "webrtc/system_wrappers/include/cpu_features_wrapper.h"
19 :
20 : /* Declare function pointers. */
21 : MaxAbsValueW16 WebRtcSpl_MaxAbsValueW16;
22 : MaxAbsValueW32 WebRtcSpl_MaxAbsValueW32;
23 : MaxValueW16 WebRtcSpl_MaxValueW16;
24 : MaxValueW32 WebRtcSpl_MaxValueW32;
25 : MinValueW16 WebRtcSpl_MinValueW16;
26 : MinValueW32 WebRtcSpl_MinValueW32;
27 : CrossCorrelation WebRtcSpl_CrossCorrelation;
28 : DownsampleFast WebRtcSpl_DownsampleFast;
29 : ScaleAndAddVectorsWithRound WebRtcSpl_ScaleAndAddVectorsWithRound;
30 :
31 : #if (!defined(WEBRTC_HAS_NEON)) && !defined(MIPS32_LE)
32 : /* Initialize function pointers to the generic C version. */
33 0 : static void InitPointersToC() {
34 0 : WebRtcSpl_MaxAbsValueW16 = WebRtcSpl_MaxAbsValueW16C;
35 0 : WebRtcSpl_MaxAbsValueW32 = WebRtcSpl_MaxAbsValueW32C;
36 0 : WebRtcSpl_MaxValueW16 = WebRtcSpl_MaxValueW16C;
37 0 : WebRtcSpl_MaxValueW32 = WebRtcSpl_MaxValueW32C;
38 0 : WebRtcSpl_MinValueW16 = WebRtcSpl_MinValueW16C;
39 0 : WebRtcSpl_MinValueW32 = WebRtcSpl_MinValueW32C;
40 0 : WebRtcSpl_CrossCorrelation = WebRtcSpl_CrossCorrelationC;
41 0 : WebRtcSpl_DownsampleFast = WebRtcSpl_DownsampleFastC;
42 0 : WebRtcSpl_ScaleAndAddVectorsWithRound =
43 : WebRtcSpl_ScaleAndAddVectorsWithRoundC;
44 0 : }
45 : #endif
46 :
47 : #if defined(WEBRTC_HAS_NEON)
48 : /* Initialize function pointers to the Neon version. */
49 : static void InitPointersToNeon() {
50 : WebRtcSpl_MaxAbsValueW16 = WebRtcSpl_MaxAbsValueW16Neon;
51 : WebRtcSpl_MaxAbsValueW32 = WebRtcSpl_MaxAbsValueW32Neon;
52 : WebRtcSpl_MaxValueW16 = WebRtcSpl_MaxValueW16Neon;
53 : WebRtcSpl_MaxValueW32 = WebRtcSpl_MaxValueW32Neon;
54 : WebRtcSpl_MinValueW16 = WebRtcSpl_MinValueW16Neon;
55 : WebRtcSpl_MinValueW32 = WebRtcSpl_MinValueW32Neon;
56 : WebRtcSpl_CrossCorrelation = WebRtcSpl_CrossCorrelationNeon;
57 : WebRtcSpl_DownsampleFast = WebRtcSpl_DownsampleFastNeon;
58 : WebRtcSpl_ScaleAndAddVectorsWithRound =
59 : WebRtcSpl_ScaleAndAddVectorsWithRoundC;
60 : }
61 : #endif
62 :
63 : #if defined(MIPS32_LE)
64 : /* Initialize function pointers to the MIPS version. */
65 : static void InitPointersToMIPS() {
66 : WebRtcSpl_MaxAbsValueW16 = WebRtcSpl_MaxAbsValueW16_mips;
67 : WebRtcSpl_MaxValueW16 = WebRtcSpl_MaxValueW16_mips;
68 : WebRtcSpl_MaxValueW32 = WebRtcSpl_MaxValueW32_mips;
69 : WebRtcSpl_MinValueW16 = WebRtcSpl_MinValueW16_mips;
70 : WebRtcSpl_MinValueW32 = WebRtcSpl_MinValueW32_mips;
71 : WebRtcSpl_CrossCorrelation = WebRtcSpl_CrossCorrelation_mips;
72 : WebRtcSpl_DownsampleFast = WebRtcSpl_DownsampleFast_mips;
73 : #if defined(MIPS_DSP_R1_LE)
74 : WebRtcSpl_MaxAbsValueW32 = WebRtcSpl_MaxAbsValueW32_mips;
75 : WebRtcSpl_ScaleAndAddVectorsWithRound =
76 : WebRtcSpl_ScaleAndAddVectorsWithRound_mips;
77 : #else
78 : WebRtcSpl_MaxAbsValueW32 = WebRtcSpl_MaxAbsValueW32C;
79 : WebRtcSpl_ScaleAndAddVectorsWithRound =
80 : WebRtcSpl_ScaleAndAddVectorsWithRoundC;
81 : #endif
82 : }
83 : #endif
84 :
85 0 : static void InitFunctionPointers(void) {
86 : #if defined(WEBRTC_HAS_NEON)
87 : InitPointersToNeon();
88 : #elif defined(MIPS32_LE)
89 : InitPointersToMIPS();
90 : #else
91 0 : InitPointersToC();
92 : #endif /* WEBRTC_HAS_NEON */
93 0 : }
94 :
95 : #if defined(WEBRTC_POSIX)
96 : #include <pthread.h>
97 :
98 0 : static void once(void (*func)(void)) {
99 : static pthread_once_t lock = PTHREAD_ONCE_INIT;
100 0 : pthread_once(&lock, func);
101 0 : }
102 :
103 : #elif defined(_WIN32)
104 : #include <windows.h>
105 :
106 : static void once(void (*func)(void)) {
107 : /* Didn't use InitializeCriticalSection() since there's no race-free context
108 : * in which to execute it.
109 : *
110 : * TODO(kma): Change to different implementation (e.g.
111 : * InterlockedCompareExchangePointer) to avoid issues similar to
112 : * http://code.google.com/p/webm/issues/detail?id=467.
113 : */
114 : static CRITICAL_SECTION lock = {(void *)((size_t)-1), -1, 0, 0, 0, 0};
115 : static int done = 0;
116 :
117 : EnterCriticalSection(&lock);
118 : if (!done) {
119 : func();
120 : done = 1;
121 : }
122 : LeaveCriticalSection(&lock);
123 : }
124 :
125 : /* There's no fallback version as an #else block here to ensure thread safety.
126 : * In case of neither pthread for WEBRTC_POSIX nor _WIN32 is present, build
127 : * system should pick it up.
128 : */
129 : #endif /* WEBRTC_POSIX */
130 :
131 0 : void WebRtcSpl_Init() {
132 0 : once(InitFunctionPointers);
133 0 : }
|