OLD | NEW |
---|---|
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/opensles_input.h" | 5 #include "media/audio/android/opensles_input.h" |
6 | 6 |
7 #include "base/debug/trace_event.h" | |
7 #include "base/logging.h" | 8 #include "base/logging.h" |
8 #include "media/audio/android/audio_manager_android.h" | 9 #include "media/audio/android/audio_manager_android.h" |
9 | 10 |
10 #define LOG_ON_FAILURE_AND_RETURN(op, ...) \ | 11 #define LOG_ON_FAILURE_AND_RETURN(op, ...) \ |
11 do { \ | 12 do { \ |
12 SLresult err = (op); \ | 13 SLresult err = (op); \ |
13 if (err != SL_RESULT_SUCCESS) { \ | 14 if (err != SL_RESULT_SUCCESS) { \ |
14 DLOG(ERROR) << #op << " failed: " << err; \ | 15 DLOG(ERROR) << #op << " failed: " << err; \ |
15 return __VA_ARGS__; \ | 16 return __VA_ARGS__; \ |
16 } \ | 17 } \ |
17 } while (0) | 18 } while (0) |
18 | 19 |
19 namespace media { | 20 namespace media { |
20 | 21 |
21 OpenSLESInputStream::OpenSLESInputStream(AudioManagerAndroid* audio_manager, | 22 OpenSLESInputStream::OpenSLESInputStream(AudioManagerAndroid* audio_manager, |
22 const AudioParameters& params) | 23 const AudioParameters& params) |
23 : audio_manager_(audio_manager), | 24 : audio_manager_(audio_manager), |
24 callback_(NULL), | 25 callback_(NULL), |
25 recorder_(NULL), | 26 recorder_(NULL), |
26 simple_buffer_queue_(NULL), | 27 simple_buffer_queue_(NULL), |
27 active_queue_(0), | 28 active_buffer_index_(0), |
28 buffer_size_bytes_(0), | 29 buffer_size_bytes_(0), |
29 started_(false) { | 30 started_(false) { |
31 DVLOG(2) << "OpenSLESInputStream::OpenSLESInputStream()"; | |
30 format_.formatType = SL_DATAFORMAT_PCM; | 32 format_.formatType = SL_DATAFORMAT_PCM; |
31 format_.numChannels = static_cast<SLuint32>(params.channels()); | 33 format_.numChannels = static_cast<SLuint32>(params.channels()); |
32 // Provides sampling rate in milliHertz to OpenSLES. | 34 // Provides sampling rate in milliHertz to OpenSLES. |
33 format_.samplesPerSec = static_cast<SLuint32>(params.sample_rate() * 1000); | 35 format_.samplesPerSec = static_cast<SLuint32>(params.sample_rate() * 1000); |
34 format_.bitsPerSample = params.bits_per_sample(); | 36 format_.bitsPerSample = params.bits_per_sample(); |
35 format_.containerSize = params.bits_per_sample(); | 37 format_.containerSize = params.bits_per_sample(); |
36 format_.endianness = SL_BYTEORDER_LITTLEENDIAN; | 38 format_.endianness = SL_BYTEORDER_LITTLEENDIAN; |
37 if (format_.numChannels == 1) | 39 if (format_.numChannels == 1) |
38 format_.channelMask = SL_SPEAKER_FRONT_CENTER; | 40 format_.channelMask = SL_SPEAKER_FRONT_CENTER; |
39 else if (format_.numChannels == 2) | 41 else if (format_.numChannels == 2) |
40 format_.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; | 42 format_.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; |
41 else | 43 else |
42 NOTREACHED() << "Unsupported number of channels: " << format_.numChannels; | 44 NOTREACHED() << "Unsupported number of channels: " << format_.numChannels; |
43 | 45 |
44 buffer_size_bytes_ = params.GetBytesPerBuffer(); | 46 buffer_size_bytes_ = params.GetBytesPerBuffer(); |
45 | 47 |
46 memset(&audio_data_, 0, sizeof(audio_data_)); | 48 memset(&audio_data_, 0, sizeof(audio_data_)); |
47 } | 49 } |
48 | 50 |
49 OpenSLESInputStream::~OpenSLESInputStream() { | 51 OpenSLESInputStream::~OpenSLESInputStream() { |
52 DVLOG(2) << "OpenSLESInputStream::~OpenSLESInputStream()"; | |
53 DCHECK(thread_checker_.CalledOnValidThread()); | |
50 DCHECK(!recorder_object_.Get()); | 54 DCHECK(!recorder_object_.Get()); |
51 DCHECK(!engine_object_.Get()); | 55 DCHECK(!engine_object_.Get()); |
52 DCHECK(!recorder_); | 56 DCHECK(!recorder_); |
53 DCHECK(!simple_buffer_queue_); | 57 DCHECK(!simple_buffer_queue_); |
54 DCHECK(!audio_data_[0]); | 58 DCHECK(!audio_data_[0]); |
55 } | 59 } |
56 | 60 |
57 bool OpenSLESInputStream::Open() { | 61 bool OpenSLESInputStream::Open() { |
62 DVLOG(2) << "OpenSLESInputStream::Open()"; | |
63 DCHECK(thread_checker_.CalledOnValidThread()); | |
58 if (engine_object_.Get()) | 64 if (engine_object_.Get()) |
59 return false; | 65 return false; |
60 | 66 |
61 if (!CreateRecorder()) | 67 if (!CreateRecorder()) |
62 return false; | 68 return false; |
63 | 69 |
64 SetupAudioBuffer(); | 70 SetupAudioBuffer(); |
65 | 71 |
66 return true; | 72 return true; |
67 } | 73 } |
68 | 74 |
69 void OpenSLESInputStream::Start(AudioInputCallback* callback) { | 75 void OpenSLESInputStream::Start(AudioInputCallback* callback) { |
76 DVLOG(2) << "OpenSLESInputStream::Start()"; | |
77 DCHECK(thread_checker_.CalledOnValidThread()); | |
70 DCHECK(callback); | 78 DCHECK(callback); |
71 DCHECK(recorder_); | 79 DCHECK(recorder_); |
72 DCHECK(simple_buffer_queue_); | 80 DCHECK(simple_buffer_queue_); |
73 if (started_) | 81 if (started_) |
74 return; | 82 return; |
75 | 83 |
76 // Enable the flags before streaming. | 84 base::AutoLock lock(lock_); |
85 DCHECK(callback_ == NULL || callback_ == callback); | |
77 callback_ = callback; | 86 callback_ = callback; |
78 active_queue_ = 0; | 87 active_buffer_index_ = 0; |
79 started_ = true; | |
80 | 88 |
89 // Enqueues kMaxNumOfBuffersInQueue zero buffers to get the ball rolling. | |
90 // TODO(henrika): add support for Start/Stop/Start sequences when we are | |
91 // able to clear the buffer queue. There is currently a bug in the OpenSLES | |
92 // implementation which forces us to always call Stop() and Close() before | |
93 // calling Start() again. | |
81 SLresult err = SL_RESULT_UNKNOWN_ERROR; | 94 SLresult err = SL_RESULT_UNKNOWN_ERROR; |
82 // Enqueues |kNumOfQueuesInBuffer| zero buffers to get the ball rolling. | 95 for (int i = 0; i < kMaxNumOfBuffersInQueue; ++i) { |
83 for (int i = 0; i < kNumOfQueuesInBuffer; ++i) { | |
84 err = (*simple_buffer_queue_)->Enqueue( | 96 err = (*simple_buffer_queue_)->Enqueue( |
85 simple_buffer_queue_, | 97 simple_buffer_queue_, audio_data_[i], buffer_size_bytes_); |
86 audio_data_[i], | |
87 buffer_size_bytes_); | |
88 if (SL_RESULT_SUCCESS != err) { | 98 if (SL_RESULT_SUCCESS != err) { |
89 HandleError(err); | 99 HandleError(err); |
100 started_ = false; | |
90 return; | 101 return; |
91 } | 102 } |
92 } | 103 } |
93 | 104 |
94 // Start the recording by setting the state to |SL_RECORDSTATE_RECORDING|. | 105 // Start the recording by setting the state to SL_RECORDSTATE_RECORDING. |
106 // When the object is in the SL_RECORDSTATE_RECORDING state, adding buffers | |
107 // will implicitly start the filling process. | |
95 err = (*recorder_)->SetRecordState(recorder_, SL_RECORDSTATE_RECORDING); | 108 err = (*recorder_)->SetRecordState(recorder_, SL_RECORDSTATE_RECORDING); |
96 if (SL_RESULT_SUCCESS != err) | 109 if (SL_RESULT_SUCCESS != err) { |
97 HandleError(err); | 110 HandleError(err); |
111 started_ = false; | |
112 return; | |
113 } | |
114 | |
115 started_ = true; | |
98 } | 116 } |
99 | 117 |
100 void OpenSLESInputStream::Stop() { | 118 void OpenSLESInputStream::Stop() { |
119 DVLOG(2) << "OpenSLESInputStream::Stop()"; | |
120 DCHECK(thread_checker_.CalledOnValidThread()); | |
101 if (!started_) | 121 if (!started_) |
102 return; | 122 return; |
103 | 123 |
104 // Stop recording by setting the record state to |SL_RECORDSTATE_STOPPED|. | 124 base::AutoLock lock(lock_); |
125 | |
126 // Stop recording by setting the record state to SL_RECORDSTATE_STOPPED. | |
105 LOG_ON_FAILURE_AND_RETURN( | 127 LOG_ON_FAILURE_AND_RETURN( |
106 (*recorder_)->SetRecordState(recorder_, | 128 (*recorder_)->SetRecordState(recorder_, SL_RECORDSTATE_STOPPED)); |
107 SL_RECORDSTATE_STOPPED)); | |
108 | 129 |
109 // Clear the buffer queue to get rid of old data when resuming recording. | 130 // Clear the buffer queue to get rid of old data when resuming recording. |
110 LOG_ON_FAILURE_AND_RETURN( | 131 LOG_ON_FAILURE_AND_RETURN( |
111 (*simple_buffer_queue_)->Clear(simple_buffer_queue_)); | 132 (*simple_buffer_queue_)->Clear(simple_buffer_queue_)); |
112 | 133 |
113 started_ = false; | 134 started_ = false; |
114 } | 135 } |
115 | 136 |
116 void OpenSLESInputStream::Close() { | 137 void OpenSLESInputStream::Close() { |
138 DVLOG(2) << "OpenSLESInputStream::Close()"; | |
139 DCHECK(thread_checker_.CalledOnValidThread()); | |
140 | |
117 // Stop the stream if it is still recording. | 141 // Stop the stream if it is still recording. |
118 Stop(); | 142 Stop(); |
143 { | |
144 base::AutoLock lock(lock_); | |
119 | 145 |
120 // Explicitly free the player objects and invalidate their associated | 146 if (callback_) { |
121 // interfaces. They have to be done in the correct order. | 147 callback_->OnClose(this); |
wjia(left Chromium)
2013/09/10 16:33:35
Since none of us knows why callback is passed in a
henrika (OOO until Aug 14)
2013/09/11 13:25:01
Done.
| |
122 recorder_object_.Reset(); | 148 callback_ = NULL; |
123 engine_object_.Reset(); | 149 } |
124 simple_buffer_queue_ = NULL; | |
125 recorder_ = NULL; | |
126 | 150 |
127 ReleaseAudioBuffer(); | 151 // Destroy the buffer queue recorder object and invalidate all associated |
152 // interfaces. | |
153 recorder_object_.Reset(); | |
154 simple_buffer_queue_ = NULL; | |
155 recorder_ = NULL; | |
156 | |
157 // Destroy the engine object. We don't store any associated interface for | |
158 // this object. | |
159 engine_object_.Reset(); | |
160 ReleaseAudioBuffer(); | |
161 } | |
128 | 162 |
129 audio_manager_->ReleaseInputStream(this); | 163 audio_manager_->ReleaseInputStream(this); |
130 } | 164 } |
131 | 165 |
132 double OpenSLESInputStream::GetMaxVolume() { | 166 double OpenSLESInputStream::GetMaxVolume() { |
133 NOTIMPLEMENTED(); | 167 NOTIMPLEMENTED(); |
134 return 0.0; | 168 return 0.0; |
135 } | 169 } |
136 | 170 |
137 void OpenSLESInputStream::SetVolume(double volume) { | 171 void OpenSLESInputStream::SetVolume(double volume) { NOTIMPLEMENTED(); } |
138 NOTIMPLEMENTED(); | |
139 } | |
140 | 172 |
141 double OpenSLESInputStream::GetVolume() { | 173 double OpenSLESInputStream::GetVolume() { |
142 NOTIMPLEMENTED(); | 174 NOTIMPLEMENTED(); |
143 return 0.0; | 175 return 0.0; |
144 } | 176 } |
145 | 177 |
146 void OpenSLESInputStream::SetAutomaticGainControl(bool enabled) { | 178 void OpenSLESInputStream::SetAutomaticGainControl(bool enabled) { |
147 NOTIMPLEMENTED(); | 179 NOTIMPLEMENTED(); |
148 } | 180 } |
149 | 181 |
150 bool OpenSLESInputStream::GetAutomaticGainControl() { | 182 bool OpenSLESInputStream::GetAutomaticGainControl() { |
151 NOTIMPLEMENTED(); | 183 NOTIMPLEMENTED(); |
152 return false; | 184 return false; |
153 } | 185 } |
154 | 186 |
155 bool OpenSLESInputStream::CreateRecorder() { | 187 bool OpenSLESInputStream::CreateRecorder() { |
188 DCHECK(thread_checker_.CalledOnValidThread()); | |
189 DCHECK(!engine_object_.Get()); | |
190 DCHECK(!recorder_object_.Get()); | |
191 DCHECK(!recorder_); | |
192 DCHECK(!simple_buffer_queue_); | |
193 | |
156 // Initializes the engine object with specific option. After working with the | 194 // Initializes the engine object with specific option. After working with the |
157 // object, we need to free the object and its resources. | 195 // object, we need to free the object and its resources. |
158 SLEngineOption option[] = { | 196 SLEngineOption option[] = { |
159 { SL_ENGINEOPTION_THREADSAFE, static_cast<SLuint32>(SL_BOOLEAN_TRUE) } | 197 {SL_ENGINEOPTION_THREADSAFE, static_cast<SLuint32>(SL_BOOLEAN_TRUE)}}; |
160 }; | 198 LOG_ON_FAILURE_AND_RETURN( |
161 LOG_ON_FAILURE_AND_RETURN(slCreateEngine(engine_object_.Receive(), | 199 slCreateEngine(engine_object_.Receive(), 1, option, 0, NULL, NULL), |
162 1, | 200 false); |
163 option, | |
164 0, | |
165 NULL, | |
166 NULL), | |
167 false); | |
168 | 201 |
169 // Realize the SL engine object in synchronous mode. | 202 // Realize the SL engine object in synchronous mode. |
170 LOG_ON_FAILURE_AND_RETURN(engine_object_->Realize(engine_object_.Get(), | 203 LOG_ON_FAILURE_AND_RETURN( |
171 SL_BOOLEAN_FALSE), | 204 engine_object_->Realize(engine_object_.Get(), SL_BOOLEAN_FALSE), false); |
172 false); | |
173 | 205 |
174 // Get the SL engine interface which is implicit. | 206 // Get the SL engine interface which is implicit. |
175 SLEngineItf engine; | 207 SLEngineItf engine; |
176 LOG_ON_FAILURE_AND_RETURN(engine_object_->GetInterface(engine_object_.Get(), | 208 LOG_ON_FAILURE_AND_RETURN(engine_object_->GetInterface( |
177 SL_IID_ENGINE, | 209 engine_object_.Get(), SL_IID_ENGINE, &engine), |
178 &engine), | |
179 false); | 210 false); |
180 | 211 |
181 // Audio source configuration. | 212 // Audio source configuration. |
182 SLDataLocator_IODevice mic_locator = { | 213 SLDataLocator_IODevice mic_locator = { |
183 SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT, | 214 SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT, |
184 SL_DEFAULTDEVICEID_AUDIOINPUT, NULL | 215 SL_DEFAULTDEVICEID_AUDIOINPUT, NULL}; |
185 }; | 216 SLDataSource audio_source = {&mic_locator, NULL}; |
186 SLDataSource audio_source = { &mic_locator, NULL }; | |
187 | 217 |
188 // Audio sink configuration. | 218 // Audio sink configuration. |
189 SLDataLocator_AndroidSimpleBufferQueue buffer_queue = { | 219 SLDataLocator_AndroidSimpleBufferQueue buffer_queue = { |
190 SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, // Locator type. | 220 SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, |
191 static_cast<SLuint32>(kNumOfQueuesInBuffer) // Number of buffers. | 221 static_cast<SLuint32>(kMaxNumOfBuffersInQueue)}; |
192 }; | 222 SLDataSink audio_sink = {&buffer_queue, &format_}; |
193 SLDataSink audio_sink = { &buffer_queue, &format_ }; | |
194 | 223 |
195 // Create an audio recorder. | 224 // Create an audio recorder. |
196 const SLInterfaceID interface_id[] = { | 225 const SLInterfaceID interface_id[] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE, |
197 SL_IID_ANDROIDSIMPLEBUFFERQUEUE, | 226 SL_IID_ANDROIDCONFIGURATION}; |
198 SL_IID_ANDROIDCONFIGURATION | 227 const SLboolean interface_required[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; |
199 }; | 228 |
200 const SLboolean interface_required[] = { | |
201 SL_BOOLEAN_TRUE, | |
202 SL_BOOLEAN_TRUE | |
203 }; | |
204 // Create AudioRecorder and specify SL_IID_ANDROIDCONFIGURATION. | 229 // Create AudioRecorder and specify SL_IID_ANDROIDCONFIGURATION. |
205 LOG_ON_FAILURE_AND_RETURN( | 230 LOG_ON_FAILURE_AND_RETURN( |
206 (*engine)->CreateAudioRecorder(engine, | 231 (*engine)->CreateAudioRecorder(engine, |
207 recorder_object_.Receive(), | 232 recorder_object_.Receive(), |
208 &audio_source, | 233 &audio_source, |
209 &audio_sink, | 234 &audio_sink, |
210 arraysize(interface_id), | 235 arraysize(interface_id), |
211 interface_id, | 236 interface_id, |
212 interface_required), | 237 interface_required), |
213 false); | 238 false); |
214 | 239 |
215 SLAndroidConfigurationItf recorder_config; | 240 SLAndroidConfigurationItf recorder_config; |
216 LOG_ON_FAILURE_AND_RETURN( | 241 LOG_ON_FAILURE_AND_RETURN( |
217 recorder_object_->GetInterface(recorder_object_.Get(), | 242 recorder_object_->GetInterface(recorder_object_.Get(), |
218 SL_IID_ANDROIDCONFIGURATION, | 243 SL_IID_ANDROIDCONFIGURATION, |
219 &recorder_config), | 244 &recorder_config), |
220 false); | 245 false); |
221 | 246 |
247 // Uses the main microphone tuned for audio communications. | |
222 SLint32 stream_type = SL_ANDROID_RECORDING_PRESET_VOICE_COMMUNICATION; | 248 SLint32 stream_type = SL_ANDROID_RECORDING_PRESET_VOICE_COMMUNICATION; |
223 LOG_ON_FAILURE_AND_RETURN( | 249 LOG_ON_FAILURE_AND_RETURN( |
224 (*recorder_config)->SetConfiguration(recorder_config, | 250 (*recorder_config)->SetConfiguration(recorder_config, |
225 SL_ANDROID_KEY_RECORDING_PRESET, | 251 SL_ANDROID_KEY_RECORDING_PRESET, |
226 &stream_type, sizeof(SLint32)), | 252 &stream_type, |
253 sizeof(SLint32)), | |
227 false); | 254 false); |
228 | 255 |
229 // Realize the recorder object in synchronous mode. | 256 // Realize the recorder object in synchronous mode. |
230 LOG_ON_FAILURE_AND_RETURN( | 257 LOG_ON_FAILURE_AND_RETURN( |
231 recorder_object_->Realize(recorder_object_.Get(), | 258 recorder_object_->Realize(recorder_object_.Get(), SL_BOOLEAN_FALSE), |
232 SL_BOOLEAN_FALSE), | |
233 false); | 259 false); |
234 | 260 |
235 // Get an implicit recorder interface. | 261 // Get an implicit recorder interface. |
236 LOG_ON_FAILURE_AND_RETURN( | 262 LOG_ON_FAILURE_AND_RETURN( |
237 recorder_object_->GetInterface(recorder_object_.Get(), | 263 recorder_object_->GetInterface( |
238 SL_IID_RECORD, | 264 recorder_object_.Get(), SL_IID_RECORD, &recorder_), |
239 &recorder_), | |
240 false); | 265 false); |
241 | 266 |
242 // Get the simple buffer queue interface. | 267 // Get the simple buffer queue interface. |
243 LOG_ON_FAILURE_AND_RETURN( | 268 LOG_ON_FAILURE_AND_RETURN( |
244 recorder_object_->GetInterface(recorder_object_.Get(), | 269 recorder_object_->GetInterface(recorder_object_.Get(), |
245 SL_IID_ANDROIDSIMPLEBUFFERQUEUE, | 270 SL_IID_ANDROIDSIMPLEBUFFERQUEUE, |
246 &simple_buffer_queue_), | 271 &simple_buffer_queue_), |
247 false); | 272 false); |
248 | 273 |
249 // Register the input callback for the simple buffer queue. | 274 // Register the input callback for the simple buffer queue. |
250 // This callback will be called when receiving new data from the device. | 275 // This callback will be called when receiving new data from the device. |
251 LOG_ON_FAILURE_AND_RETURN( | 276 LOG_ON_FAILURE_AND_RETURN( |
252 (*simple_buffer_queue_)->RegisterCallback(simple_buffer_queue_, | 277 (*simple_buffer_queue_)->RegisterCallback( |
253 SimpleBufferQueueCallback, | 278 simple_buffer_queue_, SimpleBufferQueueCallback, this), |
254 this), | |
255 false); | 279 false); |
256 | 280 |
257 return true; | 281 return true; |
258 } | 282 } |
259 | 283 |
260 void OpenSLESInputStream::SimpleBufferQueueCallback( | 284 void OpenSLESInputStream::SimpleBufferQueueCallback( |
261 SLAndroidSimpleBufferQueueItf buffer_queue, void* instance) { | 285 SLAndroidSimpleBufferQueueItf buffer_queue, |
286 void* instance) { | |
262 OpenSLESInputStream* stream = | 287 OpenSLESInputStream* stream = |
263 reinterpret_cast<OpenSLESInputStream*>(instance); | 288 reinterpret_cast<OpenSLESInputStream*>(instance); |
264 stream->ReadBufferQueue(); | 289 stream->ReadBufferQueue(); |
265 } | 290 } |
266 | 291 |
267 void OpenSLESInputStream::ReadBufferQueue() { | 292 void OpenSLESInputStream::ReadBufferQueue() { |
293 base::AutoLock lock(lock_); | |
268 if (!started_) | 294 if (!started_) |
269 return; | 295 return; |
270 | 296 |
271 // TODO(xians): Get an accurate delay estimation. | 297 TRACE_EVENT0("audio", "OpenSLESOutputStream::ReadBufferQueue"); |
298 | |
299 // TODO(henrika): Investigate if it is possible to get an accurate | |
300 // delay estimation. | |
272 callback_->OnData(this, | 301 callback_->OnData(this, |
273 audio_data_[active_queue_], | 302 audio_data_[active_buffer_index_], |
274 buffer_size_bytes_, | 303 buffer_size_bytes_, |
275 buffer_size_bytes_, | 304 buffer_size_bytes_, |
276 0.0); | 305 0.0); |
277 | 306 |
278 // Done with this buffer. Send it to device for recording. | 307 // Done with this buffer. Send it to device for recording. |
279 SLresult err = (*simple_buffer_queue_)->Enqueue( | 308 err = (*simple_buffer_queue_)->Enqueue(simple_buffer_queue_, |
280 simple_buffer_queue_, | 309 audio_data_[active_buffer_index_], |
281 audio_data_[active_queue_], | 310 buffer_size_bytes_); |
282 buffer_size_bytes_); | |
283 if (SL_RESULT_SUCCESS != err) | 311 if (SL_RESULT_SUCCESS != err) |
284 HandleError(err); | 312 HandleError(err); |
285 | 313 |
286 active_queue_ = (active_queue_ + 1) % kNumOfQueuesInBuffer; | 314 active_buffer_index_ = (active_buffer_index_ + 1) % kMaxNumOfBuffersInQueue; |
287 } | 315 } |
288 | 316 |
289 void OpenSLESInputStream::SetupAudioBuffer() { | 317 void OpenSLESInputStream::SetupAudioBuffer() { |
318 DCHECK(thread_checker_.CalledOnValidThread()); | |
290 DCHECK(!audio_data_[0]); | 319 DCHECK(!audio_data_[0]); |
291 for (int i = 0; i < kNumOfQueuesInBuffer; ++i) { | 320 for (int i = 0; i < kMaxNumOfBuffersInQueue; ++i) { |
292 audio_data_[i] = new uint8[buffer_size_bytes_]; | 321 audio_data_[i] = new uint8[buffer_size_bytes_]; |
293 } | 322 } |
294 } | 323 } |
295 | 324 |
296 void OpenSLESInputStream::ReleaseAudioBuffer() { | 325 void OpenSLESInputStream::ReleaseAudioBuffer() { |
326 DCHECK(thread_checker_.CalledOnValidThread()); | |
297 if (audio_data_[0]) { | 327 if (audio_data_[0]) { |
298 for (int i = 0; i < kNumOfQueuesInBuffer; ++i) { | 328 for (int i = 0; i < kMaxNumOfBuffersInQueue; ++i) { |
299 delete [] audio_data_[i]; | 329 delete[] audio_data_[i]; |
300 audio_data_[i] = NULL; | 330 audio_data_[i] = NULL; |
301 } | 331 } |
302 } | 332 } |
303 } | 333 } |
304 | 334 |
305 void OpenSLESInputStream::HandleError(SLresult error) { | 335 void OpenSLESInputStream::HandleError(SLresult error) { |
306 DLOG(FATAL) << "OpenSLES Input error " << error; | 336 DLOG(ERROR) << "OpenSLES Input error " << error; |
307 if (callback_) | 337 if (callback_) |
308 callback_->OnError(this); | 338 callback_->OnError(this); |
309 } | 339 } |
310 | 340 |
311 } // namespace media | 341 } // namespace media |
OLD | NEW |