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