• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef LOG_TAG
17 #define LOG_TAG "RemoteOffloadAudioRenderSink"
18 #endif
19 
20 #include "sink/remote_offload_audio_render_sink.h"
21 #include <climits>
22 #include <future>
23 #include "audio_hdi_log.h"
24 #include "audio_errors.h"
25 #include "audio_dump_pcm.h"
26 #include "volume_tools.h"
27 #include "media_monitor_manager.h"
28 #include "common/hdi_adapter_info.h"
29 #include "manager/hdi_adapter_manager.h"
30 
31 using namespace OHOS::HDI::DistributedAudio::Audio::V1_0;
32 
33 namespace OHOS {
34 namespace AudioStandard {
RemoteOffloadHdiCallbackImpl(RemoteOffloadAudioRenderSink * sink)35 RemoteOffloadHdiCallbackImpl::RemoteOffloadHdiCallbackImpl(RemoteOffloadAudioRenderSink *sink)
36     : sink_(sink)
37 {
38 }
39 
RenderCallback(AudioCallbackType type,int8_t & reserved,int8_t & cookie)40 int32_t RemoteOffloadHdiCallbackImpl::RenderCallback(AudioCallbackType type, int8_t &reserved, int8_t &cookie)
41 {
42     (void)reserved;
43     (void)cookie;
44     CHECK_AND_RETURN_RET_LOG(sink_ != nullptr, ERR_OPERATION_FAILED, "sink is nullptr");
45     if (!sink_->started_.load() || sink_->isFlushing_.load()) {
46         AUDIO_DEBUG_LOG("invalid call, started: %{public}d, isFlushing: %{public}d", sink_->started_.load(),
47             sink_->isFlushing_.load());
48         return SUCCESS;
49     }
50     sink_->hdiCallback_.serviceCallback_(static_cast<RenderCallbackType>(type));
51     return SUCCESS;
52 }
53 
ParamCallback(AudioExtParamKey key,const std::string & condition,const std::string & value,int8_t & reserved,int8_t cookie)54 int32_t RemoteOffloadHdiCallbackImpl::ParamCallback(AudioExtParamKey key, const std::string &condition,
55     const std::string &value, int8_t &reserved, int8_t cookie)
56 {
57     (void)key;
58     (void)condition;
59     (void)value;
60     (void)reserved;
61     (void)cookie;
62     return SUCCESS;
63 }
64 
RemoteOffloadAudioRenderSink(const std::string & deviceNetworkId)65 RemoteOffloadAudioRenderSink::RemoteOffloadAudioRenderSink(const std::string &deviceNetworkId)
66     : deviceNetworkId_(deviceNetworkId)
67 {
68     AUDIO_DEBUG_LOG("construction");
69 }
70 
~RemoteOffloadAudioRenderSink()71 RemoteOffloadAudioRenderSink::~RemoteOffloadAudioRenderSink()
72 {
73     if (sinkInited_.load()) {
74         DeInit();
75     }
76     AUDIO_INFO_LOG("volumeDataCount: %{public}" PRId64, volumeDataCount_);
77 }
78 
Init(const IAudioSinkAttr & attr)79 int32_t RemoteOffloadAudioRenderSink::Init(const IAudioSinkAttr &attr)
80 {
81     AUDIO_INFO_LOG("in");
82     std::lock_guard<std::mutex> lock(sinkMutex_);
83     Trace trace("RemoteOffloadAudioRenderSink::Init");
84     attr_ = attr;
85     int32_t ret = CreateRender();
86     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "create render fail");
87 
88     renderInited_.store(true);
89     sinkInited_.store(true);
90     return SUCCESS;
91 }
92 
DeInit(void)93 void RemoteOffloadAudioRenderSink::DeInit(void)
94 {
95     AUDIO_INFO_LOG("in");
96     Trace trace("RemoteOffloadAudioRenderSink::DeInit");
97     std::lock_guard<std::mutex> lock(sinkMutex_);
98     std::lock_guard<std::mutex> switchDeviceLock(switchDeviceMutex_);
99     sinkInited_.store(false);
100     renderInited_.store(false);
101     started_.store(false);
102     HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
103     std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_REMOTE);
104     CHECK_AND_RETURN(deviceManager != nullptr);
105     deviceManager->DestroyRender(deviceNetworkId_, hdiRenderId_);
106     deviceManager->UnRegistRenderSinkCallback(deviceNetworkId_, hdiRenderId_);
107     audioRender_.ForceSetRefPtr(nullptr);
108     hdiCallback_ = {};
109     muteCount_ = 0;
110     switchDeviceMute_ = false;
111     DumpFileUtil::CloseDumpFile(&dumpFile_);
112 }
113 
IsInited(void)114 bool RemoteOffloadAudioRenderSink::IsInited(void)
115 {
116     return sinkInited_.load();
117 }
118 
Start(void)119 int32_t RemoteOffloadAudioRenderSink::Start(void)
120 {
121     std::lock_guard<std::mutex> lock(sinkMutex_);
122     AUDIO_INFO_LOG("in");
123     Trace trace("RemoteOffloadAudioRenderSink::Start");
124     if (!renderInited_.load()) {
125         int32_t ret = CreateRender();
126         CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "create render fail");
127         renderInited_.store(true);
128     }
129     InitLatencyMeasurement();
130 
131     if (started_.load()) {
132         if (isFlushing_.load()) {
133             isNeedRestart_ = true;
134             AUDIO_ERR_LOG("start fail, will restart after flush");
135             return ERR_OPERATION_FAILED;
136         }
137         return SUCCESS;
138     }
139     AudioXCollie audioXCollie("RemoteOffloadAudioRenderSink::Start", TIMEOUT_SECONDS_10,
140          nullptr, nullptr, AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
141     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
142     int32_t ret = audioRender_->Start();
143     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "start fail, ret: %{public}d", ret);
144     UpdateSinkState(true);
145     dumpFileName_ = "remote_offload_sink_" + GetTime() + "_" + std::to_string(attr_.sampleRate) + "_" +
146         std::to_string(attr_.channel) + "_" + std::to_string(attr_.format) + ".pcm";
147     DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpFileName_, &dumpFile_);
148 
149     started_.store(true);
150     renderPos_ = 0;
151     return SUCCESS;
152 }
153 
Stop(void)154 int32_t RemoteOffloadAudioRenderSink::Stop(void)
155 {
156     std::lock_guard<std::mutex> lock(sinkMutex_);
157     AUDIO_INFO_LOG("in");
158     Trace trace("RemoteOffloadAudioRenderSink::Stop");
159     DeInitLatencyMeasurement();
160 
161     if (!started_.load()) {
162         UnLockOffloadRunningLock();
163         return SUCCESS;
164     }
165     int32_t ret = Flush();
166     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "flush fail");
167     AudioXCollie audioXCollie("RemoteOffloadAudioRenderSink::Stop", TIMEOUT_SECONDS_10,
168          nullptr, nullptr, AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
169     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
170     ret = audioRender_->Stop();
171     UpdateSinkState(false);
172     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "stop fail");
173     started_.store(false);
174 
175     return SUCCESS;
176 }
177 
Resume(void)178 int32_t RemoteOffloadAudioRenderSink::Resume(void)
179 {
180     std::lock_guard<std::mutex> lock(sinkMutex_);
181     AUDIO_INFO_LOG("in");
182     CHECK_AND_RETURN_RET_LOG(started_.load(), ERR_ILLEGAL_STATE, "not start, invalid state");
183 
184     if (!paused_.load()) {
185         AUDIO_INFO_LOG("already resumed");
186         return SUCCESS;
187     }
188 
189     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
190     int32_t ret = audioRender_->Resume();
191     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "resume fail, ret: %{public}d", ret);
192     paused_.store(false);
193     return SUCCESS;
194 }
195 
Pause(void)196 int32_t RemoteOffloadAudioRenderSink::Pause(void)
197 {
198     std::lock_guard<std::mutex> lock(sinkMutex_);
199     AUDIO_INFO_LOG("in");
200     CHECK_AND_RETURN_RET_LOG(started_.load(), ERR_ILLEGAL_STATE, "not start, invalid state");
201 
202     if (paused_.load()) {
203         AUDIO_INFO_LOG("already paused");
204         return SUCCESS;
205     }
206 
207     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
208     int32_t ret = audioRender_->Pause();
209     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "pause fail, ret: %{public}d", ret);
210     paused_.store(true);
211     return SUCCESS;
212 }
213 
Flush(void)214 int32_t RemoteOffloadAudioRenderSink::Flush(void)
215 {
216     Trace trace("RemoteOffloadAudioRenderSink::Flush");
217     CHECK_AND_RETURN_RET_LOG(!isFlushing_.load(), ERR_OPERATION_FAILED, "duplicate flush");
218     CHECK_AND_RETURN_RET_LOG(started_.load(), ERR_OPERATION_FAILED, "not start, invalid state");
219 
220     isFlushing_.store(true);
221     std::thread([&] {
222         auto future = async(std::launch::async, [&] {
223             std::lock_guard<std::mutex> lock(sinkMutex_);
224             CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
225             return audioRender_->Flush();
226         });
227         if (future.wait_for(std::chrono::milliseconds(250)) == std::future_status::timeout) { // 250: max wait 250ms
228             AUDIO_ERR_LOG("flush fail, timeout of 250ms");
229         } else {
230             int32_t ret = future.get();
231             if (ret != SUCCESS) {
232                 AUDIO_ERR_LOG("flush fail, ret: %{public}d", ret);
233             }
234         }
235         isFlushing_.store(false);
236         FlushResetPosition();
237         if (isNeedRestart_) {
238             isNeedRestart_ = false;
239             Start();
240         }
241     }).detach();
242     renderPos_ = 0;
243     return SUCCESS;
244 }
245 
Reset(void)246 int32_t RemoteOffloadAudioRenderSink::Reset(void)
247 {
248     std::lock_guard<std::mutex> lock(sinkMutex_);
249     Trace trace("RemoteOffloadAudioRenderSink::Reset");
250     CHECK_AND_RETURN_RET_LOG(started_.load(), ERR_OPERATION_FAILED, "not start, invalid state");
251 
252     isNeedRestart_ = true;
253     int32_t ret = Flush();
254     if (ret != SUCCESS) {
255         isNeedRestart_ = false;
256         AUDIO_ERR_LOG("reset fail");
257         return ERR_OPERATION_FAILED;
258     }
259     return SUCCESS;
260 }
261 
RenderFrame(char & data,uint64_t len,uint64_t & writeLen)262 int32_t RemoteOffloadAudioRenderSink::RenderFrame(char &data, uint64_t len, uint64_t &writeLen)
263 {
264     int64_t stamp = ClockTime::GetCurNano();
265     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
266     CHECK_AND_RETURN_RET_LOG(started_.load(), ERR_OPERATION_FAILED, "not start, invalid state");
267     CHECK_AND_RETURN_RET_LOG(!isFlushing_.load(), ERR_OPERATION_FAILED, "during flushing");
268 
269     Trace trace("RemoteOffloadAudioRenderSink::RenderFrame");
270     CheckLatencySignal(reinterpret_cast<uint8_t *>(&data), len);
271     std::vector<int8_t> bufferVec(len);
272     int32_t ret = memcpy_s(bufferVec.data(), len, &data, len);
273     CHECK_AND_RETURN_RET_LOG(ret == EOK, ERR_OPERATION_FAILED, "copy fail, error code: %{public}d", ret);
274 
275     ret = audioRender_->RenderFrame(bufferVec, writeLen);
276 #ifdef FEATURE_POWER_MANAGER
277     if (runningLock_) {
278         runningLock_->UpdateAppsUidToPowerMgr();
279     }
280 #endif
281     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_WRITE_FAILED, "fail, ret: %{public}x", ret);
282     if (writeLen != 0) {
283         BufferDesc buffer = { reinterpret_cast<uint8_t *>(&data), len, len };
284         AudioStreamInfo streamInfo(static_cast<AudioSamplingRate>(attr_.sampleRate), AudioEncodingType::ENCODING_PCM,
285             static_cast<AudioSampleFormat>(attr_.format), static_cast<AudioChannel>(attr_.channel));
286         VolumeTools::DfxOperation(buffer, streamInfo, logUtilsTag_, volumeDataCount_, OFFLOAD_DFX_SPLIT);
287         if (AudioDump::GetInstance().GetVersionType() == DumpFileUtil::BETA_VERSION) {
288             DumpFileUtil::WriteDumpFile(dumpFile_, static_cast<void *>(&data), writeLen);
289             AudioCacheMgr::GetInstance().CacheData(dumpFileName_, static_cast<void *>(&data), writeLen);
290         }
291         CheckUpdateState(&data, len);
292     }
293     renderPos_ += writeLen;
294     stamp = (ClockTime::GetCurNano() - stamp) / AUDIO_US_PER_SECOND;
295     int64_t stampThresholdMs = 50; // 50ms
296     if (stamp >= stampThresholdMs) {
297         AUDIO_WARNING_LOG("len: [%{public}" PRIu64 "], cost: [%{public}" PRId64 "]ms", len, stamp);
298     }
299     return SUCCESS;
300 }
301 
GetVolumeDataCount(void)302 int64_t RemoteOffloadAudioRenderSink::GetVolumeDataCount(void)
303 {
304     return volumeDataCount_;
305 }
306 
SuspendRenderSink(void)307 int32_t RemoteOffloadAudioRenderSink::SuspendRenderSink(void)
308 {
309     return SUCCESS;
310 }
311 
RestoreRenderSink(void)312 int32_t RemoteOffloadAudioRenderSink::RestoreRenderSink(void)
313 {
314     return SUCCESS;
315 }
316 
SetAudioParameter(const AudioParamKey key,const std::string & condition,const std::string & value)317 void RemoteOffloadAudioRenderSink::SetAudioParameter(const AudioParamKey key, const std::string &condition,
318     const std::string &value)
319 {
320 }
321 
GetAudioParameter(const AudioParamKey key,const std::string & condition)322 std::string RemoteOffloadAudioRenderSink::GetAudioParameter(const AudioParamKey key, const std::string &condition)
323 {
324     return "";
325 }
326 
SetVolume(float left,float right)327 int32_t RemoteOffloadAudioRenderSink::SetVolume(float left, float right)
328 {
329     std::lock_guard<std::mutex> lock(switchDeviceMutex_);
330     Trace trace("RemoteOffloadAudioRenderSink::SetVolume");
331 
332     leftVolume_ = left;
333     rightVolume_ = right;
334 
335     if (switchDeviceMute_) {
336         AUDIO_WARNING_LOG("mute for switch device, store volume, left: %{public}f, right: %{public}f", left, right);
337         return SUCCESS;
338     }
339     return SetVolumeInner(left, right);
340 }
341 
GetVolume(float & left,float & right)342 int32_t RemoteOffloadAudioRenderSink::GetVolume(float &left, float &right)
343 {
344     left = leftVolume_;
345     right = rightVolume_;
346     return SUCCESS;
347 }
348 
GetHdiLatency(uint32_t & latency)349 int32_t RemoteOffloadAudioRenderSink::GetHdiLatency(uint32_t &latency)
350 {
351     std::lock_guard<std::mutex> lock(sinkMutex_);
352     Trace trace("RemoteOffloadAudioRenderSink::GetLatency");
353 
354     if (hdiLatencyUS_ == 0) {
355         int32_t result = GetLatencyInner();
356         CHECK_AND_RETURN_RET_LOG(result == SUCCESS, result, "GetLatencyInner failed");
357     }
358 
359     latency = hdiLatencyUS_;
360     AUDIO_DEBUG_LOG("RemoteOffloadAudioRenderSink::GetHdiLatency hdiLatencyUS_ %{public}u", hdiLatencyUS_);
361     return SUCCESS;
362 }
363 
GetLatencyInner()364 int32_t RemoteOffloadAudioRenderSink::GetLatencyInner()
365 {
366     Trace trace("RemoteOffloadAudioRenderSink::GetLatencyInner");
367     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
368 
369     uint32_t hdiLatencyMS;
370     int32_t ret = audioRender_->GetLatency(hdiLatencyMS);
371     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "get latency fail, ret: %{public}d", ret);
372 
373     hdiLatencyUS_ = hdiLatencyMS * MICROSECOND_PER_MILLISECOND;
374     return SUCCESS;
375 }
376 
GetLatency(uint32_t & latency)377 int32_t RemoteOffloadAudioRenderSink::GetLatency(uint32_t &latency)
378 {
379     std::lock_guard<std::mutex> lock(sinkMutex_);
380 
381     // calc sample count (after scaling to one times speed) first
382     int32_t ret = SUCCESS;
383 
384     ret = lastHdiOriginFramesUS_ > 0 ? EstimateRenderPosition() : GetRenderPositionInner();
385     AUDIO_DEBUG_LOG("RemoteOffloadAudioRenderSink::GetOriginLatency lastHdiOriginFramesUS_: %{public}" PRIu64,
386         lastHdiOriginFramesUS_);
387 
388     // then get origin latency, because when calc sample count, record latency Deque
389     if (hdiLatencyUS_ == 0) {
390         int32_t result = GetLatencyInner();
391         CHECK_AND_RETURN_RET_LOG(result == SUCCESS, result, "GetLatencyInner failed");
392     }
393 
394     uint32_t realLatencyUS = 0;
395     uint32_t originLatencyUS = 0;
396     for (const auto &rl : realLatencyDeque_) {
397         if (realLatencyUS + rl.first <= hdiLatencyUS_) {
398             realLatencyUS += rl.first;
399             originLatencyUS += rl.first * rl.second;
400         } else {
401             uint32_t remainingLength = hdiLatencyUS_ - realLatencyUS;
402             realLatencyUS += remainingLength;
403             originLatencyUS += remainingLength * rl.second;
404             break;
405         }
406     }
407     AUDIO_DEBUG_LOG("RemoteOffloadAudioRenderSink::GetLatency originLatencyUS: %{public}u", originLatencyUS);
408 
409     uint64_t positionUS = lastHdiOriginFramesUS_ > originLatencyUS ? lastHdiOriginFramesUS_ - originLatencyUS : 0;
410     uint64_t renderFrameUS = renderPos_ * SECOND_TO_MICROSECOND /
411         (attr_.sampleRate * static_cast<uint32_t>(GetFormatByteSize(attr_.format)) * attr_.channel);
412     AUDIO_DEBUG_LOG("RemoteOffloadAudioRenderSink::GetOriginLatency renderFrameUS: %{public}" PRIu64, renderFrameUS);
413     latency = renderFrameUS > positionUS ? (renderFrameUS - positionUS) / MICROSECOND_PER_MILLISECOND : 0;
414     return ret;
415 }
416 
GetTransactionId(uint64_t & transactionId)417 int32_t RemoteOffloadAudioRenderSink::GetTransactionId(uint64_t &transactionId)
418 {
419     AUDIO_INFO_LOG("not support");
420     return ERR_NOT_SUPPORTED;
421 }
422 
GetHdiPresentationPosition(uint64_t & frames,int64_t & timeSec,int64_t & timeNanoSec)423 int32_t RemoteOffloadAudioRenderSink::GetHdiPresentationPosition(uint64_t &frames, int64_t &timeSec,
424     int64_t &timeNanoSec)
425 {
426     std::lock_guard<std::mutex> lock(sinkMutex_);
427 
428     // If the sample data is not zero, it means that after obtaining the sample count,
429     // the latest sample data can be inferred.
430     int32_t ret = lastHdiFramesUS_ > 0 ? EstimateRenderPosition() : GetRenderPositionInner();
431     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED,
432         "RemoteOffloadAudioRenderSink::GetHdiPresentationPosition fail, ret: %{public}d", ret);
433     frames = lastHdiFramesUS_;
434     timeSec = lastHdiTimeSec_;
435     timeNanoSec = lastHdiTimeNanoSec_;
436     return SUCCESS;
437 }
438 
ForceRefreshPresentationPosition(uint64_t & frames,uint64_t & hdiFrames,int64_t & timeSec,int64_t & timeNanoSec)439 int32_t RemoteOffloadAudioRenderSink::ForceRefreshPresentationPosition(uint64_t &frames, uint64_t &hdiFrames,
440     int64_t &timeSec, int64_t &timeNanoSec)
441 {
442     std::lock_guard<std::mutex> lock(sinkMutex_);
443 
444     int32_t ret = GetRenderPositionInner();
445     AUDIO_INFO_LOG("RemoteOffloadAudioRenderSink::ForceRefreshPresentationPosition ret: %{public}d", ret);
446     frames = lastHdiOriginFramesUS_;
447     hdiFrames = lastHdiFramesUS_;
448     timeSec = lastHdiTimeSec_;
449     timeNanoSec = lastHdiTimeNanoSec_;
450     return ret;
451 }
452 
GetPresentationPosition(uint64_t & frames,int64_t & timeSec,int64_t & timeNanoSec)453 int32_t RemoteOffloadAudioRenderSink::GetPresentationPosition(uint64_t &frames, int64_t &timeSec, int64_t &timeNanoSec)
454 {
455     AUDIO_INFO_LOG("not support");
456     return ERR_NOT_SUPPORTED;
457 }
458 
EstimateRenderPosition()459 int32_t RemoteOffloadAudioRenderSink::EstimateRenderPosition()
460 {
461     // The sample count can be inferred based on the time interval
462     // between the current time and the last occurrence.
463     int64_t now = ClockTime::GetCurNano();
464     int64_t durationNS = now > lastSystemTimeNS_ ? now - lastSystemTimeNS_ : 0;
465     uint64_t durationUS = static_cast<uint64_t>(durationNS) / NANOSECOND_TO_MICROSECOND;
466 
467     // The underlying time recorded must be calculated because this time increments at a fixed rate
468     // regardless of whether it is played or not, or whether there is buffering or not
469     lastHdiTimeNS_ += durationNS;
470     lastHdiTimeSec_ = lastHdiTimeNS_ / AUDIO_NS_PER_SECOND;
471     lastHdiTimeNanoSec_ = lastHdiTimeNS_ % AUDIO_NS_PER_SECOND;
472     // The system time also needs to be updated because it is fixed as well
473     lastSystemTimeNS_ = now;
474 
475     uint64_t renderFrameUS = renderPos_ * SECOND_TO_MICROSECOND /
476         (attr_.sampleRate * static_cast<uint32_t>(GetFormatByteSize(attr_.format)) * attr_.channel);
477     if (renderFrameUS <= lastHdiOriginFramesUS_) {
478         AUDIO_INFO_LOG("RemoteOffloadAudioRenderSink::EstimateRenderPosition renderFrameUS: %{public}" PRIu64
479             ", lastHdiFramesUS_: %{public}" PRIu64 " no need to estimate", renderFrameUS, lastHdiOriginFramesUS_);
480         return SUCCESS;
481     }
482 
483     uint64_t originFrameUS = lastHdiOriginFramesUS_ + durationUS * speed_;
484     if (originFrameUS > renderFrameUS) {
485         AUDIO_INFO_LOG("RemoteOffloadAudioRenderSink::EstimateRenderPosition renderFrameUS: %{public}" PRIu64
486             ", originFrameUS: %{public}" PRIu64 " set to renderFrameUS", renderFrameUS, originFrameUS);
487         auto excess = (renderFrameUS - lastHdiOriginFramesUS_) / speed_;
488         lastHdiOriginFramesUS_ = renderFrameUS;
489         lastHdiFramesUS_ += excess;
490 
491         AddHdiLatency(excess);
492         return SUCCESS;
493     }
494 
495     lastHdiFramesUS_ += durationUS;
496     lastHdiOriginFramesUS_ += durationUS * speed_;
497 
498     AddHdiLatency(durationUS);
499     return SUCCESS;
500 }
501 
GetRenderPositionInner()502 int32_t RemoteOffloadAudioRenderSink::GetRenderPositionInner()
503 {
504     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
505     CHECK_AND_RETURN_RET_LOG(!isFlushing_.load(), ERR_OPERATION_FAILED, "during flushing");
506 
507     uint64_t tmpFrames;
508     struct AudioTimeStamp stamp = {};
509     int32_t ret = audioRender_->GetRenderPosition(tmpFrames, stamp);
510     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "get render position fail, ret: %{public}d", ret);
511     int64_t maxSec = 9223372036; // (9223372036 + 1) * 10^9 > INT64_MAX, seconds should not bigger than it
512     CHECK_AND_RETURN_RET_LOG(stamp.tvSec >= 0 && stamp.tvSec <= maxSec && stamp.tvNSec >= 0 &&
513         stamp.tvNSec <= SECOND_TO_NANOSECOND, ERR_OPERATION_FAILED,
514         "get invalid time, second: %{public}" PRId64 ", nanosecond: %{public}" PRId64, stamp.tvSec, stamp.tvNSec);
515     CHECK_AND_RETURN_RET_LOG(tmpFrames <= UINT64_MAX / SECOND_TO_MICROSECOND, ERR_OPERATION_FAILED,
516         "frames overflow, tmpFrames: %{public}" PRIu64, tmpFrames);
517     CHECK_AND_RETURN_RET_LOG(attr_.sampleRate != 0, ERR_OPERATION_FAILED, "invalid sample rate");
518     uint64_t frames = tmpFrames * SECOND_TO_MICROSECOND / attr_.sampleRate;
519     int64_t timeSec = stamp.tvSec;
520     int64_t timeNanoSec = stamp.tvNSec;
521     AUDIO_DEBUG_LOG("RemoteOffloadAudioRenderSink::GetRenderPositionInner framesUS: [%{public}" PRIu64
522         "],[tmpFrames: %{public}" PRIu64 "]", frames, tmpFrames);
523 
524     CheckHdiTime(timeSec, timeNanoSec);
525     CalcHdiPosition(frames, timeSec, timeNanoSec);
526     return ret;
527 }
528 
CheckHdiTime(int64_t & timeSec,int64_t & timeNanoSec)529 void RemoteOffloadAudioRenderSink::CheckHdiTime(int64_t &timeSec, int64_t &timeNanoSec)
530 {
531     // check hdi timestamp out of range 40 * 1000 * 1000 ns
532     struct timespec curStamp;
533     if (clock_gettime(CLOCK_MONOTONIC, &curStamp) >= 0) {
534         int64_t curNs = curStamp.tv_sec * AUDIO_NS_PER_SECOND + curStamp.tv_nsec;
535         int64_t hdiNs = timeSec * AUDIO_NS_PER_SECOND + timeNanoSec;
536         int64_t outNs = 40 * 1000 * 1000; // 40 * 1000 * 1000 ns
537         if (curNs <= hdiNs || curNs > hdiNs + outNs) {
538             AUDIO_PRERELEASE_LOGW("HDI time is not in the range, hdi: %{public}" PRId64 ", cur: %{public}" PRId64,
539                 hdiNs, curNs);
540             timeSec = curStamp.tv_sec;
541             timeNanoSec = curStamp.tv_nsec;
542         }
543     }
544 }
545 
FlushResetPosition()546 void RemoteOffloadAudioRenderSink::FlushResetPosition()
547 {
548     std::lock_guard<std::mutex> lock(sinkMutex_);
549 
550     // If the previous sampling time is null, it indicates that a reset has already been performed; return directly.
551     if (lastHdiOriginFramesUS_ == 0) {
552         return;
553     }
554 
555     // Calculate the latest sampling time during flush operations
556     // += previous sampling time + (current system time - previous system sampling time) * rate / 1000
557     // after scaling to one times speed
558     lastHdiOriginFlushFramesUS_ += lastHdiOriginFramesUS_ +
559         (ClockTime::GetCurNano() - lastSystemTimeNS_) * speed_ / NANOSECOND_TO_MICROSECOND;
560     // before scaling to one times speed
561     lastHdiFlushFramesUS_ += lastHdiFramesUS_ +
562         (ClockTime::GetCurNano() - lastSystemTimeNS_) / NANOSECOND_TO_MICROSECOND;
563     AUDIO_INFO_LOG("RemoteOffloadAudioRenderSink::FlushResetPosition lastHdiOriginFlushFramesUS_: [%{public}" PRIu64
564         "], lastHdiFlushFramesUS_: [%{public}" PRIu64 "]", lastHdiOriginFlushFramesUS_, lastHdiFlushFramesUS_);
565 
566     lastHdiFramesUS_ = 0;
567     lastHdiOriginFramesUS_ = 0;
568     realLatencyDeque_.clear();
569     realLatencyTotalUS_ = 0;
570 }
571 
CalcHdiPosition(uint64_t frames,int64_t timeSec,int64_t timeNanoSec)572 void RemoteOffloadAudioRenderSink::CalcHdiPosition(uint64_t frames, int64_t timeSec, int64_t timeNanoSec)
573 {
574     // If the current sampling time is earlier than the previous inferred sampling time.
575     // It indicates that the inference has an error and needs correction.
576     if (frames < lastHdiOriginFramesUS_) {
577         auto duration = (lastHdiOriginFramesUS_ - frames) / speed_;
578         lastHdiFramesUS_ = lastHdiFramesUS_ > duration ? lastHdiFramesUS_ - duration : 0;
579         RemoveHdiLatency(duration);
580     } else {
581         auto duration = (frames - lastHdiOriginFramesUS_) / speed_;
582         lastHdiFramesUS_ += duration;
583         AddHdiLatency(duration);
584     }
585 
586     lastHdiOriginFramesUS_ = frames;
587     lastSystemTimeNS_ = ClockTime::GetCurNano();
588     lastHdiTimeNS_ = timeNanoSec + timeSec * AUDIO_NS_PER_SECOND;
589     lastHdiTimeSec_ = timeSec;
590     lastHdiTimeNanoSec_ = timeNanoSec;
591 }
592 
RemoveHdiLatency(uint32_t duration)593 void RemoteOffloadAudioRenderSink::RemoveHdiLatency(uint32_t duration)
594 {
595     AUDIO_INFO_LOG("RemoteOffloadAudioRenderSink::RemoveHdiLatency duration: %{public}u", duration);
596     if (realLatencyTotalUS_ <= duration) {
597         realLatencyTotalUS_ = 0;
598         realLatencyDeque_.clear();
599         return;
600     }
601 
602     while (duration > 0) {
603         if (duration >= realLatencyDeque_.front().first) {
604             duration -= realLatencyDeque_.front().first;
605             realLatencyTotalUS_ -= realLatencyDeque_.front().first;
606             realLatencyDeque_.pop_front();
607         } else {
608             realLatencyDeque_.front().first -= duration;
609             realLatencyTotalUS_ -= duration;
610             duration = 0;
611         }
612     }
613     AUDIO_INFO_LOG("RemoteOffloadAudioRenderSink::RemoveHdiLatency realLatencyTotalUS_: %{public}u",
614         realLatencyTotalUS_);
615 }
616 
AddHdiLatency(uint32_t duration)617 void RemoteOffloadAudioRenderSink::AddHdiLatency(uint32_t duration)
618 {
619     AUDIO_DEBUG_LOG("RemoteOffloadAudioRenderSink::AddHdiLatency duration: %{public}u, speed: %{public}f",
620         duration, speed_);
621     realLatencyTotalUS_ += duration;
622     realLatencyDeque_.push_front({duration, speed_});
623 
624     uint32_t maxDequeLengthUS = 1000000;
625     // If the total length exceeds 1,000,000 microseconds.
626     // clear the end of the queue to ensure the maximum length remains at 1,000,000 microseconds.
627     while (realLatencyTotalUS_ > maxDequeLengthUS) {
628         if (realLatencyTotalUS_ - realLatencyDeque_.back().first >= maxDequeLengthUS) {
629             realLatencyTotalUS_ -= realLatencyDeque_.back().first;
630             realLatencyDeque_.pop_back();
631         } else {
632             uint32_t excess = realLatencyTotalUS_ - maxDequeLengthUS;
633             realLatencyDeque_.back().first -= excess;
634             realLatencyTotalUS_ -= excess;
635         }
636     }
637     AUDIO_DEBUG_LOG("RemoteOffloadAudioRenderSink::AddHdiLatency realLatencyTotalUS_: %{public}u",
638         realLatencyTotalUS_);
639 }
640 
GetMaxAmplitude(void)641 float RemoteOffloadAudioRenderSink::GetMaxAmplitude(void)
642 {
643     lastGetMaxAmplitudeTime_ = ClockTime::GetCurNano();
644     startUpdate_ = true;
645     return maxAmplitude_;
646 }
647 
SetAudioMonoState(bool audioMono)648 void RemoteOffloadAudioRenderSink::SetAudioMonoState(bool audioMono)
649 {
650     AUDIO_INFO_LOG("not support");
651 }
652 
SetAudioBalanceValue(float audioBalance)653 void RemoteOffloadAudioRenderSink::SetAudioBalanceValue(float audioBalance)
654 {
655     AUDIO_INFO_LOG("not support");
656 }
657 
SetSinkMuteForSwitchDevice(bool mute)658 int32_t RemoteOffloadAudioRenderSink::SetSinkMuteForSwitchDevice(bool mute)
659 {
660     std::lock_guard<std::mutex> lock(switchDeviceMutex_);
661     AUDIO_INFO_LOG("set offload mute %{public}d", mute);
662 
663     if (mute) {
664         muteCount_++;
665         if (switchDeviceMute_) {
666             AUDIO_INFO_LOG("offload already muted");
667             return SUCCESS;
668         }
669         switchDeviceMute_ = true;
670         SetVolumeInner(0.0f, 0.0f);
671     } else {
672         muteCount_--;
673         if (muteCount_ > 0) {
674             AUDIO_WARNING_LOG("offload not all unmuted");
675             return SUCCESS;
676         }
677         switchDeviceMute_ = false;
678         muteCount_ = 0;
679         SetVolumeInner(leftVolume_, rightVolume_);
680     }
681 
682     return SUCCESS;
683 }
684 
SetSpeed(float speed)685 void RemoteOffloadAudioRenderSink::SetSpeed(float speed)
686 {
687     std::lock_guard<std::mutex> lock(sinkMutex_);
688     CHECK_AND_RETURN_LOG(audioRender_ != nullptr, "render is nullptr");
689 
690     AUDIO_INFO_LOG("speed: %{public}f", speed);
691     int32_t ret = audioRender_->SetRenderSpeed(speed);
692     CHECK_AND_RETURN_LOG(ret == SUCCESS, "set speed fail, ret: %{public}d", ret);
693 
694     // Every time the speed is set, the sampling count needs to be refreshed for two reasons:
695     // 1. For easier calculation, avoiding the need to consider multiple segments with different speeds
696     // 2. When setting the speed, the underlying system will wake up, eliminating concerns about power consumption
697     ret = GetRenderPositionInner();
698     AUDIO_INFO_LOG("RemoteOffloadAudioRenderSink::SetSpeed ret: %{public}d", ret);
699 
700     speed_ = speed;
701 }
702 
SetAudioScene(AudioScene audioScene,bool scoExcludeFlag)703 int32_t RemoteOffloadAudioRenderSink::SetAudioScene(AudioScene audioScene, bool scoExcludeFlag)
704 {
705     AUDIO_INFO_LOG("not support");
706     return ERR_NOT_SUPPORTED;
707 }
708 
GetAudioScene(void)709 int32_t RemoteOffloadAudioRenderSink::GetAudioScene(void)
710 {
711     AUDIO_INFO_LOG("not support");
712     return ERR_NOT_SUPPORTED;
713 }
714 
UpdateActiveDevice(std::vector<DeviceType> & outputDevices)715 int32_t RemoteOffloadAudioRenderSink::UpdateActiveDevice(std::vector<DeviceType> &outputDevices)
716 {
717     AUDIO_INFO_LOG("not support");
718     return ERR_NOT_SUPPORTED;
719 }
720 
RegistCallback(uint32_t type,IAudioSinkCallback * callback)721 void RemoteOffloadAudioRenderSink::RegistCallback(uint32_t type, IAudioSinkCallback *callback)
722 {
723     std::lock_guard<std::mutex> lock(sinkMutex_);
724     callback_.RegistCallback(type, callback);
725     AUDIO_INFO_LOG("regist succ");
726 }
727 
ResetActiveDeviceForDisconnect(DeviceType device)728 void RemoteOffloadAudioRenderSink::ResetActiveDeviceForDisconnect(DeviceType device)
729 {
730     AUDIO_INFO_LOG("not support");
731 }
732 
SetPaPower(int32_t flag)733 int32_t RemoteOffloadAudioRenderSink::SetPaPower(int32_t flag)
734 {
735     AUDIO_INFO_LOG("not support");
736     return ERR_NOT_SUPPORTED;
737 }
738 
SetPriPaPower(void)739 int32_t RemoteOffloadAudioRenderSink::SetPriPaPower(void)
740 {
741     AUDIO_INFO_LOG("not support");
742     return ERR_NOT_SUPPORTED;
743 }
744 
UpdateAppsUid(const int32_t appsUid[MAX_MIX_CHANNELS],const size_t size)745 int32_t RemoteOffloadAudioRenderSink::UpdateAppsUid(const int32_t appsUid[MAX_MIX_CHANNELS], const size_t size)
746 {
747 #ifdef FEATURE_POWER_MANAGER
748     CHECK_AND_RETURN_RET_LOG(runningLock_, ERR_INVALID_HANDLE, "running lock is nullptr");
749     runningLock_->UpdateAppsUid(appsUid, appsUid + size);
750 #endif
751     return SUCCESS;
752 }
753 
UpdateAppsUid(const std::vector<int32_t> & appsUid)754 int32_t RemoteOffloadAudioRenderSink::UpdateAppsUid(const std::vector<int32_t> &appsUid)
755 {
756 #ifdef FEATURE_POWER_MANAGER
757     CHECK_AND_RETURN_RET_LOG(runningLock_, ERR_INVALID_HANDLE, "running lock is nullptr");
758     runningLock_->UpdateAppsUid(appsUid.cbegin(), appsUid.cend());
759 #endif
760     return SUCCESS;
761 }
762 
Drain(AudioDrainType type)763 int32_t RemoteOffloadAudioRenderSink::Drain(AudioDrainType type)
764 {
765     Trace trace("RemoteOffloadAudioRenderSink::Drain");
766     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
767     auto drainType = static_cast<AudioDrainNotifyType>(type);
768     int32_t ret = audioRender_->DrainBuffer(drainType);
769     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "drain fail");
770     return SUCCESS;
771 }
772 
RegistOffloadHdiCallback(std::function<void (const RenderCallbackType type)> callback)773 void RemoteOffloadAudioRenderSink::RegistOffloadHdiCallback(std::function<void(const RenderCallbackType type)> callback)
774 {
775     CHECK_AND_RETURN_LOG(hdiCallback_.serviceCallback_ == nullptr, "already registed");
776     AUDIO_INFO_LOG("in");
777 
778     hdiCallback_ = {
779         .callback_ = new RemoteOffloadHdiCallbackImpl(this),
780         .serviceCallback_ = callback,
781     };
782     int32_t ret = audioRender_->RegCallback(hdiCallback_.callback_, (int8_t)0);
783     if (ret != SUCCESS) {
784         AUDIO_WARNING_LOG("fail, error code: %{public}d", ret);
785     }
786 }
787 
SetBufferSize(uint32_t sizeMs)788 int32_t RemoteOffloadAudioRenderSink::SetBufferSize(uint32_t sizeMs)
789 {
790     Trace trace("RemoteOffloadAudioRenderSink::SetBufferSize");
791     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
792     CHECK_AND_RETURN_RET_LOG(!isFlushing_.load(), ERR_OPERATION_FAILED, "during flushing");
793 
794     // 4: bytewidth
795     uint32_t size = (uint64_t) sizeMs * attr_.sampleRate * 4 * STEREO_CHANNEL_COUNT / SECOND_TO_MILLISECOND;
796     AUDIO_INFO_LOG("size: %{public}u, sizeMs: %{public}u", size, sizeMs);
797     AudioMmapBufferDescriptor desc;
798     int32_t ret = audioRender_->ReqMmapBuffer(size, desc);
799     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "set buffer size fail");
800     return SUCCESS;
801 }
802 
SetOffloadRenderCallbackType(RenderCallbackType type)803 int32_t RemoteOffloadAudioRenderSink::SetOffloadRenderCallbackType(RenderCallbackType type)
804 {
805     AUDIO_INFO_LOG("type: %{public}d", type);
806     CHECK_AND_RETURN_RET_LOG(hdiCallback_.serviceCallback_ != nullptr, ERR_ILLEGAL_STATE, "callback is nullptr");
807     CHECK_AND_RETURN_RET_LOG(started_.load() && !isFlushing_.load(), ERR_ILLEGAL_STATE,
808         "not start or flushing, invalid state");
809 
810     hdiCallback_.serviceCallback_(type);
811     return SUCCESS;
812 }
813 
LockOffloadRunningLock(void)814 int32_t RemoteOffloadAudioRenderSink::LockOffloadRunningLock(void)
815 {
816 #ifdef FEATURE_POWER_MANAGER
817     if (runningLock_ == nullptr) {
818         WatchTimeout guard("create AudioRunningLock start");
819         runningLock_ = std::make_shared<AudioRunningLock>(std::string(RUNNING_LOCK_NAME));
820         guard.CheckCurrTimeout();
821     }
822     CHECK_AND_RETURN_RET_LOG(runningLock_ != nullptr, ERR_OPERATION_FAILED,
823         "running lock is null, playback can not work well");
824     CHECK_AND_RETURN_RET(!runningLocked_, SUCCESS);
825     AUDIO_INFO_LOG("in");
826     runningLock_->Lock(RUNNING_LOCK_TIMEOUTMS_LASTING);
827     runningLocked_ = true;
828 #endif
829     return SUCCESS;
830 }
831 
UnLockOffloadRunningLock(void)832 int32_t RemoteOffloadAudioRenderSink::UnLockOffloadRunningLock(void)
833 {
834 #ifdef FEATURE_POWER_MANAGER
835     CHECK_AND_RETURN_RET_LOG(runningLock_ != nullptr, ERR_OPERATION_FAILED,
836         "running lock is null, playback can not work well");
837     CHECK_AND_RETURN_RET(runningLocked_, SUCCESS);
838     AUDIO_INFO_LOG("in");
839     runningLock_->UnLock();
840     runningLocked_ = false;
841 #endif
842     return SUCCESS;
843 }
844 
DumpInfo(std::string & dumpString)845 void RemoteOffloadAudioRenderSink::DumpInfo(std::string &dumpString)
846 {
847     dumpString += "type: RemoteOffloadSink\tstarted: " + std::string(started_.load() ? "true" : "false") + "\n";
848 }
849 
OnAudioParamChange(const std::string & adapterName,const AudioParamKey key,const std::string & condition,const std::string & value)850 void RemoteOffloadAudioRenderSink::OnAudioParamChange(const std::string &adapterName, const AudioParamKey key,
851     const std::string &condition, const std::string &value)
852 {
853     AUDIO_INFO_LOG("key: %{public}d, condition: %{public}s, value: %{public}s", key, condition.c_str(), value.c_str());
854     if (key == AudioParamKey::PARAM_KEY_STATE) {
855         DeInit();
856     }
857 
858     callback_.OnRenderSinkParamChange(adapterName, key, condition, value);
859 }
860 
SetDmDeviceType(uint16_t dmDeviceType,DeviceType deviceType)861 void RemoteOffloadAudioRenderSink::SetDmDeviceType(uint16_t dmDeviceType, DeviceType deviceType)
862 {
863     AUDIO_INFO_LOG("not support");
864 }
865 
PcmFormatToBit(AudioSampleFormat format)866 uint32_t RemoteOffloadAudioRenderSink::PcmFormatToBit(AudioSampleFormat format)
867 {
868     AudioFormat hdiFormat = ConvertToHdiFormat(format);
869     switch (hdiFormat) {
870         case AUDIO_FORMAT_TYPE_PCM_8_BIT:
871             return PCM_8_BIT;
872         case AUDIO_FORMAT_TYPE_PCM_16_BIT:
873             return PCM_16_BIT;
874         case AUDIO_FORMAT_TYPE_PCM_24_BIT:
875             return PCM_24_BIT;
876         case AUDIO_FORMAT_TYPE_PCM_32_BIT:
877             return PCM_32_BIT;
878         default:
879             AUDIO_DEBUG_LOG("unknown format type, set it to default");
880             return PCM_24_BIT;
881     }
882 }
883 
ConvertToHdiFormat(AudioSampleFormat format)884 AudioFormat RemoteOffloadAudioRenderSink::ConvertToHdiFormat(AudioSampleFormat format)
885 {
886     AudioFormat hdiFormat;
887     switch (format) {
888         case SAMPLE_U8:
889             hdiFormat = AUDIO_FORMAT_TYPE_PCM_8_BIT;
890             break;
891         case SAMPLE_S16LE:
892             hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT;
893             break;
894         case SAMPLE_S24LE:
895             hdiFormat = AUDIO_FORMAT_TYPE_PCM_24_BIT;
896             break;
897         case SAMPLE_S32LE:
898             hdiFormat = AUDIO_FORMAT_TYPE_PCM_32_BIT;
899             break;
900         default:
901             hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT;
902             break;
903     }
904     return hdiFormat;
905 }
906 
InitAudioSampleAttr(AudioSampleAttributes & param)907 void RemoteOffloadAudioRenderSink::InitAudioSampleAttr(AudioSampleAttributes &param)
908 {
909     param.channelCount = AUDIO_CHANNELCOUNT;
910     param.sampleRate = AUDIO_SAMPLE_RATE_48K;
911     param.interleaved = 0;
912     param.streamId = static_cast<int32_t>(GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_REMOTE_OFFLOAD));
913     param.type = AUDIO_OFFLOAD;
914     param.period = DEEP_BUFFER_RENDER_PERIOD_SIZE;
915     param.isBigEndian = false;
916     param.isSignedData = true;
917     param.stopThreshold = INT_MAX;
918     param.silenceThreshold = 0;
919 
920     param.sampleRate = attr_.sampleRate;
921     param.channelCount = attr_.channel;
922     param.format = ConvertToHdiFormat(attr_.format);
923     param.frameSize = PcmFormatToBit(attr_.format) * param.channelCount / PCM_8_BIT;
924     if (param.frameSize != 0) {
925         param.startThreshold = DEEP_BUFFER_RENDER_PERIOD_SIZE / (param.frameSize);
926     }
927 }
928 
InitDeviceDesc(AudioDeviceDescriptor & deviceDesc)929 void RemoteOffloadAudioRenderSink::InitDeviceDesc(AudioDeviceDescriptor &deviceDesc)
930 {
931     deviceDesc.pins = PIN_OUT_SPEAKER;
932     deviceDesc.desc = const_cast<char *>("");
933 }
934 
CreateRender(void)935 int32_t RemoteOffloadAudioRenderSink::CreateRender(void)
936 {
937     Trace trace("RemoteOffloadAudioRenderSink::CreateRender");
938 
939     AudioSampleAttributes param;
940     AudioDeviceDescriptor deviceDesc;
941     InitAudioSampleAttr(param);
942     InitDeviceDesc(deviceDesc);
943 
944     AUDIO_INFO_LOG("create render, rate: %{public}u, channel: %{public}u, format: %{public}u", param.sampleRate,
945         param.channelCount, param.format);
946     AudioXCollie audioXCollie("RemoteOffloadAudioRenderSink::CreateRender", TIMEOUT_SECONDS_10,
947          nullptr, nullptr, AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
948     HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
949     std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_REMOTE);
950     CHECK_AND_RETURN_RET(deviceManager != nullptr, ERR_INVALID_HANDLE);
951     void *render = deviceManager->CreateRender(deviceNetworkId_, &param, &deviceDesc, hdiRenderId_);
952     audioRender_.ForceSetRefPtr(static_cast<IAudioRender *>(render));
953     CHECK_AND_RETURN_RET(audioRender_ != nullptr, ERR_NOT_STARTED);
954     deviceManager->RegistRenderSinkCallback(deviceNetworkId_, hdiRenderId_, this);
955     return SUCCESS;
956 }
957 
InitLatencyMeasurement(void)958 void RemoteOffloadAudioRenderSink::InitLatencyMeasurement(void)
959 {
960     if (!AudioLatencyMeasurement::CheckIfEnabled()) {
961         return;
962     }
963 
964     AUDIO_INFO_LOG("in");
965     signalDetectAgent_ = std::make_shared<SignalDetectAgent>();
966     CHECK_AND_RETURN_LOG(signalDetectAgent_ != nullptr, "signalDetectAgent is nullptr");
967     signalDetectAgent_->sampleFormat_ = attr_.format;
968     signalDetectAgent_->formatByteSize_ = GetFormatByteSize(attr_.format);
969     signalDetected_ = false;
970 }
971 
DeInitLatencyMeasurement(void)972 void RemoteOffloadAudioRenderSink::DeInitLatencyMeasurement(void)
973 {
974     signalDetectAgent_ = nullptr;
975 }
976 
CheckLatencySignal(uint8_t * data,size_t len)977 void RemoteOffloadAudioRenderSink::CheckLatencySignal(uint8_t *data, size_t len)
978 {
979     CHECK_AND_RETURN(signalDetectAgent_ != nullptr);
980     uint32_t byteSize = static_cast<uint32_t>(GetFormatByteSize(attr_.format));
981     size_t newlyCheckedTime = len / (attr_.sampleRate / MILLISECOND_PER_SECOND) /
982         (byteSize * sizeof(uint8_t) * attr_.channel);
983     signalDetectedTime_ += newlyCheckedTime;
984     if (signalDetectedTime_ >= MILLISECOND_PER_SECOND && signalDetectAgent_->signalDetected_ &&
985         !signalDetectAgent_->dspTimestampGot_) {
986         AudioParamKey key = NONE;
987         std::string condition = "debug_audio_latency_measurement";
988         HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
989         std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_REMOTE);
990         CHECK_AND_RETURN(deviceManager != nullptr);
991         std::string value = deviceManager->GetAudioParameter(attr_.adapterName, key, condition);
992 
993         LatencyMonitor::GetInstance().UpdateDspTime(value.c_str());
994         LatencyMonitor::GetInstance().UpdateSinkOrSourceTime(true, signalDetectAgent_->lastPeakBufferTime_);
995         LatencyMonitor::GetInstance().ShowTimestamp(true);
996         signalDetectAgent_->dspTimestampGot_ = true;
997         signalDetectAgent_->signalDetected_ = false;
998     }
999     signalDetected_ = signalDetectAgent_->CheckAudioData(data, len);
1000     if (signalDetected_) {
1001         AUDIO_INFO_LOG("signal detected");
1002         signalDetectedTime_ = 0;
1003     }
1004 }
1005 
CheckUpdateState(char * data,uint64_t len)1006 void RemoteOffloadAudioRenderSink::CheckUpdateState(char *data, uint64_t len)
1007 {
1008     if (startUpdate_) {
1009         if (renderFrameNum_ == 0) {
1010             last10FrameStartTime_ = ClockTime::GetCurNano();
1011         }
1012         renderFrameNum_++;
1013         maxAmplitude_ = UpdateMaxAmplitude(static_cast<ConvertHdiFormat>(attr_.format), data, len);
1014         if (renderFrameNum_ == GET_MAX_AMPLITUDE_FRAMES_THRESHOLD) {
1015             renderFrameNum_ = 0;
1016             if (last10FrameStartTime_ > lastGetMaxAmplitudeTime_) {
1017                 startUpdate_ = false;
1018                 maxAmplitude_ = 0;
1019             }
1020         }
1021     }
1022 }
1023 
SetVolumeInner(float left,float right)1024 int32_t RemoteOffloadAudioRenderSink::SetVolumeInner(float left, float right)
1025 {
1026     AudioXCollie audioXCollie("RemoteOffloadAudioRenderSink::SetVolumeInner", TIMEOUT_SECONDS_10, nullptr, nullptr,
1027         AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
1028     AUDIO_INFO_LOG("set offload vol, left: %{public}f, right: %{public}f", left, right);
1029 
1030     CHECK_AND_RETURN_RET_LOG(!isFlushing_.load(), ERR_OPERATION_FAILED, "during flushing");
1031     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE,
1032         "render is nullptr, because set volume on device which offload is not available");
1033 
1034     float volume;
1035     if ((left == 0) && (right != 0)) {
1036         volume = right;
1037     } else if ((left != 0) && (right == 0)) {
1038         volume = left;
1039     } else {
1040         volume = (left + right) / HALF_FACTOR;
1041     }
1042 
1043     int32_t ret = audioRender_->SetVolume(volume);
1044     if (ret != SUCCESS) {
1045         AUDIO_WARNING_LOG("set volume fail");
1046     }
1047 
1048     return ret;
1049 }
1050 
1051 // must be called with sinkMutex_ held
UpdateSinkState(bool started)1052 void RemoteOffloadAudioRenderSink::UpdateSinkState(bool started)
1053 {
1054     callback_.OnRenderSinkStateChange(GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_REMOTE_OFFLOAD),
1055         started);
1056 }
1057 
1058 } // namespace AudioStandard
1059 } // namespace OHOS
1060