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

Side by Side Diff: webrtc/modules/audio_device/android/opensles_player.cc

Issue 2410033002: AudioTransport::NeedMorePlayData is no longer called from different threads using OpenSL ES on Andr… (Closed)
Patch Set: Created 4 years, 2 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 | « webrtc/modules/audio_device/android/opensles_player.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 } 113 }
114 // The number of lower latency audio players is limited, hence we create the 114 // The number of lower latency audio players is limited, hence we create the
115 // audio player in Start() and destroy it in Stop(). 115 // audio player in Start() and destroy it in Stop().
116 CreateAudioPlayer(); 116 CreateAudioPlayer();
117 // Fill up audio buffers to avoid initial glitch and to ensure that playback 117 // Fill up audio buffers to avoid initial glitch and to ensure that playback
118 // starts when mode is later changed to SL_PLAYSTATE_PLAYING. 118 // starts when mode is later changed to SL_PLAYSTATE_PLAYING.
119 // TODO(henrika): we can save some delay by only making one call to 119 // TODO(henrika): we can save some delay by only making one call to
120 // EnqueuePlayoutData. Most likely not worth the risk of adding a glitch. 120 // EnqueuePlayoutData. Most likely not worth the risk of adding a glitch.
121 last_play_time_ = rtc::Time(); 121 last_play_time_ = rtc::Time();
122 for (int i = 0; i < kNumOfOpenSLESBuffers; ++i) { 122 for (int i = 0; i < kNumOfOpenSLESBuffers; ++i) {
123 EnqueuePlayoutData(); 123 EnqueuePlayoutData(true);
124 } 124 }
125 // Start streaming data by setting the play state to SL_PLAYSTATE_PLAYING. 125 // Start streaming data by setting the play state to SL_PLAYSTATE_PLAYING.
126 // For a player object, when the object is in the SL_PLAYSTATE_PLAYING 126 // For a player object, when the object is in the SL_PLAYSTATE_PLAYING
127 // state, adding buffers will implicitly start playback. 127 // state, adding buffers will implicitly start playback.
128 RETURN_ON_ERROR((*player_)->SetPlayState(player_, SL_PLAYSTATE_PLAYING), -1); 128 RETURN_ON_ERROR((*player_)->SetPlayState(player_, SL_PLAYSTATE_PLAYING), -1);
129 playing_ = (GetPlayState() == SL_PLAYSTATE_PLAYING); 129 playing_ = (GetPlayState() == SL_PLAYSTATE_PLAYING);
130 RTC_DCHECK(playing_); 130 RTC_DCHECK(playing_);
131 return 0; 131 return 0;
132 } 132 }
133 133
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 stream->FillBufferQueue(); 369 stream->FillBufferQueue();
370 } 370 }
371 371
372 void OpenSLESPlayer::FillBufferQueue() { 372 void OpenSLESPlayer::FillBufferQueue() {
373 RTC_DCHECK(thread_checker_opensles_.CalledOnValidThread()); 373 RTC_DCHECK(thread_checker_opensles_.CalledOnValidThread());
374 SLuint32 state = GetPlayState(); 374 SLuint32 state = GetPlayState();
375 if (state != SL_PLAYSTATE_PLAYING) { 375 if (state != SL_PLAYSTATE_PLAYING) {
376 ALOGW("Buffer callback in non-playing state!"); 376 ALOGW("Buffer callback in non-playing state!");
377 return; 377 return;
378 } 378 }
379 EnqueuePlayoutData(); 379 EnqueuePlayoutData(false);
380 } 380 }
381 381
382 void OpenSLESPlayer::EnqueuePlayoutData() { 382 void OpenSLESPlayer::EnqueuePlayoutData(bool silence) {
383 // Check delta time between two successive callbacks and provide a warning 383 // Check delta time between two successive callbacks and provide a warning
384 // if it becomes very large. 384 // if it becomes very large.
385 // TODO(henrika): using 150ms as upper limit but this value is rather random. 385 // TODO(henrika): using 150ms as upper limit but this value is rather random.
386 const uint32_t current_time = rtc::Time(); 386 const uint32_t current_time = rtc::Time();
387 const uint32_t diff = current_time - last_play_time_; 387 const uint32_t diff = current_time - last_play_time_;
388 if (diff > 150) { 388 if (diff > 150) {
389 ALOGW("Bad OpenSL ES playout timing, dT=%u [ms]", diff); 389 ALOGW("Bad OpenSL ES playout timing, dT=%u [ms]", diff);
390 } 390 }
391 last_play_time_ = current_time; 391 last_play_time_ = current_time;
392 // Read audio data from the WebRTC source using the FineAudioBuffer object
393 // to adjust for differences in buffer size between WebRTC (10ms) and native
394 // OpenSL ES.
395 SLint8* audio_ptr = audio_buffers_[buffer_index_].get(); 392 SLint8* audio_ptr = audio_buffers_[buffer_index_].get();
396 fine_audio_buffer_->GetPlayoutData(audio_ptr); 393 if (silence) {
394 RTC_DCHECK(thread_checker_.CalledOnValidThread());
395 // Avoid aquiring real audio data from WebRTC and fill the buffer with
396 // zeros instead. Used to prime the buffer with silence and to avoid asking
397 // for audio data from two different threads.
398 memset(audio_ptr, 0, audio_parameters_.GetBytesPerBuffer());
399 } else {
400 RTC_DCHECK(thread_checker_opensles_.CalledOnValidThread());
401 // Read audio data from the WebRTC source using the FineAudioBuffer object
402 // to adjust for differences in buffer size between WebRTC (10ms) and native
403 // OpenSL ES.
404 fine_audio_buffer_->GetPlayoutData(audio_ptr);
405 }
397 // Enqueue the decoded audio buffer for playback. 406 // Enqueue the decoded audio buffer for playback.
398 SLresult err = (*simple_buffer_queue_) 407 SLresult err = (*simple_buffer_queue_)
399 ->Enqueue(simple_buffer_queue_, audio_ptr, 408 ->Enqueue(simple_buffer_queue_, audio_ptr,
400 audio_parameters_.GetBytesPerBuffer()); 409 audio_parameters_.GetBytesPerBuffer());
401 if (SL_RESULT_SUCCESS != err) { 410 if (SL_RESULT_SUCCESS != err) {
402 ALOGE("Enqueue failed: %d", err); 411 ALOGE("Enqueue failed: %d", err);
403 } 412 }
404 buffer_index_ = (buffer_index_ + 1) % kNumOfOpenSLESBuffers; 413 buffer_index_ = (buffer_index_ + 1) % kNumOfOpenSLESBuffers;
405 } 414 }
406 415
407 SLuint32 OpenSLESPlayer::GetPlayState() const { 416 SLuint32 OpenSLESPlayer::GetPlayState() const {
408 RTC_DCHECK(player_); 417 RTC_DCHECK(player_);
409 SLuint32 state; 418 SLuint32 state;
410 SLresult err = (*player_)->GetPlayState(player_, &state); 419 SLresult err = (*player_)->GetPlayState(player_, &state);
411 if (SL_RESULT_SUCCESS != err) { 420 if (SL_RESULT_SUCCESS != err) {
412 ALOGE("GetPlayState failed: %d", err); 421 ALOGE("GetPlayState failed: %d", err);
413 } 422 }
414 return state; 423 return state;
415 } 424 }
416 425
417 } // namespace webrtc 426 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/audio_device/android/opensles_player.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698