• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 
16 #ifndef AUDIO_ENDPOINT_PRIVATE_H
17 #define AUDIO_ENDPOINT_PRIVATE_H
18 
19 #include <sstream>
20 #include <memory>
21 #include <thread>
22 
23 #include "i_process_status_listener.h"
24 #include "linear_pos_time_model.h"
25 #include "audio_device_descriptor.h"
26 #include "i_stream_manager.h"
27 #include "i_renderer_stream.h"
28 #include "audio_utils.h"
29 #include "common/hdi_adapter_info.h"
30 #include "sink/i_audio_render_sink.h"
31 #include "source/i_audio_capture_source.h"
32 #include "audio_ring_cache.h"
33 #include "audio_stream_info.h"
34 
35 namespace OHOS {
36 namespace AudioStandard {
37 
38 class MockCallbacks : public IStatusCallback, public IWriteCallback {
39 public:
40     explicit MockCallbacks(uint32_t streamIndex);
41     virtual ~MockCallbacks();
42     void OnStatusUpdate(IOperation operation) override;
43     int32_t OnWriteData(size_t length) override;
44     int32_t OnWriteData(int8_t *inputData, size_t requestDataLen) override;
45     int32_t GetAvailableSize(size_t &length) override;
46     std::unique_ptr<AudioRingCache>& GetDupRingBuffer();
47 private:
48     uint32_t streamIndex_ = 0;
49     FILE *dumpDupOut_ = nullptr;
50     std::string dumpDupOutFileName_ = "";
51     std::unique_ptr<AudioRingCache> dupRingBuffer_ = nullptr;
52 };
53 
54 class AudioEndpointInner : public AudioEndpoint {
55 public:
56     AudioEndpointInner(EndpointType type, uint64_t id, const AudioProcessConfig &clientConfig);
57     ~AudioEndpointInner();
58 
59     bool Config(const AudioDeviceDescriptor &deviceInfo, AudioStreamInfo &streamInfo) override;
60     bool StartDevice(EndpointStatus preferredState = INVALID);
61     void HandleStartDeviceFailed();
62     bool StopDevice();
63 
64     // when audio process start.
65     int32_t OnStart(IAudioProcessStream *processStream) override;
66     // when audio process pause.
67     int32_t OnPause(IAudioProcessStream *processStream) override;
68     // when audio process request update handle info.
69     int32_t OnUpdateHandleInfo(IAudioProcessStream *processStream) override;
70 
71     /**
72      * Call LinkProcessStream when first create process or link other process with this endpoint.
73      * Here are cases:
74      *   case1: endpointStatus_ = UNLINKED, link not running process; UNLINKED-->IDEL & godown
75      *   case2: endpointStatus_ = UNLINKED, link running process; UNLINKED-->IDEL & godown
76      *   case3: endpointStatus_ = IDEL, link not running process; IDEL-->IDEL
77      *   case4: endpointStatus_ = IDEL, link running process; IDEL-->STARTING-->RUNNING
78      *   case5: endpointStatus_ = RUNNING; RUNNING-->RUNNING
79     */
80     int32_t LinkProcessStream(IAudioProcessStream *processStream, bool startWhenLinking = true) override;
81     void AddEndpointStreamVolume(IAudioProcessStream *processStream);
82     void LinkProcessStreamExt(IAudioProcessStream *processStream,
83     const std::shared_ptr<OHAudioBufferBase>& processBuffer);
84 
85     int32_t UnlinkProcessStream(IAudioProcessStream *processStream) override;
86 
87     int32_t GetPreferBufferInfo(uint32_t &totalSizeInframe, uint32_t &spanSizeInframe) override;
88 
89     void Dump(std::string &dumpString) override;
90 
91     std::string GetEndpointName() override;
GetEndpointType()92     EndpointType GetEndpointType() override
93     {
94         return endpointType_;
95     }
96     int32_t SetVolume(AudioStreamType streamType, float volume) override;
97 
GetBuffer()98     std::shared_ptr<OHAudioBufferBase> GetBuffer() override
99     {
100         // not support
101         return nullptr;
102     }
103 
104     // for inner-cap
105     bool ShouldInnerCap(int32_t innerCapId) override;
106     int32_t EnableFastInnerCap(int32_t innerCapId) override;
107     int32_t DisableFastInnerCap() override;
108     int32_t DisableFastInnerCap(int32_t innerCapId) override;
109 
110     int32_t InitDupStream(int32_t innerCapId);
111 
112     EndpointStatus GetStatus() override;
113 
114     void Release() override;
115     float GetMaxAmplitude() override;
116     uint32_t GetLinkedProcessCount() override;
117 
118     AudioMode GetAudioMode() const final;
119 
120     void BindCore();
121 
122     void CheckWakeUpTime(int64_t &wakeUpTime);
123 private:
124     AudioProcessConfig GetInnerCapConfig();
125     void StartThread(const IAudioSinkAttr &attr);
126     void CheckTimeAndBufferReady(uint64_t &curWritePos, int64_t &wakeUpTime, int64_t &curTime);
127     void MixToDupStream(const std::vector<AudioStreamData> &srcDataList, int32_t innerCapId);
128     bool ConfigInputPoint(const AudioDeviceDescriptor &deviceInfo);
129     int32_t PrepareDeviceBuffer(const AudioDeviceDescriptor &deviceInfo);
130     int32_t GetAdapterBufferInfo(const AudioDeviceDescriptor &deviceInfo);
131     void ReSyncPosition();
132     void RecordReSyncPosition();
133     void InitAudiobuffer(bool resetReadWritePos);
134     void ProcessData(const std::vector<AudioStreamData> &srcDataList, const AudioStreamData &dstData);
135     void ProcessSingleData(const AudioStreamData &srcData, const AudioStreamData &dstData, bool applyVol);
136     void ResetZeroVolumeState();
137     void HandleZeroVolumeStartEvent();
138     void HandleZeroVolumeStopEvent();
139     void HandleRendererDataParams(const AudioStreamData &srcData, const AudioStreamData &dstData, bool applyVol = true);
140     int32_t HandleCapturerDataParams(RingBufferWrapper &writeBuf, const BufferDesc &readBuf,
141         const BufferDesc &convertedBuffer);
142     void ZeroVolumeCheck(const int32_t vol);
143     int64_t GetPredictNextReadTime(uint64_t posInFrame);
144     int64_t GetPredictNextWriteTime(uint64_t posInFrame);
145     bool PrepareNextLoop(uint64_t curWritePos, int64_t &wakeUpTime, const std::function<void()> &moveClientIndex);
146     bool RecordPrepareNextLoop(uint64_t curReadPos, int64_t &wakeUpTime);
147     int32_t InitDupBuffer(AudioProcessConfig processConfig, int32_t innerCapId, uint32_t dupStreamIndex);
148 
149     /**
150      * @brief Get the current read position in frame and the read-time with it.
151      *
152      * @param frames the read position in frame
153      * @param nanoTime the time in nanosecond when device-sink start read the buffer
154     */
155     bool GetDeviceHandleInfo(uint64_t &frames, int64_t &nanoTime);
156 
157     void CheckStandBy();
158     bool IsAnyProcessRunning();
159     bool IsAnyProcessRunningInner();
160     bool CheckAllBufferReady(int64_t checkTime, uint64_t curWritePos);
161     void WaitAllProcessReady(uint64_t curWritePos);
162     void CheckSyncInfo(uint64_t curWritePos);
163     bool ProcessToEndpointDataHandle(uint64_t curWritePos, std::function<void()> &moveClientIndex);
164     void ProcessToDupStream(const std::vector<AudioStreamData> &audioDataList, AudioStreamData &dstStreamData,
165         int32_t innerCapId);
166 
167     struct VolumeResult {
168         int32_t volumeStart;
169         float volumeEnd;
170         float volumeHap;
171         bool muteFlag;
172     };
173 
174     VolumeResult CalculateVolume(size_t i);
175     void GetAllReadyProcessData(std::vector<AudioStreamData> &audioDataList, std::function<void()> &moveClientsIndex);
176     void GetAllReadyProcessDataSub(size_t i,
177         std::vector<AudioStreamData> &audioDataList, uint64_t curRead, std::function<void()> &moveClientIndex);
178     std::string GetStatusStr(EndpointStatus status);
179 
180     bool IsNearlinkAbsVolSupportStream(DeviceType deviceType, AudioVolumeType volumeType);
181 
182     int32_t WriteToSpecialProcBuf(const std::shared_ptr<OHAudioBufferBase> &procBuf, const BufferDesc &readBuf,
183         const BufferDesc &convertedBuffer, bool muteFlag);
184     void WriteToProcessBuffers(const BufferDesc &readBuf);
185     int32_t ReadFromEndpoint(uint64_t curReadPos);
186     bool KeepWorkloopRunning();
187 
188     void EndpointWorkLoopFuc();
189     void RecordEndpointWorkLoopFuc();
190 
191     // Call GetMmapHandlePosition in ipc may block more than a cycle, call it in another thread.
192     void AsyncGetPosTime();
193     bool DelayStopDevice();
194 
195     std::shared_ptr<IAudioRenderSink> GetFastSink(const AudioDeviceDescriptor &deviceInfo, EndpointType type);
196     std::shared_ptr<IAudioCaptureSource> GetFastSource(const std::string &networkId, EndpointType type,
197         IAudioSourceAttr &attr);
198     void InitSinkAttr(IAudioSinkAttr &attr, const AudioDeviceDescriptor &deviceInfo);
199 
200     void InitLatencyMeasurement();
201     void DeinitLatencyMeasurement();
202     void CheckPlaySignal(uint8_t *buffer, size_t bufferSize);
203     void CheckRecordSignal(uint8_t *buffer, size_t bufferSize);
204 
205     void CheckUpdateState(char *frame, uint64_t replyBytes);
206 
207     void ProcessUpdateAppsUidForPlayback();
208     void ProcessUpdateAppsUidForRecord();
209 
210     int32_t HandleDisableFastCap(CaptureInfo &captureInfo);
211 
212     void WriteMuteDataSysEvent(uint8_t *buffer, size_t bufferSize, int32_t index);
213     bool IsInvalidBuffer(uint8_t *buffer, size_t bufferSize, AudioSampleFormat format);
214     void ReportDataToResSched(std::unordered_map<std::string, std::string> payload, uint32_t type);
215     void HandleMuteWriteData(BufferDesc &bufferDesc, int32_t index);
216     int32_t CreateDupBufferInner(int32_t innerCapId);
217     int32_t WriteDupBufferInner(const BufferDesc &bufferDesc, int32_t innerCapId);
218     bool PrepareRingBuffer(size_t i, uint64_t curRead, RingBufferWrapper& ringBuffer);
219     int32_t WriteToRingBuffer(RingBufferWrapper &writeBuf, const BufferDesc &buffer);
220     void SetupMoveCallback(size_t i, uint64_t curRead, const RingBufferWrapper& ringBuffer,
221         std::function<void()>& moveClientIndex);
222     void AddProcessStreamToList(IAudioProcessStream *processStream,
223         const std::shared_ptr<OHAudioBufferBase> &processBuffer);
224     void CheckAudioHapticsSync(uint64_t curWritePos);
225     bool IsBufferDataInsufficient(int32_t readableDataFrame, uint32_t spanSizeInFrame);
226     bool NeedUseTempBuffer(const RingBufferWrapper &ringBuffer, size_t spanSizeInByte);
227     void PrepareStreamDataBuffer(size_t i, size_t spanSizeInByte,
228         RingBufferWrapper &ringBuffer, AudioStreamData &streamData);
229 private:
230     static constexpr int64_t ONE_MILLISECOND_DURATION = 1000000; // 1ms
231     static constexpr int64_t TWO_MILLISECOND_DURATION = 2000000; // 2ms
232     static constexpr int64_t THREE_MILLISECOND_DURATION = 3000000; // 3ms
233     static constexpr int64_t WRITE_TO_HDI_AHEAD_TIME = -1000000; // ahead 1ms
234     static constexpr int32_t UPDATE_THREAD_TIMEOUT = 1000; // 1000ms
235     static constexpr int32_t CPU_INDEX = 2;
236     static constexpr int64_t MAX_WAKEUP_TIME_NS = 2000000000; // 2s
237     static constexpr int64_t WAKEUPTIME_FOR_VOIP_MMAP_NS = 40000000; // 40ms
238     static constexpr int64_t WAKEUPTIME_FOR_MMAP_NS = 10000000; // 10ms
239     static constexpr int64_t RELATIVE_SLEEP_TIME_NS = 5000000; // 5ms
240 
241     enum ThreadStatus : uint32_t {
242         WAITTING = 0,
243         SLEEPING,
244         INRUNNING
245     };
246     enum FastSinkType {
247         NONE_FAST_SINK = 0,
248         FAST_SINK_TYPE_NORMAL,
249         FAST_SINK_TYPE_REMOTE,
250         FAST_SINK_TYPE_VOIP,
251         FAST_SINK_TYPE_BLUETOOTH
252     };
253     enum FastSourceType {
254         NONE_FAST_SOURCE = 0,
255         FAST_SOURCE_TYPE_NORMAL,
256         FAST_SOURCE_TYPE_REMOTE,
257         FAST_SOURCE_TYPE_VOIP
258     };
259     enum ZeroVolumeState : uint32_t {
260         INACTIVE = 0,
261         ACTIVE,
262         IN_TIMING
263     };
264 
265     EndpointType endpointType_;
266     int32_t id_ = 0;
267     std::mutex listLock_;
268     std::vector<IAudioProcessStream *> processList_;
269     std::vector<std::shared_ptr<OHAudioBufferBase>> processBufferList_;
270     std::vector<std::vector<uint8_t>> processTmpBufferList_;
271     AudioProcessConfig clientConfig_;
272 
273     std::atomic<bool> isInited_ = false;
274 
275     // for inner-cap
276     std::mutex dupMutex_;
277     size_t dupTotalSizeInFrame_ = 0;
278     size_t dupSpanSizeInFrame_ = 0;
279     size_t dupSpanSizeInByte_ = 0;
280     size_t dupByteSizePerFrame_ = 0;
281     FILE *dumpDupIn_ = nullptr;
282     std::string dumpDupInFileName_ = "";
283     std::map<int32_t, std::shared_ptr<MockCallbacks>> innerCapIdToDupStreamCallbackMap_;
284     size_t dupBufferSize_ = 0;
285     std::unique_ptr<uint8_t []> dupBuffer_ = nullptr;
286     FILE *dumpC2SDup_ = nullptr; // client to server inner-cap dump file
287     std::string dupDumpName_ = "";
288 
289     uint32_t fastRenderId_ = HDI_INVALID_ID;
290     uint32_t fastCaptureId_ = HDI_INVALID_ID;
291     FastSinkType fastSinkType_ = NONE_FAST_SINK;
292     FastSourceType fastSourceType_ = NONE_FAST_SOURCE;
293 
294     LinearPosTimeModel readTimeModel_;
295     LinearPosTimeModel writeTimeModel_;
296 
297     int64_t spanDuration_ = 0; // nano second
298     int64_t serverAheadReadTime_ = 0;
299     int dstBufferFd_ = -1; // -1: invalid fd.
300     uint32_t dstTotalSizeInframe_ = 0;
301     uint32_t dstSpanSizeInframe_ = 0;
302     uint32_t dstByteSizePerFrame_ = 0;
303     uint32_t syncInfoSize_ = 0;
304     int64_t lastWriteTime_ = 0; // ns
305     std::shared_ptr<OHAudioBuffer> dstAudioBuffer_ = nullptr;
306 
307     std::atomic<EndpointStatus> endpointStatus_ = INVALID;
308     bool isStarted_ = false;
309     int64_t delayStopTime_ = INT64_MAX;
310     int64_t zeroVolumeStartTime_ = INT64_MAX;
311     ZeroVolumeState zeroVolumeState_ = INACTIVE;
312 
313     std::atomic<ThreadStatus> threadStatus_ = WAITTING;
314     std::thread endpointWorkThread_;
315     std::mutex loopThreadLock_;
316     std::condition_variable workThreadCV_;
317     int64_t lastHandleProcessTime_ = 0;
318 
319     std::thread updatePosTimeThread_;
320     std::mutex updateThreadLock_;
321     std::condition_variable updateThreadCV_;
322     std::atomic<bool> stopUpdateThread_ = false;
323 
324     std::atomic<uint64_t> posInFrame_ = 0;
325     std::atomic<int64_t> timeInNano_ = 0;
326 
327     bool isDeviceRunningInIdel_ = true; // will call start sink when linked.
328     bool needReSyncPosition_ = true;
329     FILE *dumpHdi_ = nullptr;
330     std::string dumpHdiName_ = "";
331     mutable int64_t volumeDataCount_ = 0;
332     std::string logUtilsTag_ = "";
333 
334     // for get amplitude
335     float maxAmplitude_ = 0;
336     int64_t lastGetMaxAmplitudeTime_ = 0;
337     int64_t last10FrameStartTime_ = 0;
338     bool startUpdate_ = false;
339     int renderFrameNum_ = 0;
340 
341     bool signalDetected_ = false;
342     bool latencyMeasEnabled_ = false;
343     size_t detectedTime_ = 0;
344     std::shared_ptr<SignalDetectAgent> signalDetectAgent_ = nullptr;
345     std::unordered_map<int32_t, CaptureInfo> fastCaptureInfos_;
346     bool coreBinded_ = false;
347     bool isExistLoopback_ = false;
348     int32_t audioHapticsSyncId_ = false;
349 };
350 } // namespace AudioStandard
351 } // namespace OHOS
352 #endif // AUDIO_ENDPOINT_H
353