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