• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 #define HST_LOG_TAG "MediaSyncManager"
17 
18 #include "media_sync_manager.h"
19 #include <algorithm>
20 #include <cmath>
21 #include "common/log.h"
22 #include "osal/utils/steady_clock.h"
23 
24 namespace {
25 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_SYSTEM_PLAYER, "MediasyncManager" };
26 constexpr int64_t US_TO_MS = 1000; // 1000 us per ms
27 }
28 
29 namespace OHOS {
30 namespace Media {
31 namespace Pipeline {
32 namespace {
33 using namespace std::chrono;
34 constexpr int MEDIA_TUPLE_START_INDEX = 1;
35 constexpr int MEDIA_TUPLE_END_INDEX = 2;
36 }
37 
~MediaSyncManager()38 MediaSyncManager::~MediaSyncManager()
39 {
40     MEDIA_LOG_I("~MediaSyncManager enter.");
41 }
42 
AddSynchronizer(IMediaSynchronizer * syncer)43 void MediaSyncManager::AddSynchronizer(IMediaSynchronizer* syncer)
44 {
45     if (syncer != nullptr) {
46         OHOS::Media::AutoLock lock(syncersMutex_);
47         if (std::find(syncers_.begin(), syncers_.end(), syncer) != syncers_.end()) {
48             return;
49         }
50         syncers_.emplace_back(syncer);
51     }
52 }
53 
RemoveSynchronizer(IMediaSynchronizer * syncer)54 void MediaSyncManager::RemoveSynchronizer(IMediaSynchronizer* syncer)
55 {
56     if (syncer != nullptr) {
57         OHOS::Media::AutoLock lock(syncersMutex_);
58         auto ite = std::find(syncers_.begin(), syncers_.end(), syncer);
59         if (ite != syncers_.end()) {
60             syncers_.erase(ite);
61         }
62     }
63 }
64 
SetPlaybackRate(float rate)65 Status MediaSyncManager::SetPlaybackRate(float rate)
66 {
67     if (rate < 0) {
68         return Status::ERROR_INVALID_PARAMETER;
69     }
70     OHOS::Media::AutoLock lock(clockMutex_);
71     MEDIA_LOG_I("set play rate " PUBLIC_LOG_F, rate);
72     if (currentAbsMediaTime_ == HST_TIME_NONE || currentAnchorClockTime_ == HST_TIME_NONE
73         || currentAnchorMediaTime_ == HST_TIME_NONE || delayTime_ == HST_TIME_NONE) {
74         SimpleUpdatePlayRate(rate);
75         return Status::OK;
76     }
77     int64_t now = GetSystemClock();
78     int64_t currentMedia = SimpleGetMediaTimeExactly(currentAnchorClockTime_, delayTime_, now,
79         currentAnchorMediaTime_, playRate_);
80     int64_t currentAbsMedia = SimpleGetMediaTimeExactly(currentAnchorClockTime_, delayTime_, now,
81         currentAbsMediaTime_, playRate_);
82     SimpleUpdateTimeAnchor(now, currentMedia, currentAbsMedia);
83     SimpleUpdatePlayRate(rate);
84     return Status::OK;
85 }
86 
GetPlaybackRate()87 float MediaSyncManager::GetPlaybackRate()
88 {
89     OHOS::Media::AutoLock lock(clockMutex_);
90     return playRate_;
91 }
92 
SetMediaTimeStartEnd(int32_t trackId,int32_t index,int64_t val)93 void MediaSyncManager::SetMediaTimeStartEnd(int32_t trackId, int32_t index, int64_t val)
94 {
95     auto target = std::find_if(trackMediaTimeRange_.begin(), trackMediaTimeRange_.end(), [&trackId]
96         (const std::tuple<int32_t, int64_t, int64_t>& item) -> bool {
97             return std::get<0>(item) == trackId;
98         });
99     if (target == trackMediaTimeRange_.end()) {
100         trackMediaTimeRange_.emplace_back(std::tuple<int32_t, int64_t, int64_t>(trackId,
101             HST_TIME_NONE, HST_TIME_NONE));
102         if (index == MEDIA_TUPLE_START_INDEX) {
103             std::get<MEDIA_TUPLE_START_INDEX>(*trackMediaTimeRange_.rbegin()) = val;
104         } else if (index == MEDIA_TUPLE_END_INDEX) {
105             std::get<MEDIA_TUPLE_END_INDEX>(*trackMediaTimeRange_.rbegin()) = val;
106         } else {
107             MEDIA_LOG_W("invalid index");
108         }
109     } else {
110         if (index == MEDIA_TUPLE_START_INDEX) {
111             std::get<MEDIA_TUPLE_START_INDEX>(*target) = val;
112         } else if (index == MEDIA_TUPLE_END_INDEX) {
113             std::get<MEDIA_TUPLE_END_INDEX>(*target) = val;
114         } else {
115             MEDIA_LOG_W("invalid index");
116         }
117     }
118 }
119 
SetMediaTimeRangeStart(int64_t startMediaTime,int32_t trackId,IMediaSynchronizer * supplier)120 void MediaSyncManager::SetMediaTimeRangeStart(int64_t startMediaTime, int32_t trackId, IMediaSynchronizer* supplier)
121 {
122     if (!IsSupplierValid(supplier) || supplier->GetPriority() < currentRangeStartPriority_) {
123         return;
124     }
125     currentRangeStartPriority_ = supplier->GetPriority();
126     OHOS::Media::AutoLock lock(clockMutex_);
127     SetMediaTimeStartEnd(trackId, MEDIA_TUPLE_START_INDEX, startMediaTime);
128     if (minRangeStartOfMediaTime_ == HST_TIME_NONE || startMediaTime < minRangeStartOfMediaTime_) {
129         minRangeStartOfMediaTime_ = startMediaTime;
130         MEDIA_LOG_I("set media started at " PUBLIC_LOG_D64, minRangeStartOfMediaTime_);
131     }
132 }
133 
SetMediaTimeRangeEnd(int64_t endMediaTime,int32_t trackId,IMediaSynchronizer * supplier)134 void MediaSyncManager::SetMediaTimeRangeEnd(int64_t endMediaTime, int32_t trackId, IMediaSynchronizer* supplier)
135 {
136     if (!IsSupplierValid(supplier) || supplier->GetPriority() < currentRangeEndPriority_) {
137         return;
138     }
139     currentRangeEndPriority_ = supplier->GetPriority();
140     OHOS::Media::AutoLock lock(clockMutex_);
141     SetMediaTimeStartEnd(trackId, MEDIA_TUPLE_END_INDEX, endMediaTime);
142     if (maxRangeEndOfMediaTime_ == HST_TIME_NONE || endMediaTime > maxRangeEndOfMediaTime_) {
143         maxRangeEndOfMediaTime_ = endMediaTime;
144         MEDIA_LOG_I("set media end at " PUBLIC_LOG_D64, maxRangeEndOfMediaTime_);
145     }
146 }
147 
WaitAllPrerolled(bool prerolled)148 void MediaSyncManager::WaitAllPrerolled(bool prerolled)
149 {
150     allSyncerShouldPrerolled_ = prerolled;
151 }
152 
SetAllSyncShouldWaitNoLock()153 void MediaSyncManager::SetAllSyncShouldWaitNoLock()
154 {
155     if (allSyncerShouldPrerolled_ && !alreadySetSyncersShouldWait_) {
156         prerolledSyncers_.clear();
157         {
158             OHOS::Media::AutoLock lock1(syncersMutex_);
159             if (syncers_.size() > 1) {
160                 for (const auto &supplier: syncers_) {
161                     supplier->WaitAllPrerolled(true);
162                 }
163             }
164         }
165         alreadySetSyncersShouldWait_ = true;
166     }
167 }
168 
Resume()169 Status MediaSyncManager::Resume()
170 {
171     OHOS::Media::AutoLock lock(clockMutex_);
172     // update time anchor after a pause during normal playing
173     if (clockState_ == State::PAUSED && pausedExactAbsMediaTime_ != HST_TIME_NONE
174         && pausedExactMediaTime_ != HST_TIME_NONE && alreadySetSyncersShouldWait_) {
175         SimpleUpdateTimeAnchor(GetSystemClock(), pausedExactMediaTime_, pausedExactAbsMediaTime_);
176         pausedMediaTime_ = HST_TIME_NONE;
177         pausedExactMediaTime_ = HST_TIME_NONE;
178         pausedClockTime_ = HST_TIME_NONE;
179         pausedAbsMediaTime_ = HST_TIME_NONE;
180         pausedExactAbsMediaTime_ = HST_TIME_NONE;
181     }
182     if (clockState_ == State::RESUMED) {
183         return Status::OK;
184     }
185     SetAllSyncShouldWaitNoLock();
186     MEDIA_LOG_I("resume");
187     clockState_ = State::RESUMED;
188     return Status::OK;
189 }
190 
GetSystemClock()191 int64_t MediaSyncManager::GetSystemClock()
192 {
193     return Plugins::HstTime2Us(SteadyClock::GetCurrentTimeNanoSec());
194 }
195 
Pause()196 Status MediaSyncManager::Pause()
197 {
198     OHOS::Media::AutoLock lock(clockMutex_);
199     if (clockState_ == State::PAUSED) {
200         return Status::OK;
201     }
202     pausedClockTime_ = GetSystemClock();
203     if (currentAnchorMediaTime_ != HST_TIME_NONE && currentAnchorClockTime_ != HST_TIME_NONE) {
204         pausedMediaTime_ = SimpleGetMediaTime(currentAnchorClockTime_, delayTime_, pausedClockTime_,
205             currentAnchorMediaTime_, playRate_);
206         pausedExactMediaTime_ = SimpleGetMediaTimeExactly(currentAnchorClockTime_, delayTime_, pausedClockTime_,
207             currentAnchorMediaTime_, playRate_);
208         pausedAbsMediaTime_ = SimpleGetMediaTime(currentAnchorClockTime_, delayTime_, pausedClockTime_,
209             currentAbsMediaTime_, playRate_);
210         pausedExactAbsMediaTime_ = SimpleGetMediaTimeExactly(currentAnchorClockTime_, delayTime_, pausedClockTime_,
211             currentAbsMediaTime_, playRate_);
212     } else {
213         pausedMediaTime_ = HST_TIME_NONE;
214         pausedExactMediaTime_ = HST_TIME_NONE;
215         pausedAbsMediaTime_ = HST_TIME_NONE;
216         pausedExactAbsMediaTime_ = HST_TIME_NONE;
217     }
218     pausedMediaTime_ = ClipMediaTime(pausedMediaTime_);
219     pausedExactMediaTime_ = ClipMediaTime(pausedExactMediaTime_);
220     pausedAbsMediaTime_ = ClipMediaTime(pausedAbsMediaTime_);
221     pausedExactAbsMediaTime_ = ClipMediaTime(pausedExactAbsMediaTime_);
222     MEDIA_LOG_I("pause with clockTime " PUBLIC_LOG_D64 ", mediaTime " PUBLIC_LOG_D64 ", exactMediaTime " PUBLIC_LOG_D64,
223             pausedClockTime_, pausedAbsMediaTime_, pausedExactAbsMediaTime_);
224     clockState_ = State::PAUSED;
225     return Status::OK;
226 }
227 
Seek(int64_t mediaTime,bool isClosest)228 Status MediaSyncManager::Seek(int64_t mediaTime, bool isClosest)
229 {
230     OHOS::Media::AutoLock lock(clockMutex_);
231     if (minRangeStartOfMediaTime_ == HST_TIME_NONE || maxRangeEndOfMediaTime_ == HST_TIME_NONE) {
232         return Status::ERROR_INVALID_OPERATION;
233     }
234     isSeeking_ = true;
235     MEDIA_LOG_I("isSeeking_ mediaTime: %{public}" PRId64, mediaTime);
236     seekingMediaTime_ = mediaTime;
237     alreadySetSyncersShouldWait_ = false; // set already as false
238     SetAllSyncShouldWaitNoLock(); // all suppliers should sync preroll again after seek
239     ResetTimeAnchorNoLock(); // reset the time anchor
240     frameAfterSeeked_ = true;
241     if (isClosest) {
242         firstMediaTimeAfterSeek_ = mediaTime;
243     } else {
244         firstMediaTimeAfterSeek_ = HST_TIME_NONE;
245     }
246     return Status::OK;
247 }
248 
Reset()249 Status MediaSyncManager::Reset()
250 {
251     MEDIA_LOG_I("do Reset");
252     OHOS::Media::AutoLock lock(clockMutex_);
253     clockState_ = State::PAUSED;
254     ResetTimeAnchorNoLock();
255     pausedClockTime_ = HST_TIME_NONE;
256     playRate_ = 1.0f;
257     alreadySetSyncersShouldWait_ = false;
258     allSyncerShouldPrerolled_ = true;
259     isSeeking_ = false;
260     seekCond_.notify_all();
261     seekingMediaTime_ = HST_TIME_NONE;
262     trackMediaTimeRange_.clear();
263     minRangeStartOfMediaTime_ = HST_TIME_NONE;
264     maxRangeEndOfMediaTime_ = HST_TIME_NONE;
265     {
266         OHOS::Media::AutoLock lock1(syncersMutex_);
267         syncers_.clear();
268         prerolledSyncers_.clear();
269     }
270     frameAfterSeeked_ = false;
271     lastReportMediaTime_ = HST_TIME_NONE;
272     firstMediaTimeAfterSeek_ = HST_TIME_NONE;
273     return Status::OK;
274 }
275 
ClipMediaTime(int64_t inTime)276 int64_t MediaSyncManager::ClipMediaTime(int64_t inTime)
277 {
278     int64_t ret = inTime;
279     if (minRangeStartOfMediaTime_ != HST_TIME_NONE && ret < minRangeStartOfMediaTime_) {
280         ret = minRangeStartOfMediaTime_;
281         MEDIA_LOG_D("clip to min media time " PUBLIC_LOG_D64, ret);
282     }
283     if (maxRangeEndOfMediaTime_ != HST_TIME_NONE && ret > maxRangeEndOfMediaTime_) {
284         ret = maxRangeEndOfMediaTime_;
285         MEDIA_LOG_D("clip to max media time " PUBLIC_LOG_D64, ret);
286     }
287     return ret;
288 }
289 
ResetTimeAnchorNoLock()290 void MediaSyncManager::ResetTimeAnchorNoLock()
291 {
292     pausedMediaTime_ = HST_TIME_NONE;
293     pausedExactMediaTime_ = HST_TIME_NONE;
294     pausedAbsMediaTime_ = HST_TIME_NONE;
295     pausedExactAbsMediaTime_ = HST_TIME_NONE;
296     currentSyncerPriority_ = IMediaSynchronizer::NONE;
297     SimpleUpdateTimeAnchor(HST_TIME_NONE, HST_TIME_NONE, HST_TIME_NONE);
298 }
299 
SimpleUpdatePlayRate(float playRate)300 void MediaSyncManager::SimpleUpdatePlayRate(float playRate)
301 {
302     playRate_ = playRate;
303 }
304 
SimpleUpdateTimeAnchor(int64_t clockTime,int64_t mediaTime,int64_t absMediaTime)305 void MediaSyncManager::SimpleUpdateTimeAnchor(int64_t clockTime, int64_t mediaTime, int64_t absMediaTime)
306 {
307     currentAnchorMediaTime_ = mediaTime;
308     currentAnchorClockTime_ = clockTime;
309     currentAbsMediaTime_ = absMediaTime;
310 }
311 
IsSupplierValid(IMediaSynchronizer * supplier)312 bool MediaSyncManager::IsSupplierValid(IMediaSynchronizer* supplier)
313 {
314     OHOS::Media::AutoLock lock(syncersMutex_);
315     return std::find(syncers_.begin(), syncers_.end(), supplier) != syncers_.end();
316 }
317 
UpdateFirstPtsAfterSeek(int64_t mediaTime)318 void MediaSyncManager::UpdateFirstPtsAfterSeek(int64_t mediaTime)
319 {
320     if (firstMediaTimeAfterSeek_ == HST_TIME_NONE) {
321         firstMediaTimeAfterSeek_ = mediaTime;
322         return;
323     }
324     if (mediaTime > firstMediaTimeAfterSeek_) {
325         firstMediaTimeAfterSeek_ = mediaTime;
326     }
327 }
328 
UpdateTimeAnchor(int64_t clockTime,int64_t delayTime,int64_t mediaTime,int64_t absMediaTime,int64_t maxMediaTime,IMediaSynchronizer * supplier)329 bool MediaSyncManager::UpdateTimeAnchor(int64_t clockTime, int64_t delayTime, int64_t mediaTime,
330     int64_t absMediaTime, int64_t maxMediaTime, IMediaSynchronizer* supplier)
331 {
332     OHOS::Media::AutoLock lock(clockMutex_);
333     bool render = true;
334     if (clockTime == HST_TIME_NONE || mediaTime == HST_TIME_NONE
335         || delayTime == HST_TIME_NONE || supplier == nullptr) {
336         return render;
337     }
338     clockTime += delayTime;
339     delayTime_ = delayTime;
340     if (IsSupplierValid(supplier) && supplier->GetPriority() >= currentSyncerPriority_) {
341         currentSyncerPriority_ = supplier->GetPriority();
342         SimpleUpdateTimeAnchor(clockTime, mediaTime, absMediaTime);
343         MEDIA_LOG_D("update time anchor to priority " PUBLIC_LOG_D32 ", mediaTime " PUBLIC_LOG_D64 ", clockTime "
344         PUBLIC_LOG_D64, currentSyncerPriority_, currentAnchorMediaTime_, currentAnchorClockTime_);
345         if (isSeeking_) {
346             MEDIA_LOG_I("leaving seeking_");
347             isSeeking_ = false;
348             UpdateFirstPtsAfterSeek(mediaTime);
349             seekCond_.notify_all();
350         }
351     }
352     return render;
353 }
354 
SimpleGetMediaTime(int64_t anchorClockTime,int64_t delayTime,int64_t nowClockTime,int64_t anchorMediaTime,float playRate)355 int64_t MediaSyncManager::SimpleGetMediaTime(int64_t anchorClockTime, int64_t delayTime, int64_t nowClockTime,
356     int64_t anchorMediaTime, float playRate)
357 {
358     if (std::fabs(playRate - 0) < 1e-9) { // 0 threshold
359         return HST_TIME_NONE;
360     }
361     if (anchorClockTime == HST_TIME_NONE || nowClockTime == HST_TIME_NONE
362         || anchorMediaTime == HST_TIME_NONE || delayTime== HST_TIME_NONE) {
363         return HST_TIME_NONE;
364     }
365     return anchorMediaTime;
366 }
367 
SimpleGetMediaTimeExactly(int64_t anchorClockTime,int64_t delayTime,int64_t nowClockTime,int64_t anchorMediaTime,float playRate)368 int64_t MediaSyncManager::SimpleGetMediaTimeExactly(int64_t anchorClockTime, int64_t delayTime, int64_t nowClockTime,
369     int64_t anchorMediaTime, float playRate)
370 {
371     if (std::fabs(playRate - 0) < 1e-9) { // 0 threshold
372         return HST_TIME_NONE;
373     }
374     if (anchorClockTime == HST_TIME_NONE || nowClockTime == HST_TIME_NONE
375         || anchorMediaTime == HST_TIME_NONE || delayTime== HST_TIME_NONE) {
376         return HST_TIME_NONE;
377     }
378     return anchorMediaTime + (nowClockTime - anchorClockTime + delayTime) * static_cast<double>(playRate) - delayTime;
379 }
380 
SetLastAudioBufferDuration(int64_t durationUs)381 void MediaSyncManager::SetLastAudioBufferDuration(int64_t durationUs)
382 {
383     if (durationUs > 0) {
384         lastAudioBufferDuration_ = durationUs;
385     } else {
386         lastAudioBufferDuration_ = 0; // If buffer duration is unavailable, treat it as 0.
387     }
388 }
389 
ReportLagEvent(int64_t lagDurationMs)390 void MediaSyncManager::ReportLagEvent(int64_t lagDurationMs)
391 {
392     auto eventReceiver = eventReceiver_.lock();
393     FALSE_RETURN(eventReceiver != nullptr);
394     eventReceiver->OnEvent({"SyncManager", EventType::EVENT_STREAM_LAG, lagDurationMs});
395 }
396 
BoundMediaProgress(int64_t newMediaProgressTime)397 int64_t MediaSyncManager::BoundMediaProgress(int64_t newMediaProgressTime)
398 {
399     int64_t maxMediaProgress;
400     if (currentSyncerPriority_ == IMediaSynchronizer::AUDIO_SINK) {
401         maxMediaProgress = currentAnchorMediaTime_ + lastAudioBufferDuration_;
402     } else {
403         maxMediaProgress = currentAnchorMediaTime_;
404     }
405     if (newMediaProgressTime > maxMediaProgress) {
406         ReportLagEvent((newMediaProgressTime - maxMediaProgress) / US_TO_MS);
407         lastReportMediaTime_ = maxMediaProgress; // Avoid media progress go too far when data underrun.
408         MEDIA_LOG_W("Data underrun for %{public}" PRId64 " us, currentSyncerPriority_ is %{public}" PRId32,
409             newMediaProgressTime - maxMediaProgress, currentSyncerPriority_);
410         return lastReportMediaTime_;
411     }
412     if ((newMediaProgressTime >= lastReportMediaTime_) || frameAfterSeeked_) {
413         lastReportMediaTime_ = newMediaProgressTime;
414     } else {
415         MEDIA_LOG_W("Avoid media time to go back without seek, from %{public}" PRId64 " to %{public}" PRId64,
416             lastReportMediaTime_.load(), newMediaProgressTime);
417     }
418     frameAfterSeeked_ = false;
419     return lastReportMediaTime_;
420 }
421 
GetMediaTimeNow()422 int64_t MediaSyncManager::GetMediaTimeNow()
423 {
424     OHOS::Media::AutoLock lock(clockMutex_);
425     if (isSeeking_) {
426         // no need to bound media progress during seek
427         MEDIA_LOG_D("GetMediaTimeNow seekingMediaTime_: %{public}" PRId64, seekingMediaTime_);
428         return seekingMediaTime_;
429     }
430     int64_t currentMediaTime;
431     if (clockState_ == State::PAUSED) {
432         currentMediaTime = pausedExactAbsMediaTime_;
433     } else {
434         currentMediaTime = SimpleGetMediaTimeExactly(currentAnchorClockTime_, delayTime_, GetSystemClock(),
435             currentAbsMediaTime_, playRate_);
436     }
437     if (currentMediaTime == HST_TIME_NONE) {
438         return 0;
439     }
440     if (firstMediaTimeAfterSeek_ != HST_TIME_NONE && currentMediaTime < firstMediaTimeAfterSeek_) {
441         MEDIA_LOG_W("audio has not been rendered since seek");
442         currentMediaTime = firstMediaTimeAfterSeek_;
443     }
444     if (startPts_ != HST_TIME_NONE) {
445         currentMediaTime -= startPts_;
446     }
447     currentMediaTime = BoundMediaProgress(currentMediaTime);
448     MEDIA_LOG_D("GetMediaTimeNow currentMediaTime: %{public}" PRId64, currentMediaTime);
449     return currentMediaTime;
450 }
451 
GetClockTimeNow()452 int64_t MediaSyncManager::GetClockTimeNow()
453 {
454     {
455         OHOS::Media::AutoLock lock(clockMutex_);
456         if (clockState_ == State::PAUSED) {
457             return pausedClockTime_;
458         }
459     }
460     return GetSystemClock();
461 }
SimpleGetClockTime(int64_t anchorClockTime,int64_t nowMediaTime,int64_t anchorMediaTime,float playRate)462 int64_t MediaSyncManager::SimpleGetClockTime(int64_t anchorClockTime, int64_t nowMediaTime,
463     int64_t anchorMediaTime, float playRate)
464 {
465     if (std::fabs(playRate - 0) < 1e-9) { // 0 threshold
466         return HST_TIME_NONE;
467     }
468     if (anchorClockTime == HST_TIME_NONE || nowMediaTime == HST_TIME_NONE || anchorMediaTime == HST_TIME_NONE) {
469         return HST_TIME_NONE;
470     }
471     return anchorClockTime + (nowMediaTime - anchorMediaTime) / static_cast<double>(playRate);
472 }
473 
GetClockTime(int64_t mediaTime)474 int64_t MediaSyncManager::GetClockTime(int64_t mediaTime)
475 {
476     OHOS::Media::AutoLock lock(clockMutex_);
477     if (minRangeStartOfMediaTime_ != HST_TIME_NONE && mediaTime < minRangeStartOfMediaTime_) {
478         MEDIA_LOG_W("media time " PUBLIC_LOG_D64 " less than min media time " PUBLIC_LOG_D64,
479                 mediaTime, minRangeStartOfMediaTime_);
480     }
481     if (maxRangeEndOfMediaTime_ != HST_TIME_NONE && mediaTime > maxRangeEndOfMediaTime_) {
482         MEDIA_LOG_W("media time " PUBLIC_LOG_D64 " exceed max media time " PUBLIC_LOG_D64,
483                 mediaTime, maxRangeEndOfMediaTime_);
484     }
485     return SimpleGetClockTime(currentAnchorClockTime_, mediaTime, currentAnchorMediaTime_, playRate_);
486 }
487 
ReportPrerolled(IMediaSynchronizer * supplier)488 void MediaSyncManager::ReportPrerolled(IMediaSynchronizer* supplier)
489 {
490     if (supplier == nullptr) {
491         return;
492     }
493     if (!allSyncerShouldPrerolled_) {
494         return;
495     }
496     OHOS::Media::AutoLock lock(syncersMutex_);
497     auto ite = std::find(prerolledSyncers_.begin(), prerolledSyncers_.end(), supplier);
498     if (ite != prerolledSyncers_.end()) {
499         MEDIA_LOG_I("supplier already reported prerolled");
500         return;
501     }
502     prerolledSyncers_.emplace_back(supplier);
503     if (prerolledSyncers_.size() == syncers_.size()) {
504         for (const auto& prerolled : prerolledSyncers_) {
505             prerolled->NotifyAllPrerolled();
506         }
507         prerolledSyncers_.clear();
508     }
509 }
510 
GetSeekTime()511 int64_t MediaSyncManager::GetSeekTime()
512 {
513     return seekingMediaTime_;
514 }
515 
InSeeking()516 bool MediaSyncManager::InSeeking()
517 {
518     return isSeeking_;
519 }
520 
SetMediaStartPts(int64_t startPts)521 void MediaSyncManager::SetMediaStartPts(int64_t startPts)
522 {
523     if (startPts_ == HST_TIME_NONE || startPts < startPts_) {
524         startPts_ = startPts;
525     }
526 }
527 
ResetMediaStartPts()528 void MediaSyncManager::ResetMediaStartPts()
529 {
530     startPts_ = HST_TIME_NONE;
531 }
532 
GetMediaStartPts()533 int64_t MediaSyncManager::GetMediaStartPts()
534 {
535     return startPts_;
536 }
537 
ReportEos(IMediaSynchronizer * supplier)538 void MediaSyncManager::ReportEos(IMediaSynchronizer* supplier)
539 {
540     OHOS::Media::AutoLock lock(clockMutex_);
541     if (supplier == nullptr) {
542         return;
543     }
544     if (IsSupplierValid(supplier) && supplier->GetPriority() >= currentSyncerPriority_) {
545         currentSyncerPriority_ = IMediaSynchronizer::NONE;
546         if (isSeeking_) {
547             MEDIA_LOG_I_SHORT("reportEos leaving seeking_");
548             isSeeking_ = false;
549             seekCond_.notify_all();
550         }
551     }
552 }
553 
SetEventReceiver(std::weak_ptr<EventReceiver> eventReceiver)554 void MediaSyncManager::SetEventReceiver(std::weak_ptr<EventReceiver> eventReceiver)
555 {
556     eventReceiver_ = eventReceiver;
557 }
558 } // namespace Pipeline
559 } // namespace Media
560 } // namespace OHOS
561