AudioPlayer.cpp revision ad3af3305f024bcbbd55c894a4995e449498e1ba
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 21#include <binder/IPCThreadState.h> 22#include <media/AudioTrack.h> 23#include <media/stagefright/foundation/ADebug.h> 24#include <media/stagefright/foundation/ALooper.h> 25#include <media/stagefright/AudioPlayer.h> 26#include <media/stagefright/MediaDefs.h> 27#include <media/stagefright/MediaErrors.h> 28#include <media/stagefright/MediaSource.h> 29#include <media/stagefright/MetaData.h> 30 31#include "include/AwesomePlayer.h" 32 33namespace android { 34 35AudioPlayer::AudioPlayer( 36 const sp<MediaPlayerBase::AudioSink> &audioSink, 37 uint32_t flags, 38 AwesomePlayer *observer) 39 : mInputBuffer(NULL), 40 mSampleRate(0), 41 mLatencyUs(0), 42 mFrameSize(0), 43 mNumFramesPlayed(0), 44 mNumFramesPlayedSysTimeUs(ALooper::GetNowUs()), 45 mPositionTimeMediaUs(-1), 46 mPositionTimeRealUs(-1), 47 mSeeking(false), 48 mReachedEOS(false), 49 mFinalStatus(OK), 50 mStarted(false), 51 mIsFirstBuffer(false), 52 mFirstBufferResult(OK), 53 mFirstBuffer(NULL), 54 mAudioSink(audioSink), 55 mAllowDeepBuffering((flags & ALLOW_DEEP_BUFFERING) != 0), 56 mObserver(observer), 57 mPinnedTimeUs(-1ll) { 58} 59 60AudioPlayer::~AudioPlayer() { 61 if (mStarted) { 62 reset(); 63 } 64} 65 66void AudioPlayer::setSource(const sp<MediaSource> &source) { 67 CHECK(mSource == NULL); 68 mSource = source; 69} 70 71status_t AudioPlayer::start(bool sourceAlreadyStarted) { 72 CHECK(!mStarted); 73 CHECK(mSource != NULL); 74 75 status_t err; 76 if (!sourceAlreadyStarted) { 77 err = mSource->start(); 78 79 if (err != OK) { 80 return err; 81 } 82 } 83 84 // We allow an optional INFO_FORMAT_CHANGED at the very beginning 85 // of playback, if there is one, getFormat below will retrieve the 86 // updated format, if there isn't, we'll stash away the valid buffer 87 // of data to be used on the first audio callback. 88 89 CHECK(mFirstBuffer == NULL); 90 91 MediaSource::ReadOptions options; 92 if (mSeeking) { 93 options.setSeekTo(mSeekTimeUs); 94 mSeeking = false; 95 } 96 97 mFirstBufferResult = mSource->read(&mFirstBuffer, &options); 98 if (mFirstBufferResult == INFO_FORMAT_CHANGED) { 99 ALOGV("INFO_FORMAT_CHANGED!!!"); 100 101 CHECK(mFirstBuffer == NULL); 102 mFirstBufferResult = OK; 103 mIsFirstBuffer = false; 104 } else { 105 mIsFirstBuffer = true; 106 } 107 108 sp<MetaData> format = mSource->getFormat(); 109 const char *mime; 110 bool success = format->findCString(kKeyMIMEType, &mime); 111 CHECK(success); 112 CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)); 113 114 success = format->findInt32(kKeySampleRate, &mSampleRate); 115 CHECK(success); 116 117 int32_t numChannels, channelMask; 118 success = format->findInt32(kKeyChannelCount, &numChannels); 119 CHECK(success); 120 121 if(!format->findInt32(kKeyChannelMask, &channelMask)) { 122 // log only when there's a risk of ambiguity of channel mask selection 123 ALOGI_IF(numChannels > 2, 124 "source format didn't specify channel mask, using (%d) channel order", numChannels); 125 channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER; 126 } 127 128 if (mAudioSink.get() != NULL) { 129 130 status_t err = mAudioSink->open( 131 mSampleRate, numChannels, channelMask, AUDIO_FORMAT_PCM_16_BIT, 132 DEFAULT_AUDIOSINK_BUFFERCOUNT, 133 &AudioPlayer::AudioSinkCallback, 134 this, 135 (mAllowDeepBuffering ? 136 AUDIO_OUTPUT_FLAG_DEEP_BUFFER : 137 AUDIO_OUTPUT_FLAG_NONE)); 138 if (err != OK) { 139 if (mFirstBuffer != NULL) { 140 mFirstBuffer->release(); 141 mFirstBuffer = NULL; 142 } 143 144 if (!sourceAlreadyStarted) { 145 mSource->stop(); 146 } 147 148 return err; 149 } 150 151 mLatencyUs = (int64_t)mAudioSink->latency() * 1000; 152 mFrameSize = mAudioSink->frameSize(); 153 154 mAudioSink->start(); 155 } else { 156 // playing to an AudioTrack, set up mask if necessary 157 audio_channel_mask_t audioMask = channelMask == CHANNEL_MASK_USE_CHANNEL_ORDER ? 158 audio_channel_out_mask_from_count(numChannels) : channelMask; 159 if (0 == audioMask) { 160 return BAD_VALUE; 161 } 162 163 mAudioTrack = new AudioTrack( 164 AUDIO_STREAM_MUSIC, mSampleRate, AUDIO_FORMAT_PCM_16_BIT, audioMask, 165 0, AUDIO_OUTPUT_FLAG_NONE, &AudioCallback, this, 0); 166 167 if ((err = mAudioTrack->initCheck()) != OK) { 168 mAudioTrack.clear(); 169 170 if (mFirstBuffer != NULL) { 171 mFirstBuffer->release(); 172 mFirstBuffer = NULL; 173 } 174 175 if (!sourceAlreadyStarted) { 176 mSource->stop(); 177 } 178 179 return err; 180 } 181 182 mLatencyUs = (int64_t)mAudioTrack->latency() * 1000; 183 mFrameSize = mAudioTrack->frameSize(); 184 185 mAudioTrack->start(); 186 } 187 188 mStarted = true; 189 mPinnedTimeUs = -1ll; 190 191 return OK; 192} 193 194void AudioPlayer::pause(bool playPendingSamples) { 195 CHECK(mStarted); 196 197 if (playPendingSamples) { 198 if (mAudioSink.get() != NULL) { 199 mAudioSink->stop(); 200 } else { 201 mAudioTrack->stop(); 202 } 203 204 mNumFramesPlayed = 0; 205 mNumFramesPlayedSysTimeUs = ALooper::GetNowUs(); 206 } else { 207 if (mAudioSink.get() != NULL) { 208 mAudioSink->pause(); 209 } else { 210 mAudioTrack->pause(); 211 } 212 213 mPinnedTimeUs = ALooper::GetNowUs(); 214 } 215} 216 217void AudioPlayer::resume() { 218 CHECK(mStarted); 219 220 if (mAudioSink.get() != NULL) { 221 mAudioSink->start(); 222 } else { 223 mAudioTrack->start(); 224 } 225} 226 227void AudioPlayer::reset() { 228 CHECK(mStarted); 229 230 if (mAudioSink.get() != NULL) { 231 mAudioSink->stop(); 232 mAudioSink->close(); 233 } else { 234 mAudioTrack->stop(); 235 236 mAudioTrack.clear(); 237 } 238 239 // Make sure to release any buffer we hold onto so that the 240 // source is able to stop(). 241 242 if (mFirstBuffer != NULL) { 243 mFirstBuffer->release(); 244 mFirstBuffer = NULL; 245 } 246 247 if (mInputBuffer != NULL) { 248 ALOGV("AudioPlayer releasing input buffer."); 249 250 mInputBuffer->release(); 251 mInputBuffer = NULL; 252 } 253 254 mSource->stop(); 255 256 // The following hack is necessary to ensure that the OMX 257 // component is completely released by the time we may try 258 // to instantiate it again. 259 wp<MediaSource> tmp = mSource; 260 mSource.clear(); 261 while (tmp.promote() != NULL) { 262 usleep(1000); 263 } 264 IPCThreadState::self()->flushCommands(); 265 266 mNumFramesPlayed = 0; 267 mNumFramesPlayedSysTimeUs = ALooper::GetNowUs(); 268 mPositionTimeMediaUs = -1; 269 mPositionTimeRealUs = -1; 270 mSeeking = false; 271 mReachedEOS = false; 272 mFinalStatus = OK; 273 mStarted = false; 274} 275 276// static 277void AudioPlayer::AudioCallback(int event, void *user, void *info) { 278 static_cast<AudioPlayer *>(user)->AudioCallback(event, info); 279} 280 281bool AudioPlayer::isSeeking() { 282 Mutex::Autolock autoLock(mLock); 283 return mSeeking; 284} 285 286bool AudioPlayer::reachedEOS(status_t *finalStatus) { 287 *finalStatus = OK; 288 289 Mutex::Autolock autoLock(mLock); 290 *finalStatus = mFinalStatus; 291 return mReachedEOS; 292} 293 294status_t AudioPlayer::setPlaybackRatePermille(int32_t ratePermille) { 295 if (mAudioSink.get() != NULL) { 296 return mAudioSink->setPlaybackRatePermille(ratePermille); 297 } else if (mAudioTrack != 0){ 298 return mAudioTrack->setSampleRate(ratePermille * mSampleRate / 1000); 299 } else { 300 return NO_INIT; 301 } 302} 303 304// static 305size_t AudioPlayer::AudioSinkCallback( 306 MediaPlayerBase::AudioSink *audioSink, 307 void *buffer, size_t size, void *cookie, 308 MediaPlayerBase::AudioSink::cb_event_t event) { 309 AudioPlayer *me = (AudioPlayer *)cookie; 310 311 return me->fillBuffer(buffer, size); 312} 313 314void AudioPlayer::AudioCallback(int event, void *info) { 315 if (event != AudioTrack::EVENT_MORE_DATA) { 316 return; 317 } 318 319 AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info; 320 size_t numBytesWritten = fillBuffer(buffer->raw, buffer->size); 321 322 buffer->size = numBytesWritten; 323} 324 325uint32_t AudioPlayer::getNumFramesPendingPlayout() const { 326 uint32_t numFramesPlayedOut; 327 status_t err; 328 329 if (mAudioSink != NULL) { 330 err = mAudioSink->getPosition(&numFramesPlayedOut); 331 } else { 332 err = mAudioTrack->getPosition(&numFramesPlayedOut); 333 } 334 335 if (err != OK || mNumFramesPlayed < numFramesPlayedOut) { 336 return 0; 337 } 338 339 // mNumFramesPlayed is the number of frames submitted 340 // to the audio sink for playback, but not all of them 341 // may have played out by now. 342 return mNumFramesPlayed - numFramesPlayedOut; 343} 344 345size_t AudioPlayer::fillBuffer(void *data, size_t size) { 346 if (mNumFramesPlayed == 0) { 347 ALOGV("AudioCallback"); 348 } 349 350 if (mReachedEOS) { 351 return 0; 352 } 353 354 bool postSeekComplete = false; 355 bool postEOS = false; 356 int64_t postEOSDelayUs = 0; 357 358 size_t size_done = 0; 359 size_t size_remaining = size; 360 while (size_remaining > 0) { 361 MediaSource::ReadOptions options; 362 363 { 364 Mutex::Autolock autoLock(mLock); 365 366 if (mSeeking) { 367 if (mIsFirstBuffer) { 368 if (mFirstBuffer != NULL) { 369 mFirstBuffer->release(); 370 mFirstBuffer = NULL; 371 } 372 mIsFirstBuffer = false; 373 } 374 375 options.setSeekTo(mSeekTimeUs); 376 377 if (mInputBuffer != NULL) { 378 mInputBuffer->release(); 379 mInputBuffer = NULL; 380 } 381 382 mSeeking = false; 383 if (mObserver) { 384 postSeekComplete = true; 385 } 386 } 387 } 388 389 if (mInputBuffer == NULL) { 390 status_t err; 391 392 if (mIsFirstBuffer) { 393 mInputBuffer = mFirstBuffer; 394 mFirstBuffer = NULL; 395 err = mFirstBufferResult; 396 397 mIsFirstBuffer = false; 398 } else { 399 err = mSource->read(&mInputBuffer, &options); 400 } 401 402 CHECK((err == OK && mInputBuffer != NULL) 403 || (err != OK && mInputBuffer == NULL)); 404 405 Mutex::Autolock autoLock(mLock); 406 407 if (err != OK) { 408 if (mObserver && !mReachedEOS) { 409 // We don't want to post EOS right away but only 410 // after all frames have actually been played out. 411 412 // These are the number of frames submitted to the 413 // AudioTrack that you haven't heard yet. 414 uint32_t numFramesPendingPlayout = 415 getNumFramesPendingPlayout(); 416 417 // These are the number of frames we're going to 418 // submit to the AudioTrack by returning from this 419 // callback. 420 uint32_t numAdditionalFrames = size_done / mFrameSize; 421 422 numFramesPendingPlayout += numAdditionalFrames; 423 424 int64_t timeToCompletionUs = 425 (1000000ll * numFramesPendingPlayout) / mSampleRate; 426 427 ALOGV("total number of frames played: %lld (%lld us)", 428 (mNumFramesPlayed + numAdditionalFrames), 429 1000000ll * (mNumFramesPlayed + numAdditionalFrames) 430 / mSampleRate); 431 432 ALOGV("%d frames left to play, %lld us (%.2f secs)", 433 numFramesPendingPlayout, 434 timeToCompletionUs, timeToCompletionUs / 1E6); 435 436 postEOS = true; 437 if (mAudioSink->needsTrailingPadding()) { 438 postEOSDelayUs = timeToCompletionUs + mLatencyUs; 439 } else { 440 postEOSDelayUs = 0; 441 } 442 } 443 444 mReachedEOS = true; 445 mFinalStatus = err; 446 break; 447 } 448 449 if (mAudioSink != NULL) { 450 mLatencyUs = (int64_t)mAudioSink->latency() * 1000; 451 } else { 452 mLatencyUs = (int64_t)mAudioTrack->latency() * 1000; 453 } 454 455 CHECK(mInputBuffer->meta_data()->findInt64( 456 kKeyTime, &mPositionTimeMediaUs)); 457 458 mPositionTimeRealUs = 459 ((mNumFramesPlayed + size_done / mFrameSize) * 1000000) 460 / mSampleRate; 461 462 ALOGV("buffer->size() = %d, " 463 "mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f", 464 mInputBuffer->range_length(), 465 mPositionTimeMediaUs / 1E6, mPositionTimeRealUs / 1E6); 466 } 467 468 if (mInputBuffer->range_length() == 0) { 469 mInputBuffer->release(); 470 mInputBuffer = NULL; 471 472 continue; 473 } 474 475 size_t copy = size_remaining; 476 if (copy > mInputBuffer->range_length()) { 477 copy = mInputBuffer->range_length(); 478 } 479 480 memcpy((char *)data + size_done, 481 (const char *)mInputBuffer->data() + mInputBuffer->range_offset(), 482 copy); 483 484 mInputBuffer->set_range(mInputBuffer->range_offset() + copy, 485 mInputBuffer->range_length() - copy); 486 487 size_done += copy; 488 size_remaining -= copy; 489 } 490 491 { 492 Mutex::Autolock autoLock(mLock); 493 mNumFramesPlayed += size_done / mFrameSize; 494 mNumFramesPlayedSysTimeUs = ALooper::GetNowUs(); 495 496 if (mReachedEOS) { 497 mPinnedTimeUs = mNumFramesPlayedSysTimeUs; 498 } else { 499 mPinnedTimeUs = -1ll; 500 } 501 } 502 503 if (postEOS) { 504 mObserver->postAudioEOS(postEOSDelayUs); 505 } 506 507 if (postSeekComplete) { 508 mObserver->postAudioSeekComplete(); 509 } 510 511 return size_done; 512} 513 514int64_t AudioPlayer::getRealTimeUs() { 515 Mutex::Autolock autoLock(mLock); 516 return getRealTimeUsLocked(); 517} 518 519int64_t AudioPlayer::getRealTimeUsLocked() const { 520 CHECK(mStarted); 521 CHECK_NE(mSampleRate, 0); 522 int64_t result = -mLatencyUs + (mNumFramesPlayed * 1000000) / mSampleRate; 523 524 // Compensate for large audio buffers, updates of mNumFramesPlayed 525 // are less frequent, therefore to get a "smoother" notion of time we 526 // compensate using system time. 527 int64_t diffUs; 528 if (mPinnedTimeUs >= 0ll) { 529 diffUs = mPinnedTimeUs; 530 } else { 531 diffUs = ALooper::GetNowUs(); 532 } 533 534 diffUs -= mNumFramesPlayedSysTimeUs; 535 536 return result + diffUs; 537} 538 539int64_t AudioPlayer::getMediaTimeUs() { 540 Mutex::Autolock autoLock(mLock); 541 542 if (mPositionTimeMediaUs < 0 || mPositionTimeRealUs < 0) { 543 if (mSeeking) { 544 return mSeekTimeUs; 545 } 546 547 return 0; 548 } 549 550 int64_t realTimeOffset = getRealTimeUsLocked() - mPositionTimeRealUs; 551 if (realTimeOffset < 0) { 552 realTimeOffset = 0; 553 } 554 555 return mPositionTimeMediaUs + realTimeOffset; 556} 557 558bool AudioPlayer::getMediaTimeMapping( 559 int64_t *realtime_us, int64_t *mediatime_us) { 560 Mutex::Autolock autoLock(mLock); 561 562 *realtime_us = mPositionTimeRealUs; 563 *mediatime_us = mPositionTimeMediaUs; 564 565 return mPositionTimeRealUs != -1 && mPositionTimeMediaUs != -1; 566} 567 568status_t AudioPlayer::seekTo(int64_t time_us) { 569 Mutex::Autolock autoLock(mLock); 570 571 mSeeking = true; 572 mPositionTimeRealUs = mPositionTimeMediaUs = -1; 573 mReachedEOS = false; 574 mSeekTimeUs = time_us; 575 576 // Flush resets the number of played frames 577 mNumFramesPlayed = 0; 578 mNumFramesPlayedSysTimeUs = ALooper::GetNowUs(); 579 580 if (mAudioSink != NULL) { 581 mAudioSink->flush(); 582 } else { 583 mAudioTrack->flush(); 584 } 585 586 return OK; 587} 588 589} 590