Effect AIDL: implement IEffect.reopen
- add IEffect.reopen implementation
- now data MQs can update at runtime, sync
EffectContext access
- add clang thread annotation
Bug: 302036943
Test: atest VtsHalAudioEffectTargetTest
Test: Build and test effect on Pixel
Change-Id: Ib344abb8be6ede07bf05ba3d4829672a9ef41374
Merged-In: Ib344abb8be6ede07bf05ba3d4829672a9ef41374
diff --git a/media/libaudiohal/impl/EffectConversionHelperAidl.cpp b/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
index a807669..39999a5 100644
--- a/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
+++ b/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
@@ -187,16 +187,7 @@
IEffect::OpenEffectReturn openReturn;
RETURN_STATUS_IF_ERROR(
statusTFromBinderStatus(mEffect->open(common, std::nullopt, &openReturn)));
-
- if (mIsProxyEffect) {
- mStatusQ = std::static_pointer_cast<EffectProxy>(mEffect)->getStatusMQ();
- mInputQ = std::static_pointer_cast<EffectProxy>(mEffect)->getInputMQ();
- mOutputQ = std::static_pointer_cast<EffectProxy>(mEffect)->getOutputMQ();
- } else {
- mStatusQ = std::make_shared<StatusMQ>(openReturn.statusMQ);
- mInputQ = std::make_shared<DataMQ>(openReturn.inputDataMQ);
- mOutputQ = std::make_shared<DataMQ>(openReturn.outputDataMQ);
- }
+ updateMqs(openReturn);
if (status_t status = updateEventFlags(); status != OK) {
ALOGV("%s closing at status %d", __func__, status);
@@ -213,6 +204,18 @@
return *static_cast<int32_t*>(pReplyData) = OK;
}
+void EffectConversionHelperAidl::updateMqs(const IEffect::OpenEffectReturn& ret) {
+ if (mIsProxyEffect) {
+ mStatusQ = std::static_pointer_cast<EffectProxy>(mEffect)->getStatusMQ();
+ mInputQ = std::static_pointer_cast<EffectProxy>(mEffect)->getInputMQ();
+ mOutputQ = std::static_pointer_cast<EffectProxy>(mEffect)->getOutputMQ();
+ } else {
+ mStatusQ = std::make_shared<StatusMQ>(ret.statusMQ);
+ mInputQ = std::make_shared<DataMQ>(ret.inputDataMQ);
+ mOutputQ = std::make_shared<DataMQ>(ret.outputDataMQ);
+ }
+}
+
status_t EffectConversionHelperAidl::handleGetConfig(uint32_t cmdSize __unused,
const void* pCmdData __unused,
uint32_t* replySize, void* pReplyData) {
@@ -505,5 +508,13 @@
return desc;
}
+status_t EffectConversionHelperAidl::reopen() {
+ IEffect::OpenEffectReturn openReturn;
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->reopen(&openReturn)));
+
+ updateMqs(openReturn);
+ return OK;
+}
+
} // namespace effect
} // namespace android
diff --git a/media/libaudiohal/impl/EffectConversionHelperAidl.h b/media/libaudiohal/impl/EffectConversionHelperAidl.h
index 5db334c..8b9efb3 100644
--- a/media/libaudiohal/impl/EffectConversionHelperAidl.h
+++ b/media/libaudiohal/impl/EffectConversionHelperAidl.h
@@ -47,6 +47,7 @@
bool isBypassingOrTunnel() const;
::aidl::android::hardware::audio::effect::Descriptor getDescriptor() const;
+ status_t reopen();
protected:
const int32_t mSessionId;
@@ -108,6 +109,8 @@
std::shared_ptr<android::hardware::EventFlag> mEfGroup = nullptr;
status_t updateEventFlags();
+ void updateMqs(const ::aidl::android::hardware::audio::effect::IEffect::OpenEffectReturn& ret);
+
status_t handleInit(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
void* pReplyData);
status_t handleSetConfig(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
diff --git a/media/libaudiohal/impl/EffectHalAidl.cpp b/media/libaudiohal/impl/EffectHalAidl.cpp
index f26444c..2836727 100644
--- a/media/libaudiohal/impl/EffectHalAidl.cpp
+++ b/media/libaudiohal/impl/EffectHalAidl.cpp
@@ -56,6 +56,7 @@
using ::aidl::android::hardware::audio::effect::Descriptor;
using ::aidl::android::hardware::audio::effect::IEffect;
using ::aidl::android::hardware::audio::effect::IFactory;
+using ::aidl::android::hardware::audio::effect::kEventFlagDataMqUpdate;
using ::aidl::android::hardware::audio::effect::State;
namespace android {
@@ -165,26 +166,37 @@
// write to input FMQ here, wait for statusMQ STATUS_OK, and read from output FMQ
status_t EffectHalAidl::process() {
+ const std::string effectName = mConversion->getDescriptor().common.name;
State state = State::INIT;
if (mConversion->isBypassing() || !mEffect->getState(&state).isOk() ||
state != State::PROCESSING) {
- ALOGI("%s skipping %s process because it's %s", __func__,
- mConversion->getDescriptor().common.name.c_str(),
+ ALOGI("%s skipping %s process because it's %s", __func__, effectName.c_str(),
mConversion->isBypassing()
? "bypassing"
: aidl::android::hardware::audio::effect::toString(state).c_str());
return -ENODATA;
}
+ // check if the DataMq needs any update, timeout at 1ns to avoid being blocked
+ auto efGroup = mConversion->getEventFlagGroup();
+ if (!efGroup) {
+ ALOGE("%s invalid efGroup", __func__);
+ return INVALID_OPERATION;
+ }
+
+ if (uint32_t efState = 0;
+ ::android::OK == efGroup->wait(kEventFlagDataMqUpdate, &efState, 1 /* ns */,
+ true /* retry */)) {
+ ALOGI("%s %s receive dataMQUpdate eventFlag from HAL", __func__, effectName.c_str());
+ mConversion->reopen();
+ }
auto statusQ = mConversion->getStatusMQ();
auto inputQ = mConversion->getInputMQ();
auto outputQ = mConversion->getOutputMQ();
- auto efGroup = mConversion->getEventFlagGroup();
if (!statusQ || !statusQ->isValid() || !inputQ || !inputQ->isValid() || !outputQ ||
- !outputQ->isValid() || !efGroup) {
- ALOGE("%s invalid FMQ [Status %d I %d O %d] efGroup %p", __func__,
- statusQ ? statusQ->isValid() : 0, inputQ ? inputQ->isValid() : 0,
- outputQ ? outputQ->isValid() : 0, efGroup.get());
+ !outputQ->isValid()) {
+ ALOGE("%s invalid FMQ [Status %d I %d O %d]", __func__, statusQ ? statusQ->isValid() : 0,
+ inputQ ? inputQ->isValid() : 0, outputQ ? outputQ->isValid() : 0);
return INVALID_OPERATION;
}
@@ -225,8 +237,8 @@
return INVALID_OPERATION;
}
- ALOGD("%s %s consumed %zu produced %zu", __func__,
- mConversion->getDescriptor().common.name.c_str(), floatsToWrite, floatsToRead);
+ ALOGD("%s %s consumed %zu produced %zu", __func__, effectName.c_str(), floatsToWrite,
+ floatsToRead);
return OK;
}