• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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 #ifndef LOG_TAG
16 #define LOG_TAG "FastAudioRendererSinkInner"
17 #endif
18 
19 #include "fast_audio_renderer_sink.h"
20 
21 #include <cinttypes>
22 #include <climits>
23 #include <cstdio>
24 #include <cstring>
25 #include <dlfcn.h>
26 #include <list>
27 #include <mutex>
28 #include <string>
29 #include <unistd.h>
30 
31 #include <sys/mman.h>
32 #ifdef FEATURE_POWER_MANAGER
33 #include "power_mgr_client.h"
34 #include "running_lock.h"
35 #include "audio_running_lock_manager.h"
36 #endif
37 #include "securec.h"
38 #include "v4_0/iaudio_manager.h"
39 
40 #include "audio_errors.h"
41 #include "audio_hdi_log.h"
42 #include "audio_utils.h"
43 
44 using namespace std;
45 
46 namespace OHOS {
47 namespace AudioStandard {
48 namespace {
49 const int32_t HALF_FACTOR = 2;
50 const uint32_t MAX_AUDIO_ADAPTER_NUM = 5;
51 const float DEFAULT_VOLUME_LEVEL = 1.0f;
52 const uint32_t AUDIO_CHANNELCOUNT = 2;
53 const uint32_t DEEP_BUFFER_RENDER_PERIOD_SIZE = 3840;
54 const uint32_t INT_32_MAX = 0x7fffffff;
55 const uint32_t PCM_8_BIT = 8;
56 const uint32_t PCM_16_BIT = 16;
57 const uint32_t PCM_24_BIT = 24;
58 const uint32_t PCM_32_BIT = 32;
59 const int64_t SECOND_TO_NANOSECOND = 1000000000;
60 const int INVALID_FD = -1;
61 const unsigned int XCOLLIE_TIME_OUT_SECONDS = 10;
62 }
63 
64 class FastAudioRendererSinkInner : public FastAudioRendererSink {
65 public:
66     int32_t Init(const IAudioSinkAttr &attr) override;
67     bool IsInited(void) override;
68     void DeInit(void) override;
69 
70     int32_t Start(void) override;
71     int32_t Stop(void) override;
72     int32_t Flush(void) override;
73     int32_t Reset(void) override;
74     int32_t Pause(void) override;
75     int32_t Resume(void) override;
76 
77     int32_t SuspendRenderSink(void) override;
78     int32_t RestoreRenderSink(void) override;
79 
80     int32_t RenderFrame(char &data, uint64_t len, uint64_t &writeLen) override;
81     int32_t SetVolume(float left, float right) override;
82     int32_t GetVolume(float &left, float &right) override;
83     int32_t SetVoiceVolume(float volume) override;
84     int32_t GetLatency(uint32_t *latency) override;
85     int32_t GetTransactionId(uint64_t *transactionId) override;
86     int32_t SetAudioScene(AudioScene audioScene, std::vector<DeviceType> &activeDevices) override;
87     int32_t SetOutputRoutes(std::vector<DeviceType> &outputDevices) override;
88     void ResetOutputRouteForDisconnect(DeviceType device) override;
89 
90     void SetAudioParameter(const AudioParamKey key, const std::string &condition, const std::string &value) override;
91     std::string GetAudioParameter(const AudioParamKey key, const std::string &condition) override;
92     void RegisterParameterCallback(IAudioSinkCallback* callback) override;
93 
94     void SetAudioMonoState(bool audioMono) override;
95     void SetAudioBalanceValue(float audioBalance) override;
96 
97     int32_t GetPresentationPosition(uint64_t& frames, int64_t& timeSec, int64_t& timeNanoSec) override;
98 
99     int32_t GetMmapBufferInfo(int &fd, uint32_t &totalSizeInframe, uint32_t &spanSizeInframe,
100         uint32_t &byteSizePerFrame) override;
101     int32_t GetMmapHandlePosition(uint64_t &frames, int64_t &timeSec, int64_t &timeNanoSec) override;
102     float GetMaxAmplitude() override;
103     int32_t SetPaPower(int32_t flag) override;
104     int32_t SetPriPaPower() override;
105 
106     int32_t UpdateAppsUid(const int32_t appsUid[MAX_MIX_CHANNELS], const size_t size) final;
107     int32_t UpdateAppsUid(const std::vector<int32_t> &appsUid) final;
108 
109     FastAudioRendererSinkInner();
110     ~FastAudioRendererSinkInner();
111 
112 private:
113 #ifdef FEATURE_POWER_MANAGER
114     void KeepRunningLock();
115     void KeepRunningUnlock();
116 #endif
117     int32_t PrepareMmapBuffer();
118     void ReleaseMmapBuffer();
119 
120     int32_t CheckPositionTime();
121     void PreparePosition();
122 
123     void InitAttrs(struct AudioSampleAttributes &attrs);
124     AudioFormat ConvertToHdiFormat(HdiAdapterFormat format);
125     int32_t CreateRender(const struct AudioPort &renderPort);
126     int32_t InitAudioManager();
127 
128 private:
129     IAudioSinkAttr attr_ = {};
130     bool rendererInited_ = false;
131     bool started_ = false;
132     bool paused_ = false;
133     float leftVolume_ = 0.0f;
134     float rightVolume_ = 0.0f;
135     int32_t routeHandle_ = -1;
136     std::string adapterNameCase_ = "";
137     struct IAudioManager *audioManager_ = nullptr;
138     struct IAudioAdapter *audioAdapter_ = nullptr;
139     struct IAudioRender *audioRender_ = nullptr;
140     struct AudioAdapterDescriptor adapterDesc_ = {};
141     struct AudioPort audioPort_ = {};
142     uint32_t renderId_ = 0;
143 
144     size_t bufferSize_ = 0;
145     uint32_t bufferTotalFrameSize_ = 0;
146 
147     int bufferFd_ = INVALID_FD;
148     uint32_t frameSizeInByte_ = 1;
149     uint32_t eachReadFrameSize_ = 0;
150     std::mutex mutex_;
151 #ifdef FEATURE_POWER_MANAGER
152     std::shared_ptr<AudioRunningLockManager<PowerMgr::RunningLock>> runningLockManager_;
153 #endif
154 
155 #ifdef DEBUG_DIRECT_USE_HDI
156     char *bufferAddresss_ = nullptr;
157     bool isFirstWrite_ = true;
158     uint64_t alreadyReadFrames_ = 0;
159     uint32_t curReadPos_ = 0;
160     uint32_t curWritePos_ = 0;
161     uint32_t writeAheadPeriod_ = 1;
162 
163     int privFd_ = INVALID_FD; // invalid fd
164 #endif
165 };  // FastAudioRendererSinkInner
166 
FastAudioRendererSinkInner()167 FastAudioRendererSinkInner::FastAudioRendererSinkInner()
168     : rendererInited_(false), started_(false), paused_(false), leftVolume_(DEFAULT_VOLUME_LEVEL),
169       rightVolume_(DEFAULT_VOLUME_LEVEL), audioManager_(nullptr), audioAdapter_(nullptr),
170       audioRender_(nullptr)
171 {
172     attr_ = {};
173 }
174 
~FastAudioRendererSinkInner()175 FastAudioRendererSinkInner::~FastAudioRendererSinkInner()
176 {
177     FastAudioRendererSinkInner::DeInit();
178 }
179 
GetInstance()180 IMmapAudioRendererSink *FastAudioRendererSink::GetInstance()
181 {
182     static FastAudioRendererSinkInner audioRenderer;
183 
184     return &audioRenderer;
185 }
186 
GetVoipInstance()187 IMmapAudioRendererSink *FastAudioRendererSink::GetVoipInstance()
188 {
189     static FastAudioRendererSinkInner audioVoipRenderer;
190 
191     return &audioVoipRenderer;
192 }
193 
CreateFastRendererSink()194 std::shared_ptr<IMmapAudioRendererSink> FastAudioRendererSink::CreateFastRendererSink()
195 {
196     std::shared_ptr<IMmapAudioRendererSink> audioRenderer = std::make_shared<FastAudioRendererSinkInner>();
197 
198     return audioRenderer;
199 }
200 
IsInited()201 bool FastAudioRendererSinkInner::IsInited()
202 {
203     return rendererInited_;
204 }
205 
DeInit()206 void FastAudioRendererSinkInner::DeInit()
207 {
208 #ifdef FEATURE_POWER_MANAGER
209     KeepRunningUnlock();
210 
211 #endif
212 
213     started_ = false;
214     rendererInited_ = false;
215     if ((audioRender_ != nullptr) && (audioAdapter_ != nullptr)) {
216         audioAdapter_->DestroyRender(audioAdapter_, renderId_);
217     }
218     audioRender_ = nullptr;
219 
220     if ((audioManager_ != nullptr) && (audioAdapter_ != nullptr)) {
221         if (routeHandle_ != -1) {
222             audioAdapter_->ReleaseAudioRoute(audioAdapter_, routeHandle_);
223         }
224         audioManager_->UnloadAdapter(audioManager_, adapterDesc_.adapterName);
225     }
226     audioAdapter_ = nullptr;
227     audioManager_ = nullptr;
228 
229     ReleaseMmapBuffer();
230 }
231 
InitAttrs(struct AudioSampleAttributes & attrs)232 void FastAudioRendererSinkInner::InitAttrs(struct AudioSampleAttributes &attrs)
233 {
234     /* Initialization of audio parameters for playback */
235     attrs.channelCount = AUDIO_CHANNELCOUNT;
236     attrs.interleaved = true;
237     attrs.streamId = attr_.audioStreamFlag == AUDIO_FLAG_VOIP_FAST ?
238         static_cast<int32_t>(GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_VOIP_FAST)) :
239         static_cast<int32_t>(GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_FAST));
240     attrs.period = DEEP_BUFFER_RENDER_PERIOD_SIZE;
241     attrs.isBigEndian = false;
242     attrs.isSignedData = true;
243     attrs.stopThreshold = INT_32_MAX;
244     attrs.silenceThreshold = 0;
245 }
246 
SwitchAdapterRender(struct AudioAdapterDescriptor * descs,string adapterNameCase,enum AudioPortDirection portFlag,struct AudioPort & renderPort,int32_t size)247 static int32_t SwitchAdapterRender(struct AudioAdapterDescriptor *descs, string adapterNameCase,
248     enum AudioPortDirection portFlag, struct AudioPort &renderPort, int32_t size)
249 {
250     if (descs == nullptr) {
251         return ERROR;
252     }
253     for (int32_t index = 0; index < size; index++) {
254         struct AudioAdapterDescriptor *desc = &descs[index];
255         if (desc == nullptr || desc->adapterName == nullptr) {
256             continue;
257         }
258         if (strcmp(desc->adapterName, adapterNameCase.c_str())) {
259             continue;
260         }
261         for (uint32_t port = 0; port < desc->portsLen; port++) {
262             // Only find out the port of out in the sound card
263             if (desc->ports[port].dir == portFlag) {
264                 renderPort = desc->ports[port];
265                 return index;
266             }
267         }
268     }
269     AUDIO_ERR_LOG("SwitchAdapterRender Fail");
270 
271     return ERR_INVALID_INDEX;
272 }
273 
InitAudioManager()274 int32_t FastAudioRendererSinkInner::InitAudioManager()
275 {
276     AUDIO_INFO_LOG("Initialize audio proxy manager");
277 
278     audioManager_ = IAudioManagerGet(false);
279     if (audioManager_ == nullptr) {
280         return ERR_INVALID_HANDLE;
281     }
282 
283     return 0;
284 }
285 
PcmFormatToBits(HdiAdapterFormat format)286 uint32_t PcmFormatToBits(HdiAdapterFormat format)
287 {
288     switch (format) {
289         case SAMPLE_U8:
290             return PCM_8_BIT;
291         case SAMPLE_S16LE:
292             return PCM_16_BIT;
293         case SAMPLE_S24LE:
294             return PCM_24_BIT;
295         case SAMPLE_S32LE:
296             return PCM_32_BIT;
297         case SAMPLE_F32LE:
298             return PCM_32_BIT;
299         default:
300             return PCM_24_BIT;
301     }
302 }
303 
GetMmapBufferInfo(int & fd,uint32_t & totalSizeInframe,uint32_t & spanSizeInframe,uint32_t & byteSizePerFrame)304 int32_t FastAudioRendererSinkInner::GetMmapBufferInfo(int &fd, uint32_t &totalSizeInframe, uint32_t &spanSizeInframe,
305     uint32_t &byteSizePerFrame)
306 {
307     CHECK_AND_RETURN_RET_LOG(bufferFd_ != INVALID_FD, ERR_INVALID_HANDLE, "buffer fd has been released!");
308     fd = bufferFd_;
309     totalSizeInframe = bufferTotalFrameSize_;
310     spanSizeInframe = eachReadFrameSize_;
311     byteSizePerFrame = PcmFormatToBits(attr_.format) * attr_.channel / PCM_8_BIT;
312     return SUCCESS;
313 }
314 
GetMmapHandlePosition(uint64_t & frames,int64_t & timeSec,int64_t & timeNanoSec)315 int32_t FastAudioRendererSinkInner::GetMmapHandlePosition(uint64_t &frames, int64_t &timeSec, int64_t &timeNanoSec)
316 {
317     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "Audio render is null!");
318 
319     struct AudioTimeStamp timestamp = {};
320     int32_t ret = audioRender_->GetMmapPosition(audioRender_, &frames, &timestamp);
321     CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_OPERATION_FAILED, "Hdi GetMmapPosition filed, ret:%{public}d!", ret);
322 #ifdef DEBUG_DIRECT_USE_HDI
323     alreadyReadFrames_ = frames; // frames already read.
324     curReadPos_ = frameSizeInByte_ * (frames - bufferTotalFrameSize_ * (frames / bufferTotalFrameSize_));
325     CHECK_AND_RETURN_RET_LOG((curReadPos_ >= 0 && curReadPos_ < bufferSize_), ERR_INVALID_PARAM, "curReadPos invalid");
326     AUDIO_DEBUG_LOG("GetMmapHandlePosition frames[:%{public}" PRIu64 "] tvsec:%{public}" PRId64 " tvNSec:"
327         "%{public}" PRId64 " alreadyReadFrames:%{public}" PRId64 " curReadPos[%{public}d]",
328         frames, timestamp.tvSec, timestamp.tvNSec, alreadyReadFrames_, curReadPos_);
329 #endif
330 
331     int64_t maxSec = 9223372036; // (9223372036 + 1) * 10^9 > INT64_MAX, seconds should not bigger than it.
332     CHECK_AND_RETURN_RET_LOG(timestamp.tvSec >= 0 && timestamp.tvSec <= maxSec && timestamp.tvNSec >= 0 &&
333         timestamp.tvNSec <= SECOND_TO_NANOSECOND, ERR_OPERATION_FAILED,
334         "Hdi GetMmapPosition get invaild second:%{public}" PRId64 " or nanosecond:%{public}" PRId64 " !",
335         timestamp.tvSec, timestamp.tvNSec);
336     timeSec = timestamp.tvSec;
337     timeNanoSec = timestamp.tvNSec;
338 
339     return SUCCESS;
340 }
341 
ReleaseMmapBuffer()342 void FastAudioRendererSinkInner::ReleaseMmapBuffer()
343 {
344 #ifdef DEBUG_DIRECT_USE_HDI
345     if (bufferAddresss_ != nullptr) {
346         munmap(bufferAddresss_, bufferSize_);
347         bufferAddresss_ = nullptr;
348         bufferSize_ = 0;
349         AUDIO_INFO_LOG("ReleaseMmapBuffer end.");
350     } else {
351         AUDIO_WARNING_LOG("ReleaseMmapBuffer buffer already null.");
352     }
353     if (privFd_ != INVALID_FD) {
354         close(privFd_);
355         privFd_ = INVALID_FD;
356     }
357 #endif
358     if (bufferFd_ != INVALID_FD) {
359         close(bufferFd_);
360         bufferFd_ = INVALID_FD;
361     }
362 }
363 
PrepareMmapBuffer()364 int32_t FastAudioRendererSinkInner::PrepareMmapBuffer()
365 {
366     uint32_t totalBufferInMs = 40; // 5 * (6 + 2 * (1)) = 40ms, the buffer size, not latency.
367     frameSizeInByte_ = PcmFormatToBits(attr_.format) * attr_.channel / PCM_8_BIT;
368     uint32_t reqBufferFrameSize = totalBufferInMs * (attr_.sampleRate / 1000);
369 
370     struct AudioMmapBufferDescriptor desc = {0};
371     int32_t ret = audioRender_->ReqMmapBuffer(audioRender_, reqBufferFrameSize, &desc);
372     CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_OPERATION_FAILED, "ReqMmapBuffer failed, ret:%{public}d", ret);
373     AUDIO_INFO_LOG("AudioMmapBufferDescriptor memoryAddress[%{private}p] memoryFd[%{public}d] totalBufferFrames"
374         "[%{public}d] transferFrameSize[%{public}d] isShareable[%{public}d] offset[%{public}d]", desc.memoryAddress,
375         desc.memoryFd, desc.totalBufferFrames, desc.transferFrameSize, desc.isShareable, desc.offset);
376 
377     bufferFd_ = desc.memoryFd; // fcntl(fd, 1030,3) after dup?
378     int32_t periodFrameMaxSize = 1920000; // 192khz * 10s
379     CHECK_AND_RETURN_RET_LOG(desc.totalBufferFrames >= 0 && desc.transferFrameSize >= 0 &&
380         desc.transferFrameSize <= periodFrameMaxSize, ERR_OPERATION_FAILED,
381         "ReqMmapBuffer invalid values: totalBufferFrames[%{public}d] transferFrameSize[%{public}d]",
382         desc.totalBufferFrames, desc.transferFrameSize);
383     bufferTotalFrameSize_ = static_cast<uint32_t>(desc.totalBufferFrames); // 1440 ~ 3840
384     eachReadFrameSize_ = static_cast<uint32_t>(desc.transferFrameSize); // 240
385 
386     CHECK_AND_RETURN_RET_LOG(frameSizeInByte_ <= ULLONG_MAX / bufferTotalFrameSize_, ERR_OPERATION_FAILED,
387         "BufferSize will overflow!");
388     bufferSize_ = bufferTotalFrameSize_ * frameSizeInByte_;
389 #ifdef DEBUG_DIRECT_USE_HDI
390     privFd_ = dup(bufferFd_);
391     bufferAddresss_ = (char *)mmap(nullptr, bufferSize_, PROT_READ | PROT_WRITE, MAP_SHARED, privFd_, 0);
392     CHECK_AND_RETURN_RET_LOG(bufferAddresss_ != nullptr && bufferAddresss_ != MAP_FAILED, ERR_OPERATION_FAILED,
393         "mmap buffer failed!");
394 #endif
395     return SUCCESS;
396 }
397 
ConvertToHdiFormat(HdiAdapterFormat format)398 AudioFormat FastAudioRendererSinkInner::ConvertToHdiFormat(HdiAdapterFormat format)
399 {
400     AudioFormat hdiFormat;
401     switch (format) {
402         case SAMPLE_U8:
403             hdiFormat = AUDIO_FORMAT_TYPE_PCM_8_BIT;
404             break;
405         case SAMPLE_S16:
406             hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT;
407             break;
408         case SAMPLE_S24:
409             hdiFormat = AUDIO_FORMAT_TYPE_PCM_24_BIT;
410             break;
411         case SAMPLE_S32:
412             hdiFormat = AUDIO_FORMAT_TYPE_PCM_32_BIT;
413             break;
414         default:
415             hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT;
416             break;
417     }
418 
419     return hdiFormat;
420 }
421 
CreateRender(const struct AudioPort & renderPort)422 int32_t FastAudioRendererSinkInner::CreateRender(const struct AudioPort &renderPort)
423 {
424     int32_t ret;
425     struct AudioSampleAttributes param;
426     InitAttrs(param);
427     param.type = attr_.audioStreamFlag == AUDIO_FLAG_VOIP_FAST ? AUDIO_MMAP_VOIP : AUDIO_MMAP_NOIRQ;
428     param.sampleRate = attr_.sampleRate;
429     param.channelCount = attr_.channel;
430     if (param.channelCount == MONO) {
431         param.channelLayout = CH_LAYOUT_MONO;
432     } else if (param.channelCount == STEREO) {
433         param.channelLayout = CH_LAYOUT_STEREO;
434     }
435     param.format = ConvertToHdiFormat(attr_.format);
436     param.frameSize = PcmFormatToBits(attr_.format) * param.channelCount / PCM_8_BIT;
437     param.startThreshold = DEEP_BUFFER_RENDER_PERIOD_SIZE / (param.frameSize); // not passed in hdi
438     AUDIO_INFO_LOG("Type: %{public}d, sampleRate: %{public}u, channel: %{public}d, format: %{public}d, "
439         "device:%{public}d", param.type, param.sampleRate, param.channelCount, param.format, attr_.deviceType);
440     struct AudioDeviceDescriptor deviceDesc;
441     deviceDesc.portId = renderPort.portId;
442     switch (static_cast<DeviceType>(attr_.deviceType)) {
443         case DEVICE_TYPE_EARPIECE:
444             deviceDesc.pins = PIN_OUT_EARPIECE;
445             break;
446         case DEVICE_TYPE_SPEAKER:
447             deviceDesc.pins = PIN_OUT_SPEAKER;
448             break;
449         case DEVICE_TYPE_WIRED_HEADSET:
450             deviceDesc.pins = PIN_OUT_HEADSET;
451             break;
452         case DEVICE_TYPE_USB_HEADSET:
453             deviceDesc.pins = PIN_OUT_USB_EXT;
454             break;
455         case DEVICE_TYPE_BLUETOOTH_SCO:
456             deviceDesc.pins = PIN_OUT_BLUETOOTH_SCO;
457             break;
458         default:
459             deviceDesc.pins = PIN_OUT_SPEAKER;
460             break;
461     }
462     char desc[] = "";
463     deviceDesc.desc = desc;
464     ret = audioAdapter_->CreateRender(audioAdapter_, &deviceDesc, &param, &audioRender_, &renderId_);
465     if (ret != 0 || audioRender_ == nullptr) {
466         AUDIO_ERR_LOG("AudioDeviceCreateRender failed, ret is :%{public}d", ret);
467         audioManager_->UnloadAdapter(audioManager_, adapterDesc_.adapterName);
468         return ERR_NOT_STARTED;
469     }
470 
471     return SUCCESS;
472 }
473 
Init(const IAudioSinkAttr & attr)474 int32_t FastAudioRendererSinkInner::Init(const IAudioSinkAttr &attr)
475 {
476     AUDIO_INFO_LOG("FastAudioRendererSinkInner::Init");
477     attr_ = attr;
478     adapterNameCase_ = attr_.adapterName;  // Set sound card information
479     enum AudioPortDirection port = PORT_OUT; // Set port information
480 
481     CHECK_AND_RETURN_RET_LOG(InitAudioManager() == 0, ERR_NOT_STARTED, "Init audio manager Fail");
482 
483     uint32_t size = MAX_AUDIO_ADAPTER_NUM;
484     AudioAdapterDescriptor descs[MAX_AUDIO_ADAPTER_NUM];
485     if (audioManager_ == nullptr) {
486         AUDIO_ERR_LOG("The audioManager is nullptr!");
487         return ERROR;
488     }
489     int32_t ret = audioManager_->GetAllAdapters(audioManager_,
490         (struct AudioAdapterDescriptor *)&descs, &size);
491     CHECK_AND_RETURN_RET_LOG(size <= MAX_AUDIO_ADAPTER_NUM && size != 0 && ret == 0, ERR_NOT_STARTED,
492         "Get adapters Fail");
493 
494     int32_t index = SwitchAdapterRender((struct AudioAdapterDescriptor *)&descs, adapterNameCase_, port, audioPort_,
495         size);
496     CHECK_AND_RETURN_RET_LOG(index >= 0, ERR_NOT_STARTED, "Switch Adapter Fail");
497 
498     adapterDesc_ = descs[index];
499     int32_t result = audioManager_->LoadAdapter(audioManager_, &adapterDesc_, &audioAdapter_);
500     CHECK_AND_RETURN_RET_LOG(result == 0, ERR_NOT_STARTED, "Load Adapter Fail");
501     CHECK_AND_RETURN_RET_LOG(audioAdapter_ != nullptr, ERR_NOT_STARTED, "Load audio device failed");
502 
503     // Initialization port information, can fill through mode and other parameters
504     ret = audioAdapter_->InitAllPorts(audioAdapter_);
505     CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_NOT_STARTED, "InitAllPorts failed");
506 
507     CHECK_AND_RETURN_RET_LOG(CreateRender(audioPort_) == SUCCESS && PrepareMmapBuffer() == SUCCESS,
508         ERR_NOT_STARTED, "Create render failed, Audio Port: %{public}d", audioPort_.portId);
509 
510     rendererInited_ = true;
511 
512     return SUCCESS;
513 }
514 
PreparePosition()515 void FastAudioRendererSinkInner::PreparePosition()
516 {
517 #ifdef DEBUG_DIRECT_USE_HDI
518     isFirstWrite_ = false;
519     uint64_t frames = 0;
520     int64_t timeSec = 0;
521     int64_t timeNanoSec = 0;
522     GetMmapHandlePosition(frames, timeSec, timeNanoSec); // get first start position
523     int32_t periodByteSize = eachReadFrameSize_ * frameSizeInByte_;
524     CHECK_AND_RETURN_LOG(periodByteSize * writeAheadPeriod_ <= ULLONG_MAX - curReadPos_, "TempPos will overflow!");
525     size_t tempPos = curReadPos_ + periodByteSize * writeAheadPeriod_; // 1 period ahead
526     curWritePos_ = (tempPos < bufferSize_ ? tempPos : tempPos - bufferSize_);
527     AUDIO_INFO_LOG("First render frame start with curReadPos_[%{public}d] curWritePos_[%{public}d]", curReadPos_,
528         curWritePos_);
529 #endif
530 }
531 
RenderFrame(char & data,uint64_t len,uint64_t & writeLen)532 int32_t FastAudioRendererSinkInner::RenderFrame(char &data, uint64_t len, uint64_t &writeLen)
533 {
534 #ifdef DEBUG_DIRECT_USE_HDI
535     int64_t stamp = ClockTime::GetCurNano();
536     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "Audio Render Handle is nullptr!");
537 
538     if (len > (bufferSize_ - eachReadFrameSize_ * frameSizeInByte_ * writeAheadPeriod_)) {
539         writeLen = 0;
540         AUDIO_ERR_LOG("RenderFrame failed,too large len[%{public}" PRIu64 "]!", len);
541         return ERR_WRITE_FAILED;
542     }
543 
544     if (isFirstWrite_) {
545         PreparePosition();
546     }
547 
548     CHECK_AND_RETURN_RET_LOG((curWritePos_ >= 0 && curWritePos_ < bufferSize_), ERR_INVALID_PARAM,
549         "curWritePos_ invalid");
550     char *writePtr = bufferAddresss_ + curWritePos_;
551     uint64_t dataBefore = *(uint64_t *)writePtr;
552     uint64_t dataAfter = 0;
553     uint64_t tempPos = curWritePos_ + len;
554     if (tempPos <= bufferSize_) {
555         if (memcpy_s(writePtr, (bufferSize_ - curWritePos_), static_cast<void *>(&data), len)) {
556             AUDIO_ERR_LOG("copy failed");
557             return ERR_WRITE_FAILED;
558         }
559         dataAfter = *(uint64_t *)writePtr;
560         curWritePos_ = (tempPos == bufferSize_ ? 0 : tempPos);
561     } else {
562         AUDIO_DEBUG_LOG("(tempPos%{public}" PRIu64 ")curWritePos_ + len > bufferSize_", tempPos);
563         size_t writeableSize = bufferSize_ - curWritePos_;
564         if (memcpy_s(writePtr, writeableSize, static_cast<void *>(&data), writeableSize) ||
565             memcpy_s(bufferAddresss_, bufferSize_, static_cast<void *>((char *)&data + writeableSize),
566             (len - writeableSize))) {
567             AUDIO_ERR_LOG("copy failed");
568             return ERR_WRITE_FAILED;
569         }
570         curWritePos_ = len - writeableSize;
571     }
572     writeLen = len;
573 
574     stamp = (ClockTime::GetCurNano() - stamp) / AUDIO_US_PER_SECOND;
575     AUDIO_DEBUG_LOG("Render len[%{public}" PRIu64 "] cost[%{public}" PRId64 "]ms curWritePos[%{public}d] dataBefore"
576         "<%{public}" PRIu64 "> dataAfter<%{public}" PRIu64 ">", len, stamp, curWritePos_, dataBefore, dataAfter);
577     return SUCCESS;
578 #else
579     AUDIO_WARNING_LOG("RenderFrame is not supported.");
580     return ERR_NOT_SUPPORTED;
581 #endif
582 }
583 
GetMaxAmplitude()584 float FastAudioRendererSinkInner::GetMaxAmplitude()
585 {
586     AUDIO_WARNING_LOG("getMaxAmplitude in fast_audio_renderder_sink not support");
587     return 0;
588 }
589 
SetPaPower(int32_t flag)590 int32_t FastAudioRendererSinkInner::SetPaPower(int32_t flag)
591 {
592     (void)flag;
593     return ERR_NOT_SUPPORTED;
594 }
595 
SetPriPaPower()596 int32_t FastAudioRendererSinkInner::SetPriPaPower()
597 {
598     return ERR_NOT_SUPPORTED;
599 }
600 
CheckPositionTime()601 int32_t FastAudioRendererSinkInner::CheckPositionTime()
602 {
603     int32_t tryCount = 50;
604     uint64_t frames = 0;
605     int64_t timeSec = 0;
606     int64_t timeNanoSec = 0;
607     int64_t maxHandleCost = 10000000; // ns
608     int64_t waitTime = 2000000; // 2ms
609     while (tryCount-- > 0) {
610         ClockTime::RelativeSleep(waitTime); // us
611         int32_t ret = GetMmapHandlePosition(frames, timeSec, timeNanoSec);
612         int64_t curTime = ClockTime::GetCurNano();
613         int64_t curSec = curTime / AUDIO_NS_PER_SECOND;
614         int64_t curNanoSec = curTime - curSec * AUDIO_NS_PER_SECOND;
615         if (ret != SUCCESS || curSec != timeSec || curNanoSec - timeNanoSec > maxHandleCost) {
616             AUDIO_WARNING_LOG("CheckPositionTime[%{public}d]:ret %{public}d", tryCount, ret);
617             continue;
618         } else {
619             AUDIO_INFO_LOG("CheckPositionTime end, position and time is ok.");
620             return SUCCESS;
621         }
622     }
623     return ERROR;
624 }
625 
Start(void)626 int32_t FastAudioRendererSinkInner::Start(void)
627 {
628     std::lock_guard<std::mutex> lock(mutex_);
629     Trace trace("FastAudioRendererSinkInner::Start");
630     AudioXCollie sourceXCollie("FastAudioRendererSinkInner::Start", XCOLLIE_TIME_OUT_SECONDS);
631     AUDIO_INFO_LOG("FastAudioRendererSinkInner::Start");
632     int64_t stamp = ClockTime::GetCurNano();
633     int32_t ret;
634 
635     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE,
636         "FastAudioRendererSink::Start audioRender_ null!");
637 
638     if (!started_) {
639         ret = audioRender_->Start(audioRender_);
640         CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_NOT_STARTED,
641             "FastAudioRendererSink::Start failed!");
642         int32_t err = CheckPositionTime();
643         CHECK_AND_RETURN_RET_LOG(err == SUCCESS, ERR_NOT_STARTED,
644             "FastAudioRendererSink::CheckPositionTime failed!");
645     }
646 #ifdef FEATURE_POWER_MANAGER
647     KeepRunningLock();
648 #endif
649     started_ = true;
650     AUDIO_DEBUG_LOG("Start cost[%{public}" PRId64 "]ms", (ClockTime::GetCurNano() - stamp) / AUDIO_US_PER_SECOND);
651     return SUCCESS;
652 }
653 #ifdef FEATURE_POWER_MANAGER
KeepRunningLock()654 void FastAudioRendererSinkInner::KeepRunningLock()
655 {
656     std::shared_ptr<PowerMgr::RunningLock> keepRunningLock;
657     if (runningLockManager_ == nullptr) {
658         keepRunningLock = PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock("AudioFastBackgroundPlay",
659             PowerMgr::RunningLockType::RUNNINGLOCK_BACKGROUND_AUDIO);
660         if (keepRunningLock) {
661             runningLockManager_ = std::make_shared<AudioRunningLockManager<PowerMgr::RunningLock>> (keepRunningLock);
662         }
663     }
664 
665     if (runningLockManager_ != nullptr) {
666         int32_t timeOut = -1; // -1 for lasting.
667         AUDIO_INFO_LOG("keepRunningLock lock result: %{public}d",
668             runningLockManager_->Lock(timeOut)); // -1 for lasting.
669     } else {
670         AUDIO_ERR_LOG("keepRunningLock is null, playback can not work well!");
671     }
672 }
673 #endif
674 
675 #ifdef FEATURE_POWER_MANAGER
KeepRunningUnlock()676 void FastAudioRendererSinkInner::KeepRunningUnlock()
677 {
678     if (runningLockManager_ != nullptr) {
679         AUDIO_INFO_LOG("keepRunningLock unLock");
680         runningLockManager_->UnLock();
681     } else {
682         AUDIO_WARNING_LOG("keepRunningLock is null, playback can not work well!");
683     }
684 }
685 #endif
686 
687 
SetVolume(float left,float right)688 int32_t FastAudioRendererSinkInner::SetVolume(float left, float right)
689 {
690     int32_t ret;
691     float volume;
692 
693     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE,
694         "FastAudioRendererSink::SetVolume failed audioRender_ null");
695 
696     leftVolume_ = left;
697     rightVolume_ = right;
698     if ((leftVolume_ == 0) && (rightVolume_ != 0)) {
699         volume = rightVolume_;
700     } else if ((leftVolume_ != 0) && (rightVolume_ == 0)) {
701         volume = leftVolume_;
702     } else {
703         volume = (leftVolume_ + rightVolume_) / HALF_FACTOR;
704     }
705 
706     AUDIO_INFO_LOG("Set hdi volume to %{public}f", volume);
707     ret = audioRender_->SetVolume(audioRender_, volume);
708     if (ret) {
709         AUDIO_ERR_LOG("FastAudioRendererSink::Set volume failed!");
710     }
711 
712     return ret;
713 }
714 
GetVolume(float & left,float & right)715 int32_t FastAudioRendererSinkInner::GetVolume(float &left, float &right)
716 {
717     left = leftVolume_;
718     right = rightVolume_;
719     return SUCCESS;
720 }
721 
SetVoiceVolume(float volume)722 int32_t FastAudioRendererSinkInner::SetVoiceVolume(float volume)
723 {
724     AUDIO_ERR_LOG("FastAudioRendererSink SetVoiceVolume not supported.");
725     return ERR_NOT_SUPPORTED;
726 }
727 
SetAudioScene(AudioScene audioScene,std::vector<DeviceType> & activeDevices)728 int32_t FastAudioRendererSinkInner::SetAudioScene(AudioScene audioScene, std::vector<DeviceType> &activeDevices)
729 {
730     AUDIO_ERR_LOG("FastAudioRendererSink SetAudioScene not supported.");
731     return ERR_NOT_SUPPORTED;
732 }
733 
SetOutputRoutes(std::vector<DeviceType> & outputDevices)734 int32_t FastAudioRendererSinkInner::SetOutputRoutes(std::vector<DeviceType> &outputDevices)
735 {
736     AUDIO_ERR_LOG("SetOutputRoutes not supported.");
737     return ERR_NOT_SUPPORTED;
738 }
739 
SetAudioParameter(const AudioParamKey key,const std::string & condition,const std::string & value)740 void FastAudioRendererSinkInner::SetAudioParameter(const AudioParamKey key, const std::string &condition,
741     const std::string &value)
742 {
743     AUDIO_ERR_LOG("FastAudioRendererSink SetAudioParameter not supported.");
744     return;
745 }
746 
GetAudioParameter(const AudioParamKey key,const std::string & condition)747 std::string FastAudioRendererSinkInner::GetAudioParameter(const AudioParamKey key, const std::string &condition)
748 {
749     AUDIO_INFO_LOG("GetAudioParameter, key: %{public}d, condition: %{public}s",
750         key, condition.c_str());
751     AudioExtParamKey hdiKey = AudioExtParamKey(key);
752     char value[PARAM_VALUE_LENTH];
753     CHECK_AND_RETURN_RET_LOG(audioAdapter_ != nullptr, "",
754         "GetAudioParameter failed, audioAdapter_ is null");
755     int32_t ret = audioAdapter_->GetExtraParams(audioAdapter_, hdiKey, condition.c_str(),
756         value, PARAM_VALUE_LENTH);
757     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, "",
758         "FRSink GetAudioParameter failed, error code:%{public}d", ret);
759     return value;
760 }
761 
RegisterParameterCallback(IAudioSinkCallback * callback)762 void FastAudioRendererSinkInner::RegisterParameterCallback(IAudioSinkCallback* callback)
763 {
764     AUDIO_ERR_LOG("FastAudioRendererSink RegisterParameterCallback not supported.");
765 }
766 
SetAudioMonoState(bool audioMono)767 void FastAudioRendererSinkInner::SetAudioMonoState(bool audioMono)
768 {
769     AUDIO_ERR_LOG("FastAudioRendererSink SetAudioMonoState not supported.");
770     return;
771 }
772 
SetAudioBalanceValue(float audioBalance)773 void FastAudioRendererSinkInner::SetAudioBalanceValue(float audioBalance)
774 {
775     AUDIO_ERR_LOG("FastAudioRendererSink SetAudioBalanceValue not supported.");
776     return;
777 }
778 
GetPresentationPosition(uint64_t & frames,int64_t & timeSec,int64_t & timeNanoSec)779 int32_t FastAudioRendererSinkInner::GetPresentationPosition(uint64_t& frames, int64_t& timeSec, int64_t& timeNanoSec)
780 {
781     AUDIO_ERR_LOG("FastAudioRendererSink GetPresentationPosition not supported.");
782     return ERR_NOT_SUPPORTED;
783 }
784 
GetTransactionId(uint64_t * transactionId)785 int32_t FastAudioRendererSinkInner::GetTransactionId(uint64_t *transactionId)
786 {
787     AUDIO_ERR_LOG("FastAudioRendererSink %{public}s", __func__);
788     *transactionId = 6; // 6 is the mmap device.
789     return ERR_NOT_SUPPORTED;
790 }
791 
GetLatency(uint32_t * latency)792 int32_t FastAudioRendererSinkInner::GetLatency(uint32_t *latency)
793 {
794     Trace trace("FastAudioRendererSinkInner::GetLatency");
795     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE,
796         "GetLatency failed audio render null");
797 
798     CHECK_AND_RETURN_RET_LOG(latency, ERR_INVALID_PARAM,
799         "GetLatency failed latency null");
800 
801     uint32_t hdiLatency;
802     if (audioRender_->GetLatency(audioRender_, &hdiLatency) == 0) {
803         *latency = hdiLatency;
804         return SUCCESS;
805     } else {
806         return ERR_OPERATION_FAILED;
807     }
808 }
809 
Stop(void)810 int32_t FastAudioRendererSinkInner::Stop(void)
811 {
812     std::lock_guard<std::mutex> lock(mutex_);
813     Trace trace("FastAudioRendererSinkInner::Stop");
814     AudioXCollie sourceXCollie("FastAudioRendererSinkInner::Stop", XCOLLIE_TIME_OUT_SECONDS);
815     AUDIO_INFO_LOG("Stop.");
816 
817     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE,
818         "Stop failed audioRender_ null");
819 #ifdef FEATURE_POWER_MANAGER
820     KeepRunningUnlock();
821 #endif
822 
823     if (started_) {
824         int32_t ret = audioRender_->Stop(audioRender_);
825         CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_OPERATION_FAILED,
826             "Stop failed! ret: %{public}d.", ret);
827     }
828     started_ = false;
829 
830     return SUCCESS;
831 }
832 
Pause(void)833 int32_t FastAudioRendererSinkInner::Pause(void)
834 {
835     int32_t ret;
836 
837     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE,
838         "Pause failed audioRender_ null");
839 
840     CHECK_AND_RETURN_RET_LOG(started_, ERR_OPERATION_FAILED,
841         "Pause invalid state!");
842 
843     if (!paused_) {
844         ret = audioRender_->Pause(audioRender_);
845         CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_OPERATION_FAILED,
846             "Pause failed!");
847     }
848     paused_ = true;
849 
850     return SUCCESS;
851 }
852 
Resume(void)853 int32_t FastAudioRendererSinkInner::Resume(void)
854 {
855     Trace trace("FastAudioRendererSinkInner::Resume");
856     int32_t ret;
857 
858     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE,
859         "Resume failed audioRender_ null");
860 
861     CHECK_AND_RETURN_RET_LOG(started_, ERR_OPERATION_FAILED,
862         "Resume invalid state!");
863 
864     if (paused_) {
865         ret = audioRender_->Resume(audioRender_);
866         CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_OPERATION_FAILED,
867             "Resume failed!");
868     }
869     paused_ = false;
870 
871     return SUCCESS;
872 }
873 
SuspendRenderSink(void)874 int32_t FastAudioRendererSinkInner::SuspendRenderSink(void)
875 {
876     return SUCCESS;
877 }
878 
RestoreRenderSink(void)879 int32_t FastAudioRendererSinkInner::RestoreRenderSink(void)
880 {
881     return SUCCESS;
882 }
883 
Reset(void)884 int32_t FastAudioRendererSinkInner::Reset(void)
885 {
886     Trace trace("FastAudioRendererSinkInner::Reset");
887     int32_t ret;
888 
889     if (started_ && audioRender_ != nullptr) {
890         ret = audioRender_->Flush(audioRender_);
891 
892         CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_OPERATION_FAILED,
893             "Reset failed!");
894     }
895 
896     return SUCCESS;
897 }
898 
Flush(void)899 int32_t FastAudioRendererSinkInner::Flush(void)
900 {
901     Trace trace("FastAudioRendererSinkInner::Flush");
902     int32_t ret;
903 
904     if (started_ && audioRender_ != nullptr) {
905         ret = audioRender_->Flush(audioRender_);
906         CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_OPERATION_FAILED,
907             "Flush failed!");
908     }
909 
910     return SUCCESS;
911 }
912 
ResetOutputRouteForDisconnect(DeviceType device)913 void FastAudioRendererSinkInner::ResetOutputRouteForDisconnect(DeviceType device)
914 {
915 }
916 
UpdateAppsUid(const int32_t appsUid[MAX_MIX_CHANNELS],const size_t size)917 int32_t FastAudioRendererSinkInner::UpdateAppsUid(const int32_t appsUid[MAX_MIX_CHANNELS],
918     const size_t size)
919 {
920     return SUCCESS;
921 }
922 
UpdateAppsUid(const std::vector<int32_t> & appsUid)923 int32_t FastAudioRendererSinkInner::UpdateAppsUid(const std::vector<int32_t> &appsUid)
924 {
925 #ifdef FEATURE_POWER_MANAGER
926     if (!runningLockManager_) {
927         return ERROR;
928     }
929 
930     runningLockManager_->UpdateAppsUid(appsUid.cbegin(), appsUid.cend());
931     runningLockManager_->UpdateAppsUidToPowerMgr();
932 #endif
933 
934     return SUCCESS;
935 }
936 
937 } // namespace AudioStandard
938 } // namespace OHOS
939