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