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

Commit 40be8a34 authored by Mikhail Naganov's avatar Mikhail Naganov
Browse files

audiohal: Support stateful downmixer effects

Fraunhofer's downmixer has additional buffering, this is incompatible
with how DownmixerBufferProvider used to process incomplete buffers.

Now the effects HIDL wrapper delivers frameCount updates in
audiobuffers to the server side. This fixes playback of multichannel
sound streams.

Bug: 36181621
Test: play 5.1 track from Play Music
Change-Id: I3b2cd097d61873c6ba329f1a574235ac88b21cac
parent 9ba03c88
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -56,7 +56,8 @@ status_t EffectBufferHalInterface::mirror(
}

EffectBufferHalHidl::EffectBufferHalHidl(size_t size)
        : mBufferSize(size), mExternalData(nullptr), mAudioBuffer{0, {nullptr}} {
        : mBufferSize(size), mFrameCountChanged(false),
          mExternalData(nullptr), mAudioBuffer{0, {nullptr}} {
    mHidlBuffer.id = makeUniqueId();
    mHidlBuffer.frameCount = 0;
}
@@ -107,6 +108,13 @@ void* EffectBufferHalHidl::externalData() const {
void EffectBufferHalHidl::setFrameCount(size_t frameCount) {
    mHidlBuffer.frameCount = frameCount;
    mAudioBuffer.frameCount = frameCount;
    mFrameCountChanged = true;
}

bool EffectBufferHalHidl::checkFrameCountChange() {
    bool result = mFrameCountChanged;
    mFrameCountChanged = false;
    return result;
}

void EffectBufferHalHidl::setExternalData(void* external) {
+2 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ class EffectBufferHalHidl : public EffectBufferHalInterface

    virtual void setExternalData(void* external);
    virtual void setFrameCount(size_t frameCount);
    virtual bool checkFrameCountChange();

    virtual void update();
    virtual void commit();
@@ -51,6 +52,7 @@ class EffectBufferHalHidl : public EffectBufferHalInterface
    static uint64_t makeUniqueId();

    const size_t mBufferSize;
    bool mFrameCountChanged;
    void* mExternalData;
    AudioBuffer mHidlBuffer;
    sp<IMemory> mMemory;
+9 −2
Original line number Diff line number Diff line
@@ -39,13 +39,13 @@ status_t EffectBufferHalInterface::mirror(

EffectBufferHalLocal::EffectBufferHalLocal(size_t size)
        : mOwnBuffer(new uint8_t[size]),
          mBufferSize(size),
          mBufferSize(size), mFrameCountChanged(false),
          mAudioBuffer{0, {mOwnBuffer.get()}} {
}

EffectBufferHalLocal::EffectBufferHalLocal(void* external, size_t size)
        : mOwnBuffer(nullptr),
          mBufferSize(size),
          mBufferSize(size), mFrameCountChanged(false),
          mAudioBuffer{0, {external}} {
}

@@ -62,6 +62,7 @@ void* EffectBufferHalLocal::externalData() const {

void EffectBufferHalLocal::setFrameCount(size_t frameCount) {
    mAudioBuffer.frameCount = frameCount;
    mFrameCountChanged = true;
}

void EffectBufferHalLocal::setExternalData(void* external) {
@@ -69,6 +70,12 @@ void EffectBufferHalLocal::setExternalData(void* external) {
    mAudioBuffer.raw = external;
}

bool EffectBufferHalLocal::checkFrameCountChange() {
    bool result = mFrameCountChanged;
    mFrameCountChanged = false;
    return result;
}

void EffectBufferHalLocal::update() {
}

+2 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ class EffectBufferHalLocal : public EffectBufferHalInterface

    virtual void setExternalData(void* external);
    virtual void setFrameCount(size_t frameCount);
    virtual bool checkFrameCountChange();

    virtual void update();
    virtual void commit();
@@ -43,6 +44,7 @@ class EffectBufferHalLocal : public EffectBufferHalInterface

    std::unique_ptr<uint8_t[]> mOwnBuffer;
    const size_t mBufferSize;
    bool mFrameCountChanged;
    audio_buffer_t mAudioBuffer;

    // Can not be constructed directly by clients.
+8 −1
Original line number Diff line number Diff line
@@ -168,13 +168,20 @@ status_t EffectHalHidl::prepareForProcessing() {
    return OK;
}

bool EffectHalHidl::needToResetBuffers() {
    if (mBuffersChanged) return true;
    bool inBufferFrameCountUpdated = mInBuffer->checkFrameCountChange();
    bool outBufferFrameCountUpdated = mOutBuffer->checkFrameCountChange();
    return inBufferFrameCountUpdated || outBufferFrameCountUpdated;
}

status_t EffectHalHidl::processImpl(uint32_t mqFlag) {
    if (mEffect == 0 || mInBuffer == 0 || mOutBuffer == 0) return NO_INIT;
    status_t status;
    if (!mStatusMQ && (status = prepareForProcessing()) != OK) {
        return status;
    }
    if (mBuffersChanged && (status = setProcessBuffers()) != OK) {
    if (needToResetBuffers() && (status = setProcessBuffers()) != OK) {
        return status;
    }
    // The data is already in the buffers, just need to flush it and wake up the server side.
Loading