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

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

Issue 12806009: Add OpenSL configurations (Closed) Base URL: https://src.chromium.org/svn/trunk/src/
Patch Set: moved macro Created 7 years, 9 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
« no previous file with comments | « media/audio/android/opensles_output.h ('k') | media/audio/android/opensles_util.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/opensles_output.h" 5 #include "media/audio/android/opensles_output.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "media/audio/audio_util.h" 8 #include "media/audio/audio_util.h"
9 #include "media/audio/android/audio_manager_android.h" 9 #include "media/audio/android/audio_manager_android.h"
10 10
11 #define LOG_ON_FAILURE_AND_RETURN(op, ...) \
12 do { \
13 SLresult err = (op); \
14 if (err != SL_RESULT_SUCCESS) { \
15 DLOG(ERROR) << #op << " failed: " << err; \
16 return __VA_ARGS__; \
17 } \
18 } while (0)
19
11 namespace media { 20 namespace media {
12 21
13 OpenSLESOutputStream::OpenSLESOutputStream(AudioManagerAndroid* manager, 22 OpenSLESOutputStream::OpenSLESOutputStream(AudioManagerAndroid* manager,
14 const AudioParameters& params) 23 const AudioParameters& params)
15 : audio_manager_(manager), 24 : audio_manager_(manager),
16 callback_(NULL), 25 callback_(NULL),
17 player_(NULL), 26 player_(NULL),
18 simple_buffer_queue_(NULL), 27 simple_buffer_queue_(NULL),
19 active_queue_(0), 28 active_queue_(0),
20 buffer_size_bytes_(0), 29 buffer_size_bytes_(0),
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 // Enable the flags before streaming. 80 // Enable the flags before streaming.
72 callback_ = callback; 81 callback_ = callback;
73 active_queue_ = 0; 82 active_queue_ = 0;
74 started_ = true; 83 started_ = true;
75 84
76 // Avoid start-up glitches by filling up one buffer queue before starting 85 // Avoid start-up glitches by filling up one buffer queue before starting
77 // the stream. 86 // the stream.
78 FillBufferQueue(); 87 FillBufferQueue();
79 88
80 // Start streaming data by setting the play state to |SL_PLAYSTATE_PLAYING|. 89 // Start streaming data by setting the play state to |SL_PLAYSTATE_PLAYING|.
81 SLresult err = (*player_)->SetPlayState(player_, SL_PLAYSTATE_PLAYING); 90 LOG_ON_FAILURE_AND_RETURN(
82 DCHECK_EQ(SL_RESULT_SUCCESS, err); 91 (*player_)->SetPlayState(player_, SL_PLAYSTATE_PLAYING));
83 if (SL_RESULT_SUCCESS != err) {
84 DLOG(WARNING) << "SetPlayState() failed to start playing";
85 }
86 } 92 }
87 93
88 void OpenSLESOutputStream::Stop() { 94 void OpenSLESOutputStream::Stop() {
89 if (!started_) 95 if (!started_)
90 return; 96 return;
91 97
92 started_ = false; 98 started_ = false;
93 // Stop playing by setting the play state to |SL_PLAYSTATE_STOPPED|. 99 // Stop playing by setting the play state to |SL_PLAYSTATE_STOPPED|.
94 SLresult err = (*player_)->SetPlayState(player_, SL_PLAYSTATE_STOPPED); 100 LOG_ON_FAILURE_AND_RETURN(
95 if (SL_RESULT_SUCCESS != err) { 101 (*player_)->SetPlayState(player_, SL_PLAYSTATE_STOPPED));
96 DLOG(WARNING) << "SetPlayState() failed to set the state to stop";
97 }
98 102
99 // Clear the buffer queue so that the old data won't be played when 103 // Clear the buffer queue so that the old data won't be played when
100 // resuming playing. 104 // resuming playing.
101 err = (*simple_buffer_queue_)->Clear(simple_buffer_queue_); 105 LOG_ON_FAILURE_AND_RETURN(
102 if (SL_RESULT_SUCCESS != err) { 106 (*simple_buffer_queue_)->Clear(simple_buffer_queue_));
103 DLOG(WARNING) << "Clear() failed to clear the buffer queue";
104 }
105 } 107 }
106 108
107 void OpenSLESOutputStream::Close() { 109 void OpenSLESOutputStream::Close() {
108 // Stop the stream if it is still playing. 110 // Stop the stream if it is still playing.
109 Stop(); 111 Stop();
110 112
111 // Explicitly free the player objects and invalidate their associated 113 // Explicitly free the player objects and invalidate their associated
112 // interfaces. They have to be done in the correct order. 114 // interfaces. They have to be done in the correct order.
113 output_mixer_.Reset(); 115 output_mixer_.Reset();
114 player_object_.Reset(); 116 player_object_.Reset();
(...skipping 17 matching lines...) Expand all
132 void OpenSLESOutputStream::GetVolume(double* volume) { 134 void OpenSLESOutputStream::GetVolume(double* volume) {
133 *volume = static_cast<double>(volume_); 135 *volume = static_cast<double>(volume_);
134 } 136 }
135 137
136 bool OpenSLESOutputStream::CreatePlayer() { 138 bool OpenSLESOutputStream::CreatePlayer() {
137 // Initializes the engine object with specific option. After working with the 139 // Initializes the engine object with specific option. After working with the
138 // object, we need to free the object and its resources. 140 // object, we need to free the object and its resources.
139 SLEngineOption option[] = { 141 SLEngineOption option[] = {
140 { SL_ENGINEOPTION_THREADSAFE, static_cast<SLuint32>(SL_BOOLEAN_TRUE) } 142 { SL_ENGINEOPTION_THREADSAFE, static_cast<SLuint32>(SL_BOOLEAN_TRUE) }
141 }; 143 };
142 SLresult err = slCreateEngine(engine_object_.Receive(), 1, option, 0, 144 LOG_ON_FAILURE_AND_RETURN(
143 NULL, NULL); 145 slCreateEngine(engine_object_.Receive(), 1, option, 0, NULL, NULL),
144 DCHECK_EQ(SL_RESULT_SUCCESS, err); 146 false);
145 if (SL_RESULT_SUCCESS != err)
146 return false;
147 147
148 // Realize the SL engine object in synchronous mode. 148 // Realize the SL engine object in synchronous mode.
149 err = engine_object_->Realize(engine_object_.Get(), SL_BOOLEAN_FALSE); 149 LOG_ON_FAILURE_AND_RETURN(
150 DCHECK_EQ(SL_RESULT_SUCCESS, err); 150 engine_object_->Realize(engine_object_.Get(), SL_BOOLEAN_FALSE),
151 if (SL_RESULT_SUCCESS != err) 151 false);
152 return false;
153 152
154 // Get the SL engine interface which is implicit. 153 // Get the SL engine interface which is implicit.
155 SLEngineItf engine; 154 SLEngineItf engine;
156 err = engine_object_->GetInterface(engine_object_.Get(), 155 LOG_ON_FAILURE_AND_RETURN(
157 SL_IID_ENGINE, 156 engine_object_->GetInterface(engine_object_.Get(),
158 &engine); 157 SL_IID_ENGINE,
159 DCHECK_EQ(SL_RESULT_SUCCESS, err); 158 &engine),
160 if (SL_RESULT_SUCCESS != err) 159 false);
161 return false;
162 160
163 // Create ouput mixer object to be used by the player. 161 // Create ouput mixer object to be used by the player.
164 // TODO(xians): Do we need the environmental reverb auxiliary effect? 162 LOG_ON_FAILURE_AND_RETURN(
165 err = (*engine)->CreateOutputMix(engine, 163 (*engine)->CreateOutputMix(engine,
166 output_mixer_.Receive(), 164 output_mixer_.Receive(),
167 0, 165 0,
168 NULL, 166 NULL,
169 NULL); 167 NULL),
170 DCHECK_EQ(SL_RESULT_SUCCESS, err); 168 false);
171 if (SL_RESULT_SUCCESS != err)
172 return false;
173 169
174 // Realizing the output mix object in synchronous mode. 170 // Realizing the output mix object in synchronous mode.
175 err = output_mixer_->Realize(output_mixer_.Get(), SL_BOOLEAN_FALSE); 171 LOG_ON_FAILURE_AND_RETURN(
176 DCHECK_EQ(SL_RESULT_SUCCESS, err); 172 output_mixer_->Realize(output_mixer_.Get(), SL_BOOLEAN_FALSE),
177 if (SL_RESULT_SUCCESS != err) 173 false);
178 return false;
179 174
180 // Audio source configuration. 175 // Audio source configuration.
181 SLDataLocator_AndroidSimpleBufferQueue simple_buffer_queue = { 176 SLDataLocator_AndroidSimpleBufferQueue simple_buffer_queue = {
182 SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 177 SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
183 static_cast<SLuint32>(kNumOfQueuesInBuffer) 178 static_cast<SLuint32>(kNumOfQueuesInBuffer)
184 }; 179 };
185 SLDataSource audio_source = { &simple_buffer_queue, &format_ }; 180 SLDataSource audio_source = { &simple_buffer_queue, &format_ };
186 181
187 // Audio sink configuration. 182 // Audio sink configuration.
188 SLDataLocator_OutputMix locator_output_mix = { 183 SLDataLocator_OutputMix locator_output_mix = {
189 SL_DATALOCATOR_OUTPUTMIX, output_mixer_.Get() 184 SL_DATALOCATOR_OUTPUTMIX, output_mixer_.Get()
190 }; 185 };
191 SLDataSink audio_sink = { &locator_output_mix, NULL }; 186 SLDataSink audio_sink = { &locator_output_mix, NULL };
192 187
193 // Create an audio player. 188 // Create an audio player.
194 const SLuint32 number_of_interfaces = 1; 189 const SLInterfaceID interface_id[] = {
195 const SLInterfaceID interface_id[number_of_interfaces] = { 190 SL_IID_BUFFERQUEUE,
196 SL_IID_BUFFERQUEUE 191 SL_IID_VOLUME,
192 SL_IID_ANDROIDCONFIGURATION
197 }; 193 };
198 const SLboolean interface_required[number_of_interfaces] = { 194 const SLboolean interface_required[] = {
195 SL_BOOLEAN_TRUE,
196 SL_BOOLEAN_TRUE,
199 SL_BOOLEAN_TRUE 197 SL_BOOLEAN_TRUE
200 }; 198 };
201 err = (*engine)->CreateAudioPlayer(engine, 199 LOG_ON_FAILURE_AND_RETURN(
202 player_object_.Receive(), 200 (*engine)->CreateAudioPlayer(engine,
203 &audio_source, 201 player_object_.Receive(),
204 &audio_sink, 202 &audio_source,
205 number_of_interfaces, 203 &audio_sink,
206 interface_id, 204 arraysize(interface_id),
207 interface_required); 205 interface_id,
208 DCHECK_EQ(SL_RESULT_SUCCESS, err); 206 interface_required),
209 if (SL_RESULT_SUCCESS != err) { 207 false);
210 DLOG(ERROR) << "CreateAudioPlayer() failed with error code " << err; 208
211 return false; 209 // Create AudioPlayer and specify SL_IID_ANDROIDCONFIGURATION.
212 } 210 SLAndroidConfigurationItf player_config;
211 LOG_ON_FAILURE_AND_RETURN(
212 player_object_->GetInterface(player_object_.Get(),
213 SL_IID_ANDROIDCONFIGURATION,
214 &player_config),
215 false);
216
217 SLint32 stream_type = SL_ANDROID_STREAM_VOICE;
218 LOG_ON_FAILURE_AND_RETURN(
219 (*player_config)->SetConfiguration(player_config,
220 SL_ANDROID_KEY_STREAM_TYPE,
221 &stream_type, sizeof(SLint32)),
222 false);
213 223
214 // Realize the player object in synchronous mode. 224 // Realize the player object in synchronous mode.
215 err = player_object_->Realize(player_object_.Get(), SL_BOOLEAN_FALSE); 225 LOG_ON_FAILURE_AND_RETURN(
216 DCHECK_EQ(SL_RESULT_SUCCESS, err); 226 player_object_->Realize(player_object_.Get(), SL_BOOLEAN_FALSE),
217 if (SL_RESULT_SUCCESS != err) { 227 false);
218 DLOG(ERROR) << "Player Realize() failed with error code " << err;
219 return false;
220 }
221 228
222 // Get an implicit player interface. 229 // Get an implicit player interface.
223 err = player_object_->GetInterface( 230 LOG_ON_FAILURE_AND_RETURN(
224 player_object_.Get(), SL_IID_PLAY, &player_); 231 player_object_->GetInterface(player_object_.Get(), SL_IID_PLAY, &player_),
225 DCHECK_EQ(SL_RESULT_SUCCESS, err); 232 false);
226 if (SL_RESULT_SUCCESS != err)
227 return false;
228 233
229 // Get the simple buffer queue interface. 234 // Get the simple buffer queue interface.
230 err = player_object_->GetInterface(player_object_.Get(), 235 LOG_ON_FAILURE_AND_RETURN(
231 SL_IID_BUFFERQUEUE, 236 player_object_->GetInterface(player_object_.Get(),
232 &simple_buffer_queue_); 237 SL_IID_BUFFERQUEUE,
233 DCHECK_EQ(SL_RESULT_SUCCESS, err); 238 &simple_buffer_queue_),
234 if (SL_RESULT_SUCCESS != err) 239 false);
235 return false;
236 240
237 // Register the input callback for the simple buffer queue. 241 // Register the input callback for the simple buffer queue.
238 // This callback will be called when the soundcard needs data. 242 // This callback will be called when the soundcard needs data.
239 err = (*simple_buffer_queue_)->RegisterCallback(simple_buffer_queue_, 243 LOG_ON_FAILURE_AND_RETURN(
240 SimpleBufferQueueCallback, 244 (*simple_buffer_queue_)->RegisterCallback(simple_buffer_queue_,
241 this); 245 SimpleBufferQueueCallback,
242 DCHECK_EQ(SL_RESULT_SUCCESS, err); 246 this),
247 false);
243 248
244 return (SL_RESULT_SUCCESS == err); 249 return true;
245 } 250 }
246 251
247 void OpenSLESOutputStream::SimpleBufferQueueCallback( 252 void OpenSLESOutputStream::SimpleBufferQueueCallback(
248 SLAndroidSimpleBufferQueueItf buffer_queue, void* instance) { 253 SLAndroidSimpleBufferQueueItf buffer_queue, void* instance) {
249 OpenSLESOutputStream* stream = 254 OpenSLESOutputStream* stream =
250 reinterpret_cast<OpenSLESOutputStream*>(instance); 255 reinterpret_cast<OpenSLESOutputStream*>(instance);
251 stream->FillBufferQueue(); 256 stream->FillBufferQueue();
252 } 257 }
253 258
254 void OpenSLESOutputStream::FillBufferQueue() { 259 void OpenSLESOutputStream::FillBufferQueue() {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 void OpenSLESOutputStream::ReleaseAudioBuffer() { 303 void OpenSLESOutputStream::ReleaseAudioBuffer() {
299 if (audio_data_[0]) { 304 if (audio_data_[0]) {
300 for (int i = 0; i < kNumOfQueuesInBuffer; ++i) { 305 for (int i = 0; i < kNumOfQueuesInBuffer; ++i) {
301 delete [] audio_data_[i]; 306 delete [] audio_data_[i];
302 audio_data_[i] = NULL; 307 audio_data_[i] = NULL;
303 } 308 }
304 } 309 }
305 } 310 }
306 311
307 void OpenSLESOutputStream::HandleError(SLresult error) { 312 void OpenSLESOutputStream::HandleError(SLresult error) {
308 DLOG(ERROR) << "OpenSLES error " << error; 313 DLOG(ERROR) << "OpenSLES Output error " << error;
309 if (callback_) 314 if (callback_)
310 callback_->OnError(this, error); 315 callback_->OnError(this, error);
311 } 316 }
312 317
313 } // namespace media 318 } // namespace media
OLDNEW
« no previous file with comments | « media/audio/android/opensles_output.h ('k') | media/audio/android/opensles_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698