Merge "aaudio: cleanup FIFO"

gugelfrei
Phil Burk 6 years ago committed by Android (Google) Code Review
commit ddc47d47a9

@ -196,7 +196,7 @@ int32_t AudioEndpoint::getEmptyFramesAvailable(WrappingBuffer *wrappingBuffer) {
int32_t AudioEndpoint::getEmptyFramesAvailable()
{
return mDataQueue->getFifoControllerBase()->getEmptyFramesAvailable();
return mDataQueue->getEmptyFramesAvailable();
}
int32_t AudioEndpoint::getFullFramesAvailable(WrappingBuffer *wrappingBuffer)
@ -206,15 +206,15 @@ int32_t AudioEndpoint::getFullFramesAvailable(WrappingBuffer *wrappingBuffer)
int32_t AudioEndpoint::getFullFramesAvailable()
{
return mDataQueue->getFifoControllerBase()->getFullFramesAvailable();
return mDataQueue->getFullFramesAvailable();
}
void AudioEndpoint::advanceWriteIndex(int32_t deltaFrames) {
mDataQueue->getFifoControllerBase()->advanceWriteIndex(deltaFrames);
mDataQueue->advanceWriteIndex(deltaFrames);
}
void AudioEndpoint::advanceReadIndex(int32_t deltaFrames) {
mDataQueue->getFifoControllerBase()->advanceReadIndex(deltaFrames);
mDataQueue->advanceReadIndex(deltaFrames);
}
void AudioEndpoint::setDataReadCounter(fifo_counter_t framesRead)

@ -23,30 +23,26 @@
#include <utils/Log.h>
#include <algorithm>
#include <memory>
#include "FifoControllerBase.h"
#include "FifoController.h"
#include "FifoControllerIndirect.h"
#include "FifoBuffer.h"
using namespace android; // TODO just import names needed
using android::FifoBuffer;
using android::fifo_frames_t;
FifoBuffer::FifoBuffer(int32_t bytesPerFrame, fifo_frames_t capacityInFrames)
: mFrameCapacity(capacityInFrames)
, mBytesPerFrame(bytesPerFrame)
, mStorage(nullptr)
, mFramesReadCount(0)
, mFramesUnderrunCount(0)
, mUnderrunCount(0)
: mBytesPerFrame(bytesPerFrame)
{
// TODO Handle possible failures to allocate. Move out of constructor?
mFifo = new FifoController(capacityInFrames, capacityInFrames);
mFifo = std::make_unique<FifoController>(capacityInFrames, capacityInFrames);
// allocate buffer
int32_t bytesPerBuffer = bytesPerFrame * capacityInFrames;
mStorage = new uint8_t[bytesPerBuffer];
mStorageOwned = true;
ALOGV("capacityInFrames = %d, bytesPerFrame = %d",
capacityInFrames, bytesPerFrame);
ALOGV("%s() capacityInFrames = %d, bytesPerFrame = %d",
__func__, capacityInFrames, bytesPerFrame);
}
FifoBuffer::FifoBuffer( int32_t bytesPerFrame,
@ -55,14 +51,10 @@ FifoBuffer::FifoBuffer( int32_t bytesPerFrame,
fifo_counter_t * writeIndexAddress,
void * dataStorageAddress
)
: mFrameCapacity(capacityInFrames)
, mBytesPerFrame(bytesPerFrame)
: mBytesPerFrame(bytesPerFrame)
, mStorage(static_cast<uint8_t *>(dataStorageAddress))
, mFramesReadCount(0)
, mFramesUnderrunCount(0)
, mUnderrunCount(0)
{
mFifo = new FifoControllerIndirect(capacityInFrames,
mFifo = std::make_unique<FifoControllerIndirect>(capacityInFrames,
capacityInFrames,
readIndexAddress,
writeIndexAddress);
@ -73,10 +65,8 @@ FifoBuffer::~FifoBuffer() {
if (mStorageOwned) {
delete[] mStorage;
}
delete mFifo;
}
int32_t FifoBuffer::convertFramesToBytes(fifo_frames_t frames) {
return frames * mBytesPerFrame;
}
@ -87,11 +77,12 @@ void FifoBuffer::fillWrappingBuffer(WrappingBuffer *wrappingBuffer,
wrappingBuffer->data[1] = nullptr;
wrappingBuffer->numFrames[1] = 0;
if (framesAvailable > 0) {
fifo_frames_t capacity = mFifo->getCapacity();
uint8_t *source = &mStorage[convertFramesToBytes(startIndex)];
// Does the available data cross the end of the FIFO?
if ((startIndex + framesAvailable) > mFrameCapacity) {
if ((startIndex + framesAvailable) > capacity) {
wrappingBuffer->data[0] = source;
fifo_frames_t firstFrames = mFrameCapacity - startIndex;
fifo_frames_t firstFrames = capacity - startIndex;
wrappingBuffer->numFrames[0] = firstFrames;
wrappingBuffer->data[1] = &mStorage[0];
wrappingBuffer->numFrames[1] = framesAvailable - firstFrames;
@ -107,7 +98,8 @@ void FifoBuffer::fillWrappingBuffer(WrappingBuffer *wrappingBuffer,
fifo_frames_t FifoBuffer::getFullDataAvailable(WrappingBuffer *wrappingBuffer) {
// The FIFO might be overfull so clip to capacity.
fifo_frames_t framesAvailable = std::min(mFifo->getFullFramesAvailable(), mFrameCapacity);
fifo_frames_t framesAvailable = std::min(mFifo->getFullFramesAvailable(),
mFifo->getCapacity());
fifo_frames_t startIndex = mFifo->getReadIndex();
fillWrappingBuffer(wrappingBuffer, framesAvailable, startIndex);
return framesAvailable;
@ -115,7 +107,8 @@ fifo_frames_t FifoBuffer::getFullDataAvailable(WrappingBuffer *wrappingBuffer) {
fifo_frames_t FifoBuffer::getEmptyRoomAvailable(WrappingBuffer *wrappingBuffer) {
// The FIFO might have underrun so clip to capacity.
fifo_frames_t framesAvailable = std::min(mFifo->getEmptyFramesAvailable(), mFrameCapacity);
fifo_frames_t framesAvailable = std::min(mFifo->getEmptyFramesAvailable(),
mFifo->getCapacity());
fifo_frames_t startIndex = mFifo->getWriteIndex();
fillWrappingBuffer(wrappingBuffer, framesAvailable, startIndex);
return framesAvailable;
@ -183,23 +176,6 @@ fifo_frames_t FifoBuffer::write(const void *buffer, fifo_frames_t numFrames) {
return framesWritten;
}
fifo_frames_t FifoBuffer::readNow(void *buffer, fifo_frames_t numFrames) {
mLastReadSize = numFrames;
fifo_frames_t framesLeft = numFrames;
fifo_frames_t framesRead = read(buffer, numFrames);
framesLeft -= framesRead;
mFramesReadCount += framesRead;
mFramesUnderrunCount += framesLeft;
// Zero out any samples we could not set.
if (framesLeft > 0) {
mUnderrunCount++;
int32_t bytesToZero = convertFramesToBytes(framesLeft);
memset(buffer, 0, bytesToZero);
}
return framesRead;
}
fifo_frames_t FifoBuffer::getThreshold() {
return mFifo->getThreshold();
}

@ -17,6 +17,7 @@
#ifndef FIFO_FIFO_BUFFER_H
#define FIFO_FIFO_BUFFER_H
#include <memory>
#include <stdint.h>
#include "FifoControllerBase.h"
@ -77,24 +78,12 @@ public:
*/
fifo_frames_t 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);
int32_t getUnderrunCount() const { return mUnderrunCount; }
FifoControllerBase *getFifoControllerBase() { return mFifo; }
int32_t getBytesPerFrame() {
return mBytesPerFrame;
}
// Proxy methods for the internal FifoController
fifo_counter_t getReadCounter() {
return mFifo->getReadCounter();
}
@ -111,6 +100,22 @@ public:
mFifo->setWriteCounter(n);
}
void advanceReadIndex(fifo_frames_t numFrames) {
mFifo->advanceReadIndex(numFrames);
}
void advanceWriteIndex(fifo_frames_t numFrames) {
mFifo->advanceWriteIndex(numFrames);
}
fifo_frames_t getEmptyFramesAvailable() {
return mFifo->getEmptyFramesAvailable();
}
fifo_frames_t getFullFramesAvailable() {
return mFifo->getFullFramesAvailable();
}
/*
* This is generally only called before or after the buffer is used.
*/
@ -121,15 +126,12 @@ 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?
FifoControllerBase *mFifo;
fifo_counter_t mFramesReadCount;
fifo_counter_t mFramesUnderrunCount;
int32_t mUnderrunCount; // need? just use frames
int32_t mLastReadSize;
const int32_t mBytesPerFrame;
// We do not use a std::unique_ptr for mStorage because it is often a pointer to
// memory shared between processes and cannot be deleted trivially.
uint8_t *mStorage = nullptr;
bool mStorageOwned = false; // did this object allocate the storage?
std::unique_ptr<FifoControllerBase> mFifo{};
};
} // android

@ -30,7 +30,7 @@ namespace android {
class FifoController : public FifoControllerBase
{
public:
FifoController(fifo_counter_t bufferSize, fifo_counter_t threshold)
FifoController(fifo_frames_t bufferSize, fifo_frames_t threshold)
: FifoControllerBase(bufferSize, threshold)
, mReadCounter(0)
, mWriteCounter(0)

@ -96,14 +96,14 @@ public:
void checkWrappingBuffer() {
WrappingBuffer wrappingBuffer;
fifo_frames_t framesAvailable =
mFifoBuffer.getFifoControllerBase()->getEmptyFramesAvailable();
mFifoBuffer.getEmptyFramesAvailable();
fifo_frames_t wrapAvailable = mFifoBuffer.getEmptyRoomAvailable(&wrappingBuffer);
EXPECT_EQ(framesAvailable, wrapAvailable);
fifo_frames_t bothAvailable = wrappingBuffer.numFrames[0] + wrappingBuffer.numFrames[1];
EXPECT_EQ(framesAvailable, bothAvailable);
framesAvailable =
mFifoBuffer.getFifoControllerBase()->getFullFramesAvailable();
mFifoBuffer.getFullFramesAvailable();
wrapAvailable = mFifoBuffer.getFullDataAvailable(&wrappingBuffer);
EXPECT_EQ(framesAvailable, wrapAvailable);
bothAvailable = wrappingBuffer.numFrames[0] + wrappingBuffer.numFrames[1];
@ -113,7 +113,7 @@ public:
// Write data but do not overflow.
void writeData(fifo_frames_t numFrames) {
fifo_frames_t framesAvailable =
mFifoBuffer.getFifoControllerBase()->getEmptyFramesAvailable();
mFifoBuffer.getEmptyFramesAvailable();
fifo_frames_t framesToWrite = std::min(framesAvailable, numFrames);
for (int i = 0; i < framesToWrite; i++) {
mData[i] = mNextWriteIndex++;
@ -125,7 +125,7 @@ public:
// Read data but do not underflow.
void verifyData(fifo_frames_t numFrames) {
fifo_frames_t framesAvailable =
mFifoBuffer.getFifoControllerBase()->getFullFramesAvailable();
mFifoBuffer.getFullFramesAvailable();
fifo_frames_t framesToRead = std::min(framesAvailable, numFrames);
fifo_frames_t actual = mFifoBuffer.read(mData, framesToRead);
ASSERT_EQ(framesToRead, actual);
@ -178,12 +178,12 @@ public:
void checkRandomWriteRead() {
for (int i = 0; i < 20; i++) {
fifo_frames_t framesEmpty =
mFifoBuffer.getFifoControllerBase()->getEmptyFramesAvailable();
mFifoBuffer.getEmptyFramesAvailable();
fifo_frames_t numFrames = (fifo_frames_t)(drand48() * framesEmpty);
writeData(numFrames);
fifo_frames_t framesFull =
mFifoBuffer.getFifoControllerBase()->getFullFramesAvailable();
mFifoBuffer.getFullFramesAvailable();
numFrames = (fifo_frames_t)(drand48() * framesFull);
verifyData(numFrames);
}

@ -99,7 +99,7 @@ int32_t AAudioMixer::mix(int streamIndex, FifoBuffer *fifo, bool allowUnderflow)
}
partIndex++;
}
fifo->getFifoControllerBase()->advanceReadIndex(framesDesired);
fifo->advanceReadIndex(framesDesired);
#if AAUDIO_MIXER_ATRACE_ENABLED
ATRACE_END();

@ -102,7 +102,7 @@ void *AAudioServiceEndpointCapture::callbackLoop() {
streamShared->setTimestampPositionOffset(positionOffset);
// Is the buffer too full to write a burst?
if (fifo->getFifoControllerBase()->getEmptyFramesAvailable() <
if (fifo->getEmptyFramesAvailable() <
getFramesPerBurst()) {
streamShared->incrementXRunCount();
} else {

Loading…
Cancel
Save