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

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: add opensles_outtput.h 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
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
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 callback_ = callback; 72 callback_ = callback;
73 active_queue_ = 0; 73 active_queue_ = 0;
74 started_ = true; 74 started_ = true;
75 75
76 // Avoid start-up glitches by filling up one buffer queue before starting 76 // Avoid start-up glitches by filling up one buffer queue before starting
77 // the stream. 77 // the stream.
78 FillBufferQueue(); 78 FillBufferQueue();
79 79
80 // Start streaming data by setting the play state to |SL_PLAYSTATE_PLAYING|. 80 // Start streaming data by setting the play state to |SL_PLAYSTATE_PLAYING|.
81 SLresult err = (*player_)->SetPlayState(player_, SL_PLAYSTATE_PLAYING); 81 SLresult err = (*player_)->SetPlayState(player_, SL_PLAYSTATE_PLAYING);
82 DCHECK_EQ(SL_RESULT_SUCCESS, err);
83 if (SL_RESULT_SUCCESS != err) { 82 if (SL_RESULT_SUCCESS != err) {
84 DLOG(WARNING) << "SetPlayState() failed to start playing"; 83 DLOG(WARNING) << "SetPlayState() failed to start playing";
Ami GONE FROM CHROMIUM 2013/03/22 16:24:41 Why is this a WARNING when the rest of the failure
85 } 84 }
86 } 85 }
87 86
88 void OpenSLESOutputStream::Stop() { 87 void OpenSLESOutputStream::Stop() {
89 if (!started_) 88 if (!started_)
90 return; 89 return;
91 90
92 started_ = false; 91 started_ = false;
93 // Stop playing by setting the play state to |SL_PLAYSTATE_STOPPED|. 92 // Stop playing by setting the play state to |SL_PLAYSTATE_STOPPED|.
94 SLresult err = (*player_)->SetPlayState(player_, SL_PLAYSTATE_STOPPED); 93 SLresult err = (*player_)->SetPlayState(player_, SL_PLAYSTATE_STOPPED);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 } 133 }
135 134
136 bool OpenSLESOutputStream::CreatePlayer() { 135 bool OpenSLESOutputStream::CreatePlayer() {
137 // Initializes the engine object with specific option. After working with the 136 // Initializes the engine object with specific option. After working with the
138 // object, we need to free the object and its resources. 137 // object, we need to free the object and its resources.
139 SLEngineOption option[] = { 138 SLEngineOption option[] = {
140 { SL_ENGINEOPTION_THREADSAFE, static_cast<SLuint32>(SL_BOOLEAN_TRUE) } 139 { SL_ENGINEOPTION_THREADSAFE, static_cast<SLuint32>(SL_BOOLEAN_TRUE) }
141 }; 140 };
142 SLresult err = slCreateEngine(engine_object_.Receive(), 1, option, 0, 141 SLresult err = slCreateEngine(engine_object_.Receive(), 1, option, 0,
143 NULL, NULL); 142 NULL, NULL);
144 DCHECK_EQ(SL_RESULT_SUCCESS, err); 143 if (SL_RESULT_SUCCESS != err) {
145 if (SL_RESULT_SUCCESS != err) 144 DLOG(ERROR) << "CreatePlayer slCreateEngine: " << err;
Ami GONE FROM CHROMIUM 2013/03/22 16:24:41 When there is this much duplicated code, it's usua
leozwang1 2013/03/23 07:00:39 Done.
146 return false; 145 return false;
146 }
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 err = engine_object_->Realize(engine_object_.Get(), SL_BOOLEAN_FALSE);
150 DCHECK_EQ(SL_RESULT_SUCCESS, err); 150 if (SL_RESULT_SUCCESS != err) {
151 if (SL_RESULT_SUCCESS != err) 151 DLOG(ERROR) << "CreatePlayer Realize: " << err;
152 return false; 152 return false;
153 }
153 154
154 // Get the SL engine interface which is implicit. 155 // Get the SL engine interface which is implicit.
155 SLEngineItf engine; 156 SLEngineItf engine;
156 err = engine_object_->GetInterface(engine_object_.Get(), 157 err = engine_object_->GetInterface(engine_object_.Get(),
157 SL_IID_ENGINE, 158 SL_IID_ENGINE,
158 &engine); 159 &engine);
159 DCHECK_EQ(SL_RESULT_SUCCESS, err); 160 if (SL_RESULT_SUCCESS != err) {
160 if (SL_RESULT_SUCCESS != err) 161 DLOG(ERROR) << "GetInterface(SL_IID_ENGINE): " << err;
Ami GONE FROM CHROMIUM 2013/03/22 16:24:41 These log messages are pretty inconsistent; some h
leozwang1 2013/03/23 07:00:39 Done.
161 return false; 162 return false;
163 }
162 164
163 // Create ouput mixer object to be used by the player. 165 // Create ouput mixer object to be used by the player.
164 // TODO(xians): Do we need the environmental reverb auxiliary effect? 166 // TODO(xians): Do we need the environmental reverb auxiliary effect?
165 err = (*engine)->CreateOutputMix(engine, 167 err = (*engine)->CreateOutputMix(engine,
166 output_mixer_.Receive(), 168 output_mixer_.Receive(),
167 0, 169 0,
168 NULL, 170 NULL,
169 NULL); 171 NULL);
170 DCHECK_EQ(SL_RESULT_SUCCESS, err); 172 if (SL_RESULT_SUCCESS != err) {
171 if (SL_RESULT_SUCCESS != err) 173 DLOG(ERROR) << "CreateOutputMix: " << err;
172 return false; 174 return false;
175 }
173 176
174 // Realizing the output mix object in synchronous mode. 177 // Realizing the output mix object in synchronous mode.
175 err = output_mixer_->Realize(output_mixer_.Get(), SL_BOOLEAN_FALSE); 178 err = output_mixer_->Realize(output_mixer_.Get(), SL_BOOLEAN_FALSE);
176 DCHECK_EQ(SL_RESULT_SUCCESS, err); 179 if (SL_RESULT_SUCCESS != err) {
177 if (SL_RESULT_SUCCESS != err) 180 DLOG(ERROR) << "mixer Realize: " << err;
178 return false; 181 return false;
182 }
179 183
180 // Audio source configuration. 184 // Audio source configuration.
181 SLDataLocator_AndroidSimpleBufferQueue simple_buffer_queue = { 185 SLDataLocator_AndroidSimpleBufferQueue simple_buffer_queue = {
182 SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 186 SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
183 static_cast<SLuint32>(kNumOfQueuesInBuffer) 187 static_cast<SLuint32>(kNumOfQueuesInBuffer)
184 }; 188 };
185 SLDataSource audio_source = { &simple_buffer_queue, &format_ }; 189 SLDataSource audio_source = { &simple_buffer_queue, &format_ };
186 190
187 // Audio sink configuration. 191 // Audio sink configuration.
188 SLDataLocator_OutputMix locator_output_mix = { 192 SLDataLocator_OutputMix locator_output_mix = {
189 SL_DATALOCATOR_OUTPUTMIX, output_mixer_.Get() 193 SL_DATALOCATOR_OUTPUTMIX, output_mixer_.Get()
190 }; 194 };
191 SLDataSink audio_sink = { &locator_output_mix, NULL }; 195 SLDataSink audio_sink = { &locator_output_mix, NULL };
192 196
193 // Create an audio player. 197 // Create an audio player.
194 const SLuint32 number_of_interfaces = 1; 198 const SLInterfaceID interface_id[] = {
195 const SLInterfaceID interface_id[number_of_interfaces] = { 199 SL_IID_BUFFERQUEUE,
196 SL_IID_BUFFERQUEUE 200 SL_IID_VOLUME,
201 SL_IID_ANDROIDCONFIGURATION
197 }; 202 };
203 const SLuint32 number_of_interfaces = arraysize(interface_id);
Ami GONE FROM CHROMIUM 2013/03/22 16:24:41 inline into call below.
198 const SLboolean interface_required[number_of_interfaces] = { 204 const SLboolean interface_required[number_of_interfaces] = {
Ami GONE FROM CHROMIUM 2013/03/22 16:24:41 drop number_of_interfaces
leozwang1 2013/03/22 21:37:09 Done.
205 SL_BOOLEAN_TRUE,
206 SL_BOOLEAN_TRUE,
199 SL_BOOLEAN_TRUE 207 SL_BOOLEAN_TRUE
200 }; 208 };
201 err = (*engine)->CreateAudioPlayer(engine, 209 err = (*engine)->CreateAudioPlayer(engine,
202 player_object_.Receive(), 210 player_object_.Receive(),
203 &audio_source, 211 &audio_source,
204 &audio_sink, 212 &audio_sink,
205 number_of_interfaces, 213 number_of_interfaces,
206 interface_id, 214 interface_id,
207 interface_required); 215 interface_required);
208 DCHECK_EQ(SL_RESULT_SUCCESS, err);
209 if (SL_RESULT_SUCCESS != err) { 216 if (SL_RESULT_SUCCESS != err) {
210 DLOG(ERROR) << "CreateAudioPlayer() failed with error code " << err; 217 DLOG(ERROR) << "CreateAudioPlayer() failed with error code " << err;
211 return false; 218 return false;
212 } 219 }
213 220
221 // Create AudioPlayer and specify SL_IID_ANDROIDCONFIGURATION.
222 SLAndroidConfigurationItf player_config;
223 err = player_object_->GetInterface(player_object_.Get(),
224 SL_IID_ANDROIDCONFIGURATION,
225 &player_config);
226 if (SL_RESULT_SUCCESS != err) {
227 DLOG(ERROR) << "GetInterface(SL_IID_ANDROIDCONFIGURATION): " << err;
228 return false;
229 }
230
231 SLint32 stream_type = SL_ANDROID_STREAM_VOICE;
Ami GONE FROM CHROMIUM 2013/03/22 16:24:41 this variable is obscuring what the call below act
Ami GONE FROM CHROMIUM 2013/03/22 16:24:41 This seems to be the heart of the potential proble
leozwang1 2013/03/22 21:37:09 It's my concern too, we're going to do some tests.
Ami GONE FROM CHROMIUM 2013/03/22 22:29:55 I don't think you'd want to make the stream contai
leozwang1 2013/03/22 22:44:48 can you teach me how this "global state button (mi
Ami GONE FROM CHROMIUM 2013/03/22 23:34:20 I just mean that the toggle of what global mode to
232 err = (*player_config)->SetConfiguration(player_config,
233 SL_ANDROID_KEY_STREAM_TYPE,
234 &stream_type, sizeof(SLint32));
235 if (SL_RESULT_SUCCESS != err) {
236 DLOG(ERROR) << "SetConfiguration(SL_ANDROID_STREAM_VOICE): " << err;
237 return false;
238 }
239
214 // Realize the player object in synchronous mode. 240 // Realize the player object in synchronous mode.
215 err = player_object_->Realize(player_object_.Get(), SL_BOOLEAN_FALSE); 241 err = player_object_->Realize(player_object_.Get(), SL_BOOLEAN_FALSE);
216 DCHECK_EQ(SL_RESULT_SUCCESS, err);
217 if (SL_RESULT_SUCCESS != err) { 242 if (SL_RESULT_SUCCESS != err) {
218 DLOG(ERROR) << "Player Realize() failed with error code " << err; 243 DLOG(ERROR) << "Player Realize() failed with error code " << err;
219 return false; 244 return false;
220 } 245 }
221 246
222 // Get an implicit player interface. 247 // Get an implicit player interface.
223 err = player_object_->GetInterface( 248 err = player_object_->GetInterface(
224 player_object_.Get(), SL_IID_PLAY, &player_); 249 player_object_.Get(), SL_IID_PLAY, &player_);
225 DCHECK_EQ(SL_RESULT_SUCCESS, err); 250 if (SL_RESULT_SUCCESS != err) {
226 if (SL_RESULT_SUCCESS != err) 251 DLOG(ERROR) << "GetInterface(SL_IID_PLAYN): " << err;
227 return false; 252 return false;
253 }
228 254
229 // Get the simple buffer queue interface. 255 // Get the simple buffer queue interface.
230 err = player_object_->GetInterface(player_object_.Get(), 256 err = player_object_->GetInterface(player_object_.Get(),
231 SL_IID_BUFFERQUEUE, 257 SL_IID_BUFFERQUEUE,
232 &simple_buffer_queue_); 258 &simple_buffer_queue_);
233 DCHECK_EQ(SL_RESULT_SUCCESS, err); 259 if (SL_RESULT_SUCCESS != err) {
234 if (SL_RESULT_SUCCESS != err) 260 DLOG(ERROR) << "GetInterface(SL_IID_BUFFERQUEUE): " << err;
235 return false; 261 return false;
262 }
236 263
237 // Register the input callback for the simple buffer queue. 264 // Register the input callback for the simple buffer queue.
238 // This callback will be called when the soundcard needs data. 265 // This callback will be called when the soundcard needs data.
239 err = (*simple_buffer_queue_)->RegisterCallback(simple_buffer_queue_, 266 err = (*simple_buffer_queue_)->RegisterCallback(simple_buffer_queue_,
240 SimpleBufferQueueCallback, 267 SimpleBufferQueueCallback,
241 this); 268 this);
242 DCHECK_EQ(SL_RESULT_SUCCESS, err); 269 if (SL_RESULT_SUCCESS != err) {
270 DLOG(ERROR) << "AudioPlayer RegisterCallback: " << err;
271 return false;
272 }
243 273
244 return (SL_RESULT_SUCCESS == err); 274 return true;
245 } 275 }
246 276
247 void OpenSLESOutputStream::SimpleBufferQueueCallback( 277 void OpenSLESOutputStream::SimpleBufferQueueCallback(
248 SLAndroidSimpleBufferQueueItf buffer_queue, void* instance) { 278 SLAndroidSimpleBufferQueueItf buffer_queue, void* instance) {
249 OpenSLESOutputStream* stream = 279 OpenSLESOutputStream* stream =
250 reinterpret_cast<OpenSLESOutputStream*>(instance); 280 reinterpret_cast<OpenSLESOutputStream*>(instance);
251 stream->FillBufferQueue(); 281 stream->FillBufferQueue();
252 } 282 }
253 283
254 void OpenSLESOutputStream::FillBufferQueue() { 284 void OpenSLESOutputStream::FillBufferQueue() {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 } 334 }
305 } 335 }
306 336
307 void OpenSLESOutputStream::HandleError(SLresult error) { 337 void OpenSLESOutputStream::HandleError(SLresult error) {
308 DLOG(ERROR) << "OpenSLES error " << error; 338 DLOG(ERROR) << "OpenSLES error " << error;
309 if (callback_) 339 if (callback_)
310 callback_->OnError(this, error); 340 callback_->OnError(this, error);
311 } 341 }
312 342
313 } // namespace media 343 } // namespace media
OLDNEW
« media/audio/android/opensles_output.h ('K') | « media/audio/android/opensles_output.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698