• 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 
SuspendRenderSink(void)195 int32_t RemoteFastAudioRenderSink::SuspendRenderSink(void)
196 {
197     return SUCCESS;
198 }
199 
RestoreRenderSink(void)200 int32_t RemoteFastAudioRenderSink::RestoreRenderSink(void)
201 {
202     return SUCCESS;
203 }
204 
SetAudioParameter(const AudioParamKey key,const std::string & condition,const std::string & value)205 void RemoteFastAudioRenderSink::SetAudioParameter(const AudioParamKey key, const std::string &condition,
206     const std::string &value)
207 {
208 }
209 
GetAudioParameter(const AudioParamKey key,const std::string & condition)210 std::string RemoteFastAudioRenderSink::GetAudioParameter(const AudioParamKey key, const std::string &condition)
211 {
212     return "";
213 }
214 
SetVolume(float left,float right)215 int32_t RemoteFastAudioRenderSink::SetVolume(float left, float right)
216 {
217     leftVolume_ = left;
218     rightVolume_ = right;
219     float volume;
220     if ((leftVolume_ == 0) && (rightVolume_ != 0)) {
221         volume = rightVolume_;
222     } else if ((leftVolume_ != 0) && (rightVolume_ == 0)) {
223         volume = leftVolume_;
224     } else {
225         volume = (leftVolume_ + rightVolume_) / HALF_FACTOR;
226     }
227 
228     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
229     int32_t ret = audioRender_->SetVolume(volume);
230     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "set volume fail, ret: %{public}d", ret);
231 
232     return SUCCESS;
233 }
234 
GetVolume(float & left,float & right)235 int32_t RemoteFastAudioRenderSink::GetVolume(float &left, float &right)
236 {
237     left = leftVolume_;
238     right = rightVolume_;
239     return SUCCESS;
240 }
241 
GetLatency(uint32_t & latency)242 int32_t RemoteFastAudioRenderSink::GetLatency(uint32_t &latency)
243 {
244     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
245 
246     uint32_t hdiLatency;
247     int32_t ret = audioRender_->GetLatency(hdiLatency);
248     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "get latency fail, ret: %{public}d", ret);
249     latency = hdiLatency;
250     return SUCCESS;
251 }
252 
GetTransactionId(uint64_t & transactionId)253 int32_t RemoteFastAudioRenderSink::GetTransactionId(uint64_t &transactionId)
254 {
255     AUDIO_INFO_LOG("not support");
256     return ERR_NOT_SUPPORTED;
257 }
258 
GetPresentationPosition(uint64_t & frames,int64_t & timeSec,int64_t & timeNanoSec)259 int32_t RemoteFastAudioRenderSink::GetPresentationPosition(uint64_t &frames, int64_t &timeSec, int64_t &timeNanoSec)
260 {
261     AUDIO_INFO_LOG("not support");
262     return ERR_NOT_SUPPORTED;
263 }
264 
GetMaxAmplitude(void)265 float RemoteFastAudioRenderSink::GetMaxAmplitude(void)
266 {
267     AUDIO_INFO_LOG("not support");
268     return 0;
269 }
270 
SetAudioMonoState(bool audioMono)271 void RemoteFastAudioRenderSink::SetAudioMonoState(bool audioMono)
272 {
273     AUDIO_INFO_LOG("not support");
274 }
275 
SetAudioBalanceValue(float audioBalance)276 void RemoteFastAudioRenderSink::SetAudioBalanceValue(float audioBalance)
277 {
278     AUDIO_INFO_LOG("not support");
279 }
280 
SetAudioScene(AudioScene audioScene,std::vector<DeviceType> & activeDevices)281 int32_t RemoteFastAudioRenderSink::SetAudioScene(AudioScene audioScene, std::vector<DeviceType> &activeDevices)
282 {
283     AUDIO_INFO_LOG("not support");
284     return SUCCESS;
285 }
286 
GetAudioScene(void)287 int32_t RemoteFastAudioRenderSink::GetAudioScene(void)
288 {
289     AUDIO_INFO_LOG("not support");
290     return ERR_NOT_SUPPORTED;
291 }
292 
UpdateActiveDevice(std::vector<DeviceType> & outputDevices)293 int32_t RemoteFastAudioRenderSink::UpdateActiveDevice(std::vector<DeviceType> &outputDevices)
294 {
295     AUDIO_INFO_LOG("not support");
296     return ERR_NOT_SUPPORTED;
297 }
298 
RegistCallback(uint32_t type,IAudioSinkCallback * callback)299 void RemoteFastAudioRenderSink::RegistCallback(uint32_t type, IAudioSinkCallback *callback)
300 {
301     AUDIO_INFO_LOG("in");
302     callback_.RegistCallback(type, callback);
303 }
304 
ResetActiveDeviceForDisconnect(DeviceType device)305 void RemoteFastAudioRenderSink::ResetActiveDeviceForDisconnect(DeviceType device)
306 {
307     AUDIO_INFO_LOG("not support");
308 }
309 
SetPaPower(int32_t flag)310 int32_t RemoteFastAudioRenderSink::SetPaPower(int32_t flag)
311 {
312     AUDIO_INFO_LOG("not support");
313     return ERR_NOT_SUPPORTED;
314 }
315 
SetPriPaPower(void)316 int32_t RemoteFastAudioRenderSink::SetPriPaPower(void)
317 {
318     AUDIO_INFO_LOG("not support");
319     return ERR_NOT_SUPPORTED;
320 }
321 
UpdateAppsUid(const int32_t appsUid[MAX_MIX_CHANNELS],const size_t size)322 int32_t RemoteFastAudioRenderSink::UpdateAppsUid(const int32_t appsUid[MAX_MIX_CHANNELS], const size_t size)
323 {
324     return ERR_NOT_SUPPORTED;
325 }
326 
UpdateAppsUid(const std::vector<int32_t> & appsUid)327 int32_t RemoteFastAudioRenderSink::UpdateAppsUid(const std::vector<int32_t> &appsUid)
328 {
329     return ERR_NOT_SUPPORTED;
330 }
331 
DumpInfo(std::string & dumpString)332 void RemoteFastAudioRenderSink::DumpInfo(std::string &dumpString)
333 {
334     dumpString += "type: RemoteFastSink\tstarted: " + std::string(started_.load() ? "true" : "false") +
335         "\tdeviceNetworkId: " + deviceNetworkId_ + "\n";
336 }
337 
OnAudioParamChange(const std::string & adapterName,const AudioParamKey key,const std::string & condition,const std::string & value)338 void RemoteFastAudioRenderSink::OnAudioParamChange(const std::string &adapterName, const AudioParamKey key,
339     const std::string &condition, const std::string &value)
340 {
341     AUDIO_INFO_LOG("key: %{public}d, condition: %{public}s, value: %{public}s", key, condition.c_str(), value.c_str());
342     if (key == AudioParamKey::PARAM_KEY_STATE) {
343         DeInit();
344     }
345 
346     callback_.OnRenderSinkParamChange(adapterName, key, condition, value);
347 }
348 
GetMmapBufferInfo(int & fd,uint32_t & totalSizeInframe,uint32_t & spanSizeInframe,uint32_t & byteSizePerFrame)349 int32_t RemoteFastAudioRenderSink::GetMmapBufferInfo(int &fd, uint32_t &totalSizeInframe, uint32_t &spanSizeInframe,
350     uint32_t &byteSizePerFrame)
351 {
352     CHECK_AND_RETURN_RET_LOG(bufferFd_ != INVALID_FD, ERR_INVALID_HANDLE, "buffer fd has been released");
353     fd = bufferFd_;
354     totalSizeInframe = bufferTotalFrameSize_;
355     spanSizeInframe = eachReadFrameSize_;
356     byteSizePerFrame = PcmFormatToBit(attr_.format) * attr_.channel / PCM_8_BIT;
357     return SUCCESS;
358 }
359 
GetMmapHandlePosition(uint64_t & frames,int64_t & timeSec,int64_t & timeNanoSec)360 int32_t RemoteFastAudioRenderSink::GetMmapHandlePosition(uint64_t &frames, int64_t &timeSec, int64_t &timeNanoSec)
361 {
362     CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
363 
364     struct AudioTimeStamp stamp = {};
365     int32_t ret = audioRender_->GetMmapPosition(frames, stamp);
366     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "get mmap position fail, ret: %{public}d", ret);
367     int64_t maxSec = 9223372036; // (9223372036 + 1) * 10^9 > INT64_MAX, seconds should not bigger than it
368     CHECK_AND_RETURN_RET_LOG(stamp.tvSec >= 0 && stamp.tvSec <= maxSec && stamp.tvNSec >= 0 &&
369         stamp.tvNSec <= SECOND_TO_NANOSECOND, ERR_OPERATION_FAILED,
370         "get invalid time, second: %{public}" PRId64 ", nanosecond: %{public}" PRId64, stamp.tvSec, stamp.tvNSec);
371     timeSec = stamp.tvSec;
372     timeNanoSec = stamp.tvNSec;
373     return ret;
374 }
375 
PcmFormatToBit(AudioSampleFormat format)376 uint32_t RemoteFastAudioRenderSink::PcmFormatToBit(AudioSampleFormat format)
377 {
378     switch (format) {
379         case SAMPLE_U8:
380             return PCM_8_BIT;
381         case SAMPLE_S16LE:
382             return PCM_16_BIT;
383         case SAMPLE_S24LE:
384             return PCM_24_BIT;
385         case SAMPLE_S32LE:
386             return PCM_32_BIT;
387         case SAMPLE_F32LE:
388             return PCM_32_BIT;
389         default:
390             AUDIO_DEBUG_LOG("unknown format type, set it to default");
391             return PCM_24_BIT;
392     }
393 }
394 
ConvertToHdiFormat(AudioSampleFormat format)395 AudioFormat RemoteFastAudioRenderSink::ConvertToHdiFormat(AudioSampleFormat format)
396 {
397     AudioFormat hdiFormat;
398     switch (format) {
399         case SAMPLE_U8:
400             hdiFormat = AUDIO_FORMAT_TYPE_PCM_8_BIT;
401             break;
402         case SAMPLE_S16LE:
403             hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT;
404             break;
405         case SAMPLE_S24LE:
406             hdiFormat = AUDIO_FORMAT_TYPE_PCM_24_BIT;
407             break;
408         case SAMPLE_S32LE:
409             hdiFormat = AUDIO_FORMAT_TYPE_PCM_32_BIT;
410             break;
411         default:
412             hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT;
413             break;
414     }
415     return hdiFormat;
416 }
417 
InitAudioSampleAttr(AudioSampleAttributes & param)418 void RemoteFastAudioRenderSink::InitAudioSampleAttr(AudioSampleAttributes &param)
419 {
420     param.channelCount = AUDIO_CHANNELCOUNT;
421     param.sampleRate = AUDIO_SAMPLE_RATE_48K;
422     param.interleaved = 0;
423     param.streamId = static_cast<int32_t>(GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_REMOTE_FAST));
424     param.period = DEEP_BUFFER_RENDER_PERIOD_SIZE;
425     param.isBigEndian = false;
426     param.isSignedData = true;
427     param.stopThreshold = INT_MAX;
428     param.silenceThreshold = 0;
429 
430     param.type = attr_.audioStreamFlag == AUDIO_FLAG_VOIP_FAST ? AUDIO_MMAP_VOIP : AUDIO_MMAP_NOIRQ;
431     param.sampleRate = attr_.sampleRate;
432     param.channelCount = attr_.channel;
433     param.format = ConvertToHdiFormat(attr_.format);
434     param.frameSize = PCM_16_BIT * param.channelCount / PCM_8_BIT;
435     param.startThreshold = DEEP_BUFFER_RENDER_PERIOD_SIZE / (param.frameSize);
436 }
437 
InitDeviceDesc(AudioDeviceDescriptor & deviceDesc)438 void RemoteFastAudioRenderSink::InitDeviceDesc(AudioDeviceDescriptor &deviceDesc)
439 {
440     deviceDesc.pins = PIN_OUT_SPEAKER;
441     deviceDesc.desc = "";
442 }
443 
CreateRender(void)444 int32_t RemoteFastAudioRenderSink::CreateRender(void)
445 {
446     int64_t stamp = ClockTime::GetCurNano();
447     struct AudioSampleAttributes param;
448     struct AudioDeviceDescriptor deviceDesc;
449     InitAudioSampleAttr(param);
450     InitDeviceDesc(deviceDesc);
451 
452     AUDIO_INFO_LOG("create render, format: %{public}u", param.format);
453     HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
454     std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_REMOTE);
455     CHECK_AND_RETURN_RET(deviceManager != nullptr, ERR_INVALID_HANDLE);
456     void *render = deviceManager->CreateRender(deviceNetworkId_, &param, &deviceDesc, hdiRenderId_);
457     audioRender_.ForceSetRefPtr(static_cast<IAudioRender *>(render));
458     CHECK_AND_RETURN_RET(audioRender_ != nullptr, ERR_NOT_STARTED);
459     deviceManager->RegistRenderSinkCallback(deviceNetworkId_, hdiRenderId_, this);
460     if (param.type == AUDIO_MMAP_NOIRQ || param.type == AUDIO_MMAP_VOIP) {
461         PrepareMmapBuffer();
462     }
463 
464     stamp = (ClockTime::GetCurNano() - stamp) / AUDIO_US_PER_SECOND;
465     AUDIO_INFO_LOG("create render success, cost: [%{public}" PRId64 "]ms", stamp);
466     return SUCCESS;
467 }
468 
PrepareMmapBuffer(void)469 int32_t RemoteFastAudioRenderSink::PrepareMmapBuffer(void)
470 {
471     uint32_t totalBufferInMs = 40; // 40: 5 * (6 + 2 * (1)) = 40ms, the buffer size, not latency
472     uint32_t reqBufferFrameSize = totalBufferInMs * (attr_.sampleRate / SECOND_TO_MILLISECOND);
473     struct AudioMmapBufferDescriptor desc;
474 
475     int32_t ret = audioRender_->ReqMmapBuffer(reqBufferFrameSize, desc);
476     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "request mmap buffer fail, ret: %{public}d", ret);
477     AUDIO_INFO_LOG("memoryFd: [%{public}d], totalBufferFrames: [%{public}d], transferFrameSize: [%{public}d], "
478         "isShareable: [%{public}d], offset: [%{public}d]", desc.memoryFd, desc.totalBufferFrames,
479         desc.transferFrameSize, desc.isShareable, desc.offset);
480 
481     bufferFd_ = desc.memoryFd; // fcntl(fd, 1030, 3) after dup?
482     int32_t periodFrameMaxSize = 1920000; // 192khz * 10s
483     CHECK_AND_RETURN_RET_LOG(desc.totalBufferFrames >= 0 && desc.transferFrameSize >= 0 &&
484         desc.transferFrameSize <= periodFrameMaxSize, ERR_OPERATION_FAILED,
485         "invalid value, totalBufferFrames: [%{public}d], transferFrameSize: [%{public}d]", desc.totalBufferFrames,
486         desc.transferFrameSize);
487 
488     uint32_t frameSizeInByte = PcmFormatToBit(attr_.format) * attr_.channel / PCM_8_BIT;
489     bufferTotalFrameSize_ = static_cast<uint32_t>(desc.totalBufferFrames); // 1440 ~ 3840
490     eachReadFrameSize_ = static_cast<uint32_t>(desc.transferFrameSize); // 240
491     CHECK_AND_RETURN_RET_LOG(frameSizeInByte <= ULLONG_MAX / bufferTotalFrameSize_, ERR_OPERATION_FAILED,
492         "buffer size will overflow");
493 
494 #ifdef DEBUG_DIRECT_USE_HDI
495     bufferSize_ = bufferTotalFrameSize_ * frameSizeInByte;
496     ashmemSink_ = new Ashmem(bufferFd_, bufferSize_);
497     AUDIO_INFO_LOG("create ashmem sink succ, ashmemLen: %{public}zu", bufferSize_);
498     bool tmp = ashmemSink_->MapReadAndWriteAshmem();
499     CHECK_AND_RETURN_RET_LOG(tmp, ERR_OPERATION_FAILED, "map ashmem sink fail");
500 #endif
501     return SUCCESS;
502 }
503 
CheckPositionTime(void)504 int32_t RemoteFastAudioRenderSink::CheckPositionTime(void)
505 {
506     int32_t tryCount = MAX_GET_POSITION_TRY_COUNT;
507     uint64_t frames = 0;
508     int64_t timeSec = 0;
509     int64_t timeNanoSec = 0;
510     while (tryCount-- > 0) {
511         ClockTime::RelativeSleep(MAX_GET_POSITION_WAIT_TIME);
512         int32_t ret = GetMmapHandlePosition(frames, timeSec, timeNanoSec);
513         int64_t curTime = ClockTime::GetCurNano();
514         int64_t curSec = curTime / AUDIO_NS_PER_SECOND;
515         int64_t curNanoSec = curTime - curSec * AUDIO_NS_PER_SECOND;
516         if (ret != SUCCESS || curSec != timeSec || curNanoSec - timeNanoSec > MAX_GET_POSITION_HANDLE_TIME) {
517             AUDIO_WARNING_LOG("tryCount: %{public}d, ret: %{public}d", tryCount, ret);
518             continue;
519         } else {
520             AUDIO_INFO_LOG("check succ");
521             return SUCCESS;
522         }
523     }
524     return ERR_OPERATION_FAILED;
525 }
526 
527 } // namespace AudioStandard
528 } // namespace OHOS
529