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