AIDL effect: Add ashmem buffer implementation in libaudiohal
Also add TIME_CHECK and binder dump call implementation
Bug: 261129656
Test: enable AIDL
Test: atest
android.media.audio.cts.LoudnessEnhancerTest#test3_0MeasureGainChange
and check if data consumed by effect threads.
Change-Id: Ib2462bf47c7e9602d9eceed1bfb28d38b559fe65
diff --git a/media/libaudiohal/impl/EffectHalAidl.cpp b/media/libaudiohal/impl/EffectHalAidl.cpp
index 8fa301a..a684dee 100644
--- a/media/libaudiohal/impl/EffectHalAidl.cpp
+++ b/media/libaudiohal/impl/EffectHalAidl.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <cstddef>
#define LOG_TAG "EffectHalAidl"
//#define LOG_NDEBUG 0
@@ -136,24 +137,51 @@
}
status_t EffectHalAidl::setInBuffer(const sp<EffectBufferHalInterface>& buffer) {
- if (buffer == nullptr) {
- return BAD_VALUE;
- }
- ALOGW("%s not implemented yet", __func__);
+ mInBuffer = buffer;
return OK;
}
status_t EffectHalAidl::setOutBuffer(const sp<EffectBufferHalInterface>& buffer) {
- if (buffer == nullptr) {
- return BAD_VALUE;
- }
- ALOGW("%s not implemented yet", __func__);
+ mOutBuffer = buffer;
return OK;
}
+
+// write to input FMQ here, wait for statusMQ STATUS_OK, and read from output FMQ
status_t EffectHalAidl::process() {
- ALOGW("%s not implemented yet", __func__);
- // write to input FMQ here, and wait for statusMQ STATUS_OK
+ size_t available = mInputQ->availableToWrite();
+ size_t floatsToWrite = std::min(available, mInBuffer->getSize() / sizeof(float));
+ if (floatsToWrite == 0) {
+ ALOGW("%s not able to write, floats in buffer %zu, space in FMQ %zu", __func__,
+ mInBuffer->getSize() / sizeof(float), available);
+ return INVALID_OPERATION;
+ }
+ if (!mInputQ->write((float*)mInBuffer->ptr(), floatsToWrite)) {
+ ALOGW("%s failed to write %zu into inputQ", __func__, floatsToWrite);
+ return INVALID_OPERATION;
+ }
+
+ IEffect::Status retStatus{};
+ if (!mStatusQ->readBlocking(&retStatus, 1) || retStatus.status != OK ||
+ (size_t)retStatus.fmqConsumed != floatsToWrite || retStatus.fmqProduced == 0) {
+ ALOGW("%s read status failed: %s", __func__, retStatus.toString().c_str());
+ return INVALID_OPERATION;
+ }
+
+ available = mOutputQ->availableToRead();
+ size_t floatsToRead = std::min(available, mOutBuffer->getSize() / sizeof(float));
+ if (floatsToRead == 0) {
+ ALOGW("%s not able to read, buffer space %zu, floats in FMQ %zu", __func__,
+ mOutBuffer->getSize() / sizeof(float), available);
+ return INVALID_OPERATION;
+ }
+ if (!mOutputQ->read((float*)mOutBuffer->ptr(), floatsToRead)) {
+ ALOGW("%s failed to read %zu from outputQ", __func__, floatsToRead);
+ return INVALID_OPERATION;
+ }
+
+ ALOGD("%s %s consumed %zu produced %zu", __func__, mDesc.common.name.c_str(), floatsToWrite,
+ floatsToRead);
return OK;
}
@@ -165,14 +193,32 @@
status_t EffectHalAidl::command(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
uint32_t* replySize, void* pReplyData) {
- return mConversion
- ? mConversion->handleCommand(cmdCode, cmdSize, pCmdData, replySize, pReplyData)
- : INVALID_OPERATION;
+ TIME_CHECK();
+ if (!mConversion) {
+ ALOGE("%s can not handle command %d when conversion not exist", __func__, cmdCode);
+ return INVALID_OPERATION;
+ }
+
+ status_t ret = mConversion->handleCommand(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
+ // update FMQs when effect open successfully
+ if (ret == OK && cmdCode == EFFECT_CMD_INIT) {
+ const auto& retParam = mConversion->getEffectReturnParam();
+ mStatusQ = std::make_unique<StatusMQ>(retParam.statusMQ);
+ mInputQ = std::make_unique<DataMQ>(retParam.inputDataMQ);
+ mOutputQ = std::make_unique<DataMQ>(retParam.outputDataMQ);
+ if (!mStatusQ->isValid() || !mInputQ->isValid() || !mOutputQ->isValid()) {
+ ALOGE("%s return with invalid FMQ", __func__);
+ return NO_INIT;
+ }
+ }
+
+ return ret;
}
status_t EffectHalAidl::getDescriptor(effect_descriptor_t* pDescriptor) {
- ALOGW("%s %p", __func__, pDescriptor);
+ TIME_CHECK();
if (pDescriptor == nullptr) {
+ ALOGE("%s null descriptor pointer", __func__);
return BAD_VALUE;
}
Descriptor aidlDesc;
@@ -184,12 +230,13 @@
}
status_t EffectHalAidl::close() {
+ TIME_CHECK();
return statusTFromBinderStatus(mEffect->close());
}
status_t EffectHalAidl::dump(int fd) {
- ALOGW("%s not implemented yet, fd %d", __func__, fd);
- return OK;
+ TIME_CHECK();
+ return mEffect->dump(fd, nullptr, 0);
}
} // namespace effect