From 67295b543c16ed7c77b67f859d598fe7b4571660 Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Mon, 11 Jun 2012 14:52:53 -0700 Subject: Fix gapless playback On some devices the actual framecount per buffer of an AudioTrack will be different than what was requested, which prevented the track from being reused. Now we create a new AudioTrack with the requested parameters, and then compare it to the track we already have. If they match, we throw away the new track and reuse the existing one. b/6644559 Change-Id: Id3e8c4460436f52e59b98ecaeb01c94f02877c1d --- media/libmediaplayerservice/MediaPlayerService.cpp | 85 ++++++++++++---------- 1 file changed, 47 insertions(+), 38 deletions(-) (limited to 'media/libmediaplayerservice/MediaPlayerService.cpp') diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index 20d6d7a..4bf2d3f 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -1542,6 +1542,43 @@ status_t MediaPlayerService::AudioOutput::open( } } + AudioTrack *t; + CallbackData *newcbd = NULL; + if (mCallback != NULL) { + newcbd = new CallbackData(this); + t = new AudioTrack( + mStreamType, + sampleRate, + format, + channelMask, + frameCount, + flags, + CallbackWrapper, + newcbd, + 0, // notification frames + mSessionId); + } else { + t = new AudioTrack( + mStreamType, + sampleRate, + format, + channelMask, + frameCount, + flags, + NULL, + NULL, + 0, + mSessionId); + } + + if ((t == 0) || (t->initCheck() != NO_ERROR)) { + ALOGE("Unable to create audio track"); + delete t; + delete newcbd; + 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,11 +1590,14 @@ status_t MediaPlayerService::AudioOutput::open( reuse = false; } else if ((mRecycledTrack->getSampleRate() != sampleRate) || (mRecycledTrack->channelCount() != channelCount) || - (mRecycledTrack->frameCount() != frameCount)) { - ALOGV("samplerate, channelcount or framecount differ"); + (mRecycledTrack->frameCount() != t->frameCount())) { + ALOGV("samplerate, channelcount or framecount differ: %d/%d Hz, %d/%d ch, %d/%d frames", + mRecycledTrack->getSampleRate(), sampleRate, + mRecycledTrack->channelCount(), channelCount, + mRecycledTrack->frameCount(), t->frameCount()); reuse = false; - } if (flags != mFlags) { - ALOGV("output flags differ"); + } else if (flags != mFlags) { + ALOGV("output flags differ %08x/%08x", flags, mFlags); reuse = false; } if (reuse) { @@ -1568,6 +1608,8 @@ status_t MediaPlayerService::AudioOutput::open( if (mCallbackData != NULL) { mCallbackData->setOutput(this); } + delete t; + delete newcbd; return OK; } @@ -1584,40 +1626,7 @@ status_t MediaPlayerService::AudioOutput::open( close(); } - AudioTrack *t; - if (mCallback != NULL) { - mCallbackData = new CallbackData(this); - t = new AudioTrack( - mStreamType, - sampleRate, - format, - channelMask, - frameCount, - flags, - CallbackWrapper, - mCallbackData, - 0, // notification frames - mSessionId); - } else { - t = new AudioTrack( - mStreamType, - sampleRate, - format, - channelMask, - frameCount, - flags, - NULL, - NULL, - 0, - mSessionId); - } - - if ((t == 0) || (t->initCheck() != NO_ERROR)) { - ALOGE("Unable to create audio track"); - delete t; - return NO_INIT; - } - + mCallbackData = newcbd; ALOGV("setVolume"); t->setVolume(mLeftVolume, mRightVolume); -- cgit v1.1