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