From 2799d743ee2ae5a25fe869a7f9c052acc029559f Mon Sep 17 00:00:00 2001 From: Glenn Kasten Date: Thu, 30 May 2013 14:33:29 -0700 Subject: [PATCH] Use sp instead of raw AudioTrack * This change prepares for the new implementation of AudioTrack client, which will require clients to use only sp, not raw AudioTrack *. A raw delete will cause a race condition during AudioTrack destruction. AudioTrack was made a RefBase by commit b68a91a70bc8d0d18e7404e14443d4e4020b3635 on 2011/11/15, when it was needed by OpenSL ES (for the callback protector). At that time, the only other client that was also converted from AudioTrack * to sp was android.media.AudioTrack JNI in project frameworks/base (file android_media_AudioTrack.cpp). Details: * Use .clear() instead of delete followed by = NULL. * ALOG %p need .get(). * sp<> don't need to be listed in constructor initializer, if initially 0. * Use == 0 for sp<> vs == NULL for raw pointers. * Use if (sp != 0) instead of if (raw). Change-Id: Ic7cad25795d6e862e112abdc227b6d33afdfce17 --- include/media/AudioTrack.h | 4 ++- include/media/JetPlayer.h | 2 +- include/media/SoundPool.h | 4 +-- include/media/ToneGenerator.h | 4 +-- include/media/stagefright/AudioPlayer.h | 2 +- libvideoeditor/lvpp/VideoEditorAudioPlayer.cpp | 9 ++---- libvideoeditor/lvpp/VideoEditorAudioPlayer.h | 2 +- libvideoeditor/lvpp/VideoEditorPlayer.cpp | 21 ++++++------ libvideoeditor/lvpp/VideoEditorPlayer.h | 2 +- media/libmedia/JetPlayer.cpp | 6 ++-- media/libmedia/SoundPool.cpp | 14 ++++---- media/libmedia/ToneGenerator.cpp | 22 ++++--------- media/libmediaplayerservice/MediaPlayerService.cpp | 37 +++++++++------------- media/libmediaplayerservice/MediaPlayerService.h | 6 ++-- media/libstagefright/AudioPlayer.cpp | 11 +++---- 15 files changed, 60 insertions(+), 86 deletions(-) diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h index 0b616e3665..8dbc9eeaea 100644 --- a/include/media/AudioTrack.h +++ b/include/media/AudioTrack.h @@ -191,7 +191,9 @@ public: /* Terminates the AudioTrack and unregisters it from AudioFlinger. * Also destroys all resources associated with the AudioTrack. */ - ~AudioTrack(); +protected: + virtual ~AudioTrack(); +public: /* Initialize an uninitialized AudioTrack. * Returned status (from utils/Errors.h) can be: diff --git a/include/media/JetPlayer.h b/include/media/JetPlayer.h index 0616bf039b..388f767749 100644 --- a/include/media/JetPlayer.h +++ b/include/media/JetPlayer.h @@ -88,7 +88,7 @@ private: EAS_DATA_HANDLE mEasData; EAS_FILE_LOCATOR mEasJetFileLoc; EAS_PCM* mAudioBuffer;// EAS renders the MIDI data into this buffer, - AudioTrack* mAudioTrack; // and we play it in this audio track + sp mAudioTrack; // and we play it in this audio track int mTrackBufferSize; S_JET_STATUS mJetStatus; S_JET_STATUS mPreviousJetStatus; diff --git a/include/media/SoundPool.h b/include/media/SoundPool.h index 7bf306901b..9e5654f4f1 100644 --- a/include/media/SoundPool.h +++ b/include/media/SoundPool.h @@ -118,7 +118,7 @@ protected: class SoundChannel : public SoundEvent { public: enum state { IDLE, RESUMING, STOPPING, PAUSED, PLAYING }; - SoundChannel() : mAudioTrack(NULL), mState(IDLE), mNumChannels(1), + SoundChannel() : mState(IDLE), mNumChannels(1), mPos(0), mToggle(0), mAutoPaused(false) {} ~SoundChannel(); void init(SoundPool* soundPool); @@ -148,7 +148,7 @@ private: bool doStop_l(); SoundPool* mSoundPool; - AudioTrack* mAudioTrack; + sp mAudioTrack; SoundEvent mNextEvent; Mutex mLock; int mState; diff --git a/include/media/ToneGenerator.h b/include/media/ToneGenerator.h index 2183fbe1f4..98c4332021 100644 --- a/include/media/ToneGenerator.h +++ b/include/media/ToneGenerator.h @@ -160,7 +160,7 @@ public: bool isInited() { return (mState == TONE_IDLE)?false:true;} // returns the audio session this ToneGenerator belongs to or 0 if an error occured. - int getSessionId() { return (mpAudioTrack == NULL) ? 0 : mpAudioTrack->getSessionId(); } + int getSessionId() { return (mpAudioTrack == 0) ? 0 : mpAudioTrack->getSessionId(); } private: @@ -264,7 +264,7 @@ private: unsigned short mLoopCounter; // Current tone loopback count uint32_t mSamplingRate; // AudioFlinger Sampling rate - AudioTrack *mpAudioTrack; // Pointer to audio track used for playback + sp mpAudioTrack; // Pointer to audio track used for playback Mutex mLock; // Mutex to control concurent access to ToneGenerator object from audio callback and application API Mutex mCbkCondLock; // Mutex associated to mWaitCbkCond Condition mWaitCbkCond; // condition enabling interface to wait for audio callback completion after a change is requested diff --git a/include/media/stagefright/AudioPlayer.h b/include/media/stagefright/AudioPlayer.h index 1dc408fe65..3bf046d0b1 100644 --- a/include/media/stagefright/AudioPlayer.h +++ b/include/media/stagefright/AudioPlayer.h @@ -70,7 +70,7 @@ public: private: friend class VideoEditorAudioPlayer; sp mSource; - AudioTrack *mAudioTrack; + sp mAudioTrack; MediaBuffer *mInputBuffer; diff --git a/libvideoeditor/lvpp/VideoEditorAudioPlayer.cpp b/libvideoeditor/lvpp/VideoEditorAudioPlayer.cpp index c111ba81da..3fa8b87a6a 100755 --- a/libvideoeditor/lvpp/VideoEditorAudioPlayer.cpp +++ b/libvideoeditor/lvpp/VideoEditorAudioPlayer.cpp @@ -35,8 +35,7 @@ namespace android { VideoEditorAudioPlayer::VideoEditorAudioPlayer( const sp &audioSink, PreviewPlayer *observer) - : mAudioTrack(NULL), - mInputBuffer(NULL), + : mInputBuffer(NULL), mSampleRate(0), mLatencyUs(0), mFrameSize(0), @@ -111,8 +110,7 @@ void VideoEditorAudioPlayer::clear() { } else { mAudioTrack->stop(); - delete mAudioTrack; - mAudioTrack = NULL; + mAudioTrack.clear(); } // Make sure to release any buffer we hold onto so that the @@ -538,8 +536,7 @@ status_t VideoEditorAudioPlayer::start(bool sourceAlreadyStarted) { 0, AUDIO_OUTPUT_FLAG_NONE, &AudioCallback, this, 0); if ((err = mAudioTrack->initCheck()) != OK) { - delete mAudioTrack; - mAudioTrack = NULL; + mAudioTrack.clear(); if (mFirstBuffer != NULL) { mFirstBuffer->release(); diff --git a/libvideoeditor/lvpp/VideoEditorAudioPlayer.h b/libvideoeditor/lvpp/VideoEditorAudioPlayer.h index 626df39aca..a5616c1224 100755 --- a/libvideoeditor/lvpp/VideoEditorAudioPlayer.h +++ b/libvideoeditor/lvpp/VideoEditorAudioPlayer.h @@ -91,7 +91,7 @@ private: int64_t mBGAudioStoryBoardCurrentMediaVolumeVal; sp mSource; - AudioTrack *mAudioTrack; + sp mAudioTrack; MediaBuffer *mInputBuffer; diff --git a/libvideoeditor/lvpp/VideoEditorPlayer.cpp b/libvideoeditor/lvpp/VideoEditorPlayer.cpp index 91a44150c4..4a14b40221 100755 --- a/libvideoeditor/lvpp/VideoEditorPlayer.cpp +++ b/libvideoeditor/lvpp/VideoEditorPlayer.cpp @@ -310,7 +310,6 @@ bool VideoEditorPlayer::VeAudioOutput::mIsOnEmulator = false; VideoEditorPlayer::VeAudioOutput::VeAudioOutput() : mCallback(NULL), mCallbackCookie(NULL) { - mTrack = 0; mStreamType = AUDIO_STREAM_MUSIC; mLeftVolume = 1.0; mRightVolume = 1.0; @@ -405,7 +404,7 @@ status_t VideoEditorPlayer::VeAudioOutput::open( } ALOGV("open(%u, %d, %d, %d)", sampleRate, channelCount, format, bufferCount); - if (mTrack) close(); + if (mTrack != 0) close(); uint32_t afSampleRate; size_t afFrameCount; int frameCount; @@ -434,7 +433,7 @@ status_t VideoEditorPlayer::VeAudioOutput::open( } } - AudioTrack *t; + sp t; if (mCallback != NULL) { t = new AudioTrack( mStreamType, @@ -457,7 +456,6 @@ status_t VideoEditorPlayer::VeAudioOutput::open( if ((t == 0) || (t->initCheck() != NO_ERROR)) { ALOGE("Unable to create audio track"); - delete t; return NO_INIT; } @@ -472,7 +470,7 @@ status_t VideoEditorPlayer::VeAudioOutput::open( void VideoEditorPlayer::VeAudioOutput::start() { ALOGV("start"); - if (mTrack) { + if (mTrack != 0) { mTrack->setVolume(mLeftVolume, mRightVolume); mTrack->start(); mTrack->getPosition(&mNumFramesWritten); @@ -492,7 +490,7 @@ ssize_t VideoEditorPlayer::VeAudioOutput::write( LOG_FATAL_IF(mCallback != NULL, "Don't call write if supplying a callback."); //ALOGV("write(%p, %u)", buffer, size); - if (mTrack) { + if (mTrack != 0) { snoopWrite(buffer, size); ssize_t ret = mTrack->write(buffer, size); mNumFramesWritten += ret / 4; // assume 16 bit stereo @@ -504,26 +502,25 @@ ssize_t VideoEditorPlayer::VeAudioOutput::write( void VideoEditorPlayer::VeAudioOutput::stop() { ALOGV("stop"); - if (mTrack) mTrack->stop(); + if (mTrack != 0) mTrack->stop(); } void VideoEditorPlayer::VeAudioOutput::flush() { ALOGV("flush"); - if (mTrack) mTrack->flush(); + if (mTrack != 0) mTrack->flush(); } void VideoEditorPlayer::VeAudioOutput::pause() { ALOGV("VeAudioOutput::pause"); - if (mTrack) mTrack->pause(); + if (mTrack != 0) mTrack->pause(); } void VideoEditorPlayer::VeAudioOutput::close() { ALOGV("close"); - delete mTrack; - mTrack = 0; + mTrack.clear(); } void VideoEditorPlayer::VeAudioOutput::setVolume(float left, float right) { @@ -531,7 +528,7 @@ void VideoEditorPlayer::VeAudioOutput::setVolume(float left, float right) { ALOGV("setVolume(%f, %f)", left, right); mLeftVolume = left; mRightVolume = right; - if (mTrack) { + if (mTrack != 0) { mTrack->setVolume(left, right); } } diff --git a/libvideoeditor/lvpp/VideoEditorPlayer.h b/libvideoeditor/lvpp/VideoEditorPlayer.h index 77194ab880..defc90d351 100755 --- a/libvideoeditor/lvpp/VideoEditorPlayer.h +++ b/libvideoeditor/lvpp/VideoEditorPlayer.h @@ -71,7 +71,7 @@ class VideoEditorPlayer : public MediaPlayerInterface { static void CallbackWrapper( int event, void *me, void *info); - AudioTrack* mTrack; + sp mTrack; AudioCallback mCallback; void * mCallbackCookie; audio_stream_type_t mStreamType; diff --git a/media/libmedia/JetPlayer.cpp b/media/libmedia/JetPlayer.cpp index 59e538fd69..8fe5bb35fc 100644 --- a/media/libmedia/JetPlayer.cpp +++ b/media/libmedia/JetPlayer.cpp @@ -39,7 +39,6 @@ JetPlayer::JetPlayer(void *javaJetPlayer, int maxTracks, int trackBufferSize) : mMaxTracks(maxTracks), mEasData(NULL), mEasJetFileLoc(NULL), - mAudioTrack(NULL), mTrackBufferSize(trackBufferSize) { ALOGV("JetPlayer constructor"); @@ -140,11 +139,10 @@ int JetPlayer::release() free(mEasJetFileLoc); mEasJetFileLoc = NULL; } - if (mAudioTrack) { + if (mAudioTrack != 0) { mAudioTrack->stop(); mAudioTrack->flush(); - delete mAudioTrack; - mAudioTrack = NULL; + mAudioTrack.clear(); } if (mAudioBuffer) { delete mAudioBuffer; diff --git a/media/libmedia/SoundPool.cpp b/media/libmedia/SoundPool.cpp index ee70ef7512..e1e88ece16 100644 --- a/media/libmedia/SoundPool.cpp +++ b/media/libmedia/SoundPool.cpp @@ -547,8 +547,8 @@ void SoundChannel::init(SoundPool* soundPool) void SoundChannel::play(const sp& sample, int nextChannelID, float leftVolume, float rightVolume, int priority, int loop, float rate) { - AudioTrack* oldTrack; - AudioTrack* newTrack; + sp oldTrack; + sp newTrack; status_t status; { // scope for the lock @@ -620,7 +620,7 @@ void SoundChannel::play(const sp& sample, int nextChannelID, float leftV ALOGE("Error creating AudioTrack"); goto exit; } - ALOGV("setVolume %p", newTrack); + ALOGV("setVolume %p", newTrack.get()); newTrack->setVolume(leftVolume, rightVolume); newTrack->setLoop(0, frameCount, loop); @@ -643,11 +643,9 @@ void SoundChannel::play(const sp& sample, int nextChannelID, float leftV } exit: - ALOGV("delete oldTrack %p", oldTrack); - delete oldTrack; + ALOGV("delete oldTrack %p", oldTrack.get()); if (status != NO_ERROR) { - delete newTrack; - mAudioTrack = NULL; + mAudioTrack.clear(); } } @@ -884,7 +882,7 @@ SoundChannel::~SoundChannel() } // do not call AudioTrack destructor with mLock held as it will wait for the AudioTrack // callback thread to exit which may need to execute process() and acquire the mLock. - delete mAudioTrack; + mAudioTrack.clear(); } void SoundChannel::dump() diff --git a/media/libmedia/ToneGenerator.cpp b/media/libmedia/ToneGenerator.cpp index f55b6975ea..ebe1ba1bcb 100644 --- a/media/libmedia/ToneGenerator.cpp +++ b/media/libmedia/ToneGenerator.cpp @@ -803,7 +803,6 @@ ToneGenerator::ToneGenerator(audio_stream_type_t streamType, float volume, bool ALOGV("ToneGenerator constructor: streamType=%d, volume=%f", streamType, volume); mState = TONE_IDLE; - mpAudioTrack = NULL; if (AudioSystem::getOutputSamplingRate(&mSamplingRate, streamType) != NO_ERROR) { ALOGE("Unable to marshal AudioFlinger"); @@ -855,10 +854,10 @@ ToneGenerator::ToneGenerator(audio_stream_type_t streamType, float volume, bool ToneGenerator::~ToneGenerator() { ALOGV("ToneGenerator destructor"); - if (mpAudioTrack != NULL) { + if (mpAudioTrack != 0) { stopTone(); - ALOGV("Delete Track: %p", mpAudioTrack); - delete mpAudioTrack; + ALOGV("Delete Track: %p", mpAudioTrack.get()); + mpAudioTrack.clear(); } } @@ -1047,14 +1046,9 @@ void ToneGenerator::stopTone() { //////////////////////////////////////////////////////////////////////////////// bool ToneGenerator::initAudioTrack() { - if (mpAudioTrack) { - delete mpAudioTrack; - mpAudioTrack = NULL; - } - // Open audio track in mono, PCM 16bit, default sampling rate, default buffer size mpAudioTrack = new AudioTrack(); - ALOGV("Create Track: %p", mpAudioTrack); + ALOGV("Create Track: %p", mpAudioTrack.get()); mpAudioTrack->set(mStreamType, 0, // sampleRate @@ -1081,12 +1075,10 @@ bool ToneGenerator::initAudioTrack() { initAudioTrack_exit: + ALOGV("Init failed: %p", mpAudioTrack.get()); + // Cleanup - if (mpAudioTrack != NULL) { - ALOGV("Delete Track I: %p", mpAudioTrack); - delete mpAudioTrack; - mpAudioTrack = NULL; - } + mpAudioTrack.clear(); return false; } diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index e600a3f618..fa1ff36aec 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -1295,8 +1295,6 @@ MediaPlayerService::AudioOutput::AudioOutput(int sessionId) mSessionId(sessionId), mFlags(AUDIO_OUTPUT_FLAG_NONE) { ALOGV("AudioOutput(%d)", sessionId); - mTrack = 0; - mRecycledTrack = 0; mStreamType = AUDIO_STREAM_MUSIC; mLeftVolume = 1.0; mRightVolume = 1.0; @@ -1311,7 +1309,6 @@ MediaPlayerService::AudioOutput::AudioOutput(int sessionId) MediaPlayerService::AudioOutput::~AudioOutput() { close(); - delete mRecycledTrack; delete mCallbackData; } @@ -1422,7 +1419,7 @@ status_t MediaPlayerService::AudioOutput::open( } } - AudioTrack *t; + sp t; CallbackData *newcbd = NULL; if (mCallback != NULL) { newcbd = new CallbackData(this); @@ -1453,13 +1450,12 @@ status_t MediaPlayerService::AudioOutput::open( if ((t == 0) || (t->initCheck() != NO_ERROR)) { ALOGE("Unable to create audio track"); - delete t; delete newcbd; return NO_INIT; } - if (mRecycledTrack) { + if (mRecycledTrack != 0) { // check if the existing track can be reused as-is, or if a new track needs to be created. bool reuse = true; @@ -1484,11 +1480,10 @@ status_t MediaPlayerService::AudioOutput::open( ALOGV("chaining to next output"); close(); mTrack = mRecycledTrack; - mRecycledTrack = NULL; + mRecycledTrack.clear(); if (mCallbackData != NULL) { mCallbackData->setOutput(this); } - delete t; delete newcbd; return OK; } @@ -1499,8 +1494,7 @@ status_t MediaPlayerService::AudioOutput::open( mCallbackData->endTrackSwitch(); } mRecycledTrack->flush(); - delete mRecycledTrack; - mRecycledTrack = NULL; + mRecycledTrack.clear(); delete mCallbackData; mCallbackData = NULL; close(); @@ -1533,7 +1527,7 @@ void MediaPlayerService::AudioOutput::start() if (mCallbackData != NULL) { mCallbackData->endTrackSwitch(); } - if (mTrack) { + if (mTrack != 0) { mTrack->setVolume(mLeftVolume, mRightVolume); mTrack->setAuxEffectSendLevel(mSendLevel); mTrack->start(); @@ -1555,7 +1549,7 @@ void MediaPlayerService::AudioOutput::switchToNextOutput() { mNextOutput->mCallbackData = mCallbackData; mCallbackData = NULL; mNextOutput->mRecycledTrack = mTrack; - mTrack = NULL; + mTrack.clear(); mNextOutput->mSampleRateHz = mSampleRateHz; mNextOutput->mMsecsPerFrame = mMsecsPerFrame; mNextOutput->mBytesWritten = mBytesWritten; @@ -1568,7 +1562,7 @@ ssize_t MediaPlayerService::AudioOutput::write(const void* buffer, size_t size) LOG_FATAL_IF(mCallback != NULL, "Don't call write if supplying a callback."); //ALOGV("write(%p, %u)", buffer, size); - if (mTrack) { + if (mTrack != 0) { ssize_t ret = mTrack->write(buffer, size); mBytesWritten += ret; return ret; @@ -1579,26 +1573,25 @@ ssize_t MediaPlayerService::AudioOutput::write(const void* buffer, size_t size) void MediaPlayerService::AudioOutput::stop() { ALOGV("stop"); - if (mTrack) mTrack->stop(); + if (mTrack != 0) mTrack->stop(); } void MediaPlayerService::AudioOutput::flush() { ALOGV("flush"); - if (mTrack) mTrack->flush(); + if (mTrack != 0) mTrack->flush(); } void MediaPlayerService::AudioOutput::pause() { ALOGV("pause"); - if (mTrack) mTrack->pause(); + if (mTrack != 0) mTrack->pause(); } void MediaPlayerService::AudioOutput::close() { ALOGV("close"); - delete mTrack; - mTrack = 0; + mTrack.clear(); } void MediaPlayerService::AudioOutput::setVolume(float left, float right) @@ -1606,7 +1599,7 @@ void MediaPlayerService::AudioOutput::setVolume(float left, float right) ALOGV("setVolume(%f, %f)", left, right); mLeftVolume = left; mRightVolume = right; - if (mTrack) { + if (mTrack != 0) { mTrack->setVolume(left, right); } } @@ -1615,7 +1608,7 @@ status_t MediaPlayerService::AudioOutput::setPlaybackRatePermille(int32_t ratePe { ALOGV("setPlaybackRatePermille(%d)", ratePermille); status_t res = NO_ERROR; - if (mTrack) { + if (mTrack != 0) { res = mTrack->setSampleRate(ratePermille * mSampleRateHz / 1000); } else { res = NO_INIT; @@ -1631,7 +1624,7 @@ status_t MediaPlayerService::AudioOutput::setAuxEffectSendLevel(float level) { ALOGV("setAuxEffectSendLevel(%f)", level); mSendLevel = level; - if (mTrack) { + if (mTrack != 0) { return mTrack->setAuxEffectSendLevel(level); } return NO_ERROR; @@ -1641,7 +1634,7 @@ status_t MediaPlayerService::AudioOutput::attachAuxEffect(int effectId) { ALOGV("attachAuxEffect(%d)", effectId); mAuxEffectId = effectId; - if (mTrack) { + if (mTrack != 0) { return mTrack->attachAuxEffect(effectId); } return NO_ERROR; diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h index b33805d77c..e586156f8c 100644 --- a/media/libmediaplayerservice/MediaPlayerService.h +++ b/media/libmediaplayerservice/MediaPlayerService.h @@ -78,7 +78,7 @@ class MediaPlayerService : public BnMediaPlayerService AudioOutput(int sessionId); virtual ~AudioOutput(); - virtual bool ready() const { return mTrack != NULL; } + virtual bool ready() const { return mTrack != 0; } virtual bool realtime() const { return true; } virtual ssize_t bufferSize() const; virtual ssize_t frameCount() const; @@ -120,8 +120,8 @@ class MediaPlayerService : public BnMediaPlayerService static void CallbackWrapper( int event, void *me, void *info); - AudioTrack* mTrack; - AudioTrack* mRecycledTrack; + sp mTrack; + sp mRecycledTrack; sp mNextOutput; AudioCallback mCallback; void * mCallbackCookie; diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp index 4208019378..92efae81ad 100644 --- a/media/libstagefright/AudioPlayer.cpp +++ b/media/libstagefright/AudioPlayer.cpp @@ -36,8 +36,7 @@ AudioPlayer::AudioPlayer( const sp &audioSink, bool allowDeepBuffering, AwesomePlayer *observer) - : mAudioTrack(NULL), - mInputBuffer(NULL), + : mInputBuffer(NULL), mSampleRate(0), mLatencyUs(0), mFrameSize(0), @@ -166,8 +165,7 @@ status_t AudioPlayer::start(bool sourceAlreadyStarted) { 0, AUDIO_OUTPUT_FLAG_NONE, &AudioCallback, this, 0); if ((err = mAudioTrack->initCheck()) != OK) { - delete mAudioTrack; - mAudioTrack = NULL; + mAudioTrack.clear(); if (mFirstBuffer != NULL) { mFirstBuffer->release(); @@ -235,8 +233,7 @@ void AudioPlayer::reset() { } else { mAudioTrack->stop(); - delete mAudioTrack; - mAudioTrack = NULL; + mAudioTrack.clear(); } // Make sure to release any buffer we hold onto so that the @@ -297,7 +294,7 @@ bool AudioPlayer::reachedEOS(status_t *finalStatus) { status_t AudioPlayer::setPlaybackRatePermille(int32_t ratePermille) { if (mAudioSink.get() != NULL) { return mAudioSink->setPlaybackRatePermille(ratePermille); - } else if (mAudioTrack != NULL){ + } else if (mAudioTrack != 0){ return mAudioTrack->setSampleRate(ratePermille * mSampleRate / 1000); } else { return NO_INIT; -- 2.11.0