diff options
Diffstat (limited to 'libvideoeditor/lvpp/AudioPlayerBase.cpp')
-rw-r--r-- | libvideoeditor/lvpp/AudioPlayerBase.cpp | 510 |
1 files changed, 0 insertions, 510 deletions
diff --git a/libvideoeditor/lvpp/AudioPlayerBase.cpp b/libvideoeditor/lvpp/AudioPlayerBase.cpp deleted file mode 100644 index 67ea43c..0000000 --- a/libvideoeditor/lvpp/AudioPlayerBase.cpp +++ /dev/null @@ -1,510 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -//#define LOG_NDEBUG 0 -#define LOG_TAG "AudioPlayerBase" -#include <utils/Log.h> - -#include <binder/IPCThreadState.h> -#include <media/AudioTrack.h> -#include <media/stagefright/MediaDebug.h> -#include <media/stagefright/MediaDefs.h> -#include <media/stagefright/MediaErrors.h> -#include <media/stagefright/MediaSource.h> -#include <media/stagefright/MetaData.h> - -#include "AudioPlayerBase.h" -#include "PreviewPlayer.h" - -namespace android { - -AudioPlayerBase::AudioPlayerBase( - const sp<MediaPlayerBase::AudioSink> &audioSink, - PreviewPlayer *observer) - : mAudioTrack(NULL), - mInputBuffer(NULL), - mSampleRate(0), - mLatencyUs(0), - mFrameSize(0), - mNumFramesPlayed(0), - mPositionTimeMediaUs(-1), - mPositionTimeRealUs(-1), - mSeeking(false), - mReachedEOS(false), - mFinalStatus(OK), - mStarted(false), - mIsFirstBuffer(false), - mFirstBufferResult(OK), - mFirstBuffer(NULL), - mAudioSink(audioSink), - mObserver(observer) { -} - -AudioPlayerBase::~AudioPlayerBase() { - if (mStarted) { - reset(); - } -} - -void AudioPlayerBase::setSource(const sp<MediaSource> &source) { - CHECK_EQ(mSource, NULL); - mSource = source; -} - -status_t AudioPlayerBase::start(bool sourceAlreadyStarted) { - CHECK(!mStarted); - CHECK(mSource != NULL); - - status_t err; - if (!sourceAlreadyStarted) { - err = mSource->start(); - - if (err != OK) { - return err; - } - } - - // We allow an optional INFO_FORMAT_CHANGED at the very beginning - // of playback, if there is one, getFormat below will retrieve the - // updated format, if there isn't, we'll stash away the valid buffer - // of data to be used on the first audio callback. - - CHECK(mFirstBuffer == NULL); - - mFirstBufferResult = mSource->read(&mFirstBuffer); - if (mFirstBufferResult == INFO_FORMAT_CHANGED) { - ALOGV("INFO_FORMAT_CHANGED!!!"); - - CHECK(mFirstBuffer == NULL); - mFirstBufferResult = OK; - mIsFirstBuffer = false; - } else { - mIsFirstBuffer = true; - } - - sp<MetaData> format = mSource->getFormat(); - const char *mime; - bool success = format->findCString(kKeyMIMEType, &mime); - CHECK(success); - CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)); - - success = format->findInt32(kKeySampleRate, &mSampleRate); - CHECK(success); - - int32_t numChannels; - success = format->findInt32(kKeyChannelCount, &numChannels); - CHECK(success); - - if (mAudioSink.get() != NULL) { - status_t err = mAudioSink->open( - mSampleRate, numChannels, AUDIO_FORMAT_PCM_16_BIT, - DEFAULT_AUDIOSINK_BUFFERCOUNT, - &AudioPlayerBase::AudioSinkCallback, this); - if (err != OK) { - if (mFirstBuffer != NULL) { - mFirstBuffer->release(); - mFirstBuffer = NULL; - } - - if (!sourceAlreadyStarted) { - mSource->stop(); - } - - return err; - } - - mLatencyUs = (int64_t)mAudioSink->latency() * 1000; - mFrameSize = mAudioSink->frameSize(); - - mAudioSink->start(); - } else { - mAudioTrack = new AudioTrack( - AUDIO_STREAM_MUSIC, mSampleRate, AUDIO_FORMAT_PCM_16_BIT, - (numChannels == 2) - ? AUDIO_CHANNEL_OUT_STEREO - : AUDIO_CHANNEL_OUT_MONO, - 0, 0, &AudioCallback, this, 0); - - if ((err = mAudioTrack->initCheck()) != OK) { - delete mAudioTrack; - mAudioTrack = NULL; - - if (mFirstBuffer != NULL) { - mFirstBuffer->release(); - mFirstBuffer = NULL; - } - - if (!sourceAlreadyStarted) { - mSource->stop(); - } - - return err; - } - - mLatencyUs = (int64_t)mAudioTrack->latency() * 1000; - mFrameSize = mAudioTrack->frameSize(); - - mAudioTrack->start(); - } - - mStarted = true; - - return OK; -} - -void AudioPlayerBase::pause(bool playPendingSamples) { - CHECK(mStarted); - - if (playPendingSamples) { - if (mAudioSink.get() != NULL) { - mAudioSink->stop(); - } else { - mAudioTrack->stop(); - } - } else { - if (mAudioSink.get() != NULL) { - mAudioSink->pause(); - } else { - mAudioTrack->pause(); - } - } -} - -void AudioPlayerBase::resume() { - CHECK(mStarted); - - if (mAudioSink.get() != NULL) { - mAudioSink->start(); - } else { - mAudioTrack->start(); - } -} - -void AudioPlayerBase::reset() { - CHECK(mStarted); - - if (mAudioSink.get() != NULL) { - mAudioSink->stop(); - mAudioSink->close(); - } else { - mAudioTrack->stop(); - - delete mAudioTrack; - mAudioTrack = NULL; - } - - // Make sure to release any buffer we hold onto so that the - // source is able to stop(). - - if (mFirstBuffer != NULL) { - mFirstBuffer->release(); - mFirstBuffer = NULL; - } - - if (mInputBuffer != NULL) { - ALOGV("AudioPlayerBase releasing input buffer."); - - mInputBuffer->release(); - mInputBuffer = NULL; - } - - mSource->stop(); - - // The following hack is necessary to ensure that the OMX - // component is completely released by the time we may try - // to instantiate it again. - wp<MediaSource> tmp = mSource; - mSource.clear(); - while (tmp.promote() != NULL) { - usleep(1000); - } - IPCThreadState::self()->flushCommands(); - - mNumFramesPlayed = 0; - mPositionTimeMediaUs = -1; - mPositionTimeRealUs = -1; - mSeeking = false; - mReachedEOS = false; - mFinalStatus = OK; - mStarted = false; -} - -// static -void AudioPlayerBase::AudioCallback(int event, void *user, void *info) { - static_cast<AudioPlayerBase *>(user)->AudioCallback(event, info); -} - -bool AudioPlayerBase::isSeeking() { - Mutex::Autolock autoLock(mLock); - return mSeeking; -} - -bool AudioPlayerBase::reachedEOS(status_t *finalStatus) { - *finalStatus = OK; - - Mutex::Autolock autoLock(mLock); - *finalStatus = mFinalStatus; - return mReachedEOS; -} - -// static -size_t AudioPlayerBase::AudioSinkCallback( - MediaPlayerBase::AudioSink *audioSink, - void *buffer, size_t size, void *cookie) { - AudioPlayerBase *me = (AudioPlayerBase *)cookie; - - return me->fillBuffer(buffer, size); -} - -void AudioPlayerBase::AudioCallback(int event, void *info) { - if (event != AudioTrack::EVENT_MORE_DATA) { - return; - } - - AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info; - size_t numBytesWritten = fillBuffer(buffer->raw, buffer->size); - - buffer->size = numBytesWritten; -} - -uint32_t AudioPlayerBase::getNumFramesPendingPlayout() const { - uint32_t numFramesPlayedOut; - status_t err; - - if (mAudioSink != NULL) { - err = mAudioSink->getPosition(&numFramesPlayedOut); - } else { - err = mAudioTrack->getPosition(&numFramesPlayedOut); - } - - if (err != OK || mNumFramesPlayed < numFramesPlayedOut) { - return 0; - } - - // mNumFramesPlayed is the number of frames submitted - // to the audio sink for playback, but not all of them - // may have played out by now. - return mNumFramesPlayed - numFramesPlayedOut; -} - -size_t AudioPlayerBase::fillBuffer(void *data, size_t size) { - if (mNumFramesPlayed == 0) { - ALOGV("AudioCallback"); - } - - if (mReachedEOS) { - return 0; - } - - bool postSeekComplete = false; - bool postEOS = false; - int64_t postEOSDelayUs = 0; - - size_t size_done = 0; - size_t size_remaining = size; - while (size_remaining > 0) { - MediaSource::ReadOptions options; - - { - Mutex::Autolock autoLock(mLock); - - if (mSeeking) { - if (mIsFirstBuffer) { - if (mFirstBuffer != NULL) { - mFirstBuffer->release(); - mFirstBuffer = NULL; - } - mIsFirstBuffer = false; - } - - options.setSeekTo(mSeekTimeUs); - - if (mInputBuffer != NULL) { - mInputBuffer->release(); - mInputBuffer = NULL; - } - - mSeeking = false; - if (mObserver) { - postSeekComplete = true; - } - } - } - - if (mInputBuffer == NULL) { - status_t err; - - if (mIsFirstBuffer) { - mInputBuffer = mFirstBuffer; - mFirstBuffer = NULL; - err = mFirstBufferResult; - - mIsFirstBuffer = false; - } else { - err = mSource->read(&mInputBuffer, &options); - } - - CHECK((err == OK && mInputBuffer != NULL) - || (err != OK && mInputBuffer == NULL)); - - Mutex::Autolock autoLock(mLock); - - if (err != OK) { - if (mObserver && !mReachedEOS) { - // We don't want to post EOS right away but only - // after all frames have actually been played out. - - // These are the number of frames submitted to the - // AudioTrack that you haven't heard yet. - uint32_t numFramesPendingPlayout = - getNumFramesPendingPlayout(); - - // These are the number of frames we're going to - // submit to the AudioTrack by returning from this - // callback. - uint32_t numAdditionalFrames = size_done / mFrameSize; - - numFramesPendingPlayout += numAdditionalFrames; - - int64_t timeToCompletionUs = - (1000000ll * numFramesPendingPlayout) / mSampleRate; - - ALOGV("total number of frames played: %lld (%lld us)", - (mNumFramesPlayed + numAdditionalFrames), - 1000000ll * (mNumFramesPlayed + numAdditionalFrames) - / mSampleRate); - - ALOGV("%d frames left to play, %lld us (%.2f secs)", - numFramesPendingPlayout, - timeToCompletionUs, timeToCompletionUs / 1E6); - - postEOS = true; - postEOSDelayUs = timeToCompletionUs + mLatencyUs; - } - - mReachedEOS = true; - mFinalStatus = err; - break; - } - - CHECK(mInputBuffer->meta_data()->findInt64( - kKeyTime, &mPositionTimeMediaUs)); - - mPositionTimeRealUs = - ((mNumFramesPlayed + size_done / mFrameSize) * 1000000) - / mSampleRate; - - ALOGV("buffer->size() = %d, " - "mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f", - mInputBuffer->range_length(), - mPositionTimeMediaUs / 1E6, mPositionTimeRealUs / 1E6); - } - - if (mInputBuffer->range_length() == 0) { - mInputBuffer->release(); - mInputBuffer = NULL; - - continue; - } - - size_t copy = size_remaining; - if (copy > mInputBuffer->range_length()) { - copy = mInputBuffer->range_length(); - } - - memcpy((char *)data + size_done, - (const char *)mInputBuffer->data() + mInputBuffer->range_offset(), - copy); - - mInputBuffer->set_range(mInputBuffer->range_offset() + copy, - mInputBuffer->range_length() - copy); - - size_done += copy; - size_remaining -= copy; - } - - { - Mutex::Autolock autoLock(mLock); - mNumFramesPlayed += size_done / mFrameSize; - } - - if (postEOS) { - mObserver->postAudioEOS(postEOSDelayUs); - } - - if (postSeekComplete) { - mObserver->postAudioSeekComplete(); - } - - return size_done; -} - -int64_t AudioPlayerBase::getRealTimeUs() { - Mutex::Autolock autoLock(mLock); - return getRealTimeUsLocked(); -} - -int64_t AudioPlayerBase::getRealTimeUsLocked() const { - return -mLatencyUs + (mNumFramesPlayed * 1000000) / mSampleRate; -} - -int64_t AudioPlayerBase::getMediaTimeUs() { - Mutex::Autolock autoLock(mLock); - - if (mPositionTimeMediaUs < 0 || mPositionTimeRealUs < 0) { - if (mSeeking) { - return mSeekTimeUs; - } - - return 0; - } - - int64_t realTimeOffset = getRealTimeUsLocked() - mPositionTimeRealUs; - if (realTimeOffset < 0) { - realTimeOffset = 0; - } - - return mPositionTimeMediaUs + realTimeOffset; -} - -bool AudioPlayerBase::getMediaTimeMapping( - int64_t *realtime_us, int64_t *mediatime_us) { - Mutex::Autolock autoLock(mLock); - - *realtime_us = mPositionTimeRealUs; - *mediatime_us = mPositionTimeMediaUs; - - return mPositionTimeRealUs != -1 && mPositionTimeMediaUs != -1; -} - -status_t AudioPlayerBase::seekTo(int64_t time_us) { - Mutex::Autolock autoLock(mLock); - - mSeeking = true; - mPositionTimeRealUs = mPositionTimeMediaUs = -1; - mReachedEOS = false; - mSeekTimeUs = time_us; - - if (mAudioSink != NULL) { - mAudioSink->flush(); - } else { - mAudioTrack->flush(); - } - - return OK; -} - -} |