| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |