Merge "audiohal: Support stateful downmixer effects" into oc-dev
diff --git a/media/libaudiohal/EffectBufferHalHidl.cpp b/media/libaudiohal/EffectBufferHalHidl.cpp
index d6a41a2..ef4097a 100644
--- a/media/libaudiohal/EffectBufferHalHidl.cpp
+++ b/media/libaudiohal/EffectBufferHalHidl.cpp
@@ -56,7 +56,8 @@
 }
 
 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::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) {
diff --git a/media/libaudiohal/EffectBufferHalHidl.h b/media/libaudiohal/EffectBufferHalHidl.h
index 6e9fd0b..66a81c2 100644
--- a/media/libaudiohal/EffectBufferHalHidl.h
+++ b/media/libaudiohal/EffectBufferHalHidl.h
@@ -37,6 +37,7 @@
 
     virtual void setExternalData(void* external);
     virtual void setFrameCount(size_t frameCount);
+    virtual bool checkFrameCountChange();
 
     virtual void update();
     virtual void commit();
@@ -51,6 +52,7 @@
     static uint64_t makeUniqueId();
 
     const size_t mBufferSize;
+    bool mFrameCountChanged;
     void* mExternalData;
     AudioBuffer mHidlBuffer;
     sp<IMemory> mMemory;
diff --git a/media/libaudiohal/EffectBufferHalLocal.cpp b/media/libaudiohal/EffectBufferHalLocal.cpp
index 9fe2c7b..7951c8e 100644
--- a/media/libaudiohal/EffectBufferHalLocal.cpp
+++ b/media/libaudiohal/EffectBufferHalLocal.cpp
@@ -39,13 +39,13 @@
 
 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::setFrameCount(size_t frameCount) {
     mAudioBuffer.frameCount = frameCount;
+    mFrameCountChanged = true;
 }
 
 void EffectBufferHalLocal::setExternalData(void* external) {
@@ -69,6 +70,12 @@
     mAudioBuffer.raw = external;
 }
 
+bool EffectBufferHalLocal::checkFrameCountChange() {
+    bool result = mFrameCountChanged;
+    mFrameCountChanged = false;
+    return result;
+}
+
 void EffectBufferHalLocal::update() {
 }
 
diff --git a/media/libaudiohal/EffectBufferHalLocal.h b/media/libaudiohal/EffectBufferHalLocal.h
index 202d878..d2b624b 100644
--- a/media/libaudiohal/EffectBufferHalLocal.h
+++ b/media/libaudiohal/EffectBufferHalLocal.h
@@ -32,6 +32,7 @@
 
     virtual void setExternalData(void* external);
     virtual void setFrameCount(size_t frameCount);
+    virtual bool checkFrameCountChange();
 
     virtual void update();
     virtual void commit();
@@ -43,6 +44,7 @@
 
     std::unique_ptr<uint8_t[]> mOwnBuffer;
     const size_t mBufferSize;
+    bool mFrameCountChanged;
     audio_buffer_t mAudioBuffer;
 
     // Can not be constructed directly by clients.
diff --git a/media/libaudiohal/EffectHalHidl.cpp b/media/libaudiohal/EffectHalHidl.cpp
index 0babfda..7d61443 100644
--- a/media/libaudiohal/EffectHalHidl.cpp
+++ b/media/libaudiohal/EffectHalHidl.cpp
@@ -168,13 +168,20 @@
     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.
diff --git a/media/libaudiohal/EffectHalHidl.h b/media/libaudiohal/EffectHalHidl.h
index c8db36f..0d011aa 100644
--- a/media/libaudiohal/EffectHalHidl.h
+++ b/media/libaudiohal/EffectHalHidl.h
@@ -92,6 +92,7 @@
 
     status_t getConfigImpl(uint32_t cmdCode, uint32_t *replySize, void *pReplyData);
     status_t prepareForProcessing();
+    bool needToResetBuffers();
     status_t processImpl(uint32_t mqFlag);
     status_t setConfigImpl(
             uint32_t cmdCode, uint32_t cmdSize, void *pCmdData,
diff --git a/media/libaudiohal/include/EffectBufferHalInterface.h b/media/libaudiohal/include/EffectBufferHalInterface.h
index 6fa7940..e862f6e 100644
--- a/media/libaudiohal/include/EffectBufferHalInterface.h
+++ b/media/libaudiohal/include/EffectBufferHalInterface.h
@@ -39,6 +39,8 @@
 
     virtual void setExternalData(void* external) = 0;
     virtual void setFrameCount(size_t frameCount) = 0;
+    virtual bool checkFrameCountChange() = 0;  // returns whether frame count has been updated
+                                               // since the last call to this method
 
     virtual void update() = 0;  // copies data from the external buffer, noop for allocated buffers
     virtual void commit() = 0;  // copies data to the external buffer, noop for allocated buffers