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/MediaSource.h> 27 #include <media/stagefright/MetaData.h> 28 29 namespace android { 30 31 AudioPlayer::AudioPlayer(const sp<MediaPlayerBase::AudioSink> &audioSink) 32 : mAudioTrack(NULL), 33 mInputBuffer(NULL), 34 mSampleRate(0), 35 mLatencyUs(0), 36 mFrameSize(0), 37 mNumFramesPlayed(0), 38 mPositionTimeMediaUs(-1), 39 mPositionTimeRealUs(-1), 40 mSeeking(false), 41 mReachedEOS(false), 42 mFinalStatus(OK), 43 mStarted(false), 44 mAudioSink(audioSink) { 45 } 46 47 AudioPlayer::~AudioPlayer() { 48 if (mStarted) { 49 stop(); 50 } 51 } 52 53 void AudioPlayer::setSource(const sp<MediaSource> &source) { 54 CHECK_EQ(mSource, NULL); 55 mSource = source; 56 } 57 58 status_t AudioPlayer::start(bool sourceAlreadyStarted) { 59 CHECK(!mStarted); 60 CHECK(mSource != NULL); 61 62 status_t err; 63 if (!sourceAlreadyStarted) { 64 err = mSource->start(); 65 66 if (err != OK) { 67 return err; 68 } 69 } 70 71 sp<MetaData> format = mSource->getFormat(); 72 const char *mime; 73 bool success = format->findCString(kKeyMIMEType, &mime); 74 CHECK(success); 75 CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)); 76 77 success = format->findInt32(kKeySampleRate, &mSampleRate); 78 CHECK(success); 79 80 int32_t numChannels; 81 success = format->findInt32(kKeyChannelCount, &numChannels); 82 CHECK(success); 83 84 if (mAudioSink.get() != NULL) { 85 status_t err = mAudioSink->open( 86 mSampleRate, numChannels, AudioSystem::PCM_16_BIT, 87 DEFAULT_AUDIOSINK_BUFFERCOUNT, 88 &AudioPlayer::AudioSinkCallback, this); 89 if (err != OK) { 90 mSource->stop(); 91 92 return err; 93 } 94 95 mLatencyUs = (int64_t)mAudioSink->latency() * 1000; 96 mFrameSize = mAudioSink->frameSize(); 97 98 mAudioSink->start(); 99 } else { 100 mAudioTrack = new AudioTrack( 101 AudioSystem::MUSIC, mSampleRate, AudioSystem::PCM_16_BIT, 102 (numChannels == 2) 103 ? AudioSystem::CHANNEL_OUT_STEREO 104 : AudioSystem::CHANNEL_OUT_MONO, 105 0, 0, &AudioCallback, this, 0); 106 107 if ((err = mAudioTrack->initCheck()) != OK) { 108 delete mAudioTrack; 109 mAudioTrack = NULL; 110 111 mSource->stop(); 112 113 return err; 114 } 115 116 mLatencyUs = (int64_t)mAudioTrack->latency() * 1000; 117 mFrameSize = mAudioTrack->frameSize(); 118 119 mAudioTrack->start(); 120 } 121 122 mStarted = true; 123 124 return OK; 125 } 126 127 void AudioPlayer::pause() { 128 CHECK(mStarted); 129 130 if (mAudioSink.get() != NULL) { 131 mAudioSink->pause(); 132 } else { 133 mAudioTrack->stop(); 134 } 135 } 136 137 void AudioPlayer::resume() { 138 CHECK(mStarted); 139 140 if (mAudioSink.get() != NULL) { 141 mAudioSink->start(); 142 } else { 143 mAudioTrack->start(); 144 } 145 } 146 147 void AudioPlayer::stop() { 148 CHECK(mStarted); 149 150 if (mAudioSink.get() != NULL) { 151 mAudioSink->stop(); 152 mAudioSink->close(); 153 } else { 154 mAudioTrack->stop(); 155 156 delete mAudioTrack; 157 mAudioTrack = NULL; 158 } 159 160 // Make sure to release any buffer we hold onto so that the 161 // source is able to stop(). 162 if (mInputBuffer != NULL) { 163 LOGV("AudioPlayer releasing input buffer."); 164 165 mInputBuffer->release(); 166 mInputBuffer = NULL; 167 } 168 169 mSource->stop(); 170 171 // The following hack is necessary to ensure that the OMX 172 // component is completely released by the time we may try 173 // to instantiate it again. 174 wp<MediaSource> tmp = mSource; 175 mSource.clear(); 176 while (tmp.promote() != NULL) { 177 usleep(1000); 178 } 179 IPCThreadState::self()->flushCommands(); 180 181 mNumFramesPlayed = 0; 182 mPositionTimeMediaUs = -1; 183 mPositionTimeRealUs = -1; 184 mSeeking = false; 185 mReachedEOS = false; 186 mFinalStatus = OK; 187 mStarted = false; 188 } 189 190 // static 191 void AudioPlayer::AudioCallback(int event, void *user, void *info) { 192 static_cast<AudioPlayer *>(user)->AudioCallback(event, info); 193 } 194 195 bool AudioPlayer::isSeeking() { 196 Mutex::Autolock autoLock(mLock); 197 return mSeeking; 198 } 199 200 bool AudioPlayer::reachedEOS(status_t *finalStatus) { 201 *finalStatus = OK; 202 203 Mutex::Autolock autoLock(mLock); 204 *finalStatus = mFinalStatus; 205 return mReachedEOS; 206 } 207 208 // static 209 size_t AudioPlayer::AudioSinkCallback( 210 MediaPlayerBase::AudioSink *audioSink, 211 void *buffer, size_t size, void *cookie) { 212 AudioPlayer *me = (AudioPlayer *)cookie; 213 214 return me->fillBuffer(buffer, size); 215 } 216 217 void AudioPlayer::AudioCallback(int event, void *info) { 218 if (event != AudioTrack::EVENT_MORE_DATA) { 219 return; 220 } 221 222 AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info; 223 size_t numBytesWritten = fillBuffer(buffer->raw, buffer->size); 224 225 buffer->size = numBytesWritten; 226 } 227 228 size_t AudioPlayer::fillBuffer(void *data, size_t size) { 229 if (mNumFramesPlayed == 0) { 230 LOGV("AudioCallback"); 231 } 232 233 if (mReachedEOS) { 234 return 0; 235 } 236 237 size_t size_done = 0; 238 size_t size_remaining = size; 239 while (size_remaining > 0) { 240 MediaSource::ReadOptions options; 241 242 { 243 Mutex::Autolock autoLock(mLock); 244 245 if (mSeeking) { 246 options.setSeekTo(mSeekTimeUs); 247 248 if (mInputBuffer != NULL) { 249 mInputBuffer->release(); 250 mInputBuffer = NULL; 251 } 252 253 mSeeking = false; 254 } 255 } 256 257 if (mInputBuffer == NULL) { 258 status_t err = mSource->read(&mInputBuffer, &options); 259 260 CHECK((err == OK && mInputBuffer != NULL) 261 || (err != OK && mInputBuffer == NULL)); 262 263 Mutex::Autolock autoLock(mLock); 264 265 if (err != OK) { 266 mReachedEOS = true; 267 mFinalStatus = err; 268 break; 269 } 270 271 CHECK(mInputBuffer->meta_data()->findInt64( 272 kKeyTime, &mPositionTimeMediaUs)); 273 274 mPositionTimeRealUs = 275 ((mNumFramesPlayed + size_done / mFrameSize) * 1000000) 276 / mSampleRate; 277 278 LOGV("buffer->size() = %d, " 279 "mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f", 280 mInputBuffer->range_length(), 281 mPositionTimeMediaUs / 1E6, mPositionTimeRealUs / 1E6); 282 } 283 284 if (mInputBuffer->range_length() == 0) { 285 mInputBuffer->release(); 286 mInputBuffer = NULL; 287 288 continue; 289 } 290 291 size_t copy = size_remaining; 292 if (copy > mInputBuffer->range_length()) { 293 copy = mInputBuffer->range_length(); 294 } 295 296 memcpy((char *)data + size_done, 297 (const char *)mInputBuffer->data() + mInputBuffer->range_offset(), 298 copy); 299 300 mInputBuffer->set_range(mInputBuffer->range_offset() + copy, 301 mInputBuffer->range_length() - copy); 302 303 size_done += copy; 304 size_remaining -= copy; 305 } 306 307 Mutex::Autolock autoLock(mLock); 308 mNumFramesPlayed += size_done / mFrameSize; 309 310 return size_done; 311 } 312 313 int64_t AudioPlayer::getRealTimeUs() { 314 Mutex::Autolock autoLock(mLock); 315 return getRealTimeUsLocked(); 316 } 317 318 int64_t AudioPlayer::getRealTimeUsLocked() const { 319 return -mLatencyUs + (mNumFramesPlayed * 1000000) / mSampleRate; 320 } 321 322 int64_t AudioPlayer::getMediaTimeUs() { 323 Mutex::Autolock autoLock(mLock); 324 325 if (mPositionTimeMediaUs < 0 || mPositionTimeRealUs < 0) { 326 return 0; 327 } 328 329 int64_t realTimeOffset = getRealTimeUsLocked() - mPositionTimeRealUs; 330 if (realTimeOffset < 0) { 331 realTimeOffset = 0; 332 } 333 334 return mPositionTimeMediaUs + realTimeOffset; 335 } 336 337 bool AudioPlayer::getMediaTimeMapping( 338 int64_t *realtime_us, int64_t *mediatime_us) { 339 Mutex::Autolock autoLock(mLock); 340 341 *realtime_us = mPositionTimeRealUs; 342 *mediatime_us = mPositionTimeMediaUs; 343 344 return mPositionTimeRealUs != -1 && mPositionTimeMediaUs != -1; 345 } 346 347 status_t AudioPlayer::seekTo(int64_t time_us) { 348 Mutex::Autolock autoLock(mLock); 349 350 mSeeking = true; 351 mReachedEOS = false; 352 mSeekTimeUs = time_us; 353 354 return OK; 355 } 356 357 } 358