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