Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 45fcd2fd authored by Shunkai Yao's avatar Shunkai Yao Committed by Automerger Merge Worker
Browse files

Merge changes from topic "effect_reopen" into main am: 06267d9d

parents fa33e0e6 06267d9d
Loading
Loading
Loading
Loading
+21 −10
Original line number Original line Diff line number Diff line
@@ -187,16 +187,7 @@ status_t EffectConversionHelperAidl::handleSetConfig(uint32_t cmdSize, const voi
        IEffect::OpenEffectReturn openReturn;
        IEffect::OpenEffectReturn openReturn;
        RETURN_STATUS_IF_ERROR(
        RETURN_STATUS_IF_ERROR(
                statusTFromBinderStatus(mEffect->open(common, std::nullopt, &openReturn)));
                statusTFromBinderStatus(mEffect->open(common, std::nullopt, &openReturn)));

        updateMqs(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);
        }


        if (status_t status = updateEventFlags(); status != OK) {
        if (status_t status = updateEventFlags(); status != OK) {
            ALOGV("%s closing at status %d", __func__, status);
            ALOGV("%s closing at status %d", __func__, status);
@@ -213,6 +204,18 @@ status_t EffectConversionHelperAidl::handleSetConfig(uint32_t cmdSize, const voi
    return *static_cast<int32_t*>(pReplyData) = OK;
    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,
status_t EffectConversionHelperAidl::handleGetConfig(uint32_t cmdSize __unused,
                                                     const void* pCmdData __unused,
                                                     const void* pCmdData __unused,
                                                     uint32_t* replySize, void* pReplyData) {
                                                     uint32_t* replySize, void* pReplyData) {
@@ -505,5 +508,13 @@ Descriptor EffectConversionHelperAidl::getDescriptor() const {
    return desc;
    return desc;
}
}


status_t EffectConversionHelperAidl::reopen() {
    IEffect::OpenEffectReturn openReturn;
    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->reopen(&openReturn)));

    updateMqs(openReturn);
    return OK;
}

}  // namespace effect
}  // namespace effect
}  // namespace android
}  // namespace android
+3 −0
Original line number Original line Diff line number Diff line
@@ -47,6 +47,7 @@ class EffectConversionHelperAidl {
    bool isBypassingOrTunnel() const;
    bool isBypassingOrTunnel() const;


    ::aidl::android::hardware::audio::effect::Descriptor getDescriptor() const;
    ::aidl::android::hardware::audio::effect::Descriptor getDescriptor() const;
    status_t reopen();


  protected:
  protected:
    const int32_t mSessionId;
    const int32_t mSessionId;
@@ -108,6 +109,8 @@ class EffectConversionHelperAidl {
    std::shared_ptr<android::hardware::EventFlag> mEfGroup = nullptr;
    std::shared_ptr<android::hardware::EventFlag> mEfGroup = nullptr;
    status_t updateEventFlags();
    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,
    status_t handleInit(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
                        void* pReplyData);
                        void* pReplyData);
    status_t handleSetConfig(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
    status_t handleSetConfig(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+21 −9
Original line number Original line Diff line number Diff line
@@ -56,6 +56,7 @@ using ::aidl::android::aidl_utils::statusTFromBinderStatus;
using ::aidl::android::hardware::audio::effect::Descriptor;
using ::aidl::android::hardware::audio::effect::Descriptor;
using ::aidl::android::hardware::audio::effect::IEffect;
using ::aidl::android::hardware::audio::effect::IEffect;
using ::aidl::android::hardware::audio::effect::IFactory;
using ::aidl::android::hardware::audio::effect::IFactory;
using ::aidl::android::hardware::audio::effect::kEventFlagDataMqUpdate;
using ::aidl::android::hardware::audio::effect::State;
using ::aidl::android::hardware::audio::effect::State;


namespace android {
namespace android {
@@ -165,26 +166,37 @@ status_t EffectHalAidl::setOutBuffer(const sp<EffectBufferHalInterface>& buffer)


// write to input FMQ here, wait for statusMQ STATUS_OK, and read from output FMQ
// write to input FMQ here, wait for statusMQ STATUS_OK, and read from output FMQ
status_t EffectHalAidl::process() {
status_t EffectHalAidl::process() {
    const std::string effectName = mConversion->getDescriptor().common.name;
    State state = State::INIT;
    State state = State::INIT;
    if (mConversion->isBypassing() || !mEffect->getState(&state).isOk() ||
    if (mConversion->isBypassing() || !mEffect->getState(&state).isOk() ||
        state != State::PROCESSING) {
        state != State::PROCESSING) {
        ALOGI("%s skipping %s process because it's %s", __func__,
        ALOGI("%s skipping %s process because it's %s", __func__, effectName.c_str(),
              mConversion->getDescriptor().common.name.c_str(),
              mConversion->isBypassing()
              mConversion->isBypassing()
                      ? "bypassing"
                      ? "bypassing"
                      : aidl::android::hardware::audio::effect::toString(state).c_str());
                      : aidl::android::hardware::audio::effect::toString(state).c_str());
        return -ENODATA;
        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 statusQ = mConversion->getStatusMQ();
    auto inputQ = mConversion->getInputMQ();
    auto inputQ = mConversion->getInputMQ();
    auto outputQ = mConversion->getOutputMQ();
    auto outputQ = mConversion->getOutputMQ();
    auto efGroup = mConversion->getEventFlagGroup();
    if (!statusQ || !statusQ->isValid() || !inputQ || !inputQ->isValid() || !outputQ ||
    if (!statusQ || !statusQ->isValid() || !inputQ || !inputQ->isValid() || !outputQ ||
        !outputQ->isValid() || !efGroup) {
        !outputQ->isValid()) {
        ALOGE("%s invalid FMQ [Status %d I %d O %d] efGroup %p", __func__,
        ALOGE("%s invalid FMQ [Status %d I %d O %d]", __func__, statusQ ? statusQ->isValid() : 0,
              statusQ ? statusQ->isValid() : 0, inputQ ? inputQ->isValid() : 0,
              inputQ ? inputQ->isValid() : 0, outputQ ? outputQ->isValid() : 0);
              outputQ ? outputQ->isValid() : 0, efGroup.get());
        return INVALID_OPERATION;
        return INVALID_OPERATION;
    }
    }


@@ -225,8 +237,8 @@ status_t EffectHalAidl::process() {
        return INVALID_OPERATION;
        return INVALID_OPERATION;
    }
    }


    ALOGD("%s %s consumed %zu produced %zu", __func__,
    ALOGD("%s %s consumed %zu produced %zu", __func__, effectName.c_str(), floatsToWrite,
          mConversion->getDescriptor().common.name.c_str(), floatsToWrite, floatsToRead);
          floatsToRead);
    return OK;
    return OK;
}
}


+37 −36
Original line number Original line Diff line number Diff line
@@ -71,42 +71,6 @@ ndk::ScopedAStatus DownmixImpl::getDescriptor(Descriptor* _aidl_return) {
    return ndk::ScopedAStatus::ok();
    return ndk::ScopedAStatus::ok();
}
}


ndk::ScopedAStatus DownmixImpl::setParameterCommon(const Parameter& param) {
    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");

    auto tag = param.getTag();
    switch (tag) {
        case Parameter::common:
            RETURN_IF(mContext->setCommon(param.get<Parameter::common>()) != RetCode::SUCCESS,
                      EX_ILLEGAL_ARGUMENT, "setCommFailed");
            break;
        case Parameter::deviceDescription:
            RETURN_IF(mContext->setOutputDevice(param.get<Parameter::deviceDescription>()) !=
                              RetCode::SUCCESS,
                      EX_ILLEGAL_ARGUMENT, "setDeviceFailed");
            break;
        case Parameter::mode:
            RETURN_IF(mContext->setAudioMode(param.get<Parameter::mode>()) != RetCode::SUCCESS,
                      EX_ILLEGAL_ARGUMENT, "setModeFailed");
            break;
        case Parameter::source:
            RETURN_IF(mContext->setAudioSource(param.get<Parameter::source>()) != RetCode::SUCCESS,
                      EX_ILLEGAL_ARGUMENT, "setSourceFailed");
            break;
        case Parameter::volumeStereo:
            RETURN_IF(mContext->setVolumeStereo(param.get<Parameter::volumeStereo>()) !=
                              RetCode::SUCCESS,
                      EX_ILLEGAL_ARGUMENT, "setVolumeStereoFailed");
            break;
        default: {
            LOG(ERROR) << __func__ << " unsupportedParameterTag " << toString(tag);
            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
                                                                    "commonParamNotSupported");
        }
    }
    return ndk::ScopedAStatus::ok();
}

ndk::ScopedAStatus DownmixImpl::commandImpl(CommandId command) {
ndk::ScopedAStatus DownmixImpl::commandImpl(CommandId command) {
    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
    switch (command) {
    switch (command) {
@@ -206,6 +170,43 @@ RetCode DownmixImpl::releaseContext() {
    return RetCode::SUCCESS;
    return RetCode::SUCCESS;
}
}


void DownmixImpl::process() {
    /**
     * wait for the EventFlag without lock, it's ok because the mEfGroup pointer will not change
     * in the life cycle of workerThread (threadLoop).
     */
    uint32_t efState = 0;
    if (!mEventFlag || ::android::OK != mEventFlag->wait(kEventFlagNotEmpty, &efState)) {
        LOG(ERROR) << getEffectName() << __func__ << ": StatusEventFlag invalid";
    }

    {
        std::lock_guard lg(mImplMutex);
        RETURN_VALUE_IF(!mImplContext, void(), "nullContext");
        auto statusMQ = mImplContext->getStatusFmq();
        auto inputMQ = mImplContext->getInputDataFmq();
        auto outputMQ = mImplContext->getOutputDataFmq();
        auto buffer = mImplContext->getWorkBuffer();
        if (!inputMQ || !outputMQ) {
            return;
        }

        const auto availableToRead = inputMQ->availableToRead();
        const auto availableToWrite = outputMQ->availableToWrite() *
                                      mImplContext->getInputFrameSize() /
                                      mImplContext->getOutputFrameSize();
        auto processSamples = std::min(availableToRead, availableToWrite);
        if (processSamples) {
            inputMQ->read(buffer, processSamples);
            IEffect::Status status = effectProcessImpl(buffer, buffer, processSamples);
            outputMQ->write(buffer, status.fmqProduced);
            statusMQ->writeBlocking(&status, 1);
            LOG(VERBOSE) << getEffectName() << __func__ << ": done processing, effect consumed "
                        << status.fmqConsumed << " produced " << status.fmqProduced;
        }
    }
}

// Processing method running in EffectWorker thread.
// Processing method running in EffectWorker thread.
IEffect::Status DownmixImpl::effectProcessImpl(float* in, float* out, int sampleToProcess) {
IEffect::Status DownmixImpl::effectProcessImpl(float* in, float* out, int sampleToProcess) {
    if (!mContext) {
    if (!mContext) {
+17 −12
Original line number Original line Diff line number Diff line
@@ -34,21 +34,26 @@ class DownmixImpl final : public EffectImpl {
        LOG(DEBUG) << __func__;
        LOG(DEBUG) << __func__;
    }
    }


    ndk::ScopedAStatus commandImpl(CommandId command) override;
    ndk::ScopedAStatus commandImpl(CommandId command) REQUIRES(mImplMutex) override;
    ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
    ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
    ndk::ScopedAStatus setParameterCommon(const Parameter& param) override;
    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific)
    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
            REQUIRES(mImplMutex) override;
    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific)
                                            Parameter::Specific* specific) override;
            REQUIRES(mImplMutex) override;
    IEffect::Status effectProcessImpl(float* in, float* out, int process) override;
    IEffect::Status effectProcessImpl(float* in, float* out, int process)
    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
            REQUIRES(mImplMutex) override;
    RetCode releaseContext() override;
    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common)

            REQUIRES(mImplMutex) override;
    std::shared_ptr<EffectContext> getContext() override { return mContext; }
    RetCode releaseContext() REQUIRES(mImplMutex) override;

    std::string getEffectName() override { return kEffectName; }
    std::string getEffectName() override { return kEffectName; }


    // downmix override the process because of different input/output sample size requirement
    void process() override;

  private:
  private:
    std::shared_ptr<DownmixContext> mContext;
    std::shared_ptr<DownmixContext> mContext GUARDED_BY(mImplMutex);
    ndk::ScopedAStatus getParameterDownmix(const Downmix::Tag& tag, Parameter::Specific* specific);
    ndk::ScopedAStatus getParameterDownmix(const Downmix::Tag& tag, Parameter::Specific* specific)
            REQUIRES(mImplMutex);
};
};
}  // namespace aidl::android::hardware::audio::effect
}  // namespace aidl::android::hardware::audio::effect
Loading