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