blob: 2836727b694cdbdea7a887b8816942cc5e8d359d [file] [log] [blame]
Shunkai Yao51202502022-12-12 06:11:46 +00001/*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Shunkai Yaoc6308712023-02-22 17:53:04 +000017#include <cstddef>
Shunkai Yao51202502022-12-12 06:11:46 +000018#define LOG_TAG "EffectHalAidl"
19//#define LOG_NDEBUG 0
20
Shunkai Yao242521c2023-01-29 18:08:09 +000021#include <memory>
22
Mikhail Naganov5e406ba2023-01-13 00:27:22 +000023#include <error/expected_utils.h>
Shunkai Yao51202502022-12-12 06:11:46 +000024#include <media/AidlConversionCppNdk.h>
Shunkai Yaoa03533e2023-01-25 06:38:10 +000025#include <media/AidlConversionEffect.h>
Mikhail Naganov5e406ba2023-01-13 00:27:22 +000026#include <media/AidlConversionUtil.h>
Shunkai Yao51202502022-12-12 06:11:46 +000027#include <media/EffectsFactoryApi.h>
28#include <mediautils/TimeCheck.h>
Shunkai Yao242521c2023-01-29 18:08:09 +000029#include <system/audio.h>
Shunkai Yao399be682023-03-06 18:54:18 +000030#include <system/audio_effects/effect_uuid.h>
Shunkai Yao51202502022-12-12 06:11:46 +000031#include <utils/Log.h>
32
33#include "EffectHalAidl.h"
Shunkai Yao5c718342023-02-23 23:49:51 +000034#include "EffectProxy.h"
Shunkai Yao51202502022-12-12 06:11:46 +000035
Shunkai Yao51202502022-12-12 06:11:46 +000036#include <aidl/android/hardware/audio/effect/IEffect.h>
37
Shunkai Yaodba8ba32023-01-27 17:02:21 +000038#include "effectsAidlConversion/AidlConversionAec.h"
Shunkai Yao61ce9572023-02-28 23:55:33 +000039#include "effectsAidlConversion/AidlConversionAgc1.h"
Shunkai Yaodba8ba32023-01-27 17:02:21 +000040#include "effectsAidlConversion/AidlConversionAgc2.h"
41#include "effectsAidlConversion/AidlConversionBassBoost.h"
42#include "effectsAidlConversion/AidlConversionDownmix.h"
43#include "effectsAidlConversion/AidlConversionDynamicsProcessing.h"
Shunkai Yao242521c2023-01-29 18:08:09 +000044#include "effectsAidlConversion/AidlConversionEnvReverb.h"
45#include "effectsAidlConversion/AidlConversionEq.h"
46#include "effectsAidlConversion/AidlConversionHapticGenerator.h"
47#include "effectsAidlConversion/AidlConversionLoudnessEnhancer.h"
48#include "effectsAidlConversion/AidlConversionNoiseSuppression.h"
49#include "effectsAidlConversion/AidlConversionPresetReverb.h"
50#include "effectsAidlConversion/AidlConversionSpatializer.h"
51#include "effectsAidlConversion/AidlConversionVendorExtension.h"
52#include "effectsAidlConversion/AidlConversionVirtualizer.h"
53#include "effectsAidlConversion/AidlConversionVisualizer.h"
Shunkai Yaodba8ba32023-01-27 17:02:21 +000054
Mikhail Naganov5e406ba2023-01-13 00:27:22 +000055using ::aidl::android::aidl_utils::statusTFromBinderStatus;
Shunkai Yao51202502022-12-12 06:11:46 +000056using ::aidl::android::hardware::audio::effect::Descriptor;
57using ::aidl::android::hardware::audio::effect::IEffect;
Shunkai Yao44bdbad2023-01-14 05:11:58 +000058using ::aidl::android::hardware::audio::effect::IFactory;
Shunkai Yao1afb46c2024-01-09 20:40:45 +000059using ::aidl::android::hardware::audio::effect::kEventFlagDataMqUpdate;
Shunkai Yao26689d92023-08-01 23:06:13 +000060using ::aidl::android::hardware::audio::effect::State;
Shunkai Yao51202502022-12-12 06:11:46 +000061
62namespace android {
63namespace effect {
64
Shunkai Yao399be682023-03-06 18:54:18 +000065EffectHalAidl::EffectHalAidl(const std::shared_ptr<IFactory>& factory,
Mikhail Naganov89c22e42023-06-14 15:49:59 -070066 const std::shared_ptr<IEffect>& effect,
Shunkai Yao5c718342023-02-23 23:49:51 +000067 int32_t sessionId, int32_t ioId, const Descriptor& desc,
68 bool isProxyEffect)
Shunkai Yaodba8ba32023-01-27 17:02:21 +000069 : mFactory(factory),
Shunkai Yao44bdbad2023-01-14 05:11:58 +000070 mEffect(effect),
Shunkai Yao284bb0d2023-01-10 00:42:36 +000071 mSessionId(sessionId),
72 mIoId(ioId),
Shunkai Yao5c718342023-02-23 23:49:51 +000073 mIsProxyEffect(isProxyEffect) {
Shunkai Yaodba8ba32023-01-27 17:02:21 +000074 createAidlConversion(effect, sessionId, ioId, desc);
75}
Shunkai Yao51202502022-12-12 06:11:46 +000076
Shunkai Yao44bdbad2023-01-14 05:11:58 +000077EffectHalAidl::~EffectHalAidl() {
Shunkai Yao5c718342023-02-23 23:49:51 +000078 if (mEffect) {
Shunkai Yao79f98742023-05-03 23:54:43 +000079 if (mIsProxyEffect) {
80 std::static_pointer_cast<EffectProxy>(mEffect)->destroy();
81 } else if (mFactory) {
82 mFactory->destroyEffect(mEffect);
83 }
Shunkai Yao44bdbad2023-01-14 05:11:58 +000084 }
85}
Shunkai Yao51202502022-12-12 06:11:46 +000086
Shunkai Yaodba8ba32023-01-27 17:02:21 +000087status_t EffectHalAidl::createAidlConversion(
Shunkai Yao399be682023-03-06 18:54:18 +000088 std::shared_ptr<IEffect> effect,
Shunkai Yaodba8ba32023-01-27 17:02:21 +000089 int32_t sessionId, int32_t ioId,
Shunkai Yao399be682023-03-06 18:54:18 +000090 const Descriptor& desc) {
Shunkai Yaodba8ba32023-01-27 17:02:21 +000091 const auto& typeUuid = desc.common.id.type;
Shunkai Yao242521c2023-01-29 18:08:09 +000092 ALOGI("%s create UUID %s", __func__, typeUuid.toString().c_str());
Shunkai Yao399be682023-03-06 18:54:18 +000093 if (typeUuid ==
94 ::aidl::android::hardware::audio::effect::getEffectTypeUuidAcousticEchoCanceler()) {
Shunkai Yao323273d2023-05-24 00:45:43 +000095 mConversion = std::make_unique<android::effect::AidlConversionAec>(effect, sessionId, ioId,
96 desc, mIsProxyEffect);
Shunkai Yao399be682023-03-06 18:54:18 +000097 } else if (typeUuid == ::aidl::android::hardware::audio::effect::
98 getEffectTypeUuidAutomaticGainControlV1()) {
Shunkai Yao61ce9572023-02-28 23:55:33 +000099 mConversion = std::make_unique<android::effect::AidlConversionAgc1>(effect, sessionId, ioId,
Shunkai Yao323273d2023-05-24 00:45:43 +0000100 desc, mIsProxyEffect);
Shunkai Yao399be682023-03-06 18:54:18 +0000101 } else if (typeUuid == ::aidl::android::hardware::audio::effect::
102 getEffectTypeUuidAutomaticGainControlV2()) {
Shunkai Yaodba8ba32023-01-27 17:02:21 +0000103 mConversion = std::make_unique<android::effect::AidlConversionAgc2>(effect, sessionId, ioId,
Shunkai Yao323273d2023-05-24 00:45:43 +0000104 desc, mIsProxyEffect);
Shunkai Yao399be682023-03-06 18:54:18 +0000105 } else if (typeUuid == ::aidl::android::hardware::audio::effect::getEffectTypeUuidBassBoost()) {
Shunkai Yao323273d2023-05-24 00:45:43 +0000106 mConversion = std::make_unique<android::effect::AidlConversionBassBoost>(
107 effect, sessionId, ioId, desc, mIsProxyEffect);
Shunkai Yao399be682023-03-06 18:54:18 +0000108 } else if (typeUuid == ::aidl::android::hardware::audio::effect::getEffectTypeUuidDownmix()) {
Shunkai Yao323273d2023-05-24 00:45:43 +0000109 mConversion = std::make_unique<android::effect::AidlConversionDownmix>(
110 effect, sessionId, ioId, desc, mIsProxyEffect);
Shunkai Yao399be682023-03-06 18:54:18 +0000111 } else if (typeUuid ==
112 ::aidl::android::hardware::audio::effect::getEffectTypeUuidDynamicsProcessing()) {
Shunkai Yao323273d2023-05-24 00:45:43 +0000113 mConversion = std::make_unique<android::effect::AidlConversionDp>(effect, sessionId, ioId,
114 desc, mIsProxyEffect);
Shunkai Yao399be682023-03-06 18:54:18 +0000115 } else if (typeUuid == ::aidl::android::hardware::audio::effect::getEffectTypeUuidEnvReverb()) {
Shunkai Yao323273d2023-05-24 00:45:43 +0000116 mConversion = std::make_unique<android::effect::AidlConversionEnvReverb>(
117 effect, sessionId, ioId, desc, mIsProxyEffect);
Shunkai Yao399be682023-03-06 18:54:18 +0000118 } else if (typeUuid == ::aidl::android::hardware::audio::effect::getEffectTypeUuidEqualizer()) {
Shunkai Yao323273d2023-05-24 00:45:43 +0000119 mConversion = std::make_unique<android::effect::AidlConversionEq>(effect, sessionId, ioId,
120 desc, mIsProxyEffect);
Shunkai Yao399be682023-03-06 18:54:18 +0000121 } else if (typeUuid ==
122 ::aidl::android::hardware::audio::effect::getEffectTypeUuidHapticGenerator()) {
Shunkai Yao242521c2023-01-29 18:08:09 +0000123 mConversion = std::make_unique<android::effect::AidlConversionHapticGenerator>(
Shunkai Yao323273d2023-05-24 00:45:43 +0000124 effect, sessionId, ioId, desc, mIsProxyEffect);
Shunkai Yao399be682023-03-06 18:54:18 +0000125 } else if (typeUuid ==
126 ::aidl::android::hardware::audio::effect::getEffectTypeUuidLoudnessEnhancer()) {
Shunkai Yao242521c2023-01-29 18:08:09 +0000127 mConversion = std::make_unique<android::effect::AidlConversionLoudnessEnhancer>(
Shunkai Yao323273d2023-05-24 00:45:43 +0000128 effect, sessionId, ioId, desc, mIsProxyEffect);
Shunkai Yao399be682023-03-06 18:54:18 +0000129 } else if (typeUuid ==
130 ::aidl::android::hardware::audio::effect::getEffectTypeUuidNoiseSuppression()) {
Shunkai Yao242521c2023-01-29 18:08:09 +0000131 mConversion = std::make_unique<android::effect::AidlConversionNoiseSuppression>(
Shunkai Yao323273d2023-05-24 00:45:43 +0000132 effect, sessionId, ioId, desc, mIsProxyEffect);
Shunkai Yao399be682023-03-06 18:54:18 +0000133 } else if (typeUuid ==
134 ::aidl::android::hardware::audio::effect::getEffectTypeUuidPresetReverb()) {
Shunkai Yao242521c2023-01-29 18:08:09 +0000135 mConversion = std::make_unique<android::effect::AidlConversionPresetReverb>(
Shunkai Yao323273d2023-05-24 00:45:43 +0000136 effect, sessionId, ioId, desc, mIsProxyEffect);
Shunkai Yao399be682023-03-06 18:54:18 +0000137 } else if (typeUuid ==
138 ::aidl::android::hardware::audio::effect::getEffectTypeUuidSpatializer()) {
Shunkai Yao242521c2023-01-29 18:08:09 +0000139 mConversion = std::make_unique<android::effect::AidlConversionSpatializer>(
Shunkai Yao323273d2023-05-24 00:45:43 +0000140 effect, sessionId, ioId, desc, mIsProxyEffect);
Shunkai Yao399be682023-03-06 18:54:18 +0000141 } else if (typeUuid ==
142 ::aidl::android::hardware::audio::effect::getEffectTypeUuidVirtualizer()) {
Shunkai Yao242521c2023-01-29 18:08:09 +0000143 mConversion = std::make_unique<android::effect::AidlConversionVirtualizer>(
Shunkai Yao323273d2023-05-24 00:45:43 +0000144 effect, sessionId, ioId, desc, mIsProxyEffect);
Shunkai Yao399be682023-03-06 18:54:18 +0000145 } else if (typeUuid ==
146 ::aidl::android::hardware::audio::effect::getEffectTypeUuidVisualizer()) {
Shunkai Yao323273d2023-05-24 00:45:43 +0000147 mConversion = std::make_unique<android::effect::AidlConversionVisualizer>(
148 effect, sessionId, ioId, desc, mIsProxyEffect);
Shunkai Yaodba8ba32023-01-27 17:02:21 +0000149 } else {
Shunkai Yao242521c2023-01-29 18:08:09 +0000150 // For unknown UUID, use vendor extension implementation
151 mConversion = std::make_unique<android::effect::AidlConversionVendorExtension>(
Shunkai Yao323273d2023-05-24 00:45:43 +0000152 effect, sessionId, ioId, desc, mIsProxyEffect);
Shunkai Yaodba8ba32023-01-27 17:02:21 +0000153 }
154 return OK;
155}
156
Shunkai Yao51202502022-12-12 06:11:46 +0000157status_t EffectHalAidl::setInBuffer(const sp<EffectBufferHalInterface>& buffer) {
Shunkai Yaoc6308712023-02-22 17:53:04 +0000158 mInBuffer = buffer;
Shunkai Yao51202502022-12-12 06:11:46 +0000159 return OK;
160}
161
162status_t EffectHalAidl::setOutBuffer(const sp<EffectBufferHalInterface>& buffer) {
Shunkai Yaoc6308712023-02-22 17:53:04 +0000163 mOutBuffer = buffer;
Shunkai Yao51202502022-12-12 06:11:46 +0000164 return OK;
165}
166
Shunkai Yaoc6308712023-02-22 17:53:04 +0000167// write to input FMQ here, wait for statusMQ STATUS_OK, and read from output FMQ
Shunkai Yao51202502022-12-12 06:11:46 +0000168status_t EffectHalAidl::process() {
Shunkai Yao1afb46c2024-01-09 20:40:45 +0000169 const std::string effectName = mConversion->getDescriptor().common.name;
Shunkai Yao26689d92023-08-01 23:06:13 +0000170 State state = State::INIT;
171 if (mConversion->isBypassing() || !mEffect->getState(&state).isOk() ||
172 state != State::PROCESSING) {
Shunkai Yao1afb46c2024-01-09 20:40:45 +0000173 ALOGI("%s skipping %s process because it's %s", __func__, effectName.c_str(),
Shunkai Yao26689d92023-08-01 23:06:13 +0000174 mConversion->isBypassing()
175 ? "bypassing"
176 : aidl::android::hardware::audio::effect::toString(state).c_str());
Jaideep Sharmabd9b0d32023-09-20 11:50:25 +0530177 return -ENODATA;
Shunkai Yao26689d92023-08-01 23:06:13 +0000178 }
179
Shunkai Yao1afb46c2024-01-09 20:40:45 +0000180 // check if the DataMq needs any update, timeout at 1ns to avoid being blocked
181 auto efGroup = mConversion->getEventFlagGroup();
182 if (!efGroup) {
183 ALOGE("%s invalid efGroup", __func__);
184 return INVALID_OPERATION;
185 }
186
187 if (uint32_t efState = 0;
188 ::android::OK == efGroup->wait(kEventFlagDataMqUpdate, &efState, 1 /* ns */,
189 true /* retry */)) {
190 ALOGI("%s %s receive dataMQUpdate eventFlag from HAL", __func__, effectName.c_str());
191 mConversion->reopen();
192 }
Shunkai Yao5c718342023-02-23 23:49:51 +0000193 auto statusQ = mConversion->getStatusMQ();
194 auto inputQ = mConversion->getInputMQ();
195 auto outputQ = mConversion->getOutputMQ();
196 if (!statusQ || !statusQ->isValid() || !inputQ || !inputQ->isValid() || !outputQ ||
Shunkai Yao1afb46c2024-01-09 20:40:45 +0000197 !outputQ->isValid()) {
198 ALOGE("%s invalid FMQ [Status %d I %d O %d]", __func__, statusQ ? statusQ->isValid() : 0,
199 inputQ ? inputQ->isValid() : 0, outputQ ? outputQ->isValid() : 0);
Shunkai Yao5c718342023-02-23 23:49:51 +0000200 return INVALID_OPERATION;
201 }
202
203 size_t available = inputQ->availableToWrite();
Shunkai Yaoc6308712023-02-22 17:53:04 +0000204 size_t floatsToWrite = std::min(available, mInBuffer->getSize() / sizeof(float));
205 if (floatsToWrite == 0) {
Shunkai Yao5c718342023-02-23 23:49:51 +0000206 ALOGE("%s not able to write, floats in buffer %zu, space in FMQ %zu", __func__,
Shunkai Yaoc6308712023-02-22 17:53:04 +0000207 mInBuffer->getSize() / sizeof(float), available);
208 return INVALID_OPERATION;
209 }
Shunkai Yao5c718342023-02-23 23:49:51 +0000210 if (!mInBuffer->audioBuffer() ||
211 !inputQ->write((float*)mInBuffer->audioBuffer()->f32, floatsToWrite)) {
212 ALOGE("%s failed to write %zu floats from audiobuffer %p to inputQ [avail %zu]", __func__,
213 floatsToWrite, mInBuffer->audioBuffer(), inputQ->availableToWrite());
Shunkai Yaoc6308712023-02-22 17:53:04 +0000214 return INVALID_OPERATION;
215 }
Shunkai Yaofb79da92023-04-10 17:09:57 +0000216 efGroup->wake(aidl::android::hardware::audio::effect::kEventFlagNotEmpty);
Shunkai Yaoc6308712023-02-22 17:53:04 +0000217
218 IEffect::Status retStatus{};
Shunkai Yao5c718342023-02-23 23:49:51 +0000219 if (!statusQ->readBlocking(&retStatus, 1) || retStatus.status != OK ||
Shunkai Yaoc6308712023-02-22 17:53:04 +0000220 (size_t)retStatus.fmqConsumed != floatsToWrite || retStatus.fmqProduced == 0) {
Shunkai Yao5c718342023-02-23 23:49:51 +0000221 ALOGE("%s read status failed: %s", __func__, retStatus.toString().c_str());
Shunkai Yaoc6308712023-02-22 17:53:04 +0000222 return INVALID_OPERATION;
223 }
224
Shunkai Yao5c718342023-02-23 23:49:51 +0000225 available = outputQ->availableToRead();
Shunkai Yaoc6308712023-02-22 17:53:04 +0000226 size_t floatsToRead = std::min(available, mOutBuffer->getSize() / sizeof(float));
227 if (floatsToRead == 0) {
Shunkai Yao5c718342023-02-23 23:49:51 +0000228 ALOGE("%s not able to read, buffer space %zu, floats in FMQ %zu", __func__,
Shunkai Yaoc6308712023-02-22 17:53:04 +0000229 mOutBuffer->getSize() / sizeof(float), available);
230 return INVALID_OPERATION;
231 }
Shunkai Yao5c718342023-02-23 23:49:51 +0000232 // always read floating point data for AIDL
233 if (!mOutBuffer->audioBuffer() ||
234 !outputQ->read(mOutBuffer->audioBuffer()->f32, floatsToRead)) {
235 ALOGE("%s failed to read %zu from outputQ to audioBuffer %p", __func__, floatsToRead,
236 mOutBuffer->audioBuffer());
Shunkai Yaoc6308712023-02-22 17:53:04 +0000237 return INVALID_OPERATION;
238 }
239
Shunkai Yao1afb46c2024-01-09 20:40:45 +0000240 ALOGD("%s %s consumed %zu produced %zu", __func__, effectName.c_str(), floatsToWrite,
241 floatsToRead);
Shunkai Yao51202502022-12-12 06:11:46 +0000242 return OK;
243}
244
245// TODO: no one using, maybe deprecate this interface
246status_t EffectHalAidl::processReverse() {
247 ALOGW("%s not implemented yet", __func__);
248 return OK;
249}
250
Shunkai Yao51202502022-12-12 06:11:46 +0000251status_t EffectHalAidl::command(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
252 uint32_t* replySize, void* pReplyData) {
Shunkai Yaoc6308712023-02-22 17:53:04 +0000253 TIME_CHECK();
254 if (!mConversion) {
255 ALOGE("%s can not handle command %d when conversion not exist", __func__, cmdCode);
256 return INVALID_OPERATION;
257 }
258
Shunkai Yao5c718342023-02-23 23:49:51 +0000259 return mConversion->handleCommand(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
Shunkai Yao51202502022-12-12 06:11:46 +0000260}
261
262status_t EffectHalAidl::getDescriptor(effect_descriptor_t* pDescriptor) {
Shunkai Yaoc6308712023-02-22 17:53:04 +0000263 TIME_CHECK();
Shunkai Yao51202502022-12-12 06:11:46 +0000264 if (pDescriptor == nullptr) {
Shunkai Yaoc6308712023-02-22 17:53:04 +0000265 ALOGE("%s null descriptor pointer", __func__);
Shunkai Yao51202502022-12-12 06:11:46 +0000266 return BAD_VALUE;
267 }
268 Descriptor aidlDesc;
Mikhail Naganov5e406ba2023-01-13 00:27:22 +0000269 RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getDescriptor(&aidlDesc)));
Shunkai Yao51202502022-12-12 06:11:46 +0000270
271 *pDescriptor = VALUE_OR_RETURN_STATUS(
272 ::aidl::android::aidl2legacy_Descriptor_effect_descriptor(aidlDesc));
273 return OK;
274}
275
276status_t EffectHalAidl::close() {
Shunkai Yaoc6308712023-02-22 17:53:04 +0000277 TIME_CHECK();
Shunkai Yao44bdbad2023-01-14 05:11:58 +0000278 return statusTFromBinderStatus(mEffect->close());
Shunkai Yao51202502022-12-12 06:11:46 +0000279}
280
281status_t EffectHalAidl::dump(int fd) {
Shunkai Yaoc6308712023-02-22 17:53:04 +0000282 TIME_CHECK();
283 return mEffect->dump(fd, nullptr, 0);
Shunkai Yao51202502022-12-12 06:11:46 +0000284}
285
286} // namespace effect
287} // namespace android