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 ¶m)
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_, ¶m, &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