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