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