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 OHOS_OUTPUT_CONTROLLER_H
17 #define OHOS_OUTPUT_CONTROLLER_H
18 #include <atomic>
19 #include <condition_variable>
20 #include <mutex>
21 #include <queue>
22 #include <thread>
23 #include <memory>
24 #include "output_controller_listener.h"
25 #include "time_statistician.h"
26 #include "output_controller_constants.h"
27 #include "plugin_buffer.h"
28 #include "plugin_types.h"
29 #include "av_trans_log.h"
30 #include "av_trans_utils.h"
31 #include "av_sync_utils.h"
32 #include "event_handler.h"
33 
34 namespace OHOS {
35 namespace DistributedHardware {
36 using namespace OHOS::Media;
37 using namespace OHOS::Media::Plugin;
38 class OutputController {
39 public:
40     virtual ~OutputController();
41     virtual void PrepareSmooth();
42     virtual void PrepareSync();
43     virtual void InitBaseline(const int64_t timeStampBaseline, const int64_t clockBaseline);
44     virtual void InitTimeStatistician();
45     virtual int32_t NotifyOutput(const std::shared_ptr<Plugin::Buffer>& data);
46 
47 public:
48     enum class ControlStatus {
49         START,
50         STOP,
51         RELEASE,
52         STARTED,
53         STOPPED,
54         RELEASED,
55     };
56     enum class ControlMode {
57         SMOOTH,
58         SYNC,
59     };
60     void PushData(std::shared_ptr<Plugin::Buffer>& data);
61     ControlStatus StartControl();
62     void PrepareControl();
63     ControlStatus StopControl();
64     ControlStatus ReleaseControl();
65     void RegisterListener(const std::shared_ptr<OutputControllerListener>& listener);
66     void UnregisterListener();
67 
68     void SetBufferTime(const uint32_t time);
69     void SetTimeInitState(const bool state);
70     void SetBaselineInitState(const bool state);
71     void SetProcessDynamicBalanceState(const bool state);
72     void SetAllowControlState(const bool state);
73 
74     uint32_t GetBufferTime();
75     bool GetTimeInitState();
76     bool GetBaselineInitState();
77     bool GetProcessDynamicBalanceState();
78     bool GetAllowControlState();
79 
80     void SetClockBaseline(const int64_t clockBaseline);
81     void SetTimeStampBaseline(const int64_t timeStmapBaseline);
82 
83     void SetAverIntervalDiffThre(const uint32_t thre);
84     void SetDynamicBalanceThre(const uint8_t thre);
85     void SetPushOnceDiffThre(const uint32_t thre);
86     void SetTimeStampOnceDiffThre(const uint32_t thre);
87     void SetAdjustSleepFactor(const float factor);
88     void SetWaitClockFactor(const float factor);
89     void SetTrackClockFactor(const float factor);
90     void SetWaitClockThre(const int64_t thre);
91     void SetTrackClockThre(const int64_t thre);
92     void SetSleepThre(const int64_t thre);
93     void SetVideoFrontTime(const int64_t time);
94     void SetVideoBackTime(const int64_t time);
95     void SetAudioFrontTime(const int64_t time);
96     void SetAudioBackTime(const int64_t time);
97 
98     Status GetParameter(Tag tag, ValueType& value);
99     Status SetParameter(Tag tag, const ValueType& value);
100 
101 private:
102     ControlMode GetControlMode();
103     ControlStatus GetControlStatus();
104     void SetControlMode(ControlMode mode);
105     void SetControlStatus(ControlStatus status);
106 
107     void InitTime(const int64_t enterTime, const int64_t timeStamp);
108     void RecordTime(const int64_t enterTime, const int64_t timeStamp);
109     void CheckSyncInfo(const std::shared_ptr<Plugin::Buffer>& data);
110     void CalProcessTime(const std::shared_ptr<Plugin::Buffer>& data);
111     void SetClockTime(const int64_t clockTime);
112     int64_t GetClockTime();
113     void SetDevClockDiff(int32_t diff);
114     int32_t GetDevClockDiff();
115     int32_t AcquireSyncClockTime(const std::shared_ptr<Plugin::Buffer>& data);
116     size_t GetQueueSize();
117 
118     void ClearQueue(std::queue<std::shared_ptr<Plugin::Buffer>>& queue);
119 
120     bool CheckIsTimeInit();
121     bool CheckIsBaselineInit();
122     bool CheckIsAllowControl();
123     bool CheckIsClockInvalid(const std::shared_ptr<Plugin::Buffer>& data);
124     bool WaitRereadClockFailed(const std::shared_ptr<Plugin::Buffer>& data);
125     bool CheckIsProcessInDynamicBalance(const std::shared_ptr<Plugin::Buffer>& data);
126     bool CheckIsProcessInDynamicBalanceOnce(const std::shared_ptr<Plugin::Buffer>& data);
127 
128     void LooperHandle();
129     void LooperControl();
130     int32_t ControlOutput(const std::shared_ptr<Plugin::Buffer>& data);
131     int32_t PostOutputEvent(const std::shared_ptr<Plugin::Buffer>& data);
132     void HandleControlResult(const std::shared_ptr<Plugin::Buffer>& data, int32_t result);
133     void CalSleepTime(const int64_t timeStamp);
134     void SyncClock(const std::shared_ptr<Plugin::Buffer>& data);
135     void HandleSmoothTime(const std::shared_ptr<Plugin::Buffer>& data);
136     void HandleSyncTime(const std::shared_ptr<Plugin::Buffer>& data);
137 
138 protected:
139     std::queue<std::shared_ptr<Plugin::Buffer>> dataQueue_;
140     std::map<Tag, ValueType> paramsMap_;
141     std::shared_ptr<TimeStatistician> statistician_ = nullptr;
142     std::shared_ptr<OutputControllerListener> listener_ = nullptr;
143 
144 private:
145     std::atomic<ControlStatus> status_ {ControlStatus::RELEASE};
146     std::atomic<ControlMode> mode_ {ControlMode::SMOOTH};
147     std::unique_ptr<std::thread> controlThread_ = nullptr;
148     std::unique_ptr<std::thread> handlerThread_ = nullptr;
149     std::shared_ptr<AppExecFwk::EventHandler> handler_ = nullptr;
150     std::condition_variable controlCon_;
151     std::condition_variable sleepCon_;
152     std::condition_variable clockCon_;
153     std::condition_variable handlerCon_;
154     std::mutex handlerMutex_;
155     std::mutex queueMutex_;
156     std::mutex sleepMutex_;
157     std::mutex stateMutex_;
158     std::mutex modeMutex_;
159     std::mutex clockMutex_;
160     std::mutex paramMapMutex_;
161     std::atomic<bool> isInDynamicBalance_ = true;
162     std::atomic<bool> isBaselineInit_ = false;
163     std::atomic<bool> isTimeInit_ = false;
164     std::atomic<bool> isAllowControl_ = true;
165 
166     const uint32_t QUEUE_MAX_SIZE = 100;
167     const int64_t GREATER_HALF_REREAD_TIME = 5 * NS_ONE_MS;
168     const int64_t LESS_HALF_REREAD_TIME = 3 * GREATER_HALF_REREAD_TIME;
169     int64_t waitClockThre_ = 0;
170     int64_t trackClockThre_ = 0;
171     float adjustSleepFactor_ = 0;
172     float waitClockFactor_ = 0;
173     float trackClockFactor_ = 0;
174     uint8_t dynamicBalanceThre_ = 0;
175     uint8_t dynamicBalanceCount_ = 0;
176     uint32_t averIntervalDiffThre_ = 0;
177     uint32_t pushOnceDiffThre_ = 0;
178     uint32_t timeStampOnceDiffThre_ = 0;
179     uint32_t bufferTime_ = 0;
180     int64_t enterTime_ = 0;
181     int64_t lastEnterTime_ = 0;
182     int64_t lastTimeStamp_ = 0;
183     int64_t leaveTime_ = 0;
184     int64_t timeStampBaseline_ = 0;
185     std::atomic<int64_t> clockTime_ = 0;
186     int64_t clockBaseline_ = 0;
187     int64_t delta_ = 0;
188     int64_t sleep_ = 0;
189     int64_t sleepThre_ = 0;
190     AVTransSharedMemory sharedMem_ = { 0, 0, "" };
191     AVSyncClockUnit clockUnit_ = { 0, 0, 0 };
192     std::atomic<int32_t> devClockDiff_ = 0;
193     int64_t aFront_ = 0;
194     int64_t aBack_ = 0;
195     int64_t vFront_ = 0;
196     int64_t vBack_ = 0;
197 };
198 } // namespace DistributedHardware
199 } // namespace OHOS
200 #endif // OHOS_OUTPUT_CONTROLLER_H