Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 758ba288 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Report data from aaudio mmap path to audio flinger." into udc-dev

parents d54905c0 fc791eef
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -155,6 +155,18 @@ class MmapStreamInterface : public virtual RefBase
     */
    virtual status_t standby() = 0;

    /**
     * Report when data being written to a playback buffer. Currently, this is used by mmap
     * playback thread for sound dose computation.
     *
     * \param[in] buffer a pointer to the audio data
     * \param[in] frameCount the number of frames written by the CPU
     * \return OK in case of success.
     *         NO_INIT in case of initialization error
     *         INVALID_OPERATION in case of wrong thread type
     */
    virtual status_t reportData(const void* buffer, size_t frameCount) = 0;

  protected:
    // Subclasses can not be constructed directly by clients.
    MmapStreamInterface() {}
+85 −27
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
//#define LOG_NDEBUG 0
#include <utils/Log.h>

#include <map>
#include <stdint.h>

#include <binder/Parcel.h>
@@ -37,8 +38,7 @@ AudioEndpointParcelable::AudioEndpointParcelable(Endpoint&& parcelable)
        : mUpMessageQueueParcelable(parcelable.upMessageQueueParcelable),
          mDownMessageQueueParcelable(parcelable.downMessageQueueParcelable),
          mUpDataQueueParcelable(parcelable.upDataQueueParcelable),
          mDownDataQueueParcelable(parcelable.downDataQueueParcelable),
          mNumSharedMemories(parcelable.sharedMemories.size()) {
          mDownDataQueueParcelable(parcelable.downDataQueueParcelable) {
    for (size_t i = 0; i < parcelable.sharedMemories.size() && i < MAX_SHARED_MEMORIES; ++i) {
        // Re-construct.
        mSharedMemories[i].~SharedMemoryParcelable();
@@ -52,15 +52,48 @@ AudioEndpointParcelable& AudioEndpointParcelable::operator=(Endpoint&& parcelabl
    return *this;
}

namespace {

void updateSharedMemoryIndex(SharedRegion* sharedRegion, int oldIndex, int newIndex) {
    if (sharedRegion->sharedMemoryIndex == oldIndex) {
        sharedRegion->sharedMemoryIndex = newIndex;
    }
}

void updateSharedMemoryIndex(RingBuffer* ringBuffer, int oldIndex, int newIndex) {
    updateSharedMemoryIndex(&ringBuffer->readCounterParcelable, oldIndex, newIndex);
    updateSharedMemoryIndex(&ringBuffer->writeCounterParcelable, oldIndex, newIndex);
    updateSharedMemoryIndex(&ringBuffer->dataParcelable, oldIndex, newIndex);
}

void updateSharedMemoryIndex(Endpoint* endpoint, int oldIndex, int newIndex) {
    updateSharedMemoryIndex(&endpoint->upMessageQueueParcelable, oldIndex, newIndex);
    updateSharedMemoryIndex(&endpoint->downMessageQueueParcelable, oldIndex, newIndex);
    updateSharedMemoryIndex(&endpoint->upDataQueueParcelable, oldIndex, newIndex);
    updateSharedMemoryIndex(&endpoint->downDataQueueParcelable, oldIndex, newIndex);
}

} // namespace

Endpoint AudioEndpointParcelable::parcelable()&& {
    Endpoint result;
    result.upMessageQueueParcelable = mUpMessageQueueParcelable.parcelable();
    result.downMessageQueueParcelable = mDownMessageQueueParcelable.parcelable();
    result.upDataQueueParcelable = mUpDataQueueParcelable.parcelable();
    result.downDataQueueParcelable = mDownDataQueueParcelable.parcelable();
    result.sharedMemories.reserve(std::min(mNumSharedMemories, MAX_SHARED_MEMORIES));
    for (size_t i = 0; i < mNumSharedMemories && i < MAX_SHARED_MEMORIES; ++i) {
    // To transfer through binder, only valid/in-use shared memory is allowed. By design, the
    // shared memories that are currently in-use may not be placed continuously from position 0.
    // However, when marshalling the shared memories into Endpoint, the shared memories will be
    // re-indexed from 0. In that case, when placing a shared memory, it is needed to update the
    // corresponding cached indexes.
    for (int i = 0; i < MAX_SHARED_MEMORIES; ++i) {
        if (mSharedMemories[i].isInUse()) {
            const int index = result.sharedMemories.size();
            result.sharedMemories.emplace_back(std::move(mSharedMemories[i]).parcelable());
            // Updating all the SharedRegion that is using `i` as shared memory index with the
            // new shared memory index as `result.sharedMemories.size() - 1`.
            updateSharedMemoryIndex(&result, i, index);
        }
    }
    return result;
}
@@ -71,28 +104,50 @@ Endpoint AudioEndpointParcelable::parcelable()&& {
 */
int32_t AudioEndpointParcelable::addFileDescriptor(const unique_fd& fd,
                                                   int32_t sizeInBytes) {
    if (mNumSharedMemories >= MAX_SHARED_MEMORIES) {
    const int32_t index = getNextAvailableSharedMemoryPosition();
    if (index < 0) {
        return AAUDIO_ERROR_OUT_OF_RANGE;
    }
    int32_t index = mNumSharedMemories++;
    mSharedMemories[index].setup(fd, sizeInBytes);
    return index;
}

void AudioEndpointParcelable::closeDataFileDescriptor() {
    const int32_t curDataMemoryIndex = mDownDataQueueParcelable.getSharedMemoryIndex();
    mSharedMemories[curDataMemoryIndex].closeAndReleaseFd();
    for (const int32_t memoryIndex : std::set{mDownDataQueueParcelable.getDataSharedMemoryIndex(),
                                mDownDataQueueParcelable.getReadCounterSharedMemoryIndex(),
                                mDownDataQueueParcelable.getWriteCounterSharedMemoryIndex()}) {
        mSharedMemories[memoryIndex].closeAndReleaseFd();
    }
}

void AudioEndpointParcelable::updateDataFileDescriptor(
aaudio_result_t AudioEndpointParcelable::updateDataFileDescriptor(
        AudioEndpointParcelable* endpointParcelable) {
    const int32_t curDataMemoryIndex = mDownDataQueueParcelable.getSharedMemoryIndex();
    const int32_t newDataMemoryIndex =
            endpointParcelable->mDownDataQueueParcelable.getSharedMemoryIndex();
    mSharedMemories[curDataMemoryIndex].close();
    mSharedMemories[curDataMemoryIndex].setup(
            endpointParcelable->mSharedMemories[newDataMemoryIndex]);
    mDownDataQueueParcelable.updateMemory(endpointParcelable->mDownDataQueueParcelable);
    // Before updating data file descriptor, close the old shared memories.
    closeDataFileDescriptor();
    // The given endpoint parcelable and this one are two different objects, the indexes in
    // `mSharedMemories` for `mDownDataQueueParcelable` can be different. In that case, an index
    // map, which maps from the index in given endpoint parcelable to the index in this endpoint
    // parcelable, is required when updating shared memory.
    std::map<int32_t, int32_t> memoryIndexMap;
    auto& downDataQueueParcelable = endpointParcelable->mDownDataQueueParcelable;
    for (const int32_t memoryIndex : {downDataQueueParcelable.getDataSharedMemoryIndex(),
                                      downDataQueueParcelable.getReadCounterSharedMemoryIndex(),
                                      downDataQueueParcelable.getWriteCounterSharedMemoryIndex()}) {
        if (memoryIndexMap.find(memoryIndex) != memoryIndexMap.end()) {
            // This shared memory has been set up in this endpoint parcelable.
            continue;
        }
        // Set up the memory in the next available shared memory position.
        const int index = getNextAvailableSharedMemoryPosition();
        if (index < 0) {
            return AAUDIO_ERROR_OUT_OF_RANGE;
        }
        mSharedMemories[index].setup(endpointParcelable->mSharedMemories[memoryIndex]);
        memoryIndexMap.emplace(memoryIndex, index);
    }
    mDownDataQueueParcelable.updateMemory(
            endpointParcelable->mDownDataQueueParcelable, memoryIndexMap);
    return AAUDIO_OK;
}

aaudio_result_t AudioEndpointParcelable::resolve(EndpointDescriptor *descriptor) {
@@ -114,27 +169,30 @@ aaudio_result_t AudioEndpointParcelable::resolveDataQueue(RingBufferDescriptor *

aaudio_result_t AudioEndpointParcelable::close() {
    int err = 0;
    for (int i = 0; i < mNumSharedMemories; i++) {
        int lastErr = mSharedMemories[i].close();
    for (auto& sharedMemory : mSharedMemories) {
        const int lastErr = sharedMemory.close();
        if (lastErr < 0) err = lastErr;
    }
    return AAudioConvert_androidToAAudioResult(err);
}

aaudio_result_t AudioEndpointParcelable::validate() const {
    if (mNumSharedMemories < 0 || mNumSharedMemories >= MAX_SHARED_MEMORIES) {
        ALOGE("invalid mNumSharedMemories = %d", mNumSharedMemories);
        return AAUDIO_ERROR_INTERNAL;
int32_t AudioEndpointParcelable::getNextAvailableSharedMemoryPosition() const {
    for (int i = 0; i < MAX_SHARED_MEMORIES; ++i) {
        if (!mSharedMemories[i].isInUse()) {
            return i;
        }
    return AAUDIO_OK;
    }
    return -1;
}

void AudioEndpointParcelable::dump() {
    ALOGD("======================================= BEGIN");
    ALOGD("mNumSharedMemories = %d", mNumSharedMemories);
    for (int i = 0; i < mNumSharedMemories; i++) {
    for (int i = 0; i < MAX_SHARED_MEMORIES; ++i) {
        if (mSharedMemories[i].isInUse()) {
            ALOGD("Shared memory index=%d", i);
            mSharedMemories[i].dump();
        }
    }
    ALOGD("mUpMessageQueueParcelable =========");
    mUpMessageQueueParcelable.dump();
    ALOGD("mDownMessageQueueParcelable =======");
+6 −3
Original line number Diff line number Diff line
@@ -61,8 +61,10 @@ public:
     * Update current data file descriptor with given endpoint parcelable.
     * @param endpointParcelable an endpoint parcelable that contains new data file
     *                           descriptor information
     * @return AAUDIO_OK if the data file descriptor updates successfully.
     *         AAUDIO_ERROR_OUT_OF_RANGE if there is not enough space for the shared memory.
     */
    void updateDataFileDescriptor(AudioEndpointParcelable* endpointParcelable);
    aaudio_result_t updateDataFileDescriptor(AudioEndpointParcelable* endpointParcelable);

    aaudio_result_t resolve(EndpointDescriptor *descriptor);
    aaudio_result_t resolveDataQueue(RingBufferDescriptor *descriptor);
@@ -84,9 +86,10 @@ public: // TODO add getters
    RingBufferParcelable    mDownDataQueueParcelable;    // eg. playback

private:
    aaudio_result_t         validate() const;
    // Return the first available shared memory position. Return -1 if all shared memories are
    // in use.
    int32_t getNextAvailableSharedMemoryPosition() const;

    int32_t                 mNumSharedMemories = 0;
    SharedMemoryParcelable  mSharedMemories[MAX_SHARED_MEMORIES];
};

+20 −14
Original line number Diff line number Diff line
@@ -33,7 +33,6 @@ RingBufferParcelable::RingBufferParcelable(const RingBuffer& parcelable)
        : mReadCounterParcelable(parcelable.readCounterParcelable),
          mWriteCounterParcelable(parcelable.writeCounterParcelable),
          mDataParcelable(parcelable.dataParcelable),
          mSharedMemoryIndex(parcelable.sharedMemoryIndex),
          mBytesPerFrame(parcelable.bytesPerFrame),
          mFramesPerBurst(parcelable.framesPerBurst),
          mCapacityInFrames(parcelable.capacityInFrames),
@@ -46,7 +45,6 @@ RingBuffer RingBufferParcelable::parcelable() const {
    result.readCounterParcelable = mReadCounterParcelable.parcelable();
    result.writeCounterParcelable = mWriteCounterParcelable.parcelable();
    result.dataParcelable = mDataParcelable.parcelable();
    result.sharedMemoryIndex = mSharedMemoryIndex;
    result.bytesPerFrame = mBytesPerFrame;
    result.framesPerBurst = mFramesPerBurst;
    result.capacityInFrames = mCapacityInFrames;
@@ -62,19 +60,26 @@ void RingBufferParcelable::setupMemory(int32_t sharedMemoryIndex,
                 int32_t readCounterOffset,
                 int32_t writeCounterOffset,
                 int32_t counterSizeBytes) {
    mSharedMemoryIndex = sharedMemoryIndex;
    mReadCounterParcelable.setup(sharedMemoryIndex, readCounterOffset, counterSizeBytes);
    mWriteCounterParcelable.setup(sharedMemoryIndex, writeCounterOffset, counterSizeBytes);
    mDataParcelable.setup(sharedMemoryIndex, dataMemoryOffset, dataSizeInBytes);
    mReadCounterParcelable.setup({sharedMemoryIndex, readCounterOffset, counterSizeBytes});
    mWriteCounterParcelable.setup({sharedMemoryIndex, writeCounterOffset, counterSizeBytes});
    mDataParcelable.setup({sharedMemoryIndex, dataMemoryOffset, dataSizeInBytes});
}

void RingBufferParcelable::setupMemory(int32_t sharedMemoryIndex,
                 int32_t dataMemoryOffset,
                 int32_t dataSizeInBytes) {
    mSharedMemoryIndex = sharedMemoryIndex;
    mReadCounterParcelable.setup(sharedMemoryIndex, 0, 0);
    mWriteCounterParcelable.setup(sharedMemoryIndex, 0, 0);
    mDataParcelable.setup(sharedMemoryIndex, dataMemoryOffset, dataSizeInBytes);
    mReadCounterParcelable.setup({sharedMemoryIndex, 0, 0});
    mWriteCounterParcelable.setup({sharedMemoryIndex, 0, 0});
    mDataParcelable.setup({sharedMemoryIndex, dataMemoryOffset, dataSizeInBytes});
}

void RingBufferParcelable::setupMemory(
        const SharedRegionParcelable::MemoryInfoTuple& dataMemoryInfo,
        const SharedRegionParcelable::MemoryInfoTuple& readCounterInfo,
        const SharedRegionParcelable::MemoryInfoTuple& writeCounterInfo) {
    mReadCounterParcelable.setup(readCounterInfo);
    mWriteCounterParcelable.setup(writeCounterInfo);
    mDataParcelable.setup(dataMemoryInfo);
}

int32_t RingBufferParcelable::getBytesPerFrame() const {
@@ -128,9 +133,11 @@ aaudio_result_t RingBufferParcelable::resolve(SharedMemoryParcelable *memoryParc
    return AAUDIO_OK;
}

void RingBufferParcelable::updateMemory(const RingBufferParcelable& parcelable) {
    setupMemory(mSharedMemoryIndex, 0,
                parcelable.getCapacityInFrames() * parcelable.getBytesPerFrame());
void RingBufferParcelable::updateMemory(const RingBufferParcelable& parcelable,
                                        const std::map<int32_t, int32_t>& memoryIndexMap) {
    setupMemory(parcelable.mDataParcelable.getMemoryInfo(&memoryIndexMap),
                parcelable.mReadCounterParcelable.getMemoryInfo(&memoryIndexMap),
                parcelable.mWriteCounterParcelable.getMemoryInfo(&memoryIndexMap));
    setBytesPerFrame(parcelable.getBytesPerFrame());
    setFramesPerBurst(parcelable.getFramesPerBurst());
    setCapacityInFrames(parcelable.getCapacityInFrames());
@@ -152,7 +159,6 @@ aaudio_result_t RingBufferParcelable::validate() const {
    return AAUDIO_OK;
}


void RingBufferParcelable::dump() {
    ALOGD("mCapacityInFrames = %d ---------", mCapacityInFrames);
    if (mCapacityInFrames > 0) {
+35 −5
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#ifndef ANDROID_AAUDIO_RINGBUFFER_PARCELABLE_H
#define ANDROID_AAUDIO_RINGBUFFER_PARCELABLE_H

#include <map>
#include <stdint.h>

#include <aaudio/RingBuffer.h>
@@ -46,6 +47,22 @@ public:
                     int32_t dataMemoryOffset,
                     int32_t dataSizeInBytes);

    /**
     * Set up memory for the RingBufferParcelable.
     *
     * This function will take three MemoryInfoTuple as parameters to set up memory. The
     * MemoryInfoTuple contains the shared memory index, offset in the shared memory and size
     * of the object. This will allow setting up the read counter, write counter and data memory
     * that are located in different shared memory blocks.
     *
     * @param dataMemoryInfo
     * @param readCounterInfo
     * @param writeCounterInfo
     */
    void setupMemory(const SharedRegionParcelable::MemoryInfoTuple& dataMemoryInfo,
                     const SharedRegionParcelable::MemoryInfoTuple& readCounterInfo,
                     const SharedRegionParcelable::MemoryInfoTuple& writeCounterInfo);

    int32_t getBytesPerFrame() const;

    void setBytesPerFrame(int32_t bytesPerFrame);
@@ -62,10 +79,24 @@ public:

    aaudio_result_t resolve(SharedMemoryParcelable *memoryParcels, RingBufferDescriptor *descriptor);

    void updateMemory(const RingBufferParcelable& parcelable);
    /**
     * Update this ring buffer with the given ring buffer.
     *
     * @param parcelable the ring buffer to be used to update this ring buffer.
     * @param memoryIndexMap a map from the shared memory indexes used by the given ring buffer
     *                       to the shared memory indexes used by this ring buffer.
     */
    void updateMemory(const RingBufferParcelable& parcelable,
                      const std::map<int32_t, int32_t>& memoryIndexMap);

    int32_t getSharedMemoryIndex() const {
        return mSharedMemoryIndex;
    int32_t getReadCounterSharedMemoryIndex() const {
        return mReadCounterParcelable.getSharedMemoryIndex();
    }
    int32_t getWriteCounterSharedMemoryIndex() const {
        return mWriteCounterParcelable.getSharedMemoryIndex();
    }
    int32_t getDataSharedMemoryIndex() const {
        return mDataParcelable.getSharedMemoryIndex();
    }

    void dump();
@@ -77,7 +108,6 @@ private:
    SharedRegionParcelable  mReadCounterParcelable;
    SharedRegionParcelable  mWriteCounterParcelable;
    SharedRegionParcelable  mDataParcelable;
    int32_t                 mSharedMemoryIndex = -1;
    int32_t                 mBytesPerFrame = 0;     // index is in frames
    int32_t                 mFramesPerBurst = 0;    // for ISOCHRONOUS queues
    int32_t                 mCapacityInFrames = 0;  // zero if unused
Loading