OSDN Git Service

Pull out base class that has no knowledge of frame size or buffer
authorGlenn Kasten <gkasten@google.com>
Fri, 17 Jun 2016 17:28:05 +0000 (10:28 -0700)
committerGlenn Kasten <gkasten@google.com>
Fri, 17 Jun 2016 18:03:58 +0000 (11:03 -0700)
Change-Id: I0727601faf9766c4ed2d08346f53257c20337fe7

audio_utils/fifo.cpp
audio_utils/include/audio_utils/fifo.h

index 827b441..92e0a9f 100644 (file)
 #include <cutils/log.h>
 #include <utils/Errors.h>
 
-audio_utils_fifo::audio_utils_fifo(uint32_t frameCount, uint32_t frameSize, void *buffer)
+audio_utils_fifo_base::audio_utils_fifo_base(uint32_t frameCount)
         __attribute__((no_sanitize("integer"))) :
     mFrameCount(frameCount), mFrameCountP2(roundup(frameCount)),
-    mFudgeFactor(mFrameCountP2 - mFrameCount), mFrameSize(frameSize), mBuffer(buffer),
+    mFudgeFactor(mFrameCountP2 - mFrameCount),
     mSharedRear(0), mThrottleFront(NULL)
 {
-    // maximum value of frameCount * frameSize is INT_MAX (2^31 - 1), not 2^31, because we need to
-    // be able to distinguish successful and error return values from read and write.
-    ALOG_ASSERT(frameCount > 0 && frameSize > 0 && buffer != NULL &&
-            frameCount <= ((uint32_t) INT_MAX) / frameSize);
+    // actual upper bound on frameCount will depend on the frame size
+    ALOG_ASSERT(frameCount > 0 && frameCount <= ((uint32_t) INT_MAX));
 }
 
-audio_utils_fifo::~audio_utils_fifo()
+audio_utils_fifo_base::~audio_utils_fifo_base()
 {
 }
 
-uint32_t audio_utils_fifo::sum(uint32_t index, uint32_t increment)
+uint32_t audio_utils_fifo_base::sum(uint32_t index, uint32_t increment)
         __attribute__((no_sanitize("integer")))
 {
     if (mFudgeFactor) {
@@ -58,7 +56,7 @@ uint32_t audio_utils_fifo::sum(uint32_t index, uint32_t increment)
     }
 }
 
-int32_t audio_utils_fifo::diff(uint32_t rear, uint32_t front, size_t *lost)
+int32_t audio_utils_fifo_base::diff(uint32_t rear, uint32_t front, size_t *lost)
         __attribute__((no_sanitize("integer")))
 {
     uint32_t diff = rear - front;
@@ -93,6 +91,22 @@ int32_t audio_utils_fifo::diff(uint32_t rear, uint32_t front, size_t *lost)
 
 ////////////////////////////////////////////////////////////////////////////////
 
+audio_utils_fifo::audio_utils_fifo(uint32_t frameCount, uint32_t frameSize, void *buffer)
+        __attribute__((no_sanitize("integer"))) :
+    audio_utils_fifo_base(frameCount), mFrameSize(frameSize), mBuffer(buffer)
+{
+    // maximum value of frameCount * frameSize is INT_MAX (2^31 - 1), not 2^31, because we need to
+    // be able to distinguish successful and error return values from read and write.
+    ALOG_ASSERT(frameCount > 0 && frameSize > 0 && buffer != NULL &&
+            frameCount <= ((uint32_t) INT_MAX) / frameSize);
+}
+
+audio_utils_fifo::~audio_utils_fifo()
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
 audio_utils_fifo_provider::audio_utils_fifo_provider() :
     mObtained(0)
 {
index b8b21c5..08dc3f9 100644 (file)
 #error C API is no longer supported
 #endif
 
-// Single writer, single reader non-blocking FIFO.
-// Writer and reader must be in same process.
-
-// No user-serviceable parts within.
-class audio_utils_fifo {
-
-    friend class audio_utils_fifo_reader;
-    friend class audio_utils_fifo_writer;
-
-public:
-
-/**
- * Construct a FIFO object.
- *
- *  \param frameCount  Max number of significant frames to be stored in the FIFO > 0.
- *                     If writes and reads always use the same count, and that count is a divisor of
- *                     frameCount, then the writes and reads will never do a partial transfer.
- *  \param frameSize   Size of each frame in bytes > 0, and frameSize * frameCount <= INT_MAX.
- *  \param buffer      Pointer to a caller-allocated buffer of frameCount frames.
- */
-    audio_utils_fifo(uint32_t frameCount, uint32_t frameSize, void *buffer);
+// Base class for single writer, single-reader or multi-reader non-blocking FIFO.
+// The base class manipulates frame indices only, and has no knowledge of frame sizes or the buffer.
 
-    ~audio_utils_fifo();
+class audio_utils_fifo_base {
 
-private:
+protected:
+    audio_utils_fifo_base(uint32_t frameCount);
+    virtual ~audio_utils_fifo_base();
 
 /** Return a new index as the sum of a validated index and a specified increment.
  *
@@ -75,8 +58,6 @@ private:
     const uint32_t mFudgeFactor;  // mFrameCountP2 - mFrameCount, the number of "wasted" frames
                                   // after the end of mBuffer.  Only the indices are wasted, not any
                                   // memory.
-    const uint32_t mFrameSize;    // size of each frame in bytes
-    void * const   mBuffer;       // pointer to caller-allocated buffer of size mFrameCount frames
 
     std::atomic_uint_fast32_t mSharedRear;  // accessed by both sides using atomic operations
 
@@ -85,6 +66,38 @@ private:
     std::atomic_uint_fast32_t *mThrottleFront;
 };
 
+////////////////////////////////////////////////////////////////////////////////
+
+// Same as above, but understands frame sizes and knows about the buffer but does not own it.
+// Writer and reader must be in same process.
+
+class audio_utils_fifo : audio_utils_fifo_base {
+
+    friend class audio_utils_fifo_reader;
+    friend class audio_utils_fifo_writer;
+
+public:
+
+/**
+ * Construct a FIFO object.
+ *
+ *  \param frameCount  Max number of significant frames to be stored in the FIFO > 0.
+ *                     If writes and reads always use the same count, and that count is a divisor of
+ *                     frameCount, then the writes and reads will never do a partial transfer.
+ *  \param frameSize   Size of each frame in bytes > 0, and frameSize * frameCount <= INT_MAX.
+ *  \param buffer      Pointer to a caller-allocated buffer of frameCount frames.
+ */
+    audio_utils_fifo(uint32_t frameCount, uint32_t frameSize, void *buffer);
+
+    virtual ~audio_utils_fifo();
+
+private:
+
+    // These fields are const after initialization
+    const uint32_t mFrameSize;    // size of each frame in bytes
+    void * const   mBuffer;       // pointer to caller-allocated buffer of size mFrameCount frames
+};
+
 // Describes one virtually contiguous fragment of a logically contiguous slice.
 // Compare to struct iovec for readv(2) and writev(2).
 struct audio_utils_iovec {
@@ -118,7 +131,7 @@ class audio_utils_fifo_writer : public audio_utils_fifo_provider {
 
 public:
     audio_utils_fifo_writer(audio_utils_fifo& fifo);
-    ~audio_utils_fifo_writer();
+    virtual ~audio_utils_fifo_writer();
 
 /**
  * Write to FIFO.
@@ -151,7 +164,7 @@ class audio_utils_fifo_reader : public audio_utils_fifo_provider {
 
 public:
     audio_utils_fifo_reader(audio_utils_fifo& fifo, bool throttlesWriter);
-    ~audio_utils_fifo_reader();
+    virtual ~audio_utils_fifo_reader();
 
 /** Read from FIFO.
  *