• 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 "OffloadAudioRenderSink"
18 #endif
19 
20 #include "sink/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 namespace OHOS {
32 namespace AudioStandard {
~OffloadAudioRenderSink()33 OffloadAudioRenderSink::~OffloadAudioRenderSink()
34 {
35     AUDIO_INFO_LOG("volumeDataCount: %{public}" PRId64, volumeDataCount_);
36 }
37 
Init(const IAudioSinkAttr & attr)38 int32_t OffloadAudioRenderSink::Init(const IAudioSinkAttr &attr)
39 {
40     std::lock_guard<std::mutex> lock(sinkMutex_);
41     Trace trace("OffloadAudioRenderSink::Init");
42     attr_ = attr;
43     int32_t ret = CreateRender();
44     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "create render fail");
45 
46     sinkInited_ = true;
47     return SUCCESS;
48 }
49 
DeInit(void)50 void OffloadAudioRenderSink::DeInit(void)
51 {
52     AUDIO_INFO_LOG("in");
53     Trace trace("OffloadAudioRenderSink::DeInit");
54     std::lock_guard<std::mutex> lock(sinkMutex_);
55     std::lock_guard<std::mutex> switchDeviceLock(switchDeviceMutex_);
56     sinkInited_ = false;
57     started_ = false;
58     HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
59     std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_LOCAL);
60     CHECK_AND_RETURN(deviceManager != nullptr);
61     deviceManager->DestroyRender(attr_.adapterName, hdiRenderId_);
62     audioRender_ = nullptr;
63     hdiCallback_ = {};
64     muteCount_ = 0;
65     switchDeviceMute_ = false;
66     DumpFileUtil::CloseDumpFile(&dumpFile_);
67 }
68 
IsInited(void)69 bool OffloadAudioRenderSink::IsInited(void)
70 {
71     return sinkInited_;
72 }
73 
Start(void)74 int32_t OffloadAudioRenderSink::Start(void)
75 {
76     std::lock_guard<std::mutex> lock(sinkMutex_);
77     AUDIO_INFO_LOG("in");
78     Trace trace("OffloadAudioRenderSink::Start");
79     InitLatencyMeasurement();
80 
81     if (started_) {
82         if (isFlushing_) {
83             isNeedRestart_ = true;
84             AUDIO_ERR_LOG("start fail, will restart after flush");
85             return ERR_OPERATION_FAILED;
86         }
87         return SUCCESS;
88     }
89     AudioXCollie audioXCollie("OffloadAudioRenderSink::Start", TIMEOUT_SECONDS_10,
90          nullptr, nullptr, AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
91     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
92     int32_t ret = audioRender_->Start(audioRender_);
93     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "start fail, ret: %{public}d", ret);
94     UpdateSinkState(true);
95     dumpFileName_ = "offload_sink_" + GetTime() + "_" + std::to_string(attr_.sampleRate) + "_" +
96         std::to_string(attr_.channel) + "_" + std::to_string(attr_.format) + ".pcm";
97     DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpFileName_, &dumpFile_);
98 
99     started_ = true;
100     renderPos_ = 0;
101     return SUCCESS;
102 }
103 
Stop(void)104 int32_t OffloadAudioRenderSink::Stop(void)
105 {
106     std::lock_guard<std::mutex> lock(sinkMutex_);
107     AUDIO_INFO_LOG("in");
108     Trace trace("OffloadAudioRenderSink::Stop");
109     DeInitLatencyMeasurement();
110     if (!started_) {
111         UnLockOffloadRunningLock();
112         return SUCCESS;
113     }
114     int32_t ret = Flush();
115     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "flush fail");
116     AudioXCollie audioXCollie("OffloadAudioRenderSink::Stop", TIMEOUT_SECONDS_10,
117          nullptr, nullptr, AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
118     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
119     ret = audioRender_->Stop(audioRender_);
120     UpdateSinkState(false);
121     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "stop fail");
122     started_ = false;
123 
124     return SUCCESS;
125 }
126 
Resume(void)127 int32_t OffloadAudioRenderSink::Resume(void)
128 {
129     AUDIO_INFO_LOG("not support");
130     return ERR_NOT_SUPPORTED;
131 }
132 
Pause(void)133 int32_t OffloadAudioRenderSink::Pause(void)
134 {
135     AUDIO_INFO_LOG("not support");
136     return ERR_NOT_SUPPORTED;
137 }
138 
Flush(void)139 int32_t OffloadAudioRenderSink::Flush(void)
140 {
141     Trace trace("OffloadAudioRenderSink::Flush");
142     CHECK_AND_RETURN_RET_LOG(!isFlushing_, ERR_OPERATION_FAILED, "duplicate flush");
143     CHECK_AND_RETURN_RET_LOG(started_, ERR_OPERATION_FAILED, "not start, invalid state");
144 
145     isFlushing_ = true;
146     std::thread([&] {
147         auto future = async(std::launch::async, [&] {
148             std::lock_guard<std::mutex> lock(sinkMutex_);
149             CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
150             return audioRender_->Flush(audioRender_);
151         });
152         if (future.wait_for(std::chrono::milliseconds(250)) == std::future_status::timeout) { // 250: max wait 250ms
153             AUDIO_ERR_LOG("flush fail, timeout of 250ms");
154         } else {
155             int32_t ret = future.get();
156             if (ret != SUCCESS) {
157                 AUDIO_ERR_LOG("flush fail, ret: %{public}d", ret);
158             }
159         }
160         isFlushing_ = false;
161         if (isNeedRestart_) {
162             isNeedRestart_ = false;
163             Start();
164         }
165     }).detach();
166     renderPos_ = 0;
167     return SUCCESS;
168 }
169 
Reset(void)170 int32_t OffloadAudioRenderSink::Reset(void)
171 {
172     Trace trace("OffloadAudioRenderSink::Reset");
173     CHECK_AND_RETURN_RET_LOG(started_, ERR_OPERATION_FAILED, "not start, invalid state");
174 
175     isNeedRestart_ = true;
176     int32_t ret = Flush();
177     if (ret != SUCCESS) {
178         isNeedRestart_ = false;
179         AUDIO_ERR_LOG("reset fail");
180         return ERR_OPERATION_FAILED;
181     }
182     return SUCCESS;
183 }
184 
RenderFrame(char & data,uint64_t len,uint64_t & writeLen)185 int32_t OffloadAudioRenderSink::RenderFrame(char &data, uint64_t len, uint64_t &writeLen)
186 {
187     int64_t stamp = ClockTime::GetCurNano();
188     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
189     CHECK_AND_RETURN_RET_LOG(started_, ERR_OPERATION_FAILED, "not start, invalid state");
190     CHECK_AND_RETURN_RET_LOG(!isFlushing_, ERR_OPERATION_FAILED, "during flushing");
191 
192     if (audioMonoState_) {
193         AdjustStereoToMono(&data, len);
194     }
195     if (audioBalanceState_) {
196         AdjustAudioBalance(&data, len);
197     }
198     Trace trace("OffloadAudioRenderSink::RenderFrame");
199     CheckLatencySignal(reinterpret_cast<uint8_t *>(&data), len);
200     int32_t ret = audioRender_->RenderFrame(audioRender_, reinterpret_cast<int8_t *>(&data), static_cast<uint32_t>(len),
201         &writeLen);
202 #ifdef FEATURE_POWER_MANAGER
203     if (runningLock_) {
204         runningLock_->UpdateAppsUidToPowerMgr();
205     }
206 #endif
207     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_WRITE_FAILED, "fail, ret: %{public}x", ret);
208     if (writeLen != 0) {
209         BufferDesc buffer = { reinterpret_cast<uint8_t *>(&data), len, len };
210         AudioStreamInfo streamInfo(static_cast<AudioSamplingRate>(attr_.sampleRate), AudioEncodingType::ENCODING_PCM,
211             static_cast<AudioSampleFormat>(attr_.format), static_cast<AudioChannel>(attr_.channel));
212         VolumeTools::DfxOperation(buffer, streamInfo, logUtilsTag_, volumeDataCount_, OFFLOAD_DFX_SPLIT);
213         if (AudioDump::GetInstance().GetVersionType() == DumpFileUtil::BETA_VERSION) {
214             DumpFileUtil::WriteDumpFile(dumpFile_, static_cast<void *>(&data), writeLen);
215             AudioCacheMgr::GetInstance().CacheData(dumpFileName_, static_cast<void *>(&data), writeLen);
216         }
217         CheckUpdateState(&data, len);
218     }
219     renderPos_ += writeLen;
220     stamp = (ClockTime::GetCurNano() - stamp) / AUDIO_US_PER_SECOND;
221     int64_t stampThreshold = 50; // 50ms
222     if (stamp >= stampThreshold) {
223         AUDIO_WARNING_LOG("len: [%{public}" PRIu64 "], cost: [%{public}" PRId64 "]ms", len, stamp);
224     }
225     return SUCCESS;
226 }
227 
GetVolumeDataCount()228 int64_t OffloadAudioRenderSink::GetVolumeDataCount()
229 {
230     return volumeDataCount_;
231 }
232 
SuspendRenderSink(void)233 int32_t OffloadAudioRenderSink::SuspendRenderSink(void)
234 {
235     return SUCCESS;
236 }
237 
RestoreRenderSink(void)238 int32_t OffloadAudioRenderSink::RestoreRenderSink(void)
239 {
240     return SUCCESS;
241 }
242 
SetAudioParameter(const AudioParamKey key,const std::string & condition,const std::string & value)243 void OffloadAudioRenderSink::SetAudioParameter(const AudioParamKey key, const std::string &condition,
244     const std::string &value)
245 {
246 }
247 
GetAudioParameter(const AudioParamKey key,const std::string & condition)248 std::string OffloadAudioRenderSink::GetAudioParameter(const AudioParamKey key, const std::string &condition)
249 {
250     return "";
251 }
252 
SetVolume(float left,float right)253 int32_t OffloadAudioRenderSink::SetVolume(float left, float right)
254 {
255     std::lock_guard<std::mutex> lock(switchDeviceMutex_);
256     Trace trace("OffloadAudioRenderSink::SetVolume");
257 
258     leftVolume_ = left;
259     rightVolume_ = right;
260 
261     if (switchDeviceMute_) {
262         AUDIO_WARNING_LOG("mute for switch device, store volume, left: %{public}f, right: %{public}f", left, right);
263         return SUCCESS;
264     }
265     return SetVolumeInner(left, right);
266 }
267 
GetVolume(float & left,float & right)268 int32_t OffloadAudioRenderSink::GetVolume(float &left, float &right)
269 {
270     left = leftVolume_;
271     right = rightVolume_;
272     return SUCCESS;
273 }
274 
GetLatency(uint32_t & latency)275 int32_t OffloadAudioRenderSink::GetLatency(uint32_t &latency)
276 {
277     Trace trace("OffloadAudioRenderSink::GetLatency");
278     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
279 
280     // 4: bytewidth
281     uint64_t hdiLatency = renderPos_ * SECOND_TO_MICROSECOND / (AUDIO_SAMPLE_RATE_48K * 4 * STEREO_CHANNEL_COUNT);
282     uint64_t frames = 0;
283     int64_t timeSec = 0;
284     int64_t timeNanoSec = 0;
285     int32_t ret = GetPresentationPosition(frames, timeSec, timeNanoSec);
286     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "get frames fail");
287     latency = hdiLatency > frames ? (hdiLatency - frames) / MICROSECOND_PER_MILLISECOND : 0;
288     return SUCCESS;
289 }
290 
GetTransactionId(uint64_t & transactionId)291 int32_t OffloadAudioRenderSink::GetTransactionId(uint64_t &transactionId)
292 {
293     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
294     transactionId = reinterpret_cast<uint64_t>(audioRender_);
295     return SUCCESS;
296 }
297 
GetPresentationPosition(uint64_t & frames,int64_t & timeSec,int64_t & timeNanoSec)298 int32_t OffloadAudioRenderSink::GetPresentationPosition(uint64_t &frames, int64_t &timeSec, int64_t &timeNanoSec)
299 {
300     Trace trace("OffloadAudioRenderSink::GetPresentationPosition");
301     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
302     CHECK_AND_RETURN_RET_LOG(!isFlushing_, ERR_OPERATION_FAILED, "during flushing");
303 
304     uint64_t tmpFrames;
305     struct AudioTimeStamp stamp = {};
306     int32_t ret = audioRender_->GetRenderPosition(audioRender_, &tmpFrames, &stamp);
307     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "get render position fail, ret: %{public}d", ret);
308     int64_t maxSec = 9223372036; // (9223372036 + 1) * 10^9 > INT64_MAX, seconds should not bigger than it
309     CHECK_AND_RETURN_RET_LOG(stamp.tvSec >= 0 && stamp.tvSec <= maxSec && stamp.tvNSec >= 0 &&
310         stamp.tvNSec <= SECOND_TO_NANOSECOND, ERR_OPERATION_FAILED,
311         "get invalid time, second: %{public}" PRId64 ", nanosecond: %{public}" PRId64, stamp.tvSec, stamp.tvNSec);
312     frames = tmpFrames * SECOND_TO_MICROSECOND / attr_.sampleRate;
313     timeSec = stamp.tvSec;
314     timeNanoSec = stamp.tvNSec;
315 
316     // check hdi timestamp out of range 40 * 1000 * 1000 ns
317     struct timespec curStamp;
318     if (clock_gettime(CLOCK_MONOTONIC, &curStamp) >= 0) {
319         int64_t curNs = curStamp.tv_sec * AUDIO_NS_PER_SECOND + curStamp.tv_nsec;
320         int64_t hdiNs = stamp.tvSec * AUDIO_NS_PER_SECOND + stamp.tvNSec;
321         int64_t outNs = 40 * 1000 * 1000; // 40 * 1000 * 1000 ns
322         if (curNs <= hdiNs || curNs > hdiNs + outNs) {
323             AUDIO_PRERELEASE_LOGW("HDI time is not in the range, hdi: %{public}" PRId64 ", cur: %{public}" PRId64,
324                 hdiNs, curNs);
325             timeSec = curStamp.tv_sec;
326             timeNanoSec = curStamp.tv_nsec;
327         }
328     }
329     return ret;
330 }
331 
GetMaxAmplitude(void)332 float OffloadAudioRenderSink::GetMaxAmplitude(void)
333 {
334     lastGetMaxAmplitudeTime_ = ClockTime::GetCurNano();
335     startUpdate_ = true;
336     return maxAmplitude_;
337 }
338 
SetAudioMonoState(bool audioMono)339 void OffloadAudioRenderSink::SetAudioMonoState(bool audioMono)
340 {
341     audioMonoState_ = audioMono;
342 }
343 
SetAudioBalanceValue(float audioBalance)344 void OffloadAudioRenderSink::SetAudioBalanceValue(float audioBalance)
345 {
346     // reset the balance coefficient value firstly
347     leftBalanceCoef_ = 1.0f;
348     rightBalanceCoef_ = 1.0f;
349 
350     if (std::abs(audioBalance - 0.0f) <= std::numeric_limits<float>::epsilon()) {
351         // audioBalance is equal to 0.0f
352         audioBalanceState_ = false;
353     } else {
354         // audioBalance is not equal to 0.0f
355         audioBalanceState_ = true;
356         // calculate the balance coefficient
357         if (audioBalance > 0.0f) {
358             leftBalanceCoef_ -= audioBalance;
359         } else if (audioBalance < 0.0f) {
360             rightBalanceCoef_ += audioBalance;
361         }
362     }
363 }
364 
SetSinkMuteForSwitchDevice(bool mute)365 int32_t OffloadAudioRenderSink::SetSinkMuteForSwitchDevice(bool mute)
366 {
367     std::lock_guard<std::mutex> lock(switchDeviceMutex_);
368     AUDIO_INFO_LOG("set offload mute %{public}d", mute);
369 
370     if (mute) {
371         muteCount_++;
372         if (switchDeviceMute_) {
373             AUDIO_INFO_LOG("offload already muted");
374             return SUCCESS;
375         }
376         int32_t ret = SetVolumeInner(0.0f, 0.0f);
377         CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "set offload mute fail");
378         switchDeviceMute_ = true;
379     } else {
380         muteCount_--;
381         if (muteCount_ > 0) {
382             AUDIO_WARNING_LOG("offload not all unmuted");
383             return SUCCESS;
384         }
385         switchDeviceMute_ = false;
386         muteCount_ = 0;
387         SetVolumeInner(leftVolume_, rightVolume_);
388     }
389 
390     return SUCCESS;
391 }
392 
SetAudioScene(AudioScene audioScene,bool scoExcludeFlag)393 int32_t OffloadAudioRenderSink::SetAudioScene(AudioScene audioScene, bool scoExcludeFlag)
394 {
395     AUDIO_INFO_LOG("not support");
396     return ERR_NOT_SUPPORTED;
397 }
398 
GetAudioScene(void)399 int32_t OffloadAudioRenderSink::GetAudioScene(void)
400 {
401     AUDIO_INFO_LOG("not support");
402     return ERR_NOT_SUPPORTED;
403 }
404 
UpdateActiveDevice(std::vector<DeviceType> & outputDevices)405 int32_t OffloadAudioRenderSink::UpdateActiveDevice(std::vector<DeviceType> &outputDevices)
406 {
407     AUDIO_INFO_LOG("not support");
408     return ERR_NOT_SUPPORTED;
409 }
410 
RegistCallback(uint32_t type,IAudioSinkCallback * callback)411 void OffloadAudioRenderSink::RegistCallback(uint32_t type, IAudioSinkCallback *callback)
412 {
413     std::lock_guard<std::mutex> lock(sinkMutex_);
414     callback_.RegistCallback(type, callback);
415     AUDIO_INFO_LOG("regist succ");
416 }
417 
ResetActiveDeviceForDisconnect(DeviceType device)418 void OffloadAudioRenderSink::ResetActiveDeviceForDisconnect(DeviceType device)
419 {
420     AUDIO_INFO_LOG("not support");
421 }
422 
SetPaPower(int32_t flag)423 int32_t OffloadAudioRenderSink::SetPaPower(int32_t flag)
424 {
425     AUDIO_INFO_LOG("not support");
426     return ERR_NOT_SUPPORTED;
427 }
428 
SetPriPaPower(void)429 int32_t OffloadAudioRenderSink::SetPriPaPower(void)
430 {
431     AUDIO_INFO_LOG("not support");
432     return ERR_NOT_SUPPORTED;
433 }
434 
UpdateAppsUid(const int32_t appsUid[MAX_MIX_CHANNELS],const size_t size)435 int32_t OffloadAudioRenderSink::UpdateAppsUid(const int32_t appsUid[MAX_MIX_CHANNELS], const size_t size)
436 {
437 #ifdef FEATURE_POWER_MANAGER
438     CHECK_AND_RETURN_RET_LOG(runningLock_, ERR_INVALID_HANDLE, "running lock is nullptr");
439     runningLock_->UpdateAppsUid(appsUid, appsUid + size);
440 #endif
441     return SUCCESS;
442 }
443 
UpdateAppsUid(const std::vector<int32_t> & appsUid)444 int32_t OffloadAudioRenderSink::UpdateAppsUid(const std::vector<int32_t> &appsUid)
445 {
446 #ifdef FEATURE_POWER_MANAGER
447     CHECK_AND_RETURN_RET_LOG(runningLock_, ERR_INVALID_HANDLE, "running lock is nullptr");
448     runningLock_->UpdateAppsUid(appsUid.cbegin(), appsUid.cend());
449 #endif
450     return SUCCESS;
451 }
452 
Drain(AudioDrainType type)453 int32_t OffloadAudioRenderSink::Drain(AudioDrainType type)
454 {
455     Trace trace("OffloadAudioRenderSink::Drain");
456     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
457     int32_t ret = audioRender_->DrainBuffer(audioRender_, (AudioDrainNotifyType*)&type);
458     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "drain fail");
459     return SUCCESS;
460 }
461 
RegistOffloadHdiCallback(std::function<void (const RenderCallbackType type)> callback)462 void OffloadAudioRenderSink::RegistOffloadHdiCallback(std::function<void(const RenderCallbackType type)> callback)
463 {
464     AUDIO_INFO_LOG("in");
465 
466     hdiCallback_ = {
467         .callback_.RenderCallback = &OffloadAudioRenderSink::OffloadRenderCallback,
468         .serviceCallback_ = callback,
469         .sink_ = this,
470     };
471     int32_t ret = audioRender_->RegCallback(audioRender_, &hdiCallback_.callback_, (int8_t)0);
472     if (ret != SUCCESS) {
473         AUDIO_WARNING_LOG("fail, error code: %{public}d", ret);
474     }
475 }
476 
SetBufferSize(uint32_t sizeMs)477 int32_t OffloadAudioRenderSink::SetBufferSize(uint32_t sizeMs)
478 {
479     Trace trace("OffloadAudioRenderSink::SetBufferSize");
480     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
481     CHECK_AND_RETURN_RET_LOG(!isFlushing_, ERR_OPERATION_FAILED, "during flushing");
482 
483     // 4: bytewidth
484     uint32_t size = (uint64_t) sizeMs * AUDIO_SAMPLE_RATE_48K * 4 * STEREO_CHANNEL_COUNT / SECOND_TO_MILLISECOND;
485     AUDIO_INFO_LOG("SetBufferSize, size:%{public}u, sizeMs:%{public}u", size, sizeMs);
486     int32_t ret = audioRender_->SetBufferSize(audioRender_, size);
487     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "set buffer size fail");
488     return SUCCESS;
489 }
490 
LockOffloadRunningLock(void)491 int32_t OffloadAudioRenderSink::LockOffloadRunningLock(void)
492 {
493 #ifdef FEATURE_POWER_MANAGER
494     if (runningLock_ == nullptr) {
495         WatchTimeout guard("create AudioRunningLock start");
496         runningLock_ = std::make_shared<AudioRunningLock>(std::string(RUNNING_LOCK_NAME));
497         guard.CheckCurrTimeout();
498     }
499     CHECK_AND_RETURN_RET_LOG(runningLock_ != nullptr, ERR_OPERATION_FAILED,
500         "running lock is null, playback can not work well");
501     CHECK_AND_RETURN_RET(!runningLocked_, SUCCESS);
502     AUDIO_INFO_LOG("in");
503     runningLock_->Lock(RUNNING_LOCK_TIMEOUTMS_LASTING);
504     runningLocked_ = true;
505 #endif
506     return SUCCESS;
507 }
508 
UnLockOffloadRunningLock(void)509 int32_t OffloadAudioRenderSink::UnLockOffloadRunningLock(void)
510 {
511 #ifdef FEATURE_POWER_MANAGER
512     CHECK_AND_RETURN_RET_LOG(runningLock_ != nullptr, ERR_OPERATION_FAILED,
513         "running lock is null, playback can not work well");
514     CHECK_AND_RETURN_RET(runningLocked_, SUCCESS);
515     AUDIO_INFO_LOG("in");
516     runningLock_->UnLock();
517     runningLocked_ = false;
518 #endif
519     return SUCCESS;
520 }
521 
DumpInfo(std::string & dumpString)522 void OffloadAudioRenderSink::DumpInfo(std::string &dumpString)
523 {
524     dumpString += "type: OffloadSink\tstarted: " + std::string(started_ ? "true" : "false") + "\n";
525 }
526 
SetDmDeviceType(uint16_t dmDeviceType,DeviceType deviceType)527 void OffloadAudioRenderSink::SetDmDeviceType(uint16_t dmDeviceType, DeviceType deviceType)
528 {
529     AUDIO_INFO_LOG("not support");
530 }
531 
PcmFormatToBit(AudioSampleFormat format)532 uint32_t OffloadAudioRenderSink::PcmFormatToBit(AudioSampleFormat format)
533 {
534     AudioFormat hdiFormat = ConvertToHdiFormat(format);
535     switch (hdiFormat) {
536         case AUDIO_FORMAT_TYPE_PCM_8_BIT:
537             return PCM_8_BIT;
538         case AUDIO_FORMAT_TYPE_PCM_16_BIT:
539             return PCM_16_BIT;
540         case AUDIO_FORMAT_TYPE_PCM_24_BIT:
541             return PCM_24_BIT;
542         case AUDIO_FORMAT_TYPE_PCM_32_BIT:
543             return PCM_32_BIT;
544         default:
545             AUDIO_DEBUG_LOG("unknown format type, set it to default");
546             return PCM_24_BIT;
547     }
548 }
549 
ConvertToHdiFormat(AudioSampleFormat format)550 AudioFormat OffloadAudioRenderSink::ConvertToHdiFormat(AudioSampleFormat format)
551 {
552     AudioFormat hdiFormat;
553     switch (format) {
554         case SAMPLE_U8:
555             hdiFormat = AUDIO_FORMAT_TYPE_PCM_8_BIT;
556             break;
557         case SAMPLE_S16LE:
558             hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT;
559             break;
560         case SAMPLE_S24LE:
561             hdiFormat = AUDIO_FORMAT_TYPE_PCM_24_BIT;
562             break;
563         case SAMPLE_S32LE:
564             hdiFormat = AUDIO_FORMAT_TYPE_PCM_32_BIT;
565             break;
566         case SAMPLE_F32LE:
567             hdiFormat = AUDIO_FORMAT_TYPE_PCM_FLOAT;
568             break;
569         default:
570             hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT;
571             break;
572     }
573     return hdiFormat;
574 }
575 
OffloadRenderCallback(struct IAudioCallback * self,enum AudioCallbackType type,int8_t * reserved,int8_t * cookie)576 int32_t OffloadAudioRenderSink::OffloadRenderCallback(struct IAudioCallback *self, enum AudioCallbackType type,
577     int8_t *reserved, int8_t *cookie)
578 {
579     (void)reserved;
580     (void)cookie;
581     auto *impl = reinterpret_cast<struct OffloadHdiCallback *>(self);
582     CHECK_AND_RETURN_RET_LOG(impl != nullptr, ERR_OPERATION_FAILED, "impl is nullptr");
583     auto *sink = reinterpret_cast<OffloadAudioRenderSink *>(impl->sink_);
584     CHECK_AND_RETURN_RET_LOG(sink != nullptr, ERR_OPERATION_FAILED, "sink is nullptr");
585     if (!sink->started_ || sink->isFlushing_) {
586         AUDIO_DEBUG_LOG("invalid call, started: %{public}d, isFlushing: %{public}d", sink->started_, sink->isFlushing_);
587         return SUCCESS;
588     }
589 
590     impl->serviceCallback_(static_cast<RenderCallbackType>(type));
591     return SUCCESS;
592 }
593 
SetOffloadRenderCallbackType(RenderCallbackType type)594 int32_t OffloadAudioRenderSink::SetOffloadRenderCallbackType(RenderCallbackType type)
595 {
596     AUDIO_INFO_LOG("SetOffloadRenderCallbackType type: %{public}d", type);
597     if (hdiCallback_.serviceCallback_ == nullptr) {
598         AUDIO_ERR_LOG("SetOffloadRenderCallbackType invalid, callback is nullptr");
599         return ERR_ILLEGAL_STATE;
600     }
601 
602     if (!started_ || isFlushing_) {
603         AUDIO_INFO_LOG("SetOffloadRenderCallbackType invalid, started_ %{public}d, isFlushing_  %{public}d",
604             started_, isFlushing_);
605         return ERR_ILLEGAL_STATE;
606     }
607 
608     hdiCallback_.serviceCallback_(type);
609     return SUCCESS;
610 }
611 
InitAudioSampleAttr(struct AudioSampleAttributes & param)612 void OffloadAudioRenderSink::InitAudioSampleAttr(struct AudioSampleAttributes &param)
613 {
614     param.channelCount = AUDIO_CHANNELCOUNT;
615     param.sampleRate = AUDIO_SAMPLE_RATE_48K;
616     param.interleaved = true;
617     param.streamId = static_cast<int32_t>(GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_OFFLOAD));
618     param.type = AUDIO_OFFLOAD;
619     param.period = DEEP_BUFFER_RENDER_PERIOD_SIZE;
620     param.isBigEndian = false;
621     param.isSignedData = true;
622     param.stopThreshold = INT_MAX;
623     param.silenceThreshold = 0;
624 
625     // offload attr
626     param.offloadInfo.sampleRate = AUDIO_SAMPLE_RATE_48K;
627     param.offloadInfo.channelCount = AUDIO_CHANNELCOUNT;
628     param.offloadInfo.bitRate = AUDIO_SAMPLE_RATE_48K * BIT_IN_BYTE;
629     param.offloadInfo.bitWidth = PCM_32_BIT;
630 
631     param.sampleRate = attr_.sampleRate;
632     param.channelCount = attr_.channel;
633     if (param.channelCount == MONO) {
634         param.channelLayout = CH_LAYOUT_MONO;
635     } else if (param.channelCount == STEREO) {
636         param.channelLayout = CH_LAYOUT_STEREO;
637     }
638     param.format = ConvertToHdiFormat(attr_.format);
639     param.frameSize = PcmFormatToBit(attr_.format) * param.channelCount / PCM_8_BIT;
640     if (param.frameSize != 0) {
641         param.startThreshold = DEEP_BUFFER_RENDER_PERIOD_SIZE / (param.frameSize);
642     }
643 
644     param.offloadInfo.format = ConvertToHdiFormat(attr_.format);
645 }
646 
InitDeviceDesc(struct AudioDeviceDescriptor & deviceDesc)647 void OffloadAudioRenderSink::InitDeviceDesc(struct AudioDeviceDescriptor &deviceDesc)
648 {
649     deviceDesc.pins = PIN_OUT_SPEAKER;
650     deviceDesc.desc = const_cast<char *>("");
651 }
652 
CreateRender(void)653 int32_t OffloadAudioRenderSink::CreateRender(void)
654 {
655     Trace trace("AudioRenderSink::CreateRender");
656 
657     struct AudioSampleAttributes param;
658     struct AudioDeviceDescriptor deviceDesc;
659     InitAudioSampleAttr(param);
660     InitDeviceDesc(deviceDesc);
661 
662     AUDIO_INFO_LOG("create render, rate: %{public}u, channel: %{public}u, format: %{public}u", param.sampleRate,
663         param.channelCount, param.format);
664     AudioXCollie audioXCollie("OffloadAudioRenderSink::CreateRender", TIMEOUT_SECONDS_10,
665          nullptr, nullptr, AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
666     HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
667     std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_LOCAL);
668     CHECK_AND_RETURN_RET(deviceManager != nullptr, ERR_INVALID_HANDLE);
669     void *render = deviceManager->CreateRender(attr_.adapterName, &param, &deviceDesc, hdiRenderId_);
670     audioRender_ = static_cast<struct IAudioRender *>(render);
671     CHECK_AND_RETURN_RET(audioRender_ != nullptr, ERR_NOT_STARTED);
672 
673     return SUCCESS;
674 }
675 
InitLatencyMeasurement(void)676 void OffloadAudioRenderSink::InitLatencyMeasurement(void)
677 {
678     if (!AudioLatencyMeasurement::CheckIfEnabled()) {
679         return;
680     }
681 
682     AUDIO_INFO_LOG("in");
683     signalDetectAgent_ = std::make_shared<SignalDetectAgent>();
684     CHECK_AND_RETURN_LOG(signalDetectAgent_ != nullptr, "signalDetectAgent is nullptr");
685     signalDetectAgent_->sampleFormat_ = attr_.format;
686     signalDetectAgent_->formatByteSize_ = GetFormatByteSize(attr_.format);
687     signalDetected_ = false;
688 }
689 
DeInitLatencyMeasurement(void)690 void OffloadAudioRenderSink::DeInitLatencyMeasurement(void)
691 {
692     signalDetectAgent_ = nullptr;
693 }
694 
CheckLatencySignal(uint8_t * data,size_t len)695 void OffloadAudioRenderSink::CheckLatencySignal(uint8_t *data, size_t len)
696 {
697     CHECK_AND_RETURN(signalDetectAgent_ != nullptr);
698     uint32_t byteSize = static_cast<uint32_t>(GetFormatByteSize(attr_.format));
699     size_t newlyCheckedTime = len / (attr_.sampleRate / MILLISECOND_PER_SECOND) /
700         (byteSize * sizeof(uint8_t) * attr_.channel);
701     signalDetectedTime_ += newlyCheckedTime;
702     if (signalDetectedTime_ >= MILLISECOND_PER_SECOND && signalDetectAgent_->signalDetected_ &&
703         !signalDetectAgent_->dspTimestampGot_) {
704         AudioParamKey key = NONE;
705         std::string condition = "debug_audio_latency_measurement";
706         HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
707         std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_LOCAL);
708         CHECK_AND_RETURN(deviceManager != nullptr);
709         std::string value = deviceManager->GetAudioParameter(attr_.adapterName, key, condition);
710 
711         LatencyMonitor::GetInstance().UpdateDspTime(value.c_str());
712         LatencyMonitor::GetInstance().UpdateSinkOrSourceTime(true, signalDetectAgent_->lastPeakBufferTime_);
713         LatencyMonitor::GetInstance().ShowTimestamp(true);
714         signalDetectAgent_->dspTimestampGot_ = true;
715         signalDetectAgent_->signalDetected_ = false;
716     }
717     signalDetected_ = signalDetectAgent_->CheckAudioData(data, len);
718     if (signalDetected_) {
719         AUDIO_INFO_LOG("signal detected");
720         signalDetectedTime_ = 0;
721     }
722 }
723 
AdjustStereoToMono(char * data,uint64_t len)724 void OffloadAudioRenderSink::AdjustStereoToMono(char *data, uint64_t len)
725 {
726     // only stereo is supported now (stereo channel count is 2)
727     CHECK_AND_RETURN_LOG(attr_.channel == STEREO_CHANNEL_COUNT, "unsupport, channel: %{public}d", attr_.channel);
728 
729     switch (attr_.format) {
730         case SAMPLE_U8:
731             AdjustStereoToMonoForPCM8Bit(reinterpret_cast<int8_t *>(data), len);
732             break;
733         case SAMPLE_S16LE:
734             AdjustStereoToMonoForPCM16Bit(reinterpret_cast<int16_t *>(data), len);
735             break;
736         case SAMPLE_S24LE:
737             AdjustStereoToMonoForPCM24Bit(reinterpret_cast<uint8_t *>(data), len);
738             break;
739         case SAMPLE_S32LE:
740             AdjustStereoToMonoForPCM32Bit(reinterpret_cast<int32_t *>(data), len);
741             break;
742         default:
743             // if the audio format is unsupported, the audio data will not be changed
744             AUDIO_ERR_LOG("unsupport, format: %{public}d", attr_.format);
745             break;
746     }
747 }
748 
AdjustAudioBalance(char * data,uint64_t len)749 void OffloadAudioRenderSink::AdjustAudioBalance(char *data, uint64_t len)
750 {
751     // only stereo is supported now (stereo channel count is 2)
752     CHECK_AND_RETURN_LOG(attr_.channel == STEREO_CHANNEL_COUNT, "unsupport, channel: %{public}d", attr_.channel);
753 
754     switch (attr_.format) {
755         case SAMPLE_U8:
756             // this function needs further tested for usability
757             AdjustAudioBalanceForPCM8Bit(reinterpret_cast<int8_t *>(data), len, leftBalanceCoef_, rightBalanceCoef_);
758             break;
759         case SAMPLE_S16LE:
760             AdjustAudioBalanceForPCM16Bit(reinterpret_cast<int16_t *>(data), len, leftBalanceCoef_, rightBalanceCoef_);
761             break;
762         case SAMPLE_S24LE:
763             // this function needs further tested for usability
764             AdjustAudioBalanceForPCM24Bit(reinterpret_cast<uint8_t *>(data), len, leftBalanceCoef_, rightBalanceCoef_);
765             break;
766         case SAMPLE_S32LE:
767             AdjustAudioBalanceForPCM32Bit(reinterpret_cast<int32_t *>(data), len, leftBalanceCoef_, rightBalanceCoef_);
768             break;
769         default:
770             // if the audio format is unsupported, the audio data will not be changed
771             AUDIO_ERR_LOG("unsupport, format: %{public}d", attr_.format);
772             break;
773     }
774 }
775 
CheckUpdateState(char * data,uint64_t len)776 void OffloadAudioRenderSink::CheckUpdateState(char *data, uint64_t len)
777 {
778     if (startUpdate_) {
779         if (renderFrameNum_ == 0) {
780             last10FrameStartTime_ = ClockTime::GetCurNano();
781         }
782         renderFrameNum_++;
783         maxAmplitude_ = UpdateMaxAmplitude(static_cast<ConvertHdiFormat>(attr_.format), data, len);
784         if (renderFrameNum_ == GET_MAX_AMPLITUDE_FRAMES_THRESHOLD) {
785             renderFrameNum_ = 0;
786             if (last10FrameStartTime_ > lastGetMaxAmplitudeTime_) {
787                 startUpdate_ = false;
788                 maxAmplitude_ = 0;
789             }
790         }
791     }
792 }
793 
SetVolumeInner(float left,float right)794 int32_t OffloadAudioRenderSink::SetVolumeInner(float left, float right)
795 {
796     AudioXCollie audioXCollie("OffloadAudioRenderSink::SetVolumeInner", TIMEOUT_SECONDS_10, nullptr, nullptr,
797         AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
798     AUDIO_INFO_LOG("set offload vol, left: %{public}f, right: %{public}f", left, right);
799 
800     CHECK_AND_RETURN_RET_LOG(!isFlushing_, ERR_OPERATION_FAILED, "during flushing");
801     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE,
802         "render is nullptr, because set volume on device which offload is not available");
803 
804     float volume;
805     if ((left == 0) && (right != 0)) {
806         volume = right;
807     } else if ((left != 0) && (right == 0)) {
808         volume = left;
809     } else {
810         volume = (left + right) / HALF_FACTOR;
811     }
812 
813     int32_t ret = audioRender_->SetVolume(audioRender_, volume);
814     if (ret != SUCCESS) {
815         AUDIO_WARNING_LOG("set volume fail");
816     }
817 
818     return ret;
819 }
820 
821 // must be called with sinkMutex_ held
UpdateSinkState(bool started)822 void OffloadAudioRenderSink::UpdateSinkState(bool started)
823 {
824     callback_.OnRenderSinkStateChange(GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_OFFLOAD), started);
825 }
826 
SetSpeed(float speed)827 void OffloadAudioRenderSink::SetSpeed(float speed)
828 {
829     CHECK_AND_RETURN_LOG(speed <= 3.0f && speed >= 0.5f, "speed is invalid"); // 3.0 upper, 0.5 lower
830     uint32_t hdiSpeed = static_cast<uint32_t>(speed * AUDIO_SPEED_BASE);
831     AUDIO_INFO_LOG("speed: %{public}f, hdi speed: %{public}u", speed, hdiSpeed);
832 
833     HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
834     std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_LOCAL);
835     CHECK_AND_RETURN_LOG(deviceManager != nullptr, "deviceManager is nullptr");
836     std::string parameters = "pcm_offload_play_speed=" + std::to_string(hdiSpeed) + ";";
837     deviceManager->SetAudioParameter(attr_.adapterName, NONE, "pcm_offload_play_speed", parameters);
838 }
839 } // namespace AudioStandard
840 } // namespace OHOS
841