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, &para->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, &para, 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, &para, 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, &para, 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, &para,
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, &para, 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, &para, 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 &timestamp, 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, &para, 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, &para, 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, &para, 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, &para, 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, &para, 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