Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Side by Side Diff: media/audio/android/audio_manager_android.cc

Issue 110173003: Refactor audio manager for Android to avoid heavy tasks at startup (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: nits Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/audio/android/audio_manager_android.h" 5 #include "media/audio/android/audio_manager_android.h"
6 6
7 #include "base/android/build_info.h" 7 #include "base/android/build_info.h"
8 #include "base/android/jni_array.h" 8 #include "base/android/jni_array.h"
9 #include "base/android/jni_string.h" 9 #include "base/android/jni_string.h"
10 #include "base/android/scoped_java_ref.h" 10 #include "base/android/scoped_java_ref.h"
(...skipping 18 matching lines...) Expand all
29 static void AddDefaultDevice(AudioDeviceNames* device_names) { 29 static void AddDefaultDevice(AudioDeviceNames* device_names) {
30 DCHECK(device_names->empty()); 30 DCHECK(device_names->empty());
31 device_names->push_front( 31 device_names->push_front(
32 AudioDeviceName(AudioManagerBase::kDefaultDeviceName, 32 AudioDeviceName(AudioManagerBase::kDefaultDeviceName,
33 AudioManagerBase::kDefaultDeviceId)); 33 AudioManagerBase::kDefaultDeviceId));
34 } 34 }
35 35
36 // Maximum number of output streams that can be open simultaneously. 36 // Maximum number of output streams that can be open simultaneously.
37 static const int kMaxOutputStreams = 10; 37 static const int kMaxOutputStreams = 10;
38 38
39 static const int kAudioModeNormal = 0x00000000;
40 static const int kAudioModeInCommunication = 0x00000003;
41
42 static const int kDefaultInputBufferSize = 1024; 39 static const int kDefaultInputBufferSize = 1024;
43 static const int kDefaultOutputBufferSize = 2048; 40 static const int kDefaultOutputBufferSize = 2048;
44 41
45 AudioManager* CreateAudioManager(AudioLogFactory* audio_log_factory) { 42 AudioManager* CreateAudioManager(AudioLogFactory* audio_log_factory) {
46 return new AudioManagerAndroid(audio_log_factory); 43 return new AudioManagerAndroid(audio_log_factory);
47 } 44 }
48 45
49 AudioManagerAndroid::AudioManagerAndroid(AudioLogFactory* audio_log_factory) 46 AudioManagerAndroid::AudioManagerAndroid(AudioLogFactory* audio_log_factory)
50 : AudioManagerBase(audio_log_factory) { 47 : AudioManagerBase(audio_log_factory) {
51 SetMaxOutputStreamsAllowed(kMaxOutputStreams); 48 SetMaxOutputStreamsAllowed(kMaxOutputStreams);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 return AudioParameters( 111 return AudioParameters(
115 AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, 112 AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout,
116 GetNativeOutputSampleRate(), 16, 113 GetNativeOutputSampleRate(), 16,
117 buffer_size <= 0 ? kDefaultInputBufferSize : buffer_size); 114 buffer_size <= 0 ? kDefaultInputBufferSize : buffer_size);
118 } 115 }
119 116
120 AudioOutputStream* AudioManagerAndroid::MakeAudioOutputStream( 117 AudioOutputStream* AudioManagerAndroid::MakeAudioOutputStream(
121 const AudioParameters& params, 118 const AudioParameters& params,
122 const std::string& device_id, 119 const std::string& device_id,
123 const std::string& input_device_id) { 120 const std::string& input_device_id) {
121 bool has_no_streams = HasNoAudioStreams();
124 AudioOutputStream* stream = 122 AudioOutputStream* stream =
125 AudioManagerBase::MakeAudioOutputStream(params, std::string(), 123 AudioManagerBase::MakeAudioOutputStream(params, std::string(),
126 std::string()); 124 std::string());
127 if (stream && output_stream_count() == 1) { 125
128 SetAudioMode(kAudioModeInCommunication); 126 // The audio manager for Android creates streams intended for real-time
127 // VoIP sessions and therefore sets the audio mode to MODE_IN_COMMUNICATION.
128 // If a Bluetooth headset is used, the audio stream will use the SCO
129 // channel and therefore have a limited bandwidth (8-16kHz).
130 if (stream && has_no_streams) {
131 SetCommunicationAudioModeOn(true);
129 } 132 }
130 133
131 { 134 {
132 base::AutoLock lock(streams_lock_); 135 base::AutoLock lock(streams_lock_);
133 streams_.insert(static_cast<OpenSLESOutputStream*>(stream)); 136 streams_.insert(static_cast<OpenSLESOutputStream*>(stream));
134 } 137 }
135 138
136 return stream; 139 return stream;
137 } 140 }
138 141
139 AudioInputStream* AudioManagerAndroid::MakeAudioInputStream( 142 AudioInputStream* AudioManagerAndroid::MakeAudioInputStream(
140 const AudioParameters& params, const std::string& device_id) { 143 const AudioParameters& params, const std::string& device_id) {
144 bool has_no_streams = HasNoAudioStreams();
141 AudioInputStream* stream = 145 AudioInputStream* stream =
142 AudioManagerBase::MakeAudioInputStream(params, device_id); 146 AudioManagerBase::MakeAudioInputStream(params, device_id);
147
148 // The audio manager for Android creates streams intended for real-time
149 // VoIP sessions and therefore sets the audio mode to MODE_IN_COMMUNICATION.
150 // If a Bluetooth headset is used, the audio stream will use the SCO
151 // channel and therefore have a limited bandwidth (8kHz).
152 if (stream && has_no_streams) {
153 SetCommunicationAudioModeOn(true);
154 }
143 return stream; 155 return stream;
144 } 156 }
145 157
146 void AudioManagerAndroid::ReleaseOutputStream(AudioOutputStream* stream) { 158 void AudioManagerAndroid::ReleaseOutputStream(AudioOutputStream* stream) {
147 AudioManagerBase::ReleaseOutputStream(stream); 159 AudioManagerBase::ReleaseOutputStream(stream);
148 if (!output_stream_count()) { 160
149 SetAudioMode(kAudioModeNormal); 161 // Restore the audio mode which was used before the first communication-
162 // mode stream was created.
163 if (HasNoAudioStreams()) {
164 SetCommunicationAudioModeOn(false);
150 } 165 }
151 base::AutoLock lock(streams_lock_); 166 base::AutoLock lock(streams_lock_);
152 streams_.erase(static_cast<OpenSLESOutputStream*>(stream)); 167 streams_.erase(static_cast<OpenSLESOutputStream*>(stream));
153 } 168 }
154 169
155 void AudioManagerAndroid::ReleaseInputStream(AudioInputStream* stream) { 170 void AudioManagerAndroid::ReleaseInputStream(AudioInputStream* stream) {
156 AudioManagerBase::ReleaseInputStream(stream); 171 AudioManagerBase::ReleaseInputStream(stream);
172
173 // Restore the audio mode which was used before the first communication-
174 // mode stream was created.
175 if (HasNoAudioStreams()) {
176 SetCommunicationAudioModeOn(false);
177 }
157 } 178 }
158 179
159 AudioOutputStream* AudioManagerAndroid::MakeLinearOutputStream( 180 AudioOutputStream* AudioManagerAndroid::MakeLinearOutputStream(
160 const AudioParameters& params) { 181 const AudioParameters& params) {
161 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format()); 182 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format());
162 return new OpenSLESOutputStream(this, params); 183 return new OpenSLESOutputStream(this, params);
163 } 184 }
164 185
165 AudioOutputStream* AudioManagerAndroid::MakeLowLatencyOutputStream( 186 AudioOutputStream* AudioManagerAndroid::MakeLowLatencyOutputStream(
166 const AudioParameters& params, 187 const AudioParameters& params,
(...skipping 10 matching lines...) Expand all
177 // needs it. 198 // needs it.
178 DLOG_IF(ERROR, !device_id.empty()) << "Not implemented!"; 199 DLOG_IF(ERROR, !device_id.empty()) << "Not implemented!";
179 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format()); 200 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format());
180 return new OpenSLESInputStream(this, params); 201 return new OpenSLESInputStream(this, params);
181 } 202 }
182 203
183 AudioInputStream* AudioManagerAndroid::MakeLowLatencyInputStream( 204 AudioInputStream* AudioManagerAndroid::MakeLowLatencyInputStream(
184 const AudioParameters& params, const std::string& device_id) { 205 const AudioParameters& params, const std::string& device_id) {
185 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format()); 206 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format());
186 DLOG_IF(ERROR, device_id.empty()) << "Invalid device ID!"; 207 DLOG_IF(ERROR, device_id.empty()) << "Invalid device ID!";
187 // Utilize the device ID to select the correct input device. 208 // Use the device ID to select the correct input device.
188 // Note that the input device is always associated with a certain output 209 // Note that the input device is always associated with a certain output
189 // device, i.e., this selection does also switch the output device. 210 // device, i.e., this selection does also switch the output device.
190 // All input and output streams will be affected by the device selection. 211 // All input and output streams will be affected by the device selection.
191 SetAudioDevice(device_id); 212 if (!SetAudioDevice(device_id)) {
213 LOG(ERROR) << "Unable to select audio device!";
214 return NULL;
215 }
192 return new OpenSLESInputStream(this, params); 216 return new OpenSLESInputStream(this, params);
193 } 217 }
194 218
195 int AudioManagerAndroid::GetOptimalOutputFrameSize(int sample_rate, 219 int AudioManagerAndroid::GetOptimalOutputFrameSize(int sample_rate,
196 int channels) { 220 int channels) {
197 if (IsAudioLowLatencySupported()) { 221 if (IsAudioLowLatencySupported()) {
198 return GetAudioLowLatencyOutputFrameSize(); 222 return GetAudioLowLatencyOutputFrameSize();
199 } else { 223 } else {
200 return std::max(kDefaultOutputBufferSize, 224 return std::max(kDefaultOutputBufferSize,
201 Java_AudioManagerAndroid_getMinOutputFrameSize( 225 Java_AudioManagerAndroid_getMinOutputFrameSize(
(...skipping 24 matching lines...) Expand all
226 250
227 int user_buffer_size = GetUserBufferSize(); 251 int user_buffer_size = GetUserBufferSize();
228 if (user_buffer_size) 252 if (user_buffer_size)
229 buffer_size = user_buffer_size; 253 buffer_size = user_buffer_size;
230 254
231 return AudioParameters( 255 return AudioParameters(
232 AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, input_channels, 256 AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, input_channels,
233 sample_rate, bits_per_sample, buffer_size); 257 sample_rate, bits_per_sample, buffer_size);
234 } 258 }
235 259
260 bool AudioManagerAndroid::HasNoAudioStreams() {
261 return output_stream_count() == 0 && input_stream_count() == 0;
262 }
263
236 // static 264 // static
237 bool AudioManagerAndroid::RegisterAudioManager(JNIEnv* env) { 265 bool AudioManagerAndroid::RegisterAudioManager(JNIEnv* env) {
238 return RegisterNativesImpl(env); 266 return RegisterNativesImpl(env);
239 } 267 }
240 268
241 void AudioManagerAndroid::Init() { 269 void AudioManagerAndroid::Init() {
242 Java_AudioManagerAndroid_init( 270 Java_AudioManagerAndroid_init(
243 base::android::AttachCurrentThread(), 271 base::android::AttachCurrentThread(),
244 j_audio_manager_.obj()); 272 j_audio_manager_.obj());
245 } 273 }
(...skipping 14 matching lines...) Expand all
260 } 288 }
261 289
262 void AudioManagerAndroid::DoSetMuteOnAudioThread(bool muted) { 290 void AudioManagerAndroid::DoSetMuteOnAudioThread(bool muted) {
263 base::AutoLock lock(streams_lock_); 291 base::AutoLock lock(streams_lock_);
264 for (OutputStreams::iterator it = streams_.begin(); 292 for (OutputStreams::iterator it = streams_.begin();
265 it != streams_.end(); ++it) { 293 it != streams_.end(); ++it) {
266 (*it)->SetMute(muted); 294 (*it)->SetMute(muted);
267 } 295 }
268 } 296 }
269 297
270 void AudioManagerAndroid::SetAudioMode(int mode) { 298 void AudioManagerAndroid::SetCommunicationAudioModeOn(bool on) {
271 Java_AudioManagerAndroid_setMode( 299 Java_AudioManagerAndroid_setCommunicationAudioModeOn(
272 base::android::AttachCurrentThread(), 300 base::android::AttachCurrentThread(),
273 j_audio_manager_.obj(), mode); 301 j_audio_manager_.obj(), on);
274 } 302 }
275 303
276 void AudioManagerAndroid::SetAudioDevice(const std::string& device_id) { 304 bool AudioManagerAndroid::SetAudioDevice(const std::string& device_id) {
277 JNIEnv* env = AttachCurrentThread(); 305 JNIEnv* env = AttachCurrentThread();
278 306
279 // Send the unique device ID to the Java audio manager and make the 307 // Send the unique device ID to the Java audio manager and make the
280 // device switch. Provide an empty string to the Java audio manager 308 // device switch. Provide an empty string to the Java audio manager
281 // if the default device is selected. 309 // if the default device is selected.
282 ScopedJavaLocalRef<jstring> j_device_id = ConvertUTF8ToJavaString( 310 ScopedJavaLocalRef<jstring> j_device_id = ConvertUTF8ToJavaString(
283 env, 311 env,
284 device_id == AudioManagerBase::kDefaultDeviceId ? 312 device_id == AudioManagerBase::kDefaultDeviceId ?
285 std::string() : device_id); 313 std::string() : device_id);
286 Java_AudioManagerAndroid_setDevice( 314 return Java_AudioManagerAndroid_setDevice(
287 env, j_audio_manager_.obj(), j_device_id.obj()); 315 env, j_audio_manager_.obj(), j_device_id.obj());
288 } 316 }
289 317
290 int AudioManagerAndroid::GetNativeOutputSampleRate() { 318 int AudioManagerAndroid::GetNativeOutputSampleRate() {
291 return Java_AudioManagerAndroid_getNativeOutputSampleRate( 319 return Java_AudioManagerAndroid_getNativeOutputSampleRate(
292 base::android::AttachCurrentThread(), 320 base::android::AttachCurrentThread(),
293 j_audio_manager_.obj()); 321 j_audio_manager_.obj());
294 } 322 }
295 323
296 bool AudioManagerAndroid::IsAudioLowLatencySupported() { 324 bool AudioManagerAndroid::IsAudioLowLatencySupported() {
297 return Java_AudioManagerAndroid_isAudioLowLatencySupported( 325 return Java_AudioManagerAndroid_isAudioLowLatencySupported(
298 base::android::AttachCurrentThread(), 326 base::android::AttachCurrentThread(),
299 j_audio_manager_.obj()); 327 j_audio_manager_.obj());
300 } 328 }
301 329
302 int AudioManagerAndroid::GetAudioLowLatencyOutputFrameSize() { 330 int AudioManagerAndroid::GetAudioLowLatencyOutputFrameSize() {
303 return Java_AudioManagerAndroid_getAudioLowLatencyOutputFrameSize( 331 return Java_AudioManagerAndroid_getAudioLowLatencyOutputFrameSize(
304 base::android::AttachCurrentThread(), 332 base::android::AttachCurrentThread(),
305 j_audio_manager_.obj()); 333 j_audio_manager_.obj());
306 } 334 }
307 335
308 } // namespace media 336 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698