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