• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 #include "audio_haptic_player_impl.h"
17 #include "audio_haptic_sound_normal_impl.h"
18 
19 #include <fcntl.h>
20 
21 #include "audio_haptic_log.h"
22 #include "directory_ex.h"
23 #include "media_errors.h"
24 #include "player.h"
25 
26 namespace {
27 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_AUDIO_NAPI, "AudioHapticSoundNormalImpl"};
28 }
29 
30 namespace OHOS {
31 namespace Media {
32 const int32_t LOAD_WAIT_SECONDS = 2;
33 
AudioHapticSoundNormalImpl(const AudioSource & audioSource,const bool & muteAudio,const AudioStandard::StreamUsage & streamUsage)34 AudioHapticSoundNormalImpl::AudioHapticSoundNormalImpl(const AudioSource& audioSource, const bool &muteAudio,
35     const AudioStandard::StreamUsage &streamUsage)
36     : audioSource_(audioSource),
37       muteAudio_(muteAudio),
38       streamUsage_(streamUsage)
39 {
40 }
41 
~AudioHapticSoundNormalImpl()42 AudioHapticSoundNormalImpl::~AudioHapticSoundNormalImpl()
43 {
44     if (avPlayer_ != nullptr) {
45         (void)ReleaseSoundInternal();
46     }
47 }
48 
LoadAVPlayer()49 int32_t AudioHapticSoundNormalImpl::LoadAVPlayer()
50 {
51     avPlayer_ = PlayerFactory::CreatePlayer();
52     CHECK_AND_RETURN_RET_LOG(avPlayer_ != nullptr, MSERR_INVALID_VAL, "Failed to create AvPlayer instance");
53 
54     avPlayerCallback_ = std::make_shared<AHSoundNormalCallback>(shared_from_this());
55     CHECK_AND_RETURN_RET_LOG(avPlayerCallback_ != nullptr, MSERR_INVALID_VAL, "Failed to create callback object");
56     avPlayer_->SetPlayerCallback(avPlayerCallback_);
57 
58     configuredAudioSource_ = {};
59     playerState_ = AudioHapticPlayerState::STATE_NEW;
60     return MSERR_OK;
61 }
62 
PrepareSound()63 int32_t AudioHapticSoundNormalImpl::PrepareSound()
64 {
65     MEDIA_LOGI("PrepareSound with AVPlayer");
66     std::lock_guard<std::mutex> lock(audioHapticPlayerLock_);
67     int32_t result = LoadAVPlayer();
68     CHECK_AND_RETURN_RET_LOG(result == MSERR_OK && avPlayer_ != nullptr, MSERR_INVALID_VAL,
69         "Audio haptic player(avplayer) instance is null");
70     CHECK_AND_RETURN_RET_LOG(!audioSource_.empty(), MSERR_OPEN_FILE_FAILED, "The audio source is empty");
71     if (audioSource_ != configuredAudioSource_) {
72         return ResetAVPlayer();
73     }
74     return MSERR_OK;
75 }
76 
OpenAudioSource()77 int32_t AudioHapticSoundNormalImpl::OpenAudioSource()
78 {
79     if (fileDes_ != -1) {
80         (void)close(fileDes_);
81         fileDes_ = -1;
82     }
83 
84     auto audioUri = audioSource_.audioUri;
85     auto audioFd = audioSource_.fd;
86     MEDIA_LOGI("Set audio source to avplayer. audioUri [%{public}s] audioFd: [%{public}d]",
87         audioUri.c_str(), audioFd);
88     CHECK_AND_RETURN_RET_LOG(!audioUri.empty() || audioFd > FILE_DESCRIPTOR_INVALID, MSERR_OPEN_FILE_FAILED,
89         "The audio uri is empty or the fd is invalid");
90 
91     if (!audioUri.empty()) {
92         const std::string fdHead = "fd://";
93         if (audioUri.find(fdHead) != std::string::npos) {
94             int32_t fd = atoi(audioUri.substr(fdHead.size()).c_str());
95             CHECK_AND_RETURN_RET_LOG(fd > FILE_DESCRIPTOR_INVALID, MSERR_OPEN_FILE_FAILED,
96                 "Prepare: Failed to extract fd for avplayer.");
97             fileDes_ = dup(fd);
98         } else {
99             std::string absFilePath;
100             CHECK_AND_RETURN_RET_LOG(PathToRealPath(audioUri, absFilePath), MSERR_OPEN_FILE_FAILED,
101                 "file is not real path, file path: %{private}s", audioUri.c_str());
102             CHECK_AND_RETURN_RET_LOG(!absFilePath.empty(), MSERR_OPEN_FILE_FAILED,
103                 "Failed to obtain the canonical path for source path %{public}d %{private}s",
104                 errno, audioUri.c_str());
105             fileDes_ = open(absFilePath.c_str(), O_RDONLY | O_CLOEXEC);
106         }
107     } else {
108         fileDes_ = dup(audioFd);
109     }
110     MEDIA_LOGI("fileDes_ == %{public}d", fileDes_);
111     CHECK_AND_RETURN_RET_LOG(fileDes_ > FILE_DESCRIPTOR_INVALID, MSERR_OPEN_FILE_FAILED,
112         "Prepare: Invalid fileDes for avplayer.");
113     return MSERR_OK;
114 }
115 
ResetAVPlayer()116 int32_t AudioHapticSoundNormalImpl::ResetAVPlayer()
117 {
118     // Reset the player and reload it.
119     MEDIA_LOGI("ResetAVPlayer");
120     (void)avPlayer_->Reset();
121     int32_t ret = OpenAudioSource();
122     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "Failed to open audio source.");
123 
124     ret = avPlayer_->SetSource(fileDes_, audioSource_.offset, audioSource_.length);
125     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_OPEN_FILE_FAILED, "Set source failed %{public}d", ret);
126 
127     Format format;
128     format.PutIntValue(PlayerKeys::CONTENT_TYPE, AudioStandard::CONTENT_TYPE_UNKNOWN);
129     format.PutIntValue(PlayerKeys::STREAM_USAGE, streamUsage_);
130     ret = avPlayer_->SetParameter(format);
131     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "Set stream usage to AVPlayer failed %{public}d", ret);
132 
133     ret = avPlayer_->PrepareAsync();
134     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "Prepare failed %{public}d", ret);
135 
136     std::unique_lock<std::mutex> lockPrepare(prepareMutex_);
137     prepareCond_.wait_for(lockPrepare, std::chrono::seconds(LOAD_WAIT_SECONDS),
138         [this]() { return isPrepared_ || isReleased_ || isUnsupportedFile_; });
139     CHECK_AND_RETURN_RET_LOG(!isReleased_, MSERR_INVALID_OPERATION, "The avplayer is released when it is preparing.");
140     CHECK_AND_RETURN_RET_LOG(!isUnsupportedFile_, MSERR_UNSUPPORT_FILE, "Unsupported file when preparing avplayer.");
141     CHECK_AND_RETURN_RET_LOG(isPrepared_, MSERR_OPEN_FILE_FAILED, "Failed to load audio uri: time out.");
142 
143     // The avplayer has been prepared.
144     float actualVolume = volume_ * (muteAudio_ ? 0 : 1);
145     MEDIA_LOGI("AVPlayer has been prepared. Set volume %{public}f and loop %{public}d.", actualVolume, loop_);
146     (void)avPlayer_->SetVolume(actualVolume, actualVolume);
147     (void)avPlayer_->SetLooping(loop_);
148 
149     configuredAudioSource_ = audioSource_;
150     playerState_ = AudioHapticPlayerState::STATE_PREPARED;
151     return MSERR_OK;
152 }
153 
154 
StartSound(const int32_t & audioHapticSyncId)155 int32_t AudioHapticSoundNormalImpl::StartSound(const int32_t &audioHapticSyncId)
156 {
157     MEDIA_LOGI("StartSound with AVPlayer");
158     std::lock_guard<std::mutex> lock(audioHapticPlayerLock_);
159     CHECK_AND_RETURN_RET_LOG(avPlayer_ != nullptr && playerState_ != AudioHapticPlayerState::STATE_INVALID,
160         MSERR_INVALID_VAL, "StartAVPlayer: no available AVPlayer_");
161     CHECK_AND_RETURN_RET_LOG(!audioSource_.empty(), MSERR_OPEN_FILE_FAILED, "The audio source is invalid");
162 
163     if (playerState_ == AudioHapticPlayerState::STATE_RUNNING) {
164         MEDIA_LOGE("The avplayer has been running. Cannot start again");
165         AudioHapticPlayerImpl::SendHapticPlayerEvent(MSERR_START_FAILED, "AVPLAYER_STATE_RUNNING");
166         return MSERR_START_FAILED;
167     }
168 
169     int32_t ret = MSERR_OK;
170     // Player doesn't support play in stopped state. Hence reinitialise player for making start<-->stop to work
171     if (playerState_ == AudioHapticPlayerState::STATE_STOPPED || audioSource_ != configuredAudioSource_) {
172         ret = ResetAVPlayer();
173         CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "ResetAVPlayer failed %{public}d", ret);
174     }
175 
176     audioHapticSyncId_ = audioHapticSyncId;
177     Format format;
178     format.PutIntValue(PlayerKeys::PLAYER_AUDIO_HAPTICS_SYNC_ID, audioHapticSyncId_);
179     ret = avPlayer_->SetParameter(format);
180     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "Set stream usage to AVPlayer failed %{public}d", ret);
181 
182     ret = avPlayer_->Play();
183     AudioHapticPlayerImpl::SendHapticPlayerEvent(ret, "AVPLAYER_START_FAILED");
184     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_START_FAILED, "Start failed %{public}d", ret);
185 
186     playerState_ = AudioHapticPlayerState::STATE_RUNNING;
187     return MSERR_OK;
188 }
189 
StopSound()190 int32_t AudioHapticSoundNormalImpl::StopSound()
191 {
192     MEDIA_LOGI("StopSound with AVPlayer");
193     std::lock_guard<std::mutex> lock(audioHapticPlayerLock_);
194     CHECK_AND_RETURN_RET_LOG(avPlayer_ != nullptr && playerState_ != AudioHapticPlayerState::STATE_INVALID,
195         MSERR_INVALID_VAL, "StopAVPlayer: no available AVPlayer_");
196 
197     if (playerState_ != AudioHapticPlayerState::STATE_STOPPED) {
198         (void)avPlayer_->Stop();
199     }
200 
201     playerState_ = AudioHapticPlayerState::STATE_STOPPED;
202     return MSERR_OK;
203 }
204 
ReleaseSound()205 int32_t AudioHapticSoundNormalImpl::ReleaseSound()
206 {
207     MEDIA_LOGI("ReleaseSound with AVPlayer");
208     return ReleaseSoundInternal();
209 }
210 
ReleaseSoundInternal()211 int32_t AudioHapticSoundNormalImpl::ReleaseSoundInternal()
212 {
213     MEDIA_LOGI("Enter ReleaseSoundInternal().");
214     {
215         std::lock_guard<std::mutex> lockPrepare(prepareMutex_);
216         isReleased_ = true;
217         prepareCond_.notify_one();
218     }
219     std::lock_guard<std::mutex> lock(audioHapticPlayerLock_);
220     CHECK_AND_RETURN_RET_LOG(playerState_ != AudioHapticPlayerState::STATE_RELEASED, MSERR_OK,
221         "The audio haptic player for normal mode has been released.");
222     ReleaseAVPlayer();
223     playerState_ = AudioHapticPlayerState::STATE_RELEASED;
224     return MSERR_OK;
225 }
226 
ReleaseAVPlayer()227 void AudioHapticSoundNormalImpl::ReleaseAVPlayer()
228 {
229     if (avPlayer_ != nullptr) {
230         (void)avPlayer_->Release();
231         avPlayer_ = nullptr;
232     }
233     avPlayerCallback_ = nullptr;
234     if (fileDes_ != -1) {
235         (void)close(fileDes_);
236         fileDes_ = -1;
237     }
238 }
239 
SetVolume(float volume)240 int32_t AudioHapticSoundNormalImpl::SetVolume(float volume)
241 {
242     MEDIA_LOGI("AudioHapticSoundNormalImpl::SetVolume %{public}f", volume);
243     if (volume < 0.0f || volume > 1.0f) {
244         MEDIA_LOGE("SetVolume: the volume value is invalid.");
245         return MSERR_INVALID_VAL;
246     }
247 
248     std::lock_guard<std::mutex> lock(audioHapticPlayerLock_);
249     int32_t result = MSERR_OK;
250     volume_ = volume;
251 
252     if (playerState_ != AudioHapticPlayerState::STATE_PREPARED &&
253         playerState_ != AudioHapticPlayerState::STATE_RUNNING) {
254         MEDIA_LOGI("Audio haptic player is not prepared or running. No need to modify player");
255         return result;
256     }
257 
258     float actualVolume = volume_ * (muteAudio_ ? 0 : 1);
259     result = avPlayer_->SetVolume(actualVolume, actualVolume);
260     return result;
261 }
262 
SetLoop(bool loop)263 int32_t AudioHapticSoundNormalImpl::SetLoop(bool loop)
264 {
265     MEDIA_LOGI("AudioHapticSoundNormalImpl::SetLoop %{public}d", loop);
266     std::lock_guard<std::mutex> lock(audioHapticPlayerLock_);
267     int32_t result = MSERR_OK;
268     loop_ = loop;
269 
270     if (playerState_ != AudioHapticPlayerState::STATE_PREPARED &&
271         playerState_ != AudioHapticPlayerState::STATE_RUNNING) {
272         MEDIA_LOGI("Audio haptic player is not prepared or running. No need to modify player");
273         return result;
274     }
275 
276     result = avPlayer_->SetLooping(loop_);
277     return result;
278 }
279 
GetAudioCurrentTime()280 int32_t AudioHapticSoundNormalImpl::GetAudioCurrentTime()
281 {
282     if (avPlayer_ == nullptr) {
283         MEDIA_LOGE("GetAudioCurrentTime: avPlayer_ is nullptr. This function is only usable for avPlayer.");
284         return -1;
285     }
286     int32_t currentTime = -1;
287     (void)avPlayer_->GetCurrentTime(currentTime);
288     return currentTime;
289 }
290 
SetAudioHapticSoundCallback(const std::shared_ptr<AudioHapticSoundCallback> & callback)291 int32_t AudioHapticSoundNormalImpl::SetAudioHapticSoundCallback(
292     const std::shared_ptr<AudioHapticSoundCallback> &callback)
293 {
294     if (callback == nullptr) {
295         MEDIA_LOGE("The audio haptic player callback is nullptr.");
296         return MSERR_INVALID_VAL;
297     }
298 
299     std::lock_guard<std::mutex> lock(audioHapticPlayerLock_);
300     audioHapticPlayerCallback_ = callback;
301     return MSERR_OK;
302 }
303 
SetAVPlayerState(AudioHapticPlayerState playerState)304 void AudioHapticSoundNormalImpl::SetAVPlayerState(AudioHapticPlayerState playerState)
305 {
306     MEDIA_LOGI("SetAVPlayerState, state %{public}d", playerState);
307     playerState_ = playerState;
308 }
309 
NotifyPreparedEvent()310 void AudioHapticSoundNormalImpl::NotifyPreparedEvent()
311 {
312     std::lock_guard<std::mutex> lockPrepare(prepareMutex_);
313     isPrepared_ = true;
314     prepareCond_.notify_one();
315 }
316 
NotifyErrorEvent(int32_t errorCode)317 void AudioHapticSoundNormalImpl::NotifyErrorEvent(int32_t errorCode)
318 {
319     MediaServiceErrCode mediaErr = static_cast<MediaServiceErrCode>(errorCode);
320     if (mediaErr == MSERR_UNSUPPORT_FILE) {
321         std::lock_guard<std::mutex> lockPrepare(prepareMutex_);
322         isUnsupportedFile_ = true;
323         prepareCond_.notify_one();
324     }
325 
326     std::shared_ptr<AudioHapticSoundCallback> cb = audioHapticPlayerCallback_.lock();
327     if (cb != nullptr) {
328         MEDIA_LOGI("NotifyFirstFrameEvent for audio haptic player");
329         cb->OnError(errorCode);
330     } else {
331         MEDIA_LOGE("NotifyFirstFrameEvent: audioHapticPlayerCallback_ is nullptr");
332     }
333 }
334 
NotifyFirstFrameEvent(uint64_t latency)335 void AudioHapticSoundNormalImpl::NotifyFirstFrameEvent(uint64_t latency)
336 {
337     std::shared_ptr<AudioHapticSoundCallback> cb = audioHapticPlayerCallback_.lock();
338     if (cb != nullptr) {
339         MEDIA_LOGI("NotifyFirstFrameEvent for audio haptic player");
340         cb->OnFirstFrameWriting(latency);
341     } else {
342         MEDIA_LOGE("NotifyFirstFrameEvent: audioHapticPlayerCallback_ is nullptr");
343     }
344 }
345 
NotifyInterruptEvent(AudioStandard::InterruptEvent & interruptEvent)346 void AudioHapticSoundNormalImpl::NotifyInterruptEvent(AudioStandard::InterruptEvent &interruptEvent)
347 {
348     std::shared_ptr<AudioHapticSoundCallback> cb = audioHapticPlayerCallback_.lock();
349     if (cb != nullptr) {
350         MEDIA_LOGI("NotifyInterruptEvent for audio haptic player");
351         cb->OnInterrupt(interruptEvent);
352     } else {
353         MEDIA_LOGE("NotifyInterruptEvent: audioHapticPlayerCallback_ is nullptr");
354     }
355 }
356 
NotifyEndOfStreamEvent(const bool & isLoop)357 void AudioHapticSoundNormalImpl::NotifyEndOfStreamEvent(const bool &isLoop)
358 {
359     MEDIA_LOGI("NotifyEndOfStreamEvent");
360     if (!isLoop) {
361         playerState_ = AudioHapticPlayerState::STATE_STOPPED;
362     }
363     std::shared_ptr<AudioHapticSoundCallback> cb = audioHapticPlayerCallback_.lock();
364     if (cb != nullptr) {
365         MEDIA_LOGI("NotifyEndOfStreamEvent for audio haptic player");
366         cb->OnEndOfStream();
367     } else {
368         MEDIA_LOGE("NotifyEndOfStreamEvent: audioHapticPlayerCallback_ is nullptr");
369     }
370 }
371 
372 // Callback class symbols
AHSoundNormalCallback(std::shared_ptr<AudioHapticSoundNormalImpl> soundNormalImpl)373 AHSoundNormalCallback::AHSoundNormalCallback(std::shared_ptr<AudioHapticSoundNormalImpl> soundNormalImpl)
374     : soundNormalImpl_(soundNormalImpl) {}
375 
OnError(int32_t errorCode,const std::string & errorMsg)376 void AHSoundNormalCallback::OnError(int32_t errorCode, const std::string &errorMsg)
377 {
378     MEDIA_LOGE("OnError reported from AVPlayer: %{public}d", errorCode);
379     std::shared_ptr<AudioHapticSoundNormalImpl> soundNormalImpl = soundNormalImpl_.lock();
380     if (soundNormalImpl == nullptr) {
381         MEDIA_LOGE("The audio haptic player for normal mode has been released.");
382         return;
383     }
384     soundNormalImpl->NotifyErrorEvent(errorCode);
385 }
386 
OnInfo(Media::PlayerOnInfoType type,int32_t extra,const Media::Format & infoBody)387 void AHSoundNormalCallback::OnInfo(Media::PlayerOnInfoType type, int32_t extra, const Media::Format &infoBody)
388 {
389     if (type == INFO_TYPE_STATE_CHANGE) {
390         MEDIA_LOGI("OnInfo: state change reported from AVPlayer.");
391         HandleStateChangeEvent(extra, infoBody);
392     } else if (type == INFO_TYPE_INTERRUPT_EVENT) {
393         MEDIA_LOGI("OnInfo: interrupt event reported from AVPlayer.");
394         HandleAudioInterruptEvent(extra, infoBody);
395     } else if (type == INFO_TYPE_AUDIO_FIRST_FRAME) {
396         MEDIA_LOGI("OnInfo: first frame event reported from AVPlayer.");
397         HandleAudioFirstFrameEvent(extra, infoBody);
398     } else if (type == INFO_TYPE_EOS) {
399         HandleEOSEvent(extra, infoBody);
400     } else {
401         return;
402     }
403 }
404 
HandleStateChangeEvent(int32_t extra,const Format & infoBody)405 void AHSoundNormalCallback::HandleStateChangeEvent(int32_t extra, const Format &infoBody)
406 {
407     MEDIA_LOGI("HandleStateChangeEvent from AVPlayer");
408     PlayerStates avPlayerState = static_cast<PlayerStates>(extra);
409     switch (avPlayerState) {
410         case PLAYER_STATE_ERROR:
411             playerState_ = AudioHapticPlayerState::STATE_INVALID;
412             break;
413         case PLAYER_IDLE:
414         case PLAYER_INITIALIZED:
415         case PLAYER_PREPARING:
416             playerState_ = AudioHapticPlayerState::STATE_NEW;
417             break;
418         case PLAYER_PREPARED:
419             playerState_ = AudioHapticPlayerState::STATE_PREPARED;
420             break;
421         case PLAYER_STARTED:
422             playerState_ = AudioHapticPlayerState::STATE_RUNNING;
423             break;
424         case PLAYER_PAUSED:
425             playerState_ = AudioHapticPlayerState::STATE_PAUSED;
426             break;
427         case PLAYER_STOPPED:
428         case PLAYER_PLAYBACK_COMPLETE:
429             playerState_ = AudioHapticPlayerState::STATE_STOPPED;
430             break;
431         default:
432             break;
433     }
434     std::shared_ptr<AudioHapticSoundNormalImpl> soundNormalImpl = soundNormalImpl_.lock();
435     if (soundNormalImpl == nullptr) {
436         MEDIA_LOGE("The audio haptic player for normal mode has been released.");
437         return;
438     }
439     soundNormalImpl->SetAVPlayerState(playerState_);
440 
441     if (avPlayerState == PLAYER_PREPARED) {
442         soundNormalImpl->NotifyPreparedEvent();
443     }
444 }
445 
HandleAudioInterruptEvent(int32_t extra,const Format & infoBody)446 void AHSoundNormalCallback::HandleAudioInterruptEvent(int32_t extra, const Format &infoBody)
447 {
448     MEDIA_LOGI("HandleAudioInterruptEvent from AVPlayer");
449     AudioStandard::InterruptEvent interruptEvent;
450     int32_t eventTypeValue = 0;
451     int32_t forceTypeValue = 0;
452     int32_t hintTypeValue = 0;
453     (void)infoBody.GetIntValue(PlayerKeys::AUDIO_INTERRUPT_TYPE, eventTypeValue);
454     (void)infoBody.GetIntValue(PlayerKeys::AUDIO_INTERRUPT_FORCE, forceTypeValue);
455     (void)infoBody.GetIntValue(PlayerKeys::AUDIO_INTERRUPT_HINT, hintTypeValue);
456     interruptEvent.eventType = static_cast<AudioStandard::InterruptType>(eventTypeValue);
457     interruptEvent.forceType = static_cast<AudioStandard::InterruptForceType>(forceTypeValue);
458     interruptEvent.hintType = static_cast<AudioStandard::InterruptHint>(hintTypeValue);
459 
460     std::shared_ptr<AudioHapticSoundNormalImpl> soundNormalImpl = soundNormalImpl_.lock();
461     if (soundNormalImpl == nullptr) {
462         MEDIA_LOGE("The audio haptic player for normal mode has been released.");
463         return;
464     }
465     soundNormalImpl->NotifyInterruptEvent(interruptEvent);
466 }
467 
HandleAudioFirstFrameEvent(int32_t extra,const Format & infoBody)468 void AHSoundNormalCallback::HandleAudioFirstFrameEvent(int32_t extra, const Format &infoBody)
469 {
470     int64_t value = 0;
471     (void)infoBody.GetLongValue(PlayerKeys::AUDIO_FIRST_FRAME, value);
472     uint64_t latency = static_cast<uint64_t>(value);
473     MEDIA_LOGI("HandleAudioFirstFrameEvent from AVPlayer. Latency %{public}" PRIu64 "", latency);
474     std::shared_ptr<AudioHapticSoundNormalImpl> soundNormalImpl = soundNormalImpl_.lock();
475     if (soundNormalImpl == nullptr) {
476         MEDIA_LOGE("The audio haptic player for normal mode has been released.");
477         return;
478     }
479     soundNormalImpl->NotifyFirstFrameEvent(latency);
480 }
481 
HandleEOSEvent(int32_t extra,const Format & infoBody)482 void AHSoundNormalCallback::HandleEOSEvent(int32_t extra, const Format &infoBody)
483 {
484     MEDIA_LOGI("AHSoundNormalCallback::HandleEOSEvent from AVPlayer");
485 
486     std::shared_ptr<AudioHapticSoundNormalImpl> soundNormalImpl = soundNormalImpl_.lock();
487     if (soundNormalImpl == nullptr) {
488         MEDIA_LOGE("The audio haptic player for normal mode has been released.");
489         return;
490     }
491     soundNormalImpl->NotifyEndOfStreamEvent(static_cast<bool>(extra));
492 }
493 
494 } // namesapce AudioStandard
495 } // namespace OHOS