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

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

Issue 131503006: Initialization of audio manager for Android is now done on the audio thread (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Modified AudioInputTest Created 6 years, 10 months 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"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/message_loop/message_loop.h"
12 #include "base/strings/string_number_conversions.h" 13 #include "base/strings/string_number_conversions.h"
13 #include "jni/AudioManagerAndroid_jni.h" 14 #include "jni/AudioManagerAndroid_jni.h"
14 #include "media/audio/android/audio_record_input.h" 15 #include "media/audio/android/audio_record_input.h"
15 #include "media/audio/android/opensles_input.h" 16 #include "media/audio/android/opensles_input.h"
16 #include "media/audio/android/opensles_output.h" 17 #include "media/audio/android/opensles_output.h"
17 #include "media/audio/audio_manager.h" 18 #include "media/audio/audio_manager.h"
18 #include "media/audio/audio_parameters.h" 19 #include "media/audio/audio_parameters.h"
19 #include "media/audio/fake_audio_input_stream.h" 20 #include "media/audio/fake_audio_input_stream.h"
20 #include "media/base/channel_layout.h" 21 #include "media/base/channel_layout.h"
21 22
(...skipping 19 matching lines...) Expand all
41 static const int kDefaultOutputBufferSize = 2048; 42 static const int kDefaultOutputBufferSize = 2048;
42 43
43 AudioManager* CreateAudioManager(AudioLogFactory* audio_log_factory) { 44 AudioManager* CreateAudioManager(AudioLogFactory* audio_log_factory) {
44 return new AudioManagerAndroid(audio_log_factory); 45 return new AudioManagerAndroid(audio_log_factory);
45 } 46 }
46 47
47 AudioManagerAndroid::AudioManagerAndroid(AudioLogFactory* audio_log_factory) 48 AudioManagerAndroid::AudioManagerAndroid(AudioLogFactory* audio_log_factory)
48 : AudioManagerBase(audio_log_factory) { 49 : AudioManagerBase(audio_log_factory) {
49 SetMaxOutputStreamsAllowed(kMaxOutputStreams); 50 SetMaxOutputStreamsAllowed(kMaxOutputStreams);
50 51
51 j_audio_manager_.Reset( 52 // WARNING: This is executed on the UI loop, do not add any code here which
52 Java_AudioManagerAndroid_createAudioManagerAndroid( 53 // loads libraries or attempts to call out into the OS. Instead add such code
53 base::android::AttachCurrentThread(), 54 // to the InitializeOnAudioThread() method below.
54 base::android::GetApplicationContext(), 55
55 reinterpret_cast<intptr_t>(this))); 56 // Task must be posted last to avoid races from handing out "this" to the
56 Init(); 57 // audio thread.
58 GetTaskRunner()->PostTask(FROM_HERE, base::Bind(
59 &AudioManagerAndroid::InitializeOnAudioThread,
60 base::Unretained(this)));
57 } 61 }
58 62
59 AudioManagerAndroid::~AudioManagerAndroid() { 63 AudioManagerAndroid::~AudioManagerAndroid() {
60 Close(); 64 // It's safe to post a task here since Shutdown() will wait for all tasks to
65 // complete before returning.
66 GetTaskRunner()->PostTask(FROM_HERE, base::Bind(
DaleCurtis 2014/02/19 19:10:16 I'm not sure if this is a problem or not, but note
henrika (OOO until Aug 14) 2014/02/21 11:46:16 I am unable to see that it should be a problem but
67 &AudioManagerAndroid::ShutdownOnAudioThread, base::Unretained(this)));
61 Shutdown(); 68 Shutdown();
62 } 69 }
63 70
64 bool AudioManagerAndroid::HasAudioOutputDevices() { 71 bool AudioManagerAndroid::HasAudioOutputDevices() {
65 return true; 72 return true;
66 } 73 }
67 74
68 bool AudioManagerAndroid::HasAudioInputDevices() { 75 bool AudioManagerAndroid::HasAudioInputDevices() {
69 return true; 76 return true;
70 } 77 }
71 78
72 void AudioManagerAndroid::GetAudioInputDeviceNames( 79 void AudioManagerAndroid::GetAudioInputDeviceNames(
73 AudioDeviceNames* device_names) { 80 AudioDeviceNames* device_names) {
81 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
74 // Always add default device parameters as first element. 82 // Always add default device parameters as first element.
75 DCHECK(device_names->empty()); 83 DCHECK(device_names->empty());
76 AddDefaultDevice(device_names); 84 AddDefaultDevice(device_names);
77 85
86 // Get list of available audio devices.
78 JNIEnv* env = AttachCurrentThread(); 87 JNIEnv* env = AttachCurrentThread();
79 ScopedJavaLocalRef<jobjectArray> j_device_array = 88 ScopedJavaLocalRef<jobjectArray> j_device_array =
80 Java_AudioManagerAndroid_getAudioInputDeviceNames( 89 Java_AudioManagerAndroid_getAudioInputDeviceNames(
81 env, j_audio_manager_.obj()); 90 env, j_audio_manager_.obj());
82 jsize len = env->GetArrayLength(j_device_array.obj()); 91 jsize len = env->GetArrayLength(j_device_array.obj());
83 AudioDeviceName device; 92 AudioDeviceName device;
84 for (jsize i = 0; i < len; ++i) { 93 for (jsize i = 0; i < len; ++i) {
85 ScopedJavaLocalRef<jobject> j_device( 94 ScopedJavaLocalRef<jobject> j_device(
86 env, env->GetObjectArrayElement(j_device_array.obj(), i)); 95 env, env->GetObjectArrayElement(j_device_array.obj(), i));
87 ScopedJavaLocalRef<jstring> j_device_name = 96 ScopedJavaLocalRef<jstring> j_device_name =
88 Java_AudioDeviceName_name(env, j_device.obj()); 97 Java_AudioDeviceName_name(env, j_device.obj());
89 ConvertJavaStringToUTF8(env, j_device_name.obj(), &device.device_name); 98 ConvertJavaStringToUTF8(env, j_device_name.obj(), &device.device_name);
90 ScopedJavaLocalRef<jstring> j_device_id = 99 ScopedJavaLocalRef<jstring> j_device_id =
91 Java_AudioDeviceName_id(env, j_device.obj()); 100 Java_AudioDeviceName_id(env, j_device.obj());
92 ConvertJavaStringToUTF8(env, j_device_id.obj(), &device.unique_id); 101 ConvertJavaStringToUTF8(env, j_device_id.obj(), &device.unique_id);
93 device_names->push_back(device); 102 device_names->push_back(device);
94 } 103 }
95 } 104 }
96 105
97 void AudioManagerAndroid::GetAudioOutputDeviceNames( 106 void AudioManagerAndroid::GetAudioOutputDeviceNames(
98 AudioDeviceNames* device_names) { 107 AudioDeviceNames* device_names) {
99 // TODO(henrika): enumerate using GetAudioInputDeviceNames(). 108 // TODO(henrika): enumerate using GetAudioInputDeviceNames().
100 AddDefaultDevice(device_names); 109 AddDefaultDevice(device_names);
101 } 110 }
102 111
103 AudioParameters AudioManagerAndroid::GetInputStreamParameters( 112 AudioParameters AudioManagerAndroid::GetInputStreamParameters(
104 const std::string& device_id) { 113 const std::string& device_id) {
105 JNIEnv* env = AttachCurrentThread(); 114 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
106 // Use mono as preferred number of input channels on Android to save 115 // Use mono as preferred number of input channels on Android to save
107 // resources. Using mono also avoids a driver issue seen on Samsung 116 // resources. Using mono also avoids a driver issue seen on Samsung
108 // Galaxy S3 and S4 devices. See http://crbug.com/256851 for details. 117 // Galaxy S3 and S4 devices. See http://crbug.com/256851 for details.
118 JNIEnv* env = AttachCurrentThread();
DaleCurtis 2014/02/19 19:10:16 Check can probably be removed since you're ensurin
henrika (OOO until Aug 14) 2014/02/21 11:46:16 Done.
119 CHECK(env);
109 ChannelLayout channel_layout = CHANNEL_LAYOUT_MONO; 120 ChannelLayout channel_layout = CHANNEL_LAYOUT_MONO;
110 int buffer_size = Java_AudioManagerAndroid_getMinInputFrameSize( 121 int buffer_size = Java_AudioManagerAndroid_getMinInputFrameSize(
111 env, GetNativeOutputSampleRate(), 122 env, GetNativeOutputSampleRate(),
112 ChannelLayoutToChannelCount(channel_layout)); 123 ChannelLayoutToChannelCount(channel_layout));
113 int effects = AudioParameters::NO_EFFECTS; 124 int effects = AudioParameters::NO_EFFECTS;
114 effects |= Java_AudioManagerAndroid_shouldUseAcousticEchoCanceler(env) ? 125 effects |= Java_AudioManagerAndroid_shouldUseAcousticEchoCanceler(env) ?
115 AudioParameters::ECHO_CANCELLER : AudioParameters::NO_EFFECTS; 126 AudioParameters::ECHO_CANCELLER : AudioParameters::NO_EFFECTS;
116 AudioParameters params( 127 AudioParameters params(
117 AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, 0, 128 AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, 0,
118 GetNativeOutputSampleRate(), 16, 129 GetNativeOutputSampleRate(), 16,
119 buffer_size <= 0 ? kDefaultInputBufferSize : buffer_size, effects); 130 buffer_size <= 0 ? kDefaultInputBufferSize : buffer_size, effects);
120 return params; 131 return params;
121 } 132 }
122 133
123 AudioOutputStream* AudioManagerAndroid::MakeAudioOutputStream( 134 AudioOutputStream* AudioManagerAndroid::MakeAudioOutputStream(
124 const AudioParameters& params, 135 const AudioParameters& params,
125 const std::string& device_id) { 136 const std::string& device_id) {
126 bool had_no_streams = HadNoAudioStreams(); 137 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
138 bool has_no_streams = HasNoAudioStreams();
127 AudioOutputStream* stream = 139 AudioOutputStream* stream =
128 AudioManagerBase::MakeAudioOutputStream(params, std::string()); 140 AudioManagerBase::MakeAudioOutputStream(params, std::string());
129 141
130 // The audio manager for Android creates streams intended for real-time 142 // The audio manager for Android creates streams intended for real-time
131 // VoIP sessions and therefore sets the audio mode to MODE_IN_COMMUNICATION. 143 // VoIP sessions and therefore sets the audio mode to MODE_IN_COMMUNICATION.
132 // If a Bluetooth headset is used, the audio stream will use the SCO 144 // If a Bluetooth headset is selected, the audio stream will use the SCO
133 // channel and therefore have a limited bandwidth (8-16kHz). 145 // channel and therefore have a limited bandwidth (8-16kHz).
134 if (stream && had_no_streams) 146 if (stream && has_no_streams)
135 SetCommunicationAudioModeOn(true); 147 SetCommunicationAudioModeOn(true);
136 148
137 { 149 streams_.insert(static_cast<OpenSLESOutputStream*>(stream));
138 base::AutoLock lock(streams_lock_);
139 streams_.insert(static_cast<OpenSLESOutputStream*>(stream));
140 }
141 150
142 return stream; 151 return stream;
143 } 152 }
144 153
145 AudioInputStream* AudioManagerAndroid::MakeAudioInputStream( 154 AudioInputStream* AudioManagerAndroid::MakeAudioInputStream(
146 const AudioParameters& params, const std::string& device_id) { 155 const AudioParameters& params, const std::string& device_id) {
147 bool had_no_streams = HadNoAudioStreams(); 156 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
157 bool has_no_streams = HasNoAudioStreams();
148 AudioInputStream* stream = 158 AudioInputStream* stream =
149 AudioManagerBase::MakeAudioInputStream(params, device_id); 159 AudioManagerBase::MakeAudioInputStream(params, device_id);
150 160
151 // The audio manager for Android creates streams intended for real-time 161 // The audio manager for Android creates streams intended for real-time
152 // VoIP sessions and therefore sets the audio mode to MODE_IN_COMMUNICATION. 162 // VoIP sessions and therefore sets the audio mode to MODE_IN_COMMUNICATION.
153 // If a Bluetooth headset is used, the audio stream will use the SCO 163 // If a Bluetooth headset is used, the audio stream will use the SCO
154 // channel and therefore have a limited bandwidth (8kHz). 164 // channel and therefore have a limited bandwidth (8kHz).
155 if (stream && had_no_streams) 165 if (stream && has_no_streams)
156 SetCommunicationAudioModeOn(true); 166 SetCommunicationAudioModeOn(true);
157 return stream; 167 return stream;
158 } 168 }
159 169
160 void AudioManagerAndroid::ReleaseOutputStream(AudioOutputStream* stream) { 170 void AudioManagerAndroid::ReleaseOutputStream(AudioOutputStream* stream) {
171 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
161 AudioManagerBase::ReleaseOutputStream(stream); 172 AudioManagerBase::ReleaseOutputStream(stream);
162 173
163 // Restore the audio mode which was used before the first communication- 174 // Restore the audio mode which was used before the first communication-
164 // mode stream was created. 175 // mode stream was created.
165 if (HadNoAudioStreams()) 176 if (HasNoAudioStreams())
166 SetCommunicationAudioModeOn(false); 177 SetCommunicationAudioModeOn(false);
167 base::AutoLock lock(streams_lock_); 178
168 streams_.erase(static_cast<OpenSLESOutputStream*>(stream)); 179 streams_.erase(static_cast<OpenSLESOutputStream*>(stream));
169 } 180 }
170 181
171 void AudioManagerAndroid::ReleaseInputStream(AudioInputStream* stream) { 182 void AudioManagerAndroid::ReleaseInputStream(AudioInputStream* stream) {
183 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
184 DCHECK(!j_audio_manager_.is_null());
172 AudioManagerBase::ReleaseInputStream(stream); 185 AudioManagerBase::ReleaseInputStream(stream);
173 186
174 // Restore the audio mode which was used before the first communication- 187 // Restore the audio mode which was used before the first communication-
175 // mode stream was created. 188 // mode stream was created.
176 if (HadNoAudioStreams()) 189 if (HasNoAudioStreams())
177 SetCommunicationAudioModeOn(false); 190 SetCommunicationAudioModeOn(false);
178 } 191 }
179 192
180 AudioOutputStream* AudioManagerAndroid::MakeLinearOutputStream( 193 AudioOutputStream* AudioManagerAndroid::MakeLinearOutputStream(
181 const AudioParameters& params) { 194 const AudioParameters& params) {
182 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format()); 195 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format());
196 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
183 return new OpenSLESOutputStream(this, params); 197 return new OpenSLESOutputStream(this, params);
184 } 198 }
185 199
186 AudioOutputStream* AudioManagerAndroid::MakeLowLatencyOutputStream( 200 AudioOutputStream* AudioManagerAndroid::MakeLowLatencyOutputStream(
187 const AudioParameters& params, 201 const AudioParameters& params,
188 const std::string& device_id) { 202 const std::string& device_id) {
189 DLOG_IF(ERROR, !device_id.empty()) << "Not implemented!"; 203 DLOG_IF(ERROR, !device_id.empty()) << "Not implemented!";
190 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format()); 204 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format());
191 return new OpenSLESOutputStream(this, params); 205 return new OpenSLESOutputStream(this, params);
192 } 206 }
193 207
194 AudioInputStream* AudioManagerAndroid::MakeLinearInputStream( 208 AudioInputStream* AudioManagerAndroid::MakeLinearInputStream(
195 const AudioParameters& params, const std::string& device_id) { 209 const AudioParameters& params, const std::string& device_id) {
196 // TODO(henrika): add support for device selection if/when any client 210 // TODO(henrika): add support for device selection if/when any client
197 // needs it. 211 // needs it.
198 DLOG_IF(ERROR, !device_id.empty()) << "Not implemented!"; 212 DLOG_IF(ERROR, !device_id.empty()) << "Not implemented!";
199 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format()); 213 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format());
200 return new OpenSLESInputStream(this, params); 214 return new OpenSLESInputStream(this, params);
201 } 215 }
202 216
203 AudioInputStream* AudioManagerAndroid::MakeLowLatencyInputStream( 217 AudioInputStream* AudioManagerAndroid::MakeLowLatencyInputStream(
204 const AudioParameters& params, const std::string& device_id) { 218 const AudioParameters& params, const std::string& device_id) {
219 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
205 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format()); 220 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format());
206 DLOG_IF(ERROR, device_id.empty()) << "Invalid device ID!"; 221 DLOG_IF(ERROR, device_id.empty()) << "Invalid device ID!";
222
207 // Use the device ID to select the correct input device. 223 // Use the device ID to select the correct input device.
208 // Note that the input device is always associated with a certain output 224 // Note that the input device is always associated with a certain output
209 // device, i.e., this selection does also switch the output device. 225 // device, i.e., this selection does also switch the output device.
210 // All input and output streams will be affected by the device selection. 226 // All input and output streams will be affected by the device selection.
211 if (!SetAudioDevice(device_id)) { 227 if (!SetAudioDevice(device_id)) {
212 LOG(ERROR) << "Unable to select audio device!"; 228 LOG(ERROR) << "Unable to select audio device!";
213 return NULL; 229 return NULL;
214 } 230 }
215 231
216 if (params.effects() != AudioParameters::NO_EFFECTS) { 232 if (params.effects() != AudioParameters::NO_EFFECTS) {
217 // Platform effects can only be enabled through the AudioRecord path. 233 // Platform effects can only be enabled through the AudioRecord path.
218 // An effect should only have been requested here if recommended by 234 // An effect should only have been requested here if recommended by
219 // AudioManagerAndroid.shouldUse<Effect>. 235 // AudioManagerAndroid.shouldUse<Effect>.
220 // 236 //
221 // Creating this class requires Jelly Bean, which is already guaranteed by 237 // Creating this class requires Jelly Bean, which is already guaranteed by
222 // shouldUse<Effect>. Only DCHECK on that condition to allow tests to use 238 // shouldUse<Effect>. Only DCHECK on that condition to allow tests to use
223 // the effect settings as a way to select the input path. 239 // the effect settings as a way to select the input path.
224 DCHECK_GE(base::android::BuildInfo::GetInstance()->sdk_int(), 16); 240 DCHECK_GE(base::android::BuildInfo::GetInstance()->sdk_int(), 16);
225 DVLOG(1) << "Creating AudioRecordInputStream"; 241 DVLOG(1) << "Creating AudioRecordInputStream";
226 return new AudioRecordInputStream(this, params); 242 return new AudioRecordInputStream(this, params);
227 } 243 }
228 DVLOG(1) << "Creating OpenSLESInputStream"; 244 DVLOG(1) << "Creating OpenSLESInputStream";
229 return new OpenSLESInputStream(this, params); 245 return new OpenSLESInputStream(this, params);
230 } 246 }
231 247
232 int AudioManagerAndroid::GetOptimalOutputFrameSize(int sample_rate, 248 // static
233 int channels) { 249 bool AudioManagerAndroid::RegisterAudioManager(JNIEnv* env) {
234 if (IsAudioLowLatencySupported()) { 250 return RegisterNativesImpl(env);
235 return GetAudioLowLatencyOutputFrameSize(); 251 }
236 } else { 252
237 return std::max(kDefaultOutputBufferSize, 253 void AudioManagerAndroid::SetMute(JNIEnv* env, jobject obj, jboolean muted) {
238 Java_AudioManagerAndroid_getMinOutputFrameSize( 254 GetTaskRunner()->PostTask(
239 base::android::AttachCurrentThread(), 255 FROM_HERE,
240 sample_rate, channels)); 256 base::Bind(
241 } 257 &AudioManagerAndroid::DoSetMuteOnAudioThread,
258 base::Unretained(this),
259 muted));
242 } 260 }
243 261
244 AudioParameters AudioManagerAndroid::GetPreferredOutputStreamParameters( 262 AudioParameters AudioManagerAndroid::GetPreferredOutputStreamParameters(
245 const std::string& output_device_id, 263 const std::string& output_device_id,
246 const AudioParameters& input_params) { 264 const AudioParameters& input_params) {
247 // TODO(tommi): Support |output_device_id|. 265 // TODO(tommi): Support |output_device_id|.
266 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
248 DLOG_IF(ERROR, !output_device_id.empty()) << "Not implemented!"; 267 DLOG_IF(ERROR, !output_device_id.empty()) << "Not implemented!";
249 ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO; 268 ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO;
250 int sample_rate = GetNativeOutputSampleRate(); 269 int sample_rate = GetNativeOutputSampleRate();
251 int buffer_size = GetOptimalOutputFrameSize(sample_rate, 2); 270 int buffer_size = GetOptimalOutputFrameSize(sample_rate, 2);
252 int bits_per_sample = 16; 271 int bits_per_sample = 16;
253 int input_channels = 0; 272 int input_channels = 0;
254 if (input_params.IsValid()) { 273 if (input_params.IsValid()) {
255 // Use the client's input parameters if they are valid. 274 // Use the client's input parameters if they are valid.
256 sample_rate = input_params.sample_rate(); 275 sample_rate = input_params.sample_rate();
257 bits_per_sample = input_params.bits_per_sample(); 276 bits_per_sample = input_params.bits_per_sample();
258 channel_layout = input_params.channel_layout(); 277 channel_layout = input_params.channel_layout();
259 input_channels = input_params.input_channels(); 278 input_channels = input_params.input_channels();
260 buffer_size = GetOptimalOutputFrameSize( 279 buffer_size = GetOptimalOutputFrameSize(
261 sample_rate, ChannelLayoutToChannelCount(channel_layout)); 280 sample_rate, ChannelLayoutToChannelCount(channel_layout));
262 } 281 }
263 282
264 int user_buffer_size = GetUserBufferSize(); 283 int user_buffer_size = GetUserBufferSize();
265 if (user_buffer_size) 284 if (user_buffer_size)
266 buffer_size = user_buffer_size; 285 buffer_size = user_buffer_size;
267 286
268 return AudioParameters( 287 return AudioParameters(
269 AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, input_channels, 288 AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, input_channels,
270 sample_rate, bits_per_sample, buffer_size, AudioParameters::NO_EFFECTS); 289 sample_rate, bits_per_sample, buffer_size, AudioParameters::NO_EFFECTS);
271 } 290 }
272 291
273 bool AudioManagerAndroid::HadNoAudioStreams() { 292 void AudioManagerAndroid::InitializeOnAudioThread() {
274 return output_stream_count() == 0 && input_stream_count() == 0; 293 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
275 }
276 294
277 // static 295 JNIEnv* env = base::android::AttachCurrentThread();
278 bool AudioManagerAndroid::RegisterAudioManager(JNIEnv* env) { 296 CHECK(env);
279 return RegisterNativesImpl(env);
280 }
281 297
282 void AudioManagerAndroid::Init() { 298 // Create the Android audio manager on the audio thread.
299 DVLOG(2) << "Creating Java part of the audio manager";
300 j_audio_manager_.Reset(
301 Java_AudioManagerAndroid_createAudioManagerAndroid(
302 env,
303 base::android::GetApplicationContext(),
304 reinterpret_cast<intptr_t>(this)));
305
306 // Prepare the list of audio devices and register receivers for device
307 // notifications.
283 Java_AudioManagerAndroid_init( 308 Java_AudioManagerAndroid_init(
284 base::android::AttachCurrentThread(), 309 base::android::AttachCurrentThread(),
285 j_audio_manager_.obj()); 310 j_audio_manager_.obj());
286 } 311 }
287 312
288 void AudioManagerAndroid::Close() { 313 void AudioManagerAndroid::ShutdownOnAudioThread() {
314 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
315 DVLOG(2) << "Destroying Java part of the audio manager";
289 Java_AudioManagerAndroid_close( 316 Java_AudioManagerAndroid_close(
290 base::android::AttachCurrentThread(), 317 base::android::AttachCurrentThread(),
291 j_audio_manager_.obj()); 318 j_audio_manager_.obj());
319 j_audio_manager_.Reset();
292 } 320 }
293 321
294 void AudioManagerAndroid::SetMute(JNIEnv* env, jobject obj, jboolean muted) { 322 bool AudioManagerAndroid::HasNoAudioStreams() {
295 GetTaskRunner()->PostTask( 323 return output_stream_count() == 0 && input_stream_count() == 0;
296 FROM_HERE,
297 base::Bind(
298 &AudioManagerAndroid::DoSetMuteOnAudioThread,
299 base::Unretained(this),
300 muted));
301 }
302
303 void AudioManagerAndroid::DoSetMuteOnAudioThread(bool muted) {
304 base::AutoLock lock(streams_lock_);
305 for (OutputStreams::iterator it = streams_.begin();
306 it != streams_.end(); ++it) {
307 (*it)->SetMute(muted);
308 }
309 } 324 }
310 325
311 void AudioManagerAndroid::SetCommunicationAudioModeOn(bool on) { 326 void AudioManagerAndroid::SetCommunicationAudioModeOn(bool on) {
312 Java_AudioManagerAndroid_setCommunicationAudioModeOn( 327 Java_AudioManagerAndroid_setCommunicationAudioModeOn(
313 base::android::AttachCurrentThread(), 328 base::android::AttachCurrentThread(),
314 j_audio_manager_.obj(), on); 329 j_audio_manager_.obj(), on);
315 } 330 }
316 331
317 bool AudioManagerAndroid::SetAudioDevice(const std::string& device_id) { 332 bool AudioManagerAndroid::SetAudioDevice(const std::string& device_id) {
318 JNIEnv* env = AttachCurrentThread(); 333 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
319 334
320 // Send the unique device ID to the Java audio manager and make the 335 // Send the unique device ID to the Java audio manager and make the
321 // device switch. Provide an empty string to the Java audio manager 336 // device switch. Provide an empty string to the Java audio manager
322 // if the default device is selected. 337 // if the default device is selected.
338 JNIEnv* env = AttachCurrentThread();
339 CHECK(env);
323 ScopedJavaLocalRef<jstring> j_device_id = ConvertUTF8ToJavaString( 340 ScopedJavaLocalRef<jstring> j_device_id = ConvertUTF8ToJavaString(
324 env, 341 env,
325 device_id == AudioManagerBase::kDefaultDeviceId ? 342 device_id == AudioManagerBase::kDefaultDeviceId ?
326 std::string() : device_id); 343 std::string() : device_id);
327 return Java_AudioManagerAndroid_setDevice( 344 return Java_AudioManagerAndroid_setDevice(
328 env, j_audio_manager_.obj(), j_device_id.obj()); 345 env, j_audio_manager_.obj(), j_device_id.obj());
329 } 346 }
330 347
331 int AudioManagerAndroid::GetNativeOutputSampleRate() { 348 int AudioManagerAndroid::GetNativeOutputSampleRate() {
332 return Java_AudioManagerAndroid_getNativeOutputSampleRate( 349 return Java_AudioManagerAndroid_getNativeOutputSampleRate(
333 base::android::AttachCurrentThread(), 350 base::android::AttachCurrentThread(),
334 j_audio_manager_.obj()); 351 j_audio_manager_.obj());
335 } 352 }
336 353
337 bool AudioManagerAndroid::IsAudioLowLatencySupported() { 354 bool AudioManagerAndroid::IsAudioLowLatencySupported() {
338 return Java_AudioManagerAndroid_isAudioLowLatencySupported( 355 return Java_AudioManagerAndroid_isAudioLowLatencySupported(
339 base::android::AttachCurrentThread(), 356 base::android::AttachCurrentThread(),
340 j_audio_manager_.obj()); 357 j_audio_manager_.obj());
341 } 358 }
342 359
343 int AudioManagerAndroid::GetAudioLowLatencyOutputFrameSize() { 360 int AudioManagerAndroid::GetAudioLowLatencyOutputFrameSize() {
344 return Java_AudioManagerAndroid_getAudioLowLatencyOutputFrameSize( 361 return Java_AudioManagerAndroid_getAudioLowLatencyOutputFrameSize(
345 base::android::AttachCurrentThread(), 362 base::android::AttachCurrentThread(),
346 j_audio_manager_.obj()); 363 j_audio_manager_.obj());
347 } 364 }
348 365
366 int AudioManagerAndroid::GetOptimalOutputFrameSize(int sample_rate,
367 int channels) {
368 if (IsAudioLowLatencySupported()) {
369 return GetAudioLowLatencyOutputFrameSize();
370 } else {
371 return std::max(kDefaultOutputBufferSize,
372 Java_AudioManagerAndroid_getMinOutputFrameSize(
373 base::android::AttachCurrentThread(),
374 sample_rate, channels));
375 }
376 }
377
378 void AudioManagerAndroid::DoSetMuteOnAudioThread(bool muted) {
379 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
380 for (OutputStreams::iterator it = streams_.begin();
381 it != streams_.end(); ++it) {
382 (*it)->SetMute(muted);
383 }
384 }
385
349 } // namespace media 386 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698