• 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 "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 }