AAudioService: integrated with audioserver
Call the MmapStreamInterface from AudioFlinger instead of the FakeHAL.
Fix sending timestamps from the thread.
Add shared mode in service.
Bug: 35260844
Bug: 33398120
Test: CTS test_aaudio.cpp
Change-Id: I44c7e4ecae4ce205611b6b73a72e0ae8a5b243e5
Signed-off-by: Phil Burk <philburk@google.com>
(cherry picked from commit 7f6b40d78b1976c78d1300e8a51fda36eeb50c5d)
diff --git a/media/libaaudio/src/fifo/FifoBuffer.cpp b/media/libaaudio/src/fifo/FifoBuffer.cpp
index c5489f1..857780c 100644
--- a/media/libaaudio/src/fifo/FifoBuffer.cpp
+++ b/media/libaaudio/src/fifo/FifoBuffer.cpp
@@ -17,6 +17,7 @@
#include <cstring>
#include <unistd.h>
+
#define LOG_TAG "FifoBuffer"
//#define LOG_NDEBUG 0
#include <utils/Log.h>
@@ -26,6 +27,8 @@
#include "FifoControllerIndirect.h"
#include "FifoBuffer.h"
+using namespace android; // TODO just import names needed
+
FifoBuffer::FifoBuffer(int32_t bytesPerFrame, fifo_frames_t capacityInFrames)
: mFrameCapacity(capacityInFrames)
, mBytesPerFrame(bytesPerFrame)
@@ -79,80 +82,102 @@
return frames * mBytesPerFrame;
}
-fifo_frames_t FifoBuffer::read(void *buffer, fifo_frames_t numFrames) {
- size_t numBytes;
- fifo_frames_t framesAvailable = mFifo->getFullFramesAvailable();
- fifo_frames_t framesToRead = numFrames;
- // Is there enough data in the FIFO
- if (framesToRead > framesAvailable) {
- framesToRead = framesAvailable;
- }
- if (framesToRead == 0) {
- return 0;
- }
+void FifoBuffer::fillWrappingBuffer(WrappingBuffer *wrappingBuffer,
+ int32_t framesAvailable,
+ int32_t startIndex) {
+ wrappingBuffer->data[1] = nullptr;
+ wrappingBuffer->numFrames[1] = 0;
+ if (framesAvailable > 0) {
- fifo_frames_t readIndex = mFifo->getReadIndex();
- uint8_t *destination = (uint8_t *) buffer;
- uint8_t *source = &mStorage[convertFramesToBytes(readIndex)];
- if ((readIndex + framesToRead) > mFrameCapacity) {
- // read in two parts, first part here
- fifo_frames_t frames1 = mFrameCapacity - readIndex;
- int32_t numBytes = convertFramesToBytes(frames1);
- memcpy(destination, source, numBytes);
- destination += numBytes;
- // read second part
- source = &mStorage[0];
- fifo_frames_t frames2 = framesToRead - frames1;
- numBytes = convertFramesToBytes(frames2);
- memcpy(destination, source, numBytes);
+ uint8_t *source = &mStorage[convertFramesToBytes(startIndex)];
+ // Does the available data cross the end of the FIFO?
+ if ((startIndex + framesAvailable) > mFrameCapacity) {
+ wrappingBuffer->data[0] = source;
+ wrappingBuffer->numFrames[0] = mFrameCapacity - startIndex;
+ wrappingBuffer->data[1] = &mStorage[0];
+ wrappingBuffer->numFrames[1] = mFrameCapacity - startIndex;
+
+ } else {
+ wrappingBuffer->data[0] = source;
+ wrappingBuffer->numFrames[0] = framesAvailable;
+ }
} else {
- // just read in one shot
- numBytes = convertFramesToBytes(framesToRead);
- memcpy(destination, source, numBytes);
+ wrappingBuffer->data[0] = nullptr;
+ wrappingBuffer->numFrames[0] = 0;
}
- mFifo->advanceReadIndex(framesToRead);
- return framesToRead;
}
-fifo_frames_t FifoBuffer::write(const void *buffer, fifo_frames_t framesToWrite) {
+void FifoBuffer::getFullDataAvailable(WrappingBuffer *wrappingBuffer) {
+ fifo_frames_t framesAvailable = mFifo->getFullFramesAvailable();
+ fifo_frames_t startIndex = mFifo->getReadIndex();
+ fillWrappingBuffer(wrappingBuffer, framesAvailable, startIndex);
+}
+
+void FifoBuffer::getEmptyRoomAvailable(WrappingBuffer *wrappingBuffer) {
fifo_frames_t framesAvailable = mFifo->getEmptyFramesAvailable();
-// ALOGD("FifoBuffer::write() framesToWrite = %d, framesAvailable = %d",
-// framesToWrite, framesAvailable);
- if (framesToWrite > framesAvailable) {
- framesToWrite = framesAvailable;
- }
- if (framesToWrite <= 0) {
- return 0;
- }
+ fifo_frames_t startIndex = mFifo->getWriteIndex();
+ fillWrappingBuffer(wrappingBuffer, framesAvailable, startIndex);
+}
- size_t numBytes;
- fifo_frames_t writeIndex = mFifo->getWriteIndex();
- int byteIndex = convertFramesToBytes(writeIndex);
- const uint8_t *source = (const uint8_t *) buffer;
- uint8_t *destination = &mStorage[byteIndex];
- if ((writeIndex + framesToWrite) > mFrameCapacity) {
- // write in two parts, first part here
- fifo_frames_t frames1 = mFrameCapacity - writeIndex;
- numBytes = convertFramesToBytes(frames1);
- memcpy(destination, source, numBytes);
-// ALOGD("FifoBuffer::write(%p to %p, numBytes = %d", source, destination, numBytes);
- // read second part
- source += convertFramesToBytes(frames1);
- destination = &mStorage[0];
- fifo_frames_t framesLeft = framesToWrite - frames1;
- numBytes = convertFramesToBytes(framesLeft);
-// ALOGD("FifoBuffer::write(%p to %p, numBytes = %d", source, destination, numBytes);
- memcpy(destination, source, numBytes);
- } else {
- // just write in one shot
- numBytes = convertFramesToBytes(framesToWrite);
-// ALOGD("FifoBuffer::write(%p to %p, numBytes = %d", source, destination, numBytes);
- memcpy(destination, source, numBytes);
- }
- mFifo->advanceWriteIndex(framesToWrite);
+fifo_frames_t FifoBuffer::read(void *buffer, fifo_frames_t numFrames) {
+ WrappingBuffer wrappingBuffer;
+ uint8_t *destination = (uint8_t *) buffer;
+ fifo_frames_t framesLeft = numFrames;
- return framesToWrite;
+ getFullDataAvailable(&wrappingBuffer);
+
+ // Read data in one or two parts.
+ int partIndex = 0;
+ while (framesLeft > 0 && partIndex < WrappingBuffer::SIZE) {
+ fifo_frames_t framesToRead = framesLeft;
+ fifo_frames_t framesAvailable = wrappingBuffer.numFrames[partIndex];
+ //ALOGD("FifoProcessor::read() framesAvailable = %d, partIndex = %d",
+ // framesAvailable, partIndex);
+ if (framesAvailable > 0) {
+ if (framesToRead > framesAvailable) {
+ framesToRead = framesAvailable;
+ }
+ int32_t numBytes = convertFramesToBytes(framesToRead);
+ memcpy(destination, wrappingBuffer.data[partIndex], numBytes);
+
+ destination += numBytes;
+ framesLeft -= framesToRead;
+ }
+ partIndex++;
+ }
+ fifo_frames_t framesRead = numFrames - framesLeft;
+ mFifo->advanceReadIndex(framesRead);
+ return framesRead;
+}
+
+fifo_frames_t FifoBuffer::write(const void *buffer, fifo_frames_t numFrames) {
+ WrappingBuffer wrappingBuffer;
+ uint8_t *source = (uint8_t *) buffer;
+ fifo_frames_t framesLeft = numFrames;
+
+ getEmptyRoomAvailable(&wrappingBuffer);
+
+ // Read data in one or two parts.
+ int partIndex = 0;
+ while (framesLeft > 0 && partIndex < WrappingBuffer::SIZE) {
+ fifo_frames_t framesToWrite = framesLeft;
+ fifo_frames_t framesAvailable = wrappingBuffer.numFrames[partIndex];
+ if (framesAvailable > 0) {
+ if (framesToWrite > framesAvailable) {
+ framesToWrite = framesAvailable;
+ }
+ int32_t numBytes = convertFramesToBytes(framesToWrite);
+ memcpy(wrappingBuffer.data[partIndex], source, numBytes);
+
+ source += numBytes;
+ framesLeft -= framesToWrite;
+ }
+ partIndex++;
+ }
+ fifo_frames_t framesWritten = numFrames - framesLeft;
+ mFifo->advanceWriteIndex(framesWritten);
+ return framesWritten;
}
fifo_frames_t FifoBuffer::readNow(void *buffer, fifo_frames_t numFrames) {
diff --git a/media/libaaudio/src/fifo/FifoBuffer.h b/media/libaaudio/src/fifo/FifoBuffer.h
index faa9ae2..2b262a1 100644
--- a/media/libaaudio/src/fifo/FifoBuffer.h
+++ b/media/libaaudio/src/fifo/FifoBuffer.h
@@ -21,15 +21,29 @@
#include "FifoControllerBase.h"
+namespace android {
+
+/**
+ * Structure that represents a region in a circular buffer that might be at the
+ * end of the array and split in two.
+ */
+struct WrappingBuffer {
+ enum {
+ SIZE = 2
+ };
+ void *data[SIZE];
+ int32_t numFrames[SIZE];
+};
+
class FifoBuffer {
public:
FifoBuffer(int32_t bytesPerFrame, fifo_frames_t capacityInFrames);
- FifoBuffer(int32_t bytesPerFrame,
- fifo_frames_t capacityInFrames,
- fifo_counter_t * readCounterAddress,
- fifo_counter_t * writeCounterAddress,
- void * dataStorageAddress);
+ FifoBuffer(int32_t bytesPerFrame,
+ fifo_frames_t capacityInFrames,
+ fifo_counter_t *readCounterAddress,
+ fifo_counter_t *writeCounterAddress,
+ void *dataStorageAddress);
~FifoBuffer();
@@ -40,10 +54,33 @@
fifo_frames_t write(const void *source, fifo_frames_t framesToWrite);
fifo_frames_t getThreshold();
+
void setThreshold(fifo_frames_t threshold);
fifo_frames_t getBufferCapacityInFrames();
+ /**
+ * Return pointer to available full frames in data1 and set size in numFrames1.
+ * if the data is split across the end of the FIFO then set data2 and numFrames2.
+ * Other wise set them to null
+ * @param wrappingBuffer
+ */
+ void getFullDataAvailable(WrappingBuffer *wrappingBuffer);
+
+ /**
+ * Return pointer to available empty frames in data1 and set size in numFrames1.
+ * if the room is split across the end of the FIFO then set data2 and numFrames2.
+ * Other wise set them to null
+ * @param wrappingBuffer
+ */
+ void getEmptyRoomAvailable(WrappingBuffer *wrappingBuffer);
+
+ /**
+ * Copy data from the FIFO into the buffer.
+ * @param buffer
+ * @param numFrames
+ * @return
+ */
fifo_frames_t readNow(void *buffer, fifo_frames_t numFrames);
int64_t getNextReadTime(int32_t frameRate);
@@ -73,15 +110,21 @@
}
private:
+
+ void fillWrappingBuffer(WrappingBuffer *wrappingBuffer,
+ int32_t framesAvailable, int32_t startIndex);
+
const fifo_frames_t mFrameCapacity;
- const int32_t mBytesPerFrame;
- uint8_t * mStorage;
- bool mStorageOwned; // did this object allocate the storage?
+ const int32_t mBytesPerFrame;
+ uint8_t *mStorage;
+ bool mStorageOwned; // did this object allocate the storage?
FifoControllerBase *mFifo;
- fifo_counter_t mFramesReadCount;
- fifo_counter_t mFramesUnderrunCount;
- int32_t mUnderrunCount; // need? just use frames
- int32_t mLastReadSize;
+ fifo_counter_t mFramesReadCount;
+ fifo_counter_t mFramesUnderrunCount;
+ int32_t mUnderrunCount; // need? just use frames
+ int32_t mLastReadSize;
};
+} // android
+
#endif //FIFO_FIFO_BUFFER_H
diff --git a/media/libaaudio/src/fifo/FifoController.h b/media/libaaudio/src/fifo/FifoController.h
index 7434634..79d98a1 100644
--- a/media/libaaudio/src/fifo/FifoController.h
+++ b/media/libaaudio/src/fifo/FifoController.h
@@ -22,6 +22,8 @@
#include "FifoControllerBase.h"
+namespace android {
+
/**
* A FIFO with counters contained in the class.
*/
@@ -55,5 +57,6 @@
std::atomic<fifo_counter_t> mWriteCounter;
};
+} // android
#endif //FIFO_FIFO_CONTROLLER_H
diff --git a/media/libaaudio/src/fifo/FifoControllerBase.cpp b/media/libaaudio/src/fifo/FifoControllerBase.cpp
index 33a253e..14a2be1 100644
--- a/media/libaaudio/src/fifo/FifoControllerBase.cpp
+++ b/media/libaaudio/src/fifo/FifoControllerBase.cpp
@@ -21,6 +21,8 @@
#include <stdint.h>
#include "FifoControllerBase.h"
+using namespace android; // TODO just import names needed
+
FifoControllerBase::FifoControllerBase(fifo_frames_t capacity, fifo_frames_t threshold)
: mCapacity(capacity)
, mThreshold(threshold)
diff --git a/media/libaaudio/src/fifo/FifoControllerBase.h b/media/libaaudio/src/fifo/FifoControllerBase.h
index c543519..64af777 100644
--- a/media/libaaudio/src/fifo/FifoControllerBase.h
+++ b/media/libaaudio/src/fifo/FifoControllerBase.h
@@ -19,6 +19,8 @@
#include <stdint.h>
+namespace android {
+
typedef int64_t fifo_counter_t;
typedef int32_t fifo_frames_t;
@@ -118,4 +120,6 @@
fifo_frames_t mThreshold;
};
+} // android
+
#endif // FIFO_FIFO_CONTROLLER_BASE_H
diff --git a/media/libaaudio/src/fifo/FifoControllerIndirect.h b/media/libaaudio/src/fifo/FifoControllerIndirect.h
index 1aaf9ea..5832d9c 100644
--- a/media/libaaudio/src/fifo/FifoControllerIndirect.h
+++ b/media/libaaudio/src/fifo/FifoControllerIndirect.h
@@ -22,6 +22,8 @@
#include "FifoControllerBase.h"
+namespace android {
+
/**
* A FifoControllerBase with counters external to the class.
*
@@ -66,4 +68,6 @@
std::atomic<fifo_counter_t> * mWriteCounterAddress;
};
+} // android
+
#endif //FIFO_FIFO_CONTROLLER_INDIRECT_H