• 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 "AudioRenderSink"
18 #endif
19 
20 #include "sink/audio_render_sink.h"
21 #include <thread>
22 #include <climits>
23 #include "parameters.h"
24 #include "audio_hdi_log.h"
25 #include "audio_errors.h"
26 #include "audio_dump_pcm.h"
27 #include "volume_tools.h"
28 #include "media_monitor_manager.h"
29 #include "audio_enhance_chain_manager.h"
30 #include "common/hdi_adapter_info.h"
31 #include "manager/hdi_adapter_manager.h"
32 #include "manager/hdi_monitor.h"
33 #include "adapter/i_device_manager.h"
34 
35 namespace OHOS {
36 namespace AudioStandard {
37 namespace {
38 const int64_t RENDER_FRAME_LIMIT = 50; // 50ms
39 const int64_t RENDER_FRAME_REPORT_LIMIT = 100000000; // 100ms
40 }
AudioRenderSink(const uint32_t renderId,const std::string & halName)41 AudioRenderSink::AudioRenderSink(const uint32_t renderId, const std::string &halName)
42     : renderId_(renderId), halName_(halName)
43 {
44     if (halName_ == HDI_ID_INFO_DIRECT || halName_ == HDI_ID_INFO_VOIP) {
45         sinkType_ = ADAPTER_TYPE_DIRECT;
46     }
47 }
48 
~AudioRenderSink()49 AudioRenderSink::~AudioRenderSink()
50 {
51     AUDIO_WARNING_LOG("in");
52     AUDIO_INFO_LOG("[%{public}s] volumeDataCount: %{public}" PRId64, logUtilsTag_.c_str(), volumeDataCount_);
53 #ifdef FEATURE_POWER_MANAGER
54     if (runningLock_ != nullptr) {
55         AUDIO_INFO_LOG("running lock unlock");
56         runningLock_->UnLock();
57     } else {
58         AUDIO_WARNING_LOG("running lock is null, playback can not work well");
59     }
60 #endif
61     AudioPerformanceMonitor::GetInstance().DeleteOvertimeMonitor(sinkType_);
62 }
63 
Init(const IAudioSinkAttr & attr)64 int32_t AudioRenderSink::Init(const IAudioSinkAttr &attr)
65 {
66     std::lock_guard<std::mutex> lock(sinkMutex_);
67     attr_ = attr;
68     adapterNameCase_ = attr_.adapterName;
69     AUDIO_INFO_LOG("adapterNameCase_: %{public}s", adapterNameCase_.c_str());
70     openSpeaker_ = attr_.openMicSpeaker;
71 
72     Trace trace("AudioRenderSink::Init " + adapterNameCase_);
73     int32_t ret = InitRender();
74     CHECK_AND_RETURN_RET(ret == SUCCESS, ret);
75 
76     HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
77     std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_LOCAL);
78     CHECK_AND_RETURN_RET(deviceManager != nullptr, ERR_INVALID_HANDLE);
79 
80     sinkInited_ = true;
81     return SUCCESS;
82 }
83 
DeInit(void)84 void AudioRenderSink::DeInit(void)
85 {
86     std::lock_guard<std::mutex> lock(sinkMutex_);
87     sinkInited_ = false;
88     started_ = false;
89 
90     AUDIO_INFO_LOG("destroy render, hdiRenderId: %{public}u", hdiRenderId_);
91     HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
92     std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_LOCAL);
93     CHECK_AND_RETURN(deviceManager != nullptr);
94     renderInited_ = false;
95     deviceManager->DestroyRender(adapterNameCase_, hdiRenderId_);
96     audioRender_ = nullptr;
97 }
98 
IsInited(void)99 bool AudioRenderSink::IsInited(void)
100 {
101     return sinkInited_;
102 }
103 
Start(void)104 int32_t AudioRenderSink::Start(void)
105 {
106     std::lock_guard<std::mutex> lock(sinkMutex_);
107     AUDIO_INFO_LOG("halName: %{public}s", halName_.c_str());
108     Trace trace("AudioRenderSink::Start");
109 #ifdef FEATURE_POWER_MANAGER
110     AudioXCollie audioXCollie("AudioRenderSink::CreateRunningLock", TIMEOUT_SECONDS_10,
111          nullptr, nullptr, AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
112     if (runningLock_ == nullptr) {
113         WatchTimeout guard("create AudioRunningLock start");
114         runningLock_ = std::make_shared<AudioRunningLock>(std::string(RUNNING_LOCK_NAME_BASE) + halName_);
115         guard.CheckCurrTimeout();
116     }
117     if (runningLock_ != nullptr) {
118         runningLock_->Lock(RUNNING_LOCK_TIMEOUTMS_LASTING);
119     } else {
120         AUDIO_ERR_LOG("running lock is null, playback can not work well");
121     }
122     audioXCollie.CancelXCollieTimer();
123 #endif
124     dumpFileName_ = halName_ + "_sink_" + GetTime() + "_" + std::to_string(attr_.sampleRate) + "_" +
125         std::to_string(attr_.channel) + "_" + std::to_string(attr_.format) + ".pcm";
126     DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpFileName_, &dumpFile_);
127     logUtilsTag_ = "AudioSink" + halName_;
128 
129     InitLatencyMeasurement();
130     if (started_) {
131         return SUCCESS;
132     }
133     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
134     int32_t ret = audioRender_->Start(audioRender_);
135     if (ret != SUCCESS) {
136         HdiMonitor::ReportHdiException(HdiType::LOCAL, ErrorCase::CALL_HDI_FAILED, ret,
137             "local start failed, halName_:" + halName_);
138     }
139     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "start fail");
140     UpdateSinkState(true);
141     AudioPerformanceMonitor::GetInstance().RecordTimeStamp(sinkType_, INIT_LASTWRITTEN_TIME);
142     started_ = true;
143     isDataLinkConnected_ = false;
144     return SUCCESS;
145 }
146 
Stop(void)147 int32_t AudioRenderSink::Stop(void)
148 {
149     std::lock_guard<std::mutex> lock(sinkMutex_);
150     AUDIO_INFO_LOG("halName: %{public}s", halName_.c_str());
151     Trace trace("AudioRenderSink::Stop");
152 #ifdef FEATURE_POWER_MANAGER
153     if (runningLock_ != nullptr) {
154         std::thread runningLockThread([this] {
155             runningLock_->UnLock();
156         });
157         runningLockThread.join();
158     }
159 #endif
160 
161     DeInitLatencyMeasurement();
162     if (!started_) {
163         return SUCCESS;
164     }
165     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
166     if (halName_ == "primary") {
167         const char keyValueList[] = "primary=stop";
168         if (audioRender_->SetExtraParams(audioRender_, keyValueList) == 0) {
169             AUDIO_INFO_LOG("set primary stream stop info to hal");
170         }
171     }
172     int32_t ret = audioRender_->Stop(audioRender_);
173     UpdateSinkState(false);
174     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "stop fail");
175     started_ = false;
176 
177     DumpFileUtil::CloseDumpFile(&dumpFile_);
178     return SUCCESS;
179 }
180 
Resume(void)181 int32_t AudioRenderSink::Resume(void)
182 {
183     std::lock_guard<std::mutex> lock(sinkMutex_);
184     AUDIO_INFO_LOG("halName: %{public}s", halName_.c_str());
185     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
186     CHECK_AND_RETURN_RET_LOG(started_, ERR_OPERATION_FAILED, "not start, invalid state");
187 
188     if (!paused_) {
189         return SUCCESS;
190     }
191     int32_t ret = audioRender_->Resume(audioRender_);
192     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "resume fail");
193     AudioPerformanceMonitor::GetInstance().RecordTimeStamp(sinkType_, INIT_LASTWRITTEN_TIME);
194     paused_ = false;
195     return SUCCESS;
196 }
197 
Pause(void)198 int32_t AudioRenderSink::Pause(void)
199 {
200     std::lock_guard<std::mutex> lock(sinkMutex_);
201     AUDIO_INFO_LOG("halName: %{public}s", halName_.c_str());
202     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
203     CHECK_AND_RETURN_RET_LOG(started_, ERR_OPERATION_FAILED, "not start, invalid state");
204 
205     if (paused_) {
206         return SUCCESS;
207     }
208     int32_t ret = audioRender_->Pause(audioRender_);
209     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "pause fail");
210     paused_ = true;
211     return SUCCESS;
212 }
213 
Flush(void)214 int32_t AudioRenderSink::Flush(void)
215 {
216     AUDIO_INFO_LOG("halName: %{public}s", halName_.c_str());
217     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
218     CHECK_AND_RETURN_RET_LOG(started_, ERR_OPERATION_FAILED, "not start, invalid state");
219 
220     int32_t ret = audioRender_->Flush(audioRender_);
221     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "flush fail");
222     return SUCCESS;
223 }
224 
Reset(void)225 int32_t AudioRenderSink::Reset(void)
226 {
227     AUDIO_INFO_LOG("halName: %{public}s", halName_.c_str());
228     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
229     CHECK_AND_RETURN_RET_LOG(started_, ERR_OPERATION_FAILED, "not start, invalid state");
230 
231     int32_t ret = audioRender_->Flush(audioRender_);
232     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "reset fail");
233     return SUCCESS;
234 }
235 
RenderFrame(char & data,uint64_t len,uint64_t & writeLen)236 int32_t AudioRenderSink::RenderFrame(char &data, uint64_t len, uint64_t &writeLen)
237 {
238     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
239     if (!started_) {
240         AUDIO_WARNING_LOG("not start, invalid state");
241     }
242     if (audioMonoState_) {
243         AdjustStereoToMono(&data, len);
244     }
245     if (audioBalanceState_) {
246         AdjustAudioBalance(&data, len);
247     }
248     CheckUpdateState(&data, len);
249     if (switchDeviceMute_ || deviceConnectedFlag_) {
250         Trace trace("AudioRenderSink::RenderFrame::renderEmpty");
251         if (memset_s(reinterpret_cast<void *>(&data), static_cast<size_t>(len), 0, static_cast<size_t>(len)) != EOK) {
252             AUDIO_WARNING_LOG("call memset_s fail");
253         }
254     }
255     CheckLatencySignal(reinterpret_cast<uint8_t *>(&data), len);
256 
257     BufferDesc buffer = { reinterpret_cast<uint8_t *>(&data), len, len };
258     AudioStreamInfo streamInfo(static_cast<AudioSamplingRate>(attr_.sampleRate), AudioEncodingType::ENCODING_PCM,
259         static_cast<AudioSampleFormat>(attr_.format), static_cast<AudioChannel>(attr_.channel));
260     VolumeTools::DfxOperation(buffer, streamInfo, logUtilsTag_, volumeDataCount_);
261     if (AudioDump::GetInstance().GetVersionType() == DumpFileUtil::BETA_VERSION) {
262         DumpFileUtil::WriteDumpFile(dumpFile_, static_cast<void *>(&data), len);
263         AudioCacheMgr::GetInstance().CacheData(dumpFileName_, static_cast<void *>(&data), len);
264     }
265     Trace trace("AudioRenderSink::RenderFrame");
266     int64_t stamp = ClockTime::GetCurNano();
267     int32_t ret = audioRender_->RenderFrame(audioRender_, reinterpret_cast<int8_t *>(&data), static_cast<uint32_t>(len),
268         &writeLen);
269     stamp = (ClockTime::GetCurNano() - stamp) / AUDIO_US_PER_SECOND;
270     AudioPerformanceMonitor::GetInstance().RecordTimeStamp(sinkType_, ClockTime::GetCurNano());
271     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_WRITE_FAILED, "fail, ret: %{public}x", ret);
272     if (stamp >= RENDER_FRAME_LIMIT) {
273         AUDIO_WARNING_LOG("len: [%{public}" PRIu64 "], cost: [%{public}" PRId64 "]ms", len, stamp);
274     }
275 #ifdef FEATURE_POWER_MANAGER
276     if (runningLock_) {
277         runningLock_->UpdateAppsUidToPowerMgr();
278     }
279 #endif
280     if (stamp > RENDER_FRAME_REPORT_LIMIT) {
281         HdiMonitor::ReportHdiException(HdiType::LOCAL, ErrorCase::CALL_HDI_TIMEOUT,
282             static_cast<int32_t>(stamp), "call RenderFrame too long, " + halName_);
283     }
284 
285     return SUCCESS;
286 }
287 
GetVolumeDataCount()288 int64_t AudioRenderSink::GetVolumeDataCount()
289 {
290     return volumeDataCount_;
291 }
292 
SuspendRenderSink(void)293 int32_t AudioRenderSink::SuspendRenderSink(void)
294 {
295     return SUCCESS;
296 }
297 
RestoreRenderSink(void)298 int32_t AudioRenderSink::RestoreRenderSink(void)
299 {
300     return SUCCESS;
301 }
302 
SetAudioParameter(const AudioParamKey key,const std::string & condition,const std::string & value)303 void AudioRenderSink::SetAudioParameter(const AudioParamKey key, const std::string &condition, const std::string &value)
304 {
305     AUDIO_INFO_LOG("key: %{public}d, condition: %{public}s, value: %{public}s", key, condition.c_str(), value.c_str());
306     CHECK_AND_RETURN_LOG(audioRender_ != nullptr, "render is nullptr");
307     int32_t ret = audioRender_->SetExtraParams(audioRender_, value.c_str());
308     if (ret != SUCCESS) {
309         AUDIO_WARNING_LOG("set parameter fail, error code: %{public}d", ret);
310     }
311 }
312 
GetAudioParameter(const AudioParamKey key,const std::string & condition)313 std::string AudioRenderSink::GetAudioParameter(const AudioParamKey key, const std::string &condition)
314 {
315     std::lock_guard<std::mutex> lock(sinkMutex_);
316     AUDIO_INFO_LOG("key: %{public}d, condition: %{public}s, halName: %{public}s", key, condition.c_str(),
317         halName_.c_str());
318     if (condition.starts_with("get_usb_info#C") && halName_ == HDI_ID_INFO_USB) {
319         // init adapter to get parameter before load sink module (need fix)
320         adapterNameCase_ = "usb";
321         HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
322         std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_LOCAL);
323         CHECK_AND_RETURN_RET_LOG(deviceManager != nullptr, "", "deviceManager is nullptr");
324         return deviceManager->GetAudioParameter(adapterNameCase_, key, condition);
325     }
326     if (key == AudioParamKey::GET_DP_DEVICE_INFO && halName_ == HDI_ID_INFO_DP) {
327         // init adapter and render to get parameter before load sink module (need fix)
328         return GetDPDeviceInfo(condition);
329     }
330     return "";
331 }
332 
SetVolume(float left,float right)333 int32_t AudioRenderSink::SetVolume(float left, float right)
334 {
335     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
336 
337     leftVolume_ = left;
338     rightVolume_ = right;
339     CHECK_AND_RETURN_RET_LOG(!(halName_ == "voip" && switchDeviceMute_ && (abs(left) > FLOAT_EPS ||
340         abs(right) > FLOAT_EPS)), ERR_ILLEGAL_STATE, "mute for switch device at voip scene, not support set volume");
341     float volume;
342     if ((abs(leftVolume_) < FLOAT_EPS) && (abs(rightVolume_) > FLOAT_EPS)) {
343         volume = rightVolume_;
344     } else if ((abs(leftVolume_) > FLOAT_EPS) && (abs(rightVolume_) < FLOAT_EPS)) {
345         volume = leftVolume_;
346     } else {
347         volume = (leftVolume_ + rightVolume_) / HALF_FACTOR;
348     }
349 
350     int32_t ret = audioRender_->SetVolume(audioRender_, volume);
351     if (ret != SUCCESS) {
352         AUDIO_WARNING_LOG("set volume fail");
353     }
354 
355     return ret;
356 }
357 
GetVolume(float & left,float & right)358 int32_t AudioRenderSink::GetVolume(float &left, float &right)
359 {
360     left = leftVolume_;
361     right = rightVolume_;
362     return SUCCESS;
363 }
364 
GetLatency(uint32_t & latency)365 int32_t AudioRenderSink::GetLatency(uint32_t &latency)
366 {
367     Trace trace("AudioRenderSink::GetLatency");
368     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
369 
370     uint32_t hdiLatency;
371     int32_t ret = audioRender_->GetLatency(audioRender_, &hdiLatency);
372     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "get latency fail");
373     latency = hdiLatency;
374     return SUCCESS;
375 }
376 
GetTransactionId(uint64_t & transactionId)377 int32_t AudioRenderSink::GetTransactionId(uint64_t &transactionId)
378 {
379     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
380     transactionId = reinterpret_cast<uint64_t>(audioRender_);
381     return SUCCESS;
382 }
383 
GetPresentationPosition(uint64_t & frames,int64_t & timeSec,int64_t & timeNanoSec)384 int32_t AudioRenderSink::GetPresentationPosition(uint64_t &frames, int64_t &timeSec, int64_t &timeNanoSec)
385 {
386     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
387 
388     struct AudioTimeStamp stamp = {};
389     int32_t ret = audioRender_->GetRenderPosition(audioRender_, &frames, &stamp);
390     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "get render position fail, ret: %{public}d", ret);
391     int64_t maxSec = 9223372036; // (9223372036 + 1) * 10^9 > INT64_MAX, seconds should not bigger than it
392     CHECK_AND_RETURN_RET_LOG(stamp.tvSec >= 0 && stamp.tvSec <= maxSec && stamp.tvNSec >= 0 &&
393         stamp.tvNSec <= SECOND_TO_NANOSECOND, ERR_OPERATION_FAILED,
394         "get invalid time, second: %{public}" PRId64 ", nanosecond: %{public}" PRId64, stamp.tvSec, stamp.tvNSec);
395     timeSec = stamp.tvSec;
396     timeNanoSec = stamp.tvNSec;
397     return ret;
398 }
399 
GetMaxAmplitude(void)400 float AudioRenderSink::GetMaxAmplitude(void)
401 {
402     lastGetMaxAmplitudeTime_ = ClockTime::GetCurNano();
403     startUpdate_ = true;
404     return maxAmplitude_;
405 }
406 
SetAudioMonoState(bool audioMono)407 void AudioRenderSink::SetAudioMonoState(bool audioMono)
408 {
409     audioMonoState_ = audioMono;
410 }
411 
SetAudioBalanceValue(float audioBalance)412 void AudioRenderSink::SetAudioBalanceValue(float audioBalance)
413 {
414     // reset the balance coefficient value firstly
415     leftBalanceCoef_ = 1.0f;
416     rightBalanceCoef_ = 1.0f;
417 
418     if (std::abs(audioBalance - 0.0f) <= std::numeric_limits<float>::epsilon()) {
419         // audioBalance is equal to 0.0f
420         audioBalanceState_ = false;
421     } else {
422         // audioBalance is not equal to 0.0f
423         audioBalanceState_ = true;
424         // calculate the balance coefficient
425         if (audioBalance > 0.0f) {
426             leftBalanceCoef_ -= audioBalance;
427         } else if (audioBalance < 0.0f) {
428             rightBalanceCoef_ += audioBalance;
429         }
430     }
431 }
432 
SetSinkMuteForSwitchDevice(bool mute)433 int32_t AudioRenderSink::SetSinkMuteForSwitchDevice(bool mute)
434 {
435     std::lock_guard<std::mutex> lock(switchDeviceMutex_);
436     AUDIO_INFO_LOG("set %{public}s mute %{public}d", halName_.c_str(), mute);
437     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
438 
439     if (mute) {
440         muteCount_++;
441         if (switchDeviceMute_) {
442             AUDIO_INFO_LOG("%{public}s already muted", halName_.c_str());
443             return SUCCESS;
444         }
445         switchDeviceMute_ = true;
446         if (halName_ == HDI_ID_INFO_VOIP) {
447             audioRender_->SetVolume(audioRender_, 0.0f);
448         }
449     } else {
450         muteCount_--;
451         if (muteCount_ > 0) {
452             AUDIO_WARNING_LOG("%{public}s not all unmuted", halName_.c_str());
453             return SUCCESS;
454         }
455         switchDeviceMute_ = false;
456         muteCount_ = 0;
457         if (halName_ == HDI_ID_INFO_VOIP) {
458             SetVolume(leftVolume_, rightVolume_);
459         }
460     }
461 
462     return SUCCESS;
463 }
464 
SetDeviceConnectedFlag(bool flag)465 int32_t AudioRenderSink::SetDeviceConnectedFlag(bool flag)
466 {
467     AUDIO_INFO_LOG("flag %{public}d", flag);
468     deviceConnectedFlag_ = flag;
469     return SUCCESS;
470 }
471 
SetAudioScene(AudioScene audioScene,bool scoExcludeFlag)472 int32_t AudioRenderSink::SetAudioScene(AudioScene audioScene, bool scoExcludeFlag)
473 {
474     CHECK_AND_RETURN_RET_LOG(audioScene >= AUDIO_SCENE_DEFAULT && audioScene < AUDIO_SCENE_MAX, ERR_INVALID_PARAM,
475         "invalid scene");
476     if (!openSpeaker_) {
477         return SUCCESS;
478     }
479 
480     if (audioScene != currentAudioScene_ && !scoExcludeFlag) {
481         struct AudioSceneDescriptor sceneDesc;
482         InitSceneDesc(sceneDesc, audioScene);
483 
484         CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
485         int32_t ret = audioRender_->SelectScene(audioRender_, &sceneDesc);
486         CHECK_AND_RETURN_RET_LOG(ret >= 0, ERR_OPERATION_FAILED, "select scene fail, ret: %{public}d", ret);
487     }
488     bool isRingingToDefaultScene = false;
489     if (audioScene != currentAudioScene_) {
490         if (audioScene == AUDIO_SCENE_PHONE_CALL || audioScene == AUDIO_SCENE_PHONE_CHAT) {
491             forceSetRouteFlag_ = true;
492         }
493         if (audioScene == AUDIO_SCENE_DEFAULT &&
494             (currentAudioScene_ == AUDIO_SCENE_RINGING || currentAudioScene_ == AUDIO_SCENE_VOICE_RINGING)) {
495             isRingingToDefaultScene = true;
496         }
497         currentAudioScene_ = audioScene;
498     }
499 
500     HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
501     std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_LOCAL);
502     CHECK_AND_RETURN_RET(deviceManager != nullptr, ERR_INVALID_HANDLE);
503     deviceManager->SetAudioScene(currentAudioScene_);
504 
505     if (isRingingToDefaultScene) {
506         AUDIO_INFO_LOG("ringing scene to default scene");
507         return SUCCESS;
508     }
509     return SUCCESS;
510 }
511 
GetAudioScene(void)512 int32_t AudioRenderSink::GetAudioScene(void)
513 {
514     return currentAudioScene_;
515 }
516 
UpdateActiveDevice(std::vector<DeviceType> & outputDevices)517 int32_t AudioRenderSink::UpdateActiveDevice(std::vector<DeviceType> &outputDevices)
518 {
519     CHECK_AND_RETURN_RET_LOG(!outputDevices.empty() && outputDevices.size() <= AUDIO_CONCURRENT_ACTIVE_DEVICES_LIMIT,
520         ERR_INVALID_PARAM, "invalid device");
521     AUDIO_INFO_LOG("device: %{public}d, currentActiveDevice: %{public}d", outputDevices[0], currentActiveDevice_);
522     if (currentActiveDevice_ == outputDevices[0] && outputDevices.size() ==
523         static_cast<uint32_t>(currentDevicesSize_) && !forceSetRouteFlag_) {
524         AUDIO_INFO_LOG("output device not change, device: %{public}d", outputDevices[0]);
525         return SUCCESS;
526     }
527     forceSetRouteFlag_ = false;
528     currentActiveDevice_ = outputDevices[0];
529     currentDevicesSize_ = static_cast<int32_t>(outputDevices.size());
530     SetAudioRouteInfoForEnhanceChain();
531     return DoSetOutputRoute(outputDevices);
532 }
533 
RegistCallback(uint32_t type,IAudioSinkCallback * callback)534 void AudioRenderSink::RegistCallback(uint32_t type, IAudioSinkCallback *callback)
535 {
536     std::lock_guard<std::mutex> lock(sinkMutex_);
537     callback_.RegistCallback(type, callback);
538     AUDIO_INFO_LOG("regist succ");
539 }
540 
ResetActiveDeviceForDisconnect(DeviceType device)541 void AudioRenderSink::ResetActiveDeviceForDisconnect(DeviceType device)
542 {
543     if (currentActiveDevice_ == device) {
544         currentActiveDevice_ = DEVICE_TYPE_NONE;
545     }
546 }
547 
SetPaPower(int32_t flag)548 int32_t AudioRenderSink::SetPaPower(int32_t flag)
549 {
550     Trace trace("AudioRenderSink::SetPaPower flag: " + std::to_string(flag));
551     std::string param;
552 
553     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
554     AUDIO_INFO_LOG("flag: %{public}d, paStatus: %{public}d", flag, paStatus_);
555     if (flag == 0 && paStatus_ == 1) {
556         param = "zero_volume=true;routing=0";
557         AUDIO_INFO_LOG("param: %{public}s", param.c_str());
558         int32_t ret = audioRender_->SetExtraParams(audioRender_, param.c_str());
559         if (ret == SUCCESS) {
560             paStatus_ = 0;
561             WriteSmartPAStatusSysEvent(paStatus_);
562         }
563         return ret;
564     } else if (flag == 1 && paStatus_ == 0) {
565         param = "zero_volume=true;routing=" + GetRouting();
566         AUDIO_INFO_LOG("param: %{public}s", param.c_str());
567         int32_t ret = audioRender_->SetExtraParams(audioRender_, param.c_str());
568         param = "zero_volume=false";
569         ret += audioRender_->SetExtraParams(audioRender_, param.c_str());
570         if (ret == SUCCESS) {
571             paStatus_ = 1;
572             WriteSmartPAStatusSysEvent(paStatus_);
573         }
574         return ret;
575     } else if ((flag == 0 && paStatus_ == 0) || (flag == 1 && paStatus_ == 1)) {
576         return SUCCESS;
577     }
578 
579     AUDIO_WARNING_LOG("invalid flag");
580     return ERR_INVALID_PARAM;
581 }
582 
SetPriPaPower(void)583 int32_t AudioRenderSink::SetPriPaPower(void)
584 {
585     time_t currentTime = time(nullptr);
586     double diff = difftime(currentTime, startTime_);
587     if (diff > INTERVAL) {
588         CHECK_AND_RETURN_RET(audioRender_ != nullptr, ERR_INVALID_HANDLE);
589         int32_t ret = audioRender_->SetExtraParams(audioRender_, "primary=start");
590         if (ret == SUCCESS) {
591             AUDIO_INFO_LOG("set primary stream start info to hal");
592         }
593         time(&startTime_);
594         return ret;
595     }
596     return ERR_OPERATION_FAILED;
597 }
598 
UpdateAppsUid(const int32_t appsUid[MAX_MIX_CHANNELS],const size_t size)599 int32_t AudioRenderSink::UpdateAppsUid(const int32_t appsUid[MAX_MIX_CHANNELS], const size_t size)
600 {
601 #ifdef FEATURE_POWER_MANAGER
602     CHECK_AND_RETURN_RET_LOG(runningLock_, ERR_INVALID_HANDLE, "running lock is nullptr");
603     runningLock_->UpdateAppsUid(appsUid, appsUid + size);
604 #endif
605     return SUCCESS;
606 }
607 
UpdateAppsUid(const std::vector<int32_t> & appsUid)608 int32_t AudioRenderSink::UpdateAppsUid(const std::vector<int32_t> &appsUid)
609 {
610 #ifdef FEATURE_POWER_MANAGER
611     CHECK_AND_RETURN_RET_LOG(runningLock_, ERR_INVALID_HANDLE, "running lock is nullptr");
612     runningLock_->UpdateAppsUid(appsUid.cbegin(), appsUid.cend());
613     runningLock_->UpdateAppsUidToPowerMgr();
614 #endif
615     return SUCCESS;
616 }
617 
SetAddress(const std::string & address)618 void AudioRenderSink::SetAddress(const std::string &address)
619 {
620     address_ = address;
621 }
622 
DumpInfo(std::string & dumpString)623 void AudioRenderSink::DumpInfo(std::string &dumpString)
624 {
625     dumpString += "type: PrimarySink\tstarted: " + std::string(started_ ? "true" : "false") + "\thalName: " + halName_ +
626         "\tcurrentActiveDevice: " + std::to_string(currentActiveDevice_) + "\n";
627 }
628 
PcmFormatToBit(AudioSampleFormat format)629 uint32_t AudioRenderSink::PcmFormatToBit(AudioSampleFormat format)
630 {
631     AudioFormat hdiFormat = ConvertToHdiFormat(format);
632     switch (hdiFormat) {
633         case AUDIO_FORMAT_TYPE_PCM_8_BIT:
634             return PCM_8_BIT;
635         case AUDIO_FORMAT_TYPE_PCM_16_BIT:
636             return PCM_16_BIT;
637         case AUDIO_FORMAT_TYPE_PCM_24_BIT:
638             return PCM_24_BIT;
639         case AUDIO_FORMAT_TYPE_PCM_32_BIT:
640             return PCM_32_BIT;
641         default:
642             AUDIO_DEBUG_LOG("unknown format type, set it to default");
643             return PCM_24_BIT;
644     }
645 }
646 
ConvertToHdiFormat(AudioSampleFormat format)647 AudioFormat AudioRenderSink::ConvertToHdiFormat(AudioSampleFormat format)
648 {
649     AudioFormat hdiFormat;
650     switch (format) {
651         case SAMPLE_U8:
652             hdiFormat = AUDIO_FORMAT_TYPE_PCM_8_BIT;
653             break;
654         case SAMPLE_S16LE:
655             hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT;
656             break;
657         case SAMPLE_S24LE:
658             hdiFormat = AUDIO_FORMAT_TYPE_PCM_24_BIT;
659             break;
660         case SAMPLE_S32LE:
661             hdiFormat = AUDIO_FORMAT_TYPE_PCM_32_BIT;
662             break;
663         default:
664             hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT;
665             break;
666     }
667     return hdiFormat;
668 }
669 
ConvertByteToAudioFormat(int32_t format)670 int32_t AudioRenderSink::ConvertByteToAudioFormat(int32_t format)
671 {
672     int32_t audioSampleFormat = 0;
673     switch (format) {
674         case FORMAT_1_BYTE:
675             audioSampleFormat = SAMPLE_U8;
676             break;
677         case FORMAT_2_BYTE:
678             audioSampleFormat = SAMPLE_S16LE;
679             break;
680         case FORMAT_3_BYTE:
681             audioSampleFormat = SAMPLE_S24LE;
682             break;
683         case FORMAT_4_BYTE:
684             audioSampleFormat = SAMPLE_S32LE;
685             break;
686         default:
687             audioSampleFormat = SAMPLE_S16LE;
688             break;
689     }
690     return audioSampleFormat;
691 }
692 
ParseAudioFormatToStr(int32_t format)693 std::string AudioRenderSink::ParseAudioFormatToStr(int32_t format)
694 {
695     switch (format) {
696         case FORMAT_1_BYTE:
697             return "u8";
698         case FORMAT_2_BYTE:
699             return "s16";
700         case FORMAT_3_BYTE:
701             return "s24";
702         case FORMAT_4_BYTE:
703             return "s32";
704         default:
705             return "s16";
706     }
707     return "";
708 }
709 
ParseAudioFormat(const std::string & format)710 AudioSampleFormat AudioRenderSink::ParseAudioFormat(const std::string &format)
711 {
712     if (format == "AUDIO_FORMAT_PCM_16_BIT") {
713         return SAMPLE_S16LE;
714     } else if (format == "AUDIO_FORMAT_PCM_24_BIT" || format == "AUDIO_FORMAT_PCM_24_BIT_PACKED") {
715         return SAMPLE_S24LE;
716     } else if (format == "AUDIO_FORMAT_PCM_32_BIT") {
717         return SAMPLE_S32LE;
718     } else {
719         return SAMPLE_S16LE;
720     }
721 }
722 
GetAudioCategory(AudioScene audioScene)723 AudioCategory AudioRenderSink::GetAudioCategory(AudioScene audioScene)
724 {
725     AudioCategory audioCategory;
726     switch (audioScene) {
727         case AUDIO_SCENE_DEFAULT:
728             audioCategory = AUDIO_IN_MEDIA;
729             break;
730         case AUDIO_SCENE_RINGING:
731         case AUDIO_SCENE_VOICE_RINGING:
732             audioCategory = AUDIO_IN_RINGTONE;
733             break;
734         case AUDIO_SCENE_PHONE_CALL:
735             audioCategory = AUDIO_IN_CALL;
736             break;
737         case AUDIO_SCENE_PHONE_CHAT:
738             audioCategory = AUDIO_IN_COMMUNICATION;
739             break;
740         default:
741             audioCategory = AUDIO_IN_MEDIA;
742             break;
743     }
744     AUDIO_DEBUG_LOG("audioCategory: %{public}d", audioCategory);
745 
746     return audioCategory;
747 }
748 
GetAudioPortPin(void) const749 AudioPortPin AudioRenderSink::GetAudioPortPin(void) const noexcept
750 {
751     switch (attr_.deviceType) {
752         case DEVICE_TYPE_EARPIECE:
753             return PIN_OUT_EARPIECE;
754         case DEVICE_TYPE_SPEAKER:
755             return PIN_OUT_SPEAKER;
756         case DEVICE_TYPE_WIRED_HEADSET:
757             return PIN_OUT_HEADSET;
758         case DEVICE_TYPE_WIRED_HEADPHONES:
759             return PIN_OUT_HEADPHONE;
760         case DEVICE_TYPE_BLUETOOTH_SCO:
761             return PIN_OUT_BLUETOOTH_SCO;
762         case DEVICE_TYPE_USB_HEADSET:
763             return PIN_OUT_USB_EXT;
764         case DEVICE_TYPE_HDMI:
765              return PIN_OUT_HDMI;
766         case DEVICE_TYPE_NONE:
767             return PIN_NONE;
768         default:
769             return PIN_OUT_SPEAKER;
770     }
771 }
772 
GetUniqueId(void) const773 uint32_t AudioRenderSink::GetUniqueId(void) const
774 {
775     if (halName_ == HDI_ID_INFO_USB) {
776         return GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_USB);
777     } else if (halName_ == HDI_ID_INFO_DP) {
778         return GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_DP);
779     } else if (halName_ == HDI_ID_INFO_VOIP) {
780         return GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_VOIP);
781     } else if (halName_ == HDI_ID_INFO_DIRECT) {
782         return GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_DIRECT);
783     }
784     return GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_PRIMARY);
785 }
786 
InitAudioSampleAttr(struct AudioSampleAttributes & param)787 void AudioRenderSink::InitAudioSampleAttr(struct AudioSampleAttributes &param)
788 {
789     param.channelCount = AUDIO_CHANNELCOUNT;
790     param.sampleRate = AUDIO_SAMPLE_RATE_48K;
791     param.interleaved = true;
792     param.streamId = static_cast<int32_t>(GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_PRIMARY));
793     param.type = AUDIO_IN_MEDIA;
794     param.period = DEEP_BUFFER_RENDER_PERIOD_SIZE;
795     param.isBigEndian = false;
796     param.isSignedData = true;
797     param.stopThreshold = INT_MAX;
798     param.silenceThreshold = 0;
799 
800     param.sampleRate = attr_.sampleRate;
801     param.channelCount = attr_.channel;
802     if (param.channelCount == MONO) {
803         param.channelLayout = CH_LAYOUT_MONO;
804     } else if (param.channelCount == STEREO) {
805         param.channelLayout = CH_LAYOUT_STEREO;
806     }
807     if (halName_ == HDI_ID_INFO_DP) {
808         param.type = AUDIO_DP;
809     } else if (halName_ == HDI_ID_INFO_DIRECT) {
810         param.type = AUDIO_DIRECT;
811         param.streamId = static_cast<int32_t>(GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_DIRECT));
812     } else if (halName_ == HDI_ID_INFO_VOIP) {
813         param.type = AUDIO_IN_COMMUNICATION;
814         param.streamId = static_cast<int32_t>(GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_VOIP));
815     }
816     param.format = ConvertToHdiFormat(attr_.format);
817     param.frameSize = PcmFormatToBit(attr_.format) * param.channelCount / PCM_8_BIT;
818     if (param.frameSize != 0) {
819         param.startThreshold = DEEP_BUFFER_RENDER_PERIOD_SIZE / (param.frameSize);
820     }
821 }
822 
InitDeviceDesc(struct AudioDeviceDescriptor & deviceDesc)823 void AudioRenderSink::InitDeviceDesc(struct AudioDeviceDescriptor &deviceDesc)
824 {
825     if (halName_ == HDI_ID_INFO_USB) {
826         deviceDesc.desc = const_cast<char *>(address_.c_str());
827     } else {
828         deviceDesc.desc = const_cast<char *>(attr_.address.c_str());
829     }
830     deviceDesc.pins = GetAudioPortPin();
831     if (halName_ == HDI_ID_INFO_USB) {
832         deviceDesc.pins = PIN_OUT_USB_HEADSET;
833     } else if (halName_ == HDI_ID_INFO_DP) {
834         deviceDesc.pins = PIN_OUT_DP;
835     }
836 }
837 
InitSceneDesc(struct AudioSceneDescriptor & sceneDesc,AudioScene audioScene)838 void AudioRenderSink::InitSceneDesc(struct AudioSceneDescriptor &sceneDesc, AudioScene audioScene)
839 {
840     sceneDesc.scene.id = GetAudioCategory(audioScene);
841     if (halName_ == HDI_ID_INFO_DIRECT) {
842         sceneDesc.scene.id = AUDIO_DIRECT;
843     } else if (halName_ == HDI_ID_INFO_VOIP) {
844         sceneDesc.scene.id = AUDIO_IN_COMMUNICATION;
845     }
846 
847     AudioPortPin port = GetAudioPortPin();
848     if (halName_ == HDI_ID_INFO_USB) {
849         port = PIN_OUT_USB_HEADSET;
850     } else if (halName_ == HDI_ID_INFO_DP) {
851         port = PIN_OUT_DP;
852     }
853     AUDIO_DEBUG_LOG("port: %{public}d", port);
854     sceneDesc.desc.pins = port;
855     sceneDesc.desc.desc = const_cast<char *>("");
856 }
857 
858 // LCOV_EXCL_START
SetAudioRouteInfoForEnhanceChain(void)859 void AudioRenderSink::SetAudioRouteInfoForEnhanceChain(void)
860 {
861     int32_t engineFlag = GetEngineFlag();
862     if (engineFlag != 1) {
863         AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance();
864         CHECK_AND_RETURN_LOG(audioEnhanceChainManager != nullptr, "audioEnhanceChainManager is nullptr");
865         if (halName_ == HDI_ID_INFO_USB) {
866             audioEnhanceChainManager->SetOutputDevice(renderId_, DEVICE_TYPE_USB_ARM_HEADSET);
867         } else if (halName_ == HDI_ID_INFO_DP) {
868             audioEnhanceChainManager->SetOutputDevice(renderId_, DEVICE_TYPE_DP);
869         } else {
870             audioEnhanceChainManager->SetOutputDevice(renderId_, currentActiveDevice_);
871         }
872     }
873 }
874 // LCOV_EXCL_STOP
875 
CreateRender(void)876 int32_t AudioRenderSink::CreateRender(void)
877 {
878     Trace trace("AudioRenderSink::CreateRender");
879 
880     struct AudioSampleAttributes param;
881     struct AudioDeviceDescriptor deviceDesc;
882     InitAudioSampleAttr(param);
883     InitDeviceDesc(deviceDesc);
884 
885     AUDIO_INFO_LOG("create render, halName: %{public}s, rate: %{public}u, channel: %{public}u, format: %{public}u, "
886         "devicePin: %{public}u, desc: %{public}s", halName_.c_str(), param.sampleRate, param.channelCount, param.format,
887         deviceDesc.pins, deviceDesc.desc);
888     HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
889     std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_LOCAL);
890     CHECK_AND_RETURN_RET(deviceManager != nullptr, ERR_INVALID_HANDLE);
891     void *render = deviceManager->CreateRender(adapterNameCase_, &param, &deviceDesc, hdiRenderId_);
892     audioRender_ = static_cast<struct IAudioRender *>(render);
893     CHECK_AND_RETURN_RET(audioRender_ != nullptr, ERR_NOT_STARTED);
894     SetAudioRouteInfoForEnhanceChain();
895 
896     AUDIO_INFO_LOG("create render success, hdiRenderId_: %{public}u, desc: %{public}s", hdiRenderId_, deviceDesc.desc);
897     return SUCCESS;
898 }
899 
DoSetOutputRoute(std::vector<DeviceType> & outputDevices)900 int32_t AudioRenderSink::DoSetOutputRoute(std::vector<DeviceType> &outputDevices)
901 {
902     HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
903     std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_LOCAL);
904     CHECK_AND_RETURN_RET(deviceManager != nullptr, ERR_INVALID_HANDLE);
905     int32_t ret = deviceManager->SetOutputRoute(adapterNameCase_, outputDevices,
906         GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_PRIMARY));
907     return ret;
908 }
909 
InitRender(void)910 int32_t AudioRenderSink::InitRender(void)
911 {
912     AUDIO_INFO_LOG("start, halName: %{public}s", halName_.c_str());
913     Trace trace("AudioRenderSink::InitRender");
914     if (renderInited_) {
915         AUDIO_INFO_LOG("render already inited");
916         return SUCCESS;
917     }
918 
919     int32_t ret = CreateRender();
920     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "create render fail");
921     if (openSpeaker_) {
922         ret = SUCCESS;
923         std::vector<DeviceType> outputDevices;
924         if (halName_ == HDI_ID_INFO_USB) {
925             outputDevices.push_back(DEVICE_TYPE_USB_ARM_HEADSET);
926             ret = UpdateActiveDevice(outputDevices);
927         } else if (halName_ == HDI_ID_INFO_DP) {
928             outputDevices.push_back(DEVICE_TYPE_DP);
929             ret = UpdateActiveDevice(outputDevices);
930         } else if (halName_ == HDI_ID_INFO_VOIP) {
931             // voip hal do not need to SetOutputRoute when create render, will SetOutputRoute when start stream
932             AUDIO_INFO_LOG("voip hal do not need to SetOutputRoute when create render");
933         } else {
934             DeviceType type = static_cast<DeviceType>(attr_.deviceType);
935             if (type == DEVICE_TYPE_INVALID) {
936                 type = DEVICE_TYPE_SPEAKER;
937             }
938             outputDevices.push_back(type);
939             ret = UpdateActiveDevice(outputDevices);
940         }
941         if (ret != SUCCESS) {
942             AUDIO_WARNING_LOG("update route fail, ret: %{public}d", ret);
943         }
944     }
945     renderInited_ = true;
946     return SUCCESS;
947 }
948 
InitLatencyMeasurement(void)949 void AudioRenderSink::InitLatencyMeasurement(void)
950 {
951     if (!AudioLatencyMeasurement::CheckIfEnabled()) {
952         return;
953     }
954 
955     AUDIO_INFO_LOG("in");
956     signalDetectAgent_ = std::make_shared<SignalDetectAgent>();
957     CHECK_AND_RETURN_LOG(signalDetectAgent_ != nullptr, "signalDetectAgent is nullptr");
958     signalDetectAgent_->sampleFormat_ = attr_.format;
959     signalDetectAgent_->formatByteSize_ = GetFormatByteSize(attr_.format);
960     signalDetected_ = false;
961 }
962 
DeInitLatencyMeasurement(void)963 void AudioRenderSink::DeInitLatencyMeasurement(void)
964 {
965     signalDetectAgent_ = nullptr;
966 }
967 
CheckLatencySignal(uint8_t * data,size_t len)968 void AudioRenderSink::CheckLatencySignal(uint8_t *data, size_t len)
969 {
970     CHECK_AND_RETURN(signalDetectAgent_ != nullptr);
971     uint32_t byteSize = static_cast<uint32_t>(GetFormatByteSize(attr_.format));
972     size_t newlyCheckedTime = len / (attr_.sampleRate / MILLISECOND_PER_SECOND) /
973         (byteSize * sizeof(uint8_t) * attr_.channel);
974     signalDetectedTime_ += newlyCheckedTime;
975     if (signalDetectedTime_ >= MILLISECOND_PER_SECOND && signalDetectAgent_->signalDetected_ &&
976         !signalDetectAgent_->dspTimestampGot_) {
977         AudioParamKey key = NONE;
978         std::string condition = "debug_audio_latency_measurement";
979         HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
980         std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_LOCAL);
981         CHECK_AND_RETURN(deviceManager != nullptr);
982         std::string value = deviceManager->GetAudioParameter(adapterNameCase_, key, condition);
983 
984         LatencyMonitor::GetInstance().UpdateDspTime(value.c_str());
985         LatencyMonitor::GetInstance().UpdateSinkOrSourceTime(true, signalDetectAgent_->lastPeakBufferTime_);
986         LatencyMonitor::GetInstance().ShowTimestamp(true);
987         signalDetectAgent_->dspTimestampGot_ = true;
988         signalDetectAgent_->signalDetected_ = false;
989     }
990     signalDetected_ = signalDetectAgent_->CheckAudioData(data, len);
991     if (signalDetected_) {
992         AUDIO_INFO_LOG("signal detected");
993         signalDetectedTime_ = 0;
994     }
995 }
996 
AdjustStereoToMono(char * data,uint64_t len)997 void AudioRenderSink::AdjustStereoToMono(char *data, uint64_t len)
998 {
999     // only stereo is supported now (stereo channel count is 2)
1000     CHECK_AND_RETURN_LOG(attr_.channel == STEREO_CHANNEL_COUNT, "unsupport, channel: %{public}d", attr_.channel);
1001 
1002     switch (attr_.format) {
1003         case SAMPLE_U8:
1004             AdjustStereoToMonoForPCM8Bit(reinterpret_cast<int8_t *>(data), len);
1005             break;
1006         case SAMPLE_S16LE:
1007             AdjustStereoToMonoForPCM16Bit(reinterpret_cast<int16_t *>(data), len);
1008             break;
1009         case SAMPLE_S24LE:
1010             AdjustStereoToMonoForPCM24Bit(reinterpret_cast<uint8_t *>(data), len);
1011             break;
1012         case SAMPLE_S32LE:
1013             AdjustStereoToMonoForPCM32Bit(reinterpret_cast<int32_t *>(data), len);
1014             break;
1015         default:
1016             // if the audio format is unsupported, the audio data will not be changed
1017             AUDIO_ERR_LOG("unsupport, format: %{public}d", attr_.format);
1018             break;
1019     }
1020 }
1021 
AdjustAudioBalance(char * data,uint64_t len)1022 void AudioRenderSink::AdjustAudioBalance(char *data, uint64_t len)
1023 {
1024     // only stereo is supported now (stereo channel count is 2)
1025     CHECK_AND_RETURN_LOG(attr_.channel == STEREO_CHANNEL_COUNT, "unsupport, channel: %{public}d", attr_.channel);
1026 
1027     switch (attr_.format) {
1028         case SAMPLE_U8:
1029             // this function needs further tested for usability
1030             AdjustAudioBalanceForPCM8Bit(reinterpret_cast<int8_t *>(data), len, leftBalanceCoef_, rightBalanceCoef_);
1031             break;
1032         case SAMPLE_S16LE:
1033             AdjustAudioBalanceForPCM16Bit(reinterpret_cast<int16_t *>(data), len, leftBalanceCoef_, rightBalanceCoef_);
1034             break;
1035         case SAMPLE_S24LE:
1036             // this function needs further tested for usability
1037             AdjustAudioBalanceForPCM24Bit(reinterpret_cast<uint8_t *>(data), len, leftBalanceCoef_, rightBalanceCoef_);
1038             break;
1039         case SAMPLE_S32LE:
1040             AdjustAudioBalanceForPCM32Bit(reinterpret_cast<int32_t *>(data), len, leftBalanceCoef_, rightBalanceCoef_);
1041             break;
1042         default:
1043             // if the audio format is unsupported, the audio data will not be changed
1044             AUDIO_ERR_LOG("unsupport, format: %{public}d", attr_.format);
1045             break;
1046     }
1047 }
1048 
CheckUpdateState(char * data,uint64_t len)1049 void AudioRenderSink::CheckUpdateState(char *data, uint64_t len)
1050 {
1051     if (startUpdate_) {
1052         if (renderFrameNum_ == 0) {
1053             last10FrameStartTime_ = ClockTime::GetCurNano();
1054         }
1055         renderFrameNum_++;
1056         maxAmplitude_ = UpdateMaxAmplitude(static_cast<ConvertHdiFormat>(attr_.format), data, len);
1057         if (renderFrameNum_ == GET_MAX_AMPLITUDE_FRAMES_THRESHOLD) {
1058             renderFrameNum_ = 0;
1059             if (last10FrameStartTime_ > lastGetMaxAmplitudeTime_) {
1060                 startUpdate_ = false;
1061                 maxAmplitude_ = 0;
1062             }
1063         }
1064     }
1065 }
1066 
GetAttrInfoStr(const struct AudioSampleAttributes & attrInfo)1067 std::string AudioRenderSink::GetAttrInfoStr(const struct AudioSampleAttributes &attrInfo)
1068 {
1069     CHECK_AND_RETURN_RET_LOG(attrInfo.sampleRate > 0, "", "invalid rate: %{public}d", attrInfo.sampleRate);
1070     CHECK_AND_RETURN_RET_LOG(attrInfo.format > 0, "", "invalid format: %{public}d", attrInfo.format);
1071     CHECK_AND_RETURN_RET_LOG(attrInfo.channelCount > 0, "", "invalid channel: %{public}d", attrInfo.channelCount);
1072 
1073     uint32_t bufferSize = attrInfo.sampleRate * attrInfo.format * attrInfo.channelCount *
1074         BUFFER_CALC_20MS / BUFFER_CALC_1000MS;
1075     std::string attrInfoStr = "rate=" + std::to_string(attrInfo.sampleRate) + " format=" +
1076         ParseAudioFormatToStr(attrInfo.format) + " channels=" + std::to_string(attrInfo.channelCount) +
1077         " buffer_size=" + std::to_string(bufferSize);
1078     AUDIO_INFO_LOG("attrInfoStr: %{public}s", attrInfoStr.c_str());
1079     return attrInfoStr;
1080 }
1081 
UpdateDPAttr(const std::string & dpInfo)1082 int32_t AudioRenderSink::UpdateDPAttr(const std::string &dpInfo)
1083 {
1084     CHECK_AND_RETURN_RET_LOG(!dpInfo.empty(), ERR_INVALID_PARAM, "dp info is empty");
1085 
1086     auto sinkRate_begin = dpInfo.find("rate=");
1087     auto sinkRate_end = dpInfo.find_first_of(" ", sinkRate_begin);
1088     std::string sampleRateStr = dpInfo.substr(sinkRate_begin + std::strlen("rate="),
1089         sinkRate_end - sinkRate_begin - std::strlen("rate="));
1090 
1091     auto sinkBuffer_begin = dpInfo.find("buffer_size=");
1092     auto sinkBuffer_end = dpInfo.find_first_of(" ", sinkBuffer_begin);
1093     std::string bufferSizeStr = dpInfo.substr(sinkBuffer_begin + std::strlen("buffer_size="),
1094         sinkBuffer_end - sinkBuffer_begin - std::strlen("buffer_size="));
1095 
1096     auto sinkChannel_begin = dpInfo.find("channels=");
1097     auto sinkChannel_end = dpInfo.find_first_of(" ", sinkChannel_begin);
1098     std::string channelStr = dpInfo.substr(sinkChannel_begin + std::strlen("channels="),
1099         sinkChannel_end - sinkChannel_begin - std::strlen("channels="));
1100 
1101     auto address_begin = dpInfo.find("address=");
1102     auto address_end = dpInfo.find_first_of(" ", address_begin);
1103     std::string addressStr = dpInfo.substr(address_begin + std::strlen("address="),
1104         address_end - address_begin - std::strlen("address="));
1105 
1106     bool ret = StringConverter(sampleRateStr, attr_.sampleRate);
1107     CHECK_AND_RETURN_RET_LOG(ret, ERR_INVALID_PARAM, "convert fail, sampleRate: %{public}s", sampleRateStr.c_str());
1108     ret = StringConverter(channelStr, attr_.channel);
1109     CHECK_AND_RETURN_RET_LOG(ret, ERR_INVALID_PARAM, "convert fail, channel: %{public}s", channelStr.c_str());
1110 
1111     attr_.address = addressStr;
1112     uint32_t formatByte = 0;
1113     if (attr_.channel <= 0 || attr_.sampleRate <= 0 || bufferSizeStr.empty()) {
1114         AUDIO_ERR_LOG("check attr fail, channel: %{public}d, sampleRate: %{public}d", attr_.channel, attr_.sampleRate);
1115     } else {
1116         uint32_t bufferSize = 0;
1117         ret = StringConverter(bufferSizeStr, bufferSize);
1118         CHECK_AND_RETURN_RET_LOG(ret, ERR_INVALID_PARAM, "convert fail, bufferSize: %{public}s", bufferSizeStr.c_str());
1119         formatByte = bufferSize * BUFFER_CALC_1000MS / BUFFER_CALC_20MS / attr_.channel / attr_.sampleRate;
1120     }
1121 
1122     attr_.format = static_cast<AudioSampleFormat>(ConvertByteToAudioFormat(formatByte));
1123 
1124     AUDIO_DEBUG_LOG("sampleRate: %{public}d, format: %{public}d, channelCount: %{public}d, address: %{public}s",
1125         attr_.sampleRate, attr_.format, attr_.channel, addressStr.c_str());
1126 
1127     adapterNameCase_ = "dp";
1128     openSpeaker_ = 0;
1129     return SUCCESS;
1130 }
1131 
GetDPDeviceInfo(const std::string & condition)1132 std::string AudioRenderSink::GetDPDeviceInfo(const std::string &condition)
1133 {
1134     int32_t ret = UpdateDPAttr(condition);
1135     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, "", "init attr fail");
1136 
1137     ret = InitRender();
1138     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS && audioRender_ != nullptr, "", "init render fail");
1139 
1140     struct AudioSampleAttributes attrInfo = {};
1141     ret = audioRender_->GetSampleAttributes(audioRender_, &attrInfo);
1142     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, "", "get sample attr fail");
1143 
1144     AUDIO_DEBUG_LOG("sampleRate: %{public}d, format: %{public}d, channelCount: %{public}d, size: %{public}d",
1145         attrInfo.sampleRate, attrInfo.format, attrInfo.channelCount, attrInfo.frameSize);
1146     return GetAttrInfoStr(attrInfo);
1147 }
1148 
GetRouting(void) const1149 std::string AudioRenderSink::GetRouting(void) const
1150 {
1151     switch (currentActiveDevice_) {
1152         case DEVICE_TYPE_EARPIECE:
1153             return "1";
1154         case DEVICE_TYPE_SPEAKER:
1155             return "2";
1156         case DEVICE_TYPE_WIRED_HEADSET:
1157             return "4";
1158         case DEVICE_TYPE_USB_ARM_HEADSET:
1159             return "67108864";
1160         case DEVICE_TYPE_USB_HEADSET:
1161             return "545259520";
1162         case DEVICE_TYPE_BLUETOOTH_SCO:
1163             return "16";
1164         case DEVICE_TYPE_BLUETOOTH_A2DP:
1165             return "128";
1166         default:
1167             break;
1168     }
1169     return "0";
1170 }
1171 
WriteSmartPAStatusSysEvent(int32_t status)1172 void AudioRenderSink::WriteSmartPAStatusSysEvent(int32_t status)
1173 {
1174     std::shared_ptr<Media::MediaMonitor::EventBean> bean = std::make_shared<Media::MediaMonitor::EventBean>(
1175         Media::MediaMonitor::AUDIO, Media::MediaMonitor::SMARTPA_STATUS,
1176         Media::MediaMonitor::BEHAVIOR_EVENT);
1177     bean->Add("STATUS", status);
1178     Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
1179 }
1180 
1181 // must be called with sinkMutex_ held
UpdateSinkState(bool started)1182 void AudioRenderSink::UpdateSinkState(bool started)
1183 {
1184     callback_.OnRenderSinkStateChange(GetUniqueId(), started);
1185 }
1186 
UpdatePrimaryConnectionState(uint32_t operation)1187 int32_t AudioRenderSink::UpdatePrimaryConnectionState(uint32_t operation)
1188 {
1189     if (operation == DATA_LINK_CONNECTING) {
1190         AUDIO_INFO_LOG("Primary sink is connecting");
1191         isDataLinkConnected_ = false;
1192     }
1193     if (operation == DATA_LINK_CONNECTED) {
1194         AUDIO_INFO_LOG("Primary sink is connected");
1195         isDataLinkConnected_ = true;
1196         dataConnectionCV_.notify_all();
1197     }
1198     return SUCCESS;
1199 }
1200 
SetDmDeviceType(uint16_t dmDeviceType,DeviceType deviceType)1201 void AudioRenderSink::SetDmDeviceType(uint16_t dmDeviceType, DeviceType deviceType)
1202 {
1203     std::lock_guard<std::mutex> lock(sinkMutex_);
1204     const auto &it = dmDeviceTypeMap_.find(deviceType);
1205     bool isDmDeviceTypeUpdated = it == dmDeviceTypeMap_.end() || it->second != dmDeviceType;
1206     dmDeviceTypeMap_[deviceType] = dmDeviceType;
1207     HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
1208     std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_LOCAL);
1209     CHECK_AND_RETURN_LOG(deviceManager != nullptr, "deviceManager is nullptr");
1210     deviceManager->SetDmDeviceType(dmDeviceType, deviceType);
1211 
1212     CHECK_AND_RETURN(isDmDeviceTypeUpdated);
1213     std::vector<DeviceType> outputDevices;
1214     outputDevices.push_back(currentActiveDevice_);
1215     AUDIO_INFO_LOG("dm deviceType update, need update output port pin");
1216     int32_t ret = DoSetOutputRoute(outputDevices);
1217     CHECK_AND_RETURN_LOG(ret == SUCCESS, "DoSetOutputRoute fails");
1218 }
1219 
WaitForDataLinkConnected()1220 void AudioRenderSink::WaitForDataLinkConnected()
1221 {
1222     std::unique_lock<std::mutex> dataConnectionWaitLock(dataConnectionMutex_);
1223     if (!isDataLinkConnected_ && (halName_ == "primary") && (sinkType_ == ADAPTER_TYPE_PRIMARY)) {
1224         AUDIO_INFO_LOG("data-connection blocking starts");
1225         bool stopWaiting = dataConnectionCV_.wait_for(
1226             dataConnectionWaitLock, std::chrono::milliseconds(DATA_CONNECTION_TIMEOUT_IN_MS), [this] {
1227                 return isDataLinkConnected_;
1228             });
1229         if (stopWaiting) {
1230             AUDIO_INFO_LOG("data-connection blocking ends");
1231         } else {
1232             AUDIO_WARNING_LOG("data-connection time out, start RenderFrame anyway.");
1233         }
1234         isDataLinkConnected_ = true;
1235     }
1236     dataConnectionWaitLock.unlock();
1237 }
1238 
1239 } // namespace AudioStandard
1240 } // namespace OHOS
1241