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