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