Extract threading logic to EffectThread and other changes
Some checks failed
build / build (arm64-v8a) (push) Failing after 44s
build / build (armeabi-v7a) (push) Failing after 30s
build / build (x86) (push) Failing after 41s
build / build (x86_64) (push) Failing after 37s
build / package (push) Has been skipped

This commit is contained in:
Iscle 2025-04-02 02:43:03 +02:00
parent 90773bbf7a
commit 4c430372b5
7 changed files with 418 additions and 74 deletions

View File

@ -161,6 +161,8 @@ set(FILES
src/shim.cpp src/shim.cpp
# Main # Main
src/aidl/EffectThread.cpp
src/viper/ViPER.cpp src/viper/ViPER.cpp
src/ViPER4Android.cpp src/ViPER4Android.cpp
src/ViperContext.cpp src/ViperContext.cpp

130
src/aidl/EffectThread.cpp Normal file
View File

@ -0,0 +1,130 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <cstddef>
#include <memory>
#define LOG_TAG "AHAL_EffectThread"
#include <log/log.h>
#include <pthread.h>
#include <sys/resource.h>
#include "EffectThread.h"
#include "EffectTypes.h"
namespace aidl::android::hardware::audio::effect {
EffectThread::~EffectThread() {
destroyThread();
}
RetCode EffectThread::createThread(const std::string& name, int priority) {
if (mThread.joinable()) {
ALOGW("%s %s thread already created, no-op", mName.c_str(), __func__);
return RetCode::SUCCESS;
}
mName = name;
mPriority = priority;
{
std::lock_guard lg(mThreadMutex);
mStop = true;
mExit = false;
}
mThread = std::thread(&EffectThread::threadLoop, this);
ALOGV("%s %s priority %d done", mName.c_str(), __func__, mPriority);
return RetCode::SUCCESS;
}
RetCode EffectThread::destroyThread() {
{
std::lock_guard lg(mThreadMutex);
mStop = mExit = true;
}
mCv.notify_one();
if (mThread.joinable()) {
mThread.join();
}
ALOGV("%s", mName.c_str());
return RetCode::SUCCESS;
}
RetCode EffectThread::startThread() {
{
std::lock_guard lg(mThreadMutex);
if (mDraining) {
mDraining = false;
} else {
mStop = false;
}
mCv.notify_one();
}
ALOGV("%s", mName.c_str());
return RetCode::SUCCESS;
}
RetCode EffectThread::stopThread() {
{
std::lock_guard lg(mThreadMutex);
mStop = true;
mCv.notify_one();
}
ALOGV("%s", mName.c_str());
return RetCode::SUCCESS;
}
RetCode EffectThread::startDraining() {
std::lock_guard lg(mThreadMutex);
mDraining = true;
mCv.notify_one();
ALOGV("%s", mName.c_str());
return RetCode::SUCCESS;
}
RetCode EffectThread::finishDraining() {
std::lock_guard lg(mThreadMutex);
mDraining = false;
mStop = true;
mCv.notify_one();
ALOGV("%s", mName.c_str());
return RetCode::SUCCESS;
}
void EffectThread::threadLoop() {
pthread_setname_np(pthread_self(), mName.substr(0, kMaxTaskNameLen - 1).c_str());
setpriority(PRIO_PROCESS, 0, mPriority);
while (true) {
{
std::unique_lock l(mThreadMutex);
::android::base::ScopedLockAssertion lock_assertion(mThreadMutex);
mCv.wait(l, [&]() REQUIRES(mThreadMutex) { return mExit || !mStop; });
if (mExit) {
ALOGV("%s threadLoop EXIT!", mName.c_str());
return;
}
}
process();
}
}
} // namespace aidl::android::hardware::audio::effect

69
src/aidl/EffectThread.h Normal file
View File

@ -0,0 +1,69 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <atomic>
#include <memory>
#include <string>
#include <thread>
#include <android-base/thread_annotations.h>
#include <fmq/EventFlag.h>
#include <system/thread_defs.h>
//#include "EffectContext.h"
#include "EffectTypes.h"
namespace aidl::android::hardware::audio::effect {
class EffectThread {
public:
virtual ~EffectThread();
// called by effect implementation
RetCode createThread(const std::string& name, int priority = ANDROID_PRIORITY_URGENT_AUDIO);
RetCode destroyThread();
RetCode startThread();
RetCode stopThread();
RetCode startDraining();
RetCode finishDraining();
// Will call process() in a loop if the thread is running.
void threadLoop();
/**
* process() call effectProcessImpl() for effect data processing, it is necessary for the
* processing to be called under Effect thread mutex mThreadMutex, to avoid the effect state
* change before/during data processing, and keep the thread and effect state consistent.
*/
virtual void process() = 0;
protected:
bool mDraining GUARDED_BY(mThreadMutex) = false;
private:
static constexpr int kMaxTaskNameLen = 15;
std::mutex mThreadMutex;
std::condition_variable mCv;
bool mStop GUARDED_BY(mThreadMutex) = true;
bool mExit GUARDED_BY(mThreadMutex) = false;
std::thread mThread;
int mPriority;
std::string mName;
};
} // namespace aidl::android::hardware::audio::effect

133
src/aidl/EffectTypes.h Normal file
View File

@ -0,0 +1,133 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <string>
#include <aidl/android/hardware/audio/effect/BnEffect.h>
#include <aidl/android/hardware/audio/effect/Range.h>
#include <android-base/logging.h>
//#include <system/audio_effects/aidl_effects_utils.h>
typedef binder_exception_t (*EffectCreateFunctor)(
const ::aidl::android::media::audio::common::AudioUuid*,
std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>*);
typedef binder_exception_t (*EffectDestroyFunctor)(
const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>&);
typedef binder_exception_t (*EffectQueryFunctor)(
const ::aidl::android::media::audio::common::AudioUuid*,
::aidl::android::hardware::audio::effect::Descriptor*);
struct effect_dl_interface_s {
EffectCreateFunctor createEffectFunc;
EffectDestroyFunctor destroyEffectFunc;
EffectQueryFunctor queryEffectFunc;
};
namespace aidl::android::hardware::audio::effect {
enum class RetCode {
SUCCESS,
ERROR_ILLEGAL_PARAMETER, /* Illegal parameter */
ERROR_THREAD, /* Effect thread error */
ERROR_NULL_POINTER, /* NULL pointer */
ERROR_ALIGNMENT_ERROR, /* Memory alignment error */
ERROR_BLOCK_SIZE_EXCEED, /* Maximum block size exceeded */
ERROR_EFFECT_LIB_ERROR, /* Effect implementation library error */
ERROR_EVENT_FLAG_ERROR /* Error with effect event flags */
};
static const int INVALID_AUDIO_SESSION_ID = -1;
inline std::ostream& operator<<(std::ostream& out, const RetCode& code) {
switch (code) {
case RetCode::SUCCESS:
return out << "SUCCESS";
case RetCode::ERROR_ILLEGAL_PARAMETER:
return out << "ERROR_ILLEGAL_PARAMETER";
case RetCode::ERROR_THREAD:
return out << "ERROR_THREAD";
case RetCode::ERROR_NULL_POINTER:
return out << "ERROR_NULL_POINTER";
case RetCode::ERROR_ALIGNMENT_ERROR:
return out << "ERROR_ALIGNMENT_ERROR";
case RetCode::ERROR_BLOCK_SIZE_EXCEED:
return out << "ERROR_BLOCK_SIZE_EXCEED";
case RetCode::ERROR_EFFECT_LIB_ERROR:
return out << "ERROR_EFFECT_LIB_ERROR";
case RetCode::ERROR_EVENT_FLAG_ERROR:
return out << "ERROR_EVENT_FLAG_ERROR";
}
return out << "EnumError: " << code;
}
#define RETURN_IF_ASTATUS_NOT_OK(status, message) \
do { \
const ::ndk::ScopedAStatus curr_status = (status); \
if (!curr_status.isOk()) { \
LOG(ERROR) << __func__ << ": line" << __LINE__ \
<< " return with status: " << curr_status.getDescription() << (message); \
return ndk::ScopedAStatus::fromExceptionCodeWithMessage( \
curr_status.getExceptionCode(), (message)); \
} \
} while (0)
#define RETURN_IF(expr, exception, message) \
do { \
if (expr) { \
LOG(ERROR) << __func__ << ": line" << __LINE__ << " return with expr " << #expr; \
return ndk::ScopedAStatus::fromExceptionCodeWithMessage((exception), (message)); \
} \
} while (0)
#define RETURN_OK_IF(expr) \
do { \
if (expr) { \
LOG(INFO) << __func__ << ": line" << __LINE__ << " return with expr " << #expr; \
return ndk::ScopedAStatus::ok(); \
} \
} while (0)
#define RETURN_VALUE_IF(expr, ret, log) \
do { \
if (expr) { \
LOG(ERROR) << __func__ << ": line" << __LINE__ << " return with expr \"" << #expr \
<< "\":" << (log); \
return ret; \
} \
} while (0)
#define RETURN_IF_BINDER_EXCEPTION(functor) \
{ \
binder_exception_t exception = functor; \
if (EX_NONE != exception) { \
LOG(ERROR) << #functor << ": failed with error " << exception; \
return ndk::ScopedAStatus::fromExceptionCode(exception); \
} \
}
/**
* Make a Range::$EffectType$Range.
* T: The $EffectType$, Visualizer for example.
* Tag: The union tag name in $EffectType$ definition, latencyMs for example.
* l: The value of Range::$EffectType$Range.min.
* r: The value of Range::$EffectType$Range.max.
*/
#define MAKE_RANGE(T, Tag, l, r) \
{ .min = T::make<T::Tag>(l), .max = T::make<T::Tag>(r) }
} // namespace aidl::android::hardware::audio::effect

View File

@ -1,19 +1,20 @@
#include <string> #include <string>
#include <log/log.h>
namespace android::hardware::details { namespace android::hardware::details {
void check(bool exp) { void check(bool exp) {
ALOGE_IF(!exp, "Check failed");
} }
void check(bool exp, const char* message) { void check(bool exp, const char* message) {
ALOGE_IF(!exp, "%s", message);
} }
void logError(const std::string &message) { void logError(const std::string &message) {
ALOGE("%s", message.c_str());
} }
void errorWriteLog(int tag, const char* info) { void errorWriteLog(int tag, const char* info) {
ALOGE("%d: %s", tag, info);
} }
} // namespace android::hardware::details } // namespace android::hardware::details

View File

@ -8,6 +8,7 @@ using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::Flags; using aidl::android::hardware::audio::effect::Flags;
using aidl::android::hardware::audio::effect::IEffect; using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::Parameter; using aidl::android::hardware::audio::effect::Parameter;
using aidl::android::hardware::audio::effect::RetCode;
using aidl::android::hardware::audio::effect::State; using aidl::android::hardware::audio::effect::State;
using aidl::android::media::audio::common::AudioUuid; using aidl::android::media::audio::common::AudioUuid;
using aidl::android::media::audio::common::PcmType; using aidl::android::media::audio::common::PcmType;
@ -113,6 +114,18 @@ constexpr size_t getFrameSizeInBytes(
return 0; return 0;
} }
//int ViPER4AndroidAIDL::notifyEventFlag(uint32_t flag) {
// if (!mEventFlag) {
// ALOGE("notifyEventFlag: StatusEventFlag invalid");
// return -1;
// }
// if (const auto ret = mEventFlag->wake(flag); ret != ::android::OK) {
// ALOGE("notifyEventFlag: wake failure with ret %d", ret);
// return -1;
// }
// return 0;
//}
ndk::ScopedAStatus ViPER4AndroidAIDL::open(const Parameter::Common &common, ndk::ScopedAStatus ViPER4AndroidAIDL::open(const Parameter::Common &common,
const std::optional<Parameter::Specific> &specific, const std::optional<Parameter::Specific> &specific,
IEffect::OpenEffectReturn *ret) { IEffect::OpenEffectReturn *ret) {
@ -121,7 +134,7 @@ ndk::ScopedAStatus ViPER4AndroidAIDL::open(const Parameter::Common &common,
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
} }
std::lock_guard lg(mMutex); std::lock_guard lg(mImplMutex);
if (mState != State::INIT) { if (mState != State::INIT) {
ALOGD("open: already opened"); ALOGD("open: already opened");
@ -165,7 +178,10 @@ ndk::ScopedAStatus ViPER4AndroidAIDL::open(const Parameter::Common &common,
ret->inputDataMQ = mInputMQ->dupeDesc(); ret->inputDataMQ = mInputMQ->dupeDesc();
ret->outputDataMQ = mOutputMQ->dupeDesc(); ret->outputDataMQ = mOutputMQ->dupeDesc();
mThread = std::thread(&ViPER4AndroidAIDL::threadLoop, this); if (createThread(VIPER_NAME) != RetCode::SUCCESS) {
ALOGE("open: failed to create thread");
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
return ndk::ScopedAStatus::ok(); return ndk::ScopedAStatus::ok();
} }
@ -177,23 +193,59 @@ ndk::ScopedAStatus ViPER4AndroidAIDL::close() {
ndk::ScopedAStatus ndk::ScopedAStatus
ViPER4AndroidAIDL::getDescriptor(Descriptor *descriptor) { ViPER4AndroidAIDL::getDescriptor(Descriptor *descriptor) {
if (descriptor == nullptr) {
ALOGE("getDescriptor called with null descriptor");
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
ALOGD("getDescriptor: returning descriptor"); ALOGD("getDescriptor: returning descriptor");
*descriptor = kDescriptor; *descriptor = kDescriptor;
return ndk::ScopedAStatus::ok(); return ndk::ScopedAStatus::ok();
} }
ndk::ScopedAStatus ViPER4AndroidAIDL::command(CommandId command_id) { ndk::ScopedAStatus ViPER4AndroidAIDL::command(CommandId id) {
ALOGD("command called"); std::lock_guard lg(mImplMutex);
if (mState == State::INIT) {
ALOGE("command: instance not open");
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
}
switch (id) {
case CommandId::START: {
ALOGD("command: START");
if (mState == State::PROCESSING) {
return ndk::ScopedAStatus::ok();
}
mState = State::PROCESSING;
// if (notifyEventFlag() != 0) {
// ALOGE("id: failed to notify event flag");
// return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
// }
startThread();
break;
}
case CommandId::STOP: {
ALOGD("command: STOP");
if (mState == State::IDLE) {
return ndk::ScopedAStatus::ok();
}
mState = State::IDLE;
stopThread();
break;
}
case CommandId::RESET: {
ALOGD("command: RESET");
mState = State::IDLE;
stopThread();
break;
}
}
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
} }
ndk::ScopedAStatus ViPER4AndroidAIDL::getState(State *state) { ndk::ScopedAStatus ViPER4AndroidAIDL::getState(State *state) {
ALOGD("getState called"); ALOGD("getState: returning state");
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); *state = mState;
return ndk::ScopedAStatus::ok();
} }
ndk::ScopedAStatus ndk::ScopedAStatus
@ -203,64 +255,24 @@ ViPER4AndroidAIDL::setParameter(const Parameter &parameter) {
} }
ndk::ScopedAStatus ndk::ScopedAStatus
ViPER4AndroidAIDL::getParameter(const Parameter::Id &parameter_id, Parameter *parameter) { ViPER4AndroidAIDL::getParameter(const Parameter::Id &id, Parameter *param) {
ALOGD("getParameter called"); ALOGD("getParameter called");
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
} }
ndk::ScopedAStatus ndk::ScopedAStatus
ViPER4AndroidAIDL::reopen(IEffect::OpenEffectReturn *open_effect_return) { ViPER4AndroidAIDL::reopen(IEffect::OpenEffectReturn *open_effect_return) {
ALOGD("reopen called"); std::lock_guard lg(mImplMutex);
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); if (mState == State::INIT) {
} ALOGE("reopen: already closed");
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
void ViPER4AndroidAIDL::threadLoop() {
ALOGD("threadLoop started");
while (true) {
{
std::unique_lock l(mThreadMutex);
::android::base::ScopedLockAssertion lock_assertion(mThreadMutex);
mThreadCv.wait(l, [&]() REQUIRES(mThreadMutex) { return mThreadExit || !mThreadStop; });
if (mThreadExit) {
ALOGD("threadLoop exiting");
return;
}
}
process();
} }
// TODO
return ndk::ScopedAStatus::ok();
} }
void ViPER4AndroidAIDL::process() { void ViPER4AndroidAIDL::process() {
/** ALOGD("process called");
* wait for the EventFlag without lock, it's ok because the mEventFlag pointer will not change
* in the life cycle of workerThread (threadLoop).
*/
uint32_t efState = 0;
if (!mEventFlag ||
mEventFlag->wait(kEventFlagDataMqNotEmpty, &efState, 0 /* no timeout */, true /* retry */) != android::OK ||
!(efState & kEventFlagDataMqNotEmpty)) {
ALOGE("process: failed to wait for event flag");
return;
}
{
std::lock_guard lg(mMutex);
if (mState != State::PROCESSING && mState != State::DRAINING) {
ALOGD("process: skip process in state: %d", mState);
return;
}
auto buffer = mWorkBuffer.data();
auto processSamples = std::min(mInputMQ->availableToRead(), mOutputMQ->availableToWrite());
if (processSamples) {
mInputMQ->read(buffer, processSamples);
// IEffect::Status status = effectProcessImpl(buffer, buffer, processSamples);
ALOGD("process: processing %zu samples", processSamples);
IEffect::Status status = {STATUS_OK, static_cast<int32_t>(processSamples), static_cast<int32_t>(processSamples)};
mOutputMQ->write(buffer, status.fmqProduced);
mStatusMQ->writeBlocking(&status, 1);
}
}
} }
extern "C" binder_exception_t createEffect(const AudioUuid *audio_uuid, std::shared_ptr<IEffect> *instance) { extern "C" binder_exception_t createEffect(const AudioUuid *audio_uuid, std::shared_ptr<IEffect> *instance) {

View File

@ -5,20 +5,26 @@
#include <aidl/android/hardware/audio/effect/BnEffect.h> #include <aidl/android/hardware/audio/effect/BnEffect.h>
#include <aidl/android/hardware/audio/effect/State.h> #include <aidl/android/hardware/audio/effect/State.h>
#include <fmq/AidlMessageQueue.h> #include <fmq/AidlMessageQueue.h>
#include "aidl/EffectThread.h"
using aidl::android::hardware::audio::effect::BnEffect; using aidl::android::hardware::audio::effect::BnEffect;
using aidl::android::hardware::audio::effect::EffectThread;
using aidl::android::hardware::audio::effect::State; using aidl::android::hardware::audio::effect::State;
class ViPER4AndroidAIDL : public BnEffect { class ViPER4AndroidAIDL : public BnEffect, public EffectThread {
public: public:
// BnEffect
::ndk::ScopedAStatus open(const ::aidl::android::hardware::audio::effect::Parameter::Common &common, const std::optional< ::aidl::android::hardware::audio::effect::Parameter::Specific> &specific, ::aidl::android::hardware::audio::effect::IEffect::OpenEffectReturn *ret) override; ::ndk::ScopedAStatus open(const ::aidl::android::hardware::audio::effect::Parameter::Common &common, const std::optional< ::aidl::android::hardware::audio::effect::Parameter::Specific> &specific, ::aidl::android::hardware::audio::effect::IEffect::OpenEffectReturn *ret) override;
::ndk::ScopedAStatus close() override; ::ndk::ScopedAStatus close() override;
::ndk::ScopedAStatus getDescriptor(::aidl::android::hardware::audio::effect::Descriptor *_aidl_return) override; ::ndk::ScopedAStatus getDescriptor(::aidl::android::hardware::audio::effect::Descriptor *_aidl_return) override;
::ndk::ScopedAStatus command(::aidl::android::hardware::audio::effect::CommandId in_commandId) override; ::ndk::ScopedAStatus command(::aidl::android::hardware::audio::effect::CommandId id) override;
::ndk::ScopedAStatus getState(::aidl::android::hardware::audio::effect::State *_aidl_return) override; ::ndk::ScopedAStatus getState(::aidl::android::hardware::audio::effect::State *_aidl_return) override;
::ndk::ScopedAStatus setParameter(const ::aidl::android::hardware::audio::effect::Parameter &in_param) override; ::ndk::ScopedAStatus setParameter(const ::aidl::android::hardware::audio::effect::Parameter &in_param) override;
::ndk::ScopedAStatus getParameter(const ::aidl::android::hardware::audio::effect::Parameter::Id &in_paramId, ::aidl::android::hardware::audio::effect::Parameter *_aidl_return) override; ::ndk::ScopedAStatus getParameter(const ::aidl::android::hardware::audio::effect::Parameter::Id &in_paramId, ::aidl::android::hardware::audio::effect::Parameter *_aidl_return) override;
::ndk::ScopedAStatus reopen(::aidl::android::hardware::audio::effect::IEffect::OpenEffectReturn *_aidl_return) override; ::ndk::ScopedAStatus reopen(::aidl::android::hardware::audio::effect::IEffect::OpenEffectReturn *_aidl_return) override;
// EffectThread
void process() override;
private: private:
typedef ::android::AidlMessageQueue< typedef ::android::AidlMessageQueue<
IEffect::Status, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> IEffect::Status, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>
@ -27,10 +33,7 @@ private:
float, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> float, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>
DataMQ; DataMQ;
void threadLoop(); std::mutex mImplMutex;
void process();
std::mutex mMutex;
State mState = State::INIT; State mState = State::INIT;
std::shared_ptr<StatusMQ> mStatusMQ; std::shared_ptr<StatusMQ> mStatusMQ;
@ -38,10 +41,4 @@ private:
std::shared_ptr<DataMQ> mOutputMQ; std::shared_ptr<DataMQ> mOutputMQ;
android::hardware::EventFlag *mEventFlag; android::hardware::EventFlag *mEventFlag;
std::vector<float> mWorkBuffer; std::vector<float> mWorkBuffer;
std::thread mThread;
std::mutex mThreadMutex;
std::condition_variable mThreadCv;
bool mThreadStop = true;
bool mThreadExit = false;
}; };