diff --git a/services/audiohdiproxy/include/idaudio_hdi_callback.h b/services/audiohdiproxy/include/idaudio_hdi_callback.h index 23b257d8de7e5b498712473c4f30ae2dc2504c79..bf31d81fe43731a6a96821edf24a14ce776ea25c 100644 --- a/services/audiohdiproxy/include/idaudio_hdi_callback.h +++ b/services/audiohdiproxy/include/idaudio_hdi_callback.h @@ -37,6 +37,12 @@ public: virtual int32_t WriteStreamData(const std::string &devId, const int32_t dhId, std::shared_ptr &data) = 0; virtual int32_t ReadStreamData(const std::string &devId, const int32_t dhId, std::shared_ptr &data) = 0; + + virtual int32_t ReadMmapPosition(const std::string &devId, const int32_t dhId, + uint64_t frames, CurrentTimeHDF &time) = 0; + + virtual int32_t RefreshAshmemInfo(const std::string &devId, const int32_t dhId, + int32_t fd, int32_t ashmemLength, int32_t lengthPerTrans) = 0; }; } // DistributedHardware } // OHOS diff --git a/services/audiohdiproxy/test/unittest/daudio_hdi_handler/include/audio_test_utils.h b/services/audiohdiproxy/test/unittest/daudio_hdi_handler/include/audio_test_utils.h index 333761fcad96574e61465f3d77891d8521571f0d..7e99332d8ee10c9767895be4c31d31052c3cbd2b 100644 --- a/services/audiohdiproxy/test/unittest/daudio_hdi_handler/include/audio_test_utils.h +++ b/services/audiohdiproxy/test/unittest/daudio_hdi_handler/include/audio_test_utils.h @@ -84,6 +84,18 @@ public: { return DH_SUCCESS; } + + int32_t ReadMmapPosition(const std::string &devId, const int32_t dhId, + uint64_t frames, CurrentTimeHDF &time) + { + return DH_SUCCESS; + } + + int32_t RefreshAshmemInfo(const std::string &devId, const int32_t dhId, + int32_t fd, int32_t ashmemLength, int32_t lengthPerTrans) + { + return DH_SUCCESS; + } }; } // DistributedHardware } // OHOS diff --git a/services/audiohdiproxy/test/unittest/daudio_manager_callback/include/audio_test_utils.h b/services/audiohdiproxy/test/unittest/daudio_manager_callback/include/audio_test_utils.h index c772cbb7527f78217830db34a42b27bd23a0c401..50deca2d75b77e22e59152026b0ca3fc2ce4d594 100644 --- a/services/audiohdiproxy/test/unittest/daudio_manager_callback/include/audio_test_utils.h +++ b/services/audiohdiproxy/test/unittest/daudio_manager_callback/include/audio_test_utils.h @@ -57,6 +57,18 @@ public: data = std::make_shared(DEFAULT_AUDIO_DATA_SIZE); return DH_SUCCESS; } + + int32_t ReadMmapPosition(const std::string &devId, const int32_t dhId, + uint64_t frames, CurrentTimeHDF &time) + { + return DH_SUCCESS; + } + + int32_t RefreshAshmemInfo(const std::string &devId, const int32_t dhId, + int32_t fd, int32_t ashmemLength, int32_t lengthPerTrans) + { + return DH_SUCCESS; + } }; } // DistributedHardware } // OHOS diff --git a/services/audiomanager/managersource/include/daudio_source_dev.h b/services/audiomanager/managersource/include/daudio_source_dev.h index d4258335c90a477faa4d001b9f4f0d6eaeb9254c..0fdca2103ea1312e4b236e97359b6db43110cfa7 100644 --- a/services/audiomanager/managersource/include/daudio_source_dev.h +++ b/services/audiomanager/managersource/include/daudio_source_dev.h @@ -89,6 +89,10 @@ private: int32_t HandleFocusChange(const AudioEvent &event); int32_t HandleRenderStateChange(const AudioEvent &event); int32_t HandlePlayStatusChange(const AudioEvent &event); + int32_t HandleSpkMmapStart(const AudioEvent &event); + int32_t HandleSpkMmapStop(const AudioEvent &event); + int32_t HandleMicMmapStart(const AudioEvent &event); + int32_t HandleMicMmapStop(const AudioEvent &event); int32_t NotifySinkDev(const AudioEventType type, const json Param, const std::string dhId); int32_t NotifyHDF(const AudioEventType type, const std::string result); diff --git a/services/audiomanager/managersource/include/dmic_dev.h b/services/audiomanager/managersource/include/dmic_dev.h index 22c9ee0490ff20a34bd37c6207ea43c794b410e3..4870b2de71b763efdf3eca0f811a557213e72f1c 100644 --- a/services/audiomanager/managersource/include/dmic_dev.h +++ b/services/audiomanager/managersource/include/dmic_dev.h @@ -18,10 +18,12 @@ #include #include +#include #include "nlohmann/json.hpp" #include "audio_param.h" #include "audio_status.h" +#include "ashmem.h" #include "daudio_hdi_handler.h" #include "iaudio_datatrans_callback.h" #include "iaudio_data_transport.h" @@ -49,6 +51,12 @@ public: int32_t WriteStreamData(const std::string &devId, const int32_t dhId, std::shared_ptr &data) override; int32_t ReadStreamData(const std::string &devId, const int32_t dhId, std::shared_ptr &data) override; int32_t NotifyEvent(const std::string &devId, const int32_t dhId, const AudioEvent &event) override; + int32_t ReadMmapPosition(const std::string &devId, const int32_t dhId, + uint64_t frames, CurrentTimeHDF &time) override; + int32_t RefreshAshmemInfo(const std::string &devId, const int32_t dhId, + int32_t fd, int32_t ashmemLength, int32_t lengthPerTrans) override; + int32_t MmapStart(); + int32_t MmapStop(); int32_t SetUp(); int32_t Start(); @@ -64,6 +72,7 @@ public: private: int32_t EnableDevice(const int32_t dhId, const std::string &capability); int32_t DisableDevice(const int32_t dhId); + void EnqueueThread(); private: static constexpr uint8_t CHANNEL_WAIT_SECONDS = 5; @@ -89,6 +98,21 @@ private: // Mic capture parameters AudioParamHDF paramHDF_; AudioParam param_; + + uint32_t timeInterval_ = 5; + sptr ashmem_ = nullptr; + std::atomic isEnqueueRunning_ = false; + int32_t ashmemLength_ = -1; + int32_t lengthPerTrans_ = -1; + int32_t writeIndex_ = -1; + int64_t frameIndex_ = 0; + int64_t startTime_ = 0; + uint64_t writeNum_ = 0; + int64_t writeTvSec_ = 0; + int64_t writeTvNSec_ = 0; + std::thread enqueueDataThread_; + std::mutex writeAshmemMutex_; + std::condition_variable dataQueueCond_; }; } // DistributedHardware } // OHOS diff --git a/services/audiomanager/managersource/include/dspeaker_dev.h b/services/audiomanager/managersource/include/dspeaker_dev.h index 5b2c009bd6b550fd0096ea8fb18b86b1a5515ef8..4996c251152a3dff96d48bb10d59110cbc11eed3 100644 --- a/services/audiomanager/managersource/include/dspeaker_dev.h +++ b/services/audiomanager/managersource/include/dspeaker_dev.h @@ -22,6 +22,7 @@ #include "nlohmann/json.hpp" #include "audio_param.h" +#include "ashmem.h" #include "idaudio_hdi_callback.h" #include "daudio_hdi_handler.h" #include "iaudio_data_transport.h" @@ -49,6 +50,12 @@ public: int32_t WriteStreamData(const std::string &devId, const int32_t dhId, std::shared_ptr &data) override; int32_t ReadStreamData(const std::string &devId, const int32_t dhId, std::shared_ptr &data) override; int32_t NotifyEvent(const std::string &devId, const int32_t dhId, const AudioEvent &event) override; + int32_t ReadMmapPosition(const std::string &devId, const int32_t dhId, + uint64_t frames, CurrentTimeHDF &time) override; + int32_t RefreshAshmemInfo(const std::string &devId, const int32_t dhId, + int32_t fd, int32_t ashmemLength, int32_t lengthPerTrans) override; + int32_t MmapStart(); + int32_t MmapStop(); int32_t OnStateChange(const AudioEventType type) override; int32_t OnDecodeTransDataDone(const std::shared_ptr &audioData) override; @@ -67,6 +74,7 @@ public: private: int32_t EnableDevice(const int32_t dhId, const std::string &capability); int32_t DisableDevice(const int32_t dhId); + void EnqueueThread(); private: static constexpr const char* ENQUEUE_THREAD = "spkEnqueueTh"; @@ -84,6 +92,19 @@ private: // Speaker render parameters AudioParamHDF paramHDF_; AudioParam param_; + + uint32_t timeInterval_ = 5; + sptr ashmem_ = nullptr; + std::atomic isEnqueueRunning_ = false; + int32_t ashmemLength_ = -1; + int32_t lengthPerTrans_ = -1; + int32_t readIndex_ = -1; + int64_t frameIndex_ = 0; + int64_t startTime_ = 0; + uint64_t readNum_ = 0; + int64_t readTvSec_ = 0; + int64_t readTvNSec_ = 0; + std::thread enqueueDataThread_; }; } // DistributedHardware } // OHOS diff --git a/services/audiomanager/managersource/src/daudio_source_dev.cpp b/services/audiomanager/managersource/src/daudio_source_dev.cpp index be4ef583d1c8ba1570a733c57cd367b5c44bb352..6fe25ea26fc5af4f3575472415def79c43310a43 100644 --- a/services/audiomanager/managersource/src/daudio_source_dev.cpp +++ b/services/audiomanager/managersource/src/daudio_source_dev.cpp @@ -54,6 +54,10 @@ DAudioSourceDev::DAudioSourceDev(const std::string &devId, const std::shared_ptr memberFuncMap_[AUDIO_FOCUS_CHANGE] = &DAudioSourceDev::HandleFocusChange; memberFuncMap_[AUDIO_RENDER_STATE_CHANGE] = &DAudioSourceDev::HandleRenderStateChange; memberFuncMap_[CHANGE_PLAY_STATUS] = &DAudioSourceDev::HandlePlayStatusChange; + memberFuncMap_[MMAP_SPK_START] = &DAudioSourceDev::HandleSpkMmapStart; + memberFuncMap_[MMAP_SPK_STOP] = &DAudioSourceDev::HandleSpkMmapStop; + memberFuncMap_[MMAP_MIC_START] = &DAudioSourceDev::HandleMicMmapStart; + memberFuncMap_[MMAP_MIC_STOP] = &DAudioSourceDev::HandleMicMmapStop; eventNotifyMap_[NOTIFY_OPEN_SPEAKER_RESULT] = EVENT_NOTIFY_OPEN_SPK; eventNotifyMap_[NOTIFY_CLOSE_SPEAKER_RESULT] = EVENT_NOTIFY_CLOSE_SPK; @@ -390,6 +394,62 @@ int32_t DAudioSourceDev::HandlePlayStatusChange(const AudioEvent &event) } } +int32_t DAudioSourceDev::HandleSpkMmapStart(const AudioEvent &event) +{ + DHLOGI("Spk mmap start, content: %s.", event.content.c_str()); + if (speaker_ == nullptr) { + DHLOGE("Spk mmap start, speaker is nullptr."); + return ERR_DH_AUDIO_NULLPTR; + } + int32_t ret = speaker_->MmapStart(); + if (ret != DH_SUCCESS) { + DHLOGE("Spk mmap start fail, error code: %d.", ret); + } + return ret; +} + +int32_t DAudioSourceDev::HandleSpkMmapStop(const AudioEvent &event) +{ + DHLOGI("Spk mmap stop, content: %s.", event.content.c_str()); + if (speaker_ == nullptr) { + DHLOGE("Spk mmap stop, speaker is nullptr."); + return ERR_DH_AUDIO_NULLPTR; + } + int32_t ret = speaker_->MmapStop(); + if (ret != DH_SUCCESS) { + DHLOGE("Spk mmap stop fail, error code: %d.", ret); + } + return ret; +} + +int32_t DAudioSourceDev::HandleMicMmapStart(const AudioEvent &event) +{ + DHLOGI("Mic mmap start, content: %s.", event.content.c_str()); + if (mic_ == nullptr) { + DHLOGE("Mic mmap start, speaker is nullptr."); + return ERR_DH_AUDIO_NULLPTR; + } + int32_t ret = mic_ ->MmapStart(); + if (ret != DH_SUCCESS) { + DHLOGE("Mic mmap start fail, error code: %d.", ret); + } + return ret; +} + +int32_t DAudioSourceDev::HandleMicMmapStop(const AudioEvent &event) +{ + DHLOGI("Mic mmap stop, content: %s.", event.content.c_str()); + if (mic_ == nullptr) { + DHLOGE("mic mmap stop, speaker is nullptr."); + return ERR_DH_AUDIO_NULLPTR; + } + int32_t ret = mic_ ->MmapStop(); + if (ret != DH_SUCCESS) { + DHLOGE("Mic mmap stop fail, error code: %d.", ret); + } + return ret; +} + int32_t DAudioSourceDev::WaitForRPC(const AudioEventType type) { std::unique_lock lck(rpcWaitMutex_); diff --git a/services/audiomanager/managersource/src/dmic_dev.cpp b/services/audiomanager/managersource/src/dmic_dev.cpp index 93f46ba0ecc7dde1332a71713636925e95e4516c..960721f3c0a2e9c2988cbe225f29d037da654666 100644 --- a/services/audiomanager/managersource/src/dmic_dev.cpp +++ b/services/audiomanager/managersource/src/dmic_dev.cpp @@ -234,6 +234,12 @@ int32_t DMicDev::Stop() int32_t DMicDev::Release() { DHLOGI("Release mic device."); + if (ashmem_ != nullptr) { + ashmem_->UnmapAshmem(); + ashmem_->CloseAshmem(); + ashmem_ = nullptr; + DHLOGI("UnInit ashmem success."); + } if (micTrans_ == nullptr) { DHLOGE("Mic trans is null."); return DH_SUCCESS; @@ -277,6 +283,104 @@ int32_t DMicDev::ReadStreamData(const std::string &devId, const int32_t dhId, st return DH_SUCCESS; } +int32_t DMicDev::ReadMmapPosition(const std::string &devId, const int32_t dhId, + uint64_t frames, CurrentTimeHDF &time) +{ + DHLOGI("Read mmap position. frames: %lu, tvsec: %lu, tvNSec:%lu", + writeNum_, writeTvSec_, writeTvNSec_); + frames = writeNum_; + time.tvSec = writeTvSec_; + time.tvNSec = writeTvNSec_; + return DH_SUCCESS; +} + +int32_t DMicDev::RefreshAshmemInfo(const std::string &devId, const int32_t dhId, + int32_t fd, int32_t ashmemLength, int32_t lengthPerTrans) +{ + DHLOGI("RefreshAshmemInfo: fd:%d, ashmemLength: %d, lengthPerTrans: %d", fd, ashmemLength, lengthPerTrans); + if (param_.captureOpts.capturerFlags == MMAP_MODE) { + DHLOGI("DMic dev low-latency mode"); + if (ashmem_ != nullptr) { + return DH_SUCCESS; + } + ashmem_ = new Ashmem(fd, ashmemLength); + ashmemLength_ = ashmemLength; + lengthPerTrans_ = lengthPerTrans; + DHLOGI("Create ashmem success. fd:%d, ashmem length: %d, lengthPreTrans: %d", + fd, ashmemLength_, lengthPerTrans_); + bool mapRet = ashmem_->MapReadAndWriteAshmem(); + if (!mapRet) { + DHLOGE("Mmap ashmem failed."); + return ERR_DH_AUDIO_NULLPTR; + } + } + return DH_SUCCESS; +} + +int32_t DMicDev::MmapStart() +{ + if (ashmem_ == nullptr) { + DHLOGE("Ashmem is nullptr"); + return ERR_DH_AUDIO_NULLPTR; + } + std::lock_guard lock(writeAshmemMutex_); + frameIndex_ = 0; + startTime_ = 0; + isEnqueueRunning_.store(true); + enqueueDataThread_ = std::thread(&DMicDev::EnqueueThread, this); + if (pthread_setname_np(enqueueDataThread_.native_handle(), ENQUEUE_THREAD) != DH_SUCCESS) { + DHLOGE("Enqueue data thread setname failed."); + } + return DH_SUCCESS; +} + +void DMicDev::EnqueueThread() +{ + writeIndex_ = 0; + writeNum_ = 0; + DHLOGI("Enqueue thread start, lengthPerWrite length: %d.", lengthPerTrans_); + while (ashmem_ != nullptr && isEnqueueRunning_.load()) { + int64_t timeOffset = UpdateTimeOffset(frameIndex_, LOW_LATENCY_INTERVAL_NS, + startTime_); + DHLOGD("Write frameIndex: %lld, timeOffset: %lld.", frameIndex_, timeOffset); + std::shared_ptr audioData = nullptr; + { + std::lock_guard lock(dataQueueMtx_); + if (dataQueue_.empty()) { + DHLOGI("Data queue is Empty."); + audioData = std::make_shared(param_.comParam.frameSize); + } else { + audioData = dataQueue_.front(); + dataQueue_.pop(); + } + } + bool writeRet = ashmem_->WriteToAshmem(audioData->Data(), audioData->Size(), writeIndex_); + if (writeRet) { + DHLOGD("Write to ashmem success! write index: %d, writeLength: %d.", writeIndex_, lengthPerTrans_); + } else { + DHLOGE("Write data to ashmem failed."); + } + writeIndex_ += lengthPerTrans_; + if (writeIndex_ >= ashmemLength_) { + writeIndex_ = 0; + } + writeNum_ += static_cast(CalculateSampleNum(param_.comParam.sampleRate, timeInterval_)); + GetCurrentTime(writeTvSec_, writeTvNSec_); + frameIndex_++; + AbsoluteSleep(startTime_ + frameIndex_ * LOW_LATENCY_INTERVAL_NS - timeOffset); + } +} + +int32_t DMicDev::MmapStop() +{ + std::lock_guard lock(writeAshmemMutex_); + isEnqueueRunning_.store(false); + if (enqueueDataThread_.joinable()) { + enqueueDataThread_.join(); + } + return DH_SUCCESS; +} + AudioParam DMicDev::GetAudioParam() const { return param_; diff --git a/services/audiomanager/managersource/src/dspeaker_dev.cpp b/services/audiomanager/managersource/src/dspeaker_dev.cpp index db9eb5dc63d0d9a96ba3fb1a8f366ace5c379918..2876e7a56f790bbd3d89827c35a241addb205c8a 100644 --- a/services/audiomanager/managersource/src/dspeaker_dev.cpp +++ b/services/audiomanager/managersource/src/dspeaker_dev.cpp @@ -229,6 +229,12 @@ int32_t DSpeakerDev::Stop() int32_t DSpeakerDev::Release() { DHLOGI("Release speaker device."); + if (ashmem_ != nullptr) { + ashmem_->UnmapAshmem(); + ashmem_->CloseAshmem(); + ashmem_ = nullptr; + DHLOGI("UnInit ashmem success."); + } if (speakerTrans_ == nullptr) { DHLOGE("Speaker trans is null."); return DH_SUCCESS; @@ -304,6 +310,99 @@ int32_t DSpeakerDev::WriteStreamData(const std::string &devId, const int32_t dhI return DH_SUCCESS; } +int32_t DSpeakerDev::ReadMmapPosition(const std::string &devId, const int32_t dhId, + uint64_t frames, CurrentTimeHDF &time) +{ + DHLOGI("Read mmap position. frames: %lu, tvsec: %lu, tvNSec:%lu", + readNum_, readTvSec_, readTvNSec_); + frames = readNum_; + time.tvSec = readTvSec_; + time.tvNSec = readTvNSec_; + return DH_SUCCESS; +} +int32_t DSpeakerDev::RefreshAshmemInfo(const std::string &devId, const int32_t dhId, + int32_t fd, int32_t ashmemLength, int32_t lengthPerTrans) +{ + DHLOGI("RefreshAshmemInfo: fd:%d, ashmemLength: %d, lengthPerTrans: %d", fd, ashmemLength, lengthPerTrans); + if (param_.renderOpts.renderFlags == MMAP_MODE) { + DHLOGI("DSpeaker dev low-latency mode"); + if (ashmem_ != nullptr) { + return DH_SUCCESS; + } + ashmem_ = new Ashmem(fd, ashmemLength); + ashmemLength_ = ashmemLength; + lengthPerTrans_ = lengthPerTrans; + DHLOGI("Create ashmem success. fd:%d, ashmem length: %d, lengthPreTrans: %d", + fd, ashmemLength_, lengthPerTrans_); + bool mapRet = ashmem_->MapReadAndWriteAshmem(); + if (!mapRet) { + DHLOGE("Mmap ashmem failed."); + return ERR_DH_AUDIO_NULLPTR; + } + } + return DH_SUCCESS; +} + +int32_t DSpeakerDev::MmapStart() +{ + if (ashmem_ == nullptr) { + DHLOGE("Ashmem is nullptr"); + return ERR_DH_AUDIO_NULLPTR; + } + isEnqueueRunning_.store(true); + enqueueDataThread_ = std::thread(&DSpeakerDev::EnqueueThread, this); + if (pthread_setname_np(enqueueDataThread_.native_handle(), ENQUEUE_THREAD) != DH_SUCCESS) { + DHLOGE("Enqueue data thread setname failed."); + } + return DH_SUCCESS; +} + +void DSpeakerDev::EnqueueThread() +{ + readIndex_ = 0; + readNum_ = 0; + DHLOGI("Enqueue thread start, lengthPerRead length: %d.", lengthPerTrans_); + while (ashmem_ != nullptr && isEnqueueRunning_.load()) { + int64_t timeOffset = UpdateTimeOffset(frameIndex_, LOW_LATENCY_INTERVAL_NS, + startTime_); + DHLOGD("Read frameIndex: %lld, timeOffset: %lld.", frameIndex_, timeOffset); + auto readData = ashmem_->ReadFromAshmem(lengthPerTrans_, readIndex_); + DHLOGD("Read from ashmem success! read index: %d, readLength: %d.", readIndex_, lengthPerTrans_); + std::shared_ptr audioData = std::make_shared(lengthPerTrans_); + if (readData != nullptr) { + const uint8_t *readAudioData = reinterpret_cast(readData); + if (memcpy_s(audioData->Data(), audioData->Capacity(), readAudioData, param_.comParam.frameSize) != EOK) { + DHLOGE("Copy audio data failed."); + } + } + if (speakerTrans_ == nullptr) { + DHLOGE("Speaker enqueue thread, trans is nullptr."); + return; + } + int32_t ret = speakerTrans_->FeedAudioData(audioData); + if (ret != DH_SUCCESS) { + DHLOGE("Speaker enqueue thread, write stream data failed, ret: %d.", ret); + } + readIndex_ += lengthPerTrans_; + if (readIndex_ >= ashmemLength_) { + readIndex_ = 0; + } + readNum_ += static_cast(CalculateSampleNum(param_.comParam.sampleRate, timeInterval_)); + GetCurrentTime(readTvSec_, readTvNSec_); + frameIndex_++; + AbsoluteSleep(startTime_ + frameIndex_ * LOW_LATENCY_INTERVAL_NS - timeOffset); + } +} + +int32_t DSpeakerDev::MmapStop() +{ + isEnqueueRunning_.store(false); + if (enqueueDataThread_.joinable()) { + enqueueDataThread_.join(); + } + return DH_SUCCESS; +} + AudioParam DSpeakerDev::GetAudioParam() const { return param_; diff --git a/services/audioprocessor/directprocessor/include/audio_direct_processor.h b/services/audioprocessor/directprocessor/include/audio_direct_processor.h new file mode 100644 index 0000000000000000000000000000000000000000..eb8debbcdf8a280ad771a6c9059e329c2096f19a --- /dev/null +++ b/services/audioprocessor/directprocessor/include/audio_direct_processor.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef OHOS_IAUDIO_DIRECT_PROCESSOR_H +#define OHOS_IAUDIO_DIRECT_PROCESSOR_H + +#include + +#include "audio_data.h" +#include "audio_event.h" +#include "audio_param.h" +#include "iaudio_processor.h" +#include "iaudio_processor_callback.h" + +namespace OHOS { +namespace DistributedHardware { +class AudioDirectProcessor : public IAudioProcessor, + public std::enable_shared_from_this { +public: + AudioDirectProcessor() = default; + ~AudioDirectProcessor() =default; + + int32_t ConfigureAudioProcessor(const AudioCommonParam &localDevParam, const AudioCommonParam &remoteDevParam, + const std::shared_ptr &procCallback) override; + int32_t ReleaseAudioProcessor() override; + int32_t StartAudioProcessor() override; + int32_t StopAudioProcessor() override; + int32_t FeedAudioProcessor(const std::shared_ptr &inputData) override; + +private: + std::weak_ptr procCallback_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_IAUDIO_DIRECT_PROCESSOR_H diff --git a/services/audioprocessor/directprocessor/src/audio_direct_processor.cpp b/services/audioprocessor/directprocessor/src/audio_direct_processor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..02a360f6a45f481159e47f6b4f2cf0ec9328d381 --- /dev/null +++ b/services/audioprocessor/directprocessor/src/audio_direct_processor.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * 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 "audio_direct_processor.h" + +#include "daudio_errorcode.h" +#include "daudio_hisysevent.h" +#include "daudio_hitrace.h" +#include "daudio_log.h" + +#undef DH_LOG_TAG +#define DH_LOG_TAG "AudioDirectProcessor" + +namespace OHOS { +namespace DistributedHardware { +int32_t AudioDirectProcessor::ConfigureAudioProcessor(const AudioCommonParam &localDevParam, + const AudioCommonParam &remoteDevParam, const std::shared_ptr &procCallback) +{ + DHLOGI("Configure direct audio processor."); + if (procCallback == nullptr) { + DHLOGE("Processor callback is null."); + return ERR_DH_AUDIO_BAD_VALUE; + } + + procCallback_ = procCallback; + return DH_SUCCESS; +} + +int32_t AudioDirectProcessor::ReleaseAudioProcessor() +{ + DHLOGI("Release direct audio processor."); + return DH_SUCCESS; +} + +int32_t AudioDirectProcessor::StartAudioProcessor() +{ + DHLOGI("Start direct audio processor."); + return DH_SUCCESS; +} + +int32_t AudioDirectProcessor::StopAudioProcessor() +{ + DHLOGI("Stop direct audio processor."); + return DH_SUCCESS; +} + +int32_t AudioDirectProcessor::FeedAudioProcessor(const std::shared_ptr &inputData) +{ + DHLOGD("Feed audio processor."); + if (inputData == nullptr) { + DHLOGE("Input data is null."); + return ERR_DH_AUDIO_BAD_VALUE; + } + + auto cbObj = procCallback_.lock(); + if (cbObj == nullptr) { + DHLOGE("Processor callback is null."); + return ERR_DH_AUDIO_BAD_VALUE; + } + cbObj->OnAudioDataDone(inputData); + return DH_SUCCESS; +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/audiotransport/decodetransport/BUILD.gn b/services/audiotransport/decodetransport/BUILD.gn index 077491ab7351054af0416e7b6de5f92db3c35f97..2d14492f9f737f146521bf7fff40eb3ffac98654 100644 --- a/services/audiotransport/decodetransport/BUILD.gn +++ b/services/audiotransport/decodetransport/BUILD.gn @@ -44,6 +44,7 @@ ohos_shared_library("distributed_audio_decode_transport") { "${common_path}/dfx_utils/include", "${audio_processor_path}/decoder/include", "${audio_processor_path}/decodeprocessor/include", + "${audio_processor_path}/directprocessor/include", "${audio_processor_path}/interface", "${audio_transport_path}/audiochannel/interface", "${audio_transport_path}/audiochannel/audiodatachannel/include", @@ -61,6 +62,7 @@ ohos_shared_library("distributed_audio_decode_transport") { "${audio_processor_path}/decodeprocessor/src/audio_decoder_processor.cpp", "${audio_processor_path}/decoder/src/audio_decoder.cpp", "${audio_processor_path}/decoder/src/audio_decoder_callback.cpp", + "${audio_processor_path}/directprocessor/src/audio_direct_processor.cpp", "${services_path}/common/audiodata/src/audio_data.cpp", "src/audio_decode_transport.cpp", ] diff --git a/services/audiotransport/decodetransport/src/audio_decode_transport.cpp b/services/audiotransport/decodetransport/src/audio_decode_transport.cpp index ce6bd135b33ee3fed2f081fad830d1e31f510ba9..c1b4da3d7589a0c73c90ba694a1b173c9a62ebf6 100644 --- a/services/audiotransport/decodetransport/src/audio_decode_transport.cpp +++ b/services/audiotransport/decodetransport/src/audio_decode_transport.cpp @@ -17,6 +17,7 @@ #include "audio_data_channel.h" #include "audio_decoder_processor.h" +#include "audio_direct_processor.h" #include "audio_param.h" #include "daudio_errorcode.h" #include "daudio_log.h" @@ -237,7 +238,13 @@ int32_t AudioDecodeTransport::RegisterChannelListener(const PortCapType capType) int32_t AudioDecodeTransport::RegisterProcessorListener(const AudioParam &localParam, const AudioParam &remoteParam) { DHLOGI("Register processor listener."); - processor_ = std::make_shared(); + if (localParam.renderOpts.renderFlags == MMAP_MODE || localParam.captureOpts.capturerFlags == MMAP_MODE) { + DHLOGI("Use direct processor, renderFlags: %d, capturerFlags: %d.", + localParam.renderOpts.renderFlags, localParam.captureOpts.capturerFlags); + processor_ = std::make_shared(); + } else { + processor_ = std::make_shared(); + } int32_t ret = processor_->ConfigureAudioProcessor(localParam.comParam, remoteParam.comParam, shared_from_this()); if (ret != DH_SUCCESS) { DHLOGE("Configure audio processor failed."); diff --git a/services/audiotransport/encodetransport/BUILD.gn b/services/audiotransport/encodetransport/BUILD.gn index f302209f0e3519baad7e237fe60d4c48ae87383e..cd3eb0209c0b33948476c081e0a2a61863b4fcc3 100644 --- a/services/audiotransport/encodetransport/BUILD.gn +++ b/services/audiotransport/encodetransport/BUILD.gn @@ -43,6 +43,7 @@ ohos_shared_library("distributed_audio_encode_transport") { "${common_path}/include", "${common_path}/dfx_utils/include", "${audio_processor_path}/encodeprocessor/include", + "${audio_processor_path}/directprocessor/include", "${audio_processor_path}/encoder/include", "${audio_processor_path}/interface", "${audio_transport_path}/audiochannel/interface", @@ -58,6 +59,7 @@ ohos_shared_library("distributed_audio_encode_transport") { public_configs = [ ":encode_transport_pub_config" ] sources = [ + "${audio_processor_path}/directprocessor/src/audio_direct_processor.cpp", "${audio_processor_path}/encodeprocessor/src/audio_encoder_processor.cpp", "${audio_processor_path}/encoder/src/audio_encoder.cpp", "${audio_processor_path}/encoder/src/audio_encoder_callback.cpp", diff --git a/services/audiotransport/encodetransport/src/audio_encode_transport.cpp b/services/audiotransport/encodetransport/src/audio_encode_transport.cpp index 8f1bcbf6fa25b1601514ce7c3e45957bfa1e91cf..79f6d3c74c27ec495049ae3423b20bfbb939d2c2 100644 --- a/services/audiotransport/encodetransport/src/audio_encode_transport.cpp +++ b/services/audiotransport/encodetransport/src/audio_encode_transport.cpp @@ -17,6 +17,7 @@ #include "audio_data_channel.h" #include "audio_encoder_processor.h" +#include "audio_direct_processor.h" #include "audio_param.h" #include "daudio_errorcode.h" #include "daudio_log.h" @@ -187,7 +188,13 @@ int32_t AudioEncodeTransport::RegisterChannelListener(const PortCapType capType) int32_t AudioEncodeTransport::RegisterProcessorListener(const AudioParam &localParam, const AudioParam &remoteParam) { DHLOGI("Register processor listener."); - processor_ = std::make_shared(); + if (localParam.renderOpts.renderFlags == MMAP_MODE || localParam.captureOpts.capturerFlags == MMAP_MODE) { + DHLOGI("Use direct processor, renderFlags: %d, capturerFlags: %d.", + localParam.renderOpts.renderFlags, localParam.captureOpts.capturerFlags); + processor_ = std::make_shared(); + } else { + processor_ = std::make_shared(); + } if (audioChannel_ == nullptr) { DHLOGE("Create audio processor failed."); return ERR_DH_AUDIO_TRANS_ERROR; diff --git a/services/common/audioparam/audio_event.h b/services/common/audioparam/audio_event.h index 6952ae2ce76be3d527b7019f0b27ec0b57431b0b..9850537a8155b0ed32238a6ef3d47eb4125e1c37 100644 --- a/services/common/audioparam/audio_event.h +++ b/services/common/audioparam/audio_event.h @@ -63,6 +63,10 @@ typedef enum { CHANGE_PLAY_STATUS = 71, + MMAP_SPK_START = 81, + MMAP_SPK_STOP = 82, + MMAP_MIC_START = 83, + MMAP_MIC_STOP = 84, AUDIO_START = 85, AUDIO_STOP = 86, } AudioEventType;