• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }