• 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 "RemoteAudioRenderSink"
18 #endif
19 
20 #include "sink/remote_audio_render_sink.h"
21 #include <sstream>
22 #include <climits>
23 #include <utility>
24 #include <algorithm>
25 #include "audio_hdi_log.h"
26 #include "audio_errors.h"
27 #include "audio_utils.h"
28 #include "audio_dump_pcm.h"
29 #include "volume_tools.h"
30 #include "audio_performance_monitor.h"
31 #include "common/hdi_adapter_info.h"
32 #include "manager/hdi_adapter_manager.h"
33 
34 using namespace OHOS::HDI::DistributedAudio::Audio::V1_0;
35 
36 namespace OHOS {
37 namespace AudioStandard {
38 const std::unordered_map<std::string, AudioCategory> RemoteAudioRenderSink::SPLIT_STREAM_MAP = {
39     { std::string(MEDIA_STREAM_TYPE), AudioCategory::AUDIO_IN_MEDIA },
40     { std::string(NAVIGATION_STREAM_TYPE), AudioCategory::AUDIO_IN_NAVIGATION },
41     { std::string(COMMUNICATION_STREAM_TYPE), AudioCategory::AUDIO_IN_COMMUNICATION },
42 };
43 
RemoteAudioRenderSink(const std::string & deviceNetworkId)44 RemoteAudioRenderSink::RemoteAudioRenderSink(const std::string &deviceNetworkId)
45     : deviceNetworkId_(deviceNetworkId)
46 {
47     AUDIO_DEBUG_LOG("construction");
48 }
49 
~RemoteAudioRenderSink()50 RemoteAudioRenderSink::~RemoteAudioRenderSink()
51 {
52     if (sinkInited_.load()) {
53         DeInit();
54     }
55     AUDIO_DEBUG_LOG("destruction");
56     AudioPerformanceMonitor::GetInstance().DeleteOvertimeMonitor(ADAPTER_TYPE_REMOTE);
57 }
58 
Init(const IAudioSinkAttr & attr)59 int32_t RemoteAudioRenderSink::Init(const IAudioSinkAttr &attr)
60 {
61     std::lock_guard<std::mutex> lock(sinkMutex_);
62     AUDIO_INFO_LOG("in");
63     attr_ = attr;
64     std::vector<AudioCategory> splitStreamVector;
65     InitSplitStream(attr_.aux.c_str(), splitStreamVector);
66     std::unique_lock<std::shared_mutex> wrapperLock(renderWrapperMutex_);
67     for (auto &splitStream : splitStreamVector) {
68         audioRenderWrapperMap_[splitStream] = {};
69     }
70     sinkInited_.store(true);
71     return SUCCESS;
72 }
73 
DeInit(void)74 void RemoteAudioRenderSink::DeInit(void)
75 {
76     std::lock_guard<std::mutex> lock(sinkMutex_);
77     Trace trace("RemoteAudioRenderSink::DeInit");
78     AUDIO_INFO_LOG("in");
79 
80     JoinStartThread();
81 
82     sinkInited_.store(false);
83     renderInited_.store(false);
84     started_.store(false);
85     paused_.store(false);
86 
87     HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
88     std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_REMOTE);
89     CHECK_AND_RETURN(deviceManager != nullptr);
90     std::unique_lock<std::shared_mutex> wrapperLock(renderWrapperMutex_);
91     for (auto &it : audioRenderWrapperMap_) {
92         deviceManager->DestroyRender(deviceNetworkId_, it.second.hdiRenderId_);
93         deviceManager->UnRegistRenderSinkCallback(deviceNetworkId_, it.second.hdiRenderId_);
94         it.second.audioRender_.ForceSetRefPtr(nullptr);
95         DumpFileUtil::CloseDumpFile(&it.second.dumpFile_);
96     }
97     audioRenderWrapperMap_.clear();
98     AUDIO_INFO_LOG("end");
99 }
100 
IsInited(void)101 bool RemoteAudioRenderSink::IsInited(void)
102 {
103     return sinkInited_.load();
104 }
105 
JoinStartThread()106 void RemoteAudioRenderSink::JoinStartThread()
107 {
108     std::lock_guard<std::mutex> lock(threadMutex_);
109     if (startThread_ != nullptr) {
110         if (startThread_->joinable()) {
111             startThread_->join();
112         }
113         startThread_ = nullptr;
114     }
115 }
116 
Start(void)117 int32_t RemoteAudioRenderSink::Start(void)
118 {
119     Trace trace("RemoteAudioRenderSink::Start");
120     AUDIO_INFO_LOG("in");
121     std::lock_guard<std::mutex> lock(createRenderMutex_);
122 
123     std::shared_lock<std::shared_mutex> wrapperLock(renderWrapperMutex_);
124     for (auto &it : audioRenderWrapperMap_) {
125         it.second.dumpFileName_ = std::string(DUMP_REMOTE_RENDER_SINK_FILENAME) + "_" + std::to_string(it.first) +
126             '_' + GetTime() + "_" + std::to_string(attr_.sampleRate) + "_" + std::to_string(attr_.channel) + "_" +
127             std::to_string(attr_.format) + ".pcm";
128         DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, it.second.dumpFileName_ + std::to_string(it.first) +
129             ".pcm", &(it.second.dumpFile_));
130     }
131     wrapperLock.unlock();
132 
133     CHECK_AND_RETURN_RET_LOG(sinkInited_.load(), ERR_ILLEGAL_STATE, "not inited");
134 
135     if (isThreadRunning_.load()) {
136         AUDIO_INFO_LOG("SubThread is already running");
137         return SUCCESS;
138     }
139 
140     JoinStartThread();
141     isThreadRunning_.store(true);
142 
143     std::lock_guard<std::mutex> threadLock(threadMutex_);
144     startThread_ = std::make_shared<std::thread>([this]() {
145         AUDIO_INFO_LOG("SubThread Start");
146         if (!renderInited_.load()) {
147             std::unique_lock<std::shared_mutex> wrapperLock(renderWrapperMutex_);
148             for (auto &it : audioRenderWrapperMap_) {
149                 int32_t ret = CreateRender(it.first);
150                 CHECK_AND_RETURN_LOG(ret == SUCCESS, "create render fail");
151                 renderInited_.store(true);
152             }
153         }
154 
155         if (started_.load()) {
156             AUDIO_INFO_LOG("already started");
157             isThreadRunning_.store(false);
158             return;
159         }
160 
161         std::shared_lock<std::shared_mutex> wrapperLock(renderWrapperMutex_);
162         for (auto &it : audioRenderWrapperMap_) {
163             CHECK_AND_RETURN_LOG(it.second.audioRender_ != nullptr,
164                 "render is nullptr, type: %{public}d", it.first);
165             int32_t ret = it.second.audioRender_->Start();
166             CHECK_AND_RETURN_LOG(ret == SUCCESS, "start fail, type: %{public}d, ret: %{public}d", it.first, ret);
167         }
168         started_.store(true);
169         isThreadRunning_.store(false);
170         AUDIO_INFO_LOG("SubThread End");
171     });
172 
173     AudioPerformanceMonitor::GetInstance().RecordTimeStamp(ADAPTER_TYPE_REMOTE, INIT_LASTWRITTEN_TIME);
174     return SUCCESS;
175 }
176 
Stop(void)177 int32_t RemoteAudioRenderSink::Stop(void)
178 {
179     Trace trace("RemoteAudioRenderSink::Stop");
180     AUDIO_INFO_LOG("in");
181 
182     JoinStartThread();
183 
184     if (!started_.load()) {
185         AUDIO_INFO_LOG("already stopped");
186         return SUCCESS;
187     }
188 
189     std::shared_lock<std::shared_mutex> lock(renderWrapperMutex_);
190     for (auto &it : audioRenderWrapperMap_) {
191         CHECK_AND_RETURN_RET_LOG(it.second.audioRender_ != nullptr, ERR_INVALID_HANDLE,
192             "render is nullptr, type: %{public}d", it.first);
193         int32_t ret = it.second.audioRender_->Stop();
194         CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "stop fail, type: %{public}d, ret: %{public}d",
195             it.first, ret);
196     }
197     started_.store(false);
198     isThreadRunning_.store(false);
199     return SUCCESS;
200 }
201 
Resume(void)202 int32_t RemoteAudioRenderSink::Resume(void)
203 {
204     Trace trace("RemoteAudioRenderSink::Resume");
205     AUDIO_INFO_LOG("in");
206     CHECK_AND_RETURN_RET_LOG(started_.load(), ERR_ILLEGAL_STATE, "not start, invalid state");
207 
208     if (!paused_.load()) {
209         AUDIO_INFO_LOG("already resumed");
210         return SUCCESS;
211     }
212 
213     std::shared_lock<std::shared_mutex> lock(renderWrapperMutex_);
214     for (auto &it : audioRenderWrapperMap_) {
215         CHECK_AND_RETURN_RET_LOG(it.second.audioRender_ != nullptr, ERR_INVALID_HANDLE,
216             "render is nullptr, type: %{public}d", it.first);
217         int32_t ret = it.second.audioRender_->Resume();
218         CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "resume fail, type: %{public}d, ret: %{public}d",
219             it.first, ret);
220     }
221     paused_.store(false);
222     AudioPerformanceMonitor::GetInstance().RecordTimeStamp(ADAPTER_TYPE_REMOTE, INIT_LASTWRITTEN_TIME);
223     return SUCCESS;
224 }
225 
Pause(void)226 int32_t RemoteAudioRenderSink::Pause(void)
227 {
228     AUDIO_INFO_LOG("in");
229     CHECK_AND_RETURN_RET_LOG(started_.load(), ERR_ILLEGAL_STATE, "not start, invalid state");
230 
231     if (paused_.load()) {
232         AUDIO_INFO_LOG("already paused");
233         return SUCCESS;
234     }
235 
236     std::shared_lock<std::shared_mutex> lock(renderWrapperMutex_);
237     for (auto &it : audioRenderWrapperMap_) {
238         CHECK_AND_RETURN_RET_LOG(it.second.audioRender_ != nullptr, ERR_INVALID_HANDLE,
239             "render is nullptr, type: %{public}d", it.first);
240         int32_t ret = it.second.audioRender_->Pause();
241         CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "pause fail, type: %{public}d, ret: %{public}d",
242             it.first, ret);
243     }
244     paused_.store(true);
245     return SUCCESS;
246 }
247 
Flush(void)248 int32_t RemoteAudioRenderSink::Flush(void)
249 {
250     Trace trace("RemoteAudioRenderSink::Flush");
251     AUDIO_INFO_LOG("in");
252     CHECK_AND_RETURN_RET_LOG(started_.load(), ERR_ILLEGAL_STATE, "not start, invalid state");
253 
254     std::shared_lock<std::shared_mutex> lock(renderWrapperMutex_);
255     for (auto &it : audioRenderWrapperMap_) {
256         CHECK_AND_RETURN_RET_LOG(it.second.audioRender_ != nullptr, ERR_INVALID_HANDLE,
257             "render is nullptr, type: %{public}d", it.first);
258         int32_t ret = it.second.audioRender_->Flush();
259         CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "flush fail, type: %{public}d, ret: %{public}d",
260             it.first, ret);
261     }
262     return SUCCESS;
263 }
264 
Reset(void)265 int32_t RemoteAudioRenderSink::Reset(void)
266 {
267     Trace trace("RemoteAudioRenderSink::Reset");
268     AUDIO_INFO_LOG("in");
269     CHECK_AND_RETURN_RET_LOG(started_.load(), ERR_ILLEGAL_STATE, "not start, invalid state");
270 
271     std::shared_lock<std::shared_mutex> lock(renderWrapperMutex_);
272     for (auto &it : audioRenderWrapperMap_) {
273         CHECK_AND_RETURN_RET_LOG(it.second.audioRender_ != nullptr, ERR_INVALID_HANDLE,
274             "render is nullptr, type: %{public}d", it.first);
275         int32_t ret = it.second.audioRender_->Flush();
276         CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "reset fail, type: %{public}d, ret: %{public}d",
277             it.first, ret);
278     }
279     return SUCCESS;
280 }
281 
RenderFrame(char & data,uint64_t len,uint64_t & writeLen)282 int32_t RemoteAudioRenderSink::RenderFrame(char &data, uint64_t len, uint64_t &writeLen)
283 {
284     Trace trace("RemoteAudioRenderSink::RenderFrame");
285     AUDIO_DEBUG_LOG("in");
286     return RenderFrame(data, len, writeLen, AUDIO_IN_MEDIA);
287 }
288 
GetVolumeDataCount()289 int64_t RemoteAudioRenderSink::GetVolumeDataCount()
290 {
291     return volumeDataCount_;
292 }
293 
SuspendRenderSink(void)294 int32_t RemoteAudioRenderSink::SuspendRenderSink(void)
295 {
296     return SUCCESS;
297 }
298 
RestoreRenderSink(void)299 int32_t RemoteAudioRenderSink::RestoreRenderSink(void)
300 {
301     return SUCCESS;
302 }
303 
SetAudioParameter(const AudioParamKey key,const std::string & condition,const std::string & value)304 void RemoteAudioRenderSink::SetAudioParameter(const AudioParamKey key, const std::string &condition,
305     const std::string &value)
306 {
307 }
308 
GetAudioParameter(const AudioParamKey key,const std::string & condition)309 std::string RemoteAudioRenderSink::GetAudioParameter(const AudioParamKey key, const std::string &condition)
310 {
311     return "";
312 }
313 
SetVolume(float left,float right)314 int32_t RemoteAudioRenderSink::SetVolume(float left, float right)
315 {
316     CHECK_AND_RETURN_RET_LOG(renderInited_.load(), ERR_ILLEGAL_STATE, "not create, invalid state");
317     leftVolume_ = left;
318     rightVolume_ = right;
319     float volume;
320     if ((leftVolume_ == 0) && (rightVolume_ != 0)) {
321         volume = rightVolume_;
322     } else if ((leftVolume_ != 0) && (rightVolume_ == 0)) {
323         volume = leftVolume_;
324     } else {
325         volume = (leftVolume_ + rightVolume_) / HALF_FACTOR;
326     }
327 
328     std::shared_lock<std::shared_mutex> lock(renderWrapperMutex_);
329     for (const auto &wrapper : audioRenderWrapperMap_) {
330         CHECK_AND_RETURN_RET_LOG(wrapper.second.audioRender_ != nullptr, ERR_INVALID_HANDLE,
331             "render is nullptr, type: %{public}d", wrapper.first);
332         int32_t ret = wrapper.second.audioRender_->SetVolume(volume);
333         CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "set volume fail, ret: %{public}d", ret);
334     }
335     return SUCCESS;
336 }
337 
GetVolume(float & left,float & right)338 int32_t RemoteAudioRenderSink::GetVolume(float &left, float &right)
339 {
340     left = leftVolume_;
341     right = rightVolume_;
342     return SUCCESS;
343 }
344 
GetLatency(uint32_t & latency)345 int32_t RemoteAudioRenderSink::GetLatency(uint32_t &latency)
346 {
347     CHECK_AND_RETURN_RET_LOG(renderInited_.load(), ERR_ILLEGAL_STATE, "not create, invalid state");
348     uint32_t hdiLatency = 0;
349     std::shared_lock<std::shared_mutex> lock(renderWrapperMutex_);
350     for (const auto &wrapper : audioRenderWrapperMap_) {
351         CHECK_AND_RETURN_RET_LOG(wrapper.second.audioRender_ != nullptr, ERR_INVALID_HANDLE,
352             "render is nullptr, type: %{public}d", wrapper.first);
353         int32_t ret = wrapper.second.audioRender_->GetLatency(hdiLatency);
354         CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "get latency fail, ret: %{public}d", ret);
355     }
356     latency = hdiLatency;
357     return SUCCESS;
358 }
359 
GetTransactionId(uint64_t & transactionId)360 int32_t RemoteAudioRenderSink::GetTransactionId(uint64_t &transactionId)
361 {
362     AUDIO_INFO_LOG("not support");
363     return ERR_NOT_SUPPORTED;
364 }
365 
GetPresentationPosition(uint64_t & frames,int64_t & timeSec,int64_t & timeNanoSec)366 int32_t RemoteAudioRenderSink::GetPresentationPosition(uint64_t &frames, int64_t &timeSec, int64_t &timeNanoSec)
367 {
368     AUDIO_INFO_LOG("not support");
369     return ERR_NOT_SUPPORTED;
370 }
371 
GetMaxAmplitude(void)372 float RemoteAudioRenderSink::GetMaxAmplitude(void)
373 {
374     lastGetMaxAmplitudeTime_ = ClockTime::GetCurNano();
375     startUpdate_ = true;
376     return maxAmplitude_;
377 }
378 
SetAudioMonoState(bool audioMono)379 void RemoteAudioRenderSink::SetAudioMonoState(bool audioMono)
380 {
381     AUDIO_INFO_LOG("not support");
382 }
383 
SetAudioBalanceValue(float audioBalance)384 void RemoteAudioRenderSink::SetAudioBalanceValue(float audioBalance)
385 {
386     AUDIO_INFO_LOG("not support");
387 }
388 
SetAudioScene(AudioScene audioScene,bool scoExcludeFlag)389 int32_t RemoteAudioRenderSink::SetAudioScene(AudioScene audioScene, bool scoExcludeFlag)
390 {
391     CHECK_AND_RETURN_RET_LOG(renderInited_.load(), ERR_ILLEGAL_STATE, "not create, invalid state");
392     CHECK_AND_RETURN_RET_LOG(audioScene >= AUDIO_SCENE_DEFAULT && audioScene < AUDIO_SCENE_MAX, ERR_INVALID_PARAM,
393         "invalid scene");
394 
395     int32_t ret = DoSetOutputRoute();
396     if (ret != SUCCESS) {
397         AUDIO_WARNING_LOG("update route fail, ret: %{public}d", ret);
398     }
399 
400     struct AudioSceneDescriptor sceneDesc = {
401         .scene.id = GetAudioCategory(audioScene),
402         .desc.pins = AudioPortPin::PIN_OUT_SPEAKER,
403     };
404     AUDIO_DEBUG_LOG("start");
405     std::shared_lock<std::shared_mutex> lock(renderWrapperMutex_);
406     for (const auto &wrapper : audioRenderWrapperMap_) {
407         CHECK_AND_RETURN_RET_LOG(wrapper.second.audioRender_ != nullptr, ERR_INVALID_HANDLE,
408             "render is nullptr, type: %{public}d", wrapper.first);
409         ret = wrapper.second.audioRender_->SelectScene(sceneDesc);
410         CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "select scene fail, ret: %{public}d", ret);
411     }
412     AUDIO_DEBUG_LOG("end, audioScene: %{public}d", audioScene);
413     return SUCCESS;
414 }
415 
GetAudioScene(void)416 int32_t RemoteAudioRenderSink::GetAudioScene(void)
417 {
418     AUDIO_INFO_LOG("not support");
419     return ERR_NOT_SUPPORTED;
420 }
421 
UpdateActiveDevice(std::vector<DeviceType> & outputDevices)422 int32_t RemoteAudioRenderSink::UpdateActiveDevice(std::vector<DeviceType> &outputDevices)
423 {
424     AUDIO_INFO_LOG("not support");
425     return ERR_NOT_SUPPORTED;
426 }
427 
RegistCallback(uint32_t type,IAudioSinkCallback * callback)428 void RemoteAudioRenderSink::RegistCallback(uint32_t type, IAudioSinkCallback *callback)
429 {
430     AUDIO_INFO_LOG("in");
431     callback_.RegistCallback(type, callback);
432 }
433 
ResetActiveDeviceForDisconnect(DeviceType device)434 void RemoteAudioRenderSink::ResetActiveDeviceForDisconnect(DeviceType device)
435 {
436     AUDIO_INFO_LOG("not support");
437 }
438 
SetPaPower(int32_t flag)439 int32_t RemoteAudioRenderSink::SetPaPower(int32_t flag)
440 {
441     AUDIO_INFO_LOG("not support");
442     return ERR_NOT_SUPPORTED;
443 }
444 
SetPriPaPower(void)445 int32_t RemoteAudioRenderSink::SetPriPaPower(void)
446 {
447     AUDIO_INFO_LOG("not support");
448     return ERR_NOT_SUPPORTED;
449 }
450 
UpdateAppsUid(const int32_t appsUid[MAX_MIX_CHANNELS],const size_t size)451 int32_t RemoteAudioRenderSink::UpdateAppsUid(const int32_t appsUid[MAX_MIX_CHANNELS], const size_t size)
452 {
453     return ERR_NOT_SUPPORTED;
454 }
455 
UpdateAppsUid(const std::vector<int32_t> & appsUid)456 int32_t RemoteAudioRenderSink::UpdateAppsUid(const std::vector<int32_t> &appsUid)
457 {
458     return ERR_NOT_SUPPORTED;
459 }
460 
SplitRenderFrame(char & data,uint64_t len,uint64_t & writeLen,const char * streamType)461 int32_t RemoteAudioRenderSink::SplitRenderFrame(char &data, uint64_t len, uint64_t &writeLen, const char *streamType)
462 {
463     Trace trace("RemoteAudioRenderSink::SplitRenderFrame");
464     AUDIO_DEBUG_LOG("in, type: %{public}s", streamType);
465     auto it = SPLIT_STREAM_MAP.find(streamType);
466     CHECK_AND_RETURN_RET_LOG(it != SPLIT_STREAM_MAP.end(), ERR_INVALID_PARAM, "invalid stream type");
467     return RenderFrame(data, len, writeLen, it->second);
468 }
469 
DumpInfo(std::string & dumpString)470 void RemoteAudioRenderSink::DumpInfo(std::string &dumpString)
471 {
472     dumpString += "type: RemoteSink\tstarted: " + std::string(started_.load() ? "true" : "false") +
473         "\tdeviceNetworkId: " + deviceNetworkId_ + "\n";
474 }
475 
OnAudioParamChange(const std::string & adapterName,const AudioParamKey key,const std::string & condition,const std::string & value)476 void RemoteAudioRenderSink::OnAudioParamChange(const std::string &adapterName, const AudioParamKey key,
477     const std::string &condition, const std::string &value)
478 {
479     AUDIO_INFO_LOG("key: %{public}d, condition: %{public}s, value: %{public}s", key, condition.c_str(), value.c_str());
480     if (key == AudioParamKey::PARAM_KEY_STATE) {
481         DeInit();
482     }
483 
484     callback_.OnRenderSinkParamChange(adapterName, key, condition, value);
485 }
486 
SetDmDeviceType(uint16_t dmDeviceType,DeviceType deviceType)487 void RemoteAudioRenderSink::SetDmDeviceType(uint16_t dmDeviceType, DeviceType deviceType)
488 {
489     AUDIO_INFO_LOG("not support");
490 }
491 
ConvertToHdiFormat(AudioSampleFormat format)492 AudioFormat RemoteAudioRenderSink::ConvertToHdiFormat(AudioSampleFormat format)
493 {
494     AudioFormat hdiFormat;
495     switch (format) {
496         case SAMPLE_U8:
497             hdiFormat = AUDIO_FORMAT_TYPE_PCM_8_BIT;
498             break;
499         case SAMPLE_S16LE:
500             hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT;
501             break;
502         case SAMPLE_S24LE:
503             hdiFormat = AUDIO_FORMAT_TYPE_PCM_24_BIT;
504             break;
505         case SAMPLE_S32LE:
506             hdiFormat = AUDIO_FORMAT_TYPE_PCM_32_BIT;
507             break;
508         default:
509             hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT;
510             break;
511     }
512 
513     return hdiFormat;
514 }
515 
GetAudioCategory(AudioScene audioScene)516 AudioCategory RemoteAudioRenderSink::GetAudioCategory(AudioScene audioScene)
517 {
518     AudioCategory audioCategory;
519     switch (audioScene) {
520         case AUDIO_SCENE_DEFAULT:
521             audioCategory = AUDIO_IN_MEDIA;
522             break;
523         case AUDIO_SCENE_RINGING:
524         case AUDIO_SCENE_VOICE_RINGING:
525             audioCategory = AUDIO_IN_RINGTONE;
526             break;
527         case AUDIO_SCENE_PHONE_CALL:
528             audioCategory = AUDIO_IN_CALL;
529             break;
530         case AUDIO_SCENE_PHONE_CHAT:
531             audioCategory = AUDIO_IN_COMMUNICATION;
532             break;
533         default:
534             audioCategory = AUDIO_IN_MEDIA;
535             break;
536     }
537     AUDIO_DEBUG_LOG("audioCategory: %{public}d", audioCategory);
538 
539     return audioCategory;
540 }
541 
InitSplitStream(const char * splitStreamStr,std::vector<AudioCategory> & splitStreamVector)542 void RemoteAudioRenderSink::InitSplitStream(const char *splitStreamStr, std::vector<AudioCategory> &splitStreamVector)
543 {
544     AUDIO_INFO_LOG("splitStreamStr: %{public}s", splitStreamStr);
545     if (splitStreamStr == nullptr || strlen(splitStreamStr) == 0) {
546         splitStreamVector.push_back(AudioCategory::AUDIO_IN_MEDIA);
547         AUDIO_INFO_LOG("split stream use default 1");
548         return;
549     }
550 
551     std::istringstream iss(splitStreamStr);
552     std::string currentSplitStream;
553     std::vector<std::string> splitStreamStrVector;
554     while (getline(iss, currentSplitStream, ':')) {
555         splitStreamStrVector.push_back(currentSplitStream);
556         AUDIO_INFO_LOG("current split stream type is %{public}s", currentSplitStream.c_str());
557     }
558     sort(splitStreamStrVector.begin(), splitStreamStrVector.end());
559     for (auto &splitStream : splitStreamStrVector) {
560         auto it = SPLIT_STREAM_MAP.find(splitStream);
561         if (it == SPLIT_STREAM_MAP.end()) {
562             AUDIO_ERR_LOG("invalid stream type %{public}s", splitStream.c_str());
563             continue;
564         }
565         splitStreamVector.push_back(it->second);
566     }
567 }
568 
InitAudioSampleAttr(AudioSampleAttributes & param,AudioCategory type)569 void RemoteAudioRenderSink::InitAudioSampleAttr(AudioSampleAttributes &param, AudioCategory type)
570 {
571     param.channelCount = AUDIO_CHANNELCOUNT;
572     param.sampleRate = AUDIO_SAMPLE_RATE_48K;
573     param.interleaved = 0;
574     param.streamId = static_cast<int32_t>(GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_REMOTE));
575     param.type = AUDIO_IN_MEDIA;
576     param.period = DEEP_BUFFER_RENDER_PERIOD_SIZE;
577     param.isBigEndian = false;
578     param.isSignedData = true;
579     param.stopThreshold = INT_MAX;
580     param.silenceThreshold = 0;
581 
582     param.sampleRate = attr_.sampleRate;
583     param.channelCount = attr_.channel;
584     param.format = ConvertToHdiFormat(attr_.format);
585     param.frameSize = PCM_16_BIT * param.channelCount / PCM_8_BIT;
586     if (param.frameSize != 0) {
587         param.startThreshold = DEEP_BUFFER_RENDER_PERIOD_SIZE / (param.frameSize);
588     }
589 
590     param.type = type;
591 }
592 
InitDeviceDesc(AudioDeviceDescriptor & deviceDesc)593 void RemoteAudioRenderSink::InitDeviceDesc(AudioDeviceDescriptor &deviceDesc)
594 {
595     deviceDesc.pins = AudioPortPin::PIN_OUT_SPEAKER;
596     deviceDesc.desc = "";
597 }
598 
CreateRender(AudioCategory type)599 int32_t RemoteAudioRenderSink::CreateRender(AudioCategory type)
600 {
601     int64_t stamp = ClockTime::GetCurNano();
602 
603     struct AudioSampleAttributes param;
604     struct AudioDeviceDescriptor deviceDesc;
605     InitAudioSampleAttr(param, type);
606     InitDeviceDesc(deviceDesc);
607     struct RenderWrapper &wrapper = audioRenderWrapperMap_[type];
608 
609     AUDIO_INFO_LOG("create render, format: %{public}u", param.format);
610     HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
611     std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_REMOTE);
612     CHECK_AND_RETURN_RET(deviceManager != nullptr, ERR_INVALID_HANDLE);
613     void *render = deviceManager->CreateRender(deviceNetworkId_, &param, &deviceDesc, wrapper.hdiRenderId_);
614     wrapper.audioRender_.ForceSetRefPtr(static_cast<IAudioRender *>(render));
615     CHECK_AND_RETURN_RET(wrapper.audioRender_ != nullptr, ERR_NOT_STARTED);
616     deviceManager->RegistRenderSinkCallback(deviceNetworkId_, wrapper.hdiRenderId_, this);
617 
618     stamp = (ClockTime::GetCurNano() - stamp) / AUDIO_US_PER_SECOND;
619     AUDIO_INFO_LOG("create render success, cost: [%{public}" PRId64 "]ms", stamp);
620     return SUCCESS;
621 }
622 
DoSetOutputRoute(void)623 int32_t RemoteAudioRenderSink::DoSetOutputRoute(void)
624 {
625     std::shared_lock<std::shared_mutex> lock(renderWrapperMutex_);
626     if (audioRenderWrapperMap_.find(AUDIO_IN_MEDIA) == audioRenderWrapperMap_.end()) {
627         AUDIO_WARNING_LOG("render not include AUDIO_IN_MEDIA");
628         return ERR_INVALID_HANDLE;
629     }
630     HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
631     std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_REMOTE);
632     CHECK_AND_RETURN_RET(deviceManager != nullptr, ERR_INVALID_HANDLE);
633     int32_t ret = deviceManager->SetOutputRoute(deviceNetworkId_, { DEVICE_TYPE_SPEAKER }, static_cast<int32_t>(
634         GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_REMOTE)));
635     return ret;
636 }
637 
CheckUpdateState(char * data,uint64_t len)638 void RemoteAudioRenderSink::CheckUpdateState(char *data, uint64_t len)
639 {
640     if (startUpdate_) {
641         if (renderFrameNum_ == 0) {
642             last10FrameStartTime_ = ClockTime::GetCurNano();
643         }
644         renderFrameNum_++;
645         maxAmplitude_ = UpdateMaxAmplitude(static_cast<ConvertHdiFormat>(attr_.format), data, len);
646         if (renderFrameNum_ == GET_MAX_AMPLITUDE_FRAMES_THRESHOLD) {
647             renderFrameNum_ = 0;
648             if (last10FrameStartTime_ > lastGetMaxAmplitudeTime_) {
649                 startUpdate_ = false;
650                 maxAmplitude_ = 0;
651             }
652         }
653     }
654 }
655 
RenderFrame(char & data,uint64_t len,uint64_t & writeLen,AudioCategory type)656 int32_t RemoteAudioRenderSink::RenderFrame(char &data, uint64_t len, uint64_t &writeLen, AudioCategory type)
657 {
658     CHECK_AND_RETURN_RET_LOG(renderInited_.load(), ERR_ILLEGAL_STATE, "not create, invalid state");
659     AUDIO_DEBUG_LOG("type: %{public}d", type);
660     int64_t stamp = ClockTime::GetCurNano();
661     std::shared_lock<std::shared_mutex> lock(renderWrapperMutex_);
662     sptr<IAudioRender> audioRender = audioRenderWrapperMap_[type].audioRender_;
663     CHECK_AND_RETURN_RET_LOG(audioRender != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
664     if (!started_.load()) {
665         AUDIO_WARNING_LOG("not start, invalid state");
666     }
667 
668     std::vector<int8_t> bufferVec(len);
669     int32_t ret = memcpy_s(bufferVec.data(), len, &data, len);
670     CHECK_AND_RETURN_RET_LOG(ret == EOK, ERR_OPERATION_FAILED, "copy fail, error code: %{public}d", ret);
671 
672     BufferDesc buffer = { reinterpret_cast<uint8_t *>(&data), len, len };
673     AudioStreamInfo streamInfo(static_cast<AudioSamplingRate>(attr_.sampleRate), AudioEncodingType::ENCODING_PCM,
674         static_cast<AudioSampleFormat>(attr_.format), static_cast<AudioChannel>(attr_.channel));
675     VolumeTools::DfxOperation(buffer, streamInfo, logUtilsTag_ + std::to_string(type), volumeDataCount_);
676     Trace trace("RemoteAudioRenderSink::RenderFrame inner renderFrame");
677     Trace::CountVolume("RemoteAudioRenderSink::RenderFrame", static_cast<uint8_t>(data));
678     ret = audioRender->RenderFrame(bufferVec, writeLen);
679     AudioPerformanceMonitor::GetInstance().RecordTimeStamp(ADAPTER_TYPE_REMOTE, ClockTime::GetCurNano());
680     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_WRITE_FAILED, "fail, ret: %{public}x", ret);
681     writeLen = len;
682     if (AudioDump::GetInstance().GetVersionType() == DumpFileUtil::BETA_VERSION) {
683         FILE *dumpFile = audioRenderWrapperMap_[type].dumpFile_;
684         DumpFileUtil::WriteDumpFile(dumpFile, static_cast<void *>(&data), len);
685         std::string dumpFileName = audioRenderWrapperMap_[type].dumpFileName_;
686         AudioCacheMgr::GetInstance().CacheData(dumpFileName, static_cast<void *>(&data), len);
687     }
688     CheckUpdateState(&data, len);
689 
690     stamp = (ClockTime::GetCurNano() - stamp) / AUDIO_US_PER_SECOND;
691     int64_t stampThreshold = 50; // 50ms
692     if (stamp >= stampThreshold) {
693         AUDIO_WARNING_LOG("len: [%{public}" PRIu64 "], cost: [%{public}" PRId64 "]ms", len, stamp);
694     }
695     return SUCCESS;
696 }
697 
698 } // namespace AudioStandard
699 } // namespace OHOS
700