• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 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 "HdiSink"
17 #endif
18 
19 #include <config.h>
20 #include <pulse/rtclock.h>
21 #include <pulse/timeval.h>
22 #include <pulse/xmalloc.h>
23 #include <pulsecore/log.h>
24 #include <pulsecore/modargs.h>
25 #include <pulsecore/module.h>
26 #include <pulsecore/rtpoll.h>
27 #include <pulsecore/sink.h>
28 #include <pulsecore/thread-mq.h>
29 #include <pulsecore/thread.h>
30 #include <pulsecore/memblock.c>
31 #include <pulsecore/mix.h>
32 #include <pulse/volume.h>
33 #include <pulsecore/protocol-native.c>
34 #include <pulsecore/memblockq.c>
35 
36 #include <stddef.h>
37 #include <stdint.h>
38 #include <stdbool.h>
39 #include <string.h>
40 #include <inttypes.h>
41 #include <sys/types.h>
42 #include <pthread.h>
43 #include <semaphore.h>
44 
45 #include "securec.h"
46 
47 #include "audio_hdi_log.h"
48 #include "audio_schedule.h"
49 #include "audio_utils_c.h"
50 #include "audio_hdiadapter_info.h"
51 #include "volume_tools_c.h"
52 #include "audio_volume_c.h"
53 #include "renderer_sink_adapter.h"
54 #include "audio_effect_chain_adapter.h"
55 #include "playback_capturer_adapter.h"
56 #include "sink_userdata.h"
57 #include "time.h"
58 
59 #define DEFAULT_SINK_NAME "hdi_output"
60 #define DEFAULT_AUDIO_DEVICE_NAME "Speaker"
61 #define DEFAULT_DEVICE_CLASS "primary"
62 #define DEFAULT_DEVICE_NETWORKID "LocalDevice"
63 #define DEFAULT_BUFFER_SIZE 8192
64 #define MAX_SINK_VOLUME_LEVEL 1.0
65 #define DEFAULT_WRITE_TIME 1000
66 #define MIX_BUFFER_LENGTH (pa_page_size())
67 #define MAX_REWIND (7000 * PA_USEC_PER_MSEC)
68 #define USEC_PER_SEC 1000000
69 #define DEFAULT_IN_CHANNEL_NUM 2
70 #define PRIMARY_CHANNEL_NUM 2
71 #define IN_CHANNEL_NUM_MAX 16
72 #define OUT_CHANNEL_NUM_MAX 2
73 #define DEFAULT_FRAMELEN 2048
74 #define SCENE_TYPE_NUM 9
75 #define HDI_MIN_MS_MAINTAIN 40
76 #define OFFLOAD_HDI_CACHE1 200 // ms, should equal with val in client
77 #define OFFLOAD_HDI_CACHE2 7000 // ms, should equal with val in client
78 #define OFFLOAD_FRAME_SIZE 40
79 #define OFFLOAD_HDI_CACHE1_PLUS (OFFLOAD_HDI_CACHE1 + OFFLOAD_FRAME_SIZE + 5)   // ms, add 1 frame and 5ms
80 #define OFFLOAD_HDI_CACHE2_PLUS (OFFLOAD_HDI_CACHE2 + OFFLOAD_FRAME_SIZE + 5)   // to make sure get full
81 #define SPRINTF_STR_LEN 100
82 #define DEFAULT_MULTICHANNEL_NUM 6
83 #define DEFAULT_NUM_CHANNEL 2
84 #define DEFAULT_MULTICHANNEL_CHANNELLAYOUT 1551
85 #define DEFAULT_CHANNELLAYOUT 3
86 #define OFFLOAD_SET_BUFFER_SIZE_NUM 5
87 #define SPATIALIZATION_FADING_FRAMECOUNT 5
88 #define POSSIBLY_UNUSED __attribute__((unused))
89 #define MIN_SLEEP_FOR_USEC 2000
90 #define DEFAULT_BLOCK_USEC 20000
91 #define FADE_IN_BEGIN 0.0
92 #define FADE_IN_END 1.0
93 #define FADE_OUT_BEGIN 1.0
94 #define FADE_OUT_END 0.0
95 #define PRINT_INTERVAL_FRAME_COUNT 100
96 
97 const int64_t LOG_LOOP_THRESHOLD = 50 * 60 * 9; // about 3 min
98 const uint64_t DEFAULT_GETLATENCY_LOG_THRESHOLD_MS = 100;
99 
100 const char *DEVICE_CLASS_PRIMARY = "primary";
101 const char *DEVICE_CLASS_A2DP = "a2dp";
102 const char *DEVICE_CLASS_REMOTE = "remote";
103 const char *DEVICE_CLASS_OFFLOAD = "offload";
104 const char *DEVICE_CLASS_MULTICHANNEL = "multichannel";
105 const char *SINK_NAME_INNER_CAPTURER = "InnerCapturerSink";
106 const char *SINK_NAME_REMOTE_CAST_INNER_CAPTURER = "RemoteCastInnerCapturer";
107 const char *DUP_STEAM_NAME = "DupStream"; // should be same with DUP_STEAM in audio_info.h
108 const char *BT_SINK_NAME = "Bt_Speaker";
109 const char *MCH_SINK_NAME = "MCH_Speaker";
110 const char *OFFLOAD_SINK_NAME = "Offload_Speaker";
111 const char *DP_SINK_NAME = "DP_speaker";
112 
113 const int32_t WAIT_CLOSE_PA_OR_EFFECT_TIME = 4; // secs
114 const int32_t MONITOR_CLOSE_PA_TIME_SEC = 5 * 60; // 5min
115 bool g_speakerPaAllStreamVolumeZero = false;
116 bool g_onlyPrimarySpeakerPaLoading = false;
117 bool g_paHaveDisabled = false;
118 time_t g_speakerPaAllStreamStartVolZeroTime = 0;
119 bool g_speakerPaHaveClosed = false;
120 time_t g_speakerPaClosedTime = 0;
121 bool g_effectAllStreamVolumeZeroMap[SCENE_TYPE_NUM] = {false};
122 bool g_effectHaveDisabledMap[SCENE_TYPE_NUM] = {false};
123 time_t g_effectStartVolZeroTimeMap[SCENE_TYPE_NUM] = {0};
124 char *const SCENE_TYPE_SET[SCENE_TYPE_NUM] = {"SCENE_DEFAULT", "SCENE_MUSIC", "SCENE_GAME", "SCENE_MOVIE",
125     "SCENE_SPEECH", "SCENE_RING", "SCENE_VOIP", "SCENE_OTHERS", "EFFECT_NONE"};
126 const int32_t COMMON_SCENE_TYPE_INDEX = 0;
127 
128 enum HdiInputType { HDI_INPUT_TYPE_PRIMARY, HDI_INPUT_TYPE_OFFLOAD, HDI_INPUT_TYPE_MULTICHANNEL };
129 
130 enum {
131     HDI_INIT,
132     HDI_DEINIT,
133     HDI_START,
134     HDI_STOP,
135     HDI_RENDER,
136     QUIT
137 };
138 
139 enum AudioOffloadType {
140     /**
141      * Indicates audio offload state default.
142      */
143     OFFLOAD_DEFAULT = -1,
144     /**
145      * Indicates audio offload state : screen is active & app is foreground.
146      */
147     OFFLOAD_ACTIVE_FOREGROUND = 0,
148     /**
149      * Indicates audio offload state : screen is active & app is background.
150      */
151     OFFLOAD_ACTIVE_BACKGROUND = 1,
152     /**
153      * Indicates audio offload state : screen is inactive & app is background.
154      */
155     OFFLOAD_INACTIVE_BACKGROUND = 3,
156 };
157 
158 static int32_t g_effectProcessFrameCount = 0;
159 static void UserdataFree(struct Userdata *u);
160 static int32_t PrepareDevice(struct Userdata *u, const char *filePath);
161 
162 static int32_t PrepareDeviceOffload(struct Userdata *u);
163 static char *GetStateInfo(pa_sink_state_t state);
164 static char *GetInputStateInfo(pa_sink_input_state_t state);
165 static void PaInputStateChangeCb(pa_sink_input *i, pa_sink_input_state_t state);
166 static void OffloadLock(struct Userdata *u);
167 static void OffloadUnlock(struct Userdata *u);
168 static int32_t UpdatePresentationPosition(struct Userdata *u);
169 static bool InputIsPrimary(pa_sink_input *i);
170 static bool InputIsOffload(pa_sink_input *i);
171 static void GetSinkInputName(pa_sink_input *i, char *str, int len);
172 static const char *safeProplistGets(const pa_proplist *p, const char *key, const char *defstr);
173 static void StartOffloadHdi(struct Userdata *u, pa_sink_input *i);
174 static void StartPrimaryHdiIfRunning(struct Userdata *u);
175 static void StartMultiChannelHdiIfRunning(struct Userdata *u);
176 static void CheckInputChangeToOffload(struct Userdata *u, pa_sink_input *i);
177 static void ResetVolumeBySinkInputState(pa_sink_input *i, pa_sink_input_state_t state);
178 static void *AllocateBuffer(size_t size);
179 static bool AllocateEffectBuffer(struct Userdata *u);
180 static void FreeEffectBuffer(struct Userdata *u);
181 static void ResetBufferAttr(struct Userdata *u);
182 
183 // BEGIN Utility functions
184 #define FLOAT_EPS 1e-9f
185 #define MEMBLOCKQ_MAXLENGTH (16*1024*16)
186 #define OFFSET_BIT_24 3
187 #define BIT_DEPTH_TWO 2
188 #define BIT_8 8
189 #define BIT_16 16
190 #define BIT_24 24
191 #define BIT_32 32
Read24Bit(const uint8_t * p)192 static uint32_t Read24Bit(const uint8_t *p)
193 {
194     return ((uint32_t) p[BIT_DEPTH_TWO] << BIT_16) | ((uint32_t) p[1] << BIT_8) | ((uint32_t) p[0]);
195 }
196 
Write24Bit(uint8_t * p,uint32_t u)197 static void Write24Bit(uint8_t *p, uint32_t u)
198 {
199     p[BIT_DEPTH_TWO] = (uint8_t) (u >> BIT_16);
200     p[1] = (uint8_t) (u >> BIT_8);
201     p[0] = (uint8_t) u;
202 }
203 
ConvertFrom16BitToFloat(unsigned n,const int16_t * a,float * b)204 static void ConvertFrom16BitToFloat(unsigned n, const int16_t *a, float *b)
205 {
206     for (; n > 0; n--) {
207         *(b++) = *(a++) * (1.0f / (1 << (BIT_16 - 1)));
208     }
209 }
210 
ConvertFrom24BitToFloat(unsigned n,const uint8_t * a,float * b)211 static void ConvertFrom24BitToFloat(unsigned n, const uint8_t *a, float *b)
212 {
213     for (; n > 0; n--) {
214         int32_t s = Read24Bit(a) << BIT_8;
215         *b = s * (1.0f / (1U << (BIT_32 - 1)));
216         a += OFFSET_BIT_24;
217         b++;
218     }
219 }
220 
ConvertFrom32BitToFloat(unsigned n,const int32_t * a,float * b)221 static void ConvertFrom32BitToFloat(unsigned n, const int32_t *a, float *b)
222 {
223     for (; n > 0; n--) {
224         *(b++) = *(a++) * (1.0f / (1U << (BIT_32 - 1)));
225     }
226 }
227 
CapMax(float v)228 static float CapMax(float v)
229 {
230     float value = v;
231     if (v > 1.0f) {
232         value = 1.0f - FLOAT_EPS;
233     } else if (v < -1.0f) {
234         value = -1.0f + FLOAT_EPS;
235     }
236     return value;
237 }
238 
ConvertFromFloatTo16Bit(unsigned n,const float * a,int16_t * b)239 static void ConvertFromFloatTo16Bit(unsigned n, const float *a, int16_t *b)
240 {
241     for (; n > 0; n--) {
242         float tmp = *a++;
243         float v = CapMax(tmp) * (1 << (BIT_16 - 1));
244         *(b++) = (int16_t) v;
245     }
246 }
247 
ConvertFromFloatTo24Bit(unsigned n,const float * a,uint8_t * b)248 static void ConvertFromFloatTo24Bit(unsigned n, const float *a, uint8_t *b)
249 {
250     for (; n > 0; n--) {
251         float tmp = *a++;
252         float v = CapMax(tmp) * (1U << (BIT_32 - 1));
253         Write24Bit(b, ((int32_t) v) >> BIT_8);
254         b += OFFSET_BIT_24;
255     }
256 }
257 
ConvertFromFloatTo32Bit(unsigned n,const float * a,int32_t * b)258 static void ConvertFromFloatTo32Bit(unsigned n, const float *a, int32_t *b)
259 {
260     for (; n > 0; n--) {
261         float tmp = *a++;
262         float v = CapMax(tmp) * (1U << (BIT_32 - 1));
263         *(b++) = (int32_t) v;
264     }
265 }
266 
ConvertToFloat(pa_sample_format_t format,unsigned n,void * src,float * dst)267 static void ConvertToFloat(pa_sample_format_t format, unsigned n, void *src, float *dst)
268 {
269     pa_assert(src);
270     pa_assert(dst);
271     int32_t ret;
272     switch (format) {
273         case PA_SAMPLE_S16LE:
274             ConvertFrom16BitToFloat(n, src, dst);
275             break;
276         case PA_SAMPLE_S24LE:
277             ConvertFrom24BitToFloat(n, src, dst);
278             break;
279         case PA_SAMPLE_S32LE:
280             ConvertFrom32BitToFloat(n, src, dst);
281             break;
282         default:
283             ret = memcpy_s(dst, n, src, n);
284             if (ret != 0) {
285                 float *srcFloat = (float *)src;
286                 for (uint32_t i = 0; i < n; i++) {
287                     dst[i] = srcFloat[i];
288                 }
289             }
290             break;
291     }
292 }
293 
ConvertFromFloat(pa_sample_format_t format,unsigned n,float * src,void * dst)294 static void ConvertFromFloat(pa_sample_format_t format, unsigned n, float *src, void *dst)
295 {
296     pa_assert(src);
297     pa_assert(dst);
298     int32_t ret;
299     switch (format) {
300         case PA_SAMPLE_S16LE:
301             ConvertFromFloatTo16Bit(n, src, dst);
302             break;
303         case PA_SAMPLE_S24LE:
304             ConvertFromFloatTo24Bit(n, src, dst);
305             break;
306         case PA_SAMPLE_S32LE:
307             ConvertFromFloatTo32Bit(n, src, dst);
308             break;
309         default:
310             ret = memcpy_s(dst, n, src, n);
311             if (ret != 0) {
312                 float *dstFloat = (float *)dst;
313                 for (uint32_t i = 0; i < n; i++) {
314                     dstFloat[i] = src[i];
315                 }
316             }
317             break;
318     }
319 }
320 
updateResampler(pa_sink_input * sinkIn,const char * sceneType,bool mchFlag)321 static void updateResampler(pa_sink_input *sinkIn, const char *sceneType, bool mchFlag)
322 {
323     uint32_t processChannels = DEFAULT_NUM_CHANNEL;
324     uint64_t processChannelLayout = DEFAULT_CHANNELLAYOUT;
325     if (mchFlag) {
326         struct Userdata *u = sinkIn->sink->userdata;
327         processChannels = u->multiChannel.sinkChannel;
328         processChannelLayout = u->multiChannel.sinkChannelLayout;
329     } else {
330         EffectChainManagerReturnEffectChannelInfo(sceneType, &processChannels, &processChannelLayout);
331     }
332 
333     pa_resampler *r;
334     pa_sample_spec ss = sinkIn->thread_info.resampler->o_ss;
335     pa_channel_map processCm;
336     ConvertChLayoutToPaChMap(processChannelLayout, &processCm);
337     processCm.channels = processChannels;
338     if (processChannels == sinkIn->thread_info.resampler->i_ss.channels) {
339         ss.channels = sinkIn->thread_info.resampler->i_ss.channels;
340         pa_channel_map cm = sinkIn->thread_info.resampler->i_cm;
341         if (pa_channel_map_equal(&sinkIn->thread_info.resampler->i_cm, &processCm)) {
342             return;
343         }
344         r = pa_resampler_new(sinkIn->thread_info.resampler->mempool,
345                              &sinkIn->thread_info.resampler->i_ss,
346                              &sinkIn->thread_info.resampler->i_cm,
347                              &ss, &cm,
348                              sinkIn->core->lfe_crossover_freq,
349                              sinkIn->thread_info.resampler->method,
350                              sinkIn->thread_info.resampler->flags);
351     } else {
352         ss.channels = processChannels;
353         if (ss.channels == sinkIn->thread_info.resampler->o_ss.channels) {
354             return;
355         }
356         r = pa_resampler_new(sinkIn->thread_info.resampler->mempool,
357                              &sinkIn->thread_info.resampler->i_ss,
358                              &sinkIn->thread_info.resampler->i_cm,
359                              &ss, &processCm,
360                              sinkIn->core->lfe_crossover_freq,
361                              sinkIn->thread_info.resampler->method,
362                              sinkIn->thread_info.resampler->flags);
363     }
364     pa_resampler_free(sinkIn->thread_info.resampler);
365     sinkIn->thread_info.resampler = r;
366     return;
367 }
368 
RenderWrite(struct RendererSinkAdapter * sinkAdapter,pa_memchunk * pchunk)369 static ssize_t RenderWrite(struct RendererSinkAdapter *sinkAdapter, pa_memchunk *pchunk)
370 {
371     size_t index;
372     size_t length;
373     ssize_t count = 0;
374     void *p = NULL;
375 
376     pa_assert(pchunk);
377 
378     index = pchunk->index;
379     length = pchunk->length;
380     p = pa_memblock_acquire(pchunk->memblock);
381     pa_assert(p);
382 
383     while (true) {
384         uint64_t writeLen = 0;
385 
386         int32_t ret = sinkAdapter->RendererRenderFrame(sinkAdapter, ((char*)p + index),
387             (uint64_t)length, &writeLen);
388         if (writeLen > length) {
389             AUDIO_ERR_LOG("Error writeLen > actual bytes. Length: %zu, Written: %" PRIu64 " bytes, %d ret",
390                          length, writeLen, ret);
391             count = -1 - count;
392             break;
393         }
394         if (writeLen == 0) {
395             AUDIO_ERR_LOG("Failed to render Length: %{public}zu, Written: %{public}" PRIu64 " bytes, %{public}d ret",
396                 length, writeLen, ret);
397             count = -1 - count;
398             break;
399         } else {
400             count += (ssize_t)writeLen;
401             index += writeLen;
402             length -= writeLen;
403             if (length == 0) {
404                 break;
405             }
406         }
407     }
408     pa_memblock_release(pchunk->memblock);
409     pa_memblock_unref(pchunk->memblock);
410 
411     return count;
412 }
413 
GetInputPolicyState(pa_sink_input * i)414 static enum AudioOffloadType GetInputPolicyState(pa_sink_input *i)
415 {
416     return atoi(safeProplistGets(i->proplist, "stream.offload.statePolicy", "0"));
417 }
418 
OffloadSetHdiVolume(pa_sink_input * i)419 static void OffloadSetHdiVolume(pa_sink_input *i)
420 {
421     if (!InputIsOffload(i)) {
422         return;
423     }
424 
425     struct Userdata *u = i->sink->userdata;
426     const char *streamType = safeProplistGets(i->proplist, "stream.type", "NULL");
427     const char *sessionIDStr = safeProplistGets(i->proplist, "stream.sessionID", "NULL");
428     const char *deviceClass = GetDeviceClass(u->offload.sinkAdapter->deviceClass);
429     uint32_t sessionID = sessionIDStr != NULL ? (uint32_t)atoi(sessionIDStr) : 0;
430     float volumeEnd = GetCurVolume(sessionID, streamType, deviceClass);
431     float volumeBeg = GetPreVolume(sessionID);
432     float fadeBeg = 1.0f;
433     float fadeEnd = 1.0f;
434     if (!pa_safe_streq(streamType, "ultrasonic")) {
435         GetStreamVolumeFade(sessionID, &fadeBeg, &fadeEnd);
436     }
437     if (volumeBeg != volumeEnd || fadeBeg != fadeEnd) {
438         AUDIO_INFO_LOG("sessionID:%{public}s, volumeBeg:%{public}f, volumeEnd:%{public}f"
439             ", fadeBeg:%{public}f, fadeEnd:%{public}f",
440             sessionIDStr, volumeBeg, volumeEnd, fadeBeg, fadeEnd);
441         if (volumeBeg != volumeEnd) {
442             SetPreVolume(sessionID, volumeEnd);
443             MonitorVolume(sessionID, true);
444         }
445         if (fadeBeg != fadeEnd) {
446             SetStreamVolumeFade(sessionID, fadeEnd, fadeEnd);
447         }
448     }
449     u->offload.sinkAdapter->RendererSinkSetVolume(u->offload.sinkAdapter, volumeEnd, volumeEnd);
450 }
451 
OffloadSetHdiBufferSize(pa_sink_input * i)452 static void OffloadSetHdiBufferSize(pa_sink_input *i)
453 {
454     if (!InputIsOffload(i)) {
455         return;
456     }
457 
458     struct Userdata *u = i->sink->userdata;
459     const uint32_t bufSize = (GetInputPolicyState(i) == OFFLOAD_INACTIVE_BACKGROUND ?
460                               OFFLOAD_HDI_CACHE2 : OFFLOAD_HDI_CACHE1);
461     u->offload.sinkAdapter->RendererSinkSetBufferSize(u->offload.sinkAdapter, bufSize);
462 }
463 
RenderWriteOffload(struct Userdata * u,pa_sink_input * i,pa_memchunk * pchunk)464 static int32_t RenderWriteOffload(struct Userdata *u, pa_sink_input *i, pa_memchunk *pchunk)
465 {
466     size_t index;
467     size_t length;
468     void *p = NULL;
469 
470     pa_assert(pchunk);
471 
472     index = pchunk->index;
473     length = pchunk->length;
474     p = pa_memblock_acquire(pchunk->memblock);
475     pa_assert(p);
476 
477     uint64_t writeLen = 0;
478     uint64_t now = pa_rtclock_now();
479     if (!u->offload.isHDISinkStarted) {
480         AUDIO_DEBUG_LOG("StartOffloadHdi before write, because maybe sink switch");
481         StartOffloadHdi(u, i);
482     }
483     int32_t ret = u->offload.sinkAdapter->RendererRenderFrame(u->offload.sinkAdapter, ((char*)p + index),
484         (uint64_t)length, &writeLen);
485     pa_memblock_release(pchunk->memblock);
486     if (writeLen != length && writeLen != 0) {
487         AUDIO_ERR_LOG("Error writeLen != actual bytes. Length: %zu, Written: %" PRIu64 " bytes, %d ret",
488             length, writeLen, ret);
489         return -1;
490     }
491     if (ret == 0 && u->offload.firstWriteHdi && writeLen == length) {
492         u->offload.firstWriteHdi = false;
493         u->offload.hdiPosTs = now;
494         u->offload.hdiPos = 0;
495         // if the hdi is flushing, it will block the volume setting.
496         // so the render frame judge it.
497         OffloadSetHdiVolume(i);
498     }
499     if (ret == 0 && u->offload.setHdiBufferSizeNum > 0 && writeLen == length) {
500         u->offload.setHdiBufferSizeNum--;
501         OffloadSetHdiBufferSize(i);
502     }
503     if (ret == 0 && writeLen == 0 && !u->offload.firstWriteHdi) { // is full
504         AUDIO_DEBUG_LOG("RenderWriteOffload, hdi is full, break");
505         return 1; // 1 indicates full
506     } else if (writeLen == 0) {
507         AUDIO_ERR_LOG("Failed to render Length: %{public}zu, Written: %{public}" PRIu64 " bytes, %{public}d ret",
508             length, writeLen, ret);
509         return -1;
510     }
511     return 0;
512 }
513 
OffloadCallback(const enum RenderCallbackType type,int8_t * userdata)514 static void OffloadCallback(const enum RenderCallbackType type, int8_t *userdata)
515 {
516     struct Userdata *u = (struct Userdata *)userdata;
517     switch (type) {
518         case CB_NONBLOCK_WRITE_COMPLETED: { //need more data
519             const int hdistate = pa_atomic_load(&u->offload.hdistate);
520             if (hdistate == 1) {
521                 pa_atomic_store(&u->offload.hdistate, 0);
522                 OffloadLock(u);
523                 UpdatePresentationPosition(u);
524             }
525             if (u->thread_mq.inq) {
526                 pa_asyncmsgq_post(u->thread_mq.inq, NULL, 0, NULL, 0, NULL, NULL);
527             }
528             break;
529         }
530         case CB_DRAIN_COMPLETED:
531         case CB_FLUSH_COMPLETED:
532         case CB_RENDER_FULL:
533         case CB_ERROR_OCCUR:
534             break;
535         default:
536             break;
537     }
538 }
539 
RegOffloadCallback(struct Userdata * u)540 static void RegOffloadCallback(struct Userdata *u)
541 {
542     u->offload.sinkAdapter->RendererRegCallback(u->offload.sinkAdapter, (int8_t *)OffloadCallback, (int8_t *)u);
543 }
544 
TestModeRenderWrite(struct Userdata * u,pa_memchunk * pchunk)545 static ssize_t TestModeRenderWrite(struct Userdata *u, pa_memchunk *pchunk)
546 {
547     size_t index;
548     size_t length;
549     ssize_t count = 0;
550     void *p = NULL;
551 
552     pa_assert(pchunk);
553 
554     index = pchunk->index;
555     length = pchunk->length;
556     p = pa_memblock_acquire(pchunk->memblock);
557     pa_assert(p);
558 
559     if (*((int32_t*)p) > 0) {
560         AUDIO_DEBUG_LOG("RenderWrite Write: %{public}d", ++u->writeCount);
561     }
562     AUDIO_DEBUG_LOG("RenderWrite Write renderCount: %{public}d", ++u->renderCount);
563 
564     while (true) {
565         uint64_t writeLen = 0;
566 
567         int32_t ret = u->primary.sinkAdapter->RendererRenderFrame(u->primary.sinkAdapter, ((char *)p + index),
568             (uint64_t)length, &writeLen);
569         if (writeLen > length) {
570             AUDIO_ERR_LOG("Error writeLen > actual bytes. Length: %zu, Written: %" PRIu64 " bytes, %d ret",
571                          length, writeLen, ret);
572             count = -1 - count;
573             break;
574         }
575         if (writeLen == 0) {
576             AUDIO_ERR_LOG("Failed to render Length: %zu, Written: %" PRIu64 " bytes, %d ret",
577                          length, writeLen, ret);
578             count = -1 - count;
579             break;
580         } else {
581             count += (ssize_t)writeLen;
582             index += writeLen;
583             length -= writeLen;
584             if (length == 0) {
585                 break;
586             }
587         }
588     }
589     pa_memblock_release(pchunk->memblock);
590     pa_memblock_unref(pchunk->memblock);
591 
592     return count;
593 }
594 
IsInnerCapturer(pa_sink_input * sinkIn)595 static bool IsInnerCapturer(pa_sink_input *sinkIn)
596 {
597     pa_sink_input_assert_ref(sinkIn);
598 
599     if (!GetInnerCapturerState()) {
600         return false;
601     }
602 
603     const char *usageStr = pa_proplist_gets(sinkIn->proplist, "stream.usage");
604     const char *privacyTypeStr = pa_proplist_gets(sinkIn->proplist, "stream.privacyType");
605     int32_t usage = -1;
606     int32_t privacyType = -1;
607     bool usageSupport = false;
608     bool privacySupport = true;
609 
610     if (privacyTypeStr != NULL) {
611         pa_atoi(privacyTypeStr, &privacyType);
612         privacySupport = IsPrivacySupportInnerCapturer(privacyType);
613     }
614 
615     if (usageStr != NULL) {
616         pa_atoi(usageStr, &usage);
617         usageSupport = IsStreamSupportInnerCapturer(usage);
618     }
619     return privacySupport && usageSupport;
620 }
621 
safeProplistGets(const pa_proplist * p,const char * key,const char * defstr)622 static const char *safeProplistGets(const pa_proplist *p, const char *key, const char *defstr)
623 {
624     const char *res = pa_proplist_gets(p, key);
625     if (res == NULL) {
626         return defstr;
627     }
628     return res;
629 }
630 
631 //modify from pa inputs_drop
632 static void InputsDropFromInputs(pa_mix_info *infoInputs, unsigned nInputs, pa_mix_info *info, unsigned n,
633     pa_memchunk *result);
634 
635 static unsigned GetInputsInfo(enum HdiInputType type, bool isRun, pa_sink *s, pa_mix_info *info, unsigned maxinfo);
636 
SinkRenderPrimaryClusterCap(pa_sink * si,size_t * length,pa_mix_info * infoIn,unsigned maxInfo)637 static unsigned SinkRenderPrimaryClusterCap(pa_sink *si, size_t *length, pa_mix_info *infoIn, unsigned maxInfo)
638 {
639     AUTO_CTRACE("hdi_sink::SinkRenderPrimaryClusterCap:len:%zu", *length);
640     pa_sink_input *sinkIn;
641 
642     pa_sink_assert_ref(si);
643     pa_sink_assert_io_context(si);
644     pa_assert(infoIn);
645 
646     unsigned n = 0;
647     void *state = NULL;
648     size_t mixlength = *length;
649     while ((sinkIn = pa_hashmap_iterate(si->thread_info.inputs, &state, NULL)) && maxInfo > 0) {
650         if (IsInnerCapturer(sinkIn) && InputIsPrimary(sinkIn)) {
651             pa_sink_input_assert_ref(sinkIn);
652 
653             // max_rewind is 0 by default, need change to at least u->buffer_size for InnerCapSinkInputsRewind.
654             if (pa_memblockq_get_maxrewind(sinkIn->thread_info.render_memblockq) == 0) {
655                 AUTO_CTRACE("hdi_sink::pa_sink_input_update_max_rewind:%u len:%zu", sinkIn->index, *length);
656                 pa_sink_input_update_max_rewind(sinkIn, *length);
657             }
658             AUTO_CTRACE("hdi_sink::ClusterCap::pa_sink_input_peek:%u len:%zu", sinkIn->index, *length);
659             pa_sink_input_peek(sinkIn, *length, &infoIn->chunk, &infoIn->volume);
660 
661             if (mixlength == 0 || infoIn->chunk.length < mixlength)
662                 mixlength = infoIn->chunk.length;
663 
664             if (pa_memblock_is_silence(infoIn->chunk.memblock)) {
665                 AUTO_CTRACE("hdi_sink::SinkRenderPrimaryClusterCap::is_silence");
666                 pa_memblock_unref(infoIn->chunk.memblock);
667                 continue;
668             }
669 
670             infoIn->userdata = pa_sink_input_ref(sinkIn);
671             pa_assert(infoIn->chunk.memblock);
672             pa_assert(infoIn->chunk.length > 0);
673 
674             infoIn++;
675             n++;
676             maxInfo--;
677         }
678     }
679 
680     if (mixlength > 0) {
681         *length = mixlength;
682     }
683 
684     return n;
685 }
686 
SinkRenderPrimaryMix(pa_sink * si,size_t length,pa_mix_info * infoIn,unsigned n,pa_memchunk * chunkIn)687 static void SinkRenderPrimaryMix(pa_sink *si, size_t length, pa_mix_info *infoIn, unsigned n, pa_memchunk *chunkIn)
688 {
689     if (n == 0) {
690         if (chunkIn->length > length)
691             chunkIn->length = length;
692 
693         pa_silence_memchunk(chunkIn, &si->sample_spec);
694     } else if (n == 1) {
695         pa_cvolume volume;
696 
697         if (chunkIn->length > length)
698             chunkIn->length = length;
699 
700         pa_sw_cvolume_multiply(&volume, &si->thread_info.soft_volume, &infoIn[0].volume);
701 
702         if (si->thread_info.soft_muted || pa_cvolume_is_muted(&volume)) {
703             pa_silence_memchunk(chunkIn, &si->sample_spec);
704         } else {
705             pa_memchunk tmpChunk;
706 
707             tmpChunk = infoIn[0].chunk;
708             pa_memblock_ref(tmpChunk.memblock);
709 
710             if (tmpChunk.length > length)
711                 tmpChunk.length = length;
712 
713             if (!pa_cvolume_is_norm(&volume)) {
714                 pa_memchunk_make_writable(&tmpChunk, 0);
715                 pa_volume_memchunk(&tmpChunk, &si->sample_spec, &volume);
716             }
717 
718             pa_memchunk_memcpy(chunkIn, &tmpChunk);
719             pa_memblock_unref(tmpChunk.memblock);
720         }
721     } else {
722         void *ptr;
723 
724         ptr = pa_memblock_acquire(chunkIn->memblock);
725 
726         chunkIn->length = pa_mix(infoIn, n,
727                                  (uint8_t*) ptr + chunkIn->index, length,
728                                  &si->sample_spec,
729                                  &si->thread_info.soft_volume,
730                                  si->thread_info.soft_muted);
731 
732         pa_memblock_release(chunkIn->memblock);
733     }
734 }
735 
SinkRenderPrimaryMixCap(pa_sink * si,size_t length,pa_mix_info * infoIn,unsigned n,pa_memchunk * chunkIn)736 static void SinkRenderPrimaryMixCap(pa_sink *si, size_t length, pa_mix_info *infoIn, unsigned n, pa_memchunk *chunkIn)
737 {
738     AUTO_CTRACE("hdi_sink::SinkRenderPrimaryMixCap:%u:len:%zu", n, chunkIn->length);
739     if (n == 0) {
740         if (chunkIn->length > length) {
741             chunkIn->length = length;
742         }
743 
744         pa_silence_memchunk(chunkIn, &si->sample_spec);
745     } else if (n == 1) {
746         pa_memchunk tmpChunk;
747         // If chunkIn is not full filled, we need re-call SinkRenderPrimaryPeekCap.
748         if (chunkIn->length > length) {
749             chunkIn->length = length;
750         }
751 
752         tmpChunk = infoIn[0].chunk;
753         pa_memblock_ref(tmpChunk.memblock);
754 
755         if (tmpChunk.length > length) {
756             tmpChunk.length = length;
757         }
758 
759         pa_memchunk_memcpy(chunkIn, &tmpChunk);
760         pa_memblock_unref(tmpChunk.memblock);
761     } else {
762         void *ptr;
763 
764         ptr = pa_memblock_acquire(chunkIn->memblock);
765 
766         for (unsigned index = 0; index < n; index++) {
767             for (unsigned channel = 0; channel < si->sample_spec.channels; channel++) {
768                 infoIn[index].volume.values[channel] = PA_VOLUME_NORM;
769             }
770         }
771 
772         chunkIn->length = pa_mix(infoIn, n, (uint8_t*) ptr + chunkIn->index, length, &si->sample_spec, NULL, false);
773 
774         pa_memblock_release(chunkIn->memblock);
775     }
776 }
777 
SinkRenderPrimaryInputsDropCap(pa_sink * si,pa_mix_info * infoIn,unsigned n,pa_memchunk * chunkIn)778 static void SinkRenderPrimaryInputsDropCap(pa_sink *si, pa_mix_info *infoIn, unsigned n, pa_memchunk *chunkIn)
779 {
780     AUTO_CTRACE("hdi_sink::SinkRenderPrimaryInputsDropCap:%u:len:%zu", n, chunkIn->length);
781     pa_sink_assert_ref(si);
782     pa_sink_assert_io_context(si);
783     pa_assert(chunkIn);
784     pa_assert(chunkIn->memblock);
785     pa_assert(chunkIn->length > 0);
786 
787     /* We optimize for the case where the order of the inputs has not changed */
788 
789     pa_mix_info *infoCur = NULL;
790     pa_sink_input *sceneSinkInput = NULL;
791     bool isCaptureSilently = IsCaptureSilently();
792     for (uint32_t k = 0; k < n; k++) {
793         sceneSinkInput = infoIn[k].userdata;
794         pa_sink_input_assert_ref(sceneSinkInput);
795         AUTO_CTRACE("hdi_sink::InnerCap:pa_sink_input_drop:%u:len:%zu", sceneSinkInput->index, chunkIn->length);
796         pa_sink_input_drop(sceneSinkInput, chunkIn->length);
797 
798         infoCur = infoIn + k;
799         if (infoCur) {
800             if (infoCur->chunk.memblock) {
801                 pa_memblock_unref(infoCur->chunk.memblock);
802                 pa_memchunk_reset(&infoCur->chunk);
803             }
804 
805             pa_sink_input_unref(infoCur->userdata);
806 
807             if (isCaptureSilently) {
808                 infoCur->userdata = NULL;
809             }
810         }
811     }
812 }
813 
SinkRenderPrimaryPeekCap(pa_sink * si,pa_memchunk * chunkIn)814 static int32_t SinkRenderPrimaryPeekCap(pa_sink *si, pa_memchunk *chunkIn)
815 {
816     AUTO_CTRACE("hdi_sink::SinkRenderPrimaryPeekCap:len:%zu", chunkIn->length);
817     pa_mix_info infoIn[MAX_MIX_CHANNELS];
818     unsigned n;
819     size_t length;
820     size_t blockSizeMax;
821 
822     pa_sink_assert_ref(si);
823     pa_sink_assert_io_context(si);
824     pa_assert(PA_SINK_IS_LINKED(si->thread_info.state));
825     pa_assert(chunkIn);
826     pa_assert(chunkIn->memblock);
827     pa_assert(chunkIn->length > 0);
828     pa_assert(pa_frame_aligned(chunkIn->length, &si->sample_spec));
829 
830     pa_assert(!si->thread_info.rewind_requested);
831     pa_assert(si->thread_info.rewind_nbytes == 0);
832 
833     if (si->thread_info.state == PA_SINK_SUSPENDED) {
834         pa_silence_memchunk(chunkIn, &si->sample_spec);
835         return 0;
836     }
837 
838     pa_sink_ref(si);
839 
840     length = chunkIn->length;
841     blockSizeMax = pa_mempool_block_size_max(si->core->mempool);
842     if (length > blockSizeMax)
843         length = pa_frame_align(blockSizeMax, &si->sample_spec);
844 
845     pa_assert(length > 0);
846 
847     n = SinkRenderPrimaryClusterCap(si, &length, infoIn, MAX_MIX_CHANNELS);
848     SinkRenderPrimaryMixCap(si, length, infoIn, n, chunkIn);
849 
850     SinkRenderPrimaryInputsDropCap(si, infoIn, n, chunkIn);
851     pa_sink_unref(si);
852 
853     return n;
854 }
855 
SinkRenderPrimaryGetDataCap(pa_sink * si,pa_memchunk * chunkIn)856 static int32_t SinkRenderPrimaryGetDataCap(pa_sink *si, pa_memchunk *chunkIn)
857 {
858     AUTO_CTRACE("hdi_sink::SinkRenderPrimaryGetDataCap:len:%zu", chunkIn->length);
859     pa_memchunk chunk;
860     size_t l;
861     size_t d;
862     pa_sink_assert_ref(si);
863     pa_sink_assert_io_context(si);
864     pa_assert(PA_SINK_IS_LINKED(si->thread_info.state));
865     pa_assert(chunkIn);
866     pa_assert(chunkIn->memblock);
867     pa_assert(chunkIn->length > 0);
868     pa_assert(pa_frame_aligned(chunkIn->length, &si->sample_spec));
869 
870     pa_assert(!si->thread_info.rewind_requested);
871     pa_assert(si->thread_info.rewind_nbytes == 0);
872 
873     if (si->thread_info.state == PA_SINK_SUSPENDED) {
874         pa_silence_memchunk(chunkIn, &si->sample_spec);
875         return 0;
876     }
877 
878     pa_sink_ref(si);
879 
880     l = chunkIn->length;
881     d = 0;
882 
883     int32_t nSinkInput = 0;
884     while (l > 0) {
885         chunk = *chunkIn;
886         chunk.index += d;
887         chunk.length -= d;
888 
889         nSinkInput = SinkRenderPrimaryPeekCap(si, &chunk);
890 
891         d += (size_t)chunk.length;
892         l -= (size_t)chunk.length;
893     }
894 
895     pa_sink_unref(si);
896 
897     return nSinkInput;
898 }
899 
monitorLinked(pa_sink * si,bool isRunning)900 static bool monitorLinked(pa_sink *si, bool isRunning)
901 {
902     if (isRunning) {
903         return si->monitor_source && PA_SOURCE_IS_RUNNING(si->monitor_source->thread_info.state);
904     } else {
905         return si->monitor_source && PA_SOURCE_IS_LINKED(si->monitor_source->thread_info.state);
906     }
907 }
908 
InnerCapSinkInputsRewind(pa_sink * si,size_t length)909 static void InnerCapSinkInputsRewind(pa_sink *si, size_t length)
910 {
911     AUTO_CTRACE("hdi_sink::InnerCapSinkInputsRewind:len:%zu", length);
912 
913     pa_sink_assert_ref(si);
914     pa_sink_assert_io_context(si);
915 
916     pa_sink_input *sinkIn = NULL;
917     void *state = NULL;
918     while ((sinkIn = pa_hashmap_iterate(si->thread_info.inputs, &state, NULL))) {
919         if (IsInnerCapturer(sinkIn) && InputIsPrimary(sinkIn)) {
920             pa_sink_input_assert_ref(sinkIn);
921             pa_sink_input_process_rewind(sinkIn, length); // will not work well if maxrewind = 0
922         }
923     }
924 }
925 
SinkRenderCapProcess(pa_sink * si,size_t length,pa_memchunk * capResult)926 static void SinkRenderCapProcess(pa_sink *si, size_t length, pa_memchunk *capResult)
927 {
928     AUTO_CTRACE("hdi_sink::SinkRenderCapProcess:len:%zu", length);
929     capResult->memblock = pa_memblock_new(si->core->mempool, length);
930     capResult->index = 0;
931     capResult->length = length;
932     SinkRenderPrimaryGetDataCap(si, capResult);
933     if (monitorLinked(si, false)) {
934         AUTO_CTRACE("hdi_sink::pa_source_post:len:%zu", capResult->length);
935         pa_source_post(si->monitor_source, capResult);
936     }
937 
938     //If not silent capture, we need to call rewind for Speak.
939     if (!IsCaptureSilently()) {
940         InnerCapSinkInputsRewind(si, capResult->length);
941     }
942     return;
943 }
944 
SinkRenderPrimaryInputsDrop(pa_sink * si,pa_mix_info * infoIn,unsigned n,pa_memchunk * chunkIn)945 static void SinkRenderPrimaryInputsDrop(pa_sink *si, pa_mix_info *infoIn, unsigned n, pa_memchunk *chunkIn)
946 {
947     unsigned nUnreffed = 0;
948 
949     pa_sink_assert_ref(si);
950     pa_sink_assert_io_context(si);
951     pa_assert(chunkIn);
952     pa_assert(chunkIn->memblock);
953     pa_assert(chunkIn->length > 0);
954 
955     /* We optimize for the case where the order of the inputs has not changed */
956     pa_mix_info *infoCur = NULL;
957     pa_sink_input *sceneSinkInput = NULL;
958     for (uint32_t k = 0; k < n; k++) {
959         sceneSinkInput = infoIn[k].userdata;
960         pa_sink_input_assert_ref(sceneSinkInput);
961 
962         /* Drop read data */
963         pa_sink_input_drop(sceneSinkInput, chunkIn->length);
964         infoCur = infoIn + k;
965         if (infoCur) {
966             if (infoCur->chunk.memblock) {
967                 pa_memblock_unref(infoCur->chunk.memblock);
968                 pa_memchunk_reset(&infoCur->chunk);
969             }
970 
971             pa_sink_input_unref(infoCur->userdata);
972             infoCur->userdata = NULL;
973 
974             nUnreffed += 1;
975         }
976     }
977     /* Now drop references to entries that are included in the
978      * pa_mix_info array but don't exist anymore */
979 
980     if (nUnreffed < n) {
981         for (; n > 0; infoIn++, n--) {
982             if (infoIn->userdata)
983                 pa_sink_input_unref(infoIn->userdata);
984             if (infoIn->chunk.memblock)
985                 pa_memblock_unref(infoIn->chunk.memblock);
986         }
987     }
988 }
989 
SinkRenderMultiChannelInputsDrop(pa_sink * si,pa_mix_info * infoIn,unsigned n,pa_memchunk * chunkIn)990 static void SinkRenderMultiChannelInputsDrop(pa_sink *si, pa_mix_info *infoIn, unsigned n, pa_memchunk *chunkIn)
991 {
992     AUDIO_DEBUG_LOG("mch inputs drop start");
993     unsigned nUnreffed = 0;
994 
995     pa_sink_assert_ref(si);
996     pa_sink_assert_io_context(si);
997     pa_assert(chunkIn);
998     pa_assert(chunkIn->memblock);
999     pa_assert(chunkIn->length > 0);
1000 
1001     /* We optimize for the case where the order of the inputs has not changed */
1002     pa_mix_info *infoCur = NULL;
1003     pa_sink_input *sceneSinkInput = NULL;
1004     for (uint32_t k = 0; k < n; k++) {
1005         sceneSinkInput = infoIn[k].userdata;
1006         pa_sink_input_assert_ref(sceneSinkInput);
1007 
1008         /* Drop read data */
1009         pa_sink_input_drop(sceneSinkInput, chunkIn->length);
1010         infoCur = infoIn + k;
1011         if (infoCur) {
1012             if (infoCur->chunk.memblock) {
1013                 pa_memblock_unref(infoCur->chunk.memblock);
1014                 pa_memchunk_reset(&infoCur->chunk);
1015             }
1016 
1017             pa_sink_input_unref(infoCur->userdata);
1018             infoCur->userdata = NULL;
1019 
1020             nUnreffed += 1;
1021         }
1022     }
1023     /* Now drop references to entries that are included in the
1024      * pa_mix_info array but don't exist anymore */
1025 
1026     if (nUnreffed < n) {
1027         for (; n > 0; infoIn++, n--) {
1028             if (infoIn->userdata)
1029                 pa_sink_input_unref(infoIn->userdata);
1030             if (infoIn->chunk.memblock)
1031                 pa_memblock_unref(infoIn->chunk.memblock);
1032         }
1033     }
1034 }
1035 
CheckAndPushUidToArr(pa_sink_input * sinkIn,int32_t appsUid[MAX_MIX_CHANNELS],size_t * count)1036 static void CheckAndPushUidToArr(pa_sink_input *sinkIn, int32_t appsUid[MAX_MIX_CHANNELS], size_t *count)
1037 {
1038     const char *cstringClientUid = pa_proplist_gets(sinkIn->proplist, "stream.client.uid");
1039     if (cstringClientUid && (sinkIn->thread_info.state == PA_SINK_INPUT_RUNNING)) {
1040         appsUid[(*count)] = atoi(cstringClientUid);
1041         (*count)++;
1042     }
1043 }
1044 
SafeRendererSinkUpdateAppsUid(struct RendererSinkAdapter * sinkAdapter,const int32_t appsUid[MAX_MIX_CHANNELS],const size_t count)1045 static void SafeRendererSinkUpdateAppsUid(struct RendererSinkAdapter *sinkAdapter,
1046     const int32_t appsUid[MAX_MIX_CHANNELS], const size_t count)
1047 {
1048     if (sinkAdapter) {
1049         sinkAdapter->RendererSinkUpdateAppsUid(sinkAdapter, appsUid, count);
1050     }
1051 }
1052 
silenceData(pa_mix_info * infoIn,pa_sink * si)1053 static void silenceData(pa_mix_info *infoIn, pa_sink *si)
1054 {
1055     pa_memchunk_make_writable(&infoIn->chunk, 0);
1056     void *tmpdata = pa_memblock_acquire_chunk(&infoIn->chunk);
1057     memset_s(tmpdata, infoIn->chunk.length, 0, infoIn->chunk.length);
1058     pa_memblock_release(infoIn->chunk.memblock);
1059 }
1060 
ConvertPaToHdiAdapterFormat(pa_sample_format_t format)1061 static enum HdiAdapterFormat ConvertPaToHdiAdapterFormat(pa_sample_format_t format)
1062 {
1063     enum HdiAdapterFormat adapterFormat;
1064     switch (format) {
1065         case PA_SAMPLE_U8:
1066             adapterFormat = SAMPLE_U8;
1067             break;
1068         case PA_SAMPLE_S16LE:
1069             adapterFormat = SAMPLE_S16;
1070             break;
1071         case PA_SAMPLE_S24LE:
1072             adapterFormat = SAMPLE_S24;
1073             break;
1074         case PA_SAMPLE_S32LE:
1075             adapterFormat = SAMPLE_S32;
1076             break;
1077         default:
1078             adapterFormat = INVALID_WIDTH;
1079             break;
1080     }
1081 
1082     return adapterFormat;
1083 }
1084 
DoFading(void * data,int32_t length,uint32_t format,uint32_t channel,int32_t fadeType)1085 static void DoFading(void *data, int32_t length, uint32_t format, uint32_t channel, int32_t fadeType)
1086 {
1087     AudioRawFormat rawFormat;
1088     rawFormat.format = format;
1089     rawFormat.channels = channel;
1090     AUDIO_INFO_LOG("length:%{public}d channels:%{public}d format:%{public}d fadeType:%{public}d",
1091         length, rawFormat.channels, rawFormat.format, fadeType);
1092     int32_t ret = 0;
1093     if (fadeType == 0) {
1094         ret = ProcessVol(data, length, rawFormat, FADE_IN_BEGIN, FADE_IN_END);
1095     } else {
1096         ret = ProcessVol(data, length, rawFormat, FADE_OUT_BEGIN, FADE_OUT_END);
1097     }
1098     if (ret != 0) {
1099         AUDIO_WARNING_LOG("ProcessVol failed:%{public}d", ret);
1100     }
1101 }
1102 
PreparePrimaryFading(pa_sink_input * sinkIn,pa_mix_info * infoIn,pa_sink * si)1103 static void PreparePrimaryFading(pa_sink_input *sinkIn, pa_mix_info *infoIn, pa_sink *si)
1104 {
1105     struct Userdata *u;
1106     pa_assert_se(u = si->userdata);
1107 
1108     const char *streamType = safeProplistGets(sinkIn->proplist, "stream.type", "NULL");
1109     if (pa_safe_streq(streamType, "ultrasonic")) {
1110         return;
1111     }
1112 
1113     uint32_t streamIndex = sinkIn->index;
1114     uint32_t sinkFadeoutPause = GetFadeoutState(streamIndex);
1115     if (sinkFadeoutPause == DONE_FADE && (sinkIn->thread_info.state == PA_SINK_INPUT_RUNNING)) {
1116         silenceData(infoIn, si);
1117         AUDIO_PRERELEASE_LOGI("after pause fadeout done, silenceData");
1118         return;
1119     }
1120     uint32_t format = (uint32_t)ConvertPaToHdiAdapterFormat(u->format);
1121     if (pa_atomic_load(&u->primary.fadingFlagForPrimary) == 1 &&
1122         u->primary.primarySinkInIndex == (int32_t)sinkIn->index) {
1123         if (pa_memblock_is_silence(infoIn->chunk.memblock)) {
1124             AUDIO_PRERELEASE_LOGI("pa_memblock_is_silence");
1125             return;
1126         }
1127         //do fading in
1128         pa_memchunk_make_writable(&infoIn->chunk, 0);
1129         void *data = pa_memblock_acquire_chunk(&infoIn->chunk);
1130         DoFading(data, infoIn->chunk.length, format, (uint32_t)u->ss.channels, 0);
1131         u->primary.primaryFadingInDone = 1;
1132         pa_memblock_release(infoIn->chunk.memblock);
1133     }
1134     if (sinkFadeoutPause == DO_FADE) {
1135         //do fading out
1136         pa_memchunk_make_writable(&infoIn->chunk, 0);
1137         void *data = pa_memblock_acquire_chunk(&infoIn->chunk);
1138         DoFading(data, infoIn->chunk.length, format, (uint32_t)u->ss.channels, 1);
1139         SetFadeoutState(streamIndex, DONE_FADE);
1140         pa_memblock_release(infoIn->chunk.memblock);
1141     }
1142 }
1143 
CheckPrimaryFadeinIsDone(pa_sink * si,pa_sink_input * sinkIn)1144 static void CheckPrimaryFadeinIsDone(pa_sink *si, pa_sink_input *sinkIn)
1145 {
1146     struct Userdata *u;
1147     pa_assert_se(u = si->userdata);
1148 
1149     if (u->primary.primaryFadingInDone && u->primary.primarySinkInIndex == (int32_t)sinkIn->index) {
1150         pa_atomic_store(&u->primary.fadingFlagForPrimary, 0);
1151     }
1152 }
1153 
RecordEffectChainStatus(bool existFlag,const char * sinkSceneType,const char * sinkSceneMode,bool actualSpatializationEnabled)1154 static void RecordEffectChainStatus(bool existFlag, const char *sinkSceneType, const char *sinkSceneMode,
1155     bool actualSpatializationEnabled)
1156 {
1157     if (g_effectProcessFrameCount == PRINT_INTERVAL_FRAME_COUNT) {
1158         AUDIO_DEBUG_LOG("Effect Chain Status is %{public}d, "
1159             "scene type is %{public}s, scene mode is %{public}s, spatializationEnabled is %{public}d.",
1160             existFlag, sinkSceneType, sinkSceneMode, actualSpatializationEnabled);
1161     }
1162 }
1163 
GetExistFlag(pa_sink_input * sinkIn,const char * sinkSceneType,const char * sinkSceneMode,const char * spatializationEnabled)1164 static bool GetExistFlag(pa_sink_input *sinkIn, const char *sinkSceneType, const char *sinkSceneMode,
1165     const char *spatializationEnabled)
1166 {
1167     bool existFlag =
1168             EffectChainManagerExist(sinkSceneType, sinkSceneMode, spatializationEnabled ? "1" : "0");
1169     const char *deviceString = pa_proplist_gets(sinkIn->sink->proplist, PA_PROP_DEVICE_STRING);
1170     if (pa_safe_streq(deviceString, "remote")) {
1171         existFlag = false;
1172     }
1173 
1174     return existFlag;
1175 }
1176 
ProcessAudioVolume(pa_sink_input * sinkIn,size_t length,pa_memchunk * pchunk,pa_sink * si)1177 static void ProcessAudioVolume(pa_sink_input *sinkIn, size_t length, pa_memchunk *pchunk, pa_sink *si)
1178 {
1179     AUTO_CTRACE("hdi_sink::ProcessAudioVolume: len:%zu", length);
1180     struct Userdata *u;
1181     pa_assert_se(sinkIn);
1182     pa_assert_se(pchunk);
1183     pa_assert_se(si);
1184     pa_assert_se(u = si->userdata);
1185     const char *streamType = safeProplistGets(sinkIn->proplist, "stream.type", "NULL");
1186     const char *sessionIDStr = safeProplistGets(sinkIn->proplist, "stream.sessionID", "NULL");
1187     const char *deviceClass = GetDeviceClass(u->primary.sinkAdapter->deviceClass);
1188     uint32_t sessionID = sessionIDStr != NULL ? atoi(sessionIDStr) : 0;
1189     float volumeEnd = GetCurVolume(sessionID, streamType, deviceClass);
1190     float volumeBeg = GetPreVolume(sessionID);
1191     float fadeBeg = 1.0f;
1192     float fadeEnd = 1.0f;
1193     if (!pa_safe_streq(streamType, "ultrasonic")) {
1194         GetStreamVolumeFade(sessionID, &fadeBeg, &fadeEnd);
1195     }
1196     if (pa_memblock_is_silence(pchunk->memblock)) {
1197         AUTO_CTRACE("hdi_sink::ProcessAudioVolume: is_silence");
1198         AUDIO_PRERELEASE_LOGI("pa_memblock_is_silence");
1199     } else {
1200         AudioRawFormat rawFormat;
1201         rawFormat.format = (uint32_t)ConvertPaToHdiAdapterFormat(si->sample_spec.format);
1202         rawFormat.channels = (uint32_t)si->sample_spec.channels;
1203 
1204         pa_memchunk_make_writable(pchunk, 0);
1205         void *data = pa_memblock_acquire_chunk(pchunk);
1206 
1207         AUDIO_DEBUG_LOG("length:%{public}zu channels:%{public}d format:%{public}d"
1208             " volumeBeg:%{public}f, volumeEnd:%{public}f, fadeBeg:%{public}f, fadeEnd:%{public}f",
1209             length, rawFormat.channels, rawFormat.format, volumeBeg, volumeEnd, fadeBeg, fadeEnd);
1210         int32_t ret = ProcessVol(data, length, rawFormat, volumeBeg * fadeBeg, volumeEnd * fadeEnd);
1211         if (ret != 0) {
1212             AUDIO_WARNING_LOG("ProcessVol failed:%{public}d", ret);
1213         }
1214         pa_memblock_release(pchunk->memblock);
1215     }
1216     if (volumeBeg != volumeEnd || fadeBeg != fadeEnd) {
1217         AUDIO_INFO_LOG("sessionID:%{public}s, length:%{public}zu, volumeBeg:%{public}f, volumeEnd:%{public}f"
1218             ", fadeBeg:%{public}f, fadeEnd:%{public}f",
1219             sessionIDStr, length, volumeBeg, volumeEnd, fadeBeg, fadeEnd);
1220         if (volumeBeg != volumeEnd) {
1221             SetPreVolume(sessionID, volumeEnd);
1222             MonitorVolume(sessionID, true);
1223         }
1224         if (fadeBeg != fadeEnd) {
1225             SetStreamVolumeFade(sessionID, fadeEnd, fadeEnd);
1226         }
1227     }
1228 }
1229 
HandleFading(pa_sink * si,size_t length,pa_sink_input * sinkIn,pa_mix_info * infoIn)1230 static void HandleFading(pa_sink *si, size_t length, pa_sink_input *sinkIn, pa_mix_info *infoIn)
1231 {
1232     struct Userdata *u;
1233     pa_assert_se(u = si->userdata);
1234 
1235     infoIn->userdata = pa_sink_input_ref(sinkIn);
1236     pa_assert(infoIn->chunk.memblock);
1237     pa_assert(infoIn->chunk.length > 0);
1238     PreparePrimaryFading(sinkIn, infoIn, si);
1239     CheckPrimaryFadeinIsDone(si, sinkIn);
1240 
1241     uint32_t sinkFadeoutPause = GetFadeoutState(sinkIn->index);
1242     if (!sinkFadeoutPause && (length <= infoIn->chunk.length)) {
1243         u->streamAvailable++;
1244     }
1245 }
1246 
SinkRenderPrimaryCluster(pa_sink * si,size_t * length,pa_mix_info * infoIn,unsigned maxInfo,const char * sceneType)1247 static unsigned SinkRenderPrimaryCluster(pa_sink *si, size_t *length, pa_mix_info *infoIn,
1248     unsigned maxInfo, const char *sceneType)
1249 {
1250     AUTO_CTRACE("hdi_sink::SinkRenderPrimaryCluster:%s len:%zu", sceneType, *length);
1251 
1252     struct Userdata *u;
1253     pa_assert_se(u = si->userdata);
1254 
1255     pa_sink_input *sinkIn;
1256     unsigned n = 0;
1257     void *state = NULL;
1258     size_t mixlength = *length;
1259 
1260     pa_sink_assert_ref(si);
1261     pa_sink_assert_io_context(si);
1262     pa_assert(infoIn);
1263 
1264     int32_t appsUid[MAX_MIX_CHANNELS];
1265     size_t count = 0;
1266     while ((sinkIn = pa_hashmap_iterate(si->thread_info.inputs, &state, NULL)) && maxInfo > 0) {
1267         CheckAndPushUidToArr(sinkIn, appsUid, &count);
1268         const char *sSceneType = pa_proplist_gets(sinkIn->proplist, "scene.type");
1269         const char *sSceneMode = pa_proplist_gets(sinkIn->proplist, "scene.mode");
1270         bool existFlag = GetExistFlag(sinkIn, sSceneType, sSceneMode, u->actualSpatializationEnabled ? "1" : "0");
1271         bool sceneTypeFlag = EffectChainManagerSceneCheck(sSceneType, sceneType);
1272         if ((IsInnerCapturer(sinkIn) && IsCaptureSilently()) || !InputIsPrimary(sinkIn)) {
1273             AUTO_CTRACE("hdi_sink::PrimaryCluster:InnerCapturer and CaptureSilently or not primary");
1274             continue;
1275         } else if ((sceneTypeFlag && existFlag) || (pa_safe_streq(sceneType, "EFFECT_NONE") && (!existFlag))) {
1276             RecordEffectChainStatus(existFlag, sSceneType, sSceneMode, u->actualSpatializationEnabled);
1277             pa_sink_input_assert_ref(sinkIn);
1278             updateResampler(sinkIn, sceneType, false);
1279 
1280             AUTO_CTRACE("hdi_sink::PrimaryCluster:%u len:%zu", sinkIn->index, *length);
1281             pa_sink_input_peek(sinkIn, *length, &infoIn->chunk, &infoIn->volume);
1282 
1283             if (mixlength == 0 || infoIn->chunk.length < mixlength) {mixlength = infoIn->chunk.length;}
1284 
1285             ProcessAudioVolume(sinkIn, mixlength, &infoIn->chunk, si);
1286 
1287             if (pa_memblock_is_silence(infoIn->chunk.memblock) && sinkIn->thread_info.state == PA_SINK_INPUT_RUNNING) {
1288                 AUTO_CTRACE("hdi_sink::PrimaryCluster::is_silence");
1289                 pa_sink_input_handle_ohos_underrun(sinkIn);
1290             } else {
1291                 AUTO_CTRACE("hdi_sink::PrimaryCluster::is_not_silence");
1292             }
1293 
1294             HandleFading(si, *length, sinkIn, infoIn);
1295 
1296             infoIn++;
1297             n++;
1298             maxInfo--;
1299         }
1300     }
1301 
1302     SafeRendererSinkUpdateAppsUid(u->primary.sinkAdapter, appsUid, count);
1303 
1304     if (mixlength > 0) { *length = mixlength; }
1305 
1306     return n;
1307 }
1308 
PrepareMultiChannelFading(pa_sink_input * sinkIn,pa_mix_info * infoIn,pa_sink * si)1309 static void PrepareMultiChannelFading(pa_sink_input *sinkIn, pa_mix_info *infoIn, pa_sink *si)
1310 {
1311     struct Userdata *u;
1312     pa_assert_se(u = si->userdata);
1313 
1314     uint32_t streamIndex = sinkIn->index;
1315     uint32_t sinkFadeoutPause = GetFadeoutState(streamIndex);
1316     if (sinkFadeoutPause == DONE_FADE) {
1317         silenceData(infoIn, si);
1318         AUDIO_PRERELEASE_LOGI("silenceData.");
1319         return;
1320     }
1321 
1322     uint32_t format = (uint32_t)ConvertPaToHdiAdapterFormat(u->format);
1323     if (pa_atomic_load(&u->multiChannel.fadingFlagForMultiChannel) == 1 &&
1324         u->multiChannel.multiChannelSinkInIndex == (int32_t)sinkIn->index) {
1325         if (pa_memblock_is_silence(infoIn->chunk.memblock)) {
1326             AUDIO_DEBUG_LOG("pa_memblock_is_silence");
1327             return;
1328         }
1329         //do fading in
1330         pa_memchunk_make_writable(&infoIn->chunk, 0);
1331         void *data = pa_memblock_acquire_chunk(&infoIn->chunk);
1332         DoFading(data, infoIn->chunk.length, format, (uint32_t)u->ss.channels, 0);
1333         u->multiChannel.multiChannelFadingInDone = 1;
1334         pa_memblock_release(infoIn->chunk.memblock);
1335     }
1336     if (sinkFadeoutPause == DO_FADE) {
1337         //do fading out
1338         pa_memchunk_make_writable(&infoIn->chunk, 0);
1339         void *data = pa_memblock_acquire_chunk(&infoIn->chunk);
1340         DoFading(data, infoIn->chunk.length, format, (uint32_t)u->ss.channels, 1);
1341         SetFadeoutState(streamIndex, DONE_FADE);
1342     }
1343 }
1344 
CheckMultiChannelFadeinIsDone(pa_sink * si,pa_sink_input * sinkIn)1345 static void CheckMultiChannelFadeinIsDone(pa_sink *si, pa_sink_input *sinkIn)
1346 {
1347     struct Userdata *u;
1348     pa_assert_se(u = si->userdata);
1349 
1350     if (u->multiChannel.multiChannelFadingInDone &&
1351         u->multiChannel.multiChannelSinkInIndex == (int32_t)sinkIn->index) {
1352         pa_atomic_store(&u->multiChannel.fadingFlagForMultiChannel, 0);
1353     }
1354 }
1355 
SinkRenderMultiChannelCluster(pa_sink * si,size_t * length,pa_mix_info * infoIn,unsigned maxInfo)1356 static unsigned SinkRenderMultiChannelCluster(pa_sink *si, size_t *length, pa_mix_info *infoIn,
1357     unsigned maxInfo)
1358 {
1359     pa_sink_input *sinkIn;
1360     unsigned n = 0;
1361     void *state = NULL;
1362     size_t mixlength = *length;
1363 
1364     pa_sink_assert_ref(si);
1365     pa_sink_assert_io_context(si);
1366     pa_assert(infoIn);
1367 
1368     struct Userdata *u;
1369     pa_assert_se(u = si->userdata);
1370 
1371     int32_t appsUid[MAX_MIX_CHANNELS];
1372     size_t count = 0;
1373 
1374     while ((sinkIn = pa_hashmap_iterate(si->thread_info.inputs, &state, NULL)) && maxInfo > 0) {
1375         CheckAndPushUidToArr(sinkIn, appsUid, &count);
1376         int32_t sinkChannels = sinkIn->sample_spec.channels;
1377         const char *sinkSceneType = pa_proplist_gets(sinkIn->proplist, "scene.type");
1378         const char *sinkSceneMode = pa_proplist_gets(sinkIn->proplist, "scene.mode");
1379         const char *sinkSpatializationEnabled = pa_proplist_gets(sinkIn->proplist, "spatialization.enabled");
1380         bool existFlag = EffectChainManagerExist(sinkSceneType, sinkSceneMode, sinkSpatializationEnabled);
1381         if (!existFlag && sinkChannels > PRIMARY_CHANNEL_NUM) {
1382             pa_sink_input_assert_ref(sinkIn);
1383             updateResampler(sinkIn, NULL, true);
1384             pa_sink_input_peek(sinkIn, *length, &infoIn->chunk, &infoIn->volume);
1385 
1386             if (mixlength == 0 || infoIn->chunk.length < mixlength) {mixlength = infoIn->chunk.length;}
1387 
1388             ProcessAudioVolume(sinkIn, mixlength, &infoIn->chunk, si);
1389 
1390             if (pa_memblock_is_silence(infoIn->chunk.memblock) && sinkIn->thread_info.state == PA_SINK_INPUT_RUNNING) {
1391                 AUTO_CTRACE("hdi_sink::SinkRenderMultiChannelCluster::is_silence");
1392                 pa_sink_input_handle_ohos_underrun(sinkIn);
1393             }
1394 
1395             infoIn->userdata = pa_sink_input_ref(sinkIn);
1396             pa_assert(infoIn->chunk.memblock);
1397             pa_assert(infoIn->chunk.length > 0);
1398 
1399             if (pa_safe_streq(sinkSpatializationEnabled, "true")) {
1400                 PrepareMultiChannelFading(sinkIn, infoIn, si);
1401                 CheckMultiChannelFadeinIsDone(si, sinkIn);
1402             }
1403             infoIn++;
1404             n++;
1405             maxInfo--;
1406         }
1407     }
1408 
1409     SafeRendererSinkUpdateAppsUid(u->multiChannel.sinkAdapter, appsUid, count);
1410 
1411     if (mixlength > 0) { *length = mixlength; }
1412 
1413     return n;
1414 }
1415 
SinkRenderPrimaryPeek(pa_sink * si,pa_memchunk * chunkIn,const char * sceneType)1416 static int32_t SinkRenderPrimaryPeek(pa_sink *si, pa_memchunk *chunkIn, const char *sceneType)
1417 {
1418     pa_mix_info info[MAX_MIX_CHANNELS];
1419     unsigned n;
1420     size_t length;
1421     size_t blockSizeMax;
1422 
1423     pa_sink_assert_ref(si);
1424     pa_sink_assert_io_context(si);
1425     pa_assert(PA_SINK_IS_LINKED(si->thread_info.state));
1426     pa_assert(chunkIn);
1427     pa_assert(chunkIn->memblock);
1428     pa_assert(chunkIn->length > 0);
1429     pa_assert(pa_frame_aligned(chunkIn->length, &si->sample_spec));
1430 
1431     pa_assert(!si->thread_info.rewind_requested);
1432     pa_assert(si->thread_info.rewind_nbytes == 0);
1433 
1434     if (si->thread_info.state == PA_SINK_SUSPENDED) {
1435         AUTO_CTRACE("hdi_sink::Primary:PA_SINK_SUSPENDED");
1436         pa_silence_memchunk(chunkIn, &si->sample_spec);
1437         return 0;
1438     }
1439 
1440     pa_sink_ref(si);
1441 
1442     length = chunkIn->length;
1443     blockSizeMax = pa_mempool_block_size_max(si->core->mempool);
1444     if (length > blockSizeMax)
1445         length = pa_frame_align(blockSizeMax, &si->sample_spec);
1446 
1447     pa_assert(length > 0);
1448     n = SinkRenderPrimaryCluster(si, &length, info, MAX_MIX_CHANNELS, sceneType);
1449 
1450     AUTO_CTRACE("hdi_sink:Primary:SinkRenderPrimaryMix:%u len:%zu", n, length);
1451     SinkRenderPrimaryMix(si, length, info, n, chunkIn);
1452 
1453     SinkRenderPrimaryInputsDrop(si, info, n, chunkIn);
1454     pa_sink_unref(si);
1455     return n;
1456 }
1457 
SinkRenderMultiChannelPeek(pa_sink * si,pa_memchunk * chunkIn)1458 static int32_t SinkRenderMultiChannelPeek(pa_sink *si, pa_memchunk *chunkIn)
1459 {
1460     pa_mix_info info[MAX_MIX_CHANNELS];
1461     unsigned n;
1462     size_t length;
1463     size_t blockSizeMax;
1464 
1465     pa_sink_assert_ref(si);
1466     pa_sink_assert_io_context(si);
1467     pa_assert(PA_SINK_IS_LINKED(si->thread_info.state));
1468     pa_assert(chunkIn);
1469     pa_assert(chunkIn->memblock);
1470     pa_assert(chunkIn->length > 0);
1471     pa_assert(pa_frame_aligned(chunkIn->length, &si->sample_spec));
1472 
1473     pa_assert(!si->thread_info.rewind_requested);
1474     pa_assert(si->thread_info.rewind_nbytes == 0);
1475 
1476     if (si->thread_info.state == PA_SINK_SUSPENDED) {
1477         AUTO_CTRACE("hdi_sink::MultiCh:PA_SINK_SUSPENDED");
1478         pa_silence_memchunk(chunkIn, &si->sample_spec);
1479         return 0;
1480     }
1481 
1482     pa_sink_ref(si);
1483 
1484     length = chunkIn->length;
1485     blockSizeMax = pa_mempool_block_size_max(si->core->mempool);
1486     if (length > blockSizeMax)
1487         length = pa_frame_align(blockSizeMax, &si->sample_spec);
1488 
1489     pa_assert(length > 0);
1490 
1491     n = SinkRenderMultiChannelCluster(si, &length, info, MAX_MIX_CHANNELS);
1492 
1493     AUTO_CTRACE("hdi_sink:MultiCh:SinkRenderPrimaryMix:%u len:%zu", n, length);
1494     SinkRenderPrimaryMix(si, length, info, n, chunkIn);
1495 
1496     SinkRenderMultiChannelInputsDrop(si, info, n, chunkIn);
1497     pa_sink_unref(si);
1498 
1499     return n;
1500 }
1501 
SinkRenderPrimaryGetData(pa_sink * si,pa_memchunk * chunkIn,char * sceneType)1502 static int32_t SinkRenderPrimaryGetData(pa_sink *si, pa_memchunk *chunkIn, char *sceneType)
1503 {
1504     AUTO_CTRACE("hdi_sink::SinkRenderPrimaryGetData:%s", sceneType);
1505     pa_memchunk chunk;
1506     size_t l;
1507     size_t d;
1508     pa_sink_assert_ref(si);
1509     pa_sink_assert_io_context(si);
1510     pa_assert(PA_SINK_IS_LINKED(si->thread_info.state));
1511     pa_assert(chunkIn);
1512     pa_assert(chunkIn->memblock);
1513     pa_assert(chunkIn->length > 0);
1514     pa_assert(pa_frame_aligned(chunkIn->length, &si->sample_spec));
1515 
1516     pa_assert(!si->thread_info.rewind_requested);
1517     pa_assert(si->thread_info.rewind_nbytes == 0);
1518 
1519     if (si->thread_info.state == PA_SINK_SUSPENDED) {
1520         pa_silence_memchunk(chunkIn, &si->sample_spec);
1521         return 0;
1522     }
1523 
1524     pa_sink_ref(si);
1525 
1526     l = chunkIn->length;
1527     d = 0;
1528     int32_t nSinkInput = 0;
1529     while (l > 0) {
1530         chunk = *chunkIn;
1531         chunk.index += d;
1532         chunk.length -= d;
1533 
1534         nSinkInput = SinkRenderPrimaryPeek(si, &chunk, sceneType);
1535 
1536         d += chunk.length;
1537         l -= chunk.length;
1538     }
1539     pa_sink_unref(si);
1540 
1541     return nSinkInput;
1542 }
1543 
SinkRenderMultiChannelGetData(pa_sink * si,pa_memchunk * chunkIn)1544 static int32_t SinkRenderMultiChannelGetData(pa_sink *si, pa_memchunk *chunkIn)
1545 {
1546     pa_memchunk chunk;
1547     size_t l;
1548     size_t d;
1549     pa_sink_assert_ref(si);
1550     pa_sink_assert_io_context(si);
1551     pa_assert(PA_SINK_IS_LINKED(si->thread_info.state));
1552     pa_assert(chunkIn);
1553     pa_assert(chunkIn->memblock);
1554     pa_assert(chunkIn->length > 0);
1555     pa_assert(pa_frame_aligned(chunkIn->length, &si->sample_spec));
1556 
1557     pa_assert(!si->thread_info.rewind_requested);
1558     pa_assert(si->thread_info.rewind_nbytes == 0);
1559 
1560     if (si->thread_info.state == PA_SINK_SUSPENDED) {
1561         pa_silence_memchunk(chunkIn, &si->sample_spec);
1562         return 0;
1563     }
1564 
1565     pa_sink_ref(si);
1566 
1567     l = chunkIn->length;
1568     d = 0;
1569 
1570     int32_t nSinkInput = 0;
1571     while (l > 0) {
1572         chunk = *chunkIn;
1573         chunk.index += d;
1574         chunk.length -= d;
1575 
1576         nSinkInput = SinkRenderMultiChannelPeek(si, &chunk);
1577 
1578         d += chunk.length;
1579         l -= chunk.length;
1580     }
1581 
1582     pa_sink_unref(si);
1583 
1584     return nSinkInput;
1585 }
1586 
PrepareSpatializationFading(int8_t * fadingState,int8_t * fadingCount,bool * actualSpatializationEnabled)1587 static void PrepareSpatializationFading(int8_t *fadingState, int8_t *fadingCount, bool *actualSpatializationEnabled)
1588 {
1589     (*fadingCount) = (*fadingCount) < 0 ? 0 : (*fadingCount);
1590     (*fadingCount) =
1591         (*fadingCount) > SPATIALIZATION_FADING_FRAMECOUNT ? SPATIALIZATION_FADING_FRAMECOUNT : (*fadingCount);
1592     // fading out if spatialization changed
1593     if (*fadingState >= 0 && *actualSpatializationEnabled != EffectChainManagerGetSpatializationEnabled()) {
1594         *fadingState = -1;
1595     }
1596     // fading in when fading out is done
1597     if (*fadingState < 0 && *fadingCount == 0) {
1598         *fadingState = 1;
1599         *actualSpatializationEnabled = EffectChainManagerGetSpatializationEnabled();
1600         EffectChainManagerFlush();
1601     }
1602     // no need to fade when fading out is done
1603     if (*fadingState > 0 && *fadingCount == SPATIALIZATION_FADING_FRAMECOUNT) {
1604         *fadingState = 0;
1605     }
1606 }
1607 
DoSpatializationFading(float * buf,int8_t fadingState,int8_t * fadingCount,int32_t frameLen,int32_t channels)1608 static void DoSpatializationFading(float *buf, int8_t fadingState, int8_t *fadingCount, int32_t frameLen,
1609     int32_t channels)
1610 {
1611     // no need fading
1612     if (fadingState == 0) {
1613         return;
1614     }
1615     // fading out when fadingState equals -1, fading in when fadingState equals 1;
1616     for (int32_t i = 0; i < frameLen; i++) {
1617         for (int32_t j = 0; j < channels; j++) {
1618             buf[i * channels + j] *=
1619                 ((*fadingCount) * frameLen + i * fadingState) / (float)(SPATIALIZATION_FADING_FRAMECOUNT * frameLen);
1620         }
1621     }
1622     (*fadingCount) += fadingState;
1623 }
1624 
SinkRenderPrimaryAfterProcess(pa_sink * si,size_t length,pa_memchunk * chunkIn)1625 static void SinkRenderPrimaryAfterProcess(pa_sink *si, size_t length, pa_memchunk *chunkIn)
1626 {
1627     struct Userdata *u;
1628     pa_assert_se(u = si->userdata);
1629     int32_t bitSize = (int32_t)pa_sample_size_of_format(u->format);
1630     u->bufferAttr->numChanIn = DEFAULT_IN_CHANNEL_NUM;
1631     void *dst = pa_memblock_acquire_chunk(chunkIn);
1632     int32_t frameLen = bitSize > 0 ? ((int32_t)length / bitSize) : 0;
1633     DoSpatializationFading(u->bufferAttr->tempBufOut, u->spatializationFadingState, &u->spatializationFadingCount,
1634         frameLen / DEFAULT_IN_CHANNEL_NUM, DEFAULT_IN_CHANNEL_NUM);
1635     ConvertFromFloat(u->format, frameLen, u->bufferAttr->tempBufOut, dst);
1636 
1637     chunkIn->index = 0;
1638     chunkIn->length = length;
1639     pa_memblock_release(chunkIn->memblock);
1640 }
1641 
HandleSinkSceneType(struct Userdata * u,time_t currentTime,int32_t i)1642 static char *HandleSinkSceneType(struct Userdata *u, time_t currentTime, int32_t i)
1643 {
1644     char *sinkSceneType = SCENE_TYPE_SET[i];
1645     if (g_effectAllStreamVolumeZeroMap[i] && PA_SINK_IS_RUNNING(u->sink->thread_info.state) &&
1646         difftime(currentTime, g_effectStartVolZeroTimeMap[i]) > WAIT_CLOSE_PA_OR_EFFECT_TIME) {
1647         sinkSceneType = SCENE_TYPE_SET[SCENE_TYPE_NUM - 1]; // EFFECT_NONE
1648         if (!g_effectHaveDisabledMap[i]) {
1649             AUDIO_INFO_LOG("volume change to zero over %{public}ds, close effect:%{public}s success.",
1650                 WAIT_CLOSE_PA_OR_EFFECT_TIME, SCENE_TYPE_SET[i]);
1651             g_effectHaveDisabledMap[i] = true;
1652             g_effectStartVolZeroTimeMap[i] = 0;
1653         }
1654     } else {
1655         sinkSceneType = SCENE_TYPE_SET[i];
1656         if (g_effectHaveDisabledMap[i]) {
1657             g_effectHaveDisabledMap[i] = false;
1658             AUDIO_INFO_LOG("volume change to non zero, open effect:%{public}s success. ", SCENE_TYPE_SET[i]);
1659         }
1660     }
1661     return sinkSceneType;
1662 }
1663 
CheckAndDealEffectZeroVolume(struct Userdata * u,time_t currentTime,int32_t i)1664 static char *CheckAndDealEffectZeroVolume(struct Userdata *u, time_t currentTime, int32_t i)
1665 {
1666     void *state = NULL;
1667     pa_sink_input *input;
1668     g_effectAllStreamVolumeZeroMap[i] = true;
1669     while ((input = pa_hashmap_iterate(u->sink->thread_info.inputs, &state, NULL))) {
1670         pa_sink_input_assert_ref(input);
1671         if (input->thread_info.state != PA_SINK_INPUT_RUNNING) {
1672             continue;
1673         }
1674         const char *sinkSceneTypeTmp = pa_proplist_gets(input->proplist, "scene.type");
1675         const char *streamType = safeProplistGets(input->proplist, "stream.type", "NULL");
1676         const char *sessionIDStr = safeProplistGets(input->proplist, "stream.sessionID", "NULL");
1677         const char *deviceClass = GetDeviceClass(u->primary.sinkAdapter->deviceClass);
1678         uint32_t sessionID = sessionIDStr != NULL ? atoi(sessionIDStr) : 0;
1679         float volume = GetCurVolume(sessionID, streamType, deviceClass);
1680         bool isZeroVolume = IsSameVolume(volume, 0.0f);
1681         if (EffectChainManagerSceneCheck(sinkSceneTypeTmp, SCENE_TYPE_SET[i]) && !isZeroVolume) {
1682             g_effectAllStreamVolumeZeroMap[i] = false;
1683             g_effectStartVolZeroTimeMap[i] = 0;
1684             AUDIO_DEBUG_LOG("SCENE_TYPE_SET[%{public}d]:%{public}s for streamtype:[%{public}s]'s"
1685                 " volume is non zero, this effect all streamtype is non zero volume.", i,
1686                 SCENE_TYPE_SET[i], streamType);
1687             break;
1688         }
1689     }
1690 
1691     if (g_effectAllStreamVolumeZeroMap[i] && !g_effectHaveDisabledMap[i] && (g_effectStartVolZeroTimeMap[i] == 0) &&
1692         PA_SINK_IS_RUNNING(u->sink->thread_info.state)) {
1693         AUDIO_INFO_LOG("Timing begins, will close [%{public}s] effect after [%{public}d]s", SCENE_TYPE_SET[i],
1694             WAIT_CLOSE_PA_OR_EFFECT_TIME);
1695         time(&g_effectStartVolZeroTimeMap[i]);
1696     }
1697 
1698     char *handledSceneType = HandleSinkSceneType(u, currentTime, i);
1699     AUDIO_DEBUG_LOG("handle sink scene type:%{public}s", handledSceneType);
1700     return handledSceneType;
1701 }
1702 
CheckOnlyPrimarySpeakerPaLoading(struct Userdata * u)1703 static void CheckOnlyPrimarySpeakerPaLoading(struct Userdata *u)
1704 {
1705     pa_sink *s;
1706     pa_core *c = u->core;
1707     uint32_t idx;
1708     PA_IDXSET_FOREACH(s, c->sinks, idx) {
1709         bool isHdiSink = !strncmp(s->driver, "module_hdi_sink", 15); // 15 cmp length
1710         if (isHdiSink && strcmp(s->name, "Speaker")) {
1711             AUDIO_DEBUG_LOG("Have new routing:[%{public}s] on primary, dont close it.", s->name);
1712             g_onlyPrimarySpeakerPaLoading = false;
1713             g_speakerPaAllStreamVolumeZero = false;
1714             g_speakerPaAllStreamStartVolZeroTime = 0;
1715             break;
1716         }
1717     }
1718 
1719     if (strcmp(GetDeviceClass(u->primary.sinkAdapter->deviceClass), "primary")) {
1720         AUDIO_DEBUG_LOG("Sink[%{public}s] -- no primary, dont close it.",
1721             GetDeviceClass(u->primary.sinkAdapter->deviceClass));
1722         g_onlyPrimarySpeakerPaLoading = false;
1723         g_speakerPaAllStreamVolumeZero = false;
1724         g_speakerPaAllStreamStartVolZeroTime = 0;
1725     }
1726 
1727     if (PA_SINK_IS_RUNNING(u->sink->thread_info.state) && !g_onlyPrimarySpeakerPaLoading && g_paHaveDisabled) {
1728         int32_t ret = u->primary.sinkAdapter->RendererSinkSetPaPower(u->primary.sinkAdapter, 1);
1729         AUDIO_INFO_LOG("sink running, open closed pa:[%{public}s] -- [%{public}s], ret:%{public}d", u->sink->name,
1730             (ret == 0 ? "success" : "failed"), ret);
1731         g_paHaveDisabled = false;
1732         g_speakerPaHaveClosed = false;
1733     }
1734 }
1735 
HandleClosePa(struct Userdata * u)1736 static void HandleClosePa(struct Userdata *u)
1737 {
1738     if (!g_paHaveDisabled) {
1739         int32_t ret = u->primary.sinkAdapter->RendererSinkSetPaPower(u->primary.sinkAdapter, 0);
1740         AUDIO_INFO_LOG("Speaker pa volume change to zero over [%{public}d]s, close %{public}s pa [%{public}s], "
1741             "ret:%{public}d", WAIT_CLOSE_PA_OR_EFFECT_TIME, u->sink->name, (ret == 0 ? "success" : "failed"), ret);
1742         g_paHaveDisabled = true;
1743         g_speakerPaAllStreamStartVolZeroTime = 0;
1744         g_speakerPaHaveClosed = true;
1745         time(&g_speakerPaClosedTime);
1746     }
1747 }
1748 
HandleOpenPa(struct Userdata * u)1749 static void HandleOpenPa(struct Userdata *u)
1750 {
1751     if (g_paHaveDisabled) {
1752         int32_t ret = u->primary.sinkAdapter->RendererSinkSetPaPower(u->primary.sinkAdapter, 1);
1753         AUDIO_INFO_LOG("volume change to non zero, open closed pa:[%{public}s] -- [%{public}s], ret:%{public}d",
1754             u->sink->name, (ret == 0 ? "success" : "failed"), ret);
1755         g_paHaveDisabled = false;
1756         g_speakerPaHaveClosed = false;
1757     }
1758 }
1759 
CheckAndDealSpeakerPaZeroVolume(struct Userdata * u,time_t currentTime)1760 static void CheckAndDealSpeakerPaZeroVolume(struct Userdata *u, time_t currentTime)
1761 {
1762     if (!g_onlyPrimarySpeakerPaLoading) {
1763         AUDIO_DEBUG_LOG("Not only the speaker pa, dont deal speaker pa.");
1764         return;
1765     }
1766     void *state = NULL;
1767     pa_sink_input *input;
1768     while ((input = pa_hashmap_iterate(u->sink->thread_info.inputs, &state, NULL))) {
1769         pa_sink_input_assert_ref(input);
1770         if (input->thread_info.state != PA_SINK_INPUT_RUNNING) {
1771             continue;
1772         }
1773         const char *streamType = safeProplistGets(input->proplist, "stream.type", "NULL");
1774         const char *sessionIDStr = safeProplistGets(input->proplist, "stream.sessionID", "NULL");
1775         const char *deviceClass = GetDeviceClass(u->primary.sinkAdapter->deviceClass);
1776         uint32_t sessionID = sessionIDStr != NULL ? atoi(sessionIDStr) : 0;
1777         float volume = GetCurVolume(sessionID, streamType, deviceClass);
1778         bool isZeroVolume = IsSameVolume(volume, 0.0f);
1779         if (!strcmp(u->sink->name, "Speaker") && !isZeroVolume) {
1780             g_speakerPaAllStreamVolumeZero = false;
1781             g_speakerPaAllStreamStartVolZeroTime = 0;
1782             break;
1783         }
1784     }
1785 
1786     if (g_speakerPaAllStreamVolumeZero && !g_paHaveDisabled && (g_speakerPaAllStreamStartVolZeroTime == 0) &&
1787         PA_SINK_IS_RUNNING(u->sink->thread_info.state)) {
1788         AUDIO_INFO_LOG("Timing begins, will close speaker after [%{public}d]s", WAIT_CLOSE_PA_OR_EFFECT_TIME);
1789         time(&g_speakerPaAllStreamStartVolZeroTime);
1790     }
1791     if (g_speakerPaAllStreamVolumeZero && PA_SINK_IS_RUNNING(u->sink->thread_info.state) &&
1792         difftime(currentTime, g_speakerPaAllStreamStartVolZeroTime) > WAIT_CLOSE_PA_OR_EFFECT_TIME) {
1793         HandleClosePa(u);
1794     } else {
1795         HandleOpenPa(u);
1796     }
1797 
1798     if (g_speakerPaHaveClosed && difftime(currentTime, g_speakerPaClosedTime) >= MONITOR_CLOSE_PA_TIME_SEC) {
1799         time(&g_speakerPaClosedTime);
1800         AUDIO_INFO_LOG("Speaker pa have closed [%{public}d]s.", MONITOR_CLOSE_PA_TIME_SEC);
1801     }
1802 }
1803 
UpdateStreamAvailableMap(struct Userdata * u,const char * sceneType)1804 static void UpdateStreamAvailableMap(struct Userdata *u, const char *sceneType)
1805 {
1806     if (u->streamAvailableMap == NULL) {
1807         AUDIO_ERR_LOG("streamAvailableMap is null");
1808         return;
1809     }
1810     uint32_t *num = (uint32_t *)pa_hashmap_get(u->streamAvailableMap, sceneType);
1811     if (num == NULL) {
1812         num = pa_xnew0(uint32_t, 1);
1813         (*num) = 0;
1814     }
1815     int32_t fadeDirection = (u->streamAvailable != 0) && ((*num) == 0) ? 0 :
1816                     (u->streamAvailable == 0 && (*num) != 0) ? 1 : -1;
1817     int32_t outLength = u->bufferAttr->frameLen * u->bufferAttr->numChanOut * sizeof(float);
1818     if (fadeDirection != -1) {
1819         AUDIO_INFO_LOG("do %{public}s for MIXED DATA", fadeDirection ? "fade-out" : "fade-in");
1820         DoFading(u->bufferAttr->bufOut, outLength, (uint32_t)SAMPLE_F32, (uint32_t)u->ss.channels, fadeDirection);
1821     }
1822     if (u->streamAvailable == 0 && (*num) == 0) {
1823         memset_s(u->bufferAttr->bufOut, outLength, 0, outLength);
1824     }
1825 
1826     if (pa_hashmap_get(u->streamAvailableMap, sceneType) != NULL) {
1827         (*num) = u->streamAvailable;
1828     } else {
1829         char *scene = strdup(sceneType);
1830         if (scene != NULL) {
1831             (*num) = u->streamAvailable;
1832             if (pa_hashmap_put(u->streamAvailableMap, scene, num) != 0) {
1833                 AUDIO_ERR_LOG("pa_hashmap_put failed");
1834                 free(scene);
1835                 pa_xfree(num);
1836             }
1837         }
1838     }
1839 }
1840 
PrimaryEffectProcess(struct Userdata * u,pa_memchunk * chunkIn,char * sinkSceneType)1841 static void PrimaryEffectProcess(struct Userdata *u, pa_memchunk *chunkIn, char *sinkSceneType)
1842 {
1843     AUTO_CTRACE("hdi_sink::EffectChainManagerProcess:%s", sinkSceneType);
1844     EffectChainManagerProcess(sinkSceneType, u->bufferAttr);
1845     UpdateStreamAvailableMap(u, sinkSceneType);
1846     for (int32_t k = 0; k < u->bufferAttr->frameLen * u->bufferAttr->numChanOut; k++) {
1847         u->bufferAttr->tempBufOut[k] += u->bufferAttr->bufOut[k];
1848     }
1849     pa_memblock_release(chunkIn->memblock);
1850     u->bufferAttr->numChanIn = DEFAULT_IN_CHANNEL_NUM;
1851 }
1852 
AllocateBuffer(size_t size)1853 static void *AllocateBuffer(size_t size)
1854 {
1855     if (size > 0 && size <= sizeof(float) * DEFAULT_FRAMELEN * IN_CHANNEL_NUM_MAX) {
1856         return malloc(size);
1857     } else {
1858         return NULL;
1859     }
1860 }
1861 
AllocateEffectBuffer(struct Userdata * u)1862 static bool AllocateEffectBuffer(struct Userdata *u)
1863 {
1864     if (u->bufferAttr == NULL) {
1865         return false;
1866     }
1867     float **buffers[] = { &u->bufferAttr->bufIn, &u->bufferAttr->bufOut,
1868         &u->bufferAttr->tempBufIn, &u->bufferAttr->tempBufOut };
1869     size_t numBuffers = sizeof(buffers) / sizeof(buffers[0]);
1870     for (size_t i = 0; i < numBuffers; i++) {
1871         *buffers[i] = (float *)AllocateBuffer(u->processSize);
1872         if (*buffers[i] == NULL) {
1873             AUDIO_ERR_LOG("failed to allocate effect buffer");
1874             FreeEffectBuffer(u);
1875             return false;
1876         }
1877     }
1878     return true;
1879 }
1880 
FreeEffectBuffer(struct Userdata * u)1881 static void FreeEffectBuffer(struct Userdata *u)
1882 {
1883     if (u->bufferAttr == NULL) {
1884         return;
1885     }
1886     float **buffers[] = { &u->bufferAttr->bufIn, &u->bufferAttr->bufOut,
1887         &u->bufferAttr->tempBufIn, &u->bufferAttr->tempBufOut };
1888     size_t numBuffers = sizeof(buffers) / sizeof(buffers[0]);
1889     for (size_t i = 0; i < numBuffers; i++) {
1890         free(*buffers[i]);
1891         *buffers[i] = NULL;
1892     }
1893 }
1894 
ResetBufferAttr(struct Userdata * u)1895 static void ResetBufferAttr(struct Userdata *u)
1896 {
1897     size_t memsetInLen = sizeof(float) * DEFAULT_FRAMELEN * IN_CHANNEL_NUM_MAX;
1898     size_t memsetOutLen = sizeof(float) * DEFAULT_FRAMELEN * OUT_CHANNEL_NUM_MAX;
1899     if (memset_s(u->bufferAttr->tempBufIn, u->processSize, 0, memsetInLen) != EOK) {
1900         AUDIO_WARNING_LOG("SinkRenderBufIn memset_s failed");
1901     }
1902     if (memset_s(u->bufferAttr->tempBufOut, u->processSize, 0, memsetOutLen) != EOK) {
1903         AUDIO_WARNING_LOG("SinkRenderBufOut memset_s failed");
1904     }
1905 }
1906 
SinkRenderPrimaryProcess(pa_sink * si,size_t length,pa_memchunk * chunkIn)1907 static void SinkRenderPrimaryProcess(pa_sink *si, size_t length, pa_memchunk *chunkIn)
1908 {
1909     if (GetInnerCapturerState()) {
1910         pa_memchunk capResult;
1911         SinkRenderCapProcess(si, length, &capResult);
1912         pa_memblock_unref(capResult.memblock);
1913     }
1914 
1915     struct Userdata *u;
1916     pa_assert_se(u = si->userdata);
1917 
1918     ResetBufferAttr(u);
1919     int32_t bitSize = (int32_t)pa_sample_size_of_format(u->format);
1920     chunkIn->memblock = pa_memblock_new(si->core->mempool, length * IN_CHANNEL_NUM_MAX / DEFAULT_IN_CHANNEL_NUM);
1921     time_t currentTime = time(NULL);
1922     PrepareSpatializationFading(&u->spatializationFadingState, &u->spatializationFadingCount,
1923         &u->actualSpatializationEnabled);
1924     g_effectProcessFrameCount++;
1925     u->streamAvailable = 0;
1926     for (int32_t i = 0; i < SCENE_TYPE_NUM; i++) {
1927         uint32_t processChannels = DEFAULT_NUM_CHANNEL;
1928         uint64_t processChannelLayout = DEFAULT_CHANNELLAYOUT;
1929         EffectChainManagerReturnEffectChannelInfo(SCENE_TYPE_SET[i], &processChannels, &processChannelLayout);
1930         char *sinkSceneType = CheckAndDealEffectZeroVolume(u, currentTime, i);
1931         size_t tmpLength = length * processChannels / DEFAULT_IN_CHANNEL_NUM;
1932         chunkIn->index = 0;
1933         chunkIn->length = tmpLength;
1934         int32_t nSinkInput = SinkRenderPrimaryGetData(si, chunkIn, SCENE_TYPE_SET[i]);
1935         if (nSinkInput == 0) { continue; }
1936         chunkIn->index = 0;
1937         chunkIn->length = tmpLength;
1938         void *src = pa_memblock_acquire_chunk(chunkIn);
1939         int32_t frameLen = bitSize > 0 ? ((int32_t)tmpLength / bitSize) : 0;
1940 
1941         ConvertToFloat(u->format, frameLen, src, u->bufferAttr->tempBufIn);
1942         memcpy_s(u->bufferAttr->bufIn, frameLen * sizeof(float), u->bufferAttr->tempBufIn, frameLen * sizeof(float));
1943         u->bufferAttr->numChanIn = (int32_t)processChannels;
1944         u->bufferAttr->frameLen = frameLen / u->bufferAttr->numChanIn;
1945         PrimaryEffectProcess(u, chunkIn, sinkSceneType);
1946     }
1947     if (g_effectProcessFrameCount == PRINT_INTERVAL_FRAME_COUNT) { g_effectProcessFrameCount = 0; }
1948     CheckAndDealSpeakerPaZeroVolume(u, currentTime);
1949     SinkRenderPrimaryAfterProcess(si, length, chunkIn);
1950 }
1951 
SinkRenderPrimary(pa_sink * si,size_t length,pa_memchunk * chunkIn)1952 static void SinkRenderPrimary(pa_sink *si, size_t length, pa_memchunk *chunkIn)
1953 {
1954     pa_sink_ref(si);
1955 
1956     size_t blockSizeMax;
1957 
1958     pa_sink_assert_ref(si);
1959     pa_sink_assert_io_context(si);
1960     pa_assert(PA_SINK_IS_LINKED(si->thread_info.state));
1961     pa_assert(length > 0);
1962     pa_assert(pa_frame_aligned(length, &si->sample_spec));
1963     pa_assert(chunkIn);
1964 
1965     pa_assert(!si->thread_info.rewind_requested);
1966     pa_assert(si->thread_info.rewind_nbytes == 0);
1967 
1968     if (si->thread_info.state == PA_SINK_SUSPENDED) {
1969         chunkIn->memblock = pa_memblock_ref(si->silence.memblock);
1970         chunkIn->index = si->silence.index;
1971         chunkIn->length = PA_MIN(si->silence.length, length);
1972         return;
1973     }
1974 
1975     if (length == 0)
1976         length = pa_frame_align(MIX_BUFFER_LENGTH, &si->sample_spec);
1977 
1978     blockSizeMax = pa_mempool_block_size_max(si->core->mempool);
1979     if (length > blockSizeMax)
1980         length = pa_frame_align(blockSizeMax, &si->sample_spec);
1981 
1982     pa_assert(length > 0);
1983     AUTO_CTRACE("hdi_sink::SinkRenderPrimaryProcess:len:%zu", length);
1984     SinkRenderPrimaryProcess(si, length, chunkIn);
1985 
1986     pa_sink_unref(si);
1987 }
1988 
SetSinkVolumeByDeviceClass(pa_sink * s,const char * deviceClass)1989 static void SetSinkVolumeByDeviceClass(pa_sink *s, const char *deviceClass)
1990 {
1991     pa_assert(s);
1992     void *state = NULL;
1993     pa_sink_input *input;
1994     while ((input = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL))) {
1995         pa_sink_input_assert_ref(input);
1996         if (input->thread_info.state != PA_SINK_INPUT_RUNNING) {
1997             continue;
1998         }
1999         const char *streamType = safeProplistGets(input->proplist, "stream.type", "NULL");
2000         const char *sessionIDStr = safeProplistGets(input->proplist, "stream.sessionID", "NULL");
2001         uint32_t sessionID = sessionIDStr != NULL ? atoi(sessionIDStr) : 0;
2002         float volumeEnd = GetCurVolume(sessionID, streamType, deviceClass);
2003         float volumeBeg = GetPreVolume(sessionID);
2004         if (volumeBeg != volumeEnd) {
2005             AUDIO_INFO_LOG("sessionID:%{public}s, volumeBeg:%{public}f, volumeEnd:%{public}f",
2006                 sessionIDStr, volumeBeg, volumeEnd);
2007             SetPreVolume(sessionID, volumeEnd);
2008             MonitorVolume(sessionID, true);
2009         }
2010         uint32_t volume = pa_sw_volume_from_linear(volumeEnd);
2011         pa_cvolume_set(&input->thread_info.soft_volume, input->thread_info.soft_volume.channels, volume);
2012     }
2013 }
2014 
UnsetSinkVolume(pa_sink * s)2015 static void UnsetSinkVolume(pa_sink *s)
2016 {
2017     pa_assert(s);
2018     void *state = NULL;
2019     pa_sink_input *input;
2020     while ((input = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL))) {
2021         pa_sink_input_assert_ref(input);
2022         if (input->thread_info.state != PA_SINK_INPUT_RUNNING) {
2023             continue;
2024         }
2025         uint32_t volume = pa_sw_volume_from_linear(1.0f);
2026         pa_cvolume_set(&input->thread_info.soft_volume, input->thread_info.soft_volume.channels, volume);
2027     }
2028 }
2029 
ProcessRenderUseTiming(struct Userdata * u,pa_usec_t now)2030 static void ProcessRenderUseTiming(struct Userdata *u, pa_usec_t now)
2031 {
2032     pa_assert(u);
2033 
2034     // Fill the buffer up the latency size
2035     pa_memchunk chunk;
2036 
2037     AUTO_CTRACE("hdi_sink::SinkRenderPrimary");
2038     // Change from pa_sink_render to pa_sink_render_full for alignment issue in 3516
2039 
2040     if (!strcmp(u->sink->name, DP_SINK_NAME)) {
2041         // dp update volume
2042         SetSinkVolumeByDeviceClass(u->sink, GetDeviceClass(u->primary.sinkAdapter->deviceClass));
2043         pa_sink_render_full(u->sink, u->sink->thread_info.max_request, &chunk);
2044         UnsetSinkVolume(u->sink); // reset volume 1.0f
2045     } else {
2046         if (u->isEffectBufferAllocated || AllocateEffectBuffer(u)) {
2047             u->isEffectBufferAllocated = true;
2048             SinkRenderPrimary(u->sink, u->sink->thread_info.max_request, &chunk);
2049         }
2050     }
2051     pa_assert(chunk.length > 0);
2052 
2053     StartPrimaryHdiIfRunning(u);
2054     pa_asyncmsgq_post(u->primary.dq, NULL, HDI_RENDER, NULL, 0, &chunk, NULL);
2055     u->primary.timestamp += pa_bytes_to_usec(chunk.length, &u->sink->sample_spec);
2056 }
2057 
InputIsOffload(pa_sink_input * i)2058 static bool InputIsOffload(pa_sink_input *i)
2059 {
2060     if (monitorLinked(i->sink, true)) {
2061         return false;
2062     }
2063     if (strncmp(i->sink->driver, "module_hdi_sink", 15)) { // 15 cmp length
2064         return false;
2065     }
2066     struct Userdata *u = i->sink->userdata;
2067     if (!u->offload_enable || !u->offload.inited) {
2068         return false;
2069     }
2070     const char *offloadEnableStr = pa_proplist_gets(i->proplist, "stream.offload.enable");
2071     if (offloadEnableStr == NULL) {
2072         return false;
2073     }
2074     const bool offloadEnable = !strcmp(offloadEnableStr, "1");
2075     return offloadEnable;
2076 }
2077 
InputIsMultiChannel(pa_sink_input * i)2078 static bool InputIsMultiChannel(pa_sink_input *i)
2079 {
2080     bool effectOffloadFlag = EffectChainManagerCheckEffectOffload();
2081     if (effectOffloadFlag) {
2082         int32_t sinkChannels = i->sample_spec.channels;
2083         const char *sinkSceneType = pa_proplist_gets(i->proplist, "scene.type");
2084         const char *sinkSceneMode = pa_proplist_gets(i->proplist, "scene.mode");
2085         const char *sinkSpatializationEnabled = pa_proplist_gets(i->proplist, "spatialization.enabled");
2086         bool existFlag = EffectChainManagerExist(sinkSceneType, sinkSceneMode, sinkSpatializationEnabled);
2087         if (!existFlag && sinkChannels > PRIMARY_CHANNEL_NUM) {
2088             return true;
2089         }
2090     }
2091     return false;
2092 }
2093 
InputIsPrimary(pa_sink_input * i)2094 static bool InputIsPrimary(pa_sink_input *i)
2095 {
2096     const bool isOffload = InputIsOffload(i);
2097     const bool isRunning = i->thread_info.state == PA_SINK_INPUT_RUNNING;
2098     return !isOffload && isRunning;
2099 }
2100 
GetInputsInfo(enum HdiInputType type,bool isRun,pa_sink * s,pa_mix_info * info,unsigned maxinfo)2101 static unsigned GetInputsInfo(enum HdiInputType type, bool isRun, pa_sink *s, pa_mix_info *info, unsigned maxinfo)
2102 {
2103     pa_sink_input *i;
2104     unsigned n = 0;
2105     void *state = NULL;
2106 
2107     pa_sink_assert_ref(s);
2108     pa_sink_assert_io_context(s);
2109     pa_assert(s);
2110 
2111     while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)) && maxinfo > 0) {
2112         pa_sink_input_assert_ref(i);
2113 
2114         bool flag = false;
2115         const bool isOffload = InputIsOffload(i);
2116         const bool isHD = false; // add func is hd
2117         const bool isRunning = i->thread_info.state == PA_SINK_INPUT_RUNNING;
2118         if (isRun && !isRunning) {
2119             continue;
2120         }
2121         switch (type) {
2122             case HDI_INPUT_TYPE_PRIMARY:
2123                 flag = !isOffload && !isHD;
2124                 break;
2125             case HDI_INPUT_TYPE_OFFLOAD:
2126                 flag = isOffload;
2127                 break;
2128             case HDI_INPUT_TYPE_MULTICHANNEL:
2129                 flag = isHD;
2130                 break;
2131             default:
2132                 break;
2133         }
2134         if (flag) {
2135             info->userdata = pa_sink_input_ref(i);
2136         } else {
2137             const char *sessionIDStr = safeProplistGets(i->proplist, "stream.sessionID", "NULL");
2138             AUDIO_PRERELEASE_LOGE("sink: %{public}s, sink_input: %{public}s, the type is not %{public}d",
2139                 s->name, sessionIDStr, type);
2140             continue;
2141         }
2142 
2143         info++;
2144         n++;
2145         maxinfo--;
2146     }
2147     return n;
2148 }
2149 
GetInputsType(pa_sink * s,unsigned * nPrimary,unsigned * nOffload,unsigned * nMultiChannel,bool isRunning)2150 static int32_t GetInputsType(pa_sink *s, unsigned *nPrimary, unsigned *nOffload,
2151     unsigned *nMultiChannel, bool isRunning)
2152 {
2153     int ret;
2154     struct Userdata *u;
2155     pa_assert_se(u = s->userdata);
2156     if ((ret = pthread_mutex_lock(&u->mutexPa2)) != 0) {
2157         AUDIO_WARNING_LOG("GetInputsType pthread_mutex_lock ret %d", ret);
2158     }
2159     pa_sink_input *i;
2160     void *state = NULL;
2161     *nPrimary = 0;
2162     *nOffload = 0;
2163     *nMultiChannel = 0;
2164     int n = 0;
2165 
2166     pa_sink_assert_ref(s);
2167     pa_sink_assert_io_context(s);
2168     pa_assert(s);
2169     while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL))) {
2170         pa_sink_input_assert_ref(i);
2171         if (isRunning && i->thread_info.state != PA_SINK_INPUT_RUNNING) {
2172             continue;
2173         }
2174         n++;
2175         if (InputIsOffload(i)) {
2176             (*nOffload)++;
2177         } else if (!strcmp(u->sink->name, MCH_SINK_NAME) && InputIsMultiChannel(i)) {
2178             (*nMultiChannel)++;
2179         } else {
2180             (*nPrimary)++;
2181         }
2182     }
2183     if ((ret = pthread_mutex_unlock(&u->mutexPa2)) != 0) {
2184         AUDIO_WARNING_LOG("GetInputsType pthread_mutex_unlock ret %d", ret);
2185     }
2186     return n;
2187 }
2188 
GetOffloadRenderLength(struct Userdata * u,pa_sink_input * i,bool * wait)2189 static size_t GetOffloadRenderLength(struct Userdata *u, pa_sink_input *i, bool *wait)
2190 {
2191     size_t length;
2192     playback_stream *ps = i->userdata;
2193     const bool b = (bool)ps->sink_input->thread_info.resampler;
2194     const pa_sample_spec sampleSpecIn = b ? ps->sink_input->thread_info.resampler->i_ss : ps->sink_input->sample_spec;
2195     const pa_sample_spec sampleSpecOut = b ? ps->sink_input->thread_info.resampler->o_ss : ps->sink_input->sample_spec;
2196     const int statePolicy = GetInputPolicyState(i);
2197     u->offload.prewrite = (statePolicy == OFFLOAD_INACTIVE_BACKGROUND ?
2198                            OFFLOAD_HDI_CACHE2_PLUS : OFFLOAD_HDI_CACHE1_PLUS) * PA_USEC_PER_MSEC;
2199     size_t sizeFrame = pa_frame_align(pa_usec_to_bytes(OFFLOAD_FRAME_SIZE * PA_USEC_PER_MSEC, &sampleSpecOut),
2200         &sampleSpecOut);
2201     size_t tlengthHalfResamp = pa_frame_align(pa_usec_to_bytes(pa_bytes_to_usec(pa_memblockq_get_tlength(
2202         ps->memblockq) / 1.5, &sampleSpecIn), &sampleSpecOut), &sampleSpecOut); // 1.5 for half
2203     size_t sizeTgt = PA_MIN(sizeFrame, tlengthHalfResamp);
2204     const size_t bql = pa_memblockq_get_length(ps->memblockq);
2205     const size_t bqlResamp = pa_usec_to_bytes(pa_bytes_to_usec(bql, &sampleSpecIn), &sampleSpecOut);
2206     const size_t bqlRend = pa_memblockq_get_length(i->thread_info.render_memblockq);
2207     const size_t bqlAlin = pa_frame_align(bqlResamp + bqlRend, &sampleSpecOut);
2208 
2209     if (ps->drain_request) {
2210         if (i->thread_info.render_memblockq->maxrewind != 0) {
2211             pa_sink_input_update_max_rewind(i, 0);
2212         }
2213         const uint64_t hdiPos = u->offload.hdiPos + (pa_rtclock_now() - u->offload.hdiPosTs);
2214         *wait = u->offload.pos > hdiPos + HDI_MIN_MS_MAINTAIN * PA_USEC_PER_MSEC ? true : false;
2215         length = u->offload.pos > hdiPos + HDI_MIN_MS_MAINTAIN * PA_USEC_PER_MSEC ? 0 : sizeFrame;
2216     } else {
2217         bool waitable = false;
2218         const uint64_t hdiPos = u->offload.hdiPos + (pa_rtclock_now() - u->offload.hdiPosTs);
2219         if (u->offload.pos > hdiPos + 60 * PA_USEC_PER_MSEC) { // if hdi cache < 60ms, indicate no enough data
2220             // hdi left 100ms is triggered process_complete_msg, it leads to kartun. Could be stating time leads it.
2221             waitable = true;
2222         }
2223         length = PA_MIN(bqlAlin, sizeTgt);
2224         *wait = false;
2225         if (length < sizeTgt) {
2226             *wait = waitable || length == 0;
2227             length = waitable ? 0 : length;
2228             if (ps->memblockq->missing > 0) {
2229                 playback_stream_request_bytes(ps);
2230             }
2231         }
2232     }
2233     return length;
2234 }
2235 
InputsDropFromInputs2(pa_mix_info * info,unsigned n)2236 static void InputsDropFromInputs2(pa_mix_info *info, unsigned n)
2237 {
2238     for (; n > 0; info++, n--) {
2239         if (info->userdata) {
2240             pa_sink_input_unref(info->userdata);
2241             info->userdata = NULL;
2242         }
2243         if (info->chunk.memblock) {
2244             pa_memblock_unref(info->chunk.memblock);
2245         }
2246     }
2247 }
2248 
InputsDropFromInputs(pa_mix_info * infoInputs,unsigned nInputs,pa_mix_info * info,unsigned n,pa_memchunk * result)2249 static void InputsDropFromInputs(pa_mix_info *infoInputs, unsigned nInputs, pa_mix_info *info, unsigned n,
2250     pa_memchunk *result)
2251 {
2252     unsigned p = 0;
2253     unsigned ii = 0;
2254     unsigned nUnreffed = 0;
2255     pa_assert(result && result->memblock && result->length > 0);
2256     /* We optimize for the case where the order of the inputs has not changed */
2257 
2258     for (ii = 0; ii < nInputs; ++ii) {
2259         pa_sink_input *i = infoInputs[ii].userdata;
2260         unsigned j;
2261         pa_mix_info *m = NULL;
2262 
2263         pa_sink_input_assert_ref(i);
2264 
2265         /* Let's try to find the matching entyr info the pa_mix_info array */
2266         for (j = 0; j < n; j++) {
2267             if (info[p].userdata == i) {
2268                 m = info + p;
2269                 break;
2270             }
2271 
2272             p++;
2273             if (p >= n) {
2274                 p = 0;
2275             }
2276         }
2277 
2278         /* Drop read data */
2279         pa_sink_input_drop(i, result->length);
2280 
2281         if (m) {
2282             if (m->chunk.memblock) {
2283                 pa_memblock_unref(m->chunk.memblock);
2284                 pa_memchunk_reset(&m->chunk);
2285             }
2286 
2287             pa_sink_input_unref(m->userdata);
2288             m->userdata = NULL;
2289 
2290             nUnreffed += 1;
2291         }
2292     }
2293 
2294     /* Now drop references to entries that are included in the
2295      * pa_mix_info array but don't exist anymore */
2296 
2297     if (nUnreffed < n) {
2298         for (; n > 0; info++, n--) {
2299             if (info->userdata)
2300                 pa_sink_input_unref(info->userdata);
2301             if (info->chunk.memblock) {
2302                 pa_memblock_unref(info->chunk.memblock);
2303             }
2304         }
2305     }
2306 }
2307 
PaSinkRenderIntoOffload(pa_sink * s,pa_mix_info * infoInputs,unsigned nInputs,pa_memchunk * target)2308 static void PaSinkRenderIntoOffload(pa_sink *s, pa_mix_info *infoInputs, unsigned nInputs, pa_memchunk *target)
2309 {
2310     unsigned n = 0;
2311     unsigned ii = 0;
2312     pa_mix_info info[MAX_MIX_CHANNELS];
2313     pa_sink_assert_ref(s);
2314     pa_sink_assert_io_context(s);
2315 
2316     size_t length = target->length;
2317     size_t mixlength = length;
2318     size_t blockSizeMax = pa_mempool_block_size_max(s->core->mempool);
2319     if (length > blockSizeMax)
2320         length = pa_frame_align(blockSizeMax, &s->sample_spec);
2321 
2322     pa_assert(length > 0);
2323 
2324     for (ii = 0; ii < nInputs; ++ii) {
2325         pa_sink_input *i = infoInputs[ii].userdata;
2326         pa_sink_input_assert_ref(i);
2327         AUTO_CTRACE("hdi_sink::Offload:pa_sink_input_peek:%u len:%zu", i->index, length);
2328         pa_sink_input_peek(i, length, &info[n].chunk, &info[n].volume);
2329         if (mixlength == 0 || info[n].chunk.length < mixlength)
2330             mixlength = info[n].chunk.length;
2331 
2332         if (pa_memblock_is_silence(info[n].chunk.memblock)) {
2333             AUTO_CTRACE("hdi_sink::Offload::is_silence");
2334             pa_memblock_unref(info[n].chunk.memblock);
2335             continue;
2336         }
2337 
2338         info[n].userdata = pa_sink_input_ref(i);
2339 
2340         pa_assert(info[n].chunk.memblock);
2341         pa_assert(info[n].chunk.length > 0);
2342 
2343         n++;
2344     }
2345     length = mixlength > 0 ? mixlength : length;
2346 
2347     pa_assert(n == 1 || n == 0);
2348     if (n == 0) {
2349         if (target->length > length)
2350             target->length = length;
2351 
2352         pa_silence_memchunk(target, &s->sample_spec);
2353     } else if (n == 1) {
2354         if (target->length > length)
2355             target->length = length;
2356 
2357         pa_memchunk vchunk;
2358         vchunk = info[0].chunk;
2359 
2360         if (vchunk.length > length)
2361             vchunk.length = length;
2362         // if target lead pa_memblock_new memory leak, fixed chunk length can solve it.
2363         pa_memchunk_memcpy(target, &vchunk);
2364     }
2365 
2366     InputsDropFromInputs(infoInputs, nInputs, info, n, target);
2367 }
2368 
OffloadReset(struct Userdata * u)2369 static void OffloadReset(struct Userdata *u)
2370 {
2371     u->offload.sessionID = -1;
2372     u->offload.pos = 0;
2373     u->offload.hdiPos = 0;
2374     u->offload.hdiPosTs = pa_rtclock_now();
2375     u->offload.prewrite = OFFLOAD_HDI_CACHE1_PLUS * PA_USEC_PER_MSEC;
2376     u->offload.firstWriteHdi = true;
2377     u->offload.setHdiBufferSizeNum = OFFLOAD_SET_BUFFER_SIZE_NUM;
2378     pa_atomic_store(&u->offload.hdistate, 0);
2379     u->offload.fullTs = 0;
2380 }
2381 
RenderWriteOffloadFunc(struct Userdata * u,size_t length,pa_mix_info * infoInputs,unsigned nInputs,int32_t * writen)2382 static int32_t RenderWriteOffloadFunc(struct Userdata *u, size_t length, pa_mix_info *infoInputs, unsigned nInputs,
2383     int32_t *writen)
2384 {
2385     pa_sink_input *i = infoInputs[0].userdata;
2386 
2387     pa_assert(length != 0);
2388     pa_memchunk *chunk = &(u->offload.chunk);
2389     chunk->index = 0;
2390     chunk->length = length;
2391     int64_t l;
2392     int64_t d;
2393     l = (int64_t)chunk->length;
2394     size_t blockSize = pa_memblock_get_length(u->offload.chunk.memblock);
2395     blockSize = PA_MAX(blockSize, pa_usec_to_bytes(0.6 * OFFLOAD_HDI_CACHE1 * PA_USEC_PER_MSEC, // 0.6 40% is hdi limit
2396         &u->sink->sample_spec));
2397     d = 0;
2398     while (l > 0) {
2399         pa_memchunk tchunk;
2400         tchunk = *chunk;
2401         tchunk.index += (size_t)d;
2402         tchunk.length = PA_MIN((size_t)l, blockSize - tchunk.index);
2403 
2404         PaSinkRenderIntoOffload(i->sink, infoInputs, nInputs, &tchunk);
2405         d += (int64_t)tchunk.length;
2406         l -= (int64_t)tchunk.length;
2407     }
2408     if (l < 0) {
2409         chunk->length += (size_t)-l;
2410     }
2411 
2412     int32_t appsUid[MAX_MIX_CHANNELS];
2413     size_t count = 0;
2414 
2415     const char *cstringClientUid = pa_proplist_gets(i->proplist, "stream.client.uid");
2416     if (cstringClientUid && (i->thread_info.state == PA_SINK_INPUT_RUNNING)) {
2417         appsUid[count++] = atoi(cstringClientUid);
2418     }
2419 
2420     SafeRendererSinkUpdateAppsUid(u->offload.sinkAdapter, appsUid, count);
2421 
2422     int ret = RenderWriteOffload(u, i, chunk);
2423     *writen = ret == 0 ? (int32_t)chunk->length : 0;
2424     if (ret == 1) { // 1 indicates full
2425         const int hdistate = pa_atomic_load(&u->offload.hdistate);
2426         if (hdistate == 0) {
2427             pa_atomic_store(&u->offload.hdistate, 1);
2428         }
2429         if (GetInputPolicyState(i) == OFFLOAD_INACTIVE_BACKGROUND) {
2430             u->offload.fullTs = pa_rtclock_now();
2431         }
2432         pa_memblockq_rewind(i->thread_info.render_memblockq, chunk->length);
2433     } else if (ret < 0) {
2434         pa_memblockq_rewind(i->thread_info.render_memblockq, chunk->length);
2435     }
2436 
2437     u->offload.pos += pa_bytes_to_usec(*writen, &u->sink->sample_spec);
2438     InputsDropFromInputs2(infoInputs, nInputs);
2439     return ret;
2440 }
2441 
ProcessRenderUseTimingOffload(struct Userdata * u,bool * wait,int32_t * nInput,int32_t * writen)2442 static int32_t ProcessRenderUseTimingOffload(struct Userdata *u, bool *wait, int32_t *nInput, int32_t *writen)
2443 {
2444     *wait = true;
2445     pa_sink *s = u->sink;
2446     pa_mix_info infoInputs[MAX_MIX_CHANNELS];
2447     unsigned nInputs;
2448 
2449     pa_sink_assert_ref(s);
2450     pa_sink_assert_io_context(s);
2451     pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
2452 
2453     pa_assert(s->thread_info.rewind_nbytes == 0);
2454 
2455     if (s->thread_info.state == PA_SINK_SUSPENDED) {
2456         return 0;
2457     }
2458 
2459     pa_sink_ref(s);
2460 
2461     nInputs = GetInputsInfo(HDI_INPUT_TYPE_OFFLOAD, true, s, infoInputs, MAX_MIX_CHANNELS);
2462     *nInput = (int32_t)nInputs;
2463 
2464     if (nInputs == 0) {
2465         pa_sink_unref(s);
2466         return 0;
2467     } else if (nInputs > 1) {
2468         AUDIO_WARNING_LOG("GetInputsInfo offload input != 1");
2469     }
2470 
2471     pa_sink_input *i = infoInputs[0].userdata;
2472     if (GetFadeoutState(i->index) != NO_FADE) {
2473         InputsDropFromInputs2(infoInputs, nInputs);
2474         pa_sink_unref(s);
2475         AUDIO_WARNING_LOG("stream is croked, do not need peek");
2476         return 0;
2477     }
2478     CheckInputChangeToOffload(u, i);
2479     size_t length = GetOffloadRenderLength(u, i, wait);
2480     if (*wait && length == 0) {
2481         InputsDropFromInputs2(infoInputs, nInputs);
2482         AUTO_CTRACE("hdi_sink::ProcessRenderUseTimingOffload::underrun");
2483         pa_sink_input_handle_ohos_underrun(i);
2484         pa_sink_unref(s);
2485         return 0;
2486     }
2487     int ret = RenderWriteOffloadFunc(u, length, infoInputs, nInputs, writen);
2488     pa_sink_unref(s);
2489     return ret;
2490 }
2491 
UpdatePresentationPosition(struct Userdata * u)2492 static int32_t UpdatePresentationPosition(struct Userdata *u)
2493 {
2494     uint64_t frames;
2495     int64_t timeSec;
2496     int64_t timeNanoSec;
2497     int ret = u->offload.sinkAdapter->RendererSinkGetPresentationPosition(
2498         u->offload.sinkAdapter, &frames, &timeSec, &timeNanoSec);
2499     if (ret != 0) {
2500         AUDIO_ERR_LOG("RendererSinkGetPresentationPosition fail, ret %d", ret);
2501         return ret;
2502     }
2503     u->offload.hdiPos = frames;
2504     u->offload.hdiPosTs = (uint64_t)timeSec * USEC_PER_SEC + (uint64_t)timeNanoSec / PA_NSEC_PER_USEC;
2505     return 0;
2506 }
2507 
OffloadRewindAndFlush(struct Userdata * u,pa_sink_input * i,bool afterRender)2508 static void OffloadRewindAndFlush(struct Userdata *u, pa_sink_input *i, bool afterRender)
2509 {
2510     pa_sink_input_assert_ref(i);
2511     playback_stream *ps = i->userdata;
2512     pa_assert(ps);
2513 
2514     OffloadLock(u); // flush will interrupt the offload callback, may be offload unlock.
2515     int ret = UpdatePresentationPosition(u);
2516     u->offload.sinkAdapter->RendererSinkFlush(u->offload.sinkAdapter);
2517     if (ret == 0) {
2518         uint64_t offloadFade = 180000; // 180000 us fade out
2519         uint64_t cacheLenInHdi =
2520             u->offload.pos > u->offload.hdiPos + offloadFade ? u->offload.pos - u->offload.hdiPos - offloadFade : 0;
2521         uint64_t bufSizeInRender = pa_usec_to_bytes(cacheLenInHdi, &i->sink->sample_spec);
2522         const pa_sample_spec sampleSpecIn = i->thread_info.resampler ? i->thread_info.resampler->i_ss
2523                                                                      : i->sample_spec;
2524         uint64_t bufSizeInInput = pa_usec_to_bytes(cacheLenInHdi, &sampleSpecIn);
2525         bufSizeInInput += pa_usec_to_bytes(pa_bytes_to_usec(
2526             pa_memblockq_get_length(i->thread_info.render_memblockq), &i->sink->sample_spec), &sampleSpecIn);
2527         uint64_t rewindSize = afterRender ? bufSizeInRender : bufSizeInInput;
2528         uint64_t maxRewind = afterRender ? i->thread_info.render_memblockq->maxrewind : ps->memblockq->maxrewind;
2529         if (rewindSize > maxRewind) {
2530             AUDIO_WARNING_LOG("OffloadRewindAndFlush, rewindSize(%" PRIu64 ") > maxrewind(%u), afterRender(%d)",
2531                 rewindSize, (uint32_t)(afterRender ? i->thread_info.render_memblockq->maxrewind :
2532                                         ps->memblockq->maxrewind), afterRender);
2533             rewindSize = maxRewind;
2534         }
2535 
2536         if (afterRender) {
2537             pa_memblockq_rewind(i->thread_info.render_memblockq, rewindSize);
2538         } else {
2539             pa_memblockq_rewind(ps->memblockq, rewindSize);
2540             pa_memblockq_flush_read(i->thread_info.render_memblockq);
2541         }
2542     }
2543     OffloadReset(u);
2544 }
2545 
GetSinkInputName(pa_sink_input * i,char * str,int len)2546 static void GetSinkInputName(pa_sink_input *i, char *str, int len)
2547 {
2548     const char *streamUid = safeProplistGets(i->proplist, "stream.client.uid", "NULL");
2549     const char *streamPid = safeProplistGets(i->proplist, "stream.client.pid", "NULL");
2550     const char *streamType = safeProplistGets(i->proplist, "stream.type", "NULL");
2551     const char *sessionID = safeProplistGets(i->proplist, "stream.sessionID", "NULL");
2552     int ret = sprintf_s(str, len, "%s_%s_%s_%s_of%d", streamType, streamUid, streamPid, sessionID, InputIsOffload(i));
2553     if (ret < 0) {
2554         AUDIO_ERR_LOG("sprintf_s fail! ret %d", ret);
2555     }
2556 }
2557 
getSinkInputSessionID(pa_sink_input * i)2558 static int32_t getSinkInputSessionID(pa_sink_input *i)
2559 {
2560     const char *res = pa_proplist_gets(i->proplist, "stream.sessionID");
2561     if (res == NULL) {
2562         return -1;
2563     } else {
2564         return atoi(res);
2565     }
2566 }
2567 
OffloadLock(struct Userdata * u)2568 static void OffloadLock(struct Userdata *u)
2569 {
2570     if (!u->offload.runninglocked) {
2571         u->offload.sinkAdapter->RendererSinkOffloadRunningLockLock(u->offload.sinkAdapter);
2572         u->offload.runninglocked = true;
2573     } else {
2574     }
2575 }
2576 
OffloadUnlock(struct Userdata * u)2577 static void OffloadUnlock(struct Userdata *u)
2578 {
2579     if (u->offload.runninglocked) {
2580         u->offload.sinkAdapter->RendererSinkOffloadRunningLockUnlock(u->offload.sinkAdapter);
2581         u->offload.runninglocked = false;
2582     } else {
2583     }
2584 }
2585 
offloadSetMaxRewind(struct Userdata * u,pa_sink_input * i)2586 static void offloadSetMaxRewind(struct Userdata *u, pa_sink_input *i)
2587 {
2588     pa_sink_input_assert_ref(i);
2589     pa_sink_input_assert_io_context(i);
2590     pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
2591 
2592     size_t blockSize = pa_memblock_get_length(u->offload.chunk.memblock);
2593     pa_memblockq_set_maxrewind(i->thread_info.render_memblockq, blockSize);
2594 
2595     size_t nbytes = pa_usec_to_bytes(MAX_REWIND, &i->sink->sample_spec);
2596 
2597     if (i->update_max_rewind) {
2598         i->update_max_rewind(i, i->thread_info.resampler ?
2599                                 pa_resampler_request(i->thread_info.resampler, nbytes) : nbytes);
2600     }
2601 }
2602 
CheckInputChangeToOffload(struct Userdata * u,pa_sink_input * i)2603 static void CheckInputChangeToOffload(struct Userdata *u, pa_sink_input *i)
2604 {
2605     // if maxrewind is set to buffer_size while inner-cap, reset it to 0 for offload.
2606     if (pa_memblockq_get_maxrewind(i->thread_info.render_memblockq) == u->buffer_size) {
2607         AUDIO_INFO_LOG("Reset maxwind to 0 to enable offload for sink-input:%{public}u", i->index);
2608         pa_sink_input_update_max_rewind(i, 0);
2609     }
2610     if (InputIsOffload(i) && pa_memblockq_get_maxrewind(i->thread_info.render_memblockq) == 0) {
2611         offloadSetMaxRewind(u, i);
2612         pa_sink_input *it;
2613         void *state = NULL;
2614         while ((it = pa_hashmap_iterate(u->sink->thread_info.inputs, &state, NULL))) {
2615             if (it != i && pa_memblockq_get_maxrewind(it->thread_info.render_memblockq) != 0) {
2616                 pa_sink_input_update_max_rewind(it, 0);
2617                 drop_backlog(it->thread_info.render_memblockq);
2618                 playback_stream *ps = it->userdata;
2619                 drop_backlog(ps->memblockq);
2620             }
2621         }
2622     }
2623 }
2624 
StartOffloadHdi(struct Userdata * u,pa_sink_input * i)2625 static void StartOffloadHdi(struct Userdata *u, pa_sink_input *i)
2626 {
2627     CheckInputChangeToOffload(u, i);
2628     int32_t sessionID = getSinkInputSessionID(i);
2629     if (u->offload.isHDISinkStarted) {
2630         AUDIO_INFO_LOG("StartOffloadHdi, sessionID : %{public}d -> %{public}d", u->offload.sessionID, sessionID);
2631         if (sessionID != u->offload.sessionID) {
2632             if (u->offload.sessionID != -1) {
2633                 u->offload.sinkAdapter->RendererSinkReset(u->offload.sinkAdapter);
2634                 OffloadReset(u);
2635             }
2636             u->offload.sessionID = sessionID;
2637         }
2638         OffloadLock(u);
2639     } else {
2640         AUDIO_INFO_LOG("StartOffloadHdi, Restart offload with rate:%{public}d, channels:%{public}d",
2641             u->ss.rate, u->ss.channels);
2642         if (u->offload.sinkAdapter->RendererSinkStart(u->offload.sinkAdapter)) {
2643             AUDIO_WARNING_LOG("StartOffloadHdi, audiorenderer control start failed!");
2644         } else {
2645             RegOffloadCallback(u);
2646             u->offload.isHDISinkStarted = true;
2647             AUDIO_INFO_LOG("StartOffloadHdi, Successfully restarted offload HDI renderer");
2648             OffloadLock(u);
2649             u->offload.sessionID = sessionID;
2650             OffloadSetHdiVolume(i);
2651         }
2652     }
2653 }
2654 
PaInputStateChangeCbOffload(struct Userdata * u,pa_sink_input * i,pa_sink_input_state_t state)2655 static void POSSIBLY_UNUSED PaInputStateChangeCbOffload(struct Userdata *u, pa_sink_input *i,
2656     pa_sink_input_state_t state)
2657 {
2658     const bool corking = i->thread_info.state == PA_SINK_INPUT_RUNNING && state == PA_SINK_INPUT_CORKED;
2659     const bool starting = i->thread_info.state == PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_RUNNING;
2660     const bool stopping = state == PA_SINK_INPUT_UNLINKED;
2661 
2662     if (!u->offload.inited && PrepareDeviceOffload(u) == 0) {
2663         u->offload.inited = true;
2664     }
2665     if (starting) {
2666         StartOffloadHdi(u, i);
2667     } else if (corking) {
2668         pa_atomic_store(&u->offload.hdistate, 2); // 2 indicates corking
2669         OffloadRewindAndFlush(u, i, false);
2670     } else if (stopping) {
2671         u->offload.sinkAdapter->RendererSinkFlush(u->offload.sinkAdapter);
2672         OffloadReset(u);
2673         g_speakerPaAllStreamStartVolZeroTime = 0;
2674     }
2675     ResetVolumeBySinkInputState(i, state);
2676 }
2677 
ResetVolumeBySinkInputState(pa_sink_input * i,pa_sink_input_state_t state)2678 static void ResetVolumeBySinkInputState(pa_sink_input *i, pa_sink_input_state_t state)
2679 {
2680     pa_assert(i);
2681     const bool corking = i->thread_info.state == PA_SINK_INPUT_RUNNING && state == PA_SINK_INPUT_CORKED;
2682     if (corking) {
2683         const char *sessionIDStr = safeProplistGets(i->proplist, "stream.sessionID", "NULL");
2684         uint32_t sessionID = sessionIDStr != NULL ? atoi(sessionIDStr) : 0;
2685         SetPreVolume(sessionID, 0.0f);
2686     }
2687 }
2688 
2689 // call from IO thread(OS_ProcessData)
PaInputStateChangeCbPrimary(struct Userdata * u,pa_sink_input * i,pa_sink_input_state_t state)2690 static void PaInputStateChangeCbPrimary(struct Userdata *u, pa_sink_input *i, pa_sink_input_state_t state)
2691 {
2692     const bool starting = i->thread_info.state == PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_RUNNING;
2693     const bool corking = i->thread_info.state == PA_SINK_INPUT_RUNNING && state == PA_SINK_INPUT_CORKED;
2694     uint32_t streamIndex = i->index;
2695     if (corking) {
2696         SetFadeoutState(streamIndex, NO_FADE);
2697     }
2698 
2699     if (starting) {
2700         u->primary.timestamp = pa_rtclock_now();
2701         if (pa_atomic_load(&u->primary.isHDISinkStarted) == 1) {
2702             pa_atomic_store(&u->primary.fadingFlagForPrimary, 1);
2703             AUDIO_INFO_LOG("store fadingFlagForPrimary for 1");
2704             SetFadeoutState(streamIndex, NO_FADE);
2705             u->primary.primaryFadingInDone = 0;
2706             u->primary.primarySinkInIndex = (int32_t)(i->index);
2707             AUDIO_INFO_LOG("PaInputStateChangeCb, HDI renderer already started");
2708             return;
2709         }
2710         AUDIO_INFO_LOG("PaInputStateChangeCb, Restart with rate:%{public}d,channels:%{public}d, format:%{public}d",
2711             u->ss.rate, u->ss.channels, (int)pa_sample_size_of_format(u->format));
2712         if (pa_asyncmsgq_send(u->primary.dq, NULL, HDI_START, NULL, 0, NULL)) {
2713             AUDIO_ERR_LOG("audiorenderer control start failed!");
2714             u->primary.sinkAdapter->RendererSinkDeInit(u->primary.sinkAdapter);
2715         } else {
2716             pa_atomic_store(&u->primary.isHDISinkStarted, 1);
2717             u->writeCount = 0;
2718             u->renderCount = 0;
2719             pa_atomic_store(&u->primary.fadingFlagForPrimary, 1);
2720             AUDIO_INFO_LOG("store fadingFlagForPrimary for 1");
2721             SetFadeoutState(streamIndex, NO_FADE);
2722             u->primary.primaryFadingInDone = 0;
2723             u->primary.primarySinkInIndex = (int32_t)(i->index);
2724             AUDIO_INFO_LOG("PaInputStateChangeCb, Successfully restarted HDI renderer");
2725         }
2726     }
2727     ResetVolumeBySinkInputState(i, state);
2728 }
2729 
2730 // call from IO thread(OS_ProcessData)
StartPrimaryHdiIfRunning(struct Userdata * u)2731 static void StartPrimaryHdiIfRunning(struct Userdata *u)
2732 {
2733     AUTO_CTRACE("hdi_sink::StartPrimaryHdiIfRunning");
2734     if (pa_atomic_load(&u->primary.isHDISinkStarted) == 1) {
2735         return;
2736     }
2737 
2738     unsigned nPrimary = 0;
2739     unsigned nOffload = 0;
2740     unsigned nMultiChannel = 0;
2741     GetInputsType(u->sink, &nPrimary, &nOffload, &nMultiChannel, true);
2742     if (nPrimary == 0) {
2743         return;
2744     }
2745 
2746     if (pa_asyncmsgq_send(u->primary.dq, NULL, HDI_START, NULL, 0, NULL)) {
2747         AUDIO_ERR_LOG("audiorenderer control start failed!");
2748         u->primary.sinkAdapter->RendererSinkDeInit(u->primary.sinkAdapter);
2749     } else {
2750         pa_atomic_store(&u->primary.isHDISinkStarted, 1);
2751         u->writeCount = 0;
2752         u->renderCount = 0;
2753         AUDIO_INFO_LOG("StartPrimaryHdiIfRunning, Successfully restarted HDI renderer");
2754     }
2755 }
2756 
ResetMultiChannelHdiState(struct Userdata * u)2757 static void ResetMultiChannelHdiState(struct Userdata *u)
2758 {
2759     if (u->multiChannel.sinkAdapter == NULL) {
2760         return;
2761     }
2762     if (u->multiChannel.isHDISinkInited) {
2763         if (u->multiChannel.sample_attrs.channel != (uint32_t)u->multiChannel.sinkChannel) {
2764             u->multiChannel.sinkAdapter->RendererSinkStop(u->multiChannel.sinkAdapter);
2765             u->multiChannel.isHDISinkStarted = false;
2766             u->multiChannel.sinkAdapter->RendererSinkDeInit(u->multiChannel.sinkAdapter);
2767             u->multiChannel.isHDISinkInited = false;
2768             u->multiChannel.sample_attrs.adapterName = "primary";
2769             u->multiChannel.sample_attrs.channel = (uint32_t)u->multiChannel.sinkChannel;
2770             u->multiChannel.sample_attrs.channelLayout = u->multiChannel.sinkChannelLayout;
2771             u->multiChannel.sinkAdapter->RendererSinkInit(u->multiChannel.sinkAdapter, &u->multiChannel.sample_attrs);
2772             u->multiChannel.isHDISinkInited = true;
2773         } else {
2774             if (u->multiChannel.isHDISinkStarted) {
2775                 pa_atomic_store(&u->multiChannel.fadingFlagForMultiChannel, 1);
2776                 u->multiChannel.multiChannelFadingInDone = 0;
2777                 u->multiChannel.multiChannelSinkInIndex = u->multiChannel.multiChannelTmpSinkInIndex;
2778                 return;
2779             }
2780         }
2781     } else {
2782         u->multiChannel.sample_attrs.adapterName = "primary";
2783         u->multiChannel.sample_attrs.channel = (uint32_t)u->multiChannel.sinkChannel;
2784         u->multiChannel.sample_attrs.channelLayout = u->multiChannel.sinkChannelLayout;
2785         u->multiChannel.sinkAdapter->RendererSinkInit(u->multiChannel.sinkAdapter, &u->multiChannel.sample_attrs);
2786         u->multiChannel.isHDISinkInited = true;
2787     }
2788     if (u->multiChannel.sinkAdapter->RendererSinkStart(u->multiChannel.sinkAdapter)) {
2789         u->multiChannel.isHDISinkStarted = false;
2790         u->multiChannel.sinkAdapter->RendererSinkDeInit(u->multiChannel.sinkAdapter);
2791         u->multiChannel.isHDISinkInited = false;
2792         AUDIO_INFO_LOG("ResetMultiChannelHdiState deinit success");
2793     } else {
2794         u->multiChannel.isHDISinkStarted = true;
2795         AUDIO_INFO_LOG("ResetMultiChannelHdiState start success");
2796         u->writeCount = 0;
2797         u->renderCount = 0;
2798         pa_atomic_store(&u->multiChannel.fadingFlagForMultiChannel, 1);
2799         u->multiChannel.multiChannelFadingInDone = 0;
2800         u->multiChannel.multiChannelSinkInIndex = u->multiChannel.multiChannelTmpSinkInIndex;
2801     }
2802 }
2803 
StartMultiChannelHdiIfRunning(struct Userdata * u)2804 static void StartMultiChannelHdiIfRunning(struct Userdata *u)
2805 {
2806     ResetMultiChannelHdiState(u);
2807 }
2808 
PaInputStateChangeCbMultiChannel(struct Userdata * u,pa_sink_input * i,pa_sink_input_state_t state)2809 static void PaInputStateChangeCbMultiChannel(struct Userdata *u, pa_sink_input *i, pa_sink_input_state_t state)
2810 {
2811     const bool corking = i->thread_info.state == PA_SINK_INPUT_RUNNING && state == PA_SINK_INPUT_CORKED;
2812     const bool starting = i->thread_info.state == PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_RUNNING;
2813     const bool stopping = state == PA_SINK_INPUT_UNLINKED;
2814     if (corking) {
2815         SetFadeoutState(i->index, NO_FADE);
2816     }
2817     if (starting) {
2818         u->multiChannel.timestamp = pa_rtclock_now();
2819         u->multiChannel.multiChannelTmpSinkInIndex = (int32_t)(i->index);
2820     } else if (stopping) {
2821         // Continuously dropping data clear counter on entering suspended state.
2822         if (u->bytes_dropped != 0) {
2823             AUDIO_INFO_LOG("PaInputStateChangeCbMultiChannel, HDI-sink continuously dropping data - clear statistics "
2824                            "(%zu -> 0 bytes dropped)", u->bytes_dropped);
2825             u->bytes_dropped = 0;
2826         }
2827         g_speakerPaAllStreamStartVolZeroTime = 0;
2828     }
2829     ResetVolumeBySinkInputState(i, state);
2830 }
2831 
ResetFadeoutPause(pa_sink_input * i,pa_sink_input_state_t state)2832 static void ResetFadeoutPause(pa_sink_input *i, pa_sink_input_state_t state)
2833 {
2834     bool corking = i->thread_info.state == PA_SINK_INPUT_RUNNING && state == PA_SINK_INPUT_CORKED;
2835     bool starting = i->thread_info.state == PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_RUNNING;
2836     if (corking || starting) {
2837         AUDIO_INFO_LOG("set fadeoutPause to 0");
2838         SetFadeoutState(i->index, NO_FADE);
2839     }
2840 }
2841 
RendererSinkSetPriPaPower(pa_sink_input * i,pa_sink_input_state_t state,struct Userdata * u)2842 static void RendererSinkSetPriPaPower(pa_sink_input *i, pa_sink_input_state_t state, struct Userdata *u)
2843 {
2844     if (state == PA_SINK_INPUT_RUNNING) {
2845         if (u->primary.sinkAdapter == NULL) {
2846             return;
2847         }
2848         const char *streamType = safeProplistGets(i->proplist, "stream.type", "NULL");
2849         const char *sessionIDStr = safeProplistGets(i->proplist, "stream.sessionID", "NULL");
2850         const char *deviceClass = GetDeviceClass(u->primary.sinkAdapter->deviceClass);
2851         uint32_t sessionID = sessionIDStr != NULL ? (uint32_t)atoi(sessionIDStr) : 0;
2852         float volume = GetCurVolume(sessionID, streamType, deviceClass);
2853         bool isZeroVolume = IsSameVolume(volume, 0.0f);
2854         AUDIO_INFO_LOG(
2855             "session %{public}u, stream %{public}s, zerovol %{public}d", sessionID, streamType, isZeroVolume);
2856         if (!isZeroVolume) {
2857             u->primary.sinkAdapter->RendererSinkSetPriPaPower(u->primary.sinkAdapter);
2858         }
2859     }
2860 }
2861 
PaInputStateChangeCb(pa_sink_input * i,pa_sink_input_state_t state)2862 static void PaInputStateChangeCb(pa_sink_input *i, pa_sink_input_state_t state)
2863 {
2864     struct Userdata *u = NULL;
2865 
2866     pa_assert(i);
2867     pa_sink_input_assert_ref(i);
2868     pa_assert(i->sink);
2869 
2870     const bool corking = i->thread_info.state == PA_SINK_INPUT_RUNNING && state == PA_SINK_INPUT_CORKED;
2871     const bool starting = i->thread_info.state == PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_RUNNING;
2872     const bool stopping = state == PA_SINK_INPUT_UNLINKED;
2873 
2874     corking ? pa_atomic_store(&i->isFirstReaded, 0) : (void)0;
2875     starting ? pa_atomic_store(&i->isFirstReaded, 1) : (void)0;
2876 
2877     if (!strcmp(i->sink->name, SINK_NAME_INNER_CAPTURER) ||
2878         !strcmp(i->sink->name, SINK_NAME_REMOTE_CAST_INNER_CAPTURER) ||
2879         !strcmp(i->sink->driver, "module_split_stream_sink.c")) {
2880         ResetFadeoutPause(i, state);
2881         AUDIO_INFO_LOG("PaInputStateChangeCb inner_cap return");
2882         return;
2883     }
2884     pa_assert_se(u = i->sink->userdata);
2885 
2886     RendererSinkSetPriPaPower(i, state, u);
2887 
2888     char str[SPRINTF_STR_LEN] = {0};
2889     GetSinkInputName(i, str, SPRINTF_STR_LEN);
2890     AUDIO_INFO_LOG(
2891         "PaInputStateChangeCb, Sink[%{public}s]->SinkInput[%{public}s] state change:[%{public}s]-->[%{public}s]",
2892         GetDeviceClass(u->primary.sinkAdapter->deviceClass), str, GetInputStateInfo(i->thread_info.state),
2893         GetInputStateInfo(state));
2894 
2895     if (i->thread_info.state == state) {
2896         return;
2897     }
2898 
2899     if (!corking && !starting && !stopping) {
2900         AUDIO_WARNING_LOG("PaInputStateChangeCb, input state change: invalid");
2901         return;
2902     }
2903 
2904     if (u->offload_enable && !strcmp(i->sink->name, OFFLOAD_SINK_NAME)) {
2905         ResetFadeoutPause(i, state);
2906         PaInputStateChangeCbOffload(u, i, state);
2907     } else if (u->multichannel_enable && !strcmp(i->sink->name, MCH_SINK_NAME)) {
2908         PaInputStateChangeCbMultiChannel(u, i, state);
2909     } else {
2910         PaInputStateChangeCbPrimary(u, i, state);
2911     }
2912 }
2913 
ThreadFuncRendererTimerOffloadProcess(struct Userdata * u,pa_usec_t now,int64_t * sleepForUsec)2914 static void ThreadFuncRendererTimerOffloadProcess(struct Userdata *u, pa_usec_t now, int64_t *sleepForUsec)
2915 {
2916     static uint32_t timeWait = 1; // 1ms init
2917     const uint64_t pos = u->offload.pos;
2918     const uint64_t hdiPos = u->offload.hdiPos + (pa_rtclock_now() - u->offload.hdiPosTs);
2919     const uint64_t pw = u->offload.prewrite;
2920     int64_t blockTime = (int64_t)pa_bytes_to_usec(u->sink->thread_info.max_request, &u->sink->sample_spec);
2921 
2922     int32_t nInput = -1;
2923     const int hdistate = (int)pa_atomic_load(&u->offload.hdistate);
2924     if (pos <= hdiPos + pw && hdistate == 0) {
2925         bool wait;
2926         int32_t writen = -1;
2927         int ret = ProcessRenderUseTimingOffload(u, &wait, &nInput, &writen);
2928         if (ret < 0) {
2929             blockTime = 20 * PA_USEC_PER_MSEC; // 20ms for render write error
2930         } else if (wait) {
2931             blockTime = (int64_t)(timeWait * PA_USEC_PER_MSEC); // timeWait ms for first write no data
2932             if (timeWait < 20) { // 20ms max wait no data
2933                 timeWait++;
2934             }
2935         } else {
2936             timeWait = 1; // 1ms have data reset timeWait
2937             blockTime = 1 * PA_USEC_PER_MSEC; // 1ms for min wait
2938         }
2939     } else if (hdistate == 1) {
2940         blockTime = (int64_t)(pos - hdiPos - HDI_MIN_MS_MAINTAIN * PA_USEC_PER_MSEC);
2941         if (blockTime < 0) {
2942             blockTime = OFFLOAD_FRAME_SIZE * PA_USEC_PER_MSEC; // block for one frame
2943         }
2944     }
2945     if (pos < hdiPos) {
2946         if (pos != 0) {
2947             AUDIO_DEBUG_LOG("ThreadFuncRendererTimerOffload hdiPos wrong need sync, pos %" PRIu64 ", hdiPos %" PRIu64,
2948                 pos, hdiPos);
2949         }
2950         if (u->offload.hdiPosTs + 300 * PA_USEC_PER_MSEC < now) { // 300ms for update pos
2951             UpdatePresentationPosition(u);
2952         }
2953     }
2954     if (blockTime != -1) {
2955         *sleepForUsec = PA_MAX(blockTime, 0) - (int64_t)(pa_rtclock_now() - now);
2956         *sleepForUsec = PA_MAX(*sleepForUsec, 0);
2957     }
2958 }
2959 
ThreadFuncRendererTimerOffloadFlag(struct Userdata * u,pa_usec_t now,bool * flagOut,int64_t * sleepForUsec)2960 static void ThreadFuncRendererTimerOffloadFlag(struct Userdata *u, pa_usec_t now, bool *flagOut, int64_t *sleepForUsec)
2961 {
2962     bool flag = PA_SINK_IS_RUNNING(u->sink->thread_info.state);
2963     if (!flag && !PA_SINK_IS_OPENED(u->sink->thread_info.state)) {
2964         OffloadUnlock(u);
2965     }
2966     *flagOut = flag;
2967 }
2968 
SinkRenderMultiChannelProcess(pa_sink * si,size_t length,pa_memchunk * chunkIn)2969 static void SinkRenderMultiChannelProcess(pa_sink *si, size_t length, pa_memchunk *chunkIn)
2970 {
2971     struct Userdata *u;
2972     pa_assert_se(u = si->userdata);
2973 
2974     EffectChainManagerReturnMultiChannelInfo(&u->multiChannel.sinkChannel, &u->multiChannel.sinkChannelLayout);
2975 
2976     chunkIn->memblock = pa_memblock_new(si->core->mempool, length * IN_CHANNEL_NUM_MAX / DEFAULT_IN_CHANNEL_NUM);
2977     size_t tmpLength = length * u->multiChannel.sinkChannel / DEFAULT_IN_CHANNEL_NUM;
2978     chunkIn->index = 0;
2979     chunkIn->length = tmpLength;
2980     SinkRenderMultiChannelGetData(si, chunkIn);
2981     chunkIn->index = 0;
2982     chunkIn->length = tmpLength;
2983 }
2984 
SinkRenderMultiChannel(pa_sink * si,size_t length,pa_memchunk * chunkIn)2985 static void SinkRenderMultiChannel(pa_sink *si, size_t length, pa_memchunk *chunkIn)
2986 {
2987     pa_sink_ref(si);
2988 
2989     size_t blockSizeMax;
2990 
2991     pa_sink_assert_ref(si);
2992     pa_sink_assert_io_context(si);
2993     pa_assert(PA_SINK_IS_LINKED(si->thread_info.state));
2994     pa_assert(length > 0);
2995     pa_assert(pa_frame_aligned(length, &si->sample_spec));
2996     pa_assert(chunkIn);
2997 
2998     pa_assert(!si->thread_info.rewind_requested);
2999     pa_assert(si->thread_info.rewind_nbytes == 0);
3000 
3001     if (si->thread_info.state == PA_SINK_SUSPENDED) {
3002         chunkIn->memblock = pa_memblock_ref(si->silence.memblock);
3003         chunkIn->index = si->silence.index;
3004         chunkIn->length = PA_MIN(si->silence.length, length);
3005         return;
3006     }
3007 
3008     if (length == 0)
3009         length = pa_frame_align(MIX_BUFFER_LENGTH, &si->sample_spec);
3010 
3011     blockSizeMax = pa_mempool_block_size_max(si->core->mempool);
3012     if (length > blockSizeMax)
3013         length = pa_frame_align(blockSizeMax, &si->sample_spec);
3014 
3015     pa_assert(length > 0);
3016 
3017     SinkRenderMultiChannelProcess(si, length, chunkIn);
3018 
3019     pa_sink_unref(si);
3020 }
3021 
ProcessRenderUseTimingMultiChannel(struct Userdata * u,pa_usec_t now)3022 static void ProcessRenderUseTimingMultiChannel(struct Userdata *u, pa_usec_t now)
3023 {
3024     pa_assert(u);
3025 
3026     // Fill the buffer up the latency size
3027     pa_memchunk chunk;
3028 
3029     // Change from pa_sink_render to pa_sink_render_full for alignment issue in 3516
3030     SinkRenderMultiChannel(u->sink, u->sink->thread_info.max_request, &chunk);
3031     pa_assert(chunk.length > 0);
3032 
3033     StartMultiChannelHdiIfRunning(u);
3034 
3035     if (!chunk.memblock) {
3036         if (pa_atomic_load(&u->multiChannel.dflag) == 1) {
3037             pa_atomic_sub(&u->multiChannel.dflag, 1);
3038         }
3039         return;
3040     }
3041     pa_asyncmsgq_post(u->multiChannel.dq, NULL, HDI_RENDER, NULL, 0, &chunk, NULL);
3042     u->multiChannel.timestamp += pa_bytes_to_usec(u->sink->thread_info.max_request, &u->sink->sample_spec);
3043 }
3044 
ThreadFuncRendererTimerMultiChannelFlagJudge(struct Userdata * u)3045 static bool POSSIBLY_UNUSED ThreadFuncRendererTimerMultiChannelFlagJudge(struct Userdata *u)
3046 {
3047     pa_assert(u);
3048     bool flag = (u->render_in_idle_state && PA_SINK_IS_OPENED(u->sink->thread_info.state)) ||
3049         (!u->render_in_idle_state && PA_SINK_IS_RUNNING(u->sink->thread_info.state)) ||
3050         (u->sink->thread_info.state == PA_SINK_IDLE && u->sink->monitor_source &&
3051         PA_SOURCE_IS_RUNNING(u->sink->monitor_source->thread_info.state));
3052     pa_sink_input *i;
3053     void *state = NULL;
3054     int nMultiChannel = 0;
3055     while ((i = pa_hashmap_iterate(u->sink->thread_info.inputs, &state, NULL))) {
3056         pa_sink_input_assert_ref(i);
3057         if (InputIsMultiChannel(i)) {
3058             nMultiChannel++;
3059         }
3060     }
3061     flag &= nMultiChannel > 0;
3062     return flag;
3063 }
3064 
ProcessNormalData(struct Userdata * u)3065 static void ProcessNormalData(struct Userdata *u)
3066 {
3067     AUTO_CTRACE("ProcessNormalData");
3068     int64_t sleepForUsec = -1;
3069     pa_usec_t now = 0;
3070 
3071     if (u->sink->thread_info.state == PA_SINK_SUSPENDED && u->isEffectBufferAllocated == true) {
3072         FreeEffectBuffer(u);
3073         u->isEffectBufferAllocated = false;
3074     }
3075 
3076     bool flag = (((u->render_in_idle_state && PA_SINK_IS_OPENED(u->sink->thread_info.state)) ||
3077                 (!u->render_in_idle_state && PA_SINK_IS_RUNNING(u->sink->thread_info.state))) &&
3078                 !(u->sink->thread_info.state == PA_SINK_IDLE && u->primary.previousState == PA_SINK_SUSPENDED) &&
3079                 !(u->sink->thread_info.state == PA_SINK_IDLE && u->primary.previousState == PA_SINK_INIT)) ||
3080                 (u->sink->thread_info.state == PA_SINK_IDLE && monitorLinked(u->sink, true));
3081     if (flag) {
3082         now = pa_rtclock_now();
3083     }
3084 
3085     if (PA_UNLIKELY(u->sink->thread_info.rewind_requested)) {
3086         pa_sink_process_rewind(u->sink, 0);
3087     }
3088 
3089     if (flag) {
3090         pa_usec_t frameUsec = pa_bytes_to_usec(u->sink->thread_info.max_request, &u->sink->sample_spec);
3091         pa_usec_t blockTime = u->primary.timestamp + frameUsec - now;
3092         if (blockTime > frameUsec) { blockTime = frameUsec; }
3093         if (pa_atomic_load(&u->primary.dflag) == 1) {
3094             sleepForUsec = (int64_t)blockTime -
3095                 ((int64_t)pa_rtclock_now() - (int64_t)(u->primary.lastProcessDataTime));
3096             if (sleepForUsec < MIN_SLEEP_FOR_USEC) {
3097                 sleepForUsec = MIN_SLEEP_FOR_USEC;
3098             }
3099         } else {
3100             if (u->primary.timestamp <= now + u->primary.prewrite || !strcmp(u->sink->name, DP_SINK_NAME)) {
3101                 pa_atomic_add(&u->primary.dflag, 1);
3102                 u->primary.lastProcessDataTime = pa_rtclock_now();
3103                 ProcessRenderUseTiming(u, now);
3104             }
3105             sleepForUsec = (int64_t)blockTime - ((int64_t)pa_rtclock_now() - (int64_t)now);
3106             if (u->primary.timestamp <= now + u->primary.prewrite) {
3107                 sleepForUsec = PA_MIN(sleepForUsec, (int64_t)u->primary.writeTime);
3108             }
3109         }
3110         sleepForUsec = PA_MAX(sleepForUsec, 0);
3111     }
3112 
3113     if (sleepForUsec != -1) {
3114         if (u->timestampSleep == -1) {
3115             u->timestampSleep = (int64_t)pa_rtclock_now() + sleepForUsec;
3116         } else {
3117             u->timestampSleep = PA_MIN(u->timestampSleep, (int64_t)pa_rtclock_now() + sleepForUsec);
3118         }
3119     }
3120 }
3121 
ProcessMCHData(struct Userdata * u)3122 static void ProcessMCHData(struct Userdata *u)
3123 {
3124     AUTO_CTRACE("ProcessMCHData");
3125     const uint64_t pw = u->multiChannel.prewrite;
3126 
3127     pa_usec_t now = 0;
3128 
3129     int64_t sleepForUsec = -1;
3130 
3131     now = pa_rtclock_now();
3132 
3133     if (PA_UNLIKELY(u->sink->thread_info.rewind_requested)) {
3134         pa_sink_process_rewind(u->sink, 0);
3135     }
3136 
3137     if (!ThreadFuncRendererTimerMultiChannelFlagJudge(u)) {
3138         return;
3139     }
3140 
3141     if (u->multiChannel.timestamp <= now + pw && pa_atomic_load(&u->multiChannel.dflag) == 0) {
3142         pa_atomic_add(&u->multiChannel.dflag, 1);
3143         ProcessRenderUseTimingMultiChannel(u, now);
3144     }
3145     pa_usec_t blockTime = pa_bytes_to_usec(u->sink->thread_info.max_request, &u->sink->sample_spec);
3146     sleepForUsec = PA_MIN((int64_t)blockTime - ((int64_t)pa_rtclock_now() - (int64_t)now),
3147         (int64_t)(u->multiChannel.writeTime));
3148     sleepForUsec = PA_MAX(sleepForUsec, 0);
3149     if (sleepForUsec != -1) {
3150         if (u->timestampSleep == -1) {
3151             u->timestampSleep = (int64_t)pa_rtclock_now() + sleepForUsec;
3152         } else {
3153             u->timestampSleep = PA_MIN(u->timestampSleep, (int64_t)pa_rtclock_now() + sleepForUsec);
3154         }
3155     }
3156 }
3157 
ProcessOffloadData(struct Userdata * u)3158 static void ProcessOffloadData(struct Userdata *u)
3159 {
3160     AUTO_CTRACE("ProcessOffloadData");
3161     pa_usec_t now = pa_rtclock_now();
3162     int64_t sleepForUsec = -1;
3163     bool flag;
3164     ThreadFuncRendererTimerOffloadFlag(u, now, &flag, &sleepForUsec);
3165 
3166     if (flag) {
3167         ThreadFuncRendererTimerOffloadProcess(u, now, &sleepForUsec);
3168         sleepForUsec = PA_MAX(sleepForUsec, 0);
3169     }
3170 
3171     if (u->offload.fullTs != 0) {
3172         if (u->offload.fullTs + 10 * PA_USEC_PER_MSEC > now) { // 10 is min checking size
3173             const int64_t s = ((int64_t)(u->offload.fullTs) + 10 * PA_USEC_PER_MSEC) - (int64_t)now;
3174             sleepForUsec = sleepForUsec == -1 ? s : PA_MIN(s, sleepForUsec);
3175         } else if (pa_atomic_load(&u->offload.hdistate) == 1) {
3176             u->offload.fullTs = 0;
3177             OffloadUnlock(u);
3178         } else {
3179             u->offload.fullTs = 0;
3180         }
3181     }
3182 
3183     if (sleepForUsec != -1) {
3184         if (u->timestampSleep == -1) {
3185             u->timestampSleep = (int64_t)pa_rtclock_now() + sleepForUsec;
3186         } else {
3187             u->timestampSleep = PA_MIN(u->timestampSleep, (int64_t)pa_rtclock_now() + sleepForUsec);
3188         }
3189     }
3190 }
3191 
ThreadFuncRendererTimerProcessData(struct Userdata * u)3192 static void ThreadFuncRendererTimerProcessData(struct Userdata *u)
3193 {
3194     if (u->timestampSleep < (int64_t)pa_rtclock_now()) {
3195         u->timestampSleep = -1;
3196     }
3197 
3198     pthread_rwlock_unlock(&u->rwlockSleep);
3199 
3200     static int64_t logCnt = 0;
3201     if (logCnt == 0) {
3202         AUDIO_INFO_LOG("Bus thread still running");
3203     }
3204     ++logCnt;
3205     if (logCnt > LOG_LOOP_THRESHOLD) {
3206         logCnt = 0;
3207     }
3208 
3209     g_onlyPrimarySpeakerPaLoading = true;
3210     g_speakerPaAllStreamVolumeZero = true;
3211     CheckOnlyPrimarySpeakerPaLoading(u);
3212     if (!strcmp(u->sink->name, MCH_SINK_NAME)) {
3213         ProcessMCHData(u);
3214     } else if (!strcmp(u->sink->name, OFFLOAD_SINK_NAME) && u->offload_enable && u->offload.msgq) {
3215         ProcessOffloadData(u);
3216     } else {
3217         ProcessNormalData(u);
3218     }
3219 }
3220 
ThreadFuncRendererTimerBus(void * userdata)3221 static void ThreadFuncRendererTimerBus(void *userdata)
3222 {
3223     // set audio thread priority
3224     ScheduleThreadInServer(getpid(), gettid());
3225 
3226     struct Userdata *u = userdata;
3227 
3228     pa_assert(u);
3229 
3230     const char *deviceClass = GetDeviceClass(u->primary.sinkAdapter->deviceClass);
3231     AUDIO_INFO_LOG("Thread %s(use timing bus) starting up, pid %d, tid %d", deviceClass, getpid(), gettid());
3232     pa_thread_mq_install(&u->thread_mq);
3233 
3234     if (!strcmp(u->sink->name, OFFLOAD_SINK_NAME)) {
3235         OffloadReset(u);
3236         CHECK_AND_RETURN_LOG(u->offload.sinkAdapter != NULL, "offload.sinkAdapter is NULL");
3237         u->offload.sinkAdapter->RendererSinkOffloadRunningLockInit(u->offload.sinkAdapter);
3238     }
3239     while (true) {
3240         int ret;
3241         pthread_rwlock_wrlock(&u->rwlockSleep);
3242 
3243         int64_t sleepForUsec = 0;
3244 
3245         if (u->timestampSleep == -1) {
3246             pa_rtpoll_set_timer_disabled(u->rtpoll); // sleep forever
3247         } else if ((sleepForUsec = u->timestampSleep - (int64_t)(pa_rtclock_now())) <= 0) {
3248             pa_rtpoll_set_timer_relative(u->rtpoll, 0);
3249         } else {
3250             pa_rtpoll_set_timer_relative(u->rtpoll, sleepForUsec);
3251         }
3252 
3253         AUTO_CTRACE("ProcessDataLoop %s sleep:%lld us", deviceClass, sleepForUsec);
3254         // Hmm, nothing to do. Let's sleep
3255         if ((ret = pa_rtpoll_run(u->rtpoll)) < 0) {
3256             AUDIO_ERR_LOG("Thread %{public}s(use timing bus) shutting down, error %{public}d, "
3257                 "pid %{public}d, tid %{public}d", deviceClass, ret, getpid(), gettid());
3258             if (!strcmp(deviceClass, DEVICE_CLASS_PRIMARY)) {
3259                 AUDIO_ERR_LOG("Primary sink's pa_rtpoll_run error, exit");
3260                 _Exit(0);
3261             }
3262 
3263             // If this was no regular exit from the loop we have to continue
3264             // processing messages until we received PA_MESSAGE_SHUTDOWN
3265             pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE,
3266                 u->module, 0, NULL, NULL);
3267             pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN);
3268             pthread_rwlock_unlock(&u->rwlockSleep);
3269             break;
3270         }
3271 
3272         if (ret == 0) {
3273             AUDIO_INFO_LOG("Thread %{public}s(use timing bus) shutting down, pid %{public}d, tid %{public}d",
3274                 deviceClass, getpid(), gettid());
3275             pthread_rwlock_unlock(&u->rwlockSleep);
3276             break;
3277         }
3278 
3279         ThreadFuncRendererTimerProcessData(u);
3280     }
3281     UnscheduleThreadInServer(getpid(), gettid());
3282 }
3283 
ThreadFuncWriteHDIMultiChannel(void * userdata)3284 static void ThreadFuncWriteHDIMultiChannel(void *userdata)
3285 {
3286     AUDIO_DEBUG_LOG("ThreadFuncWriteHDIMultiChannel start");
3287     // set audio thread priority
3288     ScheduleThreadInServer(getpid(), gettid());
3289 
3290     struct Userdata *u = userdata;
3291     pa_assert(u);
3292 
3293     int32_t quit = 0;
3294 
3295     do {
3296         int32_t code = 0;
3297         pa_memchunk chunk;
3298 
3299         pa_assert_se(pa_asyncmsgq_get(u->multiChannel.dq, NULL, &code, NULL, NULL, &chunk, 1) == 0);
3300 
3301         switch (code) {
3302             case HDI_RENDER: {
3303                 pa_usec_t now = pa_rtclock_now();
3304                 if (RenderWrite(u->multiChannel.sinkAdapter, &chunk) < 0) {
3305                     AUDIO_DEBUG_LOG("ThreadFuncWriteHDIMultiChannel RenderWrite");
3306                     u->bytes_dropped += chunk.length;
3307                 }
3308                 if (pa_atomic_load(&u->multiChannel.dflag) == 1) {
3309                     pa_atomic_sub(&u->multiChannel.dflag, 1);
3310                 }
3311                 u->multiChannel.writeTime = pa_rtclock_now() - now;
3312                 break;
3313             }
3314             case QUIT:
3315                 quit = 1;
3316                 break;
3317             default:
3318                 break;
3319         }
3320         pa_asyncmsgq_done(u->multiChannel.dq, 0);
3321     } while (!quit);
3322     UnscheduleThreadInServer(getpid(), gettid());
3323 }
3324 
ProcessHdiRendererPrimary(struct Userdata * u,pa_memchunk * pChunk)3325 static void ProcessHdiRendererPrimary(struct Userdata *u, pa_memchunk *pChunk)
3326 {
3327     pa_usec_t now = pa_rtclock_now();
3328     if (pa_atomic_load(&u->primary.isHDISinkStarted) != 1 && now - u->timestampLastLog > USEC_PER_SEC) {
3329         u->timestampLastLog = now;
3330         const char *deviceClass = GetDeviceClass(u->primary.sinkAdapter->deviceClass);
3331         AUDIO_DEBUG_LOG("HDI not started, skip RenderWrite, wait sink[%s] suspend", deviceClass);
3332         pa_memblock_unref(pChunk->memblock);
3333     } else if (pa_atomic_load(&u->primary.isHDISinkStarted) != 1) {
3334         pa_memblock_unref(pChunk->memblock);
3335     } else if (RenderWrite(u->primary.sinkAdapter, pChunk) < 0) {
3336         u->bytes_dropped += pChunk->length;
3337         AUDIO_ERR_LOG("RenderWrite failed");
3338     }
3339     if (pa_atomic_load(&u->primary.dflag) == 1) {
3340         pa_atomic_sub(&u->primary.dflag, 1);
3341     }
3342     u->primary.writeTime = pa_rtclock_now() - now;
3343 }
3344 
ThreadFuncWriteHDI(void * userdata)3345 static void ThreadFuncWriteHDI(void *userdata)
3346 {
3347     // set audio thread priority
3348     ScheduleThreadInServer(getpid(), gettid());
3349 
3350     struct Userdata *u = userdata;
3351     pa_assert(u);
3352 
3353     int32_t quit = 0;
3354 
3355     do {
3356         int32_t code = 0;
3357         pa_memchunk chunk;
3358 
3359         CHECK_AND_RETURN_LOG(u->primary.dq != NULL, "u->primary.dq is NULL");
3360         pa_assert_se(pa_asyncmsgq_get(u->primary.dq, NULL, &code, NULL, NULL, &chunk, 1) == 0);
3361 
3362         int ret = 0;
3363         AUTO_CTRACE("hdi_sink::ThreadFuncWriteHDI code: %d", code);
3364         switch (code) {
3365             case HDI_RENDER: {
3366                 ProcessHdiRendererPrimary(u, &chunk);
3367                 break;
3368             }
3369             case HDI_STOP: {
3370                 if (pa_atomic_load(&u->primary.isHDISinkStarted) == 1) {
3371                     u->primary.sinkAdapter->RendererSinkStop(u->primary.sinkAdapter);
3372                     AUDIO_INFO_LOG("Stopped HDI renderer");
3373                     pa_atomic_store(&u->primary.isHDISinkStarted, 0);
3374                 }
3375                 break;
3376             }
3377             case HDI_START: {
3378                 ret = u->primary.sinkAdapter->RendererSinkStart(u->primary.sinkAdapter);
3379                 break;
3380             }
3381             case QUIT:
3382                 quit = 1;
3383                 break;
3384             default:
3385                 break;
3386         }
3387         AUTO_CTRACE("hdi_sink::ThreadFuncWriteHDI done ret: %d", ret);
3388         pa_asyncmsgq_done(u->primary.dq, ret);
3389     } while (!quit);
3390     UnscheduleThreadInServer(getpid(), gettid());
3391 }
3392 
TestModeThreadFuncWriteHDI(void * userdata)3393 static void TestModeThreadFuncWriteHDI(void *userdata)
3394 {
3395     // set audio thread priority
3396     ScheduleThreadInServer(getpid(), gettid());
3397 
3398     struct Userdata *u = userdata;
3399     pa_assert(u);
3400 
3401     int32_t quit = 0;
3402 
3403     do {
3404         int32_t code = 0;
3405         pa_memchunk chunk;
3406 
3407         pa_assert_se(pa_asyncmsgq_get(u->primary.dq, NULL, &code, NULL, NULL, &chunk, 1) == 0);
3408 
3409         switch (code) {
3410             case HDI_RENDER:
3411                 if (TestModeRenderWrite(u, &chunk) < 0) {
3412                     u->bytes_dropped += chunk.length;
3413                     AUDIO_ERR_LOG("TestModeRenderWrite failed");
3414                 }
3415                 if (pa_atomic_load(&u->primary.dflag) == 1) {
3416                     pa_atomic_sub(&u->primary.dflag, 1);
3417                 }
3418                 break;
3419             case QUIT:
3420                 quit = 1;
3421                 break;
3422             default:
3423                 break;
3424         }
3425         pa_asyncmsgq_done(u->primary.dq, 0);
3426     } while (!quit);
3427     UnscheduleThreadInServer(getpid(), gettid());
3428 }
3429 
SinkUpdateRequestedLatencyCb(pa_sink * s)3430 static void SinkUpdateRequestedLatencyCb(pa_sink *s)
3431 {
3432     struct Userdata *u = NULL;
3433     size_t nbytes;
3434 
3435     pa_sink_assert_ref(s);
3436     pa_assert_se(u = s->userdata);
3437 
3438     u->block_usec = pa_sink_get_requested_latency_within_thread(s);
3439 
3440     if (u->block_usec == (pa_usec_t) - 1)
3441         u->block_usec = s->thread_info.max_latency;
3442 
3443     if (u->block_usec < DEFAULT_BLOCK_USEC) {
3444         AUDIO_WARNING_LOG("block_usec is less than 20000, block_usec: %{public}" PRIu64, u->block_usec);
3445         u->block_usec = DEFAULT_BLOCK_USEC;
3446     }
3447     nbytes = pa_usec_to_bytes(u->block_usec, &s->sample_spec);
3448     pa_sink_set_max_request_within_thread(s, nbytes);
3449 }
3450 
CheckAndPrintLatency(uint64_t lastRecodedLatency,uint64_t latency,bool getLatencyFromHdiSucess,uint32_t continuesGetLatencyErrCount,uint64_t logThreshold)3451 static void CheckAndPrintLatency(uint64_t lastRecodedLatency, uint64_t latency, bool getLatencyFromHdiSucess,
3452     uint32_t continuesGetLatencyErrCount, uint64_t logThreshold)
3453 {
3454     uint64_t latencyDifference = (latency > lastRecodedLatency)
3455         ? (latency - lastRecodedLatency) : (lastRecodedLatency - latency);
3456     if (latencyDifference > logThreshold) {
3457         AUDIO_INFO_LOG("lastLatency: %{public}" PRIu64 " latency: %{public}" PRIu64 ""
3458             " getLatencyFromHdiSucess: %{public}d continuesGetLatencyErrCount: %{public}u",
3459             lastRecodedLatency, latency, getLatencyFromHdiSucess, continuesGetLatencyErrCount);
3460     }
3461 }
3462 
SinkProcessMsg(pa_msgobject * o,int32_t code,void * data,int64_t offset,pa_memchunk * chunk)3463 static int32_t SinkProcessMsg(pa_msgobject *o, int32_t code, void *data, int64_t offset,
3464     pa_memchunk *chunk)
3465 {
3466     AUDIO_DEBUG_LOG("SinkProcessMsg: code: %{public}d", code);
3467     AUTO_CTRACE("hdi_sink::SinkProcessMsg code: %d", code);
3468     struct Userdata *u = PA_SINK(o)->userdata;
3469     pa_assert(u);
3470 
3471     switch (code) {
3472         case PA_SINK_MESSAGE_GET_LATENCY: {
3473             if (!strcmp(GetDeviceClass(u->primary.sinkAdapter->deviceClass), DEVICE_CLASS_OFFLOAD)) {
3474                 uint64_t pos = u->offload.pos;
3475                 pa_usec_t now = pa_rtclock_now();
3476                 uint64_t time = now > u->offload.hdiPosTs ? (now - u->offload.hdiPosTs) / PA_USEC_PER_MSEC : 0;
3477                 uint64_t hdiPos = u->offload.hdiPos + time * PA_USEC_PER_MSEC;
3478                 *((uint64_t *)data) = pos > hdiPos ? (pos - hdiPos) : 0;
3479                 AUDIO_DEBUG_LOG("offload latency: %{public}" PRIu64 " write pos: %{public}" PRIu64
3480                     " hdi pos: %{public}" PRIu64 " time: %{public}" PRIu64,
3481                     *((uint64_t *)data), pos, u->offload.hdiPos, time * PA_USEC_PER_MSEC);
3482             } else if (u->sink_latency) {
3483                 *((uint64_t *)data) = u->sink_latency * PA_USEC_PER_MSEC;
3484             } else {
3485                 uint64_t latency;
3486                 uint32_t hdiLatency;
3487                 bool getLatencyFromHdiSucess = true;
3488                 // Tries to fetch latency from HDI else will make an estimate based
3489                 // on samples to be rendered based on the timestamp and current time
3490                 if (u->primary.sinkAdapter->RendererSinkGetLatency(u->primary.sinkAdapter, &hdiLatency) == 0) {
3491                     latency = (PA_USEC_PER_MSEC * hdiLatency);
3492                 } else {
3493                     pa_usec_t now = pa_rtclock_now();
3494                     latency = (now - u->primary.timestamp);
3495                     getLatencyFromHdiSucess = false;
3496                 }
3497 
3498                 *((uint64_t *)data) = latency;
3499                 CheckAndPrintLatency(u->lastRecodedLatency, latency, getLatencyFromHdiSucess,
3500                     u->continuesGetLatencyErrCount, DEFAULT_GETLATENCY_LOG_THRESHOLD_MS);
3501                 u->lastRecodedLatency = latency;
3502                 u->continuesGetLatencyErrCount = getLatencyFromHdiSucess ? 0 : (u->continuesGetLatencyErrCount + 1);
3503             }
3504             return 0;
3505         }
3506         default:
3507             break;
3508     }
3509     return pa_sink_process_msg(o, code, data, offset, chunk);
3510 }
3511 
GetStateInfo(pa_sink_state_t state)3512 static char *GetStateInfo(pa_sink_state_t state)
3513 {
3514     switch (state) {
3515         case PA_SINK_INVALID_STATE:
3516             return "INVALID";
3517         case PA_SINK_RUNNING:
3518             return "RUNNING";
3519         case PA_SINK_IDLE:
3520             return "IDLE";
3521         case PA_SINK_SUSPENDED:
3522             return "SUSPENDED";
3523         case PA_SINK_INIT:
3524             return "INIT";
3525         case PA_SINK_UNLINKED:
3526             return "UNLINKED";
3527         default:
3528             return "error state";
3529     }
3530 }
3531 
GetInputStateInfo(pa_sink_input_state_t state)3532 static char *GetInputStateInfo(pa_sink_input_state_t state)
3533 {
3534     switch (state) {
3535         case PA_SINK_INPUT_INIT:
3536             return "INIT";
3537         case PA_SINK_INPUT_RUNNING:
3538             return "RUNNING";
3539         case PA_SINK_INPUT_CORKED:
3540             return "CORKED";
3541         case PA_SINK_INPUT_UNLINKED:
3542             return "UNLINKED";
3543         default:
3544             return "UNKNOWN";
3545     }
3546 }
3547 
3548 // call from IO thread(OS_ProcessData)
RemoteSinkStateChange(pa_sink * s,pa_sink_state_t newState)3549 static int32_t RemoteSinkStateChange(pa_sink *s, pa_sink_state_t newState)
3550 {
3551     struct Userdata *u = s->userdata;
3552     if (s->thread_info.state == PA_SINK_INIT || newState == PA_SINK_INIT) {
3553         u->isFirstStarted = false;
3554     }
3555 
3556     if (!u->isFirstStarted && (newState == PA_SINK_RUNNING)) {
3557         u->primary.timestamp = pa_rtclock_now();
3558         u->isFirstStarted = true;
3559     }
3560 
3561     if (s->thread_info.state == PA_SINK_INIT && newState == PA_SINK_IDLE) {
3562         AUDIO_INFO_LOG("First start.");
3563     }
3564 
3565     if (s->thread_info.state == PA_SINK_SUSPENDED && PA_SINK_IS_OPENED(newState)) {
3566         u->primary.timestamp = pa_rtclock_now();
3567         if (pa_atomic_load(&u->primary.isHDISinkStarted) == 1) {
3568             return 0;
3569         }
3570 
3571         if (pa_asyncmsgq_send(u->primary.dq, NULL, HDI_START, NULL, 0, NULL)) {
3572             AUDIO_ERR_LOG("audiorenderer control start failed!");
3573         } else {
3574             pa_atomic_store(&u->primary.isHDISinkStarted, 1);
3575             u->render_in_idle_state = 1; // enable to reduce noise from idle to running.
3576             u->writeCount = 0;
3577             u->renderCount = 0;
3578             AUDIO_INFO_LOG("Successfully restarted remote renderer");
3579         }
3580     }
3581     if (PA_SINK_IS_OPENED(s->thread_info.state) && newState == PA_SINK_SUSPENDED) {
3582         // Continuously dropping data (clear counter on entering suspended state.
3583         if (u->bytes_dropped != 0) {
3584             AUDIO_INFO_LOG("HDI-sink continuously dropping data - clear statistics (%zu -> 0 bytes dropped)",
3585                            u->bytes_dropped);
3586             u->bytes_dropped = 0;
3587         }
3588 
3589         if (pa_atomic_load(&u->primary.isHDISinkStarted) == 1) {
3590             pa_asyncmsgq_post(u->primary.dq, NULL, HDI_STOP, NULL, 0, NULL, NULL);
3591         }
3592     }
3593 
3594     return 0;
3595 }
3596 
3597 // call from IO thread(OS_ProcessData)
SinkSetStateInIoThreadCbStartPrimary(struct Userdata * u,pa_sink_state_t newState)3598 static int32_t SinkSetStateInIoThreadCbStartPrimary(struct Userdata *u, pa_sink_state_t newState)
3599 {
3600     if (!PA_SINK_IS_OPENED(newState)) {
3601         return 0;
3602     }
3603 
3604     u->primary.timestamp = pa_rtclock_now();
3605     if (pa_atomic_load(&u->primary.isHDISinkStarted) == 1) {
3606         return 0;
3607     }
3608 
3609     if (u->sink->thread_info.state == PA_SINK_SUSPENDED && newState == PA_SINK_IDLE) {
3610         AUDIO_INFO_LOG("Primary sink from suspend to idle");
3611         return 0;
3612     }
3613 
3614     if (pa_asyncmsgq_send(u->primary.dq, NULL, HDI_START, NULL, 0, NULL)) {
3615         AUDIO_ERR_LOG("audiorenderer control start failed!");
3616         u->primary.sinkAdapter->RendererSinkDeInit(u->primary.sinkAdapter);
3617     } else {
3618         pa_atomic_store(&u->primary.isHDISinkStarted, 1);
3619         u->writeCount = 0;
3620         u->renderCount = 0;
3621         AUDIO_INFO_LOG("SinkSetStateInIoThreadCbStartPrimary, Successfully restarted HDI renderer");
3622     }
3623     return 0;
3624 }
3625 
SinkSetStateInIoThreadCbStartMultiChannel(struct Userdata * u,pa_sink_state_t newState)3626 static int32_t SinkSetStateInIoThreadCbStartMultiChannel(struct Userdata *u, pa_sink_state_t newState)
3627 {
3628     if (!PA_SINK_IS_OPENED(newState)) {
3629         return 0;
3630     }
3631 
3632     u->multiChannel.timestamp = pa_rtclock_now();
3633 
3634     EffectChainManagerReturnMultiChannelInfo(&u->multiChannel.sinkChannel, &u->multiChannel.sinkChannelLayout);
3635     ResetMultiChannelHdiState(u);
3636     return 0;
3637 }
3638 
OffloadSinkStateChangeCb(pa_sink * sink,pa_sink_state_t newState)3639 static void OffloadSinkStateChangeCb(pa_sink *sink, pa_sink_state_t newState)
3640 {
3641     struct Userdata *u = (struct Userdata *)(sink->userdata);
3642     const bool starting = PA_SINK_IS_OPENED(newState);
3643     const bool stopping = newState == PA_SINK_SUSPENDED;
3644     AUDIO_INFO_LOG("starting: %{public}d, stopping: %{public}d, offload_enable: %{public}d",
3645         starting, stopping, u->offload_enable);
3646     if (starting && u->offload_enable && !u->offload.inited && PrepareDeviceOffload(u) == 0) {
3647         u->offload.inited = true;
3648     } else if (stopping && u->offload_enable) {
3649         if (u->offload.isHDISinkStarted) {
3650             u->offload.sinkAdapter->RendererSinkStop(u->offload.sinkAdapter);
3651             AUDIO_INFO_LOG("Stopped Offload HDI renderer, DeInit later");
3652             u->offload.isHDISinkStarted = false;
3653         }
3654         OffloadReset(u);
3655         OffloadUnlock(u);
3656         if (u->offload.inited) {
3657             u->offload.inited = false;
3658             u->offload.sinkAdapter->RendererSinkDeInit(u->offload.sinkAdapter);
3659             AUDIO_INFO_LOG("DeInited Offload HDI renderer");
3660         }
3661         g_speakerPaAllStreamStartVolZeroTime = 0;
3662     }
3663 }
3664 
3665 // Called from the IO thread.
SinkSetStateInIoThreadCb(pa_sink * s,pa_sink_state_t newState,pa_suspend_cause_t newSuspendCause)3666 static int32_t SinkSetStateInIoThreadCb(pa_sink *s, pa_sink_state_t newState, pa_suspend_cause_t newSuspendCause)
3667 {
3668     struct Userdata *u = NULL;
3669 
3670     pa_assert(s);
3671     pa_assert_se(u = s->userdata);
3672 
3673     AUDIO_INFO_LOG("Sink[%{public}s] state change:[%{public}s]-->[%{public}s]",
3674         GetDeviceClass(u->primary.sinkAdapter->deviceClass), GetStateInfo(s->thread_info.state),
3675         GetStateInfo(newState));
3676     u->primary.previousState = u->sink->thread_info.state;
3677 
3678     if (!strcmp(GetDeviceClass(u->primary.sinkAdapter->deviceClass), DEVICE_CLASS_REMOTE)) {
3679         return RemoteSinkStateChange(s, newState);
3680     }
3681 
3682     if (!strcmp(u->sink->name, OFFLOAD_SINK_NAME)) {
3683         OffloadSinkStateChangeCb(s, newState);
3684         return 0;
3685     }
3686 
3687     if (s->thread_info.state == PA_SINK_SUSPENDED || s->thread_info.state == PA_SINK_INIT ||
3688         newState == PA_SINK_RUNNING) {
3689         if (EffectChainManagerCheckEffectOffload() && (!strcmp(u->sink->name, "Speaker"))) {
3690             SinkSetStateInIoThreadCbStartMultiChannel(u, newState);
3691         }
3692         if (strcmp(u->sink->name, BT_SINK_NAME) || newState == PA_SINK_RUNNING) {
3693             return SinkSetStateInIoThreadCbStartPrimary(u, newState);
3694         }
3695     } else if (PA_SINK_IS_OPENED(s->thread_info.state)) {
3696         if (newState != PA_SINK_SUSPENDED) {
3697             return 0;
3698         }
3699         // Continuously dropping data (clear counter on entering suspended state.
3700         if (u->bytes_dropped != 0) {
3701             AUDIO_INFO_LOG("HDI-sink continuously dropping data - clear statistics (%zu -> 0 bytes dropped)",
3702                            u->bytes_dropped);
3703             u->bytes_dropped = 0;
3704         }
3705 
3706         if (pa_atomic_load(&u->primary.isHDISinkStarted) == 1) {
3707             pa_asyncmsgq_post(u->primary.dq, NULL, HDI_STOP, NULL, 0, NULL, NULL);
3708         }
3709 
3710         if (u->multiChannel.isHDISinkStarted) {
3711             u->multiChannel.sinkAdapter->RendererSinkStop(u->multiChannel.sinkAdapter);
3712             AUDIO_INFO_LOG("MultiChannel Stopped HDI renderer");
3713             u->multiChannel.isHDISinkStarted = false;
3714         }
3715     }
3716 
3717     return 0;
3718 }
3719 
SinkInputMoveStartCb(pa_core * core,pa_sink_input * i,struct Userdata * u)3720 static pa_hook_result_t SinkInputMoveStartCb(pa_core *core, pa_sink_input *i, struct Userdata *u)
3721 {
3722     pa_sink_input_assert_ref(i);
3723     char str[SPRINTF_STR_LEN] = {0};
3724     GetSinkInputName(i, str, SPRINTF_STR_LEN);
3725     AUDIO_INFO_LOG("SinkInputMoveStartCb sink[%{public}s] - %{public}s", i->sink->name, str);
3726     if (u->offload_enable && !strcmp(i->sink->name, OFFLOAD_SINK_NAME) &&
3727         i->thread_info.state == PA_SINK_INPUT_RUNNING) {
3728         const bool maybeOffload = pa_memblockq_get_maxrewind(i->thread_info.render_memblockq) != 0;
3729         if (maybeOffload || InputIsOffload(i)) {
3730             OffloadRewindAndFlush(u, i, false);
3731             pa_sink_input_update_max_rewind(i, 0);
3732         }
3733     }
3734     return PA_HOOK_OK;
3735 }
3736 
SinkInputStateChangedCb(pa_core * core,pa_sink_input * i,struct Userdata * u)3737 static pa_hook_result_t SinkInputStateChangedCb(pa_core *core, pa_sink_input *i, struct Userdata *u)
3738 {
3739     pa_sink_input_assert_ref(i);
3740     char str[SPRINTF_STR_LEN] = {0};
3741     GetSinkInputName(i, str, SPRINTF_STR_LEN);
3742     AUDIO_INFO_LOG("SinkInputStateChangedCb sink[%{public}s] - %{public}s", i->sink->name, str);
3743     if (u->offload_enable && !strcmp(i->sink->name, OFFLOAD_SINK_NAME)) {
3744         if (i->thread_info.state == PA_SINK_INPUT_CORKED) {
3745             pa_atomic_store(&u->offload.hdistate, 0);
3746         }
3747     }
3748     return PA_HOOK_OK;
3749 }
3750 
SinkInputPutCb(pa_core * core,pa_sink_input * i,struct Userdata * u)3751 static pa_hook_result_t SinkInputPutCb(pa_core *core, pa_sink_input *i, struct Userdata *u)
3752 {
3753     pa_sink_input_assert_ref(i);
3754     const char *streamMode = pa_proplist_gets(i->proplist, "stream.mode");
3755     if (streamMode != NULL && !strcmp(streamMode, DUP_STEAM_NAME)) {
3756         AUDIO_INFO_LOG("Dup stream is dismissed:%{public}u", i->index);
3757         return PA_HOOK_OK;
3758     }
3759     i->state_change = PaInputStateChangeCb;
3760     return PA_HOOK_OK;
3761 }
3762 
PrepareDevice(struct Userdata * u,const char * filePath)3763 static int32_t PrepareDevice(struct Userdata *u, const char *filePath)
3764 {
3765     SinkAttr sample_attrs;
3766     int32_t ret;
3767 
3768     sample_attrs.format = ConvertPaToHdiAdapterFormat(u->ss.format);
3769     sample_attrs.adapterName = u->adapterName;
3770     sample_attrs.openMicSpeaker = u->open_mic_speaker;
3771     sample_attrs.sampleRate = (uint32_t)u->ss.rate;
3772     sample_attrs.channel = u->ss.channels;
3773     sample_attrs.volume = MAX_SINK_VOLUME_LEVEL;
3774     sample_attrs.filePath = filePath;
3775     sample_attrs.deviceNetworkId = u->deviceNetworkId;
3776     sample_attrs.deviceType =  u->deviceType;
3777 
3778     if (!strcmp(GetDeviceClass(u->primary.sinkAdapter->deviceClass), DEVICE_CLASS_MULTICHANNEL)) {
3779         sample_attrs.channel = DEFAULT_MULTICHANNEL_NUM;
3780         sample_attrs.channelLayout = DEFAULT_MULTICHANNEL_CHANNELLAYOUT;
3781     }
3782 
3783     ret = u->primary.sinkAdapter->RendererSinkInit(u->primary.sinkAdapter, &sample_attrs);
3784     if (ret != 0) {
3785         AUDIO_ERR_LOG("audiorenderer Init failed!");
3786         return -1;
3787     }
3788 
3789     if (ret != 0) {
3790         AUDIO_ERR_LOG("audiorenderer control start failed!");
3791         u->primary.sinkAdapter->RendererSinkDeInit(u->primary.sinkAdapter);
3792         return -1;
3793     }
3794 
3795     return 0;
3796 }
3797 
PrepareDeviceOffload(struct Userdata * u)3798 static int32_t PrepareDeviceOffload(struct Userdata *u)
3799 {
3800     const char *adapterName = safeProplistGets(u->sink->proplist, PA_PROP_DEVICE_STRING, "");
3801     const char *filePath = safeProplistGets(u->sink->proplist, "filePath", "");
3802     const char *deviceNetworkId = safeProplistGets(u->sink->proplist, "NetworkId", "");
3803     AUDIO_INFO_LOG("PrepareDeviceOffload enter, deviceClass %d, filePath %s",
3804         u->offload.sinkAdapter->deviceClass, filePath);
3805     SinkAttr sample_attrs;
3806     int32_t ret;
3807 
3808     enum HdiAdapterFormat format = ConvertPaToHdiAdapterFormat(u->ss.format);
3809     sample_attrs.format = format;
3810     AUDIO_INFO_LOG("PrepareDeviceOffload audiorenderer format: %d ,adapterName %s",
3811         sample_attrs.format, GetDeviceClass(u->offload.sinkAdapter->deviceClass));
3812     sample_attrs.adapterName = adapterName;
3813     sample_attrs.openMicSpeaker = u->open_mic_speaker;
3814     sample_attrs.sampleRate = u->ss.rate;
3815     sample_attrs.channel = u->ss.channels;
3816     sample_attrs.volume = MAX_SINK_VOLUME_LEVEL;
3817     sample_attrs.filePath = filePath;
3818     sample_attrs.deviceNetworkId = deviceNetworkId;
3819     sample_attrs.deviceType = u->deviceType;
3820 
3821     ret = u->offload.sinkAdapter->RendererSinkInit(u->offload.sinkAdapter, &sample_attrs);
3822     if (ret != 0) {
3823         AUDIO_ERR_LOG("PrepareDeviceOffload audiorenderer Init failed!");
3824         return -1;
3825     }
3826 
3827     return 0;
3828 }
3829 
PrepareDeviceMultiChannel(struct Userdata * u,struct RendererSinkAdapter * sinkAdapter,const char * filePath)3830 static int32_t PrepareDeviceMultiChannel(struct Userdata *u, struct RendererSinkAdapter *sinkAdapter,
3831     const char *filePath)
3832 {
3833     int32_t ret;
3834 
3835     enum HdiAdapterFormat format = ConvertPaToHdiAdapterFormat(u->ss.format);
3836 
3837     u->multiChannel.sample_attrs.format = format;
3838     u->multiChannel.sample_attrs.sampleRate = u->ss.rate;
3839     AUDIO_INFO_LOG("PrepareDeviceMultiChannel format: %d ,adapterName %s",
3840         u->multiChannel.sample_attrs.format, GetDeviceClass(sinkAdapter->deviceClass));
3841     u->multiChannel.sample_attrs.adapterName = u->adapterName;
3842     u->multiChannel.sample_attrs.openMicSpeaker = u->open_mic_speaker;
3843     u->multiChannel.sample_attrs.sampleRate = u->ss.rate;
3844     u->multiChannel.sample_attrs.channel = DEFAULT_MULTICHANNEL_NUM;
3845     u->multiChannel.sample_attrs.channelLayout = DEFAULT_MULTICHANNEL_CHANNELLAYOUT;
3846     u->multiChannel.sinkChannel = DEFAULT_MULTICHANNEL_NUM;
3847     u->multiChannel.sinkChannelLayout = DEFAULT_MULTICHANNEL_CHANNELLAYOUT;
3848     u->multiChannel.sample_attrs.volume = MAX_SINK_VOLUME_LEVEL;
3849     u->multiChannel.sample_attrs.filePath = filePath;
3850     u->multiChannel.sample_attrs.deviceNetworkId = u->deviceNetworkId;
3851     u->multiChannel.sample_attrs.deviceType = u->deviceType;
3852 
3853     ret = sinkAdapter->RendererSinkInit(sinkAdapter, &u->multiChannel.sample_attrs);
3854     if (ret != 0) {
3855         AUDIO_ERR_LOG("PrepareDeviceMultiChannel Init failed!");
3856         return -1;
3857     }
3858     u->multiChannel.isHDISinkInited = true;
3859     AUDIO_DEBUG_LOG("PrepareDeviceMultiChannel init success");
3860     return 0;
3861 }
3862 
PaHdiSinkUserdataInit(struct Userdata * u)3863 static void PaHdiSinkUserdataInit(struct Userdata *u)
3864 {
3865     u->format = u->ss.format;
3866     u->processLen = IN_CHANNEL_NUM_MAX * DEFAULT_FRAMELEN;
3867     u->processSize = (uint32_t)u->processLen * sizeof(float);
3868     u->bufferAttr = pa_xnew0(BufferAttr, 1);
3869     u->bufferAttr->samplingRate = (int32_t)u->ss.rate;
3870     u->bufferAttr->frameLen = DEFAULT_FRAMELEN;
3871     u->bufferAttr->numChanIn = u->ss.channels;
3872     u->bufferAttr->numChanOut = u->ss.channels;
3873     u->bufferAttr->bufOutUsed = true;
3874     u->sinkSceneMode = -1;
3875     u->sinkSceneType = -1;
3876 }
3877 
PaHdiSinkInit(struct Userdata * u,pa_modargs * ma,const char * driver)3878 static pa_sink *PaHdiSinkInit(struct Userdata *u, pa_modargs *ma, const char *driver)
3879 {
3880     pa_sink_new_data data;
3881     pa_module *m;
3882     pa_sink *sink = NULL;
3883 
3884     m = u->module;
3885     u->ss = m->core->default_sample_spec;
3886     u->map = m->core->default_channel_map;
3887     if (pa_modargs_get_sample_spec_and_channel_map(ma, &u->ss, &u->map, PA_CHANNEL_MAP_DEFAULT) < 0) {
3888         AUDIO_ERR_LOG("Failed to parse sample specification and channel map");
3889         goto fail;
3890     }
3891 
3892     AUDIO_INFO_LOG("Initializing HDI rendering device with rate: %{public}d, channels: %{public}d",
3893         u->ss.rate, u->ss.channels);
3894     if (PrepareDevice(u, pa_modargs_get_value(ma, "file_path", "")) < 0) { goto fail; }
3895 
3896     u->primary.prewrite = 0;
3897     if (u->offload_enable && !strcmp(GetDeviceClass(u->primary.sinkAdapter->deviceClass), DEVICE_CLASS_PRIMARY)) {
3898         u->primary.prewrite = u->block_usec * 7; // 7 frame, set cache len in hdi, avoid pop
3899     }
3900 
3901     AUDIO_DEBUG_LOG("Initialization of HDI rendering device[%{public}s] completed", u->adapterName);
3902     pa_sink_new_data_init(&data);
3903     data.driver = driver;
3904     data.module = m;
3905 
3906     PaHdiSinkUserdataInit(u);
3907     pa_sink_new_data_set_name(&data, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME));
3908     pa_sink_new_data_set_sample_spec(&data, &u->ss);
3909     pa_sink_new_data_set_channel_map(&data, &u->map);
3910     pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING,
3911         (u->adapterName ? u->adapterName : DEFAULT_AUDIO_DEVICE_NAME));
3912     pa_proplist_setf(data.proplist, PA_PROP_DEVICE_DESCRIPTION, "HDI sink is %s",
3913         (u->adapterName ? u->adapterName : DEFAULT_AUDIO_DEVICE_NAME));
3914     pa_proplist_sets(data.proplist, "filePath", pa_modargs_get_value(ma, "file_path", ""));
3915     pa_proplist_sets(data.proplist, "networkId", pa_modargs_get_value(ma, "network_id", DEFAULT_DEVICE_NETWORKID));
3916 
3917     if (pa_modargs_get_proplist(ma, "sink_properties", data.proplist, PA_UPDATE_REPLACE) < 0) {
3918         AUDIO_ERR_LOG("Invalid properties");
3919         pa_sink_new_data_done(&data);
3920         goto fail;
3921     }
3922 
3923     if (u->fixed_latency) {
3924         sink = pa_sink_new(m->core, &data, PA_SINK_HARDWARE | PA_SINK_LATENCY);
3925     } else {
3926         sink = pa_sink_new(m->core, &data,
3927                        PA_SINK_HARDWARE | PA_SINK_LATENCY | PA_SINK_DYNAMIC_LATENCY);
3928     }
3929     pa_sink_new_data_done(&data);
3930 
3931     return sink;
3932 
3933 fail:
3934     AUDIO_ERR_LOG("PaHdiSinkInit fail");
3935     return NULL;
3936 }
3937 
PaHdiSinkNewInitThreadMultiChannel(pa_module * m,pa_modargs * ma,struct Userdata * u)3938 static int32_t PaHdiSinkNewInitThreadMultiChannel(pa_module *m, pa_modargs *ma, struct Userdata *u)
3939 {
3940     int ret;
3941     pa_atomic_store(&u->multiChannel.dflag, 0);
3942     u->multiChannel.msgq = pa_asyncmsgq_new(0);
3943     u->multiChannel.dq = pa_asyncmsgq_new(0);
3944     ret = LoadSinkAdapter(DEVICE_CLASS_MULTICHANNEL, "LocalDevice", &u->multiChannel.sinkAdapter);
3945     if (ret) {
3946         AUDIO_ERR_LOG("Load mch adapter failed");
3947         return -1;
3948     }
3949     if (PrepareDeviceMultiChannel(u, u->multiChannel.sinkAdapter, pa_modargs_get_value(ma, "file_path", "")) < 0) {
3950         return -1;
3951     }
3952 
3953     u->multiChannel.used = true;
3954 
3955     u->multiChannel.chunk.memblock = pa_memblock_new(u->sink->core->mempool, -1); // -1 == pa_mempool_block_size_max
3956 
3957     return 0;
3958 }
3959 
PaHdiSinkNewInitThread(pa_module * m,pa_modargs * ma,struct Userdata * u)3960 static int32_t PaHdiSinkNewInitThread(pa_module *m, pa_modargs *ma, struct Userdata *u)
3961 {
3962     char *paThreadName = NULL;
3963 
3964     // offload
3965     const char *deviceClass = GetDeviceClass(u->primary.sinkAdapter->deviceClass);
3966     if (!strcmp(u->sink->name, OFFLOAD_SINK_NAME) && u->offload_enable) {
3967         AUDIO_DEBUG_LOG("PaHdiSinkNew device[%s] sink[%s] init offload thread", deviceClass, u->sink->name);
3968         int32_t ret = LoadSinkAdapter(DEVICE_CLASS_OFFLOAD, "LocalDevice", &u->offload.sinkAdapter);
3969         if (ret) {
3970             AUDIO_ERR_LOG("Load adapter failed");
3971             return -1;
3972         }
3973         u->offload.msgq = pa_asyncmsgq_new(0);
3974         pa_atomic_store(&u->offload.hdistate, 0);
3975         u->offload.chunk.memblock = pa_memblock_new(u->sink->core->mempool,
3976             pa_usec_to_bytes(200 * PA_USEC_PER_MSEC, &u->sink->sample_spec)); // 200ms for max len once offload render
3977         pa_module_hook_connect(m, &m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_START], PA_HOOK_LATE,
3978             (pa_hook_cb_t)SinkInputMoveStartCb, u);
3979         pa_module_hook_connect(m, &m->core->hooks[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED], PA_HOOK_NORMAL,
3980             (pa_hook_cb_t)SinkInputStateChangedCb, u);
3981     } else {
3982         AUDIO_INFO_LOG("PaHdiSinkNew device[%s] sink[%s] skip offload thread", deviceClass, u->sink->name);
3983     }
3984 
3985     if (!strcmp(u->sink->name, MCH_SINK_NAME)) {
3986         PaHdiSinkNewInitThreadMultiChannel(m, ma, u);
3987         u->multichannel_enable = true;
3988     } else {
3989         u->multichannel_enable = false;
3990     }
3991 
3992     if (!strcmp(u->sink->name, "Speaker") || !strcmp(u->sink->name, MCH_SINK_NAME)
3993             || !strcmp(u->sink->name, OFFLOAD_SINK_NAME)) {
3994         pa_module_hook_connect(m, &m->core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], PA_HOOK_EARLY,
3995                 (pa_hook_cb_t)SinkInputPutCb, u);
3996     }
3997 
3998     paThreadName = "OS_ProcessData";
3999     if (!(u->thread = pa_thread_new(paThreadName, ThreadFuncRendererTimerBus, u))) {
4000         AUDIO_ERR_LOG("Failed to create bus thread.");
4001         return -1;
4002     }
4003 
4004     return 0;
4005 }
4006 
PaHdiSinkNewInitUserData(pa_module * m,pa_modargs * ma,struct Userdata * u)4007 static int32_t PaHdiSinkNewInitUserData(pa_module *m, pa_modargs *ma, struct Userdata *u)
4008 {
4009     u->core = m->core;
4010     u->module = m;
4011 
4012     pa_memchunk_reset(&u->memchunk);
4013     u->rtpoll = pa_rtpoll_new();
4014     u->primary.msgq = pa_asyncmsgq_new(0);
4015     pthread_rwlock_init(&u->rwlockSleep, NULL);
4016     pthread_mutex_init(&u->mutexPa, NULL);
4017     pthread_mutex_init(&u->mutexPa2, NULL);
4018 
4019     if (pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll) < 0) {
4020         AUDIO_ERR_LOG("pa_thread_mq_init() failed.");
4021         return -1;
4022     }
4023 
4024     AUDIO_DEBUG_LOG("Load sink adapter");
4025     int32_t ret = LoadSinkAdapter(pa_modargs_get_value(ma, "device_class", DEFAULT_DEVICE_CLASS),
4026         pa_modargs_get_value(ma, "network_id", DEFAULT_DEVICE_NETWORKID), &u->primary.sinkAdapter);
4027     if (ret) {
4028         AUDIO_ERR_LOG("Load adapter failed");
4029         return -1;
4030     }
4031     if (pa_modargs_get_value_u32(ma, "fixed_latency", &u->fixed_latency) < 0) {
4032         AUDIO_ERR_LOG("Failed to parse fixed latency argument.");
4033         return -1;
4034     }
4035     if (pa_modargs_get_value_s32(ma, "device_type", &u->deviceType) < 0) {
4036         AUDIO_ERR_LOG("Failed to parse deviceType argument.");
4037         return -1;
4038     }
4039 
4040     u->adapterName = pa_modargs_get_value(ma, "adapter_name", DEFAULT_DEVICE_CLASS);
4041     u->sink_latency = 0;
4042     if (pa_modargs_get_value_u32(ma, "sink_latency", &u->sink_latency) < 0) {
4043         AUDIO_ERR_LOG("No sink_latency argument.");
4044     }
4045 
4046     u->deviceNetworkId = pa_modargs_get_value(ma, "network_id", DEFAULT_DEVICE_NETWORKID);
4047 
4048     if (pa_modargs_get_value_u32(ma, "render_in_idle_state", &u->render_in_idle_state) < 0) {
4049         AUDIO_ERR_LOG("Failed to parse render_in_idle_state  argument.");
4050         return -1;
4051     }
4052 
4053     if (pa_modargs_get_value_u32(ma, "open_mic_speaker", &u->open_mic_speaker) < 0) {
4054         AUDIO_ERR_LOG("Failed to parse open_mic_speaker argument.");
4055         return -1;
4056     }
4057 
4058     u->test_mode_on = false;
4059     if (pa_modargs_get_value_boolean(ma, "test_mode_on", &u->test_mode_on) < 0) {
4060         AUDIO_INFO_LOG("No test_mode_on arg. Normal mode it is.");
4061     }
4062 
4063     return 0;
4064 }
4065 
PaHdiSinkNewInitUserDataAndSink(pa_module * m,pa_modargs * ma,const char * driver,struct Userdata * u)4066 static int32_t PaHdiSinkNewInitUserDataAndSink(pa_module *m, pa_modargs *ma, const char *driver, struct Userdata *u)
4067 {
4068     if (pa_modargs_get_value_boolean(ma, "offload_enable", &u->offload_enable) < 0) {
4069         AUDIO_ERR_LOG("Failed to parse offload_enable argument.");
4070         return -1;
4071     }
4072 
4073     pa_atomic_store(&u->primary.dflag, 0);
4074     u->primary.dq = pa_asyncmsgq_new(0);
4075     CHECK_AND_RETURN_RET_LOG(u->primary.dq, -1, "Failed to create u->primary.dq");
4076 
4077     u->sink = PaHdiSinkInit(u, ma, driver);
4078     if (!u->sink) {
4079         AUDIO_ERR_LOG("Failed to create sink object");
4080         return -1;
4081     }
4082 
4083     u->sink->parent.process_msg = SinkProcessMsg;
4084     u->sink->set_state_in_io_thread = SinkSetStateInIoThreadCb;
4085     if (!u->fixed_latency) {
4086         u->sink->update_requested_latency = SinkUpdateRequestedLatencyCb;
4087     }
4088     u->sink->userdata = u;
4089 
4090     pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq);
4091     pa_sink_set_rtpoll(u->sink, u->rtpoll);
4092 
4093     u->bytes_dropped = 0;
4094     u->buffer_size = DEFAULT_BUFFER_SIZE;
4095     if (pa_modargs_get_value_u32(ma, "buffer_size", &u->buffer_size) < 0) {
4096         AUDIO_ERR_LOG("Failed to parse buffer_size argument.");
4097         return -1;
4098     }
4099 
4100     u->block_usec = pa_bytes_to_usec(u->buffer_size, &u->sink->sample_spec);
4101 
4102     u->lastRecodedLatency = 0;
4103     u->continuesGetLatencyErrCount = 0;
4104     u->lastStreamAvailable = 0;
4105     u->streamAvailable = 0;
4106 
4107     if (u->fixed_latency) {
4108         pa_sink_set_fixed_latency(u->sink, u->block_usec);
4109     } else {
4110         pa_sink_set_latency_range(u->sink, 0, u->block_usec);
4111     }
4112 
4113     pa_sink_set_max_request(u->sink, u->buffer_size);
4114 
4115     u->streamAvailableMap = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func,
4116         pa_xfree, pa_xfree);
4117 
4118     return 0;
4119 }
4120 
PaHdiSinkNew(pa_module * m,pa_modargs * ma,const char * driver)4121 pa_sink *PaHdiSinkNew(pa_module *m, pa_modargs *ma, const char *driver)
4122 {
4123     struct Userdata *u = NULL;
4124     char *hdiThreadName = NULL;
4125     char *hdiThreadNameMch = NULL;
4126 
4127     pa_assert(m);
4128     pa_assert(ma);
4129 
4130     u = pa_xnew0(struct Userdata, 1);
4131     pa_assert(u);
4132 
4133     if (PaHdiSinkNewInitUserData(m, ma, u) < 0) {
4134         goto fail;
4135     }
4136 
4137     if (PaHdiSinkNewInitUserDataAndSink(m, ma, driver, u) < 0) {
4138         goto fail;
4139     }
4140 
4141     int32_t ret = PaHdiSinkNewInitThread(m, ma, u);
4142     if (ret) {
4143         AUDIO_ERR_LOG("PaHdiSinkNewInitThread failed");
4144         goto fail;
4145     }
4146 
4147     if (u->test_mode_on) {
4148         u->writeCount = 0;
4149         u->renderCount = 0;
4150         hdiThreadName = "OS_WriteHdiTest";
4151         if (!(u->primary.thread_hdi = pa_thread_new(hdiThreadName, TestModeThreadFuncWriteHDI, u))) {
4152             AUDIO_ERR_LOG("Failed to test-mode-write-hdi thread.");
4153             goto fail;
4154         }
4155     } else {
4156         hdiThreadName = "OS_WriteHdi";
4157         if (!(u->primary.thread_hdi = pa_thread_new(hdiThreadName, ThreadFuncWriteHDI, u))) {
4158             AUDIO_ERR_LOG("Failed to write-hdi-primary2 thread.");
4159             goto fail;
4160         }
4161 
4162         if (!strcmp(u->sink->name, MCH_SINK_NAME)) {
4163             hdiThreadNameMch = "OS_WriteHdiMch";
4164             if (!(u->multiChannel.thread_hdi = pa_thread_new(hdiThreadNameMch, ThreadFuncWriteHDIMultiChannel, u))) {
4165                 AUDIO_ERR_LOG("Failed to write-hdi-multichannel thread.");
4166                 goto fail;
4167             }
4168         }
4169     }
4170 
4171     u->primary.writeTime = DEFAULT_WRITE_TIME;
4172     u->multiChannel.writeTime = DEFAULT_WRITE_TIME;
4173     pa_sink_put(u->sink);
4174 
4175     return u->sink;
4176 fail:
4177     AUDIO_ERR_LOG("PaHdiSinkNew failed, free userdata");
4178     UserdataFree(u);
4179 
4180     return NULL;
4181 }
4182 
UserdataFreeOffload(struct Userdata * u)4183 static void UserdataFreeOffload(struct Userdata *u)
4184 {
4185     if (u->offload.msgq) {
4186         pa_asyncmsgq_unref(u->offload.msgq);
4187     }
4188 
4189     if (u->offload.sinkAdapter) {
4190         u->offload.sinkAdapter->RendererSinkStop(u->offload.sinkAdapter);
4191         OffloadUnlock(u);
4192         u->offload.sinkAdapter->RendererSinkDeInit(u->offload.sinkAdapter);
4193         UnLoadSinkAdapter(u->offload.sinkAdapter);
4194     }
4195 
4196     if (u->offload.chunk.memblock) {
4197         pa_memblock_unref(u->offload.chunk.memblock);
4198     }
4199 }
4200 
UserdataFreeMultiChannel(struct Userdata * u)4201 static void UserdataFreeMultiChannel(struct Userdata *u)
4202 {
4203     if (u->multiChannel.msgq) {
4204         pa_asyncmsgq_unref(u->multiChannel.msgq);
4205     }
4206 
4207     if (u->multiChannel.dq) {
4208         pa_asyncmsgq_unref(u->multiChannel.dq);
4209     }
4210 
4211     if (u->multiChannel.sinkAdapter) {
4212         u->multiChannel.sinkAdapter->RendererSinkStop(u->multiChannel.sinkAdapter);
4213         u->multiChannel.sinkAdapter->RendererSinkDeInit(u->multiChannel.sinkAdapter);
4214         UnLoadSinkAdapter(u->multiChannel.sinkAdapter);
4215     }
4216 
4217     if (u->multiChannel.chunk.memblock) {
4218         pa_memblock_unref(u->multiChannel.chunk.memblock);
4219     }
4220 }
4221 
UserdataFreeThread(struct Userdata * u)4222 static void UserdataFreeThread(struct Userdata *u)
4223 {
4224     if (u->thread) {
4225         pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL);
4226         pa_thread_free(u->thread);
4227     }
4228 
4229     if (u->offload.thread) {
4230         pa_asyncmsgq_send(u->offload.msgq, NULL, QUIT, NULL, 0, NULL);
4231         pa_thread_free(u->offload.thread);
4232     }
4233 
4234     if (u->multiChannel.thread) {
4235         pa_asyncmsgq_send(u->multiChannel.msgq, NULL, QUIT, NULL, 0, NULL);
4236         pa_thread_free(u->multiChannel.thread);
4237     }
4238 
4239     if (u->multiChannel.thread_hdi) {
4240         pa_asyncmsgq_post(u->multiChannel.dq, NULL, QUIT, NULL, 0, NULL, NULL);
4241         pa_thread_free(u->multiChannel.thread_hdi);
4242     }
4243 
4244     if (u->primary.thread) {
4245         pa_asyncmsgq_send(u->primary.msgq, NULL, QUIT, NULL, 0, NULL);
4246         pa_thread_free(u->primary.thread);
4247     }
4248 
4249     if (u->primary.thread_hdi) {
4250         pa_asyncmsgq_post(u->primary.dq, NULL, QUIT, NULL, 0, NULL, NULL);
4251         pa_thread_free(u->primary.thread_hdi);
4252     }
4253 
4254     pa_thread_mq_done(&u->thread_mq);
4255 }
4256 
FreeBufferAttr(struct Userdata * u)4257 static bool FreeBufferAttr(struct Userdata *u)
4258 {
4259     // free heap allocated in userdata init
4260     if (u->bufferAttr == NULL) {
4261         pa_xfree(u);
4262         AUDIO_DEBUG_LOG("buffer attr is null, free done");
4263         return false;
4264     }
4265     FreeEffectBuffer(u);
4266 
4267     pa_xfree(u->bufferAttr);
4268     u->bufferAttr = NULL;
4269     return true;
4270 }
4271 
UserdataFree(struct Userdata * u)4272 static void UserdataFree(struct Userdata *u)
4273 {
4274     if (u == NULL) {
4275         AUDIO_INFO_LOG("Userdata is null, free done");
4276         return;
4277     }
4278 
4279     if (u->sink) {
4280         pa_sink_unlink(u->sink);
4281     }
4282 
4283     UserdataFreeThread(u);
4284 
4285     if (u->sink) {
4286         pa_sink_unref(u->sink);
4287     }
4288 
4289     if (u->memchunk.memblock) {
4290         pa_memblock_unref(u->memchunk.memblock);
4291     }
4292 
4293     if (u->rtpoll) {
4294         pa_rtpoll_free(u->rtpoll);
4295     }
4296 
4297     UserdataFreeOffload(u);
4298     UserdataFreeMultiChannel(u);
4299 
4300     if (u->primary.msgq) {
4301         pa_asyncmsgq_unref(u->primary.msgq);
4302     }
4303 
4304     if (u->primary.dq) {
4305         pa_asyncmsgq_unref(u->primary.dq);
4306     }
4307 
4308     if (u->primary.sinkAdapter) {
4309         u->primary.sinkAdapter->RendererSinkStop(u->primary.sinkAdapter);
4310         u->primary.sinkAdapter->RendererSinkDeInit(u->primary.sinkAdapter);
4311         UnLoadSinkAdapter(u->primary.sinkAdapter);
4312     }
4313 
4314     if (!FreeBufferAttr(u)) {
4315         return;
4316     }
4317 
4318     if (u->streamAvailableMap) {
4319         pa_hashmap_free(u->streamAvailableMap);
4320     }
4321 
4322     pa_xfree(u);
4323 
4324     AUDIO_DEBUG_LOG("UserdataFree done");
4325 }
4326 
PaHdiSinkFree(pa_sink * s)4327 void PaHdiSinkFree(pa_sink *s)
4328 {
4329     AUTO_CTRACE("PaHdiSinkFree");
4330     AUDIO_INFO_LOG("PaHdiSinkFree, free userdata");
4331     struct Userdata *u = NULL;
4332 
4333     pa_sink_assert_ref(s);
4334     pa_assert_se(u = s->userdata);
4335 
4336     UserdataFree(u);
4337 }
4338