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