1/* 2** 3** Copyright 2018, The Android Open Source Project 4** 5** Licensed under the Apache License, Version 2.0 (the "License"); 6** you may not use this file except in compliance with the License. 7** You may obtain a copy of the License at 8** 9** http://www.apache.org/licenses/LICENSE-2.0 10** 11** Unless required by applicable law or agreed to in writing, software 12** distributed under the License is distributed on an "AS IS" BASIS, 13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14** See the License for the specific language governing permissions and 15** limitations under the License. 16*/ 17 18//#define LOG_NDEBUG 0 19#define LOG_TAG "MediaPlayer2AudioOutput" 20#include <mediaplayer2/MediaPlayer2AudioOutput.h> 21 22#include <cutils/properties.h> // for property_get 23#include <utils/Log.h> 24 25#include <media/AudioPolicyHelper.h> 26#include <media/AudioTrack.h> 27#include <media/stagefright/foundation/ADebug.h> 28 29namespace { 30 31const float kMaxRequiredSpeed = 8.0f; // for PCM tracks allow up to 8x speedup. 32 33} // anonymous namespace 34 35namespace android { 36 37// TODO: Find real cause of Audio/Video delay in PV framework and remove this workaround 38/* static */ int MediaPlayer2AudioOutput::mMinBufferCount = 4; 39/* static */ bool MediaPlayer2AudioOutput::mIsOnEmulator = false; 40 41status_t MediaPlayer2AudioOutput::dump(int fd, const Vector<String16>& args) const { 42 const size_t SIZE = 256; 43 char buffer[SIZE]; 44 String8 result; 45 46 result.append(" MediaPlayer2AudioOutput\n"); 47 snprintf(buffer, 255, " stream type(%d), left - right volume(%f, %f)\n", 48 mStreamType, mLeftVolume, mRightVolume); 49 result.append(buffer); 50 snprintf(buffer, 255, " msec per frame(%f), latency (%d)\n", 51 mMsecsPerFrame, (mTrack != 0) ? mTrack->latency() : -1); 52 result.append(buffer); 53 snprintf(buffer, 255, " aux effect id(%d), send level (%f)\n", 54 mAuxEffectId, mSendLevel); 55 result.append(buffer); 56 57 ::write(fd, result.string(), result.size()); 58 if (mTrack != 0) { 59 mTrack->dump(fd, args); 60 } 61 return NO_ERROR; 62} 63 64MediaPlayer2AudioOutput::MediaPlayer2AudioOutput(audio_session_t sessionId, uid_t uid, int pid, 65 const audio_attributes_t* attr, const sp<AudioSystem::AudioDeviceCallback>& deviceCallback) 66 : mCallback(NULL), 67 mCallbackCookie(NULL), 68 mCallbackData(NULL), 69 mStreamType(AUDIO_STREAM_MUSIC), 70 mLeftVolume(1.0), 71 mRightVolume(1.0), 72 mPlaybackRate(AUDIO_PLAYBACK_RATE_DEFAULT), 73 mSampleRateHz(0), 74 mMsecsPerFrame(0), 75 mFrameSize(0), 76 mSessionId(sessionId), 77 mUid(uid), 78 mPid(pid), 79 mSendLevel(0.0), 80 mAuxEffectId(0), 81 mFlags(AUDIO_OUTPUT_FLAG_NONE), 82 mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE), 83 mRoutedDeviceId(AUDIO_PORT_HANDLE_NONE), 84 mDeviceCallbackEnabled(false), 85 mDeviceCallback(deviceCallback) { 86 ALOGV("MediaPlayer2AudioOutput(%d)", sessionId); 87 if (attr != NULL) { 88 mAttributes = (audio_attributes_t *) calloc(1, sizeof(audio_attributes_t)); 89 if (mAttributes != NULL) { 90 memcpy(mAttributes, attr, sizeof(audio_attributes_t)); 91 mStreamType = audio_attributes_to_stream_type(attr); 92 } 93 } else { 94 mAttributes = NULL; 95 } 96 97 setMinBufferCount(); 98} 99 100MediaPlayer2AudioOutput::~MediaPlayer2AudioOutput() { 101 close(); 102 free(mAttributes); 103 delete mCallbackData; 104} 105 106//static 107void MediaPlayer2AudioOutput::setMinBufferCount() { 108 char value[PROPERTY_VALUE_MAX]; 109 if (property_get("ro.kernel.qemu", value, 0)) { 110 mIsOnEmulator = true; 111 mMinBufferCount = 12; // to prevent systematic buffer underrun for emulator 112 } 113} 114 115// static 116bool MediaPlayer2AudioOutput::isOnEmulator() { 117 setMinBufferCount(); // benign race wrt other threads 118 return mIsOnEmulator; 119} 120 121// static 122int MediaPlayer2AudioOutput::getMinBufferCount() { 123 setMinBufferCount(); // benign race wrt other threads 124 return mMinBufferCount; 125} 126 127ssize_t MediaPlayer2AudioOutput::bufferSize() const { 128 Mutex::Autolock lock(mLock); 129 if (mTrack == 0) { 130 return NO_INIT; 131 } 132 return mTrack->frameCount() * mFrameSize; 133} 134 135ssize_t MediaPlayer2AudioOutput::frameCount() const { 136 Mutex::Autolock lock(mLock); 137 if (mTrack == 0) { 138 return NO_INIT; 139 } 140 return mTrack->frameCount(); 141} 142 143ssize_t MediaPlayer2AudioOutput::channelCount() const { 144 Mutex::Autolock lock(mLock); 145 if (mTrack == 0) { 146 return NO_INIT; 147 } 148 return mTrack->channelCount(); 149} 150 151ssize_t MediaPlayer2AudioOutput::frameSize() const { 152 Mutex::Autolock lock(mLock); 153 if (mTrack == 0) { 154 return NO_INIT; 155 } 156 return mFrameSize; 157} 158 159uint32_t MediaPlayer2AudioOutput::latency () const { 160 Mutex::Autolock lock(mLock); 161 if (mTrack == 0) { 162 return 0; 163 } 164 return mTrack->latency(); 165} 166 167float MediaPlayer2AudioOutput::msecsPerFrame() const { 168 Mutex::Autolock lock(mLock); 169 return mMsecsPerFrame; 170} 171 172status_t MediaPlayer2AudioOutput::getPosition(uint32_t *position) const { 173 Mutex::Autolock lock(mLock); 174 if (mTrack == 0) { 175 return NO_INIT; 176 } 177 return mTrack->getPosition(position); 178} 179 180status_t MediaPlayer2AudioOutput::getTimestamp(AudioTimestamp &ts) const { 181 Mutex::Autolock lock(mLock); 182 if (mTrack == 0) { 183 return NO_INIT; 184 } 185 return mTrack->getTimestamp(ts); 186} 187 188// TODO: Remove unnecessary calls to getPlayedOutDurationUs() 189// as it acquires locks and may query the audio driver. 190// 191// Some calls could conceivably retrieve extrapolated data instead of 192// accessing getTimestamp() or getPosition() every time a data buffer with 193// a media time is received. 194// 195// Calculate duration of played samples if played at normal rate (i.e., 1.0). 196int64_t MediaPlayer2AudioOutput::getPlayedOutDurationUs(int64_t nowUs) const { 197 Mutex::Autolock lock(mLock); 198 if (mTrack == 0 || mSampleRateHz == 0) { 199 return 0; 200 } 201 202 uint32_t numFramesPlayed; 203 int64_t numFramesPlayedAtUs; 204 AudioTimestamp ts; 205 206 status_t res = mTrack->getTimestamp(ts); 207 if (res == OK) { // case 1: mixing audio tracks and offloaded tracks. 208 numFramesPlayed = ts.mPosition; 209 numFramesPlayedAtUs = ts.mTime.tv_sec * 1000000LL + ts.mTime.tv_nsec / 1000; 210 //ALOGD("getTimestamp: OK %d %lld", numFramesPlayed, (long long)numFramesPlayedAtUs); 211 } else if (res == WOULD_BLOCK) { // case 2: transitory state on start of a new track 212 numFramesPlayed = 0; 213 numFramesPlayedAtUs = nowUs; 214 //ALOGD("getTimestamp: WOULD_BLOCK %d %lld", 215 // numFramesPlayed, (long long)numFramesPlayedAtUs); 216 } else { // case 3: transitory at new track or audio fast tracks. 217 res = mTrack->getPosition(&numFramesPlayed); 218 CHECK_EQ(res, (status_t)OK); 219 numFramesPlayedAtUs = nowUs; 220 numFramesPlayedAtUs += 1000LL * mTrack->latency() / 2; /* XXX */ 221 //ALOGD("getPosition: %u %lld", numFramesPlayed, (long long)numFramesPlayedAtUs); 222 } 223 224 // CHECK_EQ(numFramesPlayed & (1 << 31), 0); // can't be negative until 12.4 hrs, test 225 // TODO: remove the (int32_t) casting below as it may overflow at 12.4 hours. 226 int64_t durationUs = (int64_t)((int32_t)numFramesPlayed * 1000000LL / mSampleRateHz) 227 + nowUs - numFramesPlayedAtUs; 228 if (durationUs < 0) { 229 // Occurs when numFramesPlayed position is very small and the following: 230 // (1) In case 1, the time nowUs is computed before getTimestamp() is called and 231 // numFramesPlayedAtUs is greater than nowUs by time more than numFramesPlayed. 232 // (2) In case 3, using getPosition and adding mAudioSink->latency() to 233 // numFramesPlayedAtUs, by a time amount greater than numFramesPlayed. 234 // 235 // Both of these are transitory conditions. 236 ALOGV("getPlayedOutDurationUs: negative duration %lld set to zero", (long long)durationUs); 237 durationUs = 0; 238 } 239 ALOGV("getPlayedOutDurationUs(%lld) nowUs(%lld) frames(%u) framesAt(%lld)", 240 (long long)durationUs, (long long)nowUs, 241 numFramesPlayed, (long long)numFramesPlayedAtUs); 242 return durationUs; 243} 244 245status_t MediaPlayer2AudioOutput::getFramesWritten(uint32_t *frameswritten) const { 246 Mutex::Autolock lock(mLock); 247 if (mTrack == 0) { 248 return NO_INIT; 249 } 250 ExtendedTimestamp ets; 251 status_t status = mTrack->getTimestamp(&ets); 252 if (status == OK || status == WOULD_BLOCK) { 253 *frameswritten = (uint32_t)ets.mPosition[ExtendedTimestamp::LOCATION_CLIENT]; 254 } 255 return status; 256} 257 258status_t MediaPlayer2AudioOutput::setParameters(const String8& keyValuePairs) { 259 Mutex::Autolock lock(mLock); 260 if (mTrack == 0) { 261 return NO_INIT; 262 } 263 return mTrack->setParameters(keyValuePairs); 264} 265 266String8 MediaPlayer2AudioOutput::getParameters(const String8& keys) { 267 Mutex::Autolock lock(mLock); 268 if (mTrack == 0) { 269 return String8::empty(); 270 } 271 return mTrack->getParameters(keys); 272} 273 274void MediaPlayer2AudioOutput::setAudioAttributes(const audio_attributes_t * attributes) { 275 Mutex::Autolock lock(mLock); 276 if (attributes == NULL) { 277 free(mAttributes); 278 mAttributes = NULL; 279 } else { 280 if (mAttributes == NULL) { 281 mAttributes = (audio_attributes_t *) calloc(1, sizeof(audio_attributes_t)); 282 } 283 memcpy(mAttributes, attributes, sizeof(audio_attributes_t)); 284 mStreamType = audio_attributes_to_stream_type(attributes); 285 } 286} 287 288void MediaPlayer2AudioOutput::setAudioStreamType(audio_stream_type_t streamType) { 289 Mutex::Autolock lock(mLock); 290 // do not allow direct stream type modification if attributes have been set 291 if (mAttributes == NULL) { 292 mStreamType = streamType; 293 } 294} 295 296void MediaPlayer2AudioOutput::close_l() { 297 mTrack.clear(); 298} 299 300status_t MediaPlayer2AudioOutput::open( 301 uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask, 302 audio_format_t format, int bufferCount, 303 AudioCallback cb, void *cookie, 304 audio_output_flags_t flags, 305 const audio_offload_info_t *offloadInfo, 306 bool doNotReconnect, 307 uint32_t suggestedFrameCount) { 308 ALOGV("open(%u, %d, 0x%x, 0x%x, %d, %d 0x%x)", sampleRate, channelCount, channelMask, 309 format, bufferCount, mSessionId, flags); 310 311 // offloading is only supported in callback mode for now. 312 // offloadInfo must be present if offload flag is set 313 if (((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) && 314 ((cb == NULL) || (offloadInfo == NULL))) { 315 return BAD_VALUE; 316 } 317 318 // compute frame count for the AudioTrack internal buffer 319 size_t frameCount; 320 if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) { 321 frameCount = 0; // AudioTrack will get frame count from AudioFlinger 322 } else { 323 // try to estimate the buffer processing fetch size from AudioFlinger. 324 // framesPerBuffer is approximate and generally correct, except when it's not :-). 325 uint32_t afSampleRate; 326 size_t afFrameCount; 327 if (AudioSystem::getOutputFrameCount(&afFrameCount, mStreamType) != NO_ERROR) { 328 return NO_INIT; 329 } 330 if (AudioSystem::getOutputSamplingRate(&afSampleRate, mStreamType) != NO_ERROR) { 331 return NO_INIT; 332 } 333 const size_t framesPerBuffer = 334 (unsigned long long)sampleRate * afFrameCount / afSampleRate; 335 336 if (bufferCount == 0) { 337 // use suggestedFrameCount 338 bufferCount = (suggestedFrameCount + framesPerBuffer - 1) / framesPerBuffer; 339 } 340 // Check argument bufferCount against the mininum buffer count 341 if (bufferCount != 0 && bufferCount < mMinBufferCount) { 342 ALOGV("bufferCount (%d) increased to %d", bufferCount, mMinBufferCount); 343 bufferCount = mMinBufferCount; 344 } 345 // if frameCount is 0, then AudioTrack will get frame count from AudioFlinger 346 // which will be the minimum size permitted. 347 frameCount = bufferCount * framesPerBuffer; 348 } 349 350 if (channelMask == CHANNEL_MASK_USE_CHANNEL_ORDER) { 351 channelMask = audio_channel_out_mask_from_count(channelCount); 352 if (0 == channelMask) { 353 ALOGE("open() error, can\'t derive mask for %d audio channels", channelCount); 354 return NO_INIT; 355 } 356 } 357 358 Mutex::Autolock lock(mLock); 359 mCallback = cb; 360 mCallbackCookie = cookie; 361 362 sp<AudioTrack> t; 363 CallbackData *newcbd = NULL; 364 365 ALOGV("creating new AudioTrack"); 366 367 if (mCallback != NULL) { 368 newcbd = new CallbackData(this); 369 t = new AudioTrack( 370 mStreamType, 371 sampleRate, 372 format, 373 channelMask, 374 frameCount, 375 flags, 376 CallbackWrapper, 377 newcbd, 378 0, // notification frames 379 mSessionId, 380 AudioTrack::TRANSFER_CALLBACK, 381 offloadInfo, 382 mUid, 383 mPid, 384 mAttributes, 385 doNotReconnect, 386 1.0f, // default value for maxRequiredSpeed 387 mSelectedDeviceId); 388 } else { 389 // TODO: Due to buffer memory concerns, we use a max target playback speed 390 // based on mPlaybackRate at the time of open (instead of kMaxRequiredSpeed), 391 // also clamping the target speed to 1.0 <= targetSpeed <= kMaxRequiredSpeed. 392 const float targetSpeed = 393 std::min(std::max(mPlaybackRate.mSpeed, 1.0f), kMaxRequiredSpeed); 394 ALOGW_IF(targetSpeed != mPlaybackRate.mSpeed, 395 "track target speed:%f clamped from playback speed:%f", 396 targetSpeed, mPlaybackRate.mSpeed); 397 t = new AudioTrack( 398 mStreamType, 399 sampleRate, 400 format, 401 channelMask, 402 frameCount, 403 flags, 404 NULL, // callback 405 NULL, // user data 406 0, // notification frames 407 mSessionId, 408 AudioTrack::TRANSFER_DEFAULT, 409 NULL, // offload info 410 mUid, 411 mPid, 412 mAttributes, 413 doNotReconnect, 414 targetSpeed, 415 mSelectedDeviceId); 416 } 417 418 if ((t == 0) || (t->initCheck() != NO_ERROR)) { 419 ALOGE("Unable to create audio track"); 420 delete newcbd; 421 // t goes out of scope, so reference count drops to zero 422 return NO_INIT; 423 } else { 424 // successful AudioTrack initialization implies a legacy stream type was generated 425 // from the audio attributes 426 mStreamType = t->streamType(); 427 } 428 429 CHECK((t != NULL) && ((mCallback == NULL) || (newcbd != NULL))); 430 431 mCallbackData = newcbd; 432 ALOGV("setVolume"); 433 t->setVolume(mLeftVolume, mRightVolume); 434 435 mSampleRateHz = sampleRate; 436 mFlags = flags; 437 mMsecsPerFrame = 1E3f / (mPlaybackRate.mSpeed * sampleRate); 438 mFrameSize = t->frameSize(); 439 mTrack = t; 440 441 return updateTrack_l(); 442} 443 444status_t MediaPlayer2AudioOutput::updateTrack_l() { 445 if (mTrack == NULL) { 446 return NO_ERROR; 447 } 448 449 status_t res = NO_ERROR; 450 // Note some output devices may give us a direct track even though we don't specify it. 451 // Example: Line application b/17459982. 452 if ((mTrack->getFlags() 453 & (AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD | AUDIO_OUTPUT_FLAG_DIRECT)) == 0) { 454 res = mTrack->setPlaybackRate(mPlaybackRate); 455 if (res == NO_ERROR) { 456 mTrack->setAuxEffectSendLevel(mSendLevel); 457 res = mTrack->attachAuxEffect(mAuxEffectId); 458 } 459 } 460 mTrack->setOutputDevice(mSelectedDeviceId); 461 if (mDeviceCallbackEnabled) { 462 mTrack->addAudioDeviceCallback(mDeviceCallback.promote()); 463 } 464 ALOGV("updateTrack_l() DONE status %d", res); 465 return res; 466} 467 468status_t MediaPlayer2AudioOutput::start() { 469 ALOGV("start"); 470 Mutex::Autolock lock(mLock); 471 if (mCallbackData != NULL) { 472 mCallbackData->endTrackSwitch(); 473 } 474 if (mTrack != 0) { 475 mTrack->setVolume(mLeftVolume, mRightVolume); 476 mTrack->setAuxEffectSendLevel(mSendLevel); 477 status_t status = mTrack->start(); 478 return status; 479 } 480 return NO_INIT; 481} 482 483ssize_t MediaPlayer2AudioOutput::write(const void* buffer, size_t size, bool blocking) { 484 Mutex::Autolock lock(mLock); 485 LOG_ALWAYS_FATAL_IF(mCallback != NULL, "Don't call write if supplying a callback."); 486 487 //ALOGV("write(%p, %u)", buffer, size); 488 if (mTrack != 0) { 489 return mTrack->write(buffer, size, blocking); 490 } 491 return NO_INIT; 492} 493 494void MediaPlayer2AudioOutput::stop() { 495 ALOGV("stop"); 496 Mutex::Autolock lock(mLock); 497 if (mTrack != 0) { 498 mTrack->stop(); 499 } 500} 501 502void MediaPlayer2AudioOutput::flush() { 503 ALOGV("flush"); 504 Mutex::Autolock lock(mLock); 505 if (mTrack != 0) { 506 mTrack->flush(); 507 } 508} 509 510void MediaPlayer2AudioOutput::pause() { 511 ALOGV("pause"); 512 Mutex::Autolock lock(mLock); 513 if (mTrack != 0) { 514 mTrack->pause(); 515 } 516} 517 518void MediaPlayer2AudioOutput::close() { 519 ALOGV("close"); 520 sp<AudioTrack> track; 521 { 522 Mutex::Autolock lock(mLock); 523 track = mTrack; 524 close_l(); // clears mTrack 525 } 526 // destruction of the track occurs outside of mutex. 527} 528 529void MediaPlayer2AudioOutput::setVolume(float left, float right) { 530 ALOGV("setVolume(%f, %f)", left, right); 531 Mutex::Autolock lock(mLock); 532 mLeftVolume = left; 533 mRightVolume = right; 534 if (mTrack != 0) { 535 mTrack->setVolume(left, right); 536 } 537} 538 539status_t MediaPlayer2AudioOutput::setPlaybackRate(const AudioPlaybackRate &rate) { 540 ALOGV("setPlaybackRate(%f %f %d %d)", 541 rate.mSpeed, rate.mPitch, rate.mFallbackMode, rate.mStretchMode); 542 Mutex::Autolock lock(mLock); 543 if (mTrack == 0) { 544 // remember rate so that we can set it when the track is opened 545 mPlaybackRate = rate; 546 return OK; 547 } 548 status_t res = mTrack->setPlaybackRate(rate); 549 if (res != NO_ERROR) { 550 return res; 551 } 552 // rate.mSpeed is always greater than 0 if setPlaybackRate succeeded 553 CHECK_GT(rate.mSpeed, 0.f); 554 mPlaybackRate = rate; 555 if (mSampleRateHz != 0) { 556 mMsecsPerFrame = 1E3f / (rate.mSpeed * mSampleRateHz); 557 } 558 return res; 559} 560 561status_t MediaPlayer2AudioOutput::getPlaybackRate(AudioPlaybackRate *rate) { 562 ALOGV("setPlaybackRate"); 563 Mutex::Autolock lock(mLock); 564 if (mTrack == 0) { 565 return NO_INIT; 566 } 567 *rate = mTrack->getPlaybackRate(); 568 return NO_ERROR; 569} 570 571status_t MediaPlayer2AudioOutput::setAuxEffectSendLevel(float level) { 572 ALOGV("setAuxEffectSendLevel(%f)", level); 573 Mutex::Autolock lock(mLock); 574 mSendLevel = level; 575 if (mTrack != 0) { 576 return mTrack->setAuxEffectSendLevel(level); 577 } 578 return NO_ERROR; 579} 580 581status_t MediaPlayer2AudioOutput::attachAuxEffect(int effectId) { 582 ALOGV("attachAuxEffect(%d)", effectId); 583 Mutex::Autolock lock(mLock); 584 mAuxEffectId = effectId; 585 if (mTrack != 0) { 586 return mTrack->attachAuxEffect(effectId); 587 } 588 return NO_ERROR; 589} 590 591status_t MediaPlayer2AudioOutput::setOutputDevice(audio_port_handle_t deviceId) { 592 ALOGV("setOutputDevice(%d)", deviceId); 593 Mutex::Autolock lock(mLock); 594 mSelectedDeviceId = deviceId; 595 if (mTrack != 0) { 596 return mTrack->setOutputDevice(deviceId); 597 } 598 return NO_ERROR; 599} 600 601status_t MediaPlayer2AudioOutput::getRoutedDeviceId(audio_port_handle_t* deviceId) { 602 ALOGV("getRoutedDeviceId"); 603 Mutex::Autolock lock(mLock); 604 if (mTrack != 0) { 605 mRoutedDeviceId = mTrack->getRoutedDeviceId(); 606 } 607 *deviceId = mRoutedDeviceId; 608 return NO_ERROR; 609} 610 611status_t MediaPlayer2AudioOutput::enableAudioDeviceCallback(bool enabled) { 612 ALOGV("enableAudioDeviceCallback, %d", enabled); 613 Mutex::Autolock lock(mLock); 614 mDeviceCallbackEnabled = enabled; 615 if (mTrack != 0) { 616 status_t status; 617 if (enabled) { 618 status = mTrack->addAudioDeviceCallback(mDeviceCallback.promote()); 619 } else { 620 status = mTrack->removeAudioDeviceCallback(mDeviceCallback.promote()); 621 } 622 return status; 623 } 624 return NO_ERROR; 625} 626 627// static 628void MediaPlayer2AudioOutput::CallbackWrapper( 629 int event, void *cookie, void *info) { 630 //ALOGV("callbackwrapper"); 631 CallbackData *data = (CallbackData*)cookie; 632 // lock to ensure we aren't caught in the middle of a track switch. 633 data->lock(); 634 MediaPlayer2AudioOutput *me = data->getOutput(); 635 AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info; 636 if (me == NULL) { 637 // no output set, likely because the track was scheduled to be reused 638 // by another player, but the format turned out to be incompatible. 639 data->unlock(); 640 if (buffer != NULL) { 641 buffer->size = 0; 642 } 643 return; 644 } 645 646 switch(event) { 647 case AudioTrack::EVENT_MORE_DATA: { 648 size_t actualSize = (*me->mCallback)( 649 me, buffer->raw, buffer->size, me->mCallbackCookie, 650 CB_EVENT_FILL_BUFFER); 651 652 // Log when no data is returned from the callback. 653 // (1) We may have no data (especially with network streaming sources). 654 // (2) We may have reached the EOS and the audio track is not stopped yet. 655 // Note that AwesomePlayer/AudioPlayer will only return zero size when it reaches the EOS. 656 // NuPlayer2Renderer will return zero when it doesn't have data (it doesn't block to fill). 657 // 658 // This is a benign busy-wait, with the next data request generated 10 ms or more later; 659 // nevertheless for power reasons, we don't want to see too many of these. 660 661 ALOGV_IF(actualSize == 0 && buffer->size > 0, "callbackwrapper: empty buffer returned"); 662 663 buffer->size = actualSize; 664 } break; 665 666 case AudioTrack::EVENT_STREAM_END: 667 // currently only occurs for offloaded callbacks 668 ALOGV("callbackwrapper: deliver EVENT_STREAM_END"); 669 (*me->mCallback)(me, NULL /* buffer */, 0 /* size */, 670 me->mCallbackCookie, CB_EVENT_STREAM_END); 671 break; 672 673 case AudioTrack::EVENT_NEW_IAUDIOTRACK : 674 ALOGV("callbackwrapper: deliver EVENT_TEAR_DOWN"); 675 (*me->mCallback)(me, NULL /* buffer */, 0 /* size */, 676 me->mCallbackCookie, CB_EVENT_TEAR_DOWN); 677 break; 678 679 case AudioTrack::EVENT_UNDERRUN: 680 // This occurs when there is no data available, typically 681 // when there is a failure to supply data to the AudioTrack. It can also 682 // occur in non-offloaded mode when the audio device comes out of standby. 683 // 684 // If an AudioTrack underruns it outputs silence. Since this happens suddenly 685 // it may sound like an audible pop or glitch. 686 // 687 // The underrun event is sent once per track underrun; the condition is reset 688 // when more data is sent to the AudioTrack. 689 ALOGD("callbackwrapper: EVENT_UNDERRUN (discarded)"); 690 break; 691 692 default: 693 ALOGE("received unknown event type: %d inside CallbackWrapper !", event); 694 } 695 696 data->unlock(); 697} 698 699audio_session_t MediaPlayer2AudioOutput::getSessionId() const 700{ 701 Mutex::Autolock lock(mLock); 702 return mSessionId; 703} 704 705uint32_t MediaPlayer2AudioOutput::getSampleRate() const 706{ 707 Mutex::Autolock lock(mLock); 708 if (mTrack == 0) { 709 return 0; 710 } 711 return mTrack->getSampleRate(); 712} 713 714int64_t MediaPlayer2AudioOutput::getBufferDurationInUs() const 715{ 716 Mutex::Autolock lock(mLock); 717 if (mTrack == 0) { 718 return 0; 719 } 720 int64_t duration; 721 if (mTrack->getBufferDurationInUs(&duration) != OK) { 722 return 0; 723 } 724 return duration; 725} 726 727} // namespace android 728