diff options
Diffstat (limited to 'media/libmediaplayerservice/MediaPlayerService.cpp')
-rw-r--r-- | media/libmediaplayerservice/MediaPlayerService.cpp | 152 |
1 files changed, 130 insertions, 22 deletions
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index 9bedff1..414c262 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -1,5 +1,9 @@ /* ** +** Copyright (c) 2012, The Linux Foundation. All rights reserved. +** Not a Contribution, Apache license notifications and license are retained +** for attribution purposes only. +** ** Copyright 2008, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); @@ -74,6 +78,7 @@ #include "Crypto.h" #include "HDCP.h" #include "RemoteDisplay.h" +#define DEFAULT_SAMPLE_RATE 44100 namespace { using android::media::Metadata; @@ -1363,6 +1368,22 @@ status_t MediaPlayerService::AudioOutput::getPosition(uint32_t *position) const return mTrack->getPosition(position); } +#ifdef QCOM_HARDWARE +ssize_t MediaPlayerService::AudioOutput::sampleRate() const +{ + if (mTrack == 0) return NO_INIT; + return DEFAULT_SAMPLE_RATE; +} + +status_t MediaPlayerService::AudioOutput::getTimeStamp(uint64_t *tstamp) +{ + if (tstamp == 0) return BAD_VALUE; + if (mTrack == 0) return NO_INIT; + mTrack->getTimeStamp(tstamp); + return NO_ERROR; +} +#endif + status_t MediaPlayerService::AudioOutput::getFramesWritten(uint32_t *frameswritten) const { if (mTrack == 0) return NO_INIT; @@ -1379,6 +1400,65 @@ status_t MediaPlayerService::AudioOutput::open( mCallback = cb; mCallbackCookie = cookie; +#ifdef QCOM_HARDWARE + if (flags & AUDIO_OUTPUT_FLAG_LPA || flags & AUDIO_OUTPUT_FLAG_TUNNEL) { + ALOGV("AudioOutput open: with flags %x",flags); + channelMask = audio_channel_out_mask_from_count(channelCount); + if (0 == channelMask) { + ALOGE("open() error, can't derive mask for %d audio channels", channelCount); + return NO_INIT; + } + AudioTrack *audioTrack = NULL; + CallbackData *newcbd = NULL; + if (mCallback != NULL) { + newcbd = new CallbackData(this); + audioTrack = new AudioTrack( + mStreamType, + sampleRate, + format, + channelMask, + 0, + flags, + CallbackWrapper, + newcbd, + 0, + mSessionId); + if ((audioTrack == 0) || (audioTrack->initCheck() != NO_ERROR)) { + ALOGE("Unable to create audio track"); + delete audioTrack; + delete newcbd; + return NO_INIT; + } + } else { + ALOGE("no callback supplied"); + return NO_INIT; + } + + if (mRecycledTrack) { + //usleep(500000); + // if we're not going to reuse the track, unblock and flush it + if (mCallbackData != NULL) { + mCallbackData->setOutput(NULL); + mCallbackData->endTrackSwitch(); + } + mRecycledTrack->flush(); + delete mRecycledTrack; + mRecycledTrack = NULL; + delete mCallbackData; + mCallbackData = NULL; + close(); + } + + ALOGV("setVolume"); + mCallbackData = newcbd; + audioTrack->setVolume(mLeftVolume, mRightVolume); + mSampleRateHz = sampleRate; + mFlags = flags; + mTrack = audioTrack; + return NO_ERROR; + } +#endif + // Check argument "bufferCount" against the mininum buffer count if (bufferCount < mMinBufferCount) { ALOGD("bufferCount (%d) is too small and increased to %d", bufferCount, mMinBufferCount); @@ -1551,7 +1631,7 @@ void MediaPlayerService::AudioOutput::switchToNextOutput() { ssize_t MediaPlayerService::AudioOutput::write(const void* buffer, size_t size) { - LOG_FATAL_IF(mCallback != NULL, "Don't call write if supplying a callback."); + //LOG_FATAL_IF(mCallback != NULL, "Don't call write if supplying a callback."); //ALOGV("write(%p, %u)", buffer, size); if (mTrack) { @@ -1637,35 +1717,56 @@ status_t MediaPlayerService::AudioOutput::attachAuxEffect(int effectId) void MediaPlayerService::AudioOutput::CallbackWrapper( int event, void *cookie, void *info) { //ALOGV("callbackwrapper"); - if (event != AudioTrack::EVENT_MORE_DATA) { - return; - } - - CallbackData *data = (CallbackData*)cookie; - data->lock(); - AudioOutput *me = data->getOutput(); - AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info; - if (me == NULL) { - // no output set, likely because the track was scheduled to be reused - // by another player, but the format turned out to be incompatible. +#ifdef QCOM_HARDWARE + if (event == AudioTrack::EVENT_UNDERRUN) { + ALOGW("Event underrun"); + CallbackData *data = (CallbackData*)cookie; + data->lock(); + AudioOutput *me = data->getOutput(); + if (me == NULL) { + // no output set, likely because the track was scheduled to be reused + // by another player, but the format turned out to be incompatible. + data->unlock(); + return; + } + ALOGD("Callback!!!"); + (*me->mCallback)( + me, NULL, (size_t)AudioTrack::EVENT_UNDERRUN, me->mCallbackCookie); data->unlock(); - buffer->size = 0; return; } +#endif + if (event == AudioTrack::EVENT_MORE_DATA) { + CallbackData *data = (CallbackData*)cookie; + data->lock(); + AudioOutput *me = data->getOutput(); + AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info; + if (me == NULL) { + // no output set, likely because the track was scheduled to be reused + // by another player, but the format turned out to be incompatible. + data->unlock(); + buffer->size = 0; + return; + } + + size_t actualSize = (*me->mCallback)( + me, buffer->raw, buffer->size, me->mCallbackCookie); - size_t actualSize = (*me->mCallback)( - me, buffer->raw, buffer->size, me->mCallbackCookie); + if (actualSize == 0 && buffer->size > 0 && me->mNextOutput == NULL) { + // We've reached EOS but the audio track is not stopped yet, + // keep playing silence. - if (actualSize == 0 && buffer->size > 0 && me->mNextOutput == NULL) { - // We've reached EOS but the audio track is not stopped yet, - // keep playing silence. + memset(buffer->raw, 0, buffer->size); + actualSize = buffer->size; + } - memset(buffer->raw, 0, buffer->size); - actualSize = buffer->size; + buffer->size = actualSize; + data->unlock(); } - buffer->size = actualSize; - data->unlock(); + return; + + } int MediaPlayerService::AudioOutput::getSessionId() const @@ -1700,6 +1801,13 @@ status_t MediaPlayerService::AudioCache::getPosition(uint32_t *position) const return NO_ERROR; } +#ifdef QCOM_HARDWARE +ssize_t MediaPlayerService::AudioCache::sampleRate() const +{ + return mSampleRate; +} +#endif + status_t MediaPlayerService::AudioCache::getFramesWritten(uint32_t *written) const { if (written == 0) return BAD_VALUE; |