aaudio: refactor references to shared FIFO
Reduce passing of raw pointers.
Use shared_ptrs and unique_ptrs.
Simplify memory management.
Refactor FifoBuffer into two subclasses so that
the internal memory management is simpler.
Bug: 151650670
Test: OboeTester "TEST OUTPUT"
Test: disable EXCLUSIVE mode
Test: OboeTester "ECHO INPUT TO OUTPUT"
Test: disable INPUT EXCLUSIVE mode
Change-Id: I10981767f8719f3cc3525df211285c53219a7979
diff --git a/services/oboeservice/AAudioServiceStreamShared.cpp b/services/oboeservice/AAudioServiceStreamShared.cpp
index f2cf016..e88a81e 100644
--- a/services/oboeservice/AAudioServiceStreamShared.cpp
+++ b/services/oboeservice/AAudioServiceStreamShared.cpp
@@ -59,12 +59,7 @@
result << AAudioServiceStreamBase::dump();
- auto fifo = mAudioDataQueue->getFifoBuffer();
- int32_t readCounter = fifo->getReadCounter();
- int32_t writeCounter = fifo->getWriteCounter();
- result << std::setw(10) << writeCounter;
- result << std::setw(10) << readCounter;
- result << std::setw(8) << (writeCounter - readCounter);
+ result << mAudioDataQueue->dump();
result << std::setw(8) << getXRunCount();
return result.str();
@@ -180,7 +175,7 @@
{
std::lock_guard<std::mutex> lock(mAudioDataQueueLock);
// Create audio data shared memory buffer for client.
- mAudioDataQueue = new SharedRingBuffer();
+ mAudioDataQueue = std::make_shared<SharedRingBuffer>();
result = mAudioDataQueue->allocate(calculateBytesPerFrame(), getBufferCapacity());
if (result != AAUDIO_OK) {
ALOGE("%s() could not allocate FIFO with %d frames",
@@ -203,18 +198,6 @@
return result;
}
-aaudio_result_t AAudioServiceStreamShared::close_l() {
- aaudio_result_t result = AAudioServiceStreamBase::close_l();
-
- {
- std::lock_guard<std::mutex> lock(mAudioDataQueueLock);
- delete mAudioDataQueue;
- mAudioDataQueue = nullptr;
- }
-
- return result;
-}
-
/**
* Get an immutable description of the data queue created by this service.
*/
@@ -273,3 +256,37 @@
*positionFrames = position;
return result;
}
+
+void AAudioServiceStreamShared::writeDataIfRoom(int64_t mmapFramesRead,
+ const void *buffer, int32_t numFrames) {
+ int64_t clientFramesWritten = 0;
+
+ // Lock the AudioFifo to protect against close.
+ std::lock_guard <std::mutex> lock(mAudioDataQueueLock);
+
+ if (mAudioDataQueue != nullptr) {
+ std::shared_ptr<FifoBuffer> fifo = mAudioDataQueue->getFifoBuffer();
+ // Determine offset between framePosition in client's stream
+ // vs the underlying MMAP stream.
+ clientFramesWritten = fifo->getWriteCounter();
+ // There are two indices that refer to the same frame.
+ int64_t positionOffset = mmapFramesRead - clientFramesWritten;
+ setTimestampPositionOffset(positionOffset);
+
+ // Is the buffer too full to write a burst?
+ if (fifo->getEmptyFramesAvailable() < getFramesPerBurst()) {
+ incrementXRunCount();
+ } else {
+ fifo->write(buffer, numFrames);
+ }
+ clientFramesWritten = fifo->getWriteCounter();
+ }
+
+ if (clientFramesWritten > 0) {
+ // This timestamp represents the completion of data being written into the
+ // client buffer. It is sent to the client and used in the timing model
+ // to decide when data will be available to read.
+ Timestamp timestamp(clientFramesWritten, AudioClock::getNanoseconds());
+ markTransferTime(timestamp);
+ }
+}