1 /*
2  * Copyright (c) 2024 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 #include <chrono>
17 
18 #include "rs_video_frame_rate_vote.h"
19 #include "ffrt_inner.h"
20 #include "platform/common/rs_log.h"
21 
22 namespace OHOS {
23 namespace Rosen {
24 namespace {
25     const static uint32_t NORMAL_RATE_MIN = 1;
26     const static uint32_t NORMAL_RATE_MAX = 144;
27     constexpr int32_t DELAY_TIME = 1000 * 1000;
28 }
29 
RSVideoFrameRateVote(uint64_t surfaceNodeId,const std::function<void (uint64_t)> & releaseCallback,const std::function<void (uint64_t,uint32_t)> & voteCallback)30 RSVideoFrameRateVote::RSVideoFrameRateVote(uint64_t surfaceNodeId,
31     const std::function<void(uint64_t)>& releaseCallback,
32     const std::function<void(uint64_t, uint32_t)>& voteCallback)
33     : surfaceNodeId_(surfaceNodeId), releaseCallback_(releaseCallback), voteCallback_(voteCallback)
34 {
35     std::string queueName = "video_frame_rate_vote_queue_" + std::to_string(surfaceNodeId);
36     ffrtQueue_ = std::make_shared<ffrt::queue>(queueName.c_str());
37 }
38 
~RSVideoFrameRateVote()39 RSVideoFrameRateVote::~RSVideoFrameRateVote()
40 {
41     voteCallback_ = nullptr;
42     releaseCallback_ = nullptr;
43     taskHandler_ = nullptr;
44     ffrtQueue_ = nullptr;
45 }
46 
StartVideoFrameRateVote(double videoRate)47 void RSVideoFrameRateVote::StartVideoFrameRateVote(double videoRate)
48 {
49     CancelDelayTask();
50     VoteVideoFrameRate(videoRate);
51     SendDelayTask();
52 }
53 
VoteVideoFrameRate(double videoRate)54 void RSVideoFrameRateVote::VoteVideoFrameRate(double videoRate)
55 {
56     int32_t intRate = static_cast<int32_t>(videoRate);
57     uint32_t rate = static_cast<uint32_t>(intRate);
58     if (rate < NORMAL_RATE_MIN || rate > NORMAL_RATE_MAX) {
59         return;
60     }
61     if (rate == lastRate_) {
62         return;
63     }
64     RS_LOGI("video vote surfaceNodeId(%{public}s) rate(%{public}u)", std::to_string(surfaceNodeId_).c_str(), rate);
65     DoVoteCallback(rate);
66     lastRate_ = rate;
67 }
68 
SendDelayTask()69 void RSVideoFrameRateVote::SendDelayTask()
70 {
71     std::lock_guard<ffrt::mutex> autoLock(ffrtMutex_);
72     auto initTask = [this]() {
73         DoReleaseCallback();
74     };
75     ffrt::task_attr taskAttr;
76     taskAttr.delay(DELAY_TIME);
77     if (ffrtQueue_) {
78         taskHandler_ = ffrtQueue_->submit_h(initTask, taskAttr);
79     }
80 }
81 
CancelDelayTask()82 void RSVideoFrameRateVote::CancelDelayTask()
83 {
84     std::lock_guard<ffrt::mutex> autoLock(ffrtMutex_);
85     if (taskHandler_) {
86         ffrtQueue_->cancel(taskHandler_);
87         taskHandler_ = nullptr;
88     }
89 }
90 
DoVoteCallback(uint32_t rate)91 void RSVideoFrameRateVote::DoVoteCallback(uint32_t rate)
92 {
93     if (voteCallback_ == nullptr) {
94         return;
95     }
96     voteCallback_(surfaceNodeId_, rate);
97 }
98 
DoReleaseCallback()99 void RSVideoFrameRateVote::DoReleaseCallback()
100 {
101     if (releaseCallback_ == nullptr) {
102         return;
103     }
104     releaseCallback_(surfaceNodeId_);
105 }
106 } // namespace Rosen
107 } // namespace OHOS