1 /*
2 * Copyright (c) 2021-2022 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 #ifndef LOG_TAG
16 #define LOG_TAG "HdiSource"
17 #endif
18
19 #include <config.h>
20 #include <pulse/rtclock.h>
21 #include <pulse/timeval.h>
22 #include <pulse/util.h>
23 #include <pulse/xmalloc.h>
24 #include <pulsecore/core.h>
25 #include <pulsecore/log.h>
26 #include <pulsecore/memchunk.h>
27 #include <pulsecore/modargs.h>
28 #include <pulsecore/module.h>
29 #include <pulsecore/rtpoll.h>
30 #include <pulsecore/thread-mq.h>
31 #include <pulsecore/thread.h>
32 #include <pulsecore/mix.h>
33 #include <pulsecore/memblockq.h>
34 #include <pulsecore/source.h>
35 #include <pulsecore/source-output.h>
36
37 #include <inttypes.h>
38 #include <stddef.h>
39 #include <stdint.h>
40 #include <stdbool.h>
41 #include <time.h>
42
43 #include "source_userdata.h"
44 #include "securec.h"
45 #include "audio_hdi_log.h"
46 #include "audio_schedule.h"
47 #include "audio_source_type.h"
48 #include "common/hdi_adapter_info.h"
49 #include "source/source_intf.h"
50 #include "v5_0/audio_types.h"
51 #include "v5_0/iaudio_manager.h"
52 #include "audio_enhance_chain_adapter.h"
53 #include "audio_utils_c.h"
54
55 #define DEFAULT_SOURCE_NAME "hdi_input"
56 #define DEFAULT_DEVICE_CLASS "primary"
57 #define DEFAULT_AUDIO_DEVICE_NAME "Internal Mic"
58 #define DEFAULT_DEVICE_NETWORKID "LocalDevice"
59
60 #define DEFAULT_BUFFER_SIZE (1024 * 16)
61 #define MAX_VOLUME_VALUE 15.0
62 #define DEFAULT_LEFT_VOLUME MAX_VOLUME_VALUE
63 #define DEFAULT_RIGHT_VOLUME MAX_VOLUME_VALUE
64 #define MAX_LATENCY_USEC (PA_USEC_PER_SEC * 2)
65 #define MIN_LATENCY_USEC 500
66 #define AUDIO_POINT_NUM 1024
67 #define AUDIO_FRAME_NUM_IN_BUF 30
68 #define HDI_WAKEUP_BUFFER_TIME (PA_USEC_PER_SEC * 2)
69 #define DEVICE_TYPE_MIC 15
70 #define FRAME_DURATION_DEFAULT 20
71 #define MILLISECOND_PER_SECOND 1000
72 #define HDI_POST 100
73 #define MAX_SEND_COMMAND_LATANCY 10000
74 #define RTPOLL_RUN_WAKEUP_INTERVAL_USEC 500000
75 #define DOMAIN_ID 0xD002B89
76
77 const char *DEVICE_CLASS_REMOTE = "remote";
78 const char *DEVICE_CLASS_A2DP = "a2dp";
79 const char *ACCESSORY_SOURCE = "accessory_mic";
80 const int32_t SUCCESS = 0;
81 const int32_t ERROR = -1;
82
83 static int PaHdiCapturerInit(struct Userdata *u);
84 static void PaHdiCapturerExit(struct Userdata *u);
85
GetStateInfo(pa_source_state_t state)86 static char *GetStateInfo(pa_source_state_t state)
87 {
88 switch (state) {
89 case PA_SOURCE_INVALID_STATE:
90 return "INVALID";
91 case PA_SOURCE_RUNNING:
92 return "RUNNING";
93 case PA_SOURCE_IDLE:
94 return "IDLE";
95 case PA_SOURCE_SUSPENDED:
96 return "SUSPENDED";
97 case PA_SOURCE_INIT:
98 return "INIT";
99 case PA_SOURCE_UNLINKED:
100 return "UNLINKED";
101 default:
102 return "error state";
103 }
104 }
105
GetByteSizeByFormat(int32_t format)106 static uint32_t GetByteSizeByFormat(int32_t format)
107 {
108 uint32_t byteSize = 0;
109 switch (format) {
110 case SAMPLE_U8:
111 byteSize = BYTE_SIZE_SAMPLE_U8;
112 break;
113 case SAMPLE_S16:
114 byteSize = BYTE_SIZE_SAMPLE_S16;
115 break;
116 case SAMPLE_S24:
117 byteSize = BYTE_SIZE_SAMPLE_S24;
118 break;
119 case SAMPLE_S32:
120 byteSize = BYTE_SIZE_SAMPLE_S32;
121 break;
122 default:
123 byteSize = BYTE_SIZE_SAMPLE_S16;
124 break;
125 }
126 return byteSize;
127 }
128
CalculateFrameLen(uint32_t sampleRate,uint32_t channels,int32_t format)129 static uint64_t CalculateFrameLen(uint32_t sampleRate, uint32_t channels, int32_t format)
130 {
131 return sampleRate * channels * GetByteSizeByFormat(format) * FRAME_DURATION_DEFAULT / MILLISECOND_PER_SECOND;
132 }
133
AllocateFrameDesc(char * frame,uint64_t frameLen)134 static struct SourceAdapterFrameDesc *AllocateFrameDesc(char *frame, uint64_t frameLen)
135 {
136 struct SourceAdapterFrameDesc *fdesc = (struct SourceAdapterFrameDesc *)calloc(1,
137 sizeof(struct SourceAdapterFrameDesc));
138 if (fdesc != NULL) {
139 fdesc->frame = frame;
140 fdesc->frameLen = frameLen;
141 }
142
143 return fdesc;
144 }
145
FreeFrameDesc(struct SourceAdapterFrameDesc * fdesc)146 static void FreeFrameDesc(struct SourceAdapterFrameDesc *fdesc)
147 {
148 if (fdesc != NULL) {
149 // frame in desc is allocated outside, do not free here
150 free(fdesc);
151 }
152 }
153
InitAuxCapture(struct Userdata * u)154 static void InitAuxCapture(struct Userdata *u)
155 {
156 if (u->sourceAdapterEc != NULL) {
157 u->sourceAdapterEc->SourceAdapterInit(u->sourceAdapterEc, u->sourceAdapterEc->attr);
158 }
159 if (u->sourceAdapterMicRef != NULL) {
160 u->sourceAdapterMicRef->SourceAdapterInit(u->sourceAdapterMicRef, u->sourceAdapterMicRef->attr);
161 }
162 }
163
DeinitAuxCapture(struct Userdata * u)164 static void DeinitAuxCapture(struct Userdata *u)
165 {
166 if (u->sourceAdapterEc != NULL) {
167 u->sourceAdapterEc->SourceAdapterDeInit(u->sourceAdapterEc);
168 }
169 if (u->sourceAdapterMicRef != NULL) {
170 u->sourceAdapterMicRef->SourceAdapterDeInit(u->sourceAdapterMicRef);
171 }
172 }
173
StartAuxCapture(struct Userdata * u)174 static void StartAuxCapture(struct Userdata *u)
175 {
176 if (u->sourceAdapterEc != NULL) {
177 u->sourceAdapterEc->SourceAdapterStart(u->sourceAdapterEc);
178 }
179 if (u->sourceAdapterMicRef != NULL) {
180 u->sourceAdapterMicRef->SourceAdapterStart(u->sourceAdapterMicRef);
181 }
182 }
183
StopAuxCapture(struct Userdata * u)184 static void StopAuxCapture(struct Userdata *u)
185 {
186 if (u->sourceAdapterEc != NULL) {
187 u->sourceAdapterEc->SourceAdapterStop(u->sourceAdapterEc);
188 }
189 if (u->sourceAdapterMicRef != NULL) {
190 u->sourceAdapterMicRef->SourceAdapterStop(u->sourceAdapterMicRef);
191 }
192 }
193
FreeSceneMapsAndResampler(struct Userdata * u)194 static void FreeSceneMapsAndResampler(struct Userdata *u)
195 {
196 if (u->sceneToCountMap) {
197 pa_hashmap_free(u->sceneToCountMap);
198 }
199 if (u->sceneToPreResamplerMap) {
200 pa_hashmap_free(u->sceneToPreResamplerMap);
201 }
202 if (u->sceneToEcResamplerMap) {
203 pa_hashmap_free(u->sceneToEcResamplerMap);
204 }
205 if (u->sceneToMicRefResamplerMap) {
206 pa_hashmap_free(u->sceneToMicRefResamplerMap);
207 }
208
209 if (u->defaultSceneResampler) {
210 pa_resampler_free(u->defaultSceneResampler);
211 }
212 }
213
FreeThread(struct Userdata * u)214 static void FreeThread(struct Userdata *u)
215 {
216 if (u->threadCap) {
217 pa_thread_free(u->threadCap);
218 }
219
220 if (u->thread) {
221 pa_asyncmsgq_send(u->threadMq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL);
222 pa_thread_free(u->thread);
223 }
224
225 if (u->CaptureMq) {
226 pa_memchunk chunk;
227 int32_t code = 0;
228 int32_t missedMsgqNum = 0;
229 while (pa_asyncmsgq_get(u->CaptureMq, NULL, &code, NULL, NULL, &chunk, 0) == 0) {
230 pa_memblock_unref(chunk.memblock);
231 pa_asyncmsgq_done(u->CaptureMq, 0);
232 missedMsgqNum++;
233 }
234 if (missedMsgqNum > 0) {
235 AUDIO_ERR_LOG("OS_ProcessCapData missed message num: %{public}u", missedMsgqNum);
236 }
237 pa_asyncmsgq_unref(u->CaptureMq);
238 } else {
239 AUDIO_ERR_LOG("CaptureMq is null");
240 }
241
242 pa_thread_mq_done(&u->threadMq);
243 if (u->eventFd != 0) {
244 fdsan_close_with_tag(u->eventFd, DOMAIN_ID);
245 u->eventFd = 0;
246 }
247 if (u->rtpollItem) {
248 pa_rtpoll_item_free(u->rtpollItem);
249 u->rtpollItem = NULL;
250 }
251 }
252
UserdataFree(struct Userdata * u)253 static void UserdataFree(struct Userdata *u)
254 {
255 if (u == NULL) {
256 AUDIO_INFO_LOG("Userdata is null, free done");
257 return;
258 }
259 pa_atomic_store(&u->quitCaptureFlag, 1);
260 if (u->source) {
261 pa_source_unlink(u->source);
262 }
263
264 FreeThread(u);
265
266 if (u->source) {
267 pa_source_unref(u->source);
268 }
269
270 if (u->rtpoll) {
271 pa_rtpoll_free(u->rtpoll);
272 }
273
274 if (u->sourceAdapter) {
275 u->sourceAdapter->SourceAdapterStop(u->sourceAdapter);
276 u->sourceAdapter->SourceAdapterDeInit(u->sourceAdapter);
277 StopAuxCapture(u);
278 DeinitAuxCapture(u);
279 ReleaseSourceAdapter(u->sourceAdapterEc);
280 u->sourceAdapterEc = NULL;
281 ReleaseSourceAdapter(u->sourceAdapterMicRef);
282 u->sourceAdapterMicRef = NULL;
283 ReleaseSourceAdapter(u->sourceAdapter);
284 u->sourceAdapter = NULL;
285 }
286
287 if (u->bufferEc) {
288 free(u->bufferEc);
289 u->bufferEc = NULL;
290 }
291
292 if (u->bufferMicRef) {
293 free(u->bufferMicRef);
294 u->bufferMicRef = NULL;
295 }
296
297 FreeSceneMapsAndResampler(u);
298
299 pa_xfree(u);
300 }
301
SourceProcessMsg(pa_msgobject * o,int code,void * data,int64_t offset,pa_memchunk * chunk)302 static int SourceProcessMsg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk)
303 {
304 AUTO_CTRACE("hdi_source::SourceProcessMsg code: %d", code);
305 struct Userdata *u = PA_SOURCE(o)->userdata;
306 CHECK_AND_RETURN_RET_LOG(u != NULL, 0, "userdata is null");
307 if (code == PA_SOURCE_MESSAGE_GET_LATENCY) {
308 pa_usec_t now;
309 now = pa_rtclock_now();
310 *((int64_t*)data) = (int64_t)now - (int64_t)u->timestamp;
311 return 0;
312 }
313 AUDIO_DEBUG_LOG("SourceProcessMsg default case");
314 return pa_source_process_msg(o, code, data, offset, chunk);
315 }
316
SendInitCommandToAlgo(void)317 static void SendInitCommandToAlgo(void)
318 {
319 pa_usec_t now = pa_rtclock_now();
320 int32_t ret = EnhanceChainManagerSendInitCommand();
321 CHECK_AND_RETURN_LOG(ret == SUCCESS, "send init command failed");
322 pa_usec_t cost = pa_rtclock_now() - now;
323 if (cost > MAX_SEND_COMMAND_LATANCY) { // send command cost more than 10 ms
324 AUDIO_WARNING_LOG("send int command cost time:%{public}" PRIu64, cost);
325 }
326 }
327
328 /* Called from the IO thread. */
SourceSetStateInIoThreadCb(pa_source * s,pa_source_state_t newState,pa_suspend_cause_t newSuspendCause)329 static int SourceSetStateInIoThreadCb(pa_source *s, pa_source_state_t newState,
330 pa_suspend_cause_t newSuspendCause)
331 {
332 CHECK_AND_RETURN_RET_LOG(s != NULL, 0, "source is null");
333 struct Userdata *u = s->userdata;
334 CHECK_AND_RETURN_RET_LOG(u != NULL, 0, "userdata is null");
335 AUDIO_INFO_LOG("Source[%{public}s] state change:[%{public}s]-->[%{public}s]",
336 u->sourceAdapter->deviceClass, GetStateInfo(s->thread_info.state), GetStateInfo(newState));
337
338 if ((s->thread_info.state == PA_SOURCE_SUSPENDED || s->thread_info.state == PA_SOURCE_INIT) &&
339 PA_SOURCE_IS_OPENED(newState)) {
340 u->timestamp = pa_rtclock_now();
341 if (newState == PA_SOURCE_RUNNING && !u->isCapturerStarted) {
342 if (u->sourceAdapter->SourceAdapterStart(u->sourceAdapter)) {
343 AUDIO_ERR_LOG("HDI capturer start failed");
344 return -PA_ERR_IO;
345 }
346 StartAuxCapture(u);
347 u->isCapturerStarted = true;
348 AUDIO_DEBUG_LOG("Successfully started HDI capturer");
349 }
350 } else if (s->thread_info.state == PA_SOURCE_IDLE) {
351 if (newState == PA_SOURCE_SUSPENDED) {
352 if (u->isCapturerStarted) {
353 u->sourceAdapter->SourceAdapterStop(u->sourceAdapter);
354 u->isCapturerStarted = false;
355 AUDIO_DEBUG_LOG("Stopped HDI capturer");
356 StopAuxCapture(u);
357 SendInitCommandToAlgo();
358 }
359 } else if (newState == PA_SOURCE_RUNNING && !u->isCapturerStarted) {
360 AUDIO_DEBUG_LOG("Idle to Running starting HDI capturing device");
361 if (u->sourceAdapter->SourceAdapterStart(u->sourceAdapter)) {
362 AUDIO_ERR_LOG("Idle to Running HDI capturer start failed");
363 return -PA_ERR_IO;
364 }
365 StartAuxCapture(u);
366 u->isCapturerStarted = true;
367 AUDIO_DEBUG_LOG("Idle to Running: Successfully reinitialized HDI renderer");
368 }
369 }
370
371 return 0;
372 }
373
PushData(pa_source_output * sourceOutput,pa_memchunk * chunk)374 static void PushData(pa_source_output *sourceOutput, pa_memchunk *chunk)
375 {
376 CHECK_AND_RETURN_LOG(sourceOutput != NULL, "sourceOutput is null");
377 pa_source_output_assert_ref(sourceOutput);
378 pa_source_output_assert_io_context(sourceOutput);
379 CHECK_AND_RETURN_LOG(chunk != NULL, "chunk is null");
380 AUDIO_DEBUG_LOG("PushData chunk length: %{public}zu", chunk->length);
381
382 if (!sourceOutput->thread_info.direct_on_input) {
383 pa_source_output_push(sourceOutput, chunk);
384 }
385 }
386
PostSourceData(pa_source * source,pa_source_output * sourceOutput,pa_memchunk * chunk)387 static void PostSourceData(pa_source *source, pa_source_output *sourceOutput, pa_memchunk *chunk)
388 {
389 AUTO_CTRACE("PostSourceData");
390 CHECK_AND_RETURN_LOG(source != NULL, "source is null");
391 pa_source_assert_ref(source);
392 pa_source_assert_io_context(source);
393 pa_assert(PA_SOURCE_IS_LINKED(source->thread_info.state));
394 CHECK_AND_RETURN_LOG(chunk != NULL, "chunk is null");
395
396 if (source->thread_info.state == PA_SOURCE_SUSPENDED) {
397 return;
398 }
399
400 if (source->thread_info.soft_muted || !pa_cvolume_is_norm(&source->thread_info.soft_volume)) {
401 pa_memchunk vchunk = *chunk;
402 pa_memblock_ref(vchunk.memblock);
403 pa_memchunk_make_writable(&vchunk, 0);
404 if (source->thread_info.soft_muted || pa_cvolume_is_muted(&source->thread_info.soft_volume)) {
405 pa_silence_memchunk(&vchunk, &source->sample_spec);
406 } else {
407 pa_volume_memchunk(&vchunk, &source->sample_spec, &source->thread_info.soft_volume);
408 }
409 PushData(sourceOutput, &vchunk);
410 pa_memblock_unref(vchunk.memblock);
411 } else {
412 PushData(sourceOutput, chunk);
413 }
414 }
415
EnhanceProcess(const uint64_t sceneKeyCode,pa_memchunk * chunk)416 static void EnhanceProcess(const uint64_t sceneKeyCode, pa_memchunk *chunk)
417 {
418 CHECK_AND_RETURN_LOG(chunk != NULL, "chunk is null");
419 void *src = pa_memblock_acquire_chunk(chunk);
420 AUDIO_DEBUG_LOG("EnhanceProcess chunk length: %{public}zu sceneKey: %{public}" PRIu64,
421 chunk->length, sceneKeyCode);
422 pa_memblock_release(chunk->memblock);
423
424 if (CopyToEnhanceBufferAdapter(src, chunk->length) != 0) {
425 return;
426 }
427 if (EnhanceChainManagerProcess(sceneKeyCode, chunk->length) != 0) {
428 return;
429 }
430 void *dst = pa_memblock_acquire_chunk(chunk);
431 CopyFromEnhanceBufferAdapter(dst, chunk->length);
432 pa_memblock_release(chunk->memblock);
433 }
434
EnhanceProcessDefault(const uint32_t captureId,pa_memchunk * chunk)435 static void EnhanceProcessDefault(const uint32_t captureId, pa_memchunk *chunk)
436 {
437 CHECK_AND_RETURN_LOG(chunk != NULL, "chunk is null");
438 void *src = pa_memblock_acquire_chunk(chunk);
439 AUDIO_DEBUG_LOG("EnhanceProcessDefault chunk length: %{public}zu captureId: %{public}u", chunk->length, captureId);
440 pa_memblock_release(chunk->memblock);
441
442 if (CopyToEnhanceBufferAdapter(src, chunk->length) != 0) {
443 return;
444 }
445 if (EnhanceChainManagerProcessDefault(captureId, chunk->length) != 0) {
446 return;
447 }
448 void *dst = pa_memblock_acquire_chunk(chunk);
449 CopyFromEnhanceBufferAdapter(dst, chunk->length);
450 pa_memblock_release(chunk->memblock);
451 }
452
EnhanceProcessAndPost(struct Userdata * u,const uint64_t sceneKeyCode,pa_memchunk * enhanceChunk)453 static void EnhanceProcessAndPost(struct Userdata *u, const uint64_t sceneKeyCode, pa_memchunk *enhanceChunk)
454 {
455 AUTO_CTRACE("EnhanceProcessAndPost");
456 CHECK_AND_RETURN_LOG(u != NULL, "userdata is null");
457 CHECK_AND_RETURN_LOG(enhanceChunk != NULL, "enhanceChunk is null");
458 pa_source *source = u->source;
459 CHECK_AND_RETURN_LOG(source != NULL, "source is null");
460 pa_source_assert_ref(source);
461
462 void *state = NULL;
463 pa_source_output *sourceOutput;
464 EnhanceProcess(sceneKeyCode, enhanceChunk);
465
466 uint32_t captureId = u->captureId;
467 uint32_t renderId = u->renderId;
468 while ((sourceOutput = pa_hashmap_iterate(source->thread_info.outputs, &state, NULL))) {
469 pa_source_output_assert_ref(sourceOutput);
470 const char *sourceOutputSceneType = pa_proplist_gets(sourceOutput->proplist, "scene.type");
471 const char *defaultFlag = pa_proplist_gets(sourceOutput->proplist, "scene.default");
472 // do not process sceneDefault
473 if (pa_safe_streq(defaultFlag, "1")) {
474 continue;
475 }
476 uint64_t sceneTypeCode = 0;
477 if (GetSceneTypeCode(sourceOutputSceneType, &sceneTypeCode) != 0) {
478 continue;
479 }
480 uint64_t sceneKeyCodeTemp = 0;
481 sceneKeyCodeTemp = (sceneTypeCode << SCENE_TYPE_OFFSET) + (captureId << CAPTURER_ID_OFFSET) + renderId;
482 if (sceneKeyCode != sceneKeyCodeTemp) {
483 continue;
484 }
485 PostSourceData(source, sourceOutput, enhanceChunk);
486 }
487 }
488
PostDataBypass(pa_source * source,pa_memchunk * chunk)489 static void PostDataBypass(pa_source *source, pa_memchunk *chunk)
490 {
491 CHECK_AND_RETURN_LOG(source != NULL, "source is null");
492 pa_source_assert_ref(source);
493 CHECK_AND_RETURN_LOG(chunk != NULL, "chunk is null");
494 void *state = NULL;
495 pa_source_output *sourceOutput;
496 while ((sourceOutput = pa_hashmap_iterate(source->thread_info.outputs, &state, NULL))) {
497 pa_source_output_assert_ref(sourceOutput);
498 const char *sourceOutputSceneBypass = pa_proplist_gets(sourceOutput->proplist, "scene.bypass");
499 if (sourceOutputSceneBypass == NULL) {
500 continue;
501 }
502 if (strcmp(sourceOutputSceneBypass, DEFAULT_SCENE_BYPASS) == 0) {
503 PostSourceData(source, sourceOutput, chunk);
504 }
505 }
506 }
507
CheckSameAdapterEcLength(uint64_t request,uint64_t reply,uint64_t requestEc,uint64_t replyEc)508 static int32_t CheckSameAdapterEcLength(uint64_t request, uint64_t reply, uint64_t requestEc, uint64_t replyEc)
509 {
510 if ((reply == 0) || (replyEc == 0) || (request != reply) || (requestEc != replyEc)) {
511 return -1;
512 }
513 return 0;
514 }
515
CheckDiffAdapterEcLength(uint64_t request,uint64_t reply,uint64_t requestEc,uint64_t replyEc)516 static int32_t CheckDiffAdapterEcLength(uint64_t request, uint64_t reply, uint64_t requestEc, uint64_t replyEc)
517 {
518 if ((reply == 0) || (replyEc == 0) || (request != reply) || (requestEc != replyEc)) {
519 return -1;
520 }
521 return 0;
522 }
523
HandleCaptureFrame(struct Userdata * u,char * buffer,uint64_t requestBytes,uint64_t * replyBytes)524 static int32_t HandleCaptureFrame(struct Userdata *u, char *buffer, uint64_t requestBytes, uint64_t *replyBytes)
525 {
526 uint64_t replyBytesEc = 0;
527 if (u->ecType == EC_NONE) {
528 u->sourceAdapter->SourceAdapterCaptureFrame(u->sourceAdapter, buffer, requestBytes, replyBytes);
529 }
530 if (u->ecType == EC_SAME_ADAPTER) {
531 struct SourceAdapterFrameDesc *fdesc = AllocateFrameDesc(buffer, requestBytes);
532 struct SourceAdapterFrameDesc *fdescEc = AllocateFrameDesc((char *)(u->bufferEc), u->requestBytesEc);
533 u->sourceAdapter->SourceAdapterCaptureFrameWithEc(u->sourceAdapter,
534 fdesc, replyBytes, fdescEc, &replyBytesEc);
535 FreeFrameDesc(fdesc);
536 FreeFrameDesc(fdescEc);
537 if (CheckSameAdapterEcLength(requestBytes, *replyBytes, u->requestBytesEc, replyBytesEc)) {
538 u->requestBytesEc = 0;
539 }
540 }
541 if (u->ecType == EC_DIFFERENT_ADAPTER) {
542 u->sourceAdapter->SourceAdapterCaptureFrame(u->sourceAdapter, buffer, requestBytes, replyBytes);
543 if (u->sourceAdapterEc != NULL) {
544 struct SourceAdapterFrameDesc *fdesc = AllocateFrameDesc(NULL, requestBytes);
545 struct SourceAdapterFrameDesc *fdescEc = AllocateFrameDesc((char *)(u->bufferEc), u->requestBytesEc);
546 uint64_t replyBytesUnused = 0;
547 u->sourceAdapterEc->SourceAdapterCaptureFrameWithEc(u->sourceAdapterEc,
548 fdesc, &replyBytesUnused, fdescEc, &replyBytesEc);
549 FreeFrameDesc(fdesc);
550 FreeFrameDesc(fdescEc);
551 if (CheckDiffAdapterEcLength(requestBytes, *replyBytes, u->requestBytesEc, replyBytesEc)) {
552 u->requestBytesEc = 0;
553 }
554 }
555 }
556 uint64_t replyBytesMicRef = 0;
557 if (u->micRef == REF_ON) {
558 u->sourceAdapterMicRef->SourceAdapterCaptureFrame(u->sourceAdapterMicRef,
559 (char *)(u->bufferMicRef), u->requestBytesMicRef, &replyBytesMicRef);
560 if ((replyBytesMicRef == 0) && (u->requestBytesMicRef != replyBytesMicRef)) {
561 u->bufferMicRef = 0;
562 }
563 }
564 return 0;
565 }
566
GetCapturerFrameFromHdi(pa_memchunk * chunk,struct Userdata * u)567 static int GetCapturerFrameFromHdi(pa_memchunk *chunk, struct Userdata *u)
568 {
569 AUTO_CTRACE("GetCapturerFrameFromHdi");
570 uint64_t requestBytes = 0;
571 uint64_t replyBytes = 0;
572
573 void *p = NULL;
574 CHECK_AND_RETURN_RET_LOG(chunk != NULL, 0, "chunk is null");
575 CHECK_AND_RETURN_RET_LOG(chunk->memblock != NULL, 0, "chunk->memblock is null");
576 p = pa_memblock_acquire(chunk->memblock);
577 CHECK_AND_RETURN_RET_LOG(p != NULL, 0, "p is null");
578 requestBytes = pa_memblock_get_length(chunk->memblock);
579 HandleCaptureFrame(u, (char *)p, requestBytes, &replyBytes);
580 pa_memblock_release(chunk->memblock);
581
582 AUDIO_DEBUG_LOG("HDI Source: request bytes: %{public}" PRIu64 ", replyBytes: %{public}" PRIu64,
583 requestBytes, replyBytes);
584
585 if (replyBytes > requestBytes) {
586 AUDIO_ERR_LOG("HDI Source: Error replyBytes > requestBytes. Requested data Length: "
587 "%{public}" PRIu64 ", Read: %{public}" PRIu64 " bytes", requestBytes, replyBytes);
588 pa_memblock_unref(chunk->memblock);
589 return -1;
590 }
591 if (replyBytes == 0) {
592 AUDIO_ERR_LOG("HDI Source: Failed to read, Requested data Length: %{public}" PRIu64 " bytes,"
593 " Read: %{public}" PRIu64 " bytes", requestBytes, replyBytes);
594 pa_memblock_unref(chunk->memblock);
595 return -1;
596 }
597 chunk->index = 0;
598 chunk->length = replyBytes;
599
600 return 0;
601 }
602
SampleAlignment(const char * sceneKey,pa_memchunk * enhanceChunk,pa_memchunk * rChunk,struct Userdata * u)603 static int32_t SampleAlignment(const char *sceneKey, pa_memchunk *enhanceChunk, pa_memchunk *rChunk, struct Userdata *u)
604 {
605 CHECK_AND_RETURN_RET_LOG(sceneKey != NULL, ERROR, "sceneKey is null");
606 CHECK_AND_RETURN_RET_LOG(enhanceChunk != NULL, ERROR, "enhanceChunk is null");
607 CHECK_AND_RETURN_RET_LOG(u != NULL, ERROR, "Userdata is null");
608
609 pa_resampler *resampler = (pa_resampler *)pa_hashmap_get(u->sceneToPreResamplerMap, sceneKey);
610 if (resampler != NULL) {
611 pa_resampler_run(resampler, enhanceChunk, rChunk);
612 } else {
613 *rChunk = *enhanceChunk;
614 pa_memblock_ref(rChunk->memblock);
615 }
616 return SUCCESS;
617 }
618
PostDataDefault(pa_source * source,pa_memchunk * chunk,struct Userdata * u)619 static void PostDataDefault(pa_source *source, pa_memchunk *chunk, struct Userdata *u)
620 {
621 CHECK_AND_RETURN_LOG(source != NULL, "source is null");
622 pa_source_assert_ref(source);
623 CHECK_AND_RETURN_LOG(chunk != NULL, "chunk is null");
624
625 bool hasDefaultStream = false;
626 pa_source_output *sourceOutput;
627 void *state = NULL;
628 while ((sourceOutput = pa_hashmap_iterate(source->thread_info.outputs, &state, NULL))) {
629 pa_source_output_assert_ref(sourceOutput);
630 const char *defaultFlag = pa_proplist_gets(sourceOutput->proplist, "scene.default");
631 // process only sceneDefault
632 if (!pa_safe_streq(defaultFlag, "1")) {
633 continue;
634 }
635 hasDefaultStream = true;
636 }
637 if (!hasDefaultStream) { return; }
638
639 pa_memchunk enhanceChunk;
640 pa_memchunk rChunk;
641 enhanceChunk.length = chunk->length;
642 enhanceChunk.memblock = pa_memblock_new(u->core->mempool, enhanceChunk.length);
643 pa_memchunk_memcpy(&enhanceChunk, chunk);
644
645 pa_resampler *resampler = u->defaultSceneResampler;
646 if (resampler) {
647 pa_resampler_run(resampler, &enhanceChunk, &rChunk);
648 } else {
649 rChunk = enhanceChunk;
650 pa_memblock_ref(rChunk.memblock);
651 }
652 EnhanceProcessDefault(u->captureId, &rChunk);
653
654 while ((sourceOutput = pa_hashmap_iterate(source->thread_info.outputs, &state, NULL))) {
655 pa_source_output_assert_ref(sourceOutput);
656 const char *defaultFlag = pa_proplist_gets(sourceOutput->proplist, "scene.default");
657 // process only sceneDefault
658 if (!pa_safe_streq(defaultFlag, "1")) {
659 continue;
660 }
661 PostSourceData(source, sourceOutput, &rChunk);
662 }
663
664 pa_memblock_unref(enhanceChunk.memblock);
665 if (rChunk.memblock) {
666 pa_memblock_unref(rChunk.memblock);
667 }
668 }
669
EcResample(const char * sceneKey,struct Userdata * u)670 static int32_t EcResample(const char *sceneKey, struct Userdata *u)
671 {
672 pa_resampler *ecResampler = (pa_resampler *)pa_hashmap_get(u->sceneToEcResamplerMap, sceneKey);
673
674 CHECK_AND_RETURN_RET_LOG(u->bufferEc != NULL, ERROR, "bufferEc is null");
675 CHECK_AND_RETURN_RET_LOG(u->requestBytesEc != 0, ERROR, "requestBytesEc is 0");
676 if (ecResampler != NULL) {
677 pa_memchunk ecChunk;
678 pa_memchunk rEcChunk;
679 ecChunk.length = u->requestBytesEc;
680 ecChunk.memblock = pa_memblock_new_fixed(u->core->mempool, u->bufferEc, ecChunk.length, 1);
681 pa_resampler_run(ecResampler, &ecChunk, &rEcChunk);
682 void *srcEc = pa_memblock_acquire_chunk(&rEcChunk);
683 AUDIO_DEBUG_LOG("ec chunk length: %{public}zu sceneKey: %{public}s", rEcChunk.length, sceneKey);
684 CopyEcdataToEnhanceBufferAdapter(srcEc, rEcChunk.length);
685 pa_memblock_release(rEcChunk.memblock);
686 pa_memblock_unref(ecChunk.memblock);
687 pa_memblock_unref(rEcChunk.memblock);
688 } else {
689 CopyEcdataToEnhanceBufferAdapter(u->bufferEc, u->requestBytesEc);
690 }
691 return SUCCESS;
692 }
693
MicRefResample(const char * sceneKey,struct Userdata * u)694 static int32_t MicRefResample(const char *sceneKey, struct Userdata *u)
695 {
696 pa_resampler *micRefResampler = (pa_resampler *)pa_hashmap_get(u->sceneToMicRefResamplerMap, sceneKey);
697
698 CHECK_AND_RETURN_RET_LOG(u->bufferMicRef != NULL, ERROR, "bufferMicRef is null");
699 CHECK_AND_RETURN_RET_LOG(u->requestBytesMicRef != 0, ERROR, "requestBytesMicRef is 0");
700 if (micRefResampler != NULL) {
701 pa_memchunk micRefChunk;
702 pa_memchunk rMicRefChunk;
703 micRefChunk.length = u->requestBytesMicRef;
704 micRefChunk.memblock = pa_memblock_new_fixed(u->core->mempool, u->bufferMicRef, micRefChunk.length, 1);
705 pa_resampler_run(micRefResampler, &micRefChunk, &rMicRefChunk);
706 void *srcMicRef = pa_memblock_acquire_chunk(&rMicRefChunk);
707 AUDIO_DEBUG_LOG("micRef chunk length: %{public}zu sceneKey: %{public}s", rMicRefChunk.length, sceneKey);
708 CopyMicRefdataToEnhanceBufferAdapter(srcMicRef, rMicRefChunk.length);
709 pa_memblock_release(rMicRefChunk.memblock);
710 pa_memblock_unref(micRefChunk.memblock);
711 pa_memblock_unref(rMicRefChunk.memblock);
712 } else {
713 CopyMicRefdataToEnhanceBufferAdapter(u->bufferMicRef, u->requestBytesMicRef);
714 }
715 return SUCCESS;
716 }
717
AudioEnhanceExistAndProcess(pa_memchunk * chunk,struct Userdata * u)718 static int32_t AudioEnhanceExistAndProcess(pa_memchunk *chunk, struct Userdata *u)
719 {
720 AUTO_CTRACE("AudioEnhanceExistAndProcess");
721
722 bool ret = EnhanceChainManagerIsEmptyEnhanceChain();
723 if (ret) {
724 // if none enhance chain exist, post data as the original method
725 pa_source_post(u->source, chunk);
726 pa_memblock_unref(chunk->memblock);
727 return 0;
728 }
729
730 PostDataBypass(u->source, chunk);
731 PostDataDefault(u->source, chunk, u);
732 void *state = NULL;
733 uint32_t *sceneKeyNum;
734 const void *sceneKey;
735 while ((sceneKeyNum = pa_hashmap_iterate(u->sceneToCountMap, &state, &sceneKey))) {
736 uint64_t sceneKeyCode = (uint64_t)strtoul((char *)sceneKey, NULL, BASE_TEN);
737 AUDIO_DEBUG_LOG("Now sceneKeyCode is : %{public}" PRIu64, sceneKeyCode);
738
739 pa_memchunk enhanceChunk;
740 pa_memchunk rChunk;
741 enhanceChunk.length = chunk->length;
742 enhanceChunk.memblock = pa_memblock_new(u->core->mempool, enhanceChunk.length);
743 pa_memchunk_memcpy(&enhanceChunk, chunk);
744 SampleAlignment((char *)sceneKey, &enhanceChunk, &rChunk, u);
745 if (u->ecType != EC_NONE) {
746 EcResample((char *)sceneKey, u);
747 }
748 if (u->micRef == REF_ON) {
749 MicRefResample((char *)sceneKey, u);
750 }
751 EnhanceProcessAndPost(u, sceneKeyCode, &rChunk);
752 pa_memblock_unref(enhanceChunk.memblock);
753 pa_memblock_unref(rChunk.memblock);
754 }
755 pa_memblock_unref(chunk->memblock);
756
757 return 0;
758 }
759
ThreadCaptureSleep(pa_usec_t sleepTime)760 static void ThreadCaptureSleep(pa_usec_t sleepTime)
761 {
762 struct timespec req;
763 struct timespec rem;
764 req.tv_sec = 0;
765 req.tv_nsec = (int64_t)(sleepTime * MILLISECOND_PER_SECOND);
766 clock_nanosleep(CLOCK_REALTIME, 0, &req, &rem);
767 AUDIO_DEBUG_LOG("ThreadCaptureData sleep:%{public}" PRIu64, sleepTime);
768 }
769
ThreadCaptureData(void * userdata)770 static void ThreadCaptureData(void *userdata)
771 {
772 struct Userdata *u = userdata;
773 CHECK_AND_RETURN_LOG(u != NULL, "u is null");
774 // set audio thread priority
775 ScheduleThreadInServer(getpid(), gettid());
776
777 pa_memchunk chunk;
778 int32_t ret = 0;
779 pa_usec_t now = 0;
780 pa_usec_t cost = 0;
781
782 while (!pa_atomic_load(&u->quitCaptureFlag)) {
783 if (pa_atomic_load(&u->captureFlag) == 1) {
784 AUTO_CTRACE("ThreadCaptureDataLoop");
785 now = pa_rtclock_now();
786 chunk.length = u->bufferSize;
787 AUDIO_DEBUG_LOG("HDI Source: chunk.length = u->bufferSize: %{public}zu", chunk.length);
788 chunk.memblock = pa_memblock_new(u->core->mempool, chunk.length);
789 ret = GetCapturerFrameFromHdi(&chunk, u);
790 if (ret != 0) {
791 AUDIO_ERR_LOG("GetCapturerFrameFromHdi failed");
792 continue;
793 }
794 pa_asyncmsgq_post(u->CaptureMq, NULL, HDI_POST, NULL, 0, &chunk, NULL);
795 eventfd_t writEvent = 1;
796 int32_t writeRes = eventfd_write(u->eventFd, writEvent);
797 if (writeRes != 0) {
798 AUDIO_ERR_LOG("Failed to write to eventfd");
799 continue;
800 }
801 cost = pa_rtclock_now() - now;
802 AUDIO_DEBUG_LOG("capture frame cost :%{public}" PRIu64, cost);
803 } else {
804 ThreadCaptureSleep(u->blockUsec);
805 }
806 }
807 UnscheduleThreadInServer(getpid(), gettid());
808 AUDIO_INFO_LOG("ThreadCaptureData quit pid %{public}d, tid %{public}d", getpid(), gettid());
809 }
810
PaRtpollProcessFunc(struct Userdata * u)811 static void PaRtpollProcessFunc(struct Userdata *u)
812 {
813 AUTO_CTRACE("PaRtpollProcessFunc");
814
815 eventfd_t value;
816 int32_t readRet = eventfd_read(u->eventFd, &value);
817 CHECK_AND_RETURN_LOG((u->source->thread_info.state == PA_SOURCE_RUNNING) || (readRet == 0),
818 "Failed to read from eventfd");
819
820 pa_memchunk chunk;
821 int32_t code = 0;
822 pa_usec_t now = pa_rtclock_now();
823
824 while (pa_asyncmsgq_get(u->CaptureMq, NULL, &code, NULL, NULL, &chunk, 0) == 0) {
825 if (u->source->thread_info.state != PA_SOURCE_RUNNING) {
826 // when the source is not in running state, but we still recive data from CaptureMq.
827 pa_memblock_unref(chunk.memblock);
828 pa_asyncmsgq_done(u->CaptureMq, 0);
829 continue;
830 }
831 AudioEnhanceExistAndProcess(&chunk, u);
832 pa_asyncmsgq_done(u->CaptureMq, 0);
833 }
834
835 int32_t appsUid[PA_MAX_OUTPUTS_PER_SOURCE];
836 int32_t sessionId[PA_MAX_OUTPUTS_PER_SOURCE];
837 size_t count = 0;
838 size_t sessionIdCount = 0;
839 memset_s(sessionId, PA_MAX_OUTPUTS_PER_SOURCE * sizeof(uint32_t), 0, PA_MAX_OUTPUTS_PER_SOURCE * sizeof(uint32_t));
840
841 void *state = NULL;
842 pa_source_output *sourceOutput;
843 while ((sourceOutput = pa_hashmap_iterate(u->source->thread_info.outputs, &state, NULL))) {
844 const char *cstringClientUid = pa_proplist_gets(sourceOutput->proplist, "stream.client.uid");
845 if (cstringClientUid && (sourceOutput->thread_info.state == PA_SOURCE_OUTPUT_RUNNING)) {
846 appsUid[count++] = atoi(cstringClientUid);
847 }
848 const char *sessionIdInChar = pa_proplist_gets(sourceOutput->proplist, "stream.sessionID");
849 if (sessionIdInChar && (sourceOutput->thread_info.state == PA_SOURCE_OUTPUT_RUNNING) && u->sourceAdapter) {
850 sessionId[sessionIdCount++] = atoi(sessionIdInChar);
851 }
852 }
853
854 if (u->sourceAdapter) {
855 u->sourceAdapter->SourceAdapterUpdateAppsUid(u->sourceAdapter, appsUid, count);
856 u->sourceAdapter->SourceAdapterUpdateSessionUid(u->sourceAdapter, sessionId, sessionIdCount);
857 }
858
859 pa_usec_t costTime = pa_rtclock_now() - now;
860 AUDIO_DEBUG_LOG("enhance process and post costTime:%{public}" PRIu64, costTime);
861 return;
862 }
863
ThreadFuncProcessTimer(void * userdata)864 static void ThreadFuncProcessTimer(void *userdata)
865 {
866 struct Userdata *u = userdata;
867
868 // set audio thread priority
869 ScheduleThreadInServer(getpid(), gettid());
870 CHECK_AND_RETURN_LOG(u != NULL, "u is null");
871
872 pa_thread_mq_install(&u->threadMq);
873 u->timestamp = pa_rtclock_now();
874
875 AUDIO_DEBUG_LOG("HDI Source: u->timestamp : %{public}" PRIu64, u->timestamp);
876
877 if (u->rtpollItem) {
878 struct pollfd *pollFd = pa_rtpoll_item_get_pollfd(u->rtpollItem, NULL);
879 CHECK_AND_BREAK_LOG(pollFd != NULL, "pollFd is null");
880 pollFd->events = POLLIN;
881 }
882
883 while (true) {
884 bool flag = (u->attrs.sourceType == SOURCE_TYPE_WAKEUP) ?
885 (u->source->thread_info.state == PA_SOURCE_RUNNING && u->isCapturerStarted) :
886 (PA_SOURCE_IS_OPENED(u->source->thread_info.state) && u->isCapturerStarted);
887 pa_atomic_store(&u->captureFlag, flag);
888 if (flag) {
889 pa_rtpoll_set_timer_relative(u->rtpoll, RTPOLL_RUN_WAKEUP_INTERVAL_USEC);
890 } else {
891 pa_rtpoll_set_timer_disabled(u->rtpoll);
892 }
893 AUTO_CTRACE("Process Capture Data Loop");
894 /* Hmm, nothing to do. Let's sleep */
895 int ret = pa_rtpoll_run(u->rtpoll);
896 if (ret < 0) {
897 /* If this was no regular exit from the loop we have to continue
898 * processing messages until we received PA_MESSAGE_SHUTDOWN */
899 AUDIO_ERR_LOG("HDI Source: pa_rtpoll_run ret:%{public}d failed", ret);
900 pa_asyncmsgq_post(u->threadMq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module,
901 0, NULL, NULL);
902 pa_asyncmsgq_wait_for(u->threadMq.inq, PA_MESSAGE_SHUTDOWN);
903 break;
904 }
905 if (ret == 0) {
906 AUDIO_INFO_LOG("Thread OS_ProcessCapData shutting down, pid %{public}d, tid %{public}d",
907 getpid(), gettid());
908 break;
909 }
910 PaRtpollProcessFunc(u);
911 }
912 UnscheduleThreadInServer(getpid(), gettid());
913 }
914
PaHdiCapturerInit(struct Userdata * u)915 static int PaHdiCapturerInit(struct Userdata *u)
916 {
917 int ret;
918 ret = u->sourceAdapter->SourceAdapterInit(u->sourceAdapter, &u->attrs);
919 if (ret != 0) {
920 AUDIO_ERR_LOG("Audio capturer init failed!");
921 return ret;
922 }
923 InitAuxCapture(u);
924
925 u->captureId = u->sourceAdapter->captureId;
926 u->renderId = 0;
927
928 #ifdef IS_EMULATOR
929 // Due to the peculiar implementation of the emulator's HDI,
930 // an initial start and stop sequence is required to circumvent protential issues and ensure proper functionality.
931 AUDIO_INFO_LOG("do start and stop");
932 u->sourceAdapter->CapturerSourceStart(u->sourceAdapter->wapper);
933 u->sourceAdapter->CapturerSourceStop(u->sourceAdapter->wapper);
934 #endif
935
936 u->isCapturerStarted = false;
937 return ret;
938 }
939
PaHdiCapturerExit(struct Userdata * u)940 static void PaHdiCapturerExit(struct Userdata *u)
941 {
942 CHECK_AND_RETURN_LOG(u != NULL, "u is null");
943 CHECK_AND_RETURN_LOG((u->sourceAdapter) != NULL, " u->sourceAdapter is null");
944 u->sourceAdapter->SourceAdapterStop(u->sourceAdapter);
945 u->sourceAdapter->SourceAdapterDeInit(u->sourceAdapter);
946 StopAuxCapture(u);
947 DeinitAuxCapture(u);
948 }
949
PaSetSourceProperties(pa_module * m,pa_modargs * ma,const pa_sample_spec * ss,const pa_channel_map * map,struct Userdata * u)950 static int PaSetSourceProperties(pa_module *m, pa_modargs *ma, const pa_sample_spec *ss, const pa_channel_map *map,
951 struct Userdata *u)
952 {
953 pa_source_new_data data;
954
955 pa_source_new_data_init(&data);
956 data.driver = __FILE__;
957 data.module = m;
958
959 pa_source_new_data_set_name(&data, pa_modargs_get_value(ma, "source_name", DEFAULT_SOURCE_NAME));
960 pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING,
961 (u->attrs.adapterName ? u->attrs.adapterName : DEFAULT_AUDIO_DEVICE_NAME));
962 pa_proplist_setf(data.proplist, PA_PROP_DEVICE_DESCRIPTION, "HDI source is %s",
963 (u->attrs.adapterName ? u->attrs.adapterName : DEFAULT_AUDIO_DEVICE_NAME));
964 pa_source_new_data_set_sample_spec(&data, ss);
965 pa_source_new_data_set_channel_map(&data, map);
966 pa_proplist_setf(data.proplist, PA_PROP_DEVICE_BUFFERING_BUFFER_SIZE, "%lu", (unsigned long)u->bufferSize);
967
968 // set suspend on idle timeout to 0s
969 pa_proplist_setf(data.proplist, "module-suspend-on-idle.timeout", "%d", 0);
970
971 if (pa_modargs_get_proplist(ma, "source_properties", data.proplist, PA_UPDATE_REPLACE) < 0) {
972 AUDIO_ERR_LOG("Invalid properties");
973 pa_source_new_data_done(&data);
974 return -1;
975 }
976
977 u->source = pa_source_new(m->core, &data, PA_SOURCE_HARDWARE | PA_SOURCE_LATENCY | PA_SOURCE_DYNAMIC_LATENCY);
978 pa_source_new_data_done(&data);
979
980 if (!u->source) {
981 AUDIO_ERR_LOG("Failed to create source object");
982 return -1;
983 }
984
985 u->source->parent.process_msg = SourceProcessMsg;
986 u->source->set_state_in_io_thread = SourceSetStateInIoThreadCb;
987 u->source->userdata = u;
988
989 pa_source_set_asyncmsgq(u->source, u->threadMq.inq);
990 pa_source_set_rtpoll(u->source, u->rtpoll);
991
992 u->blockUsec = pa_bytes_to_usec(u->bufferSize, &u->source->sample_spec);
993 pa_source_set_latency_range(u->source, 0, u->blockUsec);
994 u->source->thread_info.max_rewind = pa_usec_to_bytes(u->blockUsec, &u->source->sample_spec);
995
996 return 0;
997 }
998
ConvertPaToHdiAdapterFormat(pa_sample_format_t format)999 static enum AudioSampleFormatIntf ConvertPaToHdiAdapterFormat(pa_sample_format_t format)
1000 {
1001 enum AudioSampleFormatIntf adapterFormat;
1002 switch (format) {
1003 case PA_SAMPLE_U8:
1004 adapterFormat = SAMPLE_U8;
1005 break;
1006 case PA_SAMPLE_S16LE:
1007 case PA_SAMPLE_S16BE:
1008 adapterFormat = SAMPLE_S16;
1009 break;
1010 case PA_SAMPLE_S24LE:
1011 case PA_SAMPLE_S24BE:
1012 adapterFormat = SAMPLE_S24;
1013 break;
1014 case PA_SAMPLE_S32LE:
1015 case PA_SAMPLE_S32BE:
1016 adapterFormat = SAMPLE_S32;
1017 break;
1018 default:
1019 adapterFormat = SAMPLE_S16;
1020 break;
1021 }
1022
1023 return adapterFormat;
1024 }
1025
GetEndianInfo(pa_sample_format_t format)1026 static bool GetEndianInfo(pa_sample_format_t format)
1027 {
1028 bool isBigEndian = false;
1029 switch (format) {
1030 case PA_SAMPLE_S16BE:
1031 case PA_SAMPLE_S24BE:
1032 case PA_SAMPLE_S32BE:
1033 case PA_SAMPLE_FLOAT32BE:
1034 case PA_SAMPLE_S24_32BE:
1035 isBigEndian = true;
1036 break;
1037 default:
1038 isBigEndian = false;
1039 break;
1040 }
1041
1042 return isBigEndian;
1043 }
1044
InitUserdataAttrs(pa_modargs * ma,struct Userdata * u,const pa_sample_spec * ss)1045 static void InitUserdataAttrs(pa_modargs *ma, struct Userdata *u, const pa_sample_spec *ss)
1046 {
1047 if (pa_modargs_get_value_s32(ma, "source_type", &u->attrs.sourceType) < 0) {
1048 AUDIO_ERR_LOG("Failed to parse source_type argument");
1049 }
1050
1051 if (pa_modargs_get_value_u32(ma, "buffer_size", &u->bufferSize) < 0) {
1052 AUDIO_ERR_LOG("Failed to parse buffer_size argument.");
1053 u->bufferSize = DEFAULT_BUFFER_SIZE;
1054 }
1055 u->attrs.bufferSize = u->bufferSize;
1056
1057 u->attrs.sampleRate = ss->rate;
1058 u->attrs.filePath = pa_modargs_get_value(ma, "file_path", "");
1059 if (pa_modargs_get_value_u32(ma, "open_mic_speaker", &u->openMicSpeaker) < 0) {
1060 AUDIO_ERR_LOG("Failed to parse open_mic_speaker argument");
1061 }
1062 u->attrs.channel = ss->channels;
1063 u->attrs.format = ConvertPaToHdiAdapterFormat(ss->format);
1064 u->attrs.isBigEndian = GetEndianInfo(ss->format);
1065 u->attrs.adapterName = pa_modargs_get_value(ma, "adapter_name", DEFAULT_DEVICE_CLASS);
1066 u->attrs.deviceNetworkId = pa_modargs_get_value(ma, "network_id", DEFAULT_DEVICE_NETWORKID);
1067 if (pa_modargs_get_value_s32(ma, "device_type", &u->attrs.deviceType) < 0) {
1068 AUDIO_ERR_LOG("Failed to parse deviceType argument");
1069 }
1070
1071 AUDIO_DEBUG_LOG("AudioDeviceCreateCapture format: %{public}d, isBigEndian: %{public}d channel: %{public}d,"
1072 "sampleRate: %{public}d", u->attrs.format, u->attrs.isBigEndian, u->attrs.channel, u->attrs.sampleRate);
1073
1074 u->attrs.openMicSpeaker = u->openMicSpeaker;
1075
1076 u->sceneToCountMap = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func,
1077 pa_xfree, pa_xfree);
1078
1079 u->sceneToPreResamplerMap = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func,
1080 pa_xfree, (pa_free_cb_t) pa_resampler_free);
1081
1082 u->sceneToEcResamplerMap = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func,
1083 pa_xfree, (pa_free_cb_t) pa_resampler_free);
1084
1085 u->sceneToMicRefResamplerMap = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func,
1086 pa_xfree, (pa_free_cb_t) pa_resampler_free);
1087 }
1088
InitDifferentAdapterEcAttr(struct Userdata * u,struct SourceAdapterAttr * attr)1089 static void InitDifferentAdapterEcAttr(struct Userdata *u, struct SourceAdapterAttr *attr)
1090 {
1091 // set attr for different adapter ec
1092 attr->sourceType = SOURCE_TYPE_EC;
1093 // device attrs
1094 attr->adapterName = u->ecAdapaterName;
1095 attr->deviceType = DEVICE_TYPE_MIC; // not needed, updateAudioRoute later
1096 // common audio attrs
1097 attr->sampleRate = u->ecSamplingRate;
1098 attr->channel = u->ecChannels;
1099 attr->format = u->ecFormat;
1100 attr->isBigEndian = false;
1101 attr->openMicSpeaker = u->openMicSpeaker;
1102 }
1103
InitMicRefAttr(struct Userdata * u,struct SourceAdapterAttr * attr)1104 static void InitMicRefAttr(struct Userdata *u, struct SourceAdapterAttr *attr)
1105 {
1106 // set attr for mic ref
1107 attr->sourceType = SOURCE_TYPE_MIC_REF;
1108 // device attrs
1109 attr->adapterName = "primary";
1110 attr->deviceType = DEVICE_TYPE_MIC;
1111 // common audio attrs
1112 attr->sampleRate = u->micRefRate;
1113 attr->channel = u->micRefChannels;
1114 attr->format = u->micRefFormat;
1115 attr->isBigEndian = false;
1116 attr->openMicSpeaker = u->openMicSpeaker;
1117 }
1118
InitSampleSpec(pa_sample_spec * spec,const uint32_t sampleRate,const pa_sample_format_t format,const uint32_t channels)1119 static void InitSampleSpec(pa_sample_spec *spec, const uint32_t sampleRate,
1120 const pa_sample_format_t format, const uint32_t channels)
1121 {
1122 pa_sample_spec_init(spec);
1123 spec->rate = sampleRate;
1124 spec->channels = (uint8_t)channels;
1125 spec->format = format;
1126 }
1127
InitEcAndMicRefAttrs(pa_modargs * ma,struct Userdata * u)1128 static void InitEcAndMicRefAttrs(pa_modargs *ma, struct Userdata *u)
1129 {
1130 if (pa_modargs_get_value_u32(ma, "ec_type", &u->ecType) < 0) {
1131 u->ecType = EC_NONE;
1132 }
1133 u->ecAdapaterName = pa_modargs_get_value(ma, "ec_adapter", "");
1134 if (pa_modargs_get_value_u32(ma, "ec_sampling_rate", &u->ecSamplingRate) < 0) {
1135 u->ecSamplingRate = 0;
1136 }
1137 const char *ecFormatStr = pa_modargs_get_value(ma, "ec_format", "");
1138 u->ecFormat = ConvertPaToHdiAdapterFormat(pa_parse_sample_format(ecFormatStr));
1139 if (pa_modargs_get_value_u32(ma, "ec_channels", &u->ecChannels) < 0) {
1140 u->ecChannels = 0;
1141 }
1142 InitSampleSpec(&u->ecSpec, u->ecSamplingRate, pa_parse_sample_format(ecFormatStr), u->ecChannels);
1143 if (pa_modargs_get_value_u32(ma, "open_mic_ref", &u->micRef) < 0) {
1144 u->micRef = REF_OFF;
1145 }
1146 if (pa_modargs_get_value_u32(ma, "mic_ref_rate", &u->micRefRate) < 0) {
1147 u->micRefRate = 0;
1148 }
1149 const char *micRefFormatStr = pa_modargs_get_value(ma, "mic_ref_format", "");
1150 u->micRefFormat = ConvertPaToHdiAdapterFormat(pa_parse_sample_format(micRefFormatStr));
1151 if (pa_modargs_get_value_u32(ma, "mic_ref_channels", &u->micRefChannels) < 0) {
1152 u->micRefChannels = 0;
1153 }
1154 InitSampleSpec(&u->micRefSpec, u->micRefRate, pa_parse_sample_format(micRefFormatStr), u->micRefChannels);
1155 AUDIO_INFO_LOG("ecType: %{public}d, ecAdapaterName: %{public}s, ecSamplingRate: %{public}d ecFormat: %{public}d,"
1156 " ecChannels: %{public}d, micRef: %{public}d, micRefRate: %{public}d, micRefFormat: %{public}d,"
1157 " micRefChannels: %{public}d", u->ecType, u->ecAdapaterName, u->ecSamplingRate, u->ecFormat,
1158 u->ecChannels, u->micRef, u->micRefRate, u->micRefFormat, u->micRefChannels);
1159 }
1160
PrepareEcCapture(struct Userdata * u)1161 static void PrepareEcCapture(struct Userdata *u)
1162 {
1163 // init to avoid unexpeceted condition
1164 u->attrs.hasEcConfig = false;
1165 u->sourceAdapterEc = NULL;
1166 u->requestBytesEc = 0;
1167 u->bufferEc = NULL;
1168
1169 if (u->ecType == EC_NONE) {
1170 return;
1171 }
1172
1173 if (u->ecType == EC_SAME_ADAPTER) {
1174 // basic record attrs already prepared, only prepare ec attrs here
1175 u->attrs.hasEcConfig = true;
1176 u->attrs.formatEc = u->ecFormat;
1177 u->attrs.sampleRateEc = u->ecSamplingRate;
1178 u->attrs.channelEc = u->ecChannels;
1179
1180 u->requestBytesEc = CalculateFrameLen(u->ecSamplingRate, u->ecChannels, u->ecFormat);
1181 u->bufferEc = malloc(u->requestBytesEc);
1182 if (u->bufferEc == NULL) {
1183 AUDIO_ERR_LOG("malloc ec buffer in same adapter failed");
1184 }
1185 }
1186
1187 if (u->ecType == EC_DIFFERENT_ADAPTER) {
1188 // only ec different adapter need create aux capture
1189 struct SourceAdapterAttr *attr = (struct SourceAdapterAttr *)calloc(1, sizeof(struct SourceAdapterAttr));
1190 if (attr == NULL) {
1191 AUDIO_ERR_LOG("capture attr allocate failed");
1192 return;
1193 }
1194 InitDifferentAdapterEcAttr(u, attr);
1195 u->sourceAdapterEc = GetSourceAdapter(DEFAULT_DEVICE_CLASS, -1, HDI_ID_INFO_EC);
1196 if (u->sourceAdapterEc == NULL) {
1197 AUDIO_ERR_LOG("create ec handle failed");
1198 free(attr);
1199 return;
1200 }
1201 u->sourceAdapterEc->attr = attr;
1202 u->requestBytesEc = CalculateFrameLen(u->ecSamplingRate, u->ecChannels, u->ecFormat);
1203 u->bufferEc = malloc(u->requestBytesEc);
1204 if (u->bufferEc == NULL) {
1205 AUDIO_ERR_LOG("malloc ec buffer in different adapter failed");
1206 }
1207 }
1208 }
1209
PrepareMicRefCapture(struct Userdata * u)1210 static void PrepareMicRefCapture(struct Userdata *u)
1211 {
1212 u->sourceAdapterMicRef = NULL;
1213 u->bufferMicRef = NULL;
1214 u->requestBytesMicRef = 0;
1215
1216 if (u->micRef != REF_ON) {
1217 return;
1218 }
1219
1220 struct SourceAdapterAttr *attr = (struct SourceAdapterAttr *)calloc(1, sizeof(struct SourceAdapterAttr));
1221 if (attr == NULL) {
1222 AUDIO_ERR_LOG("capture attr allocate failed");
1223 return;
1224 }
1225
1226 InitMicRefAttr(u, attr);
1227 u->sourceAdapterMicRef = GetSourceAdapter(DEFAULT_DEVICE_CLASS, -1, HDI_ID_INFO_MIC_REF);
1228 if (u->sourceAdapterMicRef == NULL) {
1229 AUDIO_ERR_LOG("create mic ref handle failed");
1230 free(attr);
1231 return;
1232 }
1233 u->sourceAdapterMicRef->attr = attr;
1234 u->requestBytesMicRef = CalculateFrameLen(u->micRefRate, u->micRefChannels, u->micRefFormat);
1235 u->bufferMicRef = malloc(u->requestBytesMicRef);
1236 if (u->bufferMicRef == NULL) {
1237 AUDIO_ERR_LOG("malloc micref buffer failed");
1238 }
1239 }
1240
CreateCaptureDataThread(pa_module * m,struct Userdata * u)1241 int32_t CreateCaptureDataThread(pa_module *m, struct Userdata *u)
1242 {
1243 CHECK_AND_RETURN_RET_LOG(m != NULL, -1, "m is null");
1244 CHECK_AND_RETURN_RET_LOG(u != NULL, -1, "u is null");
1245
1246 pa_atomic_store(&u->captureFlag, 0);
1247 pa_atomic_store(&u->quitCaptureFlag, 0);
1248
1249 if (!(u->CaptureMq = pa_asyncmsgq_new(0))) {
1250 AUDIO_ERR_LOG("Failed to create u->CaptureMq");
1251 return -1;
1252 }
1253
1254 u->eventFd = eventfd(0, EFD_NONBLOCK);
1255 fdsan_exchange_owner_tag(u->eventFd, 0, DOMAIN_ID);
1256 u->rtpollItem = pa_rtpoll_item_new(u->rtpoll, PA_RTPOLL_NEVER, 1);
1257 struct pollfd *pollFd = pa_rtpoll_item_get_pollfd(u->rtpollItem, NULL);
1258 CHECK_AND_RETURN_RET_LOG(pollFd != NULL, -1, "get pollfd failed");
1259 pollFd->fd = u->eventFd;
1260 pollFd->events = 0;
1261 pollFd->revents = 0;
1262
1263 if (!(u->thread = pa_thread_new("OS_ProcessCapData", ThreadFuncProcessTimer, u))) {
1264 AUDIO_ERR_LOG("Failed to create hdi-source-record thread!");
1265 return -1;
1266 }
1267
1268 if (!(u->threadCap = pa_thread_new("OS_CaptureData", ThreadCaptureData, u))) {
1269 AUDIO_ERR_LOG("Failed to create capture-data thread!");
1270 return -1;
1271 }
1272 return 0;
1273 }
1274
GetSourceAdapterBySourceType(const char * deviceClass,const int32_t sourceType,const char * sourceName,const char * networkId)1275 static struct SourceAdapter *GetSourceAdapterBySourceType(const char *deviceClass, const int32_t sourceType,
1276 const char *sourceName, const char *networkId)
1277 {
1278 if (sourceType == SOURCE_TYPE_WAKEUP) {
1279 return GetSourceAdapter(deviceClass, sourceType, sourceName);
1280 }
1281 return GetSourceAdapter(deviceClass, sourceType, networkId);
1282 }
1283
PaHdiSourceNew(pa_module * m,pa_modargs * ma,const char * driver)1284 pa_source *PaHdiSourceNew(pa_module *m, pa_modargs *ma, const char *driver)
1285 {
1286 CHECK_AND_RETURN_RET_LOG(m != NULL && ma != NULL, NULL, "m or ma is null");
1287
1288 pa_sample_spec ss = m->core->default_sample_spec;
1289 pa_channel_map map = m->core->default_channel_map;
1290
1291 /* Override with modargs if provided */
1292 if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) {
1293 AUDIO_ERR_LOG("Failed to parse sample specification and channel map");
1294 return NULL;
1295 }
1296
1297 struct Userdata *u = pa_xnew0(struct Userdata, 1);
1298 if (u == NULL) {
1299 AUDIO_ERR_LOG("userdata alloc failed");
1300 goto fail;
1301 }
1302
1303 u->core = m->core;
1304 u->module = m;
1305 u->rtpoll = pa_rtpoll_new();
1306
1307 if (pa_thread_mq_init(&u->threadMq, m->core->mainloop, u->rtpoll) < 0) {
1308 AUDIO_ERR_LOG("pa_thread_mq_init() failed.");
1309 goto fail;
1310 }
1311
1312 InitUserdataAttrs(ma, u, &ss);
1313
1314 InitEcAndMicRefAttrs(ma, u);
1315
1316 const char *deviceClass = pa_modargs_get_value(ma, "device_class", DEFAULT_DEVICE_CLASS);
1317 u->sourceAdapter = GetSourceAdapterBySourceType(deviceClass, u->attrs.sourceType, pa_modargs_get_value(ma,
1318 "source_name", DEFAULT_SOURCE_NAME), pa_modargs_get_value(ma, "network_id", DEFAULT_DEVICE_NETWORKID));
1319 if (u->sourceAdapter == NULL) {
1320 AUDIO_ERR_LOG("Load adapter failed");
1321 goto fail;
1322 }
1323
1324 PrepareEcCapture(u);
1325 PrepareMicRefCapture(u);
1326
1327 if (PaSetSourceProperties(m, ma, &ss, &map, u) != 0) {
1328 AUDIO_ERR_LOG("Failed to PaSetSourceProperties");
1329 goto fail;
1330 }
1331
1332 if (PaHdiCapturerInit(u) != 0) {
1333 AUDIO_ERR_LOG("Failed to PaHdiCapturerInit");
1334 goto fail;
1335 }
1336
1337 if (CreateCaptureDataThread(m, u) != 0) {
1338 goto fail;
1339 }
1340 return u->source;
1341
1342 fail:
1343
1344 if (u->isCapturerStarted) {
1345 PaHdiCapturerExit(u);
1346 }
1347 UserdataFree(u);
1348
1349 return NULL;
1350 }
1351
PaHdiSourceFree(pa_source * s)1352 void PaHdiSourceFree(pa_source *s)
1353 {
1354 AUTO_CTRACE("PaHdiSourceFree");
1355 struct Userdata *u = NULL;
1356 if (s == NULL) {
1357 AUDIO_INFO_LOG("pa_source is null, PaHdiSourceFree done");
1358 return;
1359 }
1360 pa_source_assert_ref(s);
1361 pa_assert_se(u = s->userdata);
1362 UserdataFree(u);
1363 }