1 /*
2 * Copyright (c) 2020 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "audio_capturer_server.h"
17 #include "audio_capturer_impl.h"
18 #include "media_errors.h"
19 #include "media_log.h"
20 #include "securec.h"
21 #include "surface.h"
22 #include "surface_impl.h"
23
24 using namespace std;
25 using namespace OHOS::Media;
26 namespace OHOS {
27 namespace Audio {
GetInstance()28 AudioCapturerServer *AudioCapturerServer::GetInstance()
29 {
30 static AudioCapturerServer mng;
31 return &mng;
32 }
33
GetAudioCapturer(pid_t pid)34 AudioCapturerImpl *AudioCapturerServer::GetAudioCapturer(pid_t pid)
35 {
36 return (pid == clientPid_) ? capturer_ : nullptr;
37 }
38
AudioCapturerServerInit()39 int32_t AudioCapturerServer::AudioCapturerServerInit()
40 {
41 return 0;
42 }
43
AcceptServer(pid_t pid,IpcIo * reply)44 void AudioCapturerServer::AcceptServer(pid_t pid, IpcIo *reply)
45 {
46 MEDIA_INFO_LOG("in");
47 if (clientPid_ == -1) {
48 capturer_ = new AudioCapturerImpl;
49 clientPid_ = pid;
50 WriteInt32(reply, MEDIA_OK);
51 } else {
52 WriteInt32(reply, MEDIA_IPC_FAILED);
53 }
54 }
55
DropServer(pid_t pid,IpcIo * reply)56 void AudioCapturerServer::DropServer(pid_t pid, IpcIo *reply)
57 {
58 MEDIA_INFO_LOG("in");
59 if (pid == clientPid_) {
60 if (dataThreadId_ != 0) {
61 threadExit_ = true;
62 pthread_join(dataThreadId_, nullptr);
63 threadExit_ = false;
64 dataThreadId_ = 0;
65 }
66 delete capturer_;
67 capturer_ = nullptr;
68 clientPid_ = -1;
69 bufCache_ = nullptr;
70 }
71 WriteInt32(reply, MEDIA_OK);
72 }
73
GetCacheBuffer(void)74 SurfaceBuffer *AudioCapturerServer::GetCacheBuffer(void)
75 {
76 if (surface_ == nullptr) {
77 MEDIA_ERR_LOG("No available serverStore in surface.");
78 return nullptr;
79 }
80
81 if (bufCache_ == nullptr) {
82 bufCache_ = surface_->RequestBuffer();
83 }
84 return bufCache_;
85 }
86
CancelBuffer(SurfaceBuffer * buffer)87 void AudioCapturerServer::CancelBuffer(SurfaceBuffer *buffer)
88 {
89 surface_->CancelBuffer(buffer);
90 FreeCacheBuffer();
91 }
92
FreeCacheBuffer(void)93 void AudioCapturerServer::FreeCacheBuffer(void)
94 {
95 bufCache_ = nullptr;
96 }
97
ReadAudioDataProcess(void * serverStr)98 void *AudioCapturerServer::ReadAudioDataProcess(void *serverStr)
99 {
100 AudioCapturerServer *serverStore = (AudioCapturerServer *)serverStr;
101 if (serverStore == nullptr || serverStore->surface_ == nullptr) {
102 MEDIA_ERR_LOG("No available serverStore in surface.");
103 return nullptr;
104 }
105
106 MEDIA_INFO_LOG("thread work");
107 while (!serverStore->threadExit_) {
108 /* request surface buffer */
109 SurfaceBuffer *surfaceBuf = serverStore->GetCacheBuffer();
110 if (surfaceBuf == nullptr) {
111 usleep(5000); // indicates 5000 microseconds
112 continue;
113 }
114 uint32_t size = serverStore->surface_->GetSize();
115 void *buf = surfaceBuf->GetVirAddr();
116 if (buf == nullptr) {
117 serverStore->CancelBuffer(surfaceBuf);
118 continue;
119 }
120 uint32_t offSet = sizeof(Timestamp);
121 /* Timestamp + audio data */
122 /* read frame data, and reserve timestamp space */
123 int32_t readLen = serverStore->capturer_->Read((uint8_t *)buf + offSet, size - offSet, true);
124 if (readLen == ERR_INVALID_READ) {
125 continue;
126 }
127
128 Timestamp timestamp;
129 Timestamp::Timebase base = {};
130 bool ret = serverStore->capturer_->GetTimestamp(timestamp, base);
131 if (!ret) {
132 MEDIA_ERR_LOG("No readtime get.");
133 continue;
134 }
135 errno_t retCopy = memcpy_s((uint8_t *)buf, sizeof(Timestamp), ×tamp, sizeof(Timestamp));
136 if (retCopy != EOK) {
137 MEDIA_ERR_LOG("retCopy = %x", retCopy);
138 continue;
139 }
140 surfaceBuf->SetSize(sizeof(Timestamp) + readLen);
141
142 // flush buffer
143 if (serverStore->surface_->FlushBuffer(surfaceBuf) != 0) {
144 MEDIA_ERR_LOG("Flush surface buffer failed.");
145 serverStore->CancelBuffer(surfaceBuf);
146 ret = MEDIA_ERR;
147 continue;
148 }
149 serverStore->FreeCacheBuffer();
150 }
151 MEDIA_INFO_LOG("thread exit");
152 return nullptr;
153 }
154
SetSurfaceProcess(Surface * surface)155 int32_t AudioCapturerServer::SetSurfaceProcess(Surface *surface)
156 {
157 if (surface == nullptr) {
158 MEDIA_INFO_LOG("Surface is null");
159 return -1;
160 }
161 surface_ = surface;
162
163 return 0;
164 }
165
GetMinFrameCount(IpcIo * req,IpcIo * reply)166 void AudioCapturerServer::GetMinFrameCount(IpcIo *req, IpcIo *reply)
167 {
168 int32_t sampleRate = 0;
169 ReadInt32(req, &sampleRate);
170 int32_t channelCount = 0;
171 ReadInt32(req, &channelCount);
172 int32_t data = 0;
173 ReadInt32(req, &data);
174 AudioCodecFormat audioFormat = (AudioCodecFormat)data;
175 size_t frameCount;
176 bool ret = AudioCapturerImpl::GetMinFrameCount(sampleRate, channelCount, audioFormat, frameCount);
177 WriteInt32(reply, ret);
178 WriteUint32(reply, frameCount);
179 }
180
SetInfo(AudioCapturerImpl * capturer,IpcIo * req,IpcIo * reply)181 void AudioCapturerServer::SetInfo(AudioCapturerImpl *capturer, IpcIo *req, IpcIo *reply)
182 {
183 AudioCapturerInfo info;
184 uint32_t size = 0;
185 ReadUint32(req, &size);
186 void *bufferAdd = (void*)ReadBuffer(req, size);
187
188 if (bufferAdd == nullptr || size == 0) {
189 MEDIA_INFO_LOG("Readbuffer info failed");
190 WriteInt32(reply, -1);
191 return;
192 }
193 errno_t retCopy = memcpy_s(&info, sizeof(AudioCapturerInfo), bufferAdd, size);
194 if (retCopy != EOK) {
195 MEDIA_ERR_LOG("retCopy = %x", retCopy);
196 return;
197 }
198 int32_t ret = capturer->SetCapturerInfo(info);
199 WriteInt32(reply, ret);
200 }
201
GetInfo(AudioCapturerImpl * capturer,IpcIo * reply)202 void AudioCapturerServer::GetInfo(AudioCapturerImpl *capturer, IpcIo *reply)
203 {
204 if (capturer == nullptr) {
205 MEDIA_ERR_LOG("GetInfo failed, capturer value is nullptr");
206 return;
207 }
208
209 AudioCapturerInfo info;
210 int32_t ret = capturer->GetCapturerInfo(info);
211 WriteInt32(reply, ret);
212 WriteUint32(reply, sizeof(AudioCapturerInfo));
213 WriteBuffer(reply, &info, sizeof(AudioCapturerInfo));
214 }
215
Start(AudioCapturerImpl * capturer,IpcIo * reply)216 void AudioCapturerServer::Start(AudioCapturerImpl *capturer, IpcIo *reply)
217 {
218 if (capturer == nullptr) {
219 MEDIA_ERR_LOG("Start failed, capturer value is nullptr");
220 return;
221 }
222
223 bool record = capturer->Record();
224 if (record) {
225 threadExit_ = false;
226 pthread_create(&dataThreadId_, nullptr, ReadAudioDataProcess, this);
227 MEDIA_INFO_LOG("create thread ReadAudioDataProcess SUCCESS");
228 }
229 WriteInt32(reply, record);
230 }
231
Stop(AudioCapturerImpl * capturer,IpcIo * reply)232 void AudioCapturerServer::Stop(AudioCapturerImpl *capturer, IpcIo *reply)
233 {
234 if (capturer == nullptr) {
235 MEDIA_ERR_LOG("Stop failed, capturer value is nullptr");
236 return;
237 }
238 int32_t ret = capturer->Stop();
239 if (dataThreadId_ != 0) {
240 threadExit_ = true;
241 pthread_join(dataThreadId_, nullptr);
242 threadExit_ = false;
243 dataThreadId_ = 0;
244 }
245 WriteInt32(reply, ret);
246 }
247
GetMiniFrameCount(IpcIo * req,IpcIo * reply)248 void AudioCapturerServer::GetMiniFrameCount(IpcIo *req, IpcIo *reply)
249 {
250 if (reply == nullptr) {
251 MEDIA_ERR_LOG("GetMinFrameCount failed, reply value is nullptr");
252 return;
253 }
254
255 int32_t sampleRate = 0;
256 ReadInt32(req, &sampleRate);
257 int32_t channelCount = 0;
258 ReadInt32(req, &channelCount);
259 uint32_t size = 0;
260 ReadUint32(req, &size);
261 AudioCodecFormat *audioFormat = (AudioCodecFormat *)ReadBuffer(req, size);
262
263 size_t frameCount;
264 bool ret = AudioCapturerImpl::GetMinFrameCount(sampleRate, channelCount, *audioFormat, frameCount);
265 WriteInt32(reply, ret);
266 WriteUint64(reply, frameCount);
267 }
268
GetFrameCount(AudioCapturerImpl * capturer,IpcIo * reply)269 void AudioCapturerServer::GetFrameCount(AudioCapturerImpl *capturer, IpcIo *reply)
270 {
271 if (capturer == nullptr) {
272 MEDIA_ERR_LOG("GetFrameCount failed, capturer value is nullptr");
273 return;
274 }
275
276 uint64_t frameCount = capturer->GetFrameCount();
277 WriteInt32(reply, MEDIA_OK);
278 WriteUint64(reply, frameCount);
279 }
280
GetStatus(AudioCapturerImpl * capturer,IpcIo * reply)281 void AudioCapturerServer::GetStatus(AudioCapturerImpl *capturer, IpcIo *reply)
282 {
283 if (capturer == nullptr) {
284 MEDIA_ERR_LOG("GetStatus failed, capturer value is nullptr");
285 return;
286 }
287
288 State status = capturer->GetStatus();
289 WriteInt32(reply, MEDIA_OK);
290 WriteInt32(reply, status);
291 }
292
SetSurface(IpcIo * req,IpcIo * reply)293 void AudioCapturerServer::SetSurface(IpcIo *req, IpcIo *reply)
294 {
295 Surface *surface = SurfaceImpl::GenericSurfaceByIpcIo(*req);
296 if (surface == nullptr) {
297 MEDIA_ERR_LOG("SetSurface failed, surface value is nullptr");
298 return;
299 }
300 int32_t ret = SetSurfaceProcess(surface);
301 WriteInt32(reply, ret);
302 }
303
Dispatch(int32_t funcId,pid_t pid,IpcIo * req,IpcIo * reply)304 void AudioCapturerServer::Dispatch(int32_t funcId, pid_t pid, IpcIo *req, IpcIo *reply)
305 {
306 if (funcId == AUD_CAP_FUNC_GET_MIN_FRAME_COUNT) {
307 return;
308 }
309 if (funcId == AUD_CAP_FUNC_CONNECT) {
310 AcceptServer(pid, reply);
311 return;
312 }
313 auto capturer = GetAudioCapturer(pid);
314 if (capturer == nullptr) {
315 MEDIA_ERR_LOG("Cannot find client object.(pid=%d)", pid);
316 WriteInt32(reply, MEDIA_IPC_FAILED);
317 return;
318 }
319 switch (funcId) {
320 case AUD_CAP_FUNC_DISCONNECT:
321 DropServer(pid, reply);
322 break;
323 case AUD_CAP_FUNC_GET_FRAME_COUNT:
324 GetFrameCount(capturer, reply);
325 break;
326 case AUD_CAP_FUNC_GET_STATUS:
327 GetStatus(capturer, reply);
328 break;
329 case AUD_CAP_FUNC_SET_INFO:
330 SetInfo(capturer, req, reply);
331 break;
332 case AUD_CAP_FUNC_GET_INFO:
333 GetInfo(capturer, reply);
334 break;
335 case AUD_CAP_FUNC_START:
336 Start(capturer, reply);
337 break;
338 case AUD_CAP_FUNC_STOP:
339 Stop(capturer, reply);
340 break;
341 case AUD_CAP_FUNC_RELEASE:
342 WriteInt32(reply, static_cast<int32_t>(capturer->Release()));
343 break;
344 case AUD_CAP_FUNC_SET_SURFACE:
345 SetSurface(req, reply);
346 break;
347 case AUD_CAP_FUNC_GET_MIN_FRAME_COUNT:
348 GetMiniFrameCount(req, reply);
349 break;
350 default:
351 break;
352 }
353 }
354 } // namespace Audio
355 } // namespace OHOS
356