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