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 #ifndef HISTREAMER_PIPELINE_CORE_PIPELINE_CLOCK_H
17 #define HISTREAMER_PIPELINE_CORE_PIPELINE_CLOCK_H
18 #include <condition_variable>
19 #include <memory>
20 #include <string>
21 #include <tuple>
22 #include <vector>
23 #include "sink/i_media_sync_center.h"
24 #include "osal/task/mutex.h"
25 #include "osal/task/autolock.h"
26 #include "osal/utils/steady_clock.h"
27 #include "filter/filter.h"
28 #include "common/status.h"
29 #include "plugin/plugin_time.h"
30 
31 namespace OHOS {
32 namespace Media {
33 namespace Pipeline {
34 using namespace OHOS::Media::Plugins;
35 class MediaSyncManager : public IMediaSyncCenter, public std::enable_shared_from_this<MediaSyncManager> {
36 public:
37     MediaSyncManager() = default;
38     virtual ~MediaSyncManager();
39     // interfaces called by hiplayer hirecoder etc.
40     Status SetPlaybackRate(float rate) override;
41     float GetPlaybackRate() override;
42     void WaitAllPrerolled(bool prerolled = true);
43     Status Resume();
44     Status Pause();
45     Status Seek(int64_t mediaTime, bool isClosest = false);
46     Status Reset() override;
47     bool InSeeking();
48     void SetEventReceiver(std::weak_ptr<EventReceiver> eventReceiver);
49     std::condition_variable seekCond_;
50 
51     // interfaces from IMediaSyncCenter
52     void AddSynchronizer(IMediaSynchronizer* syncer) override;
53 
54     void RemoveSynchronizer(IMediaSynchronizer* syncer) override;
55     /**
56      * anchor a media time(pts) with real clock time.
57      *
58      * @param clockTime based on HST_TIME_BASE
59      * @param mediaTime media time based on HST_TIME_BASE
60      * @param maxMediaTime duration of the resource
61      * @param supplier which report this time anchor
62      * @retval current frame Whether rendering is required
63      */
64     bool UpdateTimeAnchor(int64_t clockTime, int64_t delayTime, int64_t mediaTime, int64_t absMediaTime,
65         int64_t maxMediaTime, IMediaSynchronizer* supplier) override;
66 
67     /**
68      * get media time currently
69      * @return media time now
70      */
71     int64_t GetMediaTimeNow() override;
72 
73     /***
74      * get clock time now
75      * @return return clock time based on HST_TIME_BASE
76      */
77     int64_t GetClockTimeNow() override;
78 
79     /**
80      * Get clock time anchored with pts
81      *
82      * @param mediaTime target pts
83      * @return clock time anchored with pts
84      */
85     int64_t GetClockTime(int64_t mediaTime) override;
86 
87     /**
88      * after IMediaSynchronizer has received the first frame, it should call this function to report the receiving of
89      * the first frame.
90      *
91      * @param supplier which report first frame
92      */
93     void ReportPrerolled(IMediaSynchronizer* supplier) override;
94 
95     void ReportEos(IMediaSynchronizer* supplier) override;
96 
97     void SetMediaTimeRangeEnd(int64_t endMediaTime, int32_t trackId, IMediaSynchronizer* supplier) override;
98 
99     void SetMediaTimeRangeStart(int64_t startMediaTime, int32_t trackId, IMediaSynchronizer* supplier) override;
100 
101     void SetStartingTimeMediaUs(int64_t startingTimeMediaUs);
102 
103     int64_t GetSeekTime() override;
104     void ResetTimeAnchorNoLock();
105     void SetMediaStartPts(int64_t startPts) override;
106     void ResetMediaStartPts() override;
107     int64_t GetMediaStartPts() override;
108     void SetLastAudioBufferDuration(int64_t durationUs) override;
109 private:
110     enum class State {
111         RESUMED,
112         PAUSED,
113     };
114     static int64_t GetSystemClock();
115     static int64_t SimpleGetMediaTime(int64_t anchorClockTime, int64_t delayTime, int64_t nowClockTime,
116                                       int64_t anchorMediaTime, float playRate);
117     static int64_t SimpleGetMediaTimeExactly(int64_t anchorClockTime, int64_t delayTime, int64_t nowClockTime,
118                                              int64_t anchorMediaTime, float playRate);
119     static int64_t SimpleGetClockTime(int64_t anchorClockTime, int64_t nowMediaTime, int64_t anchorMediaTime,
120                                       float playRate);
121 
122     bool IsSupplierValid(IMediaSynchronizer* supplier);
123 
124     void SimpleUpdateTimeAnchor(int64_t clockTime, int64_t mediaTime, int64_t absMediaTime);
125     void SimpleUpdatePlayRate(float playRate);
126     void SetMediaTimeStartEnd(int32_t trackId, int32_t index, int64_t val);
127     void SetAllSyncShouldWaitNoLock();
128     int64_t BoundMediaProgress(int64_t newMediaProgressTime);
129     void UpdateFirstPtsAfterSeek(int64_t mediaTime);
130     void ReportLagEvent(int64_t lagDurationMs);
131 
132     int64_t ClipMediaTime(int64_t inTime);
133     OHOS::Media::Mutex clockMutex_ {};
134     State clockState_ {State::PAUSED};
135     int8_t currentSyncerPriority_ {IMediaSynchronizer::NONE};
136     int8_t currentRangeStartPriority_ {IMediaSynchronizer::NONE};
137     int8_t currentRangeEndPriority_ {IMediaSynchronizer::NONE};
138     int64_t currentAnchorClockTime_ {HST_TIME_NONE};
139     int64_t currentAnchorMediaTime_ {HST_TIME_NONE};
140     int64_t currentAbsMediaTime_ {HST_TIME_NONE};
141     int64_t pausedMediaTime_ {HST_TIME_NONE};
142     int64_t pausedExactMediaTime_ {HST_TIME_NONE};
143     int64_t pausedAbsMediaTime_ {HST_TIME_NONE};
144     int64_t pausedExactAbsMediaTime_ {HST_TIME_NONE};
145     int64_t pausedClockTime_ {HST_TIME_NONE};
146     int64_t firstMediaTimeAfterSeek_ {HST_TIME_NONE};
147     int64_t startingTimeMediaUs_ {HST_TIME_NONE};
148 
149     float playRate_ {1.0f};
150     bool alreadySetSyncersShouldWait_ {false};
151     bool allSyncerShouldPrerolled_ {true};
152     bool isSeeking_ {false};
153     int64_t seekingMediaTime_ {HST_TIME_NONE};
154 
155     // trackid start end
156     std::vector<std::tuple<int32_t, int64_t, int64_t>> trackMediaTimeRange_ {};
157     int64_t minRangeStartOfMediaTime_ {HST_TIME_NONE};
158     int64_t maxRangeEndOfMediaTime_ {HST_TIME_NONE};
159 
160     OHOS::Media::Mutex syncersMutex_ {};
161     std::vector<IMediaSynchronizer*> syncers_;
162     std::vector<IMediaSynchronizer*> prerolledSyncers_;
163     int64_t delayTime_ {HST_TIME_NONE};
164     int64_t startPts_ {HST_TIME_NONE};
165     std::atomic<int64_t> lastAudioBufferDuration_ {0};
166     std::atomic<int64_t> lastReportMediaTime_ {HST_TIME_NONE};
167     std::atomic<bool> frameAfterSeeked_ {false};
168     std::weak_ptr<EventReceiver> eventReceiver_;
169 };
170 } // namespace Pipeline
171 } // namespace Media
172 } // namespace OHOS
173 #endif // HISTREAMER_PIPELINE_CORE_PIPELINE_CLOCK_H
174