diff options
Diffstat (limited to 'media')
-rw-r--r-- | media/libmedia/AudioTrack.cpp | 4 | ||||
-rw-r--r-- | media/libmediaplayerservice/MediaPlayerService.cpp | 19 | ||||
-rw-r--r-- | media/libmediaplayerservice/MediaPlayerService.h | 7 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayer.cpp | 20 | ||||
-rw-r--r-- | media/libstagefright/AudioPlayer.cpp | 9 | ||||
-rw-r--r-- | media/libstagefright/AwesomePlayer.cpp | 13 |
6 files changed, 61 insertions, 11 deletions
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index 092b516..25d79d6 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -225,6 +225,10 @@ status_t AudioTrack::set( flags = (audio_output_flags_t) ((flags | AUDIO_OUTPUT_FLAG_DIRECT) & ~AUDIO_OUTPUT_FLAG_FAST); } + // only allow deep buffering for music stream type + if (streamType != AUDIO_STREAM_MUSIC) { + flags = (audio_output_flags_t)(flags &~AUDIO_OUTPUT_FLAG_DEEP_BUFFER); + } if (!audio_is_output_channel(channelMask)) { ALOGE("Invalid channel mask"); diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index 7254599..bfdf250 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -1412,7 +1412,8 @@ MediaPlayerService::AudioOutput::AudioOutput(int sessionId) mCallbackCookie(NULL), mCallbackData(NULL), mBytesWritten(0), - mSessionId(sessionId) { + mSessionId(sessionId), + mFlags(AUDIO_OUTPUT_FLAG_NONE) { ALOGV("AudioOutput(%d)", sessionId); mTrack = 0; mRecycledTrack = 0; @@ -1506,7 +1507,8 @@ status_t MediaPlayerService::AudioOutput::getFramesWritten(uint32_t *frameswritt status_t MediaPlayerService::AudioOutput::open( uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask, audio_format_t format, int bufferCount, - AudioCallback cb, void *cookie) + AudioCallback cb, void *cookie, + audio_output_flags_t flags) { mCallback = cb; mCallbackCookie = cookie; @@ -1521,7 +1523,7 @@ status_t MediaPlayerService::AudioOutput::open( format, bufferCount, mSessionId); int afSampleRate; int afFrameCount; - int frameCount; + uint32_t frameCount; if (AudioSystem::getOutputFrameCount(&afFrameCount, mStreamType) != NO_ERROR) { return NO_INIT; @@ -1539,6 +1541,7 @@ status_t MediaPlayerService::AudioOutput::open( return NO_INIT; } } + if (mRecycledTrack) { // check if the existing track can be reused as-is, or if a new track needs to be created. @@ -1553,6 +1556,9 @@ status_t MediaPlayerService::AudioOutput::open( (mRecycledTrack->frameCount() != frameCount)) { ALOGV("samplerate, channelcount or framecount differ"); reuse = false; + } if (flags != mFlags) { + ALOGV("output flags differ"); + reuse = false; } if (reuse) { ALOGV("chaining to next output"); @@ -1587,7 +1593,7 @@ status_t MediaPlayerService::AudioOutput::open( format, channelMask, frameCount, - AUDIO_OUTPUT_FLAG_NONE, + flags, CallbackWrapper, mCallbackData, 0, // notification frames @@ -1599,7 +1605,7 @@ status_t MediaPlayerService::AudioOutput::open( format, channelMask, frameCount, - AUDIO_OUTPUT_FLAG_NONE, + flags, NULL, NULL, 0, @@ -1616,6 +1622,7 @@ status_t MediaPlayerService::AudioOutput::open( t->setVolume(mLeftVolume, mRightVolume); mSampleRateHz = sampleRate; + mFlags = flags; mMsecsPerFrame = mPlaybackRatePermille / (float) sampleRate; uint32_t pos; if (t->getPosition(&pos) == OK) { @@ -1891,7 +1898,7 @@ bool CallbackThread::threadLoop() { status_t MediaPlayerService::AudioCache::open( uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask, audio_format_t format, int bufferCount, - AudioCallback cb, void *cookie) + AudioCallback cb, void *cookie, audio_output_flags_t flags) { ALOGV("open(%u, %d, 0x%x, %d, %d)", sampleRate, channelCount, channelMask, format, bufferCount); if (mHeap->getHeapID() < 0) { diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h index 2a8cfd2..95b1b05 100644 --- a/media/libmediaplayerservice/MediaPlayerService.h +++ b/media/libmediaplayerservice/MediaPlayerService.h @@ -91,7 +91,8 @@ class MediaPlayerService : public BnMediaPlayerService virtual status_t open( uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask, audio_format_t format, int bufferCount, - AudioCallback cb, void *cookie); + AudioCallback cb, void *cookie, + audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE); virtual void start(); virtual ssize_t write(const void* buffer, size_t size); @@ -135,6 +136,7 @@ class MediaPlayerService : public BnMediaPlayerService int mAuxEffectId; static bool mIsOnEmulator; static int mMinBufferCount; // 12 for emulator; otherwise 4 + audio_output_flags_t mFlags; // CallbackData is what is passed to the AudioTrack as the "user" data. // We need to be able to target this to a different Output on the fly, @@ -190,7 +192,8 @@ class MediaPlayerService : public BnMediaPlayerService virtual status_t open( uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask, audio_format_t format, int bufferCount = 1, - AudioCallback cb = NULL, void *cookie = NULL); + AudioCallback cb = NULL, void *cookie = NULL, + audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE); virtual void start(); virtual ssize_t write(const void* buffer, size_t size); diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index 11cea3b..f1467c4 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -390,12 +390,30 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { sampleRate, numChannels); mAudioSink->close(); + + audio_output_flags_t flags; + int64_t durationUs; + // FIXME: we should handle the case where the video decoder is created after + // we receive the format change indication. Current code will just make that + // we select deep buffer with video which should not be a problem as it should + // not prevent from keeping A/V sync. + if (mVideoDecoder == NULL && + mSource->getDuration(&durationUs) == OK && + durationUs > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) { + flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER; + } else { + flags = AUDIO_OUTPUT_FLAG_NONE; + } + CHECK_EQ(mAudioSink->open( sampleRate, numChannels, CHANNEL_MASK_USE_CHANNEL_ORDER, AUDIO_FORMAT_PCM_16_BIT, - 8 /* bufferCount */), + 8 /* bufferCount */, + NULL, + NULL, + flags), (status_t)OK); mAudioSink->start(); diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp index 468fe2c..2e0b013 100644 --- a/media/libstagefright/AudioPlayer.cpp +++ b/media/libstagefright/AudioPlayer.cpp @@ -33,6 +33,7 @@ namespace android { AudioPlayer::AudioPlayer( const sp<MediaPlayerBase::AudioSink> &audioSink, + bool allowDeepBuffering, AwesomePlayer *observer) : mAudioTrack(NULL), mInputBuffer(NULL), @@ -50,6 +51,7 @@ AudioPlayer::AudioPlayer( mFirstBufferResult(OK), mFirstBuffer(NULL), mAudioSink(audioSink), + mAllowDeepBuffering(allowDeepBuffering), mObserver(observer) { } @@ -120,10 +122,15 @@ status_t AudioPlayer::start(bool sourceAlreadyStarted) { } if (mAudioSink.get() != NULL) { + status_t err = mAudioSink->open( mSampleRate, numChannels, channelMask, AUDIO_FORMAT_PCM_16_BIT, DEFAULT_AUDIOSINK_BUFFERCOUNT, - &AudioPlayer::AudioSinkCallback, this); + &AudioPlayer::AudioSinkCallback, + this, + (mAllowDeepBuffering ? + AUDIO_OUTPUT_FLAG_DEEP_BUFFER : + AUDIO_OUTPUT_FLAG_NONE)); if (err != OK) { if (mFirstBuffer != NULL) { mFirstBuffer->release(); diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp index b67476b..b15cb67 100644 --- a/media/libstagefright/AwesomePlayer.cpp +++ b/media/libstagefright/AwesomePlayer.cpp @@ -870,7 +870,18 @@ status_t AwesomePlayer::play_l() { if (mAudioSource != NULL) { if (mAudioPlayer == NULL) { if (mAudioSink != NULL) { - mAudioPlayer = new AudioPlayer(mAudioSink, this); + bool allowDeepBuffering; + int64_t cachedDurationUs; + bool eos; + if (mVideoSource == NULL && (mDurationUs > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US || + getCachedDuration_l(&cachedDurationUs, &eos) && + cachedDurationUs > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US)) { + allowDeepBuffering = true; + } else { + allowDeepBuffering = false; + } + + mAudioPlayer = new AudioPlayer(mAudioSink, allowDeepBuffering, this); mAudioPlayer->setSource(mAudioSource); mTimeSource = mAudioPlayer; |