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::setPlaybackRatePermille(int32_t ratePermille) { 412 if (mAudioSink.get() != NULL) { 413 return mAudioSink->setPlaybackRatePermille(ratePermille); 414 } else if (mAudioTrack != 0){ 415 return mAudioTrack->setSampleRate(ratePermille * mSampleRate / 1000); 416 } else { 417 return NO_INIT; 418 } 419 } 420 421 // static 422 size_t AudioPlayer::AudioSinkCallback( 423 MediaPlayerBase::AudioSink * /* audioSink */, 424 void *buffer, size_t size, void *cookie, 425 MediaPlayerBase::AudioSink::cb_event_t event) { 426 AudioPlayer *me = (AudioPlayer *)cookie; 427 428 switch(event) { 429 case MediaPlayerBase::AudioSink::CB_EVENT_FILL_BUFFER: 430 return me->fillBuffer(buffer, size); 431 432 case MediaPlayerBase::AudioSink::CB_EVENT_STREAM_END: 433 ALOGV("AudioSinkCallback: stream end"); 434 me->mReachedEOS = true; 435 me->notifyAudioEOS(); 436 break; 437 438 case MediaPlayerBase::AudioSink::CB_EVENT_TEAR_DOWN: 439 ALOGV("AudioSinkCallback: Tear down event"); 440 me->mObserver->postAudioTearDown(); 441 break; 442 } 443 444 return 0; 445 } 446 447 void AudioPlayer::AudioCallback(int event, void *info) { 448 switch (event) { 449 case AudioTrack::EVENT_MORE_DATA: 450 { 451 AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info; 452 size_t numBytesWritten = fillBuffer(buffer->raw, buffer->size); 453 buffer->size = numBytesWritten; 454 } 455 break; 456 457 case AudioTrack::EVENT_STREAM_END: 458 mReachedEOS = true; 459 notifyAudioEOS(); 460 break; 461 } 462 } 463 464 uint32_t AudioPlayer::getNumFramesPendingPlayout() const { 465 uint32_t numFramesPlayedOut; 466 status_t err; 467 468 if (mAudioSink != NULL) { 469 err = mAudioSink->getPosition(&numFramesPlayedOut); 470 } else { 471 err = mAudioTrack->getPosition(&numFramesPlayedOut); 472 } 473 474 if (err != OK || mNumFramesPlayed < numFramesPlayedOut) { 475 return 0; 476 } 477 478 // mNumFramesPlayed is the number of frames submitted 479 // to the audio sink for playback, but not all of them 480 // may have played out by now. 481 return mNumFramesPlayed - numFramesPlayedOut; 482 } 483 484 size_t AudioPlayer::fillBuffer(void *data, size_t size) { 485 if (mNumFramesPlayed == 0) { 486 ALOGV("AudioCallback"); 487 } 488 489 if (mReachedEOS) { 490 return 0; 491 } 492 493 bool postSeekComplete = false; 494 bool postEOS = false; 495 int64_t postEOSDelayUs = 0; 496 497 size_t size_done = 0; 498 size_t size_remaining = size; 499 while (size_remaining > 0) { 500 MediaSource::ReadOptions options; 501 bool refreshSeekTime = false; 502 503 { 504 Mutex::Autolock autoLock(mLock); 505 506 if (mSeeking) { 507 if (mIsFirstBuffer) { 508 if (mFirstBuffer != NULL) { 509 mFirstBuffer->release(); 510 mFirstBuffer = NULL; 511 } 512 mIsFirstBuffer = false; 513 } 514 515 options.setSeekTo(mSeekTimeUs); 516 refreshSeekTime = true; 517 518 if (mInputBuffer != NULL) { 519 mInputBuffer->release(); 520 mInputBuffer = NULL; 521 } 522 523 mSeeking = false; 524 if (mObserver) { 525 postSeekComplete = true; 526 } 527 } 528 } 529 530 if (mInputBuffer == NULL) { 531 status_t err; 532 533 if (mIsFirstBuffer) { 534 mInputBuffer = mFirstBuffer; 535 mFirstBuffer = NULL; 536 err = mFirstBufferResult; 537 538 mIsFirstBuffer = false; 539 } else { 540 err = mSource->read(&mInputBuffer, &options); 541 } 542 543 CHECK((err == OK && mInputBuffer != NULL) 544 || (err != OK && mInputBuffer == NULL)); 545 546 Mutex::Autolock autoLock(mLock); 547 548 if (err != OK) { 549 if (!mReachedEOS) { 550 if (useOffload()) { 551 // no more buffers to push - stop() and wait for STREAM_END 552 // don't set mReachedEOS until stream end received 553 if (mAudioSink != NULL) { 554 mAudioSink->stop(); 555 } else { 556 mAudioTrack->stop(); 557 } 558 } else { 559 if (mObserver) { 560 // We don't want to post EOS right away but only 561 // after all frames have actually been played out. 562 563 // These are the number of frames submitted to the 564 // AudioTrack that you haven't heard yet. 565 uint32_t numFramesPendingPlayout = 566 getNumFramesPendingPlayout(); 567 568 // These are the number of frames we're going to 569 // submit to the AudioTrack by returning from this 570 // callback. 571 uint32_t numAdditionalFrames = size_done / mFrameSize; 572 573 numFramesPendingPlayout += numAdditionalFrames; 574 575 int64_t timeToCompletionUs = 576 (1000000ll * numFramesPendingPlayout) / mSampleRate; 577 578 ALOGV("total number of frames played: %" PRId64 " (%lld us)", 579 (mNumFramesPlayed + numAdditionalFrames), 580 1000000ll * (mNumFramesPlayed + numAdditionalFrames) 581 / mSampleRate); 582 583 ALOGV("%d frames left to play, %" PRId64 " us (%.2f secs)", 584 numFramesPendingPlayout, 585 timeToCompletionUs, timeToCompletionUs / 1E6); 586 587 postEOS = true; 588 if (mAudioSink->needsTrailingPadding()) { 589 postEOSDelayUs = timeToCompletionUs + mLatencyUs; 590 } else { 591 postEOSDelayUs = 0; 592 } 593 } 594 595 mReachedEOS = true; 596 } 597 } 598 599 mFinalStatus = err; 600 break; 601 } 602 603 if (mAudioSink != NULL) { 604 mLatencyUs = (int64_t)mAudioSink->latency() * 1000; 605 } else { 606 mLatencyUs = (int64_t)mAudioTrack->latency() * 1000; 607 } 608 609 if(mInputBuffer->range_length() != 0) { 610 CHECK(mInputBuffer->meta_data()->findInt64( 611 kKeyTime, &mPositionTimeMediaUs)); 612 } 613 614 // need to adjust the mStartPosUs for offload decoding since parser 615 // might not be able to get the exact seek time requested. 616 if (refreshSeekTime) { 617 if (useOffload()) { 618 if (postSeekComplete) { 619 ALOGV("fillBuffer is going to post SEEK_COMPLETE"); 620 mObserver->postAudioSeekComplete(); 621 postSeekComplete = false; 622 } 623 624 mStartPosUs = mPositionTimeMediaUs; 625 ALOGV("adjust seek time to: %.2f", mStartPosUs/ 1E6); 626 } 627 // clear seek time with mLock locked and once we have valid mPositionTimeMediaUs 628 // and mPositionTimeRealUs 629 // before clearing mSeekTimeUs check if a new seek request has been received while 630 // we were reading from the source with mLock released. 631 if (!mSeeking) { 632 mSeekTimeUs = 0; 633 } 634 } 635 636 if (!useOffload()) { 637 mPositionTimeRealUs = 638 ((mNumFramesPlayed + size_done / mFrameSize) * 1000000) 639 / mSampleRate; 640 ALOGV("buffer->size() = %zu, " 641 "mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f", 642 mInputBuffer->range_length(), 643 mPositionTimeMediaUs / 1E6, mPositionTimeRealUs / 1E6); 644 } 645 646 } 647 648 if (mInputBuffer->range_length() == 0) { 649 mInputBuffer->release(); 650 mInputBuffer = NULL; 651 652 continue; 653 } 654 655 size_t copy = size_remaining; 656 if (copy > mInputBuffer->range_length()) { 657 copy = mInputBuffer->range_length(); 658 } 659 660 memcpy((char *)data + size_done, 661 (const char *)mInputBuffer->data() + mInputBuffer->range_offset(), 662 copy); 663 664 mInputBuffer->set_range(mInputBuffer->range_offset() + copy, 665 mInputBuffer->range_length() - copy); 666 667 size_done += copy; 668 size_remaining -= copy; 669 } 670 671 if (useOffload()) { 672 // We must ask the hardware what it has played 673 mPositionTimeRealUs = getOutputPlayPositionUs_l(); 674 ALOGV("mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f", 675 mPositionTimeMediaUs / 1E6, mPositionTimeRealUs / 1E6); 676 } 677 678 { 679 Mutex::Autolock autoLock(mLock); 680 mNumFramesPlayed += size_done / mFrameSize; 681 mNumFramesPlayedSysTimeUs = ALooper::GetNowUs(); 682 683 if (mReachedEOS) { 684 mPinnedTimeUs = mNumFramesPlayedSysTimeUs; 685 } else { 686 mPinnedTimeUs = -1ll; 687 } 688 } 689 690 if (postEOS) { 691 mObserver->postAudioEOS(postEOSDelayUs); 692 } 693 694 if (postSeekComplete) { 695 mObserver->postAudioSeekComplete(); 696 } 697 698 return size_done; 699 } 700 701 int64_t AudioPlayer::getRealTimeUs() { 702 Mutex::Autolock autoLock(mLock); 703 if (useOffload()) { 704 if (mSeeking) { 705 return mSeekTimeUs; 706 } 707 mPositionTimeRealUs = getOutputPlayPositionUs_l(); 708 return mPositionTimeRealUs; 709 } 710 711 return getRealTimeUsLocked(); 712 } 713 714 int64_t AudioPlayer::getRealTimeUsLocked() const { 715 CHECK(mStarted); 716 CHECK_NE(mSampleRate, 0); 717 int64_t result = -mLatencyUs + (mNumFramesPlayed * 1000000) / mSampleRate; 718 719 // Compensate for large audio buffers, updates of mNumFramesPlayed 720 // are less frequent, therefore to get a "smoother" notion of time we 721 // compensate using system time. 722 int64_t diffUs; 723 if (mPinnedTimeUs >= 0ll) { 724 diffUs = mPinnedTimeUs; 725 } else { 726 diffUs = ALooper::GetNowUs(); 727 } 728 729 diffUs -= mNumFramesPlayedSysTimeUs; 730 731 return result + diffUs; 732 } 733 734 int64_t AudioPlayer::getOutputPlayPositionUs_l() 735 { 736 uint32_t playedSamples = 0; 737 uint32_t sampleRate; 738 if (mAudioSink != NULL) { 739 mAudioSink->getPosition(&playedSamples); 740 sampleRate = mAudioSink->getSampleRate(); 741 } else { 742 mAudioTrack->getPosition(&playedSamples); 743 sampleRate = mAudioTrack->getSampleRate(); 744 } 745 if (sampleRate != 0) { 746 mSampleRate = sampleRate; 747 } 748 749 int64_t playedUs; 750 if (mSampleRate != 0) { 751 playedUs = (static_cast<int64_t>(playedSamples) * 1000000 ) / mSampleRate; 752 } else { 753 playedUs = 0; 754 } 755 756 // HAL position is relative to the first buffer we sent at mStartPosUs 757 const int64_t renderedDuration = mStartPosUs + playedUs; 758 ALOGV("getOutputPlayPositionUs_l %" PRId64, renderedDuration); 759 return renderedDuration; 760 } 761 762 int64_t AudioPlayer::getMediaTimeUs() { 763 Mutex::Autolock autoLock(mLock); 764 765 if (useOffload()) { 766 if (mSeeking) { 767 return mSeekTimeUs; 768 } 769 if (mReachedEOS) { 770 int64_t durationUs; 771 mSource->getFormat()->findInt64(kKeyDuration, &durationUs); 772 return durationUs; 773 } 774 mPositionTimeRealUs = getOutputPlayPositionUs_l(); 775 ALOGV("getMediaTimeUs getOutputPlayPositionUs_l() mPositionTimeRealUs %" PRId64, 776 mPositionTimeRealUs); 777 return mPositionTimeRealUs; 778 } 779 780 781 if (mPositionTimeMediaUs < 0 || mPositionTimeRealUs < 0) { 782 // mSeekTimeUs is either seek time while seeking or 0 if playback did not start. 783 return mSeekTimeUs; 784 } 785 786 int64_t realTimeOffset = getRealTimeUsLocked() - mPositionTimeRealUs; 787 if (realTimeOffset < 0) { 788 realTimeOffset = 0; 789 } 790 791 return mPositionTimeMediaUs + realTimeOffset; 792 } 793 794 bool AudioPlayer::getMediaTimeMapping( 795 int64_t *realtime_us, int64_t *mediatime_us) { 796 Mutex::Autolock autoLock(mLock); 797 798 if (useOffload()) { 799 mPositionTimeRealUs = getOutputPlayPositionUs_l(); 800 *realtime_us = mPositionTimeRealUs; 801 *mediatime_us = mPositionTimeRealUs; 802 } else { 803 *realtime_us = mPositionTimeRealUs; 804 *mediatime_us = mPositionTimeMediaUs; 805 } 806 807 return mPositionTimeRealUs != -1 && mPositionTimeMediaUs != -1; 808 } 809 810 status_t AudioPlayer::seekTo(int64_t time_us) { 811 Mutex::Autolock autoLock(mLock); 812 813 ALOGV("seekTo( %" PRId64 " )", time_us); 814 815 mSeeking = true; 816 mPositionTimeRealUs = mPositionTimeMediaUs = -1; 817 mReachedEOS = false; 818 mSeekTimeUs = time_us; 819 mStartPosUs = time_us; 820 821 // Flush resets the number of played frames 822 mNumFramesPlayed = 0; 823 mNumFramesPlayedSysTimeUs = ALooper::GetNowUs(); 824 825 if (mAudioSink != NULL) { 826 if (mPlaying) { 827 mAudioSink->pause(); 828 } 829 mAudioSink->flush(); 830 if (mPlaying) { 831 mAudioSink->start(); 832 } 833 } else { 834 if (mPlaying) { 835 mAudioTrack->pause(); 836 } 837 mAudioTrack->flush(); 838 if (mPlaying) { 839 mAudioTrack->start(); 840 } 841 } 842 843 return OK; 844 } 845 846 } 847