OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #ifndef WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_OPENSLES_PLAYER_H_ | 11 #ifndef WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_OPENSLES_PLAYER_H_ |
12 #define WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_OPENSLES_PLAYER_H_ | 12 #define WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_OPENSLES_PLAYER_H_ |
13 | 13 |
14 #include <memory> | |
15 | |
16 #include <SLES/OpenSLES.h> | 14 #include <SLES/OpenSLES.h> |
17 #include <SLES/OpenSLES_Android.h> | 15 #include <SLES/OpenSLES_Android.h> |
18 #include <SLES/OpenSLES_AndroidConfiguration.h> | 16 #include <SLES/OpenSLES_AndroidConfiguration.h> |
19 | 17 |
20 #include "webrtc/base/thread_checker.h" | 18 #include "webrtc/base/thread_checker.h" |
21 #include "webrtc/modules/audio_device/android/audio_common.h" | 19 #include "webrtc/modules/audio_device/android/audio_common.h" |
22 #include "webrtc/modules/audio_device/android/audio_manager.h" | 20 #include "webrtc/modules/audio_device/android/audio_manager.h" |
23 #include "webrtc/modules/audio_device/android/opensles_common.h" | 21 #include "webrtc/modules/audio_device/android/opensles_common.h" |
24 #include "webrtc/modules/audio_device/include/audio_device_defines.h" | 22 #include "webrtc/modules/audio_device/include/audio_device_defines.h" |
25 #include "webrtc/modules/audio_device/audio_device_generic.h" | 23 #include "webrtc/modules/audio_device/audio_device_generic.h" |
(...skipping 16 matching lines...) Expand all Loading... |
42 // to be able to call StartPlayout() again. This is inline with how the Java- | 40 // to be able to call StartPlayout() again. This is inline with how the Java- |
43 // based implementation works. | 41 // based implementation works. |
44 // | 42 // |
45 // OpenSL ES is a native C API which have no Dalvik-related overhead such as | 43 // OpenSL ES is a native C API which have no Dalvik-related overhead such as |
46 // garbage collection pauses and it supports reduced audio output latency. | 44 // garbage collection pauses and it supports reduced audio output latency. |
47 // If the device doesn't claim this feature but supports API level 9 (Android | 45 // If the device doesn't claim this feature but supports API level 9 (Android |
48 // platform version 2.3) or later, then we can still use the OpenSL ES APIs but | 46 // platform version 2.3) or later, then we can still use the OpenSL ES APIs but |
49 // the output latency may be higher. | 47 // the output latency may be higher. |
50 class OpenSLESPlayer { | 48 class OpenSLESPlayer { |
51 public: | 49 public: |
52 // The lower output latency path is used only if the application requests a | 50 // Beginning with API level 17 (Android 4.2), a buffer count of 2 or more is |
53 // buffer count of 2 or more, and a buffer size and sample rate that are | 51 // required for lower latency. Beginning with API level 18 (Android 4.3), a |
54 // compatible with the device's native output configuration provided via the | 52 // buffer count of 1 is sufficient for lower latency. In addition, the buffer |
55 // audio manager at construction. | 53 // size and sample rate must be compatible with the device's native output |
56 static const int kNumOfOpenSLESBuffers = 4; | 54 // configuration provided via the audio manager at construction. |
| 55 // TODO(henrika): perhaps set this value dynamically based on OS version. |
| 56 static const int kNumOfOpenSLESBuffers = 2; |
57 | 57 |
58 explicit OpenSLESPlayer(AudioManager* audio_manager); | 58 explicit OpenSLESPlayer(AudioManager* audio_manager); |
59 ~OpenSLESPlayer(); | 59 ~OpenSLESPlayer(); |
60 | 60 |
61 int Init(); | 61 int Init(); |
62 int Terminate(); | 62 int Terminate(); |
63 | 63 |
64 int InitPlayout(); | 64 int InitPlayout(); |
65 bool PlayoutIsInitialized() const { return initialized_; } | 65 bool PlayoutIsInitialized() const { return initialized_; } |
66 | 66 |
(...skipping 14 matching lines...) Expand all Loading... |
81 // They are both called from an internal "OpenSL ES thread" which is not | 81 // They are both called from an internal "OpenSL ES thread" which is not |
82 // attached to the Dalvik VM. | 82 // attached to the Dalvik VM. |
83 static void SimpleBufferQueueCallback(SLAndroidSimpleBufferQueueItf caller, | 83 static void SimpleBufferQueueCallback(SLAndroidSimpleBufferQueueItf caller, |
84 void* context); | 84 void* context); |
85 void FillBufferQueue(); | 85 void FillBufferQueue(); |
86 // Reads audio data in PCM format using the AudioDeviceBuffer. | 86 // Reads audio data in PCM format using the AudioDeviceBuffer. |
87 // Can be called both on the main thread (during Start()) and from the | 87 // Can be called both on the main thread (during Start()) and from the |
88 // internal audio thread while output streaming is active. | 88 // internal audio thread while output streaming is active. |
89 void EnqueuePlayoutData(); | 89 void EnqueuePlayoutData(); |
90 | 90 |
91 // Configures the SL_DATAFORMAT_PCM structure. | |
92 SLDataFormat_PCM CreatePCMConfiguration(size_t channels, | |
93 int sample_rate, | |
94 size_t bits_per_sample); | |
95 | |
96 // Allocate memory for audio buffers which will be used to render audio | 91 // Allocate memory for audio buffers which will be used to render audio |
97 // via the SLAndroidSimpleBufferQueueItf interface. | 92 // via the SLAndroidSimpleBufferQueueItf interface. |
98 void AllocateDataBuffers(); | 93 void AllocateDataBuffers(); |
99 | 94 |
100 // Obtaines the SL Engine Interface from the existing global Engine object. | 95 // Obtaines the SL Engine Interface from the existing global Engine object. |
101 // The interface exposes creation methods of all the OpenSL ES object types. | 96 // The interface exposes creation methods of all the OpenSL ES object types. |
102 // This method defines the |engine_| member variable. | 97 // This method defines the |engine_| member variable. |
103 bool ObtainEngineInterface(); | 98 bool ObtainEngineInterface(); |
104 | 99 |
105 // Creates/destroys the output mix object. | 100 // Creates/destroys the output mix object. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 AudioDeviceBuffer* audio_device_buffer_; | 132 AudioDeviceBuffer* audio_device_buffer_; |
138 | 133 |
139 bool initialized_; | 134 bool initialized_; |
140 bool playing_; | 135 bool playing_; |
141 | 136 |
142 // PCM-type format definition. | 137 // PCM-type format definition. |
143 // TODO(henrika): add support for SLAndroidDataFormat_PCM_EX (android-21) if | 138 // TODO(henrika): add support for SLAndroidDataFormat_PCM_EX (android-21) if |
144 // 32-bit float representation is needed. | 139 // 32-bit float representation is needed. |
145 SLDataFormat_PCM pcm_format_; | 140 SLDataFormat_PCM pcm_format_; |
146 | 141 |
147 // Number of bytes per audio buffer in each |audio_buffers_[i]|. | |
148 // Typical sizes are 480 or 512 bytes corresponding to native output buffer | |
149 // sizes of 240 or 256 audio frames respectively. | |
150 size_t bytes_per_buffer_; | |
151 | |
152 // Queue of audio buffers to be used by the player object for rendering | 142 // Queue of audio buffers to be used by the player object for rendering |
153 // audio. They will be used in a Round-robin way and the size of each buffer | 143 // audio. They will be used in a Round-robin way and the size of each buffer |
154 // is given by FineAudioBuffer::RequiredBufferSizeBytes(). | 144 // is given by FineAudioBuffer::RequiredBufferSizeBytes(). |
155 std::unique_ptr<SLint8[]> audio_buffers_[kNumOfOpenSLESBuffers]; | 145 std::unique_ptr<SLint8[]> audio_buffers_[kNumOfOpenSLESBuffers]; |
156 | 146 |
157 // FineAudioBuffer takes an AudioDeviceBuffer which delivers audio data | 147 // FineAudioBuffer takes an AudioDeviceBuffer which delivers audio data |
158 // in chunks of 10ms. It then allows for this data to be pulled in | 148 // in chunks of 10ms. It then allows for this data to be pulled in |
159 // a finer or coarser granularity. I.e. interacting with this class instead | 149 // a finer or coarser granularity. I.e. interacting with this class instead |
160 // of directly with the AudioDeviceBuffer one can ask for any number of | 150 // of directly with the AudioDeviceBuffer one can ask for any number of |
161 // audio data samples. | 151 // audio data samples. |
162 // Example: native buffer size is 240 audio frames at 48kHz sample rate. | 152 // Example: native buffer size can be 192 audio frames at 48kHz sample rate. |
163 // WebRTC will provide 480 audio frames per 10ms but OpenSL ES asks for 240 | 153 // WebRTC will provide 480 audio frames per 10ms but OpenSL ES asks for 192 |
164 // in each callback (one every 5ms). This class can then ask for 240 and the | 154 // in each callback (one every 4th ms). This class can then ask for 192 and |
165 // FineAudioBuffer will ask WebRTC for new data only every second callback | 155 // the FineAudioBuffer will ask WebRTC for new data approximately only every |
166 // and also cach non-utilized audio. | 156 // second callback and also cache non-utilized audio. |
167 std::unique_ptr<FineAudioBuffer> fine_buffer_; | 157 std::unique_ptr<FineAudioBuffer> fine_audio_buffer_; |
168 | 158 |
169 // Keeps track of active audio buffer 'n' in the audio_buffers_[n] queue. | 159 // Keeps track of active audio buffer 'n' in the audio_buffers_[n] queue. |
170 // Example (kNumOfOpenSLESBuffers = 2): counts 0, 1, 0, 1, ... | 160 // Example (kNumOfOpenSLESBuffers = 2): counts 0, 1, 0, 1, ... |
171 int buffer_index_; | 161 int buffer_index_; |
172 | 162 |
173 // This interface exposes creation methods for all the OpenSL ES object types. | 163 // This interface exposes creation methods for all the OpenSL ES object types. |
174 // It is the OpenSL ES API entry point. | 164 // It is the OpenSL ES API entry point. |
175 SLEngineItf engine_; | 165 SLEngineItf engine_; |
176 | 166 |
177 // Output mix object to be used by the player object. | 167 // Output mix object to be used by the player object. |
(...skipping 16 matching lines...) Expand all Loading... |
194 // properties. This interface is supported on the Audio Player object. | 184 // properties. This interface is supported on the Audio Player object. |
195 SLVolumeItf volume_; | 185 SLVolumeItf volume_; |
196 | 186 |
197 // Last time the OpenSL ES layer asked for audio data to play out. | 187 // Last time the OpenSL ES layer asked for audio data to play out. |
198 uint32_t last_play_time_; | 188 uint32_t last_play_time_; |
199 }; | 189 }; |
200 | 190 |
201 } // namespace webrtc | 191 } // namespace webrtc |
202 | 192 |
203 #endif // WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_OPENSLES_PLAYER_H_ | 193 #endif // WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_OPENSLES_PLAYER_H_ |
OLD | NEW |