Loading audio/effect/all-versions/default/Android.bp +6 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,12 @@ cc_defaults { "libmedia_headers", "libmediautils_headers", ], cflags: [ "-Wall", "-Wthread-safety", "-Werror", ], } cc_library_shared { Loading audio/effect/all-versions/default/Effect.cpp +83 −36 Original line number Diff line number Diff line Loading @@ -321,8 +321,8 @@ Effect::~Effect() { status_t status = mProcessThread->join(); ALOGE_IF(status, "processing thread exit error: %s", strerror(-status)); } if (mEfGroup) { status_t status = EventFlag::deleteEventFlag(&mEfGroup); if (EventFlag* evFlag = mEfGroup.load(std::memory_order_acquire)) { status_t status = EventFlag::deleteEventFlag(&evFlag); ALOGE_IF(status, "processing MQ event flag deletion error: %s", strerror(-status)); } mInBuffer.clear(); Loading Loading @@ -437,6 +437,7 @@ Result Effect::analyzeCommandStatus(const char* commandName, const char* context Result Effect::analyzeStatus(const char* funcName, const char* subFuncName, const char* contextDescription, status_t status) { if (status != OK) { std::lock_guard<std::mutex> lock(mLock); ALOGW("Effect %p %s %s %s: %s", mHandle, funcName, subFuncName, contextDescription, strerror(-status)); } Loading Loading @@ -470,11 +471,14 @@ Result Effect::analyzeStatus(const char* funcName, const char* subFuncName, Return<void> Effect::getConfigImpl(int commandCode, const char* commandName, GetConfigCallback _hidl_cb) { RETURN_RESULT_IF_EFFECT_CLOSED(EffectConfig()); uint32_t halResultSize = sizeof(effect_config_t); effect_config_t halConfig{}; status_t status = (*mHandle)->command(mHandle, commandCode, 0, NULL, &halResultSize, &halConfig); status_t status = OK; { std::lock_guard<std::mutex> lock(mLock); RETURN_RESULT_IF_EFFECT_CLOSED(EffectConfig()); status = (*mHandle)->command(mHandle, commandCode, 0, NULL, &halResultSize, &halConfig); } EffectConfig config; if (status == OK) { status = EffectUtils::effectConfigFromHal(halConfig, mIsInput, &config); Loading Loading @@ -542,7 +546,10 @@ Result Effect::getSupportedConfigsImpl(uint32_t featureId, uint32_t maxConfigs, } Return<void> Effect::prepareForProcessing(prepareForProcessing_cb _hidl_cb) { { std::lock_guard<std::mutex> lock(mLock); RETURN_RESULT_IF_EFFECT_CLOSED(StatusMQ::Descriptor()); } status_t status; // Create message queue. if (mStatusMQ) { Loading @@ -556,16 +563,21 @@ Return<void> Effect::prepareForProcessing(prepareForProcessing_cb _hidl_cb) { _hidl_cb(Result::INVALID_ARGUMENTS, StatusMQ::Descriptor()); return Void(); } status = EventFlag::createEventFlag(tempStatusMQ->getEventFlagWord(), &mEfGroup); if (status != OK || !mEfGroup) { EventFlag* evFlag = nullptr; status = EventFlag::createEventFlag(tempStatusMQ->getEventFlagWord(), &evFlag); if (status != OK || !evFlag) { ALOGE("failed creating event flag for status MQ: %s", strerror(-status)); _hidl_cb(Result::INVALID_ARGUMENTS, StatusMQ::Descriptor()); return Void(); } mEfGroup.store(evFlag, std::memory_order_release); { std::lock_guard<std::mutex> lock(mLock); // Create and launch the thread. mProcessThread = new ProcessThread(&mStopProcessThread, mHandle, &mHalInBufferPtr, &mHalOutBufferPtr, tempStatusMQ.get(), mEfGroup, this); &mHalOutBufferPtr, tempStatusMQ.get(), evFlag, this); } status = mProcessThread->run("effect", PRIORITY_URGENT_AUDIO); if (status != OK) { ALOGW("failed to start effect processing thread: %s", strerror(-status)); Loading @@ -575,12 +587,16 @@ Return<void> Effect::prepareForProcessing(prepareForProcessing_cb _hidl_cb) { // For a spatializer effect, we perform scheduler adjustments to reduce glitches and power. // We do it here instead of the ProcessThread::threadLoop to ensure that mHandle is valid. { std::lock_guard<std::mutex> lock(mLock); RETURN_RESULT_IF_EFFECT_CLOSED(StatusMQ::Descriptor()); if (effect_descriptor_t halDescriptor{}; (*mHandle)->get_descriptor(mHandle, &halDescriptor) == NO_ERROR && memcmp(&halDescriptor.type, FX_IID_SPATIALIZER, sizeof(effect_uuid_t)) == 0) { const status_t status = scheduler::updateSpatializerPriority(mProcessThread->getTid()); ALOGW_IF(status != OK, "Failed to update Spatializer priority"); } } mStatusMQ = std::move(tempStatusMQ); _hidl_cb(Result::OK, *mStatusMQ->getDesc()); Loading @@ -589,7 +605,10 @@ Return<void> Effect::prepareForProcessing(prepareForProcessing_cb _hidl_cb) { Return<Result> Effect::setProcessBuffers(const AudioBuffer& inBuffer, const AudioBuffer& outBuffer) { { std::lock_guard<std::mutex> lock(mLock); RETURN_IF_EFFECT_CLOSED(); } AudioBufferManager& manager = AudioBufferManager::getInstance(); sp<AudioBufferWrapper> tempInBuffer, tempOutBuffer; if (!manager.wrap(inBuffer, &tempInBuffer)) { Loading @@ -614,8 +633,12 @@ Result Effect::sendCommand(int commandCode, const char* commandName) { } Result Effect::sendCommand(int commandCode, const char* commandName, uint32_t size, void* data) { status_t status = OK; { std::lock_guard<std::mutex> lock(mLock); RETURN_IF_EFFECT_CLOSED(); status_t status = (*mHandle)->command(mHandle, commandCode, size, data, 0, NULL); status = (*mHandle)->command(mHandle, commandCode, size, data, 0, NULL); } return analyzeCommandStatus(commandName, sContextCallToCommand, status); } Loading @@ -626,9 +649,13 @@ Result Effect::sendCommandReturningData(int commandCode, const char* commandName Result Effect::sendCommandReturningData(int commandCode, const char* commandName, uint32_t size, void* data, uint32_t* replySize, void* replyData) { RETURN_IF_EFFECT_CLOSED(); uint32_t expectedReplySize = *replySize; status_t status = (*mHandle)->command(mHandle, commandCode, size, data, replySize, replyData); status_t status = OK; { std::lock_guard<std::mutex> lock(mLock); RETURN_IF_EFFECT_CLOSED(); status = (*mHandle)->command(mHandle, commandCode, size, data, replySize, replyData); } if (status == OK && *replySize != expectedReplySize) { status = -ENODATA; } Loading @@ -651,8 +678,12 @@ Result Effect::sendCommandReturningStatusAndData(int commandCode, const char* co uint32_t size, void* data, uint32_t* replySize, void* replyData, uint32_t minReplySize, CommandSuccessCallback onSuccess) { status_t status = OK; { std::lock_guard<std::mutex> lock(mLock); RETURN_IF_EFFECT_CLOSED(); status_t status = (*mHandle)->command(mHandle, commandCode, size, data, replySize, replyData); status = (*mHandle)->command(mHandle, commandCode, size, data, replySize, replyData); } Result retval; if (status == OK && minReplySize >= sizeof(uint32_t) && *replySize >= minReplySize) { uint32_t commandStatus = *reinterpret_cast<uint32_t*>(replyData); Loading Loading @@ -860,10 +891,14 @@ Return<Result> Effect::offload(const EffectOffloadParameter& param) { } Return<void> Effect::getDescriptor(getDescriptor_cb _hidl_cb) { RETURN_RESULT_IF_EFFECT_CLOSED(EffectDescriptor()); effect_descriptor_t halDescriptor; memset(&halDescriptor, 0, sizeof(effect_descriptor_t)); status_t status = (*mHandle)->get_descriptor(mHandle, &halDescriptor); status_t status = OK; { std::lock_guard<std::mutex> lock(mLock); RETURN_RESULT_IF_EFFECT_CLOSED(EffectDescriptor()); status = (*mHandle)->get_descriptor(mHandle, &halDescriptor); } EffectDescriptor descriptor; if (status == OK) { status = EffectUtils::effectDescriptorFromHal(halDescriptor, &descriptor); Loading @@ -874,10 +909,6 @@ Return<void> Effect::getDescriptor(getDescriptor_cb _hidl_cb) { Return<void> Effect::command(uint32_t commandId, const hidl_vec<uint8_t>& data, uint32_t resultMaxSize, command_cb _hidl_cb) { if (mHandle == kInvalidEffectHandle) { _hidl_cb(-ENODATA, hidl_vec<uint8_t>()); return Void(); } uint32_t halDataSize; std::unique_ptr<uint8_t[]> halData = hidlVecToHal(data, &halDataSize); uint32_t halResultSize = resultMaxSize; Loading @@ -897,8 +928,15 @@ Return<void> Effect::command(uint32_t commandId, const hidl_vec<uint8_t>& data, } [[fallthrough]]; // allow 'gtid' overload (checked halDataSize and resultMaxSize). default: status = (*mHandle)->command(mHandle, commandId, halDataSize, dataPtr, &halResultSize, resultPtr); { std::lock_guard<std::mutex> lock(mLock); if (mHandle == kInvalidEffectHandle) { _hidl_cb(-ENODATA, hidl_vec<uint8_t>()); return Void(); } status = (*mHandle)->command(mHandle, commandId, halDataSize, dataPtr, &halResultSize, resultPtr); } break; } hidl_vec<uint8_t> result; Loading Loading @@ -967,11 +1005,17 @@ std::tuple<Result, effect_handle_t> Effect::closeImpl() { return {Result::INVALID_STATE, kInvalidEffectHandle}; } mStopProcessThread.store(true, std::memory_order_release); if (mEfGroup) { mEfGroup->wake(static_cast<uint32_t>(MessageQueueFlagBits::REQUEST_QUIT)); } effect_handle_t handle = mHandle; EventFlag* evFlag = mEfGroup.load(std::memory_order_acquire); if (evFlag) { evFlag->wake(static_cast<uint32_t>( MessageQueueFlagBits::REQUEST_QUIT)); } effect_handle_t handle; { std::lock_guard<std::mutex> lock(mLock); handle = mHandle; mHandle = kInvalidEffectHandle; } #if MAJOR_VERSION <= 5 return {Result::OK, handle}; #elif MAJOR_VERSION >= 6 Loading @@ -984,7 +1028,10 @@ std::tuple<Result, effect_handle_t> Effect::closeImpl() { } Return<Result> Effect::close() { { std::lock_guard<std::mutex> lock(mLock); RETURN_IF_EFFECT_CLOSED(); } auto [result, _] = closeImpl(); return result; } Loading audio/effect/all-versions/default/Effect.h +4 −2 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include <memory> #include <tuple> #include <vector> #include <mutex> #include <fmq/EventFlag.h> #include <fmq/MessageQueue.h> Loading Loading @@ -194,13 +195,14 @@ struct Effect : public IEffect { static const char* sContextCallFunction; const bool mIsInput; effect_handle_t mHandle; std::mutex mLock; effect_handle_t mHandle GUARDED_BY(mLock); sp<AudioBufferWrapper> mInBuffer; sp<AudioBufferWrapper> mOutBuffer; std::atomic<audio_buffer_t*> mHalInBufferPtr; std::atomic<audio_buffer_t*> mHalOutBufferPtr; std::unique_ptr<StatusMQ> mStatusMQ; EventFlag* mEfGroup; std::atomic<EventFlag*> mEfGroup; std::atomic<bool> mStopProcessThread; sp<Thread> mProcessThread; Loading Loading
audio/effect/all-versions/default/Android.bp +6 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,12 @@ cc_defaults { "libmedia_headers", "libmediautils_headers", ], cflags: [ "-Wall", "-Wthread-safety", "-Werror", ], } cc_library_shared { Loading
audio/effect/all-versions/default/Effect.cpp +83 −36 Original line number Diff line number Diff line Loading @@ -321,8 +321,8 @@ Effect::~Effect() { status_t status = mProcessThread->join(); ALOGE_IF(status, "processing thread exit error: %s", strerror(-status)); } if (mEfGroup) { status_t status = EventFlag::deleteEventFlag(&mEfGroup); if (EventFlag* evFlag = mEfGroup.load(std::memory_order_acquire)) { status_t status = EventFlag::deleteEventFlag(&evFlag); ALOGE_IF(status, "processing MQ event flag deletion error: %s", strerror(-status)); } mInBuffer.clear(); Loading Loading @@ -437,6 +437,7 @@ Result Effect::analyzeCommandStatus(const char* commandName, const char* context Result Effect::analyzeStatus(const char* funcName, const char* subFuncName, const char* contextDescription, status_t status) { if (status != OK) { std::lock_guard<std::mutex> lock(mLock); ALOGW("Effect %p %s %s %s: %s", mHandle, funcName, subFuncName, contextDescription, strerror(-status)); } Loading Loading @@ -470,11 +471,14 @@ Result Effect::analyzeStatus(const char* funcName, const char* subFuncName, Return<void> Effect::getConfigImpl(int commandCode, const char* commandName, GetConfigCallback _hidl_cb) { RETURN_RESULT_IF_EFFECT_CLOSED(EffectConfig()); uint32_t halResultSize = sizeof(effect_config_t); effect_config_t halConfig{}; status_t status = (*mHandle)->command(mHandle, commandCode, 0, NULL, &halResultSize, &halConfig); status_t status = OK; { std::lock_guard<std::mutex> lock(mLock); RETURN_RESULT_IF_EFFECT_CLOSED(EffectConfig()); status = (*mHandle)->command(mHandle, commandCode, 0, NULL, &halResultSize, &halConfig); } EffectConfig config; if (status == OK) { status = EffectUtils::effectConfigFromHal(halConfig, mIsInput, &config); Loading Loading @@ -542,7 +546,10 @@ Result Effect::getSupportedConfigsImpl(uint32_t featureId, uint32_t maxConfigs, } Return<void> Effect::prepareForProcessing(prepareForProcessing_cb _hidl_cb) { { std::lock_guard<std::mutex> lock(mLock); RETURN_RESULT_IF_EFFECT_CLOSED(StatusMQ::Descriptor()); } status_t status; // Create message queue. if (mStatusMQ) { Loading @@ -556,16 +563,21 @@ Return<void> Effect::prepareForProcessing(prepareForProcessing_cb _hidl_cb) { _hidl_cb(Result::INVALID_ARGUMENTS, StatusMQ::Descriptor()); return Void(); } status = EventFlag::createEventFlag(tempStatusMQ->getEventFlagWord(), &mEfGroup); if (status != OK || !mEfGroup) { EventFlag* evFlag = nullptr; status = EventFlag::createEventFlag(tempStatusMQ->getEventFlagWord(), &evFlag); if (status != OK || !evFlag) { ALOGE("failed creating event flag for status MQ: %s", strerror(-status)); _hidl_cb(Result::INVALID_ARGUMENTS, StatusMQ::Descriptor()); return Void(); } mEfGroup.store(evFlag, std::memory_order_release); { std::lock_guard<std::mutex> lock(mLock); // Create and launch the thread. mProcessThread = new ProcessThread(&mStopProcessThread, mHandle, &mHalInBufferPtr, &mHalOutBufferPtr, tempStatusMQ.get(), mEfGroup, this); &mHalOutBufferPtr, tempStatusMQ.get(), evFlag, this); } status = mProcessThread->run("effect", PRIORITY_URGENT_AUDIO); if (status != OK) { ALOGW("failed to start effect processing thread: %s", strerror(-status)); Loading @@ -575,12 +587,16 @@ Return<void> Effect::prepareForProcessing(prepareForProcessing_cb _hidl_cb) { // For a spatializer effect, we perform scheduler adjustments to reduce glitches and power. // We do it here instead of the ProcessThread::threadLoop to ensure that mHandle is valid. { std::lock_guard<std::mutex> lock(mLock); RETURN_RESULT_IF_EFFECT_CLOSED(StatusMQ::Descriptor()); if (effect_descriptor_t halDescriptor{}; (*mHandle)->get_descriptor(mHandle, &halDescriptor) == NO_ERROR && memcmp(&halDescriptor.type, FX_IID_SPATIALIZER, sizeof(effect_uuid_t)) == 0) { const status_t status = scheduler::updateSpatializerPriority(mProcessThread->getTid()); ALOGW_IF(status != OK, "Failed to update Spatializer priority"); } } mStatusMQ = std::move(tempStatusMQ); _hidl_cb(Result::OK, *mStatusMQ->getDesc()); Loading @@ -589,7 +605,10 @@ Return<void> Effect::prepareForProcessing(prepareForProcessing_cb _hidl_cb) { Return<Result> Effect::setProcessBuffers(const AudioBuffer& inBuffer, const AudioBuffer& outBuffer) { { std::lock_guard<std::mutex> lock(mLock); RETURN_IF_EFFECT_CLOSED(); } AudioBufferManager& manager = AudioBufferManager::getInstance(); sp<AudioBufferWrapper> tempInBuffer, tempOutBuffer; if (!manager.wrap(inBuffer, &tempInBuffer)) { Loading @@ -614,8 +633,12 @@ Result Effect::sendCommand(int commandCode, const char* commandName) { } Result Effect::sendCommand(int commandCode, const char* commandName, uint32_t size, void* data) { status_t status = OK; { std::lock_guard<std::mutex> lock(mLock); RETURN_IF_EFFECT_CLOSED(); status_t status = (*mHandle)->command(mHandle, commandCode, size, data, 0, NULL); status = (*mHandle)->command(mHandle, commandCode, size, data, 0, NULL); } return analyzeCommandStatus(commandName, sContextCallToCommand, status); } Loading @@ -626,9 +649,13 @@ Result Effect::sendCommandReturningData(int commandCode, const char* commandName Result Effect::sendCommandReturningData(int commandCode, const char* commandName, uint32_t size, void* data, uint32_t* replySize, void* replyData) { RETURN_IF_EFFECT_CLOSED(); uint32_t expectedReplySize = *replySize; status_t status = (*mHandle)->command(mHandle, commandCode, size, data, replySize, replyData); status_t status = OK; { std::lock_guard<std::mutex> lock(mLock); RETURN_IF_EFFECT_CLOSED(); status = (*mHandle)->command(mHandle, commandCode, size, data, replySize, replyData); } if (status == OK && *replySize != expectedReplySize) { status = -ENODATA; } Loading @@ -651,8 +678,12 @@ Result Effect::sendCommandReturningStatusAndData(int commandCode, const char* co uint32_t size, void* data, uint32_t* replySize, void* replyData, uint32_t minReplySize, CommandSuccessCallback onSuccess) { status_t status = OK; { std::lock_guard<std::mutex> lock(mLock); RETURN_IF_EFFECT_CLOSED(); status_t status = (*mHandle)->command(mHandle, commandCode, size, data, replySize, replyData); status = (*mHandle)->command(mHandle, commandCode, size, data, replySize, replyData); } Result retval; if (status == OK && minReplySize >= sizeof(uint32_t) && *replySize >= minReplySize) { uint32_t commandStatus = *reinterpret_cast<uint32_t*>(replyData); Loading Loading @@ -860,10 +891,14 @@ Return<Result> Effect::offload(const EffectOffloadParameter& param) { } Return<void> Effect::getDescriptor(getDescriptor_cb _hidl_cb) { RETURN_RESULT_IF_EFFECT_CLOSED(EffectDescriptor()); effect_descriptor_t halDescriptor; memset(&halDescriptor, 0, sizeof(effect_descriptor_t)); status_t status = (*mHandle)->get_descriptor(mHandle, &halDescriptor); status_t status = OK; { std::lock_guard<std::mutex> lock(mLock); RETURN_RESULT_IF_EFFECT_CLOSED(EffectDescriptor()); status = (*mHandle)->get_descriptor(mHandle, &halDescriptor); } EffectDescriptor descriptor; if (status == OK) { status = EffectUtils::effectDescriptorFromHal(halDescriptor, &descriptor); Loading @@ -874,10 +909,6 @@ Return<void> Effect::getDescriptor(getDescriptor_cb _hidl_cb) { Return<void> Effect::command(uint32_t commandId, const hidl_vec<uint8_t>& data, uint32_t resultMaxSize, command_cb _hidl_cb) { if (mHandle == kInvalidEffectHandle) { _hidl_cb(-ENODATA, hidl_vec<uint8_t>()); return Void(); } uint32_t halDataSize; std::unique_ptr<uint8_t[]> halData = hidlVecToHal(data, &halDataSize); uint32_t halResultSize = resultMaxSize; Loading @@ -897,8 +928,15 @@ Return<void> Effect::command(uint32_t commandId, const hidl_vec<uint8_t>& data, } [[fallthrough]]; // allow 'gtid' overload (checked halDataSize and resultMaxSize). default: status = (*mHandle)->command(mHandle, commandId, halDataSize, dataPtr, &halResultSize, resultPtr); { std::lock_guard<std::mutex> lock(mLock); if (mHandle == kInvalidEffectHandle) { _hidl_cb(-ENODATA, hidl_vec<uint8_t>()); return Void(); } status = (*mHandle)->command(mHandle, commandId, halDataSize, dataPtr, &halResultSize, resultPtr); } break; } hidl_vec<uint8_t> result; Loading Loading @@ -967,11 +1005,17 @@ std::tuple<Result, effect_handle_t> Effect::closeImpl() { return {Result::INVALID_STATE, kInvalidEffectHandle}; } mStopProcessThread.store(true, std::memory_order_release); if (mEfGroup) { mEfGroup->wake(static_cast<uint32_t>(MessageQueueFlagBits::REQUEST_QUIT)); } effect_handle_t handle = mHandle; EventFlag* evFlag = mEfGroup.load(std::memory_order_acquire); if (evFlag) { evFlag->wake(static_cast<uint32_t>( MessageQueueFlagBits::REQUEST_QUIT)); } effect_handle_t handle; { std::lock_guard<std::mutex> lock(mLock); handle = mHandle; mHandle = kInvalidEffectHandle; } #if MAJOR_VERSION <= 5 return {Result::OK, handle}; #elif MAJOR_VERSION >= 6 Loading @@ -984,7 +1028,10 @@ std::tuple<Result, effect_handle_t> Effect::closeImpl() { } Return<Result> Effect::close() { { std::lock_guard<std::mutex> lock(mLock); RETURN_IF_EFFECT_CLOSED(); } auto [result, _] = closeImpl(); return result; } Loading
audio/effect/all-versions/default/Effect.h +4 −2 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include <memory> #include <tuple> #include <vector> #include <mutex> #include <fmq/EventFlag.h> #include <fmq/MessageQueue.h> Loading Loading @@ -194,13 +195,14 @@ struct Effect : public IEffect { static const char* sContextCallFunction; const bool mIsInput; effect_handle_t mHandle; std::mutex mLock; effect_handle_t mHandle GUARDED_BY(mLock); sp<AudioBufferWrapper> mInBuffer; sp<AudioBufferWrapper> mOutBuffer; std::atomic<audio_buffer_t*> mHalInBufferPtr; std::atomic<audio_buffer_t*> mHalOutBufferPtr; std::unique_ptr<StatusMQ> mStatusMQ; EventFlag* mEfGroup; std::atomic<EventFlag*> mEfGroup; std::atomic<bool> mStopProcessThread; sp<Thread> mProcessThread; Loading