• 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 
33 namespace OHOS {
34 namespace AudioStandard {
35 
36 class MockCallbacks : public IStatusCallback, public IWriteCallback {
37 public:
38     explicit MockCallbacks(uint32_t streamIndex);
39     virtual ~MockCallbacks() = default;
40     void OnStatusUpdate(IOperation operation) override;
41     int32_t OnWriteData(size_t length) override;
42 private:
43     uint32_t streamIndex_ = 0;
44 };
45 
46 class AudioEndpointInner : public AudioEndpoint {
47 public:
48     AudioEndpointInner(EndpointType type, uint64_t id, const AudioProcessConfig &clientConfig);
49     ~AudioEndpointInner();
50 
51     bool Config(const AudioDeviceDescriptor &deviceInfo) override;
52     bool StartDevice(EndpointStatus preferredState = INVALID);
53     void HandleStartDeviceFailed();
54     bool StopDevice();
55 
56     // when audio process start.
57     int32_t OnStart(IAudioProcessStream *processStream) override;
58     // when audio process pause.
59     int32_t OnPause(IAudioProcessStream *processStream) override;
60     // when audio process request update handle info.
61     int32_t OnUpdateHandleInfo(IAudioProcessStream *processStream) override;
62 
63     /**
64      * Call LinkProcessStream when first create process or link other process with this endpoint.
65      * Here are cases:
66      *   case1: endpointStatus_ = UNLINKED, link not running process; UNLINKED-->IDEL & godown
67      *   case2: endpointStatus_ = UNLINKED, link running process; UNLINKED-->IDEL & godown
68      *   case3: endpointStatus_ = IDEL, link not running process; IDEL-->IDEL
69      *   case4: endpointStatus_ = IDEL, link running process; IDEL-->STARTING-->RUNNING
70      *   case5: endpointStatus_ = RUNNING; RUNNING-->RUNNING
71     */
72     int32_t LinkProcessStream(IAudioProcessStream *processStream, bool startWhenLinking = true) override;
73     void LinkProcessStreamExt(IAudioProcessStream *processStream,
74     const std::shared_ptr<OHAudioBuffer>& processBuffer);
75 
76     int32_t UnlinkProcessStream(IAudioProcessStream *processStream) override;
77 
78     int32_t GetPreferBufferInfo(uint32_t &totalSizeInframe, uint32_t &spanSizeInframe) override;
79 
80     void Dump(std::string &dumpString) override;
81 
82     std::string GetEndpointName() override;
GetEndpointType()83     EndpointType GetEndpointType() override
84     {
85         return endpointType_;
86     }
87     int32_t SetVolume(AudioStreamType streamType, float volume) override;
88 
89     int32_t ResolveBuffer(std::shared_ptr<OHAudioBuffer> &buffer) override;
90 
GetBuffer()91     std::shared_ptr<OHAudioBuffer> GetBuffer() override
92     {
93         return dstAudioBuffer_;
94     }
95 
96     // for inner-cap
97     bool ShouldInnerCap(int32_t innerCapId) override;
98     int32_t EnableFastInnerCap(int32_t innerCapId) override;
99     int32_t DisableFastInnerCap() override;
100     int32_t DisableFastInnerCap(int32_t innerCapId) override;
101 
102     int32_t InitDupStream(int32_t innerCapId);
103 
104     EndpointStatus GetStatus() override;
105 
106     void Release() override;
107 
GetDeviceInfo()108     AudioDeviceDescriptor &GetDeviceInfo() override
109     {
110         return deviceInfo_;
111     }
112 
GetDeviceRole()113     DeviceRole GetDeviceRole() override
114     {
115         return deviceInfo_.deviceRole_;
116     }
117 
118     float GetMaxAmplitude() override;
119     uint32_t GetLinkedProcessCount() override;
120 
121     AudioMode GetAudioMode() const final;
122 
123     void BindCore();
124 
125     void CheckWakeUpTime(int64_t &wakeUpTime);
126 private:
127     AudioProcessConfig GetInnerCapConfig();
128     void StartThread(const IAudioSinkAttr &attr);
129     void MixToDupStream(const std::vector<AudioStreamData> &srcDataList, int32_t innerCapId);
130     bool ConfigInputPoint(const AudioDeviceDescriptor &deviceInfo);
131     int32_t PrepareDeviceBuffer(const AudioDeviceDescriptor &deviceInfo);
132     int32_t GetAdapterBufferInfo(const AudioDeviceDescriptor &deviceInfo);
133     void ReSyncPosition();
134     void RecordReSyncPosition();
135     void InitAudiobuffer(bool resetReadWritePos);
136     void ProcessData(const std::vector<AudioStreamData> &srcDataList, const AudioStreamData &dstData);
137     void ProcessSingleData(const AudioStreamData &srcData, const AudioStreamData &dstData, bool applyVol);
138     void ResetZeroVolumeState();
139     void HandleZeroVolumeStartEvent();
140     void HandleZeroVolumeStopEvent();
141     void HandleRendererDataParams(const AudioStreamData &srcData, const AudioStreamData &dstData, bool applyVol = true);
142     int32_t HandleCapturerDataParams(const BufferDesc &writeBuf, const BufferDesc &readBuf,
143         const BufferDesc &convertedBuffer);
144     void ZeroVolumeCheck(const int32_t vol);
145     int64_t GetPredictNextReadTime(uint64_t posInFrame);
146     int64_t GetPredictNextWriteTime(uint64_t posInFrame);
147     bool PrepareNextLoop(uint64_t curWritePos, int64_t &wakeUpTime);
148     bool RecordPrepareNextLoop(uint64_t curReadPos, int64_t &wakeUpTime);
149 
150     /**
151      * @brief Get the current read position in frame and the read-time with it.
152      *
153      * @param frames the read position in frame
154      * @param nanoTime the time in nanosecond when device-sink start read the buffer
155     */
156     bool GetDeviceHandleInfo(uint64_t &frames, int64_t &nanoTime);
157     int32_t GetProcLastWriteDoneInfo(const std::shared_ptr<OHAudioBuffer> processBuffer, uint64_t curWriteFrame,
158         uint64_t &proHandleFrame, int64_t &proHandleTime);
159 
160     void CheckStandBy();
161     bool IsAnyProcessRunning();
162     bool IsAnyProcessRunningInner();
163     bool CheckAllBufferReady(int64_t checkTime, uint64_t curWritePos);
164     void WaitAllProcessReady(uint64_t curWritePos);
165     bool ProcessToEndpointDataHandle(uint64_t curWritePos);
166     void ProcessToDupStream(const std::vector<AudioStreamData> &audioDataList, AudioStreamData &dstStreamData,
167         int32_t innerCapId);
168     void GetAllReadyProcessData(std::vector<AudioStreamData> &audioDataList);
169 
170     std::string GetStatusStr(EndpointStatus status);
171 
172     int32_t WriteToSpecialProcBuf(const std::shared_ptr<OHAudioBuffer> &procBuf, const BufferDesc &readBuf,
173         const BufferDesc &convertedBuffer, bool muteFlag);
174     void WriteToProcessBuffers(const BufferDesc &readBuf);
175     int32_t ReadFromEndpoint(uint64_t curReadPos);
176     bool KeepWorkloopRunning();
177 
178     void EndpointWorkLoopFuc();
179     void RecordEndpointWorkLoopFuc();
180 
181     void WatchingEndpointWorkLoopFuc();
182     void WatchingRecordEndpointWorkLoopFuc();
183     // Call GetMmapHandlePosition in ipc may block more than a cycle, call it in another thread.
184     void AsyncGetPosTime();
185     bool DelayStopDevice();
186 
187     std::shared_ptr<IAudioRenderSink> GetFastSink(const AudioDeviceDescriptor &deviceInfo, EndpointType type);
188     std::shared_ptr<IAudioCaptureSource> GetFastSource(const std::string &networkId, EndpointType type,
189         IAudioSourceAttr &attr);
190     void InitSinkAttr(IAudioSinkAttr &attr, const AudioDeviceDescriptor &deviceInfo);
191 
192     void InitLatencyMeasurement();
193     void DeinitLatencyMeasurement();
194     void CheckPlaySignal(uint8_t *buffer, size_t bufferSize);
195     void CheckRecordSignal(uint8_t *buffer, size_t bufferSize);
196 
197     void CheckUpdateState(char *frame, uint64_t replyBytes);
198 
199     void ProcessUpdateAppsUidForPlayback();
200     void ProcessUpdateAppsUidForRecord();
201 
202     int32_t HandleDisableFastCap(CaptureInfo &captureInfo);
203 
204     void WriteMuteDataSysEvent(uint8_t *buffer, size_t bufferSize, int32_t index);
205     bool IsInvalidBuffer(uint8_t *buffer, size_t bufferSize, AudioSampleFormat format);
206     void ReportDataToResSched(std::unordered_map<std::string, std::string> payload, uint32_t type);
207     void HandleMuteWriteData(BufferDesc &bufferDesc, int32_t index);
208 private:
209     static constexpr int64_t ONE_MILLISECOND_DURATION = 1000000; // 1ms
210     static constexpr int64_t THREE_MILLISECOND_DURATION = 3000000; // 3ms
211     static constexpr int64_t WRITE_TO_HDI_AHEAD_TIME = -1000000; // ahead 1ms
212     static constexpr int32_t UPDATE_THREAD_TIMEOUT = 1000; // 1000ms
213     static constexpr int32_t CPU_INDEX = 2;
214     enum ThreadStatus : uint32_t {
215         WAITTING = 0,
216         SLEEPING,
217         INRUNNING
218     };
219     enum FastSinkType {
220         NONE_FAST_SINK = 0,
221         FAST_SINK_TYPE_NORMAL,
222         FAST_SINK_TYPE_REMOTE,
223         FAST_SINK_TYPE_VOIP,
224         FAST_SINK_TYPE_BLUETOOTH
225     };
226     enum FastSourceType {
227         NONE_FAST_SOURCE = 0,
228         FAST_SOURCE_TYPE_NORMAL,
229         FAST_SOURCE_TYPE_REMOTE,
230         FAST_SOURCE_TYPE_VOIP
231     };
232     enum ZeroVolumeState : uint32_t {
233         INACTIVE = 0,
234         ACTIVE,
235         IN_TIMING
236     };
237     // SamplingRate EncodingType SampleFormat Channel
238     AudioDeviceDescriptor deviceInfo_ = AudioDeviceDescriptor(AudioDeviceDescriptor::DEVICE_INFO);
239     AudioStreamInfo dstStreamInfo_;
240     EndpointType endpointType_;
241     int32_t id_ = 0;
242     std::mutex listLock_;
243     std::vector<IAudioProcessStream *> processList_;
244     std::vector<std::shared_ptr<OHAudioBuffer>> processBufferList_;
245     AudioProcessConfig clientConfig_;
246 
247     std::atomic<bool> isInited_ = false;
248 
249     // for inner-cap
250     std::mutex dupMutex_;
251     std::shared_ptr<MockCallbacks> dupStreamCallback_ = nullptr;
252     size_t dupBufferSize_ = 0;
253     std::unique_ptr<uint8_t []> dupBuffer_ = nullptr;
254     FILE *dumpC2SDup_ = nullptr; // client to server inner-cap dump file
255     std::string dupDumpName_ = "";
256 
257     uint32_t fastRenderId_ = HDI_INVALID_ID;
258     uint32_t fastCaptureId_ = HDI_INVALID_ID;
259     FastSinkType fastSinkType_ = NONE_FAST_SINK;
260     FastSourceType fastSourceType_ = NONE_FAST_SOURCE;
261 
262     LinearPosTimeModel readTimeModel_;
263     LinearPosTimeModel writeTimeModel_;
264 
265     int64_t spanDuration_ = 0; // nano second
266     int64_t serverAheadReadTime_ = 0;
267     int dstBufferFd_ = -1; // -1: invalid fd.
268     uint32_t dstTotalSizeInframe_ = 0;
269     uint32_t dstSpanSizeInframe_ = 0;
270     uint32_t dstByteSizePerFrame_ = 0;
271     std::shared_ptr<OHAudioBuffer> dstAudioBuffer_ = nullptr;
272 
273     std::atomic<EndpointStatus> endpointStatus_ = INVALID;
274     bool isStarted_ = false;
275     int64_t delayStopTime_ = INT64_MAX;
276     int64_t zeroVolumeStartTime_ = INT64_MAX;
277     ZeroVolumeState zeroVolumeState_ = INACTIVE;
278 
279     std::atomic<ThreadStatus> threadStatus_ = WAITTING;
280     std::thread endpointWorkThread_;
281     std::mutex loopThreadLock_;
282     std::condition_variable workThreadCV_;
283     int64_t lastHandleProcessTime_ = 0;
284 
285     std::thread updatePosTimeThread_;
286     std::mutex updateThreadLock_;
287     std::condition_variable updateThreadCV_;
288     std::atomic<bool> stopUpdateThread_ = false;
289 
290     std::atomic<uint64_t> posInFrame_ = 0;
291     std::atomic<int64_t> timeInNano_ = 0;
292 
293     bool isDeviceRunningInIdel_ = true; // will call start sink when linked.
294     bool needReSyncPosition_ = true;
295     FILE *dumpHdi_ = nullptr;
296     std::string dumpHdiName_ = "";
297     mutable int64_t volumeDataCount_ = 0;
298     std::string logUtilsTag_ = "";
299 
300     // for get amplitude
301     float maxAmplitude_ = 0;
302     int64_t lastGetMaxAmplitudeTime_ = 0;
303     int64_t last10FrameStartTime_ = 0;
304     bool startUpdate_ = false;
305     int renderFrameNum_ = 0;
306 
307     bool signalDetected_ = false;
308     bool latencyMeasEnabled_ = false;
309     size_t detectedTime_ = 0;
310     std::shared_ptr<SignalDetectAgent> signalDetectAgent_ = nullptr;
311     std::atomic_bool endpointWorkLoopFucThreadStatus_ { false };
312     std::atomic_bool recordEndpointWorkLoopFucThreadStatus_ { false };
313     std::unordered_map<int32_t, CaptureInfo> fastCaptureInfos_;
314     bool coreBinded_ = false;
315 };
316 } // namespace AudioStandard
317 } // namespace OHOS
318 #endif // AUDIO_ENDPOINT_H
319