• 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 "RemoteFastAudioRenderSink"
18 #endif
19 
20 #include "sink/remote_fast_audio_render_sink.h"
21 #include <climits>
22 #include "audio_hdi_log.h"
23 #include "audio_errors.h"
24 #include "audio_utils.h"
25 #include "common/hdi_adapter_info.h"
26 #include "manager/hdi_adapter_manager.h"
27 
28 using namespace OHOS::HDI::DistributedAudio::Audio::V1_0;
29 
30 namespace OHOS {
31 namespace AudioStandard {
RemoteFastAudioRenderSink(const std::string & deviceNetworkId)32 RemoteFastAudioRenderSink::RemoteFastAudioRenderSink(const std::string &deviceNetworkId)
33     : deviceNetworkId_(deviceNetworkId)
34 {
35     AUDIO_DEBUG_LOG("construction");
36 }
37 
~RemoteFastAudioRenderSink()38 RemoteFastAudioRenderSink::~RemoteFastAudioRenderSink()
39 {
40     if (sinkInited_.load()) {
41         DeInit();
42     }
43     AUDIO_DEBUG_LOG("destruction");
44 }
45 
Init(const IAudioSinkAttr & attr)46 int32_t RemoteFastAudioRenderSink::Init(const IAudioSinkAttr &attr)
47 {
48     AUDIO_INFO_LOG("in");
49     attr_ = attr;
50 
51     int32_t ret = CreateRender();
52     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "create render fail");
53 
54     renderInited_.store(true);
55     sinkInited_.store(true);
56     return SUCCESS;
57 }
58 
DeInit(void)59 void RemoteFastAudioRenderSink::DeInit(void)
60 {
61     AUDIO_INFO_LOG("in");
62     sinkInited_.store(false);
63     renderInited_.store(false);
64     started_.store(false);
65     paused_.store(false);
66 
67 #ifdef DEBUG_DIRECT_USE_HDI
68     if (ashmemSink_ != nullptr) {
69         ashmemSink_->UnmapAshmem();
70         ashmemSink_->CloseAshmem();
71         ashmemSink_ = nullptr;
72         AUDIO_INFO_LOG("deinit ashmem sink succ");
73     }
74 #endif
75 
76     if (bufferFd_ != INVALID_FD) {
77         CloseFd(bufferFd_);
78         bufferFd_ = INVALID_FD;
79     }
80 
81     HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
82     std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_REMOTE);
83     CHECK_AND_RETURN(deviceManager != nullptr);
84     deviceManager->DestroyRender(deviceNetworkId_, hdiRenderId_);
85     deviceManager->UnRegistRenderSinkCallback(deviceNetworkId_, hdiRenderId_);
86     audioRender_.ForceSetRefPtr(nullptr);
87     AUDIO_INFO_LOG("end");
88 }
89 
IsInited(void)90 bool RemoteFastAudioRenderSink::IsInited(void)
91 {
92     return sinkInited_.load();
93 }
94 
Start(void)95 int32_t RemoteFastAudioRenderSink::Start(void)
96 {
97     AUDIO_INFO_LOG("in");
98     if (!renderInited_.load()) {
99         int32_t ret = CreateRender();
100         CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "create render fail");
101         renderInited_.store(true);
102     }
103 
104     if (started_.load()) {
105         AUDIO_INFO_LOG("already started");
106         return SUCCESS;
107     }
108 
109     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
110     int32_t ret = audioRender_->Start();
111     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "start fail, ret: %{public}d", ret);
112     ret = CheckPositionTime();
113     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "check position time fail, ret: %{public}d", ret);
114     started_.store(true);
115     return SUCCESS;
116 }
117 
Stop(void)118 int32_t RemoteFastAudioRenderSink::Stop(void)
119 {
120     AUDIO_INFO_LOG("in");
121     if (!started_.load()) {
122         AUDIO_INFO_LOG("already stopped");
123         return SUCCESS;
124     }
125 
126     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
127     int32_t ret = audioRender_->Stop();
128     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "stop fail, ret: %{public}d", ret);
129     started_.store(false);
130     return SUCCESS;
131 }
132 
Resume(void)133 int32_t RemoteFastAudioRenderSink::Resume(void)
134 {
135     AUDIO_INFO_LOG("in");
136     CHECK_AND_RETURN_RET_LOG(started_.load(), ERR_ILLEGAL_STATE, "not start, invalid state");
137 
138     if (!paused_.load()) {
139         AUDIO_INFO_LOG("already resumed");
140         return SUCCESS;
141     }
142 
143     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
144     int32_t ret = audioRender_->Resume();
145     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "resume fail, ret: %{public}d", ret);
146     paused_.store(false);
147     return SUCCESS;
148 }
149 
Pause(void)150 int32_t RemoteFastAudioRenderSink::Pause(void)
151 {
152     AUDIO_INFO_LOG("in");
153     CHECK_AND_RETURN_RET_LOG(started_.load(), ERR_ILLEGAL_STATE, "not start, invalid state");
154 
155     if (paused_.load()) {
156         AUDIO_INFO_LOG("already paused");
157         return SUCCESS;
158     }
159 
160     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
161     int32_t ret = audioRender_->Pause();
162     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "pause fail, ret: %{public}d", ret);
163     paused_.store(true);
164     return SUCCESS;
165 }
166 
Flush(void)167 int32_t RemoteFastAudioRenderSink::Flush(void)
168 {
169     AUDIO_INFO_LOG("in");
170     CHECK_AND_RETURN_RET_LOG(started_.load(), ERR_ILLEGAL_STATE, "not start, invalid state");
171 
172     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
173     int32_t ret = audioRender_->Flush();
174     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "flush fail, ret: %{public}d", ret);
175     return SUCCESS;
176 }
177 
Reset(void)178 int32_t RemoteFastAudioRenderSink::Reset(void)
179 {
180     AUDIO_INFO_LOG("in");
181     CHECK_AND_RETURN_RET_LOG(started_.load(), ERR_ILLEGAL_STATE, "not start, invalid state");
182 
183     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
184     int32_t ret = audioRender_->Flush();
185     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "reset fail, ret: %{public}d", ret);
186     return SUCCESS;
187 }
188 
RenderFrame(char & data,uint64_t len,uint64_t & writeLen)189 int32_t RemoteFastAudioRenderSink::RenderFrame(char &data, uint64_t len, uint64_t &writeLen)
190 {
191     AUDIO_INFO_LOG("not support");
192     return SUCCESS;
193 }
194 
GetVolumeDataCount()195 int64_t RemoteFastAudioRenderSink::GetVolumeDataCount()
196 {
197     AUDIO_WARNING_LOG("not supported");
198     return 0;
199 }
200 
SuspendRenderSink(void)201 int32_t RemoteFastAudioRenderSink::SuspendRenderSink(void)
202 {
203     return SUCCESS;
204 }
205 
RestoreRenderSink(void)206 int32_t RemoteFastAudioRenderSink::RestoreRenderSink(void)
207 {
208     return SUCCESS;
209 }
210 
SetAudioParameter(const AudioParamKey key,const std::string & condition,const std::string & value)211 void RemoteFastAudioRenderSink::SetAudioParameter(const AudioParamKey key, const std::string &condition,
212     const std::string &value)
213 {
214 }
215 
GetAudioParameter(const AudioParamKey key,const std::string & condition)216 std::string RemoteFastAudioRenderSink::GetAudioParameter(const AudioParamKey key, const std::string &condition)
217 {
218     return "";
219 }
220 
SetVolume(float left,float right)221 int32_t RemoteFastAudioRenderSink::SetVolume(float left, float right)
222 {
223     leftVolume_ = left;
224     rightVolume_ = right;
225     float volume;
226     if ((leftVolume_ == 0) && (rightVolume_ != 0)) {
227         volume = rightVolume_;
228     } else if ((leftVolume_ != 0) && (rightVolume_ == 0)) {
229         volume = leftVolume_;
230     } else {
231         volume = (leftVolume_ + rightVolume_) / HALF_FACTOR;
232     }
233 
234     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
235     int32_t ret = audioRender_->SetVolume(volume);
236     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "set volume fail, ret: %{public}d", ret);
237 
238     return SUCCESS;
239 }
240 
GetVolume(float & left,float & right)241 int32_t RemoteFastAudioRenderSink::GetVolume(float &left, float &right)
242 {
243     left = leftVolume_;
244     right = rightVolume_;
245     return SUCCESS;
246 }
247 
GetLatency(uint32_t & latency)248 int32_t RemoteFastAudioRenderSink::GetLatency(uint32_t &latency)
249 {
250     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
251 
252     uint32_t hdiLatency;
253     int32_t ret = audioRender_->GetLatency(hdiLatency);
254     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "get latency fail, ret: %{public}d", ret);
255     latency = hdiLatency;
256     return SUCCESS;
257 }
258 
GetTransactionId(uint64_t & transactionId)259 int32_t RemoteFastAudioRenderSink::GetTransactionId(uint64_t &transactionId)
260 {
261     AUDIO_INFO_LOG("not support");
262     return ERR_NOT_SUPPORTED;
263 }
264 
GetPresentationPosition(uint64_t & frames,int64_t & timeSec,int64_t & timeNanoSec)265 int32_t RemoteFastAudioRenderSink::GetPresentationPosition(uint64_t &frames, int64_t &timeSec, int64_t &timeNanoSec)
266 {
267     AUDIO_INFO_LOG("not support");
268     return ERR_NOT_SUPPORTED;
269 }
270 
GetMaxAmplitude(void)271 float RemoteFastAudioRenderSink::GetMaxAmplitude(void)
272 {
273     AUDIO_INFO_LOG("not support");
274     return 0;
275 }
276 
SetAudioMonoState(bool audioMono)277 void RemoteFastAudioRenderSink::SetAudioMonoState(bool audioMono)
278 {
279     AUDIO_INFO_LOG("not support");
280 }
281 
SetAudioBalanceValue(float audioBalance)282 void RemoteFastAudioRenderSink::SetAudioBalanceValue(float audioBalance)
283 {
284     AUDIO_INFO_LOG("not support");
285 }
286 
SetAudioScene(AudioScene audioScene,bool scoExcludeFlag)287 int32_t RemoteFastAudioRenderSink::SetAudioScene(AudioScene audioScene, bool scoExcludeFlag)
288 {
289     AUDIO_INFO_LOG("not support");
290     return SUCCESS;
291 }
292 
GetAudioScene(void)293 int32_t RemoteFastAudioRenderSink::GetAudioScene(void)
294 {
295     AUDIO_INFO_LOG("not support");
296     return ERR_NOT_SUPPORTED;
297 }
298 
UpdateActiveDevice(std::vector<DeviceType> & outputDevices)299 int32_t RemoteFastAudioRenderSink::UpdateActiveDevice(std::vector<DeviceType> &outputDevices)
300 {
301     AUDIO_INFO_LOG("not support");
302     return ERR_NOT_SUPPORTED;
303 }
304 
RegistCallback(uint32_t type,IAudioSinkCallback * callback)305 void RemoteFastAudioRenderSink::RegistCallback(uint32_t type, IAudioSinkCallback *callback)
306 {
307     AUDIO_INFO_LOG("in");
308     callback_.RegistCallback(type, callback);
309 }
310 
ResetActiveDeviceForDisconnect(DeviceType device)311 void RemoteFastAudioRenderSink::ResetActiveDeviceForDisconnect(DeviceType device)
312 {
313     AUDIO_INFO_LOG("not support");
314 }
315 
SetPaPower(int32_t flag)316 int32_t RemoteFastAudioRenderSink::SetPaPower(int32_t flag)
317 {
318     AUDIO_INFO_LOG("not support");
319     return ERR_NOT_SUPPORTED;
320 }
321 
SetPriPaPower(void)322 int32_t RemoteFastAudioRenderSink::SetPriPaPower(void)
323 {
324     AUDIO_INFO_LOG("not support");
325     return ERR_NOT_SUPPORTED;
326 }
327 
UpdateAppsUid(const int32_t appsUid[MAX_MIX_CHANNELS],const size_t size)328 int32_t RemoteFastAudioRenderSink::UpdateAppsUid(const int32_t appsUid[MAX_MIX_CHANNELS], const size_t size)
329 {
330     return ERR_NOT_SUPPORTED;
331 }
332 
UpdateAppsUid(const std::vector<int32_t> & appsUid)333 int32_t RemoteFastAudioRenderSink::UpdateAppsUid(const std::vector<int32_t> &appsUid)
334 {
335     return ERR_NOT_SUPPORTED;
336 }
337 
DumpInfo(std::string & dumpString)338 void RemoteFastAudioRenderSink::DumpInfo(std::string &dumpString)
339 {
340     dumpString += "type: RemoteFastSink\tstarted: " + std::string(started_.load() ? "true" : "false") +
341         "\tdeviceNetworkId: " + deviceNetworkId_ + "\n";
342 }
343 
OnAudioParamChange(const std::string & adapterName,const AudioParamKey key,const std::string & condition,const std::string & value)344 void RemoteFastAudioRenderSink::OnAudioParamChange(const std::string &adapterName, const AudioParamKey key,
345     const std::string &condition, const std::string &value)
346 {
347     AUDIO_INFO_LOG("key: %{public}d, condition: %{public}s, value: %{public}s", key, condition.c_str(), value.c_str());
348     if (key == AudioParamKey::PARAM_KEY_STATE) {
349         DeInit();
350     }
351 
352     callback_.OnRenderSinkParamChange(adapterName, key, condition, value);
353 }
354 
SetDmDeviceType(uint16_t dmDeviceType,DeviceType deviceType)355 void RemoteFastAudioRenderSink::SetDmDeviceType(uint16_t dmDeviceType, DeviceType deviceType)
356 {
357     AUDIO_INFO_LOG("not support");
358 }
359 
GetMmapBufferInfo(int & fd,uint32_t & totalSizeInframe,uint32_t & spanSizeInframe,uint32_t & byteSizePerFrame,uint32_t & syncInfoSize)360 int32_t RemoteFastAudioRenderSink::GetMmapBufferInfo(int &fd, uint32_t &totalSizeInframe, uint32_t &spanSizeInframe,
361     uint32_t &byteSizePerFrame, uint32_t &syncInfoSize)
362 {
363     CHECK_AND_RETURN_RET_LOG(bufferFd_ != INVALID_FD, ERR_INVALID_HANDLE, "buffer fd has been released");
364     fd = bufferFd_;
365     totalSizeInframe = bufferTotalFrameSize_;
366     spanSizeInframe = eachReadFrameSize_;
367     byteSizePerFrame = PcmFormatToBit(attr_.format) * attr_.channel / PCM_8_BIT;
368     syncInfoSize = syncInfoSize_;
369     return SUCCESS;
370 }
371 
GetMmapHandlePosition(uint64_t & frames,int64_t & timeSec,int64_t & timeNanoSec)372 int32_t RemoteFastAudioRenderSink::GetMmapHandlePosition(uint64_t &frames, int64_t &timeSec, int64_t &timeNanoSec)
373 {
374     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
375 
376     struct AudioTimeStamp stamp = {};
377     int32_t ret = audioRender_->GetMmapPosition(frames, stamp);
378     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "get mmap position fail, ret: %{public}d", ret);
379     int64_t maxSec = 9223372036; // (9223372036 + 1) * 10^9 > INT64_MAX, seconds should not bigger than it
380     CHECK_AND_RETURN_RET_LOG(stamp.tvSec >= 0 && stamp.tvSec <= maxSec && stamp.tvNSec >= 0 &&
381         stamp.tvNSec <= SECOND_TO_NANOSECOND, ERR_OPERATION_FAILED,
382         "get invalid time, second: %{public}" PRId64 ", nanosecond: %{public}" PRId64, stamp.tvSec, stamp.tvNSec);
383     timeSec = stamp.tvSec;
384     timeNanoSec = stamp.tvNSec;
385     return ret;
386 }
387 
PcmFormatToBit(AudioSampleFormat format)388 uint32_t RemoteFastAudioRenderSink::PcmFormatToBit(AudioSampleFormat format)
389 {
390     switch (format) {
391         case SAMPLE_U8:
392             return PCM_8_BIT;
393         case SAMPLE_S16LE:
394             return PCM_16_BIT;
395         case SAMPLE_S24LE:
396             return PCM_24_BIT;
397         case SAMPLE_S32LE:
398             return PCM_32_BIT;
399         case SAMPLE_F32LE:
400             return PCM_32_BIT;
401         default:
402             AUDIO_DEBUG_LOG("unknown format type, set it to default");
403             return PCM_24_BIT;
404     }
405 }
406 
ConvertToHdiFormat(AudioSampleFormat format)407 AudioFormat RemoteFastAudioRenderSink::ConvertToHdiFormat(AudioSampleFormat format)
408 {
409     AudioFormat hdiFormat;
410     switch (format) {
411         case SAMPLE_U8:
412             hdiFormat = AUDIO_FORMAT_TYPE_PCM_8_BIT;
413             break;
414         case SAMPLE_S16LE:
415             hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT;
416             break;
417         case SAMPLE_S24LE:
418             hdiFormat = AUDIO_FORMAT_TYPE_PCM_24_BIT;
419             break;
420         case SAMPLE_S32LE:
421             hdiFormat = AUDIO_FORMAT_TYPE_PCM_32_BIT;
422             break;
423         default:
424             hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT;
425             break;
426     }
427     return hdiFormat;
428 }
429 
InitAudioSampleAttr(AudioSampleAttributes & param)430 void RemoteFastAudioRenderSink::InitAudioSampleAttr(AudioSampleAttributes &param)
431 {
432     param.channelCount = AUDIO_CHANNELCOUNT;
433     param.sampleRate = AUDIO_SAMPLE_RATE_48K;
434     param.interleaved = 0;
435     param.streamId = static_cast<int32_t>(GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_REMOTE_FAST));
436     param.period = DEEP_BUFFER_RENDER_PERIOD_SIZE;
437     param.isBigEndian = false;
438     param.isSignedData = true;
439     param.stopThreshold = INT_MAX;
440     param.silenceThreshold = 0;
441 
442     param.type = attr_.audioStreamFlag == AUDIO_FLAG_VOIP_FAST ? AUDIO_MMAP_VOIP : AUDIO_MMAP_NOIRQ;
443     param.sampleRate = attr_.sampleRate;
444     param.channelCount = attr_.channel;
445     param.format = ConvertToHdiFormat(attr_.format);
446     param.frameSize = PCM_16_BIT * param.channelCount / PCM_8_BIT;
447     if (param.frameSize != 0) {
448         param.startThreshold = DEEP_BUFFER_RENDER_PERIOD_SIZE / (param.frameSize);
449     }
450 }
451 
InitDeviceDesc(AudioDeviceDescriptor & deviceDesc)452 void RemoteFastAudioRenderSink::InitDeviceDesc(AudioDeviceDescriptor &deviceDesc)
453 {
454     deviceDesc.pins = PIN_OUT_SPEAKER;
455     deviceDesc.desc = "";
456 }
457 
CreateRender(void)458 int32_t RemoteFastAudioRenderSink::CreateRender(void)
459 {
460     int64_t stamp = ClockTime::GetCurNano();
461     struct AudioSampleAttributes param;
462     struct AudioDeviceDescriptor deviceDesc;
463     InitAudioSampleAttr(param);
464     InitDeviceDesc(deviceDesc);
465 
466     AUDIO_INFO_LOG("create render, format: %{public}u", param.format);
467     HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
468     std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_REMOTE);
469     CHECK_AND_RETURN_RET(deviceManager != nullptr, ERR_INVALID_HANDLE);
470     void *render = deviceManager->CreateRender(deviceNetworkId_, &param, &deviceDesc, hdiRenderId_);
471     audioRender_.ForceSetRefPtr(static_cast<IAudioRender *>(render));
472     CHECK_AND_RETURN_RET(audioRender_ != nullptr, ERR_NOT_STARTED);
473     deviceManager->RegistRenderSinkCallback(deviceNetworkId_, hdiRenderId_, this);
474     if (param.type == AUDIO_MMAP_NOIRQ || param.type == AUDIO_MMAP_VOIP) {
475         PrepareMmapBuffer();
476     }
477 
478     stamp = (ClockTime::GetCurNano() - stamp) / AUDIO_US_PER_SECOND;
479     AUDIO_INFO_LOG("create render success, cost: [%{public}" PRId64 "]ms", stamp);
480     return SUCCESS;
481 }
482 
PrepareMmapBuffer(void)483 int32_t RemoteFastAudioRenderSink::PrepareMmapBuffer(void)
484 {
485     uint32_t totalBufferInMs = 40; // 40: 5 * (6 + 2 * (1)) = 40ms, the buffer size, not latency
486     uint32_t reqBufferFrameSize = totalBufferInMs * (attr_.sampleRate / SECOND_TO_MILLISECOND);
487     struct AudioMmapBufferDescriptor desc;
488 
489     int32_t ret = audioRender_->ReqMmapBuffer(reqBufferFrameSize, desc);
490     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "request mmap buffer fail, ret: %{public}d", ret);
491     AUDIO_INFO_LOG("memoryFd: [%{public}d], totalBufferFrames: [%{public}d], transferFrameSize: [%{public}d], "
492         "isShareable: [%{public}d], offset: [%{public}d]", desc.memoryFd, desc.totalBufferFrames,
493         desc.transferFrameSize, desc.isShareable, desc.offset);
494 
495     bufferFd_ = desc.memoryFd; // fcntl(fd, 1030, 3) after dup?
496     int32_t periodFrameMaxSize = 1920000; // 192khz * 10s
497     CHECK_AND_RETURN_RET_LOG(desc.totalBufferFrames >= 0 && desc.transferFrameSize >= 0 &&
498         desc.transferFrameSize <= periodFrameMaxSize, ERR_OPERATION_FAILED,
499         "invalid value, totalBufferFrames: [%{public}d], transferFrameSize: [%{public}d]", desc.totalBufferFrames,
500         desc.transferFrameSize);
501 
502     uint32_t frameSizeInByte = PcmFormatToBit(attr_.format) * attr_.channel / PCM_8_BIT;
503     bufferTotalFrameSize_ = static_cast<uint32_t>(desc.totalBufferFrames); // 1440 ~ 3840
504     eachReadFrameSize_ = static_cast<uint32_t>(desc.transferFrameSize); // 240
505     CHECK_AND_RETURN_RET_LOG(frameSizeInByte <= ULLONG_MAX / bufferTotalFrameSize_, ERR_OPERATION_FAILED,
506         "buffer size will overflow");
507 
508 #ifdef DEBUG_DIRECT_USE_HDI
509     bufferSize_ = bufferTotalFrameSize_ * frameSizeInByte;
510     ashmemSink_ = new Ashmem(bufferFd_, bufferSize_);
511     AUDIO_INFO_LOG("create ashmem sink succ, ashmemLen: %{public}zu", bufferSize_);
512     bool tmp = ashmemSink_->MapReadAndWriteAshmem();
513     CHECK_AND_RETURN_RET_LOG(tmp, ERR_OPERATION_FAILED, "map ashmem sink fail");
514 #endif
515     return SUCCESS;
516 }
517 
CheckPositionTime(void)518 int32_t RemoteFastAudioRenderSink::CheckPositionTime(void)
519 {
520     int32_t tryCount = MAX_GET_POSITION_TRY_COUNT;
521     uint64_t frames = 0;
522     int64_t timeSec = 0;
523     int64_t timeNanoSec = 0;
524     while (tryCount-- > 0) {
525         ClockTime::RelativeSleep(MAX_GET_POSITION_WAIT_TIME);
526         int32_t ret = GetMmapHandlePosition(frames, timeSec, timeNanoSec);
527         int64_t curTime = ClockTime::GetCurNano();
528         int64_t curSec = curTime / AUDIO_NS_PER_SECOND;
529         int64_t curNanoSec = curTime - curSec * AUDIO_NS_PER_SECOND;
530         if (ret != SUCCESS || curSec != timeSec || curNanoSec - timeNanoSec > MAX_GET_POSITION_HANDLE_TIME) {
531             AUDIO_WARNING_LOG("tryCount: %{public}d, ret: %{public}d", tryCount, ret);
532             continue;
533         } else {
534             AUDIO_INFO_LOG("check succ");
535             return SUCCESS;
536         }
537     }
538     return ERR_OPERATION_FAILED;
539 }
540 
541 } // namespace AudioStandard
542 } // namespace OHOS
543