NBAIO: re-implement NBAIO Pipe and MonoPipe using fifo
Also removed const from NBAIO_Sink::availableToWrite() because
at least one implementation can no longer implement the const-ness.
Test: normal mixer, tee sink, and remote submix still work
Change-Id: I8461177efdf53bba8295b147e97835b018804903
diff --git a/include/media/nbaio/AudioStreamOutSink.h b/include/media/nbaio/AudioStreamOutSink.h
index 56052a6..56a2a38 100644
--- a/include/media/nbaio/AudioStreamOutSink.h
+++ b/include/media/nbaio/AudioStreamOutSink.h
@@ -44,7 +44,7 @@
// This is an over-estimate, and could dupe the caller into making a blocking write()
// FIXME Use an audio HAL API to query the buffer emptying status when it's available.
- virtual ssize_t availableToWrite() const { return mStreamBufferSizeBytes / mFrameSize; }
+ virtual ssize_t availableToWrite() { return mStreamBufferSizeBytes / mFrameSize; }
virtual ssize_t write(const void *buffer, size_t count);
diff --git a/include/media/nbaio/LibsndfileSink.h b/include/media/nbaio/LibsndfileSink.h
index f5d53d5..97a57e0 100644
--- a/include/media/nbaio/LibsndfileSink.h
+++ b/include/media/nbaio/LibsndfileSink.h
@@ -41,7 +41,7 @@
//virtual size_t framesWritten() const;
//virtual size_t framesUnderrun() const;
//virtual size_t underruns() const;
- //virtual ssize_t availableToWrite() const;
+ //virtual ssize_t availableToWrite();
virtual ssize_t write(const void *buffer, size_t count);
//virtual ssize_t writeVia(writeVia_t via, size_t total, void *user, size_t block);
diff --git a/include/media/nbaio/MonoPipe.h b/include/media/nbaio/MonoPipe.h
index d2cd218..60ae92e 100644
--- a/include/media/nbaio/MonoPipe.h
+++ b/include/media/nbaio/MonoPipe.h
@@ -18,8 +18,9 @@
#define ANDROID_AUDIO_MONO_PIPE_H
#include <time.h>
-#include "NBAIO.h"
+#include <audio_utils/fifo.h>
#include <media/SingleStateQueue.h>
+#include "NBAIO.h"
namespace android {
@@ -55,7 +56,10 @@
//virtual int64_t framesUnderrun() const;
//virtual int64_t underruns() const;
- virtual ssize_t availableToWrite() const;
+ // returns n where 0 <= n <= mMaxFrames, or a negative status_t
+ // including the private status codes in NBAIO.h
+ virtual ssize_t availableToWrite();
+
virtual ssize_t write(const void *buffer, size_t count);
//virtual ssize_t writeVia(writeVia_t via, size_t total, void *user, size_t block);
@@ -80,16 +84,10 @@
status_t getTimestamp(ExtendedTimestamp ×tamp);
private:
- const size_t mReqFrames; // as requested in constructor, unrounded
- const size_t mMaxFrames; // always a power of 2
+ const size_t mMaxFrames; // as requested in constructor, rounded up to a power of 2
void * const mBuffer;
- // mFront and mRear will never be separated by more than mMaxFrames.
- // 32-bit overflow is possible if the pipe is active for a long time, but if that happens it's
- // safe because we "&" with (mMaxFrames-1) at end of computations to calculate a buffer index.
- volatile int32_t mFront; // written by reader with android_atomic_release_store,
- // read by writer with android_atomic_acquire_load
- volatile int32_t mRear; // written by writer with android_atomic_release_store,
- // read by reader with android_atomic_acquire_load
+ audio_utils_fifo mFifo;
+ audio_utils_fifo_writer mFifoWriter;
bool mWriteTsValid; // whether mWriteTs is valid
struct timespec mWriteTs; // time that the previous write() completed
size_t mSetpoint; // target value for pipe fill depth
diff --git a/include/media/nbaio/MonoPipeReader.h b/include/media/nbaio/MonoPipeReader.h
index b3c891d..0776ecd 100644
--- a/include/media/nbaio/MonoPipeReader.h
+++ b/include/media/nbaio/MonoPipeReader.h
@@ -27,7 +27,7 @@
public:
// Construct a MonoPipeReader and associate it with a MonoPipe;
- // any data already in the pipe is visible to this PipeReader.
+ // any data already in the pipe is visible to this MonoPipeReader.
// There can be only a single MonoPipeReader per MonoPipe.
// FIXME make this constructor a factory method of MonoPipe.
MonoPipeReader(MonoPipe* pipe);
@@ -59,6 +59,7 @@
private:
MonoPipe * const mPipe;
+ audio_utils_fifo_reader mFifoReader;
};
} // namespace android
diff --git a/include/media/nbaio/NBAIO.h b/include/media/nbaio/NBAIO.h
index 3fd97ac..d8b7343 100644
--- a/include/media/nbaio/NBAIO.h
+++ b/include/media/nbaio/NBAIO.h
@@ -164,7 +164,12 @@
// UNDERRUN write() has not been called frequently enough, or with enough frames to keep up.
// An underrun event is counted, and the caller should re-try this operation.
// WOULD_BLOCK Determining how many frames can be written without blocking would itself block.
- virtual ssize_t availableToWrite() const { return SSIZE_MAX; }
+ virtual ssize_t availableToWrite() {
+ if (!mNegotiated) {
+ return NEGOTIATE;
+ }
+ return SSIZE_MAX;
+ }
// Transfer data to sink from single input buffer. Implies a copy.
// Inputs:
diff --git a/include/media/nbaio/Pipe.h b/include/media/nbaio/Pipe.h
index cc95ff7..58b9750 100644
--- a/include/media/nbaio/Pipe.h
+++ b/include/media/nbaio/Pipe.h
@@ -17,6 +17,7 @@
#ifndef ANDROID_AUDIO_PIPE_H
#define ANDROID_AUDIO_PIPE_H
+#include <audio_utils/fifo.h>
#include "NBAIO.h"
namespace android {
@@ -51,7 +52,7 @@
// The write side of a pipe permits overruns; flow control is the caller's responsibility.
// It doesn't return +infinity because that would guarantee an overrun.
- virtual ssize_t availableToWrite() const { return mMaxFrames; }
+ virtual ssize_t availableToWrite() { return mMaxFrames; }
virtual ssize_t write(const void *buffer, size_t count);
//virtual ssize_t writeVia(writeVia_t via, size_t total, void *user, size_t block);
@@ -59,7 +60,8 @@
private:
const size_t mMaxFrames; // always a power of 2
void * const mBuffer;
- volatile int32_t mRear; // written by android_atomic_release_store
+ audio_utils_fifo mFifo;
+ audio_utils_fifo_writer mFifoWriter;
volatile int32_t mReaders; // number of PipeReader clients currently attached to this Pipe
const bool mFreeBufferInDestructor;
};
diff --git a/include/media/nbaio/PipeReader.h b/include/media/nbaio/PipeReader.h
index 00c2b3c..70ecb34 100644
--- a/include/media/nbaio/PipeReader.h
+++ b/include/media/nbaio/PipeReader.h
@@ -57,7 +57,7 @@
private:
Pipe& mPipe;
- int32_t mFront; // follows behind mPipe.mRear
+ audio_utils_fifo_reader mFifoReader;
int64_t mFramesOverrun;
int64_t mOverruns;
};