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