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 }
27 
28 namespace OHOS {
29 namespace Media {
30 namespace Pipeline {
31 namespace {
32 using namespace std::chrono;
33 constexpr int MEDIA_TUPLE_START_INDEX = 1;
34 constexpr int MEDIA_TUPLE_END_INDEX = 2;
35 }
36 
~MediaSyncManager()37 MediaSyncManager::~MediaSyncManager()
38 {
39     MEDIA_LOG_I("~MediaSyncManager enter.");
40 }
41 
AddSynchronizer(IMediaSynchronizer * syncer)42 void MediaSyncManager::AddSynchronizer(IMediaSynchronizer* syncer)
43 {
44     if (syncer != nullptr) {
45         OHOS::Media::AutoLock lock(syncersMutex_);
46         if (std::find(syncers_.begin(), syncers_.end(), syncer) != syncers_.end()) {
47             return;
48         }
49         syncers_.emplace_back(syncer);
50     }
51 }
52 
RemoveSynchronizer(IMediaSynchronizer * syncer)53 void MediaSyncManager::RemoveSynchronizer(IMediaSynchronizer* syncer)
54 {
55     if (syncer != nullptr) {
56         OHOS::Media::AutoLock lock(syncersMutex_);
57         auto ite = std::find(syncers_.begin(), syncers_.end(), syncer);
58         if (ite != syncers_.end()) {
59             syncers_.erase(ite);
60         }
61     }
62 }
63 
SetPlaybackRate(float rate)64 Status MediaSyncManager::SetPlaybackRate(float rate)
65 {
66     if (rate < 0) {
67         return Status::ERROR_INVALID_PARAMETER;
68     }
69     OHOS::Media::AutoLock lock(clockMutex_);
70     MEDIA_LOG_I("set play rate " PUBLIC_LOG_F, rate);
71     if (currentAbsMediaTime_ == HST_TIME_NONE || currentAnchorClockTime_ == HST_TIME_NONE
72         || currentAnchorMediaTime_ == HST_TIME_NONE || delayTime_ == HST_TIME_NONE) {
73         SimpleUpdatePlayRate(rate);
74         return Status::OK;
75     }
76     int64_t now = GetSystemClock();
77     int64_t currentMedia = SimpleGetMediaTimeExactly(currentAnchorClockTime_, delayTime_, now,
78         currentAnchorMediaTime_, playRate_);
79     int64_t currentAbsMedia = SimpleGetMediaTimeExactly(currentAnchorClockTime_, delayTime_, now,
80         currentAbsMediaTime_, playRate_);
81     SimpleUpdateTimeAnchor(now, currentMedia, currentAbsMedia);
82     SimpleUpdatePlayRate(rate);
83     return Status::OK;
84 }
85 
GetPlaybackRate()86 float MediaSyncManager::GetPlaybackRate()
87 {
88     OHOS::Media::AutoLock lock(clockMutex_);
89     return playRate_;
90 }
91 
SetMediaTimeStartEnd(int32_t trackId,int32_t index,int64_t val)92 void MediaSyncManager::SetMediaTimeStartEnd(int32_t trackId, int32_t index, int64_t val)
93 {
94     auto target = std::find_if(trackMediaTimeRange_.begin(), trackMediaTimeRange_.end(), [&trackId]
95         (const std::tuple<int32_t, int64_t, int64_t>& item) -> bool {
96             return std::get<0>(item) == trackId;
97         });
98     if (target == trackMediaTimeRange_.end()) {
99         trackMediaTimeRange_.emplace_back(std::tuple<int32_t, int64_t, int64_t>(trackId,
100             HST_TIME_NONE, HST_TIME_NONE));
101         if (index == MEDIA_TUPLE_START_INDEX) {
102             std::get<MEDIA_TUPLE_START_INDEX>(*trackMediaTimeRange_.rbegin()) = val;
103         } else if (index == MEDIA_TUPLE_END_INDEX) {
104             std::get<MEDIA_TUPLE_END_INDEX>(*trackMediaTimeRange_.rbegin()) = val;
105         } else {
106             MEDIA_LOG_W("invalid index");
107         }
108     } else {
109         if (index == MEDIA_TUPLE_START_INDEX) {
110             std::get<MEDIA_TUPLE_START_INDEX>(*target) = val;
111         } else if (index == MEDIA_TUPLE_END_INDEX) {
112             std::get<MEDIA_TUPLE_END_INDEX>(*target) = val;
113         } else {
114             MEDIA_LOG_W("invalid index");
115         }
116     }
117 }
118 
SetMediaTimeRangeStart(int64_t startMediaTime,int32_t trackId,IMediaSynchronizer * supplier)119 void MediaSyncManager::SetMediaTimeRangeStart(int64_t startMediaTime, int32_t trackId, IMediaSynchronizer* supplier)
120 {
121     if (!IsSupplierValid(supplier) || supplier->GetPriority() < currentRangeStartPriority_) {
122         return;
123     }
124     currentRangeStartPriority_ = supplier->GetPriority();
125     OHOS::Media::AutoLock lock(clockMutex_);
126     SetMediaTimeStartEnd(trackId, MEDIA_TUPLE_START_INDEX, startMediaTime);
127     if (minRangeStartOfMediaTime_ == HST_TIME_NONE || startMediaTime < minRangeStartOfMediaTime_) {
128         minRangeStartOfMediaTime_ = startMediaTime;
129         MEDIA_LOG_I("set media started at " PUBLIC_LOG_D64, minRangeStartOfMediaTime_);
130     }
131 }
132 
SetMediaTimeRangeEnd(int64_t endMediaTime,int32_t trackId,IMediaSynchronizer * supplier)133 void MediaSyncManager::SetMediaTimeRangeEnd(int64_t endMediaTime, int32_t trackId, IMediaSynchronizer* supplier)
134 {
135     if (!IsSupplierValid(supplier) || supplier->GetPriority() < currentRangeEndPriority_) {
136         return;
137     }
138     currentRangeEndPriority_ = supplier->GetPriority();
139     OHOS::Media::AutoLock lock(clockMutex_);
140     SetMediaTimeStartEnd(trackId, MEDIA_TUPLE_END_INDEX, endMediaTime);
141     if (maxRangeEndOfMediaTime_ == HST_TIME_NONE || endMediaTime > maxRangeEndOfMediaTime_) {
142         maxRangeEndOfMediaTime_ = endMediaTime;
143         MEDIA_LOG_I("set media end at " PUBLIC_LOG_D64, maxRangeEndOfMediaTime_);
144     }
145 }
146 
WaitAllPrerolled(bool prerolled)147 void MediaSyncManager::WaitAllPrerolled(bool prerolled)
148 {
149     allSyncerShouldPrerolled_ = prerolled;
150 }
151 
SetAllSyncShouldWaitNoLock()152 void MediaSyncManager::SetAllSyncShouldWaitNoLock()
153 {
154     if (allSyncerShouldPrerolled_ && !alreadySetSyncersShouldWait_) {
155         prerolledSyncers_.clear();
156         {
157             OHOS::Media::AutoLock lock1(syncersMutex_);
158             if (syncers_.size() > 1) {
159                 for (const auto &supplier: syncers_) {
160                     supplier->WaitAllPrerolled(true);
161                 }
162             }
163         }
164         alreadySetSyncersShouldWait_ = true;
165     }
166 }
167 
Resume()168 Status MediaSyncManager::Resume()
169 {
170     OHOS::Media::AutoLock lock(clockMutex_);
171     // update time anchor after a pause during normal playing
172     if (clockState_ == State::PAUSED && pausedExactAbsMediaTime_ != HST_TIME_NONE
173         && pausedExactMediaTime_ != HST_TIME_NONE && alreadySetSyncersShouldWait_) {
174         SimpleUpdateTimeAnchor(GetSystemClock(), pausedExactMediaTime_, pausedExactAbsMediaTime_);
175         pausedMediaTime_ = HST_TIME_NONE;
176         pausedExactMediaTime_ = HST_TIME_NONE;
177         pausedClockTime_ = HST_TIME_NONE;
178         pausedAbsMediaTime_ = HST_TIME_NONE;
179         pausedExactAbsMediaTime_ = HST_TIME_NONE;
180     }
181     if (clockState_ == State::RESUMED) {
182         return Status::OK;
183     }
184     SetAllSyncShouldWaitNoLock();
185     MEDIA_LOG_I("resume");
186     clockState_ = State::RESUMED;
187     return Status::OK;
188 }
189 
GetSystemClock()190 int64_t MediaSyncManager::GetSystemClock()
191 {
192     return Plugins::HstTime2Us(SteadyClock::GetCurrentTimeNanoSec());
193 }
194 
Pause()195 Status MediaSyncManager::Pause()
196 {
197     OHOS::Media::AutoLock lock(clockMutex_);
198     if (clockState_ == State::PAUSED) {
199         return Status::OK;
200     }
201     pausedClockTime_ = GetSystemClock();
202     if (currentAnchorMediaTime_ != HST_TIME_NONE && currentAnchorClockTime_ != HST_TIME_NONE) {
203         pausedMediaTime_ = SimpleGetMediaTime(currentAnchorClockTime_, delayTime_, pausedClockTime_,
204             currentAnchorMediaTime_, playRate_);
205         pausedExactMediaTime_ = SimpleGetMediaTimeExactly(currentAnchorClockTime_, delayTime_, pausedClockTime_,
206             currentAnchorMediaTime_, playRate_);
207         pausedAbsMediaTime_ = SimpleGetMediaTime(currentAnchorClockTime_, delayTime_, pausedClockTime_,
208             currentAbsMediaTime_, playRate_);
209         pausedExactAbsMediaTime_ = SimpleGetMediaTimeExactly(currentAnchorClockTime_, delayTime_, pausedClockTime_,
210             currentAbsMediaTime_, playRate_);
211     } else {
212         pausedMediaTime_ = HST_TIME_NONE;
213         pausedExactMediaTime_ = HST_TIME_NONE;
214         pausedAbsMediaTime_ = HST_TIME_NONE;
215         pausedExactAbsMediaTime_ = HST_TIME_NONE;
216     }
217     pausedMediaTime_ = ClipMediaTime(pausedMediaTime_);
218     pausedExactMediaTime_ = ClipMediaTime(pausedExactMediaTime_);
219     pausedAbsMediaTime_ = ClipMediaTime(pausedAbsMediaTime_);
220     pausedExactAbsMediaTime_ = ClipMediaTime(pausedExactAbsMediaTime_);
221     MEDIA_LOG_I("pause with clockTime " PUBLIC_LOG_D64 ", mediaTime " PUBLIC_LOG_D64 ", exactMediaTime " PUBLIC_LOG_D64,
222             pausedClockTime_, pausedAbsMediaTime_, pausedExactAbsMediaTime_);
223     clockState_ = State::PAUSED;
224     return Status::OK;
225 }
226 
Seek(int64_t mediaTime,bool isClosest)227 Status MediaSyncManager::Seek(int64_t mediaTime, bool isClosest)
228 {
229     OHOS::Media::AutoLock lock(clockMutex_);
230     if (minRangeStartOfMediaTime_ == HST_TIME_NONE || maxRangeEndOfMediaTime_ == HST_TIME_NONE) {
231         return Status::ERROR_INVALID_OPERATION;
232     }
233     isSeeking_ = true;
234     MEDIA_LOG_I("isSeeking_ mediaTime: %{public}" PRId64, mediaTime);
235     seekingMediaTime_ = mediaTime;
236     alreadySetSyncersShouldWait_ = false; // set already as false
237     SetAllSyncShouldWaitNoLock(); // all suppliers should sync preroll again after seek
238     ResetTimeAnchorNoLock(); // reset the time anchor
239     frameAfterSeeked_ = true;
240     if (isClosest) {
241         firstMediaTimeAfterSeek_ = mediaTime;
242     } else {
243         firstMediaTimeAfterSeek_ = HST_TIME_NONE;
244     }
245     return Status::OK;
246 }
247 
Reset()248 Status MediaSyncManager::Reset()
249 {
250     MEDIA_LOG_I("do Reset");
251     OHOS::Media::AutoLock lock(clockMutex_);
252     clockState_ = State::PAUSED;
253     ResetTimeAnchorNoLock();
254     pausedClockTime_ = HST_TIME_NONE;
255     playRate_ = 1.0f;
256     alreadySetSyncersShouldWait_ = false;
257     allSyncerShouldPrerolled_ = true;
258     isSeeking_ = false;
259     seekCond_.notify_all();
260     seekingMediaTime_ = HST_TIME_NONE;
261     trackMediaTimeRange_.clear();
262     minRangeStartOfMediaTime_ = HST_TIME_NONE;
263     maxRangeEndOfMediaTime_ = HST_TIME_NONE;
264     {
265         OHOS::Media::AutoLock lock1(syncersMutex_);
266         syncers_.clear();
267         prerolledSyncers_.clear();
268     }
269     frameAfterSeeked_ = false;
270     lastReportMediaTime_ = HST_TIME_NONE;
271     firstMediaTimeAfterSeek_ = HST_TIME_NONE;
272     return Status::OK;
273 }
274 
ClipMediaTime(int64_t inTime)275 int64_t MediaSyncManager::ClipMediaTime(int64_t inTime)
276 {
277     int64_t ret = inTime;
278     if (minRangeStartOfMediaTime_ != HST_TIME_NONE && ret < minRangeStartOfMediaTime_) {
279         ret = minRangeStartOfMediaTime_;
280         MEDIA_LOG_D("clip to min media time " PUBLIC_LOG_D64, ret);
281     }
282     if (maxRangeEndOfMediaTime_ != HST_TIME_NONE && ret > maxRangeEndOfMediaTime_) {
283         ret = maxRangeEndOfMediaTime_;
284         MEDIA_LOG_D("clip to max media time " PUBLIC_LOG_D64, ret);
285     }
286     return ret;
287 }
288 
ResetTimeAnchorNoLock()289 void MediaSyncManager::ResetTimeAnchorNoLock()
290 {
291     pausedMediaTime_ = HST_TIME_NONE;
292     pausedExactMediaTime_ = HST_TIME_NONE;
293     pausedAbsMediaTime_ = HST_TIME_NONE;
294     pausedExactAbsMediaTime_ = HST_TIME_NONE;
295     currentSyncerPriority_ = IMediaSynchronizer::NONE;
296     SimpleUpdateTimeAnchor(HST_TIME_NONE, HST_TIME_NONE, HST_TIME_NONE);
297 }
298 
SimpleUpdatePlayRate(float playRate)299 void MediaSyncManager::SimpleUpdatePlayRate(float playRate)
300 {
301     playRate_ = playRate;
302 }
303 
SimpleUpdateTimeAnchor(int64_t clockTime,int64_t mediaTime,int64_t absMediaTime)304 void MediaSyncManager::SimpleUpdateTimeAnchor(int64_t clockTime, int64_t mediaTime, int64_t absMediaTime)
305 {
306     currentAnchorMediaTime_ = mediaTime;
307     currentAnchorClockTime_ = clockTime;
308     currentAbsMediaTime_ = absMediaTime;
309 }
310 
IsSupplierValid(IMediaSynchronizer * supplier)311 bool MediaSyncManager::IsSupplierValid(IMediaSynchronizer* supplier)
312 {
313     OHOS::Media::AutoLock lock(syncersMutex_);
314     return std::find(syncers_.begin(), syncers_.end(), supplier) != syncers_.end();
315 }
316 
UpdateFirstPtsAfterSeek(int64_t mediaTime)317 void MediaSyncManager::UpdateFirstPtsAfterSeek(int64_t mediaTime)
318 {
319     if (firstMediaTimeAfterSeek_ == HST_TIME_NONE) {
320         firstMediaTimeAfterSeek_ = mediaTime;
321         return;
322     }
323     if (mediaTime > firstMediaTimeAfterSeek_) {
324         firstMediaTimeAfterSeek_ = mediaTime;
325     }
326 }
327 
UpdateTimeAnchor(int64_t clockTime,int64_t delayTime,int64_t mediaTime,int64_t absMediaTime,int64_t maxMediaTime,IMediaSynchronizer * supplier)328 bool MediaSyncManager::UpdateTimeAnchor(int64_t clockTime, int64_t delayTime, int64_t mediaTime,
329     int64_t absMediaTime, int64_t maxMediaTime, IMediaSynchronizer* supplier)
330 {
331     OHOS::Media::AutoLock lock(clockMutex_);
332     bool render = true;
333     if (clockTime == HST_TIME_NONE || mediaTime == HST_TIME_NONE
334         || delayTime == HST_TIME_NONE || supplier == nullptr) {
335         return render;
336     }
337     clockTime += delayTime;
338     delayTime_ = delayTime;
339     if (IsSupplierValid(supplier) && supplier->GetPriority() >= currentSyncerPriority_) {
340         currentSyncerPriority_ = supplier->GetPriority();
341         SimpleUpdateTimeAnchor(clockTime, mediaTime, absMediaTime);
342         MEDIA_LOG_D("update time anchor to priority " PUBLIC_LOG_D32 ", mediaTime " PUBLIC_LOG_D64 ", clockTime "
343         PUBLIC_LOG_D64, currentSyncerPriority_, currentAnchorMediaTime_, currentAnchorClockTime_);
344         if (isSeeking_) {
345             if (clockState_ != State::PAUSED) {
346                 MEDIA_LOG_I("leaving seeking_");
347                 isSeeking_ = false;
348                 seekCond_.notify_all();
349             }
350             UpdateFirstPtsAfterSeek(mediaTime);
351         }
352     }
353     return render;
354 }
355 
SimpleGetMediaTime(int64_t anchorClockTime,int64_t delayTime,int64_t nowClockTime,int64_t anchorMediaTime,float playRate)356 int64_t MediaSyncManager::SimpleGetMediaTime(int64_t anchorClockTime, int64_t delayTime, int64_t nowClockTime,
357     int64_t anchorMediaTime, float playRate)
358 {
359     if (std::fabs(playRate - 0) < 1e-9) { // 0 threshold
360         return HST_TIME_NONE;
361     }
362     if (anchorClockTime == HST_TIME_NONE || nowClockTime == HST_TIME_NONE
363         || anchorMediaTime == HST_TIME_NONE || delayTime== HST_TIME_NONE) {
364         return HST_TIME_NONE;
365     }
366     return anchorMediaTime;
367 }
368 
SimpleGetMediaTimeExactly(int64_t anchorClockTime,int64_t delayTime,int64_t nowClockTime,int64_t anchorMediaTime,float playRate)369 int64_t MediaSyncManager::SimpleGetMediaTimeExactly(int64_t anchorClockTime, int64_t delayTime, int64_t nowClockTime,
370     int64_t anchorMediaTime, float playRate)
371 {
372     if (std::fabs(playRate - 0) < 1e-9) { // 0 threshold
373         return HST_TIME_NONE;
374     }
375     if (anchorClockTime == HST_TIME_NONE || nowClockTime == HST_TIME_NONE
376         || anchorMediaTime == HST_TIME_NONE || delayTime== HST_TIME_NONE) {
377         return HST_TIME_NONE;
378     }
379     return anchorMediaTime + (nowClockTime - anchorClockTime + delayTime) * static_cast<double>(playRate) - delayTime;
380 }
381 
SetLastAudioBufferDuration(int64_t durationUs)382 void MediaSyncManager::SetLastAudioBufferDuration(int64_t durationUs)
383 {
384     if (durationUs > 0) {
385         lastAudioBufferDuration_ = durationUs;
386     } else {
387         lastAudioBufferDuration_ = 0; // If buffer duration is unavailable, treat it as 0.
388     }
389 }
390 
ReportLagEvent(int64_t lagDurationMs)391 void MediaSyncManager::ReportLagEvent(int64_t lagDurationMs)
392 {
393     auto eventReceiver = eventReceiver_.lock();
394     FALSE_RETURN(eventReceiver != nullptr);
395     eventReceiver->OnDfxEvent({"SyncManager", DfxEventType::DFX_INFO_PLAYER_STREAM_LAG, lagDurationMs});
396 }
397 
BoundMediaProgress(int64_t newMediaProgressTime)398 int64_t MediaSyncManager::BoundMediaProgress(int64_t newMediaProgressTime)
399 {
400     int64_t maxMediaProgress;
401     if (currentSyncerPriority_ == IMediaSynchronizer::AUDIO_SINK) {
402         maxMediaProgress = currentAnchorMediaTime_ + lastAudioBufferDuration_;
403     } else {
404         maxMediaProgress = currentAnchorMediaTime_;
405     }
406     if (newMediaProgressTime > maxMediaProgress) {
407         lastReportMediaTime_ = maxMediaProgress; // Avoid media progress go too far when data underrun.
408         MEDIA_LOG_W("Media progress lag 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