AudioPlayer.cpp revision e4451a91a61a341014f5eff61db356156c3ecb37
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 bool allowDeepBuffering, 38 AwesomePlayer *observer) 39 : mAudioTrack(NULL), 40 mInputBuffer(NULL), 41 mSampleRate(0), 42 mLatencyUs(0), 43 mFrameSize(0), 44 mNumFramesPlayed(0), 45 mNumFramesPlayedSysTimeUs(ALooper::GetNowUs()), 46 mPositionTimeMediaUs(-1), 47 mPositionTimeRealUs(-1), 48 mSeeking(false), 49 mReachedEOS(false), 50 mFinalStatus(OK), 51 mStarted(false), 52 mIsFirstBuffer(false), 53 mFirstBufferResult(OK), 54 mFirstBuffer(NULL), 55 mAudioSink(audioSink), 56 mAllowDeepBuffering(allowDeepBuffering), 57 mObserver(observer) { 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 delete mAudioTrack; 169 mAudioTrack = NULL; 170 171 if (mFirstBuffer != NULL) { 172 mFirstBuffer->release(); 173 mFirstBuffer = NULL; 174 } 175 176 if (!sourceAlreadyStarted) { 177 mSource->stop(); 178 } 179 180 return err; 181 } 182 183 mLatencyUs = (int64_t)mAudioTrack->latency() * 1000; 184 mFrameSize = mAudioTrack->frameSize(); 185 186 mAudioTrack->start(); 187 } 188 189 mStarted = true; 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} 214 215void AudioPlayer::resume() { 216 CHECK(mStarted); 217 218 if (mAudioSink.get() != NULL) { 219 mAudioSink->start(); 220 } else { 221 mAudioTrack->start(); 222 } 223} 224 225void AudioPlayer::reset() { 226 CHECK(mStarted); 227 228 if (mAudioSink.get() != NULL) { 229 mAudioSink->stop(); 230 mAudioSink->close(); 231 } else { 232 mAudioTrack->stop(); 233 234 delete mAudioTrack; 235 mAudioTrack = NULL; 236 } 237 238 // Make sure to release any buffer we hold onto so that the 239 // source is able to stop(). 240 241 if (mFirstBuffer != NULL) { 242 mFirstBuffer->release(); 243 mFirstBuffer = NULL; 244 } 245 246 if (mInputBuffer != NULL) { 247 ALOGV("AudioPlayer releasing input buffer."); 248 249 mInputBuffer->release(); 250 mInputBuffer = NULL; 251 } 252 253 mSource->stop(); 254 255 // The following hack is necessary to ensure that the OMX 256 // component is completely released by the time we may try 257 // to instantiate it again. 258 wp<MediaSource> tmp = mSource; 259 mSource.clear(); 260 while (tmp.promote() != NULL) { 261 usleep(1000); 262 } 263 IPCThreadState::self()->flushCommands(); 264 265 mNumFramesPlayed = 0; 266 mNumFramesPlayedSysTimeUs = ALooper::GetNowUs(); 267 mPositionTimeMediaUs = -1; 268 mPositionTimeRealUs = -1; 269 mSeeking = false; 270 mReachedEOS = false; 271 mFinalStatus = OK; 272 mStarted = false; 273} 274 275// static 276void AudioPlayer::AudioCallback(int event, void *user, void *info) { 277 static_cast<AudioPlayer *>(user)->AudioCallback(event, info); 278} 279 280bool AudioPlayer::isSeeking() { 281 Mutex::Autolock autoLock(mLock); 282 return mSeeking; 283} 284 285bool AudioPlayer::reachedEOS(status_t *finalStatus) { 286 *finalStatus = OK; 287 288 Mutex::Autolock autoLock(mLock); 289 *finalStatus = mFinalStatus; 290 return mReachedEOS; 291} 292 293status_t AudioPlayer::setPlaybackRatePermille(int32_t ratePermille) { 294 if (mAudioSink.get() != NULL) { 295 return mAudioSink->setPlaybackRatePermille(ratePermille); 296 } else if (mAudioTrack != NULL){ 297 return mAudioTrack->setSampleRate(ratePermille * mSampleRate / 1000); 298 } else { 299 return NO_INIT; 300 } 301} 302 303// static 304size_t AudioPlayer::AudioSinkCallback( 305 MediaPlayerBase::AudioSink *audioSink, 306 void *buffer, size_t size, void *cookie) { 307 AudioPlayer *me = (AudioPlayer *)cookie; 308 309 return me->fillBuffer(buffer, size); 310} 311 312void AudioPlayer::AudioCallback(int event, void *info) { 313 if (event != AudioTrack::EVENT_MORE_DATA) { 314 return; 315 } 316 317 AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info; 318 size_t numBytesWritten = fillBuffer(buffer->raw, buffer->size); 319 320 buffer->size = numBytesWritten; 321} 322 323uint32_t AudioPlayer::getNumFramesPendingPlayout() const { 324 uint32_t numFramesPlayedOut; 325 status_t err; 326 327 if (mAudioSink != NULL) { 328 err = mAudioSink->getPosition(&numFramesPlayedOut); 329 } else { 330 err = mAudioTrack->getPosition(&numFramesPlayedOut); 331 } 332 333 if (err != OK || mNumFramesPlayed < numFramesPlayedOut) { 334 return 0; 335 } 336 337 // mNumFramesPlayed is the number of frames submitted 338 // to the audio sink for playback, but not all of them 339 // may have played out by now. 340 return mNumFramesPlayed - numFramesPlayedOut; 341} 342 343size_t AudioPlayer::fillBuffer(void *data, size_t size) { 344 if (mNumFramesPlayed == 0) { 345 ALOGV("AudioCallback"); 346 } 347 348 if (mReachedEOS) { 349 return 0; 350 } 351 352 bool postSeekComplete = false; 353 bool postEOS = false; 354 int64_t postEOSDelayUs = 0; 355 356 size_t size_done = 0; 357 size_t size_remaining = size; 358 while (size_remaining > 0) { 359 MediaSource::ReadOptions options; 360 361 { 362 Mutex::Autolock autoLock(mLock); 363 364 if (mSeeking) { 365 if (mIsFirstBuffer) { 366 if (mFirstBuffer != NULL) { 367 mFirstBuffer->release(); 368 mFirstBuffer = NULL; 369 } 370 mIsFirstBuffer = false; 371 } 372 373 options.setSeekTo(mSeekTimeUs); 374 375 if (mInputBuffer != NULL) { 376 mInputBuffer->release(); 377 mInputBuffer = NULL; 378 } 379 380 mSeeking = false; 381 if (mObserver) { 382 postSeekComplete = true; 383 } 384 } 385 } 386 387 if (mInputBuffer == NULL) { 388 status_t err; 389 390 if (mIsFirstBuffer) { 391 mInputBuffer = mFirstBuffer; 392 mFirstBuffer = NULL; 393 err = mFirstBufferResult; 394 395 mIsFirstBuffer = false; 396 } else { 397 err = mSource->read(&mInputBuffer, &options); 398 } 399 400 CHECK((err == OK && mInputBuffer != NULL) 401 || (err != OK && mInputBuffer == NULL)); 402 403 Mutex::Autolock autoLock(mLock); 404 405 if (err != OK) { 406 if (mObserver && !mReachedEOS) { 407 // We don't want to post EOS right away but only 408 // after all frames have actually been played out. 409 410 // These are the number of frames submitted to the 411 // AudioTrack that you haven't heard yet. 412 uint32_t numFramesPendingPlayout = 413 getNumFramesPendingPlayout(); 414 415 // These are the number of frames we're going to 416 // submit to the AudioTrack by returning from this 417 // callback. 418 uint32_t numAdditionalFrames = size_done / mFrameSize; 419 420 numFramesPendingPlayout += numAdditionalFrames; 421 422 int64_t timeToCompletionUs = 423 (1000000ll * numFramesPendingPlayout) / mSampleRate; 424 425 ALOGV("total number of frames played: %lld (%lld us)", 426 (mNumFramesPlayed + numAdditionalFrames), 427 1000000ll * (mNumFramesPlayed + numAdditionalFrames) 428 / mSampleRate); 429 430 ALOGV("%d frames left to play, %lld us (%.2f secs)", 431 numFramesPendingPlayout, 432 timeToCompletionUs, timeToCompletionUs / 1E6); 433 434 postEOS = true; 435 if (mAudioSink->needsTrailingPadding()) { 436 postEOSDelayUs = timeToCompletionUs + mLatencyUs; 437 } else { 438 postEOSDelayUs = 0; 439 } 440 } 441 442 mReachedEOS = true; 443 mFinalStatus = err; 444 break; 445 } 446 447 if (mAudioSink != NULL) { 448 mLatencyUs = (int64_t)mAudioSink->latency() * 1000; 449 } else { 450 mLatencyUs = (int64_t)mAudioTrack->latency() * 1000; 451 } 452 453 CHECK(mInputBuffer->meta_data()->findInt64( 454 kKeyTime, &mPositionTimeMediaUs)); 455 456 mPositionTimeRealUs = 457 ((mNumFramesPlayed + size_done / mFrameSize) * 1000000) 458 / mSampleRate; 459 460 ALOGV("buffer->size() = %d, " 461 "mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f", 462 mInputBuffer->range_length(), 463 mPositionTimeMediaUs / 1E6, mPositionTimeRealUs / 1E6); 464 } 465 466 if (mInputBuffer->range_length() == 0) { 467 mInputBuffer->release(); 468 mInputBuffer = NULL; 469 470 continue; 471 } 472 473 size_t copy = size_remaining; 474 if (copy > mInputBuffer->range_length()) { 475 copy = mInputBuffer->range_length(); 476 } 477 478 memcpy((char *)data + size_done, 479 (const char *)mInputBuffer->data() + mInputBuffer->range_offset(), 480 copy); 481 482 mInputBuffer->set_range(mInputBuffer->range_offset() + copy, 483 mInputBuffer->range_length() - copy); 484 485 size_done += copy; 486 size_remaining -= copy; 487 } 488 489 { 490 Mutex::Autolock autoLock(mLock); 491 mNumFramesPlayed += size_done / mFrameSize; 492 mNumFramesPlayedSysTimeUs = ALooper::GetNowUs(); 493 } 494 495 if (postEOS) { 496 mObserver->postAudioEOS(postEOSDelayUs); 497 } 498 499 if (postSeekComplete) { 500 mObserver->postAudioSeekComplete(); 501 } 502 503 return size_done; 504} 505 506int64_t AudioPlayer::getRealTimeUs() { 507 Mutex::Autolock autoLock(mLock); 508 return getRealTimeUsLocked(); 509} 510 511int64_t AudioPlayer::getRealTimeUsLocked() const { 512 CHECK(mStarted); 513 CHECK_NE(mSampleRate, 0); 514 int64_t result = -mLatencyUs + (mNumFramesPlayed * 1000000) / mSampleRate; 515 516 // Compensate for large audio buffers, updates of mNumFramesPlayed 517 // are less frequent, therefore to get a "smoother" notion of time we 518 // compensate using system time. 519 int64_t diffUs = ALooper::GetNowUs() - mNumFramesPlayedSysTimeUs; 520 521 return result + diffUs; 522} 523 524int64_t AudioPlayer::getMediaTimeUs() { 525 Mutex::Autolock autoLock(mLock); 526 527 if (mPositionTimeMediaUs < 0 || mPositionTimeRealUs < 0) { 528 if (mSeeking) { 529 return mSeekTimeUs; 530 } 531 532 return 0; 533 } 534 535 int64_t realTimeOffset = getRealTimeUsLocked() - mPositionTimeRealUs; 536 if (realTimeOffset < 0) { 537 realTimeOffset = 0; 538 } 539 540 return mPositionTimeMediaUs + realTimeOffset; 541} 542 543bool AudioPlayer::getMediaTimeMapping( 544 int64_t *realtime_us, int64_t *mediatime_us) { 545 Mutex::Autolock autoLock(mLock); 546 547 *realtime_us = mPositionTimeRealUs; 548 *mediatime_us = mPositionTimeMediaUs; 549 550 return mPositionTimeRealUs != -1 && mPositionTimeMediaUs != -1; 551} 552 553status_t AudioPlayer::seekTo(int64_t time_us) { 554 Mutex::Autolock autoLock(mLock); 555 556 mSeeking = true; 557 mPositionTimeRealUs = mPositionTimeMediaUs = -1; 558 mReachedEOS = false; 559 mSeekTimeUs = time_us; 560 561 // Flush resets the number of played frames 562 mNumFramesPlayed = 0; 563 mNumFramesPlayedSysTimeUs = ALooper::GetNowUs(); 564 565 if (mAudioSink != NULL) { 566 mAudioSink->flush(); 567 } else { 568 mAudioTrack->flush(); 569 } 570 571 return OK; 572} 573 574} 575