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