| 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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 pcm_format_ = CreatePCMConfiguration(audio_parameters_.channels(), | 53 pcm_format_ = CreatePCMConfiguration(audio_parameters_.channels(), |
| 54 audio_parameters_.sample_rate(), | 54 audio_parameters_.sample_rate(), |
| 55 audio_parameters_.bits_per_sample()); | 55 audio_parameters_.bits_per_sample()); |
| 56 // Detach from this thread since we want to use the checker to verify calls | 56 // Detach from this thread since we want to use the checker to verify calls |
| 57 // from the internal audio thread. | 57 // from the internal audio thread. |
| 58 thread_checker_opensles_.DetachFromThread(); | 58 thread_checker_opensles_.DetachFromThread(); |
| 59 } | 59 } |
| 60 | 60 |
| 61 OpenSLESPlayer::~OpenSLESPlayer() { | 61 OpenSLESPlayer::~OpenSLESPlayer() { |
| 62 ALOGD("dtor%s", GetThreadInfo().c_str()); | 62 ALOGD("dtor%s", GetThreadInfo().c_str()); |
| 63 DCHECK(thread_checker_.CalledOnValidThread()); | 63 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 64 Terminate(); | 64 Terminate(); |
| 65 DestroyAudioPlayer(); | 65 DestroyAudioPlayer(); |
| 66 DestroyMix(); | 66 DestroyMix(); |
| 67 DestroyEngine(); | 67 DestroyEngine(); |
| 68 DCHECK(!engine_object_.Get()); | 68 RTC_DCHECK(!engine_object_.Get()); |
| 69 DCHECK(!engine_); | 69 RTC_DCHECK(!engine_); |
| 70 DCHECK(!output_mix_.Get()); | 70 RTC_DCHECK(!output_mix_.Get()); |
| 71 DCHECK(!player_); | 71 RTC_DCHECK(!player_); |
| 72 DCHECK(!simple_buffer_queue_); | 72 RTC_DCHECK(!simple_buffer_queue_); |
| 73 DCHECK(!volume_); | 73 RTC_DCHECK(!volume_); |
| 74 } | 74 } |
| 75 | 75 |
| 76 int OpenSLESPlayer::Init() { | 76 int OpenSLESPlayer::Init() { |
| 77 ALOGD("Init%s", GetThreadInfo().c_str()); | 77 ALOGD("Init%s", GetThreadInfo().c_str()); |
| 78 DCHECK(thread_checker_.CalledOnValidThread()); | 78 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 79 return 0; | 79 return 0; |
| 80 } | 80 } |
| 81 | 81 |
| 82 int OpenSLESPlayer::Terminate() { | 82 int OpenSLESPlayer::Terminate() { |
| 83 ALOGD("Terminate%s", GetThreadInfo().c_str()); | 83 ALOGD("Terminate%s", GetThreadInfo().c_str()); |
| 84 DCHECK(thread_checker_.CalledOnValidThread()); | 84 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 85 StopPlayout(); | 85 StopPlayout(); |
| 86 return 0; | 86 return 0; |
| 87 } | 87 } |
| 88 | 88 |
| 89 int OpenSLESPlayer::InitPlayout() { | 89 int OpenSLESPlayer::InitPlayout() { |
| 90 ALOGD("InitPlayout%s", GetThreadInfo().c_str()); | 90 ALOGD("InitPlayout%s", GetThreadInfo().c_str()); |
| 91 DCHECK(thread_checker_.CalledOnValidThread()); | 91 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 92 DCHECK(!initialized_); | 92 RTC_DCHECK(!initialized_); |
| 93 DCHECK(!playing_); | 93 RTC_DCHECK(!playing_); |
| 94 CreateEngine(); | 94 CreateEngine(); |
| 95 CreateMix(); | 95 CreateMix(); |
| 96 initialized_ = true; | 96 initialized_ = true; |
| 97 buffer_index_ = 0; | 97 buffer_index_ = 0; |
| 98 return 0; | 98 return 0; |
| 99 } | 99 } |
| 100 | 100 |
| 101 int OpenSLESPlayer::StartPlayout() { | 101 int OpenSLESPlayer::StartPlayout() { |
| 102 ALOGD("StartPlayout%s", GetThreadInfo().c_str()); | 102 ALOGD("StartPlayout%s", GetThreadInfo().c_str()); |
| 103 DCHECK(thread_checker_.CalledOnValidThread()); | 103 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 104 DCHECK(initialized_); | 104 RTC_DCHECK(initialized_); |
| 105 DCHECK(!playing_); | 105 RTC_DCHECK(!playing_); |
| 106 // The number of lower latency audio players is limited, hence we create the | 106 // The number of lower latency audio players is limited, hence we create the |
| 107 // audio player in Start() and destroy it in Stop(). | 107 // audio player in Start() and destroy it in Stop(). |
| 108 CreateAudioPlayer(); | 108 CreateAudioPlayer(); |
| 109 // Fill up audio buffers to avoid initial glitch and to ensure that playback | 109 // Fill up audio buffers to avoid initial glitch and to ensure that playback |
| 110 // starts when mode is later changed to SL_PLAYSTATE_PLAYING. | 110 // starts when mode is later changed to SL_PLAYSTATE_PLAYING. |
| 111 // TODO(henrika): we can save some delay by only making one call to | 111 // TODO(henrika): we can save some delay by only making one call to |
| 112 // EnqueuePlayoutData. Most likely not worth the risk of adding a glitch. | 112 // EnqueuePlayoutData. Most likely not worth the risk of adding a glitch. |
| 113 for (int i = 0; i < kNumOfOpenSLESBuffers; ++i) { | 113 for (int i = 0; i < kNumOfOpenSLESBuffers; ++i) { |
| 114 EnqueuePlayoutData(); | 114 EnqueuePlayoutData(); |
| 115 } | 115 } |
| 116 // Start streaming data by setting the play state to SL_PLAYSTATE_PLAYING. | 116 // Start streaming data by setting the play state to SL_PLAYSTATE_PLAYING. |
| 117 // For a player object, when the object is in the SL_PLAYSTATE_PLAYING | 117 // For a player object, when the object is in the SL_PLAYSTATE_PLAYING |
| 118 // state, adding buffers will implicitly start playback. | 118 // state, adding buffers will implicitly start playback. |
| 119 RETURN_ON_ERROR((*player_)->SetPlayState(player_, SL_PLAYSTATE_PLAYING), -1); | 119 RETURN_ON_ERROR((*player_)->SetPlayState(player_, SL_PLAYSTATE_PLAYING), -1); |
| 120 playing_ = (GetPlayState() == SL_PLAYSTATE_PLAYING); | 120 playing_ = (GetPlayState() == SL_PLAYSTATE_PLAYING); |
| 121 DCHECK(playing_); | 121 RTC_DCHECK(playing_); |
| 122 return 0; | 122 return 0; |
| 123 } | 123 } |
| 124 | 124 |
| 125 int OpenSLESPlayer::StopPlayout() { | 125 int OpenSLESPlayer::StopPlayout() { |
| 126 ALOGD("StopPlayout%s", GetThreadInfo().c_str()); | 126 ALOGD("StopPlayout%s", GetThreadInfo().c_str()); |
| 127 DCHECK(thread_checker_.CalledOnValidThread()); | 127 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 128 if (!initialized_ || !playing_) { | 128 if (!initialized_ || !playing_) { |
| 129 return 0; | 129 return 0; |
| 130 } | 130 } |
| 131 // Stop playing by setting the play state to SL_PLAYSTATE_STOPPED. | 131 // Stop playing by setting the play state to SL_PLAYSTATE_STOPPED. |
| 132 RETURN_ON_ERROR((*player_)->SetPlayState(player_, SL_PLAYSTATE_STOPPED), -1); | 132 RETURN_ON_ERROR((*player_)->SetPlayState(player_, SL_PLAYSTATE_STOPPED), -1); |
| 133 // Clear the buffer queue to flush out any remaining data. | 133 // Clear the buffer queue to flush out any remaining data. |
| 134 RETURN_ON_ERROR((*simple_buffer_queue_)->Clear(simple_buffer_queue_), -1); | 134 RETURN_ON_ERROR((*simple_buffer_queue_)->Clear(simple_buffer_queue_), -1); |
| 135 #ifndef NDEBUG | 135 #ifndef NDEBUG |
| 136 // Verify that the buffer queue is in fact cleared as it should. | 136 // Verify that the buffer queue is in fact cleared as it should. |
| 137 SLAndroidSimpleBufferQueueState buffer_queue_state; | 137 SLAndroidSimpleBufferQueueState buffer_queue_state; |
| 138 (*simple_buffer_queue_)->GetState(simple_buffer_queue_, &buffer_queue_state); | 138 (*simple_buffer_queue_)->GetState(simple_buffer_queue_, &buffer_queue_state); |
| 139 DCHECK_EQ(0u, buffer_queue_state.count); | 139 RTC_DCHECK_EQ(0u, buffer_queue_state.count); |
| 140 DCHECK_EQ(0u, buffer_queue_state.index); | 140 RTC_DCHECK_EQ(0u, buffer_queue_state.index); |
| 141 #endif | 141 #endif |
| 142 // The number of lower latency audio players is limited, hence we create the | 142 // The number of lower latency audio players is limited, hence we create the |
| 143 // audio player in Start() and destroy it in Stop(). | 143 // audio player in Start() and destroy it in Stop(). |
| 144 DestroyAudioPlayer(); | 144 DestroyAudioPlayer(); |
| 145 thread_checker_opensles_.DetachFromThread(); | 145 thread_checker_opensles_.DetachFromThread(); |
| 146 initialized_ = false; | 146 initialized_ = false; |
| 147 playing_ = false; | 147 playing_ = false; |
| 148 return 0; | 148 return 0; |
| 149 } | 149 } |
| 150 | 150 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 164 int OpenSLESPlayer::SetSpeakerVolume(uint32_t volume) { | 164 int OpenSLESPlayer::SetSpeakerVolume(uint32_t volume) { |
| 165 return -1; | 165 return -1; |
| 166 } | 166 } |
| 167 | 167 |
| 168 int OpenSLESPlayer::SpeakerVolume(uint32_t& volume) const { | 168 int OpenSLESPlayer::SpeakerVolume(uint32_t& volume) const { |
| 169 return -1; | 169 return -1; |
| 170 } | 170 } |
| 171 | 171 |
| 172 void OpenSLESPlayer::AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) { | 172 void OpenSLESPlayer::AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) { |
| 173 ALOGD("AttachAudioBuffer"); | 173 ALOGD("AttachAudioBuffer"); |
| 174 DCHECK(thread_checker_.CalledOnValidThread()); | 174 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 175 audio_device_buffer_ = audioBuffer; | 175 audio_device_buffer_ = audioBuffer; |
| 176 const int sample_rate_hz = audio_parameters_.sample_rate(); | 176 const int sample_rate_hz = audio_parameters_.sample_rate(); |
| 177 ALOGD("SetPlayoutSampleRate(%d)", sample_rate_hz); | 177 ALOGD("SetPlayoutSampleRate(%d)", sample_rate_hz); |
| 178 audio_device_buffer_->SetPlayoutSampleRate(sample_rate_hz); | 178 audio_device_buffer_->SetPlayoutSampleRate(sample_rate_hz); |
| 179 const int channels = audio_parameters_.channels(); | 179 const int channels = audio_parameters_.channels(); |
| 180 ALOGD("SetPlayoutChannels(%d)", channels); | 180 ALOGD("SetPlayoutChannels(%d)", channels); |
| 181 audio_device_buffer_->SetPlayoutChannels(channels); | 181 audio_device_buffer_->SetPlayoutChannels(channels); |
| 182 CHECK(audio_device_buffer_); | 182 RTC_CHECK(audio_device_buffer_); |
| 183 AllocateDataBuffers(); | 183 AllocateDataBuffers(); |
| 184 } | 184 } |
| 185 | 185 |
| 186 SLDataFormat_PCM OpenSLESPlayer::CreatePCMConfiguration( | 186 SLDataFormat_PCM OpenSLESPlayer::CreatePCMConfiguration( |
| 187 int channels, | 187 int channels, |
| 188 int sample_rate, | 188 int sample_rate, |
| 189 size_t bits_per_sample) { | 189 size_t bits_per_sample) { |
| 190 ALOGD("CreatePCMConfiguration"); | 190 ALOGD("CreatePCMConfiguration"); |
| 191 CHECK_EQ(bits_per_sample, SL_PCMSAMPLEFORMAT_FIXED_16); | 191 RTC_CHECK_EQ(bits_per_sample, SL_PCMSAMPLEFORMAT_FIXED_16); |
| 192 SLDataFormat_PCM format; | 192 SLDataFormat_PCM format; |
| 193 format.formatType = SL_DATAFORMAT_PCM; | 193 format.formatType = SL_DATAFORMAT_PCM; |
| 194 format.numChannels = static_cast<SLuint32>(channels); | 194 format.numChannels = static_cast<SLuint32>(channels); |
| 195 // Note that, the unit of sample rate is actually in milliHertz and not Hertz. | 195 // Note that, the unit of sample rate is actually in milliHertz and not Hertz. |
| 196 switch (sample_rate) { | 196 switch (sample_rate) { |
| 197 case 8000: | 197 case 8000: |
| 198 format.samplesPerSec = SL_SAMPLINGRATE_8; | 198 format.samplesPerSec = SL_SAMPLINGRATE_8; |
| 199 break; | 199 break; |
| 200 case 16000: | 200 case 16000: |
| 201 format.samplesPerSec = SL_SAMPLINGRATE_16; | 201 format.samplesPerSec = SL_SAMPLINGRATE_16; |
| 202 break; | 202 break; |
| 203 case 22050: | 203 case 22050: |
| 204 format.samplesPerSec = SL_SAMPLINGRATE_22_05; | 204 format.samplesPerSec = SL_SAMPLINGRATE_22_05; |
| 205 break; | 205 break; |
| 206 case 32000: | 206 case 32000: |
| 207 format.samplesPerSec = SL_SAMPLINGRATE_32; | 207 format.samplesPerSec = SL_SAMPLINGRATE_32; |
| 208 break; | 208 break; |
| 209 case 44100: | 209 case 44100: |
| 210 format.samplesPerSec = SL_SAMPLINGRATE_44_1; | 210 format.samplesPerSec = SL_SAMPLINGRATE_44_1; |
| 211 break; | 211 break; |
| 212 case 48000: | 212 case 48000: |
| 213 format.samplesPerSec = SL_SAMPLINGRATE_48; | 213 format.samplesPerSec = SL_SAMPLINGRATE_48; |
| 214 break; | 214 break; |
| 215 default: | 215 default: |
| 216 CHECK(false) << "Unsupported sample rate: " << sample_rate; | 216 RTC_CHECK(false) << "Unsupported sample rate: " << sample_rate; |
| 217 } | 217 } |
| 218 format.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16; | 218 format.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16; |
| 219 format.containerSize = SL_PCMSAMPLEFORMAT_FIXED_16; | 219 format.containerSize = SL_PCMSAMPLEFORMAT_FIXED_16; |
| 220 format.endianness = SL_BYTEORDER_LITTLEENDIAN; | 220 format.endianness = SL_BYTEORDER_LITTLEENDIAN; |
| 221 if (format.numChannels == 1) | 221 if (format.numChannels == 1) |
| 222 format.channelMask = SL_SPEAKER_FRONT_CENTER; | 222 format.channelMask = SL_SPEAKER_FRONT_CENTER; |
| 223 else if (format.numChannels == 2) | 223 else if (format.numChannels == 2) |
| 224 format.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; | 224 format.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; |
| 225 else | 225 else |
| 226 CHECK(false) << "Unsupported number of channels: " << format.numChannels; | 226 RTC_CHECK(false) << "Unsupported number of channels: " |
| 227 << format.numChannels; |
| 227 return format; | 228 return format; |
| 228 } | 229 } |
| 229 | 230 |
| 230 void OpenSLESPlayer::AllocateDataBuffers() { | 231 void OpenSLESPlayer::AllocateDataBuffers() { |
| 231 ALOGD("AllocateDataBuffers"); | 232 ALOGD("AllocateDataBuffers"); |
| 232 DCHECK(thread_checker_.CalledOnValidThread()); | 233 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 233 DCHECK(!simple_buffer_queue_); | 234 RTC_DCHECK(!simple_buffer_queue_); |
| 234 CHECK(audio_device_buffer_); | 235 RTC_CHECK(audio_device_buffer_); |
| 235 bytes_per_buffer_ = audio_parameters_.GetBytesPerBuffer(); | 236 bytes_per_buffer_ = audio_parameters_.GetBytesPerBuffer(); |
| 236 ALOGD("native buffer size: %" PRIuS, bytes_per_buffer_); | 237 ALOGD("native buffer size: %" PRIuS, bytes_per_buffer_); |
| 237 // Create a modified audio buffer class which allows us to ask for any number | 238 // Create a modified audio buffer class which allows us to ask for any number |
| 238 // of samples (and not only multiple of 10ms) to match the native OpenSL ES | 239 // of samples (and not only multiple of 10ms) to match the native OpenSL ES |
| 239 // buffer size. | 240 // buffer size. |
| 240 fine_buffer_.reset(new FineAudioBuffer(audio_device_buffer_, | 241 fine_buffer_.reset(new FineAudioBuffer(audio_device_buffer_, |
| 241 bytes_per_buffer_, | 242 bytes_per_buffer_, |
| 242 audio_parameters_.sample_rate())); | 243 audio_parameters_.sample_rate())); |
| 243 // Each buffer must be of this size to avoid unnecessary memcpy while caching | 244 // Each buffer must be of this size to avoid unnecessary memcpy while caching |
| 244 // data between successive callbacks. | 245 // data between successive callbacks. |
| 245 const size_t required_buffer_size = | 246 const size_t required_buffer_size = |
| 246 fine_buffer_->RequiredPlayoutBufferSizeBytes(); | 247 fine_buffer_->RequiredPlayoutBufferSizeBytes(); |
| 247 ALOGD("required buffer size: %" PRIuS, required_buffer_size); | 248 ALOGD("required buffer size: %" PRIuS, required_buffer_size); |
| 248 for (int i = 0; i < kNumOfOpenSLESBuffers; ++i) { | 249 for (int i = 0; i < kNumOfOpenSLESBuffers; ++i) { |
| 249 audio_buffers_[i].reset(new SLint8[required_buffer_size]); | 250 audio_buffers_[i].reset(new SLint8[required_buffer_size]); |
| 250 } | 251 } |
| 251 } | 252 } |
| 252 | 253 |
| 253 bool OpenSLESPlayer::CreateEngine() { | 254 bool OpenSLESPlayer::CreateEngine() { |
| 254 ALOGD("CreateEngine"); | 255 ALOGD("CreateEngine"); |
| 255 DCHECK(thread_checker_.CalledOnValidThread()); | 256 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 256 if (engine_object_.Get()) | 257 if (engine_object_.Get()) |
| 257 return true; | 258 return true; |
| 258 DCHECK(!engine_); | 259 RTC_DCHECK(!engine_); |
| 259 const SLEngineOption option[] = { | 260 const SLEngineOption option[] = { |
| 260 {SL_ENGINEOPTION_THREADSAFE, static_cast<SLuint32>(SL_BOOLEAN_TRUE)}}; | 261 {SL_ENGINEOPTION_THREADSAFE, static_cast<SLuint32>(SL_BOOLEAN_TRUE)}}; |
| 261 RETURN_ON_ERROR( | 262 RETURN_ON_ERROR( |
| 262 slCreateEngine(engine_object_.Receive(), 1, option, 0, NULL, NULL), | 263 slCreateEngine(engine_object_.Receive(), 1, option, 0, NULL, NULL), |
| 263 false); | 264 false); |
| 264 RETURN_ON_ERROR( | 265 RETURN_ON_ERROR( |
| 265 engine_object_->Realize(engine_object_.Get(), SL_BOOLEAN_FALSE), false); | 266 engine_object_->Realize(engine_object_.Get(), SL_BOOLEAN_FALSE), false); |
| 266 RETURN_ON_ERROR(engine_object_->GetInterface(engine_object_.Get(), | 267 RETURN_ON_ERROR(engine_object_->GetInterface(engine_object_.Get(), |
| 267 SL_IID_ENGINE, &engine_), | 268 SL_IID_ENGINE, &engine_), |
| 268 false); | 269 false); |
| 269 return true; | 270 return true; |
| 270 } | 271 } |
| 271 | 272 |
| 272 void OpenSLESPlayer::DestroyEngine() { | 273 void OpenSLESPlayer::DestroyEngine() { |
| 273 ALOGD("DestroyEngine"); | 274 ALOGD("DestroyEngine"); |
| 274 DCHECK(thread_checker_.CalledOnValidThread()); | 275 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 275 if (!engine_object_.Get()) | 276 if (!engine_object_.Get()) |
| 276 return; | 277 return; |
| 277 engine_ = nullptr; | 278 engine_ = nullptr; |
| 278 engine_object_.Reset(); | 279 engine_object_.Reset(); |
| 279 } | 280 } |
| 280 | 281 |
| 281 bool OpenSLESPlayer::CreateMix() { | 282 bool OpenSLESPlayer::CreateMix() { |
| 282 ALOGD("CreateMix"); | 283 ALOGD("CreateMix"); |
| 283 DCHECK(thread_checker_.CalledOnValidThread()); | 284 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 284 DCHECK(engine_); | 285 RTC_DCHECK(engine_); |
| 285 if (output_mix_.Get()) | 286 if (output_mix_.Get()) |
| 286 return true; | 287 return true; |
| 287 | 288 |
| 288 // Create the ouput mix on the engine object. No interfaces will be used. | 289 // Create the ouput mix on the engine object. No interfaces will be used. |
| 289 RETURN_ON_ERROR((*engine_)->CreateOutputMix(engine_, output_mix_.Receive(), 0, | 290 RETURN_ON_ERROR((*engine_)->CreateOutputMix(engine_, output_mix_.Receive(), 0, |
| 290 NULL, NULL), | 291 NULL, NULL), |
| 291 false); | 292 false); |
| 292 RETURN_ON_ERROR(output_mix_->Realize(output_mix_.Get(), SL_BOOLEAN_FALSE), | 293 RETURN_ON_ERROR(output_mix_->Realize(output_mix_.Get(), SL_BOOLEAN_FALSE), |
| 293 false); | 294 false); |
| 294 return true; | 295 return true; |
| 295 } | 296 } |
| 296 | 297 |
| 297 void OpenSLESPlayer::DestroyMix() { | 298 void OpenSLESPlayer::DestroyMix() { |
| 298 ALOGD("DestroyMix"); | 299 ALOGD("DestroyMix"); |
| 299 DCHECK(thread_checker_.CalledOnValidThread()); | 300 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 300 if (!output_mix_.Get()) | 301 if (!output_mix_.Get()) |
| 301 return; | 302 return; |
| 302 output_mix_.Reset(); | 303 output_mix_.Reset(); |
| 303 } | 304 } |
| 304 | 305 |
| 305 bool OpenSLESPlayer::CreateAudioPlayer() { | 306 bool OpenSLESPlayer::CreateAudioPlayer() { |
| 306 ALOGD("CreateAudioPlayer"); | 307 ALOGD("CreateAudioPlayer"); |
| 307 DCHECK(thread_checker_.CalledOnValidThread()); | 308 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 308 DCHECK(engine_object_.Get()); | 309 RTC_DCHECK(engine_object_.Get()); |
| 309 DCHECK(output_mix_.Get()); | 310 RTC_DCHECK(output_mix_.Get()); |
| 310 if (player_object_.Get()) | 311 if (player_object_.Get()) |
| 311 return true; | 312 return true; |
| 312 DCHECK(!player_); | 313 RTC_DCHECK(!player_); |
| 313 DCHECK(!simple_buffer_queue_); | 314 RTC_DCHECK(!simple_buffer_queue_); |
| 314 DCHECK(!volume_); | 315 RTC_DCHECK(!volume_); |
| 315 | 316 |
| 316 // source: Android Simple Buffer Queue Data Locator is source. | 317 // source: Android Simple Buffer Queue Data Locator is source. |
| 317 SLDataLocator_AndroidSimpleBufferQueue simple_buffer_queue = { | 318 SLDataLocator_AndroidSimpleBufferQueue simple_buffer_queue = { |
| 318 SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, | 319 SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, |
| 319 static_cast<SLuint32>(kNumOfOpenSLESBuffers)}; | 320 static_cast<SLuint32>(kNumOfOpenSLESBuffers)}; |
| 320 SLDataSource audio_source = {&simple_buffer_queue, &pcm_format_}; | 321 SLDataSource audio_source = {&simple_buffer_queue, &pcm_format_}; |
| 321 | 322 |
| 322 // sink: OutputMix-based data is sink. | 323 // sink: OutputMix-based data is sink. |
| 323 SLDataLocator_OutputMix locator_output_mix = {SL_DATALOCATOR_OUTPUTMIX, | 324 SLDataLocator_OutputMix locator_output_mix = {SL_DATALOCATOR_OUTPUTMIX, |
| 324 output_mix_.Get()}; | 325 output_mix_.Get()}; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 | 383 |
| 383 // TODO(henrika): might not be required to set volume to max here since it | 384 // TODO(henrika): might not be required to set volume to max here since it |
| 384 // seems to be default on most devices. Might be required for unit tests. | 385 // seems to be default on most devices. Might be required for unit tests. |
| 385 // RETURN_ON_ERROR((*volume_)->SetVolumeLevel(volume_, 0), false); | 386 // RETURN_ON_ERROR((*volume_)->SetVolumeLevel(volume_, 0), false); |
| 386 | 387 |
| 387 return true; | 388 return true; |
| 388 } | 389 } |
| 389 | 390 |
| 390 void OpenSLESPlayer::DestroyAudioPlayer() { | 391 void OpenSLESPlayer::DestroyAudioPlayer() { |
| 391 ALOGD("DestroyAudioPlayer"); | 392 ALOGD("DestroyAudioPlayer"); |
| 392 DCHECK(thread_checker_.CalledOnValidThread()); | 393 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 393 if (!player_object_.Get()) | 394 if (!player_object_.Get()) |
| 394 return; | 395 return; |
| 395 player_object_.Reset(); | 396 player_object_.Reset(); |
| 396 player_ = nullptr; | 397 player_ = nullptr; |
| 397 simple_buffer_queue_ = nullptr; | 398 simple_buffer_queue_ = nullptr; |
| 398 volume_ = nullptr; | 399 volume_ = nullptr; |
| 399 } | 400 } |
| 400 | 401 |
| 401 // static | 402 // static |
| 402 void OpenSLESPlayer::SimpleBufferQueueCallback( | 403 void OpenSLESPlayer::SimpleBufferQueueCallback( |
| 403 SLAndroidSimpleBufferQueueItf caller, | 404 SLAndroidSimpleBufferQueueItf caller, |
| 404 void* context) { | 405 void* context) { |
| 405 OpenSLESPlayer* stream = reinterpret_cast<OpenSLESPlayer*>(context); | 406 OpenSLESPlayer* stream = reinterpret_cast<OpenSLESPlayer*>(context); |
| 406 stream->FillBufferQueue(); | 407 stream->FillBufferQueue(); |
| 407 } | 408 } |
| 408 | 409 |
| 409 void OpenSLESPlayer::FillBufferQueue() { | 410 void OpenSLESPlayer::FillBufferQueue() { |
| 410 DCHECK(thread_checker_opensles_.CalledOnValidThread()); | 411 RTC_DCHECK(thread_checker_opensles_.CalledOnValidThread()); |
| 411 SLuint32 state = GetPlayState(); | 412 SLuint32 state = GetPlayState(); |
| 412 if (state != SL_PLAYSTATE_PLAYING) { | 413 if (state != SL_PLAYSTATE_PLAYING) { |
| 413 ALOGW("Buffer callback in non-playing state!"); | 414 ALOGW("Buffer callback in non-playing state!"); |
| 414 return; | 415 return; |
| 415 } | 416 } |
| 416 EnqueuePlayoutData(); | 417 EnqueuePlayoutData(); |
| 417 } | 418 } |
| 418 | 419 |
| 419 void OpenSLESPlayer::EnqueuePlayoutData() { | 420 void OpenSLESPlayer::EnqueuePlayoutData() { |
| 420 // Read audio data from the WebRTC source using the FineAudioBuffer object | 421 // Read audio data from the WebRTC source using the FineAudioBuffer object |
| 421 // to adjust for differences in buffer size between WebRTC (10ms) and native | 422 // to adjust for differences in buffer size between WebRTC (10ms) and native |
| 422 // OpenSL ES. | 423 // OpenSL ES. |
| 423 SLint8* audio_ptr = audio_buffers_[buffer_index_].get(); | 424 SLint8* audio_ptr = audio_buffers_[buffer_index_].get(); |
| 424 fine_buffer_->GetPlayoutData(audio_ptr); | 425 fine_buffer_->GetPlayoutData(audio_ptr); |
| 425 // Enqueue the decoded audio buffer for playback. | 426 // Enqueue the decoded audio buffer for playback. |
| 426 SLresult err = | 427 SLresult err = |
| 427 (*simple_buffer_queue_) | 428 (*simple_buffer_queue_) |
| 428 ->Enqueue(simple_buffer_queue_, audio_ptr, bytes_per_buffer_); | 429 ->Enqueue(simple_buffer_queue_, audio_ptr, bytes_per_buffer_); |
| 429 if (SL_RESULT_SUCCESS != err) { | 430 if (SL_RESULT_SUCCESS != err) { |
| 430 ALOGE("Enqueue failed: %d", err); | 431 ALOGE("Enqueue failed: %d", err); |
| 431 } | 432 } |
| 432 buffer_index_ = (buffer_index_ + 1) % kNumOfOpenSLESBuffers; | 433 buffer_index_ = (buffer_index_ + 1) % kNumOfOpenSLESBuffers; |
| 433 } | 434 } |
| 434 | 435 |
| 435 SLuint32 OpenSLESPlayer::GetPlayState() const { | 436 SLuint32 OpenSLESPlayer::GetPlayState() const { |
| 436 DCHECK(player_); | 437 RTC_DCHECK(player_); |
| 437 SLuint32 state; | 438 SLuint32 state; |
| 438 SLresult err = (*player_)->GetPlayState(player_, &state); | 439 SLresult err = (*player_)->GetPlayState(player_, &state); |
| 439 if (SL_RESULT_SUCCESS != err) { | 440 if (SL_RESULT_SUCCESS != err) { |
| 440 ALOGE("GetPlayState failed: %d", err); | 441 ALOGE("GetPlayState failed: %d", err); |
| 441 } | 442 } |
| 442 return state; | 443 return state; |
| 443 } | 444 } |
| 444 | 445 |
| 445 } // namespace webrtc | 446 } // namespace webrtc |
| OLD | NEW |