Loading include/private/media/AudioTrackShared.h +2 −2 Original line number Diff line number Diff line Loading @@ -168,6 +168,7 @@ protected: const bool mIsOut; // true for AudioTrack, false for AudioRecord const bool mClientInServer; // true for OutputTrack, false for AudioTrack & AudioRecord bool mIsShutdown; // latch set to true when shared memory corruption detected size_t mUnreleased; // unreleased frames remaining from most recent obtainBuffer }; // ---------------------------------------------------------------------------- Loading Loading @@ -213,7 +214,7 @@ public: // DEAD_OBJECT Server has died or invalidated, caller should destroy this proxy and re-create. // -EINTR Call has been interrupted. Look around to see why, and then perhaps try again. // NO_INIT Shared memory is corrupt. // BAD_VALUE On entry buffer == NULL or buffer->mFrameCount == 0. // Assertion failure on entry, if buffer == NULL or buffer->mFrameCount == 0. status_t obtainBuffer(Buffer* buffer, const struct timespec *requested = NULL, struct timespec *elapsed = NULL); Loading Loading @@ -372,7 +373,6 @@ public: virtual void releaseBuffer(Buffer* buffer); protected: size_t mUnreleased; // unreleased frames remaining from most recent obtainBuffer() size_t mAvailToClient; // estimated frames available to client prior to releaseBuffer() private: int32_t mFlush; // our copy of cblk->u.mStreaming.mFlush, for streaming output only Loading media/libmedia/AudioTrackShared.cpp +32 −31 Original line number Diff line number Diff line Loading @@ -38,7 +38,7 @@ Proxy::Proxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t bool isOut, bool clientInServer) : mCblk(cblk), mBuffers(buffers), mFrameCount(frameCount), mFrameSize(frameSize), mFrameCountP2(roundup(frameCount)), mIsOut(isOut), mClientInServer(clientInServer), mIsShutdown(false) mIsShutdown(false), mUnreleased(0) { } Loading @@ -64,10 +64,7 @@ const struct timespec ClientProxy::kNonBlocking = {0 /*tv_sec*/, 0 /*tv_nsec*/}; status_t ClientProxy::obtainBuffer(Buffer* buffer, const struct timespec *requested, struct timespec *elapsed) { if (buffer == NULL || buffer->mFrameCount == 0) { ALOGE("%s BAD_VALUE", __func__); return BAD_VALUE; } LOG_ALWAYS_FATAL_IF(buffer == NULL || buffer->mFrameCount == 0); struct timespec total; // total elapsed time spent waiting total.tv_sec = 0; total.tv_nsec = 0; Loading Loading @@ -164,7 +161,7 @@ status_t ClientProxy::obtainBuffer(Buffer* buffer, const struct timespec *reques buffer->mRaw = part1 > 0 ? &((char *) mBuffers)[(mIsOut ? rear : front) * mFrameSize] : NULL; buffer->mNonContig = avail - part1; // mUnreleased = part1; mUnreleased = part1; status = NO_ERROR; break; } Loading Loading @@ -238,6 +235,7 @@ status_t ClientProxy::obtainBuffer(Buffer* buffer, const struct timespec *reques case -EWOULDBLOCK: // benign race condition with server case -EINTR: // wait was interrupted by signal or other spurious wakeup case -ETIMEDOUT: // time-out expired // FIXME these error/non-0 status are being dropped break; default: ALOGE("%s unexpected error %d", __func__, ret); Loading @@ -252,6 +250,7 @@ end: buffer->mFrameCount = 0; buffer->mRaw = NULL; buffer->mNonContig = 0; mUnreleased = 0; } if (elapsed != NULL) { *elapsed = total; Loading @@ -268,14 +267,17 @@ end: void ClientProxy::releaseBuffer(Buffer* buffer) { LOG_ALWAYS_FATAL_IF(buffer == NULL); size_t stepCount = buffer->mFrameCount; // FIXME // check mUnreleased // verify that stepCount <= frameCount returned by the last obtainBuffer() // verify stepCount not > total frame count of pipe if (stepCount == 0) { if (stepCount == 0 || mIsShutdown) { // prevent accidental re-use of buffer buffer->mFrameCount = 0; buffer->mRaw = NULL; buffer->mNonContig = 0; return; } LOG_ALWAYS_FATAL_IF(!(stepCount <= mUnreleased && mUnreleased <= mFrameCount)); mUnreleased -= stepCount; audio_track_cblk_t* cblk = mCblk; // Both of these barriers are required if (mIsOut) { Loading Loading @@ -362,20 +364,18 @@ size_t StaticAudioTrackClientProxy::getBufferPosition() ServerProxy::ServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize, bool isOut, bool clientInServer) : Proxy(cblk, buffers, frameCount, frameSize, isOut, clientInServer), mUnreleased(0), : Proxy(cblk, buffers, frameCount, frameSize, isOut, clientInServer), mAvailToClient(0), mFlush(0), mDeferWake(false) { } status_t ServerProxy::obtainBuffer(Buffer* buffer) { LOG_ALWAYS_FATAL_IF(buffer == NULL || buffer->mFrameCount == 0); if (mIsShutdown) { buffer->mFrameCount = 0; buffer->mRaw = NULL; buffer->mNonContig = 0; mUnreleased = 0; return NO_INIT; goto no_init; } { audio_track_cblk_t* cblk = mCblk; // compute number of frames available to write (AudioTrack) or read (AudioRecord), // or use previous cached value from framesReady(), with added barrier if it omits. Loading Loading @@ -404,11 +404,7 @@ status_t ServerProxy::obtainBuffer(Buffer* buffer) mIsShutdown = true; } if (mIsShutdown) { buffer->mFrameCount = 0; buffer->mRaw = NULL; buffer->mNonContig = 0; mUnreleased = 0; return NO_INIT; goto no_init; } // don't allow filling pipe beyond the nominal size size_t availToServer; Loading Loading @@ -446,22 +442,26 @@ status_t ServerProxy::obtainBuffer(Buffer* buffer) mDeferWake = part1 < ask && availToServer >= ask; return part1 > 0 ? NO_ERROR : WOULD_BLOCK; } void ServerProxy::releaseBuffer(Buffer* buffer) { if (mIsShutdown) { no_init: buffer->mFrameCount = 0; buffer->mRaw = NULL; buffer->mNonContig = 0; return; mUnreleased = 0; return NO_INIT; } void ServerProxy::releaseBuffer(Buffer* buffer) { LOG_ALWAYS_FATAL_IF(buffer == NULL); size_t stepCount = buffer->mFrameCount; LOG_ALWAYS_FATAL_IF(stepCount > mUnreleased); if (stepCount == 0) { if (stepCount == 0 || mIsShutdown) { // prevent accidental re-use of buffer buffer->mFrameCount = 0; buffer->mRaw = NULL; buffer->mNonContig = 0; return; } LOG_ALWAYS_FATAL_IF(!(stepCount <= mUnreleased && mUnreleased <= mFrameCount)); mUnreleased -= stepCount; audio_track_cblk_t* cblk = mCblk; if (mIsOut) { Loading Loading @@ -639,8 +639,9 @@ status_t StaticAudioTrackServerProxy::obtainBuffer(Buffer* buffer) void StaticAudioTrackServerProxy::releaseBuffer(Buffer* buffer) { size_t stepCount = buffer->mFrameCount; LOG_ALWAYS_FATAL_IF(stepCount > mUnreleased); LOG_ALWAYS_FATAL_IF(!(stepCount <= mUnreleased)); if (stepCount == 0) { // prevent accidental re-use of buffer buffer->mRaw = NULL; buffer->mNonContig = 0; return; Loading Loading
include/private/media/AudioTrackShared.h +2 −2 Original line number Diff line number Diff line Loading @@ -168,6 +168,7 @@ protected: const bool mIsOut; // true for AudioTrack, false for AudioRecord const bool mClientInServer; // true for OutputTrack, false for AudioTrack & AudioRecord bool mIsShutdown; // latch set to true when shared memory corruption detected size_t mUnreleased; // unreleased frames remaining from most recent obtainBuffer }; // ---------------------------------------------------------------------------- Loading Loading @@ -213,7 +214,7 @@ public: // DEAD_OBJECT Server has died or invalidated, caller should destroy this proxy and re-create. // -EINTR Call has been interrupted. Look around to see why, and then perhaps try again. // NO_INIT Shared memory is corrupt. // BAD_VALUE On entry buffer == NULL or buffer->mFrameCount == 0. // Assertion failure on entry, if buffer == NULL or buffer->mFrameCount == 0. status_t obtainBuffer(Buffer* buffer, const struct timespec *requested = NULL, struct timespec *elapsed = NULL); Loading Loading @@ -372,7 +373,6 @@ public: virtual void releaseBuffer(Buffer* buffer); protected: size_t mUnreleased; // unreleased frames remaining from most recent obtainBuffer() size_t mAvailToClient; // estimated frames available to client prior to releaseBuffer() private: int32_t mFlush; // our copy of cblk->u.mStreaming.mFlush, for streaming output only Loading
media/libmedia/AudioTrackShared.cpp +32 −31 Original line number Diff line number Diff line Loading @@ -38,7 +38,7 @@ Proxy::Proxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t bool isOut, bool clientInServer) : mCblk(cblk), mBuffers(buffers), mFrameCount(frameCount), mFrameSize(frameSize), mFrameCountP2(roundup(frameCount)), mIsOut(isOut), mClientInServer(clientInServer), mIsShutdown(false) mIsShutdown(false), mUnreleased(0) { } Loading @@ -64,10 +64,7 @@ const struct timespec ClientProxy::kNonBlocking = {0 /*tv_sec*/, 0 /*tv_nsec*/}; status_t ClientProxy::obtainBuffer(Buffer* buffer, const struct timespec *requested, struct timespec *elapsed) { if (buffer == NULL || buffer->mFrameCount == 0) { ALOGE("%s BAD_VALUE", __func__); return BAD_VALUE; } LOG_ALWAYS_FATAL_IF(buffer == NULL || buffer->mFrameCount == 0); struct timespec total; // total elapsed time spent waiting total.tv_sec = 0; total.tv_nsec = 0; Loading Loading @@ -164,7 +161,7 @@ status_t ClientProxy::obtainBuffer(Buffer* buffer, const struct timespec *reques buffer->mRaw = part1 > 0 ? &((char *) mBuffers)[(mIsOut ? rear : front) * mFrameSize] : NULL; buffer->mNonContig = avail - part1; // mUnreleased = part1; mUnreleased = part1; status = NO_ERROR; break; } Loading Loading @@ -238,6 +235,7 @@ status_t ClientProxy::obtainBuffer(Buffer* buffer, const struct timespec *reques case -EWOULDBLOCK: // benign race condition with server case -EINTR: // wait was interrupted by signal or other spurious wakeup case -ETIMEDOUT: // time-out expired // FIXME these error/non-0 status are being dropped break; default: ALOGE("%s unexpected error %d", __func__, ret); Loading @@ -252,6 +250,7 @@ end: buffer->mFrameCount = 0; buffer->mRaw = NULL; buffer->mNonContig = 0; mUnreleased = 0; } if (elapsed != NULL) { *elapsed = total; Loading @@ -268,14 +267,17 @@ end: void ClientProxy::releaseBuffer(Buffer* buffer) { LOG_ALWAYS_FATAL_IF(buffer == NULL); size_t stepCount = buffer->mFrameCount; // FIXME // check mUnreleased // verify that stepCount <= frameCount returned by the last obtainBuffer() // verify stepCount not > total frame count of pipe if (stepCount == 0) { if (stepCount == 0 || mIsShutdown) { // prevent accidental re-use of buffer buffer->mFrameCount = 0; buffer->mRaw = NULL; buffer->mNonContig = 0; return; } LOG_ALWAYS_FATAL_IF(!(stepCount <= mUnreleased && mUnreleased <= mFrameCount)); mUnreleased -= stepCount; audio_track_cblk_t* cblk = mCblk; // Both of these barriers are required if (mIsOut) { Loading Loading @@ -362,20 +364,18 @@ size_t StaticAudioTrackClientProxy::getBufferPosition() ServerProxy::ServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize, bool isOut, bool clientInServer) : Proxy(cblk, buffers, frameCount, frameSize, isOut, clientInServer), mUnreleased(0), : Proxy(cblk, buffers, frameCount, frameSize, isOut, clientInServer), mAvailToClient(0), mFlush(0), mDeferWake(false) { } status_t ServerProxy::obtainBuffer(Buffer* buffer) { LOG_ALWAYS_FATAL_IF(buffer == NULL || buffer->mFrameCount == 0); if (mIsShutdown) { buffer->mFrameCount = 0; buffer->mRaw = NULL; buffer->mNonContig = 0; mUnreleased = 0; return NO_INIT; goto no_init; } { audio_track_cblk_t* cblk = mCblk; // compute number of frames available to write (AudioTrack) or read (AudioRecord), // or use previous cached value from framesReady(), with added barrier if it omits. Loading Loading @@ -404,11 +404,7 @@ status_t ServerProxy::obtainBuffer(Buffer* buffer) mIsShutdown = true; } if (mIsShutdown) { buffer->mFrameCount = 0; buffer->mRaw = NULL; buffer->mNonContig = 0; mUnreleased = 0; return NO_INIT; goto no_init; } // don't allow filling pipe beyond the nominal size size_t availToServer; Loading Loading @@ -446,22 +442,26 @@ status_t ServerProxy::obtainBuffer(Buffer* buffer) mDeferWake = part1 < ask && availToServer >= ask; return part1 > 0 ? NO_ERROR : WOULD_BLOCK; } void ServerProxy::releaseBuffer(Buffer* buffer) { if (mIsShutdown) { no_init: buffer->mFrameCount = 0; buffer->mRaw = NULL; buffer->mNonContig = 0; return; mUnreleased = 0; return NO_INIT; } void ServerProxy::releaseBuffer(Buffer* buffer) { LOG_ALWAYS_FATAL_IF(buffer == NULL); size_t stepCount = buffer->mFrameCount; LOG_ALWAYS_FATAL_IF(stepCount > mUnreleased); if (stepCount == 0) { if (stepCount == 0 || mIsShutdown) { // prevent accidental re-use of buffer buffer->mFrameCount = 0; buffer->mRaw = NULL; buffer->mNonContig = 0; return; } LOG_ALWAYS_FATAL_IF(!(stepCount <= mUnreleased && mUnreleased <= mFrameCount)); mUnreleased -= stepCount; audio_track_cblk_t* cblk = mCblk; if (mIsOut) { Loading Loading @@ -639,8 +639,9 @@ status_t StaticAudioTrackServerProxy::obtainBuffer(Buffer* buffer) void StaticAudioTrackServerProxy::releaseBuffer(Buffer* buffer) { size_t stepCount = buffer->mFrameCount; LOG_ALWAYS_FATAL_IF(stepCount > mUnreleased); LOG_ALWAYS_FATAL_IF(!(stepCount <= mUnreleased)); if (stepCount == 0) { // prevent accidental re-use of buffer buffer->mRaw = NULL; buffer->mNonContig = 0; return; Loading