1 /*
2  * Copyright (c) 2023-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 "AudioEndpointInner"
17 #endif
18 
19 #include "audio_endpoint.h"
20 
21 #include <atomic>
22 #include <cinttypes>
23 #include <condition_variable>
24 #include <thread>
25 #include <vector>
26 #include <mutex>
27 
28 #include "securec.h"
29 
30 #include "audio_errors.h"
31 #include "audio_service_log.h"
32 #include "audio_schedule.h"
33 #include "audio_utils.h"
34 #include "bluetooth_renderer_sink.h"
35 #include "fast_audio_renderer_sink.h"
36 #include "fast_audio_capturer_source.h"
37 #include "format_converter.h"
38 #include "i_audio_capturer_source.h"
39 #include "i_stream_manager.h"
40 #include "linear_pos_time_model.h"
41 #include "policy_handler.h"
42 #include "audio_log_utils.h"
43 #include "media_monitor_manager.h"
44 #include "audio_dump_pcm.h"
45 #ifdef DAUDIO_ENABLE
46 #include "remote_fast_audio_renderer_sink.h"
47 #include "remote_fast_audio_capturer_source.h"
48 #endif
49 
50 namespace OHOS {
51 namespace AudioStandard {
52 namespace {
53     static constexpr int32_t VOLUME_SHIFT_NUMBER = 16; // 1 >> 16 = 65536, max volume
54     static constexpr int64_t RECORD_DELAY_TIME_NS = 4000000; // 4ms = 4 * 1000 * 1000ns
55     static constexpr int64_t RECORD_VOIP_DELAY_TIME_NS = 20000000; // 20ms = 20 * 1000 * 1000ns
56     static constexpr int64_t MAX_SPAN_DURATION_NS = 100000000; // 100ms = 100 * 1000 * 1000ns
57     static constexpr int64_t DELAY_STOP_HDI_TIME = 10000000000; // 10s
58     static constexpr int64_t WAIT_CLIENT_STANDBY_TIME_NS = 1000000000; // 1s = 1000 * 1000 * 1000ns
59     static constexpr int64_t DELAY_STOP_HDI_TIME_FOR_ZERO_VOLUME_NS = 4000000000; // 4s = 4 * 1000 * 1000 * 1000ns
60     static constexpr int64_t DELAY_STOP_HDI_TIME_WHEN_NO_RUNNING_NS = 1000000000; // 1s
61     static constexpr int32_t SLEEP_TIME_IN_DEFAULT = 400; // 400ms
62     static constexpr int64_t DELTA_TO_REAL_READ_START_TIME = 0; // 0ms
63     const uint16_t GET_MAX_AMPLITUDE_FRAMES_THRESHOLD = 40;
64     static const int32_t HALF_FACTOR = 2;
65 }
66 
ConvertToHdiAdapterFormat(AudioSampleFormat format)67 static enum HdiAdapterFormat ConvertToHdiAdapterFormat(AudioSampleFormat format)
68 {
69     enum HdiAdapterFormat adapterFormat;
70     switch (format) {
71         case AudioSampleFormat::SAMPLE_U8:
72             adapterFormat = HdiAdapterFormat::SAMPLE_U8;
73             break;
74         case AudioSampleFormat::SAMPLE_S16LE:
75             adapterFormat = HdiAdapterFormat::SAMPLE_S16;
76             break;
77         case AudioSampleFormat::SAMPLE_S24LE:
78             adapterFormat = HdiAdapterFormat::SAMPLE_S24;
79             break;
80         case AudioSampleFormat::SAMPLE_S32LE:
81             adapterFormat = HdiAdapterFormat::SAMPLE_S32;
82             break;
83         default:
84             adapterFormat = HdiAdapterFormat::INVALID_WIDTH;
85             break;
86     }
87 
88     return adapterFormat;
89 }
90 
91 class MockCallbacks : public IStatusCallback, public IWriteCallback {
92 public:
93     explicit MockCallbacks(uint32_t streamIndex);
94     virtual ~MockCallbacks() = default;
95     void OnStatusUpdate(IOperation operation) override;
96     int32_t OnWriteData(size_t length) override;
97 private:
98     uint32_t streamIndex_ = 0;
99 };
100 
101 class AudioEndpointInner : public AudioEndpoint {
102 public:
103     AudioEndpointInner(EndpointType type, uint64_t id, const AudioProcessConfig &clientConfig);
104     ~AudioEndpointInner();
105 
106     bool Config(const DeviceInfo &deviceInfo) override;
107     bool StartDevice();
108     void HandleStartDeviceFailed();
109     bool StopDevice();
110 
111     // when audio process start.
112     int32_t OnStart(IAudioProcessStream *processStream) override;
113     // when audio process pause.
114     int32_t OnPause(IAudioProcessStream *processStream) override;
115     // when audio process request update handle info.
116     int32_t OnUpdateHandleInfo(IAudioProcessStream *processStream) override;
117 
118     /**
119      * Call LinkProcessStream when first create process or link other process with this endpoint.
120      * Here are cases:
121      *   case1: endpointStatus_ = UNLINKED, link not running process; UNLINKED-->IDEL & godown
122      *   case2: endpointStatus_ = UNLINKED, link running process; UNLINKED-->IDEL & godown
123      *   case3: endpointStatus_ = IDEL, link not running process; IDEL-->IDEL
124      *   case4: endpointStatus_ = IDEL, link running process; IDEL-->STARTING-->RUNNING
125      *   case5: endpointStatus_ = RUNNING; RUNNING-->RUNNING
126     */
127     int32_t LinkProcessStream(IAudioProcessStream *processStream) override;
128     void LinkProcessStreamExt(IAudioProcessStream *processStream,
129     const std::shared_ptr<OHAudioBuffer>& processBuffer);
130 
131     int32_t UnlinkProcessStream(IAudioProcessStream *processStream) override;
132 
133     int32_t GetPreferBufferInfo(uint32_t &totalSizeInframe, uint32_t &spanSizeInframe) override;
134 
135     void Dump(std::string &dumpString) override;
136 
137     std::string GetEndpointName() override;
GetEndpointType()138     EndpointType GetEndpointType() override
139     {
140         return endpointType_;
141     }
142     int32_t SetVolume(AudioStreamType streamType, float volume) override;
143 
144     int32_t ResolveBuffer(std::shared_ptr<OHAudioBuffer> &buffer) override;
145 
GetBuffer()146     std::shared_ptr<OHAudioBuffer> GetBuffer() override
147     {
148         return dstAudioBuffer_;
149     }
150 
151     // for inner-cap
152     bool ShouldInnerCap() override;
153     int32_t EnableFastInnerCap() override;
154     int32_t DisableFastInnerCap() override;
155 
156     int32_t InitDupStream();
157 
158     EndpointStatus GetStatus() override;
159 
160     void Release() override;
161 
GetDeviceInfo()162     DeviceInfo &GetDeviceInfo() override
163     {
164         return deviceInfo_;
165     }
166 
GetDeviceRole()167     DeviceRole GetDeviceRole() override
168     {
169         return deviceInfo_.deviceRole;
170     }
171 
172     float GetMaxAmplitude() override;
173     uint32_t GetLinkedProcessCount() override;
174 
175 private:
176     AudioProcessConfig GetInnerCapConfig();
177     void StartThread(const IAudioSinkAttr &attr);
178     void MixToDupStream(const std::vector<AudioStreamData> &srcDataList);
179     bool ConfigInputPoint(const DeviceInfo &deviceInfo);
180     int32_t PrepareDeviceBuffer(const DeviceInfo &deviceInfo);
181     int32_t GetAdapterBufferInfo(const DeviceInfo &deviceInfo);
182     void ReSyncPosition();
183     void RecordReSyncPosition();
184     void InitAudiobuffer(bool resetReadWritePos);
185     void ProcessData(const std::vector<AudioStreamData> &srcDataList, const AudioStreamData &dstData);
186     void ProcessSingleData(const AudioStreamData &srcData, const AudioStreamData &dstData);
187     void HandleZeroVolumeCheckEvent();
188     void HandleRendererDataParams(const AudioStreamData &srcData, const AudioStreamData &dstData);
189     int32_t HandleCapturerDataParams(const BufferDesc &writeBuf, const BufferDesc &readBuf,
190         const BufferDesc &convertedBuffer);
191     void ZeroVolumeCheck(const int32_t vol);
192     int64_t GetPredictNextReadTime(uint64_t posInFrame);
193     int64_t GetPredictNextWriteTime(uint64_t posInFrame);
194     bool PrepareNextLoop(uint64_t curWritePos, int64_t &wakeUpTime);
195     bool RecordPrepareNextLoop(uint64_t curReadPos, int64_t &wakeUpTime);
196 
197     /**
198      * @brief Get the current read position in frame and the read-time with it.
199      *
200      * @param frames the read position in frame
201      * @param nanoTime the time in nanosecond when device-sink start read the buffer
202     */
203     bool GetDeviceHandleInfo(uint64_t &frames, int64_t &nanoTime);
204     int32_t GetProcLastWriteDoneInfo(const std::shared_ptr<OHAudioBuffer> processBuffer, uint64_t curWriteFrame,
205         uint64_t &proHandleFrame, int64_t &proHandleTime);
206 
207     void CheckStandBy();
208     bool IsAnyProcessRunning();
209     bool IsAnyProcessRunningInner();
210     bool CheckAllBufferReady(int64_t checkTime, uint64_t curWritePos);
211     void WaitAllProcessReady(uint64_t curWritePos);
212     bool ProcessToEndpointDataHandle(uint64_t curWritePos);
213     void GetAllReadyProcessData(std::vector<AudioStreamData> &audioDataList);
214 
215     std::string GetStatusStr(EndpointStatus status);
216 
217     int32_t WriteToSpecialProcBuf(const std::shared_ptr<OHAudioBuffer> &procBuf, const BufferDesc &readBuf,
218         const BufferDesc &convertedBuffer, bool muteFlag);
219     void WriteToProcessBuffers(const BufferDesc &readBuf);
220     int32_t ReadFromEndpoint(uint64_t curReadPos);
221     bool KeepWorkloopRunning();
222 
223     void EndpointWorkLoopFuc();
224     void RecordEndpointWorkLoopFuc();
225 
226     // Call GetMmapHandlePosition in ipc may block more than a cycle, call it in another thread.
227     void AsyncGetPosTime();
228     bool DelayStopDevice();
229 
230     IMmapAudioRendererSink *GetFastSink(const DeviceInfo &deviceInfo, EndpointType type);
231     IMmapAudioCapturerSource *GetFastSource(const std::string &networkId, EndpointType type, IAudioSourceAttr &attr);
232 
233     void InitLatencyMeasurement();
234     void DeinitLatencyMeasurement();
235     void CheckPlaySignal(uint8_t *buffer, size_t bufferSize);
236     void CheckRecordSignal(uint8_t *buffer, size_t bufferSize);
237     void DfxOperation(BufferDesc &buffer, AudioSampleFormat format, AudioChannel channel) const;
238 
239     void CheckUpdateState(char *frame, uint64_t replyBytes);
240 
241     void ProcessUpdateAppsUidForPlayback();
242     void ProcessUpdateAppsUidForRecord();
243 
244     void WriterRenderStreamStandbySysEvent(uint32_t sessionId, int32_t standby);
245 private:
246     static constexpr int64_t ONE_MILLISECOND_DURATION = 1000000; // 1ms
247     static constexpr int64_t THREE_MILLISECOND_DURATION = 3000000; // 3ms
248     static constexpr int64_t WRITE_TO_HDI_AHEAD_TIME = -1000000; // ahead 1ms
249     static constexpr int32_t UPDATE_THREAD_TIMEOUT = 1000; // 1000ms
250     enum ThreadStatus : uint32_t {
251         WAITTING = 0,
252         SLEEPING,
253         INRUNNING
254     };
255     enum FastSinkType {
256         NONE_FAST_SINK = 0,
257         FAST_SINK_TYPE_NORMAL,
258         FAST_SINK_TYPE_REMOTE,
259         FAST_SINK_TYPE_VOIP,
260         FAST_SINK_TYPE_BLUETOOTH
261     };
262     enum FastSourceType {
263         NONE_FAST_SOURCE = 0,
264         FAST_SOURCE_TYPE_NORMAL,
265         FAST_SOURCE_TYPE_REMOTE,
266         FAST_SOURCE_TYPE_VOIP
267     };
268     // SamplingRate EncodingType SampleFormat Channel
269     DeviceInfo deviceInfo_;
270     AudioStreamInfo dstStreamInfo_;
271     EndpointType endpointType_;
272     int32_t id_ = 0;
273     std::mutex listLock_;
274     std::vector<IAudioProcessStream *> processList_;
275     std::vector<std::shared_ptr<OHAudioBuffer>> processBufferList_;
276     AudioProcessConfig clientConfig_;
277 
278     std::atomic<bool> isInited_ = false;
279 
280     // for inner-cap
281     std::mutex dupMutex_;
282     std::atomic<bool> isInnerCapEnabled_ = false;
283     uint32_t dupStreamIndex_ = 0;
284     std::shared_ptr<MockCallbacks> dupStreamCallback_ = nullptr;
285     std::shared_ptr<IRendererStream> dupStream_ = nullptr;
286     size_t dupBufferSize_ = 0;
287     std::unique_ptr<uint8_t []> dupBuffer_ = nullptr;
288     FILE *dumpC2SDup_ = nullptr; // client to server inner-cap dump file
289     std::string dupDumpName_ = "";
290 
291     IMmapAudioRendererSink *fastSink_ = nullptr;
292     IMmapAudioCapturerSource *fastSource_ = nullptr;
293     FastSinkType fastSinkType_ = NONE_FAST_SINK;
294     FastSourceType fastSourceType_ = NONE_FAST_SOURCE;
295 
296     LinearPosTimeModel readTimeModel_;
297     LinearPosTimeModel writeTimeModel_;
298 
299     int64_t spanDuration_ = 0; // nano second
300     int64_t serverAheadReadTime_ = 0;
301     int dstBufferFd_ = -1; // -1: invalid fd.
302     uint32_t dstTotalSizeInframe_ = 0;
303     uint32_t dstSpanSizeInframe_ = 0;
304     uint32_t dstByteSizePerFrame_ = 0;
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 delayStopTimeForZeroVolume_ = INT64_MAX;
311 
312     std::atomic<ThreadStatus> threadStatus_ = WAITTING;
313     std::thread endpointWorkThread_;
314     std::mutex loopThreadLock_;
315     std::condition_variable workThreadCV_;
316     int64_t lastHandleProcessTime_ = 0;
317 
318     std::thread updatePosTimeThread_;
319     std::mutex updateThreadLock_;
320     std::condition_variable updateThreadCV_;
321     std::atomic<bool> stopUpdateThread_ = false;
322 
323     std::atomic<uint64_t> posInFrame_ = 0;
324     std::atomic<int64_t> timeInNano_ = 0;
325 
326     bool isDeviceRunningInIdel_ = true; // will call start sink when linked.
327     bool needReSyncPosition_ = true;
328     FILE *dumpHdi_ = nullptr;
329     mutable int64_t volumeDataCount_ = 0;
330     std::string logUtilsTag_ = "";
331     std::string dumpHdiName_ = "";
332 
333     bool signalDetected_ = false;
334     bool latencyMeasEnabled_ = false;
335     size_t detectedTime_ = 0;
336     std::shared_ptr<SignalDetectAgent> signalDetectAgent_ = nullptr;
337 
338     // for get amplitude
339     float maxAmplitude_ = 0;
340     int64_t lastGetMaxAmplitudeTime_ = 0;
341     int64_t last10FrameStartTime_ = 0;
342     bool startUpdate_ = false;
343     int renderFrameNum_ = 0;
344 
345     bool zeroVolumeStopDevice_ = false;
346     bool isVolumeAlreadyZero_ = false;
347 };
348 
GenerateEndpointKey(DeviceInfo & deviceInfo,int32_t endpointFlag)349 std::string AudioEndpoint::GenerateEndpointKey(DeviceInfo &deviceInfo, int32_t endpointFlag)
350 {
351     // All primary sinks share one endpoint
352     int32_t endpointId = 0;
353     if (deviceInfo.deviceType == DEVICE_TYPE_BLUETOOTH_A2DP) {
354         endpointId = deviceInfo.deviceId;
355     }
356     return deviceInfo.networkId + "_" + std::to_string(endpointId) + "_" +
357         std::to_string(deviceInfo.deviceRole) + "_" + std::to_string(endpointFlag);
358 }
359 
CreateEndpoint(EndpointType type,uint64_t id,const AudioProcessConfig & clientConfig,const DeviceInfo & deviceInfo)360 std::shared_ptr<AudioEndpoint> AudioEndpoint::CreateEndpoint(EndpointType type, uint64_t id,
361     const AudioProcessConfig &clientConfig, const DeviceInfo &deviceInfo)
362 {
363     std::shared_ptr<AudioEndpoint> audioEndpoint = nullptr;
364     if (type == EndpointType::TYPE_INDEPENDENT && deviceInfo.deviceRole != INPUT_DEVICE &&
365          deviceInfo.networkId == LOCAL_NETWORK_ID) {
366         audioEndpoint = std::make_shared<AudioEndpointSeparate>(type, id, clientConfig.streamType);
367     } else {
368         audioEndpoint = std::make_shared<AudioEndpointInner>(type, id, clientConfig);
369     }
370     CHECK_AND_RETURN_RET_LOG(audioEndpoint != nullptr, nullptr, "Create AudioEndpoint failed.");
371 
372     if (!audioEndpoint->Config(deviceInfo)) {
373         AUDIO_ERR_LOG("Config AudioEndpoint failed.");
374         audioEndpoint = nullptr;
375     }
376     return audioEndpoint;
377 }
378 
AudioEndpointInner(EndpointType type,uint64_t id,const AudioProcessConfig & clientConfig)379 AudioEndpointInner::AudioEndpointInner(EndpointType type, uint64_t id,
380     const AudioProcessConfig &clientConfig) : endpointType_(type), id_(id), clientConfig_(clientConfig)
381 {
382     AUDIO_INFO_LOG("AudioEndpoint type:%{public}d", endpointType_);
383     if (clientConfig_.audioMode == AUDIO_MODE_PLAYBACK) {
384         logUtilsTag_ = "AudioEndpoint::Play";
385     } else {
386         logUtilsTag_ = "AudioEndpoint::Rec";
387     }
388 }
389 
GetEndpointName()390 std::string AudioEndpointInner::GetEndpointName()
391 {
392     return GenerateEndpointKey(deviceInfo_, id_);
393 }
394 
SetVolume(AudioStreamType streamType,float volume)395 int32_t AudioEndpointInner::SetVolume(AudioStreamType streamType, float volume)
396 {
397     // No need set hdi volume in shared stream mode.
398     return SUCCESS;
399 }
400 
ResolveBuffer(std::shared_ptr<OHAudioBuffer> & buffer)401 int32_t AudioEndpointInner::ResolveBuffer(std::shared_ptr<OHAudioBuffer> &buffer)
402 {
403     return SUCCESS;
404 }
405 
MockCallbacks(uint32_t streamIndex)406 MockCallbacks::MockCallbacks(uint32_t streamIndex) : streamIndex_(streamIndex)
407 {
408     AUDIO_INFO_LOG("DupStream %{public}u create MockCallbacks", streamIndex_);
409 }
410 
OnStatusUpdate(IOperation operation)411 void MockCallbacks::OnStatusUpdate(IOperation operation)
412 {
413     AUDIO_INFO_LOG("DupStream %{public}u recv operation: %{public}d", streamIndex_, operation);
414 }
415 
OnWriteData(size_t length)416 int32_t MockCallbacks::OnWriteData(size_t length)
417 {
418     Trace trace("DupStream::OnWriteData length " + std::to_string(length));
419     return SUCCESS;
420 }
421 
ShouldInnerCap()422 bool AudioEndpointInner::ShouldInnerCap()
423 {
424     bool shouldBecapped = false;
425     std::lock_guard<std::mutex> lock(listLock_);
426     for (uint32_t i = 0; i < processList_.size(); i++) {
427         if (processList_[i]->GetInnerCapState()) {
428             shouldBecapped = true;
429             break;
430         }
431     }
432     AUDIO_INFO_LOG("find endpoint inner-cap state: %{public}s", shouldBecapped ? "true" : "false");
433     return shouldBecapped;
434 }
435 
GetInnerCapConfig()436 AudioProcessConfig AudioEndpointInner::GetInnerCapConfig()
437 {
438     AudioProcessConfig processConfig;
439 
440     processConfig.appInfo.appPid = static_cast<int32_t>(getpid());
441     processConfig.appInfo.appUid = static_cast<int32_t>(getuid());
442 
443     processConfig.streamInfo = dstStreamInfo_;
444 
445     processConfig.audioMode = AUDIO_MODE_PLAYBACK;
446 
447     // processConfig.rendererInfo ?
448 
449     processConfig.streamType = STREAM_MUSIC;
450 
451     return processConfig;
452 }
453 
InitDupStream()454 int32_t AudioEndpointInner::InitDupStream()
455 {
456     std::lock_guard<std::mutex> lock(dupMutex_);
457     CHECK_AND_RETURN_RET_LOG(isInnerCapEnabled_ == false, SUCCESS, "already enabled");
458 
459     AudioProcessConfig processConfig = GetInnerCapConfig();
460     int32_t ret = IStreamManager::GetDupPlaybackManager().CreateRender(processConfig, dupStream_);
461     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS && dupStream_ != nullptr, ERR_OPERATION_FAILED, "Failed: %{public}d", ret);
462     dupStreamIndex_ = dupStream_->GetStreamIndex();
463 
464     dupStreamCallback_ = std::make_shared<MockCallbacks>(dupStreamIndex_);
465     dupStream_->RegisterStatusCallback(dupStreamCallback_);
466     dupStream_->RegisterWriteCallback(dupStreamCallback_);
467 
468     // eg: /data/local/tmp/LocalDevice6_0_c2s_dup_48000_2_1.pcm
469     AudioStreamInfo tempInfo = processConfig.streamInfo;
470     dupDumpName_ = GetEndpointName() + "_c2s_dup_" + std::to_string(tempInfo.samplingRate) + "_" +
471         std::to_string(tempInfo.channels) + "_" + std::to_string(tempInfo.format) + ".pcm";
472     DumpFileUtil::OpenDumpFile(DUMP_SERVER_PARA, dupDumpName_, &dumpC2SDup_);
473 
474     AUDIO_INFO_LOG("Dup Renderer %{public}d with Endpoint status: %{public}s", dupStreamIndex_,
475         GetStatusStr(endpointStatus_).c_str());
476 
477     // buffer init
478     dupBufferSize_ = dstSpanSizeInframe_ * dstByteSizePerFrame_; // each
479     CHECK_AND_RETURN_RET_LOG(dupBufferSize_ < dstAudioBuffer_->GetDataSize(), ERR_OPERATION_FAILED, "Init buffer fail");
480     dupBuffer_ = std::make_unique<uint8_t []>(dupBufferSize_);
481     ret = memset_s(reinterpret_cast<void *>(dupBuffer_.get()), dupBufferSize_, 0, dupBufferSize_);
482     if (ret != EOK) {
483         AUDIO_WARNING_LOG("memset buffer fail, ret %{public}d", ret);
484     }
485 
486     if (endpointStatus_ == RUNNING || (endpointStatus_ == IDEL && isDeviceRunningInIdel_)) {
487         int32_t audioId = deviceInfo_.deviceId;
488         AUDIO_INFO_LOG("Endpoint %{public}d is already running, let's start the dup stream", audioId);
489         dupStream_->Start();
490     }
491     // mark enabled last
492     isInnerCapEnabled_ = true;
493     return SUCCESS;
494 }
495 
EnableFastInnerCap()496 int32_t AudioEndpointInner::EnableFastInnerCap()
497 {
498     if (isInnerCapEnabled_) {
499         AUDIO_INFO_LOG("InnerCap is already enabled");
500         return SUCCESS;
501     }
502 
503     CHECK_AND_RETURN_RET_LOG(deviceInfo_.deviceRole == OUTPUT_DEVICE, ERR_INVALID_OPERATION, "Not output device!");
504     int32_t ret = InitDupStream();
505     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "Init dup stream failed");
506     return SUCCESS;
507 }
508 
DisableFastInnerCap()509 int32_t AudioEndpointInner::DisableFastInnerCap()
510 {
511     if (deviceInfo_.deviceRole != OUTPUT_DEVICE) {
512         return SUCCESS;
513     }
514     std::lock_guard<std::mutex> lock(dupMutex_);
515     if (!isInnerCapEnabled_) {
516         AUDIO_INFO_LOG("InnerCap is already disabled.");
517         return SUCCESS;
518     }
519     isInnerCapEnabled_ = false;
520     AUDIO_INFO_LOG("Disable dup renderer %{public}d with Endpoint status: %{public}s", dupStreamIndex_,
521         GetStatusStr(endpointStatus_).c_str());
522 
523     IStreamManager::GetDupPlaybackManager().ReleaseRender(dupStreamIndex_);
524     dupStream_ = nullptr;
525 
526     return SUCCESS;
527 }
528 
GetStatus()529 AudioEndpoint::EndpointStatus AudioEndpointInner::GetStatus()
530 {
531     AUDIO_INFO_LOG("AudioEndpoint get status:%{public}s", GetStatusStr(endpointStatus_).c_str());
532     return endpointStatus_.load();
533 }
534 
Release()535 void AudioEndpointInner::Release()
536 {
537     // Wait for thread end and then clear other data to avoid using any cleared data in thread.
538     AUDIO_INFO_LOG("Release enter.");
539     if (!isInited_.load()) {
540         AUDIO_WARNING_LOG("already released");
541         return;
542     }
543 
544     isInited_.store(false);
545     workThreadCV_.notify_all();
546     if (endpointWorkThread_.joinable()) {
547         AUDIO_DEBUG_LOG("AudioEndpoint join work thread start");
548         endpointWorkThread_.join();
549         AUDIO_DEBUG_LOG("AudioEndpoint join work thread end");
550     }
551 
552     stopUpdateThread_.store(true);
553     updateThreadCV_.notify_all();
554     if (updatePosTimeThread_.joinable()) {
555         AUDIO_DEBUG_LOG("AudioEndpoint join update thread start");
556         updatePosTimeThread_.join();
557         AUDIO_DEBUG_LOG("AudioEndpoint join update thread end");
558     }
559 
560     if (fastSink_ != nullptr) {
561         fastSink_->DeInit();
562         fastSink_ = nullptr;
563     }
564 
565     if (fastSource_ != nullptr) {
566         fastSource_->DeInit();
567         fastSource_ = nullptr;
568     }
569 
570     endpointStatus_.store(INVALID);
571 
572     if (dstAudioBuffer_ != nullptr) {
573         AUDIO_INFO_LOG("Set device buffer null");
574         dstAudioBuffer_ = nullptr;
575     }
576 
577     if (deviceInfo_.deviceRole == OUTPUT_DEVICE && isInnerCapEnabled_) {
578         DisableFastInnerCap();
579     }
580 
581     DumpFileUtil::CloseDumpFile(&dumpHdi_);
582 }
583 
~AudioEndpointInner()584 AudioEndpointInner::~AudioEndpointInner()
585 {
586     if (isInited_.load()) {
587         AudioEndpointInner::Release();
588     }
589     AUDIO_INFO_LOG("~AudioEndpoint()");
590 }
591 
Dump(std::string & dumpString)592 void AudioEndpointInner::Dump(std::string &dumpString)
593 {
594     // dump endpoint stream info
595     dumpString += "Endpoint stream info:\n";
596     AppendFormat(dumpString, "  - samplingRate: %d\n", dstStreamInfo_.samplingRate);
597     AppendFormat(dumpString, "  - channels: %u\n", dstStreamInfo_.channels);
598     AppendFormat(dumpString, "  - format: %u\n", dstStreamInfo_.format);
599     AppendFormat(dumpString, "  - sink type: %d\n", fastSinkType_);
600     AppendFormat(dumpString, "  - source type: %d\n", fastSourceType_);
601 
602     // dump status info
603     AppendFormat(dumpString, "  - Current endpoint status: %s\n", GetStatusStr(endpointStatus_).c_str());
604     if (dstAudioBuffer_ != nullptr) {
605         AppendFormat(dumpString, "  - Currend hdi read position: %u\n", dstAudioBuffer_->GetCurReadFrame());
606         AppendFormat(dumpString, "  - Currend hdi write position: %u\n", dstAudioBuffer_->GetCurWriteFrame());
607     }
608 
609     // dump linked process info
610     std::lock_guard<std::mutex> lock(listLock_);
611     AppendFormat(dumpString, "  - linked process:: %zu\n", processBufferList_.size());
612     for (auto item : processBufferList_) {
613         AppendFormat(dumpString, "  - process read position: %u\n", item->GetCurReadFrame());
614         AppendFormat(dumpString, "  - process write position: %u\n", item->GetCurWriteFrame());
615     }
616     dumpString += "\n";
617 }
618 
ConfigInputPoint(const DeviceInfo & deviceInfo)619 bool AudioEndpointInner::ConfigInputPoint(const DeviceInfo &deviceInfo)
620 {
621     AUDIO_INFO_LOG("ConfigInputPoint enter.");
622     IAudioSourceAttr attr = {};
623     attr.sampleRate = dstStreamInfo_.samplingRate;
624     attr.channel = dstStreamInfo_.channels;
625     attr.format = ConvertToHdiAdapterFormat(dstStreamInfo_.format);
626     attr.deviceNetworkId = deviceInfo.networkId.c_str();
627     attr.deviceType = deviceInfo.deviceType;
628     attr.audioStreamFlag = endpointType_ == TYPE_VOIP_MMAP ? AUDIO_FLAG_VOIP_FAST : AUDIO_FLAG_MMAP;
629     attr.sourceType = endpointType_ == TYPE_VOIP_MMAP ? SOURCE_TYPE_VOICE_COMMUNICATION : SOURCE_TYPE_MIC;
630 
631     fastSource_ = GetFastSource(deviceInfo.networkId, endpointType_, attr);
632 
633     if (deviceInfo.networkId == LOCAL_NETWORK_ID) {
634         attr.adapterName = "primary";
635         fastSource_ = FastAudioCapturerSource::GetInstance();
636     } else {
637 #ifdef DAUDIO_ENABLE
638         attr.adapterName = "remote";
639         fastSource_ = RemoteFastAudioCapturerSource::GetInstance(deviceInfo.networkId);
640 #endif
641     }
642     CHECK_AND_RETURN_RET_LOG(fastSource_ != nullptr, false, "ConfigInputPoint GetInstance failed.");
643 
644     int32_t err = fastSource_->Init(attr);
645     if (err != SUCCESS || !fastSource_->IsInited()) {
646         AUDIO_ERR_LOG("init remote fast fail, err %{public}d.", err);
647         fastSource_ = nullptr;
648         return false;
649     }
650     if (PrepareDeviceBuffer(deviceInfo) != SUCCESS) {
651         fastSource_->DeInit();
652         fastSource_ = nullptr;
653         return false;
654     }
655 
656     bool ret = writeTimeModel_.ConfigSampleRate(dstStreamInfo_.samplingRate);
657     CHECK_AND_RETURN_RET_LOG(ret != false, false, "Config LinearPosTimeModel failed.");
658 
659     endpointStatus_ = UNLINKED;
660     isInited_.store(true);
661     endpointWorkThread_ = std::thread([this] { this->RecordEndpointWorkLoopFuc(); });
662     pthread_setname_np(endpointWorkThread_.native_handle(), "OS_AudioEpLoop");
663 
664     updatePosTimeThread_ = std::thread([this] { this->AsyncGetPosTime(); });
665     pthread_setname_np(updatePosTimeThread_.native_handle(), "OS_AudioEpUpdate");
666 
667     // eg: input_endpoint_hdi_audio_8_0_20240527202236189_48000_2_1.pcm
668     dumpHdiName_ = "input_endpoint_hdi_audio_" + std::to_string(attr.deviceType) + '_' +
669         std::to_string(endpointType_) + '_' + GetTime() +
670         '_' + std::to_string(attr.sampleRate) + "_" +
671         std::to_string(attr.channel) + "_" + std::to_string(attr.format) + ".pcm";
672     DumpFileUtil::OpenDumpFile(DUMP_SERVER_PARA, dumpHdiName_, &dumpHdi_);
673     return true;
674 }
675 
GetFastSource(const std::string & networkId,EndpointType type,IAudioSourceAttr & attr)676 IMmapAudioCapturerSource *AudioEndpointInner::GetFastSource(const std::string &networkId, EndpointType type,
677     IAudioSourceAttr &attr)
678 {
679     AUDIO_INFO_LOG("Network id %{public}s, endpoint type %{public}d", networkId.c_str(), type);
680 #ifdef DAUDIO_ENABLE
681     if (networkId != LOCAL_NETWORK_ID) {
682         attr.adapterName = "remote";
683         fastSourceType_ = type == AudioEndpoint::TYPE_MMAP ? FAST_SOURCE_TYPE_REMOTE : FAST_SOURCE_TYPE_VOIP;
684         // Distributed only requires a singleton because there won't be both voip and regular fast simultaneously
685         return RemoteFastAudioCapturerSource::GetInstance(networkId);
686     }
687 #endif
688 
689     attr.adapterName = "primary";
690     if (type == AudioEndpoint::TYPE_MMAP) {
691         fastSourceType_ = FAST_SOURCE_TYPE_NORMAL;
692         return FastAudioCapturerSource::GetInstance();
693     } else if (type == AudioEndpoint::TYPE_VOIP_MMAP) {
694         fastSourceType_ = FAST_SOURCE_TYPE_VOIP;
695         return FastAudioCapturerSource::GetVoipInstance();
696     }
697     return nullptr;
698 }
699 
StartThread(const IAudioSinkAttr & attr)700 void AudioEndpointInner::StartThread(const IAudioSinkAttr &attr)
701 {
702     endpointStatus_ = UNLINKED;
703     isInited_.store(true);
704     endpointWorkThread_ = std::thread([this] { this->EndpointWorkLoopFuc(); });
705     pthread_setname_np(endpointWorkThread_.native_handle(), "OS_AudioEpLoop");
706 
707     updatePosTimeThread_ = std::thread([this] { this->AsyncGetPosTime(); });
708     pthread_setname_np(updatePosTimeThread_.native_handle(), "OS_AudioEpUpdate");
709 
710     // eg: endpoint_hdi_audio_8_0_20240527202236189_48000_2_1.pcm
711     dumpHdiName_ = "endpoint_hdi_audio_" + std::to_string(attr.deviceType) + '_' + std::to_string(endpointType_) +
712         '_' + GetTime() + '_' +
713         std::to_string(attr.sampleRate) + "_" +
714         std::to_string(attr.channel) + "_" + std::to_string(attr.format) + ".pcm";
715     DumpFileUtil::OpenDumpFile(DUMP_SERVER_PARA, dumpHdiName_, &dumpHdi_);
716 }
717 
Config(const DeviceInfo & deviceInfo)718 bool AudioEndpointInner::Config(const DeviceInfo &deviceInfo)
719 {
720     AUDIO_INFO_LOG("Config enter, deviceRole %{public}d.", deviceInfo.deviceRole);
721     deviceInfo_ = deviceInfo;
722     bool res = deviceInfo_.audioStreamInfo.CheckParams();
723     CHECK_AND_RETURN_RET_LOG(res, false, "samplingRate or channels size is 0");
724 
725     dstStreamInfo_ = {
726         *deviceInfo.audioStreamInfo.samplingRate.rbegin(),
727         deviceInfo.audioStreamInfo.encoding,
728         deviceInfo.audioStreamInfo.format,
729         *deviceInfo.audioStreamInfo.channels.rbegin()
730     };
731     dstStreamInfo_.channelLayout = deviceInfo.audioStreamInfo.channelLayout;
732 
733     if (deviceInfo.deviceRole == INPUT_DEVICE) {
734         return ConfigInputPoint(deviceInfo);
735     }
736 
737     fastSink_ = GetFastSink(deviceInfo, endpointType_);
738     CHECK_AND_RETURN_RET_LOG(fastSink_ != nullptr, false, "Get fastSink instance failed");
739 
740     IAudioSinkAttr attr = {};
741     attr.adapterName = deviceInfo.networkId == LOCAL_NETWORK_ID ? "primary" : "remote";
742     attr.sampleRate = dstStreamInfo_.samplingRate; // 48000hz
743     attr.channel = dstStreamInfo_.channels; // STEREO = 2
744     attr.format = ConvertToHdiAdapterFormat(dstStreamInfo_.format); // SAMPLE_S16LE = 1
745     attr.deviceNetworkId = deviceInfo.networkId.c_str();
746     attr.deviceType = static_cast<int32_t>(deviceInfo.deviceType);
747     attr.audioStreamFlag = endpointType_ == TYPE_VOIP_MMAP ? AUDIO_FLAG_VOIP_FAST : AUDIO_FLAG_MMAP;
748 
749     fastSink_->Init(attr);
750     if (!fastSink_->IsInited()) {
751         fastSink_ = nullptr;
752         return false;
753     }
754     if (PrepareDeviceBuffer(deviceInfo) != SUCCESS) {
755         fastSink_->DeInit();
756         fastSink_ = nullptr;
757         return false;
758     }
759 
760     float initVolume = 1.0; // init volume to 1.0
761     fastSink_->SetVolume(initVolume, initVolume);
762 
763     bool ret = readTimeModel_.ConfigSampleRate(dstStreamInfo_.samplingRate);
764     CHECK_AND_RETURN_RET_LOG(ret != false, false, "Config LinearPosTimeModel failed.");
765 
766     StartThread(attr);
767     return true;
768 }
769 
GetFastSink(const DeviceInfo & deviceInfo,EndpointType type)770 IMmapAudioRendererSink *AudioEndpointInner::GetFastSink(const DeviceInfo &deviceInfo, EndpointType type)
771 {
772     AUDIO_INFO_LOG("Network id %{public}s, endpoint type %{public}d", deviceInfo.networkId.c_str(), type);
773     if (deviceInfo.networkId != LOCAL_NETWORK_ID) {
774 #ifdef DAUDIO_ENABLE
775         fastSinkType_ = type == AudioEndpoint::TYPE_MMAP ? FAST_SINK_TYPE_REMOTE : FAST_SINK_TYPE_VOIP;
776         // Distributed only requires a singleton because there won't be both voip and regular fast simultaneously
777         return RemoteFastAudioRendererSink::GetInstance(deviceInfo.networkId);
778 #endif
779     }
780 
781     if (deviceInfo.deviceType == DEVICE_TYPE_BLUETOOTH_A2DP && deviceInfo.a2dpOffloadFlag != A2DP_OFFLOAD) {
782         fastSinkType_ = FAST_SINK_TYPE_BLUETOOTH;
783         return BluetoothRendererSink::GetMmapInstance();
784     }
785 
786     if (type == AudioEndpoint::TYPE_MMAP) {
787         fastSinkType_ = FAST_SINK_TYPE_NORMAL;
788         return FastAudioRendererSink::GetInstance();
789     } else if (type == AudioEndpoint::TYPE_VOIP_MMAP) {
790         fastSinkType_ = FAST_SINK_TYPE_VOIP;
791         return FastAudioRendererSink::GetVoipInstance();
792     }
793     return nullptr;
794 }
795 
GetAdapterBufferInfo(const DeviceInfo & deviceInfo)796 int32_t AudioEndpointInner::GetAdapterBufferInfo(const DeviceInfo &deviceInfo)
797 {
798     int32_t ret = 0;
799     AUDIO_INFO_LOG("GetAdapterBufferInfo enter, deviceRole %{public}d.", deviceInfo.deviceRole);
800     if (deviceInfo.deviceRole == INPUT_DEVICE) {
801         CHECK_AND_RETURN_RET_LOG(fastSource_ != nullptr, ERR_INVALID_HANDLE,
802             "fast source is null.");
803         ret = fastSource_->GetMmapBufferInfo(dstBufferFd_, dstTotalSizeInframe_, dstSpanSizeInframe_,
804         dstByteSizePerFrame_);
805     } else {
806         CHECK_AND_RETURN_RET_LOG(fastSink_ != nullptr, ERR_INVALID_HANDLE, "fast sink is null.");
807         ret = fastSink_->GetMmapBufferInfo(dstBufferFd_, dstTotalSizeInframe_, dstSpanSizeInframe_,
808         dstByteSizePerFrame_);
809     }
810 
811     if (ret != SUCCESS || dstBufferFd_ == -1 || dstTotalSizeInframe_ == 0 || dstSpanSizeInframe_ == 0 ||
812         dstByteSizePerFrame_ == 0) {
813         AUDIO_ERR_LOG("get mmap buffer info fail, ret %{public}d, dstBufferFd %{public}d, \
814             dstTotalSizeInframe %{public}d, dstSpanSizeInframe %{public}d, dstByteSizePerFrame %{public}d.",
815             ret, dstBufferFd_, dstTotalSizeInframe_, dstSpanSizeInframe_, dstByteSizePerFrame_);
816         return ERR_ILLEGAL_STATE;
817     }
818     AUDIO_DEBUG_LOG("end, fd %{public}d.", dstBufferFd_);
819     return SUCCESS;
820 }
821 
PrepareDeviceBuffer(const DeviceInfo & deviceInfo)822 int32_t AudioEndpointInner::PrepareDeviceBuffer(const DeviceInfo &deviceInfo)
823 {
824     AUDIO_INFO_LOG("enter, deviceRole %{public}d.", deviceInfo.deviceRole);
825     if (dstAudioBuffer_ != nullptr) {
826         AUDIO_INFO_LOG("endpoint buffer is preapred, fd:%{public}d", dstBufferFd_);
827         return SUCCESS;
828     }
829 
830     int32_t ret = GetAdapterBufferInfo(deviceInfo);
831     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED,
832         "get adapter buffer Info fail, ret %{public}d.", ret);
833 
834     // spanDuration_ may be less than the correct time of dstSpanSizeInframe_.
835     spanDuration_ = static_cast<int64_t>(dstSpanSizeInframe_) * AUDIO_NS_PER_SECOND /
836         static_cast<int64_t>(dstStreamInfo_.samplingRate);
837     int64_t temp = spanDuration_ / 5 * 3; // 3/5 spanDuration
838     serverAheadReadTime_ = temp < ONE_MILLISECOND_DURATION ? ONE_MILLISECOND_DURATION : temp; // at least 1ms ahead.
839     AUDIO_DEBUG_LOG("panDuration %{public}" PRIu64" ns, serverAheadReadTime %{public}" PRIu64" ns.",
840         spanDuration_, serverAheadReadTime_);
841 
842     CHECK_AND_RETURN_RET_LOG(spanDuration_ > 0 && spanDuration_ < MAX_SPAN_DURATION_NS,
843         ERR_INVALID_PARAM, "mmap span info error, spanDuration %{public}" PRIu64".", spanDuration_);
844     dstAudioBuffer_ = OHAudioBuffer::CreateFromRemote(dstTotalSizeInframe_, dstSpanSizeInframe_, dstByteSizePerFrame_,
845         AUDIO_SERVER_ONLY, dstBufferFd_, OHAudioBuffer::INVALID_BUFFER_FD);
846     CHECK_AND_RETURN_RET_LOG(dstAudioBuffer_ != nullptr && dstAudioBuffer_->GetBufferHolder() ==
847         AudioBufferHolder::AUDIO_SERVER_ONLY, ERR_ILLEGAL_STATE, "create buffer from remote fail.");
848 
849     if (dstAudioBuffer_ == nullptr || dstAudioBuffer_->GetStreamStatus() == nullptr) {
850         AUDIO_ERR_LOG("The stream status is null!");
851         return ERR_INVALID_PARAM;
852     }
853 
854     dstAudioBuffer_->GetStreamStatus()->store(StreamStatus::STREAM_IDEL);
855 
856     // clear data buffer
857     ret = memset_s(dstAudioBuffer_->GetDataBase(), dstAudioBuffer_->GetDataSize(), 0, dstAudioBuffer_->GetDataSize());
858     if (ret != EOK) {
859         AUDIO_WARNING_LOG("memset buffer fail, ret %{public}d, fd %{public}d.", ret, dstBufferFd_);
860     }
861     InitAudiobuffer(true);
862 
863     AUDIO_DEBUG_LOG("end, fd %{public}d.", dstBufferFd_);
864     return SUCCESS;
865 }
866 
InitAudiobuffer(bool resetReadWritePos)867 void AudioEndpointInner::InitAudiobuffer(bool resetReadWritePos)
868 {
869     CHECK_AND_RETURN_LOG((dstAudioBuffer_ != nullptr), "dst audio buffer is null.");
870     if (resetReadWritePos) {
871         dstAudioBuffer_->ResetCurReadWritePos(0, 0);
872     }
873 
874     uint32_t spanCount = dstAudioBuffer_->GetSpanCount();
875     for (uint32_t i = 0; i < spanCount; i++) {
876         SpanInfo *spanInfo = dstAudioBuffer_->GetSpanInfoByIndex(i);
877         CHECK_AND_RETURN_LOG(spanInfo != nullptr, "InitAudiobuffer failed.");
878         if (deviceInfo_.deviceRole == INPUT_DEVICE) {
879             spanInfo->spanStatus = SPAN_WRITE_DONE;
880         } else {
881             spanInfo->spanStatus = SPAN_READ_DONE;
882         }
883         spanInfo->offsetInFrame = 0;
884 
885         spanInfo->readStartTime = 0;
886         spanInfo->readDoneTime = 0;
887 
888         spanInfo->writeStartTime = 0;
889         spanInfo->writeDoneTime = 0;
890 
891         spanInfo->volumeStart = 1 << VOLUME_SHIFT_NUMBER; // 65536 for initialize
892         spanInfo->volumeEnd = 1 << VOLUME_SHIFT_NUMBER; // 65536 for initialize
893         spanInfo->isMute = false;
894     }
895     return;
896 }
897 
GetPreferBufferInfo(uint32_t & totalSizeInframe,uint32_t & spanSizeInframe)898 int32_t AudioEndpointInner::GetPreferBufferInfo(uint32_t &totalSizeInframe, uint32_t &spanSizeInframe)
899 {
900     totalSizeInframe = dstTotalSizeInframe_;
901     spanSizeInframe = dstSpanSizeInframe_;
902     return SUCCESS;
903 }
904 
IsAnyProcessRunning()905 bool AudioEndpointInner::IsAnyProcessRunning()
906 {
907     std::lock_guard<std::mutex> lock(listLock_);
908     return IsAnyProcessRunningInner();
909 }
910 
911 // Should be called with AudioEndpointInner::listLock_ locked
IsAnyProcessRunningInner()912 bool AudioEndpointInner::IsAnyProcessRunningInner()
913 {
914     bool isRunning = false;
915     for (size_t i = 0; i < processBufferList_.size(); i++) {
916         if (processBufferList_[i]->GetStreamStatus() &&
917             processBufferList_[i]->GetStreamStatus()->load() == STREAM_RUNNING) {
918             isRunning = true;
919             break;
920         }
921     }
922     return isRunning;
923 }
924 
RecordReSyncPosition()925 void AudioEndpointInner::RecordReSyncPosition()
926 {
927     AUDIO_INFO_LOG("RecordReSyncPosition enter.");
928     uint64_t curHdiWritePos = 0;
929     int64_t writeTime = 0;
930     CHECK_AND_RETURN_LOG(GetDeviceHandleInfo(curHdiWritePos, writeTime),
931         "get device handle info fail.");
932     AUDIO_DEBUG_LOG("get capturer info, curHdiWritePos %{public}" PRIu64", writeTime %{public}" PRId64".",
933         curHdiWritePos, writeTime);
934     int64_t temp = ClockTime::GetCurNano() - writeTime;
935     if (temp > spanDuration_) {
936         AUDIO_WARNING_LOG("GetDeviceHandleInfo cost long time %{public}" PRIu64".", temp);
937     }
938 
939     writeTimeModel_.ResetFrameStamp(curHdiWritePos, writeTime);
940     uint64_t nextDstReadPos = curHdiWritePos;
941     uint64_t nextDstWritePos = curHdiWritePos;
942     InitAudiobuffer(false);
943     int32_t ret = dstAudioBuffer_->ResetCurReadWritePos(nextDstReadPos, nextDstWritePos);
944     CHECK_AND_RETURN_LOG(ret == SUCCESS, "ResetCurReadWritePos failed.");
945 
946     SpanInfo *nextReadSapn = dstAudioBuffer_->GetSpanInfo(nextDstReadPos);
947     CHECK_AND_RETURN_LOG(nextReadSapn != nullptr, "GetSpanInfo failed.");
948     nextReadSapn->offsetInFrame = nextDstReadPos;
949     nextReadSapn->spanStatus = SpanStatus::SPAN_WRITE_DONE;
950 }
951 
ReSyncPosition()952 void AudioEndpointInner::ReSyncPosition()
953 {
954     Trace loopTrace("AudioEndpoint::ReSyncPosition");
955     uint64_t curHdiReadPos = 0;
956     int64_t readTime = 0;
957     bool res = GetDeviceHandleInfo(curHdiReadPos, readTime);
958     CHECK_AND_RETURN_LOG(res, "ReSyncPosition call GetDeviceHandleInfo failed.");
959     int64_t curTime = ClockTime::GetCurNano();
960     int64_t temp = curTime - readTime;
961     if (temp > spanDuration_) {
962         AUDIO_ERR_LOG("GetDeviceHandleInfo may cost long time.");
963     }
964 
965     readTimeModel_.ResetFrameStamp(curHdiReadPos, readTime);
966     uint64_t nextDstWritePos = curHdiReadPos + dstSpanSizeInframe_;
967     InitAudiobuffer(false);
968     int32_t ret = dstAudioBuffer_->ResetCurReadWritePos(nextDstWritePos, nextDstWritePos);
969     CHECK_AND_RETURN_LOG(ret == SUCCESS, "ResetCurReadWritePos failed.");
970 
971     SpanInfo *nextWriteSapn = dstAudioBuffer_->GetSpanInfo(nextDstWritePos);
972     CHECK_AND_RETURN_LOG(nextWriteSapn != nullptr, "GetSpanInfo failed.");
973     nextWriteSapn->offsetInFrame = nextDstWritePos;
974     nextWriteSapn->spanStatus = SpanStatus::SPAN_READ_DONE;
975     return;
976 }
977 
StartDevice()978 bool AudioEndpointInner::StartDevice()
979 {
980     AUDIO_INFO_LOG("StartDevice enter.");
981     // how to modify the status while unlinked and started?
982     CHECK_AND_RETURN_RET_LOG(endpointStatus_ == IDEL, false, "Endpoint status is %{public}s",
983         GetStatusStr(endpointStatus_).c_str());
984     endpointStatus_ = STARTING;
985     if ((deviceInfo_.deviceRole == INPUT_DEVICE && (fastSource_ == nullptr || fastSource_->Start() != SUCCESS)) ||
986         (deviceInfo_.deviceRole == OUTPUT_DEVICE && (fastSink_ == nullptr || fastSink_->Start() != SUCCESS))) {
987         HandleStartDeviceFailed();
988         return false;
989     }
990     isStarted_ = true;
991 
992     if (isInnerCapEnabled_) {
993         Trace trace("AudioEndpointInner::StartDupStream");
994         std::lock_guard<std::mutex> lock(dupMutex_);
995         if (dupStream_ != nullptr) {
996             dupStream_->Start();
997         }
998     }
999 
1000     std::unique_lock<std::mutex> lock(loopThreadLock_);
1001     needReSyncPosition_ = true;
1002     endpointStatus_ = IsAnyProcessRunning() ? RUNNING : IDEL;
1003     workThreadCV_.notify_all();
1004     AUDIO_DEBUG_LOG("StartDevice out, status is %{public}s", GetStatusStr(endpointStatus_).c_str());
1005     return true;
1006 }
1007 
HandleStartDeviceFailed()1008 void AudioEndpointInner::HandleStartDeviceFailed()
1009 {
1010     AUDIO_ERR_LOG("Start failed for %{public}d, endpoint type %{public}u, process list size: %{public}zu.",
1011         deviceInfo_.deviceRole, endpointType_, processList_.size());
1012     std::lock_guard<std::mutex> lock(listLock_);
1013     isStarted_ = false;
1014     if (processList_.size() <= 1) { // The endpoint only has the current stream
1015         endpointStatus_ = UNLINKED;
1016     } else {
1017         endpointStatus_ = IDEL;
1018     }
1019     workThreadCV_.notify_all();
1020 }
1021 
1022 // will not change state to stopped
DelayStopDevice()1023 bool AudioEndpointInner::DelayStopDevice()
1024 {
1025     AUDIO_INFO_LOG("Status:%{public}s", GetStatusStr(endpointStatus_).c_str());
1026 
1027     // Clear data buffer to avoid noise in some case.
1028     if (dstAudioBuffer_ != nullptr) {
1029         int32_t ret = memset_s(dstAudioBuffer_->GetDataBase(), dstAudioBuffer_->GetDataSize(), 0,
1030             dstAudioBuffer_->GetDataSize());
1031         if (ret != EOK) {
1032             AUDIO_WARNING_LOG("reset buffer fail, ret %{public}d.", ret);
1033         }
1034     }
1035 
1036     if (isInnerCapEnabled_) {
1037         Trace trace("AudioEndpointInner::StopDupStreamInDelay");
1038         std::lock_guard<std::mutex> lock(dupMutex_);
1039         if (dupStream_ != nullptr) {
1040             dupStream_->Stop();
1041         }
1042     }
1043 
1044     if (deviceInfo_.deviceRole == INPUT_DEVICE) {
1045         CHECK_AND_RETURN_RET_LOG(fastSource_ != nullptr && fastSource_->Stop() == SUCCESS,
1046             false, "Source stop failed.");
1047     } else {
1048         CHECK_AND_RETURN_RET_LOG(endpointStatus_ == IDEL && fastSink_ != nullptr && fastSink_->Stop() == SUCCESS,
1049             false, "Sink stop failed.");
1050     }
1051     isStarted_ = false;
1052     return true;
1053 }
1054 
StopDevice()1055 bool AudioEndpointInner::StopDevice()
1056 {
1057     DeinitLatencyMeasurement();
1058 
1059     AUDIO_INFO_LOG("StopDevice with status:%{public}s", GetStatusStr(endpointStatus_).c_str());
1060     // todo
1061     endpointStatus_ = STOPPING;
1062     // Clear data buffer to avoid noise in some case.
1063     if (dstAudioBuffer_ != nullptr) {
1064         int32_t ret = memset_s(dstAudioBuffer_->GetDataBase(), dstAudioBuffer_->GetDataSize(), 0,
1065             dstAudioBuffer_->GetDataSize());
1066         AUDIO_INFO_LOG("StopDevice clear buffer ret:%{public}d", ret);
1067     }
1068 
1069     if (isInnerCapEnabled_) {
1070         Trace trace("AudioEndpointInner::StopDupStream");
1071         std::lock_guard<std::mutex> lock(dupMutex_);
1072         if (dupStream_ != nullptr) {
1073             dupStream_->Stop();
1074         }
1075     }
1076 
1077     if (deviceInfo_.deviceRole == INPUT_DEVICE) {
1078         CHECK_AND_RETURN_RET_LOG(fastSource_ != nullptr && fastSource_->Stop() == SUCCESS,
1079             false, "Source stop failed.");
1080     } else {
1081         CHECK_AND_RETURN_RET_LOG(fastSink_ != nullptr && fastSink_->Stop() == SUCCESS,
1082             false, "Sink stop failed.");
1083     }
1084     endpointStatus_ = STOPPED;
1085     isStarted_ = false;
1086     return true;
1087 }
1088 
OnStart(IAudioProcessStream * processStream)1089 int32_t AudioEndpointInner::OnStart(IAudioProcessStream *processStream)
1090 {
1091     InitLatencyMeasurement();
1092     // Prevents the audio from immediately stopping at 0 volume on start
1093     delayStopTimeForZeroVolume_ = ClockTime::GetCurNano() + DELAY_STOP_HDI_TIME_FOR_ZERO_VOLUME_NS;
1094     AUDIO_PRERELEASE_LOGI("OnStart endpoint status:%{public}s", GetStatusStr(endpointStatus_).c_str());
1095     if (endpointStatus_ == RUNNING) {
1096         AUDIO_INFO_LOG("OnStart find endpoint already in RUNNING.");
1097         return SUCCESS;
1098     }
1099     if (endpointStatus_ == IDEL) {
1100         // call sink start
1101         if (!isStarted_) {
1102             CHECK_AND_RETURN_RET_LOG(StartDevice(), ERR_OPERATION_FAILED, "StartDevice failed");
1103         }
1104     }
1105 
1106     endpointStatus_ = RUNNING;
1107     delayStopTime_ = INT64_MAX;
1108     return SUCCESS;
1109 }
1110 
OnPause(IAudioProcessStream * processStream)1111 int32_t AudioEndpointInner::OnPause(IAudioProcessStream *processStream)
1112 {
1113     AUDIO_PRERELEASE_LOGI("OnPause endpoint status:%{public}s", GetStatusStr(endpointStatus_).c_str());
1114     if (endpointStatus_ == RUNNING) {
1115         endpointStatus_ = IsAnyProcessRunning() ? RUNNING : IDEL;
1116     }
1117     if (endpointStatus_ == IDEL) {
1118         // delay call sink stop when no process running
1119         AUDIO_PRERELEASE_LOGI("OnPause status is IDEL, need delay call stop");
1120         delayStopTime_ = ClockTime::GetCurNano() + DELAY_STOP_HDI_TIME;
1121     }
1122     // todo
1123     return SUCCESS;
1124 }
1125 
GetProcLastWriteDoneInfo(const std::shared_ptr<OHAudioBuffer> processBuffer,uint64_t curWriteFrame,uint64_t & proHandleFrame,int64_t & proHandleTime)1126 int32_t AudioEndpointInner::GetProcLastWriteDoneInfo(const std::shared_ptr<OHAudioBuffer> processBuffer,
1127     uint64_t curWriteFrame, uint64_t &proHandleFrame, int64_t &proHandleTime)
1128 {
1129     CHECK_AND_RETURN_RET_LOG(processBuffer != nullptr, ERR_INVALID_HANDLE, "Process found but buffer is null");
1130     uint64_t curReadFrame = processBuffer->GetCurReadFrame();
1131     SpanInfo *curWriteSpan = processBuffer->GetSpanInfo(curWriteFrame);
1132     CHECK_AND_RETURN_RET_LOG(curWriteSpan != nullptr, ERR_INVALID_HANDLE,
1133         "curWriteSpan of curWriteFrame %{public}" PRIu64" is null", curWriteFrame);
1134     if (curWriteSpan->spanStatus == SpanStatus::SPAN_WRITE_DONE || curWriteFrame < dstSpanSizeInframe_ ||
1135         curWriteFrame < curReadFrame) {
1136         proHandleFrame = curWriteFrame;
1137         proHandleTime = curWriteSpan->writeDoneTime;
1138     } else {
1139         int32_t ret = GetProcLastWriteDoneInfo(processBuffer, curWriteFrame - dstSpanSizeInframe_,
1140             proHandleFrame, proHandleTime);
1141         CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret,
1142             "get process last write done info fail, ret %{public}d.", ret);
1143     }
1144 
1145     AUDIO_INFO_LOG("GetProcLastWriteDoneInfo end, curWriteFrame %{public}" PRIu64", proHandleFrame %{public}" PRIu64", "
1146         "proHandleTime %{public}" PRId64".", curWriteFrame, proHandleFrame, proHandleTime);
1147     return SUCCESS;
1148 }
1149 
OnUpdateHandleInfo(IAudioProcessStream * processStream)1150 int32_t AudioEndpointInner::OnUpdateHandleInfo(IAudioProcessStream *processStream)
1151 {
1152     Trace trace("AudioEndpoint::OnUpdateHandleInfo");
1153     bool isFind = false;
1154     std::lock_guard<std::mutex> lock(listLock_);
1155     auto processItr = processList_.begin();
1156     while (processItr != processList_.end()) {
1157         if (*processItr != processStream) {
1158             processItr++;
1159             continue;
1160         }
1161         std::shared_ptr<OHAudioBuffer> processBuffer = (*processItr)->GetStreamBuffer();
1162         CHECK_AND_RETURN_RET_LOG(processBuffer != nullptr, ERR_OPERATION_FAILED, "Process found but buffer is null");
1163         uint64_t proHandleFrame = 0;
1164         int64_t proHandleTime = 0;
1165         if (deviceInfo_.deviceRole == INPUT_DEVICE) {
1166             uint64_t curWriteFrame = processBuffer->GetCurWriteFrame();
1167             int32_t ret = GetProcLastWriteDoneInfo(processBuffer, curWriteFrame, proHandleFrame, proHandleTime);
1168             CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret,
1169                 "get process last write done info fail, ret %{public}d.", ret);
1170             processBuffer->SetHandleInfo(proHandleFrame, proHandleTime);
1171         } else {
1172             // For output device, handle info is updated in CheckAllBufferReady
1173             processBuffer->GetHandleInfo(proHandleFrame, proHandleTime);
1174         }
1175 
1176         isFind = true;
1177         break;
1178     }
1179     CHECK_AND_RETURN_RET_LOG(isFind, ERR_OPERATION_FAILED, "Can not find any process to UpdateHandleInfo");
1180     return SUCCESS;
1181 }
1182 
LinkProcessStream(IAudioProcessStream * processStream)1183 int32_t AudioEndpointInner::LinkProcessStream(IAudioProcessStream *processStream)
1184 {
1185     CHECK_AND_RETURN_RET_LOG(processStream != nullptr, ERR_INVALID_PARAM, "IAudioProcessStream is null");
1186     std::shared_ptr<OHAudioBuffer> processBuffer = processStream->GetStreamBuffer();
1187     processBuffer->SetSessionId(processStream->GetAudioSessionId());
1188     CHECK_AND_RETURN_RET_LOG(processBuffer != nullptr, ERR_INVALID_PARAM, "processBuffer is null");
1189     CHECK_AND_RETURN_RET_LOG(processBuffer->GetStreamStatus() != nullptr, ERR_INVALID_PARAM,
1190         "the stream status is null");
1191 
1192     CHECK_AND_RETURN_RET_LOG(processList_.size() < MAX_LINKED_PROCESS, ERR_OPERATION_FAILED, "reach link limit.");
1193 
1194     AUDIO_INFO_LOG("LinkProcessStream start status is:%{public}s.", GetStatusStr(endpointStatus_).c_str());
1195 
1196     bool needEndpointRunning = processBuffer->GetStreamStatus()->load() == STREAM_RUNNING;
1197 
1198     if (endpointStatus_ == STARTING) {
1199         AUDIO_INFO_LOG("LinkProcessStream wait start begin.");
1200         std::unique_lock<std::mutex> lock(loopThreadLock_);
1201         workThreadCV_.wait_for(lock, std::chrono::milliseconds(SLEEP_TIME_IN_DEFAULT), [this] {
1202             return endpointStatus_ != STARTING;
1203         });
1204         AUDIO_DEBUG_LOG("LinkProcessStream wait start end.");
1205     }
1206 
1207     if (endpointStatus_ == RUNNING) {
1208         LinkProcessStreamExt(processStream, processBuffer);
1209         return SUCCESS;
1210     }
1211 
1212     if (endpointStatus_ == UNLINKED) {
1213         endpointStatus_ = IDEL; // handle push_back in IDEL
1214         if (isDeviceRunningInIdel_) {
1215             CHECK_AND_RETURN_RET_LOG(StartDevice(), ERR_OPERATION_FAILED, "StartDevice failed");
1216             delayStopTime_ = ClockTime::GetCurNano() + DELAY_STOP_HDI_TIME;
1217         }
1218     }
1219 
1220     if (endpointStatus_ == IDEL) {
1221         {
1222             std::lock_guard<std::mutex> lock(listLock_);
1223             processList_.push_back(processStream);
1224             processBufferList_.push_back(processBuffer);
1225         }
1226         if (!needEndpointRunning) {
1227             AUDIO_INFO_LOG("LinkProcessStream success, process stream status is not running.");
1228             return SUCCESS;
1229         }
1230         // needEndpointRunning = true
1231         if (isDeviceRunningInIdel_) {
1232             endpointStatus_ = IsAnyProcessRunning() ? RUNNING : IDEL;
1233         } else {
1234             // needEndpointRunning = true & isDeviceRunningInIdel_ = false
1235             // KeepWorkloopRunning will wait on IDEL
1236             CHECK_AND_RETURN_RET_LOG(StartDevice(), ERR_OPERATION_FAILED, "StartDevice failed");
1237         }
1238         AUDIO_INFO_LOG("LinkProcessStream success with status:%{public}s", GetStatusStr(endpointStatus_).c_str());
1239         return SUCCESS;
1240     }
1241 
1242     AUDIO_INFO_LOG("LinkProcessStream success with status:%{public}s", GetStatusStr(endpointStatus_).c_str());
1243     return SUCCESS;
1244 }
1245 
LinkProcessStreamExt(IAudioProcessStream * processStream,const std::shared_ptr<OHAudioBuffer> & processBuffer)1246 void AudioEndpointInner::LinkProcessStreamExt(IAudioProcessStream *processStream,
1247     const std::shared_ptr<OHAudioBuffer>& processBuffer)
1248 {
1249     std::lock_guard<std::mutex> lock(listLock_);
1250     processList_.push_back(processStream);
1251     processBufferList_.push_back(processBuffer);
1252     AUDIO_INFO_LOG("LinkProcessStream success in RUNNING.");
1253 }
1254 
UnlinkProcessStream(IAudioProcessStream * processStream)1255 int32_t AudioEndpointInner::UnlinkProcessStream(IAudioProcessStream *processStream)
1256 {
1257     AUDIO_INFO_LOG("UnlinkProcessStream in status:%{public}s.", GetStatusStr(endpointStatus_).c_str());
1258     CHECK_AND_RETURN_RET_LOG(processStream != nullptr, ERR_INVALID_PARAM, "IAudioProcessStream is null");
1259     std::shared_ptr<OHAudioBuffer> processBuffer = processStream->GetStreamBuffer();
1260     CHECK_AND_RETURN_RET_LOG(processBuffer != nullptr, ERR_INVALID_PARAM, "processBuffer is null");
1261 
1262     bool isFind = false;
1263     std::lock_guard<std::mutex> lock(listLock_);
1264     auto processItr = processList_.begin();
1265     auto bufferItr = processBufferList_.begin();
1266     while (processItr != processList_.end()) {
1267         if (*processItr == processStream && *bufferItr == processBuffer) {
1268             processList_.erase(processItr);
1269             processBufferList_.erase(bufferItr);
1270             isFind = true;
1271             break;
1272         } else {
1273             processItr++;
1274             bufferItr++;
1275         }
1276     }
1277     if (processList_.size() == 0) {
1278         StopDevice();
1279         endpointStatus_ = UNLINKED;
1280     } else if (!IsAnyProcessRunningInner()) {
1281         endpointStatus_ = IDEL;
1282         isStarted_ = false;
1283         delayStopTime_ = DELAY_STOP_HDI_TIME_WHEN_NO_RUNNING_NS;
1284     }
1285 
1286     AUDIO_DEBUG_LOG("UnlinkProcessStream end, %{public}s the process.", (isFind ? "find and remove" : "not find"));
1287     return SUCCESS;
1288 }
1289 
CheckStandBy()1290 void AudioEndpointInner::CheckStandBy()
1291 {
1292     if (endpointStatus_ == RUNNING) {
1293         endpointStatus_ = IsAnyProcessRunning() ? RUNNING : IDEL;
1294     }
1295 
1296     if (endpointStatus_ == RUNNING) {
1297         return;
1298     }
1299 
1300     AUDIO_INFO_LOG("endpoint status:%{public}s", GetStatusStr(endpointStatus_).c_str());
1301     if (endpointStatus_ == IDEL) {
1302         // delay call sink stop when no process running
1303         AUDIO_INFO_LOG("status is IDEL, need delay call stop");
1304         delayStopTime_ = ClockTime::GetCurNano() + DELAY_STOP_HDI_TIME;
1305     }
1306 }
1307 
CheckAllBufferReady(int64_t checkTime,uint64_t curWritePos)1308 bool AudioEndpointInner::CheckAllBufferReady(int64_t checkTime, uint64_t curWritePos)
1309 {
1310     bool isAllReady = true;
1311     bool needCheckStandby = false;
1312     {
1313         // lock list without sleep
1314         std::lock_guard<std::mutex> lock(listLock_);
1315         for (size_t i = 0; i < processBufferList_.size(); i++) {
1316             std::shared_ptr<OHAudioBuffer> tempBuffer = processBufferList_[i];
1317             uint64_t eachCurReadPos = processBufferList_[i]->GetCurReadFrame();
1318             lastHandleProcessTime_ = checkTime;
1319             processBufferList_[i]->SetHandleInfo(eachCurReadPos, lastHandleProcessTime_); // update handle info
1320             if (tempBuffer->GetStreamStatus() &&
1321                 tempBuffer->GetStreamStatus()->load() != StreamStatus::STREAM_RUNNING) {
1322                 // Process is not running, server will continue to check the same location in the next cycle.
1323                 int64_t duration = 5000000; // 5ms
1324                 processBufferList_[i]->SetHandleInfo(eachCurReadPos, lastHandleProcessTime_ + duration);
1325                 continue; // process not running
1326             }
1327             // Status is RUNNING
1328             int64_t current = ClockTime::GetCurNano();
1329             int64_t lastWrittenTime = tempBuffer->GetLastWrittenTime();
1330             if (current - lastWrittenTime > WAIT_CLIENT_STANDBY_TIME_NS) {
1331                 Trace trace("AudioEndpoint::MarkClientStandby");
1332                 AUDIO_INFO_LOG("change the status to stand-by, session %{public}u", tempBuffer->GetSessionId());
1333                 CHECK_AND_RETURN_RET_LOG(tempBuffer->GetStreamStatus() != nullptr, false, "GetStreamStatus failed");
1334                 tempBuffer->GetStreamStatus()->store(StreamStatus::STREAM_STAND_BY);
1335                 WriterRenderStreamStandbySysEvent(tempBuffer->GetSessionId(), 1);
1336                 needCheckStandby = true;
1337                 continue;
1338             }
1339             uint64_t curRead = tempBuffer->GetCurReadFrame();
1340             SpanInfo *curReadSpan = tempBuffer->GetSpanInfo(curRead);
1341             if (curReadSpan == nullptr || curReadSpan->spanStatus != SpanStatus::SPAN_WRITE_DONE) {
1342                 AUDIO_DEBUG_LOG("Find one process not ready"); // print uid of the process?
1343                 isAllReady = false;
1344                 continue;
1345             }
1346             // process Status is RUNNING && buffer status is WRITE_DONE
1347             tempBuffer->SetLastWrittenTime(current);
1348         }
1349     }
1350 
1351     if (needCheckStandby) {
1352         CheckStandBy();
1353     }
1354 
1355     if (!isAllReady) {
1356         WaitAllProcessReady(curWritePos);
1357     }
1358     return isAllReady;
1359 }
1360 
WaitAllProcessReady(uint64_t curWritePos)1361 void AudioEndpointInner::WaitAllProcessReady(uint64_t curWritePos)
1362 {
1363     Trace trace("AudioEndpoint::WaitAllProcessReady");
1364     int64_t tempWakeupTime = readTimeModel_.GetTimeOfPos(curWritePos) + WRITE_TO_HDI_AHEAD_TIME;
1365     if (tempWakeupTime - ClockTime::GetCurNano() < ONE_MILLISECOND_DURATION) {
1366         ClockTime::RelativeSleep(ONE_MILLISECOND_DURATION);
1367     } else {
1368         ClockTime::AbsoluteSleep(tempWakeupTime); // sleep to hdi read time ahead 1ms.
1369     }
1370 }
1371 
MixToDupStream(const std::vector<AudioStreamData> & srcDataList)1372 void AudioEndpointInner::MixToDupStream(const std::vector<AudioStreamData> &srcDataList)
1373 {
1374     Trace trace("AudioEndpointInner::MixToDupStream");
1375     std::lock_guard<std::mutex> lock(dupMutex_);
1376     CHECK_AND_RETURN_LOG(dupBuffer_ != nullptr, "Buffer is not ready");
1377 
1378     for (size_t i = 0; i < srcDataList.size(); i++) {
1379         if (!srcDataList[i].isInnerCaped) {
1380             continue;
1381         }
1382         size_t dataLength = dupBufferSize_;
1383         dataLength /= 2; // SAMPLE_S16LE--> 2 byte
1384         int16_t *dstPtr = reinterpret_cast<int16_t *>(dupBuffer_.get());
1385 
1386         for (size_t offset = 0; dataLength > 0; dataLength--) {
1387             int32_t sum = *dstPtr;
1388             sum += *(reinterpret_cast<int16_t *>(srcDataList[i].bufferDesc.buffer) + offset);
1389             *dstPtr = sum > INT16_MAX ? INT16_MAX : (sum < INT16_MIN ? INT16_MIN : sum);
1390             dstPtr++;
1391             offset++;
1392         }
1393     }
1394     BufferDesc temp;
1395     temp.buffer = dupBuffer_.get();
1396     temp.bufLength = dupBufferSize_;
1397     temp.dataLength = dupBufferSize_;
1398 
1399     CHECK_AND_RETURN_LOG(dupStream_ != nullptr, "dupStream_ is nullptr");
1400     int32_t ret = dupStream_->EnqueueBuffer(temp);
1401     CHECK_AND_RETURN_LOG(ret == SUCCESS, "EnqueueBuffer failed:%{public}d", ret);
1402 
1403     ret = memset_s(reinterpret_cast<void *>(dupBuffer_.get()), dupBufferSize_, 0, dupBufferSize_);
1404     if (ret != EOK) {
1405         AUDIO_WARNING_LOG("memset buffer fail, ret %{public}d", ret);
1406     }
1407 }
1408 
ProcessData(const std::vector<AudioStreamData> & srcDataList,const AudioStreamData & dstData)1409 void AudioEndpointInner::ProcessData(const std::vector<AudioStreamData> &srcDataList, const AudioStreamData &dstData)
1410 {
1411     size_t srcListSize = srcDataList.size();
1412 
1413     for (size_t i = 0; i < srcListSize; i++) {
1414         if (srcDataList[i].streamInfo.format != SAMPLE_S16LE || srcDataList[i].streamInfo.channels != STEREO ||
1415             srcDataList[i].bufferDesc.bufLength != dstData.bufferDesc.bufLength ||
1416             srcDataList[i].bufferDesc.dataLength != dstData.bufferDesc.dataLength) {
1417             AUDIO_ERR_LOG("ProcessData failed, streamInfo are different");
1418             return;
1419         }
1420     }
1421 
1422     // Assum using the same format and same size
1423     CHECK_AND_RETURN_LOG(dstData.streamInfo.format == SAMPLE_S16LE && dstData.streamInfo.channels == STEREO,
1424         "ProcessData failed, streamInfo are not support");
1425 
1426     size_t dataLength = dstData.bufferDesc.dataLength;
1427     dataLength /= 2; // SAMPLE_S16LE--> 2 byte
1428     int16_t *dstPtr = reinterpret_cast<int16_t *>(dstData.bufferDesc.buffer);
1429     for (size_t offset = 0; dataLength > 0; dataLength--) {
1430         int32_t sum = 0;
1431         for (size_t i = 0; i < srcListSize; i++) {
1432             int32_t vol = srcDataList[i].volumeStart; // change to modify volume of each channel
1433             int16_t *srcPtr = reinterpret_cast<int16_t *>(srcDataList[i].bufferDesc.buffer) + offset;
1434             sum += (*srcPtr * static_cast<int64_t>(vol)) >> VOLUME_SHIFT_NUMBER; // 1/65536
1435             ZeroVolumeCheck(vol);
1436         }
1437         offset++;
1438         *dstPtr++ = sum > INT16_MAX ? INT16_MAX : (sum < INT16_MIN ? INT16_MIN : sum);
1439     }
1440     HandleZeroVolumeCheckEvent();
1441 }
1442 
HandleZeroVolumeCheckEvent()1443 void AudioEndpointInner::HandleZeroVolumeCheckEvent()
1444 {
1445     if (!zeroVolumeStopDevice_ && (ClockTime::GetCurNano() >= delayStopTimeForZeroVolume_)) {
1446         if (isStarted_) {
1447             if (fastSink_ != nullptr && fastSink_->Stop() == SUCCESS) {
1448                 AUDIO_INFO_LOG("Volume from none-zero to zero more than 4s, stop device success.");
1449                 isStarted_ = false;
1450             } else {
1451                 AUDIO_INFO_LOG("Volume from none-zero to zero more than 4s, stop device failed.");
1452                 isStarted_ = true;
1453             }
1454         }
1455         zeroVolumeStopDevice_ = true;
1456     }
1457 }
1458 
1459 
HandleRendererDataParams(const AudioStreamData & srcData,const AudioStreamData & dstData)1460 void AudioEndpointInner::HandleRendererDataParams(const AudioStreamData &srcData, const AudioStreamData &dstData)
1461 {
1462     if (srcData.streamInfo.encoding != dstData.streamInfo.encoding) {
1463         AUDIO_ERR_LOG("Different encoding formats");
1464         return;
1465     }
1466     if (srcData.streamInfo.format == SAMPLE_S16LE && srcData.streamInfo.channels == STEREO) {
1467         return ProcessSingleData(srcData, dstData);
1468     }
1469     if (srcData.streamInfo.format == SAMPLE_S16LE && srcData.streamInfo.channels == MONO) {
1470         CHECK_AND_RETURN_LOG(processList_.size() > 0 && processList_[0] != nullptr, "No avaliable process");
1471         BufferDesc &convertedBuffer = processList_[0]->GetConvertedBuffer();
1472         int32_t ret = FormatConverter::S16MonoToS16Stereo(srcData.bufferDesc, convertedBuffer);
1473         CHECK_AND_RETURN_LOG(ret == SUCCESS, "Convert channel from mono to stereo failed");
1474         AudioStreamData dataAfterProcess = srcData;
1475         dataAfterProcess.bufferDesc = convertedBuffer;
1476         ProcessSingleData(dataAfterProcess, dstData);
1477         ret = memset_s(static_cast<void *>(convertedBuffer.buffer), convertedBuffer.bufLength, 0,
1478             convertedBuffer.bufLength);
1479         CHECK_AND_RETURN_LOG(ret == EOK, "memset converted buffer to 0 failed");
1480     }
1481 }
1482 
ProcessSingleData(const AudioStreamData & srcData,const AudioStreamData & dstData)1483 void AudioEndpointInner::ProcessSingleData(const AudioStreamData &srcData, const AudioStreamData &dstData)
1484 {
1485     CHECK_AND_RETURN_LOG(dstData.streamInfo.format == SAMPLE_S16LE && dstData.streamInfo.channels == STEREO,
1486         "ProcessData failed, streamInfo are not support");
1487 
1488     size_t dataLength = dstData.bufferDesc.dataLength;
1489     dataLength /= 2; // SAMPLE_S16LE--> 2 byte
1490     int16_t *dstPtr = reinterpret_cast<int16_t *>(dstData.bufferDesc.buffer);
1491     for (size_t offset = 0; dataLength > 0; dataLength--) {
1492         int32_t vol = srcData.volumeStart; // change to modify volume of each channel
1493         int16_t *srcPtr = reinterpret_cast<int16_t *>(srcData.bufferDesc.buffer) + offset;
1494         int32_t sum = (*srcPtr * static_cast<int64_t>(vol)) >> VOLUME_SHIFT_NUMBER; // 1/65536
1495         ZeroVolumeCheck(vol);
1496         offset++;
1497         *dstPtr++ = sum > INT16_MAX ? INT16_MAX : (sum < INT16_MIN ? INT16_MIN : sum);
1498     }
1499     HandleZeroVolumeCheckEvent();
1500 }
1501 
ZeroVolumeCheck(const int32_t vol)1502 void AudioEndpointInner::ZeroVolumeCheck(const int32_t vol)
1503 {
1504     if (std::abs(vol - 0) <= std::numeric_limits<float>::epsilon()) {
1505         if (!zeroVolumeStopDevice_ && !isVolumeAlreadyZero_) {
1506             AUDIO_INFO_LOG("Begin zero volume, will stop device.");
1507             delayStopTimeForZeroVolume_ = ClockTime::GetCurNano() + DELAY_STOP_HDI_TIME_FOR_ZERO_VOLUME_NS;
1508             isVolumeAlreadyZero_ = true;
1509         }
1510     } else {
1511         if (zeroVolumeStopDevice_ && !isStarted_) {
1512             if (fastSink_ == nullptr || fastSink_->Start() != SUCCESS) {
1513                 AUDIO_INFO_LOG("Volume from zero to none-zero, start device failed.");
1514                 isStarted_ = false;
1515             } else {
1516                 AUDIO_INFO_LOG("Volume from zero to none-zero, start device success.");
1517                 isStarted_ = true;
1518                 needReSyncPosition_ = true;
1519             }
1520             zeroVolumeStopDevice_ = false;
1521         }
1522         isVolumeAlreadyZero_ = false;
1523         delayStopTimeForZeroVolume_ = INT64_MAX;
1524     }
1525 }
1526 
1527 // call with listLock_ hold
GetAllReadyProcessData(std::vector<AudioStreamData> & audioDataList)1528 void AudioEndpointInner::GetAllReadyProcessData(std::vector<AudioStreamData> &audioDataList)
1529 {
1530     for (size_t i = 0; i < processBufferList_.size(); i++) {
1531         uint64_t curRead = processBufferList_[i]->GetCurReadFrame();
1532         Trace trace("AudioEndpoint::ReadProcessData->" + std::to_string(curRead));
1533         SpanInfo *curReadSpan = processBufferList_[i]->GetSpanInfo(curRead);
1534         CHECK_AND_CONTINUE_LOG(curReadSpan != nullptr, "GetSpanInfo failed, can not get client curReadSpan");
1535         AudioStreamData streamData;
1536         Volume vol = {true, 1.0f, 0};
1537         AudioStreamType streamType = processList_[i]->GetAudioStreamType();
1538         AudioVolumeType volumeType = VolumeUtils::GetVolumeTypeFromStreamType(streamType);
1539         DeviceType deviceType = PolicyHandler::GetInstance().GetActiveOutPutDevice();
1540         bool muteFlag = processList_[i]->GetMuteState();
1541         if (deviceInfo_.networkId == LOCAL_NETWORK_ID &&
1542             !(deviceInfo_.deviceType == DEVICE_TYPE_BLUETOOTH_A2DP && volumeType == STREAM_MUSIC &&
1543                 PolicyHandler::GetInstance().IsAbsVolumeSupported()) &&
1544             PolicyHandler::GetInstance().GetSharedVolume(volumeType, deviceType, vol)) {
1545             streamData.volumeStart = vol.isMute ? 0 : static_cast<int32_t>(curReadSpan->volumeStart * vol.volumeFloat);
1546         } else {
1547             streamData.volumeStart = curReadSpan->volumeStart;
1548         }
1549         streamData.volumeEnd = curReadSpan->volumeEnd;
1550         streamData.streamInfo = processList_[i]->GetStreamInfo();
1551         streamData.isInnerCaped = processList_[i]->GetInnerCapState();
1552         SpanStatus targetStatus = SpanStatus::SPAN_WRITE_DONE;
1553         if (curReadSpan->spanStatus.compare_exchange_strong(targetStatus, SpanStatus::SPAN_READING)) {
1554             processBufferList_[i]->GetReadbuffer(curRead, streamData.bufferDesc); // check return?
1555             if (muteFlag) {
1556                 memset_s(static_cast<void *>(streamData.bufferDesc.buffer), streamData.bufferDesc.bufLength,
1557                     0, streamData.bufferDesc.bufLength);
1558             }
1559             CheckPlaySignal(streamData.bufferDesc.buffer, streamData.bufferDesc.bufLength);
1560             audioDataList.push_back(streamData);
1561             curReadSpan->readStartTime = ClockTime::GetCurNano();
1562             processList_[i]->WriteDumpFile(static_cast<void *>(streamData.bufferDesc.buffer),
1563                 streamData.bufferDesc.bufLength);
1564         }
1565     }
1566 }
1567 
ProcessToEndpointDataHandle(uint64_t curWritePos)1568 bool AudioEndpointInner::ProcessToEndpointDataHandle(uint64_t curWritePos)
1569 {
1570     std::lock_guard<std::mutex> lock(listLock_);
1571 
1572     std::vector<AudioStreamData> audioDataList;
1573     GetAllReadyProcessData(audioDataList);
1574 
1575     AudioStreamData dstStreamData;
1576     dstStreamData.streamInfo = dstStreamInfo_;
1577     int32_t ret = dstAudioBuffer_->GetWriteBuffer(curWritePos, dstStreamData.bufferDesc);
1578     CHECK_AND_RETURN_RET_LOG(((ret == SUCCESS && dstStreamData.bufferDesc.buffer != nullptr)), false,
1579         "GetWriteBuffer failed, ret:%{public}d", ret);
1580 
1581     SpanInfo *curWriteSpan = dstAudioBuffer_->GetSpanInfo(curWritePos);
1582     CHECK_AND_RETURN_RET_LOG(curWriteSpan != nullptr, false, "GetSpanInfo failed, can not get curWriteSpan");
1583 
1584     dstStreamData.volumeStart = curWriteSpan->volumeStart;
1585     dstStreamData.volumeEnd = curWriteSpan->volumeEnd;
1586 
1587     Trace trace("AudioEndpoint::WriteDstBuffer=>" + std::to_string(curWritePos));
1588     // do write work
1589     if (audioDataList.size() == 0) {
1590         memset_s(dstStreamData.bufferDesc.buffer, dstStreamData.bufferDesc.bufLength, 0,
1591             dstStreamData.bufferDesc.bufLength);
1592     } else {
1593         if (endpointType_ == TYPE_VOIP_MMAP && audioDataList.size() == 1) {
1594             HandleRendererDataParams(audioDataList[0], dstStreamData);
1595         } else {
1596             ProcessData(audioDataList, dstStreamData);
1597         }
1598     }
1599 
1600     if (isInnerCapEnabled_) {
1601         MixToDupStream(audioDataList);
1602     }
1603 
1604     DfxOperation(dstStreamData.bufferDesc, dstStreamInfo_.format, dstStreamInfo_.channels);
1605 
1606     if (AudioDump::GetInstance().GetVersionType() == BETA_VERSION) {
1607         DumpFileUtil::WriteDumpFile(dumpHdi_, static_cast<void *>(dstStreamData.bufferDesc.buffer),
1608             dstStreamData.bufferDesc.bufLength);
1609         AudioCacheMgr::GetInstance().CacheData(dumpHdiName_,
1610             static_cast<void *>(dstStreamData.bufferDesc.buffer), dstStreamData.bufferDesc.bufLength);
1611     }
1612 
1613     CheckUpdateState(reinterpret_cast<char *>(dstStreamData.bufferDesc.buffer),
1614         dstStreamData.bufferDesc.bufLength);
1615 
1616     return true;
1617 }
1618 
DfxOperation(BufferDesc & buffer,AudioSampleFormat format,AudioChannel channel) const1619 void AudioEndpointInner::DfxOperation(BufferDesc &buffer, AudioSampleFormat format, AudioChannel channel) const
1620 {
1621     ChannelVolumes vols = VolumeTools::CountVolumeLevel(buffer, format, channel);
1622     if (channel == MONO) {
1623         Trace::Count(logUtilsTag_, vols.volStart[0]);
1624     } else {
1625         Trace::Count(logUtilsTag_, (vols.volStart[0] + vols.volStart[1]) / HALF_FACTOR);
1626     }
1627     AudioLogUtils::ProcessVolumeData(logUtilsTag_, vols, volumeDataCount_);
1628 }
1629 
CheckUpdateState(char * frame,uint64_t replyBytes)1630 void AudioEndpointInner::CheckUpdateState(char *frame, uint64_t replyBytes)
1631 {
1632     if (startUpdate_) {
1633         if (renderFrameNum_ == 0) {
1634             last10FrameStartTime_ = ClockTime::GetCurNano();
1635         }
1636         renderFrameNum_++;
1637         maxAmplitude_ = UpdateMaxAmplitude(static_cast<ConvertHdiFormat>(dstStreamInfo_.format),
1638             frame, replyBytes);
1639         if (renderFrameNum_ == GET_MAX_AMPLITUDE_FRAMES_THRESHOLD) {
1640             renderFrameNum_ = 0;
1641             if (last10FrameStartTime_ > lastGetMaxAmplitudeTime_) {
1642                 startUpdate_ = false;
1643                 maxAmplitude_ = 0;
1644             }
1645         }
1646     }
1647 }
1648 
GetMaxAmplitude()1649 float AudioEndpointInner::GetMaxAmplitude()
1650 {
1651     lastGetMaxAmplitudeTime_ = ClockTime::GetCurNano();
1652     startUpdate_ = true;
1653     return maxAmplitude_;
1654 }
1655 
GetPredictNextReadTime(uint64_t posInFrame)1656 int64_t AudioEndpointInner::GetPredictNextReadTime(uint64_t posInFrame)
1657 {
1658     Trace trace("AudioEndpoint::GetPredictNextRead");
1659     uint64_t handleSpanCnt = posInFrame / dstSpanSizeInframe_;
1660     uint32_t startPeriodCnt = 20; // sync each time when start
1661     uint32_t oneBigPeriodCnt = 40; // 200ms
1662     if (handleSpanCnt < startPeriodCnt || handleSpanCnt % oneBigPeriodCnt == 0) {
1663         updateThreadCV_.notify_all();
1664     }
1665     uint64_t readFrame = 0;
1666     int64_t readtime = 0;
1667     if (readTimeModel_.GetFrameStamp(readFrame, readtime)) {
1668         if (readFrame != posInFrame_) {
1669             readTimeModel_.UpdataFrameStamp(posInFrame_, timeInNano_);
1670         }
1671     }
1672 
1673     int64_t nextHdiReadTime = readTimeModel_.GetTimeOfPos(posInFrame);
1674     return nextHdiReadTime;
1675 }
1676 
GetPredictNextWriteTime(uint64_t posInFrame)1677 int64_t AudioEndpointInner::GetPredictNextWriteTime(uint64_t posInFrame)
1678 {
1679     uint64_t handleSpanCnt = posInFrame / dstSpanSizeInframe_;
1680     uint32_t startPeriodCnt = 20;
1681     uint32_t oneBigPeriodCnt = 40;
1682     if (handleSpanCnt < startPeriodCnt || handleSpanCnt % oneBigPeriodCnt == 0) {
1683         updateThreadCV_.notify_all();
1684     }
1685     uint64_t writeFrame = 0;
1686     int64_t writetime = 0;
1687     if (writeTimeModel_.GetFrameStamp(writeFrame, writetime)) {
1688         if (writeFrame != posInFrame_) {
1689             writeTimeModel_.UpdataFrameStamp(posInFrame_, timeInNano_);
1690         }
1691     }
1692     int64_t nextHdiWriteTime = writeTimeModel_.GetTimeOfPos(posInFrame);
1693     return nextHdiWriteTime;
1694 }
1695 
RecordPrepareNextLoop(uint64_t curReadPos,int64_t & wakeUpTime)1696 bool AudioEndpointInner::RecordPrepareNextLoop(uint64_t curReadPos, int64_t &wakeUpTime)
1697 {
1698     uint64_t nextHandlePos = curReadPos + dstSpanSizeInframe_;
1699     int64_t nextHdiWriteTime = GetPredictNextWriteTime(nextHandlePos);
1700     int64_t tempDelay = endpointType_ == TYPE_VOIP_MMAP ? RECORD_VOIP_DELAY_TIME_NS : RECORD_DELAY_TIME_NS;
1701     int64_t predictWakeupTime = nextHdiWriteTime + tempDelay;
1702     if (predictWakeupTime <= ClockTime::GetCurNano()) {
1703         wakeUpTime = ClockTime::GetCurNano() + ONE_MILLISECOND_DURATION;
1704         AUDIO_ERR_LOG("hdi send wrong position time");
1705     } else {
1706         wakeUpTime = predictWakeupTime;
1707     }
1708 
1709     int32_t ret = dstAudioBuffer_->SetCurWriteFrame(nextHandlePos);
1710     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, false, "set dst buffer write frame fail, ret %{public}d.", ret);
1711     ret = dstAudioBuffer_->SetCurReadFrame(nextHandlePos);
1712     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, false, "set dst buffer read frame fail, ret %{public}d.", ret);
1713 
1714     return true;
1715 }
1716 
PrepareNextLoop(uint64_t curWritePos,int64_t & wakeUpTime)1717 bool AudioEndpointInner::PrepareNextLoop(uint64_t curWritePos, int64_t &wakeUpTime)
1718 {
1719     uint64_t nextHandlePos = curWritePos + dstSpanSizeInframe_;
1720     Trace prepareTrace("AudioEndpoint::PrepareNextLoop " + std::to_string(nextHandlePos));
1721     int64_t nextHdiReadTime = GetPredictNextReadTime(nextHandlePos);
1722     int64_t predictWakeupTime = nextHdiReadTime - serverAheadReadTime_;
1723     if (predictWakeupTime <= ClockTime::GetCurNano()) {
1724         wakeUpTime = ClockTime::GetCurNano() + ONE_MILLISECOND_DURATION;
1725         AUDIO_ERR_LOG("hdi send wrong position time");
1726     } else {
1727         wakeUpTime = predictWakeupTime;
1728     }
1729 
1730     SpanInfo *nextWriteSpan = dstAudioBuffer_->GetSpanInfo(nextHandlePos);
1731     CHECK_AND_RETURN_RET_LOG(nextWriteSpan != nullptr, false, "GetSpanInfo failed, can not get next write span");
1732 
1733     int32_t ret1 = dstAudioBuffer_->SetCurWriteFrame(nextHandlePos);
1734     int32_t ret2 = dstAudioBuffer_->SetCurReadFrame(nextHandlePos);
1735     CHECK_AND_RETURN_RET_LOG(ret1 == SUCCESS && ret2 == SUCCESS, false,
1736         "SetCurWriteFrame or SetCurReadFrame failed, ret1:%{public}d ret2:%{public}d", ret1, ret2);
1737     // handl each process buffer info
1738     int64_t curReadDoneTime = ClockTime::GetCurNano();
1739     {
1740         std::lock_guard<std::mutex> lock(listLock_);
1741         for (size_t i = 0; i < processBufferList_.size(); i++) {
1742             uint64_t eachCurReadPos = processBufferList_[i]->GetCurReadFrame();
1743             SpanInfo *tempSpan = processBufferList_[i]->GetSpanInfo(eachCurReadPos);
1744             CHECK_AND_RETURN_RET_LOG(tempSpan != nullptr, false,
1745                 "GetSpanInfo failed, can not get process read span");
1746             SpanStatus targetStatus = SpanStatus::SPAN_READING;
1747             CHECK_AND_RETURN_RET_LOG(processBufferList_[i]->GetStreamStatus() != nullptr, false,
1748                 "stream status is null");
1749             if (tempSpan->spanStatus.compare_exchange_strong(targetStatus, SpanStatus::SPAN_READ_DONE)) {
1750                 tempSpan->readDoneTime = curReadDoneTime;
1751                 BufferDesc bufferReadDone = { nullptr, 0, 0};
1752                 processBufferList_[i]->GetReadbuffer(eachCurReadPos, bufferReadDone);
1753                 if (bufferReadDone.buffer != nullptr && bufferReadDone.bufLength != 0) {
1754                     memset_s(bufferReadDone.buffer, bufferReadDone.bufLength, 0, bufferReadDone.bufLength);
1755                 }
1756                 processBufferList_[i]->SetCurReadFrame(eachCurReadPos + dstSpanSizeInframe_); // use client span size
1757             } else if (processBufferList_[i]->GetStreamStatus() &&
1758                 processBufferList_[i]->GetStreamStatus()->load() == StreamStatus::STREAM_RUNNING) {
1759                 AUDIO_DEBUG_LOG("Current %{public}" PRIu64" span not ready:%{public}d", eachCurReadPos, targetStatus);
1760             }
1761         }
1762     }
1763     return true;
1764 }
1765 
GetDeviceHandleInfo(uint64_t & frames,int64_t & nanoTime)1766 bool AudioEndpointInner::GetDeviceHandleInfo(uint64_t &frames, int64_t &nanoTime)
1767 {
1768     Trace trace("AudioEndpoint::GetMmapHandlePosition");
1769     int64_t timeSec = 0;
1770     int64_t timeNanoSec = 0;
1771     int32_t ret = 0;
1772     if (deviceInfo_.deviceRole == INPUT_DEVICE) {
1773         CHECK_AND_RETURN_RET_LOG(fastSource_ != nullptr && fastSource_->IsInited(),
1774             false, "Source start failed.");
1775         // GetMmapHandlePosition will call using ipc.
1776         ret = fastSource_->GetMmapHandlePosition(frames, timeSec, timeNanoSec);
1777     } else {
1778         CHECK_AND_RETURN_RET_LOG(fastSink_ != nullptr && fastSink_->IsInited(),
1779             false, "GetDeviceHandleInfo failed: sink is not inited.");
1780         // GetMmapHandlePosition will call using ipc.
1781         ret = fastSink_->GetMmapHandlePosition(frames, timeSec, timeNanoSec);
1782     }
1783     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, false, "Call adapter GetMmapHandlePosition failed: %{public}d", ret);
1784     trace.End();
1785     nanoTime = timeNanoSec + timeSec * AUDIO_NS_PER_SECOND;
1786     Trace infoTrace("AudioEndpoint::GetDeviceHandleInfo frames=>" + std::to_string(frames) + " " +
1787         std::to_string(nanoTime) + " at " + std::to_string(ClockTime::GetCurNano()));
1788     nanoTime += DELTA_TO_REAL_READ_START_TIME; // global delay in server
1789     return true;
1790 }
1791 
AsyncGetPosTime()1792 void AudioEndpointInner::AsyncGetPosTime()
1793 {
1794     AUDIO_INFO_LOG("AsyncGetPosTime thread start.");
1795     while (!stopUpdateThread_) {
1796         std::unique_lock<std::mutex> lock(updateThreadLock_);
1797         updateThreadCV_.wait_for(lock, std::chrono::milliseconds(UPDATE_THREAD_TIMEOUT));
1798         if (stopUpdateThread_) {
1799             break;
1800         }
1801         if (endpointStatus_ == IDEL && isStarted_ && ClockTime::GetCurNano() > delayStopTime_) {
1802             AUDIO_INFO_LOG("IDEL for too long, let's call hdi stop");
1803             DelayStopDevice();
1804             continue;
1805         }
1806         if (endpointStatus_ == IDEL && !isStarted_) {
1807             continue;
1808         }
1809         // get signaled, call get pos-time
1810         uint64_t curHdiHandlePos = posInFrame_;
1811         int64_t handleTime = timeInNano_;
1812         if (!GetDeviceHandleInfo(curHdiHandlePos, handleTime)) {
1813             AUDIO_WARNING_LOG("AsyncGetPosTime call GetDeviceHandleInfo failed.");
1814             continue;
1815         }
1816         // keep it
1817         if (posInFrame_ != curHdiHandlePos) {
1818             posInFrame_ = curHdiHandlePos;
1819             timeInNano_ = handleTime;
1820         }
1821     }
1822 }
1823 
GetStatusStr(EndpointStatus status)1824 std::string AudioEndpointInner::GetStatusStr(EndpointStatus status)
1825 {
1826     switch (status) {
1827         case INVALID:
1828             return "INVALID";
1829         case UNLINKED:
1830             return "UNLINKED";
1831         case IDEL:
1832             return "IDEL";
1833         case STARTING:
1834             return "STARTING";
1835         case RUNNING:
1836             return "RUNNING";
1837         case STOPPING:
1838             return "STOPPING";
1839         case STOPPED:
1840             return "STOPPED";
1841         default:
1842             break;
1843     }
1844     return "NO_SUCH_STATUS";
1845 }
1846 
KeepWorkloopRunning()1847 bool AudioEndpointInner::KeepWorkloopRunning()
1848 {
1849     EndpointStatus targetStatus = INVALID;
1850     switch (endpointStatus_.load()) {
1851         case RUNNING:
1852             return true;
1853         case IDEL:
1854             if (ClockTime::GetCurNano() > delayStopTime_) {
1855                 targetStatus = RUNNING;
1856                 break;
1857             }
1858             if (isDeviceRunningInIdel_) {
1859                 return true;
1860             }
1861             break;
1862         case UNLINKED:
1863             targetStatus = IDEL;
1864             break;
1865         case STARTING:
1866             targetStatus = RUNNING;
1867             break;
1868         case STOPPING:
1869             targetStatus = STOPPED;
1870             break;
1871         default:
1872             break;
1873     }
1874 
1875     // when return false, EndpointWorkLoopFuc will continue loop immediately. Wait to avoid a inifity loop.
1876     std::unique_lock<std::mutex> lock(loopThreadLock_);
1877     AUDIO_PRERELEASE_LOGI("Status is %{public}s now, wait for %{public}s...", GetStatusStr(endpointStatus_).c_str(),
1878         GetStatusStr(targetStatus).c_str());
1879     threadStatus_ = WAITTING;
1880     workThreadCV_.wait_for(lock, std::chrono::milliseconds(SLEEP_TIME_IN_DEFAULT));
1881     AUDIO_DEBUG_LOG("Wait end. Cur is %{public}s now, target is %{public}s...", GetStatusStr(endpointStatus_).c_str(),
1882         GetStatusStr(targetStatus).c_str());
1883 
1884     return false;
1885 }
1886 
WriteToSpecialProcBuf(const std::shared_ptr<OHAudioBuffer> & procBuf,const BufferDesc & readBuf,const BufferDesc & convertedBuffer,bool muteFlag)1887 int32_t AudioEndpointInner::WriteToSpecialProcBuf(const std::shared_ptr<OHAudioBuffer> &procBuf,
1888     const BufferDesc &readBuf, const BufferDesc &convertedBuffer, bool muteFlag)
1889 {
1890     CHECK_AND_RETURN_RET_LOG(procBuf != nullptr, ERR_INVALID_HANDLE, "process buffer is null.");
1891     uint64_t curWritePos = procBuf->GetCurWriteFrame();
1892     Trace trace("AudioEndpoint::WriteProcessData-<" + std::to_string(curWritePos));
1893 
1894     int32_t writeAbleSize = procBuf->GetAvailableDataFrames();
1895     if (writeAbleSize <= 0 || static_cast<uint32_t>(writeAbleSize) <= dstSpanSizeInframe_) {
1896         AUDIO_WARNING_LOG("client read too slow: curWritePos:%{public}" PRIu64" writeAbleSize:%{public}d",
1897             curWritePos, writeAbleSize);
1898         return ERR_OPERATION_FAILED;
1899     }
1900 
1901     SpanInfo *curWriteSpan = procBuf->GetSpanInfo(curWritePos);
1902     CHECK_AND_RETURN_RET_LOG(curWriteSpan != nullptr, ERR_INVALID_HANDLE,
1903         "get write span info of procBuf fail.");
1904 
1905     AUDIO_DEBUG_LOG("process buffer write start, curWritePos %{public}" PRIu64".", curWritePos);
1906     curWriteSpan->spanStatus.store(SpanStatus::SPAN_WRITTING);
1907     curWriteSpan->writeStartTime = ClockTime::GetCurNano();
1908 
1909     BufferDesc writeBuf;
1910     int32_t ret = procBuf->GetWriteBuffer(curWritePos, writeBuf);
1911     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "get write buffer fail, ret %{public}d.", ret);
1912     if (muteFlag) {
1913         memset_s(static_cast<void *>(writeBuf.buffer), writeBuf.bufLength, 0, writeBuf.bufLength);
1914     } else {
1915         if (endpointType_ == TYPE_VOIP_MMAP) {
1916             ret = HandleCapturerDataParams(writeBuf, readBuf, convertedBuffer);
1917         } else {
1918             ret = memcpy_s(static_cast<void *>(writeBuf.buffer), writeBuf.bufLength,
1919                 static_cast<void *>(readBuf.buffer), readBuf.bufLength);
1920         }
1921     }
1922 
1923     CHECK_AND_RETURN_RET_LOG(ret == EOK, ERR_WRITE_FAILED, "memcpy data to process buffer fail, "
1924         "curWritePos %{public}" PRIu64", ret %{public}d.", curWritePos, ret);
1925 
1926     curWriteSpan->writeDoneTime = ClockTime::GetCurNano();
1927     procBuf->SetHandleInfo(curWritePos, curWriteSpan->writeDoneTime);
1928     ret = procBuf->SetCurWriteFrame(curWritePos + dstSpanSizeInframe_);
1929     if (ret != SUCCESS) {
1930         AUDIO_WARNING_LOG("set procBuf next write frame fail, ret %{public}d.", ret);
1931         curWriteSpan->spanStatus.store(SpanStatus::SPAN_READ_DONE);
1932         return ERR_OPERATION_FAILED;
1933     }
1934     curWriteSpan->spanStatus.store(SpanStatus::SPAN_WRITE_DONE);
1935     return SUCCESS;
1936 }
1937 
HandleCapturerDataParams(const BufferDesc & writeBuf,const BufferDesc & readBuf,const BufferDesc & convertedBuffer)1938 int32_t AudioEndpointInner::HandleCapturerDataParams(const BufferDesc &writeBuf, const BufferDesc &readBuf,
1939     const BufferDesc &convertedBuffer)
1940 {
1941     if (clientConfig_.streamInfo.format == SAMPLE_S16LE && clientConfig_.streamInfo.channels == STEREO) {
1942         return memcpy_s(static_cast<void *>(writeBuf.buffer), writeBuf.bufLength,
1943             static_cast<void *>(readBuf.buffer), readBuf.bufLength);
1944     }
1945     if (clientConfig_.streamInfo.format == SAMPLE_S16LE && clientConfig_.streamInfo.channels == MONO) {
1946         int32_t ret = FormatConverter::S16StereoToS16Mono(readBuf, convertedBuffer);
1947         CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_WRITE_FAILED, "Convert channel from stereo to mono failed");
1948         ret = memcpy_s(static_cast<void *>(writeBuf.buffer), writeBuf.bufLength,
1949             static_cast<void *>(convertedBuffer.buffer), convertedBuffer.bufLength);
1950         CHECK_AND_RETURN_RET_LOG(ret == EOK, ERR_WRITE_FAILED, "memcpy_s failed");
1951         ret = memset_s(static_cast<void *>(convertedBuffer.buffer), convertedBuffer.bufLength, 0,
1952             convertedBuffer.bufLength);
1953         CHECK_AND_RETURN_RET_LOG(ret == EOK, ERR_WRITE_FAILED, "memset converted buffer to 0 failed");
1954         return EOK;
1955     }
1956     return ERR_NOT_SUPPORTED;
1957 }
1958 
WriteToProcessBuffers(const BufferDesc & readBuf)1959 void AudioEndpointInner::WriteToProcessBuffers(const BufferDesc &readBuf)
1960 {
1961     CheckRecordSignal(readBuf.buffer, readBuf.bufLength);
1962     std::lock_guard<std::mutex> lock(listLock_);
1963     for (size_t i = 0; i < processBufferList_.size(); i++) {
1964         CHECK_AND_CONTINUE_LOG(processBufferList_[i] != nullptr,
1965             "process buffer %{public}zu is null.", i);
1966         if (processBufferList_[i]->GetStreamStatus() &&
1967             processBufferList_[i]->GetStreamStatus()->load() != STREAM_RUNNING) {
1968             AUDIO_WARNING_LOG("process buffer %{public}zu not running, stream status %{public}d.",
1969                 i, processBufferList_[i]->GetStreamStatus()->load());
1970             continue;
1971         }
1972 
1973         int32_t ret = WriteToSpecialProcBuf(processBufferList_[i], readBuf, processList_[i]->GetConvertedBuffer(),
1974             processList_[i]->GetMuteState());
1975         CHECK_AND_CONTINUE_LOG(ret == SUCCESS,
1976             "endpoint write to process buffer %{public}zu fail, ret %{public}d.", i, ret);
1977         AUDIO_DEBUG_LOG("endpoint process buffer %{public}zu write success.", i);
1978     }
1979 }
1980 
ReadFromEndpoint(uint64_t curReadPos)1981 int32_t AudioEndpointInner::ReadFromEndpoint(uint64_t curReadPos)
1982 {
1983     Trace trace("AudioEndpoint::ReadDstBuffer=<" + std::to_string(curReadPos));
1984     AUDIO_DEBUG_LOG("ReadFromEndpoint enter, dstAudioBuffer curReadPos %{public}" PRIu64".", curReadPos);
1985     CHECK_AND_RETURN_RET_LOG(dstAudioBuffer_ != nullptr, ERR_INVALID_HANDLE,
1986         "dst audio buffer is null.");
1987     SpanInfo *curReadSpan = dstAudioBuffer_->GetSpanInfo(curReadPos);
1988     CHECK_AND_RETURN_RET_LOG(curReadSpan != nullptr, ERR_INVALID_HANDLE,
1989         "get source read span info of source adapter fail.");
1990     curReadSpan->readStartTime = ClockTime::GetCurNano();
1991     curReadSpan->spanStatus.store(SpanStatus::SPAN_READING);
1992     BufferDesc readBuf;
1993     int32_t ret = dstAudioBuffer_->GetReadbuffer(curReadPos, readBuf);
1994     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "get read buffer fail, ret %{public}d.", ret);
1995     DfxOperation(readBuf, dstStreamInfo_.format, dstStreamInfo_.channels);
1996     if (AudioDump::GetInstance().GetVersionType() == BETA_VERSION) {
1997         DumpFileUtil::WriteDumpFile(dumpHdi_, static_cast<void *>(readBuf.buffer), readBuf.bufLength);
1998         AudioCacheMgr::GetInstance().CacheData(dumpHdiName_,
1999             static_cast<void *>(readBuf.buffer), readBuf.bufLength);
2000     }
2001     WriteToProcessBuffers(readBuf);
2002     ret = memset_s(readBuf.buffer, readBuf.bufLength, 0, readBuf.bufLength);
2003     if (ret != EOK) {
2004         AUDIO_WARNING_LOG("reset buffer fail, ret %{public}d.", ret);
2005     }
2006     curReadSpan->readDoneTime = ClockTime::GetCurNano();
2007     curReadSpan->spanStatus.store(SpanStatus::SPAN_READ_DONE);
2008     return SUCCESS;
2009 }
2010 
RecordEndpointWorkLoopFuc()2011 void AudioEndpointInner::RecordEndpointWorkLoopFuc()
2012 {
2013     ScheduleReportData(getpid(), gettid(), "audio_server");
2014     int64_t curTime = 0;
2015     uint64_t curReadPos = 0;
2016     int64_t wakeUpTime = ClockTime::GetCurNano();
2017     AUDIO_INFO_LOG("Record endpoint work loop fuc start.");
2018     while (isInited_.load()) {
2019         if (!KeepWorkloopRunning()) {
2020             continue;
2021         }
2022         threadStatus_ = INRUNNING;
2023         if (needReSyncPosition_) {
2024             RecordReSyncPosition();
2025             wakeUpTime = ClockTime::GetCurNano();
2026             needReSyncPosition_ = false;
2027             continue;
2028         }
2029         curTime = ClockTime::GetCurNano();
2030         Trace loopTrace("Record_loop_trace");
2031         if (curTime - wakeUpTime > THREE_MILLISECOND_DURATION) {
2032             AUDIO_WARNING_LOG("Wake up cost %{public}" PRId64" ms!", (curTime - wakeUpTime) / AUDIO_US_PER_SECOND);
2033         } else if (curTime - wakeUpTime > ONE_MILLISECOND_DURATION) {
2034             AUDIO_DEBUG_LOG("Wake up cost %{public}" PRId64" ms!", (curTime - wakeUpTime) / AUDIO_US_PER_SECOND);
2035         }
2036 
2037         curReadPos = dstAudioBuffer_->GetCurReadFrame();
2038         CHECK_AND_BREAK_LOG(ReadFromEndpoint(curReadPos) == SUCCESS, "read from endpoint to process service fail.");
2039 
2040         bool ret = RecordPrepareNextLoop(curReadPos, wakeUpTime);
2041         CHECK_AND_BREAK_LOG(ret, "PrepareNextLoop failed!");
2042 
2043         ProcessUpdateAppsUidForRecord();
2044 
2045         loopTrace.End();
2046         threadStatus_ = SLEEPING;
2047         ClockTime::AbsoluteSleep(wakeUpTime);
2048     }
2049 }
2050 
EndpointWorkLoopFuc()2051 void AudioEndpointInner::EndpointWorkLoopFuc()
2052 {
2053     ScheduleReportData(getpid(), gettid(), "audio_server");
2054     int64_t curTime = 0;
2055     uint64_t curWritePos = 0;
2056     int64_t wakeUpTime = ClockTime::GetCurNano();
2057     AUDIO_INFO_LOG("Endpoint work loop fuc start");
2058     int32_t ret = 0;
2059     while (isInited_.load()) {
2060         if (!KeepWorkloopRunning()) {
2061             continue;
2062         }
2063         ret = 0;
2064         threadStatus_ = INRUNNING;
2065         curTime = ClockTime::GetCurNano();
2066         Trace loopTrace("AudioEndpoint::loop_trace");
2067         if (needReSyncPosition_) {
2068             ReSyncPosition();
2069             wakeUpTime = curTime;
2070             needReSyncPosition_ = false;
2071             continue;
2072         }
2073         if (curTime - wakeUpTime > THREE_MILLISECOND_DURATION) {
2074             AUDIO_WARNING_LOG("Wake up cost %{public}" PRId64" ms!", (curTime - wakeUpTime) / AUDIO_US_PER_SECOND);
2075         } else if (curTime - wakeUpTime > ONE_MILLISECOND_DURATION) {
2076             AUDIO_DEBUG_LOG("Wake up cost %{public}" PRId64" ms!", (curTime - wakeUpTime) / AUDIO_US_PER_SECOND);
2077         }
2078 
2079         // First, wake up at client may-write-done time, and check if all process write done.
2080         // If not, do another sleep to the possible latest write time.
2081         curWritePos = dstAudioBuffer_->GetCurWriteFrame();
2082         if (!CheckAllBufferReady(wakeUpTime, curWritePos)) {
2083             curTime = ClockTime::GetCurNano();
2084         }
2085 
2086         // then do mix & write to hdi buffer and prepare next loop
2087         if (!ProcessToEndpointDataHandle(curWritePos)) {
2088             AUDIO_ERR_LOG("ProcessToEndpointDataHandle failed!");
2089             break;
2090         }
2091 
2092         // prepare info of next loop
2093         if (!PrepareNextLoop(curWritePos, wakeUpTime)) {
2094             AUDIO_ERR_LOG("PrepareNextLoop failed!");
2095             break;
2096         }
2097 
2098         ProcessUpdateAppsUidForPlayback();
2099 
2100         loopTrace.End();
2101         // start sleep
2102         threadStatus_ = SLEEPING;
2103         ClockTime::AbsoluteSleep(wakeUpTime);
2104     }
2105     AUDIO_DEBUG_LOG("Endpoint work loop fuc end, ret %{public}d", ret);
2106 }
2107 
InitLatencyMeasurement()2108 void AudioEndpointInner::InitLatencyMeasurement()
2109 {
2110     if (!AudioLatencyMeasurement::CheckIfEnabled()) {
2111         return;
2112     }
2113     signalDetectAgent_ = std::make_shared<SignalDetectAgent>();
2114     CHECK_AND_RETURN_LOG(signalDetectAgent_ != nullptr, "LatencyMeas signalDetectAgent_ is nullptr");
2115     signalDetectAgent_->sampleFormat_ = SAMPLE_S16LE;
2116     signalDetectAgent_->formatByteSize_ = GetFormatByteSize(SAMPLE_S16LE);
2117     latencyMeasEnabled_ = true;
2118     signalDetected_ = false;
2119 }
2120 
DeinitLatencyMeasurement()2121 void AudioEndpointInner::DeinitLatencyMeasurement()
2122 {
2123     signalDetectAgent_ = nullptr;
2124     latencyMeasEnabled_ = false;
2125 }
2126 
CheckPlaySignal(uint8_t * buffer,size_t bufferSize)2127 void AudioEndpointInner::CheckPlaySignal(uint8_t *buffer, size_t bufferSize)
2128 {
2129     if (!latencyMeasEnabled_) {
2130         return;
2131     }
2132     CHECK_AND_RETURN_LOG(signalDetectAgent_ != nullptr, "LatencyMeas signalDetectAgent_ is nullptr");
2133     size_t byteSize = static_cast<size_t>(GetFormatByteSize(dstStreamInfo_.format));
2134     size_t newlyCheckedTime = bufferSize / (dstStreamInfo_.samplingRate /
2135         MILLISECOND_PER_SECOND) / (byteSize * sizeof(uint8_t) * dstStreamInfo_.channels);
2136     detectedTime_ += newlyCheckedTime;
2137     if (detectedTime_ >= MILLISECOND_PER_SECOND && signalDetectAgent_->signalDetected_ &&
2138         !signalDetectAgent_->dspTimestampGot_) {
2139             AudioParamKey key = NONE;
2140             std::string condition = "debug_audio_latency_measurement";
2141             std::string dspTime = fastSink_->GetAudioParameter(key, condition);
2142             LatencyMonitor::GetInstance().UpdateDspTime(dspTime);
2143             LatencyMonitor::GetInstance().UpdateSinkOrSourceTime(true,
2144                 signalDetectAgent_->lastPeakBufferTime_);
2145             AUDIO_INFO_LOG("LatencyMeas fastSink signal detected");
2146             LatencyMonitor::GetInstance().ShowTimestamp(true);
2147             signalDetectAgent_->dspTimestampGot_ = true;
2148             signalDetectAgent_->signalDetected_ = false;
2149     }
2150     signalDetected_ = signalDetectAgent_->CheckAudioData(buffer, bufferSize);
2151     if (signalDetected_) {
2152         AUDIO_INFO_LOG("LatencyMeas fastSink signal detected");
2153         detectedTime_ = 0;
2154     }
2155 }
2156 
CheckRecordSignal(uint8_t * buffer,size_t bufferSize)2157 void AudioEndpointInner::CheckRecordSignal(uint8_t *buffer, size_t bufferSize)
2158 {
2159     if (!latencyMeasEnabled_) {
2160         return;
2161     }
2162     CHECK_AND_RETURN_LOG(signalDetectAgent_ != nullptr, "LatencyMeas signalDetectAgent_ is nullptr");
2163     signalDetected_ = signalDetectAgent_->CheckAudioData(buffer, bufferSize);
2164     if (signalDetected_) {
2165         AudioParamKey key = NONE;
2166         std::string condition = "debug_audio_latency_measurement";
2167         std::string dspTime = fastSource_->GetAudioParameter(key, condition);
2168         LatencyMonitor::GetInstance().UpdateSinkOrSourceTime(false,
2169             signalDetectAgent_->lastPeakBufferTime_);
2170         LatencyMonitor::GetInstance().UpdateDspTime(dspTime);
2171         AUDIO_INFO_LOG("LatencyMeas fastSource signal detected");
2172         signalDetected_ = false;
2173     }
2174 }
2175 
ProcessUpdateAppsUidForPlayback()2176 void AudioEndpointInner::ProcessUpdateAppsUidForPlayback()
2177 {
2178     std::vector<int32_t> appsUid;
2179     {
2180         std::lock_guard<std::mutex> lock(listLock_);
2181 
2182         appsUid.reserve(processList_.size());
2183         for (auto iProccessStream : processList_) {
2184             appsUid.push_back(iProccessStream->GetAppInfo().appUid);
2185         }
2186     }
2187     CHECK_AND_RETURN_LOG(fastSink_, "fastSink_ is nullptr");
2188     fastSink_->UpdateAppsUid(appsUid);
2189 }
2190 
ProcessUpdateAppsUidForRecord()2191 void AudioEndpointInner::ProcessUpdateAppsUidForRecord()
2192 {
2193     std::vector<int32_t> appsUid;
2194     {
2195         std::lock_guard<std::mutex> lock(listLock_);
2196 
2197         appsUid.reserve(processList_.size());
2198         for (auto iProccessStream : processList_) {
2199             appsUid.push_back(iProccessStream->GetAppInfo().appUid);
2200         }
2201     }
2202     CHECK_AND_RETURN_LOG(fastSource_, "fastSource_ is nullptr");
2203     fastSource_->UpdateAppsUid(appsUid);
2204 }
2205 
WriterRenderStreamStandbySysEvent(uint32_t sessionId,int32_t standby)2206 void AudioEndpointInner::WriterRenderStreamStandbySysEvent(uint32_t sessionId, int32_t standby)
2207 {
2208     std::shared_ptr<Media::MediaMonitor::EventBean> bean = std::make_shared<Media::MediaMonitor::EventBean>(
2209         Media::MediaMonitor::AUDIO, Media::MediaMonitor::STREAM_STANDBY,
2210         Media::MediaMonitor::BEHAVIOR_EVENT);
2211     bean->Add("STREAMID", static_cast<int32_t>(sessionId));
2212     bean->Add("STANDBY", standby);
2213     Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
2214 }
2215 
GetLinkedProcessCount()2216 uint32_t AudioEndpointInner::GetLinkedProcessCount()
2217 {
2218     std::lock_guard<std::mutex> lock(listLock_);
2219     return processList_.size();
2220 }
2221 } // namespace AudioStandard
2222 } // namespace OHOS
2223