Loading include/private/media/AudioTrackShared.h +6 −0 Original line number Diff line number Diff line Loading @@ -522,6 +522,12 @@ public: mTimestampMutator.push(timestamp); } // Flushes the shared ring buffer if the client had requested it using mStreaming.mFlush. // If flush occurs then: // cblk->u.mStreaming.mFront, ServerProxy::mFlush and ServerProxy::mFlushed will be modified // client will be notified via Futex virtual void flushBufferIfNeeded(); // Total count of the number of flushed frames since creation (never reset). virtual int64_t framesFlushed() const { return mFlushed; } Loading media/libmedia/AudioTrackShared.cpp +51 −36 Original line number Diff line number Diff line Loading @@ -622,24 +622,20 @@ ServerProxy::ServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCo } __attribute__((no_sanitize("integer"))) status_t ServerProxy::obtainBuffer(Buffer* buffer, bool ackFlush) { LOG_ALWAYS_FATAL_IF(buffer == NULL || buffer->mFrameCount == 0); if (mIsShutdown) { goto no_init; } void ServerProxy::flushBufferIfNeeded() { 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. int32_t front; int32_t rear; // See notes on barriers at ClientProxy::obtainBuffer() if (mIsOut) { int32_t flush = cblk->u.mStreaming.mFlush; rear = android_atomic_acquire_load(&cblk->u.mStreaming.mRear); front = cblk->u.mStreaming.mFront; // The acquire_load is not really required. But since the write is a release_store in the // client, using acquire_load here makes it easier for people to maintain the code, // and the logic for communicating ipc variables seems somewhat standard, // and there really isn't much penalty for 4 or 8 byte atomics. int32_t flush = android_atomic_acquire_load(&cblk->u.mStreaming.mFlush); if (flush != mFlush) { ALOGV("ServerProxy::flushBufferIfNeeded() mStreaming.mFlush = 0x%x, mFlush = 0x%0x", flush, mFlush); int32_t rear = android_atomic_acquire_load(&cblk->u.mStreaming.mRear); int32_t front = cblk->u.mStreaming.mFront; // effectively obtain then release whatever is in the buffer const size_t overflowBit = mFrameCountP2 << 1; const size_t mask = overflowBit - 1; Loading Loading @@ -672,8 +668,27 @@ status_t ServerProxy::obtainBuffer(Buffer* buffer, bool ackFlush) } } mFlushed += (newFront - front) & mask; front = newFront; } } __attribute__((no_sanitize("integer"))) status_t ServerProxy::obtainBuffer(Buffer* buffer, bool ackFlush) { LOG_ALWAYS_FATAL_IF(buffer == NULL || buffer->mFrameCount == 0); if (mIsShutdown) { 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. int32_t front; int32_t rear; // See notes on barriers at ClientProxy::obtainBuffer() if (mIsOut) { flushBufferIfNeeded(); // might modify mFront rear = android_atomic_acquire_load(&cblk->u.mStreaming.mRear); front = cblk->u.mStreaming.mFront; } else { front = android_atomic_acquire_load(&cblk->u.mStreaming.mFront); rear = cblk->u.mStreaming.mRear; Loading services/audioflinger/Tracks.cpp +11 −0 Original line number Diff line number Diff line Loading @@ -777,6 +777,13 @@ void AudioFlinger::PlaybackThread::Track::flush() Mutex::Autolock _l(thread->mLock); PlaybackThread *playbackThread = (PlaybackThread *)thread.get(); // Flush the ring buffer now if the track is not active in the PlaybackThread. // Otherwise the flush would not be done until the track is resumed. // Requires FastTrack removal be BLOCK_UNTIL_ACKED if (playbackThread->mActiveTracks.indexOf(this) < 0) { (void)mServerProxy->flushBufferIfNeeded(); } if (isOffloaded()) { // If offloaded we allow flush during any state except terminated // and keep the track active to avoid problems if user is seeking Loading Loading @@ -828,6 +835,10 @@ void AudioFlinger::PlaybackThread::Track::flushAck() if (!isOffloaded() && !isDirect()) return; // Clear the client ring buffer so that the app can prime the buffer while paused. // Otherwise it might not get cleared until playback is resumed and obtainBuffer() is called. mServerProxy->flushBufferIfNeeded(); mFlushHwPending = false; } Loading Loading
include/private/media/AudioTrackShared.h +6 −0 Original line number Diff line number Diff line Loading @@ -522,6 +522,12 @@ public: mTimestampMutator.push(timestamp); } // Flushes the shared ring buffer if the client had requested it using mStreaming.mFlush. // If flush occurs then: // cblk->u.mStreaming.mFront, ServerProxy::mFlush and ServerProxy::mFlushed will be modified // client will be notified via Futex virtual void flushBufferIfNeeded(); // Total count of the number of flushed frames since creation (never reset). virtual int64_t framesFlushed() const { return mFlushed; } Loading
media/libmedia/AudioTrackShared.cpp +51 −36 Original line number Diff line number Diff line Loading @@ -622,24 +622,20 @@ ServerProxy::ServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCo } __attribute__((no_sanitize("integer"))) status_t ServerProxy::obtainBuffer(Buffer* buffer, bool ackFlush) { LOG_ALWAYS_FATAL_IF(buffer == NULL || buffer->mFrameCount == 0); if (mIsShutdown) { goto no_init; } void ServerProxy::flushBufferIfNeeded() { 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. int32_t front; int32_t rear; // See notes on barriers at ClientProxy::obtainBuffer() if (mIsOut) { int32_t flush = cblk->u.mStreaming.mFlush; rear = android_atomic_acquire_load(&cblk->u.mStreaming.mRear); front = cblk->u.mStreaming.mFront; // The acquire_load is not really required. But since the write is a release_store in the // client, using acquire_load here makes it easier for people to maintain the code, // and the logic for communicating ipc variables seems somewhat standard, // and there really isn't much penalty for 4 or 8 byte atomics. int32_t flush = android_atomic_acquire_load(&cblk->u.mStreaming.mFlush); if (flush != mFlush) { ALOGV("ServerProxy::flushBufferIfNeeded() mStreaming.mFlush = 0x%x, mFlush = 0x%0x", flush, mFlush); int32_t rear = android_atomic_acquire_load(&cblk->u.mStreaming.mRear); int32_t front = cblk->u.mStreaming.mFront; // effectively obtain then release whatever is in the buffer const size_t overflowBit = mFrameCountP2 << 1; const size_t mask = overflowBit - 1; Loading Loading @@ -672,8 +668,27 @@ status_t ServerProxy::obtainBuffer(Buffer* buffer, bool ackFlush) } } mFlushed += (newFront - front) & mask; front = newFront; } } __attribute__((no_sanitize("integer"))) status_t ServerProxy::obtainBuffer(Buffer* buffer, bool ackFlush) { LOG_ALWAYS_FATAL_IF(buffer == NULL || buffer->mFrameCount == 0); if (mIsShutdown) { 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. int32_t front; int32_t rear; // See notes on barriers at ClientProxy::obtainBuffer() if (mIsOut) { flushBufferIfNeeded(); // might modify mFront rear = android_atomic_acquire_load(&cblk->u.mStreaming.mRear); front = cblk->u.mStreaming.mFront; } else { front = android_atomic_acquire_load(&cblk->u.mStreaming.mFront); rear = cblk->u.mStreaming.mRear; Loading
services/audioflinger/Tracks.cpp +11 −0 Original line number Diff line number Diff line Loading @@ -777,6 +777,13 @@ void AudioFlinger::PlaybackThread::Track::flush() Mutex::Autolock _l(thread->mLock); PlaybackThread *playbackThread = (PlaybackThread *)thread.get(); // Flush the ring buffer now if the track is not active in the PlaybackThread. // Otherwise the flush would not be done until the track is resumed. // Requires FastTrack removal be BLOCK_UNTIL_ACKED if (playbackThread->mActiveTracks.indexOf(this) < 0) { (void)mServerProxy->flushBufferIfNeeded(); } if (isOffloaded()) { // If offloaded we allow flush during any state except terminated // and keep the track active to avoid problems if user is seeking Loading Loading @@ -828,6 +835,10 @@ void AudioFlinger::PlaybackThread::Track::flushAck() if (!isOffloaded() && !isDirect()) return; // Clear the client ring buffer so that the app can prime the buffer while paused. // Otherwise it might not get cleared until playback is resumed and obtainBuffer() is called. mServerProxy->flushBufferIfNeeded(); mFlushHwPending = false; } Loading