1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <inttypes.h> 18 19 //#define LOG_NDEBUG 0 20 #define LOG_TAG "AudioPlayer" 21 #include <utils/Log.h> 22 #include <cutils/compiler.h> 23 24 #include <binder/IPCThreadState.h> 25 #include <media/AudioTrack.h> 26 #include <media/openmax/OMX_Audio.h> 27 #include <media/stagefright/foundation/ADebug.h> 28 #include <media/stagefright/foundation/ALooper.h> 29 #include <media/stagefright/AudioPlayer.h> 30 #include <media/stagefright/MediaDefs.h> 31 #include <media/stagefright/MediaErrors.h> 32 #include <media/stagefright/MediaSource.h> 33 #include <media/stagefright/MetaData.h> 34 #include <media/stagefright/Utils.h> 35 36 #include "include/AwesomePlayer.h" 37 38 namespace android { 39 40 AudioPlayer::AudioPlayer( 41 const sp<MediaPlayerBase::AudioSink> &audioSink, 42 uint32_t flags, 43 AwesomePlayer *observer) 44 : mInputBuffer(NULL), 45 mSampleRate(0), 46 mLatencyUs(0), 47 mFrameSize(0), 48 mNumFramesPlayed(0), 49 mNumFramesPlayedSysTimeUs(ALooper::GetNowUs()), 50 mPositionTimeMediaUs(-1), 51 mPositionTimeRealUs(-1), 52 mSeeking(false), 53 mReachedEOS(false), 54 mFinalStatus(OK), 55 mSeekTimeUs(0), 56 mStarted(false), 57 mIsFirstBuffer(false), 58 mFirstBufferResult(OK), 59 mFirstBuffer(NULL), 60 mAudioSink(audioSink), 61 mObserver(observer), 62 mPinnedTimeUs(-1ll), 63 mPlaying(false), 64 mStartPosUs(0), 65 mCreateFlags(flags) { 66 } 67 68 AudioPlayer::~AudioPlayer() { 69 if (mStarted) { 70 reset(); 71 } 72 } 73 74 void AudioPlayer::setSource(const sp<MediaSource> &source) { 75 CHECK(mSource == NULL); 76 mSource = source; 77 } 78 79 status_t AudioPlayer::start(bool sourceAlreadyStarted) { 80 CHECK(!mStarted); 81 CHECK(mSource != NULL); 82 83 status_t err; 84 if (!sourceAlreadyStarted) { 85 err = mSource->start(); 86 87 if (err != OK) { 88 return err; 89 } 90 } 91 92 // We allow an optional INFO_FORMAT_CHANGED at the very beginning 93 // of playback, if there is one, getFormat below will retrieve the 94 // updated format, if there isn't, we'll stash away the valid buffer 95 // of data to be used on the first audio callback. 96 97 CHECK(mFirstBuffer == NULL); 98 99 MediaSource::ReadOptions options; 100 if (mSeeking) { 101 options.setSeekTo(mSeekTimeUs); 102 mSeeking = false; 103 } 104 105 mFirstBufferResult = mSource->read(&mFirstBuffer, &options); 106 if (mFirstBufferResult == INFO_FORMAT_CHANGED) { 107 ALOGV("INFO_FORMAT_CHANGED!!!"); 108 109 CHECK(mFirstBuffer == NULL); 110 mFirstBufferResult = OK; 111 mIsFirstBuffer = false; 112 } else { 113 mIsFirstBuffer = true; 114 } 115 116 sp<MetaData> format = mSource->getFormat(); 117 const char *mime; 118 bool success = format->findCString(kKeyMIMEType, &mime); 119 CHECK(success); 120 CHECK(useOffload() || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)); 121 122 success = format->findInt32(kKeySampleRate, &mSampleRate); 123 CHECK(success); 124 125 int32_t numChannels, channelMask; 126 success = format->findInt32(kKeyChannelCount, &numChannels); 127 CHECK(success); 128 129 if(!format->findInt32(kKeyChannelMask, &channelMask)) { 130 // log only when there's a risk of ambiguity of channel mask selection 131 ALOGI_IF(numChannels > 2, 132 "source format didn't specify channel mask, using (%d) channel order", numChannels); 133 channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER; 134 } 135 136 audio_format_t audioFormat = AUDIO_FORMAT_PCM_16_BIT; 137 138 if (useOffload()) { 139 if (mapMimeToAudioFormat(audioFormat, mime) != OK) { 140 ALOGE("Couldn't map mime type \"%s\" to a valid AudioSystem::audio_format", mime); 141 audioFormat = AUDIO_FORMAT_INVALID; 142 } else { 143 ALOGV("Mime type \"%s\" mapped to audio_format 0x%x", mime, audioFormat); 144 } 145 146 int32_t aacaot = -1; 147 if ((audioFormat == AUDIO_FORMAT_AAC) && format->findInt32(kKeyAACAOT, &aacaot)) { 148 // Redefine AAC format corrosponding to aac profile 149 mapAACProfileToAudioFormat(audioFormat,(OMX_AUDIO_AACPROFILETYPE) aacaot); 150 } 151 } 152 153 int avgBitRate = -1; 154 format->findInt32(kKeyBitRate, &avgBitRate); 155 156 if (mAudioSink.get() != NULL) { 157 158 uint32_t flags = AUDIO_OUTPUT_FLAG_NONE; 159 audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER; 160 161 if (allowDeepBuffering()) { 162 flags |= AUDIO_OUTPUT_FLAG_DEEP_BUFFER; 163 } 164 if (useOffload()) { 165 flags |= AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD; 166 167 int64_t durationUs; 168 if (format->findInt64(kKeyDuration, &durationUs)) { 169 offloadInfo.duration_us = durationUs; 170 } else { 171 offloadInfo.duration_us = -1; 172 } 173 174 offloadInfo.sample_rate = mSampleRate; 175 offloadInfo.channel_mask = channelMask; 176 offloadInfo.format = audioFormat; 177 offloadInfo.stream_type = AUDIO_STREAM_MUSIC; 178 offloadInfo.bit_rate = avgBitRate; 179 offloadInfo.has_video = ((mCreateFlags & HAS_VIDEO) != 0); 180 offloadInfo.is_streaming = ((mCreateFlags & IS_STREAMING) != 0); 181 } 182 183 status_t err = mAudioSink->open( 184 mSampleRate, numChannels, channelMask, audioFormat, 185 DEFAULT_AUDIOSINK_BUFFERCOUNT, 186 &AudioPlayer::AudioSinkCallback, 187 this, 188 (audio_output_flags_t)flags, 189 useOffload() ? &offloadInfo : NULL); 190 191 if (err == OK) { 192 mLatencyUs = (int64_t)mAudioSink->latency() * 1000; 193 mFrameSize = mAudioSink->frameSize(); 194 195 if (useOffload()) { 196 // If the playback is offloaded to h/w we pass the 197 // HAL some metadata information 198 // We don't want to do this for PCM because it will be going 199 // through the AudioFlinger mixer before reaching the hardware 200 sendMetaDataToHal(mAudioSink, format); 201 } 202 203 err = mAudioSink->start(); 204 // do not alter behavior for non offloaded tracks: ignore start status. 205 if (!useOffload()) { 206 err = OK; 207 } 208 } 209 210 if (err != OK) { 211 if (mFirstBuffer != NULL) { 212 mFirstBuffer->release(); 213 mFirstBuffer = NULL; 214 } 215 216 if (!sourceAlreadyStarted) { 217 mSource->stop(); 218 } 219 220 return err; 221 } 222 223 } else { 224 // playing to an AudioTrack, set up mask if necessary 225 audio_channel_mask_t audioMask = channelMask == CHANNEL_MASK_USE_CHANNEL_ORDER ? 226 audio_channel_out_mask_from_count(numChannels) : channelMask; 227 if (0 == audioMask) { 228 return BAD_VALUE; 229 } 230 231 mAudioTrack = new AudioTrack( 232 AUDIO_STREAM_MUSIC, mSampleRate, AUDIO_FORMAT_PCM_16_BIT, audioMask, 233 0 /*frameCount*/, AUDIO_OUTPUT_FLAG_NONE, &AudioCallback, this, 234 0 /*notificationFrames*/); 235 236 if ((err = mAudioTrack->initCheck()) != OK) { 237 mAudioTrack.clear(); 238 239 if (mFirstBuffer != NULL) { 240 mFirstBuffer->release(); 241 mFirstBuffer = NULL; 242 } 243 244 if (!sourceAlreadyStarted) { 245 mSource->stop(); 246 } 247 248 return err; 249 } 250 251 mLatencyUs = (int64_t)mAudioTrack->latency() * 1000; 252 mFrameSize = mAudioTrack->frameSize(); 253 254 mAudioTrack->start(); 255 } 256 257 mStarted = true; 258 mPlaying = true; 259 mPinnedTimeUs = -1ll; 260 261 return OK; 262 } 263 264 void AudioPlayer::pause(bool playPendingSamples) { 265 CHECK(mStarted); 266 267 if (playPendingSamples) { 268 if (mAudioSink.get() != NULL) { 269 mAudioSink->stop(); 270 } else { 271 mAudioTrack->stop(); 272 } 273 274 mNumFramesPlayed = 0; 275 mNumFramesPlayedSysTimeUs = ALooper::GetNowUs(); 276 } else { 277 if (mAudioSink.get() != NULL) { 278 mAudioSink->pause(); 279 } else { 280 mAudioTrack->pause(); 281 } 282 283 mPinnedTimeUs = ALooper::GetNowUs(); 284 } 285 286 mPlaying = false; 287 } 288 289 status_t AudioPlayer::resume() { 290 CHECK(mStarted); 291 status_t err; 292 293 if (mAudioSink.get() != NULL) { 294 err = mAudioSink->start(); 295 } else { 296 err = mAudioTrack->start(); 297 } 298 299 if (err == OK) { 300 mPlaying = true; 301 } 302 303 return err; 304 } 305 306 void AudioPlayer::reset() { 307 CHECK(mStarted); 308 309 ALOGV("reset: mPlaying=%d mReachedEOS=%d useOffload=%d", 310 mPlaying, mReachedEOS, useOffload() ); 311 312 if (mAudioSink.get() != NULL) { 313 mAudioSink->stop(); 314 // If we're closing and have reached EOS, we don't want to flush 315 // the track because if it is offloaded there could be a small 316 // amount of residual data in the hardware buffer which we must 317 // play to give gapless playback. 318 // But if we're resetting when paused or before we've reached EOS 319 // we can't be doing a gapless playback and there could be a large 320 // amount of data queued in the hardware if the track is offloaded, 321 // so we must flush to prevent a track switch being delayed playing 322 // the buffered data that we don't want now 323 if (!mPlaying || !mReachedEOS) { 324 mAudioSink->flush(); 325 } 326 327 mAudioSink->close(); 328 } else { 329 mAudioTrack->stop(); 330 331 if (!mPlaying || !mReachedEOS) { 332 mAudioTrack->flush(); 333 } 334 335 mAudioTrack.clear(); 336 } 337 338 // Make sure to release any buffer we hold onto so that the 339 // source is able to stop(). 340 341 if (mFirstBuffer != NULL) { 342 mFirstBuffer->release(); 343 mFirstBuffer = NULL; 344 } 345 346 if (mInputBuffer != NULL) { 347 ALOGV("AudioPlayer releasing input buffer."); 348 349 mInputBuffer->release(); 350 mInputBuffer = NULL; 351 } 352 353 mSource->stop(); 354 355 // The following hack is necessary to ensure that the OMX 356 // component is completely released by the time we may try 357 // to instantiate it again. 358 // When offloading, the OMX component is not used so this hack 359 // is not needed 360 if (!useOffload()) { 361 wp<MediaSource> tmp = mSource; 362 mSource.clear(); 363 while (tmp.promote() != NULL) { 364 usleep(1000); 365 } 366 } else { 367 mSource.clear(); 368 } 369 IPCThreadState::self()->flushCommands(); 370 371 mNumFramesPlayed = 0; 372 mNumFramesPlayedSysTimeUs = ALooper::GetNowUs(); 373 mPositionTimeMediaUs = -1; 374 mPositionTimeRealUs = -1; 375 mSeeking = false; 376 mSeekTimeUs = 0; 377 mReachedEOS = false; 378 mFinalStatus = OK; 379 mStarted = false; 380 mPlaying = false; 381 mStartPosUs = 0; 382 } 383 384 // static 385 void AudioPlayer::AudioCallback(int event, void *user, void *info) { 386 static_cast<AudioPlayer *>(user)->AudioCallback(event, info); 387 } 388 389 bool AudioPlayer::isSeeking() { 390 Mutex::Autolock autoLock(mLock); 391 return mSeeking; 392 } 393 394 bool AudioPlayer::reachedEOS(status_t *finalStatus) { 395 *finalStatus = OK; 396 397 Mutex::Autolock autoLock(mLock); 398 *finalStatus = mFinalStatus; 399 return mReachedEOS; 400 } 401 402 void AudioPlayer::notifyAudioEOS() { 403 ALOGV("AudioPlayer@0x%p notifyAudioEOS", this); 404 405 if (mObserver != NULL) { 406 mObserver->postAudioEOS(0); 407 ALOGV("Notified observer of EOS!"); 408 } 409 } 410 411 status_t AudioPlayer::setPlaybackRate(const AudioPlaybackRate &rate) { 412 if (mAudioSink.get() != NULL) { 413 return mAudioSink->setPlaybackRate(rate); 414 } else if (mAudioTrack != 0){ 415 return mAudioTrack->setPlaybackRate(rate); 416 } else { 417 return NO_INIT; 418 } 419 } 420 421 status_t AudioPlayer::getPlaybackRate(AudioPlaybackRate *rate /* nonnull */) { 422 if (mAudioSink.get() != NULL) { 423 return mAudioSink->getPlaybackRate(rate); 424 } else if (mAudioTrack != 0) { 425 *rate = mAudioTrack->getPlaybackRate(); 426 return OK; 427 } else { 428 return NO_INIT; 429 } 430 } 431 432 // static 433 size_t AudioPlayer::AudioSinkCallback( 434 MediaPlayerBase::AudioSink * /* audioSink */, 435 void *buffer, size_t size, void *cookie, 436 MediaPlayerBase::AudioSink::cb_event_t event) { 437 AudioPlayer *me = (AudioPlayer *)cookie; 438 439 switch(event) { 440 case MediaPlayerBase::AudioSink::CB_EVENT_FILL_BUFFER: 441 return me->fillBuffer(buffer, size); 442 443 case MediaPlayerBase::AudioSink::CB_EVENT_STREAM_END: 444 ALOGV("AudioSinkCallback: stream end"); 445 me->mReachedEOS = true; 446 me->notifyAudioEOS(); 447 break; 448 449 case MediaPlayerBase::AudioSink::CB_EVENT_TEAR_DOWN: 450 ALOGV("AudioSinkCallback: Tear down event"); 451 me->mObserver->postAudioTearDown(); 452 break; 453 } 454 455 return 0; 456 } 457 458 void AudioPlayer::AudioCallback(int event, void *info) { 459 switch (event) { 460 case AudioTrack::EVENT_MORE_DATA: 461 { 462 AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info; 463 size_t numBytesWritten = fillBuffer(buffer->raw, buffer->size); 464 buffer->size = numBytesWritten; 465 } 466 break; 467 468 case AudioTrack::EVENT_STREAM_END: 469 mReachedEOS = true; 470 notifyAudioEOS(); 471 break; 472 } 473 } 474 475 uint32_t AudioPlayer::getNumFramesPendingPlayout() const { 476 uint32_t numFramesPlayedOut; 477 status_t err; 478 479 if (mAudioSink != NULL) { 480 err = mAudioSink->getPosition(&numFramesPlayedOut); 481 } else { 482 err = mAudioTrack->getPosition(&numFramesPlayedOut); 483 } 484 485 if (err != OK || mNumFramesPlayed < numFramesPlayedOut) { 486 return 0; 487 } 488 489 // mNumFramesPlayed is the number of frames submitted 490 // to the audio sink for playback, but not all of them 491 // may have played out by now. 492 return mNumFramesPlayed - numFramesPlayedOut; 493 } 494 495 size_t AudioPlayer::fillBuffer(void *data, size_t size) { 496 if (mNumFramesPlayed == 0) { 497 ALOGV("AudioCallback"); 498 } 499 500 if (mReachedEOS) { 501 return 0; 502 } 503 504 bool postSeekComplete = false; 505 bool postEOS = false; 506 int64_t postEOSDelayUs = 0; 507 508 size_t size_done = 0; 509 size_t size_remaining = size; 510 while (size_remaining > 0) { 511 MediaSource::ReadOptions options; 512 bool refreshSeekTime = false; 513 514 { 515 Mutex::Autolock autoLock(mLock); 516 517 if (mSeeking) { 518 if (mIsFirstBuffer) { 519 if (mFirstBuffer != NULL) { 520 mFirstBuffer->release(); 521 mFirstBuffer = NULL; 522 } 523 mIsFirstBuffer = false; 524 } 525 526 options.setSeekTo(mSeekTimeUs); 527 refreshSeekTime = true; 528 529 if (mInputBuffer != NULL) { 530 mInputBuffer->release(); 531 mInputBuffer = NULL; 532 } 533 534 mSeeking = false; 535 if (mObserver) { 536 postSeekComplete = true; 537 } 538 } 539 } 540 541 if (mInputBuffer == NULL) { 542 status_t err; 543 544 if (mIsFirstBuffer) { 545 mInputBuffer = mFirstBuffer; 546 mFirstBuffer = NULL; 547 err = mFirstBufferResult; 548 549 mIsFirstBuffer = false; 550 } else { 551 err = mSource->read(&mInputBuffer, &options); 552 } 553 554 CHECK((err == OK && mInputBuffer != NULL) 555 || (err != OK && mInputBuffer == NULL)); 556 557 Mutex::Autolock autoLock(mLock); 558 559 if (err != OK) { 560 if (!mReachedEOS) { 561 if (useOffload()) { 562 // no more buffers to push - stop() and wait for STREAM_END 563 // don't set mReachedEOS until stream end received 564 if (mAudioSink != NULL) { 565 mAudioSink->stop(); 566 } else { 567 mAudioTrack->stop(); 568 } 569 } else { 570 if (mObserver) { 571 // We don't want to post EOS right away but only 572 // after all frames have actually been played out. 573 574 // These are the number of frames submitted to the 575 // AudioTrack that you haven't heard yet. 576 uint32_t numFramesPendingPlayout = 577 getNumFramesPendingPlayout(); 578 579 // These are the number of frames we're going to 580 // submit to the AudioTrack by returning from this 581 // callback. 582 uint32_t numAdditionalFrames = size_done / mFrameSize; 583 584 numFramesPendingPlayout += numAdditionalFrames; 585 586 int64_t timeToCompletionUs = 587 (1000000ll * numFramesPendingPlayout) / mSampleRate; 588 589 ALOGV("total number of frames played: %" PRId64 " (%lld us)", 590 (mNumFramesPlayed + numAdditionalFrames), 591 1000000ll * (mNumFramesPlayed + numAdditionalFrames) 592 / mSampleRate); 593 594 ALOGV("%d frames left to play, %" PRId64 " us (%.2f secs)", 595 numFramesPendingPlayout, 596 timeToCompletionUs, timeToCompletionUs / 1E6); 597 598 postEOS = true; 599 if (mAudioSink->needsTrailingPadding()) { 600 postEOSDelayUs = timeToCompletionUs + mLatencyUs; 601 } else { 602 postEOSDelayUs = 0; 603 } 604 } 605 606 mReachedEOS = true; 607 } 608 } 609 610 mFinalStatus = err; 611 break; 612 } 613 614 if (mAudioSink != NULL) { 615 mLatencyUs = (int64_t)mAudioSink->latency() * 1000; 616 } else { 617 mLatencyUs = (int64_t)mAudioTrack->latency() * 1000; 618 } 619 620 if(mInputBuffer->range_length() != 0) { 621 CHECK(mInputBuffer->meta_data()->findInt64( 622 kKeyTime, &mPositionTimeMediaUs)); 623 } 624 625 // need to adjust the mStartPosUs for offload decoding since parser 626 // might not be able to get the exact seek time requested. 627 if (refreshSeekTime) { 628 if (useOffload()) { 629 if (postSeekComplete) { 630 ALOGV("fillBuffer is going to post SEEK_COMPLETE"); 631 mObserver->postAudioSeekComplete(); 632 postSeekComplete = false; 633 } 634 635 mStartPosUs = mPositionTimeMediaUs; 636 ALOGV("adjust seek time to: %.2f", mStartPosUs/ 1E6); 637 } 638 // clear seek time with mLock locked and once we have valid mPositionTimeMediaUs 639 // and mPositionTimeRealUs 640 // before clearing mSeekTimeUs check if a new seek request has been received while 641 // we were reading from the source with mLock released. 642 if (!mSeeking) { 643 mSeekTimeUs = 0; 644 } 645 } 646 647 if (!useOffload()) { 648 mPositionTimeRealUs = 649 ((mNumFramesPlayed + size_done / mFrameSize) * 1000000) 650 / mSampleRate; 651 ALOGV("buffer->size() = %zu, " 652 "mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f", 653 mInputBuffer->range_length(), 654 mPositionTimeMediaUs / 1E6, mPositionTimeRealUs / 1E6); 655 } 656 657 } 658 659 if (mInputBuffer->range_length() == 0) { 660 mInputBuffer->release(); 661 mInputBuffer = NULL; 662 663 continue; 664 } 665 666 size_t copy = size_remaining; 667 if (copy > mInputBuffer->range_length()) { 668 copy = mInputBuffer->range_length(); 669 } 670 671 memcpy((char *)data + size_done, 672 (const char *)mInputBuffer->data() + mInputBuffer->range_offset(), 673 copy); 674 675 mInputBuffer->set_range(mInputBuffer->range_offset() + copy, 676 mInputBuffer->range_length() - copy); 677 678 size_done += copy; 679 size_remaining -= copy; 680 } 681 682 if (useOffload()) { 683 // We must ask the hardware what it has played 684 mPositionTimeRealUs = getOutputPlayPositionUs_l(); 685 ALOGV("mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f", 686 mPositionTimeMediaUs / 1E6, mPositionTimeRealUs / 1E6); 687 } 688 689 { 690 Mutex::Autolock autoLock(mLock); 691 mNumFramesPlayed += size_done / mFrameSize; 692 mNumFramesPlayedSysTimeUs = ALooper::GetNowUs(); 693 694 if (mReachedEOS) { 695 mPinnedTimeUs = mNumFramesPlayedSysTimeUs; 696 } else { 697 mPinnedTimeUs = -1ll; 698 } 699 } 700 701 if (postEOS) { 702 mObserver->postAudioEOS(postEOSDelayUs); 703 } 704 705 if (postSeekComplete) { 706 mObserver->postAudioSeekComplete(); 707 } 708 709 return size_done; 710 } 711 712 int64_t AudioPlayer::getRealTimeUs() { 713 Mutex::Autolock autoLock(mLock); 714 if (useOffload()) { 715 if (mSeeking) { 716 return mSeekTimeUs; 717 } 718 mPositionTimeRealUs = getOutputPlayPositionUs_l(); 719 return mPositionTimeRealUs; 720 } 721 722 return getRealTimeUsLocked(); 723 } 724 725 int64_t AudioPlayer::getRealTimeUsLocked() const { 726 CHECK(mStarted); 727 CHECK_NE(mSampleRate, 0); 728 int64_t result = -mLatencyUs + (mNumFramesPlayed * 1000000) / mSampleRate; 729 730 // Compensate for large audio buffers, updates of mNumFramesPlayed 731 // are less frequent, therefore to get a "smoother" notion of time we 732 // compensate using system time. 733 int64_t diffUs; 734 if (mPinnedTimeUs >= 0ll) { 735 diffUs = mPinnedTimeUs; 736 } else { 737 diffUs = ALooper::GetNowUs(); 738 } 739 740 diffUs -= mNumFramesPlayedSysTimeUs; 741 742 return result + diffUs; 743 } 744 745 int64_t AudioPlayer::getOutputPlayPositionUs_l() 746 { 747 uint32_t playedSamples = 0; 748 uint32_t sampleRate; 749 if (mAudioSink != NULL) { 750 mAudioSink->getPosition(&playedSamples); 751 sampleRate = mAudioSink->getSampleRate(); 752 } else { 753 mAudioTrack->getPosition(&playedSamples); 754 sampleRate = mAudioTrack->getSampleRate(); 755 } 756 if (sampleRate != 0) { 757 mSampleRate = sampleRate; 758 } 759 760 int64_t playedUs; 761 if (mSampleRate != 0) { 762 playedUs = (static_cast<int64_t>(playedSamples) * 1000000 ) / mSampleRate; 763 } else { 764 playedUs = 0; 765 } 766 767 // HAL position is relative to the first buffer we sent at mStartPosUs 768 const int64_t renderedDuration = mStartPosUs + playedUs; 769 ALOGV("getOutputPlayPositionUs_l %" PRId64, renderedDuration); 770 return renderedDuration; 771 } 772 773 int64_t AudioPlayer::getMediaTimeUs() { 774 Mutex::Autolock autoLock(mLock); 775 776 if (useOffload()) { 777 if (mSeeking) { 778 return mSeekTimeUs; 779 } 780 if (mReachedEOS) { 781 int64_t durationUs; 782 mSource->getFormat()->findInt64(kKeyDuration, &durationUs); 783 return durationUs; 784 } 785 mPositionTimeRealUs = getOutputPlayPositionUs_l(); 786 ALOGV("getMediaTimeUs getOutputPlayPositionUs_l() mPositionTimeRealUs %" PRId64, 787 mPositionTimeRealUs); 788 return mPositionTimeRealUs; 789 } 790 791 792 if (mPositionTimeMediaUs < 0 || mPositionTimeRealUs < 0) { 793 // mSeekTimeUs is either seek time while seeking or 0 if playback did not start. 794 return mSeekTimeUs; 795 } 796 797 int64_t realTimeOffset = getRealTimeUsLocked() - mPositionTimeRealUs; 798 if (realTimeOffset < 0) { 799 realTimeOffset = 0; 800 } 801 802 return mPositionTimeMediaUs + realTimeOffset; 803 } 804 805 bool AudioPlayer::getMediaTimeMapping( 806 int64_t *realtime_us, int64_t *mediatime_us) { 807 Mutex::Autolock autoLock(mLock); 808 809 if (useOffload()) { 810 mPositionTimeRealUs = getOutputPlayPositionUs_l(); 811 *realtime_us = mPositionTimeRealUs; 812 *mediatime_us = mPositionTimeRealUs; 813 } else { 814 *realtime_us = mPositionTimeRealUs; 815 *mediatime_us = mPositionTimeMediaUs; 816 } 817 818 return mPositionTimeRealUs != -1 && mPositionTimeMediaUs != -1; 819 } 820 821 status_t AudioPlayer::seekTo(int64_t time_us) { 822 Mutex::Autolock autoLock(mLock); 823 824 ALOGV("seekTo( %" PRId64 " )", time_us); 825 826 mSeeking = true; 827 mPositionTimeRealUs = mPositionTimeMediaUs = -1; 828 mReachedEOS = false; 829 mSeekTimeUs = time_us; 830 mStartPosUs = time_us; 831 832 // Flush resets the number of played frames 833 mNumFramesPlayed = 0; 834 mNumFramesPlayedSysTimeUs = ALooper::GetNowUs(); 835 836 if (mAudioSink != NULL) { 837 if (mPlaying) { 838 mAudioSink->pause(); 839 } 840 mAudioSink->flush(); 841 if (mPlaying) { 842 mAudioSink->start(); 843 } 844 } else { 845 if (mPlaying) { 846 mAudioTrack->pause(); 847 } 848 mAudioTrack->flush(); 849 if (mPlaying) { 850 mAudioTrack->start(); 851 } 852 } 853 854 return OK; 855 } 856 857 } 858