1d5a2a63bSopenharmony_ci/* 2d5a2a63bSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3d5a2a63bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4d5a2a63bSopenharmony_ci * you may not use this file except in compliance with the License. 5d5a2a63bSopenharmony_ci * You may obtain a copy of the License at 6d5a2a63bSopenharmony_ci * 7d5a2a63bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8d5a2a63bSopenharmony_ci * 9d5a2a63bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10d5a2a63bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11d5a2a63bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12d5a2a63bSopenharmony_ci * See the License for the specific language governing permissions and 13d5a2a63bSopenharmony_ci * limitations under the License. 14d5a2a63bSopenharmony_ci */ 15d5a2a63bSopenharmony_ci 16d5a2a63bSopenharmony_ci#include "audio_capturer_client.h" 17d5a2a63bSopenharmony_ci 18d5a2a63bSopenharmony_ci#include <cstdio> 19d5a2a63bSopenharmony_ci#include "audio_capturer_server.h" 20d5a2a63bSopenharmony_ci#include "media_log.h" 21d5a2a63bSopenharmony_ci#include "ipc_skeleton.h" 22d5a2a63bSopenharmony_ci#include "samgr_lite.h" 23d5a2a63bSopenharmony_ci#include "securec.h" 24d5a2a63bSopenharmony_ci#include "surface_impl.h" 25d5a2a63bSopenharmony_ci 26d5a2a63bSopenharmony_ciextern "C" void __attribute__((weak)) OHOS_SystemInit(void) 27d5a2a63bSopenharmony_ci{ 28d5a2a63bSopenharmony_ci SAMGR_Bootstrap(); 29d5a2a63bSopenharmony_ci} 30d5a2a63bSopenharmony_ci 31d5a2a63bSopenharmony_ciusing namespace OHOS::Media; 32d5a2a63bSopenharmony_ciusing namespace std; 33d5a2a63bSopenharmony_cinamespace OHOS { 34d5a2a63bSopenharmony_cinamespace Audio { 35d5a2a63bSopenharmony_ciconstexpr int32_t SURFACE_QUEUE_SIZE = 5; 36d5a2a63bSopenharmony_ciconstexpr int32_t SURFACE_SIZE = 8192; 37d5a2a63bSopenharmony_ciconstexpr int32_t SURFACE_HEIGHT = 1; 38d5a2a63bSopenharmony_ciconstexpr int32_t SURFACE_WIDTH = 8192; 39d5a2a63bSopenharmony_ci 40d5a2a63bSopenharmony_cistruct CallBackPara { 41d5a2a63bSopenharmony_ci int funcId; 42d5a2a63bSopenharmony_ci int32_t ret; 43d5a2a63bSopenharmony_ci void* data; 44d5a2a63bSopenharmony_ci}; 45d5a2a63bSopenharmony_ci 46d5a2a63bSopenharmony_ciAudioCapturer::AudioCapturerClient *AudioCapturer::AudioCapturerClient::GetInstance() 47d5a2a63bSopenharmony_ci{ 48d5a2a63bSopenharmony_ci static AudioCapturerClient client; 49d5a2a63bSopenharmony_ci return &client; 50d5a2a63bSopenharmony_ci} 51d5a2a63bSopenharmony_ci 52d5a2a63bSopenharmony_cistatic int32_t ProxyCallbackFunc(void *owner, int code, IpcIo *reply) 53d5a2a63bSopenharmony_ci{ 54d5a2a63bSopenharmony_ci if (code) { 55d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("callback error, code = %d", code); 56d5a2a63bSopenharmony_ci return -1; 57d5a2a63bSopenharmony_ci } 58d5a2a63bSopenharmony_ci 59d5a2a63bSopenharmony_ci if (owner == nullptr) { 60d5a2a63bSopenharmony_ci return -1; 61d5a2a63bSopenharmony_ci } 62d5a2a63bSopenharmony_ci 63d5a2a63bSopenharmony_ci CallBackPara* para = static_cast<CallBackPara*>(owner); 64d5a2a63bSopenharmony_ci AudioCapturerFuncId funcId = (AudioCapturerFuncId)para->funcId; 65d5a2a63bSopenharmony_ci ReadInt32(reply, ¶->ret); 66d5a2a63bSopenharmony_ci switch (funcId) { 67d5a2a63bSopenharmony_ci case AUD_CAP_FUNC_CONNECT: 68d5a2a63bSopenharmony_ci case AUD_CAP_FUNC_DISCONNECT: 69d5a2a63bSopenharmony_ci case AUD_CAP_FUNC_SET_INFO: 70d5a2a63bSopenharmony_ci case AUD_CAP_FUNC_START: 71d5a2a63bSopenharmony_ci case AUD_CAP_FUNC_STOP: 72d5a2a63bSopenharmony_ci case AUD_CAP_FUNC_RELEASE: 73d5a2a63bSopenharmony_ci case AUD_CAP_FUNC_SET_SURFACE: 74d5a2a63bSopenharmony_ci break; 75d5a2a63bSopenharmony_ci case AUD_CAP_FUNC_GET_FRAME_COUNT: 76d5a2a63bSopenharmony_ci ReadUint64(reply, reinterpret_cast<uint64_t*>(para->data)); 77d5a2a63bSopenharmony_ci break; 78d5a2a63bSopenharmony_ci case AUD_CAP_FUNC_GET_STATUS: 79d5a2a63bSopenharmony_ci ReadUint32(reply, reinterpret_cast<uint32_t*>(para->data)); 80d5a2a63bSopenharmony_ci break; 81d5a2a63bSopenharmony_ci case AUD_CAP_FUNC_GET_INFO: { 82d5a2a63bSopenharmony_ci uint32_t size = 0; 83d5a2a63bSopenharmony_ci ReadUint32(reply, &size); 84d5a2a63bSopenharmony_ci void *bufferAdd = (void*)ReadBuffer(reply, (size_t)size); 85d5a2a63bSopenharmony_ci if (bufferAdd == nullptr || !size) { 86d5a2a63bSopenharmony_ci MEDIA_INFO_LOG("Readbuffer info failed"); 87d5a2a63bSopenharmony_ci return -1; 88d5a2a63bSopenharmony_ci } 89d5a2a63bSopenharmony_ci (void)memcpy_s(para->data, sizeof(AudioCapturerInfo), bufferAdd, size); 90d5a2a63bSopenharmony_ci break; 91d5a2a63bSopenharmony_ci } 92d5a2a63bSopenharmony_ci case AUD_CAP_FUNC_GET_MIN_FRAME_COUNT: 93d5a2a63bSopenharmony_ci ReadUint32(reply, reinterpret_cast<uint32_t*>(para->data)); 94d5a2a63bSopenharmony_ci break; 95d5a2a63bSopenharmony_ci default : 96d5a2a63bSopenharmony_ci MEDIA_INFO_LOG("Callback, unknown funcId = %d", para->funcId); 97d5a2a63bSopenharmony_ci break; 98d5a2a63bSopenharmony_ci } 99d5a2a63bSopenharmony_ci return 0; 100d5a2a63bSopenharmony_ci} 101d5a2a63bSopenharmony_ci 102d5a2a63bSopenharmony_ciint32_t AudioCapturer::AudioCapturerClient::InitSurface(void) 103d5a2a63bSopenharmony_ci{ 104d5a2a63bSopenharmony_ci MEDIA_DEBUG_LOG("AudioCapturerClient InitSurface"); 105d5a2a63bSopenharmony_ci Surface *surface = Surface::CreateSurface(); 106d5a2a63bSopenharmony_ci if (surface == nullptr) { 107d5a2a63bSopenharmony_ci return -1; 108d5a2a63bSopenharmony_ci } 109d5a2a63bSopenharmony_ci 110d5a2a63bSopenharmony_ci surface->RegisterConsumerListener(*this); 111d5a2a63bSopenharmony_ci surface_.reset(surface); 112d5a2a63bSopenharmony_ci 113d5a2a63bSopenharmony_ci surface->SetWidthAndHeight(SURFACE_WIDTH, SURFACE_HEIGHT); 114d5a2a63bSopenharmony_ci surface->SetQueueSize(SURFACE_QUEUE_SIZE); 115d5a2a63bSopenharmony_ci surface->SetSize(SURFACE_SIZE); 116d5a2a63bSopenharmony_ci return 0; 117d5a2a63bSopenharmony_ci} 118d5a2a63bSopenharmony_ci 119d5a2a63bSopenharmony_ciint32_t AudioCapturer::AudioCapturerClient::DeleteSurface(void) 120d5a2a63bSopenharmony_ci{ 121d5a2a63bSopenharmony_ci /* release all surface buffer */ 122d5a2a63bSopenharmony_ci if (surface_ == nullptr) { 123d5a2a63bSopenharmony_ci return -1; 124d5a2a63bSopenharmony_ci } 125d5a2a63bSopenharmony_ci ReleaseAllBuffer(); 126d5a2a63bSopenharmony_ci surface_->UnregisterConsumerListener(); 127d5a2a63bSopenharmony_ci surface_.reset(); 128d5a2a63bSopenharmony_ci surface_ = nullptr; 129d5a2a63bSopenharmony_ci return 0; 130d5a2a63bSopenharmony_ci} 131d5a2a63bSopenharmony_ci 132d5a2a63bSopenharmony_ciAudioCapturer::AudioCapturerClient::AudioCapturerClient() 133d5a2a63bSopenharmony_ci{ 134d5a2a63bSopenharmony_ci OHOS_SystemInit(); 135d5a2a63bSopenharmony_ci IpcIo io; 136d5a2a63bSopenharmony_ci uint8_t tmpData[DEFAULT_IPC_SIZE]; 137d5a2a63bSopenharmony_ci IUnknown *iUnknown = SAMGR_GetInstance()->GetDefaultFeatureApi(AUDIO_CAPTURER_SERVICE_NAME); 138d5a2a63bSopenharmony_ci if (iUnknown == nullptr) { 139d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("iUnknown is nullptr"); 140d5a2a63bSopenharmony_ci throw runtime_error("Ipc proxy GetDefaultFeatureApi failed."); 141d5a2a63bSopenharmony_ci } 142d5a2a63bSopenharmony_ci 143d5a2a63bSopenharmony_ci (void)iUnknown->QueryInterface(iUnknown, CLIENT_PROXY_VER, (void **)&proxy_); 144d5a2a63bSopenharmony_ci if (proxy_ == nullptr) { 145d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("QueryInterface failed"); 146d5a2a63bSopenharmony_ci throw runtime_error("Ipc proxy init failed."); 147d5a2a63bSopenharmony_ci } 148d5a2a63bSopenharmony_ci 149d5a2a63bSopenharmony_ci IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0); 150d5a2a63bSopenharmony_ci CallBackPara para = {.funcId = AUD_CAP_FUNC_CONNECT, .ret = MEDIA_IPC_FAILED, .data = this}; 151d5a2a63bSopenharmony_ci int32_t ret = proxy_->Invoke(proxy_, AUD_CAP_FUNC_CONNECT, nullptr, ¶, ProxyCallbackFunc); 152d5a2a63bSopenharmony_ci if (ret) { 153d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("Connect audio capturer server failed, ret=%d", ret); 154d5a2a63bSopenharmony_ci throw runtime_error("Ipc proxy Invoke failed."); 155d5a2a63bSopenharmony_ci } 156d5a2a63bSopenharmony_ci 157d5a2a63bSopenharmony_ci /* Creating a Surface and Initializing Settings */ 158d5a2a63bSopenharmony_ci MEDIA_DEBUG_LOG("InitSurface audio capturer."); 159d5a2a63bSopenharmony_ci InitSurface(); 160d5a2a63bSopenharmony_ci /* The surface is transferred to the server for processing */ 161d5a2a63bSopenharmony_ci timeStampValid_ = false; 162d5a2a63bSopenharmony_ci IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 1); 163d5a2a63bSopenharmony_ci dynamic_cast<SurfaceImpl *>(surface_.get())->WriteIoIpcIo(io); 164d5a2a63bSopenharmony_ci para = {.funcId = AUD_CAP_FUNC_SET_SURFACE, .ret = MEDIA_IPC_FAILED, .data = this}; 165d5a2a63bSopenharmony_ci ret = proxy_->Invoke(proxy_, AUD_CAP_FUNC_SET_SURFACE, &io, ¶, ProxyCallbackFunc); 166d5a2a63bSopenharmony_ci if (ret) { 167d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("Connect audio capturer set surface failed, ret=%d", ret); 168d5a2a63bSopenharmony_ci throw runtime_error("Ipc proxy Invoke failed."); 169d5a2a63bSopenharmony_ci } 170d5a2a63bSopenharmony_ci 171d5a2a63bSopenharmony_ci MEDIA_INFO_LOG("Create audio capturer client succeed."); 172d5a2a63bSopenharmony_ci} 173d5a2a63bSopenharmony_ci 174d5a2a63bSopenharmony_civoid AudioCapturer::AudioCapturerClient::ReleaseAllBuffer() 175d5a2a63bSopenharmony_ci{ 176d5a2a63bSopenharmony_ci timeStampValid_ = false; 177d5a2a63bSopenharmony_ci while (true) { 178d5a2a63bSopenharmony_ci SurfaceBuffer *surfaceBuf = surface_->AcquireBuffer(); 179d5a2a63bSopenharmony_ci if (surfaceBuf == nullptr) { 180d5a2a63bSopenharmony_ci break; 181d5a2a63bSopenharmony_ci } 182d5a2a63bSopenharmony_ci surface_->ReleaseBuffer(surfaceBuf); 183d5a2a63bSopenharmony_ci } 184d5a2a63bSopenharmony_ci} 185d5a2a63bSopenharmony_ci 186d5a2a63bSopenharmony_ciAudioCapturer::AudioCapturerClient::~AudioCapturerClient() 187d5a2a63bSopenharmony_ci{ 188d5a2a63bSopenharmony_ci IpcIo io; 189d5a2a63bSopenharmony_ci uint8_t tmpData[DEFAULT_IPC_SIZE]; 190d5a2a63bSopenharmony_ci IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0); 191d5a2a63bSopenharmony_ci CallBackPara para = {.funcId = AUD_CAP_FUNC_DISCONNECT, .ret = MEDIA_IPC_FAILED}; 192d5a2a63bSopenharmony_ci uint32_t ret = proxy_->Invoke(proxy_, AUD_CAP_FUNC_DISCONNECT, &io, ¶, ProxyCallbackFunc); 193d5a2a63bSopenharmony_ci if (ret) { 194d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("Disconnect audioCapturer server failed, ret=%d", ret); 195d5a2a63bSopenharmony_ci } 196d5a2a63bSopenharmony_ci 197d5a2a63bSopenharmony_ci /* release all surface buffer */ 198d5a2a63bSopenharmony_ci if (surface_ != nullptr) { 199d5a2a63bSopenharmony_ci DeleteSurface(); 200d5a2a63bSopenharmony_ci } 201d5a2a63bSopenharmony_ci MEDIA_INFO_LOG("destructor"); 202d5a2a63bSopenharmony_ci} 203d5a2a63bSopenharmony_ci 204d5a2a63bSopenharmony_cibool AudioCapturer::AudioCapturerClient::GetMinFrameCount(int32_t sampleRate, int32_t channelCount, 205d5a2a63bSopenharmony_ci AudioCodecFormat audioFormat, size_t &frameCount) 206d5a2a63bSopenharmony_ci{ 207d5a2a63bSopenharmony_ci AudioCapturerClient *client = AudioCapturer::AudioCapturerClient::GetInstance(); 208d5a2a63bSopenharmony_ci IpcIo io; 209d5a2a63bSopenharmony_ci uint8_t tmpData[DEFAULT_IPC_SIZE]; 210d5a2a63bSopenharmony_ci IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0); 211d5a2a63bSopenharmony_ci WriteInt32(&io, sampleRate); 212d5a2a63bSopenharmony_ci WriteInt32(&io, channelCount); 213d5a2a63bSopenharmony_ci WriteUint32(&io, sizeof(audioFormat)); 214d5a2a63bSopenharmony_ci WriteBuffer(&io, &audioFormat, sizeof(audioFormat)); 215d5a2a63bSopenharmony_ci CallBackPara para = {.funcId = AUD_CAP_FUNC_GET_MIN_FRAME_COUNT, .ret = MEDIA_IPC_FAILED, .data = &frameCount}; 216d5a2a63bSopenharmony_ci uint32_t ret = client->proxy_->Invoke(client->proxy_, AUD_CAP_FUNC_GET_MIN_FRAME_COUNT, &io, ¶, 217d5a2a63bSopenharmony_ci ProxyCallbackFunc); 218d5a2a63bSopenharmony_ci if (ret) { 219d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("GetMinFrameCount failed, ret=%d", ret); 220d5a2a63bSopenharmony_ci return false; 221d5a2a63bSopenharmony_ci } 222d5a2a63bSopenharmony_ci return (!para.ret) ? true : false; 223d5a2a63bSopenharmony_ci} 224d5a2a63bSopenharmony_ci 225d5a2a63bSopenharmony_ciuint64_t AudioCapturer::AudioCapturerClient::GetFrameCount() 226d5a2a63bSopenharmony_ci{ 227d5a2a63bSopenharmony_ci IpcIo io; 228d5a2a63bSopenharmony_ci uint64_t frameCount; 229d5a2a63bSopenharmony_ci uint8_t tmpData[DEFAULT_IPC_SIZE]; 230d5a2a63bSopenharmony_ci IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0); 231d5a2a63bSopenharmony_ci CallBackPara para = {.funcId = AUD_CAP_FUNC_GET_FRAME_COUNT, .ret = MEDIA_IPC_FAILED, .data = &frameCount}; 232d5a2a63bSopenharmony_ci 233d5a2a63bSopenharmony_ci if (proxy_ == nullptr) { 234d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("GetFrameCount failed, proxy_ value is nullptr"); 235d5a2a63bSopenharmony_ci return 0; 236d5a2a63bSopenharmony_ci } 237d5a2a63bSopenharmony_ci 238d5a2a63bSopenharmony_ci uint32_t ret = proxy_->Invoke(proxy_, AUD_CAP_FUNC_GET_FRAME_COUNT, &io, ¶, ProxyCallbackFunc); 239d5a2a63bSopenharmony_ci if (ret) { 240d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("GetFrameCount failed, ret=%d", ret); 241d5a2a63bSopenharmony_ci } 242d5a2a63bSopenharmony_ci 243d5a2a63bSopenharmony_ci return frameCount; 244d5a2a63bSopenharmony_ci} 245d5a2a63bSopenharmony_ci 246d5a2a63bSopenharmony_ciState AudioCapturer::AudioCapturerClient::GetStatus() 247d5a2a63bSopenharmony_ci{ 248d5a2a63bSopenharmony_ci IpcIo io; 249d5a2a63bSopenharmony_ci uint32_t state; 250d5a2a63bSopenharmony_ci uint8_t tmpData[DEFAULT_IPC_SIZE]; 251d5a2a63bSopenharmony_ci IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0); 252d5a2a63bSopenharmony_ci CallBackPara para = {.funcId = AUD_CAP_FUNC_GET_STATUS, .ret = MEDIA_IPC_FAILED, .data = &state}; 253d5a2a63bSopenharmony_ci 254d5a2a63bSopenharmony_ci if (proxy_ == nullptr) { 255d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("GetStatus failed, proxy_ value is nullptr"); 256d5a2a63bSopenharmony_ci return (State)state; 257d5a2a63bSopenharmony_ci } 258d5a2a63bSopenharmony_ci 259d5a2a63bSopenharmony_ci uint32_t ret = proxy_->Invoke(proxy_, AUD_CAP_FUNC_GET_STATUS, &io, ¶, ProxyCallbackFunc); 260d5a2a63bSopenharmony_ci if (ret) { 261d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("GetStatus failed, ret=%d", ret); 262d5a2a63bSopenharmony_ci } 263d5a2a63bSopenharmony_ci 264d5a2a63bSopenharmony_ci return (State)state; 265d5a2a63bSopenharmony_ci} 266d5a2a63bSopenharmony_ci 267d5a2a63bSopenharmony_cibool AudioCapturer::AudioCapturerClient::GetAudioTime(Timestamp ×tamp, Timestamp::Timebase base) 268d5a2a63bSopenharmony_ci{ 269d5a2a63bSopenharmony_ci timestamp = curTimestamp_; 270d5a2a63bSopenharmony_ci return true; 271d5a2a63bSopenharmony_ci} 272d5a2a63bSopenharmony_ci 273d5a2a63bSopenharmony_ciint32_t AudioCapturer::AudioCapturerClient::SetCapturerInfo(const AudioCapturerInfo info) 274d5a2a63bSopenharmony_ci{ 275d5a2a63bSopenharmony_ci IpcIo io; 276d5a2a63bSopenharmony_ci uint8_t tmpData[DEFAULT_IPC_SIZE]; 277d5a2a63bSopenharmony_ci IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0); 278d5a2a63bSopenharmony_ci WriteUint32(&io, sizeof(info)); 279d5a2a63bSopenharmony_ci WriteBuffer(&io, &info, sizeof(info)); 280d5a2a63bSopenharmony_ci CallBackPara para = {.funcId = AUD_CAP_FUNC_SET_INFO, .ret = MEDIA_IPC_FAILED}; 281d5a2a63bSopenharmony_ci 282d5a2a63bSopenharmony_ci if (proxy_ == nullptr) { 283d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("SetCapturerInfo failed, proxy_ value is nullptr"); 284d5a2a63bSopenharmony_ci return 0; 285d5a2a63bSopenharmony_ci } 286d5a2a63bSopenharmony_ci 287d5a2a63bSopenharmony_ci int32_t ret = proxy_->Invoke(proxy_, AUD_CAP_FUNC_SET_INFO, &io, ¶, ProxyCallbackFunc); 288d5a2a63bSopenharmony_ci if (ret) { 289d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("SetCapturerInfo failed, ret=%d", ret); 290d5a2a63bSopenharmony_ci return ret; 291d5a2a63bSopenharmony_ci } 292d5a2a63bSopenharmony_ci return para.ret; 293d5a2a63bSopenharmony_ci} 294d5a2a63bSopenharmony_ci 295d5a2a63bSopenharmony_ciint32_t AudioCapturer::AudioCapturerClient::GetCapturerInfo(AudioCapturerInfo &info) 296d5a2a63bSopenharmony_ci{ 297d5a2a63bSopenharmony_ci IpcIo io; 298d5a2a63bSopenharmony_ci uint8_t tmpData[DEFAULT_IPC_SIZE]; 299d5a2a63bSopenharmony_ci IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0); 300d5a2a63bSopenharmony_ci CallBackPara para = {.funcId = AUD_CAP_FUNC_GET_INFO, .ret = MEDIA_IPC_FAILED, .data = &info}; 301d5a2a63bSopenharmony_ci 302d5a2a63bSopenharmony_ci if (proxy_ == nullptr) { 303d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("GetCapturerInfo failed, proxy_ value is nullptr"); 304d5a2a63bSopenharmony_ci return 0; 305d5a2a63bSopenharmony_ci } 306d5a2a63bSopenharmony_ci 307d5a2a63bSopenharmony_ci int32_t ret = proxy_->Invoke(proxy_, AUD_CAP_FUNC_GET_INFO, &io, ¶, ProxyCallbackFunc); 308d5a2a63bSopenharmony_ci if (ret) { 309d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("GetCapturerInfo failed, ret=%d", ret); 310d5a2a63bSopenharmony_ci return ret; 311d5a2a63bSopenharmony_ci } 312d5a2a63bSopenharmony_ci return para.ret; 313d5a2a63bSopenharmony_ci} 314d5a2a63bSopenharmony_ci 315d5a2a63bSopenharmony_cibool AudioCapturer::AudioCapturerClient::Start() 316d5a2a63bSopenharmony_ci{ 317d5a2a63bSopenharmony_ci IpcIo io; 318d5a2a63bSopenharmony_ci uint8_t tmpData[DEFAULT_IPC_SIZE]; 319d5a2a63bSopenharmony_ci IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0); 320d5a2a63bSopenharmony_ci CallBackPara para = {.funcId = AUD_CAP_FUNC_START, .ret = MEDIA_IPC_FAILED}; 321d5a2a63bSopenharmony_ci 322d5a2a63bSopenharmony_ci if (proxy_ == nullptr) { 323d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("Start failed, proxy_ value is nullptr"); 324d5a2a63bSopenharmony_ci return false; 325d5a2a63bSopenharmony_ci } 326d5a2a63bSopenharmony_ci 327d5a2a63bSopenharmony_ci int32_t ret = proxy_->Invoke(proxy_, AUD_CAP_FUNC_START, &io, ¶, ProxyCallbackFunc); 328d5a2a63bSopenharmony_ci if (ret) { 329d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("Start failed, ret=%d", ret); 330d5a2a63bSopenharmony_ci return ret; 331d5a2a63bSopenharmony_ci } 332d5a2a63bSopenharmony_ci 333d5a2a63bSopenharmony_ci return para.ret; 334d5a2a63bSopenharmony_ci} 335d5a2a63bSopenharmony_ci 336d5a2a63bSopenharmony_cibool AudioCapturer::AudioCapturerClient::Stop() 337d5a2a63bSopenharmony_ci{ 338d5a2a63bSopenharmony_ci IpcIo io; 339d5a2a63bSopenharmony_ci uint8_t tmpData[DEFAULT_IPC_SIZE]; 340d5a2a63bSopenharmony_ci IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0); 341d5a2a63bSopenharmony_ci CallBackPara para = {.funcId = AUD_CAP_FUNC_STOP, .ret = MEDIA_IPC_FAILED}; 342d5a2a63bSopenharmony_ci 343d5a2a63bSopenharmony_ci if (proxy_ == nullptr) { 344d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("Stop failed, proxy_ value is nullptr"); 345d5a2a63bSopenharmony_ci return false; 346d5a2a63bSopenharmony_ci } 347d5a2a63bSopenharmony_ci 348d5a2a63bSopenharmony_ci int32_t ret = proxy_->Invoke(proxy_, AUD_CAP_FUNC_STOP, &io, ¶, ProxyCallbackFunc); 349d5a2a63bSopenharmony_ci if (ret) { 350d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("Stop failed, ret=%d", ret); 351d5a2a63bSopenharmony_ci return ret; 352d5a2a63bSopenharmony_ci } 353d5a2a63bSopenharmony_ci 354d5a2a63bSopenharmony_ci return para.ret; 355d5a2a63bSopenharmony_ci} 356d5a2a63bSopenharmony_ci 357d5a2a63bSopenharmony_cibool AudioCapturer::AudioCapturerClient::Release() 358d5a2a63bSopenharmony_ci{ 359d5a2a63bSopenharmony_ci IpcIo io; 360d5a2a63bSopenharmony_ci uint8_t tmpData[DEFAULT_IPC_SIZE]; 361d5a2a63bSopenharmony_ci IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0); 362d5a2a63bSopenharmony_ci CallBackPara para = {.funcId = AUD_CAP_FUNC_RELEASE, .ret = MEDIA_IPC_FAILED}; 363d5a2a63bSopenharmony_ci 364d5a2a63bSopenharmony_ci if (proxy_ == nullptr) { 365d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("Release failed, proxy_ value is nullptr"); 366d5a2a63bSopenharmony_ci return false; 367d5a2a63bSopenharmony_ci } 368d5a2a63bSopenharmony_ci 369d5a2a63bSopenharmony_ci int32_t ret = proxy_->Invoke(proxy_, AUD_CAP_FUNC_RELEASE, &io, ¶, ProxyCallbackFunc); 370d5a2a63bSopenharmony_ci if (ret) { 371d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("Release failed, ret=%d", ret); 372d5a2a63bSopenharmony_ci return ret; 373d5a2a63bSopenharmony_ci } 374d5a2a63bSopenharmony_ci 375d5a2a63bSopenharmony_ci DeleteSurface(); 376d5a2a63bSopenharmony_ci return para.ret; 377d5a2a63bSopenharmony_ci} 378d5a2a63bSopenharmony_ci 379d5a2a63bSopenharmony_ciint32_t AudioCapturer::AudioCapturerClient::Read(uint8_t *buffer, size_t userSize, bool isBlockingRead) 380d5a2a63bSopenharmony_ci{ 381d5a2a63bSopenharmony_ci if (buffer == nullptr || !userSize) { 382d5a2a63bSopenharmony_ci return ERR_INVALID_READ; 383d5a2a63bSopenharmony_ci } 384d5a2a63bSopenharmony_ci int32_t readLen = ERR_INVALID_READ; 385d5a2a63bSopenharmony_ci do { 386d5a2a63bSopenharmony_ci SurfaceBuffer *surfaceBuf = surface_->AcquireBuffer(); 387d5a2a63bSopenharmony_ci if (surfaceBuf == nullptr) { 388d5a2a63bSopenharmony_ci if (isBlockingRead) { 389d5a2a63bSopenharmony_ci usleep(10000); // indicates 10000 microseconds 390d5a2a63bSopenharmony_ci continue; 391d5a2a63bSopenharmony_ci } else { 392d5a2a63bSopenharmony_ci break; 393d5a2a63bSopenharmony_ci } 394d5a2a63bSopenharmony_ci } 395d5a2a63bSopenharmony_ci 396d5a2a63bSopenharmony_ci uint8_t *buf = static_cast<uint8_t *> (surfaceBuf->GetVirAddr()); 397d5a2a63bSopenharmony_ci int32_t dataSize = surfaceBuf->GetSize(); 398d5a2a63bSopenharmony_ci if (dataSize - sizeof(Timestamp) > userSize) { 399d5a2a63bSopenharmony_ci surface_->ReleaseBuffer(surfaceBuf); 400d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("input buffer size too small."); 401d5a2a63bSopenharmony_ci break; 402d5a2a63bSopenharmony_ci } 403d5a2a63bSopenharmony_ci 404d5a2a63bSopenharmony_ci (void)memcpy_s(buffer, userSize, buf + sizeof(Timestamp), dataSize - sizeof(Timestamp)); 405d5a2a63bSopenharmony_ci (void)memcpy_s(&curTimestamp_, sizeof(Timestamp), buf, sizeof(Timestamp)); 406d5a2a63bSopenharmony_ci timeStampValid_ = true; 407d5a2a63bSopenharmony_ci 408d5a2a63bSopenharmony_ci surface_->ReleaseBuffer(surfaceBuf); 409d5a2a63bSopenharmony_ci readLen = dataSize - sizeof(Timestamp); 410d5a2a63bSopenharmony_ci break; 411d5a2a63bSopenharmony_ci } while (isBlockingRead); 412d5a2a63bSopenharmony_ci 413d5a2a63bSopenharmony_ci return readLen; 414d5a2a63bSopenharmony_ci} 415d5a2a63bSopenharmony_ci 416d5a2a63bSopenharmony_civoid AudioCapturer::AudioCapturerClient::OnBufferAvailable() 417d5a2a63bSopenharmony_ci{ 418d5a2a63bSopenharmony_ci if (surface_ == nullptr) { 419d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("OnBufferAvailable failed, surface_ is nullptr"); 420d5a2a63bSopenharmony_ci return; 421d5a2a63bSopenharmony_ci } 422d5a2a63bSopenharmony_ci} 423d5a2a63bSopenharmony_ci 424d5a2a63bSopenharmony_ciIClientProxy *AudioCapturer::AudioCapturerClient::GetIClientProxy() 425d5a2a63bSopenharmony_ci{ 426d5a2a63bSopenharmony_ci return proxy_; 427d5a2a63bSopenharmony_ci} 428d5a2a63bSopenharmony_ci} // namespace Audio 429d5a2a63bSopenharmony_ci} // namespace OHOS 430