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 &timestamp);
 
 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;
 };