diff --git a/frameworks/BUILD.gn b/frameworks/BUILD.gn index 0d14ae3553afd8d8bb12f890f337130f71577cc9..4e4298a763e1eecf7ea818987f600b7382e4d31f 100755 --- a/frameworks/BUILD.gn +++ b/frameworks/BUILD.gn @@ -16,6 +16,34 @@ import("//build/lite/ndk/ndk.gni") shared_library("audio_capturer_lite") { sources = [ "audio_capturer.cpp", + "audio_capturer_client.cpp", + ] + + cflags = [ "-fPIC" ] + cflags += [ "-Wall" ] + cflags_cc = cflags + include_dirs = [ + "//foundation/multimedia/audio_lite/interfaces/kits", + "//foundation/multimedia/audio_lite/services/include", + "//foundation/multimedia/utils/lite/interfaces/kits", + "//foundation/multimedia/audio_lite/frameworks", + "//foundation/distributedschedule/samgr_lite/interfaces/kits/registry", + "//base/security/permission/interfaces/kits/permission_lite", + "//foundation/distributedschedule/samgr_lite/interfaces/kits/registry", + "//foundation/distributedschedule/samgr_lite/interfaces/kits/samgr", + ] + + deps = [ + "//base/security/permission/services/permission_lite/pms_client:pms_client", + "//foundation/communication/ipc_lite:liteipc_adapter", + "//foundation/graphic/surface:lite_surface", + "//foundation/multimedia/utils/lite:media_common", + "//third_party/bounds_checking_function:libsec_shared", + ] +} + +shared_library("audio_capturer_impl") { + sources = [ "audio_capturer_impl.cpp", "audio_encoder/audio_encoder.cpp", "audio_source/audio_source.cpp", @@ -24,11 +52,14 @@ shared_library("audio_capturer_lite") { cflags += [ "-Wall" ] cflags_cc = cflags include_dirs = [ - "audio_encoder/include", - "audio_source/include", - "//foundation/multimedia/utils/lite/hals", + "//foundation/multimedia/audio_lite/frameworks/audio_encoder/include", + "//foundation/multimedia/audio_lite/frameworks/audio_source/include", + "//foundation/multimedia/audio_lite/frameworks", + "//foundation/multimedia/audio_lite/interfaces/kits", + "//foundation/multimedia/audio_lite/services/include", "//drivers/peripheral/audio/interfaces/include", "//drivers/peripheral/codec/interfaces/include", + "//foundation/multimedia/utils/lite/interfaces/kits", "//drivers/peripheral/format/interfaces/include", ] @@ -38,6 +69,7 @@ shared_library("audio_capturer_lite") { "-L$outdir", "-lcodec", "-laudio_hw", + "-lpthread", ] deps = [ "//foundation/graphic/surface:lite_surface", diff --git a/frameworks/audio_capturer.cpp b/frameworks/audio_capturer.cpp index 2e1eeadcdf786601462625ec9c7ec87f91a33362..f1801c3b3ff9ddba7ee6d18c39588adcbda46827 100755 --- a/frameworks/audio_capturer.cpp +++ b/frameworks/audio_capturer.cpp @@ -15,6 +15,7 @@ #include "audio_capturer.h" #include "audio_capturer_impl.h" +#include "audio_capturer_client.h" #include "media_log.h" namespace OHOS { @@ -28,7 +29,7 @@ namespace Audio { } while (0) AudioCapturer::AudioCapturer() - : impl_(new(std::nothrow) AudioCapturerImpl()) + : impl_(new(std::nothrow) AudioCapturerClient()) { } @@ -36,9 +37,10 @@ AudioCapturer::~AudioCapturer() { } -bool AudioCapturer::GetMinFrameCount(int32_t sampleRate, int32_t channelCount, AudioCodecFormat audioFormat, size_t &frameCount) +bool AudioCapturer::GetMinFrameCount(int32_t sampleRate, int32_t channelCount, AudioCodecFormat audioFormat, + size_t &frameCount) { - return AudioCapturerImpl::GetMinFrameCount(sampleRate, channelCount, audioFormat, frameCount); + return AudioCapturerClient::GetMinFrameCount(sampleRate, channelCount, audioFormat, frameCount); } uint64_t AudioCapturer::GetFrameCount() @@ -56,7 +58,7 @@ State AudioCapturer::GetStatus() bool AudioCapturer::GetAudioTime(Timestamp ×tamp, Timestamp::Timebase base) { CHK_NULL_RETURN(impl_, false); - return impl_->GetTimestamp(timestamp, base); + return impl_->GetAudioTime(timestamp, base); } int32_t AudioCapturer::SetCapturerInfo(const AudioCapturerInfo info) @@ -74,7 +76,7 @@ int32_t AudioCapturer::GetCapturerInfo(AudioCapturerInfo &info) bool AudioCapturer::Start() { CHK_NULL_RETURN(impl_, false); - return impl_->Record(); + return impl_->Start(); } bool AudioCapturer::Stop() diff --git a/frameworks/audio_capturer_client.cpp b/frameworks/audio_capturer_client.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e3ff4bccf06386a5b842355498e2ce6246f4df3d --- /dev/null +++ b/frameworks/audio_capturer_client.cpp @@ -0,0 +1,370 @@ +/* + * Copyright (c) 2020-2021 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_capturer_client.h" +#include +#include "audio_capturer_server.h" +#include "liteipc_adapter.h" +#include "media_log.h" +#include "samgr_lite.h" +#include "securec.h" +#include "surface_impl.h" + +extern "C" void __attribute__((weak)) OHOS_SystemInit(void) +{ + SAMGR_Bootstrap(); +} + +using namespace OHOS::Media; +using namespace std; +namespace OHOS { +namespace Audio { +constexpr int32_t SURFACE_QUEUE_SIZE = 5; +constexpr int32_t SURFACE_SIZE = 8192; +constexpr int32_t SURFACE_HEIGHT = 1; +constexpr int32_t SURFACE_WIDTH = 8192; + +struct CallBackPara { + int funcId; + int32_t ret; + void* data; +}; + + +AudioCapturer::AudioCapturerClient *AudioCapturer::AudioCapturerClient::GetInstance() +{ + static AudioCapturerClient client; + return &client; +} + +static int32_t ProxyCallbackFunc(void *owner, int code, IpcIo *reply) +{ + if (code != 0) { + MEDIA_ERR_LOG("callback error, code = %d", code); + return -1; + } + + if (owner == nullptr) { + return -1; + } + + CallBackPara* para = (CallBackPara*)owner; + AudioCapturerFuncId funcId = (AudioCapturerFuncId)para->funcId; + para->ret = IpcIoPopInt32(reply); + switch (funcId) { + case AUD_CAP_FUNC_CONNECT: + case AUD_CAP_FUNC_DISCONNECT: + case AUD_CAP_FUNC_SET_INFO: + case AUD_CAP_FUNC_START: + case AUD_CAP_FUNC_STOP: + case AUD_CAP_FUNC_RELEASE: + case AUD_CAP_FUNC_SET_SURFACE: + break; + case AUD_CAP_FUNC_GET_FRAME_COUNT: + (*(uint64_t *)para->data) = IpcIoPopUint64(reply); + break; + case AUD_CAP_FUNC_GET_STATUS: + (*(uint32_t *)para->data) = IpcIoPopUint32(reply); + break; + case AUD_CAP_FUNC_GET_INFO: { + uint32_t size = 0; + void *bufferAdd = IpcIoPopFlatObj(reply, &size); + if (bufferAdd == nullptr || size == 0) { + MEDIA_INFO_LOG("IpcIoPopFlatObj info failed"); + return -1; + } + memcpy_s(para->data, sizeof(AudioCapturerInfo), bufferAdd, size); + break; + } + case AUD_CAP_FUNC_GET_MIN_FRAME_COUNT: + (*(uint32_t *)para->data) = IpcIoPopUint32(reply); + break; + default : + MEDIA_INFO_LOG("Callback, unkown funcId = %d", para->funcId); + break; + } + return 0; +} + +int32_t AudioCapturer::AudioCapturerClient::InitSurface(void) +{ + MEDIA_DEBUG_LOG("AudioCapturerClient InitSurface"); + Surface *surface = Surface::CreateSurface(); + if (surface == nullptr) { + return -1; + } + + surface->RegisterConsumerListener(*this); + surface_.reset(surface); + + surface->SetWidthAndHeight(SURFACE_WIDTH, SURFACE_HEIGHT); + surface->SetQueueSize(SURFACE_QUEUE_SIZE); + surface->SetSize(SURFACE_SIZE); + return 0; +} + +AudioCapturer::AudioCapturerClient::AudioCapturerClient() +{ + OHOS_SystemInit(); + IpcIo io; + uint8_t tmpData[DEFAULT_IPC_SIZE]; + IUnknown *iUnknown = SAMGR_GetInstance()->GetDefaultFeatureApi(AUDIO_CAPTURER_SERVICE_NAME); + if (iUnknown == nullptr) { + MEDIA_ERR_LOG("iUnknown is NULL"); + throw runtime_error("Ipc proxy GetDefaultFeatureApi failed."); + } + + (void)iUnknown->QueryInterface(iUnknown, CLIENT_PROXY_VER, (void **)&proxy_); + if (proxy_ == nullptr) { + MEDIA_ERR_LOG("QueryInterface failed"); + throw runtime_error("Ipc proxy init failed."); + } + + IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0); + CallBackPara para = {.funcId = AUD_CAP_FUNC_CONNECT, .ret = MEDIA_IPC_FAILED, .data = this}; + int32_t ret = proxy_->Invoke(proxy_, AUD_CAP_FUNC_CONNECT, nullptr, ¶, ProxyCallbackFunc); + if (ret != 0) { + MEDIA_ERR_LOG("Connect audio capturer server failed, ret=%d", ret); + throw runtime_error("Ipc proxy Invoke failed."); + } + + /* Creating a Surface and Initializing Settings */ + MEDIA_DEBUG_LOG("InitSurface audio capturer."); + InitSurface(); + /* The surface is transferred to the server for processing */ + timeStampValid_ = false; + IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 1); + dynamic_cast(surface_.get())->WriteIoIpcIo(io); + para = {.funcId = AUD_CAP_FUNC_SET_SURFACE, .ret = MEDIA_IPC_FAILED, .data = this}; + ret = proxy_->Invoke(proxy_, AUD_CAP_FUNC_SET_SURFACE, &io, ¶, ProxyCallbackFunc); + if (ret != 0) { + MEDIA_ERR_LOG("Connect audio capturer set surface failed, ret=%d", ret); + throw runtime_error("Ipc proxy Invoke failed."); + } + + MEDIA_INFO_LOG("Create audio capturer client succeed."); +} + +void AudioCapturer::AudioCapturerClient::ReleaseAllBuffer() +{ + timeStampValid_ = false; + while (true) { + SurfaceBuffer *surfaceBuf = surface_->AcquireBuffer(); + if (surfaceBuf == nullptr) { + break; + } + surface_->ReleaseBuffer(surfaceBuf); + } +} + +AudioCapturer::AudioCapturerClient::~AudioCapturerClient() +{ + IpcIo io; + uint8_t tmpData[DEFAULT_IPC_SIZE]; + IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0); + CallBackPara para = {.funcId = AUD_CAP_FUNC_DISCONNECT, .ret = MEDIA_IPC_FAILED}; + uint32_t ret = proxy_->Invoke(proxy_, AUD_CAP_FUNC_DISCONNECT, &io, ¶, ProxyCallbackFunc); + if (ret != 0) { + MEDIA_ERR_LOG("Disconnect audioCapturer server failed, ret=%d", ret); + } + + /* release all surface buffer */ + ReleaseAllBuffer(); + surface_.reset(); + surface_ = nullptr; + MEDIA_INFO_LOG("dector"); +} + +bool AudioCapturer::AudioCapturerClient::GetMinFrameCount(int32_t sampleRate, int32_t channelCount, + AudioCodecFormat audioFormat, size_t &frameCount) +{ + AudioCapturerClient *client = AudioCapturer::AudioCapturerClient::GetInstance(); + IpcIo io; + uint8_t tmpData[DEFAULT_IPC_SIZE]; + IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0); + IpcIoPushInt32(&io, sampleRate); + IpcIoPushInt32(&io, channelCount); + IpcIoPushFlatObj(&io, &audioFormat, sizeof(audioFormat)); + CallBackPara para = {.funcId = AUD_CAP_FUNC_GET_MIN_FRAME_COUNT, .ret = MEDIA_IPC_FAILED, .data = &frameCount}; + uint32_t ret = client->proxy_->Invoke(client->proxy_, AUD_CAP_FUNC_GET_MIN_FRAME_COUNT, &io, ¶, + ProxyCallbackFunc); + if (ret != 0) { + MEDIA_ERR_LOG("GetMinFrameCount failed, ret=%d", ret); + return false; + } + return (para.ret == 0) ? true : false; +} + +uint64_t AudioCapturer::AudioCapturerClient::GetFrameCount() +{ + IpcIo io; + uint64_t frameCount; + uint8_t tmpData[DEFAULT_IPC_SIZE]; + IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0); + CallBackPara para = {.funcId = AUD_CAP_FUNC_GET_FRAME_COUNT, .ret = MEDIA_IPC_FAILED, .data = &frameCount}; + uint32_t ret = proxy_->Invoke(proxy_, AUD_CAP_FUNC_GET_FRAME_COUNT, &io, ¶, ProxyCallbackFunc); + if (ret != 0) { + MEDIA_ERR_LOG("GetFrameCount failed, ret=%d", ret); + } + + return frameCount; +} + +State AudioCapturer::AudioCapturerClient::GetStatus() +{ + IpcIo io; + uint32_t state; + uint8_t tmpData[DEFAULT_IPC_SIZE]; + IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0); + CallBackPara para = {.funcId = AUD_CAP_FUNC_GET_STATUS, .ret = MEDIA_IPC_FAILED, .data = &state}; + uint32_t ret = proxy_->Invoke(proxy_, AUD_CAP_FUNC_GET_STATUS, &io, ¶, ProxyCallbackFunc); + if (ret != 0) { + MEDIA_ERR_LOG("GetStatus failed, ret=%d", ret); + } + + return (State)state; +} + +bool AudioCapturer::AudioCapturerClient::GetAudioTime(Timestamp ×tamp, Timestamp::Timebase base) +{ + timestamp = curTimestamp_; + return true; +} + +int32_t AudioCapturer::AudioCapturerClient::SetCapturerInfo(const AudioCapturerInfo info) +{ + IpcIo io; + uint8_t tmpData[DEFAULT_IPC_SIZE]; + IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0); + IpcIoPushFlatObj(&io, &info, sizeof(info)); + + CallBackPara para = {.funcId = AUD_CAP_FUNC_SET_INFO, .ret = MEDIA_IPC_FAILED}; + int32_t ret = proxy_->Invoke(proxy_, AUD_CAP_FUNC_SET_INFO, &io, ¶, ProxyCallbackFunc); + if (ret != 0) { + MEDIA_ERR_LOG("SetCapturerInfo failed, ret=%d", ret); + return ret; + } + return para.ret; +} + +int32_t AudioCapturer::AudioCapturerClient::GetCapturerInfo(AudioCapturerInfo &info) +{ + IpcIo io; + uint8_t tmpData[DEFAULT_IPC_SIZE]; + IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0); + CallBackPara para = {.funcId = AUD_CAP_FUNC_GET_INFO, .ret = MEDIA_IPC_FAILED}; + int32_t ret = proxy_->Invoke(proxy_, AUD_CAP_FUNC_GET_INFO, &io, ¶, ProxyCallbackFunc); + if (ret != 0) { + MEDIA_ERR_LOG("GetCapturerInfo failed, ret=%d", ret); + return ret; + } + return para.ret; +} + +bool AudioCapturer::AudioCapturerClient::Start() +{ + IpcIo io; + uint8_t tmpData[DEFAULT_IPC_SIZE]; + IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0); + CallBackPara para = {.funcId = AUD_CAP_FUNC_START, .ret = MEDIA_IPC_FAILED}; + int32_t ret = proxy_->Invoke(proxy_, AUD_CAP_FUNC_START, &io, ¶, ProxyCallbackFunc); + if (ret != 0) { + MEDIA_ERR_LOG("Start failed, ret=%d", ret); + return ret; + } + + return para.ret; +} + +bool AudioCapturer::AudioCapturerClient::Stop() +{ + IpcIo io; + uint8_t tmpData[DEFAULT_IPC_SIZE]; + IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0); + CallBackPara para = {.funcId = AUD_CAP_FUNC_STOP, .ret = MEDIA_IPC_FAILED}; + int32_t ret = proxy_->Invoke(proxy_, AUD_CAP_FUNC_STOP, &io, ¶, ProxyCallbackFunc); + if (ret != 0) { + MEDIA_ERR_LOG("Stop failed, ret=%d", ret); + return ret; + } + + return para.ret; +} + +bool AudioCapturer::AudioCapturerClient::Release() +{ + IpcIo io; + uint8_t tmpData[DEFAULT_IPC_SIZE]; + IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0); + CallBackPara para = {.funcId = AUD_CAP_FUNC_RELEASE, .ret = MEDIA_IPC_FAILED}; + int32_t ret = proxy_->Invoke(proxy_, AUD_CAP_FUNC_RELEASE, &io, ¶, ProxyCallbackFunc); + if (ret != 0) { + MEDIA_ERR_LOG("Release failed, ret=%d", ret); + return ret; + } + return para.ret; +} + +int32_t AudioCapturer::AudioCapturerClient::Read(uint8_t *buffer, size_t userSize, bool isBlockingRead) +{ + if (buffer == NULL || userSize == 0) { + return ERR_INVALID_READ; + } + int32_t readLen = ERR_INVALID_READ; + do { + SurfaceBuffer *surfaceBuf = surface_->AcquireBuffer(); + if (surfaceBuf == nullptr) { + if (isBlockingRead) { + usleep(10000); // indicates 10000 microseconds + continue; + } else { + break; + } + } + + uint8_t *buf = static_cast (surfaceBuf->GetVirAddr()); + int32_t dataSize = surfaceBuf->GetSize(); + if (dataSize - sizeof(Timestamp) > userSize) { + surface_->ReleaseBuffer(surfaceBuf); + MEDIA_ERR_LOG("input buffer size too small."); + break; + } + + memcpy_s(buffer, userSize, buf + sizeof(Timestamp), dataSize - sizeof(Timestamp)); + memcpy_s(&curTimestamp_, sizeof(Timestamp), buf, sizeof(Timestamp)); + timeStampValid_ = true; + + surface_->ReleaseBuffer(surfaceBuf); + readLen = dataSize - sizeof(Timestamp); + break; + } while (isBlockingRead); + + return readLen; +} + +void AudioCapturer::AudioCapturerClient::OnBufferAvailable() +{ + if (surface_ == nullptr) { + MEDIA_ERR_LOG("surface is NULL"); + return; + } +} + +IClientProxy *AudioCapturer::AudioCapturerClient::GetIClientProxy() +{ + return proxy_; +} +} // namespace Audio +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/audio_capturer_client.h b/frameworks/audio_capturer_client.h new file mode 100644 index 0000000000000000000000000000000000000000..cae933222980ec81cd71b3a7639230f184bcf423 --- /dev/null +++ b/frameworks/audio_capturer_client.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2020-2021 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 AUDIO_CAPTURER_CLIENT_H +#define AUDIO_CAPTURER_CLIENT_H + +#include +#include "audio_capturer.h" +#include "iproxy_client.h" +#include "media_info.h" +#include "surface.h" + +using OHOS::Surface; +using std::mutex; +using OHOS::SurfaceBuffer; +using OHOS::IBufferConsumerListener; +using OHOS::Audio::Timestamp; +using OHOS::Audio::AudioCapturerInfo; + +namespace OHOS { +namespace Audio { +class AudioCapturer::AudioCapturerClient : public IBufferConsumerListener { +public: + AudioCapturerClient(); + ~AudioCapturerClient(); + static bool GetMinFrameCount(int32_t sampleRate, int32_t channelCount, AudioCodecFormat audioFormat, + size_t &frameCount); + uint64_t GetFrameCount(); + int32_t SetCapturerInfo(const AudioCapturerInfo info); + int32_t GetCapturerInfo(AudioCapturerInfo &info); + bool Start(); + int32_t Read(uint8_t *buffer, size_t userSize, bool isBlockingRead); + State GetStatus(); + bool GetAudioTime(Timestamp ×tamp, Timestamp::Timebase base); + bool Stop(); + bool Release(); + void OnBufferAvailable() override; + static AudioCapturerClient *GetInstance(); + +private: + bool InitAudioCapturerClient(); + IClientProxy *GetIClientProxy(); + int32_t InitSurface(void); + void ReleaseAllBuffer(); + + SvcIdentity sid_; + IClientProxy *proxy_ = nullptr; + std::shared_ptr surface_; + std::mutex lock_; + Timestamp curTimestamp_; + bool timeStampValid_ = false; +}; +} // namespace Audio +} // namespace OHOS +#endif // AUDIO_CAPTURER_CLIENT_H diff --git a/frameworks/audio_capturer_impl.cpp b/frameworks/audio_capturer_impl.cpp index 4f8ac4cb2eb4b307f2d92ced0bce3e9ce9fb95cb..d0906a1aad18136d25589c6f4ee37c637dd65643 100755 --- a/frameworks/audio_capturer_impl.cpp +++ b/frameworks/audio_capturer_impl.cpp @@ -37,14 +37,14 @@ const unsigned long long TIME_CONVERSION_NS_US = 1000ULL; /* ns to us */ } \ } while (0) -AudioCapturer::AudioCapturerImpl::AudioCapturerImpl() +AudioCapturerImpl::AudioCapturerImpl() :audioSource_(new(std::nothrow) AudioSource()), audioEncoder_(nullptr) { MEDIA_DEBUG_LOG("ctor"); } -AudioCapturer::AudioCapturerImpl::~AudioCapturerImpl() +AudioCapturerImpl::~AudioCapturerImpl() { if (status_ != RELEASED) { Release(); @@ -52,12 +52,13 @@ AudioCapturer::AudioCapturerImpl::~AudioCapturerImpl() MEDIA_ERR_LOG("dtor"); } -bool AudioCapturer::AudioCapturerImpl::GetMinFrameCount(int32_t sampleRate, int32_t channelCount, AudioCodecFormat audioFormat, size_t &frameCount) +bool AudioCapturerImpl::GetMinFrameCount(int32_t sampleRate, int32_t channelCount, AudioCodecFormat audioFormat, + size_t &frameCount) { - return AudioSource::GetMinFrameCount(sampleRate, channelCount, audioFormat, frameCount);; + return AudioSource::GetMinFrameCount(sampleRate, channelCount, audioFormat, frameCount); } -uint64_t AudioCapturer::AudioCapturerImpl::GetFrameCount() +uint64_t AudioCapturerImpl::GetFrameCount() { CHK_NULL_RETURN(audioSource_, 0); std::lock_guard lock(mutex_); @@ -68,13 +69,13 @@ uint64_t AudioCapturer::AudioCapturerImpl::GetFrameCount() return audioSource_->GetFrameCount(); } -State AudioCapturer::AudioCapturerImpl::GetStatus() +State AudioCapturerImpl::GetStatus() { std::lock_guard lock(mutex_); return status_; } -bool AudioCapturer::AudioCapturerImpl::GetTimestamp(Timestamp ×tamp, Timestamp::Timebase base) +bool AudioCapturerImpl::GetTimestamp(Timestamp ×tamp, Timestamp::Timebase base) { std::lock_guard lock(mutex_); if (status_ == RELEASED) { @@ -85,7 +86,27 @@ bool AudioCapturer::AudioCapturerImpl::GetTimestamp(Timestamp ×tamp, Timest return true; } -int32_t AudioCapturer::AudioCapturerImpl::SetCapturerInfo(const AudioCapturerInfo info) +static void FillSourceConfig(AudioSourceConfig &sourceConfig, const AudioCapturerInfo &info, uint32_t deviceId) +{ + sourceConfig.deviceId = deviceId; + sourceConfig.audioFormat = info.audioFormat; + sourceConfig.sampleRate = info.sampleRate; + sourceConfig.channelCount = info.channelCount; + sourceConfig.interleaved = false; + sourceConfig.bitWidth = info.bitWidth; + sourceConfig.streamUsage = info.streamType; +} + +static void FillEncConfig(AudioEncodeConfig &encodeConfig, const AudioCapturerInfo &info) +{ + encodeConfig.audioFormat = info.audioFormat; + encodeConfig.bitRate = info.bitRate; + encodeConfig.sampleRate = info.sampleRate; + encodeConfig.channelCount = info.channelCount; + encodeConfig.bitWidth = info.bitWidth; +} + +int32_t AudioCapturerImpl::SetCapturerInfo(const AudioCapturerInfo info) { CHK_NULL_RETURN(audioSource_, ERROR); std::lock_guard lock(mutex_); @@ -101,13 +122,7 @@ int32_t AudioCapturer::AudioCapturerImpl::SetCapturerInfo(const AudioCapturerInf } MEDIA_INFO_LOG("info.sampleRate:%d", info.sampleRate); AudioSourceConfig sourceConfig; - sourceConfig.deviceId = devices[0].deviceId; - sourceConfig.audioFormat = info.audioFormat; - sourceConfig.sampleRate = info.sampleRate; - sourceConfig.channelCount = info.channelCount; - sourceConfig.interleaved = false; - sourceConfig.bitWidth = info.bitWidth; - sourceConfig.streamUsage = info.streamType; + FillSourceConfig(sourceConfig, info, devices[0].deviceId); ret = audioSource_->Initialize(sourceConfig); if (ret != SUCCESS) { MEDIA_ERR_LOG("Initialize failed inputSource:%d", info.inputSource); @@ -115,11 +130,7 @@ int32_t AudioCapturer::AudioCapturerImpl::SetCapturerInfo(const AudioCapturerInf } if (info.audioFormat != PCM && info.audioFormat != AUDIO_DEFAULT) { AudioEncodeConfig encodeConfig; - encodeConfig.audioFormat = info.audioFormat; - encodeConfig.bitRate = info.bitRate; - encodeConfig.sampleRate = info.sampleRate; - encodeConfig.channelCount = info.channelCount; - encodeConfig.bitWidth = info.bitWidth; + FillEncConfig(encodeConfig, info); MEDIA_INFO_LOG("audioEncoder_ bitRate:%d", info.bitRate); std::unique_ptr audioEncoder(new(std::nothrow) AudioEncoder()); audioEncoder_ = std::move(audioEncoder); @@ -140,8 +151,7 @@ int32_t AudioCapturer::AudioCapturerImpl::SetCapturerInfo(const AudioCapturerInf return SUCCESS; } - -int32_t AudioCapturer::AudioCapturerImpl::GetCapturerInfo(AudioCapturerInfo &info) +int32_t AudioCapturerImpl::GetCapturerInfo(AudioCapturerInfo &info) { std::lock_guard lock(mutex_); if (status_ == RELEASED) { @@ -152,7 +162,7 @@ int32_t AudioCapturer::AudioCapturerImpl::GetCapturerInfo(AudioCapturerInfo &inf return SUCCESS; } -bool AudioCapturer::AudioCapturerImpl::Record() +bool AudioCapturerImpl::Record() { CHK_NULL_RETURN(audioSource_, false); std::lock_guard lock(mutex_); @@ -189,9 +199,9 @@ bool AudioCapturer::AudioCapturerImpl::Record() return true; } -int32_t AudioCapturer::AudioCapturerImpl::Read(uint8_t *buffer, size_t userSize, bool isBlockingRead) +int32_t AudioCapturerImpl::Read(uint8_t *buffer, size_t userSize, bool isBlockingRead) { - if (buffer == NULL || userSize == 0) { + if (buffer == nullptr || userSize == 0) { MEDIA_ERR_LOG("Invalid buffer:%p userSize:%u", buffer, userSize); return ERR_INVALID_READ; } @@ -229,7 +239,7 @@ int32_t AudioCapturer::AudioCapturerImpl::Read(uint8_t *buffer, size_t userSize, return readLen; } -bool AudioCapturer::AudioCapturerImpl::StopInternal() +bool AudioCapturerImpl::StopInternal() { CHK_NULL_RETURN(audioSource_, false); int32_t ret; @@ -252,7 +262,7 @@ bool AudioCapturer::AudioCapturerImpl::StopInternal() return true; } -bool AudioCapturer::AudioCapturerImpl::Stop() +bool AudioCapturerImpl::Stop() { std::lock_guard lock(mutex_); if (status_ != RECORDING) { @@ -262,7 +272,7 @@ bool AudioCapturer::AudioCapturerImpl::Stop() return StopInternal(); } -bool AudioCapturer::AudioCapturerImpl::Release() +bool AudioCapturerImpl::Release() { std::lock_guard lock(mutex_); if (status_ == RELEASED) { diff --git a/frameworks/audio_capturer_impl.h b/frameworks/audio_capturer_impl.h index c458ba4b94fd57499ad412111454177d83a28009..7de226cbd040b2c1b35a2f41d15e68ca262b2466 100755 --- a/frameworks/audio_capturer_impl.h +++ b/frameworks/audio_capturer_impl.h @@ -31,7 +31,7 @@ enum AudioChannel { class AudioSource; class AudioEncoder; -class AudioCapturer::AudioCapturerImpl { +class AudioCapturerImpl { public: AudioCapturerImpl(); virtual ~AudioCapturerImpl(); @@ -46,9 +46,10 @@ public: uint64_t GetFrameCount(); State GetStatus(); bool GetTimestamp(Timestamp ×tamp, Timestamp::Timebase base); - + private: bool StopInternal(); + std::unique_ptr audioSource_; std::unique_ptr audioEncoder_; State status_ = INITIALIZED; diff --git a/interfaces/kits/audio_capturer.h b/interfaces/kits/audio_capturer.h index 8d52fc9122fdf2c60c8dc637f25deb5ee3400ae0..7f3dc1a66b0dd616f627170f190c3226794d2d14 100755 --- a/interfaces/kits/audio_capturer.h +++ b/interfaces/kits/audio_capturer.h @@ -247,8 +247,8 @@ public: bool Release(); private: - class AudioCapturerImpl; - std::unique_ptr impl_; + class AudioCapturerClient; + std::unique_ptr impl_; }; } // namespace Audio } // namespace OHOS diff --git a/services/BUILD.gn b/services/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..8ab8d89b8a7fed7d902d03f47b04280c9e8be5e3 --- /dev/null +++ b/services/BUILD.gn @@ -0,0 +1,45 @@ +# Copyright (c) 2020-2021 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. +import("//build/lite/config/component/lite_component.gni") +import("//build/lite/ndk/ndk.gni") + +static_library("audio_capturer_server") { + sources = [ + "src/audio_capturer_samgr.cpp", + "src/audio_capturer_server.cpp", + ] + cflags = [ "-fPIC" ] + cflags += [ "-Wall" ] + cflags_cc = cflags + include_dirs = [ + "//foundation/multimedia/audio_lite/services/include", + "//foundation/multimedia/audio_lite/interfaces/kits", + "//foundation/multimedia/audio_lite/frameworks", + "//third_party/bounds_checking_function/include", + "//base/security/permission/interfaces/kits/permission_lite", + "//foundation/distributedschedule/samgr_lite/interfaces/kits/registry", + "//foundation/distributedschedule/samgr_lite/interfaces/kits/samgr", + "//foundation/distributedschedule/samgr_lite/interfaces/kits/communication/broadcast", + "//foundation/multimedia/utils/lite/interfaces/kits", + ] + + deps = [ + "//base/security/permission/services/permission_lite/pms_client:pms_client", + "//foundation/communication/ipc_lite:liteipc_adapter", + "//foundation/distributedschedule/samgr_lite/samgr:samgr", + "//foundation/graphic/surface:lite_surface", + "//foundation/multimedia/audio_lite/frameworks:audio_capturer_impl", + "//foundation/multimedia/utils/lite:media_common", + "//third_party/bounds_checking_function:libsec_shared", + ] +} diff --git a/services/include/audio_capturer_server.h b/services/include/audio_capturer_server.h new file mode 100644 index 0000000000000000000000000000000000000000..18174b64167a63e423bc9e05a1f7895e0c41f146 --- /dev/null +++ b/services/include/audio_capturer_server.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2020 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 AUDIO_CAPTURER_SERVER_H +#define AUDIO_CAPTURER_SERVER_H + +#include +#include +#include +#include "audio_capturer_impl.h" +#include "liteipc_adapter.h" +#include "serializer.h" +#include "surface.h" + +using OHOS::Audio::AudioCapturerImpl; +using OHOS::Surface; +namespace OHOS { +namespace Audio { +enum AudioCapturerFuncId { + AUD_CAP_FUNC_CONNECT, + AUD_CAP_FUNC_DISCONNECT, + AUD_CAP_FUNC_GET_FRAME_COUNT, + AUD_CAP_FUNC_GET_STATUS, + AUD_CAP_FUNC_GET_TIME, + AUD_CAP_FUNC_SET_INFO, + AUD_CAP_FUNC_GET_INFO, + AUD_CAP_FUNC_START, + AUD_CAP_FUNC_STOP, + AUD_CAP_FUNC_RELEASE, + AUD_CAP_FUNC_GET_MIN_FRAME_COUNT, + AUD_CAP_FUNC_SET_SURFACE, + AUD_CAP_FUNC_BUTT, +}; + +static constexpr int32_t DEFAULT_IPC_SIZE = 100; +#define AUDIO_CAPTURER_SERVICE_NAME "AudioCapServer" + +/* Since IPC is serialized, there is no concurrency problem */ +class AudioCapturerServer { +public: + AudioCapturerServer() = default; + ~AudioCapturerServer() = default; + + int32_t AudioCapturerServerInit(); + static AudioCapturerServer *GetInstance(); + AudioCapturerImpl *GetAudioCapturer(pid_t pid); + void AcceptServer(pid_t pid, IpcIo *reply); + void DropServer(pid_t pid, IpcIo *reply); + void Dispatch(int32_t funcId, pid_t pid, IpcIo *req, IpcIo *reply); + static void *ReadAudioDataProcess(void *serverStr); + +private: + void GetMinFrameCount(IpcIo *req, IpcIo *reply); + int32_t SetSurfaceProcess(Surface *surface); + void SetInfo(AudioCapturerImpl *capturer, IpcIo *req, IpcIo *reply); + void GetInfo(AudioCapturerImpl *capturer, IpcIo *reply); + void Start(AudioCapturerImpl *capturer, IpcIo *reply); + void Stop(AudioCapturerImpl *capturer, IpcIo *reply); + void GetMiniFrameCount(IpcIo *req, IpcIo *reply); + void GetFrameCount(AudioCapturerImpl *capturer, IpcIo *reply); + void GetStatus(AudioCapturerImpl *capturer, IpcIo *reply); + void SetSurface(IpcIo *req, IpcIo *reply); + + pid_t clientPid_ = -1; + AudioCapturerImpl *capturer_ = nullptr; + Surface *surface_ = nullptr; + // std::thread dataThreadId_; + pthread_t dataThreadId_ = 0; + std::mutex lock_; + bool threadExit_ = false; +}; + +void AudioCapturerServiceReg(); +} // namespace Audio +} // namespace OHOS +#endif // AUDIO_CAPTURER_SERVER_H diff --git a/services/src/audio_capturer_samgr.cpp b/services/src/audio_capturer_samgr.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e1d676a2e785dc599af56705ee2ce05e027ec310 --- /dev/null +++ b/services/src/audio_capturer_samgr.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2020-2021 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 +#include +#include "audio_capturer_server.h" +#include "feature.h" +#include "iproxy_server.h" +#include "media_log.h" +#include "samgr_lite.h" +#include "service.h" + +namespace OHOS { +namespace Audio { +struct DefaultFeatureApi { + INHERIT_SERVER_IPROXY; +}; + +struct AudioCapturerService { + INHERIT_SERVICE; + INHERIT_IUNKNOWNENTRY(DefaultFeatureApi); + Identity identity; +}; + +static const char *GetName(Service *service) +{ + (void)service; + return AUDIO_CAPTURER_SERVICE_NAME; +} + +static BOOL Initialize(Service *service, Identity identity) +{ + AudioCapturerService *capturerSvc = (AudioCapturerService *)service; + capturerSvc->identity = identity; + MEDIA_INFO_LOG("Initialize(%s)! Identity<%d, %d, %p>", AUDIO_CAPTURER_SERVICE_NAME, identity.serviceId, + identity.featureId, identity.queueId); + return TRUE; +} + +static BOOL MessageHandle(Service *service, Request *msg) +{ + MEDIA_DEBUG_LOG("MessageHandle(%s)! Request<%d, %d, %p>", service->GetName(service), msg->msgId, msg->msgValue, + msg->data); + return FALSE; +} + +static TaskConfig GetTaskConfig(Service *service) +{ + (void)service; + TaskConfig config = {LEVEL_HIGH, PRI_BELOW_NORMAL, 0x800, 20, SHARED_TASK}; + return config; +} + +static int32 Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *reply) +{ + pid_t pid = GetCallingPid(origin); + AudioCapturerServer *mng = AudioCapturerServer::GetInstance(); + mng->Dispatch(funcId, pid, req, reply); + return EC_SUCCESS; +} + +void AudioCapturerServiceReg() +{ + static AudioCapturerService audioCapturerSvc = { + .GetName = GetName, + .Initialize = Initialize, + .MessageHandle = MessageHandle, + .GetTaskConfig = GetTaskConfig, + SERVER_IPROXY_IMPL_BEGIN, + .Invoke = Invoke, + IPROXY_END, + }; + MEDIA_INFO_LOG("Input AudioCapturerServiceReg"); + bool ret = SAMGR_GetInstance()->RegisterService((Service *)&audioCapturerSvc); + if (!ret) { + MEDIA_ERR_LOG("AudioCapturer regist service failed."); + return; + } + ret = SAMGR_GetInstance()->RegisterDefaultFeatureApi(AUDIO_CAPTURER_SERVICE_NAME, GET_IUNKNOWN(audioCapturerSvc)); + if (!ret) { + MEDIA_ERR_LOG("AudioCapturer regist feature failed."); + return; + } +} +} // namespace Audio +} // namespace OHOS \ No newline at end of file diff --git a/services/src/audio_capturer_server.cpp b/services/src/audio_capturer_server.cpp new file mode 100644 index 0000000000000000000000000000000000000000..18bf147839d21264d55994817e99935410ceb920 --- /dev/null +++ b/services/src/audio_capturer_server.cpp @@ -0,0 +1,279 @@ +/* + * Copyright (c) 2020 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_capturer_server.h" +#include "audio_capturer_impl.h" +#include "media_errors.h" +#include "media_log.h" +#include "securec.h" +#include "surface.h" +#include "surface_impl.h" + +using namespace std; +using namespace OHOS::Media; +namespace OHOS { +namespace Audio { +AudioCapturerServer *AudioCapturerServer::GetInstance() +{ + static AudioCapturerServer mng; + return &mng; +} + +AudioCapturerImpl *AudioCapturerServer::GetAudioCapturer(pid_t pid) +{ + return (pid == clientPid_) ? capturer_ : nullptr; +} + +int32_t AudioCapturerServer::AudioCapturerServerInit() +{ + return 0; +} + +void AudioCapturerServer::AcceptServer(pid_t pid, IpcIo *reply) +{ + MEDIA_INFO_LOG("in"); + if (clientPid_ == -1) { + capturer_ = new AudioCapturerImpl; + clientPid_ = pid; + IpcIoPushInt32(reply, MEDIA_OK); + } else { + IpcIoPushInt32(reply, MEDIA_IPC_FAILED); + } +} + +void AudioCapturerServer::DropServer(pid_t pid, IpcIo *reply) +{ + MEDIA_INFO_LOG("in"); + if (pid == clientPid_) { + if (dataThreadId_ != 0) { + threadExit_ = true; + pthread_join(dataThreadId_, nullptr); + threadExit_ = false; + dataThreadId_ = 0; + } + delete capturer_; + capturer_ = nullptr; + clientPid_ = -1; + } + IpcIoPushInt32(reply, MEDIA_OK); +} + +void *AudioCapturerServer::ReadAudioDataProcess(void *serverStr) +{ + AudioCapturerServer *serverStore = (AudioCapturerServer *)serverStr; + if (serverStore == nullptr || serverStore->surface_ == nullptr) { + MEDIA_ERR_LOG("No available serverStore in surface."); + return nullptr; + } + + MEDIA_INFO_LOG("thread work"); + while (!serverStore->threadExit_) { + /* request surface buffer */ + SurfaceBuffer *surfaceBuf = serverStore->surface_->RequestBuffer(); + if (surfaceBuf == nullptr) { + usleep(20000); // indicates 20000 microseconds + continue; + } + uint32_t size = serverStore->surface_->GetSize(); + void *buf = surfaceBuf->GetVirAddr(); + uint32_t offSet = sizeof(Timestamp); + /* Timestamp + audio data */ + /* read frame data, and reserve timestamp space */ + int32_t readLen = serverStore->capturer_->Read((uint8_t *)buf + offSet, size - offSet, true); + if (readLen == ERR_INVALID_READ) { + serverStore->surface_->CancelBuffer(surfaceBuf); + usleep(20000); // indicates 20000 microseconds + continue; + } + + Timestamp timestamp; + Timestamp::Timebase base = {}; + bool ret = serverStore->capturer_->GetTimestamp(timestamp, base); + if (!ret) { + MEDIA_ERR_LOG("No readtime get."); + serverStore->surface_->CancelBuffer(surfaceBuf); + continue; + } + memcpy_s((uint8_t *)buf, sizeof(Timestamp), ×tamp, sizeof(Timestamp)); + surfaceBuf->SetSize(sizeof(Timestamp) + readLen); + + // flush buffer + if (serverStore->surface_->FlushBuffer(surfaceBuf) != 0) { + MEDIA_ERR_LOG("Flush surface buffer failed."); + serverStore->surface_->CancelBuffer(surfaceBuf); + ret = MEDIA_ERR; + continue; + } + } + MEDIA_INFO_LOG("thread exit"); + return nullptr; +} + +int32_t AudioCapturerServer::SetSurfaceProcess(Surface *surface) +{ + if (surface == nullptr) { + MEDIA_INFO_LOG("Surface is null"); + return -1; + } + surface_ = surface; + + return 0; +} + +void AudioCapturerServer::GetMinFrameCount(IpcIo *req, IpcIo *reply) +{ + int32_t sampleRate = IpcIoPopInt32(req); + int32_t channelCount = IpcIoPopInt32(req); + AudioCodecFormat audioFormat = (AudioCodecFormat)IpcIoPopInt32(req); + size_t frameCount; + bool ret = AudioCapturerImpl::GetMinFrameCount(sampleRate, channelCount, audioFormat, frameCount); + IpcIoPushInt32(reply, ret); + IpcIoPushUint32(reply, frameCount); +} + +void AudioCapturerServer::SetInfo(AudioCapturerImpl *capturer, IpcIo *req, IpcIo *reply) +{ + AudioCapturerInfo info; + uint32_t size = 0; + void *bufferAdd = IpcIoPopFlatObj(req, &size); + + if (bufferAdd == nullptr || size == 0) { + MEDIA_INFO_LOG("IpcIoPopFlatObj info failed"); + IpcIoPushInt32(reply, -1); + return; + } + memcpy_s(&info, sizeof(AudioCapturerInfo), bufferAdd, size); + int32_t ret = capturer->SetCapturerInfo(info); + IpcIoPushInt32(reply, ret); +} + +void AudioCapturerServer::GetInfo(AudioCapturerImpl *capturer, IpcIo *reply) +{ + AudioCapturerInfo info; + int32_t ret = capturer->GetCapturerInfo(info); + IpcIoPushInt32(reply, ret); + IpcIoPushFlatObj(reply, &info, sizeof(AudioCapturerInfo)); +} + +void AudioCapturerServer::Start(AudioCapturerImpl *capturer, IpcIo *reply) +{ + bool record = capturer->Record(); + if (record) { + threadExit_ = false; + pthread_create(&dataThreadId_, nullptr, ReadAudioDataProcess, this); + MEDIA_INFO_LOG("create thread ReadAudioDataProcess SUCCESS"); + } + IpcIoPushInt32(reply, record); +} + +void AudioCapturerServer::Stop(AudioCapturerImpl *capturer, IpcIo *reply) +{ + int32_t ret = capturer->Stop(); + if (dataThreadId_ != 0) { + threadExit_ = true; + pthread_join(dataThreadId_, nullptr); + threadExit_ = false; + dataThreadId_ = 0; + } + IpcIoPushInt32(reply, ret); +} + +void AudioCapturerServer::GetMiniFrameCount(IpcIo *req, IpcIo *reply) +{ + uint32_t size = 0; + int32_t sampleRate = IpcIoPopInt32(req); + int32_t channelCount = IpcIoPopInt32(req); + AudioCodecFormat *audioFormat = (AudioCodecFormat *)IpcIoPopFlatObj(req, &size); + + size_t frameCount; + bool ret = AudioCapturerImpl::GetMinFrameCount(sampleRate, channelCount, *audioFormat, frameCount); + IpcIoPushInt32(reply, ret); + IpcIoPushUint64(reply, frameCount); +} + +void AudioCapturerServer::GetFrameCount(AudioCapturerImpl *capturer, IpcIo *reply) +{ + uint64_t frameCount = capturer->GetFrameCount(); + IpcIoPushInt32(reply, MEDIA_OK); + IpcIoPushUint64(reply, frameCount); +} + +void AudioCapturerServer::GetStatus(AudioCapturerImpl *capturer, IpcIo *reply) +{ + State status = capturer->GetStatus(); + IpcIoPushInt32(reply, MEDIA_OK); + IpcIoPushInt32(reply, status); +} + +void AudioCapturerServer::SetSurface(IpcIo *req, IpcIo *reply) +{ + Surface *surface = SurfaceImpl::GenericSurfaceByIpcIo(*req); + int32_t ret = SetSurfaceProcess(surface); + IpcIoPushInt32(reply, ret); +} + +void AudioCapturerServer::Dispatch(int32_t funcId, pid_t pid, IpcIo *req, IpcIo *reply) +{ + int32_t ret; + if (funcId == AUD_CAP_FUNC_GET_MIN_FRAME_COUNT) { + return; + } + if (funcId == AUD_CAP_FUNC_CONNECT) { + AcceptServer(pid, reply); + return; + } + auto capturer = GetAudioCapturer(pid); + if (capturer == nullptr) { + MEDIA_ERR_LOG("Cannot find client object.(pid=%d)", pid); + IpcIoPushInt32(reply, MEDIA_IPC_FAILED); + } + switch (funcId) { + case AUD_CAP_FUNC_DISCONNECT: + DropServer(pid, reply); + break; + case AUD_CAP_FUNC_GET_FRAME_COUNT: + GetFrameCount(capturer, reply); + break; + case AUD_CAP_FUNC_GET_STATUS: + GetStatus(capturer, reply); + break; + case AUD_CAP_FUNC_SET_INFO: + SetInfo(capturer, req, reply); + break; + case AUD_CAP_FUNC_GET_INFO: + GetInfo(capturer, reply); + break; + case AUD_CAP_FUNC_START: + Start(capturer, reply); + break; + case AUD_CAP_FUNC_STOP: + Stop(capturer, reply); + break; + case AUD_CAP_FUNC_RELEASE: + ret = capturer->Release(); + IpcIoPushInt32(reply, ret); + break; + case AUD_CAP_FUNC_SET_SURFACE: + SetSurface(req, reply); + break; + case AUD_CAP_FUNC_GET_MIN_FRAME_COUNT: + GetMiniFrameCount(req, reply); + break; + default: + break; + } +} +} // namespace Audio +} // namespace OHOS \ No newline at end of file diff --git a/test/BUILD.gn b/test/BUILD.gn index f6df4f8f5ef74a7ada412252d3d536a271f1b391..d6196d57f7dc3e05f2031705db2e52f06be92053 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -20,24 +20,25 @@ group("lite_audio_test") { } if (ohos_build_type == "debug") { - unittest("lite_audio_unittest") { + unittest("lite_audio_unittest") { output_dir = "$root_out_dir/test/unittest/audiolite" sources = [ "unittest/audiolite_test.cpp" ] include_dirs = [ - "//foundation/multimedia/audio_lite/frameworks/audio_encoder/include", - "//foundation/multimedia/audio_lite/frameworks/audio_source/include", - "//foundation/multimedia/audio_lite/interfaces/kits", - "//foundation/multimedia/utils/lite/include", - "//drivers/peripheral/audio/interfaces/include", - "//drivers/peripheral/codec/interfaces/include", - "//drivers/peripheral/format/interfaces/include", - "//foundation/multimedia/audio_lite/test/unittest", + "//foundation/multimedia/audio_lite/frameworks/audio_encoder/include", + "//foundation/multimedia/audio_lite/frameworks/audio_source/include", + "//foundation/multimedia/audio_lite/interfaces/kits", + "//foundation/multimedia/utils/lite/include", + "//drivers/peripheral/audio/interfaces/include", + "//drivers/peripheral/codec/interfaces/include", + "//drivers/peripheral/format/interfaces/include", + "//foundation/multimedia/audio_lite/test/unittest", + "//foundation/multimedia/utils/lite/interfaces/kits", ] deps = [ - "//foundation/multimedia/audio_lite/frameworks:audio_capturer_lite", - "//foundation/multimedia/utils/lite:media_common", - "//third_party/bounds_checking_function:libsec_shared", + "//foundation/multimedia/audio_lite/frameworks:audio_capturer_lite", + "//foundation/multimedia/utils/lite:media_common", + "//third_party/bounds_checking_function:libsec_shared", ] } }