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 ¶m)
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_, ¶m, &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